diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebInspectorUI/UserInterface/Views/VisualStylePropertyCombiner.js | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/WebInspectorUI/UserInterface/Views/VisualStylePropertyCombiner.js')
-rw-r--r-- | Source/WebInspectorUI/UserInterface/Views/VisualStylePropertyCombiner.js | 204 |
1 files changed, 204 insertions, 0 deletions
diff --git a/Source/WebInspectorUI/UserInterface/Views/VisualStylePropertyCombiner.js b/Source/WebInspectorUI/UserInterface/Views/VisualStylePropertyCombiner.js new file mode 100644 index 000000000..285868e2b --- /dev/null +++ b/Source/WebInspectorUI/UserInterface/Views/VisualStylePropertyCombiner.js @@ -0,0 +1,204 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +WebInspector.VisualStylePropertyCombiner = class VisualStylePropertyCombiner extends WebInspector.Object +{ + constructor(propertyName, propertyEditors, spreadNumberValues) + { + super(); + + this._style = null; + this._propertyName = propertyName; + this._propertyMissing = false; + this._propertyEditors = propertyEditors || []; + this._spreadNumberValues = !!spreadNumberValues && this._propertyEditors.length >= 4; + + for (let editor of this._propertyEditors) { + editor.addEventListener(WebInspector.VisualStylePropertyEditor.Event.ValueDidChange, this._handlePropertyEditorValueChanged, this); + editor.suppressStyleTextUpdate = true; + } + + this._textContainsNameRegExp = new RegExp("(?:(?:^|;)\\s*" + this._propertyName + "\\s*:)"); + this._replacementRegExp = new RegExp("((?:^|;)\\s*)(" + this._propertyName + ")(.+?(?:;|$))"); + this._valueRegExp = /([^\s]+\(.+\)|[^\s]+)(?:;?)/g; + } + + get style() + { + return this._style; + } + + get synthesizedValue() + { + let value = ""; + let oneEditorHasValue = false; + for (let editor of this._propertyEditors) { + let editorValue = editor.synthesizedValue; + if (editorValue && editorValue.length) + oneEditorHasValue = true; + else if (editor.optionalProperty) + continue; + + if (editor.masterProperty && editor.valueIsSupportedKeyword(editor.value)) { + this._markEditors(editor, true); + return editorValue; + } + + if (editor !== this._propertyEditors[0]) + value += " "; + + value += editorValue || (editor.colorProperty ? "transparent" : 0); + } + + this._markEditors(); + return value.length && oneEditorHasValue ? value : null; + } + + modifyPropertyText(text, value) + { + if (this._textContainsNameRegExp.test(text)) + text = text.replace(this._replacementRegExp, value !== null ? "$1$2: " + value + ";" : "$1"); + else if (value !== null) + text += WebInspector.VisualStylePropertyEditor.generateFormattedTextForNewProperty(text, this._propertyName, value); + + return text; + } + + update(style) + { + if (style) + this._style = style; + else if (this._ignoreNextUpdate) { + this._ignoreNextUpdate = false; + return; + } + + if (!this._style || !this._valueRegExp) + return; + + let property = this._style.propertyForName(this._propertyName, true); + let propertyMissing = !property; + if (propertyMissing && this._style.nodeStyles) + property = this._style.nodeStyles.computedStyle.propertyForName(this._propertyName); + + if (!property) + return; + + this.updateValuesFromText(property.value, propertyMissing); + this._propertyMissing = propertyMissing; + } + + updateValuesFromText(styleText, propertyMissing) + { + if (styleText === this.synthesizedValue) + return; + + for (let editor of this._propertyEditors) + editor[WebInspector.VisualStylePropertyCombiner.EditorUpdatedSymbol] = false; + + function updateEditor(editor, value) { + let updatedValues = editor.getValuesFromText(value || "", propertyMissing); + if (!updatedValues) + return; + + editor.updateEditorValues(updatedValues); + editor[WebInspector.VisualStylePropertyCombiner.EditorUpdatedSymbol] = true; + } + + if (this._spreadNumberValues) { + let numberValues = styleText.match(/\d+[\w%]*/g); + let count = numberValues && numberValues.length; + if (count === 1) { + for (let editor of this._propertyEditors) + updateEditor(editor, numberValues[0]); + } else if (count === 2) { + for (let i = 0; i < count; ++i) { + updateEditor(this._propertyEditors[i], numberValues[i]); + updateEditor(this._propertyEditors[i + 2], numberValues[i]); + } + } else if (count === 3) { + updateEditor(this._propertyEditors[0], numberValues[0]); + updateEditor(this._propertyEditors[1], numberValues[1]); + updateEditor(this._propertyEditors[2], numberValues[2]); + updateEditor(this._propertyEditors[3], numberValues[1]); + } + } + + function updateCompatibleEditor(value) { + for (let editor of this._propertyEditors) { + if (value && !editor.valueIsCompatible(value) || editor[WebInspector.VisualStylePropertyCombiner.EditorUpdatedSymbol]) + continue; + + if (this._currentValueIsKeyword && editor.disabled) + continue; + + updateEditor(editor, value); + if (value) + return; + } + } + + let matches = styleText.match(this._valueRegExp); + for (let i = 0; i < this._propertyEditors.length; ++i) + updateCompatibleEditor.call(this, matches && matches[i]); + } + + get propertyMissing() + { + return this._propertyMissing; + } + + resetEditorValues(value) + { + this._ignoreNextUpdate = false; + this.updateValuesFromText(value || ""); + } + + // Private + + _markEditors(ignoredEditor, disabled) + { + this._currentValueIsKeyword = disabled || false; + for (let editor of this._propertyEditors) { + if (ignoredEditor && editor === ignoredEditor) + continue; + + editor.disabled = this._currentValueIsKeyword; + } + } + + _handlePropertyEditorValueChanged() + { + this._ignoreNextUpdate = true; + let value = this.synthesizedValue; + if (this._style) + this._style.text = this.modifyPropertyText(this._style.text, value); + + this._propertyMissing = !value; + this.dispatchEventToListeners(WebInspector.VisualStylePropertyEditor.Event.ValueDidChange); + } +}; + +WebInspector.VisualStylePropertyCombiner.EditorUpdatedSymbol = Symbol("visual-style-property-combiner-editor-updated"); |