ミライハック
  • Home
  • Categories
  • About

>> Home / インターネット

FirefoxアドオンとChrome拡張機能

∵ Takayoshi Saito ∴ 2015-08-07 ∞ 1'

アドオン開発について

今回はAdmatrix AnalyticsというChromeとFirefoxに関連した拡張機能・アドオンを採り上げます。SEOアナライザのような拡張機能で、サイトのSEOの内部対策を行っていくために必要な情報を抽出するアドオンです。

アドオンのスクリプトは操作すれば誰でも見られるようになっていますので、ここで一挙に公開いたします。

Google Chrome側の開発

Google Chromeで開発した拡張機能用のJavaScripyは以下のようになっています。

var page_mod = require("sdk/page-mod");
const {Cc, Ci} = require('chrome');
var request = require("sdk/request");
var widgets = require("sdk/widget");
var tabs = require("sdk/tabs");
var data = require("sdk/self").data;
var self = require("sdk/self");
var ss = require("sdk/simple-storage").storage;
ss['AdmatrixStatus'] = 'open';
var id = '0';
var mediator = Cc['@mozilla.org/appshell/window-mediator;1'].getService(Ci.nsIWindowMediator);
 
// exports.main is called when extension is installed or re-enabled
exports.main = function(options, callbacks) {
    addToolbarButton();
};
 
// exports.onUnload is called when Firefox starts and when the extension is disabled or uninstalled
exports.onUnload = function(reason) {
    removeToolbarButton();
};
 
// add our button
function addToolbarButton() {
    // this document is an XUL document
    var document = mediator.getMostRecentWindow('navigator:browser').document;      
    var navBar = document.getElementById('nav-bar');
    var btn = document.createElement('toolbarbutton');  
    if (!navBar) {
        return;
    }
    var popup = require("sdk/panel").Panel({
      width: 180,
      height: 120,
      position: {top:0,right:0},
      contentURL: data.url("panel.html"),
      contentScriptFile: 
    });
    popup.on("show", function() {
        if(ss['AdmatrixStatus']){
            status = ss['AdmatrixStatus'];
        };
        popup.port.emit("show",status);
    });

    popup.port.on("toggle", function () {
        status = ss['AdmatrixStatus'];
        worker = tabs.activeTab.attach({
            contentScriptFile: 
        });
        if(status == 'close'){
            // close -> open
            worker.port.emit("inject",id);
            ss['AdmatrixStatus'] = 'open';
            popup.port.emit("btn",'close');
            btn.setAttribute('image', data.url('images/icon/19.png'));
        }else{
            // open -> close
            worker.port.emit("remove");
            ss['AdmatrixStatus'] = 'close';
            popup.port.emit("btn",'open');
            btn.setAttribute('image', data.url('images/icon/19_off.png'));
        }
    });
    btn.setAttribute('id', 'mybutton-id');
    btn.setAttribute('type', 'button');
    // the toolbarbutton-1 class makes it look like a traditional button
    btn.setAttribute('class', 'toolbarbutton-1');
    // the data.url is relative to the data folder
    btn.setAttribute('image', data.url('images/icon/19.png'));
    btn.setAttribute('orient', 'horizontal');
    // this text will be shown when the toolbar is set to text or text and iconss
    btn.setAttribute('label', 'My Button');
    btn.addEventListener('click', function() {
        popup.show();
        status = ss['AdmatrixStatus'];
        worker = tabs.activeTab.attach({
            contentScriptFile: 
        });
        //popup.port.emit("show",status);
        if(status == 'close'){
            worker.port.emit("inject",id);
            ss['AdmatrixStatus'] = 'open';
            btn.setAttribute('image', data.url('images/icon/19.png'));
        }else{
            worker.port.emit("remove");
            ss['AdmatrixStatus'] = 'close';
            btn.setAttribute('image', data.url('images/icon/19_off.png'));
        }
        // do stuff, for example with tabs or pageMod
    }, false)
    navBar.appendChild(btn);
}
function removeToolbarButton() { 
    var enumerator = mediator.getEnumerator("navigator:browser"); 
    while(enumerator.hasMoreElements()) { 
        var document = enumerator.getNext().document; 
        var navBar = document.getElementById('nav-bar'); 
        var btn = document.getElementById('mybutton-id'); 
        if (navBar && btn) { 
            navBar.removeChild(btn); 
        } 
    } 
}

