@craftjs/utils
Advanced tools
Comparing version 0.2.0-beta.11 to 0.2.0-beta.12
@@ -6,2 +6,10 @@ # Change Log | ||
# [0.2.0-beta.12](https://github.com/prevwong/craft.js/compare/v0.2.0-beta.11...v0.2.0-beta.12) (2023-06-30) | ||
**Note:** Version bump only for package @craftjs/utils | ||
# [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) | ||
@@ -8,0 +16,0 @@ |
@@ -1,1027 +0,1 @@ | ||
'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; | ||
"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; |
@@ -1,973 +0,1 @@ | ||
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 }; | ||
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}; |
{ | ||
"name": "@craftjs/utils", | ||
"description": "Utilities used internally across the craft.js monorepo", | ||
"version": "0.2.0-beta.11", | ||
"version": "0.2.0-beta.12", | ||
"author": "Prev Wong <prevwong@gmail.com>", | ||
@@ -33,3 +33,3 @@ "license": "MIT", | ||
}, | ||
"gitHead": "0bc86651f6ffb2855edeba9aa300645007790d23" | ||
"gitHead": "6e3647ed9e7f27f1cff82b6b3d8d81d2b6d94db3" | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
310807
1816
3