OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 20 matching lines...) Expand all Loading... |
31 /** | 31 /** |
32 * @constructor | 32 * @constructor |
33 * @extends {WebInspector.UISourceCodeFrame} | 33 * @extends {WebInspector.UISourceCodeFrame} |
34 * @param {!WebInspector.UISourceCode} uiSourceCode | 34 * @param {!WebInspector.UISourceCode} uiSourceCode |
35 */ | 35 */ |
36 WebInspector.CSSSourceFrame = function(uiSourceCode) | 36 WebInspector.CSSSourceFrame = function(uiSourceCode) |
37 { | 37 { |
38 WebInspector.UISourceCodeFrame.call(this, uiSourceCode); | 38 WebInspector.UISourceCodeFrame.call(this, uiSourceCode); |
39 this._registerShortcuts(); | 39 this._registerShortcuts(); |
40 this._swatchPopoverHelper = new WebInspector.SwatchPopoverHelper(); | 40 this._swatchPopoverHelper = new WebInspector.SwatchPopoverHelper(); |
41 this._muteColorProcessing = false; | 41 this._muteSwatchProcessing = false; |
42 this.configureAutocomplete({ | 42 this.configureAutocomplete({ |
43 suggestionsCallback: this._cssSuggestions.bind(this), | 43 suggestionsCallback: this._cssSuggestions.bind(this), |
44 isWordChar: this._isWordChar.bind(this) | 44 isWordChar: this._isWordChar.bind(this) |
45 }); | 45 }); |
46 } | 46 } |
47 | 47 |
48 /** @type {number} */ | 48 /** @type {number} */ |
49 WebInspector.CSSSourceFrame.maxSwatchProcessingLength = 300; | 49 WebInspector.CSSSourceFrame.maxSwatchProcessingLength = 300; |
50 | 50 /** @type {symbol} */ |
51 WebInspector.CSSSourceFrame.SwatchBookmark = Symbol("swatch"); | 51 WebInspector.CSSSourceFrame.SwatchBookmark = Symbol("swatch"); |
52 | 52 |
53 WebInspector.CSSSourceFrame.prototype = { | 53 WebInspector.CSSSourceFrame.prototype = { |
54 _registerShortcuts: function() | 54 _registerShortcuts: function() |
55 { | 55 { |
56 var shortcutKeys = WebInspector.ShortcutsScreen.SourcesPanelShortcuts; | 56 var shortcutKeys = WebInspector.ShortcutsScreen.SourcesPanelShortcuts; |
57 for (var i = 0; i < shortcutKeys.IncreaseCSSUnitByOne.length; ++i) | 57 for (var i = 0; i < shortcutKeys.IncreaseCSSUnitByOne.length; ++i) |
58 this.addShortcut(shortcutKeys.IncreaseCSSUnitByOne[i].key, this._han
dleUnitModification.bind(this, 1)); | 58 this.addShortcut(shortcutKeys.IncreaseCSSUnitByOne[i].key, this._han
dleUnitModification.bind(this, 1)); |
59 for (var i = 0; i < shortcutKeys.DecreaseCSSUnitByOne.length; ++i) | 59 for (var i = 0; i < shortcutKeys.DecreaseCSSUnitByOne.length; ++i) |
60 this.addShortcut(shortcutKeys.DecreaseCSSUnitByOne[i].key, this._han
dleUnitModification.bind(this, -1)); | 60 this.addShortcut(shortcutKeys.DecreaseCSSUnitByOne[i].key, this._han
dleUnitModification.bind(this, -1)); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
104 selection.startColumn = token.startColumn; | 104 selection.startColumn = token.startColumn; |
105 selection.endColumn = selection.startColumn + newUnitText.length; | 105 selection.endColumn = selection.startColumn + newUnitText.length; |
106 this.textEditor.setSelection(selection); | 106 this.textEditor.setSelection(selection); |
107 return true; | 107 return true; |
108 }, | 108 }, |
109 | 109 |
110 /** | 110 /** |
111 * @param {number} startLine | 111 * @param {number} startLine |
112 * @param {number} endLine | 112 * @param {number} endLine |
113 */ | 113 */ |
114 _updateColorSwatches: function(startLine, endLine) | 114 _updateSwatches: function(startLine, endLine) |
115 { | 115 { |
116 var colorPositions = []; | 116 var swatches = []; |
| 117 var swatchPositions = []; |
117 | 118 |
118 var colorRegex = /[\s:;,(){}]((?:rgb|hsl)a?\([^)]+\)|#[0-9a-f]{8}|#[0-9a
-f]{6}|#[0-9a-f]{3,4}|[a-z]+)(?=[\s;,(){}])/gi; | 119 var regexes = [WebInspector.CSSMetadata.VariableRegex, WebInspector.CSSM
etadata.URLRegex, WebInspector.Geometry.CubicBezier.Regex, WebInspector.Color.Re
gex]; |
| 120 var handlers = new Map(); |
| 121 handlers.set(WebInspector.Color.Regex, this._createColorSwatch.bind(this
)); |
| 122 handlers.set(WebInspector.Geometry.CubicBezier.Regex, this._createBezier
Swatch.bind(this)); |
| 123 |
119 for (var lineNumber = startLine; lineNumber <= endLine; lineNumber++) { | 124 for (var lineNumber = startLine; lineNumber <= endLine; lineNumber++) { |
120 var line = "\n" + this.textEditor.line(lineNumber).substring(0, WebI
nspector.CSSSourceFrame.maxSwatchProcessingLength) + "\n"; | 125 var line = this.textEditor.line(lineNumber).substring(0, WebInspecto
r.CSSSourceFrame.maxSwatchProcessingLength); |
121 var match; | 126 var results = WebInspector.TextUtils.splitStringByRegexes(line, rege
xes); |
122 while ((match = colorRegex.exec(line)) !== null) { | 127 for (var i = 0; i < results.length; i++) { |
123 if (match.length < 2) | 128 var result = results[i]; |
| 129 if (result.regexIndex === -1 || !handlers.has(regexes[result.reg
exIndex])) |
124 continue; | 130 continue; |
125 var colorText = match[1]; | 131 var delimiters = /[\s:;,(){}]/; |
126 var color = WebInspector.Color.parse(colorText); | 132 var positionBefore = result.position - 1; |
127 if (color) | 133 var positionAfter = result.position + result.value.length; |
128 colorPositions.push(new WebInspector.CSSSourceFrame.ColorPos
ition(color, lineNumber, match.index, colorText.length)); | 134 if (positionBefore >= 0 && !delimiters.test(line.charAt(position
Before)) |
| 135 || positionAfter < line.length && !delimiters.test(line.char
At(positionAfter))) |
| 136 continue; |
| 137 var swatch = handlers.get(regexes[result.regexIndex])(result.val
ue); |
| 138 if (!swatch) |
| 139 continue; |
| 140 swatches.push(swatch); |
| 141 swatchPositions.push(WebInspector.TextRange.createFromLocation(l
ineNumber, result.position)); |
129 } | 142 } |
130 } | 143 } |
131 | 144 this.textEditor.operation(putSwatchesInline.bind(this)); |
132 this.textEditor.operation(putColorSwatchesInline.bind(this)); | |
133 | 145 |
134 /** | 146 /** |
135 * @this {WebInspector.CSSSourceFrame} | 147 * @this {WebInspector.CSSSourceFrame} |
136 */ | 148 */ |
137 function putColorSwatchesInline() | 149 function putSwatchesInline() |
138 { | 150 { |
139 this._clearBookmarks(startLine, endLine); | 151 var clearRange = new WebInspector.TextRange(startLine, 0, endLine, t
his.textEditor.line(endLine).length); |
| 152 this.textEditor.bookmarks(clearRange, WebInspector.CSSSourceFrame.Sw
atchBookmark).forEach(marker => marker.clear()); |
140 | 153 |
141 for (var i = 0; i < colorPositions.length; i++) { | 154 for (var i = 0; i < swatches.length; i++) { |
142 var colorPosition = colorPositions[i]; | 155 var swatch = swatches[i]; |
143 var swatch = WebInspector.ColorSwatch.create(); | 156 var swatchPosition = swatchPositions[i]; |
144 swatch.setColorText(colorPosition.color.asString(WebInspector.Co
lor.Format.Original)); | 157 var bookmark = this.textEditor.addBookmark(swatchPosition.startL
ine, swatchPosition.startColumn, swatch, WebInspector.CSSSourceFrame.SwatchBookm
ark); |
145 swatch.iconElement().title = WebInspector.UIString("Open color p
icker."); | 158 swatch[WebInspector.CSSSourceFrame.SwatchBookmark] = bookmark; |
146 swatch.hideText(true); | |
147 var bookmark = this.textEditor.addBookmark(colorPosition.textRan
ge.startLine, colorPosition.textRange.startColumn, swatch, WebInspector.CSSSourc
eFrame.SwatchBookmark); | |
148 swatch.iconElement().addEventListener("click", this._showSpectru
m.bind(this, swatch, bookmark), true); | |
149 } | 159 } |
150 } | 160 } |
151 }, | 161 }, |
152 | 162 |
153 /** | 163 /** |
154 * @param {number} startLine | 164 * @param {string} text |
155 * @param {number} endLine | 165 * @return {?WebInspector.ColorSwatch} |
156 */ | 166 */ |
157 _clearBookmarks: function(startLine, endLine) | 167 _createColorSwatch: function(text) |
158 { | 168 { |
159 var range = new WebInspector.TextRange(startLine, 0, endLine, this.textE
ditor.line(endLine).length); | 169 if (!WebInspector.Color.parse(text)) |
160 this.textEditor.bookmarks(range, WebInspector.CSSSourceFrame.SwatchBookm
ark).forEach(marker => marker.clear()); | 170 return null; |
| 171 var swatch = WebInspector.ColorSwatch.create(); |
| 172 swatch.setColorText(text); |
| 173 swatch.iconElement().title = WebInspector.UIString("Open color picker.")
; |
| 174 swatch.iconElement().addEventListener("click", this._swatchIconClicked.b
ind(this, swatch), false); |
| 175 swatch.hideText(true); |
| 176 return swatch; |
| 177 }, |
| 178 |
| 179 /** |
| 180 * @param {string} text |
| 181 * @return {?WebInspector.BezierSwatch} |
| 182 */ |
| 183 _createBezierSwatch: function(text) |
| 184 { |
| 185 if (!WebInspector.Geometry.CubicBezier.parse(text)) |
| 186 return null; |
| 187 var swatch = WebInspector.BezierSwatch.create(); |
| 188 swatch.setBezierText(text); |
| 189 swatch.iconElement().title = WebInspector.UIString("Open cubic bezier ed
itor."); |
| 190 swatch.iconElement().addEventListener("click", this._swatchIconClicked.b
ind(this, swatch), false); |
| 191 swatch.hideText(true); |
| 192 return swatch; |
| 193 }, |
| 194 |
| 195 /** |
| 196 * @param {!Element} swatch |
| 197 * @param {!Event} event |
| 198 */ |
| 199 _swatchIconClicked: function(swatch, event) |
| 200 { |
| 201 event.consume(true); |
| 202 this._hadSwatchChange = false; |
| 203 this._muteSwatchProcessing = true; |
| 204 var swatchPosition = swatch[WebInspector.CSSSourceFrame.SwatchBookmark].
position(); |
| 205 this.textEditor.setSelection(swatchPosition); |
| 206 this._editedSwatchTextRange = swatchPosition.clone(); |
| 207 this._editedSwatchTextRange.endColumn += swatch.textContent.length; |
| 208 this._currentSwatch = swatch; |
| 209 |
| 210 if (swatch instanceof WebInspector.ColorSwatch) |
| 211 this._showSpectrum(swatch); |
| 212 else if (swatch instanceof WebInspector.BezierSwatch) |
| 213 this._showBezierEditor(swatch); |
161 }, | 214 }, |
162 | 215 |
163 /** | 216 /** |
164 * @param {!WebInspector.ColorSwatch} swatch | 217 * @param {!WebInspector.ColorSwatch} swatch |
165 * @param {!WebInspector.TextEditorBookMark} bookmark | |
166 * @param {!Event} event | |
167 */ | 218 */ |
168 _showSpectrum: function(swatch, bookmark, event) | 219 _showSpectrum: function(swatch) |
169 { | 220 { |
170 event.consume(true); | 221 if (!this._spectrum) { |
171 if (this._swatchPopoverHelper.isShowing()) { | 222 this._spectrum = new WebInspector.Spectrum(); |
172 this._swatchPopoverHelper.hide(true); | 223 this._spectrum.addEventListener(WebInspector.Spectrum.Events.SizeCha
nged, this._spectrumResized, this); |
173 return; | 224 this._spectrum.addEventListener(WebInspector.Spectrum.Events.ColorCh
anged, this._spectrumChanged, this); |
174 } | 225 } |
175 this._hadSpectrumChange = false; | |
176 var position = bookmark.position(); | |
177 var colorText = swatch.color().asString(WebInspector.Color.Format.Origin
al); | |
178 this.textEditor.setSelection(position); | |
179 this._currentColorTextRange = position.clone(); | |
180 this._currentColorTextRange.endColumn += colorText.length; | |
181 this._currentSwatch = swatch; | |
182 | |
183 this._spectrum = new WebInspector.Spectrum(); | |
184 this._spectrum.setColor(swatch.color(), swatch.format()); | 226 this._spectrum.setColor(swatch.color(), swatch.format()); |
185 this._spectrum.addEventListener(WebInspector.Spectrum.Events.SizeChanged
, this._spectrumResized, this); | 227 this._swatchPopoverHelper.show(this._spectrum, swatch.iconElement(), thi
s._swatchPopoverHidden.bind(this)); |
186 this._spectrum.addEventListener(WebInspector.Spectrum.Events.ColorChange
d, this._spectrumChanged, this); | |
187 this._swatchPopoverHelper.show(this._spectrum, swatch.iconElement(), thi
s._spectrumHidden.bind(this)); | |
188 }, | 228 }, |
189 | 229 |
190 /** | 230 /** |
191 * @param {!WebInspector.Event} event | 231 * @param {!WebInspector.Event} event |
192 */ | 232 */ |
193 _spectrumResized: function(event) | 233 _spectrumResized: function(event) |
194 { | 234 { |
195 this._swatchPopoverHelper.reposition(); | 235 this._swatchPopoverHelper.reposition(); |
196 }, | 236 }, |
197 | 237 |
198 /** | 238 /** |
199 * @param {!WebInspector.Event} event | 239 * @param {!WebInspector.Event} event |
200 */ | 240 */ |
201 _spectrumChanged: function(event) | 241 _spectrumChanged: function(event) |
202 { | 242 { |
203 this._muteColorProcessing = true; | |
204 this._hadSpectrumChange = true; | |
205 var colorString = /** @type {string} */ (event.data); | 243 var colorString = /** @type {string} */ (event.data); |
206 this._currentSwatch.setColorText(colorString); | 244 this._currentSwatch.setColorText(colorString); |
207 this._textEditor.editRange(this._currentColorTextRange, colorString, "*c
olor-text-changed"); | 245 this._changeSwatchText(colorString); |
208 this._currentColorTextRange.endColumn = this._currentColorTextRange.star
tColumn + colorString.length; | 246 }, |
| 247 |
| 248 /** |
| 249 * @param {!WebInspector.BezierSwatch} swatch |
| 250 */ |
| 251 _showBezierEditor: function(swatch) |
| 252 { |
| 253 if (!this._bezierEditor) { |
| 254 this._bezierEditor = new WebInspector.BezierEditor(); |
| 255 this._bezierEditor.addEventListener(WebInspector.BezierEditor.Events
.BezierChanged, this._bezierChanged, this); |
| 256 } |
| 257 var cubicBezier = WebInspector.Geometry.CubicBezier.parse(swatch.bezierT
ext()); |
| 258 if (!cubicBezier) |
| 259 cubicBezier = /** @type {!WebInspector.Geometry.CubicBezier} */ (Web
Inspector.Geometry.CubicBezier.parse("linear")); |
| 260 this._bezierEditor.setBezier(cubicBezier); |
| 261 this._swatchPopoverHelper.show(this._bezierEditor, swatch.iconElement(),
this._swatchPopoverHidden.bind(this)); |
| 262 }, |
| 263 |
| 264 /** |
| 265 * @param {!WebInspector.Event} event |
| 266 */ |
| 267 _bezierChanged: function(event) |
| 268 { |
| 269 var bezierString = /** @type {string} */ (event.data); |
| 270 this._currentSwatch.setBezierText(bezierString); |
| 271 this._changeSwatchText(bezierString); |
| 272 }, |
| 273 |
| 274 /** |
| 275 * @param {string} text |
| 276 */ |
| 277 _changeSwatchText: function(text) |
| 278 { |
| 279 this._hadSwatchChange = true; |
| 280 this._textEditor.editRange(this._editedSwatchTextRange, text, "*swatch-t
ext-changed"); |
| 281 this._editedSwatchTextRange.endColumn = this._editedSwatchTextRange.star
tColumn + text.length; |
209 }, | 282 }, |
210 | 283 |
211 /** | 284 /** |
212 * @param {boolean} commitEdit | 285 * @param {boolean} commitEdit |
213 */ | 286 */ |
214 _spectrumHidden: function(commitEdit) | 287 _swatchPopoverHidden: function(commitEdit) |
215 { | 288 { |
216 this._muteColorProcessing = false; | 289 this._muteSwatchProcessing = false; |
217 this._spectrum.removeEventListener(WebInspector.Spectrum.Events.SizeChan
ged, this._spectrumResized, this); | 290 if (!commitEdit && this._hadSwatchChange) |
218 this._spectrum.removeEventListener(WebInspector.Spectrum.Events.ColorCha
nged, this._spectrumChanged, this); | |
219 if (!commitEdit && this._hadSpectrumChange) | |
220 this.textEditor.undo(); | 291 this.textEditor.undo(); |
221 delete this._spectrum; | |
222 delete this._currentSwatch; | |
223 delete this._currentColorTextRange; | |
224 }, | 292 }, |
225 | 293 |
226 /** | 294 /** |
227 * @override | 295 * @override |
228 */ | 296 */ |
229 onTextEditorContentSet: function() | 297 onTextEditorContentSet: function() |
230 { | 298 { |
231 WebInspector.UISourceCodeFrame.prototype.onTextEditorContentSet.call(thi
s); | 299 WebInspector.UISourceCodeFrame.prototype.onTextEditorContentSet.call(thi
s); |
232 if (!this._muteColorProcessing) | 300 if (!this._muteSwatchProcessing) |
233 this._updateColorSwatches(0, this.textEditor.linesCount - 1); | 301 this._updateSwatches(0, this.textEditor.linesCount - 1); |
234 }, | 302 }, |
235 | 303 |
236 /** | 304 /** |
237 * @override | 305 * @override |
238 * @param {!WebInspector.TextRange} oldRange | 306 * @param {!WebInspector.TextRange} oldRange |
239 * @param {!WebInspector.TextRange} newRange | 307 * @param {!WebInspector.TextRange} newRange |
240 */ | 308 */ |
241 onTextChanged: function(oldRange, newRange) | 309 onTextChanged: function(oldRange, newRange) |
242 { | 310 { |
243 WebInspector.UISourceCodeFrame.prototype.onTextChanged.call(this, oldRan
ge, newRange); | 311 WebInspector.UISourceCodeFrame.prototype.onTextChanged.call(this, oldRan
ge, newRange); |
244 if (!this._muteColorProcessing) | 312 if (!this._muteSwatchProcessing) |
245 this._updateColorSwatches(newRange.startLine, newRange.endLine); | 313 this._updateSwatches(newRange.startLine, newRange.endLine); |
246 }, | 314 }, |
247 | 315 |
248 /** | 316 /** |
249 * @override | 317 * @override |
250 * @param {number} lineNumber | 318 * @param {number} lineNumber |
251 */ | 319 */ |
252 scrollChanged: function(lineNumber) | 320 scrollChanged: function(lineNumber) |
253 { | 321 { |
254 WebInspector.UISourceCodeFrame.prototype.scrollChanged.call(this, lineNu
mber); | 322 WebInspector.UISourceCodeFrame.prototype.scrollChanged.call(this, lineNu
mber); |
255 if (this._swatchPopoverHelper.isShowing()) | 323 if (this._swatchPopoverHelper.isShowing()) |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
313 else | 381 else |
314 return null; | 382 return null; |
315 } | 383 } |
316 tokenPosition = token.startColumn - 1; | 384 tokenPosition = token.startColumn - 1; |
317 } | 385 } |
318 return null; | 386 return null; |
319 }, | 387 }, |
320 | 388 |
321 __proto__: WebInspector.UISourceCodeFrame.prototype | 389 __proto__: WebInspector.UISourceCodeFrame.prototype |
322 } | 390 } |
323 | |
324 /** | |
325 * @constructor | |
326 * @param {!WebInspector.Color} color | |
327 * @param {number} lineNumber | |
328 * @param {number} startColumn | |
329 * @param {number} textLength | |
330 */ | |
331 WebInspector.CSSSourceFrame.ColorPosition = function(color, lineNumber, startCol
umn, textLength) | |
332 { | |
333 this.color = color; | |
334 this.textRange = new WebInspector.TextRange(lineNumber, startColumn, lineNum
ber, startColumn + textLength); | |
335 } | |
OLD | NEW |