2015-10-01 13:07:49 -04:00
|
|
|
var parse5 = require('parse5/index');
|
2015-03-01 16:17:36 -05:00
|
|
|
|
2016-04-28 20:50:03 -04:00
|
|
|
import {ListWrapper, StringMapWrapper} from '../src/facade/collection';
|
|
|
|
import {DomAdapter, setRootDomAdapter} from '../platform_browser_private';
|
2016-05-02 01:50:37 -04:00
|
|
|
import {isPresent, isBlank, global, Type, setValueOnPath, DateWrapper} from '../src/facade/lang';
|
2016-04-28 20:50:03 -04:00
|
|
|
import {BaseException} from '../src/facade/exceptions';
|
|
|
|
import {SelectorMatcher, CssSelector} from '../compiler_private';
|
|
|
|
import {XHR} from '@angular/compiler';
|
|
|
|
|
2016-06-08 18:45:15 -04:00
|
|
|
var parser: any /** TODO #9100 */ = null;
|
|
|
|
var serializer: any /** TODO #9100 */ = null;
|
|
|
|
var treeAdapter: any /** TODO #9100 */ = null;
|
2015-03-01 16:17:36 -05:00
|
|
|
|
2015-10-02 20:33:21 -04:00
|
|
|
var _attrToPropMap: {[key: string]: string} = {
|
2015-08-12 04:44:46 -04:00
|
|
|
'class': 'className',
|
2015-03-12 12:28:35 -04:00
|
|
|
'innerHtml': 'innerHTML',
|
2015-03-01 16:17:36 -05:00
|
|
|
'readonly': 'readOnly',
|
|
|
|
'tabindex': 'tabIndex',
|
|
|
|
};
|
2016-06-08 18:45:15 -04:00
|
|
|
var defDoc: any /** TODO #9100 */ = null;
|
2015-03-01 16:17:36 -05:00
|
|
|
|
2015-06-24 16:46:39 -04:00
|
|
|
var mapProps = ['attribs', 'x-attribsNamespace', 'x-attribsPrefix'];
|
|
|
|
|
2016-06-08 18:45:15 -04:00
|
|
|
function _notImplemented(methodName: any /** TODO #9100 */) {
|
2015-03-01 16:17:36 -05:00
|
|
|
return new BaseException('This method is not implemented in Parse5DomAdapter: ' + methodName);
|
|
|
|
}
|
|
|
|
|
2015-07-07 23:03:00 -04:00
|
|
|
/* tslint:disable:requireParameterType */
|
2015-03-01 16:17:36 -05:00
|
|
|
export class Parse5DomAdapter extends DomAdapter {
|
2016-04-28 20:50:03 -04:00
|
|
|
static makeCurrent() {
|
|
|
|
parser = new parse5.Parser(parse5.TreeAdapters.htmlparser2);
|
|
|
|
serializer = new parse5.Serializer(parse5.TreeAdapters.htmlparser2);
|
|
|
|
treeAdapter = parser.treeAdapter;
|
|
|
|
setRootDomAdapter(new Parse5DomAdapter());
|
|
|
|
}
|
2015-03-01 16:17:36 -05:00
|
|
|
|
2016-06-08 18:45:15 -04:00
|
|
|
hasProperty(element: any /** TODO #9100 */, name: string): boolean {
|
2015-06-26 14:10:52 -04:00
|
|
|
return _HTMLElementPropertyList.indexOf(name) > -1;
|
|
|
|
}
|
2015-06-18 18:44:44 -04:00
|
|
|
// TODO(tbosch): don't even call this method when we run the tests on server side
|
|
|
|
// by not using the DomRenderer in tests. Keeping this for now to make tests happy...
|
|
|
|
setProperty(el: /*element*/ any, name: string, value: any) {
|
|
|
|
if (name === 'innerHTML') {
|
|
|
|
this.setInnerHTML(el, value);
|
2015-08-12 04:44:46 -04:00
|
|
|
} else if (name === 'className') {
|
2016-06-08 19:38:52 -04:00
|
|
|
el.attribs['class'] = el.className = value;
|
2015-06-18 18:44:44 -04:00
|
|
|
} else {
|
|
|
|
el[name] = value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// TODO(tbosch): don't even call this method when we run the tests on server side
|
|
|
|
// by not using the DomRenderer in tests. Keeping this for now to make tests happy...
|
|
|
|
getProperty(el: /*element*/ any, name: string): any { return el[name]; }
|
|
|
|
|
2016-06-08 18:45:15 -04:00
|
|
|
logError(error: any /** TODO #9100 */) { console.error(error); }
|
2015-04-30 14:25:50 -04:00
|
|
|
|
2016-06-08 18:45:15 -04:00
|
|
|
log(error: any /** TODO #9100 */) { console.log(error); }
|
2015-07-23 21:00:19 -04:00
|
|
|
|
2016-06-08 18:45:15 -04:00
|
|
|
logGroup(error: any /** TODO #9100 */) { console.error(error); }
|
2015-07-23 21:00:19 -04:00
|
|
|
|
|
|
|
logGroupEnd() {}
|
|
|
|
|
2015-10-14 12:41:15 -04:00
|
|
|
getXHR(): Type { return XHR; }
|
|
|
|
|
2015-05-29 19:30:39 -04:00
|
|
|
get attrToPropMap() { return _attrToPropMap; }
|
2015-03-01 16:17:36 -05:00
|
|
|
|
2016-06-08 18:45:15 -04:00
|
|
|
query(selector: any /** TODO #9100 */) { throw _notImplemented('query'); }
|
2016-06-08 19:38:52 -04:00
|
|
|
querySelector(el: any /** TODO #9100 */, selector: string): any {
|
|
|
|
return this.querySelectorAll(el, selector)[0];
|
|
|
|
}
|
2016-06-08 18:45:15 -04:00
|
|
|
querySelectorAll(el: any /** TODO #9100 */, selector: string): any[] {
|
|
|
|
var res: any[] /** TODO #9100 */ = [];
|
2016-06-08 19:38:52 -04:00
|
|
|
var _recursive =
|
|
|
|
(result: any /** TODO #9100 */, node: any /** TODO #9100 */,
|
|
|
|
selector: any /** TODO #9100 */, matcher: any /** TODO #9100 */) => {
|
|
|
|
var cNodes = node.childNodes;
|
|
|
|
if (cNodes && cNodes.length > 0) {
|
|
|
|
for (var i = 0; i < cNodes.length; i++) {
|
|
|
|
var childNode = cNodes[i];
|
|
|
|
if (this.elementMatches(childNode, selector, matcher)) {
|
|
|
|
result.push(childNode);
|
|
|
|
}
|
|
|
|
_recursive(result, childNode, selector, matcher);
|
|
|
|
}
|
2015-05-28 17:58:24 -04:00
|
|
|
}
|
2016-06-08 19:38:52 -04:00
|
|
|
};
|
2015-03-09 12:41:49 -04:00
|
|
|
var matcher = new SelectorMatcher();
|
2015-03-19 12:01:42 -04:00
|
|
|
matcher.addSelectables(CssSelector.parse(selector));
|
2015-03-09 12:41:49 -04:00
|
|
|
_recursive(res, el, selector, matcher);
|
2015-03-01 16:17:36 -05:00
|
|
|
return res;
|
|
|
|
}
|
2016-06-08 19:38:52 -04:00
|
|
|
elementMatches(
|
|
|
|
node: any /** TODO #9100 */, selector: string,
|
|
|
|
matcher: any /** TODO #9100 */ = null): boolean {
|
2015-07-31 13:58:24 -04:00
|
|
|
if (this.isElementNode(node) && selector === '*') {
|
2015-07-29 20:41:09 -04:00
|
|
|
return true;
|
|
|
|
}
|
2015-03-09 12:41:49 -04:00
|
|
|
var result = false;
|
2016-06-08 19:38:52 -04:00
|
|
|
if (selector && selector.charAt(0) == '#') {
|
2015-03-09 12:41:49 -04:00
|
|
|
result = this.getAttribute(node, 'id') == selector.substring(1);
|
|
|
|
} else if (selector) {
|
|
|
|
var result = false;
|
|
|
|
if (matcher == null) {
|
|
|
|
matcher = new SelectorMatcher();
|
2015-03-19 12:01:42 -04:00
|
|
|
matcher.addSelectables(CssSelector.parse(selector));
|
2015-03-09 12:41:49 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
var cssSelector = new CssSelector();
|
|
|
|
cssSelector.setElement(this.tagName(node));
|
|
|
|
if (node.attribs) {
|
|
|
|
for (var attrName in node.attribs) {
|
|
|
|
cssSelector.addAttribute(attrName, node.attribs[attrName]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
var classList = this.classList(node);
|
|
|
|
for (var i = 0; i < classList.length; i++) {
|
|
|
|
cssSelector.addClassName(classList[i]);
|
|
|
|
}
|
|
|
|
|
2016-06-08 19:38:52 -04:00
|
|
|
matcher.match(
|
|
|
|
cssSelector,
|
|
|
|
function(selector: any /** TODO #9100 */, cb: any /** TODO #9100 */) { result = true; });
|
2015-03-09 12:41:49 -04:00
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
2016-06-08 18:45:15 -04:00
|
|
|
on(el: any /** TODO #9100 */, evt: any /** TODO #9100 */, listener: any /** TODO #9100 */) {
|
2015-10-02 19:47:54 -04:00
|
|
|
var listenersMap: {[k: /*any*/ string]: any} = el._eventListenersMap;
|
2015-04-21 13:30:55 -04:00
|
|
|
if (isBlank(listenersMap)) {
|
2015-10-02 19:47:54 -04:00
|
|
|
var listenersMap: {[k: /*any*/ string]: any} = StringMapWrapper.create();
|
2015-04-21 13:30:55 -04:00
|
|
|
el._eventListenersMap = listenersMap;
|
|
|
|
}
|
|
|
|
var listeners = StringMapWrapper.get(listenersMap, evt);
|
|
|
|
if (isBlank(listeners)) {
|
2015-06-17 14:17:21 -04:00
|
|
|
listeners = [];
|
2015-04-21 13:30:55 -04:00
|
|
|
}
|
2015-06-17 14:17:21 -04:00
|
|
|
listeners.push(listener);
|
2015-04-21 13:30:55 -04:00
|
|
|
StringMapWrapper.set(listenersMap, evt, listeners);
|
2015-03-01 16:17:36 -05:00
|
|
|
}
|
2016-06-08 19:38:52 -04:00
|
|
|
onAndCancel(
|
|
|
|
el: any /** TODO #9100 */, evt: any /** TODO #9100 */,
|
|
|
|
listener: any /** TODO #9100 */): Function {
|
2015-04-21 13:30:55 -04:00
|
|
|
this.on(el, evt, listener);
|
2015-05-29 19:30:39 -04:00
|
|
|
return () => {
|
2015-08-28 14:29:19 -04:00
|
|
|
ListWrapper.remove(StringMapWrapper.get<any[]>(el._eventListenersMap, evt), listener);
|
2015-05-29 19:30:39 -04:00
|
|
|
};
|
2015-04-02 09:56:58 -04:00
|
|
|
}
|
2016-06-08 18:45:15 -04:00
|
|
|
dispatchEvent(el: any /** TODO #9100 */, evt: any /** TODO #9100 */) {
|
2015-04-21 13:30:55 -04:00
|
|
|
if (isBlank(evt.target)) {
|
|
|
|
evt.target = el;
|
|
|
|
}
|
|
|
|
if (isPresent(el._eventListenersMap)) {
|
2015-05-29 19:30:39 -04:00
|
|
|
var listeners: any = StringMapWrapper.get(el._eventListenersMap, evt.type);
|
2015-04-21 13:30:55 -04:00
|
|
|
if (isPresent(listeners)) {
|
|
|
|
for (var i = 0; i < listeners.length; i++) {
|
|
|
|
listeners[i](evt);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (isPresent(el.parent)) {
|
|
|
|
this.dispatchEvent(el.parent, evt);
|
|
|
|
}
|
|
|
|
if (isPresent(el._window)) {
|
|
|
|
this.dispatchEvent(el._window, evt);
|
|
|
|
}
|
2015-03-01 16:17:36 -05:00
|
|
|
}
|
2016-06-08 18:45:15 -04:00
|
|
|
createMouseEvent(eventType: any /** TODO #9100 */): Event { return this.createEvent(eventType); }
|
2015-06-26 14:10:52 -04:00
|
|
|
createEvent(eventType: string): Event {
|
|
|
|
var evt = <Event>{
|
2015-05-29 19:30:39 -04:00
|
|
|
type: eventType,
|
|
|
|
defaultPrevented: false,
|
2016-04-10 16:24:41 -04:00
|
|
|
preventDefault: () => { (<any>evt).defaultPrevented = true; }
|
2015-05-29 19:30:39 -04:00
|
|
|
};
|
2015-05-06 21:30:37 -04:00
|
|
|
return evt;
|
2015-03-01 16:17:36 -05:00
|
|
|
}
|
2016-06-08 18:45:15 -04:00
|
|
|
preventDefault(evt: any /** TODO #9100 */) { evt.returnValue = false; }
|
2016-06-08 19:38:52 -04:00
|
|
|
isPrevented(evt: any /** TODO #9100 */): boolean {
|
|
|
|
return isPresent(evt.returnValue) && !evt.returnValue;
|
|
|
|
}
|
|
|
|
getInnerHTML(el: any /** TODO #9100 */): string {
|
|
|
|
return serializer.serialize(this.templateAwareRoot(el));
|
|
|
|
}
|
2016-06-08 18:45:15 -04:00
|
|
|
getTemplateContent(el: any /** TODO #9100 */): Node {
|
2016-04-30 22:02:05 -04:00
|
|
|
return null; // no <template> support in parse5.
|
|
|
|
}
|
2016-06-08 18:45:15 -04:00
|
|
|
getOuterHTML(el: any /** TODO #9100 */): string {
|
2015-03-01 16:17:36 -05:00
|
|
|
serializer.html = '';
|
|
|
|
serializer._serializeElement(el);
|
|
|
|
return serializer.html;
|
|
|
|
}
|
2016-06-08 18:45:15 -04:00
|
|
|
nodeName(node: any /** TODO #9100 */): string { return node.tagName; }
|
|
|
|
nodeValue(node: any /** TODO #9100 */): string { return node.nodeValue; }
|
2015-05-29 19:30:39 -04:00
|
|
|
type(node: any): string { throw _notImplemented('type'); }
|
2016-06-08 18:45:15 -04:00
|
|
|
content(node: any /** TODO #9100 */): string { return node.childNodes[0]; }
|
|
|
|
firstChild(el: any /** TODO #9100 */): Node { return el.firstChild; }
|
|
|
|
nextSibling(el: any /** TODO #9100 */): Node { return el.nextSibling; }
|
|
|
|
parentElement(el: any /** TODO #9100 */): Node { return el.parent; }
|
|
|
|
childNodes(el: any /** TODO #9100 */): Node[] { return el.childNodes; }
|
|
|
|
childNodesAsList(el: any /** TODO #9100 */): any[] {
|
2015-03-01 16:17:36 -05:00
|
|
|
var childNodes = el.childNodes;
|
|
|
|
var res = ListWrapper.createFixedSize(childNodes.length);
|
|
|
|
for (var i = 0; i < childNodes.length; i++) {
|
|
|
|
res[i] = childNodes[i];
|
|
|
|
}
|
|
|
|
return res;
|
|
|
|
}
|
2016-06-08 18:45:15 -04:00
|
|
|
clearNodes(el: any /** TODO #9100 */) {
|
2015-03-01 16:17:36 -05:00
|
|
|
while (el.childNodes.length > 0) {
|
|
|
|
this.remove(el.childNodes[0]);
|
|
|
|
}
|
|
|
|
}
|
2016-06-08 18:45:15 -04:00
|
|
|
appendChild(el: any /** TODO #9100 */, node: any /** TODO #9100 */) {
|
2015-03-01 16:17:36 -05:00
|
|
|
this.remove(node);
|
|
|
|
treeAdapter.appendChild(this.templateAwareRoot(el), node);
|
|
|
|
}
|
2016-06-08 18:45:15 -04:00
|
|
|
removeChild(el: any /** TODO #9100 */, node: any /** TODO #9100 */) {
|
2015-03-01 16:17:36 -05:00
|
|
|
if (ListWrapper.contains(el.childNodes, node)) {
|
|
|
|
this.remove(node);
|
|
|
|
}
|
|
|
|
}
|
2016-06-08 18:45:15 -04:00
|
|
|
remove(el: any /** TODO #9100 */): HTMLElement {
|
2015-03-01 16:17:36 -05:00
|
|
|
var parent = el.parent;
|
|
|
|
if (parent) {
|
|
|
|
var index = parent.childNodes.indexOf(el);
|
|
|
|
parent.childNodes.splice(index, 1);
|
|
|
|
}
|
|
|
|
var prev = el.previousSibling;
|
|
|
|
var next = el.nextSibling;
|
|
|
|
if (prev) {
|
|
|
|
prev.next = next;
|
|
|
|
}
|
|
|
|
if (next) {
|
|
|
|
next.prev = prev;
|
|
|
|
}
|
|
|
|
el.prev = null;
|
|
|
|
el.next = null;
|
|
|
|
el.parent = null;
|
|
|
|
return el;
|
|
|
|
}
|
2016-06-08 18:45:15 -04:00
|
|
|
insertBefore(el: any /** TODO #9100 */, node: any /** TODO #9100 */) {
|
2015-03-01 16:17:36 -05:00
|
|
|
this.remove(node);
|
|
|
|
treeAdapter.insertBefore(el.parent, node, el);
|
|
|
|
}
|
2016-06-08 19:38:52 -04:00
|
|
|
insertAllBefore(el: any /** TODO #9100 */, nodes: any /** TODO #9100 */) {
|
|
|
|
nodes.forEach((n: any /** TODO #9100 */) => this.insertBefore(el, n));
|
|
|
|
}
|
2016-06-08 18:45:15 -04:00
|
|
|
insertAfter(el: any /** TODO #9100 */, node: any /** TODO #9100 */) {
|
2015-03-01 16:17:36 -05:00
|
|
|
if (el.nextSibling) {
|
|
|
|
this.insertBefore(el.nextSibling, node);
|
|
|
|
} else {
|
|
|
|
this.appendChild(el.parent, node);
|
|
|
|
}
|
|
|
|
}
|
2016-06-08 18:45:15 -04:00
|
|
|
setInnerHTML(el: any /** TODO #9100 */, value: any /** TODO #9100 */) {
|
2015-03-01 16:17:36 -05:00
|
|
|
this.clearNodes(el);
|
|
|
|
var content = parser.parseFragment(value);
|
|
|
|
for (var i = 0; i < content.childNodes.length; i++) {
|
|
|
|
treeAdapter.appendChild(el, content.childNodes[i]);
|
|
|
|
}
|
|
|
|
}
|
2016-06-08 18:45:15 -04:00
|
|
|
getText(el: any /** TODO #9100 */, isRecursive?: boolean): string {
|
2015-03-01 16:17:36 -05:00
|
|
|
if (this.isTextNode(el)) {
|
|
|
|
return el.data;
|
2015-12-10 13:11:39 -05:00
|
|
|
} else if (this.isCommentNode(el)) {
|
|
|
|
// In the DOM, comments within an element return an empty string for textContent
|
|
|
|
// However, comment node instances return the comment content for textContent getter
|
|
|
|
return isRecursive ? '' : el.data;
|
2015-06-10 13:31:38 -04:00
|
|
|
} else if (isBlank(el.childNodes) || el.childNodes.length == 0) {
|
2016-06-08 19:38:52 -04:00
|
|
|
return '';
|
2015-03-01 16:17:36 -05:00
|
|
|
} else {
|
2016-06-08 19:38:52 -04:00
|
|
|
var textContent = '';
|
2015-03-01 16:17:36 -05:00
|
|
|
for (var i = 0; i < el.childNodes.length; i++) {
|
2015-12-10 13:11:39 -05:00
|
|
|
textContent += this.getText(el.childNodes[i], true);
|
2015-03-01 16:17:36 -05:00
|
|
|
}
|
|
|
|
return textContent;
|
|
|
|
}
|
|
|
|
}
|
2016-06-08 18:45:15 -04:00
|
|
|
setText(el: any /** TODO #9100 */, value: string) {
|
2015-12-10 13:11:39 -05:00
|
|
|
if (this.isTextNode(el) || this.isCommentNode(el)) {
|
2015-03-12 12:28:35 -04:00
|
|
|
el.data = value;
|
2015-03-01 16:17:36 -05:00
|
|
|
} else {
|
|
|
|
this.clearNodes(el);
|
2015-06-24 03:40:35 -04:00
|
|
|
if (value !== '') treeAdapter.insertText(el, value);
|
2015-03-01 16:17:36 -05:00
|
|
|
}
|
|
|
|
}
|
2016-06-08 18:45:15 -04:00
|
|
|
getValue(el: any /** TODO #9100 */): string { return el.value; }
|
|
|
|
setValue(el: any /** TODO #9100 */, value: string) { el.value = value; }
|
|
|
|
getChecked(el: any /** TODO #9100 */): boolean { return el.checked; }
|
|
|
|
setChecked(el: any /** TODO #9100 */, value: boolean) { el.checked = value; }
|
2015-07-29 20:41:09 -04:00
|
|
|
createComment(text: string): Comment { return treeAdapter.createCommentNode(text); }
|
2016-06-08 18:45:15 -04:00
|
|
|
createTemplate(html: any /** TODO #9100 */): HTMLElement {
|
2016-06-08 19:38:52 -04:00
|
|
|
var template = treeAdapter.createElement('template', 'http://www.w3.org/1999/xhtml', []);
|
2015-03-01 16:17:36 -05:00
|
|
|
var content = parser.parseFragment(html);
|
|
|
|
treeAdapter.appendChild(template, content);
|
|
|
|
return template;
|
|
|
|
}
|
2016-06-08 18:45:15 -04:00
|
|
|
createElement(tagName: any /** TODO #9100 */): HTMLElement {
|
2015-03-01 16:17:36 -05:00
|
|
|
return treeAdapter.createElement(tagName, 'http://www.w3.org/1999/xhtml', []);
|
|
|
|
}
|
2016-06-08 19:38:52 -04:00
|
|
|
createElementNS(ns: any /** TODO #9100 */, tagName: any /** TODO #9100 */): HTMLElement {
|
|
|
|
return treeAdapter.createElement(tagName, ns, []);
|
|
|
|
}
|
2015-09-25 12:43:21 -04:00
|
|
|
createTextNode(text: string): Text {
|
|
|
|
var t = <any>this.createComment(text);
|
|
|
|
t.type = 'text';
|
|
|
|
return t;
|
|
|
|
}
|
2015-06-26 14:10:52 -04:00
|
|
|
createScriptTag(attrName: string, attrValue: string): HTMLElement {
|
2016-06-08 19:38:52 -04:00
|
|
|
return treeAdapter.createElement(
|
|
|
|
'script', 'http://www.w3.org/1999/xhtml', [{name: attrName, value: attrValue}]);
|
2015-03-01 16:17:36 -05:00
|
|
|
}
|
2015-06-26 14:10:52 -04:00
|
|
|
createStyleElement(css: string): HTMLStyleElement {
|
2015-03-01 16:17:36 -05:00
|
|
|
var style = this.createElement('style');
|
|
|
|
this.setText(style, css);
|
2015-06-26 14:10:52 -04:00
|
|
|
return <HTMLStyleElement>style;
|
2015-03-01 16:17:36 -05:00
|
|
|
}
|
2016-06-08 18:45:15 -04:00
|
|
|
createShadowRoot(el: any /** TODO #9100 */): HTMLElement {
|
2015-03-01 16:17:36 -05:00
|
|
|
el.shadowRoot = treeAdapter.createDocumentFragment();
|
|
|
|
el.shadowRoot.parent = el;
|
|
|
|
return el.shadowRoot;
|
|
|
|
}
|
2016-06-08 18:45:15 -04:00
|
|
|
getShadowRoot(el: any /** TODO #9100 */): Element { return el.shadowRoot; }
|
|
|
|
getHost(el: any /** TODO #9100 */): string { return el.host; }
|
2015-08-28 14:29:19 -04:00
|
|
|
getDistributedNodes(el: any): Node[] { throw _notImplemented('getDistributedNodes'); }
|
2015-06-26 14:10:52 -04:00
|
|
|
clone(node: Node): Node {
|
2016-06-08 18:45:15 -04:00
|
|
|
var _recursive = (node: any /** TODO #9100 */) => {
|
2015-06-24 16:46:39 -04:00
|
|
|
var nodeClone = Object.create(Object.getPrototypeOf(node));
|
|
|
|
for (var prop in node) {
|
|
|
|
var desc = Object.getOwnPropertyDescriptor(node, prop);
|
|
|
|
if (desc && 'value' in desc && typeof desc.value !== 'object') {
|
|
|
|
nodeClone[prop] = node[prop];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
nodeClone.parent = null;
|
|
|
|
nodeClone.prev = null;
|
|
|
|
nodeClone.next = null;
|
|
|
|
nodeClone.children = null;
|
|
|
|
|
|
|
|
mapProps.forEach(mapName => {
|
|
|
|
if (isPresent(node[mapName])) {
|
|
|
|
nodeClone[mapName] = {};
|
|
|
|
for (var prop in node[mapName]) {
|
|
|
|
nodeClone[mapName][prop] = node[mapName][prop];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
var cNodes = node.children;
|
|
|
|
if (cNodes) {
|
|
|
|
var cNodesClone = new Array(cNodes.length);
|
|
|
|
for (var i = 0; i < cNodes.length; i++) {
|
|
|
|
var childNode = cNodes[i];
|
|
|
|
var childNodeClone = _recursive(childNode);
|
|
|
|
cNodesClone[i] = childNodeClone;
|
|
|
|
if (i > 0) {
|
|
|
|
childNodeClone.prev = cNodesClone[i - 1];
|
|
|
|
cNodesClone[i - 1].next = childNodeClone;
|
|
|
|
}
|
|
|
|
childNodeClone.parent = nodeClone;
|
|
|
|
}
|
|
|
|
nodeClone.children = cNodesClone;
|
|
|
|
}
|
|
|
|
return nodeClone;
|
|
|
|
};
|
|
|
|
return _recursive(node);
|
2015-03-01 16:17:36 -05:00
|
|
|
}
|
2016-06-08 18:45:15 -04:00
|
|
|
getElementsByClassName(element: any /** TODO #9100 */, name: string): HTMLElement[] {
|
2016-06-08 19:38:52 -04:00
|
|
|
return this.querySelectorAll(element, '.' + name);
|
2015-03-01 16:17:36 -05:00
|
|
|
}
|
2015-08-28 14:29:19 -04:00
|
|
|
getElementsByTagName(element: any, name: string): HTMLElement[] {
|
2015-03-01 16:17:36 -05:00
|
|
|
throw _notImplemented('getElementsByTagName');
|
|
|
|
}
|
2016-06-08 18:45:15 -04:00
|
|
|
classList(element: any /** TODO #9100 */): string[] {
|
|
|
|
var classAttrValue: any /** TODO #9100 */ = null;
|
2015-03-01 16:17:36 -05:00
|
|
|
var attributes = element.attribs;
|
2016-06-08 19:38:52 -04:00
|
|
|
if (attributes && attributes.hasOwnProperty('class')) {
|
|
|
|
classAttrValue = attributes['class'];
|
2015-03-01 16:17:36 -05:00
|
|
|
}
|
|
|
|
return classAttrValue ? classAttrValue.trim().split(/\s+/g) : [];
|
|
|
|
}
|
2016-06-08 18:45:15 -04:00
|
|
|
addClass(element: any /** TODO #9100 */, className: string) {
|
2015-03-01 16:17:36 -05:00
|
|
|
var classList = this.classList(element);
|
2015-11-18 19:17:49 -05:00
|
|
|
var index = classList.indexOf(className);
|
2015-03-01 16:17:36 -05:00
|
|
|
if (index == -1) {
|
2015-11-18 19:17:49 -05:00
|
|
|
classList.push(className);
|
2016-06-08 19:38:52 -04:00
|
|
|
element.attribs['class'] = element.className = classList.join(' ');
|
2015-03-01 16:17:36 -05:00
|
|
|
}
|
|
|
|
}
|
2016-06-08 18:45:15 -04:00
|
|
|
removeClass(element: any /** TODO #9100 */, className: string) {
|
2015-03-01 16:17:36 -05:00
|
|
|
var classList = this.classList(element);
|
2015-11-18 19:17:49 -05:00
|
|
|
var index = classList.indexOf(className);
|
2015-03-01 16:17:36 -05:00
|
|
|
if (index > -1) {
|
|
|
|
classList.splice(index, 1);
|
2016-06-08 19:38:52 -04:00
|
|
|
element.attribs['class'] = element.className = classList.join(' ');
|
2015-03-01 16:17:36 -05:00
|
|
|
}
|
|
|
|
}
|
2016-06-08 18:45:15 -04:00
|
|
|
hasClass(element: any /** TODO #9100 */, className: string): boolean {
|
2015-11-18 19:17:49 -05:00
|
|
|
return ListWrapper.contains(this.classList(element), className);
|
2015-03-01 16:17:36 -05:00
|
|
|
}
|
2016-06-08 18:45:15 -04:00
|
|
|
hasStyle(element: any /** TODO #9100 */, styleName: string, styleValue: string = null): boolean {
|
2015-11-18 18:59:25 -05:00
|
|
|
var value = this.getStyle(element, styleName) || '';
|
|
|
|
return styleValue ? value == styleValue : value.length > 0;
|
2015-11-17 15:37:39 -05:00
|
|
|
}
|
2015-10-09 20:21:25 -04:00
|
|
|
/** @internal */
|
2016-06-08 18:45:15 -04:00
|
|
|
_readStyleAttribute(element: any /** TODO #9100 */) {
|
2015-03-01 16:17:36 -05:00
|
|
|
var styleMap = {};
|
|
|
|
var attributes = element.attribs;
|
2016-06-08 19:38:52 -04:00
|
|
|
if (attributes && attributes.hasOwnProperty('style')) {
|
|
|
|
var styleAttrValue = attributes['style'];
|
2015-03-01 16:17:36 -05:00
|
|
|
var styleList = styleAttrValue.split(/;+/g);
|
|
|
|
for (var i = 0; i < styleList.length; i++) {
|
|
|
|
if (styleList[i].length > 0) {
|
|
|
|
var elems = styleList[i].split(/:+/g);
|
2016-06-08 18:45:15 -04:00
|
|
|
(styleMap as any /** TODO #9100 */)[elems[0].trim()] = elems[1].trim();
|
2015-03-01 16:17:36 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return styleMap;
|
|
|
|
}
|
2015-10-09 20:21:25 -04:00
|
|
|
/** @internal */
|
2016-06-08 18:45:15 -04:00
|
|
|
_writeStyleAttribute(element: any /** TODO #9100 */, styleMap: any /** TODO #9100 */) {
|
2016-06-08 19:38:52 -04:00
|
|
|
var styleAttrValue = '';
|
2015-03-01 16:17:36 -05:00
|
|
|
for (var key in styleMap) {
|
|
|
|
var newValue = styleMap[key];
|
|
|
|
if (newValue && newValue.length > 0) {
|
2016-06-08 19:38:52 -04:00
|
|
|
styleAttrValue += key + ':' + styleMap[key] + ';';
|
2015-03-01 16:17:36 -05:00
|
|
|
}
|
|
|
|
}
|
2016-06-08 19:38:52 -04:00
|
|
|
element.attribs['style'] = styleAttrValue;
|
2015-03-01 16:17:36 -05:00
|
|
|
}
|
2016-06-08 18:45:15 -04:00
|
|
|
setStyle(element: any /** TODO #9100 */, styleName: string, styleValue: string) {
|
2015-03-01 16:17:36 -05:00
|
|
|
var styleMap = this._readStyleAttribute(element);
|
2016-06-08 18:45:15 -04:00
|
|
|
(styleMap as any /** TODO #9100 */)[styleName] = styleValue;
|
2015-03-01 16:17:36 -05:00
|
|
|
this._writeStyleAttribute(element, styleMap);
|
|
|
|
}
|
2016-06-08 19:38:52 -04:00
|
|
|
removeStyle(element: any /** TODO #9100 */, styleName: string) {
|
|
|
|
this.setStyle(element, styleName, null);
|
|
|
|
}
|
2016-06-08 18:45:15 -04:00
|
|
|
getStyle(element: any /** TODO #9100 */, styleName: string): string {
|
2015-03-01 16:17:36 -05:00
|
|
|
var styleMap = this._readStyleAttribute(element);
|
2016-06-08 19:38:52 -04:00
|
|
|
return styleMap.hasOwnProperty(styleName) ? (styleMap as any /** TODO #9100 */)[styleName] : '';
|
|
|
|
}
|
|
|
|
tagName(element: any /** TODO #9100 */): string {
|
|
|
|
return element.tagName == 'style' ? 'STYLE' : element.tagName;
|
2015-03-01 16:17:36 -05:00
|
|
|
}
|
2016-06-08 18:45:15 -04:00
|
|
|
attributeMap(element: any /** TODO #9100 */): Map<string, string> {
|
2015-09-29 14:11:06 -04:00
|
|
|
var res = new Map<string, string>();
|
2015-03-01 16:17:36 -05:00
|
|
|
var elAttrs = treeAdapter.getAttrList(element);
|
|
|
|
for (var i = 0; i < elAttrs.length; i++) {
|
|
|
|
var attrib = elAttrs[i];
|
2015-06-17 19:21:40 -04:00
|
|
|
res.set(attrib.name, attrib.value);
|
2015-03-01 16:17:36 -05:00
|
|
|
}
|
|
|
|
return res;
|
|
|
|
}
|
2016-06-08 18:45:15 -04:00
|
|
|
hasAttribute(element: any /** TODO #9100 */, attribute: string): boolean {
|
2015-05-01 07:41:56 -04:00
|
|
|
return element.attribs && element.attribs.hasOwnProperty(attribute);
|
|
|
|
}
|
2016-06-08 19:38:52 -04:00
|
|
|
hasAttributeNS(element: any /** TODO #9100 */, ns: string, attribute: string): boolean {
|
|
|
|
throw 'not implemented';
|
|
|
|
}
|
2016-06-08 18:45:15 -04:00
|
|
|
getAttribute(element: any /** TODO #9100 */, attribute: string): string {
|
2015-05-29 19:30:39 -04:00
|
|
|
return element.attribs && element.attribs.hasOwnProperty(attribute) ?
|
2016-06-08 19:38:52 -04:00
|
|
|
element.attribs[attribute] :
|
|
|
|
null;
|
|
|
|
}
|
|
|
|
getAttributeNS(element: any /** TODO #9100 */, ns: string, attribute: string): string {
|
|
|
|
throw 'not implemented';
|
2015-03-01 16:17:36 -05:00
|
|
|
}
|
2016-06-08 18:45:15 -04:00
|
|
|
setAttribute(element: any /** TODO #9100 */, attribute: string, value: string) {
|
2015-03-01 16:17:36 -05:00
|
|
|
if (attribute) {
|
|
|
|
element.attribs[attribute] = value;
|
2015-09-25 12:43:21 -04:00
|
|
|
if (attribute === 'class') {
|
|
|
|
element.className = value;
|
|
|
|
}
|
2015-03-01 16:17:36 -05:00
|
|
|
}
|
|
|
|
}
|
2016-06-08 19:38:52 -04:00
|
|
|
setAttributeNS(element: any /** TODO #9100 */, ns: string, attribute: string, value: string) {
|
|
|
|
throw 'not implemented';
|
|
|
|
}
|
2016-06-08 18:45:15 -04:00
|
|
|
removeAttribute(element: any /** TODO #9100 */, attribute: string) {
|
2015-03-01 16:17:36 -05:00
|
|
|
if (attribute) {
|
2015-05-29 19:30:39 -04:00
|
|
|
StringMapWrapper.delete(element.attribs, attribute);
|
2015-03-01 16:17:36 -05:00
|
|
|
}
|
|
|
|
}
|
2016-06-08 19:38:52 -04:00
|
|
|
removeAttributeNS(element: any /** TODO #9100 */, ns: string, name: string) {
|
|
|
|
throw 'not implemented';
|
|
|
|
}
|
|
|
|
templateAwareRoot(el: any /** TODO #9100 */): any {
|
|
|
|
return this.isTemplateElement(el) ? this.content(el) : el;
|
|
|
|
}
|
2015-06-26 14:10:52 -04:00
|
|
|
createHtmlDocument(): Document {
|
2015-04-16 12:44:34 -04:00
|
|
|
var newDoc = treeAdapter.createDocument();
|
2016-06-08 19:38:52 -04:00
|
|
|
newDoc.title = 'fake title';
|
|
|
|
var head = treeAdapter.createElement('head', null, []);
|
|
|
|
var body = treeAdapter.createElement('body', 'http://www.w3.org/1999/xhtml', []);
|
2015-04-16 12:44:34 -04:00
|
|
|
this.appendChild(newDoc, head);
|
|
|
|
this.appendChild(newDoc, body);
|
2016-06-08 19:38:52 -04:00
|
|
|
StringMapWrapper.set(newDoc, 'head', head);
|
|
|
|
StringMapWrapper.set(newDoc, 'body', body);
|
|
|
|
StringMapWrapper.set(newDoc, '_window', StringMapWrapper.create());
|
2015-04-16 12:44:34 -04:00
|
|
|
return newDoc;
|
2015-03-01 16:17:36 -05:00
|
|
|
}
|
2015-06-26 14:10:52 -04:00
|
|
|
defaultDoc(): Document {
|
2015-03-01 16:17:36 -05:00
|
|
|
if (defDoc === null) {
|
2015-04-16 12:44:34 -04:00
|
|
|
defDoc = this.createHtmlDocument();
|
2015-03-01 16:17:36 -05:00
|
|
|
}
|
|
|
|
return defDoc;
|
|
|
|
}
|
2016-06-08 19:38:52 -04:00
|
|
|
getBoundingClientRect(el: any /** TODO #9100 */): any {
|
|
|
|
return {left: 0, top: 0, width: 0, height: 0};
|
|
|
|
}
|
|
|
|
getTitle(): string { return this.defaultDoc().title || ''; }
|
2015-05-29 19:30:39 -04:00
|
|
|
setTitle(newTitle: string) { this.defaultDoc().title = newTitle; }
|
|
|
|
isTemplateElement(el: any): boolean {
|
2016-06-08 19:38:52 -04:00
|
|
|
return this.isElementNode(el) && this.tagName(el) === 'template';
|
2015-03-01 16:17:36 -05:00
|
|
|
}
|
2016-06-08 18:45:15 -04:00
|
|
|
isTextNode(node: any /** TODO #9100 */): boolean { return treeAdapter.isTextNode(node); }
|
|
|
|
isCommentNode(node: any /** TODO #9100 */): boolean { return treeAdapter.isCommentNode(node); }
|
2016-06-08 19:38:52 -04:00
|
|
|
isElementNode(node: any /** TODO #9100 */): boolean {
|
|
|
|
return node ? treeAdapter.isElementNode(node) : false;
|
|
|
|
}
|
2016-06-08 18:45:15 -04:00
|
|
|
hasShadowRoot(node: any /** TODO #9100 */): boolean { return isPresent(node.shadowRoot); }
|
|
|
|
isShadowRoot(node: any /** TODO #9100 */): boolean { return this.getShadowRoot(node) == node; }
|
|
|
|
importIntoDoc(node: any /** TODO #9100 */): any { return this.clone(node); }
|
|
|
|
adoptNode(node: any /** TODO #9100 */): any { return node; }
|
|
|
|
getHref(el: any /** TODO #9100 */): string { return el.href; }
|
|
|
|
resolveAndSetHref(el: any /** TODO #9100 */, baseUrl: string, href: string) {
|
2015-03-01 16:17:36 -05:00
|
|
|
if (href == null) {
|
|
|
|
el.href = baseUrl;
|
|
|
|
} else {
|
2015-10-01 13:07:49 -04:00
|
|
|
el.href = baseUrl + '/../' + href;
|
2015-03-01 16:17:36 -05:00
|
|
|
}
|
|
|
|
}
|
2015-10-09 20:21:25 -04:00
|
|
|
/** @internal */
|
2016-06-08 18:45:15 -04:00
|
|
|
_buildRules(parsedRules: any /** TODO #9100 */, css?: any /** TODO #9100 */) {
|
|
|
|
var rules: any[] /** TODO #9100 */ = [];
|
2015-03-01 16:17:36 -05:00
|
|
|
for (var i = 0; i < parsedRules.length; i++) {
|
|
|
|
var parsedRule = parsedRules[i];
|
2015-10-02 19:47:54 -04:00
|
|
|
var rule: {[key: string]: any} = StringMapWrapper.create();
|
2016-06-08 19:38:52 -04:00
|
|
|
StringMapWrapper.set(rule, 'cssText', css);
|
|
|
|
StringMapWrapper.set(rule, 'style', {content: '', cssText: ''});
|
|
|
|
if (parsedRule.type == 'rule') {
|
|
|
|
StringMapWrapper.set(rule, 'type', 1);
|
|
|
|
StringMapWrapper.set(
|
|
|
|
rule, 'selectorText', parsedRule.selectors.join(', ')
|
|
|
|
.replace(/\s{2,}/g, ' ')
|
|
|
|
.replace(/\s*~\s*/g, ' ~ ')
|
|
|
|
.replace(/\s*\+\s*/g, ' + ')
|
|
|
|
.replace(/\s*>\s*/g, ' > ')
|
|
|
|
.replace(/\[(\w+)=(\w+)\]/g, '[$1="$2"]'));
|
2015-03-01 16:17:36 -05:00
|
|
|
if (isBlank(parsedRule.declarations)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
for (var j = 0; j < parsedRule.declarations.length; j++) {
|
|
|
|
var declaration = parsedRule.declarations[j];
|
2016-06-08 19:38:52 -04:00
|
|
|
StringMapWrapper.set(
|
|
|
|
StringMapWrapper.get(rule, 'style'), declaration.property, declaration.value);
|
|
|
|
StringMapWrapper.get(rule, 'style').cssText +=
|
|
|
|
declaration.property + ': ' + declaration.value + ';';
|
2015-03-12 12:28:35 -04:00
|
|
|
}
|
2016-06-08 19:38:52 -04:00
|
|
|
} else if (parsedRule.type == 'media') {
|
|
|
|
StringMapWrapper.set(rule, 'type', 4);
|
|
|
|
StringMapWrapper.set(rule, 'media', {mediaText: parsedRule.media});
|
2015-03-01 16:17:36 -05:00
|
|
|
if (parsedRule.rules) {
|
2016-06-08 19:38:52 -04:00
|
|
|
StringMapWrapper.set(rule, 'cssRules', this._buildRules(parsedRule.rules));
|
2015-03-01 16:17:36 -05:00
|
|
|
}
|
|
|
|
}
|
2015-06-17 14:17:21 -04:00
|
|
|
rules.push(rule);
|
2015-03-01 16:17:36 -05:00
|
|
|
}
|
|
|
|
return rules;
|
|
|
|
}
|
2015-05-29 19:30:39 -04:00
|
|
|
supportsDOMEvents(): boolean { return false; }
|
|
|
|
supportsNativeShadowDOM(): boolean { return false; }
|
2015-06-26 14:10:52 -04:00
|
|
|
getGlobalEventTarget(target: string): any {
|
2016-06-08 19:38:52 -04:00
|
|
|
if (target == 'window') {
|
2015-06-26 14:10:52 -04:00
|
|
|
return (<any>this.defaultDoc())._window;
|
2016-06-08 19:38:52 -04:00
|
|
|
} else if (target == 'document') {
|
2015-04-21 13:30:55 -04:00
|
|
|
return this.defaultDoc();
|
2016-06-08 19:38:52 -04:00
|
|
|
} else if (target == 'body') {
|
2015-04-21 13:30:55 -04:00
|
|
|
return this.defaultDoc().body;
|
|
|
|
}
|
|
|
|
}
|
2015-08-12 01:17:39 -04:00
|
|
|
getBaseHref(): string { throw 'not implemented'; }
|
|
|
|
resetBaseElement(): void { throw 'not implemented'; }
|
2015-06-26 14:10:52 -04:00
|
|
|
getHistory(): History { throw 'not implemented'; }
|
|
|
|
getLocation(): Location { throw 'not implemented'; }
|
2016-06-08 19:38:52 -04:00
|
|
|
getUserAgent(): string { return 'Fake user agent'; }
|
|
|
|
getData(el: any /** TODO #9100 */, name: string): string {
|
|
|
|
return this.getAttribute(el, 'data-' + name);
|
|
|
|
}
|
2016-06-08 18:45:15 -04:00
|
|
|
getComputedStyle(el: any /** TODO #9100 */): any { throw 'not implemented'; }
|
2016-06-08 19:38:52 -04:00
|
|
|
setData(el: any /** TODO #9100 */, name: string, value: string) {
|
|
|
|
this.setAttribute(el, 'data-' + name, value);
|
|
|
|
}
|
2015-05-28 17:56:40 -04:00
|
|
|
// TODO(tbosch): move this into a separate environment class once we have it
|
2015-08-28 13:36:58 -04:00
|
|
|
setGlobalVar(path: string, value: any) { setValueOnPath(global, path, value); }
|
2016-06-08 18:45:15 -04:00
|
|
|
requestAnimationFrame(callback: any /** TODO #9100 */): number { return setTimeout(callback, 0); }
|
2015-08-28 17:39:34 -04:00
|
|
|
cancelAnimationFrame(id: number) { clearTimeout(id); }
|
2016-05-31 12:15:17 -04:00
|
|
|
supportsWebAnimation(): boolean { return false; }
|
2015-09-09 06:23:04 -04:00
|
|
|
performanceNow(): number { return DateWrapper.toMillis(DateWrapper.now()); }
|
2015-09-17 18:49:56 -04:00
|
|
|
getAnimationPrefix(): string { return ''; }
|
|
|
|
getTransitionEnd(): string { return 'transitionend'; }
|
|
|
|
supportsAnimation(): boolean { return true; }
|
2015-09-25 17:48:17 -04:00
|
|
|
|
2016-06-08 19:38:52 -04:00
|
|
|
replaceChild(
|
|
|
|
el: any /** TODO #9100 */, newNode: any /** TODO #9100 */, oldNode: any /** TODO #9100 */) {
|
|
|
|
throw new Error('not implemented');
|
|
|
|
}
|
2015-09-25 17:48:17 -04:00
|
|
|
parse(templateHtml: string) { throw new Error('not implemented'); }
|
|
|
|
invoke(el: Element, methodName: string, args: any[]): any { throw new Error('not implemented'); }
|
2016-06-08 18:45:15 -04:00
|
|
|
getEventKey(event: any /** TODO #9100 */): string { throw new Error('not implemented'); }
|
2016-05-27 23:15:40 -04:00
|
|
|
|
|
|
|
supportsCookies(): boolean { return false; }
|
|
|
|
getCookie(name: string): string { throw new Error('not implemented'); }
|
|
|
|
setCookie(name: string, value: string) { throw new Error('not implemented'); }
|
2016-05-31 12:15:17 -04:00
|
|
|
animate(element: any, keyframes: any[], options: any): any { throw new Error('not implemented'); }
|
2015-03-01 16:17:36 -05:00
|
|
|
}
|
|
|
|
|
2015-05-29 19:30:39 -04:00
|
|
|
// TODO: build a proper list, this one is all the keys of a HTMLInputElement
|
|
|
|
var _HTMLElementPropertyList = [
|
2016-06-08 19:38:52 -04:00
|
|
|
'webkitEntries',
|
|
|
|
'incremental',
|
|
|
|
'webkitdirectory',
|
|
|
|
'selectionDirection',
|
|
|
|
'selectionEnd',
|
|
|
|
'selectionStart',
|
|
|
|
'labels',
|
|
|
|
'validationMessage',
|
|
|
|
'validity',
|
|
|
|
'willValidate',
|
|
|
|
'width',
|
|
|
|
'valueAsNumber',
|
|
|
|
'valueAsDate',
|
|
|
|
'value',
|
|
|
|
'useMap',
|
|
|
|
'defaultValue',
|
|
|
|
'type',
|
|
|
|
'step',
|
|
|
|
'src',
|
|
|
|
'size',
|
|
|
|
'required',
|
|
|
|
'readOnly',
|
|
|
|
'placeholder',
|
|
|
|
'pattern',
|
|
|
|
'name',
|
|
|
|
'multiple',
|
|
|
|
'min',
|
|
|
|
'minLength',
|
|
|
|
'maxLength',
|
|
|
|
'max',
|
|
|
|
'list',
|
|
|
|
'indeterminate',
|
|
|
|
'height',
|
|
|
|
'formTarget',
|
|
|
|
'formNoValidate',
|
|
|
|
'formMethod',
|
|
|
|
'formEnctype',
|
|
|
|
'formAction',
|
|
|
|
'files',
|
|
|
|
'form',
|
|
|
|
'disabled',
|
|
|
|
'dirName',
|
|
|
|
'checked',
|
|
|
|
'defaultChecked',
|
|
|
|
'autofocus',
|
|
|
|
'autocomplete',
|
|
|
|
'alt',
|
|
|
|
'align',
|
|
|
|
'accept',
|
|
|
|
'onautocompleteerror',
|
|
|
|
'onautocomplete',
|
|
|
|
'onwaiting',
|
|
|
|
'onvolumechange',
|
|
|
|
'ontoggle',
|
|
|
|
'ontimeupdate',
|
|
|
|
'onsuspend',
|
|
|
|
'onsubmit',
|
|
|
|
'onstalled',
|
|
|
|
'onshow',
|
|
|
|
'onselect',
|
|
|
|
'onseeking',
|
|
|
|
'onseeked',
|
|
|
|
'onscroll',
|
|
|
|
'onresize',
|
|
|
|
'onreset',
|
|
|
|
'onratechange',
|
|
|
|
'onprogress',
|
|
|
|
'onplaying',
|
|
|
|
'onplay',
|
|
|
|
'onpause',
|
|
|
|
'onmousewheel',
|
|
|
|
'onmouseup',
|
|
|
|
'onmouseover',
|
|
|
|
'onmouseout',
|
|
|
|
'onmousemove',
|
|
|
|
'onmouseleave',
|
|
|
|
'onmouseenter',
|
|
|
|
'onmousedown',
|
|
|
|
'onloadstart',
|
|
|
|
'onloadedmetadata',
|
|
|
|
'onloadeddata',
|
|
|
|
'onload',
|
|
|
|
'onkeyup',
|
|
|
|
'onkeypress',
|
|
|
|
'onkeydown',
|
|
|
|
'oninvalid',
|
|
|
|
'oninput',
|
|
|
|
'onfocus',
|
|
|
|
'onerror',
|
|
|
|
'onended',
|
|
|
|
'onemptied',
|
|
|
|
'ondurationchange',
|
|
|
|
'ondrop',
|
|
|
|
'ondragstart',
|
|
|
|
'ondragover',
|
|
|
|
'ondragleave',
|
|
|
|
'ondragenter',
|
|
|
|
'ondragend',
|
|
|
|
'ondrag',
|
|
|
|
'ondblclick',
|
|
|
|
'oncuechange',
|
|
|
|
'oncontextmenu',
|
|
|
|
'onclose',
|
|
|
|
'onclick',
|
|
|
|
'onchange',
|
|
|
|
'oncanplaythrough',
|
|
|
|
'oncanplay',
|
|
|
|
'oncancel',
|
|
|
|
'onblur',
|
|
|
|
'onabort',
|
|
|
|
'spellcheck',
|
|
|
|
'isContentEditable',
|
|
|
|
'contentEditable',
|
|
|
|
'outerText',
|
|
|
|
'innerText',
|
|
|
|
'accessKey',
|
|
|
|
'hidden',
|
|
|
|
'webkitdropzone',
|
|
|
|
'draggable',
|
|
|
|
'tabIndex',
|
|
|
|
'dir',
|
|
|
|
'translate',
|
|
|
|
'lang',
|
|
|
|
'title',
|
|
|
|
'childElementCount',
|
|
|
|
'lastElementChild',
|
|
|
|
'firstElementChild',
|
|
|
|
'children',
|
|
|
|
'onwebkitfullscreenerror',
|
|
|
|
'onwebkitfullscreenchange',
|
|
|
|
'nextElementSibling',
|
|
|
|
'previousElementSibling',
|
|
|
|
'onwheel',
|
|
|
|
'onselectstart',
|
|
|
|
'onsearch',
|
|
|
|
'onpaste',
|
|
|
|
'oncut',
|
|
|
|
'oncopy',
|
|
|
|
'onbeforepaste',
|
|
|
|
'onbeforecut',
|
|
|
|
'onbeforecopy',
|
|
|
|
'shadowRoot',
|
|
|
|
'dataset',
|
|
|
|
'classList',
|
|
|
|
'className',
|
|
|
|
'outerHTML',
|
|
|
|
'innerHTML',
|
|
|
|
'scrollHeight',
|
|
|
|
'scrollWidth',
|
|
|
|
'scrollTop',
|
|
|
|
'scrollLeft',
|
|
|
|
'clientHeight',
|
|
|
|
'clientWidth',
|
|
|
|
'clientTop',
|
|
|
|
'clientLeft',
|
|
|
|
'offsetParent',
|
|
|
|
'offsetHeight',
|
|
|
|
'offsetWidth',
|
|
|
|
'offsetTop',
|
|
|
|
'offsetLeft',
|
|
|
|
'localName',
|
|
|
|
'prefix',
|
|
|
|
'namespaceURI',
|
|
|
|
'id',
|
|
|
|
'style',
|
|
|
|
'attributes',
|
|
|
|
'tagName',
|
|
|
|
'parentElement',
|
|
|
|
'textContent',
|
|
|
|
'baseURI',
|
|
|
|
'ownerDocument',
|
|
|
|
'nextSibling',
|
|
|
|
'previousSibling',
|
|
|
|
'lastChild',
|
|
|
|
'firstChild',
|
|
|
|
'childNodes',
|
|
|
|
'parentNode',
|
|
|
|
'nodeType',
|
|
|
|
'nodeValue',
|
|
|
|
'nodeName',
|
|
|
|
'closure_lm_714617',
|
|
|
|
'__jsaction'
|
2015-05-29 19:30:39 -04:00
|
|
|
];
|