<?xml version="1.0" encoding="utf-8" standalone="no"?><rss xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" version="2.0"><channel><title>Ascheriit</title><managingEditor>noemail@noemail.org (Alive Kuo)</managingEditor><pubDate>Mon, 16 Dec 2013 10:33:04 +0800</pubDate><generator>Octopress http://octopress.org/</generator><language>en-us</language><itunes:explicit>no</itunes:explicit><itunes:owner><itunes:email>noemail@noemail.org</itunes:email></itunes:owner><item><title>Migrated to logdown</title><pubDate>Mon, 16 Dec 2013 10:30:00 +0800</pubDate><guid isPermaLink="false">http://alivedise.github.io/blog/2013/12/16/logdown</guid><description>&lt;p&gt;Octopress 雖然很棒但是每次換環境都要重弄實在太麻煩了，
所以我偷偷的轉移到 logdown 一段時間了。&lt;/p&gt;

&lt;p&gt;&lt;a href="http://alivedise.logdown.com"&gt;http://alivedise.logdown.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Welcome to visit!&lt;/p&gt;
</description></item><item><title>[COSCUP 2013] Audio competing in FxOS</title><pubDate>Tue, 6 Aug 2013 17:40:00 +0800</pubDate><guid isPermaLink="false">http://alivedise.github.io/blog/2013/08/06/coscup-2013</guid><description>&lt;p&gt;I gave a presentation about how we implement the audio competing in FxOS in COSCUP.&lt;/p&gt;

&lt;script async="true" class="speakerdeck-embed" data-id="fbfe96a0e1390130ff014239028c3727" src="http://alivedise.github.io//speakerdeck.com/assets/embed.js"&gt; &lt;/script&gt;

</description></item><item><title>[FxOS] Plan: Window Management decoupling (CONT.)</title><pubDate>Thu, 18 Jul 2013 17:33:00 +0800</pubDate><guid isPermaLink="false">http://alivedise.github.io/blog/2013/07/18/window-manager-decoupling</guid><description>&lt;p&gt;Following are the plan about why and how to split current Gaia:System:Window Manager.&lt;/p&gt;

&lt;h2&gt;Sources/Links&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/mozilla-b2g/gaia/blob/master/apps/system/js/window_manager.js"&gt;Window Manager source&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bugzilla.mozilla.org/show_bug.cgi?id=845251"&gt;Window Manager testable meta bug&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;Current main functions in Window Manager&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;App Window Management&lt;/li&gt;
&lt;li&gt;Wrapper Window Management&lt;/li&gt;
&lt;li&gt;Inline Activity Management&lt;/li&gt;
&lt;li&gt;Homescreen Management&lt;/li&gt;
&lt;li&gt;MozBrowser Element Generation&lt;/li&gt;
&lt;li&gt;Orientation Management&lt;/li&gt;
&lt;li&gt;Visibility Management&lt;/li&gt;
&lt;li&gt;Resize Management&lt;/li&gt;
&lt;li&gt;App Screenshots Management [deprecated]&lt;/li&gt;
&lt;li&gt;System Message Handler&lt;/li&gt;
&lt;li&gt;Open app transition&lt;/li&gt;
&lt;li&gt;Close app transition&lt;/li&gt;
&lt;li&gt;FTU Management [deprecated! Become standalone FTU Launcher already!]&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;So which could be pulled out to reduce the heavy weight?&lt;/p&gt;

&lt;!--more--&gt;


&lt;h3&gt;Inline Activity Management &amp;ndash;&gt; App Window&lt;/h3&gt;

&lt;p&gt;Inline Activity Management should belong to the activity caller.&lt;/p&gt;

&lt;p&gt;If app A opens a page(open.html) of app B as an inline activity,
the life cycle of activity callee is based on app A instead of app B.&lt;/p&gt;

&lt;p&gt;Thus, if app A is killed or closed, the activity opened by app A should be killed.&lt;/p&gt;

&lt;p&gt;But if app B(index.html) is killed, activity B(open.html) shouldn&amp;rsquo;t be affected.&lt;/p&gt;

&lt;h3&gt;Resize Management&lt;/h3&gt;

&lt;p&gt;Resize is another duty of the app window instance itself.&lt;/p&gt;

&lt;p&gt;If we&amp;rsquo;re moving the activity into the app window, we could&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Recursively call current activity callee&amp;rsquo;s resize function until the last callee is found.&lt;/li&gt;
&lt;li&gt;Resize all activity callee on top of current app window.&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;in the app window&amp;rsquo;s resize function.&lt;/p&gt;

&lt;h3&gt;Visibility Management&lt;/h3&gt;

&lt;p&gt;App window would have 2 kind of &amp;ldquo;child-like&amp;rdquo; window instance:
* &lt;code&gt;var child = window.open&lt;/code&gt;
* &lt;code&gt;Activity&lt;/code&gt;&lt;/p&gt;
</description></item><item><title>[Fx OS] Background media play</title><pubDate>Tue, 16 Jul 2013 19:16:00 +0800</pubDate><guid isPermaLink="false">http://alivedise.github.io/blog/2013/07/16/audio-competing-in-fxos</guid><description>&lt;p&gt;&lt;img src="https://blog.mozilla.org/press/files/2012/09/FXOS_Music_Grid.jpg"&gt;&lt;/p&gt;

&lt;p&gt;If you want to have you own media playing app to be able to run at background,
and/or has the ability to interrupt other playing audio, please view this article for what to do.&lt;/p&gt;

&lt;!--more--&gt;


&lt;h2&gt;Audio Channel Permission&lt;/h2&gt;

&lt;p&gt;You need to specify this permission in the manifest of your app.&lt;/p&gt;

&lt;p&gt;And yes, this means we don&amp;rsquo;t allow a web page without the manifest to play at background.&lt;/p&gt;

&lt;figure class='code'&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;span class='line-number'&gt;2&lt;/span&gt;
&lt;span class='line-number'&gt;3&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='line'&gt;&lt;span class="s2"&gt;&amp;quot;permissions&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="s2"&gt;&amp;quot;audio-channel-content&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;The &lt;code&gt;content&lt;/code&gt; represents the name of the audio channel.&lt;/p&gt;

&lt;p&gt;Note: Video&amp;rsquo;s permission also uses the same &lt;code&gt;audio-channel-content&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;Audio Channel Types&lt;/h3&gt;

&lt;p&gt;We have five audio channels currently:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;normal&lt;/code&gt;: Default channel of any media element, including video.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;content&lt;/code&gt;: Especailly stands for content like music.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;notification&lt;/code&gt;: Include desktop-notification sounds&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ringer&lt;/code&gt;: Incoming call ringer&lt;/li&gt;
&lt;li&gt;&lt;code&gt;alarm&lt;/code&gt;: Alarm has a specific requirement to interrupt any other channel above.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;telephony&lt;/code&gt;: Voice.&lt;/li&gt;
&lt;/ul&gt;


&lt;h4&gt;Volume Settings&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Normal and content channel are sharing the same volume settings.&lt;/li&gt;
&lt;li&gt;Notification and ringer are another set.&lt;/li&gt;
&lt;li&gt;Other has its own settings key.&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;Audio Competing Rules&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;We&amp;rsquo;re interrupting the lower channel when higher channel occurs.&lt;/li&gt;
&lt;li&gt;If the same channel are playing and using content channel,
the one who gets visibility (go to foreground) would be the winner.&lt;/li&gt;
&lt;li&gt;The foreground page/app is always playable. However the channel type decides it could interrupt background playing content or not.&lt;/li&gt;
&lt;li&gt;The background page/app is playable if and only if the background is causing by screen off,
and the page/app is the current displayed one.&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;I would explain the rules more in another article ;)&lt;/p&gt;

&lt;h2&gt;[Statically] HTML Media Element&lt;/h2&gt;

&lt;p&gt;You could assign audio channel type to the media elements in HTML.&lt;/p&gt;

&lt;figure class='code'&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;span class='line-number'&gt;2&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class='html'&gt;&lt;span class='line'&gt;&lt;span class="nt"&gt;&amp;lt;audio&lt;/span&gt; &lt;span class="na"&gt;mozaudiochannel=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;content&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/audio&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="nt"&gt;&amp;lt;video&lt;/span&gt; &lt;span class="na"&gt;mozaudiochannel=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;content&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/video&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;Please keep in mind you need relevant channel permission.&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;Note: It&amp;#8217;s &lt;code&gt;mozaudiochannel&lt;/code&gt; instead of &lt;code&gt;mozaudiopchanneltype&lt;/code&gt; here.&lt;/p&gt;&lt;/blockquote&gt;


&lt;h2&gt;[Dynamically] Javascript&lt;/h2&gt;

&lt;p&gt;Sometimes we need to dynamically generate the player element:&lt;/p&gt;

&lt;figure class='code'&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;span class='line-number'&gt;2&lt;/span&gt;
&lt;span class='line-number'&gt;3&lt;/span&gt;
&lt;span class='line-number'&gt;4&lt;/span&gt;
&lt;span class='line-number'&gt;5&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='line'&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;audio&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Audio&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="nx"&gt;audio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mozAudioChannelType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;content&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="c1"&gt;// Set audio channel type before setting src to avoid decoder confuses.&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="nx"&gt;audio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;src&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;xxx.ogg&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;Change the channel of the audio to another type is not allowed.&lt;/p&gt;

&lt;p&gt;You should create another audio/video instance if you want to be played in another channel.&lt;/p&gt;

&lt;h2&gt;(OPTIONAL) If you want to know you&amp;rsquo;re interrupted by higher channel&lt;/h2&gt;

&lt;p&gt;Add mozinterruptbegin/mozinterruptend event handler if you need to do something with interruptions.&lt;/p&gt;

&lt;figure class='code'&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;span class='line-number'&gt;2&lt;/span&gt;
&lt;span class='line-number'&gt;3&lt;/span&gt;
&lt;span class='line-number'&gt;4&lt;/span&gt;
&lt;span class='line-number'&gt;5&lt;/span&gt;
&lt;span class='line-number'&gt;6&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='line'&gt;  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;player&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;audio#my-player&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="c1"&gt;// The event is fired on the media element. &lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="nx"&gt;player&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;mozinterruptbegin&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;onInterrupted&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="c1"&gt;//do sth....}); &lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="nx"&gt;player&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;mozinterruptend&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;onResumed&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="c1"&gt;// do sth....}); &lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;h2&gt;Notices&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Even if your are developing a HTML5 video playing app,
and we all know that video shouldn&amp;rsquo;t be played at background due to strange UX,
you should also consider to set content channel because video is expected to interrupt the current background playing media.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;Reference&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://wiki.mozilla.org/WebAPI/AudioChannels"&gt;Mozilla WIKI: Audio Channel&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://groups.google.com/forum/?fromgroups=#!topic/mozilla.dev.gaia/HyAlHdFdX68"&gt;B2G Maillist&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description></item><item><title>Proposal: System Modulization Plan</title><pubDate>Wed, 10 Jul 2013 18:04:00 +0800</pubDate><guid isPermaLink="false">http://alivedise.github.io/blog/2013/07/10/system-modulization-plan</guid><description>&lt;h4&gt;Source&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://github.com/mozilla-b2g/gaia/tree/master/apps/system"&gt;https://github.com/mozilla-b2g/gaia/tree/master/apps/system&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;Issues with Modulization-less&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Some modules directly invokes others.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lsquo;LockScreen is undefined.&amp;rsquo;&lt;/code&gt; message appears oftenly right after device boots up.&lt;/li&gt;
&lt;li&gt;Memory concern &amp;ndash; Most of the modules are not always needed. Most of the UI view doesn&amp;rsquo;t need to live in the DOM tree at first.&lt;/li&gt;
&lt;li&gt;Performance concern &amp;ndash; device bootup time is getting longer and longer.&lt;/li&gt;
&lt;/ol&gt;


&lt;!--more--&gt;


&lt;h4&gt;Proposal: Core modules and side modules&lt;/h4&gt;

&lt;p&gt;We could figure out what&amp;rsquo;s definitely necessary in an operating system and what&amp;rsquo;s not.
For example, &lt;code&gt;Window Management&lt;/code&gt; relevant modules should be a core module but &lt;code&gt;Captive Portal&lt;/code&gt; shouldn&amp;rsquo;t be.&lt;/p&gt;

&lt;p&gt;The main idea is the same as any other app performanace tuning:
Lazy load anything on demand.&lt;/p&gt;

&lt;p&gt;The key to this idea would be to establish the following rules:
* Any side module would have a main event by interest.
* An event dispatcher as a core module to gather all main events of side modules and then lazy load them.
For example, lazy load the Captive Portal:&lt;/p&gt;

&lt;figure class='code'&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;span class='line-number'&gt;2&lt;/span&gt;
&lt;span class='line-number'&gt;3&lt;/span&gt;
&lt;span class='line-number'&gt;4&lt;/span&gt;
&lt;span class='line-number'&gt;5&lt;/span&gt;
&lt;span class='line-number'&gt;6&lt;/span&gt;
&lt;span class='line-number'&gt;7&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='line'&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;mozChromeEvent&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;detail&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;captive-portal-login&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;CaptivePortal&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;undefined&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="nx"&gt;lazy&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;captive-portal&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;onReadyCallback&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;   &lt;span class="c1"&gt;// lazy load captive portal and its HTML part.&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="nx"&gt;CaptivePortal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;handleEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// Pass the event&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="p"&gt;}&lt;/span&gt;  &lt;span class="c1"&gt;// If we have already load the CaptivePortal, the event listener inside CP would catch the event by itself.&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;So another rule would be:
* expose handleEvent in any side module for Event Dispatcher to invoke when they are firt time loaded by Event Dispatcher.&lt;/p&gt;

&lt;p&gt;With this, we could even lazy load lockscreen,
because if lockscreen is disabled by the user, we don&amp;rsquo;t need to load it when the device boots.&lt;/p&gt;

&lt;p&gt;IMO there&amp;rsquo;re only few core modules now:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Window Management

