root/lang/javascript/abookmarkletsfarm/trunk/bookmarklets.html @ 8309

Revision 8309, 19.1 kB (checked in by drry, 7 years ago)

lang/javascript/abookmarkletsfarm/trunk/bookmarklets.html:

  • 正規表現を修正・削減しました。
  • Property svn:mime-type set to text/html; charset=utf-8
Line 
1<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html401/strict.dtd">
2<html lang="ja">
3<!--
4"a bookmarklets farm"
5Copyright (C) 2008 Archinet inc. / Haruka Kataoka
6
7This program is free software; you can redistribute it and/or
8modify it under the terms of the GNU General Public License
9as published by the Free Software Foundation; either version 2
10of the License, or (at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with this program; if not, write to the Free Software
19Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20-->
21<!-- $Id: bookmarklets.html,v 1.2 2008/03/06 10:43:29 Kataoka Exp Kataoka $ -->
22<head>
23        <title>a bookmarklets farm</title>
24        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
25        <meta http-equiv="Content-Script-Type" content="text/javascript">
26        <LINK REL="stylesheet" TYPE="text/css" HREF="theme.css">
27</head>
28<body onload="loadbookmarklets();">
29<h1>a bookmarklets farm</h1>
30
31<ul>
32<li>ブックマークレットの作成方法は、このページのソースの "ブックマークレットの雛形" に記載のコメントをご覧下さい。
33<li>可読風ブックマークレット: 読みやすさ優先のブックマークレットです。
34<li>可逆なブックマークレット: このページ最下部の "可逆なブックマークレットをソースに戻す" で改行やタブを含めて元に戻すことができます。(おそらく Firefox でのみ有効)
35<li>短いブックマークレット: できるだけ短くしたブックマークレットです。
36<li>実際に公開する場合は "短いブックマークレットのaタグソース" か "パブリッシュ用ソース" を使用して下さい。(各リンクから右クリックでコピーしたブックマークレットは、違うブラウザに貼り付けると文字化けします)
37<li>GNU GPL 2 の定める条件の下で再頒布する事ができます。
38        <br>ご連絡は <a href="http://www.archinet.co.jp/~kataoka/">Archinet inc. / Haruka Kataoka</a> に記載のアドレスまでどうぞ。 / <a href="http://d.hatena.ne.jp/callee/20080214/p1">解説しているブログ記事</a>
39</ul>
40
41<div>
42        リンク集
43         / <a href="http://www.teria.com/~koseki/memo/bookmarklets/tips.html">Bookmarklet - ブックマークレットを作成する際のポイント</a>
44         / <a href="http://www.tohoho-web.com/js/index.htm">とほほのJavaScriptリファレンス</a>
45         / <a href="http://krook.org/jsdom/">JavaScript DOM API</a>
46</div>
47
48<form action="#"><div>
49<input type="button" onclick="location.reload(true);" onkeypress="location.reload(true);" value="Reload Bookmarklets" style="width:100%;">
50</div></form>
51
52
53
54<!--
55ブックマークレットの雛形
56        ・class="bookmarklet" を指定した div タグが一つのブックマークになります。
57        ・名前 : ブックマークレットの名前を h2 タグで記述して下さい。
58        ・説明 : ブックマークレットの説明を p タグ記述して下さい。
59        ・本体 : script タグ中に無名関数としてソースを作成して下さい。
60        ・各ブックマークレット毎に h2, p, script は最初の1つだけ有効です。
61-->
62<div class="bookmarklet">
63<h2>ブックマークレットの雛形</h2>
64<p>作成に関するヘルプはこのファイルのソースをご覧下さい</p>
65<script type="text/javascript"><!--
66function(){
67        alert("\"ブックマークレットの雛形\"を起動しました");
68        return void(0);
69}
70// --></script>
71</div>
72
73
74
75
76
77<div class="bookmarklet">
78<h2>h*2menu</h2>
79<p>見出しタグからメニューを作る。長いドキュメントで概要もつかめて便利。</p>
80<script type="text/javascript"><!--
81function(){
82        var id = 'h2menu';
83        var hd = document.getElementsByTagName("*");
84        var cl = 0;
85        var bd = document.getElementsByTagName("body")[0];
86        var cs = document.createElement('div');
87        bd.appendChild(cs);
88        cs.setAttribute('style', 'border:1px blue solid;position:fixed;top:0px;right:0px;width:24%;height:500px;overflow:auto;font-size:small;padding:0px');
89        bd.setAttribute('style', 'width:74%;left:0px;');
90        for(var i=0,el; (el=hd[i++]); ){
91                if (!/^h(\d)$/.test(el.tagName.toLowerCase())){
92                        continue;
93                }
94                var nl = RegExp.$1;
95                al(el.innerHTML.replace(/<[^>]*>/g,''), nl, i);
96                var na = document.createElement('a');
97                na.name = id+i;
98                el.appendChild(na)
99        }
100        function al(tx, lv, nm){
101                while(cl < lv){
102                        var nn = document.createElement('ul');
103                        nn.setAttribute('style', 'margin:0px;padding:0px 0px 0px 10px;');
104                        cs.appendChild(nn);
105                        cs = nn;
106                        cl++;
107                }
108                while(cl > lv){
109                        cs = cs.parentNode;
110                        cl--;
111                }
112                var nn = document.createElement('li');
113                nn.setAttribute('style', 'margin:0px;padding:0px;');
114                var na = document.createElement('a');
115                na.href = '#'+id+nm;
116                na.innerHTML = tx;
117                nn.appendChild(na);
118                cs.appendChild(nn);
119        }
120}
121// --></script>
122</div>
123
124
125
126<div class="bookmarklet">
127<h2>畳むtable行</h2>
128<p>テーブルの行に行を非表示にする X ボタンをつける。ショッピングサイトとかで、「これは無いな」という行をプチプチ潰しながら閲覧できる。</p>
129<script type="text/javascript"><!--
130function(){
131        var i,ts=document.getElementsByTagName("tr");
132        for(i=0;i<ts.length;i++){
133                var nt=document.createElement("td");
134                nt.innerHTML="<a onclick=\"this.parentNode.parentNode.style.display=&quot;none&quot;;return false;\">X</a>";
135                ts[i].insertBefore(nt,ts[i].firstChild);
136        }
137        return void(0);
138}
139// --></script>
140</div>
141
142
143
144<div class="bookmarklet">
145<h2>隠すDIV</h2>
146<p>DIVブロックを非表示にする [X] ボタンをつける。</p>
147<script type="text/javascript"><!--
148function(){
149        var i,d=document.getElementsByTagName("div");
150        for(i=0;i<d.length;i++){
151                var sp=document.createElement("span");
152                sp.innerHTML="<a onclick=\"this.parentNode.parentNode.style.display=&quot;none&quot;;return false;\">[X]</a>";
153                d[i].insertBefore(sp,d[i].firstChild);
154                if (!d[i].style.borderWidth) d[i].style.borderWidth = 1;
155                if (!d[i].style.borderStyle || d[i].style.borderStyle == "none") d[i].style.borderStyle = "solid";
156                if (!d[i].style.borderColor) d[i].style.borderStyle = "gray";
157        }
158        return void(0);
159}
160// --></script>
161</div>
162
163
164
165
166<div class="bookmarklet">
167<h2>表→タブ区切</h2>
168<p>表をExcel等向けタブ区切りに変換 IE不可</p>
169<script type="text/javascript"><!--
170function(){
171        function ftr(tr){
172                var r="",i,td=tr.childNodes;
173                for(i=0;i<td.length;i++)
174                        if(/^(?:th|td)$/.test(td[i].tagName && td[i].tagName.toLowerCase()))
175                                r+="\""+td[i].innerHTML.replace(/\s+/g," ").replace(/<br\s*[^>]*>/ig,"\n").replace(/<[^>]*>/g,"").replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/&quot;/g,"\"").replace(/&amp;/g,"&").replace(/\"/g,"\"\"")+"\"\t";
176                return r.substr(0,r.length-1);
177        }
178        function ftb(tb){
179                var r="",i,tr=tb.childNodes;
180                for(i=0;i<tr.length;i++){
181                        if(tr[i].tagName){
182                                if(/^t(?:head|body|foot)$/.test(tr[i].tagName.toLowerCase())){
183                                        r+=ftb(tr[i]);
184                                }else if(tr[i].tagName.toLowerCase() == "tr"){
185                                        r+=ftr(tr[i])+"\n";
186                                }
187                        }
188                }
189                return r;
190        }
191        function fd(d){
192                var i,tb=d.getElementsByTagName("table");
193                for(i=0;i<tb.length;i++){
194                        var nt=document.createElement("textarea");
195                        nt.innerHTML=ftb(tb[i]);
196                        tb[i].parentNode.insertBefore(nt,tb[i]);
197                }
198        }
199        function fw(w){
200                if(w.length)
201                for(var i=0;i<w.length;i++)
202                        fw(w[i]);
203                else
204                        fd(w.document)
205        }
206        fw(window);
207        return  void(0);
208}
209// --></script>
210</div>
211
212
213
214<div class="bookmarklet">
215<h2>全角→半角</h2>
216<p>全角を半角に変換 新聞系のサイトとかでどうぞ</p>
217<script type="text/javascript"><!--
218function(){
219        function fd(d){
220                var b=d.getElementsByTagName("body")[0];
221                b.innerHTML=b.innerHTML.replace(/[!-~]/g, function(a){return String.fromCharCode(a.charCodeAt(0)-0xFEE0)});
222        }
223        function fw(w){
224                if(w.length) for(var i=0;i<w.length;i++)
225                        fw(w[i]);
226                else
227                        fd(w.document)
228        }
229        fw(window);
230        return  void(0);
231}
232// --></script>
233</div>
234
235
236
237
238<div class="bookmarklet">
239<h2>フォーム状態保存</h2>
240<p>フォームに入力途中の情報を文字列に保存します</p>
241<script type="text/javascript"><!--
242function(){
243        var q="", f=document.forms;
244        for(var i=0;i<f.length;i++){
245                q += "with(document.forms[" + (f[i].name ? "\""+quote(f[i].name)+"\"" : i) + "]){";
246                var e=f[i].elements;
247                var n=elms2names(e);
248                for(var j in n){
249                        if(e[j].length>1 && String(e[j].type).indexOf("select") != 0){
250                                for(var k=0;k<e[j].length;k++) {
251                                        q += elm2code(e[j][k],"[" + k + "]");
252                                }
253                        }else{
254                                q += elm2code(e[j],"");
255                        }
256                }
257                q += "}";
258        }
259        prompt("この内容をコピーして保存して下さい。Locationバーに入力するとフォーム内容を復帰できます",
260                   "javascript:/*"+document.title+"("+(new Date())+")*/" + q + "void(0);");
261        function elms2names(es){
262                var n = new Object();
263                for(var j=0;j<es.length;j++){
264                        if(es[j].name)
265                                n[es[j].name] = 1;
266                }
267                return n;
268        }
269        function elm2code(e,sub){
270                if(e.name && !e.disabled){
271                        var pfx = "elements[\"" + quote(e.name) + "\"]" + sub;
272                        if(e.type=="text" || e.type=="textarea"){
273                                return pfx + ".value=\"" + quote(e.value) + "\";";
274                        }else if(e.type=="checkbox" || e.type=="radio"){
275                                return pfx + ".checked=" + e.checked + ";";
276                        }else if(String(e.type).indexOf("select") == 0){
277                                var q = "", o=e.options;
278                                for(var k=0;k<o.length;k++){
279                                        q += "options[" + k + "].selected=" + o[k].selected  + ";";
280                                }
281                                return "with(" + pfx + "){" + q + "}";
282                        }
283                }
284                return "";
285        }
286        function quote(str){
287                return str.replace(/\\/g,"\\\\").replace(/\"/g,"\\\"").replace(/\r/g,"\\r").replace(/\n/g,"\\n");
288        }
289}
290// --></script>
291</div>
292
293
294
295
296
297<form action="#"><div>
298        <h2>パブリッシュ用ソース</h2>
299        パブリッシュするaタグに追加する属性:
300        <input size=60 id="bookmarkletpublishattribute" value="onclick=&quot;alert(&amp;quot;右クリックで[お気に入り]に登録して使ってください。&amp;quot;);return(false);&quot;">
301        <input type="button"
302                onclick="publishbookmarklets();" onkeypress="publishbookmarklets();"
303                value="Publish Bookmarklets" style="width:100%;">
304        <textarea rows=5 cols=60 style="width:100%;" id="bookmarkletpublish"></textarea>
305</div></form>
306
307<form action="#"><div>
308        <h2>可逆なブックマークレットをソースに戻す</h2>
309        <pre id="bookmarklet2source"></pre>
310        <textarea rows=2 cols=60
311                onchange="reversebookmarklet(this);"
312                style="width:100%;"></textarea>
313</div></form>
314
315<script type="text/javascript"><!--
316
317//ページに含まれるブックマークレットを読み込む
318function loadbookmarklets() {
319        var srcs = document.getElementsByTagName("div");
320        for (var i=0; i<srcs.length; i++)
321                if (srcs[i].className == "bookmarklet")
322                        _loadone(srcs[i]);
323}
324
325//ページに含まれるブックマークレットをパブリッシュする
326function publishbookmarklets() {
327        var textarea = document.getElementById("bookmarkletpublish");
328
329        var pubsrc = "<ul>\n";
330        var srcs = document.getElementsByTagName("div");
331        for (var i=0; i<srcs.length; i++)
332                if (srcs[i].className == "bookmarklet")
333                        pubsrc += "\t<li>" + _publishone(srcs[i]) + "\n";
334        pubsrc += "</ul>\n";
335
336        textarea.value = pubsrc;
337        textarea.select();
338}
339
340//可逆なブックマークレットをソースに戻す
341function reversebookmarklet(target) {
342        if (window.event) target = window.event.srcElement;
343        document.getElementById("bookmarklet2source").innerHTML
344                = _htmlencode(_bookmarklet2code(target.value));
345}
346
347//----
348
349//ページに含まれるブックマークレットを読み込む(一つ)
350function _loadone(src){
351        var title = src.getElementsByTagName("h2")[0].innerHTML;
352        var code = src.getElementsByTagName("script")[0].innerHTML;
353        code = _removecomment(code);
354
355        var ulnode = document.createElement("ul");
356        var tempNode;
357
358        tempNode = document.createElement("li");
359        tempNode.innerHTML = "このページで : ";
360        tempNode.appendChild(_addEvent.apply(_anchornode("実行してエラーチェック", "#"), ["click", _getEvalFun(title, code)]));
361        ulnode.appendChild(tempNode);
362
363        tempNode = document.createElement("li");
364        tempNode.innerHTML = "可読風ブックマークレット : ";
365        tempNode.appendChild(_anchornode(title, _code2bookmarklet(code, "readable")));
366        ulnode.appendChild(tempNode);
367
368        tempNode = document.createElement("li");
369        tempNode.innerHTML = "可逆なブックマークレット : ";
370        tempNode.appendChild(_anchornode(title, _code2bookmarklet(code, "reversible")));
371        ulnode.appendChild(tempNode);
372
373        var portable = _code2bookmarklet(code, "portable");
374        tempNode = document.createElement("li");
375        tempNode.innerHTML = "短いブックマークレット : ";
376        tempNode.appendChild(_anchornode(title, portable));
377        ulnode.appendChild(tempNode);
378
379        var inputNode = document.createElement("input");
380        inputNode.setAttribute("type", "text");
381        inputNode.setAttribute("readonly", null);
382        inputNode.value = "<a href=\"" + _htmlencode(portable) + "\">" + title + "</a>";
383        _addEvent.apply(inputNode, ["focus", function(){this.select();}]);
384
385        tempNode = document.createElement("li");
386        tempNode.innerHTML = "短いブックマークレットのaタグソース(" +
387                portable.length + " byte " + (portable.length > 508 ? "IEには長すぎ" : "") + ")";
388        tempNode.appendChild(inputNode);
389        ulnode.appendChild(tempNode);
390
391        src.appendChild(ulnode);
392}
393//ページに含まれるブックマークレットをパブリッシュ用ソースにする(一つ)
394function _publishone(src){
395        var title = src.getElementsByTagName("h2")[0].innerHTML;
396        var code = src.getElementsByTagName("script")[0].innerHTML;
397        var description = src.getElementsByTagName("p")[0].innerHTML;
398        var attribute = document.getElementById("bookmarkletpublishattribute").value;
399        code = _removecomment(code);
400
401        var hrefsrc = _htmlencode(_code2bookmarklet(code, "portable"));
402
403        return "<a href=\"" + hrefsrc + "\" " + attribute + " >" + title + "</a> " + description;
404}
405
406//javascriptコードの前後を挟むHTMLコメントマークを削除する
407function _removecomment (html) {
408        return html.replace(/^\s*<!-{2}|-{2}>\s*$/g, "");
409}
410
411//aタグノードを生成して返す
412function _anchornode(text, href) {
413        var t = document.createElement("a");
414        t.innerHTML = text;
415        t.href = href;
416        return t;
417}
418
419//javascriptコードをブックマークレットに変換
420// type = readable | reversible | portable
421function _code2bookmarklet (code, type ) {
422        code = "(" + code + ")();";
423        switch (type) {
424                case "readable": // 可読 .. 改行などをスペースに変えただけ
425                        code = code.replace(/\s+/g, " ");
426                        break;
427                case "reversible": // 可逆 .. URLエスケープして、UTF8エンコードする
428                        code = _url_unicode2utf8(escape(code));
429                        break;
430                case "portable": // 短い .. できるだけ短くする
431                        code = code.replace(/%/g, "&#37;");
432                        code = code.replace(/(\w)\s+(?=\w)/g, "$1%20");
433                        code = code.replace(/\s+/g, "");
434                        code = code.replace(/%20/g, " ");
435                        break;
436                default: return "ERROR";
437        }
438        return "javascript:" + code;
439}
440
441//javascriptコードを評価するイベントハンドラメソッドを作成する
442function _getEvalFun(title, code) {
443        var evalline;
444        try{ eval("(") }catch(e){
445                if (e.lineNumber) evalline = e.lineNumber + 5;/*offset to next eval*/
446        }
447        return function(ev){
448                try{
449                        (eval(code))()
450                }catch(e){
451                        var message = title + " 実行時エラー: ";
452                        if (evalline) message += "(" + (e.lineNumber - evalline) + ") ";
453                        message += (e.name && e.message) ? e.name + ", " + e.message : e.toString();
454                        if (e.stack && evalline) {
455                                var infun = false, stack = e.stack.split(/(?:\r?\n|\r)+/);
456                                for (var i = stack.length - 1; i >= 0; i--) {
457                                        var line;
458                                        if (line = stack[i].match(/^(.*:)(\d+)$/)) {
459                                                if (!infun) {
460                                                        if (line[2] == evalline) infun = true;
461                                                        stack.splice(i, 1);
462                                                }else{
463                                                        stack[i] = line[1] + (line[2] - evalline);
464                                                }
465                                        }
466                                }
467                                message += "\n" + stack.join("\n");
468                        }
469                        if (evalline) message += "\n(※行番号はscript開始タグからの相対)";
470                        alert(message)
471                }
472                if (ev && ev.preventDefault) ev.preventDefault();
473                if (window.event) window.event.returnValue = false;
474        }
475}
476
477//可逆なブックマークレットをjavascriptコードに変換
478function _bookmarklet2code (let) {
479        let = let.replace(/\s+|javascript:/ig,"");
480        let = let.replace(/^%28(.*)%29%28%29(?:%3B)?$/,"$1");
481        let = unescape(_url_utf82unicode(let));
482        return let;
483}
484
485//ユニコード(%uXXXX)入りURLエンコードをUTF-8のURLエンコードに変換
486function _url_unicode2utf8(urlunicode){
487        return urlunicode.replace(/%u([0-9a-f]{4})/ig,
488                function(m0, m1){
489                        var char = parseInt("0x" + m1);
490                        if(char <= 0x7F){
491                                return  __p02X(char);
492                        }else if(char <= 0x7FF){
493                                return  __p02X(0xc0 | (char >> 6)) +
494                                                __p02X(0x80 | (char & 0x3f));
495                        }else if(char <= 0xFFFF){
496                                return  __p02X(0xe0 | (char >> 12)) +
497                                                __p02X(0x80 | ((char >> 6) & 0x3f)) +
498                                                __p02X(0x80 | (char & 0x3f));
499                        }else if(char <= 0x1FFFFF){
500                                return  __p02X(0xf0 | (char >> 18)) +
501                                                __p02X(0x80 | ((char >> 12) & 0x3f)) +
502                                                __p02X(0x80 | ((char >> 6) & 0x3f)) +
503                                                __p02X(0x80 | (char & 0x3f));
504                        }
505                        return m0;
506                }
507        );
508}
509//printf の "%02X" フォーマットの代替
510function __p02X(char) {
511        char = char.toString(16);
512        return "%" + ("00" + char).slice(-2);
513}
514
515//UTF-8のURLエンコードをユニコード(%uXXXX)入りURLエンコードに変換
516function _url_utf82unicode(urlutf8){
517        urlutf8 = urlutf8.replace(/%([f][0-7])%([8-b][0-9a-f])%([8-b][0-9a-f])%([8-b][0-9a-f])/gi,
518                function(m0,m1,m2,m3,m4){
519                        return "%u" + (
520                                ((parseInt("0x" + m1) & 0x07) << 18) +
521                                ((parseInt("0x" + m2) & 0x3f) << 12) +
522                                ((parseInt("0x" + m3) & 0x3f) << 6) +
523                                 (parseInt("0x" + m4) & 0x3f)
524                        ).toString(16);
525                }
526        );
527        urlutf8 = urlutf8.replace(/%([e][0-9a-f])%([8-b][0-9a-f])%([8-b][0-9a-f])/gi,
528                function(m0,m1,m2,m3){
529                        return "%u" + (
530                                ((parseInt("0x" + m1) & 0x0f) << 12) +
531                                ((parseInt("0x" + m2) & 0x3f) << 6) +
532                                 (parseInt("0x" + m3) & 0x3f)
533                        ).toString(16);
534                }
535        );
536        urlutf8 = urlutf8.replace(/%([cd][0-9a-f])%([8-b][0-9a-f])/gi,
537                function(m0,m1,m2){
538                        return "%u" + (
539                                ((parseInt("0x" + m1) & 0x1f) << 6) +
540                                 (parseInt("0x" + m2) & 0x3f)
541                        ).toString(16);
542                }
543        );
544        return urlutf8;
545}
546
547//HTMLエンコードを行う
548function _htmlencode (str) {
549        return str.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
550}
551
552// イベントの追加
553function _addEvent(eventname, fun) {
554        if (this.addEventListener) {
555                this.addEventListener(eventname, fun, false);
556        } else {
557                var me = this;
558                this.attachEvent("on" + eventname, function(){return fun.apply(me);});
559        }
560        return this;
561}
562
563// --></script>
564</body>
565</html>
Note: See TracBrowser for help on using the browser.