LineNumberWriterを0.4にバージョンアップ

1年以上放置していたので今更感がありますが、LineNumberWriterをバージョンアップしました。今回から、変換対象のコード内でタグが使えるようになります。例えば以下のように、strong要素やspan要素などを挿入することが可能です。(※)

<strong>で囲んでみました
<span style="color:#F33;">で囲んでみました

※もちろん(X)HTMLの文法的にcode要素に含められない内容(ブロック要素など)は含めちゃダメですよ。

今度Sugamo.cssという企画に参加することにしたので、何かプライベートワークをやっていかなきゃいけないような気になり、とりあえずコレのバージョンアップでも、と着手しました。
実は前からタグが使えるようにしたくてちょくちょくいじってはいたんですが、IEの独自仕様でまた色々とつまづいてしまい、挫折しちゃってたんです。でもまぁ最近、良いアイデアが浮かんだのでどうにか形になった、という。

ダウンロードしようなどという奇特な方はこちらからどうぞ。

[Memo]:visitedクラスを利用した行動ターゲティング広告

とても興味深い内容だったのでメモ。

id:Hamachiya2さんのデモのソースを見るとCSSの:visited擬似クラスと、JavaScriptを併用した形で、動的にコンテンツを入れ替える方法が分かります。

まずCSSで:visited擬似クラスに別のスタイルを書いておいて

a {
display: block;
height: 22px;
overflow: hidden;
}
a:visited {
height: 16px;
}

JavaScriptの以下のようなコードで、訪問の有無を調べています。

var defHeight = 22;
var visHeight = 16;
...中略...
// 引数にはa要素ノードを入れる
// その高さがデフォルトでない(既訪問リンク)ならtrueを返す
// その高さがデフォルト(未訪問リンク)ならfalse返す
function checkVisited(elm) {
return (elm.offsetHeight != defHeight);
}

実行はwindow.onloadのイベントで。なるほど。

自らの意図しない情報が、このように簡単に取得されてしまうのかと思うと、気持ちが悪いな・・・と思うと同時に、簡単であるが故に防ぎようがないと思いました。

LineNumberWriter開発メモ

LineNumberWriterを作るに当たって気づいた点やその他補足など。自分で書いていて改めて気付きましたけど、かなりの欠陥品です…orz

基本設計

行番号を振るための処理は、基本的にsyntaxhighlithter.jsとほとんど同じ。というか、syntaxhighlighter.jsを参考にして作りました。

処理の流れとしては、

  1. まずページ内に<pre><code>とマークアップされている部分を取得します。
  2. それら個々を<ol><li>番号順リストのマークアップに変換します。それら個々を<ol><li>番号順リストのマークアップに変換したものと、そのままのもの(プレーンテキスト)、それぞれ二つづつを生成します。プレーンテキストの方はデフォルトで非表示にします
  3. 奇数行と偶数行のli要素それぞれに別のclass属性値を設定します。
  4. 変換後のコードとプレーンテキストとを切り替えるヘッダー部分を生成します。
  5. 最後にdiv要素で包みます(後でスタイルを整える都合)。最後にこれらをdiv要素内に書き出し、元の<pre><code>部分と差し替えます。
<pre><code>function sample() {
alert("sample");
}</code></pre>

これが

<div class="LNW">
<div class="header" style="display:none">
<a href="#" class="ctrl1">with line number</a>
<span class="ctrl2">plain text</span>
</div>
<div class="header">
<span class="ctrl1">with line number</span>
<a href="#" class="ctrl2">plain text</a>
</div>
<ol>
<li class="odd">function&nbsp;sample()&nbsp;{</li>
<li class="even">&nbsp;&nbsp;alert(&quot;sample&quot;);</li>
<li class="odd">}</li>
</ol>
<pre style="display:none"><code>function sample() {
alert("sample");
}</code></pre>
</div>

こうなります。

Continue reading

LineNumberWriter – syntaxhighlighter風のJavaScriptを書いてみた

