Skip to content

Commit

Permalink
Test: displaying toolbar, clicking format butons, creating links
Browse files Browse the repository at this point in the history
 * add `Helpers.dom.triggerKeyEvent` for simulating key events
 * add `Helpers.dom.triggerEvent` for simulating mouse events
 * Add View#destroy, destroy all views when destroying editor
  • Loading branch information
bantic committed Jul 13, 2015
1 parent 710664f commit 9a10d7a
Show file tree
Hide file tree
Showing 16 changed files with 348 additions and 35 deletions.
4 changes: 2 additions & 2 deletions Brocfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ var buildOptions = {
packageName: packageName
};

var jqueryTree = jquery.build('/demo/jquery');
var testTree = testTreeBuilder.build({libDirName: 'src'});
testTree = jquery.build(testTree, '/tests/jquery');
var demoTree = demo();
demoTree = mergeTrees([demoTree, jqueryTree]);
demoTree = jquery.build(demoTree, '/demo/jquery');

module.exports = mergeTrees([
builder.build('amd', buildOptions),
Expand Down
13 changes: 9 additions & 4 deletions broccoli/jquery.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
/* jshint node:true */
var funnel = require('broccoli-funnel');
var mergeTrees = require('broccoli-merge-trees');

module.exports = {
build: function(destDir) {
/**
* @param {Tree} tree existing tree to mix jquery into
* @param {String} destDir the destination directory for 'jquery.js' to go into
* @return {Tree} A tree with jquery mixed into it at the location requested
*/
build: function(tree, destDir) {
var path = require('path');
var jqueryPath = path.dirname(
require.resolve('jquery')
);
var tree = funnel(jqueryPath, {
var jqueryTree = funnel(jqueryPath, {
include: ['jquery.js'],
destDir: destDir
});

return tree;
return mergeTrees([tree, jqueryTree]);
}
};
4 changes: 3 additions & 1 deletion src/js/commands/card.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
import Command from './base';
import { inherit } from 'content-kit-utils';

function injectCardBlock(cardName, cardPayload, editor, index) {
function injectCardBlock(/* cardName, cardPayload, editor, index */) {
throw new Error('Unimplemented: BlockModel and Type.CARD are no longer things');
// FIXME: Do we change the block model internal representation here?
/*
var cardBlock = BlockModel.createWithType(Type.CARD, {
attributes: {
name: cardName,
payload: cardPayload
}
});
editor.replaceBlock(cardBlock, index);
*/
}

function CardCommand() {
Expand Down
4 changes: 3 additions & 1 deletion src/js/commands/format-block.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ FormatBlockCommand.prototype.exec = function() {
// Allow block commands to be toggled back to a text block
if(tag === blockElement.tagName.toLowerCase()) {
throw new Error('Unimplemented: Type.BOLD.paragraph must be replaced');
/*
value = Type.PARAGRAPH.tag;
*/
} else {
// Flattens the selection before applying the block format.
// Otherwise, undesirable nested blocks can occur.
Expand All @@ -27,7 +29,7 @@ FormatBlockCommand.prototype.exec = function() {
blockElement.parentNode.removeChild(blockElement);
selectNode(flatNode);
}

FormatBlockCommand._super.prototype.exec.call(this, value);
};

Expand Down
4 changes: 3 additions & 1 deletion src/js/commands/image.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,12 @@ function createFileInput(command) {
return fileInput;
}

function injectImageBlock(src, editor, index) {
function injectImageBlock(/* src, editor, index */) {
throw new Error('Unimplemented: BlockModel and Type.IMAGE are no longer things');
/*
var imageModel = BlockModel.createWithType(Type.IMAGE, { attributes: { src: src } });
editor.replaceBlock(imageModel, index);
*/
}

function renderFromFile(file, editor, index) {
Expand Down
8 changes: 6 additions & 2 deletions src/js/commands/oembed.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import Message from '../views/message';
import { inherit } from 'content-kit-utils';
import { OEmbedder } from '../utils/http-utils';

/*
function loadTwitterWidgets(element) {
if (window.twttr) {
window.twttr.widgets.load(element);
Expand All @@ -14,6 +15,7 @@ function loadTwitterWidgets(element) {
document.head.appendChild(script);
}
}
*/

function OEmbedCommand(options) {
Command.call(this, {
Expand All @@ -31,9 +33,9 @@ inherit(OEmbedCommand, Command);

OEmbedCommand.prototype.exec = function(url) {
var command = this;
var editorContext = command.editorContext;
// var editorContext = command.editorContext;
var embedIntent = command.embedIntent;
var index = editorContext.getCurrentBlockIndex();
// var index = editorContext.getCurrentBlockIndex();

embedIntent.showLoading();
this.embedService.fetch({
Expand All @@ -54,12 +56,14 @@ OEmbedCommand.prototype.exec = function(url) {
embedIntent.show();
} else {
throw new Error('Unimplemented EmbedModel is not a thing');
/*
var embedModel = new EmbedModel(response);
editorContext.insertBlock(embedModel, index);
editorContext.renderBlockAt(index);
if (embedModel.attributes.provider_name.toLowerCase() === 'twitter') {
loadTwitterWidgets(editorContext.element);
}
*/
}
}
});
Expand Down
32 changes: 24 additions & 8 deletions src/js/editor/editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,14 +124,15 @@ function bindDragAndDrop(editor) {
function initEmbedCommands(editor) {
var commands = editor.embedCommands;
if(commands) {
return new EmbedIntent({
editor.addView(new EmbedIntent({
editorContext: editor,
commands: commands,
rootElement: editor.element
});
}));
}
}

/* unused
function getNonTextBlocks(blockTypeSet, post) {
var blocks = [];
var len = post.length;
Expand All @@ -145,6 +146,7 @@ function getNonTextBlocks(blockTypeSet, post) {
}
return blocks;
}
*/

function clearChildNodes(element) {
while (element.childNodes.length) {
Expand All @@ -165,12 +167,13 @@ function Editor(element, options) {
}

this._elementListeners = [];
this._views = [];
this.element = element;

// FIXME: This should merge onto this.options
mergeWithOptions(this, defaults, options);

this._renderer = new EditorDOMRenderer(window.document, this.cards)
this._renderer = new EditorDOMRenderer(window.document, this.cards);
this._parser = new DOMParser();

this.applyClassName();
Expand All @@ -196,16 +199,16 @@ function Editor(element, options) {
this.addEventListener(element, 'input', () => this.handleInput(...arguments));
initEmbedCommands(this);

this.textFormatToolbar = new TextFormatToolbar({
this.addView(new TextFormatToolbar({
rootElement: element,
commands: this.textFormatCommands,
sticky: this.stickyToolbar
});
}));

this.linkTooltips = new Tooltip({
this.addView(new Tooltip({
rootElement: element,
showForTag: 'a'
});
}));

if (this.autofocus) {
element.focus();
Expand All @@ -216,6 +219,9 @@ function Editor(element, options) {
merge(Editor.prototype, EventEmitter);

merge(Editor.prototype, {
addView(view) {
this._views.push(view);
},

addEventListener(context, eventName, callback) {
context.addEventListener(eventName, callback);
Expand Down Expand Up @@ -271,8 +277,9 @@ merge(Editor.prototype, {
this.trigger('update');
},

renderBlockAt(index, replace) {
renderBlockAt(/* index, replace */) {
throw new Error('Unimplemented');
/*
var modelAtIndex = this.post[index];
var html = this.compiler.render([modelAtIndex]);
var dom = document.createElement('div');
Expand All @@ -285,10 +292,12 @@ merge(Editor.prototype, {
} else {
this.element.insertBefore(newEl, sibling);
}
*/
},

syncContentEditableBlocks() {
throw new Error('Unimplemented');
/*
var nonTextBlocks = getNonTextBlocks(this.compiler.blockTypes, this.post);
var blockElements = toArray(this.element.children);
var len = blockElements.length;
Expand All @@ -309,6 +318,7 @@ merge(Editor.prototype, {
}
this.post = updatedModel;
this.trigger('update');
*/
},

applyClassName() {
Expand Down Expand Up @@ -426,8 +436,14 @@ merge(Editor.prototype, {
});
},

removeAllViews() {
this._views.forEach((v) => v.destroy());
this._views = [];
},

destroy() {
this.removeAllEventListeners();
this.removeAllViews();
}

});
Expand Down
4 changes: 4 additions & 0 deletions src/js/views/view.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ View.prototype = {
setClasses: function(classNameArr) {
this.classNames = classNameArr;
renderClasses(this);
},
destroy() {
// FIXME should also clean up event listeners
this.hide();
}
};

Expand Down
4 changes: 2 additions & 2 deletions tests/acceptance/basic-editor-test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* global QUnit */

import { Editor } from 'content-kit-editor';
import { moveCursorTo } from '../test-helpers';
import Helpers from '../test-helpers';

const { test, module } = QUnit;

Expand Down Expand Up @@ -38,7 +38,7 @@ test('editing element changes editor post model', (assert) => {
let p = editorElement.querySelector('p');
let textElement = p.firstChild;

moveCursorTo(textElement, 0);
Helpers.dom.moveCursorTo(textElement, 0);

document.execCommand('insertText', false, 'A');
assert.equal(p.textContent, 'AHello');
Expand Down
115 changes: 115 additions & 0 deletions tests/acceptance/editor-commands-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import { Editor } from 'content-kit-editor';
import Helpers from '../test-helpers';

const { test, module } = QUnit;

let fixture, editor, editorElement, selectedText;

module('Acceptance: Editor commands', {
beforeEach() {
fixture = document.getElementById('qunit-fixture');
editorElement = document.createElement('div');
editorElement.setAttribute('id', 'editor');
editorElement.innerHTML = 'THIS IS A TEST';
fixture.appendChild(editorElement);
editor = new Editor(editorElement);

selectedText = 'IS A';
Helpers.dom.selectText(selectedText, editorElement);
Helpers.dom.triggerEvent(document, 'mouseup');
},

afterEach() {
editor.destroy();
}
});

function clickToolbarButton(name, assert) {
let btnSelector = `.ck-toolbar-btn[title="${name}"]`;
let button = assert.hasElement(btnSelector);

Helpers.dom.triggerEvent(button[0], 'mouseup');
}

test('when text is highlighted, shows toolbar', (assert) => {
let done = assert.async();

setTimeout(() => {
assert.hasElement('.ck-toolbar', 'displays toolbar');
assert.hasElement('.ck-toolbar-btn', 'displays toolbar buttons');
let boldBtnSelector = '.ck-toolbar-btn[title="bold"]';
assert.hasElement(boldBtnSelector, 'has bold button');
done();
}, 10);
});

test('highlight text, click "bold" button bolds text', (assert) => {
let done = assert.async();

setTimeout(() => {
clickToolbarButton('bold', assert);
assert.hasElement('#editor b:contains(IS A)');

done();
}, 10);
});

test('highlight text, click "italic" button italicizes text', (assert) => {
let done = assert.async();

setTimeout(() => {
clickToolbarButton('italic', assert);
assert.hasElement('#editor i:contains(IS A)');

done();
}, 10);
});

test('highlight text, click "heading" button turns text into h2 header', (assert) => {
let done = assert.async();

setTimeout(() => {
clickToolbarButton('heading', assert);
assert.hasElement('#editor h2:contains(THIS IS A TEST)');

done();
}, 10);
});

test('highlight text, click "subheading" button turns text into h3 header', (assert) => {
let done = assert.async();

setTimeout(() => {
clickToolbarButton('subheading', assert);
assert.hasElement('#editor h3:contains(THIS IS A TEST)');

done();
}, 10);
});

test('highlight text, click "quote" button turns text into blockquote', (assert) => {
let done = assert.async();

setTimeout(() => {
clickToolbarButton('quote', assert);
assert.hasElement('#editor blockquote:contains(THIS IS A TEST)');

done();
}, 10);
});

test('highlight text, click "link" button shows input for URL, makes link', (assert) => {
let done = assert.async();

setTimeout(() => {
clickToolbarButton('link', assert);
let input = assert.hasElement('.ck-toolbar-prompt input');
let url = 'http://google.com';
$(input).val(url);
Helpers.dom.triggerKeyEvent(input[0], 'keyup');

assert.hasElement(`#editor a[href="${url}"]:contains(${selectedText})`);

done();
}, 10);
});
Loading

0 comments on commit 9a10d7a

Please sign in to comment.