initPageMod();

function initPageMod()
{
    myPageMod = page_mod.PageMod({
        include: ['*'],
        contentScriptWhen: "end",
        contentScriptFile: ,
        attachTo: ["top"],
        onAttach: function(worker) {
            if(ss['AdmatrixId']){
                id = ss['AdmatrixId'];
            }else{
                
            }
            if(ss['AdmatrixStatus'] == 'open'){
                request.Request({
                    url : "https://seo-analytics.fs-site.net/1.0.0/"+ id +"/createUser.php",
                    content:{
                        loaded_url:worker.url
                    },
                    onComplete : function(response){
                        id = JSON.parse(response.text).id;
                        ss['AdmatrixId'] = id;
                        worker.port.emit("inject",id);
                    }
                }).get();
            }
        }
    });
}

Firefoxのアドオン開発

var page_mod = require("sdk/page-mod");
const {Cc, Ci} = require('chrome');
var request = require("sdk/request");
var widgets = require("sdk/widget");
var tabs = require("sdk/tabs");
var data = require("sdk/self").data;
var self = require("sdk/self");
var ss = require("sdk/simple-storage").storage;
var prefs = require('sdk/simple-prefs');
var mediator = Cc['@mozilla.org/appshell/window-mediator;1'].getService(Ci.nsIWindowMediator);
 
// exports.main is called when extension is installed or re-enabled
exports.main = function(options, callbacks) {
    addToolbarButton();
    initPageMod();
    makeOptions();
};
 
