| Index: third_party/WebKit/Source/devtools/front_end/ui/CSSShadowEditor.js
|
| diff --git a/third_party/WebKit/Source/devtools/front_end/ui/CSSShadowEditor.js b/third_party/WebKit/Source/devtools/front_end/ui/CSSShadowEditor.js
|
| index 74a23375f05e4e34776ea655363b76441b91a928..646927096b44fd4a166b64c0feaf6a20c511646c 100644
|
| --- a/third_party/WebKit/Source/devtools/front_end/ui/CSSShadowEditor.js
|
| +++ b/third_party/WebKit/Source/devtools/front_end/ui/CSSShadowEditor.js
|
| @@ -21,20 +21,27 @@ WebInspector.CSSShadowEditor = function()
|
| this._insetButton.textContent = WebInspector.UIString("Inset");
|
| this._insetButton.addEventListener("click", this._onButtonClick.bind(this), false);
|
|
|
| - var inputs;
|
| - inputs = this._createSliderField(WebInspector.UIString("X offset"), true);
|
| - this._xInput = inputs.textInput;
|
| - this._xSlider = inputs.rangeInput;
|
| - inputs = this._createSliderField(WebInspector.UIString("Y offset"), true);
|
| - this._yInput = inputs.textInput;
|
| - this._ySlider = inputs.rangeInput;
|
| - inputs = this._createSliderField(WebInspector.UIString("Blur"), false);
|
| - this._blurInput = inputs.textInput;
|
| - this._blurSlider = inputs.rangeInput;
|
| - inputs = this._createSliderField(WebInspector.UIString("Spread"), false);
|
| - this._spreadInput = inputs.textInput;
|
| - this._spreadSlider = inputs.rangeInput;
|
| - this._spreadField = inputs.field;
|
| + var xField = this.contentElement.createChild("div", "shadow-editor-field");
|
| + this._xInput = this._createTextInput(xField, WebInspector.UIString("X offset"));
|
| + var yField = this.contentElement.createChild("div", "shadow-editor-field");
|
| + this._yInput = this._createTextInput(yField, WebInspector.UIString("Y offset"));
|
| + this._xySlider = xField.createChild("canvas", "shadow-editor-2D-slider");
|
| + this._xySlider.width = WebInspector.CSSShadowEditor.canvasSize;
|
| + this._xySlider.height = WebInspector.CSSShadowEditor.canvasSize;
|
| + this._xySlider.tabIndex = -1;
|
| + this._halfCanvasSize = WebInspector.CSSShadowEditor.canvasSize / 2;
|
| + this._innerCanvasSize = this._halfCanvasSize - WebInspector.CSSShadowEditor.sliderThumbRadius;
|
| + WebInspector.installDragHandle(this._xySlider, this._dragStart.bind(this), this._dragMove.bind(this), null, "default");
|
| + this._xySlider.addEventListener("keydown", this._onCanvasArrowKey.bind(this), false);
|
| + this._xySlider.addEventListener("blur", this._onCanvasBlur.bind(this), false);
|
| +
|
| + var blurField = this.contentElement.createChild("div", "shadow-editor-blur-field");
|
| + this._blurInput = this._createTextInput(blurField, WebInspector.UIString("Blur"));
|
| + this._blurSlider = this._createSlider(blurField);
|
| +
|
| + this._spreadField = this.contentElement.createChild("div", "shadow-editor-field");
|
| + this._spreadInput = this._createTextInput(this._spreadField, WebInspector.UIString("Spread"));
|
| + this._spreadSlider = this._createSlider(this._spreadField);
|
| }
|
|
|
| /** @enum {symbol} */
|
| @@ -43,19 +50,22 @@ WebInspector.CSSShadowEditor.Events = {
|
| }
|
|
|
| /** @type {number} */
|
| -WebInspector.CSSShadowEditor.maxRange = 40;
|
| +WebInspector.CSSShadowEditor.maxRange = 20;
|
| /** @type {string} */
|
| WebInspector.CSSShadowEditor.defaultUnit = "px";
|
| +/** @type {number} */
|
| +WebInspector.CSSShadowEditor.sliderThumbRadius = 6;
|
| +/** @type {number} */
|
| +WebInspector.CSSShadowEditor.canvasSize = 88;
|
|
|
| WebInspector.CSSShadowEditor.prototype = {
|
| /**
|
| + * @param {!Element} field
|
| * @param {string} propertyName
|
| - * @param {boolean} negativeAllowed
|
| - * @return {{textInput: !Element, rangeInput: !Element, field: !Element}}
|
| + * @return {!Element}
|
| */
|
| - _createSliderField: function(propertyName, negativeAllowed)
|
| + _createTextInput: function(field, propertyName)
|
| {
|
| - var field = this.contentElement.createChild("div", "shadow-editor-field");
|
| var label = field.createChild("label", "shadow-editor-label");
|
| label.textContent = propertyName;
|
| label.setAttribute("for", propertyName);
|
| @@ -66,11 +76,19 @@ WebInspector.CSSShadowEditor.prototype = {
|
| textInput.addEventListener("mousewheel", this._handleValueModification.bind(this), false);
|
| textInput.addEventListener("input", this._onTextInput.bind(this), false);
|
| textInput.addEventListener("blur", this._onTextBlur.bind(this), false);
|
| - var halfRange = WebInspector.CSSShadowEditor.maxRange / 2;
|
| - var slider = negativeAllowed ? createSliderLabel(-halfRange, halfRange) : createSliderLabel(0, WebInspector.CSSShadowEditor.maxRange);
|
| + return textInput;
|
| + },
|
| +
|
| + /**
|
| + * @param {!Element} field
|
| + * @return {!Element}
|
| + */
|
| + _createSlider: function(field)
|
| + {
|
| + var slider = createSliderLabel(0, WebInspector.CSSShadowEditor.maxRange, -1);
|
| slider.addEventListener("input", this._onSliderInput.bind(this), false);
|
| field.appendChild(slider);
|
| - return {field: field, textInput: textInput, rangeInput: slider};
|
| + return slider;
|
| },
|
|
|
| /**
|
| @@ -99,10 +117,9 @@ WebInspector.CSSShadowEditor.prototype = {
|
| this._yInput.value = this._model.offsetY().asCSSText();
|
| this._blurInput.value = this._model.blurRadius().asCSSText();
|
| this._spreadInput.value = this._model.spreadRadius().asCSSText();
|
| - this._xSlider.value = this._model.offsetX().amount;
|
| - this._ySlider.value = this._model.offsetY().amount;
|
| this._blurSlider.value = this._model.blurRadius().amount;
|
| this._spreadSlider.value = this._model.spreadRadius().amount;
|
| + this._updateCanvas(false);
|
| },
|
|
|
| _updateButtons: function()
|
| @@ -112,6 +129,50 @@ WebInspector.CSSShadowEditor.prototype = {
|
| },
|
|
|
| /**
|
| + * @param {boolean} drawFocus
|
| + */
|
| + _updateCanvas: function(drawFocus)
|
| + {
|
| + var context = this._xySlider.getContext("2d");
|
| + context.clearRect(0, 0, this._xySlider.width, this._xySlider.height);
|
| +
|
| + // Draw dashed axes.
|
| + context.save();
|
| + context.setLineDash([1, 1]);
|
| + context.strokeStyle = "rgba(0, 0, 0, 0.2)";
|
| + context.beginPath();
|
| + context.moveTo(this._halfCanvasSize, 0);
|
| + context.lineTo(this._halfCanvasSize, WebInspector.CSSShadowEditor.canvasSize);
|
| + context.moveTo(0, this._halfCanvasSize);
|
| + context.lineTo(WebInspector.CSSShadowEditor.canvasSize, this._halfCanvasSize);
|
| + context.stroke();
|
| + context.restore();
|
| +
|
| + var thumbPoint = this._sliderThumbPosition();
|
| + // Draw 2D slider line.
|
| + context.save();
|
| + context.translate(this._halfCanvasSize, this._halfCanvasSize);
|
| + context.lineWidth = 2;
|
| + context.strokeStyle = "rgba(0, 0, 0, 0.3)";
|
| + context.beginPath();
|
| + context.moveTo(0, 0);
|
| + context.lineTo(thumbPoint.x, thumbPoint.y);
|
| + context.stroke();
|
| + // Draw 2D slider thumb.
|
| + if (drawFocus) {
|
| + context.beginPath();
|
| + context.fillStyle = "rgba(66, 133, 244, 0.4)";
|
| + context.arc(thumbPoint.x, thumbPoint.y, WebInspector.CSSShadowEditor.sliderThumbRadius + 2, 0, 2 * Math.PI);
|
| + context.fill();
|
| + }
|
| + context.beginPath()
|
| + context.fillStyle = "#4285F4";
|
| + context.arc(thumbPoint.x, thumbPoint.y, WebInspector.CSSShadowEditor.sliderThumbRadius, 0, 2 * Math.PI);
|
| + context.fill();
|
| + context.restore();
|
| + },
|
| +
|
| + /**
|
| * @param {!Event} event
|
| */
|
| _onButtonClick: function(event)
|
| @@ -163,16 +224,16 @@ WebInspector.CSSShadowEditor.prototype = {
|
| _onTextInput: function(event)
|
| {
|
| this._changedElement = event.currentTarget;
|
| - this._changedElement.classList.toggle("invalid", false);
|
| + this._changedElement.classList.remove("invalid");
|
| var length = WebInspector.CSSLength.parse(event.currentTarget.value);
|
| if (!length || event.currentTarget === this._blurInput && length.amount < 0)
|
| return;
|
| if (event.currentTarget === this._xInput) {
|
| this._model.setOffsetX(length);
|
| - this._xSlider.value = length.amount;
|
| + this._updateCanvas(false);
|
| } else if (event.currentTarget === this._yInput) {
|
| this._model.setOffsetY(length);
|
| - this._ySlider.value = length.amount;
|
| + this._updateCanvas(false);
|
| } else if (event.currentTarget === this._blurInput) {
|
| this._model.setBlurRadius(length);
|
| this._blurSlider.value = length.amount;
|
| @@ -187,7 +248,7 @@ WebInspector.CSSShadowEditor.prototype = {
|
| {
|
| if (!this._changedElement)
|
| return;
|
| - var length = !this._changedElement.value ? WebInspector.CSSLength.zero() : WebInspector.CSSLength.parse(this._changedElement.value);
|
| + var length = !this._changedElement.value.trim() ? WebInspector.CSSLength.zero() : WebInspector.CSSLength.parse(this._changedElement.value);
|
| if (!length)
|
| length = WebInspector.CSSLength.parse(this._changedElement.value + WebInspector.CSSShadowEditor.defaultUnit);
|
| if (!length) {
|
| @@ -198,11 +259,11 @@ WebInspector.CSSShadowEditor.prototype = {
|
| if (this._changedElement === this._xInput) {
|
| this._model.setOffsetX(length);
|
| this._xInput.value = length.asCSSText();
|
| - this._xSlider.value = length.amount;
|
| + this._updateCanvas(false);
|
| } else if (this._changedElement === this._yInput) {
|
| this._model.setOffsetY(length);
|
| this._yInput.value = length.asCSSText();
|
| - this._ySlider.value = length.amount;
|
| + this._updateCanvas(false);
|
| } else if (this._changedElement === this._blurInput) {
|
| if (length.amount < 0)
|
| length = WebInspector.CSSLength.zero();
|
| @@ -223,25 +284,121 @@ WebInspector.CSSShadowEditor.prototype = {
|
| */
|
| _onSliderInput: function(event)
|
| {
|
| - if (event.currentTarget === this._xSlider) {
|
| - this._model.setOffsetX(new WebInspector.CSSLength(this._xSlider.value, this._model.offsetX().unit || WebInspector.CSSShadowEditor.defaultUnit));
|
| - this._xInput.value = this._model.offsetX().asCSSText();
|
| - this._xInput.classList.toggle("invalid", false);
|
| - } else if (event.currentTarget === this._ySlider) {
|
| - this._model.setOffsetY(new WebInspector.CSSLength(this._ySlider.value, this._model.offsetY().unit || WebInspector.CSSShadowEditor.defaultUnit));
|
| - this._yInput.value = this._model.offsetY().asCSSText();
|
| - this._yInput.classList.toggle("invalid", false);
|
| - } else if (event.currentTarget === this._blurSlider) {
|
| + if (event.currentTarget === this._blurSlider) {
|
| this._model.setBlurRadius(new WebInspector.CSSLength(this._blurSlider.value, this._model.blurRadius().unit || WebInspector.CSSShadowEditor.defaultUnit));
|
| this._blurInput.value = this._model.blurRadius().asCSSText();
|
| - this._blurInput.classList.toggle("invalid", false);
|
| + this._blurInput.classList.remove("invalid");
|
| } else if (event.currentTarget === this._spreadSlider) {
|
| this._model.setSpreadRadius(new WebInspector.CSSLength(this._spreadSlider.value, this._model.spreadRadius().unit || WebInspector.CSSShadowEditor.defaultUnit));
|
| this._spreadInput.value = this._model.spreadRadius().asCSSText();
|
| - this._spreadInput.classList.toggle("invalid", false);
|
| + this._spreadInput.classList.remove("invalid");
|
| }
|
| this.dispatchEventToListeners(WebInspector.CSSShadowEditor.Events.ShadowChanged, this._model);
|
| },
|
|
|
| + /**
|
| + * @param {!Event} event
|
| + * @return {boolean}
|
| + */
|
| + _dragStart: function(event)
|
| + {
|
| + this._xySlider.focus();
|
| + this._updateCanvas(true);
|
| + this._canvasOrigin = new WebInspector.Geometry.Point(this._xySlider.totalOffsetLeft() + this._halfCanvasSize, this._xySlider.totalOffsetTop() + this._halfCanvasSize);
|
| + var clickedPoint = new WebInspector.Geometry.Point(event.x - this._canvasOrigin.x, event.y - this._canvasOrigin.y);
|
| + var thumbPoint = this._sliderThumbPosition();
|
| + if (clickedPoint.distanceTo(thumbPoint) >= WebInspector.CSSShadowEditor.sliderThumbRadius)
|
| + this._dragMove(event);
|
| + return true;
|
| + },
|
| +
|
| + /**
|
| + * @param {!Event} event
|
| + */
|
| + _dragMove: function(event)
|
| + {
|
| + var point = new WebInspector.Geometry.Point(event.x - this._canvasOrigin.x, event.y - this._canvasOrigin.y);
|
| + var constrainedPoint = this._constrainPoint(point, this._innerCanvasSize);
|
| + var newX = Math.round((constrainedPoint.x / this._innerCanvasSize) * WebInspector.CSSShadowEditor.maxRange);
|
| + var newY = Math.round((constrainedPoint.y / this._innerCanvasSize) * WebInspector.CSSShadowEditor.maxRange);
|
| + this._model.setOffsetX(new WebInspector.CSSLength(newX, this._model.offsetX().unit || WebInspector.CSSShadowEditor.defaultUnit));
|
| + this._model.setOffsetY(new WebInspector.CSSLength(newY, this._model.offsetY().unit || WebInspector.CSSShadowEditor.defaultUnit));
|
| + this._xInput.value = this._model.offsetX().asCSSText();
|
| + this._yInput.value = this._model.offsetY().asCSSText();
|
| + this._xInput.classList.remove("invalid");
|
| + this._yInput.classList.remove("invalid");
|
| + this._updateCanvas(true);
|
| + this.dispatchEventToListeners(WebInspector.CSSShadowEditor.Events.ShadowChanged, this._model);
|
| + },
|
| +
|
| + _onCanvasBlur: function()
|
| + {
|
| + this._updateCanvas(false);
|
| + },
|
| +
|
| + /**
|
| + * @param {!Event} event
|
| + */
|
| + _onCanvasArrowKey: function(event)
|
| + {
|
| + var shiftX = 0;
|
| + var shiftY = 0;
|
| + if (event.key === "ArrowRight")
|
| + shiftX = 1;
|
| + else if (event.key === "ArrowLeft")
|
| + shiftX = -1;
|
| + else if (event.key === "ArrowUp")
|
| + shiftY = -1;
|
| + else if (event.key === "ArrowDown")
|
| + shiftY = 1;
|
| +
|
| + if (!shiftX && !shiftY)
|
| + return;
|
| + event.consume(true);
|
| +
|
| + if (shiftX) {
|
| + var offsetX = this._model.offsetX();
|
| + var newAmount = Number.constrain(offsetX.amount + shiftX, -WebInspector.CSSShadowEditor.maxRange, WebInspector.CSSShadowEditor.maxRange);
|
| + if (newAmount === offsetX.amount)
|
| + return;
|
| + this._model.setOffsetX(new WebInspector.CSSLength(newAmount, offsetX.unit || WebInspector.CSSShadowEditor.defaultUnit));
|
| + this._xInput.value = this._model.offsetX().asCSSText();
|
| + this._xInput.classList.remove("invalid");
|
| + }
|
| + if (shiftY) {
|
| + var offsetY = this._model.offsetY();
|
| + var newAmount = Number.constrain(offsetY.amount + shiftY, -WebInspector.CSSShadowEditor.maxRange, WebInspector.CSSShadowEditor.maxRange);
|
| + if (newAmount === offsetY.amount)
|
| + return;
|
| + this._model.setOffsetY(new WebInspector.CSSLength(newAmount, offsetY.unit || WebInspector.CSSShadowEditor.defaultUnit));
|
| + this._yInput.value = this._model.offsetY().asCSSText();
|
| + this._yInput.classList.remove("invalid");
|
| + }
|
| + this._updateCanvas(true);
|
| + this.dispatchEventToListeners(WebInspector.CSSShadowEditor.Events.ShadowChanged, this._model);
|
| + },
|
| +
|
| + /**
|
| + * @param {!WebInspector.Geometry.Point} point
|
| + * @param {number} max
|
| + * @return {!WebInspector.Geometry.Point}
|
| + */
|
| + _constrainPoint: function(point, max)
|
| + {
|
| + if (Math.abs(point.x) <= max && Math.abs(point.y) <= max)
|
| + return new WebInspector.Geometry.Point(point.x, point.y);
|
| + return point.scale(max / Math.max(Math.abs(point.x), Math.abs(point.y)));
|
| + },
|
| +
|
| + /**
|
| + * @return {!WebInspector.Geometry.Point}
|
| + */
|
| + _sliderThumbPosition: function()
|
| + {
|
| + var x = (this._model.offsetX().amount / WebInspector.CSSShadowEditor.maxRange) * this._innerCanvasSize;
|
| + var y = (this._model.offsetY().amount / WebInspector.CSSShadowEditor.maxRange) * this._innerCanvasSize;
|
| + return this._constrainPoint(new WebInspector.Geometry.Point(x, y), this._innerCanvasSize);
|
| + },
|
| +
|
| __proto__: WebInspector.VBox.prototype
|
| -}
|
| +}
|
|
|