Skip to content
This repository has been archived by the owner on May 22, 2018. It is now read-only.

Server side capability via jsdom #2

Merged
merged 10 commits into from
Apr 13, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ The following options are supported for configuring a format (adapted from Quill

`style: 'fontSize'` -- set an inline style using the given name and the value from the delta

`add: function(node, value)` -- a hook for custom behavior, runs after logic for other options. e.g.
`add: function(node, value[, dom])` -- a hook for custom behavior, runs after logic for other options. e.g.

```javascript
convert(delta, {
Expand Down
6 changes: 6 additions & 0 deletions browser.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
var convert = require('./lib/convert');

module.exports = function(delta, formats, options) {
options.document = document;
return convert(delta, formats, options);
};
11 changes: 5 additions & 6 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
var Doc = require('./lib/doc');
var jsdom = require('jsdom').jsdom;
var convert = require('./lib/convert');

module.exports = function(delta, formats, options) {
var doc = new Doc(formats, options);
for (var i = 0; i < delta.ops.length; i++) {
doc.writeOp(delta.ops[i]);
}
return doc.getHTML();
options.document = jsdom();
return convert(delta, formats, options);
};

24 changes: 24 additions & 0 deletions karma.conf.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
var webpackConfig = require('./webpack.conf');

module.exports = function(config) {
config.set({
basePath: '',
browsers: ['PhantomJS'],
frameworks: ['mocha', 'chai', 'phantomjs-shim'],
plugins: [
'karma-phantomjs-shim',
'karma-phantomjs-launcher',
'karma-webpack',
'karma-mocha',
'karma-chai'
],
files: ['test/client/*.js'],
preprocessors: {
'test/client/*.js': ['webpack']
},
reporters: ['dots'],
webpack: webpackConfig,
webpackMiddleware: { noInfo: true },
singleRun: true
});
}
9 changes: 9 additions & 0 deletions lib/convert.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
var Doc = require('./doc');

module.exports = function(delta, formats, options) {
var doc = new Doc(formats, options);
for (var i = 0; i < delta.ops.length; i++) {
doc.writeOp(delta.ops[i]);
}
return doc.getHTML();
};
19 changes: 13 additions & 6 deletions lib/doc.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ module.exports = Doc;

function Doc(formats, options) {
this.formats = formats;
this.document = options.document;
this.blockTag = options && options.blockTag || 'div';
this.inlineTag = options && options.inlineTag || 'span';
this.root = document.createElement('div');
this.root = this.document.createElement('div');
}

Doc.prototype.getHTML = function() {
Expand Down Expand Up @@ -40,13 +41,13 @@ Doc.prototype.writeOp = function(op) {

Doc.prototype.writeText = function(text, attrs) {
if (!this.line) {
this.line = document.createElement(this.blockTag);
this.line = this.document.createElement(this.blockTag);
this.root.appendChild(this.line);
}

if (!text.length) { return }

var node = document.createTextNode(text);
var node = this.document.createTextNode(text);

this.line.appendChild(node);

Expand All @@ -70,7 +71,7 @@ Doc.prototype.applyFormat = function(node, format, value) {
node = dom(node).switchTag(format.tag).get();
} else {
if (dom.VOID_TAGS[format.tag]) {
node = dom(node).replaceWith(document.createElement(format.tag)).get();
node = dom(node).replaceWith(this.document.createElement(format.tag)).get();
} else {
node = dom(node).wrap(format.tag).get();
}
Expand All @@ -95,15 +96,21 @@ Doc.prototype.applyFormat = function(node, format, value) {
node.setAttribute(format.attribute, value);
}
if (format.class) {
node.classList.add(format.class + value);
if (typeof node.classList === 'undefined') {
var newClass = format.class + value;
var className = node.className;
node.className = className.length ? (className + ' ' + newClass) : (className + newClass);
} else {
node.classList.add(format.class + value);
}
}
if (format.style && value !== format.default) {
node.style[format.style] = value;
}
}

if (typeof format.add === 'function') {
node = format.add(node, value);
node = format.add(node, value, dom);
}

return node;
Expand Down
5 changes: 3 additions & 2 deletions lib/dom.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ var dom = module.exports = function(node) {
}

this.node = node;
this.document = node.ownerDocument;
};

dom.ELEMENT_NODE = 1;
Expand Down Expand Up @@ -120,7 +121,7 @@ dom.prototype.replaceWith = function(newNode) {
dom.prototype.switchTag = function(newTag) {
newTag = newTag.toUpperCase();
if (this.node.tagName === newTag) { return this.node; }
var newNode = document.createElement(newTag);
var newNode = this.document.createElement(newTag);
var attributes = this.attributes();
if (!dom.VOID_TAGS[newTag]) { this.moveChildren(newNode); }
this.replaceWith(newNode);
Expand Down Expand Up @@ -161,7 +162,7 @@ dom.prototype.text = function(text) {
};

dom.prototype.wrap = function(tag) {
var wrapper = document.createElement(tag);
var wrapper = this.document.createElement(tag);
if (this.node.parentNode) {
this.node.parentNode.insertBefore(wrapper, this.node);
}
Expand Down
18 changes: 15 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
"version": "1.2.1",
"description": "Convert an insert-only rich-text delta into HTML",
"main": "index.js",
"browser": "browser.js",
"scripts": {
"info": "make info",
"lint": "make lint",
"start": "make start",
"test": "make test"
"test": "NODE_ENV=test karma start && mocha test/server/server.js -R spec"
},
"repository": {
"type": "git",
Expand All @@ -26,13 +27,24 @@
"url": "https://github.com/thomsbg/convert-rich-text/issues"
},
"homepage": "https://github.com/thomsbg/convert-rich-text",
"dependencies": {},
"dependencies": {
"jsdom": "^3.1.2"
},
"devDependencies": {
"browserify": "^9.0.8",
"chai": "^2.2.0",
"http-server": "^0.8.0",
"jshint": "^2.7.0",
"karma": "^0.13.22",
"karma-chai": "^0.1.0",
"karma-mocha": "^0.2.2",
"karma-phantomjs-launcher": "^1.0.0",
"karma-phantomjs-shim": "^1.2.0",
"karma-source-map-support": "^1.1.0",
"karma-webpack": "^1.7.0",
"mocha-phantomjs": "^3.5.3",
"watchify": "^3.2.0"
"phantomjs-prebuilt": "^2.1.7",
"watchify": "^3.2.0",
"webpack": "^1.12.15"
}
}
31 changes: 31 additions & 0 deletions test/client/client.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
var assert = require('chai').assert;
var convert = require('../../browser');

var data = require('../data');
var formats = data.formats;
var tests = data.tests;

function runTest(test) {
it(test.desc, function(done) {
if (!test.hasOwnProperty('opts')) {
test.opts = {};
}
var result = convert(test.delta, formats, test.opts);
if (typeof test.expected === 'object') {
assert.equal(result, test.expected.client);
} else {
assert.equal(result, test.expected);
}
done();
});
}

describe('client-side', function() {
tests.forEach(runTest);

it('throws an error for a delta with non-inserts', function() {
assert.throws(function() {
convert({ ops: [{ insert: 'abc' }, { retain: 3 }] }, formats, {});
}, 'Cannot convert delta with non-insert operations');
});
});
41 changes: 15 additions & 26 deletions test/test.js → test/data.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
var assert = require('chai').assert;
var convert = require('convert-rich-text');
var dom = require('../lib/dom');
var formats = {
exports.formats = {
bold: { tag: 'B' },
color: { style: 'color' },
user: { class: 'user-' },
Expand All @@ -11,31 +8,34 @@ var formats = {
className: { attribute: 'class' },
bullet: { type: 'line', tag: 'LI', parentTag: 'UL' },
list: { type: 'line', tag: 'LI', parentTag: 'OL' },
reverse: { add: function(node) {
var newNode = document.createTextNode(node.textContent.split('').reverse().join(''));
reverse: { add: function(node, value, dom) {
var doc = dom(node).document;
var newNode = doc.createTextNode(node.textContent.split('').reverse().join(''));
node.parentNode.replaceChild(newNode, node);
return newNode;
} },
repeat: { add: function(node, value) {
var frag = document.createDocumentFragment();
repeat: { add: function(node, value, dom) {
var doc = dom(node).document;
var frag = doc.createDocumentFragment();
for (var i = 0, n = parseInt(value); i < n; i++) {
frag.appendChild(node.cloneNode(true));
}
node.parentNode.replaceChild(frag, node);
return frag;
} },
parent: { add: function(node, value) {
parent: { add: function(node, value, dom) {
dom(node.parentNode).switchTag(value);
return node;
} },
data: { type: 'line', add: function(node, value) {
Object.keys(value).forEach(function(key) {
node.dataset[key] = value[key];
node.setAttribute('data-' + key, value[key]);
});
return node;
} }
};
var tests = [

exports.tests = [
{
desc: 'No formats',
delta: { ops: [
Expand Down Expand Up @@ -80,8 +80,10 @@ var tests = [
{insert: 'Hello world', attributes: { color: 'red', user: 1234 }},
{insert: '\n'}
]},
expected:
'<div><span style="color: red; " class="user-1234">Hello world</span></div>'
expected: {
client: '<div><span class="user-1234" style="color: red;">Hello world</span></div>',
server: '<div><span style="color: red;" class="user-1234">Hello world</span></div>'
}
},
{
desc: 'attribute with implicit span tag',
Expand Down Expand Up @@ -165,16 +167,3 @@ var tests = [
expected: '<h1></h1>'
}
];

tests.forEach(function(test) {
it(test.desc, function() {
var result = convert(test.delta, formats, test.opts);
assert.equal(result, test.expected);
});
});

it('throws an error for a delta with non-inserts', function() {
assert.throws(function() {
convert({ ops: [{ insert: 'abc' }, { retain: 3 }] }, formats);
}, 'Cannot convert delta with non-insert operations');
});
26 changes: 0 additions & 26 deletions test/index.html

This file was deleted.

29 changes: 29 additions & 0 deletions test/server/server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
var assert = require('chai').assert;
var convert = require('../../index');

var data = require('../data');
var formats = data.formats;
var tests = data.tests;

describe('server-side', function() {
tests.forEach(function(test) {
it(test.desc, function(done) {
if (!test.hasOwnProperty('opts')) {
test.opts = {};
}
var result = convert(test.delta, formats, test.opts);
if (typeof test.expected === 'object') {
assert.equal(result, test.expected.server);
} else {
assert.equal(result, test.expected);
}
done();
});
});

it('throws an error for a delta with non-inserts', function() {
assert.throws(function() {
convert({ ops: [{ insert: 'abc' }, { retain: 3 }] }, formats, {});
}, 'Cannot convert delta with non-insert operations');
});
});
11 changes: 11 additions & 0 deletions webpack.conf.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
var webpack = require('webpack');

module.exports = {
progress: false,
output: {
path: __dirname + '/build',
publicPath: '/js/',
filename: 'bundle.js'
},
devtool: 'source-map',
};