@embedpdf/angular 3.0.0-next.14 → 3.0.0-next.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/README.md +309 -0
  2. package/dist/README.md +309 -0
  3. package/dist/actions/index.d.ts +34 -16
  4. package/dist/anchored/index.d.ts +67 -0
  5. package/dist/annotation/index.d.ts +602 -0
  6. package/dist/attachment/index.d.ts +29 -0
  7. package/dist/commands/index.d.ts +109 -0
  8. package/dist/fesm2022/embedpdf-angular-actions.mjs +117 -36
  9. package/dist/fesm2022/embedpdf-angular-actions.mjs.map +1 -1
  10. package/dist/fesm2022/embedpdf-angular-anchored.mjs +148 -0
  11. package/dist/fesm2022/embedpdf-angular-anchored.mjs.map +1 -0
  12. package/dist/fesm2022/embedpdf-angular-annotation.mjs +1933 -0
  13. package/dist/fesm2022/embedpdf-angular-annotation.mjs.map +1 -0
  14. package/dist/fesm2022/embedpdf-angular-attachment.mjs +67 -0
  15. package/dist/fesm2022/embedpdf-angular-attachment.mjs.map +1 -0
  16. package/dist/fesm2022/embedpdf-angular-commands.mjs +235 -0
  17. package/dist/fesm2022/embedpdf-angular-commands.mjs.map +1 -0
  18. package/dist/fesm2022/embedpdf-angular-form.mjs +1074 -0
  19. package/dist/fesm2022/embedpdf-angular-form.mjs.map +1 -0
  20. package/dist/fesm2022/embedpdf-angular-history.mjs +54 -0
  21. package/dist/fesm2022/embedpdf-angular-history.mjs.map +1 -0
  22. package/dist/fesm2022/embedpdf-angular-i18n.mjs +100 -0
  23. package/dist/fesm2022/embedpdf-angular-i18n.mjs.map +1 -0
  24. package/dist/fesm2022/embedpdf-angular-interaction.mjs +157 -0
  25. package/dist/fesm2022/embedpdf-angular-interaction.mjs.map +1 -0
  26. package/dist/fesm2022/embedpdf-angular-link.mjs +306 -0
  27. package/dist/fesm2022/embedpdf-angular-link.mjs.map +1 -0
  28. package/dist/fesm2022/embedpdf-angular-measurement.mjs +106 -0
  29. package/dist/fesm2022/embedpdf-angular-measurement.mjs.map +1 -0
  30. package/dist/fesm2022/embedpdf-angular-metadata.mjs +77 -0
  31. package/dist/fesm2022/embedpdf-angular-metadata.mjs.map +1 -0
  32. package/dist/fesm2022/embedpdf-angular-outline.mjs +76 -0
  33. package/dist/fesm2022/embedpdf-angular-outline.mjs.map +1 -0
  34. package/dist/fesm2022/embedpdf-angular-page-edit.mjs +68 -0
  35. package/dist/fesm2022/embedpdf-angular-page-edit.mjs.map +1 -0
  36. package/dist/fesm2022/embedpdf-angular-page-view.mjs +297 -0
  37. package/dist/fesm2022/embedpdf-angular-page-view.mjs.map +1 -0
  38. package/dist/fesm2022/embedpdf-angular-redaction.mjs +93 -0
  39. package/dist/fesm2022/embedpdf-angular-redaction.mjs.map +1 -0
  40. package/dist/fesm2022/embedpdf-angular-render.mjs +331 -69
  41. package/dist/fesm2022/embedpdf-angular-render.mjs.map +1 -1
  42. package/dist/fesm2022/embedpdf-angular-runtime.mjs +1151 -390
  43. package/dist/fesm2022/embedpdf-angular-runtime.mjs.map +1 -1
  44. package/dist/fesm2022/embedpdf-angular-search.mjs +251 -0
  45. package/dist/fesm2022/embedpdf-angular-search.mjs.map +1 -0
  46. package/dist/fesm2022/embedpdf-angular-selection.mjs +477 -0
  47. package/dist/fesm2022/embedpdf-angular-selection.mjs.map +1 -0
  48. package/dist/fesm2022/embedpdf-angular-shell.mjs +177 -0
  49. package/dist/fesm2022/embedpdf-angular-shell.mjs.map +1 -0
  50. package/dist/fesm2022/embedpdf-angular-signature.mjs +120 -0
  51. package/dist/fesm2022/embedpdf-angular-signature.mjs.map +1 -0
  52. package/dist/fesm2022/embedpdf-angular-stage.mjs +688 -288
  53. package/dist/fesm2022/embedpdf-angular-stage.mjs.map +1 -1
  54. package/dist/fesm2022/embedpdf-angular-stamp.mjs +169 -0
  55. package/dist/fesm2022/embedpdf-angular-stamp.mjs.map +1 -0
  56. package/dist/fesm2022/embedpdf-angular-testing.mjs +89 -0
  57. package/dist/fesm2022/embedpdf-angular-testing.mjs.map +1 -0
  58. package/dist/fesm2022/embedpdf-angular-toolbar.mjs +1123 -0
  59. package/dist/fesm2022/embedpdf-angular-toolbar.mjs.map +1 -0
  60. package/dist/fesm2022/embedpdf-angular-view-manager.mjs +69 -0
  61. package/dist/fesm2022/embedpdf-angular-view-manager.mjs.map +1 -0
  62. package/dist/fesm2022/embedpdf-angular.mjs +25 -3
  63. package/dist/fesm2022/embedpdf-angular.mjs.map +1 -1
  64. package/dist/form/index.d.ts +79 -0
  65. package/dist/history/index.d.ts +28 -0
  66. package/dist/i18n/index.d.ts +52 -0
  67. package/dist/index.d.ts +22 -0
  68. package/dist/interaction/index.d.ts +58 -0
  69. package/dist/link/index.d.ts +77 -0
  70. package/dist/measurement/index.d.ts +46 -0
  71. package/dist/metadata/index.d.ts +51 -0
  72. package/dist/outline/index.d.ts +32 -0
  73. package/dist/page-edit/index.d.ts +27 -0
  74. package/dist/page-view/index.d.ts +94 -0
  75. package/dist/redaction/index.d.ts +38 -0
  76. package/dist/render/index.d.ts +45 -6
  77. package/dist/runtime/index.d.ts +579 -199
  78. package/dist/search/index.d.ts +71 -0
  79. package/dist/selection/index.d.ts +141 -0
  80. package/dist/shell/index.d.ts +88 -0
  81. package/dist/signature/index.d.ts +45 -0
  82. package/dist/stage/index.d.ts +242 -141
  83. package/dist/stamp/index.d.ts +58 -0
  84. package/dist/testing/index.d.ts +53 -0
  85. package/dist/toolbar/index.d.ts +257 -0
  86. package/dist/view-manager/index.d.ts +23 -0
  87. package/package.json +145 -14
