@embedpdf/angular 3.0.0-next.13 → 3.0.0-next.15
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/README.md +309 -0
- package/dist/README.md +309 -0
- package/dist/actions/index.d.ts +34 -16
- package/dist/anchored/index.d.ts +67 -0
- package/dist/annotation/index.d.ts +599 -0
- package/dist/commands/index.d.ts +109 -0
- package/dist/fesm2022/embedpdf-angular-actions.mjs +117 -36
- package/dist/fesm2022/embedpdf-angular-actions.mjs.map +1 -1
- package/dist/fesm2022/embedpdf-angular-anchored.mjs +148 -0
- package/dist/fesm2022/embedpdf-angular-anchored.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular-annotation.mjs +1960 -0
- package/dist/fesm2022/embedpdf-angular-annotation.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular-commands.mjs +235 -0
- package/dist/fesm2022/embedpdf-angular-commands.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular-form.mjs +1074 -0
- package/dist/fesm2022/embedpdf-angular-form.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular-history.mjs +54 -0
- package/dist/fesm2022/embedpdf-angular-history.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular-i18n.mjs +100 -0
- package/dist/fesm2022/embedpdf-angular-i18n.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular-interaction.mjs +157 -0
- package/dist/fesm2022/embedpdf-angular-interaction.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular-link.mjs +306 -0
- package/dist/fesm2022/embedpdf-angular-link.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular-measurement.mjs +106 -0
- package/dist/fesm2022/embedpdf-angular-measurement.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular-metadata.mjs +77 -0
- package/dist/fesm2022/embedpdf-angular-metadata.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular-page-edit.mjs +65 -0
- package/dist/fesm2022/embedpdf-angular-page-edit.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular-page-view.mjs +297 -0
- package/dist/fesm2022/embedpdf-angular-page-view.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular-redaction.mjs +93 -0
- package/dist/fesm2022/embedpdf-angular-redaction.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular-render.mjs +331 -69
- package/dist/fesm2022/embedpdf-angular-render.mjs.map +1 -1
- package/dist/fesm2022/embedpdf-angular-runtime.mjs +1147 -390
- package/dist/fesm2022/embedpdf-angular-runtime.mjs.map +1 -1
- package/dist/fesm2022/embedpdf-angular-search.mjs +251 -0
- package/dist/fesm2022/embedpdf-angular-search.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular-selection.mjs +477 -0
- package/dist/fesm2022/embedpdf-angular-selection.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular-shell.mjs +177 -0
- package/dist/fesm2022/embedpdf-angular-shell.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular-signature.mjs +120 -0
- package/dist/fesm2022/embedpdf-angular-signature.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular-stage.mjs +688 -288
- package/dist/fesm2022/embedpdf-angular-stage.mjs.map +1 -1
- package/dist/fesm2022/embedpdf-angular-stamp.mjs +169 -0
- package/dist/fesm2022/embedpdf-angular-stamp.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular-testing.mjs +89 -0
- package/dist/fesm2022/embedpdf-angular-testing.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular-toolbar.mjs +1123 -0
- package/dist/fesm2022/embedpdf-angular-toolbar.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular-view-manager.mjs +69 -0
- package/dist/fesm2022/embedpdf-angular-view-manager.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular.mjs +23 -3
- package/dist/fesm2022/embedpdf-angular.mjs.map +1 -1
- package/dist/form/index.d.ts +79 -0
- package/dist/history/index.d.ts +28 -0
- package/dist/i18n/index.d.ts +52 -0
- package/dist/index.d.ts +20 -0
- package/dist/interaction/index.d.ts +58 -0
- package/dist/link/index.d.ts +77 -0
- package/dist/measurement/index.d.ts +46 -0
- package/dist/metadata/index.d.ts +51 -0
- package/dist/page-edit/index.d.ts +22 -0
- package/dist/page-view/index.d.ts +94 -0
- package/dist/redaction/index.d.ts +38 -0
- package/dist/render/index.d.ts +45 -6
- package/dist/runtime/index.d.ts +579 -199
- package/dist/search/index.d.ts +71 -0
- package/dist/selection/index.d.ts +141 -0
- package/dist/shell/index.d.ts +88 -0
- package/dist/signature/index.d.ts +45 -0
- package/dist/stage/index.d.ts +242 -141
- package/dist/stamp/index.d.ts +58 -0
- package/dist/testing/index.d.ts +53 -0
- package/dist/toolbar/index.d.ts +257 -0
- package/dist/view-manager/index.d.ts +23 -0
- package/package.json +135 -14
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"embedpdf-angular-form.mjs","sources":["../../form/src/form.ts","../../form/src/list-box.ts","../../form/src/widget-box.ts","../../form/src/controls.ts","../../form/src/field-pictures.ts","../../form/src/form-layer.ts","../../form/src/public_api.ts","../../form/src/embedpdf-angular-form.ts"],"sourcesContent":["/**\n * The form plugin's service and feature:\n *\n * withForm(config) the plugin, for provideEmbedPdf()\n * inject(EpdfForm) read, fill and build the form: `fields()`, `setValue()`, `create()`,\n * the events as streams (`valueChanged$`), and the settings\n * form.valueOf(ref) one field's value, as a signal\n * form.controlOf(ref) one field as a Reactive Forms `FormControl`, for your own inputs\n */\nimport {\n assertInInjectionContext,\n DestroyRef,\n effect,\n inject,\n Injectable,\n untracked,\n type Signal,\n} from '@angular/core';\nimport { FormControl } from '@angular/forms';\nimport { pluginService, type EmbedPdfFeature } from '@embedpdf/angular/runtime';\nimport {\n formPlugin,\n formState,\n FormToken,\n type FormConfig,\n type FormFieldRef,\n type FormFieldValue,\n type FormPlainValue,\n} from '@embedpdf/plugin-form';\n\n/** A field's ref, or a function that gives it (a component input, a route parameter). */\nexport type FieldRefSource = FormFieldRef | (() => FormFieldRef);\n\nconst refGetter = (ref: FieldRefSource): (() => FormFieldRef) =>\n typeof ref === 'function' ? ref : () => ref;\n\n/** Two plain values the same: lists element by element, everything else by value. */\nconst samePlain = (left: FormPlainValue, right: FormPlainValue): boolean =>\n Array.isArray(left) && Array.isArray(right)\n ? left.length === right.length && left.every((value, index) => value === right[index])\n : left === right;\n\n/**\n * The form: `fields()`, `status()`, `formKind()` and `selectedField()` as signals; reading,\n * filling, form data and building as methods (`setValue()`, `importValues()`, `export()`,\n * `create()`, `update()`, …, the Methods tables of the Filling forms and Building forms pages);\n * the events as streams (`valueChanged$`, `validationRejected$`, `fieldCreated$`, …); and the\n * settings. Without a document, `fields()` is empty and a method refuses with `not-ready`.\n */\n@Injectable({ providedIn: 'root' })\nexport class EpdfForm extends pluginService({\n name: 'EpdfForm',\n feature: 'withForm()',\n token: FormToken,\n state: formState,\n methods: [\n 'getSnapshot',\n 'getStatus',\n 'getFormKind',\n 'list',\n 'get',\n 'getFieldForWidget',\n 'getWidget',\n 'getValue',\n 'listWidgets',\n 'getWidgetAt',\n 'getSelectedField',\n 'validate',\n 'exportValues',\n 'setValue',\n 'setValues',\n 'importValues',\n 'reset',\n 'activateWidget',\n 'export',\n 'import',\n 'refresh',\n 'create',\n 'update',\n 'delete',\n 'removeWidget',\n 'deleteWidget',\n 'reorderCalculations',\n 'repair',\n 'canRead',\n 'canFill',\n 'canDesign',\n 'canRestoreAttribution',\n 'canWriteScripts',\n ],\n events: [\n 'onValueChanged',\n 'onFieldCreated',\n 'onFieldUpdated',\n 'onFieldDeleted',\n 'onValidationRejected',\n 'onResynced',\n ],\n}) {\n /**\n * One field's value, in the shape `setValue()` takes, as a signal: it changes only when that\n * field's value does, and is `null` for a field without a value, and without a document. Keep\n * it in a field (`readonly total = form.valueOf(toFieldRef('total'))`); `ref` may be a\n * function, such as a signal input, and the value follows it.\n *\n * (`override`: every object has a `valueOf()` without arguments, which JavaScript calls to\n * turn it into a primitive. Called that way, this returns a signal, which isn't one, so\n * JavaScript goes on to `toString()` as it would without it.)\n */\n override valueOf(ref: FieldRefSource): Signal<FormFieldValue | null> {\n const refOf = refGetter(ref);\n // The plugin keeps one value object per field while the field stays the same.\n return this.binding.select((form) => form.getValue(refOf()), null, Object.is);\n }\n\n /**\n * One field as a Reactive Forms `FormControl`, for an input of your own:\n * `<input [formControl]=\"name\" />`. The control holds the field's value as plain data (a text\n * box's, dropdown's or radio group's text, a checkbox's `true` or `false`, a list's selected\n * values; `null` for none), and takes every change of it, whoever made it. A change of the\n * control fills in the field, with the same checks and scripts as typing in the PDF does; a\n * value the form refuses puts the field's value back in the control. The control is disabled\n * while the field can't be filled in: no such field (yet), a read-only one, or no\n * `doc.forms.fill`.\n *\n * Call it in an injection context (a constructor or a field initializer): the control follows\n * the field for as long as the caller lives.\n */\n controlOf(ref: FieldRefSource): FormControl<FormPlainValue> {\n assertInInjectionContext(this.controlOf);\n const refOf = refGetter(ref);\n const field = this.binding.select((form) => form.get(refOf()), null, Object.is);\n // The plain value the plugin exports for the field, so a control reads what\n // `exportValues()` gives and writes what `importValues()` takes.\n const value = this.binding.select(\n (form) => {\n const current = form.get(refOf());\n return current ? (form.exportValues()[current.name] ?? null) : null;\n },\n null,\n samePlain,\n );\n const fillable = this.binding.select(\n (form) => {\n const current = form.get(refOf());\n return current !== null && !current.readOnly && form.canFill(current.ref);\n },\n false,\n );\n\n const control = new FormControl<FormPlainValue>(untracked(value));\n const show = (plain: FormPlainValue) => {\n if (!samePlain(plain, control.value)) control.setValue(plain, { emitEvent: false });\n };\n\n // The field shows a write as soon as it's made, so the control follows the field: a value\n // the form refuses, or its scripts rewrite, shows as the field has it.\n effect(() => {\n const plain = value();\n untracked(() => show(plain));\n });\n effect(() => {\n const enabled = fillable();\n untracked(() =>\n enabled ? control.enable({ emitEvent: false }) : control.disable({ emitEvent: false }),\n );\n });\n\n const subscription = control.valueChanges.subscribe((plain) => {\n const name = untracked(field)?.name;\n if (name === undefined) return;\n // By name, through the plugin's own plain-value conversion and its write queue.\n void Promise.resolve()\n .then(() => this.importValues({ [name]: plain }))\n .catch(() => undefined);\n });\n inject(DestroyRef).onDestroy(() => subscription.unsubscribe());\n return control;\n }\n}\n\n/** The form plugin: fields people fill in on every page with an `<epdf-form-layer>`. */\nexport function withForm(config?: FormConfig): EmbedPdfFeature {\n return { plugins: [formPlugin(config)], services: [EpdfForm] };\n}\n","/**\n * A PDF list box as a visible native `<select>`. A list needs one owner for its pixels, its\n * hit-testing and its scrolling: a baked PDF picture under an invisible select can't give that,\n * because the browser and the PDF would each keep their own top row. So the select is the list,\n * and it's never made again while the field is shown: its scroll position is the user's.\n *\n * A choice shows at once while its write is on its way, and the engine's selection again if\n * the write fails (`@embedpdf/web`'s `createOptimisticSelection`). The wheel stays in the list,\n * so it scrolls instead of the Stage below panning or zooming.\n */\nimport { isPlatformBrowser } from '@angular/common';\nimport {\n afterRenderEffect,\n ChangeDetectionStrategy,\n Component,\n computed,\n DestroyRef,\n effect,\n ElementRef,\n inject,\n input,\n PLATFORM_ID,\n signal,\n untracked,\n} from '@angular/core';\nimport { createOptimisticSelection, isolateWheel, showSelectedOptions } from '@embedpdf/web';\n\n/** One row of a list box. */\nexport interface FormListBoxOption {\n label: string;\n value: string;\n}\n\n@Component({\n selector: 'select[epdfFormListBox]',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '[attr.aria-label]': 'label()',\n '[multiple]': 'multi()',\n '[attr.size]': 'size()',\n '[disabled]': 'disabled()',\n '(change)': 'choose()',\n },\n template: `\n @for (option of options(); track $index) {\n <option [value]=\"option.value\">{{ option.label }}</option>\n }\n `,\n})\nexport class FormListBox {\n readonly label = input.required<string>();\n readonly disabled = input(false);\n /** Whether several rows can be selected. */\n readonly multi = input(false);\n readonly options = input.required<readonly FormListBoxOption[]>();\n /** The selection the engine has. */\n readonly selected = input.required<readonly string[]>();\n /** Writes a choice; a promise that rejects puts the engine's selection back. */\n readonly write = input.required<(values: string[]) => void | Promise<unknown> | undefined>();\n\n private readonly element = inject<ElementRef<HTMLSelectElement>>(ElementRef).nativeElement;\n\n /** Every row shows at least two, so a list never looks like a dropdown. */\n protected readonly size = computed(() => Math.max(2, this.options().length));\n\n /**\n * The optimistic selection, made at the first read (inputs are there by then) from the\n * engine's selection. It reads no signal, so it's made once.\n */\n private readonly selection = computed(() =>\n createOptimisticSelection(untracked(this.selected)),\n );\n /** Goes up whenever the selection shows something new. */\n private readonly changes = signal(0);\n /** The selection the list shows. */\n private readonly shown = computed(() => {\n this.changes();\n return this.selection().get();\n });\n\n constructor() {\n effect((onCleanup) => {\n const selection = this.selection();\n onCleanup(selection.subscribe(() => this.changes.update((count) => count + 1)));\n });\n effect(() => {\n const selected = this.selected();\n untracked(() => this.selection().setConfirmed(selected));\n });\n // The rows' selected state is written after each render, not bound: a choice that is\n // refused before the next render leaves the shown selection as it was, and a binding that\n // didn't change would leave the user's row selected.\n afterRenderEffect({\n write: () => {\n const shown = this.shown();\n this.options();\n showSelectedOptions(this.element, shown);\n },\n });\n if (isPlatformBrowser(inject(PLATFORM_ID))) {\n inject(DestroyRef).onDestroy(isolateWheel(this.element));\n }\n }\n\n protected choose(): void {\n const values = Array.from(this.element.selectedOptions, (option) => option.value);\n this.selection().choose(values, (chosen) => this.write()(chosen) ?? undefined);\n }\n}\n","/**\n * What every field control on a page shares: its box. The box is placed over the field's\n * widget on the page, and is the widget's event surface:\n *\n * - it is always there for the pointer, whatever the control inside allows, so a field that\n * can't be filled in still runs its PDF actions on enter, exit, press, release, focus and blur\n * (\"may edit this field\" and \"may receive PDF action events\" are different rights);\n * - it keeps a press that begins in it from the Stage below (which would start the active\n * tool's gesture, or end an edit as a click outside), and still sends it to the field's PDF\n * \"mouse down\" action;\n * - a field without a border of its own gets an edge in the form settings' color, so people\n * see where to fill in (lists and buttons draw their own).\n *\n * Each control (`controls.ts`) is a component whose host element is its box: it extends this\n * class and adds its own control inside. The listeners, the box's style and the colors are\n * `@embedpdf/web`'s, the same for every framework.\n */\nimport { isPlatformBrowser } from '@angular/common';\nimport {\n computed,\n DestroyRef,\n Directive,\n ElementRef,\n inject,\n input,\n PLATFORM_ID,\n} from '@angular/core';\nimport { CapabilityBinding, injectKernelHost, injectPage } from '@embedpdf/angular/runtime';\nimport type { FormWidgetItem } from '@embedpdf/plugin-form';\nimport { FormToken as FormHostToken } from '@embedpdf/plugin-form/contract/host';\nimport {\n bindWidgetEvents,\n isolatePointerDown,\n rectInPixels,\n widgetBoxStyleOf,\n type FormColors,\n type WidgetEventKind,\n} from '@embedpdf/web';\n\n/** One kind of field widget, as the form layer draws it: `WidgetOf<'text'>`. */\nexport type WidgetOf<Control extends FormWidgetItem['control']> = Extract<\n FormWidgetItem,\n { control: Control }\n>;\n\n@Directive({\n host: { '[style]': 'boxStyle()' },\n})\nexport abstract class FormWidgetBox<Item extends FormWidgetItem> {\n /** The widget: where it is, how it looks, its control and its value. */\n readonly item = input.required<Item>();\n /** The colors the viewer draws fields with: the form settings over the accent. */\n readonly colors = input.required<FormColors>();\n\n protected readonly page = injectPage('<epdf-form-layer>');\n protected readonly element = inject<ElementRef<HTMLElement>>(ElementRef).nativeElement;\n /** The form plugin's host side, for the page's own document: writes, drafts, activation. */\n protected readonly form = new CapabilityBinding(\n injectKernelHost('<epdf-form-layer>'),\n () => FormHostToken,\n () => this.page.documentId,\n ).capability;\n\n /** Whether a field without a border of its own gets an edge. A list and a button draw their own. */\n protected readonly drawsEdge: boolean = true;\n\n /** The box in the page layer's pixels: moves with the camera. */\n protected readonly frame = computed(() => rectInPixels(this.item().box, this.page.transform()));\n\n /** The box's place over the widget, and its edge. */\n protected readonly boxStyle = computed(() =>\n widgetBoxStyleOf(this.item(), this.frame(), this.colors(), { edge: this.drawsEdge }),\n );\n\n constructor() {\n if (!isPlatformBrowser(inject(PLATFORM_ID))) return;\n // Native listeners on the box: the PDF events of the widget, and the press kept from the\n // Stage. `bindWidgetEvents` sends the press as \"mouse down\" itself; the press only stops\n // here, so both run.\n const detachEvents = bindWidgetEvents(this.element, (kind) => this.notify(kind));\n const detachPress = isolatePointerDown(this.element);\n inject(DestroyRef).onDestroy(() => {\n detachEvents();\n detachPress();\n });\n }\n\n /**\n * Run the widget's own action, as a click on it does. ISO 32000 puts the activate action on\n * the widget, whatever its field, and many forms ship \"buttons\" as read-only text fields with\n * an action that Acrobat runs; a widget without one does nothing.\n */\n protected activate(): void {\n const widget = this.item().annotationRef;\n const form = this.form();\n if (widget && form) void form.activateWidget(widget);\n }\n\n /** One of the widget's pointer and focus events, for its `/AA` actions. */\n private notify(kind: WidgetEventKind): void {\n const item = this.item();\n const form = this.form();\n if (item.annotationRef && form) form.notifyWidgetEvent(item.fieldRef, item.annotationRef, kind);\n }\n}\n","/**\n * The controls `<epdf-form-layer>` puts over a page's fields, one per widget. Each is a\n * component whose host element is the widget's box (`widget-box.ts`), with a real HTML control\n * inside. The field's own picture (the engine's drawing of its value, borders and fonts) is\n * drawn below, by the form layer's `<epdf-field-pictures>`; the controls add what people work\n * with on top of it:\n *\n * text the picture at rest; focus shows an editor in the field's own font (the plugin\n * keeps what's typed, so a download writes it); blur or Enter commits, Escape\n * puts the value back\n * toggle the picture is the control; a click writes the toggled value\n * combo an invisible native <select> over the picture: the browser owns the dropdown,\n * the engine the pixels at rest\n * list a visible native <select> (`list-box.ts`): one surface owns the rows, the\n * keyboard and the scrolling\n * button a native click target over the picture, which runs the widget's action\n * signature with the signature plugin, \"sign here\" on an empty field, and the signature's\n * details on a signed one\n *\n * The text-editing, toggle and list policies, the field looks, the controls' styles and the\n * colors are `@embedpdf/web`'s, the same for every framework.\n */\nimport { isPlatformBrowser } from '@angular/common';\nimport {\n afterRenderEffect,\n ChangeDetectionStrategy,\n Component,\n computed,\n DestroyRef,\n effect,\n ElementRef,\n inject,\n input,\n PLATFORM_ID,\n signal,\n untracked,\n viewChild,\n} from '@angular/core';\nimport { CapabilityBinding, injectKernelHost } from '@embedpdf/angular/runtime';\nimport { SignatureToken } from '@embedpdf/plugin-signature/contract';\nimport {\n createFontMounts,\n createTextFieldEditor,\n FORM_CONTROL_FILL,\n formFocusRingStyleOf,\n listBoxControlStyleOf,\n pressToggle,\n textFieldEditorStyleOf,\n type TextFieldEditorState,\n} from '@embedpdf/web';\nimport { FormListBox } from './list-box';\nimport { FormWidgetBox, type WidgetOf } from './widget-box';\n\n/**\n * The focus ring of a field whose control is see-through or is the box itself: painted above\n * the field's picture, because an outline on the box would sit under an opaque child, and a\n * checkbox or a dropdown would look unfocused while it has the focus.\n */\n@Component({\n selector: 'span[epdfFormFocusRing]',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n 'aria-hidden': 'true',\n 'data-embedpdf-form-focus-ring': '',\n '[style]': 'ringStyle()',\n },\n template: '',\n})\nexport class FormFocusRing {\n /** The ring's CSS color: the form's `focus.color` setting, through its CSS variable. */\n readonly color = input.required<string>();\n\n protected readonly ringStyle = computed(() => formFocusRingStyleOf(this.color()));\n}\n\n/** A text box: the picture at rest, an editor in the field's own font while focused. */\n@Component({\n selector: 'div[epdfFormText]',\n changeDetection: ChangeDetectionStrategy.OnPush,\n // A click runs the widget's action too, as in Acrobat: the editor's focus click bubbles\n // here, and a read-only field's lands here directly.\n host: { '(click)': 'activate()' },\n template: `\n @if (item().multiline) {\n <textarea\n #field\n [value]=\"state().draft\"\n [attr.maxlength]=\"item().maxLength\"\n [attr.aria-label]=\"item().label\"\n [disabled]=\"item().disabled\"\n [style]=\"editorStyle()\"\n (focus)=\"editor()?.focus()\"\n (input)=\"editor()?.input(field.value)\"\n (blur)=\"editor()?.blur()\"\n (keydown)=\"keyDown($event, field)\"\n ></textarea>\n } @else {\n <input\n #field\n [type]=\"item().password ? 'password' : 'text'\"\n [value]=\"state().draft\"\n [attr.maxlength]=\"item().maxLength\"\n [attr.aria-label]=\"item().label\"\n [disabled]=\"item().disabled\"\n [style]=\"editorStyle()\"\n (focus)=\"editor()?.focus()\"\n (input)=\"editor()?.input(field.value)\"\n (blur)=\"editor()?.blur()\"\n (keydown)=\"keyDown($event, field)\"\n />\n }\n `,\n})\nexport class FormTextControl extends FormWidgetBox<WidgetOf<'text'>> {\n /**\n * The editing policy of this field. The editor is always there, see-through at rest and\n * shown while focused: the DOM is the focus manager, so Tab reaches every field. A control is\n * one widget for its whole life (the layer tracks widgets by field and widget), so one\n * editor per form.\n */\n protected readonly editor = computed(() => {\n const form = this.form();\n return form\n ? untracked(() => createTextFieldEditor(form, this.item().fieldRef, this.item().value))\n : null;\n });\n\n protected readonly state = signal<TextFieldEditorState>({ focused: false, draft: '' });\n\n /** The text being typed, where the engine will draw it, in its face. */\n private readonly layout = computed(() => {\n const form = this.form();\n const widget = this.item().annotationRef;\n return form && widget ? form.getTextEditorLayout(widget, this.state().draft) : null;\n });\n\n protected readonly editorStyle = computed(() =>\n textFieldEditorStyleOf(\n this.item(),\n this.frame(),\n this.colors(),\n this.state().focused,\n this.layout(),\n ),\n );\n\n constructor() {\n super();\n if (isPlatformBrowser(inject(PLATFORM_ID))) {\n const mounts = createFontMounts();\n inject(DestroyRef).onDestroy(() => mounts.release());\n effect(() => {\n const layout = this.layout();\n if (layout) mounts.mount([layout.program]);\n });\n }\n effect((onCleanup) => {\n const editor = this.editor();\n if (!editor) return;\n untracked(() => this.state.set(editor.getState()));\n onCleanup(editor.subscribe(() => this.state.set(editor.getState())));\n });\n // Take the field's value whenever it changes under us; the editor never takes it mid-edit.\n effect(() => {\n const editor = this.editor();\n const value = this.item().value;\n if (editor) untracked(() => editor.setValue(value));\n });\n }\n\n protected keyDown(event: KeyboardEvent, field: HTMLInputElement | HTMLTextAreaElement): void {\n if (this.editor()?.keyDown(event.key, this.item().multiline)) field.blur();\n }\n}\n\n/** A checkbox or a radio button: the picture is the control, a click writes the toggled value. */\n@Component({\n selector: 'div[epdfFormToggle]',\n imports: [FormFocusRing],\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '[attr.role]': \"item().kind === 'checkbox' ? 'checkbox' : 'radio'\",\n '[attr.aria-checked]': 'item().checked',\n '[attr.aria-label]': 'item().label',\n '[attr.tabindex]': 'item().disabled ? -1 : 0',\n '[style.cursor]': \"item().disabled ? 'default' : 'pointer'\",\n '[style.outline]': \"'none'\",\n '(click)': 'press()',\n '(keydown)': 'keyDown($event)',\n '(focus)': 'focused.set(true)',\n '(blur)': 'focused.set(false)',\n },\n template: `\n @if (focused()) {\n <span epdfFormFocusRing [color]=\"colors().focus\"></span>\n }\n `,\n})\nexport class FormToggleControl extends FormWidgetBox<WidgetOf<'toggle'>> {\n protected readonly focused = signal(false);\n\n /** The value first, then the widget's action (Acrobat's order), so its script reads the new state. */\n protected press(): void {\n const form = this.form();\n if (form) pressToggle(form, this.item(), () => this.activate());\n }\n\n protected keyDown(event: KeyboardEvent): void {\n if (event.key !== ' ' && event.key !== 'Enter') return;\n event.preventDefault();\n this.press();\n }\n}\n\n/** A dropdown: an invisible native select over the field's picture. */\n@Component({\n selector: 'div[epdfFormCombo]',\n imports: [FormFocusRing],\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: { '(click)': 'activate()' },\n template: `\n <select\n #select\n [attr.aria-label]=\"item().label\"\n [disabled]=\"item().disabled\"\n [style]=\"selectStyle()\"\n (focus)=\"focused.set(true)\"\n (blur)=\"focused.set(false)\"\n (change)=\"choose(select.value)\"\n >\n @if (item().selected.length === 0) {\n <option value=\"\"></option>\n }\n @for (option of item().options; track $index) {\n <option [value]=\"option.value\">{{ option.label }}</option>\n }\n </select>\n @if (focused()) {\n <span epdfFormFocusRing [color]=\"colors().focus\"></span>\n }\n `,\n})\nexport class FormComboControl extends FormWidgetBox<WidgetOf<'choice'>> {\n protected readonly focused = signal(false);\n private readonly select = viewChild.required<ElementRef<HTMLSelectElement>>('select');\n /** The field's choice, and its options, by value: what the select is set to show. */\n private readonly choice = computed(() => this.item().selected[0] ?? '');\n private readonly optionValues = computed(() =>\n this.item().options.map((option) => option.value).join('\\0'),\n );\n\n protected readonly selectStyle = computed(() => {\n const { disabled } = this.item();\n return {\n ...FORM_CONTROL_FILL,\n opacity: '0',\n cursor: disabled ? 'default' : 'pointer',\n 'pointer-events': disabled ? 'none' : null,\n };\n });\n\n constructor() {\n super();\n // The select shows the field's choice whenever that changes, and is the user's otherwise:\n // a write on its way (which disables the field for a moment) leaves their choice alone.\n afterRenderEffect({\n write: () => {\n const choice = this.choice();\n this.optionValues();\n this.select().nativeElement.value = choice;\n },\n });\n }\n\n protected choose(value: string): void {\n void this.form()?.setValue(this.item().fieldRef, { value: value || null });\n }\n}\n\n/** A list: a visible native select in the field's own look, the settings where it has none. */\n@Component({\n selector: 'div[epdfFormList]',\n imports: [FormFocusRing, FormListBox],\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: { '(click)': 'activate()' },\n template: `\n <select\n epdfFormListBox\n [label]=\"item().label\"\n [disabled]=\"item().disabled\"\n [multi]=\"item().multi\"\n [options]=\"item().options\"\n [selected]=\"item().selected\"\n [write]=\"write\"\n [style]=\"listStyle()\"\n (focus)=\"focused.set(true)\"\n (blur)=\"focused.set(false)\"\n ></select>\n @if (focused()) {\n <span epdfFormFocusRing [color]=\"colors().focus\"></span>\n }\n `,\n})\nexport class FormListControl extends FormWidgetBox<WidgetOf<'choice'>> {\n protected override readonly drawsEdge = false;\n protected readonly focused = signal(false);\n\n protected readonly listStyle = computed(() =>\n listBoxControlStyleOf(this.item(), this.frame(), this.colors()),\n );\n\n /** The list's write: the selection it shows at once, and the engine's once this resolves. */\n protected readonly write = (values: string[]) =>\n this.form()?.setValue(this.item().fieldRef, { selectedValues: values });\n}\n\n/** A push button: a native click target over its picture that runs its action. */\n@Component({\n selector: 'div[epdfFormButton]',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: { '[style.cursor]': \"item().disabled ? 'default' : 'pointer'\" },\n template: `\n <button\n type=\"button\"\n [attr.aria-label]=\"item().label\"\n [disabled]=\"item().disabled\"\n [style]=\"buttonStyle()\"\n (click)=\"activate()\"\n ></button>\n `,\n})\nexport class FormButtonControl extends FormWidgetBox<WidgetOf<'button'>> {\n protected override readonly drawsEdge = false;\n\n protected readonly buttonStyle = computed(() => ({\n ...FORM_CONTROL_FILL,\n padding: '0',\n border: '0',\n background: 'transparent',\n cursor: 'inherit',\n // The box is the event surface; a disabled button must not swallow the pointer.\n 'pointer-events': this.item().disabled ? 'none' : 'auto',\n }));\n}\n\n/**\n * A signature field: with the signature plugin, an empty field is \"sign here\" (it becomes the\n * target the next mark goes to), and a signed one asks your UI to show its details. Without\n * the plugin, the field is only its picture.\n */\n@Component({\n selector: 'div[epdfFormSignature]',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: { '[style.cursor]': \"actionable() ? 'pointer' : 'default'\" },\n template: `\n @if (actionable()) {\n <button\n type=\"button\"\n [attr.aria-label]=\"item().label\"\n [attr.data-signed]=\"signed() ? '' : null\"\n [style]=\"buttonStyle\"\n (click)=\"open()\"\n ></button>\n }\n `,\n})\nexport class FormSignatureControl extends FormWidgetBox<WidgetOf<'signature'>> {\n private readonly signature = new CapabilityBinding(\n injectKernelHost('<epdf-form-layer>'),\n () => SignatureToken,\n () => this.page.documentId,\n );\n\n private readonly signedByPlugin = this.signature.select(\n (signature) => signature.getSignature(this.item().fieldRef)?.signed ?? null,\n null,\n );\n /**\n * Whether the field is signed: the signature plugin knows best (it reads again after every\n * new version), the field's own value is the fallback.\n */\n protected readonly signed = computed(() => this.signedByPlugin() ?? this.item().signed);\n\n protected readonly actionable = computed(\n () => this.signature.capability() !== null && (this.signed() || !this.item().disabled),\n );\n\n protected readonly buttonStyle = {\n ...FORM_CONTROL_FILL,\n padding: '0',\n border: '0',\n background: 'transparent',\n cursor: 'inherit',\n };\n\n protected open(): void {\n const signature = this.signature.capability();\n if (!signature) return;\n const field = this.item().fieldRef;\n if (this.signed()) signature.requestInspection(field);\n else signature.setTarget(field);\n }\n}\n","/**\n * `<epdf-field-pictures>`: the page's fields as they look now, under the form layer's controls.\n * Each widget shows its picture, as the engine draws it (the form plugin's, every state loaded, so\n * a check box shows its new state at once), or the painter's drawing while its look is pending or\n * its picture is of an older version (`pictureOrPainting`): a value, a calculation, a restyle\n * shows at once. Hidden widgets aren't drawn.\n */\nimport { isPlatformBrowser } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n computed,\n DestroyRef,\n effect,\n inject,\n PLATFORM_ID,\n signal,\n untracked,\n} from '@angular/core';\nimport {\n CapabilityBinding,\n EpdfSvgShapes,\n injectKernelHost,\n injectPage,\n} from '@embedpdf/angular/runtime';\nimport { annotationKey } from '@embedpdf/core';\nimport { MITER_LIMIT } from '@embedpdf/core-annotation';\nimport { FormToken as FormHostToken, type ShownWidget } from '@embedpdf/plugin-form/contract/host';\nimport { RenderToken } from '@embedpdf/plugin-render/contract/host';\nimport {\n createShownUrls,\n loadAppearanceUrls,\n pictureOrPainting,\n rectInPixels,\n shownAppearance,\n svgShapesOf,\n type AppearanceUrl,\n type PixelRect,\n type SvgShape,\n} from '@embedpdf/web';\n\nconst NO_WIDGETS: readonly ShownWidget[] = Object.freeze([]);\n\n/** A widget as the template draws it: its picture, or the painter's shapes in its box. */\ntype ShownLook = { key: string; frame: PixelRect } & (\n | { kind: 'picture'; url: string }\n | { kind: 'painting'; viewBox: string; shapes: SvgShape[] }\n);\n\n@Component({\n selector: 'epdf-field-pictures',\n imports: [EpdfSvgShapes],\n changeDetection: ChangeDetectionStrategy.OnPush,\n // A global `img { max-width: 100% }` reset would clamp a picture: the sizes are explicit.\n template: `\n @for (look of looks(); track look.key) {\n @if (look.kind === 'picture') {\n <img\n alt=\"\"\n draggable=\"false\"\n style=\"position: absolute; max-width: none; max-height: none; pointer-events: none\"\n [attr.src]=\"look.url\"\n [style.left.px]=\"look.frame.left\"\n [style.top.px]=\"look.frame.top\"\n [style.width.px]=\"look.frame.width\"\n [style.height.px]=\"look.frame.height\"\n />\n } @else {\n <svg\n style=\"position: absolute; overflow: visible; pointer-events: none\"\n [attr.viewBox]=\"look.viewBox\"\n [style.left.px]=\"look.frame.left\"\n [style.top.px]=\"look.frame.top\"\n [style.width.px]=\"look.frame.width\"\n [style.height.px]=\"look.frame.height\"\n >\n <svg:g [epdfSvgShapes]=\"look.shapes\"></svg:g>\n </svg>\n }\n }\n `,\n})\nexport class EpdfFieldPictures {\n private readonly page = injectPage('<epdf-form-layer>');\n private readonly host = injectKernelHost('<epdf-form-layer>');\n private readonly render = new CapabilityBinding(\n this.host,\n () => RenderToken,\n () => this.page.documentId,\n );\n private readonly form = new CapabilityBinding(\n this.host,\n () => FormHostToken,\n () => this.page.documentId,\n );\n\n /** The widgets the page shows: the same array while none of them changes. */\n private readonly widgets = this.form.select(\n (form) => form.listShownWidgets(this.page.ref),\n NO_WIDGETS,\n );\n /** Loaded again when one of the page's widgets is drawn again, and at appearance-scale crossings. */\n private readonly epoch = this.form.select((form) => form.getAppearanceEpoch(this.page.ref), '');\n private readonly scale = this.render.select(\n (render) => render.getAppearanceScale(this.page.transform().renderScale),\n 0,\n );\n /** The pictures' URLs, by widget and state; `null` until the page's first ones arrive. */\n private readonly urls = signal<Record<string, AppearanceUrl> | null>(null);\n /** The pictures shown stay valid until the next ones are shown. */\n private readonly shown = createShownUrls();\n\n protected readonly looks = computed(() => {\n const urls = this.urls();\n const transform = this.page.transform();\n const form = this.form.capability();\n return this.widgets().flatMap((widget): ShownLook[] => {\n const key = annotationKey(widget.ref);\n const look = pictureOrPainting({\n pending: widget.pending,\n picture: urls && shownAppearance(urls, key, widget.appearanceState),\n version: widget.pictureVersion,\n loaded: urls !== null,\n paint: () => form?.getWidgetPainting(widget.ref) ?? null,\n });\n if (!look) return [];\n if (look.kind === 'picture') {\n return [\n {\n kind: 'picture',\n key,\n url: look.picture.url,\n frame: rectInPixels(look.picture.box, transform),\n },\n ];\n }\n const { x, y, width, height } = widget.rect;\n return [\n {\n kind: 'painting',\n key,\n viewBox: `${x} ${y} ${width} ${height}`,\n shapes: svgShapesOf(look.painting.scene, { miterLimit: MITER_LIMIT }),\n frame: rectInPixels(widget.rect, transform),\n },\n ];\n });\n });\n\n constructor() {\n if (!isPlatformBrowser(inject(PLATFORM_ID))) return;\n inject(DestroyRef).onDestroy(() => this.shown.release());\n effect((onCleanup) => {\n const form = this.form.capability();\n const scale = this.scale();\n const ref = this.page.ref;\n this.epoch();\n if (!form || !scale) return;\n onCleanup(\n untracked(() =>\n loadAppearanceUrls(\n this.shown,\n (signal) => form.renderAppearances(ref, scale, signal),\n annotationKey,\n (urls) => this.urls.set(urls),\n ),\n ),\n );\n });\n }\n}\n","/**\n * `<epdf-form-layer>`: the form's fields on one page, painted as the engine draws them (their\n * values, borders and fonts), with the controls people fill them in with. Put it above the\n * page's picture (`<epdf-render-layer>`, and `<epdf-annotation-layer>` when the annotation\n * plugin is registered); while it's there, the render layer leaves the fields out of the page's\n * picture:\n *\n * <ng-template epdfPage>\n * <epdf-render-layer />\n * <epdf-form-layer />\n * </ng-template>\n *\n * It works with or without the annotation plugin. The controls show while the active tool fills\n * forms (the `pointer` and `pan` tools do), and stand down in design mode, where fields are\n * boxes you select and move. Each field becomes a real HTML control (`controls.ts`), placed and\n * styled like the field in the PDF, in the colors of the form settings, which the\n * `--epdf-form-*` CSS variables override.\n */\nimport {\n ChangeDetectionStrategy,\n Component,\n computed,\n effect,\n signal,\n untracked,\n type Signal,\n} from '@angular/core';\nimport type { CapabilityToken } from '@embedpdf/core';\nimport {\n CapabilityBinding,\n injectKernelHost,\n injectPage,\n paintsPagePart,\n} from '@embedpdf/angular/runtime';\nimport {\n FORM_DEFAULTS,\n FormToken,\n type FormSettings,\n type FormWidgetItem,\n} from '@embedpdf/plugin-form';\nimport { FormToken as FormHostToken } from '@embedpdf/plugin-form/contract/host';\nimport { InteractionToken as InteractionHostToken } from '@embedpdf/plugin-interaction/contract/host';\nimport { formColorsOf } from '@embedpdf/web';\nimport {\n FormButtonControl,\n FormComboControl,\n FormListControl,\n FormSignatureControl,\n FormTextControl,\n FormToggleControl,\n} from './controls';\nimport { EpdfFieldPictures } from './field-pictures';\n\nconst NO_WIDGETS: readonly FormWidgetItem[] = Object.freeze([]);\n\n@Component({\n selector: 'epdf-form-layer',\n imports: [\n EpdfFieldPictures,\n FormTextControl,\n FormToggleControl,\n FormComboControl,\n FormListControl,\n FormButtonControl,\n FormSignatureControl,\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <div style=\"position: absolute; inset: 0; pointer-events: none\">\n <epdf-field-pictures />\n @if (active()) {\n <!-- One control per widget: a field with several boxes has one per box. -->\n @for (item of widgets(); track item.key + ':' + item.annotObjectNumber) {\n @switch (item.control) {\n @case ('text') {\n <div epdfFormText [item]=\"item\" [colors]=\"colors()\"></div>\n }\n @case ('toggle') {\n <div epdfFormToggle [item]=\"item\" [colors]=\"colors()\"></div>\n }\n @case ('choice') {\n @if (item.kind === 'list') {\n <div epdfFormList [item]=\"item\" [colors]=\"colors()\"></div>\n } @else {\n <div epdfFormCombo [item]=\"item\" [colors]=\"colors()\"></div>\n }\n }\n @case ('button') {\n <div epdfFormButton [item]=\"item\" [colors]=\"colors()\"></div>\n }\n @case ('signature') {\n <div epdfFormSignature [item]=\"item\" [colors]=\"colors()\"></div>\n }\n }\n }\n }\n </div>\n `,\n})\nexport class EpdfFormLayer {\n private readonly page = injectPage('<epdf-form-layer>');\n private readonly host = injectKernelHost('<epdf-form-layer>');\n\n /** A plugin of the page's own document: every plugin below is read for it. */\n private bindTo<Capability>(token: CapabilityToken<Capability>): CapabilityBinding<Capability> {\n return new CapabilityBinding(\n this.host,\n () => token,\n () => this.page.documentId,\n );\n }\n\n private readonly form = this.bindTo(FormHostToken);\n\n /** Whether the active tool fills forms: the layer draws nothing in design mode. */\n protected readonly active = this.bindTo(InteractionHostToken).select(\n (interaction) => interaction.activeToolEnables('form-fill'),\n false,\n );\n\n /** The page's widgets: the same array while nothing on the page changes. */\n protected readonly widgets = this.form.select(\n (form) => form.listWidgets(this.page.ref),\n NO_WIDGETS,\n );\n\n /** The form settings, with or without a document: they belong to the plugin. */\n private readonly settings: Signal<FormSettings> = this.host.provides(FormToken)\n ? this.host.settingsOf<FormSettings>(FormToken).current\n : signal(FORM_DEFAULTS).asReadonly();\n\n /** The colors the viewer draws fields with: the form settings over the viewer's accent. */\n protected readonly colors = computed(() => {\n const { focus, fields } = this.settings();\n return formColorsOf({ focus, fields }, this.host.viewerSettings().accent);\n });\n\n constructor() {\n // While it's here with the form plugin, the page's picture leaves the fields to it.\n paintsPagePart(() => (this.form.capability() ? this.page.ref : null), 'formFields');\n // Read the page's widgets when the layer comes to it: one read for the form.\n effect(() => {\n const form = this.form.capability();\n if (form) untracked(() => void form.ensureLoaded(this.page.ref));\n });\n }\n}\n","/**\n * @embedpdf/angular/form: PDF forms people fill in, and that your code reads, fills and builds.\n *\n * withForm(config) the plugin, for provideEmbedPdf()\n * inject(EpdfForm) the fields, filling, form data and building, as signals, methods\n * and streams\n * form.valueOf(ref) one field's value, as a signal\n * form.controlOf(ref) one field as a Reactive Forms FormControl\n * <epdf-form-layer> the fields on each page, as real HTML controls\n */\n\n// The plugin's types and helpers (`toFieldRef`), so app code has one import for the feature.\nexport * from '@embedpdf/plugin-form';\nexport { EpdfForm, withForm } from './form';\nexport type { FieldRefSource } from './form';\nexport { EpdfFormLayer } from './form-layer';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":["FormHostToken","NO_WIDGETS","InteractionHostToken"],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { historyState, HistoryToken, historyPlugin } from '@embedpdf/plugin-history';
|
|
2
|
+
export * from '@embedpdf/plugin-history';
|
|
3
|
+
import * as i0 from '@angular/core';
|
|
4
|
+
import { Injectable } from '@angular/core';
|
|
5
|
+
import { pluginService } from '@embedpdf/angular/runtime';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* The history plugin's service and feature: undo and redo of what you change through the viewer,
|
|
9
|
+
* one history per open document. An action shows undone at once, even while it is still on its
|
|
10
|
+
* way to the engine:
|
|
11
|
+
*
|
|
12
|
+
* protected readonly history = inject(EpdfHistory);
|
|
13
|
+
* <button [disabled]="!history.canUndo()" (click)="history.undo()">Undo</button>
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* The history of the document in scope (`[epdfDocumentScope]`), else the active one: `undo()`,
|
|
17
|
+
* `redo()`, `clear()`, the State table as signals (`canUndo()`, `canRedo()`, `undoLabel()`,
|
|
18
|
+
* `redoLabel()`), the streams `undone$` and `undoFailed$`, and the settings. With no document
|
|
19
|
+
* the signals read false and null, and every call refuses with `not-ready`.
|
|
20
|
+
*/
|
|
21
|
+
class EpdfHistory extends pluginService({
|
|
22
|
+
name: 'EpdfHistory',
|
|
23
|
+
feature: 'withHistory()',
|
|
24
|
+
token: HistoryToken,
|
|
25
|
+
state: historyState,
|
|
26
|
+
methods: ['undo', 'redo', 'clear', 'getUndoLabel', 'getRedoLabel'],
|
|
27
|
+
events: ['onUndone', 'onUndoFailed'],
|
|
28
|
+
}) {
|
|
29
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: EpdfHistory, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
|
|
30
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: EpdfHistory, providedIn: 'root' });
|
|
31
|
+
}
|
|
32
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: EpdfHistory, decorators: [{
|
|
33
|
+
type: Injectable,
|
|
34
|
+
args: [{ providedIn: 'root' }]
|
|
35
|
+
}] });
|
|
36
|
+
/** Undo and redo, with their settings: `withHistory({ limit: 200 })`. */
|
|
37
|
+
function withHistory(options) {
|
|
38
|
+
return { plugins: [historyPlugin(options)], services: [EpdfHistory] };
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* @embedpdf/angular/history: undo and redo, one history per open document.
|
|
43
|
+
*
|
|
44
|
+
* withHistory() the plugin, for provideEmbedPdf()
|
|
45
|
+
* inject(EpdfHistory) undo(), redo(), canUndo(), undoLabel(), undone$, …
|
|
46
|
+
*/
|
|
47
|
+
// The plugin's types and helpers, so app code has one import for the feature.
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Generated bundle index. Do not edit.
|
|
51
|
+
*/
|
|
52
|
+
|
|
53
|
+
export { EpdfHistory, withHistory };
|
|
54
|
+
//# sourceMappingURL=embedpdf-angular-history.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"embedpdf-angular-history.mjs","sources":["../../history/src/history.ts","../../history/src/public_api.ts","../../history/src/embedpdf-angular-history.ts"],"sourcesContent":["/**\n * The history plugin's service and feature: undo and redo of what you change through the viewer,\n * one history per open document. An action shows undone at once, even while it is still on its\n * way to the engine:\n *\n * protected readonly history = inject(EpdfHistory);\n * <button [disabled]=\"!history.canUndo()\" (click)=\"history.undo()\">Undo</button>\n */\nimport { Injectable } from '@angular/core';\nimport { pluginService, type EmbedPdfFeature } from '@embedpdf/angular/runtime';\nimport {\n historyPlugin,\n historyState,\n HistoryToken,\n type HistoryConfig,\n} from '@embedpdf/plugin-history';\n\n/**\n * The history of the document in scope (`[epdfDocumentScope]`), else the active one: `undo()`,\n * `redo()`, `clear()`, the State table as signals (`canUndo()`, `canRedo()`, `undoLabel()`,\n * `redoLabel()`), the streams `undone$` and `undoFailed$`, and the settings. With no document\n * the signals read false and null, and every call refuses with `not-ready`.\n */\n@Injectable({ providedIn: 'root' })\nexport class EpdfHistory extends pluginService({\n name: 'EpdfHistory',\n feature: 'withHistory()',\n token: HistoryToken,\n state: historyState,\n methods: ['undo', 'redo', 'clear', 'getUndoLabel', 'getRedoLabel'],\n events: ['onUndone', 'onUndoFailed'],\n}) {}\n\n/** Undo and redo, with their settings: `withHistory({ limit: 200 })`. */\nexport function withHistory(options?: HistoryConfig): EmbedPdfFeature {\n return { plugins: [historyPlugin(options)], services: [EpdfHistory] };\n}\n","/**\n * @embedpdf/angular/history: undo and redo, one history per open document.\n *\n * withHistory() the plugin, for provideEmbedPdf()\n * inject(EpdfHistory) undo(), redo(), canUndo(), undoLabel(), undone$, …\n */\n\n// The plugin's types and helpers, so app code has one import for the feature.\nexport * from '@embedpdf/plugin-history';\nexport * from './history';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":";;;;;;AAAA;;;;;;;AAOG;AAUH;;;;;AAKG;AAEG,MAAO,WAAY,SAAQ,aAAa,CAAC;AAC7C,IAAA,IAAI,EAAE,aAAa;AACnB,IAAA,OAAO,EAAE,eAAe;AACxB,IAAA,KAAK,EAAE,YAAY;AACnB,IAAA,KAAK,EAAE,YAAY;IACnB,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,cAAc,CAAC;AAClE,IAAA,MAAM,EAAE,CAAC,UAAU,EAAE,cAAc,CAAC;CACrC,CAAC,CAAA;uGAPW,WAAW,EAAA,IAAA,EAAA,IAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAAX,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAW,cADE,MAAM,EAAA,CAAA;;2FACnB,WAAW,EAAA,UAAA,EAAA,CAAA;kBADvB,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;AAUlC;AACM,SAAU,WAAW,CAAC,OAAuB,EAAA;AACjD,IAAA,OAAO,EAAE,OAAO,EAAE,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,WAAW,CAAC,EAAE;AACvE;;ACpCA;;;;;AAKG;AAEH;;ACPA;;AAEG;;;;"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { i18nState, I18nToken, i18nPlugin } from '@embedpdf/plugin-i18n';
|
|
2
|
+
export * from '@embedpdf/plugin-i18n';
|
|
3
|
+
import * as i0 from '@angular/core';
|
|
4
|
+
import { Injectable, inject, Pipe } from '@angular/core';
|
|
5
|
+
import { pluginService } from '@embedpdf/angular/runtime';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* The translations plugin's service, feature and pipe:
|
|
9
|
+
*
|
|
10
|
+
* withI18n(options) the plugin, for provideEmbedPdf()
|
|
11
|
+
* inject(EpdfI18n) `locale()`, `direction()`, `locales()`, `loading()`, `setLocale()`, …
|
|
12
|
+
* {{ 'key' | epdfT }} a string in the current language, updated when it changes
|
|
13
|
+
*
|
|
14
|
+
* The plugin needs no engine and no document, so a loading screen and a password prompt
|
|
15
|
+
* translate too, as soon as the viewer exists.
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* Before the viewer exists (a lazily loaded engine, or rendering on the server) there are no
|
|
19
|
+
* strings yet: a string shows its `fallback`, else its key, as a key no language has does.
|
|
20
|
+
*/
|
|
21
|
+
const untranslated = (key, options) => options?.fallback ?? key;
|
|
22
|
+
/**
|
|
23
|
+
* The languages: `locale()`, `direction()`, `locales()` and `loading()` as signals, `t()`,
|
|
24
|
+
* `setLocale()`, `addTranslations()` and `registerLocale()`, `localeChanged$` and
|
|
25
|
+
* `localeLoadFailed$`, and the settings. The plugin is the workspace's, so all of it works
|
|
26
|
+
* before a document opens.
|
|
27
|
+
*/
|
|
28
|
+
class EpdfI18n extends pluginService({
|
|
29
|
+
name: 'EpdfI18n',
|
|
30
|
+
feature: 'withI18n()',
|
|
31
|
+
token: I18nToken,
|
|
32
|
+
state: i18nState,
|
|
33
|
+
methods: [
|
|
34
|
+
't',
|
|
35
|
+
'getTranslator',
|
|
36
|
+
'hasKey',
|
|
37
|
+
'getLocale',
|
|
38
|
+
'getDirection',
|
|
39
|
+
'listLocales',
|
|
40
|
+
'getLoadingLocale',
|
|
41
|
+
'setLocale',
|
|
42
|
+
'registerLocale',
|
|
43
|
+
'addTranslations',
|
|
44
|
+
],
|
|
45
|
+
events: ['onLocaleChanged', 'onLocaleLoadFailed'],
|
|
46
|
+
}) {
|
|
47
|
+
/**
|
|
48
|
+
* The translate function as a signal: a new function when the language or the strings
|
|
49
|
+
* change, the same one otherwise. What the `epdfT` pipe reads; a `computed()` that calls it
|
|
50
|
+
* follows the language too.
|
|
51
|
+
*/
|
|
52
|
+
translator = this.binding.select((i18n) => i18n.getTranslator(), untranslated, Object.is);
|
|
53
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: EpdfI18n, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
|
|
54
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: EpdfI18n, providedIn: 'root' });
|
|
55
|
+
}
|
|
56
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: EpdfI18n, decorators: [{
|
|
57
|
+
type: Injectable,
|
|
58
|
+
args: [{ providedIn: 'root' }]
|
|
59
|
+
}] });
|
|
60
|
+
/** The translations plugin, with its settings: `withI18n({ locale, locales, loaders })`. */
|
|
61
|
+
function withI18n(options) {
|
|
62
|
+
return { plugins: [i18nPlugin(options)], services: [EpdfI18n] };
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* A string in the current language: `{{ 'toolbar.save' | epdfT }}`, or with the options `t()`
|
|
66
|
+
* takes, `{{ 'search.results' | epdfT: { params: { count } } }}`. It updates when the language
|
|
67
|
+
* or the strings change.
|
|
68
|
+
*
|
|
69
|
+
* Not pure, because the language is not one of its arguments: it reads the translator signal
|
|
70
|
+
* each time the template is checked, which is what wakes the template when the language
|
|
71
|
+
* changes, and the translator keeps a looked-up string cheap.
|
|
72
|
+
*/
|
|
73
|
+
class EpdfTPipe {
|
|
74
|
+
i18n = inject(EpdfI18n);
|
|
75
|
+
transform(key, options) {
|
|
76
|
+
return this.i18n.translator()(key, options);
|
|
77
|
+
}
|
|
78
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: EpdfTPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
79
|
+
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.2.4", ngImport: i0, type: EpdfTPipe, isStandalone: true, name: "epdfT", pure: false });
|
|
80
|
+
}
|
|
81
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: EpdfTPipe, decorators: [{
|
|
82
|
+
type: Pipe,
|
|
83
|
+
args: [{ name: 'epdfT', pure: false }]
|
|
84
|
+
}] });
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* @embedpdf/angular/i18n: the viewer in the user's language.
|
|
88
|
+
*
|
|
89
|
+
* withI18n(options) the plugin, for provideEmbedPdf()
|
|
90
|
+
* inject(EpdfI18n) the languages, as signals, calls and streams
|
|
91
|
+
* {{ 'key' | epdfT }} the EpdfTPipe: a string in the current language
|
|
92
|
+
*/
|
|
93
|
+
// The plugin's types and helpers (`negotiateLocale`), so app code has one import for the feature.
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Generated bundle index. Do not edit.
|
|
97
|
+
*/
|
|
98
|
+
|
|
99
|
+
export { EpdfI18n, EpdfTPipe, withI18n };
|
|
100
|
+
//# sourceMappingURL=embedpdf-angular-i18n.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"embedpdf-angular-i18n.mjs","sources":["../../i18n/src/i18n.ts","../../i18n/src/public_api.ts","../../i18n/src/embedpdf-angular-i18n.ts"],"sourcesContent":["/**\n * The translations plugin's service, feature and pipe:\n *\n * withI18n(options) the plugin, for provideEmbedPdf()\n * inject(EpdfI18n) `locale()`, `direction()`, `locales()`, `loading()`, `setLocale()`, …\n * {{ 'key' | epdfT }} a string in the current language, updated when it changes\n *\n * The plugin needs no engine and no document, so a loading screen and a password prompt\n * translate too, as soon as the viewer exists.\n */\nimport { inject, Injectable, Pipe, type PipeTransform, type Signal } from '@angular/core';\nimport { pluginService, type EmbedPdfFeature } from '@embedpdf/angular/runtime';\nimport {\n i18nPlugin,\n i18nState,\n I18nToken,\n type I18nConfig,\n type TranslateOptions,\n} from '@embedpdf/plugin-i18n';\n\n/** A translate function: `t('toolbar.save')`, `t('search.results', { params: { count } })`. */\nexport type Translate = (key: string, options?: TranslateOptions) => string;\n\n/**\n * Before the viewer exists (a lazily loaded engine, or rendering on the server) there are no\n * strings yet: a string shows its `fallback`, else its key, as a key no language has does.\n */\nconst untranslated: Translate = (key, options) => options?.fallback ?? key;\n\n/**\n * The languages: `locale()`, `direction()`, `locales()` and `loading()` as signals, `t()`,\n * `setLocale()`, `addTranslations()` and `registerLocale()`, `localeChanged$` and\n * `localeLoadFailed$`, and the settings. The plugin is the workspace's, so all of it works\n * before a document opens.\n */\n@Injectable({ providedIn: 'root' })\nexport class EpdfI18n extends pluginService({\n name: 'EpdfI18n',\n feature: 'withI18n()',\n token: I18nToken,\n state: i18nState,\n methods: [\n 't',\n 'getTranslator',\n 'hasKey',\n 'getLocale',\n 'getDirection',\n 'listLocales',\n 'getLoadingLocale',\n 'setLocale',\n 'registerLocale',\n 'addTranslations',\n ],\n events: ['onLocaleChanged', 'onLocaleLoadFailed'],\n}) {\n /**\n * The translate function as a signal: a new function when the language or the strings\n * change, the same one otherwise. What the `epdfT` pipe reads; a `computed()` that calls it\n * follows the language too.\n */\n readonly translator: Signal<Translate> = this.binding.select(\n (i18n) => i18n.getTranslator(),\n untranslated,\n Object.is,\n );\n}\n\n/** The translations plugin, with its settings: `withI18n({ locale, locales, loaders })`. */\nexport function withI18n(options?: I18nConfig): EmbedPdfFeature {\n return { plugins: [i18nPlugin(options)], services: [EpdfI18n] };\n}\n\n/**\n * A string in the current language: `{{ 'toolbar.save' | epdfT }}`, or with the options `t()`\n * takes, `{{ 'search.results' | epdfT: { params: { count } } }}`. It updates when the language\n * or the strings change.\n *\n * Not pure, because the language is not one of its arguments: it reads the translator signal\n * each time the template is checked, which is what wakes the template when the language\n * changes, and the translator keeps a looked-up string cheap.\n */\n@Pipe({ name: 'epdfT', pure: false })\nexport class EpdfTPipe implements PipeTransform {\n private readonly i18n = inject(EpdfI18n);\n\n transform(key: string, options?: TranslateOptions): string {\n return this.i18n.translator()(key, options);\n }\n}\n","/**\n * @embedpdf/angular/i18n: the viewer in the user's language.\n *\n * withI18n(options) the plugin, for provideEmbedPdf()\n * inject(EpdfI18n) the languages, as signals, calls and streams\n * {{ 'key' | epdfT }} the EpdfTPipe: a string in the current language\n */\n\n// The plugin's types and helpers (`negotiateLocale`), so app code has one import for the feature.\nexport * from '@embedpdf/plugin-i18n';\nexport * from './i18n';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":";;;;;;AAAA;;;;;;;;;AASG;AAcH;;;AAGG;AACH,MAAM,YAAY,GAAc,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,EAAE,QAAQ,IAAI,GAAG;AAE1E;;;;;AAKG;AAEG,MAAO,QAAS,SAAQ,aAAa,CAAC;AAC1C,IAAA,IAAI,EAAE,UAAU;AAChB,IAAA,OAAO,EAAE,YAAY;AACrB,IAAA,KAAK,EAAE,SAAS;AAChB,IAAA,KAAK,EAAE,SAAS;AAChB,IAAA,OAAO,EAAE;QACP,GAAG;QACH,eAAe;QACf,QAAQ;QACR,WAAW;QACX,cAAc;QACd,aAAa;QACb,kBAAkB;QAClB,WAAW;QACX,gBAAgB;QAChB,iBAAiB;AAClB,KAAA;AACD,IAAA,MAAM,EAAE,CAAC,iBAAiB,EAAE,oBAAoB,CAAC;CAClD,CAAC,CAAA;AACA;;;;AAIG;IACM,UAAU,GAAsB,IAAI,CAAC,OAAO,CAAC,MAAM,CAC1D,CAAC,IAAI,KAAK,IAAI,CAAC,aAAa,EAAE,EAC9B,YAAY,EACZ,MAAM,CAAC,EAAE,CACV;uGA5BU,QAAQ,EAAA,IAAA,EAAA,IAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAAR,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,QAAQ,cADK,MAAM,EAAA,CAAA;;2FACnB,QAAQ,EAAA,UAAA,EAAA,CAAA;kBADpB,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;AAgClC;AACM,SAAU,QAAQ,CAAC,OAAoB,EAAA;AAC3C,IAAA,OAAO,EAAE,OAAO,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,QAAQ,CAAC,EAAE;AACjE;AAEA;;;;;;;;AAQG;MAEU,SAAS,CAAA;AACH,IAAA,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC;IAExC,SAAS,CAAC,GAAW,EAAE,OAA0B,EAAA;QAC/C,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,GAAG,EAAE,OAAO,CAAC;IAC7C;uGALW,SAAS,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,IAAA,EAAA,CAAA;qGAAT,SAAS,EAAA,YAAA,EAAA,IAAA,EAAA,IAAA,EAAA,OAAA,EAAA,IAAA,EAAA,KAAA,EAAA,CAAA;;2FAAT,SAAS,EAAA,UAAA,EAAA,CAAA;kBADrB,IAAI;AAAC,YAAA,IAAA,EAAA,CAAA,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE;;;ACjFpC;;;;;;AAMG;AAEH;;ACRA;;AAEG;;;;"}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { interactionState, InteractionToken, interactionPlugin, feedbackPlugin } from '@embedpdf/plugin-interaction';
|
|
2
|
+
export * from '@embedpdf/plugin-interaction';
|
|
3
|
+
import { toolCursorsOf, attachPagePointer } from '@embedpdf/web';
|
|
4
|
+
export { svgCursor, vibrationFeedback, wkFeedback } from '@embedpdf/web';
|
|
5
|
+
import * as i0 from '@angular/core';
|
|
6
|
+
import { computed, effect, Injectable, inject, PLATFORM_ID, ElementRef, untracked, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
7
|
+
import { pluginService, injectPage, CapabilityBinding, injectKernelHost } from '@embedpdf/angular/runtime';
|
|
8
|
+
import { isPlatformBrowser } from '@angular/common';
|
|
9
|
+
import { InteractionToken as InteractionToken$1 } from '@embedpdf/plugin-interaction/contract/host';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* The interaction plugin's service and features: which tool the pointer works with, the tools
|
|
13
|
+
* you can switch to, and their cursors.
|
|
14
|
+
*
|
|
15
|
+
* withInteraction(options) the plugin, for provideEmbedPdf()
|
|
16
|
+
* withFeedback({ provider }) haptics for the moments that call for them
|
|
17
|
+
* inject(EpdfInteraction) `activeToolId()`, `activateTool()`, `toolChanged$`, …
|
|
18
|
+
*/
|
|
19
|
+
/** The same spec, compared by value: a spec rebuilt with the same content changes nothing. */
|
|
20
|
+
const sameSpec = (left, right) => JSON.stringify(left) === JSON.stringify(right);
|
|
21
|
+
/**
|
|
22
|
+
* The tools: `activeToolId()` and `tools()` as signals, `activateTool()`, `pushTool()` and
|
|
23
|
+
* `popTool()` to switch, `registerTool()` for a tool of your own, `toolChanged$` and the
|
|
24
|
+
* gesture streams, and the settings. Without a document there is no active tool.
|
|
25
|
+
*/
|
|
26
|
+
class EpdfInteraction extends pluginService({
|
|
27
|
+
name: 'EpdfInteraction',
|
|
28
|
+
feature: 'withInteraction()',
|
|
29
|
+
token: InteractionToken,
|
|
30
|
+
state: interactionState,
|
|
31
|
+
methods: [
|
|
32
|
+
'getActiveTool',
|
|
33
|
+
'getActiveToolId',
|
|
34
|
+
'getDefaultToolId',
|
|
35
|
+
'listTools',
|
|
36
|
+
'getTool',
|
|
37
|
+
'hasTool',
|
|
38
|
+
'activateTool',
|
|
39
|
+
'activateDefaultTool',
|
|
40
|
+
'pushTool',
|
|
41
|
+
'popTool',
|
|
42
|
+
'setToolCursor',
|
|
43
|
+
'registerTool',
|
|
44
|
+
],
|
|
45
|
+
events: ['onToolChanged', 'onGestureStarted', 'onGestureEnded', 'onGestureCancelled'],
|
|
46
|
+
}) {
|
|
47
|
+
/**
|
|
48
|
+
* Give a tool cursors of your own, such as a pen in the ink color, for as long as the caller
|
|
49
|
+
* lives: the tool gets its own cursors back when the component or directive that called it
|
|
50
|
+
* goes. `spec` is read again when the signals it reads change, so the cursor follows a color
|
|
51
|
+
* setting. `null` puts nothing in place. Call it in an injection context (a constructor or a
|
|
52
|
+
* field initializer).
|
|
53
|
+
*
|
|
54
|
+
* The cursor is the one pixel that follows the pointer with no delay, so it shows the armed
|
|
55
|
+
* tool better than anything drawn under the pointer could.
|
|
56
|
+
*/
|
|
57
|
+
overrideCursor(spec) {
|
|
58
|
+
const current = computed(spec, ...(ngDevMode ? [{ debugName: "current", equal: sameSpec }] : [{ equal: sameSpec }]));
|
|
59
|
+
effect((onCleanup) => {
|
|
60
|
+
const cursorSpec = current();
|
|
61
|
+
const interaction = this.binding.capability();
|
|
62
|
+
if (!cursorSpec || !interaction)
|
|
63
|
+
return;
|
|
64
|
+
interaction.setToolCursor(cursorSpec.toolId, toolCursorsOf(cursorSpec.cursors));
|
|
65
|
+
onCleanup(() => interaction.setToolCursor(cursorSpec.toolId, null));
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: EpdfInteraction, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
|
|
69
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: EpdfInteraction, providedIn: 'root' });
|
|
70
|
+
}
|
|
71
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: EpdfInteraction, decorators: [{
|
|
72
|
+
type: Injectable,
|
|
73
|
+
args: [{ providedIn: 'root' }]
|
|
74
|
+
}] });
|
|
75
|
+
/** The interaction plugin: the tools and the pointer. `withInteraction({ defaultTool: 'pan' })`. */
|
|
76
|
+
function withInteraction(options) {
|
|
77
|
+
return { plugins: [interactionPlugin(options)], services: [EpdfInteraction] };
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Haptics: one provider for the whole viewer, which plugins call at their moments (a word
|
|
81
|
+
* selected on a long press). `withFeedback({ provider: vibrationFeedback })`.
|
|
82
|
+
*/
|
|
83
|
+
function withFeedback(options) {
|
|
84
|
+
return { plugins: [feedbackPlugin(options)] };
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* `<epdf-page-pointer-source>`: a page's pointer input, for the tools. It covers the page as one
|
|
89
|
+
* transparent element, turns each pointer event into a point on the page (through the page
|
|
90
|
+
* context, so it needs nothing but the page), and hands it to the interaction plugin, whose
|
|
91
|
+
* active tool decides what the press means.
|
|
92
|
+
*
|
|
93
|
+
* You rarely mount it: a Stage takes its pointer input itself, and `<epdf-page-view>` mounts
|
|
94
|
+
* this below its layers when the interaction plugin is registered. It's here for a page surface
|
|
95
|
+
* of your own. Features never listen to the pointer themselves: they register with the
|
|
96
|
+
* interaction plugin.
|
|
97
|
+
*/
|
|
98
|
+
/**
|
|
99
|
+
* The page's pointer input, for the active tool. Put it first in the page's content, below the
|
|
100
|
+
* layers: a layer that lets the pointer through (the picture, a highlight) passes presses on to
|
|
101
|
+
* it, and a control that takes its own presses (a link, a form field) keeps them. Shows the
|
|
102
|
+
* cursor the active tool asks for (text over text, a crosshair for a drawing tool).
|
|
103
|
+
*/
|
|
104
|
+
class EpdfPagePointerSource {
|
|
105
|
+
page = injectPage('<epdf-page-pointer-source>');
|
|
106
|
+
/** The interaction plugin of the page's own document. */
|
|
107
|
+
interaction = new CapabilityBinding(injectKernelHost('<epdf-page-pointer-source>'), () => InteractionToken$1, () => this.page.documentId);
|
|
108
|
+
cursor = this.interaction.select((interaction) => interaction.getCursor(), 'default');
|
|
109
|
+
constructor() {
|
|
110
|
+
if (!isPlatformBrowser(inject(PLATFORM_ID)))
|
|
111
|
+
return;
|
|
112
|
+
const element = inject(ElementRef).nativeElement;
|
|
113
|
+
// The listener is `@embedpdf/web`'s, shared with every framework. It reads the page when an
|
|
114
|
+
// event arrives: a zoom changes its transform, and a drag carries on through it.
|
|
115
|
+
const page = this.page;
|
|
116
|
+
effect((onCleanup) => {
|
|
117
|
+
const interaction = this.interaction.capability();
|
|
118
|
+
if (!interaction)
|
|
119
|
+
return;
|
|
120
|
+
onCleanup(untracked(() => attachPagePointer(element, interaction, () => ({
|
|
121
|
+
ref: page.ref,
|
|
122
|
+
transform: untracked(page.transform),
|
|
123
|
+
toPagePoint: page.toPagePoint,
|
|
124
|
+
}))));
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: EpdfPagePointerSource, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
128
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.2.4", type: EpdfPagePointerSource, isStandalone: true, selector: "epdf-page-pointer-source", host: { properties: { "style.cursor": "cursor()" }, styleAttribute: "position: absolute; inset: 0; display: block; touch-action: none" }, ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
129
|
+
}
|
|
130
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: EpdfPagePointerSource, decorators: [{
|
|
131
|
+
type: Component,
|
|
132
|
+
args: [{
|
|
133
|
+
selector: 'epdf-page-pointer-source',
|
|
134
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
135
|
+
host: {
|
|
136
|
+
style: 'position: absolute; inset: 0; display: block; touch-action: none',
|
|
137
|
+
'[style.cursor]': 'cursor()',
|
|
138
|
+
},
|
|
139
|
+
template: '',
|
|
140
|
+
}]
|
|
141
|
+
}], ctorParameters: () => [] });
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* @embedpdf/angular/interaction: the tools and the pointer.
|
|
145
|
+
*
|
|
146
|
+
* withInteraction(options), withFeedback({ provider }) for provideEmbedPdf()
|
|
147
|
+
* inject(EpdfInteraction) the tools, their cursors, their events
|
|
148
|
+
* <epdf-page-pointer-source> a page's pointer input (a page view mounts it itself)
|
|
149
|
+
*/
|
|
150
|
+
// The plugin's types and helpers, so app code has one import for the feature.
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Generated bundle index. Do not edit.
|
|
154
|
+
*/
|
|
155
|
+
|
|
156
|
+
export { EpdfInteraction, EpdfPagePointerSource, withFeedback, withInteraction };
|
|
157
|
+
//# sourceMappingURL=embedpdf-angular-interaction.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"embedpdf-angular-interaction.mjs","sources":["../../interaction/src/interaction.ts","../../interaction/src/page-pointer-source.ts","../../interaction/src/public_api.ts","../../interaction/src/embedpdf-angular-interaction.ts"],"sourcesContent":["/**\n * The interaction plugin's service and features: which tool the pointer works with, the tools\n * you can switch to, and their cursors.\n *\n * withInteraction(options) the plugin, for provideEmbedPdf()\n * withFeedback({ provider }) haptics for the moments that call for them\n * inject(EpdfInteraction) `activeToolId()`, `activateTool()`, `toolChanged$`, …\n */\nimport { computed, effect, Injectable } from '@angular/core';\nimport { pluginService, type EmbedPdfFeature } from '@embedpdf/angular/runtime';\nimport {\n feedbackPlugin,\n interactionPlugin,\n interactionState,\n InteractionToken,\n type FeedbackPluginOptions,\n type InteractionConfig,\n} from '@embedpdf/plugin-interaction';\nimport { toolCursorsOf, type ToolCursorSpec } from '@embedpdf/web';\n\n/** A tool's cursors (`ToolCursorSpec`) and one of them (`ToolCursorImage`), from `@embedpdf/web`. */\nexport type { ToolCursorImage, ToolCursorSpec } from '@embedpdf/web';\n\n/** The same spec, compared by value: a spec rebuilt with the same content changes nothing. */\nconst sameSpec = (left: ToolCursorSpec | null, right: ToolCursorSpec | null) =>\n JSON.stringify(left) === JSON.stringify(right);\n\n/**\n * The tools: `activeToolId()` and `tools()` as signals, `activateTool()`, `pushTool()` and\n * `popTool()` to switch, `registerTool()` for a tool of your own, `toolChanged$` and the\n * gesture streams, and the settings. Without a document there is no active tool.\n */\n@Injectable({ providedIn: 'root' })\nexport class EpdfInteraction extends pluginService({\n name: 'EpdfInteraction',\n feature: 'withInteraction()',\n token: InteractionToken,\n state: interactionState,\n methods: [\n 'getActiveTool',\n 'getActiveToolId',\n 'getDefaultToolId',\n 'listTools',\n 'getTool',\n 'hasTool',\n 'activateTool',\n 'activateDefaultTool',\n 'pushTool',\n 'popTool',\n 'setToolCursor',\n 'registerTool',\n ],\n events: ['onToolChanged', 'onGestureStarted', 'onGestureEnded', 'onGestureCancelled'],\n}) {\n /**\n * Give a tool cursors of your own, such as a pen in the ink color, for as long as the caller\n * lives: the tool gets its own cursors back when the component or directive that called it\n * goes. `spec` is read again when the signals it reads change, so the cursor follows a color\n * setting. `null` puts nothing in place. Call it in an injection context (a constructor or a\n * field initializer).\n *\n * The cursor is the one pixel that follows the pointer with no delay, so it shows the armed\n * tool better than anything drawn under the pointer could.\n */\n overrideCursor(spec: () => ToolCursorSpec | null): void {\n const current = computed(spec, { equal: sameSpec });\n effect((onCleanup) => {\n const cursorSpec = current();\n const interaction = this.binding.capability();\n if (!cursorSpec || !interaction) return;\n interaction.setToolCursor(cursorSpec.toolId, toolCursorsOf(cursorSpec.cursors));\n onCleanup(() => interaction.setToolCursor(cursorSpec.toolId, null));\n });\n }\n}\n\n/** The interaction plugin: the tools and the pointer. `withInteraction({ defaultTool: 'pan' })`. */\nexport function withInteraction(options?: InteractionConfig): EmbedPdfFeature {\n return { plugins: [interactionPlugin(options)], services: [EpdfInteraction] };\n}\n\n/**\n * Haptics: one provider for the whole viewer, which plugins call at their moments (a word\n * selected on a long press). `withFeedback({ provider: vibrationFeedback })`.\n */\nexport function withFeedback(options?: FeedbackPluginOptions): EmbedPdfFeature {\n return { plugins: [feedbackPlugin(options)] };\n}\n","/**\n * `<epdf-page-pointer-source>`: a page's pointer input, for the tools. It covers the page as one\n * transparent element, turns each pointer event into a point on the page (through the page\n * context, so it needs nothing but the page), and hands it to the interaction plugin, whose\n * active tool decides what the press means.\n *\n * You rarely mount it: a Stage takes its pointer input itself, and `<epdf-page-view>` mounts\n * this below its layers when the interaction plugin is registered. It's here for a page surface\n * of your own. Features never listen to the pointer themselves: they register with the\n * interaction plugin.\n */\nimport { isPlatformBrowser } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n effect,\n ElementRef,\n inject,\n PLATFORM_ID,\n untracked,\n} from '@angular/core';\nimport {\n InteractionToken as InteractionHostToken,\n type InteractionHostCapability,\n} from '@embedpdf/plugin-interaction/contract/host';\nimport { attachPagePointer } from '@embedpdf/web';\nimport { CapabilityBinding, injectKernelHost, injectPage } from '@embedpdf/angular/runtime';\n\n/**\n * The page's pointer input, for the active tool. Put it first in the page's content, below the\n * layers: a layer that lets the pointer through (the picture, a highlight) passes presses on to\n * it, and a control that takes its own presses (a link, a form field) keeps them. Shows the\n * cursor the active tool asks for (text over text, a crosshair for a drawing tool).\n */\n@Component({\n selector: 'epdf-page-pointer-source',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n style: 'position: absolute; inset: 0; display: block; touch-action: none',\n '[style.cursor]': 'cursor()',\n },\n template: '',\n})\nexport class EpdfPagePointerSource {\n private readonly page = injectPage('<epdf-page-pointer-source>');\n /** The interaction plugin of the page's own document. */\n private readonly interaction = new CapabilityBinding<InteractionHostCapability>(\n injectKernelHost('<epdf-page-pointer-source>'),\n () => InteractionHostToken,\n () => this.page.documentId,\n );\n protected readonly cursor = this.interaction.select(\n (interaction) => interaction.getCursor(),\n 'default',\n );\n\n constructor() {\n if (!isPlatformBrowser(inject(PLATFORM_ID))) return;\n const element = inject<ElementRef<HTMLElement>>(ElementRef).nativeElement;\n // The listener is `@embedpdf/web`'s, shared with every framework. It reads the page when an\n // event arrives: a zoom changes its transform, and a drag carries on through it.\n const page = this.page;\n effect((onCleanup) => {\n const interaction = this.interaction.capability();\n if (!interaction) return;\n onCleanup(\n untracked(() =>\n attachPagePointer(element, interaction, () => ({\n ref: page.ref,\n transform: untracked(page.transform),\n toPagePoint: page.toPagePoint,\n })),\n ),\n );\n });\n }\n}\n","/**\n * @embedpdf/angular/interaction: the tools and the pointer.\n *\n * withInteraction(options), withFeedback({ provider }) for provideEmbedPdf()\n * inject(EpdfInteraction) the tools, their cursors, their events\n * <epdf-page-pointer-source> a page's pointer input (a page view mounts it itself)\n */\n\n// The plugin's types and helpers, so app code has one import for the feature.\nexport * from '@embedpdf/plugin-interaction';\n// The browser helpers live in @embedpdf/web (the plugin has no DOM); here for one import.\nexport { svgCursor, vibrationFeedback, wkFeedback } from '@embedpdf/web';\nexport type { SvgCursorOptions } from '@embedpdf/web';\nexport * from './interaction';\nexport * from './page-pointer-source';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":["InteractionHostToken"],"mappings":";;;;;;;;;;AAAA;;;;;;;AAOG;AAgBH;AACA,MAAM,QAAQ,GAAG,CAAC,IAA2B,EAAE,KAA4B,KACzE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;AAEhD;;;;AAIG;AAEG,MAAO,eAAgB,SAAQ,aAAa,CAAC;AACjD,IAAA,IAAI,EAAE,iBAAiB;AACvB,IAAA,OAAO,EAAE,mBAAmB;AAC5B,IAAA,KAAK,EAAE,gBAAgB;AACvB,IAAA,KAAK,EAAE,gBAAgB;AACvB,IAAA,OAAO,EAAE;QACP,eAAe;QACf,iBAAiB;QACjB,kBAAkB;QAClB,WAAW;QACX,SAAS;QACT,SAAS;QACT,cAAc;QACd,qBAAqB;QACrB,UAAU;QACV,SAAS;QACT,eAAe;QACf,cAAc;AACf,KAAA;IACD,MAAM,EAAE,CAAC,eAAe,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,oBAAoB,CAAC;CACtF,CAAC,CAAA;AACA;;;;;;;;;AASG;AACH,IAAA,cAAc,CAAC,IAAiC,EAAA;AAC9C,QAAA,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,2CAAI,KAAK,EAAE,QAAQ,EAAA,CAAA,GAAA,CAAjB,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAC;AACnD,QAAA,MAAM,CAAC,CAAC,SAAS,KAAI;AACnB,YAAA,MAAM,UAAU,GAAG,OAAO,EAAE;YAC5B,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE;AAC7C,YAAA,IAAI,CAAC,UAAU,IAAI,CAAC,WAAW;gBAAE;AACjC,YAAA,WAAW,CAAC,aAAa,CAAC,UAAU,CAAC,MAAM,EAAE,aAAa,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;AAC/E,YAAA,SAAS,CAAC,MAAM,WAAW,CAAC,aAAa,CAAC,UAAU,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AACrE,QAAA,CAAC,CAAC;IACJ;uGAxCW,eAAe,EAAA,IAAA,EAAA,IAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAAf,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,eAAe,cADF,MAAM,EAAA,CAAA;;2FACnB,eAAe,EAAA,UAAA,EAAA,CAAA;kBAD3B,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;AA4ClC;AACM,SAAU,eAAe,CAAC,OAA2B,EAAA;AACzD,IAAA,OAAO,EAAE,OAAO,EAAE,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,eAAe,CAAC,EAAE;AAC/E;AAEA;;;AAGG;AACG,SAAU,YAAY,CAAC,OAA+B,EAAA;IAC1D,OAAO,EAAE,OAAO,EAAE,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,EAAE;AAC/C;;ACvFA;;;;;;;;;;AAUG;AAkBH;;;;;AAKG;MAUU,qBAAqB,CAAA;AACf,IAAA,IAAI,GAAG,UAAU,CAAC,4BAA4B,CAAC;;IAE/C,WAAW,GAAG,IAAI,iBAAiB,CAClD,gBAAgB,CAAC,4BAA4B,CAAC,EAC9C,MAAMA,kBAAoB,EAC1B,MAAM,IAAI,CAAC,IAAI,CAAC,UAAU,CAC3B;AACkB,IAAA,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,CACjD,CAAC,WAAW,KAAK,WAAW,CAAC,SAAS,EAAE,EACxC,SAAS,CACV;AAED,IAAA,WAAA,GAAA;AACE,QAAA,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;YAAE;QAC7C,MAAM,OAAO,GAAG,MAAM,CAA0B,UAAU,CAAC,CAAC,aAAa;;;AAGzE,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI;AACtB,QAAA,MAAM,CAAC,CAAC,SAAS,KAAI;YACnB,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC,UAAU,EAAE;AACjD,YAAA,IAAI,CAAC,WAAW;gBAAE;AAClB,YAAA,SAAS,CACP,SAAS,CAAC,MACR,iBAAiB,CAAC,OAAO,EAAE,WAAW,EAAE,OAAO;gBAC7C,GAAG,EAAE,IAAI,CAAC,GAAG;AACb,gBAAA,SAAS,EAAE,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC;gBACpC,WAAW,EAAE,IAAI,CAAC,WAAW;aAC9B,CAAC,CAAC,CACJ,CACF;AACH,QAAA,CAAC,CAAC;IACJ;uGAhCW,qBAAqB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAArB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,qBAAqB,8NAFtB,EAAE,EAAA,QAAA,EAAA,IAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;2FAED,qBAAqB,EAAA,UAAA,EAAA,CAAA;kBATjC,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,0BAA0B;oBACpC,eAAe,EAAE,uBAAuB,CAAC,MAAM;AAC/C,oBAAA,IAAI,EAAE;AACJ,wBAAA,KAAK,EAAE,kEAAkE;AACzE,wBAAA,gBAAgB,EAAE,UAAU;AAC7B,qBAAA;AACD,oBAAA,QAAQ,EAAE,EAAE;AACb,iBAAA;;;AC1CD;;;;;;AAMG;AAEH;;ACRA;;AAEG;;;;"}
|