Skip to content

Commit

Permalink
Update editor to parse the DOM to the post AT
Browse files Browse the repository at this point in the history
  • Loading branch information
mixonic committed Jul 6, 2015
1 parent 0a36660 commit e59eaf7
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 26 deletions.
65 changes: 57 additions & 8 deletions src/js/editor/editor.js
Expand Up @@ -22,6 +22,7 @@ import {
} from 'content-kit-compiler';
import { toArray, merge, mergeWithOptions } from 'content-kit-utils';
import { win, doc } from 'content-kit-editor/utils/compat';
import ElementMap from "../utils/element-map";

var defaults = {
placeholder: 'Write here...',
Expand Down Expand Up @@ -51,6 +52,17 @@ var defaults = {
cards: {}
};

function replaceInArray(array, original, replacement) {
var i, l, possibleOriginal;
for (i=0,l=array.length;i<l;i++) {
possibleOriginal = array[i];
if (possibleOriginal === original) {
array[i] = replacement;
return;
}
}
}

function bindContentEditableTypingListeners(editor) {


Expand Down Expand Up @@ -85,7 +97,43 @@ function bindContentEditableTypingListeners(editor) {
}

function bindLiveUpdate(editor) {
editor.element.addEventListener('input', function() {
editor.element.addEventListener('input', () => {
var selection = document.getSelection();
if (selection.rangeCount) {
var range = selection.getRangeAt(0);
if (range.collapsed) {
var element = range.startContainer;
var sectionElement, section;
while (element) {
section = editor.sectionElementMap.get(element);
if (section) {
sectionElement = element;
break;
}
element = element.parentNode;
}

if (!sectionElement) {
throw new Error('There is not section element for the previous edit');
}

var previousSectionElement;
if (sectionElement && sectionElement.previousSibling) {
previousSectionElement = sectionElement.previousSibling;
}

var newSection = editor.compiler.parseSection(
previousSectionElement.dataset.section,
sectionElement.firstChild
);

// FIXME: This would benefit from post being a linked-list of sections
replaceInArray(editor.model.sections, section, newSection);
editor.sectionElementMap.set(sectionElement, newSection);
editor.trigger('update');
return;
}
}
editor.syncContentEditableBlocks();
});
}
Expand Down Expand Up @@ -178,6 +226,8 @@ function Editor(element, options) {
});
}

this.sectionElementMap = new ElementMap();

if (element) {
applyClassName(element);
applyPlaceholder(element, editor.placeholder);
Expand All @@ -188,7 +238,11 @@ function Editor(element, options) {
if (editor.model) {
editor.loadModel(editor.model);
} else {
editor.sync();
this.syncModel();
while (element.childNodes.length) {
element.childNodes[0].remove();
}
this.syncVisual();
}

bindContentEditableTypingListeners(editor);
Expand Down Expand Up @@ -219,12 +273,7 @@ Editor.prototype.syncModel = function() {
};

Editor.prototype.syncVisual = function() {
this.compiler.render(this.model, this.element);
};

Editor.prototype.sync = function() {
this.syncModel();
this.syncVisual();
this.compiler.render(this.model, this.sectionElementMap, this.element);
};

Editor.prototype.getCurrentBlockIndex = function(element) {
Expand Down
29 changes: 11 additions & 18 deletions src/js/renderers/new-dom-renderer.js
@@ -1,21 +1,15 @@
function renderHeadline(doc, text) {
var element = doc.createElement('h2');
element.textContent = text;
return element;
}

function renderParagraph(doc, types, markers) {
var element = doc.createElement('p');
function renderMarkupSection(doc, section, markers) {
var element = doc.createElement(section.tagName);
var elements = [element];
var currentElement = element;
var i, l, j, m, marker, openTypes, closeTypes, text;
var markerType, markerTypeAttrs;
var openedElement, openedTagName;
for (i=0, l=markers.length;i<l;i++) {
marker = markers[i];
openTypes = marker[0];
closeTypes = marker[1];
text = marker[2];
openTypes = marker.open;
closeTypes = marker.close;
text = marker.value;

for (j=0, m=openTypes.length;j<m;j++) {
markerType = openTypes[j];
Expand Down Expand Up @@ -58,22 +52,21 @@ function NewDOMRenderer(doc, cards) {
this.cards = cards;
};

NewDOMRenderer.prototype.render = function NewDOMRenderer_render(data, target) {
NewDOMRenderer.prototype.render = function NewDOMRenderer_render(data, elementMap, target) {
var sections = data.sections;
var i, l, section, node;
for (i=0, l=sections.length;i<l;i++) {
node = this.document.createElement('section');
section = sections[i];
switch (section[0]) {
case 2:
node.appendChild(renderHeadline(this.document, section[1]));
break;
elementMap.set(node, section);
switch (section.type) {
case 1:
node.appendChild(renderParagraph(this.document, section[1]));
node.appendChild(renderMarkupSection(this.document, section, section.markups));
break;
case 5:
throw new Error('unimplemented');
var componentFn = this.cards[section[1]];
node.appendChild(componentFn(this.document, section[2]));
node.appendChild(componentFn(this.document, section.markups));
break;
}
target.appendChild(node);
Expand Down
30 changes: 30 additions & 0 deletions src/js/utils/element-map.js
@@ -0,0 +1,30 @@
// start at one to make the falsy semantics easier
let uuidGenerator = 1;

class ElementMap {
constructor() {
this._map = {};
}
set(key, value) {
let uuid = key.dataset.uuid;
if (!uuid) {
key.dataset.uuid = uuid = uuidGenerator++;
}
this._map[uuid] = value;
}
get(key) {
if (key.dataset && key.dataset.uuid) {
return this._map[key.dataset.uuid];
}
return null;
}
remove(key) {
if (!key.dataset.uuid) {
throw new Error('tried to fetch a value for an element not seen before');
}
delete this._map[key.dataset.uuid];
}

}

export default ElementMap;

0 comments on commit e59eaf7

Please sign in to comment.