<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>techno.blog(&#34;Dion&#34;) &#187; chrome</title>
	<atom:link href="http://almaer.com/blog/tag/chrome/feed" rel="self" type="application/rss+xml" />
	<link>http://almaer.com/blog</link>
	<description>blogging about life, the universe, and everything tech</description>
	<lastBuildDate>Tue, 28 Aug 2012 14:41:55 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Chrome Speak To Site; Give any input the power to listen to you</title>
		<link>http://almaer.com/blog/chrome-speak-to-site-give-any-input-the-power-to-listen-to-you</link>
		<comments>http://almaer.com/blog/chrome-speak-to-site-give-any-input-the-power-to-listen-to-you#comments</comments>
		<pubDate>Tue, 28 Sep 2010 16:34:43 +0000</pubDate>
		<dc:creator>dion</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Tech]]></category>
		<category><![CDATA[Web Browsing]]></category>
		<category><![CDATA[chrome]]></category>
		<category><![CDATA[extensions]]></category>
		<category><![CDATA[speech]]></category>

		<guid isPermaLink="false">http://almaer.com/blog/?p=2796</guid>
		<description><![CDATA[Paul Irish gave a fantastic updated State of HTML5 talk at JSConf.EU. It is packed full of demos, including sharks with freaking lazer beams!
At one point he showed off the WebKit support for &#60;input speech&#62; implementation that allows you to talk into an input area. You click on the microphone, speak in, and it will [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://paulirish.com/">Paul Irish</a> gave a fantastic updated <a href="http://jsconfeu2010-pi.appspot.com/">State of HTML5</a> talk at JSConf.EU. It is packed full of demos, including sharks with freaking lazer beams!</p>
<p>At one point he showed off the <a href="http://trac.webkit.org/export/66389/trunk/LayoutTests/fast/speech/input-appearance-speechbutton.html">WebKit support for &lt;input speech&gt;</a> implementation that allows you to talk into an input area. You click on the microphone, speak in, and it will get translated for you with the results. I am not sure if you can tweak how the translation is done (choose a Nuance vs. Google vs. &#8230;. solution for example), but it definitely works well out of the box.</p>
<p><img src="http://almaer.com/blog/uploads/speak-to-site.png" alt="speak-to-site" title="speak-to-site" width="509" height="379" class="alignnone size-full wp-image-2797"></p>
<p>I was surprised to see this already landed in my developer-channel Chrome, so I was incented to do something with it on the plane trip back from Berlin to New York City. Something simple would be to give the user the ability to enable speech on any input. I whipped up a Chrome extension using the <a href="http://code.google.com/chrome/extensions/beta/contextMenus.html">context menu API</a>, but was quickly surprised to see that there isn&#8217;t <a href="http://code.google.com/p/chromium/issues/detail?id=39507">support in the API to get the DOM node that you are working on</a>. Huh. Kinda crazy in fact.</p>
<p>Then the whizzkid <a href="http://antimatter15.com/wp/2010/08/chrome-extension-hide-element/">antimatter came to the rescue</a> with his cheeky little hack around the system. Here is how it plays out in the world of this extension:</p>
<p><b>The background page</b></p>
<p>First we enable the context menu on any &#8220;editable&#8221; element (vs. anywhere on the page, on any text, etc), and when clicked we fire off an event to the content script in the given tab:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #339933;">&lt;</span>script<span style="color: #339933;">&gt;</span>
chrome.<span style="color: #660066;">contextMenus</span>.<span style="color: #660066;">create</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
    title<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;Turn on speech input&quot;</span><span style="color: #339933;">,</span>
    contexts<span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span><span style="color: #3366CC;">&quot;editable&quot;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
    onclick<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>info<span style="color: #339933;">,</span> tab<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        chrome.<span style="color: #660066;">tabs</span>.<span style="color: #660066;">sendRequest</span><span style="color: #009900;">&#40;</span>tab.<span style="color: #660066;">id</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'letmespeak'</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #339933;">&lt;/</span>script<span style="color: #339933;">&gt;</span></pre></div></div>

<p><b>Catching in a content script</b></p>
<p>A content script then does two things:</p>
<ul>
<li>Listens for mousedown events to keep resetting the last element in focus
<li>Catches the event, and turns on the speech attribute on the target DOM node
</ul>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> last_target <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">;</span>
document.<span style="color: #660066;">addEventListener</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'mousedown'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>event<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    last_target <span style="color: #339933;">=</span> event.<span style="color: #660066;">target</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
chrome.<span style="color: #660066;">extension</span>.<span style="color: #660066;">onRequest</span>.<span style="color: #660066;">addListener</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>event<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    last_target.<span style="color: #660066;">setAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;speech&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;on&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    last_target <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span></pre></div></div>

<p><b>Wire-y wire-y</b></p>
<p>Of course, it all gets wired up in the manifest:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #009900;">&#123;</span>
    <span style="color: #3366CC;">&quot;name&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;Turn on Speech Input&quot;</span><span style="color: #339933;">,</span>
    <span style="color: #3366CC;">&quot;description&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;Turns on the speech attribute, allows you to speak into an input&quot;</span><span style="color: #339933;">,</span>
    <span style="color: #3366CC;">&quot;version&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;0.1&quot;</span><span style="color: #339933;">,</span>
    <span style="color: #3366CC;">&quot;permissions&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span><span style="color: #3366CC;">&quot;contextMenus&quot;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
    <span style="color: #3366CC;">&quot;minimum_chrome_version&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;6&quot;</span><span style="color: #339933;">,</span>
    <span style="color: #3366CC;">&quot;background_page&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;background.html&quot;</span><span style="color: #339933;">,</span>
    <span style="color: #3366CC;">&quot;content_scripts&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#123;</span>
        <span style="color: #3366CC;">&quot;matches&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span><span style="color: #3366CC;">&quot;&lt;all_urls&gt;&quot;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
        <span style="color: #3366CC;">&quot;js&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span><span style="color: #3366CC;">&quot;input-speech.js&quot;</span><span style="color: #009900;">&#93;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#93;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>This <a href="http://github.com/dalmaer/chrome-speaktosite/raw/master/chrome-speaktosite.crx">trivial extension</a> is <a href="http://github.com/dalmaer/chrome-speaktosite">of course on GitHub</a> (I want <a href="http://thechangelog.com/post/1200486354/git-achievements-aquire-achievements-while-using-git">git-achivements</a> after all! :).</p>
<p>A couple of things trouble me though:</p>
<ul>
<li>The microphone icon should sit on the right of the input, however when dynamically tweaked like this it shows up on the left by mistake [BUG]
<li>I have also played with extensions such as <a href="https://chrome.google.com/extensions/detail/jlhhbmloafbaonaondjcedenomeeggda">Google Scribe</a>. Adding icons like this doesn&#8217;t scale. Having them show up all the time gets in my way. I think I want one ability to popup special powers like scribe completion, or speech-to-text, without it getting in my way
<li>When services are built into standard elements like this, it feels like I want to have the ability to tweak how they work (with great defaults of course, as 99.9999% of the time they won&#8217;t be changed.
</ul>
<p>You?</p>
]]></content:encoded>
			<wfw:commentRss>http://almaer.com/blog/chrome-speak-to-site-give-any-input-the-power-to-listen-to-you/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Chrome Win Size; Playing with Chrome extension mechanism</title>
		<link>http://almaer.com/blog/chrome-winsize</link>
		<comments>http://almaer.com/blog/chrome-winsize#comments</comments>
		<pubDate>Mon, 12 Oct 2009 15:52:06 +0000</pubDate>
		<dc:creator>dion</dc:creator>
				<category><![CDATA[Google]]></category>
		<category><![CDATA[chrome]]></category>
		<category><![CDATA[extensions]]></category>

		<guid isPermaLink="false">http://almaer.com/blog/?p=2553</guid>
		<description><![CDATA[I have been watching the work of Aaron and the Chrome Extensions team for awhile. I love that with that effort and Jetpack we are going to see extension creation made simpler and more approachable for Web developers.
I realized that I hadn&#8217;t written a Chrome extension, so I wanted to try it on for size. [...]]]></description>
			<content:encoded><![CDATA[<p>I have been watching the work of <a href="http://blog.youngpup.net/">Aaron</a> and the Chrome Extensions team for awhile. I love that with that effort and <a href="https://jetpack.mozillalabs.com/">Jetpack</a> we are going to see extension creation made simpler and more approachable for Web developers.</p>
<p>I realized that I hadn&#8217;t written a Chrome extension, so I wanted to try it on for size. I thus created an incredibly simple extension that tells you the size of the window on the fly: <a href="http://github.com/dalmaer/chrome-winsize">Chrome Win Size</a>.</p>
<p><img src="http://almaer.com/blog/uploads/chromewinsize.png" alt="chromewinsize" title="chromewinsize" width="500" class="alignnone size-full wp-image-2554" /></p>
<p>In an ideal world this extension would be as easy as:</p>
<ul>
<li>Create a bit of HTML for the tooltip
<li>Attach an onresize handler to the window that changes the HTML
</ul>
<p>Unfortunately, it wasn&#8217;t quite that easy&#8230;. but it was pretty close. The only difference involves the fact that you can&#8217;t easily get the window object to resize.</p>
<p>Here is the entire extension to show how simple it is:</p>
<p><b>Web page for the tool strip</b></p>
<p>For now, I wanted to put the windows size information in the <a href="http://code.google.com/chrome/extensions/toolstrip.html">toolstrip</a>. This isn&#8217;t ideal, especially if you don&#8217;t have other extensions that turn on the toolstrip. It could be nicer to either: have a subtle grey width/height in the background of the URL bar itself; show the info only when a certain keystroke is pressed. That is all for version 0.2 :)</p>
<p>As you will see below, the extension is just a Web page, and the toolstrip is just a div. You could use <code>class="toolstrip-button"</code> but for now a click doesn&#8217;t do anything, so I didn&#8217;t use that. Instead I have a <code>title</code> attribute that uses plain English to explain the info.</p>
<p>Once you have the HTML itself, you also have some JavaScript to do the work. The <code>init</code> kicks things off the first time, but the interesting code is the <code>chrome.extension.onConnect.addListener</code> piece that sets up the extension so that a content script can talk to it via <code>postMessage</code>.</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&lt;html&gt;
&lt;head&gt;
&lt;script&gt;
&nbsp;
// Query the current window (anyone will do) and set the window size in the toolstrip
function showDimensions() {
    chrome.windows.getCurrent(function(w) {
        var el = document.getElementById(&quot;windowsize&quot;);
    	el.innerHTML = w.width + &quot; x &quot; + w.height;
    	el.setAttribute(&quot;title&quot;, &quot;width: &quot; + w.width + &quot;px, height: &quot; + w.height + &quot;px&quot;);
    });
}
&nbsp;
// Listen to the content script and when told there is a change, query again
chrome.extension.onConnect.addListener(function(port, name) {    
  console.assert(name == &quot;resize&quot;);
  port.onMessage.addListener(function() {
      showDimensions();
  });
});
&nbsp;
&lt;/script&gt;
&lt;/head&gt;
&lt;body onload=&quot;showDimensions()&quot;&gt;
  &lt;div id=&quot;windowsize&quot;&gt;&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;</pre></div></div>

<p><b>Content Script</b></p>
<p>Why do we need a content script? Ideally, we would be able to grab a window in the extension and add a resize listener to it and be done. That isn&#8217;t the case right now though. In the code above, the window object that we get in <code>w</code> from <code>chrome.windows.getCurrent(function(w) {...</code> isn&#8217;t a DOM Window, but just something with a <a href="http://code.google.com/chrome/extensions/windows.html#type-Window">few properties</a> (width, height, etc).</p>
<p>To get an actual DOM window, we need to inject a content script and have that talk to the extension. The code is as simple as below&#8230; which does the <code>postMessage()</code> back to the listener that we setup in the extension:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// When the window resizes send a quick message to the extension</span>
window.<span style="color: #660066;">addEventListener</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;resize&quot;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	chrome.<span style="color: #660066;">extension</span>.<span style="color: #660066;">connect</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span><span style="color: #000066;">name</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;resize&quot;</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">postMessage</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p><b>Manifest</b></p>
<p>Now we need to put it all together and that is where the <a href="http://code.google.com/chrome/extensions/manifest.html">manifest</a> comes in. It is here that we tell Chrome where the files are for the toolstrip and content script, and what permissions they have (e.g. give it the tabs permission), as well as metadata:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #009900;">&#123;</span>
  <span style="color: #3366CC;">&quot;name&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;Window Size&quot;</span><span style="color: #339933;">,</span> 
  <span style="color: #3366CC;">&quot;version&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;0.1&quot;</span><span style="color: #339933;">,</span>
  <span style="color: #3366CC;">&quot;description&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;Displays the size of the main window&quot;</span><span style="color: #339933;">,</span>
<span style="color: #009966; font-style: italic;">/*  &quot;icons&quot;: { &quot;128&quot;: &quot;gmail-128x128.png&quot; }, */</span>
  <span style="color: #3366CC;">&quot;permissions&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span>
    <span style="color: #3366CC;">&quot;tabs&quot;</span>
  <span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
  <span style="color: #3366CC;">&quot;toolstrips&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span>
    <span style="color: #3366CC;">&quot;winsize.html&quot;</span>
  <span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
  <span style="color: #3366CC;">&quot;content_scripts&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #3366CC;">&quot;matches&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span><span style="color: #3366CC;">&quot;http://*/*&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;https://*/*&quot;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
      <span style="color: #3366CC;">&quot;js&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span><span style="color: #3366CC;">&quot;contentscript.js&quot;</span><span style="color: #009900;">&#93;</span>
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#93;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p><b>Caveats</b></p>
<p>Even with the content script hack, it is pretty easy to do this kind of thing. It would be nice to do more with the window object as the hack has limitations beyond the extra code. For one, if you are on a page such as <code>chrome://extensions/</code> nothing kicks in (due to the matching). Rather than matching on pages for content scripts to embed, it would be much better to declare that you care about windows themselves.</p>
<p>The toolstrips themselves are a little bulky and ugly, at least on Chrome for Mac (which is very much in beta) and as mentioned earlier&#8230;. unless you are using a bunch of extensions, it feels very unChrome-like to use that space.</p>
<p>FYI: To package an extension on Mac/Linux use this <a href="http://gist.github.com/142422">handy script</a> as the built-in functionality isn&#8217;t there yet.</p>
<p>All in all a decent experience already. Really nice to just work on an HTML document to kick out the functionality. The idealist in me would love to see Jetpack and Chrome Extensions coming together so Web devs had One Way to extend the platform&#8230;&#8230; The Web is in a fortunate position to have folks like <a href="http://blog.youngpup.net/">Aaron Boodman</a>, <a href="http://azarask.in/">Aza Raskin</a>, <a href="http://toolness.com/">Atul Varma</a> and many others on the case of Web extensions.</p>
]]></content:encoded>
			<wfw:commentRss>http://almaer.com/blog/chrome-winsize/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
