Commit d929e37b authored by Jeffery's avatar Jeffery
Browse files

init

parents
{
"presets": [
"env"
]
}
\ No newline at end of file
node_modules
src
test
.travis.yml
.gitignore
.babelrc
language: node_js
node_js:
- stable
MIT License
Copyright (c) 2016 Ray Di Ciaccio
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# snabbdom-virtualize [![Build Status](https://travis-ci.org/appcues/snabbdom-virtualize.svg?branch=master)](https://travis-ci.org/appcues/snabbdom-virtualize)
Library for turning strings and DOM nodes into virtual DOM nodes compatible with [Snabbdom](https://github.com/paldepind/snabbdom).
## API
### `virtualize(nodes, options)`
* `nodes: Element|String` - Either a DOM `Element` or a string of HTML to turn into a set of virtual DOM nodes.
* `options: Object` - A hash of options to pass into the virtualize call. Available options are currently:
* `context: Document` - An alternative DOM document to use (default is `window.document`).
* `hooks: Object` - An object specifying hooks to call during the virtualization process. See the [hooks](#hooks) section below.
## Usage
Add it to your application with
```
npm install --save snabbdom-virtualize
```
Require/import it.
```javascript
// ES6
import virtualize from 'snabbdom-virtualize';
// Require.
let virtualize = require('snabbdom-virtualize').default;
```
Pass it a set of DOM nodes or a string representing DOM nodes with one root node.
```javascript
// Actual DOM nodes
let topNode = document.createElement('div');
let textNode = document.createTextNode('Click ');
let linkNode = document.createElement('a');
linkNode.setAttribute('href', 'http://example.com');
linkNode.textContent = 'here';
topNode.appendChild(textNode);
topNode.appendChild(linkNode);
let vnode = virtualize(topNode);
// String
let vnode = virtualize('<div>Click <a href="http://example.com">here</a></div>');
```
#### Specifying a different document
You can specify a different DOM document (other than the default `window.document` in a browser) by passing a `context` option into your calls to `virtualize`. This will allow for usage in a server-side setting, where there is no browser. One option is to use `jsdom` to create a DOM document that can be used:
```javascript
const virtualize = require('snabbdom-virtualize').default;
const jsdom = require('jsdom').jsdom;
virtualizeString('<div>Click <a href="http://example.com">here</a></div>', {
context: jsdom('<html></html>')
});
```
#### Using modules à la carte
If you'd prefer to import just the function for virtualizing DOM nodes or just
the function for virtualizing HTML strings, you're in luck. Just import
`snabbdom-virtualize/nodes` or `snabbdom-virtualize/strings` and use in the
same way:
```javascript
// DOM nodes.
import virtualize from 'snabbdom-virtualize/nodes';
let topNode = document.createElement('div');
let textNode = document.createTextNode('Click ');
let linkNode = document.createElement('a');
linkNode.setAttribute('href', 'http://example.com');
linkNode.textContent = 'here';
topNode.appendChild(textNode);
topNode.appendChild(linkNode);
let vnode = virtualize(topNode);
// HTML strings.
import virtualize from 'snabbdom-virtualize/strings';
let vnode = virtualize('<div>Click <a href="http://example.com">here</a></div>');
```
#### Hooks
You can register a `create` hook with any of the `virtualize` functions. This will be called once for each vnode that was created. It's called after the virtualization process is completed. The function receives one argument - the `VNode` that was created.
```javascript
// The function passed as the 'create' hook is called 3 times: once for the
// <div>, once for the <span> and once for the text node inside the <span>.
virtualize("<div><span>Hi!</span></div>", {
hooks: {
create: function(vnode) { ... }
}
});
```
Hooks allow you to perform some operations on your VNodes after virtualization but before patching with snabbdom.
### Project setup
Written in ES6, compiled using Babel. To get started:
```
npm install
npm run build
```
This will output compiled files in the `lib` directory.
### Tests
Tests can be run with `npm test`.
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
// List from https://html.spec.whatwg.org/multipage/webappapis.html#globaleventhandlers.
exports.default = ['onabort', 'onautocomplete', 'onautocompleteerror', 'onblur', 'oncancel', 'oncanplay', 'oncanplaythrough', 'onchange', 'onclick', 'onclose', 'oncontextmenu', 'oncuechange', 'ondblclick', 'ondrag', 'ondragend', 'ondragenter', 'ondragexit', 'ondragleave', 'ondragover', 'ondragstart', 'ondrop', 'ondurationchange', 'onemptied', 'onended', 'onerror', 'onfocus', 'oninput', 'oninvalid', 'onkeydown', 'onkeypress', 'onkeyup', 'onload', 'onloadeddata', 'onloadedmetadata', 'onloadstart', 'onmousedown', 'onmouseenter', 'onmouseleave', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'onwheel', 'onpause', 'onplay', 'onplaying', 'onprogress', 'onratechange', 'onreset', 'onresize', 'onscroll', 'onseeked', 'onseeking', 'onselect', 'onshow', 'onstalled', 'onsubmit', 'onsuspend', 'ontimeupdate', 'ontoggle', 'onvolumechange', 'onwaiting'];
\ No newline at end of file
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.virtualizeString = exports.virtualizeNode = undefined;
exports.default = function (el, options) {
if (typeof el === 'string') {
return (0, _strings2.default)(el, options);
} else {
return (0, _nodes2.default)(el, options);
}
};
var _nodes = require('./nodes');
var _nodes2 = _interopRequireDefault(_nodes);
var _strings = require('./strings');
var _strings2 = _interopRequireDefault(_strings);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
exports.virtualizeNode = _nodes2.default;
exports.virtualizeString = _strings2.default;
\ No newline at end of file
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = virtualizeNodes;
var _h = require('snabbdom/h');
var _h2 = _interopRequireDefault(_h);
var _utils = require('./utils');
var _eventListeners = require('./event-listeners');
var _eventListeners2 = _interopRequireDefault(_eventListeners);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function virtualizeNodes(element) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var context = options.context || document;
if (!element) {
return null;
}
var createdVNodes = [];
var vnode = convertNode(element, createdVNodes, context);
options.hooks && options.hooks.create && createdVNodes.forEach(function (node) {
options.hooks.create(node);
});
return vnode;
}
function convertNode(element, createdVNodes, context) {
// If our node is a text node, then we only want to set the `text` part of
// the VNode.
if (element.nodeType === context.defaultView.Node.TEXT_NODE) {
var _newNode = (0, _utils.createTextVNode)(element.textContent, context);
_newNode.elm = element;
createdVNodes.push(_newNode);
return _newNode;
}
// If not a text node, then build up a VNode based on the element's tag
// name, class and style attributes, and remaining attributes.
// Special values: style, class. We don't include these in the attrs hash
// of the VNode.
var data = {};
var classes = getClasses(element);
if (Object.keys(classes).length !== 0) {
data.class = classes;
}
var style = getStyle(element);
if (Object.keys(style).length !== 0) {
data.style = style;
}
// Build up set of attributes on the element.
var attributes = element.attributes;
for (var _i = 0; _i < attributes.length; _i++) {
var attr = attributes.item(_i);
var name = attr.name;
if (name !== 'style' && name !== 'class') {
if (!data.attrs) {
data.attrs = {};
}
data.attrs[name] = attr.value;
}
}
// Check for event listeners.
var on = {};
_eventListeners2.default.forEach(function (key) {
if (element[key]) {
on[key.substring(2)] = element[key];
}
});
if (Object.keys(on).length > 0) {
data.on = on;
}
// Build up set of children.
var childNodes = null;
var children = element.childNodes;
if (children.length > 0) {
childNodes = [];
for (var i = 0; i < children.length; i++) {
childNodes.push(convertNode(children.item(i), createdVNodes, context));
}
}
var newNode = (0, _h2.default)(element.tagName.toLowerCase(), data, childNodes);
newNode.elm = element;
createdVNodes.push(newNode);
return newNode;
}
// Builds the class object for the VNode.
function getClasses(element) {
var className = element.className;
var classes = {};
if (className !== null && className.length > 0) {
className.split(' ').forEach(function (className) {
if (className.trim().length) {
classes[className.trim()] = true;
}
});
}
return classes;
}
// Builds the style object for the VNode.
function getStyle(element) {
var style = element.style;
var styles = {};
for (var i = 0; i < style.length; i++) {
var name = style.item(i);
var transformedName = (0, _utils.transformName)(name);
styles[transformedName] = style.getPropertyValue(name);
}
return styles;
}
\ No newline at end of file
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = function (html) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var context = options.context || document;
// If there's nothing here, return null;
if (!html) {
return null;
}
// Maintain a list of created vnodes so we can call the create hook.
var createdVNodes = [];
// Parse the string into the AST and convert to VNodes.
var vnodes = convertNodes(parseHTML(html), createdVNodes, context);
var res = void 0;
if (!vnodes) {
// If there are no vnodes but there is string content, then the string
// must be just text or at least invalid HTML that we should treat as
// text (since the AST parser didn't find any well-formed HTML).
res = toVNode({
type: 'text',
content: html
}, createdVNodes, context);
} else if (vnodes.length === 1) {
// If there's only one root node, just return it as opposed to an array.
res = vnodes[0];
} else {
// Otherwise we have an array of VNodes, which we should return.
res = vnodes;
}
// Call the 'create' hook for each created node.
options.hooks && options.hooks.create && createdVNodes.forEach(function (node) {
options.hooks.create(node);
});
return res;
};
var _htmlparser = require('htmlparser2');
var _htmlparser2 = _interopRequireDefault(_htmlparser);
var _h = require('snabbdom/h');
var _h2 = _interopRequireDefault(_h);
var _utils = require('./utils');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
var parseHTML = function parseHTML(html) {
var handler = new _htmlparser2.default.DomHandler();
var parser = new _htmlparser2.default.Parser(handler, {
lowerCaseAttributeNames: false
});
parser.parseComplete(html);
return handler.dom;
};
function convertNodes(nodes, createdVNodes, context) {
if (nodes instanceof Array && nodes.length > 0) {
var convertedNodes = [];
nodes.forEach(function (node) {
if (node.type !== 'comment') {
convertedNodes.push(toVNode(node, createdVNodes, context));
}
});
return convertedNodes;
} else {
return undefined;
}
}
function toVNode(node, createdVNodes, context) {
var newNode = void 0;
if (node.type === 'text') {
newNode = (0, _utils.createTextVNode)(node.data, context);
} else {
newNode = (0, _h2.default)(node.name, buildVNodeData(node, context), convertNodes(node.children, createdVNodes, context));
}
createdVNodes.push(newNode);
return newNode;
}
function buildVNodeData(node, context) {
var data = {};
if (!node.attribs) {
return data;
}
var attrs = Object.keys(node.attribs).reduce(function (memo, name) {
if (name !== 'style' && name !== 'class') {
var val = (0, _utils.unescapeEntities)(node.attribs[name], context);
memo ? memo[name] = val : memo = _defineProperty({}, name, val);
}
return memo;
}, null);
if (attrs) {
data.attrs = attrs;
}
var style = parseStyle(node);
if (style) {
data.style = style;
}
var classes = parseClass(node);
if (classes) {
data.class = classes;
}
return data;
}
function parseStyle(node) {
try {
return node.attribs.style.split(';').reduce(function (memo, styleProp) {
var res = styleProp.split(':');
var name = (0, _utils.transformName)(res[0].trim());
if (name) {
var val = res[1].replace('!important', '').trim();
memo ? memo[name] = val : memo = _defineProperty({}, name, val);
}
return memo;
}, null);
} catch (e) {
return null;
}
}
function parseClass(node) {
try {
return node.attribs.class.split(' ').reduce(function (memo, className) {
className = className.trim();
if (className) {
memo ? memo[className] = true : memo = _defineProperty({}, className, true);
}
return memo;
}, null);
} catch (e) {
return null;
}
}
\ No newline at end of file
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.createTextVNode = createTextVNode;
exports.transformName = transformName;
exports.unescapeEntities = unescapeEntities;
var _vnode = require('snabbdom/vnode');
var _vnode2 = _interopRequireDefault(_vnode);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function createTextVNode(text, context) {
return (0, _vnode2.default)(undefined, undefined, undefined, unescapeEntities(text, context));
}
function transformName(name) {
// Replace -a with A to help camel case style property names.
name = name.replace(/-(\w)/g, function _replace($1, $2) {
return $2.toUpperCase();
});
// Handle properties that start with a -.
var firstChar = name.charAt(0).toLowerCase();
return '' + firstChar + name.substring(1);
}
// Regex for matching HTML entities.
var entityRegex = new RegExp('&[a-z0-9#]+;', 'gi');
// Element for setting innerHTML for transforming entities.
var el = null;
function unescapeEntities(text, context) {
// Create the element using the context if it doesn't exist.
if (!el) {
el = context.createElement('div');
}
return text.replace(entityRegex, function (entity) {
el.innerHTML = entity;
return el.textContent;
});
}
\ No newline at end of file
module.exports = require('./lib/nodes');
{
"name": "snabbdom-virtualize",
"version": "0.7.0",
"description": "Library for turning strings and DOM nodes into virtual DOM nodes compatible with snabbdom.",
"author": {
"name": "Ray Di Ciaccio",
"email": "ray@appcues.com"
},
"license": "MIT",
"bugs": "https://github.com/appcues/snabbdom-virtualize/issues",
"repository": {
"type": "git",
"url": "https://github.com/appcues/snabbdom-virtualize.git"
},
"scripts": {
"prepublish": "npm run build",
"build": "babel src -d lib",
"watch": "npm run build -- --watch",
"test": "npm run build && mocha test/nodejs_tests.js && karma start test/karma.conf.js"
},
"main": "lib/index.js",
"devDependencies": {
"babel-cli": "^6.26.0",
"babel-core": "^6.22.1",
"babel-loader": "^7.1.5",
"babel-preset-env": "^1.3.2",
"chai": "^4.1.2",
"jsdom": "^9.4.2",
"karma": "^1.4.1",
"karma-chai": "^0.1.0",
"karma-chai-sinon": "^0.1.5",
"karma-chrome-launcher": "^0.2.2",
"karma-coverage": "^1.1.1",
"karma-firefox-launcher": "^0.1.7",
"karma-mocha": "^1.3.0",
"karma-sauce-launcher": "^0.3.0",
"karma-sinon": "^1.0.5",
"karma-sourcemap-loader": "^0.3.7",
"karma-spec-reporter": "0.0.31",
"karma-webpack": "^2.0.2",
"mocha": "^3.2.0",
"sinon": "^6.1.4",
"sinon-chai": "^3.2.0",
"snabbdom": "~0.7.1",
"socket.io": "^2.1.1",
"webpack": "^3.6.0"
},
"peerDependencies": {
"snabbdom": "~0.7.1"
},
"dependencies": {
"htmlparser2": "3.9.2"
}
}
\ No newline at end of file
// List from https://html.spec.whatwg.org/multipage/webappapis.html#globaleventhandlers.
export default [
'onabort',
'onautocomplete',
'onautocompleteerror',
'onblur',
'oncancel',
'oncanplay',
'oncanplaythrough',
'onchange',
'onclick',
'onclose',
'oncontextmenu',
'oncuechange',
'ondblclick',
'ondrag',
'ondragend',
'ondragenter',
'ondragexit',
'ondragleave',
'ondragover',
'ondragstart',
'ondrop',
'ondurationchange',
'onemptied',
'onended',
'onerror',
'onfocus',
'oninput',
'oninvalid',
'onkeydown',
'onkeypress',
'onkeyup',
'onload',
'onloadeddata',
'onloadedmetadata',
'onloadstart',
'onmousedown',
'onmouseenter',
'onmouseleave',
'onmousemove',
'onmouseout',
'onmouseover',
'onmouseup',
'onwheel',
'onpause',
'onplay',
'onplaying',
'onprogress',
'onratechange',
'onreset',
'onresize',
'onscroll',
'onseeked',
'onseeking',
'onselect',
'onshow',
'onstalled',
'onsubmit',
'onsuspend',
'ontimeupdate',
'ontoggle',
'onvolumechange',
'onwaiting'
];
import virtualizeNode from './nodes';
import virtualizeString from './strings';
export default function (el, options) {
if (typeof el === 'string') {
return virtualizeString(el, options);
}
else {
return virtualizeNode(el, options);
}
}
export { virtualizeNode, virtualizeString };
import h from 'snabbdom/h';
import { createTextVNode, transformName } from './utils';
import listeners from './event-listeners';
export default function virtualizeNodes(element, options = {}) {
const context = options.context || document;
if (!element) {
return null;
}
const createdVNodes = [];
const vnode = convertNode(element, createdVNodes, context);
options.hooks && options.hooks.create && createdVNodes.forEach((node) => { options.hooks.create(node); });
return vnode;
}
function convertNode(element, createdVNodes, context) {
// If our node is a text node, then we only want to set the `text` part of
// the VNode.
if (element.nodeType === context.defaultView.Node.TEXT_NODE) {
const newNode = createTextVNode(element.textContent, context);
newNode.elm = element;
createdVNodes.push(newNode);
return newNode
}
// If not a text node, then build up a VNode based on the element's tag
// name, class and style attributes, and remaining attributes.
// Special values: style, class. We don't include these in the attrs hash
// of the VNode.
const data = {};
const classes = getClasses(element);
if (Object.keys(classes).length !== 0) {
data.class = classes;
}
const style = getStyle(element);
if (Object.keys(style).length !== 0) {
data.style = style;
}
// Build up set of attributes on the element.
const attributes = element.attributes;
for (let i = 0; i < attributes.length; i++) {
const attr = attributes.item(i);
const name = attr.name;
if (name !== 'style' && name !== 'class') {
if (!data.attrs) {
data.attrs = {};
}
data.attrs[name] = attr.value;
}
}
// Check for event listeners.
const on = {};
listeners.forEach((key) => {
if (element[key]) {
on[key.substring(2)] = element[key];
}
});
if (Object.keys(on).length > 0) {
data.on = on;
}
// Build up set of children.
let childNodes = null;
const children = element.childNodes;
if (children.length > 0) {
childNodes = [];
for (var i = 0; i < children.length; i++) {
childNodes.push(convertNode(children.item(i), createdVNodes, context));
}
}
const newNode = h(element.tagName.toLowerCase(), data, childNodes);
newNode.elm = element;
createdVNodes.push(newNode);
return newNode
}
// Builds the class object for the VNode.
function getClasses(element) {
const className = element.className;
const classes = {};
if (className !== null && className.length > 0) {
className.split(' ').forEach((className) => {
if (className.trim().length) {
classes[className.trim()] = true;
}
});
}
return classes;
}
// Builds the style object for the VNode.
function getStyle(element) {
const style = element.style;
const styles = {};
for (let i = 0; i < style.length; i++) {
const name = style.item(i);
const transformedName = transformName(name);
styles[transformedName] = style.getPropertyValue(name);
}
return styles;
}
import htmlparser from 'htmlparser2';
import h from 'snabbdom/h';
import {
createTextVNode,
transformName,
unescapeEntities
} from './utils';
const parseHTML = function (html) {
let handler = new htmlparser.DomHandler();
let parser = new htmlparser.Parser(handler, {
lowerCaseAttributeNames: false
});
parser.parseComplete(html);
return handler.dom;
}
export default function (html, options = {}) {
const context = options.context || document;
// If there's nothing here, return null;
if (!html) {
return null;
}
// Maintain a list of created vnodes so we can call the create hook.
const createdVNodes = [];
// Parse the string into the AST and convert to VNodes.
const vnodes = convertNodes(parseHTML(html), createdVNodes, context);
let res;
if (!vnodes) {
// If there are no vnodes but there is string content, then the string
// must be just text or at least invalid HTML that we should treat as
// text (since the AST parser didn't find any well-formed HTML).
res = toVNode({
type: 'text',
content: html
}, createdVNodes, context);
} else if (vnodes.length === 1) {
// If there's only one root node, just return it as opposed to an array.
res = vnodes[0];
} else {
// Otherwise we have an array of VNodes, which we should return.
res = vnodes;
}
// Call the 'create' hook for each created node.
options.hooks && options.hooks.create && createdVNodes.forEach((node) => {
options.hooks.create(node);
});
return res;
}
function convertNodes(nodes, createdVNodes, context) {
if (nodes instanceof Array && nodes.length > 0) {
let convertedNodes = [];
nodes.forEach((node) => {
if (node.type !== 'comment') {
convertedNodes.push(toVNode(node, createdVNodes, context));
}
});
return convertedNodes
} else {
return undefined;
}
}
function toVNode(node, createdVNodes, context) {
let newNode;
if (node.type === 'text') {
newNode = createTextVNode(node.data, context);
} else {
newNode = h(node.name, buildVNodeData(node, context), convertNodes(node.children, createdVNodes, context));
}
createdVNodes.push(newNode);
return newNode;
}
function buildVNodeData(node, context) {
const data = {};
if (!node.attribs) {
return data;
}
const attrs = Object.keys(node.attribs).reduce((memo, name) => {
if (name !== 'style' && name !== 'class') {
const val = unescapeEntities(node.attribs[name], context);
memo ? memo[name] = val : memo = {
[name]: val
};
}
return memo;
}, null);
if (attrs) {
data.attrs = attrs;
}
const style = parseStyle(node);
if (style) {
data.style = style;
}
const classes = parseClass(node);
if (classes) {
data.class = classes;
}
return data;
}
function parseStyle(node) {
try {
return node.attribs.style.split(';').reduce((memo, styleProp) => {
const res = styleProp.split(':');
const name = transformName(res[0].trim());
if (name) {
const val = res[1].replace('!important', '').trim();
memo ? memo[name] = val : memo = {
[name]: val
};
}
return memo;
}, null);
} catch (e) {
return null;
}
}
function parseClass(node) {
try {
return node.attribs.class.split(' ').reduce((memo, className) => {
className = className.trim();
if (className) {
memo ? memo[className] = true : memo = {
[className]: true
};
}
return memo;
}, null);
} catch (e) {
return null;
}
}
\ No newline at end of file
import VNode from 'snabbdom/vnode';
export function createTextVNode(text, context) {
return VNode(undefined, undefined, undefined, unescapeEntities(text, context));
}
export function transformName(name) {
// Replace -a with A to help camel case style property names.
name = name.replace( /-(\w)/g, function _replace( $1, $2 ) {
return $2.toUpperCase();
});
// Handle properties that start with a -.
const firstChar = name.charAt(0).toLowerCase();
return `${firstChar}${name.substring(1)}`;
}
// Regex for matching HTML entities.
const entityRegex = new RegExp('&[a-z0-9#]+;', 'gi')
// Element for setting innerHTML for transforming entities.
let el = null;
export function unescapeEntities(text, context) {
// Create the element using the context if it doesn't exist.
if (!el) {
el = context.createElement('div');
}
return text.replace(entityRegex, (entity) => {
el.innerHTML = entity;
return el.textContent;
});
}
module.exports = require('./lib/strings');
"use strict";
module.exports = function (config) {
var isCI = process.env['CI'];
var baseConfig = {
frameworks: ['mocha', 'chai-sinon', 'sinon', 'chai'],
files: [
'tests/**/*.js'
],
preprocessors: {
'tests/**/*.js': ['webpack', 'sourcemap']
},
webpack: {
devtool: 'inline-source-map',
module: {
loaders: [{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader'
}]
}
},
webpackMiddleware: {
noInfo: true
},
reporters: [
'dots'
],
// web server port
port: 8081,
// cli runner port
runnerPort: 9100,
// enable / disable colors in the output (reporters and logs)
colors: true,
// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO,
// enable / disable watching file and executing tests whenever any file changes
autoWatch: true,
// Start these browsers.
browsers: [
'Firefox',
'Chrome'
],
// If browser does not capture in given timeout [ms], kill it
captureTimeout: 120000,
// Continuous Integration mode
// if true, it capture browsers, run tests and exit
singleRun: true
};
if (isCI) {
// Open Sauce config.
baseConfig.sauceLabs = {
testName: 'snabbdom-virtualize unit tests',
recordScreenshots: false
};
baseConfig.customLaunchers = {
'SL_Chrome': {
base: 'SauceLabs',
platform: 'OS X 10.11',
browserName: 'chrome'
},
'SL_Firefox': {
base: 'SauceLabs',
platform: 'OS X 10.11',
browserName: 'firefox'
},
'SL_Edge': {
base: 'SauceLabs',
platform: 'Windows 10',
browserName: 'microsoftedge'
},
'SL_IE_9': {
base: 'SauceLabs',
browserName: 'internet explorer',
version: '9.0',
platform: 'Windows 7'
},
'SL_Safari_9': {
base: 'SauceLabs',
browserName: 'safari',
version: '9.0',
platform: 'OS X 10.11'
}
};
baseConfig.reporters.push('saucelabs');
baseConfig.browsers = Object.keys(baseConfig.customLaunchers);
}
config.set(baseConfig);
}
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment