Commit 50e20ed2 authored by Fred Chasen's avatar Fred Chasen

Break layout on break-before elements

parent 4d46a83d
Pipeline #35 failed with stage
......@@ -40,6 +40,8 @@ const TEMPLATE = `<div class="pagedjs_page">
</div>
</div>`;
const _requestIdleCallback = 'requestIdleCallback' in window ? requestIdleCallback : requestAnimationFrame;
/**
* Chop up text into flows
* @class
......@@ -116,7 +118,7 @@ class Chunker {
renderOnIdle(renderer) {
return new Promise(resolve => {
requestIdleCallback(() => {
_requestIdleCallback(() => {
let result = renderer.next();
resolve(result);
});
......@@ -208,9 +210,13 @@ class Chunker {
if (!blank) {
// Listen for page overflow
page.onOverflow((overflow) => {
requestIdleCallback(() => {
if (total < this.pages.length) {
this.pages[total].prepend(overflow);
_requestIdleCallback(() => {
let index = this.pages.indexOf(page) + 1;
if (this.pages[index].breakBefore || this.pages[index].previousBreakAfter) {
let newPage = this.insertPage(index - 1);
newPage.prepend(overflow);
} else if (index < this.pages.length) {
this.pages[index].prepend(overflow);
} else {
let newPage = this.addPage();
newPage.prepend(overflow);
......@@ -247,7 +253,7 @@ class Chunker {
if (!blank) {
// Listen for page overflow
page.onOverflow((overflow) => {
requestIdleCallback(() => {
_requestIdleCallback(() => {
if (total < this.pages.length) {
this.pages[total].prepend(overflow);
} else {
......
......@@ -5,10 +5,12 @@ import {
stackChildren,
rebuildAncestors,
needsBreakBefore,
needsBreakAfter
needsBreakAfter,
needsPreviousBreakAfter
} from "../utils/dom";
import EventEmitter from "event-emitter";
import Hook from "../utils/hook";
const _requestIdleCallback = 'requestIdleCallback' in window ? requestIdleCallback : requestAnimationFrame;
const PER_PAGE_CHECK = 4;
......@@ -126,6 +128,7 @@ class Layout {
let next;
let offset = 0;
let hasOverflow = false;
let hasContent = false;
let newBreakToken;
let after;
......@@ -145,20 +148,43 @@ class Layout {
this.hooks.layoutNode.trigger(node);
// Check if the rendered element has a breakBefore set
// if (needsBreakBefore(node)) {
// // Break layout with current node
// newBreakToken = {
// node: node,
// offset: 0
// };
// break;
// }
if (hasContent && (needsBreakBefore(node) || needsPreviousBreakAfter(node))) {
// Check for overflow
hasOverflow = this.hasOverflow();
if (hasOverflow) {
let overflow = this.overflow(this.element);
if (overflow) {
newBreakToken = this.findBreakToken(overflow, content);
if (newBreakToken && newBreakToken.node) {
this.removeOverflow(overflow);
}
break;
}
} else {
// Break layout with current node
newBreakToken = {
node: node,
offset: 0
};
break;
}
}
shallow = this.isContainer(node);
rendered = this.render(node, this.wrapper, breakToken, shallow);
// Only register element content
if (!hasContent && (node.nodeType === 1 || node.nodeType === 3)) {
hasContent = true;
}
if (!shallow) {
after = nodeAfter(node, content);
......@@ -202,7 +228,7 @@ class Layout {
check += 1;
}
requestIdleCallback(() => {
_requestIdleCallback(() => {
this.listened = this.listeners();
})
......@@ -309,7 +335,7 @@ class Layout {
return overflow.extractContents();
// requestIdleCallback(() => this.removeEmpty());
// _requestIdleCallback(() => this.removeEmpty());
}
removeEmpty() {
......@@ -337,7 +363,7 @@ class Layout {
});
stack = undefined;
requestIdleCallback(() => this.floats());
_requestIdleCallback(() => this.floats());
}
......
......@@ -65,10 +65,7 @@ class Breaks extends Handler {
}
})
// Always break -- handle right / left in module
// declaration.property = property;
// child.name = "column";
// Remove from CSS -- handle right / left in module
dList.remove(dItem);
}
}
......@@ -91,9 +88,9 @@ class Breaks extends Handler {
if (nodeAfter) {
nodeAfter.setAttribute("data-previous-break-after", prop.value);
}
} else {
elements[i].setAttribute("data-" + prop.property, prop.value);
}
elements[i].setAttribute("data-" + prop.property, prop.value);
}
}
}
......@@ -113,6 +110,7 @@ class Breaks extends Handler {
addBreakAttributes(page) {
let before = page.wrapper.querySelector("[data-break-before]");
let after = page.wrapper.querySelector("[data-break-after]");
let previousBreakAfter = page.wrapper.querySelector("[data-previous-break-after]");
if (before) {
if (before.dataset.splitFrom) {
......@@ -133,6 +131,12 @@ class Breaks extends Handler {
page.element.setAttribute("data-break-after", after.dataset.breakAfter);
}
}
if (previousBreakAfter && previousBreakAfter.dataset) {
if (previousBreakAfter.dataset.previousBreakAfter && previousBreakAfter.dataset.previousBreakAfter !== "avoid") {
page.previousBreakAfter = previousBreakAfter.dataset.previousBreakAfter;
}
}
}
layout(pageElement, page) {
......
......@@ -242,6 +242,7 @@ export default `
[data-break-before="recto"]:not([data-split-from]),
[data-break-before="verso"]:not([data-split-from])
{
-webkit-column-break-before: always;
break-before: column;
}
......@@ -253,6 +254,7 @@ export default `
[data-break-after="recto"]:not([data-split-to]),
[data-break-after="verso"]:not([data-split-to])
{
-webkit-column-break-after: always;
break-after: column;
}
......@@ -290,6 +292,7 @@ export default `
max-height: 100%;
min-height: 100%;
height: 100% !important;
page-break-after: always;
break-after: page;
}
}
......
......@@ -60,11 +60,11 @@ export function nodeAfter(node, limiter) {
export function nodeBefore(node, limiter) {
let before = node;
if (after.prevSibling) {
if (before.prevSibling) {
if (limiter && node === limiter) {
return;
}
before = after.prevSibling;
before = before.prevSibling;
} else {
while (before) {
before = before.parentNode;
......@@ -147,9 +147,9 @@ export function rebuildAncestors(node) {
parent.removeAttribute("data-break-before");
}
// if (ancestor.hasAttribute("data-break-after")) {
// ancestor.removeAttribute("data-break-after");
// }
if (parent.hasAttribute("data-previous-break-after")) {
parent.removeAttribute("data-previous-break-after");
}
if (added.length) {
let container = added[added.length-1];
......@@ -216,8 +216,12 @@ export function needsBreakBefore(node) {
typeof node.dataset !== "undefined" &&
typeof node.dataset.breakBefore !== "undefined" &&
(node.dataset.breakBefore === "always" ||
node.dataset.breakBefore === "page" ||
node.dataset.breakBefore === "left" ||
node.dataset.breakBefore === "right")) {
node.dataset.breakBefore === "right" ||
node.dataset.breakBefore === "recto" ||
node.dataset.breakBefore === "verso")
) {
return true;
}
......@@ -229,8 +233,29 @@ export function needsBreakAfter(node) {
typeof node.dataset !== "undefined" &&
typeof node.dataset.breakAfter !== "undefined" &&
(node.dataset.breakAfter === "always" ||
node.dataset.breakAfter === "page" ||
node.dataset.breakAfter === "left" ||
node.dataset.breakAfter === "right")) {
node.dataset.breakAfter === "right" ||
node.dataset.breakAfter === "recto" ||
node.dataset.breakAfter === "verso")
) {
return true;
}
return false;
}
export function needsPreviousBreakAfter(node) {
if( typeof node !== "undefined" &&
typeof node.dataset !== "undefined" &&
typeof node.dataset.previousBreakAfter !== "undefined" &&
(node.dataset.previousBreakAfter === "always" ||
node.dataset.previousBreakAfter === "page" ||
node.dataset.previousBreakAfter === "left" ||
node.dataset.previousBreakAfter === "right" ||
node.dataset.previousBreakAfter === "recto" ||
node.dataset.previousBreakAfter === "verso")
) {
return true;
}
......
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