Skip to content

Commit

Permalink
chore(website): Use plain-js demo (#509)
Browse files Browse the repository at this point in the history
* Move demo site assets into assets/demo
 * Add rudimentary debug tool at assets/demo/debug.html
 * Style/polish demo site
 * Change README to explain how to run demo locally
 * Change npm website build and deploy scripts
  • Loading branch information
bantic committed Nov 3, 2016
1 parent 0271871 commit a6e5805
Show file tree
Hide file tree
Showing 226 changed files with 1,889 additions and 64,560 deletions.
4 changes: 3 additions & 1 deletion Brocfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ var jquery = require('./broccoli/jquery');
var injectLiveReload = require('broccoli-inject-livereload');
var LiveReload = require('tiny-lr');
var replace = require('broccoli-string-replace');
var demoTree = require('./broccoli/demo');

var vendoredModules = [
{name: 'mobiledoc-html-renderer'},
Expand Down Expand Up @@ -58,5 +59,6 @@ module.exports = mergeTrees([
replaceVersion(builder.build('global', buildOptions)),
replaceVersion(builder.build('commonjs', buildOptions)),
styles(),
injectLiveReload(testTree)
injectLiveReload(testTree),
demoTree()
]);
13 changes: 6 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -338,13 +338,12 @@ Tests in CI are run at Travis via Saucelabs (see the `test:ci` npm script).

### Demo

There is a demo app that uses the Mobiledoc kit via the [ember-mobiledoc-editor](https://github.com/bustlelabs/ember-mobiledoc-editor)
in `demo/`. To run the demo:
To run the demo site locally:

* `cd demo/ && npm install && bower install`
* `ember serve` (shut down your broccoli server if it is already running on port 4200)
* visit http://localhost:4200/
* `npm start`
* `open http://localhost:4200/demo`

The assets for the demo are in `assets/demo`.

### Getting Help

Expand All @@ -361,8 +360,8 @@ If you have a question about usage you can post in the [gitter channel](https://

The demo website is hosted at github pages. To publish a new version:

* `npm run build-website` - This builds the website into `website/` and commits it
* `npm run deploy-website` - Pushes the `website/` subtree to the `gh-pages`
* `npm run build:website` - This builds the website into `website/` and commits it
* `npm run deploy:website` - Pushes the `website/` subtree to the `gh-pages`
branch of your `origin` at github

Visit [bustlelabs.github.io/mobiledoc-kit/demo](https://bustlelabs.github.io/mobiledoc-kit/demo).
Expand Down
3 changes: 3 additions & 0 deletions assets/demo/debug.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#toolbar button.active {
font-weight: bold;
}
45 changes: 45 additions & 0 deletions assets/demo/debug.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Mobiledoc Kit Debug</title>
</head>
<body>
<script src="../tests/jquery/jquery.js"></script>
<script src="../global/mobiledoc-kit.js"></script>
<script src="./debug.js"></script>
<link rel="stylesheet" href="../css/mobiledoc-kit.css">
<link rel="stylesheet" href="./debug.css">
</body>

<div id='toolbar'>
<button class='toggle' data-action='toggleSection' data-toggle='h1'>h1</button>
<button class='toggle' data-action='toggleSection' data-toggle='h2'>h2</button>
<button class='toggle' data-action='toggleMarkup' data-toggle='strong'>strong</button>
<button class='toggle' data-action='toggleMarkup' data-toggle='em'>em</button>
<button class='insert-atom' data-name='mention'>@mention</button>
<button class='insert-atom' data-name='click'>@click</button>
<button class='insert-card' data-name='movable'>movable card</button>
</div>

<div id="editor" style='outline: 1px solid black; width: 200px; min-height: 300px;'></div>

<div>
<h3>Cursor</h3>
<div id='cursor'>
</div>
</div>

<div>
<h3>Post</h3>
<div id='post'>
</div>
</div>

<div>
<h3>Input Mode</h3>
<div id='input-mode'>
</div>
</div>

</html>
208 changes: 208 additions & 0 deletions assets/demo/debug.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
/* global Mobiledoc */
'use strict';

var editor;

function renderSection(section) {
return '[' +
'Section: tagName ' + section.tagName +
' type: ' + section.type +
' isNested? ' + section.isNested +
(section.isMarkerable ? (' Markers: ' + section.markers.length + ')') : '') +
']';
}

function renderPosition(pos) {
if (pos.isBlank) {
return '[Blank Position]';
}
return '[Position: ' + pos.leafSectionIndex + ':' + pos.offset + '. Section ' + renderSection(pos.section) + ']';
}

function updateCursor() {
var range = editor.range;

var head = renderPosition(range.head);
var tail = renderPosition(range.tail);
var html = 'Head ' + head + '<br>Tail ' + tail;

$('#cursor').html(html);
}

function renderMarkup(markup) {
function renderAttrs(obj) {
var str = Object.keys(obj).reduce(function (memo, key) {
memo += key + ': ' + obj[key];
return memo;
}, '{');
str += '}';
return str;
}
return '[' + markup.type + ' tagName <b>' + markup.tagName + '</b> attrs: ' + renderAttrs(markup.attributes) + ']';
}

function updatePost() {
var serialized = editor.serialize();
$('#post').html(JSON.stringify(serialized));
}

function updateInputMode() {
var activeMarkups = editor.activeMarkups.map(renderMarkup).join(',');
var activeSections = editor.activeSections.map(renderSection).join(',');
var html = 'Active Markups: ' + activeMarkups + '<br>Active Sections: ' + activeSections;
$('#input-mode').html(html);
}

function updateButtons() {
let activeSectionTagNames = editor.activeSections.map(section => {
return section.tagName;
});
let activeMarkupTagNames = editor.activeMarkups.map(markup => markup.tagName);

$('#toolbar button').each(function() {
let toggle = $(this).data('toggle');

let hasSection = false, hasMarkup = false;
if (activeSectionTagNames.indexOf(toggle) !== -1) {
hasSection = true;
}
if (activeMarkupTagNames.indexOf(toggle) !== -1) {
hasMarkup = true;
}
if (hasSection || hasMarkup) {
$(this).addClass('active');
} else {
$(this).removeClass('active');
}
});
}

let mentionAtom = {
name: 'mention',
type: 'dom',
render({value}) {
let el = $(`<span>@${value}</span>`)[0];
return el;
}
};

let clickAtom = {
name: 'click',
type: 'dom',
render({env, value, payload}) {
let el = document.createElement('button');
let clicks = payload.clicks || 0;
el.appendChild(document.createTextNode('Clicks: ' + clicks));
el.onclick = () => {
payload.clicks = payload.clicks || 0;
payload.clicks++;
env.save(value, payload);
};
return el;
}
};

let tableCard = {
name: 'table',
type: 'dom',
render() {
let [table, tr, td] = ['table','tr','td'].map(tagName => document.createElement(tagName));

table.appendChild(tr);
tr.appendChild(td);
td.appendChild(document.createTextNode("I was created from a pasted table"));

return table;
}
};

function moveCard(section, dir) {
editor.run(postEditor => {
if (dir === 'up') {
postEditor.moveSectionUp(section);
} else {
postEditor.moveSectionDown(section);
}
});
}

let movableCard = {
name: 'movable',
type: 'dom',
render({env, payload}) {
let cardSection = env.postModel;
let text = payload.text || 'new';
let up = $('<button>up</button>').click(() => moveCard(cardSection, 'up'));
let down = $('<button>down</button>').click(() => moveCard(cardSection, 'down'));
let x = $('<button>X</button>').click(env.remove);

let edit = $('<button>edit</button>').click(env.edit);

let el = $('<div>').append([text,up,down,x,edit])[0];
return el;
},
edit({env, payload}) {
let cardSection = env.postModel;
let text = payload.text || 'new';
let up = $('<button>up</button>').click(() => moveCard(cardSection, 'up'));
let down = $('<button>down</button>').click(() => moveCard(cardSection, 'down'));
let x = $('<button>X</button>').click(env.remove);

let input = $('<input>');
let save = $('<button>save</button>').click(() => {
payload.text = input.val();
env.save(payload);
});
let el = $('<div>').append([text, up,down,x,input,save])[0];
return el;
}
};

function speakingPlugin(node, builder, {addSection, addMarkerable, nodeFinished}) {
console.log('got node!',node);
}

function tableConverterPlugin(node, builder, {addSection, addMarkerable, nodeFinished}) {
if (node.tagName !== 'TABLE') { return; }

let tableCard = builder.createCardSection("table");
addSection(tableCard);
nodeFinished();
}

$(function () {
var el = $('#editor')[0];
editor = new Mobiledoc.Editor({
placeholder: 'write something',
autofocus: true,
atoms: [mentionAtom, clickAtom],
parserPlugins: [speakingPlugin, tableConverterPlugin],
cards: [tableCard, movableCard]
});

editor.cursorDidChange(updateCursor);
editor.postDidChange(updatePost);
editor.inputModeDidChange(updateInputMode);

editor.inputModeDidChange(updateButtons);

editor.render(el);

$('#toolbar button.toggle').click(function() {
let action = $(this).data('action');
let toggle = $(this).data('toggle');

editor[action](toggle);
});

$('#toolbar button.insert-atom').click(function() {
let name = $(this).data('name');
let value = $(this).data('value') || '';
editor.insertAtom(name, value);
});

$('#toolbar button.insert-card').click(function() {
let name = $(this).data('name');
editor.insertCard(name);
});
});
Loading

0 comments on commit a6e5805

Please sign in to comment.