2015年2月28日土曜日

Firefox36.0がリリースされました。

02月24日に Firefox36.0 がリリースされました。

デスクトップ版 Firefox のダウンロード
http://www.mozilla.jp/firefox/download/
デスクトップ版 Firefox のリリースノート
http://www.mozilla.jp/firefox/36.0/releasenotes/

新機能では

新しいタブページにピン止めしたWebサイトのタイルを Firefox Sync で同期できるようになったほか、HTTP/2 がサポートされるようになりました。検索バーのデザインが新しくなりました。

新しい検索バー

  • 新しい検索バーにキーワードを入力すると、デフォルト検索エンジンによる検索候補のリストが表示されます。さらにリストの下には検索エンジンのパレット(ワンクリック検索エンジン)が追加されました。このパレットを使えば、デフォルト検索エンジン以外の検索も簡単にできるようになります。
  • 検索候補リストの時計のアイコンは、その候補が検索履歴に基づいて表示されたことを示しています。
  • 検索バーに追加可能な検索エンジンがある場合は、検索バーに表示して知らせてくれます。
  • 検索候補の無効化や検索エンジンの登録は、検索バーの「検索設定を変更」やオプション設定で行えます。

さらに詳しく : 検索バー - Firefox の検索エンジンの追加、変更、管理 | Firefox ヘルプ


そのほかの新機能の詳細はリリースノートをご覧ください。



デスクトップ版 Firefox の、開発ツールの更新と追加された機能のまとめ



インスペクタ

右クリックメニューの「貼り付け」方法を選択できるようになりました。

  • HTMLツリーの右クリックメニューに表示される「貼り付け」の項目追加されて、貼り付けの方法を選択できるようになりました。
  • 追加された項目は、ノードの innerHTML や outerHTML として貼り付けのほか、ノードの 直前 や 直後 に貼り付け。ノードの 最初の子要素 として貼り付けや 最後の子要素 として貼り付けが追加されました。

ノード削除時の選択動作の改善

  • 選択したノードを削除した場合、新しい選択位置として前の兄弟要素が選択されます。


デバッガ

eval で評価されるソースを表示

動的に評価される eval() や、関数コンストラクタに渡される文字列をデバッグできるようになりました。

//# sourceURL ディレクティブを使うと、評価される eval ソースに名前をつけることができます。これによって、ソース一覧に名前が表示されて、ソースが整形表示されるようになります。また、この名前は Web コンソールのスタックトレースでも使用されるようになります。

さらに詳しく : eval ソースをデバッグする | MDN



Web コンソール

コンソールで Promise オブジェクトを調査できるようになりました。

Promise オブジェクトの状態や、値が表示されます。

  • pending(初期状態)
    Promise { <state> "pending" }
  • rejected(失敗)の場合 xx に失敗したオブジェクトの値が表示されます
    Promise { <state> "rejected" <reason>: xx }
  • fulfilled(成功)の場合 xx に成功したオブジェクトの値が表示されます
    Promise { <state> "fulfilled" <value>: xx }

さらに詳しく :

参考:Promise の使い方については「JavaScript Promiseの本」がお勧めです。詳しく書かれていて分かりやすいです。


メッセージ発生元の列番号を表示

コンソールのメッセージ表示ペインでは、メッセージが発生した行へのリンクに列番号も含めて表示するようになりました。


SHA-1ベースの証明書のセキュリティ警告

SHA-1証明書を利用したサイトにアクセスした場合、コンソールに以下の警告メッセージが表示されるようになりました。

「このサイトは SHA-1 証明書を利用しています。SHA-1 より強固なハッシュアルゴリズムを使用した証明書の利用をお勧めします。」

さらに詳しく :



WebIDE

Android 版 Firefox への接続手順を改善

WebIDE を使用した接続方法によって、Android 版 Firefox に簡単に接続できるようになりました。

さらに詳しく : WebIDE による Android 版 Firefox のデバッグ | MDN


WebIDE のフォントサイズの変更

キーボードショートカットを使用して変更できるようになりました。

  • Ctrl + でフォントサイズを拡大
  • Ctrl - でフォントサイズを縮小
  • Ctrl 0 でフォントサイズを既定に戻す


パフォーマンス

パフォーマンスに"呼び出しツリーを反転"のチェックボックスが追加されました。

デフォルト設定では、プロファイラのコールツリーはトップレベルの関数をルートとして、末端の関数の方向に向かって順に表示されます。いっぽうで、コールツリーの末端のほうにボトルネック箇所が存在することがよくあります。そのような場合は、コールツリーを反転表示することによって、コールツリーのリストがサンプル数の大きい順に並べかえられます。サンプル数はブラウザの実行時間に対応するため、コード内のボトルネック箇所を見つけやすくなります。

