C-MOON

主にプログラミング勉強中のメモを書いていきます。

【Firefox】拡張機能のパッケージ化・署名・インストール

以前の記事で、Firefox拡張機能を作成し、ローカル環境でテストを行いました。

thenewsinpu.hatenablog.jp

今回は、拡張機能のパッケージ化・署名を行い、自身のブラウザにインストールしてみたいと思います。

1. パッケージ化

以下のページを参考に、拡張機能のパッケージ化を行います。

developer.mozilla.org
と言っても、パッケージ化は拡張機能に必要なファイルをすべて選択し、zip化するだけです。
今回は、以下の2ファイルです。

manifest.json
{
    "name": "KakomonDontOpacity",
    "description" : "過去問道場で解説が透明になるのを防ぎます。",
    "version": "1.0",
    "manifest_version": 2,
    "content_scripts":[
        {
        "matches":["*://www.ap-siken.com/*", "*://www.db-siken.com/*", "*://www.nw-siken.com/*"],
        "js":["kakomon_dont_opacity.js"]
        }
    ]
}
kakomon_dont_opacity.js
var ads = document.getElementsByClassName('adsbygoogle');

for (var i = 0; i < ads.length; i++){
ads[i].innerHTML = 'abc';
}


二つのファイルをzip形式で圧縮します。
f:id:thenewsinpu:20180508003108p:plain

2. 署名

拡張機能をインストール可能にするために、Mozillaによって署名を施す必要があります。
以下のページを参考にします。

developer.mozilla.org

赤枠のリンクをクリックします。
f:id:thenewsinpu:20180514230117p:plain

firefoxへのログインを求められるので、ログインします。
アカウントがない場合は新規作成します。

ログインすると、以下のページに移動します。
f:id:thenewsinpu:20180514230434p:plain
今回は投稿を行わないので、「自分自身で。」を選択し、続けるをクリックします。

次のページで、先ほど作成したzipファイルを選択します。
f:id:thenewsinpu:20180514231230p:plain

エラーや警告が無いことを確認して、「アドオンの署名」を行います。
f:id:thenewsinpu:20180517223229p:plain

アドオンの署名が完了しました。〜〜.xpiファイルが、署名されたアドオンファイルです。
「〜〜.xpiをダウンロード」ボタンでダウンロードします。
f:id:thenewsinpu:20180514231856p:plain

3. インストール

Firefoxのアドオンマネージャを開きます。
ダウンロードした〜〜.xpiファイルを下図のようにドラッグ&ドロップします。
f:id:thenewsinpu:20180514232920p:plain

拡張機能として登録されました。
f:id:thenewsinpu:20180514233315p:plain

4. 動作確認

応用情報技術者試験 過去問道場のページを開きます。
コンテンツブロッカーを使用しても、解説が非表示(半透明化)されていないことを確認します。

デバッガを使用すると、作成した拡張機能が動作しているのが確認できます。
f:id:thenewsinpu:20180517225646p:plain

今回は以上です。

【Javascript】情報技術者試験 過去問道場で解説が表示されない原因2

以前の記事で、過去問道場で解説が表示されない(半透明になる)原因を調べましたが、今月(2018年5月)に入り、解説を半透明化する条件が変更されたようです。

thenewsinpu.hatenablog.jp



条件式の比較

以前(2018年4月29日時点)のソースは以下の通りです。

if ($('.ansbg').length == 2 && Math.random() > 0.2){
    setTimeout(function(){
        var ad = $('ins.adsbygoogle')[0];
        if (ad && ad.innerHTML.replace(/\s/g , "").length === 0) {
            $('.ansbg').last().attr('style', 'opacity:.05 !important').before("<p>※解説へのアクセスはアプリやプラグインなどの拡張機能によって制限されています。</p>");
        }
    }, 2000);
}


現在のソースは以下の通りです。

if ($('.ansbg').length === 2 && Math.random() > 0.2){
    setTimeout(function(){
        var ad = $('ins.adsbygoogle').show();
        if (ad[0]) {
            ad.each(function(){
                if (!$(this).html()) {
                    $('.ansbg').last().attr('style', 'opacity:.05 !important').before("<p>※解説へのアクセスはアプリやプラグインなどの拡張機能によって制限されています。</p>");
                    return false;
                }
            });
        }
    }, 2000);
}


