2013年04月01日


Google Chrome 拡張作成入門

最新の情報は以下のリンク先です

マウスカーソル下の画像表示用 HTML コードをクリップボードにコピーする Google Chrome 拡張

▼ 以下はバージョンアップ(仕様変更)の為、動作しません
---------------------------------------------------------

以下のコードは最も簡単でかつ利用価値の高いものです。必要なファイルは、拡張アプリケーションの基本定義である『background.html』と、全体の仕様を定義する『manifest.json』と、アイコンファイルが3つです( アイコンは必ずしも必要ではありません )

以上の5つファイルを任意のディレクトリ内に配置して、Google Chrome から読み込むだけで、拡張機能として実装されて、デバッグも可能になります。もし、世の中に配布したいのであれば、そこからパッケージを作成する事も可能です
background.html(UTF-8N)
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script type="text/javascript">

// *************************************************
// クリップボードへコピー
// *************************************************
function clip_Copy(str) {
	document.getElementById('text').value = str;
	document.getElementById('text').select();
	document.getElementById('text').focus();
	document.execCommand("Copy");
}

// *********************************************************
// 右クリックメニューの処理
// *********************************************************
function active_Action(info, tab) {

	var str = "";

	if ( info.mediaType == 'image' && typeof( info.srcUrl ) !== 'undefined' ) {
		str = '<img src="' + info.srcUrl + '"';
		str += ' style="border: solid 0px #000000" />';
		clip_Copy( str );
		chrome.tabs.executeScript(
			null,
			{ code: "alert('"+str+"');" },
			function() {
			}
		);
	}

}

// *********************************************************
// 初期処理
// *********************************************************
try {
	chrome.contextMenus.removeAll();
}catch(e) {}

// 右クリックメニューを作成
chrome.contextMenus.create(
	{
		"title": "画像HTML取得",
		"contexts":["image"],
		"onclick": active_Action
	}
);
</script>
</head>
<body>
<textarea name="text" id="text"></textarea> 
</body>
</html>

manifest.json
{
   "background_page": "background.html",
   "description": "\u53F3\u30AF\u30EA\u30C3\u30AF\u3088\u308A\u6A19\u6E96\u7684\u306A \u753B\u50CF\u7528HTML \u3092\u53D6\u5F97\u3057\u307E\u3059",
   "icons": {
      "128": "icon128.png",
      "16": "icon16.png",
      "48": "icon48.png"
   },
   "name": "\u753B\u50CFHTML\u53D6\u5F97",
   "permissions": [ "contextMenus", "tabs", "http://*/*", "https://*/*" ],
   "version": "1.0"
}

まず最初にデベロッパーモードのチェックボックスをオンにします。そうすると、読み込み用のボタンが現れるので5つのファイルを配置したフォルダを選択します






ファイルを読み込んだ状態



詳細を表示した状態



background.html のリンクをクリックすると、非表示である background.html 用のデベロッパーツールが開きます( 通常は F12 でひらくもの )

id は、仮の id で、正式に登録されるとGoogle Chrome の環境フォルダ でダウンロードしたスクリプトを実行して、さらに extentions フォルダに入るとその中にあるはずです。

この拡張機能の要点

画像を右クリックすると、コンテキストメニューに登録した機能が表示されて、選択するとその画像を使用した HTML 記述がクリップボードにコピーされます。





クリップボードへのコピー

background.html はもともと非表示なので、コピーするために必要な入力エリアを作成しておいて、データをセットして選択して document.execCommand("Copy"); でコピーします

コンテキストメニューの追加

これは、API の処理なので、まず manifest.json で利用する API を宣言する必要があります。その上で、chrome.contextMenus.removeAll(); で既存のメニューを削除しておいて、chrome.contextMenus.create で作成します。

"contexts":["image"] の記述が、対象が画像のみであることを示しています。他には、 "page", "frame", "selection", "link", "editable", "video", "audio" というようなコンテンツを複数配列で指定する仕様になっています。

実際の処理

クリックすると、定義した function が呼び出されますが、その際に API から引数が渡されて、ある程度の情報をその場で利用する事ができます。この場合は、画像の URL を使って、IMG 要素を完成させています。

