]> gitweb @ CieloNegro.org - sugar.git/blob - dot-files/_vimperator/plugin/copy_js
Auto commit by The Sugar System.
[sugar.git] / dot-files / _vimperator / plugin / copy_js
1 var INFO =
2 <plugin name="copy" version="0.7.6"
3         href="http://svn.coderepos.org/share/lang/javascript/vimperator-plugins/trunk/copy.js"
4         summary="copy strings from the template (like CopyURL+)"
5         xmlns="http://vimperator.org/namespaces/liberator">
6     <author email="teramako@gmail.com">teramako</author>
7     <license>MPL 1.1/GPL 2.0/LGPL 2.1</license>
8     <project name="Vimperator" minVersion="2.3"/>
9     <item>
10     <tags>:copy</tags>
11     <spec>:copy <a>label</a></spec>
12     <description>
13         <p>copy the argument replaced some certain string.</p>
14     </description>
15     </item>
16     <item>
17     <tags>:copy!</tags>
18     <spec>:copy! <a>expr</a></spec>
19     <description>
20         <p>evaluate the argument(javascript code) and copy the result.</p>
21     </description>
22     </item>
23     <item>
24     <tags>copy-keyword</tags>
25     <spec>copy-keyword</spec>
26     <description>
27         <p>replaces following keywords</p>
28         <dl>
29             <dt>%TITLE%</dt>
30             <dd>to the title of the current page</dd>
31             <dt>%URL%</dt>
32             <dd>to the currenet URL</dd>
33             <dt>%SEL</dt>
34             <dd>to the string of selection</dd>
35             <dt>%HTMLSEL</dt>
36             <dd>to the html string of selection</dd>
37             <dt>%HOSTNAME%</dt>
38             <dd>to the hostname of the current location</dd>
39             <dt>%PATHNAME%</dt>
40             <dd>to the pathname of the current location</dd>
41             <dt>%HOST%</dt>
42             <dd>to the host of the current location</dd>
43             <dt>%PORT%</dt>
44             <dd>to the port of the current location</dd>
45             <dt>%PROTOCOL%</dt>
46             <dd>to the protocol of the current location</dd>
47             <dt>%SERCH%</dt>
48             <dd>to the search(?...) of the curernt location</dd>
49             <dt>%HASH%</dt>
50             <dd>to the hash(anchor #..) of the current location</dd>
51         </dl>
52     </description>
53     </item>
54     <item>
55         <tags>copy-template</tags>
56         <spec>copy-template</spec>
57         <description>
58             <p>you can set your own template using inline JavaScript</p>
59             <code><![CDATA[
60 javascript <<EOM
61 liberator.globalVariables.copy_templates = [
62   { label: 'titleAndURL',    value: '%TITLE%\n%URL%' },
63   { label: 'title',          value: '%TITLE%', map: ',y' },
64   { label: 'anchor',         value: '<a href="%URL%">%TITLE%</a>' },
65   { label: 'selanchor',      value: '<a href="%URL%" title="%TITLE%">%SEL%</a>' },
66   { label: 'htmlblockquote', value: '<blockquote cite="%URL%" title="%TITLE%">%HTMLSEL%</blockquote>' }
67   { label: 'ASIN',   value: 'copy ASIN code from Amazon', custom: function(){return content.document.getElementById('ASIN').value;} },
68 ];
69 EOM
70             ]]></code>
71             <dl>
72                 <dt>label</dt>
73                 <dd>template name which is command argument</dd>
74                 <dt>value</dt>
75                 <dd>copy string. <a>copy-keyword</a> is replaced</dd>
76                 <dt>map</dt>
77                 <dd>key map <a>lhs</a> (optional)</dd>
78                 <dt>custom</dt>
79                 <dd>
80                     <a>function</a> or <a>Array</a> (optional)
81                     <dl>
82                         <dt><a>function</a></dt>
83                         <dd>execute the function and copy return value, if specified</dd>
84                         <dt><a>Array</a></dt>
85                         <dd>
86                             replace to the <a>value</a> by normal way at first.
87                             then replace words matched <a>Array</a>[0] in the repalced string to <a>Array</a>[1].
88                             <dl>
89                             <dt><a>Array</a>[0]</dt>
90                             <dd>String or RegExp</dd>
91                             <dt><a>Array</a>[1]</dt>
92                             <dd>String or Function</dd>
93                             </dl>
94                             see: <link topic="http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:String:replace">http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:String:replace</link>
95                         </dd>
96                     </dl>
97                 </dd>
98             </dl>
99         </description>
100     </item>
101     <item>
102         <tags>copy-option</tags>
103         <spec>copy-option</spec>
104         <description>
105             <code><ex>liberator.globalVariables.copy_use_wedata = false; // false by default</ex></code>
106             <p>true に設定すると wedata からテンプレートを読込みます。</p>
107             <code><ex>liberator.globalVariables.copy_wedata_include_custom = true; // false by default</ex></code>
108             <p>custom が設定された wedata を読込みます。
109             SandBox でなく、window.eval を利用してオブジェクトする為、
110             セキュリティ上の理由で初期設定は false になっています。
111             true に設定する場合は、動作を理解したうえ自己責任でご利用ください。</p>
112             <code><ex>liberator.globalVariables.copy_wedata_exclude_labels = ['pathtraqnormalize', ];</ex></code>
113             <p>wedata から読込まない label のリストを定義します。</p>
114         </description>
115     </item>
116 </plugin>;
117 var PLUGIN_INFO =
118 <VimperatorPlugin>
119 <name>{NAME}</name>
120 <description>enable to copy strings from a template (like CopyURL+)</description>
121 <description lang="ja">テンプレートから文字列のコピーを可能にします(CopyURL+みたいなもの)</description>
122 <minVersion>2.0pre</minVersion>
123 <maxVersion>2.0pre</maxVersion>
124 <updateURL>http://svn.coderepos.org/share/lang/javascript/vimperator-plugins/trunk/copy.js</updateURL>
125 <author mail="teramako@gmail.com" homepage="http://vimperator.g.hatena.ne.jp/teramako/">teramako</author>
126 <license>MPL 1.1/GPL 2.0/LGPL 2.1</license>
127 <version>0.7.5</version>
128 </VimperatorPlugin>;
129
130 liberator.plugins.exCopy = (function(){
131 var excludeLabelsMap = {};
132 var copy_templates = [];
133 if (!liberator.globalVariables.copy_templates){
134     liberator.globalVariables.copy_templates = [
135         { label: 'titleAndURL',    value: '%TITLE%\n%URL%' },
136         { label: 'title',          value: '%TITLE%' },
137         { label: 'anchor',         value: '<a href="%URL%">%TITLE%</a>' },
138         { label: 'selanchor',      value: '<a href="%URL%" title="%TITLE%">%SEL%</a>' },
139         { label: 'htmlblockquote', value: '<blockquote cite="%URL%" title="%TITLE%">%HTMLSEL%</blockquote>' }
140     ];
141 }
142
143 copy_templates = liberator.globalVariables.copy_templates.map(function(t){
144     return { label: t.label, value: t.value, custom: t.custom, map: t.map }
145 });
146
147 copy_templates.forEach(function(template){
148     if (typeof template.map == 'string')
149         addUserMap(template.label, [template.map]);
150     else if (template.map instanceof Array)
151         addUserMap(template.label, template.map);
152 });
153
154 const REPLACE_TABLE = {
155     get TITLE () buffer.title,
156     get URL () buffer.URL,
157     get SEL () {
158         var sel = '';
159         var win = new XPCNativeWrapper(window.content.window);
160         var selection =  win.getSelection();
161         if (selection.rangeCount < 1)
162             return '';
163
164         for (var i=0, c=selection.rangeCount; i<c; i++){
165             sel += selection.getRangeAt(i).toString();
166         }
167         return sel;
168     },
169     get HTMLSEL () {
170         var htmlsel = '';
171         var win = new XPCNativeWrapper(window.content.window);
172         var selection =  win.getSelection();
173         if (selection.rangeCount < 1)
174             return '';
175
176         var serializer = new XMLSerializer();
177         for (var i=0, c=selection.rangeCount; i<c; i++){
178             htmlsel += serializer.serializeToString(selection.getRangeAt(i).cloneContents());
179         }
180         return htmlsel.replace(/<(\/)?(\w+)([\s\S]*?)>/g, function(all, close, tag, attr){
181             return "<" + close + tag.toLowerCase() + attr + ">";
182         });
183     },
184     get CLIP () {
185         return util.readFromClipboard();
186     }
187 };
188 'hostname pathname host port protocol search hash'.split(' ').forEach(function (name){
189     REPLACE_TABLE[name.toUpperCase()] = function () content.location && content.location[name];
190 });
191
192 // used when argument is none
193 //const defaultValue = templates[0].label;
194 commands.addUserCommand(['copy'],'Copy to clipboard',
195     function(args){
196         liberator.plugins.exCopy.copy(args.literalArg, args.bang, !!args["-append"]);
197     },{
198         completer: function(context, args){
199             if (args.bang){
200                 completion.javascript(context);
201                 return;
202             }
203             context.title = ['Template','Value'];
204             var templates = copy_templates.map(function(template)
205                 [template.label, liberator.modules.util.escapeString(template.value, '"')]
206             );
207             if (!context.filter){ context.completions = templates; return; }
208             var candidates = [];
209             var filter = context.filter.toLowerCase();
210             context.completions = templates.filter(function(template) template[0].toLowerCase().indexOf(filter) == 0);
211         },
212         literal: 0,
213         bang: true,
214         options: [
215             [["-append","-a"], commands.OPTION_NOARG]
216         ]
217     },
218     true
219 );
220
221 function addUserMap(label, map){
222     mappings.addUserMap([modes.NORMAL,modes.VISUAL], map,
223         label,
224         function(){ liberator.plugins.exCopy.copy(label); },
225         { rhs: label }
226     );
227 }
228 function getCopyTemplate(label){
229     var ret = null;
230     copy_templates.some(function(template)
231         template.label == label ? (ret = template) && true : false);
232     return ret;
233 }
234 function replaceVariable(str){
235     if (!str) return '';
236     function replacer(orig, name){ //{{{
237         if (name == '')
238             return '%';
239         if (!REPLACE_TABLE.hasOwnProperty(name))
240             return orig;
241         let value = REPLACE_TABLE[name];
242         if (typeof value == 'function')
243             return value();
244         else
245             return value.toString();
246         return orig;
247     } //}}}
248     return str.replace(/%([A-Z]*)%/g, replacer);
249 }
250
251 function wedataRegister(item){
252     var libly = liberator.plugins.libly;
253     var logger = libly.$U.getLogger("copy");
254     item = item.data;
255     if (excludeLabelsMap[item.label]) return;
256
257     if (item.custom && item.custom.toLowerCase().indexOf('function') != -1) {
258         if (!liberator.globalVariables.copy_wedata_include_custom ||
259              item.label == 'test') {
260             logger.log('skip: ' + item.label);
261             return;
262         }
263
264         let custom = (function(item){
265
266             return function(value, value2){
267                 var STORE_KEY = 'plugins-copy-ok-func';
268                 var store = storage.newMap(STORE_KEY, true);
269                 var check = store.get(item.label);
270                 var ans;
271
272                 if (!check){
273                     ans = window.confirm(
274                         'warning!!!: execute "' + item.label + '" ok ?\n' +
275                         '(this function is working with unsafe sandbox.)\n\n' +
276                         '----- execute code -----\n\n' +
277                         'value: ' + item.value + '\n' +
278                         'function: ' +
279                         item.custom
280                     );
281                 } else {
282                     if (item.value == check.value &&
283                         item.custom == check.custom &&
284                         item.map == check.map){
285                         ans = true;
286                     } else {
287                         ans = window.confirm(
288                             'warning!!!: "' + item.label + '" was changed when you registered the function.\n' +
289                             '(this function is working with unsafe sandbox.)\n\n' +
290                             '----- execute code -----\n\n' +
291                             'value: ' + item.value + '\n' +
292                             'function: ' +
293                             item.custom
294                         );
295                     }
296                 }
297
298                 if (!ans) return;
299                 store.set(item.label, item);
300                 store.save();
301
302                 var func;
303                 try{
304                     func = window.eval('(' + item.custom + ')');
305                 } catch (e){
306                     logger.echoerr(e);
307                     logger.log(item.custom);
308                     return;
309                 }
310                 return func(value, value2);
311             };
312         })(item);
313
314         exCopyManager.add(item.label, item.value, custom, item.map);
315     } else {
316         exCopyManager.add(item.label, item.value, null, item.map);
317     }
318 }
319 var exCopyManager = {
320     add: function(label, value, custom, map){
321         var template = {label: label, value: value, custom: custom, map: map};
322         copy_templates.unshift(template);
323         if (map) addUserMap(label, map);
324
325         return template;
326     },
327     get: function(label){
328         return getCopyTemplate(label);
329     },
330     copy: function(arg, special, appendMode){
331         var copyString = '';
332         var isError = false;
333         if (special && arg){
334             try {
335                 copyString = liberator.eval(arg);
336                 switch (typeof copyString){
337                     case 'object':
338                         copyString = copyString === null ? 'null' : copyString.toSource();
339                         break;
340                     case 'function':
341                         copyString = copyString.toString();
342                         break;
343                     case 'number':
344                     case 'boolean':
345                         copyString = '' + copyString;
346                         break;
347                     case 'undefined':
348                         copyString = 'undefined';
349                         break;
350                 }
351             } catch (e){
352                 isError = true;
353                 copyString = e.toString();
354             }
355         } else {
356             if (!arg) arg = copy_templates[0].label;
357
358             var template = getCopyTemplate(arg) || {value: arg};
359             if (typeof template.custom == 'function'){
360                 copyString = template.custom.call(this, template.value, replaceVariable(template.value));
361             } else if (template.custom instanceof Array){
362                 copyString = replaceVariable(template.value).replace(template.custom[0], template.custom[1]);
363             } else {
364                 copyString = replaceVariable(template.value);
365             }
366         }
367
368         if (appendMode){
369             copyString = util.readFromClipboard() + copyString;
370         }
371
372         if (copyString)
373             util.copyToClipboard(copyString);
374         if (isError){
375             liberator.echoerr('CopiedErrorString: `' + copyString + "'");
376         } else {
377             liberator.echo('CopiedString: `' + util.escapeHTML(copyString || '') + "'");
378         }
379     }
380 };
381
382 if (liberator.globalVariables.copy_use_wedata){
383     function loadWedata(){
384         if (!liberator.plugins.libly){
385             liberator.echomsg("need a _libly.js when use wedata.");
386             return;
387         }
388
389         var libly = liberator.plugins.libly;
390         copy_templates.forEach(function(item) excludeLabelsMap[item.label] = item.value);
391         if (liberator.globalVariables.copy_wedata_exclude_labels)
392             liberator.globalVariables.copy_wedata_exclude_labels.forEach(function(item) excludeLabelsMap[item] = 1);
393         var wedata = new libly.Wedata("vimp%20copy");
394         wedata.getItems(24 * 60 * 60 * 1000, wedataRegister);
395     }
396     loadWedata();
397 }
398
399 return exCopyManager;
400 })();
401
402 // vim: set fdm=marker sw=4 ts=4 et:
403