@embedpdf/plugin-interaction-manager 1.0.12 → 1.0.14
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 +3 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/types.d.ts +2 -0
- package/dist/preact/index.cjs +1 -1
- package/dist/preact/index.cjs.map +1 -1
- package/dist/preact/index.js +3 -1
- 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 +3 -1
- package/dist/react/index.js.map +1 -1
- package/dist/vue/index.cjs +1 -1
- package/dist/vue/index.cjs.map +1 -1
- package/dist/vue/index.js +3 -1
- package/dist/vue/index.js.map +1 -1
- package/package.json +4 -4
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",r="INTERACTION/SET_CURSOR";const o=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:"default",scope:"page",exclusive:!1,cursor:"auto"})}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(),finish:()=>this.activate("default"),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}}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})}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],r=[];for(const o of s){const e=this.buckets.get(o);if(!e)throw new Error(`unknown mode '${o}'`);if(null==a)e.global.add(t);else{const s=e.page.get(a)??new Set;s.add(t),e.page.set(a,s)}r.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}),()=>{r.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"],a={};for(const s of t)a[s]=(t,a,r)=>{var o;for(const i of e)null==(o=i[s])||o.call(i,t,a,r)};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:r,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()}};o.id="interaction-manager";let i=o;const n="interaction-manager",l={id:n,name:"Interaction Manager Plugin",version:"1.0.0",provides:["interaction-manager"],requires:[],optional:[],defaultConfig:{enabled:!0}},c={activeMode:"default",cursor:"auto",paused:!1},h=(e,o)=>{switch(o.type){case t:return{...e,activeMode:o.payload.mode};case r:return{...e,cursor:o.payload.cursor};case a:return{...e,paused:!0};case s:return{...e,paused:!1};default:return e}},d={manifest:l,create:e=>new i(n,e),reducer:h,initialState:c};exports.INTERACTION_MANAGER_PLUGIN_ID=n,exports.InteractionManagerPlugin=i,exports.InteractionManagerPluginPackage=d,exports.initialState=c,exports.manifest=l,exports.reducer=h;
|
|
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",r="INTERACTION/SET_CURSOR";const o=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:"default",scope:"page",exclusive:!1,cursor:"auto"})}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(),finish:()=>this.activate("default"),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}}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})}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],r=[];for(const o of s){const e=this.buckets.get(o);if(!e)throw new Error(`unknown mode '${o}'`);if(null==a)e.global.add(t);else{const s=e.page.get(a)??new Set;s.add(t),e.page.set(a,s)}r.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}),()=>{r.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","onClick","onDoubleClick"],a={};for(const s of t)a[s]=(t,a,r)=>{var o;for(const i of e)null==(o=i[s])||o.call(i,t,a,r)};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:r,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()}};o.id="interaction-manager";let i=o;const n="interaction-manager",l={id:n,name:"Interaction Manager Plugin",version:"1.0.0",provides:["interaction-manager"],requires:[],optional:[],defaultConfig:{enabled:!0}},c={activeMode:"default",cursor:"auto",paused:!1},h=(e,o)=>{switch(o.type){case t:return{...e,activeMode:o.payload.mode};case r:return{...e,cursor:o.payload.cursor};case a:return{...e,paused:!0};case s:return{...e,paused:!1};default:return e}},d={manifest:l,create:e=>new i(n,e),reducer:h,initialState:c};exports.INTERACTION_MANAGER_PLUGIN_ID=n,exports.InteractionManagerPlugin=i,exports.InteractionManagerPluginPackage=d,exports.initialState=c,exports.manifest=l,exports.reducer=h;
|
|
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 ];\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":"kHAEaA,EAAgB,4BAChBC,EAAoB,oBACpBC,EAAqB,qBACrBC,EAAa,yBC0BnB,MAAMC,EAAN,cAAuCC,EAAAA,WAmB5C,WAAAC,CAAYC,EAAYC,GACtBC,MAAMF,EAAIC,GAbJE,KAAAC,UAAYC,IACZF,KAAAG,iBAAmBD,IACnBF,KAAAI,YAAcF,IAEdF,KAAAK,iBAAmBC,IACnBN,KAAAO,eAAiBL,IAERF,KAAAQ,cAAgBC,kBAChBT,KAAAU,iBAAmBD,kBACnBT,KAAAW,gBAAkBF,kBAClBT,KAAAY,eAAiBC,0BAKhCb,KAAKc,aAAa,CAChBjB,GAAI,UACJkB,MAAO,OACPC,WAAW,EACXC,OAAQ,QACT,CAGH,gBAAMC,CAAWC,GAAkD,CAEzD,eAAAC,GACD,MAAA,CACLC,SAAWC,GAAmBtB,KAAKqB,SAASC,GAC5CC,aAAcvB,KAAKQ,cAAcgB,GACjCC,eAAgBzB,KAAKW,gBAAgBa,GACrCE,gBAAiB1B,KAAKU,iBAAiBc,GACvCG,cAAe3B,KAAKY,eAAeY,GACnCI,cAAe,IAAM5B,KAAK6B,MAAMC,WAChCC,yBAA0B,IAAM/B,KAAK+B,2BACrCC,OAAQ,IAAMhC,KAAKqB,SAAS,WAC5BP,aAAemB,GAA0BjC,KAAKc,aAAamB,GAC3DC,iBAAmBC,GAAqCnC,KAAKkC,iBAAiBC,GAC9EC,eAAiBD,GAAmCnC,KAAKoC,eAAeD,GACxEE,UAAW,CAACC,EAAerB,EAAgBsB,EAAW,IACpDvC,KAAKqC,UAAUC,EAAOrB,EAAQsB,GAChCC,aAAeF,GAAkBtC,KAAKwC,aAAaF,GACnDG,iBAAkB,IAAMzC,KAAK6B,MAAMZ,OACnCyB,oBAAsB3B,GAA4Bf,KAAK0C,oBAAoB3B,GAC3E4B,sBAAuB,IAAM3C,KAAK2C,wBAClCC,MAAO,IAAM5C,KAAK6C,SD/CuC,CAC7DC,KAAMvD,IC+CFwD,OAAQ,IAAM/C,KAAK6C,SD5CwC,CAC/DC,KAAMtD,IC4CFwD,SAAU,IAAMhD,KAAK6B,MAAMoB,OAC7B,CAGM,QAAA5B,CAASY,GACf,IAAKjC,KAAKC,MAAMiD,IAAIjB,GAClB,MAAM,IAAIkB,MAAM,+BAA+BlB,MAE7C,GAAAA,IAASjC,KAAK6B,MAAMC,WAAY,OAE9B,MAAAsB,EAAepD,KAAK6B,MAAMC,WAChC9B,KAAKG,aAAakD,QAElBrD,KAAKsD,uBAAuBF,GAEvBpD,KAAA6C,SD1EmB,CAACZ,IAAsC,CACjEa,KAAMxD,EACNiE,QAAS,CAAEtB,UCwEKuB,CAAavB,IAC3BjC,KAAKyD,aAGLzD,KAAK0D,qBAAqBzB,GAErBjC,KAAAQ,cAAcmD,KAAK,IAAK3D,KAAK6B,MAAOC,WAAYG,GAAM,CAGrD,oBAAAyB,CAAqBpC,GACtBtB,KAAAK,aAAauD,SAASC,UACzB,OAAAC,EAAAD,EAAQE,uBAAuBD,EAAAE,KAAAH,EAAAvC,EAAA,IAG5BtB,KAAAO,WAAWqD,SAASK,IACZA,EAAAL,SAASC,UAClB,OAAAC,EAAAD,EAAQE,uBAAuBD,EAAAE,KAAAH,EAAAvC,EAAA,GAChC,IAGH,MAAMW,EAAOjC,KAAKC,MAAMiE,IAAI5C,GAC5B,IAAKW,EAAM,OAEX,MAAMkC,EAASnE,KAAKI,QAAQ8D,IAAI5C,GAC3B6C,IAGc,WAAflC,EAAKlB,OACAoD,EAAAC,OAAOR,SAASC,UACrB,OAAAC,EAAAD,EAAQE,uBAAuBD,EAAAE,KAAAH,EAAAvC,EAAA,IAKhB,SAAfW,EAAKlB,OACPoD,EAAOE,KAAKT,SAAQ,CAACK,EAAYK,KACpBL,EAAAL,SAASC,UAClB,OAAAC,EAAAD,EAAQE,uBAAuBD,EAAAE,KAAAH,EAAAvC,EAAA,GAChC,IAEL,CAGM,sBAAAgC,CAAuBhC,GACxBtB,KAAAK,aAAauD,SAASC,UACzB,OAAAC,EAAAD,EAAQU,qBAAqBT,EAAAE,KAAAH,EAAAvC,EAAA,IAG1BtB,KAAAO,WAAWqD,SAASK,IACZA,EAAAL,SAASC,UAClB,OAAAC,EAAAD,EAAQU,qBAAqBT,EAAAE,KAAAH,EAAAvC,EAAA,GAC9B,IAGH,MAAMW,EAAOjC,KAAKC,MAAMiE,IAAI5C,GAC5B,IAAKW,EAAM,OAEX,MAAMkC,EAASnE,KAAKI,QAAQ8D,IAAI5C,GAC3B6C,IAGc,WAAflC,EAAKlB,OACAoD,EAAAC,OAAOR,SAASC,UACrB,OAAAC,EAAAD,EAAQU,qBAAqBT,EAAAE,KAAAH,EAAAvC,EAAA,IAKd,SAAfW,EAAKlB,OACPoD,EAAOE,KAAKT,SAAQ,CAACK,EAAYK,KACpBL,EAAAL,SAASC,UAClB,OAAAC,EAAAD,EAAQU,qBAAqBT,EAAAE,KAAAH,EAAAvC,EAAA,GAC9B,IAEL,CAGM,YAAAR,CAAamB,GACnBjC,KAAKC,MAAMuE,IAAIvC,EAAKpC,GAAIoC,GACnBjC,KAAKI,QAAQ8C,IAAIjB,EAAKpC,KACzBG,KAAKI,QAAQoE,IAAIvC,EAAKpC,GAAI,CAAEuE,OAAY,IAAA9D,IAAO+D,KAAU,IAAAnE,KAC3D,CAIM,gBAAAgC,EAAiBZ,OAAEA,EAAQmD,SAAAA,EAAAH,UAAUA,IAC3C,MAAMI,EAAUC,MAAMC,QAAQtD,GAAUA,EAAS,CAACA,GAC5CuD,EAAmC,GAEzC,IAAA,MAAWhF,KAAM6E,EAAS,CACxB,MAAMP,EAASnE,KAAKI,QAAQ8D,IAAIrE,GAChC,IAAKsE,EAAQ,MAAM,IAAIhB,MAAM,iBAAiBtD,MAE9C,GAAiB,MAAbyE,EACKH,EAAAC,OAAOU,IAAIL,OACb,CACL,MAAMD,EAAML,EAAOE,KAAKH,IAAII,QAAkBhE,IAC9CkE,EAAIM,IAAIL,GACDN,EAAAE,KAAKG,IAAIF,EAAWE,EAAG,CAIhCK,EAAiBE,MAAK,KACpB,GAAiB,MAAbT,EACKH,EAAAC,OAAOY,OAAOP,OAChB,CACL,MAAMD,EAAML,EAAOE,KAAKH,IAAII,GACxBE,IACFA,EAAIQ,OAAOP,GACM,IAAbD,EAAIS,MACCd,EAAAE,KAAKW,OAAOV,GAEvB,IAEH,CAMH,OAHAtE,KAAKU,iBAAiBiD,KAAK,IAAK3D,KAAK6B,QAG9B,KACLgD,EAAiBjB,SAASsB,GAAYA,MACtClF,KAAKU,iBAAiBiD,KAAK,IAAK3D,KAAK6B,OAAO,CAC9C,CAGK,cAAAO,EAAerB,MAAEA,EAAO0D,SAAAA,IACzB,GAAe,WAAf1D,EAAM+B,KAGR,OAFK9C,KAAAK,aAAayE,IAAIL,GACtBzE,KAAKU,iBAAiBiD,KAAK,IAAK3D,KAAK6B,QAC9B,IAAM7B,KAAKK,aAAa2E,OAAOP,GAElC,MAAAD,EAAMxE,KAAKO,WAAW2D,IAAInD,EAAMuD,gBAAkBhE,IAIxD,OAHAkE,EAAIM,IAAIL,GACRzE,KAAKO,WAAWiE,IAAIzD,EAAMuD,UAAWE,GACrCxE,KAAKU,iBAAiBiD,KAAK,IAAK3D,KAAK6B,QAC9B,KACL2C,EAAIQ,OAAOP,GACXzE,KAAKU,iBAAiBiD,KAAK,IAAK3D,KAAK6B,OAAO,CAC9C,CAQM,mBAAAa,CAAoB3B,GACtB,IAACf,KAAK6B,MAAc,OAAA,KAExB,MAAMI,EAAOjC,KAAKC,MAAMiE,IAAIlE,KAAK6B,MAAMC,YACnC,IAACG,EAAa,OAAA,KAElB,MAAMkC,EAASnE,KAAKI,QAAQ8D,IAAIjC,EAAKpC,IACjC,IAACsE,EAAe,OAAA,KAGpB,MAAMgB,EAAY,CAACC,EAAeC,IAChCD,EAAEH,MAAQI,EAAEJ,KC/PX,SAAuBK,GAC5B,MAAMC,EAAuC,CAC3C,gBACA,cACA,gBACA,iBACA,iBACA,mBAEIC,EAAqC,CAAC,EAC5C,IAAA,MAAWC,KAAKF,EACdC,EAAIC,GAAK,CAACC,EAAUC,EAAgBrE,WAClC,IAAA,MAAWsE,KAAKN,EAAM,OAAAxB,EAAA8B,EAAEH,KAAF3B,EAAAE,KAAA4B,EAAOF,EAAKC,EAAWrE,EAAA,EAG1C,OAAAkE,CACT,CD+OyBK,CAAc,IAAIT,KAAMC,IAAM,KAG/C,GAAe,WAAftE,EAAM+B,KAAmB,CAC3B,MAAMgD,EACW,WAAf7D,EAAKlB,MACDoD,EAAOC,WACH9D,IACH,OAAA6E,EAAUnF,KAAKK,aAAcyF,EAAY,CAU3C,OAAAX,EANenF,KAAKO,WAAW2D,IAAInD,EAAMuD,gBAAkBhE,IAEjD,SAAf2B,EAAKlB,MACAoD,EAAOE,KAAKH,IAAInD,EAAMuD,YAAc,IAAIhE,QACrCA,IAEiC,CAIrC,SAAA+B,CAAUC,EAAerB,EAAgBsB,EAAW,GAC1DvC,KAAKG,aAAaqE,IAAIlC,EAAO,CAAErB,SAAQsB,aACvCvC,KAAKyD,YAAW,CAEV,YAAAjB,CAAaF,GACdtC,KAAAG,aAAa6E,OAAO1C,GACzBtC,KAAKyD,YAAW,CAGV,UAAAA,SAEN,MAAMsC,EAAM,IAAI/F,KAAKG,aAAa6F,UAAUC,MAAK,CAACb,EAAGC,IAAMA,EAAE9C,SAAW6C,EAAE7C,WAAU,IAAM,CACxFtB,QAAQ,OAAA6C,OAAK7D,MAAMiE,IAAIlE,KAAK6B,MAAMC,kBAA1B,EAAAgC,EAAuC7C,SAAU,QDrQtC,IAACA,ECwQlB8E,EAAI9E,SAAWjB,KAAK6B,MAAMZ,SAC5BjB,KAAK6C,UDzQe5B,ECyQI8E,EAAI9E,ODzQ6B,CAC7D6B,KAAMrD,EACN8D,QAAS,CAAEtC,aCwQFjB,KAAAW,gBAAgBgD,KAAKoC,EAAI9E,QAChC,CAGO,cAAAiF,CAAe/E,EAA4BgF,GAC7CnG,KAAAY,eAAe+C,KAAKwC,EAAQ,CAG3B,qBAAAxD,GACN,MAAMV,EAAOjC,KAAKC,MAAMiE,IAAIlE,KAAK6B,MAAMC,YAChC,SAAQ,MAANG,OAAM,EAAAA,EAAAjB,UAAA,CAGT,wBAAAe,GACN,OAAO/B,KAAKC,MAAMiE,IAAIlE,KAAK6B,MAAMC,aAAe,IAAA,CAIlD,aAAMsE,GACJpG,KAAKQ,cAAc6C,QACnBrD,KAAKW,gBAAgB0C,cACftD,MAAMqG,SAAQ,GAzRtB1G,EAAgBG,GAAK,sBALhB,IAAMwG,EAAN3G,EE5BA,MAAM4G,EAAgC,sBAEhCC,EAA2D,CACtE1G,GAAIyG,EACJE,KAAM,6BACNC,QAAS,QACTC,SAAU,CAAC,uBACXC,SAAU,GACVC,SAAU,GACVC,cAAe,CACbC,SAAS,ICHAC,EAAwC,CACnDjF,WAAY,UACZb,OAAQ,OACRgC,QAAQ,GAGG+D,EAAsE,CACjFnF,EACAoF,KAEA,OAAQA,EAAOnE,MACb,KAAKxD,EACI,MAAA,IACFuC,EACHC,WAAYmF,EAAO1D,QAAQtB,MAE/B,KAAKxC,EACI,MAAA,IACFoC,EACHZ,OAAQgG,EAAO1D,QAAQtC,QAE3B,KAAK1B,EACI,MAAA,IACFsC,EACHoB,QAAQ,GAEZ,KAAKzD,EACI,MAAA,IACFqC,EACHoB,QAAQ,GAEZ,QACS,OAAApB,EAAA,EClCAqF,EAKT,CACFX,WACAY,OAASrH,GAAa,IAAIuG,EAAyBC,EAA+BxG,GAClFkH,UACAD"}
|
|
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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"}
|
package/dist/index.js
CHANGED
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 ];\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":"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"}
|
|
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":"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"}
|
package/dist/lib/types.d.ts
CHANGED
|
@@ -36,6 +36,8 @@ export interface PointerEventHandlers<T = EmbedPdfPointerEvent> {
|
|
|
36
36
|
onPointerEnter?(pos: Position, evt: T, modeId: string): void;
|
|
37
37
|
onPointerLeave?(pos: Position, evt: T, modeId: string): void;
|
|
38
38
|
onPointerCancel?(pos: Position, evt: T, modeId: string): void;
|
|
39
|
+
onClick?(pos: Position, evt: T, modeId: string): void;
|
|
40
|
+
onDoubleClick?(pos: Position, evt: T, modeId: string): void;
|
|
39
41
|
}
|
|
40
42
|
export interface PointerEventHandlersWithLifecycle<T = EmbedPdfPointerEvent> extends PointerEventHandlers<T> {
|
|
41
43
|
onHandlerActiveStart?(modeId: string): void;
|
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"),n=require("preact/hooks"),r=require("preact/jsx-runtime"),o=require("@embedpdf/models"),i=()=>e.useCapability(t.InteractionManagerPlugin.id);function l(){const{provides:e}=i(),[t,r]=n.useState((()=>{const t=null==e?void 0:e.getActiveInteractionMode();return"page"===(null==t?void 0:t.scope)&&!!t.exclusive}));return n.useEffect((()=>{if(e)return e.onModeChange((()=>{const t=e.getActiveInteractionMode();r("page"===(null==t?void 0:t.scope)&&!!(null==t?void 0:t.exclusive))}))}),[e]),t}function s(e,t,n,r){let o=e.getHandlersForScope(t);const i=e.onModeChange((()=>{if("global"===t.type){const t=e.getActiveInteractionMode();n.style.cursor="global"===(null==t?void 0:t.scope)?t.cursor??"auto":"auto"}o=e.getHandlersForScope(t)})),l=e.onHandlerChange((()=>{o=e.getHandlersForScope(t)})),s=e.getActiveInteractionMode(),u=e.getCurrentCursor();"global"===t.type?n.style.cursor="global"===(null==s?void 0:s.scope)?u:"auto":n.style.cursor=u;const c=e.onCursorChange((r=>{var o;if("global"===t.type){if(!("global"===(null==(o=e.getActiveInteractionMode())?void 0:o.scope)))return}n.style.cursor=r})),a={onPointerDown:"pointerdown",onPointerUp:"pointerup",onPointerMove:"pointermove",onPointerEnter:"pointerenter",onPointerLeave:"pointerleave",onPointerCancel:"pointercancel",onClick:"click",onDoubleClick:"dblclick"},d={};return Object.keys(a).forEach((t=>{d[t]=i=>{var l;if(e.isPaused())return;const s=i,u=e.getActiveMode();null==(l=null==o?void 0:o[t])||l.call(o,((e,t)=>{if(r)return r(e,t);const n=t.getBoundingClientRect();return{x:e.clientX-n.left,y:e.clientY-n.top}})(s,n),s,u)},n.addEventListener(a[t],d[t])})),()=>{Object.keys(a).forEach((e=>n.removeEventListener(a[e],d[e]))),i(),c(),l()}}exports.GlobalPointerProvider=({children:e,style:t,...o})=>{const l=n.useRef(null),{provides:u}=i();return n.useEffect((()=>{if(u&&l.current)return s(u,{type:"global"},l.current)}),[u]),r.jsx("div",{ref:l,style:{width:"100%",height:"100%",...t},...o,children:e})},exports.PagePointerProvider=({pageIndex:e,children:t,pageWidth:u,pageHeight:c,rotation:a,scale:d,convertEventToPoint:p,style:g,...v})=>{const f=n.useRef(null),{provides:x}=i(),y=l(),b=n.useCallback(((e,t)=>{const n=t.getBoundingClientRect(),r={x:e.clientX-n.left,y:e.clientY-n.top};return o.restorePosition({width:u,height:c},r,a,d)}),[u,c,a,d]);return n.useEffect((()=>{if(x&&f.current)return s(x,{type:"page",pageIndex:e},f.current,p||b)}),[x,e,p,b]),r.jsxs("div",{ref:f,style:{...g},...v,children:[t,y&&r.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,n,r=0)=>{null==e||e.setCursor(t,n,r)},removeCursor:t=>{null==e||e.removeCursor(t)}}},exports.useInteractionManager=function(){const{provides:e}=i(),[r,o]=n.useState(t.initialState);return n.useEffect((()=>{if(e)return e.onStateChange((e=>{o(e)}))}),[e]),{provides:e,state:r}},exports.useInteractionManagerCapability=i,exports.useInteractionManagerPlugin=()=>e.usePlugin(t.InteractionManagerPlugin.id),exports.useIsPageExclusive=l,exports.usePointerHandlers=function({modeId:e,pageIndex:t}){const{provides:n}=i();return{register:(r,o)=>{const i=(null==o?void 0:o.modeId)??e,l=(null==o?void 0:o.pageIndex)??t;return i?null==n?void 0:n.registerHandlers({modeId:i,handlers:r,pageIndex:l}):null==n?void 0:n.registerAlways({scope:void 0!==l?{type:"page",pageIndex:l}:{type:"global"},handlers:r})}}};
|
|
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 };\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","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":"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"}
|
|
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"}
|
package/dist/preact/index.js
CHANGED
|
@@ -95,7 +95,9 @@ function createPointerProvider(cap, scope, element, convertEventToPoint) {
|
|
|
95
95
|
onPointerMove: "pointermove",
|
|
96
96
|
onPointerEnter: "pointerenter",
|
|
97
97
|
onPointerLeave: "pointerleave",
|
|
98
|
-
onPointerCancel: "pointercancel"
|
|
98
|
+
onPointerCancel: "pointercancel",
|
|
99
|
+
onClick: "click",
|
|
100
|
+
onDoubleClick: "dblclick"
|
|
99
101
|
};
|
|
100
102
|
const listeners = {};
|
|
101
103
|
const toPos = (e, host) => {
|
package/dist/preact/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","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 };\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":["state"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","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":["state"],"mappings":";;;;;AAUO,MAAM,8BAA8B,MACzC,UAAoC,yBAAyB,EAAE;AAC1D,MAAM,kCAAkC,MAC7C,cAAwC,yBAAyB,EAAE;AAE9D,SAAS,wBAAwB;AAChC,QAAA,EAAE,SAAS,IAAI,gCAAgC;AACrD,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAkC,YAAY;AAExE,YAAU,MAAM;AACd,QAAI,CAAC,SAAU;AACR,WAAA,SAAS,cAAc,CAACA,WAAU;AACvC,eAASA,MAAK;AAAA,IAAA,CACf;AAAA,EAAA,GACA,CAAC,QAAQ,CAAC;AAEN,SAAA;AAAA,IACL;AAAA,IACA;AAAA,EACF;AACF;AAEO,SAAS,YAAY;AACpB,QAAA,EAAE,SAAS,IAAI,gCAAgC;AAC9C,SAAA;AAAA,IACL,WAAW,CAAC,OAAe,QAAgB,OAAO,MAAM;AAC5C,2CAAA,UAAU,OAAO,QAAQ;AAAA,IACrC;AAAA,IACA,cAAc,CAAC,UAAkB;AAC/B,2CAAU,aAAa;AAAA,IAAK;AAAA,EAEhC;AACF;AAOO,SAAS,mBAAmB,EAAE,QAAQ,aAAwC;AAC7E,QAAA,EAAE,SAAS,IAAI,gCAAgC;AAC9C,SAAA;AAAA,IACL,UAAU,CACR,UACA,YACG;AAEG,YAAA,eAAc,mCAAS,WAAU;AACjC,YAAA,kBAAiB,mCAAS,cAAa;AAEtC,aAAA,cACH,qCAAU,iBAAiB;AAAA,QACzB,QAAQ;AAAA,QACR;AAAA,QACA,WAAW;AAAA,MAAA,KAEb,qCAAU,eAAe;AAAA,QACvB,OACE,mBAAmB,SACf,EAAE,MAAM,QAAQ,WAAW,eAAe,IAC1C,EAAE,MAAM,SAAS;AAAA,QACvB;AAAA,MAAA;AAAA,IACD;AAAA,EAET;AACF;AAEO,SAAS,qBAAqB;AACnC,QAAM,EAAE,UAAU,IAAI,IAAI,gCAAgC;AAE1D,QAAM,CAAC,iBAAiB,kBAAkB,IAAI,SAAkB,MAAM;AAC9D,UAAA,IAAI,2BAAK;AACf,YAAO,uBAAG,WAAU,UAAU,CAAC,CAAC,EAAE;AAAA,EAAA,CACnC;AAED,YAAU,MAAM;AACd,QAAI,CAAC,IAAK;AAEH,WAAA,IAAI,aAAa,MAAM;AACtB,YAAA,OAAO,IAAI,yBAAyB;AAC1C,0BAAmB,6BAAM,WAAU,UAAU,CAAC,EAAC,6BAAM,UAAS;AAAA,IAAA,CAC/D;AAAA,EAAA,GACA,CAAC,GAAG,CAAC;AAED,SAAA;AACT;ACnFO,SAAS,sBACd,KACA,OACA,SACA,qBACA;AAII,MAAA,SAAsC,IAAI,oBAAoB,KAAK;AAEjE,QAAA,WAAW,IAAI,aAAa,MAAM;AAClC,QAAA,MAAM,SAAS,UAAU;AACrB,YAAA,OAAO,IAAI,yBAAyB;AAC1C,cAAQ,MAAM,UAAS,6BAAM,WAAU,WAAY,KAAK,UAAU,SAAU;AAAA,IAAA;AAErE,aAAA,IAAI,oBAAoB,KAAK;AAAA,EAAA,CACvC;AAEK,QAAA,cAAc,IAAI,gBAAgB,MAAM;AACnC,aAAA,IAAI,oBAAoB,KAAK;AAAA,EAAA,CACvC;AAKK,QAAA,UAAU,IAAI,yBAAyB;AACvC,QAAA,YAAY,IAAI,iBAAiB;AAGnC,MAAA,MAAM,SAAS,UAAU;AAE3B,YAAQ,MAAM,UAAS,mCAAS,WAAU,WAAW,YAAY;AAAA,EAAA,OAC5D;AAEL,YAAQ,MAAM,SAAS;AAAA,EAAA;AAGzB,QAAM,aAAa,IAAI,eAAe,CAAC,MAAM;;AAOvC,QAAA,MAAM,SAAS,UAAU;AAC3B,YAAM,iBAAe,SAAI,yBAAyB,MAA7B,mBAAgC,WAAU;AAC/D,UAAI,CAAC,aAAc;AAAA,IAAA;AAErB,YAAQ,MAAM,SAAS;AAAA,EAAA,CACxB;AAMD,QAAM,WAAiD;AAAA,IACrD,eAAe;AAAA,IACf,aAAa;AAAA,IACb,eAAe;AAAA,IACf,gBAAgB;AAAA,IAChB,gBAAgB;AAAA,IAChB,iBAAiB;AAAA,IACjB,SAAS;AAAA,IACT,eAAe;AAAA,EACjB;AAGA,QAAM,YAA+C,CAAC;AAEhD,QAAA,QAAQ,CAAC,GAAiB,SAAgC;AAC9D,QAAI,oBAAqB,QAAO,oBAAoB,GAAG,IAAI;AACrD,UAAA,IAAI,KAAK,sBAAsB;AAC9B,WAAA,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,GAAG,EAAE,UAAU,EAAE,IAAI;AAAA,EACvD;AAEC,SAAO,KAAK,QAAQ,EAAU,QAAQ,CAAC,MAAM;AAClC,cAAA,CAAC,IAAI,CAAC,QAAe;;AACzB,UAAA,IAAI,WAAY;AAEpB,YAAM,KAAK;AACL,YAAA,gBAAgB,IAAI,cAAc;AACxC,6CAAS,OAAT,gCAAc,MAAM,IAAI,OAAO,GAAG,IAAI;AAAA,IAGxC;AACA,YAAQ,iBAAiB,SAAS,CAAC,GAAG,UAAU,CAAC,CAAE;AAAA,EAAA,CACpD;AAKD,SAAO,MAAM;AACV,WAAO,KAAK,QAAQ,EAAU;AAAA,MAAQ,CAAC,MACtC,QAAQ,oBAAoB,SAAS,CAAC,GAAG,UAAU,CAAC,CAAE;AAAA,IACxD;AACS,aAAA;AACE,eAAA;AACC,gBAAA;AAAA,EACd;AACF;ACtGO,MAAM,wBAAwB,CAAC;AAAA,EACpC;AAAA,EACA;AAAA,EACA,GAAG;AACL,MAAkC;AAC1B,QAAA,MAAM,OAAuB,IAAI;AACvC,QAAM,EAAE,UAAU,IAAI,IAAI,gCAAgC;AAE1D,YAAU,MAAM;AACd,QAAI,CAAC,OAAO,CAAC,IAAI,QAAS;AAE1B,WAAO,sBAAsB,KAAK,EAAE,MAAM,SAAS,GAAG,IAAI,OAAO;AAAA,EAAA,GAChE,CAAC,GAAG,CAAC;AAGN,SAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACC;AAAA,MACA,OAAO;AAAA,QACL,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,GAAG;AAAA,MACL;AAAA,MACC,GAAG;AAAA,MAEH;AAAA,IAAA;AAAA,EACH;AAEJ;ACbO,MAAM,sBAAsB,CAAC;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,MAAgC;AACxB,QAAA,MAAM,OAAuB,IAAI;AACvC,QAAM,EAAE,UAAU,IAAI,IAAI,gCAAgC;AAC1D,QAAM,kBAAkB,mBAAmB;AAG3C,QAAM,6BAA6B;AAAA,IACjC,CAAC,OAAqB,YAAmC;AACjD,YAAA,OAAO,QAAQ,sBAAsB;AAC3C,YAAM,eAAe;AAAA,QACnB,GAAG,MAAM,UAAU,KAAK;AAAA,QACxB,GAAG,MAAM,UAAU,KAAK;AAAA,MAC1B;AACO,aAAA;AAAA,QACL,EAAE,OAAO,WAAW,QAAQ,WAAW;AAAA,QACvC;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,IACA,CAAC,WAAW,YAAY,UAAU,KAAK;AAAA,EACzC;AAEA,YAAU,MAAM;AACd,QAAI,CAAC,OAAO,CAAC,IAAI,QAAS;AAEnB,WAAA;AAAA,MACL;AAAA,MACA,EAAE,MAAM,QAAQ,UAAU;AAAA,MAC1B,IAAI;AAAA,MACJ,uBAAuB;AAAA,IACzB;AAAA,KACC,CAAC,KAAK,WAAW,qBAAqB,0BAA0B,CAAC;AAGlE,SAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACC;AAAA,MACA,OAAO;AAAA,QACL,GAAG;AAAA,MACL;AAAA,MACC,GAAG;AAAA,MAEH,UAAA;AAAA,QAAA;AAAA,QACA,mBACE,oBAAA,OAAA,EAAI,OAAO,EAAE,UAAU,YAAY,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,KAAM,CAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAE5F;AAEJ;"}
|
package/dist/react/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("@embedpdf/core/react"),t=require("@embedpdf/plugin-interaction-manager"),
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("@embedpdf/core/react"),t=require("@embedpdf/plugin-interaction-manager"),n=require("react"),r=require("react/jsx-runtime"),o=require("@embedpdf/models"),i=()=>e.useCapability(t.InteractionManagerPlugin.id);function l(){const{provides:e}=i(),[t,r]=n.useState((()=>{const t=null==e?void 0:e.getActiveInteractionMode();return"page"===(null==t?void 0:t.scope)&&!!t.exclusive}));return n.useEffect((()=>{if(e)return e.onModeChange((()=>{const t=e.getActiveInteractionMode();r("page"===(null==t?void 0:t.scope)&&!!(null==t?void 0:t.exclusive))}))}),[e]),t}function s(e,t,n,r){let o=e.getHandlersForScope(t);const i=e.onModeChange((()=>{if("global"===t.type){const t=e.getActiveInteractionMode();n.style.cursor="global"===(null==t?void 0:t.scope)?t.cursor??"auto":"auto"}o=e.getHandlersForScope(t)})),l=e.onHandlerChange((()=>{o=e.getHandlersForScope(t)})),s=e.getActiveInteractionMode(),u=e.getCurrentCursor();"global"===t.type?n.style.cursor="global"===(null==s?void 0:s.scope)?u:"auto":n.style.cursor=u;const c=e.onCursorChange((r=>{var o;if("global"===t.type){if(!("global"===(null==(o=e.getActiveInteractionMode())?void 0:o.scope)))return}n.style.cursor=r})),a={onPointerDown:"pointerdown",onPointerUp:"pointerup",onPointerMove:"pointermove",onPointerEnter:"pointerenter",onPointerLeave:"pointerleave",onPointerCancel:"pointercancel",onClick:"click",onDoubleClick:"dblclick"},d={};return Object.keys(a).forEach((t=>{d[t]=i=>{var l;if(e.isPaused())return;const s=i,u=e.getActiveMode();null==(l=null==o?void 0:o[t])||l.call(o,((e,t)=>{if(r)return r(e,t);const n=t.getBoundingClientRect();return{x:e.clientX-n.left,y:e.clientY-n.top}})(s,n),s,u)},n.addEventListener(a[t],d[t])})),()=>{Object.keys(a).forEach((e=>n.removeEventListener(a[e],d[e]))),i(),c(),l()}}exports.GlobalPointerProvider=({children:e,style:t,...o})=>{const l=n.useRef(null),{provides:u}=i();return n.useEffect((()=>{if(u&&l.current)return s(u,{type:"global"},l.current)}),[u]),r.jsx("div",{ref:l,style:{width:"100%",height:"100%",...t},...o,children:e})},exports.PagePointerProvider=({pageIndex:e,children:t,pageWidth:u,pageHeight:c,rotation:a,scale:d,convertEventToPoint:p,style:g,...v})=>{const f=n.useRef(null),{provides:x}=i(),y=l(),b=n.useCallback(((e,t)=>{const n=t.getBoundingClientRect(),r={x:e.clientX-n.left,y:e.clientY-n.top};return o.restorePosition({width:u,height:c},r,a,d)}),[u,c,a,d]);return n.useEffect((()=>{if(x&&f.current)return s(x,{type:"page",pageIndex:e},f.current,p||b)}),[x,e,p,b]),r.jsxs("div",{ref:f,style:{...g},...v,children:[t,y&&r.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,n,r=0)=>{null==e||e.setCursor(t,n,r)},removeCursor:t=>{null==e||e.removeCursor(t)}}},exports.useInteractionManager=function(){const{provides:e}=i(),[r,o]=n.useState(t.initialState);return n.useEffect((()=>{if(e)return e.onStateChange((e=>{o(e)}))}),[e]),{provides:e,state:r}},exports.useInteractionManagerCapability=i,exports.useInteractionManagerPlugin=()=>e.usePlugin(t.InteractionManagerPlugin.id),exports.useIsPageExclusive=l,exports.usePointerHandlers=function({modeId:e,pageIndex:t}){const{provides:n}=i();return{register:(r,o)=>{const i=(null==o?void 0:o.modeId)??e,l=(null==o?void 0:o.pageIndex)??t;return i?null==n?void 0:n.registerHandlers({modeId:i,handlers:r,pageIndex:l}):null==n?void 0:n.registerAlways({scope:void 0!==l?{type:"page",pageIndex:l}:{type:"global"},handlers:r})}}};
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
package/dist/react/index.cjs.map
CHANGED
|
@@ -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 };\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","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":"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"}
|
|
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":"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"}
|
package/dist/react/index.js
CHANGED
|
@@ -95,7 +95,9 @@ function createPointerProvider(cap, scope, element, convertEventToPoint) {
|
|
|
95
95
|
onPointerMove: "pointermove",
|
|
96
96
|
onPointerEnter: "pointerenter",
|
|
97
97
|
onPointerLeave: "pointerleave",
|
|
98
|
-
onPointerCancel: "pointercancel"
|
|
98
|
+
onPointerCancel: "pointercancel",
|
|
99
|
+
onClick: "click",
|
|
100
|
+
onDoubleClick: "dblclick"
|
|
99
101
|
};
|
|
100
102
|
const listeners = {};
|
|
101
103
|
const toPos = (e, host) => {
|
package/dist/react/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","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 };\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":["state"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","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":["state"],"mappings":"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"}
|
package/dist/vue/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("vue"),t=require("@embedpdf/core/vue"),o=require("@embedpdf/plugin-interaction-manager"),n=require("@embedpdf/models");function r(e,t,o,n){let r=e.getHandlersForScope(t);const l=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)})),i=e.onHandlerChange((()=>{r=e.getHandlersForScope(t)})),a=e.getActiveInteractionMode(),u=e.getCurrentCursor();"global"===t.type?o.style.cursor="global"===(null==a?void 0:a.scope)?u:"auto":o.style.cursor=u;const s=e.onCursorChange((n=>{var r;if("global"===t.type){if(!("global"===(null==(r=e.getActiveInteractionMode())?void 0:r.scope)))return}o.style.cursor=n})),c={onPointerDown:"pointerdown",onPointerUp:"pointerup",onPointerMove:"pointermove",onPointerEnter:"pointerenter",onPointerLeave:"pointerleave",onPointerCancel:"pointercancel"},d={};return Object.keys(c).forEach((t=>{d[t]=l=>{var i;if(e.isPaused())return;const a=l,u=e.getActiveMode();null==(i=null==r?void 0:r[t])||i.call(r,((e,t)=>{if(n)return n(e,t);const o=t.getBoundingClientRect();return{x:e.clientX-o.left,y:e.clientY-o.top}})(a,o),a,u)},o.addEventListener(c[t],d[t])})),()=>{Object.keys(c).forEach((e=>o.removeEventListener(c[e],d[e]))),l(),s(),i()}}const l=()=>t.useCapability(o.InteractionManagerPlugin.id);function i(){const{provides:t}=l(),o=e.ref(!1);return e.watchEffect((e=>{if(t.value){const n=t.value.getActiveInteractionMode();o.value="page"===(null==n?void 0:n.scope)&&!!(null==n?void 0:n.exclusive);e(t.value.onModeChange((()=>{if(!t.value)return;const e=t.value.getActiveInteractionMode();o.value="page"===(null==e?void 0:e.scope)&&!!(null==e?void 0:e.exclusive)})))}})),e.readonly(o)}const a=e.defineComponent({__name:"global-pointer-provider",setup(t){const o=e.ref(null),{provides:n}=l();return e.watchEffect((e=>{if(n.value&&o.value){e(r(n.value,{type:"global"},o.value))}})),(t,n)=>(e.openBlock(),e.createElementBlock("div",{ref_key:"divRef",ref:o,style:{width:"100%",height:"100%"}},[e.renderSlot(t.$slots,"default")],512))}}),u={key:0,style:{position:"absolute",top:0,left:0,right:0,bottom:0,zIndex:10}},s=e.defineComponent({__name:"page-pointer-provider",props:{pageIndex:{},pageWidth:{},pageHeight:{},rotation:{},scale:{},convertEventToPoint:{type:Function}},setup(t){const o=t,a=e.ref(null),{provides:s}=l(),c=i(),d=e.computed((()=>(e,t)=>{const r=t.getBoundingClientRect(),l={x:e.clientX-r.left,y:e.clientY-r.top};return n.restorePosition({width:o.pageWidth,height:o.pageHeight},l,o.rotation,o.scale)}));return e.watchEffect((e=>{if(s.value&&a.value){e(r(s.value,{type:"page",pageIndex:o.pageIndex},a.value,o.convertEventToPoint||d.value))}})),(t,o)=>(e.openBlock(),e.createElementBlock("div",{ref_key:"divRef",ref:a},[e.renderSlot(t.$slots,"default"),e.unref(c)?(e.openBlock(),e.createElementBlock("div",u)):e.createCommentVNode("",!0)],512))}});exports.GlobalPointerProvider=a,exports.PagePointerProvider=s,exports.useCursor=function(){const{provides:e}=l();return{setCursor:(t,o,n=0)=>{var r;null==(r=e.value)||r.setCursor(t,o,n)},removeCursor:t=>{var o;null==(o=e.value)||o.removeCursor(t)}}},exports.useInteractionManager=function(){const{provides:t}=l(),n=e.ref(o.initialState);return e.watchEffect((e=>{if(t.value){e(t.value.onStateChange((e=>{n.value=e})))}})),{provides:t,state:e.readonly(n)}},exports.useInteractionManagerCapability=l,exports.useInteractionManagerPlugin=()=>t.usePlugin(o.InteractionManagerPlugin.id),exports.useIsPageExclusive=i,exports.usePointerHandlers=function({modeId:e,pageIndex:t}){const{provides:o}=l();return{register:(n,r)=>{const l=(null==r?void 0:r.modeId)??e,i=(null==r?void 0:r.pageIndex)??t;if(o.value)return l?o.value.registerHandlers({modeId:l,handlers:n,pageIndex:i}):o.value.registerAlways({scope:void 0!==i?{type:"page",pageIndex:i}:{type:"global"},handlers:n})}}};
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("vue"),t=require("@embedpdf/core/vue"),o=require("@embedpdf/plugin-interaction-manager"),n=require("@embedpdf/models");function r(e,t,o,n){let r=e.getHandlersForScope(t);const l=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)})),i=e.onHandlerChange((()=>{r=e.getHandlersForScope(t)})),a=e.getActiveInteractionMode(),u=e.getCurrentCursor();"global"===t.type?o.style.cursor="global"===(null==a?void 0:a.scope)?u:"auto":o.style.cursor=u;const s=e.onCursorChange((n=>{var r;if("global"===t.type){if(!("global"===(null==(r=e.getActiveInteractionMode())?void 0:r.scope)))return}o.style.cursor=n})),c={onPointerDown:"pointerdown",onPointerUp:"pointerup",onPointerMove:"pointermove",onPointerEnter:"pointerenter",onPointerLeave:"pointerleave",onPointerCancel:"pointercancel",onClick:"click",onDoubleClick:"dblclick"},d={};return Object.keys(c).forEach((t=>{d[t]=l=>{var i;if(e.isPaused())return;const a=l,u=e.getActiveMode();null==(i=null==r?void 0:r[t])||i.call(r,((e,t)=>{if(n)return n(e,t);const o=t.getBoundingClientRect();return{x:e.clientX-o.left,y:e.clientY-o.top}})(a,o),a,u)},o.addEventListener(c[t],d[t])})),()=>{Object.keys(c).forEach((e=>o.removeEventListener(c[e],d[e]))),l(),s(),i()}}const l=()=>t.useCapability(o.InteractionManagerPlugin.id);function i(){const{provides:t}=l(),o=e.ref(!1);return e.watchEffect((e=>{if(t.value){const n=t.value.getActiveInteractionMode();o.value="page"===(null==n?void 0:n.scope)&&!!(null==n?void 0:n.exclusive);e(t.value.onModeChange((()=>{if(!t.value)return;const e=t.value.getActiveInteractionMode();o.value="page"===(null==e?void 0:e.scope)&&!!(null==e?void 0:e.exclusive)})))}})),e.readonly(o)}const a=e.defineComponent({__name:"global-pointer-provider",setup(t){const o=e.ref(null),{provides:n}=l();return e.watchEffect((e=>{if(n.value&&o.value){e(r(n.value,{type:"global"},o.value))}})),(t,n)=>(e.openBlock(),e.createElementBlock("div",{ref_key:"divRef",ref:o,style:{width:"100%",height:"100%"}},[e.renderSlot(t.$slots,"default")],512))}}),u={key:0,style:{position:"absolute",top:0,left:0,right:0,bottom:0,zIndex:10}},s=e.defineComponent({__name:"page-pointer-provider",props:{pageIndex:{},pageWidth:{},pageHeight:{},rotation:{},scale:{},convertEventToPoint:{type:Function}},setup(t){const o=t,a=e.ref(null),{provides:s}=l(),c=i(),d=e.computed((()=>(e,t)=>{const r=t.getBoundingClientRect(),l={x:e.clientX-r.left,y:e.clientY-r.top};return n.restorePosition({width:o.pageWidth,height:o.pageHeight},l,o.rotation,o.scale)}));return e.watchEffect((e=>{if(s.value&&a.value){e(r(s.value,{type:"page",pageIndex:o.pageIndex},a.value,o.convertEventToPoint||d.value))}})),(t,o)=>(e.openBlock(),e.createElementBlock("div",{ref_key:"divRef",ref:a},[e.renderSlot(t.$slots,"default"),e.unref(c)?(e.openBlock(),e.createElementBlock("div",u)):e.createCommentVNode("",!0)],512))}});exports.GlobalPointerProvider=a,exports.PagePointerProvider=s,exports.useCursor=function(){const{provides:e}=l();return{setCursor:(t,o,n=0)=>{var r;null==(r=e.value)||r.setCursor(t,o,n)},removeCursor:t=>{var o;null==(o=e.value)||o.removeCursor(t)}}},exports.useInteractionManager=function(){const{provides:t}=l(),n=e.ref(o.initialState);return e.watchEffect((e=>{if(t.value){e(t.value.onStateChange((e=>{n.value=e})))}})),{provides:t,state:e.readonly(n)}},exports.useInteractionManagerCapability=l,exports.useInteractionManagerPlugin=()=>t.usePlugin(o.InteractionManagerPlugin.id),exports.useIsPageExclusive=i,exports.usePointerHandlers=function({modeId:e,pageIndex:t}){const{provides:o}=l();return{register:(n,r)=>{const l=(null==r?void 0:r.modeId)??e,i=(null==r?void 0:r.pageIndex)??t;if(o.value)return l?o.value.registerHandlers({modeId:l,handlers:n,pageIndex:i}):o.value.registerAlways({scope:void 0!==i?{type:"page",pageIndex:i}:{type:"global"},handlers:n})}}};
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
package/dist/vue/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../../src/shared/utils.ts","../../src/vue/hooks/use-interaction-manager.ts","../../src/vue/components/global-pointer-provider.vue","../../src/vue/components/page-pointer-provider.vue"],"sourcesContent":["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 };\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 { useCapability, usePlugin } from '@embedpdf/core/vue';\nimport {\n initialState,\n InteractionManagerPlugin,\n InteractionManagerState,\n PointerEventHandlersWithLifecycle,\n} from '@embedpdf/plugin-interaction-manager';\nimport { ref, watchEffect, readonly } from 'vue';\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 = ref<InteractionManagerState>(initialState);\n\n watchEffect((onCleanup) => {\n if (provides.value) {\n // onStateChange is a BehaviorEmitter, so it emits the current state upon subscription\n const unsubscribe = provides.value.onStateChange((newState) => {\n state.value = newState;\n });\n onCleanup(unsubscribe);\n }\n });\n\n return {\n provides,\n state: readonly(state),\n };\n}\n\nexport function useCursor() {\n const { provides } = useInteractionManagerCapability();\n return {\n setCursor: (token: string, cursor: string, prio = 0) => {\n provides.value?.setCursor(token, cursor, prio);\n },\n removeCursor: (token: string) => {\n provides.value?.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 if (!provides.value) return;\n\n return finalModeId\n ? provides.value.registerHandlers({\n modeId: finalModeId,\n handlers,\n pageIndex: finalPageIndex,\n })\n : provides.value.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 const isPageExclusive = ref<boolean>(false);\n\n watchEffect((onCleanup) => {\n if (cap.value) {\n const mode = cap.value.getActiveInteractionMode();\n isPageExclusive.value = mode?.scope === 'page' && !!mode?.exclusive;\n\n const unsubscribe = cap.value.onModeChange(() => {\n if (!cap.value) return;\n const newMode = cap.value.getActiveInteractionMode();\n isPageExclusive.value = newMode?.scope === 'page' && !!newMode?.exclusive;\n });\n onCleanup(unsubscribe);\n }\n });\n\n return readonly(isPageExclusive);\n}\n","<script setup lang=\"ts\">\nimport { ref, watchEffect } from 'vue';\nimport { createPointerProvider } from '../../shared/utils';\nimport { useInteractionManagerCapability } from '../hooks';\n\nconst divRef = ref<HTMLDivElement | null>(null);\nconst { provides: cap } = useInteractionManagerCapability();\n\n// watchEffect automatically handles setup and teardown when capability or element is ready\nwatchEffect((onCleanup) => {\n if (cap.value && divRef.value) {\n const cleanup = createPointerProvider(cap.value, { type: 'global' }, divRef.value);\n onCleanup(cleanup);\n }\n});\n</script>\n\n<template>\n <div\n ref=\"divRef\"\n :style=\"{\n width: '100%',\n height: '100%',\n }\"\n >\n <slot />\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { ref, watchEffect, computed, StyleValue } from 'vue';\nimport { Position, restorePosition } from '@embedpdf/models';\nimport { createPointerProvider } from '../../shared/utils';\nimport { useInteractionManagerCapability, useIsPageExclusive } from '../hooks';\n\ninterface Props {\n pageIndex: number;\n pageWidth: number;\n pageHeight: number;\n rotation: number;\n scale: number;\n convertEventToPoint?: (event: PointerEvent, element: HTMLElement) => Position;\n}\n\nconst props = defineProps<Props>();\n\nconst divRef = ref<HTMLDivElement | null>(null);\nconst { provides: cap } = useInteractionManagerCapability();\nconst isPageExclusive = useIsPageExclusive();\n\nconst defaultConvertEventToPoint = computed(() => {\n return (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: props.pageWidth, height: props.pageHeight },\n displayPoint,\n props.rotation,\n props.scale,\n );\n };\n});\n\nwatchEffect((onCleanup) => {\n if (cap.value && divRef.value) {\n const cleanup = createPointerProvider(\n cap.value,\n { type: 'page', pageIndex: props.pageIndex },\n divRef.value,\n props.convertEventToPoint || defaultConvertEventToPoint.value,\n );\n onCleanup(cleanup);\n }\n});\n</script>\n\n<template>\n <div ref=\"divRef\">\n <slot />\n <div\n v-if=\"isPageExclusive\"\n :style=\"{ position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, zIndex: 10 }\"\n />\n </div>\n</template>\n"],"names":["createPointerProvider","cap","scope","element","convertEventToPoint","active","getHandlersForScope","stopMode","onModeChange","type","mode","getActiveInteractionMode","style","cursor","stopHandler","onHandlerChange","modeNow","cursorNow","getCurrentCursor","stopCursor","onCursorChange","c","_a","domEvent","onPointerDown","onPointerUp","onPointerMove","onPointerEnter","onPointerLeave","onPointerCancel","listeners","Object","keys","forEach","k","evt","isPaused","pe","currentModeId","getActiveMode","call","e","host","r","getBoundingClientRect","x","clientX","left","y","clientY","top","toPos","addEventListener","removeEventListener","useInteractionManagerCapability","useCapability","InteractionManagerPlugin","id","useIsPageExclusive","provides","isPageExclusive","ref","readonly","vue$1","watchEffect","onCleanup","value","exclusive","newMode","divRef","_createElementBlock","createElementBlock","_renderSlot","_ctx","$slots","props","__props","defaultConvertEventToPoint","computed","event","rect","displayPoint","restorePosition","width","pageWidth","height","pageHeight","rotation","scale","pageIndex","_unref","_openBlock","_hoisted_1","setCursor","token","prio","removeCursor","state","initialState","onStateChange","newState","usePlugin","modeId","register","handlers","options","finalModeId","finalPageIndex","registerHandlers","registerAlways"],"mappings":"uNAYO,SAASA,EACdC,EACAC,EACAC,EACAC,GAKI,IAAAC,EAAsCJ,EAAIK,oBAAoBJ,GAE5D,MAAAK,EAAWN,EAAIO,cAAa,KAC5B,GAAe,WAAfN,EAAMO,KAAmB,CACrB,MAAAC,EAAOT,EAAIU,2BACjBR,EAAQS,MAAMC,OAAyB,YAAhB,MAAAH,OAAA,EAAAA,EAAMR,OAAsBQ,EAAKG,QAAU,OAAU,MAAA,CAErER,EAAAJ,EAAIK,oBAAoBJ,EAAK,IAGlCY,EAAcb,EAAIc,iBAAgB,KAC7BV,EAAAJ,EAAIK,oBAAoBJ,EAAK,IAMlCc,EAAUf,EAAIU,2BACdM,EAAYhB,EAAIiB,mBAGH,WAAfhB,EAAMO,KAERN,EAAQS,MAAMC,OAA4B,YAAV,MAATG,OAAS,EAAAA,EAAAd,OAAqBe,EAAY,OAGjEd,EAAQS,MAAMC,OAASI,EAGzB,MAAME,EAAalB,EAAImB,gBAAgBC,UAOjC,GAAe,WAAfnB,EAAMO,KAAmB,CAE3B,KAD+D,YAA1C,OAAAa,EAAArB,EAAIU,qCAA4BT,QAClC,MAAA,CAErBC,EAAQS,MAAMC,OAASQ,CAAA,IAOnBE,EAAiD,CACrDC,cAAe,cACfC,YAAa,YACbC,cAAe,cACfC,eAAgB,eAChBC,eAAgB,eAChBC,gBAAiB,iBAIbC,EAA+C,CAAC,EAwBtD,OAhBCC,OAAOC,KAAKT,GAAkBU,SAASC,IAC5BJ,EAAAI,GAAMC,UACV,GAAAlC,EAAImC,WAAY,OAEpB,MAAMC,EAAKF,EACLG,EAAgBrC,EAAIsC,gBAC1B,OAAAjB,EAAA,MAAAjB,OAAA,EAAAA,EAAS6B,KAAKZ,EAAAkB,KAAAnC,EAZJ,EAACoC,EAAiBC,KAC9B,GAAItC,EAAqB,OAAOA,EAAoBqC,EAAGC,GACjD,MAAAC,EAAID,EAAKE,wBACR,MAAA,CAAEC,EAAGJ,EAAEK,QAAUH,EAAEI,KAAMC,EAAGP,EAAEQ,QAAUN,EAAEO,IAAI,EASrCC,CAAMd,EAAIlC,GAAUkC,EAAIC,EAAA,EAIxCnC,EAAQiD,iBAAiB7B,EAASW,GAAIJ,EAAUI,GAAG,IAM9C,KACGH,OAAAC,KAAKT,GAAkBU,SAASC,GACtC/B,EAAQkD,oBAAoB9B,EAASW,GAAIJ,EAAUI,MAE5C3B,IACEY,IACCL,GAAA,CAEhB,CCrGO,MAEMwC,EAAkC,IAC7CC,gBAAwCC,EAAAA,yBAAyBC,IAqE5D,SAASC,IACd,MAAQC,SAAU1D,GAAQqD,IACpBM,EAAkBC,OAAa,GAgB9BC,OAdPC,EAAAC,aAAaC,IACX,GAAIhE,EAAIiE,MAAO,CACP,MAAAxD,EAAOT,EAAIiE,MAAMvD,2BACvBiD,EAAgBM,MAAwB,UAAV,MAANxD,OAAM,EAAAA,EAAAR,WAA4B,MAANQ,OAAM,EAAAA,EAAAyD,WAO1DF,EALoBhE,EAAIiE,MAAM1D,cAAa,KACrC,IAACP,EAAIiE,MAAO,OACV,MAAAE,EAAUnE,EAAIiE,MAAMvD,2BAC1BiD,EAAgBM,MAA2B,UAAV,MAATE,OAAS,EAAAA,EAAAlE,WAA+B,MAATkE,OAAS,EAAAA,EAAAD,UAAA,IAE7C,KAIlBL,EAAAA,SAASF,EAClB,sEC/FM,MAAAS,EAASR,MAA2B,OAClCF,SAAU1D,GAAQqD,WAG1BS,EAAAC,aAAaC,IACP,GAAAhE,EAAIiE,OAASG,EAAOH,MAAO,CAE7BD,EADgBjE,EAAsBC,EAAIiE,MAAO,CAAEzD,KAAM,UAAY4D,EAAOH,OAC3D,2BAMnBI,EAAAC,mBAQM,MAAA,SAPA,SAAJV,IAAIQ,EACHzD,MAAO,+BAKR4D,aAAQC,EAAAC,OAAA,yQCVZ,MAAMC,EAAQC,EAERP,EAASR,MAA2B,OAClCF,SAAU1D,GAAQqD,IACpBM,EAAkBF,IAElBmB,EAA6BC,EAAAA,UAAS,IACnC,CAACC,EAAqB5E,KACrB,MAAA6E,EAAO7E,EAAQyC,wBACfqC,EAAe,CACnBpC,EAAGkC,EAAMjC,QAAUkC,EAAKjC,KACxBC,EAAG+B,EAAM9B,QAAU+B,EAAK9B,KAEnB,OAAAgC,EAAAA,gBACL,CAAEC,MAAOR,EAAMS,UAAWC,OAAQV,EAAMW,YACxCL,EACAN,EAAMY,SACNZ,EAAMa,MACR,WAIJzB,EAAAC,aAAaC,IACP,GAAAhE,EAAIiE,OAASG,EAAOH,MAAO,CAO7BD,EANgBjE,EACdC,EAAIiE,MACJ,CAAEzD,KAAM,OAAQgF,UAAWd,EAAMc,WACjCpB,EAAOH,MACPS,EAAMvE,qBAAuByE,EAA2BX,OAEzC,2BAMnBI,EAAAC,mBAMM,MAAA,SANG,SAAJV,IAAIQ,IACPG,aAAQC,EAAAC,OAAA,WAEAgB,QAAe9B,IADvB+B,EAAAA,YAAArB,EAAAA,mBAGE,MAHFsB,0HFnBG,WACC,MAAAjC,SAAEA,GAAaL,IACd,MAAA,CACLuC,UAAW,CAACC,EAAejF,EAAgBkF,EAAO,WAChD,OAAAzE,EAAAqC,EAASO,QAAT5C,EAAgBuE,UAAUC,EAAOjF,EAAQkF,EAAA,EAE3CC,aAAeF,UACJ,OAAAxE,EAAAqC,EAAAO,UAAO8B,aAAaF,EAAA,EAGnC,gCA9BO,WACC,MAAAnC,SAAEA,GAAaL,IACf2C,EAAQpC,MAA6BqC,gBAYpC,OAVPnC,EAAAC,aAAaC,IACX,GAAIN,EAASO,MAAO,CAKlBD,EAHoBN,EAASO,MAAMiC,eAAeC,IAChDH,EAAM/B,MAAQkC,CAAA,IAEK,KAIlB,CACLzC,WACAsC,MAAOnC,WAASmC,GAEpB,gFAvB2C,IACzCI,YAAoC7C,EAAAA,yBAAyBC,4DAyCxD,UAA4B6C,OAAEA,EAAQb,UAAAA,IACrC,MAAA9B,SAAEA,GAAaL,IACd,MAAA,CACLiD,SAAU,CACRC,EACAC,KAGM,MAAAC,SAAcD,WAASH,SAAUA,EACjCK,SAAiBF,WAAShB,YAAaA,EAEzC,GAAC9B,EAASO,MAEP,OAAAwC,EACH/C,EAASO,MAAM0C,iBAAiB,CAC9BN,OAAQI,EACRF,WACAf,UAAWkB,IAEbhD,EAASO,MAAM2C,eAAe,CAC5B3G,WACqB,IAAnByG,EACI,CAAElG,KAAM,OAAQgF,UAAWkB,GAC3B,CAAElG,KAAM,UACd+F,YACD,EAGX"}
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../../src/shared/utils.ts","../../src/vue/hooks/use-interaction-manager.ts","../../src/vue/components/global-pointer-provider.vue","../../src/vue/components/page-pointer-provider.vue"],"sourcesContent":["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 { useCapability, usePlugin } from '@embedpdf/core/vue';\nimport {\n initialState,\n InteractionManagerPlugin,\n InteractionManagerState,\n PointerEventHandlersWithLifecycle,\n} from '@embedpdf/plugin-interaction-manager';\nimport { ref, watchEffect, readonly } from 'vue';\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 = ref<InteractionManagerState>(initialState);\n\n watchEffect((onCleanup) => {\n if (provides.value) {\n // onStateChange is a BehaviorEmitter, so it emits the current state upon subscription\n const unsubscribe = provides.value.onStateChange((newState) => {\n state.value = newState;\n });\n onCleanup(unsubscribe);\n }\n });\n\n return {\n provides,\n state: readonly(state),\n };\n}\n\nexport function useCursor() {\n const { provides } = useInteractionManagerCapability();\n return {\n setCursor: (token: string, cursor: string, prio = 0) => {\n provides.value?.setCursor(token, cursor, prio);\n },\n removeCursor: (token: string) => {\n provides.value?.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 if (!provides.value) return;\n\n return finalModeId\n ? provides.value.registerHandlers({\n modeId: finalModeId,\n handlers,\n pageIndex: finalPageIndex,\n })\n : provides.value.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 const isPageExclusive = ref<boolean>(false);\n\n watchEffect((onCleanup) => {\n if (cap.value) {\n const mode = cap.value.getActiveInteractionMode();\n isPageExclusive.value = mode?.scope === 'page' && !!mode?.exclusive;\n\n const unsubscribe = cap.value.onModeChange(() => {\n if (!cap.value) return;\n const newMode = cap.value.getActiveInteractionMode();\n isPageExclusive.value = newMode?.scope === 'page' && !!newMode?.exclusive;\n });\n onCleanup(unsubscribe);\n }\n });\n\n return readonly(isPageExclusive);\n}\n","<script setup lang=\"ts\">\nimport { ref, watchEffect } from 'vue';\nimport { createPointerProvider } from '../../shared/utils';\nimport { useInteractionManagerCapability } from '../hooks';\n\nconst divRef = ref<HTMLDivElement | null>(null);\nconst { provides: cap } = useInteractionManagerCapability();\n\n// watchEffect automatically handles setup and teardown when capability or element is ready\nwatchEffect((onCleanup) => {\n if (cap.value && divRef.value) {\n const cleanup = createPointerProvider(cap.value, { type: 'global' }, divRef.value);\n onCleanup(cleanup);\n }\n});\n</script>\n\n<template>\n <div\n ref=\"divRef\"\n :style=\"{\n width: '100%',\n height: '100%',\n }\"\n >\n <slot />\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { ref, watchEffect, computed, StyleValue } from 'vue';\nimport { Position, restorePosition } from '@embedpdf/models';\nimport { createPointerProvider } from '../../shared/utils';\nimport { useInteractionManagerCapability, useIsPageExclusive } from '../hooks';\n\ninterface Props {\n pageIndex: number;\n pageWidth: number;\n pageHeight: number;\n rotation: number;\n scale: number;\n convertEventToPoint?: (event: PointerEvent, element: HTMLElement) => Position;\n}\n\nconst props = defineProps<Props>();\n\nconst divRef = ref<HTMLDivElement | null>(null);\nconst { provides: cap } = useInteractionManagerCapability();\nconst isPageExclusive = useIsPageExclusive();\n\nconst defaultConvertEventToPoint = computed(() => {\n return (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: props.pageWidth, height: props.pageHeight },\n displayPoint,\n props.rotation,\n props.scale,\n );\n };\n});\n\nwatchEffect((onCleanup) => {\n if (cap.value && divRef.value) {\n const cleanup = createPointerProvider(\n cap.value,\n { type: 'page', pageIndex: props.pageIndex },\n divRef.value,\n props.convertEventToPoint || defaultConvertEventToPoint.value,\n );\n onCleanup(cleanup);\n }\n});\n</script>\n\n<template>\n <div ref=\"divRef\">\n <slot />\n <div\n v-if=\"isPageExclusive\"\n :style=\"{ position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, zIndex: 10 }\"\n />\n </div>\n</template>\n"],"names":["createPointerProvider","cap","scope","element","convertEventToPoint","active","getHandlersForScope","stopMode","onModeChange","type","mode","getActiveInteractionMode","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","useInteractionManagerCapability","useCapability","InteractionManagerPlugin","id","useIsPageExclusive","provides","isPageExclusive","ref","readonly","vue$1","watchEffect","onCleanup","value","exclusive","newMode","divRef","_createElementBlock","createElementBlock","_renderSlot","_ctx","$slots","props","__props","defaultConvertEventToPoint","computed","event","rect","displayPoint","restorePosition","width","pageWidth","height","pageHeight","rotation","scale","pageIndex","_unref","_openBlock","_hoisted_1","setCursor","token","prio","removeCursor","state","initialState","onStateChange","newState","usePlugin","modeId","register","handlers","options","finalModeId","finalPageIndex","registerHandlers","registerAlways"],"mappings":"uNAYO,SAASA,EACdC,EACAC,EACAC,EACAC,GAKI,IAAAC,EAAsCJ,EAAIK,oBAAoBJ,GAE5D,MAAAK,EAAWN,EAAIO,cAAa,KAC5B,GAAe,WAAfN,EAAMO,KAAmB,CACrB,MAAAC,EAAOT,EAAIU,2BACjBR,EAAQS,MAAMC,OAAyB,YAAhB,MAAAH,OAAA,EAAAA,EAAMR,OAAsBQ,EAAKG,QAAU,OAAU,MAAA,CAErER,EAAAJ,EAAIK,oBAAoBJ,EAAK,IAGlCY,EAAcb,EAAIc,iBAAgB,KAC7BV,EAAAJ,EAAIK,oBAAoBJ,EAAK,IAMlCc,EAAUf,EAAIU,2BACdM,EAAYhB,EAAIiB,mBAGH,WAAfhB,EAAMO,KAERN,EAAQS,MAAMC,OAA4B,YAAV,MAATG,OAAS,EAAAA,EAAAd,OAAqBe,EAAY,OAGjEd,EAAQS,MAAMC,OAASI,EAGzB,MAAME,EAAalB,EAAImB,gBAAgBC,UAOjC,GAAe,WAAfnB,EAAMO,KAAmB,CAE3B,KAD+D,YAA1C,OAAAa,EAAArB,EAAIU,qCAA4BT,QAClC,MAAA,CAErBC,EAAQS,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,GAAApC,EAAIqC,WAAY,OAEpB,MAAMC,EAAKF,EACLG,EAAgBvC,EAAIwC,gBAC1B,OAAAnB,EAAA,MAAAjB,OAAA,EAAAA,EAAS+B,KAAKd,EAAAoB,KAAArC,EAZJ,EAACsC,EAAiBC,KAC9B,GAAIxC,EAAqB,OAAOA,EAAoBuC,EAAGC,GACjD,MAAAC,EAAID,EAAKE,wBACR,MAAA,CAAEC,EAAGJ,EAAEK,QAAUH,EAAEI,KAAMC,EAAGP,EAAEQ,QAAUN,EAAEO,IAAI,EASrCC,CAAMd,EAAIpC,GAAUoC,EAAIC,EAAA,EAIxCrC,EAAQmD,iBAAiB/B,EAASa,GAAIJ,EAAUI,GAAG,IAM9C,KACGH,OAAAC,KAAKX,GAAkBY,SAASC,GACtCjC,EAAQoD,oBAAoBhC,EAASa,GAAIJ,EAAUI,MAE5C7B,IACEY,IACCL,GAAA,CAEhB,CCvGO,MAEM0C,EAAkC,IAC7CC,gBAAwCC,EAAAA,yBAAyBC,IAqE5D,SAASC,IACd,MAAQC,SAAU5D,GAAQuD,IACpBM,EAAkBC,OAAa,GAgB9BC,OAdPC,EAAAC,aAAaC,IACX,GAAIlE,EAAImE,MAAO,CACP,MAAA1D,EAAOT,EAAImE,MAAMzD,2BACvBmD,EAAgBM,MAAwB,UAAV,MAAN1D,OAAM,EAAAA,EAAAR,WAA4B,MAANQ,OAAM,EAAAA,EAAA2D,WAO1DF,EALoBlE,EAAImE,MAAM5D,cAAa,KACrC,IAACP,EAAImE,MAAO,OACV,MAAAE,EAAUrE,EAAImE,MAAMzD,2BAC1BmD,EAAgBM,MAA2B,UAAV,MAATE,OAAS,EAAAA,EAAApE,WAA+B,MAAToE,OAAS,EAAAA,EAAAD,UAAA,IAE7C,KAIlBL,EAAAA,SAASF,EAClB,sEC/FM,MAAAS,EAASR,MAA2B,OAClCF,SAAU5D,GAAQuD,WAG1BS,EAAAC,aAAaC,IACP,GAAAlE,EAAImE,OAASG,EAAOH,MAAO,CAE7BD,EADgBnE,EAAsBC,EAAImE,MAAO,CAAE3D,KAAM,UAAY8D,EAAOH,OAC3D,2BAMnBI,EAAAC,mBAQM,MAAA,SAPA,SAAJV,IAAIQ,EACH3D,MAAO,+BAKR8D,aAAQC,EAAAC,OAAA,yQCVZ,MAAMC,EAAQC,EAERP,EAASR,MAA2B,OAClCF,SAAU5D,GAAQuD,IACpBM,EAAkBF,IAElBmB,EAA6BC,EAAAA,UAAS,IACnC,CAACC,EAAqB9E,KACrB,MAAA+E,EAAO/E,EAAQ2C,wBACfqC,EAAe,CACnBpC,EAAGkC,EAAMjC,QAAUkC,EAAKjC,KACxBC,EAAG+B,EAAM9B,QAAU+B,EAAK9B,KAEnB,OAAAgC,EAAAA,gBACL,CAAEC,MAAOR,EAAMS,UAAWC,OAAQV,EAAMW,YACxCL,EACAN,EAAMY,SACNZ,EAAMa,MACR,WAIJzB,EAAAC,aAAaC,IACP,GAAAlE,EAAImE,OAASG,EAAOH,MAAO,CAO7BD,EANgBnE,EACdC,EAAImE,MACJ,CAAE3D,KAAM,OAAQkF,UAAWd,EAAMc,WACjCpB,EAAOH,MACPS,EAAMzE,qBAAuB2E,EAA2BX,OAEzC,2BAMnBI,EAAAC,mBAMM,MAAA,SANG,SAAJV,IAAIQ,IACPG,aAAQC,EAAAC,OAAA,WAEAgB,QAAe9B,IADvB+B,EAAAA,YAAArB,EAAAA,mBAGE,MAHFsB,0HFnBG,WACC,MAAAjC,SAAEA,GAAaL,IACd,MAAA,CACLuC,UAAW,CAACC,EAAenF,EAAgBoF,EAAO,WAChD,OAAA3E,EAAAuC,EAASO,QAAT9C,EAAgByE,UAAUC,EAAOnF,EAAQoF,EAAA,EAE3CC,aAAeF,UACJ,OAAA1E,EAAAuC,EAAAO,UAAO8B,aAAaF,EAAA,EAGnC,gCA9BO,WACC,MAAAnC,SAAEA,GAAaL,IACf2C,EAAQpC,MAA6BqC,gBAYpC,OAVPnC,EAAAC,aAAaC,IACX,GAAIN,EAASO,MAAO,CAKlBD,EAHoBN,EAASO,MAAMiC,eAAeC,IAChDH,EAAM/B,MAAQkC,CAAA,IAEK,KAIlB,CACLzC,WACAsC,MAAOnC,WAASmC,GAEpB,gFAvB2C,IACzCI,YAAoC7C,EAAAA,yBAAyBC,4DAyCxD,UAA4B6C,OAAEA,EAAQb,UAAAA,IACrC,MAAA9B,SAAEA,GAAaL,IACd,MAAA,CACLiD,SAAU,CACRC,EACAC,KAGM,MAAAC,SAAcD,WAASH,SAAUA,EACjCK,SAAiBF,WAAShB,YAAaA,EAEzC,GAAC9B,EAASO,MAEP,OAAAwC,EACH/C,EAASO,MAAM0C,iBAAiB,CAC9BN,OAAQI,EACRF,WACAf,UAAWkB,IAEbhD,EAASO,MAAM2C,eAAe,CAC5B7G,WACqB,IAAnB2G,EACI,CAAEpG,KAAM,OAAQkF,UAAWkB,GAC3B,CAAEpG,KAAM,UACdiG,YACD,EAGX"}
|
package/dist/vue/index.js
CHANGED
|
@@ -35,7 +35,9 @@ function createPointerProvider(cap, scope, element, convertEventToPoint) {
|
|
|
35
35
|
onPointerMove: "pointermove",
|
|
36
36
|
onPointerEnter: "pointerenter",
|
|
37
37
|
onPointerLeave: "pointerleave",
|
|
38
|
-
onPointerCancel: "pointercancel"
|
|
38
|
+
onPointerCancel: "pointercancel",
|
|
39
|
+
onClick: "click",
|
|
40
|
+
onDoubleClick: "dblclick"
|
|
39
41
|
};
|
|
40
42
|
const listeners = {};
|
|
41
43
|
const toPos = (e, host) => {
|
package/dist/vue/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../src/shared/utils.ts","../../src/vue/hooks/use-interaction-manager.ts","../../src/vue/components/global-pointer-provider.vue","../../src/vue/components/page-pointer-provider.vue"],"sourcesContent":["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 };\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 { useCapability, usePlugin } from '@embedpdf/core/vue';\nimport {\n initialState,\n InteractionManagerPlugin,\n InteractionManagerState,\n PointerEventHandlersWithLifecycle,\n} from '@embedpdf/plugin-interaction-manager';\nimport { ref, watchEffect, readonly } from 'vue';\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 = ref<InteractionManagerState>(initialState);\n\n watchEffect((onCleanup) => {\n if (provides.value) {\n // onStateChange is a BehaviorEmitter, so it emits the current state upon subscription\n const unsubscribe = provides.value.onStateChange((newState) => {\n state.value = newState;\n });\n onCleanup(unsubscribe);\n }\n });\n\n return {\n provides,\n state: readonly(state),\n };\n}\n\nexport function useCursor() {\n const { provides } = useInteractionManagerCapability();\n return {\n setCursor: (token: string, cursor: string, prio = 0) => {\n provides.value?.setCursor(token, cursor, prio);\n },\n removeCursor: (token: string) => {\n provides.value?.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 if (!provides.value) return;\n\n return finalModeId\n ? provides.value.registerHandlers({\n modeId: finalModeId,\n handlers,\n pageIndex: finalPageIndex,\n })\n : provides.value.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 const isPageExclusive = ref<boolean>(false);\n\n watchEffect((onCleanup) => {\n if (cap.value) {\n const mode = cap.value.getActiveInteractionMode();\n isPageExclusive.value = mode?.scope === 'page' && !!mode?.exclusive;\n\n const unsubscribe = cap.value.onModeChange(() => {\n if (!cap.value) return;\n const newMode = cap.value.getActiveInteractionMode();\n isPageExclusive.value = newMode?.scope === 'page' && !!newMode?.exclusive;\n });\n onCleanup(unsubscribe);\n }\n });\n\n return readonly(isPageExclusive);\n}\n","<script setup lang=\"ts\">\nimport { ref, watchEffect } from 'vue';\nimport { createPointerProvider } from '../../shared/utils';\nimport { useInteractionManagerCapability } from '../hooks';\n\nconst divRef = ref<HTMLDivElement | null>(null);\nconst { provides: cap } = useInteractionManagerCapability();\n\n// watchEffect automatically handles setup and teardown when capability or element is ready\nwatchEffect((onCleanup) => {\n if (cap.value && divRef.value) {\n const cleanup = createPointerProvider(cap.value, { type: 'global' }, divRef.value);\n onCleanup(cleanup);\n }\n});\n</script>\n\n<template>\n <div\n ref=\"divRef\"\n :style=\"{\n width: '100%',\n height: '100%',\n }\"\n >\n <slot />\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { ref, watchEffect, computed, StyleValue } from 'vue';\nimport { Position, restorePosition } from '@embedpdf/models';\nimport { createPointerProvider } from '../../shared/utils';\nimport { useInteractionManagerCapability, useIsPageExclusive } from '../hooks';\n\ninterface Props {\n pageIndex: number;\n pageWidth: number;\n pageHeight: number;\n rotation: number;\n scale: number;\n convertEventToPoint?: (event: PointerEvent, element: HTMLElement) => Position;\n}\n\nconst props = defineProps<Props>();\n\nconst divRef = ref<HTMLDivElement | null>(null);\nconst { provides: cap } = useInteractionManagerCapability();\nconst isPageExclusive = useIsPageExclusive();\n\nconst defaultConvertEventToPoint = computed(() => {\n return (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: props.pageWidth, height: props.pageHeight },\n displayPoint,\n props.rotation,\n props.scale,\n );\n };\n});\n\nwatchEffect((onCleanup) => {\n if (cap.value && divRef.value) {\n const cleanup = createPointerProvider(\n cap.value,\n { type: 'page', pageIndex: props.pageIndex },\n divRef.value,\n props.convertEventToPoint || defaultConvertEventToPoint.value,\n );\n onCleanup(cleanup);\n }\n});\n</script>\n\n<template>\n <div ref=\"divRef\">\n <slot />\n <div\n v-if=\"isPageExclusive\"\n :style=\"{ position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, zIndex: 10 }\"\n />\n </div>\n</template>\n"],"names":["_createElementBlock","_renderSlot","_unref","_openBlock"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../src/shared/utils.ts","../../src/vue/hooks/use-interaction-manager.ts","../../src/vue/components/global-pointer-provider.vue","../../src/vue/components/page-pointer-provider.vue"],"sourcesContent":["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 { useCapability, usePlugin } from '@embedpdf/core/vue';\nimport {\n initialState,\n InteractionManagerPlugin,\n InteractionManagerState,\n PointerEventHandlersWithLifecycle,\n} from '@embedpdf/plugin-interaction-manager';\nimport { ref, watchEffect, readonly } from 'vue';\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 = ref<InteractionManagerState>(initialState);\n\n watchEffect((onCleanup) => {\n if (provides.value) {\n // onStateChange is a BehaviorEmitter, so it emits the current state upon subscription\n const unsubscribe = provides.value.onStateChange((newState) => {\n state.value = newState;\n });\n onCleanup(unsubscribe);\n }\n });\n\n return {\n provides,\n state: readonly(state),\n };\n}\n\nexport function useCursor() {\n const { provides } = useInteractionManagerCapability();\n return {\n setCursor: (token: string, cursor: string, prio = 0) => {\n provides.value?.setCursor(token, cursor, prio);\n },\n removeCursor: (token: string) => {\n provides.value?.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 if (!provides.value) return;\n\n return finalModeId\n ? provides.value.registerHandlers({\n modeId: finalModeId,\n handlers,\n pageIndex: finalPageIndex,\n })\n : provides.value.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 const isPageExclusive = ref<boolean>(false);\n\n watchEffect((onCleanup) => {\n if (cap.value) {\n const mode = cap.value.getActiveInteractionMode();\n isPageExclusive.value = mode?.scope === 'page' && !!mode?.exclusive;\n\n const unsubscribe = cap.value.onModeChange(() => {\n if (!cap.value) return;\n const newMode = cap.value.getActiveInteractionMode();\n isPageExclusive.value = newMode?.scope === 'page' && !!newMode?.exclusive;\n });\n onCleanup(unsubscribe);\n }\n });\n\n return readonly(isPageExclusive);\n}\n","<script setup lang=\"ts\">\nimport { ref, watchEffect } from 'vue';\nimport { createPointerProvider } from '../../shared/utils';\nimport { useInteractionManagerCapability } from '../hooks';\n\nconst divRef = ref<HTMLDivElement | null>(null);\nconst { provides: cap } = useInteractionManagerCapability();\n\n// watchEffect automatically handles setup and teardown when capability or element is ready\nwatchEffect((onCleanup) => {\n if (cap.value && divRef.value) {\n const cleanup = createPointerProvider(cap.value, { type: 'global' }, divRef.value);\n onCleanup(cleanup);\n }\n});\n</script>\n\n<template>\n <div\n ref=\"divRef\"\n :style=\"{\n width: '100%',\n height: '100%',\n }\"\n >\n <slot />\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { ref, watchEffect, computed, StyleValue } from 'vue';\nimport { Position, restorePosition } from '@embedpdf/models';\nimport { createPointerProvider } from '../../shared/utils';\nimport { useInteractionManagerCapability, useIsPageExclusive } from '../hooks';\n\ninterface Props {\n pageIndex: number;\n pageWidth: number;\n pageHeight: number;\n rotation: number;\n scale: number;\n convertEventToPoint?: (event: PointerEvent, element: HTMLElement) => Position;\n}\n\nconst props = defineProps<Props>();\n\nconst divRef = ref<HTMLDivElement | null>(null);\nconst { provides: cap } = useInteractionManagerCapability();\nconst isPageExclusive = useIsPageExclusive();\n\nconst defaultConvertEventToPoint = computed(() => {\n return (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: props.pageWidth, height: props.pageHeight },\n displayPoint,\n props.rotation,\n props.scale,\n );\n };\n});\n\nwatchEffect((onCleanup) => {\n if (cap.value && divRef.value) {\n const cleanup = createPointerProvider(\n cap.value,\n { type: 'page', pageIndex: props.pageIndex },\n divRef.value,\n props.convertEventToPoint || defaultConvertEventToPoint.value,\n );\n onCleanup(cleanup);\n }\n});\n</script>\n\n<template>\n <div ref=\"divRef\">\n <slot />\n <div\n v-if=\"isPageExclusive\"\n :style=\"{ position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, zIndex: 10 }\"\n />\n </div>\n</template>\n"],"names":["_createElementBlock","_renderSlot","_unref","_openBlock"],"mappings":";;;;AAYO,SAAS,sBACd,KACA,OACA,SACA,qBACA;AAII,MAAA,SAAsC,IAAI,oBAAoB,KAAK;AAEjE,QAAA,WAAW,IAAI,aAAa,MAAM;AAClC,QAAA,MAAM,SAAS,UAAU;AACrB,YAAA,OAAO,IAAI,yBAAyB;AAC1C,cAAQ,MAAM,UAAS,6BAAM,WAAU,WAAY,KAAK,UAAU,SAAU;AAAA,IAAA;AAErE,aAAA,IAAI,oBAAoB,KAAK;AAAA,EAAA,CACvC;AAEK,QAAA,cAAc,IAAI,gBAAgB,MAAM;AACnC,aAAA,IAAI,oBAAoB,KAAK;AAAA,EAAA,CACvC;AAKK,QAAA,UAAU,IAAI,yBAAyB;AACvC,QAAA,YAAY,IAAI,iBAAiB;AAGnC,MAAA,MAAM,SAAS,UAAU;AAE3B,YAAQ,MAAM,UAAS,mCAAS,WAAU,WAAW,YAAY;AAAA,EAAA,OAC5D;AAEL,YAAQ,MAAM,SAAS;AAAA,EAAA;AAGzB,QAAM,aAAa,IAAI,eAAe,CAAC,MAAM;;AAOvC,QAAA,MAAM,SAAS,UAAU;AAC3B,YAAM,iBAAe,SAAI,yBAAyB,MAA7B,mBAAgC,WAAU;AAC/D,UAAI,CAAC,aAAc;AAAA,IAAA;AAErB,YAAQ,MAAM,SAAS;AAAA,EAAA,CACxB;AAMD,QAAM,WAAiD;AAAA,IACrD,eAAe;AAAA,IACf,aAAa;AAAA,IACb,eAAe;AAAA,IACf,gBAAgB;AAAA,IAChB,gBAAgB;AAAA,IAChB,iBAAiB;AAAA,IACjB,SAAS;AAAA,IACT,eAAe;AAAA,EACjB;AAGA,QAAM,YAA+C,CAAC;AAEhD,QAAA,QAAQ,CAAC,GAAiB,SAAgC;AAC9D,QAAI,oBAAqB,QAAO,oBAAoB,GAAG,IAAI;AACrD,UAAA,IAAI,KAAK,sBAAsB;AAC9B,WAAA,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,GAAG,EAAE,UAAU,EAAE,IAAI;AAAA,EACvD;AAEC,SAAO,KAAK,QAAQ,EAAU,QAAQ,CAAC,MAAM;AAClC,cAAA,CAAC,IAAI,CAAC,QAAe;;AACzB,UAAA,IAAI,WAAY;AAEpB,YAAM,KAAK;AACL,YAAA,gBAAgB,IAAI,cAAc;AACxC,6CAAS,OAAT,gCAAc,MAAM,IAAI,OAAO,GAAG,IAAI;AAAA,IAGxC;AACA,YAAQ,iBAAiB,SAAS,CAAC,GAAG,UAAU,CAAC,CAAE;AAAA,EAAA,CACpD;AAKD,SAAO,MAAM;AACV,WAAO,KAAK,QAAQ,EAAU;AAAA,MAAQ,CAAC,MACtC,QAAQ,oBAAoB,SAAS,CAAC,GAAG,UAAU,CAAC,CAAE;AAAA,IACxD;AACS,aAAA;AACE,eAAA;AACC,gBAAA;AAAA,EACd;AACF;ACvGO,MAAM,8BAA8B,MACzC,UAAoC,yBAAyB,EAAE;AAC1D,MAAM,kCAAkC,MAC7C,cAAwC,yBAAyB,EAAE;AAE9D,SAAS,wBAAwB;AAChC,QAAA,EAAE,SAAS,IAAI,gCAAgC;AAC/C,QAAA,QAAQ,IAA6B,YAAY;AAEvD,cAAY,CAAC,cAAc;AACzB,QAAI,SAAS,OAAO;AAElB,YAAM,cAAc,SAAS,MAAM,cAAc,CAAC,aAAa;AAC7D,cAAM,QAAQ;AAAA,MAAA,CACf;AACD,gBAAU,WAAW;AAAA,IAAA;AAAA,EACvB,CACD;AAEM,SAAA;AAAA,IACL;AAAA,IACA,OAAO,SAAS,KAAK;AAAA,EACvB;AACF;AAEO,SAAS,YAAY;AACpB,QAAA,EAAE,SAAS,IAAI,gCAAgC;AAC9C,SAAA;AAAA,IACL,WAAW,CAAC,OAAe,QAAgB,OAAO,MAAM;;AACtD,qBAAS,UAAT,mBAAgB,UAAU,OAAO,QAAQ;AAAA,IAC3C;AAAA,IACA,cAAc,CAAC,UAAkB;;AACtB,qBAAA,UAAA,mBAAO,aAAa;AAAA,IAAK;AAAA,EAEtC;AACF;AAOO,SAAS,mBAAmB,EAAE,QAAQ,aAAwC;AAC7E,QAAA,EAAE,SAAS,IAAI,gCAAgC;AAC9C,SAAA;AAAA,IACL,UAAU,CACR,UACA,YACG;AAEG,YAAA,eAAc,mCAAS,WAAU;AACjC,YAAA,kBAAiB,mCAAS,cAAa;AAEzC,UAAA,CAAC,SAAS,MAAO;AAEd,aAAA,cACH,SAAS,MAAM,iBAAiB;AAAA,QAC9B,QAAQ;AAAA,QACR;AAAA,QACA,WAAW;AAAA,MAAA,CACZ,IACD,SAAS,MAAM,eAAe;AAAA,QAC5B,OACE,mBAAmB,SACf,EAAE,MAAM,QAAQ,WAAW,eAAe,IAC1C,EAAE,MAAM,SAAS;AAAA,QACvB;AAAA,MAAA,CACD;AAAA,IAAA;AAAA,EAET;AACF;AAEO,SAAS,qBAAqB;AACnC,QAAM,EAAE,UAAU,IAAI,IAAI,gCAAgC;AACpD,QAAA,kBAAkB,IAAa,KAAK;AAE1C,cAAY,CAAC,cAAc;AACzB,QAAI,IAAI,OAAO;AACP,YAAA,OAAO,IAAI,MAAM,yBAAyB;AAChD,sBAAgB,SAAQ,6BAAM,WAAU,UAAU,CAAC,EAAC,6BAAM;AAE1D,YAAM,cAAc,IAAI,MAAM,aAAa,MAAM;AAC3C,YAAA,CAAC,IAAI,MAAO;AACV,cAAA,UAAU,IAAI,MAAM,yBAAyB;AACnD,wBAAgB,SAAQ,mCAAS,WAAU,UAAU,CAAC,EAAC,mCAAS;AAAA,MAAA,CACjE;AACD,gBAAU,WAAW;AAAA,IAAA;AAAA,EACvB,CACD;AAED,SAAO,SAAS,eAAe;AACjC;;;;AC/FM,UAAA,SAAS,IAA2B,IAAI;AAC9C,UAAM,EAAE,UAAU,IAAI,IAAI,gCAAgC;AAG1D,gBAAY,CAAC,cAAc;AACrB,UAAA,IAAI,SAAS,OAAO,OAAO;AACvB,cAAA,UAAU,sBAAsB,IAAI,OAAO,EAAE,MAAM,SAAA,GAAY,OAAO,KAAK;AACjF,kBAAU,OAAO;AAAA,MAAA;AAAA,IACnB,CACD;;0BAICA,mBAQM,OAAA;AAAA,iBAPA;AAAA,QAAJ,KAAI;AAAA,QACH,OAAO;AAAA;;;MAGP;QAEDC,WAAQ,KAAA,QAAA,SAAA;AAAA;;;;;;;;;;;;;;;;;;;ACVZ,UAAM,QAAQ;AAER,UAAA,SAAS,IAA2B,IAAI;AAC9C,UAAM,EAAE,UAAU,IAAI,IAAI,gCAAgC;AAC1D,UAAM,kBAAkB,mBAAmB;AAErC,UAAA,6BAA6B,SAAS,MAAM;AACzC,aAAA,CAAC,OAAqB,YAAmC;AACxD,cAAA,OAAO,QAAQ,sBAAsB;AAC3C,cAAM,eAAe;AAAA,UACnB,GAAG,MAAM,UAAU,KAAK;AAAA,UACxB,GAAG,MAAM,UAAU,KAAK;AAAA,QAC1B;AACO,eAAA;AAAA,UACL,EAAE,OAAO,MAAM,WAAW,QAAQ,MAAM,WAAW;AAAA,UACnD;AAAA,UACA,MAAM;AAAA,UACN,MAAM;AAAA,QACR;AAAA,MACF;AAAA,IAAA,CACD;AAED,gBAAY,CAAC,cAAc;AACrB,UAAA,IAAI,SAAS,OAAO,OAAO;AAC7B,cAAM,UAAU;AAAA,UACd,IAAI;AAAA,UACJ,EAAE,MAAM,QAAQ,WAAW,MAAM,UAAU;AAAA,UAC3C,OAAO;AAAA,UACP,MAAM,uBAAuB,2BAA2B;AAAA,QAC1D;AACA,kBAAU,OAAO;AAAA,MAAA;AAAA,IACnB,CACD;;0BAICD,mBAMM,OAAA;AAAA,iBANG;AAAA,QAAJ,KAAI;AAAA,MAAA;QACPC,WAAQ,KAAA,QAAA,SAAA;AAAA,QAEAC,MAAe,eAAA,KADvBC,aAAAH,mBAGE,OAHF,UAGE;;;;;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@embedpdf/plugin-interaction-manager",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.14",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.cjs",
|
|
6
6
|
"module": "./dist/index.js",
|
|
@@ -28,12 +28,12 @@
|
|
|
28
28
|
}
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@embedpdf/models": "1.0.
|
|
31
|
+
"@embedpdf/models": "1.0.14"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"@types/react": "^18.2.0",
|
|
35
35
|
"typescript": "^5.0.0",
|
|
36
|
-
"@embedpdf/core": "1.0.
|
|
36
|
+
"@embedpdf/core": "1.0.14",
|
|
37
37
|
"@embedpdf/build": "1.0.0"
|
|
38
38
|
},
|
|
39
39
|
"peerDependencies": {
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"react-dom": ">=16.8.0",
|
|
42
42
|
"preact": "^10.26.4",
|
|
43
43
|
"vue": ">=3.2.0",
|
|
44
|
-
"@embedpdf/core": "1.0.
|
|
44
|
+
"@embedpdf/core": "1.0.14"
|
|
45
45
|
},
|
|
46
46
|
"files": [
|
|
47
47
|
"dist",
|