@hmcts/media-viewer 4.1.9-exui-1580 → 4.1.9-exui-2821-1

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 (26) hide show
  1. package/assets/sass/pdf-viewer.scss +1 -79
  2. package/esm2022/lib/annotations/annotation-set/annotation-create/highlight-create/highlight-create.directive.mjs +21 -80
  3. package/esm2022/lib/annotations/annotation-set/annotation-view/annotation-view.component.mjs +1 -1
  4. package/esm2022/lib/annotations/annotation-set/ctx-toolbar/ctx-toolbar.component.mjs +5 -31
  5. package/esm2022/lib/annotations/annotation-set/metadata-layer/metadata-layer.component.mjs +4 -17
  6. package/esm2022/lib/icp/confirm-exit/confirm-action-dialog.component.mjs +13 -5
  7. package/esm2022/lib/media-viewer.module.mjs +1 -4
  8. package/esm2022/lib/viewers/pdf-viewer/pdf-viewer.component.mjs +7 -45
  9. package/fesm2022/hmcts-media-viewer.mjs +724 -1202
  10. package/fesm2022/hmcts-media-viewer.mjs.map +1 -1
  11. package/lib/annotations/annotation-set/annotation-create/highlight-create/highlight-create.directive.d.ts +2 -6
  12. package/lib/annotations/annotation-set/annotation-create/highlight-create/highlight-create.directive.d.ts.map +1 -1
  13. package/lib/annotations/annotation-set/ctx-toolbar/ctx-toolbar.component.d.ts +2 -6
  14. package/lib/annotations/annotation-set/ctx-toolbar/ctx-toolbar.component.d.ts.map +1 -1
  15. package/lib/annotations/annotation-set/metadata-layer/metadata-layer.component.d.ts +0 -3
  16. package/lib/annotations/annotation-set/metadata-layer/metadata-layer.component.d.ts.map +1 -1
  17. package/lib/icp/confirm-exit/confirm-action-dialog.component.d.ts +4 -1
  18. package/lib/icp/confirm-exit/confirm-action-dialog.component.d.ts.map +1 -1
  19. package/lib/media-viewer.module.d.ts +18 -19
  20. package/lib/media-viewer.module.d.ts.map +1 -1
  21. package/lib/viewers/pdf-viewer/pdf-viewer.component.d.ts +0 -20
  22. package/lib/viewers/pdf-viewer/pdf-viewer.component.d.ts.map +1 -1
  23. package/package.json +1 -1
  24. package/esm2022/lib/annotations/annotation-set/annotation-create/highlight-create/keyboard-text-highlight.directive.mjs +0 -354
  25. package/lib/annotations/annotation-set/annotation-create/highlight-create/keyboard-text-highlight.directive.d.ts +0 -63
  26. package/lib/annotations/annotation-set/annotation-create/highlight-create/keyboard-text-highlight.directive.d.ts.map +0 -1