1) OnClickData
2) Tab

表示されているページへの通信

セキュリティ上の理由だと思われますが、直接表示しているページへのアクセスは禁じられており、メッセージを送る事によって互いに通信するような仕様になっているようです。

その中で簡単に background から呼び出せる方法がこの、chrome.tabs.executeScript を使った実行です。

この処理はメニューとは別の API 分類になるので、manifest.json で宣言しておく必要があります。

関連する記事

Twitter用埋め込みコードを取得する Google Chrome 拡張


posted by at 2013-04-01 02:24 | Comment(0) | ツール | このブログの読者になる | 更新情報をチェックする

2012年06月19日


既存の Google Chrome 拡張のカスタマイズ( ブラウザのクイックリンク )



この拡張は便利ですし、中身は難しい事を一切やっていないので、ちょっと知識があれば自分でカスタマイズできます。画像の下3つは追加したもので、上の部分も順序を入れ替えています。必要無いエントリは、コードの一番下の div 一列を削除するだけです。

1) Google Chrome の拡張フォルダへ移動
( このスクリプトで開くフォルダの中にある Extentions フォルダが拡張フォルダです )
2) plpjogfhobhpdcmcblieglnoooccfcmm フォルダに入る
3) 1.5_0\popup.html をエディタで開く
4) 以下のコードですべて置き換える
<style> 
body {
  overflow: hidden;
  margin: 0px;
  padding: 0px;
  background: white;
}
 
div:first-child {
  xmargin-top: 0px;
}
 
div {
  cursor: pointer;
  text-align: left;
  padding: 0px;
  
  width: 212px;
  height:38px;
  margin-top: 0px;
  background: #ffffff;
  background-image:url(Blank.png);
  background-position:center center;
  background-repeat:no-repeat;
}
div:hover {
  background-image:url(Hover.png);
}
table 
{
    border-collapse:collapse;
    padding:0;
    margin-left:2px;
    vertical-align:middle;
    font-family: verdana, Arial, Helvetica;
    font-size: 12px;
    font-weight:500;

}
</style> 


<body onload="Localise();">

    <script>
        function getLocal(sID, sDefault) {
            var sRes = chrome.i18n.getMessage(sID);
            if (sRes == "") sRes = sDefault;
            return(sRes);
        }

        function Localise() {
            document.getElementById("tB").innerHTML = getLocal("lbookmarks", "Bookmarks");
            document.getElementById("tH").innerHTML = getLocal("lhistory", "History");
            document.getElementById("tD").innerHTML = getLocal("ldownloads", "Downloads");
            document.getElementById("tE").innerHTML = getLocal("lextensions", "Extensions");
            document.getElementById("tP").innerHTML = getLocal("lplugins", "Plugins");
            document.getElementById("tM").innerHTML = getLocal("lmemory", "Memory");
            document.getElementById("tS").innerHTML = getLocal("lsettings", "Settings");
        }

    
        function xclick(ClickedItem) {
            var Clicked = ClickedItem.id.toString();
            var strURL = "";
            if (Clicked.charAt(0) == "c") {
                strURL = "chrome://";
                strURL += Clicked.substr(1);
                strURL += "/";
            }
            if (Clicked.charAt(0) == "a") {
                strURL = "about:";
                strURL += Clicked.substr(1);
                strURL += "/";
            }
            if (Clicked.charAt(0) == "w") {
                strURL = "http://goo.gl/";
                strURL += Clicked.substr(1);
            }
            chrome.tabs.create({ url: strURL, selected: true });
            window.close();
        }
    </script> 

    <div onclick="xclick(this);" id="csettings"><table><tr><td><img src="iSettings.png" /></td><td id=tS>Settings</td></tr></table></div>
    <div onclick="xclick(this);" id="cdownloads"><table><tr><td><img src="iDownloads.png" /></td><td id=tD>Downloads</td></tr></table></div>
    <div onclick="xclick(this);" id="cbookmarks"><table><tr><td><img src="iBookmarks.png" /></td><td id=tB>Bookmarks</td></tr></table></div>
    <div onclick="xclick(this);" id="chistory"><table><tr><td><img src="iHistory.png" /></td><td id=tH>History</td></tr></table></div>
    <div onclick="xclick(this);" id="cextensions"><table><tr><td><img src="iExtensions.png" /></td><td id=tE>Extensions</td></tr></table></div>
    <div onclick="xclick(this);" id="cplugins"><table><tr><td><img src="iPlugins.png" /></td><td id=tP>Plugins</td></tr></table></div>
    <div onclick="xclick(this);" id="amemory"><table><tr><td><img src="iMemory.png" /></td><td id=tM>Memory</td></tr></table></div> 

    <div onclick="xclick(this);" id="csettings/cookies"><table><tr><td><img src="iSettings.png" /></td><td>Cookies</td></tr></table></div>
    <div onclick="xclick(this);" id="w"><table><tr><td><img src="iBookmarks.png" /></td><td>URL短縮</td></tr></table></div> 
    <div onclick="xclick(this);" id="wg4lFF"><table><tr><td><img src="iBookmarks.png" /></td><td>Google+</td></tr></table></div> 

