Bug 712982 - can't select line by clicking the line number in scratchpad; r=rcampbell
☠☠ backed out by 2f8173cb3e9f ☠ ☠
authorMihai Sucan <mihai.sucan@gmail.com>
Fri, 17 Feb 2012 19:10:40 +0200
changeset 87141 8114f8011a9ed75020df02f64de8fad9d327062c
parent 87140 0815f202f7f14d168f338f793178fd898bd91b53
child 87142 00bce5149395c84b8ad57fb7cc063ea63d5ec0d3
push id543
push usermihai.sucan@gmail.com
push dateSat, 18 Feb 2012 12:04:18 +0000
treeherderfx-team@00bce5149395 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersrcampbell
bugs712982
milestone13.0a1
Bug 712982 - can't select line by clicking the line number in scratchpad; r=rcampbell
browser/devtools/sourceeditor/source-editor-orion.jsm
browser/devtools/sourceeditor/test/Makefile.in
browser/devtools/sourceeditor/test/browser_bug712982_line_ruler_click.js
--- a/browser/devtools/sourceeditor/source-editor-orion.jsm
+++ b/browser/devtools/sourceeditor/source-editor-orion.jsm
@@ -302,16 +302,18 @@ SourceEditor.prototype = {
       let rulerClass = this._annotationRuler ?
                        "ruler lines linesWithAnnotations" :
                        "ruler lines";
 
       this._linesRuler = new LineNumberRuler(this._annotationModel, "left",
         {styleClass: rulerClass}, {styleClass: "rulerLines odd"},
         {styleClass: "rulerLines even"});
 
+      this._linesRuler.onClick = this._linesRulerClick.bind(this);
+      this._linesRuler.onDblClick = this._linesRulerDblClick.bind(this);
       this._view.addRuler(this._linesRuler);
     }
 
     if (config.showOverviewRuler) {
       this._overviewRuler = new OverviewRuler(this._annotationModel, "right",
         {styleClass: "ruler overview"});
       this._overviewRuler.onClick = this._overviewRulerClick.bind(this);
 
@@ -615,16 +617,69 @@ SourceEditor.prototype = {
       lineStyle: {styleClass: "annotationLine currentLine"},
     };
 
     annotationModel.replaceAnnotations(oldAnnotation ? [oldAnnotation] : null,
                                        [this._currentLineAnnotation]);
   },
 
   /**
+   * The click event handler for the lines gutter. This function allows the user
+   * to jump to a line or to perform line selection while holding the Shift key
+   * down.
+   *
+   * @private
+   * @param number aLineIndex
+   *        The line index where the click event occurred.
+   * @param object aEvent
+   *        The DOM click event object.
+   */
+  _linesRulerClick: function SE__linesRulerClick(aLineIndex, aEvent)
+  {
+    if (aLineIndex === undefined) {
+      return;
+    }
+
+    if (aEvent.shiftKey) {
+      let model = this._model;
+      let selection = this.getSelection();
+      let selectionLineStart = model.getLineAtOffset(selection.start);
+      let selectionLineEnd = model.getLineAtOffset(selection.end);
+      let newStart = aLineIndex <= selectionLineStart ?
+                     model.getLineStart(aLineIndex) : selection.start;
+      let newEnd = aLineIndex <= selectionLineStart ?
+                   selection.end : model.getLineEnd(aLineIndex);
+      this.setSelection(newStart, newEnd);
+    } else {
+      this.setCaretPosition(aLineIndex);
+    }
+  },
+
+  /**
+   * The dblclick event handler for the lines gutter. This function selects the
+   * whole line where the event occurred.
+   *
+   * @private
+   * @param number aLineIndex
+   *        The line index where the double click event occurred.
+   * @param object aEvent
+   *        The DOM dblclick event object.
+   */
+  _linesRulerDblClick: function SE__linesRulerDblClick(aLineIndex)
+  {
+    if (aLineIndex === undefined) {
+      return;
+    }
+
+    let newStart = this._model.getLineStart(aLineIndex);
+    let newEnd = this._model.getLineEnd(aLineIndex);
+    this.setSelection(newStart, newEnd);
+  },
+
+  /**
    * Highlight the Orion annotations. This updates the annotation styler as
    * needed.
    * @private
    */
   _highlightAnnotations: function SE__highlightAnnotations()
   {
     if (this._annotationStyler) {
       this._annotationStyler.destroy();
--- a/browser/devtools/sourceeditor/test/Makefile.in
+++ b/browser/devtools/sourceeditor/test/Makefile.in
@@ -52,12 +52,13 @@ include $(topsrcdir)/config/rules.mk
 		browser_bug687580_drag_and_drop.js \
 		browser_bug684546_reset_undo.js \
 		browser_bug695035_middle_click_paste.js \
 		browser_bug687160_line_api.js \
 		browser_bug650345_find.js \
 		browser_bug703692_focus_blur.js \
 		browser_bug725388_mouse_events.js \
 		browser_bug707987_debugger_breakpoints.js \
+		browser_bug712982_line_ruler_click.js \
 		head.js \
 
 libs:: $(_BROWSER_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)
new file mode 100644
--- /dev/null
+++ b/browser/devtools/sourceeditor/test/browser_bug712982_line_ruler_click.js
@@ -0,0 +1,74 @@
+/* vim: set ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+function test() {
+
+  let temp = {};
+  Cu.import("resource:///modules/source-editor.jsm", temp);
+  let SourceEditor = temp.SourceEditor;
+
+  let component = Services.prefs.getCharPref(SourceEditor.PREFS.COMPONENT);
+  if (component == "textarea") {
+    ok(true, "skip test for bug 712982: only applicable for non-textarea components");
+    return;
+  }
+
+  waitForExplicitFinish();
+
+  let editor;
+
+  const windowUrl = "data:text/xml,<?xml version='1.0'?>" +
+    "<window xmlns='http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul'" +
+    " title='test for bug 712982' width='600' height='500'><hbox flex='1'/></window>";
+  const windowFeatures = "chrome,titlebar,toolbar,centerscreen,resizable,dialog=no";
+
+  let testWin = Services.ww.openWindow(null, windowUrl, "_blank", windowFeatures, null);
+  testWin.addEventListener("load", function onWindowLoad() {
+    testWin.removeEventListener("load", onWindowLoad, false);
+    waitForFocus(initEditor, testWin);
+  }, false);
+
+  function initEditor()
+  {
+    let hbox = testWin.document.querySelector("hbox");
+    editor = new SourceEditor();
+    editor.init(hbox, {showLineNumbers: true}, editorLoaded);
+  }
+
+  function editorLoaded()
+  {
+    editor.focus();
+
+    editor.setText("line1\nline2\nline3\nline4");
+
+    editor.setCaretPosition(3);
+    let pos = editor.getCaretPosition();
+    ok(pos.line == 3 && pos.col == 0, "initial caret location is correct");
+
+    EventUtils.synthesizeMouse(editor.editorElement, 10, 10, {}, testWin);
+
+    is(editor.getCaretOffset(), 0, "click on line 0 worked");
+
+    editor.setCaretPosition(2);
+    EventUtils.synthesizeMouse(editor.editorElement, 11, 11,
+                               {shiftKey: true}, testWin);
+    is(editor.getSelectedText().trim(), "line1\nline2", "shift+click works");
+
+    editor.setCaretOffset(0);
+
+    EventUtils.synthesizeMouse(editor.editorElement, 10, 10,
+                               {clickCount: 2}, testWin);
+
+    is(editor.getSelectedText().trim(), "line1", "double click works");
+
+    editor.destroy();
+
+    testWin.close();
+    testWin = editor = null;
+
+    waitForFocus(finish, window);
+  }
+}