@hmcts/media-viewer 4.1.8 → 4.1.9-exui-1580

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 (34) hide show
  1. package/assets/all.scss +1 -0
  2. package/assets/sass/pdf-viewer.scss +79 -1
  3. package/assets/sass/tooltip.scss +50 -0
  4. package/esm2022/lib/annotations/annotation-set/annotation-create/highlight-create/highlight-create.directive.mjs +80 -21
  5. package/esm2022/lib/annotations/annotation-set/annotation-create/highlight-create/keyboard-text-highlight.directive.mjs +354 -0
  6. package/esm2022/lib/annotations/annotation-set/annotation-view/annotation-view.component.mjs +1 -1
  7. package/esm2022/lib/annotations/annotation-set/ctx-toolbar/ctx-toolbar.component.mjs +31 -5
  8. package/esm2022/lib/annotations/annotation-set/metadata-layer/metadata-layer.component.mjs +17 -4
  9. package/esm2022/lib/media-viewer.module.mjs +4 -1
  10. package/esm2022/lib/shared/directives/tooltip-dismiss.directive.mjs +36 -0
  11. package/esm2022/lib/toolbar/highlight-toolbar/highlight-toolbar.component.mjs +6 -4
  12. package/esm2022/lib/toolbar/main-toolbar/main-toolbar.component.mjs +5 -4
  13. package/esm2022/lib/toolbar/redaction-toolbar/redaction-toolbar.component.mjs +5 -4
  14. package/esm2022/lib/toolbar/toolbar.module.mjs +7 -4
  15. package/esm2022/lib/viewers/pdf-viewer/pdf-viewer.component.mjs +45 -7
  16. package/fesm2022/hmcts-media-viewer.mjs +1448 -926
  17. package/fesm2022/hmcts-media-viewer.mjs.map +1 -1
  18. package/lib/annotations/annotation-set/annotation-create/highlight-create/highlight-create.directive.d.ts +6 -2
  19. package/lib/annotations/annotation-set/annotation-create/highlight-create/highlight-create.directive.d.ts.map +1 -1
  20. package/lib/annotations/annotation-set/annotation-create/highlight-create/keyboard-text-highlight.directive.d.ts +63 -0
  21. package/lib/annotations/annotation-set/annotation-create/highlight-create/keyboard-text-highlight.directive.d.ts.map +1 -0
  22. package/lib/annotations/annotation-set/ctx-toolbar/ctx-toolbar.component.d.ts +6 -2
  23. package/lib/annotations/annotation-set/ctx-toolbar/ctx-toolbar.component.d.ts.map +1 -1
  24. package/lib/annotations/annotation-set/metadata-layer/metadata-layer.component.d.ts +3 -0
  25. package/lib/annotations/annotation-set/metadata-layer/metadata-layer.component.d.ts.map +1 -1
  26. package/lib/media-viewer.module.d.ts +19 -18
  27. package/lib/media-viewer.module.d.ts.map +1 -1
  28. package/lib/shared/directives/tooltip-dismiss.directive.d.ts +11 -0
  29. package/lib/shared/directives/tooltip-dismiss.directive.d.ts.map +1 -0
  30. package/lib/toolbar/toolbar.module.d.ts +7 -6
  31. package/lib/toolbar/toolbar.module.d.ts.map +1 -1
  32. package/lib/viewers/pdf-viewer/pdf-viewer.component.d.ts +20 -0
  33. package/lib/viewers/pdf-viewer/pdf-viewer.component.d.ts.map +1 -1
  34. package/package.json +2 -2
@@ -1,15 +1,15 @@
1
1
  import * as i5$1 from 'rpx-xui-translation';
2
2
  import { RpxTranslationModule } from 'rpx-xui-translation';
3
3
  import * as i0 from '@angular/core';
4
- import { Injectable, Component, ViewChild, HostListener, Directive, Input, ViewEncapsulation, Pipe, EventEmitter, Output, ViewChildren, NgModule } from '@angular/core';
4
+ import { Injectable, Directive, HostListener, Component, ViewChild, Input, ViewEncapsulation, Pipe, EventEmitter, Output, ViewChildren, NgModule } from '@angular/core';
5
5
  import * as i5 from '@angular/common';
6
6
  import { DatePipe, CommonModule } from '@angular/common';
7
7
  import * as i2 from '@angular/forms';
8
8
  import { UntypedFormControl, FormGroup, FormControl, Validators, FormsModule, ReactiveFormsModule } from '@angular/forms';
9
9
  import * as i1$1 from '@angular/common/http';
10
10
  import { HttpClientModule } from '@angular/common/http';
11
- import { BehaviorSubject, Subject, of, combineLatest, asyncScheduler } from 'rxjs';
12
- import { take, distinctUntilChanged, filter, auditTime, tap, throttleTime, map, catchError, switchMap, concatMap, exhaustMap, withLatestFrom } from 'rxjs/operators';
11
+ import { BehaviorSubject, Subject, filter, debounceTime, of, combineLatest, asyncScheduler } from 'rxjs';
12
+ import { take, distinctUntilChanged, filter as filter$1, auditTime, tap, throttleTime, map, catchError, switchMap, concatMap, exhaustMap, withLatestFrom } from 'rxjs/operators';
13
13
  import * as i1 from '@ngrx/store';
14
14
  import { createFeatureSelector, createSelector, select, StoreModule } from '@ngrx/store';
15
15
  import { v4 } from 'uuid';
