Skip to content

Commit

Permalink
fix: fixed pdf container
Browse files Browse the repository at this point in the history
  • Loading branch information
mbret committed Jan 25, 2025
1 parent 8033ee5 commit 18915dd
Show file tree
Hide file tree
Showing 9 changed files with 110 additions and 119 deletions.
17 changes: 6 additions & 11 deletions packages/core/src/enhancers/html/renderer/HtmlRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,9 @@ export class HtmlRenderer extends DocumentRenderer {
onCreateDocument() {
const frameElement = createFrameElement()

this.layers = [
{
element: frameElement,
},
]
this.documentContainer = frameElement

return EMPTY
return of(frameElement)
}

onLoadDocument() {
Expand All @@ -46,8 +42,8 @@ export class HtmlRenderer extends DocumentRenderer {
settings: this.settings,
}),
waitForSwitch(this.context.bridgeEvent.viewportFree$),
tap((frameElement) => {
this.containerElement.appendChild(frameElement)
tap(() => {
this.attach()
}),
waitForFrameLoad,
loadAssets({
Expand All @@ -62,8 +58,7 @@ export class HtmlRenderer extends DocumentRenderer {
onUnload() {
unloadMedias(this.getFrameElement())

this.layers.forEach((layer) => layer.element.remove())
this.layers = []
this.detach()

return EMPTY
}
Expand Down Expand Up @@ -164,7 +159,7 @@ export class HtmlRenderer extends DocumentRenderer {
}

private getFrameElement() {
const frame = this.layers[0]?.element
const frame = this.documentContainer

if (!(frame instanceof HTMLIFrameElement)) return

Expand Down
33 changes: 18 additions & 15 deletions packages/core/src/enhancers/layoutEnhancer/layoutEnhancer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,36 +157,39 @@ export const layoutEnhancer =

fixReflowable(reader)

reader.hookManager.register(`item.onDocumentCreated`, ({ layers }) => {
layers.forEach(({ element }) => {
reader.hookManager.register(
`item.onDocumentCreated`,
({ documentContainer }) => {
/**
* Hide document until it's ready
*/
element.style.opacity = `0`
documentContainer.style.opacity = `0`
if (settingsManager.values.layoutLayerTransition) {
element.style.transition = `opacity 300ms`
documentContainer.style.transition = `opacity 300ms`
}
})
})
},
)

reader.hookManager.register(`item.onBeforeLayout`, ({ item }) => {
const spineItem = reader.spineItemsManager.get(item.id)

spineItem?.renderer.layers.forEach(({ element }) => {
// @todo dont remember why i did this but there should be a reason. If i get time to explain
if (reader.settings.values.computedPageTurnMode !== `scrollable`) {
// @todo see what's the impact
element.setAttribute(`tab-index`, `0`)
}
})
const element = spineItem?.renderer.documentContainer

// @todo dont remember why i did this but there should be a reason. If i get time to explain
if (reader.settings.values.computedPageTurnMode !== `scrollable`) {
// @todo see what's the impact
element?.setAttribute(`tab-index`, `0`)
}
})

const revealItemOnReady$ = reader.spineItemsObserver.itemIsReady$.pipe(
filter(({ isReady }) => isReady),
tap(({ item }) => {
item.renderer.layers.forEach(({ element }) => {
const element = item.renderer.documentContainer

if (element) {
element.style.opacity = `1`
})
}
}),
)

Expand Down
21 changes: 9 additions & 12 deletions packages/core/src/enhancers/media/ImageRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,19 @@ import { DocumentRenderer } from "../../spineItem/renderer/DocumentRenderer"

export class ImageRenderer extends DocumentRenderer {
private getImageElement() {
const element = this.layers[0]?.element
const element = this.documentContainer

if (!(element instanceof HTMLImageElement)) return undefined

return element
}

onCreateDocument() {
const imgElement = this.containerElement.ownerDocument.createElement(`img`)

return from(this.resourcesHandler.getResource()).pipe(
switchMap((responseOrUrl) => {
const imgElement =
this.containerElement.ownerDocument.createElement(`img`)

this.layers = [{ element: imgElement }]
this.documentContainer = imgElement

imgElement.style.objectFit = `contain`
imgElement.style.userSelect = `none`
Expand All @@ -34,12 +33,14 @@ export class ImageRenderer extends DocumentRenderer {

throw new Error(`Invalid resource`)
}),
tap((src) => {
map((src) => {
const element = this.getImageElement()

if (element) {
element.src = src
}

return imgElement
}),
)
}
Expand All @@ -49,7 +50,7 @@ export class ImageRenderer extends DocumentRenderer {

if (!imageElement) throw new Error(`invalid element`)

this.containerElement.appendChild(imageElement)
this.attach()

return fromEvent(imageElement, `load`)
}
Expand All @@ -61,11 +62,7 @@ export class ImageRenderer extends DocumentRenderer {
URL.revokeObjectURL(imageElement.src)
}

this.layers.forEach(({ element }) => {
element.remove()
})

this.layers = []
this.detach()

return EMPTY
}
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/hooks/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export type CoreHook =
name: `item.onDocumentCreated`
runFn: (params: {
itemId: string
layers: { element: HTMLElement }[]
documentContainer: HTMLElement
}) => Observable<void> | void
}
| {
Expand All @@ -36,7 +36,7 @@ export type CoreHook =
destroy$: Observable<void>
destroy: (fn: UserDestroyFn) => void
itemId: string
layers: { element: HTMLElement }[]
documentContainer: HTMLElement
}) => Observable<void> | void
}
| {
Expand Down
17 changes: 9 additions & 8 deletions packages/core/src/spine/layout/layoutItem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export const layoutItem = ({
}): Observable<{ horizontalOffset: number; verticalOffset: number }> => {
let minimumWidth = context.getPageSize().width
let blankPagePosition: `none` | `before` | `after` = `none`
const itemStartOnNewScreen =
const isScreenStartItem =
horizontalOffset % context.state.visibleAreaRect.width === 0
const isLastItem = index === spineItemsManager.items.length - 1

Expand Down Expand Up @@ -64,20 +64,20 @@ export const layoutItem = ({
!isGloballyPrePaginated &&
item.renditionLayout === `reflowable` &&
isLastItem &&
itemStartOnNewScreen
isScreenStartItem
) {
minimumWidth = context.getPageSize().width * 2
}

const lastItemStartOnNewScreenInAPrepaginatedBook =
itemStartOnNewScreen && isLastItem && isGloballyPrePaginated
isScreenStartItem && isLastItem && isGloballyPrePaginated

if (item.item.pageSpreadRight && itemStartOnNewScreen && !context.isRTL()) {
if (item.item.pageSpreadRight && isScreenStartItem && !context.isRTL()) {
blankPagePosition = `before`
minimumWidth = context.getPageSize().width * 2
} else if (
item.item.pageSpreadLeft &&
itemStartOnNewScreen &&
isScreenStartItem &&
context.isRTL()
) {
blankPagePosition = `before`
Expand All @@ -88,6 +88,7 @@ export const layoutItem = ({
} else {
blankPagePosition = `after`
}

minimumWidth = context.getPageSize().width * 2
}
}
Expand All @@ -99,7 +100,7 @@ export const layoutItem = ({
minimumWidth,
blankPagePosition,
spreadPosition: context.state.isUsingSpreadMode
? itemStartOnNewScreen
? isScreenStartItem
? context.isRTL()
? `right`
: `left`
Expand All @@ -112,10 +113,10 @@ export const layoutItem = ({
return itemLayout$.pipe(
map(({ width, height }) => {
if (settings.values.computedPageTurnDirection === `vertical`) {
const currentValidEdgeYForVerticalPositioning = itemStartOnNewScreen
const currentValidEdgeYForVerticalPositioning = isScreenStartItem
? verticalOffset
: verticalOffset - context.state.visibleAreaRect.height
const currentValidEdgeXForVerticalPositioning = itemStartOnNewScreen
const currentValidEdgeXForVerticalPositioning = isScreenStartItem
? 0
: horizontalOffset

Expand Down
59 changes: 34 additions & 25 deletions packages/core/src/spineItem/renderer/DocumentRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
first,
map,
merge,
mergeMap,
Observable,
of,
share,
Expand Down Expand Up @@ -83,7 +84,7 @@ export abstract class DocumentRenderer extends DestroyableClass {
share(),
)

public layers: Layer[] = []
public documentContainer: HTMLElement | undefined

constructor(params: {
context: Context
Expand Down Expand Up @@ -123,39 +124,36 @@ export abstract class DocumentRenderer extends DestroyableClass {
switchMap(() => {
this.stateSubject.next(`loading`)

const createDocument$ = this.onCreateDocument().pipe(
endWith(null),
first(),
)
const createDocument$ = this.onCreateDocument().pipe(first())

return createDocument$.pipe(
tap(() => {
mergeMap((documentContainer) => {
this.hookManager.execute(`item.onDocumentCreated`, this.item.id, {
itemId: this.item.id,
layers: this.layers,
documentContainer,
})
}),
switchMap(() => {

const loadDocument$ = this.onLoadDocument().pipe(
endWith(null),
first(),
)

return loadDocument$
}),
waitForSwitch(this.context.bridgeEvent.viewportFree$),
switchMap(() => {
const hookResults = this.hookManager
.execute(`item.onDocumentLoad`, this.item.id, {
itemId: this.item.id,
layers: this.layers,
})
.filter(
(result): result is Observable<void> =>
result instanceof Observable,
)

return combineLatest([of(null), ...hookResults]).pipe(first())
return loadDocument$.pipe(
waitForSwitch(this.context.bridgeEvent.viewportFree$),
switchMap(() => {
const hookResults = this.hookManager
.execute(`item.onDocumentLoad`, this.item.id, {
itemId: this.item.id,
documentContainer,
})
.filter(
(result): result is Observable<void> =>
result instanceof Observable,
)

return combineLatest([of(null), ...hookResults]).pipe(first())
}),
)
}),
tap(() => {
this.stateSubject.next(`loaded`)
Expand Down Expand Up @@ -191,6 +189,17 @@ export abstract class DocumentRenderer extends DestroyableClass {
merge(unload$).pipe(takeUntil(this.destroy$)).subscribe()
}

protected attach() {
if (this.documentContainer) {
this.containerElement.appendChild(this.documentContainer)
}
}

protected detach() {
this.documentContainer?.remove()
this.documentContainer = undefined
}

public get state$() {
return this.stateSubject
}
Expand Down Expand Up @@ -304,7 +313,7 @@ export abstract class DocumentRenderer extends DestroyableClass {
*
* @important Do not attach anything to the dom yet.
*/
abstract onCreateDocument(): Observable<unknown>
abstract onCreateDocument(): Observable<HTMLElement>

/**
* This lifecycle lets you load whatever you need once the document is attached to
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export class SpineItemHighlights extends DestroyableClass {
super()

const firstLayerElement =
spineItem.renderer.layers[0]?.element ?? document.createElement("div")
spineItem.renderer.documentContainer ?? document.createElement("div")

this.layer = createAnnotationLayer(
this.spineItem.containerElement,
Expand Down Expand Up @@ -80,7 +80,7 @@ export class SpineItemHighlights extends DestroyableClass {

layout() {
const firstLayerElement =
this.spineItem.renderer.layers[0]?.element ??
this.spineItem.renderer.documentContainer ??
document.createElement("div")

layoutAnnotationLayer(firstLayerElement, this.layer)
Expand Down
Loading

0 comments on commit 18915dd

Please sign in to comment.