From a611f1c6ff91dc1fbea8adc5fbfe6c2dcf16ab78 Mon Sep 17 00:00:00 2001 From: anekos Date: Tue, 29 Dec 2009 05:29:43 +0000 Subject: $U.around に二重包み込み防止機能をつけた git-svn-id: http://svn.coderepos.org/share/lang/javascript/vimperator-plugins/trunk@36303 d0d07461-0603-4401-acd4-de1884942a52 --- _libly.js | 62 +++++++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 49 insertions(+), 13 deletions(-) (limited to '_libly.js') diff --git a/_libly.js b/_libly.js index c7f6e7c..11d3fa8 100755 --- a/_libly.js +++ b/_libly.js @@ -12,7 +12,7 @@ var PLUGIN_INFO = 適当なライブラリっぽいものたち。 suVene MIT - 0.1.29 + 0.1.30 2.3pre 2.3pre http://svn.coderepos.org/share/lang/javascript/vimperator-plugins/trunk/_libly.js @@ -34,7 +34,7 @@ extend(dst, src): オブジェクトを拡張します。 A(iterable): オブジェクトを配列にします。 -around(obj, name, func): +around(obj, name, func, autoRestore): obj がもつ name 関数を、func に置き換えます。 func は function (next, args) {...} @@ -43,6 +43,8 @@ around(obj, name, func): args はオリジナルの引数列です。 通常、next には引数を渡す必要はありません。 (任意の引数を渡したい場合は配列で渡します。) + また、autoRestore が真であれば、プラグインの再ロードなどで around が再実行されたときに、関数の置き換え前にオリジナル状態に書き戻します。 + (多重に置き換えられなくなるので、auto_source.js などを使ったプラグイン開発で便利です) 返値は以下のオブジェクトです >|| { @@ -232,18 +234,52 @@ libly.$U = {//{{{ } return ret; }, - around: function around (obj, name, func) { - let next = obj[name]; - let current = obj[name] = function () { - let self = this, args = arguments; - return func.call(self, function (_args) next.apply(self, _args || args), args); + around: (function () { + function getPluginPath () { + let pluginPath; + Error('hoge').stack.split(/\n/).some( + function (s) + let (m = s.match(/^\(\)@chrome:\/\/liberator\/content\/liberator\.js -> (.+):\d+$/)) + (m && (pluginPath = m[1])) + ); + return pluginPath; + } + + let restores = {}; + + return function (obj, name, func, autoRestore) { + let original; + let restore = function () obj[name] = original; + if (autoRestore) { + let pluginPath = getPluginPath(); + if (!pluginPath) + throw 'getPluginPath failed'; + restores[pluginPath] = + (restores[pluginPath] || []).filter( + function (res) ( + res.object != obj || + res.name != name || + (res.restore() && false) + ) + ); + restores[pluginPath].push({ + object: obj, + name: name, + restore: restore + }); + } + original = obj[name]; + let current = obj[name] = function () { + let self = this, args = arguments; + return func.call(self, function (_args) original.apply(self, _args || args), args); + }; + return libly.$U.extend({ + original: original, + current: current, + restore: restore + }, [original, current]); }; - return libly.$U.extend({ - original: next, - current: current, - restore: function () (obj[name] = next) - }, [next, current]); - }, + })(), bind: function(obj, func) { return function() { return func.apply(obj, arguments); -- cgit v1.2.3