+ if(lastRect.bottom === caretRect.bottom || (caretRect.left > lastRect.left + lastRect.width)) {
+ e.preventDefault();
+ s.canvas.rootWrapper.find('[document-text-element]').each(function() {
+ var test = getFirstRectBelow(this, caretRect.bottom);
+ if(test) {
+ target = this;
+ rect = test;
+ return false;
+ }
+ });
+ if(target) {
+ scrolled = scroll('bottom', target);
+ position = utils.caretPositionFromPoint(caretRect.left, rect.top +1 - scrolled);
+ s.canvas.setCurrentElement(s.canvas.getDocumentElement(position.textNode), {caretTo: position.offset});
+ }
+ }
+ if(target) {
+ scrolled = scroll('bottom', target);
+ var left = caretRect.left;
+ if(left > rect.left + rect.width) {
+ left = rect.left + rect.width;
+ } else if(left < rect.left ) {
+ left = rect.left;
+ }
+ position = utils.caretPositionFromPoint(left, rect.top +1 - scrolled);
+ s.canvas.setCurrentElement(s.canvas.getDocumentElement(position.textNode), {caretTo: position.offset});
+ }
+ }
+ },
+ {
+ applies: function(e, s) {
+ return e.key === KEYS.ARROW_LEFT && s.type === 'caret';
+ },
+ run: function(e, s) {
+ /* globals window */
+ var prev;
+
+ if(s.offset === 0) {
+ e.preventDefault();
+ prev = s.canvas.getPreviousTextElement(s.element);
+ if(prev) {
+ scroll('top', prev.dom[0]);
+ s.canvas.setCurrentElement(s.canvas.getDocumentElement(prev.dom.contents()[0]), {caretTo: 'end'});
+ }
+ }
+ }
+ },
+ {
+ applies: function(e, s) {
+ return e.key === KEYS.ARROW_RIGHT && s.type === 'caret';
+ },
+ run: function(e, s) {
+ /* globals window */
+ var next;
+ if(s.isAtEnd()) {
+ e.preventDefault();
+ next = s.canvas.getNextTextElement(s.element);
+ if(next) {
+ scroll('bottom', next.dom[0]);
+ s.canvas.setCurrentElement(s.canvas.getDocumentElement(next.dom.contents()[0]), {caretTo: 0});
+ }
+ } else {
+ var secondToLast = (s.offset === s.element.wlxmlNode.getText().length -1);
+ if(secondToLast) {
+ // Only Flying Spaghetti Monster knows why this is need for FF (for versions at least 26 to 31)
+ e.preventDefault();
+ s.canvas.setCurrentElement(s.element, {caretTo: 'end'});
+ }
+ }
+ }
+ },
+ {
+ applies: function(e, s) {
+ return s.type === 'caret' &&
+ s.element.wlxmlNode.parent().is({tagName: 'span'}) &&
+ s.element.wlxmlNode.getText().length === 1 &&
+ s.offset === 1 &&
+ (e.key === KEYS.BACKSPACE);
+ },
+ run: function(e, s) {
+ var params = {},
+ prevTextNode = s.element.canvas.getPreviousTextElement(s.element).wlxmlNode;
+ e.preventDefault();
+ s.element.wlxmlNode.parent().detach(params);
+ s.canvas.setCurrentElement(
+ (params.ret && params.ret.mergedTo) || prevTextNode,
+ {caretTo: params.ret ? params.ret.previousLen : (prevTextNode ? prevTextNode.getText().length : 0)});
+ }
+ },
+ {
+ applies: function(e, s) {
+ return s.type === 'caret' && (
+ (s.isAtBeginning() && e.key === KEYS.BACKSPACE) ||
+ (s.isAtEnd() && e.key === KEYS.DELETE)
+ );
+ },
+ run: function(e,s) {
+ var direction, caretTo, cursorAtOperationEdge, goto, element;
+
+ if(e.key === KEYS.BACKSPACE) {
+ direction = 'above';