</body>

どういうわけか、SHIFT_JIS で直接日本語書き込んでいるのに正しく表示されました。
c と a は、chrome:// と about: が対象ですが、新たに http:// を追加しました。id の一文字目を w にして、http://goo.gl/ に続く文字列を w に続けて id にするようにしています。続ける内容は移動したい URLを Google URL 短縮で短縮して作成しています。


posted by at 2012-06-19 22:42 | Comment(0) | ツール | このブログの読者になる | 更新情報をチェックする

2012年05月17日


『Yahoo!24H番組』ボタン(2) / コンボボックス & localStorage 版

ブログに貼りつけるツールとしてコンボボックスを使って、一度選択した地域を localStorage に保存するようにしました。

<style>
#yahoo_bangumi input {
	color: #fff;
	font-weight: bold;
	border-radius: 6px;
	background: -moz-linear-gradient(top, #f00, #333);
	background: -webkit-linear-gradient(top, #f00, #333);
	background: -o-linear-gradient(top, #f00, #333);
	background: linear-gradient(to bottom, #f00, #333);
	-ms-filter: "progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr=#ff0000, endColorstr=#333333)";
}
</style>
<div id="yahoo_bangumi" style='margin-top:0px;'>
<select id="yahoo_area">
<option value="10">北海道(札幌)</option><option value="11">北海道(函館)</option><option value="12">北海道(旭川)</option><option value="13">北海道(帯広)</option><option value="14">北海道(釧路)</option><option value="15">北海道(北見)</option><option value="16">北海道(室蘭)</option><option value="22">青森</option><option value="20">岩手</option><option value="18">秋田</option><option value="19">山形</option><option value="17">宮城</option><option value="21">福島</option><option value="28">栃木</option><option value="25">群馬</option><option value="26">茨城</option><option value="23">東京</option><option value="24">神奈川</option><option value="29">埼玉</option><option value="27">千葉</option><option value="32">山梨</option><option value="31">新潟</option><option value="30">長野</option><option value="34">石川</option><option value="37">富山</option><option value="36">福井</option><option value="35">静岡</option><option value="33">愛知</option><option value="39">岐阜</option><option value="38">三重</option><option value="43">和歌山</option><option value="44">奈良</option><option value="45">滋賀</option><option value="41">京都</option><option value="40">大阪</option><option value="42">兵庫</option><option value="53">徳島</option><option value="51">愛媛</option><option value="54">高知</option><option value="52">香川</option><option value="47">岡山</option><option value="46">広島</option><option value="49">鳥取</option><option value="48">島根</option><option value="50">山口</option><option value="55">福岡</option><option value="61">佐賀</option><option value="56">熊本</option><option value="57">長崎</option><option value="60">大分</option><option value="59">宮崎</option><option value="58">鹿児島</option><option value="62">沖縄</option></select>
<br />
<script type="text/javascript">
(function() {
	var wk = localStorage['yahoo_area'] || '';
	if ( wk != '' ) {
		document.getElementById('yahoo_area').value = wk;
	}
})();
</script>
<input
	type="button"
	value="Yahoo! 24H番組"
	onclick="
(function(){
	localStorage['yahoo_area'] = document.getElementById('yahoo_area').value;
	var url = 'http://tv.yahoo.co.jp/listings/?&type=normal&a='+document.getElementById('yahoo_area').value+'&t=TV&s=1&vb=1&vc=0&vd=0&ve=1&va=24';
	var d = new Date();
	var yyyy = d.getFullYear();
	var mm = (d.getMonth()+1);
	var len1 = ('00'+mm).length;
	mm = ('00'+mm).substr(len1-2,2);
	var dd = d.getDate();
	var len2 = ('00'+dd).length;
	dd = ('00'+dd).substr(len2-2,2);
	var hh = d.getHours() - 2;
	if ( hh <= 1 ) {
		hh = hh + 24;
		dd = d.getDate()-1;
		len2 = ('00'+dd).length;
		dd = ('00'+dd).substr(len2-2,2);
	}
	url += '&d=' + yyyy+mm+dd;
	url += '&st=' + hh;
	window.open(url);
})();
	"
/>
</div>



posted by at 2012-05-17 23:55 | Comment(0) | ツール | このブログの読者になる | 更新情報をチェックする

2012年04月30日


『Yahoo!大阪24H番組』ボタン

2012/4/30 : 24〜3 の間がうまく行ってなかったのを修正しました


最近、WEB から番組をチェックするようになったので、専用のボタンを作成しました。
地域は、大阪が 40 ですが、他は以下のようになります
<input
	type="button"
	value="Yahoo!大阪24H番組"
	onclick="
(function(){
	var url = 'http://tv.yahoo.co.jp/listings/?&type=normal&a=40&t=TV&s=1&vb=1&vc=0&vd=0&ve=1&va=24';
	var d = new Date();
	var yyyy = d.getFullYear();
	var mm = (d.getMonth()+1);
	var len1 = ('00'+mm).length;
	mm = ('00'+mm).substr(len1-2,2);
	var dd = d.getDate();
	var len2 = ('00'+dd).length;
	dd = ('00'+dd).substr(len2-2,2);
	var hh = d.getHours() - 2;
	if ( hh <= 1 ) {
		hh = hh + 24;
		dd = d.getDate()-1;
		len2 = ('00'+dd).length;
		dd = ('00'+dd).substr(len2-2,2);
	}
	url += '&d=' + yyyy+mm+dd;
	url += '&st=' + hh;
	window.open(url);
})();
	"
/>
この下はさらに、ボタン画像を使ったものです。


<style type="text/css">
.bt {
	border: 0px;
	width: 180px;
	height: 30px;
	text-align: left;
	padding-left: 32px;
	font-size:13px; 
	font-weight: bold;
	cursor: pointer;
	background-color: #fff;
	margin: 4px 4px 4px 4px;
}
</style>
<input
	class="bt"
	type="button"
	value="Yahoo!東京24H番組"
 	style='background-image: url(https://lh6.googleusercontent.com/-dZnazzvnzCw/T5FN4nTSUrI/AAAAAAAAFnQ/JMTzwUr7CDk/s180/btn049_06.png);'
	onclick="
(function(){
	var url = 'http://tv.yahoo.co.jp/listings/?&type=normal&a=23&t=TV&s=1&vb=1&vc=0&vd=0&ve=1&va=24';
	var d = new Date();
	var yyyy = d.getFullYear();
	var mm = (d.getMonth()+1);
	var len1 = ('00'+mm).length;
	mm = ('00'+mm).substr(len1-2,2);
	var dd = d.getDate();
	var len2 = ('00'+dd).length;
	dd = ('00'+dd).substr(len2-2,2);
	var hh = d.getHours() - 2;
	if ( hh <= 1 ) {
		hh = hh + 24;
		dd = d.getDate()-1;
		len2 = ('00'+dd).length;
		dd = ('00'+dd).substr(len2-2,2);
	}
	url += '&d=' + yyyy+mm+dd;
	url += '&st=' + hh;
	window.open(url);
})();
	"
/>

▼ボタン画像
WEBデザイナーが作った超シンプル素材集
posted by at 2012-04-30 14:29 | Comment(0) | ツール | このブログの読者になる | 更新情報をチェックする

2012年02月01日


Twitter用埋め込みコードを取得する Google Chrome 拡張

▼ Google Chrome で以下をクリックして下さい(ダウンロードして、Chrome にドラッグ&ドロップでも OK )
http://winofsql.jp/download/twitter_get_embed.crx



IE と Firefox で作ったものとほぼ同等の機能を Chrome の 拡張で実装しました。
IE と Firefox はかなり作り込んだ経験を持ってますが、Chrome の拡張は手強か
ったです。特に、直接 WEB ページ上のオブシェクトを操作できないので、Flex の
ようなイベントの連鎖で作業を書いていかないといけないので大変でした。

でも、おかげでいろいろノウハウも手に入ったので解説するのが楽しみです。

ダウンロードして、拡張子を .zip に変更して解凍してサンプルとして見た
ほうが早いとは思いますが、さすがにソースコードだけでは理解不能な部分
が多いです。Google のドキュメントを見ながらですらやっとの思いで完成
させましたし( 実際バグっぽい部分の対症療法も残っていますし )

この処理に特に必要は無かったのですが、サンプルとして使いたかったので、
WEBページと拡張の対話のバリエーションも組み込んであります。マニフェス
トファイルの内容が重要になるので、ドキュメントの参照は必要です。

機能実装の必要から、別ドメイン間のデータ交換テクニックである、メッセ
ージのポストと、ローカルストレージの利用はおすすめです。

1) 右クリックのポップアップメニュー( リンクのみのメニュー )
2) メニューから一旦 WEB 上に組み込んだ関数を呼び出す(強制呼び出し)
3) WEB ページの情報を取得して、再び拡張を呼び返す(送信)
4) 受信してからモーダルダイアログ(実際はモーダルにはならない)を開く
5) XMLHttpRequest で Twitter API を呼び出してデータを取得
6) クリップボードにコピー
7) 別ドメインのページをデータ交換してから呼び出す