@@ -1526,482 +1526,887 @@ const getConvertedDocument = createSelector(getDocumentState, getConvertedDocume
1526
1526
  const getRotation = createSelector(getDocumentState, getRotation$1);
1527
1527
  const rotationLoaded = createSelector(getDocumentState, rotationLoaded$1);
1528
1528
 
1529
- pdfjs.GlobalWorkerOptions.workerSrc = '/assets/build/pdf.worker.min.js';
1530
1529
  /**
1531
- * Values of the state field returned by the find events
1532
- */
1533
- var FindState;
1534
- (function (FindState) {
1535
- FindState[FindState["FOUND"] = 0] = "FOUND";
1536
- FindState[FindState["NOT_FOUND"] = 1] = "NOT_FOUND";
1537
- FindState[FindState["WRAPPED"] = 2] = "WRAPPED";
1538
- FindState[FindState["PENDING"] = 3] = "PENDING";
1539
- })(FindState || (FindState = {}));
1540
- class PdfJsWrapper {
1541
- constructor(pdfViewer, downloadManager, toolbarEvents, documentLoadInit, documentLoadProgress, documentLoaded, outlineLoaded, documentLoadFailed, pageRendered, positionUpdated) {
1542
- this.pdfViewer = pdfViewer;
1543
- this.downloadManager = downloadManager;
1544
- this.toolbarEvents = toolbarEvents;
1545
- this.documentLoadInit = documentLoadInit;
1546
- this.documentLoadProgress = documentLoadProgress;
1547
- this.documentLoaded = documentLoaded;
1548
- this.outlineLoaded = outlineLoaded;
1549
- this.documentLoadFailed = documentLoadFailed;
1550
- this.pageRendered = pageRendered;
1551
- this.positionUpdated = positionUpdated;
1552
- this.pdfViewer.eventBus.on('updateviewarea', e => positionUpdated.next(e));
1553
- this.pdfViewer.eventBus.on('pagechanging', e => this.toolbarEvents.setCurrentPageInputValueSubject.next(e.pageNumber));
1554
- this.pdfViewer.eventBus.on('pagechanging', e => this.drawMissingPages(e));
1555
- this.pdfViewer.eventBus.on('pagesinit', () => this.pdfViewer.currentScaleValue = '1');
1556
- this.pdfViewer.eventBus.on('pagerendered', e => { }); // not used left for future convenience
1557
- this.pdfViewer.eventBus.on('pagesloaded', (e) => this.emitDocumentInfo(e));
1558
- this.pdfViewer.eventBus.on('scalechanging', (e) => this.emitDocumentInfo(e));
1559
- this.pdfViewer.eventBus.on('rotationchanging', (e) => this.emitDocumentInfo(e));
1560
- this.pdfViewer.eventBus.on('updatefindcontrolstate', event => {
1561
- this.sendSearchDetails(event);
1562
- });
1563
- this.pdfViewer.eventBus.on('updatefindmatchescount', event => {
1564
- const result = { ...event.matchesCount, isPrevious: event?.source?.state?.findPrevious };
1565
- this.toolbarEvents.searchResultsCountSubject.next(result);
1566
- });
1567
- this.zoomValue = 1;
1568
- this.redactionPages = [];
1569
- // Subscribe to redactionMode changes and run a function when it changes
1570
- this.toolbarEvents.redactionMode.subscribe((redactionModeValue) => {
1571
- this.onRedactionModeChanged(redactionModeValue);
1572
- });
1530
+ * Helper Class
1531
+ * Used for dynamic templates manipulation
1532
+ * */
1533
+ class HtmlTemplatesHelper {
1534
+ static setDescribedBy(errorMessage, config) {
1535
+ if (!errorMessage) {
1536
+ return config.hint ? `${config.id}-hint` : null;
1537
+ }
1538
+ else if (errorMessage && errorMessage.isInvalid) {
1539
+ return config.hint ? `${config.id}-hint ${config.id}-error` : `${config.id}-error`;
1540
+ }
1541
+ else {
1542
+ return config.hint ? `${config.id}-hint` : null;
1543
+ }
1573
1544
  }
1574
- sendSearchDetails(event) {
1575
- if (event.state !== FindState.PENDING) {
1576
- const result = { ...event.matchesCount, isPrevious: event?.source?.state?.findPrevious };
1577
- this.toolbarEvents.searchResultsCountSubject.next(result);
1578
- if (event?.source?.selected?.pageIdx !== -1 && event.matchesCount.total > 0) {
1579
- this.toolbarEvents.redactionSerachSubject.next({
1580
- page: event?.source?.selected?.pageIdx,
1581
- matchedIndex: event?.source?.selected?.matchIdx,
1582
- matchesCount: event.matchesCount.total
1583
- });
1584
- }
1545
+ static getAdjustedBoundingRect(element, log = true) {
1546
+ const viewportX = window.visualViewport.offsetLeft;
1547
+ const viewportY = window.visualViewport.offsetTop;
1548
+ const viewportScale = window.visualViewport.scale;
1549
+ const viewportPageX = window.visualViewport.pageLeft;
1550
+ const viewportPageY = window.visualViewport.pageTop;
1551
+ if (log && viewportX || viewportY || (viewportScale != 1) || viewportPageX || viewportPageY) {
1552
+ console.log(`Element: ${element.id} Viewport X: ${viewportX}, Y: ${viewportY}, Scale: ${viewportScale}, PageX: ${viewportPageX}, PageY: ${viewportPageY}`);
1585
1553
  }
1554
+ return element.getBoundingClientRect();
1586
1555
  }
1587
- // in the event a user fast scrolls or navigates to a specific page,
1588
- // we need to render the missing pages so redaction box is in right place
1589
- drawMissingPages(e) {
1590
- const redactionMode = this.toolbarEvents.redactionMode.getValue();
1591
- const { pageNumber, previous: previousPageNumber } = e;
1592
- if (!previousPageNumber || pageNumber < previousPageNumber || Math.abs(pageNumber - previousPageNumber) <= 1) {
1593
- return;
1556
+ }
1557
+
1558
+ class IcpEventService {
1559
+ constructor() {
1560
+ this.enabled = new BehaviorSubject(false);
1561
+ this.sessionLaunch = new Subject();
1562
+ this.becomingPresenter = new Subject();
1563
+ this.stoppingPresenting = new Subject();
1564
+ this.leavingSession = new BehaviorSubject(false);
1565
+ this.sessionExitConfirmed = new Subject();
1566
+ this.participantsListVisible = new BehaviorSubject(false);
1567
+ this.launchSession = () => {
1568
+ this.sessionLaunch.next();
1569
+ };
1570
+ this.enable = () => {
1571
+ this.enabled.next(true);
1572
+ this.launchSession();
1573
+ };
1574
+ this.becomePresenter = () => {
1575
+ this.becomingPresenter.next();
1576
+ };
1577
+ this.stopPresenting = () => {
1578
+ this.stoppingPresenting.next();
1579
+ };
1580
+ this.leaveSession = () => {
1581
+ this.leavingSession.next(true);
1582
+ };
1583
+ this.confirmExit = () => {
1584
+ this.sessionExitConfirmed.next();
1585
+ this.participantsListVisible.next(false);
1586
+ this.enabled.next(false);
1587
+ };
1588
+ }
1589
+ /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: IcpEventService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1590
+ /** @nocollapse */ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: IcpEventService, providedIn: 'root' }); }
1591
+ }
1592
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: IcpEventService, decorators: [{
1593
+ type: Injectable,
1594
+ args: [{
1595
+ providedIn: 'root'
1596
+ }]
1597
+ }], ctorParameters: () => [] });
1598
+
1599
+ var SearchType;
1600
+ (function (SearchType) {
1601
+ SearchType["Redact"] = "Redact";
1602
+ SearchType["Highlight"] = "Highlight";
1603
+ })(SearchType || (SearchType = {}));
1604
+ class ToolbarEventService {
1605
+ constructor(icpEventService) {
1606
+ this.icpEventService = icpEventService;
1607
+ this.highlightModeSubject = new BehaviorSubject(false);
1608
+ this.highlightToolbarSubject = new BehaviorSubject(false);
1609
+ this.drawModeSubject = new BehaviorSubject(false);
1610
+ this.rotateSubject = new Subject();
1611
+ this.searchSubject = new Subject();
1612
+ this.searchResultsCountSubject = new Subject();
1613
+ this.zoomSubject = new Subject();
1614
+ this.stepZoomSubject = new Subject();
1615
+ this.zoomValueSubject = new BehaviorSubject(1);
1616
+ this.pageCountSubject = new Subject();
1617
+ this.printSubject = new Subject();
1618
+ this.downloadSubject = new Subject();
1619
+ this.setCurrentPageSubject = new Subject();
1620
+ this.setCurrentPageInputValueSubject = new Subject();
1621
+ this.changePageByDeltaSubject = new Subject();
1622
+ this.showCommentSummary = new BehaviorSubject(false);
1623
+ this.grabNDrag = new BehaviorSubject(false);
1624
+ this.saveRotationSubject = new Subject();
1625
+ this.redactionMode = new BehaviorSubject(false);
1626
+ this.redactionPreview = new Subject();
1627
+ this.applyRedactToDocument = new Subject();
1628
+ this.clearAllRedactMarkers = new Subject();
1629
+ this.redactWholePage = new Subject();
1630
+ this.redactionSerachSubject = new Subject();
1631
+ this.redactAllInProgressSubject = new BehaviorSubject(false);
1632
+ this.openRedactionSearch = new BehaviorSubject(null);
1633
+ this.sidebarOpen = new BehaviorSubject(false);
1634
+ this.sidebarOutlineView = new BehaviorSubject(true);
1635
+ this.searchBarHidden = new BehaviorSubject(true);
1636
+ this.commentsPanelVisible = new BehaviorSubject(false);
1637
+ }
1638
+ /**
1639
+ * Reset the stateful behaviour subjects
1640
+ */
1641
+ reset() {
1642
+ this.setCurrentPageSubject.next(1);
1643
+ this.zoomValueSubject.next(1);
1644
+ this.highlightModeSubject.next(false);
1645
+ this.highlightToolbarSubject.next(false);
1646
+ this.drawModeSubject.next(false);
1647
+ this.showCommentSummary.next(false);
1648
+ this.grabNDrag.next(false);
1649
+ }
1650
+ // Function to inform Observers that highlightMode has been enabled
1651
+ toggleHighlightMode() {
1652
+ // Highlight and Draw states are mutually exclusive
1653
+ if (this.highlightModeSubject.getValue() === false) {
1654
+ this.drawModeSubject.next(false);
1655
+ this.grabNDrag.next(false);
1656
+ this.highlightModeSubject.next(true);
1594
1657
  }
1595
- const start = previousPageNumber + 1;
1596
- const end = pageNumber;
1597
- // if the redaction mode is on render the pages now
1598
- if (redactionMode) {
1599
- for (let i = start; i < end; i++) {
1600
- const page = this.pdfViewer._pages[i - 1];
1601
- if (page && !page.renderingState) {
1602
- page.draw();
1603
- }
1604
- }
1658
+ else {
1659
+ this.highlightModeSubject.next(false);
1660
+ }
1661
+ }
1662
+ // Function to inform Observers that ToggleMode has been enabled
1663
+ toggleDrawMode() {
1664
+ if (this.drawModeSubject.getValue() === false) {
1665
+ this.highlightModeSubject.next(false);
1666
+ this.grabNDrag.next(false);
1667
+ this.drawModeSubject.next(true);
1605
1668
  }
1606
1669
  else {
1607
- // keep track of pages as if a user skips to a page we need to render all the missing pages
1608
- console.log('Adding redaction pages to queue:', start, end);
1609
- this.redactionPages.push({ start, end });
1670
+ this.drawModeSubject.next(false);
1610
1671
  }
1611
1672
  }
1612
- onRedactionModeChanged(redactionMode) {
1613
- if (redactionMode && this.redactionPages.length) {
1614
- this.redactionPages.forEach(({ start, end }) => {
1615
- console.log('Drawing redaction pages from queue:', start, end);
1616
- for (let i = start; i < end; i++) {
1617
- const page = this.pdfViewer._pages[i - 1];
1618
- if (page && !page.renderingState) {
1619
- page.draw();
1620
- }
1621
- }
1622
- });
1623
- this.redactionPages = [];
1673
+ toggleHighlightToolbar() {
1674
+ this.highlightToolbarSubject.next(!this.highlightToolbarSubject.getValue());
1675
+ }
1676
+ rotate(angle) {
1677
+ this.rotateSubject.next(angle);
1678
+ }
1679
+ search(phrase) {
1680
+ this.searchSubject.next(phrase);
1681
+ }
1682
+ getSearchResultsCount() {
1683
+ return this.searchResultsCountSubject.asObservable();
1684
+ }
1685
+ zoom(value) {
1686
+ this.zoomSubject.next(value);
1687
+ }
1688
+ stepZoom(value) {
1689
+ this.stepZoomSubject.next(value);
1690
+ }
1691
+ getZoomValue() {
1692
+ return this.zoomValueSubject.asObservable();
1693
+ }
1694
+ getPageCount() {
1695
+ return this.pageCountSubject.asObservable();
1696
+ }
1697
+ print() {
1698
+ this.printSubject.next();
1699
+ }
1700
+ download() {
1701
+ this.downloadSubject.next();
1702
+ }
1703
+ setPage(value) {
1704
+ this.setCurrentPageSubject.next(value);
1705
+ }
1706
+ incrementPage(value) {
1707
+ this.changePageByDeltaSubject.next(value);
1708
+ }
1709
+ getCurrentPageNumber() {
1710
+ return this.setCurrentPageInputValueSubject.asObservable();
1711
+ }
1712
+ getShowCommentSummary() {
1713
+ return this.showCommentSummary.asObservable();
1714
+ }
1715
+ toggleCommentsSummary(value) {
1716
+ this.showCommentSummary.next(value);
1717
+ }
1718
+ saveRotation() {
1719
+ this.saveRotationSubject.next();
1720
+ }
1721
+ toggleGrabNDrag() {
1722
+ this.grabNDrag.next(!this.grabNDrag.getValue());
1723
+ }
1724
+ toggleSideBar(toggle) {
1725
+ this.sidebarOpen.next(toggle);
1726
+ }
1727
+ toggleSideBarView(toggle) {
1728
+ this.sidebarOutlineView.next(toggle);
1729
+ }
1730
+ toggleRedactionMode() {
1731
+ if (this.redactionMode.getValue() === false) {
1732
+ this.drawModeSubject.next(false);
1733
+ this.grabNDrag.next(false);
1734
+ this.redactionMode.next(true);
1735
+ }
1736
+ else {
1737
+ this.redactionMode.next(false);
1624
1738
  }
1739
+ this.openRedactionSearch.next({ modeType: SearchType.Redact, isOpen: false });
1625
1740
  }
1626
- emitDocumentInfo(e) {
1627
- const allPages = [...this.pdfViewer._pages].map(page => {
1628
- return {
1629
- div: page.div,
1630
- scale: page.scale,
1631
- rotation: page.rotation,
1632
- id: page.id,
1633
- viewportScale: page.viewport.scale
1634
- };
1635
- });
1636
- this.pageRendered.next(allPages);
1741
+ toggleRedactionPreview(viewMode) {
1742
+ this.redactionPreview.next(viewMode);
1637
1743
  }
1638
- async loadDocument(documentUrl) {
1639
- const loadingTask = this.createLoadingTask(documentUrl);
1640
- loadingTask.onProgress = ({ loaded, total }) => {
1641
- this.documentLoadProgress.next({ loaded, total });
1642
- };
1643
- this.documentLoadInit.next(documentUrl);
1644
- try {
1645
- const pdfDocument = await loadingTask.promise;
1646
- this.documentLoaded.next(pdfDocument);
1647
- this.toolbarEvents.pageCountSubject.next(pdfDocument.numPages);
1648
- this.pdfViewer.setDocument(pdfDocument);
1649
- if (this.pdfViewer.linkService instanceof PDFLinkService) {
1650
- const linkservice = this.pdfViewer.linkService;
1651
- linkservice.setDocument(pdfDocument, null);
1652
- }
1653
- const outlineNode = await pdfDocument.getOutline();
1654
- const outline = outlineNode ? outlineNode.map(x => {
1655
- return {
1656
- bold: x.bold,
1657
- color: x.color,
1658
- count: x.count,
1659
- dest: x.dest,
1660
- italic: x.italic,
1661
- items: x.items,
1662
- newWindow: x.newWindow,
1663
- title: x.title,
1664
- unsafeUrl: x.unsafeUrl,
1665
- url: x.url
1666
- };
1667
- }) : null;
1668
- if (outline) {
1669
- await this.setOutlinePageNumbers(pdfDocument, outline);
1670
- }
1671
- this.documentOutline = outline;
1672
- this.outlineLoaded.next(this.documentOutline);
1673
- const pdfMetaData = await pdfDocument.getMetadata();
1674
- this.setCurrentPDFTitle(pdfMetaData.info?.Title);
1744
+ unmarkAll() {
1745
+ this.clearAllRedactMarkers.next();
1746
+ }
1747
+ applyRedactionToDocument() {
1748
+ this.applyRedactToDocument.next();
1749
+ }
1750
+ redactPage() {
1751
+ this.redactWholePage.next();
1752
+ }
1753
+ toggleCommentsPanel(isVisible) {
1754
+ if (isVisible) {
1755
+ this.toggleParticipantsList(!isVisible);
1675
1756
  }
1676
- catch (e) {
1677
- this.documentLoadFailed.next(e);
1757
+ this.commentsPanelVisible.next(isVisible);
1758
+ }
1759
+ toggleParticipantsList(isVisible) {
1760
+ if (isVisible) {
1761
+ this.toggleCommentsPanel(!isVisible);
1678
1762
  }
1763
+ this.icpEventService.participantsListVisible.next(isVisible);
1679
1764
  }
1680
- createLoadingTask(documentUrl) {
1681
- return pdfjs.getDocument({
1682
- url: documentUrl,
1683
- cMapUrl: 'assets/minified/cmaps',
1684
- cMapPacked: true,
1685
- withCredentials: true,
1686
- isEvalSupported: false
1765
+ /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ToolbarEventService, deps: [{ token: IcpEventService }], target: i0.ɵɵFactoryTarget.Injectable }); }
1766
+ /** @nocollapse */ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ToolbarEventService, providedIn: 'root' }); }
1767
+ }
1768
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ToolbarEventService, decorators: [{
1769
+ type: Injectable,
1770
+ args: [{ providedIn: 'root' }]
1771
+ }], ctorParameters: () => [{ type: IcpEventService }] });
1772
+
1773
+ class ViewerEventService {
1774
+ constructor() {
1775
+ this.textHighlight = new Subject();
1776
+ this.boxHighlight = new Subject();
1777
+ this.ctxToolbarCleared = new Subject();
1778
+ this.navigationEvent = new Subject();
1779
+ this.navigationEventICP = new Subject();
1780
+ }
1781
+ textSelected(selectionData) {
1782
+ this.textHighlight.next(selectionData);
1783
+ }
1784
+ boxSelected(selectionData) {
1785
+ this.boxHighlight.next(selectionData);
1786
+ }
1787
+ clearCtxToolbar() {
1788
+ this.ctxToolbarCleared.next();
1789
+ }
1790
+ goToDestination(destination) {
1791
+ this.navigationEvent.next(destination);
1792
+ }
1793
+ goToDestinationICP(destination) {
1794
+ this.navigationEventICP.next(destination);
1795
+ }
1796
+ /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ViewerEventService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1797
+ /** @nocollapse */ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ViewerEventService, providedIn: 'root' }); }
1798
+ }
1799
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ViewerEventService, decorators: [{
1800
+ type: Injectable,
1801
+ args: [{ providedIn: 'root' }]
1802
+ }], ctorParameters: () => [] });
1803
+
1804
+ const getTagsRootState = createSelector(getMVState, (state) => state.tags);
1805
+ const getTagEntities = createSelector(getTagsRootState, getTagNameEnt);
1806
+ const getTagFilters = createSelector(getTagsRootState, getFilters);
1807
+ const getTagFiltered = createSelector(getTagsRootState, getFilteredComments);
1808
+ const getFilteredPageEntities = createSelector(getTagsRootState, getFilteredPageEnt);
1809
+ const getAllTagsArr = createSelector(getTagEntities, (tagEnt) => Object.keys(tagEnt).map(key => {
1810
+ return {
1811
+ key,
1812
+ length: Object.keys(tagEnt[key]).length
1813
+ };
1814
+ }));
1815
+
1816
+ const getAnnotationsSetState = createSelector(getMVState, (state) => state.annotations);
1817
+ const getAnnotationEntities = createSelector(getAnnotationsSetState, getAnnoEnt);
1818
+ const getSet = createSelector(getAnnotationsSetState, getAnnoSet);
1819
+ const getDocumentIdSetId = createSelector(getSet, (annoSet) => {
1820
+ return {
1821
+ documentId: annoSet.documentId,
1822
+ annotationSetId: annoSet.id
1823
+ };
1824
+ });
1825
+ const getAnnotationSet = createSelector(getAnnotationEntities, getSet, (entities, set) => {
1826
+ return {
1827
+ ...set,
1828
+ annotations: Object.keys(entities).map(key => entities[key])
1829
+ };
1830
+ });
1831
+ const getSelectedAnnotation = createSelector(getAnnotationsSetState, getSelectedAnno);
1832
+ const getCommentEntities = createSelector(getAnnotationsSetState, getCommentEnts);
1833
+ const getPageEntities = createSelector(getAnnotationsSetState, getAnnoPageEnt);
1834
+ const getComponentSearchQueries = createSelector(getAnnotationsSetState, commentSearchQ);
1835
+ const getComponentSearchText = createSelector(getComponentSearchQueries, (queries) => queries.commentSearch);
1836
+ const getCommentSummaryFilters = createSelector(getAnnotationsSetState, getSummaryFilters);
1837
+ const getAnnoPerPage = createSelector(getPages, getPageEntities, getFilteredPageEntities, (pages, pageEnt, filteredPageEnt) => {
1838
+ const isFiltered = !!Object.keys(filteredPageEnt).length;
1839
+ const entities = isFiltered ? filteredPageEnt : pageEnt;
1840
+ if (pages) {
1841
+ const arr = [];
1842
+ Object.keys(pages).forEach(key => {
1843
+ arr.push({
1844
+ anno: entities[key] ? entities[key] : [],
1845
+ styles: pages[key].styles
1846
+ });
1687
1847
  });
1848
+ return arr;
1688
1849
  }
1689
- async setOutlinePageNumbers(pdfDocument, outlineArray) {
1690
- outlineArray.forEach(async (outline) => {
1691
- await this.setNestedOutlinePageNumbers(pdfDocument, outline);
1850
+ });
1851
+ const getCommentsArray = createSelector(getCommentEntities, getPages, getAnnotationEntities, getTagFiltered, (commentEnts, pages, annoEnts, filtered) => {
1852
+ if (commentEnts && annoEnts && pages[1]) {
1853
+ const isFiltered = !!Object.keys(filtered).length;
1854
+ const com = isFiltered ? filtered : commentEnts;
1855
+ return Object.keys(com).map(key => {
1856
+ const page = annoEnts[key].page;
1857
+ return {
1858
+ ...commentEnts[key],
1859
+ page,
1860
+ pages
1861
+ };
1692
1862
  });
1693
1863
  }
1694
- async setNestedOutlinePageNumbers(pdfDocument, outline) {
1695
- outline.pageNumber = await this.getOutlinePageNumber(pdfDocument, outline);
1696
- outline.items.forEach(async (outlineItem) => {
1697
- outlineItem.pageNumber = await this.getOutlinePageNumber(pdfDocument, outlineItem);
1698
- this.setNestedOutlinePageNumbers(pdfDocument, outlineItem);
1864
+ });
1865
+ const getCommentSummary = createSelector(getCommentsArray, getCommentSummaryFilters, (commentSummary = [], filters) => {
1866
+ const comments = StoreUtils.filterCommentsSummary(commentSummary, filters.filters);
1867
+ if (comments.length) {
1868
+ const savedComments = comments.filter((comment) => {
1869
+ return comment.createdByDetails !== undefined;
1870
+ });
1871
+ return savedComments.map((comment) => {
1872
+ return {
1873
+ page: comment.page,
1874
+ user: comment.createdByDetails.forename.concat(' ').concat(comment.createdByDetails.surname),
1875
+ date: moment(comment.lastModifiedDate).format('D MMMM YYYY'),
1876
+ tags: comment.tags,
1877
+ comment: comment.content
1878
+ };
1699
1879
  });
1700
1880
  }
1701
- async getOutlinePageNumber(pdfDocument, outline) {
1702
- const dest = outline.dest;
1703
- const pageIndex = await pdfDocument.getPageIndex(dest[0]);
1704
- return Number(pageIndex) + 1;
1881
+ return [''];
1882
+ });
1883
+ const getFilteredAnnotations = createSelector(getAnnotationEntities, getTagFiltered, (annoEnt, filters) => {
1884
+ const isFiltered = !!Object.keys(filters).length;
1885
+ const anno = isFiltered ? filters : annoEnt;
1886
+ return Object.keys(anno).map(key => annoEnt[key])
1887
+ .filter(annotation => annotation.comments && annotation.comments.length > 0);
1888
+ });
1889
+
1890
+ class HighlightCreateService {
1891
+ constructor(toolBarEvents, store) {
1892
+ this.toolBarEvents = toolBarEvents;
1893
+ this.store = store;
1705
1894
  }
1706
- downloadFile(url, filename) {
1707
- this.downloadManager.download(null, url, filename);
1895
+ saveAnnotation(rectangles, page) {
1896
+ this.store.pipe(select(getDocumentIdSetId), take(1)).subscribe(anoSetDocId => {
1897
+ const anno = {
1898
+ id: v4(),
1899
+ color: 'FFFF00',
1900
+ comments: [],
1901
+ page: page,
1902
+ rectangles: rectangles,
1903
+ type: 'highlight',
1904
+ ...anoSetDocId,
1905
+ createdBy: '',
1906
+ createdByDetails: undefined,
1907
+ createdDate: moment.utc().tz('Europe/London').toISOString(),
1908
+ lastModifiedBy: '',
1909
+ lastModifiedByDetails: undefined,
1910
+ lastModifiedDate: '',
1911
+ tags: [],
1912
+ };
1913
+ this.store.dispatch(new SaveAnnotation(anno));
1914
+ });
1708
1915
  }
1709
- setPageNumber(pageNumber) {
1710
- this.pdfViewer.currentPageNumber = pageNumber;
1916
+ saveAnnotationSet(searchRectangles) {
1917
+ this.store.pipe(select(getDocumentIdSetId), take(1)).subscribe(anoSetDocId => {
1918
+ const annoSet = searchRectangles.map(x => {
1919
+ return {
1920
+ id: v4(),
1921
+ color: 'FFFF00',
1922
+ comments: [],
1923
+ page: x.page,
1924
+ rectangles: x.rectangles,
1925
+ type: 'highlight',
1926
+ ...anoSetDocId,
1927
+ createdBy: '',
1928
+ createdByDetails: undefined,
1929
+ createdDate: moment.utc().tz('Europe/London').toISOString(),
1930
+ lastModifiedBy: '',
1931
+ lastModifiedByDetails: undefined,
1932
+ lastModifiedDate: '',
1933
+ tags: [],
1934
+ };
1935
+ });
1936
+ this.store.dispatch(new SaveAnnotationSet({
1937
+ id: anoSetDocId.annotationSetId, annotations: annoSet, documentId: anoSetDocId.documentId
1938
+ }));
1939
+ });
1711
1940
  }
1712
- getPageNumber() {
1713
- return this.pdfViewer.currentPageNumber;
1941
+ applyRotation(pageHeight, pageWidth, offsetHeight, offsetWidth, offsetTop, offsetLeft, rotate, zoom) {
1942
+ const { x, y, width, height } = {
1943
+ x: +(offsetLeft / zoom).toFixed(2),
1944
+ y: +(offsetTop / zoom).toFixed(2),
1945
+ width: +(offsetWidth / zoom).toFixed(2),
1946
+ height: +(offsetHeight / zoom).toFixed(2)
1947
+ };
1948
+ const rectangle = { x, y, width, height };
1949
+ switch (rotate) {
1950
+ case 90:
1951
+ rectangle.width = height;
1952
+ rectangle.height = width;
1953
+ rectangle.x = y;
1954
+ rectangle.y = +(pageWidth / zoom - x - width).toFixed(2);
1955
+ break;
1956
+ case 180:
1957
+ rectangle.x = +(pageWidth / zoom - x - width).toFixed(2);
1958
+ rectangle.y = +(pageHeight / zoom - y - height).toFixed(2);
1959
+ break;
1960
+ case 270:
1961
+ rectangle.width = height;
1962
+ rectangle.height = width;
1963
+ rectangle.x = +(pageHeight / zoom - y - height).toFixed(2);
1964
+ rectangle.y = x;
1965
+ break;
1966
+ }
1967
+ return rectangle;
1714
1968
  }
1715
- changePageNumber(numPages) {
1716
- this.pdfViewer.currentPageNumber += numPages;
1969
+ resetHighlight() {
1970
+ window.getSelection().removeAllRanges();
1971
+ this.toolBarEvents.highlightModeSubject.next(false);
1717
1972
  }
1718
- search(operation) {
1719
- const command = operation.reset ? '' : 'again';
1720
- const data = {
1721
- source: this.pdfViewer,
1722
- type: command,
1723
- query: operation.searchTerm,
1724
- phraseSearch: true,
1725
- caseSensitive: operation.matchCase,
1726
- entireWord: operation.wholeWord,
1727
- highlightAll: operation.highlightAll,
1728
- findPrevious: operation.previous,
1729
- };
1730
- this.pdfViewer.eventBus.dispatch('find', data);
1973
+ /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: HighlightCreateService, deps: [{ token: ToolbarEventService }, { token: i1.Store }], target: i0.ɵɵFactoryTarget.Injectable }); }
1974
+ /** @nocollapse */ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: HighlightCreateService, providedIn: 'root' }); }
1975
+ }
1976
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: HighlightCreateService, decorators: [{
1977
+ type: Injectable,
1978
+ args: [{ providedIn: 'root' }]
1979
+ }], ctorParameters: () => [{ type: ToolbarEventService }, { type: i1.Store }] });
1980
+
1981
+ class HighlightCreateDirective {
1982
+ constructor(element, toolbarEvents, viewerEvents, highlightService, store) {
1983
+ this.element = element;
1984
+ this.toolbarEvents = toolbarEvents;
1985
+ this.viewerEvents = viewerEvents;
1986
+ this.highlightService = highlightService;
1987
+ this.store = store;
1988
+ this.$subscriptions = [];
1731
1989
  }
1732
- clearSearch() {
1733
- this.pdfViewer.eventBus.dispatch('findbarclose', {});
1990
+ ngOnInit() {
1991
+ this.$subscriptions.push(this.store.select(getPages).subscribe((pages) => {
1992
+ if (pages[1]) {
1993
+ this.allPages = pages;
1994
+ }
1995
+ }));
1996
+ this.$subscriptions.push(this.toolbarEvents.highlightModeSubject.pipe(filter(enabled => enabled && !!this.element.nativeElement), debounceTime(100)).subscribe(() => {
1997
+ this.element.nativeElement.focus();
1998
+ }));
1734
1999
  }
1735
- navigateTo(destination) {
1736
- if (destination instanceof Object) {
1737
- if (!destination[1].name.includes('XYZ')) {
1738
- destination[1] = { name: 'XYZ' };
1739
- destination[2] = destination[2] || null;
1740
- destination[3] = destination[3] || null;
2000
+ ngOnDestroy() {
2001
+ this.$subscriptions.forEach(sub => sub.unsubscribe());
2002
+ }
2003
+ onMouseUp(mouseEvent) {
2004
+ let page;
2005
+ let currentElement = mouseEvent.target;
2006
+ while (currentElement.offsetParent) {
2007
+ currentElement = currentElement.offsetParent;
2008
+ if (currentElement.getAttribute) {
2009
+ page = parseInt(currentElement.getAttribute('data-page-number'), 10);
2010
+ if (page) {
2011
+ break;
2012
+ }
1741
2013
  }
1742
- destination[4] = this.zoomValue;
1743
2014
  }
1744
- this.nativeNavigate(destination);
1745
- }
1746
- nativeNavigate(destination) {
1747
- this.pdfViewer.linkService.goToDestination(destination);
2015
+ if (this.toolbarEvents.highlightModeSubject.getValue()) {
2016
+ const rectangles = this.getRectangles(mouseEvent, page);
2017
+ this.viewerEvents.textSelected({ page, rectangles });
2018
+ }
1748
2019
  }
1749
- setZoom(zoomValue) {
1750
- this.pdfViewer.currentScaleValue = this.getZoomValue(zoomValue).toString();
1751
- this.zoomValue = +this.pdfViewer.currentScaleValue;
1752
- this.toolbarEvents.zoomValueSubject.next(this.zoomValue);
2020
+ onKeyboardSelectionConfirmed() {
2021
+ if (this.toolbarEvents.highlightModeSubject.getValue()) {
2022
+ const selection = window.getSelection();
2023
+ if (selection && selection.rangeCount && !selection.isCollapsed) {
2024
+ const page = this.getCurrentPageFromSelection(selection);
2025
+ const rectangles = this.getRectanglesFromSelection(selection, page);
2026
+ if (rectangles && rectangles.length > 0) {
2027
+ this.viewerEvents.textSelected({ page, rectangles });
2028
+ }
2029
+ }
2030
+ }
1753
2031
  }
1754
- stepZoom(zoomValue) {
1755
- this.pdfViewer.currentScaleValue = this.getZoomValue((+this.pdfViewer.currentScaleValue) + zoomValue).toString();
1756
- this.zoomValue = +this.pdfViewer.currentScaleValue;
1757
- this.toolbarEvents.zoomValueSubject.next(this.zoomValue);
2032
+ getCurrentPageFromSelection(selection) {
2033
+ const range = selection.getRangeAt(0);
2034
+ let currentElement = range.startContainer;
2035
+ if (currentElement.nodeType === Node.TEXT_NODE) {
2036
+ currentElement = currentElement.parentElement;
2037
+ }
2038
+ while (currentElement && currentElement.offsetParent) {
2039
+ currentElement = currentElement.offsetParent;
2040
+ if (currentElement.getAttribute) {
2041
+ const page = parseInt(currentElement.getAttribute('data-page-number'), 10);
2042
+ if (page) {
2043
+ return page;
2044
+ }
2045
+ }
2046
+ }
2047
+ return 1;
1758
2048
  }
1759
- getZoomValue(zoomValue) {
1760
- if (isNaN(zoomValue)) {
1761
- return this.zoomValue;
2049
+ getRectanglesFromSelection(selection, page) {
2050
+ if (!this.allPages || !this.allPages[page]) {
2051
+ return [];
1762
2052
  }
1763
- if (zoomValue > 5) {
1764
- return 5;
2053
+ this.setPageProperties(page);
2054
+ const range = selection.getRangeAt(0).cloneRange();
2055
+ const clientRects = range.getClientRects();
2056
+ if (!clientRects || clientRects.length === 0) {
2057
+ return [];
1765
2058
  }
1766
- if (zoomValue < 0.1) {
1767
- return 0.1;
2059
+ let textLayerElement = range.startContainer;
2060
+ if (textLayerElement.nodeType === Node.TEXT_NODE) {
2061
+ textLayerElement = textLayerElement.parentElement;
1768
2062
  }
1769
- return +zoomValue.toFixed(2);
1770
- }
1771
- rotate(rotation) {
1772
- return this.pdfViewer.pagesRotation = (this.pdfViewer.pagesRotation + rotation) % 360;
2063
+ const textLayer = textLayerElement.closest('.textLayer');
2064
+ if (!textLayer) {
2065
+ return [];
2066
+ }
2067
+ this.removeEnhancedTextModeStyling(textLayerElement);
2068
+ return this.processClientRects(clientRects, textLayer);
1773
2069
  }
1774
- resetRotation(rotation) {
1775
- return this.pdfViewer.pagesRotation = rotation;
2070
+ onPdfViewerClick(event) {
2071
+ this.store.dispatch(new SelectedAnnotation({
2072
+ annotationId: '',
2073
+ selected: false,
2074
+ editable: false,
2075
+ }));
2076
+ this.viewerEvents.clearCtxToolbar();
1776
2077
  }
1777
- getNormalisedPagesRotation() {
1778
- return this.pdfViewer.pagesRotation;
2078
+ getRectangles(event, page) {
2079
+ this.setPageProperties(page);
2080
+ const selection = window.getSelection();
2081
+ if (selection) {
2082
+ const localElement = event.target;
2083
+ this.removeEnhancedTextModeStyling(localElement);
2084
+ if (selection.rangeCount && !selection.isCollapsed) {
2085
+ const range = selection.getRangeAt(0).cloneRange();
2086
+ const clientRects = range.getClientRects();
2087
+ if (clientRects) {
2088
+ const textLayer = localElement.closest(".textLayer");
2089
+ return this.processClientRects(clientRects, textLayer);
2090
+ }
2091
+ }
2092
+ }
1779
2093
  }
1780
- getCurrentPDFZoomValue() {
1781
- return +this.pdfViewer.currentScaleValue;
2094
+ createTextRectangle(rect, parentRect) {
2095
+ const height = rect.bottom - rect.top;
2096
+ const width = rect.right - rect.left;
2097
+ const top = rect.top - parentRect.top;
2098
+ const left = rect.left - parentRect.left;
2099
+ let rectangle = this.highlightService.applyRotation(this.pageHeight, this.pageWidth, height, width, top, left, this.rotate, this.zoom);
2100
+ rectangle = { id: v4(), ...rectangle };
2101
+ return rectangle;
1782
2102
  }
1783
- setCurrentPDFTitle(title) {
1784
- this.documentTitle = title;
2103
+ removeEnhancedTextModeStyling(element) {
2104
+ if (element.parentElement.children) {
2105
+ for (let i = 0; i < element.parentElement.children.length; i++) {
2106
+ const child = element.parentElement.children[i];
2107
+ child.style.padding = '0';
2108
+ // regex will be targeting the translate style in string
2109
+ // e.g. scaleX(0.969918) translateX(-110.684px) translateY(-105.274px) will become scaleX(0.969918)
2110
+ const translateCSSRegex = /translate[XYZ]\(-?\d*(\.\d+)?(px)?\)/g;
2111
+ child.style.transform = child.style.transform.replace(translateCSSRegex, '').trim();
2112
+ }
2113
+ }
1785
2114
  }
1786
- getCurrentPDFTitle() {
1787
- return this.documentTitle;
2115
+ setPageProperties(page) {
2116
+ this.pageHeight = this.allPages[page].styles.height;
2117
+ this.pageWidth = this.allPages[page].styles.width;
2118
+ this.zoom = parseFloat(this.allPages[page].scaleRotation.scale);
2119
+ this.rotate = parseInt(this.allPages[page].scaleRotation.rotation, 10);
1788
2120
  }
1789
- }
1790
-
1791
- class IcpEventService {
1792
- constructor() {
1793
- this.enabled = new BehaviorSubject(false);
1794
- this.sessionLaunch = new Subject();
1795
- this.becomingPresenter = new Subject();
1796
- this.stoppingPresenting = new Subject();
1797
- this.leavingSession = new BehaviorSubject(false);
1798
- this.sessionExitConfirmed = new Subject();
1799
- this.participantsListVisible = new BehaviorSubject(false);
1800
- this.launchSession = () => {
1801
- this.sessionLaunch.next();
1802
- };
1803
- this.enable = () => {
1804
- this.enabled.next(true);
1805
- this.launchSession();
1806
- };
1807
- this.becomePresenter = () => {
1808
- this.becomingPresenter.next();
1809
- };
1810
- this.stopPresenting = () => {
1811
- this.stoppingPresenting.next();
1812
- };
1813
- this.leaveSession = () => {
1814
- this.leavingSession.next(true);
1815
- };
1816
- this.confirmExit = () => {
1817
- this.sessionExitConfirmed.next();
1818
- this.participantsListVisible.next(false);
1819
- this.enabled.next(false);
1820
- };
2121
+ processClientRects(clientRects, textLayer) {
2122
+ const parentRect = HtmlTemplatesHelper.getAdjustedBoundingRect(textLayer);
2123
+ const selectionRectangles = [];
2124
+ for (let i = 0; i < clientRects.length; i++) {
2125
+ const selectionRectangle = this.createTextRectangle(clientRects[i], parentRect);
2126
+ const findSelectionRectangle = selectionRectangles.find((rect) => rect.width === selectionRectangle.width && rect.x === selectionRectangle.x);
2127
+ if (!findSelectionRectangle) {
2128
+ selectionRectangles.push(selectionRectangle);
2129
+ }
2130
+ }
2131
+ return selectionRectangles;
1821
2132
  }
1822
- /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: IcpEventService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1823
- /** @nocollapse */ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: IcpEventService, providedIn: 'root' }); }
2133
+ /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: HighlightCreateDirective, deps: [{ token: i0.ElementRef }, { token: ToolbarEventService }, { token: ViewerEventService }, { token: HighlightCreateService }, { token: i1.Store }], target: i0.ɵɵFactoryTarget.Directive }); }
2134
+ /** @nocollapse */ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.13", type: HighlightCreateDirective, selector: "[mvCreateTextHighlight]", host: { listeners: { "mouseup": "onMouseUp($event)", "mousedown": "onPdfViewerClick($event)" } }, ngImport: i0 }); }
1824
2135
  }
1825
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: IcpEventService, decorators: [{
1826
- type: Injectable,
2136
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: HighlightCreateDirective, decorators: [{
2137
+ type: Directive,
1827
2138
  args: [{
1828
- providedIn: 'root'
2139
+ selector: '[mvCreateTextHighlight]'
1829
2140
  }]
1830
- }], ctorParameters: () => [] });
2141
+ }], ctorParameters: () => [{ type: i0.ElementRef }, { type: ToolbarEventService }, { type: ViewerEventService }, { type: HighlightCreateService }, { type: i1.Store }], propDecorators: { onMouseUp: [{
2142
+ type: HostListener,
2143
+ args: ['mouseup', ['$event']]
2144
+ }], onPdfViewerClick: [{
2145
+ type: HostListener,
2146
+ args: ['mousedown', ['$event']]
2147
+ }] } });
1831
2148
 
1832
- var SearchType;
1833
- (function (SearchType) {
1834
- SearchType["Redact"] = "Redact";
1835
- SearchType["Highlight"] = "Highlight";
1836
- })(SearchType || (SearchType = {}));
1837
- class ToolbarEventService {
1838
- constructor(icpEventService) {
1839
- this.icpEventService = icpEventService;
1840
- this.highlightModeSubject = new BehaviorSubject(false);
1841
- this.highlightToolbarSubject = new BehaviorSubject(false);
1842
- this.drawModeSubject = new BehaviorSubject(false);
1843
- this.rotateSubject = new Subject();
1844
- this.searchSubject = new Subject();
1845
- this.searchResultsCountSubject = new Subject();
1846
- this.zoomSubject = new Subject();
1847
- this.stepZoomSubject = new Subject();
1848
- this.zoomValueSubject = new BehaviorSubject(1);
1849
- this.pageCountSubject = new Subject();
1850
- this.printSubject = new Subject();
1851
- this.downloadSubject = new Subject();
1852
- this.setCurrentPageSubject = new Subject();
1853
- this.setCurrentPageInputValueSubject = new Subject();
1854
- this.changePageByDeltaSubject = new Subject();
1855
- this.showCommentSummary = new BehaviorSubject(false);
1856
- this.grabNDrag = new BehaviorSubject(false);
1857
- this.saveRotationSubject = new Subject();
1858
- this.redactionMode = new BehaviorSubject(false);
1859
- this.redactionPreview = new Subject();
1860
- this.applyRedactToDocument = new Subject();
1861
- this.clearAllRedactMarkers = new Subject();
1862
- this.redactWholePage = new Subject();
1863
- this.redactionSerachSubject = new Subject();
1864
- this.redactAllInProgressSubject = new BehaviorSubject(false);
1865
- this.openRedactionSearch = new BehaviorSubject(null);
1866
- this.sidebarOpen = new BehaviorSubject(false);
1867
- this.sidebarOutlineView = new BehaviorSubject(true);
1868
- this.searchBarHidden = new BehaviorSubject(true);
1869
- this.commentsPanelVisible = new BehaviorSubject(false);
2149
+ pdfjs.GlobalWorkerOptions.workerSrc = '/assets/build/pdf.worker.min.js';
2150
+ /**
2151
+ * Values of the state field returned by the find events
2152
+ */
2153
+ var FindState;
2154
+ (function (FindState) {
2155
+ FindState[FindState["FOUND"] = 0] = "FOUND";
2156
+ FindState[FindState["NOT_FOUND"] = 1] = "NOT_FOUND";
2157
+ FindState[FindState["WRAPPED"] = 2] = "WRAPPED";
2158
+ FindState[FindState["PENDING"] = 3] = "PENDING";
2159
+ })(FindState || (FindState = {}));
2160
+ class PdfJsWrapper {
2161
+ constructor(pdfViewer, downloadManager, toolbarEvents, documentLoadInit, documentLoadProgress, documentLoaded, outlineLoaded, documentLoadFailed, pageRendered, positionUpdated) {
2162
+ this.pdfViewer = pdfViewer;
2163
+ this.downloadManager = downloadManager;
2164
+ this.toolbarEvents = toolbarEvents;
2165
+ this.documentLoadInit = documentLoadInit;
2166
+ this.documentLoadProgress = documentLoadProgress;
2167
+ this.documentLoaded = documentLoaded;
2168
+ this.outlineLoaded = outlineLoaded;
2169
+ this.documentLoadFailed = documentLoadFailed;
2170
+ this.pageRendered = pageRendered;
2171
+ this.positionUpdated = positionUpdated;
2172
+ this.pdfViewer.eventBus.on('updateviewarea', e => positionUpdated.next(e));
2173
+ this.pdfViewer.eventBus.on('pagechanging', e => this.toolbarEvents.setCurrentPageInputValueSubject.next(e.pageNumber));
2174
+ this.pdfViewer.eventBus.on('pagechanging', e => this.drawMissingPages(e));
2175
+ this.pdfViewer.eventBus.on('pagesinit', () => this.pdfViewer.currentScaleValue = '1');
2176
+ this.pdfViewer.eventBus.on('pagerendered', e => { }); // not used left for future convenience
2177
+ this.pdfViewer.eventBus.on('pagesloaded', (e) => this.emitDocumentInfo(e));
2178
+ this.pdfViewer.eventBus.on('scalechanging', (e) => this.emitDocumentInfo(e));
2179
+ this.pdfViewer.eventBus.on('rotationchanging', (e) => this.emitDocumentInfo(e));
2180
+ this.pdfViewer.eventBus.on('updatefindcontrolstate', event => {
2181
+ this.sendSearchDetails(event);
2182
+ });
2183
+ this.pdfViewer.eventBus.on('updatefindmatchescount', event => {
2184
+ const result = { ...event.matchesCount, isPrevious: event?.source?.state?.findPrevious };
2185
+ this.toolbarEvents.searchResultsCountSubject.next(result);
2186
+ });
2187
+ this.zoomValue = 1;
2188
+ this.redactionPages = [];
2189
+ // Subscribe to redactionMode changes and run a function when it changes
2190
+ this.toolbarEvents.redactionMode.subscribe((redactionModeValue) => {
2191
+ this.onRedactionModeChanged(redactionModeValue);
2192
+ });
1870
2193
  }
1871
- /**
1872
- * Reset the stateful behaviour subjects
1873
- */
1874
- reset() {
1875
- this.setCurrentPageSubject.next(1);
1876
- this.zoomValueSubject.next(1);
1877
- this.highlightModeSubject.next(false);
1878
- this.highlightToolbarSubject.next(false);
1879
- this.drawModeSubject.next(false);
1880
- this.showCommentSummary.next(false);
1881
- this.grabNDrag.next(false);
2194
+ sendSearchDetails(event) {
2195
+ if (event.state !== FindState.PENDING) {
2196
+ const result = { ...event.matchesCount, isPrevious: event?.source?.state?.findPrevious };
2197
+ this.toolbarEvents.searchResultsCountSubject.next(result);
2198
+ if (event?.source?.selected?.pageIdx !== -1 && event.matchesCount.total > 0) {
2199
+ this.toolbarEvents.redactionSerachSubject.next({
2200
+ page: event?.source?.selected?.pageIdx,
2201
+ matchedIndex: event?.source?.selected?.matchIdx,
2202
+ matchesCount: event.matchesCount.total
2203
+ });
2204
+ }
2205
+ }
1882
2206
  }
1883
- // Function to inform Observers that highlightMode has been enabled
1884
- toggleHighlightMode() {
1885
- // Highlight and Draw states are mutually exclusive
1886
- if (this.highlightModeSubject.getValue() === false) {
1887
- this.drawModeSubject.next(false);
1888
- this.grabNDrag.next(false);
1889
- this.highlightModeSubject.next(true);
2207
+ // in the event a user fast scrolls or navigates to a specific page,
2208
+ // we need to render the missing pages so redaction box is in right place
2209
+ drawMissingPages(e) {
2210
+ const redactionMode = this.toolbarEvents.redactionMode.getValue();
2211
+ const { pageNumber, previous: previousPageNumber } = e;
2212
+ if (!previousPageNumber || pageNumber < previousPageNumber || Math.abs(pageNumber - previousPageNumber) <= 1) {
2213
+ return;
2214
+ }
2215
+ const start = previousPageNumber + 1;
2216
+ const end = pageNumber;
2217
+ // if the redaction mode is on render the pages now
2218
+ if (redactionMode) {
2219
+ for (let i = start; i < end; i++) {
2220
+ const page = this.pdfViewer._pages[i - 1];
2221
+ if (page && !page.renderingState) {
2222
+ page.draw();
2223
+ }
2224
+ }
1890
2225
  }
1891
2226
  else {
1892
- this.highlightModeSubject.next(false);
2227
+ // keep track of pages as if a user skips to a page we need to render all the missing pages
2228
+ console.log('Adding redaction pages to queue:', start, end);
2229
+ this.redactionPages.push({ start, end });
1893
2230
  }
1894
2231
  }
1895
- // Function to inform Observers that ToggleMode has been enabled
1896
- toggleDrawMode() {
1897
- if (this.drawModeSubject.getValue() === false) {
1898
- this.highlightModeSubject.next(false);
1899
- this.grabNDrag.next(false);
1900
- this.drawModeSubject.next(true);
1901
- }
1902
- else {
1903
- this.drawModeSubject.next(false);
2232
+ onRedactionModeChanged(redactionMode) {
2233
+ if (redactionMode && this.redactionPages.length) {
2234
+ this.redactionPages.forEach(({ start, end }) => {
2235
+ console.log('Drawing redaction pages from queue:', start, end);
2236
+ for (let i = start; i < end; i++) {
2237
+ const page = this.pdfViewer._pages[i - 1];
2238
+ if (page && !page.renderingState) {
2239
+ page.draw();
2240
+ }
2241
+ }
2242
+ });
2243
+ this.redactionPages = [];
1904
2244
  }
1905
2245
  }
1906
- toggleHighlightToolbar() {
1907
- this.highlightToolbarSubject.next(!this.highlightToolbarSubject.getValue());
1908
- }
1909
- rotate(angle) {
1910
- this.rotateSubject.next(angle);
1911
- }
1912
- search(phrase) {
1913
- this.searchSubject.next(phrase);
1914
- }
1915
- getSearchResultsCount() {
1916
- return this.searchResultsCountSubject.asObservable();
2246
+ emitDocumentInfo(e) {
2247
+ const allPages = [...this.pdfViewer._pages].map(page => {
2248
+ return {
2249
+ div: page.div,
2250
+ scale: page.scale,
2251
+ rotation: page.rotation,
2252
+ id: page.id,
2253
+ viewportScale: page.viewport.scale
2254
+ };
2255
+ });
2256
+ this.pageRendered.next(allPages);
1917
2257
  }
1918
- zoom(value) {
1919
- this.zoomSubject.next(value);
2258
+ async loadDocument(documentUrl) {
2259
+ const loadingTask = this.createLoadingTask(documentUrl);
2260
+ loadingTask.onProgress = ({ loaded, total }) => {
2261
+ this.documentLoadProgress.next({ loaded, total });
2262
+ };
2263
+ this.documentLoadInit.next(documentUrl);
2264
+ try {
2265
+ const pdfDocument = await loadingTask.promise;
2266
+ this.documentLoaded.next(pdfDocument);
2267
+ this.toolbarEvents.pageCountSubject.next(pdfDocument.numPages);
2268
+ this.pdfViewer.setDocument(pdfDocument);
2269
+ if (this.pdfViewer.linkService instanceof PDFLinkService) {
2270
+ const linkservice = this.pdfViewer.linkService;
2271
+ linkservice.setDocument(pdfDocument, null);
2272
+ }
2273
+ const outlineNode = await pdfDocument.getOutline();
2274
+ const outline = outlineNode ? outlineNode.map(x => {
2275
+ return {
2276
+ bold: x.bold,
2277
+ color: x.color,
2278
+ count: x.count,
2279
+ dest: x.dest,
2280
+ italic: x.italic,
2281
+ items: x.items,
2282
+ newWindow: x.newWindow,
2283
+ title: x.title,
2284
+ unsafeUrl: x.unsafeUrl,
2285
+ url: x.url
2286
+ };
2287
+ }) : null;
2288
+ if (outline) {
2289
+ await this.setOutlinePageNumbers(pdfDocument, outline);
2290
+ }
2291
+ this.documentOutline = outline;
2292
+ this.outlineLoaded.next(this.documentOutline);
2293
+ const pdfMetaData = await pdfDocument.getMetadata();
2294
+ this.setCurrentPDFTitle(pdfMetaData.info?.Title);
2295
+ }
2296
+ catch (e) {
2297
+ this.documentLoadFailed.next(e);
2298
+ }
1920
2299
  }
1921
- stepZoom(value) {
1922
- this.stepZoomSubject.next(value);
2300
+ createLoadingTask(documentUrl) {
2301
+ return pdfjs.getDocument({
2302
+ url: documentUrl,
2303
+ cMapUrl: 'assets/minified/cmaps',
2304
+ cMapPacked: true,
2305
+ withCredentials: true,
2306
+ isEvalSupported: false
2307
+ });
1923
2308
  }
1924
- getZoomValue() {
1925
- return this.zoomValueSubject.asObservable();
2309
+ async setOutlinePageNumbers(pdfDocument, outlineArray) {
2310
+ outlineArray.forEach(async (outline) => {
2311
+ await this.setNestedOutlinePageNumbers(pdfDocument, outline);
2312
+ });
1926
2313
  }
1927
- getPageCount() {
1928
- return this.pageCountSubject.asObservable();
2314
+ async setNestedOutlinePageNumbers(pdfDocument, outline) {
2315
+ outline.pageNumber = await this.getOutlinePageNumber(pdfDocument, outline);
2316
+ outline.items.forEach(async (outlineItem) => {
2317
+ outlineItem.pageNumber = await this.getOutlinePageNumber(pdfDocument, outlineItem);
2318
+ this.setNestedOutlinePageNumbers(pdfDocument, outlineItem);
2319
+ });
1929
2320
  }
1930
- print() {
1931
- this.printSubject.next();
2321
+ async getOutlinePageNumber(pdfDocument, outline) {
2322
+ const dest = outline.dest;
2323
+ const pageIndex = await pdfDocument.getPageIndex(dest[0]);
2324
+ return Number(pageIndex) + 1;
1932
2325
  }
1933
- download() {
1934
- this.downloadSubject.next();
2326
+ downloadFile(url, filename) {
2327
+ this.downloadManager.download(null, url, filename);
1935
2328
  }
1936
- setPage(value) {
1937
- this.setCurrentPageSubject.next(value);
2329
+ setPageNumber(pageNumber) {
2330
+ this.pdfViewer.currentPageNumber = pageNumber;
1938
2331
  }
1939
- incrementPage(value) {
1940
- this.changePageByDeltaSubject.next(value);
2332
+ getPageNumber() {
2333
+ return this.pdfViewer.currentPageNumber;
1941
2334
  }
1942
- getCurrentPageNumber() {
1943
- return this.setCurrentPageInputValueSubject.asObservable();
2335
+ changePageNumber(numPages) {
2336
+ this.pdfViewer.currentPageNumber += numPages;
1944
2337
  }
1945
- getShowCommentSummary() {
1946
- return this.showCommentSummary.asObservable();
2338
+ search(operation) {
2339
+ const command = operation.reset ? '' : 'again';
2340
+ const data = {
2341
+ source: this.pdfViewer,
2342
+ type: command,
2343
+ query: operation.searchTerm,
2344
+ phraseSearch: true,
2345
+ caseSensitive: operation.matchCase,
2346
+ entireWord: operation.wholeWord,
2347
+ highlightAll: operation.highlightAll,
2348
+ findPrevious: operation.previous,
2349
+ };
2350
+ this.pdfViewer.eventBus.dispatch('find', data);
1947
2351
  }
1948
- toggleCommentsSummary(value) {
1949
- this.showCommentSummary.next(value);
2352
+ clearSearch() {
2353
+ this.pdfViewer.eventBus.dispatch('findbarclose', {});
1950
2354
  }
1951
- saveRotation() {
1952
- this.saveRotationSubject.next();
2355
+ navigateTo(destination) {
2356
+ if (destination instanceof Object) {
2357
+ if (!destination[1].name.includes('XYZ')) {
2358
+ destination[1] = { name: 'XYZ' };
2359
+ destination[2] = destination[2] || null;
2360
+ destination[3] = destination[3] || null;
2361
+ }
2362
+ destination[4] = this.zoomValue;
2363
+ }
2364
+ this.nativeNavigate(destination);
1953
2365
  }
1954
- toggleGrabNDrag() {
1955
- this.grabNDrag.next(!this.grabNDrag.getValue());
2366
+ nativeNavigate(destination) {
2367
+ this.pdfViewer.linkService.goToDestination(destination);
1956
2368
  }
1957
- toggleSideBar(toggle) {
1958
- this.sidebarOpen.next(toggle);
2369
+ setZoom(zoomValue) {
2370
+ this.pdfViewer.currentScaleValue = this.getZoomValue(zoomValue).toString();
2371
+ this.zoomValue = +this.pdfViewer.currentScaleValue;
2372
+ this.toolbarEvents.zoomValueSubject.next(this.zoomValue);
1959
2373
  }
1960
- toggleSideBarView(toggle) {
1961
- this.sidebarOutlineView.next(toggle);
2374
+ stepZoom(zoomValue) {
2375
+ this.pdfViewer.currentScaleValue = this.getZoomValue((+this.pdfViewer.currentScaleValue) + zoomValue).toString();
2376
+ this.zoomValue = +this.pdfViewer.currentScaleValue;
2377
+ this.toolbarEvents.zoomValueSubject.next(this.zoomValue);
1962
2378
  }
1963
- toggleRedactionMode() {
1964
- if (this.redactionMode.getValue() === false) {
1965
- this.drawModeSubject.next(false);
1966
- this.grabNDrag.next(false);
1967
- this.redactionMode.next(true);
2379
+ getZoomValue(zoomValue) {
2380
+ if (isNaN(zoomValue)) {
2381
+ return this.zoomValue;
1968
2382
  }
1969
- else {
1970
- this.redactionMode.next(false);
2383
+ if (zoomValue > 5) {
2384
+ return 5;
1971
2385
  }
1972
- this.openRedactionSearch.next({ modeType: SearchType.Redact, isOpen: false });
2386
+ if (zoomValue < 0.1) {
2387
+ return 0.1;
2388
+ }
2389
+ return +zoomValue.toFixed(2);
1973
2390
  }
1974
- toggleRedactionPreview(viewMode) {
1975
- this.redactionPreview.next(viewMode);
2391
+ rotate(rotation) {
2392
+ return this.pdfViewer.pagesRotation = (this.pdfViewer.pagesRotation + rotation) % 360;
1976
2393
  }
1977
- unmarkAll() {
1978
- this.clearAllRedactMarkers.next();
2394
+ resetRotation(rotation) {
2395
+ return this.pdfViewer.pagesRotation = rotation;
1979
2396
  }
1980
- applyRedactionToDocument() {
1981
- this.applyRedactToDocument.next();
2397
+ getNormalisedPagesRotation() {
2398
+ return this.pdfViewer.pagesRotation;
1982
2399
  }
1983
- redactPage() {
1984
- this.redactWholePage.next();
2400
+ getCurrentPDFZoomValue() {
2401
+ return +this.pdfViewer.currentScaleValue;
1985
2402
  }
1986
- toggleCommentsPanel(isVisible) {
1987
- if (isVisible) {
1988
- this.toggleParticipantsList(!isVisible);
1989
- }
1990
- this.commentsPanelVisible.next(isVisible);
2403
+ setCurrentPDFTitle(title) {
2404
+ this.documentTitle = title;
1991
2405
  }
1992
- toggleParticipantsList(isVisible) {
1993
- if (isVisible) {
1994
- this.toggleCommentsPanel(!isVisible);
1995
- }
1996
- this.icpEventService.participantsListVisible.next(isVisible);
2406
+ getCurrentPDFTitle() {
2407
+ return this.documentTitle;
1997
2408
  }
1998
- /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ToolbarEventService, deps: [{ token: IcpEventService }], target: i0.ɵɵFactoryTarget.Injectable }); }
1999
- /** @nocollapse */ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ToolbarEventService, providedIn: 'root' }); }
2000
2409
  }
2001
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ToolbarEventService, decorators: [{
2002
- type: Injectable,
2003
- args: [{ providedIn: 'root' }]
2004
- }], ctorParameters: () => [{ type: IcpEventService }] });
2005
2410
 
2006
2411
  class PdfJsWrapperFactory {
2007
2412
  constructor(toolbarEvents) {
@@ -2046,56 +2451,25 @@ class PrintService {
2046
2451
  }
2047
2452
  printElementNatively(element, width, height) {
2048
2453
  const printWindow = window.open('', '', `left=0,top=0,width=${width},height=${height},toolbar=0,scrollbars=0,status=0`);
2049
- const documentHead = document.head;
2050
- printWindow.document.body.appendChild(documentHead.cloneNode(true));
2051
- printWindow.document.body.appendChild(element.cloneNode(true));
2052
- printWindow.document.close();
2053
- printWindow.focus();
2054
- printWindow.print();
2055
- setTimeout((printer) => {
2056
- printer.close();
2057
- }, 1000, printWindow);
2058
- }
2059
- /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: PrintService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2060
- /** @nocollapse */ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: PrintService, providedIn: 'root' }); }
2061
- }
2062
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: PrintService, decorators: [{
2063
- type: Injectable,
2064
- args: [{
2065
- providedIn: 'root'
2066
- }]
2067
- }] });
2068
-
2069
- class ViewerEventService {
2070
- constructor() {
2071
- this.textHighlight = new Subject();
2072
- this.boxHighlight = new Subject();
2073
- this.ctxToolbarCleared = new Subject();
2074
- this.navigationEvent = new Subject();
2075
- this.navigationEventICP = new Subject();
2076
- }
2077
- textSelected(selectionData) {
2078
- this.textHighlight.next(selectionData);
2079
- }
2080
- boxSelected(selectionData) {
2081
- this.boxHighlight.next(selectionData);
2082
- }
2083
- clearCtxToolbar() {
2084
- this.ctxToolbarCleared.next();
2085
- }
2086
- goToDestination(destination) {
2087
- this.navigationEvent.next(destination);
2088
- }
2089
- goToDestinationICP(destination) {
2090
- this.navigationEventICP.next(destination);
2454
+ const documentHead = document.head;
2455
+ printWindow.document.body.appendChild(documentHead.cloneNode(true));
2456
+ printWindow.document.body.appendChild(element.cloneNode(true));
2457
+ printWindow.document.close();
2458
+ printWindow.focus();
2459
+ printWindow.print();
2460
+ setTimeout((printer) => {
2461
+ printer.close();
2462
+ }, 1000, printWindow);
2091
2463
  }
2092
- /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ViewerEventService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2093
- /** @nocollapse */ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ViewerEventService, providedIn: 'root' }); }
2464
+ /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: PrintService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2465
+ /** @nocollapse */ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: PrintService, providedIn: 'root' }); }
2094
2466
  }
2095
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ViewerEventService, decorators: [{
2467
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: PrintService, decorators: [{
2096
2468
  type: Injectable,
2097
- args: [{ providedIn: 'root' }]
2098
- }], ctorParameters: () => [] });
2469
+ args: [{
2470
+ providedIn: 'root'
2471
+ }]
2472
+ }] });
2099
2473
 
2100
2474
  const getIcpState = createSelector(getMVState, (state) => state.icp);
2101
2475
  const getIcpSession = createSelector(getIcpState, getIcpSession$1);
@@ -2428,7 +2802,7 @@ class IcpService {
2428
2802
  this.followerSubscriptions = followerSubscriptions;
2429
2803
  this.store = store;
2430
2804
  this.icpEventService = icpEventService;
2431
- this.subscription = this.store.pipe(select(getCaseId), filter(value => !!value)).subscribe(caseId => {
2805
+ this.subscription = this.store.pipe(select(getCaseId), filter$1(value => !!value)).subscribe(caseId => {
2432
2806
  this.caseId = caseId;
2433
2807
  });
2434
2808
  this.subscription.add(this.store.pipe(select(getDocumentId)).subscribe(docId => this.documentId = docId));
@@ -2444,7 +2818,7 @@ class IcpService {
2444
2818
  }
2445
2819
  launchSession() {
2446
2820
  this.store.dispatch(new LoadIcpSession({ caseId: this.caseId, documentId: this.documentId }));
2447
- this.subscription.add(this.store.pipe(select(getIcpSession), filter(value => !!value && Object.keys(value).length > 1), take(1)).subscribe(() => { this.setUpSessionSubscriptions(); }));
2821
+ this.subscription.add(this.store.pipe(select(getIcpSession), filter$1(value => !!value && Object.keys(value).length > 1), take(1)).subscribe(() => { this.setUpSessionSubscriptions(); }));
2448
2822
  }
2449
2823
  setUpSessionSubscriptions() {
2450
2824
  this.sessionSubscription = this.icpEventService.becomingPresenter.subscribe(() => this.becomePresenter());
@@ -2565,241 +2939,35 @@ const defaultPdfOptions = {
2565
2939
  showSearchBar: true,
2566
2940
  showSidebar: true,
2567
2941
  showGrabNDragButton: true,
2568
- showCommentSummary: true,
2569
- showPresentationMode: true,
2570
- showRedact: true
2571
- };
2572
- /**
2573
- * Default toolbar state for the image viewer
2574
- */
2575
- const defaultImageOptions = {
2576
- showPrint: true,
2577
- showDownload: true,
2578
- showZoom: true,
2579
- showRotate: true,
2580
- showGrabNDragButton: true,
2581
- showCommentSummary: true,
2582
- showRedact: true
2583
- };
2584
- /**
2585
- * Default toolbar state for multimedia
2586
- */
2587
- const defaultMultimediaOptions = {
2588
- showDownload: true
2589
- };
2590
- /**
2591
- * Default toolbar state for unsupported media
2592
- */
2593
- const defaultUnsupportedOptions = {
2594
- showDownload: true,
2595
- showPrint: true
2596
- };
2597
-
2598
- /**
2599
- * Helper Class
2600
- * Used for dynamic templates manipulation
2601
- * */
2602
- class HtmlTemplatesHelper {
2603
- static setDescribedBy(errorMessage, config) {
2604
- if (!errorMessage) {
2605
- return config.hint ? `${config.id}-hint` : null;
2606
- }
2607
- else if (errorMessage && errorMessage.isInvalid) {
2608
- return config.hint ? `${config.id}-hint ${config.id}-error` : `${config.id}-error`;
2609
- }
2610
- else {
2611
- return config.hint ? `${config.id}-hint` : null;
2612
- }
2613
- }
2614
- static getAdjustedBoundingRect(element, log = true) {
2615
- const viewportX = window.visualViewport.offsetLeft;
2616
- const viewportY = window.visualViewport.offsetTop;
2617
- const viewportScale = window.visualViewport.scale;
2618
- const viewportPageX = window.visualViewport.pageLeft;
2619
- const viewportPageY = window.visualViewport.pageTop;
2620
- if (log && viewportX || viewportY || (viewportScale != 1) || viewportPageX || viewportPageY) {
2621
- console.log(`Element: ${element.id} Viewport X: ${viewportX}, Y: ${viewportY}, Scale: ${viewportScale}, PageX: ${viewportPageX}, PageY: ${viewportPageY}`);
2622
- }
2623
- return element.getBoundingClientRect();
2624
- }
2625
- }
2626
-
2627
- const getTagsRootState = createSelector(getMVState, (state) => state.tags);
2628
- const getTagEntities = createSelector(getTagsRootState, getTagNameEnt);
2629
- const getTagFilters = createSelector(getTagsRootState, getFilters);
2630
- const getTagFiltered = createSelector(getTagsRootState, getFilteredComments);
2631
- const getFilteredPageEntities = createSelector(getTagsRootState, getFilteredPageEnt);
2632
- const getAllTagsArr = createSelector(getTagEntities, (tagEnt) => Object.keys(tagEnt).map(key => {
2633
- return {
2634
- key,
2635
- length: Object.keys(tagEnt[key]).length
2636
- };
2637
- }));
2638
-
2639
- const getAnnotationsSetState = createSelector(getMVState, (state) => state.annotations);
2640
- const getAnnotationEntities = createSelector(getAnnotationsSetState, getAnnoEnt);
2641
- const getSet = createSelector(getAnnotationsSetState, getAnnoSet);
2642
- const getDocumentIdSetId = createSelector(getSet, (annoSet) => {
2643
- return {
2644
- documentId: annoSet.documentId,
2645
- annotationSetId: annoSet.id
2646
- };
2647
- });
2648
- const getAnnotationSet = createSelector(getAnnotationEntities, getSet, (entities, set) => {
2649
- return {
2650
- ...set,
2651
- annotations: Object.keys(entities).map(key => entities[key])
2652
- };
2653
- });
2654
- const getSelectedAnnotation = createSelector(getAnnotationsSetState, getSelectedAnno);
2655
- const getCommentEntities = createSelector(getAnnotationsSetState, getCommentEnts);
2656
- const getPageEntities = createSelector(getAnnotationsSetState, getAnnoPageEnt);
2657
- const getComponentSearchQueries = createSelector(getAnnotationsSetState, commentSearchQ);
2658
- const getComponentSearchText = createSelector(getComponentSearchQueries, (queries) => queries.commentSearch);
2659
- const getCommentSummaryFilters = createSelector(getAnnotationsSetState, getSummaryFilters);
2660
- const getAnnoPerPage = createSelector(getPages, getPageEntities, getFilteredPageEntities, (pages, pageEnt, filteredPageEnt) => {
2661
- const isFiltered = !!Object.keys(filteredPageEnt).length;
2662
- const entities = isFiltered ? filteredPageEnt : pageEnt;
2663
- if (pages) {
2664
- const arr = [];
2665
- Object.keys(pages).forEach(key => {
2666
- arr.push({
2667
- anno: entities[key] ? entities[key] : [],
2668
- styles: pages[key].styles
2669
- });
2670
- });
2671
- return arr;
2672
- }
2673
- });
2674
- const getCommentsArray = createSelector(getCommentEntities, getPages, getAnnotationEntities, getTagFiltered, (commentEnts, pages, annoEnts, filtered) => {
2675
- if (commentEnts && annoEnts && pages[1]) {
2676
- const isFiltered = !!Object.keys(filtered).length;
2677
- const com = isFiltered ? filtered : commentEnts;
2678
- return Object.keys(com).map(key => {
2679
- const page = annoEnts[key].page;
2680
- return {
2681
- ...commentEnts[key],
2682
- page,
2683
- pages
2684
- };
2685
- });
2686
- }
2687
- });
2688
- const getCommentSummary = createSelector(getCommentsArray, getCommentSummaryFilters, (commentSummary = [], filters) => {
2689
- const comments = StoreUtils.filterCommentsSummary(commentSummary, filters.filters);
2690
- if (comments.length) {
2691
- const savedComments = comments.filter((comment) => {
2692
- return comment.createdByDetails !== undefined;
2693
- });
2694
- return savedComments.map((comment) => {
2695
- return {
2696
- page: comment.page,
2697
- user: comment.createdByDetails.forename.concat(' ').concat(comment.createdByDetails.surname),
2698
- date: moment(comment.lastModifiedDate).format('D MMMM YYYY'),
2699
- tags: comment.tags,
2700
- comment: comment.content
2701
- };
2702
- });
2703
- }
2704
- return [''];
2705
- });
2706
- const getFilteredAnnotations = createSelector(getAnnotationEntities, getTagFiltered, (annoEnt, filters) => {
2707
- const isFiltered = !!Object.keys(filters).length;
2708
- const anno = isFiltered ? filters : annoEnt;
2709
- return Object.keys(anno).map(key => annoEnt[key])
2710
- .filter(annotation => annotation.comments && annotation.comments.length > 0);
2711
- });
2712
-
2713
- class HighlightCreateService {
2714
- constructor(toolBarEvents, store) {
2715
- this.toolBarEvents = toolBarEvents;
2716
- this.store = store;
2717
- }
2718
- saveAnnotation(rectangles, page) {
2719
- this.store.pipe(select(getDocumentIdSetId), take(1)).subscribe(anoSetDocId => {
2720
- const anno = {
2721
- id: v4(),
2722
- color: 'FFFF00',
2723
- comments: [],
2724
- page: page,
2725
- rectangles: rectangles,
2726
- type: 'highlight',
2727
- ...anoSetDocId,
2728
- createdBy: '',
2729
- createdByDetails: undefined,
2730
- createdDate: moment.utc().tz('Europe/London').toISOString(),
2731
- lastModifiedBy: '',
2732
- lastModifiedByDetails: undefined,
2733
- lastModifiedDate: '',
2734
- tags: [],
2735
- };
2736
- this.store.dispatch(new SaveAnnotation(anno));
2737
- });
2738
- }
2739
- saveAnnotationSet(searchRectangles) {
2740
- this.store.pipe(select(getDocumentIdSetId), take(1)).subscribe(anoSetDocId => {
2741
- const annoSet = searchRectangles.map(x => {
2742
- return {
2743
- id: v4(),
2744
- color: 'FFFF00',
2745
- comments: [],
2746
- page: x.page,
2747
- rectangles: x.rectangles,
2748
- type: 'highlight',
2749
- ...anoSetDocId,
2750
- createdBy: '',
2751
- createdByDetails: undefined,
2752
- createdDate: moment.utc().tz('Europe/London').toISOString(),
2753
- lastModifiedBy: '',
2754
- lastModifiedByDetails: undefined,
2755
- lastModifiedDate: '',
2756
- tags: [],
2757
- };
2758
- });
2759
- this.store.dispatch(new SaveAnnotationSet({
2760
- id: anoSetDocId.annotationSetId, annotations: annoSet, documentId: anoSetDocId.documentId
2761
- }));
2762
- });
2763
- }
2764
- applyRotation(pageHeight, pageWidth, offsetHeight, offsetWidth, offsetTop, offsetLeft, rotate, zoom) {
2765
- const { x, y, width, height } = {
2766
- x: +(offsetLeft / zoom).toFixed(2),
2767
- y: +(offsetTop / zoom).toFixed(2),
2768
- width: +(offsetWidth / zoom).toFixed(2),
2769
- height: +(offsetHeight / zoom).toFixed(2)
2770
- };
2771
- const rectangle = { x, y, width, height };
2772
- switch (rotate) {
2773
- case 90:
2774
- rectangle.width = height;
2775
- rectangle.height = width;
2776
- rectangle.x = y;
2777
- rectangle.y = +(pageWidth / zoom - x - width).toFixed(2);
2778
- break;
2779
- case 180:
2780
- rectangle.x = +(pageWidth / zoom - x - width).toFixed(2);
2781
- rectangle.y = +(pageHeight / zoom - y - height).toFixed(2);
2782
- break;
2783
- case 270:
2784
- rectangle.width = height;
2785
- rectangle.height = width;
2786
- rectangle.x = +(pageHeight / zoom - y - height).toFixed(2);
2787
- rectangle.y = x;
2788
- break;
2789
- }
2790
- return rectangle;
2791
- }
2792
- resetHighlight() {
2793
- window.getSelection().removeAllRanges();
2794
- this.toolBarEvents.highlightModeSubject.next(false);
2795
- }
2796
- /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: HighlightCreateService, deps: [{ token: ToolbarEventService }, { token: i1.Store }], target: i0.ɵɵFactoryTarget.Injectable }); }
2797
- /** @nocollapse */ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: HighlightCreateService, providedIn: 'root' }); }
2798
- }
2799
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: HighlightCreateService, decorators: [{
2800
- type: Injectable,
2801
- args: [{ providedIn: 'root' }]
2802
- }], ctorParameters: () => [{ type: ToolbarEventService }, { type: i1.Store }] });
2942
+ showCommentSummary: true,
2943
+ showPresentationMode: true,
2944
+ showRedact: true
2945
+ };
2946
+ /**
2947
+ * Default toolbar state for the image viewer
2948
+ */
2949
+ const defaultImageOptions = {
2950
+ showPrint: true,
2951
+ showDownload: true,
2952
+ showZoom: true,
2953
+ showRotate: true,
2954
+ showGrabNDragButton: true,
2955
+ showCommentSummary: true,
2956
+ showRedact: true
2957
+ };
2958
+ /**
2959
+ * Default toolbar state for multimedia
2960
+ */
2961
+ const defaultMultimediaOptions = {
2962
+ showDownload: true
2963
+ };
2964
+ /**
2965
+ * Default toolbar state for unsupported media
2966
+ */
2967
+ const defaultUnsupportedOptions = {
2968
+ showDownload: true,
2969
+ showPrint: true
2970
+ };
2803
2971
 
2804
2972
  class RedactionSearchBarComponent {
2805
2973
  constructor(store, toolbarButtons, toolbarEvents, highlightService) {
@@ -3889,6 +4057,148 @@ const getBookmarksPerPage = createSelector(getPages, getBookmarkPages, (pages, p
3889
4057
  }
3890
4058
  });
3891
4059
 
4060
+ class CtxToolbarComponent {
4061
+ constructor() {
4062
+ this.createHighlightEvent = new EventEmitter();
4063
+ this.deleteHighlightEvent = new EventEmitter();
4064
+ this.addOrEditCommentEvent = new EventEmitter();
4065
+ this.createBookmarkEvent = new EventEmitter();
4066
+ this.cancelEvent = new EventEmitter();
4067
+ this.defaultHeight = 70;
4068
+ this.defaultWidth = 300;
4069
+ }
4070
+ ngOnChanges(changes) {
4071
+ this.setRectangle();
4072
+ this.top = this.popupTop();
4073
+ this.left = this.popupLeft();
4074
+ }
4075
+ onEscapeKey(event) {
4076
+ if (this.rectangle) {
4077
+ event.stopPropagation();
4078
+ event.preventDefault();
4079
+ this.rectangle = undefined;
4080
+ this.cancelEvent.emit();
4081
+ }
4082
+ }
4083
+ set rectangles(rectangles) {
4084
+ if (rectangles) {
4085
+ this._rectangles = rectangles;
4086
+ this.setRectangle();
4087
+ }
4088
+ }
4089
+ get rectangles() {
4090
+ return this._rectangles;
4091
+ }
4092
+ createHighlight() {
4093
+ this.createHighlightEvent.emit();
4094
+ this.rectangle = undefined;
4095
+ }
4096
+ deleteHighlight() {
4097
+ this.deleteHighlightEvent.emit();
4098
+ }
4099
+ addOrEditComment() {
4100
+ this.addOrEditCommentEvent.emit();
4101
+ setTimeout(() => {
4102
+ // This hack to wait until the element is rendered seems to be unreliable,
4103
+ if (!location.hash) {
4104
+ document.getElementById('viewerContainer')?.scrollBy(0, 1);
4105
+ }
4106
+ }, 20);
4107
+ }
4108
+ createBookmark() {
4109
+ this.createBookmarkEvent.emit(this.rectangle);
4110
+ this.rectangle = undefined;
4111
+ }
4112
+ setRectangle() {
4113
+ const rectangle = this.rectangles
4114
+ .reduce((prev, current) => prev.y < current.y ? prev : current);
4115
+ this.rectangle = { ...rectangle };
4116
+ switch (this.rotate) {
4117
+ case 90:
4118
+ this.rectangle.width = rectangle.height;
4119
+ this.rectangle.height = rectangle.width;
4120
+ this.rectangle.x = (this.pageWidth / this.zoom) - rectangle.y - rectangle.height;
4121
+ this.rectangle.y = rectangle.x;
4122
+ break;
4123
+ case 180:
4124
+ this.rectangle.x = (this.pageWidth / this.zoom) - rectangle.x - rectangle.width;
4125
+ this.rectangle.y = (this.pageHeight / this.zoom) - rectangle.y - rectangle.height;
4126
+ break;
4127
+ case 270:
4128
+ this.rectangle.width = rectangle.height;
4129
+ this.rectangle.height = rectangle.width;
4130
+ this.rectangle.x = rectangle.y;
4131
+ this.rectangle.y = (this.pageHeight / this.zoom) - rectangle.x - rectangle.width;
4132
+ break;
4133
+ }
4134
+ }
4135
+ popupTop() {
4136
+ const popupTop = this.rectangle.y * this.zoom - this.defaultHeight;
4137
+ return popupTop <= 0 ? this.defaultHeight : popupTop;
4138
+ }
4139
+ popupLeft() {
4140
+ const popupLeft = (this.rectangle.x + (this.rectangle.width / 2)) * this.zoom - (this.defaultWidth / 2);
4141
+ if (popupLeft <= 0) {
4142
+ return 0;
4143
+ }
4144
+ else if (popupLeft >= this.pageWidth - this.defaultWidth) {
4145
+ return this.pageWidth - this.defaultWidth;
4146
+ }
4147
+ else {
4148
+ return popupLeft;
4149
+ }
4150
+ }
4151
+ focusToolbar() {
4152
+ if (this.toolbarContainer?.nativeElement) {
4153
+ const firstButton = this.toolbarContainer.nativeElement.querySelector('button');
4154
+ if (firstButton) {
4155
+ setTimeout(() => firstButton.focus(), 0);
4156
+ return;
4157
+ }
4158
+ }
4159
+ }
4160
+ /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CtxToolbarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4161
+ /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: CtxToolbarComponent, selector: "mv-ctx-toolbar", inputs: { zoom: "zoom", rotate: "rotate", pageHeight: "pageHeight", pageWidth: "pageWidth", canHighlight: "canHighlight", canBookmark: "canBookmark", canComment: "canComment", canDelete: "canDelete", rectangles: "rectangles" }, outputs: { createHighlightEvent: "createHighlightEvent", deleteHighlightEvent: "deleteHighlightEvent", addOrEditCommentEvent: "addOrEditCommentEvent", createBookmarkEvent: "createBookmarkEvent", cancelEvent: "cancelEvent" }, host: { listeners: { "document:keydown.escape": "onEscapeKey($event)" } }, viewQueries: [{ propertyName: "toolbarContainer", first: true, predicate: ["toolbarContainer"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div #toolbarContainer class=\"toolbar\" *ngIf=\"rectangle\"\n [style.top.px]=\"top\"\n [style.left.px]=\"left\">\n <button *ngIf=\"canHighlight\"\n type=\"button\" title=\"Highlight\"\n class=\"aui__toolbar-button aui__toolbar-button--comments contextual-btn leftButton aui__toolbar-button-highlight\"\n (mousedown)=\"createHighlight()\"\n (keydown.enter)=\"createHighlight()\">\n <span>Highlight</span>\n </button>\n <button *ngIf=\"canDelete\"\n type=\"button\" title=\"Delete\"\n class=\"aui__toolbar-button aui__toolbar-button--comments contextual-btn leftButton\"\n (mousedown)=\"deleteHighlight()\"\n (keydown.enter)=\"deleteHighlight()\">\n <span>Remove</span>\n </button>\n <button *ngIf=\"canComment\"\n type=\"button\" title=\"Comment\"\n class=\"aui__toolbar-button aui__toolbar-button--comments contextual-btn rightButton aui__toolbar-button-comment\"\n (mousedown)=\"addOrEditComment()\"\n (keydown.enter)=\"addOrEditComment()\">\n <span>Comment</span></button>\n <button *ngIf=\"canBookmark\"\n type=\"button\" title=\"Bookmark\"\n class=\"aui__toolbar-button aui__toolbar-button--comments contextual-btn rightButton aui__toolbar-button-bookmark\"\n id=\"bookmarkButton\"\n (mousedown)=\"createBookmark()\"\n (keydown.enter)=\"createBookmark()\">\n <span>Bookmark</span></button>\n <div class=\"arrow-down\">\n <div class=\"inner-triangle\"></div>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] }); }
4162
+ }
4163
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CtxToolbarComponent, decorators: [{
4164
+ type: Component,
4165
+ args: [{ selector: 'mv-ctx-toolbar', template: "<div #toolbarContainer class=\"toolbar\" *ngIf=\"rectangle\"\n [style.top.px]=\"top\"\n [style.left.px]=\"left\">\n <button *ngIf=\"canHighlight\"\n type=\"button\" title=\"Highlight\"\n class=\"aui__toolbar-button aui__toolbar-button--comments contextual-btn leftButton aui__toolbar-button-highlight\"\n (mousedown)=\"createHighlight()\"\n (keydown.enter)=\"createHighlight()\">\n <span>Highlight</span>\n </button>\n <button *ngIf=\"canDelete\"\n type=\"button\" title=\"Delete\"\n class=\"aui__toolbar-button aui__toolbar-button--comments contextual-btn leftButton\"\n (mousedown)=\"deleteHighlight()\"\n (keydown.enter)=\"deleteHighlight()\">\n <span>Remove</span>\n </button>\n <button *ngIf=\"canComment\"\n type=\"button\" title=\"Comment\"\n class=\"aui__toolbar-button aui__toolbar-button--comments contextual-btn rightButton aui__toolbar-button-comment\"\n (mousedown)=\"addOrEditComment()\"\n (keydown.enter)=\"addOrEditComment()\">\n <span>Comment</span></button>\n <button *ngIf=\"canBookmark\"\n type=\"button\" title=\"Bookmark\"\n class=\"aui__toolbar-button aui__toolbar-button--comments contextual-btn rightButton aui__toolbar-button-bookmark\"\n id=\"bookmarkButton\"\n (mousedown)=\"createBookmark()\"\n (keydown.enter)=\"createBookmark()\">\n <span>Bookmark</span></button>\n <div class=\"arrow-down\">\n <div class=\"inner-triangle\"></div>\n </div>\n</div>\n" }]
4166
+ }], ctorParameters: () => [], propDecorators: { toolbarContainer: [{
4167
+ type: ViewChild,
4168
+ args: ['toolbarContainer', { static: false }]
4169
+ }], zoom: [{
4170
+ type: Input
4171
+ }], rotate: [{
4172
+ type: Input
4173
+ }], pageHeight: [{
4174
+ type: Input
4175
+ }], pageWidth: [{
4176
+ type: Input
4177
+ }], canHighlight: [{
4178
+ type: Input
4179
+ }], canBookmark: [{
4180
+ type: Input
4181
+ }], canComment: [{
4182
+ type: Input
4183
+ }], canDelete: [{
4184
+ type: Input
4185
+ }], createHighlightEvent: [{
4186
+ type: Output
4187
+ }], deleteHighlightEvent: [{
4188
+ type: Output
4189
+ }], addOrEditCommentEvent: [{
4190
+ type: Output
4191
+ }], createBookmarkEvent: [{
4192
+ type: Output
4193
+ }], cancelEvent: [{
4194
+ type: Output
4195
+ }], onEscapeKey: [{
4196
+ type: HostListener,
4197
+ args: ['document:keydown.escape', ['$event']]
4198
+ }], rectangles: [{
4199
+ type: Input
4200
+ }] } });
4201
+
3892
4202
  class BoxHighlightCreateComponent {
3893
4203
  constructor(toolbarEvents, highlightService) {
3894
4204
  this.toolbarEvents = toolbarEvents;
@@ -4071,163 +4381,47 @@ class RectangleComponent {
4071
4381
  this.top = this.pageHeight - top - height;
4072
4382
  break;
4073
4383
  case 270:
4074
- this.width = height;
4075
- this.height = width;
4076
- this.left = top;
4077
- this.top = this.pageHeight - left - width;
4078
- break;
4079
- }
4080
- }
4081
- hasRectangleChanged(viewRect) {
4082
- return Math.round(this.left) !== viewRect.offsetLeft ||
4083
- Math.round(this.top) !== viewRect.offsetTop ||
4084
- Math.round(this.width) !== viewRect.offsetWidth ||
4085
- Math.round(this.height) !== viewRect.offsetHeight;
4086
- }
4087
- /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RectangleComponent, deps: [{ token: ToolbarEventService }, { token: HighlightCreateService }], target: i0.ɵɵFactoryTarget.Component }); }
4088
- /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: RectangleComponent, selector: "mv-anno-rectangle", inputs: { color: "color", zoom: "zoom", rotate: "rotate", editable: "editable", pageHeight: "pageHeight", pageWidth: "pageWidth", annoRect: "annoRect", selected: "selected" }, outputs: { selectEvent: "selectEvent", updateEvent: "updateEvent" }, viewQueries: [{ propertyName: "viewRect", first: true, predicate: ["rectElement"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div *ngIf=\"editable; else nonEditable\">\n <div #rectElement\n class=\"rectangle\"\n draggable\n resizable\n [tabindex]=\"annoRect.id\"\n [ngClass]=\"{ 'selected': selected, 'grabNDrag': enableGrabNDrag }\"\n [style.backgroundColor]=\"'#' + color\"\n [style.width]=\"width + 'px'\"\n [style.height]=\"height + 'px'\"\n [style.left]=\"left + 'px'\"\n [style.top]=\"top + 'px'\"\n [rotate]=\"0\"\n [selected]=\"selected\"\n (click)=\"onClick()\"\n (stopped)=\"onUpdate(rectElement)\">\n </div>\n</div>\n<ng-template #nonEditable>\n <div #rectElement\n class=\"rectangle\"\n [tabindex]=\"annoRect.id\"\n [ngClass]=\"{ 'selected': selected }\"\n [style.backgroundColor]=\"'#' + color\"\n [style.width]=\"width + 'px'\"\n [style.height]=\"height+ 'px'\"\n [style.left]=\"left + 'px'\"\n [style.top]=\"top + 'px'\"\n (click)=\"onClick()\">\n </div>\n</ng-template>\n", dependencies: [{ kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4$1.DraggableElementDirective, selector: "[draggable]", inputs: ["rotate"], outputs: ["coordinates", "stopped"] }, { kind: "directive", type: i4$1.ResizableElementDirective, selector: "[resizable]", inputs: ["rotate", "selected"], outputs: ["stopped"] }] }); }
4089
- }
4090
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RectangleComponent, decorators: [{
4091
- type: Component,
4092
- args: [{ selector: 'mv-anno-rectangle', template: "<div *ngIf=\"editable; else nonEditable\">\n <div #rectElement\n class=\"rectangle\"\n draggable\n resizable\n [tabindex]=\"annoRect.id\"\n [ngClass]=\"{ 'selected': selected, 'grabNDrag': enableGrabNDrag }\"\n [style.backgroundColor]=\"'#' + color\"\n [style.width]=\"width + 'px'\"\n [style.height]=\"height + 'px'\"\n [style.left]=\"left + 'px'\"\n [style.top]=\"top + 'px'\"\n [rotate]=\"0\"\n [selected]=\"selected\"\n (click)=\"onClick()\"\n (stopped)=\"onUpdate(rectElement)\">\n </div>\n</div>\n<ng-template #nonEditable>\n <div #rectElement\n class=\"rectangle\"\n [tabindex]=\"annoRect.id\"\n [ngClass]=\"{ 'selected': selected }\"\n [style.backgroundColor]=\"'#' + color\"\n [style.width]=\"width + 'px'\"\n [style.height]=\"height+ 'px'\"\n [style.left]=\"left + 'px'\"\n [style.top]=\"top + 'px'\"\n (click)=\"onClick()\">\n </div>\n</ng-template>\n" }]
4093
- }], ctorParameters: () => [{ type: ToolbarEventService }, { type: HighlightCreateService }], propDecorators: { color: [{
4094
- type: Input
4095
- }], zoom: [{
4096
- type: Input
4097
- }], rotate: [{
4098
- type: Input
4099
- }], editable: [{
4100
- type: Input
4101
- }], pageHeight: [{
4102
- type: Input
4103
- }], pageWidth: [{
4104
- type: Input
4105
- }], selectEvent: [{
4106
- type: Output
4107
- }], updateEvent: [{
4108
- type: Output
4109
- }], viewRect: [{
4110
- type: ViewChild,
4111
- args: ['rectElement', { static: false }]
4112
- }], annoRect: [{
4113
- type: Input
4114
- }], selected: [{
4115
- type: Input
4116
- }] } });
4117
-
4118
- class CtxToolbarComponent {
4119
- constructor() {
4120
- this.createHighlightEvent = new EventEmitter();
4121
- this.deleteHighlightEvent = new EventEmitter();
4122
- this.addOrEditCommentEvent = new EventEmitter();
4123
- this.createBookmarkEvent = new EventEmitter();
4124
- this.defaultHeight = 70;
4125
- this.defaultWidth = 300;
4126
- }
4127
- ngOnChanges(changes) {
4128
- this.setRectangle();
4129
- this.top = this.popupTop();
4130
- this.left = this.popupLeft();
4131
- }
4132
- set rectangles(rectangles) {
4133
- if (rectangles) {
4134
- this._rectangles = rectangles;
4135
- this.setRectangle();
4136
- }
4137
- }
4138
- get rectangles() {
4139
- return this._rectangles;
4140
- }
4141
- createHighlight() {
4142
- this.createHighlightEvent.emit();
4143
- this.rectangle = undefined;
4144
- }
4145
- deleteHighlight() {
4146
- this.deleteHighlightEvent.emit();
4147
- }
4148
- addOrEditComment() {
4149
- this.addOrEditCommentEvent.emit();
4150
- setTimeout(() => {
4151
- // This hack to wait until the element is rendered seems to be unreliable,
4152
- if (!location.hash) {
4153
- document.getElementById('viewerContainer')?.scrollBy(0, 1);
4154
- }
4155
- }, 20);
4156
- }
4157
- createBookmark() {
4158
- this.createBookmarkEvent.emit(this.rectangle);
4159
- this.rectangle = undefined;
4160
- }
4161
- setRectangle() {
4162
- const rectangle = this.rectangles
4163
- .reduce((prev, current) => prev.y < current.y ? prev : current);
4164
- this.rectangle = { ...rectangle };
4165
- switch (this.rotate) {
4166
- case 90:
4167
- this.rectangle.width = rectangle.height;
4168
- this.rectangle.height = rectangle.width;
4169
- this.rectangle.x = (this.pageWidth / this.zoom) - rectangle.y - rectangle.height;
4170
- this.rectangle.y = rectangle.x;
4171
- break;
4172
- case 180:
4173
- this.rectangle.x = (this.pageWidth / this.zoom) - rectangle.x - rectangle.width;
4174
- this.rectangle.y = (this.pageHeight / this.zoom) - rectangle.y - rectangle.height;
4175
- break;
4176
- case 270:
4177
- this.rectangle.width = rectangle.height;
4178
- this.rectangle.height = rectangle.width;
4179
- this.rectangle.x = rectangle.y;
4180
- this.rectangle.y = (this.pageHeight / this.zoom) - rectangle.x - rectangle.width;
4384
+ this.width = height;
4385
+ this.height = width;
4386
+ this.left = top;
4387
+ this.top = this.pageHeight - left - width;
4181
4388
  break;
4182
4389
  }
4183
4390
  }
4184
- popupTop() {
4185
- const popupTop = this.rectangle.y * this.zoom - this.defaultHeight;
4186
- return popupTop <= 0 ? this.defaultHeight : popupTop;
4187
- }
4188
- popupLeft() {
4189
- const popupLeft = (this.rectangle.x + (this.rectangle.width / 2)) * this.zoom - (this.defaultWidth / 2);
4190
- if (popupLeft <= 0) {
4191
- return 0;
4192
- }
4193
- else if (popupLeft >= this.pageWidth - this.defaultWidth) {
4194
- return this.pageWidth - this.defaultWidth;
4195
- }
4196
- else {
4197
- return popupLeft;
4198
- }
4391
+ hasRectangleChanged(viewRect) {
4392
+ return Math.round(this.left) !== viewRect.offsetLeft ||
4393
+ Math.round(this.top) !== viewRect.offsetTop ||
4394
+ Math.round(this.width) !== viewRect.offsetWidth ||
4395
+ Math.round(this.height) !== viewRect.offsetHeight;
4199
4396
  }
4200
- /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CtxToolbarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4201
- /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: CtxToolbarComponent, selector: "mv-ctx-toolbar", inputs: { zoom: "zoom", rotate: "rotate", pageHeight: "pageHeight", pageWidth: "pageWidth", canHighlight: "canHighlight", canBookmark: "canBookmark", canComment: "canComment", canDelete: "canDelete", rectangles: "rectangles" }, outputs: { createHighlightEvent: "createHighlightEvent", deleteHighlightEvent: "deleteHighlightEvent", addOrEditCommentEvent: "addOrEditCommentEvent", createBookmarkEvent: "createBookmarkEvent" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"toolbar\" *ngIf=\"rectangle\"\n [style.top.px]=\"top\"\n [style.left.px]=\"left\">\n <button *ngIf=\"canHighlight\"\n type=\"button\" title=\"Highlight\"\n class=\"aui__toolbar-button aui__toolbar-button--comments contextual-btn leftButton aui__toolbar-button-highlight\"\n (mousedown)=\"createHighlight()\">\n <span>Highlight</span>\n </button>\n <button *ngIf=\"canDelete\"\n type=\"button\" title=\"Delete\"\n class=\"aui__toolbar-button aui__toolbar-button--comments contextual-btn leftButton\"\n (mousedown)=\"deleteHighlight()\">\n <span>Remove</span>\n </button>\n <button *ngIf=\"canComment\"\n type=\"button\" title=\"Comment\"\n class=\"aui__toolbar-button aui__toolbar-button--comments contextual-btn rightButton aui__toolbar-button-comment\"\n (mousedown)=\"addOrEditComment()\">\n <span>Comment</span></button>\n <button *ngIf=\"canBookmark\"\n type=\"button\" title=\"Bookmark\"\n class=\"aui__toolbar-button aui__toolbar-button--comments contextual-btn rightButton aui__toolbar-button-bookmark\"\n id=\"bookmarkButton\"\n (mousedown)=\"createBookmark()\">\n <span>Bookmark</span></button>\n <div class=\"arrow-down\">\n <div class=\"inner-triangle\"></div>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] }); }
4397
+ /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RectangleComponent, deps: [{ token: ToolbarEventService }, { token: HighlightCreateService }], target: i0.ɵɵFactoryTarget.Component }); }
4398
+ /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: RectangleComponent, selector: "mv-anno-rectangle", inputs: { color: "color", zoom: "zoom", rotate: "rotate", editable: "editable", pageHeight: "pageHeight", pageWidth: "pageWidth", annoRect: "annoRect", selected: "selected" }, outputs: { selectEvent: "selectEvent", updateEvent: "updateEvent" }, viewQueries: [{ propertyName: "viewRect", first: true, predicate: ["rectElement"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div *ngIf=\"editable; else nonEditable\">\n <div #rectElement\n class=\"rectangle\"\n draggable\n resizable\n [tabindex]=\"annoRect.id\"\n [ngClass]=\"{ 'selected': selected, 'grabNDrag': enableGrabNDrag }\"\n [style.backgroundColor]=\"'#' + color\"\n [style.width]=\"width + 'px'\"\n [style.height]=\"height + 'px'\"\n [style.left]=\"left + 'px'\"\n [style.top]=\"top + 'px'\"\n [rotate]=\"0\"\n [selected]=\"selected\"\n (click)=\"onClick()\"\n (stopped)=\"onUpdate(rectElement)\">\n </div>\n</div>\n<ng-template #nonEditable>\n <div #rectElement\n class=\"rectangle\"\n [tabindex]=\"annoRect.id\"\n [ngClass]=\"{ 'selected': selected }\"\n [style.backgroundColor]=\"'#' + color\"\n [style.width]=\"width + 'px'\"\n [style.height]=\"height+ 'px'\"\n [style.left]=\"left + 'px'\"\n [style.top]=\"top + 'px'\"\n (click)=\"onClick()\">\n </div>\n</ng-template>\n", dependencies: [{ kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4$1.DraggableElementDirective, selector: "[draggable]", inputs: ["rotate"], outputs: ["coordinates", "stopped"] }, { kind: "directive", type: i4$1.ResizableElementDirective, selector: "[resizable]", inputs: ["rotate", "selected"], outputs: ["stopped"] }] }); }
4202
4399
  }
4203
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CtxToolbarComponent, decorators: [{
4400
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RectangleComponent, decorators: [{
4204
4401
  type: Component,
4205
- args: [{ selector: 'mv-ctx-toolbar', template: "<div class=\"toolbar\" *ngIf=\"rectangle\"\n [style.top.px]=\"top\"\n [style.left.px]=\"left\">\n <button *ngIf=\"canHighlight\"\n type=\"button\" title=\"Highlight\"\n class=\"aui__toolbar-button aui__toolbar-button--comments contextual-btn leftButton aui__toolbar-button-highlight\"\n (mousedown)=\"createHighlight()\">\n <span>Highlight</span>\n </button>\n <button *ngIf=\"canDelete\"\n type=\"button\" title=\"Delete\"\n class=\"aui__toolbar-button aui__toolbar-button--comments contextual-btn leftButton\"\n (mousedown)=\"deleteHighlight()\">\n <span>Remove</span>\n </button>\n <button *ngIf=\"canComment\"\n type=\"button\" title=\"Comment\"\n class=\"aui__toolbar-button aui__toolbar-button--comments contextual-btn rightButton aui__toolbar-button-comment\"\n (mousedown)=\"addOrEditComment()\">\n <span>Comment</span></button>\n <button *ngIf=\"canBookmark\"\n type=\"button\" title=\"Bookmark\"\n class=\"aui__toolbar-button aui__toolbar-button--comments contextual-btn rightButton aui__toolbar-button-bookmark\"\n id=\"bookmarkButton\"\n (mousedown)=\"createBookmark()\">\n <span>Bookmark</span></button>\n <div class=\"arrow-down\">\n <div class=\"inner-triangle\"></div>\n </div>\n</div>\n" }]
4206
- }], ctorParameters: () => [], propDecorators: { zoom: [{
4402
+ args: [{ selector: 'mv-anno-rectangle', template: "<div *ngIf=\"editable; else nonEditable\">\n <div #rectElement\n class=\"rectangle\"\n draggable\n resizable\n [tabindex]=\"annoRect.id\"\n [ngClass]=\"{ 'selected': selected, 'grabNDrag': enableGrabNDrag }\"\n [style.backgroundColor]=\"'#' + color\"\n [style.width]=\"width + 'px'\"\n [style.height]=\"height + 'px'\"\n [style.left]=\"left + 'px'\"\n [style.top]=\"top + 'px'\"\n [rotate]=\"0\"\n [selected]=\"selected\"\n (click)=\"onClick()\"\n (stopped)=\"onUpdate(rectElement)\">\n </div>\n</div>\n<ng-template #nonEditable>\n <div #rectElement\n class=\"rectangle\"\n [tabindex]=\"annoRect.id\"\n [ngClass]=\"{ 'selected': selected }\"\n [style.backgroundColor]=\"'#' + color\"\n [style.width]=\"width + 'px'\"\n [style.height]=\"height+ 'px'\"\n [style.left]=\"left + 'px'\"\n [style.top]=\"top + 'px'\"\n (click)=\"onClick()\">\n </div>\n</ng-template>\n" }]
4403
+ }], ctorParameters: () => [{ type: ToolbarEventService }, { type: HighlightCreateService }], propDecorators: { color: [{
4404
+ type: Input
4405
+ }], zoom: [{
4207
4406
  type: Input
4208
4407
  }], rotate: [{
4209
4408
  type: Input
4409
+ }], editable: [{
4410
+ type: Input
4210
4411
  }], pageHeight: [{
4211
4412
  type: Input
4212
4413
  }], pageWidth: [{
4213
4414
  type: Input
4214
- }], canHighlight: [{
4215
- type: Input
4216
- }], canBookmark: [{
4217
- type: Input
4218
- }], canComment: [{
4219
- type: Input
4220
- }], canDelete: [{
4221
- type: Input
4222
- }], createHighlightEvent: [{
4223
- type: Output
4224
- }], deleteHighlightEvent: [{
4225
- type: Output
4226
- }], addOrEditCommentEvent: [{
4415
+ }], selectEvent: [{
4227
4416
  type: Output
4228
- }], createBookmarkEvent: [{
4417
+ }], updateEvent: [{
4229
4418
  type: Output
4230
- }], rectangles: [{
4419
+ }], viewRect: [{
4420
+ type: ViewChild,
4421
+ args: ['rectElement', { static: false }]
4422
+ }], annoRect: [{
4423
+ type: Input
4424
+ }], selected: [{
4231
4425
  type: Input
4232
4426
  }] } });
4233
4427
 
@@ -4287,7 +4481,7 @@ class AnnotationViewComponent {
4287
4481
  this.toolbarEvents.toggleCommentsPanel(true);
4288
4482
  }
4289
4483
  /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AnnotationViewComponent, deps: [{ token: ToolbarEventService }, { token: i1.Store }], target: i0.ɵɵFactoryTarget.Component }); }
4290
- /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AnnotationViewComponent, selector: "mv-annotation", inputs: { annotation: "annotation", zoom: "zoom", rotate: "rotate", selectedAnnoId: "selectedAnnoId", pageHeight: "pageHeight", pageWidth: "pageWidth" }, outputs: { update: "update", delete: "delete", annotationClick: "annotationClick" }, viewQueries: [{ propertyName: "container", first: true, predicate: ["container"], descendants: true }], ngImport: i0, template: "<div #container [tabindex]=\"anno.id\">\n <mv-ctx-toolbar *ngIf=\"selected\"\n [canDelete]=\"true\" [canComment]=\"true\"\n [rectangles]=\"anno.rectangles\"\n [zoom]=\"zoom\"\n [rotate]=\"rotate\"\n [pageHeight]=\"pageHeight\"\n [pageWidth]=\"pageWidth\"\n (deleteHighlightEvent)=\"deleteHighlight()\"\n (addOrEditCommentEvent)=\"addOrEditComment()\">\n </mv-ctx-toolbar>\n <ng-container *ngFor=\"let rectangle of anno.rectangles\">\n <mv-anno-rectangle\n (selectEvent)=\"onSelect()\"\n (updateEvent)=\"onRectangleUpdate($event)\"\n [selected]=\"selected\"\n [zoom]=\"zoom\"\n [rotate]=\"rotate\"\n [pageHeight]=\"pageHeight\"\n [pageWidth]=\"pageWidth\"\n [editable]=\"anno.rectangles.length <= 1\"\n [annoRect]=\"rectangle\"\n [color]=\"anno.color\">\n </mv-anno-rectangle>\n </ng-container>\n</div>\n", dependencies: [{ kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: RectangleComponent, selector: "mv-anno-rectangle", inputs: ["color", "zoom", "rotate", "editable", "pageHeight", "pageWidth", "annoRect", "selected"], outputs: ["selectEvent", "updateEvent"] }, { kind: "component", type: CtxToolbarComponent, selector: "mv-ctx-toolbar", inputs: ["zoom", "rotate", "pageHeight", "pageWidth", "canHighlight", "canBookmark", "canComment", "canDelete", "rectangles"], outputs: ["createHighlightEvent", "deleteHighlightEvent", "addOrEditCommentEvent", "createBookmarkEvent"] }] }); }
4484
+ /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AnnotationViewComponent, selector: "mv-annotation", inputs: { annotation: "annotation", zoom: "zoom", rotate: "rotate", selectedAnnoId: "selectedAnnoId", pageHeight: "pageHeight", pageWidth: "pageWidth" }, outputs: { update: "update", delete: "delete", annotationClick: "annotationClick" }, viewQueries: [{ propertyName: "container", first: true, predicate: ["container"], descendants: true }], ngImport: i0, template: "<div #container [tabindex]=\"anno.id\">\n <mv-ctx-toolbar *ngIf=\"selected\"\n [canDelete]=\"true\" [canComment]=\"true\"\n [rectangles]=\"anno.rectangles\"\n [zoom]=\"zoom\"\n [rotate]=\"rotate\"\n [pageHeight]=\"pageHeight\"\n [pageWidth]=\"pageWidth\"\n (deleteHighlightEvent)=\"deleteHighlight()\"\n (addOrEditCommentEvent)=\"addOrEditComment()\">\n </mv-ctx-toolbar>\n <ng-container *ngFor=\"let rectangle of anno.rectangles\">\n <mv-anno-rectangle\n (selectEvent)=\"onSelect()\"\n (updateEvent)=\"onRectangleUpdate($event)\"\n [selected]=\"selected\"\n [zoom]=\"zoom\"\n [rotate]=\"rotate\"\n [pageHeight]=\"pageHeight\"\n [pageWidth]=\"pageWidth\"\n [editable]=\"anno.rectangles.length <= 1\"\n [annoRect]=\"rectangle\"\n [color]=\"anno.color\">\n </mv-anno-rectangle>\n </ng-container>\n</div>\n", dependencies: [{ kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: RectangleComponent, selector: "mv-anno-rectangle", inputs: ["color", "zoom", "rotate", "editable", "pageHeight", "pageWidth", "annoRect", "selected"], outputs: ["selectEvent", "updateEvent"] }, { kind: "component", type: CtxToolbarComponent, selector: "mv-ctx-toolbar", inputs: ["zoom", "rotate", "pageHeight", "pageWidth", "canHighlight", "canBookmark", "canComment", "canDelete", "rectangles"], outputs: ["createHighlightEvent", "deleteHighlightEvent", "addOrEditCommentEvent", "createBookmarkEvent", "cancelEvent"] }] }); }
4291
4485
  }
4292
4486
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AnnotationViewComponent, decorators: [{
4293
4487
  type: Component,
@@ -4381,11 +4575,20 @@ class MetadataLayerComponent {
4381
4575
  this.rectangles = highlight.rectangles;
4382
4576
  if (this.rectangles) {
4383
4577
  this.toolbarEvents.highlightModeSubject.next(false);
4578
+ setTimeout(() => this.ctxToolbar.focusToolbar(), 0);
4384
4579
  }
4385
4580
  }
4386
4581
  clearContextToolbar() {
4387
4582
  this.rectangles = undefined;
4388
4583
  }
4584
+ cancelContextToolbar() {
4585
+ const selection = window.getSelection();
4586
+ if (selection) {
4587
+ selection.removeAllRanges();
4588
+ }
4589
+ this.rectangles = undefined;
4590
+ this.toolbarEvents.highlightModeSubject.next(true);
4591
+ }
4389
4592
  createHighlight() {
4390
4593
  this.highlightService.saveAnnotation(this.rectangles, this.highlightPage);
4391
4594
  this.highlightService.resetHighlight();
@@ -4414,15 +4617,18 @@ class MetadataLayerComponent {
4414
4617
  this.toolbarEvents.drawModeSubject.next(false);
4415
4618
  }
4416
4619
  /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: MetadataLayerComponent, deps: [{ token: i1.Store }, { token: HighlightCreateService }, { token: ToolbarEventService }, { token: ViewerEventService }], target: i0.ɵɵFactoryTarget.Component }); }
4417
- /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: MetadataLayerComponent, selector: "mv-metadata-layer", inputs: { zoom: "zoom", rotate: "rotate" }, ngImport: i0, template: "<div class=\"pageContainer\">\n <div *ngFor=\"let page of pages; index as i\"\n class=\"pageContainer__page\"\n [ngStyle]=\"{\n 'width.px': page.styles.width,\n 'height.px': page.styles.height\n }\"\n [ngClass]=\"{ 'pageContainer__page--draw' : drawMode }\">\n <mv-box-highlight-create\n [page]=\"i + 1\"\n [pageHeight]=\"page.styles.height\"\n [pageWidth]=\"page.styles.width\"\n [rotate]=\"rotate\"\n [zoom]=\"zoom\"\n (saveSelection)=\"saveAnnotation($event)\">\n </mv-box-highlight-create>\n <mv-ctx-toolbar *ngIf=\"rectangles && highlightPage === (i + 1)\"\n [rectangles]=\"rectangles\"\n [canBookmark]=\"true\" [canHighlight]=\"true\"\n [zoom]=\"zoom\"\n [rotate]=\"rotate\"\n [pageHeight]=\"page.styles.height\"\n [pageWidth]=\"page.styles.width\"\n (createBookmarkEvent)=\"createBookmark($event)\"\n (createHighlightEvent)=\"createHighlight()\">\n </mv-ctx-toolbar>\n <div class=\"pageContainer__page-item\">\n <mv-annotation-set *ngIf=\"(annoPages$ | async) as annoPages\"\n [zoom]=\"zoom\"\n [rotate]=\"rotate\"\n [pageHeight]=\"page.styles.height\"\n [pageWidth]=\"page.styles.width\"\n [page]=\"i\" [annotations]=\"annoPages[i + 1]\"></mv-annotation-set>\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: BoxHighlightCreateComponent, selector: "mv-box-highlight-create", inputs: ["page", "pageHeight", "pageWidth", "rotate", "zoom", "container"], outputs: ["saveSelection"] }, { kind: "component", type: AnnotationSetComponent, selector: "mv-annotation-set", inputs: ["page", "annotations", "zoom", "rotate", "pageHeight", "pageWidth"] }, { kind: "component", type: CtxToolbarComponent, selector: "mv-ctx-toolbar", inputs: ["zoom", "rotate", "pageHeight", "pageWidth", "canHighlight", "canBookmark", "canComment", "canDelete", "rectangles"], outputs: ["createHighlightEvent", "deleteHighlightEvent", "addOrEditCommentEvent", "createBookmarkEvent"] }, { kind: "pipe", type: i5.AsyncPipe, name: "async" }] }); }
4620
+ /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: MetadataLayerComponent, selector: "mv-metadata-layer", inputs: { zoom: "zoom", rotate: "rotate" }, viewQueries: [{ propertyName: "ctxToolbar", first: true, predicate: CtxToolbarComponent, descendants: true }], ngImport: i0, template: "<div class=\"pageContainer\">\n <div *ngFor=\"let page of pages; index as i\"\n class=\"pageContainer__page\"\n [ngStyle]=\"{\n 'width.px': page.styles.width,\n 'height.px': page.styles.height\n }\"\n [ngClass]=\"{ 'pageContainer__page--draw' : drawMode }\">\n <mv-box-highlight-create\n [page]=\"i + 1\"\n [pageHeight]=\"page.styles.height\"\n [pageWidth]=\"page.styles.width\"\n [rotate]=\"rotate\"\n [zoom]=\"zoom\"\n (saveSelection)=\"saveAnnotation($event)\">\n </mv-box-highlight-create>\n <mv-ctx-toolbar *ngIf=\"rectangles && highlightPage === (i + 1)\"\n [rectangles]=\"rectangles\"\n [canBookmark]=\"true\" [canHighlight]=\"true\"\n [zoom]=\"zoom\"\n [rotate]=\"rotate\"\n [pageHeight]=\"page.styles.height\"\n [pageWidth]=\"page.styles.width\"\n (createBookmarkEvent)=\"createBookmark($event)\"\n (createHighlightEvent)=\"createHighlight()\"\n (cancelEvent)=\"cancelContextToolbar()\">\n </mv-ctx-toolbar>\n <div class=\"pageContainer__page-item\">\n <mv-annotation-set *ngIf=\"(annoPages$ | async) as annoPages\"\n [zoom]=\"zoom\"\n [rotate]=\"rotate\"\n [pageHeight]=\"page.styles.height\"\n [pageWidth]=\"page.styles.width\"\n [page]=\"i\" [annotations]=\"annoPages[i + 1]\"></mv-annotation-set>\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: BoxHighlightCreateComponent, selector: "mv-box-highlight-create", inputs: ["page", "pageHeight", "pageWidth", "rotate", "zoom", "container"], outputs: ["saveSelection"] }, { kind: "component", type: AnnotationSetComponent, selector: "mv-annotation-set", inputs: ["page", "annotations", "zoom", "rotate", "pageHeight", "pageWidth"] }, { kind: "component", type: CtxToolbarComponent, selector: "mv-ctx-toolbar", inputs: ["zoom", "rotate", "pageHeight", "pageWidth", "canHighlight", "canBookmark", "canComment", "canDelete", "rectangles"], outputs: ["createHighlightEvent", "deleteHighlightEvent", "addOrEditCommentEvent", "createBookmarkEvent", "cancelEvent"] }, { kind: "pipe", type: i5.AsyncPipe, name: "async" }] }); }
4418
4621
  }
4419
4622
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: MetadataLayerComponent, decorators: [{
4420
4623
  type: Component,
4421
- args: [{ selector: 'mv-metadata-layer', template: "<div class=\"pageContainer\">\n <div *ngFor=\"let page of pages; index as i\"\n class=\"pageContainer__page\"\n [ngStyle]=\"{\n 'width.px': page.styles.width,\n 'height.px': page.styles.height\n }\"\n [ngClass]=\"{ 'pageContainer__page--draw' : drawMode }\">\n <mv-box-highlight-create\n [page]=\"i + 1\"\n [pageHeight]=\"page.styles.height\"\n [pageWidth]=\"page.styles.width\"\n [rotate]=\"rotate\"\n [zoom]=\"zoom\"\n (saveSelection)=\"saveAnnotation($event)\">\n </mv-box-highlight-create>\n <mv-ctx-toolbar *ngIf=\"rectangles && highlightPage === (i + 1)\"\n [rectangles]=\"rectangles\"\n [canBookmark]=\"true\" [canHighlight]=\"true\"\n [zoom]=\"zoom\"\n [rotate]=\"rotate\"\n [pageHeight]=\"page.styles.height\"\n [pageWidth]=\"page.styles.width\"\n (createBookmarkEvent)=\"createBookmark($event)\"\n (createHighlightEvent)=\"createHighlight()\">\n </mv-ctx-toolbar>\n <div class=\"pageContainer__page-item\">\n <mv-annotation-set *ngIf=\"(annoPages$ | async) as annoPages\"\n [zoom]=\"zoom\"\n [rotate]=\"rotate\"\n [pageHeight]=\"page.styles.height\"\n [pageWidth]=\"page.styles.width\"\n [page]=\"i\" [annotations]=\"annoPages[i + 1]\"></mv-annotation-set>\n </div>\n </div>\n</div>\n" }]
4624
+ args: [{ selector: 'mv-metadata-layer', template: "<div class=\"pageContainer\">\n <div *ngFor=\"let page of pages; index as i\"\n class=\"pageContainer__page\"\n [ngStyle]=\"{\n 'width.px': page.styles.width,\n 'height.px': page.styles.height\n }\"\n [ngClass]=\"{ 'pageContainer__page--draw' : drawMode }\">\n <mv-box-highlight-create\n [page]=\"i + 1\"\n [pageHeight]=\"page.styles.height\"\n [pageWidth]=\"page.styles.width\"\n [rotate]=\"rotate\"\n [zoom]=\"zoom\"\n (saveSelection)=\"saveAnnotation($event)\">\n </mv-box-highlight-create>\n <mv-ctx-toolbar *ngIf=\"rectangles && highlightPage === (i + 1)\"\n [rectangles]=\"rectangles\"\n [canBookmark]=\"true\" [canHighlight]=\"true\"\n [zoom]=\"zoom\"\n [rotate]=\"rotate\"\n [pageHeight]=\"page.styles.height\"\n [pageWidth]=\"page.styles.width\"\n (createBookmarkEvent)=\"createBookmark($event)\"\n (createHighlightEvent)=\"createHighlight()\"\n (cancelEvent)=\"cancelContextToolbar()\">\n </mv-ctx-toolbar>\n <div class=\"pageContainer__page-item\">\n <mv-annotation-set *ngIf=\"(annoPages$ | async) as annoPages\"\n [zoom]=\"zoom\"\n [rotate]=\"rotate\"\n [pageHeight]=\"page.styles.height\"\n [pageWidth]=\"page.styles.width\"\n [page]=\"i\" [annotations]=\"annoPages[i + 1]\"></mv-annotation-set>\n </div>\n </div>\n</div>\n" }]
4422
4625
  }], ctorParameters: () => [{ type: i1.Store }, { type: HighlightCreateService }, { type: ToolbarEventService }, { type: ViewerEventService }], propDecorators: { zoom: [{
4423
4626
  type: Input
4424
4627
  }], rotate: [{
4425
4628
  type: Input
4629
+ }], ctxToolbar: [{
4630
+ type: ViewChild,
4631
+ args: [CtxToolbarComponent, { static: false }]
4426
4632
  }] } });