&lt;ul&gt;
&lt;li&gt;App Window&lt;/li&gt;
&lt;li&gt;Browser Frame&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Utility-tray&lt;/li&gt;
&lt;li&gt;Statusbar&lt;/li&gt;
&lt;li&gt;Init Logo Handler (But this is useless after device boot finishes.)&lt;/li&gt;
&lt;li&gt;Screen Management (Exactly, it&amp;rsquo;s indeed Wake Lock Management)&lt;/li&gt;
&lt;li&gt;Applications (API Wrapper for mozApp)&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;The following are API wrappers which I believe is also important enough to be a core module.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hardware Button Management (Many other modules&amp;#8217; execution route is started here.)&lt;/li&gt;
&lt;li&gt;Battery Management (UI-less but more like an API wrapper for mozBattery so I would put this into core module.)&lt;/li&gt;
&lt;li&gt;Airplane Mode (API Wrapper of mozSettings: radio.enabled)&lt;/li&gt;
&lt;li&gt;Bluetooth (API Wrapper for mozBluetooth)&lt;/li&gt;
&lt;li&gt;Cost Control (It already lives inside an iframe.)&lt;/li&gt;
&lt;li&gt;Ftu Launcher (Necessary only for one time when device is first time booted.)&lt;/li&gt;
&lt;li&gt;Keyboard Management&lt;/li&gt;
&lt;li&gt;mouse2touch&lt;/li&gt;
&lt;li&gt;Notifications&lt;/li&gt;
&lt;li&gt;Orientation observer (API Wrapper for deviceorientation event)&lt;/li&gt;
&lt;li&gt;Sound manager (There are too many events involed here.)&lt;/li&gt;
&lt;li&gt;Update Management&lt;/li&gt;
&lt;/ul&gt;


&lt;h5&gt;Chanllenge&lt;/h5&gt;

&lt;p&gt;If we want to &amp;ldquo;unload&amp;rdquo; the module and its view using iframe,
we need a way for modules inside iframe to communicate.
The first thing come to my mind is &lt;code&gt;window.parent.postMessage&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Second, we need to consider dependency problems if it&amp;rsquo;s too complex.&lt;/p&gt;
</description></item><item><title>[Window Management] Transition state machine</title><pubDate>Fri, 5 Jul 2013 14:53:00 +0800</pubDate><guid isPermaLink="false">http://alivedise.github.io/blog/2013/07/05/transition-state-machine</guid><description>&lt;p&gt;The article is inspired by Tim&amp;rsquo;s &lt;a href="http://blog.timc.idv.tw/posts/css-classes-state-machine-puzzle/"&gt;CSS Classes State Machine Puzzle&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We had some frustrations all the times, on animating a window correctly.&lt;/p&gt;

&lt;p&gt;Recently I try to dedicate on solving the puzzle.
But at first I need to apologize for my poor knowledge and thought about css transitions using class names.&lt;/p&gt;

&lt;!--more--&gt;


&lt;p&gt;In the past I usually thought it was stupid to use class list to control the style.
I thought it was ambiguous and strange if we ran into a situation that there&amp;rsquo;re more than one classes of same type put on one element. And an element full of different class names for different purposes may conflict. Recently I see &lt;a href="https://github.com/h5bp/Effeckt.css"&gt;Effeckt&lt;/a&gt; and know this is the trend: a simple class name stands for a kind of animation.&lt;/p&gt;

&lt;p&gt;The real problem is that we should never put wrong class on the DOM element, in javascript. So this now turns to be a pure javascript puzzle.&lt;/p&gt;

&lt;p&gt;We know, that, in certain moment, the app window is always in a specific state A, not B nor C. So what&amp;rsquo;s the problem? It&amp;rsquo;s how could we switch the state correctly.&lt;/p&gt;

&lt;p&gt;Let&amp;rsquo;s create a real state machine in javascript!&lt;/p&gt;

&lt;p&gt;So far it doesn&amp;rsquo;t take times for us to figure out that a window should have 4 basic transition state: &lt;code&gt;closed&lt;/code&gt;, &lt;code&gt;opening&lt;/code&gt;, &lt;code&gt;opened&lt;/code&gt;, &lt;code&gt;closing&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A basic transition life cycle of a window could be:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;(initial) -&gt; closed -&gt; opening -&gt; opened &amp;#8212;&amp;#8212;&gt; closing -&gt; opening &amp;#8212;&amp;#8212;&gt; &amp;#8230;.&lt;/p&gt;&lt;/blockquote&gt;


&lt;p&gt;Now we have 4 states, the next is what&amp;rsquo;s the trigger to states switching?&lt;/p&gt;

&lt;p&gt;In finite state machine, what triggers state change is named for &lt;a href="https://en.wikipedia.org/wiki/Finite-state_machine"&gt;&amp;lsquo;event&amp;rsquo;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We know that at least we have 2 events: &amp;lsquo;open&amp;rsquo; and &amp;lsquo;close&amp;rsquo;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&amp;lsquo;open&amp;rsquo; would trigger &lt;code&gt;closed&lt;/code&gt; switches to &lt;code&gt;opening&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&amp;lsquo;close&amp;rsquo; would trigger &lt;code&gt;opened&lt;/code&gt; switches to &lt;code&gt;closing&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;If we sends &amp;lsquo;open&amp;rsquo; event into the state machine continously,
the second event would be ignored.
(Exactly it depends on what policy we choose. For example, we could devide &amp;lsquo;opening&amp;rsquo; state into &amp;lsquo;opening-part-1&amp;rsquo; and &amp;lsquo;opening-part-2&amp;rsquo; states. And implement the async state change. But if we need s two-state opening, it sounds like a CSS design problem to me. Let&amp;rsquo;s discuss this later if necessary.)&lt;/li&gt;
&lt;li&gt;In order to gurantee the transition does really end and thus being independent from the &amp;lsquo;animationend&amp;rsquo; event(The event here is HTML DOM Event), we need to add a timer between &amp;lsquo;opening&amp;rsquo; and &amp;lsquo;opened&amp;rsquo; state. Also between &amp;lsquo;closing&amp;rsquo; and &amp;lsquo;closed&amp;rsquo; state.&lt;/li&gt;
&lt;li&gt;Let&amp;rsquo;s call the new event &amp;lsquo;timeout&amp;rsquo;, the timing we set the timer is right after the transitioning from &amp;lsquo;closed&amp;rsquo; to &amp;lsquo;opening&amp;rsquo;, and from &amp;lsquo;opened&amp;rsquo; to &amp;lsquo;closing&amp;rsquo; successfully occurs.&lt;/li&gt;
&lt;li&gt;For some use case we may want to cancel the transition. The &amp;lsquo;cancel&amp;rsquo; event is only valid in &amp;lsquo;opening&amp;rsquo; and &amp;lsquo;closing&amp;rsquo; state.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;So far, the state machine for transition we have:
&lt;img src="http://i.imgur.com/MmBj2pY.jpg"&gt;&lt;/p&gt;

&lt;p&gt;Now the problem is, how to represent this machine in javascript?&lt;/p&gt;

&lt;p&gt;My anwser is put every transition relevant functions/attributes in another mixin object, which would be mixed into appWindow.prototype:&lt;/p&gt;

&lt;figure class='code'&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;span class='line-number'&gt;2&lt;/span&gt;
&lt;span class='line-number'&gt;3&lt;/span&gt;
&lt;span class='line-number'&gt;4&lt;/span&gt;
&lt;span class='line-number'&gt;5&lt;/span&gt;
&lt;span class='line-number'&gt;6&lt;/span&gt;
&lt;span class='line-number'&gt;7&lt;/span&gt;
&lt;span class='line-number'&gt;8&lt;/span&gt;
&lt;span class='line-number'&gt;9&lt;/span&gt;
&lt;span class='line-number'&gt;10&lt;/span&gt;
&lt;span class='line-number'&gt;11&lt;/span&gt;
&lt;span class='line-number'&gt;12&lt;/span&gt;
&lt;span class='line-number'&gt;13&lt;/span&gt;
&lt;span class='line-number'&gt;14&lt;/span&gt;
&lt;span class='line-number'&gt;15&lt;/span&gt;
&lt;span class='line-number'&gt;16&lt;/span&gt;
&lt;span class='line-number'&gt;17&lt;/span&gt;
&lt;span class='line-number'&gt;18&lt;/span&gt;
&lt;span class='line-number'&gt;19&lt;/span&gt;
&lt;span class='line-number'&gt;20&lt;/span&gt;
&lt;span class='line-number'&gt;21&lt;/span&gt;
&lt;span class='line-number'&gt;22&lt;/span&gt;
&lt;span class='line-number'&gt;23&lt;/span&gt;
&lt;span class='line-number'&gt;24&lt;/span&gt;
&lt;span class='line-number'&gt;25&lt;/span&gt;
&lt;span class='line-number'&gt;26&lt;/span&gt;
&lt;span class='line-number'&gt;27&lt;/span&gt;
&lt;span class='line-number'&gt;28&lt;/span&gt;
&lt;span class='line-number'&gt;29&lt;/span&gt;
&lt;span class='line-number'&gt;30&lt;/span&gt;
&lt;span class='line-number'&gt;31&lt;/span&gt;
&lt;span class='line-number'&gt;32&lt;/span&gt;
&lt;span class='line-number'&gt;33&lt;/span&gt;
&lt;span class='line-number'&gt;34&lt;/span&gt;
&lt;span class='line-number'&gt;35&lt;/span&gt;
&lt;span class='line-number'&gt;36&lt;/span&gt;
&lt;span class='line-number'&gt;37&lt;/span&gt;
&lt;span class='line-number'&gt;38&lt;/span&gt;
&lt;span class='line-number'&gt;39&lt;/span&gt;
&lt;span class='line-number'&gt;40&lt;/span&gt;
&lt;span class='line-number'&gt;41&lt;/span&gt;
&lt;span class='line-number'&gt;42&lt;/span&gt;
&lt;span class='line-number'&gt;43&lt;/span&gt;
&lt;span class='line-number'&gt;44&lt;/span&gt;
&lt;span class='line-number'&gt;45&lt;/span&gt;
&lt;span class='line-number'&gt;46&lt;/span&gt;
&lt;span class='line-number'&gt;47&lt;/span&gt;
&lt;span class='line-number'&gt;48&lt;/span&gt;
&lt;span class='line-number'&gt;49&lt;/span&gt;
&lt;span class='line-number'&gt;50&lt;/span&gt;
&lt;span class='line-number'&gt;51&lt;/span&gt;
&lt;span class='line-number'&gt;52&lt;/span&gt;
&lt;span class='line-number'&gt;53&lt;/span&gt;
&lt;span class='line-number'&gt;54&lt;/span&gt;
&lt;span class='line-number'&gt;55&lt;/span&gt;
&lt;span class='line-number'&gt;56&lt;/span&gt;
&lt;span class='line-number'&gt;57&lt;/span&gt;
&lt;span class='line-number'&gt;58&lt;/span&gt;
&lt;span class='line-number'&gt;59&lt;/span&gt;
&lt;span class='line-number'&gt;60&lt;/span&gt;
&lt;span class='line-number'&gt;61&lt;/span&gt;
&lt;span class='line-number'&gt;62&lt;/span&gt;
&lt;span class='line-number'&gt;63&lt;/span&gt;
&lt;span class='line-number'&gt;64&lt;/span&gt;
&lt;span class='line-number'&gt;65&lt;/span&gt;
&lt;span class='line-number'&gt;66&lt;/span&gt;
&lt;span class='line-number'&gt;67&lt;/span&gt;
&lt;span class='line-number'&gt;68&lt;/span&gt;
&lt;span class='line-number'&gt;69&lt;/span&gt;
&lt;span class='line-number'&gt;70&lt;/span&gt;
&lt;span class='line-number'&gt;71&lt;/span&gt;
&lt;span class='line-number'&gt;72&lt;/span&gt;
&lt;span class='line-number'&gt;73&lt;/span&gt;
&lt;span class='line-number'&gt;74&lt;/span&gt;
&lt;span class='line-number'&gt;75&lt;/span&gt;
&lt;span class='line-number'&gt;76&lt;/span&gt;
&lt;span class='line-number'&gt;77&lt;/span&gt;
&lt;span class='line-number'&gt;78&lt;/span&gt;
&lt;span class='line-number'&gt;79&lt;/span&gt;
&lt;span class='line-number'&gt;80&lt;/span&gt;
&lt;span class='line-number'&gt;81&lt;/span&gt;
&lt;span class='line-number'&gt;82&lt;/span&gt;
&lt;span class='line-number'&gt;83&lt;/span&gt;
&lt;span class='line-number'&gt;84&lt;/span&gt;
&lt;span class='line-number'&gt;85&lt;/span&gt;
&lt;span class='line-number'&gt;86&lt;/span&gt;
&lt;span class='line-number'&gt;87&lt;/span&gt;
&lt;span class='line-number'&gt;88&lt;/span&gt;
&lt;span class='line-number'&gt;89&lt;/span&gt;
&lt;span class='line-number'&gt;90&lt;/span&gt;
&lt;span class='line-number'&gt;91&lt;/span&gt;
&lt;span class='line-number'&gt;92&lt;/span&gt;
&lt;span class='line-number'&gt;93&lt;/span&gt;
&lt;span class='line-number'&gt;94&lt;/span&gt;
&lt;span class='line-number'&gt;95&lt;/span&gt;
&lt;span class='line-number'&gt;96&lt;/span&gt;
&lt;span class='line-number'&gt;97&lt;/span&gt;
&lt;span class='line-number'&gt;98&lt;/span&gt;
&lt;span class='line-number'&gt;99&lt;/span&gt;
&lt;span class='line-number'&gt;100&lt;/span&gt;
&lt;span class='line-number'&gt;101&lt;/span&gt;
&lt;span class='line-number'&gt;102&lt;/span&gt;
&lt;span class='line-number'&gt;103&lt;/span&gt;
&lt;span class='line-number'&gt;104&lt;/span&gt;
&lt;span class='line-number'&gt;105&lt;/span&gt;
&lt;span class='line-number'&gt;106&lt;/span&gt;
&lt;span class='line-number'&gt;107&lt;/span&gt;
&lt;span class='line-number'&gt;108&lt;/span&gt;
&lt;span class='line-number'&gt;109&lt;/span&gt;
&lt;span class='line-number'&gt;110&lt;/span&gt;
&lt;span class='line-number'&gt;111&lt;/span&gt;
&lt;span class='line-number'&gt;112&lt;/span&gt;
&lt;span class='line-number'&gt;113&lt;/span&gt;
&lt;span class='line-number'&gt;114&lt;/span&gt;
&lt;span class='line-number'&gt;115&lt;/span&gt;
&lt;span class='line-number'&gt;116&lt;/span&gt;
&lt;span class='line-number'&gt;117&lt;/span&gt;
&lt;span class='line-number'&gt;118&lt;/span&gt;
&lt;span class='line-number'&gt;119&lt;/span&gt;
&lt;span class='line-number'&gt;120&lt;/span&gt;
&lt;span class='line-number'&gt;121&lt;/span&gt;
&lt;span class='line-number'&gt;122&lt;/span&gt;
&lt;span class='line-number'&gt;123&lt;/span&gt;
&lt;span class='line-number'&gt;124&lt;/span&gt;
&lt;span class='line-number'&gt;125&lt;/span&gt;
&lt;span class='line-number'&gt;126&lt;/span&gt;
&lt;span class='line-number'&gt;127&lt;/span&gt;
&lt;span class='line-number'&gt;128&lt;/span&gt;
&lt;span class='line-number'&gt;129&lt;/span&gt;
&lt;span class='line-number'&gt;130&lt;/span&gt;
&lt;span class='line-number'&gt;131&lt;/span&gt;
&lt;span class='line-number'&gt;132&lt;/span&gt;
&lt;span class='line-number'&gt;133&lt;/span&gt;
&lt;span class='line-number'&gt;134&lt;/span&gt;
&lt;span class='line-number'&gt;135&lt;/span&gt;
&lt;span class='line-number'&gt;136&lt;/span&gt;
&lt;span class='line-number'&gt;137&lt;/span&gt;
&lt;span class='line-number'&gt;138&lt;/span&gt;
&lt;span class='line-number'&gt;139&lt;/span&gt;
&lt;span class='line-number'&gt;140&lt;/span&gt;
&lt;span class='line-number'&gt;141&lt;/span&gt;
&lt;span class='line-number'&gt;142&lt;/span&gt;
&lt;span class='line-number'&gt;143&lt;/span&gt;
&lt;span class='line-number'&gt;144&lt;/span&gt;
&lt;span class='line-number'&gt;145&lt;/span&gt;
&lt;span class='line-number'&gt;146&lt;/span&gt;
&lt;span class='line-number'&gt;147&lt;/span&gt;
&lt;span class='line-number'&gt;148&lt;/span&gt;
&lt;span class='line-number'&gt;149&lt;/span&gt;
&lt;span class='line-number'&gt;150&lt;/span&gt;
&lt;span class='line-number'&gt;151&lt;/span&gt;
&lt;span class='line-number'&gt;152&lt;/span&gt;
&lt;span class='line-number'&gt;153&lt;/span&gt;
&lt;span class='line-number'&gt;154&lt;/span&gt;
&lt;span class='line-number'&gt;155&lt;/span&gt;
&lt;span class='line-number'&gt;156&lt;/span&gt;
&lt;span class='line-number'&gt;157&lt;/span&gt;
&lt;span class='line-number'&gt;158&lt;/span&gt;
&lt;span class='line-number'&gt;159&lt;/span&gt;
&lt;span class='line-number'&gt;160&lt;/span&gt;
&lt;span class='line-number'&gt;161&lt;/span&gt;
&lt;span class='line-number'&gt;162&lt;/span&gt;
&lt;span class='line-number'&gt;163&lt;/span&gt;
&lt;span class='line-number'&gt;164&lt;/span&gt;
&lt;span class='line-number'&gt;165&lt;/span&gt;
&lt;span class='line-number'&gt;166&lt;/span&gt;
&lt;span class='line-number'&gt;167&lt;/span&gt;
&lt;span class='line-number'&gt;168&lt;/span&gt;
&lt;span class='line-number'&gt;169&lt;/span&gt;
&lt;span class='line-number'&gt;170&lt;/span&gt;
&lt;span class='line-number'&gt;171&lt;/span&gt;
&lt;span class='line-number'&gt;172&lt;/span&gt;
&lt;span class='line-number'&gt;173&lt;/span&gt;
&lt;span class='line-number'&gt;174&lt;/span&gt;
&lt;span class='line-number'&gt;175&lt;/span&gt;
&lt;span class='line-number'&gt;176&lt;/span&gt;
&lt;span class='line-number'&gt;177&lt;/span&gt;
&lt;span class='line-number'&gt;178&lt;/span&gt;
&lt;span class='line-number'&gt;179&lt;/span&gt;
&lt;span class='line-number'&gt;180&lt;/span&gt;
&lt;span class='line-number'&gt;181&lt;/span&gt;
&lt;span class='line-number'&gt;182&lt;/span&gt;
&lt;span class='line-number'&gt;183&lt;/span&gt;
&lt;span class='line-number'&gt;184&lt;/span&gt;
&lt;span class='line-number'&gt;185&lt;/span&gt;
&lt;span class='line-number'&gt;186&lt;/span&gt;
&lt;span class='line-number'&gt;187&lt;/span&gt;
&lt;span class='line-number'&gt;188&lt;/span&gt;
&lt;span class='line-number'&gt;189&lt;/span&gt;
&lt;span class='line-number'&gt;190&lt;/span&gt;
&lt;span class='line-number'&gt;191&lt;/span&gt;
&lt;span class='line-number'&gt;192&lt;/span&gt;
&lt;span class='line-number'&gt;193&lt;/span&gt;
&lt;span class='line-number'&gt;194&lt;/span&gt;
&lt;span class='line-number'&gt;195&lt;/span&gt;
&lt;span class='line-number'&gt;196&lt;/span&gt;
&lt;span class='line-number'&gt;197&lt;/span&gt;
&lt;span class='line-number'&gt;198&lt;/span&gt;
&lt;span class='line-number'&gt;199&lt;/span&gt;
&lt;span class='line-number'&gt;200&lt;/span&gt;
&lt;span class='line-number'&gt;201&lt;/span&gt;
&lt;span class='line-number'&gt;202&lt;/span&gt;
&lt;span class='line-number'&gt;203&lt;/span&gt;
&lt;span class='line-number'&gt;204&lt;/span&gt;
&lt;span class='line-number'&gt;205&lt;/span&gt;
&lt;span class='line-number'&gt;206&lt;/span&gt;
&lt;span class='line-number'&gt;207&lt;/span&gt;
&lt;span class='line-number'&gt;208&lt;/span&gt;
&lt;span class='line-number'&gt;209&lt;/span&gt;
&lt;span class='line-number'&gt;210&lt;/span&gt;
&lt;span class='line-number'&gt;211&lt;/span&gt;
&lt;span class='line-number'&gt;212&lt;/span&gt;
&lt;span class='line-number'&gt;213&lt;/span&gt;
&lt;span class='line-number'&gt;214&lt;/span&gt;
&lt;span class='line-number'&gt;215&lt;/span&gt;
&lt;span class='line-number'&gt;216&lt;/span&gt;
&lt;span class='line-number'&gt;217&lt;/span&gt;
&lt;span class='line-number'&gt;218&lt;/span&gt;
&lt;span class='line-number'&gt;219&lt;/span&gt;
&lt;span class='line-number'&gt;220&lt;/span&gt;
&lt;span class='line-number'&gt;221&lt;/span&gt;
&lt;span class='line-number'&gt;222&lt;/span&gt;
&lt;span class='line-number'&gt;223&lt;/span&gt;
&lt;span class='line-number'&gt;224&lt;/span&gt;
&lt;span class='line-number'&gt;225&lt;/span&gt;
&lt;span class='line-number'&gt;226&lt;/span&gt;
&lt;span class='line-number'&gt;227&lt;/span&gt;
&lt;span class='line-number'&gt;228&lt;/span&gt;
&lt;span class='line-number'&gt;229&lt;/span&gt;
&lt;span class='line-number'&gt;230&lt;/span&gt;
&lt;span class='line-number'&gt;231&lt;/span&gt;
&lt;span class='line-number'&gt;232&lt;/span&gt;
&lt;span class='line-number'&gt;233&lt;/span&gt;
&lt;span class='line-number'&gt;234&lt;/span&gt;
&lt;span class='line-number'&gt;235&lt;/span&gt;
&lt;span class='line-number'&gt;236&lt;/span&gt;
&lt;span class='line-number'&gt;237&lt;/span&gt;
&lt;span class='line-number'&gt;238&lt;/span&gt;
&lt;span class='line-number'&gt;239&lt;/span&gt;
&lt;span class='line-number'&gt;240&lt;/span&gt;
&lt;span class='line-number'&gt;241&lt;/span&gt;
&lt;span class='line-number'&gt;242&lt;/span&gt;
&lt;span class='line-number'&gt;243&lt;/span&gt;
&lt;span class='line-number'&gt;244&lt;/span&gt;
&lt;span class='line-number'&gt;245&lt;/span&gt;
&lt;span class='line-number'&gt;246&lt;/span&gt;
&lt;span class='line-number'&gt;247&lt;/span&gt;
&lt;span class='line-number'&gt;248&lt;/span&gt;
&lt;span class='line-number'&gt;249&lt;/span&gt;
&lt;span class='line-number'&gt;250&lt;/span&gt;
&lt;span class='line-number'&gt;251&lt;/span&gt;
&lt;span class='line-number'&gt;252&lt;/span&gt;
&lt;span class='line-number'&gt;253&lt;/span&gt;
&lt;span class='line-number'&gt;254&lt;/span&gt;
&lt;span class='line-number'&gt;255&lt;/span&gt;
&lt;span class='line-number'&gt;256&lt;/span&gt;
&lt;span class='line-number'&gt;257&lt;/span&gt;
&lt;span class='line-number'&gt;258&lt;/span&gt;
&lt;span class='line-number'&gt;259&lt;/span&gt;
&lt;span class='line-number'&gt;260&lt;/span&gt;
&lt;span class='line-number'&gt;261&lt;/span&gt;
&lt;span class='line-number'&gt;262&lt;/span&gt;
&lt;span class='line-number'&gt;263&lt;/span&gt;
&lt;span class='line-number'&gt;264&lt;/span&gt;
&lt;span class='line-number'&gt;265&lt;/span&gt;
&lt;span class='line-number'&gt;266&lt;/span&gt;
&lt;span class='line-number'&gt;267&lt;/span&gt;
&lt;span class='line-number'&gt;268&lt;/span&gt;
&lt;span class='line-number'&gt;269&lt;/span&gt;
&lt;span class='line-number'&gt;270&lt;/span&gt;
&lt;span class='line-number'&gt;271&lt;/span&gt;
&lt;span class='line-number'&gt;272&lt;/span&gt;
&lt;span class='line-number'&gt;273&lt;/span&gt;
&lt;span class='line-number'&gt;274&lt;/span&gt;
&lt;span class='line-number'&gt;275&lt;/span&gt;
&lt;span class='line-number'&gt;276&lt;/span&gt;
&lt;span class='line-number'&gt;277&lt;/span&gt;
&lt;span class='line-number'&gt;278&lt;/span&gt;
&lt;span class='line-number'&gt;279&lt;/span&gt;
&lt;span class='line-number'&gt;280&lt;/span&gt;
&lt;span class='line-number'&gt;281&lt;/span&gt;
&lt;span class='line-number'&gt;282&lt;/span&gt;
&lt;span class='line-number'&gt;283&lt;/span&gt;
&lt;span class='line-number'&gt;284&lt;/span&gt;
&lt;span class='line-number'&gt;285&lt;/span&gt;
&lt;span class='line-number'&gt;286&lt;/span&gt;
&lt;span class='line-number'&gt;287&lt;/span&gt;
&lt;span class='line-number'&gt;288&lt;/span&gt;
&lt;span class='line-number'&gt;289&lt;/span&gt;
&lt;span class='line-number'&gt;290&lt;/span&gt;
&lt;span class='line-number'&gt;291&lt;/span&gt;
&lt;span class='line-number'&gt;292&lt;/span&gt;
&lt;span class='line-number'&gt;293&lt;/span&gt;
&lt;span class='line-number'&gt;294&lt;/span&gt;
&lt;span class='line-number'&gt;295&lt;/span&gt;
&lt;span class='line-number'&gt;296&lt;/span&gt;
&lt;span class='line-number'&gt;297&lt;/span&gt;
&lt;span class='line-number'&gt;298&lt;/span&gt;
&lt;span class='line-number'&gt;299&lt;/span&gt;
&lt;span class='line-number'&gt;300&lt;/span&gt;
&lt;span class='line-number'&gt;301&lt;/span&gt;
&lt;span class='line-number'&gt;302&lt;/span&gt;
&lt;span class='line-number'&gt;303&lt;/span&gt;
&lt;span class='line-number'&gt;304&lt;/span&gt;
&lt;span class='line-number'&gt;305&lt;/span&gt;
&lt;span class='line-number'&gt;306&lt;/span&gt;
&lt;span class='line-number'&gt;307&lt;/span&gt;
&lt;span class='line-number'&gt;308&lt;/span&gt;
&lt;span class='line-number'&gt;309&lt;/span&gt;
&lt;span class='line-number'&gt;310&lt;/span&gt;
&lt;span class='line-number'&gt;311&lt;/span&gt;
&lt;span class='line-number'&gt;312&lt;/span&gt;
&lt;span class='line-number'&gt;313&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='line'&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="s1"&gt;&amp;#39;use strict&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;capitalize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;charAt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toUpperCase&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="cm"&gt;/**&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   * This object declares all transition event enum:&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   *&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   * * OPEN&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   * * CLOSE&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   * * FINISH&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   * * END&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   * * CANCEL&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   *&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   * @static&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   * @namespace TransitionEvent&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   * @type {Object}&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   */&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;EVT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="nx"&gt;OPEN&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="nx"&gt;CLOSE&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="nx"&gt;FINISH&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="nx"&gt;END&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="nx"&gt;CANCEL&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;_EVTARRAY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;OPEN&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;CLOSE&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;FINISH&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;END&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;CANCEL&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="cm"&gt;/**&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   * Describe the transition state table.&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   *&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   * @example&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   * var toState = transitionTable[currentState][event];&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   *&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   * The value &amp;quot;null&amp;quot; indicates that the transition won&amp;#39;t happen.&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   * &lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   * @type {Object}&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   */&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;transitionTable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;              &lt;span class="cm"&gt;/* OPEN|CLOSE|FINISH|END|CANCEL */&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="s1"&gt;&amp;#39;closed&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;opening&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="s1"&gt;&amp;#39;opened&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;closing&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="s1"&gt;&amp;#39;closing&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;opened&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;closed&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;closed&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;opened&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="s1"&gt;&amp;#39;opening&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;closed&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;opened&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;opened&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;closed&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="cm"&gt;/**&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   * This provides methods and attributes used for transition state handling. It&amp;#39;s not meant to&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   * be used directly.&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   *&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   * The finite state machine of transition is working as(being from normal state):&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   * &lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   * * `closed`  ---*event* **OPEN** ----------------&amp;gt; `opening`&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   * * `opening` ---*event* **END/FINISH/CANCEL** ---&amp;gt; `opened`&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   * * `opened`  ---*event* **CLOSE** ---------------&amp;gt; `closing`&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   * * `closing` ---*event* **END/FINISH/CANCEL** ---&amp;gt; `closed`&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   *&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   * If you want to reuse this mixin in your object, you need to define these attributes: `this.element`&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   *&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   * And these method: `this.setVisible()` `this.publish()`&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   *&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   * The following callback functions are executed only when the transition state are successfully switched:&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   * `_onOpen`&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   * `_onClose`&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   * `_onEnd`&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   * `_onFinish`&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   * `_onCancel`&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   * `_leaveOpened`&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   * `_enterOpened`&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   * `_leaveClosed`&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   * `_enterClosed`&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   * `_leaveClosing`&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   * `_enterClosing`&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   * `_leaveOpening`&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   * `_enterOpening`&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   *&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   * Every callback here is for internal usage and would be executed only once.&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   *&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   * However you could utilize inner event in other functions.&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   * &lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   *&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   * @mixin WindowTransition&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   */&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="cm"&gt;/**&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   * @event AppWindow#_onTransitionOpen&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   * @private&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   * @memberof AppWindow&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   */&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="cm"&gt;/**&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   * @event AppWindow#_onTransitionClose&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   * @private&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   * @memberof AppWindow&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   */&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="cm"&gt;/**&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   * @event AppWindow#_onTransitionEnd&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   * @private&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   * @memberof AppWindow&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   */&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="cm"&gt;/**&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   * @event AppWindow#_onTransitionFinish&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   * @private&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   * @memberof AppWindow&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   */&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="cm"&gt;/**&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   * @event AppWindow#_onTransitionCancel&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   * @private&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   * @memberof AppWindow&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   */&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;WindowTransition&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="nx"&gt;TRANSITION_EVENT&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;EVT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="cm"&gt;/**&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;     * _transitionState indicates current transition state of appWindow.&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;     *&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;     * @memberOf WindowTransition&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;     * @default&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;     * @type {String}&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;     */&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="nx"&gt;_transitionState&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;closed&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="cm"&gt;/**&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;     * Record the previous transition state.&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;     *&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;     * **Only updated if the state changes successfully.**&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;     * &lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;     * @type {String|null}&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;     * @memberOf WindowTransition&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;     */&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="nx"&gt;_previousTransitionState&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="cm"&gt;/**&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;     * Handle the transition event.&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;     * @memberOf WindowTransition&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;     */&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="nx"&gt;_transitionHandler&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;aw__transitionHandler&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_cancelTransition&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_processTransitionEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;EVT&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;FINISH&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="nx"&gt;_cancelTransition&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;aw__cancelTransition&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/\s+/&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;indexOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;transition-&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;          &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="nx"&gt;_enterOpening&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;aw__enterOpening&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;evt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="cm"&gt;/**&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;       * @todo set this._unloaded&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;       */&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_unloaded&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="c1"&gt;//this.element.style.backgroundImage = &amp;#39;url(&amp;#39; + this._splash + &amp;#39;)&amp;#39;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="c1"&gt;// Turn of visibility once we&amp;#39;re entering opening state.&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setVisible&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="c1"&gt;// Make sure the transition is terminated.&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_openingTransitionTimer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_previousTransitionState&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_previousTransitionState&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nx"&gt;from&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_transitionState&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;          &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_processTransitionEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;EVT&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;END&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="p"&gt;}.&lt;/span&gt;&lt;span class="nx"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_transitionTimeout&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mf"&gt;1.2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="cm"&gt;/**&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;       * @event AppWindow#appwillopen&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;       * @memberof AppWindow&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;       */&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;from&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;opened&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="c1"&gt;// Only publish |willopen| event when previous state is &amp;quot;closed&amp;quot;.&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;willopen&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;transition-opening&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_transition&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;open&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="nx"&gt;_enterClosing&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;aw__enterClosing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;evt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="c1"&gt;// Make sure the transition is terminated.&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_closingTransitionTimer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_previousTransitionState&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_previousTransitionState&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nx"&gt;from&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_transitionState&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;          &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_processTransitionEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;EVT&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;END&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="p"&gt;}.&lt;/span&gt;&lt;span class="nx"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_transitionTimeout&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mf"&gt;1.2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="cm"&gt;/**&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;       * @event AppWindow#appwillclose&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;       * @memberof AppWindow&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;       */&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;from&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;opened&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="c1"&gt;// Only publish |willclose| event when previous state is &amp;quot;opened&amp;quot;.&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;willclose&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;transition-closing&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_transition&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;close&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="nx"&gt;_processTransitionEvent&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;aw__processTransitionEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;evt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;transitionTable&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_transitionState&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="nx"&gt;evt&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;from&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_transitionState&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;leaveState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;evt&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;evt&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;enterState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;evt&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_previousTransitionState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;from&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_transitionState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="nx"&gt;enterState&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;aw_enterState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;evt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;funcName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;_enter&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;capitalize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;funcName&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;function&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="nx"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;          &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;funcName&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="nx"&gt;from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;evt&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="p"&gt;}.&lt;/span&gt;&lt;span class="nx"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;funcName&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;funcName&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;funcName&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;func&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;          &lt;span class="nx"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;            &lt;span class="nx"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;evt&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;          &lt;span class="p"&gt;}.&lt;/span&gt;&lt;span class="nx"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="nx"&gt;leaveState&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;aw_leaveState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;evt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;funcName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;_leave&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;capitalize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;from&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;funcName&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;function&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="nx"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;          &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;funcName&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="nx"&gt;from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;evt&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="p"&gt;}.&lt;/span&gt;&lt;span class="nx"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;funcName&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;funcName&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;funcName&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;func&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;          &lt;span class="nx"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;            &lt;span class="nx"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;evt&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;          &lt;span class="p"&gt;}.&lt;/span&gt;&lt;span class="nx"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="nx"&gt;onEvent&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;aw_onEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;evt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;funcName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;_onTransition&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;capitalize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_EVTARRAY&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;evt&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;funcName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="nx"&gt;_enterOpened&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;aw__enterOpened&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;evt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_cancelTransition&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_openingTransitionTimer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clearTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_openingTransitionTimer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_openingTransitionTimer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;active&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="cm"&gt;/**&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;       * @event AppWindow#appopen&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;       * @memberOf AppWindow&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;       */&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;from&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;opening&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="c1"&gt;// Only publish |open| event when previous state is &amp;quot;opening&amp;quot;.&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;open&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="nx"&gt;_enterClosed&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;aw__enterClosed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;evt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_cancelTransition&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_closingTransitionTimer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clearTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_closingTransitionTimer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_closingTransitionTimer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;active&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setVisible&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="cm"&gt;/**&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;       * @event AppWindow#appclose&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;       * @memberof AppWindow&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;       */&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;from&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;closing&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="c1"&gt;// Only publish |close| event when previous state is &amp;quot;closing&amp;quot;.&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;close&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="cm"&gt;/**&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;     * Set the transition way of opening or closing transition.&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;     * @param  {String} type       &amp;#39;open&amp;#39; or &amp;#39;close&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;     * @param  {String} transition The CSS rule name about window transition.&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;     * @memberOf WindowTransition&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;     */&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="nx"&gt;_setTransition&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;aw__setTransition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;transition&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;open&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;close&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_transition&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;transition&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="nx"&gt;AppWindow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addMixin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;WindowTransition&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="p"&gt;}(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;h5&gt;The state machine&amp;rsquo;s usage and notes&lt;/h5&gt;

&lt;ol&gt;
&lt;li&gt;A single app window instance would send &amp;lsquo;open&amp;rsquo; and &amp;lsquo;close&amp;rsquo; event due to user action:
&lt;code&gt;
transitionStateMachine.&lt;em&gt;processEvent(&amp;lsquo;open&amp;rsquo;);
transitionStateMachine.&lt;/em&gt;processEvent(&amp;lsquo;close&amp;rsquo;);
&lt;/code&gt;
Note, app window doesn&amp;rsquo;t need to know current state of the state machine.&lt;/li&gt;
&lt;li&gt;The state machine itself is the one who creates/removes the timer which triggers timeout event. I am also thinking about moving this out of the state machine and do this in another mixin, only have the callback functions provided by the state machine. But I am not sure.&lt;/li&gt;
&lt;li&gt;The state machine has some callback for others(other state machine!) listed below:

&lt;ul&gt;
&lt;li&gt;Enter a state successfully.&lt;/li&gt;
&lt;li&gt;Leave a state successfully.&lt;/li&gt;
&lt;li&gt;When an event triggers state switch successfully.
In all these callback we would get the previous state and current state, and the event who triggers them.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;The CSS class for real UI closing animation is added in &lt;code&gt;&lt;em&gt;enterClosing&lt;/code&gt; and removed in &lt;code&gt;&lt;/em&gt;enterClosed&lt;/code&gt;. Or else we could do that in &lt;code&gt;&lt;em&gt;leaveOpened&lt;/code&gt; and &lt;code&gt;&lt;/em&gt;leaveClosing&lt;/code&gt;. I have no strong opinion here.
Maybe we could define the level of the callback into three here, according to the callback order.&lt;/li&gt;
&lt;li&gt;The CSS class for real UI opening animation is added in &lt;code&gt;&lt;em&gt;enterOpening&lt;/code&gt; and removed in &lt;code&gt;&lt;/em&gt;enterOpened&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;We could also move out (4) and (5) to another mixin to purify the state machine.&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;Finally, back to the problems addressed in Tim&amp;rsquo;s article:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Do we need intermediate state?

&lt;ul&gt;
&lt;li&gt;I don&amp;rsquo;t think so, at least for now. If we really need to goto next state when we successfully from state A to state B, we could call &lt;code&gt;_processEvent&lt;/code&gt; again in the inner callback of the state machine. This doesn&amp;rsquo;t violate the policy that only state machine ifself could decide its next state.&lt;/li&gt;
&lt;li&gt;If the intermediate state needs to acquire other type of state &amp;mdash; just fetch the current state of the other state machine. Or, if we need, register an one-time callback if the current state doesn&amp;rsquo;t meet our requirement.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;How about state conflict between two apps?

&lt;ul&gt;
&lt;li&gt;That won&amp;rsquo;t happen if we deal with the state changes correctly and independently in each app&amp;rsquo;s scope. I hope so.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description></item><item><title>HTML5 Page visibility on Fx OS</title><pubDate>Fri, 5 Jul 2013 04:23:00 +0800</pubDate><guid isPermaLink="false">http://alivedise.github.io/blog/2013/07/05/page-visibility-on-firefox-os</guid><description>&lt;p&gt;在桌面版本的網頁開發中，我們可以透過 HTML5 的 page visibility API 來知道目前的網頁是否為使用者焦點，或者目前不可為使用者所見，來達成某些目的：如停止 UI 更新，資料交換&amp;hellip;等，範例程式如下：&lt;/p&gt;

&lt;figure class='code'&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;span class='line-number'&gt;2&lt;/span&gt;
&lt;span class='line-number'&gt;3&lt;/span&gt;
&lt;span class='line-number'&gt;4&lt;/span&gt;
&lt;span class='line-number'&gt;5&lt;/span&gt;
&lt;span class='line-number'&gt;6&lt;/span&gt;
&lt;span class='line-number'&gt;7&lt;/span&gt;
&lt;span class='line-number'&gt;8&lt;/span&gt;
&lt;span class='line-number'&gt;9&lt;/span&gt;
&lt;span class='line-number'&gt;10&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='line'&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;handleVisibilityChange&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hidden&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="c1"&gt;// Pause UI update&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="c1"&gt;// Begin UI update&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;visibilitychange&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="nx"&gt;handleVisibilityChange&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;我們將這個 API 帶到 Firefox OS 中，並賦予了它更深一層的意義：&lt;/p&gt;

&lt;!--more--&gt;




&lt;blockquote&gt;&lt;p&gt;應用程式判斷自己在前景/背景的依據，類似 android 的 onPause/onResume&lt;br/&gt;系統底層 Low Memory Killer 的參數之一：背景應用程式在可用記憶體過低時會優先被 kill&lt;br/&gt;在電力消耗變成一個必須優先考量要點的手持裝置上，透過進入背景時停止更新 UI 對電力節約有很大幅度的幫助。&lt;br/&gt;然而，在手機系統上，並不像在桌面瀏覽器一樣單純的是透過頁面切換 (onPageShow/onPageHide) 來決定要不要對某個 web page/app 做前景背景切換，而是要根據系統 UI hierarchy 以及當前介面中層級較高的其他元件的狀態來維持 visibility 的協調性。&lt;/p&gt;&lt;/blockquote&gt;


&lt;p&gt;聽起來很抽象嗎？先來張系統模組介面架構圖：
&lt;img src="http://i.imgur.com/ypJSsQg.jpg"&gt;
Gaia System Architecture Diagram (source from &lt;a href="https://docs.google.com/drawings/d/18DnhTgQBK3M0KBeLGJkWW1hfiYBB6GgTmfdbUnT2SLs/edit?usp=sharing"&gt;https://docs.google.com/drawings/d/18DnhTgQBK3M0KBeLGJkWW1hfiYBB6GgTmfdbUnT2SLs/edit?usp=sharing&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;簡單的說，手機系統介面在特定狀態下會將目前已經是前景的 app 設定為背景狀態，其優先層級如下：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Screen off (螢幕關閉)&lt;/li&gt;
&lt;li&gt;Call screen (電話中介面)&lt;/li&gt;
&lt;li&gt;Lockscreen on (手機鎖定介面啟動)&lt;/li&gt;
&lt;li&gt;Inline activities (app內嵌 web activities 作用中)&lt;/li&gt;
&lt;li&gt;App transition end (app 切換結束)&lt;/li&gt;
&lt;li&gt;Back to home (回到 homescreen)&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;而這些事件又可能會同時發生而產生互相影響，如：inline activity 作用時電話打進來，多重 inline activities 中第一次產生的 activity frame 會被第二次的 activity frame 蓋掉&amp;hellip;等。&lt;/p&gt;

&lt;p&gt;這些決策發生在哪呢？與桌面瀏覽器不同，決定這一切的是發生在 Gaia，也就是 Firefox OS 的 UI 層：換句話說，是以 JavaScript 撰寫的噢。而實現的方式是系統中各個模組對各個底層 moz-*  API 的 callback 重新包覆並以 custom event 的形式通知其他模組，最後集中給 system app 中的 Window Manager 來做統一管理。&lt;/p&gt;

&lt;p&gt;這樣做最大的原因是：只有 Gaia 本身最了解與 UI 相關的一切，而既然 Gecko 將 API expose 出來，只要你對 API 夠熟悉，想要自己用 JavaScript/HTML 實現一個瀏覽器是可能的。&lt;/p&gt;

&lt;p&gt;這部份我們可以用一個實例說明：
「裝置從進入閒置狀態，到使用者按下電源鍵，之後解開鎖定螢幕 (LockScreen)」對 visibility 影響的過程：&lt;/p&gt;

&lt;h5&gt;Screen is off by idle timeout:&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;(Gaia) [Screen Manager] mozPower.screenEnabled = false&lt;/li&gt;
&lt;li&gt;(Gaia) [Screen Manager] send custom &amp;lsquo;screenchange&amp;rsquo; event&lt;/li&gt;
&lt;li&gt;(Gaia) [Lockscreen] get &amp;lsquo;screenchange&amp;rsquo; event, check the settings of &amp;ldquo;lockscreen.enabled&amp;rdquo; and dispatch custom &amp;lsquo;lock&amp;rsquo; event&lt;/li&gt;
&lt;li&gt;(Gaia) [Window Manager] get &amp;lsquo;lock&amp;rsquo; event, and then set visibility = false for current app(focused one).&lt;/li&gt;
&lt;li&gt;(Gonk) [/sys/power] See mozPower.screenEnabled is modified and send &amp;lsquo;sizemodechange&amp;rsquo; to simulate the content window is minimized.&lt;/li&gt;
&lt;li&gt;(Gecko) [shell] Get &amp;lsquo;sizemodechange&amp;rsquo; event, set visibility = false for the whole system app&lt;/li&gt;
&lt;/ul&gt;


&lt;h5&gt;Turn on screen:&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;(Gecko) Get keypress event of sleep-button, and then send mozChromeEvent to gaia&lt;/li&gt;
&lt;li&gt;(Gaia) [Hardware Button Manager] Get mozChromeEvent with type = &amp;ldquo;sleep-button-press&amp;rdquo;, wrap the event to &amp;lsquo;wake&amp;rsquo; event&lt;/li&gt;
&lt;li&gt;(Gaia) [Screen Manager] mozPower.screenEnabled = true&lt;/li&gt;
&lt;li&gt;(Gecko) [shell] Get &amp;lsquo;sizemodechange&amp;rsquo; event, set visibility = true for the whole system app
[NOTE] the current app is still invisible now, but the system app is visible.&lt;/li&gt;
&lt;/ul&gt;


&lt;h5&gt;Unlock the lockscreen:&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;(Gaia) [Lockscreen] Send custom &amp;lsquo;unlock&amp;rsquo; event.&lt;/li&gt;
&lt;li&gt;(Gaia) [Widow Manager] Get &amp;lsquo;unlock&amp;rsquo; event and turn on the active app&amp;rsquo;s visibility.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;對 App 開發者來說，其實你只要適當地註冊 visibilitychange event handler 去分別處理前景與背景的任務，而維持 visibility state 的正確性與一致性則是作業系統的責任，這也是開發 website/web application 與 web-based OS 之間最大的不同吧：必須同時考慮到過去（已經存在的網頁）/現在（我們正在開發中的內建app）/未來（即將到來的 FirefoxOS app）。&lt;/p&gt;

&lt;p&gt;P.S. This is posted at moztech first. See &lt;a href="http://tech.mozilla.com.tw/posts/2020/visibility-api-on-firefox-os-%E5%BE%9E%E6%87%89%E7%94%A8%E7%A8%8B%E5%BC%8F%E5%89%8D%E8%83%8C%E6%99%AF%E6%8E%A7%E5%88%B6%E7%9C%8B-os-%E5%AF%A6%E4%BD%9C"&gt;here&lt;/a&gt;&lt;/p&gt;
</description></item><item><title>My first year at Mozilla</title><pubDate>Fri, 5 Jul 2013 02:31:00 +0800</pubDate><guid isPermaLink="false">http://alivedise.github.io/blog/2013/07/05/one-year-at-mozilla</guid><description>&lt;h3&gt;Achievements&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;第一次出國，第一次出差。&lt;/li&gt;
&lt;li&gt;工作關係出差四次去了三個國家（美國兩次，德國，西班牙），自己自助旅行去了日本。&lt;/li&gt;
&lt;li&gt;&lt;a href="https://wiki.mozilla.org/Modules/FirefoxOS#System"&gt;變成module peer&lt;/a&gt;。&lt;/li&gt;
&lt;li&gt;參與了一些以前沒有被發明過的WebAPI的設計或討論。&lt;/li&gt;
&lt;li&gt;有了當面試官的經驗。&lt;/li&gt;
&lt;li&gt;第一次參加全公司的出遊活動。&lt;/li&gt;
&lt;li&gt;對Firefox的layout engine: Gecko送了幾次patch，&lt;a href="http://www.mozilla.org/hacking/committer/"&gt;簽了Level 1 Committer賣身契&lt;/a&gt;。&lt;/li&gt;
&lt;li&gt;寫了數百個各種patch，解了數百個各種bug。&lt;/li&gt;
&lt;li&gt;看到很多以前沒有遇過的pattern，現在回去看一年前寫的東西感覺又不同了。&lt;/li&gt;
&lt;li&gt;當然也看到一些不好的設計，很希望有機會能夠改變它。&lt;/li&gt;
&lt;li&gt;認識一些除了我之外在工作之餘還是對技術玩意很有熱忱的人。&lt;/li&gt;
&lt;/ul&gt;


&lt;!--more--&gt;


&lt;ul&gt;
&lt;li&gt;目前身分是自由球員，理論上被允許去做任何我想做的事，不太被干涉，我非常，非常喜歡這件事。也很感謝我的主管&amp;#8221;縱容&amp;#8221;我。&lt;/li&gt;
&lt;li&gt;養了叫bug的貓。&lt;img src="http://i.imgur.com/JPR0wzu.jpg"&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://coscup.org/2012/en/program/"&gt;在COSCUP 2012給過talk&lt;/a&gt;。&lt;/li&gt;
&lt;li&gt;&lt;a href="http://coscup.org/2013/zh-tw/program/"&gt;今年還有一次跟FxOS有關的talk&lt;/a&gt;。&lt;/li&gt;
&lt;li&gt;在柏林的時候人生第一次看到雪。&lt;img src="http://i.imgur.com/ffpaudD.jpg"&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;Canvas&lt;/h3&gt;

&lt;h4&gt;MountainView&lt;/h4&gt;

&lt;p&gt;&lt;img src="http://i.imgur.com/V1mXfJf.jpg"&gt;
&lt;img src="http://i.imgur.com/ytFnxpi.jpg"&gt;
&lt;img src="http://i.imgur.com/pCGMHcF.jpg"&gt;&lt;/p&gt;

&lt;h4&gt;San Francisco&lt;/h4&gt;

&lt;p&gt;&lt;img src="http://i.imgur.com/2WElJM1.jpg"&gt;
&lt;img src="http://i.imgur.com/OBv99Ty.jpg"&gt;
&lt;img src="http://i.imgur.com/7u3g8IC.jpg"&gt;&lt;/p&gt;

&lt;h4&gt;Berlin &amp;ndash; Snow!&lt;/h4&gt;

&lt;p&gt;&lt;img src="http://i.imgur.com/cO74ubC.jpg"&gt;
&lt;img src="http://i.imgur.com/EULi3MV.jpg"&gt;
&lt;img src="http://i.imgur.com/tSer20f.jpg"&gt;
&lt;img src="http://i.imgur.com/FEtE2wg.jpg"&gt;&lt;/p&gt;

&lt;h4&gt;Spain&lt;/h4&gt;

&lt;p&gt;&lt;img src="http://i.imgur.com/eufuWlp.jpg"&gt;
&lt;img src="http://i.imgur.com/tbjIL9m.jpg"&gt;
&lt;img src="http://i.imgur.com/GkWfumD.jpg"&gt;
&lt;img src="http://i.imgur.com/v8Y3472.jpg"&gt;&lt;/p&gt;

&lt;h4&gt;Japan&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;自助旅行 &amp;ndash; 是的，這其實跟工作無關，不過也因為是在這裡，請長假出國玩絕對不是太困難的事情。&lt;/li&gt;
&lt;li&gt;我在日本期間去了日本Mozilla辦公室 &amp;ndash; 位在六本木，一個很棒的空間。
&lt;img src="http://i.imgur.com/z4ekB4W.jpg"&gt;
&lt;img src="http://i.imgur.com/2ErLpTd.jpg"&gt;
&lt;img src="http://i.imgur.com/qtQGJuH.jpg"&gt;
&lt;img src="http://i.imgur.com/BTRD67c.jpg"&gt;
&lt;img src="http://i.imgur.com/q27j5yp.jpg"&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;While (true) {&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;還想多用javascript寫一些不同的pattern。&lt;/li&gt;
&lt;li&gt;想培養持續玩一些小的side probject的習慣。&lt;/li&gt;
&lt;li&gt;想把自己bug track list裡面的bug通通吃完。&lt;/li&gt;
&lt;li&gt;想了解gaia裡面某些至今還沒有看完的複雜的應用做了什麼，為了什麼，可以學到什麼。&lt;/li&gt;
&lt;li&gt;繼續寫blog吧!&lt;/li&gt;
&lt;li&gt;想改變我想改變的事情。

&lt;h3&gt;}&lt;/h3&gt;&lt;/li&gt;
&lt;/ul&gt;

</description></item><item><title>Recent side projects: Alvitr, Lucifer, GaiaSystemAPIDOC</title><pubDate>Tue, 18 Jun 2013 12:33:00 +0800</pubDate><guid isPermaLink="false">http://alivedise.github.io/blog/2013/06/18/alvitr</guid><description>&lt;h3&gt;Alvitr&lt;/h3&gt;

&lt;p&gt;Alvitr(艾爾薇妲）是北歐神話中戰女神的其中一名，其名意為「全知」。&lt;/p&gt;

&lt;p&gt;最近對某個遊戲(Puzzle &amp;amp; Dragon)很沉迷，
但是在網路上遍尋不著產生簽名檔的服務，
於是就興起了想要自己做的念頭。&lt;/p&gt;

&lt;p&gt;&lt;a href="http://alivedise.github.io/alvitr"&gt;Alvitr&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;大概花了一個禮拜的時間，本來想用Amazon AWS + node.js的組合來用伺服器端產生圖檔，
但是遇到了不少問題如：
1. AWS初始化實在太煩人了。
2. node.js跑起來會莫名的crash，錯誤訊息看起來像是c語言的某個函式。（我不是在寫js嗎？！)&lt;/p&gt;

&lt;p&gt;後來還是決定用client端javascript application的形式做，
至少IE9可以支援Canvas。&lt;/p&gt;

&lt;!--more--&gt;


&lt;h4&gt;Canvas templating&lt;/h4&gt;

&lt;p&gt;因為目標是把使用者輸入的資料轉成不同大小內容配置也不同的圖片，&lt;/p&gt;

&lt;p&gt;於是我在想可以針對不同大小圖片弄一個像是configurtaion的物件，每次配置選擇改變只要換掉configuration就好了。&lt;/p&gt;

&lt;p&gt;最後成果&lt;a href="https://github.com/alivedise/alvitr/blob/gh-pages/javascripts/client.js"&gt;client.js&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;繪圖元件配置不外乎：x, y, weight, height, color等的參數，所以要創造一個新的配置物件只要複製貼上再去微調就好了。&lt;/p&gt;

&lt;h3&gt;Lucifer&lt;/h3&gt;

&lt;blockquote&gt;&lt;p&gt;明亮之星，早晨之子啊，你何竟從天墜落？你這攻敗列國的何竟被砍倒在地上？你心裡曾說：我要升到天上；我要高舉我的寶座在神眾星以上；我要坐在聚會的山上，在北方的極處。我要升到高雲之上；我要與至上者同等。然而，你必墜落陰間，到坑中極深之處。&lt;/p&gt;&lt;/blockquote&gt;


&lt;p&gt;&lt;a href="http://alivedise.github.io/lucifer"&gt;Lucifer&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;拿某篇文章來開的小玩笑，主要是用了ejs template engine來亂數產生一些怪物資料在文章內。&lt;/p&gt;

&lt;h3&gt;Gaia System API Documentation&lt;/h3&gt;

&lt;p&gt;&lt;a href="http://alivedise.github.io/gaia-system-jsdoc/"&gt;Gaia System JSDOC&lt;/a&gt;
&lt;a href="https://github.com/alivedise/jsdoc3-bootstrap"&gt;JSDOC3 bootstrap template&lt;/a&gt;
不知道為什麼jsdoc2我電腦一直裝不成功，jsdoc3倒是很簡單的用npm就裝好了。&lt;/p&gt;

&lt;p&gt;找了一下找不到專門給jsdoc3用的好看template&amp;hellip;我就自己套bootstrap上去了，成果如上。&lt;/p&gt;

&lt;h3&gt;其他&lt;/h3&gt;

&lt;p&gt;我還有一兩個一直很想做的probject&amp;hellip;不過總是因為懶惰作罷:P&lt;/p&gt;

&lt;p&gt;回首到Mozilla也一年了，感覺自身還有很多不足&amp;hellip;.
督促自己寫side project只是開始而已，還要再努力阿！&lt;/p&gt;
</description></item><item><title>Javascript從變形矩陣反推scale以及rotate</title><pubDate>Mon, 27 May 2013 15:41:00 +0800</pubDate><guid isPermaLink="false">http://alivedise.github.io/blog/2013/05/27/rotation-matrix</guid><description>&lt;p&gt;原文：
&lt;a href="http://css-tricks.com/get-value-of-css-rotation-through-javascript/"&gt;http://css-tricks.com/get-value-of-css-rotation-through-javascript/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;今天在追一個跟CSS3 transform有關的bug，
過程中懷疑是transform沒有正確應用到element上。&lt;/p&gt;

&lt;p&gt;最後想到用一個Mutation Observer去觀察元素的變形矩陣的某個值（在此例為scale)的變化，
因為transform沒辦法直接用element.style直接拿到scale的值，
所以要用getComputedStyle拿出變形矩陣後算出來：
（skew跟translate的值原文沒有提供算法，看了一下網路文章似乎沒辦法逆推。）&lt;/p&gt;

&lt;!--more--&gt;




&lt;figure class='code'&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;span class='line-number'&gt;2&lt;/span&gt;
&lt;span class='line-number'&gt;3&lt;/span&gt;
&lt;span class='line-number'&gt;4&lt;/span&gt;
&lt;span class='line-number'&gt;5&lt;/span&gt;
&lt;span class='line-number'&gt;6&lt;/span&gt;
&lt;span class='line-number'&gt;7&lt;/span&gt;
&lt;span class='line-number'&gt;8&lt;/span&gt;
&lt;span class='line-number'&gt;9&lt;/span&gt;
&lt;span class='line-number'&gt;10&lt;/span&gt;
&lt;span class='line-number'&gt;11&lt;/span&gt;
&lt;span class='line-number'&gt;12&lt;/span&gt;
&lt;span class='line-number'&gt;13&lt;/span&gt;
&lt;span class='line-number'&gt;14&lt;/span&gt;
&lt;span class='line-number'&gt;15&lt;/span&gt;
&lt;span class='line-number'&gt;16&lt;/span&gt;
&lt;span class='line-number'&gt;17&lt;/span&gt;
&lt;span class='line-number'&gt;18&lt;/span&gt;
&lt;span class='line-number'&gt;19&lt;/span&gt;
&lt;span class='line-number'&gt;20&lt;/span&gt;
&lt;span class='line-number'&gt;21&lt;/span&gt;
&lt;span class='line-number'&gt;22&lt;/span&gt;
&lt;span class='line-number'&gt;23&lt;/span&gt;
&lt;span class='line-number'&gt;24&lt;/span&gt;
&lt;span class='line-number'&gt;25&lt;/span&gt;
&lt;span class='line-number'&gt;26&lt;/span&gt;
&lt;span class='line-number'&gt;27&lt;/span&gt;
&lt;span class='line-number'&gt;28&lt;/span&gt;
&lt;span class='line-number'&gt;29&lt;/span&gt;
&lt;span class='line-number'&gt;30&lt;/span&gt;
&lt;span class='line-number'&gt;31&lt;/span&gt;
&lt;span class='line-number'&gt;32&lt;/span&gt;
&lt;span class='line-number'&gt;33&lt;/span&gt;
&lt;span class='line-number'&gt;34&lt;/span&gt;
&lt;span class='line-number'&gt;35&lt;/span&gt;
&lt;span class='line-number'&gt;36&lt;/span&gt;
&lt;span class='line-number'&gt;37&lt;/span&gt;
&lt;span class='line-number'&gt;38&lt;/span&gt;
&lt;span class='line-number'&gt;39&lt;/span&gt;
&lt;span class='line-number'&gt;40&lt;/span&gt;
&lt;span class='line-number'&gt;41&lt;/span&gt;
&lt;span class='line-number'&gt;42&lt;/span&gt;
&lt;span class='line-number'&gt;43&lt;/span&gt;
&lt;span class='line-number'&gt;44&lt;/span&gt;
&lt;span class='line-number'&gt;45&lt;/span&gt;
&lt;span class='line-number'&gt;46&lt;/span&gt;
&lt;span class='line-number'&gt;47&lt;/span&gt;
&lt;span class='line-number'&gt;48&lt;/span&gt;
&lt;span class='line-number'&gt;49&lt;/span&gt;
&lt;span class='line-number'&gt;50&lt;/span&gt;
&lt;span class='line-number'&gt;51&lt;/span&gt;
&lt;span class='line-number'&gt;52&lt;/span&gt;
&lt;span class='line-number'&gt;53&lt;/span&gt;
&lt;span class='line-number'&gt;54&lt;/span&gt;
&lt;span class='line-number'&gt;55&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='line'&gt;  &lt;span class="cm"&gt;/**&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   * Construct a mutation observer.&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   * See https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   */&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="cm"&gt;/**&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   * var target = document.querySelector(&amp;#39;#id&amp;#39;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   */&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;target&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;#id&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="cm"&gt;/**&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   * create an observer instance&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   */&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;observer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;MutationObserver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mutations&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="cm"&gt;/**&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;     * We could iterate the mutations here,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;     * but I don&amp;#39;t really care it now.&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;     */&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;st&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getComputedStyle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;tr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;st&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getPropertyValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;-webkit-transform&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;             &lt;span class="nx"&gt;st&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getPropertyValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;-moz-transform&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;             &lt;span class="nx"&gt;st&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getPropertyValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;-ms-transform&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;             &lt;span class="nx"&gt;st&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getPropertyValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;-o-transform&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;             &lt;span class="nx"&gt;st&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getPropertyValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;transform&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Matrix: &amp;#39;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;tr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="c1"&gt;// rotation matrix - http://en.wikipedia.org/wiki/Rotation_matrix&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;values&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;tr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;(&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="nx"&gt;values&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;values&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;)&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="nx"&gt;values&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;values&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;,&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;values&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;values&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;values&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;d&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;values&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;scale&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sqrt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="c1"&gt;// arc sin, convert from radians to degrees, round&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="c1"&gt;// DO NOT USE: see update below&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;sin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;angle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;asin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sin&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;180&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PI&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="c1"&gt;// works!&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Scale: &amp;#39;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;scale&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;;Rotate: &amp;#39;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;angle&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;deg&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="cm"&gt;/**&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;    * Configuration of mutation observer.&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;    */&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;attributes&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;childList&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;characterData&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="cm"&gt;/**&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   * pass in the target node, as well as the observer options&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;   */&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="nx"&gt;observer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;observe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;

</description></item><item><title>From browser to browser. (1)</title><pubDate>Sat, 23 Feb 2013 17:40:00 +0800</pubDate><guid isPermaLink="false">http://alivedise.github.io/blog/2013/02/23/from-browser-to-browser</guid><description>&lt;h3&gt;Firefox OS&lt;/h3&gt;

&lt;p&gt;&lt;img src="http://cdn0.mos.techradar.futurecdn.net///art/mobile_phones/Mozilla/FireFoxOS/DeveloperHandsets/FirefoxOSDev-Press-01-580-75.jpg"&gt;&lt;/p&gt;

&lt;h3&gt;System app&lt;/h3&gt;

&lt;p&gt;Exactly, Firefox OS, also known for boot 2 gecko, is having only one app/one page.
It&amp;rsquo;s the system app, which controls all web app&amp;rsquo;s life cycle.
When FirefoxOS is booted, it would load the system app from &lt;code&gt;system/index.html&lt;/code&gt;.
Then system app would take care of the remaing stuff.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Load modules&lt;/li&gt;
&lt;li&gt;Init homescreen app&lt;/li&gt;
&lt;li&gt;Etc.&lt;/li&gt;
&lt;/ul&gt;


&lt;!--more--&gt;


&lt;h3&gt;Window Manager&lt;/h3&gt;

&lt;p&gt;Window Manager is the core of Firefox OS, the core of system app, which is in charge of creating/maintaining/killing apps.
An app, indeed, is a web page.&lt;/p&gt;

&lt;p&gt;We use a magic, calling browser API, to make a web page act like an app.&lt;/p&gt;

&lt;h3&gt;Browser API&lt;/h3&gt;

&lt;p&gt;See &lt;a href="https://developer.mozilla.org/en-US/docs/DOM/Using_the_Browser_API"&gt;https://developer.mozilla.org/en-US/docs/DOM/Using_the_Browser_API&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A browser here means that the web page acts like it is living in a browser &lt;code&gt;frame&lt;/code&gt;.
We are replacing nearly every XUL-based UI with HTML to &lt;code&gt;port&lt;/code&gt; the WEB to the phone.&lt;/p&gt;

&lt;h3&gt;Module Pattern&lt;/h3&gt;

&lt;p&gt;Module pattern is the way Window Manager being imeplemented.
A module pattern looks like:&lt;/p&gt;

&lt;figure class='code'&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;span class='line-number'&gt;2&lt;/span&gt;
&lt;span class='line-number'&gt;3&lt;/span&gt;
&lt;span class='line-number'&gt;4&lt;/span&gt;
&lt;span class='line-number'&gt;5&lt;/span&gt;
&lt;span class='line-number'&gt;6&lt;/span&gt;
&lt;span class='line-number'&gt;7&lt;/span&gt;
&lt;span class='line-number'&gt;8&lt;/span&gt;
&lt;span class='line-number'&gt;9&lt;/span&gt;
&lt;span class='line-number'&gt;10&lt;/span&gt;
&lt;span class='line-number'&gt;11&lt;/span&gt;
&lt;span class='line-number'&gt;12&lt;/span&gt;
&lt;span class='line-number'&gt;13&lt;/span&gt;
&lt;span class='line-number'&gt;14&lt;/span&gt;
&lt;span class='line-number'&gt;15&lt;/span&gt;
&lt;span class='line-number'&gt;16&lt;/span&gt;
&lt;span class='line-number'&gt;17&lt;/span&gt;
&lt;span class='line-number'&gt;18&lt;/span&gt;
&lt;span class='line-number'&gt;19&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='line'&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;WindowManager&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;_running&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;createApp&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;     &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;     &lt;span class="nx"&gt;_running&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;_id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;     &lt;span class="nx"&gt;_id&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;     &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;killApp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="k"&gt;delete&lt;/span&gt; &lt;span class="nx"&gt;_running&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="nx"&gt;create&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;createApp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="nx"&gt;kill&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;killApp&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="p"&gt;})();&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;Thus the Window Manager object only has 2 public attributes.
This looks fine, but it would be a nightmare if this pattern grows to over 2000 lines.
And it&amp;rsquo;s having countless private functions now.&lt;/p&gt;

