"foo": [[1, "string", "anotherstring" {object:true}]]
I expect output like this from JSON.stringify:
"foo":[[1, \"string\", \"anotherstring\" {object:true}]]
And I get it, from native JSON, from json2.js, and from the older YAHOO.lang.JSON.
Mootools returned:
"foo":"[[1, \"string\", \"anotherstring\" {object:true}]]"
The object attribute was represented as a string!
So, I dug into the reasons why the shiny new JSON2 library had this issue, and only with Mootools present. Here is some history, and results of debugging.
typeof value.toJSON === 'function') {
// (JSON2's test now returns false, so the serialization is handled by JSON, not Mootools)
Below is the nitty gritty of how Mootools 1.2.4 can break JSON2.
Mootools 1.2.4
Here's the line where Crockford's JSON2.js tries to optimize by using a native method:
function str(key, holder) {
...
// If the value has a toJSON method, call it to obtain a replacement value.
if (value && typeof value === 'object' &&
typeof value.toJSON === 'function') {
value = value.toJSON(key);
}
Execution steps into Mootools' intrusive method:
Native.implement([Hash, Array, String, Number], {
toJSON: function(){
return JSON.encode(this);
}
});
Mootools $type function returns 'array' for a literal []. (Standard typeof operator returns 'object')
obj.$family.name // property $family was added by Mootools
I've seen this a few times in the past 3 weeks. Thought it was an intermittent glitch, connection problem, CDN. Today, I've seen it in Chrome and Firefox (FireBug enabled and Firebug disabled).
The everyday user sees something like screenshot 1.
The FireBug-using developer types can see that LinkedIn's CDN, and the JavaScript that calls it, are in a world of hurt.
LI_WCT is not defined
[Break on this error] LI_WCT([
nhome (line 619)
LI is not defined
[Break on this error] LI.i18n.register( 'share-dialog-title', 'Share' );
nhome (line 2850)
LI is not defined
[Break on this error] LI.i18n.register( 'Dialog-closeWindow', 'Close this window' );
nhome (line 4116)
ChameleonService is not defined
[Break on this error] ChameleonService.setPanel('1', {div: d...panel-01'),txId: '0', maxSlots: 15});
nhome (line 10635)
LI is not defined
[Break on this error]
nhome (line 10804)
LI is not defined
[Break on this error]
nhome (line 10805)
LI_WCT is not defined
[Break on this error] LI_WCT([
nhome (line 11008)
LI is not defined
[Break on this error] LI.Controls.processQueue();
nhome (line 11160)
YEvent is not defined
[Break on this error] YEvent.onDOMReady(function() {
nhome (line 11244)
LI is not defined
[Break on this error]
nhome (line 11286)
YEvent is not defined
[Break on this error] YEvent.on( window, 'load', function() {
nhome (line 11310)
YEvent is not defined
[Break on this error] YEvent.on( window, 'load', function() {
nhome (line 11339)
appendTryNewEditorButton is not defined
[Break on this error] appendTryNewEditorButton(); Labels: CDN, javascript, linkedin
I'm not convinced that you can get your mind outside-the-box by working on a little box. There's also a disconnect that occurs, I think of a new node. Then I must switch to gizmo-futzing mode in order to create the node container. Then typing mode. The keyboard grabs up about half the screen. These "not-conceptualizing" steps disrupt the free association and flow of the exercise.
iThoughtsHD
http://www.ipadmindmap.com/iPadMindmap/Welcome.html
I ran this as an app trial for iPhone and found it to be cool, but the maps are too complex and sprawling for the iPhone display. Two positive points: First, It can explore and some thoughts when you are in tight quarters, like a waiting room or airplane seat. Second, it was the only mind mapping app I kept on my iPhone.
MindMeister for iPad
http://itunes.apple.com/app/mindmeister-for-ipad/id381073026?mt=8
They ported it to iPad. Work locally until in-range of wifi, then it auto-syncs with server. First few reviews are mixed.
Labels: cognitive exercise, mind map, mind mapping
extensions.enabledItems;firebug@software.joehewitt.com:1.5.4,{3d7eb24f-2740-49df-
8937-200b1cc08f8a}:1.5.13,{d10d0bf8-f5b5-c8b4-a8b2-2b9879e08c5d}:1.2,{3112ca9c-
de6d-4884-
a869-9855de68056c}:7.1.20100408Mb1,foxmarks@kei.com:3.6.15,checkplaces@andyhalford.com:
2.2.1,{3c6e1eed-a07e-4c80-9cf3-66ea0bf40b37}:2.2,yslow@yahoo-inc.com:2.0.7,{AB7308B2-
C13C-4eba-
AC78-2AD55B96EE09}:3.0.0,csscoverage@spaghetticoder.org:0.2.1,closureinspector@google.com:0.9.5,{e3f6c2cc-
d8db-498c-af6c-499fb211db97}:1.8.1,{972ce4c6-7e08-4474-
a285-3208198ce6fd}:3.6.3
For Extra Credit, Go into vi and make the list more readable:
vi the_list.txt
:% s/[,]/\r/g
extensions.enabledItems
firebug@software.joehewitt.com:1.5.4{3d7eb24f-2740-49df-8937-200b1cc08f8a}:1.5.13
{d10d0bf8-f5b5-c8b4-a8b2-2b9879e08c5d}:1.2
{3112ca9c-de6d-4884-a869-9855de68056c}:7.1.20100408Mb1
foxmarks@kei.com:3.6.15
checkplaces@andyhalford.com:2.2.1
{3c6e1eed-a07e-4c80-9cf3-66ea0bf40b37}:2.2
yslow@yahoo-inc.com:2.0.7
{AB7308B2-C13C-4eba-AC78-2AD55B96EE09}:3.0.0
csscoverage@spaghetticoder.org:0.2.1
closureinspector@google.com:0.9.5
{e3f6c2cc-d8db-498c-af6c-499fb211db97}:1.8.1
{972ce4c6-7e08-4474-a285-3208198ce6fd}:3.6.3
Some legacy JavaScript code broke in Firefox 3.1 recently. An endless loop was formed, causing a "too much recursion" error and browser crashes. Here's a brief summary of how the loop was formed, and how I broke out of it. I grossly simplified the code for the example.
this.htmlBuffer += '<input type="radio" onclick="doStuff();repaintForm();"'; this.htmlBuffer += '/>'; // Some other inputs someDiv.innerHTML = this.htmlBuffer;
All tested browsers that came before Firefox 3 stopped propagation of the click event. Firefox 3 continued to propagate the click event after the form was repainted, so it effectively added a new event listener with each iteration.
I did some reading on the subject, at whirlpool and eyeOS. I tried various means of stopping the event, including...
e.stopPropagation(); // Mozilla e.preventDefault(); // Mozilla e.cancelBubble = true;// IE e.returnValue = false;// IE
None worked.
Adding "return false;" to the XHTML text of the onclick stopped event propagation in Firefox 3. It had no ill effects in Firefox 2, Safari 3, IE7, or IE6.
this.htmlBuffer += '<input type="radio" onclick="doStuff(this);repaintForm();return false;"'; this.htmlBuffer += '/>'; // Some other inputs someDiv.innerHTML = this.htmlBuffer;
Clearly, a better solution would include use of DOM methods to construct objects, instead of innerHTML. However, this solution fixed the problem in a hurry. If your existing application seems to get caught in an endless loop only in Firefox 3, the "return false" solution may help.
Labels: event propagation, Firefox 3, javascript
March 2006 May 2006 July 2006 August 2006 January 2007 March 2007 April 2007 August 2007 March 2008 April 2008 August 2008 April 2010 May 2010 July 2010 September 2010 April 2011