4427
4633
 
4428
4634
  class BookmarksComponent {
@@ -4975,114 +5181,356 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
4975
5181
  args: ['window:pointerup']
4976
5182
  }] } });
4977
5183
 
4978
- class HighlightCreateDirective {
4979
- constructor(element, toolbarEvents, viewerEvents, highlightService, store) {
4980
- this.element = element;
4981
- this.toolbarEvents = toolbarEvents;
4982
- this.viewerEvents = viewerEvents;
4983
- this.highlightService = highlightService;
4984
- this.store = store;
5184
+ class KeyboardTextHighlightDirective {
5185
+ set enabled(value) {
5186
+ const wasEnabled = this._enabled;
5187
+ this._enabled = value;
5188
+ // Don't auto-initialize cursor - let it appear on first arrow key press
5189
+ // This prevents the Enter key from the button click triggering startTextSelection
5190
+ }
5191
+ get enabled() {
5192
+ return this._enabled;
5193
+ }
5194
+ static { this.lastInteractionWasKeyboard = false; }
5195
+ constructor(elementRef) {
5196
+ this.elementRef = elementRef;
5197
+ this._enabled = false;
5198
+ this.incrementSmall = 5;
5199
+ this.incrementMedium = 10;
5200
+ this.incrementLarge = 20;
5201
+ this.selectionStarted = new EventEmitter();
5202
+ this.selectionUpdated = new EventEmitter();
5203
+ this.selectionConfirmed = new EventEmitter();
5204
+ this.selectionCancelled = new EventEmitter();
5205
+ this.cursorPositionChanged = new EventEmitter();
5206
+ this.selectionCursorPositionChanged = new EventEmitter();
5207
+ this.isSelecting = false;
5208
+ this.showCursor = false;
5209
+ this.lastValidEndNode = null;
5210
+ this.lastValidEndOffset = 0;
5211
+ if (typeof window !== 'undefined') {
5212
+ window.addEventListener('keydown', KeyboardTextHighlightDirective.onGlobalKeyDown, { capture: true });
5213
+ window.addEventListener('mousedown', KeyboardTextHighlightDirective.onGlobalMouseDown, { capture: true });
5214
+ }
5215
+ }
5216
+ static onGlobalKeyDown() {
5217
+ KeyboardTextHighlightDirective.lastInteractionWasKeyboard = true;
5218
+ }
5219
+ static onGlobalMouseDown() {
5220
+ KeyboardTextHighlightDirective.lastInteractionWasKeyboard = false;
4985
5221
  }
4986
- ngOnInit() {
4987
- this.$subscription = this.store.select(getPages).subscribe((pages) => {
4988
- if (pages[1]) {
4989
- this.allPages = pages;
5222
+ ngOnDestroy() {
5223
+ this.cleanup();
5224
+ }
5225
+ onKeyDown(event) {
5226
+ if (!this.enabled) {
5227
+ return;
5228
+ }
5229
+ if (event.key === 'Enter') {
5230
+ event.preventDefault();
5231
+ event.stopPropagation();
5232
+ if (!this.isSelecting) {
5233
+ this.startTextSelection();
4990
5234
  }
4991
- });
5235
+ else {
5236
+ this.confirmTextSelection();
5237
+ }
5238
+ return;
5239
+ }
5240
+ if (event.key === 'Escape') {
5241
+ event.preventDefault();
5242
+ event.stopPropagation();
5243
+ if (this.isSelecting) {
5244
+ this.cancelTextSelection();
5245
+ }
5246
+ else if (this.showCursor) {
5247
+ this.hideCursor();
5248
+ }
5249
+ return;
5250
+ }
5251
+ if (['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'].includes(event.key)) {
5252
+ event.preventDefault();
5253
+ event.stopPropagation();
5254
+ if (this.isSelecting) {
5255
+ this.expandTextSelection(event);
5256
+ }
5257
+ else {
5258
+ this.moveCursor(event);
5259
+ }
5260
+ }
4992
5261
  }
4993
- ngOnDestroy() {
4994
- if (this.$subscription) {
4995
- this.$subscription.unsubscribe();
5262
+ onBlur() {
5263
+ if (this.showCursor && !this.isSelecting) {
5264
+ this.hideCursor();
4996
5265
  }
4997
5266
  }
4998
- onMouseUp(mouseEvent) {
4999
- let page;
5000
- let currentElement = mouseEvent.target;
5001
- while (currentElement.offsetParent) {
5002
- currentElement = currentElement.offsetParent;
5003
- if (currentElement.getAttribute) {
5004
- page = parseInt(currentElement.getAttribute('data-page-number'), 10);
5005
- if (page) {
5006
- break;
5007
- }
5267
+ moveCursor(event) {
5268
+ const increment = event.shiftKey ? this.incrementLarge : this.incrementMedium;
5269
+ if (!this.showCursor) {
5270
+ // we use window dimensions because we're using fixed positioning
5271
+ const viewportWidth = window.innerWidth;
5272
+ const viewportHeight = window.innerHeight;
5273
+ this.cursorX = viewportWidth / 2;
5274
+ this.cursorY = viewportHeight / 2;
5275
+ this.showCursor = true;
5276
+ this.emitCursorPosition();
5277
+ return;
5278
+ }
5279
+ const viewportWidth = window.innerWidth;
5280
+ const viewportHeight = window.innerHeight;
5281
+ switch (event.key) {
5282
+ case 'ArrowUp':
5283
+ this.cursorY = Math.max(0, this.cursorY - increment);
5284
+ break;
5285
+ case 'ArrowDown':
5286
+ this.cursorY = Math.min(viewportHeight, this.cursorY + increment);
5287
+ break;
5288
+ case 'ArrowLeft':
5289
+ this.cursorX = Math.max(0, this.cursorX - increment);
5290
+ break;
5291
+ case 'ArrowRight':
5292
+ this.cursorX = Math.min(viewportWidth, this.cursorX + increment);
5293
+ break;
5294
+ }
5295
+ this.emitCursorPosition();
5296
+ }
5297
+ startTextSelection() {
5298
+ if (this.showCursor) {
5299
+ this.selectionStartX = this.cursorX;
5300
+ this.selectionStartY = this.cursorY;
5301
+ this.selectionEndX = this.cursorX;
5302
+ this.selectionEndY = this.cursorY;
5303
+ this.showCursor = false;
5304
+ this.emitCursorPosition();
5305
+ }
5306
+ else {
5307
+ // default to center
5308
+ this.selectionStartX = window.innerWidth / 2;
5309
+ this.selectionStartY = window.innerHeight / 2;
5310
+ this.selectionEndX = this.selectionStartX;
5311
+ this.selectionEndY = this.selectionStartY;
5312
+ }
5313
+ this.isSelecting = true;
5314
+ this.currentPage = this.getCurrentPageNumber();
5315
+ this.lastValidEndNode = null;
5316
+ this.lastValidEndOffset = 0;
5317
+ this.selectionCursorPositionChanged.emit({
5318
+ x: this.selectionEndX,
5319
+ y: this.selectionEndY,
5320
+ visible: true
5321
+ });
5322
+ this.createTextSelectionAtPoint(this.selectionStartX, this.selectionStartY);
5323
+ this.selectionStarted.emit();
5324
+ }
5325
+ expandTextSelection(event) {
5326
+ const increment = event.shiftKey ? this.incrementLarge : this.incrementSmall;
5327
+ const viewportWidth = window.innerWidth;
5328
+ const viewportHeight = window.innerHeight;
5329
+ switch (event.key) {
5330
+ case 'ArrowRight':
5331
+ this.selectionEndX = Math.min(viewportWidth, this.selectionEndX + increment);
5332
+ break;
5333
+ case 'ArrowLeft':
5334
+ this.selectionEndX = Math.max(0, this.selectionEndX - increment);
5335
+ break;
5336
+ case 'ArrowDown':
5337
+ this.selectionEndY = Math.min(viewportHeight, this.selectionEndY + increment);
5338
+ break;
5339
+ case 'ArrowUp':
5340
+ this.selectionEndY = Math.max(0, this.selectionEndY - increment);
5341
+ break;
5342
+ }
5343
+ this.selectionCursorPositionChanged.emit({
5344
+ x: this.selectionEndX,
5345
+ y: this.selectionEndY,
5346
+ visible: true
5347
+ });
5348
+ this.updateTextSelection();
5349
+ this.emitSelectionUpdated();
5350
+ }
5351
+ createTextSelectionAtPoint(viewportX, viewportY) {
5352
+ const selection = window.getSelection();
5353
+ // get precise caret position at the coordinates
5354
+ // caretPositionFromPoint is standard but not supported in all browsers
5355
+ // caretRangeFromPoint is older and supported in more browsers
5356
+ let range = null;
5357
+ if (document.caretPositionFromPoint) {
5358
+ const caretPosition = document.caretPositionFromPoint(viewportX, viewportY);
5359
+ if (caretPosition) {
5360
+ range = document.createRange();
5361
+ range.setStart(caretPosition.offsetNode, caretPosition.offset);
5362
+ range.collapse(true);
5008
5363
  }
5009
5364
  }
5010
- if (this.toolbarEvents.highlightModeSubject.getValue()) {
5011
- const rectangles = this.getRectangles(mouseEvent, page);
5012
- this.viewerEvents.textSelected({ page, rectangles });
5365
+ else if (document.caretRangeFromPoint) {
5366
+ range = document.caretRangeFromPoint(viewportX, viewportY);
5367
+ }
5368
+ if (range) {
5369
+ selection.removeAllRanges();
5370
+ selection.addRange(range);
5013
5371
  }
5014
5372
  }
5015
- onPdfViewerClick(event) {
5016
- this.store.dispatch(new SelectedAnnotation({
5017
- annotationId: '',
5018
- selected: false,
5019
- editable: false,
5020
- }));
5021
- this.viewerEvents.clearCtxToolbar();
5373
+ updateTextSelection() {
5374
+ const selection = window.getSelection();
5375
+ if (!selection || selection.rangeCount === 0) {
5376
+ return;
5377
+ }
5378
+ const range = selection.getRangeAt(0);
5379
+ const startNode = range.startContainer;
5380
+ const startOffset = range.startOffset;
5381
+ // get end position using caret APIs
5382
+ // caretPositionFromPoint is standard but not supported in all browsers
5383
+ // caretRangeFromPoint is older and supported in more browsers
5384
+ let endNode = null;
5385
+ let endOffset = 0;
5386
+ if (document.caretPositionFromPoint) {
5387
+ const caretPosition = document.caretPositionFromPoint(this.selectionEndX, this.selectionEndY);
5388
+ if (caretPosition) {
5389
+ endNode = caretPosition.offsetNode;
5390
+ endOffset = caretPosition.offset;
5391
+ }
5392
+ }
5393
+ else if (document.caretRangeFromPoint) {
5394
+ const caretRange = document.caretRangeFromPoint(this.selectionEndX, this.selectionEndY);
5395
+ if (caretRange) {
5396
+ endNode = caretRange.startContainer;
5397
+ endOffset = caretRange.startOffset;
5398
+ }
5399
+ }
5400
+ if (endNode) {
5401
+ const range = document.createRange();
5402
+ range.setStart(startNode, startOffset);
5403
+ range.setEnd(endNode, endOffset);
5404
+ const isBackward = range.collapsed && (startNode !== endNode || endOffset < startOffset);
5405
+ const comparison = startNode.compareDocumentPosition(endNode);
5406
+ const endBeforeStart = (comparison & Node.DOCUMENT_POSITION_PRECEDING) !== 0;
5407
+ if (isBackward || endBeforeStart) {
5408
+ if (this.lastValidEndNode) {
5409
+ endNode = this.lastValidEndNode;
5410
+ endOffset = this.lastValidEndOffset;
5411
+ }
5412
+ else {
5413
+ endNode = startNode;
5414
+ endOffset = startOffset;
5415
+ }
5416
+ }
5417
+ else {
5418
+ this.lastValidEndNode = endNode;
5419
+ this.lastValidEndOffset = endOffset;
5420
+ }
5421
+ // use setBaseAndExtent to handle selection direction with precise offsets
5422
+ // to ensure the selection always starts from the original start point
5423
+ // and extends to the exact character position at the cursor
5424
+ selection.setBaseAndExtent(startNode, startOffset, endNode, endOffset);
5425
+ }
5426
+ }
5427
+ confirmTextSelection() {
5428
+ this.selectionConfirmed.emit();
5429
+ this.selectionCursorPositionChanged.emit({
5430
+ x: this.selectionEndX,
5431
+ y: this.selectionEndY,
5432
+ visible: false
5433
+ });
5434
+ this.cleanup();
5022
5435
  }
5023
- getRectangles(event, page) {
5024
- this.pageHeight = this.allPages[page].styles.height;
5025
- this.pageWidth = this.allPages[page].styles.width;
5026
- this.zoom = parseFloat(this.allPages[page].scaleRotation.scale);
5027
- this.rotate = parseInt(this.allPages[page].scaleRotation.rotation, 10);
5436
+ cancelTextSelection() {
5028
5437
  const selection = window.getSelection();
5029
5438
  if (selection) {
5030
- const localElement = event.target;
5031
- this.removeEnhancedTextModeStyling(localElement);
5032
- if (selection.rangeCount && !selection.isCollapsed) {
5033
- const range = selection.getRangeAt(0).cloneRange();
5034
- const clientRects = range.getClientRects();
5035
- if (clientRects) {
5036
- const parentRect = HtmlTemplatesHelper
5037
- .getAdjustedBoundingRect(localElement.closest(".textLayer"));
5038
- const selectionRectangles = [];
5039
- for (let i = 0; i < clientRects.length; i++) {
5040
- const selectionRectangle = this.createTextRectangle(clientRects[i], parentRect);
5041
- const findSelecttionRectangle = selectionRectangles.find((rect) => rect.width === selectionRectangle.width && rect.x === selectionRectangle.x);
5042
- if (!findSelecttionRectangle) {
5043
- selectionRectangles.push(selectionRectangle);
5044
- }
5045
- }
5046
- return selectionRectangles;
5439
+ selection.removeAllRanges();
5440
+ }
5441
+ this.selectionCancelled.emit();
5442
+ this.selectionCursorPositionChanged.emit({
5443
+ x: this.selectionEndX,
5444
+ y: this.selectionEndY,
5445
+ visible: false
5446
+ });
5447
+ this.cleanup();
5448
+ }
5449
+ hideCursor() {
5450
+ this.showCursor = false;
5451
+ this.emitCursorPosition();
5452
+ }
5453
+ cleanup() {
5454
+ this.isSelecting = false;
5455
+ this.showCursor = false;
5456
+ this.cursorX = undefined;
5457
+ this.cursorY = undefined;
5458
+ this.selectionStartX = undefined;
5459
+ this.selectionStartY = undefined;
5460
+ this.selectionEndX = undefined;
5461
+ this.selectionEndY = undefined;
5462
+ this.currentPage = undefined;
5463
+ this.lastValidEndNode = null;
5464
+ this.lastValidEndOffset = 0;
5465
+ }
5466
+ getCurrentPageNumber() {
5467
+ let currentElement = this.elementRef.nativeElement;
5468
+ while (currentElement && currentElement.offsetParent) {
5469
+ currentElement = currentElement.offsetParent;
5470
+ if (currentElement.getAttribute) {
5471
+ const page = parseInt(currentElement.getAttribute('data-page-number'), 10);
5472
+ if (page) {
5473
+ return page;
5047
5474
  }
5048
5475
  }
5049
5476
  }
5477
+ return 1;
5050
5478
  }
5051
- createTextRectangle(rect, parentRect) {
5052
- const height = rect.bottom - rect.top;
5053
- const width = rect.right - rect.left;
5054
- const top = rect.top - parentRect.top;
5055
- const left = rect.left - parentRect.left;
5056
- let rectangle = this.highlightService.applyRotation(this.pageHeight, this.pageWidth, height, width, top, left, this.rotate, this.zoom);
5057
- rectangle = { id: v4(), ...rectangle };
5058
- return rectangle;
5479
+ emitCursorPosition() {
5480
+ const position = {
5481
+ x: this.cursorX,
5482
+ y: this.cursorY,
5483
+ visible: this.showCursor
5484
+ };
5485
+ this.cursorPositionChanged.emit(position);
5486
+ }
5487
+ emitSelectionUpdated() {
5488
+ this.selectionUpdated.emit({
5489
+ page: this.currentPage,
5490
+ startX: this.selectionStartX,
5491
+ startY: this.selectionStartY,
5492
+ endX: this.selectionEndX,
5493
+ endY: this.selectionEndY
5494
+ });
5059
5495
  }
5060
- removeEnhancedTextModeStyling(element) {
5061
- if (element.parentElement.children) {
5062
- for (let i = 0; i < element.parentElement.children.length; i++) {
5063
- const child = element.parentElement.children[i];
5064
- child.style.padding = '0';
5065
- // regex will be targeting the translate style in string
5066
- // e.g. scaleX(0.969918) translateX(-110.684px) translateY(-105.274px) will become scaleX(0.969918)
5067
- const translateCSSRegex = /translate[XYZ]\(-?\d*(\.\d+)?(px)?\)/g;
5068
- child.style.transform = child.style.transform.replace(translateCSSRegex, '').trim();
5069
- }
5070
- }
5496
+ reset() {
5497
+ this.cleanup();
5498
+ this.emitCursorPosition();
5071
5499
  }
5072
- /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: HighlightCreateDirective, deps: [{ token: i0.ElementRef }, { token: ToolbarEventService }, { token: ViewerEventService }, { token: HighlightCreateService }, { token: i1.Store }], target: i0.ɵɵFactoryTarget.Directive }); }
5073
- /** @nocollapse */ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.13", type: HighlightCreateDirective, selector: "[mvCreateTextHighlight]", host: { listeners: { "mouseup": "onMouseUp($event)", "mousedown": "onPdfViewerClick($event)" } }, ngImport: i0 }); }
5500
+ /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: KeyboardTextHighlightDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); }
5501
+ /** @nocollapse */ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.13", type: KeyboardTextHighlightDirective, selector: "[mvKeyboardTextHighlight]", inputs: { enabled: "enabled", incrementSmall: "incrementSmall", incrementMedium: "incrementMedium", incrementLarge: "incrementLarge" }, outputs: { selectionStarted: "selectionStarted", selectionUpdated: "selectionUpdated", selectionConfirmed: "selectionConfirmed", selectionCancelled: "selectionCancelled", cursorPositionChanged: "cursorPositionChanged", selectionCursorPositionChanged: "selectionCursorPositionChanged" }, host: { listeners: { "keydown": "onKeyDown($event)", "blur": "onBlur()" } }, ngImport: i0 }); }
5074
5502
  }
5075
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: HighlightCreateDirective, decorators: [{
5503
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: KeyboardTextHighlightDirective, decorators: [{
5076
5504
  type: Directive,
5077
5505
  args: [{
5078
- selector: '[mvCreateTextHighlight]'
5506
+ selector: '[mvKeyboardTextHighlight]'
5079
5507
  }]
5080
- }], ctorParameters: () => [{ type: i0.ElementRef }, { type: ToolbarEventService }, { type: ViewerEventService }, { type: HighlightCreateService }, { type: i1.Store }], propDecorators: { onMouseUp: [{
5508
+ }], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { enabled: [{
5509
+ type: Input
5510
+ }], incrementSmall: [{
5511
+ type: Input
5512
+ }], incrementMedium: [{
5513
+ type: Input
5514
+ }], incrementLarge: [{
5515
+ type: Input
5516
+ }], selectionStarted: [{
5517
+ type: Output
5518
+ }], selectionUpdated: [{
5519
+ type: Output
5520
+ }], selectionConfirmed: [{
5521
+ type: Output
5522
+ }], selectionCancelled: [{
5523
+ type: Output
5524
+ }], cursorPositionChanged: [{
5525
+ type: Output
5526
+ }], selectionCursorPositionChanged: [{
5527
+ type: Output
5528
+ }], onKeyDown: [{
5081
5529
  type: HostListener,
5082
- args: ['mouseup', ['$event']]
5083
- }], onPdfViewerClick: [{
5530
+ args: ['keydown', ['$event']]
5531
+ }], onBlur: [{
5084
5532
  type: HostListener,
5085
- args: ['mousedown', ['$event']]
5533
+ args: ['blur']
5086
5534
  }] } });
5087
5535
 
5088
5536
  const getRedactionState = createSelector(getMVState, (state) => state.redactions);
@@ -5117,7 +5565,7 @@ class RedactionComponent {
5117
5565
  this.redactionsPerPage$ = this.store.pipe(select(getRedactionsPerPage));
5118
5566
  this.selectedRedaction$ = this.store.pipe(select(getSelected));
5119
5567
  this.$subscription = this.toolbarEvents.drawModeSubject.subscribe(drawMode => this.drawMode = drawMode);
5120
- this.$subscription.add(this.store.pipe(select(getRedactedDocumentInfo), filter(value => !!value))
5568
+ this.$subscription.add(this.store.pipe(select(getRedactedDocumentInfo), filter$1(value => !!value))
5121
5569
  .subscribe(redactedDocInfo => this.downloadDocument(redactedDocInfo)));
5122
5570
  this.$subscription.add(this.store.pipe(select(getDocumentId)).subscribe(docId => this.documentId = docId));
5123
5571
  this.$subscription.add(this.viewerEvents.textHighlight.subscribe(highlight => this.markTextRedaction(highlight)));
@@ -5244,6 +5692,8 @@ class PdfViewerComponent {
5244
5692
  this.loadingDocument = false;
5245
5693
  this.hasDifferentPageSize = false;
5246
5694
  this.enableGrabNDrag = false;
5695
+ this.showSelectionStartCursor = false;
5696
+ this.showSelectionEndCursor = false;
5247
5697
  this.highlightMode = toolbarEvents.highlightModeSubject.pipe(tap(() => {
5248
5698
  this.store.dispatch(new ClearFilterTags());
5249
5699
  }));
@@ -5282,7 +5732,7 @@ class PdfViewerComponent {
5282
5732
  if (changes.url && this.pdfWrapper) {
5283
5733
  await this.loadDocument();
5284
5734
  if (this.enableRedactions) {
5285
- this.toolbarEvents.redactionMode.pipe(filter(value => !!value))
5735
+ this.toolbarEvents.redactionMode.pipe(filter$1(value => !!value))
5286
5736
  .subscribe(() => this.resetRotation());
5287
5737
  }
5288
5738
  }
@@ -5393,12 +5843,43 @@ class PdfViewerComponent {
5393
5843
  getCurrentPageNumber() {
5394
5844
  return this.pdfWrapper.getPageNumber();
5395
5845
  }
5846
+ onKeyboardTextSelectionConfirmed() {
5847
+ if (this.highlightCreateDirective) {
5848
+ this.highlightCreateDirective.onKeyboardSelectionConfirmed();
5849
+ }
5850
+ }
5851
+ onKeyboardTextSelectionCancelled() {
5852
+ const selection = window.getSelection();
5853
+ if (selection) {
5854
+ selection.removeAllRanges();
5855
+ }
5856
+ }
5857
+ onSelectionStartCursorChanged(position) {
5858
+ if (position.visible) {
5859
+ this.selectionStartCursorX = position.x;
5860
+ this.selectionStartCursorY = position.y;
5861
+ this.showSelectionStartCursor = true;
5862
+ }
5863
+ else {
5864
+ this.showSelectionStartCursor = false;
5865
+ }
5866
+ }
5867
+ onSelectionEndCursorChanged(position) {
5868
+ if (position.visible) {
5869
+ this.selectionEndCursorX = position.x;
5870
+ this.selectionEndCursorY = position.y;
5871
+ this.showSelectionEndCursor = true;
5872
+ }
5873
+ else {
5874
+ this.showSelectionEndCursor = false;
5875
+ }
5876
+ }
5396
5877
  /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: PdfViewerComponent, deps: [{ token: i1.Store }, { token: i1.Store }, { token: PdfJsWrapperFactory }, { token: PrintService }, { token: ToolbarEventService }, { token: ViewerEventService }, { token: IcpService }, { token: ToolbarButtonVisibilityService }, { token: IcpEventService }], target: i0.ɵɵFactoryTarget.Component }); }
5397
- /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: PdfViewerComponent, selector: "mv-pdf-viewer", inputs: { downloadUrl: "downloadUrl", url: "url", downloadFileName: "downloadFileName", enableAnnotations: "enableAnnotations", enableRedactions: "enableRedactions", enableICP: "enableICP", annotationSet: "annotationSet", enableRedactSearch: "enableRedactSearch", height: "height", caseId: "caseId", searchBarHidden: "searchBarHidden" }, outputs: { mediaLoadStatus: "mediaLoadStatus", pdfViewerException: "pdfViewerException", documentTitle: "documentTitle" }, viewQueries: [{ propertyName: "viewerContainer", first: true, predicate: ["viewerContainer"], descendants: true, static: true }, { propertyName: "pdfViewer", first: true, predicate: ["pdfViewer"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<mv-side-bar\n *ngIf=\"toolbarEvents.sidebarOpen\"\n id=\"sidebarContainer\"\n [url]=\"url\"\n [zoom]=\"zoom\"\n [rotate]=\"rotation\"\n [outline]=\"documentOutline\"\n [annotationsEnabled]=\"enableAnnotations\"\n [currentPageNumber]=\"getCurrentPageNumber()\"\n>\n</mv-side-bar>\n<mv-comment-set-header\n *ngIf=\"enableAnnotations\"\n [ngClass]=\"{ 'show-comments-panel': showCommentsPanel }\"\n [isHidden]=\"!showCommentsPanel\"\n [showCommentSummary]=\"toolbarButtons.showCommentSummary\"\n (showCommentSummaryDialog)=\"toggleCommentsSummary()\"\n>\n</mv-comment-set-header>\n<mv-participants-list></mv-participants-list>\n<div\n class=\"pdfContainer\"\n [ngStyle]=\"{ height: height }\"\n [ngClass]=\"{ pdfContainer: true, hidden: errorMessage }\"\n>\n <mv-redaction-search-bar></mv-redaction-search-bar>\n <div\n #viewerContainer\n mvGrabNDrag\n [dragX]=\"viewerContainer\"\n [dragEnabled]=\"enableGrabNDrag\"\n id=\"viewerContainer\"\n class=\"viewer-container\"\n [class.annotations]=\"enableAnnotations\"\n [class.show-comments-panel]=\"\n (showCommentsPanel || showIcpParticipantsList) &&\n (toolbarEvents.redactionMode | async) !== true\n \"\n [class.grabNDrag]=\"enableGrabNDrag\"\n >\n <div\n #pdfViewer\n class=\"pdfViewer\"\n mvCreateTextHighlight\n [ngClass]=\"{\n hidden: false,\n highlightMode: highlightMode | async,\n drawMode: drawMode | async\n }\"\n ></div>\n <mv-redactions\n *ngIf=\"toolbarEvents.redactionMode | async; else annotationTemplate\"\n [zoom]=\"zoom\"\n [rotate]=\"rotation\"\n ></mv-redactions>\n <ng-template #annotationTemplate>\n <mv-metadata-layer\n *ngIf=\"enableAnnotations && annotationSet\"\n [zoom]=\"zoom\"\n [rotate]=\"rotation\"\n >\n </mv-metadata-layer>\n <mv-bookmark-icons [zoom]=\"zoom\" [rotate]=\"rotation\"> </mv-bookmark-icons>\n </ng-template>\n </div>\n <mv-comment-set\n [contentScrollTop]=\"viewerContainer.scrollTop\"\n *ngIf=\"\n enableAnnotations &&\n annotationSet &&\n (toolbarEvents.redactionMode | async) !== true\n \"\n [annotationSet]=\"annotationSet\"\n [zoom]=\"zoom\"\n [rotate]=\"rotation\"\n [height]=\"pdfViewer.offsetHeight\"\n [pageHeights]=\"pageHeights\"\n >\n </mv-comment-set>\n <div class=\"loadingMessage\" *ngIf=\"loadingDocument\">\n <h3 class=\"govuk-heading-m\">\n {{ \"Loading...\" | rpxTranslate}}{{\n loadingDocumentProgress ? loadingDocumentProgress + \"%\" : \"\"\n }}\n </h3>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: RedactionSearchBarComponent, selector: "mv-redaction-search-bar" }, { kind: "component", type: CommentSetComponent, selector: "mv-comment-set", inputs: ["annotationSet", "zoom", "rotate", "height", "pageHeights", "contentScrollTop"] }, { kind: "component", type: CommentSetHeaderComponent, selector: "mv-comment-set-header", inputs: ["showCommentSummary", "isHidden"], outputs: ["showCommentSummaryDialog"] }, { kind: "component", type: MetadataLayerComponent, selector: "mv-metadata-layer", inputs: ["zoom", "rotate"] }, { kind: "component", type: SideBarComponent, selector: "mv-side-bar", inputs: ["annotationsEnabled", "outline", "url", "zoom", "rotate", "currentPageNumber"] }, { kind: "directive", type: GrabNDragDirective, selector: "[mvGrabNDrag]", inputs: ["dragEnabled", "dragX"] }, { kind: "directive", type: HighlightCreateDirective, selector: "[mvCreateTextHighlight]" }, { kind: "component", type: RedactionComponent, selector: "mv-redactions", inputs: ["zoom", "rotate"] }, { kind: "component", type: BookmarkIconsComponent, selector: "mv-bookmark-icons", inputs: ["zoom", "rotate"] }, { kind: "component", type: ParticipantsListComponent, selector: "mv-participants-list" }, { kind: "pipe", type: i5.AsyncPipe, name: "async" }, { kind: "pipe", type: i5$1.RpxTranslatePipe, name: "rpxTranslate" }], encapsulation: i0.ViewEncapsulation.None }); }
5878
+ /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: PdfViewerComponent, selector: "mv-pdf-viewer", inputs: { downloadUrl: "downloadUrl", url: "url", downloadFileName: "downloadFileName", enableAnnotations: "enableAnnotations", enableRedactions: "enableRedactions", enableICP: "enableICP", annotationSet: "annotationSet", enableRedactSearch: "enableRedactSearch", height: "height", caseId: "caseId", searchBarHidden: "searchBarHidden" }, outputs: { mediaLoadStatus: "mediaLoadStatus", pdfViewerException: "pdfViewerException", documentTitle: "documentTitle" }, viewQueries: [{ propertyName: "viewerContainer", first: true, predicate: ["viewerContainer"], descendants: true, static: true }, { propertyName: "pdfViewer", first: true, predicate: ["pdfViewer"], descendants: true }, { propertyName: "highlightCreateDirective", first: true, predicate: HighlightCreateDirective, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<mv-side-bar\n *ngIf=\"toolbarEvents.sidebarOpen\"\n id=\"sidebarContainer\"\n [url]=\"url\"\n [zoom]=\"zoom\"\n [rotate]=\"rotation\"\n [outline]=\"documentOutline\"\n [annotationsEnabled]=\"enableAnnotations\"\n [currentPageNumber]=\"getCurrentPageNumber()\"\n>\n</mv-side-bar>\n<mv-comment-set-header\n *ngIf=\"enableAnnotations\"\n [ngClass]=\"{ 'show-comments-panel': showCommentsPanel }\"\n [isHidden]=\"!showCommentsPanel\"\n [showCommentSummary]=\"toolbarButtons.showCommentSummary\"\n (showCommentSummaryDialog)=\"toggleCommentsSummary()\"\n>\n</mv-comment-set-header>\n<mv-participants-list></mv-participants-list>\n<div\n class=\"pdfContainer\"\n [ngStyle]=\"{ height: height }\"\n [ngClass]=\"{ pdfContainer: true, hidden: errorMessage }\"\n>\n <mv-redaction-search-bar></mv-redaction-search-bar>\n <div\n #viewerContainer\n mvGrabNDrag\n [dragX]=\"viewerContainer\"\n [dragEnabled]=\"enableGrabNDrag\"\n id=\"viewerContainer\"\n class=\"viewer-container\"\n [class.annotations]=\"enableAnnotations\"\n [class.show-comments-panel]=\"\n (showCommentsPanel || showIcpParticipantsList) &&\n (toolbarEvents.redactionMode | async) !== true\n \"\n [class.grabNDrag]=\"enableGrabNDrag\"\n >\n <div\n #pdfViewer\n class=\"pdfViewer\"\n mvCreateTextHighlight\n mvKeyboardTextHighlight\n [enabled]=\"highlightMode | async\"\n [tabindex]=\"(highlightMode | async) ? 0 : -1\"\n (selectionConfirmed)=\"onKeyboardTextSelectionConfirmed()\"\n (selectionCancelled)=\"onKeyboardTextSelectionCancelled()\"\n (cursorPositionChanged)=\"onSelectionStartCursorChanged($event)\"\n (selectionCursorPositionChanged)=\"onSelectionEndCursorChanged($event)\"\n [ngClass]=\"{\n hidden: false,\n highlightMode: highlightMode | async,\n drawMode: drawMode | async\n }\"\n ></div>\n <div *ngIf=\"showSelectionStartCursor\"\n class=\"selection-start-cursor\"\n [style.position]=\"'fixed'\"\n [style.top]=\"selectionStartCursorY + 'px'\"\n [style.left]=\"selectionStartCursorX + 'px'\">\n </div>\n <div *ngIf=\"showSelectionEndCursor\"\n class=\"selection-end-cursor\"\n [style.position]=\"'fixed'\"\n [style.top]=\"selectionEndCursorY + 'px'\"\n [style.left]=\"selectionEndCursorX + 'px'\">\n </div>\n <mv-redactions\n *ngIf=\"toolbarEvents.redactionMode | async; else annotationTemplate\"\n [zoom]=\"zoom\"\n [rotate]=\"rotation\"\n ></mv-redactions>\n <ng-template #annotationTemplate>\n <mv-metadata-layer\n *ngIf=\"enableAnnotations && annotationSet\"\n [zoom]=\"zoom\"\n [rotate]=\"rotation\"\n >\n </mv-metadata-layer>\n <mv-bookmark-icons [zoom]=\"zoom\" [rotate]=\"rotation\"> </mv-bookmark-icons>\n </ng-template>\n </div>\n <mv-comment-set\n [contentScrollTop]=\"viewerContainer.scrollTop\"\n *ngIf=\"\n enableAnnotations &&\n annotationSet &&\n (toolbarEvents.redactionMode | async) !== true\n \"\n [annotationSet]=\"annotationSet\"\n [zoom]=\"zoom\"\n [rotate]=\"rotation\"\n [height]=\"pdfViewer.offsetHeight\"\n [pageHeights]=\"pageHeights\"\n >\n </mv-comment-set>\n <div class=\"loadingMessage\" *ngIf=\"loadingDocument\">\n <h3 class=\"govuk-heading-m\">\n {{ \"Loading...\" | rpxTranslate}}{{\n loadingDocumentProgress ? loadingDocumentProgress + \"%\" : \"\"\n }}\n </h3>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: RedactionSearchBarComponent, selector: "mv-redaction-search-bar" }, { kind: "component", type: CommentSetComponent, selector: "mv-comment-set", inputs: ["annotationSet", "zoom", "rotate", "height", "pageHeights", "contentScrollTop"] }, { kind: "component", type: CommentSetHeaderComponent, selector: "mv-comment-set-header", inputs: ["showCommentSummary", "isHidden"], outputs: ["showCommentSummaryDialog"] }, { kind: "component", type: MetadataLayerComponent, selector: "mv-metadata-layer", inputs: ["zoom", "rotate"] }, { kind: "component", type: SideBarComponent, selector: "mv-side-bar", inputs: ["annotationsEnabled", "outline", "url", "zoom", "rotate", "currentPageNumber"] }, { kind: "directive", type: GrabNDragDirective, selector: "[mvGrabNDrag]", inputs: ["dragEnabled", "dragX"] }, { kind: "directive", type: HighlightCreateDirective, selector: "[mvCreateTextHighlight]" }, { kind: "directive", type: KeyboardTextHighlightDirective, selector: "[mvKeyboardTextHighlight]", inputs: ["enabled", "incrementSmall", "incrementMedium", "incrementLarge"], outputs: ["selectionStarted", "selectionUpdated", "selectionConfirmed", "selectionCancelled", "cursorPositionChanged", "selectionCursorPositionChanged"] }, { kind: "component", type: RedactionComponent, selector: "mv-redactions", inputs: ["zoom", "rotate"] }, { kind: "component", type: BookmarkIconsComponent, selector: "mv-bookmark-icons", inputs: ["zoom", "rotate"] }, { kind: "component", type: ParticipantsListComponent, selector: "mv-participants-list" }, { kind: "pipe", type: i5.AsyncPipe, name: "async" }, { kind: "pipe", type: i5$1.RpxTranslatePipe, name: "rpxTranslate" }], encapsulation: i0.ViewEncapsulation.None }); }
5398
5879
  }
5399
5880
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: PdfViewerComponent, decorators: [{
5400
5881
  type: Component,
5401
- args: [{ selector: 'mv-pdf-viewer', encapsulation: ViewEncapsulation.None, template: "<mv-side-bar\n *ngIf=\"toolbarEvents.sidebarOpen\"\n id=\"sidebarContainer\"\n [url]=\"url\"\n [zoom]=\"zoom\"\n [rotate]=\"rotation\"\n [outline]=\"documentOutline\"\n [annotationsEnabled]=\"enableAnnotations\"\n [currentPageNumber]=\"getCurrentPageNumber()\"\n>\n</mv-side-bar>\n<mv-comment-set-header\n *ngIf=\"enableAnnotations\"\n [ngClass]=\"{ 'show-comments-panel': showCommentsPanel }\"\n [isHidden]=\"!showCommentsPanel\"\n [showCommentSummary]=\"toolbarButtons.showCommentSummary\"\n (showCommentSummaryDialog)=\"toggleCommentsSummary()\"\n>\n</mv-comment-set-header>\n<mv-participants-list></mv-participants-list>\n<div\n class=\"pdfContainer\"\n [ngStyle]=\"{ height: height }\"\n [ngClass]=\"{ pdfContainer: true, hidden: errorMessage }\"\n>\n <mv-redaction-search-bar></mv-redaction-search-bar>\n <div\n #viewerContainer\n mvGrabNDrag\n [dragX]=\"viewerContainer\"\n [dragEnabled]=\"enableGrabNDrag\"\n id=\"viewerContainer\"\n class=\"viewer-container\"\n [class.annotations]=\"enableAnnotations\"\n [class.show-comments-panel]=\"\n (showCommentsPanel || showIcpParticipantsList) &&\n (toolbarEvents.redactionMode | async) !== true\n \"\n [class.grabNDrag]=\"enableGrabNDrag\"\n >\n <div\n #pdfViewer\n class=\"pdfViewer\"\n mvCreateTextHighlight\n [ngClass]=\"{\n hidden: false,\n highlightMode: highlightMode | async,\n drawMode: drawMode | async\n }\"\n ></div>\n <mv-redactions\n *ngIf=\"toolbarEvents.redactionMode | async; else annotationTemplate\"\n [zoom]=\"zoom\"\n [rotate]=\"rotation\"\n ></mv-redactions>\n <ng-template #annotationTemplate>\n <mv-metadata-layer\n *ngIf=\"enableAnnotations && annotationSet\"\n [zoom]=\"zoom\"\n [rotate]=\"rotation\"\n >\n </mv-metadata-layer>\n <mv-bookmark-icons [zoom]=\"zoom\" [rotate]=\"rotation\"> </mv-bookmark-icons>\n </ng-template>\n </div>\n <mv-comment-set\n [contentScrollTop]=\"viewerContainer.scrollTop\"\n *ngIf=\"\n enableAnnotations &&\n annotationSet &&\n (toolbarEvents.redactionMode | async) !== true\n \"\n [annotationSet]=\"annotationSet\"\n [zoom]=\"zoom\"\n [rotate]=\"rotation\"\n [height]=\"pdfViewer.offsetHeight\"\n [pageHeights]=\"pageHeights\"\n >\n </mv-comment-set>\n <div class=\"loadingMessage\" *ngIf=\"loadingDocument\">\n <h3 class=\"govuk-heading-m\">\n {{ \"Loading...\" | rpxTranslate}}{{\n loadingDocumentProgress ? loadingDocumentProgress + \"%\" : \"\"\n }}\n </h3>\n </div>\n</div>\n" }]
5882
+ args: [{ selector: 'mv-pdf-viewer', encapsulation: ViewEncapsulation.None, template: "<mv-side-bar\n *ngIf=\"toolbarEvents.sidebarOpen\"\n id=\"sidebarContainer\"\n [url]=\"url\"\n [zoom]=\"zoom\"\n [rotate]=\"rotation\"\n [outline]=\"documentOutline\"\n [annotationsEnabled]=\"enableAnnotations\"\n [currentPageNumber]=\"getCurrentPageNumber()\"\n>\n</mv-side-bar>\n<mv-comment-set-header\n *ngIf=\"enableAnnotations\"\n [ngClass]=\"{ 'show-comments-panel': showCommentsPanel }\"\n [isHidden]=\"!showCommentsPanel\"\n [showCommentSummary]=\"toolbarButtons.showCommentSummary\"\n (showCommentSummaryDialog)=\"toggleCommentsSummary()\"\n>\n</mv-comment-set-header>\n<mv-participants-list></mv-participants-list>\n<div\n class=\"pdfContainer\"\n [ngStyle]=\"{ height: height }\"\n [ngClass]=\"{ pdfContainer: true, hidden: errorMessage }\"\n>\n <mv-redaction-search-bar></mv-redaction-search-bar>\n <div\n #viewerContainer\n mvGrabNDrag\n [dragX]=\"viewerContainer\"\n [dragEnabled]=\"enableGrabNDrag\"\n id=\"viewerContainer\"\n class=\"viewer-container\"\n [class.annotations]=\"enableAnnotations\"\n [class.show-comments-panel]=\"\n (showCommentsPanel || showIcpParticipantsList) &&\n (toolbarEvents.redactionMode | async) !== true\n \"\n [class.grabNDrag]=\"enableGrabNDrag\"\n >\n <div\n #pdfViewer\n class=\"pdfViewer\"\n mvCreateTextHighlight\n mvKeyboardTextHighlight\n [enabled]=\"highlightMode | async\"\n [tabindex]=\"(highlightMode | async) ? 0 : -1\"\n (selectionConfirmed)=\"onKeyboardTextSelectionConfirmed()\"\n (selectionCancelled)=\"onKeyboardTextSelectionCancelled()\"\n (cursorPositionChanged)=\"onSelectionStartCursorChanged($event)\"\n (selectionCursorPositionChanged)=\"onSelectionEndCursorChanged($event)\"\n [ngClass]=\"{\n hidden: false,\n highlightMode: highlightMode | async,\n drawMode: drawMode | async\n }\"\n ></div>\n <div *ngIf=\"showSelectionStartCursor\"\n class=\"selection-start-cursor\"\n [style.position]=\"'fixed'\"\n [style.top]=\"selectionStartCursorY + 'px'\"\n [style.left]=\"selectionStartCursorX + 'px'\">\n </div>\n <div *ngIf=\"showSelectionEndCursor\"\n class=\"selection-end-cursor\"\n [style.position]=\"'fixed'\"\n [style.top]=\"selectionEndCursorY + 'px'\"\n [style.left]=\"selectionEndCursorX + 'px'\">\n </div>\n <mv-redactions\n *ngIf=\"toolbarEvents.redactionMode | async; else annotationTemplate\"\n [zoom]=\"zoom\"\n [rotate]=\"rotation\"\n ></mv-redactions>\n <ng-template #annotationTemplate>\n <mv-metadata-layer\n *ngIf=\"enableAnnotations && annotationSet\"\n [zoom]=\"zoom\"\n [rotate]=\"rotation\"\n >\n </mv-metadata-layer>\n <mv-bookmark-icons [zoom]=\"zoom\" [rotate]=\"rotation\"> </mv-bookmark-icons>\n </ng-template>\n </div>\n <mv-comment-set\n [contentScrollTop]=\"viewerContainer.scrollTop\"\n *ngIf=\"\n enableAnnotations &&\n annotationSet &&\n (toolbarEvents.redactionMode | async) !== true\n \"\n [annotationSet]=\"annotationSet\"\n [zoom]=\"zoom\"\n [rotate]=\"rotation\"\n [height]=\"pdfViewer.offsetHeight\"\n [pageHeights]=\"pageHeights\"\n >\n </mv-comment-set>\n <div class=\"loadingMessage\" *ngIf=\"loadingDocument\">\n <h3 class=\"govuk-heading-m\">\n {{ \"Loading...\" | rpxTranslate}}{{\n loadingDocumentProgress ? loadingDocumentProgress + \"%\" : \"\"\n }}\n </h3>\n </div>\n</div>\n" }]
5402
5883
  }], ctorParameters: () => [{ type: i1.Store }, { type: i1.Store }, { type: PdfJsWrapperFactory }, { type: PrintService }, { type: ToolbarEventService }, { type: ViewerEventService }, { type: IcpService }, { type: ToolbarButtonVisibilityService }, { type: IcpEventService }], propDecorators: { mediaLoadStatus: [{
5403
5884
  type: Output
5404
5885
  }], pdfViewerException: [{
@@ -5431,6 +5912,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
5431
5912
  }], pdfViewer: [{
5432
5913
  type: ViewChild,
5433
5914
  args: ['pdfViewer', { static: false }]
5915
+ }], highlightCreateDirective: [{
5916
+ type: ViewChild,
5917
+ args: [HighlightCreateDirective, { static: false }]
5434
5918
  }], searchBarHidden: [{
5435
5919
  type: Input
5436
5920
  }] } });
@@ -5820,6 +6304,40 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
5820
6304
  args: ['window:keydown', ['$event']]
5821
6305
  }] } });
5822
6306
 
6307
+ class TooltipDismissDirective {
6308
+ constructor(el) {
6309
+ this.el = el;
6310
+ }
6311
+ onEscapeDismissTooltip() {
6312
+ const element = this.el.nativeElement;
6313
+ element.setAttribute('data-tooltip-dismissed', 'true');
6314
+ }
6315
+ onShowTooltip() {
6316
+ const element = this.el.nativeElement;
6317
+ element.removeAttribute('data-tooltip-dismissed');
6318
+ }
6319
+ /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TooltipDismissDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); }
6320
+ /** @nocollapse */ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.13", type: TooltipDismissDirective, selector: ".mv-tooltip, [mvTooltipDismiss]", host: { listeners: { "document:keydown.escape": "onEscapeDismissTooltip($event)", "mouseenter": "onShowTooltip()", "focus": "onShowTooltip()", "focusin": "onShowTooltip()" } }, ngImport: i0 }); }
6321
+ }
6322
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TooltipDismissDirective, decorators: [{
6323
+ type: Directive,
6324
+ args: [{
6325
+ selector: '.mv-tooltip, [mvTooltipDismiss]'
6326
+ }]
6327
+ }], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { onEscapeDismissTooltip: [{
6328
+ type: HostListener,
6329
+ args: ['document:keydown.escape', ['$event']]
6330
+ }], onShowTooltip: [{
6331
+ type: HostListener,
6332
+ args: ['mouseenter']
6333
+ }, {
6334
+ type: HostListener,
6335
+ args: ['focus']
6336
+ }, {
6337
+ type: HostListener,
6338
+ args: ['focusin']
6339
+ }] } });
6340
+
5823
6341
  class MainToolbarComponent {
5824
6342
  constructor(toolbarEvents, toolbarButtons, cdr, numberHelper, icpEventService) {
5825
6343
  this.toolbarEvents = toolbarEvents;
@@ -5980,11 +6498,11 @@ class MainToolbarComponent {
5980
6498
  }, 100);
5981
6499
  }
5982
6500
  /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: MainToolbarComponent, deps: [{ token: ToolbarEventService }, { token: ToolbarButtonVisibilityService }, { token: i0.ChangeDetectorRef }, { token: NumberHelperService }, { token: IcpEventService }], target: i0.ɵɵFactoryTarget.Component }); }
5983
- /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: MainToolbarComponent, selector: "mv-main-toolbar", inputs: { enableAnnotations: "enableAnnotations", enableRedactions: "enableRedactions", enableICP: "enableICP", contentType: "contentType" }, host: { listeners: { "window:resize": "onResize()", "document:keydown.control.p": "onControlPrint($event)", "document:keydown.meta.p": "onControlPrint($event)" } }, viewQueries: [{ propertyName: "zoomSelect", first: true, predicate: ["zoomSelect"], descendants: true }, { propertyName: "mvToolbarMain", first: true, predicate: ["mvToolbarMain"], descendants: true }, { propertyName: "mvMenuItems", first: true, predicate: ["dropdownMenu"], descendants: true }], ngImport: i0, template: "<div class=\"toolbar\">\n <div id=\"toolbarContainer\">\n <div class=\"mv-toolbar__container\">\n <div #mvToolbar class=\"mv-toolbar\" [class.notSupported]=\"!contentType\">\n <!-- The mvToolbarMain div contains all toolbar buttons except the \"More options\" button. This allows for calculation of the available space to display buttons -->\n <div id=\"mvToolbarMain\" class=\"mv-toolbar-main\" #mvToolbarMain>\n <ng-container *ngTemplateOutlet=\"menuItems\"></ng-container>\n </div>\n <!-- The mvToolbarMoreOptions div contains the \"More options\" toolbar button (and the overlay template for the dropdown menu).\n The space occupied by the button (if visible) is excluded from the toolbar space available calculation -->\n <div id=\"mvToolbarMoreOptions\" class=\"mv-toolbar-more-options\">\n <button\n id=\"mvMoreOptionsBtn\"\n class=\"mv-button mv-toolbar__menu-button--more-options\"\n [class.mv-toolbar__menu-button--more-options__hidden]=\"\n mvToolbar.offsetWidth >= allButtonsWidth\n \"\n [attr.aria-expanded]=\"isDropdownMenuOpen\"\n (click)=\"toggleMoreOptions()\"\n cdkOverlayOrigin\n #trigger=\"cdkOverlayOrigin\"\n [disabled]=\"redactAllInProgress\"\n >\n <span>{{ \"More options\" | rpxTranslate }}</span>\n </button>\n <!-- This template displays the overlay content for the dropdown menu and is connected to the \"More options\" button -->\n <ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"trigger\"\n [cdkConnectedOverlayOpen]=\"isDropdownMenuOpen\"\n [cdkConnectedOverlayPositions]=\"dropdownMenuPositions\"\n >\n <div class=\"dropdown-menu\" #dropdownMenu tabindex=\"0\">\n <ng-container *ngTemplateOutlet=\"menuItems\"></ng-container>\n </div>\n </ng-template>\n </div>\n </div>\n\n <div id=\"mvMenuItems\" #mvMenuItems>\n <ng-template #menuItems>\n <button\n *ngIf=\"toolbarButtons.showSidebar\"\n id=\"mvIndexBtn\"\n title=\"Index\"\n data-l10n-id=\"index\"\n #mvIndexBtn\n class=\"mv-button mv-toolbar__menu-button--index\"\n [class.button-hidden-on-toolbar]=\"\n mvToolbarMain.offsetWidth < widthRequiredForBtn['mvIndexBtn']\n \"\n [class.button-hidden-on-dropdown]=\"\n mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvIndexBtn']\n \"\n [attr.aria-expanded]=\"isIndexOpen\"\n [disabled]=\"redactAllInProgress\"\n (click)=\"toggleIndexSideBar(); isDropdownMenuOpen = false\"\n >\n <span>{{ \"Index\" | rpxTranslate }}</span>\n </button>\n\n <button\n *ngIf=\"toolbarButtons.showSidebar\"\n id=\"mvBookmarksBtn\"\n title=\"Bookmarks\"\n data-l10n-id=\"bookmarks\"\n #mvBookmarksBtn\n [ngClass]=\"{\n 'mv-button mv-toolbar__menu-button--bookmarks': true,\n 'button-hidden-on-toolbar':\n mvToolbarMain.offsetWidth <\n widthRequiredForBtn['mvBookmarksBtn'],\n 'button-hidden-on-dropdown':\n mvToolbarMain.offsetWidth >=\n widthRequiredForBtn['mvBookmarksBtn']\n }\"\n [attr.aria-expanded]=\"isBookmarksOpen\"\n [disabled]=\"redactAllInProgress\"\n (click)=\"toggleBookmarksSideBar(); isDropdownMenuOpen = false\"\n >\n <span>{{ \"Bookmarks\" | rpxTranslate }}</span>\n </button>\n\n <button\n *ngIf=\"toolbarButtons.showDrawButton\"\n [disabled]=\"icpEnabled || redactionEnabled\"\n id=\"mvDrawBtn\"\n #mvDrawBtn\n class=\"mv-button mv-toolbar__menu-button--draw\"\n title=\"Draw a box\"\n [class.button-hidden-on-toolbar]=\"\n mvToolbarMain.offsetWidth < widthRequiredForBtn['mvDrawBtn']\n \"\n [class.button-hidden-on-dropdown]=\"\n mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvDrawBtn']\n \"\n [class.toggled]=\"toolbarEvents.drawModeSubject | async\"\n aria-pressed=\"false\"\n data-l10n-id=\"toggleDrawButton\"\n (click)=\"onClickDrawToggle(); isDropdownMenuOpen = false\"\n >\n <span data-l10n-id=\"draw_label\">{{\n \"Draw a box\" | rpxTranslate\n }}</span>\n </button>\n\n <button\n *ngIf=\"toolbarButtons.showHighlightButton\"\n [disabled]=\"icpEnabled || redactionEnabled\"\n id=\"mvHighlightBtn\"\n #mvHighlightBtn\n class=\"mv-button mv-toolbar__menu-button--highlight\"\n title=\"Highlight\"\n aria-label=\"Highlight\"\n [class.button-hidden-on-toolbar]=\"\n mvToolbarMain.offsetWidth < widthRequiredForBtn['mvHighlightBtn']\n \"\n [class.button-hidden-on-dropdown]=\"\n mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvHighlightBtn']\n \"\n [class.toggled]=\"toolbarEvents.highlightToolbarSubject | async\"\n aria-pressed=\"false\"\n (click)=\"onClickHighlightToggle(); isDropdownMenuOpen = false\"\n data-l10n-id=\"toggleHighlightButton\"\n >\n <span data-l10n-id=\"highlight_label\">{{\n \"Highlight\" | rpxTranslate\n }}</span>\n </button>\n\n <ng-container *ngIf=\"toolbarButtons.showNavigation\">\n <div\n id=\"mvPageBtn\"\n #mvPageBtn\n class=\"mv-toolbar__menu-button--page\"\n [class.button-hidden-on-toolbar]=\"\n mvToolbarMain.offsetWidth < widthRequiredForBtn['mvPageBtn']\n \"\n [class.button-hidden-on-dropdown]=\"\n mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvPageBtn']\n \"\n >\n <span>{{ \"Page\" | rpxTranslate }}</span>\n\n <button\n id=\"mvUpBtn\"\n [disabled]=\"pageNumber === 1 || redactAllInProgress\"\n title=\"Previous Page\"\n class=\"mv-toolbar__menu-button--up button-image\"\n data-l10n-id=\"previous\"\n (click)=\"decreasePageNumber()\"\n [disabled]=\"redactAllInProgress\"\n >\n <span></span>\n </button>\n <button\n id=\"mvDownBtn\"\n [disabled]=\"pageNumber === pageCount || redactAllInProgress\"\n title=\"Next Page\"\n class=\"mv-toolbar__menu-button--down button-image\"\n data-l10n-id=\"next\"\n (click)=\"increasePageNumber()\"\n >\n <span></span>\n </button>\n\n <input\n type=\"number\"\n id=\"pageNumber\"\n class=\"hmcts-toolbar-input govuk-input--width-2\"\n title=\"Page Number\"\n value=\"1\"\n size=\"4\"\n min=\"1\"\n [value]=\"pageNumber\"\n aria-label=\"page number\"\n tabindex=\"0\"\n data-l10n-id=\"page\"\n (change)=\"onPageNumberInputChange(pageNumberInput.value)\"\n [disabled]=\"redactAllInProgress\"\n #pageNumberInput\n />\n <span id=\"numPages\" class=\"toolbarLabel\">/ {{ pageCount }}</span>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"toolbarButtons.showZoom\">\n <div\n id=\"mvZoomBtn\"\n #mvZoomBtn\n class=\"mv-toolbar__menu-button--zoom\"\n aria-pressed=\"false\"\n [class.button-hidden-on-toolbar]=\"\n mvToolbarMain.offsetWidth < widthRequiredForBtn['mvZoomBtn']\n \"\n [class.button-hidden-on-dropdown]=\"\n mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvZoomBtn']\n \"\n >\n <button\n [disabled]=\"\n toolbarEvents.zoomValueSubject.value === 0.1 ||\n redactAllInProgress\n \"\n id=\"mvMinusBtn\"\n class=\"mv-toolbar__menu-button--zoom-out button-image\"\n title=\"Zoom Out\"\n data-l10n-id=\"zoom_out\"\n (click)=\"stepZoom(-0.1)\"\n >\n <span class=\"mv-toolbar__menu-button--zoom-out-text\">{{\n \"Zoom Out\" | rpxTranslate\n }}</span>\n </button>\n <select\n id=\"scaleSelect\"\n class=\"hmcts-toolbar-select\"\n title=\"Zoom\"\n tabindex=\"0\"\n data-l10n-id=\"zoom\"\n (change)=\"zoom($event.target.value)\"\n aria-label=\"zoom\"\n [disabled]=\"redactAllInProgress\"\n >\n <option\n #zoomSelect\n id=\"customScaleOption\"\n title=\"\"\n [value]=\"toolbarEvents.zoomValueSubject.value\"\n >\n {{\n toolbarEvents.zoomValueSubject.value * 100\n | number : \"1.0-0\"\n }}%\n </option>\n <option\n *ngFor=\"let zoomScale of zoomScales\"\n title=\"\"\n [value]=\"zoomScale\"\n [attr.data-l10n-id]=\"'page_scale_percent_' + zoomScale * 100\"\n >\n {{ zoomScale * 100 }}%\n </option>\n </select>\n\n <button\n [disabled]=\"\n toolbarEvents.zoomValueSubject.value === 5 ||\n redactAllInProgress\n \"\n id=\"mvPlusBtn\"\n class=\"mv-toolbar__menu-button--zoom-in button-image\"\n (click)=\"stepZoom(0.1)\"\n title=\"Zoom In\"\n data-l10n-id=\"zoom_in\"\n >\n <span class=\"mv-toolbar__menu-button--zoom-out-text\">{{\n \"Zoom In\" | rpxTranslate\n }}</span>\n </button>\n </div>\n </ng-container>\n\n <div\n *ngIf=\"toolbarButtons.showRotate\"\n id=\"mvRotateBtn\"\n #mvRotateBtn\n class=\"mv-toolbar__menu-button--rotate\"\n [class.button-hidden-on-toolbar]=\"\n mvToolbarMain.offsetWidth < widthRequiredForBtn['mvRotateBtn']\n \"\n [class.button-hidden-on-dropdown]=\"\n mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvRotateBtn']\n \"\n >\n <button\n id=\"mvRotateLeftBtn\"\n class=\"mv-toolbar__menu-button--rotate_left button-image\"\n title=\"Rotate Counterclockwise\"\n data-l10n-id=\"page_rotate_ccw\"\n (click)=\"rotate(270)\"\n [disabled]=\"redactAllInProgress\"\n >\n <span></span>\n </button>\n <button\n id=\"mvRotateRightBtn\"\n class=\"mv-toolbar__menu-button--rotate_right button-image\"\n title=\"Rotate Clockwise\"\n data-l10n-id=\"page_rotate_cw\"\n (click)=\"rotate(90)\"\n [disabled]=\"redactAllInProgress\"\n >\n <span></span>\n </button>\n <span>{{ \"Rotate\" | rpxTranslate }}</span>\n </div>\n\n <button\n *ngIf=\"toolbarButtons.showSearchBar\"\n [disabled]=\"icpEnabled || redactAllInProgress\"\n id=\"mvSearchBtn\"\n #mvSearchBtn\n title=\"Search\"\n data-l10n-id=\"searchbar\"\n class=\"mv-button mv-toolbar__menu-button--search\"\n [class.button-hidden-on-toolbar]=\"\n mvToolbarMain.offsetWidth < widthRequiredForBtn['mvSearchBtn']\n \"\n [class.button-hidden-on-dropdown]=\"\n mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvSearchBtn']\n \"\n aria-pressed=\"false\"\n (click)=\"toggleSearchBar(); isDropdownMenuOpen = false\"\n >\n <span>{{ \"Search\" | rpxTranslate }}</span>\n </button>\n <mv-search-bar\n *ngIf=\"!toolbarEvents.searchBarHidden.getValue()\"\n ></mv-search-bar>\n\n <button\n *ngIf=\"enableICP && toolbarButtons.showPresentationMode && isPdf()\"\n [disabled]=\"icpEnabled || !contentType || redactionEnabled\"\n id=\"mvPresentBtn\"\n #mvPresentBtn\n class=\"mv-button mv-toolbar__menu-button--present\"\n title=\"In-Court Presentation Mode\"\n data-l10n-id=\"icpMode_label\"\n [ngClass]=\"onToolBarOffSetChange('mvPresentBtn')\"\n aria-pressed=\"false\"\n (click)=\"togglePresentBar(); isDropdownMenuOpen = false\"\n >\n <span data-l10n-id=\"icpMode_label\">{{\n \"Present\" | rpxTranslate\n }}</span>\n </button>\n\n <button\n *ngIf=\"enableRedactions && toolbarButtons.showRedact\"\n [disabled]=\"icpEnabled || redactAllInProgress\"\n id=\"mvRedactBtn\"\n #mvRedactBtn\n title=\"Redact\"\n data-l10n-id=\"redact\"\n class=\"mv-button mv-toolbar__menu-button--redact\"\n [ngClass]=\"onToolBarOffSetChange('mvRedactBtn')\"\n [attr.aria-expanded]=\"isRedactOpen\"\n (click)=\"toggleRedactBar(); isDropdownMenuOpen = false\"\n >\n <span>{{ \"Redact\" | rpxTranslate }}</span>\n </button>\n\n <button\n *ngIf=\"toolbarButtons.showGrabNDragButton\"\n [disabled]=\"icpEnabled || redactAllInProgress\"\n id=\"mvGrabBtn\"\n #mvGrabBtn\n class=\"mv-button mv-toolbar__menu-button--grab\"\n title=\"Grab and drag\"\n [ngClass]=\"onToolBarOffSetChange('mvGrabBtn')\"\n aria-pressed=\"false\"\n (click)=\"toggleGrabNDrag(); isDropdownMenuOpen = false\"\n >\n <span>{{ \"Grab and drag\" | rpxTranslate }}</span>\n </button>\n\n <button\n *ngIf=\"toolbarButtons.showDownload\"\n [disabled]=\"icpEnabled || redactionEnabled\"\n id=\"mvDownloadBtn\"\n #mvDownloadBtn\n class=\"mv-button mv-toolbar__menu-button--download\"\n title=\"Download\"\n data-l10n-id=\"download\"\n [ngClass]=\"onToolBarOffSetChange('mvDownloadBtn')\"\n aria-pressed=\"false\"\n (click)=\"downloadFile(); isDropdownMenuOpen = false\"\n >\n <span>{{ \"Download\" | rpxTranslate }}</span>\n </button>\n\n <button\n *ngIf=\"toolbarButtons.showPrint\"\n [disabled]=\"icpEnabled || redactionEnabled\"\n id=\"mvPrintBtn\"\n #mvPrintBtn\n title=\"Print\"\n data-l10n-id=\"print\"\n class=\"mv-button mv-toolbar__menu-button--print\"\n [ngClass]=\"onToolBarOffSetChange('mvPrintBtn')\"\n aria-pressed=\"false\"\n (click)=\"printFile(); isDropdownMenuOpen = false\"\n >\n <span>{{ \"Print\" | rpxTranslate }}</span>\n </button>\n\n <button\n *ngIf=\"enableAnnotations && toolbarButtons.showCommentSummary\"\n [disabled]=\"redactionEnabled\"\n id=\"mvCommentsBtn\"\n #mvCommentsBtn\n class=\"mv-button mv-toolbar__menu-button--comments\"\n title=\"Comments\"\n data-l10n-id=\"comments\"\n [ngClass]=\"onToolBarOffSetChange('mvCommentsBtn')\"\n [attr.aria-expanded]=\"isCommentsOpen\"\n (click)=\"toggleCommentsPanel(); isDropdownMenuOpen = false\"\n >\n <span>{{ \"Comments\" | rpxTranslate }}</span>\n </button>\n </ng-template>\n </div>\n </div>\n\n <div id=\"loadingBar\">\n <div class=\"progress\">\n <div class=\"glimmer\"></div>\n </div>\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i7.CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "directive", type: i7.CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { kind: "component", type: SearchBarComponent, selector: "mv-search-bar" }, { kind: "pipe", type: i5.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.DecimalPipe, name: "number" }, { kind: "pipe", type: i5$1.RpxTranslatePipe, name: "rpxTranslate" }] }); }
6501
+ /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: MainToolbarComponent, selector: "mv-main-toolbar", inputs: { enableAnnotations: "enableAnnotations", enableRedactions: "enableRedactions", enableICP: "enableICP", contentType: "contentType" }, host: { listeners: { "window:resize": "onResize()", "document:keydown.control.p": "onControlPrint($event)", "document:keydown.meta.p": "onControlPrint($event)" } }, viewQueries: [{ propertyName: "zoomSelect", first: true, predicate: ["zoomSelect"], descendants: true }, { propertyName: "mvToolbarMain", first: true, predicate: ["mvToolbarMain"], descendants: true }, { propertyName: "mvMenuItems", first: true, predicate: ["dropdownMenu"], descendants: true }], ngImport: i0, template: "<div class=\"toolbar\">\n <div id=\"toolbarContainer\">\n <div class=\"mv-toolbar__container\">\n <div #mvToolbar class=\"mv-toolbar\" [class.notSupported]=\"!contentType\">\n <!-- The mvToolbarMain div contains all toolbar buttons except the \"More options\" button. This allows for calculation of the available space to display buttons -->\n <div id=\"mvToolbarMain\" class=\"mv-toolbar-main\" #mvToolbarMain>\n <ng-container *ngTemplateOutlet=\"menuItems\"></ng-container>\n </div>\n <!-- The mvToolbarMoreOptions div contains the \"More options\" toolbar button (and the overlay template for the dropdown menu).\n The space occupied by the button (if visible) is excluded from the toolbar space available calculation -->\n <div id=\"mvToolbarMoreOptions\" class=\"mv-toolbar-more-options\">\n <button\n id=\"mvMoreOptionsBtn\"\n class=\"mv-button mv-toolbar__menu-button--more-options mv-tooltip\"\n [class.mv-toolbar__menu-button--more-options__hidden]=\"\n mvToolbar.offsetWidth >= allButtonsWidth\n \"\n [attr.aria-expanded]=\"isDropdownMenuOpen\"\n [attr.data-tooltip]=\"'More options' | rpxTranslate\"\n (click)=\"toggleMoreOptions()\"\n cdkOverlayOrigin\n #trigger=\"cdkOverlayOrigin\"\n [disabled]=\"redactAllInProgress\"\n >\n <span>{{ \"More options\" | rpxTranslate }}</span>\n </button>\n <!-- This template displays the overlay content for the dropdown menu and is connected to the \"More options\" button -->\n <ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"trigger\"\n [cdkConnectedOverlayOpen]=\"isDropdownMenuOpen\"\n [cdkConnectedOverlayPositions]=\"dropdownMenuPositions\"\n >\n <div class=\"dropdown-menu\" #dropdownMenu tabindex=\"0\">\n <ng-container *ngTemplateOutlet=\"menuItems\"></ng-container>\n </div>\n </ng-template>\n </div>\n </div>\n <div id=\"mvMenuItems\" #mvMenuItems>\n <ng-template #menuItems>\n <button\n *ngIf=\"toolbarButtons.showSidebar\"\n id=\"mvIndexBtn\"\n data-l10n-id=\"index\"\n [attr.data-tooltip]=\"'Index' | rpxTranslate\"\n #mvIndexBtn\n class=\"mv-button mv-toolbar__menu-button--index mv-tooltip\"\n [class.button-hidden-on-toolbar]=\"\n mvToolbarMain.offsetWidth < widthRequiredForBtn['mvIndexBtn']\n \"\n [class.button-hidden-on-dropdown]=\"\n mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvIndexBtn']\n \"\n [attr.aria-expanded]=\"isIndexOpen\"\n [disabled]=\"redactAllInProgress\"\n (click)=\"toggleIndexSideBar(); isDropdownMenuOpen = false\"\n >\n <span>{{ \"Index\" | rpxTranslate }}</span>\n </button>\n\n <button\n *ngIf=\"toolbarButtons.showSidebar\"\n id=\"mvBookmarksBtn\"\n data-l10n-id=\"bookmarks\"\n [attr.data-tooltip]=\"'Bookmarks' | rpxTranslate\"\n #mvBookmarksBtn\n [ngClass]=\"{\n 'mv-button mv-tooltip mv-toolbar__menu-button--bookmarks': true,\n 'button-hidden-on-toolbar':\n mvToolbarMain.offsetWidth <\n widthRequiredForBtn['mvBookmarksBtn'],\n 'button-hidden-on-dropdown':\n mvToolbarMain.offsetWidth >=\n widthRequiredForBtn['mvBookmarksBtn']\n }\"\n [attr.aria-expanded]=\"isBookmarksOpen\"\n [disabled]=\"redactAllInProgress\"\n (click)=\"toggleBookmarksSideBar(); isDropdownMenuOpen = false\"\n >\n <span>{{ \"Bookmarks\" | rpxTranslate }}</span>\n </button>\n\n <button\n *ngIf=\"toolbarButtons.showDrawButton\"\n [disabled]=\"icpEnabled || redactionEnabled\"\n id=\"mvDrawBtn\"\n #mvDrawBtn\n class=\"mv-button mv-toolbar__menu-button--draw mv-tooltip\"\n [attr.data-tooltip]=\"'Draw a box' | rpxTranslate\"\n [class.button-hidden-on-toolbar]=\"\n mvToolbarMain.offsetWidth < widthRequiredForBtn['mvDrawBtn']\n \"\n [class.button-hidden-on-dropdown]=\"\n mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvDrawBtn']\n \"\n [class.toggled]=\"toolbarEvents.drawModeSubject | async\"\n aria-pressed=\"false\"\n data-l10n-id=\"toggleDrawButton\"\n (click)=\"onClickDrawToggle(); isDropdownMenuOpen = false\"\n >\n <span data-l10n-id=\"draw_label\">{{\n \"Draw a box\" | rpxTranslate\n }}</span>\n </button>\n\n <button\n *ngIf=\"toolbarButtons.showHighlightButton\"\n [disabled]=\"icpEnabled || redactionEnabled\"\n id=\"mvHighlightBtn\"\n #mvHighlightBtn\n class=\"mv-button mv-toolbar__menu-button--highlight mv-tooltip\"\n [attr.data-tooltip]=\"'Highlight' | rpxTranslate\"\n [class.button-hidden-on-toolbar]=\"\n mvToolbarMain.offsetWidth < widthRequiredForBtn['mvHighlightBtn']\n \"\n [class.button-hidden-on-dropdown]=\"\n mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvHighlightBtn']\n \"\n [class.toggled]=\"toolbarEvents.highlightToolbarSubject | async\"\n aria-pressed=\"false\"\n (click)=\"onClickHighlightToggle(); isDropdownMenuOpen = false\"\n data-l10n-id=\"toggleHighlightButton\"\n >\n <span data-l10n-id=\"highlight_label\">{{\n \"Highlight\" | rpxTranslate\n }}</span>\n </button>\n\n <ng-container *ngIf=\"toolbarButtons.showNavigation\">\n <div\n id=\"mvPageBtn\"\n #mvPageBtn\n class=\"mv-toolbar__menu-button--page\"\n [attr.data-tooltip]=\"'Page' | rpxTranslate\"\n [class.button-hidden-on-toolbar]=\"\n mvToolbarMain.offsetWidth < widthRequiredForBtn['mvPageBtn']\n \"\n [class.button-hidden-on-dropdown]=\"\n mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvPageBtn']\n \"\n >\n <span>{{ \"Page\" | rpxTranslate }}</span>\n\n <button\n id=\"mvUpBtn\"\n [disabled]=\"pageNumber === 1 || redactAllInProgress\"\n [attr.data-tooltip]=\"'Previous page' | rpxTranslate\"\n [attr.aria-label]=\"'Previous page' | rpxTranslate\"\n class=\"mv-toolbar__menu-button--up button-image mv-tooltip\"\n data-l10n-id=\"previous\"\n (click)=\"decreasePageNumber()\"\n [disabled]=\"redactAllInProgress\"\n >\n <span></span>\n </button>\n <button\n id=\"mvDownBtn\"\n [disabled]=\"pageNumber === pageCount || redactAllInProgress\"\n [attr.data-tooltip]=\"'Next page' | rpxTranslate\"\n [attr.aria-label]=\"'Next page' | rpxTranslate\"\n class=\"mv-toolbar__menu-button--down button-image mv-tooltip\"\n data-l10n-id=\"next\"\n (click)=\"increasePageNumber()\"\n >\n <span></span>\n </button>\n\n <span class=\"mv-tooltip\" [attr.data-tooltip]=\"'Page number' | rpxTranslate\">\n <input\n type=\"number\"\n id=\"pageNumber\"\n class=\"hmcts-toolbar-input govuk-input--width-2\"\n [attr.aria-label]=\"'Page number' | rpxTranslate\"\n value=\"1\"\n size=\"4\"\n min=\"1\"\n [value]=\"pageNumber\"\n tabindex=\"0\"\n data-l10n-id=\"page\"\n (change)=\"onPageNumberInputChange(pageNumberInput.value)\"\n [disabled]=\"redactAllInProgress\"\n #pageNumberInput\n />\n </span>\n <span id=\"numPages\" class=\"toolbarLabel\">/ {{ pageCount }}</span>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"toolbarButtons.showZoom\">\n <div\n id=\"mvZoomBtn\"\n #mvZoomBtn\n class=\"mv-toolbar__menu-button--zoom\"\n aria-pressed=\"false\"\n [class.button-hidden-on-toolbar]=\"\n mvToolbarMain.offsetWidth < widthRequiredForBtn['mvZoomBtn']\n \"\n [class.button-hidden-on-dropdown]=\"\n mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvZoomBtn']\n \"\n >\n <button\n [disabled]=\"\n toolbarEvents.zoomValueSubject.value === 0.1 ||\n redactAllInProgress\n \"\n id=\"mvMinusBtn\"\n class=\"mv-toolbar__menu-button--zoom-out button-image mv-tooltip\"\n [attr.data-tooltip]=\"'Zoom out' | rpxTranslate\"\n data-l10n-id=\"zoom_out\"\n (click)=\"stepZoom(-0.1)\"\n >\n <span class=\"mv-toolbar__menu-button--zoom-out-text\">{{\n \"Zoom Out\" | rpxTranslate\n }}</span>\n </button>\n <span class=\"mv-tooltip\" [attr.data-tooltip]=\"'Zoom' | rpxTranslate\"> \n <select\n id=\"scaleSelect\"\n class=\"hmcts-toolbar-select\"\n data-l10n-id=\"zoom\"\n (change)=\"zoom($event.target.value)\"\n tabindex=\"0\"\n [disabled]=\"redactAllInProgress\"\n >\n <option\n #zoomSelect\n id=\"customScaleOption\"\n title=\"\"\n [value]=\"toolbarEvents.zoomValueSubject.value\"\n >\n {{\n toolbarEvents.zoomValueSubject.value * 100\n | number : \"1.0-0\"\n }}%\n </option>\n <option\n *ngFor=\"let zoomScale of zoomScales\"\n title=\"\"\n [value]=\"zoomScale\"\n [attr.data-l10n-id]=\"'page_scale_percent_' + zoomScale * 100\"\n >\n {{ zoomScale * 100 }}%\n </option>\n </select>\n </span>\n <button\n [disabled]=\"\n toolbarEvents.zoomValueSubject.value === 5 ||\n redactAllInProgress\n \"\n id=\"mvPlusBtn\"\n class=\"mv-toolbar__menu-button--zoom-in button-image mv-tooltip\"\n (click)=\"stepZoom(0.1)\"\n [attr.data-tooltip]=\"'Zoom in' | rpxTranslate\"\n data-l10n-id=\"zoom_in\"\n >\n <span class=\"mv-toolbar__menu-button--zoom-out-text\">{{\n \"Zoom In\" | rpxTranslate\n }}</span>\n </button>\n </div>\n </ng-container>\n\n <div\n *ngIf=\"toolbarButtons.showRotate\"\n id=\"mvRotateBtn\"\n #mvRotateBtn\n class=\"mv-toolbar__menu-button--rotate\"\n [class.button-hidden-on-toolbar]=\"\n mvToolbarMain.offsetWidth < widthRequiredForBtn['mvRotateBtn']\n \"\n [class.button-hidden-on-dropdown]=\"\n mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvRotateBtn']\n \"\n >\n <button\n id=\"mvRotateLeftBtn\"\n class=\"mv-toolbar__menu-button--rotate_left button-image mv-tooltip\"\n [attr.aria-label]=\"'Rotate counterclockwise' | rpxTranslate\"\n [attr.data-tooltip]=\"'Rotate counterclockwise' | rpxTranslate\"\n data-l10n-id=\"page_rotate_ccw\"\n (click)=\"rotate(270)\"\n [disabled]=\"redactAllInProgress\"\n >\n <span></span>\n </button>\n <button\n id=\"mvRotateRightBtn\"\n class=\"mv-toolbar__menu-button--rotate_right button-image mv-tooltip\"\n [attr.aria-label]=\"'Rotate clockwise' | rpxTranslate\"\n [attr.data-tooltip]=\"'Rotate clockwise' | rpxTranslate\"\n data-l10n-id=\"page_rotate_cw\"\n (click)=\"rotate(90)\"\n [disabled]=\"redactAllInProgress\"\n >\n <span></span>\n </button>\n <span>{{ \"Rotate\" | rpxTranslate }}</span>\n </div>\n\n <button\n *ngIf=\"toolbarButtons.showSearchBar\"\n [disabled]=\"icpEnabled || redactAllInProgress\"\n id=\"mvSearchBtn\"\n #mvSearchBtn\n [attr.data-tooltip]=\"'Search' | rpxTranslate\"\n data-l10n-id=\"searchbar\"\n class=\"mv-button mv-toolbar__menu-button--search mv-tooltip\"\n [class.button-hidden-on-toolbar]=\"\n mvToolbarMain.offsetWidth < widthRequiredForBtn['mvSearchBtn']\n \"\n [class.button-hidden-on-dropdown]=\"\n mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvSearchBtn']\n \"\n aria-pressed=\"false\"\n (click)=\"toggleSearchBar(); isDropdownMenuOpen = false\"\n >\n <span>{{ \"Search\" | rpxTranslate }}</span>\n </button>\n <mv-search-bar\n *ngIf=\"!toolbarEvents.searchBarHidden.getValue()\"\n ></mv-search-bar>\n\n <button\n *ngIf=\"enableICP && toolbarButtons.showPresentationMode && isPdf()\"\n [disabled]=\"icpEnabled || !contentType || redactionEnabled\"\n id=\"mvPresentBtn\"\n #mvPresentBtn\n class=\"mv-button mv-toolbar__menu-button--present mv-tooltip\"\n [attr.data-tooltip]=\"'In-Court presentation mode' | rpxTranslate\"\n data-l10n-id=\"icpMode_label\"\n [ngClass]=\"onToolBarOffSetChange('mvPresentBtn')\"\n aria-pressed=\"false\"\n (click)=\"togglePresentBar(); isDropdownMenuOpen = false\"\n >\n <span data-l10n-id=\"icpMode_label\">{{\n \"Present\" | rpxTranslate\n }}</span>\n </button>\n\n <button\n *ngIf=\"enableRedactions && toolbarButtons.showRedact\"\n [disabled]=\"icpEnabled || redactAllInProgress\"\n id=\"mvRedactBtn\"\n #mvRedactBtn\n [attr.data-tooltip]=\"'Redact' | rpxTranslate\"\n data-l10n-id=\"redact\"\n class=\"mv-button mv-toolbar__menu-button--redact mv-tooltip\"\n [ngClass]=\"onToolBarOffSetChange('mvRedactBtn')\"\n [attr.aria-expanded]=\"isRedactOpen\"\n (click)=\"toggleRedactBar(); isDropdownMenuOpen = false\"\n >\n <span>{{ \"Redact\" | rpxTranslate }}</span>\n </button>\n\n <button\n *ngIf=\"toolbarButtons.showGrabNDragButton\"\n [disabled]=\"icpEnabled || redactAllInProgress\"\n id=\"mvGrabBtn\"\n #mvGrabBtn\n class=\"mv-button mv-toolbar__menu-button--grab mv-tooltip\"\n data-tooltip=\"Grab and drag\"\n [ngClass]=\"onToolBarOffSetChange('mvGrabBtn')\"\n aria-pressed=\"false\"\n (click)=\"toggleGrabNDrag(); isDropdownMenuOpen = false\"\n >\n <span>{{ \"Grab and drag\" | rpxTranslate }}</span>\n </button>\n\n <button\n *ngIf=\"toolbarButtons.showDownload\"\n [disabled]=\"icpEnabled || redactionEnabled\"\n id=\"mvDownloadBtn\"\n #mvDownloadBtn\n class=\"mv-button mv-toolbar__menu-button--download mv-tooltip\"\n [attr.data-tooltip]=\"'Download' | rpxTranslate\"\n data-l10n-id=\"download\"\n [ngClass]=\"onToolBarOffSetChange('mvDownloadBtn')\"\n aria-pressed=\"false\"\n (click)=\"downloadFile(); isDropdownMenuOpen = false\"\n >\n <span>{{ \"Download\" | rpxTranslate }}</span>\n </button>\n\n <button\n *ngIf=\"toolbarButtons.showPrint\"\n [disabled]=\"icpEnabled || redactionEnabled\"\n id=\"mvPrintBtn\"\n #mvPrintBtn\n data-l10n-id=\"print\"\n aria-label=\"Print\"\n [attr.data-tooltip]=\"'Print' | rpxTranslate\"\n data-l10n-id=\"print\"\n class=\"mv-button mv-toolbar__menu-button--print mv-tooltip\"\n [ngClass]=\"onToolBarOffSetChange('mvPrintBtn')\"\n aria-pressed=\"false\"\n (click)=\"printFile(); isDropdownMenuOpen = false\"\n >\n <span>{{ \"Print\" | rpxTranslate }}</span>\n </button>\n\n <button\n *ngIf=\"enableAnnotations && toolbarButtons.showCommentSummary\"\n [disabled]=\"redactionEnabled\"\n id=\"mvCommentsBtn\"\n #mvCommentsBtn\n class=\"mv-button mv-toolbar__menu-button--comments mv-tooltip\"\n [attr.data-tooltip]=\"'Comments' | rpxTranslate\"\n data-l10n-id=\"comments\"\n [ngClass]=\"onToolBarOffSetChange('mvCommentsBtn')\"\n [attr.aria-expanded]=\"isCommentsOpen\"\n (click)=\"toggleCommentsPanel(); isDropdownMenuOpen = false\"\n >\n <span>{{ \"Comments\" | rpxTranslate }}</span>\n </button>\n </ng-template>\n </div>\n </div>\n\n <div id=\"loadingBar\">\n <div class=\"progress\">\n <div class=\"glimmer\"></div>\n </div>\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i7.CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "directive", type: i7.CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { kind: "component", type: SearchBarComponent, selector: "mv-search-bar" }, { kind: "directive", type: TooltipDismissDirective, selector: ".mv-tooltip, [mvTooltipDismiss]" }, { kind: "pipe", type: i5.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.DecimalPipe, name: "number" }, { kind: "pipe", type: i5$1.RpxTranslatePipe, name: "rpxTranslate" }] }); }
5984
6502
  }
5985
6503
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: MainToolbarComponent, decorators: [{
5986
6504
  type: Component,
5987
- args: [{ selector: 'mv-main-toolbar', template: "<div class=\"toolbar\">\n <div id=\"toolbarContainer\">\n <div class=\"mv-toolbar__container\">\n <div #mvToolbar class=\"mv-toolbar\" [class.notSupported]=\"!contentType\">\n <!-- The mvToolbarMain div contains all toolbar buttons except the \"More options\" button. This allows for calculation of the available space to display buttons -->\n <div id=\"mvToolbarMain\" class=\"mv-toolbar-main\" #mvToolbarMain>\n <ng-container *ngTemplateOutlet=\"menuItems\"></ng-container>\n </div>\n <!-- The mvToolbarMoreOptions div contains the \"More options\" toolbar button (and the overlay template for the dropdown menu).\n The space occupied by the button (if visible) is excluded from the toolbar space available calculation -->\n <div id=\"mvToolbarMoreOptions\" class=\"mv-toolbar-more-options\">\n <button\n id=\"mvMoreOptionsBtn\"\n class=\"mv-button mv-toolbar__menu-button--more-options\"\n [class.mv-toolbar__menu-button--more-options__hidden]=\"\n mvToolbar.offsetWidth >= allButtonsWidth\n \"\n [attr.aria-expanded]=\"isDropdownMenuOpen\"\n (click)=\"toggleMoreOptions()\"\n cdkOverlayOrigin\n #trigger=\"cdkOverlayOrigin\"\n [disabled]=\"redactAllInProgress\"\n >\n <span>{{ \"More options\" | rpxTranslate }}</span>\n </button>\n <!-- This template displays the overlay content for the dropdown menu and is connected to the \"More options\" button -->\n <ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"trigger\"\n [cdkConnectedOverlayOpen]=\"isDropdownMenuOpen\"\n [cdkConnectedOverlayPositions]=\"dropdownMenuPositions\"\n >\n <div class=\"dropdown-menu\" #dropdownMenu tabindex=\"0\">\n <ng-container *ngTemplateOutlet=\"menuItems\"></ng-container>\n </div>\n </ng-template>\n </div>\n </div>\n\n <div id=\"mvMenuItems\" #mvMenuItems>\n <ng-template #menuItems>\n <button\n *ngIf=\"toolbarButtons.showSidebar\"\n id=\"mvIndexBtn\"\n title=\"Index\"\n data-l10n-id=\"index\"\n #mvIndexBtn\n class=\"mv-button mv-toolbar__menu-button--index\"\n [class.button-hidden-on-toolbar]=\"\n mvToolbarMain.offsetWidth < widthRequiredForBtn['mvIndexBtn']\n \"\n [class.button-hidden-on-dropdown]=\"\n mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvIndexBtn']\n \"\n [attr.aria-expanded]=\"isIndexOpen\"\n [disabled]=\"redactAllInProgress\"\n (click)=\"toggleIndexSideBar(); isDropdownMenuOpen = false\"\n >\n <span>{{ \"Index\" | rpxTranslate }}</span>\n </button>\n\n <button\n *ngIf=\"toolbarButtons.showSidebar\"\n id=\"mvBookmarksBtn\"\n title=\"Bookmarks\"\n data-l10n-id=\"bookmarks\"\n #mvBookmarksBtn\n [ngClass]=\"{\n 'mv-button mv-toolbar__menu-button--bookmarks': true,\n 'button-hidden-on-toolbar':\n mvToolbarMain.offsetWidth <\n widthRequiredForBtn['mvBookmarksBtn'],\n 'button-hidden-on-dropdown':\n mvToolbarMain.offsetWidth >=\n widthRequiredForBtn['mvBookmarksBtn']\n }\"\n [attr.aria-expanded]=\"isBookmarksOpen\"\n [disabled]=\"redactAllInProgress\"\n (click)=\"toggleBookmarksSideBar(); isDropdownMenuOpen = false\"\n >\n <span>{{ \"Bookmarks\" | rpxTranslate }}</span>\n </button>\n\n <button\n *ngIf=\"toolbarButtons.showDrawButton\"\n [disabled]=\"icpEnabled || redactionEnabled\"\n id=\"mvDrawBtn\"\n #mvDrawBtn\n class=\"mv-button mv-toolbar__menu-button--draw\"\n title=\"Draw a box\"\n [class.button-hidden-on-toolbar]=\"\n mvToolbarMain.offsetWidth < widthRequiredForBtn['mvDrawBtn']\n \"\n [class.button-hidden-on-dropdown]=\"\n mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvDrawBtn']\n \"\n [class.toggled]=\"toolbarEvents.drawModeSubject | async\"\n aria-pressed=\"false\"\n data-l10n-id=\"toggleDrawButton\"\n (click)=\"onClickDrawToggle(); isDropdownMenuOpen = false\"\n >\n <span data-l10n-id=\"draw_label\">{{\n \"Draw a box\" | rpxTranslate\n }}</span>\n </button>\n\n <button\n *ngIf=\"toolbarButtons.showHighlightButton\"\n [disabled]=\"icpEnabled || redactionEnabled\"\n id=\"mvHighlightBtn\"\n #mvHighlightBtn\n class=\"mv-button mv-toolbar__menu-button--highlight\"\n title=\"Highlight\"\n aria-label=\"Highlight\"\n [class.button-hidden-on-toolbar]=\"\n mvToolbarMain.offsetWidth < widthRequiredForBtn['mvHighlightBtn']\n \"\n [class.button-hidden-on-dropdown]=\"\n mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvHighlightBtn']\n \"\n [class.toggled]=\"toolbarEvents.highlightToolbarSubject | async\"\n aria-pressed=\"false\"\n (click)=\"onClickHighlightToggle(); isDropdownMenuOpen = false\"\n data-l10n-id=\"toggleHighlightButton\"\n >\n <span data-l10n-id=\"highlight_label\">{{\n \"Highlight\" | rpxTranslate\n }}</span>\n </button>\n\n <ng-container *ngIf=\"toolbarButtons.showNavigation\">\n <div\n id=\"mvPageBtn\"\n #mvPageBtn\n class=\"mv-toolbar__menu-button--page\"\n [class.button-hidden-on-toolbar]=\"\n mvToolbarMain.offsetWidth < widthRequiredForBtn['mvPageBtn']\n \"\n [class.button-hidden-on-dropdown]=\"\n mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvPageBtn']\n \"\n >\n <span>{{ \"Page\" | rpxTranslate }}</span>\n\n <button\n id=\"mvUpBtn\"\n [disabled]=\"pageNumber === 1 || redactAllInProgress\"\n title=\"Previous Page\"\n class=\"mv-toolbar__menu-button--up button-image\"\n data-l10n-id=\"previous\"\n (click)=\"decreasePageNumber()\"\n [disabled]=\"redactAllInProgress\"\n >\n <span></span>\n </button>\n <button\n id=\"mvDownBtn\"\n [disabled]=\"pageNumber === pageCount || redactAllInProgress\"\n title=\"Next Page\"\n class=\"mv-toolbar__menu-button--down button-image\"\n data-l10n-id=\"next\"\n (click)=\"increasePageNumber()\"\n >\n <span></span>\n </button>\n\n <input\n type=\"number\"\n id=\"pageNumber\"\n class=\"hmcts-toolbar-input govuk-input--width-2\"\n title=\"Page Number\"\n value=\"1\"\n size=\"4\"\n min=\"1\"\n [value]=\"pageNumber\"\n aria-label=\"page number\"\n tabindex=\"0\"\n data-l10n-id=\"page\"\n (change)=\"onPageNumberInputChange(pageNumberInput.value)\"\n [disabled]=\"redactAllInProgress\"\n #pageNumberInput\n />\n <span id=\"numPages\" class=\"toolbarLabel\">/ {{ pageCount }}</span>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"toolbarButtons.showZoom\">\n <div\n id=\"mvZoomBtn\"\n #mvZoomBtn\n class=\"mv-toolbar__menu-button--zoom\"\n aria-pressed=\"false\"\n [class.button-hidden-on-toolbar]=\"\n mvToolbarMain.offsetWidth < widthRequiredForBtn['mvZoomBtn']\n \"\n [class.button-hidden-on-dropdown]=\"\n mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvZoomBtn']\n \"\n >\n <button\n [disabled]=\"\n toolbarEvents.zoomValueSubject.value === 0.1 ||\n redactAllInProgress\n \"\n id=\"mvMinusBtn\"\n class=\"mv-toolbar__menu-button--zoom-out button-image\"\n title=\"Zoom Out\"\n data-l10n-id=\"zoom_out\"\n (click)=\"stepZoom(-0.1)\"\n >\n <span class=\"mv-toolbar__menu-button--zoom-out-text\">{{\n \"Zoom Out\" | rpxTranslate\n }}</span>\n </button>\n <select\n id=\"scaleSelect\"\n class=\"hmcts-toolbar-select\"\n title=\"Zoom\"\n tabindex=\"0\"\n data-l10n-id=\"zoom\"\n (change)=\"zoom($event.target.value)\"\n aria-label=\"zoom\"\n [disabled]=\"redactAllInProgress\"\n >\n <option\n #zoomSelect\n id=\"customScaleOption\"\n title=\"\"\n [value]=\"toolbarEvents.zoomValueSubject.value\"\n >\n {{\n toolbarEvents.zoomValueSubject.value * 100\n | number : \"1.0-0\"\n }}%\n </option>\n <option\n *ngFor=\"let zoomScale of zoomScales\"\n title=\"\"\n [value]=\"zoomScale\"\n [attr.data-l10n-id]=\"'page_scale_percent_' + zoomScale * 100\"\n >\n {{ zoomScale * 100 }}%\n </option>\n </select>\n\n <button\n [disabled]=\"\n toolbarEvents.zoomValueSubject.value === 5 ||\n redactAllInProgress\n \"\n id=\"mvPlusBtn\"\n class=\"mv-toolbar__menu-button--zoom-in button-image\"\n (click)=\"stepZoom(0.1)\"\n title=\"Zoom In\"\n data-l10n-id=\"zoom_in\"\n >\n <span class=\"mv-toolbar__menu-button--zoom-out-text\">{{\n \"Zoom In\" | rpxTranslate\n }}</span>\n </button>\n </div>\n </ng-container>\n\n <div\n *ngIf=\"toolbarButtons.showRotate\"\n id=\"mvRotateBtn\"\n #mvRotateBtn\n class=\"mv-toolbar__menu-button--rotate\"\n [class.button-hidden-on-toolbar]=\"\n mvToolbarMain.offsetWidth < widthRequiredForBtn['mvRotateBtn']\n \"\n [class.button-hidden-on-dropdown]=\"\n mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvRotateBtn']\n \"\n >\n <button\n id=\"mvRotateLeftBtn\"\n class=\"mv-toolbar__menu-button--rotate_left button-image\"\n title=\"Rotate Counterclockwise\"\n data-l10n-id=\"page_rotate_ccw\"\n (click)=\"rotate(270)\"\n [disabled]=\"redactAllInProgress\"\n >\n <span></span>\n </button>\n <button\n id=\"mvRotateRightBtn\"\n class=\"mv-toolbar__menu-button--rotate_right button-image\"\n title=\"Rotate Clockwise\"\n data-l10n-id=\"page_rotate_cw\"\n (click)=\"rotate(90)\"\n [disabled]=\"redactAllInProgress\"\n >\n <span></span>\n </button>\n <span>{{ \"Rotate\" | rpxTranslate }}</span>\n </div>\n\n <button\n *ngIf=\"toolbarButtons.showSearchBar\"\n [disabled]=\"icpEnabled || redactAllInProgress\"\n id=\"mvSearchBtn\"\n #mvSearchBtn\n title=\"Search\"\n data-l10n-id=\"searchbar\"\n class=\"mv-button mv-toolbar__menu-button--search\"\n [class.button-hidden-on-toolbar]=\"\n mvToolbarMain.offsetWidth < widthRequiredForBtn['mvSearchBtn']\n \"\n [class.button-hidden-on-dropdown]=\"\n mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvSearchBtn']\n \"\n aria-pressed=\"false\"\n (click)=\"toggleSearchBar(); isDropdownMenuOpen = false\"\n >\n <span>{{ \"Search\" | rpxTranslate }}</span>\n </button>\n <mv-search-bar\n *ngIf=\"!toolbarEvents.searchBarHidden.getValue()\"\n ></mv-search-bar>\n\n <button\n *ngIf=\"enableICP && toolbarButtons.showPresentationMode && isPdf()\"\n [disabled]=\"icpEnabled || !contentType || redactionEnabled\"\n id=\"mvPresentBtn\"\n #mvPresentBtn\n class=\"mv-button mv-toolbar__menu-button--present\"\n title=\"In-Court Presentation Mode\"\n data-l10n-id=\"icpMode_label\"\n [ngClass]=\"onToolBarOffSetChange('mvPresentBtn')\"\n aria-pressed=\"false\"\n (click)=\"togglePresentBar(); isDropdownMenuOpen = false\"\n >\n <span data-l10n-id=\"icpMode_label\">{{\n \"Present\" | rpxTranslate\n }}</span>\n </button>\n\n <button\n *ngIf=\"enableRedactions && toolbarButtons.showRedact\"\n [disabled]=\"icpEnabled || redactAllInProgress\"\n id=\"mvRedactBtn\"\n #mvRedactBtn\n title=\"Redact\"\n data-l10n-id=\"redact\"\n class=\"mv-button mv-toolbar__menu-button--redact\"\n [ngClass]=\"onToolBarOffSetChange('mvRedactBtn')\"\n [attr.aria-expanded]=\"isRedactOpen\"\n (click)=\"toggleRedactBar(); isDropdownMenuOpen = false\"\n >\n <span>{{ \"Redact\" | rpxTranslate }}</span>\n </button>\n\n <button\n *ngIf=\"toolbarButtons.showGrabNDragButton\"\n [disabled]=\"icpEnabled || redactAllInProgress\"\n id=\"mvGrabBtn\"\n #mvGrabBtn\n class=\"mv-button mv-toolbar__menu-button--grab\"\n title=\"Grab and drag\"\n [ngClass]=\"onToolBarOffSetChange('mvGrabBtn')\"\n aria-pressed=\"false\"\n (click)=\"toggleGrabNDrag(); isDropdownMenuOpen = false\"\n >\n <span>{{ \"Grab and drag\" | rpxTranslate }}</span>\n </button>\n\n <button\n *ngIf=\"toolbarButtons.showDownload\"\n [disabled]=\"icpEnabled || redactionEnabled\"\n id=\"mvDownloadBtn\"\n #mvDownloadBtn\n class=\"mv-button mv-toolbar__menu-button--download\"\n title=\"Download\"\n data-l10n-id=\"download\"\n [ngClass]=\"onToolBarOffSetChange('mvDownloadBtn')\"\n aria-pressed=\"false\"\n (click)=\"downloadFile(); isDropdownMenuOpen = false\"\n >\n <span>{{ \"Download\" | rpxTranslate }}</span>\n </button>\n\n <button\n *ngIf=\"toolbarButtons.showPrint\"\n [disabled]=\"icpEnabled || redactionEnabled\"\n id=\"mvPrintBtn\"\n #mvPrintBtn\n title=\"Print\"\n data-l10n-id=\"print\"\n class=\"mv-button mv-toolbar__menu-button--print\"\n [ngClass]=\"onToolBarOffSetChange('mvPrintBtn')\"\n aria-pressed=\"false\"\n (click)=\"printFile(); isDropdownMenuOpen = false\"\n >\n <span>{{ \"Print\" | rpxTranslate }}</span>\n </button>\n\n <button\n *ngIf=\"enableAnnotations && toolbarButtons.showCommentSummary\"\n [disabled]=\"redactionEnabled\"\n id=\"mvCommentsBtn\"\n #mvCommentsBtn\n class=\"mv-button mv-toolbar__menu-button--comments\"\n title=\"Comments\"\n data-l10n-id=\"comments\"\n [ngClass]=\"onToolBarOffSetChange('mvCommentsBtn')\"\n [attr.aria-expanded]=\"isCommentsOpen\"\n (click)=\"toggleCommentsPanel(); isDropdownMenuOpen = false\"\n >\n <span>{{ \"Comments\" | rpxTranslate }}</span>\n </button>\n </ng-template>\n </div>\n </div>\n\n <div id=\"loadingBar\">\n <div class=\"progress\">\n <div class=\"glimmer\"></div>\n </div>\n </div>\n </div>\n</div>\n" }]
6505
+ args: [{ selector: 'mv-main-toolbar', template: "<div class=\"toolbar\">\n <div id=\"toolbarContainer\">\n <div class=\"mv-toolbar__container\">\n <div #mvToolbar class=\"mv-toolbar\" [class.notSupported]=\"!contentType\">\n <!-- The mvToolbarMain div contains all toolbar buttons except the \"More options\" button. This allows for calculation of the available space to display buttons -->\n <div id=\"mvToolbarMain\" class=\"mv-toolbar-main\" #mvToolbarMain>\n <ng-container *ngTemplateOutlet=\"menuItems\"></ng-container>\n </div>\n <!-- The mvToolbarMoreOptions div contains the \"More options\" toolbar button (and the overlay template for the dropdown menu).\n The space occupied by the button (if visible) is excluded from the toolbar space available calculation -->\n <div id=\"mvToolbarMoreOptions\" class=\"mv-toolbar-more-options\">\n <button\n id=\"mvMoreOptionsBtn\"\n class=\"mv-button mv-toolbar__menu-button--more-options mv-tooltip\"\n [class.mv-toolbar__menu-button--more-options__hidden]=\"\n mvToolbar.offsetWidth >= allButtonsWidth\n \"\n [attr.aria-expanded]=\"isDropdownMenuOpen\"\n [attr.data-tooltip]=\"'More options' | rpxTranslate\"\n (click)=\"toggleMoreOptions()\"\n cdkOverlayOrigin\n #trigger=\"cdkOverlayOrigin\"\n [disabled]=\"redactAllInProgress\"\n >\n <span>{{ \"More options\" | rpxTranslate }}</span>\n </button>\n <!-- This template displays the overlay content for the dropdown menu and is connected to the \"More options\" button -->\n <ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"trigger\"\n [cdkConnectedOverlayOpen]=\"isDropdownMenuOpen\"\n [cdkConnectedOverlayPositions]=\"dropdownMenuPositions\"\n >\n <div class=\"dropdown-menu\" #dropdownMenu tabindex=\"0\">\n <ng-container *ngTemplateOutlet=\"menuItems\"></ng-container>\n </div>\n </ng-template>\n </div>\n </div>\n <div id=\"mvMenuItems\" #mvMenuItems>\n <ng-template #menuItems>\n <button\n *ngIf=\"toolbarButtons.showSidebar\"\n id=\"mvIndexBtn\"\n data-l10n-id=\"index\"\n [attr.data-tooltip]=\"'Index' | rpxTranslate\"\n #mvIndexBtn\n class=\"mv-button mv-toolbar__menu-button--index mv-tooltip\"\n [class.button-hidden-on-toolbar]=\"\n mvToolbarMain.offsetWidth < widthRequiredForBtn['mvIndexBtn']\n \"\n [class.button-hidden-on-dropdown]=\"\n mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvIndexBtn']\n \"\n [attr.aria-expanded]=\"isIndexOpen\"\n [disabled]=\"redactAllInProgress\"\n (click)=\"toggleIndexSideBar(); isDropdownMenuOpen = false\"\n >\n <span>{{ \"Index\" | rpxTranslate }}</span>\n </button>\n\n <button\n *ngIf=\"toolbarButtons.showSidebar\"\n id=\"mvBookmarksBtn\"\n data-l10n-id=\"bookmarks\"\n [attr.data-tooltip]=\"'Bookmarks' | rpxTranslate\"\n #mvBookmarksBtn\n [ngClass]=\"{\n 'mv-button mv-tooltip mv-toolbar__menu-button--bookmarks': true,\n 'button-hidden-on-toolbar':\n mvToolbarMain.offsetWidth <\n widthRequiredForBtn['mvBookmarksBtn'],\n 'button-hidden-on-dropdown':\n mvToolbarMain.offsetWidth >=\n widthRequiredForBtn['mvBookmarksBtn']\n }\"\n [attr.aria-expanded]=\"isBookmarksOpen\"\n [disabled]=\"redactAllInProgress\"\n (click)=\"toggleBookmarksSideBar(); isDropdownMenuOpen = false\"\n >\n <span>{{ \"Bookmarks\" | rpxTranslate }}</span>\n </button>\n\n <button\n *ngIf=\"toolbarButtons.showDrawButton\"\n [disabled]=\"icpEnabled || redactionEnabled\"\n id=\"mvDrawBtn\"\n #mvDrawBtn\n class=\"mv-button mv-toolbar__menu-button--draw mv-tooltip\"\n [attr.data-tooltip]=\"'Draw a box' | rpxTranslate\"\n [class.button-hidden-on-toolbar]=\"\n mvToolbarMain.offsetWidth < widthRequiredForBtn['mvDrawBtn']\n \"\n [class.button-hidden-on-dropdown]=\"\n mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvDrawBtn']\n \"\n [class.toggled]=\"toolbarEvents.drawModeSubject | async\"\n aria-pressed=\"false\"\n data-l10n-id=\"toggleDrawButton\"\n (click)=\"onClickDrawToggle(); isDropdownMenuOpen = false\"\n >\n <span data-l10n-id=\"draw_label\">{{\n \"Draw a box\" | rpxTranslate\n }}</span>\n </button>\n\n <button\n *ngIf=\"toolbarButtons.showHighlightButton\"\n [disabled]=\"icpEnabled || redactionEnabled\"\n id=\"mvHighlightBtn\"\n #mvHighlightBtn\n class=\"mv-button mv-toolbar__menu-button--highlight mv-tooltip\"\n [attr.data-tooltip]=\"'Highlight' | rpxTranslate\"\n [class.button-hidden-on-toolbar]=\"\n mvToolbarMain.offsetWidth < widthRequiredForBtn['mvHighlightBtn']\n \"\n [class.button-hidden-on-dropdown]=\"\n mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvHighlightBtn']\n \"\n [class.toggled]=\"toolbarEvents.highlightToolbarSubject | async\"\n aria-pressed=\"false\"\n (click)=\"onClickHighlightToggle(); isDropdownMenuOpen = false\"\n data-l10n-id=\"toggleHighlightButton\"\n >\n <span data-l10n-id=\"highlight_label\">{{\n \"Highlight\" | rpxTranslate\n }}</span>\n </button>\n\n <ng-container *ngIf=\"toolbarButtons.showNavigation\">\n <div\n id=\"mvPageBtn\"\n #mvPageBtn\n class=\"mv-toolbar__menu-button--page\"\n [attr.data-tooltip]=\"'Page' | rpxTranslate\"\n [class.button-hidden-on-toolbar]=\"\n mvToolbarMain.offsetWidth < widthRequiredForBtn['mvPageBtn']\n \"\n [class.button-hidden-on-dropdown]=\"\n mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvPageBtn']\n \"\n >\n <span>{{ \"Page\" | rpxTranslate }}</span>\n\n <button\n id=\"mvUpBtn\"\n [disabled]=\"pageNumber === 1 || redactAllInProgress\"\n [attr.data-tooltip]=\"'Previous page' | rpxTranslate\"\n [attr.aria-label]=\"'Previous page' | rpxTranslate\"\n class=\"mv-toolbar__menu-button--up button-image mv-tooltip\"\n data-l10n-id=\"previous\"\n (click)=\"decreasePageNumber()\"\n [disabled]=\"redactAllInProgress\"\n >\n <span></span>\n </button>\n <button\n id=\"mvDownBtn\"\n [disabled]=\"pageNumber === pageCount || redactAllInProgress\"\n [attr.data-tooltip]=\"'Next page' | rpxTranslate\"\n [attr.aria-label]=\"'Next page' | rpxTranslate\"\n class=\"mv-toolbar__menu-button--down button-image mv-tooltip\"\n data-l10n-id=\"next\"\n (click)=\"increasePageNumber()\"\n >\n <span></span>\n </button>\n\n <span class=\"mv-tooltip\" [attr.data-tooltip]=\"'Page number' | rpxTranslate\">\n <input\n type=\"number\"\n id=\"pageNumber\"\n class=\"hmcts-toolbar-input govuk-input--width-2\"\n [attr.aria-label]=\"'Page number' | rpxTranslate\"\n value=\"1\"\n size=\"4\"\n min=\"1\"\n [value]=\"pageNumber\"\n tabindex=\"0\"\n data-l10n-id=\"page\"\n (change)=\"onPageNumberInputChange(pageNumberInput.value)\"\n [disabled]=\"redactAllInProgress\"\n #pageNumberInput\n />\n </span>\n <span id=\"numPages\" class=\"toolbarLabel\">/ {{ pageCount }}</span>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"toolbarButtons.showZoom\">\n <div\n id=\"mvZoomBtn\"\n #mvZoomBtn\n class=\"mv-toolbar__menu-button--zoom\"\n aria-pressed=\"false\"\n [class.button-hidden-on-toolbar]=\"\n mvToolbarMain.offsetWidth < widthRequiredForBtn['mvZoomBtn']\n \"\n [class.button-hidden-on-dropdown]=\"\n mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvZoomBtn']\n \"\n >\n <button\n [disabled]=\"\n toolbarEvents.zoomValueSubject.value === 0.1 ||\n redactAllInProgress\n \"\n id=\"mvMinusBtn\"\n class=\"mv-toolbar__menu-button--zoom-out button-image mv-tooltip\"\n [attr.data-tooltip]=\"'Zoom out' | rpxTranslate\"\n data-l10n-id=\"zoom_out\"\n (click)=\"stepZoom(-0.1)\"\n >\n <span class=\"mv-toolbar__menu-button--zoom-out-text\">{{\n \"Zoom Out\" | rpxTranslate\n }}</span>\n </button>\n <span class=\"mv-tooltip\" [attr.data-tooltip]=\"'Zoom' | rpxTranslate\"> \n <select\n id=\"scaleSelect\"\n class=\"hmcts-toolbar-select\"\n data-l10n-id=\"zoom\"\n (change)=\"zoom($event.target.value)\"\n tabindex=\"0\"\n [disabled]=\"redactAllInProgress\"\n >\n <option\n #zoomSelect\n id=\"customScaleOption\"\n title=\"\"\n [value]=\"toolbarEvents.zoomValueSubject.value\"\n >\n {{\n toolbarEvents.zoomValueSubject.value * 100\n | number : \"1.0-0\"\n }}%\n </option>\n <option\n *ngFor=\"let zoomScale of zoomScales\"\n title=\"\"\n [value]=\"zoomScale\"\n [attr.data-l10n-id]=\"'page_scale_percent_' + zoomScale * 100\"\n >\n {{ zoomScale * 100 }}%\n </option>\n </select>\n </span>\n <button\n [disabled]=\"\n toolbarEvents.zoomValueSubject.value === 5 ||\n redactAllInProgress\n \"\n id=\"mvPlusBtn\"\n class=\"mv-toolbar__menu-button--zoom-in button-image mv-tooltip\"\n (click)=\"stepZoom(0.1)\"\n [attr.data-tooltip]=\"'Zoom in' | rpxTranslate\"\n data-l10n-id=\"zoom_in\"\n >\n <span class=\"mv-toolbar__menu-button--zoom-out-text\">{{\n \"Zoom In\" | rpxTranslate\n }}</span>\n </button>\n </div>\n </ng-container>\n\n <div\n *ngIf=\"toolbarButtons.showRotate\"\n id=\"mvRotateBtn\"\n #mvRotateBtn\n class=\"mv-toolbar__menu-button--rotate\"\n [class.button-hidden-on-toolbar]=\"\n mvToolbarMain.offsetWidth < widthRequiredForBtn['mvRotateBtn']\n \"\n [class.button-hidden-on-dropdown]=\"\n mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvRotateBtn']\n \"\n >\n <button\n id=\"mvRotateLeftBtn\"\n class=\"mv-toolbar__menu-button--rotate_left button-image mv-tooltip\"\n [attr.aria-label]=\"'Rotate counterclockwise' | rpxTranslate\"\n [attr.data-tooltip]=\"'Rotate counterclockwise' | rpxTranslate\"\n data-l10n-id=\"page_rotate_ccw\"\n (click)=\"rotate(270)\"\n [disabled]=\"redactAllInProgress\"\n >\n <span></span>\n </button>\n <button\n id=\"mvRotateRightBtn\"\n class=\"mv-toolbar__menu-button--rotate_right button-image mv-tooltip\"\n [attr.aria-label]=\"'Rotate clockwise' | rpxTranslate\"\n [attr.data-tooltip]=\"'Rotate clockwise' | rpxTranslate\"\n data-l10n-id=\"page_rotate_cw\"\n (click)=\"rotate(90)\"\n [disabled]=\"redactAllInProgress\"\n >\n <span></span>\n </button>\n <span>{{ \"Rotate\" | rpxTranslate }}</span>\n </div>\n\n <button\n *ngIf=\"toolbarButtons.showSearchBar\"\n [disabled]=\"icpEnabled || redactAllInProgress\"\n id=\"mvSearchBtn\"\n #mvSearchBtn\n [attr.data-tooltip]=\"'Search' | rpxTranslate\"\n data-l10n-id=\"searchbar\"\n class=\"mv-button mv-toolbar__menu-button--search mv-tooltip\"\n [class.button-hidden-on-toolbar]=\"\n mvToolbarMain.offsetWidth < widthRequiredForBtn['mvSearchBtn']\n \"\n [class.button-hidden-on-dropdown]=\"\n mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvSearchBtn']\n \"\n aria-pressed=\"false\"\n (click)=\"toggleSearchBar(); isDropdownMenuOpen = false\"\n >\n <span>{{ \"Search\" | rpxTranslate }}</span>\n </button>\n <mv-search-bar\n *ngIf=\"!toolbarEvents.searchBarHidden.getValue()\"\n ></mv-search-bar>\n\n <button\n *ngIf=\"enableICP && toolbarButtons.showPresentationMode && isPdf()\"\n [disabled]=\"icpEnabled || !contentType || redactionEnabled\"\n id=\"mvPresentBtn\"\n #mvPresentBtn\n class=\"mv-button mv-toolbar__menu-button--present mv-tooltip\"\n [attr.data-tooltip]=\"'In-Court presentation mode' | rpxTranslate\"\n data-l10n-id=\"icpMode_label\"\n [ngClass]=\"onToolBarOffSetChange('mvPresentBtn')\"\n aria-pressed=\"false\"\n (click)=\"togglePresentBar(); isDropdownMenuOpen = false\"\n >\n <span data-l10n-id=\"icpMode_label\">{{\n \"Present\" | rpxTranslate\n }}</span>\n </button>\n\n <button\n *ngIf=\"enableRedactions && toolbarButtons.showRedact\"\n [disabled]=\"icpEnabled || redactAllInProgress\"\n id=\"mvRedactBtn\"\n #mvRedactBtn\n [attr.data-tooltip]=\"'Redact' | rpxTranslate\"\n data-l10n-id=\"redact\"\n class=\"mv-button mv-toolbar__menu-button--redact mv-tooltip\"\n [ngClass]=\"onToolBarOffSetChange('mvRedactBtn')\"\n [attr.aria-expanded]=\"isRedactOpen\"\n (click)=\"toggleRedactBar(); isDropdownMenuOpen = false\"\n >\n <span>{{ \"Redact\" | rpxTranslate }}</span>\n </button>\n\n <button\n *ngIf=\"toolbarButtons.showGrabNDragButton\"\n [disabled]=\"icpEnabled || redactAllInProgress\"\n id=\"mvGrabBtn\"\n #mvGrabBtn\n class=\"mv-button mv-toolbar__menu-button--grab mv-tooltip\"\n data-tooltip=\"Grab and drag\"\n [ngClass]=\"onToolBarOffSetChange('mvGrabBtn')\"\n aria-pressed=\"false\"\n (click)=\"toggleGrabNDrag(); isDropdownMenuOpen = false\"\n >\n <span>{{ \"Grab and drag\" | rpxTranslate }}</span>\n </button>\n\n <button\n *ngIf=\"toolbarButtons.showDownload\"\n [disabled]=\"icpEnabled || redactionEnabled\"\n id=\"mvDownloadBtn\"\n #mvDownloadBtn\n class=\"mv-button mv-toolbar__menu-button--download mv-tooltip\"\n [attr.data-tooltip]=\"'Download' | rpxTranslate\"\n data-l10n-id=\"download\"\n [ngClass]=\"onToolBarOffSetChange('mvDownloadBtn')\"\n aria-pressed=\"false\"\n (click)=\"downloadFile(); isDropdownMenuOpen = false\"\n >\n <span>{{ \"Download\" | rpxTranslate }}</span>\n </button>\n\n <button\n *ngIf=\"toolbarButtons.showPrint\"\n [disabled]=\"icpEnabled || redactionEnabled\"\n id=\"mvPrintBtn\"\n #mvPrintBtn\n data-l10n-id=\"print\"\n aria-label=\"Print\"\n [attr.data-tooltip]=\"'Print' | rpxTranslate\"\n data-l10n-id=\"print\"\n class=\"mv-button mv-toolbar__menu-button--print mv-tooltip\"\n [ngClass]=\"onToolBarOffSetChange('mvPrintBtn')\"\n aria-pressed=\"false\"\n (click)=\"printFile(); isDropdownMenuOpen = false\"\n >\n <span>{{ \"Print\" | rpxTranslate }}</span>\n </button>\n\n <button\n *ngIf=\"enableAnnotations && toolbarButtons.showCommentSummary\"\n [disabled]=\"redactionEnabled\"\n id=\"mvCommentsBtn\"\n #mvCommentsBtn\n class=\"mv-button mv-toolbar__menu-button--comments mv-tooltip\"\n [attr.data-tooltip]=\"'Comments' | rpxTranslate\"\n data-l10n-id=\"comments\"\n [ngClass]=\"onToolBarOffSetChange('mvCommentsBtn')\"\n [attr.aria-expanded]=\"isCommentsOpen\"\n (click)=\"toggleCommentsPanel(); isDropdownMenuOpen = false\"\n >\n <span>{{ \"Comments\" | rpxTranslate }}</span>\n </button>\n </ng-template>\n </div>\n </div>\n\n <div id=\"loadingBar\">\n <div class=\"progress\">\n <div class=\"glimmer\"></div>\n </div>\n </div>\n </div>\n</div>\n" }]
5988
6506
  }], ctorParameters: () => [{ type: ToolbarEventService }, { type: ToolbarButtonVisibilityService }, { type: i0.ChangeDetectorRef }, { type: NumberHelperService }, { type: IcpEventService }], propDecorators: { enableAnnotations: [{
5989
6507
  type: Input
5990
6508
  }], enableRedactions: [{
@@ -6062,11 +6580,11 @@ class RedactionToolbarComponent {
6062
6580
  }
6063
6581
  }
6064
6582
  /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RedactionToolbarComponent, deps: [{ token: ToolbarEventService }, { token: ToolbarButtonVisibilityService }, { token: i1.Store }], target: i0.ɵɵFactoryTarget.Component }); }
6065
- /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: RedactionToolbarComponent, selector: "mv-redaction-toolbar", inputs: { showRedactSearch: "showRedactSearch" }, ngImport: i0, template: "<div class=\"redaction\">\n <label class=\"govuk-label redaction-title\" data-l10n-id=\"redaction_options\">{{\n \"Redaction options\" | rpxTranslate\n }}</label>\n <button\n id=\"toggleDrawButton\"\n class=\"mv-button redaction-button--draw\"\n title=\"{{ 'Draw a box' | rpxTranslate }}}\"\n data-l10n-id=\"toggleDrawButton\"\n (click)=\"toggleDrawMode()\"\n [disabled]=\"redactionAllInProgress\"\n >\n <span data-l10n-id=\"toggleDrawButton_label\">{{\n \"Draw a box\" | rpxTranslate\n }}</span>\n </button>\n\n <button\n id=\"redactPageButton\"\n class=\"mv-button redaction-button--redact-page\"\n title=\"{{ 'Redact page' | rpxTranslate }}\"\n data-l10n-id=\"redactPageButton\"\n (click)=\"redactPage()\"\n [disabled]=\"redactionAllInProgress\"\n >\n <span data-l10n-id=\"redactPageButton_label\">{{\n \"Redact page\" | rpxTranslate\n }}</span>\n </button>\n <button\n *ngIf=\"showRedactSearch\"\n id=\"mvRedactFromSearchBtn\"\n title=\"{{ 'From search' | rpxTranslate }}\"\n data-l10n-id=\"fromSearchButton\"\n class=\"mv-button redaction-button--search\"\n (click)=\"onRedactAllSearch()\"\n [disabled]=\"redactionAllInProgress\"\n >\n <span style=\"width: 5rem\" data-l10n-id=\"fromSearchButton_label\">{{\n \"From search\" | rpxTranslate\n }}</span>\n </button>\n\n <button\n *ngIf=\"toolbarButtons.showHighlightButton\"\n id=\"toggleHighlightButton\"\n class=\"mv-button redaction-button--redact\"\n aria-pressed=\"false\"\n title=\"{{ 'Redact text' | rpxTranslate }}\"\n data-l10n-id=\"toggleTextRedactionButton\"\n (click)=\"toggleTextRedactionMode()\"\n [disabled]=\"redactionAllInProgress\"\n >\n <span data-l10n-id=\"toggleTextRedactionButton_label\">{{\n \"Redact text\" | rpxTranslate\n }}</span>\n </button>\n\n <button\n [disabled]=\"!hasRedactions || redactionAllInProgress\"\n id=\"mvClearBtn\"\n #mvClearBtn\n class=\"mv-button redaction-button--clear\"\n aria-pressed=\"false\"\n title=\"{{ 'Clear all' | rpxTranslate }}\"\n data-l10n-id=\"toggleClearAllButton\"\n (click)=\"unmarkAll()\"\n >\n <span data-l10n-id=\"Clear all\">{{ \"Clear all\" | rpxTranslate }}</span>\n </button>\n\n <button\n [disabled]=\"!hasRedactions || redactionAllInProgress\"\n id=\"mvPreviewBtn\"\n class=\"mv-button\"\n [class.redaction-button--preview]=\"!preview\"\n [class.redaction-button--hide-preview]=\"preview\"\n redaction-button--preview\n aria-pressed=\"false\"\n title=\"{{ 'Preview' | rpxTranslate }}\"\n data-l10n-id=\"togglePreviewButton\"\n (click)=\"togglePreview()\"\n >\n <span *ngIf=\"!preview\" data-l10n-id=\"redaction-preview_label\">{{\n \"Preview\" | rpxTranslate\n }}</span>\n <span *ngIf=\"preview\" data-l10n-id=\"redaction-hide-preview_label\">{{\n \"Hide preview\" | rpxTranslate\n }}</span>\n </button>\n\n <button\n [disabled]=\"!hasRedactions || redactionAllInProgress\"\n id=\"mvRedactBtn\"\n class=\"mv-button redaction-button--download\"\n aria-pressed=\"false\"\n title=\"{{ 'Save document' | rpxTranslate }}\"\n data-l10n-id=\"mvRedactBtn\"\n (click)=\"redact()\"\n >\n <span data-l10n-id=\"Save Document\">{{\n \"Save document\" | rpxTranslate\n }}</span>\n </button>\n\n <button\n id=\"mvCloseBtn\"\n #mvCloseBtn\n class=\"mv-button redaction-button--close\"\n title=\"{{ 'Close Redaction' | rpxTranslate }}\"\n data-l10n-id=\"mvRedactBtn\"\n (click)=\"toggleRedactBar()\"\n [disabled]=\"redactionAllInProgress\"\n >\n <span data-l10n-id=\"Close Redaction\">{{\n \"Close Redaction\" | rpxTranslate\n }}</span>\n </button>\n</div>\n", dependencies: [{ kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i5$1.RpxTranslatePipe, name: "rpxTranslate" }] }); }
6583
+ /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: RedactionToolbarComponent, selector: "mv-redaction-toolbar", inputs: { showRedactSearch: "showRedactSearch" }, ngImport: i0, template: "<div class=\"redaction\">\n <label class=\"govuk-label redaction-title\" data-l10n-id=\"redaction_options\">{{\n \"Redaction options\" | rpxTranslate\n }}</label>\n <button\n id=\"toggleDrawButton\"\n class=\"mv-button redaction-button--draw mv-tooltip\"\n [attr.data-tooltip]=\"'Draw a box' | rpxTranslate\"\n data-l10n-id=\"toggleDrawButton\"\n (click)=\"toggleDrawMode()\"\n [disabled]=\"redactionAllInProgress\"\n >\n <span data-l10n-id=\"toggleDrawButton_label\">{{\n \"Draw a box\" | rpxTranslate\n }}</span>\n </button>\n <button\n id=\"redactPageButton\"\n class=\"mv-button redaction-button--redact-page mv-tooltip\"\n [attr.data-tooltip]=\"'Redact page' | rpxTranslate\"\n data-l10n-id=\"redactPageButton\"\n (click)=\"redactPage()\"\n [disabled]=\"redactionAllInProgress\"\n >\n <span data-l10n-id=\"redactPageButton_label\">{{\n \"Redact page\" | rpxTranslate\n }}</span>\n </button>\n <button\n *ngIf=\"showRedactSearch\"\n id=\"mvRedactFromSearchBtn\"\n class=\"mv-button redaction-button--search mv-tooltip\"\n [attr.data-tooltip]=\"'From search' | rpxTranslate\"\n data-l10n-id=\"fromSearchButton\"\n (click)=\"onRedactAllSearch()\"\n [disabled]=\"redactionAllInProgress\"\n >\n <span style=\"width: 5rem\" data-l10n-id=\"fromSearchButton_label\">{{\n \"From search\" | rpxTranslate\n }}</span>\n </button>\n\n <button\n *ngIf=\"toolbarButtons.showHighlightButton\"\n id=\"toggleHighlightButton\"\n class=\"mv-button redaction-button--redact mv-tooltip\"\n aria-pressed=\"false\"\n [attr.data-tooltip]=\"'Redact text' | rpxTranslate\"\n data-l10n-id=\"toggleTextRedactionButton\"\n (click)=\"toggleTextRedactionMode()\"\n [disabled]=\"redactionAllInProgress\"\n >\n <span data-l10n-id=\"toggleTextRedactionButton_label\">{{\n \"Redact text\" | rpxTranslate\n }}</span>\n </button>\n\n <button\n [disabled]=\"!hasRedactions || redactionAllInProgress\"\n id=\"mvClearBtn\"\n #mvClearBtn\n class=\"mv-button redaction-button--clear mv-tooltip\"\n aria-pressed=\"false\"\n [attr.data-tooltip]=\"'Clear all' | rpxTranslate\"\n data-l10n-id=\"toggleClearAllButton\"\n (click)=\"unmarkAll()\"\n >\n <span data-l10n-id=\"Clear all\">{{ \"Clear all\" | rpxTranslate }}</span>\n </button>\n\n <button\n [disabled]=\"!hasRedactions || redactionAllInProgress\"\n id=\"mvPreviewBtn\"\n class=\"mv-button mv-tooltip\"\n [class.redaction-button--preview]=\"!preview\"\n [class.redaction-button--hide-preview]=\"preview\"\n redaction-button--preview\n aria-pressed=\"false\"\n [attr.data-tooltip]=\"'Preview' | rpxTranslate\"\n data-l10n-id=\"togglePreviewButton\"\n (click)=\"togglePreview()\"\n >\n <span *ngIf=\"!preview\" data-l10n-id=\"redaction-preview_label\">{{\n \"Preview\" | rpxTranslate\n }}</span>\n <span *ngIf=\"preview\" data-l10n-id=\"redaction-hide-preview_label\">{{\n \"Hide preview\" | rpxTranslate\n }}</span>\n </button>\n\n <button\n [disabled]=\"!hasRedactions || redactionAllInProgress\"\n id=\"mvRedactBtn\"\n class=\"mv-button redaction-button--download mv-tooltip\"\n aria-pressed=\"false\"\n [attr.data-tooltip]=\"'Save document' | rpxTranslate\"\n data-l10n-id=\"mvRedactBtn\"\n (click)=\"redact()\"\n >\n <span data-l10n-id=\"Save Document\">{{\n \"Save document\" | rpxTranslate\n }}</span>\n </button>\n\n <button\n id=\"mvCloseBtn\"\n #mvCloseBtn\n class=\"mv-button redaction-button--close mv-tooltip\"\n [attr.data-tooltip]=\"'Close Redaction' | rpxTranslate\"\n data-l10n-id=\"mvRedactBtn\"\n (click)=\"toggleRedactBar()\"\n [disabled]=\"redactionAllInProgress\"\n >\n <span data-l10n-id=\"Close Redaction\">{{\n \"Close Redaction\" | rpxTranslate\n }}</span>\n </button>\n</div>\n", dependencies: [{ kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: TooltipDismissDirective, selector: ".mv-tooltip, [mvTooltipDismiss]" }, { kind: "pipe", type: i5$1.RpxTranslatePipe, name: "rpxTranslate" }] }); }
6066
6584
  }
