Skip to content

Commit a66d938

Browse files
[IIIF-148] fix location plugin, configure message listeners
1 parent 616c2f0 commit a66d938

6 files changed

Lines changed: 107 additions & 37 deletions

File tree

package.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,8 @@
8484
"@angular/platform-browser-dynamic": "^15.2.10",
8585
"@angular/platform-server": "^15.2.10",
8686
"@angular/router": "^15.2.10",
87-
"@babel/runtime": "7.26.0",
8887
"@asymmetrik/ngx-leaflet": "^15.0.0",
88+
"@babel/runtime": "7.26.0",
8989
"@datadog/browser-rum": "^5.7.0",
9090
"@kolkov/ngx-gallery": "^2.0.1",
9191
"@ng-bootstrap/ng-bootstrap": "^11.0.0",
@@ -146,14 +146,15 @@
146146
"ng2-pdfjs-viewer": "^15.0.0",
147147
"ngx-infinite-scroll": "^15.0.0",
148148
"ngx-pagination": "6.0.3",
149+
"ngx-quill": "21.0.2",
149150
"ngx-skeleton-loader": "^7.0.0",
150151
"nouislider": "^15.8.1",
151152
"pem": "1.14.8",
152-
"ngx-quill": "21.0.2",
153153
"prop-types": "^15.8.1",
154154
"quill": "1.3.7",
155155
"quill-emoji": "^0.2.0",
156156
"react-copy-to-clipboard": "^5.1.0",
157+
"redux-saga": "^1.3.0",
157158
"reflect-metadata": "^0.2.2",
158159
"rxjs": "^7.8.0",
159160
"sanitize-html": "^2.14.0",
@@ -221,8 +222,8 @@
221222
"karma-jasmine": "~4.0.0",
222223
"karma-jasmine-html-reporter": "^1.5.0",
223224
"karma-mocha-reporter": "2.2.5",
224-
"ngx-export-as": "~1.15.1",
225225
"ng-mocks": "^14.13.2",
226+
"ngx-export-as": "~1.15.1",
226227
"ngx-mask": "13.1.7",
227228
"nodemon": "^2.0.22",
228229
"postcss": "^8.5",

src/app/item-page/mirador-viewer/mirador-viewer.component.spec.ts

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { of as observableOf } from 'rxjs';
1313
import { MiradorViewerService } from './mirador-viewer.service';
1414
import { HostWindowService } from '../../shared/host-window.service';
1515
import { BundleDataService } from '../../core/data/bundle-data.service';
16+
import { NativeWindowRef, NativeWindowService } from '../../core/services/window.service';
1617

1718