// exports.onUnload is called when Firefox starts and when the extension is disabled or uninstalled
exports.onUnload = function(reason) {
    removeToolbarButton();
};
function getExceptions(url) {
    if(!exceptions_enable) {
        return false;
    }
    var domainLabels = url.split('/')[2].split(':')[0].split('.').reverse();
    var loadedExceptions = ss['exceptions'];
    loadedExceptions = (loadedExceptions == null) ? [] : loadedExceptions.split(/\t/);
    var len = loadedExceptions.length;
    for (var i=0; i open
            ss['AdmatrixStatus'] = 'open';
            popup.port.emit("btn",'close');
            btn.setAttribute('image', data.url('images/icon/19.png'));
            for each (var tab in tabs) {
                worker = tab.attach({
                    contentScriptFile: 
                });
                worker.port.on('save-state', function(state) {
                    ss['state' + worker.tab.id] = state;
                });
                inject(worker);
            }
        }else{
            // open -> close
            ss['AdmatrixStatus'] = 'close';
            popup.port.emit("btn",'open');
            btn.setAttribute('image', data.url('images/icon/19_off.png'));
            for each (var tab in tabs) {
                worker = tab.attach({
                    contentScriptFile: 
                });
                worker.port.emit("remove");
            }
        }
    });
    btn.setAttribute('id', 'mybutton-id');
    btn.setAttribute('type', 'button');
    // the toolbarbutton-1 class makes it look like a traditional button
    btn.setAttribute('class', 'toolbarbutton-1');
    // the data.url is relative to the data folder
    if(ss['AdmatrixStatus'] == 'open' || ss['AdmatrixStatus'] == null){
        btn.setAttribute('image', data.url('images/icon/19.png'));
    } else {
        btn.setAttribute('image', data.url('images/icon/19_off.png'));
    }
    //2回目以降の起動でアップデートが検知されたらアイコンをオンにする
    if(ss['AdmatrixId'] != null && ss['addon-version'] != self.version) {
        btn.setAttribute('image', data.url('images/icon/19.png'));
    }
    btn.setAttribute('orient', 'horizontal');
    // this text will be shown when the toolbar is set to text or text and iconss
    btn.setAttribute('label', 'My Button');
    btn.addEventListener('click', function() {
        popup.show();
        status = ss['AdmatrixStatus'];
        //popup.port.emit("show",status);
        if(status == 'close'){
            ss['AdmatrixStatus'] = 'open';
            btn.setAttribute('image', data.url('images/icon/19.png'));
            for each (var tab in tabs) {
                worker = tab.attach({
                    contentScriptFile: 
                });
                worker.port.on('save-state', function(state) {
                    ss['state' + worker.tab.id] = state;
                });
                inject(worker);
            }
        } else {
            ss['AdmatrixStatus'] = 'close';
            btn.setAttribute('image', data.url('images/icon/19_off.png'));
            for each (var tab in tabs) {
                worker = tab.attach({
                    contentScriptFile: 
                });
                worker.port.emit("remove");
            }
        }
        // do stuff, for example with tabs or pageMod
    }, false)
    navBar.appendChild(btn);
}
function removeToolbarButton() { 
    var enumerator = mediator.getEnumerator("navigator:browser"); 
    while(enumerator.hasMoreElements()) { 
        var document = enumerator.getNext().document; 
        var navBar = document.getElementById('nav-bar'); 
        var btn = document.getElementById('mybutton-id'); 
        if (navBar && btn) { 
            navBar.removeChild(btn); 
        } 
    } 
}
function initPageMod()
{
    myPageMod = page_mod.PageMod({
        include: ['*'],
        contentScriptWhen: "end",
        contentScriptFile: ,
        attachTo: ["top"],
        onAttach: function(worker) {
            //各tabが閉じられたら該当するストレージを削除するイベントハンドラ
            worker.tab.on("close", function() {
                delete ss['state' + worker.tab.id];
            });
            //stateの保存用のイベントハンドラ
            worker.port.on('save-state', function(state) {
                ss['state' + worker.tab.id] = state;
            })
            //tabごとのストレージがなかったら初期値を設定する
            if(ss['state' + worker.tab.id] == null) {
                ss['state' + worker.tab.id] = {"height" : "380", "minimize" : "open", "title" : "on"};
            }
            update = versionCheck();
            //アップデートが検知されたらアップデート用の設定にする
            if(update) {
                ss['state' + worker.tab.id] = {"height" : "380", "minimize" : "close", "title" : "on"};
            }
            if(ss['AdmatrixId']){
                id = ss['AdmatrixId'];
            } else {
                id = 'idIsNotStored';
            }
            request.Request({
                url : "https://seo-analytics.fs-site.net/1.0.0/"+ id +"/createUser.php",
                onComplete : function(response){
                    ss['AdmatrixId'] = JSON.parse(response.text)['id'];
                    token = JSON.parse(response.text)['token'];
                    script_version = JSON.parse(response.text)['script-version'];
                    title_view_enable = JSON.parse(response.text)['title-view-enable'];
                    exceptions_enable = JSON.parse(response.text)['exceptions-enable'];
                    inject(worker);
                }
            }).get();
        }
    });
}
function inject(worker) {
    if(ss['AdmatrixStatus'] == 'open' && !getExceptions(worker.url)){
        worker.port.emit("inject",{
        "AdmatrixId" : ss['AdmatrixId'],
        "token" : token,
        "script_version" : script_version,
        "addon_version" : ss['addon-version'],
        "title_view_enable" : title_view_enable,
        "exceptions_enable" : exceptions_enable,
        "state" : ss['state' + worker.tab.id],
        "update" : update
        });
    }
}
Search

Categories
  • LInux
  • インターネット
  • インフラ
  • エッセイ
  • ゲーム
  • システム開発
  • セキュリティ
  • データサイエンス
  • 国際関係
  • 政治
  • 歴史
  • 社会学
  • 自己紹介
  • 行ってきた

Pages
  • 齊藤貴義
  • 職務経歴
  • スクレイピング・ハッキング・ラボ サポートページ
  • 『爆速開発を支えるClaude Code上級者テクニック』サポートページ

2026 © Takayoshi Saito | Twitter GitHub | Built on Zola