aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsuVene2008-12-08 18:04:17 +0000
committersuVene2008-12-08 18:04:17 +0000
commit4012d388f4e4698ac13e30f0d8d3c310cdfe55d5 (patch)
treea5759baaed32f98fefc96af30d3b930d4675e9e8
parenta9eaeea1f3d7fdff871a94801d7b278b5def26ba (diff)
downloadvimperator-plugins-4012d388f4e4698ac13e30f0d8d3c310cdfe55d5.tar.bz2
*SubjectHttp定義.
*registerするときに下位クラスから基底クラスを指定するように変更. *notifier/observer/subject の PLUGIN_INFO対応 @see http://coderepos.org/share/browser/lang/javascript/vimperator-plugins/trunk/pluginManager.js *ほか. git-svn-id: http://svn.coderepos.org/share/lang/javascript/vimperator-plugins/trunk@26152 d0d07461-0603-4401-acd4-de1884942a52
-rw-r--r--_libly.js10
-rw-r--r--notifier.js185
-rw-r--r--notifier/observer_growl.js60
-rw-r--r--notifier/subject_hatelabo_bottle.js89
4 files changed, 245 insertions, 99 deletions
diff --git a/_libly.js b/_libly.js
index e9c6fa6..8644a62 100644
--- a/_libly.js
+++ b/_libly.js
@@ -5,7 +5,7 @@ var PLUGIN_INFO =
<description>vimperator plugins library?</description>
<description lang="ja">適当なライブラリっぽいものたち。</description>
<author mail="suvene@zeromemory.info" homepage="http://zeromemory.sblo.jp/">suVene</author>
- <version>0.1.1</version>
+ <version>0.1.2</version>
<minVersion>1.2</minVersion>
<maxVersion>2.0pre</maxVersion>
<detail><![CDATA[
@@ -150,6 +150,14 @@ lib.$U = {//{{{
}
}
},
+ xmlSerialize: function(xml) {
+ try {
+ return (new XMLSerializer()).serializeToString(xml)
+ .replace(/<[^>]+>/g, function(all) all.toLowerCase())
+ .replace(/<!--(?:[^-]|-(?!->))*-->/g, ''); // actually
+ //.replace(/<!--(?:[^-]|-(?!-))*-->/g, ''); // strictly
+ } catch (e) { return '' }
+ }
};
//}}}
diff --git a/notifier.js b/notifier.js
index 126c523..5dcdfe5 100644
--- a/notifier.js
+++ b/notifier.js
@@ -1,22 +1,112 @@
-/**
- * ==VimperatorPlugin==
- * @name notifier.js
- * @description notice of change framework.
- * @description-ja 変更通知フレームワーク。
- * @author suVene suvene@zeromemory.info
- * @version 0.1.0
- * @minVersion 2.0pre
- * @maxVersion 2.0pre
- * Last Change: 07-Dec-2008.
- * ==/VimperatorPlugin==
- *
- * HEAD COMMENT {{{
- * }}}
- */
+// PLUGIN_INFO//{{{
+var PLUGIN_INFO =
+<VimperatorPlugin>
+ <name>{name}</name>
+ <description>notice of change framework.</description>
+ <description lang="ja">変更通知フレームワーク。</description>
+ <author mail="suvene@zeromemory.info" homepage="http://zeromemory.sblo.jp/">suVene</author>
+ <version>0.1.0</version>
+ <minVersion>2.0pre</minVersion>
+ <maxVersion>2.0pre</maxVersion>
+ <detail><![CDATA[
+== Command ==
+:notifierstart:
+ 変更通知をスタートします。
+:notifierrestart:
+ 変更通知をリスタートします。
+:notifierstop:
+ 変更通知をストップします。
+
+== Observer ==
+* 通知された変更を扱うオブジェクトを定義します。
+Subject からの Message オブジェクトを解析し、何らかの動作を行います。
+Observer ⇒ Subject への依存は高くて OK です。
+
+* 命名規約
+prefix に 'observer_' を付け、'rumtimepath/notifier' の下にインストールして下さい。
+ex.)'${rumtimepath}/notifier/observer_XXX.js'
+
+* 登録方法
+liberator.plugins.notifier.observer.register(baseClass, extendsMethods)
+baseClass:
+ 基底クラスとなります。現在以下の基底クラスが存在します。
+ - liberator.plugins.notifier.Observer
+extendsMethosd:
+ 基底クラスの拡張となるメソッドをハッシュ形式で渡します。
+ 実装するメソッドは基底クラスのルールに従って下さい。
+
+* 基底クラスの説明
+** librator.plugins.notifier.Observer
+Observerの基本クラスです。
+initialize():
+ 必要の無い場合、実装しなくても OK です。
+ インスタンス生成時に1度だけフレームワークによって呼び出されます。
+ 初期化処理など必要な処理を実装して下さい。
+update(liberator.plugins.notifier.Message):
+ 必ず実装して下さい。
+ Subject からの変更通知がなされた場合、引数 Message と共にフレームワークより呼び出されます。
+
+== Subject ==
+* 変更を検知し Observer に通知します。
+原則、observer との依存を少なくして下さい。
+(Message の解析の役割は Observer にある)
+
+* 命名規約
+prefix に 'subject_' を付け、'rumtimepath/notifier' の下にインストールして下さい。
+ex.)'${rumtimepath}/notifier/subject_XXX.js'
+
+* 登録方法
+liberator.plugins.notifier.subject.register(baseClass, extendsMethods)
+baseClass:
+ 基底クラスとなります。現在以下の基底クラスが存在します。
+ - liberator.plugins.notifier.Subject
+ - liberator.plugins.notifier.SubjectHttp
+extendsMethosd:
+ 基底クラスへの拡張をハッシュ形式で渡します。
+
+* 基底クラスの説明
+** librator.plugins.notifier.Subject
+Subject の基本クラスです。
+interval:
+ 秒で変更チェックするインターバルを指定します。デフォルトは 60 です。
+initialize():
+ 必要の無い場合、実装しなくても OK です。
+ インスタンス生成時に1度だけフレームワークによって呼び出されます。
+ 初期化処理など必要な処理を実装して下さい。
+check():
+ 必ず実装して下さい。
+ 指定したインターバルごとにフレームワークによって呼び出されます。
+ 変更を検知した場合、liberator.plugins.notifier.Message のインスタンスを引数に
+ this.notify(message) を呼び出してください。
+
+** librator.plugins.notifier.SubjectHttp
+Httpを利用した変更検知の基底クラスです。
+リクエスト内容をキャッシュします。
+options{}:
+ url:
+ URL を指定します。
+ headers{}:
+ リクエストに header が必要な場合ハッシュで指定します。
+ extra{}:
+ リクエストのオプションです。ハッシュで指定します。
+ 以下の key が有効です。
+ asynchronose (false), encoding(default utf-8)
+parse(liberator.pluginsnotifier.Request):
+ 必ず実装して下さい。
+ リクエストを解析した結果を返却して下さい。
+diff(cache, parsed):
+ 必ず実装して下さい。
+ this.parse() による解析結果と、そのキャッシュとの差分を抽出して返却して下さい。
+buildMessages(diff):
+ 必ず実装して下さい。
+ this.diff() により抽出されたオブジェクトを元に、liberator.plugins.notifier.Message のインスタンス、
+ または、その配列を返却して下さい。
+ ]]></detail>
+</VimperatorPlugin>;
+//}}}
(function() {
-io.sourceFromRuntimePath(['libly.js']);
if (!liberator.plugins.libly) {
- liberator.log('notifier: needs libly.js');
+ liberator.log('notifier: needs _libly.js');
return;
}
@@ -37,11 +127,10 @@ function bootstrap() {
this.initialize.apply(this, arguments);
};
Loader.prototype = {
- initialize: function(name, registerHook) {
+ initialize: function(name) {
liberator.plugins.notifier[name] = this;
this.name = name;
this.plugins = [];
- this.registerHook = registerHook;
this.load(name);
},
load: function(name) {
@@ -56,8 +145,8 @@ function bootstrap() {
});
});
},
- register: function(plugin) {
- this.plugins.push(this.registerHook(plugin));
+ register: function(baseClass, pluginExtends) {
+ this.plugins.push(new baseClass(pluginExtends));
},
unregister: function(plugin) {
var ret = [];
@@ -105,8 +194,7 @@ function bootstrap() {
__initialize__: function(args) {
this.isActive = false;
this.observers = [];
- this.interval = 0;
- //if (this.interval < 60) this.interval = 60;
+ this.interval = 60;
this.__nextTime = new Date();
$U.extend(this, args);
if (typeof this.initialize == 'function') this.initialize();
@@ -128,6 +216,50 @@ function bootstrap() {
check: function() { throw 'needs override.' }
};//}}}
+ var SubjectHttp = Subject;//{{{
+ $U.extend(SubjectHttp.prototype, {
+ initialize: function() {
+ this.initialized = false;
+ this.count = 0;
+ this.cache;
+
+ var req = new libly.Request(
+ this.options.url,
+ this.options.headers,
+ this.options.extra
+ );
+ req.addEventListener('onSuccess', $U.bind(this, function(res) {
+ if (typeof this.parse == 'function') this.cache = this.parse(res);
+ if (this.cache)
+ this.initialized = true;
+ }));
+ req.get();
+ },
+ check: function() {
+ if (!this.initialized) return;
+
+ this.count++;
+ var req = new libly.Request(
+ this.options.url,
+ this.options.headers,
+ this.options.extra
+ );
+ req.addEventListener('onSuccess', $U.bind(this, function(res) {
+ var parsed, diff;
+ if (typeof this.parse == 'function') parsed = this.parse(res);
+ if (parsed && typeof this.diff == 'function') diff = this.diff(this.cache, parsed);
+ if (diff && (typeof diff.length != 'undefined' && diff.length > 0)) {
+ if (typeof this.buildMessages == 'function') {
+ let messages = this.buildMessages([].concat(diff));
+ [].concat(messages).forEach($U.bind(this, function(m) this.notify(m)));
+ }
+ this.cache = parsed;
+ }
+ }));
+ req.get();
+ }
+ });//}}}
+
var Notifier = function() {//{{{
this.initialize.apply(this, arguments);
};
@@ -143,7 +275,7 @@ function bootstrap() {
setup: function() {//{{{
if (this.isBusy) {
- logger.log('bussy.' + this.id);
+ logger.log('busy.' + this.id);
return;
}
@@ -161,6 +293,9 @@ function bootstrap() {
);
liberator.plugins.notifier.libly = libly;
+ liberator.plugins.notifier.Observer = Observer;
+ liberator.plugins.notifier.Subject = Subject;
+ liberator.plugins.notifier.SubjectHttp = SubjectHttp;
liberator.plugins.notifier.Message = Message;
this.observers = new Loader('observer', function(args) new Observer(args));
@@ -204,7 +339,7 @@ function bootstrap() {
s.isActive = false;
s.__nextTime = new Date(s.__nextTime.getTime() + s.interval * 1000);
if (s.__nextTime < now) s.__nextTime = now;
- }, 10);
+ }, 1000);
}
});
liberator.sleep(3 * 1000);
diff --git a/notifier/observer_growl.js b/notifier/observer_growl.js
index e8d61e5..0a3d1d3 100644
--- a/notifier/observer_growl.js
+++ b/notifier/observer_growl.js
@@ -1,17 +1,17 @@
-/**
- * notifier.js plugin observer
- * @name observer_growl.js
- * @description growl when notified.
- * @description-ja Growl風通知。
- * @author suVene suvene@zeromemory.info
- * @version 0.1.0
- * Last Change: 07-Dec-2008.
- *
- * use jQuery
- * http://jquery.com/
- * use JGrowl
- * http://stanlemon.net/projects/jgrowl.html
- */
+// PLUGIN_INFO//{{{
+var PLUGIN_INFO =
+<VimperatorPlugin>
+ <name>{name}</name>
+ <description>notification from the subjects is notified to you by the Growl style.</description>
+ <description lang="ja">Growl風通知。</description>
+ <author mail="suvene@zeromemory.info" homepage="http://zeromemory.sblo.jp/">suVene</author>
+ <version>0.1.0</version>
+ <minVersion>2.0pre</minVersion>
+ <maxVersion>2.0pre</maxVersion>
+ <detail><![CDATA[
+ ]]></detail>
+</VimperatorPlugin>;
+//}}}
(function() {
var notifier = liberator.plugins.notifier;
@@ -28,22 +28,23 @@ Growl.prototype = {
defaults: {
life: 5000
},
- initialize: function(dom, container) {
+ initialize: function(dom, container, options) {
this.dom = dom;
this.container = container;
this.created = new Date();
- this.life = this.defaults.life;
+ this.options = $U.extend(this.defaults, (options || {}));
+ this.life = this.options.life;
dom.childNodes[0].addEventListener("click", $U.bind(this, this.remove), false);
},
remove: function() {
+ // TODO: animation!!!!
this.container.removeChild(this.dom);
},
}//}}}
-notifier.observer.register({
+notifier.observer.register(notifier.Observer, {
initialize: function () {
- logger.log('initialize');
this.count = 1;
io.getRuntimeDirectories('').forEach(function(dir) {
@@ -59,7 +60,6 @@ notifier.observer.register({
});
},
update: function(message) {
- logger.log('update:' + this.count);
var doc = window.content.document;
var container = doc.getElementById("observer_growl");
@@ -68,8 +68,9 @@ notifier.observer.register({
container = doc.getElementById("observer_growl");
}
- this.createPopup(doc, message, container);
- container.appendChild(this.createPopup(doc, message, container));
+ var notification = this.createPopup(message, doc, container);
+ // TODO: animation!!!
+ container.appendChild(notification);
if (container.childNodes.length == 1) {
let interval = setInterval($U.bind(this, this.checkStatus), 1000);
@@ -78,17 +79,16 @@ notifier.observer.register({
this.count++;
},
- createPopup: function(doc, message, nodes) {
+ createPopup: function(message, doc, nodes) {
var dom;
var html =
- <div class="observer_growl_notification" style="display: block;">
- <div class="close">&#215;</div>
- <div class="header">{util.escapeHTML(this.count + ': ' + message.title)}</div>
- <div class="message">{util.escapeHTML(message.message)}</div>
- </div>;
+ <div class="observer_growl_notification" style="display: block;">
+ <div class="close">&#215;</div>
+ <div class="header">{new XMLList(this.count + ': ' + message.title)}</div>
+ <div class="message">{new XMLList(message.message || '')}</div>
+ </div>;
dom = util.xmlToDom(html, doc, nodes);
- dom.__data__ = new Growl(dom, nodes);
-
+ dom.__data__ = new Growl(dom, nodes, message.options.growl);
return dom;
},
checkStatus: function() {
@@ -106,7 +106,7 @@ notifier.observer.register({
removeNodes.push(item);
}
}
- removeNodes.forEach(function(n) container.removeChild(n));
+ removeNodes.forEach(function(element) element.__data__.remove());
if (container.childNodes.length == 0)
clearInterval(container.__interval__);
diff --git a/notifier/subject_hatelabo_bottle.js b/notifier/subject_hatelabo_bottle.js
index 9c4914d..6c4a330 100644
--- a/notifier/subject_hatelabo_bottle.js
+++ b/notifier/subject_hatelabo_bottle.js
@@ -1,12 +1,17 @@
-/**
- * notifier.js plugin subject
- * @name subject_hatena_bottle.js
- * @description notify if hatena bottle changed.
- * @description-ja はてなボトルの変更通知。
- * @author suVene suvene@zeromemory.info
- * @version 0.1.0
- * Last Change: 08-Dec-2008.
- */
+// PLUGIN_INFO//{{{
+var PLUGIN_INFO =
+<VimperatorPlugin>
+ <name>{name}</name>
+ <description>notifies if hatena bottle was changed.</description>
+ <description lang="ja">はてなボトルの変更通知。</description>
+ <author mail="suvene@zeromemory.info" homepage="http://zeromemory.sblo.jp/">suVene</author>
+ <version>0.1.0</version>
+ <minVersion>2.0pre</minVersion>
+ <maxVersion>2.0pre</maxVersion>
+ <detail><![CDATA[
+ ]]></detail>
+</VimperatorPlugin>;
+//}}}
(function() {
var notifier = liberator.plugins.notifier;
@@ -17,22 +22,14 @@ var $U = libly.$U;
var logger = $U.getLogger('subject_hatelabo_bottle');
var URL = 'http://bottle.hatelabo.jp';
+//var URL = 'http://localhost/index.html?a';
-notifier.subject.register({
- interval: 30,
- initialize: function() {
- this.count = 0;
- this.initialized = false;
- this.cache;
-
- var req = new libly.Request(URL);
- req.addEventListener('onSuccess', $U.bind(this, function(res) {
- logger.log('initialized');
- this.cache = this.parse(res);
- if (this.cache)
- this.initialized = true;
- }));
- req.get();
+notifier.subject.register(notifier.SubjectHttp, {
+ interval: 40,
+ options: {
+ url: URL,
+ headers: null,
+ extra: null
},
parse: function(res) {
@@ -44,31 +41,37 @@ notifier.subject.register({
if (!dom) return ret;
ret = [];
- for (let i = 0, len < dom.childNodes.length; i < len; i++) {
+ for (let i = 0, len = dom.childNodes.length; i < len; i++) {
ret.push(dom.childNodes[i]);
}
return ret;
},
- check: function() {
-
- if (!this.initialized) return;
-
- this.count++;
- logger.log('check');
- var req = new libly.Request(URL);
- req.addEventListener('onSuccess', $U.bind(this, function(res) {
- var text = res.responseText;
- logger.log('success!! ');
- var message = new notifier.Message('TEST', text);
- this.notify(message);
+ diff: function(cache, parsed) {
+ var ret = [];
+ parsed.forEach(function(element) {
+ if (!cache.some(function(c) { if (c.toString() == element.toString()) return true }))
+ ret.push(element);
+ });
- if (this.count == 5) {
- notifier.subject.unregister(this);
- this.count = 0;
- }
- }));
- req.get();
+ return ret;
+ var text = (new XMLSerializer()).serializeToString(parsed[0])
+ .replace(/<[^>]+>/g, function(all) all.toLowerCase())
+ .replace(/<!--(?:[^-]|-(?!->))*-->/g, ''); // actually
+ return text;
+ },
+ buildMessages: function(diff) {
+ var ret = [];
+ diff.forEach(function(d) {
+ ret.push(
+ new notifier.Message('Hatelab bottle', $U.xmlSerialize(d), {
+ growl: {
+ life: 7000
+ }
+ })
+ );
+ });
+ return ret;
}
});