1819
function getItem(metadata: MetadataMap) {
@@ -48,7 +49,9 @@ describe('MiradorViewerComponent with search', () => {
4849
providers: [
4950
{ provide: BitstreamDataService, useValue: {} },
5051
{ provide: BundleDataService, useValue: {} },
51-
{ provide: HostWindowService, useValue: mockHostWindowService }
52+
{ provide: HostWindowService, useValue: mockHostWindowService },
53+
{ provide: NativeWindowService, useValue: new NativeWindowRef() },
54+
{ provide: Location, useValue: {} },
5255
],
5356
schemas: [NO_ERRORS_SCHEMA]
5457
}).overrideComponent(MiradorViewerComponent, {
@@ -111,7 +114,9 @@ describe('MiradorViewerComponent with multiple images', () => {
111114
providers: [
112115
{ provide: BitstreamDataService, useValue: {} },
113116
{ provide: BundleDataService, useValue: {} },
114-
{ provide: HostWindowService, useValue: mockHostWindowService }
117+
{ provide: HostWindowService, useValue: mockHostWindowService },
118+
{ provide: NativeWindowService, useValue: new NativeWindowRef() },
119+
{ provide: Location, useValue: {} },
115120
],
116121
schemas: [NO_ERRORS_SCHEMA]
117122
}).overrideComponent(MiradorViewerComponent, {
@@ -171,7 +176,9 @@ describe('MiradorViewerComponent with a single image', () => {
171176
providers: [
172177
{ provide: BitstreamDataService, useValue: {} },
173178
{ provide: BundleDataService, useValue: {} },
174-
{ provide: HostWindowService, useValue: mockHostWindowService }
179+
{ provide: HostWindowService, useValue: mockHostWindowService },
180+
{ provide: NativeWindowService, useValue: new NativeWindowRef() },
181+
{ provide: Location, useValue: {} },
175182
],
176183
schemas: [NO_ERRORS_SCHEMA]
177184
}).overrideComponent(MiradorViewerComponent, {
@@ -222,15 +229,17 @@ describe('MiradorViewerComponent in development mode', () => {
222229
})],
223230
declarations: [MiradorViewerComponent],
224231
providers: [
225-
{ provide: BitstreamDataService, useValue: {} }
232+
{ provide: BitstreamDataService, useValue: {} },
226233
],
227234
schemas: [NO_ERRORS_SCHEMA]
228235
}).overrideComponent(MiradorViewerComponent, {
229236
set: {
230237
providers: [
231238
{ provide: MiradorViewerService, useValue: viewerService },
232239
{ provide: BundleDataService, useValue: {} },
233-
{ provide: HostWindowService, useValue: mockHostWindowService }
240+
{ provide: HostWindowService, useValue: mockHostWindowService },
241+
{ provide: NativeWindowService, useValue: new NativeWindowRef() },
242+
{ provide: Location, useValue: {} },
234243
]
235244
}
236245
}).compileComponents();

src/app/item-page/mirador-viewer/mirador-viewer.component.ts

Lines changed: 48 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,23 @@
1-
import { ChangeDetectionStrategy, Component, Inject, Input, OnInit, PLATFORM_ID } from '@angular/core';
1+
import { ChangeDetectionStrategy, Component, Inject, Input, OnInit, OnDestroy, PLATFORM_ID } from '@angular/core';
22
import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser';
33
import { Item } from '../../core/shared/item.model';
44
import { environment } from '../../../environments/environment';
55
import { BitstreamDataService } from '../../core/data/bitstream-data.service';
66
import { Observable, of } from 'rxjs';
77
import { map, take } from 'rxjs/operators';
8-
import { isPlatformBrowser } from '@angular/common';
8+
import { isPlatformBrowser, Location } from '@angular/common';
99
import { MiradorViewerService } from './mirador-viewer.service';
1010
import { HostWindowService, WidthCategory } from '../../shared/host-window.service';
1111
import { BundleDataService } from '../../core/data/bundle-data.service';
12+
import { NativeWindowRef, NativeWindowService } from '../../core/services/window.service';
13+
14+
const IFRAME_UPDATE_URL_MESSAGE = 'update-url';
15+
16+
interface IFrameMessageData {
17+
canvasId: string;
18+
type: string;
19+
param: string;
20+
}
1221

1322
@Component({
1423
selector: 'ds-mirador-viewer',
@@ -17,7 +26,7 @@ import { BundleDataService } from '../../core/data/bundle-data.service';
1726
changeDetection: ChangeDetectionStrategy.OnPush,
1827
providers: [ MiradorViewerService ]
1928
})
20-
export class MiradorViewerComponent implements OnInit {
29+
export class MiradorViewerComponent implements OnInit, OnDestroy {
2130

2231
@Input() object: Item;
2332

@@ -63,12 +72,17 @@ export class MiradorViewerComponent implements OnInit {
6372

6473
viewerMessage = 'Sorry, the Mirador viewer is not currently available in development mode.';
6574

66-
constructor(private sanitizer: DomSanitizer,
67-
private viewerService: MiradorViewerService,
68-
private bitstreamDataService: BitstreamDataService,
69-
private bundleDataService: BundleDataService,
70-
private hostWindowService: HostWindowService,
71-
@Inject(PLATFORM_ID) private platformId: any) {
75+
constructor(
76+
private sanitizer: DomSanitizer,
77+
private viewerService: MiradorViewerService,
78+
private bitstreamDataService: BitstreamDataService,
79+
private bundleDataService: BundleDataService,
80+
private hostWindowService: HostWindowService,
81+
private location: Location,
82+
@Inject(PLATFORM_ID) private platformId: any,
83+
@Inject(NativeWindowService) protected _window: NativeWindowRef,
84+
) {
85+
7286
}
7387

7488
/**
@@ -116,6 +130,7 @@ export class MiradorViewerComponent implements OnInit {
116130
* Initializes the iframe url observable.
117131
*/
118132
if (isPlatformBrowser(this.platformId)) {
133+
this._window.nativeWindow.addEventListener('message', this.iframeMessageListener);
119134

120135
// Viewer is not currently available in dev mode so hide it in that case.
121136
this.isViewerAvailable = this.viewerService.showEmbeddedViewer();
@@ -158,4 +173,28 @@ export class MiradorViewerComponent implements OnInit {
158173
}
159174
}
160175
}
176+
177+
ngOnDestroy(): void {
178+
this._window.nativeWindow.removeEventListener('message', this.iframeMessageListener);
179+
}
180+
181+
182+
iframeMessageListener = (event: MessageEvent) => {
183+
const data: IFrameMessageData = event.data;
184+
185+
if (data.type === IFRAME_UPDATE_URL_MESSAGE) {
186+
const currentPath = this.location.path();
187+
const canvasId = data.canvasId;
188+
const param = data.param;
189+
// Use URL API for easier query param manipulation
190+
const url = new URL(window.location.origin + currentPath);
191+
console.log(url);
192+
// Set or update the query param
193+
url.searchParams.set(param, canvasId);
194+
const newPathWithQuery = url.pathname + url.search;
195+
// Replace the current state (no reload, no new history entry)
196+
console.log('newPathWithQuery', newPathWithQuery);
197+
this.location.replaceState(newPathWithQuery);
198+
}
199+
};
161200
}

src/mirador-viewer/config.default.js

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import miradorShareDialogPlugin from 'mirador-share-plugin/es/MiradorShareDialog
1616
import miradorSharePlugin from 'mirador-share-plugin/es/miradorSharePlugin';
1717
import miradorDownloadPlugin from 'mirador-dl-plugin/es/miradorDownloadPlugin';
1818
import miradorDownloadDialog from 'mirador-dl-plugin/es/MiradorDownloadDialog';
19-
import myPlugin from './locationPlugin';
19+
import locationPlugin from './locationPlugin';
2020

2121
const MANIFEST_URL_PART = /\/manifest$/;
2222

@@ -186,7 +186,7 @@ let miradorPlugins = [
186186
miradorShareDialogPlugin,
187187
miradorSharePlugin,
188188
miradorDownloadDialog,
189-
myPlugin
189+
locationPlugin
190190
];
191191

192192
(() => {
@@ -197,14 +197,3 @@ let miradorPlugins = [
197197
})();
198198

199199
Mirador.viewer(miradorConfiguration, miradorPlugins);
200-
/*miradorInstance?.store?.subscribe((store) => {
201-
console.log(miradorInstance?.store, store);
202-
const state = store?.getState();
203-
const lastAction = state?.lastAction;
204-
console.log(state, lastAction);
205-
206-
if (lastAction && lastAction.type === 'SELECT_CANVAS') {
207-
const canvasId = lastAction.canvasId;
208-
console.log('Canvas cliccato:', canvasId);
209-
}
210-
});*/
Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,36 @@
1-
import takeEvery from 'redux-saga/effects';
1+
import { takeEvery } from 'redux-saga/effects';
22
import ActionTypes from 'mirador/dist/es/src/state/actions/action-types';
33

4+
export
5+
46
/** This will be called every time the SET_CANVAS action is dispatched */
57
const onCanvasChange = function* (action) {
6-
console.log(action);
8+
console.log('SET_CANVAS action: ', action);
9+
if(action.canvasId) {
10+
// IDs are in the format of "https://dspaceglam7dev.4science.cloud/server/iiif/392363fe-015f-41e6-8cdd-b5c754605787/canvas/03c322b7-0182-44fa-8dc3-5d2efcece237"
11+
const id = action.canvasId.split('/').pop();
12+
const message = {
13+
type: 'update-url',
14+
param: 'canvasId',
15+
canvasId: id
16+
};
17+
console.log('POSTING MESSAGE: ', message);
18+
if (id && id !== 'undefined') {
19+
window.parent.postMessage(message, '*');
20+
}
21+
}
722
}
823

924
const pluginSaga = function* () {
1025
/* `takeEvery` calls the associated function every time the action is dispatched */
1126
yield takeEvery([
1227
ActionTypes.SET_CANVAS,
13-
ActionTypes.RECEIVE_SEARCH,
14-
ActionTypes.REMOVE_SEARCH,
15-
ActionTypes.SET_WINDOW_VIEW_TYPE,
1628
], onCanvasChange);
1729
}
1830

19-
const myPlugin = {
31+
const locationPlugin = {
2032
component: () => null,
2133
saga: pluginSaga,
2234
}
2335

24-
export default myPlugin;
36+
export default locationPlugin;

yarn.lock

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2469,6 +2469,19 @@
24692469
redux "^4.0.4"
24702470
typescript-tuple "^2.2.1"
24712471

2472+
"@redux-saga/core@^1.3.0":
2473+
version "1.3.0"
2474+
resolved "https://registry.yarnpkg.com/@redux-saga/core/-/core-1.3.0.tgz#2ce08b73d407fc6ea9e7f7d83d2e97d981a3a8b8"
2475+
integrity sha512-L+i+qIGuyWn7CIg7k1MteHGfttKPmxwZR5E7OsGikCL2LzYA0RERlaUY00Y3P3ZV2EYgrsYlBrGs6cJP5OKKqA==
2476+
dependencies:
2477+
"@babel/runtime" "^7.6.3"
2478+
"@redux-saga/deferred" "^1.2.1"
2479+
"@redux-saga/delay-p" "^1.2.1"
2480+
"@redux-saga/is" "^1.1.3"
2481+
"@redux-saga/symbols" "^1.1.3"
2482+
"@redux-saga/types" "^1.2.1"
2483+
typescript-tuple "^2.2.1"
2484+
24722485
"@redux-saga/deferred@^1.2.1":
24732486
version "1.2.1"
24742487
resolved "https://registry.yarnpkg.com/@redux-saga/deferred/-/deferred-1.2.1.tgz#aca373a08ccafd6f3481037f2f7ee97f2c87c3ec"
@@ -11778,6 +11791,13 @@ redux-saga@^1.1.3:
1177811791
dependencies:
1177911792
"@redux-saga/core" "^1.2.3"
1178011793

11794+
redux-saga@^1.3.0:
11795+
version "1.3.0"
11796+
resolved "https://registry.yarnpkg.com/redux-saga/-/redux-saga-1.3.0.tgz#a59ada7c28010189355356b99738c9fcb7ade30e"
11797+
integrity sha512-J9RvCeAZXSTAibFY0kGw6Iy4EdyDNW7k6Q+liwX+bsck7QVsU78zz8vpBRweEfANxnnlG/xGGeOvf6r8UXzNJQ==
11798+
dependencies:
11799+
"@redux-saga/core" "^1.3.0"
11800+
1178111801
redux-thunk@^2.3.0:
1178211802
version "2.4.2"
1178311803
resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.4.2.tgz#b9d05d11994b99f7a91ea223e8b04cf0afa5ef3b"

0 commit comments

Comments
 (0)