6 description: One of the most important items in MooTools. Contains the dollar function, the dollars function, and an handful of cross-browser, time-saver methods to let you easily work with HTML Elements.
8 license: MIT-style license.
10 requires: [Window, Document, Array, String, Function, Object, Number, Slick.Parser, Slick.Finder]
12 provides: [Element, Elements, $, $$, IFrame, Selectors]
17 var Element = this.Element = function(tag, props){
18 var konstructor = Element.Constructors[tag];
19 if (konstructor) return konstructor(props);
20 if (typeof tag != 'string') return document.id(tag).set(props);
22 if (!props) props = {};
24 if (!(/^[\w-]+$/).test(tag)){
25 var parsed = Slick.parse(tag).expressions[0][0];
26 tag = (parsed.tag == '*') ? 'div' : parsed.tag;
27 if (parsed.id && props.id == null) props.id = parsed.id;
29 var attributes = parsed.attributes;
30 if (attributes) for (var attr, i = 0, l = attributes.length; i < l; i++){
32 if (props[attr.key] != null) continue;
34 if (attr.value != null && attr.operator == '=') props[attr.key] = attr.value;
35 else if (!attr.value && !attr.operator) props[attr.key] = true;
38 if (parsed.classList && props['class'] == null) props['class'] = parsed.classList.join(' ');
41 return document.newElement(tag, props);
46 Element.prototype = Browser.Element.prototype;
47 // IE8 and IE9 require the wrapping.
48 Element.prototype._fireEvent = (function(fireEvent){
49 return function(type, event){
50 return fireEvent.call(this, type, event);
52 })(Element.prototype.fireEvent);
55 new Type('Element', Element).mirror(function(name){
56 if (Array.prototype[name]) return;
59 obj[name] = function(){
60 var results = [], args = arguments, elements = true;
61 for (var i = 0, l = this.length; i < l; i++){
62 var element = this[i], result = results[i] = element[name].apply(element, args);
63 elements = (elements && typeOf(result) == 'element');
65 return (elements) ? new Elements(results) : results;
68 Elements.implement(obj);
71 if (!Browser.Element){
72 Element.parent = Object;
75 '$constructor': Element,
76 '$family': Function.from('element').hide()
79 Element.mirror(function(name, method){
80 Element.Prototype[name] = method;
84 Element.Constructors = {};
88 Element.Constructors = new Hash;
92 var IFrame = new Type('IFrame', function(){
93 var params = Array.link(arguments, {
94 properties: Type.isObject,
95 iframe: function(obj){
100 var props = params.properties || {}, iframe;
101 if (params.iframe) iframe = document.id(params.iframe);
102 var onload = props.onload || function(){};
104 props.id = props.name = [props.id, props.name, iframe ? (iframe.id || iframe.name) : 'IFrame_' + String.uniqueID()].pick();
105 iframe = new Element(iframe || 'iframe', props);
107 var onLoad = function(){
108 onload.call(iframe.contentWindow);
111 if (window.frames[props.id]) onLoad();
112 else iframe.addListener('load', onLoad);
116 var Elements = this.Elements = function(nodes){
117 if (nodes && nodes.length){
118 var uniques = {}, node;
119 for (var i = 0; node = nodes[i++];){
120 var uid = Slick.uidOf(node);
129 Elements.prototype = {length: 0};
130 Elements.parent = Array;
132 new Type('Elements', Elements).implement({
134 filter: function(filter, bind){
135 if (!filter) return this;
136 return new Elements(Array.filter(this, (typeOf(filter) == 'string') ? function(item){
137 return item.match(filter);
142 var length = this.length;
143 for (var i = 0, l = arguments.length; i < l; i++){
144 var item = document.id(arguments[i]);
145 if (item) this[length++] = item;
147 return (this.length = length);
152 for (var i = 0, l = arguments.length; i < l; i++){
153 var item = document.id(arguments[i]);
154 if (item) items.push(item);
156 return Array.prototype.unshift.apply(this, items);
160 var newElements = new Elements(this);
161 for (var i = 0, l = arguments.length; i < l; i++){
162 var item = arguments[i];
163 if (Type.isEnumerable(item)) newElements.append(item);
164 else newElements.push(item);
169 append: function(collection){
170 for (var i = 0, l = collection.length; i < l; i++) this.push(collection[i]);
175 while (this.length) delete this[--this.length];
183 Elements.alias('extend', 'append');
190 var splice = Array.prototype.splice, object = {'0': 0, '1': 1, length: 2};
192 splice.call(object, 1, 1);
193 if (object[1] == 1) Elements.implement('splice', function(){
194 var length = this.length;
195 var result = splice.apply(this, arguments);
196 while (length >= this.length) delete this[length--];
200 Array.forEachMethod(function(method, name){
201 Elements.implement(name, method);
204 Array.mirror(Elements);
207 var createElementAcceptsHTML;
209 createElementAcceptsHTML = (document.createElement('<input name=x>').name == 'x');
212 var escapeQuotes = function(html){
213 return ('' + html).replace(/&/g, '&').replace(/"/g, '"');
218 // #2479 - IE8 Cannot set HTML of style element
219 var canChangeStyleHTML = (function(){
220 var div = document.createElement('style'),
223 div.innerHTML = '#justTesing{margin: 0px;}';
224 flag = !!div.innerHTML;
232 newElement: function(tag, props){
234 if (props.checked != null) props.defaultChecked = props.checked;
235 if ((props.type == 'checkbox' || props.type == 'radio') && props.value == null) props.value = 'on';
236 /*<ltIE9>*/ // IE needs the type to be set before changing content of style element
237 if (!canChangeStyleHTML && tag == 'style'){
238 var styleElement = document.createElement('style');
239 styleElement.setAttribute('type', 'text/css');
240 if (props.type) delete props.type;
241 return this.id(styleElement).set(props);
244 /*<ltIE8>*/// Fix for readonly name and type properties in IE < 8
245 if (createElementAcceptsHTML){
247 if (props.name) tag += ' name="' + escapeQuotes(props.name) + '"';
248 if (props.type) tag += ' type="' + escapeQuotes(props.type) + '"';
255 return this.id(this.createElement(tag)).set(props);
265 Slick.uidOf(document);
269 newTextNode: function(text){
270 return this.createTextNode(text);
273 getDocument: function(){
277 getWindow: function(){
285 string: function(id, nocash, doc){
286 id = Slick.find(doc, '#' + id.replace(/(\W)/g, '\\$1'));
287 return (id) ? types.element(id, nocash) : null;
290 element: function(el, nocash){
292 if (!nocash && !el.$family && !(/^(?:object|embed)$/i).test(el.tagName)){
293 var fireEvent = el.fireEvent;
294 // wrapping needed in IE7, or else crash
295 el._fireEvent = function(type, event){
296 return fireEvent(type, event);
298 Object.append(el, Element.Prototype);
303 object: function(obj, nocash, doc){
304 if (obj.toElement) return types.element(obj.toElement(doc), nocash);
310 types.textnode = types.whitespace = types.window = types.document = function(zero){
314 return function(el, nocash, doc){
315 if (el && el.$family && el.uniqueNumber) return el;
316 var type = typeOf(el);
317 return (types[type]) ? types[type](el, nocash, doc || document) : null;
324 if (window.$ == null) Window.implement('$', function(el, nc){
325 return document.id(el, nc, this.document);
330 getDocument: function(){
331 return this.document;
334 getWindow: function(){
340 [Document, Element].invoke('implement', {
342 getElements: function(expression){
343 return Slick.search(this, expression, new Elements);
346 getElement: function(expression){
347 return document.id(Slick.find(this, expression));
352 var contains = {contains: function(element){
353 return Slick.contains(this, element);
356 if (!document.contains) Document.implement(contains);
357 if (!document.createElement('div').contains) Element.implement(contains);
361 Element.implement('hasChild', function(element){
362 return this !== element && this.contains(element);
365 (function(search, find, match){
368 var pseudos = this.Selectors.Pseudo = new Hash();
370 var addSlickPseudos = function(){
371 for (var name in pseudos) if (pseudos.hasOwnProperty(name)){
372 Slick.definePseudo(name, pseudos[name]);
373 delete pseudos[name];
377 Slick.search = function(context, expression, append){
379 return search.call(this, context, expression, append);
382 Slick.find = function(context, expression){
384 return find.call(this, context, expression);
387 Slick.match = function(node, selector){
389 return match.call(this, node, selector);
392 })(Slick.search, Slick.find, Slick.match);
398 var injectCombinator = function(expression, combinator){
399 if (!expression) return combinator;
401 expression = Object.clone(Slick.parse(expression));
403 var expressions = expression.expressions;
404 for (var i = expressions.length; i--;)
405 expressions[i][0].combinator = combinator;
414 }, function(combinator, method){
415 Element.implement(method, function(expression){
416 return this.getElement(injectCombinator(expression, combinator));
422 getAllPrevious: '!~',
426 }, function(combinator, method){
427 Element.implement(method, function(expression){
428 return this.getElements(injectCombinator(expression, combinator));
434 getFirst: function(expression){
435 return document.id(Slick.search(this, injectCombinator(expression, '>'))[0]);
438 getLast: function(expression){
439 return document.id(Slick.search(this, injectCombinator(expression, '>')).getLast());
442 getWindow: function(){
443 return this.ownerDocument.window;
446 getDocument: function(){
447 return this.ownerDocument;
450 getElementById: function(id){
451 return document.id(Slick.find(this, '#' + ('' + id).replace(/(\W)/g, '\\$1')));
454 match: function(expression){
455 return !expression || Slick.match(this, expression);
462 if (window.$$ == null) Window.implement('$$', function(selector){
463 var elements = new Elements;
464 if (arguments.length == 1 && typeof selector == 'string') return Slick.search(this.document, selector, elements);
465 var args = Array.flatten(arguments);
466 for (var i = 0, l = args.length; i < l; i++){
468 switch (typeOf(item)){
469 case 'element': elements.push(item); break;
470 case 'string': Slick.search(this.document, item, elements);
478 if (window.$$ == null) Window.implement('$$', function(selector){
479 if (arguments.length == 1){
480 if (typeof selector == 'string') return Slick.search(this.document, selector, new Elements);
481 else if (Type.isEnumerable(selector)) return new Elements(selector);
483 return new Elements(arguments);
490 before: function(context, element){
491 var parent = element.parentNode;
492 if (parent) parent.insertBefore(context, element);
495 after: function(context, element){
496 var parent = element.parentNode;
497 if (parent) parent.insertBefore(context, element.nextSibling);
500 bottom: function(context, element){
501 element.appendChild(context);
504 top: function(context, element){
505 element.insertBefore(context, element.firstChild);
510 inserters.inside = inserters.bottom;
514 Object.each(inserters, function(inserter, where){
516 where = where.capitalize();
520 methods['inject' + where] = function(el){
521 inserter(this, document.id(el, true));
525 methods['grab' + where] = function(el){
526 inserter(document.id(el, true), this);
530 Element.implement(methods);
536 // getProperty / setProperty
538 var propertyGetters = {}, propertySetters = {};
544 'type', 'value', 'defaultValue', 'accessKey', 'cellPadding', 'cellSpacing', 'colSpan',
545 'frameBorder', 'rowSpan', 'tabIndex', 'useMap'
546 ], function(property){
547 properties[property.toLowerCase()] = property;
550 properties.html = 'innerHTML';
551 properties.text = (document.createElement('div').textContent == null) ? 'innerText': 'textContent';
553 Object.forEach(properties, function(real, key){
554 propertySetters[key] = function(node, value){
557 propertyGetters[key] = function(node){
563 propertySetters.text = (function(setter){
564 return function(node, value){
565 if (node.get('tag') == 'style') node.set('html', value);
566 else node[properties.text] = value;
568 })(propertySetters.text);
570 propertyGetters.text = (function(getter){
571 return function(node){
572 return (node.get('tag') == 'style') ? node.innerHTML : getter(node);
574 })(propertyGetters.text);
580 'compact', 'nowrap', 'ismap', 'declare', 'noshade', 'checked',
581 'disabled', 'readOnly', 'multiple', 'selected', 'noresize',
582 'defer', 'defaultChecked', 'autofocus', 'controls', 'autoplay',
587 Array.forEach(bools, function(bool){
588 var lower = bool.toLowerCase();
589 booleans[lower] = bool;
590 propertySetters[lower] = function(node, value){
591 node[bool] = !!value;
593 propertyGetters[lower] = function(node){
600 Object.append(propertySetters, {
602 'class': function(node, value){
603 ('className' in node) ? node.className = (value || '') : node.setAttribute('class', value);
606 'for': function(node, value){
607 ('htmlFor' in node) ? node.htmlFor = value : node.setAttribute('for', value);
610 'style': function(node, value){
611 (node.style) ? node.style.cssText = value : node.setAttribute('style', value);
614 'value': function(node, value){
615 node.value = (value != null) ? value : '';
620 propertyGetters['class'] = function(node){
621 return ('className' in node) ? node.className || null : node.getAttribute('class');
625 var el = document.createElement('button');
626 // IE sets type as readonly and throws
627 try { el.type = 'button'; } catch(e){}
628 if (el.type != 'button') propertySetters.type = function(node, value){
629 node.setAttribute('type', value);
637 // #2479 - IE8 Cannot set HTML of style element
638 var canChangeStyleHTML = (function(){
639 var div = document.createElement('style'),
642 div.innerHTML = '#justTesing{margin: 0px;}';
643 flag = !!div.innerHTML;
649 var input = document.createElement('input'), volatileInputValue, html5InputSupport;
653 input.type = 'submit';
654 volatileInputValue = input.value != 't';
656 // #2443 - IE throws "Invalid Argument" when trying to use html5 input types
658 input.type = 'email';
659 html5InputSupport = input.type == 'email';
664 if (volatileInputValue || !html5InputSupport) propertySetters.type = function(node, type){
666 var value = node.value;
673 /* getProperty, setProperty */
676 var pollutesGetAttribute = (function(div){
677 div.random = 'attribute';
678 return (div.getAttribute('random') == 'attribute');
679 })(document.createElement('div'));
681 var hasCloneBug = (function(test){
682 test.innerHTML = '<object><param name="should_fix" value="the unknown" /></object>';
683 return test.cloneNode(true).firstChild.childNodes.length != 1;
684 })(document.createElement('div'));
687 var hasClassList = !!document.createElement('div').classList;
689 var classes = function(className){
690 var classNames = (className || '').clean().split(" "), uniques = {};
691 return classNames.filter(function(className){
692 if (className !== "" && !uniques[className]) return uniques[className] = className;
696 var addToClassList = function(name){
697 this.classList.add(name);
700 var removeFromClassList = function(name){
701 this.classList.remove(name);
706 setProperty: function(name, value){
707 var setter = propertySetters[name.toLowerCase()];
712 var attributeWhiteList;
713 if (pollutesGetAttribute) attributeWhiteList = this.retrieve('$attributeWhiteList', {});
717 this.removeAttribute(name);
719 if (pollutesGetAttribute) delete attributeWhiteList[name];
722 this.setAttribute(name, '' + value);
724 if (pollutesGetAttribute) attributeWhiteList[name] = true;
731 setProperties: function(attributes){
732 for (var attribute in attributes) this.setProperty(attribute, attributes[attribute]);
736 getProperty: function(name){
737 var getter = propertyGetters[name.toLowerCase()];
738 if (getter) return getter(this);
740 if (pollutesGetAttribute){
741 var attr = this.getAttributeNode(name), attributeWhiteList = this.retrieve('$attributeWhiteList', {});
742 if (!attr) return null;
743 if (attr.expando && !attributeWhiteList[name]){
744 var outer = this.outerHTML;
745 // segment by the opening tag and find mention of attribute name
746 if (outer.substr(0, outer.search(/\/?['"]?>(?![^<]*<['"])/)).indexOf(name) < 0) return null;
747 attributeWhiteList[name] = true;
751 var result = Slick.getAttribute(this, name);
752 return (!result && !Slick.hasAttribute(this, name)) ? null : result;
755 getProperties: function(){
756 var args = Array.from(arguments);
757 return args.map(this.getProperty, this).associate(args);
760 removeProperty: function(name){
761 return this.setProperty(name, null);
764 removeProperties: function(){
765 Array.each(arguments, this.removeProperty, this);
769 set: function(prop, value){
770 var property = Element.Properties[prop];
771 (property && property.set) ? property.set.call(this, value) : this.setProperty(prop, value);
775 var property = Element.Properties[prop];
776 return (property && property.get) ? property.get.apply(this) : this.getProperty(prop);
779 erase: function(prop){
780 var property = Element.Properties[prop];
781 (property && property.erase) ? property.erase.apply(this) : this.removeProperty(prop);
785 hasClass: hasClassList ? function(className){
786 return this.classList.contains(className);
787 } : function(className){
788 return classes(this.className).contains(className);
791 addClass: hasClassList ? function(className){
792 classes(className).forEach(addToClassList, this);
794 } : function(className){
795 this.className = classes(className + ' ' + this.className).join(' ');
799 removeClass: hasClassList ? function(className){
800 classes(className).forEach(removeFromClassList, this);
802 } : function(className){
803 var classNames = classes(this.className);
804 classes(className).forEach(classNames.erase, classNames);
805 this.className = classNames.join(' ');
809 toggleClass: function(className, force){
810 if (force == null) force = !this.hasClass(className);
811 return (force) ? this.addClass(className) : this.removeClass(className);
815 var parent = this, fragment, elements = Array.flatten(arguments), length = elements.length;
816 if (length > 1) parent = fragment = document.createDocumentFragment();
818 for (var i = 0; i < length; i++){
819 var element = document.id(elements[i], true);
820 if (element) parent.appendChild(element);
823 if (fragment) this.appendChild(fragment);
828 appendText: function(text, where){
829 return this.grab(this.getDocument().newTextNode(text), where);
832 grab: function(el, where){
833 inserters[where || 'bottom'](document.id(el, true), this);
837 inject: function(el, where){
838 inserters[where || 'bottom'](this, document.id(el, true));
842 replaces: function(el){
843 el = document.id(el, true);
844 el.parentNode.replaceChild(this, el);
848 wraps: function(el, where){
849 el = document.id(el, true);
850 return this.replaces(el).grab(el, where);
853 getSelected: function(){
854 this.selectedIndex; // Safari 3.2.1
855 return new Elements(Array.from(this.options).filter(function(option){
856 return option.selected;
860 toQueryString: function(){
861 var queryString = [];
862 this.getElements('input, select, textarea').each(function(el){
864 if (!el.name || el.disabled || type == 'submit' || type == 'reset' || type == 'file' || type == 'image') return;
866 var value = (el.get('tag') == 'select') ? el.getSelected().map(function(opt){
868 return document.id(opt).get('value');
869 }) : ((type == 'radio' || type == 'checkbox') && !el.checked) ? null : el.get('value');
871 Array.from(value).each(function(val){
872 if (typeof val != 'undefined') queryString.push(encodeURIComponent(el.name) + '=' + encodeURIComponent(val));
875 return queryString.join('&');
883 var appendInserters = {
884 before: 'beforeBegin',
891 Element.implement('appendHTML', ('insertAdjacentHTML' in document.createElement('div')) ? function(html, where){
892 this.insertAdjacentHTML(appendInserters[where || 'bottom'], html);
894 } : function(html, where){
895 var temp = new Element('div', {html: html}),
896 children = temp.childNodes,
897 fragment = temp.firstChild;
899 if (!fragment) return this;
900 if (children.length > 1){
901 fragment = document.createDocumentFragment();
902 for (var i = 0, l = children.length; i < l; i++){
903 fragment.appendChild(children[i]);
907 inserters[where || 'bottom'](fragment, this);
911 var collected = {}, storage = {};
913 var get = function(uid){
914 return (storage[uid] || (storage[uid] = {}));
917 var clean = function(item){
918 var uid = item.uniqueNumber;
919 if (item.removeEvents) item.removeEvents();
920 if (item.clearAttributes) item.clearAttributes();
922 delete collected[uid];
928 var formProps = {input: 'checked', option: 'selected', textarea: 'value'};
933 var children = clean(this).getElementsByTagName('*');
934 Array.each(children, clean);
935 Element.dispose(this);
940 Array.from(this.childNodes).each(Element.dispose);
945 return (this.parentNode) ? this.parentNode.removeChild(this) : this;
948 clone: function(contents, keepid){
949 contents = contents !== false;
950 var clone = this.cloneNode(contents), ce = [clone], te = [this], i;
953 ce.append(Array.from(clone.getElementsByTagName('*')));
954 te.append(Array.from(this.getElementsByTagName('*')));
957 for (i = ce.length; i--;){
958 var node = ce[i], element = te[i];
959 if (!keepid) node.removeAttribute('id');
961 if (node.clearAttributes){
962 node.clearAttributes();
963 node.mergeAttributes(element);
964 node.removeAttribute('uniqueNumber');
966 var no = node.options, eo = element.options;
967 for (var j = no.length; j--;) no[j].selected = eo[j].selected;
971 var prop = formProps[element.tagName.toLowerCase()];
972 if (prop && element[prop]) node[prop] = element[prop];
977 var co = clone.getElementsByTagName('object'), to = this.getElementsByTagName('object');
978 for (i = co.length; i--;) co[i].outerHTML = to[i].outerHTML;
981 return document.id(clone);
986 [Element, Window, Document].invoke('implement', {
988 addListener: function(type, fn){
989 if (window.attachEvent && !window.addEventListener){
990 collected[Slick.uidOf(this)] = this;
992 if (this.addEventListener) this.addEventListener(type, fn, !!arguments[2]);
993 else this.attachEvent('on' + type, fn);
997 removeListener: function(type, fn){
998 if (this.removeEventListener) this.removeEventListener(type, fn, !!arguments[2]);
999 else this.detachEvent('on' + type, fn);
1003 retrieve: function(property, dflt){
1004 var storage = get(Slick.uidOf(this)), prop = storage[property];
1005 if (dflt != null && prop == null) prop = storage[property] = dflt;
1006 return prop != null ? prop : null;
1009 store: function(property, value){
1010 var storage = get(Slick.uidOf(this));
1011 storage[property] = value;
1015 eliminate: function(property){
1016 var storage = get(Slick.uidOf(this));
1017 delete storage[property];
1024 if (window.attachEvent && !window.addEventListener){
1025 var gc = function(){
1026 Object.each(collected, clean);
1027 if (window.CollectGarbage) CollectGarbage();
1028 window.removeListener('unload', gc);
1030 window.addListener('unload', gc);
1034 Element.Properties = {};
1038 Element.Properties = new Hash;
1042 Element.Properties.style = {
1044 set: function(style){
1045 this.style.cssText = style;
1049 return this.style.cssText;
1053 this.style.cssText = '';
1058 Element.Properties.tag = {
1061 return this.tagName.toLowerCase();
1066 Element.Properties.html = {
1068 set: function(html){
1069 if (html == null) html = '';
1070 else if (typeOf(html) == 'array') html = html.join('');
1073 if (this.styleSheet && !canChangeStyleHTML) this.styleSheet.cssText = html;
1074 else /*</ltIE9>*/this.innerHTML = html;
1077 this.set('html', '');
1082 var supportsHTML5Elements = true, supportsTableInnerHTML = true, supportsTRInnerHTML = true;
1085 // technique by jdbarlett - http://jdbartlett.com/innershiv/
1086 var div = document.createElement('div');
1087 div.innerHTML = '<nav></nav>';
1088 supportsHTML5Elements = (div.childNodes.length == 1);
1089 if (!supportsHTML5Elements){
1090 var tags = 'abbr article aside audio canvas datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video'.split(' '),
1091 fragment = document.createDocumentFragment(), l = tags.length;
1092 while (l--) fragment.createElement(tags[l]);
1098 supportsTableInnerHTML = Function.attempt(function(){
1099 var table = document.createElement('table');
1100 table.innerHTML = '<tr><td></td></tr>';
1105 var tr = document.createElement('tr'), html = '<td></td>';
1106 tr.innerHTML = html;
1107 supportsTRInnerHTML = (tr.innerHTML == html);
1111 if (!supportsTableInnerHTML || !supportsTRInnerHTML || !supportsHTML5Elements){
1113 Element.Properties.html.set = (function(set){
1115 var translations = {
1116 table: [1, '<table>', '</table>'],
1117 select: [1, '<select>', '</select>'],
1118 tbody: [2, '<table><tbody>', '</tbody></table>'],
1119 tr: [3, '<table><tbody><tr>', '</tr></tbody></table>']
1122 translations.thead = translations.tfoot = translations.tbody;
1124 return function(html){
1127 if (this.styleSheet) return set.call(this, html);
1129 var wrap = translations[this.get('tag')];
1130 if (!wrap && !supportsHTML5Elements) wrap = [0, '', ''];
1131 if (!wrap) return set.call(this, html);
1133 var level = wrap[0], wrapper = document.createElement('div'), target = wrapper;
1134 if (!supportsHTML5Elements) fragment.appendChild(wrapper);
1135 wrapper.innerHTML = [wrap[1], html, wrap[2]].flatten().join('');
1136 while (level--) target = target.firstChild;
1137 this.empty().adopt(target.childNodes);
1138 if (!supportsHTML5Elements) fragment.removeChild(wrapper);
1142 })(Element.Properties.html.set);
1147 var testForm = document.createElement('form');
1148 testForm.innerHTML = '<select><option>s</option></select>';
1150 if (testForm.firstChild.value != 's') Element.Properties.value = {
1152 set: function(value){
1153 var tag = this.get('tag');
1154 if (tag != 'select') return this.setProperty('value', value);
1155 var options = this.getElements('option');
1156 value = String(value);
1157 for (var i = 0; i < options.length; i++){
1158 var option = options[i],
1159 attr = option.getAttributeNode('value'),
1160 optionValue = (attr && attr.specified) ? option.value : option.get('text');
1161 if (optionValue === value) return option.selected = true;
1166 var option = this, tag = option.get('tag');
1168 if (tag != 'select' && tag != 'option') return this.getProperty('value');
1170 if (tag == 'select' && !(option = option.getSelected()[0])) return '';
1172 var attr = option.getAttributeNode('value');
1173 return (attr && attr.specified) ? option.value : option.get('text');
1181 if (document.createElement('div').getAttributeNode('id')) Element.Properties.id = {
1183 this.id = this.getAttributeNode('id').value = id;
1186 return this.id || null;
1189 this.id = this.getAttributeNode('id').value = '';