diff --git a/browser/devtools/sourceeditor/source-editor-orion.jsm b/browser/devtools/sourceeditor/source-editor-orion.jsm index f6d379618c5..1aa2181e055 100644 --- a/browser/devtools/sourceeditor/source-editor-orion.jsm +++ b/browser/devtools/sourceeditor/source-editor-orion.jsm @@ -153,16 +153,10 @@ const DEFAULT_KEYBINDINGS = [ alt: true, }, { - action: "Comment", + action: "Comment/Uncomment", code: Ci.nsIDOMKeyEvent.DOM_VK_SLASH, accel: true, }, - { - action: "Uncomment", - code: Ci.nsIDOMKeyEvent.DOM_VK_SLASH, - accel: true, - shift: true, - }, ]; var EXPORTED_SYMBOLS = ["SourceEditor"]; @@ -403,8 +397,7 @@ SourceEditor.prototype = { "Find Previous Occurrence": [this.ui.findPrevious, this.ui], "Goto Line...": [this.ui.gotoLine, this.ui], "Move Lines Down": [this._moveLines, this], - "Comment": [this._doComment, this], - "Uncomment": [this._doUncomment, this], + "Comment/Uncomment": [this._doCommentUncomment, this], }; for (let name in actions) { @@ -1050,6 +1043,63 @@ SourceEditor.prototype = { return {line: line, blockStart: blockCommentStart, blockEnd: blockCommentEnd}; }, + /** + * Decide whether to comment the selection/current line or to uncomment it. + * + * @private + */ + _doCommentUncomment: function SE__doCommentUncomment() + { + if (this.readOnly) { + return false; + } + + let commentObject = this._getCommentStrings(); + if (!commentObject) { + return false; + } + + let selection = this.getSelection(); + let model = this._model; + let firstLine = model.getLineAtOffset(selection.start); + let lastLine = model.getLineAtOffset(selection.end); + + // Checks for block comment. + let firstLineText = model.getLine(firstLine); + let lastLineText = model.getLine(lastLine); + let openIndex = firstLineText.indexOf(commentObject.blockStart); + let closeIndex = lastLineText.lastIndexOf(commentObject.blockEnd); + if (openIndex != -1 && closeIndex != -1 && + (firstLine != lastLine || + (closeIndex - openIndex) >= commentObject.blockStart.length)) { + return this._doUncomment(); + } + + if (!commentObject.line) { + return this._doComment(); + } + + // If the selection is not a block comment, check for the first and the last + // lines to be line commented. + let firstLastCommented = [firstLineText, + lastLineText].every(function(aLineText) { + let openIndex = aLineText.indexOf(commentObject.line); + if (openIndex != -1) { + let textUntilComment = aLineText.slice(0, openIndex); + if (!textUntilComment || /^\s+$/.test(textUntilComment)) { + return true; + } + } + return false; + }); + if (firstLastCommented) { + return this._doUncomment(); + } + + // If we reach here, then we have to comment the selection/line. + return this._doComment(); + }, + /** * Wrap the selected text in comments. If nothing is selected the current * caret line is commented out. Single line and block comments depend on the @@ -1123,7 +1173,9 @@ SourceEditor.prototype = { let lastLineText = this._model.getLine(lastLine); let openIndex = firstLineText.indexOf(commentObject.blockStart); let closeIndex = lastLineText.lastIndexOf(commentObject.blockEnd); - if (openIndex != -1 && closeIndex != -1) { + if (openIndex != -1 && closeIndex != -1 && + (firstLine != lastLine || + (closeIndex - openIndex) >= commentObject.blockStart.length)) { let firstLineStartOffset = this.getLineStart(firstLine); let lastLineStartOffset = this.getLineStart(lastLine); let openOffset = firstLineStartOffset + openIndex; diff --git a/browser/devtools/sourceeditor/test/browser_bug725430_comment_uncomment.js b/browser/devtools/sourceeditor/test/browser_bug725430_comment_uncomment.js index fca682a692b..5fbe1d89bd8 100644 --- a/browser/devtools/sourceeditor/test/browser_bug725430_comment_uncomment.js +++ b/browser/devtools/sourceeditor/test/browser_bug725430_comment_uncomment.js @@ -48,7 +48,7 @@ function test() { editor.redo(); is(editor.getText(), "//" + text, "Redo works"); editor.setCaretPosition(0); - EventUtils.synthesizeKey("/", {accelKey: true, shiftKey: true}, testWin); + EventUtils.synthesizeKey("/", {accelKey: true}, testWin); is(editor.getText(), text, "JS Single Line Uncommenting works"); editor.setText(text); @@ -61,18 +61,18 @@ function test() { editor.redo(); is(editor.getText(), "/*" + text + "*/", "Redo works"); EventUtils.synthesizeKey("VK_A", {accelKey: true}, testWin); - EventUtils.synthesizeKey("/", {accelKey: true, shiftKey: true}, testWin); + EventUtils.synthesizeKey("/", {accelKey: true}, testWin); is(editor.getText(), text, "JS Block Uncommenting works"); editor.undo(); is(editor.getText(), "/*" + text + "*/", "Undo Block Uncommenting works"); editor.redo(); is(editor.getText(), text, "Redo works"); - let regText = "//firstline\n // secondline\nthird//line\nfourthline//"; - let expText = "firstline\n secondline\nthird//line\nfourthline//"; + let regText = "//firstline\n // secondline\nthird//line\n//fourthline"; + let expText = "firstline\n secondline\nthird//line\nfourthline"; editor.setText(regText); EventUtils.synthesizeKey("VK_A", {accelKey: true}, testWin); - EventUtils.synthesizeKey("/", {accelKey: true, shiftKey: true}, testWin); + EventUtils.synthesizeKey("/", {accelKey: true}, testWin); is(editor.getText(), expText, "JS Multiple Line Uncommenting works"); editor.undo(); is(editor.getText(), regText, "Undo Multiple Line Uncommenting works"); @@ -87,7 +87,7 @@ function test() { EventUtils.synthesizeKey("/", {accelKey: true}, testWin); is(editor.getText(), expText, "CSS Commenting without selection works"); editor.setCaretPosition(0); - EventUtils.synthesizeKey("/", {accelKey: true, shiftKey: true}, testWin); + EventUtils.synthesizeKey("/", {accelKey: true}, testWin); is(editor.getText(), text, "CSS Uncommenting without selection works"); editor.setText(text); @@ -96,7 +96,7 @@ function test() { EventUtils.synthesizeKey("/", {accelKey: true}, testWin); is(editor.getText(), "/*" + text + "*/", "CSS Multiple Line Commenting works"); EventUtils.synthesizeKey("VK_A", {accelKey: true}, testWin); - EventUtils.synthesizeKey("/", {accelKey: true, shiftKey: true}, testWin); + EventUtils.synthesizeKey("/", {accelKey: true}, testWin); is(editor.getText(), text, "CSS Multiple Line Uncommenting works"); editor.setMode(SourceEditor.MODES.HTML); @@ -107,7 +107,7 @@ function test() { EventUtils.synthesizeKey("/", {accelKey: true}, testWin); is(editor.getText(), expText, "HTML Commenting without selection works"); editor.setCaretPosition(0); - EventUtils.synthesizeKey("/", {accelKey: true, shiftKey: true}, testWin); + EventUtils.synthesizeKey("/", {accelKey: true}, testWin); is(editor.getText(), text, "HTML Uncommenting without selection works"); editor.setText(text); @@ -116,7 +116,7 @@ function test() { EventUtils.synthesizeKey("/", {accelKey: true}, testWin); is(editor.getText(), "", "HTML Multiple Line Commenting works"); EventUtils.synthesizeKey("VK_A", {accelKey: true}, testWin); - EventUtils.synthesizeKey("/", {accelKey: true, shiftKey: true}, testWin); + EventUtils.synthesizeKey("/", {accelKey: true}, testWin); is(editor.getText(), text, "HTML Multiple Line Uncommenting works"); editor.setMode(SourceEditor.MODES.TEXT); @@ -125,10 +125,10 @@ function test() { editor.setCaretPosition(0); EventUtils.synthesizeKey("/", {accelKey: true}, testWin); is(editor.getText(), text, "Commenting disabled in Text mode"); - editor.setText("//" + text); + editor.setText(regText); EventUtils.synthesizeKey("VK_A", {accelKey: true}, testWin); - EventUtils.synthesizeKey("/", {accelKey: true, shiftKey: true}, testWin); - is(editor.getText(), "//" + text, "Uncommenting disabled in Text mode"); + EventUtils.synthesizeKey("/", {accelKey: true}, testWin); + is(editor.getText(), regText, "Uncommenting disabled in Text mode"); editor.setText(text); editor.readOnly = true; @@ -136,10 +136,10 @@ function test() { editor.setCaretPosition(0); EventUtils.synthesizeKey("/", {accelKey: true}, testWin); is(editor.getText(), text, "Commenting disabled in ReadOnly mode"); - editor.setText("//" + text); + editor.setText(regText); EventUtils.synthesizeKey("VK_A", {accelKey: true}, testWin); - EventUtils.synthesizeKey("/", {accelKey: true, shiftKey: true}, testWin); - is(editor.getText(), "//" + text, "Uncommenting disabled in ReadOnly mode"); + EventUtils.synthesizeKey("/", {accelKey: true}, testWin); + is(editor.getText(), regText, "Uncommenting disabled in ReadOnly mode"); editor.destroy();