5fcd6f918462e944be9ef49a09cfcc0b9ded7089
[WebKit-https.git] / Source / WebInspectorUI / UserInterface / Views / CanvasDetailsSidebarPanel.js
1 /*
2  * Copyright (C) 2017 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 WebInspector.CanvasDetailsSidebarPanel = class CanvasDetailsSidebarPanel extends WebInspector.DetailsSidebarPanel
27 {
28     constructor()
29     {
30         super("canvas-details", WebInspector.UIString("Canvas"));
31
32         this.element.classList.add("canvas");
33
34         this._canvas = null;
35         this._node = null;
36     }
37
38     // Public
39
40     inspect(objects)
41     {
42         if (!(objects instanceof Array))
43             objects = [objects];
44
45         this.canvas = objects.find((object) => object instanceof WebInspector.Canvas);
46
47         return !!this._canvas;
48     }
49
50     get canvas()
51     {
52         return this._canvas;
53     }
54
55     set canvas(canvas)
56     {
57         if (canvas === this._canvas)
58             return;
59
60         this._canvas = canvas || null;
61
62         if (this._node) {
63             this._node.removeEventListener(WebInspector.DOMNode.Event.AttributeModified, this._refreshSourceSection, this);
64             this._node.removeEventListener(WebInspector.DOMNode.Event.AttributeRemoved, this._refreshSourceSection, this);
65
66             this._node = null;
67         }
68
69         this.needsLayout();
70     }
71
72     // Protected
73
74     initialLayout()
75     {
76         super.initialLayout();
77
78         this._nameRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Name"));
79         this._typeRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Type"));
80
81         let identitySection = new WebInspector.DetailsSection("canvas-details", WebInspector.UIString("Identity"));
82         identitySection.groups = [new WebInspector.DetailsSectionGroup([this._nameRow, this._typeRow])];
83         this.contentView.element.appendChild(identitySection.element);
84
85         this._nodeRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Node"));
86         this._cssCanvasRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("CSS Canvas"));
87         this._widthRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Width"));
88         this._heightRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Height"));
89         this._datachedRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Detached"));
90
91         let sourceSection = new WebInspector.DetailsSection("canvas-source", WebInspector.UIString("Source"));
92         sourceSection.groups = [new WebInspector.DetailsSectionGroup([this._nodeRow, this._cssCanvasRow, this._widthRow, this._heightRow, this._datachedRow])];
93         this.contentView.element.appendChild(sourceSection.element);
94     }
95
96     layout()
97     {
98         super.layout();
99
100         if (!this._canvas)
101             return;
102
103         this._refreshIdentitySection();
104         this._refreshSourceSection();
105     }
106
107     // Private
108
109     _refreshIdentitySection()
110     {
111         if (!this._canvas)
112             return;
113
114         this._nameRow.value = this._canvas.displayName;
115         this._typeRow.value = WebInspector.Canvas.displayNameForContextType(this._canvas.contextType);
116     }
117
118     _refreshSourceSection()
119     {
120         if (!this._canvas)
121             return;
122
123         this._nodeRow.value = this._canvas.cssCanvasName ? null : emDash;
124         this._cssCanvasRow.value = this._canvas.cssCanvasName || null;
125         this._widthRow.value = emDash;
126         this._heightRow.value = emDash;
127         this._datachedRow.value = null;
128
129         this._canvas.requestNode((node) => {
130             if (!node)
131                 return;
132
133             if (node !== this._node) {
134                 if (this._node) {
135                     this._node.removeEventListener(WebInspector.DOMNode.Event.AttributeModified, this._refreshSourceSection, this);
136                     this._node.removeEventListener(WebInspector.DOMNode.Event.AttributeRemoved, this._refreshSourceSection, this);
137
138                     this._node = null;
139                 }
140
141                 this._node = node;
142
143                 this._node.addEventListener(WebInspector.DOMNode.Event.AttributeModified, this._refreshSourceSection, this);
144                 this._node.addEventListener(WebInspector.DOMNode.Event.AttributeRemoved, this._refreshSourceSection, this);
145             }
146
147             if (!this._canvas.cssCanvasName)
148                 this._nodeRow.value = WebInspector.linkifyNodeReference(this._node);
149
150             let setRowValueIfValidAttributeValue = (row, attribute) => {
151                 let value = Number(this._node.getAttribute(attribute));
152                 if (!Number.isInteger(value) || value < 0)
153                     return false;
154
155                 row.value = value;
156                 return true;
157             };
158
159             let validWidth = setRowValueIfValidAttributeValue(this._widthRow, "width");
160             let validHeight = setRowValueIfValidAttributeValue(this._heightRow, "height");
161             if (!validWidth || !validHeight) {
162                 // Since the "width" and "height" properties of canvas elements are more than just
163                 // attributes, we need to invoke the getter for each to get the actual value.
164                 //  - https://html.spec.whatwg.org/multipage/canvas.html#attr-canvas-width
165                 //  - https://html.spec.whatwg.org/multipage/canvas.html#attr-canvas-height
166                 WebInspector.RemoteObject.resolveNode(node, "", (remoteObject) => {
167                     if (!remoteObject)
168                         return;
169
170                     function setRowValueToPropertyValue(row, property) {
171                         remoteObject.getProperty(property, (error, result, wasThrown) => {
172                             if (!error && result.type === "number")
173                                 row.value = `${result.value}px`;
174                         });
175                     }
176
177                     setRowValueToPropertyValue(this._widthRow, "width");
178                     setRowValueToPropertyValue(this._heightRow, "height");
179
180                     remoteObject.release();
181                 });
182             }
183
184             if (!this._canvas.cssCanvasName && !this._node.parentNode)
185                 this._datachedRow.value = WebInspector.UIString("Yes");
186         });
187     }
188 };