@embedpdf/plugin-interaction-manager 1.0.15 → 1.0.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +32 -4
- package/dist/index.js.map +1 -1
- package/dist/lib/actions.d.ts +9 -1
- package/dist/lib/interaction-manager-plugin.d.ts +1 -0
- package/dist/lib/types.d.ts +17 -2
- package/dist/preact/index.cjs +1 -1
- package/dist/preact/index.cjs.map +1 -1
- package/dist/preact/index.js +102 -34
- package/dist/preact/index.js.map +1 -1
- package/dist/react/index.cjs +1 -1
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.js +102 -34
- package/dist/react/index.js.map +1 -1
- package/dist/shared-preact/utils.d.ts +0 -5
- package/dist/shared-react/utils.d.ts +0 -5
- package/dist/shared-vue/utils.d.ts +0 -5
- package/dist/vue/hooks/use-interaction-manager.d.ts +2 -0
- package/dist/vue/index.cjs +1 -1
- package/dist/vue/index.cjs.map +1 -1
- package/dist/vue/index.js +102 -34
- package/dist/vue/index.js.map +1 -1
- package/package.json +5 -5
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("@embedpdf/core"),t="INTERACTION/ACTIVATE_MODE",a="INTERACTION/PAUSE",s="INTERACTION/RESUME",
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("@embedpdf/core"),t="INTERACTION/ACTIVATE_MODE",a="INTERACTION/PAUSE",s="INTERACTION/RESUME",o="INTERACTION/SET_CURSOR",r="INTERACTION/SET_DEFAULT_MODE";const n="pointerMode",i=class extends e.BasePlugin{constructor(t,a){super(t,a),this.modes=new Map,this.cursorClaims=new Map,this.buckets=new Map,this.alwaysGlobal=new Set,this.alwaysPage=new Map,this.onModeChange$=e.createEmitter(),this.onHandlerChange$=e.createEmitter(),this.onCursorChange$=e.createEmitter(),this.onStateChange$=e.createBehaviorEmitter(),this.registerMode({id:n,scope:"page",exclusive:!1,cursor:"auto"}),this.setDefaultMode(n),this.activate(n)}async initialize(e){}buildCapability(){return{activate:e=>this.activate(e),onModeChange:this.onModeChange$.on,onCursorChange:this.onCursorChange$.on,onHandlerChange:this.onHandlerChange$.on,onStateChange:this.onStateChange$.on,getActiveMode:()=>this.state.activeMode,getActiveInteractionMode:()=>this.getActiveInteractionMode(),activateDefaultMode:()=>this.activate(this.state.defaultMode),registerMode:e=>this.registerMode(e),registerHandlers:e=>this.registerHandlers(e),registerAlways:e=>this.registerAlways(e),setCursor:(e,t,a=0)=>this.setCursor(e,t,a),removeCursor:e=>this.removeCursor(e),getCurrentCursor:()=>this.state.cursor,getHandlersForScope:e=>this.getHandlersForScope(e),activeModeIsExclusive:()=>this.activeModeIsExclusive(),pause:()=>this.dispatch({type:a}),resume:()=>this.dispatch({type:s}),isPaused:()=>this.state.paused,setDefaultMode:e=>this.setDefaultMode(e),getDefaultMode:()=>this.state.defaultMode}}activate(e){if(!this.modes.has(e))throw new Error(`[interaction] unknown mode '${e}'`);if(e===this.state.activeMode)return;const a=this.state.activeMode;this.cursorClaims.clear(),this.notifyHandlersInactive(a),this.dispatch((e=>({type:t,payload:{mode:e}}))(e)),this.emitCursor(),this.notifyHandlersActive(e),this.onModeChange$.emit({...this.state,activeMode:e})}setDefaultMode(e){if(!this.modes.has(e))throw new Error(`[interaction] cannot set unknown mode '${e}' as default`);this.dispatch({type:r,payload:{mode:e}})}notifyHandlersActive(e){this.alwaysGlobal.forEach((t=>{var a;null==(a=t.onHandlerActiveStart)||a.call(t,e)})),this.alwaysPage.forEach((t=>{t.forEach((t=>{var a;null==(a=t.onHandlerActiveStart)||a.call(t,e)}))}));const t=this.modes.get(e);if(!t)return;const a=this.buckets.get(e);a&&("global"===t.scope&&a.global.forEach((t=>{var a;null==(a=t.onHandlerActiveStart)||a.call(t,e)})),"page"===t.scope&&a.page.forEach(((t,a)=>{t.forEach((t=>{var a;null==(a=t.onHandlerActiveStart)||a.call(t,e)}))})))}notifyHandlersInactive(e){this.alwaysGlobal.forEach((t=>{var a;null==(a=t.onHandlerActiveEnd)||a.call(t,e)})),this.alwaysPage.forEach((t=>{t.forEach((t=>{var a;null==(a=t.onHandlerActiveEnd)||a.call(t,e)}))}));const t=this.modes.get(e);if(!t)return;const a=this.buckets.get(e);a&&("global"===t.scope&&a.global.forEach((t=>{var a;null==(a=t.onHandlerActiveEnd)||a.call(t,e)})),"page"===t.scope&&a.page.forEach(((t,a)=>{t.forEach((t=>{var a;null==(a=t.onHandlerActiveEnd)||a.call(t,e)}))})))}registerMode(e){this.modes.set(e.id,e),this.buckets.has(e.id)||this.buckets.set(e.id,{global:new Set,page:new Map})}registerHandlers({modeId:e,handlers:t,pageIndex:a}){const s=Array.isArray(e)?e:[e],o=[];for(const r of s){const e=this.buckets.get(r);if(!e)throw new Error(`unknown mode '${r}'`);if(null==a)e.global.add(t);else{const s=e.page.get(a)??new Set;s.add(t),e.page.set(a,s)}o.push((()=>{if(null==a)e.global.delete(t);else{const s=e.page.get(a);s&&(s.delete(t),0===s.size&&e.page.delete(a))}}))}return this.onHandlerChange$.emit({...this.state}),()=>{o.forEach((e=>e())),this.onHandlerChange$.emit({...this.state})}}registerAlways({scope:e,handlers:t}){if("global"===e.type)return this.alwaysGlobal.add(t),this.onHandlerChange$.emit({...this.state}),()=>this.alwaysGlobal.delete(t);const a=this.alwaysPage.get(e.pageIndex)??new Set;return a.add(t),this.alwaysPage.set(e.pageIndex,a),this.onHandlerChange$.emit({...this.state}),()=>{a.delete(t),this.onHandlerChange$.emit({...this.state})}}getHandlersForScope(e){if(!this.state)return null;const t=this.modes.get(this.state.activeMode);if(!t)return null;const a=this.buckets.get(t.id);if(!a)return null;const s=(e,t)=>e.size||t.size?function(e){const t=["onPointerDown","onPointerUp","onPointerMove","onPointerEnter","onPointerLeave","onPointerCancel","onMouseDown","onMouseUp","onMouseMove","onMouseEnter","onMouseLeave","onMouseCancel","onClick","onDoubleClick"],a={};for(const s of t)a[s]=(t,a,o)=>{var r;for(const n of e)null==(r=n[s])||r.call(n,t,a,o)};return a}([...e,...t]):null;if("global"===e.type){const e="global"===t.scope?a.global:new Set;return s(this.alwaysGlobal,e)}return s(this.alwaysPage.get(e.pageIndex)??new Set,"page"===t.scope?a.page.get(e.pageIndex)??new Set:new Set)}setCursor(e,t,a=0){this.cursorClaims.set(e,{cursor:t,priority:a}),this.emitCursor()}removeCursor(e){this.cursorClaims.delete(e),this.emitCursor()}emitCursor(){var e;const t=[...this.cursorClaims.values()].sort(((e,t)=>t.priority-e.priority))[0]??{cursor:(null==(e=this.modes.get(this.state.activeMode))?void 0:e.cursor)??"auto"};var a;t.cursor!==this.state.cursor&&(this.dispatch((a=t.cursor,{type:o,payload:{cursor:a}})),this.onCursorChange$.emit(t.cursor))}onStoreUpdated(e,t){this.onStateChange$.emit(t)}activeModeIsExclusive(){const e=this.modes.get(this.state.activeMode);return!!(null==e?void 0:e.exclusive)}getActiveInteractionMode(){return this.modes.get(this.state.activeMode)??null}async destroy(){this.onModeChange$.clear(),this.onCursorChange$.clear(),await super.destroy()}};i.id="interaction-manager";let l=i;const c="interaction-manager",d={id:c,name:"Interaction Manager Plugin",version:"1.0.0",provides:["interaction-manager"],requires:[],optional:[],defaultConfig:{enabled:!0}},h={activeMode:"pointerMode",defaultMode:"pointerMode",cursor:"auto",paused:!1},u=(e,n)=>{switch(n.type){case t:return{...e,activeMode:n.payload.mode};case o:return{...e,cursor:n.payload.cursor};case a:return{...e,paused:!0};case s:return{...e,paused:!1};case r:return{...e,defaultMode:n.payload.mode};default:return e}},g={manifest:d,create:e=>new l(c,e),reducer:u,initialState:h};exports.INTERACTION_MANAGER_PLUGIN_ID=c,exports.InteractionManagerPlugin=l,exports.InteractionManagerPluginPackage=g,exports.initialState=h,exports.manifest=d,exports.reducer=u;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../src/lib/actions.ts","../src/lib/interaction-manager-plugin.ts","../src/lib/helper.ts","../src/lib/manifest.ts","../src/lib/reducer.ts","../src/lib/index.ts"],"sourcesContent":["import { Action } from '@embedpdf/core';\n\nexport const ACTIVATE_MODE = 'INTERACTION/ACTIVATE_MODE';\nexport const PAUSE_INTERACTION = 'INTERACTION/PAUSE';\nexport const RESUME_INTERACTION = 'INTERACTION/RESUME';\nexport const SET_CURSOR = 'INTERACTION/SET_CURSOR';\n\nexport interface ActivateModeAction extends Action {\n type: typeof ACTIVATE_MODE;\n payload: { mode: string };\n}\n\nexport interface PauseInteractionAction extends Action {\n type: typeof PAUSE_INTERACTION;\n}\n\nexport interface ResumeInteractionAction extends Action {\n type: typeof RESUME_INTERACTION;\n}\n\nexport interface SetCursorAction extends Action {\n type: typeof SET_CURSOR;\n payload: { cursor: string };\n}\n\nexport const activateMode = (mode: string): ActivateModeAction => ({\n type: ACTIVATE_MODE,\n payload: { mode },\n});\n\nexport const setCursor = (cursor: string): SetCursorAction => ({\n type: SET_CURSOR,\n payload: { cursor },\n});\n\nexport const pauseInteraction = (): PauseInteractionAction => ({\n type: PAUSE_INTERACTION,\n});\n\nexport const resumeInteraction = (): ResumeInteractionAction => ({\n type: RESUME_INTERACTION,\n});\n\nexport type InteractionManagerAction =\n | ActivateModeAction\n | PauseInteractionAction\n | ResumeInteractionAction\n | SetCursorAction;\n","import { BasePlugin, createBehaviorEmitter, createEmitter, PluginRegistry } from '@embedpdf/core';\n\nimport {\n InteractionManagerCapability,\n InteractionManagerPluginConfig,\n InteractionManagerState,\n InteractionMode,\n InteractionScope,\n PointerEventHandlers,\n PointerEventHandlersWithLifecycle,\n RegisterAlwaysOptions,\n RegisterHandlersOptions,\n} from './types';\nimport { activateMode, pauseInteraction, resumeInteraction, setCursor } from './actions';\nimport { mergeHandlers } from './helper';\n\ninterface CursorClaim {\n cursor: string;\n priority: number;\n}\n\ntype HandlerSet = Set<PointerEventHandlersWithLifecycle>;\ntype PageHandlerMap = Map<number /*pageIdx*/, HandlerSet>;\n\ninterface ModeBuckets {\n /** handlers that listen on the global wrapper (only once per viewer) */\n global: HandlerSet;\n /** handlers that listen on a *specific* page wrapper */\n page: PageHandlerMap;\n}\n\nexport class InteractionManagerPlugin extends BasePlugin<\n InteractionManagerPluginConfig,\n InteractionManagerCapability,\n InteractionManagerState\n> {\n static readonly id = 'interaction-manager' as const;\n\n private modes = new Map<string, InteractionMode>();\n private cursorClaims = new Map<string, CursorClaim>();\n private buckets = new Map<string, ModeBuckets>();\n\n private alwaysGlobal = new Set<PointerEventHandlersWithLifecycle>();\n private alwaysPage = new Map<number, Set<PointerEventHandlersWithLifecycle>>();\n\n private readonly onModeChange$ = createEmitter<InteractionManagerState>();\n private readonly onHandlerChange$ = createEmitter<InteractionManagerState>();\n private readonly onCursorChange$ = createEmitter<string>();\n private readonly onStateChange$ = createBehaviorEmitter<InteractionManagerState>();\n\n constructor(id: string, registry: PluginRegistry) {\n super(id, registry);\n\n this.registerMode({\n id: 'default',\n scope: 'page',\n exclusive: false,\n cursor: 'auto',\n });\n }\n\n async initialize(_: InteractionManagerPluginConfig): Promise<void> {}\n\n protected buildCapability(): InteractionManagerCapability {\n return {\n activate: (modeId: string) => this.activate(modeId),\n onModeChange: this.onModeChange$.on,\n onCursorChange: this.onCursorChange$.on,\n onHandlerChange: this.onHandlerChange$.on,\n onStateChange: this.onStateChange$.on,\n getActiveMode: () => this.state.activeMode,\n getActiveInteractionMode: () => this.getActiveInteractionMode(),\n finish: () => this.activate('default'),\n registerMode: (mode: InteractionMode) => this.registerMode(mode),\n registerHandlers: (options: RegisterHandlersOptions) => this.registerHandlers(options),\n registerAlways: (options: RegisterAlwaysOptions) => this.registerAlways(options),\n setCursor: (token: string, cursor: string, priority = 0) =>\n this.setCursor(token, cursor, priority),\n removeCursor: (token: string) => this.removeCursor(token),\n getCurrentCursor: () => this.state.cursor,\n getHandlersForScope: (scope: InteractionScope) => this.getHandlersForScope(scope),\n activeModeIsExclusive: () => this.activeModeIsExclusive(),\n pause: () => this.dispatch(pauseInteraction()),\n resume: () => this.dispatch(resumeInteraction()),\n isPaused: () => this.state.paused,\n };\n }\n\n private activate(mode: string) {\n if (!this.modes.has(mode)) {\n throw new Error(`[interaction] unknown mode '${mode}'`);\n }\n if (mode === this.state.activeMode) return;\n\n const previousMode = this.state.activeMode;\n this.cursorClaims.clear(); // prevent cursor leaks\n\n this.notifyHandlersInactive(previousMode);\n\n this.dispatch(activateMode(mode));\n this.emitCursor();\n\n // Call lifecycle hooks for handlers going active\n this.notifyHandlersActive(mode);\n\n this.onModeChange$.emit({ ...this.state, activeMode: mode });\n }\n\n private notifyHandlersActive(modeId: string) {\n this.alwaysGlobal.forEach((handler) => {\n handler.onHandlerActiveStart?.(modeId);\n });\n\n this.alwaysPage.forEach((handlerSet) => {\n handlerSet.forEach((handler) => {\n handler.onHandlerActiveStart?.(modeId);\n });\n });\n\n const mode = this.modes.get(modeId);\n if (!mode) return;\n\n const bucket = this.buckets.get(modeId);\n if (!bucket) return;\n\n // Notify global handlers if mode is global\n if (mode.scope === 'global') {\n bucket.global.forEach((handler) => {\n handler.onHandlerActiveStart?.(modeId);\n });\n }\n\n // Notify page handlers if mode is page\n if (mode.scope === 'page') {\n bucket.page.forEach((handlerSet, pageIndex) => {\n handlerSet.forEach((handler) => {\n handler.onHandlerActiveStart?.(modeId);\n });\n });\n }\n }\n\n private notifyHandlersInactive(modeId: string) {\n this.alwaysGlobal.forEach((handler) => {\n handler.onHandlerActiveEnd?.(modeId);\n });\n\n this.alwaysPage.forEach((handlerSet) => {\n handlerSet.forEach((handler) => {\n handler.onHandlerActiveEnd?.(modeId);\n });\n });\n\n const mode = this.modes.get(modeId);\n if (!mode) return;\n\n const bucket = this.buckets.get(modeId);\n if (!bucket) return;\n\n // Notify global handlers if mode is global\n if (mode.scope === 'global') {\n bucket.global.forEach((handler) => {\n handler.onHandlerActiveEnd?.(modeId);\n });\n }\n\n // Notify page handlers if mode is page\n if (mode.scope === 'page') {\n bucket.page.forEach((handlerSet, pageIndex) => {\n handlerSet.forEach((handler) => {\n handler.onHandlerActiveEnd?.(modeId);\n });\n });\n }\n }\n\n private registerMode(mode: InteractionMode) {\n this.modes.set(mode.id, mode);\n if (!this.buckets.has(mode.id)) {\n this.buckets.set(mode.id, { global: new Set(), page: new Map() });\n }\n }\n\n /** ---------- pointer-handler handling ------------ */\n private registerHandlers({ modeId, handlers, pageIndex }: RegisterHandlersOptions): () => void {\n const modeIds = Array.isArray(modeId) ? modeId : [modeId];\n const cleanupFunctions: (() => void)[] = [];\n\n for (const id of modeIds) {\n const bucket = this.buckets.get(id);\n if (!bucket) throw new Error(`unknown mode '${id}'`);\n\n if (pageIndex == null) {\n bucket.global.add(handlers);\n } else {\n const set = bucket.page.get(pageIndex) ?? new Set();\n set.add(handlers);\n bucket.page.set(pageIndex, set);\n }\n\n // Create cleanup function for this specific mode\n cleanupFunctions.push(() => {\n if (pageIndex == null) {\n bucket.global.delete(handlers);\n } else {\n const set = bucket.page.get(pageIndex);\n if (set) {\n set.delete(handlers);\n if (set.size === 0) {\n bucket.page.delete(pageIndex);\n }\n }\n }\n });\n }\n\n this.onHandlerChange$.emit({ ...this.state });\n\n // Return a cleanup function that removes handlers from all registered modes\n return () => {\n cleanupFunctions.forEach((cleanup) => cleanup());\n this.onHandlerChange$.emit({ ...this.state });\n };\n }\n\n public registerAlways({ scope, handlers }: RegisterAlwaysOptions): () => void {\n if (scope.type === 'global') {\n this.alwaysGlobal.add(handlers);\n this.onHandlerChange$.emit({ ...this.state });\n return () => this.alwaysGlobal.delete(handlers);\n }\n const set = this.alwaysPage.get(scope.pageIndex) ?? new Set();\n set.add(handlers);\n this.alwaysPage.set(scope.pageIndex, set);\n this.onHandlerChange$.emit({ ...this.state });\n return () => {\n set.delete(handlers);\n this.onHandlerChange$.emit({ ...this.state });\n };\n }\n\n /** Returns the *merged* handler set that should be active for the given\n * provider (`global` wrapper or a single page wrapper).\n * – `alwaysGlobal` / `alwaysPage` are **always** active.\n * – Handlers that belong to the current mode are added on top **iff**\n * the mode’s own scope matches the provider’s scope. */\n private getHandlersForScope(scope: InteractionScope): PointerEventHandlers | null {\n if (!this.state) return null;\n\n const mode = this.modes.get(this.state.activeMode);\n if (!mode) return null;\n\n const bucket = this.buckets.get(mode.id);\n if (!bucket) return null;\n\n /** helper – merge two handler sets into one object (or `null` if both are empty) */\n const mergeSets = (a: HandlerSet, b: HandlerSet) =>\n a.size || b.size ? mergeHandlers([...a, ...b]) : null;\n\n /* ───────────────────── GLOBAL PROVIDER ─────────────────────── */\n if (scope.type === 'global') {\n const modeSpecific =\n mode.scope === 'global' // only include mode handlers if the\n ? bucket.global // mode itself is global-scoped\n : new Set<PointerEventHandlers>();\n return mergeSets(this.alwaysGlobal, modeSpecific);\n }\n\n /* ─────────────────────── PAGE PROVIDER ──────────────────────── */\n const alwaysPageSet = this.alwaysPage.get(scope.pageIndex) ?? new Set<PointerEventHandlers>();\n const modePageSet =\n mode.scope === 'page'\n ? (bucket.page.get(scope.pageIndex) ?? new Set<PointerEventHandlers>())\n : new Set<PointerEventHandlers>(); // global-scoped mode → ignore page buckets\n\n return mergeSets(alwaysPageSet, modePageSet);\n }\n\n /** ---------- cursor handling --------------------- */\n private setCursor(token: string, cursor: string, priority = 0) {\n this.cursorClaims.set(token, { cursor, priority });\n this.emitCursor();\n }\n private removeCursor(token: string) {\n this.cursorClaims.delete(token);\n this.emitCursor();\n }\n\n private emitCursor() {\n /* pick highest priority claim, else mode baseline */\n const top = [...this.cursorClaims.values()].sort((a, b) => b.priority - a.priority)[0] ?? {\n cursor: this.modes.get(this.state.activeMode)?.cursor ?? 'auto',\n };\n\n if (top.cursor !== this.state.cursor) {\n this.dispatch(setCursor(top.cursor));\n this.onCursorChange$.emit(top.cursor);\n }\n }\n\n override onStoreUpdated(_: InteractionManagerState, newState: InteractionManagerState): void {\n this.onStateChange$.emit(newState);\n }\n\n private activeModeIsExclusive(): boolean {\n const mode = this.modes.get(this.state.activeMode);\n return !!mode?.exclusive;\n }\n\n private getActiveInteractionMode(): InteractionMode | null {\n return this.modes.get(this.state.activeMode) ?? null;\n }\n\n // keep emitter clean\n async destroy(): Promise<void> {\n this.onModeChange$.clear();\n this.onCursorChange$.clear();\n await super.destroy();\n }\n}\n","import { PointerEventHandlers } from './types';\n\nexport function mergeHandlers(list: PointerEventHandlers[]): PointerEventHandlers {\n const keys: (keyof PointerEventHandlers)[] = [\n 'onPointerDown',\n 'onPointerUp',\n 'onPointerMove',\n 'onPointerEnter',\n 'onPointerLeave',\n 'onPointerCancel',\n 'onClick',\n 'onDoubleClick',\n ];\n const out: Partial<PointerEventHandlers> = {};\n for (const k of keys) {\n out[k] = (evt: any, nativeEvt: any, modeId: string) => {\n for (const h of list) h[k]?.(evt, nativeEvt, modeId);\n };\n }\n return out as PointerEventHandlers;\n}\n","import { PluginManifest } from '@embedpdf/core';\nimport { InteractionManagerPluginConfig } from './types';\n\nexport const INTERACTION_MANAGER_PLUGIN_ID = 'interaction-manager';\n\nexport const manifest: PluginManifest<InteractionManagerPluginConfig> = {\n id: INTERACTION_MANAGER_PLUGIN_ID,\n name: 'Interaction Manager Plugin',\n version: '1.0.0',\n provides: ['interaction-manager'],\n requires: [],\n optional: [],\n defaultConfig: {\n enabled: true,\n },\n};\n","import { Reducer } from '@embedpdf/core';\nimport {\n ACTIVATE_MODE,\n InteractionManagerAction,\n PAUSE_INTERACTION,\n RESUME_INTERACTION,\n SET_CURSOR,\n} from './actions';\nimport { InteractionManagerState } from './types';\n\nexport const initialState: InteractionManagerState = {\n activeMode: 'default',\n cursor: 'auto',\n paused: false,\n};\n\nexport const reducer: Reducer<InteractionManagerState, InteractionManagerAction> = (\n state,\n action,\n) => {\n switch (action.type) {\n case ACTIVATE_MODE:\n return {\n ...state,\n activeMode: action.payload.mode,\n };\n case SET_CURSOR:\n return {\n ...state,\n cursor: action.payload.cursor,\n };\n case PAUSE_INTERACTION:\n return {\n ...state,\n paused: true,\n };\n case RESUME_INTERACTION:\n return {\n ...state,\n paused: false,\n };\n default:\n return state;\n }\n};\n","import { PluginPackage } from '@embedpdf/core';\n\nimport { InteractionManagerPlugin } from './interaction-manager-plugin';\nimport { manifest, INTERACTION_MANAGER_PLUGIN_ID } from './manifest';\nimport { InteractionManagerPluginConfig, InteractionManagerState } from './types';\nimport { reducer, initialState } from './reducer';\nimport { InteractionManagerAction } from './actions';\n\nexport const InteractionManagerPluginPackage: PluginPackage<\n InteractionManagerPlugin,\n InteractionManagerPluginConfig,\n InteractionManagerState,\n InteractionManagerAction\n> = {\n manifest,\n create: (registry) => new InteractionManagerPlugin(INTERACTION_MANAGER_PLUGIN_ID, registry),\n reducer,\n initialState,\n};\n\nexport * from './interaction-manager-plugin';\nexport * from './types';\nexport * from './manifest';\nexport * from './reducer';\n"],"names":["ACTIVATE_MODE","PAUSE_INTERACTION","RESUME_INTERACTION","SET_CURSOR","_InteractionManagerPlugin","BasePlugin","constructor","id","registry","super","this","modes","Map","cursorClaims","buckets","alwaysGlobal","Set","alwaysPage","onModeChange$","createEmitter","onHandlerChange$","onCursorChange$","onStateChange$","createBehaviorEmitter","registerMode","scope","exclusive","cursor","initialize","_","buildCapability","activate","modeId","onModeChange","on","onCursorChange","onHandlerChange","onStateChange","getActiveMode","state","activeMode","getActiveInteractionMode","finish","mode","registerHandlers","options","registerAlways","setCursor","token","priority","removeCursor","getCurrentCursor","getHandlersForScope","activeModeIsExclusive","pause","dispatch","type","resume","isPaused","paused","has","Error","previousMode","clear","notifyHandlersInactive","payload","activateMode","emitCursor","notifyHandlersActive","emit","forEach","handler","_a","onHandlerActiveStart","call","handlerSet","get","bucket","global","page","pageIndex","onHandlerActiveEnd","set","handlers","modeIds","Array","isArray","cleanupFunctions","add","push","delete","size","cleanup","mergeSets","a","b","list","keys","out","k","evt","nativeEvt","h","mergeHandlers","modeSpecific","top","values","sort","onStoreUpdated","newState","destroy","InteractionManagerPlugin","INTERACTION_MANAGER_PLUGIN_ID","manifest","name","version","provides","requires","optional","defaultConfig","enabled","initialState","reducer","action","InteractionManagerPluginPackage","create"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../src/lib/actions.ts","../src/lib/interaction-manager-plugin.ts","../src/lib/helper.ts","../src/lib/manifest.ts","../src/lib/reducer.ts","../src/lib/index.ts"],"sourcesContent":["import { Action } from '@embedpdf/core';\n\nexport const ACTIVATE_MODE = 'INTERACTION/ACTIVATE_MODE';\nexport const PAUSE_INTERACTION = 'INTERACTION/PAUSE';\nexport const RESUME_INTERACTION = 'INTERACTION/RESUME';\nexport const SET_CURSOR = 'INTERACTION/SET_CURSOR';\nexport const SET_DEFAULT_MODE = 'INTERACTION/SET_DEFAULT_MODE';\n\nexport interface ActivateModeAction extends Action {\n type: typeof ACTIVATE_MODE;\n payload: { mode: string };\n}\n\nexport interface PauseInteractionAction extends Action {\n type: typeof PAUSE_INTERACTION;\n}\n\nexport interface ResumeInteractionAction extends Action {\n type: typeof RESUME_INTERACTION;\n}\n\nexport interface SetCursorAction extends Action {\n type: typeof SET_CURSOR;\n payload: { cursor: string };\n}\n\nexport interface SetDefaultModeAction extends Action {\n type: typeof SET_DEFAULT_MODE;\n payload: { mode: string };\n}\n\nexport const activateMode = (mode: string): ActivateModeAction => ({\n type: ACTIVATE_MODE,\n payload: { mode },\n});\n\nexport const setCursor = (cursor: string): SetCursorAction => ({\n type: SET_CURSOR,\n payload: { cursor },\n});\n\nexport const setDefaultMode = (mode: string): SetDefaultModeAction => ({\n type: SET_DEFAULT_MODE,\n payload: { mode },\n});\n\nexport const pauseInteraction = (): PauseInteractionAction => ({\n type: PAUSE_INTERACTION,\n});\n\nexport const resumeInteraction = (): ResumeInteractionAction => ({\n type: RESUME_INTERACTION,\n});\n\nexport type InteractionManagerAction =\n | ActivateModeAction\n | PauseInteractionAction\n | ResumeInteractionAction\n | SetCursorAction\n | SetDefaultModeAction;\n","import { BasePlugin, createBehaviorEmitter, createEmitter, PluginRegistry } from '@embedpdf/core';\n\nimport {\n InteractionManagerCapability,\n InteractionManagerPluginConfig,\n InteractionManagerState,\n InteractionMode,\n InteractionScope,\n PointerEventHandlers,\n PointerEventHandlersWithLifecycle,\n RegisterAlwaysOptions,\n RegisterHandlersOptions,\n} from './types';\nimport {\n activateMode,\n pauseInteraction,\n resumeInteraction,\n setCursor,\n setDefaultMode,\n} from './actions';\nimport { mergeHandlers } from './helper';\n\ninterface CursorClaim {\n cursor: string;\n priority: number;\n}\n\ntype HandlerSet = Set<PointerEventHandlersWithLifecycle>;\ntype PageHandlerMap = Map<number /*pageIdx*/, HandlerSet>;\n\ninterface ModeBuckets {\n /** handlers that listen on the global wrapper (only once per viewer) */\n global: HandlerSet;\n /** handlers that listen on a *specific* page wrapper */\n page: PageHandlerMap;\n}\n\nconst INITIAL_MODE = 'pointerMode';\n\nexport class InteractionManagerPlugin extends BasePlugin<\n InteractionManagerPluginConfig,\n InteractionManagerCapability,\n InteractionManagerState\n> {\n static readonly id = 'interaction-manager' as const;\n\n private modes = new Map<string, InteractionMode>();\n private cursorClaims = new Map<string, CursorClaim>();\n private buckets = new Map<string, ModeBuckets>();\n\n private alwaysGlobal = new Set<PointerEventHandlersWithLifecycle>();\n private alwaysPage = new Map<number, Set<PointerEventHandlersWithLifecycle>>();\n\n private readonly onModeChange$ = createEmitter<InteractionManagerState>();\n private readonly onHandlerChange$ = createEmitter<InteractionManagerState>();\n private readonly onCursorChange$ = createEmitter<string>();\n private readonly onStateChange$ = createBehaviorEmitter<InteractionManagerState>();\n\n constructor(id: string, registry: PluginRegistry) {\n super(id, registry);\n\n this.registerMode({\n id: INITIAL_MODE,\n scope: 'page',\n exclusive: false,\n cursor: 'auto',\n });\n\n this.setDefaultMode(INITIAL_MODE);\n this.activate(INITIAL_MODE);\n }\n\n async initialize(_: InteractionManagerPluginConfig): Promise<void> {}\n\n protected buildCapability(): InteractionManagerCapability {\n return {\n activate: (modeId: string) => this.activate(modeId),\n onModeChange: this.onModeChange$.on,\n onCursorChange: this.onCursorChange$.on,\n onHandlerChange: this.onHandlerChange$.on,\n onStateChange: this.onStateChange$.on,\n getActiveMode: () => this.state.activeMode,\n getActiveInteractionMode: () => this.getActiveInteractionMode(),\n activateDefaultMode: () => this.activate(this.state.defaultMode),\n registerMode: (mode: InteractionMode) => this.registerMode(mode),\n registerHandlers: (options: RegisterHandlersOptions) => this.registerHandlers(options),\n registerAlways: (options: RegisterAlwaysOptions) => this.registerAlways(options),\n setCursor: (token: string, cursor: string, priority = 0) =>\n this.setCursor(token, cursor, priority),\n removeCursor: (token: string) => this.removeCursor(token),\n getCurrentCursor: () => this.state.cursor,\n getHandlersForScope: (scope: InteractionScope) => this.getHandlersForScope(scope),\n activeModeIsExclusive: () => this.activeModeIsExclusive(),\n pause: () => this.dispatch(pauseInteraction()),\n resume: () => this.dispatch(resumeInteraction()),\n isPaused: () => this.state.paused,\n setDefaultMode: (id: string) => this.setDefaultMode(id),\n getDefaultMode: () => this.state.defaultMode,\n };\n }\n\n private activate(mode: string) {\n if (!this.modes.has(mode)) {\n throw new Error(`[interaction] unknown mode '${mode}'`);\n }\n if (mode === this.state.activeMode) return;\n\n const previousMode = this.state.activeMode;\n this.cursorClaims.clear(); // prevent cursor leaks\n\n this.notifyHandlersInactive(previousMode);\n\n this.dispatch(activateMode(mode));\n this.emitCursor();\n\n // Call lifecycle hooks for handlers going active\n this.notifyHandlersActive(mode);\n\n this.onModeChange$.emit({ ...this.state, activeMode: mode });\n }\n\n private setDefaultMode(modeId: string) {\n if (!this.modes.has(modeId)) {\n throw new Error(`[interaction] cannot set unknown mode '${modeId}' as default`);\n }\n this.dispatch(setDefaultMode(modeId));\n }\n\n private notifyHandlersActive(modeId: string) {\n this.alwaysGlobal.forEach((handler) => {\n handler.onHandlerActiveStart?.(modeId);\n });\n\n this.alwaysPage.forEach((handlerSet) => {\n handlerSet.forEach((handler) => {\n handler.onHandlerActiveStart?.(modeId);\n });\n });\n\n const mode = this.modes.get(modeId);\n if (!mode) return;\n\n const bucket = this.buckets.get(modeId);\n if (!bucket) return;\n\n // Notify global handlers if mode is global\n if (mode.scope === 'global') {\n bucket.global.forEach((handler) => {\n handler.onHandlerActiveStart?.(modeId);\n });\n }\n\n // Notify page handlers if mode is page\n if (mode.scope === 'page') {\n bucket.page.forEach((handlerSet, pageIndex) => {\n handlerSet.forEach((handler) => {\n handler.onHandlerActiveStart?.(modeId);\n });\n });\n }\n }\n\n private notifyHandlersInactive(modeId: string) {\n this.alwaysGlobal.forEach((handler) => {\n handler.onHandlerActiveEnd?.(modeId);\n });\n\n this.alwaysPage.forEach((handlerSet) => {\n handlerSet.forEach((handler) => {\n handler.onHandlerActiveEnd?.(modeId);\n });\n });\n\n const mode = this.modes.get(modeId);\n if (!mode) return;\n\n const bucket = this.buckets.get(modeId);\n if (!bucket) return;\n\n // Notify global handlers if mode is global\n if (mode.scope === 'global') {\n bucket.global.forEach((handler) => {\n handler.onHandlerActiveEnd?.(modeId);\n });\n }\n\n // Notify page handlers if mode is page\n if (mode.scope === 'page') {\n bucket.page.forEach((handlerSet, pageIndex) => {\n handlerSet.forEach((handler) => {\n handler.onHandlerActiveEnd?.(modeId);\n });\n });\n }\n }\n\n private registerMode(mode: InteractionMode) {\n this.modes.set(mode.id, mode);\n if (!this.buckets.has(mode.id)) {\n this.buckets.set(mode.id, { global: new Set(), page: new Map() });\n }\n }\n\n /** ---------- pointer-handler handling ------------ */\n private registerHandlers({ modeId, handlers, pageIndex }: RegisterHandlersOptions): () => void {\n const modeIds = Array.isArray(modeId) ? modeId : [modeId];\n const cleanupFunctions: (() => void)[] = [];\n\n for (const id of modeIds) {\n const bucket = this.buckets.get(id);\n if (!bucket) throw new Error(`unknown mode '${id}'`);\n\n if (pageIndex == null) {\n bucket.global.add(handlers);\n } else {\n const set = bucket.page.get(pageIndex) ?? new Set();\n set.add(handlers);\n bucket.page.set(pageIndex, set);\n }\n\n // Create cleanup function for this specific mode\n cleanupFunctions.push(() => {\n if (pageIndex == null) {\n bucket.global.delete(handlers);\n } else {\n const set = bucket.page.get(pageIndex);\n if (set) {\n set.delete(handlers);\n if (set.size === 0) {\n bucket.page.delete(pageIndex);\n }\n }\n }\n });\n }\n\n this.onHandlerChange$.emit({ ...this.state });\n\n // Return a cleanup function that removes handlers from all registered modes\n return () => {\n cleanupFunctions.forEach((cleanup) => cleanup());\n this.onHandlerChange$.emit({ ...this.state });\n };\n }\n\n public registerAlways({ scope, handlers }: RegisterAlwaysOptions): () => void {\n if (scope.type === 'global') {\n this.alwaysGlobal.add(handlers);\n this.onHandlerChange$.emit({ ...this.state });\n return () => this.alwaysGlobal.delete(handlers);\n }\n const set = this.alwaysPage.get(scope.pageIndex) ?? new Set();\n set.add(handlers);\n this.alwaysPage.set(scope.pageIndex, set);\n this.onHandlerChange$.emit({ ...this.state });\n return () => {\n set.delete(handlers);\n this.onHandlerChange$.emit({ ...this.state });\n };\n }\n\n /** Returns the *merged* handler set that should be active for the given\n * provider (`global` wrapper or a single page wrapper).\n * – `alwaysGlobal` / `alwaysPage` are **always** active.\n * – Handlers that belong to the current mode are added on top **iff**\n * the mode’s own scope matches the provider’s scope. */\n private getHandlersForScope(scope: InteractionScope): PointerEventHandlers | null {\n if (!this.state) return null;\n\n const mode = this.modes.get(this.state.activeMode);\n if (!mode) return null;\n\n const bucket = this.buckets.get(mode.id);\n if (!bucket) return null;\n\n /** helper – merge two handler sets into one object (or `null` if both are empty) */\n const mergeSets = (a: HandlerSet, b: HandlerSet) =>\n a.size || b.size ? mergeHandlers([...a, ...b]) : null;\n\n /* ───────────────────── GLOBAL PROVIDER ─────────────────────── */\n if (scope.type === 'global') {\n const modeSpecific =\n mode.scope === 'global' // only include mode handlers if the\n ? bucket.global // mode itself is global-scoped\n : new Set<PointerEventHandlers>();\n return mergeSets(this.alwaysGlobal, modeSpecific);\n }\n\n /* ─────────────────────── PAGE PROVIDER ──────────────────────── */\n const alwaysPageSet = this.alwaysPage.get(scope.pageIndex) ?? new Set<PointerEventHandlers>();\n const modePageSet =\n mode.scope === 'page'\n ? (bucket.page.get(scope.pageIndex) ?? new Set<PointerEventHandlers>())\n : new Set<PointerEventHandlers>(); // global-scoped mode → ignore page buckets\n\n return mergeSets(alwaysPageSet, modePageSet);\n }\n\n /** ---------- cursor handling --------------------- */\n private setCursor(token: string, cursor: string, priority = 0) {\n this.cursorClaims.set(token, { cursor, priority });\n this.emitCursor();\n }\n private removeCursor(token: string) {\n this.cursorClaims.delete(token);\n this.emitCursor();\n }\n\n private emitCursor() {\n /* pick highest priority claim, else mode baseline */\n const top = [...this.cursorClaims.values()].sort((a, b) => b.priority - a.priority)[0] ?? {\n cursor: this.modes.get(this.state.activeMode)?.cursor ?? 'auto',\n };\n\n if (top.cursor !== this.state.cursor) {\n this.dispatch(setCursor(top.cursor));\n this.onCursorChange$.emit(top.cursor);\n }\n }\n\n override onStoreUpdated(_: InteractionManagerState, newState: InteractionManagerState): void {\n this.onStateChange$.emit(newState);\n }\n\n private activeModeIsExclusive(): boolean {\n const mode = this.modes.get(this.state.activeMode);\n return !!mode?.exclusive;\n }\n\n private getActiveInteractionMode(): InteractionMode | null {\n return this.modes.get(this.state.activeMode) ?? null;\n }\n\n // keep emitter clean\n async destroy(): Promise<void> {\n this.onModeChange$.clear();\n this.onCursorChange$.clear();\n await super.destroy();\n }\n}\n","import { PointerEventHandlers } from './types';\n\nexport function mergeHandlers(list: PointerEventHandlers[]): PointerEventHandlers {\n const keys: (keyof PointerEventHandlers)[] = [\n 'onPointerDown',\n 'onPointerUp',\n 'onPointerMove',\n 'onPointerEnter',\n 'onPointerLeave',\n 'onPointerCancel',\n 'onMouseDown',\n 'onMouseUp',\n 'onMouseMove',\n 'onMouseEnter',\n 'onMouseLeave',\n 'onMouseCancel',\n 'onClick',\n 'onDoubleClick',\n ];\n const out: Partial<PointerEventHandlers> = {};\n for (const k of keys) {\n out[k] = (evt: any, nativeEvt: any, modeId: string) => {\n for (const h of list) h[k]?.(evt, nativeEvt, modeId);\n };\n }\n return out as PointerEventHandlers;\n}\n","import { PluginManifest } from '@embedpdf/core';\nimport { InteractionManagerPluginConfig } from './types';\n\nexport const INTERACTION_MANAGER_PLUGIN_ID = 'interaction-manager';\n\nexport const manifest: PluginManifest<InteractionManagerPluginConfig> = {\n id: INTERACTION_MANAGER_PLUGIN_ID,\n name: 'Interaction Manager Plugin',\n version: '1.0.0',\n provides: ['interaction-manager'],\n requires: [],\n optional: [],\n defaultConfig: {\n enabled: true,\n },\n};\n","import { Reducer } from '@embedpdf/core';\nimport {\n ACTIVATE_MODE,\n SET_DEFAULT_MODE,\n InteractionManagerAction,\n PAUSE_INTERACTION,\n RESUME_INTERACTION,\n SET_CURSOR,\n} from './actions';\nimport { InteractionManagerState } from './types';\n\nexport const initialState: InteractionManagerState = {\n activeMode: 'pointerMode',\n defaultMode: 'pointerMode',\n cursor: 'auto',\n paused: false,\n};\n\nexport const reducer: Reducer<InteractionManagerState, InteractionManagerAction> = (\n state,\n action,\n) => {\n switch (action.type) {\n case ACTIVATE_MODE:\n return {\n ...state,\n activeMode: action.payload.mode,\n };\n case SET_CURSOR:\n return {\n ...state,\n cursor: action.payload.cursor,\n };\n case PAUSE_INTERACTION:\n return {\n ...state,\n paused: true,\n };\n case RESUME_INTERACTION:\n return {\n ...state,\n paused: false,\n };\n case SET_DEFAULT_MODE:\n return {\n ...state,\n defaultMode: action.payload.mode,\n };\n default:\n return state;\n }\n};\n","import { PluginPackage } from '@embedpdf/core';\n\nimport { InteractionManagerPlugin } from './interaction-manager-plugin';\nimport { manifest, INTERACTION_MANAGER_PLUGIN_ID } from './manifest';\nimport { InteractionManagerPluginConfig, InteractionManagerState } from './types';\nimport { reducer, initialState } from './reducer';\nimport { InteractionManagerAction } from './actions';\n\nexport const InteractionManagerPluginPackage: PluginPackage<\n InteractionManagerPlugin,\n InteractionManagerPluginConfig,\n InteractionManagerState,\n InteractionManagerAction\n> = {\n manifest,\n create: (registry) => new InteractionManagerPlugin(INTERACTION_MANAGER_PLUGIN_ID, registry),\n reducer,\n initialState,\n};\n\nexport * from './interaction-manager-plugin';\nexport * from './types';\nexport * from './manifest';\nexport * from './reducer';\n"],"names":["ACTIVATE_MODE","PAUSE_INTERACTION","RESUME_INTERACTION","SET_CURSOR","SET_DEFAULT_MODE","INITIAL_MODE","_InteractionManagerPlugin","BasePlugin","constructor","id","registry","super","this","modes","Map","cursorClaims","buckets","alwaysGlobal","Set","alwaysPage","onModeChange$","createEmitter","onHandlerChange$","onCursorChange$","onStateChange$","createBehaviorEmitter","registerMode","scope","exclusive","cursor","setDefaultMode","activate","initialize","_","buildCapability","modeId","onModeChange","on","onCursorChange","onHandlerChange","onStateChange","getActiveMode","state","activeMode","getActiveInteractionMode","activateDefaultMode","defaultMode","mode","registerHandlers","options","registerAlways","setCursor","token","priority","removeCursor","getCurrentCursor","getHandlersForScope","activeModeIsExclusive","pause","dispatch","type","resume","isPaused","paused","getDefaultMode","has","Error","previousMode","clear","notifyHandlersInactive","payload","activateMode","emitCursor","notifyHandlersActive","emit","forEach","handler","_a","onHandlerActiveStart","call","handlerSet","get","bucket","global","page","pageIndex","onHandlerActiveEnd","set","handlers","modeIds","Array","isArray","cleanupFunctions","add","push","delete","size","cleanup","mergeSets","a","b","list","keys","out","k","evt","nativeEvt","h","mergeHandlers","modeSpecific","top","values","sort","onStoreUpdated","newState","destroy","InteractionManagerPlugin","INTERACTION_MANAGER_PLUGIN_ID","manifest","name","version","provides","requires","optional","defaultConfig","enabled","initialState","reducer","action","InteractionManagerPluginPackage","create"],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -3,6 +3,7 @@ const ACTIVATE_MODE = "INTERACTION/ACTIVATE_MODE";
|
|
|
3
3
|
const PAUSE_INTERACTION = "INTERACTION/PAUSE";
|
|
4
4
|
const RESUME_INTERACTION = "INTERACTION/RESUME";
|
|
5
5
|
const SET_CURSOR = "INTERACTION/SET_CURSOR";
|
|
6
|
+
const SET_DEFAULT_MODE = "INTERACTION/SET_DEFAULT_MODE";
|
|
6
7
|
const activateMode = (mode) => ({
|
|
7
8
|
type: ACTIVATE_MODE,
|
|
8
9
|
payload: { mode }
|
|
@@ -11,6 +12,10 @@ const setCursor = (cursor) => ({
|
|
|
11
12
|
type: SET_CURSOR,
|
|
12
13
|
payload: { cursor }
|
|
13
14
|
});
|
|
15
|
+
const setDefaultMode = (mode) => ({
|
|
16
|
+
type: SET_DEFAULT_MODE,
|
|
17
|
+
payload: { mode }
|
|
18
|
+
});
|
|
14
19
|
const pauseInteraction = () => ({
|
|
15
20
|
type: PAUSE_INTERACTION
|
|
16
21
|
});
|
|
@@ -25,6 +30,12 @@ function mergeHandlers(list) {
|
|
|
25
30
|
"onPointerEnter",
|
|
26
31
|
"onPointerLeave",
|
|
27
32
|
"onPointerCancel",
|
|
33
|
+
"onMouseDown",
|
|
34
|
+
"onMouseUp",
|
|
35
|
+
"onMouseMove",
|
|
36
|
+
"onMouseEnter",
|
|
37
|
+
"onMouseLeave",
|
|
38
|
+
"onMouseCancel",
|
|
28
39
|
"onClick",
|
|
29
40
|
"onDoubleClick"
|
|
30
41
|
];
|
|
@@ -37,6 +48,7 @@ function mergeHandlers(list) {
|
|
|
37
48
|
}
|
|
38
49
|
return out;
|
|
39
50
|
}
|
|
51
|
+
const INITIAL_MODE = "pointerMode";
|
|
40
52
|
const _InteractionManagerPlugin = class _InteractionManagerPlugin extends BasePlugin {
|
|
41
53
|
constructor(id, registry) {
|
|
42
54
|
super(id, registry);
|
|
@@ -50,11 +62,13 @@ const _InteractionManagerPlugin = class _InteractionManagerPlugin extends BasePl
|
|
|
50
62
|
this.onCursorChange$ = createEmitter();
|
|
51
63
|
this.onStateChange$ = createBehaviorEmitter();
|
|
52
64
|
this.registerMode({
|
|
53
|
-
id:
|
|
65
|
+
id: INITIAL_MODE,
|
|
54
66
|
scope: "page",
|
|
55
67
|
exclusive: false,
|
|
56
68
|
cursor: "auto"
|
|
57
69
|
});
|
|
70
|
+
this.setDefaultMode(INITIAL_MODE);
|
|
71
|
+
this.activate(INITIAL_MODE);
|
|
58
72
|
}
|
|
59
73
|
async initialize(_) {
|
|
60
74
|
}
|
|
@@ -67,7 +81,7 @@ const _InteractionManagerPlugin = class _InteractionManagerPlugin extends BasePl
|
|
|
67
81
|
onStateChange: this.onStateChange$.on,
|
|
68
82
|
getActiveMode: () => this.state.activeMode,
|
|
69
83
|
getActiveInteractionMode: () => this.getActiveInteractionMode(),
|
|
70
|
-
|
|
84
|
+
activateDefaultMode: () => this.activate(this.state.defaultMode),
|
|
71
85
|
registerMode: (mode) => this.registerMode(mode),
|
|
72
86
|
registerHandlers: (options) => this.registerHandlers(options),
|
|
73
87
|
registerAlways: (options) => this.registerAlways(options),
|
|
@@ -78,7 +92,9 @@ const _InteractionManagerPlugin = class _InteractionManagerPlugin extends BasePl
|
|
|
78
92
|
activeModeIsExclusive: () => this.activeModeIsExclusive(),
|
|
79
93
|
pause: () => this.dispatch(pauseInteraction()),
|
|
80
94
|
resume: () => this.dispatch(resumeInteraction()),
|
|
81
|
-
isPaused: () => this.state.paused
|
|
95
|
+
isPaused: () => this.state.paused,
|
|
96
|
+
setDefaultMode: (id) => this.setDefaultMode(id),
|
|
97
|
+
getDefaultMode: () => this.state.defaultMode
|
|
82
98
|
};
|
|
83
99
|
}
|
|
84
100
|
activate(mode) {
|
|
@@ -94,6 +110,12 @@ const _InteractionManagerPlugin = class _InteractionManagerPlugin extends BasePl
|
|
|
94
110
|
this.notifyHandlersActive(mode);
|
|
95
111
|
this.onModeChange$.emit({ ...this.state, activeMode: mode });
|
|
96
112
|
}
|
|
113
|
+
setDefaultMode(modeId) {
|
|
114
|
+
if (!this.modes.has(modeId)) {
|
|
115
|
+
throw new Error(`[interaction] cannot set unknown mode '${modeId}' as default`);
|
|
116
|
+
}
|
|
117
|
+
this.dispatch(setDefaultMode(modeId));
|
|
118
|
+
}
|
|
97
119
|
notifyHandlersActive(modeId) {
|
|
98
120
|
this.alwaysGlobal.forEach((handler) => {
|
|
99
121
|
var _a;
|
|
@@ -280,7 +302,8 @@ const manifest = {
|
|
|
280
302
|
}
|
|
281
303
|
};
|
|
282
304
|
const initialState = {
|
|
283
|
-
activeMode: "
|
|
305
|
+
activeMode: "pointerMode",
|
|
306
|
+
defaultMode: "pointerMode",
|
|
284
307
|
cursor: "auto",
|
|
285
308
|
paused: false
|
|
286
309
|
};
|
|
@@ -306,6 +329,11 @@ const reducer = (state, action) => {
|
|
|
306
329
|
...state,
|
|
307
330
|
paused: false
|
|
308
331
|
};
|
|
332
|
+
case SET_DEFAULT_MODE:
|
|
333
|
+
return {
|
|
334
|
+
...state,
|
|
335
|
+
defaultMode: action.payload.mode
|
|
336
|
+
};
|
|
309
337
|
default:
|
|
310
338
|
return state;
|
|
311
339
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/lib/actions.ts","../src/lib/helper.ts","../src/lib/interaction-manager-plugin.ts","../src/lib/manifest.ts","../src/lib/reducer.ts","../src/lib/index.ts"],"sourcesContent":["import { Action } from '@embedpdf/core';\n\nexport const ACTIVATE_MODE = 'INTERACTION/ACTIVATE_MODE';\nexport const PAUSE_INTERACTION = 'INTERACTION/PAUSE';\nexport const RESUME_INTERACTION = 'INTERACTION/RESUME';\nexport const SET_CURSOR = 'INTERACTION/SET_CURSOR';\n\nexport interface ActivateModeAction extends Action {\n type: typeof ACTIVATE_MODE;\n payload: { mode: string };\n}\n\nexport interface PauseInteractionAction extends Action {\n type: typeof PAUSE_INTERACTION;\n}\n\nexport interface ResumeInteractionAction extends Action {\n type: typeof RESUME_INTERACTION;\n}\n\nexport interface SetCursorAction extends Action {\n type: typeof SET_CURSOR;\n payload: { cursor: string };\n}\n\nexport const activateMode = (mode: string): ActivateModeAction => ({\n type: ACTIVATE_MODE,\n payload: { mode },\n});\n\nexport const setCursor = (cursor: string): SetCursorAction => ({\n type: SET_CURSOR,\n payload: { cursor },\n});\n\nexport const pauseInteraction = (): PauseInteractionAction => ({\n type: PAUSE_INTERACTION,\n});\n\nexport const resumeInteraction = (): ResumeInteractionAction => ({\n type: RESUME_INTERACTION,\n});\n\nexport type InteractionManagerAction =\n | ActivateModeAction\n | PauseInteractionAction\n | ResumeInteractionAction\n | SetCursorAction;\n","import { PointerEventHandlers } from './types';\n\nexport function mergeHandlers(list: PointerEventHandlers[]): PointerEventHandlers {\n const keys: (keyof PointerEventHandlers)[] = [\n 'onPointerDown',\n 'onPointerUp',\n 'onPointerMove',\n 'onPointerEnter',\n 'onPointerLeave',\n 'onPointerCancel',\n 'onClick',\n 'onDoubleClick',\n ];\n const out: Partial<PointerEventHandlers> = {};\n for (const k of keys) {\n out[k] = (evt: any, nativeEvt: any, modeId: string) => {\n for (const h of list) h[k]?.(evt, nativeEvt, modeId);\n };\n }\n return out as PointerEventHandlers;\n}\n","import { BasePlugin, createBehaviorEmitter, createEmitter, PluginRegistry } from '@embedpdf/core';\n\nimport {\n InteractionManagerCapability,\n InteractionManagerPluginConfig,\n InteractionManagerState,\n InteractionMode,\n InteractionScope,\n PointerEventHandlers,\n PointerEventHandlersWithLifecycle,\n RegisterAlwaysOptions,\n RegisterHandlersOptions,\n} from './types';\nimport { activateMode, pauseInteraction, resumeInteraction, setCursor } from './actions';\nimport { mergeHandlers } from './helper';\n\ninterface CursorClaim {\n cursor: string;\n priority: number;\n}\n\ntype HandlerSet = Set<PointerEventHandlersWithLifecycle>;\ntype PageHandlerMap = Map<number /*pageIdx*/, HandlerSet>;\n\ninterface ModeBuckets {\n /** handlers that listen on the global wrapper (only once per viewer) */\n global: HandlerSet;\n /** handlers that listen on a *specific* page wrapper */\n page: PageHandlerMap;\n}\n\nexport class InteractionManagerPlugin extends BasePlugin<\n InteractionManagerPluginConfig,\n InteractionManagerCapability,\n InteractionManagerState\n> {\n static readonly id = 'interaction-manager' as const;\n\n private modes = new Map<string, InteractionMode>();\n private cursorClaims = new Map<string, CursorClaim>();\n private buckets = new Map<string, ModeBuckets>();\n\n private alwaysGlobal = new Set<PointerEventHandlersWithLifecycle>();\n private alwaysPage = new Map<number, Set<PointerEventHandlersWithLifecycle>>();\n\n private readonly onModeChange$ = createEmitter<InteractionManagerState>();\n private readonly onHandlerChange$ = createEmitter<InteractionManagerState>();\n private readonly onCursorChange$ = createEmitter<string>();\n private readonly onStateChange$ = createBehaviorEmitter<InteractionManagerState>();\n\n constructor(id: string, registry: PluginRegistry) {\n super(id, registry);\n\n this.registerMode({\n id: 'default',\n scope: 'page',\n exclusive: false,\n cursor: 'auto',\n });\n }\n\n async initialize(_: InteractionManagerPluginConfig): Promise<void> {}\n\n protected buildCapability(): InteractionManagerCapability {\n return {\n activate: (modeId: string) => this.activate(modeId),\n onModeChange: this.onModeChange$.on,\n onCursorChange: this.onCursorChange$.on,\n onHandlerChange: this.onHandlerChange$.on,\n onStateChange: this.onStateChange$.on,\n getActiveMode: () => this.state.activeMode,\n getActiveInteractionMode: () => this.getActiveInteractionMode(),\n finish: () => this.activate('default'),\n registerMode: (mode: InteractionMode) => this.registerMode(mode),\n registerHandlers: (options: RegisterHandlersOptions) => this.registerHandlers(options),\n registerAlways: (options: RegisterAlwaysOptions) => this.registerAlways(options),\n setCursor: (token: string, cursor: string, priority = 0) =>\n this.setCursor(token, cursor, priority),\n removeCursor: (token: string) => this.removeCursor(token),\n getCurrentCursor: () => this.state.cursor,\n getHandlersForScope: (scope: InteractionScope) => this.getHandlersForScope(scope),\n activeModeIsExclusive: () => this.activeModeIsExclusive(),\n pause: () => this.dispatch(pauseInteraction()),\n resume: () => this.dispatch(resumeInteraction()),\n isPaused: () => this.state.paused,\n };\n }\n\n private activate(mode: string) {\n if (!this.modes.has(mode)) {\n throw new Error(`[interaction] unknown mode '${mode}'`);\n }\n if (mode === this.state.activeMode) return;\n\n const previousMode = this.state.activeMode;\n this.cursorClaims.clear(); // prevent cursor leaks\n\n this.notifyHandlersInactive(previousMode);\n\n this.dispatch(activateMode(mode));\n this.emitCursor();\n\n // Call lifecycle hooks for handlers going active\n this.notifyHandlersActive(mode);\n\n this.onModeChange$.emit({ ...this.state, activeMode: mode });\n }\n\n private notifyHandlersActive(modeId: string) {\n this.alwaysGlobal.forEach((handler) => {\n handler.onHandlerActiveStart?.(modeId);\n });\n\n this.alwaysPage.forEach((handlerSet) => {\n handlerSet.forEach((handler) => {\n handler.onHandlerActiveStart?.(modeId);\n });\n });\n\n const mode = this.modes.get(modeId);\n if (!mode) return;\n\n const bucket = this.buckets.get(modeId);\n if (!bucket) return;\n\n // Notify global handlers if mode is global\n if (mode.scope === 'global') {\n bucket.global.forEach((handler) => {\n handler.onHandlerActiveStart?.(modeId);\n });\n }\n\n // Notify page handlers if mode is page\n if (mode.scope === 'page') {\n bucket.page.forEach((handlerSet, pageIndex) => {\n handlerSet.forEach((handler) => {\n handler.onHandlerActiveStart?.(modeId);\n });\n });\n }\n }\n\n private notifyHandlersInactive(modeId: string) {\n this.alwaysGlobal.forEach((handler) => {\n handler.onHandlerActiveEnd?.(modeId);\n });\n\n this.alwaysPage.forEach((handlerSet) => {\n handlerSet.forEach((handler) => {\n handler.onHandlerActiveEnd?.(modeId);\n });\n });\n\n const mode = this.modes.get(modeId);\n if (!mode) return;\n\n const bucket = this.buckets.get(modeId);\n if (!bucket) return;\n\n // Notify global handlers if mode is global\n if (mode.scope === 'global') {\n bucket.global.forEach((handler) => {\n handler.onHandlerActiveEnd?.(modeId);\n });\n }\n\n // Notify page handlers if mode is page\n if (mode.scope === 'page') {\n bucket.page.forEach((handlerSet, pageIndex) => {\n handlerSet.forEach((handler) => {\n handler.onHandlerActiveEnd?.(modeId);\n });\n });\n }\n }\n\n private registerMode(mode: InteractionMode) {\n this.modes.set(mode.id, mode);\n if (!this.buckets.has(mode.id)) {\n this.buckets.set(mode.id, { global: new Set(), page: new Map() });\n }\n }\n\n /** ---------- pointer-handler handling ------------ */\n private registerHandlers({ modeId, handlers, pageIndex }: RegisterHandlersOptions): () => void {\n const modeIds = Array.isArray(modeId) ? modeId : [modeId];\n const cleanupFunctions: (() => void)[] = [];\n\n for (const id of modeIds) {\n const bucket = this.buckets.get(id);\n if (!bucket) throw new Error(`unknown mode '${id}'`);\n\n if (pageIndex == null) {\n bucket.global.add(handlers);\n } else {\n const set = bucket.page.get(pageIndex) ?? new Set();\n set.add(handlers);\n bucket.page.set(pageIndex, set);\n }\n\n // Create cleanup function for this specific mode\n cleanupFunctions.push(() => {\n if (pageIndex == null) {\n bucket.global.delete(handlers);\n } else {\n const set = bucket.page.get(pageIndex);\n if (set) {\n set.delete(handlers);\n if (set.size === 0) {\n bucket.page.delete(pageIndex);\n }\n }\n }\n });\n }\n\n this.onHandlerChange$.emit({ ...this.state });\n\n // Return a cleanup function that removes handlers from all registered modes\n return () => {\n cleanupFunctions.forEach((cleanup) => cleanup());\n this.onHandlerChange$.emit({ ...this.state });\n };\n }\n\n public registerAlways({ scope, handlers }: RegisterAlwaysOptions): () => void {\n if (scope.type === 'global') {\n this.alwaysGlobal.add(handlers);\n this.onHandlerChange$.emit({ ...this.state });\n return () => this.alwaysGlobal.delete(handlers);\n }\n const set = this.alwaysPage.get(scope.pageIndex) ?? new Set();\n set.add(handlers);\n this.alwaysPage.set(scope.pageIndex, set);\n this.onHandlerChange$.emit({ ...this.state });\n return () => {\n set.delete(handlers);\n this.onHandlerChange$.emit({ ...this.state });\n };\n }\n\n /** Returns the *merged* handler set that should be active for the given\n * provider (`global` wrapper or a single page wrapper).\n * – `alwaysGlobal` / `alwaysPage` are **always** active.\n * – Handlers that belong to the current mode are added on top **iff**\n * the mode’s own scope matches the provider’s scope. */\n private getHandlersForScope(scope: InteractionScope): PointerEventHandlers | null {\n if (!this.state) return null;\n\n const mode = this.modes.get(this.state.activeMode);\n if (!mode) return null;\n\n const bucket = this.buckets.get(mode.id);\n if (!bucket) return null;\n\n /** helper – merge two handler sets into one object (or `null` if both are empty) */\n const mergeSets = (a: HandlerSet, b: HandlerSet) =>\n a.size || b.size ? mergeHandlers([...a, ...b]) : null;\n\n /* ───────────────────── GLOBAL PROVIDER ─────────────────────── */\n if (scope.type === 'global') {\n const modeSpecific =\n mode.scope === 'global' // only include mode handlers if the\n ? bucket.global // mode itself is global-scoped\n : new Set<PointerEventHandlers>();\n return mergeSets(this.alwaysGlobal, modeSpecific);\n }\n\n /* ─────────────────────── PAGE PROVIDER ──────────────────────── */\n const alwaysPageSet = this.alwaysPage.get(scope.pageIndex) ?? new Set<PointerEventHandlers>();\n const modePageSet =\n mode.scope === 'page'\n ? (bucket.page.get(scope.pageIndex) ?? new Set<PointerEventHandlers>())\n : new Set<PointerEventHandlers>(); // global-scoped mode → ignore page buckets\n\n return mergeSets(alwaysPageSet, modePageSet);\n }\n\n /** ---------- cursor handling --------------------- */\n private setCursor(token: string, cursor: string, priority = 0) {\n this.cursorClaims.set(token, { cursor, priority });\n this.emitCursor();\n }\n private removeCursor(token: string) {\n this.cursorClaims.delete(token);\n this.emitCursor();\n }\n\n private emitCursor() {\n /* pick highest priority claim, else mode baseline */\n const top = [...this.cursorClaims.values()].sort((a, b) => b.priority - a.priority)[0] ?? {\n cursor: this.modes.get(this.state.activeMode)?.cursor ?? 'auto',\n };\n\n if (top.cursor !== this.state.cursor) {\n this.dispatch(setCursor(top.cursor));\n this.onCursorChange$.emit(top.cursor);\n }\n }\n\n override onStoreUpdated(_: InteractionManagerState, newState: InteractionManagerState): void {\n this.onStateChange$.emit(newState);\n }\n\n private activeModeIsExclusive(): boolean {\n const mode = this.modes.get(this.state.activeMode);\n return !!mode?.exclusive;\n }\n\n private getActiveInteractionMode(): InteractionMode | null {\n return this.modes.get(this.state.activeMode) ?? null;\n }\n\n // keep emitter clean\n async destroy(): Promise<void> {\n this.onModeChange$.clear();\n this.onCursorChange$.clear();\n await super.destroy();\n }\n}\n","import { PluginManifest } from '@embedpdf/core';\nimport { InteractionManagerPluginConfig } from './types';\n\nexport const INTERACTION_MANAGER_PLUGIN_ID = 'interaction-manager';\n\nexport const manifest: PluginManifest<InteractionManagerPluginConfig> = {\n id: INTERACTION_MANAGER_PLUGIN_ID,\n name: 'Interaction Manager Plugin',\n version: '1.0.0',\n provides: ['interaction-manager'],\n requires: [],\n optional: [],\n defaultConfig: {\n enabled: true,\n },\n};\n","import { Reducer } from '@embedpdf/core';\nimport {\n ACTIVATE_MODE,\n InteractionManagerAction,\n PAUSE_INTERACTION,\n RESUME_INTERACTION,\n SET_CURSOR,\n} from './actions';\nimport { InteractionManagerState } from './types';\n\nexport const initialState: InteractionManagerState = {\n activeMode: 'default',\n cursor: 'auto',\n paused: false,\n};\n\nexport const reducer: Reducer<InteractionManagerState, InteractionManagerAction> = (\n state,\n action,\n) => {\n switch (action.type) {\n case ACTIVATE_MODE:\n return {\n ...state,\n activeMode: action.payload.mode,\n };\n case SET_CURSOR:\n return {\n ...state,\n cursor: action.payload.cursor,\n };\n case PAUSE_INTERACTION:\n return {\n ...state,\n paused: true,\n };\n case RESUME_INTERACTION:\n return {\n ...state,\n paused: false,\n };\n default:\n return state;\n }\n};\n","import { PluginPackage } from '@embedpdf/core';\n\nimport { InteractionManagerPlugin } from './interaction-manager-plugin';\nimport { manifest, INTERACTION_MANAGER_PLUGIN_ID } from './manifest';\nimport { InteractionManagerPluginConfig, InteractionManagerState } from './types';\nimport { reducer, initialState } from './reducer';\nimport { InteractionManagerAction } from './actions';\n\nexport const InteractionManagerPluginPackage: PluginPackage<\n InteractionManagerPlugin,\n InteractionManagerPluginConfig,\n InteractionManagerState,\n InteractionManagerAction\n> = {\n manifest,\n create: (registry) => new InteractionManagerPlugin(INTERACTION_MANAGER_PLUGIN_ID, registry),\n reducer,\n initialState,\n};\n\nexport * from './interaction-manager-plugin';\nexport * from './types';\nexport * from './manifest';\nexport * from './reducer';\n"],"names":[],"mappings":";AAEO,MAAM,gBAAgB;AACtB,MAAM,oBAAoB;AAC1B,MAAM,qBAAqB;AAC3B,MAAM,aAAa;AAoBb,MAAA,eAAe,CAAC,UAAsC;AAAA,EACjE,MAAM;AAAA,EACN,SAAS,EAAE,KAAK;AAClB;AAEa,MAAA,YAAY,CAAC,YAAqC;AAAA,EAC7D,MAAM;AAAA,EACN,SAAS,EAAE,OAAO;AACpB;AAEO,MAAM,mBAAmB,OAA+B;AAAA,EAC7D,MAAM;AACR;AAEO,MAAM,oBAAoB,OAAgC;AAAA,EAC/D,MAAM;AACR;ACvCO,SAAS,cAAc,MAAoD;AAChF,QAAM,OAAuC;AAAA,IAC3C;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,QAAM,MAAqC,CAAC;AAC5C,aAAW,KAAK,MAAM;AACpB,QAAI,CAAC,IAAI,CAAC,KAAU,WAAgB,WAAmB;;AACrD,iBAAW,KAAK,KAAM,SAAE,OAAF,2BAAO,KAAK,WAAW;AAAA,IAC/C;AAAA,EAAA;AAEK,SAAA;AACT;ACWO,MAAM,4BAAN,MAAM,kCAAiC,WAI5C;AAAA,EAeA,YAAY,IAAY,UAA0B;AAChD,UAAM,IAAI,QAAQ;AAbZ,SAAA,4BAAY,IAA6B;AACzC,SAAA,mCAAmB,IAAyB;AAC5C,SAAA,8BAAc,IAAyB;AAEvC,SAAA,mCAAmB,IAAuC;AAC1D,SAAA,iCAAiB,IAAoD;AAE7E,SAAiB,gBAAgB,cAAuC;AACxE,SAAiB,mBAAmB,cAAuC;AAC3E,SAAiB,kBAAkB,cAAsB;AACzD,SAAiB,iBAAiB,sBAA+C;AAK/E,SAAK,aAAa;AAAA,MAChB,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,WAAW;AAAA,MACX,QAAQ;AAAA,IAAA,CACT;AAAA,EAAA;AAAA,EAGH,MAAM,WAAW,GAAkD;AAAA,EAAA;AAAA,EAEzD,kBAAgD;AACjD,WAAA;AAAA,MACL,UAAU,CAAC,WAAmB,KAAK,SAAS,MAAM;AAAA,MAClD,cAAc,KAAK,cAAc;AAAA,MACjC,gBAAgB,KAAK,gBAAgB;AAAA,MACrC,iBAAiB,KAAK,iBAAiB;AAAA,MACvC,eAAe,KAAK,eAAe;AAAA,MACnC,eAAe,MAAM,KAAK,MAAM;AAAA,MAChC,0BAA0B,MAAM,KAAK,yBAAyB;AAAA,MAC9D,QAAQ,MAAM,KAAK,SAAS,SAAS;AAAA,MACrC,cAAc,CAAC,SAA0B,KAAK,aAAa,IAAI;AAAA,MAC/D,kBAAkB,CAAC,YAAqC,KAAK,iBAAiB,OAAO;AAAA,MACrF,gBAAgB,CAAC,YAAmC,KAAK,eAAe,OAAO;AAAA,MAC/E,WAAW,CAAC,OAAe,QAAgB,WAAW,MACpD,KAAK,UAAU,OAAO,QAAQ,QAAQ;AAAA,MACxC,cAAc,CAAC,UAAkB,KAAK,aAAa,KAAK;AAAA,MACxD,kBAAkB,MAAM,KAAK,MAAM;AAAA,MACnC,qBAAqB,CAAC,UAA4B,KAAK,oBAAoB,KAAK;AAAA,MAChF,uBAAuB,MAAM,KAAK,sBAAsB;AAAA,MACxD,OAAO,MAAM,KAAK,SAAS,kBAAkB;AAAA,MAC7C,QAAQ,MAAM,KAAK,SAAS,mBAAmB;AAAA,MAC/C,UAAU,MAAM,KAAK,MAAM;AAAA,IAC7B;AAAA,EAAA;AAAA,EAGM,SAAS,MAAc;AAC7B,QAAI,CAAC,KAAK,MAAM,IAAI,IAAI,GAAG;AACzB,YAAM,IAAI,MAAM,+BAA+B,IAAI,GAAG;AAAA,IAAA;AAEpD,QAAA,SAAS,KAAK,MAAM,WAAY;AAE9B,UAAA,eAAe,KAAK,MAAM;AAChC,SAAK,aAAa,MAAM;AAExB,SAAK,uBAAuB,YAAY;AAEnC,SAAA,SAAS,aAAa,IAAI,CAAC;AAChC,SAAK,WAAW;AAGhB,SAAK,qBAAqB,IAAI;AAEzB,SAAA,cAAc,KAAK,EAAE,GAAG,KAAK,OAAO,YAAY,MAAM;AAAA,EAAA;AAAA,EAGrD,qBAAqB,QAAgB;AACtC,SAAA,aAAa,QAAQ,CAAC,YAAY;;AACrC,oBAAQ,yBAAR,iCAA+B;AAAA,IAAM,CACtC;AAEI,SAAA,WAAW,QAAQ,CAAC,eAAe;AAC3B,iBAAA,QAAQ,CAAC,YAAY;;AAC9B,sBAAQ,yBAAR,iCAA+B;AAAA,MAAM,CACtC;AAAA,IAAA,CACF;AAED,UAAM,OAAO,KAAK,MAAM,IAAI,MAAM;AAClC,QAAI,CAAC,KAAM;AAEX,UAAM,SAAS,KAAK,QAAQ,IAAI,MAAM;AACtC,QAAI,CAAC,OAAQ;AAGT,QAAA,KAAK,UAAU,UAAU;AACpB,aAAA,OAAO,QAAQ,CAAC,YAAY;;AACjC,sBAAQ,yBAAR,iCAA+B;AAAA,MAAM,CACtC;AAAA,IAAA;AAIC,QAAA,KAAK,UAAU,QAAQ;AACzB,aAAO,KAAK,QAAQ,CAAC,YAAY,cAAc;AAClC,mBAAA,QAAQ,CAAC,YAAY;;AAC9B,wBAAQ,yBAAR,iCAA+B;AAAA,QAAM,CACtC;AAAA,MAAA,CACF;AAAA,IAAA;AAAA,EACH;AAAA,EAGM,uBAAuB,QAAgB;AACxC,SAAA,aAAa,QAAQ,CAAC,YAAY;;AACrC,oBAAQ,uBAAR,iCAA6B;AAAA,IAAM,CACpC;AAEI,SAAA,WAAW,QAAQ,CAAC,eAAe;AAC3B,iBAAA,QAAQ,CAAC,YAAY;;AAC9B,sBAAQ,uBAAR,iCAA6B;AAAA,MAAM,CACpC;AAAA,IAAA,CACF;AAED,UAAM,OAAO,KAAK,MAAM,IAAI,MAAM;AAClC,QAAI,CAAC,KAAM;AAEX,UAAM,SAAS,KAAK,QAAQ,IAAI,MAAM;AACtC,QAAI,CAAC,OAAQ;AAGT,QAAA,KAAK,UAAU,UAAU;AACpB,aAAA,OAAO,QAAQ,CAAC,YAAY;;AACjC,sBAAQ,uBAAR,iCAA6B;AAAA,MAAM,CACpC;AAAA,IAAA;AAIC,QAAA,KAAK,UAAU,QAAQ;AACzB,aAAO,KAAK,QAAQ,CAAC,YAAY,cAAc;AAClC,mBAAA,QAAQ,CAAC,YAAY;;AAC9B,wBAAQ,uBAAR,iCAA6B;AAAA,QAAM,CACpC;AAAA,MAAA,CACF;AAAA,IAAA;AAAA,EACH;AAAA,EAGM,aAAa,MAAuB;AAC1C,SAAK,MAAM,IAAI,KAAK,IAAI,IAAI;AAC5B,QAAI,CAAC,KAAK,QAAQ,IAAI,KAAK,EAAE,GAAG;AAC9B,WAAK,QAAQ,IAAI,KAAK,IAAI,EAAE,QAAY,oBAAA,IAAA,GAAO,MAAU,oBAAA,OAAO;AAAA,IAAA;AAAA,EAClE;AAAA;AAAA,EAIM,iBAAiB,EAAE,QAAQ,UAAU,aAAkD;AAC7F,UAAM,UAAU,MAAM,QAAQ,MAAM,IAAI,SAAS,CAAC,MAAM;AACxD,UAAM,mBAAmC,CAAC;AAE1C,eAAW,MAAM,SAAS;AACxB,YAAM,SAAS,KAAK,QAAQ,IAAI,EAAE;AAClC,UAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,iBAAiB,EAAE,GAAG;AAEnD,UAAI,aAAa,MAAM;AACd,eAAA,OAAO,IAAI,QAAQ;AAAA,MAAA,OACrB;AACL,cAAM,MAAM,OAAO,KAAK,IAAI,SAAS,yBAAS,IAAI;AAClD,YAAI,IAAI,QAAQ;AACT,eAAA,KAAK,IAAI,WAAW,GAAG;AAAA,MAAA;AAIhC,uBAAiB,KAAK,MAAM;AAC1B,YAAI,aAAa,MAAM;AACd,iBAAA,OAAO,OAAO,QAAQ;AAAA,QAAA,OACxB;AACL,gBAAM,MAAM,OAAO,KAAK,IAAI,SAAS;AACrC,cAAI,KAAK;AACP,gBAAI,OAAO,QAAQ;AACf,gBAAA,IAAI,SAAS,GAAG;AACX,qBAAA,KAAK,OAAO,SAAS;AAAA,YAAA;AAAA,UAC9B;AAAA,QACF;AAAA,MACF,CACD;AAAA,IAAA;AAGH,SAAK,iBAAiB,KAAK,EAAE,GAAG,KAAK,OAAO;AAG5C,WAAO,MAAM;AACX,uBAAiB,QAAQ,CAAC,YAAY,QAAA,CAAS;AAC/C,WAAK,iBAAiB,KAAK,EAAE,GAAG,KAAK,OAAO;AAAA,IAC9C;AAAA,EAAA;AAAA,EAGK,eAAe,EAAE,OAAO,YAA+C;AACxE,QAAA,MAAM,SAAS,UAAU;AACtB,WAAA,aAAa,IAAI,QAAQ;AAC9B,WAAK,iBAAiB,KAAK,EAAE,GAAG,KAAK,OAAO;AAC5C,aAAO,MAAM,KAAK,aAAa,OAAO,QAAQ;AAAA,IAAA;AAE1C,UAAA,MAAM,KAAK,WAAW,IAAI,MAAM,SAAS,yBAAS,IAAI;AAC5D,QAAI,IAAI,QAAQ;AAChB,SAAK,WAAW,IAAI,MAAM,WAAW,GAAG;AACxC,SAAK,iBAAiB,KAAK,EAAE,GAAG,KAAK,OAAO;AAC5C,WAAO,MAAM;AACX,UAAI,OAAO,QAAQ;AACnB,WAAK,iBAAiB,KAAK,EAAE,GAAG,KAAK,OAAO;AAAA,IAC9C;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQM,oBAAoB,OAAsD;AAC5E,QAAA,CAAC,KAAK,MAAc,QAAA;AAExB,UAAM,OAAO,KAAK,MAAM,IAAI,KAAK,MAAM,UAAU;AAC7C,QAAA,CAAC,KAAa,QAAA;AAElB,UAAM,SAAS,KAAK,QAAQ,IAAI,KAAK,EAAE;AACnC,QAAA,CAAC,OAAe,QAAA;AAGpB,UAAM,YAAY,CAAC,GAAe,MAChC,EAAE,QAAQ,EAAE,OAAO,cAAc,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC,IAAI;AAG/C,QAAA,MAAM,SAAS,UAAU;AAC3B,YAAM,eACJ,KAAK,UAAU,WACX,OAAO,6BACH,IAA0B;AAC7B,aAAA,UAAU,KAAK,cAAc,YAAY;AAAA,IAAA;AAI5C,UAAA,gBAAgB,KAAK,WAAW,IAAI,MAAM,SAAS,yBAAS,IAA0B;AAC5F,UAAM,cACJ,KAAK,UAAU,SACV,OAAO,KAAK,IAAI,MAAM,SAAS,KAAK,oBAAI,IAA0B,wBAC/D,IAA0B;AAE7B,WAAA,UAAU,eAAe,WAAW;AAAA,EAAA;AAAA;AAAA,EAIrC,UAAU,OAAe,QAAgB,WAAW,GAAG;AAC7D,SAAK,aAAa,IAAI,OAAO,EAAE,QAAQ,UAAU;AACjD,SAAK,WAAW;AAAA,EAAA;AAAA,EAEV,aAAa,OAAe;AAC7B,SAAA,aAAa,OAAO,KAAK;AAC9B,SAAK,WAAW;AAAA,EAAA;AAAA,EAGV,aAAa;;AAEnB,UAAM,MAAM,CAAC,GAAG,KAAK,aAAa,OAAQ,CAAA,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC,KAAK;AAAA,MACxF,UAAQ,UAAK,MAAM,IAAI,KAAK,MAAM,UAAU,MAApC,mBAAuC,WAAU;AAAA,IAC3D;AAEA,QAAI,IAAI,WAAW,KAAK,MAAM,QAAQ;AACpC,WAAK,SAAS,UAAU,IAAI,MAAM,CAAC;AAC9B,WAAA,gBAAgB,KAAK,IAAI,MAAM;AAAA,IAAA;AAAA,EACtC;AAAA,EAGO,eAAe,GAA4B,UAAyC;AACtF,SAAA,eAAe,KAAK,QAAQ;AAAA,EAAA;AAAA,EAG3B,wBAAiC;AACvC,UAAM,OAAO,KAAK,MAAM,IAAI,KAAK,MAAM,UAAU;AAC1C,WAAA,CAAC,EAAC,6BAAM;AAAA,EAAA;AAAA,EAGT,2BAAmD;AACzD,WAAO,KAAK,MAAM,IAAI,KAAK,MAAM,UAAU,KAAK;AAAA,EAAA;AAAA;AAAA,EAIlD,MAAM,UAAyB;AAC7B,SAAK,cAAc,MAAM;AACzB,SAAK,gBAAgB,MAAM;AAC3B,UAAM,MAAM,QAAQ;AAAA,EAAA;AAExB;AA3RE,0BAAgB,KAAK;AALhB,IAAM,2BAAN;AC5BA,MAAM,gCAAgC;AAEtC,MAAM,WAA2D;AAAA,EACtE,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,SAAS;AAAA,EACT,UAAU,CAAC,qBAAqB;AAAA,EAChC,UAAU,CAAC;AAAA,EACX,UAAU,CAAC;AAAA,EACX,eAAe;AAAA,IACb,SAAS;AAAA,EAAA;AAEb;ACLO,MAAM,eAAwC;AAAA,EACnD,YAAY;AAAA,EACZ,QAAQ;AAAA,EACR,QAAQ;AACV;AAEa,MAAA,UAAsE,CACjF,OACA,WACG;AACH,UAAQ,OAAO,MAAM;AAAA,IACnB,KAAK;AACI,aAAA;AAAA,QACL,GAAG;AAAA,QACH,YAAY,OAAO,QAAQ;AAAA,MAC7B;AAAA,IACF,KAAK;AACI,aAAA;AAAA,QACL,GAAG;AAAA,QACH,QAAQ,OAAO,QAAQ;AAAA,MACzB;AAAA,IACF,KAAK;AACI,aAAA;AAAA,QACL,GAAG;AAAA,QACH,QAAQ;AAAA,MACV;AAAA,IACF,KAAK;AACI,aAAA;AAAA,QACL,GAAG;AAAA,QACH,QAAQ;AAAA,MACV;AAAA,IACF;AACS,aAAA;AAAA,EAAA;AAEb;ACpCO,MAAM,kCAKT;AAAA,EACF;AAAA,EACA,QAAQ,CAAC,aAAa,IAAI,yBAAyB,+BAA+B,QAAQ;AAAA,EAC1F;AAAA,EACA;AACF;"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/lib/actions.ts","../src/lib/helper.ts","../src/lib/interaction-manager-plugin.ts","../src/lib/manifest.ts","../src/lib/reducer.ts","../src/lib/index.ts"],"sourcesContent":["import { Action } from '@embedpdf/core';\n\nexport const ACTIVATE_MODE = 'INTERACTION/ACTIVATE_MODE';\nexport const PAUSE_INTERACTION = 'INTERACTION/PAUSE';\nexport const RESUME_INTERACTION = 'INTERACTION/RESUME';\nexport const SET_CURSOR = 'INTERACTION/SET_CURSOR';\nexport const SET_DEFAULT_MODE = 'INTERACTION/SET_DEFAULT_MODE';\n\nexport interface ActivateModeAction extends Action {\n type: typeof ACTIVATE_MODE;\n payload: { mode: string };\n}\n\nexport interface PauseInteractionAction extends Action {\n type: typeof PAUSE_INTERACTION;\n}\n\nexport interface ResumeInteractionAction extends Action {\n type: typeof RESUME_INTERACTION;\n}\n\nexport interface SetCursorAction extends Action {\n type: typeof SET_CURSOR;\n payload: { cursor: string };\n}\n\nexport interface SetDefaultModeAction extends Action {\n type: typeof SET_DEFAULT_MODE;\n payload: { mode: string };\n}\n\nexport const activateMode = (mode: string): ActivateModeAction => ({\n type: ACTIVATE_MODE,\n payload: { mode },\n});\n\nexport const setCursor = (cursor: string): SetCursorAction => ({\n type: SET_CURSOR,\n payload: { cursor },\n});\n\nexport const setDefaultMode = (mode: string): SetDefaultModeAction => ({\n type: SET_DEFAULT_MODE,\n payload: { mode },\n});\n\nexport const pauseInteraction = (): PauseInteractionAction => ({\n type: PAUSE_INTERACTION,\n});\n\nexport const resumeInteraction = (): ResumeInteractionAction => ({\n type: RESUME_INTERACTION,\n});\n\nexport type InteractionManagerAction =\n | ActivateModeAction\n | PauseInteractionAction\n | ResumeInteractionAction\n | SetCursorAction\n | SetDefaultModeAction;\n","import { PointerEventHandlers } from './types';\n\nexport function mergeHandlers(list: PointerEventHandlers[]): PointerEventHandlers {\n const keys: (keyof PointerEventHandlers)[] = [\n 'onPointerDown',\n 'onPointerUp',\n 'onPointerMove',\n 'onPointerEnter',\n 'onPointerLeave',\n 'onPointerCancel',\n 'onMouseDown',\n 'onMouseUp',\n 'onMouseMove',\n 'onMouseEnter',\n 'onMouseLeave',\n 'onMouseCancel',\n 'onClick',\n 'onDoubleClick',\n ];\n const out: Partial<PointerEventHandlers> = {};\n for (const k of keys) {\n out[k] = (evt: any, nativeEvt: any, modeId: string) => {\n for (const h of list) h[k]?.(evt, nativeEvt, modeId);\n };\n }\n return out as PointerEventHandlers;\n}\n","import { BasePlugin, createBehaviorEmitter, createEmitter, PluginRegistry } from '@embedpdf/core';\n\nimport {\n InteractionManagerCapability,\n InteractionManagerPluginConfig,\n InteractionManagerState,\n InteractionMode,\n InteractionScope,\n PointerEventHandlers,\n PointerEventHandlersWithLifecycle,\n RegisterAlwaysOptions,\n RegisterHandlersOptions,\n} from './types';\nimport {\n activateMode,\n pauseInteraction,\n resumeInteraction,\n setCursor,\n setDefaultMode,\n} from './actions';\nimport { mergeHandlers } from './helper';\n\ninterface CursorClaim {\n cursor: string;\n priority: number;\n}\n\ntype HandlerSet = Set<PointerEventHandlersWithLifecycle>;\ntype PageHandlerMap = Map<number /*pageIdx*/, HandlerSet>;\n\ninterface ModeBuckets {\n /** handlers that listen on the global wrapper (only once per viewer) */\n global: HandlerSet;\n /** handlers that listen on a *specific* page wrapper */\n page: PageHandlerMap;\n}\n\nconst INITIAL_MODE = 'pointerMode';\n\nexport class InteractionManagerPlugin extends BasePlugin<\n InteractionManagerPluginConfig,\n InteractionManagerCapability,\n InteractionManagerState\n> {\n static readonly id = 'interaction-manager' as const;\n\n private modes = new Map<string, InteractionMode>();\n private cursorClaims = new Map<string, CursorClaim>();\n private buckets = new Map<string, ModeBuckets>();\n\n private alwaysGlobal = new Set<PointerEventHandlersWithLifecycle>();\n private alwaysPage = new Map<number, Set<PointerEventHandlersWithLifecycle>>();\n\n private readonly onModeChange$ = createEmitter<InteractionManagerState>();\n private readonly onHandlerChange$ = createEmitter<InteractionManagerState>();\n private readonly onCursorChange$ = createEmitter<string>();\n private readonly onStateChange$ = createBehaviorEmitter<InteractionManagerState>();\n\n constructor(id: string, registry: PluginRegistry) {\n super(id, registry);\n\n this.registerMode({\n id: INITIAL_MODE,\n scope: 'page',\n exclusive: false,\n cursor: 'auto',\n });\n\n this.setDefaultMode(INITIAL_MODE);\n this.activate(INITIAL_MODE);\n }\n\n async initialize(_: InteractionManagerPluginConfig): Promise<void> {}\n\n protected buildCapability(): InteractionManagerCapability {\n return {\n activate: (modeId: string) => this.activate(modeId),\n onModeChange: this.onModeChange$.on,\n onCursorChange: this.onCursorChange$.on,\n onHandlerChange: this.onHandlerChange$.on,\n onStateChange: this.onStateChange$.on,\n getActiveMode: () => this.state.activeMode,\n getActiveInteractionMode: () => this.getActiveInteractionMode(),\n activateDefaultMode: () => this.activate(this.state.defaultMode),\n registerMode: (mode: InteractionMode) => this.registerMode(mode),\n registerHandlers: (options: RegisterHandlersOptions) => this.registerHandlers(options),\n registerAlways: (options: RegisterAlwaysOptions) => this.registerAlways(options),\n setCursor: (token: string, cursor: string, priority = 0) =>\n this.setCursor(token, cursor, priority),\n removeCursor: (token: string) => this.removeCursor(token),\n getCurrentCursor: () => this.state.cursor,\n getHandlersForScope: (scope: InteractionScope) => this.getHandlersForScope(scope),\n activeModeIsExclusive: () => this.activeModeIsExclusive(),\n pause: () => this.dispatch(pauseInteraction()),\n resume: () => this.dispatch(resumeInteraction()),\n isPaused: () => this.state.paused,\n setDefaultMode: (id: string) => this.setDefaultMode(id),\n getDefaultMode: () => this.state.defaultMode,\n };\n }\n\n private activate(mode: string) {\n if (!this.modes.has(mode)) {\n throw new Error(`[interaction] unknown mode '${mode}'`);\n }\n if (mode === this.state.activeMode) return;\n\n const previousMode = this.state.activeMode;\n this.cursorClaims.clear(); // prevent cursor leaks\n\n this.notifyHandlersInactive(previousMode);\n\n this.dispatch(activateMode(mode));\n this.emitCursor();\n\n // Call lifecycle hooks for handlers going active\n this.notifyHandlersActive(mode);\n\n this.onModeChange$.emit({ ...this.state, activeMode: mode });\n }\n\n private setDefaultMode(modeId: string) {\n if (!this.modes.has(modeId)) {\n throw new Error(`[interaction] cannot set unknown mode '${modeId}' as default`);\n }\n this.dispatch(setDefaultMode(modeId));\n }\n\n private notifyHandlersActive(modeId: string) {\n this.alwaysGlobal.forEach((handler) => {\n handler.onHandlerActiveStart?.(modeId);\n });\n\n this.alwaysPage.forEach((handlerSet) => {\n handlerSet.forEach((handler) => {\n handler.onHandlerActiveStart?.(modeId);\n });\n });\n\n const mode = this.modes.get(modeId);\n if (!mode) return;\n\n const bucket = this.buckets.get(modeId);\n if (!bucket) return;\n\n // Notify global handlers if mode is global\n if (mode.scope === 'global') {\n bucket.global.forEach((handler) => {\n handler.onHandlerActiveStart?.(modeId);\n });\n }\n\n // Notify page handlers if mode is page\n if (mode.scope === 'page') {\n bucket.page.forEach((handlerSet, pageIndex) => {\n handlerSet.forEach((handler) => {\n handler.onHandlerActiveStart?.(modeId);\n });\n });\n }\n }\n\n private notifyHandlersInactive(modeId: string) {\n this.alwaysGlobal.forEach((handler) => {\n handler.onHandlerActiveEnd?.(modeId);\n });\n\n this.alwaysPage.forEach((handlerSet) => {\n handlerSet.forEach((handler) => {\n handler.onHandlerActiveEnd?.(modeId);\n });\n });\n\n const mode = this.modes.get(modeId);\n if (!mode) return;\n\n const bucket = this.buckets.get(modeId);\n if (!bucket) return;\n\n // Notify global handlers if mode is global\n if (mode.scope === 'global') {\n bucket.global.forEach((handler) => {\n handler.onHandlerActiveEnd?.(modeId);\n });\n }\n\n // Notify page handlers if mode is page\n if (mode.scope === 'page') {\n bucket.page.forEach((handlerSet, pageIndex) => {\n handlerSet.forEach((handler) => {\n handler.onHandlerActiveEnd?.(modeId);\n });\n });\n }\n }\n\n private registerMode(mode: InteractionMode) {\n this.modes.set(mode.id, mode);\n if (!this.buckets.has(mode.id)) {\n this.buckets.set(mode.id, { global: new Set(), page: new Map() });\n }\n }\n\n /** ---------- pointer-handler handling ------------ */\n private registerHandlers({ modeId, handlers, pageIndex }: RegisterHandlersOptions): () => void {\n const modeIds = Array.isArray(modeId) ? modeId : [modeId];\n const cleanupFunctions: (() => void)[] = [];\n\n for (const id of modeIds) {\n const bucket = this.buckets.get(id);\n if (!bucket) throw new Error(`unknown mode '${id}'`);\n\n if (pageIndex == null) {\n bucket.global.add(handlers);\n } else {\n const set = bucket.page.get(pageIndex) ?? new Set();\n set.add(handlers);\n bucket.page.set(pageIndex, set);\n }\n\n // Create cleanup function for this specific mode\n cleanupFunctions.push(() => {\n if (pageIndex == null) {\n bucket.global.delete(handlers);\n } else {\n const set = bucket.page.get(pageIndex);\n if (set) {\n set.delete(handlers);\n if (set.size === 0) {\n bucket.page.delete(pageIndex);\n }\n }\n }\n });\n }\n\n this.onHandlerChange$.emit({ ...this.state });\n\n // Return a cleanup function that removes handlers from all registered modes\n return () => {\n cleanupFunctions.forEach((cleanup) => cleanup());\n this.onHandlerChange$.emit({ ...this.state });\n };\n }\n\n public registerAlways({ scope, handlers }: RegisterAlwaysOptions): () => void {\n if (scope.type === 'global') {\n this.alwaysGlobal.add(handlers);\n this.onHandlerChange$.emit({ ...this.state });\n return () => this.alwaysGlobal.delete(handlers);\n }\n const set = this.alwaysPage.get(scope.pageIndex) ?? new Set();\n set.add(handlers);\n this.alwaysPage.set(scope.pageIndex, set);\n this.onHandlerChange$.emit({ ...this.state });\n return () => {\n set.delete(handlers);\n this.onHandlerChange$.emit({ ...this.state });\n };\n }\n\n /** Returns the *merged* handler set that should be active for the given\n * provider (`global` wrapper or a single page wrapper).\n * – `alwaysGlobal` / `alwaysPage` are **always** active.\n * – Handlers that belong to the current mode are added on top **iff**\n * the mode’s own scope matches the provider’s scope. */\n private getHandlersForScope(scope: InteractionScope): PointerEventHandlers | null {\n if (!this.state) return null;\n\n const mode = this.modes.get(this.state.activeMode);\n if (!mode) return null;\n\n const bucket = this.buckets.get(mode.id);\n if (!bucket) return null;\n\n /** helper – merge two handler sets into one object (or `null` if both are empty) */\n const mergeSets = (a: HandlerSet, b: HandlerSet) =>\n a.size || b.size ? mergeHandlers([...a, ...b]) : null;\n\n /* ───────────────────── GLOBAL PROVIDER ─────────────────────── */\n if (scope.type === 'global') {\n const modeSpecific =\n mode.scope === 'global' // only include mode handlers if the\n ? bucket.global // mode itself is global-scoped\n : new Set<PointerEventHandlers>();\n return mergeSets(this.alwaysGlobal, modeSpecific);\n }\n\n /* ─────────────────────── PAGE PROVIDER ──────────────────────── */\n const alwaysPageSet = this.alwaysPage.get(scope.pageIndex) ?? new Set<PointerEventHandlers>();\n const modePageSet =\n mode.scope === 'page'\n ? (bucket.page.get(scope.pageIndex) ?? new Set<PointerEventHandlers>())\n : new Set<PointerEventHandlers>(); // global-scoped mode → ignore page buckets\n\n return mergeSets(alwaysPageSet, modePageSet);\n }\n\n /** ---------- cursor handling --------------------- */\n private setCursor(token: string, cursor: string, priority = 0) {\n this.cursorClaims.set(token, { cursor, priority });\n this.emitCursor();\n }\n private removeCursor(token: string) {\n this.cursorClaims.delete(token);\n this.emitCursor();\n }\n\n private emitCursor() {\n /* pick highest priority claim, else mode baseline */\n const top = [...this.cursorClaims.values()].sort((a, b) => b.priority - a.priority)[0] ?? {\n cursor: this.modes.get(this.state.activeMode)?.cursor ?? 'auto',\n };\n\n if (top.cursor !== this.state.cursor) {\n this.dispatch(setCursor(top.cursor));\n this.onCursorChange$.emit(top.cursor);\n }\n }\n\n override onStoreUpdated(_: InteractionManagerState, newState: InteractionManagerState): void {\n this.onStateChange$.emit(newState);\n }\n\n private activeModeIsExclusive(): boolean {\n const mode = this.modes.get(this.state.activeMode);\n return !!mode?.exclusive;\n }\n\n private getActiveInteractionMode(): InteractionMode | null {\n return this.modes.get(this.state.activeMode) ?? null;\n }\n\n // keep emitter clean\n async destroy(): Promise<void> {\n this.onModeChange$.clear();\n this.onCursorChange$.clear();\n await super.destroy();\n }\n}\n","import { PluginManifest } from '@embedpdf/core';\nimport { InteractionManagerPluginConfig } from './types';\n\nexport const INTERACTION_MANAGER_PLUGIN_ID = 'interaction-manager';\n\nexport const manifest: PluginManifest<InteractionManagerPluginConfig> = {\n id: INTERACTION_MANAGER_PLUGIN_ID,\n name: 'Interaction Manager Plugin',\n version: '1.0.0',\n provides: ['interaction-manager'],\n requires: [],\n optional: [],\n defaultConfig: {\n enabled: true,\n },\n};\n","import { Reducer } from '@embedpdf/core';\nimport {\n ACTIVATE_MODE,\n SET_DEFAULT_MODE,\n InteractionManagerAction,\n PAUSE_INTERACTION,\n RESUME_INTERACTION,\n SET_CURSOR,\n} from './actions';\nimport { InteractionManagerState } from './types';\n\nexport const initialState: InteractionManagerState = {\n activeMode: 'pointerMode',\n defaultMode: 'pointerMode',\n cursor: 'auto',\n paused: false,\n};\n\nexport const reducer: Reducer<InteractionManagerState, InteractionManagerAction> = (\n state,\n action,\n) => {\n switch (action.type) {\n case ACTIVATE_MODE:\n return {\n ...state,\n activeMode: action.payload.mode,\n };\n case SET_CURSOR:\n return {\n ...state,\n cursor: action.payload.cursor,\n };\n case PAUSE_INTERACTION:\n return {\n ...state,\n paused: true,\n };\n case RESUME_INTERACTION:\n return {\n ...state,\n paused: false,\n };\n case SET_DEFAULT_MODE:\n return {\n ...state,\n defaultMode: action.payload.mode,\n };\n default:\n return state;\n }\n};\n","import { PluginPackage } from '@embedpdf/core';\n\nimport { InteractionManagerPlugin } from './interaction-manager-plugin';\nimport { manifest, INTERACTION_MANAGER_PLUGIN_ID } from './manifest';\nimport { InteractionManagerPluginConfig, InteractionManagerState } from './types';\nimport { reducer, initialState } from './reducer';\nimport { InteractionManagerAction } from './actions';\n\nexport const InteractionManagerPluginPackage: PluginPackage<\n InteractionManagerPlugin,\n InteractionManagerPluginConfig,\n InteractionManagerState,\n InteractionManagerAction\n> = {\n manifest,\n create: (registry) => new InteractionManagerPlugin(INTERACTION_MANAGER_PLUGIN_ID, registry),\n reducer,\n initialState,\n};\n\nexport * from './interaction-manager-plugin';\nexport * from './types';\nexport * from './manifest';\nexport * from './reducer';\n"],"names":[],"mappings":"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"}
|
package/dist/lib/actions.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ export declare const ACTIVATE_MODE = "INTERACTION/ACTIVATE_MODE";
|
|
|
3
3
|
export declare const PAUSE_INTERACTION = "INTERACTION/PAUSE";
|
|
4
4
|
export declare const RESUME_INTERACTION = "INTERACTION/RESUME";
|
|
5
5
|
export declare const SET_CURSOR = "INTERACTION/SET_CURSOR";
|
|
6
|
+
export declare const SET_DEFAULT_MODE = "INTERACTION/SET_DEFAULT_MODE";
|
|
6
7
|
export interface ActivateModeAction extends Action {
|
|
7
8
|
type: typeof ACTIVATE_MODE;
|
|
8
9
|
payload: {
|
|
@@ -21,8 +22,15 @@ export interface SetCursorAction extends Action {
|
|
|
21
22
|
cursor: string;
|
|
22
23
|
};
|
|
23
24
|
}
|
|
25
|
+
export interface SetDefaultModeAction extends Action {
|
|
26
|
+
type: typeof SET_DEFAULT_MODE;
|
|
27
|
+
payload: {
|
|
28
|
+
mode: string;
|
|
29
|
+
};
|
|
30
|
+
}
|
|
24
31
|
export declare const activateMode: (mode: string) => ActivateModeAction;
|
|
25
32
|
export declare const setCursor: (cursor: string) => SetCursorAction;
|
|
33
|
+
export declare const setDefaultMode: (mode: string) => SetDefaultModeAction;
|
|
26
34
|
export declare const pauseInteraction: () => PauseInteractionAction;
|
|
27
35
|
export declare const resumeInteraction: () => ResumeInteractionAction;
|
|
28
|
-
export type InteractionManagerAction = ActivateModeAction | PauseInteractionAction | ResumeInteractionAction | SetCursorAction;
|
|
36
|
+
export type InteractionManagerAction = ActivateModeAction | PauseInteractionAction | ResumeInteractionAction | SetCursorAction | SetDefaultModeAction;
|
|
@@ -15,6 +15,7 @@ export declare class InteractionManagerPlugin extends BasePlugin<InteractionMana
|
|
|
15
15
|
initialize(_: InteractionManagerPluginConfig): Promise<void>;
|
|
16
16
|
protected buildCapability(): InteractionManagerCapability;
|
|
17
17
|
private activate;
|
|
18
|
+
private setDefaultMode;
|
|
18
19
|
private notifyHandlersActive;
|
|
19
20
|
private notifyHandlersInactive;
|
|
20
21
|
private registerMode;
|
package/dist/lib/types.d.ts
CHANGED
|
@@ -9,6 +9,8 @@ export interface InteractionManagerState {
|
|
|
9
9
|
cursor: string;
|
|
10
10
|
/** Whether the interaction is paused */
|
|
11
11
|
paused: boolean;
|
|
12
|
+
/** Mode-id that is treated as the resolver’s fall-back (“finish → …”). */
|
|
13
|
+
defaultMode: string;
|
|
12
14
|
}
|
|
13
15
|
export interface InteractionMode {
|
|
14
16
|
/** unique id */
|
|
@@ -20,6 +22,9 @@ export interface InteractionMode {
|
|
|
20
22
|
exclusive: boolean;
|
|
21
23
|
/** baseline cursor while the mode is active (before any handler overrides it). */
|
|
22
24
|
cursor?: string;
|
|
25
|
+
/** Set to `false` when this tool wants to disable raw touch events.
|
|
26
|
+
* Defaults to `true`. */
|
|
27
|
+
wantsRawTouch?: boolean;
|
|
23
28
|
}
|
|
24
29
|
export interface EmbedPdfPointerEvent {
|
|
25
30
|
clientX: number;
|
|
@@ -36,6 +41,12 @@ export interface PointerEventHandlers<T = EmbedPdfPointerEvent> {
|
|
|
36
41
|
onPointerEnter?(pos: Position, evt: T, modeId: string): void;
|
|
37
42
|
onPointerLeave?(pos: Position, evt: T, modeId: string): void;
|
|
38
43
|
onPointerCancel?(pos: Position, evt: T, modeId: string): void;
|
|
44
|
+
onMouseDown?(pos: Position, evt: T, modeId: string): void;
|
|
45
|
+
onMouseUp?(pos: Position, evt: T, modeId: string): void;
|
|
46
|
+
onMouseMove?(pos: Position, evt: T, modeId: string): void;
|
|
47
|
+
onMouseEnter?(pos: Position, evt: T, modeId: string): void;
|
|
48
|
+
onMouseLeave?(pos: Position, evt: T, modeId: string): void;
|
|
49
|
+
onMouseCancel?(pos: Position, evt: T, modeId: string): void;
|
|
39
50
|
onClick?(pos: Position, evt: T, modeId: string): void;
|
|
40
51
|
onDoubleClick?(pos: Position, evt: T, modeId: string): void;
|
|
41
52
|
}
|
|
@@ -70,8 +81,8 @@ export interface InteractionManagerCapability {
|
|
|
70
81
|
getActiveInteractionMode(): InteractionMode | null;
|
|
71
82
|
/** programmatically switch to a mode */
|
|
72
83
|
activate(modeId: string): void;
|
|
73
|
-
/**
|
|
74
|
-
|
|
84
|
+
/** set default mode */
|
|
85
|
+
activateDefaultMode(): void;
|
|
75
86
|
/** register a mode (should be called at start‑up by each plugin/tool). */
|
|
76
87
|
registerMode(mode: InteractionMode): void;
|
|
77
88
|
/** register pointer handlers that run *only* while the given mode is active. */
|
|
@@ -104,5 +115,9 @@ export interface InteractionManagerCapability {
|
|
|
104
115
|
resume(): void;
|
|
105
116
|
/** Returns whether the interaction is paused */
|
|
106
117
|
isPaused(): boolean;
|
|
118
|
+
/** Set the default mode */
|
|
119
|
+
setDefaultMode(id: string): void;
|
|
120
|
+
/** Get the default mode */
|
|
121
|
+
getDefaultMode(): string;
|
|
107
122
|
}
|
|
108
123
|
export {};
|
package/dist/preact/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("@embedpdf/core/preact"),t=require("@embedpdf/plugin-interaction-manager"),
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("@embedpdf/core/preact"),t=require("@embedpdf/plugin-interaction-manager"),o=require("preact/hooks"),n=require("preact/jsx-runtime"),r=require("@embedpdf/models"),i=()=>e.useCapability(t.InteractionManagerPlugin.id);function c(){const{provides:e}=i(),[t,n]=o.useState((()=>{const t=null==e?void 0:e.getActiveInteractionMode();return"page"===(null==t?void 0:t.scope)&&!!t.exclusive}));return o.useEffect((()=>{if(e)return e.onModeChange((()=>{const t=e.getActiveInteractionMode();n("page"===(null==t?void 0:t.scope)&&!!(null==t?void 0:t.exclusive))}))}),[e]),t}const s={pointerdown:"onPointerDown",pointerup:"onPointerUp",pointermove:"onPointerMove",pointerenter:"onPointerEnter",pointerleave:"onPointerLeave",pointercancel:"onPointerCancel",mousedown:"onMouseDown",mouseup:"onMouseUp",mousemove:"onMouseMove",mouseenter:"onMouseEnter",mouseleave:"onMouseLeave",mousecancel:"onMouseCancel",click:"onClick",dblclick:"onDoubleClick",touchstart:"onPointerDown",touchend:"onPointerUp",touchmove:"onPointerMove",touchcancel:"onPointerCancel"},u=["pointerdown","pointerup","pointermove","pointerenter","pointerleave","pointercancel","mousedown","mouseup","mousemove","mouseenter","mouseleave","mousecancel","click","dblclick","touchstart","touchend","touchmove","touchcancel"];function l(e,t,o,n){let r=e.getHandlersForScope(t);const i=()=>{var t;return!1!==(null==(t=e.getActiveInteractionMode())?void 0:t.wantsRawTouch)},c={};let l=i();const a=e=>{u.forEach((t=>{const n=c[t]??(c[t]=y);var r;o.addEventListener(t,n,(r=e,t.startsWith("touch")?{passive:!r}:{passive:!1}))}))},d=()=>{u.forEach((e=>{const t=c[e];t&&o.removeEventListener(e,t)}))};a(l);const p=e.onModeChange((()=>{if("global"===t.type){const t=e.getActiveInteractionMode();o.style.cursor="global"===(null==t?void 0:t.scope)?t.cursor??"auto":"auto"}r=e.getHandlersForScope(t);const n=i();n!==l&&(d(),a(n),l=n)})),v=e.onHandlerChange((()=>{r=e.getHandlersForScope(t)})),g=e.getActiveInteractionMode(),h=e.getCurrentCursor();o.style.cursor="global"===t.type&&"global"!==(null==g?void 0:g.scope)?"auto":h;const f=e.onCursorChange((n=>{var r;"global"===t.type&&"global"!==(null==(r=e.getActiveInteractionMode())?void 0:r.scope)||(o.style.cursor=n)})),m=(e,t)=>{if(n)return n(e,t);const o=t.getBoundingClientRect();return{x:e.clientX-o.left,y:e.clientY-o.top}};function y(t){var n;if(e.isPaused())return;const i=s[t.type];if(!i||!(null==r?void 0:r[i]))return;let c,u;if(t instanceof TouchEvent&&l&&("touchmove"===t.type||"touchcancel"===t.type)&&t.preventDefault(),t instanceof TouchEvent){const e="touchend"===t.type||"touchcancel"===t.type?t.changedTouches[0]:t.touches[0];if(!e)return;c=m(e,o),u={clientX:e.clientX,clientY:e.clientY,ctrlKey:t.ctrlKey,shiftKey:t.shiftKey,altKey:t.altKey,metaKey:t.metaKey,target:t.target,currentTarget:t.currentTarget}}else{const e=t;c=m(e,o),u=e}null==(n=r[i])||n.call(r,c,u,e.getActiveMode())}return()=>{d(),p(),f(),v()}}exports.GlobalPointerProvider=({children:e,style:t,...r})=>{const c=o.useRef(null),{provides:s}=i();return o.useEffect((()=>{if(s&&c.current)return l(s,{type:"global"},c.current)}),[s]),n.jsx("div",{ref:c,style:{width:"100%",height:"100%",...t},...r,children:e})},exports.PagePointerProvider=({pageIndex:e,children:t,pageWidth:s,pageHeight:u,rotation:a,scale:d,convertEventToPoint:p,style:v,...g})=>{const h=o.useRef(null),{provides:f}=i(),m=c(),y=o.useCallback(((e,t)=>{const o=t.getBoundingClientRect(),n={x:e.clientX-o.left,y:e.clientY-o.top};return r.restorePosition({width:s,height:u},n,a,d)}),[s,u,a,d]);return o.useEffect((()=>{if(f&&h.current)return l(f,{type:"page",pageIndex:e},h.current,p||y)}),[f,e,p,y]),n.jsxs("div",{ref:h,style:{...v},...g,children:[t,m&&n.jsx("div",{style:{position:"absolute",top:0,left:0,right:0,bottom:0,zIndex:10}})]})},exports.useCursor=function(){const{provides:e}=i();return{setCursor:(t,o,n=0)=>{null==e||e.setCursor(t,o,n)},removeCursor:t=>{null==e||e.removeCursor(t)}}},exports.useInteractionManager=function(){const{provides:e}=i(),[n,r]=o.useState(t.initialState);return o.useEffect((()=>{if(e)return e.onStateChange((e=>{r(e)}))}),[e]),{provides:e,state:n}},exports.useInteractionManagerCapability=i,exports.useInteractionManagerPlugin=()=>e.usePlugin(t.InteractionManagerPlugin.id),exports.useIsPageExclusive=c,exports.usePointerHandlers=function({modeId:e,pageIndex:t}){const{provides:o}=i();return{register:(n,r)=>{const i=(null==r?void 0:r.modeId)??e,c=(null==r?void 0:r.pageIndex)??t;return i?null==o?void 0:o.registerHandlers({modeId:i,handlers:n,pageIndex:c}):null==o?void 0:o.registerAlways({scope:void 0!==c?{type:"page",pageIndex:c}:{type:"global"},handlers:n})}}};
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../../src/shared/hooks/use-interaction-manager.ts","../../src/shared/utils.ts","../../src/shared/components/global-pointer-provider.tsx","../../src/shared/components/page-pointer-provider.tsx"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/@framework';\nimport {\n initialState,\n InteractionManagerPlugin,\n InteractionManagerState,\n PointerEventHandlers,\n PointerEventHandlersWithLifecycle,\n} from '@embedpdf/plugin-interaction-manager';\nimport { useState, useEffect } from '@framework';\n\nexport const useInteractionManagerPlugin = () =>\n usePlugin<InteractionManagerPlugin>(InteractionManagerPlugin.id);\nexport const useInteractionManagerCapability = () =>\n useCapability<InteractionManagerPlugin>(InteractionManagerPlugin.id);\n\nexport function useInteractionManager() {\n const { provides } = useInteractionManagerCapability();\n const [state, setState] = useState<InteractionManagerState>(initialState);\n\n useEffect(() => {\n if (!provides) return;\n return provides.onStateChange((state) => {\n setState(state);\n });\n }, [provides]);\n\n return {\n provides,\n state,\n };\n}\n\nexport function useCursor() {\n const { provides } = useInteractionManagerCapability();\n return {\n setCursor: (token: string, cursor: string, prio = 0) => {\n provides?.setCursor(token, cursor, prio);\n },\n removeCursor: (token: string) => {\n provides?.removeCursor(token);\n },\n };\n}\n\ninterface UsePointerHandlersOptions {\n modeId?: string | string[];\n pageIndex?: number;\n}\n\nexport function usePointerHandlers({ modeId, pageIndex }: UsePointerHandlersOptions) {\n const { provides } = useInteractionManagerCapability();\n return {\n register: (\n handlers: PointerEventHandlersWithLifecycle,\n options?: { modeId?: string | string[]; pageIndex?: number },\n ) => {\n // Use provided options or fall back to hook-level options\n const finalModeId = options?.modeId ?? modeId;\n const finalPageIndex = options?.pageIndex ?? pageIndex;\n\n return finalModeId\n ? provides?.registerHandlers({\n modeId: finalModeId,\n handlers,\n pageIndex: finalPageIndex,\n })\n : provides?.registerAlways({\n scope:\n finalPageIndex !== undefined\n ? { type: 'page', pageIndex: finalPageIndex }\n : { type: 'global' },\n handlers,\n });\n },\n };\n}\n\nexport function useIsPageExclusive() {\n const { provides: cap } = useInteractionManagerCapability();\n\n const [isPageExclusive, setIsPageExclusive] = useState<boolean>(() => {\n const m = cap?.getActiveInteractionMode();\n return m?.scope === 'page' && !!m.exclusive;\n });\n\n useEffect(() => {\n if (!cap) return;\n\n return cap.onModeChange(() => {\n const mode = cap.getActiveInteractionMode();\n setIsPageExclusive(mode?.scope === 'page' && !!mode?.exclusive);\n });\n }, [cap]);\n\n return isPageExclusive;\n}\n","import { Position } from '@embedpdf/models';\nimport type {\n InteractionManagerCapability,\n InteractionScope,\n PointerEventHandlers,\n} from '@embedpdf/plugin-interaction-manager';\n\n/**\n * Hook one DOM element into the interaction-manager.\n * – keeps handlers & cursor in-sync with the current mode\n * – returns a teardown fn for React/Preact effects\n */\nexport function createPointerProvider(\n cap: InteractionManagerCapability,\n scope: InteractionScope,\n element: HTMLElement,\n convertEventToPoint?: (evt: PointerEvent, host: HTMLElement) => Position,\n) {\n /* ------------------------------------------------------------------ */\n /* active handler set – hot-swapped on every mode change */\n /* ------------------------------------------------------------------ */\n let active: PointerEventHandlers | null = cap.getHandlersForScope(scope);\n\n const stopMode = cap.onModeChange(() => {\n if (scope.type === 'global') {\n const mode = cap.getActiveInteractionMode();\n element.style.cursor = mode?.scope === 'global' ? (mode.cursor ?? 'auto') : 'auto';\n }\n active = cap.getHandlersForScope(scope);\n });\n\n const stopHandler = cap.onHandlerChange(() => {\n active = cap.getHandlersForScope(scope);\n });\n\n /* ------------------------------------------------------------------ */\n /* cursor */\n /* ------------------------------------------------------------------ */\n const modeNow = cap.getActiveInteractionMode();\n const cursorNow = cap.getCurrentCursor();\n\n /** initial cursor -------------------------------------------------- */\n if (scope.type === 'global') {\n // global wrapper only shows the cursor while a *global* mode is active\n element.style.cursor = modeNow?.scope === 'global' ? cursorNow : 'auto';\n } else {\n // page wrappers always mirror the latest cursor\n element.style.cursor = cursorNow;\n }\n\n const stopCursor = cap.onCursorChange((c) => {\n /** ❖ Propagation rule\n * ─────────────────\n * • global provider updates its cursor *only* while the active\n * mode itself is ‘global’.\n * • page providers always sync (so they show the cursor during\n * a global mode as well). */\n if (scope.type === 'global') {\n const isGlobalMode = cap.getActiveInteractionMode()?.scope === 'global';\n if (!isGlobalMode) return; // active mode is page-scoped → ignore\n }\n element.style.cursor = c;\n });\n\n /* ------------------------------------------------------------------ */\n /* event wiring */\n /* ------------------------------------------------------------------ */\n type K = keyof PointerEventHandlers;\n const domEvent: Record<K, keyof HTMLElementEventMap> = {\n onPointerDown: 'pointerdown',\n onPointerUp: 'pointerup',\n onPointerMove: 'pointermove',\n onPointerEnter: 'pointerenter',\n onPointerLeave: 'pointerleave',\n onPointerCancel: 'pointercancel',\n onClick: 'click',\n onDoubleClick: 'dblclick',\n };\n\n /* one stable EventListener per key -> needed for removeEventListener */\n const listeners: Partial<Record<K, EventListener>> = {};\n\n const toPos = (e: PointerEvent, host: HTMLElement): Position => {\n if (convertEventToPoint) return convertEventToPoint(e, host);\n const r = host.getBoundingClientRect();\n return { x: e.clientX - r.left, y: e.clientY - r.top };\n };\n\n (Object.keys(domEvent) as K[]).forEach((k) => {\n listeners[k] = (evt: Event) => {\n if (cap.isPaused()) return;\n\n const pe = evt as PointerEvent; // safe – we only attach to pointer*\n const currentModeId = cap.getActiveMode();\n active?.[k]?.(toPos(pe, element), pe, currentModeId);\n /* if you need to stop default behaviour when no handler is active:\n * if (!active?.[k]) pe.preventDefault(); */\n };\n element.addEventListener(domEvent[k], listeners[k]!);\n });\n\n /* ------------------------------------------------------------------ */\n /* teardown */\n /* ------------------------------------------------------------------ */\n return () => {\n (Object.keys(domEvent) as K[]).forEach((k) =>\n element.removeEventListener(domEvent[k], listeners[k]!),\n );\n stopMode();\n stopCursor();\n stopHandler();\n };\n}\n","import { ReactNode, useEffect, useRef, HTMLAttributes, CSSProperties } from '@framework';\nimport { createPointerProvider } from '../utils';\n\nimport { useInteractionManagerCapability } from '../hooks';\n\ninterface GlobalPointerProviderProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n style?: CSSProperties;\n}\n\nexport const GlobalPointerProvider = ({\n children,\n style,\n ...props\n}: GlobalPointerProviderProps) => {\n const ref = useRef<HTMLDivElement>(null);\n const { provides: cap } = useInteractionManagerCapability();\n\n useEffect(() => {\n if (!cap || !ref.current) return;\n\n return createPointerProvider(cap, { type: 'global' }, ref.current);\n }, [cap]);\n\n return (\n <div\n ref={ref}\n style={{\n width: '100%',\n height: '100%',\n ...style,\n }}\n {...props}\n >\n {children}\n </div>\n );\n};\n","import {\n ReactNode,\n useEffect,\n useRef,\n useCallback,\n HTMLAttributes,\n CSSProperties,\n} from '@framework';\nimport { Position, restorePosition } from '@embedpdf/models';\nimport { createPointerProvider } from '../utils';\n\nimport { useInteractionManagerCapability, useIsPageExclusive } from '../hooks';\n\ninterface PagePointerProviderProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n pageIndex: number;\n pageWidth: number;\n pageHeight: number;\n rotation: number;\n scale: number;\n style?: CSSProperties;\n convertEventToPoint?: (event: PointerEvent, element: HTMLElement) => Position;\n}\n\nexport const PagePointerProvider = ({\n pageIndex,\n children,\n pageWidth,\n pageHeight,\n rotation,\n scale,\n convertEventToPoint,\n style,\n ...props\n}: PagePointerProviderProps) => {\n const ref = useRef<HTMLDivElement>(null);\n const { provides: cap } = useInteractionManagerCapability();\n const isPageExclusive = useIsPageExclusive();\n\n // Memoize the default conversion function\n const defaultConvertEventToPoint = useCallback(\n (event: PointerEvent, element: HTMLElement): Position => {\n const rect = element.getBoundingClientRect();\n const displayPoint = {\n x: event.clientX - rect.left,\n y: event.clientY - rect.top,\n };\n return restorePosition(\n { width: pageWidth, height: pageHeight },\n displayPoint,\n rotation,\n scale,\n );\n },\n [pageWidth, pageHeight, rotation, scale],\n );\n\n useEffect(() => {\n if (!cap || !ref.current) return;\n\n return createPointerProvider(\n cap,\n { type: 'page', pageIndex },\n ref.current,\n convertEventToPoint || defaultConvertEventToPoint,\n );\n }, [cap, pageIndex, convertEventToPoint, defaultConvertEventToPoint]);\n\n return (\n <div\n ref={ref}\n style={{\n ...style,\n }}\n {...props}\n >\n {children}\n {isPageExclusive && (\n <div style={{ position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, zIndex: 10 }} />\n )}\n </div>\n );\n};\n"],"names":["useInteractionManagerCapability","useCapability","InteractionManagerPlugin","id","useIsPageExclusive","provides","cap","isPageExclusive","setIsPageExclusive","useState","m","getActiveInteractionMode","scope","exclusive","useEffect","onModeChange","mode","createPointerProvider","element","convertEventToPoint","active","getHandlersForScope","stopMode","type","style","cursor","stopHandler","onHandlerChange","modeNow","cursorNow","getCurrentCursor","stopCursor","onCursorChange","c","_a","domEvent","onPointerDown","onPointerUp","onPointerMove","onPointerEnter","onPointerLeave","onPointerCancel","onClick","onDoubleClick","listeners","Object","keys","forEach","k","evt","isPaused","pe","currentModeId","getActiveMode","call","e","host","r","getBoundingClientRect","x","clientX","left","y","clientY","top","toPos","addEventListener","removeEventListener","children","props","ref","useRef","current","jsxRuntime","jsx","width","height","pageIndex","pageWidth","pageHeight","rotation","scale","defaultConvertEventToPoint","useCallback","event","rect","displayPoint","restorePosition","jsxs","position","right","bottom","zIndex","setCursor","token","prio","removeCursor","state","setState","initialState","onStateChange","usePlugin","modeId","register","handlers","options","finalModeId","finalPageIndex","registerHandlers","registerAlways"],"mappings":"mQAYaA,EAAkC,IAC7CC,gBAAwCC,EAAAA,yBAAyBC,IAgE5D,SAASC,IACd,MAAQC,SAAUC,GAAQN,KAEnBO,EAAiBC,GAAsBC,YAAkB,KACxD,MAAAC,EAAS,MAALJ,OAAK,EAAAA,EAAAK,2BACf,MAAoB,UAAV,MAAHD,OAAG,EAAAA,EAAAE,UAAsBF,EAAEG,SAAA,IAY7B,OATPC,EAAAA,WAAU,KACR,GAAKR,EAEE,OAAAA,EAAIS,cAAa,KAChB,MAAAC,EAAOV,EAAIK,2BACjBH,EAAmC,gBAAhBQ,WAAMJ,iBAAsBI,WAAMH,WAAS,GAC/D,GACA,CAACP,IAEGC,CACT,CCnFO,SAASU,EACdX,EACAM,EACAM,EACAC,GAKI,IAAAC,EAAsCd,EAAIe,oBAAoBT,GAE5D,MAAAU,EAAWhB,EAAIS,cAAa,KAC5B,GAAe,WAAfH,EAAMW,KAAmB,CACrB,MAAAP,EAAOV,EAAIK,2BACjBO,EAAQM,MAAMC,OAAyB,YAAhB,MAAAT,OAAA,EAAAA,EAAMJ,OAAsBI,EAAKS,QAAU,OAAU,MAAA,CAErEL,EAAAd,EAAIe,oBAAoBT,EAAK,IAGlCc,EAAcpB,EAAIqB,iBAAgB,KAC7BP,EAAAd,EAAIe,oBAAoBT,EAAK,IAMlCgB,EAAUtB,EAAIK,2BACdkB,EAAYvB,EAAIwB,mBAGH,WAAflB,EAAMW,KAERL,EAAQM,MAAMC,OAA4B,YAAV,MAATG,OAAS,EAAAA,EAAAhB,OAAqBiB,EAAY,OAGjEX,EAAQM,MAAMC,OAASI,EAGzB,MAAME,EAAazB,EAAI0B,gBAAgBC,UAOjC,GAAe,WAAfrB,EAAMW,KAAmB,CAE3B,KAD+D,YAA1C,OAAAW,EAAA5B,EAAIK,qCAA4BC,QAClC,MAAA,CAErBM,EAAQM,MAAMC,OAASQ,CAAA,IAOnBE,EAAiD,CACrDC,cAAe,cACfC,YAAa,YACbC,cAAe,cACfC,eAAgB,eAChBC,eAAgB,eAChBC,gBAAiB,gBACjBC,QAAS,QACTC,cAAe,YAIXC,EAA+C,CAAC,EAwBtD,OAhBCC,OAAOC,KAAKX,GAAkBY,SAASC,IAC5BJ,EAAAI,GAAMC,UACV,GAAA3C,EAAI4C,WAAY,OAEpB,MAAMC,EAAKF,EACLG,EAAgB9C,EAAI+C,gBAC1B,OAAAnB,EAAA,MAAAd,OAAA,EAAAA,EAAS4B,KAAKd,EAAAoB,KAAAlC,EAZJ,EAACmC,EAAiBC,KAC9B,GAAIrC,EAAqB,OAAOA,EAAoBoC,EAAGC,GACjD,MAAAC,EAAID,EAAKE,wBACR,MAAA,CAAEC,EAAGJ,EAAEK,QAAUH,EAAEI,KAAMC,EAAGP,EAAEQ,QAAUN,EAAEO,IAAI,EASrCC,CAAMd,EAAIjC,GAAUiC,EAAIC,EAAA,EAIxClC,EAAQgD,iBAAiB/B,EAASa,GAAIJ,EAAUI,GAAG,IAM9C,KACGH,OAAAC,KAAKX,GAAkBY,SAASC,GACtC9B,EAAQiD,oBAAoBhC,EAASa,GAAIJ,EAAUI,MAE5C1B,IACES,IACCL,GAAA,CAEhB,+BCtGqC,EACnC0C,WACA5C,WACG6C,MAEG,MAAAC,EAAMC,SAAuB,OAC3BlE,SAAUC,GAAQN,IASxB,OAPFc,EAAAA,WAAU,KACR,GAAKR,GAAQgE,EAAIE,QAEjB,OAAOvD,EAAsBX,EAAK,CAAEiB,KAAM,UAAY+C,EAAIE,QAAO,GAChE,CAAClE,IAGFmE,EAAAC,IAAC,MAAA,CACCJ,MACA9C,MAAO,CACLmD,MAAO,OACPC,OAAQ,UACLpD,MAED6C,EAEHD,YACH,8BCX+B,EACjCS,YACAT,WACAU,YACAC,aACAC,WACAC,QACA9D,sBACAK,WACG6C,MAEG,MAAAC,EAAMC,SAAuB,OAC3BlE,SAAUC,GAAQN,IACpBO,EAAkBH,IAGlB8E,EAA6BC,EAAAA,aACjC,CAACC,EAAqBlE,KACd,MAAAmE,EAAOnE,EAAQwC,wBACf4B,EAAe,CACnB3B,EAAGyB,EAAMxB,QAAUyB,EAAKxB,KACxBC,EAAGsB,EAAMrB,QAAUsB,EAAKrB,KAEnB,OAAAuB,EAAAA,gBACL,CAAEZ,MAAOG,EAAWF,OAAQG,GAC5BO,EACAN,EACAC,EACF,GAEF,CAACH,EAAWC,EAAYC,EAAUC,IAelC,OAZFnE,EAAAA,WAAU,KACR,GAAKR,GAAQgE,EAAIE,QAEV,OAAAvD,EACLX,EACA,CAAEiB,KAAM,OAAQsD,aAChBP,EAAIE,QACJrD,GAAuB+D,EACzB,GACC,CAAC5E,EAAKuE,EAAW1D,EAAqB+D,IAGvCT,EAAAe,KAAC,MAAA,CACClB,MACA9C,MAAO,IACFA,MAED6C,EAEHD,SAAA,CAAAA,EACA7D,KACEmE,IAAA,MAAA,CAAIlD,MAAO,CAAEiE,SAAU,WAAYzB,IAAK,EAAGH,KAAM,EAAG6B,MAAO,EAAGC,OAAQ,EAAGC,OAAQ,QAEtF,oBHhDG,WACC,MAAAvF,SAAEA,GAAaL,IACd,MAAA,CACL6F,UAAW,CAACC,EAAerE,EAAgBsE,EAAO,KACtC,MAAA1F,GAAAA,EAAAwF,UAAUC,EAAOrE,EAAQsE,EAAA,EAErCC,aAAeF,IACb,MAAAzF,GAAAA,EAAU2F,aAAaF,EAAA,EAG7B,gCA3BO,WACC,MAAAzF,SAAEA,GAAaL,KACdiG,EAAOC,GAAYzF,EAAAA,SAAkC0F,EAAAA,cASrD,OAPPrF,EAAAA,WAAU,KACR,GAAKT,EACE,OAAAA,EAAS+F,eAAeH,IAC7BC,EAASD,EAAK,GACf,GACA,CAAC5F,IAEG,CACLA,WACA4F,QAEJ,gFApB2C,IACzCI,YAAoCnG,EAAAA,yBAAyBC,4DAsCxD,UAA4BmG,OAAEA,EAAQzB,UAAAA,IACrC,MAAAxE,SAAEA,GAAaL,IACd,MAAA,CACLuG,SAAU,CACRC,EACAC,KAGM,MAAAC,SAAcD,WAASH,SAAUA,EACjCK,SAAiBF,WAAS5B,YAAaA,EAEtC,OAAA6B,QACHrG,WAAUuG,iBAAiB,CACzBN,OAAQI,EACRF,WACA3B,UAAW8B,UAEbtG,WAAUwG,eAAe,CACvBjG,WACqB,IAAnB+F,EACI,CAAEpF,KAAM,OAAQsD,UAAW8B,GAC3B,CAAEpF,KAAM,UACdiF,YAAA,EAIZ"}
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../../src/shared/hooks/use-interaction-manager.ts","../../src/shared/utils.ts","../../src/shared/components/global-pointer-provider.tsx","../../src/shared/components/page-pointer-provider.tsx"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/@framework';\nimport {\n initialState,\n InteractionManagerPlugin,\n InteractionManagerState,\n PointerEventHandlers,\n PointerEventHandlersWithLifecycle,\n} from '@embedpdf/plugin-interaction-manager';\nimport { useState, useEffect } from '@framework';\n\nexport const useInteractionManagerPlugin = () =>\n usePlugin<InteractionManagerPlugin>(InteractionManagerPlugin.id);\nexport const useInteractionManagerCapability = () =>\n useCapability<InteractionManagerPlugin>(InteractionManagerPlugin.id);\n\nexport function useInteractionManager() {\n const { provides } = useInteractionManagerCapability();\n const [state, setState] = useState<InteractionManagerState>(initialState);\n\n useEffect(() => {\n if (!provides) return;\n return provides.onStateChange((state) => {\n setState(state);\n });\n }, [provides]);\n\n return {\n provides,\n state,\n };\n}\n\nexport function useCursor() {\n const { provides } = useInteractionManagerCapability();\n return {\n setCursor: (token: string, cursor: string, prio = 0) => {\n provides?.setCursor(token, cursor, prio);\n },\n removeCursor: (token: string) => {\n provides?.removeCursor(token);\n },\n };\n}\n\ninterface UsePointerHandlersOptions {\n modeId?: string | string[];\n pageIndex?: number;\n}\n\nexport function usePointerHandlers({ modeId, pageIndex }: UsePointerHandlersOptions) {\n const { provides } = useInteractionManagerCapability();\n return {\n register: (\n handlers: PointerEventHandlersWithLifecycle,\n options?: { modeId?: string | string[]; pageIndex?: number },\n ) => {\n // Use provided options or fall back to hook-level options\n const finalModeId = options?.modeId ?? modeId;\n const finalPageIndex = options?.pageIndex ?? pageIndex;\n\n return finalModeId\n ? provides?.registerHandlers({\n modeId: finalModeId,\n handlers,\n pageIndex: finalPageIndex,\n })\n : provides?.registerAlways({\n scope:\n finalPageIndex !== undefined\n ? { type: 'page', pageIndex: finalPageIndex }\n : { type: 'global' },\n handlers,\n });\n },\n };\n}\n\nexport function useIsPageExclusive() {\n const { provides: cap } = useInteractionManagerCapability();\n\n const [isPageExclusive, setIsPageExclusive] = useState<boolean>(() => {\n const m = cap?.getActiveInteractionMode();\n return m?.scope === 'page' && !!m.exclusive;\n });\n\n useEffect(() => {\n if (!cap) return;\n\n return cap.onModeChange(() => {\n const mode = cap.getActiveInteractionMode();\n setIsPageExclusive(mode?.scope === 'page' && !!mode?.exclusive);\n });\n }, [cap]);\n\n return isPageExclusive;\n}\n","import { Position } from '@embedpdf/models';\nimport type {\n InteractionManagerCapability,\n InteractionScope,\n PointerEventHandlers,\n EmbedPdfPointerEvent,\n} from '@embedpdf/plugin-interaction-manager';\n\n/* -------------------------------------------------- */\n/* event → handler key lookup */\n/* -------------------------------------------------- */\ntype K = keyof PointerEventHandlers;\nconst domEventMap: Record<string, K> = {\n pointerdown: 'onPointerDown',\n pointerup: 'onPointerUp',\n pointermove: 'onPointerMove',\n pointerenter: 'onPointerEnter',\n pointerleave: 'onPointerLeave',\n pointercancel: 'onPointerCancel',\n\n mousedown: 'onMouseDown',\n mouseup: 'onMouseUp',\n mousemove: 'onMouseMove',\n mouseenter: 'onMouseEnter',\n mouseleave: 'onMouseLeave',\n mousecancel: 'onMouseCancel',\n\n click: 'onClick',\n dblclick: 'onDoubleClick',\n\n /* touch → pointer fallback for very old browsers */\n touchstart: 'onPointerDown',\n touchend: 'onPointerUp',\n touchmove: 'onPointerMove',\n touchcancel: 'onPointerCancel',\n};\n\nconst pointerEventTypes = [\n 'pointerdown',\n 'pointerup',\n 'pointermove',\n 'pointerenter',\n 'pointerleave',\n 'pointercancel',\n 'mousedown',\n 'mouseup',\n 'mousemove',\n 'mouseenter',\n 'mouseleave',\n 'mousecancel',\n 'click',\n 'dblclick',\n];\n\nconst touchEventTypes = ['touchstart', 'touchend', 'touchmove', 'touchcancel'];\nconst allEventTypes = [...pointerEventTypes, ...touchEventTypes];\n\n/* -------------------------------------------------- */\n/* helper: decide listener options per event type */\n/* -------------------------------------------------- */\nfunction listenerOpts(eventType: string, wantsRawTouch: boolean): AddEventListenerOptions {\n // Only touch events are toggled; pointer/mouse stay non-passive\n return eventType.startsWith('touch') ? { passive: !wantsRawTouch } : { passive: false };\n}\n\n/* -------------------------------------------------- */\n/* createPointerProvider */\n/* -------------------------------------------------- */\nexport function createPointerProvider(\n cap: InteractionManagerCapability,\n scope: InteractionScope,\n element: HTMLElement,\n convertEventToPoint?: (evt: PointerEvent, host: HTMLElement) => Position,\n) {\n /* ---------- live handler set --------------------------------------------------- */\n let active: PointerEventHandlers | null = cap.getHandlersForScope(scope);\n\n /* ---------- helper to compute current wantsRawTouch (defaults to true) --------- */\n const wantsRawTouchNow = () => cap.getActiveInteractionMode()?.wantsRawTouch !== false; // default → true\n\n /* ---------- dynamic listener (re)attachment ------------------------------------ */\n const listeners: Record<string, (evt: Event) => void> = {};\n let attachedWithRawTouch = wantsRawTouchNow(); // remember current mode’s wish\n\n const addListeners = (raw: boolean) => {\n allEventTypes.forEach((type) => {\n const fn = (listeners[type] ??= handleEvent);\n element.addEventListener(type, fn, listenerOpts(type, raw));\n });\n };\n const removeListeners = () => {\n allEventTypes.forEach((type) => {\n const fn = listeners[type];\n if (fn) element.removeEventListener(type, fn);\n });\n };\n\n /* attach for the first time */\n addListeners(attachedWithRawTouch);\n\n /* ---------- mode & handler change hooks --------------------------------------- */\n const stopMode = cap.onModeChange(() => {\n /* cursor baseline update for global wrapper */\n if (scope.type === 'global') {\n const mode = cap.getActiveInteractionMode();\n element.style.cursor = mode?.scope === 'global' ? (mode.cursor ?? 'auto') : 'auto';\n }\n\n active = cap.getHandlersForScope(scope);\n\n /* re-attach listeners if wantsRawTouch toggled */\n const raw = wantsRawTouchNow();\n if (raw !== attachedWithRawTouch) {\n removeListeners();\n addListeners(raw);\n attachedWithRawTouch = raw;\n }\n });\n\n const stopHandler = cap.onHandlerChange(() => {\n active = cap.getHandlersForScope(scope);\n });\n\n /* ---------- cursor sync -------------------------------------------------------- */\n const initialMode = cap.getActiveInteractionMode();\n const initialCursor = cap.getCurrentCursor();\n element.style.cursor =\n scope.type === 'global' && initialMode?.scope !== 'global' ? 'auto' : initialCursor;\n\n const stopCursor = cap.onCursorChange((c) => {\n if (scope.type === 'global' && cap.getActiveInteractionMode()?.scope !== 'global') return;\n element.style.cursor = c;\n });\n\n /* ---------- point conversion --------------------------------------------------- */\n const toPos = (e: { clientX: number; clientY: number }, host: HTMLElement): Position => {\n if (convertEventToPoint) return convertEventToPoint(e as PointerEvent, host);\n const r = host.getBoundingClientRect();\n return { x: e.clientX - r.left, y: e.clientY - r.top };\n };\n\n /* ---------- central event handler --------------------------------------------- */\n function handleEvent(evt: Event) {\n if (cap.isPaused()) return;\n\n const handlerKey = domEventMap[evt.type];\n if (!handlerKey || !active?.[handlerKey]) return;\n\n /* preventDefault only when mode really wants raw touch */\n if (\n evt instanceof TouchEvent &&\n attachedWithRawTouch &&\n (evt.type === 'touchmove' || evt.type === 'touchcancel')\n ) {\n evt.preventDefault();\n }\n\n // ----- normalise ----------------------------------------------------------------\n let pos!: Position;\n let normEvt!: EmbedPdfPointerEvent & {\n target: EventTarget | null;\n currentTarget: EventTarget | null;\n };\n\n if (evt instanceof TouchEvent) {\n const tp =\n evt.type === 'touchend' || evt.type === 'touchcancel'\n ? evt.changedTouches[0]\n : evt.touches[0];\n if (!tp) return;\n\n pos = toPos(tp, element);\n normEvt = {\n clientX: tp.clientX,\n clientY: tp.clientY,\n ctrlKey: evt.ctrlKey,\n shiftKey: evt.shiftKey,\n altKey: evt.altKey,\n metaKey: evt.metaKey,\n target: evt.target,\n currentTarget: evt.currentTarget,\n };\n } else {\n const pe = evt as PointerEvent;\n pos = toPos(pe, element);\n normEvt = pe;\n }\n\n active[handlerKey]?.(pos, normEvt, cap.getActiveMode());\n }\n\n /* ---------- teardown ----------------------------------------------------------- */\n return () => {\n removeListeners();\n stopMode();\n stopCursor();\n stopHandler();\n };\n}\n","import { ReactNode, useEffect, useRef, HTMLAttributes, CSSProperties } from '@framework';\nimport { createPointerProvider } from '../utils';\n\nimport { useInteractionManagerCapability } from '../hooks';\n\ninterface GlobalPointerProviderProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n style?: CSSProperties;\n}\n\nexport const GlobalPointerProvider = ({\n children,\n style,\n ...props\n}: GlobalPointerProviderProps) => {\n const ref = useRef<HTMLDivElement>(null);\n const { provides: cap } = useInteractionManagerCapability();\n\n useEffect(() => {\n if (!cap || !ref.current) return;\n\n return createPointerProvider(cap, { type: 'global' }, ref.current);\n }, [cap]);\n\n return (\n <div\n ref={ref}\n style={{\n width: '100%',\n height: '100%',\n ...style,\n }}\n {...props}\n >\n {children}\n </div>\n );\n};\n","import {\n ReactNode,\n useEffect,\n useRef,\n useCallback,\n HTMLAttributes,\n CSSProperties,\n} from '@framework';\nimport { Position, restorePosition } from '@embedpdf/models';\nimport { createPointerProvider } from '../utils';\n\nimport { useInteractionManagerCapability, useIsPageExclusive } from '../hooks';\n\ninterface PagePointerProviderProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n pageIndex: number;\n pageWidth: number;\n pageHeight: number;\n rotation: number;\n scale: number;\n style?: CSSProperties;\n convertEventToPoint?: (event: PointerEvent, element: HTMLElement) => Position;\n}\n\nexport const PagePointerProvider = ({\n pageIndex,\n children,\n pageWidth,\n pageHeight,\n rotation,\n scale,\n convertEventToPoint,\n style,\n ...props\n}: PagePointerProviderProps) => {\n const ref = useRef<HTMLDivElement>(null);\n const { provides: cap } = useInteractionManagerCapability();\n const isPageExclusive = useIsPageExclusive();\n\n // Memoize the default conversion function\n const defaultConvertEventToPoint = useCallback(\n (event: PointerEvent, element: HTMLElement): Position => {\n const rect = element.getBoundingClientRect();\n const displayPoint = {\n x: event.clientX - rect.left,\n y: event.clientY - rect.top,\n };\n return restorePosition(\n { width: pageWidth, height: pageHeight },\n displayPoint,\n rotation,\n scale,\n );\n },\n [pageWidth, pageHeight, rotation, scale],\n );\n\n useEffect(() => {\n if (!cap || !ref.current) return;\n\n return createPointerProvider(\n cap,\n { type: 'page', pageIndex },\n ref.current,\n convertEventToPoint || defaultConvertEventToPoint,\n );\n }, [cap, pageIndex, convertEventToPoint, defaultConvertEventToPoint]);\n\n return (\n <div\n ref={ref}\n style={{\n ...style,\n }}\n {...props}\n >\n {children}\n {isPageExclusive && (\n <div style={{ position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, zIndex: 10 }} />\n )}\n </div>\n );\n};\n"],"names":["useInteractionManagerCapability","useCapability","InteractionManagerPlugin","id","useIsPageExclusive","provides","cap","isPageExclusive","setIsPageExclusive","useState","m","getActiveInteractionMode","scope","exclusive","useEffect","onModeChange","mode","domEventMap","pointerdown","pointerup","pointermove","pointerenter","pointerleave","pointercancel","mousedown","mouseup","mousemove","mouseenter","mouseleave","mousecancel","click","dblclick","touchstart","touchend","touchmove","touchcancel","allEventTypes","createPointerProvider","element","convertEventToPoint","active","getHandlersForScope","wantsRawTouchNow","_a","wantsRawTouch","listeners","attachedWithRawTouch","addListeners","raw","forEach","type","fn","handleEvent","addEventListener","startsWith","passive","removeListeners","removeEventListener","stopMode","style","cursor","stopHandler","onHandlerChange","initialMode","initialCursor","getCurrentCursor","stopCursor","onCursorChange","c","toPos","e","host","r","getBoundingClientRect","x","clientX","left","y","clientY","top","evt","isPaused","handlerKey","pos","normEvt","TouchEvent","preventDefault","tp","changedTouches","touches","ctrlKey","shiftKey","altKey","metaKey","target","currentTarget","pe","call","getActiveMode","children","props","ref","useRef","current","jsxRuntime","jsx","width","height","pageIndex","pageWidth","pageHeight","rotation","scale","defaultConvertEventToPoint","useCallback","event","rect","displayPoint","restorePosition","jsxs","position","right","bottom","zIndex","setCursor","token","prio","removeCursor","state","setState","initialState","onStateChange","usePlugin","modeId","register","handlers","options","finalModeId","finalPageIndex","registerHandlers","registerAlways"],"mappings":"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"}
|