さらに詳しく : プロファイラのチュートリアル | MDN



パフォーマンスタイムライン

タイムラインに「メモリ計測を有効にする」オプションが追加されました。

この機能はデフォルトでは無効化されています。Firefox35からオプションメニューに表示されるようになっていますが、未だテスト段階なのかもしれません。このパフォーマンスタイムラインは、実行中のブラウザ・エンジンGeckoの稼働状況を追跡するようです。

さらに詳しく : Timeline - Firefox Developer Tools | MDN

2015年2月24日火曜日

TiddlyWikiの検索プラグインをカスタマイズ

この投稿では TiddlyWiki classic (TWc)のプラグインのひとつ 「SimpleSearchPlugin」について書いています。

SimpleSearchPlugin

TiddlyWiki に標準で組み込まれている検索機能は、マッチした tiddler を全て表示するタイプなので検索結果によっては tiddler の洪水になってしまうことがありました。この SimpleSearchPlugin では、そんな心配はありません。

SimpleSearchPlugin は検索結果を「リスト形式」で表示してくれる便利なプラグインです。検索結果リストの tiddler を全て一括して開くこともできますが、選択した tiddler だけを開くことができるのが大きな特長です。マッチした結果リストから、どの tiddler を開くべきなのかは全てユーザーの選択に委ねられています。検索結果は 「ほぼタイトル順」 に表示されます。(「ほぼタイトル順」については後述します)

既に1年ほど、このプラグインを使っていますが、ここ最近の個人的なニーズでは検索結果リストの並び順は時系列のほうが使いやすいように感じています。特にマッチ件数が多い場合はなおさらのことです。そこで今回は検索結果リストの並び順を tiddler の変更日順に修正することにしました。



SimpleSearchPlugin の動作概要

  1. SimpleSearchPlugin は、前半に検索結果を表示する UI と css 部分、後半に標準の検索機能をオーバーライドする関数で構成されています。これによって標準の検索機能は、新しい検索機能に書き換えられます。
  2. TiddlyWiki の検索機能は、標準の組み込みマクロの search ハンドラ がユーザーからの入力を受け取った後、引数に検索文字列と検索オプションをセットして Story.search() を呼び出します。
  3. オーバーライドされた Story.prototype.search() と TiddlyWiki.prototype.search() によって、新しい検索機能で処理された検索結果リストを画面に出力します。


はじめに Story.search() から見ていきます

Story.search() は、引数に検索文字列と検索オプションを受け取り、マッチした結果のリストを画面に表示します。

Story って何?
story オブジェクトは Story クラスのインスタンスです。tiddler の表示全般を受け持つオブジェクトです。

Story.prototype.search = function(text, useCaseSensitive, useRegExp) {}

引数

  • text : (string) 検索文字列。
  • useCaseSensitive : (boolean) 検索で大文字小文字を区別。
  • useRegExp : (boolean) 正規表現で検索。

Story.search() は、検索オプションに従って予め検索文字列を加工してから store.search() に渡します。このとき、ソート項目を指定する引数 sortField は null が設定されています。

    var matches = store.search(highlightHack, null, "excludeSearch");

Story.search() の最後で、マッチした検索結果のリストを displayResults() に渡して画面に表示します。



つづいて store.search() を見ていきます

store.search() は、引数に検索文字列の正規表現オブジェクトと検索オプションを受け取り、マッチした tiddler オブジェクトの配列を返す関数で、このプラグインの主役です。

store って何?
store オブジェクトは TiddlyWiki クラスのインスタンスで、tiddler の作成や削除、保存や更新などの tiddler の操作全般を受け持つオブジェクトです。store オブジェクトの実体は HTML の非表示 DIV 要素です。

TiddlyWiki.prototype.search = function(searchRegExp, sortField, excludeTag, match) {}

引数

  • searchRegExp : (string) 検索文字列。
  • sortField : (string) ソート対象のフィールド名( tiddler オブジェクトのプロパティ)を指定。
  • excludeTag : (string) 検索結果から除外するタグ名を指定。
  • match : (boolean) 検索条件にマッチするものを含めるか、又は除外するかを指定。


対象 tiddler を抽出

store.search() は、最初に reverseLookup() を実行しています。このとき実際に渡される引数を整理すると、このようになります。

  var candidates = this.reverseLookup("tags", "excludeSearch", false);

この場合 reverseLookup() は「"tags" フィールドの値が "excludeSearch" にマッチしない」 tiddler を全て検索して、その結果を tiddler オブジェクトの配列で返します。このとき、引数 sortField を指定しない場合は、検索結果をタイトル順にソートして返されます。また、タグ名 "excludeSearch" はスペシャルタグのひとつで、検索結果から除外するタグ名として TiddlyWiki で設定されています。

