Skip to content

Commit

Permalink
Refactor implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
jrlarano committed Mar 20, 2024
1 parent cdb5f60 commit 311588e
Show file tree
Hide file tree
Showing 7 changed files with 137 additions and 141 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ const defaultTemplate = `\
<div class="verso__scroller">
<div class="sgn-pp__pages"></div>
</div>
<div class="sgn-page_decorations"></div>
</div>
{{#disableHeader}}
Expand Down Expand Up @@ -47,6 +46,7 @@ const defaultTemplate = `\
>
&raquo;
</button>
<div class="sgn-page_decorations"></div>
</div>\
`;

Expand Down
3 changes: 3 additions & 0 deletions lib/kits/core-ui/page-decorations.styl
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@
.sgn-pagedecoration-hotspot
position absolute
z-index 99
box-shadow unset
border 0
opacity 1

.sgn-pagedecoration-hotspot-link
text-decoration none
Expand Down
118 changes: 5 additions & 113 deletions lib/kits/core-ui/page-decorations.ts
Original file line number Diff line number Diff line change
@@ -1,39 +1,15 @@
import Mustache from 'mustache';
import {V2PageDecoration} from '../core';
import './page-decorations.styl';
import PageSpread from '../../verso-browser/page_spread';
import PagedPublicationPageSpread from '../paged-publication/page-spread';

const defaultTemplate = `\
{{#hotspot}}
{{#link_embed}}
<iframe src="{{link}}" height="100%" width="100%" style="border:0;"></iframe>
{{/link_embed}}
{{^link_embed}}
<a href="{{link}}" class="sgn-pagedecoration-hotspot-link" rel="noreferrer noopener" target="_blank">
<div class="sgn-pagedecoration-hotspot-link-content" style="width:100%;height:100%;">
<div class="sgn-pagedecoration-hotspot-link-icon">
<svg class="sgn-pagedecoration-link-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<path d="M352 0c-12.9 0-24.6 7.8-29.6 19.8s-2.2 25.7 6.9 34.9L370.7 96 201.4 265.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L416 141.3l41.4 41.4c9.2 9.2 22.9 11.9 34.9 6.9s19.8-16.6 19.8-29.6V32c0-17.7-14.3-32-32-32H352zM80 32C35.8 32 0 67.8 0 112V432c0 44.2 35.8 80 80 80H400c44.2 0 80-35.8 80-80V320c0-17.7-14.3-32-32-32s-32 14.3-32 32V432c0 8.8-7.2 16-16 16H80c-8.8 0-16-7.2-16-16V112c0-8.8 7.2-16 16-16H192c17.7 0 32-14.3 32-32s-14.3-32-32-32H80z"/>
</svg>
</div>
<div class="sgn-pagedecoration-hotspot-link-label">
<span>{{hostname}}</span>
</div>
</div>
</a>
{{/link_embed}}
{{/hotspot}}
{{^hotspot}}
{{#pageDecoration.website_link}}
<div class="sgn-pagedecoration__content">
<a href="{{pageDecoration.website_link}}" rel="noreferrer noopener" target="_blank">
<p class="sgn-pagedecoration-item__domain">{{pageDecoration.hostname}}</p>
</a>
</div>
{{/pageDecoration.website_link}}
{{/hotspot}}
\
{{/pageDecoration.website_link}}\
`;

const PageDecorations = () => {
Expand All @@ -46,14 +22,10 @@ const PageDecorations = () => {

const render = ({
pageDecorations,
aspectRatio,
versoPageSpreads,
pageSpreads
aspectRatio
}: {
pageDecorations: V2PageDecoration[];
aspectRatio: {};
versoPageSpreads?: PageSpread[];
pageSpreads?: PagedPublicationPageSpread[];
}) => {
if (pageDecorationsContainer?.innerHTML) {
pageDecorationsContainer.innerHTML = '';
Expand All @@ -70,92 +42,14 @@ const PageDecorations = () => {
);

filteredPageDecorations?.forEach((pageDecoration) => {
if (pageDecoration && pageDecoration.hotspots?.length) {
pageDecoration.hotspots?.forEach((hotspot, index) => {
const el = document.createElement('div');
el.classList.add('sgn-pagedecoration-hotspot');
el.classList.add(`sgn-pagedecoration-hotspot-${index}`);

let x1 = hotspot.x1;
let x2 = hotspot.x2;

const versoPageSpread = versoPageSpreads?.find(
(pageSpread) =>
pageSpread.pageIds.includes(
`page${pageDecoration.page_number}`
)
);
const contentRect = versoPageSpread?.getContentRect();

const pageSpreadEl = pageSpreads
?.find((spread) =>
spread
.getPages()
.some(
(page) =>
page.id ===
`page${pageDecoration.page_number}`
)
)
?.getEl();
const boundingRect = pageSpreadEl?.getBoundingClientRect();

if (versoPageSpread?.pageIds?.length == 2 && contentRect) {
contentRect.width = contentRect?.width / 2;
if (
versoPageSpread?.pageIds?.indexOf(
`page${pageDecoration.page_number}`
)
) {
x1 += 1;
x2 += 1;
}
}

let top = Math.round(
((contentRect?.height || 0) / 100) * (hotspot.y1! * 100)
);
let left = Math.round(
((contentRect?.width || 0) / 100) * (x1 * 100)
);
const width = Math.round(
((contentRect?.width || 0) / 100) * ((x2 - x1) * 100)
);
const height = Math.round(
((contentRect?.height || 0) / 100) *
((hotspot.y2 - hotspot.y1) * 100)
);

top += Math.round(contentRect?.top || 0);
left += Math.round(contentRect?.left || 0);
left -= boundingRect?.left || 0;

el.style.top = `${top}px`;
el.style.left = `${left}px`;
el.style.width = `${width}px`;
el.style.height = `${height}px`;
el.style.transform = `rotate(${hotspot.rotate}deg)`;

el.innerHTML = Mustache.render(
pageDecorationTemplate?.innerHTML || defaultTemplate,
{
hotspot: {
...hotspot,
hostname: getHostname(hotspot.link)
}
}
);

pageDecorationsEls?.appendChild(el);
});
} else if (
if (
pageDecoration &&
pageDecoration.website_link &&
getHostname(pageDecoration.website_link)
) {
const el = document.createElement('div');
const position =
filteredPageDecorations?.length <= 1
pageDecorations?.length <= 1
? 'center'
: pageDecoration.page_number % 2 == 0
? 'left'
Expand All @@ -173,9 +67,7 @@ const PageDecorations = () => {
{
pageDecoration: {
...pageDecoration,
hostname:
pageDecoration.website_link_title ||
getHostname(pageDecoration.website_link)
hostname: getHostname(pageDecoration.website_link)
}
}
);
Expand Down
12 changes: 6 additions & 6 deletions lib/kits/core-ui/paged-publication.ts
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,11 @@ const PagedPublication = (

header.show(sgnData);

if (!scriptEls.disablePageDecorations) {
sgnPageDecorations = await bootstrapper.fetchPageDecorations();
bootstrapper.applyPageDecorations(sgnViewer, sgnPageDecorations);
}

sgnViewer.bind('hotspotClicked', clickHotspot);

sgnViewer.start();
Expand All @@ -204,12 +209,7 @@ const PagedPublication = (
}

const hotspots = await bootstrapper.fetchHotspots();
bootstrapper.applyHotspots(sgnViewer, hotspots);

if (!scriptEls.disablePageDecorations) {
sgnPageDecorations = await bootstrapper.fetchPageDecorations();
bootstrapper.applyPageDecorations(sgnViewer, sgnPageDecorations);
}
bootstrapper.applyHotspots(sgnViewer, hotspots, sgnPageDecorations);

displayUrlParams();
addFirstLastControlListener();
Expand Down
53 changes: 52 additions & 1 deletion lib/kits/paged-publication/bootstrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,58 @@ export default class Bootstrapper {
});
}

applyHotspots(viewer: Viewer, hotspots: V2Hotspot[]) {
transformPageDecrationHotspots(pageDecorations: V2PageDecoration[]) {
const filteredPageDecorations = pageDecorations?.filter(
(pageDecoration) => pageDecoration.hotspots?.length
);
const pageDecorationHotspots: {
id: string;
type: string;
link_embed: boolean;
link: string;
rotate: number;
locations: any;
}[] = [];

filteredPageDecorations.forEach((pageDecoration) => {
pageDecoration.hotspots?.forEach((hotspot, index) => {
pageDecorationHotspots.push({
id: `page${pageDecoration.page_number}-hotspot-${index}`,
type: 'pagedecoration',
link_embed: hotspot.link_embed,
link: hotspot.link,
rotate: hotspot.rotate,
locations: {
[pageDecoration.page_number]: [
[hotspot.x1, hotspot.y1],
[hotspot.x1, hotspot.y2],
[hotspot.x2, hotspot.y2],
[hotspot.x2, hotspot.y1]
]
}
});
});
});

return pageDecorationHotspots;
}

applyHotspots(
viewer: Viewer,
hotspots: V2Hotspot[],
pageDecorations?: V2PageDecoration[]
) {
let pageDecorationHotspots;

if (pageDecorations?.length) {
pageDecorationHotspots =
this.transformPageDecrationHotspots(pageDecorations);

if (pageDecorationHotspots.length) {
hotspots = hotspots.concat(pageDecorationHotspots);
}
}

viewer.applyHotspots(
hotspots.reduce((obj, hotspot) => {
obj[hotspot.id] = hotspot;
Expand Down
46 changes: 45 additions & 1 deletion lib/kits/paged-publication/hotspots.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,23 @@ function getPosition(pages: Page[], ratio: number, hotspot: V2Hotspot) {
};
}

function getHostname(link: string) {
try {
const url = new URL(link);

const hostnameArr = url.hostname.split('.');
const [subDomain, secondDomain, topDomain] = hostnameArr;

return subDomain === 'www'
? [secondDomain, topDomain].join('.')
: url.hostname;
} catch (e) {
console.log('Error:', e?.message);

return null;
}
}

function renderHotspot(hotspot, position, contentRect, boundingRect) {
const el = document.createElement('div');
let top = Math.round((contentRect.height / 100) * position.top);
Expand All @@ -65,6 +82,33 @@ function renderHotspot(hotspot, position, contentRect, boundingRect) {

el.innerHTML = '';

if (hotspot.type === 'pagedecoration') {
el.className += ' sgn-pagedecoration-hotspot';

if (hotspot.link_embed) {
el.innerHTML = `<iframe src="${hotspot.link}" height="100%" width="100%" style="border:0;"></iframe>`;
} else {
el.innerHTML = `
<a href="${
hotspot.link
}" class="sgn-pagedecoration-hotspot-link" rel="noreferrer noopener" target="_blank">
<div class="sgn-pagedecoration-hotspot-link-content" style="width:100%;height:100%;">
<div class="sgn-pagedecoration-hotspot-link-icon">
<svg class="sgn-pagedecoration-link-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<path d="M352 0c-12.9 0-24.6 7.8-29.6 19.8s-2.2 25.7 6.9 34.9L370.7 96 201.4 265.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L416 141.3l41.4 41.4c9.2 9.2 22.9 11.9 34.9 6.9s19.8-16.6 19.8-29.6V32c0-17.7-14.3-32-32-32H352zM80 32C35.8 32 0 67.8 0 112V432c0 44.2 35.8 80 80 80H400c44.2 0 80-35.8 80-80V320c0-17.7-14.3-32-32-32s-32 14.3-32 32V432c0 8.8-7.2 16-16 16H80c-8.8 0-16-7.2-16-16V112c0-8.8 7.2-16 16-16H192c17.7 0 32-14.3 32-32s-14.3-32-32-32H80z"/>
</svg>
</div>
<div class="sgn-pagedecoration-hotspot-link-label">
<span>${getHostname(hotspot.link)}</span>
</div>
</div>
</a>
`;
}

el.style.transform = `rotate(${hotspot.rotate}deg)`;
}

el.style.top = `${top}px`;
el.style.left = `${left}px`;
el.style.width = `${width}px`;
Expand Down Expand Up @@ -152,7 +196,7 @@ class PagedPublicationHotspots extends MicroEvent {

setCache(
pageSpreadId: string,
data: typeof this.cache[keyof typeof this.cache]
data: (typeof this.cache)[keyof typeof this.cache]
) {
this.cache[pageSpreadId] = data;

Expand Down
Loading

0 comments on commit 311588e

Please sign in to comment.