&lt;p&gt;This module now is not unit testable nor maintainable.&lt;/p&gt;

&lt;h3&gt;Break it!&lt;/h3&gt;

&lt;h4&gt;From the browser to the browser&lt;/h4&gt;

&lt;p&gt;Let&amp;rsquo;s define a new object to contain and manage itself in its own scope.&lt;/p&gt;

&lt;p&gt;It&amp;rsquo;s called &lt;code&gt;browserFrame&lt;/code&gt;.&lt;/p&gt;

&lt;h5&gt;The responsibility of browserFrame&lt;/h5&gt;

&lt;p&gt;It would create an iframe with all attributes needed for BrowserAPI.&lt;/p&gt;

&lt;figure class='code'&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;span class='line-number'&gt;2&lt;/span&gt;
&lt;span class='line-number'&gt;3&lt;/span&gt;
&lt;span class='line-number'&gt;4&lt;/span&gt;
&lt;span class='line-number'&gt;5&lt;/span&gt;
&lt;span class='line-number'&gt;6&lt;/span&gt;
&lt;span class='line-number'&gt;7&lt;/span&gt;
&lt;span class='line-number'&gt;8&lt;/span&gt;
&lt;span class='line-number'&gt;9&lt;/span&gt;
&lt;span class='line-number'&gt;10&lt;/span&gt;
&lt;span class='line-number'&gt;11&lt;/span&gt;
&lt;span class='line-number'&gt;12&lt;/span&gt;
&lt;span class='line-number'&gt;13&lt;/span&gt;
&lt;span class='line-number'&gt;14&lt;/span&gt;
&lt;span class='line-number'&gt;15&lt;/span&gt;
&lt;span class='line-number'&gt;16&lt;/span&gt;
&lt;span class='line-number'&gt;17&lt;/span&gt;
&lt;span class='line-number'&gt;18&lt;/span&gt;
&lt;span class='line-number'&gt;19&lt;/span&gt;
&lt;span class='line-number'&gt;20&lt;/span&gt;
&lt;span class='line-number'&gt;21&lt;/span&gt;
&lt;span class='line-number'&gt;22&lt;/span&gt;
&lt;span class='line-number'&gt;23&lt;/span&gt;
&lt;span class='line-number'&gt;24&lt;/span&gt;
&lt;span class='line-number'&gt;25&lt;/span&gt;
&lt;span class='line-number'&gt;26&lt;/span&gt;
&lt;span class='line-number'&gt;27&lt;/span&gt;
&lt;span class='line-number'&gt;28&lt;/span&gt;
&lt;span class='line-number'&gt;29&lt;/span&gt;
&lt;span class='line-number'&gt;30&lt;/span&gt;
&lt;span class='line-number'&gt;31&lt;/span&gt;
&lt;span class='line-number'&gt;32&lt;/span&gt;
&lt;span class='line-number'&gt;33&lt;/span&gt;
&lt;span class='line-number'&gt;34&lt;/span&gt;
&lt;span class='line-number'&gt;35&lt;/span&gt;
&lt;span class='line-number'&gt;36&lt;/span&gt;
&lt;span class='line-number'&gt;37&lt;/span&gt;
&lt;span class='line-number'&gt;38&lt;/span&gt;
&lt;span class='line-number'&gt;39&lt;/span&gt;
&lt;span class='line-number'&gt;40&lt;/span&gt;
&lt;span class='line-number'&gt;41&lt;/span&gt;
&lt;span class='line-number'&gt;42&lt;/span&gt;
&lt;span class='line-number'&gt;43&lt;/span&gt;
&lt;span class='line-number'&gt;44&lt;/span&gt;
&lt;span class='line-number'&gt;45&lt;/span&gt;
&lt;span class='line-number'&gt;46&lt;/span&gt;
&lt;span class='line-number'&gt;47&lt;/span&gt;
&lt;span class='line-number'&gt;48&lt;/span&gt;
&lt;span class='line-number'&gt;49&lt;/span&gt;
&lt;span class='line-number'&gt;50&lt;/span&gt;
&lt;span class='line-number'&gt;51&lt;/span&gt;
&lt;span class='line-number'&gt;52&lt;/span&gt;
&lt;span class='line-number'&gt;53&lt;/span&gt;
&lt;span class='line-number'&gt;54&lt;/span&gt;
&lt;span class='line-number'&gt;55&lt;/span&gt;
&lt;span class='line-number'&gt;56&lt;/span&gt;
&lt;span class='line-number'&gt;57&lt;/span&gt;
&lt;span class='line-number'&gt;58&lt;/span&gt;
&lt;span class='line-number'&gt;59&lt;/span&gt;
&lt;span class='line-number'&gt;60&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='line'&gt;&lt;span class="s1"&gt;&amp;#39;use strict&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;/* Define a basic mozbrowser iframe class.&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt; * It creates a mozbrowser iframe,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt; * and finally returns the DOM element it just created.&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt; */&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;BrowserFrame&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;invocation&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;BrowserFrame&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// This constructor function is a local variable.&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;nextId&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;callbacks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="nx"&gt;createFrame&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;apply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// All arguments are values to createFrame&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="nx"&gt;BrowserFrame&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;className&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;browser&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="c1"&gt;// These are helper functions and variables used by the methods above&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="c1"&gt;// They&amp;#39;re not part of the public API of the module, but they&amp;#39;re hidden&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="c1"&gt;// within this function scope so we don&amp;#39;t have to define them as a&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="c1"&gt;// property of Browser or prefix them with underscores.&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;createFrame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;origin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;manifestURL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;oop&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;browser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;iframe&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="nx"&gt;browser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;mozallowfullscreen&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;true&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="c1"&gt;// Most apps currently need to be hosted in a special &amp;#39;mozbrowser&amp;#39; iframe.&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="c1"&gt;// They also need to be marked as &amp;#39;mozapp&amp;#39; to be recognized as apps by the&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="c1"&gt;// platform.&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="nx"&gt;browser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;mozbrowser&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;true&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;oop&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="nx"&gt;browser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;remote&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;true&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;manifestURL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="nx"&gt;browser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;mozapp&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;manifestURL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;origin&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;origin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;origin&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="nx"&gt;browser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;src&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="nx"&gt;browser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;className&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="nx"&gt;browser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;BrowserFrame&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="c1"&gt;// Store the element&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;browser&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;nextId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="c1"&gt;// The public API for this module is the Browser() constructor function.&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="c1"&gt;// We need to export that function from this private namespace so that&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="c1"&gt;// it can be used on the outside. In this case, we export the constructor&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="c1"&gt;// by returning it. It becomes the value of the assignment expression&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="c1"&gt;// on the first line above.&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;BrowserFrame&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="p"&gt;}());&lt;/span&gt; &lt;span class="c1"&gt;// Invoke the function immediately after defining it.&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;

