Socket
Socket
Sign inDemoInstall

@craftjs/utils

Package Overview
Dependencies
Maintainers
1
Versions
74
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@craftjs/utils - npm Package Compare versions

Comparing version 0.2.0-beta.10 to 0.2.0-beta.11

8

CHANGELOG.md

@@ -6,2 +6,10 @@ # Change Log

# [0.2.0-beta.11](https://github.com/prevwong/craft.js/compare/v0.2.0-beta.10...v0.2.0-beta.11) (2023-05-30)
**Note:** Version bump only for package @craftjs/utils
# [0.2.0-beta.10](https://github.com/prevwong/craft.js/compare/v0.2.0-beta.9...v0.2.0-beta.10) (2023-04-09)

@@ -8,0 +16,0 @@

1028

dist/cjs/index.js

@@ -1,1 +0,1027 @@

"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("immer"),t=require("lodash/isEqualWith"),n=require("react"),r=require("shallowequal"),o=require("nanoid"),i=require("tiny-invariant"),a=require("react-dom");function s(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var c=s(e),u=s(t),l=s(n),f=s(r),d=s(i),p=s(a);function h(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function y(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?h(Object(n),!0).forEach((function(t){g(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):h(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function v(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function E(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,C(r.key),r)}}function b(e,t,n){return t&&E(e.prototype,t),n&&E(e,n),Object.defineProperty(e,"prototype",{writable:!1}),e}function g(e,t,n){return(t=C(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function O(e){return O=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(e){return e.__proto__||Object.getPrototypeOf(e)},O(e)}function m(e,t){return m=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,t){return e.__proto__=t,e},m(e,t)}function R(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function _(){return _="undefined"!=typeof Reflect&&Reflect.get?Reflect.get.bind():function(e,t,n){var r=function(e,t){for(;!Object.prototype.hasOwnProperty.call(e,t)&&null!==(e=O(e)););return e}(e,t);if(r){var o=Object.getOwnPropertyDescriptor(r,t);return o.get?o.get.call(arguments.length<3?e:n):o.value}},_.apply(this,arguments)}function w(e,t){return x(e)||function(e,t){var n=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=n){var r,o,i,a,s=[],c=!0,u=!1;try{if(i=(n=n.call(e)).next,0===t){if(Object(n)!==n)return;c=!1}else for(;!(c=(r=i.call(n)).done)&&(s.push(r.value),s.length!==t);c=!0);}catch(e){u=!0,o=e}finally{try{if(!c&&null!=n.return&&(a=n.return(),Object(a)!==a))return}finally{if(u)throw o}}return s}}(e,t)||N(e,t)||P()}function T(e){return function(e){if(Array.isArray(e))return D(e)}(e)||I(e)||N(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function x(e){if(Array.isArray(e))return e}function I(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}function N(e,t){if(e){if("string"==typeof e)return D(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?D(e,t):void 0}}function D(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function P(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function C(e){var t=function(e,t){if("object"!=typeof e||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,"string");if("object"!=typeof r)return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e);return"symbol"==typeof t?t:String(t)}var k={UNDO:"HISTORY_UNDO",REDO:"HISTORY_REDO",THROTTLE:"HISTORY_THROTTLE",IGNORE:"HISTORY_IGNORE",MERGE:"HISTORY_MERGE",CLEAR:"HISTORY_CLEAR"},A=function(){function t(){v(this,t),g(this,"timeline",[]),g(this,"pointer",-1)}return b(t,[{key:"add",value:function(e,t){0===e.length&&0===t.length||(this.pointer=this.pointer+1,this.timeline.length=this.pointer,this.timeline[this.pointer]={patches:e,inversePatches:t,timestamp:Date.now()})}},{key:"throttleAdd",value:function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:500;if(0!==e.length||0!==t.length){if(this.timeline.length&&this.pointer>=0){var r=this.timeline[this.pointer],o=r.patches,i=r.inversePatches,a=r.timestamp;if((new Date).getTime()-a<n)return void(this.timeline[this.pointer]={timestamp:a,patches:[].concat(T(o),T(e)),inversePatches:[].concat(T(t),T(i))})}this.add(e,t)}}},{key:"merge",value:function(e,t){if(0!==e.length||0!==t.length)if(this.timeline.length&&this.pointer>=0){var n=this.timeline[this.pointer],r=n.inversePatches;this.timeline[this.pointer]={timestamp:n.timestamp,patches:[].concat(T(n.patches),T(e)),inversePatches:[].concat(T(t),T(r))}}else this.add(e,t)}},{key:"clear",value:function(){this.timeline=[],this.pointer=-1}},{key:"canUndo",value:function(){return this.pointer>=0}},{key:"canRedo",value:function(){return this.pointer<this.timeline.length-1}},{key:"undo",value:function(t){if(this.canUndo()){var n=this.timeline[this.pointer].inversePatches;return this.pointer=this.pointer-1,e.applyPatches(t,n)}}},{key:"redo",value:function(t){if(this.canRedo())return this.pointer=this.pointer+1,e.applyPatches(t,this.timeline[this.pointer].patches)}}]),t}();function S(e,t,n){var r=Object.keys(e()).reduce((function(n,r){return y(y({},n),{},g({},r,(function(){var n;return(n=e(t()))[r].apply(n,arguments)})))}),{});return y(y({},r),{},{history:{canUndo:function(){return n.canUndo()},canRedo:function(){return n.canRedo()}}})}e.enableMapSet(),e.enablePatches();var j,H=function(){function e(t){v(this,e),g(this,"getState",void 0),g(this,"subscribers",[]),this.getState=t}return b(e,[{key:"subscribe",value:function(e,t,n){var r=this,o=new M((function(){return e(r.getState())}),t,n);return this.subscribers.push(o),this.unsubscribe.bind(this,o)}},{key:"unsubscribe",value:function(e){if(this.subscribers.length){var t=this.subscribers.indexOf(e);if(t>-1)return this.subscribers.splice(t,1)}}},{key:"notify",value:function(){this.subscribers.forEach((function(e){return e.collect()}))}}]),e}(),M=function(){function e(t,n){var r=arguments.length>2&&void 0!==arguments[2]&&arguments[2];v(this,e),g(this,"collected",void 0),g(this,"collector",void 0),g(this,"onChange",void 0),g(this,"id",void 0),this.collector=t,this.onChange=n,r&&this.collect()}return b(e,[{key:"collect",value:function(){try{var e=this.collector();u.default(e,this.collected)||(this.collected=e,this.onChange&&this.onChange(this.collected))}catch(e){console.warn(e)}}}]),e}(),L=function(){return o.nanoid(arguments.length>0&&void 0!==arguments[0]?arguments[0]:10)},U=function(){function e(){v(this,e),g(this,"isEnabled",!0),g(this,"elementIdMap",new WeakMap),g(this,"registry",new Map)}return b(e,[{key:"getElementId",value:function(e){var t=this.elementIdMap.get(e);if(t)return t;var n=L();return this.elementIdMap.set(e,n),n}},{key:"getConnectorId",value:function(e,t){var n=this.getElementId(e);return"".concat(t,"--").concat(n)}},{key:"register",value:function(e,t){var n=this,r=this.getByElement(e,t.name);if(r){if(f.default(t.required,r.required))return r;this.getByElement(e,t.name).disable()}var o=null,i=this.getConnectorId(e,t.name);return this.registry.set(i,{id:i,required:t.required,enable:function(){o&&o(),o=t.connector(e,t.required,t.options)},disable:function(){o&&o()},remove:function(){return n.remove(i)}}),this.isEnabled&&this.registry.get(i).enable(),this.registry.get(i)}},{key:"get",value:function(e){return this.registry.get(e)}},{key:"remove",value:function(e){var t=this.get(e);t&&(t.disable(),this.registry.delete(t.id))}},{key:"enable",value:function(){this.isEnabled=!0,this.registry.forEach((function(e){e.enable()}))}},{key:"disable",value:function(){this.isEnabled=!1,this.registry.forEach((function(e){e.disable()}))}},{key:"getByElement",value:function(e,t){return this.get(this.getConnectorId(e,t))}},{key:"removeByElement",value:function(e,t){return this.remove(this.getConnectorId(e,t))}},{key:"clear",value:function(){this.disable(),this.elementIdMap=new WeakMap,this.registry=new Map}}]),e}();exports.EventHandlerUpdates=void 0,(j=exports.EventHandlerUpdates||(exports.EventHandlerUpdates={}))[j.HandlerDisabled=0]="HandlerDisabled",j[j.HandlerEnabled=1]="HandlerEnabled";var V=function(){function e(t){v(this,e),g(this,"options",void 0),g(this,"registry",new U),g(this,"subscribers",new Set),this.options=t}return b(e,[{key:"listen",value:function(e){var t=this;return this.subscribers.add(e),function(){return t.subscribers.delete(e)}}},{key:"disable",value:function(){this.onDisable&&this.onDisable(),this.registry.disable(),this.subscribers.forEach((function(e){e(exports.EventHandlerUpdates.HandlerDisabled)}))}},{key:"enable",value:function(){this.onEnable&&this.onEnable(),this.registry.enable(),this.subscribers.forEach((function(e){e(exports.EventHandlerUpdates.HandlerEnabled)}))}},{key:"cleanup",value:function(){this.disable(),this.subscribers.clear(),this.registry.clear()}},{key:"addCraftEventListener",value:function(e,t,n,r){var o=function(r){(function(e,t,n){e.craft||(e.craft={stopPropagation:function(){},blockedEvents:{}});for(var r=e.craft&&e.craft.blockedEvents[t]||[],o=0;o<r.length;o++){var i=r[o];if(n!==i&&n.contains(i))return!0}return!1})(r,t,e)||(r.craft.stopPropagation=function(){r.craft.blockedEvents[t]||(r.craft.blockedEvents[t]=[]),r.craft.blockedEvents[t].push(e)},n(r))};return e.addEventListener(t,o,r),function(){return e.removeEventListener(t,o,r)}}},{key:"createConnectorsUsage",value:function(){var e=this,t=this.handlers(),n=new Set,r=!1,o=new Map;return{connectors:Object.entries(t).reduce((function(t,i){var a=w(i,2),s=a[0],c=a[1];return y(y({},t),{},g({},s,(function(t,i,a){var u=function(){var r=e.registry.register(t,{required:i,name:s,options:a,connector:c});return n.add(r.id),r};return o.set(e.registry.getConnectorId(t,s),u),r&&u(),t})))}),{}),register:function(){r=!0,o.forEach((function(e){e()}))},cleanup:function(){r=!1,n.forEach((function(t){return e.registry.remove(t)}))}}}},{key:"derive",value:function(e,t){return new e(this,t)}},{key:"createProxyHandlers",value:function(e,t){var n=[],r=e.handlers(),o=new Proxy(r,{get:function(e,t,o){return t in r==0?Reflect.get(e,t,o):function(e){for(var o=arguments.length,i=new Array(o>1?o-1:0),a=1;a<o;a++)i[a-1]=arguments[a];var s=r[t].apply(r,[e].concat(i));s&&n.push(s)}}});return t(o),function(){n.forEach((function(e){e()}))}}},{key:"reflect",value:function(e){return this.createProxyHandlers(this,e)}}]),e}(),q=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),Object.defineProperty(e,"prototype",{writable:!1}),t&&m(e,t)}(o,V);var t,n,r=(t=o,n=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,r=O(t);if(n){var o=O(this).constructor;e=Reflect.construct(r,arguments,o)}else e=r.apply(this,arguments);return function(e,t){if(t&&("object"==typeof t||"function"==typeof t))return t;if(void 0!==t)throw new TypeError("Derived constructors may only return object or undefined");return R(e)}(this,e)});function o(e,t){var n;return v(this,o),g(R(n=r.call(this,t)),"derived",void 0),g(R(n),"unsubscribeParentHandlerListener",void 0),n.derived=e,n.options=t,n.unsubscribeParentHandlerListener=n.derived.listen((function(e){switch(e){case exports.EventHandlerUpdates.HandlerEnabled:return n.enable();case exports.EventHandlerUpdates.HandlerDisabled:return n.disable();default:return}})),n}return b(o,[{key:"inherit",value:function(e){return this.createProxyHandlers(this.derived,e)}},{key:"cleanup",value:function(){_(O(o.prototype),"cleanup",this).call(this),this.unsubscribeParentHandlerListener()}}]),o}();function G(e,t){t&&("function"==typeof e?e(t):e.current=t)}function B(e,t){const r=e.ref;return d.default("string"!=typeof r,"Cannot connect to an element with an existing string ref. Please convert it to use a callback ref instead, or wrap it into a <span> or <div>. Read more: https://facebook.github.io/react/docs/more-about-refs.html#the-ref-callback-attribute"),n.cloneElement(e,r?{ref:e=>{G(r,e),G(t,e)}}:{ref:t})}function Y(e){return(t=null,...r)=>{if(!n.isValidElement(t)){if(!t)return;const n=t;return n&&e(n,...r),n}const o=t;return function(e){if("string"!=typeof e.type)throw new Error}(o),B(o,e)}}var W=function(){return"undefined"!=typeof window};exports.DEPRECATED_ROOT_NODE="canvas-ROOT",exports.DerivedEventHandlers=q,exports.ERROR_CANNOT_DRAG="The node has specified a canDrag() rule that prevents it from being dragged",exports.ERROR_DELETE_TOP_LEVEL_NODE="Attempting to delete a top-level Node",exports.ERROR_DESERIALIZE_COMPONENT_NOT_IN_RESOLVER="An Error occurred while deserializing components: Cannot find component <%displayName% /> in resolver map. Please check your resolver in <Editor />\n\nAvailable components in resolver: %availableComponents%\n\nMore info: https://craft.js.org/r/docs/api/editor#props",exports.ERROR_DUPLICATE_NODEID="Attempting to add a node with duplicated id",exports.ERROR_INFINITE_CANVAS="The component specified in the <Canvas> `is` prop has additional Canvas specified in it's render template.",exports.ERROR_INVALID_NODEID="Node does not exist, it may have been removed",exports.ERROR_INVALID_NODE_ID="Invalid parameter Node Id specified",exports.ERROR_MISSING_PLACEHOLDER_PLACEMENT="Placeholder required placement info (parent, index, or where) is missing",exports.ERROR_MOVE_CANNOT_DROP="Node cannot be dropped into target parent",exports.ERROR_MOVE_INCOMING_PARENT="Target parent rejects incoming node",exports.ERROR_MOVE_NONCANVAS_CHILD="Cannot move node that is not a direct child of a Canvas node",exports.ERROR_MOVE_OUTGOING_PARENT="Current parent rejects outgoing node",exports.ERROR_MOVE_ROOT_NODE="Root Node cannot be moved",exports.ERROR_MOVE_TOP_LEVEL_NODE="A top-level Node cannot be moved",exports.ERROR_MOVE_TO_DESCENDANT="Cannot move node into a descendant",exports.ERROR_MOVE_TO_NONCANVAS_PARENT="Cannot move node into a non-Canvas parent",exports.ERROR_NOPARENT="Parent id cannot be ommited",exports.ERROR_NOT_IN_RESOLVER="The component type specified for this node (%node_type%) does not exist in the resolver",exports.ERROR_RESOLVER_NOT_AN_OBJECT="Resolver in <Editor /> has to be an object. For (de)serialization Craft.js needs a list of all the User Components. \n \nMore info: https://craft.js.org/r/docs/api/editor#props",exports.ERROR_TOP_LEVEL_ELEMENT_NO_ID='A <Element /> that is used inside a User Component must specify an `id` prop, eg: <Element id="text_element">...</Element> ',exports.ERROR_USE_EDITOR_OUTSIDE_OF_EDITOR_CONTEXT="You can only use useEditor in the context of <Editor />. \n\nPlease only use useEditor in components that are children of the <Editor /> component.",exports.ERROR_USE_NODE_OUTSIDE_OF_EDITOR_CONTEXT="You can only use useNode in the context of <Editor />. \n\nPlease only use useNode in components that are children of the <Editor /> component.",exports.EventHandlers=V,exports.HISTORY_ACTIONS=k,exports.History=A,exports.ROOT_NODE="ROOT",exports.RenderIndicator=({style:e,parentDom:t})=>{const n=l.default.createElement("div",{style:{position:"fixed",display:"block",opacity:1,borderStyle:"solid",borderWidth:"1px",borderColor:"transparent",zIndex:99999,...e}});return t&&t.ownerDocument!==document?p.default.createPortal(n,t.ownerDocument.body):n},exports.cloneWithRef=B,exports.createQuery=S,exports.deprecationWarning=function(e,t){var n="Deprecation warning: ".concat(e," will be deprecated in future relases."),r=t.suggest,o=t.doc;r&&(n+=" Please use ".concat(r," instead.")),o&&(n+="(".concat(o,")")),console.warn(n)},exports.getDOMInfo=function(e){var t=e.getBoundingClientRect(),n=t.x,r=t.y,o=t.top,i=t.left,a=t.bottom,s=t.right,c=t.width,u=t.height,l=window.getComputedStyle(e),f={left:parseInt(l.marginLeft),right:parseInt(l.marginRight),bottom:parseInt(l.marginBottom),top:parseInt(l.marginTop)},d={left:parseInt(l.paddingLeft),right:parseInt(l.paddingRight),bottom:parseInt(l.paddingBottom),top:parseInt(l.paddingTop)};return{x:n,y:r,top:o,left:i,bottom:a,right:s,width:c,height:u,outerWidth:Math.round(c+f.left+f.right),outerHeight:Math.round(u+f.top+f.bottom),margin:f,padding:d,inFlow:e.parentElement&&!!function(t){var n=getComputedStyle(t);if(!(l.overflow&&"visible"!==l.overflow||"none"!==n.float||"grid"===n.display||"flex"===n.display&&"column"!==n["flex-direction"])){switch(l.position){case"static":case"relative":break;default:return}switch(e.tagName){case"TR":case"TBODY":case"THEAD":case"TFOOT":return!0}switch(l.display){case"block":case"list-item":case"table":case"flex":case"grid":return!0}}}(e.parentElement)}},exports.getRandomId=L,exports.isChromium=function(){return W()&&/Chrome/i.test(window.navigator.userAgent)},exports.isClientSide=W,exports.isLinux=function(){return W()&&/Linux/i.test(window.navigator.userAgent)},exports.useCollector=function(e,t){const{subscribe:r,getState:o,actions:i,query:a}=e,s=n.useRef(!0),c=n.useRef(null),u=n.useRef(t);u.current=t;const l=n.useCallback((e=>({...e,actions:i,query:a})),[i,a]);s.current&&t&&(c.current=t(o(),a),s.current=!1);const[f,d]=n.useState(l(c.current));return n.useEffect((()=>{let e;return u.current&&(e=r((e=>u.current(e,a)),(e=>{d(l(e))}))),()=>{e&&e()}}),[l,a,r]),f},exports.useEffectOnce=e=>{n.useEffect(e,[])},exports.useMethods=function(t,r,o,i){var a,s=n.useMemo((function(){return new A}),[]),u=n.useRef([]),l=n.useRef();"function"==typeof t?a=t:(a=t.methods,u.current=t.ignoreHistoryForActions,l.current=t.normalizeHistory);var f=n.useRef(i);f.current=i;var d=n.useRef(r),p=n.useMemo((function(){var t=l.current,n=u.current,r=f.current;return function(i,u){var l,f=o&&S(o,(function(){return i}),s),d=w(e.produceWithPatches(i,(function(e){var t,n;switch(u.type){case k.UNDO:return s.undo(e);case k.REDO:return s.redo(e);case k.CLEAR:return s.clear(),y({},e);case k.IGNORE:case k.MERGE:case k.THROTTLE:var r,o=x(n=u.payload)||I(n)||N(n)||P(),i=o[0],c=o.slice(1);(r=a(e,f))[i].apply(r,T(c));break;default:(t=a(e,f))[u.type].apply(t,T(u.payload))}})),3),p=d[0],h=d[1],v=d[2];return l=p,r&&r(p,i,{type:u.type,params:u.payload,patches:h},f,(function(t){var n=e.produceWithPatches(p,t);l=n[0],h=[].concat(T(h),T(n[1])),v=[].concat(T(n[2]),T(v))})),[k.UNDO,k.REDO].includes(u.type)&&t&&(l=c.default(l,t)),[].concat(T(n),[k.UNDO,k.REDO,k.IGNORE,k.CLEAR]).includes(u.type)||(u.type===k.THROTTLE?s.throttleAdd(h,v,u.config&&u.config.rate):u.type===k.MERGE?s.merge(h,v):s.add(h,v)),l}}),[s,a,o]),h=n.useCallback((function(){return d.current}),[]),v=n.useMemo((function(){return new H(h)}),[h]),E=n.useCallback((function(e){var t=p(d.current,e);d.current=t,v.notify()}),[p,v]);n.useEffect((function(){v.notify()}),[v]);var b=n.useMemo((function(){return o?S(o,(function(){return d.current}),s):[]}),[s,o]),g=n.useMemo((function(){var e=Object.keys(a(null,null)),t=u.current;return y(y({},e.reduce((function(e,t){return e[t]=function(){for(var e=arguments.length,n=new Array(e),r=0;r<e;r++)n[r]=arguments[r];return E({type:t,payload:n})},e}),{})),{},{history:{undo:function(){return E({type:k.UNDO})},redo:function(){return E({type:k.REDO})},clear:function(){return E({type:k.CLEAR})},throttle:function(n){return y({},e.filter((function(e){return!t.includes(e)})).reduce((function(e,t){return e[t]=function(){for(var e=arguments.length,r=new Array(e),o=0;o<e;o++)r[o]=arguments[o];return E({type:k.THROTTLE,payload:[t].concat(r),config:{rate:n}})},e}),{}))},ignore:function(){return y({},e.filter((function(e){return!t.includes(e)})).reduce((function(e,t){return e[t]=function(){for(var e=arguments.length,n=new Array(e),r=0;r<e;r++)n[r]=arguments[r];return E({type:k.IGNORE,payload:[t].concat(n)})},e}),{}))},merge:function(){return y({},e.filter((function(e){return!t.includes(e)})).reduce((function(e,t){return e[t]=function(){for(var e=arguments.length,n=new Array(e),r=0;r<e;r++)n[r]=arguments[r];return E({type:k.MERGE,payload:[t].concat(n)})},e}),{}))}}})}),[E,a]);return n.useMemo((function(){return{getState:h,subscribe:function(e,t,n){return v.subscribe(e,t,n)},actions:g,query:b,history:s}}),[g,b,v,h,s])},exports.wrapConnectorHooks=function(e){return Object.keys(e).reduce(((t,n)=>(t[n]=Y(((...t)=>e[n](...t))),t)),{})},exports.wrapHookToRecognizeElement=Y;
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var produce = require('immer');
var isEqualWith = require('lodash/isEqualWith');
var React = require('react');
var isEqual = require('shallowequal');
var nanoid = require('nanoid');
var invariant = require('tiny-invariant');
var ReactDOM = require('react-dom');
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
var produce__default = /*#__PURE__*/_interopDefaultLegacy(produce);
var isEqualWith__default = /*#__PURE__*/_interopDefaultLegacy(isEqualWith);
var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
var isEqual__default = /*#__PURE__*/_interopDefaultLegacy(isEqual);
var invariant__default = /*#__PURE__*/_interopDefaultLegacy(invariant);
var ReactDOM__default = /*#__PURE__*/_interopDefaultLegacy(ReactDOM);
const ROOT_NODE = 'ROOT';
const DEPRECATED_ROOT_NODE = 'canvas-ROOT';
// TODO: Use a better way to store/display error messages
const ERROR_NOPARENT = 'Parent id cannot be ommited';
const ERROR_DUPLICATE_NODEID = 'Attempting to add a node with duplicated id';
const ERROR_INVALID_NODEID = 'Node does not exist, it may have been removed';
const ERROR_TOP_LEVEL_ELEMENT_NO_ID = 'A <Element /> that is used inside a User Component must specify an `id` prop, eg: <Element id="text_element">...</Element> ';
const ERROR_MISSING_PLACEHOLDER_PLACEMENT = 'Placeholder required placement info (parent, index, or where) is missing';
const ERROR_MOVE_CANNOT_DROP = 'Node cannot be dropped into target parent';
const ERROR_MOVE_INCOMING_PARENT = 'Target parent rejects incoming node';
const ERROR_MOVE_OUTGOING_PARENT = 'Current parent rejects outgoing node';
const ERROR_MOVE_NONCANVAS_CHILD = 'Cannot move node that is not a direct child of a Canvas node';
const ERROR_MOVE_TO_NONCANVAS_PARENT = 'Cannot move node into a non-Canvas parent';
const ERROR_MOVE_TOP_LEVEL_NODE = 'A top-level Node cannot be moved';
const ERROR_MOVE_ROOT_NODE = 'Root Node cannot be moved';
const ERROR_MOVE_TO_DESCENDANT = 'Cannot move node into a descendant';
const ERROR_NOT_IN_RESOLVER = 'The component type specified for this node (%node_type%) does not exist in the resolver';
const ERROR_INFINITE_CANVAS = "The component specified in the <Canvas> `is` prop has additional Canvas specified in it's render template.";
const ERROR_CANNOT_DRAG = 'The node has specified a canDrag() rule that prevents it from being dragged';
const ERROR_INVALID_NODE_ID = 'Invalid parameter Node Id specified';
const ERROR_DELETE_TOP_LEVEL_NODE = 'Attempting to delete a top-level Node';
const ERROR_RESOLVER_NOT_AN_OBJECT = "Resolver in <Editor /> has to be an object. For (de)serialization Craft.js needs a list of all the User Components. \n \nMore info: https://craft.js.org/r/docs/api/editor#props";
const ERROR_DESERIALIZE_COMPONENT_NOT_IN_RESOLVER = "An Error occurred while deserializing components: Cannot find component <%displayName% /> in resolver map. Please check your resolver in <Editor />\n\nAvailable components in resolver: %availableComponents%\n\nMore info: https://craft.js.org/r/docs/api/editor#props";
const ERROR_USE_EDITOR_OUTSIDE_OF_EDITOR_CONTEXT = "You can only use useEditor in the context of <Editor />. \n\nPlease only use useEditor in components that are children of the <Editor /> component.";
const ERROR_USE_NODE_OUTSIDE_OF_EDITOR_CONTEXT = "You can only use useNode in the context of <Editor />. \n\nPlease only use useNode in components that are children of the <Editor /> component.";
function ownKeys(object, enumerableOnly) {
var keys = Object.keys(object);
if (Object.getOwnPropertySymbols) {
var symbols = Object.getOwnPropertySymbols(object);
enumerableOnly && (symbols = symbols.filter(function (sym) {
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
})), keys.push.apply(keys, symbols);
}
return keys;
}
function _objectSpread2(target) {
for (var i = 1; i < arguments.length; i++) {
var source = null != arguments[i] ? arguments[i] : {};
i % 2 ? ownKeys(Object(source), !0).forEach(function (key) {
_defineProperty(target, key, source[key]);
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) {
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
});
}
return target;
}
function _defineProperty(obj, key, value) {
key = _toPropertyKey(key);
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
}
function _toPrimitive(input, hint) {
if (typeof input !== "object" || input === null) return input;
var prim = input[Symbol.toPrimitive];
if (prim !== undefined) {
var res = prim.call(input, hint || "default");
if (typeof res !== "object") return res;
throw new TypeError("@@toPrimitive must return a primitive value.");
}
return (hint === "string" ? String : Number)(input);
}
function _toPropertyKey(arg) {
var key = _toPrimitive(arg, "string");
return typeof key === "symbol" ? key : String(key);
}
const HISTORY_ACTIONS = {
UNDO: 'HISTORY_UNDO',
REDO: 'HISTORY_REDO',
THROTTLE: 'HISTORY_THROTTLE',
IGNORE: 'HISTORY_IGNORE',
MERGE: 'HISTORY_MERGE',
CLEAR: 'HISTORY_CLEAR'
};
class History {
constructor() {
_defineProperty(this, "timeline", []);
_defineProperty(this, "pointer", -1);
}
add(patches, inversePatches) {
if (patches.length === 0 && inversePatches.length === 0) {
return;
}
this.pointer = this.pointer + 1;
this.timeline.length = this.pointer;
this.timeline[this.pointer] = {
patches,
inversePatches,
timestamp: Date.now()
};
}
throttleAdd(patches, inversePatches) {
let throttleRate = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 500;
if (patches.length === 0 && inversePatches.length === 0) {
return;
}
if (this.timeline.length && this.pointer >= 0) {
const {
patches: currPatches,
inversePatches: currInversePatches,
timestamp
} = this.timeline[this.pointer];
const now = new Date();
const diff = now.getTime() - timestamp;
if (diff < throttleRate) {
this.timeline[this.pointer] = {
timestamp,
patches: [...currPatches, ...patches],
inversePatches: [...inversePatches, ...currInversePatches]
};
return;
}
}
this.add(patches, inversePatches);
}
merge(patches, inversePatches) {
if (patches.length === 0 && inversePatches.length === 0) {
return;
}
if (this.timeline.length && this.pointer >= 0) {
const {
patches: currPatches,
inversePatches: currInversePatches,
timestamp
} = this.timeline[this.pointer];
this.timeline[this.pointer] = {
timestamp,
patches: [...currPatches, ...patches],
inversePatches: [...inversePatches, ...currInversePatches]
};
return;
}
this.add(patches, inversePatches);
}
clear() {
this.timeline = [];
this.pointer = -1;
}
canUndo() {
return this.pointer >= 0;
}
canRedo() {
return this.pointer < this.timeline.length - 1;
}
undo(state) {
if (!this.canUndo()) {
return;
}
const {
inversePatches
} = this.timeline[this.pointer];
this.pointer = this.pointer - 1;
return produce.applyPatches(state, inversePatches);
}
redo(state) {
if (!this.canRedo()) {
return;
}
this.pointer = this.pointer + 1;
const {
patches
} = this.timeline[this.pointer];
return produce.applyPatches(state, patches);
}
}
produce.enableMapSet();
produce.enablePatches();
function useMethods(methodsOrOptions, initialState, queryMethods, patchListener) {
const history = React.useMemo(() => new History(), []);
let methodsFactory;
let ignoreHistoryForActionsRef = React.useRef([]);
let normalizeHistoryRef = React.useRef();
if (typeof methodsOrOptions === 'function') {
methodsFactory = methodsOrOptions;
} else {
methodsFactory = methodsOrOptions.methods;
ignoreHistoryForActionsRef.current = methodsOrOptions.ignoreHistoryForActions;
normalizeHistoryRef.current = methodsOrOptions.normalizeHistory;
}
const patchListenerRef = React.useRef(patchListener);
patchListenerRef.current = patchListener;
const stateRef = React.useRef(initialState);
const reducer = React.useMemo(() => {
const {
current: normalizeHistory
} = normalizeHistoryRef;
const {
current: ignoreHistoryForActions
} = ignoreHistoryForActionsRef;
const {
current: patchListener
} = patchListenerRef;
return (state, action) => {
const query = queryMethods && createQuery(queryMethods, () => state, history);
let finalState;
let [nextState, patches, inversePatches] = produce.produceWithPatches(state, draft => {
switch (action.type) {
case HISTORY_ACTIONS.UNDO:
{
return history.undo(draft);
}
case HISTORY_ACTIONS.REDO:
{
return history.redo(draft);
}
case HISTORY_ACTIONS.CLEAR:
{
history.clear();
return _objectSpread2({}, draft);
}
// TODO: Simplify History API
case HISTORY_ACTIONS.IGNORE:
case HISTORY_ACTIONS.MERGE:
case HISTORY_ACTIONS.THROTTLE:
{
const [type, ...params] = action.payload;
methodsFactory(draft, query)[type](...params);
break;
}
default:
methodsFactory(draft, query)[action.type](...action.payload);
}
});
finalState = nextState;
if (patchListener) {
patchListener(nextState, state, {
type: action.type,
params: action.payload,
patches
}, query, cb => {
let normalizedDraft = produce.produceWithPatches(nextState, cb);
finalState = normalizedDraft[0];
patches = [...patches, ...normalizedDraft[1]];
inversePatches = [...normalizedDraft[2], ...inversePatches];
});
}
if ([HISTORY_ACTIONS.UNDO, HISTORY_ACTIONS.REDO].includes(action.type) && normalizeHistory) {
finalState = produce__default["default"](finalState, normalizeHistory);
}
if (![...ignoreHistoryForActions, HISTORY_ACTIONS.UNDO, HISTORY_ACTIONS.REDO, HISTORY_ACTIONS.IGNORE, HISTORY_ACTIONS.CLEAR].includes(action.type)) {
if (action.type === HISTORY_ACTIONS.THROTTLE) {
history.throttleAdd(patches, inversePatches, action.config && action.config.rate);
} else if (action.type === HISTORY_ACTIONS.MERGE) {
history.merge(patches, inversePatches);
} else {
history.add(patches, inversePatches);
}
}
return finalState;
};
}, [history, methodsFactory, queryMethods]);
const getState = React.useCallback(() => stateRef.current, []);
const watcher = React.useMemo(() => new Watcher(getState), [getState]);
const dispatch = React.useCallback(action => {
const newState = reducer(stateRef.current, action);
stateRef.current = newState;
watcher.notify();
}, [reducer, watcher]);
React.useEffect(() => {
watcher.notify();
}, [watcher]);
const query = React.useMemo(() => !queryMethods ? [] : createQuery(queryMethods, () => stateRef.current, history), [history, queryMethods]);
const actions = React.useMemo(() => {
const actionTypes = Object.keys(methodsFactory(null, null));
const {
current: ignoreHistoryForActions
} = ignoreHistoryForActionsRef;
return _objectSpread2(_objectSpread2({}, actionTypes.reduce((accum, type) => {
accum[type] = function () {
for (var _len = arguments.length, payload = new Array(_len), _key = 0; _key < _len; _key++) {
payload[_key] = arguments[_key];
}
return dispatch({
type,
payload
});
};
return accum;
}, {})), {}, {
history: {
undo() {
return dispatch({
type: HISTORY_ACTIONS.UNDO
});
},
redo() {
return dispatch({
type: HISTORY_ACTIONS.REDO
});
},
clear: () => {
return dispatch({
type: HISTORY_ACTIONS.CLEAR
});
},
throttle: rate => {
return _objectSpread2({}, actionTypes.filter(type => !ignoreHistoryForActions.includes(type)).reduce((accum, type) => {
accum[type] = function () {
for (var _len2 = arguments.length, payload = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
payload[_key2] = arguments[_key2];
}
return dispatch({
type: HISTORY_ACTIONS.THROTTLE,
payload: [type, ...payload],
config: {
rate: rate
}
});
};
return accum;
}, {}));
},
ignore: () => {
return _objectSpread2({}, actionTypes.filter(type => !ignoreHistoryForActions.includes(type)).reduce((accum, type) => {
accum[type] = function () {
for (var _len3 = arguments.length, payload = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
payload[_key3] = arguments[_key3];
}
return dispatch({
type: HISTORY_ACTIONS.IGNORE,
payload: [type, ...payload]
});
};
return accum;
}, {}));
},
merge: () => {
return _objectSpread2({}, actionTypes.filter(type => !ignoreHistoryForActions.includes(type)).reduce((accum, type) => {
accum[type] = function () {
for (var _len4 = arguments.length, payload = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
payload[_key4] = arguments[_key4];
}
return dispatch({
type: HISTORY_ACTIONS.MERGE,
payload: [type, ...payload]
});
};
return accum;
}, {}));
}
}
});
}, [dispatch, methodsFactory]);
return React.useMemo(() => ({
getState,
subscribe: (collector, cb, collectOnCreate) => watcher.subscribe(collector, cb, collectOnCreate),
actions,
query,
history
}), [actions, query, watcher, getState, history]);
}
function createQuery(queryMethods, getState, history) {
const queries = Object.keys(queryMethods()).reduce((accum, key) => {
return _objectSpread2(_objectSpread2({}, accum), {}, {
[key]: function () {
return queryMethods(getState())[key](...arguments);
}
});
}, {});
return _objectSpread2(_objectSpread2({}, queries), {}, {
history: {
canUndo: () => history.canUndo(),
canRedo: () => history.canRedo()
}
});
}
class Watcher {
constructor(getState) {
_defineProperty(this, "getState", void 0);
_defineProperty(this, "subscribers", []);
this.getState = getState;
}
/**
* Creates a Subscriber
* @returns {() => void} a Function that removes the Subscriber
*/
subscribe(collector, onChange, collectOnCreate) {
const subscriber = new Subscriber(() => collector(this.getState()), onChange, collectOnCreate);
this.subscribers.push(subscriber);
return this.unsubscribe.bind(this, subscriber);
}
unsubscribe(subscriber) {
if (this.subscribers.length) {
const index = this.subscribers.indexOf(subscriber);
if (index > -1) return this.subscribers.splice(index, 1);
}
}
notify() {
this.subscribers.forEach(subscriber => subscriber.collect());
}
}
class Subscriber {
/**
* Creates a Subscriber
* @param collector The method that returns an object of values to be collected
* @param onChange A callback method that is triggered when the collected values has changed
* @param collectOnCreate If set to true, the collector/onChange will be called on instantiation
*/
constructor(collector, onChange) {
let collectOnCreate = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
_defineProperty(this, "collected", void 0);
_defineProperty(this, "collector", void 0);
_defineProperty(this, "onChange", void 0);
_defineProperty(this, "id", void 0);
this.collector = collector;
this.onChange = onChange;
// Collect and run onChange callback when Subscriber is created
if (collectOnCreate) this.collect();
}
collect() {
try {
const recollect = this.collector();
if (!isEqualWith__default["default"](recollect, this.collected)) {
this.collected = recollect;
if (this.onChange) this.onChange(this.collected);
}
} catch (err) {
// eslint-disable-next-line no-console
console.warn(err);
}
}
}
const getDOMInfo = el => {
const {
x,
y,
top,
left,
bottom,
right,
width,
height
} = el.getBoundingClientRect();
const style = window.getComputedStyle(el);
const margin = {
left: parseInt(style.marginLeft),
right: parseInt(style.marginRight),
bottom: parseInt(style.marginBottom),
top: parseInt(style.marginTop)
};
const padding = {
left: parseInt(style.paddingLeft),
right: parseInt(style.paddingRight),
bottom: parseInt(style.paddingBottom),
top: parseInt(style.paddingTop)
};
const styleInFlow = parent => {
const parentStyle = getComputedStyle(parent);
if (style.overflow && style.overflow !== 'visible') {
return;
}
if (parentStyle.float !== 'none') {
return;
}
if (parentStyle.display === 'grid') {
return;
}
if (parentStyle.display === 'flex' && parentStyle['flex-direction'] !== 'column') {
return;
}
switch (style.position) {
case 'static':
case 'relative':
break;
default:
return;
}
switch (el.tagName) {
case 'TR':
case 'TBODY':
case 'THEAD':
case 'TFOOT':
return true;
}
switch (style.display) {
case 'block':
case 'list-item':
case 'table':
case 'flex':
case 'grid':
return true;
}
return;
};
return {
x,
y,
top,
left,
bottom,
right,
width,
height,
outerWidth: Math.round(width + margin.left + margin.right),
outerHeight: Math.round(height + margin.top + margin.bottom),
margin,
padding,
inFlow: el.parentElement && !!styleInFlow(el.parentElement)
};
};
function useCollector(store, collector) {
const { subscribe, getState, actions, query } = store;
const initial = React.useRef(true);
const collected = React.useRef(null);
const collectorRef = React.useRef(collector);
collectorRef.current = collector;
const onCollect = React.useCallback((collected) => {
return { ...collected, actions, query };
}, [actions, query]);
// Collect states for initial render
if (initial.current && collector) {
collected.current = collector(getState(), query);
initial.current = false;
}
const [renderCollected, setRenderCollected] = React.useState(onCollect(collected.current));
// Collect states on state change
React.useEffect(() => {
let unsubscribe;
if (collectorRef.current) {
unsubscribe = subscribe((current) => collectorRef.current(current, query), (collected) => {
setRenderCollected(onCollect(collected));
});
}
return () => {
if (unsubscribe)
unsubscribe();
};
}, [onCollect, query, subscribe]);
return renderCollected;
}
// By default nanoid generate an ID with 21 characters. To reduce the footprint, we default to 10 characters.
// We have a higher probability for collisions, though
/**
* Generate a random ID. That ID can for example be used as a node ID.
*
* @param size The number of characters that are generated for the ID. Defaults to `10`
* @returns A random id
*/
const getRandomId = function () {
let size = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 10;
return nanoid.nanoid(size);
};
/**
* Stores all connected DOM elements and their connectors here
* This allows us to easily enable/disable and perform cleanups
*/
class ConnectorRegistry {
constructor() {
_defineProperty(this, "isEnabled", true);
_defineProperty(this, "elementIdMap", new WeakMap());
_defineProperty(this, "registry", new Map());
}
getElementId(element) {
const existingId = this.elementIdMap.get(element);
if (existingId) {
return existingId;
}
const newId = getRandomId();
this.elementIdMap.set(element, newId);
return newId;
}
getConnectorId(element, connectorName) {
const elementId = this.getElementId(element);
return "".concat(connectorName, "--").concat(elementId);
}
register(element, connectorPayload) {
const existingConnector = this.getByElement(element, connectorPayload.name);
if (existingConnector) {
if (isEqual__default["default"](connectorPayload.required, existingConnector.required)) {
return existingConnector;
}
this.getByElement(element, connectorPayload.name).disable();
}
let cleanup = null;
const id = this.getConnectorId(element, connectorPayload.name);
this.registry.set(id, {
id,
required: connectorPayload.required,
enable: () => {
if (cleanup) {
cleanup();
}
cleanup = connectorPayload.connector(element, connectorPayload.required, connectorPayload.options);
},
disable: () => {
if (!cleanup) {
return;
}
cleanup();
},
remove: () => {
return this.remove(id);
}
});
if (this.isEnabled) {
this.registry.get(id).enable();
}
return this.registry.get(id);
}
get(id) {
return this.registry.get(id);
}
remove(id) {
const connector = this.get(id);
if (!connector) {
return;
}
connector.disable();
this.registry.delete(connector.id);
}
enable() {
this.isEnabled = true;
this.registry.forEach(connectors => {
connectors.enable();
});
}
disable() {
this.isEnabled = false;
this.registry.forEach(connectors => {
connectors.disable();
});
}
getByElement(element, connectorName) {
return this.get(this.getConnectorId(element, connectorName));
}
removeByElement(element, connectorName) {
return this.remove(this.getConnectorId(element, connectorName));
}
clear() {
this.disable();
this.elementIdMap = new WeakMap();
this.registry = new Map();
}
}
exports.EventHandlerUpdates = void 0;
(function (EventHandlerUpdates) {
EventHandlerUpdates[EventHandlerUpdates["HandlerDisabled"] = 0] = "HandlerDisabled";
EventHandlerUpdates[EventHandlerUpdates["HandlerEnabled"] = 1] = "HandlerEnabled";
})(exports.EventHandlerUpdates || (exports.EventHandlerUpdates = {}));
/**
* Check if a specified event is blocked by a child
* that's a descendant of the specified element
*/
function isEventBlockedByDescendant(e, eventName, el) {
// Store initial Craft event value
if (!e.craft) {
e.craft = {
stopPropagation: () => {},
blockedEvents: {}
};
}
const blockingElements = e.craft && e.craft.blockedEvents[eventName] || [];
for (let i = 0; i < blockingElements.length; i++) {
const blockingElement = blockingElements[i];
if (el !== blockingElement && el.contains(blockingElement)) {
return true;
}
}
return false;
}
class EventHandlers {
constructor(options) {
_defineProperty(this, "options", void 0);
_defineProperty(this, "registry", new ConnectorRegistry());
_defineProperty(this, "subscribers", new Set());
this.options = options;
}
listen(cb) {
this.subscribers.add(cb);
return () => this.subscribers.delete(cb);
}
disable() {
if (this.onDisable) {
this.onDisable();
}
this.registry.disable();
this.subscribers.forEach(listener => {
listener(exports.EventHandlerUpdates.HandlerDisabled);
});
}
enable() {
if (this.onEnable) {
this.onEnable();
}
this.registry.enable();
this.subscribers.forEach(listener => {
listener(exports.EventHandlerUpdates.HandlerEnabled);
});
}
cleanup() {
this.disable();
this.subscribers.clear();
this.registry.clear();
}
addCraftEventListener(el, eventName, listener, options) {
const bindedListener = e => {
if (!isEventBlockedByDescendant(e, eventName, el)) {
e.craft.stopPropagation = () => {
if (!e.craft.blockedEvents[eventName]) {
e.craft.blockedEvents[eventName] = [];
}
e.craft.blockedEvents[eventName].push(el);
};
listener(e);
}
};
el.addEventListener(eventName, bindedListener, options);
return () => el.removeEventListener(eventName, bindedListener, options);
}
/**
* Creates a record of chainable connectors and tracks their usages
*/
createConnectorsUsage() {
const handlers = this.handlers();
// Track all active connector ids here
// This is so we can return a cleanup method below so the callee can programmatically cleanup all connectors
const activeConnectorIds = new Set();
let canRegisterConnectors = false;
const connectorsToRegister = new Map();
const connectors = Object.entries(handlers).reduce((accum, _ref) => {
let [name, handler] = _ref;
return _objectSpread2(_objectSpread2({}, accum), {}, {
[name]: (el, required, options) => {
const registerConnector = () => {
const connector = this.registry.register(el, {
required,
name,
options,
connector: handler
});
activeConnectorIds.add(connector.id);
return connector;
};
connectorsToRegister.set(this.registry.getConnectorId(el, name), registerConnector);
/**
* If register() has been called,
* register the connector immediately.
*
* Otherwise, registration is deferred until after register() is called
*/
if (canRegisterConnectors) {
registerConnector();
}
return el;
}
});
}, {});
return {
connectors,
register: () => {
canRegisterConnectors = true;
connectorsToRegister.forEach(registerConnector => {
registerConnector();
});
},
cleanup: () => {
canRegisterConnectors = false;
activeConnectorIds.forEach(connectorId => this.registry.remove(connectorId));
}
};
}
derive(type, opts) {
return new type(this, opts);
}
// This method allows us to execute multiple connectors and returns a single cleanup method for all of them
createProxyHandlers(instance, cb) {
const connectorsToCleanup = [];
const handlers = instance.handlers();
const proxiedHandlers = new Proxy(handlers, {
get: (target, key, receiver) => {
if (key in handlers === false) {
return Reflect.get(target, key, receiver);
}
return function (el) {
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
args[_key - 1] = arguments[_key];
}
const cleanup = handlers[key](el, ...args);
if (!cleanup) {
return;
}
connectorsToCleanup.push(cleanup);
};
}
});
cb(proxiedHandlers);
return () => {
connectorsToCleanup.forEach(cleanup => {
cleanup();
});
};
}
// This lets us to execute and cleanup sibling connectors
reflect(cb) {
return this.createProxyHandlers(this, cb);
}
}
// Creates EventHandlers that depends on another EventHandlers instance
// This lets us to easily create new connectors that composites of the parent EventHandlers instance
class DerivedEventHandlers extends EventHandlers {
constructor(derived, options) {
super(options);
_defineProperty(this, "derived", void 0);
_defineProperty(this, "unsubscribeParentHandlerListener", void 0);
this.derived = derived;
this.options = options;
// Automatically disable/enable depending on the parent handlers
this.unsubscribeParentHandlerListener = this.derived.listen(msg => {
switch (msg) {
case exports.EventHandlerUpdates.HandlerEnabled:
{
return this.enable();
}
case exports.EventHandlerUpdates.HandlerDisabled:
{
return this.disable();
}
default:
{
return;
}
}
});
}
// A method to easily inherit parent connectors
inherit(cb) {
return this.createProxyHandlers(this.derived, cb);
}
cleanup() {
super.cleanup();
this.unsubscribeParentHandlerListener();
}
}
// https://github.com/react-dnd/react-dnd
function setRef(ref, node) {
if (node) {
if (typeof ref === 'function') {
ref(node);
}
else {
ref.current = node;
}
}
}
function cloneWithRef(element, newRef) {
const previousRef = element.ref;
invariant__default["default"](typeof previousRef !== 'string', 'Cannot connect to an element with an existing string ref. ' +
'Please convert it to use a callback ref instead, or wrap it into a <span> or <div>. ' +
'Read more: https://facebook.github.io/react/docs/more-about-refs.html#the-ref-callback-attribute');
if (!previousRef) {
// When there is no ref on the element, use the new ref directly
return React.cloneElement(element, {
ref: newRef,
});
}
else {
return React.cloneElement(element, {
ref: (node) => {
setRef(previousRef, node);
setRef(newRef, node);
},
});
}
}
function throwIfCompositeComponentElement(element) {
if (typeof element.type === 'string') {
return;
}
throw new Error();
}
function wrapHookToRecognizeElement(hook) {
return (elementOrNode = null, ...args) => {
// When passed a node, call the hook straight away.
if (!React.isValidElement(elementOrNode)) {
if (!elementOrNode) {
return;
}
const node = elementOrNode;
node && hook(node, ...args);
return node;
}
// If passed a ReactElement, clone it and attach this function as a ref.
// This helps us achieve a neat API where user doesn't even know that refs
// are being used under the hood.
const element = elementOrNode;
throwIfCompositeComponentElement(element);
return cloneWithRef(element, hook);
};
}
// A React wrapper for our connectors
// Wrap all our connectors so that would additionally accept React.ReactElement
function wrapConnectorHooks(connectors) {
return Object.keys(connectors).reduce((accum, key) => {
accum[key] = wrapHookToRecognizeElement((...args) => {
// @ts-ignore
return connectors[key](...args);
});
return accum;
}, {});
}
const RenderIndicator = ({ style, parentDom }) => {
const indicator = (React__default["default"].createElement("div", { style: {
position: 'fixed',
display: 'block',
opacity: 1,
borderStyle: 'solid',
borderWidth: '1px',
borderColor: 'transparent',
zIndex: 99999,
...style,
} }));
if (parentDom && parentDom.ownerDocument !== document) {
return ReactDOM__default["default"].createPortal(indicator, parentDom.ownerDocument.body);
}
return indicator;
};
const useEffectOnce = (effect) => {
/* eslint-disable-next-line react-hooks/exhaustive-deps */
React.useEffect(effect, []);
};
const deprecationWarning = (name, payload) => {
let message = "Deprecation warning: ".concat(name, " will be deprecated in future relases.");
const {
suggest,
doc
} = payload;
if (suggest) {
message += " Please use ".concat(suggest, " instead.");
}
// URL link to Documentation
if (doc) {
message += "(".concat(doc, ")");
}
// eslint-disable-next-line no-console
console.warn(message);
};
const isClientSide = () => typeof window !== 'undefined';
const isLinux = () => isClientSide() && /Linux/i.test(window.navigator.userAgent);
const isChromium = () => isClientSide() && /Chrome/i.test(window.navigator.userAgent);
exports.DEPRECATED_ROOT_NODE = DEPRECATED_ROOT_NODE;
exports.DerivedEventHandlers = DerivedEventHandlers;
exports.ERROR_CANNOT_DRAG = ERROR_CANNOT_DRAG;
exports.ERROR_DELETE_TOP_LEVEL_NODE = ERROR_DELETE_TOP_LEVEL_NODE;
exports.ERROR_DESERIALIZE_COMPONENT_NOT_IN_RESOLVER = ERROR_DESERIALIZE_COMPONENT_NOT_IN_RESOLVER;
exports.ERROR_DUPLICATE_NODEID = ERROR_DUPLICATE_NODEID;
exports.ERROR_INFINITE_CANVAS = ERROR_INFINITE_CANVAS;
exports.ERROR_INVALID_NODEID = ERROR_INVALID_NODEID;
exports.ERROR_INVALID_NODE_ID = ERROR_INVALID_NODE_ID;
exports.ERROR_MISSING_PLACEHOLDER_PLACEMENT = ERROR_MISSING_PLACEHOLDER_PLACEMENT;
exports.ERROR_MOVE_CANNOT_DROP = ERROR_MOVE_CANNOT_DROP;
exports.ERROR_MOVE_INCOMING_PARENT = ERROR_MOVE_INCOMING_PARENT;
exports.ERROR_MOVE_NONCANVAS_CHILD = ERROR_MOVE_NONCANVAS_CHILD;
exports.ERROR_MOVE_OUTGOING_PARENT = ERROR_MOVE_OUTGOING_PARENT;
exports.ERROR_MOVE_ROOT_NODE = ERROR_MOVE_ROOT_NODE;
exports.ERROR_MOVE_TOP_LEVEL_NODE = ERROR_MOVE_TOP_LEVEL_NODE;
exports.ERROR_MOVE_TO_DESCENDANT = ERROR_MOVE_TO_DESCENDANT;
exports.ERROR_MOVE_TO_NONCANVAS_PARENT = ERROR_MOVE_TO_NONCANVAS_PARENT;
exports.ERROR_NOPARENT = ERROR_NOPARENT;
exports.ERROR_NOT_IN_RESOLVER = ERROR_NOT_IN_RESOLVER;
exports.ERROR_RESOLVER_NOT_AN_OBJECT = ERROR_RESOLVER_NOT_AN_OBJECT;
exports.ERROR_TOP_LEVEL_ELEMENT_NO_ID = ERROR_TOP_LEVEL_ELEMENT_NO_ID;
exports.ERROR_USE_EDITOR_OUTSIDE_OF_EDITOR_CONTEXT = ERROR_USE_EDITOR_OUTSIDE_OF_EDITOR_CONTEXT;
exports.ERROR_USE_NODE_OUTSIDE_OF_EDITOR_CONTEXT = ERROR_USE_NODE_OUTSIDE_OF_EDITOR_CONTEXT;
exports.EventHandlers = EventHandlers;
exports.HISTORY_ACTIONS = HISTORY_ACTIONS;
exports.History = History;
exports.ROOT_NODE = ROOT_NODE;
exports.RenderIndicator = RenderIndicator;
exports.cloneWithRef = cloneWithRef;
exports.createQuery = createQuery;
exports.deprecationWarning = deprecationWarning;
exports.getDOMInfo = getDOMInfo;
exports.getRandomId = getRandomId;
exports.isChromium = isChromium;
exports.isClientSide = isClientSide;
exports.isLinux = isLinux;
exports.useCollector = useCollector;
exports.useEffectOnce = useEffectOnce;
exports.useMethods = useMethods;
exports.wrapConnectorHooks = wrapConnectorHooks;
exports.wrapHookToRecognizeElement = wrapHookToRecognizeElement;

