diff --git a/sandbox/aloha-bootstrap-ui/index.html b/sandbox/aloha-bootstrap-ui/index.html
index 9c5961cadf..8f2e9e9e1a 100644
--- a/sandbox/aloha-bootstrap-ui/index.html
+++ b/sandbox/aloha-bootstrap-ui/index.html
@@ -13,7 +13,7 @@
- testing
+ Aloha Editot Bootstrap UI
diff --git a/src/aloha.js b/src/aloha.js
index 16e8215e48..be0de0f787 100644
--- a/src/aloha.js
+++ b/src/aloha.js
@@ -7,6 +7,7 @@ define([
'dragdrop',
'editables',
'autoformat',
+ 'boundaries',
'events',
'functions',
'keys',
@@ -23,6 +24,7 @@ define([
DragDrop,
Editables,
AutoFormat,
+ Boundaries,
Events,
Fn,
Keys,
@@ -37,14 +39,92 @@ define([
var doc = document;
var win = Dom.documentWindow(doc);
+ function getBoundaries(type, nativeEvent, target) {
+ var doc = target.document || target.ownerDocument;
+ if (('mousedown' === type || 'click' === type) && nativeEvent && doc) {
+ return Boundaries.fromPosition(
+ nativeEvent.clientX,
+ nativeEvent.clientY,
+ doc
+ );
+ }
+ if ('aloha' === type || 'mahalo' === type) {
+ return [Boundaries.create(target, 0), Boundaries.create(target, 0)];
+ }
+ return doc && Boundaries.get(doc);
+ }
+
+ /**
+ * Creates an event object that will contain the following properties:
+ * type
+ * target
+ * editor
+ * boundaries
+ *
+ * In addition to these mandatory properties, it may contain the following:
+ * editable
+ * nativeEvent
+ *
+ * @param {!Editor} editor
+ * @param {!Event} nativeEvent
+ * @param {!Object} custom
+ * @return {?Event}
+ */
+ function createEvent(editor, nativeEvent, custom) {
+ var type, target, editable, boundaries;
+ if (custom) {
+ type = custom.type;
+ target = custom.target;
+ editable = custom.editable;
+ boundaries = custom.boundaries;
+ }
+ if (!type && nativeEvent) {
+ type = nativeEvent.type;
+ if (!type) {
+ console.warn('no type');
+ return null;
+ }
+ }
+ if ('mousemove' === type) {
+ console.warn('ignore mousemove');
+ return null;
+ }
+ if (!target && nativeEvent) {
+ target = nativeEvent.target;
+ if (!target) {
+ console.warn('no target');
+ return null;
+ }
+ }
+ if (!boundaries) {
+ boundaries = getBoundaries(type, nativeEvent, target);
+ if (!boundaries) {
+ console.warn('no boundaries');
+ return null;
+ }
+ }
+ if (!editable) {
+ var cac = Boundaries.commonContainer(boundaries[0], boundaries[1]);
+ if (Dom.isEditableNode(cac)) {
+ editable = Editables.fromBoundary(editor, boundaries[0]);
+ }
+ }
+ return {
+ type : type,
+ target : target,
+ editor : editor,
+ editable : editable,
+ boundaries : boundaries,
+ nativeEvent : nativeEvent
+ };
+ }
+
function editor(nativeEvent, custom) {
- var event = custom || {nativeEvent : nativeEvent};
- event.editor = editor;
- event.lastEditableBoundaries = editor.lastEditableBoundaries;
- event.type = event.type || (nativeEvent && nativeEvent.type) || 'unknown';
- event = Fn.comp.apply(editor.stack, editor.stack)(event);
- editor.lastEditableBoundaries = event.boundaries;
- Selections.update(event);
+ var event = createEvent(editor, nativeEvent, custom);
+ if (event) {
+ event = Fn.comp.apply(editor.stack, editor.stack)(event);
+ Selections.update(event);
+ }
}
editor.BLOCK_CLASS = 'aloha-block';
@@ -73,24 +153,26 @@ define([
*
* Also serves as short aloha.aloha.
*
- * @param {Element} element
- * @parma {Object} options
+ * @param {!Element} element
+ * @parma {Object=} options
*/
function aloha(element, options) {
editor(null, {
type : 'aloha',
- element : element,
+ target : element,
options : options
});
}
+ /**
+ * Destroys an editable.
+ *
+ * @param {!Element} element
+ */
function mahalo(element) {
- var editable = Editables.fromElem(editor, element);
- Editables.close(editable);
- Editables.dissocFromEditor(editor, editable);
editor(null, {
- type : 'mahalo',
- editable : editable
+ type : 'mahalo',
+ target : element
});
}
diff --git a/src/autoformat.js b/src/autoformat.js
index 06e8f1afff..88ff4f1070 100644
--- a/src/autoformat.js
+++ b/src/autoformat.js
@@ -131,7 +131,7 @@ define([
}
function handleAutoFormat(event) {
- if ('keydown' !== event.type || !event.editable || !event.boundaries) {
+ if (!event.editable || 'keydown' !== event.type) {
return event;
}
if (
diff --git a/src/blocks.js b/src/blocks.js
index 001ff55721..9f38cf83ff 100644
--- a/src/blocks.js
+++ b/src/blocks.js
@@ -80,7 +80,7 @@ define([
}
function handleAloha(event) {
- var blocks = event.editable['elem'].querySelectorAll('.aloha-block,img');
+ var blocks = event.editable.elem.querySelectorAll('.aloha-block,img');
[].forEach.call(blocks, function (block) {
block.setAttribute('contentEditable', 'false');
Dom.setStyle(block, 'cursor', Browsers.VENDOR_PREFIX + 'grab');
@@ -128,18 +128,16 @@ define([
};
/**
- * Requires:
- * editor
- * Updates:
- * editable
+ * Updates editable
*
* @param {AlohaEvent} event
* @return {Event}
*/
function handleBlocks(event) {
- if (handlers[event.type]) {
- handlers[event.type](event);
+ if (!event.editable || !handlers[event.type]) {
+ return event;
}
+ handlers[event.type](event);
return event;
}
diff --git a/src/dragdrop.js b/src/dragdrop.js
index 6b6188c0b7..e81173c204 100644
--- a/src/dragdrop.js
+++ b/src/dragdrop.js
@@ -174,9 +174,7 @@ define([
alohaEvent.editor.dnd.element
);
}
- if (event.stopPropagation) {
- event.stopPropagation();
- }
+ Events.stopPropagation(event);
// Because some browsers will otherwise redirect
Events.preventDefault(event);
}
@@ -190,20 +188,16 @@ define([
/**
* Processes drag and drop events.
*
- * Requires:
- * editor
- * target
- * Updates:
- * editor.dnd
- * nativeEvent
+ * Updates editor.dnd and nativeEvent
*
* @param {AlohaEvent} event
* @return {AlohaEvent}
*/
function handleDragDrop(event) {
- if (event.editor.dnd && handlers[event.type]) {
- handlers[event.type](event);
+ if (!event.editable || !event.editor.dnd || !handlers[event.type]) {
+ return event;
}
+ handlers[event.type](event);
return event;
}
diff --git a/src/editables.js b/src/editables.js
index 57e47bc67c..a04a77083b 100644
--- a/src/editables.js
+++ b/src/editables.js
@@ -106,25 +106,26 @@ define([
return editable;
}
+ function destroy(editor, element) {
+ var editable = fromElem(editor, element);
+ close(editable);
+ dissocFromEditor(editor, editable);
+ return editable;
+ }
+
/**
* Associates an editable to the given AlohaEvent.
*
- * Require:
- * type
- * editor
- * Provides:
- * editable
+ * Provides editable
*
* @param {AlohaEvent} event
* @return {AlohaEvent}
*/
function handleEditables(event) {
if ('aloha' === event.type) {
- event.editable = create(event.editor, event.element, event.options);
- } else if (event.boundaries) {
- if (Dom.isEditableNode(Boundaries.container(event.boundaries[0]))) {
- event.editable = fromBoundary(event.editor, event.boundaries[0]);
- }
+ event.editable = create(event.editor, event.target, event.options);
+ } else if ('mahalo' === event.type) {
+ event.editable = destroy(event.editor, event.target);
}
return event;
}
diff --git a/src/keys.js b/src/keys.js
index d742f7df6c..8732b8f9d4 100644
--- a/src/keys.js
+++ b/src/keys.js
@@ -88,22 +88,16 @@ define(['strings', 'boundaries'], function (Strings, Boundaries) {
};
/**
- * Requires:
- * type
- * target
- * Provides:
- * meta
- * keycode
+ * Provides meta, keycode
*/
function handleKeys(event) {
- if (event.nativeEvent) {
- event.meta = metaKeys(event.nativeEvent);
- if (EVENTS[event.type]) {
- event.keycode = event.nativeEvent.which;
- if (!event.boundaries) {
- event.boundaries = Boundaries.get(event.target.ownerDocument);
- }
- }
+ if (!event.editable || !event.nativeEvent) {
+ return event;
+ }
+ event.meta = metaKeys(event.nativeEvent);
+ if (EVENTS[event.type]) {
+ event.keycode = event.nativeEvent.which;
+ event.boundaries = Boundaries.get(event.target.ownerDocument);
}
return event;
}
diff --git a/src/links.js b/src/links.js
index cfee7c8b5e..d07c32578f 100644
--- a/src/links.js
+++ b/src/links.js
@@ -228,7 +228,7 @@ define([
}
function handleLinks(event) {
- if (!event.boundaries || 'click' !== event.type) {
+ if (!event.editable || 'click' !== event.type) {
return event;
}
var cac = Boundaries.commonContainer(event.boundaries[0], event.boundaries[1]);
diff --git a/src/mouse.js b/src/mouse.js
index aa5683e3a0..fb2019c1e5 100644
--- a/src/mouse.js
+++ b/src/mouse.js
@@ -25,40 +25,17 @@ define(['boundaries'], function (Boundaries) {
};
/**
- * Requires:
- * type
- * editor
- * Provides:
- * target
- * boundaries
- * Updates:
- * editor.selection
+ * Updates event.editor.selection
*
* @param {AlohaEvent} event
* @return {AlohaEVent}
*/
function handleMouse(event) {
- var nativeEvent = event.nativeEvent;
- if (!nativeEvent) {
+ if (!event.editable || !event.nativeEvent || 'mousedown' !== event.type) {
return event;
}
- event.target = nativeEvent.target;
- if ('mousedown' === event.type) {
- event.editor.selection.formatting = [];
- event.editor.selection.overrides = [];
- }
- if (event.boundaries || !event.target.ownerDocument) {
- return event;
- }
- if ('mousedown' === event.type || 'click' === event.type) {
- event.boundaries = Boundaries.fromPosition(
- nativeEvent.clientX,
- nativeEvent.clientY,
- event.target.ownerDocument
- );
- } else if ('mousemove' !== event.type) {
- event.boundaries = Boundaries.get(event.target.ownerDocument);
- }
+ event.editor.selection.formatting = [];
+ event.editor.selection.overrides = [];
return event;
}
diff --git a/src/paste.js b/src/paste.js
index 99c557047b..f890efd782 100644
--- a/src/paste.js
+++ b/src/paste.js
@@ -58,7 +58,7 @@ define([
*/
function isPasteEvent(event) {
return 'paste' === event.type
- || (event.nativeEvent && event.nativeEvent.clipboardData !== undefined);
+ || (event.nativeEvent && 'undefined' !== typeof event.nativeEvent.clipboardData);
}
/**
@@ -209,7 +209,7 @@ define([
* @return {AlohaEvent}
*/
function handlePaste(event) {
- if (!event.editable || !event.boundaries || !isPasteEvent(event)) {
+ if (!event.editable || !isPasteEvent(event)) {
return event;
}
Events.suppress(event.nativeEvent);
@@ -221,7 +221,7 @@ define([
if (!content) {
return event;
}
- Undo.capture(event.editable['undoContext'], {
+ Undo.capture(event.editable.undoContext, {
meta: {type: 'paste'}
}, function () {
event.boundaries = insert(event.boundaries[0], event.boundaries[1], content);
diff --git a/src/selections.js b/src/selections.js
index e5417dff61..5835b7529e 100644
--- a/src/selections.js
+++ b/src/selections.js
@@ -800,7 +800,7 @@ define([
* @return {AlohaEvent}
*/
function handleSelections(event) {
- if (!handlers[event.type]) {
+ if (!event.editable || !handlers[event.type]) {
return event;
}
diff --git a/src/typing.js b/src/typing.js
index d7e74e2d46..a8ed87f485 100644
--- a/src/typing.js
+++ b/src/typing.js
@@ -366,11 +366,12 @@ define([
* nativeEvent
*/
function handleTyping(event) {
- if (!event.boundaries) {
+ if (!event.editable) {
return event;
}
var start = event.boundaries[0];
var end = event.boundaries[1];
+ /*
if (!event.editable) {
if ('keydown' === event.type) {
if (Dom.isEditableNode(Boundaries.container(start))
@@ -380,6 +381,7 @@ define([
}
return event;
}
+ */
var handling = handler(event);
if (!handling) {
return event;