Prev: What is a software engineer?
Next: Java Front end Developer | NYC | Long term (Only GC/Citizens)
From: David Mark on 27 Nov 2009 22:53 On Nov 27, 3:35 am, Garrett Smith <dhtmlkitc...(a)gmail.com> wrote: [...] > > The jQuery attr function, as a core method, is broken by design. The > attr function seems to be an attempt to provide a cross browser function > to read *something* about an object. That something was either content > attributes or dom properties, and the discrimination between the two was > apparently grossly overlooked in the initial design. > > From jQuery attr: > | // If applicable, access the attribute via the DOM 0 way > | if ( name in elem && notxml && !special ) { > -- > Garrett > comp.lang.javascript FAQ:http://jibbering.com/faq/ Then there's GoogClosure (but why?) Here's the documentation for createDOM:- Returns a dom node with a set of attributes. This function accepts varargs for subsequent nodes to be added. Subsequent nodes will be added to the first node as childNodes. So: createDom('div', null, createDom('p'), createDom('p')); would return a div with two child paragraphs Yeah, that's it. No idea what it means. Could be important. goog.dom.createDom_ = function(doc, args) { var tagName = args[0]; var attributes = args[1]; Confusing start (and it doesn't get any better). // Internet Explorer is dumb: http://msdn.microsoft.com/workshop/author/ // dhtml/reference/properties/name_2.asp As mentioned, PKB. // Also does not allow setting of 'type' attribute on 'input' or 'button'. Oh but it does. They'd know if they only tested (instead of misinterpreting a Microsoft missive). if (goog.userAgent.IE && attributes && (attributes.name || attributes.type)) { So, if the UA string says IE (!) and the attributes argument passed has "name" or "type" properties... var tagNameArr = ['<', tagName]; if (attributes.name) { tagNameArr.push(' name="', goog.string.htmlEscape (attributes.name), '"'); } if (attributes.type) { tagNameArr.push(' type="', goog.string.htmlEscape (attributes.type), '"'); // Create copy of attribute map to remove 'type' without mutating argument attributes = goog.cloneObject(attributes); delete attributes.type; It's interesting. They didn't delete attributes.name. } tagNameArr.push('>'); tagName = tagNameArr.join(''); } This whole mess is a completely unneeded workaround that will fail miserably (likely throwing an exception) in any non-IE browser. Unnecessary and programming for disaster as many UA strings look like IE's. In short, type can be set once. Set it immediately after creating the element (before some other property set causes it to sprout a document fragment). You can set name any time, but set it after appending if you want the element to show up in DOM collections (e.g. form elements collection). I haven't read the MSDN article they cited (at least not recently). Perhaps it is wildly inaccurate (wouldn't be the first time). Regardless, these things are easy to test and the behavior has been the same for IE4-8 AFAIK. var element = doc.createElement(tagName); if (attributes) { if (goog.isString(attributes)) { typeof attributes == 'string' I am pleasantly surprised they checked for the string first. :) element.className = attributes; Seems an odd design. } else { goog.dom.setProperties(element, attributes); That looks critical. } } if (args.length > 2) { var childHandler = function(child) { // TODO: More coercion, ala MochiKit? if (child) { element.appendChild(goog.isString(child) ? doc.createTextNode(child) : child); } }; for (var i = 2; i < args.length; i++) { var arg = args[i]; // TODO: Fix isArrayLike to return false for a text node. if (goog.isArrayLike(arg) && !goog.dom.isNodeLike(arg)) { "Overloading" strategy is designed for failure. // If the argument is a node list, not a real array, use a clone, // because forEach can't be used to mutate a NodeList. goog.array.forEach(goog.dom.isNodeList(arg) ? goog.array.clone(arg) : arg, childHandler); } else { childHandler(arg); } } } Right, we'll skip that mess. Here's the salient bit:- goog.dom.setProperties = function(element, properties) { goog.object.forEach(properties, function(val, key) { if (key == 'style') { element.style.cssText = val; No feature detection. } else if (key == 'class') { As there is no real documentation, this is the first clue as to what is expected for attribute (property?) names. That's an attribute name. element.className = val; } else if (key == 'for') { As is that. element.htmlFor = val; } else if (key in goog.dom.DIRECT_ATTRIBUTE_MAP_) { No filter. And that object is a partial mapping of attribute names to DOM property names (see below). element.setAttribute(goog.dom.DIRECT_ATTRIBUTE_MAP_[key], val); Cue the Twilight Zone music. This passes a DOM property name to setAttribute. } else { This sets a DOM property with an attribute name. element[key] = val; element.readonly = ???; // Don't know what to pass for values element.colspan = ???; Those result in useless host object augmentations and you can't pass the property names (e.g. readOnly, colSpan) either (see mapping below). } }); }; In a nutshell, this is completely unusable. It literally makes no sense. Should be immediately apparent to almost anyone who has ever scripted an MSHTML DOM. Look closer and notice it is broken (by design) for everything else as well. I can see why their "technical writers" punted on writing this one up. As advertised:- goog.dom.DIRECT_ATTRIBUTE_MAP_ = { 'cellpadding': 'cellPadding', 'cellspacing': 'cellSpacing', 'colspan': 'colSpan', 'rowspan': 'rowSpan', 'valign': 'vAlign', 'height': 'height', 'width': 'width', 'usemap': 'useMap', 'frameborder': 'frameBorder', 'type': 'type' }; The height and width "mappings" are intriguing. Will force the use of setAttribute for height/width. Same for type, which makes no sense either. So eliminate those three. goog.dom.DIRECT_ATTRIBUTE_MAP_ = { 'cellpadding': 'cellPadding', 'cellspacing': 'cellSpacing', 'colspan': 'colSpan', 'rowspan': 'rowSpan', 'valign': 'vAlign', 'usemap': 'useMap', 'frameborder': 'frameBorder' }; Nobody really cares about the old cellpadding (padding style) or cellspacing (border-collapse style) or valign (vertical-align style) attributes/properties. So this is left:- goog.dom.DIRECT_ATTRIBUTE_MAP_ = { 'colspan': 'colSpan', 'rowspan': 'rowSpan', 'usemap': 'useMap', 'frameborder': 'frameBorder' }; ....accesskey, codebase, framespacing, maxlength, readonly, longdesc, tabindex, ismap... Overlooked? I suppose it doesn't really matter when you consider how this is used above. ;) Google couldn't have budgeted more than a case of Ripple for this (back in 2005). They got what they paid for. It was broken then and it is even more so now, even in an IE8-only environment. (!) Hard to believe they've been using this code for anything, but their developers have probably been stepping on mines for years, creating maps, passing along folklore, etc. Did nobody have time to look at (or test) the code that creates DOM nodes in five years? I see a note to go back and raid more fantasy code from MochiKit, which is a further indication of staleness (not to mention apathy).
From: David Mark on 28 Nov 2009 00:02 On Nov 27, 3:35 am, Garrett Smith <dhtmlkitc...(a)gmail.com> wrote: > David Mark wrote: > > On Nov 26, 10:05 pm, Garrett Smith <dhtmlkitc...(a)gmail.com> wrote: > >> David Mark wrote: > >>> On Nov 26, 3:45 am, Garrett Smith <dhtmlkitc...(a)gmail.com> wrote: > >>>> David Mark wrote: > >>>>> On Nov 26, 2:17 am, Garrett Smith <dhtmlkitc...(a)gmail.com> wrote: > >>>>> [...] > >>>>>> The realAttr? I don't think it does that. That function parses outerHTML > >>>>>> for IE. It seems like overkill. > >>>> Method realAttr address attribute issue; not properties. > >>> Of course. There is a companion (unfortunately) called "attr" that > >>> addresses properties. ;) > >>>> link.href (as in HTMLLinkElement) is a property. > >>> Yes. > >>>> The value is a relative > >>>> URI in IE. > >>> That's a bug > >> Why do you say so? > > > Because it should be absolute, just like a.href, img.src, etc. > > Alas, the DOM 2 HTML specification does not standardize it that way. Not > even for img.src. > > [snip] > > Understanding what browsers do offers the most benefit developers and > HTML 5 spec authors. That goal is best realized in a comprehensive table > showing browser+version in column with property names in rows. > > Trying to create a comprehensive realAttr or resolvedURI(prop) method is > just going to add a lot extra cruft and slow the code down. > It's not that much cruft, though any is too much IMO. Why put in workarounds for things you don't use? But the slowdown isn't an issue, even with the all the extra baggage of a GP wrapper. I added times at the end of each set. In IE, as expected (and regardless of mode), the wrappers are definitely several milliseconds slower. Results vary from one load to the next, but the direct method calls always win. It's about even in FF with the direct method calls usually a bit faster and, oddly enough, reversed in Chome where the wrappers are twice as fast as the direct method calls. YMMV of course. And I think I'd be more confident in the comparison if it looped through the 50 tests 100 times.
From: kangax on 28 Nov 2009 21:03 David Mark wrote: > On Nov 25, 12:42 pm, kangax <kan...(a)gmail.com> wrote: >> David Mark wrote: >>> On Nov 25, 2:37 am, Garrett Smith <dhtmlkitc...(a)gmail.com> wrote: [...] >>>> To run Blackberry Simulator, you need Email and MDS and then one or more >>>> Simulators. >>>> https://www.blackberry.com/Downloads/ >>> Page not found. :( I would like to see the results posted for this >>> device. >> Which results? > > Whatever was "document.written" at the time you ran it. You reported > 20-something errors, but didn't say if that total was for both sets of > tests (I assume it was). I'm curious about which tests failed as > well. So far I've been able to smooth out the kinks in every tested > browser (other than file URI's of course). I get 2 errors now (on 9530). Removed column span: '2' is not null Input checked property set: false is not true > > I downloaded a simulator recently, but didn't see immediately how to > do anything useful with it (it did hog my resources quite a bit to > show a picture of a phone though). I'll have to give that another go > some time. I know. That simulator is a PITA to set up. Good luck ;) -- kangax
From: kangax on 28 Nov 2009 21:15 Garrett Smith wrote: > kangax wrote: [...] >> >> There are rumors of Blackberry switching to WebKit in a very near future > > Yes, I have heard those rumors. Does Iris uses a proxy, like Opera Mobile? No idea. > >> >> There's no point in developing yet another proprietary engine. > > There may be a point for keeping Blackberry. If Blackberry is more > efficient, the battery would last longer. With a smaller app footprint, > the browser will launch faster. There may be other reasons related to > the device hardware or OS. That could be a reason, sure. But look at how poor its standards support is: <http://www.quirksmode.org/m/table.html#link23> It gets 14 on Acid 3, comparing to Iris' 100. [...] -- kangax
From: David Mark on 28 Nov 2009 21:31
On Nov 28, 9:03 pm, kangax <kan...(a)gmail.com> wrote: > David Mark wrote: > > On Nov 25, 12:42 pm, kangax <kan...(a)gmail.com> wrote: > >> David Mark wrote: > >>> On Nov 25, 2:37 am, Garrett Smith <dhtmlkitc...(a)gmail.com> wrote: > [...] > >>>> To run Blackberry Simulator, you need Email and MDS and then one or more > >>>> Simulators. > >>>>https://www.blackberry.com/Downloads/ > >>> Page not found. :( I would like to see the results posted for this > >>> device. > >> Which results? > > > Whatever was "document.written" at the time you ran it. You reported > > 20-something errors, but didn't say if that total was for both sets of > > tests (I assume it was). I'm curious about which tests failed as > > well. So far I've been able to smooth out the kinks in every tested > > browser (other than file URI's of course). > > I get 2 errors now (on 9530). That means either some of the same quirks found in the old Opera versions were also present in Blackberry or (less likely) the beefed up test for broken MSHTML DOM's put it on the right path. Either way, I'm quite pleased with the progress on the bizarre and ancient browser front. :) > > Removed column span: '2' is not null > Input checked property set: false is not true The former likely means the Blackberry DOM can't remove that attribute (and probably others). Looking at the latter, I can see how that slipped through the net (never feature tested that the boolean properties were consistent in their reflections). > 2 on the right (wrapped) and 30-something on the left (raw), right? Thanks for your help! |