Commit 02a61dc5 authored by flandy's avatar flandy Committed by Commit bot

DevTools: Add bezier swatches to CSS Sources

Bezier swatches will complement color swatches.

BUG=642782

Review-Url: https://codereview.chromium.org/2297873004
Cr-Commit-Position: refs/heads/master@{#417177}
parent 626cb8e7
...@@ -32,4 +32,15 @@ InspectorTest.testPrettyPrint = function(mimeType, text, mappingQueries, next) ...@@ -32,4 +32,15 @@ InspectorTest.testPrettyPrint = function(mimeType, text, mappingQueries, next)
} }
} }
InspectorTest.dumpSwatchPositions = function(sourceFrame, bookmarkType)
{
var textEditor = sourceFrame.textEditor;
var markers = textEditor.bookmarks(textEditor.fullRange(), bookmarkType);
for (var i = 0; i < markers.length; i++) {
var position = markers[i].position();
var text = markers[i]._marker.widgetNode.firstChild.textContent;
InspectorTest.addResult("Line " + position.startLine + ", Column " + position.startColumn + ": " + text);
}
}
}; };
Tests that bezier swatches are updated properly in CSS Sources.
Initial swatch positions:
Line 1, Column 25: ease-in-out
Line 4, Column 32: cubic-bezier(0.25, 0.46, 0.45, 0.94)
Running: testEditBezier
Line 1, Column 25: linear
Line 4, Column 32: cubic-bezier(0.25, 0.46, 0.45, 0.94)
Running: testAddBezier
Line 1, Column 25: linear
Line 1, Column 55: cubic-bezier(0, 0.5, 1, 1)
Line 4, Column 32: cubic-bezier(0.25, 0.46, 0.45, 0.94)
Running: testInvalidateBezier
Line 1, Column 25: linear
Line 4, Column 32: cubic-bezier(0.25, 0.46, 0.45, 0.94)
<html>
<head>
<link rel="stylesheet" href="resources/bezier.css">
<script src="../../http/tests/inspector/inspector-test.js"></script>
<script src="../../http/tests/inspector/debugger-test.js"></script>
<script src="../../http/tests/inspector/sources-test.js"></script>
<script>
function test()
{
InspectorTest.showScriptSource("bezier.css", onSourceFrame);
function onSourceFrame(sourceFrame)
{
InspectorTest.addResult("Initial swatch positions:");
InspectorTest.dumpSwatchPositions(sourceFrame, WebInspector.CSSSourceFrame.SwatchBookmark);
InspectorTest.runTestSuite([
function testEditBezier(next)
{
var swatch = sourceFrame.textEditor._codeMirrorElement.querySelector("span[is=bezier-swatch]");
swatch.shadowRoot.querySelector(".bezier-swatch-icon").click();
sourceFrame._bezierEditor.setBezier(WebInspector.Geometry.CubicBezier.parse("linear"));
sourceFrame._bezierEditor._onchange();
sourceFrame._swatchPopoverHelper.hide(true)
InspectorTest.dumpSwatchPositions(sourceFrame, WebInspector.CSSSourceFrame.SwatchBookmark);
next();
},
function testAddBezier(next)
{
var bodyLineEnd = new WebInspector.TextRange(1, 37, 1, 37);
sourceFrame.textEditor.editRange(bodyLineEnd, " transition: height 1s cubic-bezier(0, 0.5, 1, 1);");
InspectorTest.dumpSwatchPositions(sourceFrame, WebInspector.CSSSourceFrame.SwatchBookmark);
next();
},
function testInvalidateBezier(next)
{
var startParenthesis = new WebInspector.TextRange(1, 67, 1, 68);
sourceFrame.textEditor.editRange(startParenthesis, "[");
InspectorTest.dumpSwatchPositions(sourceFrame, WebInspector.CSSSourceFrame.SwatchBookmark);
next();
}
]);
}
}
</script>
</head>
<body onload="runTest()">
<p>
Tests that bezier swatches are updated properly in CSS Sources.
</p>
</body>
</html>
...@@ -5,17 +5,16 @@ ...@@ -5,17 +5,16 @@
<script src="../../http/tests/inspector/inspector-test.js"></script> <script src="../../http/tests/inspector/inspector-test.js"></script>
<script src="../../http/tests/inspector/debugger-test.js"></script> <script src="../../http/tests/inspector/debugger-test.js"></script>
<script src="../../http/tests/inspector/sources-test.js"></script>
<script> <script>
function test() function test()
{ {
Runtime.experiments.enableForTest("sourceColorPicker");
InspectorTest.showScriptSource("color.css", onSourceFrame); InspectorTest.showScriptSource("color.css", onSourceFrame);
function onSourceFrame(sourceFrame) function onSourceFrame(sourceFrame)
{ {
var range = new WebInspector.TextRange(0, 0, 6, 0);
InspectorTest.addResult("Initial swatch positions:"); InspectorTest.addResult("Initial swatch positions:");
dumpSwatchPositions(); InspectorTest.dumpSwatchPositions(sourceFrame, WebInspector.CSSSourceFrame.SwatchBookmark);
InspectorTest.runTestSuite([ InspectorTest.runTestSuite([
function testEditSpectrum(next) function testEditSpectrum(next)
...@@ -24,7 +23,7 @@ function test() ...@@ -24,7 +23,7 @@ function test()
swatch.shadowRoot.querySelector(".color-swatch-inner").click(); swatch.shadowRoot.querySelector(".color-swatch-inner").click();
sourceFrame._spectrum._innerSetColor(WebInspector.Color.parse("#008000").hsva(), "", WebInspector.Color.Format.HEX, WebInspector.Spectrum._ChangeSource.Other); sourceFrame._spectrum._innerSetColor(WebInspector.Color.parse("#008000").hsva(), "", WebInspector.Color.Format.HEX, WebInspector.Spectrum._ChangeSource.Other);
sourceFrame._swatchPopoverHelper.hide(true) sourceFrame._swatchPopoverHelper.hide(true)
dumpSwatchPositions(); InspectorTest.dumpSwatchPositions(sourceFrame, WebInspector.CSSSourceFrame.SwatchBookmark);
next(); next();
}, },
...@@ -32,7 +31,7 @@ function test() ...@@ -32,7 +31,7 @@ function test()
{ {
var start = WebInspector.TextRange.createFromLocation(0, 0); var start = WebInspector.TextRange.createFromLocation(0, 0);
sourceFrame.textEditor.editRange(start, "/* New line */\n"); sourceFrame.textEditor.editRange(start, "/* New line */\n");
dumpSwatchPositions(); InspectorTest.dumpSwatchPositions(sourceFrame, WebInspector.CSSSourceFrame.SwatchBookmark);
next(); next();
}, },
...@@ -40,7 +39,7 @@ function test() ...@@ -40,7 +39,7 @@ function test()
{ {
var bodyLine = new WebInspector.TextRange(2, 0, 3, 0); var bodyLine = new WebInspector.TextRange(2, 0, 3, 0);
sourceFrame.textEditor.editRange(bodyLine, ""); sourceFrame.textEditor.editRange(bodyLine, "");
dumpSwatchPositions(); InspectorTest.dumpSwatchPositions(sourceFrame, WebInspector.CSSSourceFrame.SwatchBookmark);
next(); next();
}, },
...@@ -48,7 +47,7 @@ function test() ...@@ -48,7 +47,7 @@ function test()
{ {
var emptyBodyLine = new WebInspector.TextRange(2, 0, 2, 0); var emptyBodyLine = new WebInspector.TextRange(2, 0, 2, 0);
sourceFrame.textEditor.editRange(emptyBodyLine, "color: hsl(300, 100%, 35%);"); sourceFrame.textEditor.editRange(emptyBodyLine, "color: hsl(300, 100%, 35%);");
dumpSwatchPositions(); InspectorTest.dumpSwatchPositions(sourceFrame, WebInspector.CSSSourceFrame.SwatchBookmark);
next(); next();
}, },
...@@ -56,7 +55,7 @@ function test() ...@@ -56,7 +55,7 @@ function test()
{ {
var endParenthesis = new WebInspector.TextRange(2, 25, 2, 26); var endParenthesis = new WebInspector.TextRange(2, 25, 2, 26);
sourceFrame.textEditor.editRange(endParenthesis, "]"); sourceFrame.textEditor.editRange(endParenthesis, "]");
dumpSwatchPositions(); InspectorTest.dumpSwatchPositions(sourceFrame, WebInspector.CSSSourceFrame.SwatchBookmark);
next(); next();
}, },
...@@ -64,20 +63,10 @@ function test() ...@@ -64,20 +63,10 @@ function test()
{ {
var lineStart = new WebInspector.TextRange(5, 0, 5, 0); var lineStart = new WebInspector.TextRange(5, 0, 5, 0);
sourceFrame.textEditor.editRange(lineStart, "background color:\n#ff0;\n"); sourceFrame.textEditor.editRange(lineStart, "background color:\n#ff0;\n");
dumpSwatchPositions(); InspectorTest.dumpSwatchPositions(sourceFrame, WebInspector.CSSSourceFrame.SwatchBookmark);
next(); next();
} }
]); ]);
function dumpSwatchPositions()
{
var markers = sourceFrame.textEditor.bookmarks(range, WebInspector.CSSSourceFrame.SwatchBookmark);
for (var i = 0; i < markers.length; i++) {
var position = markers[i].position();
var color = markers[i]._marker.widgetNode.firstChild.color();
InspectorTest.addResult("Line " + position.startLine + ", Column " + position.startColumn + ": " + color.asString(color.format()));
}
}
} }
} }
</script> </script>
......
body {
transition: width 1s ease-in-out;
}
div {
transition-timing-function: cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
...@@ -38,7 +38,7 @@ WebInspector.CSSSourceFrame = function(uiSourceCode) ...@@ -38,7 +38,7 @@ WebInspector.CSSSourceFrame = function(uiSourceCode)
WebInspector.UISourceCodeFrame.call(this, uiSourceCode); WebInspector.UISourceCodeFrame.call(this, uiSourceCode);
this._registerShortcuts(); this._registerShortcuts();
this._swatchPopoverHelper = new WebInspector.SwatchPopoverHelper(); this._swatchPopoverHelper = new WebInspector.SwatchPopoverHelper();
this._muteColorProcessing = false; this._muteSwatchProcessing = false;
this.configureAutocomplete({ this.configureAutocomplete({
suggestionsCallback: this._cssSuggestions.bind(this), suggestionsCallback: this._cssSuggestions.bind(this),
isWordChar: this._isWordChar.bind(this) isWordChar: this._isWordChar.bind(this)
...@@ -47,7 +47,7 @@ WebInspector.CSSSourceFrame = function(uiSourceCode) ...@@ -47,7 +47,7 @@ WebInspector.CSSSourceFrame = function(uiSourceCode)
/** @type {number} */ /** @type {number} */
WebInspector.CSSSourceFrame.maxSwatchProcessingLength = 300; WebInspector.CSSSourceFrame.maxSwatchProcessingLength = 300;
/** @type {symbol} */
WebInspector.CSSSourceFrame.SwatchBookmark = Symbol("swatch"); WebInspector.CSSSourceFrame.SwatchBookmark = Symbol("swatch");
WebInspector.CSSSourceFrame.prototype = { WebInspector.CSSSourceFrame.prototype = {
...@@ -111,80 +111,120 @@ WebInspector.CSSSourceFrame.prototype = { ...@@ -111,80 +111,120 @@ WebInspector.CSSSourceFrame.prototype = {
* @param {number} startLine * @param {number} startLine
* @param {number} endLine * @param {number} endLine
*/ */
_updateColorSwatches: function(startLine, endLine) _updateSwatches: function(startLine, endLine)
{ {
var colorPositions = []; var swatches = [];
var swatchPositions = [];
var regexes = [WebInspector.CSSMetadata.VariableRegex, WebInspector.CSSMetadata.URLRegex, WebInspector.Geometry.CubicBezier.Regex, WebInspector.Color.Regex];
var handlers = new Map();
handlers.set(WebInspector.Color.Regex, this._createColorSwatch.bind(this));
handlers.set(WebInspector.Geometry.CubicBezier.Regex, this._createBezierSwatch.bind(this));
var colorRegex = /[\s:;,(){}]((?:rgb|hsl)a?\([^)]+\)|#[0-9a-f]{8}|#[0-9a-f]{6}|#[0-9a-f]{3,4}|[a-z]+)(?=[\s;,(){}])/gi;
for (var lineNumber = startLine; lineNumber <= endLine; lineNumber++) { for (var lineNumber = startLine; lineNumber <= endLine; lineNumber++) {
var line = "\n" + this.textEditor.line(lineNumber).substring(0, WebInspector.CSSSourceFrame.maxSwatchProcessingLength) + "\n"; var line = this.textEditor.line(lineNumber).substring(0, WebInspector.CSSSourceFrame.maxSwatchProcessingLength);
var match; var results = WebInspector.TextUtils.splitStringByRegexes(line, regexes);
while ((match = colorRegex.exec(line)) !== null) { for (var i = 0; i < results.length; i++) {
if (match.length < 2) var result = results[i];
if (result.regexIndex === -1 || !handlers.has(regexes[result.regexIndex]))
continue;
var delimiters = /[\s:;,(){}]/;
var positionBefore = result.position - 1;
var positionAfter = result.position + result.value.length;
if (positionBefore >= 0 && !delimiters.test(line.charAt(positionBefore))
|| positionAfter < line.length && !delimiters.test(line.charAt(positionAfter)))
continue; continue;
var colorText = match[1]; var swatch = handlers.get(regexes[result.regexIndex])(result.value);
var color = WebInspector.Color.parse(colorText); if (!swatch)
if (color) continue;
colorPositions.push(new WebInspector.CSSSourceFrame.ColorPosition(color, lineNumber, match.index, colorText.length)); swatches.push(swatch);
swatchPositions.push(WebInspector.TextRange.createFromLocation(lineNumber, result.position));
} }
} }
this.textEditor.operation(putSwatchesInline.bind(this));
this.textEditor.operation(putColorSwatchesInline.bind(this));
/** /**
* @this {WebInspector.CSSSourceFrame} * @this {WebInspector.CSSSourceFrame}
*/ */
function putColorSwatchesInline() function putSwatchesInline()
{ {
this._clearBookmarks(startLine, endLine); var clearRange = new WebInspector.TextRange(startLine, 0, endLine, this.textEditor.line(endLine).length);
this.textEditor.bookmarks(clearRange, WebInspector.CSSSourceFrame.SwatchBookmark).forEach(marker => marker.clear());
for (var i = 0; i < colorPositions.length; i++) {
var colorPosition = colorPositions[i]; for (var i = 0; i < swatches.length; i++) {
var swatch = WebInspector.ColorSwatch.create(); var swatch = swatches[i];
swatch.setColorText(colorPosition.color.asString(WebInspector.Color.Format.Original)); var swatchPosition = swatchPositions[i];
swatch.iconElement().title = WebInspector.UIString("Open color picker."); var bookmark = this.textEditor.addBookmark(swatchPosition.startLine, swatchPosition.startColumn, swatch, WebInspector.CSSSourceFrame.SwatchBookmark);
swatch.hideText(true); swatch[WebInspector.CSSSourceFrame.SwatchBookmark] = bookmark;
var bookmark = this.textEditor.addBookmark(colorPosition.textRange.startLine, colorPosition.textRange.startColumn, swatch, WebInspector.CSSSourceFrame.SwatchBookmark);
swatch.iconElement().addEventListener("click", this._showSpectrum.bind(this, swatch, bookmark), true);
} }
} }
}, },
/** /**
* @param {number} startLine * @param {string} text
* @param {number} endLine * @return {?WebInspector.ColorSwatch}
*/ */
_clearBookmarks: function(startLine, endLine) _createColorSwatch: function(text)
{ {
var range = new WebInspector.TextRange(startLine, 0, endLine, this.textEditor.line(endLine).length); if (!WebInspector.Color.parse(text))
this.textEditor.bookmarks(range, WebInspector.CSSSourceFrame.SwatchBookmark).forEach(marker => marker.clear()); return null;
var swatch = WebInspector.ColorSwatch.create();
swatch.setColorText(text);
swatch.iconElement().title = WebInspector.UIString("Open color picker.");
swatch.iconElement().addEventListener("click", this._swatchIconClicked.bind(this, swatch), false);
swatch.hideText(true);
return swatch;
}, },
/** /**
* @param {!WebInspector.ColorSwatch} swatch * @param {string} text
* @param {!WebInspector.TextEditorBookMark} bookmark * @return {?WebInspector.BezierSwatch}
*/
_createBezierSwatch: function(text)
{
if (!WebInspector.Geometry.CubicBezier.parse(text))
return null;
var swatch = WebInspector.BezierSwatch.create();
swatch.setBezierText(text);
swatch.iconElement().title = WebInspector.UIString("Open cubic bezier editor.");
swatch.iconElement().addEventListener("click", this._swatchIconClicked.bind(this, swatch), false);
swatch.hideText(true);
return swatch;
},
/**
* @param {!Element} swatch
* @param {!Event} event * @param {!Event} event
*/ */
_showSpectrum: function(swatch, bookmark, event) _swatchIconClicked: function(swatch, event)
{ {
event.consume(true); event.consume(true);
if (this._swatchPopoverHelper.isShowing()) { this._hadSwatchChange = false;
this._swatchPopoverHelper.hide(true); this._muteSwatchProcessing = true;
return; var swatchPosition = swatch[WebInspector.CSSSourceFrame.SwatchBookmark].position();
} this.textEditor.setSelection(swatchPosition);
this._hadSpectrumChange = false; this._editedSwatchTextRange = swatchPosition.clone();
var position = bookmark.position(); this._editedSwatchTextRange.endColumn += swatch.textContent.length;
var colorText = swatch.color().asString(WebInspector.Color.Format.Original);
this.textEditor.setSelection(position);
this._currentColorTextRange = position.clone();
this._currentColorTextRange.endColumn += colorText.length;
this._currentSwatch = swatch; this._currentSwatch = swatch;
this._spectrum = new WebInspector.Spectrum(); if (swatch instanceof WebInspector.ColorSwatch)
this._showSpectrum(swatch);
else if (swatch instanceof WebInspector.BezierSwatch)
this._showBezierEditor(swatch);
},
/**
* @param {!WebInspector.ColorSwatch} swatch
*/
_showSpectrum: function(swatch)
{
if (!this._spectrum) {
this._spectrum = new WebInspector.Spectrum();
this._spectrum.addEventListener(WebInspector.Spectrum.Events.SizeChanged, this._spectrumResized, this);
this._spectrum.addEventListener(WebInspector.Spectrum.Events.ColorChanged, this._spectrumChanged, this);
}
this._spectrum.setColor(swatch.color(), swatch.format()); this._spectrum.setColor(swatch.color(), swatch.format());
this._spectrum.addEventListener(WebInspector.Spectrum.Events.SizeChanged, this._spectrumResized, this); this._swatchPopoverHelper.show(this._spectrum, swatch.iconElement(), this._swatchPopoverHidden.bind(this));
this._spectrum.addEventListener(WebInspector.Spectrum.Events.ColorChanged, this._spectrumChanged, this);
this._swatchPopoverHelper.show(this._spectrum, swatch.iconElement(), this._spectrumHidden.bind(this));
}, },
/** /**
...@@ -200,27 +240,55 @@ WebInspector.CSSSourceFrame.prototype = { ...@@ -200,27 +240,55 @@ WebInspector.CSSSourceFrame.prototype = {
*/ */
_spectrumChanged: function(event) _spectrumChanged: function(event)
{ {
this._muteColorProcessing = true;
this._hadSpectrumChange = true;
var colorString = /** @type {string} */ (event.data); var colorString = /** @type {string} */ (event.data);
this._currentSwatch.setColorText(colorString); this._currentSwatch.setColorText(colorString);
this._textEditor.editRange(this._currentColorTextRange, colorString, "*color-text-changed"); this._changeSwatchText(colorString);
this._currentColorTextRange.endColumn = this._currentColorTextRange.startColumn + colorString.length; },
/**
* @param {!WebInspector.BezierSwatch} swatch
*/
_showBezierEditor: function(swatch)
{
if (!this._bezierEditor) {
this._bezierEditor = new WebInspector.BezierEditor();
this._bezierEditor.addEventListener(WebInspector.BezierEditor.Events.BezierChanged, this._bezierChanged, this);
}
var cubicBezier = WebInspector.Geometry.CubicBezier.parse(swatch.bezierText());
if (!cubicBezier)
cubicBezier = /** @type {!WebInspector.Geometry.CubicBezier} */ (WebInspector.Geometry.CubicBezier.parse("linear"));
this._bezierEditor.setBezier(cubicBezier);
this._swatchPopoverHelper.show(this._bezierEditor, swatch.iconElement(), this._swatchPopoverHidden.bind(this));
},
/**
* @param {!WebInspector.Event} event
*/
_bezierChanged: function(event)
{
var bezierString = /** @type {string} */ (event.data);
this._currentSwatch.setBezierText(bezierString);
this._changeSwatchText(bezierString);
},
/**
* @param {string} text
*/
_changeSwatchText: function(text)
{
this._hadSwatchChange = true;
this._textEditor.editRange(this._editedSwatchTextRange, text, "*swatch-text-changed");
this._editedSwatchTextRange.endColumn = this._editedSwatchTextRange.startColumn + text.length;
}, },
/** /**
* @param {boolean} commitEdit * @param {boolean} commitEdit
*/ */
_spectrumHidden: function(commitEdit) _swatchPopoverHidden: function(commitEdit)
{ {
this._muteColorProcessing = false; this._muteSwatchProcessing = false;
this._spectrum.removeEventListener(WebInspector.Spectrum.Events.SizeChanged, this._spectrumResized, this); if (!commitEdit && this._hadSwatchChange)
this._spectrum.removeEventListener(WebInspector.Spectrum.Events.ColorChanged, this._spectrumChanged, this);
if (!commitEdit && this._hadSpectrumChange)
this.textEditor.undo(); this.textEditor.undo();
delete this._spectrum;
delete this._currentSwatch;
delete this._currentColorTextRange;
}, },
/** /**
...@@ -229,8 +297,8 @@ WebInspector.CSSSourceFrame.prototype = { ...@@ -229,8 +297,8 @@ WebInspector.CSSSourceFrame.prototype = {
onTextEditorContentSet: function() onTextEditorContentSet: function()
{ {
WebInspector.UISourceCodeFrame.prototype.onTextEditorContentSet.call(this); WebInspector.UISourceCodeFrame.prototype.onTextEditorContentSet.call(this);
if (!this._muteColorProcessing) if (!this._muteSwatchProcessing)
this._updateColorSwatches(0, this.textEditor.linesCount - 1); this._updateSwatches(0, this.textEditor.linesCount - 1);
}, },
/** /**
...@@ -241,8 +309,8 @@ WebInspector.CSSSourceFrame.prototype = { ...@@ -241,8 +309,8 @@ WebInspector.CSSSourceFrame.prototype = {
onTextChanged: function(oldRange, newRange) onTextChanged: function(oldRange, newRange)
{ {
WebInspector.UISourceCodeFrame.prototype.onTextChanged.call(this, oldRange, newRange); WebInspector.UISourceCodeFrame.prototype.onTextChanged.call(this, oldRange, newRange);
if (!this._muteColorProcessing) if (!this._muteSwatchProcessing)
this._updateColorSwatches(newRange.startLine, newRange.endLine); this._updateSwatches(newRange.startLine, newRange.endLine);
}, },
/** /**
...@@ -320,16 +388,3 @@ WebInspector.CSSSourceFrame.prototype = { ...@@ -320,16 +388,3 @@ WebInspector.CSSSourceFrame.prototype = {
__proto__: WebInspector.UISourceCodeFrame.prototype __proto__: WebInspector.UISourceCodeFrame.prototype
} }
/**
* @constructor
* @param {!WebInspector.Color} color
* @param {number} lineNumber
* @param {number} startColumn
* @param {number} textLength
*/
WebInspector.CSSSourceFrame.ColorPosition = function(color, lineNumber, startColumn, textLength)
{
this.color = color;
this.textRange = new WebInspector.TextRange(lineNumber, startColumn, lineNumber, startColumn + textLength);
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment