Permalink
Browse files

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
  • Loading branch information...
natecavanaugh committed Aug 10, 2010
1 parent 65ecdf3 commit 77c942c4be24ed396e7b76ecf4a767834f6d5fce
View
@@ -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.
-<http://creativecommons.org/licenses/by/3.0/>
+<http://creativecommons.org/licenses/by/3.0/>
+----------------------------------
+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.
@@ -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 = '&nbsp;'; // IE throws an error on fireEvent if the element does not have child nodes
+
+ div.style.display = 'none';
+ div.innerHTML = ' <link/><table></table>&nbsp;';
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 = /<tbody/i,
+ REGEX_HTML = /<|&#?\w+;/,
+
+ FN_CLOSE_TAG = function(all, start, tagName) {
+ return REGEX_SELF_CLOSING_ELEMENT.test(tagName)
+ ? all
+ : start + '></' + tagName + '>';
+ };
+
+ var MAP_WRAPPERS = {
+ _default: [0, STR_EMPTY, STR_EMPTY],
+ area: [1, '<map>', '</map>'],
+ col: [2, '<table><tbody></tbody><colgroup>', '</colgroup></table>'],
+ legend: [1, '<fieldset>', '</fieldset>'],
+ option: [1, '<select multiple="multiple">', '</select>'],
+ td: [3, '<table><tbody><tr>', '</tr></tbody></table>'],
+ thead: [1, '<table>', '</table>'],
+ tr: [2, '<table><tbody>', '</tbody></table>']
+ };
+
+ 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<div>', '</div>'];
+ }
+
/**
* Augment the <a href="Node.html">YUI3 Node</a> 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] == '<table>' && !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 <a href="NodeList.html">YUI3 NodeList</a> with more util methods.
*

Some generated files are not rendered by default. Learn more.

Oops, something went wrong.
Oops, something went wrong.

0 comments on commit 77c942c

Please sign in to comment.