6067
6585
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RedactionToolbarComponent, decorators: [{
6068
6586
  type: Component,
6069
- args: [{ selector: 'mv-redaction-toolbar', template: "<div class=\"redaction\">\n <label class=\"govuk-label redaction-title\" data-l10n-id=\"redaction_options\">{{\n \"Redaction options\" | rpxTranslate\n }}</label>\n <button\n id=\"toggleDrawButton\"\n class=\"mv-button redaction-button--draw\"\n title=\"{{ 'Draw a box' | rpxTranslate }}}\"\n data-l10n-id=\"toggleDrawButton\"\n (click)=\"toggleDrawMode()\"\n [disabled]=\"redactionAllInProgress\"\n >\n <span data-l10n-id=\"toggleDrawButton_label\">{{\n \"Draw a box\" | rpxTranslate\n }}</span>\n </button>\n\n <button\n id=\"redactPageButton\"\n class=\"mv-button redaction-button--redact-page\"\n title=\"{{ 'Redact page' | rpxTranslate }}\"\n data-l10n-id=\"redactPageButton\"\n (click)=\"redactPage()\"\n [disabled]=\"redactionAllInProgress\"\n >\n <span data-l10n-id=\"redactPageButton_label\">{{\n \"Redact page\" | rpxTranslate\n }}</span>\n </button>\n <button\n *ngIf=\"showRedactSearch\"\n id=\"mvRedactFromSearchBtn\"\n title=\"{{ 'From search' | rpxTranslate }}\"\n data-l10n-id=\"fromSearchButton\"\n class=\"mv-button redaction-button--search\"\n (click)=\"onRedactAllSearch()\"\n [disabled]=\"redactionAllInProgress\"\n >\n <span style=\"width: 5rem\" data-l10n-id=\"fromSearchButton_label\">{{\n \"From search\" | rpxTranslate\n }}</span>\n </button>\n\n <button\n *ngIf=\"toolbarButtons.showHighlightButton\"\n id=\"toggleHighlightButton\"\n class=\"mv-button redaction-button--redact\"\n aria-pressed=\"false\"\n title=\"{{ 'Redact text' | rpxTranslate }}\"\n data-l10n-id=\"toggleTextRedactionButton\"\n (click)=\"toggleTextRedactionMode()\"\n [disabled]=\"redactionAllInProgress\"\n >\n <span data-l10n-id=\"toggleTextRedactionButton_label\">{{\n \"Redact text\" | rpxTranslate\n }}</span>\n </button>\n\n <button\n [disabled]=\"!hasRedactions || redactionAllInProgress\"\n id=\"mvClearBtn\"\n #mvClearBtn\n class=\"mv-button redaction-button--clear\"\n aria-pressed=\"false\"\n title=\"{{ 'Clear all' | rpxTranslate }}\"\n data-l10n-id=\"toggleClearAllButton\"\n (click)=\"unmarkAll()\"\n >\n <span data-l10n-id=\"Clear all\">{{ \"Clear all\" | rpxTranslate }}</span>\n </button>\n\n <button\n [disabled]=\"!hasRedactions || redactionAllInProgress\"\n id=\"mvPreviewBtn\"\n class=\"mv-button\"\n [class.redaction-button--preview]=\"!preview\"\n [class.redaction-button--hide-preview]=\"preview\"\n redaction-button--preview\n aria-pressed=\"false\"\n title=\"{{ 'Preview' | rpxTranslate }}\"\n data-l10n-id=\"togglePreviewButton\"\n (click)=\"togglePreview()\"\n >\n <span *ngIf=\"!preview\" data-l10n-id=\"redaction-preview_label\">{{\n \"Preview\" | rpxTranslate\n }}</span>\n <span *ngIf=\"preview\" data-l10n-id=\"redaction-hide-preview_label\">{{\n \"Hide preview\" | rpxTranslate\n }}</span>\n </button>\n\n <button\n [disabled]=\"!hasRedactions || redactionAllInProgress\"\n id=\"mvRedactBtn\"\n class=\"mv-button redaction-button--download\"\n aria-pressed=\"false\"\n title=\"{{ 'Save document' | rpxTranslate }}\"\n data-l10n-id=\"mvRedactBtn\"\n (click)=\"redact()\"\n >\n <span data-l10n-id=\"Save Document\">{{\n \"Save document\" | rpxTranslate\n }}</span>\n </button>\n\n <button\n id=\"mvCloseBtn\"\n #mvCloseBtn\n class=\"mv-button redaction-button--close\"\n title=\"{{ 'Close Redaction' | rpxTranslate }}\"\n data-l10n-id=\"mvRedactBtn\"\n (click)=\"toggleRedactBar()\"\n [disabled]=\"redactionAllInProgress\"\n >\n <span data-l10n-id=\"Close Redaction\">{{\n \"Close Redaction\" | rpxTranslate\n }}</span>\n </button>\n</div>\n" }]
6587
+ args: [{ selector: 'mv-redaction-toolbar', template: "<div class=\"redaction\">\n <label class=\"govuk-label redaction-title\" data-l10n-id=\"redaction_options\">{{\n \"Redaction options\" | rpxTranslate\n }}</label>\n <button\n id=\"toggleDrawButton\"\n class=\"mv-button redaction-button--draw mv-tooltip\"\n [attr.data-tooltip]=\"'Draw a box' | rpxTranslate\"\n data-l10n-id=\"toggleDrawButton\"\n (click)=\"toggleDrawMode()\"\n [disabled]=\"redactionAllInProgress\"\n >\n <span data-l10n-id=\"toggleDrawButton_label\">{{\n \"Draw a box\" | rpxTranslate\n }}</span>\n </button>\n <button\n id=\"redactPageButton\"\n class=\"mv-button redaction-button--redact-page mv-tooltip\"\n [attr.data-tooltip]=\"'Redact page' | rpxTranslate\"\n data-l10n-id=\"redactPageButton\"\n (click)=\"redactPage()\"\n [disabled]=\"redactionAllInProgress\"\n >\n <span data-l10n-id=\"redactPageButton_label\">{{\n \"Redact page\" | rpxTranslate\n }}</span>\n </button>\n <button\n *ngIf=\"showRedactSearch\"\n id=\"mvRedactFromSearchBtn\"\n class=\"mv-button redaction-button--search mv-tooltip\"\n [attr.data-tooltip]=\"'From search' | rpxTranslate\"\n data-l10n-id=\"fromSearchButton\"\n (click)=\"onRedactAllSearch()\"\n [disabled]=\"redactionAllInProgress\"\n >\n <span style=\"width: 5rem\" data-l10n-id=\"fromSearchButton_label\">{{\n \"From search\" | rpxTranslate\n }}</span>\n </button>\n\n <button\n *ngIf=\"toolbarButtons.showHighlightButton\"\n id=\"toggleHighlightButton\"\n class=\"mv-button redaction-button--redact mv-tooltip\"\n aria-pressed=\"false\"\n [attr.data-tooltip]=\"'Redact text' | rpxTranslate\"\n data-l10n-id=\"toggleTextRedactionButton\"\n (click)=\"toggleTextRedactionMode()\"\n [disabled]=\"redactionAllInProgress\"\n >\n <span data-l10n-id=\"toggleTextRedactionButton_label\">{{\n \"Redact text\" | rpxTranslate\n }}</span>\n </button>\n\n <button\n [disabled]=\"!hasRedactions || redactionAllInProgress\"\n id=\"mvClearBtn\"\n #mvClearBtn\n class=\"mv-button redaction-button--clear mv-tooltip\"\n aria-pressed=\"false\"\n [attr.data-tooltip]=\"'Clear all' | rpxTranslate\"\n data-l10n-id=\"toggleClearAllButton\"\n (click)=\"unmarkAll()\"\n >\n <span data-l10n-id=\"Clear all\">{{ \"Clear all\" | rpxTranslate }}</span>\n </button>\n\n <button\n [disabled]=\"!hasRedactions || redactionAllInProgress\"\n id=\"mvPreviewBtn\"\n class=\"mv-button mv-tooltip\"\n [class.redaction-button--preview]=\"!preview\"\n [class.redaction-button--hide-preview]=\"preview\"\n redaction-button--preview\n aria-pressed=\"false\"\n [attr.data-tooltip]=\"'Preview' | rpxTranslate\"\n data-l10n-id=\"togglePreviewButton\"\n (click)=\"togglePreview()\"\n >\n <span *ngIf=\"!preview\" data-l10n-id=\"redaction-preview_label\">{{\n \"Preview\" | rpxTranslate\n }}</span>\n <span *ngIf=\"preview\" data-l10n-id=\"redaction-hide-preview_label\">{{\n \"Hide preview\" | rpxTranslate\n }}</span>\n </button>\n\n <button\n [disabled]=\"!hasRedactions || redactionAllInProgress\"\n id=\"mvRedactBtn\"\n class=\"mv-button redaction-button--download mv-tooltip\"\n aria-pressed=\"false\"\n [attr.data-tooltip]=\"'Save document' | rpxTranslate\"\n data-l10n-id=\"mvRedactBtn\"\n (click)=\"redact()\"\n >\n <span data-l10n-id=\"Save Document\">{{\n \"Save document\" | rpxTranslate\n }}</span>\n </button>\n\n <button\n id=\"mvCloseBtn\"\n #mvCloseBtn\n class=\"mv-button redaction-button--close mv-tooltip\"\n [attr.data-tooltip]=\"'Close Redaction' | rpxTranslate\"\n data-l10n-id=\"mvRedactBtn\"\n (click)=\"toggleRedactBar()\"\n [disabled]=\"redactionAllInProgress\"\n >\n <span data-l10n-id=\"Close Redaction\">{{\n \"Close Redaction\" | rpxTranslate\n }}</span>\n </button>\n</div>\n" }]
6070
6588
  }], ctorParameters: () => [{ type: ToolbarEventService }, { type: ToolbarButtonVisibilityService }, { type: i1.Store }], propDecorators: { showRedactSearch: [{
6071
6589
  type: Input
6072
6590
  }] } });
