Mojo, the javascript framework in HP WebOS offer convenient ways to save data like Mojo.Model.Cookie…
Cookies can save javascript objects. Unfortunately, as this API is based on a JSON serialization, it can’t naturally deserialize all objects.
JSON can only serialize numbers, strings, booleans, arrays and objects. But when it serialize objects, obviously, only the object properties that can be serialized are serialized. Functions and prototype are not saved, and as a consequence not restored… In fact, arrays are the only objects that truly can be serialized…
For example, we can’t save Date instances… In fact, by default Date instance are serialized into ISO 8601 strings…
Mojo is based on the prototype javascript framework. To serialize an object in JSON, we just call the Object.toJSON function. When we look at the source code, we can see that this function call, if exists, a _toJSON method of the current serialized object (toJSON without underscore, in the real prototype framework, with underscore in Mojo). So if we implement a Date#toJSON method, we can change the way Date are serialized…
We can implement something like this :
1 2 3 |
<span class="nb">Date</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">_toJSON</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span> <span class="k">return</span> <span class="s1">'new Date('</span> <span class="o">+</span> <span class="k">this</span><span class="p">.</span><span class="nx">getFullYear</span><span class="p">()</span> <span class="o">+</span> <span class="s1">', '</span> <span class="o">+</span> <span class="k">this</span><span class="p">.</span><span class="nx">getMonth</span><span class="p">()</span> <span class="o">+</span> <span class="s1">', '</span> <span class="o">+</span> <span class="k">this</span><span class="p">.</span><span class="nx">getDay</span><span class="p">()</span> <span class="o">+</span> <span class="s1">', '</span> <span class="o">+</span> <span class="k">this</span><span class="p">.</span><span class="nx">getHours</span><span class="p">()</span> <span class="o">+</span> <span class="s1">', '</span> <span class="o">+</span> <span class="k">this</span><span class="p">.</span><span class="nx">getMinutes</span><span class="p">()</span> <span class="o">+</span> <span class="s1">', '</span> <span class="o">+</span> <span class="k">this</span><span class="p">.</span><span class="nx">getSeconds</span><span class="p">()</span> <span class="o">+</span> <span class="s1">')'</span><span class="p">;</span> <span class="p">};</span> |
This will broke the JSON specification, but if the string is deserialized in javascript with an eval(), this will create a new Date instance with the right parameters… But, prototype offer a String#evalJSON method. This method check the validity of the JSON string before evaluating it. The check is done with the String#isJSON method. And this method will broke on serialized date… We must update it to allow our new way to serialize dates…
1 2 3 4 5 6 |
<span class="nb">String</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">isJSON</span> <span class="o">=</span> <span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">orig</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span> <span class="kd">var</span> <span class="nx">str</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">replace</span><span class="p">(</span><span class="sr">/new Date\([0-9, ]\)/g</span><span class="p">,</span> <span class="s1">'"@"'</span><span class="p">);</span> <span class="k">return</span> <span class="nx">orig</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">str</span><span class="p">);</span> <span class="p">};</span> <span class="p">})(</span><span class="nb">String</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">isJSON</span><span class="p">);</span> |
So now, we can serialize date objects :
1 2 3 |
<span class="kd">var</span> <span class="nx">cookie</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Mojo</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">Cookie</span><span class="p">(</span><span class="s1">'date'</span><span class="p">);</span> <span class="kd">var</span> <span class="nx">d</span> <span class="o">=</span><span class="p">{</span> <span class="nx">date</span><span class="o">:</span> <span class="k">new</span> <span class="nb">Date</span><span class="p">()</span> <span class="p">};</span> <span class="nx">cookie</span><span class="p">.</span><span class="nx">put</span><span class="p">(</span><span class="nx">d</span><span class="p">);</span> |
And the deserialization is automagically done with a :
1 2 3 |
<span class="kd">var</span> <span class="nx">cookie</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Mojo</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">Cookie</span><span class="p">(</span><span class="s1">'date'</span><span class="p">);</span> <span class="kd">var</span> <span class="nx">d</span> <span class="o">=</span> <span class="nx">cookie</span><span class="p">.</span><span class="nx">get</span><span class="p">();</span> <span class="nx">Mojo</span><span class="p">.</span><span class="nx">Log</span><span class="p">.</span><span class="nx">info</span><span class="p">(</span><span class="nx">d</span><span class="p">.</span><span class="nx">date</span><span class="p">.</span><span class="nx">getTime</span><span class="p">());</span> |
That’s it… And this can be done with any objects…
Of course, this can also be done in non Mojo javascript environment…
Commentaires récents