最近いろんなところで見かけるようになったsyntaxhighlighter.js。文法が分かりやすいようにコードがカラーリングされ、行番号が付いてとてもコードが見やすいです。導入を検討しようかと思ったのですが、(X)HTML的に文法違反になるのは許せないなーと思い、違った形のものをJavaScriptで書いてみました。当サイトに導入済みです。次のような見た目になります。

function sample() {
alert("sample");
}

ただし、私が作ったのはSyntaxHighlighterではありません。行番号が付き1行おきに背景色が付くだけのものです。syntaxはhighlightされません。よって、SyntaxHighlighterとは名乗れないので、LineNumberWriterと名乗ることにします(これ、果たして妥当な英語なんでしょうか・・・)。

もし使ってみたいという方がおりましたらご自由に使ってみてくださいまし。下記リンクからzipファイルでダウンロードできます。

linenumberlighter Ver.0.4.1

勢いで作ったものなので、バージョンは0.1ということにします。それから一応、ライセンスはMITライセンスとしておきますね。(2008年4月5日追記)更新履歴を付けるようにしました。

Continue reading

JavaScriptのオブジェクトシステムについての、現時点での私の理解

JavaScriptでは全てのデータをオブジェクトで表現できる

通常はリテラル(スクリプト文中に直接データを書き込んだもの)で表現するデータを、JavaScriptではオブジェクトとしても表現できるようになっています。(厳密にはリテラルで書いたデータとオブジェクトで書いたデータは異なるものですが、その説明は省略)

リテラルで表現した場合と、オブジェクトとして表現した場合の比較
  リテラルで表現した場合 オブジェクトとして表現した場合
数値 100 new Number(100)
文字列 "fuga" new String("fuga")
真偽値 true new Boolean(true)
配列 ["foo","bar"] new Array("foo","bar")
正規表現 /fuga/ new RegExp("fuga")
オブジェクト {} new Object()
関数 function(foo) {alert(foo)} new Function("foo","alert(foo)")

プロパティについて

オブジェクトはその内部にプロパティを持つことができます。オブジェクト名とプロパティ名をドットで繋げることプロパティを呼び出せます。
例えば Array オブジェクトは length というプロパティを持ち、オブジェクト名.lengthとすることで、この配列オブジェクトの持つ要素の数を取り出すことができます。

var hoge = new Array("foo","bar");
alert(hoge.length) // 2 が表示される

length のようなものは Array オブジェクトに最初から組み込まれているプロパティなので、特に自分で定義しなくてもいきなり使うことができます。もちろん自分でプロパティを作ることもできます。

プロパティを作るには、作成したオブジェクトに .(ドット)を付けてプロパティを定義します。

var hoge = {};
hoge.x = 100;
alert(hoge.x); // 100 が表示される

もしくは、オブジェクトを作成する際にオブジェクトリテラル形式で定義します。

var fuga = {x: 100, y: 50}
alert(fuga.x + fuga.y); // 150 が表示される

コンストラクタとインスタンス

「オブジェクトで表現した」場合、new XXX()という文になりますがこれはXXX()というコンストラクタから新たなオブジェクトを作る、という意味となります。コンストラクタとは新たなオブジェクトを作る雛形のようなものであり、コンストラクタから作られたオブジェクトをインスタンスと呼びます。

JavaScriptでは関数をコンストラクタとして使うことができます。関数を定義する際、this.XXXという書き方でプロパティを定義しておくと、そのプロパティはインスタンスにも引き継がれます。

// hoge()コンストラクタを作成
// hoge()のプロパティとして x=100 を定義
function hoge() {this.x = 100;}
// hoge()コンストラクタからfugaオブジェクトを作る
// fugaオブジェクトはhoge()コンストラクタのインスタンスとなる
var fuga = new hoge()
// hoge()コンストラクタから x=100 プロパティが
// 継承されているので 100 が表示される
alert(fuga.x)

今回はこの辺までで。
prototypeチェーンについてはまだ勉強中・・・。

Continue reading