Diff
Modified: trunk/Source/WebInspectorUI/ChangeLog (204774 => 204775)
--- trunk/Source/WebInspectorUI/ChangeLog 2016-08-23 07:17:11 UTC (rev 204774)
+++ trunk/Source/WebInspectorUI/ChangeLog 2016-08-23 07:23:24 UTC (rev 204775)
@@ -1,3 +1,143 @@
+2016-08-23 Devin Rousso <[email protected]>
+
+ Web Inspector: Add visual editor for spring() timing-function
+ https://bugs.webkit.org/show_bug.cgi?id=159315
+
+ Reviewed by Joseph Pecoraro.
+
+ * Localizations/en.lproj/localizedStrings.js:
+ * UserInterface/Main.html:
+
+ * UserInterface/Base/Utilities.js:
+ (Number.prototype.maxDecimals):
+ Limits the number of decimals for the number object via rounding.
+
+ * UserInterface/Controllers/CodeMirrorSpringEditingController.js:
+ (WebInspector.CodeMirrorSpringEditingController.prototype.get initialValue):
+ (WebInspector.CodeMirrorSpringEditingController.prototype.get cssClassName):
+ (WebInspector.CodeMirrorSpringEditingController.prototype.popoverWillPresent):
+ (WebInspector.CodeMirrorSpringEditingController.prototype.popoverDidPresent):
+ (WebInspector.CodeMirrorSpringEditingController.prototype.popoverDidDismiss):
+ (WebInspector.CodeMirrorSpringEditingController.prototype._springEditorSpringChanged):
+ Controller for Spring editors inside CodeMirror instances.
+
+ * UserInterface/Models/Geometry.js:
+ (WebInspector.Spring):
+ (WebInspector.Spring.fromValues):
+ (WebInspector.Spring.fromString):
+ (WebInspector.Spring.prototype.copy):
+ (WebInspector.Spring.prototype.toString):
+ (WebInspector.Spring.prototype.solve):
+ (WebInspector.Spring.prototype.calculateDuration):
+ Spring data class based on <https://webkit.org/demos/spring/>.
+
+ * UserInterface/Models/TextMarker.js:
+ (WebInspector.TextMarker.Type):
+ Added Spring marker type.
+
+ * UserInterface/Views/CSSStyleDeclarationTextEditor.js:
+ (WebInspector.CSSStyleDeclarationTextEditor.prototype._createInlineSwatches):
+ (WebInspector.CSSStyleDeclarationTextEditor.prototype._createInlineSwatches.update):
+ (WebInspector.CSSStyleDeclarationTextEditor.prototype._inlineSwatchValueChanged):
+ (WebInspector.CSSStyleDeclarationTextEditor.prototype._inlineSwatchValueChanged.update):
+
+ * UserInterface/Views/CodeMirrorTextMarkers.js:
+ (createCodeMirrorSpringTextMarkers):
+
+ * UserInterface/Views/InlineSwatch.css:
+ (.inline-swatch:matches(.bezier, .spring)):
+ (.inline-swatch:matches(.bezier, .spring):hover):
+ (.inline-swatch:matches(.bezier, .spring):active):
+ (.inline-swatch:matches(.bezier, .spring) > span):
+ (.inline-swatch.bezier): Deleted.
+ (.inline-swatch.bezier:hover): Deleted.
+ (.inline-swatch.bezier:active): Deleted.
+ (.inline-swatch.bezier > span): Deleted.
+
+ * UserInterface/Views/InlineSwatch.js:
+ (WebInspector.InlineSwatch):
+ (WebInspector.InlineSwatch.prototype._fallbackValue):
+ (WebInspector.InlineSwatch.prototype._swatchElementClicked):
+ (WebInspector.InlineSwatch.prototype._valueEditorValueDidChange):
+ (WebInspector.InlineSwatch.Type):
+ Added support for Spring editor Inline Swatches.
+
+ * UserInterface/Views/SourceCodeTextEditor.js:
+ (WebInspector.SourceCodeTextEditor.prototype._updateEditableMarkers):
+ (WebInspector.SourceCodeTextEditor.prototype._tokenTrackingControllerHighlightedMarkedExpression):
+
+ * UserInterface/Views/SpringEditor.css:
+ (.spring-editor):
+ (.spring-editor > .spring-preview):
+ (.spring-editor > .spring-preview > div):
+ (.spring-editor > .spring-timing):
+ (.spring-editor > .spring-timing > div):
+ (.spring-editor > .spring-timing:matches(::before, ::after)):
+ (.spring-editor > .spring-timing::before):
+ (.spring-editor > .spring-timing::after):
+ (.spring-editor > :matches(.spring-preview, .spring-timing) > div):
+ (.spring-editor > .animate:matches(.spring-preview, .spring-timing) > div):
+ (.spring-editor > .number-input-container > .number-input-row):
+ (.spring-editor > .number-input-container > .number-input-row > .number-input-row-title):
+ (.spring-editor > .number-input-container > .number-input-row > input):
+ (.spring-editor > .number-input-container > .number-input-row > input[type="range"]):
+
+ * UserInterface/Views/SpringEditor.js:
+ (WebInspector.SpringEditor):
+ (WebInspector.SpringEditor.prototype.get element):
+ (WebInspector.SpringEditor.prototype.set spring):
+ (WebInspector.SpringEditor.prototype.get spring):
+ (WebInspector.SpringEditor.prototype._handleNumberInputInput):
+ (WebInspector.SpringEditor.prototype._handleNumberInputKeydown):
+ (WebInspector.SpringEditor.prototype._handleNumberSliderInput):
+ (WebInspector.SpringEditor.prototype._handleNumberSliderMousedown):
+ (WebInspector.SpringEditor.prototype._handleNumberSliderMouseup):
+ (WebInspector.SpringEditor.prototype._changeSpringForInput):
+ (WebInspector.SpringEditor.prototype._resetPreviewAnimation):
+ (WebInspector.SpringEditor.prototype._updatePreviewAnimation):
+ (WebInspector.SpringEditor.Event):
+ Visual editor for CSS Spring timing function values. Organized into 5 rows:
+ - Preview: shows movement of spring and total duration
+ - Mass: slider and input for "mass" parameter
+ - Stiffness: slider and input for "stiffness" parameter
+ - Damping: slider and input for "damping" parameter
+ - Initial Velocity: slider and input for "initial velocity" parameter
+ The preview animation will loop indefinitely until the user clicks the animation row
+ or changes the value of one of the parameters, at which point the duration will also
+ be recalculated.
+
+ * UserInterface/Views/TextEditor.js:
+ (WebInspector.TextEditor.prototype.createSpringMarkers):
+ (WebInspector.TextEditor.prototype.editingControllerForMarker):
+
+ * UserInterface/Views/VisualStyleCommaSeparatedKeywordEditor.js:
+ (WebInspector.VisualStyleCommaSeparatedKeywordEditor.prototype.set value):
+ (WebInspector.VisualStyleCommaSeparatedKeywordEditor.prototype._generateTextFromLonghandProperties):
+ Add support for CSS spring timing functions by allowing parenthesis in comma separated
+ values so long as there are no commas inside the parenthesis.
+
+ * UserInterface/Views/VisualStyleTimingEditor.css:
+ (.visual-style-property-container.timing-editor > .visual-style-property-value-container > .inline-swatch:matches(.bezier, .spring)):
+ (.visual-style-property-container.timing-editor > .visual-style-property-value-container:not(.spring-value) > .inline-swatch.spring):
+ (.visual-style-property-container.timing-editor > .visual-style-property-value-container > .inline-swatch.bezier): Deleted.
+ (.visual-style-property-container.timing-editor > .visual-style-property-value-container:not(.bezier-value) > .inline-swatch.bezier): Deleted.
+
+ * UserInterface/Views/VisualStyleTimingEditor.js:
+ (WebInspector.VisualStyleTimingEditor):
+ (WebInspector.VisualStyleTimingEditor.prototype.get value):
+ (WebInspector.VisualStyleTimingEditor.prototype.set value):
+ (WebInspector.VisualStyleTimingEditor.prototype.get synthesizedValue):
+ (WebInspector.VisualStyleTimingEditor.prototype.parseValue):
+ (WebInspector.VisualStyleTimingEditor.prototype.get _bezierValue):
+ (WebInspector.VisualStyleTimingEditor.prototype.set _bezierValue):
+ (WebInspector.VisualStyleTimingEditor.prototype.get _springValue):
+ (WebInspector.VisualStyleTimingEditor.prototype.set _springValue):
+ (WebInspector.VisualStyleTimingEditor.prototype._handleKeywordChanged):
+ (WebInspector.VisualStyleTimingEditor.prototype._springSwatchValueChanged):
+ (WebInspector.VisualStyleTimingEditor.prototype.get bezierValue): Renamed.
+ (WebInspector.VisualStyleTimingEditor.prototype.set bezierValue): Renamed.
+ Duplicate Bezier custom timing function logic for Spring timing functions.
+
2016-08-22 Devin Rousso <[email protected]>
Web Inspector: Styles -> Computed -> Box Model shows NaN x NaN for invisible elements
Modified: trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js (204774 => 204775)
--- trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js 2016-08-23 07:17:11 UTC (rev 204774)
+++ trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js 2016-08-23 07:23:24 UTC (rev 204775)
@@ -102,6 +102,7 @@
localizedStrings["Back (%s)"] = "Back (%s)";
localizedStrings["Background"] = "Background";
localizedStrings["Basis"] = "Basis";
+localizedStrings["Bezier"] = "Bezier";
localizedStrings["Blend"] = "Blend";
localizedStrings["Block Variables"] = "Block Variables";
localizedStrings["Blur"] = "Blur";
@@ -153,6 +154,7 @@
localizedStrings["Click to enable the selected rule"] = "Click to enable the selected rule";
localizedStrings["Click to link property values"] = "Click to link property values";
localizedStrings["Click to open a cubic-bezier editor."] = "Click to open a cubic-bezier editor.";
+localizedStrings["Click to open a spring editor."] = "Click to open a spring editor.";
localizedStrings["Click to remove link"] = "Click to remove link";
localizedStrings["Click to remove the selected item."] = "Click to remove the selected item.";
localizedStrings["Click to restart the animation"] = "Click to restart the animation";
@@ -208,8 +210,8 @@
localizedStrings["Create a new tab"] = "Create a new tab";
localizedStrings["Current"] = "Current";
localizedStrings["Cursor"] = "Cursor";
-localizedStrings["Custom"] = "Custom";
localizedStrings["DOM Content Loaded \u2014 %s"] = "DOM Content Loaded \u2014 %s";
+localizedStrings["Damping"] = "Damping";
localizedStrings["Dash Array"] = "Dash Array";
localizedStrings["Data"] = "Data";
localizedStrings["Data returned from the database is too large."] = "Data returned from the database is too large.";
@@ -402,6 +404,7 @@
localizedStrings["Info: "] = "Info: ";
localizedStrings["Inherited From: "] = "Inherited From: ";
localizedStrings["Inherited from %s"] = "Inherited from %s";
+localizedStrings["Initial Velocity"] = "Initial Velocity";
localizedStrings["Initiated"] = "Initiated";
localizedStrings["Initiator"] = "Initiator";
localizedStrings["Input: "] = "Input: ";
@@ -454,6 +457,7 @@
localizedStrings["Main Frame"] = "Main Frame";
localizedStrings["Manifest URL"] = "Manifest URL";
localizedStrings["Margin"] = "Margin";
+localizedStrings["Mass"] = "Mass";
localizedStrings["Max"] = "Max";
localizedStrings["Max Comparison"] = "Max Comparison";
localizedStrings["Maximum"] = "Maximum";
@@ -674,6 +678,7 @@
localizedStrings["Specificity: No value for selected element"] = "Specificity: No value for selected element";
localizedStrings["Spelling"] = "Spelling";
localizedStrings["Spread"] = "Spread";
+localizedStrings["Spring"] = "Spring";
localizedStrings["Start Playback"] = "Start Playback";
localizedStrings["Start Recording"] = "Start Recording";
localizedStrings["Start Time"] = "Start Time";
@@ -685,6 +690,7 @@
localizedStrings["Step into (%s or %s)"] = "Step into (%s or %s)";
localizedStrings["Step out (%s or %s)"] = "Step out (%s or %s)";
localizedStrings["Step over (%s or %s)"] = "Step over (%s or %s)";
+localizedStrings["Stiffness"] = "Stiffness";
localizedStrings["Stop Recording"] = "Stop Recording";
localizedStrings["Stop element selection (%s)"] = "Stop element selection (%s)";
localizedStrings["Stop recording (%s)"] = "Stop recording (%s)";
Modified: trunk/Source/WebInspectorUI/UserInterface/Base/Utilities.js (204774 => 204775)
--- trunk/Source/WebInspectorUI/UserInterface/Base/Utilities.js 2016-08-23 07:17:11 UTC (rev 204774)
+++ trunk/Source/WebInspectorUI/UserInterface/Base/Utilities.js 2016-08-23 07:23:24 UTC (rev 204775)
@@ -1069,6 +1069,15 @@
}
});
+Object.defineProperty(Number.prototype, "maxDecimals",
+{
+ value(decimals)
+ {
+ let power = 10 ** decimals;
+ return Math.round(this * power) / power;
+ }
+});
+
Object.defineProperty(Uint32Array, "isLittleEndian",
{
value: function()
Copied: trunk/Source/WebInspectorUI/UserInterface/Controllers/CodeMirrorSpringEditingController.js (from rev 204772, trunk/Source/WebInspectorUI/UserInterface/Views/VisualStyleTimingEditor.css) (0 => 204775)
--- trunk/Source/WebInspectorUI/UserInterface/Controllers/CodeMirrorSpringEditingController.js (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Controllers/CodeMirrorSpringEditingController.js 2016-08-23 07:23:24 UTC (rev 204775)
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2016 Devin Rousso <[email protected]>. 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.CodeMirrorSpringEditingController = class CodeMirrorSpringEditingController extends WebInspector.CodeMirrorEditingController
+{
+ // Public
+
+ get initialValue()
+ {
+ return WebInspector.Spring.fromString(this.text);
+ }
+
+ get cssClassName()
+ {
+ return "spring";
+ }
+
+ popoverWillPresent(popover)
+ {
+ this._springEditor = new WebInspector.SpringEditor;
+ this._springEditor.addEventListener(WebInspector.SpringEditor.Event.SpringChanged, this._springEditorSpringChanged, this);
+ popover.content = this._springEditor.element;
+ }
+
+ popoverDidPresent(popover)
+ {
+ this._springEditor.spring = this.value;
+ }
+
+ popoverDidDismiss(popover)
+ {
+ this._springEditor.removeListeners();
+ }
+
+ // Private
+
+ _springEditorSpringChanged(event)
+ {
+ this.value = event.data.spring;
+ }
+};
Modified: trunk/Source/WebInspectorUI/UserInterface/Main.html (204774 => 204775)
--- trunk/Source/WebInspectorUI/UserInterface/Main.html 2016-08-23 07:17:11 UTC (rev 204774)
+++ trunk/Source/WebInspectorUI/UserInterface/Main.html 2016-08-23 07:23:24 UTC (rev 204775)
@@ -151,6 +151,7 @@
<link rel="stylesheet" href=""
<link rel="stylesheet" href=""
<link rel="stylesheet" href=""
+ <link rel="stylesheet" href=""
<link rel="stylesheet" href=""
<link rel="stylesheet" href=""
<link rel="stylesheet" href=""
@@ -621,6 +622,7 @@
<script src=""
<script src=""
<script src=""
+ <script src=""
<script src=""
<script src=""
<script src=""
@@ -680,6 +682,7 @@
<script src=""
<script src=""
<script src=""
+ <script src=""
<script src=""
<script src=""
<script src=""
Modified: trunk/Source/WebInspectorUI/UserInterface/Models/Geometry.js (204774 => 204775)
--- trunk/Source/WebInspectorUI/UserInterface/Models/Geometry.js 2016-08-23 07:17:11 UTC (rev 204774)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/Geometry.js 2016-08-23 07:23:24 UTC (rev 204775)
@@ -476,3 +476,96 @@
"ease-in-out": [0.42, 0, 0.58, 1],
"linear": [0, 0, 1, 1]
};
+
+WebInspector.Spring = class Spring
+{
+ constructor(mass, stiffness, damping, initialVelocity)
+ {
+ this.mass = Math.max(1, mass);
+ this.stiffness = Math.max(1, stiffness);
+ this.damping = Math.max(0, damping);
+ this.initialVelocity = initialVelocity;
+ }
+
+ // Static
+
+ static fromValues(values)
+ {
+ if (!values || values.length < 4)
+ return null;
+
+ values = values.map(Number);
+ if (values.includes(NaN))
+ return null;
+
+ return new WebInspector.Spring(...values);
+ }
+
+ static fromString(text)
+ {
+ if (!text || !text.length)
+ return null;
+
+ let trimmedText = text.toLowerCase().trim();
+ if (!trimmedText.length)
+ return null;
+
+ let matches = trimmedText.match(/^spring\(([\d.]+)\s+([\d.]+)\s+([\d.]+)\s+([-\d.]+)\)$/);
+ if (!matches)
+ return null;
+
+ return WebInspector.Spring.fromValues(matches.slice(1));
+ }
+
+ // Public
+
+ copy()
+ {
+ return new WebInspector.Spring(this.mass, this.stiffness, this.damping, this.initialVelocity);
+ }
+
+ toString()
+ {
+ return `spring(${this.mass} ${this.stiffness} ${this.damping} ${this.initialVelocity})`;
+ }
+
+ solve(t)
+ {
+ let w0 = Math.sqrt(this.stiffness / this.mass);
+ let zeta = this.damping / (2 * Math.sqrt(this.stiffness * this.mass));
+
+ let wd = 0;
+ let A = 1;
+ let B = -this.initialVelocity + w0;
+ if (zeta < 1) {
+ // Under-damped.
+ wd = w0 * Math.sqrt(1 - zeta * zeta);
+ A = 1;
+ B = (zeta * w0 + -this.initialVelocity) / wd;
+ }
+
+ if (zeta < 1) // Under-damped
+ t = Math.exp(-t * zeta * w0) * (A * Math.cos(wd * t) + B * Math.sin(wd * t));
+ else // Critically damped (ignoring over-damped case).
+ t = (A + B * t) * Math.exp(-t * w0);
+
+ return 1 - t; // Map range from [1..0] to [0..1].
+ }
+
+ calculateDuration(epsilon)
+ {
+ epsilon = epsilon || 0.0001;
+ let t = 0;
+ let current = 0;
+ let minimum = Number.POSITIVE_INFINITY;
+ while (current >= epsilon || minimum >= epsilon) {
+ current = Math.abs(1 - this.solve(t)); // Undo the range mapping
+ if (minimum < epsilon && current >= epsilon)
+ minimum = Number.POSITIVE_INFINITY; // Spring reversed direction
+ else if (current < minimum)
+ minimum = current;
+ t += 0.1;
+ }
+ return t;
+ }
+}
Modified: trunk/Source/WebInspectorUI/UserInterface/Models/TextMarker.js (204774 => 204775)
--- trunk/Source/WebInspectorUI/UserInterface/Models/TextMarker.js 2016-08-23 07:17:11 UTC (rev 204774)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/TextMarker.js 2016-08-23 07:23:24 UTC (rev 204775)
@@ -83,5 +83,6 @@
Color: "text-marker-type-color",
Gradient: "text-marker-type-gradient",
Plain: "text-marker-type-plain",
- CubicBezier: "text-marker-type-cubic-bezier"
+ CubicBezier: "text-marker-type-cubic-bezier",
+ Spring: "text-marker-type-spring",
};
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/CSSStyleDeclarationTextEditor.js (204774 => 204775)
--- trunk/Source/WebInspectorUI/UserInterface/Views/CSSStyleDeclarationTextEditor.js 2016-08-23 07:17:11 UTC (rev 204774)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/CSSStyleDeclarationTextEditor.js 2016-08-23 07:23:24 UTC (rev 204775)
@@ -886,6 +886,12 @@
let swatch = new WebInspector.InlineSwatch(WebInspector.InlineSwatch.Type.Bezier, bezier, this._codeMirror.getOption("readOnly"));
createSwatch.call(this, swatch, marker, bezier, bezierString);
});
+
+ // Look for spring strings and add swatches in front of them.
+ createCodeMirrorSpringTextMarkers(this._codeMirror, range, (marker, spring, springString) => {
+ let swatch = new WebInspector.InlineSwatch(WebInspector.InlineSwatch.Type.Spring, spring, this._codeMirror.getOption("readOnly"));
+ createSwatch.call(this, swatch, marker, spring, springString);
+ });
}
if (nonatomic)
@@ -1318,8 +1324,9 @@
for (let mark of marks) {
let type = WebInspector.TextMarker.textMarkerForCodeMirrorTextMarker(mark).type;
- if (type !== WebInspector.TextMarker.Type.Color && type !== WebInspector.TextMarker.Type.Gradient && type !== WebInspector.TextMarker.Type.CubicBezier)
+ if (Object.values(WebInspector.TextMarker.Type).includes(type))
continue;
+
textMarker = mark;
break;
}
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/CodeMirrorTextMarkers.js (204774 => 204775)
--- trunk/Source/WebInspectorUI/UserInterface/Views/CodeMirrorTextMarkers.js 2016-08-23 07:17:11 UTC (rev 204774)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/CodeMirrorTextMarkers.js 2016-08-23 07:23:24 UTC (rev 204775)
@@ -195,3 +195,9 @@
var cubicBezierRegex = /(cubic-bezier\([^)]+\)|\b\w+\b(?:-\b\w+\b){0,2})/g;
return createCodeMirrorTextMarkers("CubicBezier", cubicBezierRegex, null, codeMirror, range, callback);
}
+
+function createCodeMirrorSpringTextMarkers(codeMirror, range, callback)
+{
+ const springRegex = /(spring\([^)]+\))/g;
+ return createCodeMirrorTextMarkers("Spring", springRegex, null, codeMirror, range, callback);
+}
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/InlineSwatch.css (204774 => 204775)
--- trunk/Source/WebInspectorUI/UserInterface/Views/InlineSwatch.css 2016-08-23 07:17:11 UTC (rev 204774)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/InlineSwatch.css 2016-08-23 07:23:24 UTC (rev 204775)
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2015 Apple Inc. All rights reserved.
- * Copyright (C) 2015 Devin Rousso <[email protected]>. All rights reserved.
+ * Copyright (C) 2015-2016 Devin Rousso <[email protected]>. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -43,17 +43,20 @@
cursor: default;
}
-.inline-swatch.bezier {
+.inline-swatch:matches(.bezier, .spring) {
+ content: url(../Images/CubicBezier.svg);
+}
+
+.inline-swatch:matches(.bezier, .spring) {
margin-right: 2px;
- content: url(../Images/CubicBezier.svg);
background: none;
}
-.inline-swatch.bezier:hover {
+.inline-swatch:matches(.bezier, .spring):hover {
filter: brightness(0.9);
}
-.inline-swatch.bezier:active {
+.inline-swatch:matches(.bezier, .spring):active {
filter: brightness(0.8);
}
@@ -85,7 +88,7 @@
border-color: hsl(0, 0%, 25%);
}
-.inline-swatch.bezier > span {
+.inline-swatch:matches(.bezier, .spring) > span {
display: none;
}
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/InlineSwatch.js (204774 => 204775)
--- trunk/Source/WebInspectorUI/UserInterface/Views/InlineSwatch.js 2016-08-23 07:17:11 UTC (rev 204774)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/InlineSwatch.js 2016-08-23 07:23:24 UTC (rev 204775)
@@ -39,6 +39,9 @@
case WebInspector.InlineSwatch.Type.Bezier:
this._swatchElement.title = WebInspector.UIString("Click to open a cubic-bezier editor.");
break;
+ case WebInspector.InlineSwatch.Type.Spring:
+ this._swatchElement.title = WebInspector.UIString("Click to open a spring editor.");
+ break;
case WebInspector.InlineSwatch.Type.Gradient:
this._swatchElement.title = WebInspector.UIString("Click to select a gradient.");
break;
@@ -98,6 +101,8 @@
switch (this._type) {
case WebInspector.InlineSwatch.Type.Bezier:
return WebInspector.CubicBezier.fromString("linear");
+ case WebInspector.InlineSwatch.Type.Spring:
+ return WebInspector.Spring.fromString("1 100 10 0");
case WebInspector.InlineSwatch.Type.Gradient:
return WebInspector.Gradient.fromString("linear-gradient(transparent, transparent)");
case WebInspector.InlineSwatch.Type.Color:
@@ -143,6 +148,9 @@
if (this._type === WebInspector.InlineSwatch.Type.Bezier) {
this._valueEditor = new WebInspector.BezierEditor;
this._valueEditor.addEventListener(WebInspector.BezierEditor.Event.BezierChanged, this._valueEditorValueDidChange, this);
+ } else if (this._type === WebInspector.InlineSwatch.Type.Spring) {
+ this._valueEditor = new WebInspector.SpringEditor;
+ this._valueEditor.addEventListener(WebInspector.SpringEditor.Event.SpringChanged, this._valueEditorValueDidChange, this);
} else if (this._type === WebInspector.InlineSwatch.Type.Gradient) {
this._valueEditor = new WebInspector.GradientEditor;
this._valueEditor.addEventListener(WebInspector.GradientEditor.Event.GradientChanged, this._valueEditorValueDidChange, this);
@@ -158,6 +166,8 @@
let value = this._value || this._fallbackValue();
if (this._type === WebInspector.InlineSwatch.Type.Bezier)
this._valueEditor.bezier = value;
+ else if (this._type === WebInspector.InlineSwatch.Type.Spring)
+ this._valueEditor.spring = value;
else if (this._type === WebInspector.InlineSwatch.Type.Gradient)
this._valueEditor.gradient = value;
else
@@ -168,6 +178,8 @@
{
if (this._type === WebInspector.InlineSwatch.Type.Bezier)
this._value = event.data.bezier;
+ else if (this._type === WebInspector.InlineSwatch.Type.Spring)
+ this._value = event.data.spring;
else if (this._type === WebInspector.InlineSwatch.Type.Gradient)
this._value = event.data.gradient;
else
@@ -279,7 +291,8 @@
WebInspector.InlineSwatch.Type = {
Color: "inline-swatch-type-color",
Gradient: "inline-swatch-type-gradient",
- Bezier: "inline-swatch-type-bezier"
+ Bezier: "inline-swatch-type-bezier",
+ Spring: "inline-swatch-type-spring",
};
WebInspector.InlineSwatch.Event = {
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/SourceCodeTextEditor.js (204774 => 204775)
--- trunk/Source/WebInspectorUI/UserInterface/Views/SourceCodeTextEditor.js 2016-08-23 07:17:11 UTC (rev 204774)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/SourceCodeTextEditor.js 2016-08-23 07:23:24 UTC (rev 204775)
@@ -1604,6 +1604,7 @@
this.createColorMarkers(range);
this.createGradientMarkers(range);
this.createCubicBezierMarkers(range);
+ this.createSpringMarkers(range);
}
this._updateTokenTrackingControllerState();
@@ -1614,7 +1615,7 @@
// Look for the outermost editable marker.
var editableMarker;
for (var marker of markers) {
- if (!marker.range || (marker.type !== WebInspector.TextMarker.Type.Color && marker.type !== WebInspector.TextMarker.Type.Gradient && marker.type !== WebInspector.TextMarker.Type.CubicBezier))
+ if (!marker.range || !Object.values(WebInspector.TextMarker.Type).includes(marker.type))
continue;
if (!editableMarker || (marker.range.startLine < editableMarker.range.startLine || (marker.range.startLine === editableMarker.range.startLine && marker.range.startColumn < editableMarker.range.startColumn)))
Added: trunk/Source/WebInspectorUI/UserInterface/Views/SpringEditor.css (0 => 204775)
--- trunk/Source/WebInspectorUI/UserInterface/Views/SpringEditor.css (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/SpringEditor.css 2016-08-23 07:23:24 UTC (rev 204775)
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2016 Devin Rousso <[email protected]>. 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.
+ */
+
+.spring-editor {
+ width: 200px;
+ height: 210px;
+}
+
+.spring-editor > .spring-preview {
+ width: calc(100% - 10px);
+ height: 25px;
+ margin: 5px 5px 0;
+ border-bottom: 1px solid lightgrey;
+}
+
+.spring-editor > .spring-preview > div {
+ position: relative;
+ width: 20px;
+ height: 20px;
+ background-color: var(--selected-background-color);
+ border-radius: 50%;
+}
+
+.spring-editor > .spring-timing {
+ position: relative;
+ margin: -0.5px 11px 0;
+}
+
+.spring-editor > .spring-timing > div {
+ width: 0;
+ border-left: 4px solid transparent;
+ border-right: 4px solid transparent;
+ border-top: 4px solid black;
+ transition-timing-function: linear;
+}
+
+.spring-editor > .spring-timing:matches(::before, ::after) {
+ position: absolute;
+ top: 2.5px;
+ font-size: 9px;
+}
+
+.spring-editor > .spring-timing::before {
+ left: 0;
+ content: "0s";
+}
+
+.spring-editor > .spring-timing::after {
+ right: 0;
+ content: attr(data-duration) "s";
+}
+
+.spring-editor > :matches(.spring-preview, .spring-timing) > div {
+ transition-property: none;
+}
+
+.spring-editor > .animate:matches(.spring-preview, .spring-timing) > div {
+ transition-property: transform;
+}
+
+.spring-editor > .number-input-container > .number-input-row {
+ display: flex;
+ flex-wrap: wrap;
+ margin-bottom: 3px;
+}
+
+.spring-editor > .number-input-container > .number-input-row > .number-input-row-title {
+ width: 100%;
+ margin: 7px 0 3px;
+ text-align: center;
+}
+
+.spring-editor > .number-input-container > .number-input-row > input {
+ width: calc(50% - 10px);
+ margin: 0 5px;
+}
+
+.spring-editor > .number-input-container > .number-input-row > input[type="range"] {
+ background-color: transparent;
+}
Added: trunk/Source/WebInspectorUI/UserInterface/Views/SpringEditor.js (0 => 204775)
--- trunk/Source/WebInspectorUI/UserInterface/Views/SpringEditor.js (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/SpringEditor.js 2016-08-23 07:23:24 UTC (rev 204775)
@@ -0,0 +1,227 @@
+/*
+ * Copyright (C) 2016 Devin Rousso <[email protected]>. 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.SpringEditor = class SpringEditor extends WebInspector.Object
+{
+ constructor()
+ {
+ super();
+
+ this._element = document.createElement("div");
+ this._element.classList.add("spring-editor");
+
+ this._previewContainer = this._element.createChild("div", "spring-preview");
+ this._previewContainer.title = WebInspector.UIString("Click to restart the animation");
+ this._previewContainer.addEventListener("mousedown", this._resetPreviewAnimation.bind(this));
+
+ this._previewElement = this._previewContainer.createChild("div");
+ this._previewElement.addEventListener("transitionend", this.debounce(500)._resetPreviewAnimation);
+
+ this._timingContainer = this._element.createChild("div", "spring-timing");
+
+ this._timingElement = this._timingContainer.createChild("div");
+
+ this._numberInputContainer = this._element.createChild("div", "number-input-container");
+
+ function createInputsForParameter(id, title)
+ {
+ let row = this._numberInputContainer.createChild("div", `number-input-row ${id}`);
+
+ row.createChild("div", "number-input-row-title").textContent = title;
+
+ let sliderKey = `_${id}Slider`;
+ this[sliderKey] = row.createChild("input");
+ this[sliderKey].type = "range";
+ this[sliderKey].addEventListener("input", this._handleNumberSliderInput.bind(this));
+ this[sliderKey].addEventListener("mousedown", this._handleNumberSliderMousedown.bind(this));
+ this[sliderKey].addEventListener("mouseup", this._handleNumberSliderMouseup.bind(this));
+
+ let inputKey = `_${id}Input`;
+ this[inputKey] = row.createChild("input");
+ this[inputKey].type = "number";
+ this[inputKey].addEventListener("input", this._handleNumberInputInput.bind(this));
+ this[inputKey].addEventListener("keydown", this._handleNumberInputKeydown.bind(this));
+ }
+
+ createInputsForParameter.call(this, "mass", WebInspector.UIString("Mass"));
+ this._massInput.min = this._massSlider.min = 1;
+
+ createInputsForParameter.call(this, "stiffness", WebInspector.UIString("Stiffness"));
+ this._stiffnessInput.min = this._stiffnessSlider.min = 1;
+
+ createInputsForParameter.call(this, "damping", WebInspector.UIString("Damping"));
+ this._dampingInput.min = this._dampingSlider.min = 0;
+
+ createInputsForParameter.call(this, "initialVelocity", WebInspector.UIString("Initial Velocity"));
+
+ this._spring = new WebInspector.Spring(1, 100, 10, 0);
+ }
+
+ // Public
+
+ get element()
+ {
+ return this._element;
+ }
+
+ get spring()
+ {
+ return this._spring;
+ }
+
+ set spring(spring)
+ {
+ if (!spring)
+ return;
+
+ let isSpring = spring instanceof WebInspector.Spring;
+ console.assert(isSpring);
+ if (!isSpring)
+ return;
+
+ this._spring = spring;
+ this._massInput.value = this._massSlider.value = this._spring.mass;
+ this._stiffnessInput.value = this._stiffnessSlider.value = this._spring.stiffness;
+ this._dampingInput.value = this._dampingSlider.value = this._spring.damping;
+ this._initialVelocityInput.value = this._initialVelocitySlider.value = this._spring.initialVelocity;
+ this._resetPreviewAnimation();
+ }
+
+ // Private
+
+ _handleNumberInputInput(event)
+ {
+ this._changeSpringForInput(event.target, event.target.value);
+ }
+
+ _handleNumberInputKeydown(event)
+ {
+ let shift = 0;
+ if (event.keyIdentifier === "Up")
+ shift = 1;
+ else if (event.keyIdentifier === "Down")
+ shift = -1;
+
+ if (!shift)
+ return;
+
+ if (event.shiftKey)
+ shift *= 10;
+ else if (event.altKey)
+ shift /= 10;
+
+ event.preventDefault();
+ this._changeSpringForInput(event.target, parseFloat(event.target.value) + shift);
+ }
+
+ _handleNumberSliderInput(event)
+ {
+ this._changeSpringForInput(event.target, event.target.value);
+ }
+
+ _handleNumberSliderMousedown(event)
+ {
+ this._changeSpringForInput(event.target, event.target.value);
+ }
+
+ _handleNumberSliderMouseup(event)
+ {
+ this._changeSpringForInput(event.target, event.target.value);
+ }
+
+ _changeSpringForInput(target, value)
+ {
+ value = parseFloat(value);
+
+ switch (target) {
+ case this._massInput:
+ case this._massSlider:
+ this._spring.mass = Math.max(1, value);
+ this._massInput.value = this._massSlider.value = this._spring.mass.maxDecimals(3);
+ break;
+ case this._stiffnessInput:
+ case this._stiffnessSlider:
+ this._spring.stiffness = Math.max(1, value);
+ this._stiffnessInput.value = this._stiffnessSlider.value = this._spring.stiffness.maxDecimals(3);
+ break;
+ case this._dampingInput:
+ case this._dampingSlider:
+ this._spring.damping = Math.max(0, value);
+ this._dampingInput.value = this._dampingSlider.value = this._spring.damping.maxDecimals(3);
+ break;
+ case this._initialVelocityInput:
+ case this._initialVelocitySlider:
+ this._spring.initialVelocity = value;
+ this._initialVelocityInput.value = this._initialVelocitySlider.value = this._spring.initialVelocity.maxDecimals(3);
+ break;
+ default:
+ return;
+ }
+
+ this.dispatchEventToListeners(WebInspector.SpringEditor.Event.SpringChanged, {spring: this._spring});
+
+ this._resetPreviewAnimation();
+ }
+
+ _resetPreviewAnimation(event)
+ {
+ this._previewContainer.classList.remove("animate");
+ this._previewElement.style.transitionTimingFunction = null;
+ this._previewElement.style.transform = null;
+
+ this._timingContainer.classList.remove("animate");
+ this._timingElement.style.transform = null;
+
+ // Only reset the duration text when a spring parameter is changed.
+ if (!event)
+ this._timingContainer.dataset.duration = "0";
+
+ this.debounce(500)._updatePreviewAnimation(event);
+ }
+
+ _updatePreviewAnimation(event)
+ {
+ this._previewContainer.classList.add("animate");
+ this._previewElement.style.transform = "translateX(85px)";
+ this._previewElement.style.transitionTimingFunction = this._spring.toString();
+
+ this._timingContainer.classList.add("animate");
+ this._timingElement.style.transform = "translateX(170px)";
+
+ // Only calculate the duration when a spring parameter is changed.
+ if (!event) {
+ let duration = this._spring.calculateDuration();
+
+ this._timingContainer.dataset.duration = duration.toFixed(2);
+ this._timingElement.style.transitionDuration = `${duration}s`;
+
+ this._previewElement.style.transitionDuration = `${duration}s`;
+ }
+ }
+};
+
+WebInspector.SpringEditor.Event = {
+ SpringChanged: "spring-editor-spring-changed"
+};
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/TextEditor.js (204774 => 204775)
--- trunk/Source/WebInspectorUI/UserInterface/Views/TextEditor.js 2016-08-23 07:17:11 UTC (rev 204774)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/TextEditor.js 2016-08-23 07:23:24 UTC (rev 204775)
@@ -617,6 +617,11 @@
return createCodeMirrorCubicBezierTextMarkers(this._codeMirror, range);
}
+ createSpringMarkers(range)
+ {
+ return createCodeMirrorSpringTextMarkers(this._codeMirror, range);
+ }
+
editingControllerForMarker(editableMarker)
{
switch (editableMarker.type) {
@@ -626,6 +631,8 @@
return new WebInspector.CodeMirrorGradientEditingController(this._codeMirror, editableMarker);
case WebInspector.TextMarker.Type.CubicBezier:
return new WebInspector.CodeMirrorBezierEditingController(this._codeMirror, editableMarker);
+ case WebInspector.TextMarker.Type.Spring:
+ return new WebInspector.CodeMirrorSpringEditingController(this._codeMirror, editableMarker);
default:
return new WebInspector.CodeMirrorEditingController(this._codeMirror, editableMarker);
}
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/VisualStyleCommaSeparatedKeywordEditor.js (204774 => 204775)
--- trunk/Source/WebInspectorUI/UserInterface/Views/VisualStyleCommaSeparatedKeywordEditor.js 2016-08-23 07:17:11 UTC (rev 204774)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/VisualStyleCommaSeparatedKeywordEditor.js 2016-08-23 07:23:24 UTC (rev 204775)
@@ -111,7 +111,9 @@
values[i] += (openParentheses - closedParenthesis === 1) ? ")" : "";
}
- if (values.length === 1 && !values[0].includes("(") && !values[0].includes(")"))
+ // Allow splitting with parenthesis if the parenthesis does not have any commas.
+ let hasParenthesis = values[0] && (values[0].includes("(") || values[0].includes(")"));
+ if (values.length === 1 && (!hasParenthesis || !/\([^\)]*,[^\)]*\)/.test(values[0])))
values = values[0].split(/\s*,\s*/);
for (let value of values)
@@ -176,7 +178,7 @@
let count = 0;
while (count < valuesCount) {
if (count > 0)
- text += ",";
+ text += ", ";
for (let valueList of valueLists)
text += valueList[count > valueList.length - 1 ? valueList.length - 1 : count] + " ";
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/VisualStyleTimingEditor.css (204774 => 204775)
--- trunk/Source/WebInspectorUI/UserInterface/Views/VisualStyleTimingEditor.css 2016-08-23 07:17:11 UTC (rev 204774)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/VisualStyleTimingEditor.css 2016-08-23 07:23:24 UTC (rev 204775)
@@ -31,12 +31,13 @@
order: 1;
}
-.visual-style-property-container.timing-editor > .visual-style-property-value-container > .inline-swatch.bezier {
+.visual-style-property-container.timing-editor > .visual-style-property-value-container > .inline-swatch:matches(.bezier, .spring) {
width: 23px;
height: 20px;
}
-.visual-style-property-container.timing-editor > .visual-style-property-value-container:not(.bezier-value) > .inline-swatch.bezier {
+.visual-style-property-container.timing-editor > .visual-style-property-value-container:not(.bezier-value) > .inline-swatch.bezier,
+.visual-style-property-container.timing-editor > .visual-style-property-value-container:not(.spring-value) > .inline-swatch.spring {
display: none;
}
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/VisualStyleTimingEditor.js (204774 => 204775)
--- trunk/Source/WebInspectorUI/UserInterface/Views/VisualStyleTimingEditor.js 2016-08-23 07:17:11 UTC (rev 204774)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/VisualStyleTimingEditor.js 2016-08-23 07:23:24 UTC (rev 204775)
@@ -31,77 +31,122 @@
this.element.classList.add("timing-editor");
- this._customValueOptionElement = document.createElement("option");
- this._customValueOptionElement.value = "custom";
- this._customValueOptionElement.text = WebInspector.UIString("Custom");
- this._keywordSelectElement.appendChild(this._customValueOptionElement);
+ this._keywordSelectElement.createChild("hr");
+ this._customBezierOptionElement = this._keywordSelectElement.createChild("option");
+ this._customBezierOptionElement.value = "bezier";
+ this._customBezierOptionElement.text = WebInspector.UIString("Bezier");
+
+ this._customSpringOptionElement = this._keywordSelectElement.createChild("option");
+ this._customSpringOptionElement.value = "spring";
+ this._customSpringOptionElement.text = WebInspector.UIString("Spring");
+
this._bezierSwatch = new WebInspector.InlineSwatch(WebInspector.InlineSwatch.Type.Bezier);
this._bezierSwatch.addEventListener(WebInspector.InlineSwatch.Event.ValueChanged, this._bezierSwatchValueChanged, this);
this.contentElement.appendChild(this._bezierSwatch.element);
- }
- // Public
-
- get bezierValue()
- {
- let bezier = this._bezierSwatch.value;
- if (!bezier)
- return null;
-
- return bezier.toString();
+ this._springSwatch = new WebInspector.InlineSwatch(WebInspector.InlineSwatch.Type.Spring);
+ this._springSwatch.addEventListener(WebInspector.InlineSwatch.Event.ValueChanged, this._springSwatchValueChanged, this);
+ this.contentElement.appendChild(this._springSwatch.element);
}
- set bezierValue(text)
- {
- let bezier = WebInspector.CubicBezier.fromString(text);
- this._bezierSwatch.value = bezier;
- }
-
// Protected
get value()
{
- return this._customValueOptionElement.selected ? this.bezierValue : super.value;
+ if (this._customBezierOptionElement.selected)
+ return this._bezierValue;
+
+ if (this._customSpringOptionElement.selected)
+ return this._springValue;
+
+ return super.value;
}
set value(value)
{
- this.bezierValue = value;
+ this._bezierValue = value;
+ this._springValue = value;
if (this.valueIsSupportedKeyword(value)) {
super.value = value;
- this.contentElement.classList.remove("bezier-value");
+ this.contentElement.classList.remove("bezier-value", "spring-value");
return;
}
- let bezier = this.bezierValue;
- this._customValueOptionElement.selected = !!bezier;
+ let bezier = this._bezierValue;
+ this._customBezierOptionElement.selected = !!bezier;
this.contentElement.classList.toggle("bezier-value", !!bezier);
- this.specialPropertyPlaceholderElement.hidden = !!bezier;
- if (!bezier)
+
+ let spring = this._springValue;
+ this._customSpringOptionElement.selected = !!spring;
+ this.contentElement.classList.toggle("spring-value", !!spring);
+
+ this.specialPropertyPlaceholderElement.hidden = !!bezier || !!spring;
+ if (!bezier && !spring)
super.value = value;
}
get synthesizedValue()
{
- return this._customValueOptionElement.selected ? this.bezierValue : super.synthesizedValue;
+ if (this._customBezierOptionElement.selected)
+ return this._bezierValue;
+
+ if (this._customSpringOptionElement.selected)
+ return this._springValue;
+
+ return super.synthesizedValue;
}
parseValue(text)
{
- return /(cubic-bezier\(.+\))/.exec(text);
+ return /((?:cubic-bezier|spring)\(.+\))/.exec(text);
}
// Private
+ get _bezierValue()
+ {
+ let bezier = this._bezierSwatch.value;
+ if (!bezier)
+ return null;
+
+ return bezier.toString();
+ }
+
+ set _bezierValue(text)
+ {
+ this._bezierSwatch.value = WebInspector.CubicBezier.fromString(text);
+ }
+
+ get _springValue()
+ {
+ let spring = this._springSwatch.value;
+ if (!spring)
+ return null;
+
+ return spring.toString();
+ }
+
+ set _springValue(text)
+ {
+ this._springSwatch.value = WebInspector.Spring.fromString(text);
+ }
+
_handleKeywordChanged()
{
super._handleKeywordChanged();
- let customOptionSelected = this._customValueOptionElement.selected;
- this.contentElement.classList.toggle("bezier-value", !!customOptionSelected);
- this.specialPropertyPlaceholderElement.hidden = !!customOptionSelected;
- if (customOptionSelected)
- this.bezierValue = "linear";
+
+ let customBezierOptionSelected = this._customBezierOptionElement.selected;
+ this.contentElement.classList.toggle("bezier-value", !!customBezierOptionSelected);
+ if (customBezierOptionSelected)
+ this._bezierValue = "linear";
+
+ let customSpringOptionSelected = this._customSpringOptionElement.selected;
+ this.contentElement.classList.toggle("spring-value", !!customSpringOptionSelected);
+ if (customSpringOptionSelected)
+ this._springValue = "1 100 10 0";
+
+ this.specialPropertyPlaceholderElement.hidden = !!customBezierOptionSelected || !!customSpringOptionSelected;
}
_bezierSwatchValueChanged(event)
@@ -108,4 +153,9 @@
{
this._valueDidChange();
}
+
+ _springSwatchValueChanged(event)
+ {
+ this._valueDidChange();
+ }
};