@@ -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, Directive, HostListener, Component, ViewChild, Input, ViewEncapsulation, Pipe, EventEmitter, Output, ViewChildren, NgModule } from '@angular/core';
4
+ import { Injectable, Component, ViewChild, HostListener, Directive, 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, 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';
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';
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,626 +1526,6 @@ const getConvertedDocument = createSelector(getDocumentState, getConvertedDocume
1526
1526
  const getRotation = createSelector(getDocumentState, getRotation$1);
1527
1527
  const rotationLoaded = createSelector(getDocumentState, rotationLoaded$1);
1528
1528
 
1529
- /**
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
- }
1544
- }
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}`);
1553
- }
1554
- return element.getBoundingClientRect();
1555
- }
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);
1657
- }
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);
1668
- }
1669
- else {
1670
- this.drawModeSubject.next(false);
1671
- }
1672
- }
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);
1738
- }
1739
- this.openRedactionSearch.next({ modeType: SearchType.Redact, isOpen: false });
1740
- }
1741
- toggleRedactionPreview(viewMode) {
1742
- this.redactionPreview.next(viewMode);
1743
- }
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);
1756
- }
1757
- this.commentsPanelVisible.next(isVisible);
1758
- }
1759
- toggleParticipantsList(isVisible) {
1760
- if (isVisible) {
1761
- this.toggleCommentsPanel(!isVisible);
1762
- }
1763
- this.icpEventService.participantsListVisible.next(isVisible);
1764
- }
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
- });
1847
- });
1848
- return arr;
1849
- }
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
- };
1862
- });
1863
- }
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
- };
1879
- });
1880
- }
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;
1894
- }
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
- });
1915
- }
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
- });
1940
- }
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;
1968
- }
1969
- resetHighlight() {
1970
- window.getSelection().removeAllRanges();
1971
- this.toolBarEvents.highlightModeSubject.next(false);
1972
- }
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 = [];
1989
- }
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
- }));
1999
- }
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
- }
2013
- }
2014
- }
2015
- if (this.toolbarEvents.highlightModeSubject.getValue()) {
2016
- const rectangles = this.getRectangles(mouseEvent, page);
2017
- this.viewerEvents.textSelected({ page, rectangles });
2018
- }
2019
- }
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
- }
2031
- }
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;
2048
- }
2049
- getRectanglesFromSelection(selection, page) {
2050
- if (!this.allPages || !this.allPages[page]) {
2051
- return [];
2052
- }
2053
- this.setPageProperties(page);
2054
- const range = selection.getRangeAt(0).cloneRange();
2055
- const clientRects = range.getClientRects();
2056
- if (!clientRects || clientRects.length === 0) {
2057
- return [];
2058
- }
2059
- let textLayerElement = range.startContainer;
2060
- if (textLayerElement.nodeType === Node.TEXT_NODE) {
2061
- textLayerElement = textLayerElement.parentElement;
2062
- }
2063
- const textLayer = textLayerElement.closest('.textLayer');
2064
- if (!textLayer) {
2065
- return [];
2066
- }
2067
- this.removeEnhancedTextModeStyling(textLayerElement);
2068
- return this.processClientRects(clientRects, textLayer);
2069
- }
2070
- onPdfViewerClick(event) {
2071
- this.store.dispatch(new SelectedAnnotation({
2072
- annotationId: '',
2073
- selected: false,
2074
- editable: false,
2075
- }));
2076
- this.viewerEvents.clearCtxToolbar();
2077
- }
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
- }
2093
- }
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;
2102
- }
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
- }
2114
- }
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);
2120
- }
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;
2132
- }
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 }); }
2135
- }
2136
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: HighlightCreateDirective, decorators: [{
2137
- type: Directive,
2138
- args: [{
2139
- selector: '[mvCreateTextHighlight]'
2140
- }]
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
- }] } });
2148
-
2149
1529
  pdfjs.GlobalWorkerOptions.workerSrc = '/assets/build/pdf.worker.min.js';
2150
1530
  /**
2151
1531
  * Values of the state field returned by the find events
@@ -2383,30 +1763,245 @@ class PdfJsWrapper {
2383
1763
  if (zoomValue > 5) {
2384
1764
  return 5;
2385
1765
  }
2386
- if (zoomValue < 0.1) {
2387
- return 0.1;
1766
+ if (zoomValue < 0.1) {
1767
+ return 0.1;
1768
+ }
1769
+ return +zoomValue.toFixed(2);
1770
+ }
1771
+ rotate(rotation) {
1772
+ return this.pdfViewer.pagesRotation = (this.pdfViewer.pagesRotation + rotation) % 360;
1773
+ }
1774
+ resetRotation(rotation) {
1775
+ return this.pdfViewer.pagesRotation = rotation;
1776
+ }
1777
+ getNormalisedPagesRotation() {
1778
+ return this.pdfViewer.pagesRotation;
1779
+ }
1780
+ getCurrentPDFZoomValue() {
1781
+ return +this.pdfViewer.currentScaleValue;
1782
+ }
1783
+ setCurrentPDFTitle(title) {
1784
+ this.documentTitle = title;
1785
+ }
1786
+ getCurrentPDFTitle() {
1787
+ return this.documentTitle;
1788
+ }
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
+ };
1821
+ }
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' }); }
1824
+ }
1825
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: IcpEventService, decorators: [{
1826
+ type: Injectable,
1827
+ args: [{
1828
+ providedIn: 'root'
1829
+ }]
1830
+ }], ctorParameters: () => [] });
1831
+
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);
1870
+ }
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);
1882
+ }
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);
1890
+ }
1891
+ else {
1892
+ this.highlightModeSubject.next(false);
1893
+ }
1894
+ }
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);
1904
+ }
1905
+ }
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();
1917
+ }
1918
+ zoom(value) {
1919
+ this.zoomSubject.next(value);
1920
+ }
1921
+ stepZoom(value) {
1922
+ this.stepZoomSubject.next(value);
1923
+ }
1924
+ getZoomValue() {
1925
+ return this.zoomValueSubject.asObservable();
1926
+ }
1927
+ getPageCount() {
1928
+ return this.pageCountSubject.asObservable();
1929
+ }
1930
+ print() {
1931
+ this.printSubject.next();
1932
+ }
1933
+ download() {
1934
+ this.downloadSubject.next();
1935
+ }
1936
+ setPage(value) {
1937
+ this.setCurrentPageSubject.next(value);
1938
+ }
1939
+ incrementPage(value) {
1940
+ this.changePageByDeltaSubject.next(value);
1941
+ }
1942
+ getCurrentPageNumber() {
1943
+ return this.setCurrentPageInputValueSubject.asObservable();
1944
+ }
1945
+ getShowCommentSummary() {
1946
+ return this.showCommentSummary.asObservable();
1947
+ }
1948
+ toggleCommentsSummary(value) {
1949
+ this.showCommentSummary.next(value);
1950
+ }
1951
+ saveRotation() {
1952
+ this.saveRotationSubject.next();
1953
+ }
1954
+ toggleGrabNDrag() {
1955
+ this.grabNDrag.next(!this.grabNDrag.getValue());
1956
+ }
1957
+ toggleSideBar(toggle) {
1958
+ this.sidebarOpen.next(toggle);
1959
+ }
1960
+ toggleSideBarView(toggle) {
1961
+ this.sidebarOutlineView.next(toggle);
1962
+ }
1963
+ toggleRedactionMode() {
1964
+ if (this.redactionMode.getValue() === false) {
1965
+ this.drawModeSubject.next(false);
1966
+ this.grabNDrag.next(false);
1967
+ this.redactionMode.next(true);
1968
+ }
1969
+ else {
1970
+ this.redactionMode.next(false);
2388
1971
  }
2389
- return +zoomValue.toFixed(2);
1972
+ this.openRedactionSearch.next({ modeType: SearchType.Redact, isOpen: false });
2390
1973
  }
2391
- rotate(rotation) {
2392
- return this.pdfViewer.pagesRotation = (this.pdfViewer.pagesRotation + rotation) % 360;
1974
+ toggleRedactionPreview(viewMode) {
1975
+ this.redactionPreview.next(viewMode);
2393
1976
  }
2394
- resetRotation(rotation) {
2395
- return this.pdfViewer.pagesRotation = rotation;
1977
+ unmarkAll() {
1978
+ this.clearAllRedactMarkers.next();
2396
1979
  }
2397
- getNormalisedPagesRotation() {
2398
- return this.pdfViewer.pagesRotation;
1980
+ applyRedactionToDocument() {
1981
+ this.applyRedactToDocument.next();
2399
1982
  }
2400
- getCurrentPDFZoomValue() {
2401
- return +this.pdfViewer.currentScaleValue;
1983
+ redactPage() {
1984
+ this.redactWholePage.next();
2402
1985
  }
2403
- setCurrentPDFTitle(title) {
2404
- this.documentTitle = title;
1986
+ toggleCommentsPanel(isVisible) {
1987
+ if (isVisible) {
1988
+ this.toggleParticipantsList(!isVisible);
1989
+ }
1990
+ this.commentsPanelVisible.next(isVisible);
2405
1991
  }
2406
- getCurrentPDFTitle() {
2407
- return this.documentTitle;
1992
+ toggleParticipantsList(isVisible) {
1993
+ if (isVisible) {
1994
+ this.toggleCommentsPanel(!isVisible);
1995
+ }
1996
+ this.icpEventService.participantsListVisible.next(isVisible);
2408
1997
  }
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' }); }
2409
2000
  }
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 }] });
2410
2005
 
2411
2006
  class PdfJsWrapperFactory {
2412
2007
  constructor(toolbarEvents) {
@@ -2471,6 +2066,37 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
2471
2066
  }]
2472
2067
  }] });
2473
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);
2091
+ }
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' }); }
2094
+ }
2095
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ViewerEventService, decorators: [{
2096
+ type: Injectable,
2097
+ args: [{ providedIn: 'root' }]
2098
+ }], ctorParameters: () => [] });
2099
+
2474
2100
  const getIcpState = createSelector(getMVState, (state) => state.icp);
2475
2101
  const getIcpSession = createSelector(getIcpState, getIcpSession$1);
2476
2102
  const getCaseId = createSelector(getIcpSession, session => session === null ? null : session.caseId);
@@ -2802,7 +2428,7 @@ class IcpService {
2802
2428
  this.followerSubscriptions = followerSubscriptions;
2803
2429
  this.store = store;
2804
2430
  this.icpEventService = icpEventService;
2805
- this.subscription = this.store.pipe(select(getCaseId), filter$1(value => !!value)).subscribe(caseId => {
2431
+ this.subscription = this.store.pipe(select(getCaseId), filter(value => !!value)).subscribe(caseId => {
2806
2432
  this.caseId = caseId;
2807
2433
  });
2808
2434
  this.subscription.add(this.store.pipe(select(getDocumentId)).subscribe(docId => this.documentId = docId));
@@ -2818,7 +2444,7 @@ class IcpService {
2818
2444
  }
2819
2445
  launchSession() {
2820
2446
  this.store.dispatch(new LoadIcpSession({ caseId: this.caseId, documentId: this.documentId }));
2821
- this.subscription.add(this.store.pipe(select(getIcpSession), filter$1(value => !!value && Object.keys(value).length > 1), take(1)).subscribe(() => { this.setUpSessionSubscriptions(); }));
2447
+ this.subscription.add(this.store.pipe(select(getIcpSession), filter(value => !!value && Object.keys(value).length > 1), take(1)).subscribe(() => { this.setUpSessionSubscriptions(); }));
2822
2448
  }
2823
2449
  setUpSessionSubscriptions() {
2824
2450
  this.sessionSubscription = this.icpEventService.becomingPresenter.subscribe(() => this.becomePresenter());
@@ -2969,6 +2595,212 @@ const defaultUnsupportedOptions = {
2969
2595
  showPrint: true
2970
2596
  };
2971
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 }] });
2803
+
2972
2804
  class RedactionSearchBarComponent {
2973
2805
  constructor(store, toolbarButtons, toolbarEvents, highlightService) {
2974
2806
  this.store = store;
@@ -4057,148 +3889,6 @@ const getBookmarksPerPage = createSelector(getPages, getBookmarkPages, (pages, p
4057
3889
  }
4058
3890
  });
4059
3891
 
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
-
4202
3892
  class BoxHighlightCreateComponent {
4203
3893
  constructor(toolbarEvents, highlightService) {
4204
3894
  this.toolbarEvents = toolbarEvents;
@@ -4371,57 +4061,173 @@ class RectangleComponent {
4371
4061
  const { top, left, height, width } = this;
4372
4062
  switch (rotation) {
4373
4063
  case 90:
4374
- this.width = height;
4375
- this.height = width;
4376
- this.left = this.pageWidth - top - height;
4377
- this.top = left;
4064
+ this.width = height;
4065
+ this.height = width;
4066
+ this.left = this.pageWidth - top - height;
4067
+ this.top = left;
4068
+ break;
4069
+ case 180:
4070
+ this.left = this.pageWidth - left - width;
4071
+ this.top = this.pageHeight - top - height;
4072
+ break;
4073
+ 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;
4378
4171
  break;
4379
4172
  case 180:
4380
- this.left = this.pageWidth - left - width;
4381
- this.top = this.pageHeight - top - height;
4173
+ this.rectangle.x = (this.pageWidth / this.zoom) - rectangle.x - rectangle.width;
4174
+ this.rectangle.y = (this.pageHeight / this.zoom) - rectangle.y - rectangle.height;
4382
4175
  break;
4383
4176
  case 270:
4384
- this.width = height;
4385
- this.height = width;
4386
- this.left = top;
4387
- this.top = this.pageHeight - left - width;
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;
4388
4181
  break;
4389
4182
  }
4390
4183
  }
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;
4184
+ popupTop() {
4185
+ const popupTop = this.rectangle.y * this.zoom - this.defaultHeight;
4186
+ return popupTop <= 0 ? this.defaultHeight : popupTop;
4396
4187
  }
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"] }] }); }
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
+ }
4199
+ }
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"] }] }); }
4399
4202
  }
4400
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RectangleComponent, decorators: [{
4203
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CtxToolbarComponent, decorators: [{
4401
4204
  type: Component,
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: [{
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: [{
4406
4207
  type: Input
4407
4208
  }], rotate: [{
4408
4209
  type: Input
4409
- }], editable: [{
4410
- type: Input
4411
4210
  }], pageHeight: [{
4412
4211
  type: Input
4413
4212
  }], pageWidth: [{
4414
4213
  type: Input
4415
- }], selectEvent: [{
4214
+ }], canHighlight: [{
4215
+ type: Input
4216
+ }], canBookmark: [{
4217
+ type: Input
4218
+ }], canComment: [{
4219
+ type: Input
4220
+ }], canDelete: [{
4221
+ type: Input
4222
+ }], createHighlightEvent: [{
4416
4223
  type: Output
4417
- }], updateEvent: [{
4224
+ }], deleteHighlightEvent: [{
4418
4225
  type: Output
4419
- }], viewRect: [{
4420
- type: ViewChild,
4421
- args: ['rectElement', { static: false }]
4422
- }], annoRect: [{
4423
- type: Input
4424
- }], selected: [{
4226
+ }], addOrEditCommentEvent: [{
4227
+ type: Output
4228
+ }], createBookmarkEvent: [{
4229
+ type: Output
4230
+ }], rectangles: [{
4425
4231
  type: Input
4426
4232
  }] } });
4427
4233
 
@@ -4481,7 +4287,7 @@ class AnnotationViewComponent {
4481
4287
  this.toolbarEvents.toggleCommentsPanel(true);
4482
4288
  }
4483
4289
  /** @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 }); }
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"] }] }); }
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"] }] }); }
4485
4291
  }
4486
4292
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AnnotationViewComponent, decorators: [{
4487
4293
  type: Component,
@@ -4575,20 +4381,11 @@ class MetadataLayerComponent {
4575
4381
  this.rectangles = highlight.rectangles;
4576
4382
  if (this.rectangles) {
4577
4383
  this.toolbarEvents.highlightModeSubject.next(false);
4578
- setTimeout(() => this.ctxToolbar.focusToolbar(), 0);
4579
4384
  }
4580
4385
  }
4581
4386
  clearContextToolbar() {
4582
4387
  this.rectangles = undefined;
4583
4388
  }
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
- }
4592
4389
  createHighlight() {
4593
4390
  this.highlightService.saveAnnotation(this.rectangles, this.highlightPage);
4594
4391
  this.highlightService.resetHighlight();
@@ -4617,18 +4414,15 @@ class MetadataLayerComponent {
4617
4414
  this.toolbarEvents.drawModeSubject.next(false);
4618
4415
  }
4619
4416
  /** @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 }); }
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" }] }); }
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" }] }); }
4621
4418
  }
4622
4419
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: MetadataLayerComponent, decorators: [{
4623
4420
  type: Component,
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" }]
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" }]
4625
4422
  }], ctorParameters: () => [{ type: i1.Store }, { type: HighlightCreateService }, { type: ToolbarEventService }, { type: ViewerEventService }], propDecorators: { zoom: [{
4626
4423
  type: Input
4627
4424
  }], rotate: [{
4628
4425
  type: Input
4629
- }], ctxToolbar: [{
4630
- type: ViewChild,
4631
- args: [CtxToolbarComponent, { static: false }]
4632
4426
  }] } });
4633
4427
 
4634
4428
  class BookmarksComponent {
@@ -5181,356 +4975,114 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
5181
4975
  args: ['window:pointerup']
5182
4976
  }] } });
5183
4977
 
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;
5221
- }
5222
- ngOnDestroy() {
5223
- this.cleanup();
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;
5224
4985
  }
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();
5234
- }
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);
4986
+ ngOnInit() {
4987
+ this.$subscription = this.store.select(getPages).subscribe((pages) => {
4988
+ if (pages[1]) {
4989
+ this.allPages = pages;
5259
4990
  }
5260
- }
5261
- }
5262
- onBlur() {
5263
- if (this.showCursor && !this.isSelecting) {
5264
- this.hideCursor();
5265
- }
5266
- }
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
4991
  });
5348
- this.updateTextSelection();
5349
- this.emitSelectionUpdated();
5350
4992
  }
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);
5363
- }
5364
- }
5365
- else if (document.caretRangeFromPoint) {
5366
- range = document.caretRangeFromPoint(viewportX, viewportY);
5367
- }
5368
- if (range) {
5369
- selection.removeAllRanges();
5370
- selection.addRange(range);
4993
+ ngOnDestroy() {
4994
+ if (this.$subscription) {
4995
+ this.$subscription.unsubscribe();
5371
4996
  }
5372
4997
  }
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;
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
+ }
5391
5008
  }
5392
5009
  }
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
- }
5010
+ if (this.toolbarEvents.highlightModeSubject.getValue()) {
5011
+ const rectangles = this.getRectangles(mouseEvent, page);
5012
+ this.viewerEvents.textSelected({ page, rectangles });
5399
5013
  }
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();
5435
5014
  }
5436
- cancelTextSelection() {
5015
+ onPdfViewerClick(event) {
5016
+ this.store.dispatch(new SelectedAnnotation({
5017
+ annotationId: '',
5018
+ selected: false,
5019
+ editable: false,
5020
+ }));
5021
+ this.viewerEvents.clearCtxToolbar();
5022
+ }
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);
5437
5028
  const selection = window.getSelection();
5438
5029
  if (selection) {
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;
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;
5474
5047
  }
5475
5048
  }
5476
5049
  }
5477
- return 1;
5478
5050
  }
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
- });
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;
5495
5059
  }
5496
- reset() {
5497
- this.cleanup();
5498
- this.emitCursorPosition();
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
+ }
5499
5071
  }
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 }); }
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 }); }
5502
5074
  }
5503
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: KeyboardTextHighlightDirective, decorators: [{
5075
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: HighlightCreateDirective, decorators: [{
5504
5076
  type: Directive,
5505
5077
  args: [{
5506
- selector: '[mvKeyboardTextHighlight]'
5078
+ selector: '[mvCreateTextHighlight]'
5507
5079
  }]
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: [{
5080
+ }], ctorParameters: () => [{ type: i0.ElementRef }, { type: ToolbarEventService }, { type: ViewerEventService }, { type: HighlightCreateService }, { type: i1.Store }], propDecorators: { onMouseUp: [{
5529
5081
  type: HostListener,
5530
- args: ['keydown', ['$event']]
5531
- }], onBlur: [{
5082
+ args: ['mouseup', ['$event']]
5083
+ }], onPdfViewerClick: [{
5532
5084
  type: HostListener,
5533
- args: ['blur']
5085
+ args: ['mousedown', ['$event']]
5534
5086
  }] } });
5535
5087
 
5536
5088
  const getRedactionState = createSelector(getMVState, (state) => state.redactions);
@@ -5565,7 +5117,7 @@ class RedactionComponent {
5565
5117
  this.redactionsPerPage$ = this.store.pipe(select(getRedactionsPerPage));
5566
5118
  this.selectedRedaction$ = this.store.pipe(select(getSelected));
5567
5119
  this.$subscription = this.toolbarEvents.drawModeSubject.subscribe(drawMode => this.drawMode = drawMode);
5568
- this.$subscription.add(this.store.pipe(select(getRedactedDocumentInfo), filter$1(value => !!value))
5120
+ this.$subscription.add(this.store.pipe(select(getRedactedDocumentInfo), filter(value => !!value))
5569
5121
  .subscribe(redactedDocInfo => this.downloadDocument(redactedDocInfo)));
5570
5122
  this.$subscription.add(this.store.pipe(select(getDocumentId)).subscribe(docId => this.documentId = docId));
5571
5123
  this.$subscription.add(this.viewerEvents.textHighlight.subscribe(highlight => this.markTextRedaction(highlight)));
@@ -5692,8 +5244,6 @@ class PdfViewerComponent {
5692
5244
  this.loadingDocument = false;
5693
5245
  this.hasDifferentPageSize = false;
5694
5246
  this.enableGrabNDrag = false;
5695
- this.showSelectionStartCursor = false;
5696
- this.showSelectionEndCursor = false;
5697
5247
  this.highlightMode = toolbarEvents.highlightModeSubject.pipe(tap(() => {
5698
5248
  this.store.dispatch(new ClearFilterTags());
5699
5249
  }));
@@ -5732,7 +5282,7 @@ class PdfViewerComponent {
5732
5282
  if (changes.url && this.pdfWrapper) {
5733
5283
  await this.loadDocument();
5734
5284
  if (this.enableRedactions) {
5735
- this.toolbarEvents.redactionMode.pipe(filter$1(value => !!value))
5285
+ this.toolbarEvents.redactionMode.pipe(filter(value => !!value))
5736
5286
  .subscribe(() => this.resetRotation());
5737
5287
  }
5738
5288
  }
@@ -5843,43 +5393,12 @@ class PdfViewerComponent {
5843
5393
  getCurrentPageNumber() {
5844
5394
  return this.pdfWrapper.getPageNumber();
5845
5395
  }
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
- }
5877
5396
  /** @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 }); }
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 }); }
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 }); }
5879
5398
  }
5880
5399
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: PdfViewerComponent, decorators: [{
5881
5400
  type: Component,
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" }]
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" }]
5883
5402
  }], ctorParameters: () => [{ type: i1.Store }, { type: i1.Store }, { type: PdfJsWrapperFactory }, { type: PrintService }, { type: ToolbarEventService }, { type: ViewerEventService }, { type: IcpService }, { type: ToolbarButtonVisibilityService }, { type: IcpEventService }], propDecorators: { mediaLoadStatus: [{
5884
5403
  type: Output
5885
5404
  }], pdfViewerException: [{
@@ -5912,9 +5431,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
5912
5431
  }], pdfViewer: [{
5913
5432
  type: ViewChild,
5914
5433
  args: ['pdfViewer', { static: false }]
5915
- }], highlightCreateDirective: [{
5916
- type: ViewChild,
5917
- args: [HighlightCreateDirective, { static: false }]
5918
5434
  }], searchBarHidden: [{
5919
5435
  type: Input
5920
5436
  }] } });
@@ -6975,7 +6491,7 @@ class ConvertibleContentViewerComponent {
6975
6491
  this.documentTitle = new EventEmitter();
6976
6492
  }
6977
6493
  ngOnInit() {
6978
- this.$subscription = this.store.pipe(select(getConvertedDocument), filter$1(value => !!value))
6494
+ this.$subscription = this.store.pipe(select(getConvertedDocument), filter(value => !!value))
6979
6495
  .subscribe((docInfo) => {
6980
6496
  if (docInfo.url) {
6981
6497
  this.convertedUrl = docInfo.url;
@@ -7060,7 +6576,7 @@ class RotationPersistDirective {
7060
6576
  onMediaLoad(status) {
7061
6577
  this.rotation = 0;
7062
6578
  this.store.dispatch(new LoadRotation(this.documentId));
7063
- this.store.pipe(select(rotationLoaded), filter$1(value => !!value), take(1))
6579
+ this.store.pipe(select(rotationLoaded), filter(value => !!value), take(1))
7064
6580
  .subscribe(() => {
7065
6581
  if (this.savedRotation) {
7066
6582
  this.toolbarEvents.rotateSubject.next(this.savedRotation);
@@ -7095,6 +6611,11 @@ class ConfirmActionDialogComponent {
7095
6611
  constructor(icpEventService) {
7096
6612
  this.icpEventService = icpEventService;
7097
6613
  }
6614
+ ngAfterViewInit() {
6615
+ if (this.modalContainer) {
6616
+ this.modalContainer.nativeElement.focus();
6617
+ }
6618
+ }
7098
6619
  onCancel() {
7099
6620
  this.icpEventService.leavingSession.next(false);
7100
6621
  }
@@ -7103,12 +6624,15 @@ class ConfirmActionDialogComponent {
7103
6624
  this.icpEventService.leavingSession.next(false);
7104
6625
  }
7105
6626
  /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ConfirmActionDialogComponent, deps: [{ token: IcpEventService }], target: i0.ɵɵFactoryTarget.Component }); }
7106
- /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: ConfirmActionDialogComponent, selector: "mv-confirm-action", ngImport: i0, template: "<div id=\"modal-background\" class=\"modal\" (click)=\"onCancel()\">\n <div id=\"modal\" class=\"modal-content govuk-width-container clearfix\" (click)=\"$event.stopPropagation()\">\n <h2 class=\"govuk-heading-s\">Are you sure you want to leave the presentation?</h2>\n <div class=\"button-container\">\n <button id=\"modal-close-button\" (click)=\"onConfirm()\" class=\"govuk-button\">Confirm</button>\n <button (click)=\"onCancel()\" class=\"govuk-button govuk-button--secondary\">Cancel</button>\n </div>\n </div>\n</div>\n" }); }
6627
+ /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: ConfirmActionDialogComponent, selector: "mv-confirm-action", viewQueries: [{ propertyName: "modalContainer", first: true, predicate: ["modalContainer"], descendants: true }], ngImport: i0, template: "<div id=\"modal-background\" class=\"modal\" (click)=\"onCancel()\">\n <div id=\"modal\" \n class=\"modal-content govuk-width-container clearfix\"\n (click)=\"$event.stopPropagation()\"\n #modalContainer\n tabIndex=\"-1\"\n role=\"dialog\"\n aria-modal=\"true\"\n >\n <h2 class=\"govuk-heading-s\">Are you sure you want to leave the presentation?</h2>\n <div class=\"button-container\">\n <button id=\"modal-close-button\" (click)=\"onConfirm()\" class=\"govuk-button\">Confirm</button>\n <button (click)=\"onCancel()\" class=\"govuk-button govuk-button--secondary\">Cancel</button>\n </div>\n </div>\n</div>\n" }); }
7107
6628
  }
7108
6629
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ConfirmActionDialogComponent, decorators: [{
7109
6630
  type: Component,
7110
- args: [{ selector: 'mv-confirm-action', template: "<div id=\"modal-background\" class=\"modal\" (click)=\"onCancel()\">\n <div id=\"modal\" class=\"modal-content govuk-width-container clearfix\" (click)=\"$event.stopPropagation()\">\n <h2 class=\"govuk-heading-s\">Are you sure you want to leave the presentation?</h2>\n <div class=\"button-container\">\n <button id=\"modal-close-button\" (click)=\"onConfirm()\" class=\"govuk-button\">Confirm</button>\n <button (click)=\"onCancel()\" class=\"govuk-button govuk-button--secondary\">Cancel</button>\n </div>\n </div>\n</div>\n" }]
7111
- }], ctorParameters: () => [{ type: IcpEventService }] });
6631
+ args: [{ selector: 'mv-confirm-action', template: "<div id=\"modal-background\" class=\"modal\" (click)=\"onCancel()\">\n <div id=\"modal\" \n class=\"modal-content govuk-width-container clearfix\"\n (click)=\"$event.stopPropagation()\"\n #modalContainer\n tabIndex=\"-1\"\n role=\"dialog\"\n aria-modal=\"true\"\n >\n <h2 class=\"govuk-heading-s\">Are you sure you want to leave the presentation?</h2>\n <div class=\"button-container\">\n <button id=\"modal-close-button\" (click)=\"onConfirm()\" class=\"govuk-button\">Confirm</button>\n <button (click)=\"onCancel()\" class=\"govuk-button govuk-button--secondary\">Cancel</button>\n </div>\n </div>\n</div>\n" }]
6632
+ }], ctorParameters: () => [{ type: IcpEventService }], propDecorators: { modalContainer: [{
6633
+ type: ViewChild,
6634
+ args: ['modalContainer']
6635
+ }] } });
7112
6636
 
7113
6637
  var CoreContentTypes;
7114
6638
  (function (CoreContentTypes) {
@@ -7907,7 +7431,6 @@ class MediaViewerModule {
7907
7431
  GrabNDragDirective,
7908
7432
  RotationPersistDirective,
7909
7433
  HighlightCreateDirective,
7910
- KeyboardTextHighlightDirective,
7911
7434
  ConfirmActionDialogComponent,
7912
7435
  RedactionComponent,
7913
7436
  BookmarkIconsComponent,
@@ -7974,7 +7497,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
7974
7497
  GrabNDragDirective,
7975
7498
  RotationPersistDirective,
7976
7499
  HighlightCreateDirective,
7977
- KeyboardTextHighlightDirective,
7978
7500
  ConfirmActionDialogComponent,
7979
7501
  RedactionComponent,
7980
7502
  BookmarkIconsComponent,