</description></item><item><title>Mocha: MockMozActivity與global leak</title><pubDate>Sat, 23 Feb 2013 16:56:00 +0800</pubDate><guid isPermaLink="false">http://alivedise.github.io/blog/2013/02/23/mock-moz-activity</guid><description>&lt;p&gt;之前在寫單元測試時，需要測到MozActivity的呼叫。&lt;/p&gt;

&lt;p&gt;當我們嘗試去取代window object中的MozActivity時，會遇到：&lt;/p&gt;

&lt;figure class='code'&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class=''&gt;&lt;span class='line'&gt;0) Feed "before all" hook: Error: global leak detected:&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;解決方法：&lt;/p&gt;

&lt;!--more--&gt;


&lt;p&gt;在程式前面加上&lt;code&gt;mocha.setup({ignoreLeaks: true});&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;最後加上&lt;code&gt;mocha.setup({ignoreLeaks: true});&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;碰到這個錯誤是在嘗試加入假的MozActivity給window時。&lt;/p&gt;

&lt;p&gt;因為要被測試的module中有如下的程式片段：&lt;/p&gt;

&lt;figure class='code'&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;span class='line-number'&gt;2&lt;/span&gt;
&lt;span class='line-number'&gt;3&lt;/span&gt;
&lt;span class='line-number'&gt;4&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='line'&gt;  &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;MozActivity&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;view&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;url&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;去呼叫browser app開啟某個特定網頁，&lt;/p&gt;