@@ -0,0 +1 @@
1
+ {"version":3,"file":"embedpdf-angular-outline.mjs","sources":["../../outline/src/outline.ts","../../outline/src/public_api.ts","../../outline/src/embedpdf-angular-outline.ts"],"sourcesContent":["/**\n * The outline plugin's service and feature: the document's outline (its bookmarks). Reading it\n * reads the outline; the plugin keeps it live off the document's event stream, and shows your\n * own edits at once:\n *\n * protected readonly outline = inject(EpdfOutline);\n * @for (row of outline.rows(); track row.item.ref.objectNumber) { … }\n * (click)=\"outline.activate(row.item.ref)\" goes where the item goes, as a click does\n */\nimport { Injectable } from '@angular/core';\nimport { pluginService, type EmbedPdfFeature } from '@embedpdf/angular/runtime';\nimport { outlinePlugin, outlineState, OutlineToken } from '@embedpdf/plugin-outline';\n\n/**\n * The outline of the document in scope (`[epdfDocumentScope]`), else the active one: the State\n * table as signals (`items()`, `rows()`, `current()`, `selected()`, `status()`, `incomplete()`,\n * `canEdit()`), the reads that take an item (`get()`, `getChildren()`, `isExpanded()`), the\n * calls that expand, select, follow and edit items, and the streams `changed$` and\n * `resynced$`. Reading it reads the outline. With no document the signals read empty, and every\n * call refuses with `not-ready`.\n */\n@Injectable({ providedIn: 'root' })\nexport class EpdfOutline extends pluginService({\n name: 'EpdfOutline',\n feature: 'withOutline()',\n token: OutlineToken,\n state: outlineState,\n methods: [\n 'get',\n 'getChildren',\n 'isExpanded',\n 'getCurrentViewTarget',\n 'ensureLoaded',\n 'refresh',\n 'expand',\n 'collapse',\n 'toggle',\n 'expandAll',\n 'collapseAll',\n 'reveal',\n 'select',\n 'activate',\n 'create',\n 'update',\n 'move',\n 'delete',\n ],\n events: ['onChanged', 'onResynced'],\n}) {}\n\n/** The outline, for `provideEmbedPdf()`. */\nexport function withOutline(): EmbedPdfFeature {\n return { plugins: [outlinePlugin()], services: [EpdfOutline] };\n}\n","/**\n * @embedpdf/angular/outline: the document's outline (its bookmarks).\n *\n * withOutline() the plugin, for provideEmbedPdf()\n * inject(EpdfOutline) rows(), current(), canEdit(), activate(), create(), changed$, …\n */\n\n// The plugin's types and helpers, so app code has one import for the feature.\nexport * from '@embedpdf/plugin-outline';\nexport * from './outline';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":";;;;;;AAAA;;;;;;;;AAQG;AAKH;;;;;;;AAOG;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;AACnB,IAAA,OAAO,EAAE;QACP,KAAK;QACL,aAAa;QACb,YAAY;QACZ,sBAAsB;QACtB,cAAc;QACd,SAAS;QACT,QAAQ;QACR,UAAU;QACV,QAAQ;QACR,WAAW;QACX,aAAa;QACb,QAAQ;QACR,QAAQ;QACR,UAAU;QACV,QAAQ;QACR,QAAQ;QACR,MAAM;QACN,QAAQ;AACT,KAAA;AACD,IAAA,MAAM,EAAE,CAAC,WAAW,EAAE,YAAY,CAAC;CACpC,CAAC,CAAA;uGA1BW,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;;AA6BlC;SACgB,WAAW,GAAA;AACzB,IAAA,OAAO,EAAE,OAAO,EAAE,CAAC,aAAa,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,WAAW,CAAC,EAAE;AAChE;;ACrDA;;;;;AAKG;AAEH;;ACPA;;AAEG;;;;"}
@@ -0,0 +1,68 @@
1
+ import { pageEditState, PageEditToken, pageEditPlugin } from '@embedpdf/plugin-page-edit';
2
+ export * from '@embedpdf/plugin-page-edit';
3
+ import * as i0 from '@angular/core';
4
+ import { Injectable } from '@angular/core';
5
+ import { pluginService } from '@embedpdf/angular/runtime';
6
+
7
+ /**
8
+ * The page-edit plugin's service and feature. The plugin turns a page relative to its rotation
9
+ * and resolves where pages go, so the service is the plugin's calls and its selection:
10
+ *
11
+ * await pageEdit.rotateBy([page.ref], 90);
12
+ */
13
+ /**
14
+ * The page edits of the document in scope (`[epdfDocumentScope]`), else the active one. The
15
+ * checks `canEdit()` and `canExtract()` follow the document when a template reads them; with no
16
+ * document every call refuses with `not-ready`. `selected()` is the selection, a signal. The
17
+ * plugin has no events of its own: page changes are document events
18
+ * (`inject(EpdfDocuments).pagesChanged$`), and the pages are `inject(EpdfDocument).pages()`.
19
+ */
20
+ class EpdfPageEdit extends pluginService({
21
+ name: 'EpdfPageEdit',
22
+ feature: 'withPageEdit()',
23
+ token: PageEditToken,
24
+ state: pageEditState,
25
+ // `canEdit` and `canExtract` stay calls: with no document they refuse `not-ready`.
26
+ methods: [
27
+ 'select',
28
+ 'rotateBy',
29
+ 'setRotation',
30
+ 'reorder',
31
+ 'delete',
32
+ 'insertBlank',
33
+ 'insertFromBytes',
34
+ 'insertFromDocument',
35
+ 'duplicate',
36
+ 'extract',
37
+ 'canEdit',
38
+ 'canExtract',
39
+ ],
40
+ }) {
41
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: EpdfPageEdit, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
42
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: EpdfPageEdit, providedIn: 'root' });
43
+ }
44
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: EpdfPageEdit, decorators: [{
45
+ type: Injectable,
46
+ args: [{ providedIn: 'root' }]
47
+ }] });
48
+ /** Page editing, for `provideEmbedPdf()`. */
49
+ function withPageEdit() {
50
+ return { plugins: [pageEditPlugin()], services: [EpdfPageEdit] };
51
+ }
52
+
53
+ /**
54
+ * @embedpdf/angular/page-edit: changing a document's pages.
55
+ *
56
+ * withPageEdit() the plugin, for provideEmbedPdf()
57
+ * inject(EpdfPageEdit) rotateBy(), reorder(), delete(), insertBlank(), extract(), canEdit(), …
58
+ *
59
+ * The pages themselves are `inject(EpdfDocument).pages()`, which follows every change.
60
+ */
61
+ // The plugin's types and helpers, so app code has one import for the feature.
62
+
63
+ /**
64
+ * Generated bundle index. Do not edit.
65
+ */
66
+
67
+ export { EpdfPageEdit, withPageEdit };
68
+ //# sourceMappingURL=embedpdf-angular-page-edit.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"embedpdf-angular-page-edit.mjs","sources":["../../page-edit/src/page-edit.ts","../../page-edit/src/public_api.ts","../../page-edit/src/embedpdf-angular-page-edit.ts"],"sourcesContent":["/**\n * The page-edit plugin's service and feature. The plugin turns a page relative to its rotation\n * and resolves where pages go, so the service is the plugin's calls and its selection:\n *\n * await pageEdit.rotateBy([page.ref], 90);\n */\nimport { Injectable } from '@angular/core';\nimport { pluginService, type EmbedPdfFeature } from '@embedpdf/angular/runtime';\nimport { pageEditPlugin, pageEditState, PageEditToken } from '@embedpdf/plugin-page-edit';\n\n/**\n * The page edits of the document in scope (`[epdfDocumentScope]`), else the active one. The\n * checks `canEdit()` and `canExtract()` follow the document when a template reads them; with no\n * document every call refuses with `not-ready`. `selected()` is the selection, a signal. The\n * plugin has no events of its own: page changes are document events\n * (`inject(EpdfDocuments).pagesChanged$`), and the pages are `inject(EpdfDocument).pages()`.\n */\n@Injectable({ providedIn: 'root' })\nexport class EpdfPageEdit extends pluginService({\n name: 'EpdfPageEdit',\n feature: 'withPageEdit()',\n token: PageEditToken,\n state: pageEditState,\n // `canEdit` and `canExtract` stay calls: with no document they refuse `not-ready`.\n methods: [\n 'select',\n 'rotateBy',\n 'setRotation',\n 'reorder',\n 'delete',\n 'insertBlank',\n 'insertFromBytes',\n 'insertFromDocument',\n 'duplicate',\n 'extract',\n 'canEdit',\n 'canExtract',\n ],\n}) {}\n\n/** Page editing, for `provideEmbedPdf()`. */\nexport function withPageEdit(): EmbedPdfFeature {\n return { plugins: [pageEditPlugin()], services: [EpdfPageEdit] };\n}\n","/**\n * @embedpdf/angular/page-edit: changing a document's pages.\n *\n * withPageEdit() the plugin, for provideEmbedPdf()\n * inject(EpdfPageEdit) rotateBy(), reorder(), delete(), insertBlank(), extract(), canEdit(), …\n *\n * The pages themselves are `inject(EpdfDocument).pages()`, which follows every change.\n */\n\n// The plugin's types and helpers, so app code has one import for the feature.\nexport * from '@embedpdf/plugin-page-edit';\nexport * from './page-edit';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":";;;;;;AAAA;;;;;AAKG;AAKH;;;;;;AAMG;AAEG,MAAO,YAAa,SAAQ,aAAa,CAAC;AAC9C,IAAA,IAAI,EAAE,cAAc;AACpB,IAAA,OAAO,EAAE,gBAAgB;AACzB,IAAA,KAAK,EAAE,aAAa;AACpB,IAAA,KAAK,EAAE,aAAa;;AAEpB,IAAA,OAAO,EAAE;QACP,QAAQ;QACR,UAAU;QACV,aAAa;QACb,SAAS;QACT,QAAQ;QACR,aAAa;QACb,iBAAiB;QACjB,oBAAoB;QACpB,WAAW;QACX,SAAS;QACT,SAAS;QACT,YAAY;AACb,KAAA;CACF,CAAC,CAAA;uGApBW,YAAY,EAAA,IAAA,EAAA,IAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAAZ,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,YAAY,cADC,MAAM,EAAA,CAAA;;2FACnB,YAAY,EAAA,UAAA,EAAA,CAAA;kBADxB,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;AAuBlC;SACgB,YAAY,GAAA;AAC1B,IAAA,OAAO,EAAE,OAAO,EAAE,CAAC,cAAc,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,YAAY,CAAC,EAAE;AAClE;;AC3CA;;;;;;;AAOG;AAEH;;ACTA;;AAEG;;;;"}
@@ -0,0 +1,297 @@
1
+ import { isPlatformBrowser, NgTemplateOutlet } from '@angular/common';
2
+ import * as i0 from '@angular/core';
3
+ import { inject, TemplateRef, Directive, input, viewChild, contentChild, computed, PLATFORM_ID, signal, ChangeDetectionStrategy, Component } from '@angular/core';
4
+ import { toPageRef, shallowEqual } from '@embedpdf/core';
5
+ import { pageTransform } from '@embedpdf/core-geometry';
6
+ import { InteractionToken } from '@embedpdf/plugin-interaction/contract/host';
7
+ import { pageViewTransformInput, pageSurfaceLayout, paint, observeClientGeometry, clientPageProjector } from '@embedpdf/web';
8
+ import { injectKernelHost, EPDF_DOCUMENT_SCOPE, CapabilityBinding, createPageContext, EPDF_PAGE, EPDF_SCOPED_SERVICES } from '@embedpdf/angular/runtime';
9
+ import { EPDF_PROJECTOR } from '@embedpdf/angular/anchored';
10
+ import { EpdfPagePointerSource } from '@embedpdf/angular/interaction';
11
+ import { EpdfPageChrome } from '@embedpdf/angular/stage';
12
+ export { EpdfPageChrome } from '@embedpdf/angular/stage';
13
+
14
+ /**
15
+ * `<epdf-page-view>`: one page on its own, with no Stage. A preview in a card, a page picker,
16
+ * the page a comment belongs to:
17
+ *
18
+ * <epdf-page-view [page]="0" [width]="240">
19
+ * <epdf-render-layer />
20
+ * </epdf-page-view>
21
+ *
22
+ * It has no camera, scrolling or zoom, and it doesn't need the Stage plugin: it builds the
23
+ * page's transform from `[width]` and gives the layers between its tags the same page context
24
+ * a Stage's page gives them, so every layer works here as it does on a Stage. With the
25
+ * interaction plugin it takes pointer input for the tools too, so text selection and annotation
26
+ * editing work in it. Anchored UI works as well: it measures the page on screen and is
27
+ * positioned `fixed`, so a card or a scrolling list around the page can't cut it off.
28
+ *
29
+ * What goes between the tags is drawn on the page and turns with it. `<ng-template
30
+ * epdfPageChrome let-page>` draws in the bands `[pageFrame]` reserves around the page and never
31
+ * turns; `<ng-template epdfFallback>` shows until the document and the page are there. `class`
32
+ * and `style` go on the outer box, which is the element itself.
33
+ *
34
+ * The layout is a Stage page's: a shadow that stays put, and a content box with the page's
35
+ * background that turns about its centre (with no transform at all when upright).
36
+ */
37
+ /**
38
+ * What a page view shows until its document and its page are there, instead of nothing:
39
+ * `<ng-template epdfFallback>Loading…</ng-template>`.
40
+ */
41
+ class EpdfFallback {
42
+ template = inject(TemplateRef);
43
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: EpdfFallback, deps: [], target: i0.ɵɵFactoryTarget.Directive });
44
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.2.4", type: EpdfFallback, isStandalone: true, selector: "ng-template[epdfFallback]", ngImport: i0 });
45
+ }
46
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: EpdfFallback, decorators: [{
47
+ type: Directive,
48
+ args: [{ selector: 'ng-template[epdfFallback]' }]
49
+ }] });
50
+ /** Every page view plans its pictures as its own view, so two views of one page never mix. */
51
+ let nextViewId = 0;
52
+ const frameEqual = (left, right) => left.top === right.top &&
53
+ left.right === right.right &&
54
+ left.bottom === right.bottom &&
55
+ left.left === right.left;
56
+ /** The page's box before the content element exists (only a pointer event would ask). */
57
+ const NO_RECT = { x: 0, y: 0, left: 0, top: 0, right: 0, bottom: 0, width: 0, height: 0 };
58
+ class EpdfPageView {
59
+ /** The page: its `ref`, which follows it when pages move, or its index, from 0. */
60
+ page = input.required(...(ngDevMode ? [{ debugName: "page" }] : []));
61
+ /**
62
+ * Which document to show. Without it, the one the surrounding `[epdfDocumentScope]` names,
63
+ * else the active one.
64
+ */
65
+ documentId = input(undefined, ...(ngDevMode ? [{ debugName: "documentId" }] : []));
66
+ /** The width of the page upright, in pixels: a page turned a quarter is that tall. */
67
+ width = input(240, ...(ngDevMode ? [{ debugName: "width" }] : []));
68
+ /** Space reserved around the page for your own labels, in pixels per side; 0 for the others. */
69
+ pageFrame = input(undefined, ...(ngDevMode ? [{ debugName: "pageFrame" }] : []));
70
+ host = injectKernelHost('<epdf-page-view>');
71
+ parentScope = inject(EPDF_DOCUMENT_SCOPE, { optional: true, skipSelf: true });
72
+ content = viewChild('content', ...(ngDevMode ? [{ debugName: "content" }] : []));
73
+ chromeDirective = contentChild(EpdfPageChrome, ...(ngDevMode ? [{ debugName: "chromeDirective" }] : []));
74
+ fallbackDirective = contentChild(EpdfFallback, ...(ngDevMode ? [{ debugName: "fallbackDirective" }] : []));
75
+ chromeTemplate = computed(() => this.chromeDirective()?.template ?? null, ...(ngDevMode ? [{ debugName: "chromeTemplate" }] : []));
76
+ fallbackTemplate = computed(() => this.fallbackDirective()?.template ?? null, ...(ngDevMode ? [{ debugName: "fallbackTemplate" }] : []));
77
+ activeId = this.host.read((kernel) => kernel.documents.getActiveId(), () => null);
78
+ /** The document shown: `[documentId]`, else the scope's, else the active one. */
79
+ docId = computed(() => this.documentId() ?? this.parentScope?.id() ?? this.activeId(), ...(ngDevMode ? [{ debugName: "docId" }] : []));
80
+ /** For what's inside: services and layers talk to the document shown. */
81
+ documentScope = { id: this.docId };
82
+ /** The interaction plugin of the document shown, when the viewer has it. */
83
+ interaction = new CapabilityBinding(this.host, () => InteractionToken, this.docId).capability;
84
+ /**
85
+ * The page's entry in the document, by its object number or its index. Entries stay the
86
+ * same object until their page changes, so a turn or a move reads as a new entry.
87
+ */
88
+ entry = this.host.read((kernel) => {
89
+ const id = this.docId();
90
+ if (!id)
91
+ return null;
92
+ const wanted = this.page();
93
+ const pages = kernel.documents.listPages(id);
94
+ const found = typeof wanted === 'number'
95
+ ? pages[wanted]
96
+ : pages.find((page) => page.ref.objectNumber === wanted.objectNumber);
97
+ return found ?? null;
98
+ }, () => null);
99
+ /** Whether there's a page to show: the document is there and has it. */
100
+ shown = computed(() => this.entry() !== null, ...(ngDevMode ? [{ debugName: "shown" }] : []));
101
+ /** Whether the tools take the pointer here: with the interaction plugin, as on a Stage. */
102
+ takesPointer = computed(() => this.interaction() !== null, ...(ngDevMode ? [{ debugName: "takesPointer" }] : []));
103
+ pageIndex = computed(() => {
104
+ const wanted = this.page();
105
+ return this.entry()?.index ?? (typeof wanted === 'number' ? wanted : 0);
106
+ }, ...(ngDevMode ? [{ debugName: "pageIndex" }] : []));
107
+ /** The page's object number: a stand-in (its index + 1) only until the page is known. */
108
+ objectNumber = computed(() => {
109
+ const wanted = this.page();
110
+ return (this.entry()?.ref.objectNumber ??
111
+ (typeof wanted === 'number' ? wanted + 1 : wanted.objectNumber));
112
+ }, ...(ngDevMode ? [{ debugName: "objectNumber" }] : []));
113
+ /** The same ref object while the page is the same, so layers can key their work on it. */
114
+ pageRef = computed(() => toPageRef(this.objectNumber()), ...(ngDevMode ? [{ debugName: "pageRef" }] : []));
115
+ frame = computed(() => {
116
+ const { top = 0, right = 0, bottom = 0, left = 0 } = this.pageFrame() ?? {};
117
+ return { top, right, bottom, left };
118
+ }, ...(ngDevMode ? [{ debugName: "frame", equal: frameEqual }] : [{ equal: frameEqual }]));
119
+ dpr = isPlatformBrowser(inject(PLATFORM_ID)) ? window.devicePixelRatio || 1 : 1;
120
+ /** What the transform depends on, by value: a new entry for an unchanged page changes nothing. */
121
+ geometry = computed(() => {
122
+ const entry = this.entry();
123
+ return {
124
+ width: entry?.size.width ?? 1,
125
+ height: entry?.size.height ?? 1,
126
+ rotation: entry?.rotation ?? 0,
127
+ userUnit: entry?.userUnit ?? 1,
128
+ target: this.width(),
129
+ known: entry !== null,
130
+ };
131
+ }, ...(ngDevMode ? [{ debugName: "geometry", equal: shallowEqual }] : [{ equal: shallowEqual }]));
132
+ /**
133
+ * The page's transform, from the width alone (`pageViewTransformInput` from `@embedpdf/web`,
134
+ * the same in every framework): view pixels per point is `width / page width`, and 100% is 1
135
+ * point = 96/72 CSS pixels times the page's user unit, as on a Stage.
136
+ */
137
+ transform = computed(() => {
138
+ const { width, height, rotation, userUnit, target, known } = this.geometry();
139
+ const page = known ? { size: { width, height }, rotation, userUnit } : null;
140
+ return pageTransform(pageViewTransformInput(page, target, this.dpr));
141
+ }, ...(ngDevMode ? [{ debugName: "transform" }] : []));
142
+ /** The outer box, the shadow at the footprint, and the turned content box. */
143
+ layout = computed(() => pageSurfaceLayout(this.transform(), this.frame()), ...(ngDevMode ? [{ debugName: "layout" }] : []));
144
+ /** The viewer's `page` settings; CSS `--epdf-page-shadow` and `--epdf-page-background` win. */
145
+ look = computed(() => this.host.viewerSettings().page, ...(ngDevMode ? [{ debugName: "look", equal: shallowEqual }] : [{
146
+ equal: shallowEqual,
147
+ }]));
148
+ shadow = computed(() => paint('page-shadow', this.look().shadow), ...(ngDevMode ? [{ debugName: "shadow" }] : []));
149
+ background = computed(() => paint('page-background', this.look().background), ...(ngDevMode ? [{ debugName: "background" }] : []));
150
+ viewId = `page-view:${++nextViewId}`;
151
+ /**
152
+ * The page context for the layers inside: one object for the view's lifetime, whose `ref`,
153
+ * `documentId` and signals follow `[page]` and `[documentId]`. No view demand: a page view
154
+ * wants the whole page.
155
+ */
156
+ pageContext = createPageContext({
157
+ documentId: () => this.docId() ?? '',
158
+ ref: () => this.pageRef(),
159
+ view: () => this.viewId,
160
+ pageIndex: this.pageIndex,
161
+ frame: this.frame,
162
+ transform: this.transform,
163
+ getRect: () => this.content()?.nativeElement.getBoundingClientRect() ?? NO_RECT,
164
+ });
165
+ templateContext = { $implicit: this.pageContext };
166
+ /**
167
+ * How anchored UI inside follows the page: by measuring it on screen. The revision is the
168
+ * page and its transform; a scroll or a resize of the window moves the page without either,
169
+ * so `observeClientGeometry` reports those.
170
+ */
171
+ projection = {
172
+ // `@embedpdf/web`'s measured projector, shared by every framework. It reads the context (and
173
+ // its transform signal) when it projects, so it never goes stale.
174
+ projector: signal(clientPageProjector(this.pageContext, () => this.content() !== undefined)).asReadonly(),
175
+ revision: computed(() => [this.pageRef(), this.transform()]),
176
+ shownPages: computed(() => new Set([this.objectNumber()])),
177
+ subscribe: observeClientGeometry,
178
+ };
179
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: EpdfPageView, deps: [], target: i0.ɵɵFactoryTarget.Component });
180
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.2.4", type: EpdfPageView, isStandalone: true, selector: "epdf-page-view", inputs: { page: { classPropertyName: "page", publicName: "page", isSignal: true, isRequired: true, transformFunction: null }, documentId: { classPropertyName: "documentId", publicName: "documentId", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, pageFrame: { classPropertyName: "pageFrame", publicName: "pageFrame", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "style.width.px": "shown() ? layout().outer.width : null", "style.height.px": "shown() ? layout().outer.height : null" }, styleAttribute: "position: relative; display: block" }, providers: [
181
+ // What's inside talks to this view's document, draws on its page, and anchors to it.
182
+ { provide: EPDF_DOCUMENT_SCOPE, useFactory: () => inject(EpdfPageView).documentScope },
183
+ { provide: EPDF_PAGE, useFactory: () => inject(EpdfPageView).pageContext },
184
+ { provide: EPDF_PROJECTOR, useFactory: () => inject(EpdfPageView).projection },
185
+ EPDF_SCOPED_SERVICES,
186
+ ], queries: [{ propertyName: "chromeDirective", first: true, predicate: EpdfPageChrome, descendants: true, isSignal: true }, { propertyName: "fallbackDirective", first: true, predicate: EpdfFallback, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "content", first: true, predicate: ["content"], descendants: true, isSignal: true }], ngImport: i0, template: `
187
+ @if (shown()) {
188
+ <!-- The shadow only: axis-aligned, with no fill that could show behind the picture. -->
189
+ <div
190
+ style="position: absolute"
191
+ [style.left.px]="layout().shadow.left"
192
+ [style.top.px]="layout().shadow.top"
193
+ [style.width.px]="layout().shadow.width"
194
+ [style.height.px]="layout().shadow.height"
195
+ [style.box-shadow]="shadow()"
196
+ ></div>
197
+ <!-- The page: its background and its layers as one box, the only thing that turns. -->
198
+ <div
199
+ #content
200
+ style="position: absolute; user-select: none; -webkit-user-select: none"
201
+ [style.left.px]="layout().content.left"
202
+ [style.top.px]="layout().content.top"
203
+ [style.width.px]="layout().content.width"
204
+ [style.height.px]="layout().content.height"
205
+ [style.background]="background()"
206
+ [style.transform]="layout().turn"
207
+ >
208
+ <!-- The tools' pointer input comes first, so the layers sit on top of it: a press on a
209
+ layer that lets the pointer through reaches the tools, and a control that takes its
210
+ own presses (a link, a form field) keeps them. -->
211
+ @if (takesPointer()) {
212
+ <epdf-page-pointer-source />
213
+ }
214
+ <ng-content />
215
+ </div>
216
+ <!-- Around the page: fills the outer box, never turns. -->
217
+ @if (chromeTemplate(); as chrome) {
218
+ <ng-container [ngTemplateOutlet]="chrome" [ngTemplateOutletContext]="templateContext" />
219
+ }
220
+ } @else if (fallbackTemplate(); as fallback) {
221
+ <ng-container [ngTemplateOutlet]="fallback" />
222
+ }
223
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: EpdfPagePointerSource, selector: "epdf-page-pointer-source" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
224
+ }
225
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: EpdfPageView, decorators: [{
226
+ type: Component,
227
+ args: [{
228
+ selector: 'epdf-page-view',
229
+ imports: [NgTemplateOutlet, EpdfPagePointerSource],
230
+ changeDetection: ChangeDetectionStrategy.OnPush,
231
+ providers: [
232
+ // What's inside talks to this view's document, draws on its page, and anchors to it.
233
+ { provide: EPDF_DOCUMENT_SCOPE, useFactory: () => inject(EpdfPageView).documentScope },
234
+ { provide: EPDF_PAGE, useFactory: () => inject(EpdfPageView).pageContext },
235
+ { provide: EPDF_PROJECTOR, useFactory: () => inject(EpdfPageView).projection },
236
+ EPDF_SCOPED_SERVICES,
237
+ ],
238
+ host: {
239
+ style: 'position: relative; display: block',
240
+ '[style.width.px]': 'shown() ? layout().outer.width : null',
241
+ '[style.height.px]': 'shown() ? layout().outer.height : null',
242
+ },
243
+ template: `
244
+ @if (shown()) {
245
+ <!-- The shadow only: axis-aligned, with no fill that could show behind the picture. -->
246
+ <div
247
+ style="position: absolute"
248
+ [style.left.px]="layout().shadow.left"
249
+ [style.top.px]="layout().shadow.top"
250
+ [style.width.px]="layout().shadow.width"
251
+ [style.height.px]="layout().shadow.height"
252
+ [style.box-shadow]="shadow()"
253
+ ></div>
254
+ <!-- The page: its background and its layers as one box, the only thing that turns. -->
255
+ <div
256
+ #content
257
+ style="position: absolute; user-select: none; -webkit-user-select: none"
258
+ [style.left.px]="layout().content.left"
259
+ [style.top.px]="layout().content.top"
260
+ [style.width.px]="layout().content.width"
261
+ [style.height.px]="layout().content.height"
262
+ [style.background]="background()"
263
+ [style.transform]="layout().turn"
264
+ >
265
+ <!-- The tools' pointer input comes first, so the layers sit on top of it: a press on a
266
+ layer that lets the pointer through reaches the tools, and a control that takes its
267
+ own presses (a link, a form field) keeps them. -->
268
+ @if (takesPointer()) {
269
+ <epdf-page-pointer-source />
270
+ }
271
+ <ng-content />
272
+ </div>
273
+ <!-- Around the page: fills the outer box, never turns. -->
274
+ @if (chromeTemplate(); as chrome) {
275
+ <ng-container [ngTemplateOutlet]="chrome" [ngTemplateOutletContext]="templateContext" />
276
+ }
277
+ } @else if (fallbackTemplate(); as fallback) {
278
+ <ng-container [ngTemplateOutlet]="fallback" />
279
+ }
280
+ `,
281
+ }]
282
+ }] });
283
+
284
+ /**
285
+ * @embedpdf/angular/page-view: one page on its own, with no Stage.
286
+ *
287
+ * <epdf-page-view [page] [width]> the page, drawn with the layers between its tags
288
+ * <ng-template epdfFallback> what shows until the document and the page are there
289
+ * <ng-template epdfPageChrome> what goes around the page: the Stage's own template
290
+ */
291
+
292
+ /**
293
+ * Generated bundle index. Do not edit.
294
+ */
295
+
296
+ export { EpdfFallback, EpdfPageView };
297
+ //# sourceMappingURL=embedpdf-angular-page-view.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"embedpdf-angular-page-view.mjs","sources":["../../page-view/src/page-view.ts","../../page-view/src/public_api.ts","../../page-view/src/embedpdf-angular-page-view.ts"],"sourcesContent":["/**\n * `<epdf-page-view>`: one page on its own, with no Stage. A preview in a card, a page picker,\n * the page a comment belongs to:\n *\n * <epdf-page-view [page]=\"0\" [width]=\"240\">\n * <epdf-render-layer />\n * </epdf-page-view>\n *\n * It has no camera, scrolling or zoom, and it doesn't need the Stage plugin: it builds the\n * page's transform from `[width]` and gives the layers between its tags the same page context\n * a Stage's page gives them, so every layer works here as it does on a Stage. With the\n * interaction plugin it takes pointer input for the tools too, so text selection and annotation\n * editing work in it. Anchored UI works as well: it measures the page on screen and is\n * positioned `fixed`, so a card or a scrolling list around the page can't cut it off.\n *\n * What goes between the tags is drawn on the page and turns with it. `<ng-template\n * epdfPageChrome let-page>` draws in the bands `[pageFrame]` reserves around the page and never\n * turns; `<ng-template epdfFallback>` shows until the document and the page are there. `class`\n * and `style` go on the outer box, which is the element itself.\n *\n * The layout is a Stage page's: a shadow that stays put, and a content box with the page's\n * background that turns about its centre (with no transform at all when upright).\n */\nimport { isPlatformBrowser, NgTemplateOutlet } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n computed,\n contentChild,\n Directive,\n ElementRef,\n inject,\n input,\n PLATFORM_ID,\n signal,\n TemplateRef,\n viewChild,\n type Signal,\n} from '@angular/core';\nimport { shallowEqual, toPageRef } from '@embedpdf/core';\nimport type { PageInfo, PageRef } from '@embedpdf/core';\nimport { pageTransform, type PageFrame, type PageTransform } from '@embedpdf/core-geometry';\nimport { InteractionToken as InteractionHostToken } from '@embedpdf/plugin-interaction/contract/host';\nimport {\n clientPageProjector,\n observeClientGeometry,\n pageSurfaceLayout,\n pageViewTransformInput,\n paint,\n} from '@embedpdf/web';\nimport {\n CapabilityBinding,\n createPageContext,\n EPDF_DOCUMENT_SCOPE,\n EPDF_PAGE,\n EPDF_SCOPED_SERVICES,\n injectKernelHost,\n type EpdfDocumentScopeRef,\n type EpdfPageContext,\n} from '@embedpdf/angular/runtime';\nimport { EPDF_PROJECTOR, type EpdfProjectorBinding } from '@embedpdf/angular/anchored';\nimport { EpdfPagePointerSource } from '@embedpdf/angular/interaction';\nimport { EpdfPageChrome, type EpdfPageTemplateContext } from '@embedpdf/angular/stage';\n\n/**\n * What a page view shows until its document and its page are there, instead of nothing:\n * `<ng-template epdfFallback>Loading…</ng-template>`.\n */\n@Directive({ selector: 'ng-template[epdfFallback]' })\nexport class EpdfFallback {\n readonly template = inject<TemplateRef<unknown>>(TemplateRef);\n}\n\n/** Every page view plans its pictures as its own view, so two views of one page never mix. */\nlet nextViewId = 0;\n\nconst frameEqual = (left: PageFrame, right: PageFrame) =>\n left.top === right.top &&\n left.right === right.right &&\n left.bottom === right.bottom &&\n left.left === right.left;\n\n/** The page's box before the content element exists (only a pointer event would ask). */\nconst NO_RECT = { x: 0, y: 0, left: 0, top: 0, right: 0, bottom: 0, width: 0, height: 0 };\n\n@Component({\n selector: 'epdf-page-view',\n imports: [NgTemplateOutlet, EpdfPagePointerSource],\n changeDetection: ChangeDetectionStrategy.OnPush,\n providers: [\n // What's inside talks to this view's document, draws on its page, and anchors to it.\n { provide: EPDF_DOCUMENT_SCOPE, useFactory: () => inject(EpdfPageView).documentScope },\n { provide: EPDF_PAGE, useFactory: () => inject(EpdfPageView).pageContext },\n { provide: EPDF_PROJECTOR, useFactory: () => inject(EpdfPageView).projection },\n EPDF_SCOPED_SERVICES,\n ],\n host: {\n style: 'position: relative; display: block',\n '[style.width.px]': 'shown() ? layout().outer.width : null',\n '[style.height.px]': 'shown() ? layout().outer.height : null',\n },\n template: `\n @if (shown()) {\n <!-- The shadow only: axis-aligned, with no fill that could show behind the picture. -->\n <div\n style=\"position: absolute\"\n [style.left.px]=\"layout().shadow.left\"\n [style.top.px]=\"layout().shadow.top\"\n [style.width.px]=\"layout().shadow.width\"\n [style.height.px]=\"layout().shadow.height\"\n [style.box-shadow]=\"shadow()\"\n ></div>\n <!-- The page: its background and its layers as one box, the only thing that turns. -->\n <div\n #content\n style=\"position: absolute; user-select: none; -webkit-user-select: none\"\n [style.left.px]=\"layout().content.left\"\n [style.top.px]=\"layout().content.top\"\n [style.width.px]=\"layout().content.width\"\n [style.height.px]=\"layout().content.height\"\n [style.background]=\"background()\"\n [style.transform]=\"layout().turn\"\n >\n <!-- The tools' pointer input comes first, so the layers sit on top of it: a press on a\n layer that lets the pointer through reaches the tools, and a control that takes its\n own presses (a link, a form field) keeps them. -->\n @if (takesPointer()) {\n <epdf-page-pointer-source />\n }\n <ng-content />\n </div>\n <!-- Around the page: fills the outer box, never turns. -->\n @if (chromeTemplate(); as chrome) {\n <ng-container [ngTemplateOutlet]=\"chrome\" [ngTemplateOutletContext]=\"templateContext\" />\n }\n } @else if (fallbackTemplate(); as fallback) {\n <ng-container [ngTemplateOutlet]=\"fallback\" />\n }\n `,\n})\nexport class EpdfPageView {\n /** The page: its `ref`, which follows it when pages move, or its index, from 0. */\n readonly page = input.required<PageRef | number>();\n /**\n * Which document to show. Without it, the one the surrounding `[epdfDocumentScope]` names,\n * else the active one.\n */\n readonly documentId = input<string | null | undefined>(undefined);\n /** The width of the page upright, in pixels: a page turned a quarter is that tall. */\n readonly width = input(240);\n /** Space reserved around the page for your own labels, in pixels per side; 0 for the others. */\n readonly pageFrame = input<Partial<PageFrame> | null | undefined>(undefined);\n\n private readonly host = injectKernelHost('<epdf-page-view>');\n private readonly parentScope = inject(EPDF_DOCUMENT_SCOPE, { optional: true, skipSelf: true });\n private readonly content = viewChild<ElementRef<HTMLDivElement>>('content');\n private readonly chromeDirective = contentChild(EpdfPageChrome);\n private readonly fallbackDirective = contentChild(EpdfFallback);\n protected readonly chromeTemplate = computed(() => this.chromeDirective()?.template ?? null);\n protected readonly fallbackTemplate = computed(() => this.fallbackDirective()?.template ?? null);\n\n private readonly activeId = this.host.read(\n (kernel) => kernel.documents.getActiveId(),\n () => null,\n );\n /** The document shown: `[documentId]`, else the scope's, else the active one. */\n private readonly docId = computed(\n () => this.documentId() ?? this.parentScope?.id() ?? this.activeId(),\n );\n\n /** For what's inside: services and layers talk to the document shown. */\n readonly documentScope: EpdfDocumentScopeRef = { id: this.docId };\n /** The interaction plugin of the document shown, when the viewer has it. */\n private readonly interaction = new CapabilityBinding(\n this.host,\n () => InteractionHostToken,\n this.docId,\n ).capability;\n\n /**\n * The page's entry in the document, by its object number or its index. Entries stay the\n * same object until their page changes, so a turn or a move reads as a new entry.\n */\n private readonly entry: Signal<PageInfo | null> = this.host.read(\n (kernel) => {\n const id = this.docId();\n if (!id) return null;\n const wanted = this.page();\n const pages = kernel.documents.listPages(id);\n const found =\n typeof wanted === 'number'\n ? pages[wanted]\n : pages.find((page) => page.ref.objectNumber === wanted.objectNumber);\n return found ?? null;\n },\n () => null,\n );\n\n /** Whether there's a page to show: the document is there and has it. */\n protected readonly shown = computed(() => this.entry() !== null);\n /** Whether the tools take the pointer here: with the interaction plugin, as on a Stage. */\n protected readonly takesPointer = computed(() => this.interaction() !== null);\n\n private readonly pageIndex = computed(() => {\n const wanted = this.page();\n return this.entry()?.index ?? (typeof wanted === 'number' ? wanted : 0);\n });\n /** The page's object number: a stand-in (its index + 1) only until the page is known. */\n private readonly objectNumber = computed(() => {\n const wanted = this.page();\n return (\n this.entry()?.ref.objectNumber ??\n (typeof wanted === 'number' ? wanted + 1 : wanted.objectNumber)\n );\n });\n /** The same ref object while the page is the same, so layers can key their work on it. */\n private readonly pageRef = computed(() => toPageRef(this.objectNumber()));\n\n protected readonly frame = computed(\n (): PageFrame => {\n const { top = 0, right = 0, bottom = 0, left = 0 } = this.pageFrame() ?? {};\n return { top, right, bottom, left };\n },\n { equal: frameEqual },\n );\n\n private readonly dpr = isPlatformBrowser(inject(PLATFORM_ID)) ? window.devicePixelRatio || 1 : 1;\n /** What the transform depends on, by value: a new entry for an unchanged page changes nothing. */\n private readonly geometry = computed(\n () => {\n const entry = this.entry();\n return {\n width: entry?.size.width ?? 1,\n height: entry?.size.height ?? 1,\n rotation: entry?.rotation ?? 0,\n userUnit: entry?.userUnit ?? 1,\n target: this.width(),\n known: entry !== null,\n };\n },\n { equal: shallowEqual },\n );\n /**\n * The page's transform, from the width alone (`pageViewTransformInput` from `@embedpdf/web`,\n * the same in every framework): view pixels per point is `width / page width`, and 100% is 1\n * point = 96/72 CSS pixels times the page's user unit, as on a Stage.\n */\n protected readonly transform: Signal<PageTransform> = computed(() => {\n const { width, height, rotation, userUnit, target, known } = this.geometry();\n const page = known ? { size: { width, height }, rotation, userUnit } : null;\n return pageTransform(pageViewTransformInput(page, target, this.dpr));\n });\n\n /** The outer box, the shadow at the footprint, and the turned content box. */\n protected readonly layout = computed(() => pageSurfaceLayout(this.transform(), this.frame()));\n /** The viewer's `page` settings; CSS `--epdf-page-shadow` and `--epdf-page-background` win. */\n private readonly look = computed(() => this.host.viewerSettings().page, {\n equal: shallowEqual,\n });\n protected readonly shadow = computed(() => paint('page-shadow', this.look().shadow));\n protected readonly background = computed(() => paint('page-background', this.look().background));\n\n private readonly viewId = `page-view:${++nextViewId}`;\n\n /**\n * The page context for the layers inside: one object for the view's lifetime, whose `ref`,\n * `documentId` and signals follow `[page]` and `[documentId]`. No view demand: a page view\n * wants the whole page.\n */\n readonly pageContext: EpdfPageContext = createPageContext({\n documentId: () => this.docId() ?? '',\n ref: () => this.pageRef(),\n view: () => this.viewId,\n pageIndex: this.pageIndex,\n frame: this.frame,\n transform: this.transform,\n getRect: () => this.content()?.nativeElement.getBoundingClientRect() ?? (NO_RECT as DOMRect),\n });\n\n protected readonly templateContext: EpdfPageTemplateContext = { $implicit: this.pageContext };\n\n /**\n * How anchored UI inside follows the page: by measuring it on screen. The revision is the\n * page and its transform; a scroll or a resize of the window moves the page without either,\n * so `observeClientGeometry` reports those.\n */\n readonly projection: EpdfProjectorBinding = {\n // `@embedpdf/web`'s measured projector, shared by every framework. It reads the context (and\n // its transform signal) when it projects, so it never goes stale.\n projector: signal(\n clientPageProjector(this.pageContext, () => this.content() !== undefined),\n ).asReadonly(),\n revision: computed(() => [this.pageRef(), this.transform()]),\n shownPages: computed(() => new Set([this.objectNumber()])),\n subscribe: observeClientGeometry,\n };\n}\n","/**\n * @embedpdf/angular/page-view: one page on its own, with no Stage.\n *\n * <epdf-page-view [page] [width]> the page, drawn with the layers between its tags\n * <ng-template epdfFallback> what shows until the document and the page are there\n * <ng-template epdfPageChrome> what goes around the page: the Stage's own template\n */\nexport * from './page-view';\nexport { EpdfPageChrome } from '@embedpdf/angular/stage';\nexport type { EpdfPageTemplateContext } from '@embedpdf/angular/stage';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":["InteractionHostToken"],"mappings":"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"}
@@ -0,0 +1,93 @@
1
+ import { redactionState, RedactionToken, redactionPlugin } from '@embedpdf/plugin-redaction';
2
+ export * from '@embedpdf/plugin-redaction';
3
+ import * as i0 from '@angular/core';
4
+ import { Injectable } from '@angular/core';
5
+ import { pluginService } from '@embedpdf/angular/runtime';
6
+
7
+ /**
8
+ * The redaction plugin's service and feature. Marking rides the annotation plugin (the `redact`
9
+ * tool makes ordinary annotations); the service is the workflow around it:
10
+ *
11
+ * withRedaction(options) the plugin, for provideEmbedPdf()
12
+ * inject(EpdfRedaction) marking, the marks waiting (`pending()`, `pendingOn(page)`),
13
+ * applying them, the State table as signals (`pendingCount()`,
14
+ * `applying()`, `lastResult()`), the events as streams, the settings
15
+ *
16
+ * await redaction.applyAll(); // can't be undone: ask first
17
+ */
18
+ const NO_MARKS = Object.freeze([]);
19
+ /**
20
+ * Redaction in the document in scope (`[epdfDocumentScope]`), else the active one: the
21
+ * Redaction page's methods, its State table as signals, the marks waiting to be applied as
22
+ * signals, the events as streams (`applied$`, `pendingChanged$`), and the settings. Without a
23
+ * document the signals read empty and the methods refuse with `not-ready`.
24
+ */
25
+ class EpdfRedaction extends pluginService({
26
+ name: 'EpdfRedaction',
27
+ feature: 'withRedaction()',
28
+ token: RedactionToken,
29
+ state: redactionState,
30
+ methods: [
31
+ 'markSelection',
32
+ 'markArea',
33
+ 'markPage',
34
+ 'markMatches',
35
+ 'unmark',
36
+ 'clearPending',
37
+ 'updateLabel',
38
+ 'listPending',
39
+ 'getPending',
40
+ 'getPendingCount',
41
+ 'estimateCollateral',
42
+ 'applyAll',
43
+ 'apply',
44
+ 'applyPages',
45
+ 'canMark',
46
+ 'canUnmark',
47
+ 'canUpdateLabel',
48
+ 'canApply',
49
+ 'isApplying',
50
+ 'getLastResult',
51
+ ],
52
+ events: ['onApplied', 'onPendingChanged'],
53
+ }) {
54
+ /**
55
+ * The marks waiting to be applied, in page order, for a review panel. The plugin hands out
56
+ * the same list until a mark changes, so a list redraws only then. Empty without a document.
57
+ */
58
+ pending = this.binding.select((redaction) => redaction.listPending(), NO_MARKS);
59
+ /**
60
+ * One page's marks (its ref or its index). Pass a function (`() => this.page().ref`) and it
61
+ * follows the page you show. Empty for a page without marks, and without a document.
62
+ */
63
+ pendingOn(page) {
64
+ const pageOf = typeof page === 'function' ? page : () => page;
65
+ return this.binding.select((redaction) => redaction.listPending({ page: pageOf() }), NO_MARKS);
66
+ }
67
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: EpdfRedaction, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
68
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: EpdfRedaction, providedIn: 'root' });
69
+ }
70
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: EpdfRedaction, decorators: [{
71
+ type: Injectable,
72
+ args: [{ providedIn: 'root' }]
73
+ }] });
74
+ /** Redaction, with its settings: `withRedaction({ overlay: { fill: '#1d2b53' } })`. */
75
+ function withRedaction(options) {
76
+ return { plugins: [redactionPlugin(options)], services: [EpdfRedaction] };
77
+ }
78
+
79
+ /**
80
+ * @embedpdf/angular/redaction: mark text and areas, review the marks, remove the content.
81
+ *
82
+ * withRedaction(options) the plugin, for provideEmbedPdf()
83
+ * inject(EpdfRedaction) markArea(), markMatches(), pending(), pendingOn(page),
84
+ * applyAll(), pendingCount(), applying(), applied$, …
85
+ */
86
+ // The plugin's types and helpers, so app code has one import for the feature.
87
+
88
+ /**
89
+ * Generated bundle index. Do not edit.
90
+ */
91
+
92
+ export { EpdfRedaction, withRedaction };
93
+ //# sourceMappingURL=embedpdf-angular-redaction.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"embedpdf-angular-redaction.mjs","sources":["../../redaction/src/redaction.ts","../../redaction/src/public_api.ts","../../redaction/src/embedpdf-angular-redaction.ts"],"sourcesContent":["/**\n * The redaction plugin's service and feature. Marking rides the annotation plugin (the `redact`\n * tool makes ordinary annotations); the service is the workflow around it:\n *\n * withRedaction(options) the plugin, for provideEmbedPdf()\n * inject(EpdfRedaction) marking, the marks waiting (`pending()`, `pendingOn(page)`),\n * applying them, the State table as signals (`pendingCount()`,\n * `applying()`, `lastResult()`), the events as streams, the settings\n *\n * await redaction.applyAll(); // can't be undone: ask first\n */\nimport { Injectable, type Signal } from '@angular/core';\nimport type { PageRef } from '@embedpdf/core';\nimport { pluginService, type EmbedPdfFeature } from '@embedpdf/angular/runtime';\n// `RedactionApplyResult` (what `lastResult()` holds) is imported so the built declarations take\n// it from the plugin, a dependency of this package, not from the engine package that declares it.\nimport {\n redactionPlugin,\n redactionState,\n RedactionToken,\n type RedactionApplyResult,\n type RedactionConfig,\n type RedactionMark,\n} from '@embedpdf/plugin-redaction';\n\nconst NO_MARKS: readonly RedactionMark[] = Object.freeze([]);\n\n/**\n * Redaction in the document in scope (`[epdfDocumentScope]`), else the active one: the\n * Redaction page's methods, its State table as signals, the marks waiting to be applied as\n * signals, the events as streams (`applied$`, `pendingChanged$`), and the settings. Without a\n * document the signals read empty and the methods refuse with `not-ready`.\n */\n@Injectable({ providedIn: 'root' })\nexport class EpdfRedaction extends pluginService({\n name: 'EpdfRedaction',\n feature: 'withRedaction()',\n token: RedactionToken,\n state: redactionState,\n methods: [\n 'markSelection',\n 'markArea',\n 'markPage',\n 'markMatches',\n 'unmark',\n 'clearPending',\n 'updateLabel',\n 'listPending',\n 'getPending',\n 'getPendingCount',\n 'estimateCollateral',\n 'applyAll',\n 'apply',\n 'applyPages',\n 'canMark',\n 'canUnmark',\n 'canUpdateLabel',\n 'canApply',\n 'isApplying',\n 'getLastResult',\n ],\n events: ['onApplied', 'onPendingChanged'],\n}) {\n /**\n * The marks waiting to be applied, in page order, for a review panel. The plugin hands out\n * the same list until a mark changes, so a list redraws only then. Empty without a document.\n */\n readonly pending: Signal<readonly RedactionMark[]> = this.binding.select(\n (redaction) => redaction.listPending(),\n NO_MARKS,\n );\n\n /**\n * One page's marks (its ref or its index). Pass a function (`() => this.page().ref`) and it\n * follows the page you show. Empty for a page without marks, and without a document.\n */\n pendingOn(page: PageRef | number | (() => PageRef | number)): Signal<readonly RedactionMark[]> {\n const pageOf = typeof page === 'function' ? page : () => page;\n return this.binding.select((redaction) => redaction.listPending({ page: pageOf() }), NO_MARKS);\n }\n}\n\n/** Redaction, with its settings: `withRedaction({ overlay: { fill: '#1d2b53' } })`. */\nexport function withRedaction(options?: RedactionConfig): EmbedPdfFeature {\n return { plugins: [redactionPlugin(options)], services: [EpdfRedaction] };\n}\n","/**\n * @embedpdf/angular/redaction: mark text and areas, review the marks, remove the content.\n *\n * withRedaction(options) the plugin, for provideEmbedPdf()\n * inject(EpdfRedaction) markArea(), markMatches(), pending(), pendingOn(page),\n * applyAll(), pendingCount(), applying(), applied$, …\n */\n\n// The plugin's types and helpers, so app code has one import for the feature.\nexport * from '@embedpdf/plugin-redaction';\nexport * from './redaction';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":";;;;;;AAAA;;;;;;;;;;AAUG;AAeH,MAAM,QAAQ,GAA6B,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;AAE5D;;;;;AAKG;AAEG,MAAO,aAAc,SAAQ,aAAa,CAAC;AAC/C,IAAA,IAAI,EAAE,eAAe;AACrB,IAAA,OAAO,EAAE,iBAAiB;AAC1B,IAAA,KAAK,EAAE,cAAc;AACrB,IAAA,KAAK,EAAE,cAAc;AACrB,IAAA,OAAO,EAAE;QACP,eAAe;QACf,UAAU;QACV,UAAU;QACV,aAAa;QACb,QAAQ;QACR,cAAc;QACd,aAAa;QACb,aAAa;QACb,YAAY;QACZ,iBAAiB;QACjB,oBAAoB;QACpB,UAAU;QACV,OAAO;QACP,YAAY;QACZ,SAAS;QACT,WAAW;QACX,gBAAgB;QAChB,UAAU;QACV,YAAY;QACZ,eAAe;AAChB,KAAA;AACD,IAAA,MAAM,EAAE,CAAC,WAAW,EAAE,kBAAkB,CAAC;CAC1C,CAAC,CAAA;AACA;;;AAGG;AACM,IAAA,OAAO,GAAqC,IAAI,CAAC,OAAO,CAAC,MAAM,CACtE,CAAC,SAAS,KAAK,SAAS,CAAC,WAAW,EAAE,EACtC,QAAQ,CACT;AAED;;;AAGG;AACH,IAAA,SAAS,CAAC,IAAiD,EAAA;AACzD,QAAA,MAAM,MAAM,GAAG,OAAO,IAAI,KAAK,UAAU,GAAG,IAAI,GAAG,MAAM,IAAI;QAC7D,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,CAAC;IAChG;uGA7CW,aAAa,EAAA,IAAA,EAAA,IAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAAb,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,aAAa,cADA,MAAM,EAAA,CAAA;;2FACnB,aAAa,EAAA,UAAA,EAAA,CAAA;kBADzB,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;AAiDlC;AACM,SAAU,aAAa,CAAC,OAAyB,EAAA;AACrD,IAAA,OAAO,EAAE,OAAO,EAAE,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,aAAa,CAAC,EAAE;AAC3E;;ACrFA;;;;;;AAMG;AAEH;;ACRA;;AAEG;;;;"}