Bug 713612 - add closing curly bracket to avoid disrupting the rest of the CSS. r=rcampbell
authorCedric Vivier <cedricv@neonux.com>
Wed, 25 Jan 2012 03:04:00 +0100
changeset 86561 006eb238ac904fdba62b7eb3eb7411d5d09b4c8b
parent 86560 2d2a7c5534e37ddccd283331e88357cbeee9e1b5
child 86562 01a1a9d501067995a4748d8327af189974230494
push id805
push userakeybl@mozilla.com
push dateWed, 01 Feb 2012 18:17:35 +0000
treeherdermozilla-aurora@6fb3bf232436 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersrcampbell
bugs713612
milestone12.0a1
Bug 713612 - add closing curly bracket to avoid disrupting the rest of the CSS. r=rcampbell
browser/devtools/styleeditor/StyleEditor.jsm
browser/devtools/styleeditor/test/browser_styleeditor_new.js
--- a/browser/devtools/styleeditor/StyleEditor.jsm
+++ b/browser/devtools/styleeditor/StyleEditor.jsm
@@ -224,16 +224,18 @@ StyleEditor.prototype = {
       placeholderText: this._state.text, //! this is initialText (bug 680371)
       showLineNumbers: true,
       mode: SourceEditor.MODES.CSS,
       readOnly: this._state.readOnly,
       keys: this._getKeyBindings()
     };
 
     sourceEditor.init(aElement, config, function onSourceEditorReady() {
+      setupBracketCompletion(sourceEditor);
+
       sourceEditor.addEventListener(SourceEditor.EVENTS.TEXT_CHANGED,
                                     function onTextChanged(aEvent) {
         this.updateStyleSheet();
       }.bind(this));
 
       this._sourceEditor = sourceEditor;
 
       if (this._focusOnSourceEditorReady) {
@@ -1127,8 +1129,53 @@ function prettifyCSS(aText)
   * @param string aText
   * @param number aCount
   * @return string
   */
 function repeat(aText, aCount)
 {
   return (new Array(aCount + 1)).join(aText);
 }
+
+/**
+ * Set up bracket completion on a given SourceEditor.
+ * This automatically closes the following CSS brackets: "{", "(", "["
+ *
+ * @param SourceEditor aSourceEditor
+ */
+function setupBracketCompletion(aSourceEditor)
+{
+  let editorElement = aSourceEditor.editorElement;
+  let pairs = {
+    123: { // {
+      closeString: "}",
+      closeKeyCode: Ci.nsIDOMKeyEvent.DOM_VK_CLOSE_BRACKET
+    },
+    40: { // (
+      closeString: ")",
+      closeKeyCode: Ci.nsIDOMKeyEvent.DOM_VK_0
+    },
+    91: { // [
+      closeString: "]",
+      closeKeyCode: Ci.nsIDOMKeyEvent.DOM_VK_CLOSE_BRACKET
+    },
+  };
+
+  editorElement.addEventListener("keypress", function onKeyPress(aEvent) {
+    let pair = pairs[aEvent.charCode];
+    if (!pair) {
+      return true;
+    }
+
+    // We detected an open bracket, sending closing character
+    let keyCode = pair.closeKeyCode;
+    let charCode = pair.closeString.charCodeAt(0);
+    let modifiers = 0;
+    let utils = editorElement.ownerDocument.defaultView.
+                  QueryInterface(Ci.nsIInterfaceRequestor).
+                  getInterface(Ci.nsIDOMWindowUtils);
+    let handled = utils.sendKeyEvent("keydown", keyCode, 0, modifiers);
+    utils.sendKeyEvent("keypress", 0, charCode, modifiers, !handled);
+    utils.sendKeyEvent("keyup", keyCode, 0, modifiers);
+    // and rewind caret
+    aSourceEditor.setCaretOffset(aSourceEditor.getCaretOffset() - 1);
+  }, false);
+}
--- a/browser/devtools/styleeditor/test/browser_styleeditor_new.js
+++ b/browser/devtools/styleeditor/test/browser_styleeditor_new.js
@@ -1,16 +1,16 @@
 /* vim: set ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 const TESTCASE_URI = TEST_BASE + "simple.html";
 
 const TRANSITION_CLASS = "moz-styleeditor-transitioning";
-
+const TESTCASE_CSS_SOURCE = "body{background-color:red;";
 
 function test()
 {
   waitForExplicitFinish();
 
   addTabAndLaunchStyleEditorChromeWhenLoaded(function (aChrome) {
     aChrome.addChromeListener({
       onContentAttach: run,
@@ -74,19 +74,23 @@ function testEditorAdded(aChrome, aEdito
         let ruleCount = summary.querySelector(".stylesheet-rule-count").textContent;
         is(parseInt(ruleCount), 0,
            "new editor initially shows 0 rules");
 
         let computedStyle = content.getComputedStyle(content.document.body, null);
         is(computedStyle.backgroundColor, "rgb(255, 255, 255)",
            "content's background color is initially white");
 
-        for each (let c in "body{background-color:red;}") {
+        for each (let c in TESTCASE_CSS_SOURCE) {
           EventUtils.synthesizeKey(c, {}, gChromeWindow);
         }
+
+        is(aEditor.sourceEditor.getText(), TESTCASE_CSS_SOURCE + "}",
+           "rule bracket has been auto-closed");
+
       }, gChromeWindow) ;
     },
 
     onUpdate: function (aEditor) {
       gUpdateCount++;
 
       ok(content.document.documentElement.classList.contains(TRANSITION_CLASS),
          "StyleEditor's transition class has been added to content");