source: DASISH/t5.6/client/trunk/chrome/markingcollection/content/markingcollection/autocache.js @ 3406

Last change on this file since 3406 was 3406, checked in by sroth, 11 years ago

Update of comment concerning fix for not enough arguments exception.

File size: 132.8 KB
Line 
1var bitsAutocacheObserver = {
2        domain  : 'wiredmarker', //"objectmng.xxx"ずいう名前の蚭定が倉曎された堎合党おで凊理を行う
3        observe : function(aSubject, aTopic, aPrefstring) {
4                try{
5                        if (aTopic == 'nsPref:changed') {
6                                switch (aPrefstring){
7                                        case "wiredmarker.autocache.use":
8                                                var use = nsPreferences.copyUnicharPref(aPrefstring,"valid");
9                                                var exec = nsPreferences.getBoolPref("wiredmarker.autocache.manually.exec",false);
10                                                var btn = bitsAutocacheService.BUTTON;
11                                                if(btn){
12                                                        if(use == "switching"){
13                                                                btn.removeAttribute("hidden");
14                                                        }else if(use == "valid"){
15                                                                btn.setAttribute("hidden",true);
16                                                        }else{
17                                                                var exec = nsPreferences.getBoolPref("wiredmarker.autocache.manually.exec",false);
18                                                                if(exec){
19                                                                        btn.removeAttribute("hidden");
20                                                                }else{
21                                                                        btn.setAttribute("hidden",true);
22                                                                }
23                                                        }
24                                                }
25                                                var btn = bitsAutocacheService.TOGGLE_BUTTON;
26                                                if(btn){
27                                                        if(use == "valid" || exec){
28                                                                btn.removeAttribute("hidden");
29                                                                if(bitsAutocacheService._pref.view.disp) btn.setAttribute("checked","true");
30                                                        }else{
31                                                                btn.setAttribute("hidden","true");
32                                                                btn.removeAttribute("checked");
33                                                                bitsAutocacheService._pref.view.disp = false;
34                                                        }
35                                                }
36                                                bitsAutocacheService.toggleCacheView();
37                                                var menu = bitsAutocacheService.CACHEMENU;
38                                                if(menu){
39                                                        menu.setAttribute("hidden","true");
40                                                        if(use == "valid" || exec) menu.removeAttribute("hidden");
41                                                }
42                                                break;
43                                        case "wiredmarker.autocache.manually.exec":
44                                                var value = nsPreferences.getBoolPref(aPrefstring,false);
45                                                var btn = bitsAutocacheService.BUTTON;
46                                                if(btn){
47                                                        if(value){
48                                                                btn.removeAttribute("hidden");
49                                                        }else{
50                                                                btn.setAttribute("hidden",true);
51                                                        }
52                                                }
53                                                var btn = bitsAutocacheService.TOGGLE_BUTTON;
54                                                if(btn){
55                                                        if(value){
56                                                                btn.removeAttribute("hidden");
57                                                        }else{
58                                                                btn.setAttribute("hidden",true);
59                                                        }
60                                                        if(bitsAutocacheService._pref.view.disp) btn.setAttribute("checked","true");
61                                                }
62                                                bitsAutocacheService.toggleCacheView();
63                                                var menu = bitsAutocacheService.CACHEMENU;
64                                                if(menu){
65                                                        menu.setAttribute("hidden","true");
66                                                        if(value) menu.removeAttribute("hidden");
67                                                }
68                                                break;
69                                        case "wiredmarker.autocache.topmenu.display":
70                                                var display = nsPreferences.getBoolPref(aPrefstring, true);
71                                                var menu = bitsAutocacheService.CACHEMENU;
72                                                if(menu){
73                                                        if(display){
74                                                                menu.removeAttribute("hidden");
75                                                        }else{
76                                                                menu.setAttribute("hidden","true");
77                                                        }
78                                                }
79                                                break;
80                                        default:
81                                                break;
82                                }
83                        }
84                }catch(ex){
85                        window.top.bitsObjectMng.Common.alert("bitsAutocacheObserver:"+ex);
86                }
87        }
88};
89
90var bitsAutocacheService = {
91        _refreshFlag : true,
92        _cahceinfo : {},
93        _url2timestamp : {},
94        _disabledTimer : null,
95        _refreshTimer : null,
96        _refreshDTimer : null,
97        _openobject : null,
98        _pref : {},
99        _cacheList : [],
100        _cacheList2URL : {},
101        _dbConn : null,
102        _dbName : "autocache.sqlite",
103        _debuginfo : null,
104        _debug_idlist : null,
105
106        get STRING() { return document.getElementById("MarkingCollectionOverlayString"); },
107        get DataSource() { return window.top.bitsObjectMng.DataSource; },
108        get Common()     { return window.top.bitsObjectMng.Common;     },
109        get Database()   { return window.top.bitsObjectMng.Database;   },
110        get XML()        { return window.top.bitsObjectMng.XML;        },
111        get XPath()      { return window.top.bitsObjectMng.XPath;      },
112        get gBrowser()   { return window.top.bitsObjectMng.getBrowser();},
113        get SIDEBAR() { return window.top.document.getElementById("sidebar"); },
114        get SIDEBAR_DOC() {try{return this.SIDEBAR.contentDocument;}catch(e){return undefined;}},
115        get SIDEBAR_WIN() {try{return this.SIDEBAR.contentWindow;}catch(e){return undefined;}},
116        get mcTreeHandler() {try{return this.SIDEBAR_WIN.mcTreeHandler;}catch(e){return undefined;}},
117        get mcMainService() {try{return this.SIDEBAR_WIN.mcMainService;}catch(e){return undefined;}},
118        get mcController() {try{return this.SIDEBAR_WIN.mcController;}catch(e){return undefined;}},
119        get mcPropertyView() {try{return this.SIDEBAR_WIN.mcPropertyView;}catch(e){return undefined;}},
120        get bitsItemView() {try{return this.SIDEBAR_WIN.bitsItemView;}catch(e){return undefined;}},
121        get mcTreeViewModeService() {try{return this.SIDEBAR_WIN.mcTreeViewModeService;}catch(e){return undefined;}},
122        get BUTTON(){try{return this.SIDEBAR_DOC.getElementById("mcToolbarAutocacheButton");}catch(e){return undefined;}},
123        get OPEN1() {try{return this.SIDEBAR_DOC.getElementById("mcPopupCache");}catch(e){return undefined;}},
124        get OPEN2() {try{return this.SIDEBAR_DOC.getElementById("bitsItemTreePopupCache");}catch(e){return undefined;}},
125        get OPEN3() {try{return this.SIDEBAR_DOC.getElementById("mcPopupObjectCache");}catch(e){return undefined;}},
126        get OPEN_MENUTREE(){return window.top.document.getElementById("bitsMenuTreeObjectContextmenuCache");},
127        get CACHEMENU(){return window.top.document.getElementById("bitsCacheMenu");},
128        get SPLITTER(){try{return this.SIDEBAR_DOC.getElementById("bitsBrowserAutocacheSplitter");}catch(e){return undefined;}},
129        get TOGGLE_BUTTON(){try{return this.SIDEBAR_DOC.getElementById("mcToolbarAutocacheView");}catch(e){return undefined;}},
130        get VBOX(){try{return this.SIDEBAR_DOC.getElementById("bitsBrowserAutocacheVBox");}catch(e){return undefined;}},
131        get TREE(){try{return this.SIDEBAR_DOC.getElementById("bitsAutocacheTree");}catch(e){return undefined;}},
132        get VSB(){try{return this.SIDEBAR_DOC.getElementById("bitsAutocacheSearchButton");}catch(e){return undefined;}},
133        get VSM(){try{return this.SIDEBAR_DOC.getElementById("bitsAutocacheSearchTextbox");}catch(e){return undefined;}},
134        get idTREE_IFAVICON()  { return "bitsAutocacheIFavicon";   },
135        get idTREE_IURL()      { return "bitsAutocacheIUrl";       },
136        get idTREE_ITITLE()    { return "bitsAutocacheITitle";     },
137        get idTREE_IDATE()     { return "bitsAutocacheIDate";      },
138        get idTREE_ICACHE()    { return "bitsAutocacheICache";     },
139        get idTREE_IMARKER()   { return "bitsAutocacheIMarker";    },
140        get idTREE_ICACHESIZE(){ return "bitsAutocacheICacheSize"; },
141        get TREE_IFAVICON()    { try{return this.SIDEBAR_DOC.getElementById(this.idTREE_IFAVICON);}catch(e){return undefined;}  },
142        get TREE_IURL()        { try{return this.SIDEBAR_DOC.getElementById(this.idTREE_IURL);}catch(e){return undefined;}      },
143        get TREE_ITITLE()      { try{return this.SIDEBAR_DOC.getElementById(this.idTREE_ITITLE);}catch(e){return undefined;}    },
144        get TREE_IDATE()       { try{return this.SIDEBAR_DOC.getElementById(this.idTREE_IDATE);}catch(e){return undefined;}     },
145        get TREE_ICACHE()      { try{return this.SIDEBAR_DOC.getElementById(this.idTREE_ICACHE);}catch(e){return undefined;}    },
146        get TREE_IMARKER()     { try{return this.SIDEBAR_DOC.getElementById(this.idTREE_IMARKER);}catch(e){return undefined;}   },
147        get TREE_ICACHESIZE()  { try{return this.SIDEBAR_DOC.getElementById(this.idTREE_ICACHESIZE);}catch(e){return undefined;}},
148        get idCONTEXTMENU_OPENALL(){ return "bitsAutocacheTreeContextmenuCacheOpenAll"; },
149        get CONTEXTMENU_OPENALL(){try{return this.SIDEBAR_DOC.getElementById(this.idCONTEXTMENU_OPENALL);}catch(e){return undefined;}},
150
151/////////////////////////////////////////////////////////////////////
152        get default_cachedir(){
153                var dir = this.Common.getExtensionDir();
154                dir.append("cache");
155                return dir;
156        },
157
158/////////////////////////////////////////////////////////////////////
159        get cachedir(){
160                try{
161                        var prefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
162                        var cache_folder = prefs.getComplexValue("wiredmarker.autocache.save.folder", Components.interfaces.nsILocalFile);
163                }catch(e){
164                        cache_folder = undefined;
165                }
166                var save_default = nsPreferences.getBoolPref("wiredmarker.autocache.save.default", true);
167                if(save_default || !cache_folder){
168                        return this.default_cachedir;
169                }else{
170                        return cache_folder;
171                }
172        },
173
174/////////////////////////////////////////////////////////////////////
175        getCacheDir : function(){
176                var dir;
177                if(this.bitsItemView && this.bitsItemView.isChecked){
178                        var object = this.bitsItemView.object;
179                        if(object) dir = this.getURLCacheDirFromTimeStamp(object.doc_url,object.oid_date);
180                }else{
181                        var curIdx = this.mcTreeHandler.TREE.currentIndex;
182                        var curRes = null;
183                        if(curIdx>=0 && !this.mcTreeHandler.TREE.view.isContainer(curIdx)) curRes = this.mcTreeHandler.TREE.builderView.getResourceAtIndex(curIdx);
184                        if(curRes) dir = this.getURLCacheDirFromTimeStamp(this.DataSource.getProperty(curRes,"uri"),this.DataSource.getProperty(curRes,"date"));
185                }
186                return dir;
187        },
188
189/////////////////////////////////////////////////////////////////////
190        setCacheInfo : function(aURLString,aCacheInfo){
191                if(!aURLString || !aCacheInfo) return;
192                if(this.isCacheURL(aURLString)) return;
193                if(!this._cahceinfo[aURLString]) this._cahceinfo[aURLString] = {};
194                for(var key in aCacheInfo){
195                        this._cahceinfo[aURLString][key] = aCacheInfo[key];
196                }
197        },
198
199/////////////////////////////////////////////////////////////////////
200        getCacheInfo : function(aURLString){
201                if(!aURLString) return undefined;
202                return (this._cahceinfo[aURLString]?this._cahceinfo[aURLString]:undefined);
203        },
204
205/////////////////////////////////////////////////////////////////////
206// 指定URLがキャッシュドキュメントぞのURLか
207/////////////////////////////////////////////////////////////////////
208        isCacheURL : function(aURLString){
209                if(!aURLString || !aURLString.match(/^file:/)) return false;
210                var docFile = this.Common.convertURLToFile(aURLString);
211                var autocachedir = this.cachedir;
212                var rtn = (autocachedir.path == docFile.path.substr(0,autocachedir.path.length));
213                if(rtn) return rtn;
214                var url = Components.classes['@mozilla.org/network/standard-url;1'].createInstance(Components.interfaces.nsIURL);
215                url.spec = aURLString;
216                var path = url.scheme + "://" + url.host +url.directory;
217                var histdbs = this._selectHistoryDB({hid_file:url.fileName,hid_path:path});
218                return (histdbs?true:false);
219        },
220
221/////////////////////////////////////////////////////////////////////
222// キャッシュドキュメントの堎合、マヌキングするか
223/////////////////////////////////////////////////////////////////////
224        isMarking : function(aURLString){
225               
226                var use = nsPreferences.copyUnicharPref("wiredmarker.autocache.use", "valid");
227                if(use == "disabled") return true;
228                if(!this.isCacheURL(aURLString)) return true;
229                var autocache_marking = nsPreferences.copyUnicharPref("wiredmarker.autocache.marking","confirm");
230                if(autocache_marking == "disabled"){
231                        this.Common.alert(this.STRING.getString("ALERT_CACHEPAGE_MARKING"));
232                        return false;
233                }
234                if(autocache_marking == "confirm"){
235                        var info = this.getSaveCacheInfo(aURLString);
236                        var prompts = this.Common.PROMPT;
237                        var title = this.STRING.getString("APP_DISP_TITLE");
238                        var flags;
239                        if(info && info.URL){
240                                flags = prompts.BUTTON_POS_0 * prompts.BUTTON_TITLE_YES +
241                                        prompts.BUTTON_POS_1 * prompts.BUTTON_TITLE_IS_STRING  +
242                                        prompts.BUTTON_POS_2 * prompts.BUTTON_TITLE_NO +
243                                        prompts.BUTTON_POS_2_DEFAULT;
244                        }else{
245                                flags = prompts.BUTTON_POS_0 * prompts.BUTTON_TITLE_YES +
246                                        prompts.BUTTON_POS_1 * prompts.BUTTON_TITLE_NO +
247                                        prompts.BUTTON_POS_1_DEFAULT;
248                        }
249                        var checkMsg = null;
250                        var checkState = {value: false};
251                        var button = prompts.confirmEx(
252                                window,
253                                title,
254                                this.STRING.getString("CONFIRM_CACHEPAGE_MARKING"),
255                                flags, "", this.STRING.getString("BUTTON_CACHEPAGE_MARKING"), "", checkMsg, checkState);
256                        if(button!=0){
257                                if(info && info.URL && button==1) this.Common.loadURL(info.URL);
258                                return false;
259                        }
260                }
261                return true;
262        },
263
264/////////////////////////////////////////////////////////////////////
265// 指定した日時のキャッシュが存圚するか
266/////////////////////////////////////////////////////////////////////
267        existsCache : function(aURLString,aTimeStamp){
268                if(!aURLString){
269                        var dir = this.cachedir.clone();
270                        var dir_arr = [];
271                        if(dir.exists() && dir.directoryEntries){
272                                var entries = dir.directoryEntries;
273                                while(entries.hasMoreElements()){
274                                        var entry = entries.getNext().QueryInterface(Components.interfaces.nsILocalFile);
275                                        if(!entry.isDirectory() || (entry.isDirectory() && entry.leafName.match(/^\./))) continue;
276                                        dir_arr.push(entry);
277                                }
278                        }
279                        return (dir_arr.length>0?true:false);
280                }
281                if(aTimeStamp && aTimeStamp.match(/^(\d{2})\/(\d{2})\/(\d{4})\s+(\d{2}):(\d{2}):(\d{2})$/)) aTimeStamp = RegExp.$3 + RegExp.$1 + RegExp.$2 + RegExp.$4 + RegExp.$5 + RegExp.$6;
282                var dir = this.getURLCacheDir(aURLString);
283                if(dir || !dir.exists()) return false;
284                if(aTimeStamp) dir.append(aTimeStamp);
285                return dir.exists();
286        },
287
288/////////////////////////////////////////////////////////////////////
289// ドキュメントを開いた日時
290/////////////////////////////////////////////////////////////////////
291        getURLTimeStamp : function(aURLString){
292                if(!aURLString) return undefined;
293                // キャッシュの堎合、キャッシュした日時を返す
294                if(this.isCacheURL(aURLString)){
295                        var file = this.getSaveCacheInfoFile(aURLString);
296                        if(file && file.parent) return file.parent.leafName;
297                }
298                if(this._url2timestamp[aURLString] == undefined) this._url2timestamp[aURLString] = this.Common.getTimeStamp();
299                return this._url2timestamp[aURLString];
300        },
301
302        getURLTimeStampFormatDate : function(aURLString){
303                if(!aURLString) return undefined;
304                var timeStamp = this.getURLTimeStamp(aURLString);
305                if(!timeStamp) return undefined;
306                if(timeStamp.match(/^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})$/)){
307                        return RegExp.$2+"/"+RegExp.$3+"/"+RegExp.$1+" "+RegExp.$4+":"+RegExp.$5+":"+RegExp.$6;
308                }else{
309                        return undefined;
310                }
311        },
312
313/////////////////////////////////////////////////////////////////////
314// キャッシュURLをオリゞナルのURLぞ倉換
315/////////////////////////////////////////////////////////////////////
316        convertCacheURLToOriginalURL : function(aURLString){
317                if(!aURLString) return undefined;
318                if(!this.isCacheURL(aURLString)) return aURLString;
319                try{
320                        var infofile = this.getSaveCacheInfoFile(aURLString);
321                        var infodir = infofile.parent.clone();
322                        var baseURL = this.Common.convertFilePathToURL(infodir.path);
323                        var urlinfo_str = this._getSaveCacheUrlInfo(infodir);
324                        var urlinfo = {};
325                        var urlinfo_arr = urlinfo_str.split("\n");
326                        var i;
327                        var arr;
328                        for(i=0;i<urlinfo_arr.length;i++){
329                                arr = urlinfo_arr[i].split("\t");
330                                if(arr.length>1) urlinfo[arr[1]] = arr[0];
331                        }
332                        var cacheurl = aURLString.substring(baseURL.length);
333                        if(cacheurl.match(/^([^\?#;]+)([\?#;].*)$/)){
334                                cacheurl = RegExp.$1;
335                                if(urlinfo[cacheurl] != undefined) return urlinfo[cacheurl] + RegExp.$2;
336                        }else{
337                                if(urlinfo[cacheurl] != undefined) return urlinfo[cacheurl];
338                        }
339                }catch(e){
340                        this._dump("bitsAutocacheService.convertCacheURLToOriginalURL():aURLString=["+aURLString+"]");
341                        this._dump("bitsAutocacheService.convertCacheURLToOriginalURL():"+e);
342                        return aURLString;
343                }
344        },
345
346/////////////////////////////////////////////////////////////////////
347// URLずタむムスタンプでフォルダ
348/////////////////////////////////////////////////////////////////////
349        getURLCacheDirFromTimeStamp : function(aURLString,aTimeStamp){
350                if(!aURLString || !aTimeStamp) return undefined;
351                var dir = this.cachedir.clone();
352                if(aTimeStamp.match(/^(\d{2})\/(\d{2})\/(\d{4})\s+(\d{2}):(\d{2}):(\d{2})$/)) aTimeStamp = RegExp.$3 + RegExp.$1 + RegExp.$2 + RegExp.$4 + RegExp.$5 + RegExp.$6;
353                if(aTimeStamp.match(/^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})$/)){
354                        dir.append(RegExp.$1);
355                        dir.append(RegExp.$2);
356                        dir.append(RegExp.$3);
357                        dir.append(RegExp.$4);
358                }else{
359                        dir.append(aTimeStamp.substr(0,4));
360                        if(aTimeStamp.length>3) dir.append(aTimeStamp.substr(3,2));
361                        if(aTimeStamp.length>5) dir.append(aTimeStamp.substr(5,2));
362                        if(aTimeStamp.length>7) dir.append(aTimeStamp.substr(7,2));
363                }
364                dir.append(this._string2CryptoHash(aURLString));
365                dir.append(aTimeStamp);
366                return dir;
367        },
368
369/////////////////////////////////////////////////////////////////////
370// URLのBaseCacheフォルダ
371/////////////////////////////////////////////////////////////////////
372        getURLCacheDir : function(aURLString,aBaseDir){
373                if(!aURLString) return undefined;
374                var dir;
375                if(aBaseDir){
376                        dir = aBaseDir.clone();
377                }else{
378                        dir = this.cachedir.clone();
379                }
380                dir.append(this._string2CryptoHash(aURLString));
381                return dir;
382        },
383
384/////////////////////////////////////////////////////////////////////
385// 新芏のCacheフォルダ
386/////////////////////////////////////////////////////////////////////
387        getNewCacheDir : function(aURLString,aBaseDir){
388                if(!aURLString) return undefined;
389                var dir = this.getURLCacheDir(aURLString,aBaseDir);
390                dir.append(this.getURLTimeStamp(aURLString));
391                return dir;
392        },
393
394/////////////////////////////////////////////////////////////////////
395// 最新のCacheのタむムスタンプ
396/////////////////////////////////////////////////////////////////////
397        getNewestCacheTimeStamp : function(aURLString,aBaseDir){
398                if(!aURLString) return undefined;
399                var dir = this.getURLCacheDir(aURLString,aBaseDir);
400                if(!dir.exists()) return undefined;
401                var dir_arr = [];
402                var entries = dir.directoryEntries;
403                while(entries.hasMoreElements()){
404                        var entry = entries.getNext().QueryInterface(Components.interfaces.nsILocalFile);
405                        if(!entry.isDirectory() || (entry.isDirectory() && entry.leafName.match(/^\./))) continue;
406                        dir_arr.push(entry);
407                }
408                if(dir_arr.length>0){
409                        dir_arr.sort(function(a, b) { return(parseInt(b.leafName) - parseInt(a.leafName)); });
410                        return dir_arr[0].leafName;
411                }else{
412                        return undefined;
413                }
414        },
415
416        getNewestCacheFormatDate : function(aURLString,aBaseDir){
417                var timeStamp = this.getNewestCacheTimeStamp(aURLString,aBaseDir);
418                if(!timeStamp) return undefined;
419                if(timeStamp.match(/^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})$/)){
420                        return RegExp.$2+"/"+RegExp.$3+"/"+RegExp.$1+" "+RegExp.$4+":"+RegExp.$5+":"+RegExp.$6;
421                }else{
422                        return undefined;
423                }
424        },
425
426/////////////////////////////////////////////////////////////////////
427// 最新のCacheフォルダ
428/////////////////////////////////////////////////////////////////////
429        getNewestCacheDir : function(aURLString,aBaseDir){
430                if(!aURLString) return undefined;
431                var dir = this.getURLCacheDir(aURLString,aBaseDir);
432                if(!dir.exists()) return undefined;
433                var newestCacheTimeStamp = this.getNewestCacheTimeStamp(aURLString,aBaseDir);
434                if(newestCacheTimeStamp){
435                        dir.append(newestCacheTimeStamp);
436                        return dir;
437                }else{
438                        return undefined;
439                }
440        },
441
442/////////////////////////////////////////////////////////////////////
443// 指定した日時の盎前のタむムスタンプ
444/////////////////////////////////////////////////////////////////////
445        getApproximateCacheTimeStamp : function(aURLString,aTimeStamp){
446                if(!aURLString || !aTimeStamp) return undefined;
447                if(aTimeStamp.match(/^(\d{2})\/(\d{2})\/(\d{4})\s+(\d{2}):(\d{2}):(\d{2})$/)) aTimeStamp = RegExp.$3+RegExp.$1+RegExp.$2+RegExp.$4+RegExp.$5+RegExp.$6;
448                var dir = this.getURLCacheDir(aURLString);
449                if(!dir.exists()) return undefined;
450                var minDir=dir.clone();
451                if(aTimeStamp){
452                        minDir.append(aTimeStamp);
453                        if(minDir.exists()) return minDir;
454                        minDir = undefined;
455                }
456                var min = -1;
457                var entries = dir.directoryEntries;
458                while(entries.hasMoreElements()){
459                        var entry = entries.getNext().QueryInterface(Components.interfaces.nsILocalFile);
460                        if(!entry.isDirectory() || (entry.isDirectory() && entry.leafName.match(/^\./))) continue;
461                        if(parseInt(aTimeStamp) < parseInt(entry.leafName)) continue;
462                        if(min<0 || (parseInt(aTimeStamp)- parseInt(entry.leafName))<min){
463                                min = parseInt(aTimeStamp)- parseInt(entry.leafName);
464                                minDir = entry.clone();
465                                if(min == 0) break;
466                        }
467                }
468                if(minDir){
469                        return minDir.leafName;
470                }else{
471                        return undefined;
472                }
473        },
474
475/////////////////////////////////////////////////////////////////////
476// 指定した日時の盎前のCacheフォルダ
477/////////////////////////////////////////////////////////////////////
478        getApproximateCacheDir : function(aURLString,aTimeStamp){
479                if(!aURLString) return undefined;
480                var dir = this.getURLCacheDir(aURLString);
481                if(!dir.exists()) return undefined;
482                var approximateCacheTimeStamp = this.getApproximateCacheTimeStamp(aURLString,aTimeStamp);
483                if(approximateCacheTimeStamp){
484                        dir.append(approximateCacheTimeStamp);
485                        return dir;
486                }else{
487                        return undefined;
488                }
489        },
490
491/////////////////////////////////////////////////////////////////////
492// 保存したのCacheの情報を取埗
493/////////////////////////////////////////////////////////////////////
494        getSaveCacheInfo : function(aURLString){
495                var aFile = this.Common.convertURLToFile(aURLString);
496                if(!aFile || !aFile.exists()) return undefined;
497                return this._getSaveCacheInfo((aFile.isDirectory() ? aFile : aFile.parent));
498        },
499        getSaveCacheInfoFile : function(aURLString){
500                var aFile = this.Common.convertURLToFile(aURLString);
501                if(!aFile || !aFile.exists()) return undefined;
502                return this._getSaveCacheInfoFile((aFile.isDirectory() ? aFile : aFile.parent));
503        },
504        _getSaveCacheInfoFile : function(aInfoDir){
505                if(!aInfoDir) return undefined;
506                var infoFile = aInfoDir.clone();
507                infoFile.append(".info");
508                while(!infoFile.exists()){
509                        try{if(!aInfoDir.parent) return undefined;}catch(e){return undefined;}
510                        aInfoDir = aInfoDir.parent.clone();
511                        infoFile = aInfoDir.clone();
512                        infoFile.append(".info");
513                }
514                return infoFile.clone();
515        },
516        _getSaveCacheInfo : function(aInfoDir){
517                if(!aInfoDir) return undefined;
518                var infoFile = this._getSaveCacheInfoFile(aInfoDir);
519                if(!infoFile) return undefined;
520                var info_str = this.readFile(infoFile);
521                if(!info_str) return undefined;
522                var info = {};
523                var info_arr = info_str.split("\n");
524                for(var i=0;i<info_arr.length;i++){
525                        var arr = info_arr[i].split("\t");
526                        info[arr[0]] = arr[1];
527                }
528                return info;
529        },
530
531        _getSaveCacheUrlInfo : function(aInfoDir){
532                if(!aInfoDir) return undefined;
533                var infoFile = aInfoDir.clone();
534                infoFile.append(".urlinfo");
535                var info_str = this.readFile(infoFile);
536                if(!info_str) return undefined;
537                return info_str;
538        },
539
540/////////////////////////////////////////////////////////////////////
541        init : function(){
542                this.gBrowser.addEventListener("pageshow", this.pageshow, false);
543                this.gBrowser.tabContainer.addEventListener("TabSelect", this.tabselect, false);
544                bitsMenuTree.POPUP.addEventListener("popupshowing",this.popupshowing_menutree, false);
545                this.Common.addPrefListener(bitsAutocacheObserver);
546                if(this._connectDB()){
547                        this._insertInitDB();
548                }
549                var menu = this.CACHEMENU;
550                if(menu){
551                        menu.setAttribute("hidden","true");
552                        var display = nsPreferences.getBoolPref("wiredmarker.autocache.topmenu.display", false);
553                        if(display){
554                                var use = nsPreferences.copyUnicharPref("wiredmarker.autocache.use", "valid");
555                                if(use == "valid"){
556                                        menu.removeAttribute("hidden");
557                                }else if(use == "disabled" && nsPreferences.getBoolPref("wiredmarker.autocache.manually.exec",false)){
558                                        menu.removeAttribute("hidden");
559                                }else if(use != "valid" && use != "disabled"){
560                                        use = "valid";
561                                        nsPreferences.setUnicharPref("wiredmarker.autocache.use", use);
562                                }
563                        }
564                }
565                var info = Components.classes["@mozilla.org/xre/app-info;1"].getService(Components.interfaces.nsIXULAppInfo);
566                this._app_version = parseInt(info.version);
567                this._pref.view = {
568                        disp : nsPreferences.getBoolPref("wiredmarker.autocache.view.disp", false),
569                };
570        },
571
572/////////////////////////////////////////////////////////////////////
573        done : function(){
574                this.gBrowser.removeEventListener("pageshow", this.pageshow, false);
575                this.gBrowser.tabContainer.removeEventListener("TabSelect", this.tabselect, false);
576                bitsMenuTree.POPUP.removeEventListener("popupshowing",this.popupshowing_menutree, false);
577                this.Common.removePrefListener(bitsAutocacheObserver);
578                this._disconnectDB();
579                nsPreferences.setBoolPref("wiredmarker.autocache.view.disp", this._pref.view.disp);
580        },
581
582/////////////////////////////////////////////////////////////////////
583        load : function(aEvent){
584                this.SPLITTER.setAttribute("hidden","true");
585                if(this.bitsItemView && this.bitsItemView.isChecked){
586                        this.bitsItemView.POPUP.addEventListener("popupshowing",this.popupshowing, false);
587                }else{
588                        this.mcTreeHandler.POPUP.addEventListener("popupshowing",this.popupshowing, false);
589                        this.mcTreeHandler.POPUP_OBJECT.addEventListener("popupshowing",this.popupshowing, false);
590                }
591                var btn = this.BUTTON;
592                if(btn){
593                        var use = nsPreferences.copyUnicharPref("wiredmarker.autocache.use", "valid");
594                        if(use == "switching"){
595                                btn.removeAttribute("hidden");
596                        }else if(use == "disabled" && nsPreferences.getBoolPref("wiredmarker.autocache.manually.exec",false)){
597                                btn.removeAttribute("hidden");
598                        }
599                }
600                var btn = this.TOGGLE_BUTTON;
601                if(btn){
602                        var use = nsPreferences.copyUnicharPref("wiredmarker.autocache.use", "valid");
603                        if(use == "valid"){
604                                btn.removeAttribute("hidden");
605                        }else if(use == "disabled" && nsPreferences.getBoolPref("wiredmarker.autocache.manually.exec",false)){
606                                btn.removeAttribute("hidden");
607                        }
608                        if(this._pref.view.disp) btn.setAttribute("checked","true");
609                        if(!btn.hasAttribute("hidden") && btn.hasAttribute("checked")) this.SPLITTER.removeAttribute("hidden");
610                }
611                this.toggleCacheView();
612                if(!this.TREE.hasAttribute("hidden")) this.rebuild();
613        },
614
615/////////////////////////////////////////////////////////////////////
616        unload : function(aEvent){
617                if(this.bitsItemView && this.bitsItemView.isChecked){
618                        this.bitsItemView.POPUP.removeEventListener("popupshowing",this.popupshowing, false);
619                }else if(this.mcTreeHandler){
620                        this.mcTreeHandler.POPUP.removeEventListener("popupshowing",this.popupshowing, false);
621                        this.mcTreeHandler.POPUP_OBJECT.removeEventListener("popupshowing",this.popupshowing, false);
622                }
623        },
624
625/////////////////////////////////////////////////////////////////////
626// キャッシュファむルを開いたずきの凊理を行う
627/////////////////////////////////////////////////////////////////////
628        pageshow : function(aEvent){
629                bitsAutocacheService._pageshow(aEvent);
630        },
631
632        _pageshow : function(aEvent){
633                var btn = this.BUTTON;
634                if(btn) btn.removeAttribute("disabled");
635                var urlString = this.Common.getURLStringFromDocument(aEvent.target);
636                if(!this.isCacheURL(urlString)){
637                        try{
638                                var aURL = Components.classes['@mozilla.org/network/standard-url;1'].createInstance(Components.interfaces.nsIURL);
639                                aURL.spec = urlString;
640                        }catch(ex){
641                                this._dump("bitsAutocacheService._pageshow():"+ ex);
642                                aURL = undefined;
643                        }
644                        if(aURL && aURL.scheme == "file"){
645                                var fileHandler = this.Common.IO.getProtocolHandler(aURL.scheme).QueryInterface(Components.interfaces.nsIFileProtocolHandler);
646                                var file = fileHandler.getFileFromURLSpec(urlString);
647                                var dd = new Date;
648                                dd.setTime(file.lastModifiedTime);
649                                var y = dd.getFullYear();
650                                var m = dd.getMonth() + 1; if(m < 10) m = "0" + m;
651                                var d = dd.getDate();      if(d < 10) d = "0" + d;
652                                var h = dd.getHours();     if(h < 10) h = "0" + h;
653                                var i = dd.getMinutes();   if(i < 10) i = "0" + i;
654                                var s = dd.getSeconds();   if(s < 10) s = "0" + s;
655                                this._url2timestamp[urlString] = y.toString() + m.toString() + d.toString() + h.toString() + i.toString() + s.toString();
656                        }else{
657                                this._url2timestamp[urlString] = this.Common.getTimeStamp();
658                        }
659                        this.disabledButton(aEvent.target);
660                        try{
661                                var row = this._cacheList2URL[urlString];
662                                if(row != undefined){
663                                        this.TREE.currentIndex = row;
664                                        if(!this.TREE.view.selection.isSelected(row)) this.TREE.view.selection.select(row);
665                                        this.TREE.treeBoxObject.ensureRowIsVisible(row);
666                                }
667                        }catch(e){}
668                }else{
669                        try{
670                                var doc = aEvent.target;
671                                if(doc.location.toString() == this.gBrowser.contentDocument.location.toString()){
672                                        var info = this.getSaveCacheInfo(urlString);
673                                        var timestamp = this.getURLTimeStampFormatDate(urlString);
674                                        var cached_msg = "Cached from " + info.URL;
675                                        if(timestamp) cached_msg += " on " + timestamp;
676                                        doc.title = "["+ cached_msg + "] : " + doc.title;
677                                }
678                        }catch(e){alert(e);}
679                }
680                if(btn) btn.setAttribute("disabled","true");
681
682                var info = this.getSaveCacheInfo(urlString);
683                var rtn = bitsMarkingCollection.marking(aEvent.target,(info?info.URL:undefined));
684                if(this._isOpenCache && (typeof this._isOpenCache == "string" && this._isOpenCache == urlString)){
685                        this._isOpenCache = undefined;
686                        var markerid;
687                        var oid;
688                        var style;
689                        var dbtype;
690                        if(this._openobject){
691                                oid = this._openobject.oid;
692                                style = this._openobject.fid_style;
693                                dbtype = this._openobject.dbtype;
694                                markerid = bitsMarker.id_key + this._openobject.dbtype + this._openobject.oid;
695                                this._openobject = null;
696                        }else if(this.bitsItemView && this.bitsItemView.isChecked){
697                                var object = this.bitsItemView.object;
698                                if(object){
699                                        oid = object.oid;
700                                        style = object.fid_style;
701                                        dbtype = object.dbtype;
702                                        markerid = bitsMarker.id_key + object.dbtype + object.oid;
703                                }
704                        }else if(this.mcTreeHandler){
705                                var curIdx = this.mcTreeHandler.TREE.currentIndex;
706                                var curRes = null;
707                                if(curIdx>=0 && !this.mcTreeHandler.TREE.view.isContainer(curIdx)) curRes = this.mcTreeHandler.TREE.builderView.getResourceAtIndex(curIdx);
708                                if(curRes){
709                                        oid = this.DataSource.getProperty(curRes,"id");
710                                        style = this.DataSource.getProperty(curRes,"style");
711                                        dbtype = this.DataSource.getProperty(curRes,"dbtype");
712                                        markerid = bitsMarker.id_key + dbtype + oid;
713                                }
714                        }
715                        if(markerid){ if(!this.Common.doTopElement(markerid,style,oid,dbtype)) this.Common.doTopElementIMG(oid,dbtype); }
716                }
717                if(this.TREE && this.TREE.view && info && info.URL && this._cacheList2URL && this._cacheList2URL[info.URL] != undefined){
718                        this.TREE.currentIndex = this._cacheList2URL[info.URL];
719                        if(!this.TREE.view.selection.isSelected(this.TREE.currentIndex)) this.TREE.view.selection.select(this.TREE.currentIndex);
720                        this.TREE.treeBoxObject.ensureRowIsVisible(this.TREE.currentIndex);
721                }
722        },
723
724/////////////////////////////////////////////////////////////////////
725        tabselect : function(aEvent){
726                bitsAutocacheService._tabselect(aEvent);
727        },
728
729        _tabselect : function(aEvent){
730                this.disabledButton(this.gBrowser.selectedBrowser.contentDocument);
731        },
732
733/////////////////////////////////////////////////////////////////////
734        popupshowingMainContextmenu : function(aEvent){
735                if(aEvent.target.id != "bitsCacheContextmenuPopup") return;
736                this._explicitOriginalTarget = aEvent.explicitOriginalTarget;
737        },
738
739/////////////////////////////////////////////////////////////////////
740        popupshowingMainmenu : function(aEvent){
741                if(!aEvent.target.nodeName || aEvent.target.nodeName != "menupopup") return;
742                aEvent.stopPropagation();
743                if(aEvent.target.id == "bitsCacheMenuPopup"){
744                        var urlsdb = this._selectUrlDB();
745                        if(!urlsdb){
746                                var menuitem = document.createElement("menuitem");
747                                menuitem.setAttribute("label",this.STRING.getString("MSG_CACHEPAGE_NONE"));
748                                menuitem.setAttribute("disabled","true");
749                                aEvent.target.appendChild(menuitem);
750                                return;
751                        }
752                        var urlcnt;
753                        var histcnt;
754                        for(urlcnt=0;urlcnt<urlsdb.length;urlcnt++){
755                                var histsdb = this._selectHistoryDB({uid_url:urlsdb[urlcnt].uid_url});
756                                if(!histsdb) continue;
757                                histcnt = 0;
758                                urlsdb[urlcnt] = histsdb[histcnt];
759                        }
760                        if(urlsdb.length>0) urlsdb.sort(function(a, b) { return(parseInt(b.hid_date) - parseInt(a.hid_date)); });
761                        var topmenu_number = nsPreferences.getIntPref("wiredmarker.autocache.topmenu.number", 0);
762                        if(topmenu_number) urlsdb.length = topmenu_number;
763                        for(urlcnt=0;urlcnt<urlsdb.length;urlcnt++){
764                                var menu = document.createElement("menu");
765                                menu.setAttribute("label",urlsdb[urlcnt].hid_title);
766                                var icon = this.Database.getFavicon(urlsdb[urlcnt].uid_url);
767                                if(!icon) icon = "chrome://markingcollection/skin/defaultFavicon.png";
768                                if(icon){
769                                        menu.setAttribute("class","menu-iconic");
770                                        menu.setAttribute("image",icon);
771                                }
772                                menu.setAttribute("contextmenu","bitsCacheContextmenuPopup");
773                                menu.setAttribute("doc_url",urlsdb[urlcnt].uid_url);
774                                var menupopup = document.createElement("menupopup");
775                                menupopup.setAttribute("doc_url",urlsdb[urlcnt].uid_url);
776                                menu.appendChild(menupopup);
777                                aEvent.target.appendChild(menu);
778                        }
779                }else if(aEvent.target.hasAttribute("file_url") && aEvent.target.hasAttribute("doc_url")){  //この凊理は䜿甚しない
780                        var dir = this.Common.convertURLToFile(aEvent.target.getAttribute("file_url"));
781                        var doc_url = aEvent.target.getAttribute("doc_url");
782                        var temp_arr = [];
783                        var temp_entries = dir.directoryEntries;
784                        while(temp_entries.hasMoreElements()){
785                                var temp_entry = temp_entries.getNext().QueryInterface(Components.interfaces.nsILocalFile);
786                                if(!temp_entry.isDirectory() || (temp_entry.isDirectory() && temp_entry.leafName.match(/^\./))) continue;
787                                temp_arr.push(temp_entry);
788                        }
789                        if(temp_arr.length>0) temp_arr.sort(function(a, b) { return(parseInt(b.leafName) - parseInt(a.leafName)); });
790                        var itemcnt;
791                        for(itemcnt=0;itemcnt<temp_arr.length;itemcnt++){
792                                var objs = null;
793                                var menu = document.createElement("menu");
794                                if(temp_arr[itemcnt].leafName.match(/^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})$/)){
795                                        var item_label = RegExp.$1+"/"+RegExp.$2+"/"+RegExp.$3+" "+RegExp.$4+":"+RegExp.$5+":"+RegExp.$6;
796                                        var item_date = RegExp.$2+"/"+RegExp.$3+"/"+RegExp.$1+" "+RegExp.$4+":"+RegExp.$5+":"+RegExp.$6;
797                                        if(doc_url){
798                                                objs = this.Database.getObject({doc_url : doc_url, oid_date : item_date});
799                                                item_label += " (" + (objs?objs.length:0) + ")";
800                                        }
801                                        menu.setAttribute("label",item_label);
802                                }else{
803                                        menu.setAttribute("label",temp_arr[itemcnt].leafName);
804                                }
805                                menu.setAttribute("class","menu-iconic");
806                                menu.setAttribute("image","chrome://markingcollection/skin/defaultFavicon.png");
807                                var menupopup = document.createElement("menupopup");
808                                menupopup.setAttribute("oid_date",temp_arr[itemcnt].leafName);
809                                var info = this._getSaveCacheInfo(temp_arr[itemcnt]);
810                                if(info && info.URL) menupopup.setAttribute("doc_url",info.URL);
811                                menu.appendChild(menupopup);
812                                var contextmenu = document.getElementById("bitsCacheMenuPopupMenupopup");
813                                if(contextmenu && contextmenu.hasChildNodes()){
814                                        var childNode = contextmenu.firstChild;
815                                        while(childNode){
816                                                menupopup.appendChild(childNode.cloneNode(true));
817                                                childNode = childNode.nextSibling;
818                                        }
819                                }
820                                if(objs){
821                                        var menuseparator = document.createElement("menuseparator");
822                                        menupopup.appendChild(menuseparator);
823                                        var objcnt;
824                                        for(objcnt=0;objcnt<objs.length;objcnt++){
825                                                var menuitem = document.createElement("menuitem");
826                                                bitsMenuTree._setMenuitemObjectAttribute(menuitem,objs[objcnt]);
827                                                menuitem.addEventListener("command",this.commandTreeContextmenu,false);
828                                                menupopup.appendChild(menuitem);
829                                        }
830                                }
831                                aEvent.target.appendChild(menu);
832                        }
833                }else if(aEvent.target.hasAttribute("doc_url") && !aEvent.target.hasAttribute("oid_date")){
834                        var doc_url = aEvent.target.getAttribute("doc_url");
835                        var histsdb = this._selectHistoryDB({uid_url:doc_url});
836                        if(!histsdb){
837                                aEvent.target.setAttribute("hidden","true");
838                                return;
839                        }
840                        var histcnt;
841                        for(histcnt=0;histcnt<histsdb.length;histcnt++){
842                                var objs = null;
843                                var menu = document.createElement("menu");
844                                if(histsdb[histcnt].hid_date.match(/^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})$/)){
845                                        var item_label = RegExp.$1+"/"+RegExp.$2+"/"+RegExp.$3+" "+RegExp.$4+":"+RegExp.$5+":"+RegExp.$6;
846                                        var item_date = RegExp.$2+"/"+RegExp.$3+"/"+RegExp.$1+" "+RegExp.$4+":"+RegExp.$5+":"+RegExp.$6;
847                                        if(doc_url){
848                                                objs = this.Database.getObject({doc_url : doc_url, oid_date : item_date});
849                                                item_label += " (" + (objs?objs.length:0) + ")";
850                                        }
851                                        menu.setAttribute("label",item_label);
852                                }else{
853                                        menu.setAttribute("label",histsdb[histcnt].hid_date);
854                                }
855                                menu.setAttribute("class","menu-iconic");
856                                menu.setAttribute("image","chrome://markingcollection/skin/defaultFavicon.png");
857                                menu.setAttribute("doc_url",histsdb[histcnt].uid_url);
858                                menu.setAttribute("oid_date",histsdb[histcnt].hid_date);
859                                var menupopup = document.createElement("menupopup");
860                                menupopup.setAttribute("doc_url",histsdb[histcnt].uid_url);
861                                menupopup.setAttribute("oid_date",histsdb[histcnt].hid_date);
862                                menu.appendChild(menupopup);
863                                var contextmenu = document.getElementById("bitsCacheMenuPopupMenupopup");
864                                if(contextmenu && contextmenu.hasChildNodes()){
865                                        var childNode = contextmenu.firstChild;
866                                        while(childNode){
867                                                menupopup.appendChild(childNode.cloneNode(true));
868                                                childNode = childNode.nextSibling;
869                                        }
870                                }
871                                if(objs){
872                                        var menuseparator = document.createElement("menuseparator");
873                                        menupopup.appendChild(menuseparator);
874                                        var objcnt;
875                                        for(objcnt=0;objcnt<objs.length;objcnt++){
876                                                var menuitem = document.createElement("menuitem");
877                                                bitsMenuTree._setMenuitemObjectAttribute(menuitem,objs[objcnt]);
878                                                menuitem.addEventListener("command",this.commandTreeContextmenu,false);
879                                                menupopup.appendChild(menuitem);
880                                        }
881                                }
882                                aEvent.target.appendChild(menu);
883                        }
884                }else{
885                }
886
887        },
888
889/////////////////////////////////////////////////////////////////////
890        popuphidingMainmenu : function(aEvent){
891                if(!aEvent.target.nodeName || aEvent.target.nodeName != "menupopup") return;
892                aEvent.stopPropagation();
893                if(aEvent.target.id == "bitsCacheMenuPopup" || (!aEvent.target.hasAttribute("oid_date") && aEvent.target.hasAttribute("doc_url"))){
894                        while(aEvent.target.hasChildNodes()){
895                                aEvent.target.removeChild(aEvent.target.lastChild);
896                        }
897                }
898        },
899
900/////////////////////////////////////////////////////////////////////
901        popupshowingTreeContextmenu : function(aEvent){
902                if(!aEvent.target.nodeName || aEvent.target.nodeName != "popup") return;
903                if(!this._cacheList || this.TREE.currentIndex<0 || this._cacheList.length<this.TREE.currentIndex || !this._cacheList[this.TREE.currentIndex]) return;
904                var menuitem = this.CONTEXTMENU_OPENALL;
905                var sellist = this.getSelection();
906                if(sellist && sellist.length>1){
907                        if(menuitem) menuitem.setAttribute("hidden","true");
908                        return;
909                }else{
910                        if(menuitem) menuitem.removeAttribute("hidden");
911                }
912                var cacheinfo = this._cacheList[this.TREE.currentIndex];
913                var doc_url = cacheinfo.URL;
914                var temp_arr = this._selectHistoryDB({uid_url:doc_url});
915                var itemcnt;
916                for(itemcnt=0;itemcnt<temp_arr.length;itemcnt++){
917                        var objs = null;
918                        var menu = document.createElement("menu");
919                        if(temp_arr[itemcnt].hid_date.match(/^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})$/)){
920                                var item_label = RegExp.$1+"/"+RegExp.$2+"/"+RegExp.$3+" "+RegExp.$4+":"+RegExp.$5+":"+RegExp.$6;
921                                var item_date = RegExp.$2+"/"+RegExp.$3+"/"+RegExp.$1+" "+RegExp.$4+":"+RegExp.$5+":"+RegExp.$6;
922                                if(doc_url){
923                                        objs = this.Database.getObject({doc_url : doc_url, oid_date : item_date});
924                                        item_label += " (" + (objs?objs.length:0) + ")";
925                                }
926                                menu.setAttribute("label",item_label);
927                        }else{
928                                menu.setAttribute("label",temp_arr[itemcnt].hid_date);
929                        }
930                        menu.setAttribute("class","menu-iconic");
931                        menu.setAttribute("image","chrome://markingcollection/skin/defaultFavicon.png");
932                        var menupopup = document.createElement("menupopup");
933                        menupopup.setAttribute("oid_date",temp_arr[itemcnt].hid_date);
934                        menupopup.setAttribute("doc_url",doc_url);
935                        menu.appendChild(menupopup);
936                        var contextmenu = aEvent.target.ownerDocument.getElementById("bitsAutocacheTreeItemContextmenu");
937                        if(contextmenu && contextmenu.hasChildNodes()){
938                                var childNode = contextmenu.firstChild;
939                                while(childNode){
940                                        menupopup.appendChild(childNode.cloneNode(true));
941                                        childNode = childNode.nextSibling;
942                                }
943                        }
944                        if(objs){
945                                var menuseparator = document.createElement("menuseparator");
946                                menupopup.appendChild(menuseparator);
947                                var objcnt;
948                                for(objcnt=0;objcnt<objs.length;objcnt++){
949                                        var menuitem = document.createElement("menuitem");
950                                        bitsMenuTree._setMenuitemObjectAttribute(menuitem,objs[objcnt]);
951                                        menuitem.removeAttribute("contextmenu");
952                                        menuitem.addEventListener("command",this.commandTreeContextmenu,false);
953                                        menupopup.appendChild(menuitem);
954                                }
955                        }
956                        aEvent.target.appendChild(menu);
957                }
958        },
959
960/////////////////////////////////////////////////////////////////////
961        popuphidingTreeContextmenu : function(aEvent){
962                if(!aEvent.target.nodeName || aEvent.target.nodeName != "popup") return;
963                while(aEvent.target.hasChildNodes()){
964                        if(aEvent.target.lastChild.nodeName == "menuseparator") break;
965                        aEvent.target.removeChild(aEvent.target.lastChild);
966                }
967        },
968
969/////////////////////////////////////////////////////////////////////
970        commandTreeContextmenu : function(aEvent){
971                bitsAutocacheService._commandTreeContextmenu(aEvent);
972        },
973
974        _commandTreeContextmenu : function(aEvent){
975                this.openCache(aEvent, aEvent.shiftKey);
976        },
977
978/////////////////////////////////////////////////////////////////////
979        commandMainmenu : function(aEvent){
980                aEvent.stopPropagation();
981        },
982
983/////////////////////////////////////////////////////////////////////
984        popupshowing_menutree : function(aEvent){
985                bitsAutocacheService._popupshowing_menutree(aEvent);
986        },
987        _popupshowing_menutree : function(aEvent){
988                this.OPEN_MENUTREE.setAttribute("hidden","true");
989                var autocache_use = nsPreferences.copyUnicharPref("wiredmarker.autocache.use","valid");
990                if(autocache_use == "disabled") return;
991                this.OPEN_MENUTREE.removeAttribute("hidden");
992
993                if(!bitsMenuTree._explicitOriginalTarget){
994                        this.OPEN_MENUTREE.setAttribute("disabled","true");
995                        return;
996                }
997                var target = bitsMenuTree._explicitOriginalTarget;
998                var dir = this.getURLCacheDirFromTimeStamp(target.getAttribute("doc_url"),target.getAttribute("oid_date"));
999                if(!dir || !dir.exists()){
1000                        var histsdb = this._selectHistoryDB({uid_url:target.getAttribute("doc_url"),hid_date:target.getAttribute("oid_date")});
1001                        if(histsdb) dir = this.Common.convertURLToFile(histsdb[0].hid_path);
1002                }
1003                if(!dir || !dir.exists()){
1004                        this.OPEN_MENUTREE.setAttribute("disabled","true");
1005                }else{
1006                        this.OPEN_MENUTREE.removeAttribute("disabled");
1007                }
1008        },
1009
1010/////////////////////////////////////////////////////////////////////
1011        popupshowing : function(aEvent){
1012                bitsAutocacheService._popupshowing(aEvent);
1013        },
1014        _popupshowing : function(aEvent){
1015                var doc_url;
1016                var oid_date;
1017                this.OPEN1.setAttribute("hidden","true");
1018                this.OPEN2.setAttribute("hidden","true");
1019                this.OPEN3.setAttribute("hidden","true");
1020                var autocache_use = nsPreferences.copyUnicharPref("wiredmarker.autocache.use","valid");
1021                if(autocache_use == "disabled") return;
1022                if(this.bitsItemView && this.bitsItemView.isChecked){
1023                        this.OPEN2.removeAttribute("hidden");
1024                        var object = this.bitsItemView.object;
1025                        if(object){
1026                                doc_url = object.doc_url;
1027                                oid_date = object.oid_date;
1028                        }
1029                }else{
1030                        this.OPEN3.removeAttribute("hidden");
1031                        var curRes = null;
1032                        var curIdx = this.mcTreeHandler.TREE.currentIndex;
1033                        if(curIdx>=0 && !this.mcTreeHandler.TREE.view.isContainer(curIdx)){
1034                                this.OPEN1.removeAttribute("hidden");
1035                                curRes = this.mcTreeHandler.TREE.builderView.getResourceAtIndex(curIdx);
1036                        }
1037                        if(curRes){
1038                                doc_url = this.DataSource.getProperty(curRes,"uri");
1039                                oid_date = this.DataSource.getProperty(curRes,"date");
1040                        }
1041                }
1042                var dir;
1043                if(doc_url && oid_date){
1044                        dir = this.getURLCacheDirFromTimeStamp(doc_url,oid_date);
1045                        if(!dir || !dir.exists()){
1046                                var histsdb = this._selectHistoryDB({uid_url:doc_url,hid_date:oid_date});
1047                                if(histsdb) dir = this.Common.convertURLToFile(histsdb[0].hid_path);
1048                        }
1049                }
1050                if(!dir || !dir.exists()){
1051                        this.OPEN1.setAttribute("disabled","true");
1052                        this.OPEN2.setAttribute("disabled","true");
1053                        this.OPEN3.setAttribute("disabled","true");
1054                }else{
1055                        this.OPEN1.removeAttribute("disabled");
1056                        this.OPEN2.removeAttribute("disabled");
1057                        this.OPEN3.removeAttribute("disabled");
1058                }
1059        },
1060
1061/////////////////////////////////////////////////////////////////////
1062        openCache : function(aEvent, aTabbed){
1063                this._openobject = null;
1064                var dir;
1065                var doc_url;
1066                var oid_date;
1067                var oid;
1068                var pfid;
1069                var dbtype;
1070                var style;
1071                var source;
1072                if(aEvent.target.id == "bitsItemTreePopupCacheOpen" || aEvent.target.id == "bitsItemTreePopupCacheOpenNewtab"){
1073                        var object = this.bitsItemView.object;
1074                        if(object){
1075                                doc_url = object.doc_url;
1076                                oid_date = object.oid_date;
1077                                oid = object.oid;
1078                                pfid = object.pfid;
1079                                dbtype = object.dbtype;
1080                        }
1081                }else if(
1082                        aEvent.target.id == "mcPopupCacheOpen" ||
1083                        aEvent.target.id == "mcPopupCacheOpenNewtab" ||
1084                        aEvent.target.id == "mcPopupObjectCacheOpen" ||
1085                        aEvent.target.id == "mcPopupObjectCacheOpenNewtab"
1086                ){
1087                        var curIdx = this.mcTreeHandler.TREE.currentIndex;
1088                        var curRes = null;
1089                        if(curIdx>=0 && !this.mcTreeHandler.TREE.view.isContainer(curIdx)) curRes = this.mcTreeHandler.TREE.builderView.getResourceAtIndex(curIdx);
1090                        if(curRes){
1091                                doc_url = this.DataSource.getProperty(curRes,"uri");
1092                                oid_date = this.DataSource.getProperty(curRes,"date");
1093
1094                                oid = this.DataSource.getProperty(curRes,"id");
1095                                pfid = this.DataSource.getProperty(curRes,"pfid");
1096                                dbtype = this.DataSource.getProperty(curRes,"dbtype");
1097                        }
1098                }else if(aEvent.target.id == "bitsMenuTreeObjectContextmenuCacheOpen" || aEvent.target.id == "bitsMenuTreeObjectContextmenuCacheOpenNewtab"){
1099                        var target = bitsMenuTree._explicitOriginalTarget;
1100                        if(target){
1101                                doc_url = target.getAttribute("doc_url");
1102                                oid_date = target.getAttribute("oid_date");
1103                                this._openobject = this.Database.newObject(undefined,target.getAttribute("dbtype"));
1104                                if(this._openobject){
1105                                        var key;
1106                                        for(key in this._openobject){
1107                                                this._openobject[key] = target.getAttribute(key);
1108                                        }
1109                                        this._openobject.fid_style = target.getAttribute("fid_style");
1110                                        this._openobject.dbtype = target.getAttribute("dbtype");
1111
1112                                        oid = this._openobject.oid;
1113                                        pfid = this._openobject.pfid;
1114                                        dbtype = this._openobject.dbtype;
1115                                }
1116                        }
1117                }else if(
1118                        aEvent.target.id == "bitsCacheMenuPopupCacheOpen" || 
1119                        aEvent.target.id == "bitsCacheMenuPopupCacheOpenNewtab" ||
1120                        aEvent.target.id == "bitsAutocacheTreeContextmenuOpen" || 
1121                        aEvent.target.id == "bitsAutocacheTreeContextmenuNewtab"
1122                ){
1123                        var target = aEvent.target.parentNode;
1124                        if(target){
1125                                doc_url = target.getAttribute("doc_url");
1126                                oid_date = target.getAttribute("oid_date");
1127                                this._openobject = this.Database.newObject(undefined,target.getAttribute("dbtype"));
1128                                if(this._openobject){
1129                                        var key;
1130                                        for(key in this._openobject){
1131                                                this._openobject[key] = target.getAttribute(key);
1132                                        }
1133                                        this._openobject.fid_style = target.getAttribute("fid_style");
1134                                        this._openobject.dbtype = target.getAttribute("dbtype");
1135
1136                                        oid = this._openobject.oid;
1137                                        pfid = this._openobject.pfid;
1138                                        dbtype = this._openobject.dbtype;
1139                                }
1140                        }
1141                }else{
1142                        var target = aEvent.target;
1143                        if(target){
1144                                doc_url = target.getAttribute("doc_url");
1145                                oid_date = target.getAttribute("oid_date");
1146                                this._openobject = this.Database.newObject(undefined,target.getAttribute("dbtype"));
1147                                if(this._openobject){
1148                                        var key;
1149                                        for(key in this._openobject){
1150                                                this._openobject[key] = target.getAttribute(key);
1151                                        }
1152                                        this._openobject.fid_style = target.getAttribute("fid_style");
1153                                        this._openobject.dbtype = target.getAttribute("dbtype");
1154                                        if(this.mcTreeViewModeService) this.mcTreeViewModeService.selectTreeObject(this._openobject.oid,this._openobject.dbtype,this._openobject.pfid);
1155                                        oid = this._openobject.oid;
1156                                        pfid = this._openobject.pfid;
1157                                        dbtype = this._openobject.dbtype;
1158                                }
1159                        }
1160                }
1161                if(doc_url && oid_date){
1162                        dir = this.getURLCacheDirFromTimeStamp(doc_url,oid_date);
1163                        if(!dir || !dir.exists()){
1164                                if(oid_date && oid_date.match(/^(\d{2})\/(\d{2})\/(\d{4})\s+(\d{2}):(\d{2}):(\d{2})$/)) oid_date = RegExp.$3 + RegExp.$1 + RegExp.$2 + RegExp.$4 + RegExp.$5 + RegExp.$6;
1165                                var histsdb = this._selectHistoryDB({uid_url:doc_url,hid_date:oid_date});
1166                                if(histsdb) dir = this.Common.convertURLToFile(histsdb[0].hid_path);
1167                        }
1168                }
1169                if(!dir || !dir.exists()) return;
1170                var doc = this.gBrowser.contentDocument;
1171                var cur_uri = this.Common.getURLStringFromDocument(this.gBrowser.contentDocument);
1172                var res_uri = this.Common.convertFilePathToURL(dir.path);
1173                var loadFlag = false;
1174                if(aTabbed) loadFlag = aTabbed;
1175                if(!aTabbed){
1176                        if(this.gBrowser.browsers.length == 1 && res_uri != "" && cur_uri.indexOf(res_uri)<0){
1177                                loadFlag = true;
1178                        }else if(cur_uri == res_uri){
1179                                loadFlag = false;
1180                        }else{
1181                                loadFlag = true;
1182                                var i;
1183                                for(i=0;i<this.gBrowser.browsers.length;i++){
1184                                        var doc = this.gBrowser.browsers[i].contentDocument;
1185                                        var cur_uri = this.Common.getURLStringFromDocument(doc);
1186                                        if(cur_uri.indexOf(res_uri)>=0){
1187                                                loadFlag = false;
1188                                                this.gBrowser.tabContainer.selectedIndex = i;
1189                                                break;
1190                                        }
1191                                }
1192                        }
1193                        aTabbed = aEvent.shiftKey;
1194                }
1195                var info = this._getSaveCacheInfo(dir);
1196                if(loadFlag){
1197                        if(info && info.INDEX){
1198                                var indexFile = dir.clone();
1199                                indexFile.append(info.INDEX);
1200                                if(indexFile.exists()){
1201                                        var indexURLString = this.Common.convertFilePathToURL(indexFile.path);
1202                                        if(indexURLString){
1203                                                this._isOpenCache = indexURLString;
1204                                                var tab = this.Common.loadURL(indexURLString,aTabbed);
1205                                                if(tab && oid!=undefined && pfid!=undefined && dbtype!=undefined){
1206                                                        try{
1207                                                                var object = this.Database.getObject({oid:oid,pfid:pfid}, dbtype)[0];
1208                                                                if(object){
1209                                                                        oid = object.oid;
1210                                                                        pfid = object.pfid;
1211                                                                        dbtype = object.dbtype;
1212                                                                        style = object.fid_style;
1213                                                                        if(!object.oid_type.match(/^image\/(.+)$/)) source = bitsMarker.id_key+object.dbtype+object.oid;
1214                                                                        tab.setAttribute("Wired-Marker:oid",oid);
1215                                                                        tab.setAttribute("Wired-Marker:pfid",pfid);
1216                                                                        tab.setAttribute("Wired-Marker:dbtype",dbtype);
1217                                                                        tab.setAttribute("Wired-Marker:style",style);
1218                                                                        if(source) tab.setAttribute("Wired-Marker:source",source);
1219                                                                }
1220                                                        }catch(e){}
1221                                                }
1222
1223                                        }
1224                                }
1225                        }
1226                }else{
1227                        //マヌカヌぞスクロヌル
1228                        var markerid;
1229                        var oid;
1230                        var style;
1231                        var dbtype;
1232                        if(this._openobject){
1233                                oid = this._openobject.oid;
1234                                style = this._openobject.fid_style;
1235                                dbtype = this._openobject.dbtype;
1236                                markerid = bitsMarker.id_key + this._openobject.dbtype + this._openobject.oid;
1237                                this._openobject = null;
1238                        }else if(this.bitsItemView && this.bitsItemView.isChecked){
1239                                var object = this.bitsItemView.object;
1240                                if(object){
1241                                        oid = object.oid;
1242                                        style = object.fid_style;
1243                                        dbtype = object.dbtype;
1244                                        markerid = bitsMarker.id_key + object.dbtype + object.oid;
1245                                }
1246                        }else if(this.mcTreeHandler){
1247                                var curIdx = this.mcTreeHandler.TREE.currentIndex;
1248                                var curRes = null;
1249                                if(curIdx>=0 && !this.mcTreeHandler.TREE.view.isContainer(curIdx)) curRes = this.mcTreeHandler.TREE.builderView.getResourceAtIndex(curIdx);
1250                                if(curRes){
1251                                        oid = this.DataSource.getProperty(curRes,"id");
1252                                        style = this.DataSource.getProperty(curRes,"style");
1253                                        dbtype = this.DataSource.getProperty(curRes,"dbtype");
1254                                        markerid = bitsMarker.id_key + dbtype + oid;
1255                                }
1256                        }
1257                        if(markerid){ if(!this.Common.doTopElement(markerid,style,oid,dbtype)) this.Common.doTopElementIMG(oid,dbtype); }
1258                        if(this.TREE && this.TREE.view && info && info.URL && this._cacheList2URL && this._cacheList2URL[info.URL] != undefined){
1259                                this.TREE.currentIndex = this._cacheList2URL[info.URL];
1260                                if(!this.TREE.view.selection.isSelected(this.TREE.currentIndex)) this.TREE.view.selection.select(this.TREE.currentIndex);
1261                                this.TREE.treeBoxObject.ensureRowIsVisible(this.TREE.currentIndex);
1262                        }
1263                }
1264                aEvent.stopPropagation();
1265        },
1266
1267/////////////////////////////////////////////////////////////////////
1268        openCacheAll : function(aEvent, aTabbed){
1269                var doc_url;
1270                if(aEvent.target.id == "bitsCacheContextmenuMenuitemCacheOpenAll"){
1271                        var target = this._explicitOriginalTarget;
1272                        if(target) doc_url = target.getAttribute("doc_url");
1273                }else if(aEvent.target.id == this.idCONTEXTMENU_OPENALL){
1274                        if(!this._cacheList || this.TREE.currentIndex<0 || this._cacheList.length<this.TREE.currentIndex || !this._cacheList[this.TREE.currentIndex]) return;
1275                        var cacheinfo = this._cacheList[this.TREE.currentIndex];
1276                        if(cacheinfo && cacheinfo.URL) doc_url = cacheinfo.URL;
1277                }
1278                if(!doc_url) return;
1279                var dir_arr = [];
1280                var histdbs = this._selectHistoryDB({uid_url : doc_url});
1281                if(histdbs){
1282                        var i;
1283                        for(i=0;i<histdbs.length;i++){
1284                                var dir = this.Common.convertURLToFile(histdbs[i].hid_path);
1285                                if(dir.exists()) dir_arr.push(dir.clone());
1286                        }
1287                }
1288                var i;
1289                for(i=0;i<dir_arr.length;i++){
1290                        var dir = dir_arr[i].clone();
1291                        var info = this._getSaveCacheInfo(dir);
1292                        if(info && info.INDEX){
1293                                var indexFile = dir.clone();
1294                                indexFile.append(info.INDEX);
1295                                if(indexFile.exists()){
1296                                        var indexURLString = this.Common.convertFilePathToURL(indexFile.path);
1297                                        if(indexURLString) this.Common.loadURL(indexURLString,true);
1298                                }
1299                        }
1300                }
1301                aEvent.stopPropagation();
1302        },
1303
1304/////////////////////////////////////////////////////////////////////
1305        pastCache : function(aEvent){
1306                var dir;
1307                if(aEvent.target.id == "bitsItemTreePopupCachePast"){
1308                        var object = this.bitsItemView.object;
1309                        if(object) dir = this.getURLCacheDir(object.doc_url);
1310                }else if(aEvent.target.id == "mcPopupCachePast"){
1311                        var curIdx = this.mcTreeHandler.TREE.currentIndex;
1312                        var curRes = null;
1313                        if(curIdx>=0 && !this.mcTreeHandler.TREE.view.isContainer(curIdx)) curRes = this.mcTreeHandler.TREE.builderView.getResourceAtIndex(curIdx);
1314                        if(curRes) dir = this.getURLCacheDir(this.DataSource.getProperty(curRes,"uri"));
1315                }else if(aEvent.target.id == "bitsMenuTreeObjectContextmenuCachePast"){
1316                        var target = bitsMenuTree._explicitOriginalTarget;
1317                        if(target) dir = this.getURLCacheDir(target.getAttribute("doc_url"));
1318                }
1319                if(!dir || !dir.exists()) return;
1320                var dir_arr = [];
1321                var entries = dir.directoryEntries;
1322                while(entries.hasMoreElements()){
1323                        var entry = entries.getNext().QueryInterface(Components.interfaces.nsILocalFile);
1324                        if(!entry.isDirectory() || (entry.isDirectory() && entry.leafName.match(/^\./))) continue;
1325                        dir_arr.push(entry.clone());
1326                }
1327                if(dir_arr.length>0) dir_arr.sort(function(a, b) { return(parseInt(b.leafName) - parseInt(a.leafName)); });
1328                var result = {
1329                        accept : false,
1330                        list   : dir_arr,
1331                        dir    : dir,
1332                };
1333                window.openDialog("chrome://markingcollection/content/autocacheDialog.xul", "", "chrome,centerscreen,modal", result);
1334                if(result.accept){
1335                        if(result.acceptdir){
1336                                var dir = result.acceptdir.clone();
1337                                if(!dir || !dir.exists()) return;
1338                                var info = this._getSaveCacheInfo(dir);
1339                                if(info && info.INDEX){
1340                                        var indexFile = dir.clone();
1341                                        indexFile.append(info.INDEX);
1342                                        if(indexFile.exists()){
1343                                                var indexURLString = this.Common.convertFilePathToURL(indexFile.path);
1344                                                if(indexURLString){
1345                                                        this.Common.loadURL(indexURLString,true);
1346                                                        this._isOpenCache = indexURLString;
1347                                                }
1348                                        }
1349                                }
1350                        }
1351                }
1352                this.disabledButton();
1353                aEvent.stopPropagation();
1354        },
1355
1356/////////////////////////////////////////////////////////////////////
1357        removeCache : function(aEvent){
1358                try{
1359                        var doc_url;
1360                        var oid_date;
1361                        if(
1362                                aEvent.target.id == "bitsCacheMenuPopupCacheRemove" ||
1363                                aEvent.target.id == "bitsAutocacheTreeContextmenuRemove"
1364                        ){
1365                                var target = aEvent.target.parentNode;
1366                                if(!target || !target.hasAttribute("doc_url") || !target.hasAttribute("oid_date")) return;
1367                                if(target) dir = this.getURLCacheDirFromTimeStamp(target.getAttribute("doc_url"),target.getAttribute("oid_date"));
1368                                doc_url = target.getAttribute("doc_url");
1369                                oid_date = target.getAttribute("oid_date");
1370                        }
1371                        if(!doc_url || !oid_date) return;
1372                        var self = this;
1373                        setTimeout(function(){
1374                                try{
1375                                        if(!self.Common.confirm( self.STRING.getString("CONFIRM_DELETE") )) return;
1376                                        var histsdb = self._selectHistoryDB({uid_url:doc_url,hid_date:oid_date});
1377                                        if(!histsdb) return;
1378                                        var j;
1379                                        for(j=0;j<histsdb.length;j++){
1380                                                if(!self._deleteHistoryDB({uid:histsdb[j].uid,hid:histsdb[j].hid})) continue;
1381                                                var dir = self.Common.convertURLToFile(histsdb[j].hid_path);
1382                                                if(!dir || !dir.exists()) continue;
1383                                                var parent = dir.parent.clone();
1384                                                try{ dir.remove(true); }catch(e){}
1385                                                while(!self.Common.hasDirChilds(parent)){
1386                                                        var n_parent = parent.parent.clone();
1387                                                        try{ parent.remove(true); }catch(e){break;}
1388                                                        parent = n_parent;
1389                                                }
1390                                        }
1391                                        histsdb = self._selectHistoryDB({uid_url:doc_url});
1392                                        if(!histsdb) self._deleteUrlDB({uid_url:doc_url});
1393                                        self.refresh();
1394                                }catch(e){self._dump("bitsAutocacheService.removeCacheAll():"+ e);}
1395                        },0);
1396                }catch(e){self._dump("bitsAutocacheService.removeCacheAll():"+ e);}
1397                aEvent.stopPropagation();
1398        },
1399
1400/////////////////////////////////////////////////////////////////////
1401        removeCacheAll : function(aEvent){
1402                try{
1403                        var doc_urls = [];
1404                        if(aEvent.target.id == "bitsCacheContextmenuMenuitemCacheRemoveAll"){
1405                                var target = this._explicitOriginalTarget;
1406                                if(target){
1407                                        var doc_url = target.getAttribute("doc_url");
1408                                        if(doc_url) doc_urls.push(doc_url);
1409                                }
1410                        }else if(aEvent.target.id == "bitsAutocacheTreeContextmenuCacheRemoveAll"){
1411                                if(!this._cacheList || this.TREE.currentIndex<0 || this._cacheList.length<this.TREE.currentIndex || !this._cacheList[this.TREE.currentIndex]) return;
1412                                var sellist = this.getSelection();
1413                                var i;
1414                                for(i=0;i<sellist.length;i++){
1415                                        var cacheinfo = this._cacheList[sellist[i]];
1416                                        if(cacheinfo && cacheinfo.URL) doc_urls.push(cacheinfo.URL);
1417                                }
1418                        }
1419                        if(doc_urls.length==0) return;
1420                        var self = this;
1421                        setTimeout(function(){
1422                                try{
1423                                        if(!self.Common.confirm( self.STRING.getString("CONFIRM_DELETE") )) return;
1424                                        self._removeCacheAll(doc_urls);
1425                                }catch(e){self._dump("bitsAutocacheService.removeCacheAll():"+ e);}
1426                        },0);
1427                        aEvent.stopPropagation();
1428                }catch(e){
1429                        this._dump("bitsAutocacheService.removeCacheAll():"+ e);
1430                }
1431        },
1432
1433/////////////////////////////////////////////////////////////////////
1434        _removeCacheAll : function(aURLs){
1435                var self = this;
1436                if(!aURLs || aURLs.length == 0){
1437                        self.refresh();
1438                        return;
1439                }
1440                var doc_url = aURLs.shift();
1441                var i,j;
1442                var histsdb = self._selectHistoryDB({uid_url:doc_url});
1443                if(histsdb){
1444                        for(j=0;j<histsdb.length;j++){
1445                                var dir = self.Common.convertURLToFile(histsdb[j].hid_path);
1446                                if(!dir || !dir.exists()) continue;
1447                                var parent = dir.parent.clone();
1448                                try{ dir.remove(true); }catch(e){}
1449                                while(!self.Common.hasDirChilds(parent)){
1450                                        var n_parent = parent.parent.clone();
1451                                        try{ parent.remove(true); }catch(e){break;}
1452                                        parent = n_parent;
1453                                }
1454                        }
1455                        var rtn = self._deleteUrlDB({uid_url:doc_url});
1456                }
1457                setTimeout(function(){ self._removeCacheAll(aURLs); },0);
1458        },
1459
1460/////////////////////////////////////////////////////////////////////
1461        disabledButton : function(aDoc){
1462                var self = this;
1463                var btn = self.BUTTON;
1464                if(!btn || btn.hasAttribute("hidden")) return;
1465                if(!aDoc) aDoc = self.gBrowser.contentDocument;
1466                if(self._disabledTimer) clearTimeout(self._disabledTimer);
1467                self._disabledTimer = setTimeout(function(){
1468                        btn.setAttribute("disabled","true");
1469                        var urlString = self.Common.getURLStringFromDocument(aDoc);
1470                        if(!self.isCacheURL(urlString)){
1471                                var dir = self.getNewestCacheTimeStamp(urlString);
1472                                if(!dir) btn.removeAttribute("disabled");
1473                        }
1474                },500);
1475        },
1476
1477/////////////////////////////////////////////////////////////////////
1478        manuallyCache : function(aEvent){},
1479
1480/////////////////////////////////////////////////////////////////////
1481        toggleCacheView : function(aEvent){
1482                if(this.SPLITTER) this.SPLITTER.setAttribute("hidden","true");
1483                if(this.VBOX) this.VBOX.setAttribute("hidden","true");
1484                var btn = this.TOGGLE_BUTTON;
1485                if(!btn || btn.hasAttribute("hidden")) return;
1486                var self = this;
1487                setTimeout(function(){
1488                        self._pref.view.disp = btn.hasAttribute("checked");
1489                        if(!self._pref.view.disp) return;
1490                        if(self.SPLITTER) self.SPLITTER.removeAttribute("hidden");
1491                        if(self.VBOX) self.VBOX.removeAttribute("hidden");
1492                },0);
1493        },
1494
1495/////////////////////////////////////////////////////////////////////
1496        createCache : function(aURLString, aForced, aRebuild){
1497                if(aForced == undefined) aForced = false;
1498                if(aRebuild == undefined) aRebuild = true;
1499                var use = nsPreferences.copyUnicharPref("wiredmarker.autocache.use", "valid");
1500                if(use == "disabled" && !aForced) return;
1501                if(aURLString){
1502                        var urlString = this.Common.getURLStringFromDocument(this.gBrowser.contentDocument);
1503                        if(aURLString != urlString) return;
1504                }else{
1505                        aURLString = this.Common.getURLStringFromDocument(this.gBrowser.contentDocument);
1506                }
1507                var timeStamp = this.getURLTimeStamp(aURLString);
1508                var dir = this.getURLCacheDirFromTimeStamp(aURLString,timeStamp);
1509                if(!aForced && dir && dir.exists()) return false;
1510                var self = this;
1511                setTimeout(function(){
1512                        var cache = new bitsAutocacheDocument();
1513                        cache.exec(aForced);
1514                        cache.done();
1515                        cache = undefined;
1516                        self.disabledButton();
1517                        if(aRebuild) self.refresh(true);
1518                },100);
1519        },
1520
1521/////////////////////////////////////////////////////////////////////
1522// TREE 衚瀺制埡関連
1523/////////////////////////////////////////////////////////////////////
1524        get rowCount(){
1525                return (this._cacheList?this._cacheList.length:0);
1526        },
1527        getCellText : function(row,column){
1528                if(column.id == this.idTREE_ITITLE){
1529                        return this._cacheList[row].TITLE;
1530                }else if(column.id == this.idTREE_IURL){
1531                        return this._cacheList[row].URL;
1532                }else if(column.id == this.idTREE_IDATE){
1533                        if(!this._cacheList) return null;
1534                        if(this._cacheList[row].DATE.match(/^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})$/)){
1535                                return RegExp.$1+"/"+RegExp.$2+"/"+RegExp.$3+" "+RegExp.$4+":"+RegExp.$5+":"+RegExp.$6;
1536                        }else{
1537                                return this._cacheList[row].DATE;
1538                        }
1539                }else if(column.id == this.idTREE_ICACHE){
1540                        return this._cacheList[row].CACHE_NUM;
1541                }else if(column.id == this.idTREE_IMARKER){
1542                        return this._cacheList[row].MARKER_NUM;
1543                }else if(column.id == this.idTREE_ICACHESIZE){
1544                        return this.Common.formatFileSize(this._cacheList[row].CACHE_SIZE);
1545                }else{
1546                        return null;
1547                }
1548        },
1549        setTree: function(treebox){ this.treebox = treebox; },
1550        isContainer: function(row){ return false; },
1551        isSeparator: function(row){ return false; },
1552        isSorted: function(){ return true; },
1553        getLevel: function(row){ return 0; },
1554        getImageSrc: function(row,column){
1555                var icon;
1556                if(column.id != this.idTREE_IFAVICON) return icon;
1557                if(!this._cacheList) return icon;
1558                if(!this._cacheList[row]) return icon;
1559                var info = this._cacheList[row];
1560                var icon = null;
1561                if(info && info.URL) icon = this.Database.getFavicon(info.URL);
1562                if(!icon) icon = "chrome://markingcollection/skin/defaultFavicon.png";
1563                return icon;
1564        },
1565        getRowProperties: function(row,prop){},
1566        getCellProperties: function(row, column, prop) {
1567                if(column.id == this.idTREE_IFAVICON){
1568                        var aserv=Components.classes["@mozilla.org/atom-service;1"].getService(Components.interfaces.nsIAtomService);
1569                        prop.AppendElement(aserv.getAtom("ItemView"));
1570                        if(this._cacheList[row]) prop.AppendElement(aserv.getAtom("ItemViewImage"));
1571                }
1572        },
1573        getColumnProperties: function(column, element, prop) {},
1574        cycleHeader : function(col){},
1575        setCellText : function(row,column,text){},
1576  getParentIndex: function(idx) { return -1; },
1577        canDrop : function(index, orient){ return false; },
1578        drop : function(row, orient){},
1579        selectRowFromURL : function(aURLString){
1580                var rtn = false;
1581                try{
1582                        if(!aURLString || !this.TREE || !this.TREE.view) return rtn;
1583                        aURLString = this.convertCacheURLToOriginalURL(aURLString);
1584                        var row = this._cacheList2URL[aURLString];
1585                        if(row != undefined){
1586                                this.TREE.currentIndex = row;
1587                                if(!this.TREE.view.selection.isSelected(this.TREE.currentIndex)) this.TREE.view.selection.select(this.TREE.currentIndex);
1588                                this.TREE.focus();
1589                                this.TREE.treeBoxObject.ensureRowIsVisible(this.TREE.currentIndex);
1590                                rtn = true;
1591                        }
1592                }catch(e){
1593                        rtn = false;
1594                        bitsAutocacheService._dump("bitsAutocacheDocument.selectRowFromURL():"+e);
1595                }
1596                return rtn;
1597        },
1598
1599/////////////////////////////////////////////////////////////////////
1600        refresh : function(aForced,aTimeout){
1601                if(!this._refreshFlag) return;
1602                var self = this;
1603                if(self._refreshTimer) clearTimeout(self._refreshTimer);
1604                self._refreshTimer = setTimeout(function(){ self._refresh(); },(aForced?0: (aTimeout!=undefined?aTimeout:250) ));
1605        },
1606        _refresh : function(){
1607                if(!this.TREE) return;
1608                var idx = this.TREE.currentIndex;
1609                var rows = this.getSelection();
1610                this.rebuild();
1611                try{this.TREE.currentIndex=idx;}catch(e){}
1612                if(!this._cacheList) return;
1613                try{
1614                        var i;
1615                        for(i=0;i<rows.length;i++){
1616                                if(!this.TREE.view.selection.isSelected(rows[i])) this.TREE.view.selection.select(rows[i]);
1617                        }
1618                }catch(e){}
1619                this.TREE.blur();
1620                this.TREE.focus();
1621        },
1622
1623/////////////////////////////////////////////////////////////////////
1624        rebuild : function(){
1625                if(!this.TREE) return;
1626                try{this.TREE.currentIndex = -1;}catch(e){}
1627                try{this.TREE.view.selection.clearSelection();}catch(e){}
1628                if(this._cacheList){
1629                        this._cacheList.length = 0;
1630                        this._cacheList = undefined;
1631                        this._cacheList2URL = undefined;
1632                }
1633                this.TREE.removeAttribute("flex");
1634                try{
1635                        var urlsdb = this._selectUrlDB();
1636                        if(urlsdb){
1637                                var i;
1638                                var j;
1639                                for(i=0;i<urlsdb.length;i++){
1640                                        var histsdb = this._selectHistoryDB({uid_url : urlsdb[i].uid_url});
1641                                        if(histsdb){
1642                                                var info = {
1643                                                        URL        : urlsdb[i].uid_url,
1644                                                        TITLE      : histsdb[0].hid_title,
1645                                                        INDEX      : histsdb[0].hid_file,
1646                                                        PATH       : histsdb[0].hid_path,
1647                                                        DATE       : histsdb[0].hid_date,
1648                                                        CACHE_NUM  : histsdb.length,
1649                                                        CACHE_SIZE : 0,
1650                                                        MARKER_NUM : 0
1651                                                };
1652                                                if(urlsdb[i].uid_url){
1653                                                        var objcnt;
1654                                                        for(objcnt=0;objcnt<histsdb.length;objcnt++){
1655                                                                if(histsdb[objcnt].hid_date.match(/^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})$/)){
1656                                                                        var item_date = RegExp.$2+"/"+RegExp.$3+"/"+RegExp.$1+" "+RegExp.$4+":"+RegExp.$5+":"+RegExp.$6;
1657                                                                        var objs = this.Database.getObject({doc_url : urlsdb[i].uid_url, oid_date : item_date});
1658                                                                        if(objs) info.MARKER_NUM += objs.length;
1659                                                                }
1660                                                                info.CACHE_SIZE += parseInt(histsdb[objcnt].hid_filesize);
1661                                                        }
1662                                                }
1663                                                if(!this._cacheList) this._cacheList = [];
1664                                                this._cacheList.push(info);
1665                                        }
1666                                }
1667                        }
1668                }catch(e){
1669                        this._dump("bitsAutocacheService.rebuild():"+e);
1670                        this._cacheList = undefined;
1671                        this._cacheList2URL = undefined;
1672                }
1673                if(this._cacheList){
1674                        if(this.VSB.checked && this.VSM.value != ""){
1675                                var regexp = new RegExp(this.VSM.value,"img");
1676                                this._cacheList = this._cacheList.filter(
1677                                        function(element, index, array) {
1678                                                return regexp.test(element.TITLE) || regexp.test(element.URL);
1679                                        }
1680                                );
1681                        }
1682                        var self = this;
1683                        this._cacheList.sort(
1684                                function(a,b){
1685                                        var direction = "";
1686                                        if(
1687                                                self.TREE_IFAVICON.hasAttribute("sortDirection") ||
1688                                                self.TREE_IURL.hasAttribute("sortDirection")
1689                                        ){
1690                                                if(self.TREE_IFAVICON.hasAttribute("sortDirection")){
1691                                                        direction = self.TREE_IFAVICON.getAttribute("sortDirection");
1692                                                }else if(self.TREE_IURL.hasAttribute("sortDirection")){
1693                                                        direction = self.TREE_IURL.getAttribute("sortDirection");
1694                                                }
1695                                                if(direction == "ascending"){
1696                                                        if(a.URL < b.URL) return -1;
1697                                                        if(a.URL > b.URL) return 1;
1698                                                }else if(direction == "descending"){
1699                                                        if(a.URL < b.URL) return 1;
1700                                                        if(a.URL > b.URL) return -1;
1701                                                }
1702                                        }else if(self.TREE_ITITLE.hasAttribute("sortDirection")){
1703                                                direction = self.TREE_ITITLE.getAttribute("sortDirection");
1704                                                if(direction == "ascending"){
1705                                                        if(a.TITLE < b.TITLE) return -1;
1706                                                        if(a.TITLE > b.TITLE) return 1;
1707                                                }else if(direction == "descending"){
1708                                                        if(a.TITLE < b.TITLE) return 1;
1709                                                        if(a.TITLE > b.TITLE) return -1;
1710                                                }
1711                                        }else if(self.TREE_IDATE.hasAttribute("sortDirection")){
1712                                                direction = self.TREE_IDATE.getAttribute("sortDirection");
1713                                                if(direction == "ascending"){
1714                                                        if(parseInt(a.DATE) < parseInt(b.DATE)) return -1;
1715                                                        if(parseInt(a.DATE) > parseInt(b.DATE)) return 1;
1716                                                }else if(direction == "descending"){
1717                                                        if(parseInt(a.DATE) < parseInt(b.DATE)) return 1;
1718                                                        if(parseInt(a.DATE) > parseInt(b.DATE)) return -1;
1719                                                }
1720                                        }else if(self.TREE_ICACHE.hasAttribute("sortDirection")){
1721                                                direction = self.TREE_ICACHE.getAttribute("sortDirection");
1722                                                if(direction == "ascending"){
1723                                                        if(parseInt(a.CACHE_NUM) < parseInt(b.CACHE_NUM)) return -1;
1724                                                        if(parseInt(a.CACHE_NUM) > parseInt(b.CACHE_NUM)) return 1;
1725                                                }else if(direction == "descending"){
1726                                                        if(parseInt(a.CACHE_NUM) < parseInt(b.CACHE_NUM)) return 1;
1727                                                        if(parseInt(a.CACHE_NUM) > parseInt(b.CACHE_NUM)) return -1;
1728                                                }
1729                                        }else if(self.TREE_IMARKER.hasAttribute("sortDirection")){
1730                                                direction = self.TREE_IMARKER.getAttribute("sortDirection");
1731                                                if(direction == "ascending"){
1732                                                        if(parseInt(a.MARKER_NUM) < parseInt(b.MARKER_NUM)) return -1;
1733                                                        if(parseInt(a.MARKER_NUM) > parseInt(b.MARKER_NUM)) return 1;
1734                                                }else if(direction == "descending"){
1735                                                        if(parseInt(a.MARKER_NUM) < parseInt(b.MARKER_NUM)) return 1;
1736                                                        if(parseInt(a.MARKER_NUM) > parseInt(b.MARKER_NUM)) return -1;
1737                                                }
1738                                        }else if(self.TREE_ICACHESIZE.hasAttribute("sortDirection")){
1739                                                direction = self.TREE_ICACHESIZE.getAttribute("sortDirection");
1740                                                if(direction == "ascending"){
1741                                                        if(parseInt(a.CACHE_SIZE) < parseInt(b.CACHE_SIZE)) return -1;
1742                                                        if(parseInt(a.CACHE_SIZE) > parseInt(b.CACHE_SIZE)) return 1;
1743                                                }else if(direction == "descending"){
1744                                                        if(parseInt(a.CACHE_SIZE) < parseInt(b.CACHE_SIZE)) return 1;
1745                                                        if(parseInt(a.CACHE_SIZE) > parseInt(b.CACHE_SIZE)) return -1;
1746                                                }
1747                                        }else{
1748                                                if(parseInt(a.DATE) < parseInt(b.DATE)) return 1;
1749                                                if(parseInt(a.DATE) > parseInt(b.DATE)) return -1;
1750                                        }
1751                                        return 0;
1752                                }
1753                        );
1754                        this.TREE.setAttribute("flex","1");
1755                        if(!this._cacheList2URL) this._cacheList2URL = {};
1756                        var i;
1757                        for(i=0;i<this._cacheList.length;i++){
1758                                if(!this._cacheList[i].URL) continue;
1759                                this._cacheList2URL[this._cacheList[i].URL] = i;
1760                        }
1761                }
1762                this.TREE.setAttribute("hidden",true);
1763                if(this.TREE.hasAttribute("flex")){
1764                        var self = this;
1765                        setTimeout(function(){
1766                                if(!self.TREE) return;
1767                                self.TREE.view = self;
1768                                self.TREE.removeAttribute("hidden");
1769                                self.VSB.removeAttribute("disabled");
1770                                if(self.VSB.hasAttribute("checked")) self.VSM.removeAttribute("disabled");
1771                        },0);
1772                }else{
1773                        this.VSB.setAttribute("disabled",true);
1774                        this.VSM.setAttribute("disabled",true);
1775                }
1776        },
1777
1778/////////////////////////////////////////////////////////////////////
1779        getSelection : function(){
1780                if(!this.TREE || !this.TREE.view) return undefined;
1781                var ret = [];
1782                var rc;
1783                var i;
1784                for(rc=0;rc<this.TREE.view.selection.getRangeCount();rc++){
1785                        var start = {}, end = {};
1786                        this.TREE.view.selection.getRangeAt(rc, start, end);
1787                        for(i=start.value;i<= end.value;i++){
1788                                if(!this.TREE.view.selection.isSelected(i)) continue;
1789                                ret.push(i);
1790                        }
1791                }
1792                return ret;
1793        },
1794
1795/////////////////////////////////////////////////////////////////////
1796        onSearchButtonCommand : function(aEvent){
1797                var self = this;
1798                var checked = this.VSB.hasAttribute("checked");
1799                if(checked){
1800                        this.VSM.removeAttribute("disabled");
1801                        setTimeout(function(){
1802                                self.VSM.focus();
1803                                self.refresh();
1804                        },0);
1805                }else{
1806                        this.VSM.blur();
1807                        this.VSM.setAttribute("disabled","true");
1808                        setTimeout(function(){
1809                                self.refresh();
1810                        },0);
1811                }
1812        },
1813
1814/////////////////////////////////////////////////////////////////////
1815        onSearchKeyPress : function(aEvent){
1816                switch(aEvent.keyCode){
1817                        case aEvent.DOM_VK_RETURN :
1818                                this.refresh();
1819                                break;
1820                        default:
1821                                break;
1822                }
1823        },
1824
1825/////////////////////////////////////////////////////////////////////
1826// TREE むベント関連
1827/////////////////////////////////////////////////////////////////////
1828        onClick : function(aEvent){
1829                if(aEvent.button != 0) return;
1830                if(aEvent.altKey || aEvent.shiftKey || aEvent.ctrlKey) return;
1831                if(aEvent.target.id){
1832                        if(aEvent.target.id != this.idTREE_IFAVICON)   this.TREE_IFAVICON.removeAttribute("sortDirection");
1833                        if(aEvent.target.id != this.idTREE_IURL)       this.TREE_IURL.removeAttribute("sortDirection");
1834                        if(aEvent.target.id != this.idTREE_ITITLE)     this.TREE_ITITLE.removeAttribute("sortDirection");
1835                        if(aEvent.target.id != this.idTREE_IDATE)      this.TREE_IDATE.removeAttribute("sortDirection");
1836                        if(aEvent.target.id != this.idTREE_ICACHE)     this.TREE_ICACHE.removeAttribute("sortDirection");
1837                        if(aEvent.target.id != this.idTREE_IMARKER)    this.TREE_IMARKER.removeAttribute("sortDirection");
1838                        if(aEvent.target.id != this.idTREE_ICACHESIZE) this.TREE_ICACHESIZE.removeAttribute("sortDirection");
1839                        if(!aEvent.target.hasAttribute("sortDirection")){
1840                                aEvent.target.setAttribute("sortDirection","ascending");
1841                        }else if(aEvent.target.getAttribute("sortDirection") == "ascending"){
1842                                aEvent.target.setAttribute("sortDirection","descending");
1843                        }else{
1844                                aEvent.target.removeAttribute("sortDirection");
1845                        }
1846                        this.refresh(true);
1847                        return;
1848                }
1849        },
1850
1851/////////////////////////////////////////////////////////////////////
1852        onDblClick : function(aEvent){
1853                if(aEvent.button != 0) return;
1854                if(aEvent.altKey) return;
1855                var row = {};
1856                var col = {};
1857                var obj = {};
1858                this.TREE.treeBoxObject.getCellAt(aEvent.clientX, aEvent.clientY, row, col, obj);
1859                if(row.value<0){
1860                        this.TREE.view.selection.clearSelection();
1861                        return;
1862                }
1863                this.open(aEvent);
1864        },
1865
1866        open : function(aEvent){
1867                if(this.bitsItemView && this.bitsItemView.isChecked){
1868                        this.bitsItemView.TREE.currentIndex = -1;
1869                        try{this.bitsItemView.TREE.view.selection.clearSelection();}catch(e){}
1870                }else if(this.mcTreeHandler){
1871                        var curIdx = this.mcTreeHandler.TREE.currentIndex;
1872                        if(curIdx>=0 && !this.mcTreeHandler.TREE.view.isContainer(curIdx)){
1873                                this.mcTreeHandler.TREE.currentIndex = -1;
1874                                try{this.mcTreeHandler.TREE.view.selection.clearSelection();}catch(e){}
1875                        }
1876                }
1877
1878                try{
1879                        var cacheinfo = this._cacheList[this.TREE.currentIndex];
1880                        var dir = this.getURLCacheDirFromTimeStamp(cacheinfo.URL,cacheinfo.DATE);
1881                        if(!dir || !dir.exists()){
1882                                var histsdb = this._selectHistoryDB({uid_url:cacheinfo.URL,hid_date:cacheinfo.DATE});
1883                                if(histsdb) dir = this.Common.convertURLToFile(histsdb[0].hid_path);
1884                        }
1885                        if(!dir || !dir.exists()) return;
1886                        var doc = this.gBrowser.contentDocument;
1887                        var cur_uri = this.Common.getURLStringFromDocument(this.gBrowser.contentDocument);
1888                        var res_uri = this.Common.convertFilePathToURL(dir.parent.path);
1889                        var aTabbed = false;
1890                        var loadFlag = false;
1891                        if(aTabbed) loadFlag = aTabbed;
1892                        if(!aTabbed){
1893                                if(this.gBrowser.browsers.length == 1 && res_uri != "" && cur_uri.indexOf(res_uri)<0){
1894                                        loadFlag = true;
1895                                }else if(cur_uri == res_uri){
1896                                        loadFlag = false;
1897                                }else{
1898                                        loadFlag = true;
1899                                        var i;
1900                                        for(i=0;i<this.gBrowser.browsers.length;i++){
1901                                                var doc = this.gBrowser.browsers[i].contentDocument;
1902                                                var cur_uri = this.Common.getURLStringFromDocument(doc);
1903                                                if(cur_uri.indexOf(res_uri)>=0){
1904                                                        if(cur_uri == res_uri) loadFlag = false;
1905                                                        this.gBrowser.tabContainer.selectedIndex = i;
1906                                                        break;
1907                                                }
1908                                        }
1909                                }
1910                                aTabbed = aEvent.shiftKey | aEvent.ctrlKey;
1911                        }
1912                        if(loadFlag){
1913                                if(cacheinfo && cacheinfo.INDEX){
1914                                        var indexFile = dir.clone();
1915                                        indexFile.append(cacheinfo.INDEX);
1916                                        if(indexFile.exists()){
1917                                                var indexURLString = this.Common.convertFilePathToURL(indexFile.path);
1918                                                if(indexURLString){
1919                                                        this.Common.loadURL(indexURLString,aTabbed);
1920                                                        this._isOpenCache = indexURLString;
1921                                                }
1922                                        }
1923                                }
1924                        }
1925                        aEvent.stopPropagation();
1926                }catch(e){
1927                        this._dump("bitsAutocacheService.onDblClick():"+e);
1928                }
1929        },
1930
1931        remove : function(aEvent){
1932                var sellist = this.getSelection();
1933                var self = this;
1934                setTimeout(function(){
1935                        if(!self.Common.confirm( self.STRING.getString("CONFIRM_DELETE") )) return;
1936                        if(sellist){
1937                                var i,j;
1938                                for(i=0;i<sellist.length;i++){
1939                                        var basedir = null;
1940                                        var cacheinfo = self._cacheList[sellist[i]];
1941                                        if(!cacheinfo || !cacheinfo.URL) continue;
1942                                        var histddb = self._selectHistoryDB({uid_url:cacheinfo.URL});
1943                                        if(histddb){
1944                                                for(j=0;j<histddb.length;j++){
1945                                                        var histdir = self.Common.convertURLToFile(histddb[j].hid_path);
1946                                                        if(!histdir || !histdir.exists()) continue;
1947                                                        try{ histdir.remove(true); }catch(e){}
1948                                                        var parent = histdir.parent.clone();
1949                                                        while(!self.Common.hasDirChilds(parent)){
1950                                                                var n_parent = parent.parent.clone();
1951                                                                try{ parent.remove(true); }catch(e){break;}
1952                                                                parent = n_parent;
1953                                                        }
1954                                                }
1955                                        }
1956                                        self._deleteUrlDB({uid_url:cacheinfo.URL});
1957                                }
1958                        }
1959                        self.refresh();
1960                },0);
1961                aEvent.stopPropagation();
1962        },
1963
1964/////////////////////////////////////////////////////////////////////
1965        onKeyPress : function(aEvent){
1966                switch(aEvent.keyCode){
1967                        case aEvent.DOM_VK_RETURN :
1968                                aEvent.preventDefault();
1969                                this.open(aEvent);
1970                                break;
1971                        case aEvent.DOM_VK_DELETE :
1972                                if(!(aEvent.ctrlKey || aEvent.shiftKey)){
1973                                        aEvent.preventDefault();
1974                                        this.remove(aEvent);
1975                                }
1976                                break;
1977                        default:
1978                                break;
1979                }
1980        },
1981
1982/////////////////////////////////////////////////////////////////////
1983        onKeyDown : function(aEvent){
1984                switch(aEvent.keyCode){
1985                        case aEvent.DOM_VK_A :
1986                                if(aEvent.ctrlKey){
1987                                        aEvent.preventDefault();
1988                                        this.TREE.view.selection.selectAll();
1989                                }
1990                                break;
1991                        default:
1992                                break;
1993                }
1994        },
1995
1996/////////////////////////////////////////////////////////////////////
1997// 1 バむトに察しお 2 ぀の 16 進数コヌドを返す。
1998/////////////////////////////////////////////////////////////////////
1999        _toHexString : function(charCode){
2000                return("0" + charCode.toString(16)).slice(-2);
2001        },
2002
2003/////////////////////////////////////////////////////////////////////
2004        _string2CryptoHash : function(aString){
2005                if(aString == undefined || aString == "") return undefined;
2006                try{
2007                        var str = aString;
2008                        var converter = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
2009                        converter.charset = "UTF-8";
2010                        var result = {};
2011                        var data = converter.convertToByteArray(str, result);
2012                        var ch = Components.classes["@mozilla.org/security/hash;1"].createInstance(Components.interfaces.nsICryptoHash);
2013                        ch.init(ch.MD5);
2014                        ch.update(data, data.length);
2015                        var hash = ch.finish(false);
2016                        var s = "";
2017                        var i;
2018                        for(i in hash){
2019                                if(typeof hash[i] == "function") continue;
2020                                s += this._toHexString(hash.charCodeAt(i));
2021                        }
2022                        var top = s.substr(0,2);
2023                        var regexp = new RegExp(top+"$","mg");
2024                        while(s.match(regexp)) s = s.replace(regexp,"");
2025                        return s;
2026                }catch(ex){
2027                        return undefined;
2028                }
2029        },
2030
2031/////////////////////////////////////////////////////////////////////
2032        readFile : function(aFile){
2033                if(!aFile || !aFile.exists()) return undefined;
2034                try {
2035                        var istream = Components.classes['@mozilla.org/network/file-input-stream;1'].createInstance(Components.interfaces.nsIFileInputStream);
2036                        istream.init(aFile, 1, 0, false);
2037                        var sstream = Components.classes['@mozilla.org/scriptableinputstream;1'].createInstance(Components.interfaces.nsIScriptableInputStream);
2038                        sstream.init(istream);
2039                        var content = sstream.read(sstream.available());
2040                        sstream.close();
2041                        istream.close();
2042                        if(content.indexOf("%09")>=0){
2043                                content = unescape(content);
2044                        }else{
2045                                content = this.Common.convertToUnicode(content,"UTF-8");
2046                        }
2047                        return content;
2048                }catch(ex){
2049                        this._dump("bitsAutocacheService ERROR: readFile():" + ex);
2050                        return undefined;
2051                }
2052        },
2053
2054/////////////////////////////////////////////////////////////////////
2055        writeFile : function(aFile, aContent){
2056                if(aFile.exists()) aFile.remove(false);
2057                try {
2058                        aFile.create(aFile.NORMAL_FILE_TYPE, 0666);
2059                        var content = this.Common.convertFormUnicode(aContent,"UTF-8");
2060                        var ostream = Components.classes['@mozilla.org/network/file-output-stream;1'].createInstance(Components.interfaces.nsIFileOutputStream);
2061                        ostream.init(aFile, 2, 0x200, false);
2062                        ostream.write(content, content.length);
2063                        ostream.close();
2064                }catch(ex){
2065                        this._dump("bitsAutocacheService ERROR: Failed to write file: " + aFile.path + "["+ ex + "]");
2066                }
2067        },
2068
2069/////////////////////////////////////////////////////////////////////
2070// Database関連
2071/////////////////////////////////////////////////////////////////////
2072        _getFileDB : function(){
2073                var dbFile = this.Common.getExtensionDir().clone();
2074                dbFile.append(this._dbName);
2075                return dbFile;
2076        },
2077
2078/////////////////////////////////////////////////////////////////////
2079        _connectDB : function(){
2080                var dbFile = this._getFileDB();
2081                if(!this._dbConn && dbFile) this._dbConn = this.Common.STORAGE.openDatabase(dbFile);
2082                this._createTableDB();
2083                return (this._dbConn?true:false);
2084        },
2085
2086/////////////////////////////////////////////////////////////////////
2087        _disconnectDB : function(aVacuum){
2088                var dbFile = this._dbConn.databaseFile.clone();
2089                this._backupDB(dbFile);
2090
2091                if(aVacuum == undefined) aVacuum = false;
2092                try{ if(aVacuum) this._vacuumDB(); }catch(ex){};
2093                this._dbConn = undefined;
2094        },
2095
2096/////////////////////////////////////////////////////////////////////
2097        _vacuumDB : function(){
2098                try{
2099                        this._dbConn.executeSimpleSQL("VACUUM");
2100                }catch(ex){
2101                        this._dump("bitsAutocacheService.vacuumDB():"+ex);
2102                };
2103        },
2104
2105/////////////////////////////////////////////////////////////////////
2106        _backupDB : function(aFile){
2107                try{
2108                        var bDir = bitsObjectMng.Common.getExtensionDir();
2109                        bDir.append("backup");
2110                        var aBackupFile = bDir.clone();
2111                        aBackupFile.append(aFile.leafName+".1");
2112                        if(aBackupFile.exists() && aFile.exists()){
2113                                if(aBackupFile.lastModifiedTime == aFile.lastModifiedTime) return;
2114                        }
2115                        for(var i=4;i>0;i--){
2116                                var aFile1 = bDir.clone();
2117                                aFile1.append(aFile.leafName+"."+i);
2118                                if(!aFile1.exists()) continue;
2119                                var aFile2 = bDir.clone();
2120                                aFile2.append(aFile.leafName+"."+(i+1));
2121                                if(aFile2.exists()) aFile2.remove(true);
2122                                aFile1.moveTo(aFile2.parent ,aFile2.leafName);
2123                        }
2124                        if(aBackupFile.exists()) aBackupFile.remove(true);
2125                        aFile.copyTo(aBackupFile.parent ,aBackupFile.leafName);
2126                }catch(e){}
2127        },
2128
2129/////////////////////////////////////////////////////////////////////
2130        _createTableDB : function(){
2131                var ourTransaction = false;
2132                try{
2133                        var createTable = !this._dbConn.tableExists("om_url");
2134                        if(!createTable) createTable = !this._dbConn.tableExists("om_history");
2135                        if(!createTable) createTable = !this._dbConn.indexExists("om_url_idx_url");
2136                        if(!createTable) createTable = !this._dbConn.indexExists("om_history_idx_file");
2137                        if(!createTable) createTable = !this._dbConn.indexExists("om_history_idx_path");
2138                        if(!createTable) createTable = !this._dbConn.indexExists("om_history_idx_date");
2139                        if(createTable){
2140                                if(this._dbConn.transactionInProgress){
2141                                        ourTransaction = true;
2142                                        this._dbConn.beginTransactionAs(this._dbConn.TRANSACTION_DEFERRED);
2143                                }
2144                                if(!this._dbConn.tableExists("om_url")){
2145                                        this._dbConn.executeSimpleSQL(
2146                                                "CREATE TABLE om_url (" +
2147                                                "  uid       INTEGER," +
2148                                                "  uid_url   TEXT NOT NULL," +
2149                                                "PRIMARY KEY (uid)"+
2150                                                ")"
2151                                        );
2152                                }
2153                                if(!this._dbConn.tableExists("om_history")){
2154                                        this._dbConn.executeSimpleSQL(
2155                                                "CREATE TABLE om_history (" +
2156                                                "  uid          INTEGER," +
2157                                                "  hid          INTEGER," +
2158                                                "  hid_file     TEXT NOT NULL," +
2159                                                "  hid_path     TEXT NOT NULL," +
2160                                                "  hid_title    TEXT," +
2161                                                "  hid_date     TEXT NOT NULL," +
2162                                                "  hid_filesize INTEGER," +
2163                                                "PRIMARY KEY (uid,hid)"+
2164                                                ")"
2165                                        );
2166                                }
2167                                try{if(!this._dbConn.indexExists("om_url_idx_url"))      this._dbConn.executeSimpleSQL("CREATE INDEX om_url_idx_url      ON om_url(uid_url);");     }catch(ex){}
2168                                try{if(!this._dbConn.indexExists("om_history_idx_file")) this._dbConn.executeSimpleSQL("CREATE INDEX om_history_idx_file ON om_history(hid_file);");}catch(ex){}
2169                                try{if(!this._dbConn.indexExists("om_history_idx_path")) this._dbConn.executeSimpleSQL("CREATE INDEX om_history_idx_path ON om_history(hid_path);");}catch(ex){}
2170                                try{if(!this._dbConn.indexExists("om_history_idx_date")) this._dbConn.executeSimpleSQL("CREATE INDEX om_history_idx_date ON om_history(hid_date);");}catch(ex){}
2171                        }
2172                }
2173                finally {
2174                        if(this._dbConn.lastError) this._dump("bitsAutocacheService._createTableDB():"+this._dbConn.lastErrorString+" ("+this._dbConn.lastError+")");
2175                        if(ourTransaction){
2176                                this._dbConn.rollbackTransaction();
2177                                ourTransaction = false;
2178                        }
2179                }
2180                if(ourTransaction) this._dbConn.commitTransaction();
2181                if(createTable){
2182                        if(!this._dbConn.tableExists("om_url")) return false;
2183                        if(!this._dbConn.tableExists("om_history")) return false;
2184                        if(!this._dbConn.indexExists("om_url_idx_url")) return false;
2185                        return true;
2186                }else{
2187                        return false;
2188                }
2189        },
2190
2191/////////////////////////////////////////////////////////////////////
2192        _setStatementValueDB : function(aStatement,aIndex,aValue,aType) {
2193                try{
2194                        if(aType == undefined) aType = aStatement.VALUE_TYPE_TEXT;
2195                        if(aValue == undefined){
2196                                aStatement.bindNullParameter(aIndex);
2197                        }else{
2198                                switch(aType){
2199                                        case aStatement.VALUE_TYPE_INTEGER :
2200                                        case aStatement.VALUE_TYPE_FLOAT :
2201                                        case aStatement.VALUE_TYPE_TEXT :
2202                                                aStatement.bindUTF8StringParameter(aIndex,aValue);
2203                                                break;
2204                                        case aStatement.VALUE_TYPE_BLOB :
2205                                                aStatement.bindBlobParameter(aIndex,aValue,aValue.length);
2206                                                break;
2207                                        default :
2208                                                break;
2209                                }
2210                        }
2211                }catch(e){
2212                        bitsObjectMng._dump("bitsAutocacheService._setStatementValueDB():"+e);
2213                }
2214        },
2215
2216/////////////////////////////////////////////////////////////////////
2217        _selectDB : function(aSql,aPara){
2218                var ourTransaction = false;
2219                if(this._dbConn.transactionInProgress){
2220                        ourTransaction = true;
2221                        this._dbConn.beginTransactionAs(this._dbConn.TRANSACTION_DEFERRED);
2222                }
2223                var i;
2224                try{
2225                        var statement = this._dbConn.createStatement(aSql);
2226                        if(aPara){
2227                                var i;
2228                                for(i=0;i<aPara.length;i++){
2229                                        this._setStatementValueDB(statement,i,aPara[i]);
2230                                }
2231                        }
2232                        var k=statement.columnCount;
2233                        var columnNames = [];
2234                        for(i=0;i<k;i++){
2235                                columnNames.push(statement.getColumnName(i));
2236                        }
2237                }catch(ex){
2238                        this._dump("bitsAutocacheService._selectDB(1):"+ex);
2239                        this._dump("bitsAutocacheService._selectDB():aSql="+aSql);
2240                        return null;
2241                }
2242                var dataset = [];
2243                try{
2244                        while(statement.executeStep()){
2245                                var row = {};
2246                                var utf8String;
2247                                for(i=0;i<k;i++){
2248                                        utf8String = statement.getUTF8String(i);
2249                                        row[columnNames[i]] = utf8String ? utf8String : "";
2250                                }
2251                                dataset.push(row);
2252                        }
2253                        columnNames = undefined;
2254                }finally {
2255                        if(this._dbConn.lastError > 0 && this._dbConn.lastError <= 100){
2256                                this._dump("bitsAutocacheService._selectDB(3):"+this._dbConn.lastErrorString+" ("+this._dbConn.lastError+")\n\n"+aSql);
2257                        }
2258                        if(this._dbConn.lastError && this._dbConn.lastError != 101){
2259                                this._dump("bitsAutocacheService._selectDB(2):"+this._dbConn.lastErrorString+" ("+this._dbConn.lastError+")\n\n"+aSql);
2260                                dataset = null;
2261                        }
2262                        if(ourTransaction && this._dbConn.lastError && this._dbConn.lastError != 101){
2263                                this._dbConn.rollbackTransaction();
2264                                ourTransaction = false;
2265                        }
2266                        statement.reset();
2267                }
2268                if(ourTransaction) this._dbConn.commitTransaction();
2269                return dataset;
2270        },
2271
2272/////////////////////////////////////////////////////////////////////
2273        _cmdDB : function(aSql,aPara){
2274                var rtn = true;
2275                var ourTransaction = false;
2276                if(this._dbConn.transactionInProgress){
2277                        ourTransaction = true;
2278                        this._dbConn.beginTransactionAs(this._dbConn.TRANSACTION_DEFERRED);
2279                }
2280                try{
2281                        var statement = this._dbConn.createStatement(aSql);
2282                        if(aPara){
2283                                var i;
2284                                for(i=0;i<aPara.length;i++){
2285                                        this._setStatementValueDB(statement,i,aPara[i]);
2286                                }
2287                        }
2288                }catch(ex){
2289                        this._dump("bitsAutocacheService._cmdDB():"+ex);
2290                        this._dump("bitsAutocacheService._cmdDB():aSql="+aSql);
2291                        return false;
2292                }
2293                try{
2294                        statement.execute();
2295                }finally {
2296                        if(this._dbConn.lastError){
2297                                this._dump("bitsAutocacheService._cmdDB():"+this._dbConn.lastErrorString+" ("+this._dbConn.lastError+")");
2298                                this._dump("bitsAutocacheService._cmdDB():aSql="+aSql);
2299                                rtn = false;
2300                        }
2301                        if(ourTransaction && this._dbConn.lastError){
2302                                this._dbConn.rollbackTransaction();
2303                                ourTransaction = false;
2304                        }
2305                        statement.reset();
2306                }
2307                if(ourTransaction) this._dbConn.commitTransaction();
2308                return rtn;
2309        },
2310
2311/////////////////////////////////////////////////////////////////////
2312        _uidExistsDB : function(aUID){
2313                var fSql = 'select count(uid) as uid_num from om_url where uid=?1';
2314                var fRtn = this._selectDB(fSql,[aUID]);
2315                return ((fRtn && fRtn[0].uid_num>0)?true:false);
2316        },
2317
2318/////////////////////////////////////////////////////////////////////
2319        _urlExistsDB : function(aURL){
2320                var fSql = 'select count(uid_url) as uid_num from om_url where uid_url=?1';
2321                var fRtn = this._selectDB(fSql,[aURL]);
2322                return ((fRtn && fRtn[0].uid_num>0)?true:false);
2323        },
2324
2325/////////////////////////////////////////////////////////////////////
2326        _hidExistsDB : function(aHID){
2327                var fSql = 'select count(hid) as hid_num from om_history where hid=?1';
2328                var fRtn = this._selectDB(fSql,[aHID]);
2329                return ((fRtn && fRtn[0].hid_num>0)?true:false);
2330        },
2331
2332/////////////////////////////////////////////////////////////////////
2333        _uidIdentifyDB : function(aUID){
2334                var i = 0;
2335                while(this._uidExistsDB(aUID) && i < 100){
2336                        aUID = this.Common.getTimeStamp(--i);
2337                }
2338                return aUID;
2339        },
2340
2341/////////////////////////////////////////////////////////////////////
2342        _hidIdentifyDB : function(aHID){
2343                var i = 0;
2344                while(this._hidExistsDB(aHID) && i < 100){
2345                        aHID = this.Common.getTimeStamp(--i);
2346                }
2347                return aHID;
2348        },
2349
2350/////////////////////////////////////////////////////////////////////
2351        _insertInitDB : function(){
2352                var basedir = this.cachedir.clone();
2353                if(!basedir.exists() || !basedir.directoryEntries) return;
2354                var dir_arr = [];
2355                var entries = basedir.directoryEntries;
2356                while(entries.hasMoreElements()){
2357                        var entry = entries.getNext().QueryInterface(Components.interfaces.nsILocalFile);
2358                        if(!entry.isDirectory() || (entry.isDirectory() && entry.leafName.match(/^\./))) continue;
2359                        if(entry.leafName.match(/^[0-9]{4}$/)) continue; //倉換枈みのディレクトリはパス
2360                        dir_arr.push(entry);
2361                }
2362                setTimeout(function(){ bitsAutocacheService._insertInitDB_exec(dir_arr); },100);
2363        },
2364
2365        _insertInitDB_exec : function(aDirArray){
2366                if(!aDirArray || aDirArray.length == 0){
2367                        this.refresh();
2368                        return;
2369                }
2370                var entry = aDirArray.shift();
2371                var temp_arr = [];
2372                var temp_entries = entry.directoryEntries;
2373                while(temp_entries.hasMoreElements()){
2374                        var temp_entry = temp_entries.getNext().QueryInterface(Components.interfaces.nsILocalFile);
2375                        if(!temp_entry.isDirectory() || (temp_entry.isDirectory() && temp_entry.leafName.match(/^\./))) continue;
2376                        temp_arr.push(temp_entry);
2377                }
2378                if(temp_arr.length>0){
2379                        temp_arr.sort(function(a, b) { return(parseInt(a.leafName) - parseInt(b.leafName)); });
2380                        var i;
2381                        var info;
2382                        for(i=0;i<temp_arr.length;i++){
2383                                info = this._getSaveCacheInfo(temp_arr[i].clone());
2384                                if(!info || !info.URL){
2385                                        info = undefined;
2386                                        continue;
2387                                }
2388                                info.DIR = entry.clone();
2389                                info.DATE = temp_arr[0].leafName;
2390                                break;
2391                        }
2392                        if(info && info.URL){
2393                                info.URL = info.URL.replace(/^\s*/mg,"").replace(/\s*$/mg,"");
2394                                var urldbs = this._selectUrlDB({uid_url : info.URL});
2395                                if(!urldbs){
2396                                        this._insertUrlDB({
2397                                                uid       : info.DATE,
2398                                                uid_url   : info.URL,
2399                                        });
2400                                        urldbs = this._selectUrlDB({uid_url : info.URL});
2401                                }
2402                                if(urldbs){
2403                                        var urldb = urldbs[0];
2404                                        for(i=0;i<temp_arr.length;i++){
2405                                                var temp_info = this._getSaveCacheInfo(temp_arr[i].clone());
2406                                                if(!temp_info || !temp_info.URL){
2407                                                        temp_info = undefined;
2408                                                        continue;
2409                                                }
2410                                                temp_info.DIR = entry.clone();
2411                                                temp_info.DATE = temp_arr[i].leafName;
2412                                                var rtn = this._insertHistoryDB({
2413                                                        uid          : urldb.uid,
2414                                                        hid          : temp_info.DATE,
2415                                                        hid_file     : temp_info.INDEX,
2416                                                        hid_path     : this.Common.convertFilePathToURL(temp_arr[i].path),
2417                                                        hid_title    : temp_info.TITLE,
2418                                                        hid_date     : temp_info.DATE,
2419                                                        hid_filesize : this.Common.getFilesize(temp_arr[i]),
2420                                                });
2421                                        }
2422                                }
2423                                var histdbs = this._selectHistoryDB({
2424                                        uid_url : info.URL
2425                                });
2426                                if(histdbs){
2427                                        for(i=0;i<histdbs.length;i++){
2428                                                var dir = this.getURLCacheDir(histdbs[i].uid_url);
2429                                                if(!dir || !dir.exists()) continue;
2430                                                var approximateCacheTimeStamp = this.getApproximateCacheTimeStamp(histdbs[i].uid_url,histdbs[i].hid_date);
2431                                                if(approximateCacheTimeStamp){
2432                                                        dir.append(approximateCacheTimeStamp);
2433                                                        if(!dir || !dir.exists()) continue;
2434                                                }else{
2435                                                        continue;
2436                                                }
2437                                                var newDir = this.getURLCacheDirFromTimeStamp(histdbs[i].uid_url,histdbs[i].hid_date);
2438                                                this._updateHistoryDB({
2439                                                        uid      : histdbs[i].uid,
2440                                                        hid      : histdbs[i].hid,
2441                                                        hid_path : this.Common.convertFilePathToURL(newDir.path),
2442                                                });
2443                                                if(newDir.exists()){
2444                                                        dir.remove(true);
2445                                                        continue;
2446                                                }
2447                                                if(!newDir.parent.exists()) newDir.parent.create(newDir.DIRECTORY_TYPE, 0777);
2448                                                dir.moveTo(newDir.parent,newDir.leafName);
2449                                        }
2450                                }
2451                                var dir = this.getURLCacheDir(info.URL);
2452                                if(dir && dir.exists()){
2453                                        var histnum = 0;
2454                                        var temp_entries = dir.directoryEntries;
2455                                        while(temp_entries.hasMoreElements()){
2456                                                var temp_entry = temp_entries.getNext().QueryInterface(Components.interfaces.nsILocalFile);
2457                                                if(!temp_entry.isDirectory() || (temp_entry.isDirectory() && temp_entry.leafName.match(/^\./))) continue;
2458                                                histnum++;
2459                                        }
2460                                        if(histnum == 0) dir.remove(true);
2461                                }
2462                        }
2463                }
2464                temp_arr = undefined;
2465                setTimeout(function(){ bitsAutocacheService._insertInitDB_exec(aDirArray); },100);
2466        },
2467
2468/////////////////////////////////////////////////////////////////////
2469        _insertUrlDB : function(aUrlObject){
2470                try{
2471                        if(!aUrlObject) return false;
2472                        if(!aUrlObject.uid_url) return false;
2473                        var rtn = true;
2474                        if(aUrlObject.uid == undefined){
2475                                aUrlObject.uid = this._uidIdentifyDB(this.Common.getTimeStamp());
2476                        }else{
2477                                if(this._uidExistsDB(aUrlObject.uid)) return false;
2478                        }
2479                        if(this._urlExistsDB(aUrlObject.uid_url)) return false;
2480                        var columns = [];
2481                        var values = [];
2482                        var para = [];
2483                        var index=0;
2484                        var key;
2485                        for(key in aUrlObject){
2486                                if(!aUrlObject[key] || aUrlObject[key] == "") continue;
2487                                columns.push(key);
2488                                values.push('?'+(++index));
2489                                para.push(aUrlObject[key]);
2490                        }
2491                        if(columns.length == 0) rtn = false;
2492                        if(rtn){
2493                                var aSql = "insert into om_url ("+ columns.join(",") +") values ("+ values.join(",") +")";
2494                                rtn = this._cmdDB(aSql,para);
2495                                if(!rtn) this._dump("bitsAutocacheService._insertUrlDB():aSql="+aSql);
2496                        }
2497                }catch(ex){
2498                        this._dump("bitsAutocacheService._insertUrlDB():"+ex);
2499                }
2500                return rtn;
2501        },
2502
2503/////////////////////////////////////////////////////////////////////
2504        _selectUrlDB : function(aUrlObject){
2505                try{
2506                        var para = [];
2507                        var where = [];
2508                        var key;
2509                        var index=0;
2510                        if(aUrlObject){
2511                                for(key in aUrlObject){
2512                                        where.push("om_url."+key+"=?"+(++index));
2513                                        para.push(aUrlObject[key]);
2514                                }
2515                        }
2516                        var oSql = 'select' +
2517                                                                ' om_url.uid' +
2518                                                                ',om_url.uid_url' +
2519                                                                ' from om_url';
2520                        if(where.length>0) oSql += " where " + where.join(" and ");
2521                        var oFld = this._selectDB(oSql,para);
2522                        if(oFld && oFld.length>0)
2523                                return oFld;
2524                        else
2525                                return null;
2526                }catch(ex){
2527                        this._dump("bitsAutocacheService._selectUrlDB():"+ex);
2528                        return null;
2529                }
2530        },
2531
2532/////////////////////////////////////////////////////////////////////
2533        _updateUrlDB : function(aUrlObject){
2534                if(!aUrlObject) return false;
2535                if(!aUrlObject.uid && !aUrlObject.uid_url) return false;
2536                try{
2537                        var rtn = true;
2538                        var om_link = {};
2539                        var values = [];
2540                        var para = [];
2541                        var index=0;
2542                        var key;
2543                        for(key in aUrlObject){
2544                                if(aUrlObject[key] == undefined || key == "uid" || key == "uid_url") continue;
2545                                values.push(key+'=?'+(++index));
2546                                para.push(aUrlObject[key]);
2547                        }
2548                        if(rtn && values.length>0){
2549                                var aSql = 'update om_url set '+ values.join(",");
2550                                var where = [];
2551                                if(aUrlObject.uid){
2552                                        where.push("uid=?"+(++index));
2553                                        para.push(aUrlObject.uid);
2554                                }
2555                                if(aUrlObject.uid_url){
2556                                        where.push("uid_url=?"+(++index));
2557                                        para.push(aUrlObject.uid_url);
2558                                }
2559                                if(where.length>0) aSql += " where " + where.join(" and ");
2560                                rtn = this._cmdDB(aSql,para);
2561                        }
2562                        return rtn;
2563                }catch(ex){
2564                        this._dump("bitsAutocacheService._updateUrlDB():"+ex);
2565                        return false;
2566                }
2567        },
2568
2569/////////////////////////////////////////////////////////////////////
2570        _deleteUrlDB : function(aUrlObject){
2571                if(!aUrlObject) return false;
2572                if(!aUrlObject.uid && !aUrlObject.uid_url) return false;
2573                if(!aUrlObject.uid){
2574                        var urldbs = this._selectUrlDB(aUrlObject);
2575                        if(urldbs) aUrlObject.uid = urldbs[0].uid;
2576                }
2577                if(!aUrlObject.uid) return false;
2578                if(!this._deleteHistoryDB({uid:aUrlObject.uid})) return false;
2579                try{
2580                        var para = [];
2581                        var where = [];
2582                        var key;
2583                        var index=0;
2584                        if(aUrlObject){
2585                                for(key in aUrlObject){
2586                                        where.push("om_url."+key+"=?"+(++index));
2587                                        para.push(aUrlObject[key]);
2588                                }
2589                        }
2590                        var oSql = 'delete from om_url';
2591                        if(where.length>0) oSql += " where " + where.join(" and ");
2592                        return this._cmdDB(oSql,para);
2593                }catch(ex){
2594                        this._dump("bitsAutocacheService._deleteUrlDB():"+ex);
2595                        return false;
2596                }
2597        },
2598
2599/////////////////////////////////////////////////////////////////////
2600        _insertHistoryDB : function(aHistObject){
2601                try{
2602                        if(!aHistObject) return false;
2603                        if(aHistObject.uid == undefined) return false;
2604                        if(!this._uidExistsDB(aHistObject.uid)) return false;
2605                        if(aHistObject.hid == undefined){
2606                                aHistObject.hid = this._hidIdentifyDB(this.Common.getTimeStamp());
2607                        }else{
2608                                if(this._hidExistsDB(aHistObject.hid)) return false;
2609                        }
2610                        var columns = [];
2611                        var values = [];
2612                        var para = [];
2613                        var index=0;
2614                        var key;
2615                        for(key in aHistObject){
2616                                if(!aHistObject[key] || aHistObject[key] == "") continue;
2617                                columns.push(key);
2618                                values.push('?'+(++index));
2619                                para.push(aHistObject[key]);
2620                        }
2621                        var rtn = (columns.length == 0)?false:true;
2622                        if(rtn){
2623                                var aSql = "insert into om_history ("+ columns.join(",") +") values ("+ values.join(",") +")";
2624                                rtn = this._cmdDB(aSql,para);
2625                                if(!rtn) this._dump("bitsAutocacheService._insertHistoryDB():aSql="+aSql);
2626                        }
2627                }catch(ex){
2628                        this._dump("bitsAutocacheService._insertHistoryDB():"+ex);
2629                        rtn = false;
2630                }
2631                return rtn;
2632        },
2633
2634/////////////////////////////////////////////////////////////////////
2635        _selectHistoryDB : function(aHistObject){
2636                try{
2637                        var para = [];
2638                        var where = [];
2639                        var key;
2640                        var index=0;
2641                        if(aHistObject){
2642                                if(aHistObject.hid_date && aHistObject.hid_date.match(/^(\d{2})\/(\d{2})\/(\d{4})\s+(\d{2}):(\d{2}):(\d{2})$/)) aHistObject.hid_date = RegExp.$3 + RegExp.$1 + RegExp.$2 + RegExp.$4 + RegExp.$5 + RegExp.$6;
2643                                for(key in aHistObject){
2644                                        if(key == "uid_url"){
2645                                                where.push("om_url."+key+"=?"+(++index));
2646                                        }else{
2647                                                where.push("om_history."+key+"=?"+(++index));
2648                                        }
2649                                        para.push(aHistObject[key]);
2650                                }
2651                        }
2652                        var oSql = 'select' +
2653                                ' om_url.uid' +
2654                                ',om_url.uid_url' +
2655                                ',om_history.hid' +
2656                                ',om_history.hid_file' +
2657                                ',om_history.hid_path' +
2658                                ',om_history.hid_title' +
2659                                ',om_history.hid_date' +
2660                                ',om_history.hid_filesize' +
2661                                ' from om_history' +
2662                                ' LEFT JOIN om_url ON om_url.uid = om_history.uid';
2663                        if(where.length>0) oSql += " where " + where.join(" and ");
2664                        oSql += ' order by om_history.hid_date desc';
2665                        var oFld = this._selectDB(oSql,para);
2666                        if(oFld && oFld.length>0)
2667                                return oFld;
2668                        else
2669                                return null;
2670                }catch(ex){
2671                        this._dump("bitsAutocacheService._selectHistoryDB():"+ex);
2672                        return null;
2673                }
2674        },
2675
2676/////////////////////////////////////////////////////////////////////
2677        _updateHistoryDB : function(aHistObject){
2678                if(!aHistObject) return false;
2679                if(!aHistObject.uid && !aHistObject.hid) return false;
2680                try{
2681                        var rtn = true;
2682                        var values = [];
2683                        var para = [];
2684                        var index=0;
2685                        var key;
2686                        for(key in aHistObject){
2687                                if(aHistObject[key] == undefined || key == "uid" || key == "uid_url" || key == "hid") continue;
2688                                values.push(key+'=?'+(++index));
2689                                para.push(aHistObject[key]);
2690                        }
2691                        if(rtn && values.length>0){
2692                                var aSql = 'update om_history set '+ values.join(",");
2693                                var where = [];
2694                                if(aHistObject.uid){
2695                                        where.push("uid=?"+(++index));
2696                                        para.push(aHistObject.uid);
2697                                }
2698                                if(aHistObject.hid){
2699                                        where.push("hid=?"+(++index));
2700                                        para.push(aHistObject.hid);
2701                                }
2702                                if(where.length>0) aSql += " where " + where.join(" and ");
2703                                rtn = this._cmdDB(aSql,para);
2704                        }
2705                        return rtn;
2706                }catch(ex){
2707                        this._dump("bitsAutocacheService._updateUrlDB():"+ex);
2708                        return false;
2709                }
2710        },
2711/////////////////////////////////////////////////////////////////////
2712        _deleteHistoryDB : function(aHistObject){
2713                if(!aHistObject) return false;
2714                if(!aHistObject.uid && !aHistObject.hid) return false;
2715                try{
2716                        var para = [];
2717                        var where = [];
2718                        var key;
2719                        var index=0;
2720                        if(aHistObject){
2721                                for(key in aHistObject){
2722                                        where.push("om_history."+key+"=?"+(++index));
2723                                        para.push(aHistObject[key]);
2724                                }
2725                        }
2726                        var oSql = 'delete from om_history';
2727                        if(where.length>0) oSql += " where " + where.join(" and ");
2728                        return this._cmdDB(oSql,para);
2729                }catch(ex){
2730                        this._dump("bitsAutocacheService._deleteHistoryDB():"+ex);
2731                        return false;
2732                }
2733        },
2734
2735/////////////////////////////////////////////////////////////////////
2736/////////////////////////////////////////////////////////////////////
2737        _dump : function(aString){
2738                window.top.bitsMarkingCollection._dump(aString);
2739        },
2740};
2741
2742/////////////////////////////////////////////////////////////////////
2743function bitsAutocacheDocument(aAutocacheDir) {
2744        this.document = null;
2745        this._name = "";
2746        this.dataDirName = null;
2747        this.AutocacheDir = null;
2748        if(aAutocacheDir) this.AutocacheDir = aAutocacheDir;
2749        this._id = null;
2750        this._treeRes = null;
2751        this._url2autocache = [];
2752        this.oid = null;
2753        this.oldURL2newURL = [];
2754        this.scrollhref = "";
2755        this.scrollWin = [];
2756        this.AutocacheURL = [];
2757        this.item = this.Common.newItem(this.DataSource.identify(this.Common.getTimeStamp()));
2758        this.file2URL = [];
2759        this.httpTask = [];
2760        this.linkURLs = [];
2761        this.frameList = [];
2762        this.frameNumber = 0;
2763        this.fileNumber = 0;
2764        this.httpTask[this.item.id] = 0;
2765        this.basedir = bitsAutocacheService.cachedir;
2766        if(!this.basedir.exists()) this.basedir.create(this.basedir.DIRECTORY_TYPE, 0777);
2767};
2768
2769bitsAutocacheDocument.prototype = {
2770        get SAVEMODE_FILEONLY()     { return 0x00 },
2771        get SAVEMODE_COMPLETE_DOM() { return 0x01 },
2772        get SAVEMODE_COMPLETE_TEXT(){ return 0x02 },
2773
2774        get STRING() { return document.getElementById("bitsAutocacheString"); },
2775
2776        get DataSource() { return bitsObjectMng.DataSource; },
2777        get Common()     { return bitsObjectMng.Common;     },
2778        get XPath()      { return bitsObjectMng.XPath;      },
2779        get Database()   { return bitsObjectMng.Database;   },
2780        get gBrowser()   { return bitsObjectMng.getBrowser();},
2781
2782        get name() {
2783                return this._name;
2784        },
2785        set name(aName) {
2786                if(aName && aName != ""){
2787                        this.dataDirName = aName + "_files";
2788                }else{
2789                        this.dataDirName = null;
2790                }
2791                return this._name = aName;
2792        },
2793
2794        get id() {
2795                return this._id;
2796        },
2797        set id(aID) {
2798                return this._id = aID;
2799        },
2800
2801        get treeRes() { return this._treeRes; },
2802        set treeRes(aRes) { return this._treeRes = aRes; },
2803
2804        get autocache() {
2805                var autocache = bitsMarkingCollection.getExtensionDir();
2806                if(!autocache.exists()) autocache.create(autocache.DIRECTORY_TYPE, 0777);
2807                autocache.append("autocache");
2808                if(!autocache.exists()) autocache.create(autocache.DIRECTORY_TYPE, 0777);
2809                return autocache;
2810        },
2811
2812        get defaultdir() {
2813                return this.basedir.clone();
2814        },
2815
2816        Autocachedir : function(aClass) {
2817                if(this.AutocacheDir) return this.AutocacheDir.clone();
2818                var dir;
2819                if(bitsAutocacheService.prefs.data.default || !bitsAutocacheService.prefs.data.localfile){
2820                        dir = aClass.defaultdir;
2821                }else{
2822                        dir = bitsAutocacheService.prefs.data.localfile.clone();
2823                }
2824                if(aClass.id){
2825                        dir.append(aClass.id);
2826                        if(!dir.exists()) try{ dir.create(dir.DIRECTORY_TYPE, 0777); }catch(ex){ alert("bitsAutocacheDocument.Autocachedir()"+ex);return undefined; }
2827                }
2828                return dir.clone();
2829        },
2830
2831/////////////////////////////////////////////////////////////////////
2832        done : function(){},
2833
2834/////////////////////////////////////////////////////////////////////
2835
2836/////////////////////////////////////////////////////////////////////
2837        markingDocument : function(aDocument){
2838                try{
2839                        var doc_url = this.Common.getURLStringFromDocument(aDocument);
2840                        if(this.AutocacheURL[doc_url] == undefined) return;
2841                        var dir_arr = [];
2842                        var entries = this.AutocacheURL[doc_url].dir.directoryEntries;
2843                        while(entries.hasMoreElements()){
2844                                var entry = entries.getNext().QueryInterface(Components.interfaces.nsILocalFile);
2845                                if(!entry.isDirectory() || (entry.isDirectory() && entry.leafName.match(/^\./))) continue;
2846                                dir_arr.push(entry);
2847                        }
2848                        if(dir_arr.length == 0) return;
2849                        dir_arr.sort(function(a,b){ return b.lastModifiedTime - a.lastModifiedTime; });
2850                        while(dir_arr.length>0){
2851                                var dir = dir_arr.shift();
2852                                var url_file = dir.clone();
2853                                url_file.append(".urlinfo");
2854                                if(!url_file.exists()) continue;
2855                                var oldURL2newURL = [];
2856                                var newURL2oldURL = [];
2857                                var url = this.readFile(url_file);
2858                                var url_arr = url.split("\n");
2859                                var urlcnt;
2860                                for(urlcnt=0;urlcnt<url_arr.length;urlcnt++){
2861                                        var temp_arr = url_arr[urlcnt].split("\t");
2862                                        oldURL2newURL[temp_arr[0]] = temp_arr[1];
2863                                        newURL2oldURL[temp_arr[1]] = temp_arr[0];
2864                                }
2865                                if(oldURL2newURL[doc_url] == undefined) continue;
2866                                var rtnObj = this.Database.getAllObjectFormURL(oldURL2newURL[doc_url],undefined,undefined,"text");
2867                                if(!rtnObj) continue;
2868                                var cnt;
2869                                for(cnt=0;cnt<rtnObj.length;cnt++){
2870                                        var rObj = rtnObj[cnt];
2871                                        if(newURL2oldURL[rObj.con_url] == undefined) continue;
2872                                        var con_url = newURL2oldURL[rObj.con_url];
2873                                        var rtnContent = bitsMarker.xPathMarker(aDocument, {start:rObj.bgn_dom,end:rObj.end_dom,context:rObj.oid_txt,con_url:con_url}, { id:rObj.oid, dbtype:rObj.dbtype, pfid:rObj.pfid, style:rObj.fid_style });
2874                                }
2875                        }
2876                }catch(ex){
2877                        throw new Error("bitsAutocacheDocument.markingDocument():"+ex);
2878                }
2879        },
2880
2881/////////////////////////////////////////////////////////////////////
2882        exec : function(aForced){
2883                var self = this;
2884                return self._exec(self, aForced);
2885        },
2886
2887/////////////////////////////////////////////////////////////////////
2888        _exec : function(aClass, aForced){
2889                if(!aForced) aForced = false;
2890                try{
2891                        var doc = bitsAutocacheService.gBrowser.contentDocument;
2892                        var urlString = bitsAutocacheService.Common.getURLStringFromDocument(doc);
2893                        if(bitsAutocacheService.isCacheURL(urlString)) return false;
2894                        var timeStamp = bitsAutocacheService.getURLTimeStamp(urlString);
2895                        var dir = bitsAutocacheService.getURLCacheDirFromTimeStamp(urlString,timeStamp);
2896                        if(!aForced && dir && dir.exists()) return false;
2897                        if(!dir.exists()) dir.create(dir.DIRECTORY_TYPE, 0777);
2898                        setTimeout(function(){
2899                                try{
2900                                        aClass.frameList = aClass.flattenFrames(aClass, doc.defaultView);
2901                                        if(aClass.frameList){
2902                                                var marker_arr = [];
2903                                                var cnt;
2904                                                for(cnt=0;cnt<aClass.frameList.length;cnt++){
2905                                                        var xPathSPAN = bitsAutocacheService.XPath.evaluate('//*[starts-with(@id,"'+bitsMarker.id_key+'")]', aClass.frameList[cnt].document);
2906                                                        if(xPathSPAN){
2907                                                                var keyreg = new RegExp("^"+bitsMarker.id_key);
2908                                                                var xpathcnt;
2909                                                                for(xpathcnt=0;xpathcnt<xPathSPAN.snapshotLength;xpathcnt++){
2910                                                                        var node = xPathSPAN.snapshotItem(xpathcnt);
2911                                                                        var id_attr = node.getAttribute("id");
2912                                                                        if(!id_attr.match(keyreg)) continue;
2913                                                                        marker_arr.push(id_attr);
2914                                                                        node = undefined;
2915                                                                }
2916                                                                xPathSPAN = undefined;
2917                                                        }
2918                                                }
2919                                                for(cnt=0;cnt<marker_arr.length;cnt++){
2920                                                        bitsMarker.unmarkerWindow(marker_arr[cnt]);
2921                                                }
2922                                                marker_arr.length = 0;
2923                                                marker_arr = undefined;
2924                                        }
2925                                }catch(e){
2926                                        aClass._dump("bitsAutocacheDocument._exec():"+e);
2927                                }
2928                                aClass._createDocCache(aClass, doc, dir, false);
2929                                var rtn = bitsMarkingCollection.marking(doc);
2930                        },0);
2931                        return true;
2932                }catch(ex){
2933                        throw new Error("bitsAutocacheDocument._exec():"+ex);
2934                }
2935        },
2936
2937/////////////////////////////////////////////////////////////////////
2938        _createDocCache : function(aClass, aDocument, aCacheDir, aLoadURL){
2939                var newFile;
2940                if(aLoadURL == undefined) aLoadURL = false;
2941                var fileKey = null;
2942                var fileName = bitsAutocacheService.Common.getFileName(aDocument.location.href);
2943                var splitFileName = bitsAutocacheService.Common.splitFileName(fileName);
2944                if(!splitFileName[0] || splitFileName[0] == ""){
2945                        fileKey = "index";
2946                }else{
2947                        fileKey = splitFileName[0];
2948                }
2949                if(fileKey.length>8) fileKey = fileKey.substr(0,8);
2950                fileKey = aClass.validateFileName(fileKey);
2951                try{
2952                        if(aDocument.location){
2953                                newFile = aClass.cacheDocumentInternal(aClass, aDocument, fileKey, aCacheDir);
2954                                if(newFile){
2955                                        var urlString = bitsAutocacheService.Common.getURLStringFromDocument(aDocument);
2956                                        var info_file = aCacheDir.clone();
2957                                        info_file.append(".info");
2958                                        if(!info_file.exists()){
2959                                                var info = "URL\t"   + urlString + "\n";
2960                                                info += "INDEX\t" + newFile.leafName + "\n";
2961                                                info += "TITLE\t" + aDocument.title + "\n";
2962                                                bitsAutocacheService.writeFile(info_file,info);
2963                                        }
2964                                        var url_file = aCacheDir.clone();
2965                                        url_file.append(".urlinfo");
2966                                        if(url_file.exists()) url_file.remove(true);
2967                                        var url = "";
2968                                        var urlkey;
2969                                        var baseURL = bitsAutocacheService.Common.convertFilePathToURL(aCacheDir.path);
2970                                        var resolveURL;
2971                                        for(urlkey in aClass.oldURL2newURL){
2972                                                if(typeof aClass.oldURL2newURL[urlkey] == "function") continue;
2973                                                resolveURL = new String(aClass.oldURL2newURL[urlkey]);
2974                                                if(resolveURL.indexOf(baseURL)==0) resolveURL = resolveURL.substring(baseURL.length);
2975                                                url += urlkey + "\t" + resolveURL + "\n";
2976                                        }
2977                                        if(url != "") bitsAutocacheService.writeFile(url_file,url);
2978                                        var timeStamp = aCacheDir.leafName;
2979                                        var urlsdb = bitsAutocacheService._selectUrlDB({uid_url:urlString});
2980                                        if(!urlsdb){
2981                                                bitsAutocacheService._insertUrlDB({uid:timeStamp,uid_url:urlString});
2982                                                urlsdb = bitsAutocacheService._selectUrlDB({uid_url:urlString});
2983                                        }
2984                                        if(urlsdb){
2985                                                var rtn = bitsAutocacheService._insertHistoryDB({
2986                                                        uid          : urlsdb[0].uid,
2987                                                        hid          : timeStamp,
2988                                                        hid_file     : newFile.leafName,
2989                                                        hid_path     : this.Common.convertFilePathToURL(aCacheDir.path),
2990                                                        hid_title    : aDocument.title?aDocument.title:urlString,
2991                                                        hid_date     : timeStamp,
2992                                                        hid_filesize : this.Common.getFilesize(aCacheDir),
2993                                                });
2994                                        }
2995                                }
2996                        }
2997                }catch(ex){
2998                        throw new Error("bitsAutocacheDocument._createDocCache():"+ex);
2999                }
3000                return newFile;
3001        },
3002
3003/////////////////////////////////////////////////////////////////////
3004        scroll : function(aClass, aEvent){
3005                if(aClass.scrollhref == "") return;
3006                if(aEvent.target.location.href != aClass.scrollhref) return;
3007                if(aClass.httpTask[aClass.item.id] > 0) return;
3008                aClass.scrollhref = "";
3009                bitsAutocacheService.gBrowser.removeEventListener("pageshow", function(aEvent){ aClass.scroll(aClass, aEvent); }, false);
3010                var frameList = aClass.flattenFrames(aClass, aEvent.target.defaultView);
3011                var i,j;
3012                for(i=0;i<aClass.scrollWin.length;i++){
3013                        var val = aClass.scrollWin[i];
3014                        if(val.scrollLeft == 0 && val.scrollTop == 0 && val.scrollBLeft == 0 && val.scrollBTop == 0) continue;
3015                        for(j=0;j<frameList.length;j++){
3016                                if(val.href != frameList[j].document.location.href) continue;
3017                                if(val.scrollLeft != 0  || val.scrollTop != 0)  frameList[j].scrollTo(val.scrollLeft,val.scrollTop);
3018                                if(val.scrollBLeft != 0 || val.scrollBTop != 0) frameList[j].scrollTo(val.scrollBLeft,val.scrollBTop);
3019                        }
3020                }
3021                aClass.scrollWin.length = 0;
3022                aClass.scrollWin = [];
3023        },
3024
3025/////////////////////////////////////////////////////////////////////
3026        flattenFrames : function(aClass, aWindow){
3027                if(!aWindow) return [];
3028                var ret = [aWindow];
3029                var i;
3030                for(i=0;i < aWindow.frames.length;i++){
3031                        ret = ret.concat(aClass.flattenFrames(aClass, aWindow.frames[i]));
3032                }
3033                return ret;
3034        },
3035
3036/////////////////////////////////////////////////////////////////////
3037        validateFileName : function(aFileName){
3038                var re = /[\/]+/g;
3039                if(navigator.appVersion.indexOf("Windows") != -1){
3040                        re = /[\\\/\|]+/g;
3041                        aFileName = aFileName.replace(/[\"]+/g, "'");
3042                        aFileName = aFileName.replace(/[\*\:\?]+/g, " ");
3043                        aFileName = aFileName.replace(/[\<]+/g, "(");
3044                        aFileName = aFileName.replace(/[\>]+/g, ")");
3045                        aFileName = aFileName.replace(/[\"\?!~`]+/g, "");
3046                        aFileName = aFileName.replace(/[\*\&]+/g, "+");
3047                        aFileName = aFileName.replace(/[\\\/\|\:;]+/g, "-");
3048                        aFileName = aFileName.replace(/[\<]+/g, "(");
3049                        aFileName = aFileName.replace(/[\>]+/g, ")");
3050                        aFileName = aFileName.replace(/[\s]+/g, "_");
3051                        aFileName = aFileName.replace(/[%]+/g, "@");
3052                }else if(navigator.appVersion.indexOf("Macintosh") != -1)
3053                        re = /[\:\/]+/g;
3054                return aFileName.replace(re, "_");
3055        },
3056
3057/////////////////////////////////////////////////////////////////////
3058        cacheDocumentInternal : function(aClass, aDocument, aFileKey, aCacheDir){
3059                if(!aDocument) return undefined;
3060                if(!aFileKey) return undefined;
3061                if(!aCacheDir) return undefined;
3062                if(!aDocument.location) return undefined;
3063                aClass.document = aDocument;
3064                aClass.name = aFileKey;
3065                aClass.AutocacheDir = aCacheDir.clone();
3066                aClass.frameList = aClass.flattenFrames(aClass, aDocument.defaultView);
3067                aClass.frameListHash = {};
3068                for(var cnt=0;cnt<aClass.frameList.length;cnt++){
3069                        var url = aClass.frameList[cnt].document.location.href;
3070                        aClass.frameListHash[url] = aClass.frameList[cnt];
3071                }
3072                var dataDir = aClass.AutocacheDir.clone();
3073                if(aClass.dataDirName) dataDir.append(aClass.dataDirName);
3074                if(!aDocument.body || !aDocument.contentType || !aDocument.contentType.match(/html|xml/i)){
3075                        var captureType = (aDocument.contentType && aDocument.contentType.substring(0,5) == "image") ? "image" : "file";
3076                        if(aClass.frameNumber == 0 ) aClass.item.type = captureType;
3077                        var newLeafName = aClass.cacheFileInternal(aClass, aDocument.location.href, aFileKey, captureType);
3078                        return newLeafName;
3079                }
3080                aClass.refURLObj = bitsAutocacheService.Common.convertURLToObject(aDocument.location.href);
3081                var tmpNodeList = [];
3082                tmpNodeList.unshift(aDocument.body.cloneNode(true));
3083                var rootNode = aDocument.getElementsByTagName("html")[0].cloneNode(false);
3084                try{
3085                        var headNode = aDocument.getElementsByTagName("head")[0].cloneNode(true);
3086                        rootNode.appendChild(headNode);
3087                        rootNode.appendChild(aDocument.createTextNode("\n"));
3088                }catch(ex){}
3089                rootNode.appendChild(tmpNodeList[0]);
3090                rootNode.appendChild(aDocument.createTextNode("\n"));
3091                var n;
3092                for(n=0;n<tmpNodeList.length-1;n++){
3093                        tmpNodeList[n].appendChild(aDocument.createTextNode("\n"));
3094                        tmpNodeList[n].appendChild(tmpNodeList[n+1]);
3095                        tmpNodeList[n].appendChild(aDocument.createTextNode("\n"));
3096                }
3097                aClass.processDOMRecursively(aClass, rootNode);
3098                var cssFileKey = bitsAutocacheService.Common.getTimeStamp();
3099                cssFileKey = "sp_" + cssFileKey.substr(-5,5);
3100                if(cssFileKey.length>8) cssFileKey = cssFileKey.substr(0,8);
3101                var myCSS = "";
3102                var myStyleSheets = aDocument.styleSheets;
3103                var i;
3104                for(i=0;i<myStyleSheets.length;i++){
3105                        myCSS += aClass.processCSSRecursively(aClass, myStyleSheets[i]);
3106                }
3107                if(myCSS){
3108                        var newLinkNode = aDocument.createElement("link");
3109                        newLinkNode.setAttribute("media", "all");
3110                        newLinkNode.setAttribute("href", (aClass.dataDirName ? aClass.dataDirName + "/" : "") + cssFileKey + ".css");
3111                        newLinkNode.setAttribute("type", "text/css");
3112                        newLinkNode.setAttribute("rel", "stylesheet");
3113                        rootNode.firstChild.appendChild(aDocument.createTextNode("\n"));
3114                        rootNode.firstChild.appendChild(newLinkNode);
3115                        rootNode.firstChild.appendChild(aDocument.createTextNode("\n"));
3116                        myCSS = myCSS.replace(/\*\|/g, "");
3117                        if(aClass.dataDirName){
3118                                var regexp = new RegExp(aClass.dataDirName+"/","img");
3119                                if(regexp) myCSS = myCSS.replace(regexp, "");
3120                        }
3121                }
3122                var myHTML;
3123                myHTML = aClass.surroundByTags(rootNode, rootNode.innerHTML);
3124                myHTML = aClass.doctypeToString(aDocument.doctype) + myHTML;
3125                myHTML = myHTML.replace(/\x00/g, " ");
3126                var characterSet = aDocument.characterSet;
3127                var myHTMLFile = aCacheDir.clone();
3128                myHTMLFile.append(aFileKey + ".html");
3129                if(!myHTMLFile.exists()) bitsAutocacheService.Common.writeFile(myHTMLFile, myHTML, characterSet);
3130                if(myCSS){
3131                        if(!dataDir.exists()) dataDir.create(dataDir.DIRECTORY_TYPE, 0777);
3132                        if(!dataDir.exists()){
3133                                alert(dataDir.path);
3134                                return undefined;
3135                        }
3136                        var myCSSFile = dataDir.clone();
3137                        myCSSFile.append(cssFileKey + ".css");
3138                        if(!myCSSFile.exists()) bitsAutocacheService.Common.writeFile(myCSSFile, myCSS, characterSet);
3139                        if(!myCSSFile.exists()) alert(myCSSFile.path);
3140                }
3141                aClass.oldURL2newURL[aDocument.location.href] = bitsAutocacheService.Common.convertFilePathToURL(myHTMLFile.path);
3142                return myHTMLFile;
3143        },
3144
3145/////////////////////////////////////////////////////////////////////
3146        cacheFileInternal : function(aClass, aFileURL, aFileKey, aCaptureType){
3147                if(!aFileKey) aFileKey = "file" + Math.random().toString();
3148                if(!aClass.refURLObj ) aClass.refURLObj = bitsAutocacheService.Common.convertURLToObject(aFileURL);
3149                if(aClass.frameNumber == 0){
3150                        aClass.item.icon  = "chrome://markingcollection/skin/defaultFavicon.png";
3151                        aClass.item.type  = aCaptureType;
3152                        aClass.item.chars = "";
3153                }
3154                var newFileName = aClass.download(aClass, aFileURL);
3155                var myHTML;
3156                if(aCaptureType == "image"){
3157                        myHTML = '<html><body><img src="' + newFileName + '"></body></html>';
3158                } else {
3159                        myHTML = '<html><head><meta http-equiv="refresh" content="0;URL=./' + newFileName + '"></head><body></body></html>';
3160                }
3161                var myHTMLFile = aClass.Autocachedir(aClass).clone();
3162                myHTMLFile.append(aFileKey + ".html");
3163                if(!myHTMLFile.exists()) bitsAutocacheService.Common.writeFile(myHTMLFile, myHTML, "UTF-8");
3164
3165                return myHTMLFile;
3166        },
3167
3168/////////////////////////////////////////////////////////////////////
3169        surroundByTags : function(aNode, aContent){
3170                var tag = "<" + aNode.nodeName.toLowerCase();
3171                var i;
3172                for(i=0;i<aNode.attributes.length;i++){
3173                        tag += ' ' + aNode.attributes[i].name + '="' + aNode.attributes[i].value + '"';
3174                }
3175                tag += ">\n";
3176                return tag + aContent + "</" + aNode.nodeName.toLowerCase() + ">\n";
3177        },
3178
3179/////////////////////////////////////////////////////////////////////
3180        doctypeToString : function(aDoctype){
3181                if(!aDoctype) return "";
3182                var ret = "<!DOCTYPE " + aDoctype.name;
3183                if(aDoctype.publicId) ret += ' PUBLIC "' + aDoctype.publicId + '"';
3184                if(aDoctype.systemId) ret += ' "'        + aDoctype.systemId + '"';
3185                ret += ">\n";
3186                return ret;
3187        },
3188
3189/////////////////////////////////////////////////////////////////////
3190        processDOMRecursively : function(aClass, rootNode){
3191                var curNode;
3192                for(curNode=rootNode.firstChild;curNode != null;curNode = curNode.nextSibling){
3193                        if(curNode.nodeName == "#text" || curNode.nodeName == "#comment") continue;
3194                        curNode = aClass.inspectNode(aClass, curNode);
3195                        aClass.processDOMRecursively(aClass, curNode);
3196                }
3197        },
3198
3199/////////////////////////////////////////////////////////////////////
3200        inspectNode : function(aClass, aNode){
3201                switch(aNode.nodeName.toLowerCase()){
3202                        case "img" : 
3203                        case "embed" : 
3204                                if(aNode.hasAttribute("onclick")) aNode = aClass.normalizeJSLink(aClass, aNode, "onclick");
3205                                var aFileName = aClass.download(aClass, aNode.src);
3206                                if(aFileName) aNode.setAttribute("src", aFileName);
3207                                break;
3208                        case "object" : 
3209                                var aFileName = aClass.download(aClass, aNode.data);
3210                                if (aFileName) aNode.setAttribute("data", aFileName);
3211                                break;
3212                        case "body" : 
3213                                var aFileName = aClass.download(aClass, aNode.background);
3214                                if (aFileName) aNode.setAttribute("background", aFileName);
3215                                break;
3216                        case "table" : 
3217                        case "tr" : 
3218                        case "th" : 
3219                        case "td" : 
3220                                var aFileName = aClass.download(aClass, aNode.getAttribute("background"));
3221                                if (aFileName) aNode.setAttribute("background", aFileName);
3222                                break;
3223                        case "input" : 
3224                                if(aNode.type.toLowerCase() == "image"){
3225                                        var aFileName = aClass.download(aClass, aNode.src);
3226                                        if(aFileName) aNode.setAttribute("src", aFileName);
3227                                }
3228                                break;
3229                        case "link" : 
3230                                if(aNode.rel.toLowerCase() == "stylesheet" && aNode.href.indexOf("chrome") != 0){
3231                                        return aClass.removeNodeFromParent(aNode);
3232                                }else if(aNode.rel.toLowerCase() == "shortcut icon" || aNode.rel.toLowerCase() == "icon"){
3233                                        var aFileName = aClass.download(aClass, aNode.href);
3234                                        if(aFileName) aNode.setAttribute("href", aFileName);
3235                                        if(aClass.frameNumber == 0 && !aClass.favicon) aClass.favicon = aFileName;
3236                                }else{
3237                                        aNode.setAttribute("href", aNode.href);
3238                                }
3239                                break;
3240                        case "base" : 
3241                                aNode.removeAttribute("href");
3242                                if(!aNode.hasAttribute("target")) return aClass.removeNodeFromParent(aNode);
3243                                break;
3244                        case "style" : 
3245                                return aClass.removeNodeFromParent(aNode);
3246                                break;
3247                        case "script" : 
3248                        case "noscript" : 
3249                                return aClass.removeNodeFromParent(aNode);
3250                                break;
3251                        case "a" : 
3252                                if(aNode.hasAttribute("href")){
3253                                        var href = aNode.getAttribute("href");
3254                                        if(href.match(/http:\/\/ad\.doubleclick\.net\//)){
3255                                                aNode.removeAttribute("href");
3256                                                aNode.innerHTML = "";
3257                                                break;
3258                                        }
3259                                }
3260                        case "area" : 
3261                                if(aNode.hasAttribute("onclick")) aNode = aClass.normalizeJSLink(aClass, aNode, "onclick");
3262                                if(!aNode.hasAttribute("href")) return aNode;
3263                                if(aNode.target == "_blank") aNode.setAttribute("target", "_top");
3264                                if(aNode.href.match(/^javascript:/i) ) aNode = aClass.normalizeJSLink(aClass, aNode, "href");
3265                                if(aNode.getAttribute("href").charAt(0) == "#") return aNode;
3266                                var ext = bitsAutocacheService.Common.splitFileName(bitsAutocacheService.Common.getFileName(aNode.href))[1].toLowerCase();
3267                                var flag = false;
3268                                switch(ext){
3269                                        case "jpg" : case "jpeg" : case "png" : case "gif" : case "tiff" : flag = true; break;
3270                                        case "mp3" : case "wav"  : case "ram" : case "rm"  : case "wma"  : flag = true; break;
3271                                        case "mpg" : case "mpeg" : case "avi" : case "mov" : case "wmv"  : flag = true; break;
3272                                        case "zip" : case "lzh"  : case "rar" : case "jar" : case "xpi"  : flag = true; break;
3273                                        default : aClass.linkURLs.push(aNode.href);
3274                                }
3275                                if(!flag && aNode.href.indexOf("file://") == 0 && !aNode.href.match(/\.html(?:#.*)?$/)) flag = true;
3276                                if(flag){
3277                                        var aFileName = aClass.download(aClass, aNode.href);
3278                                        if(aFileName) aNode.setAttribute("href", aFileName);
3279                                }else{
3280                                        aNode.setAttribute("href", aNode.href);
3281                                }
3282                                break;
3283                        case "form" : 
3284                                aNode.setAttribute("action", bitsAutocacheService.Common.resolveURL(aClass.refURLObj.spec, aNode.action));
3285                                break;
3286                        case "meta" : 
3287                                break;
3288                        case "frame"  : 
3289                        case "iframe" : 
3290                                var tmpRefURL = aClass.refURLObj;
3291                                aClass.frameNumber++
3292                                try{
3293                                        var src = aNode.src;
3294                                        var contentDocument;
3295                                        if(!contentDocument) contentDocument = aClass.frameList[aClass.frameNumber].document;
3296                                        if(!contentDocument){
3297                                                aNode.removeAttribute("src");
3298                                                break;
3299                                        }
3300                                        if(contentDocument.location.href.match(/http:\/\/ad\.doubleclick\.net\//)){
3301                                                aNode.removeAttribute("src");
3302                                                break;
3303                                        }
3304                                        var fileName = bitsAutocacheService.Common.getFileName(contentDocument.location.href);
3305                                        var splitFileName = bitsAutocacheService.Common.splitFileName(fileName);
3306                                        if(!splitFileName[0] || splitFileName[0] == "") splitFileName[0] = "index";
3307                                        splitFileName[0] = aClass.validateFileName(splitFileName[0]);
3308                                        var dataDir = aClass.AutocacheDir.clone();
3309                                        if(aClass.dataDirName) dataDir.append(aClass.dataDirName);
3310                                        if(!dataDir.exists()) dataDir.create(dataDir.DIRECTORY_TYPE, 0777);
3311                                        var newClass = new bitsAutocacheDocument(dataDir);
3312                                        newClass.id = null;
3313                                        var framedoc = contentDocument;
3314                                        var aCacheDir = dataDir.clone();
3315                                        splitFileName[0] = (splitFileName[0].length>8 ? splitFileName[0].substr(0,8) : splitFileName[0]);
3316                                        var newFile = newClass.cacheDocumentInternal(newClass, framedoc, splitFileName[0], aCacheDir);
3317                                        if(newFile) aNode.setAttribute("src", (aClass.dataDirName ? aClass.dataDirName + "/" : "") + newFile.leafName);
3318                                        var key;
3319                                        for(key in newClass.oldURL2newURL){
3320                                                if(typeof newClass.oldURL2newURL[key] == "function") continue;
3321                                                aClass.oldURL2newURL[key] = newClass.oldURL2newURL[key];
3322                                        }
3323                                        newClass.done();
3324                                        newClass = undefined;
3325                                }catch(ex){
3326                                        aClass._dump("WiredMarker ERROR: Failed to get document in a frame.\n\n" + ex);
3327                                }
3328                                aClass.refURLObj = tmpRefURL;
3329                                break;
3330                        case "xmp" : 
3331                                var pre = aNode.ownerDocument.createElement("pre");
3332                                pre.appendChild(aNode.firstChild);
3333                                aNode.parentNode.replaceChild(pre, aNode);
3334                                break;
3335                }
3336                if(aNode.style && aNode.style.cssText){
3337                        var newCSStext = aClass.inspectCSSText(aClass, aNode.style.cssText, aClass.refURLObj.spec);
3338                        if(newCSStext) aNode.setAttribute("style", newCSStext);
3339                }
3340                return aNode;
3341        },
3342
3343/////////////////////////////////////////////////////////////////////
3344        removeNodeFromParent : function(aNode){
3345                var newNode = aNode.ownerDocument.createTextNode("");
3346                aNode.parentNode.replaceChild(newNode, aNode);
3347                aNode = newNode;
3348                return aNode;
3349        },
3350
3351/////////////////////////////////////////////////////////////////////
3352        processCSSRecursively : function(aClass, aCSS){
3353                var content = "";
3354                if(!aCSS) return "";
3355                if(aCSS.disabled) return "";
3356                var medium = aCSS.media.mediaText;
3357                if(medium != "" && medium.indexOf("screen") < 0 && medium.indexOf("all") < 0) return "";
3358                if(aCSS.href && aCSS.href.indexOf("chrome") == 0) return "";
3359                var flag = false;
3360                var i;
3361                for(i=0;i<aCSS.cssRules.length;i++){
3362                        if(aCSS.cssRules[i].type == 1 || aCSS.cssRules[i].type == 4){
3363                                if(!flag){
3364                                        content += "\n/* ::::: " + aCSS.href + " ::::: */\n\n";
3365                                        flag = true;
3366                                }
3367                                content += aClass.inspectCSSText(aClass, aCSS.cssRules[i].cssText, (aCSS.href?aCSS.href: bitsAutocacheService.Common.getURLStringFromDocument(aClass.document) )) + "\n";
3368                        }else if(aCSS.cssRules[i].type == 3){
3369                                content += aClass.processCSSRecursively(aClass, aCSS.cssRules[i].styleSheet);
3370                        }
3371                }
3372                return content;
3373        },
3374
3375/////////////////////////////////////////////////////////////////////
3376        inspectCSSText : function(aClass, aCSStext, aCSShref){
3377                if(!aCSStext) return "";
3378                var re = new RegExp(/ url\(([^\'\)\s]+)\)/);
3379                var i = 0;
3380                while(aCSStext.match(re)){
3381                        if(++i > 10) break;
3382                        var relURL = RegExp.$1;
3383                        relURL = relURL.replace(/^\s*/g,"").replace(/\s*$/g,"").replace(/^(['"])(.+)\1$/,"$2");
3384                        var imgURL  = bitsAutocacheService.Common.resolveURL(aCSShref, relURL);
3385                        var imgFile = aClass.download(aClass, imgURL);
3386                        aCSStext = aCSStext.replace(re, " url('" + imgFile + "')");
3387                }
3388                aCSStext = aCSStext.replace(/([^\{\}])(\r|\n)/g, "$1\\A");
3389                re = new RegExp(/ content: \"(.*?)\"; /);
3390                if(aCSStext.match(re)){
3391                        var innerQuote = RegExp.$1;
3392                        innerQuote = innerQuote.replace(/\"/g, '\\"');
3393                        innerQuote = innerQuote.replace(/\\\" attr\(([^\)]+)\) \\\"/g, '" attr($1) "');
3394                        aCSStext = aCSStext.replace(re, ' content: "' + innerQuote + '"; ');
3395                }
3396                if(aCSStext.match(/ (quotes|voice-family): \"/)) return "";
3397                if(aCSStext.indexOf(" background: ") >= 0){
3398                        aCSStext = aCSStext.replace(/ -moz-background-[^:]+: -moz-[^;]+;/g, "");
3399                        aCSStext = aCSStext.replace(/ scroll 0(?:pt|px|%);/g, ";");
3400                }
3401                if(aCSStext.indexOf(" background-position: 0") >= 0) aCSStext = aCSStext.replace(/ background-position: 0(?:pt|px|%);/, " background-position: 0 0;");
3402                return aCSStext;
3403        },
3404
3405/////////////////////////////////////////////////////////////////////
3406        download : function(aClass, aURLSpec){
3407                if(!aURLSpec) return "";
3408                if(aURLSpec.indexOf("://") < 0) aURLSpec = bitsAutocacheService.Common.resolveURL(aClass.refURLObj.spec, aURLSpec);
3409                try{
3410                        var aURL = Components.classes['@mozilla.org/network/standard-url;1'].createInstance(Components.interfaces.nsIURL);
3411                        aURL.spec = aURLSpec;
3412                }catch(ex){
3413                        return "";
3414                }
3415                var newFileName = aURL.fileName.toLowerCase();
3416                if(!newFileName) newFileName = "untitled";
3417                newFileName = bitsAutocacheService.Common.validateFileName(newFileName);
3418                var ret = bitsAutocacheService.Common.splitFileName(newFileName);
3419                if(ret.length == 2 && ret[0].length>8){
3420                        ret[0] = aClass.fileNumber++;
3421                        newFileName = ret.join(".");
3422                }
3423                if(aClass.file2URL[newFileName] == undefined){
3424                }
3425                else if(aClass.file2URL[newFileName] != aURLSpec){
3426                        var seq = 1;
3427                        var fileLR = bitsAutocacheService.Common.splitFileName(newFileName);
3428                        if ( !fileLR[1] ) fileLR[1] = "dat";
3429                        newFileName = fileLR[0] + "_" + aClass.leftZeroPad3(seq) + "." + fileLR[1];
3430                        while(aClass.file2URL[newFileName] != undefined){
3431                                if(aClass.file2URL[newFileName] == aURLSpec){
3432                                        return (aClass.dataDirName ? aClass.dataDirName + "/" : "") + newFileName;
3433                                }
3434                                newFileName = fileLR[0] + "_" + aClass.leftZeroPad3(++seq) + "." + fileLR[1];
3435                        }
3436                }
3437                else{
3438                        return (aClass.dataDirName ? aClass.dataDirName + "/" : "") + newFileName;
3439                }
3440                if(aURL.schemeIs("http") || aURL.schemeIs("https") || aURL.schemeIs("ftp")){
3441                        var targetFile = aClass.AutocacheDir.clone();
3442                        if(aClass.dataDirName) targetFile.append(aClass.dataDirName);
3443                        if(!targetFile.exists()) targetFile.create(targetFile.DIRECTORY_TYPE, 0777);
3444                        targetFile.append(newFileName);
3445                        if(!targetFile.exists()){
3446                                aClass.httpTask[aClass.item.id]++;
3447                                try{
3448                                        var WBP = Components.classes['@mozilla.org/embedding/browser/nsWebBrowserPersist;1'].createInstance(Components.interfaces.nsIWebBrowserPersist);
3449                                        WBP.persistFlags |= WBP.PERSIST_FLAGS_FROM_CACHE;
3450                                       
3451                                        /* TODO: Not enough arguments exception issue needs to be addressed */
3452                                        /* See: https://developer.mozilla.org/en-US/docs/XPCOM_Interface_Reference/nsIWebBrowserPersist */
3453                                        /* See even: https://bugzilla.mozilla.org/show_bug.cgi?id=820522 */
3454                                       
3455                                        /* Dirty fix, might need to get replaced by a clean fix in case privacy information leak issues arise. */
3456                                        var privacyContext = null;
3457                                       
3458                                        WBP.saveURI(aURL, null, aClass.refURLObj, null, null, targetFile, privacyContext);
3459                                        var progressListener = {
3460                                                onLocationChange : function(webProgress, request, location){},
3461                                                onProgressChange : function(webProgress, request, curSelfProgress, maxSelfProgress, curTotalProgress, maxTotalProgress){},
3462                                                onSecurityChange : function(webProgress, request, state){},
3463                                                onStateChange    : function(webProgress, request, stateFlags, status){
3464                                                        if((WBP.currentState & WBP.PERSIST_STATE_FINISHED)){
3465                                                                if(targetFile && targetFile.exists()){
3466                                                                        aClass.httpTask[aClass.item.id]--;
3467                                                                        var infoFile = bitsAutocacheService._getSaveCacheInfoFile(targetFile.parent);
3468                                                                        if(infoFile){
3469                                                                                var info = bitsAutocacheService._getSaveCacheInfo(infoFile.parent);
3470                                                                                if(info && info.URL){
3471                                                                                        var histsdb = bitsAutocacheService._selectHistoryDB({uid_url:info.URL,hid_date:infoFile.parent.leafName});
3472                                                                                        if(histsdb){
3473                                                                                                histsdb[0].hid_filesize = targetFile.fileSize + parseInt(histsdb[0].hid_filesize);
3474                                                                                                bitsAutocacheService._updateHistoryDB({
3475                                                                                                        uid          : histsdb[0].uid,
3476                                                                                                        hid          : histsdb[0].hid,
3477                                                                                                        hid_filesize : histsdb[0].hid_filesize,
3478                                                                                                });
3479                                                                                        }
3480                                                                                }
3481                                                                        }
3482                                                                        if(aClass.httpTask[aClass.item.id]<=0){
3483                                                                                bitsAutocacheService.refresh(false,1000);
3484                                                                        }else{
3485                                                                        }
3486                                                                }else if(status != 0){
3487                                                                }
3488                                                        }
3489                                                },
3490                                                onStatusChange   : function(webProgress, request, status, message){},
3491                                        };
3492                                        WBP.progressListener = progressListener;
3493                                        aClass.file2URL[newFileName] = aURLSpec;
3494                                        aClass.oldURL2newURL[aURLSpec] = bitsAutocacheService.Common.convertFilePathToURL(targetFile.path);
3495                                        return (aClass.dataDirName ? aClass.dataDirName + "/" : "") + newFileName;
3496                                }
3497                                catch(ex) {
3498                                        dump("*** SCRAPPARTY_PERSIST_FAILURE: " + aURLSpec + "\n" + ex + "\n");
3499                                        aClass.httpTask[aClass.item.id]--;
3500                                        return "";
3501                                }
3502                        }else{
3503                                aClass.oldURL2newURL[aURLSpec] = bitsAutocacheService.Common.convertFilePathToURL(targetFile.path);
3504                                return (aClass.dataDirName ? aClass.dataDirName + "/" : "") + newFileName;
3505                        }
3506                }
3507                else if(aURL.schemeIs("file")){
3508                        var targetDir = aClass.AutocacheDir.clone();
3509                        if(aClass.dataDirName) targetDir.append(aClass.dataDirName);
3510                        if(!targetDir.exists()) targetDir.create(targetDir.DIRECTORY_TYPE, 0777);
3511                        var targetFile = targetDir.clone();
3512                        targetFile.append(newFileName);
3513                        if(!targetFile.exists()){
3514                                try {
3515                                        var orgFile = bitsAutocacheService.Common.convertURLToFile(aURLSpec);
3516                                        if(orgFile && orgFile.exists()){
3517                                                if(!orgFile.isFile()) return "";
3518                                                orgFile.copyTo(targetDir, newFileName);
3519                                                aClass.file2URL[newFileName] = aURLSpec;
3520                                                aClass.oldURL2newURL[aURLSpec] = bitsAutocacheService.Common.convertFilePathToURL(targetFile.path);
3521                                                return (aClass.dataDirName ? aClass.dataDirName + "/" : "") + newFileName;
3522                                        }else{
3523                                                return "";
3524                                        }
3525                                }
3526                                catch(ex) {
3527                                        aClass._dump("*** WIRED-MARKER_DOWNLOAD_FAILURE: " + aURLSpec + "\n" + ex + "\n");
3528                                        return "";
3529                                }
3530                        }else{
3531                                aClass.oldURL2newURL[aURLSpec] = bitsAutocacheService.Common.convertFilePathToURL(targetFile.path);
3532                                return (aClass.dataDirName ? aClass.dataDirName + "/" : "") + newFileName;
3533                        }
3534                }
3535        },
3536
3537/////////////////////////////////////////////////////////////////////
3538        leftZeroPad3 : function(num){
3539                if(num<10){return "00"+num;}else if(num<100){return "0"+num;}else{return num;}
3540        },
3541
3542/////////////////////////////////////////////////////////////////////
3543        normalizeJSLink : function(aClass, aNode, aAttr){
3544                var val = aNode.getAttribute(aAttr);
3545                if(!val.match(/\(\'([^\']+)\'/)) return aNode;
3546                val = RegExp.$1;
3547                if(val.indexOf("/") == -1 && val.indexOf(".") == -1) return aNode;
3548                val = bitsAutocacheService.Common.resolveURL(aClass.refURLObj.spec, val);
3549                if(aNode.nodeName.toLowerCase() == "img"){
3550                        if(aNode.parentNode.nodeName.toLowerCase() == "a"){
3551                                aNode.parentNode.setAttribute("href", val);
3552                                aNode.removeAttribute("onclick");
3553                        }else{
3554                                val = "window.open('" + val + "');";
3555                                aNode.setAttribute(aAttr, val);
3556                        }
3557                }
3558                else{
3559                        if(aNode.hasAttribute("href") && aNode.getAttribute("href").indexOf("http://") != 0){
3560                                aNode.setAttribute("href", val);
3561                                aNode.removeAttribute("onclick");
3562                        }
3563                }
3564                return aNode;
3565        },
3566
3567/////////////////////////////////////////////////////////////////////
3568        _dump : function(aString){
3569                window.top.bitsMarkingCollection._dump(aString);
3570        },
3571};
3572
3573
Note: See TracBrowser for help on using the repository browser.