From 77c942c4be24ed396e7b76ecf4a767834f6d5fce Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Tue, 10 Aug 2010 17:05:40 +0000 Subject: [PATCH] AUI-152 - Special elements are not properly cloned git-svn-id: svn://svn.liferay.com/repos/public/alloy/trunk@59971 05bdf26c-840f-0410-9ced-eb539d925f36 --- ATTRIBUTION.txt | 7 +- build/aui-node/aui-node-base-debug.js | 130 ++++++++++++++++++++++++-- build/aui-node/aui-node-base-min.js | 4 +- build/aui-node/aui-node-base.js | 130 ++++++++++++++++++++++++-- build/aui-node/aui-node-debug.js | 130 ++++++++++++++++++++++++-- build/aui-node/aui-node-min.js | 8 +- build/aui-node/aui-node.js | 130 ++++++++++++++++++++++++-- src/aui-node/js/aui-node-base.js | 130 ++++++++++++++++++++++++-- 8 files changed, 627 insertions(+), 42 deletions(-) diff --git a/ATTRIBUTION.txt b/ATTRIBUTION.txt index 123c7d0ca4f..2568d84a389 100644 --- a/ATTRIBUTION.txt +++ b/ATTRIBUTION.txt @@ -6,4 +6,9 @@ Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses Fugue Icons (icon_sprite.png) Copyright (C) 2009 Yusuke Kamiyamane. All rights reserved. The icons are licensed under a Creative Commons Attribution 3.0 license. - \ No newline at end of file + +---------------------------------- +Portions of the aui-node-base module +were used from the jQuery Javascript library +Copyright (c) 2010 John Resig & the jQuery team (http://jquery.com) +Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses. \ No newline at end of file diff --git a/build/aui-node/aui-node-base-debug.js b/build/aui-node/aui-node-base-debug.js index e78bf7ba9de..2be5abbd2a6 100644 --- a/build/aui-node/aui-node-base-debug.js +++ b/build/aui-node/aui-node-base-debug.js @@ -15,7 +15,9 @@ var Lang = A.Lang, getClassName = A.ClassNameManager.getClassName, - CLONED_EVENTS = false, + STR_EMPTY = '', + + ARRAY_EMPTY_STRINGS = [STR_EMPTY, STR_EMPTY], HELPER = 'helper', @@ -27,17 +29,25 @@ var Lang = A.Lang, NONE = 'none', PARENT_NODE = 'parentNode', SCRIPT = 'script', + + SUPPORT_CLONED_EVENTS = false, + VALUE = 'value'; - // Event cloning detection support based on pieces from jQuery + /* + Parts of this file are used from jQuery (http://jquery.com) + Dual-licensed under MIT/GPL + */ var div = document.createElement('div'); - div.innerHTML = ' '; // IE throws an error on fireEvent if the element does not have child nodes + + div.style.display = 'none'; + div.innerHTML = '
 '; if (div.attachEvent && div.fireEvent) { div.attachEvent( 'onclick', function(){ - CLONED_EVENTS = true; + SUPPORT_CLONED_EVENTS = true; div.detachEvent('onclick', arguments.callee); } @@ -46,6 +56,43 @@ var Lang = A.Lang, div.cloneNode(true).fireEvent('onclick'); } + var SUPPORT_SERIALIZE_HTML = !!div.getElementsByTagName('link').length, + SUPPORT_OPTIONAL_TBODY = !div.getElementsByTagName('tbody').length, + SUPPORT_LEADING_WHITESPACE = div.firstChild.nodeType === 3; + + var REGEX_LEADING_WHITE_SPACE = /^\s+/, + REGEX_IE8_ACTION = /=([^=\x27\x22>\s]+\/)>/g, + REGEX_XHTML_TAG = /(<([\w:]+)[^>]*?)\/>/g, + REGEX_SELF_CLOSING_ELEMENT = /^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i, + REGEX_TAGNAME = /<([\w:]+)/, + REGEX_TBODY = /'; + }; + + var MAP_WRAPPERS = { + _default: [0, STR_EMPTY, STR_EMPTY], + area: [1, '', ''], + col: [2, '', '
'], + legend: [1, '
', '
'], + option: [1, ''], + td: [3, '', '
'], + thead: [1, '', '
'], + tr: [2, '', '
'] + }; + + MAP_WRAPPERS.optgroup = MAP_WRAPPERS.option; + MAP_WRAPPERS.tbody = MAP_WRAPPERS.tfoot = MAP_WRAPPERS.colgroup = MAP_WRAPPERS.caption = MAP_WRAPPERS.thead; + MAP_WRAPPERS.th = MAP_WRAPPERS.td; + + if (!SUPPORT_SERIALIZE_HTML) { + MAP_WRAPPERS._default = [1, 'div
', '
']; + } + /** * Augment the YUI3 Node with more util methods. * @@ -215,13 +262,17 @@ A.mix(A.Node.prototype, { clone: (function() { var clone; - if (CLONED_EVENTS) { + if (SUPPORT_CLONED_EVENTS) { clone = function() { var el = this.getDOM(); var clone; if (el.nodeType != 3) { - clone = A.Node.create(this.outerHTML()) + var outerHTML = this.outerHTML(); + + outerHTML = outerHTML.replace(REGEX_IE8_ACTION, '="$1">').replace(REGEX_LEADING_WHITE_SPACE, ''); + + clone = A.one(A.Node._prepareHTML(outerHTML)[0]); } else { clone = A.one(el.cloneNode()); @@ -913,7 +964,7 @@ A.mix(A.Node.prototype, { var parent = instance.get(PARENT_NODE); if (parent) { - if (Lang.isString(newNode)) { + if (isString(newNode)) { newNode = A.Node.create(newNode); } @@ -933,6 +984,71 @@ A.mix(A.Node.prototype, { } }, true); +A.Node._prepareHTML = function(element) { + var doc = A.config.doc; + + var returnData = []; + + if (isString(element)) { + if (!REGEX_HTML.test(element)) { + element = doc.createTextNode(element); + } + else { + element = element.replace(REGEX_XHTML_TAG, FN_CLOSE_TAG); + + var tagName = (REGEX_TAGNAME.exec(element) || ARRAY_EMPTY_STRINGS)[1].toLowerCase(); + var wrap = MAP_WRAPPERS[tagName] || MAP_WRAPPERS._default; + var depth = wrap[0]; + var div = doc.createElement('div'); + + div.innerHTML = wrap[1] + element + wrap[2]; + + while (depth--) { + div = div.lastChild; + } + + if (!SUPPORT_OPTIONAL_TBODY) { + var hasTBody = REGEX_TBODY.test(element); + var tbody = []; + + if (tagName == 'table' && !hasTBody) { + if (div.firstChild) { + tbody = div.firstChild.childNodes; + } + } + else { + if (wrap[1] == '' && !hasTBody) { + tbody = div.childNodes; + } + } + + for (var i = tbody.length - 1; i >= 0; --i) { + var node = tbody[i]; + + if (node.nodeName.toLowerCase() == 'tbody' && node.childNodes.length) { + node.parentNode.removeChild(node); + } + } + } + + if (!SUPPORT_LEADING_WHITESPACE && REGEX_LEADING_WHITE_SPACE.test(element)) { + div.insertBefore(doc.createTextNode(REGEX_LEADING_WHITE_SPACE.exec(element)[0]), div.firstChild); + } + + element = div.childNodes; + } + } + + if (element.nodeType) { + returnData.push(element); + } + else { + returnData = element; + } + + return returnData; +}; + /** * Augment the YUI3 NodeList with more util methods. * diff --git a/build/aui-node/aui-node-base-min.js b/build/aui-node/aui-node-base-min.js index 20224536e43..d9da0e06340 100644 --- a/build/aui-node/aui-node-base-min.js +++ b/build/aui-node/aui-node-base-min.js @@ -1,2 +1,2 @@ -AUI.add("aui-node-base",function(O){var D=O.Lang,K=D.isArray,J=D.isObject,L=D.isString,C=D.isUndefined,R=D.isValue,F=O.ClassNameManager.getClassName,N=false,B="helper",T=F(B,"hidden"),P=F(B,"unselectable"),Q="innerHTML",S="nextSibling",H="none",G="parentNode",I="script",E="value";var M=document.createElement("div");M.innerHTML=" ";if(M.attachEvent&&M.fireEvent){M.attachEvent("onclick",function(){N=true;M.detachEvent("onclick",arguments.callee);});M.cloneNode(true).fireEvent("onclick");}O.mix(O.Node.prototype,{ancestors:function(U){var A=this;var W=[];var X=A.getDOM();while(X&&X.nodeType!==9){if(X.nodeType===1){W.push(X);}X=X.parentNode;}var V=new O.all(W);if(U){V=V.filter(U);}return V;},ancestorsByClassName:function(W){var A=this;var V=[];var U=new RegExp("\\b"+W+"\\b");var X=A.getDOM();while(X&&X.nodeType!==9){if(X.nodeType===1&&U.test(X.className)){V.push(X);}X=X.parentNode;}return O.all(V);},appendTo:function(U){var A=this;O.one(U).append(A);return A;},attr:function(U,X){var A=this;if(!C(X)){var W=A.getDOM();if(U in W){A.set(U,X);}else{A.setAttribute(U,X);}return A;}else{if(J(U)){for(var V in U){A.attr(V,U[V]);}return A;}return A.get(U)||A.getAttribute(U);}},clone:(function(){var A;if(N){A=function(){var U=this.getDOM();var V;if(U.nodeType!=3){V=O.Node.create(this.outerHTML());}else{V=O.one(U.cloneNode());}return V;};}else{A=function(){return this.cloneNode(true);};}return A;})(),center:function(Y){var A=this;Y=(Y&&O.one(Y))||O.getBody();var W=Y.get("region");var V=A.get("region");var X=W.left+(W.width/2);var U=W.top+(W.height/2);A.setXY([X-(V.width/2),U-(V.height/2)]);},empty:function(){var A=this;A.all(">*").remove().purge();var U=O.Node.getDOMNode(A);while(U.firstChild){U.removeChild(U.firstChild);}return A;},getDOM:function(){var A=this;return O.Node.getDOMNode(A);},guid:function(V){var U=this;var A=U.get("id");if(!A){A=O.stamp(U);U.set("id",A);}return A;},hide:function(U){var A=this;A.addClass(U||A._hideClass||T);return A;},hover:function(V,U){var A=this;var W;var Z=A._defaultHoverOptions;if(J(V,true)){W=V;W=O.mix(W,Z);V=W.over;U=W.out;}else{W=O.mix({over:V,out:U},Z);}A._hoverOptions=W;var Y=new O.DelayedTask(A._hoverOverTaskFn,A);var X=new O.DelayedTask(A._hoverOutTaskFn,A);W.overTask=Y;W.outTask=X;A.on(W.overEventType,A._hoverOverHandler,A);A.on(W.outEventType,A._hoverOutHandler,A);},html:function(){var A=arguments,U=A.length;if(U){this.set(Q,A[0]);}else{return this.get(Q);}return this;},outerHTML:function(){var A=this;var V=A.getDOM();if("outerHTML" in V){return V.outerHTML;}var U=O.Node.create("
").append(this.clone());try{return U.html();}catch(W){}finally{U=null;}},placeAfter:function(U){var A=this;return A._place(U,A.get(S));},placeBefore:function(U){var A=this;return A._place(U,A);},prependTo:function(U){var A=this;O.one(U).prepend(A);return A;},radioClass:function(U){var A=this;A.siblings().removeClass(U);A.addClass(U);return A;},resetId:function(U){var A=this;A.attr("id",O.guid(U));return A;},selectText:function(Z,V){var A=this;var U=A.getDOM();var X=A.val().length;V=R(V)?V:X;Z=R(Z)?Z:0;try{if(U.setSelectionRange){U.setSelectionRange(Z,V);}else{if(U.createTextRange){var W=U.createTextRange();W.moveStart("character",Z);W.moveEnd("character",V-X);W.select();}else{U.select();}}if(U!=document.activeElement){U.focus();}}catch(Y){}return A;},selectable:function(){var A=this;A.getDOM().unselectable="off";A.detach("selectstart");A.setStyles({"MozUserSelect":"","KhtmlUserSelect":""});A.removeClass(P);return A;},show:function(U){var A=this;A.removeClass(U||A._hideClass||T);return A;},swallowEvent:function(U,V){var A=this;var W=function(X){X.stopPropagation();if(V){X.preventDefault();X.halt();}return false;};if(K(U)){O.Array.each(U,function(X){A.on(X,W);});return this;}else{A.on(U,W);}return A;},text:function(V){var A=this;var U=A.getDOM();if(!C(V)){V=O.DOM._getDoc(U).createTextNode(V);return A.empty().append(V);}return A._getText(U.childNodes);},toggle:function(U){var A=this;var V="hide";var W=U||A._hideClass||T;if(A.hasClass(W)){V="show";}A[V](W);return A;},unselectable:function(){var A=this;A.getDOM().unselectable="on";A.swallowEvent("selectstart",true);A.setStyles({"MozUserSelect":H,"KhtmlUserSelect":H});A.addClass(P);return A;},val:function(U){var A=this;if(C(U)){return A.get(E);}else{return A.set(E,U);}},_getText:function(Y){var A=this;var W=Y.length;var V;var X=[];for(var U=0;U
 ";if(T.attachEvent&&T.fireEvent){T.attachEvent("onclick",function(){U=true;T.detachEvent("onclick",arguments.callee);});T.cloneNode(true).fireEvent("onclick");}var P=!!T.getElementsByTagName("link").length,I=!T.getElementsByTagName("tbody").length,C=T.firstChild.nodeType===3;var b=/^\s+/,B=/=([^=\x27\x22>\s]+\/)>/g,a=/(<([\w:]+)[^>]*?)\/>/g,g=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,S=/<([\w:]+)/,e=/";};var Y={_default:[0,W,W],area:[1,"",""],col:[2,"","
"],legend:[1,"
","
"],option:[1,'"],td:[3,"","
"],thead:[1,"","
"],tr:[2,"","
"]};Y.optgroup=Y.option;Y.tbody=Y.tfoot=Y.colgroup=Y.caption=Y.thead;Y.th=Y.td;if(!P){Y._default=[1,"div
","
"];}V.mix(V.Node.prototype,{ancestors:function(i){var A=this;var k=[];var l=A.getDOM();while(l&&l.nodeType!==9){if(l.nodeType===1){k.push(l);}l=l.parentNode;}var j=new V.all(k);if(i){j=j.filter(i);}return j;},ancestorsByClassName:function(k){var A=this;var j=[];var i=new RegExp("\\b"+k+"\\b");var l=A.getDOM();while(l&&l.nodeType!==9){if(l.nodeType===1&&i.test(l.className)){j.push(l);}l=l.parentNode;}return V.all(j);},appendTo:function(i){var A=this;V.one(i).append(A);return A;},attr:function(j,m){var A=this;if(!E(m)){var l=A.getDOM();if(j in l){A.set(j,m);}else{A.setAttribute(j,m);}return A;}else{if(N(j)){for(var k in j){A.attr(k,j[k]);}return A;}return A.get(j)||A.getAttribute(j);}},clone:(function(){var A;if(U){A=function(){var i=this.getDOM();var k;if(i.nodeType!=3){var j=this.outerHTML();j=j.replace(B,'="$1">').replace(b,"");k=V.one(V.Node._prepareHTML(j)[0]);}else{k=V.one(i.cloneNode());}return k;};}else{A=function(){return this.cloneNode(true);};}return A;})(),center:function(m){var A=this;m=(m&&V.one(m))||V.getBody();var k=m.get("region");var j=A.get("region");var l=k.left+(k.width/2);var i=k.top+(k.height/2);A.setXY([l-(j.width/2),i-(j.height/2)]);},empty:function(){var A=this;A.all(">*").remove().purge();var i=V.Node.getDOMNode(A);while(i.firstChild){i.removeChild(i.firstChild);}return A;},getDOM:function(){var A=this;return V.Node.getDOMNode(A);},guid:function(j){var i=this;var A=i.get("id");if(!A){A=V.stamp(i);i.set("id",A);}return A;},hide:function(i){var A=this;A.addClass(i||A._hideClass||h);return A;},hover:function(j,i){var A=this;var k;var n=A._defaultHoverOptions;if(N(j,true)){k=j;k=V.mix(k,n);j=k.over;i=k.out;}else{k=V.mix({over:j,out:i},n);}A._hoverOptions=k;var m=new V.DelayedTask(A._hoverOverTaskFn,A);var l=new V.DelayedTask(A._hoverOutTaskFn,A);k.overTask=m;k.outTask=l;A.on(k.overEventType,A._hoverOverHandler,A);A.on(k.outEventType,A._hoverOutHandler,A);},html:function(){var A=arguments,i=A.length;if(i){this.set(Z,A[0]);}else{return this.get(Z);}return this;},outerHTML:function(){var A=this;var j=A.getDOM();if("outerHTML" in j){return j.outerHTML;}var i=V.Node.create("
").append(this.clone());try{return i.html();}catch(k){}finally{i=null;}},placeAfter:function(i){var A=this;return A._place(i,A.get(f));},placeBefore:function(i){var A=this;return A._place(i,A);},prependTo:function(i){var A=this;V.one(i).prepend(A);return A;},radioClass:function(i){var A=this;A.siblings().removeClass(i);A.addClass(i);return A;},resetId:function(i){var A=this;A.attr("id",V.guid(i));return A;},selectText:function(n,j){var A=this;var i=A.getDOM();var l=A.val().length;j=c(j)?j:l;n=c(n)?n:0;try{if(i.setSelectionRange){i.setSelectionRange(n,j);}else{if(i.createTextRange){var k=i.createTextRange();k.moveStart("character",n);k.moveEnd("character",j-l);k.select();}else{i.select();}}if(i!=document.activeElement){i.focus();}}catch(m){}return A;},selectable:function(){var A=this;A.getDOM().unselectable="off";A.detach("selectstart");A.setStyles({"MozUserSelect":"","KhtmlUserSelect":""});A.removeClass(X);return A;},show:function(i){var A=this;A.removeClass(i||A._hideClass||h);return A;},swallowEvent:function(i,j){var A=this;var k=function(l){l.stopPropagation();if(j){l.preventDefault();l.halt();}return false;};if(O(i)){V.Array.each(i,function(l){A.on(l,k);});return this;}else{A.on(i,k);}return A;},text:function(j){var A=this;var i=A.getDOM();if(!E(j)){j=V.DOM._getDoc(i).createTextNode(j);return A.empty().append(j);}return A._getText(i.childNodes);},toggle:function(i){var A=this;var j="hide";var k=i||A._hideClass||h;if(A.hasClass(k)){j="show";}A[j](k);return A;},unselectable:function(){var A=this;A.getDOM().unselectable="on";A.swallowEvent("selectstart",true);A.setStyles({"MozUserSelect":L,"KhtmlUserSelect":L});A.addClass(X);return A;},val:function(i){var A=this;if(E(i)){return A.get(H);}else{return A.set(H,i);}},_getText:function(n){var A=this;var l=n.length;var k;var m=[];for(var j=0;j"&&!s){o=A.childNodes;}}for(var n=o.length-1;n>=0;--n){var l=o[n];if(l.nodeName.toLowerCase()=="tbody"&&l.childNodes.length){l.parentNode.removeChild(l);}}}if(!C&&b.test(q)){A.insertBefore(r.createTextNode(b.exec(q)[0]),A.firstChild);}q=A.childNodes;}}if(q.nodeType){m.push(q);}else{m=q;}return m;};V.NodeList.importMethod(V.Node.prototype,["after","appendTo","attr","before","empty","hide","hover","html","outerHTML","prepend","prependTo","purge","selectText","selectable","show","text","toggle","unselectable","val"]);V.mix(V.NodeList.prototype,{all:function(k){var j=this;var o=[];var l=j._nodes;var n=l.length;var A;for(var m=0;m\s]+\/)>/g, + REGEX_XHTML_TAG = /(<([\w:]+)[^>]*?)\/>/g, + REGEX_SELF_CLOSING_ELEMENT = /^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i, + REGEX_TAGNAME = /<([\w:]+)/, + REGEX_TBODY = /'; + }; + + var MAP_WRAPPERS = { + _default: [0, STR_EMPTY, STR_EMPTY], + area: [1, '', ''], + col: [2, '', '
'], + legend: [1, '
', '
'], + option: [1, ''], + td: [3, '', '
'], + thead: [1, '', '
'], + tr: [2, '', '
'] + }; + + MAP_WRAPPERS.optgroup = MAP_WRAPPERS.option; + MAP_WRAPPERS.tbody = MAP_WRAPPERS.tfoot = MAP_WRAPPERS.colgroup = MAP_WRAPPERS.caption = MAP_WRAPPERS.thead; + MAP_WRAPPERS.th = MAP_WRAPPERS.td; + + if (!SUPPORT_SERIALIZE_HTML) { + MAP_WRAPPERS._default = [1, 'div
', '
']; + } + /** * Augment the YUI3 Node with more util methods. * @@ -215,13 +262,17 @@ A.mix(A.Node.prototype, { clone: (function() { var clone; - if (CLONED_EVENTS) { + if (SUPPORT_CLONED_EVENTS) { clone = function() { var el = this.getDOM(); var clone; if (el.nodeType != 3) { - clone = A.Node.create(this.outerHTML()) + var outerHTML = this.outerHTML(); + + outerHTML = outerHTML.replace(REGEX_IE8_ACTION, '="$1">').replace(REGEX_LEADING_WHITE_SPACE, ''); + + clone = A.one(A.Node._prepareHTML(outerHTML)[0]); } else { clone = A.one(el.cloneNode()); @@ -913,7 +964,7 @@ A.mix(A.Node.prototype, { var parent = instance.get(PARENT_NODE); if (parent) { - if (Lang.isString(newNode)) { + if (isString(newNode)) { newNode = A.Node.create(newNode); } @@ -933,6 +984,71 @@ A.mix(A.Node.prototype, { } }, true); +A.Node._prepareHTML = function(element) { + var doc = A.config.doc; + + var returnData = []; + + if (isString(element)) { + if (!REGEX_HTML.test(element)) { + element = doc.createTextNode(element); + } + else { + element = element.replace(REGEX_XHTML_TAG, FN_CLOSE_TAG); + + var tagName = (REGEX_TAGNAME.exec(element) || ARRAY_EMPTY_STRINGS)[1].toLowerCase(); + var wrap = MAP_WRAPPERS[tagName] || MAP_WRAPPERS._default; + var depth = wrap[0]; + var div = doc.createElement('div'); + + div.innerHTML = wrap[1] + element + wrap[2]; + + while (depth--) { + div = div.lastChild; + } + + if (!SUPPORT_OPTIONAL_TBODY) { + var hasTBody = REGEX_TBODY.test(element); + var tbody = []; + + if (tagName == 'table' && !hasTBody) { + if (div.firstChild) { + tbody = div.firstChild.childNodes; + } + } + else { + if (wrap[1] == '' && !hasTBody) { + tbody = div.childNodes; + } + } + + for (var i = tbody.length - 1; i >= 0; --i) { + var node = tbody[i]; + + if (node.nodeName.toLowerCase() == 'tbody' && node.childNodes.length) { + node.parentNode.removeChild(node); + } + } + } + + if (!SUPPORT_LEADING_WHITESPACE && REGEX_LEADING_WHITE_SPACE.test(element)) { + div.insertBefore(doc.createTextNode(REGEX_LEADING_WHITE_SPACE.exec(element)[0]), div.firstChild); + } + + element = div.childNodes; + } + } + + if (element.nodeType) { + returnData.push(element); + } + else { + returnData = element; + } + + return returnData; +}; + /** * Augment the YUI3 NodeList with more util methods. * diff --git a/build/aui-node/aui-node-debug.js b/build/aui-node/aui-node-debug.js index 285d02243a3..fd0527d49e7 100644 --- a/build/aui-node/aui-node-debug.js +++ b/build/aui-node/aui-node-debug.js @@ -15,7 +15,9 @@ var Lang = A.Lang, getClassName = A.ClassNameManager.getClassName, - CLONED_EVENTS = false, + STR_EMPTY = '', + + ARRAY_EMPTY_STRINGS = [STR_EMPTY, STR_EMPTY], HELPER = 'helper', @@ -27,17 +29,25 @@ var Lang = A.Lang, NONE = 'none', PARENT_NODE = 'parentNode', SCRIPT = 'script', + + SUPPORT_CLONED_EVENTS = false, + VALUE = 'value'; - // Event cloning detection support based on pieces from jQuery + /* + Parts of this file are used from jQuery (http://jquery.com) + Dual-licensed under MIT/GPL + */ var div = document.createElement('div'); - div.innerHTML = ' '; // IE throws an error on fireEvent if the element does not have child nodes + + div.style.display = 'none'; + div.innerHTML = '
 '; if (div.attachEvent && div.fireEvent) { div.attachEvent( 'onclick', function(){ - CLONED_EVENTS = true; + SUPPORT_CLONED_EVENTS = true; div.detachEvent('onclick', arguments.callee); } @@ -46,6 +56,43 @@ var Lang = A.Lang, div.cloneNode(true).fireEvent('onclick'); } + var SUPPORT_SERIALIZE_HTML = !!div.getElementsByTagName('link').length, + SUPPORT_OPTIONAL_TBODY = !div.getElementsByTagName('tbody').length, + SUPPORT_LEADING_WHITESPACE = div.firstChild.nodeType === 3; + + var REGEX_LEADING_WHITE_SPACE = /^\s+/, + REGEX_IE8_ACTION = /=([^=\x27\x22>\s]+\/)>/g, + REGEX_XHTML_TAG = /(<([\w:]+)[^>]*?)\/>/g, + REGEX_SELF_CLOSING_ELEMENT = /^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i, + REGEX_TAGNAME = /<([\w:]+)/, + REGEX_TBODY = /'; + }; + + var MAP_WRAPPERS = { + _default: [0, STR_EMPTY, STR_EMPTY], + area: [1, '', ''], + col: [2, '', '
'], + legend: [1, '
', '
'], + option: [1, ''], + td: [3, '', '
'], + thead: [1, '', '
'], + tr: [2, '', '
'] + }; + + MAP_WRAPPERS.optgroup = MAP_WRAPPERS.option; + MAP_WRAPPERS.tbody = MAP_WRAPPERS.tfoot = MAP_WRAPPERS.colgroup = MAP_WRAPPERS.caption = MAP_WRAPPERS.thead; + MAP_WRAPPERS.th = MAP_WRAPPERS.td; + + if (!SUPPORT_SERIALIZE_HTML) { + MAP_WRAPPERS._default = [1, 'div
', '
']; + } + /** * Augment the YUI3 Node with more util methods. * @@ -215,13 +262,17 @@ A.mix(A.Node.prototype, { clone: (function() { var clone; - if (CLONED_EVENTS) { + if (SUPPORT_CLONED_EVENTS) { clone = function() { var el = this.getDOM(); var clone; if (el.nodeType != 3) { - clone = A.Node.create(this.outerHTML()) + var outerHTML = this.outerHTML(); + + outerHTML = outerHTML.replace(REGEX_IE8_ACTION, '="$1">').replace(REGEX_LEADING_WHITE_SPACE, ''); + + clone = A.one(A.Node._prepareHTML(outerHTML)[0]); } else { clone = A.one(el.cloneNode()); @@ -913,7 +964,7 @@ A.mix(A.Node.prototype, { var parent = instance.get(PARENT_NODE); if (parent) { - if (Lang.isString(newNode)) { + if (isString(newNode)) { newNode = A.Node.create(newNode); } @@ -933,6 +984,71 @@ A.mix(A.Node.prototype, { } }, true); +A.Node._prepareHTML = function(element) { + var doc = A.config.doc; + + var returnData = []; + + if (isString(element)) { + if (!REGEX_HTML.test(element)) { + element = doc.createTextNode(element); + } + else { + element = element.replace(REGEX_XHTML_TAG, FN_CLOSE_TAG); + + var tagName = (REGEX_TAGNAME.exec(element) || ARRAY_EMPTY_STRINGS)[1].toLowerCase(); + var wrap = MAP_WRAPPERS[tagName] || MAP_WRAPPERS._default; + var depth = wrap[0]; + var div = doc.createElement('div'); + + div.innerHTML = wrap[1] + element + wrap[2]; + + while (depth--) { + div = div.lastChild; + } + + if (!SUPPORT_OPTIONAL_TBODY) { + var hasTBody = REGEX_TBODY.test(element); + var tbody = []; + + if (tagName == 'table' && !hasTBody) { + if (div.firstChild) { + tbody = div.firstChild.childNodes; + } + } + else { + if (wrap[1] == '' && !hasTBody) { + tbody = div.childNodes; + } + } + + for (var i = tbody.length - 1; i >= 0; --i) { + var node = tbody[i]; + + if (node.nodeName.toLowerCase() == 'tbody' && node.childNodes.length) { + node.parentNode.removeChild(node); + } + } + } + + if (!SUPPORT_LEADING_WHITESPACE && REGEX_LEADING_WHITE_SPACE.test(element)) { + div.insertBefore(doc.createTextNode(REGEX_LEADING_WHITE_SPACE.exec(element)[0]), div.firstChild); + } + + element = div.childNodes; + } + } + + if (element.nodeType) { + returnData.push(element); + } + else { + returnData = element; + } + + return returnData; +}; + /** * Augment the YUI3 NodeList with more util methods. * diff --git a/build/aui-node/aui-node-min.js b/build/aui-node/aui-node-min.js index 7060532bf88..25fbeb59a3d 100644 --- a/build/aui-node/aui-node-min.js +++ b/build/aui-node/aui-node-min.js @@ -1,5 +1,5 @@ -AUI.add("aui-node-base",function(O){var D=O.Lang,K=D.isArray,J=D.isObject,L=D.isString,C=D.isUndefined,R=D.isValue,F=O.ClassNameManager.getClassName,N=false,B="helper",T=F(B,"hidden"),P=F(B,"unselectable"),Q="innerHTML",S="nextSibling",H="none",G="parentNode",I="script",E="value";var M=document.createElement("div");M.innerHTML=" ";if(M.attachEvent&&M.fireEvent){M.attachEvent("onclick",function(){N=true;M.detachEvent("onclick",arguments.callee);});M.cloneNode(true).fireEvent("onclick");}O.mix(O.Node.prototype,{ancestors:function(U){var A=this;var W=[];var X=A.getDOM();while(X&&X.nodeType!==9){if(X.nodeType===1){W.push(X);}X=X.parentNode;}var V=new O.all(W);if(U){V=V.filter(U);}return V;},ancestorsByClassName:function(W){var A=this;var V=[];var U=new RegExp("\\b"+W+"\\b");var X=A.getDOM();while(X&&X.nodeType!==9){if(X.nodeType===1&&U.test(X.className)){V.push(X);}X=X.parentNode;}return O.all(V);},appendTo:function(U){var A=this;O.one(U).append(A);return A;},attr:function(U,X){var A=this;if(!C(X)){var W=A.getDOM();if(U in W){A.set(U,X);}else{A.setAttribute(U,X);}return A;}else{if(J(U)){for(var V in U){A.attr(V,U[V]);}return A;}return A.get(U)||A.getAttribute(U);}},clone:(function(){var A;if(N){A=function(){var U=this.getDOM();var V;if(U.nodeType!=3){V=O.Node.create(this.outerHTML());}else{V=O.one(U.cloneNode());}return V;};}else{A=function(){return this.cloneNode(true);};}return A;})(),center:function(Y){var A=this;Y=(Y&&O.one(Y))||O.getBody();var W=Y.get("region");var V=A.get("region");var X=W.left+(W.width/2);var U=W.top+(W.height/2);A.setXY([X-(V.width/2),U-(V.height/2)]);},empty:function(){var A=this;A.all(">*").remove().purge();var U=O.Node.getDOMNode(A);while(U.firstChild){U.removeChild(U.firstChild);}return A;},getDOM:function(){var A=this;return O.Node.getDOMNode(A);},guid:function(V){var U=this;var A=U.get("id");if(!A){A=O.stamp(U);U.set("id",A);}return A;},hide:function(U){var A=this;A.addClass(U||A._hideClass||T);return A;},hover:function(V,U){var A=this;var W;var Z=A._defaultHoverOptions;if(J(V,true)){W=V;W=O.mix(W,Z);V=W.over;U=W.out;}else{W=O.mix({over:V,out:U},Z);}A._hoverOptions=W;var Y=new O.DelayedTask(A._hoverOverTaskFn,A);var X=new O.DelayedTask(A._hoverOutTaskFn,A);W.overTask=Y;W.outTask=X;A.on(W.overEventType,A._hoverOverHandler,A);A.on(W.outEventType,A._hoverOutHandler,A);},html:function(){var A=arguments,U=A.length;if(U){this.set(Q,A[0]);}else{return this.get(Q);}return this;},outerHTML:function(){var A=this;var V=A.getDOM();if("outerHTML" in V){return V.outerHTML;}var U=O.Node.create("
").append(this.clone());try{return U.html();}catch(W){}finally{U=null;}},placeAfter:function(U){var A=this;return A._place(U,A.get(S));},placeBefore:function(U){var A=this;return A._place(U,A);},prependTo:function(U){var A=this;O.one(U).prepend(A);return A;},radioClass:function(U){var A=this;A.siblings().removeClass(U);A.addClass(U);return A;},resetId:function(U){var A=this;A.attr("id",O.guid(U));return A;},selectText:function(Z,V){var A=this;var U=A.getDOM();var X=A.val().length;V=R(V)?V:X;Z=R(Z)?Z:0;try{if(U.setSelectionRange){U.setSelectionRange(Z,V);}else{if(U.createTextRange){var W=U.createTextRange();W.moveStart("character",Z);W.moveEnd("character",V-X);W.select();}else{U.select();}}if(U!=document.activeElement){U.focus();}}catch(Y){}return A;},selectable:function(){var A=this;A.getDOM().unselectable="off";A.detach("selectstart");A.setStyles({"MozUserSelect":"","KhtmlUserSelect":""});A.removeClass(P);return A;},show:function(U){var A=this;A.removeClass(U||A._hideClass||T);return A;},swallowEvent:function(U,V){var A=this;var W=function(X){X.stopPropagation();if(V){X.preventDefault();X.halt();}return false;};if(K(U)){O.Array.each(U,function(X){A.on(X,W);});return this;}else{A.on(U,W);}return A;},text:function(V){var A=this;var U=A.getDOM();if(!C(V)){V=O.DOM._getDoc(U).createTextNode(V);return A.empty().append(V);}return A._getText(U.childNodes);},toggle:function(U){var A=this;var V="hide";var W=U||A._hideClass||T;if(A.hasClass(W)){V="show";}A[V](W);return A;},unselectable:function(){var A=this;A.getDOM().unselectable="on";A.swallowEvent("selectstart",true);A.setStyles({"MozUserSelect":H,"KhtmlUserSelect":H});A.addClass(P);return A;},val:function(U){var A=this;if(C(U)){return A.get(E);}else{return A.set(E,U);}},_getText:function(Y){var A=this;var W=Y.length;var V;var X=[];for(var U=0;U
 ";if(T.attachEvent&&T.fireEvent){T.attachEvent("onclick",function(){U=true;T.detachEvent("onclick",arguments.callee);});T.cloneNode(true).fireEvent("onclick");}var P=!!T.getElementsByTagName("link").length,I=!T.getElementsByTagName("tbody").length,C=T.firstChild.nodeType===3;var b=/^\s+/,B=/=([^=\x27\x22>\s]+\/)>/g,a=/(<([\w:]+)[^>]*?)\/>/g,g=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,S=/<([\w:]+)/,e=/";};var Y={_default:[0,W,W],area:[1,"",""],col:[2,"","
"],legend:[1,"
","
"],option:[1,'"],td:[3,"","
"],thead:[1,"","
"],tr:[2,"","
"]};Y.optgroup=Y.option;Y.tbody=Y.tfoot=Y.colgroup=Y.caption=Y.thead;Y.th=Y.td;if(!P){Y._default=[1,"div
","
"];}V.mix(V.Node.prototype,{ancestors:function(i){var A=this;var k=[];var l=A.getDOM();while(l&&l.nodeType!==9){if(l.nodeType===1){k.push(l);}l=l.parentNode;}var j=new V.all(k);if(i){j=j.filter(i);}return j;},ancestorsByClassName:function(k){var A=this;var j=[];var i=new RegExp("\\b"+k+"\\b");var l=A.getDOM();while(l&&l.nodeType!==9){if(l.nodeType===1&&i.test(l.className)){j.push(l);}l=l.parentNode;}return V.all(j);},appendTo:function(i){var A=this;V.one(i).append(A);return A;},attr:function(j,m){var A=this;if(!E(m)){var l=A.getDOM();if(j in l){A.set(j,m);}else{A.setAttribute(j,m);}return A;}else{if(N(j)){for(var k in j){A.attr(k,j[k]);}return A;}return A.get(j)||A.getAttribute(j);}},clone:(function(){var A;if(U){A=function(){var i=this.getDOM();var k;if(i.nodeType!=3){var j=this.outerHTML();j=j.replace(B,'="$1">').replace(b,"");k=V.one(V.Node._prepareHTML(j)[0]);}else{k=V.one(i.cloneNode());}return k;};}else{A=function(){return this.cloneNode(true);};}return A;})(),center:function(m){var A=this;m=(m&&V.one(m))||V.getBody();var k=m.get("region");var j=A.get("region");var l=k.left+(k.width/2);var i=k.top+(k.height/2);A.setXY([l-(j.width/2),i-(j.height/2)]);},empty:function(){var A=this;A.all(">*").remove().purge();var i=V.Node.getDOMNode(A);while(i.firstChild){i.removeChild(i.firstChild);}return A;},getDOM:function(){var A=this;return V.Node.getDOMNode(A);},guid:function(j){var i=this;var A=i.get("id");if(!A){A=V.stamp(i);i.set("id",A);}return A;},hide:function(i){var A=this;A.addClass(i||A._hideClass||h);return A;},hover:function(j,i){var A=this;var k;var n=A._defaultHoverOptions;if(N(j,true)){k=j;k=V.mix(k,n);j=k.over;i=k.out;}else{k=V.mix({over:j,out:i},n);}A._hoverOptions=k;var m=new V.DelayedTask(A._hoverOverTaskFn,A);var l=new V.DelayedTask(A._hoverOutTaskFn,A);k.overTask=m;k.outTask=l;A.on(k.overEventType,A._hoverOverHandler,A);A.on(k.outEventType,A._hoverOutHandler,A);},html:function(){var A=arguments,i=A.length;if(i){this.set(Z,A[0]);}else{return this.get(Z);}return this;},outerHTML:function(){var A=this;var j=A.getDOM();if("outerHTML" in j){return j.outerHTML;}var i=V.Node.create("
").append(this.clone());try{return i.html();}catch(k){}finally{i=null;}},placeAfter:function(i){var A=this;return A._place(i,A.get(f));},placeBefore:function(i){var A=this;return A._place(i,A);},prependTo:function(i){var A=this;V.one(i).prepend(A);return A;},radioClass:function(i){var A=this;A.siblings().removeClass(i);A.addClass(i);return A;},resetId:function(i){var A=this;A.attr("id",V.guid(i));return A;},selectText:function(n,j){var A=this;var i=A.getDOM();var l=A.val().length;j=c(j)?j:l;n=c(n)?n:0;try{if(i.setSelectionRange){i.setSelectionRange(n,j);}else{if(i.createTextRange){var k=i.createTextRange();k.moveStart("character",n);k.moveEnd("character",j-l);k.select();}else{i.select();}}if(i!=document.activeElement){i.focus();}}catch(m){}return A;},selectable:function(){var A=this;A.getDOM().unselectable="off";A.detach("selectstart");A.setStyles({"MozUserSelect":"","KhtmlUserSelect":""});A.removeClass(X);return A;},show:function(i){var A=this;A.removeClass(i||A._hideClass||h);return A;},swallowEvent:function(i,j){var A=this;var k=function(l){l.stopPropagation();if(j){l.preventDefault();l.halt();}return false;};if(O(i)){V.Array.each(i,function(l){A.on(l,k);});return this;}else{A.on(i,k);}return A;},text:function(j){var A=this;var i=A.getDOM();if(!E(j)){j=V.DOM._getDoc(i).createTextNode(j);return A.empty().append(j);}return A._getText(i.childNodes);},toggle:function(i){var A=this;var j="hide";var k=i||A._hideClass||h;if(A.hasClass(k)){j="show";}A[j](k);return A;},unselectable:function(){var A=this;A.getDOM().unselectable="on";A.swallowEvent("selectstart",true);A.setStyles({"MozUserSelect":L,"KhtmlUserSelect":L});A.addClass(X);return A;},val:function(i){var A=this;if(E(i)){return A.get(H);}else{return A.set(H,i);}},_getText:function(n){var A=this;var l=n.length;var k;var m=[];for(var j=0;j"&&!s){o=A.childNodes;}}for(var n=o.length-1;n>=0;--n){var l=o[n];if(l.nodeName.toLowerCase()=="tbody"&&l.childNodes.length){l.parentNode.removeChild(l);}}}if(!C&&b.test(q)){A.insertBefore(r.createTextNode(b.exec(q)[0]),A.firstChild);}q=A.childNodes;}}if(q.nodeType){m.push(q);}else{m=q;}return m;};V.NodeList.importMethod(V.Node.prototype,["after","appendTo","attr","before","empty","hide","hover","html","outerHTML","prepend","prependTo","purge","selectText","selectable","show","text","toggle","unselectable","val"]);V.mix(V.NodeList.prototype,{all:function(k){var j=this;var o=[];var l=j._nodes;var n=l.length;var A;for(var m=0;m\s]+\/)>/g, + REGEX_XHTML_TAG = /(<([\w:]+)[^>]*?)\/>/g, + REGEX_SELF_CLOSING_ELEMENT = /^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i, + REGEX_TAGNAME = /<([\w:]+)/, + REGEX_TBODY = /'; + }; + + var MAP_WRAPPERS = { + _default: [0, STR_EMPTY, STR_EMPTY], + area: [1, '', ''], + col: [2, '', '
'], + legend: [1, '
', '
'], + option: [1, ''], + td: [3, '', '
'], + thead: [1, '', '
'], + tr: [2, '', '
'] + }; + + MAP_WRAPPERS.optgroup = MAP_WRAPPERS.option; + MAP_WRAPPERS.tbody = MAP_WRAPPERS.tfoot = MAP_WRAPPERS.colgroup = MAP_WRAPPERS.caption = MAP_WRAPPERS.thead; + MAP_WRAPPERS.th = MAP_WRAPPERS.td; + + if (!SUPPORT_SERIALIZE_HTML) { + MAP_WRAPPERS._default = [1, 'div
', '
']; + } + /** * Augment the YUI3 Node with more util methods. * @@ -215,13 +262,17 @@ A.mix(A.Node.prototype, { clone: (function() { var clone; - if (CLONED_EVENTS) { + if (SUPPORT_CLONED_EVENTS) { clone = function() { var el = this.getDOM(); var clone; if (el.nodeType != 3) { - clone = A.Node.create(this.outerHTML()) + var outerHTML = this.outerHTML(); + + outerHTML = outerHTML.replace(REGEX_IE8_ACTION, '="$1">').replace(REGEX_LEADING_WHITE_SPACE, ''); + + clone = A.one(A.Node._prepareHTML(outerHTML)[0]); } else { clone = A.one(el.cloneNode()); @@ -913,7 +964,7 @@ A.mix(A.Node.prototype, { var parent = instance.get(PARENT_NODE); if (parent) { - if (Lang.isString(newNode)) { + if (isString(newNode)) { newNode = A.Node.create(newNode); } @@ -933,6 +984,71 @@ A.mix(A.Node.prototype, { } }, true); +A.Node._prepareHTML = function(element) { + var doc = A.config.doc; + + var returnData = []; + + if (isString(element)) { + if (!REGEX_HTML.test(element)) { + element = doc.createTextNode(element); + } + else { + element = element.replace(REGEX_XHTML_TAG, FN_CLOSE_TAG); + + var tagName = (REGEX_TAGNAME.exec(element) || ARRAY_EMPTY_STRINGS)[1].toLowerCase(); + var wrap = MAP_WRAPPERS[tagName] || MAP_WRAPPERS._default; + var depth = wrap[0]; + var div = doc.createElement('div'); + + div.innerHTML = wrap[1] + element + wrap[2]; + + while (depth--) { + div = div.lastChild; + } + + if (!SUPPORT_OPTIONAL_TBODY) { + var hasTBody = REGEX_TBODY.test(element); + var tbody = []; + + if (tagName == 'table' && !hasTBody) { + if (div.firstChild) { + tbody = div.firstChild.childNodes; + } + } + else { + if (wrap[1] == '' && !hasTBody) { + tbody = div.childNodes; + } + } + + for (var i = tbody.length - 1; i >= 0; --i) { + var node = tbody[i]; + + if (node.nodeName.toLowerCase() == 'tbody' && node.childNodes.length) { + node.parentNode.removeChild(node); + } + } + } + + if (!SUPPORT_LEADING_WHITESPACE && REGEX_LEADING_WHITE_SPACE.test(element)) { + div.insertBefore(doc.createTextNode(REGEX_LEADING_WHITE_SPACE.exec(element)[0]), div.firstChild); + } + + element = div.childNodes; + } + } + + if (element.nodeType) { + returnData.push(element); + } + else { + returnData = element; + } + + return returnData; +}; + /** * Augment the YUI3 NodeList with more util methods. * diff --git a/src/aui-node/js/aui-node-base.js b/src/aui-node/js/aui-node-base.js index 9e231ecd482..81932e102c7 100644 --- a/src/aui-node/js/aui-node-base.js +++ b/src/aui-node/js/aui-node-base.js @@ -14,7 +14,9 @@ var Lang = A.Lang, getClassName = A.ClassNameManager.getClassName, - CLONED_EVENTS = false, + STR_EMPTY = '', + + ARRAY_EMPTY_STRINGS = [STR_EMPTY, STR_EMPTY], HELPER = 'helper', @@ -26,17 +28,25 @@ var Lang = A.Lang, NONE = 'none', PARENT_NODE = 'parentNode', SCRIPT = 'script', + + SUPPORT_CLONED_EVENTS = false, + VALUE = 'value'; - // Event cloning detection support based on pieces from jQuery + /* + Parts of this file are used from jQuery (http://jquery.com) + Dual-licensed under MIT/GPL + */ var div = document.createElement('div'); - div.innerHTML = ' '; // IE throws an error on fireEvent if the element does not have child nodes + + div.style.display = 'none'; + div.innerHTML = '
 '; if (div.attachEvent && div.fireEvent) { div.attachEvent( 'onclick', function(){ - CLONED_EVENTS = true; + SUPPORT_CLONED_EVENTS = true; div.detachEvent('onclick', arguments.callee); } @@ -45,6 +55,43 @@ var Lang = A.Lang, div.cloneNode(true).fireEvent('onclick'); } + var SUPPORT_SERIALIZE_HTML = !!div.getElementsByTagName('link').length, + SUPPORT_OPTIONAL_TBODY = !div.getElementsByTagName('tbody').length, + SUPPORT_LEADING_WHITESPACE = div.firstChild.nodeType === 3; + + var REGEX_LEADING_WHITE_SPACE = /^\s+/, + REGEX_IE8_ACTION = /=([^=\x27\x22>\s]+\/)>/g, + REGEX_XHTML_TAG = /(<([\w:]+)[^>]*?)\/>/g, + REGEX_SELF_CLOSING_ELEMENT = /^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i, + REGEX_TAGNAME = /<([\w:]+)/, + REGEX_TBODY = /'; + }; + + var MAP_WRAPPERS = { + _default: [0, STR_EMPTY, STR_EMPTY], + area: [1, '', ''], + col: [2, '', '
'], + legend: [1, '
', '
'], + option: [1, ''], + td: [3, '', '
'], + thead: [1, '', '
'], + tr: [2, '', '
'] + }; + + MAP_WRAPPERS.optgroup = MAP_WRAPPERS.option; + MAP_WRAPPERS.tbody = MAP_WRAPPERS.tfoot = MAP_WRAPPERS.colgroup = MAP_WRAPPERS.caption = MAP_WRAPPERS.thead; + MAP_WRAPPERS.th = MAP_WRAPPERS.td; + + if (!SUPPORT_SERIALIZE_HTML) { + MAP_WRAPPERS._default = [1, 'div
', '
']; + } + /** * Augment the YUI3 Node with more util methods. * @@ -214,13 +261,17 @@ A.mix(A.Node.prototype, { clone: (function() { var clone; - if (CLONED_EVENTS) { + if (SUPPORT_CLONED_EVENTS) { clone = function() { var el = this.getDOM(); var clone; if (el.nodeType != 3) { - clone = A.Node.create(this.outerHTML()) + var outerHTML = this.outerHTML(); + + outerHTML = outerHTML.replace(REGEX_IE8_ACTION, '="$1">').replace(REGEX_LEADING_WHITE_SPACE, ''); + + clone = A.one(A.Node._prepareHTML(outerHTML)[0]); } else { clone = A.one(el.cloneNode()); @@ -912,7 +963,7 @@ A.mix(A.Node.prototype, { var parent = instance.get(PARENT_NODE); if (parent) { - if (Lang.isString(newNode)) { + if (isString(newNode)) { newNode = A.Node.create(newNode); } @@ -932,6 +983,71 @@ A.mix(A.Node.prototype, { } }, true); +A.Node._prepareHTML = function(element) { + var doc = A.config.doc; + + var returnData = []; + + if (isString(element)) { + if (!REGEX_HTML.test(element)) { + element = doc.createTextNode(element); + } + else { + element = element.replace(REGEX_XHTML_TAG, FN_CLOSE_TAG); + + var tagName = (REGEX_TAGNAME.exec(element) || ARRAY_EMPTY_STRINGS)[1].toLowerCase(); + var wrap = MAP_WRAPPERS[tagName] || MAP_WRAPPERS._default; + var depth = wrap[0]; + var div = doc.createElement('div'); + + div.innerHTML = wrap[1] + element + wrap[2]; + + while (depth--) { + div = div.lastChild; + } + + if (!SUPPORT_OPTIONAL_TBODY) { + var hasTBody = REGEX_TBODY.test(element); + var tbody = []; + + if (tagName == 'table' && !hasTBody) { + if (div.firstChild) { + tbody = div.firstChild.childNodes; + } + } + else { + if (wrap[1] == '' && !hasTBody) { + tbody = div.childNodes; + } + } + + for (var i = tbody.length - 1; i >= 0; --i) { + var node = tbody[i]; + + if (node.nodeName.toLowerCase() == 'tbody' && node.childNodes.length) { + node.parentNode.removeChild(node); + } + } + } + + if (!SUPPORT_LEADING_WHITESPACE && REGEX_LEADING_WHITE_SPACE.test(element)) { + div.insertBefore(doc.createTextNode(REGEX_LEADING_WHITE_SPACE.exec(element)[0]), div.firstChild); + } + + element = div.childNodes; + } + } + + if (element.nodeType) { + returnData.push(element); + } + else { + returnData = element; + } + + return returnData; +}; + /** * Augment the YUI3 NodeList with more util methods. *