Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue in Uize.Node.injectHtml #6

Open
BenAtZazzle opened this issue May 6, 2011 · 0 comments
Open

Issue in Uize.Node.injectHtml #6

BenAtZazzle opened this issue May 6, 2011 · 0 comments

Comments

@BenAtZazzle
Copy link
Contributor

Stumbled across and issue with Uize.Node.injectHtml. It really isn't an issue w/ the method per se, but it doesn't account for a bug in IE 6-9. The bug is best explained here: http://www.thecssninja.com/javascript/noscope

Essentially how I came across the bug was I was deferred loading a dialog via useDialog in Uize.Widget.Page. The dialog had minimal contents: a few container divs, a JST script block and a widget data script block. There was no actual textual content since the UI was going to be built client side. This (mysteriously) resulted in the markup within the container divs getting stripped when inserted via innerHTML. I changed the code in Uize.Node.injectHtml to prepend a scoped element (e) before the markup to insert and then the code just skips that child node when doing the rest of the work.

Here's the resultant code:

if (_isInnerReplace) _node.innerHTML = '';
var _dummyNode = document.createElement ('DIV');
_dummyNode.innerHTML = '<i>e</i>'   // fix for IE NoScope issue (http://www.thecssninja.com/javascript/noscope)
    + _htmlToInject
;
var
    _nodeToInsertBefore = _isInnerTop
        ? _nodeChildNodes [0]
        : _isOuterBottom ? _node.nextSibling : _node
    ,
    _nodesToInject = _dummyNode.childNodes,
    _nodeParentNode = _node.parentNode
;
function _fixCrippledScripts (_node) {
    ...
}
while (_nodesToInject.length > 1) { // should always have at least one node because of NoScope fix
    var _childNodeToInject = _nodesToInject [1];    // Skip the scope node
    if (_isInnerBottom || _isInnerReplace) {
        _node.appendChild (_childNodeToInject);
    } else if (_isInnerTop) {
        _nodeToInsertBefore
            ? _node.insertBefore (_childNodeToInject,_nodeToInsertBefore)
            : _node.appendChild (_childNodeToInject)
        ;
    } else if (_isOuterTop || _isOuterReplace) {
        _nodeParentNode.insertBefore (_childNodeToInject,_nodeToInsertBefore);
    } else if (_isOuterBottom) {
        _nodeToInsertBefore
            ? _nodeParentNode.insertBefore (_childNodeToInject,_nodeToInsertBefore)
            : _nodeParentNode.appendChild (_childNodeToInject)
        ;
    }
    _fixCrippledScripts (_childNodeToInject);
}

The lines with comments are the lines that were changed. I decided to add an actual container DOM node (e) instead of just an entity like that page suggests because if someone is just adding text, that entity would just get added to the test and there'd be only one child node instead of two

And here's the markup that was failing initially:

<div id="page_dialog-shield" class="selectionUiPickerDialog-shield"></div>
<div id="page_dialog" class="selectionUiPickerDialog">
<div id="page_dialog_value" class="optionsSelector ">
    <div id="page_dialog_value-options" class="optionsSelector-options">
        <script type="text/jst">
        <!-- JST code here -->
        </script>
    </div>
</div>
</div>
<script type='text/javascript'>
<!--
// widget data here

//-->
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant