slate-hyperscript
Advanced tools
Comparing version 0.6.3 to 0.7.0
@@ -7,2 +7,23 @@ # Changelog | ||
### `0.7.0` — August 3, 2018 | ||
###### NEW | ||
**Updated to work with `slate@0.37.0` with points.** This isn't a breaking change to any of the API's in `slate-hyperscript` itself, but it does update it to no longer depend on the core API's that were deprecated in `0.37.0`. | ||
###### DEPRECATED | ||
**The `<selection>` tag now takes `<anchor />` and `<focus />` children.** Previously you would set properties like `anchorKey=` or `focusOffset=` directly on the `<selection>` itself, but now these are handled as two children point tags: | ||
```jsx | ||
const selection = ( | ||
<selection> | ||
<anchor key="a" offset={1} /> | ||
<focus key="a" offset={3} /> | ||
</selection> | ||
) | ||
``` | ||
--- | ||
### `0.6.0` — July 27, 2018 | ||
@@ -9,0 +30,0 @@ |
@@ -7,81 +7,2 @@ (function (global, factory) { | ||
/** | ||
* Has own property. | ||
* | ||
* @type {Function} | ||
*/ | ||
var has = Object.prototype.hasOwnProperty; | ||
/** | ||
* To string. | ||
* | ||
* @type {Function} | ||
*/ | ||
var toString = Object.prototype.toString; | ||
/** | ||
* Test whether a value is "empty". | ||
* | ||
* @param {Mixed} val | ||
* @return {Boolean} | ||
*/ | ||
function isEmpty(val) { | ||
// Null and Undefined... | ||
if (val == null) return true | ||
// Booleans... | ||
if ('boolean' == typeof val) return false | ||
// Numbers... | ||
if ('number' == typeof val) return val === 0 | ||
// Strings... | ||
if ('string' == typeof val) return val.length === 0 | ||
// Functions... | ||
if ('function' == typeof val) return val.length === 0 | ||
// Arrays... | ||
if (Array.isArray(val)) return val.length === 0 | ||
// Errors... | ||
if (val instanceof Error) return val.message === '' | ||
// Objects... | ||
if (val.toString == toString) { | ||
switch (val.toString()) { | ||
// Maps, Sets, Files and Errors... | ||
case '[object File]': | ||
case '[object Map]': | ||
case '[object Set]': { | ||
return val.size === 0 | ||
} | ||
// Plain objects... | ||
case '[object Object]': { | ||
for (var key in val) { | ||
if (has.call(val, key)) return false | ||
} | ||
return true | ||
} | ||
} | ||
} | ||
// Anything else... | ||
return false | ||
} | ||
/** | ||
* Export `isEmpty`. | ||
* | ||
* @type {Function} | ||
*/ | ||
var lib = isEmpty; | ||
/*! | ||
@@ -178,24 +99,73 @@ * isobject <https://github.com/jonschlinkert/isobject> | ||
/** | ||
* Create selection point constants, for comparison by reference. | ||
* Point classes that can be created at different points in the document and | ||
* then searched for afterwards, for creating ranges. | ||
* | ||
* @type {Object} | ||
* @type {Class} | ||
*/ | ||
var ANCHOR = {}; | ||
var CURSOR = {}; | ||
var FOCUS = {}; | ||
var CursorPoint = function CursorPoint() { | ||
classCallCheck(this, CursorPoint); | ||
/** | ||
* wrappers for decorator points, for comparison by instanceof, | ||
* and for composition into ranges (anchor.combine(focus), etc) | ||
*/ | ||
this.offset = null; | ||
}; | ||
var DecoratorPoint = function DecoratorPoint(_ref, marks) { | ||
var key = _ref.key, | ||
data = _ref.data; | ||
classCallCheck(this, DecoratorPoint); | ||
var AnchorPoint = function AnchorPoint() { | ||
var attrs = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; | ||
classCallCheck(this, AnchorPoint); | ||
var _attrs$key = attrs.key, | ||
key = _attrs$key === undefined ? null : _attrs$key, | ||
_attrs$offset = attrs.offset, | ||
offset = _attrs$offset === undefined ? null : _attrs$offset, | ||
_attrs$path = attrs.path, | ||
path = _attrs$path === undefined ? null : _attrs$path; | ||
_initialiseProps.call(this); | ||
this.key = key; | ||
this.offset = offset; | ||
this.path = path; | ||
}; | ||
this._key = key; | ||
var FocusPoint = function FocusPoint() { | ||
var attrs = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; | ||
classCallCheck(this, FocusPoint); | ||
var _attrs$key2 = attrs.key, | ||
key = _attrs$key2 === undefined ? null : _attrs$key2, | ||
_attrs$offset2 = attrs.offset, | ||
offset = _attrs$offset2 === undefined ? null : _attrs$offset2, | ||
_attrs$path2 = attrs.path, | ||
path = _attrs$path2 === undefined ? null : _attrs$path2; | ||
this.key = key; | ||
this.offset = offset; | ||
this.path = path; | ||
}; | ||
var DecorationPoint = function DecorationPoint(attrs) { | ||
var _this = this; | ||
classCallCheck(this, DecorationPoint); | ||
this.combine = function (focus) { | ||
if (!(focus instanceof DecorationPoint)) throw new Error('misaligned decorations'); | ||
return slate.Range.create(_extends({ | ||
anchor: { | ||
key: _this.key, | ||
offset: _this.offset | ||
}, | ||
focus: { | ||
key: focus.key, | ||
offset: focus.offset | ||
}, | ||
marks: _this.marks, | ||
isAtomic: _this.isAtomic | ||
}, _this.attribs)); | ||
}; | ||
var _attrs$key3 = attrs.key, | ||
key = _attrs$key3 === undefined ? null : _attrs$key3, | ||
_attrs$data = attrs.data, | ||
data = _attrs$data === undefined ? {} : _attrs$data, | ||
marks = attrs.marks; | ||
this.id = key; | ||
this.offset = 0; | ||
this.marks = marks; | ||
@@ -214,36 +184,5 @@ this.attribs = data || {}; | ||
var _initialiseProps = function _initialiseProps() { | ||
var _this = this; | ||
this.withPosition = function (offset) { | ||
_this.offset = offset; | ||
return _this; | ||
}; | ||
this.addOffset = function (offset) { | ||
_this.offset += offset; | ||
return _this; | ||
}; | ||
this.withKey = function (key) { | ||
_this.key = key; | ||
return _this; | ||
}; | ||
this.combine = function (focus) { | ||
if (!(focus instanceof DecoratorPoint)) throw new Error('misaligned decorations'); | ||
return slate.Range.create(_extends({ | ||
anchorKey: _this.key, | ||
focusKey: focus.key, | ||
anchorOffset: _this.offset, | ||
focusOffset: focus.offset, | ||
marks: _this.marks, | ||
isAtomic: _this.isAtomic | ||
}, _this.attribs)); | ||
}; | ||
}; | ||
var CREATORS = { | ||
anchor: function anchor(tagName, attributes, children) { | ||
return ANCHOR; | ||
return new AnchorPoint(attributes); | ||
}, | ||
@@ -256,3 +195,3 @@ block: function block(tagName, attributes, children) { | ||
cursor: function cursor(tagName, attributes, children) { | ||
return CURSOR; | ||
return new CursorPoint(); | ||
}, | ||
@@ -265,3 +204,3 @@ document: function document(tagName, attributes, children) { | ||
focus: function focus(tagName, attributes, children) { | ||
return FOCUS; | ||
return new FocusPoint(attributes); | ||
}, | ||
@@ -280,8 +219,14 @@ inline: function inline(tagName, attributes, children) { | ||
if (attributes.key) { | ||
return new DecoratorPoint(attributes, [{ type: tagName }]); | ||
return new DecorationPoint(_extends({}, attributes, { | ||
marks: [{ type: tagName }] | ||
})); | ||
} | ||
var nodes = createChildren(children, { key: attributes.key }); | ||
var nodes = createChildren(children); | ||
var node = nodes[0]; | ||
nodes[0].__decorations = (nodes[0].__decorations || []).concat([{ | ||
var _node$__decorations = node.__decorations, | ||
__decorations = _node$__decorations === undefined ? [] : _node$__decorations; | ||
var __decoration = { | ||
anchorOffset: 0, | ||
@@ -293,7 +238,29 @@ focusOffset: nodes.reduce(function (len, n) { | ||
isAtomic: !!attributes.data.atomic | ||
}]); | ||
}; | ||
__decorations.push(__decoration); | ||
node.__decorations = __decorations; | ||
return nodes; | ||
}, | ||
selection: function selection(tagName, attributes, children) { | ||
return slate.Range.create(attributes); | ||
var anchor = children.find(function (c) { | ||
return c instanceof AnchorPoint; | ||
}); | ||
var focus = children.find(function (c) { | ||
return c instanceof FocusPoint; | ||
}); | ||
var selection = slate.Range.create(_extends({}, attributes, { | ||
anchor: anchor && { | ||
key: anchor.key, | ||
offset: anchor.offset, | ||
path: anchor.path | ||
}, | ||
focus: focus && { | ||
key: focus.key, | ||
offset: focus.offset, | ||
path: focus.path | ||
} | ||
})); | ||
return selection; | ||
}, | ||
@@ -307,48 +274,62 @@ value: function value(tagName, attributes, children) { | ||
var selection = children.find(slate.Range.isRange) || slate.Range.create(); | ||
var props = {}; | ||
var anchor = void 0; | ||
var focus = void 0; | ||
var decorations = []; | ||
var partialDecorations = {}; | ||
var partials = {}; | ||
// Search the document's texts to see if any of them have the anchor or | ||
// focus information saved, so we can set the selection. | ||
// focus information saved, or decorations applied. | ||
if (document) { | ||
document.getTexts().forEach(function (text) { | ||
if (text.__anchor != null) { | ||
props.anchorKey = text.key; | ||
props.anchorOffset = text.__anchor; | ||
props.isFocused = true; | ||
anchor = slate.Point.create({ key: text.key, offset: text.__anchor.offset }); | ||
} | ||
if (text.__focus != null) { | ||
props.focusKey = text.key; | ||
props.focusOffset = text.__focus; | ||
props.isFocused = true; | ||
focus = slate.Point.create({ key: text.key, offset: text.__focus.offset }); | ||
} | ||
}); | ||
// now check for decorations and hoist them to the top | ||
document.getTexts().forEach(function (text) { | ||
if (text.__decorations != null) { | ||
// add in all mark-like (keyless) decorations | ||
decorations = decorations.concat(text.__decorations.filter(function (d) { | ||
return d._key === undefined; | ||
}).map(function (d) { | ||
return slate.Range.create(_extends({}, d, { | ||
anchorKey: text.key, | ||
focusKey: text.key | ||
})); | ||
})); | ||
text.__decorations.forEach(function (dec) { | ||
var id = dec.id; | ||
// store or combine partial decorations (keyed with anchor / focus) | ||
text.__decorations.filter(function (d) { | ||
return d._key !== undefined; | ||
}).forEach(function (partial) { | ||
if (partialDecorations[partial._key]) { | ||
decorations.push(partialDecorations[partial._key].combine(partial.withKey(text.key))); | ||
var range = void 0; | ||
delete partialDecorations[partial._key]; | ||
return; | ||
if (!id) { | ||
range = slate.Range.create({ | ||
anchor: { | ||
key: text.key, | ||
offset: dec.anchorOffset | ||
}, | ||
focus: { | ||
key: text.key, | ||
offset: dec.focusOffset | ||
}, | ||
marks: dec.marks, | ||
isAtomic: dec.isAtomic | ||
}); | ||
} else if (partials[id]) { | ||
var partial = partials[id]; | ||
delete partials[id]; | ||
range = slate.Range.create({ | ||
anchor: { | ||
key: partial.key, | ||
offset: partial.offset | ||
}, | ||
focus: { | ||
key: text.key, | ||
offset: dec.offset | ||
}, | ||
marks: partial.marks, | ||
isAtomic: partial.isAtomic | ||
}); | ||
} else { | ||
dec.key = text.key; | ||
partials[id] = dec; | ||
} | ||
partialDecorations[partial._key] = partial.withKey(text.key); | ||
if (range) { | ||
decorations.push(range); | ||
} | ||
}); | ||
@@ -359,13 +340,12 @@ } | ||
// should have no more parital decorations outstanding (all paired) | ||
if (Object.keys(partialDecorations).length > 0) { | ||
throw new Error('Slate hyperscript must have both an anchor and focus defined for each keyed decorator.'); | ||
if (Object.keys(partials).length > 0) { | ||
throw new Error('Slate hyperscript must have both a start and an end defined for each decoration using the `key=` prop.'); | ||
} | ||
if (props.anchorKey && !props.focusKey) { | ||
throw new Error('Slate hyperscript must have both `<anchor/>` and `<focus/>` defined if one is defined, but you only defined `<anchor/>`. For collapsed selections, use `<cursor/>`.'); | ||
if (anchor && !focus) { | ||
throw new Error('Slate hyperscript ranges must have both `<anchor />` and `<focus />` defined if one is defined, but you only defined `<anchor />`. For collapsed selections, use `<cursor />` instead.'); | ||
} | ||
if (!props.anchorKey && props.focusKey) { | ||
throw new Error('Slate hyperscript must have both `<anchor/>` and `<focus/>` defined if one is defined, but you only defined `<focus/>`. For collapsed selections, use `<cursor/>`.'); | ||
if (!anchor && focus) { | ||
throw new Error('Slate hyperscript ranges must have both `<anchor />` and `<focus />` defined if one is defined, but you only defined `<focus />`. For collapsed selections, use `<cursor />` instead.'); | ||
} | ||
@@ -375,4 +355,6 @@ | ||
if (!lib(props)) { | ||
selection = selection.merge(props).normalize(value.document); | ||
if (anchor || focus) { | ||
selection = selection.setPoints([anchor, focus]); | ||
selection = selection.merge({ isFocused: true }); | ||
selection = selection.normalize(value.document); | ||
value = value.set('selection', selection); | ||
@@ -523,12 +505,24 @@ } | ||
if (__anchor != null) node.__anchor = __anchor + length; | ||
if (__focus != null) node.__focus = __focus + length; | ||
if (__anchor != null) { | ||
node.__anchor = new AnchorPoint(); | ||
node.__anchor.offset = __anchor.offset + length; | ||
} | ||
if (__focus != null) { | ||
node.__focus = new FocusPoint(); | ||
node.__focus.offset = __focus.offset + length; | ||
} | ||
if (__decorations != null) { | ||
node.__decorations = (node.__decorations || []).concat(__decorations.map(function (d) { | ||
return d instanceof DecoratorPoint ? d.addOffset(length) : _extends({}, d, { | ||
anchorOffset: d.anchorOffset + length, | ||
focusOffset: d.focusOffset + length | ||
}); | ||
})); | ||
__decorations.forEach(function (d) { | ||
if (d instanceof DecorationPoint) { | ||
d.offset += length; | ||
} else { | ||
d.anchorOffset += length; | ||
d.focusOffset += length; | ||
} | ||
}); | ||
node.__decorations = node.__decorations || []; | ||
node.__decorations = node.__decorations.concat(__decorations); | ||
} | ||
@@ -539,10 +533,17 @@ | ||
// If the child is a selection object store the current position. | ||
if (child == ANCHOR || child == CURSOR) node.__anchor = length; | ||
if (child == FOCUS || child == CURSOR) node.__focus = length; | ||
if (child instanceof AnchorPoint || child instanceof CursorPoint) { | ||
child.offset = length; | ||
node.__anchor = child; | ||
} | ||
// if child is a decorator point, store it as partial decorator | ||
if (child instanceof DecoratorPoint) { | ||
node.__decorations = (node.__decorations || []).concat([child.withPosition(length)]); | ||
if (child instanceof FocusPoint || child instanceof CursorPoint) { | ||
child.offset = length; | ||
node.__focus = child; | ||
} | ||
if (child instanceof DecorationPoint) { | ||
child.offset = length; | ||
node.__decorations = node.__decorations || []; | ||
node.__decorations = node.__decorations.concat(child); | ||
} | ||
}); | ||
@@ -549,0 +550,0 @@ |
@@ -1,1 +0,1 @@ | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("slate")):"function"==typeof define&&define.amd?define(["exports","slate"],t):t(e.SlateHyperscript={},e.Slate)}(this,function(e,t){"use strict";var n=Object.prototype.hasOwnProperty,r=Object.prototype.toString;var o=function(e){if(null==e)return!0;if("boolean"==typeof e)return!1;if("number"==typeof e)return 0===e;if("string"==typeof e)return 0===e.length;if("function"==typeof e)return 0===e.length;if(Array.isArray(e))return 0===e.length;if(e instanceof Error)return""===e.message;if(e.toString==r)switch(e.toString()){case"[object File]":case"[object Map]":case"[object Set]":return 0===e.size;case"[object Object]":for(var t in e)if(n.call(e,t))return!1;return!0}return!1},c=function(e){return null!=e&&"object"==typeof e&&!1===Array.isArray(e)};function i(e){return!0===c(e)&&"[object Object]"===Object.prototype.toString.call(e)}var a=function(e){var t,n;return!1!==i(e)&&("function"==typeof(t=e.constructor)&&(!1!==i(n=t.prototype)&&!1!==n.hasOwnProperty("isPrototypeOf")))},s=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},u=function(e,t){var n={};for(var r in e)t.indexOf(r)>=0||Object.prototype.hasOwnProperty.call(e,r)&&(n[r]=e[r]);return n},f={},l={},y={},h=function e(t,n){var r=t.key,o=t.data;return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),d.call(this),this._key=r,this.marks=n,this.attribs=o||{},this.isAtomic=!!this.attribs.atomic,delete this.attribs.atomic,this},d=function(){var e=this;this.withPosition=function(t){return e.offset=t,e},this.addOffset=function(t){return e.offset+=t,e},this.withKey=function(t){return e.key=t,e},this.combine=function(n){if(!(n instanceof h))throw new Error("misaligned decorations");return t.Range.create(s({anchorKey:e.key,focusKey:n.key,anchorOffset:e.offset,focusOffset:n.offset,marks:e.marks,isAtomic:e.isAtomic},e.attribs))}},p={anchor:function(e,t,n){return f},block:function(e,n,r){return t.Block.create(s({},n,{nodes:k(r)}))},cursor:function(e,t,n){return l},document:function(e,n,r){return t.Document.create(s({},n,{nodes:k(r)}))},focus:function(e,t,n){return y},inline:function(e,n,r){return t.Inline.create(s({},n,{nodes:k(r)}))},mark:function(e,n,r){return k(r,{marks:t.Mark.createSet([n])})},decoration:function(e,t,n){if(t.key)return new h(t,[{type:e}]);var r=k(n,{key:t.key});return r[0].__decorations=(r[0].__decorations||[]).concat([{anchorOffset:0,focusOffset:r.reduce(function(e,t){return e+t.text.length},0),marks:[{type:e}],isAtomic:!!t.data.atomic}]),r},selection:function(e,n,r){return t.Range.create(n)},value:function(e,n,r){var c=n.data,i=n.normalize,a=void 0===i||i,u=r.find(t.Document.isDocument),f=r.find(t.Range.isRange)||t.Range.create(),l={},y=[],h={};if(u&&(u.getTexts().forEach(function(e){null!=e.__anchor&&(l.anchorKey=e.key,l.anchorOffset=e.__anchor,l.isFocused=!0),null!=e.__focus&&(l.focusKey=e.key,l.focusOffset=e.__focus,l.isFocused=!0)}),u.getTexts().forEach(function(e){null!=e.__decorations&&(y=y.concat(e.__decorations.filter(function(e){return void 0===e._key}).map(function(n){return t.Range.create(s({},n,{anchorKey:e.key,focusKey:e.key}))})),e.__decorations.filter(function(e){return void 0!==e._key}).forEach(function(t){if(h[t._key])return y.push(h[t._key].combine(t.withKey(e.key))),void delete h[t._key];h[t._key]=t.withKey(e.key)}))})),Object.keys(h).length>0)throw new Error("Slate hyperscript must have both an anchor and focus defined for each keyed decorator.");if(l.anchorKey&&!l.focusKey)throw new Error("Slate hyperscript must have both `<anchor/>` and `<focus/>` defined if one is defined, but you only defined `<anchor/>`. For collapsed selections, use `<cursor/>`.");if(!l.anchorKey&&l.focusKey)throw new Error("Slate hyperscript must have both `<anchor/>` and `<focus/>` defined if one is defined, but you only defined `<focus/>`. For collapsed selections, use `<cursor/>`.");var d=t.Value.fromJSON({data:c,document:u,selection:f},{normalize:a});return o(l)||(f=f.merge(l).normalize(d.document),d=d.set("selection",f)),y.length>0&&(y=y.map(function(e){return e.normalize(d.document)}),y=t.Range.createList(y),d=d.set("decorations",y)),d},text:function(e,t,n){return k(n,{key:t.key})}};function _(){var e=function(e){var t=e.blocks,n=void 0===t?{}:t,r=e.inlines,o=void 0===r?{}:r,c=e.marks,i=void 0===c?{}:c,u=e.decorators,f=void 0===u?{}:u,l=s({},p,e.creators||{});return Object.keys(n).map(function(e){l[e]=m(e,n[e],"block")}),Object.keys(o).map(function(e){l[e]=m(e,o[e],"inline")}),Object.keys(i).map(function(e){l[e]=function(e,t){if("function"==typeof t)return t;if("string"==typeof t&&(t={type:t}),a(t))return function(e,n,r){var o=s({},t,{data:s({},t.data||{},n)});return p.mark(e,o,r)};throw new Error("Slate hyperscript mark creators can be either functions, objects or strings, but you passed: "+t)}(0,i[e])}),Object.keys(f).map(function(e){l[e]=m(e,f[e],"decoration")}),l}(arguments.length>0&&void 0!==arguments[0]?arguments[0]:{});return function(t,n){for(var r=arguments.length,o=Array(r>2?r-2:0),c=2;c<r;c++)o[c-2]=arguments[c];var i=e[t];if(!i)throw new Error('No hyperscript creator found for tag: "'+t+'"');return null==n&&(n={}),a(n)||(o=[n].concat(o),n={}),i(t,n,o=o.filter(function(e){return Boolean(e)}).reduce(function(e,t){return e.concat(t)},[]))}}function k(e){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=[],o=0,c=e.find(function(e){return"string"!=typeof e}),i=t.Text.isText(c)?c:null,a=n.key?n.key:i?i.key:void 0,u=t.Text.create({key:a,leaves:[{text:"",marks:n.marks}]});function d(e){var t=u,n=t.__anchor,r=t.__focus,o=t.__decorations;null!=n&&(e.__anchor=n),null!=r&&(e.__focus=r),null!=o&&(e.__decorations=o),u=e}return e.forEach(function(c,i){var a=i===e.length-1;if(t.Node.isNode(c)&&!t.Text.isText(c)&&((u.text.length||null!=u.__anchor||null!=u.__focus||u.getMarksAtIndex(0).size)&&r.push(u),r.push(c),u=a?null:t.Text.create({leaves:[{text:"",marks:n.marks}]}),o=0),"string"==typeof c&&(d(u.insertText(u.text.length,c,n.marks)),o+=c.length),t.Text.isText(c)){var p=c.__anchor,_=c.__focus,k=c.__decorations,m=u.text.length;n.key||0!=u.text.length||d(u.set("key",c.key)),c.getLeaves().forEach(function(e){var t=e.marks;n.marks&&(t=t.union(n.marks)),d(u.insertText(m,e.text,t)),m+=e.text.length}),null!=p&&(u.__anchor=p+o),null!=_&&(u.__focus=_+o),null!=k&&(u.__decorations=(u.__decorations||[]).concat(k.map(function(e){return e instanceof h?e.addOffset(o):s({},e,{anchorOffset:e.anchorOffset+o,focusOffset:e.focusOffset+o})}))),o+=c.text.length}c!=f&&c!=l||(u.__anchor=o),c!=y&&c!=l||(u.__focus=o),c instanceof h&&(u.__decorations=(u.__decorations||[]).concat([c.withPosition(o)]))}),null!=u&&r.push(u),r}function m(e,t,n){if("function"==typeof t)return t;if("string"==typeof t&&(t={type:t}),a(t))return function(e,r,o){var c=r.key,i=u(r,["key"]),a=s({},t,{object:n,key:c,data:s({},t.data||{},i)});return p[n](e,a,o)};throw new Error("Slate hyperscript "+n+" creators can be either functions, objects or strings, but you passed: "+t)}var v=_();e.default=v,e.createHyperscript=_,Object.defineProperty(e,"__esModule",{value:!0})}); | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("slate")):"function"==typeof define&&define.amd?define(["exports","slate"],t):t(e.SlateHyperscript={},e.Slate)}(this,function(e,t){"use strict";var n=function(e){return null!=e&&"object"==typeof e&&!1===Array.isArray(e)};function o(e){return!0===n(e)&&"[object Object]"===Object.prototype.toString.call(e)}var r=function(e){var t,n;return!1!==o(e)&&("function"==typeof(t=e.constructor)&&(!1!==o(n=t.prototype)&&!1!==n.hasOwnProperty("isPrototypeOf")))},i=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")},s=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var o in n)Object.prototype.hasOwnProperty.call(n,o)&&(e[o]=n[o])}return e},a=function(e,t){var n={};for(var o in e)t.indexOf(o)>=0||Object.prototype.hasOwnProperty.call(e,o)&&(n[o]=e[o]);return n},c=function e(){i(this,e),this.offset=null},f=function e(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};i(this,e);var n=t.key,o=void 0===n?null:n,r=t.offset,s=void 0===r?null:r,a=t.path,c=void 0===a?null:a;this.key=o,this.offset=s,this.path=c},u=function e(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};i(this,e);var n=t.key,o=void 0===n?null:n,r=t.offset,s=void 0===r?null:r,a=t.path,c=void 0===a?null:a;this.key=o,this.offset=s,this.path=c},l=function e(n){var o=this;i(this,e),this.combine=function(n){if(!(n instanceof e))throw new Error("misaligned decorations");return t.Range.create(s({anchor:{key:o.key,offset:o.offset},focus:{key:n.key,offset:n.offset},marks:o.marks,isAtomic:o.isAtomic},o.attribs))};var r=n.key,a=void 0===r?null:r,c=n.data,f=void 0===c?{}:c,u=n.marks;return this.id=a,this.offset=0,this.marks=u,this.attribs=f||{},this.isAtomic=!!this.attribs.atomic,delete this.attribs.atomic,this},d={anchor:function(e,t,n){return new f(t)},block:function(e,n,o){return t.Block.create(s({},n,{nodes:y(o)}))},cursor:function(e,t,n){return new c},document:function(e,n,o){return t.Document.create(s({},n,{nodes:y(o)}))},focus:function(e,t,n){return new u(t)},inline:function(e,n,o){return t.Inline.create(s({},n,{nodes:y(o)}))},mark:function(e,n,o){return y(o,{marks:t.Mark.createSet([n])})},decoration:function(e,t,n){if(t.key)return new l(s({},t,{marks:[{type:e}]}));var o=y(n),r=o[0],i=r.__decorations,a=void 0===i?[]:i,c={anchorOffset:0,focusOffset:o.reduce(function(e,t){return e+t.text.length},0),marks:[{type:e}],isAtomic:!!t.data.atomic};return a.push(c),r.__decorations=a,o},selection:function(e,n,o){var r=o.find(function(e){return e instanceof f}),i=o.find(function(e){return e instanceof u}),a=t.Range.create(s({},n,{anchor:r&&{key:r.key,offset:r.offset,path:r.path},focus:i&&{key:i.key,offset:i.offset,path:i.path}}));return a},value:function(e,n,o){var r=n.data,i=n.normalize,s=void 0===i||i,a=o.find(t.Document.isDocument),c=o.find(t.Range.isRange)||t.Range.create(),f=void 0,u=void 0,l=[],d={};if(a&&a.getTexts().forEach(function(e){null!=e.__anchor&&(f=t.Point.create({key:e.key,offset:e.__anchor.offset})),null!=e.__focus&&(u=t.Point.create({key:e.key,offset:e.__focus.offset})),null!=e.__decorations&&e.__decorations.forEach(function(n){var o=n.id,r=void 0;if(o)if(d[o]){var i=d[o];delete d[o],r=t.Range.create({anchor:{key:i.key,offset:i.offset},focus:{key:e.key,offset:n.offset},marks:i.marks,isAtomic:i.isAtomic})}else n.key=e.key,d[o]=n;else r=t.Range.create({anchor:{key:e.key,offset:n.anchorOffset},focus:{key:e.key,offset:n.focusOffset},marks:n.marks,isAtomic:n.isAtomic});r&&l.push(r)})}),Object.keys(d).length>0)throw new Error("Slate hyperscript must have both a start and an end defined for each decoration using the `key=` prop.");if(f&&!u)throw new Error("Slate hyperscript ranges must have both `<anchor />` and `<focus />` defined if one is defined, but you only defined `<anchor />`. For collapsed selections, use `<cursor />` instead.");if(!f&&u)throw new Error("Slate hyperscript ranges must have both `<anchor />` and `<focus />` defined if one is defined, but you only defined `<focus />`. For collapsed selections, use `<cursor />` instead.");var h=t.Value.fromJSON({data:r,document:a,selection:c},{normalize:s});return(f||u)&&(c=(c=(c=c.setPoints([f,u])).merge({isFocused:!0})).normalize(h.document),h=h.set("selection",c)),l.length>0&&(l=l.map(function(e){return e.normalize(h.document)}),l=t.Range.createList(l),h=h.set("decorations",l)),h},text:function(e,t,n){return y(n,{key:t.key})}};function h(){var e=function(e){var t=e.blocks,n=void 0===t?{}:t,o=e.inlines,i=void 0===o?{}:o,a=e.marks,c=void 0===a?{}:a,f=e.decorators,u=void 0===f?{}:f,l=s({},d,e.creators||{});return Object.keys(n).map(function(e){l[e]=k(e,n[e],"block")}),Object.keys(i).map(function(e){l[e]=k(e,i[e],"inline")}),Object.keys(c).map(function(e){l[e]=function(e,t){if("function"==typeof t)return t;if("string"==typeof t&&(t={type:t}),r(t))return function(e,n,o){var r=s({},t,{data:s({},t.data||{},n)});return d.mark(e,r,o)};throw new Error("Slate hyperscript mark creators can be either functions, objects or strings, but you passed: "+t)}(0,c[e])}),Object.keys(u).map(function(e){l[e]=k(e,u[e],"decoration")}),l}(arguments.length>0&&void 0!==arguments[0]?arguments[0]:{});return function(t,n){for(var o=arguments.length,i=Array(o>2?o-2:0),s=2;s<o;s++)i[s-2]=arguments[s];var a=e[t];if(!a)throw new Error('No hyperscript creator found for tag: "'+t+'"');return null==n&&(n={}),r(n)||(i=[n].concat(i),n={}),a(t,n,i=i.filter(function(e){return Boolean(e)}).reduce(function(e,t){return e.concat(t)},[]))}}function y(e){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},o=[],r=0,i=e.find(function(e){return"string"!=typeof e}),s=t.Text.isText(i)?i:null,a=n.key?n.key:s?s.key:void 0,d=t.Text.create({key:a,leaves:[{text:"",marks:n.marks}]});function h(e){var t=d,n=t.__anchor,o=t.__focus,r=t.__decorations;null!=n&&(e.__anchor=n),null!=o&&(e.__focus=o),null!=r&&(e.__decorations=r),d=e}return e.forEach(function(i,s){var a=s===e.length-1;if(t.Node.isNode(i)&&!t.Text.isText(i)&&((d.text.length||null!=d.__anchor||null!=d.__focus||d.getMarksAtIndex(0).size)&&o.push(d),o.push(i),d=a?null:t.Text.create({leaves:[{text:"",marks:n.marks}]}),r=0),"string"==typeof i&&(h(d.insertText(d.text.length,i,n.marks)),r+=i.length),t.Text.isText(i)){var y=i.__anchor,k=i.__focus,p=i.__decorations,_=d.text.length;n.key||0!=d.text.length||h(d.set("key",i.key)),i.getLeaves().forEach(function(e){var t=e.marks;n.marks&&(t=t.union(n.marks)),h(d.insertText(_,e.text,t)),_+=e.text.length}),null!=y&&(d.__anchor=new f,d.__anchor.offset=y.offset+r),null!=k&&(d.__focus=new u,d.__focus.offset=k.offset+r),null!=p&&(p.forEach(function(e){e instanceof l?e.offset+=r:(e.anchorOffset+=r,e.focusOffset+=r)}),d.__decorations=d.__decorations||[],d.__decorations=d.__decorations.concat(p)),r+=i.text.length}(i instanceof f||i instanceof c)&&(i.offset=r,d.__anchor=i),(i instanceof u||i instanceof c)&&(i.offset=r,d.__focus=i),i instanceof l&&(i.offset=r,d.__decorations=d.__decorations||[],d.__decorations=d.__decorations.concat(i))}),null!=d&&o.push(d),o}function k(e,t,n){if("function"==typeof t)return t;if("string"==typeof t&&(t={type:t}),r(t))return function(e,o,r){var i=o.key,c=a(o,["key"]),f=s({},t,{object:n,key:i,data:s({},t.data||{},c)});return d[n](e,f,r)};throw new Error("Slate hyperscript "+n+" creators can be either functions, objects or strings, but you passed: "+t)}var p=h();e.default=p,e.createHyperscript=h,Object.defineProperty(e,"__esModule",{value:!0})}); |
@@ -1,4 +0,3 @@ | ||
import isEmpty from 'is-empty'; | ||
import isPlainObject from 'is-plain-object'; | ||
import { Block, Document, Inline, Mark, Node, Range, Text, Value } from 'slate'; | ||
import { Block, Document, Inline, Mark, Node, Point, Range, Text, Value } from 'slate'; | ||
@@ -58,24 +57,73 @@ var classCallCheck = function (instance, Constructor) { | ||
/** | ||
* Create selection point constants, for comparison by reference. | ||
* Point classes that can be created at different points in the document and | ||
* then searched for afterwards, for creating ranges. | ||
* | ||
* @type {Object} | ||
* @type {Class} | ||
*/ | ||
var ANCHOR = {}; | ||
var CURSOR = {}; | ||
var FOCUS = {}; | ||
var CursorPoint = function CursorPoint() { | ||
classCallCheck(this, CursorPoint); | ||
/** | ||
* wrappers for decorator points, for comparison by instanceof, | ||
* and for composition into ranges (anchor.combine(focus), etc) | ||
*/ | ||
this.offset = null; | ||
}; | ||
var DecoratorPoint = function DecoratorPoint(_ref, marks) { | ||
var key = _ref.key, | ||
data = _ref.data; | ||
classCallCheck(this, DecoratorPoint); | ||
var AnchorPoint = function AnchorPoint() { | ||
var attrs = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; | ||
classCallCheck(this, AnchorPoint); | ||
var _attrs$key = attrs.key, | ||
key = _attrs$key === undefined ? null : _attrs$key, | ||
_attrs$offset = attrs.offset, | ||
offset = _attrs$offset === undefined ? null : _attrs$offset, | ||
_attrs$path = attrs.path, | ||
path = _attrs$path === undefined ? null : _attrs$path; | ||
_initialiseProps.call(this); | ||
this.key = key; | ||
this.offset = offset; | ||
this.path = path; | ||
}; | ||
this._key = key; | ||
var FocusPoint = function FocusPoint() { | ||
var attrs = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; | ||
classCallCheck(this, FocusPoint); | ||
var _attrs$key2 = attrs.key, | ||
key = _attrs$key2 === undefined ? null : _attrs$key2, | ||
_attrs$offset2 = attrs.offset, | ||
offset = _attrs$offset2 === undefined ? null : _attrs$offset2, | ||
_attrs$path2 = attrs.path, | ||
path = _attrs$path2 === undefined ? null : _attrs$path2; | ||
this.key = key; | ||
this.offset = offset; | ||
this.path = path; | ||
}; | ||
var DecorationPoint = function DecorationPoint(attrs) { | ||
var _this = this; | ||
classCallCheck(this, DecorationPoint); | ||
this.combine = function (focus) { | ||
if (!(focus instanceof DecorationPoint)) throw new Error('misaligned decorations'); | ||
return Range.create(_extends({ | ||
anchor: { | ||
key: _this.key, | ||
offset: _this.offset | ||
}, | ||
focus: { | ||
key: focus.key, | ||
offset: focus.offset | ||
}, | ||
marks: _this.marks, | ||
isAtomic: _this.isAtomic | ||
}, _this.attribs)); | ||
}; | ||
var _attrs$key3 = attrs.key, | ||
key = _attrs$key3 === undefined ? null : _attrs$key3, | ||
_attrs$data = attrs.data, | ||
data = _attrs$data === undefined ? {} : _attrs$data, | ||
marks = attrs.marks; | ||
this.id = key; | ||
this.offset = 0; | ||
this.marks = marks; | ||
@@ -94,36 +142,5 @@ this.attribs = data || {}; | ||
var _initialiseProps = function _initialiseProps() { | ||
var _this = this; | ||
this.withPosition = function (offset) { | ||
_this.offset = offset; | ||
return _this; | ||
}; | ||
this.addOffset = function (offset) { | ||
_this.offset += offset; | ||
return _this; | ||
}; | ||
this.withKey = function (key) { | ||
_this.key = key; | ||
return _this; | ||
}; | ||
this.combine = function (focus) { | ||
if (!(focus instanceof DecoratorPoint)) throw new Error('misaligned decorations'); | ||
return Range.create(_extends({ | ||
anchorKey: _this.key, | ||
focusKey: focus.key, | ||
anchorOffset: _this.offset, | ||
focusOffset: focus.offset, | ||
marks: _this.marks, | ||
isAtomic: _this.isAtomic | ||
}, _this.attribs)); | ||
}; | ||
}; | ||
var CREATORS = { | ||
anchor: function anchor(tagName, attributes, children) { | ||
return ANCHOR; | ||
return new AnchorPoint(attributes); | ||
}, | ||
@@ -136,3 +153,3 @@ block: function block(tagName, attributes, children) { | ||
cursor: function cursor(tagName, attributes, children) { | ||
return CURSOR; | ||
return new CursorPoint(); | ||
}, | ||
@@ -145,3 +162,3 @@ document: function document(tagName, attributes, children) { | ||
focus: function focus(tagName, attributes, children) { | ||
return FOCUS; | ||
return new FocusPoint(attributes); | ||
}, | ||
@@ -160,8 +177,14 @@ inline: function inline(tagName, attributes, children) { | ||
if (attributes.key) { | ||
return new DecoratorPoint(attributes, [{ type: tagName }]); | ||
return new DecorationPoint(_extends({}, attributes, { | ||
marks: [{ type: tagName }] | ||
})); | ||
} | ||
var nodes = createChildren(children, { key: attributes.key }); | ||
var nodes = createChildren(children); | ||
var node = nodes[0]; | ||
nodes[0].__decorations = (nodes[0].__decorations || []).concat([{ | ||
var _node$__decorations = node.__decorations, | ||
__decorations = _node$__decorations === undefined ? [] : _node$__decorations; | ||
var __decoration = { | ||
anchorOffset: 0, | ||
@@ -173,7 +196,29 @@ focusOffset: nodes.reduce(function (len, n) { | ||
isAtomic: !!attributes.data.atomic | ||
}]); | ||
}; | ||
__decorations.push(__decoration); | ||
node.__decorations = __decorations; | ||
return nodes; | ||
}, | ||
selection: function selection(tagName, attributes, children) { | ||
return Range.create(attributes); | ||
var anchor = children.find(function (c) { | ||
return c instanceof AnchorPoint; | ||
}); | ||
var focus = children.find(function (c) { | ||
return c instanceof FocusPoint; | ||
}); | ||
var selection = Range.create(_extends({}, attributes, { | ||
anchor: anchor && { | ||
key: anchor.key, | ||
offset: anchor.offset, | ||
path: anchor.path | ||
}, | ||
focus: focus && { | ||
key: focus.key, | ||
offset: focus.offset, | ||
path: focus.path | ||
} | ||
})); | ||
return selection; | ||
}, | ||
@@ -187,48 +232,62 @@ value: function value(tagName, attributes, children) { | ||
var selection = children.find(Range.isRange) || Range.create(); | ||
var props = {}; | ||
var anchor = void 0; | ||
var focus = void 0; | ||
var decorations = []; | ||
var partialDecorations = {}; | ||
var partials = {}; | ||
// Search the document's texts to see if any of them have the anchor or | ||
// focus information saved, so we can set the selection. | ||
// focus information saved, or decorations applied. | ||
if (document) { | ||
document.getTexts().forEach(function (text) { | ||
if (text.__anchor != null) { | ||
props.anchorKey = text.key; | ||
props.anchorOffset = text.__anchor; | ||
props.isFocused = true; | ||
anchor = Point.create({ key: text.key, offset: text.__anchor.offset }); | ||
} | ||
if (text.__focus != null) { | ||
props.focusKey = text.key; | ||
props.focusOffset = text.__focus; | ||
props.isFocused = true; | ||
focus = Point.create({ key: text.key, offset: text.__focus.offset }); | ||
} | ||
}); | ||
// now check for decorations and hoist them to the top | ||
document.getTexts().forEach(function (text) { | ||
if (text.__decorations != null) { | ||
// add in all mark-like (keyless) decorations | ||
decorations = decorations.concat(text.__decorations.filter(function (d) { | ||
return d._key === undefined; | ||
}).map(function (d) { | ||
return Range.create(_extends({}, d, { | ||
anchorKey: text.key, | ||
focusKey: text.key | ||
})); | ||
})); | ||
text.__decorations.forEach(function (dec) { | ||
var id = dec.id; | ||
// store or combine partial decorations (keyed with anchor / focus) | ||
text.__decorations.filter(function (d) { | ||
return d._key !== undefined; | ||
}).forEach(function (partial) { | ||
if (partialDecorations[partial._key]) { | ||
decorations.push(partialDecorations[partial._key].combine(partial.withKey(text.key))); | ||
var range = void 0; | ||
delete partialDecorations[partial._key]; | ||
return; | ||
if (!id) { | ||
range = Range.create({ | ||
anchor: { | ||
key: text.key, | ||
offset: dec.anchorOffset | ||
}, | ||
focus: { | ||
key: text.key, | ||
offset: dec.focusOffset | ||
}, | ||
marks: dec.marks, | ||
isAtomic: dec.isAtomic | ||
}); | ||
} else if (partials[id]) { | ||
var partial = partials[id]; | ||
delete partials[id]; | ||
range = Range.create({ | ||
anchor: { | ||
key: partial.key, | ||
offset: partial.offset | ||
}, | ||
focus: { | ||
key: text.key, | ||
offset: dec.offset | ||
}, | ||
marks: partial.marks, | ||
isAtomic: partial.isAtomic | ||
}); | ||
} else { | ||
dec.key = text.key; | ||
partials[id] = dec; | ||
} | ||
partialDecorations[partial._key] = partial.withKey(text.key); | ||
if (range) { | ||
decorations.push(range); | ||
} | ||
}); | ||
@@ -239,13 +298,12 @@ } | ||
// should have no more parital decorations outstanding (all paired) | ||
if (Object.keys(partialDecorations).length > 0) { | ||
throw new Error('Slate hyperscript must have both an anchor and focus defined for each keyed decorator.'); | ||
if (Object.keys(partials).length > 0) { | ||
throw new Error('Slate hyperscript must have both a start and an end defined for each decoration using the `key=` prop.'); | ||
} | ||
if (props.anchorKey && !props.focusKey) { | ||
throw new Error('Slate hyperscript must have both `<anchor/>` and `<focus/>` defined if one is defined, but you only defined `<anchor/>`. For collapsed selections, use `<cursor/>`.'); | ||
if (anchor && !focus) { | ||
throw new Error('Slate hyperscript ranges must have both `<anchor />` and `<focus />` defined if one is defined, but you only defined `<anchor />`. For collapsed selections, use `<cursor />` instead.'); | ||
} | ||
if (!props.anchorKey && props.focusKey) { | ||
throw new Error('Slate hyperscript must have both `<anchor/>` and `<focus/>` defined if one is defined, but you only defined `<focus/>`. For collapsed selections, use `<cursor/>`.'); | ||
if (!anchor && focus) { | ||
throw new Error('Slate hyperscript ranges must have both `<anchor />` and `<focus />` defined if one is defined, but you only defined `<focus />`. For collapsed selections, use `<cursor />` instead.'); | ||
} | ||
@@ -255,4 +313,6 @@ | ||
if (!isEmpty(props)) { | ||
selection = selection.merge(props).normalize(value.document); | ||
if (anchor || focus) { | ||
selection = selection.setPoints([anchor, focus]); | ||
selection = selection.merge({ isFocused: true }); | ||
selection = selection.normalize(value.document); | ||
value = value.set('selection', selection); | ||
@@ -403,12 +463,24 @@ } | ||
if (__anchor != null) node.__anchor = __anchor + length; | ||
if (__focus != null) node.__focus = __focus + length; | ||
if (__anchor != null) { | ||
node.__anchor = new AnchorPoint(); | ||
node.__anchor.offset = __anchor.offset + length; | ||
} | ||
if (__focus != null) { | ||
node.__focus = new FocusPoint(); | ||
node.__focus.offset = __focus.offset + length; | ||
} | ||
if (__decorations != null) { | ||
node.__decorations = (node.__decorations || []).concat(__decorations.map(function (d) { | ||
return d instanceof DecoratorPoint ? d.addOffset(length) : _extends({}, d, { | ||
anchorOffset: d.anchorOffset + length, | ||
focusOffset: d.focusOffset + length | ||
}); | ||
})); | ||
__decorations.forEach(function (d) { | ||
if (d instanceof DecorationPoint) { | ||
d.offset += length; | ||
} else { | ||
d.anchorOffset += length; | ||
d.focusOffset += length; | ||
} | ||
}); | ||
node.__decorations = node.__decorations || []; | ||
node.__decorations = node.__decorations.concat(__decorations); | ||
} | ||
@@ -419,10 +491,17 @@ | ||
// If the child is a selection object store the current position. | ||
if (child == ANCHOR || child == CURSOR) node.__anchor = length; | ||
if (child == FOCUS || child == CURSOR) node.__focus = length; | ||
if (child instanceof AnchorPoint || child instanceof CursorPoint) { | ||
child.offset = length; | ||
node.__anchor = child; | ||
} | ||
// if child is a decorator point, store it as partial decorator | ||
if (child instanceof DecoratorPoint) { | ||
node.__decorations = (node.__decorations || []).concat([child.withPosition(length)]); | ||
if (child instanceof FocusPoint || child instanceof CursorPoint) { | ||
child.offset = length; | ||
node.__focus = child; | ||
} | ||
if (child instanceof DecorationPoint) { | ||
child.offset = length; | ||
node.__decorations = node.__decorations || []; | ||
node.__decorations = node.__decorations.concat(child); | ||
} | ||
}); | ||
@@ -429,0 +508,0 @@ |
@@ -7,3 +7,2 @@ 'use strict'; | ||
var isEmpty = _interopDefault(require('is-empty')); | ||
var isPlainObject = _interopDefault(require('is-plain-object')); | ||
@@ -65,24 +64,73 @@ var slate = require('slate'); | ||
/** | ||
* Create selection point constants, for comparison by reference. | ||
* Point classes that can be created at different points in the document and | ||
* then searched for afterwards, for creating ranges. | ||
* | ||
* @type {Object} | ||
* @type {Class} | ||
*/ | ||
var ANCHOR = {}; | ||
var CURSOR = {}; | ||
var FOCUS = {}; | ||
var CursorPoint = function CursorPoint() { | ||
classCallCheck(this, CursorPoint); | ||
/** | ||
* wrappers for decorator points, for comparison by instanceof, | ||
* and for composition into ranges (anchor.combine(focus), etc) | ||
*/ | ||
this.offset = null; | ||
}; | ||
var DecoratorPoint = function DecoratorPoint(_ref, marks) { | ||
var key = _ref.key, | ||
data = _ref.data; | ||
classCallCheck(this, DecoratorPoint); | ||
var AnchorPoint = function AnchorPoint() { | ||
var attrs = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; | ||
classCallCheck(this, AnchorPoint); | ||
var _attrs$key = attrs.key, | ||
key = _attrs$key === undefined ? null : _attrs$key, | ||
_attrs$offset = attrs.offset, | ||
offset = _attrs$offset === undefined ? null : _attrs$offset, | ||
_attrs$path = attrs.path, | ||
path = _attrs$path === undefined ? null : _attrs$path; | ||
_initialiseProps.call(this); | ||
this.key = key; | ||
this.offset = offset; | ||
this.path = path; | ||
}; | ||
this._key = key; | ||
var FocusPoint = function FocusPoint() { | ||
var attrs = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; | ||
classCallCheck(this, FocusPoint); | ||
var _attrs$key2 = attrs.key, | ||
key = _attrs$key2 === undefined ? null : _attrs$key2, | ||
_attrs$offset2 = attrs.offset, | ||
offset = _attrs$offset2 === undefined ? null : _attrs$offset2, | ||
_attrs$path2 = attrs.path, | ||
path = _attrs$path2 === undefined ? null : _attrs$path2; | ||
this.key = key; | ||
this.offset = offset; | ||
this.path = path; | ||
}; | ||
var DecorationPoint = function DecorationPoint(attrs) { | ||
var _this = this; | ||
classCallCheck(this, DecorationPoint); | ||
this.combine = function (focus) { | ||
if (!(focus instanceof DecorationPoint)) throw new Error('misaligned decorations'); | ||
return slate.Range.create(_extends({ | ||
anchor: { | ||
key: _this.key, | ||
offset: _this.offset | ||
}, | ||
focus: { | ||
key: focus.key, | ||
offset: focus.offset | ||
}, | ||
marks: _this.marks, | ||
isAtomic: _this.isAtomic | ||
}, _this.attribs)); | ||
}; | ||
var _attrs$key3 = attrs.key, | ||
key = _attrs$key3 === undefined ? null : _attrs$key3, | ||
_attrs$data = attrs.data, | ||
data = _attrs$data === undefined ? {} : _attrs$data, | ||
marks = attrs.marks; | ||
this.id = key; | ||
this.offset = 0; | ||
this.marks = marks; | ||
@@ -101,36 +149,5 @@ this.attribs = data || {}; | ||
var _initialiseProps = function _initialiseProps() { | ||
var _this = this; | ||
this.withPosition = function (offset) { | ||
_this.offset = offset; | ||
return _this; | ||
}; | ||
this.addOffset = function (offset) { | ||
_this.offset += offset; | ||
return _this; | ||
}; | ||
this.withKey = function (key) { | ||
_this.key = key; | ||
return _this; | ||
}; | ||
this.combine = function (focus) { | ||
if (!(focus instanceof DecoratorPoint)) throw new Error('misaligned decorations'); | ||
return slate.Range.create(_extends({ | ||
anchorKey: _this.key, | ||
focusKey: focus.key, | ||
anchorOffset: _this.offset, | ||
focusOffset: focus.offset, | ||
marks: _this.marks, | ||
isAtomic: _this.isAtomic | ||
}, _this.attribs)); | ||
}; | ||
}; | ||
var CREATORS = { | ||
anchor: function anchor(tagName, attributes, children) { | ||
return ANCHOR; | ||
return new AnchorPoint(attributes); | ||
}, | ||
@@ -143,3 +160,3 @@ block: function block(tagName, attributes, children) { | ||
cursor: function cursor(tagName, attributes, children) { | ||
return CURSOR; | ||
return new CursorPoint(); | ||
}, | ||
@@ -152,3 +169,3 @@ document: function document(tagName, attributes, children) { | ||
focus: function focus(tagName, attributes, children) { | ||
return FOCUS; | ||
return new FocusPoint(attributes); | ||
}, | ||
@@ -167,8 +184,14 @@ inline: function inline(tagName, attributes, children) { | ||
if (attributes.key) { | ||
return new DecoratorPoint(attributes, [{ type: tagName }]); | ||
return new DecorationPoint(_extends({}, attributes, { | ||
marks: [{ type: tagName }] | ||
})); | ||
} | ||
var nodes = createChildren(children, { key: attributes.key }); | ||
var nodes = createChildren(children); | ||
var node = nodes[0]; | ||
nodes[0].__decorations = (nodes[0].__decorations || []).concat([{ | ||
var _node$__decorations = node.__decorations, | ||
__decorations = _node$__decorations === undefined ? [] : _node$__decorations; | ||
var __decoration = { | ||
anchorOffset: 0, | ||
@@ -180,7 +203,29 @@ focusOffset: nodes.reduce(function (len, n) { | ||
isAtomic: !!attributes.data.atomic | ||
}]); | ||
}; | ||
__decorations.push(__decoration); | ||
node.__decorations = __decorations; | ||
return nodes; | ||
}, | ||
selection: function selection(tagName, attributes, children) { | ||
return slate.Range.create(attributes); | ||
var anchor = children.find(function (c) { | ||
return c instanceof AnchorPoint; | ||
}); | ||
var focus = children.find(function (c) { | ||
return c instanceof FocusPoint; | ||
}); | ||
var selection = slate.Range.create(_extends({}, attributes, { | ||
anchor: anchor && { | ||
key: anchor.key, | ||
offset: anchor.offset, | ||
path: anchor.path | ||
}, | ||
focus: focus && { | ||
key: focus.key, | ||
offset: focus.offset, | ||
path: focus.path | ||
} | ||
})); | ||
return selection; | ||
}, | ||
@@ -194,48 +239,62 @@ value: function value(tagName, attributes, children) { | ||
var selection = children.find(slate.Range.isRange) || slate.Range.create(); | ||
var props = {}; | ||
var anchor = void 0; | ||
var focus = void 0; | ||
var decorations = []; | ||
var partialDecorations = {}; | ||
var partials = {}; | ||
// Search the document's texts to see if any of them have the anchor or | ||
// focus information saved, so we can set the selection. | ||
// focus information saved, or decorations applied. | ||
if (document) { | ||
document.getTexts().forEach(function (text) { | ||
if (text.__anchor != null) { | ||
props.anchorKey = text.key; | ||
props.anchorOffset = text.__anchor; | ||
props.isFocused = true; | ||
anchor = slate.Point.create({ key: text.key, offset: text.__anchor.offset }); | ||
} | ||
if (text.__focus != null) { | ||
props.focusKey = text.key; | ||
props.focusOffset = text.__focus; | ||
props.isFocused = true; | ||
focus = slate.Point.create({ key: text.key, offset: text.__focus.offset }); | ||
} | ||
}); | ||
// now check for decorations and hoist them to the top | ||
document.getTexts().forEach(function (text) { | ||
if (text.__decorations != null) { | ||
// add in all mark-like (keyless) decorations | ||
decorations = decorations.concat(text.__decorations.filter(function (d) { | ||
return d._key === undefined; | ||
}).map(function (d) { | ||
return slate.Range.create(_extends({}, d, { | ||
anchorKey: text.key, | ||
focusKey: text.key | ||
})); | ||
})); | ||
text.__decorations.forEach(function (dec) { | ||
var id = dec.id; | ||
// store or combine partial decorations (keyed with anchor / focus) | ||
text.__decorations.filter(function (d) { | ||
return d._key !== undefined; | ||
}).forEach(function (partial) { | ||
if (partialDecorations[partial._key]) { | ||
decorations.push(partialDecorations[partial._key].combine(partial.withKey(text.key))); | ||
var range = void 0; | ||
delete partialDecorations[partial._key]; | ||
return; | ||
if (!id) { | ||
range = slate.Range.create({ | ||
anchor: { | ||
key: text.key, | ||
offset: dec.anchorOffset | ||
}, | ||
focus: { | ||
key: text.key, | ||
offset: dec.focusOffset | ||
}, | ||
marks: dec.marks, | ||
isAtomic: dec.isAtomic | ||
}); | ||
} else if (partials[id]) { | ||
var partial = partials[id]; | ||
delete partials[id]; | ||
range = slate.Range.create({ | ||
anchor: { | ||
key: partial.key, | ||
offset: partial.offset | ||
}, | ||
focus: { | ||
key: text.key, | ||
offset: dec.offset | ||
}, | ||
marks: partial.marks, | ||
isAtomic: partial.isAtomic | ||
}); | ||
} else { | ||
dec.key = text.key; | ||
partials[id] = dec; | ||
} | ||
partialDecorations[partial._key] = partial.withKey(text.key); | ||
if (range) { | ||
decorations.push(range); | ||
} | ||
}); | ||
@@ -246,13 +305,12 @@ } | ||
// should have no more parital decorations outstanding (all paired) | ||
if (Object.keys(partialDecorations).length > 0) { | ||
throw new Error('Slate hyperscript must have both an anchor and focus defined for each keyed decorator.'); | ||
if (Object.keys(partials).length > 0) { | ||
throw new Error('Slate hyperscript must have both a start and an end defined for each decoration using the `key=` prop.'); | ||
} | ||
if (props.anchorKey && !props.focusKey) { | ||
throw new Error('Slate hyperscript must have both `<anchor/>` and `<focus/>` defined if one is defined, but you only defined `<anchor/>`. For collapsed selections, use `<cursor/>`.'); | ||
if (anchor && !focus) { | ||
throw new Error('Slate hyperscript ranges must have both `<anchor />` and `<focus />` defined if one is defined, but you only defined `<anchor />`. For collapsed selections, use `<cursor />` instead.'); | ||
} | ||
if (!props.anchorKey && props.focusKey) { | ||
throw new Error('Slate hyperscript must have both `<anchor/>` and `<focus/>` defined if one is defined, but you only defined `<focus/>`. For collapsed selections, use `<cursor/>`.'); | ||
if (!anchor && focus) { | ||
throw new Error('Slate hyperscript ranges must have both `<anchor />` and `<focus />` defined if one is defined, but you only defined `<focus />`. For collapsed selections, use `<cursor />` instead.'); | ||
} | ||
@@ -262,4 +320,6 @@ | ||
if (!isEmpty(props)) { | ||
selection = selection.merge(props).normalize(value.document); | ||
if (anchor || focus) { | ||
selection = selection.setPoints([anchor, focus]); | ||
selection = selection.merge({ isFocused: true }); | ||
selection = selection.normalize(value.document); | ||
value = value.set('selection', selection); | ||
@@ -410,12 +470,24 @@ } | ||
if (__anchor != null) node.__anchor = __anchor + length; | ||
if (__focus != null) node.__focus = __focus + length; | ||
if (__anchor != null) { | ||
node.__anchor = new AnchorPoint(); | ||
node.__anchor.offset = __anchor.offset + length; | ||
} | ||
if (__focus != null) { | ||
node.__focus = new FocusPoint(); | ||
node.__focus.offset = __focus.offset + length; | ||
} | ||
if (__decorations != null) { | ||
node.__decorations = (node.__decorations || []).concat(__decorations.map(function (d) { | ||
return d instanceof DecoratorPoint ? d.addOffset(length) : _extends({}, d, { | ||
anchorOffset: d.anchorOffset + length, | ||
focusOffset: d.focusOffset + length | ||
}); | ||
})); | ||
__decorations.forEach(function (d) { | ||
if (d instanceof DecorationPoint) { | ||
d.offset += length; | ||
} else { | ||
d.anchorOffset += length; | ||
d.focusOffset += length; | ||
} | ||
}); | ||
node.__decorations = node.__decorations || []; | ||
node.__decorations = node.__decorations.concat(__decorations); | ||
} | ||
@@ -426,10 +498,17 @@ | ||
// If the child is a selection object store the current position. | ||
if (child == ANCHOR || child == CURSOR) node.__anchor = length; | ||
if (child == FOCUS || child == CURSOR) node.__focus = length; | ||
if (child instanceof AnchorPoint || child instanceof CursorPoint) { | ||
child.offset = length; | ||
node.__anchor = child; | ||
} | ||
// if child is a decorator point, store it as partial decorator | ||
if (child instanceof DecoratorPoint) { | ||
node.__decorations = (node.__decorations || []).concat([child.withPosition(length)]); | ||
if (child instanceof FocusPoint || child instanceof CursorPoint) { | ||
child.offset = length; | ||
node.__focus = child; | ||
} | ||
if (child instanceof DecorationPoint) { | ||
child.offset = length; | ||
node.__decorations = node.__decorations || []; | ||
node.__decorations = node.__decorations.concat(child); | ||
} | ||
}); | ||
@@ -436,0 +515,0 @@ |
{ | ||
"name": "slate-hyperscript", | ||
"description": "A hyperscript helper for creating Slate documents.", | ||
"version": "0.6.3", | ||
"version": "0.7.0", | ||
"license": "MIT", | ||
@@ -21,7 +21,7 @@ "repository": "git://github.com/ianstormtaylor/slate.git", | ||
"peerDependencies": { | ||
"slate": ">=0.35.0" | ||
"slate": ">=0.37.0" | ||
}, | ||
"devDependencies": { | ||
"mocha": "^2.5.3", | ||
"slate": "^0.36.2" | ||
"slate": "^0.37.0" | ||
}, | ||
@@ -28,0 +28,0 @@ "scripts": { |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
116458
1556