&lt;p&gt;但是mocha跑的環境中有可能：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;並沒有window.MozActivity這個物件。&lt;/li&gt;
&lt;li&gt;有MozActivity但是我們無法知道他是否被呼叫。&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;這時候需要塞一個MockMozActivity給window，暫時取代掉原本的MozActivity，&lt;/p&gt;

&lt;p&gt;然後從MockMozActivity裡面留個變數記錄被呼叫的參數狀況來判斷程式是否正確的執行呼叫activity。&lt;/p&gt;

&lt;figure class='code'&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;span class='line-number'&gt;2&lt;/span&gt;
&lt;span class='line-number'&gt;3&lt;/span&gt;
&lt;span class='line-number'&gt;4&lt;/span&gt;
&lt;span class='line-number'&gt;5&lt;/span&gt;
&lt;span class='line-number'&gt;6&lt;/span&gt;
&lt;span class='line-number'&gt;7&lt;/span&gt;
&lt;span class='line-number'&gt;8&lt;/span&gt;
&lt;span class='line-number'&gt;9&lt;/span&gt;
&lt;span class='line-number'&gt;10&lt;/span&gt;
&lt;span class='line-number'&gt;11&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='line'&gt;&lt;span class="s1"&gt;&amp;#39;use strict&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;mockMozActivityInstance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;MockMozActivity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;MozActivity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;configuration&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;property&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;configuration&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;property&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;configuration&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;property&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="nx"&gt;mockMozActivityInstance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;之後寫的測試內容：&lt;/p&gt;