言い換えると reverseLookup() は「検索除外に設定されていない tiddler 全て」を、タイトル順にソート済みの tiddler オブジェクトの配列で返します。


抽出結果を検索

次の search 部分ではオブジェクト配列の中から、「タイトル名」、「タグ名」、「本文テキスト」の各プロパティの値を検索して、各々の検索結果を収集した後で全てを結合しています。ここでは標準の検索機能に無かった「タグ名」が、新たに検索対象に加えられていることがわかります。

  var results = primary.concat(secondary).concat(tertiary);

検索結果をタイトル順にソート

if(sortField) {
  results.sort(function(a, b) {
    return a[sortField] < b[sortField] ? -1 : (a[sortField] == b[sortField] ? 0 : +1);
  });
}

最後に、検索結果を格納したオブジェクト配列を Story.search() に返す。


おおまかに、このような流れで処理が行われていることがわかります。

デバッガでコードをトレースしていて分かったのですが、どうやらタイトル順にソートするところで失敗しているようです。 と言うのも、引数の sortField は null で呼び出されているので、
if(sortField) {}if(null) {} となります。
したがってソートが実行されずにそのまま通過しているようです。その結果、「タイトル名」、「タグ名」、「本文のテキスト」のそれぞれの検索結果が存在する場合、検索結果リストは 「それぞれの、タイトル順」 で表示されることになります。

いままで「検索結果の一覧の並び順、なんか変だな?」と感じながら使っていたのですが、ようやく理由が分かった気がします。



検索結果の一覧を、変更日順に修正する

修正箇所がわかったので、ソート部分のコードを少し修正して 「tiddler の変更日順」 にしてみました。合わせて検索結果のリスト表示を修正して、変更日付を表示するようにしました。 tiddler オブジェクトのソートは store.sortTiddlers() を使っています。この関数は与えられた tiddler オブジェクトの配列を、指定した field でソートして返してくれます。


修正箇所は以下のとおりです

  1. displayResults()
    • 変更日を先頭に追加。
  2. TiddlyWiki.prototype.search()
    • 機能していないソート部分のコードをコメントアウト
    • ソート項目を指定する sortField の値を追加。
    • リストの内容を sortTiddlers() を使って並べ替え。

修正部分のコード

displayResults() の変更と追加

  displayResults: function(matches, query) {


    ......................


    if(matches.length > 0) {
      msg += "''" + config.macros.search.successMsg.format([matches.length.toString(), query]) + ":''\n";
      this.results = [];
      for(var i = 0 ; i < matches.length; i++) {
        this.results.push(matches[i].title);
  // add Date for results list
        msg += "* " + matches[i].modified.formatString("[ YYYY-0MM-0DD ]");
        msg += "  [[" + matches[i].title + "]]\n";
      }
    } else {
      msg += "''" + config.macros.search.failureMsg.format([query]) + "''"; // XXX: do not use bold here!?
    }


    ......................


    }
  },

TiddlyWiki.prototype.search() の変更と追加

  // override TiddlyWiki.search() to sort by relevance
  TiddlyWiki.prototype.search = function(searchRegExp, sortField, excludeTag, match) {


    ......................


    var results = primary.concat(secondary).concat(tertiary);

  // comment out sort function
  //  if(sortField) {
  //    results.sort(function(a, b) {
  //      return a[sortField] < b[sortField] ? -1 : (a[sortField] == b[sortField] ? 0 : +1);
  //    });
  //  }

  // add sortField, sortTiddlers
    sortField = "-modified";
    this.sortTiddlers(results,sortField);

    return results;
  };


一覧のソート項目や並び順を変更するには

sortField に "-modified" を指定すると、tiddler の変更日の新しい順にソートできます。tiddler の変更日の古い順にソートする場合は、マイナス記号の無い "modified" を指定します。文字の先頭に "-" をつけると降順になります。

他に、tiddler の作成日でソートする場合は "created" を、タイトル順なら "title" を指定できます。



修正済みのプラグイン全体のコード

https://icm7216.github.io/MyTiddlyWiki/#SimpleSearchPluginでも確認できます。



さいごに

TiddlyWiki を使い始めた頃は tiddler?, story?, store? と、良くわからない事がたくさんありましたが、ソースコードを眺めているうちに少しずつ TiddlyWiki World の謎が解けていくのが面白く感じています。TiddlyWiki の中は HTML, CSS, JavaScript で構成されているのでエディタで直接編集することも出来たり、Firefox の開発ツールで 「ごにょごにょ」 すれば、なんとか 「痒いところに手が届く」 のも気に入っている部分です。