1 // Copyright (c) 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
7 * @extends {WebInspector.Object}
9 WebInspector
.StylesPopoverHelper = function()
11 this._popover
= new WebInspector
.Popover();
12 this._popover
.setCanShrink(false);
13 this._popover
.setNoMargins(true);
14 this._popover
.element
.addEventListener("mousedown", consumeEvent
, false);
16 this._hideProxy
= this.hide
.bind(this, true);
17 this._boundOnKeyDown
= this._onKeyDown
.bind(this);
18 this._repositionBound
= this.reposition
.bind(this);
19 this._boundFocusOut
= this._onFocusOut
.bind(this);
22 WebInspector
.StylesPopoverHelper
.prototype = {
24 * @param {!Event} event
26 _onFocusOut: function(event
)
28 if (!event
.relatedTarget
|| event
.relatedTarget
.isSelfOrDescendant(this._view
.contentElement
))
38 return this._popover
.isShowing();
42 * @param {!WebInspector.Widget} view
43 * @param {!Element} anchorElement
44 * @param {function(boolean)=} hiddenCallback
46 show: function(view
, anchorElement
, hiddenCallback
)
48 if (this._popover
.isShowing()) {
49 if (this._anchorElement
=== anchorElement
)
52 // Reopen the picker for another anchor element.
56 delete this._isHidden
;
57 this._anchorElement
= anchorElement
;
59 this._hiddenCallback
= hiddenCallback
;
62 var document
= this._popover
.element
.ownerDocument
;
63 document
.addEventListener("mousedown", this._hideProxy
, false);
64 document
.defaultView
.addEventListener("resize", this._hideProxy
, false);
65 this._view
.contentElement
.addEventListener("keydown", this._boundOnKeyDown
, false);
67 this._scrollerElement
= anchorElement
.enclosingNodeOrSelfWithClass("style-panes-wrapper");
68 if (this._scrollerElement
)
69 this._scrollerElement
.addEventListener("scroll", this._repositionBound
, false);
73 * @param {!Event=} event
75 reposition: function(event
)
77 if (!this._previousFocusElement
)
78 this._previousFocusElement
= WebInspector
.currentFocusElement();
79 // Unbind "blur" listener to avoid reenterability: |popover.showView| will hide the popover and trigger it synchronously.
80 this._view
.contentElement
.removeEventListener("focusout", this._boundFocusOut
, false);
81 this._popover
.showView(this._view
, this._anchorElement
);
82 this._view
.contentElement
.addEventListener("focusout", this._boundFocusOut
, false);
83 WebInspector
.setCurrentFocusElement(this._view
.contentElement
);
87 * @param {boolean=} commitEdit
89 hide: function(commitEdit
)
93 var document
= this._popover
.element
.ownerDocument
;
94 this._isHidden
= true;
97 if (this._scrollerElement
)
98 this._scrollerElement
.removeEventListener("scroll", this._repositionBound
, false);
100 document
.removeEventListener("mousedown", this._hideProxy
, false);
101 document
.defaultView
.removeEventListener("resize", this._hideProxy
, false);
103 if (this._hiddenCallback
)
104 this._hiddenCallback
.call(null, !!commitEdit
);
106 WebInspector
.setCurrentFocusElement(this._previousFocusElement
);
107 delete this._previousFocusElement
;
108 delete this._anchorElement
;
111 this._view
.contentElement
.removeEventListener("keydown", this._boundOnKeyDown
, false);
112 this._view
.contentElement
.removeEventListener("focusout", this._boundFocusOut
, false);
118 * @param {!Event} event
120 _onKeyDown: function(event
)
122 if (event
.keyIdentifier
=== "Enter") {
127 if (event
.keyIdentifier
=== "U+001B") { // Escape key
133 __proto__
: WebInspector
.Object
.prototype
138 * @param {!WebInspector.StylePropertyTreeElement} treeElement
139 * @param {!WebInspector.StylesPopoverHelper} stylesPopoverHelper
140 * @param {string} text
142 WebInspector
.BezierPopoverIcon = function(treeElement
, stylesPopoverHelper
, text
)
144 this._treeElement
= treeElement
;
145 this._stylesPopoverHelper
= stylesPopoverHelper
;
146 this._createDOM(text
);
148 this._boundBezierChanged
= this._bezierChanged
.bind(this);
151 WebInspector
.BezierPopoverIcon
.prototype = {
157 return this._element
;
161 * @param {string} text
163 _createDOM: function(text
)
165 this._element
= createElement("nobr");
166 WebInspector
.Tooltip
.install(this._element
, WebInspector
.UIString("Open cubic bezier editor"));
168 this._iconElement
= this._element
.createSVGChild("svg", "popover-icon bezier-icon");
169 this._iconElement
.setAttribute("height", 10);
170 this._iconElement
.setAttribute("width", 10);
171 this._iconElement
.addEventListener("click", this._iconClick
.bind(this), false);
172 var g
= this._iconElement
.createSVGChild("g");
173 var path
= g
.createSVGChild("path");
174 path
.setAttribute("d", "M2,8 C2,3 8,7 8,2");
176 this._bezierValueElement
= this._element
.createChild("span");
177 this._bezierValueElement
.textContent
= text
;
181 * @param {!Event} event
183 _iconClick: function(event
)
186 if (this._stylesPopoverHelper
.isShowing()) {
187 this._stylesPopoverHelper
.hide(true);
191 this._bezierEditor
= new WebInspector
.BezierEditor();
192 var geometry
= WebInspector
.Geometry
.CubicBezier
.parse(this._bezierValueElement
.textContent
);
193 this._bezierEditor
.setBezier(geometry
);
194 this._bezierEditor
.addEventListener(WebInspector
.BezierEditor
.Events
.BezierChanged
, this._boundBezierChanged
);
195 this._stylesPopoverHelper
.show(this._bezierEditor
, this._iconElement
, this._onPopoverHidden
.bind(this));
197 this._originalPropertyText
= this._treeElement
.property
.propertyText
;
198 this._treeElement
.parentPane().setEditingStyle(true);
202 * @param {!WebInspector.Event} event
204 _bezierChanged: function(event
)
206 this._bezierValueElement
.textContent
= /** @type {string} */ (event
.data
);
207 this._treeElement
.applyStyleText(this._treeElement
.renderedPropertyText(), false);
211 * @param {boolean} commitEdit
213 _onPopoverHidden: function(commitEdit
)
215 this._bezierEditor
.removeEventListener(WebInspector
.BezierEditor
.Events
.BezierChanged
, this._boundBezierChanged
);
216 delete this._bezierEditor
;
218 var propertyText
= commitEdit
? this._treeElement
.renderedPropertyText() : this._originalPropertyText
;
219 this._treeElement
.applyStyleText(propertyText
, true);
220 this._treeElement
.parentPane().setEditingStyle(false);
221 delete this._originalPropertyText
;
227 * @param {!WebInspector.StylePropertyTreeElement} treeElement
228 * @param {!WebInspector.StylesPopoverHelper} stylesPopoverHelper
229 * @param {string} colorText
231 WebInspector
.ColorSwatchPopoverIcon = function(treeElement
, stylesPopoverHelper
, colorText
)
233 this._treeElement
= treeElement
;
234 this._stylesPopoverHelper
= stylesPopoverHelper
;
236 this._swatch
= WebInspector
.ColorSwatch
.create();
237 this._swatch
.setColorText(colorText
);
238 this._swatch
.setFormat(WebInspector
.ColorSwatchPopoverIcon
._colorFormat(this._swatch
.color()));
239 var shiftClickMessage
= WebInspector
.UIString("Shift + Click to change color format.");
240 WebInspector
.Tooltip
.install(this._swatch
.iconElement(), WebInspector
.UIString("Open color picker. %s", shiftClickMessage
));
241 this._swatch
.iconElement().addEventListener("click", this._iconClick
.bind(this));
242 this._contrastColor
= null;
244 this._boundSpectrumChanged
= this._spectrumChanged
.bind(this);
248 * @param {!WebInspector.Color} color
249 * @return {!WebInspector.Color.Format}
251 WebInspector
.ColorSwatchPopoverIcon
._colorFormat = function(color
)
253 const cf
= WebInspector
.Color
.Format
;
255 var formatSetting
= WebInspector
.moduleSetting("colorFormat").get();
256 if (formatSetting
=== cf
.Original
)
257 format
= cf
.Original
;
258 else if (formatSetting
=== cf
.RGB
)
259 format
= (color
.hasAlpha() ? cf
.RGBA
: cf
.RGB
);
260 else if (formatSetting
=== cf
.HSL
)
261 format
= (color
.hasAlpha() ? cf
.HSLA
: cf
.HSL
);
262 else if (!color
.hasAlpha())
263 format
= (color
.canBeShortHex() ? cf
.ShortHEX
: cf
.HEX
);
270 WebInspector
.ColorSwatchPopoverIcon
.prototype = {
280 * @param {!WebInspector.Color} color
282 setContrastColor: function(color
)
284 this._contrastColor
= color
;
286 this._spectrum
.setContrastColor(this._contrastColor
);
290 * @param {!Event} event
292 _iconClick: function(event
)
295 if (this._stylesPopoverHelper
.isShowing()) {
296 this._stylesPopoverHelper
.hide(true);
300 var color
= this._swatch
.color();
301 var format
= this._swatch
.format();
302 if (format
=== WebInspector
.Color
.Format
.Original
)
303 format
= color
.format();
304 this._spectrum
= new WebInspector
.Spectrum();
305 this._spectrum
.setColor(color
, format
);
306 if (this._contrastColor
)
307 this._spectrum
.setContrastColor(this._contrastColor
);
309 this._spectrum
.addEventListener(WebInspector
.Spectrum
.Events
.SizeChanged
, this._spectrumResized
, this);
310 this._spectrum
.addEventListener(WebInspector
.Spectrum
.Events
.ColorChanged
, this._boundSpectrumChanged
);
311 this._stylesPopoverHelper
.show(this._spectrum
, this._swatch
.iconElement(), this._onPopoverHidden
.bind(this));
313 this._originalPropertyText
= this._treeElement
.property
.propertyText
;
314 this._treeElement
.parentPane().setEditingStyle(true);
318 * @param {!WebInspector.Event} event
320 _spectrumResized: function(event
)
322 this._stylesPopoverHelper
.reposition();
326 * @param {!WebInspector.Event} event
328 _spectrumChanged: function(event
)
330 var colorString
= /** @type {string} */ (event
.data
);
331 this._swatch
.setColorText(colorString
);
332 this._treeElement
.applyStyleText(this._treeElement
.renderedPropertyText(), false);
336 * @param {boolean} commitEdit
338 _onPopoverHidden: function(commitEdit
)
340 this._spectrum
.removeEventListener(WebInspector
.Spectrum
.Events
.ColorChanged
, this._boundSpectrumChanged
);
341 delete this._spectrum
;
343 var propertyText
= commitEdit
? this._treeElement
.renderedPropertyText() : this._originalPropertyText
;
344 this._treeElement
.applyStyleText(propertyText
, true);
345 this._treeElement
.parentPane().setEditingStyle(false);
346 delete this._originalPropertyText
;