Skip to content

Add Shadow DOM v1 APIs #151

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Nov 14, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 36 additions & 1 deletion baselines/dom.generated.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ interface DoubleRange {
}

interface EventInit {
scoped?: boolean;
bubbles?: boolean;
cancelable?: boolean;
}
Expand Down Expand Up @@ -2291,7 +2292,7 @@ declare var DeviceRotationRate: {
new(): DeviceRotationRate;
}

interface Document extends Node, GlobalEventHandlers, NodeSelector, DocumentEvent, ParentNode {
interface Document extends Node, GlobalEventHandlers, NodeSelector, DocumentEvent, ParentNode, DocumentOrShadowRoot {
/**
* Sets or gets the URL for the current document.
*/
Expand Down Expand Up @@ -3467,6 +3468,9 @@ interface Element extends Node, GlobalEventHandlers, ElementTraversal, NodeSelec
readonly scrollWidth: number;
readonly tagName: string;
innerHTML: string;
readonly assignedSlot: HTMLSlotElement | null;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The property is optional on the spec, we should make it optional here so that undefined can be accepted as well.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And the same for other places too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I initially wrote it like that, but I when I was doing some double-checking it looked like WebIDL's ? suffix is different from typescript's ?. Take a look at this and let me know what you think:

So for places where the DOM accepts an IDL type T? from ES code then T | null | undefined looks like the right TS type, but for readonly properties it seems like T | null is more correct.

Apologies if this debate has already been litigated and the decision to treat nullable values as also allowing undefined has been made across the board.

I have made the non-required members of dictionaries, like EventInit#scoped optional.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the links. Yeah I agree it makes more sense, since the readonly types are from DOM itself.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not see why a readonly propoerty can not be undefined. this is useful for users who want to feature dection. this should be:

readonly assignedSlot?: HTMLSlotElement | null;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I read the spec, in a browser that implements this API, assignedSlot will never be undefined.

It's true that in an environment without the API it could be undefined, but this is true of most browser APIs.

slot: string;
readonly shadowRoot: ShadowRoot | null;
getAttribute(name: string): string | null;
getAttributeNS(namespaceURI: string, localName: string): string;
getAttributeNode(name: string): Attr;
Expand Down Expand Up @@ -3688,6 +3692,7 @@ interface Element extends Node, GlobalEventHandlers, ElementTraversal, NodeSelec
insertAdjacentElement(position: string, insertedElement: Element): Element | null;
insertAdjacentHTML(where: string, html: string): void;
insertAdjacentText(where: string, text: string): void;
attachShadow(shadowRootInitDict: ShadowRootInit): ShadowRoot;
addEventListener(type: "MSGestureChange", listener: (this: this, ev: MSGestureEvent) => any, useCapture?: boolean): void;
addEventListener(type: "MSGestureDoubleTap", listener: (this: this, ev: MSGestureEvent) => any, useCapture?: boolean): void;
addEventListener(type: "MSGestureEnd", listener: (this: this, ev: MSGestureEvent) => any, useCapture?: boolean): void;
Expand Down Expand Up @@ -3759,10 +3764,12 @@ interface Event {
readonly target: EventTarget;
readonly timeStamp: number;
readonly type: string;
readonly scoped: boolean;
initEvent(eventTypeArg: string, canBubbleArg: boolean, cancelableArg: boolean): void;
preventDefault(): void;
stopImmediatePropagation(): void;
stopPropagation(): void;
deepPath(): EventTarget[];
readonly AT_TARGET: number;
readonly BUBBLING_PHASE: number;
readonly CAPTURING_PHASE: number;
Expand Down Expand Up @@ -11521,6 +11528,7 @@ declare var SubtleCrypto: {

interface Text extends CharacterData {
readonly wholeText: string;
readonly assignedSlot: HTMLSlotElement | null;
splitText(offset: number): Text;
}

Expand Down Expand Up @@ -14247,6 +14255,33 @@ interface ParentNode {
readonly childElementCount: number;
}

interface DocumentOrShadowRoot {
readonly activeElement: Element | null;
readonly stylesheets: StyleSheetList;
getSelection(): Selection | null;
elementFromPoint(x: number, y: number): Element | null;
elementsFromPoint(x: number, y: number): Element[];
}

interface ShadowRoot extends DocumentOrShadowRoot, DocumentFragment {
readonly host: Element;
innerHTML: string;
}

interface ShadowRootInit {
mode: 'open'|'closed';
delegatesFocus?: boolean;
}

interface HTMLSlotElement extends HTMLElement {
name: string;
assignedNodes(options?: AssignedNodesOptions): Node[];
}

interface AssignedNodesOptions {
flatten?: boolean;
}

declare type EventListenerOrEventListenerObject = EventListener | EventListenerObject;

interface ErrorEventHandler {
Expand Down
3 changes: 3 additions & 0 deletions baselines/webworker.generated.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ interface Algorithm {
}

interface EventInit {
scoped?: boolean;
bubbles?: boolean;
cancelable?: boolean;
}
Expand Down Expand Up @@ -242,10 +243,12 @@ interface Event {
readonly target: EventTarget;
readonly timeStamp: number;
readonly type: string;
readonly scoped: boolean;
initEvent(eventTypeArg: string, canBubbleArg: boolean, cancelableArg: boolean): void;
preventDefault(): void;
stopImmediatePropagation(): void;
stopPropagation(): void;
deepPath(): EventTarget[];
readonly AT_TARGET: number;
readonly BUBBLING_PHASE: number;
readonly CAPTURING_PHASE: number;
Expand Down
146 changes: 145 additions & 1 deletion inputfiles/addedTypes.json
Original file line number Diff line number Diff line change
Expand Up @@ -1155,7 +1155,7 @@
"type": "string"
},
{
"kind": "interface",
"kind": "interface",
"name": "ParentNode",
"flavor": "DOM",
"properties": [
Expand Down Expand Up @@ -1220,5 +1220,149 @@
"interface": "CanvasPattern",
"name": "setTransform",
"signatures": ["setTransform(matrix: SVGMatrix): void"]
},
{
"kind": "interface",
"name": "DocumentOrShadowRoot",
"flavor": "DOM",
"methods": [
{
"name": "getSelection",
"signatures": ["getSelection(): Selection | null"]
},
{
"name": "elementFromPoint",
"signatures": ["elementFromPoint(x: number, y: number): Element | null"]
},
{
"name": "elementsFromPoint",
"signatures": ["elementsFromPoint(x: number, y: number): Element[]"]
}
],
"properties": [
{
"name": "activeElement",
"type": "Element | null",
"readonly": true
},
{
"name": "stylesheets",
"type": "StyleSheetList",
"readonly": true
}
]
},
{
"kind": "interface",
"name": "ShadowRoot",
"extends": "DocumentOrShadowRoot, DocumentFragment",
"flavor": "DOM",
"properties": [
{
"name": "host",
"type": "Element",
"readonly": true
},
{
"name": "innerHTML",
"type": "string"
}
]
},
{
"kind": "method",
"interface": "Element",
"name": "attachShadow",
"signatures": ["attachShadow(shadowRootInitDict: ShadowRootInit): ShadowRoot"]
},
{
"kind": "property",
"interface": "Element",
"name": "assignedSlot",
"type": "HTMLSlotElement | null",
"readonly": true
},
{
"kind": "property",
"interface": "Element",
"name": "slot",
"type": "string"
},
{
"kind": "property",
"interface": "Element",
"name": "shadowRoot",
"type": "ShadowRoot | null",
"readonly": true
},
{
"kind": "interface",
"name": "ShadowRootInit",
"flavor": "DOM",
"properties": [
{
"name": "mode",
"type": "'open'|'closed'"
},
{
"name": "delegatesFocus?",
"type": "boolean"
}
]
},
{
"kind": "property",
"interface": "Text",
"name": "assignedSlot",
"type": "HTMLSlotElement | null",
"readonly": true
},
{
"kind": "interface",
"name": "HTMLSlotElement",
"extends": "HTMLElement",
"flavor": "DOM",
"properties": [
{
"name": "name",
"type": "string"
}
],
"methods": [
{
"name": "assignedNodes",
"signatures": ["assignedNodes(options?: AssignedNodesOptions): Node[]"]
}
]
},
{
"kind": "interface",
"name": "AssignedNodesOptions",
"flavor": "DOM",
"properties": [
{
"name": "flatten?",
"type": "boolean"
}
]
},
{
"kind": "property",
"interface": "EventInit",
"name": "scoped?",
"type": "boolean"
},
{
"kind": "property",
"interface": "Event",
"name": "scoped",
"type": "boolean",
"readonly": true
},
{
"kind": "method",
"interface": "Event",
"name": "deepPath",
"signatures": ["deepPath(): EventTarget[]"]
}
]
5 changes: 5 additions & 0 deletions inputfiles/overridingTypes.json
Original file line number Diff line number Diff line change
Expand Up @@ -924,5 +924,10 @@
"interface": "XPathExpression",
"name": "evaluate",
"signatures": ["evaluate(contextNode: Node, type: number, result: XPathResult | null): XPathResult"]
},
{
"kind": "extends",
"baseInterface": "Node, GlobalEventHandlers, NodeSelector, DocumentEvent, ParentNode, DocumentOrShadowRoot",
"interface": "Document"
}
]