Merge pull request #1275 from ajaxorg/dnd

fix editor getting stuck in drag mode
This commit is contained in:
Lennart Kats 2013-03-08 06:22:42 -08:00
commit 614a0b57d1
8 changed files with 209 additions and 64 deletions

View file

@ -1800,6 +1800,10 @@ var Editor = function(renderer, session) {
* *
**/ **/
this.navigateUp = function(times) { this.navigateUp = function(times) {
if (this.selection.isMultiLine() && !this.selection.isBackwards()) {
var selectionStart = this.selection.anchor.getPosition();
return this.moveCursorToPosition(selectionStart);
}
this.selection.clearSelection(); this.selection.clearSelection();
times = times || 1; times = times || 1;
this.selection.moveCursorBy(-times, 0); this.selection.moveCursorBy(-times, 0);
@ -1812,6 +1816,10 @@ var Editor = function(renderer, session) {
* *
**/ **/
this.navigateDown = function(times) { this.navigateDown = function(times) {
if (this.selection.isMultiLine() && this.selection.isBackwards()) {
var selectionEnd = this.selection.anchor.getPosition();
return this.moveCursorToPosition(selectionEnd);
}
this.selection.clearSelection(); this.selection.clearSelection();
times = times || 1; times = times || 1;
this.selection.moveCursorBy(times, 0); this.selection.moveCursorBy(times, 0);

View file

@ -73,7 +73,7 @@ function HashHandler(config, platform) {
if(!key) if(!key)
return; return;
if (typeof command == "function") { if (typeof command == "function") {
this.addCommand({exec: command, bindKey: key, name: key}); this.addCommand({exec: command, bindKey: key, name: command.name || key});
return; return;
} }

View file

@ -13,3 +13,22 @@
[1, +1, -1, 12_345, 0.000_1, [1, +1, -1, 12_345, 0.000_1,
_, 3_1, 1_2, 1_.0, 0._1]; _, 3_1, 1_2, 1_.0, 0._1];
{:id => 34, :key => "value"}
=begin
=end
=begin x
=end-
=end x
herDocs = [<<'FOO', <<BAR, <<-BAZ, <<-`EXEC`] #comment
FOO #{literal}
FOO
BAR #{fact(10)}
BAR
BAZ indented
BAZ
echo hi
EXEC
puts herDocs

View file

@ -132,4 +132,101 @@
],[ ],[
"start", "start",
["text"," "] ["text"," "]
],[
"start",
["paren.lparen","{"],
["constant.other.symbol.ruby",":id"],
["text"," "],
["punctuation.separator.key-value","=>"],
["text"," "],
["constant.numeric","34"],
["text",", "],
["constant.other.symbol.ruby",":key"],
["text"," "],
["punctuation.separator.key-value","=>"],
["text"," "],
["string","\"value\""],
["paren.rparen","}"]
],[
"start"
],[
"comment",
["comment","=begin"]
],[
"start",
["comment","=end"]
],[
"start"
],[
"comment",
["comment","=begin x"]
],[
"comment",
["comment","=end-"]
],[
"start",
["comment","=end x"]
],[
"start"
],[
["heredoc","FOO","heredoc","BAR","indentedHeredoc","BAZ","indentedHeredoc","EXEC"],
["text"," "],
["identifier","herDocs"],
["text"," "],
["keyword.operator","="],
["text"," "],
["paren.lparen","["],
["constant","<<"],
["string","'"],
["support.class","FOO"],
["string","'"],
["text",", "],
["constant","<<"],
["string",""],
["support.class","BAR"],
["string",""],
["text",", "],
["constant","<<-"],
["string",""],
["support.class","BAZ"],
["string",""],
["text",", "],
["constant","<<-"],
["string","`"],
["support.class","EXEC"],
["string","`"],
["paren.rparen","]"],
["text"," "],
["comment","#comment"]
],[
["heredoc","FOO","heredoc","BAR","indentedHeredoc","BAZ","indentedHeredoc","EXEC"],
["string"," FOO #{literal}"]
],[
["heredoc","BAR","indentedHeredoc","BAZ","indentedHeredoc","EXEC"],
["support.class","FOO"]
],[
["heredoc","BAR","indentedHeredoc","BAZ","indentedHeredoc","EXEC"],
["string"," BAR #{fact(10)}"]
],[
["indentedHeredoc","BAZ","indentedHeredoc","EXEC"],
["support.class","BAR"]
],[
["indentedHeredoc","BAZ","indentedHeredoc","EXEC"],
["string"," BAZ indented"]
],[
["indentedHeredoc","EXEC"],
["string"," "],
["support.class","BAZ"]
],[
["indentedHeredoc","EXEC"],
["string"," echo hi"]
],[
"start",
["string"," "],
["support.class","EXEC"]
],[
"start",
["support.function","puts"],
["text"," "],
["identifier","herDocs"]
]] ]]

View file

@ -930,6 +930,12 @@ var PhpLangHighlightRules = function() {
"HP_(?:BINDIR|CONFIG_FILE_(?:PATH|SCAN_DIR)|DATADIR|E(?:OL|XTENSION_DIR)|INT_(?:MAX|SIZE)|" + "HP_(?:BINDIR|CONFIG_FILE_(?:PATH|SCAN_DIR)|DATADIR|E(?:OL|XTENSION_DIR)|INT_(?:MAX|SIZE)|" +
"L(?:IBDIR|OCALSTATEDIR)|O(?:S|UTPUT_HANDLER_(?:CONT|END|START))|PREFIX|S(?:API|HLIB_SUFFIX|YSCONFDIR)|" + "L(?:IBDIR|OCALSTATEDIR)|O(?:S|UTPUT_HANDLER_(?:CONT|END|START))|PREFIX|S(?:API|HLIB_SUFFIX|YSCONFDIR)|" +
"VERSION))|__COMPILER_HALT_OFFSET__)\\b" "VERSION))|__COMPILER_HALT_OFFSET__)\\b"
}, {
token : ["keyword", "text", "support.class"],
regex : "\\b(new)(\\s+)(\\w+)"
}, {
token : ["support.class", "keyword.operator"],
regex : "\\b(\\w+)(::)"
}, { }, {
token : "constant.language", // constants token : "constant.language", // constants
regex : "\\b(?:A(?:B(?:DAY_(?:1|2|3|4|5|6|7)|MON_(?:1(?:0|1|2|)|2|3|4|5|6|7|8|9))|LT_DIGITS|M_STR|" + regex : "\\b(?:A(?:B(?:DAY_(?:1|2|3|4|5|6|7)|MON_(?:1(?:0|1|2|)|2|3|4|5|6|7|8|9))|LT_DIGITS|M_STR|" +
@ -982,7 +988,7 @@ var PhpLangHighlightRules = function() {
next: "heredoc" next: "heredoc"
}, { }, {
token : "keyword.operator", token : "keyword.operator",
regex : "!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)" regex : "::|!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)"
}, { }, {
token : "paren.lparen", token : "paren.lparen",
regex : "[[({]" regex : "[[({]"

View file

@ -134,7 +134,7 @@ var RubyHighlightRules = function() {
regex : "#.*$" regex : "#.*$"
}, { }, {
token : "comment", // multi line comment token : "comment", // multi line comment
regex : "^=begin\\s", regex : "^=begin(?:$|\\s.*$)",
next : "comment" next : "comment"
}, { }, {
token : "string.regexp", token : "string.regexp",
@ -231,7 +231,7 @@ var RubyHighlightRules = function() {
"comment" : [ "comment" : [
{ {
token : "comment", // closing comment token : "comment", // closing comment
regex : "^=end\\s.*$", regex : "^=end(?:$|\\s.*$)",
next : "start" next : "start"
}, { }, {
token : "comment", // comment spanning whole line token : "comment", // comment spanning whole line

View file

@ -36,7 +36,7 @@ var event = require("../lib/event");
var DragdropHandler = function(mouseHandler) { var DragdropHandler = function(mouseHandler) {
var editor = mouseHandler.editor; var editor = mouseHandler.editor;
var dragSelectionMarker, x, y; var dragSelectionMarker, x, y;
var timerId, range, isBackwards; var timerId, range;
var dragCursor, counter = 0; var dragCursor, counter = 0;
var mouseTarget = editor.container; var mouseTarget = editor.container;
@ -44,18 +44,11 @@ var DragdropHandler = function(mouseHandler) {
if (editor.getReadOnly()) if (editor.getReadOnly())
return; return;
var types = e.dataTransfer.types; var types = e.dataTransfer.types;
if (types && Array.prototype.indexOf.call(types, 'Files') !== -1) if (types && Array.prototype.indexOf.call(types, "text/plain") === -1)
return; return;
if (!dragSelectionMarker)
addDragMarker();
counter++; counter++;
if (!dragSelectionMarker) {
range = editor.getSelectionRange();
isBackwards = editor.selection.isBackwards();
var style = editor.getSelectionStyle();
dragSelectionMarker = editor.session.addMarker(range, "ace_selection", style);
editor.clearSelection();
clearInterval(timerId);
timerId = setInterval(onDragInterval, 20);
}
return event.preventDefault(e); return event.preventDefault(e);
}); });
@ -63,8 +56,10 @@ var DragdropHandler = function(mouseHandler) {
if (editor.getReadOnly()) if (editor.getReadOnly())
return; return;
var types = e.dataTransfer.types; var types = e.dataTransfer.types;
if (types && Array.prototype.indexOf.call(types, 'Files') !== -1) if (types && Array.prototype.indexOf.call(types, "text/plain") === -1)
return; return;
if (onMouseMoveTimer !== null)
onMouseMoveTimer = null;
x = e.clientX; x = e.clientX;
y = e.clientY; y = e.clientY;
return event.preventDefault(e); return event.preventDefault(e);
@ -77,36 +72,50 @@ var DragdropHandler = function(mouseHandler) {
}; };
event.addListener(mouseTarget, "dragleave", function(e) { event.addListener(mouseTarget, "dragleave", function(e) {
if (editor.getReadOnly())
return;
var types = e.dataTransfer.types;
if (types && Array.prototype.indexOf.call(types, 'Files') !== -1)
return;
counter--; counter--;
if (counter > 0) if (counter <= 0 && dragSelectionMarker) {
return; clearDragMarker();
clearInterval(timerId); return event.preventDefault(e);
editor.session.removeMarker(dragSelectionMarker); }
dragSelectionMarker = null;
editor.selection.setSelectionRange(range, isBackwards);
return event.preventDefault(e);
}); });
event.addListener(mouseTarget, "drop", function(e) { event.addListener(mouseTarget, "drop", function(e) {
if (editor.getReadOnly()) if (!dragSelectionMarker)
return; return;
counter = 0;
clearInterval(timerId);
editor.session.removeMarker(dragSelectionMarker);
dragSelectionMarker = null;
range.end = editor.session.insert(dragCursor, e.dataTransfer.getData('Text')); range.end = editor.session.insert(dragCursor, e.dataTransfer.getData('Text'));
range.start = dragCursor; range.start = dragCursor;
clearDragMarker();
editor.focus(); editor.focus();
editor.selection.setSelectionRange(range);
return event.preventDefault(e); return event.preventDefault(e);
}); });
function addDragMarker() {
range = editor.selection.toOrientedRange();
dragSelectionMarker = editor.session.addMarker(range, "ace_selection", editor.getSelectionStyle());
editor.clearSelection();
clearInterval(timerId);
timerId = setInterval(onDragInterval, 20);
counter = 0;
event.addListener(document, "mousemove", onMouseMove);
}
function clearDragMarker() {
clearInterval(timerId);
editor.session.removeMarker(dragSelectionMarker);
dragSelectionMarker = null;
editor.selection.fromOrientedRange(range);
counter = 0;
event.removeListener(document, "mousemove", onMouseMove);
}
// sometimes other code on the page can stop dragleave event leaving editor stuck in the drag state
var onMouseMoveTimer = null;
function onMouseMove() {
if (onMouseMoveTimer == null) {
onMouseMoveTimer = setTimeout(function() {
if (onMouseMoveTimer != null && dragSelectionMarker)
clearDragMarker();
}, 20);
}
}
}; };
exports.DragdropHandler = DragdropHandler; exports.DragdropHandler = DragdropHandler;

View file

@ -75,6 +75,7 @@ function simpleRule(regex, name, captures) {
name = name || "text"; name = name || "text";
var rule = {}; var rule = {};
var origRegex = regex
regex = transformRegExp(regex, rule); regex = transformRegExp(regex, rule);
if (captures) { if (captures) {
var tokenArray = []; var tokenArray = [];
@ -94,6 +95,7 @@ function simpleRule(regex, name, captures) {
try {new RegExp(regex);} catch(e) { try {new RegExp(regex);} catch(e) {
rule.TODO = "FIXME: regexp doesn't have js equivalent"; rule.TODO = "FIXME: regexp doesn't have js equivalent";
rule.originalRegex = origRegex
} }
rule.token = name; rule.token = name;
rule.regex = regex; rule.regex = regex;
@ -111,18 +113,21 @@ function removeXFlag(str) {
if (s[0] == "\\") if (s[0] == "\\")
return /[#\s]/.test(s[1]) ? s[1] : s; return /[#\s]/.test(s[1]) ? s[1] : s;
return ""; return "";
}); }).substr(4);
} }
return str; return str;
} }
function transformRegExp(str, rule) { function transformRegExp(str, rule) {
str = removeXFlag(str); str = removeXFlag(str);
//str = str.replace(/\\n\$|\$\\n/g, '$');
str = str.replace(/\\n(?!\?).?/g, '$'); // replace newlines by $ except if its postfixed by ? str = str.replace(/\\n(?!\?).?/g, '$'); // replace newlines by $ except if its postfixed by ?
if (/\(\?[i]\:/g.test(str)) { if (/\(\?[i]\:|\(?\w*i\w*\)/g.test(str)) {
str = str.replace(/\(\?[ims\-]\:/g, "(?:"); // checkForInvariantRegex str = str.replace(/\(\?[ims\-]\:/g, "(?:"); // checkForInvariantRegex
str = str.replace(/\(\?[imsx\-]\)/g, "");
rule && (rule.caseInsensitive = true); rule && (rule.caseInsensitive = true);
} }
str = str.replace(/(\\[xu]){([a-fA-F\d]+)}/g, '$1$2');
return str; return str;
} }
@ -140,7 +145,8 @@ var modeTemplate = fs.readFileSync(__dirname + "/mode.tmpl.js", "utf8");
var modeHighlightTemplate = fs.readFileSync(__dirname + "/mode_highlight_rules.tmpl.js", "utf8"); var modeHighlightTemplate = fs.readFileSync(__dirname + "/mode_highlight_rules.tmpl.js", "utf8");
function convertLanguageFile(name) { function convertLanguageFile(name) {
var tmLanguage = fs.readFileSync(process.cwd() + "/" + name, "utf8"); var path = /^(\/|\w:)/.test(name) ? name : process.cwd() + "/" + name
var tmLanguage = fs.readFileSync(path, "utf8");
parseLanguage(tmLanguage, function(language) { parseLanguage(tmLanguage, function(language) {
var languageHighlightFilename = language.name.replace(/[-_]/g, "").toLowerCase(); var languageHighlightFilename = language.name.replace(/[-_]/g, "").toLowerCase();
var languageNameSanitized = language.name.replace(/-/g, ""); var languageNameSanitized = language.name.replace(/-/g, "");