/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ "use strict"; const { Arg, Option, RetVal, generateActorSpec, types } = require("devtools/shared/protocol"); const { nodeSpec } = require("devtools/shared/specs/node"); require("devtools/shared/specs/styles"); require("devtools/shared/specs/highlighters"); require("devtools/shared/specs/layout"); exports.nodeSpec = nodeSpec; /** * Returned from any call that might return a node that isn't connected to root * by nodes the child has seen, such as querySelector. */ types.addDictType("disconnectedNode", { // The actual node to return node: "domnode", // Nodes that are needed to connect the node to a node the client has already // seen newParents: "array:domnode" }); types.addDictType("disconnectedNodeArray", { // The actual node list to return nodes: "array:domnode", // Nodes that are needed to connect those nodes to the root. newParents: "array:domnode" }); types.addDictType("dommutation", {}); types.addDictType("searchresult", { list: "domnodelist", // Right now there is isn't anything required for metadata, // but it's json so it can be extended with extra data. metadata: "array:json" }); const nodeListSpec = generateActorSpec({ typeName: "domnodelist", methods: { item: { request: { item: Arg(0) }, response: RetVal("disconnectedNode") }, items: { request: { start: Arg(0, "nullable:number"), end: Arg(1, "nullable:number") }, response: RetVal("disconnectedNodeArray") }, release: { release: true } } }); exports.nodeListSpec = nodeListSpec; // Some common request/response templates for the dom walker var nodeArrayMethod = { request: { node: Arg(0, "domnode"), maxNodes: Option(1), center: Option(1, "domnode"), start: Option(1, "domnode"), whatToShow: Option(1) }, response: RetVal(types.addDictType("domtraversalarray", { nodes: "array:domnode" })) }; var traversalMethod = { request: { node: Arg(0, "domnode"), whatToShow: Option(1) }, response: { node: RetVal("nullable:domnode") } }; const walkerSpec = generateActorSpec({ typeName: "domwalker", events: { "new-mutations": { type: "newMutations" }, "picker-node-picked": { type: "pickerNodePicked", node: Arg(0, "disconnectedNode") }, "picker-node-previewed": { type: "pickerNodePreviewed", node: Arg(0, "disconnectedNode") }, "picker-node-hovered": { type: "pickerNodeHovered", node: Arg(0, "disconnectedNode") }, "picker-node-canceled": { type: "pickerNodeCanceled" }, "highlighter-ready": { type: "highlighter-ready" }, "highlighter-hide": { type: "highlighter-hide" }, "display-change": { type: "display-change", nodes: Arg(0, "array:domnode") }, // The walker actor emits a useful "resize" event to its front to let // clients know when the browser window gets resized. This may be useful // for refreshing a DOM node's styles for example, since those may depend on // media-queries. "resize": { type: "resize" } }, methods: { release: { release: true }, pick: { request: {}, response: RetVal("disconnectedNode") }, cancelPick: {}, highlight: { request: {node: Arg(0, "nullable:domnode")} }, document: { request: { node: Arg(0, "nullable:domnode") }, response: { node: RetVal("domnode") }, }, documentElement: { request: { node: Arg(0, "nullable:domnode") }, response: { node: RetVal("domnode") }, }, parents: { request: { node: Arg(0, "domnode"), sameDocument: Option(1), sameTypeRootTreeItem: Option(1) }, response: { nodes: RetVal("array:domnode") }, }, retainNode: { request: { node: Arg(0, "domnode") }, response: {} }, unretainNode: { request: { node: Arg(0, "domnode") }, response: {}, }, releaseNode: { request: { node: Arg(0, "domnode"), force: Option(1) } }, children: nodeArrayMethod, siblings: nodeArrayMethod, nextSibling: traversalMethod, previousSibling: traversalMethod, findInspectingNode: { request: {}, response: RetVal("disconnectedNode") }, querySelector: { request: { node: Arg(0, "domnode"), selector: Arg(1) }, response: RetVal("disconnectedNode") }, querySelectorAll: { request: { node: Arg(0, "domnode"), selector: Arg(1) }, response: { list: RetVal("domnodelist") } }, multiFrameQuerySelectorAll: { request: { selector: Arg(0) }, response: { list: RetVal("domnodelist") } }, search: { request: { query: Arg(0), }, response: { list: RetVal("searchresult"), } }, getSuggestionsForQuery: { request: { query: Arg(0), completing: Arg(1), selectorState: Arg(2) }, response: { list: RetVal("array:array:string") } }, addPseudoClassLock: { request: { node: Arg(0, "domnode"), pseudoClass: Arg(1), parents: Option(2) }, response: {} }, hideNode: { request: { node: Arg(0, "domnode") } }, unhideNode: { request: { node: Arg(0, "domnode") } }, removePseudoClassLock: { request: { node: Arg(0, "domnode"), pseudoClass: Arg(1), parents: Option(2) }, response: {} }, clearPseudoClassLocks: { request: { node: Arg(0, "nullable:domnode") }, response: {} }, innerHTML: { request: { node: Arg(0, "domnode") }, response: { value: RetVal("longstring") } }, setInnerHTML: { request: { node: Arg(0, "domnode"), value: Arg(1, "string"), }, response: {} }, outerHTML: { request: { node: Arg(0, "domnode") }, response: { value: RetVal("longstring") } }, setOuterHTML: { request: { node: Arg(0, "domnode"), value: Arg(1, "string"), }, response: {} }, insertAdjacentHTML: { request: { node: Arg(0, "domnode"), position: Arg(1, "string"), value: Arg(2, "string") }, response: RetVal("disconnectedNodeArray") }, duplicateNode: { request: { node: Arg(0, "domnode") }, response: {} }, removeNode: { request: { node: Arg(0, "domnode") }, response: { nextSibling: RetVal("nullable:domnode") } }, removeNodes: { request: { node: Arg(0, "array:domnode") }, response: {} }, insertBefore: { request: { node: Arg(0, "domnode"), parent: Arg(1, "domnode"), sibling: Arg(2, "nullable:domnode") }, response: {} }, editTagName: { request: { node: Arg(0, "domnode"), tagName: Arg(1, "string") }, response: {} }, getMutations: { request: { cleanup: Option(0) }, response: { mutations: RetVal("array:dommutation") } }, isInDOMTree: { request: { node: Arg(0, "domnode") }, response: { attached: RetVal("boolean") } }, getNodeActorFromObjectActor: { request: { objectActorID: Arg(0, "string") }, response: { nodeFront: RetVal("nullable:disconnectedNode") } }, getStyleSheetOwnerNode: { request: { styleSheetActorID: Arg(0, "string") }, response: { ownerNode: RetVal("nullable:disconnectedNode") } }, getNodeFromActor: { request: { actorID: Arg(0, "string"), path: Arg(1, "array:string") }, response: { node: RetVal("nullable:disconnectedNode") } }, getLayoutInspector: { request: {}, response: { actor: RetVal("layout") } } } }); exports.walkerSpec = walkerSpec; const inspectorSpec = generateActorSpec({ typeName: "inspector", events: { "color-picked": { type: "colorPicked", color: Arg(0, "string") }, "color-pick-canceled": { type: "colorPickCanceled" } }, methods: { getWalker: { request: { options: Arg(0, "nullable:json") }, response: { walker: RetVal("domwalker") } }, getPageStyle: { request: {}, response: { pageStyle: RetVal("pagestyle") } }, getHighlighter: { request: { autohide: Arg(0, "boolean") }, response: { highligter: RetVal("highlighter") } }, getHighlighterByType: { request: { typeName: Arg(0) }, response: { highlighter: RetVal("nullable:customhighlighter") } }, getImageDataFromURL: { request: {url: Arg(0), maxDim: Arg(1, "nullable:number")}, response: RetVal("imageData") }, resolveRelativeURL: { request: {url: Arg(0, "string"), node: Arg(1, "nullable:domnode")}, response: {value: RetVal("string")} }, pickColorFromPage: { request: {options: Arg(0, "nullable:json")}, response: {} }, cancelPickColorFromPage: { request: {}, response: {} } } }); exports.inspectorSpec = inspectorSpec;