ins.adsbygoogleクラスの要素が広告部分で、コンテンツブロッカーを使用するとこの要素内が空になります。条件式if (!$(this).html())は要素が空かどうかを判定しています。
以前のソースはins.adsbygoogleクラスの最初の要素しかチェックしていませんでしたが、現在のソースではすべてのins.adsbygoogleクラスの要素をチェックしています。

半透明化を防ぐ拡張機能の改良

前回の記事で作成した拡張機能は、「適当な文字を入れたinsタグでadsbygoogleクラスの要素」をbodyタグ先頭に追加する処理を行っていましたが、上記の通り、すべてのins.adsbygoogleクラスの要素の文字数をチェックされてしまうため、半透明化を防げなくなりました。

現在の半透明化条件式に対応するため、拡張機能のソースを改良します。

参考までに、改良前のソースです(ファイル名:kakomon_dont_opacity.js)。

var insertText = '<ins class="adsbygoogle">abc</ins>';
document.body.insertAdjacentHTML('afterbegin', insertText);



このソースを以下のように変更します。

var ads = document.getElementsByClassName('adsbygoogle');

for (var i = 0; i < ads.length; i++){
    ads[i].innerHTML = 'abc';
}

改良後のソースは、ページ内すべてのins.adsbygoogleクラスの要素に適当な文字列*1を挿入します。
これにより、空のins.adsbygoogleクラスの要素は無くなるので、半透明化処理は行われないはずです。

拡張機能の動作確認

Firefoxのデバッガーを使用し、半透明化の条件式に入らないこと、解説がきちんと表示されることを確認しました。
f:id:thenewsinpu:20180516233057p:plain

今回は以上です。

*1:コンテンツブロッカーを使用していれば、ins.adsbygoogleクラスの要素は非表示になるので、文字列がページに表示されることはありません。

情報技術者試験 過去問道場で解説が半透明になるのを防ぐ拡張機能

前回、 応用情報技術者過去問道場|応用情報技術者試験.com で解説が半透明になり見えにくくなる問題の原因を調査しました。

thenewsinpu.hatenablog.jp



今回は、解説が透明になるのを防ぐブラウザ拡張機能(アドオン)を開発してみます。

開発は、Firefoxで行います。

拡張機能の開発は以下のページを参考に行います。

developer.mozilla.org

1. ディレクトリの作成

任意の場所に任意の名前のディレクトリを作成します。

今回は、デスクトップに「KakomonDontOpacity」という名前のディレクトリを作成しました。

2. manifest.jsonを作成

作成したディレクトリ「KakomonDontOpacity」内に「manifest.json」ファイルを作成し、以下のように記述します。

{
    "name": "KakomonDontOpacity",
    "description" : "過去問道場で解説が透明になるのを防ぎます。",
    "version": "1.0",
    "manifest_version": 2,
    "content_scripts":[
        {
        "matches":["*://www.ap-siken.com/*", "*://www.db-siken.com/*", "*://www.nw-siken.com/*"],
        "js":["kakomon_dont_opacity.js"]
        }
    ]
}


"content_scripts"配列内の"matches"では、対象となるURLを選択できます。
今回は、「応用情報技術者試験.com」「データベーススペシャリスト.com」「ネットワークスペシャリスト.com」を指定しました。

3. kakomon_dont_opacity.jsの作成

ディレクトリ「KakomonDontOpacity」内に「kakomon_dont_opacity.js」ファイルを作成し、以下のように記述します。

var insertText = '<ins class="adsbygoogle">abc</ins>';
document.body.insertAdjacentHTML('afterbegin', insertText);


前回の記事で調査した通り、情報技術者試験 過去問道場ではinsタグでadsbygoogleクラスの1つ目の要素の文字数が0のとき解説を半透明にする処理を行っていました。

「適当な文字を入れたinsタグでadsbygoogleクラスの要素」をbodyタグ先頭に追加すれば、上記条件に引っかからなくなります。

【2018/05/16 追記】
過去問道場の半透明化処理の条件式が変更されていました。
上記処理では半透明化を防げません。
以下のソースに変更してください。
詳細はこちら

var ads = document.getElementsByClassName('adsbygoogle');

for (var i = 0; i < ads.length; i++){
    ads[i].innerHTML = 'abc';
}

4. インストール

