Changeset 185935 in webkit
- Timestamp:
- Jun 24, 2015 4:54:12 PM (9 years ago)
- Location:
- trunk/Source/WebInspectorUI
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebInspectorUI/ChangeLog
r185933 r185935 1 2015-06-24 Devin Rousso <drousso@apple.com> 2 3 Web Inspector: Pressing tab in the styles sidebar shouldn't insert a tab character 4 https://bugs.webkit.org/show_bug.cgi?id=146189 5 6 Reviewed by Timothy Hatcher. 7 8 * UserInterface/Controllers/CodeMirrorCompletionController.js: Added variable to control whether semicolons are added to the end of autocompleted css values. 9 (WebInspector.CodeMirrorCompletionController): 10 (WebInspector.CodeMirrorCompletionController.prototype.set noEndingSemicolon): 11 (WebInspector.CodeMirrorCompletionController.prototype._generateCSSCompletions): 12 * UserInterface/Views/CSSStyleDeclarationSection.js: 13 (WebInspector.CSSStyleDeclarationSection): 14 (WebInspector.CSSStyleDeclarationSection.prototype.cssStyleDeclarationTextEditorSwitchRule): 15 (WebInspector.CSSStyleDeclarationSection.prototype.focusRuleSelector): 16 (WebInspector.CSSStyleDeclarationSection.prototype.selectLastProperty): 17 (WebInspector.CSSStyleDeclarationSection.prototype.get selectorLocked): 18 (WebInspector.CSSStyleDeclarationSection.prototype.get locked): 19 (WebInspector.CSSStyleDeclarationSection.prototype._handleKeyDown): 20 * UserInterface/Views/CSSStyleDeclarationTextEditor.js: 21 (WebInspector.CSSStyleDeclarationTextEditor): Added functions for "Tab", "Shift-Tab", and "Shift-Enter" keypresses to improve usability. 22 (WebInspector.CSSStyleDeclarationTextEditor.prototype.selectFirstProperty): Highlights the first property. 23 (WebInspector.CSSStyleDeclarationTextEditor.prototype.selectLastProperty): Highlights the last property. 24 (WebInspector.CSSStyleDeclarationTextEditor.prototype._insertNewlineAfterCurrentLine): Inserts a newline after the currently selected line. 25 (WebInspector.CSSStyleDeclarationTextEditor.prototype._handleShiftTabKey.switchRule): 26 (WebInspector.CSSStyleDeclarationTextEditor.prototype._handleShiftTabKey): Pressing shift-tab will move the cursor to the previous non-word character that is immediately after a word character. 27 (WebInspector.CSSStyleDeclarationTextEditor.prototype._handleTabKey.switchRule): 28 (WebInspector.CSSStyleDeclarationTextEditor.prototype._handleTabKey.highlightNextNameOrValue): 29 (WebInspector.CSSStyleDeclarationTextEditor.prototype._handleTabKey): Pressing tab will move the cursor to each space character until the end of the line is reached, at 30 which point the cursor will move to the beginning of the next line. Once the cursor is at the last line, pressing tab again will insert a newline. 31 * UserInterface/Views/RulesStyleDetailsPanel.js: 32 (WebInspector.RulesStyleDetailsPanel.prototype.cssStyleDeclarationSectionEditorNextRule): Switches the focused rule to the next section. 33 (WebInspector.RulesStyleDetailsPanel.prototype.cssStyleDeclarationSectionEditorPrevRule): Switches the focused rule to the previous section. 34 1 35 2015-06-24 Joseph Pecoraro <pecoraro@apple.com> 2 36 -
trunk/Source/WebInspectorUI/UserInterface/Controllers/CodeMirrorCompletionController.js
r182113 r185935 40 40 this._lineNumber = NaN; 41 41 this._prefix = ""; 42 this._noEndingSemicolon = false; 42 43 this._completions = []; 43 44 this._extendedCompletionProviders = {}; … … 186 187 } 187 188 189 set noEndingSemicolon(noEndingSemicolon) 190 { 191 this._noEndingSemicolon = noEndingSemicolon; 192 } 193 188 194 // Private 189 195 … … 525 531 // If there is a suffix and it isn't a semicolon, then we should use a space since 526 532 // the user is editing in the middle. 527 this._implicitSuffix = suffix && suffix !== ";" ? " " : ";";533 this._implicitSuffix = suffix && suffix !== ";" ? " " : (this._noEndingSemicolon ? "" : ";"); 528 534 529 535 // Don't use an implicit suffix if it would be the same as the existing suffix. -
trunk/Source/WebInspectorUI/UserInterface/Views/CSSStyleDeclarationSection.js
r185784 r185935 51 51 this._selectorElement.addEventListener("mouseover", this._highlightNodesWithSelector.bind(this)); 52 52 this._selectorElement.addEventListener("mouseout", this._hideHighlightOnNodesWithSelector.bind(this)); 53 this._selectorElement.addEventListener("keydown", this._handleKeyDown.bind(this)); 53 54 this._headerElement.appendChild(this._selectorElement); 54 55 … … 334 335 }, 335 336 337 cssStyleDeclarationTextEditorSwitchRule: function(reverse) 338 { 339 if (!this._delegate) 340 return; 341 342 if (reverse && typeof this._delegate.cssStyleDeclarationSectionEditorPreviousRule === "function") 343 this._delegate.cssStyleDeclarationSectionEditorPreviousRule(this); 344 else if (!reverse && typeof this._delegate.cssStyleDeclarationSectionEditorNextRule === "function") 345 this._delegate.cssStyleDeclarationSectionEditorNextRule(this); 346 }, 347 348 focusRuleSelector: function(reverse) 349 { 350 if (this.selectorLocked) { 351 this.focus(); 352 return; 353 } 354 355 if (this.locked) { 356 this.cssStyleDeclarationTextEditorSwitchRule(reverse); 357 return; 358 } 359 360 var selection = window.getSelection(); 361 selection.removeAllRanges(); 362 363 this._element.scrollIntoViewIfNeeded(); 364 365 var range = document.createRange(); 366 range.selectNodeContents(this._selectorElement); 367 selection.addRange(range); 368 }, 369 370 selectLastProperty: function() 371 { 372 this._propertiesTextEditor.selectLastProperty(); 373 }, 374 375 get selectorLocked() 376 { 377 return !this.locked && !this._style.ownerRule; 378 }, 379 380 get locked() 381 { 382 return !this._style.editable; 383 }, 384 336 385 // Private 337 386 … … 419 468 }, 420 469 470 _handleKeyDown: function(event) 471 { 472 if (event.keyCode !== 9) 473 return; 474 475 if (event.shiftKey && this._delegate && typeof this._delegate.cssStyleDeclarationSectionEditorPreviousRule === "function") { 476 event.preventDefault(); 477 this._delegate.cssStyleDeclarationSectionEditorPreviousRule(this, true); 478 return; 479 } 480 481 if (!event.metaKey) { 482 event.preventDefault(); 483 this.focus(); 484 this._propertiesTextEditor.selectFirstProperty(); 485 return; 486 } 487 }, 488 421 489 _commitSelector: function(mutations) 422 490 { -
trunk/Source/WebInspectorUI/UserInterface/Views/CSSStyleDeclarationTextEditor.js
r185928 r185935 58 58 }); 59 59 60 this._codeMirror.addKeyMap({ 61 "Shift-Enter": this._insertNewlineAfterCurrentLine.bind(this), 62 "Shift-Tab": this._handleShiftTabKey.bind(this), 63 "Tab": this._handleTabKey.bind(this) 64 }); 65 60 66 this._completionController = new WebInspector.CodeMirrorCompletionController(this._codeMirror, this); 61 67 this._tokenTrackingController = new WebInspector.CodeMirrorTokenTrackingController(this._codeMirror, this); 68 69 this._completionController.noEndingSemicolon = true; 62 70 63 71 this._jumpToSymbolTrackingModeEnabled = false; … … 334 342 335 343 return true; 344 } 345 346 selectFirstProperty() 347 { 348 var line = this._codeMirror.getLine(0); 349 var trimmedLine = line.trimRight(); 350 351 if (!line || !trimmedLine.trimLeft().length) 352 this.clearSelection(); 353 354 var index = line.indexOf(":"); 355 this._codeMirror.setSelection({line: 0, ch: 0}, {line: 0, ch: index < 0 ? trimmedLine.length : index}); 356 } 357 358 selectLastProperty() 359 { 360 var line = this._codeMirror.lineCount() - 1; 361 var lineText = this._codeMirror.getLine(line); 362 var trimmedLine = lineText.trimRight(); 363 364 var colon = /(?::\s*)/.exec(lineText); 365 this._codeMirror.setSelection({line, ch: colon ? colon.index + colon[0].length : 0}, {line, ch: trimmedLine.length - trimmedLine.endsWith(";")}); 336 366 } 337 367 … … 359 389 360 390 // Private 391 392 _insertNewlineAfterCurrentLine(codeMirror) 393 { 394 var cursor = codeMirror.getCursor(); 395 var line = codeMirror.getLine(cursor.line); 396 var trimmedLine = line.trimRight(); 397 398 cursor.ch = trimmedLine.length; 399 400 if (cursor.ch) { 401 codeMirror.replaceRange(trimmedLine.endsWith(";") ? "\n" : ";\n", cursor); 402 return; 403 } 404 405 return CodeMirror.Pass; 406 } 407 408 _handleShiftTabKey(codeMirror) 409 { 410 function switchRule() 411 { 412 if (this._delegate && typeof this._delegate.cssStyleDeclarationTextEditorSwitchRule === "function") { 413 this._delegate.cssStyleDeclarationTextEditorSwitchRule(true); 414 return; 415 } 416 417 return CodeMirror.Pass; 418 } 419 420 var cursor = codeMirror.getCursor(); 421 var line = codeMirror.getLine(cursor.line); 422 var previousLine = codeMirror.getLine(cursor.line - 1); 423 var trimmedPreviousLine = previousLine ? previousLine.trimRight() : ""; 424 425 if (!line && !previousLine && !cursor.line) 426 return switchRule.call(this); 427 428 if (cursor.ch === line.indexOf(":") || line.indexOf(":") < 0) { 429 if (previousLine) { 430 var colon = /(?::\s*)/.exec(previousLine); 431 codeMirror.setSelection({line: cursor.line - 1, ch: colon ? colon.index + colon[0].length : 0}, {line: cursor.line - 1, ch: trimmedPreviousLine.length - trimmedPreviousLine.endsWith(";")}); 432 return; 433 } 434 435 if (cursor.line) { 436 codeMirror.setCursor(cursor.line - 1, 0); 437 return; 438 } 439 440 return switchRule.call(this); 441 } 442 443 var match = line.match(/(?:[^:;\s]\s*)+/g); 444 var lastMatch = line.indexOf(match.lastValue) + match.lastValue.length; 445 var prevHead = cursor.ch > lastMatch ? line.indexOf(match.lastValue) : line.indexOf(match[0]); 446 var prevAnchor = cursor.ch > lastMatch ? lastMatch : line.indexOf(match[0]) + match[0].length; 447 448 codeMirror.setSelection({line: cursor.line, ch: prevHead}, {line: cursor.line, ch: prevAnchor}); 449 } 450 451 _handleTabKey(codeMirror) 452 { 453 function switchRule() { 454 if (this._delegate && typeof this._delegate.cssStyleDeclarationTextEditorSwitchRule === "function") { 455 this._delegate.cssStyleDeclarationTextEditorSwitchRule(); 456 return; 457 } 458 459 return CodeMirror.Pass; 460 } 461 462 function highlightNextNameOrValue(text) 463 { 464 var match = text.match(/(?:[^:;\s]\s*)+/g); 465 var firstMatch = text.indexOf(match[0]) + match[0].length; 466 var nextHead = cursor.ch < firstMatch ? text.indexOf(match[0]) : text.indexOf(match[1]); 467 var nextAnchor = cursor.ch < firstMatch ? firstMatch : text.indexOf(match[1]) + match[1].length; 468 469 codeMirror.setSelection({line: cursor.line, ch: nextHead}, {line: cursor.line, ch: nextAnchor}); 470 } 471 472 var cursor = codeMirror.getCursor(); 473 var line = codeMirror.getLine(cursor.line); 474 var trimmedLine = line.trimRight(); 475 var lastLine = cursor.line === codeMirror.lineCount() - 1; 476 var nextLine = codeMirror.getLine(cursor.line + 1); 477 var trimmedNextLine = nextLine ? nextLine.trimRight() : ""; 478 479 if (!trimmedLine.trimLeft().length) { 480 if (lastLine) 481 return switchRule.call(this); 482 483 if (!trimmedNextLine.trimLeft().length) { 484 codeMirror.setCursor(cursor.line + 1, 0); 485 return; 486 } 487 488 ++cursor.line; 489 highlightNextNameOrValue(nextLine); 490 return; 491 } 492 493 if (trimmedLine.endsWith(":")) { 494 codeMirror.setCursor(cursor.line, line.length); 495 this._completionController._completeAtCurrentPosition(true); 496 return; 497 } 498 499 var hasEndingSemicolon = trimmedLine.endsWith(";"); 500 501 if (cursor.ch >= line.trimRight().length - hasEndingSemicolon) { 502 if (!line.includes(":")) { 503 codeMirror.setCursor(cursor.line, line.length); 504 codeMirror.replaceRange(": ", cursor); 505 return; 506 } 507 508 var replacement = ""; 509 510 if (!hasEndingSemicolon) 511 replacement += ";"; 512 513 if (lastLine) 514 replacement += "\n"; 515 516 if (replacement.length) 517 codeMirror.replaceRange(replacement, {line: cursor.line, ch: trimmedLine.length}); 518 519 if (!nextLine) { 520 codeMirror.setCursor(cursor.line + 1, 0); 521 return; 522 } 523 524 var colon = nextLine.indexOf(":"); 525 codeMirror.setSelection({line: cursor.line + 1, ch: 0}, {line: cursor.line + 1, ch: colon < 0 ? trimmedNextLine.length : colon}); 526 return; 527 } 528 529 highlightNextNameOrValue(line); 530 } 361 531 362 532 _clearRemoveEditingLineClassesTimeout() -
trunk/Source/WebInspectorUI/UserInterface/Views/RulesStyleDetailsPanel.js
r185845 r185935 303 303 } 304 304 305 cssStyleDeclarationSectionEditorNextRule(currentSection) 306 { 307 currentSection.clearSelection(); 308 309 var index = this._sections.indexOf(currentSection); 310 this._sections[index < this._sections.length - 1 ? index + 1 : 0].focusRuleSelector(); 311 } 312 313 cssStyleDeclarationSectionEditorPreviousRule(currentSection, selectLastProperty) { 314 currentSection.clearSelection(); 315 316 if (selectLastProperty || currentSection.selectorLocked) { 317 var index = this._sections.indexOf(currentSection); 318 index = index > 0 ? index - 1 : this._sections.length - 1; 319 320 var section = this._sections[index]; 321 while (section.locked) { 322 index = index > 0 ? index - 1 : this._sections.length - 1; 323 section = this._sections[index]; 324 } 325 326 section.focus(); 327 section.selectLastProperty(); 328 return; 329 } 330 331 currentSection.focusRuleSelector(true); 332 } 333 305 334 filterDidChange(filterBar) 306 335 {
Note: See TracChangeset
for help on using the changeset viewer.