{
    "componentChunkName": "component---src-templates-blog-post-jsx",
    "path": "/post/how-to-extend-chatwork-in-google-chrome/",
    "result": {"data":{"site":{"siteMetadata":{"title":"WEB EGG","author":"Leko - CTO at Yuimedi"}},"markdownRemark":{"id":"5b7c9163-be4d-520e-81e2-116623cf8629","excerpt":"こんにちは。 とても今更ながら、Chrome 拡張機能が HTML と CSS と js で作れるらしいので、作ってみました。 よくあるサンプルの、「ただ alert 出すだけ」だと芸がないので、 web 版の ChatWork を改造しつつ、拡張機能について学んだメモです。 注意 この記事を執筆したのは 201…","html":"<p>こんにちは。<br>\nとても今更ながら、Chrome 拡張機能が HTML と CSS と js で作れるらしいので、作ってみました。</p>\n<p>よくあるサンプルの、「ただ alert 出すだけ」だと芸がないので、<br>\nweb 版の ChatWork を改造しつつ、拡張機能について学んだメモです。</p>\n<!--more-->\n<h2 id=\"注意\" style=\"position:relative;\"><a href=\"#%E6%B3%A8%E6%84%8F\" aria-label=\"注意 permalink\" class=\"autolink-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>注意</h2>\n<p>この記事を執筆したのは 2014/07/20 です。</p>\n<p>ChatWork の HTML 構造に激しく依存するため、<br>\nHTML や js の回収があった場合には動作しなくなる可能性が非常に高いです。<br>\n情報が古くなり動かなくなる可能性があることを、あらかじめご了承ください。</p>\n<h2 id=\"制作するもの\" style=\"position:relative;\"><a href=\"#%E5%88%B6%E4%BD%9C%E3%81%99%E3%82%8B%E3%82%82%E3%81%AE\" aria-label=\"制作するもの permalink\" class=\"autolink-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>制作するもの</h2>\n<p><a href=\"http://namuol.github.io/cheet.js/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">コナミコマンドを実装する js</a>を利用して、</p>\n<p>ChatWork のページ内で、<br>\n<strong>コナミコマンド（↑↑↓↓←→←→ba）が入力されたら、マイチャットにグラディウスの AA を投稿する</strong></p>\n<p>というしょうもない小ネタをやってみたいと思います。<br>\nちなみに完成した物は<span class=\"removed_link\" title=\"https://github.com/Leko/chrome-ext-gradius\">こちら</span>になります。</p>\n<h2 id=\"前提\" style=\"position:relative;\"><a href=\"#%E5%89%8D%E6%8F%90\" aria-label=\"前提 permalink\" class=\"autolink-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>前提</h2>\n<p>ライブラリの導入に bower を使用します。<br>\nインストールされている前提で話を進めます。ご了承下さい。</p>\n<h2 id=\"まずは-alert\" style=\"position:relative;\"><a href=\"#%E3%81%BE%E3%81%9A%E3%81%AF-alert\" aria-label=\"まずは alert permalink\" class=\"autolink-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>まずは alert</h2>\n<p>とりあえず動作確認のために、<br>\nChatWork のドメイン（<code>https://www.chatwork.com</code>）なら alert を出すようにしてみます。</p>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\"><span class=\"token builtin class-name\">cd</span> /path/to/work\n<span class=\"token function\">mkdir</span> chrome-ext-gradius <span class=\"token operator\">&amp;&amp;</span> <span class=\"token builtin class-name\">cd</span> chrome-ext-gradius\nbower init <span class=\"token comment\"># 適当に入力()</span>\nbower <span class=\"token function\">install</span> --save cheet.js jquery\n<span class=\"token function\">touch</span> manifest.json main.js chatwork-util.js\n<span class=\"token builtin class-name\">echo</span> <span class=\"token string\">\"bower_components\"</span> <span class=\"token operator\">>></span> .gitignore\n<span class=\"token function\">git</span> init\n<span class=\"token function\">git</span> <span class=\"token function\">add</span> <span class=\"token builtin class-name\">.</span>\n<span class=\"token function\">git</span> commit -m <span class=\"token string\">\"initial commit\"</span></code></pre></div>\n<p>コナミコマンドを実現する js、jQuery は bower で配布されています。<br>\nあとは拡張機能に必要な<code>manifest.json</code>と、自作する js ファイルを生成します。</p>\n<p>manifest.json は以下の内容にします。</p>\n<div class=\"gatsby-highlight\" data-language=\"json\"><pre class=\"language-json\"><code class=\"language-json\"><span class=\"token punctuation\">{</span>\n  <span class=\"token property\">\"version\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"1.0.0\"</span><span class=\"token punctuation\">,</span>\n  <span class=\"token property\">\"manifest_version\"</span><span class=\"token operator\">:</span> <span class=\"token number\">2</span><span class=\"token punctuation\">,</span>\n\n  <span class=\"token property\">\"name\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"CONAMI command for ChatWork\"</span><span class=\"token punctuation\">,</span>\n  <span class=\"token property\">\"description\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"コナミコマンドを入力するとChatWorkに何かが起こる・・・！\"</span><span class=\"token punctuation\">,</span>\n\n  <span class=\"token property\">\"content_scripts\"</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">[</span>\n    <span class=\"token punctuation\">{</span>\n      <span class=\"token property\">\"matches\"</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">[</span><span class=\"token string\">\"https://www.chatwork.com/*\"</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span>\n      <span class=\"token property\">\"js\"</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">[</span>\n        <span class=\"token string\">\"bower_components/jquery/dist/jquery.min.js\"</span><span class=\"token punctuation\">,</span>\n        <span class=\"token string\">\"bower_components/cheet.js/cheet.min.js\"</span><span class=\"token punctuation\">,</span>\n        <span class=\"token string\">\"chatwork-util.js\"</span><span class=\"token punctuation\">,</span>\n        <span class=\"token string\">\"main.js\"</span>\n      <span class=\"token punctuation\">]</span>\n    <span class=\"token punctuation\">}</span>\n  <span class=\"token punctuation\">]</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>そして、main.js にアラートだけ書きます。</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token function\">alert</span><span class=\"token punctuation\">(</span><span class=\"token string\">'ChatWorkです'</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>この状態で、Chrome 拡張機能として Chrome にインポートして動作確認します。</p>\n<h2 id=\"拡張機能を-chrome-にインポート\" style=\"position:relative;\"><a href=\"#%E6%8B%A1%E5%BC%B5%E6%A9%9F%E8%83%BD%E3%82%92-chrome-%E3%81%AB%E3%82%A4%E3%83%B3%E3%83%9D%E3%83%BC%E3%83%88\" aria-label=\"拡張機能を chrome にインポート permalink\" class=\"autolink-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>拡張機能を Chrome にインポート</h2>\n<p>ストアで販売してない拡張機能でもインポートできます。</p>\n<p>メニューから拡張機能のページを開き、</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 600px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/3be4807224e1ee362947c6551941716c/0a47e/step01.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 40.7185628742515%; position: relative; bottom: 0; left: 0; background-image: url('data:image/svg+xml,%3csvg%20xmlns=\\'http://www.w3.org/2000/svg\\'%20width=\\'400\\'%20height=\\'163\\'%20viewBox=\\'0%200%20400%20163\\'%20preserveAspectRatio=\\'none\\'%3e%3cpath%20d=\\'M17%202l-2%201-3%203c0%203%200%203-6%203s-6%200-6%203v3l201-1h200v-3c0-2%200-3-1-2h-41l1-2%201-4-1-1-5%201c-3%200-3%202%201%202%202%200%202%201%201%202-3%203-6%203-5%200l-1-1c-2%201-2%200-2-1l-2-2-2%202c0%204-2%204-5%201-2-3-2-3-4-2l-1%203-3%201c-3%201-3%201-3-4V0h-56v5c0%203%200%205-1%204h-1c-2%201-5-1-5-3%201-3-3-4-5-1-2%202-1%203%201%201l2-1c3%201-4%204-10%204s-9-1-6-2c2-2%201-4-2-4-5%200-5%202-1%202%202%200%202%200%200%201-2%200-2%200-1%201s0%202-2%202c-3%200-3%200-2-3V4l-3-1-3%202c-2%202%200%203%202%201%201-1%203-1%201%201-1%202-5%202-6%200%200-2-1-2-2-2a1038%201038%200%2000-2%202l1%201c-1%201-6%200-5-1l1-3c0-2%200-2-2-2l-5%201-2%201%203%201c3%200%203%200%202%202-2%201-4%202-10%202h-7V6c0-3%200-3-4-3s-4%200-4%203c-1%203-1%203-1%200%200-4%200-4-3-4-4%200-5%201-5%205%200%201-1%202-5%202l-5%201c-1%200-3-3-2-4l-4-1-5-1c0-3-7-1-8%202v3l-6%201c-6%200-6%200-6-5l-1-2h-10c-6-1-6-1-6%203%200%203%200%203-6%203-5%200-6%200-6-2h-1l-1-2c0-3-2-2-2%201v4l-1-4c-1-4-1-3-2%201-1%203-1%203-2%202h-1c-1%201-1%200-1-1l1-4-3%201c-4%202-5%204-2%202l2%201h-6V5h-5v1c2%200%200%202-2%203-2%200-2-1-1-3%200-3%200-3-3-3l-4%201%203%201c2%200%203%201%201%203l-9%201-7-1c0-3-3-4-4-3h-2c-1-1-6-1-8%201l-1-1h-6l-6-1c0-1-1-2-3-2-5%201-6%202-6%204s-1%203-5%203c-6%200-8-1-7-4l-1-2-1-1-1-2-2%202m97%2086v3l-2%201v-1c2-2%201-4-1-4v2l-1%202%201%202v2c-2%201-1%202%204%202l5-1-1-1v-1c1-2%203-1%203%201%200%201%201%202%204%202%204%200%205-1%205-3%200-7-2-9-7-7h-1c-1-1-1%200-2%202%200%203-2%203-2-1%200-2-4-3-5%200m159%209v6h60l60-1V91H273v6m23%2050c0%204%201%204%204%204l3-1%201-1%201%201%204%201c4%200%204%200%204-4%200-3-1-4-4-4s-4%201-4%202l-1%202-1-2c0-2-1-2-3-2-4%200-4%200-4%204m-16%2011c-2%202-2%205%200%205l1-2c0-2%201-3%202-3l2%201c0%203%200%204%202%204s2-1%202-3l1-2c1%200%202%201%201%202l1%202h1c0-1%200-2%201-1v1l1%201%201-2v-3h46c30%200%2045%200%2044-1a840%20840%200%2000-106%201\\'%20fill=\\'%23d3d3d3\\'%20fill-rule=\\'evenodd\\'/%3e%3c/svg%3e'); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/3be4807224e1ee362947c6551941716c/5251b/step01.webp 167w,\n/static/3be4807224e1ee362947c6551941716c/7390e/step01.webp 334w,\n/static/3be4807224e1ee362947c6551941716c/e88ff/step01.webp 600w\"\n              sizes=\"(max-width: 600px) 100vw, 600px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/3be4807224e1ee362947c6551941716c/21521/step01.png 167w,\n/static/3be4807224e1ee362947c6551941716c/86d36/step01.png 334w,\n/static/3be4807224e1ee362947c6551941716c/0a47e/step01.png 600w\"\n            sizes=\"(max-width: 600px) 100vw, 600px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/3be4807224e1ee362947c6551941716c/0a47e/step01.png\"\n            alt=\"Step01\"\n            title=\"Step01\"\n            loading=\"lazy\"\n            decoding=\"async\"\n            style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n          />\n        </picture>\n  </a>\n    </span></p>\n<p>「パッケージ化されていない拡張機能を読み込む…」ボタンをクリックします。<br>\n選択するファイルは、先ほど作成した chrome-ext-gradius フォルダです。</p>\n<p>フォルダを選択すると、下記の画面のように拡張機能の一覧に現れます。</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 600px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/a362a8d55cf6b4efb9c07ea8ae626285/0a47e/step02.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 40.7185628742515%; position: relative; bottom: 0; left: 0; background-image: url('data:image/svg+xml,%3csvg%20xmlns=\\'http://www.w3.org/2000/svg\\'%20width=\\'400\\'%20height=\\'164\\'%20viewBox=\\'0%200%20400%20164\\'%20preserveAspectRatio=\\'none\\'%3e%3cpath%20d=\\'M8%207c-2%203-1%205%203%206%202%200%203-1%203-2l1-1%201%201%201%202%202-2c1-2%201-2%201%200%200%203%206%203%206%200V9l1%202c1%203%208%203%208%200s0-3-10-3L11%207H8m59%200l-1%204c0%202%201%202%204%202%204%200%205-1%203-2l-1-3c1-1%204%203%203%205h3l3-1%201-1%201%201%204%201c3%200%203%200%203-3V7l-8-1-7%201h-8m60%2024h-5v2h2c0-1%201-1%203%201h6l2-1h2l1%201c-1%201%202%201%2010%201l11-1h1c2%201%203%201%203-1h1c0%202%207%202%2010%201h1l3%201%202-1h5v-3h-4l-1%201-1-1-2-2-2%202h-2l-2-1c0%202-2%203-2%201-1-2-5-2-5-1h-1a94%2094%200%2000-28%201h-1c0-2-2-1-2%201h-1c0-2-3-3-4-1m75%200v2c-1%202%200%202%2013%202l15-2h1l2%201v-4c-2%200-4%200-4%202h-1c0-2-1-2-3-2h-3c0-1-20-1-20%201m126-1v2l-1%203h11l11-1h1c2%201%203%201%203-1l2-1%202%201v2l2-1c0-3%202-2%202%200l2-1c2-3%201-5-2-3h-18l-8-1-7%201M68%2036c0%202%204%202%2063%202h64l-63-1a478%20478%200%2001-64-1m23%2021c-1%203%201%204%203%204h14c8%200%208%200%208-2s-1-3-2-3l-2%201h-1c-2-1-2-1-2%201l-1-1H91m54%200h-14c-11%200-13%201-13%202%200%202%2012%203%2013%201h3l3%201%203-1h1l3%201c2%200%202%200%202-2%200-3%200-3-1-2M99%2080c0%203%205%204%207%202%200-2%201-2%201-1l7%201a150%20150%200%200132%201l21-1c24%200%2023%200%2023-1%200-2%204-2-49-2l-42%201m16%208l1%203h22l1-2%201%201c-1%201%201%202%202%201h5a358%20358%200%200040%200h40c1%202%202%202%203%201h8c5%200%207-1%208-2%200-2-3-3-4-1h-1a289%20289%200%2001-48-1l-4%201h-1c-1-1-2-2-3-1h-8c-1-1-2%200-2%201h-1l-2-1h-5l-5%201h-1l-2-2-3%202h-1l-2-2c-2%200-2%200-1%202v1l-1-1-6-1-1%201-2-1h-22l-1%201-1-1h-3m93%2014l-1%202-4%201%2020%201%2020-1-1-1-2-1-1-3-1%202v2l-1-2c-1-2-9-2-10%200%200%202-3%203-5%200h-2c0%204-7%204-8%201-1-4-3-4-4-1M66%20132v10h22v-9c0-13%201-12-12-12H66v11m9-5l-4%202h-2l2%202c1%202%202%203%201%205%200%203%200%203%202%202%202-2%203-2%205%200l3%201v-3c-1-2-1-3%201-5l2-2h-2l-4-2-2-3-2%203m46%2027h-11c-10%200-11%200-11%202s6%202%207%201h1l3%201%202-1h3l2%201h16l6-1h1c1%202%205%202%206%200h1c0%201%203%202%204%201h25c5%200%207-1%207-2s-2-2-5-2h-7a367%20367%200%2001-50%200\\'%20fill=\\'%23d3d3d3\\'%20fill-rule=\\'evenodd\\'/%3e%3c/svg%3e'); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/a362a8d55cf6b4efb9c07ea8ae626285/5251b/step02.webp 167w,\n/static/a362a8d55cf6b4efb9c07ea8ae626285/7390e/step02.webp 334w,\n/static/a362a8d55cf6b4efb9c07ea8ae626285/e88ff/step02.webp 600w\"\n              sizes=\"(max-width: 600px) 100vw, 600px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/a362a8d55cf6b4efb9c07ea8ae626285/21521/step02.png 167w,\n/static/a362a8d55cf6b4efb9c07ea8ae626285/86d36/step02.png 334w,\n/static/a362a8d55cf6b4efb9c07ea8ae626285/0a47e/step02.png 600w\"\n            sizes=\"(max-width: 600px) 100vw, 600px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/a362a8d55cf6b4efb9c07ea8ae626285/0a47e/step02.png\"\n            alt=\"Step02\"\n            title=\"Step02\"\n            loading=\"lazy\"\n            decoding=\"async\"\n            style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n          />\n        </picture>\n  </a>\n    </span></p>\n<p>なお、一度取り込みを行ってしまえば、<br>\nファイルを変更した時に拡張機能のページをリロードするだけで再読込されます。</p>\n<p><strong>リロードしないと拡張機能の再読み込みがされない</strong>ので、<br>\n**あれ動かない？**と思ったら拡張機能のページをリロードしてみてください。</p>\n<p>次に、Chrome 拡張機能の<code>content scripts</code>についての理解を深めます。</p>\n<h2 id=\"content-scripts\" style=\"position:relative;\"><a href=\"#content-scripts\" aria-label=\"content scripts permalink\" class=\"autolink-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>content scripts</h2>\n<p>content scripts は任意の web ページに対して任意の js を実行できますが、いくつか制限があります。</p>\n<blockquote>\n<p>コンテント・スクリプトは “Isolated World”(隔離空間) と呼ばれる特殊な環境で実行される。ここでは読み込まれたページの DOM にはアクセスできるが、該当ページの JavaScript の変数や関数には出来ない。そのため、各コンテンツ・スクリプトからは、あたかも他の JavaScript が全く実行されていないページで自分が実行されるように見える。逆もまた真なりで、各ページのスクリプトからもコンテンツ・スクリプトで定義した変数や関数にアクセスすることは出来ない。<br>\n— <span class=\"removed_link\" title=\"http://dev.screw-axis.com/doc/chrome_extensions/guide/content_script/\">コンテント・スクリプト | Chrome Extensions API リファレンス</span></p>\n</blockquote>\n<p>このように、そのページで読み込まれている js には一切アクセスできず、<br>\n拡張機能で定義した機能についてもそのページの js からはアクセスできません。</p>\n<p>ただし、DOM を介してデータのやりとりを行うことができます。</p>\n<p>「DOM を書き換えることができて、どんな命名をしても対象ページ内の js と衝突することはない」</p>\n<p>と捉えるとかなり幸せに思いますが、<br>\n特定のページ用（今回なら ChatWork 専用）の拡張機能を作る場合には、<br>\nChatWork で動作している js にアクセスできないため、<strong>いちいち各操作を自前で実装する必要があります。</strong><br>\n例えば、チャットルームの切り替えは、タイミング制御まで合わせるとなかなかの鬼門です。</p>\n<p>不幸中の幸いながら、<br>\nChatWork の HTML には属性として各種パラメータが埋め込まれているので、パース処理や値の取得自体は簡単です。</p>\n<p>では早速実装していきます。</p>\n<h2 id=\"コナミコマンドを有効化\" style=\"position:relative;\"><a href=\"#%E3%82%B3%E3%83%8A%E3%83%9F%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%82%92%E6%9C%89%E5%8A%B9%E5%8C%96\" aria-label=\"コナミコマンドを有効化 permalink\" class=\"autolink-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>コナミコマンドを有効化</h2>\n<p>基本的には<code>cheet</code>関数を使用してショートカットを設定するだけなのですが、</p>\n<p>キーボードイベントに関して要注意なのは、ChatWork の js と衝突して、<br>\n↑ キーと ↓ キーが奪われてしまい、<strong>しかも握りつぶされています。</strong></p>\n<p>cheet.js は<code>window</code>にイベントを設定しているので、<br>\n<code>document</code>で止められてしまうと反応できません。</p>\n<p>つらい。これはつらい。</p>\n<p>と思って心が折れかけましたが、無理やりイベントを先取りすることが出来ました。</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token comment\">// 握りつぶされる前にkeydownイベントをwindowオブジェクトに伝播させる</span>\n<span class=\"token function\">$</span><span class=\"token punctuation\">(</span>document<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">on</span><span class=\"token punctuation\">(</span><span class=\"token string\">'keydown'</span><span class=\"token punctuation\">,</span> <span class=\"token keyword\">function</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">e</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">var</span> ev <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Event</span><span class=\"token punctuation\">(</span><span class=\"token string\">'keydown'</span><span class=\"token punctuation\">)</span>\n  ev<span class=\"token punctuation\">.</span>keyCode <span class=\"token operator\">=</span> e<span class=\"token punctuation\">.</span>keyCode\n\n  window<span class=\"token punctuation\">.</span><span class=\"token function\">dispatchEvent</span><span class=\"token punctuation\">(</span>ev<span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n\n<span class=\"token function\">cheet</span><span class=\"token punctuation\">(</span><span class=\"token string\">'U U D D L R L R b a'</span><span class=\"token punctuation\">,</span> <span class=\"token keyword\">function</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token function\">alert</span><span class=\"token punctuation\">(</span><span class=\"token string\">'コナミコマンド発動!'</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>カスタムイベントを作り window へぶん投げるようにしました。</p>\n<p>拡張機能をリロードし、ChatWork もリロードし、<br>\n「↑ ↑ ↓ ↓ ← → ← → B A」と入力してみると、以下のようになります。</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 457px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/92eed9060503d12d32ed9b081cc8ff5c/34f1d/step03.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 40.7185628742515%; position: relative; bottom: 0; left: 0; background-image: url('data:image/svg+xml,%3csvg%20xmlns=\\'http://www.w3.org/2000/svg\\'%20width=\\'400\\'%20height=\\'163\\'%20viewBox=\\'0%200%20400%20163\\'%20preserveAspectRatio=\\'none\\'%3e%3cpath%20d=\\'M385%2021v4h-21a346%20346%200%2000-27%200h-49l-4-1h-1l-26%201a507%20507%200%2000-51%200h-30l-4-1h-1l-20%201a124110%20124110%200%2000-113%200H18v-5l-1%202-1%209c0%204%200%206-1%205-1-2-1-2-1%201-2%205-3%206-9%206s-4%202%203%202h3l-1%204c-2%208-1%2092%200%2092l-4%201c-6%202-6%202-3%202l8%202c-1%200%203%2010%206%2014l2%203h364l3-3%205-10c2-7%203-8%203-54%200-49-1-50-5-59l-3-12c0-5-1-7-1-4M18%2085l1%2057h365l1-57V29H18v56m38-36c-6%203-8%205-11%2011-11%2021%2011%2043%2032%2034%206-3%2014-12%2012-15l-1%202c-2%203-18%2012-20%2010l3-5c4-7%204-7%200-5-7%203-15-2-15-10%200-7%207-12%2014-10%205%201%2018%200%2018-2s-6-8-10-10c-6-3-17-3-22%200m6%2014c-3%201-5%206-5%2010%202%207%2011%2010%2016%205%207-7-1-19-11-15m237%2046c-2%202-2%204-2%209%200%2011-2%2010%2036%2010s36%201%2036-10c0-12%202-11-36-11h-32l-2%202m2%202l-1%204v3h12l12%201%201-3c2-6%208-3%208%203-1%203-5%204-7%202h-25l-1%203c1%203%2065%203%2066%200l-1-3h-29l-1%201-1-4%201-5%201%201h2c2-2%203%200%201%202-3%202-3%203%2013%202h14v-7l-33-1-32%201\\'%20fill=\\'%23d3d3d3\\'%20fill-rule=\\'evenodd\\'/%3e%3c/svg%3e'); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/92eed9060503d12d32ed9b081cc8ff5c/5251b/step03.webp 167w,\n/static/92eed9060503d12d32ed9b081cc8ff5c/7390e/step03.webp 334w,\n/static/92eed9060503d12d32ed9b081cc8ff5c/0903d/step03.webp 457w\"\n              sizes=\"(max-width: 457px) 100vw, 457px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/92eed9060503d12d32ed9b081cc8ff5c/21521/step03.png 167w,\n/static/92eed9060503d12d32ed9b081cc8ff5c/86d36/step03.png 334w,\n/static/92eed9060503d12d32ed9b081cc8ff5c/34f1d/step03.png 457w\"\n            sizes=\"(max-width: 457px) 100vw, 457px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/92eed9060503d12d32ed9b081cc8ff5c/34f1d/step03.png\"\n            alt=\"Step03\"\n            title=\"Step03\"\n            loading=\"lazy\"\n            decoding=\"async\"\n            style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n          />\n        </picture>\n  </a>\n    </span></p>\n<p>cheet.js 側が反応するようになったので OK です。次へ進みます。</p>\n<h2 id=\"ユーティリティを作成\" style=\"position:relative;\"><a href=\"#%E3%83%A6%E3%83%BC%E3%83%86%E3%82%A3%E3%83%AA%E3%83%86%E3%82%A3%E3%82%92%E4%BD%9C%E6%88%90\" aria-label=\"ユーティリティを作成 permalink\" class=\"autolink-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>ユーティリティを作成</h2>\n<ul>\n<li>チャットルームを切り替える</li>\n<li>チャットに投稿する</li>\n<li><a href=\"http://developer.chatwork.com/ja/messagenotation.html\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">ChatWork 記法</a>を使う</li>\n</ul>\n<p>などの部分を直接書くと煩雑になるため、<br>\nDOM 操作や記法のユーティリティは、作成しておいた<code>chatwork-util.js</code>のほうに記述していきます。</p>\n<h3 id=\"infoタグ記法のテキストを生成するユーティリティ\" style=\"position:relative;\"><a href=\"#info%E3%82%BF%E3%82%B0%E8%A8%98%E6%B3%95%E3%81%AE%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88%E3%82%92%E7%94%9F%E6%88%90%E3%81%99%E3%82%8B%E3%83%A6%E3%83%BC%E3%83%86%E3%82%A3%E3%83%AA%E3%83%86%E3%82%A3\" aria-label=\"infoタグ記法のテキストを生成するユーティリティ permalink\" class=\"autolink-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>[info]タグ記法のテキストを生成するユーティリティ</h3>\n<p>ChatWork では、<code>[info]</code>というタグが使えます。<br>\nAA など等幅にしてほしいテキストを送る場合に便利です。</p>\n<p>使用するのでユーティリティ化します。</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token punctuation\">;</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">function</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">global</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token string\">'use strict'</span>\n\n  <span class=\"token keyword\">var</span> util <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token comment\">/**\n     * 指定されたテキストをChatWork記法の[info]タグへ変換する\n     * @param string body    [info]タグの本文にあたる部分\n     * @param string [title] 指定されたら[title]タグも使用する。省略された場合使用しない\n     * @return string [info]...[/info]で囲われた文字列\n     */</span>\n    <span class=\"token function-variable function\">toInfomation</span><span class=\"token operator\">:</span> <span class=\"token keyword\">function</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">body<span class=\"token punctuation\">,</span> title</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      <span class=\"token keyword\">var</span> info <span class=\"token operator\">=</span> <span class=\"token string\">'[info]'</span>\n\n      <span class=\"token comment\">// titleが指定されていたらtitleタグを使用</span>\n      <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">typeof</span> title <span class=\"token operator\">!==</span> <span class=\"token string\">'undefined'</span><span class=\"token punctuation\">)</span> info <span class=\"token operator\">+=</span> <span class=\"token string\">'[title]'</span> <span class=\"token operator\">+</span> title <span class=\"token operator\">+</span> <span class=\"token string\">'[/title]'</span>\n\n      info <span class=\"token operator\">+=</span> body <span class=\"token operator\">+</span> <span class=\"token string\">'[/info]'</span>\n      <span class=\"token keyword\">return</span> info\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n  <span class=\"token punctuation\">}</span>\n\n  global<span class=\"token punctuation\">.</span>util <span class=\"token operator\">=</span> util\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">)</span></code></pre></div>\n<h3 id=\"マイチャットの-html-要素を取得するユーティリティ\" style=\"position:relative;\"><a href=\"#%E3%83%9E%E3%82%A4%E3%83%81%E3%83%A3%E3%83%83%E3%83%88%E3%81%AE-html-%E8%A6%81%E7%B4%A0%E3%82%92%E5%8F%96%E5%BE%97%E3%81%99%E3%82%8B%E3%83%A6%E3%83%BC%E3%83%86%E3%82%A3%E3%83%AA%E3%83%86%E3%82%A3\" aria-label=\"マイチャットの html 要素を取得するユーティリティ permalink\" class=\"autolink-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>マイチャットの HTML 要素を取得するユーティリティ</h3>\n<p>ChatWork の左側にあるチャットルーム一覧は、<br>\n頻繁に DOM の書き換えが行われるため、変数にキャッシュすると期待通りの動作になりません。<br>\nなのでメソッド化して、毎度 HTML に問い合わせて取得します。</p>\n<p>なお、全体を記述すると長くなってしまうので、<br>\nファイル全体ではなく必要な箇所のみ記述します。</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token keyword\">var</span> util <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token comment\">/**\n   * マイチャットの名前。もし名前を変更している人がいたらここを書き換えてください。\n   */</span>\n  <span class=\"token constant\">MYCHAT_NAME</span><span class=\"token operator\">:</span> <span class=\"token string\">'マイチャット'</span><span class=\"token punctuation\">,</span>\n\n  <span class=\"token comment\">/**\n   * マイチャットへのリンクを表す要素を取得する\n   * NOTE: チャット一覧のDOMは頻繁に書き換わるため変数にキャッシュすると期待道理に動かない。\n   *       なので変数にキャッシュせずに毎回取得を行う\n   * NOTE: MYCHAT_NAMEに設定されている名前のチャットをマイチャットとみなす\n   * @return jQuery マイチャットを表すjQueryオブジェクト\n   */</span>\n  <span class=\"token function-variable function\">getMyChat</span><span class=\"token operator\">:</span> <span class=\"token keyword\">function</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token comment\">// チャットルーム名がMYCHAT_NAMEのチャットを返す</span>\n    <span class=\"token keyword\">var</span> selector <span class=\"token operator\">=</span> <span class=\"token string\">'li[aria-label=\"'</span> <span class=\"token operator\">+</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span><span class=\"token constant\">MYCHAT_NAME</span> <span class=\"token operator\">+</span> <span class=\"token string\">'\"]'</span>\n    <span class=\"token keyword\">return</span> <span class=\"token function\">$</span><span class=\"token punctuation\">(</span><span class=\"token string\">'#_roomListItems'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">find</span><span class=\"token punctuation\">(</span>selector<span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n\n  <span class=\"token comment\">// ...</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>マイチャットを取得出来ました。<br>\n何らかのフラグではなく、チャットルームの名前と<code>MYCHAT_NAME</code>という変数の値に依存してしまっているので、治せる方法があれば治したいです。</p>\n<h3 id=\"マイチャットへ切り替えるユーティリティ\" style=\"position:relative;\"><a href=\"#%E3%83%9E%E3%82%A4%E3%83%81%E3%83%A3%E3%83%83%E3%83%88%E3%81%B8%E5%88%87%E3%82%8A%E6%9B%BF%E3%81%88%E3%82%8B%E3%83%A6%E3%83%BC%E3%83%86%E3%82%A3%E3%83%AA%E3%83%86%E3%82%A3\" aria-label=\"マイチャットへ切り替えるユーティリティ permalink\" class=\"autolink-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>マイチャットへ切り替えるユーティリティ</h3>\n<p>マイチャットの要素を取得できたので、マイチャットへ切り替えるユーティリティも作成しておきます。</p>\n<p>実装は簡単で、単に<code>click</code>イベントを発行するだけです。</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token keyword\">var</span> util <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token comment\">/**\n   * 現在のチャットをマイチャットへ切り替える\n   * @return void\n   */</span>\n  <span class=\"token function-variable function\">changeMyChat</span><span class=\"token operator\">:</span> <span class=\"token keyword\">function</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span><span class=\"token function\">getMyChat</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">trigger</span><span class=\"token punctuation\">(</span><span class=\"token string\">'click'</span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n\n  <span class=\"token comment\">// ...</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>これだけです。</p>\n<p><strong>…なわけありません。</strong><br>\nチャットルームの切替時に非同期で Ajax が走り、<br>\n切り替え先のチャットのメッセージ一覧を取得しメッセージ一覧画面をかきえます。<br>\nこのチャットルームの切り替え完了を検知するタイミングの制御が、なかなか難しいです。</p>\n<p>制御に失敗すると、チャットへ投稿するときに、別のチャットへ投稿してしまうことが起こります。<br>\nですが、詳細までお話していると今回本筋から大きくそれるため触れません。<br>\n<code>MutationObserver</code>というオブジェクトを利用しています。詳しくは<span class=\"removed_link\" title=\"https://github.com/Leko/chrome-ext-gradius\">リポジトリ</span>を御覧ください。</p>\n<h3 id=\"チャットに投稿するユーティリティ\" style=\"position:relative;\"><a href=\"#%E3%83%81%E3%83%A3%E3%83%83%E3%83%88%E3%81%AB%E6%8A%95%E7%A8%BF%E3%81%99%E3%82%8B%E3%83%A6%E3%83%BC%E3%83%86%E3%82%A3%E3%83%AA%E3%83%86%E3%82%A3\" aria-label=\"チャットに投稿するユーティリティ permalink\" class=\"autolink-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>チャットに投稿するユーティリティ</h3>\n<p>前述のタイミング制御の問題さえなければごくシンプルです。</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token keyword\">var</span> util <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token comment\">/**\n   * 現在のチャットへ発言する\n   * @param string body 発言内容\n   * @return void\n   */</span>\n  <span class=\"token function-variable function\">send</span><span class=\"token operator\">:</span> <span class=\"token keyword\">function</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">body</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    util<span class=\"token punctuation\">.</span>$chatText<span class=\"token punctuation\">.</span><span class=\"token function\">val</span><span class=\"token punctuation\">(</span>body<span class=\"token punctuation\">)</span>\n    util<span class=\"token punctuation\">.</span>$sendBtn<span class=\"token punctuation\">.</span><span class=\"token function\">trigger</span><span class=\"token punctuation\">(</span><span class=\"token string\">'click'</span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token function\">$</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">function</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token comment\">// チャット内容入力フォーム、送信ボタンを変数にキャッシュ</span>\n  util<span class=\"token punctuation\">.</span>$chatText <span class=\"token operator\">=</span> <span class=\"token function\">$</span><span class=\"token punctuation\">(</span><span class=\"token string\">'#_chatText'</span><span class=\"token punctuation\">)</span>\n  util<span class=\"token punctuation\">.</span>$sendBtn <span class=\"token operator\">=</span> <span class=\"token function\">$</span><span class=\"token punctuation\">(</span><span class=\"token string\">'#_sendButton'</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>チャット内容入力フォームと送信ボタンの HTML は、<br>\n書き換えられることがないので、速度のため変数にキャッシュしています。</p>\n<p>動作確認をしてみます。</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token function\">$</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">function</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  util<span class=\"token punctuation\">.</span><span class=\"token function\">send</span><span class=\"token punctuation\">(</span><span class=\"token string\">'hogehoge'</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 600px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/72632c4fc9b16d2da985113d6bc7689f/0a47e/Screen-Shot-2014-07-20-at-5.30.13-PM.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 15.568862275449103%; position: relative; bottom: 0; left: 0; background-image: url('data:image/svg+xml,%3csvg%20xmlns=\\'http://www.w3.org/2000/svg\\'%20width=\\'400\\'%20height=\\'61\\'%20viewBox=\\'0%200%20400%2061\\'%20preserveAspectRatio=\\'none\\'%3e%3cpath%20d=\\'M26%2025c0%203%202%204%202%201h1l4%202%203%201h4l3-1c2%200%203-1%203-2h1c0%202%201%202%204%202l3%201h4c0-1%201-2%202-1%202%200%202%200%202-2s-1-2-4-2h-8c-1%201-2%201-3-1h-3l-4%201H29c-2-3-3-2-3%201\\'%20fill=\\'%23d3d3d3\\'%20fill-rule=\\'evenodd\\'/%3e%3c/svg%3e'); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/72632c4fc9b16d2da985113d6bc7689f/5251b/Screen-Shot-2014-07-20-at-5.30.13-PM.webp 167w,\n/static/72632c4fc9b16d2da985113d6bc7689f/7390e/Screen-Shot-2014-07-20-at-5.30.13-PM.webp 334w,\n/static/72632c4fc9b16d2da985113d6bc7689f/e88ff/Screen-Shot-2014-07-20-at-5.30.13-PM.webp 600w\"\n              sizes=\"(max-width: 600px) 100vw, 600px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/72632c4fc9b16d2da985113d6bc7689f/21521/Screen-Shot-2014-07-20-at-5.30.13-PM.png 167w,\n/static/72632c4fc9b16d2da985113d6bc7689f/86d36/Screen-Shot-2014-07-20-at-5.30.13-PM.png 334w,\n/static/72632c4fc9b16d2da985113d6bc7689f/0a47e/Screen-Shot-2014-07-20-at-5.30.13-PM.png 600w\"\n            sizes=\"(max-width: 600px) 100vw, 600px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/72632c4fc9b16d2da985113d6bc7689f/0a47e/Screen-Shot-2014-07-20-at-5.30.13-PM.png\"\n            alt=\"Scree\"\n            title=\"Scree\"\n            loading=\"lazy\"\n            decoding=\"async\"\n            style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n          />\n        </picture>\n  </a>\n    </span></p>\n<p>OK です。</p>\n<p>さて、マイチャットに切り替えられるようになり、発言もできるようになったので、<br>\n早速 AA を投稿してみたいと思います。</p>\n<h2 id=\"aa-を投稿する\" style=\"position:relative;\"><a href=\"#aa-%E3%82%92%E6%8A%95%E7%A8%BF%E3%81%99%E3%82%8B\" aria-label=\"aa を投稿する permalink\" class=\"autolink-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>AA を投稿する</h2>\n<p>今回使用する AA はこちら。</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">　　　　　　　　　_ _\n　　　　　　　　（_ _ ）―――――――――――\n　　　ぴちゅーん\n　　　　　　　　　　　　　　　　　　　_ _\n　　　　　　　　　　　　　　　　　　（_ _ ）―――――――――――\n　　 _\n　 _ヽ ヽ.__________　\n≡] _三 ,. ヽ_ 丶-｀ﾞ__=-　―――――――――――\n　　　 ∥_,\"===￣￣\n　　　　　　　　　　　　　　　　　　ぴちゅーん\n　　　　　　　　　　　　　　　　　　　　　　　　　　　_ _\n　　　　　　　　　　　　　　　　　　　　　　　　　　（_ _ ）―――――――――――\n　　　　　　　　　　　　　　ぴちゅーん\n　　　　　　　　　_ _\n　　　　　　　　（_ _ ）――――――――</code></pre></div>\n<p>はい。ビックバイパーです。<del>グラディウスやったことないけど。</del></p>\n<p><strong>ナメてんのか</strong>って感じの良い AA ですね。<br>\n<a href=\"http://bhdaa.sakura.ne.jp/gradius/gradius-asciiart.html\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">こちら</a>のサイト様に掲載されていた AA を少し改変させていただきました。</p>\n<p>あまり複雑な AA だと分かりにくいと思ったので、シンプルな AA で行きます。</p>\n<p>ユーティリティは揃えらので、<br>\nあとはもうコナミコマンドのコールバックを仕上げるだけです。</p>\n<p>main.js の内容は以下の通りになります。</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token punctuation\">(</span><span class=\"token keyword\">function</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">global</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token string\">'use strict'</span><span class=\"token punctuation\">;</span>\n\n    <span class=\"token keyword\">var</span> <span class=\"token constant\">AA</span> <span class=\"token operator\">=</span> util<span class=\"token punctuation\">.</span><span class=\"token function\">toInfomation</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"　　　　　　　　　_ _\\n\\\n　　　　　　　　（_ _ ）―――――――――――\\n\\\n　　　ぴちゅーん\\n\\\n　　　　　　　　　　　　　　　　　　　_ _\\n\\\n　　　　　　　　　　　　　　　　　　（_ _ ）―――――――――――\\n\\\n　　 _\\n\\\n　 _ヽ ヽ.__________　\\n\\\n≡] _三 ,. ヽ_ 丶-｀ﾞ__=-　―――――――――――\\n\\\n　　　 ∥_,\\\"===￣￣\\n\\\n　　　　　　　　　　　　　　　　　　ぴちゅーん\\n\\\n　　　　　　　　　　　　　　　　　　　　　　　　　　　_ _\\n\\\n　　　　　　　　　　　　　　　　　　　　　　　　　　（_ _ ）―――――――――――\\n\\\n　　　　　　　　　　　　　　ぴちゅーん\\n\\\n　　　　　　　　　_ _\\n\\\n　　　　　　　　（_ _ ）―――――――――――\"</span><span class=\"token punctuation\">,</span> <span class=\"token string\">'コナミコマンドが入力されました'</span><span class=\"token punctuation\">)</span>\\<span class=\"token punctuation\">;</span>\\\n\n    <span class=\"token comment\">// 握りつぶされる前にkeydownイベントをwindowオブジェクトに伝播させる</span>\n    <span class=\"token function\">$</span><span class=\"token punctuation\">(</span>document<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">on</span><span class=\"token punctuation\">(</span><span class=\"token string\">'keydown'</span><span class=\"token punctuation\">,</span> <span class=\"token keyword\">function</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">e</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">var</span> ev <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Event</span><span class=\"token punctuation\">(</span><span class=\"token string\">'keydown'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        ev<span class=\"token punctuation\">.</span>keyCode <span class=\"token operator\">=</span> e<span class=\"token punctuation\">.</span>keyCode<span class=\"token punctuation\">;</span>\n\n        window<span class=\"token punctuation\">.</span><span class=\"token function\">dispatchEvent</span><span class=\"token punctuation\">(</span>ev<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n    <span class=\"token comment\">// コナミコマンドが入力されたらマイチャットへ切り替えて発言を行う</span>\n    <span class=\"token function\">cheet</span><span class=\"token punctuation\">(</span><span class=\"token string\">'U U D D L R L R b a'</span><span class=\"token punctuation\">,</span> <span class=\"token keyword\">function</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        util<span class=\"token punctuation\">.</span><span class=\"token function\">changeMyChat</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">function</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n            <span class=\"token comment\">// 切り替わったらAAを投稿</span>\n            util<span class=\"token punctuation\">.</span><span class=\"token function\">send</span><span class=\"token punctuation\">(</span><span class=\"token constant\">AA</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>コナミコマンドを入力してみます。</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 600px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/e91a86b587c9dcd6a9b17cb8aa477b84/0a47e/Screen-Shot-2014-07-20-at-5.46.36-PM1.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 55.08982035928144%; position: relative; bottom: 0; left: 0; background-image: url('data:image/svg+xml,%3csvg%20xmlns=\\'http://www.w3.org/2000/svg\\'%20width=\\'400\\'%20height=\\'219\\'%20viewBox=\\'0%200%20400%20219\\'%20preserveAspectRatio=\\'none\\'%3e%3cpath%20d=\\'M20%20214c0%202%200%203%201%201%200-2%202-3%202%200l5%201%201%201%202%201%202-1%202-1c3%200%205%200%205-2%201-1%201-1%201%201s3%202%206%201h1c0%202%202%203%203%201h3c1%200%202-1%202-3%200-1%200-2-4-2h-3c-1%201-8%200-9-1%200-2-2-1-2%201H25l-4-1c-1-1-1%200-1%203\\'%20fill=\\'%23d3d3d3\\'%20fill-rule=\\'evenodd\\'/%3e%3c/svg%3e'); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/e91a86b587c9dcd6a9b17cb8aa477b84/5251b/Screen-Shot-2014-07-20-at-5.46.36-PM1.webp 167w,\n/static/e91a86b587c9dcd6a9b17cb8aa477b84/7390e/Screen-Shot-2014-07-20-at-5.46.36-PM1.webp 334w,\n/static/e91a86b587c9dcd6a9b17cb8aa477b84/e88ff/Screen-Shot-2014-07-20-at-5.46.36-PM1.webp 600w\"\n              sizes=\"(max-width: 600px) 100vw, 600px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/e91a86b587c9dcd6a9b17cb8aa477b84/21521/Screen-Shot-2014-07-20-at-5.46.36-PM1.png 167w,\n/static/e91a86b587c9dcd6a9b17cb8aa477b84/86d36/Screen-Shot-2014-07-20-at-5.46.36-PM1.png 334w,\n/static/e91a86b587c9dcd6a9b17cb8aa477b84/0a47e/Screen-Shot-2014-07-20-at-5.46.36-PM1.png 600w\"\n            sizes=\"(max-width: 600px) 100vw, 600px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/e91a86b587c9dcd6a9b17cb8aa477b84/0a47e/Screen-Shot-2014-07-20-at-5.46.36-PM1.png\"\n            alt=\"Scree\"\n            title=\"Scree\"\n            loading=\"lazy\"\n            decoding=\"async\"\n            style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n          />\n        </picture>\n  </a>\n    </span></p>\n<p>OK です。</p>\n<p>どのチャットに居てもマイチャットへ移動し、AA が投稿されます。<br>\n<strong>動作がとても重い環境だと投稿しそこねたり、マイチャット以外へ投稿してしまうこともあるのでご注意ください。</strong></p>\n<p>ということで拡張機能が完成しました。<br>\n拡張機能では CSS を読み込めるようなので、<br>\nもっと深めてみたら面白いことになりそうです。</p>\n<p>完成したファイルはこちらからご覧になることができます。</p>\n<blockquote>\n<p>— <span class=\"removed_link\" title=\"https://github.com/Leko/chrome-ext-gradius\">Leko/chrome-ext-gradius · GitHub</span></p>\n</blockquote>\n<h2 id=\"参考\" style=\"position:relative;\"><a href=\"#%E5%8F%82%E8%80%83\" aria-label=\"参考 permalink\" class=\"autolink-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>参考</h2>\n<blockquote>\n<p>— <a href=\"http://dotinstall.com/lessons/basic_chrome_v2\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Google Chrome 拡張機能入門 (全 20 回) – プログラミングならドットインストール</a></p>\n</blockquote>\n<!---->\n<blockquote>\n<p>— <span class=\"removed_link\" title=\"http://dev.screw-axis.com/doc/chrome_extensions/guide/content_script/\">コンテント・スクリプト | Chrome Extensions API リファレンス</span></p>\n</blockquote>\n<!---->\n<blockquote>\n<p>— <a href=\"http://bhdaa.sakura.ne.jp/gradius/gradius-asciiart.html\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">グラディウス AA 集　（ボスのアスキーアート）</a></p>\n</blockquote>","timeToRead":14,"frontmatter":{"title":"Chrome拡張を作ってweb版ChatWorkを改造してみた","tags":["cheet.js","Chrome extension","JavaScript","jQuery","ChatWork"],"date":"August 05, 2014","featuredImage":{"childImageSharp":{"fluid":{"tracedSVG":"data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20width='400'%20height='135'%20viewBox='0%200%20400%20135'%20preserveAspectRatio='none'%3e%3cpath%20d='M275%2062l-1%208v7h4c7%200%2010-3%207-7v-3c1-2%201-3-1-4-2-2-8-3-9-1m18%200l-6%2015%204-1%204-2c2%200%203%201%203%202l3%201c2%200%202%200-1-8-3-7-6-10-7-7m-106%204l-4%203%204%204c3%203%204%204%205%203v-3c-2-2-2-2%204-2%209-1%209-3%201-3-7%200-8-1-6-3%202-1%202-3%200-3l-4%204m30-3l1%202c2%202%201%203-6%203-8%200-8%202%201%203%206%200%206%200%205%202-2%201-2%202-1%203s3%200%206-3l3-4-3-3c-3-4-5-5-6-3m15%203l-3%203%203%204c3%203%205%204%206%203s1-2-1-3c-1-2-1-2%205-2l6-1c0-2-1-2-7-2h-6l2-2c2-3%202-4%200-4l-5%204m30-3l2%203c1%202%201%202-5%202s-7%200-7%202l7%201c6%200%206%200%205%202-4%204-1%204%204%200l4-3-4-4c-3-4-6-5-6-3'%20fill='%23d3d3d3'%20fill-rule='evenodd'/%3e%3c/svg%3e","aspectRatio":2.9557522123893807,"src":"/static/e43911acb6b80e992575cfb4a43f6c7e/32d53/featured-image.png","srcSet":"/static/e43911acb6b80e992575cfb4a43f6c7e/1ec58/featured-image.png 334w,\n/static/e43911acb6b80e992575cfb4a43f6c7e/32d53/featured-image.png 614w","srcWebp":"/static/e43911acb6b80e992575cfb4a43f6c7e/9b99b/featured-image.webp","srcSetWebp":"/static/e43911acb6b80e992575cfb4a43f6c7e/cd98f/featured-image.webp 334w,\n/static/e43911acb6b80e992575cfb4a43f6c7e/9b99b/featured-image.webp 614w","sizes":"(max-width: 614px) 100vw, 614px"}}}}}},"pageContext":{"slug":"/how-to-extend-chatwork-in-google-chrome/","previous":{"fields":{"slug":"/benchmark-with-syntax-and-language-structure/"},"frontmatter":{"title":"php5.4から使える[]での配列初期化と、array()との速度比較","tags":["benchmark","PHP"]}},"next":{"fields":{"slug":"/examination-of-and-or-operator-in-php/"},"frontmatter":{"title":"PHPのand,or演算子の使い道を考えてみる","tags":["PHP"]}}}},
    "staticQueryHashes": ["2585454260","2954598359"]}