"about:debugging" を Firefox で開いたら "一時的なアドオンを読み込む" をクリックし、アドオンのディレクトリにあるファイルをどれか 1 つ選択します。

5. テスト

μBlock等のコンテンツブロッカーを有効にします。
次に、応用情報技術者過去問道場|応用情報技術者試験.com にアクセスし、解説を表示させます。
解説が透明になっていなければ、成功です。
f:id:thenewsinpu:20180507005323p:plain

今回は以上です。

【Javascript】情報技術者試験 過去問道場で解説が表示されない原因

応用情報技術者試験の勉強で応用情報技術者過去問道場|応用情報技術者試験.comを利用していますが、問題を解いた後、解説が表示されない(厳密にはうっすら見えてる)状態になります。
f:id:thenewsinpu:20180428224423p:plain

原因

ページに「※解説へのアクセスはアプリやプラグインなどの拡張機能によって制限されています。」と書かれているので解るのですが、一応ヘルプページを見ます。

過去問道場の使い方・各機能について|応用情報技術者試験.comによると、

過去問道場(PC版、スマホ版)では、広告ブロックのプラグイン等を使用している場合に解説部分が広告と一緒に非表示になる仕組みを取り入れているため、それが影響している可能性があります。

広告をブロックすると解説を表示させない仕組みのようです。

確かに、私はコンテンツブロッカー「μBlock Origin」を使用していおり、サイトをホワイトリストに追加することで解説が表示されました。

コンテンツブロッカー使用で解説が非表示になる仕組み

応用情報技術者」を目指すものとしては、コンテンツブロッカー使用で解説が非表示になる仕組みがどのようなっているのか気になるので、調べることにしました。

サイトのJavascriptを確認

解説を消し、「※解説へのアクセスはアプリやプラグインなどの拡張機能によって制限されています。」という一文を表示させる処理を行っているのはサーバ(PHP等)でしょうか?ブラウザ(Javascript)でしょうか?

コンテンツブロックはブラウザ側の処理なので、解説を消す/消さないの判断もブラウザ(Javascript)で行う必要があるはずです。

さっそく、サイトのソースを表示し、Javascriptを確認します。
私の環境がFirefoxなので、Firefoxで説明します。
ブラウザでF12を押し、開発ツールを表示します。
f:id:thenewsinpu:20180428233123p:plain
デバッガーのタブを選び、Ctrl(⌘)+Shift+F で「解説へのアクセス」を検索します。すると、以下のように、該当箇所がヒットします。
f:id:thenewsinpu:20180428233942p:plain なぜか二つ表示されますが、両方同じです。

該当箇所を抜粋しました。

if ($('.ansbg').length == 2 && Math.random() > 0.2){
    setTimeout(function(){
        var ad = $('ins.adsbygoogle')[0];
        if (ad && ad.innerHTML.replace(/\s/g , "").length === 0) {
            $('.ansbg').last().attr('style', 'opacity:.05 !important').before("<p>※解説へのアクセスはアプリやプラグインなどの拡張機能によって制限されています。</p>");
        }
    }, 2000);
}

HTMLを確認すると、ansbgは問題文と解説タグのクラスで、広告はinsタグadsbygoogleクラスの要素です。
抜粋したソースの上から4行目を見ると、'ins.adsbygoogle'要素の子要素の文字数が0の場合、解説を消す処理を行っています。(不透明度0.5に設定)

確かに、広告をブロックすると、'ins.adsbygoogle'要素の子要素がなくなります。
子要素が無い(文字数が0)ことを検知して、解説を消していたわけです。

・コンテンツブロック無し f:id:thenewsinpu:20180428235700p:plain
・コンテンツブロック有り f:id:thenewsinpu:20180428235724p:plain

【2018/05/16 追記】
過去問道場の半透明化処理の条件式が変更されていました。
詳細は以下ページを参照してください。
thenewsinpu.hatenablog.jp 【追記 ここまで】

まとめ

情報技術者試験 過去問道場で解説が表示されない原因(解説を消す処理の仕組み)を知ることができました。
もし、コンテンツブロッカーを使用したまま解説を表示させたいと考えた時、仕組みがわかれば方法を思いつくことができます。
例えば、解説を消す処理は、ifで複数の条件を満たす必要があります。
この条件に必ず当てはまらなくなるようにすれば、解説が消されることはありません。