&lt;figure class='code'&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;span class='line-number'&gt;2&lt;/span&gt;
&lt;span class='line-number'&gt;3&lt;/span&gt;
&lt;span class='line-number'&gt;4&lt;/span&gt;
&lt;span class='line-number'&gt;5&lt;/span&gt;
&lt;span class='line-number'&gt;6&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='line'&gt;&lt;span class="c1"&gt;// Captive Portal Test&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;system/captive portal login w/o manual enable wifi&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="nx"&gt;CaptivePortal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;handleEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="nx"&gt;MockSettingsListener&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mCallback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="nx"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mockMozActivityInstance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;view&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;人生第一個單元測試程式完成 \O/&lt;/p&gt;
</description></item><item><title>Javascript memorization</title><pubDate>Sat, 22 Dec 2012 00:28:00 +0800</pubDate><guid isPermaLink="false">http://alivedise.github.io/blog/2012/12/22/javascript-memorization</guid><description>&lt;p&gt;As you know, function in javascript is also an object,
you could use a property of the object to keep function result.
This is called &lt;code&gt;Memorization&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Today I have a chance to utilize this skill.&lt;/p&gt;

&lt;p&gt;Please read codes below first:&lt;/p&gt;

&lt;figure class='code'&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;span class='line-number'&gt;2&lt;/span&gt;
&lt;span class='line-number'&gt;3&lt;/span&gt;
&lt;span class='line-number'&gt;4&lt;/span&gt;
&lt;span class='line-number'&gt;5&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='line'&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getOffOrigin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;frame&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;frame&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;frame&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;origin&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;subtitle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;p&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="nx"&gt;subtitle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;getOffOrigin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;frame&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;frame&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;frame&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;origin&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="nx"&gt;card&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;subtitle&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;




&lt;!--more--&gt;


&lt;p&gt;&lt;code&gt;getOffOrigin&lt;/code&gt; has to use some logic to compare the two arguments and return a string.
The result wouldn&amp;rsquo;t change if the arguments are the same.
Therefore, to avoid calling the function many times, the result could be stored in the function itself.&lt;/p&gt;

&lt;figure class='code'&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;span class='line-number'&gt;2&lt;/span&gt;
&lt;span class='line-number'&gt;3&lt;/span&gt;
&lt;span class='line-number'&gt;4&lt;/span&gt;
&lt;span class='line-number'&gt;5&lt;/span&gt;
&lt;span class='line-number'&gt;6&lt;/span&gt;
&lt;span class='line-number'&gt;7&lt;/span&gt;
&lt;span class='line-number'&gt;8&lt;/span&gt;
&lt;span class='line-number'&gt;9&lt;/span&gt;
&lt;span class='line-number'&gt;10&lt;/span&gt;
&lt;span class='line-number'&gt;11&lt;/span&gt;
&lt;span class='line-number'&gt;12&lt;/span&gt;
&lt;span class='line-number'&gt;13&lt;/span&gt;
&lt;span class='line-number'&gt;14&lt;/span&gt;
&lt;span class='line-number'&gt;15&lt;/span&gt;
&lt;span class='line-number'&gt;16&lt;/span&gt;
&lt;span class='line-number'&gt;17&lt;/span&gt;
&lt;span class='line-number'&gt;18&lt;/span&gt;
&lt;span class='line-number'&gt;19&lt;/span&gt;
&lt;span class='line-number'&gt;20&lt;/span&gt;
&lt;span class='line-number'&gt;21&lt;/span&gt;
&lt;span class='line-number'&gt;22&lt;/span&gt;
&lt;span class='line-number'&gt;23&lt;/span&gt;
&lt;span class='line-number'&gt;24&lt;/span&gt;
&lt;span class='line-number'&gt;25&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='line'&gt;  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;getOffOrigin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;origin&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="c1"&gt;// Use src and origin as cache key&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;cacheKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;getOffOrigin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;cacheKey&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="kr"&gt;native&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;getOriginObject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;origin&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;getOriginObject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;protocol&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;http:&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="c1"&gt;// Display http:// protocol anyway&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="nx"&gt;getOffOrigin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;cacheKey&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;protocol&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;//&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hostname&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kr"&gt;native&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;protocol&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;protocol&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;          &lt;span class="kr"&gt;native&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hostname&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hostname&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;          &lt;span class="kr"&gt;native&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;port&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;port&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="c1"&gt;// Same origin policy&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="nx"&gt;getOffOrigin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;cacheKey&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;protocol&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;app:&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="c1"&gt;// Avoid displaying app:// protocol&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="nx"&gt;getOffOrigin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;cacheKey&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="nx"&gt;getOffOrigin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;cacheKey&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;protocol&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;//&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hostname&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;getOffOrigin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;cacheKey&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="nx"&gt;getOffOrigin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cache&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;ul&gt;
&lt;li&gt;&lt;p&gt;If we only have one arguments we could use it as the key to cache directly.
But we have multiple arguments in this case, we then use stringilized JSON to be the key.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Hence we don&amp;rsquo;t need to do the same thing every time we enter this function if the arguments are used before.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Have fun with your function cache!&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description></item><item><title>Web activity</title><pubDate>Tue, 4 Sep 2012 15:45:00 +0800</pubDate><guid isPermaLink="false">http://alivedise.github.io/blog/2012/09/04/web-activity</guid><description>&lt;p&gt;Web activity是由Mozilla設計並開發，用來使web app之間共享資源的框架。
在Firefox OS中已經存在Platform/UI上的實作，並且有一些內建的主要Web app已經利用Web activity來達成跨應用程式溝通的目的。
（如：Gallery使用它來讓其他程式從它挑選圖片，也用同一技術來實現圖片分享到不同應用）&lt;/p&gt;

&lt;p&gt;以下介紹如何使用這個新穎的技術。&lt;/p&gt;

&lt;!--more--&gt;


&lt;h3&gt;Request&lt;/h3&gt;

&lt;p&gt;假設今天E-mail應用程式需要從圖片集中挑選圖片來寄送，
那麼它必須新增一個Activity物件如下：&lt;/p&gt;

&lt;figure class='code'&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;span class='line-number'&gt;2&lt;/span&gt;
&lt;span class='line-number'&gt;3&lt;/span&gt;
&lt;span class='line-number'&gt;4&lt;/span&gt;
&lt;span class='line-number'&gt;5&lt;/span&gt;
&lt;span class='line-number'&gt;6&lt;/span&gt;
&lt;span class='line-number'&gt;7&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='line'&gt;  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;MozActivity&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;browse&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;image/png&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;...&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;type欄位是用來當filter用的
在data中的其他欄位可以傳你想要的資料給接收方。&lt;/p&gt;

&lt;p&gt;當收到資料後，處理回呼函數的方式：&lt;/p&gt;

&lt;figure class='code'&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;span class='line-number'&gt;2&lt;/span&gt;
&lt;span class='line-number'&gt;3&lt;/span&gt;
&lt;span class='line-number'&gt;4&lt;/span&gt;
&lt;span class='line-number'&gt;5&lt;/span&gt;
&lt;span class='line-number'&gt;6&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='line'&gt;  &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onsuccess&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;on_success&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onerror&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;on_error&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;warn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;error when picking!&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;h3&gt;Reciever&lt;/h3&gt;

&lt;p&gt;接受某個Activity的App必須在Manifest.webapp中宣告：&lt;/p&gt;

&lt;figure class='code'&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;span class='line-number'&gt;2&lt;/span&gt;
&lt;span class='line-number'&gt;3&lt;/span&gt;
&lt;span class='line-number'&gt;4&lt;/span&gt;
&lt;span class='line-number'&gt;5&lt;/span&gt;
&lt;span class='line-number'&gt;6&lt;/span&gt;
&lt;span class='line-number'&gt;7&lt;/span&gt;
&lt;span class='line-number'&gt;8&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='line'&gt;&lt;span class="s2"&gt;&amp;quot;activities&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;   &lt;span class="s2"&gt;&amp;quot;pick&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;     &lt;span class="s2"&gt;&amp;quot;filters&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;       &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;image/png&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;image/gif&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;     &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;     &lt;span class="s2"&gt;&amp;quot;disposition&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;window&amp;quot;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;並且在自己的javascript檔中寫好當Activity產生時的處理函式&lt;/p&gt;

&lt;figure class='code'&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;span class='line-number'&gt;2&lt;/span&gt;
&lt;span class='line-number'&gt;3&lt;/span&gt;
&lt;span class='line-number'&gt;4&lt;/span&gt;
&lt;span class='line-number'&gt;5&lt;/span&gt;
&lt;span class='line-number'&gt;6&lt;/span&gt;
&lt;span class='line-number'&gt;7&lt;/span&gt;
&lt;span class='line-number'&gt;8&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='line'&gt;&lt;span class="nx"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setMozMessageHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;activity&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;getImageToReturn&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;image&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;postError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;NoImage&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;postResult&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;image/png&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;image&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;h4&gt;data/type的用法&lt;/h4&gt;

&lt;p&gt;如聯絡人程式可以接受同一個叫做pick的Activity，
但是電子郵件程式需要的是&amp;#8217;email&amp;#8217;這類資料，
而電話程式需要的是&amp;#8217;號碼&amp;#8217;這類資料，
對於這兩類資料需要呈現的UI與最後傳回去的資料當然會是不一樣的。&lt;/p&gt;

&lt;p&gt;解決方法就是利用不同的data type來區分同種activity的不同需求：&lt;/p&gt;

&lt;figure class='code'&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;span class='line-number'&gt;2&lt;/span&gt;
&lt;span class='line-number'&gt;3&lt;/span&gt;
&lt;span class='line-number'&gt;4&lt;/span&gt;
&lt;span class='line-number'&gt;5&lt;/span&gt;
&lt;span class='line-number'&gt;6&lt;/span&gt;
&lt;span class='line-number'&gt;7&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='line'&gt;  &lt;span class="c1"&gt;// Email app&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;MozActivity&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;pick&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;web-content/email&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;figure class='code'&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;span class='line-number'&gt;2&lt;/span&gt;
&lt;span class='line-number'&gt;3&lt;/span&gt;
&lt;span class='line-number'&gt;4&lt;/span&gt;
&lt;span class='line-number'&gt;5&lt;/span&gt;
&lt;span class='line-number'&gt;6&lt;/span&gt;
&lt;span class='line-number'&gt;7&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='line'&gt;  &lt;span class="c1"&gt;// Dialer app&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;MozActivity&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;pick&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;web-content/numbers&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;在聯絡人程式中&lt;/p&gt;

&lt;figure class='code'&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;span class='line-number'&gt;2&lt;/span&gt;
&lt;span class='line-number'&gt;3&lt;/span&gt;
&lt;span class='line-number'&gt;4&lt;/span&gt;
&lt;span class='line-number'&gt;5&lt;/span&gt;
&lt;span class='line-number'&gt;6&lt;/span&gt;
&lt;span class='line-number'&gt;7&lt;/span&gt;
&lt;span class='line-number'&gt;8&lt;/span&gt;
&lt;span class='line-number'&gt;9&lt;/span&gt;
&lt;span class='line-number'&gt;10&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='line'&gt;&lt;span class="nx"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setMozMessageHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;activity&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="k"&gt;switch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;source&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;webcontacts/numbers&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;webcontacts/email&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;如此一來就可以分開處理UI變化及後續回傳資料的部分。&lt;/p&gt;

&lt;h3&gt;多於一個可以處理的Reciever?&lt;/h3&gt;

&lt;p&gt;比如圖片應用程式可以分享的對象有兩個以上的時候，
Firefox OS的系統UI便會自動列出可用的應用程式清單，如圖：
&lt;img src="http://i.imgur.com/V2rgq.jpg"&gt;
&lt;img src="http://i.imgur.com/xcgBK.png"&gt;
&lt;img src="http://i.imgur.com/UpaOC.png"&gt;&lt;/p&gt;

&lt;h3&gt;結論&lt;/h3&gt;

&lt;p&gt;Web activity是一個實驗中的新功能，雖然還有一些地方未盡完善，
但是看著它從spec到platform implementation到UI implementation，
就好像親身參與了網路/網頁進化的過程一樣。&lt;/p&gt;
</description></item><item><title>[gaia] HTML5 Window Shade</title><pubDate>Thu, 5 Jul 2012 13:58:00 +0800</pubDate><guid isPermaLink="false">http://alivedise.github.io/blog/2012/07/05/gaia-window-shade</guid><description>&lt;h1&gt;Window Shade&lt;/h1&gt;

&lt;p&gt;我手上的Samsung Galaxy S3的作業系統是Android 4.0.4。&lt;/p&gt;

&lt;p&gt;當我收到facebook/google+/&amp;hellip;等程式通知的時候，最上面那條bar會出現對應的圖示。&lt;/p&gt;

&lt;p&gt;這時候可以透過將bar「滑下來」的動作拉出一個UI，裡面會有&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;快速設定&lt;/li&gt;
&lt;li&gt;通知項目詳細列表&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;&lt;img src="http://i.imgur.com/nU76i.png"&gt;&lt;/p&gt;

&lt;p&gt;這個UX，Google把它稱為&lt;b&gt;Window shade&lt;/b&gt;&lt;/p&gt;

&lt;!--more--&gt;


&lt;p&gt;神奇的地方在於當你在拉下或拉上面板的同時，
快速設定與通知項目是會先「掉下來」到底端，
到了項目的頂端出現之後才會黏在頂部。
（相信我你沒有特別注意這件事情，而且用久了會覺得理所當然）&lt;/p&gt;

&lt;h1&gt;GAIA也有notification panel&lt;/h1&gt;

&lt;p&gt;Firefox OS的UI &amp;ndash; &lt;a href="http://github.com/mozilla-central/gaia"&gt;GAIA&lt;/a&gt;裡面也有定義功能列以及通知面板這件事，
這個功能正在開發中。&lt;/p&gt;

&lt;p&gt;有一天我們收到某個contributor提交的pull request：&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/mozilla-b2g/gaia/pull/1898"&gt;Gaia pull request#1898&lt;/a&gt;
節錄重要的修改如下：&lt;/p&gt;

&lt;figure class='code'&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;span class='line-number'&gt;2&lt;/span&gt;
&lt;span class='line-number'&gt;3&lt;/span&gt;
&lt;span class='line-number'&gt;4&lt;/span&gt;
&lt;span class='line-number'&gt;5&lt;/span&gt;
&lt;span class='line-number'&gt;6&lt;/span&gt;
&lt;span class='line-number'&gt;7&lt;/span&gt;
&lt;span class='line-number'&gt;8&lt;/span&gt;
&lt;span class='line-number'&gt;9&lt;/span&gt;
&lt;span class='line-number'&gt;10&lt;/span&gt;
&lt;span class='line-number'&gt;11&lt;/span&gt;
&lt;span class='line-number'&gt;12&lt;/span&gt;
&lt;span class='line-number'&gt;13&lt;/span&gt;
&lt;span class='line-number'&gt;14&lt;/span&gt;
&lt;span class='line-number'&gt;15&lt;/span&gt;
&lt;span class='line-number'&gt;16&lt;/span&gt;
&lt;span class='line-number'&gt;17&lt;/span&gt;
&lt;span class='line-number'&gt;18&lt;/span&gt;
&lt;span class='line-number'&gt;19&lt;/span&gt;
&lt;span class='line-number'&gt;20&lt;/span&gt;
&lt;span class='line-number'&gt;21&lt;/span&gt;
&lt;span class='line-number'&gt;22&lt;/span&gt;
&lt;span class='line-number'&gt;23&lt;/span&gt;
&lt;span class='line-number'&gt;24&lt;/span&gt;
&lt;span class='line-number'&gt;25&lt;/span&gt;
&lt;span class='line-number'&gt;26&lt;/span&gt;
&lt;span class='line-number'&gt;27&lt;/span&gt;
&lt;span class='line-number'&gt;28&lt;/span&gt;
&lt;span class='line-number'&gt;29&lt;/span&gt;
&lt;span class='line-number'&gt;30&lt;/span&gt;
&lt;span class='line-number'&gt;31&lt;/span&gt;
&lt;span class='line-number'&gt;32&lt;/span&gt;
&lt;span class='line-number'&gt;33&lt;/span&gt;
&lt;span class='line-number'&gt;34&lt;/span&gt;
&lt;span class='line-number'&gt;35&lt;/span&gt;
&lt;span class='line-number'&gt;36&lt;/span&gt;
&lt;span class='line-number'&gt;37&lt;/span&gt;
&lt;span class='line-number'&gt;38&lt;/span&gt;
&lt;span class='line-number'&gt;39&lt;/span&gt;
&lt;span class='line-number'&gt;40&lt;/span&gt;
&lt;span class='line-number'&gt;41&lt;/span&gt;
&lt;span class='line-number'&gt;42&lt;/span&gt;
&lt;span class='line-number'&gt;43&lt;/span&gt;
&lt;span class='line-number'&gt;44&lt;/span&gt;
&lt;span class='line-number'&gt;45&lt;/span&gt;
&lt;span class='line-number'&gt;46&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='line'&gt;  &lt;span class="nx"&gt;onTouchMove&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;ut_onTouchMove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;touch&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;screenHeight&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;overlay&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getBoundingClientRect&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="nx"&gt;gripBarHeight&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;gripBar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getBoundingClientRect&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="nx"&gt;dy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;startY&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;touch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pageY&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="nx"&gt;newHeight&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;shown&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="nx"&gt;dy&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;screenHeight&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="nx"&gt;dy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;screenHeight&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;dy&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dy&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;gripBarHeight&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;quickSettingsHeight&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;quickSettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getBoundingClientRect&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dy&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;quickSettingsHeight&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;gripBarHeight&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="nx"&gt;newHeight&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;screenHeight&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;quickSettingsHeight&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;gripBarHeight&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="nx"&gt;newHeight&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;screenHeight&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;dy&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;quickSettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MozTransition&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;quickSettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MozTransform&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;translateY(&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;newHeight&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;px)&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;overlay&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MozTransition&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MozTransform&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;translateY(&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;dy&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;px)&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="c1"&gt;//....skiped...&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="nx"&gt;show&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;ut_show&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dy&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;alreadyShown&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;shown&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="nx"&gt;trayStyle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;overlay&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="nx"&gt;quickSettingsStyle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;quickSettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="nx"&gt;trayStyle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MozTransition&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;-moz-transform 0.2s linear&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="nx"&gt;trayStyle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MozTransform&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;translateY(100%)&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="nx"&gt;quickSettingsStyle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MozTransition&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;-moz-transform 0.2s linear&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="nx"&gt;quickSettingsStyle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MozTransform&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;translateY(0px)&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;shown&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;utility-tray&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;alreadyShown&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;evt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;CustomEvent&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="nx"&gt;evt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;initCustomEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;utilitytrayshow&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dispatchEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;evt&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;原作者提到他做這件事是要讓&lt;code&gt;quick-setting&lt;/code&gt;更快的出現。
這段code也已經被merge了。&lt;/p&gt;