@@ -6137,11 +6655,11 @@ class HighlightToolbarComponent {
6137
6655
  }
6138
6656
  }
6139
6657
  /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: HighlightToolbarComponent, deps: [{ token: ToolbarEventService }, { token: ToolbarButtonVisibilityService }], target: i0.ɵɵFactoryTarget.Component }); }
6140
- /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: HighlightToolbarComponent, selector: "mv-highlight-toolbar", ngImport: i0, template: "<div class=\"redaction\">\n <label class=\"govuk-label redaction-title\" data-l10n-id=\"redaction_options\"\n >Highlight options</label\n >\n\n <button\n id=\"mvDrawBtn\"\n #mvDrawBtn\n class=\"mv-button mv-toolbar__menu-button--draw\"\n title=\"Draw a box\"\n [class.toggled]=\"toolbarEventService.drawModeSubject | async\"\n aria-pressed=\"false\"\n data-l10n-id=\"mvDrawBtn\"\n (click)=\"onClickDrawToggle()\"\n [disabled]=\"redactionAllInProgress\"\n >\n <span data-l10n-id=\"draw_label\">Draw a box</span>\n </button>\n\n <button\n id=\"highlightTextBtn\"\n class=\"mv-button mv-toolbar__menu-button--highlight\"\n title=\"Highlight text\"\n data-l10n-id=\"highlightTextBtn\"\n (click)=\"onHighlight()\"\n [class.toggled]=\"toolbarEventService.highlightModeSubject | async\"\n [disabled]=\"redactionAllInProgress\"\n >\n <span data-l10n-id=\"highlightTextBtn_label\">Highlight text</span>\n </button>\n\n <button\n id=\"mvHighlightFromSearchBtn\"\n title=\"From search\"\n data-l10n-id=\"fromSearchButton\"\n class=\"mv-button redaction-button--search\"\n (click)=\"onAllSearch()\"\n [disabled]=\"redactionAllInProgress\"\n >\n <span style=\"width: 5rem\" data-l10n-id=\"fromSearchButton_label\"\n >From search</span\n >\n </button>\n\n <button\n id=\"mvCloseBtn\"\n #mvCloseBtn\n class=\"mv-button redaction-button--close\"\n title=\"Close Redaction\"\n data-l10n-id=\"mvRedactBtn\"\n (click)=\"onClose()\"\n [disabled]=\"redactionAllInProgress\"\n >\n <span data-l10n-id=\"Close Redaction\">Close Highlight</span>\n </button>\n</div>\n", styles: [""], dependencies: [{ kind: "pipe", type: i5.AsyncPipe, name: "async" }] }); }
6658
+ /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: HighlightToolbarComponent, selector: "mv-highlight-toolbar", ngImport: i0, template: "<div class=\"redaction\">\n <label class=\"govuk-label redaction-title\" data-l10n-id=\"redaction_options\"\n >{{ \"Highlight options\" | rpxTranslate }}</label\n >\n\n <button\n id=\"mvDrawBtn\"\n #mvDrawBtn\n class=\"mv-button mv-toolbar__menu-button--draw mv-tooltip\"\n [attr.data-tooltip]=\"'Draw a box' | rpxTranslate\"\n [class.toggled]=\"toolbarEventService.drawModeSubject | async\"\n aria-pressed=\"false\"\n data-l10n-id=\"mvDrawBtn\"\n (click)=\"onClickDrawToggle()\"\n [disabled]=\"redactionAllInProgress\"\n >\n <span data-l10n-id=\"draw_label\">{{ \"Draw a box\" | rpxTranslate }}</span>\n </button>\n\n <button\n id=\"highlightTextBtn\"\n class=\"mv-button mv-toolbar__menu-button--highlight mv-tooltip\"\n [attr.data-tooltip]=\"'Highlight text' | rpxTranslate\"\n data-l10n-id=\"highlightTextBtn\"\n (click)=\"onHighlight()\"\n [class.toggled]=\"toolbarEventService.highlightModeSubject | async\"\n [disabled]=\"redactionAllInProgress\"\n >\n <span data-l10n-id=\"highlightTextBtn_label\">{{ \"Highlight text\" | rpxTranslate }}</span>\n </button>\n\n <button\n id=\"mvHighlightFromSearchBtn\"\n [attr.data-tooltip]=\"'From search' | rpxTranslate\"\n data-l10n-id=\"fromSearchButton\"\n class=\"mv-button redaction-button--search mv-tooltip\"\n (click)=\"onAllSearch()\"\n [disabled]=\"redactionAllInProgress\"\n >\n <span style=\"width: 5rem\" data-l10n-id=\"fromSearchButton_label\"\n >{{ \"From search\" | rpxTranslate }}</span\n >\n </button>\n\n <button\n id=\"mvCloseBtn\"\n #mvCloseBtn\n class=\"mv-button redaction-button--close mv-tooltip\"\n [attr.data-tooltip]=\"'Close highlight' | rpxTranslate\"\n data-l10n-id=\"mvRedactBtn\"\n (click)=\"onClose()\"\n [disabled]=\"redactionAllInProgress\"\n >\n <span data-l10n-id=\"Close Redaction\">{{ \"Close Highlight\" | rpxTranslate }}</span>\n </button>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: TooltipDismissDirective, selector: ".mv-tooltip, [mvTooltipDismiss]" }, { kind: "pipe", type: i5.AsyncPipe, name: "async" }, { kind: "pipe", type: i5$1.RpxTranslatePipe, name: "rpxTranslate" }] }); }
6141
6659
  }