@@ -1,1 +0,973 @@

import e,{applyPatches as t,enableMapSet as n,enablePatches as r,produceWithPatches as i}from"immer";import o from"lodash/isEqualWith";import a,{useMemo as c,useRef as u,useCallback as s,useEffect as l,useState as f,cloneElement as d,isValidElement as h}from"react";import p from"shallowequal";import{nanoid as y}from"nanoid";import v from"tiny-invariant";import b from"react-dom";var m="ROOT",g="canvas-ROOT",E="Parent id cannot be ommited",w="Attempting to add a node with duplicated id",O="Node does not exist, it may have been removed",R='A <Element /> that is used inside a User Component must specify an `id` prop, eg: <Element id="text_element">...</Element> ',k="Placeholder required placement info (parent, index, or where) is missing",P="Node cannot be dropped into target parent",j="Target parent rejects incoming node",T="Current parent rejects outgoing node",I="Cannot move node that is not a direct child of a Canvas node",C="Cannot move node into a non-Canvas parent",D="A top-level Node cannot be moved",A="Root Node cannot be moved",S="Cannot move node into a descendant",H="The component type specified for this node (%node_type%) does not exist in the resolver",x="The component specified in the <Canvas> `is` prop has additional Canvas specified in it's render template.",N="The node has specified a canDrag() rule that prevents it from being dragged",L="Invalid parameter Node Id specified",M="Attempting to delete a top-level Node",_="Resolver in <Editor /> has to be an object. For (de)serialization Craft.js needs a list of all the User Components. \n \nMore info: https://craft.js.org/r/docs/api/editor#props",U="An Error occurred while deserializing components: Cannot find component <%displayName% /> in resolver map. Please check your resolver in <Editor />\n\nAvailable components in resolver: %availableComponents%\n\nMore info: https://craft.js.org/r/docs/api/editor#props",q="You can only use useEditor in the context of <Editor />. \n\nPlease only use useEditor in components that are children of the <Editor /> component.",B="You can only use useNode in the context of <Editor />. \n\nPlease only use useNode in components that are children of the <Editor /> component.";function G(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function Y(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?G(Object(n),!0).forEach((function(t){$(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):G(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function W(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function z(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,oe(r.key),r)}}function F(e,t,n){return t&&z(e.prototype,t),n&&z(e,n),Object.defineProperty(e,"prototype",{writable:!1}),e}function $(e,t,n){return(t=oe(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function J(e){return J=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(e){return e.__proto__||Object.getPrototypeOf(e)},J(e)}function K(e,t){return K=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,t){return e.__proto__=t,e},K(e,t)}function Q(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function V(){return V="undefined"!=typeof Reflect&&Reflect.get?Reflect.get.bind():function(e,t,n){var r=function(e,t){for(;!Object.prototype.hasOwnProperty.call(e,t)&&null!==(e=J(e)););return e}(e,t);if(r){var i=Object.getOwnPropertyDescriptor(r,t);return i.get?i.get.call(arguments.length<3?e:n):i.value}},V.apply(this,arguments)}function X(e,t){return ee(e)||function(e,t){var n=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=n){var r,i,o,a,c=[],u=!0,s=!1;try{if(o=(n=n.call(e)).next,0===t){if(Object(n)!==n)return;u=!1}else for(;!(u=(r=o.call(n)).done)&&(c.push(r.value),c.length!==t);u=!0);}catch(e){s=!0,i=e}finally{try{if(!u&&null!=n.return&&(a=n.return(),Object(a)!==a))return}finally{if(s)throw i}}return c}}(e,t)||ne(e,t)||ie()}function Z(e){return function(e){if(Array.isArray(e))return re(e)}(e)||te(e)||ne(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function ee(e){if(Array.isArray(e))return e}function te(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}function ne(e,t){if(e){if("string"==typeof e)return re(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?re(e,t):void 0}}function re(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function ie(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function oe(e){var t=function(e,t){if("object"!=typeof e||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,"string");if("object"!=typeof r)return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e);return"symbol"==typeof t?t:String(t)}var ae={UNDO:"HISTORY_UNDO",REDO:"HISTORY_REDO",THROTTLE:"HISTORY_THROTTLE",IGNORE:"HISTORY_IGNORE",MERGE:"HISTORY_MERGE",CLEAR:"HISTORY_CLEAR"},ce=function(){function e(){W(this,e),$(this,"timeline",[]),$(this,"pointer",-1)}return F(e,[{key:"add",value:function(e,t){0===e.length&&0===t.length||(this.pointer=this.pointer+1,this.timeline.length=this.pointer,this.timeline[this.pointer]={patches:e,inversePatches:t,timestamp:Date.now()})}},{key:"throttleAdd",value:function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:500;if(0!==e.length||0!==t.length){if(this.timeline.length&&this.pointer>=0){var r=this.timeline[this.pointer],i=r.patches,o=r.inversePatches,a=r.timestamp;if((new Date).getTime()-a<n)return void(this.timeline[this.pointer]={timestamp:a,patches:[].concat(Z(i),Z(e)),inversePatches:[].concat(Z(t),Z(o))})}this.add(e,t)}}},{key:"merge",value:function(e,t){if(0!==e.length||0!==t.length)if(this.timeline.length&&this.pointer>=0){var n=this.timeline[this.pointer],r=n.inversePatches;this.timeline[this.pointer]={timestamp:n.timestamp,patches:[].concat(Z(n.patches),Z(e)),inversePatches:[].concat(Z(t),Z(r))}}else this.add(e,t)}},{key:"clear",value:function(){this.timeline=[],this.pointer=-1}},{key:"canUndo",value:function(){return this.pointer>=0}},{key:"canRedo",value:function(){return this.pointer<this.timeline.length-1}},{key:"undo",value:function(e){if(this.canUndo()){var n=this.timeline[this.pointer].inversePatches;return this.pointer=this.pointer-1,t(e,n)}}},{key:"redo",value:function(e){if(this.canRedo())return this.pointer=this.pointer+1,t(e,this.timeline[this.pointer].patches)}}]),e}();function ue(t,n,r,o){var a,f=c((function(){return new ce}),[]),d=u([]),h=u();"function"==typeof t?a=t:(a=t.methods,d.current=t.ignoreHistoryForActions,h.current=t.normalizeHistory);var p=u(o);p.current=o;var y=u(n),v=c((function(){var t=h.current,n=d.current,o=p.current;return function(c,u){var s,l=r&&se(r,(function(){return c}),f),d=X(i(c,(function(e){var t,n;switch(u.type){case ae.UNDO:return f.undo(e);case ae.REDO:return f.redo(e);case ae.CLEAR:return f.clear(),Y({},e);case ae.IGNORE:case ae.MERGE:case ae.THROTTLE:var r,i=ee(n=u.payload)||te(n)||ne(n)||ie(),o=i[0],c=i.slice(1);(r=a(e,l))[o].apply(r,Z(c));break;default:(t=a(e,l))[u.type].apply(t,Z(u.payload))}})),3),h=d[0],p=d[1],y=d[2];return s=h,o&&o(h,c,{type:u.type,params:u.payload,patches:p},l,(function(e){var t=i(h,e);s=t[0],p=[].concat(Z(p),Z(t[1])),y=[].concat(Z(t[2]),Z(y))})),[ae.UNDO,ae.REDO].includes(u.type)&&t&&(s=e(s,t)),[].concat(Z(n),[ae.UNDO,ae.REDO,ae.IGNORE,ae.CLEAR]).includes(u.type)||(u.type===ae.THROTTLE?f.throttleAdd(p,y,u.config&&u.config.rate):u.type===ae.MERGE?f.merge(p,y):f.add(p,y)),s}}),[f,a,r]),b=s((function(){return y.current}),[]),m=c((function(){return new le(b)}),[b]),g=s((function(e){var t=v(y.current,e);y.current=t,m.notify()}),[v,m]);l((function(){m.notify()}),[m]);var E=c((function(){return r?se(r,(function(){return y.current}),f):[]}),[f,r]),w=c((function(){var e=Object.keys(a(null,null)),t=d.current;return Y(Y({},e.reduce((function(e,t){return e[t]=function(){for(var e=arguments.length,n=new Array(e),r=0;r<e;r++)n[r]=arguments[r];return g({type:t,payload:n})},e}),{})),{},{history:{undo:function(){return g({type:ae.UNDO})},redo:function(){return g({type:ae.REDO})},clear:function(){return g({type:ae.CLEAR})},throttle:function(n){return Y({},e.filter((function(e){return!t.includes(e)})).reduce((function(e,t){return e[t]=function(){for(var e=arguments.length,r=new Array(e),i=0;i<e;i++)r[i]=arguments[i];return g({type:ae.THROTTLE,payload:[t].concat(r),config:{rate:n}})},e}),{}))},ignore:function(){return Y({},e.filter((function(e){return!t.includes(e)})).reduce((function(e,t){return e[t]=function(){for(var e=arguments.length,n=new Array(e),r=0;r<e;r++)n[r]=arguments[r];return g({type:ae.IGNORE,payload:[t].concat(n)})},e}),{}))},merge:function(){return Y({},e.filter((function(e){return!t.includes(e)})).reduce((function(e,t){return e[t]=function(){for(var e=arguments.length,n=new Array(e),r=0;r<e;r++)n[r]=arguments[r];return g({type:ae.MERGE,payload:[t].concat(n)})},e}),{}))}}})}),[g,a]);return c((function(){return{getState:b,subscribe:function(e,t,n){return m.subscribe(e,t,n)},actions:w,query:E,history:f}}),[w,E,m,b,f])}function se(e,t,n){var r=Object.keys(e()).reduce((function(n,r){return Y(Y({},n),{},$({},r,(function(){var n;return(n=e(t()))[r].apply(n,arguments)})))}),{});return Y(Y({},r),{},{history:{canUndo:function(){return n.canUndo()},canRedo:function(){return n.canRedo()}}})}n(),r();var le=function(){function e(t){W(this,e),$(this,"getState",void 0),$(this,"subscribers",[]),this.getState=t}return F(e,[{key:"subscribe",value:function(e,t,n){var r=this,i=new fe((function(){return e(r.getState())}),t,n);return this.subscribers.push(i),this.unsubscribe.bind(this,i)}},{key:"unsubscribe",value:function(e){if(this.subscribers.length){var t=this.subscribers.indexOf(e);if(t>-1)return this.subscribers.splice(t,1)}}},{key:"notify",value:function(){this.subscribers.forEach((function(e){return e.collect()}))}}]),e}(),fe=function(){function e(t,n){var r=arguments.length>2&&void 0!==arguments[2]&&arguments[2];W(this,e),$(this,"collected",void 0),$(this,"collector",void 0),$(this,"onChange",void 0),$(this,"id",void 0),this.collector=t,this.onChange=n,r&&this.collect()}return F(e,[{key:"collect",value:function(){try{var e=this.collector();o(e,this.collected)||(this.collected=e,this.onChange&&this.onChange(this.collected))}catch(e){console.warn(e)}}}]),e}(),de=function(e){var t=e.getBoundingClientRect(),n=t.x,r=t.y,i=t.top,o=t.left,a=t.bottom,c=t.right,u=t.width,s=t.height,l=window.getComputedStyle(e),f={left:parseInt(l.marginLeft),right:parseInt(l.marginRight),bottom:parseInt(l.marginBottom),top:parseInt(l.marginTop)},d={left:parseInt(l.paddingLeft),right:parseInt(l.paddingRight),bottom:parseInt(l.paddingBottom),top:parseInt(l.paddingTop)};return{x:n,y:r,top:i,left:o,bottom:a,right:c,width:u,height:s,outerWidth:Math.round(u+f.left+f.right),outerHeight:Math.round(s+f.top+f.bottom),margin:f,padding:d,inFlow:e.parentElement&&!!function(t){var n=getComputedStyle(t);if(!(l.overflow&&"visible"!==l.overflow||"none"!==n.float||"grid"===n.display||"flex"===n.display&&"column"!==n["flex-direction"])){switch(l.position){case"static":case"relative":break;default:return}switch(e.tagName){case"TR":case"TBODY":case"THEAD":case"TFOOT":return!0}switch(l.display){case"block":case"list-item":case"table":case"flex":case"grid":return!0}}}(e.parentElement)}};function he(e,t){const{subscribe:n,getState:r,actions:i,query:o}=e,a=u(!0),c=u(null),d=u(t);d.current=t;const h=s((e=>({...e,actions:i,query:o})),[i,o]);a.current&&t&&(c.current=t(r(),o),a.current=!1);const[p,y]=f(h(c.current));return l((()=>{let e;return d.current&&(e=n((e=>d.current(e,o)),(e=>{y(h(e))}))),()=>{e&&e()}}),[h,o,n]),p}var pe,ye=function(){return y(arguments.length>0&&void 0!==arguments[0]?arguments[0]:10)},ve=function(){function e(){W(this,e),$(this,"isEnabled",!0),$(this,"elementIdMap",new WeakMap),$(this,"registry",new Map)}return F(e,[{key:"getElementId",value:function(e){var t=this.elementIdMap.get(e);if(t)return t;var n=ye();return this.elementIdMap.set(e,n),n}},{key:"getConnectorId",value:function(e,t){var n=this.getElementId(e);return"".concat(t,"--").concat(n)}},{key:"register",value:function(e,t){var n=this,r=this.getByElement(e,t.name);if(r){if(p(t.required,r.required))return r;this.getByElement(e,t.name).disable()}var i=null,o=this.getConnectorId(e,t.name);return this.registry.set(o,{id:o,required:t.required,enable:function(){i&&i(),i=t.connector(e,t.required,t.options)},disable:function(){i&&i()},remove:function(){return n.remove(o)}}),this.isEnabled&&this.registry.get(o).enable(),this.registry.get(o)}},{key:"get",value:function(e){return this.registry.get(e)}},{key:"remove",value:function(e){var t=this.get(e);t&&(t.disable(),this.registry.delete(t.id))}},{key:"enable",value:function(){this.isEnabled=!0,this.registry.forEach((function(e){e.enable()}))}},{key:"disable",value:function(){this.isEnabled=!1,this.registry.forEach((function(e){e.disable()}))}},{key:"getByElement",value:function(e,t){return this.get(this.getConnectorId(e,t))}},{key:"removeByElement",value:function(e,t){return this.remove(this.getConnectorId(e,t))}},{key:"clear",value:function(){this.disable(),this.elementIdMap=new WeakMap,this.registry=new Map}}]),e}();!function(e){e[e.HandlerDisabled=0]="HandlerDisabled",e[e.HandlerEnabled=1]="HandlerEnabled"}(pe||(pe={}));var be=function(){function e(t){W(this,e),$(this,"options",void 0),$(this,"registry",new ve),$(this,"subscribers",new Set),this.options=t}return F(e,[{key:"listen",value:function(e){var t=this;return this.subscribers.add(e),function(){return t.subscribers.delete(e)}}},{key:"disable",value:function(){this.onDisable&&this.onDisable(),this.registry.disable(),this.subscribers.forEach((function(e){e(pe.HandlerDisabled)}))}},{key:"enable",value:function(){this.onEnable&&this.onEnable(),this.registry.enable(),this.subscribers.forEach((function(e){e(pe.HandlerEnabled)}))}},{key:"cleanup",value:function(){this.disable(),this.subscribers.clear(),this.registry.clear()}},{key:"addCraftEventListener",value:function(e,t,n,r){var i=function(r){(function(e,t,n){e.craft||(e.craft={stopPropagation:function(){},blockedEvents:{}});for(var r=e.craft&&e.craft.blockedEvents[t]||[],i=0;i<r.length;i++){var o=r[i];if(n!==o&&n.contains(o))return!0}return!1})(r,t,e)||(r.craft.stopPropagation=function(){r.craft.blockedEvents[t]||(r.craft.blockedEvents[t]=[]),r.craft.blockedEvents[t].push(e)},n(r))};return e.addEventListener(t,i,r),function(){return e.removeEventListener(t,i,r)}}},{key:"createConnectorsUsage",value:function(){var e=this,t=this.handlers(),n=new Set,r=!1,i=new Map;return{connectors:Object.entries(t).reduce((function(t,o){var a=X(o,2),c=a[0],u=a[1];return Y(Y({},t),{},$({},c,(function(t,o,a){var s=function(){var r=e.registry.register(t,{required:o,name:c,options:a,connector:u});return n.add(r.id),r};return i.set(e.registry.getConnectorId(t,c),s),r&&s(),t})))}),{}),register:function(){r=!0,i.forEach((function(e){e()}))},cleanup:function(){r=!1,n.forEach((function(t){return e.registry.remove(t)}))}}}},{key:"derive",value:function(e,t){return new e(this,t)}},{key:"createProxyHandlers",value:function(e,t){var n=[],r=e.handlers(),i=new Proxy(r,{get:function(e,t,i){return t in r==0?Reflect.get(e,t,i):function(e){for(var i=arguments.length,o=new Array(i>1?i-1:0),a=1;a<i;a++)o[a-1]=arguments[a];var c=r[t].apply(r,[e].concat(o));c&&n.push(c)}}});return t(i),function(){n.forEach((function(e){e()}))}}},{key:"reflect",value:function(e){return this.createProxyHandlers(this,e)}}]),e}(),me=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),Object.defineProperty(e,"prototype",{writable:!1}),t&&K(e,t)}(i,be);var t,n,r=(t=i,n=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,r=J(t);if(n){var i=J(this).constructor;e=Reflect.construct(r,arguments,i)}else e=r.apply(this,arguments);return function(e,t){if(t&&("object"==typeof t||"function"==typeof t))return t;if(void 0!==t)throw new TypeError("Derived constructors may only return object or undefined");return Q(e)}(this,e)});function i(e,t){var n;return W(this,i),$(Q(n=r.call(this,t)),"derived",void 0),$(Q(n),"unsubscribeParentHandlerListener",void 0),n.derived=e,n.options=t,n.unsubscribeParentHandlerListener=n.derived.listen((function(e){switch(e){case pe.HandlerEnabled:return n.enable();case pe.HandlerDisabled:return n.disable();default:return}})),n}return F(i,[{key:"inherit",value:function(e){return this.createProxyHandlers(this.derived,e)}},{key:"cleanup",value:function(){V(J(i.prototype),"cleanup",this).call(this),this.unsubscribeParentHandlerListener()}}]),i}();function ge(e,t){t&&("function"==typeof e?e(t):e.current=t)}function Ee(e,t){const n=e.ref;return v("string"!=typeof n,"Cannot connect to an element with an existing string ref. Please convert it to use a callback ref instead, or wrap it into a <span> or <div>. Read more: https://facebook.github.io/react/docs/more-about-refs.html#the-ref-callback-attribute"),d(e,n?{ref:e=>{ge(n,e),ge(t,e)}}:{ref:t})}function we(e){return(t=null,...n)=>{if(!h(t)){if(!t)return;const r=t;return r&&e(r,...n),r}const r=t;return function(e){if("string"!=typeof e.type)throw new Error}(r),Ee(r,e)}}function Oe(e){return Object.keys(e).reduce(((t,n)=>(t[n]=we(((...t)=>e[n](...t))),t)),{})}const Re=({style:e,parentDom:t})=>{const n=a.createElement("div",{style:{position:"fixed",display:"block",opacity:1,borderStyle:"solid",borderWidth:"1px",borderColor:"transparent",zIndex:99999,...e}});return t&&t.ownerDocument!==document?b.createPortal(n,t.ownerDocument.body):n},ke=e=>{l(e,[])};var Pe=function(e,t){var n="Deprecation warning: ".concat(e," will be deprecated in future relases."),r=t.suggest,i=t.doc;r&&(n+=" Please use ".concat(r," instead.")),i&&(n+="(".concat(i,")")),console.warn(n)},je=function(){return"undefined"!=typeof window},Te=function(){return je()&&/Linux/i.test(window.navigator.userAgent)},Ie=function(){return je()&&/Chrome/i.test(window.navigator.userAgent)};export{g as DEPRECATED_ROOT_NODE,me as DerivedEventHandlers,N as ERROR_CANNOT_DRAG,M as ERROR_DELETE_TOP_LEVEL_NODE,U as ERROR_DESERIALIZE_COMPONENT_NOT_IN_RESOLVER,w as ERROR_DUPLICATE_NODEID,x as ERROR_INFINITE_CANVAS,O as ERROR_INVALID_NODEID,L as ERROR_INVALID_NODE_ID,k as ERROR_MISSING_PLACEHOLDER_PLACEMENT,P as ERROR_MOVE_CANNOT_DROP,j as ERROR_MOVE_INCOMING_PARENT,I as ERROR_MOVE_NONCANVAS_CHILD,T as ERROR_MOVE_OUTGOING_PARENT,A as ERROR_MOVE_ROOT_NODE,D as ERROR_MOVE_TOP_LEVEL_NODE,S as ERROR_MOVE_TO_DESCENDANT,C as ERROR_MOVE_TO_NONCANVAS_PARENT,E as ERROR_NOPARENT,H as ERROR_NOT_IN_RESOLVER,_ as ERROR_RESOLVER_NOT_AN_OBJECT,R as ERROR_TOP_LEVEL_ELEMENT_NO_ID,q as ERROR_USE_EDITOR_OUTSIDE_OF_EDITOR_CONTEXT,B as ERROR_USE_NODE_OUTSIDE_OF_EDITOR_CONTEXT,pe as EventHandlerUpdates,be as EventHandlers,ae as HISTORY_ACTIONS,ce as History,m as ROOT_NODE,Re as RenderIndicator,Ee as cloneWithRef,se as createQuery,Pe as deprecationWarning,de as getDOMInfo,ye as getRandomId,Ie as isChromium,je as isClientSide,Te as isLinux,he as useCollector,ke as useEffectOnce,ue as useMethods,Oe as wrapConnectorHooks,we as wrapHookToRecognizeElement};
import produce, { applyPatches, enableMapSet, enablePatches, produceWithPatches } from 'immer';
import isEqualWith from 'lodash/isEqualWith';
import React, { useMemo, useRef, useCallback, useEffect, useState, cloneElement, isValidElement } from 'react';
import isEqual from 'shallowequal';
import { nanoid } from 'nanoid';
import invariant from 'tiny-invariant';
import ReactDOM from 'react-dom';
const ROOT_NODE = 'ROOT';
const DEPRECATED_ROOT_NODE = 'canvas-ROOT';
// TODO: Use a better way to store/display error messages
const ERROR_NOPARENT = 'Parent id cannot be ommited';
const ERROR_DUPLICATE_NODEID = 'Attempting to add a node with duplicated id';
const ERROR_INVALID_NODEID = 'Node does not exist, it may have been removed';
const ERROR_TOP_LEVEL_ELEMENT_NO_ID = 'A <Element /> that is used inside a User Component must specify an `id` prop, eg: <Element id="text_element">...</Element> ';
const ERROR_MISSING_PLACEHOLDER_PLACEMENT = 'Placeholder required placement info (parent, index, or where) is missing';
const ERROR_MOVE_CANNOT_DROP = 'Node cannot be dropped into target parent';
const ERROR_MOVE_INCOMING_PARENT = 'Target parent rejects incoming node';
const ERROR_MOVE_OUTGOING_PARENT = 'Current parent rejects outgoing node';
const ERROR_MOVE_NONCANVAS_CHILD = 'Cannot move node that is not a direct child of a Canvas node';
const ERROR_MOVE_TO_NONCANVAS_PARENT = 'Cannot move node into a non-Canvas parent';
const ERROR_MOVE_TOP_LEVEL_NODE = 'A top-level Node cannot be moved';
const ERROR_MOVE_ROOT_NODE = 'Root Node cannot be moved';
const ERROR_MOVE_TO_DESCENDANT = 'Cannot move node into a descendant';
const ERROR_NOT_IN_RESOLVER = 'The component type specified for this node (%node_type%) does not exist in the resolver';
const ERROR_INFINITE_CANVAS = "The component specified in the <Canvas> `is` prop has additional Canvas specified in it's render template.";
const ERROR_CANNOT_DRAG = 'The node has specified a canDrag() rule that prevents it from being dragged';
const ERROR_INVALID_NODE_ID = 'Invalid parameter Node Id specified';
const ERROR_DELETE_TOP_LEVEL_NODE = 'Attempting to delete a top-level Node';
const ERROR_RESOLVER_NOT_AN_OBJECT = "Resolver in <Editor /> has to be an object. For (de)serialization Craft.js needs a list of all the User Components. \n \nMore info: https://craft.js.org/r/docs/api/editor#props";
const ERROR_DESERIALIZE_COMPONENT_NOT_IN_RESOLVER = "An Error occurred while deserializing components: Cannot find component <%displayName% /> in resolver map. Please check your resolver in <Editor />\n\nAvailable components in resolver: %availableComponents%\n\nMore info: https://craft.js.org/r/docs/api/editor#props";
const ERROR_USE_EDITOR_OUTSIDE_OF_EDITOR_CONTEXT = "You can only use useEditor in the context of <Editor />. \n\nPlease only use useEditor in components that are children of the <Editor /> component.";
const ERROR_USE_NODE_OUTSIDE_OF_EDITOR_CONTEXT = "You can only use useNode in the context of <Editor />. \n\nPlease only use useNode in components that are children of the <Editor /> component.";
function ownKeys(object, enumerableOnly) {
var keys = Object.keys(object);
if (Object.getOwnPropertySymbols) {
var symbols = Object.getOwnPropertySymbols(object);
enumerableOnly && (symbols = symbols.filter(function (sym) {
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
})), keys.push.apply(keys, symbols);
}
return keys;
}
function _objectSpread2(target) {
for (var i = 1; i < arguments.length; i++) {
var source = null != arguments[i] ? arguments[i] : {};
i % 2 ? ownKeys(Object(source), !0).forEach(function (key) {
_defineProperty(target, key, source[key]);
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) {
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
});
}
return target;
}
function _defineProperty(obj, key, value) {
key = _toPropertyKey(key);
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
}
function _toPrimitive(input, hint) {
if (typeof input !== "object" || input === null) return input;
var prim = input[Symbol.toPrimitive];
if (prim !== undefined) {
var res = prim.call(input, hint || "default");
if (typeof res !== "object") return res;
throw new TypeError("@@toPrimitive must return a primitive value.");
}
return (hint === "string" ? String : Number)(input);
}
function _toPropertyKey(arg) {
var key = _toPrimitive(arg, "string");
return typeof key === "symbol" ? key : String(key);
}
const HISTORY_ACTIONS = {
UNDO: 'HISTORY_UNDO',
REDO: 'HISTORY_REDO',
THROTTLE: 'HISTORY_THROTTLE',
IGNORE: 'HISTORY_IGNORE',
MERGE: 'HISTORY_MERGE',
CLEAR: 'HISTORY_CLEAR'
};
class History {
constructor() {
_defineProperty(this, "timeline", []);
_defineProperty(this, "pointer", -1);
}
add(patches, inversePatches) {
if (patches.length === 0 && inversePatches.length === 0) {
return;
}
this.pointer = this.pointer + 1;
this.timeline.length = this.pointer;
this.timeline[this.pointer] = {
patches,
inversePatches,
timestamp: Date.now()
};
}
throttleAdd(patches, inversePatches) {
let throttleRate = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 500;
if (patches.length === 0 && inversePatches.length === 0) {
return;
}
if (this.timeline.length && this.pointer >= 0) {
const {
patches: currPatches,
inversePatches: currInversePatches,
timestamp
} = this.timeline[this.pointer];
const now = new Date();
const diff = now.getTime() - timestamp;
if (diff < throttleRate) {
this.timeline[this.pointer] = {
timestamp,
patches: [...currPatches, ...patches],
inversePatches: [...inversePatches, ...currInversePatches]
};
return;
}
}
this.add(patches, inversePatches);
}
merge(patches, inversePatches) {
if (patches.length === 0 && inversePatches.length === 0) {
return;
}
if (this.timeline.length && this.pointer >= 0) {
const {
patches: currPatches,
inversePatches: currInversePatches,
timestamp
} = this.timeline[this.pointer];
this.timeline[this.pointer] = {
timestamp,
patches: [...currPatches, ...patches],
inversePatches: [...inversePatches, ...currInversePatches]
};
return;
}
this.add(patches, inversePatches);
}
clear() {
this.timeline = [];
this.pointer = -1;
}
canUndo() {
return this.pointer >= 0;
}
canRedo() {
return this.pointer < this.timeline.length - 1;
}
undo(state) {
if (!this.canUndo()) {
return;
}
const {
inversePatches
} = this.timeline[this.pointer];
this.pointer = this.pointer - 1;
return applyPatches(state, inversePatches);
}
redo(state) {
if (!this.canRedo()) {
return;
}
this.pointer = this.pointer + 1;
const {
patches
} = this.timeline[this.pointer];
return applyPatches(state, patches);
}
}
enableMapSet();
enablePatches();
function useMethods(methodsOrOptions, initialState, queryMethods, patchListener) {
const history = useMemo(() => new History(), []);
let methodsFactory;
let ignoreHistoryForActionsRef = useRef([]);
let normalizeHistoryRef = useRef();
if (typeof methodsOrOptions === 'function') {
methodsFactory = methodsOrOptions;
} else {
methodsFactory = methodsOrOptions.methods;
ignoreHistoryForActionsRef.current = methodsOrOptions.ignoreHistoryForActions;
normalizeHistoryRef.current = methodsOrOptions.normalizeHistory;
}
const patchListenerRef = useRef(patchListener);
patchListenerRef.current = patchListener;
const stateRef = useRef(initialState);
const reducer = useMemo(() => {
const {
current: normalizeHistory
} = normalizeHistoryRef;
const {
current: ignoreHistoryForActions
} = ignoreHistoryForActionsRef;
const {
current: patchListener
} = patchListenerRef;
return (state, action) => {
const query = queryMethods && createQuery(queryMethods, () => state, history);
let finalState;
let [nextState, patches, inversePatches] = produceWithPatches(state, draft => {
switch (action.type) {
case HISTORY_ACTIONS.UNDO:
{
return history.undo(draft);
}
case HISTORY_ACTIONS.REDO:
{
return history.redo(draft);
}
case HISTORY_ACTIONS.CLEAR:
{
history.clear();
return _objectSpread2({}, draft);
}
// TODO: Simplify History API
case HISTORY_ACTIONS.IGNORE:
case HISTORY_ACTIONS.MERGE:
case HISTORY_ACTIONS.THROTTLE:
{
const [type, ...params] = action.payload;
methodsFactory(draft, query)[type](...params);
break;
}
default:
methodsFactory(draft, query)[action.type](...action.payload);
}
});
finalState = nextState;
if (patchListener) {
patchListener(nextState, state, {
type: action.type,
params: action.payload,
patches
}, query, cb => {
let normalizedDraft = produceWithPatches(nextState, cb);
finalState = normalizedDraft[0];
patches = [...patches, ...normalizedDraft[1]];
inversePatches = [...normalizedDraft[2], ...inversePatches];
});
}
if ([HISTORY_ACTIONS.UNDO, HISTORY_ACTIONS.REDO].includes(action.type) && normalizeHistory) {
finalState = produce(finalState, normalizeHistory);
}
if (![...ignoreHistoryForActions, HISTORY_ACTIONS.UNDO, HISTORY_ACTIONS.REDO, HISTORY_ACTIONS.IGNORE, HISTORY_ACTIONS.CLEAR].includes(action.type)) {
if (action.type === HISTORY_ACTIONS.THROTTLE) {
history.throttleAdd(patches, inversePatches, action.config && action.config.rate);
} else if (action.type === HISTORY_ACTIONS.MERGE) {
history.merge(patches, inversePatches);
} else {
history.add(patches, inversePatches);
}
}
return finalState;
};
}, [history, methodsFactory, queryMethods]);
const getState = useCallback(() => stateRef.current, []);
const watcher = useMemo(() => new Watcher(getState), [getState]);
const dispatch = useCallback(action => {
const newState = reducer(stateRef.current, action);
stateRef.current = newState;
watcher.notify();
}, [reducer, watcher]);
useEffect(() => {
watcher.notify();
}, [watcher]);
const query = useMemo(() => !queryMethods ? [] : createQuery(queryMethods, () => stateRef.current, history), [history, queryMethods]);
const actions = useMemo(() => {
const actionTypes = Object.keys(methodsFactory(null, null));
const {
current: ignoreHistoryForActions
} = ignoreHistoryForActionsRef;
return _objectSpread2(_objectSpread2({}, actionTypes.reduce((accum, type) => {
accum[type] = function () {
for (var _len = arguments.length, payload = new Array(_len), _key = 0; _key < _len; _key++) {
payload[_key] = arguments[_key];
}
return dispatch({
type,
payload
});
};
return accum;
}, {})), {}, {
history: {
undo() {
return dispatch({
type: HISTORY_ACTIONS.UNDO
});
},
redo() {
return dispatch({
type: HISTORY_ACTIONS.REDO
});
},
clear: () => {
return dispatch({
type: HISTORY_ACTIONS.CLEAR
});
},
throttle: rate => {
return _objectSpread2({}, actionTypes.filter(type => !ignoreHistoryForActions.includes(type)).reduce((accum, type) => {
accum[type] = function () {
for (var _len2 = arguments.length, payload = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
payload[_key2] = arguments[_key2];
}
return dispatch({
type: HISTORY_ACTIONS.THROTTLE,
payload: [type, ...payload],
config: {
rate: rate
}
});
};
return accum;
}, {}));
},
ignore: () => {
return _objectSpread2({}, actionTypes.filter(type => !ignoreHistoryForActions.includes(type)).reduce((accum, type) => {
accum[type] = function () {
for (var _len3 = arguments.length, payload = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
payload[_key3] = arguments[_key3];
}
return dispatch({
type: HISTORY_ACTIONS.IGNORE,
payload: [type, ...payload]
});
};
return accum;
}, {}));
},
merge: () => {
return _objectSpread2({}, actionTypes.filter(type => !ignoreHistoryForActions.includes(type)).reduce((accum, type) => {
accum[type] = function () {
for (var _len4 = arguments.length, payload = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
payload[_key4] = arguments[_key4];
}
return dispatch({
type: HISTORY_ACTIONS.MERGE,
payload: [type, ...payload]
});
};
return accum;
}, {}));
}
}
});
}, [dispatch, methodsFactory]);
return useMemo(() => ({
getState,
subscribe: (collector, cb, collectOnCreate) => watcher.subscribe(collector, cb, collectOnCreate),
actions,
query,
history
}), [actions, query, watcher, getState, history]);
}
function createQuery(queryMethods, getState, history) {
const queries = Object.keys(queryMethods()).reduce((accum, key) => {
return _objectSpread2(_objectSpread2({}, accum), {}, {
[key]: function () {
return queryMethods(getState())[key](...arguments);
}
});
}, {});
return _objectSpread2(_objectSpread2({}, queries), {}, {
history: {
canUndo: () => history.canUndo(),
canRedo: () => history.canRedo()
}
});
}
class Watcher {
constructor(getState) {
_defineProperty(this, "getState", void 0);
_defineProperty(this, "subscribers", []);
this.getState = getState;
}
/**
* Creates a Subscriber
* @returns {() => void} a Function that removes the Subscriber
*/
subscribe(collector, onChange, collectOnCreate) {
const subscriber = new Subscriber(() => collector(this.getState()), onChange, collectOnCreate);
this.subscribers.push(subscriber);
return this.unsubscribe.bind(this, subscriber);
}
unsubscribe(subscriber) {
if (this.subscribers.length) {
const index = this.subscribers.indexOf(subscriber);
if (index > -1) return this.subscribers.splice(index, 1);
}
}
notify() {
this.subscribers.forEach(subscriber => subscriber.collect());
}
}
class Subscriber {
/**
* Creates a Subscriber
* @param collector The method that returns an object of values to be collected
* @param onChange A callback method that is triggered when the collected values has changed
* @param collectOnCreate If set to true, the collector/onChange will be called on instantiation
*/
constructor(collector, onChange) {
let collectOnCreate = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
_defineProperty(this, "collected", void 0);
_defineProperty(this, "collector", void 0);
_defineProperty(this, "onChange", void 0);
_defineProperty(this, "id", void 0);
this.collector = collector;
this.onChange = onChange;
// Collect and run onChange callback when Subscriber is created
if (collectOnCreate) this.collect();
}
collect() {
try {
const recollect = this.collector();
if (!isEqualWith(recollect, this.collected)) {
this.collected = recollect;
if (this.onChange) this.onChange(this.collected);
}
} catch (err) {
// eslint-disable-next-line no-console
console.warn(err);
}
}
}
const getDOMInfo = el => {
const {
x,
y,
top,
left,
bottom,
right,
width,
height
} = el.getBoundingClientRect();
const style = window.getComputedStyle(el);
const margin = {
left: parseInt(style.marginLeft),
right: parseInt(style.marginRight),
bottom: parseInt(style.marginBottom),
top: parseInt(style.marginTop)
};
const padding = {
left: parseInt(style.paddingLeft),
right: parseInt(style.paddingRight),
bottom: parseInt(style.paddingBottom),
top: parseInt(style.paddingTop)
};
const styleInFlow = parent => {
const parentStyle = getComputedStyle(parent);
if (style.overflow && style.overflow !== 'visible') {
return;
}
if (parentStyle.float !== 'none') {
return;
}
if (parentStyle.display === 'grid') {
return;
}
if (parentStyle.display === 'flex' && parentStyle['flex-direction'] !== 'column') {
return;
}
switch (style.position) {
case 'static':
case 'relative':
break;
default:
return;
}
switch (el.tagName) {
case 'TR':
case 'TBODY':
case 'THEAD':
case 'TFOOT':
return true;
}
switch (style.display) {
case 'block':
case 'list-item':
case 'table':
case 'flex':
case 'grid':
return true;
}
return;
};
return {
x,
y,
top,
left,
bottom,
right,
width,
height,
outerWidth: Math.round(width + margin.left + margin.right),
outerHeight: Math.round(height + margin.top + margin.bottom),
margin,
padding,
inFlow: el.parentElement && !!styleInFlow(el.parentElement)
};
};
function useCollector(store, collector) {
const { subscribe, getState, actions, query } = store;
const initial = useRef(true);
const collected = useRef(null);
const collectorRef = useRef(collector);
collectorRef.current = collector;
const onCollect = useCallback((collected) => {
return { ...collected, actions, query };
}, [actions, query]);
// Collect states for initial render
if (initial.current && collector) {
collected.current = collector(getState(), query);
initial.current = false;
}
const [renderCollected, setRenderCollected] = useState(onCollect(collected.current));
// Collect states on state change
useEffect(() => {
let unsubscribe;
if (collectorRef.current) {
unsubscribe = subscribe((current) => collectorRef.current(current, query), (collected) => {
setRenderCollected(onCollect(collected));
});
}
return () => {
if (unsubscribe)
unsubscribe();
};
}, [onCollect, query, subscribe]);
return renderCollected;
}
// By default nanoid generate an ID with 21 characters. To reduce the footprint, we default to 10 characters.
// We have a higher probability for collisions, though
/**
* Generate a random ID. That ID can for example be used as a node ID.
*
* @param size The number of characters that are generated for the ID. Defaults to `10`
* @returns A random id
*/
const getRandomId = function () {
let size = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 10;
return nanoid(size);
};
/**
* Stores all connected DOM elements and their connectors here
* This allows us to easily enable/disable and perform cleanups
*/
class ConnectorRegistry {
constructor() {
_defineProperty(this, "isEnabled", true);
_defineProperty(this, "elementIdMap", new WeakMap());
_defineProperty(this, "registry", new Map());
}
getElementId(element) {
const existingId = this.elementIdMap.get(element);
if (existingId) {
return existingId;
}
const newId = getRandomId();
this.elementIdMap.set(element, newId);
return newId;
}
getConnectorId(element, connectorName) {
const elementId = this.getElementId(element);
return "".concat(connectorName, "--").concat(elementId);
}
register(element, connectorPayload) {
const existingConnector = this.getByElement(element, connectorPayload.name);
if (existingConnector) {
if (isEqual(connectorPayload.required, existingConnector.required)) {
return existingConnector;
}
this.getByElement(element, connectorPayload.name).disable();
}
let cleanup = null;
const id = this.getConnectorId(element, connectorPayload.name);
this.registry.set(id, {
id,
required: connectorPayload.required,
enable: () => {
if (cleanup) {
cleanup();
}
cleanup = connectorPayload.connector(element, connectorPayload.required, connectorPayload.options);
},
disable: () => {
if (!cleanup) {
return;
}
cleanup();
},
remove: () => {
return this.remove(id);
}
});
if (this.isEnabled) {
this.registry.get(id).enable();
}
return this.registry.get(id);
}
get(id) {
return this.registry.get(id);
}
remove(id) {
const connector = this.get(id);
if (!connector) {
return;
}
connector.disable();
this.registry.delete(connector.id);
}
enable() {
this.isEnabled = true;
this.registry.forEach(connectors => {
connectors.enable();
});
}
disable() {
this.isEnabled = false;
this.registry.forEach(connectors => {
connectors.disable();
});
}
getByElement(element, connectorName) {
return this.get(this.getConnectorId(element, connectorName));
}
removeByElement(element, connectorName) {
return this.remove(this.getConnectorId(element, connectorName));
}
clear() {
this.disable();
this.elementIdMap = new WeakMap();
this.registry = new Map();
}
}
var EventHandlerUpdates;
(function (EventHandlerUpdates) {
EventHandlerUpdates[EventHandlerUpdates["HandlerDisabled"] = 0] = "HandlerDisabled";
EventHandlerUpdates[EventHandlerUpdates["HandlerEnabled"] = 1] = "HandlerEnabled";
})(EventHandlerUpdates || (EventHandlerUpdates = {}));
/**
* Check if a specified event is blocked by a child
* that's a descendant of the specified element
*/
function isEventBlockedByDescendant(e, eventName, el) {
// Store initial Craft event value
if (!e.craft) {
e.craft = {
stopPropagation: () => {},
blockedEvents: {}
};
}
const blockingElements = e.craft && e.craft.blockedEvents[eventName] || [];
for (let i = 0; i < blockingElements.length; i++) {
const blockingElement = blockingElements[i];
if (el !== blockingElement && el.contains(blockingElement)) {
return true;
}
}
return false;
}
class EventHandlers {
constructor(options) {
_defineProperty(this, "options", void 0);
_defineProperty(this, "registry", new ConnectorRegistry());
_defineProperty(this, "subscribers", new Set());
this.options = options;
}
listen(cb) {
this.subscribers.add(cb);
return () => this.subscribers.delete(cb);
}
disable() {
if (this.onDisable) {
this.onDisable();
}
this.registry.disable();
this.subscribers.forEach(listener => {
listener(EventHandlerUpdates.HandlerDisabled);
});
}
enable() {
if (this.onEnable) {
this.onEnable();
}
this.registry.enable();
this.subscribers.forEach(listener => {
listener(EventHandlerUpdates.HandlerEnabled);
});
}
cleanup() {
this.disable();
this.subscribers.clear();
this.registry.clear();
}
addCraftEventListener(el, eventName, listener, options) {
const bindedListener = e => {
if (!isEventBlockedByDescendant(e, eventName, el)) {
e.craft.stopPropagation = () => {
if (!e.craft.blockedEvents[eventName]) {
e.craft.blockedEvents[eventName] = [];
}
e.craft.blockedEvents[eventName].push(el);
};
listener(e);
}
};
el.addEventListener(eventName, bindedListener, options);
return () => el.removeEventListener(eventName, bindedListener, options);
}
/**
* Creates a record of chainable connectors and tracks their usages
*/
createConnectorsUsage() {
const handlers = this.handlers();
// Track all active connector ids here
// This is so we can return a cleanup method below so the callee can programmatically cleanup all connectors
const activeConnectorIds = new Set();
let canRegisterConnectors = false;
const connectorsToRegister = new Map();
const connectors = Object.entries(handlers).reduce((accum, _ref) => {
let [name, handler] = _ref;
return _objectSpread2(_objectSpread2({}, accum), {}, {
[name]: (el, required, options) => {
const registerConnector = () => {
const connector = this.registry.register(el, {
required,
name,
options,
connector: handler
});
activeConnectorIds.add(connector.id);
return connector;
};
connectorsToRegister.set(this.registry.getConnectorId(el, name), registerConnector);
/**
* If register() has been called,
* register the connector immediately.
*
* Otherwise, registration is deferred until after register() is called
*/
if (canRegisterConnectors) {
registerConnector();
}
return el;
}
});
}, {});
return {
connectors,
register: () => {
canRegisterConnectors = true;
connectorsToRegister.forEach(registerConnector => {
registerConnector();
});
},
cleanup: () => {
canRegisterConnectors = false;
activeConnectorIds.forEach(connectorId => this.registry.remove(connectorId));
}
};
}
derive(type, opts) {
return new type(this, opts);
}
// This method allows us to execute multiple connectors and returns a single cleanup method for all of them
createProxyHandlers(instance, cb) {
const connectorsToCleanup = [];
const handlers = instance.handlers();
const proxiedHandlers = new Proxy(handlers, {
get: (target, key, receiver) => {
if (key in handlers === false) {
return Reflect.get(target, key, receiver);
}
return function (el) {
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
args[_key - 1] = arguments[_key];
}
const cleanup = handlers[key](el, ...args);
if (!cleanup) {
return;
}
connectorsToCleanup.push(cleanup);
};
}
});
cb(proxiedHandlers);
return () => {
connectorsToCleanup.forEach(cleanup => {
cleanup();
});
};
}
// This lets us to execute and cleanup sibling connectors
reflect(cb) {
return this.createProxyHandlers(this, cb);
}
}
// Creates EventHandlers that depends on another EventHandlers instance
// This lets us to easily create new connectors that composites of the parent EventHandlers instance
class DerivedEventHandlers extends EventHandlers {
constructor(derived, options) {
super(options);
_defineProperty(this, "derived", void 0);
_defineProperty(this, "unsubscribeParentHandlerListener", void 0);
this.derived = derived;
this.options = options;
// Automatically disable/enable depending on the parent handlers
this.unsubscribeParentHandlerListener = this.derived.listen(msg => {
switch (msg) {
case EventHandlerUpdates.HandlerEnabled:
{
return this.enable();
}
case EventHandlerUpdates.HandlerDisabled:
{
return this.disable();
}
default:
{
return;
}
}
});
}
// A method to easily inherit parent connectors
inherit(cb) {
return this.createProxyHandlers(this.derived, cb);
}
cleanup() {
super.cleanup();
this.unsubscribeParentHandlerListener();
}
}
// https://github.com/react-dnd/react-dnd
function setRef(ref, node) {
if (node) {
if (typeof ref === 'function') {
ref(node);
}
else {
ref.current = node;
}
}
}
function cloneWithRef(element, newRef) {
const previousRef = element.ref;
invariant(typeof previousRef !== 'string', 'Cannot connect to an element with an existing string ref. ' +
'Please convert it to use a callback ref instead, or wrap it into a <span> or <div>. ' +
'Read more: https://facebook.github.io/react/docs/more-about-refs.html#the-ref-callback-attribute');
if (!previousRef) {
// When there is no ref on the element, use the new ref directly
return cloneElement(element, {
ref: newRef,
});
}
else {
return cloneElement(element, {
ref: (node) => {
setRef(previousRef, node);
setRef(newRef, node);
},
});
}
}
function throwIfCompositeComponentElement(element) {
if (typeof element.type === 'string') {
return;
}
throw new Error();
}
function wrapHookToRecognizeElement(hook) {
return (elementOrNode = null, ...args) => {
// When passed a node, call the hook straight away.
if (!isValidElement(elementOrNode)) {
if (!elementOrNode) {
return;
}
const node = elementOrNode;
node && hook(node, ...args);
return node;
}
// If passed a ReactElement, clone it and attach this function as a ref.
// This helps us achieve a neat API where user doesn't even know that refs
// are being used under the hood.
const element = elementOrNode;
throwIfCompositeComponentElement(element);
return cloneWithRef(element, hook);
};
}
// A React wrapper for our connectors
// Wrap all our connectors so that would additionally accept React.ReactElement
function wrapConnectorHooks(connectors) {
return Object.keys(connectors).reduce((accum, key) => {
accum[key] = wrapHookToRecognizeElement((...args) => {
// @ts-ignore
return connectors[key](...args);
});
return accum;
}, {});
}
const RenderIndicator = ({ style, parentDom }) => {
const indicator = (React.createElement("div", { style: {
position: 'fixed',
display: 'block',
opacity: 1,
borderStyle: 'solid',
borderWidth: '1px',
borderColor: 'transparent',
zIndex: 99999,
...style,
} }));
if (parentDom && parentDom.ownerDocument !== document) {
return ReactDOM.createPortal(indicator, parentDom.ownerDocument.body);
}
return indicator;
};
const useEffectOnce = (effect) => {
/* eslint-disable-next-line react-hooks/exhaustive-deps */
useEffect(effect, []);
};
const deprecationWarning = (name, payload) => {
let message = "Deprecation warning: ".concat(name, " will be deprecated in future relases.");
const {
suggest,
doc
} = payload;
if (suggest) {
message += " Please use ".concat(suggest, " instead.");
}
// URL link to Documentation
if (doc) {
message += "(".concat(doc, ")");
}
// eslint-disable-next-line no-console
console.warn(message);
};
const isClientSide = () => typeof window !== 'undefined';
const isLinux = () => isClientSide() && /Linux/i.test(window.navigator.userAgent);
const isChromium = () => isClientSide() && /Chrome/i.test(window.navigator.userAgent);
export { DEPRECATED_ROOT_NODE, DerivedEventHandlers, ERROR_CANNOT_DRAG, ERROR_DELETE_TOP_LEVEL_NODE, ERROR_DESERIALIZE_COMPONENT_NOT_IN_RESOLVER, ERROR_DUPLICATE_NODEID, ERROR_INFINITE_CANVAS, ERROR_INVALID_NODEID, ERROR_INVALID_NODE_ID, ERROR_MISSING_PLACEHOLDER_PLACEMENT, ERROR_MOVE_CANNOT_DROP, ERROR_MOVE_INCOMING_PARENT, ERROR_MOVE_NONCANVAS_CHILD, ERROR_MOVE_OUTGOING_PARENT, ERROR_MOVE_ROOT_NODE, ERROR_MOVE_TOP_LEVEL_NODE, ERROR_MOVE_TO_DESCENDANT, ERROR_MOVE_TO_NONCANVAS_PARENT, ERROR_NOPARENT, ERROR_NOT_IN_RESOLVER, ERROR_RESOLVER_NOT_AN_OBJECT, ERROR_TOP_LEVEL_ELEMENT_NO_ID, ERROR_USE_EDITOR_OUTSIDE_OF_EDITOR_CONTEXT, ERROR_USE_NODE_OUTSIDE_OF_EDITOR_CONTEXT, EventHandlerUpdates, EventHandlers, HISTORY_ACTIONS, History, ROOT_NODE, RenderIndicator, cloneWithRef, createQuery, deprecationWarning, getDOMInfo, getRandomId, isChromium, isClientSide, isLinux, useCollector, useEffectOnce, useMethods, wrapConnectorHooks, wrapHookToRecognizeElement };

4

package.json
{
"name": "@craftjs/utils",
"description": "Utilities used internally across the craft.js monorepo",
"version": "0.2.0-beta.10",
"version": "0.2.0-beta.11",
"author": "Prev Wong <prevwong@gmail.com>",

@@ -33,3 +33,3 @@ "license": "MIT",

},
"gitHead": "fb0d5177ffc85f00a533a2b18cf19d85bf075634"
"gitHead": "0bc86651f6ffb2855edeba9aa300645007790d23"
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc