Checkpoint WebGL book reveal optimization
This commit is contained in:
@@ -32,6 +32,8 @@ class BookPaginationModule extends BaseModule {
|
||||
'extractLayoutLine',
|
||||
'extractRemainingLayoutText',
|
||||
'extractLines',
|
||||
'getActiveStyleTags',
|
||||
'updateStyleTagStack',
|
||||
'countLineWords',
|
||||
'getLineGeometry',
|
||||
'getSpread',
|
||||
@@ -95,8 +97,8 @@ class BookPaginationModule extends BaseModule {
|
||||
this.publish();
|
||||
}
|
||||
|
||||
async preparePendingBlock(block = {}) {
|
||||
const token = ++this.refreshToken;
|
||||
async preparePendingBlock(block = {}, options = {}) {
|
||||
const token = options.activate === false ? this.refreshToken : ++this.refreshToken;
|
||||
const gameId = block.gameId || block.metadata?.gameId || this.storyHistory?.currentGameId || null;
|
||||
const latestRenderedBlockId = Math.max(0, Number(this.storyHistory?.latestRenderedBlockId || 0));
|
||||
const pendingBlockId = Math.max(0, Number(block.blockId || block.metadata?.blockId || 0));
|
||||
@@ -104,10 +106,13 @@ class BookPaginationModule extends BaseModule {
|
||||
return null;
|
||||
}
|
||||
|
||||
const historyBlocks = latestRenderedBlockId > 0
|
||||
? await this.storyHistory.getBlocksRange(gameId, 1, latestRenderedBlockId)
|
||||
const historyEndBlockId = options.includeUnrenderedHistory
|
||||
? Math.max(0, pendingBlockId - 1)
|
||||
: latestRenderedBlockId;
|
||||
const historyBlocks = historyEndBlockId > 0
|
||||
? await this.storyHistory.getBlocksRange(gameId, 1, historyEndBlockId)
|
||||
: [];
|
||||
if (token !== this.refreshToken) return null;
|
||||
if (options.activate !== false && token !== this.refreshToken) return null;
|
||||
|
||||
const normalizedBlock = {
|
||||
...block,
|
||||
@@ -121,26 +126,30 @@ class BookPaginationModule extends BaseModule {
|
||||
gameId
|
||||
}
|
||||
};
|
||||
this.latestBlockId = pendingBlockId;
|
||||
this.latestRenderedBlockId = latestRenderedBlockId;
|
||||
this.spreads = this.buildSpreads([...historyBlocks, normalizedBlock]);
|
||||
this.currentSpreadIndex = Math.max(0, Math.min(this.spreads.length - 1, this.currentSpreadIndex));
|
||||
const targetSpread = this.spreads.find(spread => ['left', 'right'].some(side => {
|
||||
const preparedSpreads = this.buildSpreads([...historyBlocks, normalizedBlock]);
|
||||
const targetSpread = preparedSpreads.find(spread => ['left', 'right'].some(side => {
|
||||
const lines = Array.isArray(spread?.[side]) ? spread[side] : [];
|
||||
return lines.some(line => Number(line?.blockId || 0) === pendingBlockId);
|
||||
}));
|
||||
if (targetSpread) this.currentSpreadIndex = targetSpread.index;
|
||||
this.publish();
|
||||
if (options.activate !== false) {
|
||||
this.latestBlockId = pendingBlockId;
|
||||
this.latestRenderedBlockId = latestRenderedBlockId;
|
||||
this.spreads = preparedSpreads;
|
||||
this.currentSpreadIndex = Math.max(0, Math.min(this.spreads.length - 1, this.currentSpreadIndex));
|
||||
if (targetSpread) this.currentSpreadIndex = targetSpread.index;
|
||||
}
|
||||
if (options.publish !== false) this.publish();
|
||||
document.dispatchEvent(new CustomEvent('book-pagination:block-prepared', {
|
||||
detail: {
|
||||
blockId: pendingBlockId,
|
||||
spread: this.getCurrentSpread(),
|
||||
spreadIndex: this.currentSpreadIndex,
|
||||
latestBlockId: this.latestBlockId,
|
||||
latestRenderedBlockId: this.latestRenderedBlockId
|
||||
spread: targetSpread || (options.activate === false ? preparedSpreads[0] : this.getCurrentSpread()),
|
||||
spreadIndex: targetSpread?.index ?? this.currentSpreadIndex,
|
||||
latestBlockId: pendingBlockId,
|
||||
latestRenderedBlockId,
|
||||
preloadOnly: options.activate === false
|
||||
}
|
||||
}));
|
||||
return this.getCurrentSpread();
|
||||
return targetSpread || (options.activate === false ? preparedSpreads[0] : this.getCurrentSpread());
|
||||
}
|
||||
|
||||
buildSpreads(blocks = []) {
|
||||
@@ -342,6 +351,7 @@ class BookPaginationModule extends BaseModule {
|
||||
isFinal: lineIndex === layout.breaks.length - 2,
|
||||
smallCaps: Boolean(metadata.smallCaps),
|
||||
hyphenated: Boolean(endNode?.type === 'penalty' && endNode.penalty === 100),
|
||||
activeStyleTags: this.getActiveStyleTags(layout.nodes, startBreak.position),
|
||||
align: 'justify'
|
||||
};
|
||||
}
|
||||
@@ -385,12 +395,45 @@ class BookPaginationModule extends BaseModule {
|
||||
ratio: breaks[index].ratio || 0,
|
||||
isFinal: index === breaks.length - 1,
|
||||
hyphenated: Boolean(lineNodes.at(-1)?.type === 'penalty' && lineNodes.at(-1)?.penalty === 100),
|
||||
activeStyleTags: this.getActiveStyleTags(nodes, start),
|
||||
align: options.align || 'justify'
|
||||
});
|
||||
}
|
||||
return lines;
|
||||
}
|
||||
|
||||
getActiveStyleTags(nodes = [], endPosition = 0) {
|
||||
const stack = [];
|
||||
for (let index = 0; index < endPosition; index += 1) {
|
||||
const node = nodes[index];
|
||||
if (node?.type !== 'tag') continue;
|
||||
this.updateStyleTagStack(stack, node.value);
|
||||
}
|
||||
return stack.map(tag => ({ ...tag }));
|
||||
}
|
||||
|
||||
updateStyleTagStack(stack = [], value = '') {
|
||||
const text = String(value || '');
|
||||
if (!text.startsWith('<')) return stack;
|
||||
if (text.startsWith('</')) {
|
||||
if (stack.length) stack.pop();
|
||||
return stack;
|
||||
}
|
||||
const template = document.createElement('div');
|
||||
template.innerHTML = text;
|
||||
const element = template.firstElementChild;
|
||||
if (!element) return stack;
|
||||
const tagName = element.tagName.toLowerCase();
|
||||
const style = String(element.getAttribute('style') || '').toLowerCase();
|
||||
const className = String(element.getAttribute('class') || '').toLowerCase();
|
||||
stack.push({
|
||||
tagName,
|
||||
bold: tagName === 'strong' || tagName === 'b' || /font-weight\s*:\s*(bold|[6-9]00)/.test(style) || className.includes('bold'),
|
||||
italic: tagName === 'em' || tagName === 'i' || /font-style\s*:\s*italic/.test(style) || className.includes('italic')
|
||||
});
|
||||
return stack;
|
||||
}
|
||||
|
||||
countLineWords(line = {}) {
|
||||
const nodes = Array.isArray(line.nodes) ? line.nodes : [];
|
||||
let count = 0;
|
||||
|
||||
Reference in New Issue
Block a user