6142
6660
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: HighlightToolbarComponent, decorators: [{
6143
6661
  type: Component,
6144
- args: [{ selector: 'mv-highlight-toolbar', template: "<div class=\"redaction\">\n <label class=\"govuk-label redaction-title\" data-l10n-id=\"redaction_options\"\n >Highlight options</label\n >\n\n <button\n id=\"mvDrawBtn\"\n #mvDrawBtn\n class=\"mv-button mv-toolbar__menu-button--draw\"\n title=\"Draw a box\"\n [class.toggled]=\"toolbarEventService.drawModeSubject | async\"\n aria-pressed=\"false\"\n data-l10n-id=\"mvDrawBtn\"\n (click)=\"onClickDrawToggle()\"\n [disabled]=\"redactionAllInProgress\"\n >\n <span data-l10n-id=\"draw_label\">Draw a box</span>\n </button>\n\n <button\n id=\"highlightTextBtn\"\n class=\"mv-button mv-toolbar__menu-button--highlight\"\n title=\"Highlight text\"\n data-l10n-id=\"highlightTextBtn\"\n (click)=\"onHighlight()\"\n [class.toggled]=\"toolbarEventService.highlightModeSubject | async\"\n [disabled]=\"redactionAllInProgress\"\n >\n <span data-l10n-id=\"highlightTextBtn_label\">Highlight text</span>\n </button>\n\n <button\n id=\"mvHighlightFromSearchBtn\"\n title=\"From search\"\n data-l10n-id=\"fromSearchButton\"\n class=\"mv-button redaction-button--search\"\n (click)=\"onAllSearch()\"\n [disabled]=\"redactionAllInProgress\"\n >\n <span style=\"width: 5rem\" data-l10n-id=\"fromSearchButton_label\"\n >From search</span\n >\n </button>\n\n <button\n id=\"mvCloseBtn\"\n #mvCloseBtn\n class=\"mv-button redaction-button--close\"\n title=\"Close Redaction\"\n data-l10n-id=\"mvRedactBtn\"\n (click)=\"onClose()\"\n [disabled]=\"redactionAllInProgress\"\n >\n <span data-l10n-id=\"Close Redaction\">Close Highlight</span>\n </button>\n</div>\n" }]
6662
+ args: [{ selector: 'mv-highlight-toolbar', template: "<div class=\"redaction\">\n <label class=\"govuk-label redaction-title\" data-l10n-id=\"redaction_options\"\n >{{ \"Highlight options\" | rpxTranslate }}</label\n >\n\n <button\n id=\"mvDrawBtn\"\n #mvDrawBtn\n class=\"mv-button mv-toolbar__menu-button--draw mv-tooltip\"\n [attr.data-tooltip]=\"'Draw a box' | rpxTranslate\"\n [class.toggled]=\"toolbarEventService.drawModeSubject | async\"\n aria-pressed=\"false\"\n data-l10n-id=\"mvDrawBtn\"\n (click)=\"onClickDrawToggle()\"\n [disabled]=\"redactionAllInProgress\"\n >\n <span data-l10n-id=\"draw_label\">{{ \"Draw a box\" | rpxTranslate }}</span>\n </button>\n\n <button\n id=\"highlightTextBtn\"\n class=\"mv-button mv-toolbar__menu-button--highlight mv-tooltip\"\n [attr.data-tooltip]=\"'Highlight text' | rpxTranslate\"\n data-l10n-id=\"highlightTextBtn\"\n (click)=\"onHighlight()\"\n [class.toggled]=\"toolbarEventService.highlightModeSubject | async\"\n [disabled]=\"redactionAllInProgress\"\n >\n <span data-l10n-id=\"highlightTextBtn_label\">{{ \"Highlight text\" | rpxTranslate }}</span>\n </button>\n\n <button\n id=\"mvHighlightFromSearchBtn\"\n [attr.data-tooltip]=\"'From search' | rpxTranslate\"\n data-l10n-id=\"fromSearchButton\"\n class=\"mv-button redaction-button--search mv-tooltip\"\n (click)=\"onAllSearch()\"\n [disabled]=\"redactionAllInProgress\"\n >\n <span style=\"width: 5rem\" data-l10n-id=\"fromSearchButton_label\"\n >{{ \"From search\" | rpxTranslate }}</span\n >\n </button>\n\n <button\n id=\"mvCloseBtn\"\n #mvCloseBtn\n class=\"mv-button redaction-button--close mv-tooltip\"\n [attr.data-tooltip]=\"'Close highlight' | rpxTranslate\"\n data-l10n-id=\"mvRedactBtn\"\n (click)=\"onClose()\"\n [disabled]=\"redactionAllInProgress\"\n >\n <span data-l10n-id=\"Close Redaction\">{{ \"Close Highlight\" | rpxTranslate }}</span>\n </button>\n</div>\n" }]
6145
6663
  }], ctorParameters: () => [{ type: ToolbarEventService }, { type: ToolbarButtonVisibilityService }] });
