Chromium Code Reviews| Index: third_party/WebKit/Source/devtools/front_end/elements/ClassesPaneWidget.js |
| diff --git a/third_party/WebKit/Source/devtools/front_end/elements/ClassesPaneWidget.js b/third_party/WebKit/Source/devtools/front_end/elements/ClassesPaneWidget.js |
| index fb51c7711602456714e7f61fcceeb49355e810b3..e36000e33a1e838062ccda2773288583173c16ac 100644 |
| --- a/third_party/WebKit/Source/devtools/front_end/elements/ClassesPaneWidget.js |
| +++ b/third_party/WebKit/Source/devtools/front_end/elements/ClassesPaneWidget.js |
| @@ -19,44 +19,68 @@ Elements.ClassesPaneWidget = class extends UI.Widget { |
| var proxyElement = this._prompt.attach(this._input); |
| this._prompt.setPlaceholder(Common.UIString('Add new class')); |
| + this._prompt.on(UI.TextPrompt.TextChangedEvent, this._onTextChanged, this); |
| proxyElement.addEventListener('keydown', this._onKeyDown.bind(this), false); |
| SDK.targetManager.addModelListener(SDK.DOMModel, SDK.DOMModel.Events.DOMMutated, this._onDOMMutated, this); |
| /** @type {!Set<!SDK.DOMNode>} */ |
| this._mutatingNodes = new Set(); |
| - UI.context.addFlavorChangeListener(SDK.DOMNode, this._update, this); |
| + this._updateNodeThrottler = new Common.Throttler(0); |
| + /** @type {?SDK.DOMNode} */ |
| + this._previousTarget = null; |
| + UI.context.addFlavorChangeListener(SDK.DOMNode, this._onFlavorChange, this); |
| + } |
| + |
| + /** |
| + * @param {string} text |
| + * @return {!Array.<string>} |
| + */ |
| + _splitTextIntoClasses(text) { |
| + return text.split(/[.,\s]/) |
| + .map(className => className.trim()) |
| + .filter(className => className.length); |
| } |
| /** |
| * @param {!Event} event |
| */ |
| _onKeyDown(event) { |
| + if (!isEnterKey(event) && !isEscKey(event)) |
| + return; |
| + |
| var text = event.target.textContent; |
| if (isEscKey(event)) { |
| - event.target.textContent = ''; |
| if (!text.isWhitespace()) |
| event.consume(true); |
| - return; |
| + text = ''; |
| } |
| - if (!isEnterKey(event)) |
| - return; |
| + if (isEnterKey(event)) |
| + event.consume(true); |
| + |
| + this._prompt.clearAutocomplete(); |
| + event.target.textContent = ''; |
| + |
| var node = UI.context.flavor(SDK.DOMNode); |
| if (!node) |
| return; |
| - this._prompt.clearAutocomplete(); |
| - event.target.textContent = ''; |
| - var classNames = text.split(/[.,\s]/); |
| - for (var className of classNames) { |
| - var className = className.trim(); |
| - if (!className.length) |
| - continue; |
| + var classNames = this._splitTextIntoClasses(text); |
| + for (var className of classNames) |
| this._toggleClass(node, className, true); |
| - } |
| this._installNodeClasses(node); |
| this._update(); |
| - event.consume(true); |
| + } |
| + |
| + _onTextChanged() { |
| + var node = UI.context.flavor(SDK.DOMNode); |
| + if (!node) |
| + return; |
| + var text = this._prompt.textWithCurrentSuggestion(); |
| + var classes = this._splitTextIntoClasses(text); |
| + |
| + this._installNodeClasses(node, classes); |
| + this._update(); |
|
lushnikov
2017/03/22 01:37:33
you don't need _update() here, do you?
|
| } |
| /** |
| @@ -71,6 +95,18 @@ Elements.ClassesPaneWidget = class extends UI.Widget { |
| } |
| /** |
| + * @param {!Common.Event} event |
| + */ |
| + _onFlavorChange(event) { |
|
lushnikov
2017/03/22 01:37:33
let's name this _onSelectedNodeChanged
|
| + if (this._previousTarget && this._prompt.text()) { |
| + this._input.textContent = ''; |
| + this._installNodeClasses(this._previousTarget, [], true); |
| + } |
| + this._previousTarget = /** @type {?SDK.DOMNode} */ (event.data); |
| + this._update(); |
| + } |
| + |
| + /** |
| * @override |
| */ |
| wasShown() { |
| @@ -150,8 +186,10 @@ Elements.ClassesPaneWidget = class extends UI.Widget { |
| /** |
| * @param {!SDK.DOMNode} node |
| + * @param {!Array.<string>=} additionalClasses |
| + * @param {boolean=} immediately |
| */ |
| - _installNodeClasses(node) { |
| + _installNodeClasses(node, additionalClasses, immediately) { |
| var classes = this._nodeClasses(node); |
| var activeClasses = new Set(); |
| for (var className of classes.keys()) { |
| @@ -159,17 +197,39 @@ Elements.ClassesPaneWidget = class extends UI.Widget { |
| activeClasses.add(className); |
| } |
| + if (additionalClasses) { |
|
lushnikov
2017/03/22 01:37:33
it looks like you never want to call "_installNode
|
| + for (className of additionalClasses) |
| + activeClasses.add(className); |
| + } |
| var newClasses = activeClasses.valuesArray(); |
| newClasses.sort(); |
| + |
| + if (immediately) |
| + this._updateNodeThrottler.flush(); |
|
lushnikov
2017/03/22 01:37:33
i looked closer into the flush() method and it tur
|
| + this._updateNodeThrottler.schedule(this._setClassValue.bind(this, node, newClasses.join(' '))); |
| + } |
| + |
| + /** |
| + * @param {!SDK.DOMNode} node |
| + * @param {string} value |
| + * @return {!Promise} |
| + */ |
| + _setClassValue(node, value) { |
| + var fulfill; |
| + var promise = new Promise(f => fulfill = f); |
| + |
| this._mutatingNodes.add(node); |
| - node.setAttributeValue('class', newClasses.join(' '), onClassNameUpdated.bind(this)); |
| + node.setAttributeValue('class', value, onClassValueUpdated.bind(this)); |
| /** |
| * @this {Elements.ClassesPaneWidget} |
| */ |
| - function onClassNameUpdated() { |
| + function onClassValueUpdated() { |
| this._mutatingNodes.delete(node); |
| + fulfill(); |
| } |
| + |
| + return promise; |
| } |
| }; |