summaryrefslogtreecommitdiff
path: root/lib/epub.js/src/managers/helpers/stage.js
diff options
context:
space:
mode:
Diffstat (limited to 'lib/epub.js/src/managers/helpers/stage.js')
-rw-r--r--lib/epub.js/src/managers/helpers/stage.js363
1 files changed, 363 insertions, 0 deletions
diff --git a/lib/epub.js/src/managers/helpers/stage.js b/lib/epub.js/src/managers/helpers/stage.js
new file mode 100644
index 0000000..d0f67e6
--- /dev/null
+++ b/lib/epub.js/src/managers/helpers/stage.js
@@ -0,0 +1,363 @@
+import {uuid, isNumber, isElement, windowBounds, extend} from "../../utils/core";
+import throttle from 'lodash/throttle'
+
+class Stage {
+ constructor(_options) {
+ this.settings = _options || {};
+ this.id = "epubjs-container-" + 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;
+
+ extend(this.settings, options);
+
+ if(options.height && isNumber(options.height)) {
+ height = options.height + "px";
+ }
+
+ if(options.width && 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(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(!isNumber(this.settings.width) ||
+ !isNumber(this.settings.height) ) {
+ this.resizeFunc = throttle(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 (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 (isNumber(height)) {
+ this.container.style.height = height + "px";
+ } else {
+ this.container.style.height = height;
+ }
+ }
+
+ if(!isNumber(width)) {
+ width = this.container.clientWidth;
+ }
+
+ if(!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 = 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 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);
+
+ }
+ }
+}
+
+export default Stage;