From 244b7b50cd04affbd7abfefab09c644eebf67d3b Mon Sep 17 00:00:00 2001 From: gdub22 Date: Tue, 30 Sep 2014 18:35:51 -0400 Subject: [PATCH] ability to get cursor index --- demo/index.html | 3 +- src/css/embeds.less | 3 +- src/js/content-kit-editor/editor/editor.js | 42 ++++++++++++++----- .../utils/selection-utils.js | 16 ++++++- 4 files changed, 49 insertions(+), 15 deletions(-) diff --git a/demo/index.html b/demo/index.html index 034bc75f0..8d2da4c3a 100644 --- a/demo/index.html +++ b/demo/index.html @@ -24,7 +24,8 @@

ContentKit Editor

-

A modern, minimalist text editor allowing you to write in a distraction free environment. Simply select any text you would like to format and a toolbar will appear where you can toggle options such as bold and italic, or create a link.

+

+ A modern, minimalist text editor allowing you to write in a distraction free environment. Simply select any text you would like to format and a toolbar will appear where you can toggle options such as bold and italic, or create a link.

Create headings by pressing "H1" on the toolbar

Pressing "H2" will create a subheading, like this one.

Create block quotes by selecting any text and pressing the "quote" button. Press it again to toggle back to a standard paragraph.
diff --git a/src/css/embeds.less b/src/css/embeds.less index cd04bb2d8..cf051335c 100644 --- a/src/css/embeds.less +++ b/src/css/embeds.less @@ -75,8 +75,7 @@ .ck-embed iframe { margin: 0 auto !important; - // Allows us to select embeds and show a toolbar when clicking instead of playing videos/executing links - pointer-events: none; + // pointer-events: none; } .ck-embed figure { diff --git a/src/js/content-kit-editor/editor/editor.js b/src/js/content-kit-editor/editor/editor.js index 1340c60ef..c6c301384 100644 --- a/src/js/content-kit-editor/editor/editor.js +++ b/src/js/content-kit-editor/editor/editor.js @@ -14,11 +14,10 @@ import ImageCommand from '../commands/image'; import OEmbedCommand from '../commands/oembed'; import TextFormatCommand from '../commands/text-format'; import Keycodes from '../utils/keycodes'; -import { getSelectionBlockElement, getSelectionBlockTagName } from '../utils/selection-utils'; +import { getSelectionBlockElement, getSelectionBlockTagName, getCursorOffsetInElement } from '../utils/selection-utils'; import EventEmitter from '../utils/event-emitter'; import { cleanPastedContent } from '../utils/paste-utils'; import Compiler from '../../content-kit-compiler/compiler'; -import TextModel from '../../content-kit-compiler/models/text'; import Type from '../../content-kit-compiler/types/type'; import { toArray } from '../../content-kit-utils/array-utils'; import { merge, mergeWithOptions } from '../../content-kit-utils/object-utils'; @@ -94,14 +93,10 @@ function bindAutoTypingListeners(editor) { } function bindDragAndDrop() { - // Use these to add/remove classes - // window.addEventListener('dragenter', function(e) { }); - // window.addEventListener('dragleave', function(e) { }); - + // TODO. For now, just prevent redirect when dropping something on the page window.addEventListener('dragover', function(e) { e.preventDefault(); // prevents showing cursor where to drop }); - window.addEventListener('drop', function(e) { e.preventDefault(); // prevent page from redirecting }); @@ -159,6 +154,8 @@ function Editor(element, options) { element.setAttribute('contentEditable', true); editor.element = element; + editor.sync(); + bindContentEditableTypingCorrections(editor); bindPasteListener(editor); bindAutoTypingListeners(editor); @@ -169,7 +166,15 @@ function Editor(element, options) { editor.textFormatToolbar = new TextFormatToolbar({ rootElement: element, commands: editor.textFormatCommands, sticky: editor.stickyToolbar }); editor.linkTooltips = new Tooltip({ rootElement: element, showForTag: Type.LINK.tag }); - editor.syncModel(); + // TESTING + /* + editor.element.addEventListener('mouseup', function() { + console.log(editor.getCurrentEditingIndex()); + }); + editor.element.addEventListener('keyup', function() { + console.log(editor.getCurrentEditingIndex()); + }); + */ if(editor.autofocus) { element.focus(); } } @@ -178,6 +183,11 @@ function Editor(element, options) { // Add event emitter pub/sub functionality merge(Editor.prototype, EventEmitter); +Editor.prototype.sync = function() { + this.syncModel(); + this.syncVisual(); +}; + Editor.prototype.syncModel = function() { this.model = this.compiler.parse(this.element.innerHTML); this.trigger('update'); @@ -203,8 +213,7 @@ Editor.prototype.syncModelAtSelection = function() { }; Editor.prototype.syncVisual = function() { - var html = this.compiler.render(this.model); - this.element.innerHTML = html; + this.element.innerHTML = this.compiler.render(this.model); }; Editor.prototype.syncVisualAt = function(index) { @@ -223,13 +232,24 @@ Editor.prototype.getCurrentBlockIndex = function() { return blockElements.indexOf(selectionEl); }; +Editor.prototype.getCurrentCursorIndex = function() { + var currentBlock = getSelectionBlockElement(); + if (currentBlock) { + return getCursorOffsetInElement(currentBlock); + } + return -1; +}; + +Editor.prototype.getCurrentEditingIndex = function() { + return [this.getCurrentBlockIndex(), this.getCurrentCursorIndex()]; +}; + Editor.prototype.insertBlock = function(model) { this.insertBlockAt(model, this.getCurrentBlockIndex()); this.trigger('update'); }; Editor.prototype.insertBlockAt = function(model, index) { - model = model || new TextModel(); this.model.splice(index, 0, model); this.trigger('update'); }; diff --git a/src/js/content-kit-editor/utils/selection-utils.js b/src/js/content-kit-editor/utils/selection-utils.js index d88359c56..cd00eb3f4 100644 --- a/src/js/content-kit-editor/utils/selection-utils.js +++ b/src/js/content-kit-editor/utils/selection-utils.js @@ -94,5 +94,19 @@ function selectNode(node) { selection.addRange(range); } +function getCursorOffsetInElement(element) { + // http://stackoverflow.com/questions/4811822/get-a-ranges-start-and-end-offsets-relative-to-its-parent-container/4812022#4812022 + var caretOffset = 0; + var selection = window.getSelection(); + if (selection.rangeCount > 0) { + var range = selection.getRangeAt(0); + var preCaretRange = range.cloneRange(); + preCaretRange.selectNodeContents(element); + preCaretRange.setEnd(range.endContainer, range.endOffset); + caretOffset = preCaretRange.toString().length; + } + return caretOffset; +} + export { getDirectionOfSelection, getSelectionElement, getSelectionBlockElement, getSelectionTagName, - getSelectionBlockTagName, tagsInSelection, selectionIsInElement, selectionIsEditable, restoreRange, selectNode }; + getSelectionBlockTagName, tagsInSelection, selectionIsInElement, selectionIsEditable, restoreRange, selectNode, getCursorOffsetInElement };