つくってみよう - FireFox拡張機能でブックマークを一覧表示する 記事一覧
つくってみよう - FireFox拡張機能でブックマークを一覧表示する(1)公式サンプルを体験する
つくってみよう - FireFox拡張機能でブックマークを一覧表示する(2)動作を確認する
[つくってみよう - FireFox拡張機能でブックマークを一覧表示する(3)ソースコードを読む - 構成について]
(https://qiita.com/madaaamj/items/bef7102722da2f249515)
[つくってみよう - FireFox拡張機能でブックマークを一覧表示する(4)ソースコードを読む - 画面について]
(https://qiita.com/madaaamj/items/27dd820d10fd20c51dee)
[つくってみよう - FireFox拡張機能でブックマークを一覧表示する(5)ソースコードを読む - 処理の概要について]
(https://qiita.com/madaaamj/items/af88405b30820b19a114)
[つくってみよう - FireFox拡張機能でブックマークを一覧表示する(6)ソースコードを読む - JSON情報の取得について]
(https://qiita.com/madaaamj/items/d9e7b1c296221218d46a)
[つくってみよう - FireFox拡張機能でブックマークを一覧表示する(7)ソースコードを読む - 表示について①]
(https://qiita.com/madaaamj/items/68888b5d0fdb8f2af84f)
[つくってみよう - FireFox拡張機能でブックマークを一覧表示する(8)ソースコードを読む - 表示について②]
(https://qiita.com/madaaamj/items/a7e3f764f8177139bf7d)
ソースコードを読む
「FireFox拡張機能でブックマークを一覧表示する」機能をつくっていきましょう。
今回はJSON情報の取得の処理を見ていきます。
ブックマークファイルを読み込み配列に入れる
選択されたブックマークファイルのデータが保持されている変数lines
をJSON.parse()でパースしてオブジェクトjsonObj
に保持します。
そしてmakeTagdic()
でjsonObj
を元に変数dicTags
にキー/値の組み合わせで連想配列風配列を生成します。
// 1.ブックマークファイルを選択して読み込み一覧表を生成する。
function readFile() {
・・・
// ファイル読み込み時:ブックマークファイル(.json)を読み込む
reader.onload = function(e) {
let lines = e.target.result;
const jsonObj = JSON.parse(lines);
// JSONから辞書(連想配列)を作る
let dicTags = [];
try {
makeTagdic(jsonObj, dicTags);
}
catch (e) {
alert("Error : " + e.message);
return false;
}
・・・
ブックマークファイル(.json)の情報を保持する連想配列(dicTags)を生成する(makeTagdic)
makeTagdic関数では直前でパースしたjsonObj
を元に変数dicTags
にキー/値の組み合わせで連想配列風配列を生成します。
// 2.readFileから呼び出される。ブックマークファイル(.json)の情報を保持する連想配列(dicTags)を生成する。
function makeTagdic(jsonObj, dicTags) {
// タグ辞書を作る
let bookmarks = jsonObj['children']; // ルートの子供
for (let i = 0; i < bookmarks.length; i++) {
let folders = bookmarks[i].children;
if (folders) {
for (let j = 0; j < folders.length; j++) {
let arrFolders = [];
switchByTypecode(folders[j], dicTags, arrFolders);
}
}
}
// 取得したタグ辞書をソート
dicTags.sort(function(a, b) {
// フォルダーをタグより上に表示する
let flagA = a.folder;
let flagB = b.folder;
if (flagA < flagB) return 1; // 0より大きい場合、bをaより小さいインデックスにソート
if (flagA > flagB) return -1; // 0未満の場合、aをbより小さいインデックスにソート
// タイトル(フォルダー名・タグ名)の昇順にソートする
let nameA = a.name;
let nameB = b.name;
if (nameA < nameB) return -1;
if (nameA > nameB) return 1;
// URLの昇順にソートする
let urlA = a.url.toUpperCase(); // 大文字と小文字を無視する
let urlB = b.url.toUpperCase(); // 大文字と小文字を無視する
if (urlA < urlB) return -1;
if (urlA > urlB) return 1;
return 0; // 0を返した場合、aとbは互いに変更せず、他のすべての要素に対してソート
});
}
まずJSONファイルの構造を見ていきましょう。
GitHubに読みやすく整形したJSONファイルを置きましたのでそちらを参照しながら解説していきます。
最初(ルート)にある'children'タグの内容を取得します。
'children'には"title": "ブックマークメニュー",
"title": "ブックマークツールバー",
"title": "他のブックマーク",
"title": "モバイルのブックマーク",
の4つのブロックがあります。
それぞれのブロックの中に'children'があり、下層へ向かって辿っていくと"typeCode": 1,
を持つブロックにブックマーク情報があります。下の画像ではブックマークで"mecab"フォルダーにあるタグが"tags": "MeCab,リファレンス,自然言語処理",
、タイトルが"title": "MeCab: Yet Another Japanese Dependency Structure Analyzer",
、URLが"uri": "http://taku910.github.io/mecab/format.html"
についてのブックマークの情報が保持されていることがわかります。
このJSONの構造を利用して上のようなブックマーク情報をdicTags
に保持していきます。
今回はswitchByTypecode()
でtypeCode
を見て2の場合は再帰的に下層を辿っていく関数で処理しています。typeCode
が1の場合はブックマーク情報なのでこのブロックの情報をmakeDictionary()
でdicTags
にセットします。
// 3.makeTagdicから呼び出される。JSONのURL要素まで下りブックマークの情報を取得する。
function switchByTypecode(folderObj, dicTags, arrFolders) {
switch (folderObj.typeCode) {
case 1: // bookmark "text/x-moz-place"
if (!folderObj.uri.includes("place:")) { // "最近付けたタグ"と"よく見るページ"は含めない
makeDictionary(folderObj, dicTags, arrFolders);
arrFolders = [];
}
arrFolders = [];
break;
case 2: // folder "text/x-moz-place-container"
arrFolders.push(folderObj.title);
let folders = folderObj.children;
if (folders) {
for (let i = 0; i < folders.length; i++) {
switchByTypecode(folders[i], dicTags, arrFolders); // 再起呼び出し
}
}
arrFolders.pop();
break;
case 3: // "text/x-moz-place-separator"
break;
default:
break;
}
}
makeDictionary()
では、タグがセットされている場合は{name:item, title:jsonObj.title, url:jsonObj.uri, iconurl:jsonObj.iconuri, folder:0}
のようにタグ名、タイトル、URL、アイコンURL(アイコンを表示するためにセット、ブックマークが多い場合アクセスが発生しすぎるので今回はこの機能は未使用にしてあります)、フォルダーフラグをセットします。
switchByTypecode()
でtypeCode
が2の場合はフォルダーなので情報がフォルダー配列にセットしてあります。
この内容で{name:"F-" + item, title:jsonObj.title, url:jsonObj.uri, iconurl:jsonObj.iconuri, folder:1}
のようにフォルダー名(F-付き)、タイトル、URL、アイコンURL、フォルダーフラグをセットします。
// 4.switchByTypecodeから呼び出される。ブックマークファイル(.json)の情報を保持する連想配列(dicTags)を生成する。
function makeDictionary(jsonObj, dicTags, arrFolders) {
g_bookmark_num = g_bookmark_num + 1;
let strTags = jsonObj.tags;
if (strTags) {
let arrTags = strTags.split(",");
arrTags.forEach(function(item){
dicTags.push({name:item, title:jsonObj.title, url:jsonObj.uri, iconurl:jsonObj.iconuri, folder:0});
})
}
// folder tag array があったらタグリストに追加 dicTagsにfolder:0/1を追加する
if (arrFolders.length > 0) {
arrFolders.forEach(function(item){
dicTags.push({name:"F-" + item, title:jsonObj.title, url:jsonObj.uri, iconurl:jsonObj.iconuri, folder:1});
})
}
}
すべてのブックマーク情報をdicTags
に保持したら表示用に並び順をソートします。
makeDictionary()
でセットしたフォルダーフラグでフォルダーを上にタグを下にソートします。
次にタイトル(フォルダー名・タグ名)の昇順にソート、最後にURLの昇順にソートします。
// 取得したタグ辞書をソート
dicTags.sort(function(a, b) {
// フォルダーをタグより上に表示する
let flagA = a.folder;
let flagB = b.folder;
if (flagA < flagB) return 1; // 0より大きい場合、bをaより小さいインデックスにソート
if (flagA > flagB) return -1; // 0未満の場合、aをbより小さいインデックスにソート
// タイトル(フォルダー名・タグ名)の昇順にソートする
let nameA = a.name;
let nameB = b.name;
if (nameA < nameB) return -1;
if (nameA > nameB) return 1;
// URLの昇順にソートする
let urlA = a.url.toUpperCase(); // 大文字と小文字を無視する
let urlB = b.url.toUpperCase(); // 大文字と小文字を無視する
if (urlA < urlB) return -1;
if (urlA > urlB) return 1;
return 0; // 0を返した場合、aとbは互いに変更せず、他のすべての要素に対してソート
});
これでブックマーク情報を表示するためのdicTags
の準備ができました。
次回はブックマーク情報を表示する処理について解説します。
[ソースコードを読むへもどる]