コネタ ― 2007年05月15日 12時14分05秒
スクリプトも書かずに他人様のサイトへのリンクでお茶を濁してみたり。
なつかし~。昔ブックマークしてたけどどっかに埋もれちゃった上に忘れてた。TITLEが「PI=3.」というのがイカす。
はてブ経由。ひさびさに衝撃を受けた。ここと似たにおいがする。もう更新しないのかなぁ。
いままでなかなかありそうでなかったツールかな。自分でもつくろう作ろうと思って手を付けてなかった。ただ、リテラルのArrayはJSONテキストを直接編集なのが残念。プロパティ名をツリーノードに割り当てるので仕方ないが。
JSONの整形出力 ― 2007年05月15日 15時02分35秒
JSONの可読性
先のエントリで、オンラインJSONエディタのことを書いたが、それと関連。
dara-jは、個人的なスクリプト(WSH/HTA/ASP)をちょろちょろ書いているが、設定を要するものは今は大体JSONにしている。
ところがjson.jsなどのライブラリで出力すると、不要な空白や改行が除去されるため可読性が極端に悪く、テキストエディタでちょっと編集というわけには行かない。まぁそのおかげで処理が速いんだけど。
そこで、ちょっとでも編集しやすいようにと思い、整形出力するライブラリを書いてみた。
Json.Formatter
コードはちょっと大きめで申し訳ないが、以下のような感じ。
// 文字列を引用符で囲う String.prototype.quote = function() { var s = this; var a = [ { match : /\\/g, replace : "\\\\" }, { match : /\f/g, replace : "\\f" }, { match : /\n/g, replace : "\\n" }, { match : /\r/g, replace : "\\r" }, { match : /\t/g, replace : "\\t" }, { match : /\v/g, replace : "\\v" }, { match : /"/g, replace : "\\\"" } ]; for(var i = 0; i < a.length; i++) { var value = a[i]; s = s.replace( value.match, value.replace ); }; return [ "\"", s, "\"" ].join(""); } if( typeof( Json ) == "undefined" ) { var Json = { } } Json.Formatter = function() { this.initialize.apply( this, arguments ); } Json.Formatter.prototype = { value : false, // 初期化処理 initialize : function(obj) { var indent_char = Json.Formatter.indentString || "\t"; var name = arguments[1] ? arguments[1].toString().quote() : null; var indent = isNaN( arguments[2] ) ? 0 : Number( arguments[2] ); var current_indent = Json.Formatter.createString( indent_char, indent ); var buffer = [ current_indent ]; if( name ) { buffer.push( name ); buffer.push( " : " ); } var type = typeof( obj ); if( type == "undefined" ) { // undefined // なにもしない } else if( obj == null ) { // null // プロパティの値の場合のみ'null'を追加 if( name ) buffer.push( "null" ); } else if( type == "string" ) { // string buffer.push( obj.quote() ); } else if( type == "number" ) { // number buffer.push( obj.toString() ); } else if( type == "boolean" ) { // boolean buffer.push( ( !! obj ).toString() ); } else if( obj instanceof Array ) { // array var hasProp = obj.length > 0; var lastIndex = obj.length - 1; buffer.push( "[" ); buffer.push( hasProp ? "\r\n" : "" ); // 要素を再帰処理 for(var index = 0; index < obj.length; index++) { var v = obj[ index ]; if( v != null ) { buffer.push( new Json.Formatter( v, null, indent + 1 ).value ); buffer.push( index < lastIndex ? "," : "" ); buffer.push( "\r\n" ); } } if( buffer.length > 2 && buffer[ buffer.length - 2 ] == "," ) buffer[ buffer.length - 2 ] = ""; buffer.push( hasProp ? current_indent : "" ); buffer.push( "]" ); } else { // object var hasProp = false; for(var key in obj) { if( typeof(obj) != "function" ) { hasProp = true; break; } } buffer.push( "{" ); buffer.push( hasProp ? "\r\n" : "" ); // プロパティを再帰処理 for(key in obj) { if( typeof(obj[key]) == "function" ) continue; buffer.push( new Json.Formatter( obj[key], key, indent + 1 ).value ); buffer.push( ",\r\n" ); } if( hasProp ) buffer.length--; buffer.push( hasProp ? "\r\n" : "" ); buffer.push( hasProp ? current_indent : "" ); buffer.push( "}" ); } // valueプロパティ確定 this.value = buffer.join(""); var self = this; this.toString = function() { return self.value; } } } Json.Formatter.createString = function(c, l) { var result = new Array( l ); for(var i = 0; i < l; i++) result[ i ] = c; return result.join(""); } Json.Formatter.indentString = "\t";他のライブラリには依存していないのでこれ単体で使用できるが、文字列を引用符でくくるためにString.prototypeを拡張している。気になる向きは関数化するなどすれば問題ないと思う。コード中で使用しているのは2箇所のみだし。
使い方
コンストラクタにJSON化したいオブジェクトを渡してvalueプロパティを参照するだけ。
var obj = { a : "property A", b : 30, c : true, d : [ 0, 1, 2 ] }; var formatter = new Json.Formatter( obj ); alert( formatter.value ); // 以下のような出力を得る /* { "a" : "property A", "b" : 30, "c" : true, "d" : [ 0, 1, 2 ] } */インデントはタブで行われるが、Json.Formatter.indentStringプロパティを変更することで任意の文字列にできる。
サンプル
注意など
重い。小さなオブジェクトなら問題ないけど、100行単位のArrayとか、ネストが深いObjectとかをかませるとかなり重い。だれか効率よくなるようにアドバイスください><
あと、このライブラリはオブジェクト → JSONのみのライブラリです。JSON → オブジェクトは他のライブラリを併用するか、漢らしくeval()するかで対応してください。dara-jはjson.js使うけど。
ま、あまり需要ないかな。
StartForceとFirebug ― 2007年05月15日 18時56分04秒
EditGrid使えるよ
5/12のエントリでStartForceをFirefoxで動かした場合に
アップロードした.xlsファイルまで開ける表計算アプリがあるんだけど、Firefoxで開くとFirefox自体まで道連れにしてフリーズしてしまう。ということを書いた。
ところで今日、IT戦記さんとこの記事で「Livedoor Readerなんかを使うとFirebugが壊れる原因」てのが書いてあり、
ここをなんてことが書いてあった。while (win && win.parent != win)こういう風に修正while (win && win.parent != win && win.parent instanceof Window)
これみてなんとなく「ありゃ、Firebugと相性悪いか?」と思い、Firebugを切ってStartForceにログイン、EditGrid(表計算アプリ)を立ち上げてみた。おお、ちゃんと起動できるじゃん
LDRと同じ原因か?
ああ、ひょっとしたら根っこは同じかも、と思い、IT戦記さんとこの修正を自分の環境に適用してみた。
が、状況は変わらず、ブラウザ本体を道連れにフリーズ。ふむ。
せめてInspect Elementくらい...
EditGridには効果がなかったものの、ひょっとしたら「Inspect Element」でのスクリプトエラー多発にはなにがしかの効果があったかも、と思って試してみたがあえなく沈没。ただし、Firebugのメニューから(Inspect Elementではなく)Command Lineを実行する分には問題ないので、「あー、なんかしょっちゅうPOSTしてるよー、なんにもしてないのに」とかを確認することはできたが、うっかりしてフリーズすると腹立たしいのでStartForceのサイト(www1.startforce.jp)をFirebugから除外することにした。
結論
- FirebugをenabledにしているときにEditGridを立ち上げてはいけない
- 間違ってもInspect Elementしてはいけない
- なんでFirefoxのときはコンテキストメニューが働かない?
最近のコメント