関連する記事

Twitter用埋め込みコードを取得する IE拡張
Twitter用埋め込みコードを取得する Firefox アドオン



posted by at 2012-02-01 00:26 | Comment(0) | ツール | このブログの読者になる | 更新情報をチェックする
Seesaa の各ページの表示について
Seesaa の 記事がたまに全く表示されない場合があります。その場合は、設定> 詳細設定> ブログ設定 で 最新の情報に更新の『実行ボタン』で記事やアーカイブが最新にビルドされます。

Seesaa のページで、アーカイブとタグページは要注意です。タグページはコンテンツが全く無い状態になりますし、アーカイブページも歯抜けページはコンテンツが存在しないのにページが表示されてしまいます。

また、カテゴリページもそういう意味では完全ではありません。『カテゴリID-番号』というフォーマットで表示されるページですが、実際存在するより大きな番号でも表示されてしまいます。

※ インデックスページのみ、実際の記事数を超えたページを指定しても最後のページが表示されるようです

対処としては、このようなヘルプ的な情報を固定でページの最後に表示するようにするといいでしょう。具体的には、メインの記事コンテンツの下に『自由形式』を追加し、アーカイブとカテゴリページでのみ表示するように設定し、コンテンツを用意するといいと思います。


※ エキスパートモードで表示しています

アーカイブとカテゴリページはこのように簡単に設定できますが、タグページは HTML 設定を直接変更して、以下の『タグページでのみ表示される内容』の記述方法で設定する必要があります

<% if:page_name eq 'archive' -%>
アーカイブページでのみ表示される内容
<% /if %>

<% if:page_name eq 'category' -%>
カテゴリページでのみ表示される内容
<% /if %>

<% if:page_name eq 'tag' -%>
タグページでのみ表示される内容
<% /if %>
この記述は、以下の場所で使用します