&lt;h1&gt;不過就在昨天同事發現了一個關於功能列的issue&lt;/h1&gt;

&lt;p&gt;於是我開始看發生了什麼事。然後上面那兩個function耗費了我一個下午&amp;hellip;.XD&lt;/p&gt;

&lt;p&gt;@colinfrei其實做了一件非常有趣但是很難從code裡面看出端倪的事情。
甚至也很難用語言來描述，不過我想試著說明發生了什麼事，怎麼做到的。&lt;/p&gt;

&lt;p&gt;簡單的說，他利用兩個「不同」區塊的CSS3的Transition「同步化」來實現剛剛所提的Window Shade的行為。&lt;/p&gt;

&lt;h2&gt;CSS: Transition&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://developer.mozilla.org/en/CSS/transition"&gt;參閱MDN: transition&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;CSS: Transform&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://developer.mozilla.org/en/CSS/transform"&gt;參閱MDN: transform&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;真相其實是：&lt;/h1&gt;

&lt;ol&gt;
&lt;li&gt;&lt;code&gt;utility-tray&lt;/code&gt;是一個絕對定位的&lt;code&gt;div&lt;/code&gt;，平常位置定在螢幕上方&lt;code&gt;-moz-calc(100% &amp;ndash; UTILITY_TRAY_HEIGHT)&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;p&gt;當你開始Touch的時候，根據你的移動距離計算&lt;code&gt;translateY&lt;/code&gt;，使它產生位移&lt;/p&gt;

&lt;p&gt; 你可以把&lt;code&gt;-moz-transform: translateY(px)&lt;/code&gt;當成是&lt;code&gt;top: px&lt;/code&gt;在CSS3的新招。
 它提供了更快速的rendering &amp;mdash; 當你想利用&lt;code&gt;-moz-transition: -moz-transform&lt;/code&gt;來做位移動畫的時候。
 這件事情可以另外寫一篇文章來說（挖洞的意味）。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;當你放開拉bar的時候而且如果已經超過「要讓通知面板掉下來的合法距離」：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;設定一個&lt;code&gt;MozTransition&lt;/code&gt;給&lt;code&gt;utility-tray-overlay&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;再設定一個&lt;code&gt;MozTransition&lt;/code&gt;給&lt;code&gt;quick-setting&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;4.讓&lt;code&gt;utility-tray&lt;/code&gt;整個以某個定速掉下來到螢幕底端 + 讓&lt;code&gt;quick-setting&lt;/code&gt;以同樣的定速往上移動到&lt;code&gt;utility-tray&lt;/code&gt;的開端&lt;/p&gt;

&lt;p&gt;  = 於是就造成了&lt;code&gt;quick-setting&lt;/code&gt;似乎黏在通知列下方不動但整個面板是往下掉的假象！&lt;/p&gt;

&lt;h1&gt;the story continues&lt;/h1&gt;

&lt;p&gt;不過可惜的是似乎沒有考慮到當通知面板要滑上去的時候，&lt;/p&gt;

&lt;p&gt;「有物件的部份也應該留在頂端直到被拉bar撞到一起彈上去」這件事&lt;/p&gt;

&lt;p&gt;於是我也仿造這個作法另外送了一個pull request&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/mozilla-b2g/gaia/pull/2181"&gt;GAIA pull request#2181&lt;/a&gt;&lt;/p&gt;

&lt;figure class='code'&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;span class='line-number'&gt;2&lt;/span&gt;
&lt;span class='line-number'&gt;3&lt;/span&gt;
&lt;span class='line-number'&gt;4&lt;/span&gt;
&lt;span class='line-number'&gt;5&lt;/span&gt;
&lt;span class='line-number'&gt;6&lt;/span&gt;
&lt;span class='line-number'&gt;7&lt;/span&gt;
&lt;span class='line-number'&gt;8&lt;/span&gt;
&lt;span class='line-number'&gt;9&lt;/span&gt;
&lt;span class='line-number'&gt;10&lt;/span&gt;
&lt;span class='line-number'&gt;11&lt;/span&gt;
&lt;span class='line-number'&gt;12&lt;/span&gt;
&lt;span class='line-number'&gt;13&lt;/span&gt;
&lt;span class='line-number'&gt;14&lt;/span&gt;
&lt;span class='line-number'&gt;15&lt;/span&gt;
&lt;span class='line-number'&gt;16&lt;/span&gt;
&lt;span class='line-number'&gt;17&lt;/span&gt;
&lt;span class='line-number'&gt;18&lt;/span&gt;
&lt;span class='line-number'&gt;19&lt;/span&gt;
&lt;span class='line-number'&gt;20&lt;/span&gt;
&lt;span class='line-number'&gt;21&lt;/span&gt;
&lt;span class='line-number'&gt;22&lt;/span&gt;
&lt;span class='line-number'&gt;23&lt;/span&gt;
&lt;span class='line-number'&gt;24&lt;/span&gt;
&lt;span class='line-number'&gt;25&lt;/span&gt;
&lt;span class='line-number'&gt;26&lt;/span&gt;
&lt;span class='line-number'&gt;27&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='line'&gt;  &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;transitionend&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;shown&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;utility-tray&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;overlayStyle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;overlay&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;firstShownStyle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;firstShowStyle&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="nx"&gt;firstShownStyle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MozTransition&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;phase2hide&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="nx"&gt;firstShownStyle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MozTransition&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;-moz-transform 0.2s linear&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="nx"&gt;firstShownStyle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MozTransform&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;          &lt;span class="s1"&gt;&amp;#39;translateY(&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;firstShownPosition&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;px)&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="nx"&gt;overlayStyle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MozTransition&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;-moz-transform 0.2s linear&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="nx"&gt;overlayStyle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MozTransform&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;translateY(0)&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="c1"&gt;// Check the transition event is triggered at firstShown.&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="c1"&gt;// If so, turn off the flag which represent for&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="c1"&gt;// &amp;#39;The overlay has already reached the bottom of quick-setting&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;evt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;firstShown&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;          &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;phase2hide&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="c1"&gt;// Reset position of this.firstShown&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;firstShown&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MozTransition&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;firstShown&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MozTransform&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;translateY(0)&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;      &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;利用&lt;code&gt;transitionend&lt;/code&gt; event callback，透過連續兩次的&lt;code&gt;Transition&lt;/code&gt;來：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;讓&lt;code&gt;utility-tray&lt;/code&gt;先定速往上移動/讓&lt;code&gt;quick-setting&lt;/code&gt;定速往下移動到底端。&lt;/li&gt;
&lt;li&gt;等到&lt;code&gt;utility-tray&lt;/code&gt;的transition結束時，會收到&lt;code&gt;transitionend&lt;/code&gt;的事件。
 這時候再讓&lt;code&gt;utility-tray&lt;/code&gt;進行第二次transition&amp;hellip;而目的地就是螢幕頂端。
 同時&lt;code&gt;quick-setting&lt;/code&gt;就不再動作了，讓它跟著&lt;code&gt;utility-tray&lt;/code&gt;一起被往上卷走。&lt;/li&gt;
&lt;/ol&gt;


&lt;h2&gt;transitionend&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://developer.mozilla.org/zh_tw/CSS_%E8%BD%89%E5%A0%B4#.E5.81.B5.E6.B8.AC_transition_.E7.9A.84.E5.AE.8C.E6.88.90"&gt;參閱MDN: transitionend&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;the end?&lt;/h1&gt;

&lt;p&gt;其實UX還沒有定義這個行為，所以pull request本身沒有被接受。
不過&amp;hellip;I did learn something from these codes:)&lt;/p&gt;
</description></item><item><title>[WEB] Web Application Core</title><pubDate>Sun, 10 Jun 2012 17:06:00 +0800</pubDate><guid isPermaLink="false">http://alivedise.github.io/blog/2012/06/10/web-application-core</guid><description>&lt;p&gt;最近看到這篇文章&lt;a href="http://addyosmani.github.com/backbone-aura/"&gt;Backbone Aura&lt;/a&gt;難得的有提到一個web application core該做些什麼事情？跟我想的蠻相似的，這邊將他列出來：
* 管理widget的life cycle的能力。
* 低階DOM操作處理
* 提供publish/subscribe的溝通管道給應用程式的各部位互相溝通&lt;/p&gt;

&lt;p&gt;以下是我流解析。&lt;/p&gt;

&lt;h2&gt;管理widget的life cycle&lt;/h2&gt;

&lt;p&gt;Core是應用程式的進入點(entry poing)，它必須在適當的時機init需要的widget/application part起來做事情，也只有Core才知道什麼時候必須做這些事情。當然也包括在適當的時機讓widget沈睡或消滅。&lt;/p&gt;

&lt;h2&gt;低階DOM操作&lt;/h2&gt;

&lt;p&gt;這有點像jQuery library主要在做的事情，不過世界上不是只有jQuery一種library，也不是任何情況下都可以用jQuery，有一個可以快速操作DOM的方法是必要的。&lt;/p&gt;

&lt;h2&gt;提供publish/subscribe的溝通方式&lt;/h2&gt;

&lt;p&gt;解耦後的application part/widget當然不能直接呼叫別人的attribute function（不然還解什麼耦），那要怎麼叫別人做事？行之有年的publish/subscribe機制在jmvc已經被整合進去，backbone上面還欠缺方法，backbone aura把這件事做出來了。&lt;/p&gt;

&lt;p&gt;然後因為好奇它怎麼做的就看了一下source，在&lt;code&gt;aura/www/js/aura/mediator.js&lt;/code&gt;裡面定義了：&lt;/p&gt;

&lt;figure class='code'&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;span class='line-number'&gt;2&lt;/span&gt;
&lt;span class='line-number'&gt;3&lt;/span&gt;
&lt;span class='line-number'&gt;4&lt;/span&gt;
&lt;span class='line-number'&gt;5&lt;/span&gt;
&lt;span class='line-number'&gt;6&lt;/span&gt;
&lt;span class='line-number'&gt;7&lt;/span&gt;
&lt;span class='line-number'&gt;8&lt;/span&gt;
&lt;span class='line-number'&gt;9&lt;/span&gt;
&lt;span class='line-number'&gt;10&lt;/span&gt;
&lt;span class='line-number'&gt;11&lt;/span&gt;
&lt;span class='line-number'&gt;12&lt;/span&gt;
&lt;span class='line-number'&gt;13&lt;/span&gt;
&lt;span class='line-number'&gt;14&lt;/span&gt;
&lt;span class='line-number'&gt;15&lt;/span&gt;
&lt;span class='line-number'&gt;16&lt;/span&gt;
&lt;span class='line-number'&gt;17&lt;/span&gt;
&lt;span class='line-number'&gt;18&lt;/span&gt;
&lt;span class='line-number'&gt;19&lt;/span&gt;
&lt;span class='line-number'&gt;20&lt;/span&gt;
&lt;span class='line-number'&gt;21&lt;/span&gt;
&lt;span class='line-number'&gt;22&lt;/span&gt;
&lt;span class='line-number'&gt;23&lt;/span&gt;
&lt;span class='line-number'&gt;24&lt;/span&gt;
&lt;span class='line-number'&gt;25&lt;/span&gt;
&lt;span class='line-number'&gt;26&lt;/span&gt;
&lt;span class='line-number'&gt;27&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;/**&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt; * Subscribe to an event&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt; * @param {string} channel Event name&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt; * @param {object} subscription Module callback&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt; * @param {object} context Context in which to execute the module&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt; */&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subscribe&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="nx"&gt;channels&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;channels&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;channels&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="nx"&gt;channels&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;util&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;/**&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt; * Publish an event, passing arguments to subscribers. Will&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt; * call start if the channel is not already registered.&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt; * @param {string} channel Event name&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt; */&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;publish&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;l&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;args&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[].&lt;/span&gt;&lt;span class="nx"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;channels&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;apply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;l&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;channels&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;l&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;        &lt;span class="nx"&gt;channels&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;apply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;看起來是利用一個變數來根據widget name儲存callback function進array裡面。&lt;/p&gt;
</description></item><item><title>[javascript] function hoisting應用</title><pubDate>Sun, 10 Jun 2012 16:17:00 +0800</pubDate><guid isPermaLink="false">http://alivedise.github.io/blog/2012/06/10/function-hoisting-appliance</guid><description>&lt;h1&gt;function hoisting是什麼？&lt;/h1&gt;

&lt;p&gt;一個不說你也不會知道的js語言特性，是指js看到function xxx(){}這種宣告時會把定義搬到scope最頂端
的行為，hoisting的意思是提昇。&lt;/p&gt;

&lt;p&gt;自從在Javascript Patterns這本書上面看到hoisting的時候，就一直在想到底有什麼場合可以用到這個奇妙的語言特性？想不到還真的遇到了，雖然其實是個反例XD&lt;/p&gt;

&lt;p&gt;原文出自PTT Web_Design版「&lt;a href="http://www.ptt.cc/bbs/Ajax/M.1339127132.A.226.html"&gt;[問題] jQuery 參數的問題~&lt;/a&gt;」，這名網友問為什麼下面的js不能用？&lt;/p&gt;

&lt;!--more--&gt;




&lt;figure class='code'&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;span class='line-number'&gt;2&lt;/span&gt;
&lt;span class='line-number'&gt;3&lt;/span&gt;
&lt;span class='line-number'&gt;4&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='line'&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;#test&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;click&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;aaa&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;aaa&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="nx"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;yo&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;h2&gt;好傻好天真？&lt;/h2&gt;

&lt;p&gt;雖然不知道為什麼提問者堅持要把函數宣告放在用它之前，不過既然他問了，剛好這情況可以利用function hoisting來做，只是要修改一些小地方。&lt;/p&gt;

&lt;figure class='code'&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;span class='line-number'&gt;2&lt;/span&gt;
&lt;span class='line-number'&gt;3&lt;/span&gt;
&lt;span class='line-number'&gt;4&lt;/span&gt;
&lt;span class='line-number'&gt;5&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='line'&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;#test&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;click&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;aaa&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;aaa&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;  &lt;span class="nx"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;yo&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="cm"&gt;/* function expression instead of function declaration */&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;我另外寫了一個jsfiddle來測試：&lt;/p&gt;

&lt;iframe style="width: 100%; height: 300px" src="http://jsfiddle.net/Ytmqw/embedded/js,resources,html,css,result/light/"&gt;&lt;/iframe&gt;


&lt;h1&gt;做的到，只不過真的有必要嗎？&lt;/h1&gt;

&lt;p&gt;真的有太多理由不建議這樣做。原po在我回文後也沒出現，看來也無從得知他這樣做的理由了。&lt;/p&gt;
</description></item><item><title>把assignment變數轉成JSON格式</title><pubDate>Thu, 31 May 2012 10:53:00 +0800</pubDate><guid isPermaLink="false">http://alivedise.github.io/blog/2012/05/31/underline-to-json</guid><description>&lt;p&gt;從Server端收到的資訊是如下格式&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;user_i0_name=alive
user_i0_gender=male
user_i0_age=27
user_i0_company_c0_name=VIVOTEK
user_i0_company_c1_name=Mozilla
system_model=ABC1234
network_hostname=abc1234
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;但是這些資訊很難使用，想透過某個統一的方法把它轉成object來用。
另外存回去的時候要把object轉回跟上面一樣的assignment。&lt;/p&gt;

&lt;h1&gt;Step#1: eval拆解進區域變數&lt;/h1&gt;

&lt;p&gt;為了避免污染全域變數，前後取代原本的字串：&lt;/p&gt;

