epubjs
Version:
Parse and Render Epubs
351 lines (279 loc) • 9.22 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _core = require("../../utils/core");
var _throttle = _interopRequireDefault(require("lodash/throttle"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
class Stage {
constructor(_options) {
this.settings = _options || {};
this.id = "epubjs-container-" + (0, _core.uuid)();
this.container = this.create(this.settings);
if (this.settings.hidden) {
this.wrapper = this.wrap(this.container);
}
}
/*
* Creates an element to render to.
* Resizes to passed width and height or to the elements size
*/
create(options) {
let height = options.height; // !== false ? options.height : "100%";
let width = options.width; // !== false ? options.width : "100%";
let overflow = options.overflow || false;
let axis = options.axis || "vertical";
let direction = options.direction;
(0, _core.extend)(this.settings, options);
if (options.height && (0, _core.isNumber)(options.height)) {
height = options.height + "px";
}
if (options.width && (0, _core.isNumber)(options.width)) {
width = options.width + "px";
} // Create new container element
let container = document.createElement("div");
container.id = this.id;
container.classList.add("epub-container"); // Style Element
// container.style.fontSize = "0";
container.style.wordSpacing = "0";
container.style.lineHeight = "0";
container.style.verticalAlign = "top";
container.style.position = "relative";
if (axis === "horizontal") {
// container.style.whiteSpace = "nowrap";
container.style.display = "flex";
container.style.flexDirection = "row";
container.style.flexWrap = "nowrap";
}
if (width) {
container.style.width = width;
}
if (height) {
container.style.height = height;
}
if (overflow) {
if (overflow === "scroll" && axis === "vertical") {
container.style["overflow-y"] = overflow;
container.style["overflow-x"] = "hidden";
} else if (overflow === "scroll" && axis === "horizontal") {
container.style["overflow-y"] = "hidden";
container.style["overflow-x"] = overflow;
} else {
container.style["overflow"] = overflow;
}
}
if (direction) {
container.dir = direction;
container.style["direction"] = direction;
}
if (direction && this.settings.fullsize) {
document.body.style["direction"] = direction;
}
return container;
}
wrap(container) {
var wrapper = document.createElement("div");
wrapper.style.visibility = "hidden";
wrapper.style.overflow = "hidden";
wrapper.style.width = "0";
wrapper.style.height = "0";
wrapper.appendChild(container);
return wrapper;
}
getElement(_element) {
var element;
if ((0, _core.isElement)(_element)) {
element = _element;
} else if (typeof _element === "string") {
element = document.getElementById(_element);
}
if (!element) {
throw new Error("Not an Element");
}
return element;
}
attachTo(what) {
var element = this.getElement(what);
var base;
if (!element) {
return;
}
if (this.settings.hidden) {
base = this.wrapper;
} else {
base = this.container;
}
element.appendChild(base);
this.element = element;
return element;
}
getContainer() {
return this.container;
}
onResize(func) {
// Only listen to window for resize event if width and height are not fixed.
// This applies if it is set to a percent or auto.
if (!(0, _core.isNumber)(this.settings.width) || !(0, _core.isNumber)(this.settings.height)) {
this.resizeFunc = (0, _throttle.default)(func, 50);
window.addEventListener("resize", this.resizeFunc, false);
}
}
onOrientationChange(func) {
this.orientationChangeFunc = func;
window.addEventListener("orientationchange", this.orientationChangeFunc, false);
}
size(width, height) {
var bounds;
let _width = width || this.settings.width;
let _height = height || this.settings.height; // If width or height are set to false, inherit them from containing element
if (width === null) {
bounds = this.element.getBoundingClientRect();
if (bounds.width) {
width = Math.floor(bounds.width);
this.container.style.width = width + "px";
}
} else {
if ((0, _core.isNumber)(width)) {
this.container.style.width = width + "px";
} else {
this.container.style.width = width;
}
}
if (height === null) {
bounds = bounds || this.element.getBoundingClientRect();
if (bounds.height) {
height = bounds.height;
this.container.style.height = height + "px";
}
} else {
if ((0, _core.isNumber)(height)) {
this.container.style.height = height + "px";
} else {
this.container.style.height = height;
}
}
if (!(0, _core.isNumber)(width)) {
width = this.container.clientWidth;
}
if (!(0, _core.isNumber)(height)) {
height = this.container.clientHeight;
}
this.containerStyles = window.getComputedStyle(this.container);
this.containerPadding = {
left: parseFloat(this.containerStyles["padding-left"]) || 0,
right: parseFloat(this.containerStyles["padding-right"]) || 0,
top: parseFloat(this.containerStyles["padding-top"]) || 0,
bottom: parseFloat(this.containerStyles["padding-bottom"]) || 0
}; // Bounds not set, get them from window
let _windowBounds = (0, _core.windowBounds)();
let bodyStyles = window.getComputedStyle(document.body);
let bodyPadding = {
left: parseFloat(bodyStyles["padding-left"]) || 0,
right: parseFloat(bodyStyles["padding-right"]) || 0,
top: parseFloat(bodyStyles["padding-top"]) || 0,
bottom: parseFloat(bodyStyles["padding-bottom"]) || 0
};
if (!_width) {
width = _windowBounds.width - bodyPadding.left - bodyPadding.right;
}
if (this.settings.fullsize && !_height || !_height) {
height = _windowBounds.height - bodyPadding.top - bodyPadding.bottom;
}
return {
width: width - this.containerPadding.left - this.containerPadding.right,
height: height - this.containerPadding.top - this.containerPadding.bottom
};
}
bounds() {
let box;
if (this.container.style.overflow !== "visible") {
box = this.container && this.container.getBoundingClientRect();
}
if (!box || !box.width || !box.height) {
return (0, _core.windowBounds)();
} else {
return box;
}
}
getSheet() {
var style = document.createElement("style"); // WebKit hack --> https://davidwalsh.name/add-rules-stylesheets
style.appendChild(document.createTextNode(""));
document.head.appendChild(style);
return style.sheet;
}
addStyleRules(selector, rulesArray) {
var scope = "#" + this.id + " ";
var rules = "";
if (!this.sheet) {
this.sheet = this.getSheet();
}
rulesArray.forEach(function (set) {
for (var prop in set) {
if (set.hasOwnProperty(prop)) {
rules += prop + ":" + set[prop] + ";";
}
}
});
this.sheet.insertRule(scope + selector + " {" + rules + "}", 0);
}
axis(axis) {
if (axis === "horizontal") {
this.container.style.display = "flex";
this.container.style.flexDirection = "row";
this.container.style.flexWrap = "nowrap";
} else {
this.container.style.display = "block";
}
this.settings.axis = axis;
} // orientation(orientation) {
// if (orientation === "landscape") {
//
// } else {
//
// }
//
// this.orientation = orientation;
// }
direction(dir) {
if (this.container) {
this.container.dir = dir;
this.container.style["direction"] = dir;
}
if (this.settings.fullsize) {
document.body.style["direction"] = dir;
}
this.settings.dir = dir;
}
overflow(overflow) {
if (this.container) {
if (overflow === "scroll" && this.settings.axis === "vertical") {
this.container.style["overflow-y"] = overflow;
this.container.style["overflow-x"] = "hidden";
} else if (overflow === "scroll" && this.settings.axis === "horizontal") {
this.container.style["overflow-y"] = "hidden";
this.container.style["overflow-x"] = overflow;
} else {
this.container.style["overflow"] = overflow;
}
}
this.settings.overflow = overflow;
}
destroy() {
var base;
if (this.element) {
if (this.settings.hidden) {
base = this.wrapper;
} else {
base = this.container;
}
if (this.element.contains(this.container)) {
this.element.removeChild(this.container);
}
window.removeEventListener("resize", this.resizeFunc);
window.removeEventListener("orientationChange", this.orientationChangeFunc);
}
}
}
var _default = Stage;
exports.default = _default;