今回は以上です。

【VSCode】ヘッダファイルの言語設定をワークスペースごとに行う

C言語のヘッダファイル(~.h)をC言語として認識させる方法です。 Java等、他の言語のワークスペースに影響が出ないよう、ワークスペースの設定を変更します。

  1. ファイル→基本設定→設定で設定の編集画面を開く。
    (macOSの場合、Code→基本設定→設定)

  2. ワークスペースの設定」タブに切り替える。 f:id:thenewsinpu:20180426234331p:plain

  3. 以下を{}内に追加する。

"files.associations": {
"*.h": "c"
}

f:id:thenewsinpu:20180426234600p:plain
ヘッダファイルもC言語として扱われるようになります。

以上です。

【Javascript】月の加算・減算は月末に注意【Date()】

前回の記事

【C#, JS】 今年度を取得する - C-MOON

でDateオブジェクトの関数を利用した日付の減算を行いました。

// 現在から3ヶ月前にセット
date.setMonth(date.getMonth() - 3);


ここで、一つ疑問が湧きました。
「5月30日の1ヶ月前は4月30日だけど、5月31日はの1ヶ月前は何月何日になるのか?」

4月31日は存在しないので、月末の4月30日になるのでしょうか?

実際に試すことのできるプログラムを作成しました。
※日付入力欄はyyyy-mm-dd形式で入力します。存在しない日付はエラーになります。
※使用ブラウザがchromefirefoxの場合カレンダーが表示され、日付を選択できます。


月の引き算を行うサンプル


ヶ月前は...

です。



結果

実行結果を見てみると、5月31日の1ヶ月前は5月1日になります。
4月31日=4月30日+1日 → 5月1日ということでしょう。
同様に、5月31日の3ヶ月前は
2月31日=2月28日+3日 → 3月3日となります。(閏年でない場合)

ソースコード

最後にソースコードを貼っておきます。
html部分

<dev style="line-height: 200%;">
<input type="date" id="inputDate"><br>
<input type="number" id="subMonth" value="3" max="99" min="0" style="width: 3em"> ヶ月前は...<br>
<input type="button" value="計算する" onclick="calcDate();">
<p> 
    <div id="outputDate"></div> です。
</p>
</dev>

javascript部分

<script>
    var nowDate = new Date();

    var yyyy = nowDate.getFullYear();
    var mm = ("0"+(nowDate.getMonth()+1)).slice(-2);
    var dd = ("0"+nowDate.getDate()).slice(-2);

    // 日付入力欄の初期値をセット(今日の日付)
    var inputElem = document.getElementById("inputDate");
    inputElem.value=yyyy+'-'+mm+'-'+dd;

    // 結果の初期値をセット
    calcDate();

    // 日付の引き算をして、表示する関数
    function calcDate(){
        var outputElem = document.getElementById("outputDate");
        var outputDate = new Date(inputElem.value);
        var subMonth = document.getElementById("subMonth").value;

        // 入力した月を減算
        outputDate.setMonth(outputDate.getMonth() - subMonth);
        // yyyy/mm/dd 形式で表示
        outputElem.innerText = outputDate.toLocaleDateString();
    };
</script>


今回は以上です。

【C#, JS】 今年度を取得する

今年度を求めるプログラムを作りたいと思います。

今年度とは、今年4月から来年の3月までのことを言います。
求める方法は色々あると思いますが、C#Javascriptのような日付のクラスや関数が用意されている言語であれば、次の方法が簡単だと思います。

年度 = 今月の3ヶ月前の年

例えば、2018年3月31日の3ヶ月前は2017年12月31日なので「2017年度」、2018年4月1日の3ヶ月前は2018年1月1日なので「2018年度」となります。

C#ソースコードは次のようになります。

int Nendo = (DateTime.Today.AddMonths(-3)).Year;

Javascriptでも方法は同じです。

<script>
    var date = new Date();

    document.write(date.getFullYear() + "年" + (date.getMonth() + 1) + "月" + date.getDate() + "日は、");

    // 現在から3ヶ月前にセット
    date.setMonth(date.getMonth() - 3);
    // 今年度を表示
    document.write(date.getFullYear());
</script>

Javascriptソースコードを、ページの一番下に埋め込んでいます。
今日の日付と、今年度が表示されていると思います。
↓↓↓

↑↑↑

以上です。