Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(49)

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/elements/ClassesPaneWidget.js

Issue 2466123002: DevTools: reformat front-end code to match chromium style. (Closed)
Patch Set: all done Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2015 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4
5 /** 4 /**
6 * @constructor 5 * @unrestricted
7 * @extends {WebInspector.Widget}
8 */ 6 */
9 WebInspector.ClassesPaneWidget = function() 7 WebInspector.ClassesPaneWidget = class extends WebInspector.Widget {
10 { 8 constructor() {
11 WebInspector.Widget.call(this); 9 super();
12 this.element.className = "styles-element-classes-pane"; 10 this.element.className = 'styles-element-classes-pane';
13 var container = this.element.createChild("div", "title-container"); 11 var container = this.element.createChild('div', 'title-container');
14 this._input = container.createChild("div", "new-class-input monospace"); 12 this._input = container.createChild('div', 'new-class-input monospace');
15 this._input.setAttribute("placeholder", WebInspector.UIString("Add new class ")); 13 this._input.setAttribute('placeholder', WebInspector.UIString('Add new class '));
16 this.setDefaultFocusedElement(this._input); 14 this.setDefaultFocusedElement(this._input);
17 this._classesContainer = this.element.createChild("div", "source-code"); 15 this._classesContainer = this.element.createChild('div', 'source-code');
18 this._classesContainer.classList.add("styles-element-classes-container"); 16 this._classesContainer.classList.add('styles-element-classes-container');
19 this._prompt = new WebInspector.ClassesPaneWidget.ClassNamePrompt(); 17 this._prompt = new WebInspector.ClassesPaneWidget.ClassNamePrompt();
20 this._prompt.setAutocompletionTimeout(0); 18 this._prompt.setAutocompletionTimeout(0);
21 this._prompt.renderAsBlock(); 19 this._prompt.renderAsBlock();
22 20
23 var proxyElement = this._prompt.attach(this._input); 21 var proxyElement = this._prompt.attach(this._input);
24 proxyElement.addEventListener("keydown", this._onKeyDown.bind(this), false); 22 proxyElement.addEventListener('keydown', this._onKeyDown.bind(this), false);
25 23
26 WebInspector.targetManager.addModelListener(WebInspector.DOMModel, WebInspec tor.DOMModel.Events.DOMMutated, this._onDOMMutated, this); 24 WebInspector.targetManager.addModelListener(
25 WebInspector.DOMModel, WebInspector.DOMModel.Events.DOMMutated, this._on DOMMutated, this);
27 /** @type {!Set<!WebInspector.DOMNode>} */ 26 /** @type {!Set<!WebInspector.DOMNode>} */
28 this._mutatingNodes = new Set(); 27 this._mutatingNodes = new Set();
29 WebInspector.context.addFlavorChangeListener(WebInspector.DOMNode, this._upd ate, this); 28 WebInspector.context.addFlavorChangeListener(WebInspector.DOMNode, this._upd ate, this);
29 }
30
31 /**
32 * @param {!Event} event
33 */
34 _onKeyDown(event) {
35 var text = event.target.textContent;
36 if (isEscKey(event)) {
37 event.target.textContent = '';
38 if (!text.isWhitespace())
39 event.consume(true);
40 return;
41 }
42
43 if (!isEnterKey(event))
44 return;
45 var node = WebInspector.context.flavor(WebInspector.DOMNode);
46 if (!node)
47 return;
48
49 this._prompt.clearAutocomplete();
50 event.target.textContent = '';
51 var classNames = text.split(/[.,\s]/);
52 for (var className of classNames) {
53 var className = className.trim();
54 if (!className.length)
55 continue;
56 this._toggleClass(node, className, true);
57 }
58 this._installNodeClasses(node);
59 this._update();
60 event.consume(true);
61 }
62
63 /**
64 * @param {!WebInspector.Event} event
65 */
66 _onDOMMutated(event) {
67 var node = /** @type {!WebInspector.DOMNode} */ (event.data);
68 if (this._mutatingNodes.has(node))
69 return;
70 delete node[WebInspector.ClassesPaneWidget._classesSymbol];
71 this._update();
72 }
73
74 /**
75 * @override
76 */
77 wasShown() {
78 this._update();
79 }
80
81 _update() {
82 if (!this.isShowing())
83 return;
84
85 var node = WebInspector.context.flavor(WebInspector.DOMNode);
86 if (node)
87 node = node.enclosingElementOrSelf();
88
89 this._classesContainer.removeChildren();
90 this._input.disabled = !node;
91
92 if (!node)
93 return;
94
95 var classes = this._nodeClasses(node);
96 var keys = classes.keysArray();
97 keys.sort(String.caseInsensetiveComparator);
98 for (var i = 0; i < keys.length; ++i) {
99 var className = keys[i];
100 var label = createCheckboxLabel(className, classes.get(className));
101 label.visualizeFocus = true;
102 label.classList.add('monospace');
103 label.checkboxElement.addEventListener('click', this._onClick.bind(this, c lassName), false);
104 this._classesContainer.appendChild(label);
105 }
106 }
107
108 /**
109 * @param {string} className
110 * @param {!Event} event
111 */
112 _onClick(className, event) {
113 var node = WebInspector.context.flavor(WebInspector.DOMNode);
114 if (!node)
115 return;
116 var enabled = event.target.checked;
117 this._toggleClass(node, className, enabled);
118 this._installNodeClasses(node);
119 }
120
121 /**
122 * @param {!WebInspector.DOMNode} node
123 * @return {!Map<string, boolean>}
124 */
125 _nodeClasses(node) {
126 var result = node[WebInspector.ClassesPaneWidget._classesSymbol];
127 if (!result) {
128 var classAttribute = node.getAttribute('class') || '';
129 var classes = classAttribute.split(/\s/);
130 result = new Map();
131 for (var i = 0; i < classes.length; ++i) {
132 var className = classes[i].trim();
133 if (!className.length)
134 continue;
135 result.set(className, true);
136 }
137 node[WebInspector.ClassesPaneWidget._classesSymbol] = result;
138 }
139 return result;
140 }
141
142 /**
143 * @param {!WebInspector.DOMNode} node
144 * @param {string} className
145 * @param {boolean} enabled
146 */
147 _toggleClass(node, className, enabled) {
148 var classes = this._nodeClasses(node);
149 classes.set(className, enabled);
150 }
151
152 /**
153 * @param {!WebInspector.DOMNode} node
154 */
155 _installNodeClasses(node) {
156 var classes = this._nodeClasses(node);
157 var activeClasses = new Set();
158 for (var className of classes.keys()) {
159 if (classes.get(className))
160 activeClasses.add(className);
161 }
162
163 var newClasses = activeClasses.valuesArray();
164 newClasses.sort();
165 this._mutatingNodes.add(node);
166 node.setAttributeValue('class', newClasses.join(' '), onClassNameUpdated.bin d(this));
167
168 /**
169 * @this {WebInspector.ClassesPaneWidget}
170 */
171 function onClassNameUpdated() {
172 this._mutatingNodes.delete(node);
173 }
174 }
30 }; 175 };
31 176
32 WebInspector.ClassesPaneWidget._classesSymbol = Symbol("WebInspector.ClassesPane Widget._classesSymbol"); 177 WebInspector.ClassesPaneWidget._classesSymbol = Symbol('WebInspector.ClassesPane Widget._classesSymbol');
33 178
34 WebInspector.ClassesPaneWidget.prototype = { 179 /**
35 /** 180 * @implements {WebInspector.ToolbarItem.Provider}
36 * @param {!Event} event 181 * @unrestricted
37 */ 182 */
38 _onKeyDown: function(event) 183 WebInspector.ClassesPaneWidget.ButtonProvider = class {
39 { 184 constructor() {
40 var text = event.target.textContent; 185 this._button = new WebInspector.ToolbarToggle(WebInspector.UIString('Element Classes'), '');
41 if (isEscKey(event)) { 186 this._button.setText('.cls');
42 event.target.textContent = ""; 187 this._button.element.classList.add('monospace');
43 if (!text.isWhitespace()) 188 this._button.addEventListener('click', this._clicked, this);
44 event.consume(true); 189 this._view = new WebInspector.ClassesPaneWidget();
45 return; 190 }
46 } 191
47 192 _clicked() {
48 if (!isEnterKey(event)) 193 WebInspector.ElementsPanel.instance().showToolbarPane(!this._view.isShowing( ) ? this._view : null, this._button);
49 return; 194 }
50 var node = WebInspector.context.flavor(WebInspector.DOMNode); 195
51 if (!node) 196 /**
52 return; 197 * @override
53 198 * @return {!WebInspector.ToolbarItem}
54 this._prompt.clearAutocomplete(); 199 */
55 event.target.textContent = ""; 200 item() {
56 var classNames = text.split(/[.,\s]/); 201 return this._button;
57 for (var className of classNames) { 202 }
58 var className = className.trim();
59 if (!className.length)
60 continue;
61 this._toggleClass(node, className, true);
62 }
63 this._installNodeClasses(node);
64 this._update();
65 event.consume(true);
66 },
67
68 /**
69 * @param {!WebInspector.Event} event
70 */
71 _onDOMMutated: function(event)
72 {
73 var node = /** @type {!WebInspector.DOMNode} */(event.data);
74 if (this._mutatingNodes.has(node))
75 return;
76 delete node[WebInspector.ClassesPaneWidget._classesSymbol];
77 this._update();
78 },
79
80 /**
81 * @override
82 */
83 wasShown: function()
84 {
85 this._update();
86 },
87
88 _update: function()
89 {
90 if (!this.isShowing())
91 return;
92
93 var node = WebInspector.context.flavor(WebInspector.DOMNode);
94 if (node)
95 node = node.enclosingElementOrSelf();
96
97 this._classesContainer.removeChildren();
98 this._input.disabled = !node;
99
100 if (!node)
101 return;
102
103 var classes = this._nodeClasses(node);
104 var keys = classes.keysArray();
105 keys.sort(String.caseInsensetiveComparator);
106 for (var i = 0; i < keys.length; ++i) {
107 var className = keys[i];
108 var label = createCheckboxLabel(className, classes.get(className));
109 label.visualizeFocus = true;
110 label.classList.add("monospace");
111 label.checkboxElement.addEventListener("click", this._onClick.bind(t his, className), false);
112 this._classesContainer.appendChild(label);
113 }
114 },
115
116 /**
117 * @param {string} className
118 * @param {!Event} event
119 */
120 _onClick: function(className, event)
121 {
122 var node = WebInspector.context.flavor(WebInspector.DOMNode);
123 if (!node)
124 return;
125 var enabled = event.target.checked;
126 this._toggleClass(node, className, enabled);
127 this._installNodeClasses(node);
128 },
129
130 /**
131 * @param {!WebInspector.DOMNode} node
132 * @return {!Map<string, boolean>}
133 */
134 _nodeClasses: function(node)
135 {
136 var result = node[WebInspector.ClassesPaneWidget._classesSymbol];
137 if (!result) {
138 var classAttribute = node.getAttribute("class") || "";
139 var classes = classAttribute.split(/\s/);
140 result = new Map();
141 for (var i = 0; i < classes.length; ++i) {
142 var className = classes[i].trim();
143 if (!className.length)
144 continue;
145 result.set(className, true);
146 }
147 node[WebInspector.ClassesPaneWidget._classesSymbol] = result;
148 }
149 return result;
150 },
151
152 /**
153 * @param {!WebInspector.DOMNode} node
154 * @param {string} className
155 * @param {boolean} enabled
156 */
157 _toggleClass: function(node, className, enabled)
158 {
159 var classes = this._nodeClasses(node);
160 classes.set(className, enabled);
161 },
162
163 /**
164 * @param {!WebInspector.DOMNode} node
165 */
166 _installNodeClasses: function(node)
167 {
168 var classes = this._nodeClasses(node);
169 var activeClasses = new Set();
170 for (var className of classes.keys()) {
171 if (classes.get(className))
172 activeClasses.add(className);
173 }
174
175 var newClasses = activeClasses.valuesArray();
176 newClasses.sort();
177 this._mutatingNodes.add(node);
178 node.setAttributeValue("class", newClasses.join(" "), onClassNameUpdated .bind(this));
179
180 /**
181 * @this {WebInspector.ClassesPaneWidget}
182 */
183 function onClassNameUpdated()
184 {
185 this._mutatingNodes.delete(node);
186 }
187 },
188
189 __proto__: WebInspector.Widget.prototype
190 }; 203 };
191 204
192 /** 205 /**
193 * @constructor 206 * @unrestricted
194 * @implements {WebInspector.ToolbarItem.Provider}
195 */ 207 */
196 WebInspector.ClassesPaneWidget.ButtonProvider = function() 208 WebInspector.ClassesPaneWidget.ClassNamePrompt = class extends WebInspector.Text Prompt {
197 { 209 constructor() {
198 this._button = new WebInspector.ToolbarToggle(WebInspector.UIString("Element Classes"), ""); 210 super();
199 this._button.setText(".cls"); 211 this.initialize(this._buildClassNameCompletions.bind(this), ' ');
200 this._button.element.classList.add("monospace");
201 this._button.addEventListener("click", this._clicked, this);
202 this._view = new WebInspector.ClassesPaneWidget();
203 };
204
205 WebInspector.ClassesPaneWidget.ButtonProvider.prototype = {
206 _clicked: function()
207 {
208 WebInspector.ElementsPanel.instance().showToolbarPane(!this._view.isShow ing() ? this._view : null, this._button);
209 },
210
211 /**
212 * @override
213 * @return {!WebInspector.ToolbarItem}
214 */
215 item: function()
216 {
217 return this._button;
218 }
219 };
220
221 /**
222 * @constructor
223 * @extends {WebInspector.TextPrompt}
224 */
225 WebInspector.ClassesPaneWidget.ClassNamePrompt = function()
226 {
227 WebInspector.TextPrompt.call(this);
228 this.initialize(this._buildClassNameCompletions.bind(this), " ");
229 this.setSuggestBoxEnabled(true); 212 this.setSuggestBoxEnabled(true);
230 this.disableDefaultSuggestionForEmptyInput(); 213 this.disableDefaultSuggestionForEmptyInput();
231 this._selectedFrameId = ""; 214 this._selectedFrameId = '';
232 this._classNamesPromise = null; 215 this._classNamesPromise = null;
216 }
217
218 /**
219 * @param {!WebInspector.DOMNode} selectedNode
220 * @return {!Promise.<!Array.<string>>}
221 */
222 _getClassNames(selectedNode) {
223 var promises = [];
224 var completions = new Set();
225 this._selectedFrameId = selectedNode.frameId();
226
227 var cssModel = WebInspector.CSSModel.fromTarget(selectedNode.target());
228 var allStyleSheets = cssModel.allStyleSheets();
229 for (var stylesheet of allStyleSheets) {
230 if (stylesheet.frameId !== this._selectedFrameId)
231 continue;
232 var cssPromise = cssModel.classNamesPromise(stylesheet.id).then(classes => completions.addAll(classes));
233 promises.push(cssPromise);
234 }
235
236 var domPromise = selectedNode.domModel()
237 .classNamesPromise(selectedNode.ownerDocument.id)
238 .then(classes => completions.addAll(classes));
239 promises.push(domPromise);
240 return Promise.all(promises).then(() => completions.valuesArray());
241 }
242
243 /**
244 * @param {!Element} proxyElement
245 * @param {!Range} wordRange
246 * @param {boolean} force
247 * @param {function(!Array.<string>, number=)} completionsReadyCallback
248 */
249 _buildClassNameCompletions(proxyElement, wordRange, force, completionsReadyCal lback) {
250 var prefix = wordRange.toString();
251 if (!prefix || force)
252 this._classNamesPromise = null;
253
254 var selectedNode = WebInspector.context.flavor(WebInspector.DOMNode);
255 if (!selectedNode || (!prefix && !force && !proxyElement.textContent.length) ) {
256 completionsReadyCallback([]);
257 return;
258 }
259
260 if (!this._classNamesPromise || this._selectedFrameId !== selectedNode.frame Id())
261 this._classNamesPromise = this._getClassNames(selectedNode);
262
263 this._classNamesPromise.then(completions => {
264 if (prefix[0] === '.')
265 completions = completions.map(value => '.' + value);
266 var results = completions.filter(value => value.startsWith(prefix));
267 completionsReadyCallback(results, 0);
268 });
269 }
233 }; 270 };
234
235 WebInspector.ClassesPaneWidget.ClassNamePrompt.prototype = {
236 /**
237 * @param {!WebInspector.DOMNode} selectedNode
238 * @return {!Promise.<!Array.<string>>}
239 */
240 _getClassNames: function(selectedNode)
241 {
242 var promises = [];
243 var completions = new Set();
244 this._selectedFrameId = selectedNode.frameId();
245
246 var cssModel = WebInspector.CSSModel.fromTarget(selectedNode.target());
247 var allStyleSheets = cssModel.allStyleSheets();
248 for (var stylesheet of allStyleSheets) {
249 if (stylesheet.frameId !== this._selectedFrameId)
250 continue;
251 var cssPromise = cssModel.classNamesPromise(stylesheet.id).then(clas ses => completions.addAll(classes));
252 promises.push(cssPromise);
253 }
254
255 var domPromise = selectedNode.domModel().classNamesPromise(selectedNode. ownerDocument.id).then(classes => completions.addAll(classes));
256 promises.push(domPromise);
257 return Promise.all(promises).then(() => completions.valuesArray());
258 },
259
260 /**
261 * @param {!Element} proxyElement
262 * @param {!Range} wordRange
263 * @param {boolean} force
264 * @param {function(!Array.<string>, number=)} completionsReadyCallback
265 */
266 _buildClassNameCompletions: function(proxyElement, wordRange, force, complet ionsReadyCallback)
267 {
268 var prefix = wordRange.toString();
269 if (!prefix || force)
270 this._classNamesPromise = null;
271
272 var selectedNode = WebInspector.context.flavor(WebInspector.DOMNode);
273 if (!selectedNode || (!prefix && !force && !proxyElement.textContent.len gth)) {
274 completionsReadyCallback([]);
275 return;
276 }
277
278 if (!this._classNamesPromise || this._selectedFrameId !== selectedNode.f rameId())
279 this._classNamesPromise = this._getClassNames(selectedNode);
280
281 this._classNamesPromise.then(completions => {
282 if (prefix[0] === ".")
283 completions = completions.map(value => "." + value);
284 var results = completions.filter(value => value.startsWith(prefix));
285 completionsReadyCallback(results, 0);
286 });
287 },
288
289 __proto__: WebInspector.TextPrompt.prototype
290 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698