blob: a649f89a29aebe509533e2b573ace8f6a3933ada [file] [log] [blame]
Blink Reformat4c46d092018-04-07 15:32:371/*
2 * Copyright (C) 2011 Google 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 are
6 * met:
7 *
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31ObjectUI.ObjectPopoverHelper = class {
32 /**
33 * @param {?Components.Linkifier} linkifier
34 * @param {boolean} resultHighlightedAsDOM
35 */
36 constructor(linkifier, resultHighlightedAsDOM) {
37 this._linkifier = linkifier;
38 this._resultHighlightedAsDOM = resultHighlightedAsDOM;
39 }
40
41 dispose() {
42 if (this._resultHighlightedAsDOM)
43 SDK.OverlayModel.hideDOMNodeHighlight();
44 if (this._linkifier)
45 this._linkifier.dispose();
46 }
47
48 /**
49 * @param {!SDK.RemoteObject} result
50 * @param {!UI.GlassPane} popover
51 * @return {!Promise<?ObjectUI.ObjectPopoverHelper>}
52 */
53 static buildObjectPopover(result, popover) {
54 let fulfill;
55 const promise = new Promise(x => fulfill = x);
56
57 /**
58 * @param {!SDK.RemoteObject} funcObject
59 * @param {!Element} popoverContentElement
60 * @param {!Element} popoverValueElement
61 * @param {?Array.<!SDK.RemoteObjectProperty>} properties
62 * @param {?Array.<!SDK.RemoteObjectProperty>} internalProperties
63 */
64 function didGetFunctionProperties(
65 funcObject, popoverContentElement, popoverValueElement, properties, internalProperties) {
66 if (internalProperties) {
67 for (let i = 0; i < internalProperties.length; i++) {
68 if (internalProperties[i].name === '[[TargetFunction]]') {
69 funcObject = internalProperties[i].value;
70 break;
71 }
72 }
73 }
74 ObjectUI.ObjectPropertiesSection.formatObjectAsFunction(funcObject, popoverValueElement, true);
75 funcObject.debuggerModel()
76 .functionDetailsPromise(funcObject)
77 .then(didGetFunctionDetails.bind(null, popoverContentElement));
78 }
79
80 /**
81 * @param {!Element} popoverContentElement
82 * @param {?SDK.DebuggerModel.FunctionDetails} response
83 */
84 function didGetFunctionDetails(popoverContentElement, response) {
85 if (!response) {
86 fulfill(null);
87 return;
88 }
89
90 const container = createElementWithClass('div', 'object-popover-container');
91 const title = container.createChild('div', 'function-popover-title source-code');
92 const functionName = title.createChild('span', 'function-name');
93 functionName.textContent = UI.beautifyFunctionName(response.functionName);
94
95 const rawLocation = response.location;
96 const linkContainer = title.createChild('div', 'function-title-link-container');
97 const sourceURL = rawLocation && rawLocation.script() ? rawLocation.script().sourceURL : null;
98 let linkifier = null;
99 if (rawLocation && sourceURL) {
100 linkifier = new Components.Linkifier();
101 linkContainer.appendChild(linkifier.linkifyRawLocation(rawLocation, sourceURL));
102 }
103 container.appendChild(popoverContentElement);
104 popover.contentElement.appendChild(container);
105 fulfill(new ObjectUI.ObjectPopoverHelper(linkifier, false));
106 }
107
108 const description = result.description.trimEnd(ObjectUI.ObjectPopoverHelper.MaxPopoverTextLength);
109 let popoverContentElement = null;
110 if (result.type !== 'object') {
111 popoverContentElement = createElement('span');
112 UI.appendStyle(popoverContentElement, 'object_ui/objectValue.css');
113 UI.appendStyle(popoverContentElement, 'object_ui/objectPopover.css');
114 const valueElement = popoverContentElement.createChild('span', 'monospace object-value-' + result.type);
115 valueElement.style.whiteSpace = 'pre';
116
117 if (result.type === 'string')
118 valueElement.createTextChildren('"', description, '"');
119 else if (result.type !== 'function')
120 valueElement.textContent = description;
121
122 if (result.type === 'function') {
123 result.getOwnProperties(
124 false /* generatePreview */,
125 didGetFunctionProperties.bind(null, result, popoverContentElement, valueElement));
126 return promise;
127 }
128 popover.contentElement.appendChild(popoverContentElement);
129 fulfill(new ObjectUI.ObjectPopoverHelper(null, false));
130 } else {
131 let linkifier = null;
132 let resultHighlightedAsDOM = false;
133 if (result.subtype === 'node') {
134 SDK.OverlayModel.highlightObjectAsDOMNode(result);
135 resultHighlightedAsDOM = true;
136 }
137
138 if (result.customPreview()) {
139 const customPreviewComponent = new ObjectUI.CustomPreviewComponent(result);
140 customPreviewComponent.expandIfPossible();
141 popoverContentElement = customPreviewComponent.element;
142 } else {
143 popoverContentElement = createElementWithClass('div', 'object-popover-content');
144 UI.appendStyle(popoverContentElement, 'object_ui/objectPopover.css');
145 const titleElement = popoverContentElement.createChild('div', 'monospace object-popover-title');
146 titleElement.createChild('span').textContent = description;
147 linkifier = new Components.Linkifier();
148 const section = new ObjectUI.ObjectPropertiesSection(result, '', linkifier);
149 section.element.classList.add('object-popover-tree');
150 section.titleLessMode();
151 popoverContentElement.appendChild(section.element);
152 }
153 popover.setMaxContentSize(new UI.Size(300, 250));
154 popover.setSizeBehavior(UI.GlassPane.SizeBehavior.SetExactSize);
155 popover.contentElement.appendChild(popoverContentElement);
156 fulfill(new ObjectUI.ObjectPopoverHelper(linkifier, resultHighlightedAsDOM));
157 }
158 return promise;
159 }
160};
161
162ObjectUI.ObjectPopoverHelper.MaxPopoverTextLength = 10000;