(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global.Typester = factory());
}(this, (function () { 'use strict';
// Production steps of ECMA-262, Edition 5, 15.4.4.18
// Reference: http://es5.github.io/#x15.4.4.18
if (!Array.prototype.forEach) {
Array.prototype.forEach = function (callback /*, thisArg*/) {
var T, k;
if (this == null) {
throw new TypeError('this is null or not defined');
}
// 1. Let O be the result of calling toObject() passing the
// |this| value as the argument.
var O = Object(this);
// 2. Let lenValue be the result of calling the Get() internal
// method of O with the argument "length".
// 3. Let len be toUint32(lenValue).
var len = O.length >>> 0;
// 4. If isCallable(callback) is false, throw a TypeError exception.
// See: http://es5.github.com/#x9.11
if (typeof callback !== 'function') {
throw new TypeError(callback + ' is not a function');
}
// 5. If thisArg was supplied, let T be thisArg; else let
// T be undefined.
if (arguments.length > 1) {
T = arguments[1];
}
// 6. Let k be 0
k = 0;
// 7. Repeat, while k < len
while (k < len) {
var kValue;
// a. Let Pk be ToString(k).
// This is implicit for LHS operands of the in operator
// b. Let kPresent be the result of calling the HasProperty
// internal method of O with argument Pk.
// This step can be combined with c
// c. If kPresent is true, then
if (k in O) {
// i. Let kValue be the result of calling the Get internal
// method of O with argument Pk.
kValue = O[k];
// ii. Call the Call internal method of callback with T as
// the this value and argument list containing kValue, k, and O.
callback.call(T, kValue, k, O);
}
// d. Increase k by 1.
k++;
}
// 8. return undefined
};
}
if (window.NodeList && !NodeList.prototype.forEach) {
NodeList.prototype.forEach = function (callback, thisArg) {
thisArg = thisArg || window;
for (var i = 0; i < this.length; i++) {
callback.call(thisArg, this[i], i, this);
}
};
}
if (typeof Object.assign !== 'function') {
Object.assign = function (target) {
// .length of function is 2
'use strict';
var to, index, nextSource, nextKey;
if (target === null) {
// TypeError if undefined or null
throw new TypeError('Cannot convert undefined or null to object');
}
to = Object(target);
for (index = 1; index < arguments.length; index++) {
nextSource = arguments[index];
if (nextSource !== null) {
// Skip over if undefined or null
for (nextKey in nextSource) {
// Avoid bugs when hasOwnProperty is shadowed
if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
to[nextKey] = nextSource[nextKey];
}
}
}
}
return to;
};
}
// jshint strict: false
var guid = function guid() {
function s4() {
return Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1);
}
return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
};
// jshint strict: false
var Mediator = function Mediator() {
var opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var internal = {
parent: opts.parent,
children: [],
id: guid(),
conceal: opts.conceal || []
};
var requests = {
handlers: {},
new: function _new(requestKey, requestHandler) {
if (requests.handlers[requestKey]) {
throw new Error('Only one requestHandler per requestKey: ' + requestKey);
}
requests.handlers[requestKey] = requestHandler;
},
getHandler: function getHandler(requestKey) {
return requests.handlers[requestKey];
},
canHandle: function canHandle(requestKey) {
return !!requests.getHandler(requestKey);
},
request: function request(requestKey, options) {
var requestHandler = requests.getHandler(requestKey);
if (requestHandler) {
return requestHandler(options);
}
}
};
var commands = {
handlers: {},
new: function _new(commandKey, commandHandler) {
if (commands.handlers[commandKey]) {
throw new Error('Only one commandHandler per commandKey: ' + commandKey);
}
commands.handlers[commandKey] = commandHandler;
},
getHandler: function getHandler(commandKey) {
return commands.handlers[commandKey];
},
canHandle: function canHandle(commandKey) {
return !!commands.getHandler(commandKey);
},
exec: function exec(commandKey, options) {
var commandHandler = commands.getHandler(commandKey);
if (commandHandler) {
commandHandler(options);
}
}
};
var events = {
handlers: {},
new: function _new(eventKey, eventHandler) {
events.handlers[eventKey] = events.handlers[eventKey] || [];
events.handlers[eventKey].push(eventHandler);
},
getHandlers: function getHandlers(eventKey) {
return events.handlers[eventKey] || [];
},
canHandle: function canHandle(eventKey) {
return !!events.getHandlers(eventKey);
},
emit: function emit(eventKey, options) {
var eventHandlers = events.getHandlers(eventKey);
if (eventHandlers.length) {
eventHandlers.forEach(function (eventHandler) {
return eventHandler(options);
});
}
}
};
var registers = {
registerHandler: function registerHandler(type, typeKey, typeHandler) {
switch (type) {
case 'request':
requests.new(typeKey, typeHandler);
break;
case 'command':
commands.new(typeKey, typeHandler);
break;
case 'event':
events.new(typeKey, typeHandler);
break;
}
},
registerRequestHandlers: function registerRequestHandlers() {
var requestHandlers = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
Object.keys(requestHandlers).forEach(function (requestKey) {
var requestHandler = requestHandlers[requestKey];
registers.registerHandler('request', requestKey, requestHandler);
});
},
registerCommandHandlers: function registerCommandHandlers() {
var commandHandlers = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
Object.keys(commandHandlers).forEach(function (commandKey) {
var commandHandler = commandHandlers[commandKey];
registers.registerHandler('command', commandKey, commandHandler);
});
},
registerEventHandlers: function registerEventHandlers() {
var eventHandlers = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
Object.keys(eventHandlers).forEach(function (eventKey) {
var eventHandler = eventHandlers[eventKey];
registers.registerHandler('event', eventKey, eventHandler);
});
}
};
var fn = {
init: function init() {
if (internal.parent) {
internal.parent.registerChild(api);
}
},
shouldConceal: function shouldConceal(msgKey) {
var shouldConceal = false;
internal.conceal.forEach(function (concealPattern) {
shouldConceal = shouldConceal || concealPattern.test(msgKey);
});
return shouldConceal;
},
delegate: function delegate(type, msgKey) {
var args = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
var opts = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
var _state = opts._state;
if (!_state.hasAttempted(internal.id)) {
fn.handle(type, msgKey, args, opts);
}
if (!_state.hasBeenHandled) {
internal.children.forEach(function (childMediator) {
if (!_state.hasBeenHandled && !_state.hasAttempted(childMediator.getId())) {
childMediator.handle(type, msgKey, args, opts);
}
});
}
if (!_state.hasBeenHandled) {
if (internal.parent && !_state.hasAttempted(internal.parent.getId()) && !fn.shouldConceal(msgKey)) {
internal.parent.delegate(type, msgKey, args, opts);
}
}
return _state.response;
},
canHandle: function canHandle(type, msgKey) {
switch (type) {
case 'request':
return requests.canHandle(msgKey);
case 'command':
return commands.canHandle(msgKey);
case 'event':
return events.canHandle(msgKey);
}
},
handle: function handle(type, msgKey) {
var args = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
var opts = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
opts._state = opts._state || fn.newStateObj();
var canHandle = fn.canHandle(type, msgKey);
var _state = opts._state;
if (_state.hasAttempted(internal.id)) {
return _state.response;
}
opts._state.logAttempt(internal.id);
if (canHandle) {
switch (type) {
case 'request':
_state.response = requests.request(msgKey, args);
_state.hasBeenHandled = true;
break;
case 'command':
commands.exec(msgKey, args);
_state.hasBeenHandled = true;
break;
case 'event':
events.emit(msgKey, args);
fn.delegate(type, msgKey, args, opts);
break;
}
return _state.response;
} else {
return fn.delegate(type, msgKey, args, opts);
}
},
newStateObj: function newStateObj() {
var stateObj = {
attempts: [],
hasBeenHandled: false,
response: null,
logAttempt: function logAttempt(mediatorId) {
this.attempts.push(mediatorId);
},
hasAttempted: function hasAttempted(mediatorId) {
return this.attempts.indexOf(mediatorId) > -1;
}
};
return stateObj;
},
request: function request(requestKey) {
var opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
return fn.handle('request', requestKey, opts);
},
exec: function exec(commandKey) {
var opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
fn.handle('command', commandKey, opts);
},
emit: function emit(eventKey) {
var opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
fn.handle('event', eventKey, opts);
},
hasAttemptedToHandle: function hasAttemptedToHandle(opts) {
return opts.attemptedDelegates.indexOf(internal.id) > -1;
},
registerChild: function registerChild(childApi) {
childApi.childIndex = internal.children.length;
internal.children.push(childApi);
},
deregisterChild: function deregisterChild(childApi) {
internal.children.slice(childApi.childIndex, 1);
},
setParent: function setParent(parentApi) {
if (internal.parent) {
internal.parent.deregisterChild(api);
}
internal.parent = parentApi;
internal.parent.registerChild(api);
},
getId: function getId() {
return internal.id;
}
};
var api = {
getId: fn.getId,
registerRequestHandlers: registers.registerRequestHandlers,
registerCommandHandlers: registers.registerCommandHandlers,
registerEventHandlers: registers.registerEventHandlers,
registerHandler: registers.registerHandler,
request: fn.request,
exec: fn.exec,
emit: fn.emit,
get: fn.request,
canHandle: fn.canHandle,
handle: fn.handle,
registerChild: fn.registerChild,
hasAttemptedToHandle: fn.hasAttemptedToHandle,
deregisterChild: fn.deregisterChild,
setParent: fn.setParent,
delegate: fn.delegate,
getHandlerKeys: function getHandlerKeys() {
var handlers = [];
handlers.concat(Object.keys(requests.handlers));
handlers.concat(Object.keys(commands.handlers));
handlers.concat(Object.keys(events.handlers));
return handlers;
}
};
fn.init();
return api;
};
// jshint strict: false
var Context = function Context() {
this.mixin.apply(this, arguments);
};
Object.assign(Context.prototype, {
mixin: function mixin() {
var _this = this;
for (var _len = arguments.length, contexts = Array(_len), _key = 0; _key < _len; _key++) {
contexts[_key] = arguments[_key];
}
contexts.forEach(function (context) {
Object.assign(_this, context);
});
},
extendWith: function extendWith(mixinContext) {
var _this2 = this;
var opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
if (opts.keys) {
opts.keys.forEach(function (key) {
_this2[key] = mixinContext[key];
});
} else {
this.mixin(mixinContext);
}
}
});
// jshint strict: false
var func = {
bind: function bind(func, context) {
return function () {
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
return func.apply(context, args);
};
},
bindObj: function bindObj(funcObj, context) {
var boundFuncObj = {};
Object.keys(funcObj).forEach(function (funcKey) {
boundFuncObj[funcKey] = func.bind(funcObj[funcKey], context);
});
return boundFuncObj;
}
};
// jshint strict: false
var Container = function Container(containerObj) {
var containerName = containerObj.name,
containerHandlers = containerObj.handlers,
containerMethods = containerObj.methods,
containerModules = containerObj.modules,
containerChildContainers = containerObj.containers,
mediatorOpts = containerObj.mediatorOpts;
if (!containerName) {
throw new Error('No name given for container');
}
var containerUtils = {
createContext: function createContext() {
for (var _len = arguments.length, contexts = Array(_len), _key = 0; _key < _len; _key++) {
contexts[_key] = arguments[_key];
}
return new (Function.prototype.bind.apply(Context, [null].concat(contexts)))();
},
bindMethods: function bindMethods(methods, context) {
methods = methods || {};
return func.bindObj(methods, context);
},
initModules: function initModules() {
var modules = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
var opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
modules.forEach(function (module) {
var moduleOpts = Object.assign({}, opts, module.opts || {});
module.instance = new module.class(moduleOpts);
});
},
initChildContainers: function initChildContainers() {
var childContainers = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
var opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
childContainers.forEach(function (containerObj) {
var containerOpts = Object.assign({}, opts, containerObj.opts || {});
containerObj.instance = new containerObj.class(containerOpts);
});
},
registerHandlers: function registerHandlers(mediator, handlers, context) {
Object.keys(handlers).forEach(function (handlerKey) {
var handlerMap = handlers[handlerKey];
var handlerMethods = containerUtils.getHandlerMethods(handlerMap, context);
switch (handlerKey) {
case 'requests':
mediator.registerRequestHandlers(handlerMethods);
break;
case 'commands':
mediator.registerCommandHandlers(handlerMethods);
break;
case 'events':
mediator.registerEventHandlers(handlerMethods);
break;
}
});
},
getHandlerMethods: function getHandlerMethods(handlerMap, context) {
var routedHandlers = {};
Object.keys(handlerMap).forEach(function (commandStr) {
var methodKey = handlerMap[commandStr];
var handlerMethod = context[methodKey];
routedHandlers[commandStr] = handlerMethod;
});
return routedHandlers;
}
};
var containerProto = {
containerConstructor: function containerConstructor() {
var opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var context = containerUtils.createContext();
var boundMethods = containerUtils.bindMethods(containerMethods, context);
context.extendWith(boundMethods);
var mediator = new Mediator(Object.assign({ parent: opts.mediator }, mediatorOpts));
context.extendWith({ mediator: mediator });
if (containerHandlers) {
containerUtils.registerHandlers(mediator, containerHandlers, context);
}
if (boundMethods.setup) {
boundMethods.setup();
}
containerUtils.initModules(containerModules, {
dom: opts.dom,
mediator: mediator
});
containerUtils.initChildContainers(containerChildContainers, {
dom: opts.dom,
mediator: mediator
});
if (boundMethods.init) {
boundMethods.init();
}
return {
setMediatorParent: function setMediatorParent(parentMediator) {
mediator.setParent(parentMediator);
}
};
}
};
return containerProto.containerConstructor;
};
// jshint strict: false
var browser = {
// From https://codepen.io/gapcode/pen/vEJNZN
ieVersion: function ieVersion() {
var ua = window.navigator.userAgent;
var msie = ua.indexOf('MSIE ');
if (msie > 0) {
// IE 10 or older => return version number
return parseInt(ua.substring(msie + 5, ua.indexOf('.', msie)), 10);
}
var trident = ua.indexOf('Trident/');
if (trident > 0) {
// IE 11 => return version number
var rv = ua.indexOf('rv:');
return parseInt(ua.substring(rv + 3, ua.indexOf('.', rv)), 10);
}
var edge = ua.indexOf('Edge/');
if (edge > 0) {
// Edge (IE 12+) => return version number
return parseInt(ua.substring(edge + 5, ua.indexOf('.', edge)), 10);
}
// other browser
return false;
},
isIE: function isIE() {
var ieVersion = browser.ieVersion();
return ieVersion && ieVersion < 12;
},
isFirefox: function isFirefox() {
return window.navigator.userAgent.indexOf('Firefox') > -1;
}
};
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
return typeof obj;
} : function (obj) {
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
};
var asyncGenerator = function () {
function AwaitValue(value) {
this.value = value;
}
function AsyncGenerator(gen) {
var front, back;
function send(key, arg) {
return new Promise(function (resolve, reject) {
var request = {
key: key,
arg: arg,
resolve: resolve,
reject: reject,
next: null
};
if (back) {
back = back.next = request;
} else {
front = back = request;
resume(key, arg);
}
});
}
function resume(key, arg) {
try {
var result = gen[key](arg);
var value = result.value;
if (value instanceof AwaitValue) {
Promise.resolve(value.value).then(function (arg) {
resume("next", arg);
}, function (arg) {
resume("throw", arg);
});
} else {
settle(result.done ? "return" : "normal", result.value);
}
} catch (err) {
settle("throw", err);
}
}
function settle(type, value) {
switch (type) {
case "return":
front.resolve({
value: value,
done: true
});
break;
case "throw":
front.reject(value);
break;
default:
front.resolve({
value: value,
done: false
});
break;
}
front = front.next;
if (front) {
resume(front.key, front.arg);
} else {
back = null;
}
}
this._invoke = send;
if (typeof gen.return !== "function") {
this.return = undefined;
}
}
if (typeof Symbol === "function" && Symbol.asyncIterator) {
AsyncGenerator.prototype[Symbol.asyncIterator] = function () {
return this;
};
}
AsyncGenerator.prototype.next = function (arg) {
return this._invoke("next", arg);
};
AsyncGenerator.prototype.throw = function (arg) {
return this._invoke("throw", arg);
};
AsyncGenerator.prototype.return = function (arg) {
return this._invoke("return", arg);
};
return {
wrap: function (fn) {
return function () {
return new AsyncGenerator(fn.apply(this, arguments));
};
},
await: function (value) {
return new AwaitValue(value);
}
};
}();
var slicedToArray = function () {
function sliceIterator(arr, i) {
var _arr = [];
var _n = true;
var _d = false;
var _e = undefined;
try {
for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
_arr.push(_s.value);
if (i && _arr.length === i) break;
}
} catch (err) {
_d = true;
_e = err;
} finally {
try {
if (!_n && _i["return"]) _i["return"]();
} finally {
if (_d) throw _e;
}
}
return _arr;
}
return function (arr, i) {
if (Array.isArray(arr)) {
return arr;
} else if (Symbol.iterator in Object(arr)) {
return sliceIterator(arr, i);
} else {
throw new TypeError("Invalid attempt to destructure non-iterable instance");
}
};
}();
// jshint strict: false
/* eslint-disable no-alert, no-console */
var DOM = {
regex: {
getById: /^#/,
getByClassName: /^\./,
getByTag: /^[a-z]/
},
getElements: function getElements(elementsObj, rootEl) {
for (var elementKey in elementsObj) {
if (elementsObj.hasOwnProperty(elementKey) && elementKey !== 'rootEl') {
var elementObj = elementsObj[elementKey];
var selector = elementObj.selector;
rootEl = elementObj.rootEl || rootEl;
rootEl = typeof rootEl === 'function' ? rootEl() : rootEl;
elementObj.el = DOM.get(selector, rootEl);
}
}
},
// Public methods
get: function get$$1(selector) {
var domRoot = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : document;
if (DOM.isElement(selector)) {
return [selector];
}
var getMethodName = DOM._getGetMethodName(selector);
return DOM[getMethodName](selector, domRoot);
},
getByClassName: function getByClassName(className) {
var domRoot = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : document;
className = DOM._cleanSelector(className);
return domRoot.getElementsByClassName(className);
},
getByTag: function getByTag(tag) {
var domRoot = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : document;
tag = DOM._cleanSelector(tag);
return domRoot.getElementsByTagName(tag);
},
getById: function getById(id) {
return document.getElementById(id);
},
getClosest: function getClosest(node, selector, ceilNode) {
var rootEl = ceilNode || DOM.getRootEl();
var checkType = /^\[/.test(selector) ? 'attribute' : /^\./.test(selector) ? 'class' : /^\#/.test(selector) ? 'id' : 'tag';
var returnNode = false;
var attrName = void 0,
className = void 0,
idStr = void 0,
parentId = void 0;
if (node === rootEl) {
return null;
}
while (node.nodeType !== Node.ELEMENT_NODE) {
node = node.parentNode;
}
switch (checkType) {
case 'attribute':
attrName = selector.match(/\[(.*?)\]/)[1];
returnNode = node.hasAttribute(attrName);
break;
case 'class':
className = selector.replace('.', '');
returnNode = node.classList && node.classList.contains(className);
break;
case 'id':
idStr = selector.replace('#', '');
parentId = node.getAttribute('id');
returnNode = idStr === parentId;
break;
case 'tag':
returnNode = node.nodeName.toLowerCase() === selector.toLowerCase();
break;
}
if (returnNode) {
return node;
} else {
return DOM.getClosest(node.parentNode, selector, rootEl);
}
},
getClosestInArray: function getClosestInArray(node, nameArray, ceilNode) {
var parentNode = node;
while (nameArray.indexOf(parentNode.nodeName) < 0 && parentNode !== ceilNode) {
parentNode = parentNode.parentNode;
}
if (parentNode !== ceilNode) {
return parentNode;
} else {
return null;
}
},
getFurthest: function getFurthest(node, selector) {
var rootEl = DOM.getRootEl();
var currentNode = node;
var furthest = null;
selector = selector instanceof Array ? selector : [selector];
while (currentNode && currentNode !== rootEl) {
if (selector.indexOf(currentNode.nodeName) > -1) {
furthest = currentNode;
}
currentNode = currentNode.parentNode || currentNode.parentElement;
}
return furthest;
},
nextNode: function nextNode(node) {
if (node.hasChildNodes()) {
return node.firstChild;
} else {
while (node && !node.nextSibling) {
node = node.parentNode;
}
if (!node) {
return null;
}
return node.nextSibling;
}
},
appendTo: function appendTo(selector, tag) {
var htmlNode = DOM.isElement(tag) ? tag : document.createElement(tag);
var targetEl = DOM.get(selector);
for (var i = 0; i < targetEl.length; i++) {
targetEl[i].appendChild(htmlNode);
}
return htmlNode;
},
addStyles: function addStyles(styles) {
var styleEl = DOM.appendTo('head', 'style');
styleEl.setAttribute('id', 'typester-styles');
styleEl.setAttribute('type', 'text/css');
if (styleEl.styleSheet) {
styleEl.styleSheet.cssText = styles;
} else {
styleEl.appendChild(document.createTextNode(styles));
}
return styleEl;
},
// From http://stackoverflow.com/questions/384286/javascript-isdom-how-do-you-check-if-a-javascript-object-is-a-dom-object
isNode: function isNode(o) {
return (typeof Node === 'undefined' ? 'undefined' : _typeof(Node)) === 'object' ? o instanceof Node : o && (typeof o === 'undefined' ? 'undefined' : _typeof(o)) === 'object' && typeof o.nodeType === 'number' && typeof o.nodeName === 'string';
},
isElement: function isElement(elem) {
var isElement = false;
isElement = elem instanceof Window || elem instanceof Document;
isElement = isElement || (typeof HTMLElement === 'undefined' ? 'undefined' : _typeof(HTMLElement)) === 'object' && elem instanceof HTMLElement;
isElement = isElement || elem && (typeof elem === 'undefined' ? 'undefined' : _typeof(elem)) === 'object' && elem !== null && elem.nodeType === 1 && typeof elem.nodeName === 'string';
return isElement;
},
isIn: function isIn(node, nodeName, ceilNode) {
var isIn = false;
var currentNode = node;
var nameArray = nodeName instanceof Array ? nodeName : nodeName.split('/');
ceilNode = ceilNode || DOM.getRootEl();
nameArray = nameArray.map(function (name) {
return name.toLowerCase();
});
while (!isIn && currentNode !== ceilNode) {
isIn = nameArray.indexOf(currentNode.nodeName.toLowerCase()) > -1;
currentNode = currentNode.parentNode;
}
return isIn;
},
isChildOf: function isChildOf(childNode, parentNode) {
if (childNode instanceof Array) {
childNode = childNode[0];
}
if (parentNode instanceof Array) {
parentNode = parentNode[0];
}
return parentNode && childNode && parentNode.contains(childNode);
},
addClass: function addClass(el, classStr) {
el.classList.add(classStr);
},
toggleClass: function toggleClass(el, classStr, force) {
var addClass = force !== undefined ? force : !el.classList.contains(classStr);
if (addClass) {
DOM.addClass(el, classStr);
} else {
DOM.removeClass(el, classStr);
}
},
removeClass: function removeClass(el, classStr) {
el.classList.remove(classStr);
},
isBlock: function isBlock(node) {
return DOM.getStyle(node, 'display') === 'block';
},
closestElement: function closestElement(node) {
var returnNode = node;
while (returnNode.nodeType !== 1) {
returnNode = returnNode.parentNode;
}
return returnNode;
},
getStyles: function getStyles(node) {
var closestElement = DOM.closestElement(node);
var gcs = 'getComputedStyle' in window;
return gcs ? window.getComputedStyle(closestElement) : closestElement.currentStyle;
},
getStyle: function getStyle(node, property) {
var nodeStyles = DOM.getStyles(node);
return nodeStyles[property];
},
insertBefore: function insertBefore(newNode, referenceNode) {
var parentNode = referenceNode.parentNode;
parentNode.insertBefore(newNode, referenceNode);
},
insertAfter: function insertAfter(newNode, referenceNode) {
var parentNode = referenceNode.parentNode;
if (parentNode.lastChild === referenceNode) {
parentNode.appendChild(newNode);
} else {
parentNode.insertBefore(newNode, referenceNode.nextSibling);
}
},
isLastChild: function isLastChild(node) {
return node === node.parentNode.lastChild;
},
isFirstChild: function isFirstChild(node) {
return node === node.parentNode.firstChild;
},
wrapRange: function wrapRange(nodeName, nodeOpts) {
var sel = window.getSelection();
var range = sel.getRangeAt(0);
var wrapper = document.createElement(nodeName);
for (var optKey in nodeOpts) {
if (nodeOpts.hasOwnProperty(optKey)) {
wrapper[optKey] = nodeOpts[optKey];
}
}
range.surroundContents(wrapper);
return wrapper;
},
unwrap: function unwrap(node) {
var opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var unwrappedNodes = [];
if (node.childNodes) {
while (node.firstChild) {
unwrappedNodes.push(node.firstChild);
DOM.insertBefore(node.firstChild, node);
}
}
if (!opts.keepNode) {
DOM.removeNode(node);
}
return unwrappedNodes;
},
unwrapFrom: function unwrapFrom(node, wrappers) {
var rootEl = DOM.getRootEl();
var currentNode = node;
var unwrappedNodes = [currentNode];
while (currentNode !== rootEl) {
var parentNode = currentNode.parentNode || currentNode.parentElement;
if (wrappers.indexOf(currentNode.nodeName) > -1) {
unwrappedNodes = DOM.unwrap(currentNode);
}
currentNode = parentNode;
}
return unwrappedNodes;
},
unwrapToRoot: function unwrapToRoot(node) {
var rootEl = DOM.getRootEl();
var currentNode = node.parentNode;
while (currentNode !== rootEl) {
var parentNode = currentNode.parentNode;
DOM.unwrap(currentNode);
currentNode = parentNode;
}
},
removeNode: function removeNode(node) {
var parentNode = node.parentElement || node.parentNode;
if (parentNode) {
parentNode.removeChild(node);
}
},
replaceNode: function replaceNode(node, newNode) {
var parentNode = node.parentNode || node.parentElement;
if (parentNode) {
parentNode.replaceChild(newNode, node);
}
},
getContainerZIndex: function getContainerZIndex(node) {
var container = node;
var topMostContainerZIndex = 0;
while (container && container !== document.body) {
var containerZIndex = window.getComputedStyle(container).zIndex;
if (/^[0-9]+$/.test(containerZIndex)) {
topMostContainerZIndex = parseInt(containerZIndex);
}
container = container.parentNode;
}
return topMostContainerZIndex;
},
// // From http://stackoverflow.com/questions/6139107/programmatically-select-text-in-a-contenteditable-html-element
// selectNodeContents(node) {
// node = node || DOM.getAnchorNode();
// if (!node) {
// return;
// }
//
// const nodes = node instanceof Array ? node : [node];
// const startNode = nodes[0];
// const endNode = nodes[nodes.length - 1];
//
// const range = document.createRange();
// range.setStart(startNode, 0);
// range.setEnd(endNode, endNode.length);
//
// const sel = window.getSelection();
// if (sel.rangeCount > 0) {
// sel.removeAllRanges();
// }
// sel.addRange(range);
// },
getRootEl: function getRootEl() {
var selection = document.getSelection();
var anchorNode = selection.anchorNode;
var rootEl = anchorNode;
while (rootEl && !(rootEl.nodeType === Node.ELEMENT_NODE && rootEl.hasAttribute('contenteditable'))) {
rootEl = rootEl.parentNode;
}
return rootEl;
},
removeInvalidTagsUpward: function removeInvalidTagsUpward(node, acceptedTags) {
var rootEl = DOM.getRootEl();
var currentNode = node;
var invalidTags = [];
var unwrappedNodes = [node];
while (currentNode !== rootEl) {
if (currentNode.nodeType === 1 && acceptedTags.indexOf(currentNode.nodeName) < 0) {
invalidTags.push(currentNode);
}
currentNode = currentNode.parentNode || currentNode.parentElement;
}
for (var i = 0; i < invalidTags.length; i++) {
var invalidTag = invalidTags[i];
unwrappedNodes = DOM.unwrap(invalidTag);
}
return unwrappedNodes;
},
// From: http://stackoverflow.com/questions/37025488/remove-whitespace-from-window-selection-in-js
trimSelection: function trimSelection(opts) {
opts = opts || { fromEnd: true };
var sel = window.getSelection();
var range = sel.getRangeAt(0);
var selStr = sel.toString();
var regEx = void 0,
container = void 0,
method = void 0,
regExResult = void 0,
offset = range.startOffset,
rangeClone = void 0;
if (opts.bothEnds) {
opts.fromEnd = true;
}
if (opts.fromEnd) {
regEx = /\s+$/;
container = range.endContainer;
method = range.setEnd;
} else if (opts.fromStart) {
regEx = /[^\s]/;
container = range.startContainer;
method = range.setStart;
}
regExResult = regEx.exec(selStr);
if (regExResult && regExResult.index > 0) {
if (opts.fromEnd && offset + regExResult.index > container.length) {
regExResult = regEx.exec(container.textContent);
if (regExResult) {
method.call(range, container, regExResult.index);
}
} else {
method.call(range, container, offset + regExResult.index);
}
rangeClone = range.cloneRange();
sel.removeAllRanges();
sel.addRange(rangeClone);
}
if (opts.bothEnds) {
if (opts.fromEnd) {
DOM.trimSelection({ fromStart: true });
} else {
DOM.trimSelection({ fromEnd: true });
}
}
},
createPseudoSelect: function createPseudoSelect() {
var rootEl = DOM.getRootEl();
var wrapper = DOM.wrapRange('SPAN', {
className: 'pseudo-selection'
});
var selectionStyles = void 0;
if (browser.isFirefox()) {
selectionStyles = window.getComputedStyle(rootEl, '::-moz-selection');
} else {
selectionStyles = window.getComputedStyle(rootEl, '::selection');
}
wrapper.style['background-color'] = selectionStyles['background-color'];
if (wrapper.style['background-color'] === 'transparent') {
wrapper.style['background-color'] = '#EEEEEE';
}
wrapper.style.color = selectionStyles.color;
return wrapper;
},
// From: https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollY
getScrollOffset: function getScrollOffset() {
var supportPageOffset = window.pageXOffset !== undefined;
var isCSS1Compat = (document.compatMode || '') === 'CSS1Compat';
var x = supportPageOffset ? window.pageXOffset : isCSS1Compat ? document.documentElement.scrollLeft : document.body.scrollLeft;
var y = supportPageOffset ? window.pageYOffset : isCSS1Compat ? document.documentElement.scrollTop : document.body.scrollTop;
return { x: x, y: y };
},
childIndex: function childIndex(node) {
var child = node;
var childIndex = 0;
while ((child = child.previousSibling) !== null) {
childIndex++;
}
return childIndex;
},
//Pseudo-private methods
_getGetMethodName: function _getGetMethodName(selector) {
var methodName = null;
Object.keys(DOM.regex).forEach(function (regexKey) {
var regex = DOM.regex[regexKey];
if (regex.test(selector)) {
methodName = regexKey;
}
});
return methodName;
},
_cleanSelector: function _cleanSelector(selector) {
return selector.replace(/^[\.#]/, '');
},
_createEl: function _createEl(tag) {
return document.createElement(tag);
}
};
// jshint strict: false
var Module = function Module(moduleObj) {
var moduleName = moduleObj.name,
moduleProps = moduleObj.props,
moduleHandlers = moduleObj.handlers,
moduleDom = moduleObj.dom,
moduleMethods = moduleObj.methods,
moduleRequiredProps = moduleObj.requiredProps;
if (!moduleName) {
throw new Error('No name given for module', moduleObj);
}
var moduleUtils = {
createContext: function createContext() {
for (var _len = arguments.length, contexts = Array(_len), _key = 0; _key < _len; _key++) {
contexts[_key] = arguments[_key];
}
return new (Function.prototype.bind.apply(Context, [null].concat(contexts)))();
},
bindMethods: function bindMethods(methods, context) {
methods = methods || {};
return func.bindObj(methods, context);
},
wrapRenderMethod: function wrapRenderMethod(renderMethod, opts) {
var wrappedRenderMethod = function wrappedRenderMethod() {
var context = opts.context;
var mergedDom = void 0;
mergedDom = moduleUtils.mergeDom(moduleDom, opts.dom);
mergedDom.el = renderMethod.apply(undefined, arguments);
moduleUtils.getDom(mergedDom);
context.extendWith({ dom: mergedDom });
if (moduleHandlers.domEvents) {
moduleUtils.registerDomHandlers(moduleHandlers.domEvents, context);
}
};
return wrappedRenderMethod;
},
registerHandlers: function registerHandlers(mediator, handlers, context) {
Object.keys(handlers).forEach(function (handlerKey) {
var handlerMap = handlers[handlerKey];
var handlerMethods = moduleUtils.getHandlerMethods(handlerMap, context);
switch (handlerKey) {
case 'requests':
mediator.registerRequestHandlers(handlerMethods);
break;
case 'commands':
mediator.registerCommandHandlers(handlerMethods);
break;
case 'events':
mediator.registerEventHandlers(handlerMethods);
break;
}
});
},
registerDomHandlers: function registerDomHandlers(domHandlersMap, context) {
var handlerMethods = moduleUtils.getHandlerMethods(domHandlersMap, context);
moduleUtils.bindDomEvents(handlerMethods, context);
},
getHandlerMethods: function getHandlerMethods(handlerMap, context) {
var routedHandlers = {};
Object.keys(handlerMap).forEach(function (commandStr) {
var methodKey = handlerMap[commandStr];
var handlerMethod = context[methodKey];
routedHandlers[commandStr] = handlerMethod;
});
return routedHandlers;
},
mergeDom: function mergeDom(defaultDom) {
var dom = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var mergedDom = {};
Object.keys(defaultDom).forEach(function (domKey) {
mergedDom[domKey] = defaultDom[domKey];
});
Object.keys(dom).forEach(function (domKey) {
mergedDom[domKey] = dom[domKey];
mergedDom[domKey].selector = dom[domKey];
});
return mergedDom;
},
getDom: function getDom(dom) {
var rootEl = dom.el || document.body;
Object.keys(dom).forEach(function (domKey) {
var selector = void 0,
domEl = void 0;
selector = dom[domKey];
if (selector === null) {
return;
} else if ((typeof selector === 'undefined' ? 'undefined' : _typeof(selector)) === 'object') {
selector = selector.selector || selector;
}
domEl = DOM.get(selector, rootEl);
domEl.selector = selector;
dom[domKey] = domEl;
});
},
bindDomEvents: function bindDomEvents(handlers, context) {
var dom = context.dom;
Object.keys(handlers).forEach(function (eventElKey) {
var _eventElKey$split = eventElKey.split(' @'),
_eventElKey$split2 = slicedToArray(_eventElKey$split, 2),
eventKey = _eventElKey$split2[0],
elemKey = _eventElKey$split2[1];
var elem = elemKey ? dom[elemKey][0] : dom.el[0];
var eventHandler = handlers[eventElKey];
elem.addEventListener(eventKey, eventHandler);
});
},
mergeProps: function mergeProps(defaultProps) {
var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var mergedProps = {};
Object.keys(defaultProps).forEach(function (propKey) {
var propValue = props[propKey] || defaultProps[propKey];
mergedProps[propKey] = propValue;
});
return mergedProps;
},
validateProps: function validateProps(props, requiredProps) {
Object.keys(props).forEach(function (propKey) {
if (requiredProps.indexOf(propKey) > -1 && !props[propKey]) {
throw new Error(moduleName + ' requires prop: ' + propKey);
}
});
}
};
var moduleProto = {
moduleConstructor: function moduleConstructor(opts) {
moduleProto.prepModule(opts);
moduleProto.buildModule(opts);
moduleProto.setupModule(opts);
moduleProto.renderModule(opts);
moduleProto.initModule(opts);
},
prepModule: function prepModule(opts) {
var context = moduleUtils.createContext();
if (moduleProps) {
var mergedProps = moduleUtils.mergeProps(moduleProps, opts.props);
context.extendWith({ props: mergedProps });
if (moduleRequiredProps) {
moduleUtils.validateProps(mergedProps, moduleRequiredProps);
}
}
opts.context = context;
},
buildModule: function buildModule(opts) {
var context = opts.context;
var boundMethods = moduleUtils.bindMethods(moduleMethods, context);
if (boundMethods.render) {
boundMethods.render = moduleUtils.wrapRenderMethod(boundMethods.render, opts);
}
context.extendWith(boundMethods);
context.extendWith({ mediator: opts.mediator });
},
setupModule: function setupModule(opts) {
var context = opts.context;
if (context.setup) {
context.setup();
}
if (moduleHandlers) {
moduleUtils.registerHandlers(opts.mediator, moduleHandlers, context);
}
},
renderModule: function renderModule(opts) {
var context = opts.context;
var mergedDom = void 0;
if (context.render) {
return;
}
if (moduleDom) {
mergedDom = moduleUtils.mergeDom(moduleDom, opts.dom);
moduleUtils.getDom(mergedDom);
context.extendWith({ dom: mergedDom });
}
if (moduleHandlers.domEvents) {
moduleUtils.registerDomHandlers(moduleHandlers.domEvents, context);
}
},
initModule: function initModule(opts) {
var context = opts.context;
if (context.init) {
context.init();
}
},
destroyModule: function destroyModule() {}
};
return moduleProto.moduleConstructor;
};
var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
function createCommonjsModule(fn, module) {
return module = { exports: {} }, fn(module, module.exports), module.exports;
}
var utils = createCommonjsModule(function (module, exports) {
'use strict';
exports.__esModule = true;
exports.extend = extend;
exports.indexOf = indexOf;
exports.escapeExpression = escapeExpression;
exports.isEmpty = isEmpty;
exports.createFrame = createFrame;
exports.blockParams = blockParams;
exports.appendContextPath = appendContextPath;
var escape = {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": ''',
'`': '`',
'=': '='
};
var badChars = /[&<>"'`=]/g,
possible = /[&<>"'`=]/;
function escapeChar(chr) {
return escape[chr];
}
function extend(obj /* , ...source */) {
for (var i = 1; i < arguments.length; i++) {
for (var key in arguments[i]) {
if (Object.prototype.hasOwnProperty.call(arguments[i], key)) {
obj[key] = arguments[i][key];
}
}
}
return obj;
}
var toString = Object.prototype.toString;
exports.toString = toString;
// Sourced from lodash
// https://github.com/bestiejs/lodash/blob/master/LICENSE.txt
/* eslint-disable func-style */
var isFunction = function isFunction(value) {
return typeof value === 'function';
};
// fallback for older versions of Chrome and Safari
/* istanbul ignore next */
if (isFunction(/x/)) {
exports.isFunction = isFunction = function (value) {
return typeof value === 'function' && toString.call(value) === '[object Function]';
};
}
exports.isFunction = isFunction;
/* eslint-enable func-style */
/* istanbul ignore next */
var isArray = Array.isArray || function (value) {
return value && typeof value === 'object' ? toString.call(value) === '[object Array]' : false;
};
exports.isArray = isArray;
// Older IE versions do not directly support indexOf so we must implement our own, sadly.
function indexOf(array, value) {
for (var i = 0, len = array.length; i < len; i++) {
if (array[i] === value) {
return i;
}
}
return -1;
}
function escapeExpression(string) {
if (typeof string !== 'string') {
// don't escape SafeStrings, since they're already safe
if (string && string.toHTML) {
return string.toHTML();
} else if (string == null) {
return '';
} else if (!string) {
return string + '';
}
// Force a string conversion as this will be done by the append regardless and
// the regex test will do this transparently behind the scenes, causing issues if
// an object's to string has escaped characters in it.
string = '' + string;
}
if (!possible.test(string)) {
return string;
}
return string.replace(badChars, escapeChar);
}
function isEmpty(value) {
if (!value && value !== 0) {
return true;
} else if (isArray(value) && value.length === 0) {
return true;
} else {
return false;
}
}
function createFrame(object) {
var frame = extend({}, object);
frame._parent = object;
return frame;
}
function blockParams(params, ids) {
params.path = ids;
return params;
}
function appendContextPath(contextPath, id) {
return (contextPath ? contextPath + '.' : '') + id;
}
});
var exception = createCommonjsModule(function (module, exports) {
'use strict';
exports.__esModule = true;
var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack'];
function Exception(message, node) {
var loc = node && node.loc,
line = undefined,
column = undefined;
if (loc) {
line = loc.start.line;
column = loc.start.column;
message += ' - ' + line + ':' + column;
}
var tmp = Error.prototype.constructor.call(this, message);
// Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work.
for (var idx = 0; idx < errorProps.length; idx++) {
this[errorProps[idx]] = tmp[errorProps[idx]];
}
/* istanbul ignore else */
if (Error.captureStackTrace) {
Error.captureStackTrace(this, Exception);
}
try {
if (loc) {
this.lineNumber = line;
// Work around issue under safari where we can't directly set the column value
/* istanbul ignore next */
if (Object.defineProperty) {
Object.defineProperty(this, 'column', {
value: column,
enumerable: true
});
} else {
this.column = column;
}
}
} catch (nop) {
/* Ignore if the browser is very particular */
}
}
Exception.prototype = new Error();
exports['default'] = Exception;
module.exports = exports['default'];
});
var blockHelperMissing = createCommonjsModule(function (module, exports) {
'use strict';
exports.__esModule = true;
exports['default'] = function (instance) {
instance.registerHelper('blockHelperMissing', function (context, options) {
var inverse = options.inverse,
fn = options.fn;
if (context === true) {
return fn(this);
} else if (context === false || context == null) {
return inverse(this);
} else if (utils.isArray(context)) {
if (context.length > 0) {
if (options.ids) {
options.ids = [options.name];
}
return instance.helpers.each(context, options);
} else {
return inverse(this);
}
} else {
if (options.data && options.ids) {
var data = utils.createFrame(options.data);
data.contextPath = utils.appendContextPath(options.data.contextPath, options.name);
options = { data: data };
}
return fn(context, options);
}
});
};
module.exports = exports['default'];
});
var each = createCommonjsModule(function (module, exports) {
'use strict';
exports.__esModule = true;
// istanbul ignore next
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
var _exception2 = _interopRequireDefault(exception);
exports['default'] = function (instance) {
instance.registerHelper('each', function (context, options) {
if (!options) {
throw new _exception2['default']('Must pass iterator to #each');
}
var fn = options.fn,
inverse = options.inverse,
i = 0,
ret = '',
data = undefined,
contextPath = undefined;
if (options.data && options.ids) {
contextPath = utils.appendContextPath(options.data.contextPath, options.ids[0]) + '.';
}
if (utils.isFunction(context)) {
context = context.call(this);
}
if (options.data) {
data = utils.createFrame(options.data);
}
function execIteration(field, index, last) {
if (data) {
data.key = field;
data.index = index;
data.first = index === 0;
data.last = !!last;
if (contextPath) {
data.contextPath = contextPath + field;
}
}
ret = ret + fn(context[field], {
data: data,
blockParams: utils.blockParams([context[field], field], [contextPath + field, null])
});
}
if (context && typeof context === 'object') {
if (utils.isArray(context)) {
for (var j = context.length; i < j; i++) {
if (i in context) {
execIteration(i, i, i === context.length - 1);
}
}
} else {
var priorKey = undefined;
for (var key in context) {
if (context.hasOwnProperty(key)) {
// We're running the iterations one step out of sync so we can detect
// the last iteration without have to scan the object twice and create
// an itermediate keys array.
if (priorKey !== undefined) {
execIteration(priorKey, i - 1);
}
priorKey = key;
i++;
}
}
if (priorKey !== undefined) {
execIteration(priorKey, i - 1, true);
}
}
}
if (i === 0) {
ret = inverse(this);
}
return ret;
});
};
module.exports = exports['default'];
});
var helperMissing = createCommonjsModule(function (module, exports) {
'use strict';
exports.__esModule = true;
// istanbul ignore next
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
var _exception2 = _interopRequireDefault(exception);
exports['default'] = function (instance) {
instance.registerHelper('helperMissing', function () /* [args, ]options */{
if (arguments.length === 1) {
// A missing field in a {{foo}} construct.
return undefined;
} else {
// Someone is actually trying to call something, blow up.
throw new _exception2['default']('Missing helper: "' + arguments[arguments.length - 1].name + '"');
}
});
};
module.exports = exports['default'];
});
var _if = createCommonjsModule(function (module, exports) {
'use strict';
exports.__esModule = true;
exports['default'] = function (instance) {
instance.registerHelper('if', function (conditional, options) {
if (utils.isFunction(conditional)) {
conditional = conditional.call(this);
}
// Default behavior is to render the positive path if the value is truthy and not empty.
// The `includeZero` option may be set to treat the condtional as purely not empty based on the
// behavior of isEmpty. Effectively this determines if 0 is handled by the positive path or negative.
if (!options.hash.includeZero && !conditional || utils.isEmpty(conditional)) {
return options.inverse(this);
} else {
return options.fn(this);
}
});
instance.registerHelper('unless', function (conditional, options) {
return instance.helpers['if'].call(this, conditional, { fn: options.inverse, inverse: options.fn, hash: options.hash });
});
};
module.exports = exports['default'];
});
var log = createCommonjsModule(function (module, exports) {
'use strict';
exports.__esModule = true;
exports['default'] = function (instance) {
instance.registerHelper('log', function () /* message, options */{
var args = [undefined],
options = arguments[arguments.length - 1];
for (var i = 0; i < arguments.length - 1; i++) {
args.push(arguments[i]);
}
var level = 1;
if (options.hash.level != null) {
level = options.hash.level;
} else if (options.data && options.data.level != null) {
level = options.data.level;
}
args[0] = level;
instance.log.apply(instance, args);
});
};
module.exports = exports['default'];
});
var lookup = createCommonjsModule(function (module, exports) {
'use strict';
exports.__esModule = true;
exports['default'] = function (instance) {
instance.registerHelper('lookup', function (obj, field) {
return obj && obj[field];
});
};
module.exports = exports['default'];
});
var _with = createCommonjsModule(function (module, exports) {
'use strict';
exports.__esModule = true;
exports['default'] = function (instance) {
instance.registerHelper('with', function (context, options) {
if (utils.isFunction(context)) {
context = context.call(this);
}
var fn = options.fn;
if (!utils.isEmpty(context)) {
var data = options.data;
if (options.data && options.ids) {
data = utils.createFrame(options.data);
data.contextPath = utils.appendContextPath(options.data.contextPath, options.ids[0]);
}
return fn(context, {
data: data,
blockParams: utils.blockParams([context], [data && data.contextPath])
});
} else {
return options.inverse(this);
}
});
};
module.exports = exports['default'];
});
var helpers = createCommonjsModule(function (module, exports) {
'use strict';
exports.__esModule = true;
exports.registerDefaultHelpers = registerDefaultHelpers;
// istanbul ignore next
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
var _helpersBlockHelperMissing2 = _interopRequireDefault(blockHelperMissing);
var _helpersEach2 = _interopRequireDefault(each);
var _helpersHelperMissing2 = _interopRequireDefault(helperMissing);
var _helpersIf2 = _interopRequireDefault(_if);
var _helpersLog2 = _interopRequireDefault(log);
var _helpersLookup2 = _interopRequireDefault(lookup);
var _helpersWith2 = _interopRequireDefault(_with);
function registerDefaultHelpers(instance) {
_helpersBlockHelperMissing2['default'](instance);
_helpersEach2['default'](instance);
_helpersHelperMissing2['default'](instance);
_helpersIf2['default'](instance);
_helpersLog2['default'](instance);
_helpersLookup2['default'](instance);
_helpersWith2['default'](instance);
}
});
var inline = createCommonjsModule(function (module, exports) {
'use strict';
exports.__esModule = true;
exports['default'] = function (instance) {
instance.registerDecorator('inline', function (fn, props, container, options) {
var ret = fn;
if (!props.partials) {
props.partials = {};
ret = function (context, options) {
// Create a new partials stack frame prior to exec.
var original = container.partials;
container.partials = utils.extend({}, original, props.partials);
var ret = fn(context, options);
container.partials = original;
return ret;
};
}
props.partials[options.args[0]] = options.fn;
return ret;
});
};
module.exports = exports['default'];
});
var decorators = createCommonjsModule(function (module, exports) {
'use strict';
exports.__esModule = true;
exports.registerDefaultDecorators = registerDefaultDecorators;
// istanbul ignore next
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
var _decoratorsInline2 = _interopRequireDefault(inline);
function registerDefaultDecorators(instance) {
_decoratorsInline2['default'](instance);
}
});
var logger_1 = createCommonjsModule(function (module, exports) {
'use strict';
exports.__esModule = true;
var logger = {
methodMap: ['debug', 'info', 'warn', 'error'],
level: 'info',
// Maps a given level value to the `methodMap` indexes above.
lookupLevel: function lookupLevel(level) {
if (typeof level === 'string') {
var levelMap = utils.indexOf(logger.methodMap, level.toLowerCase());
if (levelMap >= 0) {
level = levelMap;
} else {
level = parseInt(level, 10);
}
}
return level;
},
// Can be overridden in the host environment
log: function log(level) {
level = logger.lookupLevel(level);
if (typeof console !== 'undefined' && logger.lookupLevel(logger.level) <= level) {
var method = logger.methodMap[level];
if (!console[method]) {
// eslint-disable-line no-console
method = 'log';
}
for (var _len = arguments.length, message = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
message[_key - 1] = arguments[_key];
}
console[method].apply(console, message); // eslint-disable-line no-console
}
}
};
exports['default'] = logger;
module.exports = exports['default'];
});
var base = createCommonjsModule(function (module, exports) {
'use strict';
exports.__esModule = true;
exports.HandlebarsEnvironment = HandlebarsEnvironment;
// istanbul ignore next
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
var _exception2 = _interopRequireDefault(exception);
var _logger2 = _interopRequireDefault(logger_1);
var VERSION = '4.0.10';
exports.VERSION = VERSION;
var COMPILER_REVISION = 7;
exports.COMPILER_REVISION = COMPILER_REVISION;
var REVISION_CHANGES = {
1: '<= 1.0.rc.2', // 1.0.rc.2 is actually rev2 but doesn't report it
2: '== 1.0.0-rc.3',
3: '== 1.0.0-rc.4',
4: '== 1.x.x',
5: '== 2.0.0-alpha.x',
6: '>= 2.0.0-beta.1',
7: '>= 4.0.0'
};
exports.REVISION_CHANGES = REVISION_CHANGES;
var objectType = '[object Object]';
function HandlebarsEnvironment(helpers$$1, partials, decorators$$1) {
this.helpers = helpers$$1 || {};
this.partials = partials || {};
this.decorators = decorators$$1 || {};
helpers.registerDefaultHelpers(this);
decorators.registerDefaultDecorators(this);
}
HandlebarsEnvironment.prototype = {
constructor: HandlebarsEnvironment,
logger: _logger2['default'],
log: _logger2['default'].log,
registerHelper: function registerHelper(name, fn) {
if (utils.toString.call(name) === objectType) {
if (fn) {
throw new _exception2['default']('Arg not supported with multiple helpers');
}
utils.extend(this.helpers, name);
} else {
this.helpers[name] = fn;
}
},
unregisterHelper: function unregisterHelper(name) {
delete this.helpers[name];
},
registerPartial: function registerPartial(name, partial) {
if (utils.toString.call(name) === objectType) {
utils.extend(this.partials, name);
} else {
if (typeof partial === 'undefined') {
throw new _exception2['default']('Attempting to register a partial called "' + name + '" as undefined');
}
this.partials[name] = partial;
}
},
unregisterPartial: function unregisterPartial(name) {
delete this.partials[name];
},
registerDecorator: function registerDecorator(name, fn) {
if (utils.toString.call(name) === objectType) {
if (fn) {
throw new _exception2['default']('Arg not supported with multiple decorators');
}
utils.extend(this.decorators, name);
} else {
this.decorators[name] = fn;
}
},
unregisterDecorator: function unregisterDecorator(name) {
delete this.decorators[name];
}
};
var log = _logger2['default'].log;
exports.log = log;
exports.createFrame = utils.createFrame;
exports.logger = _logger2['default'];
});
var safeString = createCommonjsModule(function (module, exports) {
// Build out our basic SafeString type
'use strict';
exports.__esModule = true;
function SafeString(string) {
this.string = string;
}
SafeString.prototype.toString = SafeString.prototype.toHTML = function () {
return '' + this.string;
};
exports['default'] = SafeString;
module.exports = exports['default'];
});
var runtime$1 = createCommonjsModule(function (module, exports) {
'use strict';
exports.__esModule = true;
exports.checkRevision = checkRevision;
exports.template = template;
exports.wrapProgram = wrapProgram;
exports.resolvePartial = resolvePartial;
exports.invokePartial = invokePartial;
exports.noop = noop;
// istanbul ignore next
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
// istanbul ignore next
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
var Utils = _interopRequireWildcard(utils);
var _exception2 = _interopRequireDefault(exception);
function checkRevision(compilerInfo) {
var compilerRevision = compilerInfo && compilerInfo[0] || 1,
currentRevision = base.COMPILER_REVISION;
if (compilerRevision !== currentRevision) {
if (compilerRevision < currentRevision) {
var runtimeVersions = base.REVISION_CHANGES[currentRevision],
compilerVersions = base.REVISION_CHANGES[compilerRevision];
throw new _exception2['default']('Template was precompiled with an older version of Handlebars than the current runtime. ' + 'Please update your precompiler to a newer version (' + runtimeVersions + ') or downgrade your runtime to an older version (' + compilerVersions + ').');
} else {
// Use the embedded version info since the runtime doesn't know about this revision yet
throw new _exception2['default']('Template was precompiled with a newer version of Handlebars than the current runtime. ' + 'Please update your runtime to a newer version (' + compilerInfo[1] + ').');
}
}
}
function template(templateSpec, env) {
/* istanbul ignore next */
if (!env) {
throw new _exception2['default']('No environment passed to template');
}
if (!templateSpec || !templateSpec.main) {
throw new _exception2['default']('Unknown template object: ' + typeof templateSpec);
}
templateSpec.main.decorator = templateSpec.main_d;
// Note: Using env.VM references rather than local var references throughout this section to allow
// for external users to override these as psuedo-supported APIs.
env.VM.checkRevision(templateSpec.compiler);
function invokePartialWrapper(partial, context, options) {
if (options.hash) {
context = Utils.extend({}, context, options.hash);
if (options.ids) {
options.ids[0] = true;
}
}
partial = env.VM.resolvePartial.call(this, partial, context, options);
var result = env.VM.invokePartial.call(this, partial, context, options);
if (result == null && env.compile) {
options.partials[options.name] = env.compile(partial, templateSpec.compilerOptions, env);
result = options.partials[options.name](context, options);
}
if (result != null) {
if (options.indent) {
var lines = result.split('\n');
for (var i = 0, l = lines.length; i < l; i++) {
if (!lines[i] && i + 1 === l) {
break;
}
lines[i] = options.indent + lines[i];
}
result = lines.join('\n');
}
return result;
} else {
throw new _exception2['default']('The partial ' + options.name + ' could not be compiled when running in runtime-only mode');
}
}
// Just add water
var container = {
strict: function strict(obj, name) {
if (!(name in obj)) {
throw new _exception2['default']('"' + name + '" not defined in ' + obj);
}
return obj[name];
},
lookup: function lookup(depths, name) {
var len = depths.length;
for (var i = 0; i < len; i++) {
if (depths[i] && depths[i][name] != null) {
return depths[i][name];
}
}
},
lambda: function lambda(current, context) {
return typeof current === 'function' ? current.call(context) : current;
},
escapeExpression: Utils.escapeExpression,
invokePartial: invokePartialWrapper,
fn: function fn(i) {
var ret = templateSpec[i];
ret.decorator = templateSpec[i + '_d'];
return ret;
},
programs: [],
program: function program(i, data, declaredBlockParams, blockParams, depths) {
var programWrapper = this.programs[i],
fn = this.fn(i);
if (data || depths || blockParams || declaredBlockParams) {
programWrapper = wrapProgram(this, i, fn, data, declaredBlockParams, blockParams, depths);
} else if (!programWrapper) {
programWrapper = this.programs[i] = wrapProgram(this, i, fn);
}
return programWrapper;
},
data: function data(value, depth) {
while (value && depth--) {
value = value._parent;
}
return value;
},
merge: function merge(param, common) {
var obj = param || common;
if (param && common && param !== common) {
obj = Utils.extend({}, common, param);
}
return obj;
},
// An empty object to use as replacement for null-contexts
nullContext: Object.seal({}),
noop: env.VM.noop,
compilerInfo: templateSpec.compiler
};
function ret(context) {
var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
var data = options.data;
ret._setup(options);
if (!options.partial && templateSpec.useData) {
data = initData(context, data);
}
var depths = undefined,
blockParams = templateSpec.useBlockParams ? [] : undefined;
if (templateSpec.useDepths) {
if (options.depths) {
depths = context != options.depths[0] ? [context].concat(options.depths) : options.depths;
} else {
depths = [context];
}
}
function main(context /*, options*/) {
return '' + templateSpec.main(container, context, container.helpers, container.partials, data, blockParams, depths);
}
main = executeDecorators(templateSpec.main, main, container, options.depths || [], data, blockParams);
return main(context, options);
}
ret.isTop = true;
ret._setup = function (options) {
if (!options.partial) {
container.helpers = container.merge(options.helpers, env.helpers);
if (templateSpec.usePartial) {
container.partials = container.merge(options.partials, env.partials);
}
if (templateSpec.usePartial || templateSpec.useDecorators) {
container.decorators = container.merge(options.decorators, env.decorators);
}
} else {
container.helpers = options.helpers;
container.partials = options.partials;
container.decorators = options.decorators;
}
};
ret._child = function (i, data, blockParams, depths) {
if (templateSpec.useBlockParams && !blockParams) {
throw new _exception2['default']('must pass block params');
}
if (templateSpec.useDepths && !depths) {
throw new _exception2['default']('must pass parent depths');
}
return wrapProgram(container, i, templateSpec[i], data, 0, blockParams, depths);
};
return ret;
}
function wrapProgram(container, i, fn, data, declaredBlockParams, blockParams, depths) {
function prog(context) {
var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
var currentDepths = depths;
if (depths && context != depths[0] && !(context === container.nullContext && depths[0] === null)) {
currentDepths = [context].concat(depths);
}
return fn(container, context, container.helpers, container.partials, options.data || data, blockParams && [options.blockParams].concat(blockParams), currentDepths);
}
prog = executeDecorators(fn, prog, container, depths, data, blockParams);
prog.program = i;
prog.depth = depths ? depths.length : 0;
prog.blockParams = declaredBlockParams || 0;
return prog;
}
function resolvePartial(partial, context, options) {
if (!partial) {
if (options.name === '@partial-block') {
partial = options.data['partial-block'];
} else {
partial = options.partials[options.name];
}
} else if (!partial.call && !options.name) {
// This is a dynamic partial that returned a string
options.name = partial;
partial = options.partials[partial];
}
return partial;
}
function invokePartial(partial, context, options) {
// Use the current closure context to save the partial-block if this partial
var currentPartialBlock = options.data && options.data['partial-block'];
options.partial = true;
if (options.ids) {
options.data.contextPath = options.ids[0] || options.data.contextPath;
}
var partialBlock = undefined;
if (options.fn && options.fn !== noop) {
(function () {
options.data = base.createFrame(options.data);
// Wrapper function to get access to currentPartialBlock from the closure
var fn = options.fn;
partialBlock = options.data['partial-block'] = function partialBlockWrapper(context) {
var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
// Restore the partial-block from the closure for the execution of the block
// i.e. the part inside the block of the partial call.
options.data = base.createFrame(options.data);
options.data['partial-block'] = currentPartialBlock;
return fn(context, options);
};
if (fn.partials) {
options.partials = Utils.extend({}, options.partials, fn.partials);
}
})();
}
if (partial === undefined && partialBlock) {
partial = partialBlock;
}
if (partial === undefined) {
throw new _exception2['default']('The partial ' + options.name + ' could not be found');
} else if (partial instanceof Function) {
return partial(context, options);
}
}
function noop() {
return '';
}
function initData(context, data) {
if (!data || !('root' in data)) {
data = data ? base.createFrame(data) : {};
data.root = context;
}
return data;
}
function executeDecorators(fn, prog, container, depths, data, blockParams) {
if (fn.decorator) {
var props = {};
prog = fn.decorator(prog, props, container, depths && depths[0], data, blockParams, depths);
Utils.extend(prog, props);
}
return prog;
}
});
var noConflict = createCommonjsModule(function (module, exports) {
/* global window */
'use strict';
exports.__esModule = true;
exports['default'] = function (Handlebars) {
/* istanbul ignore next */
var root = typeof commonjsGlobal !== 'undefined' ? commonjsGlobal : window,
$Handlebars = root.Handlebars;
/* istanbul ignore next */
Handlebars.noConflict = function () {
if (root.Handlebars === Handlebars) {
root.Handlebars = $Handlebars;
}
return Handlebars;
};
};
module.exports = exports['default'];
});
var handlebars_runtime = createCommonjsModule(function (module, exports) {
'use strict';
exports.__esModule = true;
// istanbul ignore next
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
// istanbul ignore next
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
var base$$1 = _interopRequireWildcard(base);
// Each of these augment the Handlebars object. No need to setup here.
// (This is done to easily share code between commonjs and browse envs)
var _handlebarsSafeString2 = _interopRequireDefault(safeString);
var _handlebarsException2 = _interopRequireDefault(exception);
var Utils = _interopRequireWildcard(utils);
var runtime = _interopRequireWildcard(runtime$1);
var _handlebarsNoConflict2 = _interopRequireDefault(noConflict);
// For compatibility and usage outside of module systems, make the Handlebars object a namespace
function create() {
var hb = new base$$1.HandlebarsEnvironment();
Utils.extend(hb, base$$1);
hb.SafeString = _handlebarsSafeString2['default'];
hb.Exception = _handlebarsException2['default'];
hb.Utils = Utils;
hb.escapeExpression = Utils.escapeExpression;
hb.VM = runtime;
hb.template = function (spec) {
return runtime.template(spec, hb);
};
return hb;
}
var inst = create();
inst.create = create;
_handlebarsNoConflict2['default'](inst);
inst['default'] = inst;
exports['default'] = inst;
module.exports = exports['default'];
});
// Create a simple path alias to allow browserify to resolve
// the runtime on a supported path.
var runtime = handlebars_runtime['default'];
var Template = runtime.template({ "compiler": [7, ">= 4.0.0"], "main": function main(container, depth0, helpers, partials, data) {
return "\n \n\n";
}, "useData": true });
var linkIcon = function (data, options, asString) {
var html = Template(data, options);
return asString || typeof $ === 'undefined' ? html : $(html);
};
var Template$1 = runtime.template({ "compiler": [7, ">= 4.0.0"], "main": function main(container, depth0, helpers, partials, data) {
return "\n \n\n";
}, "useData": true });
var orderedlistIcon = function (data, options, asString) {
var html = Template$1(data, options);
return asString || typeof $ === 'undefined' ? html : $(html);
};
var Template$2 = runtime.template({ "compiler": [7, ">= 4.0.0"], "main": function main(container, depth0, helpers, partials, data) {
return "\n \n\n";
}, "useData": true });
var unorderedlistIcon = function (data, options, asString) {
var html = Template$2(data, options);
return asString || typeof $ === 'undefined' ? html : $(html);
};
var Template$3 = runtime.template({ "compiler": [7, ">= 4.0.0"], "main": function main(container, depth0, helpers, partials, data) {
return "\n \n\n";
}, "useData": true });
var quoteIcon = function (data, options, asString) {
var html = Template$3(data, options);
return asString || typeof $ === 'undefined' ? html : $(html);
};
// jshint strict: false
var Toolbar$2 = {
buttons: ['bold', 'italic', 'h1', 'h2', 'orderedlist', 'unorderedlist', 'quote', 'link'],
preventNewlineDefault: ['ul', 'ol'],
blockTags: ['P'],
validTags: ['P'],
listTags: [],
getValidTags: function getValidTags() {
var validTags = Toolbar$2.validTags;
if (validTags.length === 1) {
Toolbar$2.parseForTagLists();
}
return Toolbar$2.validTags;
},
getBlockTags: function getBlockTags() {
var blockTags = Toolbar$2.blockTags;
if (blockTags.length === 1) {
Toolbar$2.parseForTagLists();
}
return Toolbar$2.blockTags;
},
getListTags: function getListTags() {
var listTags = Toolbar$2.listTags;
if (listTags.length === 0) {
Toolbar$2.parseForTagLists();
}
return Toolbar$2.listTags;
},
parseForTagLists: function parseForTagLists() {
var validTags = Toolbar$2.validTags,
blockTags = Toolbar$2.blockTags,
listTags = Toolbar$2.listTags;
Toolbar$2.buttons.forEach(function (buttonKey) {
var buttonConfig = Toolbar$2.buttonConfigs[buttonKey];
var configValidTags = buttonConfig.opts.validTags;
validTags = validTags.concat(configValidTags);
switch (buttonConfig.formatter) {
case 'block':
blockTags = blockTags.concat(configValidTags);
break;
case 'list':
listTags = listTags.concat(configValidTags);
break;
}
});
Toolbar$2.validTags = validTags;
Toolbar$2.blockTags = blockTags;
Toolbar$2.listTags = listTags;
},
buttonConfigs: {
// Text styles
bold: {
formatter: 'text',
opts: {
style: 'bold',
rootEl: 'b',
validTags: ['B', 'STRONG']
},
content: 'B',
disabledIn: ['H1', 'H2', 'BLOCKQUOTE'],
activeIn: ['B']
},
italic: {
formatter: 'text',
opts: {
style: 'italic',
rootEl: 'i',
validTags: ['I']
},
content: 'I',
activeIn: ['I']
},
underline: {
formatter: 'text:underline',
content: 'U'
},
strikethrough: {
formatter: 'text:strikethrough',
content: 'A'
},
superscript: {
formatter: 'text:superscript',
content: 'x1'
},
subscript: {
formatter: 'text:subscript',
content: 'x1'
},
// Paragraph styles
justifyCenter: {
formatter: 'paragraph:justifyCenter'
},
justifyFull: {
formatter: 'paragraph:justifyFull'
},
justifyLeft: {
formatter: 'paragraph:justifyLeft'
},
justifyRight: {
formatter: 'paragraph:justifyRight'
},
indent: {
formatter: 'paragraph:indent'
},
outdent: {
formatter: 'paragraph:outdent'
},
// Lists
orderedlist: {
formatter: 'list',
content: orderedlistIcon({}, {}, true),
opts: {
style: 'ordered',
validTags: ['OL', 'LI']
},
activeIn: ['OL']
},
unorderedlist: {
formatter: 'list',
content: unorderedlistIcon({}, {}, true),
opts: {
style: 'unordered',
validTags: ['UL', 'LI']
},
activeIn: ['UL']
},
// Block level elements
quote: {
formatter: 'block',
content: quoteIcon({}, {}, true),
opts: {
style: 'BLOCKQUOTE',
validTags: ['BLOCKQUOTE']
},
activeIn: ['BLOCKQUOTE'],
disabledIn: function disabledIn(mediator) {
var disabled = mediator.get('selection:in:or:contains', ['OL', 'UL']);
disabled = disabled || mediator.get('selection:spans:multiple:blocks');
return disabled;
},
toggles: true
},
pre: {
formatter: 'block',
opts: {
style: 'PRE'
},
disabledIn: function disabledIn(mediator) {
var disabled = mediator.get('selection:in:or:contains', ['OL', 'UL']);
disabled = disabled || mediator.get('selection:spans:multiple:blocks');
return disabled;
},
content: 'PRE'
},
h1: {
formatter: 'block',
opts: {
style: 'H1',
validTags: ['H1']
},
content: 'H1',
activeIn: ['H1'],
disabledIn: function disabledIn(mediator) {
var disabled = mediator.get('selection:in:or:contains', ['OL', 'UL']);
disabled = disabled || mediator.get('selection:spans:multiple:blocks');
return disabled;
},
toggles: true
},
h2: {
formatter: 'block',
opts: {
style: 'H2',
validTags: ['H2']
},
content: 'H2',
activeIn: ['H2'],
disabledIn: function disabledIn(mediator) {
var disabled = mediator.get('selection:in:or:contains', ['OL', 'UL']);
disabled = disabled || mediator.get('selection:spans:multiple:blocks');
return disabled;
},
toggles: true
},
h3: {
formatter: 'block',
opts: {
style: 'H3',
validTags: ['H3']
},
content: 'H3',
activeIn: ['H3'],
disabledIn: function disabledIn(mediator) {
var disabled = mediator.get('selection:in:or:contains', ['OL', 'UL']);
disabled = disabled || mediator.get('selection:spans:multiple:blocks');
return disabled;
},
toggles: true
},
h4: {
formatter: 'block',
opts: {
style: 'H4',
validTags: ['H4']
},
content: 'H4',
activeIn: ['H4'],
disabledIn: function disabledIn(mediator) {
var disabled = mediator.get('selection:in:or:contains', ['OL', 'UL']);
disabled = disabled || mediator.get('selection:spans:multiple:blocks');
return disabled;
},
toggles: true
},
h5: {
formatter: 'block',
opts: {
style: 'H5',
validTags: ['H5']
},
content: 'H5',
activeIn: ['H5'],
disabledIn: function disabledIn(mediator) {
var disabled = mediator.get('selection:in:or:contains', ['OL', 'UL']);
disabled = disabled || mediator.get('selection:spans:multiple:blocks');
return disabled;
},
toggles: true
},
h6: {
formatter: 'block',
opts: {
style: 'H6',
validTags: ['H6']
},
content: 'H6',
activeIn: ['H6'],
disabledIn: function disabledIn(mediator) {
var disabled = mediator.get('selection:in:or:contains', ['OL', 'UL']);
disabled = disabled || mediator.get('selection:spans:multiple:blocks');
return disabled;
},
toggles: true
},
// Link
link: {
formatter: 'link',
opts: {
validTags: ['A']
},
content: linkIcon({}, {}, true),
activeIn: ['A'],
disabledIn: function disabledIn(mediator) {
var disabled = mediator.get('selection:spans:multiple:blocks');
return disabled;
}
}
}
};
var Template$4 = runtime.template({ "1": function _(container, depth0, helpers, partials, data, blockParams) {
var stack1, helper;
return "
\n \n \n";
}, "compiler": [7, ">= 4.0.0"], "main": function main(container, depth0, helpers, partials, data, blockParams) {
var stack1;
return "\n";
}, "useData": true, "useBlockParams": true });
var toolbarTemplate = function (data, options, asString) {
var html = Template$4(data, options);
return asString || typeof $ === 'undefined' ? html : $(html);
};
var toolbarStyles = ".typester-toolbar .buttons-wrapper,\n.typester-toolbar .inputs-wrapper {\n transition: opacity 200ms, -webkit-transform 200ms;\n transition: opacity 200ms, transform 200ms;\n transition: opacity 200ms, transform 200ms, -webkit-transform 200ms;\n -webkit-transform: translateY(-40px);\n transform: translateY(-40px);\n opacity: 0; }\n .typester-toolbar .buttons-wrapper.s--active,\n .typester-toolbar .inputs-wrapper.s--active {\n -webkit-transform: translateY(0px);\n transform: translateY(0px);\n opacity: 1; }\n\n.typester-toolbar .inputs-wrapper {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%; }\n\n.typester-toolbar ul {\n overflow: hidden;\n list-style: none; }\n\n.typester-toolbar li {\n float: left;\n list-style: none; }\n\n.typester-toolbar .typester-menu-item {\n color: #FFF;\n font-family: sans-serif;\n font-size: 16px;\n width: 40px;\n height: 40px;\n display: block;\n line-height: 40px;\n font-weight: bold;\n text-align: center;\n cursor: pointer;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none; }\n .typester-toolbar .typester-menu-item svg {\n display: block;\n fill: #FFF;\n height: 16px;\n width: 16px;\n padding: 12px; }\n .typester-toolbar .typester-menu-item b {\n font-weight: bold; }\n .typester-toolbar .typester-menu-item i {\n font-style: italic; }\n .typester-toolbar .typester-menu-item:hover {\n background: #00aeef; }\n .typester-toolbar .typester-menu-item.s--active {\n background: #0089bc; }\n .typester-toolbar .typester-menu-item[disabled] {\n width: 0;\n overflow: hidden; }\n";
// jshint strict: false
var Toolbar = Module({
name: 'Toolbar',
dom: {
'toolbarMenuItems': '.typester-menu-item'
},
props: {
el: null,
styles: null,
mouseover: 0,
classNames: {
MENU_ITEM: 'typester-menu-item',
ACTIVE: 's--active'
}
},
handlers: {
commands: {
'toolbar:hide': 'hideToolbar',
'toolbar:set:buttons': 'setButtons'
},
events: {
// 'contenteditable:focus': 'showToolbar',
'app:destroy': 'destroy',
'selection:update': 'handleSelectionChange',
// 'selection:start' : 'handleSelectStart',
'selection:change': 'handleSelectionChange',
'mouse:down': 'handleMouseDown',
'mouse:up': 'handleMouseUp',
'import:from:canvas:complete': 'handleCanvasImport'
},
domEvents: {
'click': 'handleToolbarClick',
'mouseover': 'handleMouseOver',
'mouseout': 'handleMouseOut'
}
},
methods: {
setup: function setup() {
this.appendStyles();
this.render();
},
init: function init() {
this.updateToolbarState();
},
appendStyles: function appendStyles() {
var props = this.props;
props.styles = DOM.addStyles(toolbarStyles);
},
render: function render() {
var mediator = this.mediator,
props = this.props;
var buttonConfigs = this.getButtonConfigs();
var wrapperEl = document.createElement('div');
var toolbarHTML = toolbarTemplate(buttonConfigs);
if (typeof toolbarHTML === 'string') {
wrapperEl.innerHTML = toolbarHTML;
} else {
wrapperEl.appendChild(toolbarHTML[0]);
}
var toolbarEl = wrapperEl.childNodes[0];
props.flyout = props.flyout || mediator.get('flyout:new');
props.flyout.clearContent();
props.flyout.show();
props.flyout.appendContent(wrapperEl.childNodes[0]);
return toolbarEl;
},
getButtonConfigs: function getButtonConfigs() {
var mediator = this.mediator;
var contentEditableButtons = mediator.get('contenteditable:toolbar:buttons') || [];
var configButtons = contentEditableButtons.length ? contentEditableButtons : Toolbar$2.buttons;
var buttons = [];
configButtons.forEach(function (configKey) {
// NB This needs to be looked at
if (configKey === 'anchor') {
configKey = 'link';
}
var buttonConfig = Object.assign({ configKey: configKey }, Toolbar$2.buttonConfigs[configKey]);
buttons.push(buttonConfig);
});
return { buttons: buttons };
},
handleToolbarClick: function handleToolbarClick(evnt) {
var mediator = this.mediator,
props = this.props;
mediator.exec('contenteditable:refocus');
mediator.exec('selection:reselect');
var menuItemEl = DOM.getClosest(evnt.target, '.' + props.classNames.MENU_ITEM);
var dataset = menuItemEl.dataset;
var configKey = dataset.configKey;
var buttonConfig = Toolbar$2.buttonConfigs[configKey];
var formatter = buttonConfig.formatter,
opts = buttonConfig.opts;
var toolbarMenuItemState = this.getMenuItemState(menuItemEl);
opts.toggle = buttonConfig.toggles && toolbarMenuItemState.isActive;
mediator.exec('format:' + formatter, opts);
},
// handleSelectStart () {
// this.hideToolbar();
// },
handleSelectionChange: function handleSelectionChange() {
var _this = this;
var props = this.props;
if (props.selectionChangeTimeout) {
clearTimeout(props.selectionChangeTimeout);
}
props.selectionChangeTimeout = setTimeout(function () {
_this.updateToolbarState();
}, 10);
},
handleMouseDown: function handleMouseDown() {
this.updateToolbarState();
},
handleMouseUp: function handleMouseUp() {
this.updateToolbarState();
},
handleMouseOver: function handleMouseOver() {
var props = this.props;
props.mouseover += 1;
props.mouseover = Math.min(1, props.mouseover);
},
handleMouseOut: function handleMouseOut() {
var props = this.props;
props.mouseover -= 1;
props.mouseover = Math.max(0, props.mouseover);
},
handleCanvasImport: function handleCanvasImport() {
this.updateToolbarState();
},
hideToolbar: function hideToolbar() {
var props = this.props;
props.flyout.hide();
},
showToolbar: function showToolbar() {
this.render();
},
positionToolbar: function positionToolbar() {
var mediator = this.mediator,
props = this.props;
var selectionBounds = mediator.get('selection:bounds');
if (selectionBounds.initialWidth > 0) {
var scrollOffset = DOM.getScrollOffset();
var docRelTop = selectionBounds.top + scrollOffset.y;
var docRelLeft = selectionBounds.initialLeft + scrollOffset.x;
var docRelCenter = selectionBounds.initialWidth / 2 + docRelLeft;
props.flyout.position({
left: docRelCenter + 'px',
top: docRelTop + 'px'
});
}
},
updateToolbarState: function updateToolbarState() {
var mediator = this.mediator,
props = this.props;
var currentSelection = mediator.get('selection:current');
var linkFormatterActive = mediator.get('format:link:active');
var mouseIsDown = mediator.get('mouse:is:down');
if (!currentSelection || currentSelection.isCollapsed || !currentSelection.toString().trim().length || linkFormatterActive || !document.activeElement.hasAttribute('contenteditable') || mouseIsDown) {
if (props.mouseover) {
return;
}
this.hideToolbar();
} else {
this.positionToolbar();
this.showToolbar();
this.updateMenuItems();
}
},
updateMenuItems: function updateMenuItems() {
var dom = this.dom,
mediator = this.mediator;
mediator.exec('selection:ensure:text:only');
for (var i = 0; i < dom.toolbarMenuItems.length; i++) {
var toolbarMenuItem = dom.toolbarMenuItems[i];
this.updateMenuItemState(toolbarMenuItem);
}
},
updateMenuItemState: function updateMenuItemState(toolbarMenuItem) {
var props = this.props;
var toolbarMenuItemState = this.getMenuItemState(toolbarMenuItem);
if (toolbarMenuItemState.isDisabled) {
toolbarMenuItem.setAttribute('disabled', '');
} else {
toolbarMenuItem.removeAttribute('disabled');
}
DOM.toggleClass(toolbarMenuItem, props.classNames.ACTIVE, toolbarMenuItemState.isActive);
},
getMenuItemState: function getMenuItemState(toolbarMenuItem) {
var mediator = this.mediator;
var configKey = toolbarMenuItem.dataset.configKey;
var config = Toolbar$2.buttonConfigs[configKey];
var activeIn = config.activeIn || [];
var disabledIn = config.disabledIn || [];
var isActive = mediator.get('selection:in:or:contains', activeIn);
var isDisabled = false;
if (typeof disabledIn === 'function') {
isDisabled = disabledIn.call(config, mediator);
} else {
isDisabled = mediator.get('selection:in:or:contains', disabledIn);
}
return {
isActive: isActive,
isDisabled: isDisabled
};
},
destroy: function destroy() {
var props = this.props;
props.flyout.remove();
}
}
});
var Template$5 = runtime.template({ "compiler": [7, ">= 4.0.0"], "main": function main(container, depth0, helpers, partials, data) {
var stack1, helper;
return "\n
\n " + ((stack1 = (helper = (helper = helpers.content || (depth0 != null ? depth0.content : depth0)) != null ? helper : helpers.helperMissing, typeof helper === "function" ? helper.call(depth0 != null ? depth0 : container.nullContext || {}, { "name": "content", "hash": {}, "data": data }) : helper)) != null ? stack1 : "") + "\n
\n
\n";
}, "useData": true });
var flyoutTemplate = function (data, options, asString) {
var html = Template$5(data, options);
return asString || typeof $ === 'undefined' ? html : $(html);
};
var flyoutStyles = ".typester-flyout {\n transition: top 200ms, left 200ms;\n position: absolute;\n z-index: 1600;\n top: 50%;\n left: 50%; }\n .typester-flyout .typester-flyout-content {\n background: #201f20;\n height: 40px;\n width: auto; }\n .typester-flyout .typester-flyout-content:after {\n content: '';\n position: absolute;\n left: 50%;\n height: 0;\n width: 0;\n border-left: 10px solid transparent;\n border-right: 10px solid transparent; }\n .typester-flyout.place-above {\n -webkit-transform: translate3d(-50%, -100%, 0);\n transform: translate3d(-50%, -100%, 0);\n padding-bottom: 12px; }\n .typester-flyout.place-above .typester-flyout-content:after {\n top: 100%;\n border-top: 10px solid #201f20;\n -webkit-transform: translate3d(-50%, -13px, 0);\n transform: translate3d(-50%, -13px, 0); }\n .typester-flyout.place-below {\n -webkit-transform: translate3d(-50%, 0, 0);\n transform: translate3d(-50%, 0, 0);\n padding-top: 12px; }\n .typester-flyout.place-below .typester-flyout-content:after {\n bottom: 100%;\n border-bottom: 10px solid #201f20;\n -webkit-transform: translate3d(-50%, 13px, 0);\n transform: translate3d(-50%, 13px, 0); }\n .typester-flyout a {\n color: #FFF; }\n";
// jshint strict: false
var Flyout = Module({
name: 'Flyout',
dom: {},
props: {
minZIndex: 90,
styles: null,
flyouts: []
},
handlers: {
requests: {
'flyout:new': 'newFlyout'
},
commands: {},
events: {
'app:destroy': 'destroy'
}
},
methods: {
setup: function setup() {
this.appendStyles();
},
init: function init() {},
appendStyles: function appendStyles() {
var props = this.props;
props.styles = DOM.addStyles(flyoutStyles);
},
newFlyout: function newFlyout() {
var props = this.props;
var flyout = this.buildFlyout();
props.flyouts.push(flyout);
return flyout;
},
buildFlyout: function buildFlyout() {
var _this = this;
var flyout = {
el: this.buildTemplate(),
appended: null
};
flyout.contentEl = flyout.el.querySelector('.typester-flyout-content');
flyout.clearContent = function () {
flyout.contentEl.innerHTML = '';
};
flyout.appendContent = function (content) {
return DOM.appendTo(flyout.contentEl, content);
};
flyout.show = function () {
_this.showFlyout(flyout);
};
flyout.remove = function () {
_this.removeFlyout(flyout);
};
flyout.hide = function () {
_this.hideFlyout(flyout);
};
flyout.position = function (coordinates) {
_this.positionFlyout(flyout, coordinates);
};
flyout.setPlacement = function (placement) {
_this.setPlacement(flyout, placement);
};
return flyout;
},
buildTemplate: function buildTemplate() {
var wrapperEl = document.createElement('div');
var flyoutHTML = void 0,
flyoutEl = void 0;
flyoutHTML = flyoutTemplate();
if (typeof flyoutHTML === 'string') {
wrapperEl.innerHTML = flyoutHTML;
} else {
wrapperEl.appendChild(flyoutHTML[0]);
}
flyoutEl = wrapperEl.childNodes[0];
return flyoutEl;
},
appendFlyout: function appendFlyout(flyout) {
DOM.appendTo(document.body, flyout.el);
},
removeFlyout: function removeFlyout(flyout) {
if (flyout.appended) {
DOM.removeNode(flyout.el);
flyout.appended = false;
}
},
positionFlyout: function positionFlyout(flyout, coordinates) {
var mediator = this.mediator,
props = this.props;
var contentEditableEl = mediator.get('contenteditable:element');
var containerZIndex = Math.max(props.minZIndex, DOM.getContainerZIndex(contentEditableEl));
console.log('positionFlyout', coordinates);
Object.keys(coordinates).forEach(function (coordinateKey) {
flyout.el.style[coordinateKey] = coordinates[coordinateKey];
});
flyout.el.style.zIndex = containerZIndex + 1;
},
setPlacement: function setPlacement(flyout) {
var placement = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'above';
flyout.el.classList.remove('place-below');
flyout.el.classList.remove('place-above');
flyout.el.classList.add('place-' + placement);
},
showFlyout: function showFlyout(flyout) {
if (!flyout.appended) {
this.appendFlyout(flyout);
flyout.appended = true;
} else {
flyout.el.style.display = 'block';
}
},
hideFlyout: function hideFlyout(flyout) {
flyout.el.style.display = 'none';
},
destroy: function destroy() {
var props = this.props;
props.flyouts.forEach(function (flyout) {
flyout.remove();
});
}
}
});
// jshint strict: false
var Mouse = Module({
name: 'Mouse',
props: {
mousedown: 0
},
dom: {},
handlers: {
requests: {
'mouse:is:down': 'mouseIsDown'
},
commands: {},
events: {
'contenteditable:blur': 'handleContentEditableBlur'
}
},
methods: {
init: function init() {
var _this = this;
var mediator = this.mediator;
document.body.onmousedown = function () {
_this.setMousedown();
mediator.emit('mouse:down');
};
document.body.onmouseup = function () {
_this.unsetMousedown();
mediator.emit('mouse:up');
};
// document.body.onmouseout = () => {
// props.mousedown = 0;
// };
},
setMousedown: function setMousedown() {
var props = this.props;
props.mousedown += 1;
props.mousedown = Math.min(1, props.mousedown);
},
unsetMousedown: function unsetMousedown() {
var props = this.props;
props.mousedown -= 1;
props.mousedown = Math.max(0, props.mousedown);
},
mouseIsDown: function mouseIsDown() {
var props = this.props;
return !!props.mousedown;
},
handleContentEditableBlur: function handleContentEditableBlur() {
var props = this.props;
props.mousedown = 0;
}
}
});
// jshint strict: false
var UIContainer = Container({
name: 'UIContainer',
modules: [{
class: Flyout
}, {
class: Toolbar,
opts: {
dom: {
el: document.body
}
}
}, {
class: Mouse
}]
});
var conf = {
commands: {
bold: {
tags: ['B', 'STRONG'],
togglable: true
},
italic: {
tags: ['I'],
togglable: true
},
formatBlock: {
tags: ['H1', 'H2', 'H3', 'H4', 'H5', 'H6', 'P', 'BLOCKQUOTE'],
unwrapIfIn: ['bold', 'formatBlock', 'insertOrderedList', 'insertUnorderedList']
},
insertOrderedList: {
tags: ['OL', 'LI'],
unwrapIfIn: ['formatBlock'],
togglable: true
},
insertUnorderedList: {
tags: ['UL', 'LI'],
unwrapIfIn: ['formatBlock'],
togglable: true
},
createLink: {
tags: ['A']
}
},
defaultBlock: 'P',
paste: {
invalidTags: ['SCRIPT', 'LINK', 'IMG']
},
global: {},
toolbar: {},
contentEditable: {}
};
// jshint strict: false
var commands = {
exec: function exec(command) {
var value = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
var contextDocument = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : document;
if (command === 'formatBlock') {
value = commands.prepBlockValue(value);
}
contextDocument.execCommand(command, false, value);
},
formatBlock: function formatBlock(style) {
var contextDocument = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : document;
commands.exec('formatBlock', style, contextDocument);
},
defaultBlockFormat: function defaultBlockFormat() {
var contextDocument = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : document;
commands.formatBlock(conf.defaultBlock, contextDocument);
},
prepBlockValue: function prepBlockValue(value) {
var ieVersion = browser.ieVersion();
value = value.toUpperCase();
return ieVersion && ieVersion < 12 ? '<' + value + '>' : value;
}
};
// jshint strict: false
var zeroWidthSpaceEntity = '​';
var zeroWidthSpace = {
generate: function generate() {
var tmpEl = document.createElement('span');
tmpEl.innerHTML = zeroWidthSpaceEntity;
return tmpEl;
},
get: function get() {
var tmpEl = zeroWidthSpace.generate();
return tmpEl.firstChild;
},
assert: function assert(node) {
var tmpEl = zeroWidthSpace.generate();
if (node.nodeType === Node.ELEMENT_NODE) {
return node.innerHTML === tmpEl.innerHTML;
} else if (node.nodeType === Node.TEXT_NODE) {
return node.nodeValue === tmpEl.firstChild.nodeValue;
}
}
};
// jshint strict: false
var validTags = Toolbar$2.getValidTags();
var blockTags = Toolbar$2.getBlockTags();
var listTags = Toolbar$2.getListTags();
var BaseFormatter = Module({
name: 'BaseFormatter',
props: {},
handlers: {
requests: {},
commands: {
'format:export:to:canvas': 'exportToCanvas',
'format:import:from:canvas': 'importFromCanvas',
'format:default': 'formatDefault',
'format:clean': 'formatClean'
},
events: {
'contenteditable:newline': 'handleNewLine'
}
},
methods: {
init: function init() {},
exportToCanvas: function exportToCanvas() {
var mediator = this.mediator;
var rootElement = mediator.get('selection:rootelement');
var canvasBody = mediator.get('canvas:body');
this.injectHooks(rootElement);
var rangeCoordinates = mediator.get('selection:range:coordinates');
var clonedNodes = this.cloneNodes(rootElement);
mediator.exec('canvas:content', clonedNodes);
mediator.exec('canvas:select:by:coordinates', rangeCoordinates);
this.removeZeroWidthSpaces(canvasBody);
},
cloneNodes: function cloneNodes(rootElement) {
var clonedNodes = [];
rootElement.childNodes.forEach(function (node) {
clonedNodes.push(node.cloneNode(true));
});
return clonedNodes;
},
injectHooks: function injectHooks(rootElement) {
while (!/\w+/.test(rootElement.firstChild.textContent)) {
DOM.removeNode(rootElement.firstChild);
}
while (!/\w+/.test(rootElement.lastChild.textContent)) {
DOM.removeNode(rootElement.lastChild);
}
DOM.insertBefore(zeroWidthSpace.get(), rootElement.firstChild);
DOM.insertAfter(zeroWidthSpace.get(), rootElement.lastChild);
},
importFromCanvas: function importFromCanvas() {
var opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var mediator = this.mediator;
var canvasBody = mediator.get('canvas:body');
mediator.exec('canvas:cache:selection');
mediator.exec('format:clean', canvasBody);
if (opts.importFilter) {
opts.importFilter(canvasBody);
}
mediator.exec('canvas:select:cachedSelection');
var canvasSelectionCoordinates = mediator.get('canvas:selection:coordinates');
mediator.exec('selection:select:all');
mediator.exec('contenteditable:inserthtml', canvasBody.innerHTML);
mediator.exec('selection:select:coordinates', canvasSelectionCoordinates);
mediator.emit('import:from:canvas:complete');
},
formatDefault: function formatDefault() {
var mediator = this.mediator;
var rootElem = mediator.get('selection:rootelement');
commands.defaultBlockFormat();
this.removeStyledSpans(rootElem);
},
formatEmptyNewLine: function formatEmptyNewLine() {
var mediator = this.mediator;
var anchorNode = mediator.get('selection:anchornode');
var canDefaultNewline = !(anchorNode.innerText && anchorNode.innerText.trim().length) && !DOM.isIn(anchorNode, Toolbar$2.preventNewlineDefault);
var anchorIsContentEditable = anchorNode.hasAttribute && anchorNode.hasAttribute('contenteditable');
if (canDefaultNewline || anchorIsContentEditable) {
this.formatDefault();
}
},
formateBlockquoteNewLine: function formateBlockquoteNewLine() {
var mediator = this.mediator;
commands.exec('outdent');
this.formatDefault();
var currentRangeClone = mediator.get('selection:range').cloneRange();
var startContainer = currentRangeClone.startContainer;
if (startContainer.previousSibling && startContainer.previousSibling.nodeName === 'BLOCKQUOTE') {
var brEls = startContainer.previousSibling.querySelectorAll('br');
var divEls = startContainer.previousSibling.querySelectorAll('div');
for (var i = 0; i < brEls.length; i++) {
DOM.removeNode(brEls[i]);
}
for (var _i = 0; _i < divEls.length; _i++) {
DOM.unwrap(divEls[_i]);
}
mediator.exec('selection:update:range', currentRangeClone);
}
},
handleNewLine: function handleNewLine() {
var mediator = this.mediator;
var _mediator$get = mediator.get('selection:range'),
startContainer = _mediator$get.startContainer;
var containerIsEmpty = !/\w+/.test(startContainer.textContent);
var containerIsBlockquote = DOM.isIn(startContainer, 'BLOCKQUOTE');
var isContentEditable = startContainer.nodeType === Node.ELEMENT_NODE && startContainer.hasAttribute('contenteditable');
if (containerIsBlockquote) {
this.formateBlockquoteNewLine();
} else if (containerIsEmpty || isContentEditable) {
this.formatEmptyNewLine();
}
},
formatClean: function formatClean(rootElem) {
this.unwrapInvalidElements(rootElem);
this.defaultOrphanedTextNodes(rootElem);
this.removeBrNodes(rootElem);
this.ensureRootElems(rootElem);
this.removeStyleAttributes(rootElem);
this.removeEmptyNodes(rootElem, { recursive: true });
// -----
// this.removeBrNodes(rootElem);
// // this.removeEmptyNodes(rootElem);
// this.removeFontTags(rootElem);
// this.removeStyledSpans(rootElem);
// this.clearEntities(rootElem);
// this.removeZeroWidthSpaces(rootElem);
// this.defaultOrphanedTextNodes(rootElem);
// this.removeEmptyNodes(rootElem, { recursive: true });
},
removeStyleAttributes: function removeStyleAttributes(rootElem) {
var styleAttributeNodes = rootElem.querySelectorAll('[style]');
styleAttributeNodes.forEach(function (styleAttributeNode) {
styleAttributeNode.removeAttribute('style');
});
},
removeBrNodes: function removeBrNodes(rootElem) {
var brNodes = rootElem.querySelectorAll('br');
var brNodesToProcess = [];
var brNodesToRemove = [];
brNodes.forEach(function (brNode) {
var skipNode = brNode.skipNode;
if (skipNode) {
return;
}
var isLastChild = brNode === brNode.parentNode.lastChild;
var isDoubleBreak = brNode.nextSibling && brNode.nextSibling.nodeName === 'BR';
var isInBlock = DOM.isIn(brNode, blockTags, rootElem);
if (isLastChild) {
brNodesToRemove.push(isLastChild);
return;
}
if (isDoubleBreak && isInBlock) {
brNodesToProcess.push([brNode, brNode.nextSibling]);
brNode.nextSibling.skipNode = true;
return;
}
});
brNodesToProcess.forEach(function (brNodePair) {
var _brNodePair = slicedToArray(brNodePair, 2),
firstBrNode = _brNodePair[0],
secondBrNode = _brNodePair[1];
var closestBlock = DOM.getClosestInArray(firstBrNode, blockTags, rootElem);
var newParagraph = document.createElement('p');
var previousSibling = void 0;
while (previousSibling = firstBrNode.previousSibling) {
if (newParagraph.firstChild) {
DOM.insertBefore(previousSibling, newParagraph.firstChild);
} else {
newParagraph.appendChild(previousSibling);
}
DOM.insertBefore(newParagraph, closestBlock);
}
DOM.removeNode(firstBrNode);
DOM.removeNode(secondBrNode);
});
brNodesToRemove.forEach(function (brNode) {
DOM.removeNode(brNode);
});
},
unwrapInvalidElements: function unwrapInvalidElements(rootElem) {
var rootDoc = rootElem.ownerDocument;
var walker = rootDoc.createTreeWalker(rootElem, NodeFilter.SHOW_ELEMENT, null, false);
var invalidElements = [];
while (walker.nextNode()) {
var currentNode = walker.currentNode;
var isInvalid = validTags.indexOf(currentNode.nodeName) < 0;
var isBrNode = currentNode.nodeName === 'BR'; // BR nodes are handled elsewhere
var isTypesterElem = currentNode.className && /typester/.test(currentNode.className);
if (isInvalid && !isBrNode && !isTypesterElem) {
invalidElements.unshift(currentNode);
}
}
invalidElements.forEach(function (invalidElement) {
var unwrappedNodes = DOM.unwrap(invalidElement, { keepNode: true });
if (!DOM.isIn(invalidElement, validTags, rootElem) && unwrappedNodes.length) {
var newParagraph = rootDoc.createElement('p');
unwrappedNodes.forEach(function (unwrappedNode) {
newParagraph.appendChild(unwrappedNode);
});
DOM.insertBefore(newParagraph, invalidElement);
}
DOM.removeNode(invalidElement);
});
},
defaultOrphanedTextNodes: function defaultOrphanedTextNodes(rootElem) {
var childNodes = rootElem.childNodes;
for (var i = 0; i < childNodes.length; i++) {
var childNode = childNodes[i];
if (childNode.nodeType === Node.TEXT_NODE && /\w+/.test(childNode.textContent)) {
var newParagraph = document.createElement('p');
DOM.insertBefore(newParagraph, childNode);
newParagraph.appendChild(childNode);
while (newParagraph.nextSibling && blockTags.concat(listTags).indexOf(newParagraph.nextSibling.nodeName) < 0) {
newParagraph.appendChild(newParagraph.nextSibling);
}
}
}
},
clearEntities: function clearEntities(rootElem) {
var rootDoc = rootElem.ownerDocument;
var walker = rootDoc.createTreeWalker(rootElem, NodeFilter.SHOW_TEXT, null, false);
var textNodes = [];
while (walker.nextNode()) {
textNodes.push(walker.currentNode);
}
textNodes.forEach(function (textNode) {
if (/\w+/.test(textNode.textContent)) {
textNode.nodeValue = textNode.nodeValue.replace(/^\u00a0/, '');
textNode.nodeValue = textNode.nodeValue.replace(/\u00a0$/, '');
}
});
},
ensureRootElems: function ensureRootElems(rootElem) {
var rootNodeTags = ['H1', 'H2', 'H3', 'H4', 'H5', 'H6', 'OL', 'UL', 'BLOCKQUOTE', 'P'];
var nestableTags = [{
tags: ['OL', 'UL'],
validParents: ['OL', 'UL', 'LI']
}, {
tags: ['H1', 'H2', 'H3', 'H4', 'H5', 'H6'],
validParents: ['LI']
}];
var rootNodes = rootElem.querySelectorAll(rootNodeTags.join(', '));
var validNesting = function validNesting(node) {
var validNesting = false;
nestableTags.forEach(function (nestingDict) {
if (nestingDict.tags.indexOf(node.tagName) > -1 && nestingDict.validParents.indexOf(node.parentNode.tagName) > -1) {
validNesting = true;
}
});
return validNesting;
};
var moveNodeToRoot = function moveNodeToRoot(node) {
if (node.parentNode === rootElem) {
return;
}
if (validNesting(node)) {
return;
}
var rootParentNode = node.parentNode;
if (node.tagName === 'P' && ['LI', 'BLOCKQUOTE'].indexOf(rootParentNode.tagName) > -1) {
while (node.firstChild) {
DOM.insertBefore(node.firstChild, node);
}
DOM.removeNode(node);
return;
}
while (rootParentNode.parentNode !== rootElem) {
rootParentNode = rootParentNode.parentNode;
}
DOM.insertBefore(node, rootParentNode);
};
rootNodes.forEach(moveNodeToRoot);
},
removeZeroWidthSpaces: function removeZeroWidthSpaces(rootElem) {
rootElem.childNodes.forEach(function (childNode) {
if (childNode.nodeType === Node.TEXT_NODE && zeroWidthSpace.assert(childNode)) {
DOM.removeNode(childNode);
}
});
},
removeEmptyNodes: function removeEmptyNodes(rootElem) {
var opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
if (rootElem.normalize) {
rootElem.normalize();
}
for (var i = rootElem.childNodes.length - 1; i >= 0; i--) {
var childNode = rootElem.childNodes[i];
if (childNode.nodeName === 'BR') {
continue;
}
if (opts.recursive && childNode.childNodes.length) {
this.removeEmptyNodes(childNode, { recursive: true, rootIsChild: true });
}
if (!/[\w\.,\/#!$%\^&\*;:{}=\-_`~()\'\"]/.test(childNode.textContent)) {
if (!opts.rootIsChild && !zeroWidthSpace.assert(childNode) && i > 0 || childNode.nodeType === Node.ELEMENT_NODE) {
DOM.removeNode(childNode);
}
}
}
},
removeStyledSpans: function removeStyledSpans(rootElem) {
var styledSpans = rootElem.querySelectorAll('span[style]');
for (var i = styledSpans.length - 1; i >= 0; i--) {
var styledSpan = styledSpans[i];
while (styledSpan.firstChild) {
DOM.insertBefore(styledSpan.firstChild, styledSpan);
}
DOM.removeNode(styledSpan);
}
},
removeFontNodes: function removeFontNodes(rootElem) {
var fontTags = rootElem.querySelectorAll('font');
for (var i = fontTags.length - 1; i >= 0; i--) {
var fontTag = fontTags[i];
while (fontTag.firstChild) {
DOM.insertBefore(fontTag.firstChild, fontTag);
}
DOM.removeNode(fontTag);
}
}
}
});
// jshint strict: false
var BlockFormatter = Module({
name: 'BlockFormatter',
props: {
selectionRootEl: null
},
handlers: {
commands: {
'format:block': 'formatBlock'
},
events: {}
},
methods: {
init: function init() {},
formatBlock: function formatBlock(opts) {
this.preProcess(opts);
this.process(opts);
this.commit(opts);
},
preProcess: function preProcess() {
var mediator = this.mediator;
mediator.exec('format:export:to:canvas');
},
process: function process(opts) {
var mediator = this.mediator;
var canvasDoc = mediator.get('canvas:document');
if (opts.toggle) {
if (opts.style === 'BLOCKQUOTE') {
commands.exec('outdent', null, canvasDoc);
}
commands.defaultBlockFormat(canvasDoc);
} else {
commands.formatBlock(opts.style, canvasDoc);
}
},
commit: function commit(opts) {
var mediator = this.mediator,
cleanupBlockquote = this.cleanupBlockquote;
var importFilter = opts.style === 'BLOCKQUOTE' ? cleanupBlockquote : null;
mediator.exec('format:import:from:canvas', { importFilter: importFilter });
},
cleanupBlockquote: function cleanupBlockquote(rootElem) {
var blockquoteParagraphs = rootElem.querySelectorAll('BLOCKQUOTE P');
blockquoteParagraphs.forEach(function (paragraph) {
DOM.unwrap(paragraph);
});
}
}
});
// jshint strict: false
var TextFormatter = Module({
name: 'TextFormatter',
props: {
cachedRange: null
},
handlers: {
requests: {},
commands: {
'format:text': 'formatText'
},
events: {}
},
methods: {
formatText: function formatText(opts) {
this.preProcess();
this.process(opts);
this.postProcess();
},
preProcess: function preProcess() {
var mediator = this.mediator;
mediator.exec('contenteditable:refocus');
mediator.exec('selection:reselect');
},
process: function process(opts) {
commands.exec(opts.style, null);
},
postProcess: function postProcess() {
var mediator = this.mediator;
mediator.exec('contenteditable:refocus');
// mediator.exec('selection:reselect');
}
}
});
// jshint strict: false
var ListFormatter = Module({
name: 'ListFormatter',
props: {},
dom: {},
handlers: {
requests: {},
commands: {
'format:list': 'formatList',
'format:list:cleanup': 'cleanupListDOM'
},
events: {
'contenteditable:tab:down': 'handleTabDown',
'contenteditable:tab:up': 'handleTabUp'
}
},
methods: {
init: function init() {},
formatList: function formatList(opts) {
this.preProcess(opts);
this.process(opts);
this.commit(opts);
},
preProcess: function preProcess() {
var mediator = this.mediator;
mediator.exec('format:export:to:canvas');
},
process: function process(opts) {
var mediator = this.mediator;
var canvasDoc = mediator.get('canvas:document');
var toggle = false;
mediator.exec('canvas:cache:selection');
switch (opts.style) {
case 'ordered':
toggle = mediator.get('selection:in:or:contains', ['OL']);
if (toggle) {
// this.prepListItemsForToggle();
// while (mediator.get('canvas:selection:in:or:contains', ['OL'])) {
// commands.exec('outdent', null, canvasDoc);
// }
// commands.exec('insertOrderedList', null, canvasDoc);
// return;
} else if (mediator.get('selection:in:or:contains', ['UL'])) {
commands.exec('insertUnorderedList', null, canvasDoc);
}
commands.exec('insertOrderedList', null, canvasDoc);
break;
case 'unordered':
toggle = mediator.get('selection:in:or:contains', ['UL']);
if (mediator.get('selection:in:or:contains', ['OL'])) {
commands.exec('insertOrderedList', null, canvasDoc);
}
commands.exec('insertUnorderedList', null, canvasDoc);
break;
case 'outdent':
commands.exec('outdent', null, canvasDoc);
break;
case 'indent':
commands.exec('indent', null, canvasDoc);
break;
}
if (toggle) {
// mediator.exec('canvas:select:cachedSelection');
this.postProcessToggle(opts);
} else {
mediator.exec('canvas:select:ensure:offsets');
}
// mediator.exec('canvas:select:cachedSelection');
},
commit: function commit() {
var mediator = this.mediator,
cleanupListDOM = this.cleanupListDOM;
mediator.exec('format:import:from:canvas', {
importFilter: cleanupListDOM
});
},
handleTabDown: function handleTabDown(evnt) {
var mediator = this.mediator;
var isInList = mediator.get('selection:in:or:contains', ['UL', 'OL']);
if (isInList) {
evnt.preventDefault();
}
},
handleTabUp: function handleTabUp(evnt) {
var mediator = this.mediator;
var isInList = mediator.get('selection:in:or:contains', ['UL', 'OL']);
if (isInList) {
evnt.preventDefault();
}
},
prepListItemsForToggle: function prepListItemsForToggle() {
var mediator = this.mediator;
var canvasDoc = mediator.get('canvas:document');
var canvasBody = mediator.get('canvas:body');
var _mediator$get = mediator.get('canvas:selection'),
anchorNode = _mediator$get.anchorNode,
focusNode = _mediator$get.focusNode;
var anchorLiNode = DOM.getClosest(anchorNode, 'LI', canvasBody);
var focusLiNode = DOM.getClosest(focusNode, 'LI', canvasBody);
mediator.exec('canvas:cache:selection');
var selectedLiNodes = [anchorLiNode];
var nextLiNode = anchorLiNode.nextSibling;
while (nextLiNode && nextLiNode !== focusLiNode) {
selectedLiNodes.push(nextLiNode);
nextLiNode = nextLiNode.nextSibling;
}
selectedLiNodes.push(focusLiNode);
selectedLiNodes.forEach(function (selectedLiNode) {
var contentWrapper = canvasDoc.createElement('span');
selectedLiNode.appendChild(contentWrapper);
while (selectedLiNode.firstChild !== contentWrapper) {
contentWrapper.appendChild(selectedLiNode.firstChild);
}
});
mediator.exec('canvas:select:cachedSelection');
return;
// const canvasBody = mediator.get('canvas:body');
// const canvasDoc = mediator.get('canvas:document');
//
// let rootBlock = anchorNode;
// while(rootBlock.parentNode !== canvasBody) {
// rootBlock = rootBlock.parentNode;
// }
//
// const liNodes = rootBlock.querySelectorAll('li');
// liNodes.forEach((liNode) => {
// let pNode = canvasDoc.createElement('span');
// liNode.appendChild(pNode);
// while (liNode.firstChild !== pNode) {
// pNode.appendChild(liNode.firstChild);
// }
// });
},
postProcessToggle: function postProcessToggle() {
var mediator = this.mediator;
// return;
var canvasDoc = mediator.get('canvas:document');
var canvasBody = mediator.get('canvas:body');
mediator.exec('canvas:cache:selection');
var _mediator$get2 = mediator.get('canvas:selection'),
anchorNode = _mediator$get2.anchorNode,
focusNode = _mediator$get2.focusNode;
var walkToRoot = function walkToRoot(node) {
var rootNode = node;
while (rootNode.parentNode !== canvasBody) {
rootNode = rootNode.parentNode;
}
return rootNode;
};
var anchorRootNode = walkToRoot(anchorNode);
var focusRootNode = walkToRoot(focusNode);
var currentNode = anchorRootNode;
var currentParagraph = void 0;
var createParagraph = function createParagraph() {
currentParagraph = canvasDoc.createElement('p');
DOM.insertBefore(currentParagraph, currentNode);
};
var handleBrNode = function handleBrNode(brNode) {
createParagraph();
currentNode = brNode.nextSibling;
DOM.removeNode(brNode);
};
var handleDivNode = function handleDivNode(divNode) {
createParagraph();
currentNode = divNode.nextSibling;
while (divNode.firstChild) {
currentParagraph.appendChild(divNode.firstChild);
}
DOM.removeNode(divNode);
};
createParagraph();
while (currentNode !== focusRootNode) {
if (currentNode.nodeName === 'BR') {
handleBrNode(currentNode);
} else if (currentNode.nodeName === 'DIV') {
handleDivNode(currentNode);
} else {
var orphanedNode = currentNode;
currentNode = currentNode.nextSibling;
currentParagraph.appendChild(orphanedNode);
}
}
if (focusRootNode.nodeName === 'DIV') {
handleDivNode(focusRootNode);
} else {
currentParagraph.appendChild(focusRootNode);
}
mediator.exec('canvas:select:cachedSelection');
},
cleanupListDOM: function cleanupListDOM(rootElem) {
var listContainers = rootElem.querySelectorAll('OL, UL');
for (var i = listContainers.length - 1; i >= 0; i--) {
var listContainer = listContainers[i];
if (['OL', 'UL'].indexOf(listContainer.parentNode.nodeName) > -1) {
if (listContainer.previousSibling) {
if (listContainer.previousSibling.nodeName === 'LI') {
listContainer.previousSibling.appendChild(listContainer);
}
if (['OL', 'UL'].indexOf(listContainer.previousSibling.nodeName) > -1) {
for (var j = 0; j <= listContainer.childNodes.length; j++) {
listContainer.previousSibling.appendChild(listContainer.childNodes[j]);
}
DOM.removeNode(listContainer);
}
} else {
DOM.unwrap(listContainer);
}
} else {
while (listContainer.parentNode && listContainer.parentNode !== rootElem && ['LI'].indexOf(listContainer.parentNode.nodeName) < 0) {
DOM.insertBefore(listContainer, listContainer.parentNode);
}
}
}
var nestedListItems = rootElem.querySelectorAll('LI > LI');
for (var _i = nestedListItems.length - 1; _i >= 0; _i--) {
var nestedListItem = nestedListItems[_i];
DOM.insertAfter(nestedListItem, nestedListItem.parentNode);
}
}
}
});
var Template$6 = runtime.template({ "compiler": [7, ">= 4.0.0"], "main": function main(container, depth0, helpers, partials, data) {
var helper;
return "\n";
}, "useData": true });
var inputFormTemplate = function (data, options, asString) {
var html = Template$6(data, options);
return asString || typeof $ === 'undefined' ? html : $(html);
};
var Template$7 = runtime.template({ "compiler": [7, ">= 4.0.0"], "main": function main(container, depth0, helpers, partials, data) {
var helper;
return "\n";
}, "useData": true });
var linkDisplayTemplate = function (data, options, asString) {
var html = Template$7(data, options);
return asString || typeof $ === 'undefined' ? html : $(html);
};
var inputFormStyles = ".typester-input-form input[type=text] {\n background: none;\n border: none;\n padding: 5px 15px;\n height: 30px;\n color: #FFF;\n width: 250px;\n outline: none;\n vertical-align: top; }\n\n.typester-input-form button {\n height: 40px;\n width: 40px;\n line-height: 40px;\n background: none;\n border: none;\n color: #FFF;\n cursor: pointer;\n outline: none;\n text-align: center;\n padding: 0;\n margin: 0;\n vertical-align: top; }\n .typester-input-form button:hover {\n background: #00aeef; }\n .typester-input-form button svg {\n display: block;\n height: 16px;\n width: 16px;\n margin: 12px;\n fill: #FFF;\n stroke: #FFF;\n text-align: center; }\n\n.typester-link-display a {\n display: block;\n cursor: pointer;\n line-height: 20px;\n padding: 10px; }\n";
// jshint strict: false
var LinkFormatter = Module({
name: 'LinkFormatter',
props: {
urlRegex: /[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,4}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/,
styles: null,
currentAnchor: null,
active: false,
hasMouse: false,
showing: null,
hideTimeout: null,
initialEvent: null,
targetEl: null,
hasRendered: null
},
dom: {
'userInput': '.user-input'
},
handlers: {
requests: {
'format:link:active': 'isActive'
},
commands: {
'format:link': 'formatLink'
},
events: {
'app:destroy': 'destroy',
'contenteditable:mouseover:anchor': 'showLinkFlyout',
'contenteditable:mouseout:anchor': 'hideFlyout',
'selection:update': 'handleSelectionChange',
'selection:change': 'handleSelectionChange',
'contenteditable:blur': 'handleContentEditableBlur'
},
domEvents: {
'submit': 'handleSubmit',
'click': 'handleClick',
'mouseover': 'handleMouseOver',
'mouseout': 'handleMouseOut'
}
},
methods: {
setup: function setup() {
this.appendStyles();
},
appendStyles: function appendStyles() {
var props = this.props;
props.styles = DOM.addStyles(inputFormStyles);
},
formatLink: function formatLink() {
if (this.isInLink()) {
this.removeLink();
} else {
this.showLinkFormFlyout();
}
},
isInLink: function isInLink() {
var mediator = this.mediator;
return mediator.get('selection:in:or:contains', ['A']);
},
showLinkFormFlyout: function showLinkFormFlyout(data) {
var mediator = this.mediator,
props = this.props;
var linkForm = this.compileLinkForm(data);
props.showing = 'linkForm';
this.render({ content: linkForm });
mediator.exec('selection:wrap:pseudo');
this.focusInput();
this.bindInput();
},
showLinkFlyout: function showLinkFlyout(evnt) {
var props = this.props,
mediator = this.mediator;
var anchor = DOM.getClosest(evnt.target, 'A');
if (mediator.get('selection:contains:node', anchor) || props.showing === 'linkForm') {
return;
}
this.clearHideTimeout();
var linkDisplay = this.compileLinkDisplay({ href: anchor.href });
props.initialEvent = evnt;
props.targetEl = anchor;
this.render({
content: linkDisplay,
flyoutPlacement: 'below'
});
props.showing = 'linkDisplay';
props.currentAnchor = anchor;
},
hideFlyout: function hideFlyout() {
var _this = this;
var props = this.props;
props.hideTimeout = setTimeout(function () {
if (!_this.isActive() && props.hasRendered) {
_this.destroy();
}
}, 350);
},
clearHideTimeout: function clearHideTimeout() {
var props = this.props;
if (props.hideTimeout) {
clearTimeout(props.hideTimeout);
props.hideTimeout = null;
}
},
compileLinkForm: function compileLinkForm(data) {
var wrapperEl = document.createElement('div');
var inputFormHTML = inputFormTemplate(data);
if (typeof inputFormHTML === 'string') {
wrapperEl.innerHTML = inputFormHTML;
} else {
wrapperEl.appendChild(inputFormHTML[0]);
}
return wrapperEl.childNodes[0];
},
compileLinkDisplay: function compileLinkDisplay(data) {
var wrapperEl = document.createElement('div');
var inputFormHTML = linkDisplayTemplate(data);
if (typeof inputFormHTML === 'string') {
wrapperEl.innerHTML = inputFormHTML;
} else {
wrapperEl.appendChild(inputFormHTML[0]);
}
return wrapperEl.childNodes[0];
},
render: function render(opts) {
var mediator = this.mediator,
props = this.props;
props.hasMouse = false;
props.flyout = props.flyout || mediator.get('flyout:new');
props.flyout.clearContent();
props.flyout.setPlacement(opts.flyoutPlacement);
props.flyout.appendContent(opts.content);
this.positionFlyout(opts);
this.showFlyout();
props.hasRendered = true;
return props.flyout.el;
},
positionFlyout: function positionFlyout(opts) {
var mediator = this.mediator,
props = this.props;
var initialEvent = props.initialEvent,
targetEl = props.targetEl;
var targetBounds = void 0,
elStyles = void 0,
elLineHeight = void 0,
lineCount = void 0,
lineStepHeight = void 0;
if (targetEl) {
targetBounds = targetEl.getBoundingClientRect();
elStyles = window.getComputedStyle(targetEl);
elLineHeight = parseInt(elStyles.getPropertyValue('line-height'), 10);
lineCount = Math.ceil(targetBounds.height / elLineHeight);
lineStepHeight = targetBounds.height / lineCount;
} else {
targetBounds = mediator.get('selection:bounds');
}
if (targetBounds.width > 0) {
var scrollOffset = DOM.getScrollOffset();
var docRelTop = void 0,
docRelCenter = void 0;
if (initialEvent) {
var topDiff = initialEvent.clientY - targetBounds.top;
docRelTop = initialEvent.clientY;
docRelCenter = initialEvent.clientX;
if (opts.flyoutPlacement === 'below') {
docRelTop = targetBounds.top + lineStepHeight * Math.ceil(topDiff / lineStepHeight);
} else {
docRelTop = targetBounds.top + lineStepHeight * Math.floor(topDiff / lineStepHeight);
}
} else {
docRelTop = opts.flyoutPlacement === 'below' ? targetBounds.bottom : targetBounds.top;
docRelCenter = targetBounds.width / 2 + targetBounds.left + scrollOffset.x;
}
docRelTop += scrollOffset.y;
props.flyout.position({
left: docRelCenter + 'px',
top: docRelTop + 'px'
});
}
},
showFlyout: function showFlyout() {
var mediator = this.mediator,
props = this.props;
props.flyout.show();
mediator.exec('toolbar:hide');
},
focusInput: function focusInput() {
var dom = this.dom;
dom.userInput[0].focus();
},
bindInput: function bindInput() {
var dom = this.dom,
props = this.props;
dom.userInput[0].addEventListener('blur', this.handleBlur);
props.userInputBound = true;
},
unbindInput: function unbindInput() {
var dom = this.dom,
props = this.props;
if (props.userInputBound) {
props.userInputBound = false;
dom.userInput[0].removeEventListener('blur', this.handleBlur);
}
},
handleSubmit: function handleSubmit(evnt) {
evnt.preventDefault();
var formJSON = this.processForm();
if (formJSON['user-input']) {
this.createLink(formJSON);
} else {
this.removeLink({ byPseudo: true });
}
},
handleClick: function handleClick(evnt) {
var mediator = this.mediator,
props = this.props;
if (evnt.target.nodeName === 'A') {
evnt.preventDefault();
mediator.exec('selection:wrap:element', props.currentAnchor, { silent: true });
this.showLinkFormFlyout({ value: props.currentAnchor.href });
}
},
handleMouseOver: function handleMouseOver() {
var props = this.props;
props.hasMouse = true;
},
handleMouseOut: function handleMouseOut() {
var props = this.props;
props.hasMouse = false;
if (props.showing === 'linkDisplay') {
this.hideFlyout();
}
},
handleBlur: function handleBlur() {
var _this2 = this;
var props = this.props;
if (props.blurTimeout) {
clearTimeout(props.blurTimeout);
}
props.blurTimeout = setTimeout(function () {
_this2.hideFlyout();
}, 100);
},
handleSelectionChange: function handleSelectionChange() {
if (!this.isActive()) {
this.hideFlyout();
}
},
handleContentEditableBlur: function handleContentEditableBlur() {
this.hideFlyout();
},
isActive: function isActive() {
var props = this.props,
dom = this.dom;
return props.hasMouse || dom && document.activeElement === dom.userInput[0] || props.showingLinkFlyout;
},
processForm: function processForm() {
var dom = this.dom;
var formInputs = dom.el[0].querySelectorAll('input, select, textarea');
var formJSON = {};
for (var i = 0; i < formInputs.length; i++) {
var inputEl = formInputs[i];
var inputName = inputEl.name;
var inputValue = inputEl.value;
if (inputName) {
formJSON[inputName] = inputValue;
}
}
return formJSON;
},
processLinkInput: function processLinkInput(linkInput) {
var props = this.props;
if (props.urlRegex.test(linkInput) && linkInput.indexOf('//') < 0) {
linkInput = 'http://' + linkInput;
}
return linkInput;
},
createLink: function createLink(formJSON) {
var mediator = this.mediator;
if (formJSON['user-input']) {
var linkURL = this.processLinkInput(formJSON['user-input']);
mediator.exec('selection:select:pseudo');
commands.exec('unlink');
commands.exec('createLink', linkURL);
}
this.destroy();
},
removeLink: function removeLink() {
var opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var mediator = this.mediator;
if (opts.byPseudo) {
mediator.exec('selection:select:pseudo');
} else {
var anchorNode = mediator.get('selection:anchornode');
var anchor = DOM.getClosest(anchorNode, 'A');
mediator.exec('selection:wrap:element', anchor);
}
commands.exec('unlink');
this.destroy();
},
destroy: function destroy() {
var props = this.props,
mediator = this.mediator;
if (props.flyout) {
this.unbindInput();
props.flyout.remove();
}
props.showing = null;
props.hasMouse = false;
props.hasRendered = null;
mediator.exec('selection:select:remove:pseudo');
}
}
});
var purify = createCommonjsModule(function (module, exports) {
(function (global, factory) {
module.exports = factory();
}(commonjsGlobal, (function () { 'use strict';
var html = ['a', 'abbr', 'acronym', 'address', 'area', 'article', 'aside', 'audio', 'b', 'bdi', 'bdo', 'big', 'blink', 'blockquote', 'body', 'br', 'button', 'canvas', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'content', 'data', 'datalist', 'dd', 'decorator', 'del', 'details', 'dfn', 'dir', 'div', 'dl', 'dt', 'element', 'em', 'fieldset', 'figcaption', 'figure', 'font', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'i', 'img', 'input', 'ins', 'kbd', 'label', 'legend', 'li', 'main', 'map', 'mark', 'marquee', 'menu', 'menuitem', 'meter', 'nav', 'nobr', 'ol', 'optgroup', 'option', 'output', 'p', 'pre', 'progress', 'q', 'rp', 'rt', 'ruby', 's', 'samp', 'section', 'select', 'shadow', 'small', 'source', 'spacer', 'span', 'strike', 'strong', 'style', 'sub', 'summary', 'sup', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'time', 'tr', 'track', 'tt', 'u', 'ul', 'var', 'video', 'wbr'];
// SVG
var svg = ['svg', 'a', 'altglyph', 'altglyphdef', 'altglyphitem', 'animatecolor', 'animatemotion', 'animatetransform', 'audio', 'canvas', 'circle', 'clippath', 'defs', 'desc', 'ellipse', 'filter', 'font', 'g', 'glyph', 'glyphref', 'hkern', 'image', 'line', 'lineargradient', 'marker', 'mask', 'metadata', 'mpath', 'path', 'pattern', 'polygon', 'polyline', 'radialgradient', 'rect', 'stop', 'style', 'switch', 'symbol', 'text', 'textpath', 'title', 'tref', 'tspan', 'video', 'view', 'vkern'];
var svgFilters = ['feBlend', 'feColorMatrix', 'feComponentTransfer', 'feComposite', 'feConvolveMatrix', 'feDiffuseLighting', 'feDisplacementMap', 'feFlood', 'feFuncA', 'feFuncB', 'feFuncG', 'feFuncR', 'feGaussianBlur', 'feMerge', 'feMergeNode', 'feMorphology', 'feOffset', 'feSpecularLighting', 'feTile', 'feTurbulence'];
var mathMl = ['math', 'menclose', 'merror', 'mfenced', 'mfrac', 'mglyph', 'mi', 'mlabeledtr', 'mmuliscripts', 'mn', 'mo', 'mover', 'mpadded', 'mphantom', 'mroot', 'mrow', 'ms', 'mpspace', 'msqrt', 'mystyle', 'msub', 'msup', 'msubsup', 'mtable', 'mtd', 'mtext', 'mtr', 'munder', 'munderover'];
var text = ['#text'];
var html$1 = ['accept', 'action', 'align', 'alt', 'autocomplete', 'background', 'bgcolor', 'border', 'cellpadding', 'cellspacing', 'checked', 'cite', 'class', 'clear', 'color', 'cols', 'colspan', 'coords', 'datetime', 'default', 'dir', 'disabled', 'download', 'enctype', 'face', 'for', 'headers', 'height', 'hidden', 'high', 'href', 'hreflang', 'id', 'ismap', 'label', 'lang', 'list', 'loop', 'low', 'max', 'maxlength', 'media', 'method', 'min', 'multiple', 'name', 'noshade', 'novalidate', 'nowrap', 'open', 'optimum', 'pattern', 'placeholder', 'poster', 'preload', 'pubdate', 'radiogroup', 'readonly', 'rel', 'required', 'rev', 'reversed', 'role', 'rows', 'rowspan', 'spellcheck', 'scope', 'selected', 'shape', 'size', 'span', 'srclang', 'start', 'src', 'step', 'style', 'summary', 'tabindex', 'title', 'type', 'usemap', 'valign', 'value', 'width', 'xmlns'];
var svg$1 = ['accent-height', 'accumulate', 'additivive', 'alignment-baseline', 'ascent', 'attributename', 'attributetype', 'azimuth', 'basefrequency', 'baseline-shift', 'begin', 'bias', 'by', 'class', 'clip', 'clip-path', 'clip-rule', 'color', 'color-interpolation', 'color-interpolation-filters', 'color-profile', 'color-rendering', 'cx', 'cy', 'd', 'dx', 'dy', 'diffuseconstant', 'direction', 'display', 'divisor', 'dur', 'edgemode', 'elevation', 'end', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'flood-color', 'flood-opacity', 'font-family', 'font-size', 'font-size-adjust', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'fx', 'fy', 'g1', 'g2', 'glyph-name', 'glyphref', 'gradientunits', 'gradienttransform', 'height', 'href', 'id', 'image-rendering', 'in', 'in2', 'k', 'k1', 'k2', 'k3', 'k4', 'kerning', 'keypoints', 'keysplines', 'keytimes', 'lang', 'lengthadjust', 'letter-spacing', 'kernelmatrix', 'kernelunitlength', 'lighting-color', 'local', 'marker-end', 'marker-mid', 'marker-start', 'markerheight', 'markerunits', 'markerwidth', 'maskcontentunits', 'maskunits', 'max', 'mask', 'media', 'method', 'mode', 'min', 'name', 'numoctaves', 'offset', 'operator', 'opacity', 'order', 'orient', 'orientation', 'origin', 'overflow', 'paint-order', 'path', 'pathlength', 'patterncontentunits', 'patterntransform', 'patternunits', 'points', 'preservealpha', 'r', 'rx', 'ry', 'radius', 'refx', 'refy', 'repeatcount', 'repeatdur', 'restart', 'result', 'rotate', 'scale', 'seed', 'shape-rendering', 'specularconstant', 'specularexponent', 'spreadmethod', 'stddeviation', 'stitchtiles', 'stop-color', 'stop-opacity', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke', 'stroke-width', 'style', 'surfacescale', 'tabindex', 'targetx', 'targety', 'transform', 'text-anchor', 'text-decoration', 'text-rendering', 'textlength', 'type', 'u1', 'u2', 'unicode', 'values', 'viewbox', 'visibility', 'vert-adv-y', 'vert-origin-x', 'vert-origin-y', 'width', 'word-spacing', 'wrap', 'writing-mode', 'xchannelselector', 'ychannelselector', 'x', 'x1', 'x2', 'xmlns', 'y', 'y1', 'y2', 'z', 'zoomandpan'];
var mathMl$1 = ['accent', 'accentunder', 'align', 'bevelled', 'close', 'columnsalign', 'columnlines', 'columnspan', 'denomalign', 'depth', 'dir', 'display', 'displaystyle', 'fence', 'frame', 'height', 'href', 'id', 'largeop', 'length', 'linethickness', 'lspace', 'lquote', 'mathbackground', 'mathcolor', 'mathsize', 'mathvariant', 'maxsize', 'minsize', 'movablelimits', 'notation', 'numalign', 'open', 'rowalign', 'rowlines', 'rowspacing', 'rowspan', 'rspace', 'rquote', 'scriptlevel', 'scriptminsize', 'scriptsizemultiplier', 'selection', 'separator', 'separators', 'stretchy', 'subscriptshift', 'supscriptshift', 'symmetric', 'voffset', 'width', 'xmlns'];
var xml = ['xlink:href', 'xml:id', 'xlink:title', 'xml:space', 'xmlns:xlink'];
/* Add properties to a lookup table */
function addToSet(set, array) {
var l = array.length;
while (l--) {
if (typeof array[l] === 'string') {
array[l] = array[l].toLowerCase();
}
set[array[l]] = true;
}
return set;
}
/* Shallow clone an object */
function clone(object) {
var newObject = {};
var property = void 0;
for (property in object) {
if (Object.prototype.hasOwnProperty.call(object, property)) {
newObject[property] = object[property];
}
}
return newObject;
}
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
var getGlobal = function getGlobal() {
return typeof window === 'undefined' ? null : window;
};
function createDOMPurify() {
var window = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getGlobal();
var DOMPurify = function DOMPurify(root) {
return createDOMPurify(root);
};
/**
* Version label, exposed for easier checks
* if DOMPurify is up to date or not
*/
DOMPurify.version = '1.0.2';
/**
* Array of elements that DOMPurify removed during sanitation.
* Empty if nothing was removed.
*/
DOMPurify.removed = [];
if (!window || !window.document || window.document.nodeType !== 9) {
// Not running in a browser, provide a factory function
// so that you can pass your own Window
DOMPurify.isSupported = false;
return DOMPurify;
}
var originalDocument = window.document;
var useDOMParser = false; // See comment below
var useXHR = false;
var document = window.document;
var DocumentFragment = window.DocumentFragment,
HTMLTemplateElement = window.HTMLTemplateElement,
Node = window.Node,
NodeFilter = window.NodeFilter,
_window$NamedNodeMap = window.NamedNodeMap,
NamedNodeMap = _window$NamedNodeMap === undefined ? window.NamedNodeMap || window.MozNamedAttrMap : _window$NamedNodeMap,
Text = window.Text,
Comment = window.Comment,
DOMParser = window.DOMParser,
_window$XMLHttpReques = window.XMLHttpRequest,
XMLHttpRequest = _window$XMLHttpReques === undefined ? window.XMLHttpRequest : _window$XMLHttpReques,
_window$encodeURI = window.encodeURI,
encodeURI = _window$encodeURI === undefined ? window.encodeURI : _window$encodeURI;
// As per issue #47, the web-components registry is inherited by a
// new document created via createHTMLDocument. As per the spec
// (http://w3c.github.io/webcomponents/spec/custom/#creating-and-passing-registries)
// a new empty registry is used when creating a template contents owner
// document, so we use that as our parent document to ensure nothing
// is inherited.
if (typeof HTMLTemplateElement === 'function') {
var template = document.createElement('template');
if (template.content && template.content.ownerDocument) {
document = template.content.ownerDocument;
}
}
var _document = document,
implementation = _document.implementation,
createNodeIterator = _document.createNodeIterator,
getElementsByTagName = _document.getElementsByTagName,
createDocumentFragment = _document.createDocumentFragment;
var importNode = originalDocument.importNode;
var hooks = {};
/**
* Expose whether this browser supports running the full DOMPurify.
*/
DOMPurify.isSupported = implementation && typeof implementation.createHTMLDocument !== 'undefined' && document.documentMode !== 9;
/**
* We consider the elements and attributes below to be safe. Ideally
* don't add any new ones but feel free to remove unwanted ones.
*/
/* allowed element names */
var ALLOWED_TAGS = null;
var DEFAULT_ALLOWED_TAGS = addToSet({}, [].concat(_toConsumableArray(html), _toConsumableArray(svg), _toConsumableArray(svgFilters), _toConsumableArray(mathMl), _toConsumableArray(text)));
/* Allowed attribute names */
var ALLOWED_ATTR = null;
var DEFAULT_ALLOWED_ATTR = addToSet({}, [].concat(_toConsumableArray(html$1), _toConsumableArray(svg$1), _toConsumableArray(mathMl$1), _toConsumableArray(xml)));
/* Explicitly forbidden tags (overrides ALLOWED_TAGS/ADD_TAGS) */
var FORBID_TAGS = null;
/* Explicitly forbidden attributes (overrides ALLOWED_ATTR/ADD_ATTR) */
var FORBID_ATTR = null;
/* Decide if ARIA attributes are okay */
var ALLOW_ARIA_ATTR = true;
/* Decide if custom data attributes are okay */
var ALLOW_DATA_ATTR = true;
/* Decide if unknown protocols are okay */
var ALLOW_UNKNOWN_PROTOCOLS = false;
/* Output should be safe for jQuery's $() factory? */
var SAFE_FOR_JQUERY = false;
/* Output should be safe for common template engines.
* This means, DOMPurify removes data attributes, mustaches and ERB
*/
var SAFE_FOR_TEMPLATES = false;
/* Specify template detection regex for SAFE_FOR_TEMPLATES mode */
var MUSTACHE_EXPR = /\{\{[\s\S]*|[\s\S]*\}\}/gm;
var ERB_EXPR = /<%[\s\S]*|[\s\S]*%>/gm;
/* Decide if document with ... should be returned */
var WHOLE_DOCUMENT = false;
/* Track whether config is already set on this instance of DOMPurify. */
var SET_CONFIG = false;
/* Decide if all elements (e.g. style, script) must be children of
* document.body. By default, browsers might move them to document.head */
var FORCE_BODY = false;
/* Decide if a DOM `HTMLBodyElement` should be returned, instead of a html string.
* If `WHOLE_DOCUMENT` is enabled a `HTMLHtmlElement` will be returned instead
*/
var RETURN_DOM = false;
/* Decide if a DOM `DocumentFragment` should be returned, instead of a html string */
var RETURN_DOM_FRAGMENT = false;
/* If `RETURN_DOM` or `RETURN_DOM_FRAGMENT` is enabled, decide if the returned DOM
* `Node` is imported into the current `Document`. If this flag is not enabled the
* `Node` will belong (its ownerDocument) to a fresh `HTMLDocument`, created by
* DOMPurify. */
var RETURN_DOM_IMPORT = false;
/* Output should be free from DOM clobbering attacks? */
var SANITIZE_DOM = true;
/* Keep element content when removing element? */
var KEEP_CONTENT = true;
/* Allow usage of profiles like html, svg and mathMl */
var USE_PROFILES = {};
/* Tags to ignore content of when KEEP_CONTENT is true */
var FORBID_CONTENTS = addToSet({}, ['audio', 'head', 'math', 'script', 'style', 'template', 'svg', 'video']);
/* Tags that are safe for data: URIs */
var DATA_URI_TAGS = addToSet({}, ['audio', 'video', 'img', 'source', 'image']);
/* Attributes safe for values like "javascript:" */
var URI_SAFE_ATTRIBUTES = addToSet({}, ['alt', 'class', 'for', 'id', 'label', 'name', 'pattern', 'placeholder', 'summary', 'title', 'value', 'style', 'xmlns']);
/* Keep a reference to config to pass to hooks */
var CONFIG = null;
/* Ideally, do not touch anything below this line */
/* ______________________________________________ */
var formElement = document.createElement('form');
/**
* _parseConfig
*
* @param optional config literal
*/
// eslint-disable-next-line complexity
var _parseConfig = function _parseConfig(cfg) {
/* Shield configuration object from tampering */
if ((typeof cfg === 'undefined' ? 'undefined' : _typeof(cfg)) !== 'object') {
cfg = {};
}
/* Set configuration parameters */
ALLOWED_TAGS = 'ALLOWED_TAGS' in cfg ? addToSet({}, cfg.ALLOWED_TAGS) : DEFAULT_ALLOWED_TAGS;
ALLOWED_ATTR = 'ALLOWED_ATTR' in cfg ? addToSet({}, cfg.ALLOWED_ATTR) : DEFAULT_ALLOWED_ATTR;
FORBID_TAGS = 'FORBID_TAGS' in cfg ? addToSet({}, cfg.FORBID_TAGS) : {};
FORBID_ATTR = 'FORBID_ATTR' in cfg ? addToSet({}, cfg.FORBID_ATTR) : {};
USE_PROFILES = 'USE_PROFILES' in cfg ? cfg.USE_PROFILES : false;
ALLOW_ARIA_ATTR = cfg.ALLOW_ARIA_ATTR !== false; // Default true
ALLOW_DATA_ATTR = cfg.ALLOW_DATA_ATTR !== false; // Default true
ALLOW_UNKNOWN_PROTOCOLS = cfg.ALLOW_UNKNOWN_PROTOCOLS || false; // Default false
SAFE_FOR_JQUERY = cfg.SAFE_FOR_JQUERY || false; // Default false
SAFE_FOR_TEMPLATES = cfg.SAFE_FOR_TEMPLATES || false; // Default false
WHOLE_DOCUMENT = cfg.WHOLE_DOCUMENT || false; // Default false
RETURN_DOM = cfg.RETURN_DOM || false; // Default false
RETURN_DOM_FRAGMENT = cfg.RETURN_DOM_FRAGMENT || false; // Default false
RETURN_DOM_IMPORT = cfg.RETURN_DOM_IMPORT || false; // Default false
FORCE_BODY = cfg.FORCE_BODY || false; // Default false
SANITIZE_DOM = cfg.SANITIZE_DOM !== false; // Default true
KEEP_CONTENT = cfg.KEEP_CONTENT !== false; // Default true
if (SAFE_FOR_TEMPLATES) {
ALLOW_DATA_ATTR = false;
}
if (RETURN_DOM_FRAGMENT) {
RETURN_DOM = true;
}
/* Parse profile info */
if (USE_PROFILES) {
ALLOWED_TAGS = addToSet({}, [].concat(_toConsumableArray(text)));
ALLOWED_ATTR = [];
if (USE_PROFILES.html === true) {
addToSet(ALLOWED_TAGS, html);
addToSet(ALLOWED_ATTR, html$1);
}
if (USE_PROFILES.svg === true) {
addToSet(ALLOWED_TAGS, svg);
addToSet(ALLOWED_ATTR, svg$1);
addToSet(ALLOWED_ATTR, xml);
}
if (USE_PROFILES.svgFilters === true) {
addToSet(ALLOWED_TAGS, svgFilters);
addToSet(ALLOWED_ATTR, svg$1);
addToSet(ALLOWED_ATTR, xml);
}
if (USE_PROFILES.mathMl === true) {
addToSet(ALLOWED_TAGS, mathMl);
addToSet(ALLOWED_ATTR, mathMl$1);
addToSet(ALLOWED_ATTR, xml);
}
}
/* Merge configuration parameters */
if (cfg.ADD_TAGS) {
if (ALLOWED_TAGS === DEFAULT_ALLOWED_TAGS) {
ALLOWED_TAGS = clone(ALLOWED_TAGS);
}
addToSet(ALLOWED_TAGS, cfg.ADD_TAGS);
}
if (cfg.ADD_ATTR) {
if (ALLOWED_ATTR === DEFAULT_ALLOWED_ATTR) {
ALLOWED_ATTR = clone(ALLOWED_ATTR);
}
addToSet(ALLOWED_ATTR, cfg.ADD_ATTR);
}
if (cfg.ADD_URI_SAFE_ATTR) {
addToSet(URI_SAFE_ATTRIBUTES, cfg.ADD_URI_SAFE_ATTR);
}
/* Add #text in case KEEP_CONTENT is set to true */
if (KEEP_CONTENT) {
ALLOWED_TAGS['#text'] = true;
}
// Prevent further manipulation of configuration.
// Not available in IE8, Safari 5, etc.
if (Object && 'freeze' in Object) {
Object.freeze(cfg);
}
CONFIG = cfg;
};
/**
* _forceRemove
*
* @param a DOM node
*/
var _forceRemove = function _forceRemove(node) {
DOMPurify.removed.push({ element: node });
try {
node.parentNode.removeChild(node);
} catch (err) {
node.outerHTML = '';
}
};
/**
* _removeAttribute
*
* @param an Attribute name
* @param a DOM node
*/
var _removeAttribute = function _removeAttribute(name, node) {
DOMPurify.removed.push({
attribute: node.getAttributeNode(name),
from: node
});
node.removeAttribute(name);
};
/**
* _initDocument
*
* @param a string of dirty markup
* @return a DOM, filled with the dirty markup
*/
var _initDocument = function _initDocument(dirty) {
/* Create a HTML document */
var doc = void 0;
var body = void 0;
if (FORCE_BODY) {
dirty = '' + dirty;
}
/* Use XHR if necessary because Safari 10.1 and newer are buggy */
if (useXHR) {
try {
dirty = encodeURI(dirty);
} catch (err) {}
var xhr = new XMLHttpRequest();
xhr.responseType = 'document';
xhr.open('GET', 'data:text/html;charset=utf-8,' + dirty, false);
xhr.send(null);
doc = xhr.response;
}
/* Use DOMParser to workaround Firefox bug (see comment below) */
if (useDOMParser) {
try {
doc = new DOMParser().parseFromString(dirty, 'text/html');
} catch (err) {}
}
/* Otherwise use createHTMLDocument, because DOMParser is unsafe in
Safari (see comment below) */
if (!doc || !doc.documentElement) {
doc = implementation.createHTMLDocument('');
body = doc.body;
body.parentNode.removeChild(body.parentNode.firstElementChild);
body.outerHTML = dirty;
}
/* Work on whole document or just its body */
return getElementsByTagName.call(doc, WHOLE_DOCUMENT ? 'html' : 'body')[0];
};
// Safari 10.1+ (unfixed as of time of writing) has a catastrophic bug in
// its implementation of DOMParser such that the following executes the
// JavaScript:
//
// new DOMParser()
// .parseFromString('