6146
6664
 
6147
6665
  /*
@@ -6457,7 +6975,7 @@ class ConvertibleContentViewerComponent {
6457
6975
  this.documentTitle = new EventEmitter();
6458
6976
  }
6459
6977
  ngOnInit() {
6460
- this.$subscription = this.store.pipe(select(getConvertedDocument), filter(value => !!value))
6978
+ this.$subscription = this.store.pipe(select(getConvertedDocument), filter$1(value => !!value))
6461
6979
  .subscribe((docInfo) => {
6462
6980
  if (docInfo.url) {
6463
6981
  this.convertedUrl = docInfo.url;
@@ -6542,7 +7060,7 @@ class RotationPersistDirective {
6542
7060
  onMediaLoad(status) {
6543
7061
  this.rotation = 0;
6544
7062
  this.store.dispatch(new LoadRotation(this.documentId));
6545
- this.store.pipe(select(rotationLoaded), filter(value => !!value), take(1))
7063
+ this.store.pipe(select(rotationLoaded), filter$1(value => !!value), take(1))
6546
7064
  .subscribe(() => {
6547
7065
  if (this.savedRotation) {
6548
7066
  this.toolbarEvents.rotateSubject.next(this.savedRotation);
@@ -6817,7 +7335,8 @@ class ToolbarModule {
6817
7335
  RedactionToolbarComponent,
6818
7336
  IcpToolbarComponent,
6819
7337
  RedactionSearchBarComponent,
6820
- HighlightToolbarComponent], imports: [CommonModule,
7338
+ HighlightToolbarComponent,
7339
+ TooltipDismissDirective], imports: [CommonModule,
6821
7340
  FormsModule,
6822
7341
  OverlayModule,
6823
7342
  RouterModule, i5$1.RpxTranslationModule], exports: [MainToolbarComponent,
@@ -6843,7 +7362,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
6843
7362
  RedactionToolbarComponent,
6844
7363
  IcpToolbarComponent,
6845
7364
  RedactionSearchBarComponent,
6846
- HighlightToolbarComponent
7365
+ HighlightToolbarComponent,
7366
+ TooltipDismissDirective
6847
7367
  ],
6848
7368
  providers: [
6849
7369
  ToolbarButtonVisibilityService
@@ -6861,7 +7381,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
6861
7381
  FormsModule,
6862
7382
  OverlayModule,
6863
7383
  RouterModule,
6864
- RpxTranslationModule.forChild(),
7384
+ RpxTranslationModule.forChild()
6865
7385
  ]
6866
7386
  }]
6867
7387
  }] });
@@ -7387,6 +7907,7 @@ class MediaViewerModule {
7387
7907
  GrabNDragDirective,
7388
7908
  RotationPersistDirective,
7389
7909
  HighlightCreateDirective,
7910
+ KeyboardTextHighlightDirective,
7390
7911
  ConfirmActionDialogComponent,
7391
7912
  RedactionComponent,
7392
7913
  BookmarkIconsComponent,
@@ -7453,6 +7974,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
7453
7974
  GrabNDragDirective,
7454
7975
  RotationPersistDirective,
7455
7976
  HighlightCreateDirective,
7977
+ KeyboardTextHighlightDirective,
7456
7978
  ConfirmActionDialogComponent,
7457
7979
  RedactionComponent,
7458
7980
  BookmarkIconsComponent,