]> gitweb @ CieloNegro.org - sugar.git/blob - dot-files/_vimperator/plugin/_libly_js
Auto commit by The Sugar System.
[sugar.git] / dot-files / _vimperator / plugin / _libly_js
1 /*** BEGIN LICENSE BLOCK {{{
2     Copyright (c) 2008 suVene<suvene@zeromemory.info>
3
4     distributable under the terms of an MIT-style license.
5     http://www.opensource.jp/licenses/mit-license.html
6 }}}  END LICENSE BLOCK ***/
7 // PLUGIN_INFO//{{{
8 var PLUGIN_INFO =
9 <VimperatorPlugin>
10     <name>libly(filename _libly.js)</name>
11     <description>Vimperator plugins library?</description>
12     <description lang="ja">適当なライブラリっぽいものたち。</description>
13     <author mail="suvene@zeromemory.info" homepage="http://zeromemory.sblo.jp/">suVene</author>
14     <license>MIT</license>
15     <version>0.1.24</version>
16     <minVersion>1.2</minVersion>
17     <maxVersion>2.0pre</maxVersion>
18     <updateURL>http://svn.coderepos.org/share/lang/javascript/vimperator-plugins/trunk/_libly.js</updateURL>
19     <detail><![CDATA[
20 == Objects ==
21 - liberator.plugins.libly.$U
22 - liberator.plugins.libly.Request
23 - liberator.plugins.libly.Response
24 - liberator.plugins.libly.Wedata
25
26 == Logger ==
27 getLogger(prefix):
28     log(msg, level), echo(msg, flg), echoerr(msg)
29     のメソッドを持つ logger インスタンスを取得します。
30     ログの書式は prefix + ': ' + yyyy/MM/dd + msg となります。
31
32 == Object Utility ==
33 extend(dst, src):
34     オブジェクトを拡張します。
35 A(iterable):
36     オブジェクトを配列にします。
37 around(obj, name, func):
38   obj がもつ name 関数を、func に置き換えます。
39   func は
40     function (next, args) {...}
41   という形で呼ばれます。
42   next はオリジナルの関数を呼び出すための関数、
43   args はオリジナルの引数列です。
44   next には引数を渡す必要はありません。
45 bind(obj, func):
46     func に obj を bind します。
47     func内からは this で obj が参照できるようになります。
48 eval(text):
49     Sandbox による、window.eval を極力利用するようにします。
50     Snadbox が利用できない場合は、unsafe な window の eval が直接利用されます。
51 evalJson(str, toRemove):
52     str を decode します。
53     toRemove が true の場合、文字列の前後を1文字削除します。
54     "(key:value)" 形式の場合などに true を指定して下さい。
55 dateFormat(dtm, fmt):
56     Date型インスタンスを、指定されたフォーマットで文字列に変換します。
57     fmt を省略した場合、"%y/%M/%d %h:%m:%s" となります。
58 runnable(generator):
59     gererator を実行し、再帰的に resume する為の引数を渡します。
60
61 ==  Browser ==
62 getSelectedString:
63     window の選択文字列を返却します。
64 getUserAndPassword(hostname, formSubmitURL, username):
65     login-manager から [username, password] を取得します。
66     引数の username が省略された場合、検索された 1件目を返却します。
67     データが存在しない場合は、null を返却します。
68
69 == System ==
70 readDirectory(path, fileter, func):
71     path で指定したディレクトリから、filter で指定された正規表現に match する場合、
72     func をファイル名を引数にコールバックします。
73     filter は Function を指定することも可能です。
74
75 == HTML, XML, DOM, E4X ==
76 pathToURL(a, baseURL, doc):
77     相対パスを絶対パスに変換します。
78 getHTMLFragment(html):
79     <html>※1</html>
80     ※1 の文字列を取得します。
81 stripTags(str, tags):
82     str から tags で指定されたタグを取り除いて返却します。
83     tags は文字列、または配列で指定して下さい。
84 createHTMLDocument(str, xmlns):
85     引数 str より、HTMLFragment を作成します。
86 getFirstNodeFromXPath(xpath, context):
87     xpath を評価しオブジェクトをを返却します。
88 getNodesFromXPath(xpath, context, callback, thisObj):
89     xpath を評価し snapshot の配列を返却します。
90 xmlSerialize(xml):
91     xml を文字列化します。
92 xmlToDom(node, doc, nodes):
93     for vimperator1.2.
94     @see vimperator2.0pre util.
95 getElementPosition(elem):
96     elem の offset を返却します。
97     return {top: 0, left: 0}
98 toStyleText(style):
99     スタイルが格納されているオブジェクトを
100     >||
101         position: fixed;
102         left: 10px;
103     ||<
104     のような文字列に変換します。
105
106 == Object Request ==
107 Request(url, headers, options):
108     コンストラクタ
109     url:
110         HTTPリクエスト先のURL
111     headers:
112         以下のようにHTTPヘッダの値を指定できる(省略可)
113         >||
114         {
115             'Referrer' : 'http://example.com/'
116         }
117         ||<
118         以下の値はデフォルトで設定される('Content-type'はPOST時のみ)
119         >||
120         {
121             'Accept': 'text/javascript, application/javascript, text/html, application/xhtml+xml, application/xml, text/xml, */*;q=0.1',
122             'Content-type': 'application/x-www-form-urlencoded; charset=' + options.encodingの値
123         }
124         ||<
125
126     options:
127         オプションとして以下のようなオブジェクトを指定できる(省略可)
128         asynchronous:
129             true: 同期モード/false: 非同期モード(デフォルト:true)
130         encoding:
131             エンコーディング(デフォルト: 'UTF-8')
132         username:
133             BASIC認証時のuser名
134         password:
135             BASIC認証時のパスワード
136         postBody:
137             POSTメソッドにより送信するbody
138 addEventLister(name, func):
139     イベントリスナを登録する。
140     name:
141         'onSuccess':
142             成功時
143         'onFailure':
144             失敗を表すステータスコードが返ってきた時
145         'onException':
146             例外発生時
147     func:
148         イベント発火時の処理
149         引数として以下Responseオブジェクトが渡される
150 get():
151     GETメソッドによりHTTPリクエストを発行する。
152 post():
153     POSTメソッドによりHTTPリクエストを発行する。
154
155 == Object Response ==
156 HTTPレスポンスを表すオブジェクト
157 req:
158     レスポンスと対となるRequestオブジェクト
159 doc:
160     レスポンスから生成されたHTMLDocumentオブジェクト
161 isSuccess():
162     ステータスコードが成功を表していればtrue、失敗であればfalse
163 getStatus():
164     ステータスコードを取得する
165 getStatusText():
166     ステータを表す文字列を取得する
167 getHTMLDocument(xpath, xmlns, ignoreTags, callback, thisObj):
168     レスポンスからHTMLDocumentオブジェクトを生成し、xpath を評価した結果の snapshot の配列を返す
169
170 == Object Wedata ==
171 ~/vimperator/info/profile_name/plugins-libly-wedata-?????
172 に store されます。
173 getItems(expire, itemCallback, finalCallback):
174     インスタンス作成時に指定した dbname から、item を読込みます。
175 === TODO ===
176 clearCache:
177   wedata 読込み成功したら、強制的にキャッシュと置き換えるの作って!
178
179     ]]></detail>
180 </VimperatorPlugin>;
181 //}}}
182 //if (!liberator.plugins.libly) {
183
184 liberator.plugins.libly = {};
185 var libly = liberator.plugins.libly;
186
187 libly.$U = {//{{{
188     // Logger {{{
189     getLogger: function(prefix) {
190         return new function() {
191             this.log = function(msg, level) {
192                 if (typeof msg == 'object') msg = util.objectToString(msg);
193                 liberator.log(libly.$U.dateFormat(new Date()) + ': ' + (prefix || '') + ': ' + msg, (level || 0));
194             };
195             this.echo = function(msg, flg) {
196                 flg = flg || commandline.FORCE_MULTILINE;
197                 // this.log(msg);
198                 liberator.echo(msg, flg);
199             };
200             this.echoerr = function(msg) {
201                 this.log('error: ' + msg);
202                 liberator.echoerr(msg);
203             };
204         }
205     },
206     // }}}
207     // Object Utility {{{
208     extend: function(dst, src) {
209         for (let prop in src)
210             dst[prop] = src[prop];
211         return dst;
212     },
213     A: function(iterable) {
214         var ret = [];
215         if (!iterable) return ret;
216         if (typeof iterable == 'string') return [iterable];
217         if (!(typeof iterable == 'function' && iterable == '[object NodeList]') &&
218             iterable.toArray) return iterable.toArray();
219         if (typeof iterable.length != 'undefined') {
220             for (let i = 0, len = iterable.length; i < len; ret.push(iterable[i++]));
221         } else {
222             for each (let item in iterable) ret.push(item);
223         }
224         return ret;
225     },
226     around: function around (obj, name, func) {
227         let next = obj[name];
228         let current = obj[name] = function () {
229             let self = this, args = arguments;
230             return func.call(self, function () next.apply(self, args), args);
231         };
232         return [next, current];
233     },
234     bind: function(obj, func) {
235         return function() {
236             return func.apply(obj, arguments);
237         }
238     },
239     eval: function(text) {
240         var fnc = window.eval;
241         var sandbox;
242         try {
243             sandbox = new Components.utils.Sandbox("about:blank");
244             if (Components.utils.evalInSandbox('true', sandbox) === true) {
245                 fnc = function(text) { return Components.utils.evalInSandbox(text, sandbox); };
246             }
247         } catch (e) { liberator.log('warning: _libly.js is working with unsafe sandbox.'); }
248
249         return fnc(text);
250     },
251     evalJson: function(str, toRemove) {
252         var json;
253         try {
254             json = Components.classes['@mozilla.org/dom/json;1'].getService(Components.interfaces.nsIJSON);
255             if (toRemove) str = str.substring(1, str.length - 1);
256             return json.decode(str);
257         } catch (e) { return null; }
258     },
259     dateFormat: function(dtm, fmt) {
260         var d = {
261             y: dtm.getFullYear(),
262             M: dtm.getMonth() + 1,
263             d: dtm.getDate(),
264             h: dtm.getHours(),
265             m: dtm.getMinutes(),
266             s: dtm.getSeconds(),
267             '%': '%'
268         };
269         for (let [n, v] in Iterator(d)) {
270             if (v < 10)
271                 d[n] = '0' + v;
272         }
273         return (fmt || '%y/%M/%d %h:%m:%s').replace(/%([yMdhms%])/g, function (_, n) d[n]);
274     },
275     /**
276      * example)
277      *  $U.runnable(function(resume) {
278      *      // execute asynchronous function.
279      *      // goto next yield;
280      *      var val = yield setTimeout(function() { resume('value!'), 1000) });
281      *      alert(val);  // value!
282      *      yield;
283      *  });
284      */
285     runnable: function(generator) {
286         var it = generator(function(value) {
287                     try { it.send(value); } catch (e) {}
288                  });
289         it.next();
290     },
291     // }}}
292     // Browser {{{
293     getSelectedString: function() {
294          return (new XPCNativeWrapper(window.content.window)).getSelection().toString();
295     },
296     getUserAndPassword: function(hostname, formSubmitURL, username) {
297         var passwordManager, logins;
298         try {
299             passwordManager = Cc["@mozilla.org/login-manager;1"].getService(Ci.nsILoginManager);
300             logins = passwordManager.findLogins({}, hostname, formSubmitURL, null);
301             if (logins.length) {
302                 if (username) {
303                     for (let i = 0, len = logins.lengh; i < len; i++) {
304                         if (logins[i].username == username)
305                             return [logins[i].username, logins[i].password]
306                     }
307                     liberator.log(this.dateFormat(new Date()) +': [getUserAndPassword] username notfound');
308                     //throw 'username notfound.';
309                     return [];
310                 } else {
311                     return [logins[0].username, logins[0].password];
312                 }
313             } else {
314                 liberator.log(this.dateFormat(new Date()) + ': [getUserAndPassword] account notfound');
315                 return [];
316             }
317         } catch (e) {
318             liberator.log(this.dateFormat(new Date()) + ': [getUserAndPassword] error: ' + e, 0);
319             return null;
320         }
321     },
322     // }}}
323     // System {{{
324     readDirectory: function(path, filter, func) {
325         var d = io.getFile(path);
326         if (d.exists() && d.isDirectory()) {
327             let enm = d.directoryEntries;
328             let flg = false;
329             while (enm.hasMoreElements()) {
330                 let item = enm.getNext();
331                 item.QueryInterface(Components.interfaces.nsIFile);
332                 flg = false;
333                 if (typeof filter == 'string') {
334                     if ((new RegExp(filter)).test(item.leafName)) flg = true;
335                 } else if (typeof filter == 'function') {
336                     flg = filter(item);
337                 }
338                 if (flg) func(item);
339             }
340         }
341     },
342     // }}}
343     // HTML, XML, DOM, E4X {{{
344     pathToURL: function(a, baseURL, doc) {
345         if (!a) return '';
346         var XHTML_NS = "http://www.w3.org/1999/xhtml";
347         var XML_NS   = "http://www.w3.org/XML/1998/namespace";
348         //var path = (a.href || a.getAttribute('src') || a.action || a.value || a);
349         var path = (a.getAttribute('href') || a.getAttribute('src') || a.action || a.value || a);
350         if (/^https?:\/\//.test(path)) return path;
351         var link = (doc || window.content.documtent).createElementNS(XHTML_NS, 'a');
352         link.setAttributeNS(XML_NS, 'xml:base', baseURL);
353         link.href = path;
354         return link.href;
355     },
356     getHTMLFragment: function(html) {
357         if (!html) return html;
358         return html.replace(/^[\s\S]*?<html(?:[ \t\n\r][^>]*)?>|<\/html[ \t\r\n]*>[\S\s]*$/ig, '');
359     },
360     stripTags: function(str, tags) {
361         var ignoreTags = '(?:' + [].concat(tags).join('|') + ')';
362         return str.replace(new RegExp('<' + ignoreTags + '(?:[ \\t\\n\\r][^>]*|/)?>([\\S\\s]*?)<\/' + ignoreTags + '[ \\t\\r\\n]*>', 'ig'), '');
363     },
364     createHTMLDocument: function(str, xmlns, doc) {
365         let root = document.createElementNS("http://www.w3.org/1999/xhtml", "html");
366         let uhService = Cc["@mozilla.org/feed-unescapehtml;1"].getService(Ci.nsIScriptableUnescapeHTML);
367         let text = str.replace(/^[\s\S]*?<body([ \t\n\r][^>]*)?>[\s]*|<\/body[ \t\r\n]*>[\S\s]*$/ig, '');
368         let fragment = uhService.parseFragment(text, false, null, root);
369         let htmlFragment = document.implementation.createDocument(null, 'html', null);
370         htmlFragment.documentElement.appendChild(htmlFragment.importNode(fragment,true));
371         return htmlFragment;
372         /* うまく動いていない場合はこちらに戻してください
373         doc = doc || window.content.document;
374         var htmlFragment = doc.implementation.createDocument(null, 'html', null);
375         var range = doc.createRange();
376         range.setStartAfter(doc.body);
377         htmlFragment.documentElement.appendChild(htmlFragment.importNode(range.createContextualFragment(str), true));
378         return htmlFragment;
379         */
380     },
381     getFirstNodeFromXPath: function(xpath, context) {
382         if (!xpath) return null;
383         context = context || window.content.document;
384         var result = (context.ownerDocument || context).evaluate(xpath, context, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
385         return result.singleNodeValue || null;
386     },
387     getNodesFromXPath: function(xpath, context, callback, thisObj) {
388         var ret = [];
389         if (!xpath) return ret;
390         context = context || window.content.document;
391         var nodesSnapshot = (context.ownerDocument || context).evaluate(xpath, context, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
392         for (let i = 0, l = nodesSnapshot.snapshotLength; i < l; i++) {
393             if (typeof callback == 'function') callback.call(thisObj, nodesSnapshot.snapshotItem(i), i);
394             ret.push(nodesSnapshot.snapshotItem(i));
395         }
396         return ret;
397     },
398     xmlSerialize: function(xml) {
399         try {
400             return (new XMLSerializer()).serializeToString(xml)
401                                         .replace(/<!--(?:[^-]|-(?!->))*-->/g, '')
402                                         .replace(/<\s*\/?\s*\w+/g, function(all) all.toLowerCase());
403         } catch (e) { return '' }
404     },
405     xmlToDom: function xmlToDom(node, doc, nodes)
406     {
407         XML.prettyPrinting = false;
408         switch (node.nodeKind())
409         {
410             case "text":
411                 return doc.createTextNode(node);
412             case "element":
413                 let domnode = doc.createElementNS(node.namespace(), node.localName());
414                 for each (let attr in node.@*)
415                     domnode.setAttributeNS(attr.name() == "highlight" ? NS.uri : attr.namespace(), attr.name(), String(attr));
416                 for each (let child in node.*)
417                     domnode.appendChild(arguments.callee(child, doc, nodes));
418                 if (nodes && node.@key)
419                     nodes[node.@key] = domnode;
420                 return domnode;
421         }
422     },
423     getElementPosition: function(elem) {
424         var offsetTrail = elem;
425         var offsetLeft  = 0;
426         var offsetTop   = 0;
427         while (offsetTrail) {
428             offsetLeft += offsetTrail.offsetLeft;
429             offsetTop  += offsetTrail.offsetTop;
430             offsetTrail = offsetTrail.offsetParent;
431         }
432         offsetTop = offsetTop || null;
433         offsetLeft = offsetLeft || null;
434         return {top: offsetTop, left: offsetLeft};
435     },
436     toStyleText: function(style) {
437         var result = '';
438         for (let name in style) {
439             result += name.replace(/[A-Z]/g, function (c) ('-' + c.toLowerCase())) +
440                       ': ' +
441                       style[name] +
442                       ';\n';
443         }
444         return result;
445     }
446     // }}}
447 };
448 //}}}
449
450 libly.Request = function() {//{{{
451     this.initialize.apply(this, arguments);
452 };
453 libly.Request.EVENTS = ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
454 libly.Request.requestCount = 0;
455 libly.Request.prototype = {
456     initialize: function(url, headers, options) {
457         this.url = url;
458         this.headers = headers || {};
459         this.options = libly.$U.extend({
460             asynchronous: true,
461             encoding: 'UTF-8'
462         }, options || {});
463         this.observers = {};
464     },
465     addEventListener: function(name, func) {
466         try {
467             if (typeof this.observers[name] == 'undefined') this.observers[name] = [];
468             this.observers[name].push(func);
469         } catch (e) {
470             if (!this.fireEvent('onException', new libly.Response(this), e)) throw e;
471         }
472     },
473     fireEvent: function(name, args, asynchronous) {
474         if (!(this.observers[name] instanceof Array)) return false;
475         this.observers[name].forEach(function(event) {
476             if (asynchronous) {
477                 setTimeout(event, 10, args);
478             } else {
479                 event(args);
480             }
481         });
482         return true;
483     },
484     _complete: false,
485     _request: function(method) {
486
487         try {
488             libly.Request.requestCount++;
489
490             this.method = method;
491             this.transport = new XMLHttpRequest();
492             this.transport.open(method, this.url, this.options.asynchronous, this.options.username, this.options.password);
493
494             this.transport.onreadystatechange = libly.$U.bind(this, this._onStateChange);
495             this.setRequestHeaders();
496             this.transport.overrideMimeType('text/html; charset=' + this.options.encoding);
497
498             this.body = this.method == 'POST' ? this.options.postBody : null;
499
500             this.transport.send(this.body);
501
502             // Force Firefox to handle ready state 4 for synchronous requests
503             if (!this.options.asynchronous && this.transport.overrideMimeType)
504                 this._onStateChange();
505
506         } catch (e) {
507             if (!this.fireEvent('onException', new libly.Response(this), e)) throw e;
508         }
509     },
510     _onStateChange: function() {
511         var readyState = this.transport.readyState;
512         if (readyState > 1 && !(readyState == 4 && this._complete))
513             this.respondToReadyState(this.transport.readyState);
514     },
515     getStatus: function() {
516         try {
517             return this.transport.status || 0;
518         } catch (e) { return 0; }
519     },
520     isSuccess: function() {
521         var status = this.getStatus();
522         return !status || (status >= 200 && status < 300);
523     },
524     respondToReadyState: function(readyState) {
525         var state = libly.Request.EVENTS[readyState];
526         var res = new libly.Response(this);
527
528         if (state == 'Complete') {
529             libly.Request.requestCount--;
530             try {
531                 this._complete = true;
532                 this.fireEvent('on' + (this.isSuccess() ? 'Success' : 'Failure'), res, this.options.asynchronous);
533             } catch (e) {
534                 if (!this.fireEvent('onException', res, e)) throw e;
535             }
536         }
537     },
538     setRequestHeaders: function() {
539         var headers = {
540             'Accept': 'text/javascript, application/javascript, text/html, application/xhtml+xml, application/xml, text/xml, */*;q=0.1'
541         };
542
543         if (this.method == 'POST') {
544             headers['Content-type'] = 'application/x-www-form-urlencoded' +
545                 (this.options.encoding ? '; charset=' + this.options.encoding : '');
546
547             if (this.transport.overrideMimeType) {
548                 let year = parseInt((navigator.userAgent.match(/\bGecko\/(\d{4})/) || [0, 2005])[1], 10);
549                 if (0 < year && year < 2005)
550                      headers['Connection'] = 'close';
551             }
552         }
553
554         for (let key in this.headers)
555             if (this.headers.hasOwnProperty(key)) headers[key] = this.headers[key];
556
557         for (let name in headers)
558             this.transport.setRequestHeader(name, headers[name]);
559     },
560     get: function() {
561         this._request('GET');
562     },
563     post: function() {
564         this._request('POST');
565     }
566 };//}}}
567
568 libly.Response = function() {//{{{
569     this.initialize.apply(this, arguments);
570 };
571 libly.Response.prototype = {
572     initialize: function(req) {
573         this.req = req;
574         this.transport = req.transport;
575         this.isSuccess = req.isSuccess;
576         this.readyState = this.transport.readyState;
577
578         if (this.readyState == 4) {
579             this.status = this.getStatus();
580             this.statusText = this.getStatusText();
581             this.responseText = (this.transport.responseText == null) ? '' : this.transport.responseText;
582         }
583
584         this.doc = null;
585         this.htmlFragmentstr = '';
586     },
587     status: 0,
588     statusText: '',
589     getStatus: libly.Request.prototype.getStatus,
590     getStatusText: function() {
591         try {
592             return this.transport.statusText || '';
593         } catch (e) { return ''; }
594     },
595     getHTMLDocument: function(xpath, xmlns, ignoreTags, callback, thisObj) {
596         if (!this.doc) {
597             //if (doc.documentElement.nodeName != 'HTML') {
598             //    return new DOMParser().parseFromString(str, 'application/xhtml+xml');
599             //}
600             this.htmlFragmentstr = libly.$U.getHTMLFragment(this.responseText);
601             this.htmlStripScriptFragmentstr = libly.$U.stripTags(this.htmlFragmentstr, ignoreTags);
602             this.doc = libly.$U.createHTMLDocument(this.htmlStripScriptFragmentstr, xmlns);
603         }
604         if (!xpath) xpath = '//*';
605         return libly.$U.getNodesFromXPath(xpath, this.doc, callback, thisObj);
606     }
607 };
608 //}}}
609
610 libly.Wedata = function(dbname) { // {{{
611     this.initialize.apply(this, arguments);
612 };
613 libly.Wedata.prototype = {
614     initialize: function(dbname) {
615         this.HOST_NAME = 'http://wedata.net/';
616         this.dbname = dbname;
617         this.logger = libly.$U.getLogger('libly.Wedata');
618     },
619     getItems: function(expire, itemCallback, finalCallback) {
620
621         var logger = this.logger;
622         var STORE_KEY = 'plugins-libly-wedata-' + this.dbname + '-items';
623         var store = storage.newMap(STORE_KEY, true);
624         var cache = store && store.get('data');
625
626         if (store && cache && new Date(store.get('expire')) > new Date()) {
627             logger.log('return cache. ');
628             cache.forEach(function(item) { if (typeof itemCallback == 'function') itemCallback(item); });
629             if (typeof finalCallback == 'function')
630                 finalCallback(true, cache);
631             return;
632         }
633
634         expire = expire || 0;
635
636         function errDispatcher(msg, cache) {
637             if (cache) {
638                 logger.log('return cache. -> ' + msg);
639                 cache.forEach(function(item) { if (typeof itemCallback == 'function') itemCallback(item); });
640                 if (typeof finalCallback == 'function')
641                     finalCallback(true, cache);
642             } else {
643                 logger.log(msg + ': cache notfound.');
644                 if (typeof finalCallback == 'function')
645                     finalCallback(false, msg);
646             }
647         }
648
649         var req = new libly.Request(this.HOST_NAME + 'databases/' + this.dbname + '/items.json');
650         req.addEventListener('onSuccess', libly.$U.bind(this, function(res) {
651             var text = res.responseText;
652             if (!text) {
653                 errDispatcher('respons is null.', cache);
654                 return;
655             }
656             var json = libly.$U.evalJson(text);
657             if (!json) {
658                 errDispatcher('failed eval json.', cache);
659                 return;
660             }
661             logger.log('success get wedata.');
662             store.set('expire', new Date(new Date().getTime() + expire).toString());
663             store.set('data', json);
664             store.save();
665             json.forEach(function(item) { if (typeof itemCallback == 'function') itemCallback(item); });
666             if (typeof finalCallback == 'function')
667                 finalCallback(true, json);
668         }));
669         req.addEventListener('onFailure', function() errDispatcher('onFailure', cache));
670         req.addEventListener('onException', function() errDispatcher('onException', cache));
671         req.get();
672     }
673 };
674 //}}}
675
676 //}
677 // vim: set fdm=marker sw=4 ts=4 sts=0 et:
678