Skip to content

Commit

Permalink
Re-organize the editor into a more self-contained object.
Browse files Browse the repository at this point in the history
  • Loading branch information
pdubroy committed Sep 17, 2014
1 parent a8e2f77 commit 1b5d54a
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 75 deletions.
106 changes: 59 additions & 47 deletions editor/editor.js
Original file line number Diff line number Diff line change
@@ -1,48 +1,20 @@
function $(sel) { return document.querySelector(sel); }
function $$(sel) { return document.querySelectorAll(sel); }

var nodes = {};
var codeMirror = CodeMirror.fromTextArea($('textarea'));
codeMirror.on('change', _.debounce(editorOnChange, 250));

var moonchild = Moonchild.registerExtension();
Moonchild.setEditor(new Editor());

var options = {};

function editorOnChange(cm, changeObj) {
Moonchild.onChange(cm.getValue());
}
var codeMirror; // TODO: Get rid of this global.

function render(node) {
var widgetInfo = moonchild.getWidget(node);
if (widgetInfo)
renderWidget(codeMirror, node, widgetInfo);
else
clearWidgets(codeMirror, node);
}
// Private helpers
// ---------------

moonchild.on('render', function(ast, comments) {
ast.each(render);
comments.each(render);
});
function $(sel) { return document.querySelector(sel); }
function $$(sel) { return document.querySelectorAll(sel); }