&lt;figure class='code'&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;span class='line-number'&gt;2&lt;/span&gt;
&lt;span class='line-number'&gt;3&lt;/span&gt;
&lt;span class='line-number'&gt;4&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='line'&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;object&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;string_rev_1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;object[\&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/\r\n$/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/\r\n/gi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;\r\nobject[\&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/=/gi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;\&amp;#39;]=&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="nb"&gt;eval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;string_rev_1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class='line'&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;現在得到了一個只有一層的object，是好用了一點，但是能不能切出多層來？&lt;/p&gt;

&lt;h1&gt;Step#2: 用底線切object&lt;/h1&gt;

&lt;figure class='code'&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='line'&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;string_rev_2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;string_rev_1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/_/gi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;\&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;但是這樣會有undefined的問題，如&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;user_i0_name=alive
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;會變成&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;object['user']['i0']['name']=alive
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;eval後會出現&lt;code&gt;i10 is undefined.&lt;/code&gt;
所以要想辦法解決這種超前reference的狀況。&lt;/p&gt;

&lt;p&gt;一個辦法是用&lt;code&gt;\r\n&lt;/code&gt;切分assignment後個別eval，再用try catch區塊判斷是否發生超前定義的情況。
假設發生了就個別處理該assignment。&lt;/p&gt;

&lt;p&gt;(待續)&lt;/p&gt;
</description></item><item><title>CanJS簡介</title><pubDate>Wed, 30 May 2012 17:33:00 +0800</pubDate><guid isPermaLink="false">http://alivedise.github.io/blog/2012/05/30/can-js</guid><description>&lt;h1&gt;CanJS是什麼？&lt;/h1&gt;

&lt;p&gt;CanJS是JMVC團隊把MVC這一塊獨立出來的結果，並且做了一些改良。以往談到JavascriptMVC跟Backbone的時候，其實這兩個框架的目的是不同的。
JMVC除了MVC還提供其他的case solution，而Backbone只專注在MVC身上。另外一個不同點是JMVC當時的MVC framework只能綁定在jQuery上面，Backbone可以把核心抽換成zepto(一個類似于jQuery但輕量化的js lib)，這也是有手機網頁app使用backbone卻沒有人使用jmvc的原因。&lt;/p&gt;

&lt;h1&gt;CanJS&lt;/h1&gt;

&lt;p&gt;&lt;a href="http://canjs.us"&gt;CanJS官網&lt;/a&gt;
以下節錄幾個要點：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;核心可抽換成Zepto, jQuery, YUI, Dojo, Mootools。&lt;/li&gt;
&lt;li&gt;非常快，
&lt;img src="http://bitovi.com/images/introducing-canjs/performance_control.png"&gt;
&lt;img src="http://bitovi.com/images/introducing-canjs/performance_livebind.png"&gt;
比較令我訝異的是backbone竟然沒有live binding功能？&lt;/li&gt;
&lt;li&gt;安全的Model。jqueryMX一個缺點是常常會有內容相同的model instance，CanJS解決了這點。它保證相同內容的Object只會有一個instance。&lt;/li&gt;
&lt;li&gt;View可以做live binding了，直接對應Model change。&lt;/li&gt;
&lt;/ol&gt;


&lt;h1&gt;展望&lt;/h1&gt;

&lt;p&gt;以往JMVC為人詬病的就是本身提供的東西太複雜，不會有全部學完的動力。看來CanJS可以在專心這件事上趕上Backbone。&lt;/p&gt;
</description></item><item><title>「WEB」我也有一個故事要說。</title><pubDate>Wed, 30 May 2012 04:15:00 +0800</pubDate><guid isPermaLink="false">http://alivedise.github.io/blog/2012/05/30/i-have-also-a-story-to-tell</guid><description>&lt;p&gt;這個部落格在我的定位中是純技術取向，但這篇應該會是唯一一篇非關技術的文章。&lt;/p&gt;

&lt;p&gt;文長。&lt;/p&gt;

&lt;p&gt;我在確定得到新工作的那一天，在ptt soft_job以及web_design版發表了那段時間的面試心得，內容是有關前端工程師的工作面試經歷。（文章在&lt;a href="http://www.ptt.cc/bbs/Soft_Job/M.1335873183.A.F23.html"&gt;http://www.ptt.cc/bbs/Soft_Job/M.1335873183.A.F23.html&lt;/a&gt;）因為那篇文章我收到很多回應，也很感謝所有來信的人的鼓勵。就在明天我將要離開現在的公司然後到新公司報到，我想在這邊簡單寫下一個平凡的網頁工程師一路走來的心路歷程。一些細碎片段構成的過往。&lt;/p&gt;

&lt;p&gt;&lt;img src="http://i.imgur.com/CB6eE.jpg"&gt;&lt;/p&gt;

&lt;!--more--&gt;


&lt;h3&gt;0&lt;/h3&gt;

&lt;p&gt;我是一個普通的大學畢業生，大學混了六年才畢業。相當然爾在就業市場上只能任人魚肉，剛退伍時進入了一間要做嵌入式系統的公司。而我幾乎什麼也不會，就只有一個在學歷上跌倒的經驗而已。&lt;/p&gt;

&lt;h3&gt;1&lt;/h3&gt;

&lt;p&gt;如前文所講，沒寫過網頁之前我很看不起寫網頁的人。現在呢？真的覺得WEB很有意思。技術發展很快又很廣，隨便找一項鑽研都能玩很久。每天睜開眼都有新的東西產生。&lt;b&gt;你永遠不會覺得無聊&lt;/b&gt;。&lt;/p&gt;

&lt;p&gt;大家都知道新人就是要打雜，而寫網頁這件事本身在某些公司就是一種雜務。不幸的是在公司某些部門內，網頁都會丟給新人負責，新人來了再給新人。裡面充滿着陳舊不堪參疵不齊的程式碼，那個年代jQuery剛崛起，會看到js檔內有部分jQuery寫法，有部分是javascript原生寫法。而我第一個案子就是接手這樣的網頁開發新功能。結束之後仍然不知道自己會了什麼。&lt;/p&gt;

&lt;p&gt;第二個案子是作一個很龐大的web application，而這個案子一拖就是快兩年，也是我初嘗開發網頁快樂與痛苦的來源。&lt;/p&gt;

&lt;h3&gt;2&lt;/h3&gt;

&lt;p&gt;&lt;img src="http://i.imgur.com/CMRWv.jpg"&gt;&lt;/p&gt;

&lt;p&gt;題外話，你們知道嗎，IPAD上有一款app叫zite，它會根據你看文章的喜好來決定要給你什麼material。唯一的缺點是不支援中文，文章source都是英文，不過英文資源本來就多於中文。所以當你看完一篇在寫css hack的文章，旁邊就有選項問你喜不喜歡，順便列出跟css相關的tag給你toggle。你會收到越來越多你想要的相關知識。我有一陣子睡前會躺在床上抱著ipad看新技術文章看到睡著。&lt;/p&gt;

&lt;p&gt;即使是最漫長的那段日子也是一樣。&lt;/p&gt;

&lt;h3&gt;3&lt;/h3&gt;

&lt;p&gt;&lt;img src="http://i.imgur.com/R7n2P.png"&gt;&lt;/p&gt;

&lt;p&gt;我認為部落格的蓬勃發展很大的促進了技術分享這件事。當你遇到問題的時候你會google，而解決你的問題的通常是來自某個熱血的開發者的部落格的某篇獨門心得。我一開始只把這些部落格當成解決問題的手段，平常沒事不會去看。&lt;/p&gt;

&lt;p&gt;但後來有天我突然覺得沒有他們日子會很難過，而這時候我也確定自己想走web這一塊。我開始注意每個web developer的部落格，其中提到非技術的部分。&lt;b&gt;很大一部分在說自己對於這一塊的熱情與期望。&lt;/b&gt;
檯面上的技術心得文，檯面下往往是要十倍百倍於文字量的熱情支撐。&lt;/p&gt;

&lt;p&gt;比如熱血的前Y!前端工程師Josephj(我從他的部落格知道F2E這個字的意義。)&lt;/p&gt;

&lt;p&gt;比如版上很熱心的TonyQ大大在版上的每篇熱心文章。&lt;/p&gt;

&lt;p&gt;比如我剛進前公司時發現公司裡面有個好人前輩有在經營部落格分享自己在open source的知識跟經驗，那時候就很想認識他但覺得自己不是個咖所以沒膽去搭訕認識。&lt;/p&gt;

&lt;p&gt;比如這個中國人寫的部落格：&lt;a href="http://coolshell.cn"&gt;酷殼&lt;/a&gt;，作者是Amazon中國研發經理，
裡面的文章不一定全都跟Web相關，我第一次讀是從這篇開始：&lt;a href="http://coolshell.cn/articles/1932.html"&gt;哥是玩程序的&lt;/a&gt;。但後來我發現更有價值的東西不只是javascript相關的有趣文章，而是他的工作思想，是他提倡&lt;b&gt;將工作提升到事業層次&lt;/b&gt;這個想法，
如：&lt;a href="http://coolshell.cn/articles/6346.html"&gt;程序員因為女孩而美麗！&lt;/a&gt;，&lt;a href="http://coolshell.cn/articles/7186.html"&gt;做個環保主義的程序員&lt;/a&gt;，&lt;a href="http://coolshell.cn/articles/6142.html"&gt;三個事與三個問題&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;然後我也開始自己寫部落格，是因為有天看到某篇文章說，現在工程師面試需要的是：自己經營的技術部落格，github上的帳號等等。然後我就這麼做了，申請github帳號，先用自己的NAS架wordpress，後來覺得很難用，看到XDite等前輩在推octopress，剛好github也可以玩，就轉到github pages發展了。&lt;/p&gt;

&lt;p&gt;以上這些跟我的工作其實都沒有直接關係，都是利用下班的空閒時間做的。&lt;/p&gt;

&lt;h3&gt;4&lt;/h3&gt;

&lt;p&gt;&lt;img src="http://i.imgur.com/V8dg6.jpg" title="有人問我這是什麼？最後一個下班者拿走鑰匙的簽名。被跳過的平常日期是：沒回家。" &gt;&lt;/p&gt;

&lt;p&gt;然後就是那個一直被傳頌的故事。&lt;/p&gt;

&lt;p&gt;我不知道是不是每一間公司都有保全系統。我們公司跟中X保全簽約，每一天必須關門的時間是半夜12點。這半年來我每一天幾乎都超過12點下班，今年初變本加厲到凌晨3,4,5,6,7,8點，然後隔天依然九點半上班。我每天晚上都會打電話給中x保全說我要加班，請延長保全時間。到後來他們都知道了，只要我們公司過了半夜兩點還沒設定保全，他們會直接打電話到我私人手機問我在不在公司。&lt;/p&gt;

&lt;p&gt;而我通常都在。&lt;/p&gt;

&lt;p&gt;嗯，我知道你要問為什麼？&lt;/p&gt;

&lt;p&gt;前公司並不是很重視WEB技術，但這個專案的規格跟複雜度遠遠超出他們的輕蔑。對當時的我來說，我覺得以自己當時的知識完全不足以開發出那個大型Web Application，但也只能硬著頭皮幹。隨著專案時間越拉越長，無止盡的會議，UI上的功能需求越改越多，越來越複雜，到我離開的時候整個網站介面翻掉了七次之多。就像OSDC中那個需求變更的lighting talk講的好，&lt;b&gt;權威人士握有對你的東西的最高指導權。&lt;/b&gt;而你毫無反應，只是個底層的前端工程師。連Interface Designer都可以決定你的生死(畫一個很難實現的按鈕/對話框/視窗你就準備寫CSS寫到爽了)。到最後其實案子已經有點失控，所以我就跳出來說：「好吧，如果沒人想寫下並定好這些規格那我來寫。」&lt;/p&gt;

&lt;p&gt;這是去年十月的事情，而，這是地獄的開端。&lt;/p&gt;

&lt;p&gt;每天白天跟作風非常強勢的QA用電話討論UI spec細節，晚上利用空檔寫functional spec，一邊改網頁到符合spec。這段時間平均下班時間是11點~1點，直到某天公司總務發群體信說中X保全抱怨我們超過時間，我才知道原來要加班要先打電話給保全。寫了兩個月終於完成spec第一版，圖文並茂六萬字word。但是根本沒有時間去補足那千餘個功能，因為只有我一個人在做WEB。然後有趣的是上頭很急著進測，他們認為spec寫完就是完成了一切，當然不是。進測結果很糟糕，大部分是未完成功能與ui文字拼寫等UI bug。&lt;/p&gt;

&lt;p&gt;我在這段期間還一邊接觸了一些新的技術，因為我想利用MVC框架來解決那些我在這個web application上遇到的種種奇特困難。案子被QA退回後，上頭重新檢討認為是spec不夠詳細嚴謹，於是兩位主管級跳下來接手spec重寫。我自己利用這段時間拼命研究各種網路上的資源。&lt;/p&gt;

&lt;h3&gt;5&lt;/h3&gt;

&lt;p&gt;&lt;img src="http://i.imgur.com/6FkRe.jpg"&gt;&lt;/p&gt;

&lt;p&gt;我選擇的技術叫JavascriptMVC，是一個total solution client side MVC framework。與它相似的東西是Backbone.js，而最近這段期間我也體悟到其實backbone比較多人在用。也很多人問我為什麼當時不用backbone? 我的答案很簡單，當時花了兩天熬夜做不出一個簡單的起始範例，backbone的文件實在令我費解，就放棄了，&lt;/p&gt;

&lt;p&gt;我並沒有太多時間。&lt;/p&gt;

&lt;p&gt;當然不只backbone跟jmvc，為了解決問題我也看了YUI, extJS, 甚至zk。我還花時間研究extJS的對話框是怎樣用div拼出來的，那噁心的東西。還有我順便買了一台Synology的NAS回家研究他們怎麼做出那麼漂亮的東西。&lt;/p&gt;

&lt;h3&gt;6&lt;/h3&gt;

&lt;p&gt;選定JMVC之後一切就順利了嘛？當然不是。這東西在台灣甚至大陸根本沒人在用，網路上清一色都是用backbone。連英文資源也不多。我遇到問題只能到官方forum用破爛英文問作者這功能是什麼？還被嫌棄過我寫的字句他看不懂:D&lt;/p&gt;

&lt;p&gt;斷斷續續利用工作空檔時間看jmvc doc兩三個月之後我終於動手對那個改不動的噁心網頁做了refactor。整個砍掉重寫。這次花了三個月的時間寫了五萬行code。重點是，主管並不支持我做重構這件事。而我認為不重構的話某些該死的複雜功能根本無以實現。&lt;/p&gt;

&lt;p&gt;我們的想法有衝突，而&lt;b&gt;我只是個想把這件事情做好的死心眼的傢伙。&lt;/b&gt;我就在幾乎得不到任何support的情況下開始了進階版的地獄：平均下班時間延長到凌晨兩三點。有段時間每個禮拜會有一天通宵然後隔天不請假繼續上班。&lt;/p&gt;

&lt;p&gt;支持我的信念只是相信自己辦的到。但，我曾有很多次在凌晨四五點回到家，洗澡的時候跌坐在地上任熱水沖淋，問自己「這一切到底有何意義？」即使是現在，我也不認為自己是因為那段時間的拼命而獲得一份好的工作，你知道的，努力跟回報從來都不是成正比。但當你真心愛某件事，過程才是重點。&lt;/p&gt;

&lt;h3&gt;7&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;最痛苦的事情不是每天加班，而是你的主管在這段期間不但沒幫你，還處於某種狀況之下導致常常對自己發動言語精神攻擊。&lt;/li&gt;
&lt;li&gt;畢竟我只是個人微言輕的小工程師，沒有拿出成果之前，一切都是白搭，不管你多有熱情，對其他人來說「做不到」他們要的東西，你講話就不會有分量。&lt;/li&gt;
&lt;li&gt;&lt;p&gt;「孤立無援」是一句成語，可以用來造句。對我來說是殘酷的現實。因為最後實做的人是你，不管你有什麼困難，都是你家的事。不管你&lt;code&gt;rhino debugger多難用Makefile多難寫dir-based namespace pattern多難改resize event delegation在IE8出了什麼問題收不到對話框多難刻用js模擬dbus請求多難搞同時採用不同來源data model並行多難做多重ActiveX callback多難整按鈕不同尺寸css sprite多難寫&lt;/code&gt;，別人只看得到UI最後的模樣，你做不出來就是你無能，你說做得出來就是「不管我壓什麼時間都做得出來」。&lt;/p&gt;

&lt;p&gt;  「你到底有沒有珍惜這份工作？」某天晚上七點主管把我叫進會議室檢討。他不滿意我的進度，給了我很爛的評價。
  你知道眼前坐在椅子上不發一語的我，昨天趕你要的東西沒睡覺嗎？
  我就算不是你最強的員工，也是你最拼命的員工，你該珍惜的不是別人給你的案子的評價，而是身為你員工的我。&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;8&lt;/h3&gt;

&lt;p&gt;然後我趕上了不可能的deadline，終於覺得累了，  release的隔天我便打開104更新履歷然後放著。&lt;/p&gt;

&lt;h3&gt;9&lt;/h3&gt;

&lt;p&gt;原本只是想換一間重視技術也重視web的公司待，沒有預期自己一定會去哪。收到Mozilla的面試邀約，我很驚訝他們有要找Frontend，當然被他們錄取我更suprise。直到現在我依然不得不壓抑自己內心的激動，畢竟，那可是Mozilla。身為一個F2E Newbie，竟然可以在那邊跟全世界的高手們cowork，並且有機會見到一些此領域的大師級人物（jQuery的創始者John Resig曾經待過Mozilla）。&lt;/p&gt;

&lt;p&gt;而Mozilla本身想要做某些事情來改變網際網路的未來讓網路變得更好，而，改變網路就幾乎等於著手&lt;u&gt;改變這個世界的未來。&lt;/u&gt;&lt;/p&gt;

&lt;p&gt;有幸參與這個過程，怎能叫人不興奮？&lt;/p&gt;

&lt;p&gt;但，你知道的，激情並不是能永久持續的狀態。我現在必須努力把這份激動壓抑下來，然後希望自己永遠莫忘初衷。&lt;/p&gt;

&lt;br/&gt;


&lt;p&gt;以上是一個剛起步的小小前端工程師的一段經歷，希望對讀到這篇文章的人有幫助。&lt;/p&gt;

&lt;p&gt;Alive Kuo@20120530&lt;/p&gt;

&lt;h1&gt;Q&amp;amp;A&lt;/h1&gt;

&lt;ol&gt;
&lt;li&gt;有人問第4段的那張手寫日期表是什麼？最後一個下班者拿走公司鑰匙的簽名。被我懶得寫跳過的平常日期是：沒回家。假日來公司：不會記。&lt;/li&gt;
&lt;/ol&gt;

</description></item></channel></rss>