ThoughtWorkshopDigital Bigs in my thought2016-07-10T04:42:09.000Zhttp://timnew.me/TimNewtimnew.wti@gmail.comHexoCollection Filtering Algorithm with Bit Operation - Part.1http://timnew.me/blog/2016/04/23/collection-filtering-algorithm-with-bit-operation-part-1/2016-04-23T09:46:30.000Z2016-07-10T04:42:09.000Z<h2 id="Background"><a href="#Background" class="headerlink" title="Background"></a>Background</h2><p>Collection must be the most commonly used data model in programming. And there are a number of data structure that represents collection in memory, in which <code>Array</code> and <code>Liked List</code> must be the most well known ones.</p>
<p>When dealing with collection, <code>filtering</code> must be one of the most widely used operation being used. Such as find item(s) satisfies specific criteria from the collection. Although filtering is used a lot, but it isn’t actually a simple or easy operation to apply, especially dealing with tremendous data volume.</p>
<p>In fact, there are a number of derived topics about collection filtering, which is impossible to cover them all in the article. This article will focus on <code>bit operation</code>, probably a not widely known but really interesting topic to introduce.</p>
<h2 id="Problem-Find-the-missing-integer"><a href="#Problem-Find-the-missing-integer" class="headerlink" title="Problem: Find the missing integer"></a>Problem: Find the missing integer</h2><blockquote><p><strong>Problem</strong><br>Suppose there is a collection of integers <code>L</code>.<br>Name the collection that contains integers from 1 to <code>N</code> as <code>G</code><br>Then <code>L</code> contains all the elements of <code>G</code> except one number <code>x</code>.<br>Items in <code>L</code> are in random order.<br>Find <code>x</code>.</p>
</blockquote>
<p><strong>TIP: </strong> This problem be too easy to experienced developers and algorithm hackers. But it is a good opening words to the following 2 problems in this series. Also it reveals the core concept of some other advanced technologies, such as <code>CRC</code> or <code>bloom filter</code>.</p>
<p>When got this problem, the very intuitive(means do it manually by human being) idea is to compare the elements in <code>L</code> and <code>G</code>, find each element in <code>L</code> and remove it from <code>G</code>, then the only left item in <code>G</code> is <code>x</code>.</p>
<p>Here is the code:</p>
<figure class="highlight ruby"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div></pre></td><td class="code"><pre><div class="line"><span class="comment"># <span class="doctag">@param</span> Integer[] L</span></div><div class="line"><span class="comment"># <span class="doctag">@param</span> Integer N</span></div><div class="line"><span class="comment"># <span class="doctag">@return</span> Integer x</span></div><div class="line"><span class="function"><span class="keyword">def</span> <span class="title">find_missing_x</span><span class="params">(L, N)</span></span></div><div class="line"> G = [*(<span class="number">1</span>..N)] <span class="comment"># Create G with all integers from 1 to N</span></div><div class="line"></div><div class="line"> L.each { <span class="params">|i|</span> G.delete(i) } <span class="comment"># Traverse L, and remove each item in L from G</span></div><div class="line"></div><div class="line"> <span class="keyword">return</span> G.last <span class="comment"># Return the only rest item from G</span></div><div class="line"><span class="keyword">end</span></div></pre></td></tr></table></figure>
<p>Well this is a work but brute algorithm, which is not efficient in both time and space:</p>
<ul>
<li>Instantiate <code>G</code> means it has space complexity <code>N</code></li>
<li>Find and remove <code>i</code> from <code>G</code> means it has time complexity at <code>O(N*Log(N))</code></li>
</ul>
<p>Yes, the algorithm can be optimized, with bit operation. In fact the problem can be resolved with time complexity <code>O(N)</code> and space complexity <code>O(1)</code>.</p>
<h2 id="Exclusive-Or-Operation"><a href="#Exclusive-Or-Operation" class="headerlink" title="Exclusive-Or Operation"></a><code>Exclusive-Or</code> Operation</h2><p><code>Exclusive-Or</code>(Or <code>XOR</code> for short, written as <code>^</code> in this article) is a basic bit operation, here is an Venn Diagram explains it:</p>
<img src="/blog/2016/04/23/collection-filtering-algorithm-with-bit-operation-part-1/xor_venn.png" alt="XOR" title="XOR">
<p><code>XOR</code> is an important bit operation because it has following interesting features:</p>
<ol>
<li>A ^ B = B ^ A (aka <strong>Commutativity</strong>)</li>
<li>(A ^ B) ^ C = A ^ (B ^ C) (aka <strong>Associativity</strong>)</li>
<li>A ^ A = 0</li>
<li>A ^ 0 = A</li>
</ol>
<p>Commutativity and Associativity ensure that <code>XOR</code> can be used despite of order. The 3rd and 4th feature establishes a critical position for <code>XOR</code> in <code>cryptology</code> and <code>encoding</code>.</p>
<h2 id="Solution-with-XOR"><a href="#Solution-with-XOR" class="headerlink" title="Solution: with XOR"></a>Solution: with <code>XOR</code></h2><p>By making use of <code>XOR</code>, previous problem can ben resolved in a much more graceful way:</p>
<ul>
<li>Given <code>y</code> is the <code>xor</code> result of all items in <code>G</code></li>
<li>And <code>z</code> is the <code>xor</code> result of all items in <code>L</code></li>
<li>Then <code>x = y ^ z</code></li>
</ul>
<figure class="highlight ruby"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div></pre></td><td class="code"><pre><div class="line"><span class="comment"># <span class="doctag">@param</span> Integer[] L</span></div><div class="line"><span class="comment"># <span class="doctag">@param</span> Integer N</span></div><div class="line"><span class="comment"># <span class="doctag">@return</span> Integer x</span></div><div class="line"><span class="function"><span class="keyword">def</span> <span class="title">find_missing_x</span><span class="params">(L, N)</span></span></div><div class="line"> x = <span class="number">0</span> <span class="comment"># Set x to 0, since A ^ 0 = A</span></div><div class="line"></div><div class="line"> (<span class="number">1</span>..N).each { <span class="params">|i|</span> x ^= i } <span class="comment"># Calculate the xor result for G</span></div><div class="line"></div><div class="line"> L.each { <span class="params">|i|</span> x ^= i } <span class="comment"># Keep xor all elements in L</span></div><div class="line"></div><div class="line"> <span class="keyword">return</span> x <span class="comment"># Return the only rest item from G</span></div><div class="line"><span class="keyword">end</span></div></pre></td></tr></table></figure>
<p>Let’s prove it mathematically:<br><figure class="highlight nginx"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div></pre></td><td class="code"><pre><div class="line"><span class="attribute">Given</span> x<span class="string">'= y ^ z</span></div><div class="line">Then x' = (n1<span class="regexp"> ^</span> n2<span class="regexp"> ^</span> n3<span class="regexp"> ^</span> ...<span class="regexp"> ^</span> x<span class="regexp"> ^</span> ...<span class="regexp"> ^</span> nN)<span class="regexp"> ^</span> (n1<span class="regexp"> ^</span> n2<span class="regexp"> ^</span> n3<span class="regexp"> ^</span> ...<span class="regexp"> ^</span> nN)</div><div class="line">Since<span class="regexp"> ^</span> obeys commutativity and associativity</div><div class="line">Then = (n1<span class="regexp"> ^</span> n1)<span class="regexp"> ^</span> (n2<span class="regexp"> ^</span> n2)<span class="regexp"> ^</span> ...<span class="regexp"> ^</span> (nN<span class="regexp"> ^</span> nN)<span class="regexp"> ^</span> x</div><div class="line">As n<span class="regexp"> ^</span> n = <span class="number">0</span> and n<span class="regexp"> ^</span> <span class="number">0</span> = n</div><div class="line">Then x<span class="string">'= 0 ^ 0 ^ ... ^ 0 ^ x</span></div><div class="line"> = x</div></pre></td></tr></table></figure></p>
<p>Actually the code can be more concise by using <code>reduce</code>, with 2-lines of code</p>
<figure class="highlight ruby"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line"><span class="comment"># <span class="doctag">@param</span> Integer[] L</span></div><div class="line"><span class="comment"># <span class="doctag">@param</span> Integer N</span></div><div class="line"><span class="comment"># <span class="doctag">@return</span> Integer x</span></div><div class="line"><span class="function"><span class="keyword">def</span> <span class="title">find_missing_x</span><span class="params">(L, N)</span></span></div><div class="line"> x = (<span class="number">1</span>..N).reduce(&<span class="symbol">:^</span>) <span class="comment"># Calculate the xor result for G</span></div><div class="line"></div><div class="line"> L.reduce(x, &<span class="symbol">:^</span>) <span class="comment"># Keep xor all elements in L and return</span></div><div class="line"><span class="keyword">end</span></div></pre></td></tr></table></figure>
<p>Or <code>C</code> version:<br><figure class="highlight c"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">int</span> <span class="title">find_missing_x</span><span class="params">(<span class="keyword">long</span> N, <span class="keyword">long</span>* L)</span> </span>{</div><div class="line"> <span class="keyword">long</span> x = N;</div><div class="line"></div><div class="line"> <span class="keyword">for</span>(<span class="keyword">long</span> i = <span class="number">0</span>; i < N - <span class="number">1</span>; i++) { <span class="comment">// L has size of N-1</span></div><div class="line"> x ^= i ^ L[i];</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span> x;</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h2 id="Extending-problems"><a href="#Extending-problems" class="headerlink" title="Extending problems"></a>Extending problems</h2><p>So far the problem has been gracefully resolved. But it is yet the end, here is a couple of extending questions:</p>
<ol>
<li>If <code>G</code> is collection with random but unique numbers (Not continues integer from 1 to <code>N</code>). How to write the code?</li>
<li>Based on <code>1</code>, if there are 2 numbers are missing? How to find them both?</li>
<li>Based on <code>1</code>, but <code>L</code> contains the members from <code>G</code> except <code>x</code>for exactly 2 times. That means <code>L</code> might contain 0 or 1 <code>x</code>, but exactly 2 for any other members from <code>G</code>. How to find <code>x</code>?</li>
<li>Based on <code>1</code>, but <code>G</code> isn’t a collection of integer, but a collection of web urls. How to find the one missing url?</li>
<li>Based on <code>4</code>, <code>G</code> is a collection of url, <code>L</code> is subset of <code>G</code> (might contains fewer members other than exactly <code>N</code> - 1). How can we know a randomly picked member from <code>G</code> is absolutely not contained by <code>L</code>. Given the tolerance to mistake on saying a member from <code>G</code> is in <code>L</code> but it doesn’t.</li>
</ol>
<p>These problems will be explained in the following posts.</p>
<h2 id="Background"><a href="#Background" class="headerlink" title="Background"></a>Background</h2><p>Collection must be the most commonly u
A clean way to test rejected promisehttp://timnew.me/blog/2015/08/14/a-clean-way-to-test-rejected-promise/2015-08-14T08:08:53.000Z2016-04-12T14:58:03.000Z<p>To test the the exception in a rejected promise could be a little bit painful.</p>
<p>And <a href="https://mochajs.org/" target="_blank" rel="external">Mocha</a> is Promise-friendly, which means it fails the test if exception is not caught.</p>
<p>So as a result, here is a simple code example to explain how it is being done:</p>
<figure class="highlight coffeescript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line">it <span class="string">'should throw session-expired exception'</span></div><div class="line"> <span class="keyword">new</span> Session().generateId().bindUserFromRedis()</div><div class="line"> .<span class="keyword">then</span> -></div><div class="line"> <span class="literal">null</span></div><div class="line"> .<span class="keyword">catch</span> (ex) -></div><div class="line"> ex</div><div class="line"> .<span class="keyword">then</span> (ex) -></div><div class="line"> expect(ex).to.be.<span class="keyword">instanceof</span>(ResponseError)</div><div class="line"> .<span class="keyword">and</span>.that.have.property(<span class="string">'errorName'</span>, <span class="string">'session-expired'</span>)</div></pre></td></tr></table></figure>
<hr>
<p><strong>Update:</strong> A Chai Plugin can mitigate the pain</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line">it(<span class="string">'should throw session-expired exception'</span>, () => {</div><div class="line"> <span class="keyword">return</span> expect(<span class="keyword">new</span> Session().generateId().bindUserFromRedis())</div><div class="line"> .to.evetually.rejected</div><div class="line"> .and.that.have.property(<span class="string">'errorName'</span>, <span class="string">'session-expired'</span>)</div><div class="line">})</div></pre></td></tr></table></figure>
<p><strong>Update 2:</strong> With async, it can be converted into normal test<br><figure class="highlight js"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line">it(<span class="string">'should throw session-expired exception'</span>, () => {</div><div class="line"> <span class="keyword">return</span> expect(<span class="keyword">async</span> () => <span class="keyword">await</span> <span class="keyword">new</span> Session().generateId().bindUserFromRedis())</div><div class="line"> .to.throw</div><div class="line"> .and.that.have.property(<span class="string">'errorName'</span>, <span class="string">'session-expired'</span>)</div><div class="line">})</div></pre></td></tr></table></figure></p>
<p>To test the the exception in a rejected promise could be a little bit painful.</p>
<p>And <a href="https://mochajs.org/" target="_blank"
Typical EventBus Design Patternshttp://timnew.me/blog/2014/12/06/typical-eventbus-design-patterns/2014-12-06T08:37:41.000Z2016-01-31T16:21:00.000Z<p><code>EventBus</code> is an special <a href="`Pub & Sub`">Publish & Subscribe Pattern</a> implementation. <code>EventBus</code> enable message to be delivered between components without requiring the components to register itself to others.</p>
<p>Comparing <code>EventBus</code> to other <code>Pub & Sub</code> implementations, <code>EventBus</code> is:</p>
<ol>
<li>Designed to replace the original event distribution system, which requires the components register itself to each other.</li>
<li>Not designed for general use, <code>EventBus</code> adds additional complexity and runtime overhead to the system. So it is not designed to replace normal method calls.</li>
<li>Not designed for inter-process communication as some other Pub&Sub.</li>
</ol>
<h2 id="EventBus-saves-Android-developers’-life"><a href="#EventBus-saves-Android-developers’-life" class="headerlink" title="EventBus saves Android developers’ life"></a><code>EventBus</code> saves Android developers’ life</h2><p>When developing Android application, I strongly recommend developer to introduce an <code>EventBus</code> library. <a href="https://github.com/greenrobot/EventBus" target="_blank" rel="external">EventBus</a> from <code>GreenRobot</code>, <a href="http://square.github.io/otto/" target="_blank" rel="external">Otto</a> from <code>Squqre</code> are good solutions. Or even to choose the original <code>EventBus</code> in <a href="https://code.google.com/p/guava-libraries/" target="_blank" rel="external">Guava</a> library from Google.</p>
<p>With <code>EventBus</code>, components can communicate with each other without need to hold direct reference of each other. This is very important to avoid app crashes when calling a method on a detached or destroyed component. Usually this kind of issue isn’t that easy to handle due to Android’s over-complicated life cycle management. So even in the worst case that one component is sending message to another component which has been destroyed (which should unregister itself from EventBus on that time), it only triggered a <code>norecipient waring</code> instead of crashing the app.</p>
<p>Also with <code>EventBus</code> as intermedia, you can avoid to exposing objects to root activity or application just for registering callbacks on each other. Components are higher cohesion & lower coupling.</p>
<p>As the result, <code>EventBus</code> saves tons of time to debugging crash, and make your code more readable, maintainble, extensible, and flexible.</p>
<h2 id="Abusing-EventBus-kills-your-app-easily"><a href="#Abusing-EventBus-kills-your-app-easily" class="headerlink" title="Abusing EventBus kills your app easily"></a>Abusing <code>EventBus</code> kills your app easily</h2><p>“<code>EventBus</code> is awesome! It is so convenient, so let’s replace everything with event”… This kind of saying is commonly heard from the developers who just realized the benefits from <code>EventBus</code>. Since <code>EventBus</code> is too convenient to use, they tends to replace everything with EventBus.</p>
<p>But we mentioned in the introduction of <code>EventBus</code> that <code>EventBus</code> is design to replace traditional event system in Java, and is not designed for general use. Abusing makes your code hard to understand, hard to debug. Long event chain is a common reason that cause of unexpected behavior.</p>
<h2 id="Broadcast-Event-Command-and-Request"><a href="#Broadcast-Event-Command-and-Request" class="headerlink" title="Broadcast Event, Command and Request"></a>Broadcast Event, Command and Request</h2><p><code>EventBus</code> is powerful, but can be easily abused. To make a better use of EventBus, I learn a number of EventBus usages, and evaluated the scenario, and summarized out 3 typeical EventBus usage patterns: <strong>Broadcast Event</strong>, <strong>Command</strong> and <strong>Request</strong>.</p>
<h3 id="Broadcast-Event"><a href="#Broadcast-Event" class="headerlink" title="Broadcast Event"></a>Broadcast Event</h3><p><code>Broadcast Event</code> is a special kind of event that used by a specific component to broadcast its status updated to other components.</p>
<h4 id="Declaration"><a href="#Declaration" class="headerlink" title="Declaration"></a>Declaration</h4><p><code>Broadcast Event</code> should be used when several components cares about the specific component’s status update. So usually <code>Broadcast Event</code> should have more than one recipients or, at least, potential recipients.</p>
<p><code>Broadcast Event</code> should be an immutable data object, so:</p>
<ol>
<li>It is immutable, so once it is created, its status should not changed, which guarantees the equality between recipients.</li>
<li>It is data object, so it should not has methods that might change other classes status.</li>
<li>It might have methods that helps its consumer to consume the data it contains.</li>
<li>It should be declared as a nested static class of publisher.</li>
</ol>
<p><strong>NOTICE</strong><br>If you thought a Event is “Broadcast Event”, but later you found it has only one recipient, then you might need to consider refact it into a <code>Command</code> or a <code>Request</code>.</p>
<h3 id="Command"><a href="#Command" class="headerlink" title="Command"></a>Command</h3><p><code>Command</code> is a special kind of event that has the ability to update specific object or specific type of objects. In most cases, <code>Command</code> should have only one recipient. In some special cases, it might has a group of recipients with exactly same type.</p>
<p>Precisely, the latter case is a variant of <code>Command</code> pattern, <code>Batch Command</code>, which works as same as <code>Command</code> but have multiple recipients so it can update multiple instances in a batch.</p>
<p><code>Command</code> should be a immutable object that able to update specific object, so:</p>
<ol>
<li>It should have 1 <code>execute</code> method with 1 parameter, which represents the target that the command updates.</li>
<li>When invoking execute method shouldn’t change its own status, so it does exactly same thing when applying it to multiple targets.</li>
<li>It behavior should be stable across time, so its behavior won’t change when it is apply asynchronously.</li>
<li>The object that <code>execute</code> method accepts is not necessarily to be the recipient. It could be the object that recipient holds or it has access to.</li>
<li>It should be declared as nested static class of the recipient.</li>
<li>If recipient accepts multiple events, these events are recommended to derived from the same base class. So The recipient could subscribe to the base class, rather than every command.</li>
</ol>
<p><strong>NOTICE</strong><br><code>Command</code> can be seen as recipient’s special method that can be invoked without known recipient instance. So its behavior should fully contained in the class. The subscribing method on recipient should contain one line of code to invoke <code>execute</code> method on command.</p>
<h3 id="Request"><a href="#Request" class="headerlink" title="Request"></a>Request</h3><p><code>Request</code> is a special kind of event that has the ability to accept data from another object. If the request has multiple recipients, to avoid ambiguous behavior, there should be only one of <code>Request</code>‘s respond the request.</p>
<p>But there is one exception, that is for the request collects data from multiple objects, multiple objects might respond to the request. This special kind of <code>Request</code> is called <code>Collector</code>.</p>
<p><code>Request</code> should be a object that accept data from recipient, so:</p>
<ol>
<li>It should have <code>respond</code> method with 1 parameter, which represents the data the request asks for.</li>
<li>Request should contains enough information for the recipients to determine whether to respond the request.</li>
<li>The recipients should check request’s status to determine whether it should respond request.</li>
<li>The request can update the publisher directly in the <code>respond</code> method</li>
<li>It should be declared as nested class of publisher. If possible, also declare it as static, which will be helpful to simplify the tests.</li>
<li>Request might has methods to help recipient to determine whether to respond the request.</li>
</ol>
<p><strong>NOTICE</strong><br><code>Request</code> can be seen as a special method that publisher exposes to a specific recipient, so the specific recipient can invoke the method to provide data. For <code>Request</code>, you might need to aware that that sometimes request might not found proper recipient to respond. If the responder is not guaranteed to exist, then the publish to watch out no-recipent warning from EventBus.</p>
<p><code>EventBus</code> is an special <a href="`Pub & Sub`">Publish & Subscribe Pattern</a> implementation. <code>EventBus</code> e
Understand Styles in Android - Part 1. What it is for and how to used ithttp://timnew.me/blog/2014/11/09/understand-styles-in-android-part-1-what-it-is-for-and-how-to-used-it/2014-11-09T05:44:29.000Z2014-11-14T10:26:19.000Z<ul>
<li><a href="/blog/2014/11/09/understand-styles-in-android-part-1-what-it-is-for-and-how-to-used-it/">Part 1: What it is for and how to used it</a></li>
</ul>
<hr>
<p>In android, view hierarchy usually are created via <code>layout</code> xml file. In the file, to instantiate a <code>TextView</code> we write:</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line"><span class="tag"><<span class="name">TextView</span></span></div><div class="line"> <span class="attr">android:layout_width</span>=<span class="string">"wrap_content"</span></div><div class="line"> <span class="attr">android:layout_height</span>=<span class="string">"wrap_content"</span></div><div class="line"> <span class="attr">android:text</span>=<span class="string">"Sample 1"</span> /></div></pre></td></tr></table></figure>
<p>Usually, we need to specify the visual of the <code>TextView</code>, so we keep adding attributes to the <code>TextView</code> element:</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div></pre></td><td class="code"><pre><div class="line"><span class="tag"><<span class="name">TextView</span></span></div><div class="line"> <span class="attr">android:layout_width</span>=<span class="string">"wrap_content"</span></div><div class="line"> <span class="attr">android:layout_height</span>=<span class="string">"wrap_content"</span></div><div class="line"> <span class="attr">android:text</span>=<span class="string">"Sample 1"</span></div><div class="line"> <span class="attr">android:background</span>=<span class="string">"@drawable/category_indicator_background"</span></div><div class="line"> <span class="attr">android:gravity</span>=<span class="string">"center"</span></div><div class="line"> <span class="attr">android:maxLines</span>=<span class="string">"1"</span></div><div class="line"> <span class="attr">android:paddingBottom</span>=<span class="string">"12dp"</span></div><div class="line"> <span class="attr">android:paddingLeft</span>=<span class="string">"22dp"</span></div><div class="line"> <span class="attr">android:paddingRight</span>=<span class="string">"22dp"</span></div><div class="line"> <span class="attr">android:paddingTop</span>=<span class="string">"12dp"</span></div><div class="line"> <span class="attr">android:textSize</span>=<span class="string">"12sp"</span> /></div></pre></td></tr></table></figure>
<p>Usually to fully customize visual representation of a view needs a lot of attributes and resources. Such as in this example. we added <code>background</code>, <code>gravity</code>, <code>maxLines</code>, <code>padding</code> and <code>textSize</code>, which is a lot of code.</p>
<p>And if we want to create another <code>TextView</code> with exactly same visual representation, we need to copy all the values again:</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div></pre></td><td class="code"><pre><div class="line"><span class="tag"><<span class="name">TextView</span></span></div><div class="line"> <span class="attr">android:layout_width</span>=<span class="string">"wrap_content"</span></div><div class="line"> <span class="attr">android:layout_height</span>=<span class="string">"wrap_content"</span></div><div class="line"> <span class="attr">android:text</span>=<span class="string">"Sample 1"</span></div><div class="line"> <span class="attr">android:background</span>=<span class="string">"@drawable/category_indicator_background"</span></div><div class="line"> <span class="attr">android:gravity</span>=<span class="string">"center"</span></div><div class="line"> <span class="attr">android:maxLines</span>=<span class="string">"1"</span></div><div class="line"> <span class="attr">android:paddingBottom</span>=<span class="string">"12dp"</span></div><div class="line"> <span class="attr">android:paddingLeft</span>=<span class="string">"22dp"</span></div><div class="line"> <span class="attr">android:paddingRight</span>=<span class="string">"22dp"</span></div><div class="line"> <span class="attr">android:paddingTop</span>=<span class="string">"12dp"</span></div><div class="line"> <span class="attr">android:textSize</span>=<span class="string">"12sp"</span> /></div><div class="line"></div><div class="line"><span class="tag"><<span class="name">TextView</span></span></div><div class="line"> <span class="attr">android:layout_width</span>=<span class="string">"wrap_content"</span></div><div class="line"> <span class="attr">android:layout_height</span>=<span class="string">"wrap_content"</span></div><div class="line"> <span class="attr">android:text</span>=<span class="string">"Sample 2"</span></div><div class="line"> <span class="attr">android:background</span>=<span class="string">"@drawable/category_indicator_background"</span></div><div class="line"> <span class="attr">android:gravity</span>=<span class="string">"center"</span></div><div class="line"> <span class="attr">android:maxLines</span>=<span class="string">"1"</span></div><div class="line"> <span class="attr">android:paddingBottom</span>=<span class="string">"12dp"</span></div><div class="line"> <span class="attr">android:paddingLeft</span>=<span class="string">"22dp"</span></div><div class="line"> <span class="attr">android:paddingRight</span>=<span class="string">"22dp"</span></div><div class="line"> <span class="attr">android:paddingTop</span>=<span class="string">"12dp"</span></div><div class="line"> <span class="attr">android:textSize</span>=<span class="string">"12sp"</span> /></div></pre></td></tr></table></figure>
<p>Obviously, in this piece of code, there are a lot of duplications. We need to compare all the values to figure out the 2 <code>TextViews</code> have the same visual. If we want to change the style, we need to update 2 TextViews. And the last, if we want to create the 3rd <code>TextView</code> or even more ones, we need copy the code again and again, which makes the issue become more troublsome.</p>
<p>In a short word, the code has bad readability, bad maintainability, bad reusability. In the book <code>Refactor</code>, we know that code redundancy is bad smell. To mitigate the issue, we need to extract the shared code into another “unit”, and replace all the occurrences with the reference.</p>
<p>In Android layout xml, the extract “unit”, which represents the shared attributes, are called <code>Style</code>. After introduced <code>Style</code>, we have:</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div></pre></td><td class="code"><pre><div class="line"><span class="tag"><<span class="name">TextView</span></span></div><div class="line"> <span class="attr">android:layout_width</span>=<span class="string">"wrap_content"</span></div><div class="line"> <span class="attr">android:layout_height</span>=<span class="string">"wrap_content"</span></div><div class="line"> <span class="attr">android:text</span>=<span class="string">"Sample 1"</span></div><div class="line"> <span class="attr">style</span>=<span class="string">"@style/TextView.Customized"</span>/></div><div class="line"></div><div class="line"><span class="tag"><<span class="name">TextView</span></span></div><div class="line"> <span class="attr">android:layout_width</span>=<span class="string">"wrap_content"</span></div><div class="line"> <span class="attr">android:layout_height</span>=<span class="string">"wrap_content"</span></div><div class="line"> <span class="attr">android:text</span>=<span class="string">"Sample 2"</span></div><div class="line"> <span class="attr">style</span>=<span class="string">"@style/TextView.Customized"</span>/></div></pre></td></tr></table></figure>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div></pre></td><td class="code"><pre><div class="line"><span class="tag"><<span class="name">resources</span>></span></div><div class="line"> <span class="tag"><<span class="name">style</span> <span class="attr">name</span>=<span class="string">"TextView.Customized"</span>></span><span class="xml"></span></div><div class="line"> <span class="tag"><<span class="name">item</span> <span class="attr">name</span>=<span class="string">"android:gravity"</span>></span>center<span class="tag"></<span class="name">item</span>></span></div><div class="line"> <span class="tag"><<span class="name">item</span> <span class="attr">name</span>=<span class="string">"android:background"</span>></span>@drawable/category_indicator_background<span class="tag"></<span class="name">item</span>></span></div><div class="line"> <span class="tag"><<span class="name">item</span> <span class="attr">name</span>=<span class="string">"android:paddingLeft"</span>></span>22dp<span class="tag"></<span class="name">item</span>></span></div><div class="line"> <span class="tag"><<span class="name">item</span> <span class="attr">name</span>=<span class="string">"android:paddingRight"</span>></span>22dp<span class="tag"></<span class="name">item</span>></span></div><div class="line"> <span class="tag"><<span class="name">item</span> <span class="attr">name</span>=<span class="string">"android:paddingTop"</span>></span>12dp<span class="tag"></<span class="name">item</span>></span></div><div class="line"> <span class="tag"><<span class="name">item</span> <span class="attr">name</span>=<span class="string">"android:paddingBottom"</span>></span>12dp<span class="tag"></<span class="name">item</span>></span></div><div class="line"> <span class="tag"><<span class="name">item</span> <span class="attr">name</span>=<span class="string">"android:textAppearance"</span>></span>@style/CategoryIndicator.Text<span class="tag"></<span class="name">item</span>></span></div><div class="line"> <span class="tag"><<span class="name">item</span> <span class="attr">name</span>=<span class="string">"android:textSize"</span>></span>12sp<span class="tag"></<span class="name">item</span>></span></div><div class="line"> <span class="tag"><<span class="name">item</span> <span class="attr">name</span>=<span class="string">"android:maxLines"</span>></span>1<span class="tag"></<span class="name">item</span>></span></div><div class="line"> <span class="tag"></<span class="name">style</span>></span></div><div class="line"><span class="tag"></<span class="name">resources</span>></span></div></pre></td></tr></table></figure>
<p>Well, this is the basics about the <code>Style</code>: why we need it and how it is used.</p>
<ul>
<li><a href="/blog/2014/11/09/understand-styles-in-android-part-1-what-it-is-for-and-how-to-used-it/">Part 1: What it is for and how to
Walkthrough: Untrusted - the Continuing Adventures of Dr. Evalhttp://timnew.me/blog/2014/11/07/walkthrough-untrusted-the-continuing-adventures-of-dr-eval/2014-11-07T15:38:08.000Z2016-03-25T13:01:53.000Z<p>This post is Walkthrough to the game <a href="http://alexnisnevich.github.io/untrusted/" target="_blank" rel="external">Untrusted</a><br>The game introduction is available here: <a href="/blog/2014/11/05/awesome-geek-game-untrusted-the-continuing-adventures-of-dr-eval/">Awesome geek game Untrusted</a></p>
<h3 id="Level-1-cellBlockA"><a href="#Level-1-cellBlockA" class="headerlink" title="Level 1: cellBlockA"></a>Level 1: cellBlockA</h3><p>Well, you are trapped in a box. And you need to move yourself to the exit (blue squre).</p>
<ol>
<li>Before you can do anything, you need to pick the computer first, then you will be access to the source code interface.</li>
<li>Once you got the computer, you can figure out the code that generates the walls.</li>
<li>Remove the code that generate the wall! And press <code>Ctrl+5</code> to apply it.</li>
<li><script src="//gist.github.com/e2c2ea766f6163ccfcb6.js"></script>
</li>
</ol>
<h3 id="Level-2-theLongWayOut"><a href="#Level-2-theLongWayOut" class="headerlink" title="Level 2: theLongWayOut"></a>Level 2: theLongWayOut</h3><p>Well, you have learn the trick from Level 1, but it doesn’t work anylonger this time. You need to figure out a new apporach.</p>
<ol>
<li>Don’t try to find a path in the maze, there is no such solution.</li>
<li>You cannot change the maze created, but you can do something to it before it is deployed.</li>
<li>You have learn how to create it for specific size. Why not create another smaller one that doesn’t trouble you?!</li>
<li>A maze with size (0,0) is not possible, try a more realistic one, such as (3, 3) or (4, 4).</li>
<li>Exit is blocked completely. Do think about to break the wall, that is impossible.</li>
<li>Who said there can be only 1 exit per level?!</li>
<li>Create a new exit at a different location! You can learn the code form existing one.</li>
<li><script src="//gist.github.com/59ff5de31063dd27ce9d.js"></script>
</li>
</ol>
<h3 id="Level-3-validationEngaged"><a href="#Level-3-validationEngaged" class="headerlink" title="Level 3: validationEngaged"></a>Level 3: validationEngaged</h3><p>Well, again, <code>validateLevel</code> is introduced, which prevents you to replay the old tricks. So you cannot create or remove objects on the fly this time.</p>
<ol>
<li>Since you cannot create or remove objects this time, but you still can move objects.</li>
<li>Move one of the wall away to make a gap between the wall.</li>
<li><script src="//gist.github.com/a51ca90e78c392b453ae.js"></script>
</li>
</ol>
<h3 id="Level-4-multiplicity"><a href="#Level-4-multiplicity" class="headerlink" title="Level 4: multiplicity"></a>Level 4: multiplicity</h3><p>You cannot move wall this time, what will you do?</p>
<ol>
<li>Well, this is just a mindset trap. Forget about moving stuff aroud.</li>
<li>There is no <code>validateLevel</code> in this level.</li>
<li>What you did in level 2.</li>
<li>Just create a exit in the box.</li>
<li><script src="//gist.github.com/59c9d0f95aa2dabd303f.js"></script>
</li>
</ol>
<h3 id="Level-5-minesweeper"><a href="#Level-5-minesweeper" class="headerlink" title="Level 5: minesweeper"></a>Level 5: minesweeper</h3><p>Remember the favous game in Windows? Try it here.</p>
<ol>
<li>The issue here is that the mine cannot be distinguished.</li>
<li>Mark the mine with a color other than red.</li>
<li>You can change block block color by call <code>setSquareColor</code>.</li>
<li><script src="//gist.github.com/14cd0090ffe945cf7b54.js"></script>
</li>
</ol>
<h3 id="Level-6-drones101"><a href="#Level-6-drones101" class="headerlink" title="Level 6: drones101"></a>Level 6: drones101</h3><p>A killing drone? Keep away from it.</p>
<ol>
<li>Well, check <code>moveToward</code>, the logic is actually very dumb.</li>
<li>It always, move <code>up</code> and <code>down</code> if the x offset is larger than y offset.</li>
<li>It will not move, it the intented direction is blocked.</li>
<li><script src="//gist.github.com/d3c146559b8c3d7d0f41.js"></script></li>
<li>Move right first, then move down when you at the same col as the drone and block. Then move right, the drone will not follow you.</li>
</ol>
<h3 id="Level-7-colors"><a href="#Level-7-colors" class="headerlink" title="Level 7: colors"></a>Level 7: colors</h3><p>A phone to make call? Great idea!</p>
<ol>
<li>Pick up the phone, then press <code>q</code></li>
<li>The callback will be executed everytime you pressed <code>q</code></li>
<li>Rotate your color in the callback</li>
<li><script src="//gist.github.com/47bd1335906094d412aa.js"></script>
</li>
</ol>
<h3 id="Level-8-intoTheWoods"><a href="#Level-8-intoTheWoods" class="headerlink" title="Level 8: intoTheWoods"></a>Level 8: intoTheWoods</h3><p>Go across the forest from the left to the right!<br>In this level, there is very little code that you can change!</p>
<ol>
<li>Press <code>q</code></li>
<li>The only code you can change is the callback function name</li>
<li>All the functions that you can call are in the <code>functionList</code></li>
<li>Generate a new forest, when you press <code>q</code></li>
<li><script src="//gist.github.com/663f51f6cf02891a0b4a.js"></script></li>
<li>Move right as far as you can; Once you are blocked, press <code>q</code> to generate a new forest, the move.</li>
<li>Repeat move and generate forest untill you reach the exit.</li>
</ol>
<h3 id="Level-9-fordingTheRiver"><a href="#Level-9-fordingTheRiver" class="headerlink" title="Level 9: fordingTheRiver"></a>Level 9: fordingTheRiver</h3><p>Well, a self driven raft, the raft comes to pick you up.<br>BTW, I really love the BG music of this level.</p>
<ol>
<li>The raft direction is stored in variable <code>raftDirection</code>.</li>
<li>Change the <code>raftDirection</code> to <code>up</code>, will make the raft move up each turn.</li>
<li>Find a chance to override the value of <code>raftDirection</code>.</li>
<li>Write a function that registerd as phone call back with API <code>setPhoneCallback</code></li>
<li><script src="//gist.github.com/584529348a4010ef6512.js"></script></li>
<li>Go to the raft, after boarding the raft press <code>q</code> to execute callback, then move up.</li>
</ol>
<h3 id="Level-10-ambush"><a href="#Level-10-ambush" class="headerlink" title="Level 10: ambush"></a>Level 10: ambush</h3><p>Well, this time, there are a dozen of drones are on your way. You need to figure out a possible to get rid of them as fast as you can.</p>
<ol>
<li>Don’t try to run away as what you did in Level 6. It is a different scenario.</li>
<li>Try to change the drone behavior.</li>
<li>To apply the same logic to 3 kinds of drones might not be a good idea.</li>
<li>Move attak drones away from the row you’re in.</li>
<li>Move the Defence Drones away from the row you’re in.</li>
<li>Ask Reinforcement Drones to stay at the place.</li>
<li><script src="//gist.github.com/8f7358d7f81792eecb2d.js"></script>
</li>
</ol>
<h3 id="Level-11-robot"><a href="#Level-11-robot" class="headerlink" title="Level 11: robot"></a>Level 11: robot</h3><p>This time, there is very little thing about you. It is about the robot.</p>
<ol>
<li>“Hit and turn” should be smart enough for the puzzle.</li>
<li>Move forward, when hit something, turn 90 deg.</li>
<li>Use <code>me.canMove</code> to test the hit.</li>
<li>Since there just 2 states, a boolean should be enough to represent the state.</li>
<li><script src="//gist.github.com/4820d49d07688a4d5e08.js"></script>
</li>
</ol>
<h3 id="Level-12-robotNav"><a href="#Level-12-robotNav" class="headerlink" title="Level 12: robotNav"></a>Level 12: robotNav</h3><p>Well this time, it goes a little complicate.</p>
<ol>
<li>“Hit and turn” won’t work here.</li>
<li>Path seeking algorithm is way too complicate for this puzzle.</li>
<li>Robot should be able to be “programmed”.</li>
<li>An instruction system should be enough for the puzzle.</li>
<li>Preset the instruction to the robot, and ask robot to execute it step by step.</li>
<li><script src="//gist.github.com/ed9e09f7f630b745dc02.js"></script>
</li>
</ol>
<h3 id="Level-13-robotMaze"><a href="#Level-13-robotMaze" class="headerlink" title="Level 13: robotMaze"></a>Level 13: robotMaze</h3><p>Well, Well, Well, it upgraded again. More intelligence is needed.</p>
<ol>
<li>Maze is randomly generated, so fixed instruction sequence won’t work any longer.</li>
<li>Again, Path seeking algorithm is way too complicate for this puzzle.</li>
<li>Don’t waste your intelligence.</li>
<li>A lot of robot can be “controlled” remotely.</li>
<li>Try to teach the robot how to move by your character’s movement.</li>
<li><script src="//gist.github.com/76a8c8dd62310ccb1cd3.js"></script></li>
<li>The robot move down when you’re in last row; the robot move up when you’re in the last 3rd row; the robot try to move to your col when you’re in the last 2nd row.</li>
<li>Move into last 2nd row, and the move to most left. Move left and right to control robot move horizontally. Move to last 3rd row or last row when you need to tell robot move up and down.</li>
<li>Stay in last row and last 3rd row, and press ‘r’ will move robot up and down continuously.</li>
</ol>
<h3 id="Level-14-crispsContest"><a href="#Level-14-crispsContest" class="headerlink" title="Level 14: crispsContest"></a>Level 14: crispsContest</h3><p>Again another maze!</p>
<ol>
<li>The maze is unsolvable, don’t try to solve it.</li>
<li>Divide the maze into 5 regions, top left 2 rooms, top right 2 rooms, left 1 room, right 1 room, and bottom 2 rooms.</li>
<li>You can hold only one key for each color, or the key will be wasted</li>
<li>Because of restriction(hint.3), left and right regions are meaningless.</li>
<li>Region top left, top right, and bottom, enter and exists direction doesn’t matter.</li>
<li>Check carefully, a string in the code isn’t locked.</li>
<li>The item will be taken away is editable when you pass <code>greenLock</code>.</li>
<li>Computer and phone are important items for your further plan.</li>
<li><code>null</code> or undeclared value causes exception.</li>
<li>Exception will break the code execution, which blocks you from passing the door.</li>
<li>Try to find something exists, but you don’t have yet.</li>
<li><code>The Algorithm</code> ?</li>
<li><script src="//gist.github.com/0581159360391ecd6386.js"></script>
</li>
</ol>
<h3 id="Level-15-exceptionalCrossing"><a href="#Level-15-exceptionalCrossing" class="headerlink" title="Level 15: exceptionalCrossing"></a>Level 15: exceptionalCrossing</h3><p>Really a cruel design… Pick how to die? Tricky but interesting!</p>
<ol>
<li>The only thing you can change it the value passed to <code>player.killBy()</code>.</li>
<li>Try to remember what you encounter in last level.</li>
<li>Get some hint from the name of this level.</li>
<li>Exception breaks code execution.</li>
<li><code>null</code> is a valid value.</li>
<li>Undeclared value causes exception.</li>
<li><script src="//gist.github.com/274c06bf1ce471e98972.js"></script>
</li>
</ol>
<h3 id="Level-16-lasers"><a href="#Level-16-lasers" class="headerlink" title="Level 16: lasers"></a>Level 16: lasers</h3><p>Lazer kills different races.</p>
<p><strong>NOTICE</strong> You might got killed by lazer when you haven’t actually touched it. The reason is that the line isn’t 100% align with the coord is given. And I think it is a <strong>BUG</strong> than designed by purpose.</p>
<ol>
<li>Lazer representation and collision detection are separated.</li>
<li>Remove the drawing logic won’t solve the issue.</li>
<li>Lazer only kills the object with different color than itself.</li>
<li>Color the lines with the lazer color.</li>
<li>Use the phone to update your color.</li>
<li><script src="//gist.github.com/8742a1d05da744f52fa1.js"></script>
</li>
</ol>
<h3 id="Level-17-pointers"><a href="#Level-17-pointers" class="headerlink" title="Level 17: pointers"></a>Level 17: pointers</h3><p>This must be the most problematic level in the game!!!!<br>Since fortune is more important than wisdom in this level!<br>If you’re lucky enough, you might able to clear the level by entering a randomly picked portal.<br>Actually when I play this level for 1st time, I passed without dohing any code work.</p>
<ol>
<li>Well, you can do nothing to the layout, and teleporter links.</li>
<li>A path seeking algorithm won’t be helpful for this puzzle.</li>
<li>Not all the layout is solvable. That’s why you need some fortune!</li>
<li>You’ll be killed immediately if the teleporter is linked to a trap.</li>
<li>Try to figure out all the safe links, whose 2 end-points are teleporters.</li>
<li>Try to visualize the the safe links.</li>
<li>Check API document for new available APIs.</li>
<li>Use <code>map.getCanvasCoords</code> to figure out the plot coords for teleporters.</li>
<li>Draw lines between safe teleporters.</li>
<li>Line drawing code can be found in previous level.</li>
<li><script src="//gist.github.com/d5a34b58f979991195c0.js"></script></li>
<li>Restart the level, if the level is obviously not solvable.</li>
<li>The puzzle is unsolvable, if there is no link to the room where exit locates</li>
<li>The puzzle is unsolvable, if there is no link to the room player is placed.</li>
<li>Luck is the key!</li>
</ol>
<h3 id="Level-18-superDrEvalBros"><a href="#Level-18-superDrEvalBros" class="headerlink" title="Level 18: superDrEvalBros"></a>Level 18: superDrEvalBros</h3><p>Great honor to <code>Super Bro.Mario</code> 🏆</p>
<ol>
<li><code>Jump</code> is kind of misleading word.</li>
<li>“Bridge” should be a better solution.</li>
<li>To material builds the bridge is not necessarily to be “block”.</li>
<li>Create your material.</li>
<li><script src="//gist.github.com/510eb8288e8df8cd6d53.js"></script>
</li>
</ol>
<p><strong>HINT</strong> If you really like to jump:</p>
<ol>
<li><code>Jump</code> is possible, but not a really good solution, since it introduces <code>races</code> between 2 timers.</li>
<li><script src="//gist.github.com/c2eb267825c105774482.js"></script>
</li>
</ol>
<h3 id="Level-19-documentObjectMadness"><a href="#Level-19-documentObjectMadness" class="headerlink" title="Level 19: documentObjectMadness"></a>Level 19: documentObjectMadness</h3><p>jQuery!!!!</p>
<ol>
<li>Code isn’t editable at all in this level.</li>
<li>Use the <code>arrow keys</code> to navigate the green block.</li>
<li>You need to use green block to cover the red block.</li>
<li>If you familiar with <code>EverNote Web Clipper</code>, then it should be very easy for you.</li>
<li>Press <code>up</code> for 4 times, then <code>right</code> 2 times, and adjust your green block to cover <code>red</code></li>
</ol>
<h3 id="Level-20-bossFight"><a href="#Level-20-bossFight" class="headerlink" title="Level 20: bossFight"></a>Level 20: bossFight</h3><p>Finally, fight against the BOSS!</p>
<ol>
<li>To clear the level, you need to kill all the bosses to get the Algorithm first.</li>
<li>Timer is not available.</li>
<li>So before you can do anything, you need the phone to trigger something.</li>
<li>Only 1 block is available</li>
<li>You can place the only block in the middle of the gap to shelter the bullet for you. With its help, it isn’t that hard to get the phone without being shot.</li>
<li>Or You might create a new tile to shelter the bullets for you, the number of new material blocks are not limited.</li>
<li>To kill the <code>Boss</code>, you need create your own bullet!</li>
<li>If you create your own shelter material, you can make it <code>passable for</code> your bullet.</li>
<li>Who said the bullet must be shot from your position?</li>
<li>Who said the bullet must fly from bottom to top?</li>
<li>Who said you can only shot one bullet per key press?</li>
<li><script src="//gist.github.com/32f51daac7d17b9e233f.js"></script>
</li>
</ol>
<h3 id="Level-21-endOfTheLine"><a href="#Level-21-endOfTheLine" class="headerlink" title="Level 21: endOfTheLine"></a>Level 21: endOfTheLine</h3><p>It is <code>the End</code>?</p>
<ol>
<li>This isn’t really the last level!</li>
<li>The key is <code>map.finalLevel = true;</code>.</li>
<li>Press <code>Ctrl+0</code> to check what is inside.</li>
<li>What is in <code>scripts/</code> folder?</li>
<li>Why some blocks are purple, some others are black?</li>
<li>Check <code>objects.js</code>, find <code>exit</code> object definition.</li>
<li>Comment out <code>if (!game.map.finalLevel) {</code> and <code>}</code></li>
<li>Go to next level!</li>
</ol>
<script src="//code.jquery.com/jquery-2.1.1.min.js"></script>
<script>
$(function(){var $root = $('.article-entry');
$root.find('ol li').css('display', 'none');
$root.find('ol').each(function(){var $ol = $(this);
$('<li><a href="#">Hint me</a></li>').click(function(e){e.preventDefault();
$ol.find('li:hidden:first').css('display', 'list-item')
if($ol.find('li:hidden').length === 0) {$(this).remove();}
}).appendTo($ol);
});
});
</script>
<p>This post is Walkthrough to the game <a href="http://alexnisnevich.github.io/untrusted/" target="_blank" rel="external">Untrusted</a><br>
Awesome geek game Untrusted - the Continuing Adventures of Dr. Evalhttp://timnew.me/blog/2014/11/05/awesome-geek-game-untrusted-the-continuing-adventures-of-dr-eval/2014-11-05T14:21:40.000Z2014-11-07T15:41:00.000Z<p><a href="http://alexnisnevich.github.io/untrusted/" target="_blank" rel="external">Untrusted</a> is an awesome game brought to us by <a href="http://alex.nisnevich.com/portfolio/" target="_blank" rel="external">Alex Nisnevich</a> and <a href="http://github.everydayimshuflin.com/" target="_blank" rel="external">Greg Shuflin</a>. <code>Untrusted</code> is an unique puzzle game designed for geeks and developers. The reason I said it is designed for geeks and developer is because to solve the puzzles in the game, you need to know or even to write some <code>javascript</code>.</p>
<p>Here is how the creators describe their baby:</p>
<blockquote><p>Untrusted —or— the Continuing Adventures of Dr. Eval is an exciting Meta-Javascript Adventure Game wherein you guide the dashing, steadfast Dr. Eval through a mysterious MACHINE CONTINUUM, wherein, using only his trusty computer and the TURING-COMPLETE power of Javascript, he must literally ALTER HIS REALITY in order to find his freedom! You must literally edit and re-execute the very Javascript running the game in your browser to save Dr. Eval from this dark and confusing reality!</p>
<footer><strong>Untrusted Repo</strong><cite><a href="https://github.com/AlexNisnevich/untrusted" target="_blank" rel="external">github.com/AlexNisnevich/untrusted</a></cite></footer></blockquote>
<p>The description is a little bit hard to understand if you don’t touch the game. I’ll try to translate it a little bit:</p>
<p>In the game, to clear a level, you need to move your <code>avatar</code> to the exit. And just like other normal acarde game, you can control the your <code>avatar</code>, Dr. Eval using <code>arrow keys</code>. The intresting part of this game is that basically, you will always run into the a dead end if you just move Dr.Eval around without doing anything else. Luckily, you will be able to access the source code that creates the world and the rule in the world. To save yourself from the dead end, you need to change part the world/rule by hacking the source code.</p>
<p>The game isn’t that hard if you have some coding experience and is familiar with javascript concepts. And learn from the passed level is very important, since you might find either useful hints or even code to solve your current problem.</p>
<p><strong>NOTE</strong> Besides the puzzle and the code, the music of each level is also great! 8Bit music in different style! Really awesome!</p>
<p>Insterested? Here is the port lead to the game: <a href="http://alexnisnevich.github.io/untrusted/" target="_blank" rel="external">Untrusted</a></p>
<h2 id="Hints-and-Walkthrough"><a href="#Hints-and-Walkthrough" class="headerlink" title="Hints and Walkthrough"></a>Hints and Walkthrough</h2><p><del>I attached my hints and solutions below, is case if you run into trouble.</del></p>
<p>I have extract the walkthrough into another post.</p>
<p>Here is the link to the walkthrough: <a href="/blog/2014/11/07/walkthrough-untrusted-the-continuing-adventures-of-dr-eval/">Walkthrough</a></p>
<p><a href="http://alexnisnevich.github.io/untrusted/" target="_blank" rel="external">Untrusted</a> is an awesome game brought to us by <a h
Perform Clicks in Android Robolectric Unit Testhttp://timnew.me/blog/2014/10/27/perform-clicks-in-android-robolectric-unit-test/2014-10-27T08:17:13.000Z2014-10-27T09:47:34.000Z<p>Robolectric is an awesome library that makes UI unit test on Android a lot easier and faster. In UI test, one of the most basic thing is to simulate user interaction, such as clicking a button.</p>
<h2 id="Click-on-individual-View"><a href="#Click-on-individual-View" class="headerlink" title="Click on individual View"></a>Click on individual View</h2><p><code>Click</code> should be the most basic user interaction, besides invokeing the <code>View.performClick()</code> method, Robolectric provides a more smarter version <code>Robolectric.clickOn(View)</code>, which checks the view visibility and <code>enabled</code> status before actually “click” the view. If a view is either not visible or disabled, the click action will not be performed. This mechanism is useful to avoid some silly cases in automated tests.</p>
<h2 id="Long-Click-on-individual-View"><a href="#Long-Click-on-individual-View" class="headerlink" title="Long Click on individual View"></a>Long Click on individual View</h2><p><code>Long click</code> is a more advanced <code>click</code> action. To simulate a long click action, <code>View.performLongClick()</code> can be invoked. But since Robolectric doesn’t provide any long click helper, make sure you do it by yourself, including checking whether view is <code>long-clickable</code>, which usually will be set manually or more often, when <code>View.setOnLongClickListener</code> is invoked; view is visible and enabled as what <code>click</code> does. Although <code>Long click</code> is avaible to use, but from my experience, long click on a individual view is rarely used in real UI design, instead <code>long click</code> is usually performed on an item of list view or grid view. This is the trickest case that I’ll leave it to the last.</p>
<h2 id="Click-on-item-of-List-Grid"><a href="#Click-on-item-of-List-Grid" class="headerlink" title="Click on item of List/Grid"></a>Click on item of List/Grid</h2><p><code>Click</code> on List View or Grid View item. Well, idally, this shouldn’t be so much different than click on a indiviual view. But in Android implementation, item click is handled by the list view with a much more complicated API. To perform an <code>item click</code>, <code>boolean performItemClick(View v, int position, long id)</code> can be invoked. <code>performItemClick</code> requires 3 parameters, the first one is the view being clicked, the second one is the position of clicked view’s corresponding data item in adapter and the last is the if of clicked view’s corresponding data item. Complicated, isn’t it?</p>
<p>In Android implementation, item view displayed in ListView/GridView is actually provided by its adapter. Adapter works like a presenter in MVP pattern that creates/update item view based on the item data it holds. It also provides the id for the item. So to perform a item click, besides the ListView/GridView, you also need its adapter.</p>
<p>Following implementation explains how it works:</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">clickItem</span><span class="params">(AbsListView listView, <span class="keyword">int</span> position)</span> </span>{</div><div class="line"> ListAdapter adapter = listView.getAdapter();</div><div class="line"> View itemView = adapter.getView(position, <span class="keyword">null</span>, listView);</div><div class="line"> listView.performItemClick(itemView, position, adapter.getItemId(position));</div><div class="line">}</div></pre></td></tr></table></figure>
<p>In the code, <code>AbsListView</code> is the base class of <code>ListView</code> and <code>GridView</code>. To click the item, you need</p>
<ol>
<li>Get the adapter of the <code>AbsListView</code></li>
<li>Create an <code>item view</code> for specific <code>position</code> with adapter</li>
<li>Calculate the <code>item id</code> of corresponding <code>position</code></li>
<li>Invoke <code>performItemClick</code> method with data we got before.</li>
</ol>
<p>In the implementation, for simplicity reason, we ignored some cases, such as convertView reusing. From my experience, in most cases, it won’t impact the functionality, so we don’t need to worry about it, unless you clearly know that matters, then you need to cover them in your tests.</p>
<h2 id="Long-click-and-item-of-List-Grid"><a href="#Long-click-and-item-of-List-Grid" class="headerlink" title="Long click and item of List/Grid"></a>Long click and item of List/Grid</h2><p>Well, this action is also not a commonly used. It is only used in limited cases, such as selecting multiple item or displaying context menu for specific item.<br>To perform a long click on the item is the most trickest case. In previous 3 cases, we either directly or indrectly depends on <code>View.perform***Click</code> method. But not sure why, android doesn’t provide similar public API method of <code>item long click</code>. By diving into Anrdoid source code, we can figure out that Item Long Click isn’t really handled by ListView itself, instead it is handled by a <code>Runnable</code> named <code>CheckForKeyLongPress</code>. To invoke method on this object isn’t that streight forward, and might involes unnecessary multithread issue.</p>
<p>I just want to click a item, why I have to deal with these unnecessary complicates? So I learnt from the <code>CheckForKeyLongPress</code> implementation, and implmented my own “API”:</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">longClickItem</span><span class="params">(AbsListView listView, <span class="keyword">int</span> position)</span> </span>{</div><div class="line"> <span class="keyword">if</span> (!listView.isLongClickable())</div><div class="line"> <span class="keyword">return</span>;</div><div class="line"></div><div class="line"> OnItemLongClickListener listener = listView.getOnItemLongClickListener();</div><div class="line"> <span class="keyword">if</span> (listener == <span class="keyword">null</span>)</div><div class="line"> <span class="keyword">return</span>;</div><div class="line"></div><div class="line"> ListAdapter adapter = listView.getAdapter();</div><div class="line"> View itemView = adapter.getView(position, <span class="keyword">null</span>, listView);</div><div class="line"></div><div class="line"> listener.onItemLongClick(listView, itemView, position, adapter.getItemId(position));</div><div class="line"> listView.performHapticFeedback(LONG_PRESS);</div><div class="line">}</div></pre></td></tr></table></figure>
<p>My main purpose of perform a click is to trigger the corresponding listener, so I tried to invoke the listener directly with some necessary pre-checks. This aporach will not triggers these UI effects, but I assume it can meet most test cases.</p>
<h2 id="APPENDIX-UIActions-helper-class"><a href="#APPENDIX-UIActions-helper-class" class="headerlink" title="APPENDIX UIActions helper class"></a>APPENDIX UIActions helper class</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div><div class="line">45</div><div class="line">46</div><div class="line">47</div><div class="line">48</div><div class="line">49</div><div class="line">50</div><div class="line">51</div><div class="line">52</div><div class="line">53</div><div class="line">54</div><div class="line">55</div><div class="line">56</div><div class="line">57</div><div class="line">58</div><div class="line">59</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">package</span> me.timnew.robolectric.utils;</div><div class="line"></div><div class="line"><span class="keyword">import</span> android.app.Activity;</div><div class="line"><span class="keyword">import</span> android.app.Fragment;</div><div class="line"><span class="keyword">import</span> android.view.View;</div><div class="line"><span class="keyword">import</span> android.widget.AbsListView;</div><div class="line"><span class="keyword">import</span> android.widget.ListAdapter;</div><div class="line"></div><div class="line"><span class="keyword">import</span> org.robolectric.Robolectric;</div><div class="line"></div><div class="line"><span class="keyword">import</span> <span class="keyword">static</span> android.view.HapticFeedbackConstants.LONG_PRESS;</div><div class="line"><span class="keyword">import</span> <span class="keyword">static</span> android.widget.AdapterView.OnItemLongClickListener;</div><div class="line"></div><div class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">UiActions</span> </span>{</div><div class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">boolean</span> <span class="title">clickOn</span><span class="params">(View view)</span> </span>{</div><div class="line"> <span class="keyword">return</span> Robolectric.clickOn(view);</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">boolean</span> <span class="title">clickOn</span><span class="params">(Activity activity, <span class="keyword">int</span> targetViewId)</span> </span>{</div><div class="line"> <span class="keyword">return</span> Robolectric.clickOn(activity.findViewById(targetViewId));</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">boolean</span> <span class="title">clickOn</span><span class="params">(View parentView, <span class="keyword">int</span> targetViewId)</span> </span>{</div><div class="line"> <span class="keyword">return</span> Robolectric.clickOn(parentView.findViewById(targetViewId));</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">boolean</span> <span class="title">clickOn</span><span class="params">(Fragment fragment, <span class="keyword">int</span> targetViewId)</span> </span>{</div><div class="line"> <span class="comment">//noinspection ConstantConditions</span></div><div class="line"> <span class="keyword">return</span> Robolectric.clickOn(fragment.getView().findViewById(targetViewId));</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">pressBackButton</span><span class="params">(Activity currentActivity)</span> </span>{</div><div class="line"> <span class="keyword">if</span> (currentActivity.getFragmentManager().getBackStackEntryCount() > <span class="number">0</span>)</div><div class="line"> currentActivity.getFragmentManager().popBackStackImmediate();</div><div class="line"> <span class="keyword">else</span></div><div class="line"> currentActivity.onBackPressed();</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">clickItem</span><span class="params">(AbsListView listView, <span class="keyword">int</span> position)</span> </span>{</div><div class="line"> ListAdapter adapter = listView.getAdapter();</div><div class="line"> View itemView = adapter.getView(position, <span class="keyword">null</span>, listView);</div><div class="line"> listView.performItemClick(itemView, position, adapter.getItemId(position));</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">longClickItem</span><span class="params">(AbsListView listView, <span class="keyword">int</span> position)</span> </span>{</div><div class="line"> <span class="keyword">if</span> (!listView.isLongClickable())</div><div class="line"> <span class="keyword">return</span>;</div><div class="line"></div><div class="line"> OnItemLongClickListener listener = listView.getOnItemLongClickListener();</div><div class="line"> <span class="keyword">if</span> (listener == <span class="keyword">null</span>)</div><div class="line"> <span class="keyword">return</span>;</div><div class="line"></div><div class="line"> ListAdapter adapter = listView.getAdapter();</div><div class="line"> View itemView = adapter.getView(position, <span class="keyword">null</span>, listView);</div><div class="line"></div><div class="line"> listener.onItemLongClick(listView, itemView, position, adapter.getItemId(position));</div><div class="line"> listView.performHapticFeedback(LONG_PRESS);</div><div class="line"> }</div><div class="line">}</div></pre></td></tr></table></figure>
<p>Robolectric is an awesome library that makes UI unit test on Android a lot easier and faster. In UI test, one of the most basic thing is
2 Modules Android project with Robolectric, Gradle, Android Studiohttp://timnew.me/blog/2014/09/30/2-modules-android-project-with-robolectric-gradle-android-studio/2014-09-30T05:00:58.000Z2014-09-30T06:50:11.000Z<p>Start a new Android project this week, so I started to setup the development environment. To be honest, it is not an easy experience to me.</p>
<h2 id="Features"><a href="#Features" class="headerlink" title="Features"></a>Features</h2><p>Here are the features I got now:</p>
<ul>
<li>Unit test with Robolectric. (Very fundamental requirement)</li>
<li>Unit tests are separated into an independent module. (Provide flexibility when project growing larger. And provide a more clear view of code organization)</li>
<li>Running unit tests recognized by Android Studio/IntelliJ unit test plugin and debug UTs in IDE. (This is very important when diagnose failure UT)</li>
<li>Running unit tests via CLI with <code>gradle wrapper</code>. (This is necessary requirement for CI servers)</li>
<li>Using resources in Robolectric test. (Avoid <code>Resource Not Found</code> exception in unit tests)</li>
<li>Test Android Annotation powered async implementation. (AA introduces new Async implementation, which is not supported by Robolectric by default)</li>
<li>AssertJ core support. (Fest has been deprecated since no one is maintain it now.)</li>
</ul>
<h2 id="Versions"><a href="#Versions" class="headerlink" title="Versions"></a>Versions</h2><p>The major difficulties that I met are version compatibility, I almost tried all available version combinations to make them all works. Here are the versions that I uses</p>
<ul>
<li>Gradle: 2.1</li>
<li>Groovy: 2.3.6</li>
<li>Ant: 1.9.3</li>
<li>JVM: 1.6.0_65 (Apple Inc. 20.65-b04-462)</li>
<li>OS: Mac OS X 10.9.5 x86_64</li>
<li>Android Studio: 0.8.11 (build AI-135.1446794)</li>
<li>IntelliJ: IDEA 14 CE EAP, build IC-138.2458.8</li>
<li>Android gradle plugin: com.android.tools.build:gradle:0.13.0</li>
<li>Android ADT gradle plugin: com.neenbedankt.gradle.plugins:android-apt:1.4+</li>
<li>Compile SDK version: 20</li>
<li>Build tool version: 20.0.0</li>
<li>Robolectric: 2.3</li>
</ul>
<h1 id="Known-Issues"><a href="#Known-Issues" class="headerlink" title="Known Issues"></a>Known Issues</h1><p>My current solution isn’t perfect. But for now, I haven’t working solution for them. Hope it could be fixed in the future</p>
<ul>
<li><code>AAR</code> is not supported in Unit Test. (A tricky issue, I’ll explain more in detail later)</li>
<li><a href="https://github.com/square/assertj-android" target="_blank" rel="external">AssertJ-Android</a> is not supported. (Cause by AAR support issue, alternative available.)</li>
</ul>
<h2 id="Project-Structure-and-configurations"><a href="#Project-Structure-and-configurations" class="headerlink" title="Project Structure and configurations"></a>Project Structure and configurations</h2><p>Here are the project structure:<br><figure class="highlight 1c"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line">RootProject</div><div class="line"><span class="string">|- settings.gradle</span></div><div class="line"><span class="string">|- build.gradle</span></div><div class="line"><span class="string">|- Launcher</span></div><div class="line"> \- builde.gradle</div><div class="line">\- UnitTest</div><div class="line"> <span class="string">|- build.gradle</span></div><div class="line"> \- UnitTest.iml</div></pre></td></tr></table></figure></p>
<p>Here are the contents</p>
<figure class="highlight gradle"><figcaption><span>\Settings.gradle</span></figcaption><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">include</span> <span class="string">':Launcher'</span>, <span class="string">':UnitTest'</span></div></pre></td></tr></table></figure>
<figure class="highlight gradle"><figcaption><span>\build.gradle</span></figcaption><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">buildscript</span> {</div><div class="line"> <span class="keyword">repositories</span> {</div><div class="line"> mavenCentral()</div><div class="line"> }</div><div class="line"> <span class="keyword">dependencies</span> {</div><div class="line"> <span class="keyword">classpath</span> <span class="string">'com.android.tools.build:gradle:0.13.0'</span></div><div class="line"> }</div><div class="line">}</div><div class="line"></div><div class="line"><span class="keyword">allprojects</span> {</div><div class="line"> <span class="keyword">repositories</span> {</div><div class="line"> mavenLocal()</div><div class="line"> mavenCentral()</div><div class="line"> }</div><div class="line">}</div></pre></td></tr></table></figure>
<figure class="highlight gradle"><figcaption><span>\Launcher\build.gradle</span></figcaption><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div><div class="line">45</div><div class="line">46</div><div class="line">47</div><div class="line">48</div><div class="line">49</div><div class="line">50</div><div class="line">51</div><div class="line">52</div><div class="line">53</div><div class="line">54</div><div class="line">55</div><div class="line">56</div><div class="line">57</div><div class="line">58</div><div class="line">59</div><div class="line">60</div><div class="line">61</div><div class="line">62</div><div class="line">63</div><div class="line">64</div><div class="line">65</div><div class="line">66</div><div class="line">67</div><div class="line">68</div><div class="line">69</div><div class="line">70</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">buildscript</span> {</div><div class="line"> <span class="keyword">repositories</span> {</div><div class="line"> mavenCentral()</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">dependencies</span> {</div><div class="line"> <span class="keyword">classpath</span> <span class="string">'com.android.tools.build:gradle:0.13.0'</span></div><div class="line"> <span class="keyword">classpath</span> <span class="string">'com.neenbedankt.gradle.plugins:android-apt:1.4+'</span></div><div class="line"> }</div><div class="line">}</div><div class="line"></div><div class="line"><span class="keyword">repositories</span> {</div><div class="line"> mavenLocal()</div><div class="line"> mavenCentral()</div><div class="line">}</div><div class="line"></div><div class="line">apply plugin: <span class="string">'com.android.application'</span></div><div class="line">apply plugin: <span class="string">'android-apt'</span></div><div class="line"></div><div class="line"></div><div class="line">android {</div><div class="line"> compileSdkVersion <span class="number">20</span></div><div class="line"> buildToolsVersion <span class="string">'20.0.0'</span></div><div class="line"></div><div class="line"> defaultConfig {</div><div class="line"> minSdkVersion <span class="number">9</span></div><div class="line"> targetSdkVersion <span class="number">19</span></div><div class="line"> versionCode <span class="number">1</span></div><div class="line"> versionName <span class="string">"1.0"</span></div><div class="line"> }</div><div class="line"></div><div class="line"> buildTypes {</div><div class="line"> debug {</div><div class="line"> runProguard <span class="keyword">false</span></div><div class="line"> proguardFiles getDefaultProguardFile(<span class="string">'proguard-android.txt'</span>), <span class="string">'proguard-rules.txt'</span></div><div class="line"> }</div><div class="line"> release {</div><div class="line"> runProguard <span class="keyword">false</span></div><div class="line"> proguardFiles getDefaultProguardFile(<span class="string">'proguard-android.txt'</span>), <span class="string">'proguard-rules.txt'</span></div><div class="line"> }</div><div class="line"> }</div><div class="line">}</div><div class="line"></div><div class="line">apt {</div><div class="line"> arguments {</div><div class="line"> androidManifestFile variant.processResources.manifestFile</div><div class="line"> resourcePackageName <span class="string">'me.timnew.game.launcher'</span></div><div class="line"> }</div><div class="line">}</div><div class="line"></div><div class="line"><span class="keyword">def</span> AAVersion = <span class="string">'3.1'</span></div><div class="line"><span class="keyword">dependencies</span> {</div><div class="line"> apt <span class="string">"org.androidannotations:androidannotations:$AAVersion"</span> <span class="comment">// Process AA annotations</span></div><div class="line"> <span class="comment">/*</span></div><div class="line"> * Android Studio will remove this line if you try to edit project configuration with GUI.</div><div class="line"> * It seems it is a bug of Android Studio since it does not understand DSL `apt`</div><div class="line"> */</div><div class="line"> <span class="keyword">compile</span> <span class="string">"org.androidannotations:androidannotations-api:$AAVersion"</span> <span class="comment">// AA Runtime API. Becareful</span></div><div class="line"></div><div class="line"> <span class="keyword">compile</span> <span class="string">'de.greenrobot:eventbus:2.2.1'</span></div><div class="line"> <span class="keyword">compile</span> <span class="string">'org.easytesting:fest-reflect:1.4.1'</span></div><div class="line"> <span class="keyword">compile</span> <span class="string">'com.google.guava:guava:18.0'</span></div><div class="line"> <span class="keyword">compile</span> <span class="string">'com.koushikdutta.ion:ion:1.3.8'</span></div><div class="line"></div><div class="line"> <span class="keyword">compile</span> <span class="keyword">fileTree</span>(dir: <span class="string">'libs'</span>, <span class="keyword">include</span>: [<span class="string">'*.jar'</span>, <span class="string">'*.aar'</span>]) <span class="comment">// Well although I mentioned aar here, but it doesn't load correctly.</span></div><div class="line"></div><div class="line"> <span class="keyword">compile</span> <span class="string">'com.android.support:support-v4:20.0.0'</span></div><div class="line"> <span class="keyword">compile</span> <span class="string">'com.android.support:support-annotations:20.0.0'</span></div><div class="line"> <span class="keyword">compile</span> <span class="string">'com.android.support:appcompat-v7:20.0.0'</span></div><div class="line">}</div></pre></td></tr></table></figure>
<figure class="highlight gradle"><figcaption><span>\UnitTest\build.gradle</span></figcaption><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">buildscript</span> {</div><div class="line"> <span class="keyword">repositories</span> {</div><div class="line"> mavenCentral()</div><div class="line"> }</div><div class="line"> <span class="keyword">dependencies</span> {</div><div class="line"> <span class="keyword">classpath</span> <span class="string">'com.android.tools.build:gradle:0.13.0'</span></div><div class="line"> }</div><div class="line">}</div><div class="line"></div><div class="line">apply plugin: <span class="string">'java'</span></div><div class="line"></div><div class="line"><span class="keyword">repositories</span> {</div><div class="line"> mavenLocal()</div><div class="line"> maven { url <span class="string">"$System.env.ANDROID_HOME/extras/android/m2repository"</span> } <span class="comment">// Fix 'com.android.support:*' package not found issue</span></div><div class="line"> mavenCentral()</div><div class="line">}</div><div class="line"></div><div class="line"><span class="keyword">dependencies</span> {</div><div class="line"> <span class="keyword">def</span> appModule = <span class="keyword">project</span>(<span class="string">':Launcher'</span>)</div><div class="line"> <span class="keyword">compile</span> appModule</div><div class="line"></div><div class="line"> testCompile appModule.android.applicationVariants.<span class="keyword">toList</span>().first().javaCompile.<span class="keyword">classpath</span> <span class="comment">// Include classes from main project</span></div><div class="line"> testCompile appModule.android.applicationVariants.<span class="keyword">toList</span>().first().javaCompile.outputs.files</div><div class="line"> testCompile files(appModule.plugins.findPlugin(<span class="string">"com.android.application"</span>).getBootClasspath())</div><div class="line"></div><div class="line"> testCompile(<span class="string">'junit:junit:4.+'</span>) {</div><div class="line"> <span class="keyword">exclude</span> module: <span class="string">'hamcrest-core'</span> <span class="comment">// Exclude problematic 'hamcrest'</span></div><div class="line"> }</div><div class="line"> testCompile <span class="string">'org.robolectric:robolectric:2.3'</span></div><div class="line"> testCompile <span class="string">'org.mockito:mockito-core:1.9.5'</span></div><div class="line"> testCompile <span class="string">'org.assertj:assertj-core:1.6.1'</span></div><div class="line">}</div><div class="line"></div><div class="line">tasks.withType(Test) {</div><div class="line"> scanForTestClasses = <span class="keyword">false</span></div><div class="line"> <span class="keyword">include</span> <span class="string">"**/*Should.class"</span></div><div class="line"> <span class="keyword">include</span> <span class="string">"**/*Test.class"</span></div><div class="line"> <span class="keyword">include</span> <span class="string">"**/*Tests.class"</span></div><div class="line">}</div></pre></td></tr></table></figure>
<h2 id="Why-uses-java-plug-in-instead-of-android-unit-test-plug-ins"><a href="#Why-uses-java-plug-in-instead-of-android-unit-test-plug-ins" class="headerlink" title="Why uses java plug-in instead of android unit test plug-ins"></a>Why uses <code>java</code> plug-in instead of <code>android unit test</code> plug-ins</h2><p>Well, Gradle DSL provides a lot of flexibility to developer. But it also brought a lot complexity to IDE implementation. To figure out project configuration, IDE need to parse and understand the gradle scripts. Not only DSLs provided by gradle but all stuff come with plug-ins. From IDE, this is almost an impossible mission. So IDE need to figure out a way to simplify the process, such as support a subset of DSL.</p>
<p>For Android project, IntelliJ has difficulties to understand the all variations of <code>android unit test</code> plug-ins. So it is not easy to make unit test runnable from IDE. To solve the issue, you either try to teach IDE about the DSL by providing plug-in to IDE, or uses some languages that IDE understood.</p>
<p>I tried some plug-in available today, but none of them works for me. So I decide to use <code>java</code> DSL, which IntelliJ understood natively. As a trade off, since <code>java</code> gradle plugin doesn’t understand <code>Android Library</code>, so it cannot import <code>.aar</code> libries.</p>
<p>Besides I tried all <code>android unit test</code> gradle plugins, I found all of them depends on <code>android</code> gradle plugin. And <code>android</code> plugin depends on <code>AndroidManifest.xml</code> and some other stuff. It is wield to provide an manifest for your unit test.</p>
<p>So as the final solution, I uses <code>java</code> plug-in, avoid using <code>aar</code> in the test.</p>
<h2 id="Why-so-complicate"><a href="#Why-so-complicate" class="headerlink" title="Why so complicate"></a>Why so complicate</h2><p>Configurate an working Android project isn’t as easy as it sounds. Differ from iOS community, Google isn’t strong-minded as Apple. As a consequence that Android community is fragmented and lack of unified solution. There are tons of solutions available, but you might need to try them one by one to figure out which fits your requirement.</p>
<p>To make your tool chain, dependencies, IDE work together, compatibility is always your enemy. Even Google has to publish <a href="http://tools.android.com/tech-docs/new-build-system/version-compatibility" target="_blank" rel="external">Version Compatibility Table</a> to mitigate the pain.</p>
<p>What a mess!!!!!</p>
<h2 id="References-posts-plugins-or-template-projects"><a href="#References-posts-plugins-or-template-projects" class="headerlink" title="References posts, plugins or template projects"></a>References posts, plugins or template projects</h2><p>Here is a list of things that I tried but failed to fit my requirement. List here since it might be helpful to other people.</p>
<ul>
<li><a href="http://blog.blundell-apps.com/android-gradle-app-with-robolectric-junit-tests/" target="_blank" rel="external">Android Gradle App with Robolectric JUnit tests</a></li>
<li><a href="https://github.com/blundell/tests-app-robolectric-junit" target="_blank" rel="external">tests-app-robolectric-junit</a> template project</li>
<li><a href="https://github.com/robolectric/deckard-gradle" target="_blank" rel="external">deckard-gradle</a> template project</li>
<li><a href="https://github.com/JCAndKSolutions/android-unit-test" target="_blank" rel="external">android-unit-test</a> gradle plug in</li>
<li><a href="https://github.com/evant/android-studio-unit-test-plugin" target="_blank" rel="external">android-studio-unit-test-plugin</a> android studio/intellij plugin</li>
<li><a href="https://github.com/robolectric/robolectric-gradle-plugin" target="_blank" rel="external">robolectric-gradle-plugin</a></li>
<li><a href="https://github.com/novoda/robolectric-plugin" target="_blank" rel="external">robolectric-plugin</a></li>
</ul>
<p>Start a new Android project this week, so I started to setup the development environment. To be honest, it is not an easy experience to m
Trello Confetti Effecthttp://timnew.me/blog/2014/09/24/trello-confetti-effect/2014-09-24T05:13:33.000Z2016-04-13T16:29:32.000Z<p><a href="https://trello.com" target="_blank" rel="external">Trello</a> just created a <a href="https://trello.com/5m" target="_blank" rel="external">page</a> to celebrate their user number reaches 5 million. In their celebration page, they introduce an interesting effect, a number of blue squares rotating and falling from the sky.</p>
<p>By inspecting their source code, I extracted the effect implementation from the page.</p>
<iframe id="cp_embed_tlEBe" src="//codepen.io/timnew/embed/tlEBe?height=500&theme-id=7928&slug-hash=tlEBe&default-tab=result" scrolling="no" frameborder="no" height="500" allowtransparency="true" allowfullscreen="true" class="cp_embed_iframe" style="width: 100%; overflow: hidden;"></iframe>
<p>As you can see, the effect is implemented with Canvas animation. Trello guys created a light weight particle system.</p>
<ul>
<li><code>ConfettiMachine</code> is the particle system controller, which takes the responsibility to create new particles and call <code>draw</code> method on them one by one.</li>
<li><code>Particle</code> is the representation of the blue square, it takes the rotation, fading out and rendering.</li>
</ul>
<p>The source code is extracted for study purpose, all code and credits belongs to Trello guys.</p>
<p><a href="https://trello.com" target="_blank" rel="external">Trello</a> just created a <a href="https://trello.com/5m" target="_blank" rel
Otto and Android Annotations Compatibility Issue Analysishttp://timnew.me/blog/2014/09/14/otto-and-android-annotations-compatibility-issue-analysis/2014-09-14T08:14:22.000Z2014-09-14T08:14:22.000Z<h2 id="Introduction"><a href="#Introduction" class="headerlink" title="Introduction"></a>Introduction</h2><p><a href="https://github.com/square/otto" target="_blank" rel="external">Otto</a> is a great Android event bus solution developed by <a href="http://square.github.io/" target="_blank" rel="external">SquareUp</a> guys. These guys extract the event bus related classes from <a href="https://code.google.com/p/guava-libraries/" target="_blank" rel="external">Google’s Guava</a>, and optimized it for Android. Event Bus is a great solution to keep your code away from messy anonymous or internal classes only used for event handling! And Otto’s simplicity and performance makes it used to be the most popular event bus solution in Android development.</p>
<p><a href="http://androidannotations.org/" target="_blank" rel="external">Android Annotations</a>, as known as <code>AA</code>, is another great library that makes Android developers’ lives a lot easier. Just annotating the code, AA helps developer handles the most boring or error-proning tasks for you, including binding widgets binding, asynchronous tasks, life time management, etc…</p>
<h2 id="Issue"><a href="#Issue" class="headerlink" title="Issue"></a>Issue</h2><p>Otto and AA are the libraries focusing on different aspects. Theoretically speaking, there shouldn’t be any compatibility issue between them. But the reality Otto event is never delivered to AA annotated classes. By inspecting the code with step by step debugging, I found the root cause of the issue is Otto failed to located <code>@Produce</code> and <code>@Subscribe</code> annotated methods in AA generated code.</p>
<h2 id="Analysis"><a href="#Analysis" class="headerlink" title="Analysis"></a>Analysis</h2><p>After a few study work, I finally understood what is the reason behind:</p>
<p>For performance consideration, Android Annotations actually does it work during the compilation time instead of Runtime. AA will derive the annotated classes, and generate some code according to the annotations applied. During the runtime, the classes got instantiated is actually the derived classes instead of the original one, although in the code is accessed via the original class as interface.</p>
<p>Here is a simple example:</p>
<p>I have the class <code>ServerListAdapter</code>, which is used to provide data for a grid view.</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div><div class="line">45</div><div class="line">46</div><div class="line">47</div><div class="line">48</div><div class="line">49</div><div class="line">50</div></pre></td><td class="code"><pre><div class="line"><span class="meta">@EBean</span></div><div class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ServerListAdapter</span> <span class="keyword">extends</span> <span class="title">AdvBaseAdapter</span><<span class="title">InetAddress</span>, <span class="title">ServerView</span>> </span>{</div><div class="line"></div><div class="line"> <span class="meta">@RootContext</span></div><div class="line"> <span class="keyword">protected</span> Context context;</div><div class="line"></div><div class="line"> <span class="meta">@SystemService</span></div><div class="line"> <span class="keyword">protected</span> LayoutInflater inflater;</div><div class="line"></div><div class="line"> <span class="meta">@Bean</span></div><div class="line"> <span class="keyword">protected</span> Bus bus;</div><div class="line"></div><div class="line"> <span class="function"><span class="keyword">public</span> <span class="title">ServerListAdapter</span><span class="params">()</span> </span>{</div><div class="line"> <span class="keyword">super</span>(<span class="keyword">new</span> ArrayList<InetAddress>());</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="meta">@AfterInject</span></div><div class="line"> <span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">afterInject</span><span class="params">()</span> </span>{</div><div class="line"> bus.register(<span class="keyword">this</span>);</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="meta">@Override</span></div><div class="line"> <span class="function"><span class="keyword">protected</span> ServerView <span class="title">createView</span><span class="params">(ViewGroup parent)</span> </span>{</div><div class="line"> <span class="keyword">return</span> ServerView_.build(context);</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="meta">@Override</span></div><div class="line"> <span class="function"><span class="keyword">protected</span> ServerView <span class="title">updateView</span><span class="params">(ServerView itemView, InetAddress item)</span> </span>{</div><div class="line"> itemView.update(item);</div><div class="line"> <span class="keyword">return</span> itemView;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="meta">@Subscribe</span></div><div class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">fetchServerStatus</span><span class="params">(DiscoveryStatusEvent event)</span> </span>{</div><div class="line"> setItems(event.addresses);</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="meta">@Subscribe</span></div><div class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onServerStatusUpdated</span><span class="params">(DiscoveryStatusChangedEvent event)</span> </span>{</div><div class="line"> <span class="keyword">switch</span> (event.type) {</div><div class="line"> <span class="keyword">case</span> SERVER_ONLINE:</div><div class="line"> getItems().add(event.address);</div><div class="line"> <span class="keyword">break</span>;</div><div class="line"> <span class="keyword">case</span> SERVER_OFFLINE:</div><div class="line"> getItems().remove(event.address);</div><div class="line"> <span class="keyword">break</span>;</div><div class="line"> }</div><div class="line"> notifyDataSetChanged();</div><div class="line"> }</div><div class="line">}</div></pre></td></tr></table></figure>
<p>And this is the derived class generated by <code>AA</code> during the compiling-time:<br><figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">public</span> <span class="keyword">final</span> <span class="class"><span class="keyword">class</span> <span class="title">ServerListAdapter_</span></span></div><div class="line"> <span class="keyword">extends</span> <span class="title">ServerListAdapter</span></div><div class="line">{</div><div class="line"></div><div class="line"> <span class="keyword">private</span> Context context_;</div><div class="line"></div><div class="line"> <span class="function"><span class="keyword">private</span> <span class="title">ServerListAdapter_</span><span class="params">(Context context)</span> </span>{</div><div class="line"> context_ = context;</div><div class="line"> init_();</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> ServerListAdapter_ <span class="title">getInstance_</span><span class="params">(Context context)</span> </span>{</div><div class="line"> <span class="keyword">return</span> <span class="keyword">new</span> ServerListAdapter_(context);</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="function"><span class="keyword">private</span> <span class="keyword">void</span> <span class="title">init_</span><span class="params">()</span> </span>{</div><div class="line"> inflater = ((LayoutInflater) context_.getSystemService(Context.LAYOUT_INFLATER_SERVICE));</div><div class="line"> context = context_;</div><div class="line"> bus = Bus_.getInstance_(context_);</div><div class="line"> afterInject();</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">rebind</span><span class="params">(Context context)</span> </span>{</div><div class="line"> context_ = context;</div><div class="line"> init_();</div><div class="line"> }</div><div class="line"></div><div class="line">}</div></pre></td></tr></table></figure></p>
<p>And here is how it is consumed:<br><figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div></pre></td><td class="code"><pre><div class="line"><span class="meta">@EFragment</span>(R.layout.fragment_server_list)</div><div class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ServerListFragment</span> <span class="keyword">extends</span> <span class="title">Fragment</span> </span>{</div><div class="line"> <span class="meta">@Bean</span></div><div class="line"> <span class="keyword">protected</span> DiscoveryService discoveryService;</div><div class="line"></div><div class="line"> <span class="meta">@Bean</span></div><div class="line"> <span class="keyword">protected</span> ServerListAdapter adapter;</div><div class="line"></div><div class="line"> <span class="meta">@ViewById</span>(R.id.server_list)</div><div class="line"> <span class="keyword">protected</span> GridView serverGridView;</div><div class="line"></div><div class="line"> <span class="meta">@AfterViews</span></div><div class="line"> <span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">afterViews</span><span class="params">()</span> </span>{</div><div class="line"> serverGridView.setAdapter(adapter);</div><div class="line"></div><div class="line"> discoveryService.start();</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="meta">@Override</span></div><div class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onDetach</span><span class="params">()</span> </span>{</div><div class="line"> <span class="keyword">super</span>.onDetach();</div><div class="line"> discoveryService.stop();</div><div class="line"> }</div><div class="line">}</div></pre></td></tr></table></figure></p>
<p>As you can see, in the <code>ServerListFragment</code>, the <code>ServerListAdapter</code> instance injected into <code>bean</code> is actually the instance of <code>ServerListAdapter_</code>. And due to polymorphic, the instance just behaves like a <code>ServerListAdapter</code> instance.</p>
<p>On the other hand, according to the description on <a href="http://square.github.io/otto/" target="_blank" rel="external">Otto’s Home Page</a>:</p>
<blockquote><p>In order to receive events, a class instance needs to register with the bus.<br>…<br>Registering will only find methods on the immediate class type. Unlike the Guava event bus, Otto will not traverse the class hierarchy and add methods from base classes or interfaces that are annotated. This is an explicit design decision to improve performance of the library as well as keep your code simple and unambiguous.</p>
<footer><strong>@Otto</strong><cite><a href="http://square.github.io/otto/" target="_blank" rel="external">Otto Homepage</a></cite></footer></blockquote>
<p>Otto only search annotations in direct class, which is <code>ServerListAdapter_</code> in instance, and there isn’t any annotation included. As a consequence, all the <code>@Subscribe</code> annotated methods are ignored by <code>com.squareup.otto.AnnotatedHandlerFinder</code>. So the posted events become <code>dead event</code> due to no subscriber found.</p>
<h2 id="Comments"><a href="#Comments" class="headerlink" title="Comments"></a>Comments</h2><p>There is <a href="https://github.com/square/otto/issues/61" target="_blank" rel="external">rumor</a> that this issue will be fixed in <code>Otto 2.0</code>. But according to the <a href="https://github.com/square/otto/issues/61#issuecomment-44453104" target="_blank" rel="external">comment</a> from <a href="https://github.com/JakeWharton" target="_blank" rel="external">Jake Wharton</a>, Otto’s developer, <code>Otto 2.0</code> will take forever to release.</p>
<p>In fact <a href="https://github.com/square/otto/tree/2.0-wip" target="_blank" rel="external">Otto 2.0 Repo</a> has been not touched for 2 years already. Although we could check out the code and build Otto 2.0 by ourselves, but it takes efforts. Especially when some bug is found.</p>
<h2 id="Conclusion"><a href="#Conclusion" class="headerlink" title="Conclusion"></a>Conclusion</h2><p>Luckily, although <code>Otto</code> turns into “maintenance mode”, the compatibility issue takes forever to resolve. I found a great Otto alternative, EventBus from GreenRobot. A boring name, but great library.</p>
<p>According to <code>EventBus</code>‘s document, it provides richer feature and better performance than <code>Otto</code>.<br>The most important <code>EventBus</code> is friendly to <code>AndroidAnnoations</code>. They two works well together.</p>
<h3 id="EventBus-and-Otto-Feature-Comparison"><a href="#EventBus-and-Otto-Feature-Comparison" class="headerlink" title="EventBus and Otto Feature Comparison"></a>EventBus and Otto Feature Comparison</h3><table>
<thead>
<tr>
<th></th>
<th>EventBus</th>
<th>Otto</th>
</tr>
</thead>
<tbody>
<tr>
<td>Declare event handling methods</td>
<td>Name conventions</td>
<td>Annotations</td>
</tr>
<tr>
<td>Event inheritance</td>
<td>Yes</td>
<td>Yes</td>
</tr>
<tr>
<td>Subscriber inheritance</td>
<td>Yes</td>
<td>No</td>
</tr>
<tr>
<td>Cache most recent events</td>
<td>Yes, sticky events</td>
<td>No</td>
</tr>
<tr>
<td>Event producers (e.g. for coding cached events)</td>
<td>No</td>
<td>Yes</td>
</tr>
<tr>
<td>Event delivery in posting thread</td>
<td>Yes (Default)</td>
<td>Yes</td>
</tr>
<tr>
<td>Event delivery in main thread</td>
<td>Yes</td>
<td>No</td>
</tr>
<tr>
<td>Event delivery in background thread</td>
<td>Yes</td>
<td>No</td>
</tr>
<tr>
<td>Asynchronous event delivery</td>
<td>Yes</td>
<td>No</td>
</tr>
</tbody>
</table>
<h3 id="EventBus-and-Otto-Performance-Comparison"><a href="#EventBus-and-Otto-Performance-Comparison" class="headerlink" title="EventBus and Otto Performance Comparison"></a>EventBus and Otto Performance Comparison</h3><table>
<thead>
<tr>
<th></th>
<th>EventBus over Otto</th>
</tr>
</thead>
<tbody>
<tr>
<td>Posting 1000 events, Android 2.3 emulator</td>
<td>~70% faster</td>
</tr>
<tr>
<td>Posting 1000 events, S3 Android 4.0</td>
<td>~110% faster</td>
</tr>
<tr>
<td>Register 1000 subscribers, Android 2.3 emulator</td>
<td>~10% faster</td>
</tr>
<tr>
<td>Register 1000 subscribers, S3 Android 4.0</td>
<td>~70% faster</td>
</tr>
<tr>
<td>Register subscribers cold start, Android 2.3 emulator</td>
<td>~350% faster</td>
</tr>
<tr>
<td>Register subscribers cold start, S3 Android 4.0</td>
<td>About the same</td>
</tr>
</tbody>
</table>
<h2 id="Introduction"><a href="#Introduction" class="headerlink" title="Introduction"></a>Introduction</h2><p><a href="https://github.com/sq
An interesting share box hover effecthttp://timnew.me/blog/2014/08/26/an-interesting-share-box-hover-effect/2014-08-25T16:13:54.000Z2016-04-13T16:29:40.000Z<p>Today I spent some time on customizing the share-box used in this blog.</p>
<p>Here is the effect</p>
<iframe id="cp_embed_AweKi" src="//codepen.io/timnew/embed/AweKi?height=257&theme-id=7928&slug-hash=AweKi&default-tab=result" scrolling="no" frameborder="no" height="257" allowtransparency="true" allowfullscreen="true" class="cp_embed_iframe" style="width: 100%; overflow: hidden;"></iframe>
<p>The cover effect for the social network icons are simulate the icon is floating from the background by animating the shadow. In the implementation, I used some shadow described in <a href="http://timnew.me/blog/2014/08/16/material-design-shadow-in-html/">Material Design Shadow in HTML</a>. For the texts, I use the <code>text-shadow</code> effect that used on the same text shadow used on tht title of the article.</p>
<p>Today I spent some time on customizing the share-box used in this blog.</p>
<p>Here is the effect</p>
<iframe id="cp_embed_AweKi" src="//
Hexo file name escape issue and solutionhttp://timnew.me/blog/2014/08/20/hexo-file-name-escape-issue-and-solution/2014-08-19T18:49:13.000Z2014-08-23T10:07:47.000Z<p>I’m working on reorganize posts today, and found some filename issue with <code>Hexo</code>.</p>
<h2 id="Speical-symbols-are-not-escaped-properly"><a href="#Speical-symbols-are-not-escaped-properly" class="headerlink" title="Speical symbols are not escaped properly"></a>Speical symbols are not escaped properly</h2><p>Just found this issue today.</p>
<p>To ensure filename generate from title is legal as either file name or url path, <code>Hexo</code> uses <a href="https://github.com/hexojs/hexo/blob/master/lib/util/escape.js#L22" target="_blank" rel="external">hexo.util.escape.filename</a> to escape the illegal symbols. <code>filename</code> does escape some symbols, but it doesn’t cover all illegal symbols, such as <code>+</code>, <code>=</code>, <code>&</code>, etc. If these symbols are not escaped properly, which generates illegal url link. As a result, your post will never be acessible.</p>
<p>I found this issue is because, I have a post with <code>+3 trainer</code> in its title, since <code>+</code> is not escaped, and <code>+</code> will be treated as space by http. As a consequence, my post will never be able to open, unless I escape <code>+</code> as <code>%2B</code>. To avoid this kind of problem, I wish all the symbols in post name are escaped as <code>-</code>.</p>
<p>Besides this issue, <code>Hexo</code> has another issue with name escaping that the escaped file name might contains continues <code>-</code>. For example, your post title is “A great introduction - part 1”, you will get escaped name <code>a-great-introduction---part-1.md</code>. I wish the continues <code>-</code> in the file name should be replaced with single <code>-</code>, name <code>a-great-introduction-part-1.md</code> is more readable than previous one.</p>
<p>To fix the 2 issues, I just created a <a href="https://github.com/hexojs/hexo/pull/804" target="_blank" rel="external">pull request</a>, hope it will be merged soon.</p>
<p>I cared about this issue so much is because I uses <a href="https://github.com/timnew/hexo-console-rename" target="_blank" rel="external">hexo-consle-rename</a> plug-in, which also uses <code>util.escape</code> to handle file name. To keep naming consistency when between different version of <code>Hexo</code>, I addd a kind of evil <a href="https://github.com/timnew/hexo-console-rename/blob/master/lib_src/monkey_patch.js" target="_blank" rel="external">monkey patch</a> in the <code>v0.1.2</code>. So make sure the plug in can work properly even with old <code>Hexo</code>.</p>
<h2 id="File-name-case-issue"><a href="#File-name-case-issue" class="headerlink" title="File name case issue"></a>File name case issue</h2><p>Besides the <code>Hexo</code> naming issue, I also met the case of the filename today. Although it depends on the blog hosting, but it might cause <code>404</code> if the file name case changed.</p>
<p>To avoid this kind of issue, I strongly recommend to set <code>filename_case: 1</code> in <code>_config.yml</code>, which will make sure all file name are in lower case.</p>
<p>There is common pitfall here for Windows or Mac with case-insensitive file system. If you have deploy the website once with wrong filename casing. Regenerate after updated <code>filename_case</code> won’t help, because file system won’t treat case change in filename as “change”. So you cannot really commit the “change” to fix the <code>404</code> issue.</p>
<p>To fix this issue, there is easy and efficient trick. Go to <code>.deploy</code> folder, execute following commands:</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line">$ git rm -rf *</div><div class="line">$ git ci -m "Clean all file"</div><div class="line">$ hexo clean</div><div class="line">$ hexo d -g</div></pre></td></tr></table></figure>
<p>To force clean the repo once enforce git to treat 2 files with same name but different casing as different ones. So the name casing issue can be fixed.</p>
<p>I’m working on reorganize posts today, and found some filename issue with <code>Hexo</code>.</p>
<h2 id="Speical-symbols-are-not-escaped-
Use Hexo Asset Folder to manage resource used by posthttp://timnew.me/blog/2014/08/19/use-hexo-asset-folder-to-manage-resource-used-by-post/2014-08-19T07:57:18.000Z2014-08-23T10:07:47.000Z<p><a href="http://hexo.io" target="_blank" rel="external">Hexo</a> <code>asset folder</code> is a folder that with the same name as you post file, the content in which will be copied to the folder where the rendered post html file located. It is a great way to keep the relationship between the post and its referenced resources. Personally, I prefers to put all the images or other downloadable files that referenced by the post into its <code>asset folder</code>.</p>
<p>Although <code>asset folder</code> is a great idea, but in practice, there are some common pitfall might disappoint you badly.</p>
<h2 id="Relative-Path-Pitfall"><a href="#Relative-Path-Pitfall" class="headerlink" title="Relative Path Pitfall"></a>Relative Path Pitfall</h2><p>The idea of <code>asset folder</code> is actually based on an assumption, that the asset resources will be placed under the same folder with the html. The html can reference these files with relative path.</p>
<p>Suppose we have following files as post file:</p>
<figure class="highlight lsl"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line">/<span class="number">2014</span><span class="number">-08</span><span class="number">-19</span>-awesome-post.md</div><div class="line">/<span class="number">2014</span><span class="number">-08</span><span class="number">-19</span>-awesome-post/</div><div class="line"> screenshot.png</div><div class="line"> document.pdf</div></pre></td></tr></table></figure>
<p>The compiled file structure will be like this:<br><figure class="highlight stylus"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line">/<span class="number">2014</span>/<span class="number">08</span>/<span class="number">19</span>/awesome-post/</div><div class="line"> index<span class="selector-class">.html</span></div><div class="line"> screenshot<span class="selector-class">.png</span></div><div class="line"> document.pdf</div></pre></td></tr></table></figure></p>
<p>The asset files are located in the same folder as the html file. So in the post file, you can reference the resource files as</p>
<figure class="highlight markdown"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">![<span class="string">ScreenShot</span>](<span class="link">screenshot.png</span>)</div><div class="line"></div><div class="line">[<span class="string">Document</span>](<span class="link">document.pdf</span>)</div></pre></td></tr></table></figure>
<p>Then this will be compiled as following Html:<br><figure class="highlight html"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line"><span class="tag"><<span class="name">p</span>></span></div><div class="line"> <span class="tag"><<span class="name">img</span> <span class="attr">src</span>=<span class="string">"screenshot.png"</span>></span></div><div class="line"><span class="tag"></<span class="name">p</span>></span></div><div class="line"><span class="tag"><<span class="name">p</span>></span></div><div class="line"> <span class="tag"><<span class="name">a</span> <span class="attr">href</span>=<span class="string">"document.pdf"</span>></span>Document<span class="tag"></<span class="name">a</span>></span></div><div class="line"><span class="tag"></<span class="name">p</span>></span></div></pre></td></tr></table></figure></p>
<p>So far it looks great. But if you open your <code>home page</code> of you site, you find the image isn’t displayed, and the link to <code>document.pdf</code> is also broken.</p>
<p>The problem here is that the the relative path assumption only works in <code>/2014/08/19/awesome-post/index.html</code>. But the content compiled from <code>2014-08-19-awesome-post.md</code> might also be used by HomePage(<code>/index.html</code>), Archive Page(<code>/archive/index.html</code>), and <code>tag pages</code> and <code>category pages</code>. For these html pages, the relative path relationship doesn’t exist. So the relative link causes <code>404</code> error.</p>
<p>To solve the issue, someone use absolute url in the post. So they write markdown in this way:<br><figure class="highlight markdown"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">![<span class="string">ScreenShot</span>](<span class="link">/2014/08/19/awesome-post/screenshot.png</span>)</div><div class="line"></div><div class="line">[<span class="string">Document</span>](<span class="link">/2014/08/19/awesome-post/document.pdf</span>)</div></pre></td></tr></table></figure></p>
<p>This approach fix the link issue, but makes you lost the benefits of using relative path.</p>
<p>So you need <a href="https://github.com/timnew/hexo-tag-asset-res" target="_blank" rel="external">hexo-tag-asset-res</a>, which allow you to reference asset resources with relative path. It will convert them into absolute path during compilation. Easy and efficient.</p>
<h2 id="Empty-asset-folders"><a href="#Empty-asset-folders" class="headerlink" title="Empty asset folders"></a>Empty asset folders</h2><p>For convenience, I turned on the <code>post_asset_folder</code> to <code>true</code> in my <code>_config.yml</code>. So the <code>asset folder</code> will be created along with post when I execute <code>hexo new</code>. It is great because create asset folder manually is boring and error-proning. If you introduced a typo carelessly, the link will be broken immediately.</p>
<p>But by ask <code>Hexo</code> to create asset folder automatically causes another problem. I don’t really have asset resources for each post, then there must be a number of empty asset folders. So I wish these folders can be removed if it is empty.</p>
<p>For this purpose, you might need <a href="https://github.com/timnew/hexo-console-clean-asset-folder" target="_blank" rel="external">hexo-console-clean-asset-folder</a>. This plugin helps you to remove all the empty asset folders automatically.</p>
<h2 id="Rename-the-post"><a href="#Rename-the-post" class="headerlink" title="Rename the post"></a>Rename the post</h2><p>Well, renaming a post already published is that common. But it is very likely to rename a draft. When renaming the post file, you have to remember also rename the asset folder too, or the link will broken.</p>
<p>To help you on this issue, you might need <a href="https://github.com/timnew/hexo-console-rename" target="_blank" rel="external">hexo-console-rename</a>. The plugin helps you to rename the asset folder along with post. And it also helps you on migration once you updated your <code>new_post_name</code> pattern.</p>
<p>So this is the common pitfalls in using <code>asset folder</code> in <code>Hexo</code>, and the plug-ins that help you to mitigate the pain.</p>
<p><a href="http://hexo.io" target="_blank" rel="external">Hexo</a> <code>asset folder</code> is a folder that with the same name as you pos
Hexo plug-in to rename the post according to title automaticallyhttp://timnew.me/blog/2014/08/19/hexo-plug-in-to-rename-the-post-according-to-title-automatically/2014-08-18T17:17:28.000Z2014-09-19T03:00:22.000Z<p>When writing blog with [Hexo], I uses <code>hexo new</code> command to create new post file. If the title of the post is provided, then the file is named according to the tile. This is super convinient, and I’m really loving it.</p>
<p>But there is problem! If I changed my mind when during the writing, so I changed the title of the post. As a consequence, the post file name doesn’t match to the post title any longer.</p>
<p>In the past, I have to rename the post file manually. If there is asset folder, I also have to remember rename it accordingly. And I have to becareful to avoid introduce typo, or it either break the reference or cause other problems.</p>
<p>Besides, if you have special name pattern for your post, such as have time-stamp in your post name. The problem is more complicated. You have to reserve the time-stamp carefully, and replace all the space or any other improper characters with <code>-</code>.</p>
<p>At least for me, it is a complicated, error-proning and unpleasant work to do.</p>
<p>I’m a lazy guy, I don’t want to repeat this pain time and time again. To save myself from such pain, I create the plug-in <a href="https://github.com/timnew/hexo-console-rename" target="_blank" rel="external">hexo-console-rename</a>.</p>
<p>The plug-in reads the <code>front-matter</code> of the post, then figure out the proper name. It is smart enough to know what is the proper name for the post, when you changed your configuration, it changes its behavior also.</p>
<p>To use the plug-in is super easy. I usually use it in this way:</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">$ hexo r source/**/*.md</div></pre></td></tr></table></figure>
<p>Then it scans all the posts for me, and fix the filename when necessary. Easy and efficient.</p>
<h2 id="Advanced-Usages"><a href="#Advanced-Usages" class="headerlink" title="Advanced Usages"></a>Advanced Usages</h2><p>Actually after I created the plugin, I figured out sevearl advance usages of this plug-in. Sometimes, it could become your life savor!</p>
<h3 id="new-post-name-updated"><a href="#new-post-name-updated" class="headerlink" title="new_post_name updated"></a><code>new_post_name</code> updated</h3><p>If you change the <code>new_post_name</code> in your <code>_config.yml</code>. You new post will follow a different name pattern than old ones. At this time, you might really want to rename all the old posts to keep consistency! But do it manually is a painful job to do!</p>
<p>Then <a href="https://github.com/timnew/hexo-console-rename" target="_blank" rel="external">hexo-console-rename</a> is your live-savor! You just run</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">$ hexo r -p ':title.md' source/**/*.md</div></pre></td></tr></table></figure>
<p>Then all the old files will be renamed under your new naming rule! Aesome!</p>
<h3 id="date-in-your-post-changed"><a href="#date-in-your-post-changed" class="headerlink" title="date in your post changed"></a><code>date</code> in your post changed</h3><p>It isn’t a common case, but if you have changed the <code>date</code> field in the <code>front-matter</code> of your post. And you have time-stamp in your file name. You can also use <a href="https://github.com/timnew/hexo-console-rename" target="_blank" rel="external">hexo-console-rename</a> to rename the file for you.</p>
<p>For more detail, check out the <a href="https://github.com/timnew/hexo-console-rename" target="_blank" rel="external">hexo-console-rename</a> home page.</p>
<p>When writing blog with [Hexo], I uses <code>hexo new</code> command to create new post file. If the title of the post is provided, then t
Trick to use CoffeeScript in Hexohttp://timnew.me/blog/2014/08/18/trick-to-use-coffeescript-in-hexo/2014-08-18T10:19:44.000Z2016-03-25T13:01:38.000Z<p><a href="http://hexo.io/" target="_blank" rel="external">Hexo</a> has a <code>scripts</code> folder, and the files under which are loaded by <code>Hexo</code> when start. I usually uses this folder as the development folder for my plug-in scripts. And extract them into independent package after polished it into package-ready quality.</p>
<p>Usually, the files under scripts should be <code>javascripts</code>. But as I’m a fan of <a href="http://coffeescript.org/" target="_blank" rel="external">Coffee Script</a>, so I wish to use <code>coffee-script</code> to write the plug-ins. For the formal package, I compile the <code>coffee scripts</code> into <code>javascripts</code> before release. But for development, I wish to use <code>coffee script</code> directly.</p>
<p>In <code>node.js</code>, it is possible to require <code>coffee-script</code> directly, if you registered the <code>coffee-script</code> runtime compiler:</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="built_in">require</span>(<span class="string">'coffee-script/register'</span>);</div></pre></td></tr></table></figure>
<p>And as how node.js <code>require</code> function is implemented, you cannot register <code>coffee-script</code> runtime compiler in <code>.coffee</code> file. Or the compiler will complain:</p>
<figure class="highlight crystal"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div></pre></td><td class="code"><pre><div class="line">[error] <span class="symbol">HexoError:</span> Script load <span class="symbol">failed:</span> plugin.coffee</div><div class="line"><span class="symbol">SyntaxError:</span> Unexpected string</div><div class="line"> at Module._compile (<span class="class"><span class="keyword">module</span>.<span class="title">js</span>:439:25)</span></div><div class="line"> at Object.Module._extensions..js (<span class="class"><span class="keyword">module</span>.<span class="title">js</span>:474:10)</span></div><div class="line"> at Module.load (<span class="class"><span class="keyword">module</span>.<span class="title">js</span>:356:32)</span></div><div class="line"> at Function.Module._load (<span class="class"><span class="keyword">module</span>.<span class="title">js</span>:312:12)</span></div><div class="line"> at Module.<span class="keyword">require</span> (<span class="class"><span class="keyword">module</span>.<span class="title">js</span>:364:17)</span></div><div class="line"> at <span class="keyword">require</span> (<span class="class"><span class="keyword">module</span>.<span class="title">js</span>:380:17)</span></div><div class="line"> at /usr/local/<span class="class"><span class="keyword">lib</span>/<span class="title">node_modules</span>/<span class="title">hexo</span>/<span class="title">lib</span>/<span class="title">loaders</span>/<span class="title">scripts</span>.<span class="title">js</span>:17:11</span></div><div class="line"> at Array.forEach (native)</div><div class="line"> at /usr/local/<span class="class"><span class="keyword">lib</span>/<span class="title">node_modules</span>/<span class="title">hexo</span>/<span class="title">lib</span>/<span class="title">loaders</span>/<span class="title">scripts</span>.<span class="title">js</span>:15:13</span></div><div class="line"> at /usr/local/<span class="class"><span class="keyword">lib</span>/<span class="title">node_modules</span>/<span class="title">hexo</span>/<span class="title">lib</span>/<span class="title">util</span>/<span class="title">file2</span>.<span class="title">js</span>:339:7</span></div><div class="line"> at done (<span class="regexp">/usr/local</span><span class="regexp">/lib/node</span>_modules/hexo/node_modules/async/<span class="class"><span class="keyword">lib</span>/<span class="title">async</span>.<span class="title">js</span>:135:19)</span></div><div class="line"> at /usr/local/<span class="class"><span class="keyword">lib</span>/<span class="title">node_modules</span>/<span class="title">hexo</span>/<span class="title">node_modules</span>/<span class="title">async</span>/<span class="title">lib</span>/<span class="title">async</span>.<span class="title">js</span>:32:16</span></div><div class="line"> at /usr/local/<span class="class"><span class="keyword">lib</span>/<span class="title">node_modules</span>/<span class="title">hexo</span>/<span class="title">lib</span>/<span class="title">util</span>/<span class="title">file2</span>.<span class="title">js</span>:335:11</span></div><div class="line"> at Object.oncomplete (evalmachine.<anonymous>:<span class="number">107</span>:<span class="number">15</span>)</div></pre></td></tr></table></figure>
<p>Theoretically, it is possible to put the <code>coffee-script</code> registration code in a <code>javascript</code> file and also put it under <code>/scripts</code> folder. SO <code>Hexo</code> will load it when start-up.</p>
<p>Well, this approach doesn’t really work. If you try it, it is very likely to get the exactly same error as before. The reason is related to <code>Hexo</code> implementation. <code>Hexo</code> uses <a href="https://github.com/hexojs/hexo/blob/master/lib/loaders/scripts.js" target="_blank" rel="external">Scripts Loader</a> to require files under <code>/scripts</code>. The loader doesn’t really provide an explicit way to specify which file is loaded before another. So the registration file is guaranteed to be loaded before any <code>.coffee</code>.</p>
<p>So far, it seems that there is no cure to this problem! But actually it does. There is undocumented feature will help to solve this issue.</p>
<p>Hexo uses [Script Loader] to load the scripts. In <a href="https://github.com/hexojs/hexo/blob/master/lib/loaders/scripts.js" target="_blank" rel="external">Scripts Loader</a> use <a href="https://github.com/hexojs/hexo/blob/master/lib/util/file2.js#L313" target="_blank" rel="external">hexo.util.file2</a> to populate the source files under <code>/scripts</code>. And <a href="https://github.com/hexojs/hexo/blob/master/lib/util/file2.js#L313" target="_blank" rel="external">hexo.util.file2</a> use <a href="http://nodejs.org/api/fs.html#fs_fs_readdir_path_callback" target="_blank" rel="external">fs.readdir</a> to actully populate the file system entries. For <a href="http://nodejs.org/api/fs.html#fs_fs_readdir_path_callback" target="_blank" rel="external">fs.readdir</a>, there is a undocumented feature, that the populated entries are actually sorted alphabetically, which means <code>a.js</code> is loaded before <code>b.coffee</code>.</p>
<p>With this feature, we can put our <code>coffee-script</code> registration in a file with lower alphabetic-order name. Personally, I’d like called <code>___register_coffeescript.js</code>, since <code>_</code> is smaller than any letter or number.</p>
<p>⚠️<strong>WARNING</strong>: <a href="http://nodejs.org/api/fs.html#fs_fs_readdir_path_callback" target="_blank" rel="external">fs.readdir</a> yielding sorted files is an undocumented behavior, which means it is not guaranteed either to work across platforms or not get changed in the future. So for, it works on Mac, and I expect it behaves similar on Linux. But not sure about Windows, since <code>fs</code> uses a different native binding on Windows.</p>
<p><a href="http://hexo.io/" target="_blank" rel="external">Hexo</a> has a <code>scripts</code> folder, and the files under which are loaded
New Favicon design for my bloghttp://timnew.me/blog/2014/08/18/new-favicon-design-for-my-blog/2014-08-17T16:18:04.000Z2016-03-25T13:04:24.000Z<p>To ㊗️ my wife passed driver license theory course, I created a new log for my blog 😝</p>
<p>Here is what I got:</p>
<img src="/blog/2014/08/18/new-favicon-design-for-my-blog/logo.png" alt="Logo for ThoughtWorkshop" title="Logo for ThoughtWorkshop">
<h2 id="Gear"><a href="#Gear" class="headerlink" title="Gear"></a>Gear</h2><p><code>Gear</code> is the hint of workshop. Because this blog is named as <code>TimNew's ThoughtWorkshop</code></p>
<p>In the beginning, I was intend to create the gear in <a href="https://www.google.com/search?q=steampunk%20gear&tbm=isch" target="_blank" rel="external">Steampunk style</a>. I like such old-fashioned style, but later I found such style is not distinguishable in small icon, so I simplified it to the dark-metel gear.</p>
<h2 id="D"><a href="#D" class="headerlink" title="D"></a>D</h2><p>Letter <code>D</code> is from the pronunciation of my Chinese name, which might not be well-known. It is a personal logo, so I wish to have something personal in it.</p>
<p>The font is <code>Gear Box</code> from <a href="http://moorstation.org/typoasis/designers/gaut/index.htm" target="_blank" rel="external">Gaut Fonts</a>.</p>
<p>It is an awesome font to create some mechanical feel design.</p>
<img src="/blog/2014/08/18/new-favicon-design-for-my-blog/gearbox.jpg" alt="Gear Box Logo" title="Gear Box Logo">
<p>The rainbow color is the hint of unrestrained idea and inspiration. In Chinese, it reads 天 🌌 马 🐎 行 ✈️ 空 🚀 不 🚫 靠 🎵 谱.</p>
<p>Well, this is it.</p>
<p>To ㊗️ my wife passed driver license theory course, I created a new log for my blog 😝</p>
<p>Here is what I got:</p>
<img src="/blog/2014
Favicon is not as simple as you thinkhttp://timnew.me/blog/2014/08/18/favicon-is-not-as-simple-as-you-think/2014-08-17T16:04:36.000Z2014-08-23T10:07:47.000Z<p><code>Favicon</code> is the little icon that displayed on the title bar or tab bar when you browsing a web site. At very beginning, it is used to be the little icon displayed in favoriate bar when user add the website to favorites. Then later, it becomes the the standard way to specify custom icon for a website.</p>
<p>Most web site provides <code>favico</code>, developer add one line description in the <code><head></code>:</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="tag"><<span class="name">link</span> <span class="attr">rel</span>=<span class="string">"shortcut icon"</span> <span class="attr">href</span>=<span class="string">"/favico.ico"</span> <span class="attr">type</span>=<span class="string">"image/x-icon"</span>></span></div></pre></td></tr></table></figure>
<p>This simple piece of code works, but there are a lot of issues with this declaration. Actually specify the <code>favico</code> isn’t as simple as you might expect!</p>
<p>For this piece of code, according to W3C document <a href="http://www.w3.org/2005/10/howto-favicon" target="_blank" rel="external">how to favicon</a>, there are 2 issues with it:</p>
<p>First, <code>shortcut</code> isn’t a standard value for <code>rel</code>, it is only for <code>IE</code>.</p>
<p>Second, <code>ico</code> format is a Microsoft oriented file type, not all platform likes it. Linux, Mac, iOS, Android, do not really appreciate this format.</p>
<p>Beides the 2 issues described above, the size of the <code>favicon</code> also matters.</p>
<p>Someone says it should be <code>16x16</code>. Yes, <code>16x16</code> icon is used in tab or tree view. Some other says it should be <code>32x32</code>. Well, this is also true. <code>32x32</code> icon is displayed in toolbar.</p>
<p><code>16x16</code> and <code>32x32</code> are the most used sizes for <code>favico</code>, but that’s not all. The reality is a lot complicated, I’ll explain this issue later. Let focus on this 2 size first.</p>
<p>To provide the image with 2 different sizes. For <code>ico</code> it is not an issue, since <code>ico</code> is a image container file format, which can encapsulate several images with different sizes and color in a single file. It is convenient for developer, but not for users. Because it means the users need to download a big file, most of the data in which is not used at all.</p>
<p>For the recommended <code>png</code>, it is no way to provide multiple images in a single file. So we have to provide 2 different separate files, and specify them with 2 different <code><link></code> tags with <code>sizes</code> attribute. This is a more efficient way, but unfortunately, you’re living in the world has something called <code>Internet Explorer</code>. The <code>favico</code> in <code>png</code> is not supported by IE until <code>IE 11</code>. What a hell!</p>
<p>Actually, there is a lot of issue with IE in this case. There is an <a href="https://mathiasbynens.be/notes/rel-shortcut-icon" target="_blank" rel="external">great article</a> by Mathias Bynen that discussed this issue in detail, which provides a lot of interesting information related to <code>favico</code>.</p>
<h3 id="Microsoft-Windows-8"><a href="#Microsoft-Windows-8" class="headerlink" title="Microsoft Windows 8"></a>Microsoft Windows 8</h3><p>Besides typical browser usage, <code>Favicon</code> is also used to create <code>Metro Tile</code> by <code>IE 10</code> and <code>IE 11</code> on Windows 8. It requires something quite different. Here is a MSDN document that described how to <a href="http://msdn.microsoft.com/en-us/library/ie/dn455106(v=vs.85).aspx" target="_blank" rel="external">create custom tiles for IE11 websites</a>. For these <code>tile icon</code>, Windows 8 also asks for a background color other than the icon itself.</p>
<h3 id="Android"><a href="#Android" class="headerlink" title="Android"></a>Android</h3><p>In the age of mobile internet, <code>favicon</code> is not just used by the desktop browser, but also mobile devices. On mobile devices, there are some more specific requirements.</p>
<p>On android, the screen size and resolution varies between devices. So the visual elements on Android are measured in <code>dp</code>. According to the screen resolution, there are different conversion ratios between <code>dp</code> and <code>px</code>. And to have pixel perfect image on Android, developer should provide several images for different <code>dp-px-ratios</code>.</p>
<p>Google have a well written document that described how to create icon for the web app that <a href="https://developer.chrome.com/multidevice/android/installtohomescreen" target="_blank" rel="external">added to homescreen</a>.</p>
<h3 id="iOS"><a href="#iOS" class="headerlink" title="iOS"></a>iOS</h3><p>For iOS, it is simliar to Android, but seems to be much more complicated. On iOS, it is also possible to create a shortcut for the web apps. Apple named such icon as <code>apple touch icon</code>, which is used by Safari and other browsers on iOS.</p>
<p>For the iOS devices, iPhone and iPad have different screen sizes, so they have different size requirements for <code>touch icon</code>.</p>
<p>Furthermore, there are device with <code>retina</code> display and with normal one. To have pixel perfect image on <code>retina display</code>, it requires the resolution of the image to be doubled.</p>
<p>And since iOS 7, iOS changed its UI style, the icon size used by iOS 7 is also slightly changed. So you should provide new icons for iOS 7 devices!</p>
<p>To make the icon fit iOS visual style best, Apple recommend web application to provide <code>precomposed icon</code>, which is a icon that added <code>rounded corner</code> and background by itself.</p>
<p>To have the pixel perfect icon on iOS, you might need to provide around 10 different images files as <code>apple touch icon</code>.</p>
<p>What a hell!!!! The <code>touch icon</code> on iOS is totally a mess!!!!</p>
<p>Here is a document from Apple that describes how <a href="https://developer.apple.com/library/ios/documentation/AppleApplications/Reference/SafariWebContent/ConfiguringWebApplications/ConfiguringWebApplications.html" target="_blank" rel="external">configure web application icon</a>.</p>
<h3 id="Other"><a href="#Other" class="headerlink" title="Other"></a>Other</h3><p>Besides all cases that describe above, <code>favicon</code> is also used in some special cases, such as <a href="https://developers.google.com/tv/web/docs/design_for_tv#favicons" target="_blank" rel="external">Google TV</a>, <a href="http://operacoast.com/developer#icon" target="_blank" rel="external">Opera Speed Dial</a>, Chrome Web App. They all requires different size of <code>favico</code>.</p>
<h3 id="Conclusion"><a href="#Conclusion" class="headerlink" title="Conclusion"></a>Conclusion</h3><p>In a short description, <code>favico</code> isn’t as simple as it looks. And it actually used wrongly by most websites.<br>To provide proper <code>favico</code> for all platforms and devices is not a simple work to do.<br>Here is the <code>favico</code> declaration that used this blog:</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div></pre></td><td class="code"><pre><div class="line"><span class="tag"><<span class="name">link</span> <span class="attr">rel</span>=<span class="string">"apple-touch-icon"</span> <span class="attr">sizes</span>=<span class="string">"57x57"</span> <span class="attr">href</span>=<span class="string">"/apple-touch-icon-57x57.png"</span>></span></div><div class="line"><span class="tag"><<span class="name">link</span> <span class="attr">rel</span>=<span class="string">"apple-touch-icon"</span> <span class="attr">sizes</span>=<span class="string">"114x114"</span> <span class="attr">href</span>=<span class="string">"/apple-touch-icon-114x114.png"</span>></span></div><div class="line"><span class="tag"><<span class="name">link</span> <span class="attr">rel</span>=<span class="string">"apple-touch-icon"</span> <span class="attr">sizes</span>=<span class="string">"72x72"</span> <span class="attr">href</span>=<span class="string">"/apple-touch-icon-72x72.png"</span>></span></div><div class="line"><span class="tag"><<span class="name">link</span> <span class="attr">rel</span>=<span class="string">"apple-touch-icon"</span> <span class="attr">sizes</span>=<span class="string">"144x144"</span> <span class="attr">href</span>=<span class="string">"/apple-touch-icon-144x144.png"</span>></span></div><div class="line"><span class="tag"><<span class="name">link</span> <span class="attr">rel</span>=<span class="string">"apple-touch-icon"</span> <span class="attr">sizes</span>=<span class="string">"60x60"</span> <span class="attr">href</span>=<span class="string">"/apple-touch-icon-60x60.png"</span>></span></div><div class="line"><span class="tag"><<span class="name">link</span> <span class="attr">rel</span>=<span class="string">"apple-touch-icon"</span> <span class="attr">sizes</span>=<span class="string">"120x120"</span> <span class="attr">href</span>=<span class="string">"/apple-touch-icon-120x120.png"</span>></span></div><div class="line"><span class="tag"><<span class="name">link</span> <span class="attr">rel</span>=<span class="string">"apple-touch-icon"</span> <span class="attr">sizes</span>=<span class="string">"76x76"</span> <span class="attr">href</span>=<span class="string">"/apple-touch-icon-76x76.png"</span>></span></div><div class="line"><span class="tag"><<span class="name">link</span> <span class="attr">rel</span>=<span class="string">"apple-touch-icon"</span> <span class="attr">sizes</span>=<span class="string">"152x152"</span> <span class="attr">href</span>=<span class="string">"/apple-touch-icon-152x152.png"</span>></span></div><div class="line"><span class="tag"><<span class="name">link</span> <span class="attr">rel</span>=<span class="string">"icon"</span> <span class="attr">type</span>=<span class="string">"image/png"</span> <span class="attr">href</span>=<span class="string">"/favicon-196x196.png"</span> <span class="attr">sizes</span>=<span class="string">"196x196"</span>></span></div><div class="line"><span class="tag"><<span class="name">link</span> <span class="attr">rel</span>=<span class="string">"icon"</span> <span class="attr">type</span>=<span class="string">"image/png"</span> <span class="attr">href</span>=<span class="string">"/favicon-160x160.png"</span> <span class="attr">sizes</span>=<span class="string">"160x160"</span>></span></div><div class="line"><span class="tag"><<span class="name">link</span> <span class="attr">rel</span>=<span class="string">"icon"</span> <span class="attr">type</span>=<span class="string">"image/png"</span> <span class="attr">href</span>=<span class="string">"/favicon-96x96.png"</span> <span class="attr">sizes</span>=<span class="string">"96x96"</span>></span></div><div class="line"><span class="tag"><<span class="name">link</span> <span class="attr">rel</span>=<span class="string">"icon"</span> <span class="attr">type</span>=<span class="string">"image/png"</span> <span class="attr">href</span>=<span class="string">"/favicon-16x16.png"</span> <span class="attr">sizes</span>=<span class="string">"16x16"</span>></span></div><div class="line"><span class="tag"><<span class="name">link</span> <span class="attr">rel</span>=<span class="string">"icon"</span> <span class="attr">type</span>=<span class="string">"image/png"</span> <span class="attr">href</span>=<span class="string">"/favicon-32x32.png"</span> <span class="attr">sizes</span>=<span class="string">"32x32"</span>></span></div><div class="line"><span class="tag"><<span class="name">meta</span> <span class="attr">name</span>=<span class="string">"msapplication-TileColor"</span> <span class="attr">content</span>=<span class="string">"#00a300"</span>></span></div><div class="line"><span class="tag"><<span class="name">meta</span> <span class="attr">name</span>=<span class="string">"msapplication-TileImage"</span> <span class="attr">content</span>=<span class="string">"/mstile-144x144.png"</span>></span></div></pre></td></tr></table></figure>
<p>And these files are served on this blog as <code>favico</code>:</p>
<figure class="highlight lsl"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div></pre></td><td class="code"><pre><div class="line">favicon.ico</div><div class="line"></div><div class="line">favicon<span class="number">-16</span>x16.png</div><div class="line">favicon<span class="number">-32</span>x32.png</div><div class="line">favicon<span class="number">-96</span>x96.png</div><div class="line">favicon<span class="number">-160</span>x160.png</div><div class="line">favicon<span class="number">-196</span>x196.png</div><div class="line"></div><div class="line">apple-<span class="section">touch</span>-icon.png</div><div class="line">apple-<span class="section">touch</span>-icon-precomposed.png</div><div class="line">apple-<span class="section">touch</span>-icon<span class="number">-57</span>x57.png</div><div class="line">apple-<span class="section">touch</span>-icon<span class="number">-60</span>x60.png</div><div class="line">apple-<span class="section">touch</span>-icon<span class="number">-72</span>x72.png</div><div class="line">apple-<span class="section">touch</span>-icon<span class="number">-76</span>x76.png</div><div class="line">apple-<span class="section">touch</span>-icon<span class="number">-114</span>x114.png</div><div class="line">apple-<span class="section">touch</span>-icon<span class="number">-120</span>x120.png</div><div class="line">apple-<span class="section">touch</span>-icon<span class="number">-144</span>x144.png</div><div class="line">apple-<span class="section">touch</span>-icon<span class="number">-152</span>x152.png</div><div class="line"></div><div class="line">browserconfig.xml</div><div class="line">mstile<span class="number">-70</span>x70.png</div><div class="line">mstile<span class="number">-144</span>x144.png</div><div class="line">mstile<span class="number">-150</span>x150.png</div><div class="line">mstile<span class="number">-310</span>x150.png</div><div class="line">mstile<span class="number">-310</span>x310.png</div></pre></td></tr></table></figure>
<p>As you can see, to prepare all these configurations and files is not an easy job to do. It really consumes you a lot effort.</p>
<p>Fortunately, we have the awesome <a href="http://realfavicongenerator.net/" target="_blank" rel="external">Real Favicon Generator</a> brought by <a href="https://github.com/phbernard/" target="_blank" rel="external">Philippe Bernard</a>, which will save your tons of time to have the proper fav icon configuration.</p>
<p><code>Real Favicon Generator</code> also comes with a <a href="http://realfavicongenerator.net/favicon_checker" target="_blank" rel="external">favicon checker</a>, which check the favorite configuration for your website, and generates <a href="http://realfavicongenerator.net/favicon_checker?site=timnew.github.io" target="_blank" rel="external">beautiful report</a>.</p>
<p>At last the <a href="http://realfavicongenerator.net/faq" target="_blank" rel="external">FAQ</a> of the site also provides a good explanation of the issue described above in details. Hope it helps.</p>
<p><code>Favicon</code> is the little icon that displayed on the title bar or tab bar when you browsing a web site. At very beginning, it is
Embed CodePen snippet in Hexohttp://timnew.me/blog/2014/08/17/embed-codepen-snippet-in-hexo/2014-08-17T04:49:50.000Z2016-04-13T16:30:31.000Z<p><a href="http://codepen.io/" target="_blank" rel="external">CodePen</a> is a service that provide <code>Html</code>, <code>JavaScript</code> and <code>Css</code> live show-case. It is another clone of <a href="http://jsfiddle.net/" target="_blank" rel="external">Js Fiddle</a>, but with cooler UI and support.</p>
<p>Both <code>CodePen</code> and <code>Js Fiddle</code> provides embedded widget that allow user to embedded their code into blog or articles.</p>
<p>Here is the example, code from <code>CodePen</code>:</p>
<iframe id="cp_embed_cGEqB" src="//codepen.io/timnew/embed/cGEqB?height=257&theme-id=7928&slug-hash=cGEqB&default-tab=result" scrolling="no" frameborder="no" height="257" allowtransparency="true" allowfullscreen="true" class="cp_embed_iframe" style="width: 100%; overflow: hidden;"></iframe>
<p>This is from <code>Js Fiddle</code>:</p>
<iframe scrolling="no" width="100%" height="300" src="http://jsfiddle.net/timnew/r3j6a92c/4/embedded/result,css,html,js/light" frameborder="0" allowfullscreen></iframe>
<p><a href="http://hexo.io/" target="_blank" rel="external">Hexo</a> has built-in the <a href="http://hexo.io/docs/tag-plugins.html#jsFiddle" target="_blank" rel="external">Js Fiddle Plug-in</a> to allow writer to embed code from <code>Js Fiddle</code>, which is probably ported from <code>Octopress</code>.<br>But for <code>CodePen</code>, there is not such thing.</p>
<p>So I created <a href="https://github.com/timnew/hexo-tag-codepen" target="_blank" rel="external">hexo-tag-codepen</a>, its provides similar syntax as built-in ‘Js Fiddle’ plug in:</p>
<figure class="highlight clojure"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">{% codepen userId|anonymous|anon slugHash theme [defaultTab [height [width]]] %}</div></pre></td></tr></table></figure>
<p>Now you can embedded <code>Pens</code> from <code>CodePen</code> in your <code>Hexo</code> blog. Enjoy.</p>
<p>For detail, check out <a href="https://github.com/timnew/hexo-tag-codepen" target="_blank" rel="external">hexo-tag-codepen</a> document.</p>
<p><a href="http://codepen.io/" target="_blank" rel="external">CodePen</a> is a service that provide <code>Html</code>, <code>JavaScript</co
Complex Value Array in Stylushttp://timnew.me/blog/2014/08/16/complex-value-array-in-stylus/2014-08-16T15:32:38.000Z2014-08-23T10:07:47.000Z<p><a href="http://learnboost.github.io/stylus/" target="_blank" rel="external">Stylus</a> is an awesome CSS pre-processor, which provides much more concise syntax and more powerful feature than its competitors, such as <a href="http://lesscss.org/" target="_blank" rel="external">LESS</a> or <a href="http://sass-lang.com/" target="_blank" rel="external">SCSS</a>.</p>
<p>But now, with more and more features added into <code>Stylus</code>, it seems its syntax become over-weighted. Pitfall come up.</p>
<p>I wish to declare an array of values for <code>box-shadow</code> property. And I can reference them with index:</p>
<figure class="highlight stylus"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div></pre></td><td class="code"><pre><div class="line">drop-shadows = [</div><div class="line"> <span class="number">0</span> <span class="number">2px</span> <span class="number">10px</span> <span class="number">0</span> rgba(<span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0.16</span>),</div><div class="line"> <span class="number">0</span> <span class="number">6px</span> <span class="number">20px</span> <span class="number">0</span> rgba(<span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0.19</span>),</div><div class="line"> <span class="number">0</span> <span class="number">17px</span> <span class="number">50px</span> <span class="number">0</span> rgba(<span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0.19</span>),</div><div class="line"> <span class="number">0</span> <span class="number">25px</span> <span class="number">55px</span> <span class="number">0</span> rgba(<span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0.21</span>),</div><div class="line"> <span class="number">0</span> <span class="number">40px</span> <span class="number">77px</span> <span class="number">0</span> rgba(<span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0.22</span>)</div><div class="line">]</div><div class="line"></div><div class="line"><span class="function"><span class="title">drop-shadow</span><span class="params">(n)</span></span></div><div class="line"> <span class="attribute">box-shadow</span> shadows[n]</div><div class="line"></div><div class="line"><span class="keyword">for</span> <span class="selector-tag">i</span> <span class="keyword">in</span> (<span class="number">1</span>..<span class="number">5</span>) </div><div class="line"> .drop-shadow-{i}</div><div class="line"> drop-shadow(i)</div></pre></td></tr></table></figure>
<p>And expect it generates</p>
<figure class="highlight css"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div></pre></td><td class="code"><pre><div class="line"><span class="selector-class">.drop-shadow-1</span> {</div><div class="line"> <span class="attribute">box-shadow</span>: <span class="number">0</span> <span class="number">2px</span> <span class="number">10px</span> <span class="number">0</span> <span class="built_in">rgba</span>(0, 0, 0, 0.16);</div><div class="line">} </div><div class="line"><span class="selector-class">.drop-shadow-2</span> {</div><div class="line"> <span class="attribute">box-shadow</span>: <span class="number">0</span> <span class="number">6px</span> <span class="number">20px</span> <span class="number">0</span> <span class="built_in">rgba</span>(0, 0, 0, 0.19);</div><div class="line">} </div><div class="line"><span class="selector-class">.drop-shadow-3</span> {</div><div class="line"> <span class="attribute">box-shadow</span>: <span class="number">0</span> <span class="number">17px</span> <span class="number">50px</span> <span class="number">0</span> <span class="built_in">rgba</span>(0, 0, 0, 0.19);</div><div class="line">} </div><div class="line"><span class="selector-class">.drop-shadow-4</span> {</div><div class="line"> <span class="attribute">box-shadow</span>: <span class="number">0</span> <span class="number">25px</span> <span class="number">55px</span> <span class="number">0</span> <span class="built_in">rgba</span>(0, 0, 0, 0.21);</div><div class="line">} </div><div class="line"><span class="selector-class">.drop-shadow-5</span> {</div><div class="line"> <span class="attribute">box-shadow</span>: <span class="number">0</span> <span class="number">40px</span> <span class="number">77px</span> <span class="number">0</span> <span class="built_in">rgba</span>(0, 0, 0, 0.22;</div><div class="line">}</div></pre></td></tr></table></figure>
<p><del>But I found there is not such thing called <code>Array</code> in <code>Stylus</code>!!!!<del><br>There is only <code>Hash</code>, and Hash doesn’t accept number as key!<br>So finally, I come up something like this:</del></del></p>
<figure class="highlight stylus"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div></pre></td><td class="code"><pre><div class="line">drop-shadows = {</div><div class="line"> <span class="string">'1'</span>: <span class="number">0</span> <span class="number">2px</span> <span class="number">10px</span> <span class="number">0</span> rgba(<span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0.16</span>),</div><div class="line"> <span class="string">'2'</span>: <span class="number">0</span> <span class="number">6px</span> <span class="number">20px</span> <span class="number">0</span> rgba(<span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0.19</span>),</div><div class="line"> <span class="string">'3'</span>: <span class="number">0</span> <span class="number">17px</span> <span class="number">50px</span> <span class="number">0</span> rgba(<span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0.19</span>),</div><div class="line"> <span class="string">'4'</span>: <span class="number">0</span> <span class="number">25px</span> <span class="number">55px</span> <span class="number">0</span> rgba(<span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0.21</span>),</div><div class="line"> <span class="string">'5'</span>: <span class="number">0</span> <span class="number">40px</span> <span class="number">77px</span> <span class="number">0</span> rgba(<span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0.22</span>)</div><div class="line">}</div><div class="line"></div><div class="line"><span class="function"><span class="title">drop-shadow</span><span class="params">(n)</span></span></div><div class="line"> <span class="attribute">box-shadow</span> shadows[n+<span class="string">''</span>]</div><div class="line"></div><div class="line"><span class="keyword">for</span> <span class="selector-tag">i</span> <span class="keyword">in</span> (<span class="number">1</span>..<span class="number">5</span>) </div><div class="line"> .drop-shadow-{i}</div><div class="line"> drop-shadow(i)</div></pre></td></tr></table></figure>
<p>In this piece of code, there are a bunch of pitfalls:</p>
<ol>
<li>Hash doesn’t accept number as key. So <code>1: 0 2px 10px 0 rgba(0, 0, 0, 0.16)</code> cause compile error.</li>
<li><code>'1' != 1</code>, so <code>drop-shadows[1]</code> returns <code>null</code></li>
<li>There is no type conversion function in <code>Stylus</code>, use the same trick as <code>JavaScript</code>. <code>''+n</code> convert <code>n</code> into <code>string</code>.</li>
</ol>
<hr>
<p>Just found <code>Stylus</code> provides something called <code>List</code>, which is pretty much similar to what array in other languages, except the syntax.</p>
<figure class="highlight stylus"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div></pre></td><td class="code"><pre><div class="line">drop-shadows = <span class="number">0</span> <span class="number">2px</span> <span class="number">10px</span> <span class="number">0</span> rgba(<span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0.16</span>),</div><div class="line"> <span class="number">0</span> <span class="number">6px</span> <span class="number">20px</span> <span class="number">0</span> rgba(<span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0.19</span>),</div><div class="line"> <span class="number">0</span> <span class="number">17px</span> <span class="number">50px</span> <span class="number">0</span> rgba(<span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0.19</span>),</div><div class="line"> <span class="number">0</span> <span class="number">25px</span> <span class="number">55px</span> <span class="number">0</span> rgba(<span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0.21</span>),</div><div class="line"> <span class="number">0</span> <span class="number">40px</span> <span class="number">77px</span> <span class="number">0</span> rgba(<span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0.22</span>)</div><div class="line"></div><div class="line"></div><div class="line"><span class="function"><span class="title">drop-shadow</span><span class="params">(n)</span></span></div><div class="line"> <span class="attribute">box-shadow</span> shadows[n]</div><div class="line"></div><div class="line"><span class="keyword">for</span> <span class="selector-tag">i</span> <span class="keyword">in</span> (<span class="number">1</span>..<span class="number">5</span>) </div><div class="line"> .drop-shadow-{i}</div><div class="line"> drop-shadow(i)</div></pre></td></tr></table></figure>
<p>So no brackets or parentesis needed.</p>
<p><a href="http://learnboost.github.io/stylus/" target="_blank" rel="external">Stylus</a> is an awesome CSS pre-processor, which provides m
Material Design Shadow in HTMLhttp://timnew.me/blog/2014/08/16/material-design-shadow-in-html/2014-08-16T09:45:05.000Z2016-07-27T05:28:21.000Z<p>Working on <code>Hexo</code> theme customization in past few days. And wish to borrow some concepts from Google’s <a href="http://www.google.com/design/spec/material-design/introduction.html" target="_blank" rel="external">Material Design</a>.</p>
<p>The concept that I’m interested most in <code>Material Design</code> is the <a href="http://www.google.com/design/spec/layout/layout-principles.html#layout-principles-dimensionality" target="_blank" rel="external">Dimensionality</a>. It identify visual area on the page with <code>Shadow</code>.<br>By defining multiple shadow configuration, it creates layers in a 2-D space! Simple and efficient. What a graceful solution!</p>
<p>By referencing the <a href="http://www.google.com/design/spec/layout/layout-principles.html#dimensionality-%20Shadows-1" target="_blank" rel="external">Shadow Definition</a> in the spec, I recreate the effect with plain CSS.</p>
<p>Clicking the div will shift the shadow depth.</p>
<iframe scrolling="no" width="100%" height="300" src="http://jsfiddle.net/timnew/r3j6a92c/16/embedded/result,css,html,js/light" frameborder="0" allowfullscreen></iframe>
<hr>
<h3 id="Mobile-Support"><a href="#Mobile-Support" class="headerlink" title="Mobile Support"></a>Mobile Support</h3><p>Test it on Mobile, and found the top-shadow is not displayed properly. The reason is that I used <code>multiple-shadow</code> to apply <code>Top Shadow</code> and <code>Bottom Shadow</code> to the same div. But according to <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/box-shadow" target="_blank" rel="external">Box-Shadow MDN Document</a>, <code>Multiple shadows</code> is only supported by iOS Safari with <code>-webkit-</code> prefix. So it doesn’t work properly.</p>
<hr>
<h3 id="Polymer-and-Angular-Js-official-implementations"><a href="#Polymer-and-Angular-Js-official-implementations" class="headerlink" title="Polymer and Angular-Js official implementations"></a>Polymer and Angular-Js official implementations</h3><p>Before recreate it, I also checked the <a href="http://www.polymer-project.org/components/paper-elements/demo.html" target="_blank" rel="external">Polymer</a> and <a href="https://material.angularjs.org/" target="_blank" rel="external">Angular JS</a>, and the result is disappointing. <code>Ploymer</code> version has better quality than <code>Angular Js</code> version, <code>Angular JS</code> one is still very buggy.</p>
<p>Even they’re functioning, either <code>Polymer</code> or <code>Angular-JS</code> is too intrusive or too heavy for simple page to use, such as blog. If you don’t really need these transition animations, to implement these basic effects, CSS3 should be enough.</p>
<p>Working on <code>Hexo</code> theme customization in past few days. And wish to borrow some concepts from Google’s <a href="http://www.goo
Atom Editor Background Imagehttp://timnew.me/blog/2014/08/14/atom-editor-background-image/2014-08-14T15:41:31.000Z2014-08-23T10:07:47.000Z<p>Today spent some time to customize <a href="https://atom.io/" target="_blank" rel="external">Atom</a> user stylesheet to display the background image for editor.<br>Background image is a feature that I expected so much in either <code>TextMate</code> or <code>Sublime</code>.<br>Now finally I have it in <code>Atom</code>.</p>
<p>Finding the class for each html component is a little bit tricky<br>My theme is <a href="https://github.com/jesseweed/seti-ui" target="_blank" rel="external">seti-ui</a>.</p>
<h2 id="Stylesheet-to-display-background-image"><a href="#Stylesheet-to-display-background-image" class="headerlink" title="Stylesheet to display background image"></a>Stylesheet to display background image</h2><figure class="highlight less"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div></pre></td><td class="code"><pre><div class="line"><span class="comment">//.react is needed to avoid impact on mini-editor</span></div><div class="line"><span class="selector-class">.editor</span><span class="selector-class">.react</span> {</div><div class="line"> <span class="comment">// Fix the color strip between gutter and the editing area.</span></div><div class="line"> <span class="attribute">background</span>: <span class="number">#0e1112</span>;</div><div class="line"></div><div class="line"> <span class="selector-class">.scroll-view</span> {</div><div class="line"> <span class="comment">// Align the Background Image with Editing Area</span></div><div class="line"> <span class="attribute">padding-left</span>: <span class="number">0</span>;</div><div class="line"> <span class="attribute">margin-left</span>: <span class="number">10px</span>;</div><div class="line"></div><div class="line"> <span class="comment">// I put the background image under ~/.atom/images</span></div><div class="line"> <span class="attribute">background</span>: url(<span class="string">'/Users/timnew/.atom/images/batou.jpg'</span>) no-repeat fixed;</div><div class="line"></div><div class="line"> <span class="comment">// Stretch the image</span></div><div class="line"> <span class="comment">// I tried to set it in with other background properties,</span></div><div class="line"> <span class="comment">// but it doesn't work. Looks like a bug in Chrome.</span></div><div class="line"> <span class="attribute">background-size</span>: cover;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="selector-class">.cursor-line</span> {</div><div class="line"> <span class="comment">// Set cursor-line semi-transparent to make background visible.</span></div><div class="line"> <span class="comment">// Adjust the alpha value to fit your taste.</span></div><div class="line"> <span class="attribute">background</span>: rgba(<span class="number">90</span>,<span class="number">90</span>,<span class="number">90</span>,.<span class="number">4</span>) <span class="meta">!important</span>;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="selector-class">.overlayer</span> {</div><div class="line"> <span class="comment">// Set overlayer semi-transparent to make background visible.</span></div><div class="line"> <span class="comment">// Adjust the alpha value to fit your taste.</span></div><div class="line"> <span class="attribute">background-color</span>: rgba(<span class="number">21</span>, <span class="number">23</span>, <span class="number">24</span>, .<span class="number">7</span>) <span class="meta">!important</span>;</div><div class="line"> }</div><div class="line">}</div></pre></td></tr></table></figure>
<h2 id="Screenshots"><a href="#Screenshots" class="headerlink" title="Screenshots"></a>Screenshots</h2><h3 id="Without-TreeView"><a href="#Without-TreeView" class="headerlink" title="Without TreeView"></a>Without TreeView</h3><img src="/blog/2014/08/14/atom-editor-background-image/no_treeview.png" alt="Without Tree View" title="Without Tree View">
<h2 id="With-TreeView"><a href="#With-TreeView" class="headerlink" title="With TreeView"></a>With TreeView</h2><img src="/blog/2014/08/14/atom-editor-background-image/treeview.png" alt="With Tree View" title="With Tree View">
<p>Today spent some time to customize <a href="https://atom.io/" target="_blank" rel="external">Atom</a> user stylesheet to display the back
Atom Editorhttp://timnew.me/blog/2014/08/14/atom-editor/2014-08-14T11:00:01.000Z2016-03-25T13:00:49.000Z<p><a href="https://atom.io/" target="_blank" rel="external">Atom</a> is general purpose text editor brought to us by GitHub guys, which is empowered by the loved <code>Node.js</code> and <code>Chrome</code>.</p>
<p>Someone said <code>Atom</code> is just another clone of <a href="http://www.sublimetext.com/" target="_blank" rel="external">Sublime</a>. Well, I don’t quite agree with the saying. I’d like to say <code>Atom</code> learnt a lot from <code>Sublime</code>.<br>And I’d like to explain why.</p>
<p>I think <code>Sublime</code> itself is a great text editor, powerful to use, easy to learn, ready to be hacked, matured community, tons of plug-ins… almost unlimited possibilities…</p>
<p>But on the other hand, I think, <code>Sublime</code> is too sticky to “Text”. Yes, it is a text editor, but it doesn’t mean everything in the editor could only be text-based.<br>Implementing custom UI in <code>Sublime</code> isn’t a easy job to do. Benefits from HTML based technologies, <code>Atom</code> has a lot more rich features, CSS3 effects, CSS3 Animations, SVG, and a lot more…</p>
<p>Along with <a href="http://brackets.io/" target="_blank" rel="external">Brackets</a>, <a href="https://c9.io/" target="_blank" rel="external">C9</a>, <code>Atom</code> is the important candidates of next-gen editors. But among them, only <code>Atom</code> is a general purpose editor.</p>
<p>Since <code>Atom</code> is still in the eary stage, there are a number of flaws and issues in it. Besides these bugs, the biggest problem of <code>Atom</code> is performance.<br>Loading a several MB text file or thousands pages document will kill the editor in no time. <ins>(<code>Atom</code> blocks user to load file larger than <code>2MB</code>.)</ins></p>
<p>But still, these issues won’t block me from loving it. As a <code>node.js</code> and <code>Ruby</code> developer, it is an awesome companion to my work. ❤️</p>
<p><a href="https://atom.io/" target="_blank" rel="external">Atom</a> is general purpose text editor brought to us by GitHub guys, which is
Migrate Blog to Hexohttp://timnew.me/blog/2014/08/12/migrate-blog-to-hexo/2014-08-12T14:59:14.000Z2014-08-23T10:07:47.000Z<p>This post is a celebration for the migration from <a href="http://octopress.org/" target="_blank" rel="external">Octopress</a> to <a href="http://hexo.io/" target="_blank" rel="external">Hexo</a></p>
<p><code>Octopress</code> has done an excellent job on filling the gap between <code>jekyll</code> and full function repo based blog engine. But because of the tech stack it is based on. It isn’t really a awesome framework to use.</p>
<p>The first time I got pissed off by <code>Octopress</code> was by the end of 2012. Then I come up the idea to rewrite it in <code>Node.js</code>. But I wasn’t able to make it happen, because I was held by the new project assignment, and didn’t have too many spare time on the blog engine.</p>
<p>To save effort, I began to customize <code>Octopress</code> by rewriting some code in <code>Octopress</code> and <code>Jekyll</code>, which started the long march of <code>Octopress</code> customization.</p>
<p>I did a number of customization on <code>Octopress</code>, from erb template to Jekyll generators, from <code>Rake</code> script to TextMate bundles.</p>
<p>Before I switch to Sublime, I uses TextMate for quite long time. So I customized the <code>Rake</code> script and TextMate bundle, which enables me to invoke almost every rake command in TextMate with hotkey. I can even rename the blog post file name according to the title in front-matter without leaving TextMate. Besides the functionality, I also customized the templates and the widgets a lot to get better visual effects and reading experience.</p>
<p>I’ve benefited from these customization a lot. On the other hand, these deep customization blocks me from migrating to <code>Hexo</code>, a better alternative. Even I have found <code>Hexo</code> in the early 2013, and believe it is a better blog platform. But it is really costy for me to migrate the blogs away from the Octopress.</p>
<p>Luckily, after years development, a bunch of tools and libraries came up, which has minimized the gap between <code>Octopress</code> and <code>Hexo</code>.<br>After several days effort, finally retired the <code>Octoress</code> engine, and completed the journey of moving from <code>Octopress</code> to <code>Hexo</code>.</p>
<p>This post is a celebration for the migration from <a href="http://octopress.org/" target="_blank" rel="external">Octopress</a> to <a href
Page renders improperly in IE before developer tool has openedhttp://timnew.me/blog/2014/08/01/page-renders-improperly-in-ie-before-developer-tool-has-opened/2014-08-01T00:00:00.000Z2014-08-23T10:07:47.000Z<p>Today I found a super annoying issue about IE. Our website works perfectly in any browser except IE. The page isn’t rendered properly in IE 9. Well, this is common, this is the nature of IE. The mysterious issue I found is that once you opened or ever opened the developer tool, open the page or refresh the page, the problem is gone magically!!!!</p>
<p>As a conclusion, opening the developer tool changes the browser behavior!!!!! What a hell! So you know there is something wrong, but once you try to figure out the error message, you have to open developer tool. Once you open the developer tool, the bug is gone! <strong>DEAD END!!!</strong></p>
<p>Because I cannot open developer tool, so I have to debug with <code>alert</code>. It is really a horrible experience to me, and feels like inspecting nuclear reaction with a plain optical magnifier or fixing a high-tech spacecraft with stones and clubs.</p>
<p>Since it is client-rich page, a lot of javascript is introduced. So I cannot go through the scripts line by line, instead I have to make an assumption to explain the phenomena spotted, then validate it with experiments, finally correct or extend the assumption according the validation result.</p>
<p>During the process I invalidated a couple of assumptions, some of them are seems very close to the “right answer”, such as “some script is loaded and executed before its dependencies, and developer tool load all the scripts first because it displays all the scripts”.</p>
<p>After spending a couple of hours on it, I put on eye on a line of code that is really out of my expectation: <code>console.warn</code>.</p>
<figure class="highlight javascript"><figcaption><span>Code breaks the page rendering</span></figcaption><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line"></div><div class="line"><span class="built_in">console</span>.warn(<span class="string">'__proto__ is not supported by current browser, fallback to hard-copy approach'</span>);</div><div class="line"></div></pre></td></tr></table></figure>
<p>I displays a warning message to console when a workaround is applied. But a tricky fact about IE 9 is that <code>console</code> isn’t available until developer tool is opened (<a href="http://msdn.microsoft.com/library/ie/bg182326(v=vs.85" target="_blank" rel="external">MSDN reference here</a>))!!!</p>
<p>The fact that console is not available until developer tools is opened really blows my mind away! (Maybe it is because I have little experience work with IE). As a chrome user, I take console as the universal log system for javascript. But in IE, according to the <a href="http://msdn.microsoft.com/library/ie/bg182326(v=vs.85" target="_blank" rel="external">document</a>), the code should check the existence of console every time print a log.</p>
<p>There is another pitfall here, and I saw someone really post it as answer on <a href="http://stackoverflow.com/questions/2656730/internet-explorer-console" target="_blank" rel="external">StackOverflow</a>:</p>
<figure class="highlight javascript"><figcaption><span>Bad polyfill implemntation</span></figcaption><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line"></div><div class="line"><span class="keyword">if</span> (<span class="keyword">typeof</span> <span class="built_in">console</span> == <span class="string">"undefined"</span>) {</div><div class="line"> <span class="keyword">this</span>.console = { log: <span class="function"><span class="keyword">function</span> (<span class="params">msg</span>) </span>{ alert(msg); } };</div><div class="line">}</div><div class="line"></div></pre></td></tr></table></figure>
<p>We usually access <code>console</code> as <code>console.log</code>, feels like <code>console</code> is a global instance to access. But actually console is an member of <code>window</code>, its full name should be <code>window.console</code>. When <code>console</code> exists, we can definitely reference to it via <code>console</code>. But if it doesn’t exist, the statement <code>console</code> cause script error! So the following code doesn’t work:</p>
<figure class="highlight javascript"><figcaption><span>Pitfalls in console existence check</span></figcaption><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div></pre></td><td class="code"><pre><div class="line"></div><div class="line"><span class="keyword">if</span> (<span class="keyword">typeof</span>(<span class="built_in">console</span>) === <span class="string">'undefined'</span>){ <span class="comment">// Break the script execution</span></div><div class="line"> <span class="built_in">console</span>.log(<span class="string">'Never got executed'</span>);</div><div class="line">}</div><div class="line"></div><div class="line"><span class="keyword">if</span> (<span class="built_in">console</span> != <span class="literal">null</span>) { <span class="comment">// Break the script execution</span></div><div class="line"> <span class="built_in">console</span>.log(<span class="string">'Never got executed'</span>);</div><div class="line">}</div><div class="line"></div><div class="line"><span class="keyword">if</span> (<span class="built_in">console</span>) { <span class="comment">// Break the script execution</span></div><div class="line"> <span class="built_in">console</span>.log(<span class="string">'Never got executed'</span>);</div><div class="line">}</div><div class="line"></div><div class="line"><span class="keyword">if</span> (<span class="built_in">window</span>.console) {</div><div class="line"> <span class="built_in">console</span>.log(<span class="string">'this works!'</span>);</div><div class="line">}</div><div class="line"></div></pre></td></tr></table></figure>
<p>To avoid <code>console</code> issue, a ployfill could be very useful. Here is a great implementation available as <code>bower</code> package: <a href="https://github.com/paulmillr/console-polyfill" target="_blank" rel="external">console-polyfill</a></p>
<p>Today I found a super annoying issue about IE. Our website works perfectly in any browser except IE. The page isn’t rendered properly in
JavaScript Prototype Chain Mutatorhttp://timnew.me/blog/2014/07/30/javascript-prototype-chain-mutator/2014-07-30T00:00:00.000Z2014-08-23T10:07:47.000Z<p>In JavaScript world, JSON serialization is widely used. When fetching data from server via Ajax, the data is usually represented in JSON; or loading configuration/data from file in Node.js application, the configuration/data is usually in JSON format.</p>
<p>JSON serialization is powerful and convenient, but there is limitation. For security and other reason, behavior and type information are forbidden in JSON. Functions members are removed when stringify a JavaScript object, also functions are not allowed in JSON.</p>
<p>Comparing Yaml to Ruby, this limitation isn’t that convenient when writing JavaScript application. For example, to consume the JSON data fetched via ajax from server, I really wish I can invoke some method on the deserialized model.</p>
<p>Here is simple example:</p>
<figure class="highlight coffeescript"><figcaption><span>Ideal World</span></figcaption><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div></pre></td><td class="code"><pre><div class="line"></div><div class="line"><span class="class"><span class="keyword">class</span> <span class="title">Rect</span></span></div><div class="line"> constructor: <span class="function"><span class="params">(width, height)</span> -></span></div><div class="line"> @width = width <span class="keyword">if</span> width?</div><div class="line"> @height = height <span class="keyword">if</span> height?</div><div class="line"></div><div class="line"> area: <span class="function">-></span></div><div class="line"> @width * @height</div><div class="line"></div><div class="line">$.get <span class="string">'/rect/latest'</span>, <span class="function"><span class="params">(rectJSON)</span> -></span> </div><div class="line"> rect = JSON.parse(rectJSON)</div><div class="line"> <span class="built_in">console</span>.log rect.area() <span class="comment"># This code doesn't work because there is rect is a plain object</span></div><div class="line"></div></pre></td></tr></table></figure>
<p>The code doesn’t work, because <code>rect</code> in a plain object, which doesn’t contains any behavior. Someone called the rect <code>DTO</code>, Data Transfer Object, or POJO, Plain Old Java Object, a concept borrowed from Java world. Here we call it <code>DTO</code>.</p>
<p>To add behaviors to <code>DTO</code>, there are variant approaches. Such as create a behavior wrapper around the <code>DTO</code>, or create a new model with behavior and copy all the data from <code>DTO</code> to model. These practices are borrowed from Java world, or traditional Object Oriented world.</p>
<p>In fact, in JavaScript, there could be a better and smarter way to achieve that: <code>Object Mutation</code>, altering object prototype chain on the fly to convert a object into the instance of a specific type. The process is really similar to biologic genetic mutation, converting a species into another by altering the gene, so I borrow the term <code>mutation</code>.</p>
<p>With the idea, we can achieve this:</p>
<figure class="highlight coffeescript"><figcaption><span>Mutate rect with Mutator</span></figcaption><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div></pre></td><td class="code"><pre><div class="line"></div><div class="line"><span class="class"><span class="keyword">class</span> <span class="title">Rect</span></span></div><div class="line"> constructor: <span class="function"><span class="params">(width, height)</span> -></span></div><div class="line"> @width = width <span class="keyword">if</span> width?</div><div class="line"> @height = height <span class="keyword">if</span> height?</div><div class="line"></div><div class="line"> area: <span class="function">-></span></div><div class="line"> @width * @height</div><div class="line"></div><div class="line">$.get <span class="string">'/rect/latest'</span>, <span class="function"><span class="params">(rectJSON)</span> -></span> </div><div class="line"> rect = JSON.parse(rectJSON)</div><div class="line"></div><div class="line"> mutate(rect, Rect)</div><div class="line"></div><div class="line"> <span class="built_in">console</span>.log rect.area()</div><div class="line"></div></pre></td></tr></table></figure>
<p>The key to implement <code>mutate</code> function is to simulate <code>new</code> operator behavior, alerting <code>object.__proto__</code> and apply <code>constructor</code> to the instance! For more detail, check out the library <a href="https://github.com/timnew/mutator" target="_blank" rel="external">mutator</a> <a href="https://github.com/timnew/mutator" target="_blank" rel="external"><img src="https://badge.fury.io/bo/widget.coffee.svg" alt="Bower version"></a> <a href="https://www.npmjs.org/package/mutator" target="_blank" rel="external"><img src="http://img.shields.io/npm/v/mutator.svg" alt="NPM version"></a>, which is available as both <code>NPM</code> package and <code>bower</code> package.</p>
<p>When implementing the <code>mutator</code>, in IE, again, in the evil IE, the idea doesn’t work. Before IE 11, JavaScript prototype chain for instance is not accessible. There is nothing equivalent to <code>object.__proto__</code> in IE 10 and prior. The most similar workaround is doing a hard-copy of all the members, but it still fails in type check and some dynamical usage.</p>
<p><strong>Background</strong></p>
<blockquote>
<p><code>object.__proto__</code> is a Mozilla “private” implementation until EcmaScript 6.<br>It is interesting that most JavaScript support it except IE.<br>Luckily, IE 11 introduced some features in EcmaScript 6, <code>object.__proto__</code> is one of them.</p>
</blockquote>
<p>In JavaScript world, JSON serialization is widely used. When fetching data from server via Ajax, the data is usually represented in JSON;
converting between HTML 5 data-attribute style hyphen name and javascript camcel-case namehttp://timnew.me/blog/2014/07/29/converting-between-html-5-data-attribute-style-hyphen-name-and-javascript-camcel-case-name/2014-07-29T00:00:00.000Z2014-08-23T10:07:47.000Z<p>I found a bug in <a href="http://bower.io/search/?q=widget.coffee" target="_blank" rel="external">widget.coffee</a> today. To fix the issue, I need the conversion between HTML 5 <code>data-attribute</code> name and javascript function name, e.g. conversion between <code>data-action-handler</code> and <code>actionHandler</code>.</p>
<p>By taking jQuery implementation as reference, I come up 2 utility functions for the conversion:</p>
<figure class="highlight coffeescript"><figcaption><span>NameConversion</span></figcaption><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div></pre></td><td class="code"><pre><div class="line"></div><div class="line">Utils =</div><div class="line"> hyphenToCamelCase: <span class="function"><span class="params">(hyphen)</span> -></span> <span class="comment"># Convert 'action-handler' to 'actionHandler'</span></div><div class="line"> hyphen.replace <span class="regexp">/-([a-z])/g</span>, <span class="function"><span class="params">(match)</span> -></span></div><div class="line"> match[<span class="number">1</span>].toUppercase()</div><div class="line"></div><div class="line"> camelCaseToHyphen: <span class="function"><span class="params">(camelCase)</span> -></span> <span class="comment"># Convert 'actionHandler' to 'action-handler'</span></div><div class="line"> camelCase.replace(<span class="regexp">/[A-Z]/g</span>, <span class="string">'-$1'</span>).toLowerCase()</div><div class="line"></div><div class="line"> attributeToCamelCase: <span class="function"><span class="params">(attribute)</span> -></span> <span class="comment"># Convert 'data-action-handler' or 'action-handler' to 'actionHandler'</span></div><div class="line"> Utils.hyphenToCamelCase dataAttribute.replace(<span class="regexp">/^(data-)?(.*)/</span>, <span class="string">'$2'</span>)</div><div class="line"></div><div class="line"> camelCaseToAttribute: <span class="function"><span class="params">(camelCase)</span> -></span> <span class="comment"># Convert 'actionHanlder' to 'data-action-handler'</span></div><div class="line"> <span class="string">'data-'</span> + Utils.camelCaseToHyphen(camelCase)</div><div class="line"></div></pre></td></tr></table></figure>
<p>Here is a more solid implementation based on previous one.</p>
<figure class="highlight javascript"><figcaption><span>a sloid javascript version</span></figcaption><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div></pre></td><td class="code"><pre><div class="line"></div><div class="line"><span class="keyword">var</span> Utils = (<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</div><div class="line"> <span class="function"><span class="keyword">function</span> <span class="title">hyphenToCamelCase</span>(<span class="params">hyphen</span>) </span>{</div><div class="line"> <span class="keyword">return</span> hyphen.replace(<span class="regexp">/-([a-z])/g</span>, <span class="function"><span class="keyword">function</span>(<span class="params">match</span>) </span>{</div><div class="line"> <span class="keyword">return</span> match[<span class="number">1</span>].toUppercase();</div><div class="line"> });</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="function"><span class="keyword">function</span> <span class="title">camelCaseToHyphen</span>(<span class="params">camelCase</span>) </span>{</div><div class="line"> <span class="keyword">return</span> camelCase.replace(<span class="regexp">/[A-Z]/g</span>, <span class="string">'-$1'</span>).toLowerCase();</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="function"><span class="keyword">function</span> <span class="title">attributeToCamelCase</span>(<span class="params">attribute</span>) </span>{</div><div class="line"> <span class="keyword">return</span> hyphenToCamelCase(dataAttribute.replace(<span class="regexp">/^(data-)?(.*)/</span>, <span class="string">'$2'</span>));</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="function"><span class="keyword">function</span> <span class="title">camelCaseToAttribute</span>(<span class="params">camelCase</span>) </span>{</div><div class="line"> <span class="keyword">return</span> <span class="string">'data-'</span> + camelCaseToHyphen(camelCase);</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span> {</div><div class="line"> hyphenToCamelCase: hyphenToCamelCase,</div><div class="line"> camelCaseToHyphen: camelCaseToHyphen,</div><div class="line"> attributeToCamelCase: attributeToCamelCase,</div><div class="line"> camelCaseToAttribute: camelCaseToAttribute</div><div class="line"> };</div><div class="line">})();</div><div class="line"></div></pre></td></tr></table></figure>
<p>I found a bug in <a href="http://bower.io/search/?q=widget.coffee" target="_blank" rel="external">widget.coffee</a> today. To fix the iss
Remove Bower from your build scripthttp://timnew.me/blog/2014/07/10/remove-bower-from-your-build-script/2014-07-10T00:00:00.000Z2014-08-23T10:07:47.000Z<h3 id="The-mysterious-broken-build"><a href="#The-mysterious-broken-build" class="headerlink" title="The mysterious broken build"></a>The mysterious broken build</h3><p>This morning, our QA told us that <code>knockout</code>, a javascript library that we used in our web app is missing on staging environment. Then we checked the package she got from CI server, and the javascript library was indeed not included. But when we tried to generate the package on our local dev box, we found that <code>knockout</code> is included.</p>
<p>It is a big surprise to us, because we share the exact same build scripts and environment between dev-boxes and CI agents and because we manage the front-end dependencies with <code>bower</code>. In our <code>gulp</code> script, we ask <code>bower</code> to install the dependencies every time to make sure they are up to date.</p>
<h3 id="The-root-cause-of-the-broken-build"><a href="#The-root-cause-of-the-broken-build" class="headerlink" title="The root cause of the broken build"></a>The root cause of the broken build</h3><p>After spending hours on diagnosing the CI agents, we finally figure out the reason, a tricky story:</p>
<p>When the Knockout maintainer released the v3.1 bower package, they made a mistake in <code>bower.json</code> config file, which packaged the <code>spec</code> folder instead of the <code>dist</code> folder. So this package is actually broken, because the main javascript file <code>dist/knockout.js</code> , described in <code>bower.json</code> doesn’t exist.</p>
<p>Later, the engineers realized they made a mistake, and they fixed the issue by releasing a new package. Maybe they think they haven’t changed any script logic, so <strong>they release the new package under the same version number</strong>, which is the criminal who broke our builds.</p>
<p>We’re so unlucky that the broken package is downloaded on our CI server when our build script was executed there for the first time. And the broken package is stored in <code>bower</code> cache at that time.</p>
<p>Because of Bower’s cache mechanism, the broken package is used unless the version is bumped or cache is expired. This is the reason why our build is broken on the CI server.</p>
<p>But on our dev box, for some reason, we had run <code>bower cache clean</code>, which invalidated the cache. So we have a good build on our local dev box. This is the reason why we can generate good package on our dev box.</p>
<p>It is a very tricky issue when using bower to manage dependencies. Although it is not completely our fault, but it is kind of the worst case then we can face. The build broke silently, there were no error logs or messages that helped to figure out the reason. (Well, we haven’t got a chance to setup the smoke test for our app yet, so it could be kind of our fault.)</p>
<p>We thought we had been careful enough to clean the <code>bower_components</code> folder every time, but that prevented us from figuring out the real cause.</p>
<p>After fixing this issue, discussed with my pair Rafa and we came up some practices that could be helpful to avoid this kind of issue:</p>
<h3 id="Best-practices"><a href="#Best-practices" class="headerlink" title="Best practices"></a>Best practices</h3><ul>
<li>Avoid <code>bower install</code> or any equivalent step (such as <code>gulp-bower</code>, <code>grunt-bower</code>, etc.) in the build script</li>
<li>Check <code>bower_components</code> into the code repository or download the dependencies from our self managed repository for large projects.</li>
<li>When dependencies are changed, manually install them and make sure they’re good.</li>
</ul>
<p>After doing this, our build script runs even faster, because we don’t need to check all dependencies are up-to-date every time. This is a bonus from removing <code>bower install</code> from our build script.</p>
<h3 id="Some-thoughts-on-the-package-system"><a href="#Some-thoughts-on-the-package-system" class="headerlink" title="Some thoughts on the package system"></a>Some thoughts on the package system</h3><p>Bower components are maintained by the community, and there is no strict quality control to ensure the package is bug-free or being released in an appropriate way. So it could be safer if we can check them manually, and lock them down across environments.</p>
<p>This could be common issue for all kind of community managed package system. Not just Bower, it could be Maven, Ruby Gem, Node.js package, Python pip package, nuget package or even Docker containers!</p>
<h3 id="The-mysterious-broken-build"><a href="#The-mysterious-broken-build" class="headerlink" title="The mysterious broken build"></a>The m
The battle between Game developers and Game Hackers - Part.1 How HiddenInt workshttp://timnew.me/blog/2014/06/24/the-battle-between-game-developers-and-game-hackers-part-1-how-hiddenint-works/2014-06-24T00:00:00.000Z2014-08-23T10:07:47.000Z<p><code>Harvest: Massive Encounter</code> is a very unique strategic tower defense game published by <a href="http://www.oxeyegames.com/harvest-massive-encounter/" target="_blank" rel="external">Oxeye Game Studio</a>. The game is amazing, but I won’t focus on that. I will discuss something interesting I discovered when hacking the game.</p>
<p>By hacking the game, I want to lock down the the number of Mineral that I have in the game. Mineral is the only key resource in the game, which is used to build or upgrade structures. Theoretically locking down a value is easy. Scan the memory for specific number for a few times to filter out the list of potential memory addresses. Then try them one by one. And finally figure out the proper address, then locked it down with the game hacking tool. Very standard approach, and supported by most of the game hacking tool.</p>
<p>But in Harvest, the story is quite different. By searching the mineral value, we can locate a specific address. But we can easily find that the value is only used for display instead of real game state data. In fact, Harvest uses a quite unique approach to protect its game status data! Oxeye guys call it the <code>Hidden Int</code>.</p>
<p>Here is the psudo-code explains how the it works:</p>
<figure class="highlight csharp"><figcaption><span>HiddenInt Psudo implementation</span></figcaption><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div></pre></td><td class="code"><pre><div class="line"></div><div class="line"><span class="keyword">class</span> <span class="title">HiddenInt</span> {</div><div class="line"></div><div class="line"> <span class="keyword">private</span> <span class="keyword">int</span> mask;</div><div class="line"> <span class="keyword">private</span> <span class="keyword">int</span> hashedValue;</div><div class="line"> <span class="keyword">private</span> Random maskGenerator;</div><div class="line"></div><div class="line"> <span class="function"><span class="keyword">public</span> <span class="title">HiddenInt</span>(<span class="params"><span class="keyword">int</span> initialValue</span>) </span>{</div><div class="line"> maskGenerator = <span class="keyword">new</span> Random();</div><div class="line"> setValue(initialValue);</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setValue</span>(<span class="params"><span class="keyword">int</span> <span class="keyword">value</span></span>) </span>{</div><div class="line"> <span class="keyword">this</span>.mask = maskGenerator.next();</div><div class="line"> <span class="keyword">this</span>.hashedValue = <span class="keyword">value</span> ^ <span class="keyword">this</span>.mask; <span class="comment">// ^ is xor operator.</span></div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">getValue</span>(<span class="params"></span>) </span>{</div><div class="line"> <span class="keyword">int</span> <span class="keyword">value</span> = <span class="keyword">this</span>.hashedValue ^ <span class="keyword">this</span>.mask;</div><div class="line"> setValue(<span class="keyword">value</span>); <span class="comment">// Generate a new mask and hashed value every time when the value is read.</span></div><div class="line"> <span class="keyword">return</span> <span class="keyword">value</span>;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">modifyValue</span>(<span class="params"><span class="keyword">int</span> difference</span>) </span>{</div><div class="line"> <span class="keyword">int</span> <span class="keyword">value</span> = getValue();</div><div class="line"> <span class="keyword">value</span> += difference;</div><div class="line"> setValue(<span class="keyword">value</span>);</div><div class="line"> <span class="keyword">return</span> <span class="keyword">value</span>;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">public</span> ~HiddenInt() { <span class="comment">// Destructor</span></div><div class="line"> delete maskGenerator;</div><div class="line"> }</div><div class="line">}</div><div class="line"></div></pre></td></tr></table></figure>
<p>So from the code, you can see, the plain value is never got stored in memory. Instead, it stored a “hashed” value, which is the plain value xor a random generated mask. And every time, when either the value being read or written, the mask changes. This kills the almost all kind of memory scanning features in all kind of game hacking tool! You cannot find the plain value in the memory, so you have to use “fuzzy scan”, which detects the values changes instead of scanning specific value. Again, the data in memory keeps changing even when the value doesn’t (I’ll explain why it happens later), so “fuzzy scan” doesn’t work either here!! That’s a master kill!</p>
<p>Besides of keeping mask changing, it also keeps reading the value out and writing it back, which kills most game editing tool “value frozen” feature! Unless you can ensure you freeze the <code>mask</code> and <code>hashed value</code> at the same time, or it breaks the value! Since the reading and writing happen in a very high frequency (Again I’ll explain why it happens later), so you have to lock down the value at a specific point, or the locked value will be overwritten immediately.</p>
<p>Furthermore, since this value is the key game value, which is displayed on Game UI all the time, the <code>getValue()</code> is called every time when game UI renders! And usually game UI renders in at least 60fps. So the value is read 60 times per second, and the mask changes 60 times per second! (This is why the value keep changing in a high frequency!)</p>
<p>So this is the almost invincible way to keep key game state data safe from common game hacking tools!</p>
<p>In the next post, I’ll explain how to find out a bypass to this security mechanism!</p>
<p><code>Harvest: Massive Encounter</code> is a very unique strategic tower defense game published by <a href="http://www.oxeyegames.com/har
Process.nextTick Implementation in Browserhttp://timnew.me/blog/2014/06/23/process-nexttick-implementation-in-browser/2014-06-23T00:00:00.000Z2014-08-23T10:07:47.000Z<p>Recursion is a common trick that is often used in JavaScript programming. So infinite recursion will cause stack overflow errors.<br>Some languages resolves this issue by introduce automatically tail call optimization, but in JavaScript we need to take care it on our own.</p>
<p>To solve the issue, <code>Node.js</code> has the utility functions <code>nextTick</code> to ensure specific code is invoked after the current function returned.<br>In Browser there is no standard approach to solve this issue, so workarounds are needed.</p>
<p>Thanks to <a href="https://github.com/defunctzombie" target="_blank" rel="external">Roman Shtylman(@defunctzombie)</a>, who created the <code>node-process</code> for <code>Browserify</code>, which simulate the <code>Node.js</code> API in browser environment.<br>Here is his implementation:</p>
<p><a href="https://github.com/defunctzombie/node-process/blob/master/browser.js" target="_blank" rel="external">node-process</a><br><figure class="highlight js"><figcaption><span>Infinite Recursion</span></figcaption><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div></pre></td><td class="code"><pre><div class="line"></div><div class="line">process.nextTick = (<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{</div><div class="line"> <span class="keyword">var</span> canSetImmediate = <span class="keyword">typeof</span> <span class="built_in">window</span> !== <span class="string">'undefined'</span></div><div class="line"> && <span class="built_in">window</span>.setImmediate;</div><div class="line"> <span class="keyword">var</span> canPost = <span class="keyword">typeof</span> <span class="built_in">window</span> !== <span class="string">'undefined'</span></div><div class="line"> && <span class="built_in">window</span>.postMessage && <span class="built_in">window</span>.addEventListener;</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (canSetImmediate) {</div><div class="line"> <span class="keyword">return</span> <span class="function"><span class="keyword">function</span> (<span class="params">f</span>) </span>{ <span class="keyword">return</span> <span class="built_in">window</span>.setImmediate(f) };</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (canPost) {</div><div class="line"> <span class="keyword">var</span> queue = [];</div><div class="line"> <span class="built_in">window</span>.addEventListener(<span class="string">'message'</span>, <span class="function"><span class="keyword">function</span> (<span class="params">ev</span>) </span>{</div><div class="line"> <span class="keyword">var</span> source = ev.source;</div><div class="line"> <span class="keyword">if</span> ((source === <span class="built_in">window</span> || source === <span class="literal">null</span>) && ev.data === <span class="string">'process-tick'</span>) {</div><div class="line"> ev.stopPropagation();</div><div class="line"> <span class="keyword">if</span> (queue.length > <span class="number">0</span>) {</div><div class="line"> <span class="keyword">var</span> fn = queue.shift();</div><div class="line"> fn();</div><div class="line"> }</div><div class="line"> }</div><div class="line"> }, <span class="literal">true</span>);</div><div class="line"></div><div class="line"> <span class="keyword">return</span> <span class="function"><span class="keyword">function</span> <span class="title">nextTick</span>(<span class="params">fn</span>) </span>{</div><div class="line"> queue.push(fn);</div><div class="line"> <span class="built_in">window</span>.postMessage(<span class="string">'process-tick'</span>, <span class="string">'*'</span>);</div><div class="line"> };</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span> <span class="function"><span class="keyword">function</span> <span class="title">nextTick</span>(<span class="params">fn</span>) </span>{</div><div class="line"> setTimeout(fn, <span class="number">0</span>);</div><div class="line"> };</div><div class="line">})();</div><div class="line"></div></pre></td></tr></table></figure></p>
<p>Here is some comments on the implementation.</p>
<h3 id="setTimeout"><a href="#setTimeout" class="headerlink" title="setTimeout"></a>setTimeout</h3><p>To simulate the nextTick behavior, <code>setTimeout(fn, 0)</code> is a well-known and easy to adopt approach. The issue of this method is that <code>setTimeout</code> function does heavy operations, call it in loop causes significant performance issue. So we should try to use cheaper approach when possible.</p>
<h3 id="setImmidate"><a href="#setImmidate" class="headerlink" title="setImmidate"></a>setImmidate</h3><p>There is a function called <code>setImmediate</code>, which behaves quite similar to <code>nextTick</code> but with a few differences when dealing with IO stuff. But in browser environment, there is no IO issue, so we can definitely replace the <code>nextTick</code> with it.</p>
<blockquote><p>Immediates are queued in the order created, and are popped off the queue once per loop iteration. This is different from process.nextTick which will execute process.maxTickDepth queued callbacks per iteration. setImmediate will yield to the event loop after firing a queued callback to make sure I/O is not being starved. While order is preserved for execution, other I/O events may fire between any two scheduled immediate callbacks.</p>
<footer><strong>setImmediate(callback, [arg], [...])</strong><cite><a href="http://nodejs.org/api/timers.html#timers_setimmediate_callback_arg" target="_blank" rel="external">Node.js</a></cite></footer></blockquote>
<p>The <code>setImmediate</code> function is perfect replacement for <code>nextTick</code>, but it is not supported by all the browsers. Only <code>IE 10</code> and <code>Node.js 0.10.+</code> supports it. Chrome, Firefox, Opera and all mobile browsers don’t.</p>
<blockquote><p>Note: This method is not expected to become standard, and is only implemented by recent builds of Internet Explorer and Node.js 0.10+. It meets resistance both from Gecko (Firefox) and Webkit (Google/Apple).</p>
<footer><strong>window.setImmediate</strong><cite><a href="https://developer.mozilla.org/en-US/docs/Web/API/Window.setImmediate" target="_blank" rel="external">MDN</a></cite></footer></blockquote>
<h3 id="window-postMessage"><a href="#window-postMessage" class="headerlink" title="window.postMessage"></a>window.postMessage</h3><p><code>window.postMessage</code> enable developer to access message queue in the browser. By adding some additional code, we can simulate nextTick behavior based on message queue. It works in most modern browser, except <code>IE 8</code>. In <code>IE 8</code>, the API is implemented in a synchronous way, which introduce an extra level of stack-push, so it cannot be used to simulate <code>nextTick</code>.</p>
<p>Overall, there is no perfect workaround to the <code>nextTick</code> issue for now. All the solutions have different limitations, we can only hope that this issue can be resolved in the future ECMAScript standard.</p>
<p>Recursion is a common trick that is often used in JavaScript programming. So infinite recursion will cause stack overflow errors.<br>Some
Android Studio 0.6.1 SDK recognition issue when using Android SDK 19 and Gradlehttp://timnew.me/blog/2014/06/20/android-studio-0-6-1-sdk-recognition-issue-when-using-android-sdk-19-and-gradle/2014-06-20T00:00:00.000Z2014-08-23T10:07:47.000Z<p>A few days ago I upgraded my Android Studio to version 0.6.1. And migrated my android project build system from Maven to Gradle. Then nightmare happened!</p>
<img src="/blog/2014/06/20/android-studio-0-6-1-sdk-recognition-issue-when-using-android-sdk-19-and-gradle/android_studio_version.png" alt="Android Studio Version" title="Android Studio Version">
<p>It looks there are some issue with Android Studio version 0.6.1, which cannot recognize the jar files in Android SDK 19 (4.4 Kit Kat). As a consequence that all the Android fundemantal classes are not recognized properly, which makes IDEA almost impossible to be used.</p>
<img src="/blog/2014/06/20/android-studio-0-6-1-sdk-recognition-issue-when-using-android-sdk-19-and-gradle/classes_not_recognized.png" alt="Classes Not Recognized" title="Classes Not Recognized">
<p>After spending days on googling and trying, I realize the issue is caused that Android Studio doesn’t recognize the sdk 19 content properly.</p>
<p>Here is the content of Android SDK 19 that Android Studio 0.6.1 identified:</p>
<img src="/blog/2014/06/20/android-studio-0-6-1-sdk-recognition-issue-when-using-android-sdk-19-and-gradle/sdk_in_android_studio.png" alt="SDK in Android Studio" title="SDK in Android Studio">
<p>As comparison, here is a list of proper content of Andrdoid SDK 19 with Google API:</p>
<img src="/blog/2014/06/20/android-studio-0-6-1-sdk-recognition-issue-when-using-android-sdk-19-and-gradle/sdk_in_idea.png" alt="SDK in IDEA" title="SDK in IDEA">
<p>Here is a list of proper content of Andrdoid SDK 19 retrived from Maven Repository:</p>
<img src="/blog/2014/06/20/android-studio-0-6-1-sdk-recognition-issue-when-using-android-sdk-19-and-gradle/maven_sdk_in_idea.png" alt="Maven SDK" title="Maven SDK">
<p>In the list, you can easily figure out that the <code>android.jar</code> file is missing! It is the reason why the classes are not properly recognized! Even more if you compare the list against the JDK 1.6, you will find that most of the content are the same.</p>
<img src="/blog/2014/06/20/android-studio-0-6-1-sdk-recognition-issue-when-using-android-sdk-19-and-gradle/jdk.png" alt="JDK" title="JDK">
<p>Ideally, to fix this issue should be quite easy. Android Studio provides a <code>Project Settings</code> dialog allow developer to adjust the SDK configurations.</p>
<p>Project Settings Dialog:</p>
<img src="/blog/2014/06/20/android-studio-0-6-1-sdk-recognition-issue-when-using-android-sdk-19-and-gradle/project_settings.png" alt="Project Settings" title="Project Settings">
<p>But for Gradle projects, Android Studio displays a greately simplified project settings dialog instead of the original one, which doesn’t allow developer to config the SDK in dialog any longer.</p>
<p>Gradle Project Settings Dialog:</p>
<img src="/blog/2014/06/20/android-studio-0-6-1-sdk-recognition-issue-when-using-android-sdk-19-and-gradle/gradle_project_settings.png" alt="Project Settings" title="Project Settings">
<p>Still now, I figured out several potentisal workarounds to this issue, hope these helps:</p>
<ol>
<li>Downgrade the SDK version from 19 to 18 fixes the issue.<br>If you not really needs SDK 19 features, try to downgrade the SDK version to 18 to fix the issue.</li>
<li>Use IntelliJ instead of Android Studio<br>I encounters a different issue when using IDEA, it fails to sync the Gradle file.</li>
<li>Use Maven or ANT instead of Gradle<br>Gradle is powerful, but there are too many environment issues when using with IDEs… Maven is relatively more stable.</li>
</ol>
<p>I haven’t figure out a perfect solution to this issue, just hope the Google can fix the issue as soon as possible.</p>
<p>A few days ago I upgraded my Android Studio to version 0.6.1. And migrated my android project build system from Maven to Gradle. Then nig