// Highlights the text of the given AST node in the editor.
function highlightNode(node) {
var marker = markNodeText(codeMirror, node, { className: 'highlight' });
setTimeout(function() {
marker.clear();
}, 1000);
function editorOnChange(cm, changeObj) {
Moonchild.onChange(cm.getValue());
}

codeMirror.on('mousedown', function(cm, e) {
var classList = e.target.classList;
if (classList.contains('mc-metadata')) {
var id = _.find(classList, function(className) {
return className.indexOf('mc-node-') == 0;
});
highlightNode(nodes[id]);
}
});

function toggle(el, value) {
if (value !== undefined)
el.classList.toggle('on', value);
Expand All @@ -51,15 +23,55 @@ function toggle(el, value) {
options[el.id] = el.classList.contains('on');
}

var controls = $$('#controls > div');
for (var i = 0; i < controls.length; i++) {
controls[i].addEventListener('click', function(e) {
toggle(this);
e.preventDefault();
if (this.id == 'all') {
for (var j = 0; j < controls.length; j++)
toggle(controls[j], this.classList.contains('on'));
}
Moonchild.onChange(codeMirror.getValue());
function initializeExtensionToggles(cm) {
var controls = $$('#controls > div');
for (var i = 0; i < controls.length; i++) {
controls[i].addEventListener('click', function(e) {
toggle(this);
e.preventDefault();
if (this.id == 'all') {
for (var j = 0; j < controls.length; j++)
toggle(controls[j], this.classList.contains('on'));
}
Moonchild.onChange(cm.getValue());
});
}
}

function renderNode(cm, node) {
var widgetInfo = moonchild.getWidget(node);
if (widgetInfo)
renderWidget(cm, node, widgetInfo);
else
clearWidgets(cm, node);
}

// Editor
// ------

function Editor() {
codeMirror = CodeMirror.fromTextArea($('textarea'));
codeMirror.on('change', _.debounce(editorOnChange, 250));

var render = _.partial(renderNode, codeMirror);
moonchild.on('render', function(ast, comments) {
ast.each(render);
comments.each(render);
});

codeMirror.on('cursorActivity', function(cm, e) {
var adjacentMarks = cm.findMarksAt(cm.getCursor());
if (adjacentMarks.length == 0 || !adjacentMarks[0].replacedWith)
return;

var markEl = widgetForMark(adjacentMarks[0]);
var widgetType = markEl._moonchildWidgetType;
if (widgetType && widgetType.editable)
console.log(markEl);
});

initializeExtensionToggles(codeMirror);
}

Editor.prototype.replaceRange = function(text, fromOffset, toOffset) {
}
2 changes: 1 addition & 1 deletion editor/plugins/metadata.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
<script>
Moonchild.registerExtension('metadata', function(moonchild) {
var markers = [];
var nodes = {};

// Add a parse listener that attaches a unique ID to each node, and then marks
// the text of each comment with its associated AST node.
Expand Down Expand Up @@ -34,7 +35,6 @@

// When the mark is cleared because the cursor is inside it, trigger a
// reparse as soon as the cursor leaves the node again.
// TODO
marker.on('clear', function() {
if (!containsCursor(codeMirror, node.metadata))
return;
Expand Down
37 changes: 21 additions & 16 deletions lib/moonchild-bundle.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@
},{"FWaASH":4,"esprima":21,"estraverse":22,"fs":3,"underscore":24}],2:[function(_dereq_,module,exports){
// Generated by CoffeeScript 1.7.1
(function() {
var Extension, addHook, applySafely, estraverse, expanders, exportsExpander, getHookArgs, globalExtensions, globalHooks, hooksDo, initializeExtension, onChange, parse, parser, registerExtension, widgetExpander, _;
var Extension, addHook, applySafely, estraverse, expanders, exportsExpander, getEditor, getHookArgs, globalEditor, globalExtensions, globalHooks, initializeExtension, invokeHook, onChange, parse, parser, registerExtension, setEditor, widgetExpander, _;

parser = _dereq_('./metadata');

Expand All @@ -113,6 +113,8 @@

globalExtensions = {};

globalEditor = {};

widgetExpander = expanders.createExpander('displayWidget');

exportsExpander = expanders.createExpander('extensionId');
Expand Down Expand Up @@ -175,10 +177,10 @@
hooks[id].push(func);
};

hooksDo = function(hook, iter) {
return _.each(hook, function(hookFns, id) {
invokeHook = function(hook, args) {
return _.each(globalHooks[hook], function(hookFns, id) {
return _.each(hookFns, function(fn) {
return iter(fn, id);
return applySafely(fn, args);
});
});
};
Expand Down Expand Up @@ -214,12 +216,9 @@
};

parse = function(hooks, source) {
var hookArgs, tree;
var tree;
tree = parser.parse(source);
hookArgs = getHookArgs(tree);
hooksDo(globalHooks['parse'], function(func, id) {
return applySafely(func, hookArgs);
});
invokeHook('parse', getHookArgs(tree));
return tree;
};

Expand Down Expand Up @@ -254,20 +253,26 @@
return;
}
hookArgs = getHookArgs(tree);
hooksDo(globalHooks['display'], function(func, id) {
return applySafely(func, hookArgs);
});
return hooksDo(globalHooks['render'], function(func, id) {
return applySafely(func, hookArgs);
});
invokeHook('display', hookArgs);
return invokeHook('render', hookArgs);
};

setEditor = function(editor) {
return globalEditor = editor;
};

getEditor = function() {
return globalEditor;
};

module.exports = {
on: _.partial(addHook, null, globalHooks),
onChange: onChange,
parse: parse,
registerExtension: registerExtension,
traverse: estraverse.traverse
traverse: estraverse.traverse,
setEditor: setEditor,
getEditor: getEditor
};

}).call(this);
Expand Down
27 changes: 16 additions & 11 deletions moonchild.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ expanders = require 'expanders'

globalHooks = {}
globalExtensions = {}
globalEditor = {}

widgetExpander = expanders.createExpander('displayWidget')
exportsExpander = expanders.createExpander('extensionId')
Expand Down Expand Up @@ -63,9 +64,10 @@ addHook = (id, hookState, hookName, func) ->
hooks[id].push(func)
return

hooksDo = (hook, iter) ->
_.each hook, (hookFns, id) ->
_.each hookFns, (fn) -> iter(fn, id)
invokeHook = (hook, args) ->
_.each globalHooks[hook], (hookFns, id) ->
_.each hookFns, (fn) ->
applySafely(fn, args)

initializeExtension = (ext, deps, initFn) ->
result = initFn?.apply(null, [ext].concat(deps))
Expand Down Expand Up @@ -94,9 +96,7 @@ registerExtension = (id, deps, initFn) ->

parse = (hooks, source) ->
tree = parser.parse(source)
hookArgs = getHookArgs(tree)
hooksDo globalHooks['parse'], (func, id) ->
applySafely(func, hookArgs)
invokeHook('parse', getHookArgs(tree))
tree

getHookArgs = (ast) ->
Expand All @@ -123,17 +123,22 @@ onChange = (newValue) ->
# TODO: This should be moved into a function that can be invoked by the
# editor plugin.
hookArgs = getHookArgs(tree)
hooksDo globalHooks['display'], (func, id) ->
applySafely(func, hookArgs)
invokeHook('display', hookArgs)

# Run the render hooks.
hooksDo globalHooks['render'], (func, id) ->
applySafely(func, hookArgs)
invokeHook('render', hookArgs)

setEditor = (editor) ->
globalEditor = editor

getEditor = -> globalEditor

module.exports = {
on: _.partial(addHook, null, globalHooks)
onChange, # TODO: Get rid of this.
parse,
registerExtension,
traverse: estraverse.traverse
traverse: estraverse.traverse,
setEditor,
getEditor
}

0 comments on commit 1b5d54a

Please sign in to comment.