Commit 0f4581a2 authored by Fred Chasen's avatar Fred Chasen

Track average length of text for checking for overflow

parent 55f7d884
...@@ -31,7 +31,7 @@ module.exports = { ...@@ -31,7 +31,7 @@ module.exports = {
"always" "always"
], ],
"no-unused-vars" : ["warn"], "no-unused-vars" : ["warn"],
"no-console" : ["warn"], "no-console" : ["error", { allow: ["warn", "error"] }],
"no-unused-vars": [ "no-unused-vars": [
"error", "error",
{ "vars": "all", "args": "none" } { "vars": "all", "args": "none" }
......
...@@ -9,6 +9,11 @@ ...@@ -9,6 +9,11 @@
<link rel="coverpage" href="assets/aurorae/images/cover.jpg" /> <link rel="coverpage" href="assets/aurorae/images/cover.jpg" />
<script>
window.PagedConfig = {
after: (flow) => console.log(flow.performance)
}
</script>
<script src="../dist/paged.polyfill.js"></script> <script src="../dist/paged.polyfill.js"></script>
<link href="assets/aurorae/book.css" rel="stylesheet" type='text/css'> <link href="assets/aurorae/book.css" rel="stylesheet" type='text/css'>
......
...@@ -76,6 +76,9 @@ class Chunker { ...@@ -76,6 +76,9 @@ class Chunker {
this.content = content; this.content = content;
this.charsPerBreak = [];
this.maxChars;
if (content) { if (content) {
this.flow(content, renderTo); this.flow(content, renderTo);
} }
...@@ -169,7 +172,7 @@ class Chunker { ...@@ -169,7 +172,7 @@ class Chunker {
let result; let result;
while (!done) { while (!done) {
result = await this.q.enqueue(async () => { return this.renderOnIdle(renderer); }); result = await this.q.enqueue(() => { return this.renderAsync(renderer); });
done = result.done; done = result.done;
} }
...@@ -202,6 +205,18 @@ class Chunker { ...@@ -202,6 +205,18 @@ class Chunker {
}); });
} }
async renderAsync(renderer) {
if (this.stopped) {
return { done: true, canceled: true };
}
let result = await renderer.next();
if (this.stopped) {
return { done: true, canceled: true };
} else {
return result;
}
}
async handleBreaks(node) { async handleBreaks(node) {
let currentPage = this.total + 1; let currentPage = this.total + 1;
let currentPosition = currentPage % 2 === 0 ? "left" : "right"; let currentPosition = currentPage % 2 === 0 ? "left" : "right";
...@@ -271,17 +286,34 @@ class Chunker { ...@@ -271,17 +286,34 @@ class Chunker {
this.emit("page", page); this.emit("page", page);
// Layout content in the page, starting from the breakToken // Layout content in the page, starting from the breakToken
breakToken = await page.layout(content, breakToken); breakToken = await page.layout(content, breakToken, this.maxChars);
await this.hooks.afterPageLayout.trigger(page.element, page, breakToken, this); await this.hooks.afterPageLayout.trigger(page.element, page, breakToken, this);
this.emit("renderedPage", page); this.emit("renderedPage", page);
this.recoredCharLength(page.wrapper.textContent.length);
yield breakToken; yield breakToken;
// Stop if we get undefined, showing we have reached the end of the content // Stop if we get undefined, showing we have reached the end of the content
} }
} }
recoredCharLength(length) {
if (length === 0) {
return;
}
this.charsPerBreak.push(length);
// Keep the length of the last few breaks
if (this.charsPerBreak.length > 4) {
this.charsPerBreak.shift();
}
this.maxChars = this.charsPerBreak.reduce((a, b) => a + b, 0) / (this.charsPerBreak.length);
}
removePages(fromIndex=0) { removePages(fromIndex=0) {
if (fromIndex >= this.pages.length) { if (fromIndex >= this.pages.length) {
......
import { getBoundingClientRect, getClientRects } from "../utils/utils"; import {
getBoundingClientRect,
getClientRects
} from "../utils/utils";
import { import {
walk, walk,
nodeAfter, nodeAfter,
nodeBefore, nodeBefore,
stackChildren,
rebuildAncestors, rebuildAncestors,
needsBreakBefore, needsBreakBefore,
needsBreakAfter,
needsPreviousBreakAfter, needsPreviousBreakAfter,
needsPageBreak, needsPageBreak,
isElement, isElement,
...@@ -14,23 +15,18 @@ import { ...@@ -14,23 +15,18 @@ import {
indexOf, indexOf,
cloneNode, cloneNode,
findElement, findElement,
findRef,
child, child,
isVisible,
isContainer, isContainer,
hasContent, hasContent,
hasTextContent,
validNode, validNode,
prevValidNode, prevValidNode,
nextValidNode,
words, words,
letters letters
} from "../utils/dom"; } from "../utils/dom";
import EventEmitter from "event-emitter"; import EventEmitter from "event-emitter";
import Hook from "../utils/hook"; import Hook from "../utils/hook";
const _requestIdleCallback = typeof window !== "undefined" && ('requestIdleCallback' in window ? requestIdleCallback : requestAnimationFrame);
const PER_PAGE_CHECK = 4; const MAX_CHARS_PER_BREAK = 1500;
/** /**
* Layout * Layout
...@@ -38,7 +34,7 @@ const PER_PAGE_CHECK = 4; ...@@ -38,7 +34,7 @@ const PER_PAGE_CHECK = 4;
*/ */
class Layout { class Layout {
constructor(element, hooks) { constructor(element, hooks, maxChars) {
this.element = element; this.element = element;
this.bounds = this.element.getBoundingClientRect(); this.bounds = this.element.getBoundingClientRect();
...@@ -53,6 +49,7 @@ class Layout { ...@@ -53,6 +49,7 @@ class Layout {
this.hooks.overflow = new Hook(); this.hooks.overflow = new Hook();
} }
this.maxChars = maxChars || MAX_CHARS_PER_BREAK;
} }
async renderTo(wrapper, source, breakToken, bounds=this.bounds) { async renderTo(wrapper, source, breakToken, bounds=this.bounds) {
...@@ -67,6 +64,7 @@ class Layout { ...@@ -67,6 +64,7 @@ class Layout {
let newBreakToken; let newBreakToken;
let check = 0; let check = 0;
let length = 0;
while (!done && !newBreakToken) { while (!done && !newBreakToken) {
next = walker.next(); next = walker.next();
...@@ -74,6 +72,13 @@ class Layout { ...@@ -74,6 +72,13 @@ class Layout {
done = next.done; done = next.done;
if (!node) { if (!node) {
this.hooks && this.hooks.layout.trigger(wrapper, this);
let imgs = wrapper.querySelectorAll("img");
if (imgs.length) {
await this.waitForImages(imgs);
}
newBreakToken = this.findBreakToken(wrapper, source, bounds); newBreakToken = this.findBreakToken(wrapper, source, bounds);
return newBreakToken; return newBreakToken;
} }
...@@ -96,6 +101,8 @@ class Layout { ...@@ -96,6 +101,8 @@ class Layout {
newBreakToken = this.breakAt(node); newBreakToken = this.breakAt(node);
} }
length = 0;
break; break;
} }
...@@ -104,6 +111,8 @@ class Layout { ...@@ -104,6 +111,8 @@ class Layout {
let rendered = this.append(node, wrapper, breakToken, shallow); let rendered = this.append(node, wrapper, breakToken, shallow);
length += rendered.textContent.length;
// Check if layout has content yet // Check if layout has content yet
if (!hasRenderedContent) { if (!hasRenderedContent) {
hasRenderedContent = hasContent(node); hasRenderedContent = hasContent(node);
...@@ -114,9 +123,8 @@ class Layout { ...@@ -114,9 +123,8 @@ class Layout {
walker = walk(nodeAfter(node, source), source); walker = walk(nodeAfter(node, source), source);
} }
// Only check every few elements // Only check x characters
if (check >= PER_PAGE_CHECK) { if (length >= this.maxChars) {
check = 0;
this.hooks && this.hooks.layout.trigger(wrapper, this); this.hooks && this.hooks.layout.trigger(wrapper, this);
...@@ -126,9 +134,12 @@ class Layout { ...@@ -126,9 +134,12 @@ class Layout {
} }
newBreakToken = this.findBreakToken(wrapper, source, bounds); newBreakToken = this.findBreakToken(wrapper, source, bounds);
if (newBreakToken) {
length = 0;
}
} }
check += 1;
} }
return newBreakToken; return newBreakToken;
......
...@@ -109,13 +109,13 @@ class Page { ...@@ -109,13 +109,13 @@ class Page {
} }
*/ */
async layout(contents, breakToken) { async layout(contents, breakToken, maxChars) {
this.clear(); this.clear();
this.startToken = breakToken; this.startToken = breakToken;
this.layoutMethod = new Layout(this.area, this.hooks); this.layoutMethod = new Layout(this.area, this.hooks, maxChars);
let newBreakToken = await this.layoutMethod.renderTo(this.wrapper, contents, breakToken); let newBreakToken = await this.layoutMethod.renderTo(this.wrapper, contents, breakToken);
......
...@@ -138,6 +138,9 @@ class Previewer { ...@@ -138,6 +138,9 @@ class Previewer {
let endTime = performance.now(); let endTime = performance.now();
let msg = "Rendering " + flow.total + " pages took " + (endTime - startTime) + " milliseconds."; let msg = "Rendering " + flow.total + " pages took " + (endTime - startTime) + " milliseconds.";
flow.performance = (endTime - startTime);
flow.size = this.size;
this.emit("rendered", msg, this.size.width && this.size.width.value + this.size.width.unit, this.size.height && this.size.height.value + this.size.height.unit, this.size.orientation, this.size.format); this.emit("rendered", msg, this.size.width && this.size.width.value + this.size.width.unit, this.size.height && this.size.height.value + this.size.height.unit, this.size.orientation, this.size.format);
if (typeof window.onPagesRendered !== "undefined") { if (typeof window.onPagesRendered !== "undefined") {
window.onPagesRendered(msg, this.size.width && this.size.width.value + this.size.width.unit, this.size.height && this.size.height.value + this.size.height.unit, this.size.orientation, this.size.format); window.onPagesRendered(msg, this.size.width && this.size.width.value + this.size.width.unit, this.size.height && this.size.height.value + this.size.height.unit, this.size.orientation, this.size.format);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment