// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. /** * Custom DOM elements. * * This library provides access to the Polymer project's * [Custom Elements] * (http://www.polymer-project.org/platform/custom-elements.html) * API, which lets you define your own elements. With custom elements, you * associate code with custom tag names, and then use those custom tag names * as you would any standard tag. For more information, see the * [Polymer.dart homepage](https://www.dartlang.org/polymer-dart/) and its * [custom element example] * (https://www.dartlang.org/polymer-dart/#custom-elements). */ library custom_element; import 'dart:async'; import 'dart:html'; import 'src/custom_tag_name.dart'; /** * *Deprecated* -- do not use. Extend [HtmlElement] and use * [document.register] instead. If running on a browser without native * document.register, you can add the polyfill script to your page: * * * * You can also use "custom-elements.min.js" for the minified version. */ // This is only used by Dart Web UI. class CustomElement implements Element { /** The web component element wrapped by this class. */ Element _host; List _shadowRoots; /** * Shadow roots generated by dwc for each custom element, indexed by the * custom element tag name. */ Map _generatedRoots = {}; /** * Temporary property until components extend [Element]. An element can * only be associated with one host, and it is an error to use a web component * without an associated host element. */ Element get host { if (_host == null) throw new StateError('host element has not been set.'); return _host; } set host(Element value) { if (value == null) { throw new ArgumentError('host must not be null.'); } // TODO(jmesserly): xtag used to return "null" if unset, now it checks for // "this". Temporarily allow both. var xtag = value.xtag; if (xtag != null && xtag != value) { throw new ArgumentError('host must not have its xtag property set.'); } if (_host != null) { throw new StateError('host can only be set once.'); } value.xtag = this; _host = value; } /** * **Note**: This is an implementation helper and should not need to be called * from your code. * * Creates the [ShadowRoot] backing this component. */ createShadowRoot([String componentName]) { var root = host.createShadowRoot(); if (componentName != null) { _generatedRoots[componentName] = root; } return root; } getShadowRoot(String componentName) => _generatedRoots[componentName]; /** * Invoked when this component gets created. * Note that [root] will be a [ShadowRoot] if the browser supports Shadow DOM. */ void created() {} // Added for analyzer warnings @deprecated void createdCallback() {} /** Invoked when this component gets inserted in the DOM tree. */ void inserted() {} @deprecated void enteredView() {} /** Invoked when this component is removed from the DOM tree. */ void removed() {} @deprecated void leftView() {} /** Invoked when any attribute of the component is modified. */ void attributeChanged(String name, String oldValue, String newValue) => host.attributeChanged(name, oldValue, newValue); // TODO(efortuna): Update these when we decide what to do with these // properties. @deprecated String getAttribute(String name) => host.getAttribute(name); @deprecated String getAttributeNS(String namespaceUri, String localName) => host.getAttributeNS(namespaceUri, localName); @deprecated String setAttributeNS( String namespaceUri, String localName, String value) { host.setAttributeNS(namespaceUri, localName, value); } @deprecated void setAttribute(String name, String value) => host.setAttribute(name, value); @deprecated List get childNodes => host.childNodes; // TODO(jmesserly): this forwarding is temporary until Dart supports // subclassing Elements. // TODO(jmesserly): we were missing the setter for title, are other things // missing setters? List get nodes => host.nodes; set nodes(Iterable value) { host.nodes = value; } /** * Replaces this node with another node. */ Node replaceWith(Node otherNode) { host.replaceWith(otherNode); } /** * Removes this node from the DOM. */ void remove() => host.remove(); Node get nextNode => host.nextNode; String get nodeName => host.nodeName; Document get ownerDocument => host.ownerDocument; Node get previousNode => host.previousNode; String get text => host.text; set text(String v) { host.text = v; } bool contains(Node other) => host.contains(other); bool hasChildNodes() => host.hasChildNodes(); Node insertBefore(Node newChild, Node refChild) => host.insertBefore(newChild, refChild); Node insertAllBefore(Iterable newChild, Node refChild) => host.insertAllBefore(newChild, refChild); Map get attributes => host.attributes; set attributes(Map value) { host.attributes = value; } List get elements => host.children; set elements(List value) { host.children = value; } List get children => host.children; set children(List value) { host.children = value; } Set get classes => host.classes; set classes(Iterable value) { host.classes = value; } CssRect get contentEdge => host.contentEdge; CssRect get paddingEdge => host.paddingEdge; CssRect get borderEdge => host.borderEdge; CssRect get marginEdge => host.marginEdge; Point get documentOffset => host.documentOffset; Point offsetTo(Element parent) => host.offsetTo(parent); Map getNamespacedAttributes(String namespace) => host.getNamespacedAttributes(namespace); CssStyleDeclaration getComputedStyle([String pseudoElement]) => host.getComputedStyle(pseudoElement); Element clone(bool deep) => host.clone(deep); Element get parent => host.parent; Node get parentNode => host.parentNode; String get nodeValue => host.nodeValue; Events get on => host.on; String get contentEditable => host.contentEditable; set contentEditable(String v) { host.contentEditable = v; } String get dir => host.dir; set dir(String v) { host.dir = v; } bool get draggable => host.draggable; set draggable(bool v) { host.draggable = v; } bool get hidden => host.hidden; set hidden(bool v) { host.hidden = v; } String get id => host.id; set id(String v) { host.id = v; } String get innerHtml => host.innerHtml; void set innerHtml(String v) { host.innerHtml = v; } void setInnerHtml(String html, {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) { host.setInnerHtml(html, validator: validator, treeSanitizer: treeSanitizer); } DocumentFragment createFragment(String html, {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) => host.createFragment(html, validator: validator, treeSanitizer: treeSanitizer); InputMethodContext get inputMethodContext => host.inputMethodContext; bool get isContentEditable => host.isContentEditable; String get lang => host.lang; set lang(String v) { host.lang = v; } String get outerHtml => host.outerHtml; bool get spellcheck => host.spellcheck; set spellcheck(bool v) { host.spellcheck = v; } int get tabIndex => host.tabIndex; set tabIndex(int i) { host.tabIndex = i; } String get title => host.title; set title(String value) { host.title = value; } bool get translate => host.translate; set translate(bool v) { host.translate = v; } String get dropzone => host.dropzone; set dropzone(String v) { host.dropzone = v; } void click() { host.click(); } List getDestinationInsertionPoints() => host.getDestinationInsertionPoints(); Element insertAdjacentElement(String where, Element element) => host.insertAdjacentElement(where, element); void insertAdjacentHtml(String where, String html) { host.insertAdjacentHtml(where, html); } void insertAdjacentText(String where, String text) { host.insertAdjacentText(where, text); } Map get dataset => host.dataset; set dataset(Map value) { host.dataset = value; } Element get nextElementSibling => host.nextElementSibling; Element get offsetParent => host.offsetParent; Element get previousElementSibling => host.previousElementSibling; CssStyleDeclaration get style => host.style; String get tagName => host.tagName; String get pseudo => host.pseudo; void set pseudo(String value) { host.pseudo = value; } // Note: we are not polyfilling the shadow root here. This will be fixed when // we migrate to the JS Shadow DOM polyfills. You can still use getShadowRoot // to retrieve a node that behaves as the shadow root when Shadow DOM is not // enabled. ShadowRoot get shadowRoot => host.shadowRoot; void blur() { host.blur(); } void focus() { host.focus(); } void scrollByLines(int lines) { host.scrollByLines(lines); } void scrollByPages(int pages) { host.scrollByPages(pages); } void scrollIntoView([ScrollAlignment alignment]) { host.scrollIntoView(alignment); } bool matches(String selectors) => host.matches(selectors); bool matchesWithAncestors(String selectors) => host.matchesWithAncestors(selectors); @deprecated void requestFullScreen(int flags) { requestFullscreen(); } void requestFullscreen() { host.requestFullscreen(); } void requestPointerLock() { host.requestPointerLock(); } Element querySelector(String selectors) => host.querySelector(selectors); ElementList querySelectorAll(String selectors) => host.querySelectorAll(selectors); @deprecated Element query(String selectors) => host.querySelector(selectors); @deprecated ElementList queryAll(String selectors) => host.querySelectorAll(selectors); String get className => host.className; set className(String value) { host.className = value; } @deprecated int get clientHeight => client.height; @deprecated int get clientLeft => client.left; @deprecated int get clientTop => client.top; @deprecated int get clientWidth => client.width; Rectangle get client => host.client; @deprecated int get offsetHeight => offset.height; @deprecated int get offsetLeft => offset.left; @deprecated int get offsetTop => offset.top; @deprecated int get offsetWidth => offset.width; Rectangle get offset => host.offset; int get scrollHeight => host.scrollHeight; int get scrollLeft => host.scrollLeft; int get scrollTop => host.scrollTop; set scrollLeft(int value) { host.scrollLeft = value; } set scrollTop(int value) { host.scrollTop = value; } int get scrollWidth => host.scrollWidth; Rectangle getBoundingClientRect() => host.getBoundingClientRect(); List getClientRects() => host.getClientRects(); List getElementsByClassName(String name) => host.getElementsByClassName(name); Node get firstChild => host.firstChild; Node get lastChild => host.lastChild; String get localName => host.localName; String get namespaceUri => host.namespaceUri; int get nodeType => host.nodeType; void addEventListener(String type, EventListener listener, [bool useCapture]) { host.addEventListener(type, listener, useCapture); } bool dispatchEvent(Event event) => host.dispatchEvent(event); void removeEventListener(String type, EventListener listener, [bool useCapture]) { host.removeEventListener(type, listener, useCapture); } get xtag => host.xtag; set xtag(value) { host.xtag = value; } Node append(Node e) => host.append(e); void appendText(String text) => host.appendText(text); void appendHtml(String html) => host.appendHtml(html); String get regionOverset => host.regionOverset; List getRegionFlowRanges() => host.getRegionFlowRanges(); // TODO(jmesserly): rename "created" to "onCreated". void onCreated() => created(); Stream get onAbort => host.onAbort; Stream get onBeforeCopy => host.onBeforeCopy; Stream get onBeforeCut => host.onBeforeCut; Stream get onBeforePaste => host.onBeforePaste; Stream get onBlur => host.onBlur; Stream get onChange => host.onChange; Stream get onClick => host.onClick; Stream get onContextMenu => host.onContextMenu; Stream get onCopy => host.onCopy; Stream get onCut => host.onCut; Stream get onDoubleClick => host.onDoubleClick; Stream get onDrag => host.onDrag; Stream get onDragEnd => host.onDragEnd; Stream get onDragEnter => host.onDragEnter; Stream get onDragLeave => host.onDragLeave; Stream get onDragOver => host.onDragOver; Stream get onDragStart => host.onDragStart; Stream get onDrop => host.onDrop; Stream get onError => host.onError; Stream get onFocus => host.onFocus; Stream get onInput => host.onInput; Stream get onInvalid => host.onInvalid; Stream get onKeyDown => host.onKeyDown; Stream get onKeyPress => host.onKeyPress; Stream get onKeyUp => host.onKeyUp; Stream get onLoad => host.onLoad; Stream get onMouseDown => host.onMouseDown; Stream get onMouseEnter => host.onMouseEnter; Stream get onMouseLeave => host.onMouseLeave; Stream get onMouseMove => host.onMouseMove; Stream get onFullscreenChange => host.onFullscreenChange; Stream get onFullscreenError => host.onFullscreenError; Stream get onPaste => host.onPaste; Stream get onReset => host.onReset; Stream get onScroll => host.onScroll; Stream get onSearch => host.onSearch; Stream get onSelect => host.onSelect; Stream get onSelectStart => host.onSelectStart; Stream get onSubmit => host.onSubmit; Stream get onMouseOut => host.onMouseOut; Stream get onMouseOver => host.onMouseOver; Stream get onMouseUp => host.onMouseUp; Stream get onTouchCancel => host.onTouchCancel; Stream get onTouchEnd => host.onTouchEnd; Stream get onTouchEnter => host.onTouchEnter; Stream get onTouchLeave => host.onTouchLeave; Stream get onTouchMove => host.onTouchMove; Stream get onTouchStart => host.onTouchStart; Stream get onTransitionEnd => host.onTransitionEnd; // TODO(sigmund): do the normal forwarding when dartbug.com/7919 is fixed. Stream get onMouseWheel { throw new UnsupportedError('onMouseWheel is not supported'); } }