ブックマークレットでpukiwkiの編集中のDiffをとるサンプルを先日示したが、同様に表題のようなサンプルを作成してみた。前回同様、EUC/utf-8、PukiWiki/PukiWikiPlusなどのターゲットの環境を選ばないようにしています。
このブックマークレットでできること
- pukiwiki及びPlusなどの派生版で、tracker_list、bugtrack_listで表示される表を、ExtJSのGridPanelで置き換えます
- 置き換えられたGridPanelは、ヘッダ部をクリックすることにより、サーバと通信することなくソート可能です
- 同じくヘッダ部を操作することにより、列の表示/非表示切り替え、列幅の調整、列の表示位置変更等が可能です
- 「ページ名」というヘッダを持つ列は、単に文字列によるソートでなく、ページ名に現れる番号を意識して並べ替えられるので、「BugTrack1/100」は「BugTrack1/22」や「BugTrack1/9」よりも後に表示されます((並べ替えの際、スラッシュで区切られる文字列が数字のみである場合、5ケタになるよう前ゼロを付けたのちに比較されます。「BugTrack1/22」は「BugTrack1/00022」に、「ほげ/2/3」は「ほげ/00002/00003」に、比較時に内部的に変換されます))
- 1.まず下記のURLをブックマーク(IEはお気に入り)に登録します。名前はなんでもいいです。(たとえば「pukiwiki Table」)
javascript:(function(){var%20e=document.createElement('script');e.charset='utf-8';e.src='http://www123.ddo.jp/tools/tracker00.js';document.body.appendChild(e);})()
- 2.いつも使っているpukiwikiのサイトのBugTrackの画面等を開き、登録したブックマーク(お気に入り)を選びます。
- 3.すると、上記のようにテーブルがExtJSのgridに変換され、ソートなどの操作ができるようになります
ブックマークレットとスクリプトの解説
上記のブックマークは改行とインデントを入れ読みやすくすると
javascript:(
function(){
var e=document.createElement('script');
e.charset='utf-8';
e.src='http://www123.ddo.jp/tools/tracker00.js';
document.body.appendChild(e);
}
)()
見ての通り、これでwww123.ddo.jpからtracker00.jsというスクリプトを読み込んで実行しているわけです。
読み込んだtracker00.jsは下記のような動作をします。
読み込んだtracker00.jsは下記のような動作をします。
- ExtJS 3.3.1を動かすために必要なライブラリやスタイルシートを読み込む
- 最初のtrの要素がtdでなくすべてthであるtableタグについて下記を行います
- ヘッダー部の解析とデータストアの作成
- データの読み込みとGridPanelの描画
下記ページにて確認をしています
- extwiki(utf-8) BugTrack1
http://extwiki.sourceforge.jp/index.php?cmd=read&page=BugTrack1
- PukiWiki dev(EUC) BugTrack2
http://pukiwiki.sourceforge.jp/dev/?BugTrack2
- PukiWIkiPlus(utf-8) BugTrack
http://pukiwiki.cafelounge.net/plus/?BugTrack
セキュリティについて
edit00.jsと同様なセキュリティのリスクがあります。理解したうえでお試しください。
tracker00.jsソースコード
// tracker.js v 00 -- pukiwikiのTrackerの機能アップ
// Bookmarklet example
// javascript:(function(){var%20e=document.createElement('script');e.charset='utf-8';e.src='http://www123.ddo.jp/tools/tracker00.js?';document.body.appendChild(e);})()
// Copyright(c) 2010 mashiki
// License: GPL version 3
(function(){
var cf='http://extjs.cachefly.net/ext-3.3.1/';
addEl('style', {type:'text/css',innerHTML:'td {background-color:transparent}'});
addEl('link',{rel:'stylesheet',type:'text/css',href:cf+'resources/css/ext-all.css'});
addEl('script',{src:cf+'adapter/ext/ext-base.js'});
addEl('script',{src:cf+'ext-all.js'});
addEl('script',{src:cf+'examples/ux/TableGrid.js'});
function addEl(tag, cfg) {
var e=document.createElement(tag);
for (var key in cfg) e[key]=cfg[key];
document.body.appendChild(e);
}
var id=setInterval(function(){
if(window.Ext && Ext.MessageBox){
clearInterval(id);
var ce = Ext.select('table');
ce.each(function(tbl){
var tr0 = tbl.select('tr', true).first();
var hdrs = tr0.query('th');
if (hdrs.length>0 && tr0.query("td").length===0 ) {
convertToGrid(tbl, hdrs);
}
},true);
}
},100);
function convertToGrid(tbl, hdrs) {
var ct = tbl.insertSibling(),
flds = [{name:'no'}],
cols = [];
for (var i=0, h; h=hdrs[i]; ++i) {
var text = h.innerHTML.replace(/]+>(.+?)<\/a>/gi,'$1')
.replace(/\s*(:?↑|↓)\([\d]+\)/,''),
name = 'tcol-' + i;
var fld = {
name: name,
mapping: 'td:nth('+ (i+1) +')/@innerHTML'
};
if (text==='ページ名') {
fld.sortType = function(val) {
var parts = val.replace(/]+>(.+?)<\/a>/gi,'$1').split("/");
for (var i=0,p; p=parts[i];++i) {
if (p.match(/^[\d]+$/)) {
parts[i]=String.leftPad(p, 5, '0')
}
}
return parts.join('/');
}
}
flds.push(fld);
cols.push({
header: text,
dataIndex: name,
width: h.offsetWidth,
tooltip: h.title,
align: 'left',
sortable: true
});
}
var ds = new Ext.data.Store({
reader: new Ext.data.XmlReader({
record: 'tbody tr'
}, flds)
});
ds.loadData(tbl.dom);
var r = ds.getAt(0);
if (!(r.get(0))) ds.remove(r);
i = 0;
ds.each(function(r){r.set('no',++i)});
ds.commitChanges();
ct.setWidth(tbl.getWidth());
tbl.remove();
var grid = new Ext.grid.GridPanel({
stripeRows: true,
'ds': ds,
'cm': new Ext.grid.ColumnModel(cols),
'sm': new Ext.grid.RowSelectionModel(),
autoHeight: true,
autoWidth: false,
renderTo:ct
});
}
})();
tracker00.jsソースコード
// tracker.js v 00 -- pukiwikiのTrackerの機能アップ
// Bookmarklet example
// javascript:(function(){var%20e=document.createElement('script');e.charset='utf-8';e.src='http://www123.ddo.jp/tools/tracker00.js?';document.body.appendChild(e);})()
// Copyright(c) 2010 mashiki
// License: GPL version 3
(function(){
var cf='http://extjs.cachefly.net/ext-3.3.1/';
addEl('style', {type:'text/css',innerHTML:'td {background-color:transparent}'});
addEl('link',{rel:'stylesheet',type:'text/css',href:cf+'resources/css/ext-all.css'});
addEl('script',{src:cf+'adapter/ext/ext-base.js'});
addEl('script',{src:cf+'ext-all.js'});
addEl('script',{src:cf+'examples/ux/TableGrid.js'});
function addEl(tag, cfg) {
var e=document.createElement(tag);
for (var key in cfg) e[key]=cfg[key];
document.body.appendChild(e);
}
var id=setInterval(function(){
if(window.Ext && Ext.MessageBox){
clearInterval(id);
var ce = Ext.select('table');
ce.each(function(tbl){
var tr0 = tbl.select('tr', true).first();
var hdrs = tr0.query('th');
if (hdrs.length>0 && tr0.query("td").length===0 ) {
convertToGrid(tbl, hdrs);
}
},true);
}
},100);
function convertToGrid(tbl, hdrs) {
var ct = tbl.insertSibling(),
flds = [{name:'no'}],
cols = [];
for (var i=0, h; h=hdrs[i]; ++i) {
var text = h.innerHTML.replace(/]+>(.+?)<\/a>/gi,'$1')
.replace(/
name = 'tcol-' + i;
var fld = {
name: name,
mapping: 'td:nth('+ (i+1) +')/@innerHTML'
};
if (text==='ページ名') {
fld.sortType = function(val) {
var parts = val.replace(/]+>(.+?)<\/a>/gi,'$1').split("/");
for (var i=0,p; p=parts[i];++i) {
if (p.match(/^[\d]+$/)) {
parts[i]=String.leftPad(p, 5, '0')
}
}
return parts.join('/');
}
}
flds.push(fld);
cols.push({
header: text,
dataIndex: name,
width: h.offsetWidth,
tooltip: h.title,
align: 'left',
sortable: true
});
}
var ds = new Ext.data.Store({
reader: new Ext.data.XmlReader({
record: 'tbody tr'
}, flds)
});
ds.loadData(tbl.dom);
var r = ds.getAt(0);
if (!(r.get(0))) ds.remove(r);
i = 0;
ds.each(function(r){r.set('no',++i)});
ds.commitChanges();
ct.setWidth(tbl.getWidth());
tbl.remove();
var grid = new Ext.grid.GridPanel({
stripeRows: true,
'ds': ds,
'cm': new Ext.grid.ColumnModel(cols),
'sm': new Ext.grid.RowSelectionModel(),
autoHeight: true,
autoWidth: false,
renderTo:ct
});
}
})();
0 件のコメント:
コメントを投稿