Skip to content

Instantly share code, notes, and snippets.

@JayPanoz
Created April 5, 2018 14:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JayPanoz/0a4b92c2c0000af76fc18ee848d900dd to your computer and use it in GitHub Desktop.
Save JayPanoz/0a4b92c2c0000af76fc18ee848d900dd to your computer and use it in GitHub Desktop.
JS and CSS files Pages iOS outputs when exporting to EPUB3
/* unvisited link */
a:link {
color: initial;
}
/* visited link */
a:visited {
color: initial;
}
/* mouse over link */
a:hover {
color: initial;
}
/* selected link */
a:active {
color: initial;
}
a{
text-decoration: none;
}
p{
margin: 0px;
}
sub{
vertical-align: -10%;
font-size: 67%;
}
sup{
vertical-align: 33%;
font-size: 67%;
}
.s1{
list-style: none;
}
.p1{
padding-left: 0;
margin-top: 0;
padding-top: 0;
padding-right: 0;
margin-bottom: 2.4%;
padding-bottom: 0;
font-style: normal;
font-weight: 400;
font-size: 100.0%;
font-family: "Iowan Old Style";
color: #000000;
letter-spacing: 0;
font-variant: normal;
text-transform: none;
text-decoration: none;
text-align: left;
text-indent: 0;
break-after: page;
page-break-after: always;
hyphens: none;
-webkit-hyphens: none;
text-shadow: none;
}
.p2{
padding-left: 0;
margin-top: 0;
padding-top: 0;
padding-right: 0;
margin-bottom: 0;
padding-bottom: 0;
font-style: normal;
font-weight: 700;
font-size: 100.0%;
font-family: "Futura";
color: #000000;
letter-spacing: 0;
font-variant: normal;
text-transform: none;
text-decoration: none;
text-align: left;
text-indent: 0;
hyphens: none;
-webkit-hyphens: none;
text-shadow: none;
}
.p3{
padding-left: 2.7%;
margin-bottom: 0.9%;
font-weight: 500;
}
.p4{
padding-left: 0;
margin-top: 0;
padding-top: 0;
padding-right: 0;
margin-bottom: 2.1%;
padding-bottom: 0;
font-style: normal;
font-weight: 700;
font-size: 162.5%;
font-family: "Futura";
color: #000000;
letter-spacing: 0.2em;
font-variant: normal;
text-transform: uppercase;
text-decoration: none;
text-align: center;
text-indent: 0;
hyphens: none;
-webkit-hyphens: none;
text-shadow: none;
}
.p5{
padding-left: 0;
margin-top: 0;
padding-top: 0;
padding-right: 0;
margin-bottom: 2.4%;
padding-bottom: 0;
font-style: normal;
font-weight: 400;
font-size: 100.0%;
font-family: "Iowan Old Style";
color: #000000;
letter-spacing: 0;
font-variant: normal;
text-transform: none;
text-decoration: none;
text-align: left;
text-indent: 0;
hyphens: none;
-webkit-hyphens: none;
text-shadow: none;
}
.p6{
padding-left: 0;
margin-top: 0;
padding-top: 0;
padding-right: 0;
margin-bottom: 3.8%;
padding-bottom: 0;
font-style: normal;
font-weight: 700;
font-size: 106.2%;
font-family: "Futura";
color: #000000;
letter-spacing: 0.2em;
font-variant: normal;
text-transform: uppercase;
text-decoration: none;
text-align: left;
text-indent: 0;
hyphens: none;
-webkit-hyphens: none;
text-shadow: none;
}
.p7{
padding-left: 0;
margin-top: 0;
padding-top: 0;
padding-right: 0;
margin-bottom: 3.8%;
padding-bottom: 0;
font-style: normal;
font-weight: 500;
font-size: 100.0%;
font-family: "Futura";
color: #000000;
letter-spacing: 0;
font-variant: normal;
text-transform: none;
text-decoration: none;
text-align: left;
text-indent: 0;
hyphens: none;
-webkit-hyphens: none;
text-shadow: none;
}
.p8{
padding-left: 0;
margin-top: 0;
padding-top: 0;
padding-right: 0;
margin-bottom: 2.4%;
padding-bottom: 0;
font-style: normal;
font-weight: 400;
font-size: 100.0%;
font-family: "Iowan Old Style";
color: #000000;
letter-spacing: 0;
font-variant: normal;
text-transform: none;
text-align: left;
text-indent: 0;
hyphens: none;
-webkit-hyphens: none;
text-shadow: none;
}
.c1{
background: transparent;
}
.c2{
color: #000000;
}
.c3{
font-style: normal;
font-weight: 700;
font-family: "Iowan Old Style";
}
.c4{
font-style: italic;
font-weight: 700;
font-family: "Iowan Old Style";
}
function debugLog(string) {
//iBooks.log(string);
}
function debugLogError(error) {
debugLog("ERROR: " + error.name + ", " + error.message);
//window.alert("ERROR: " + error.name + ", " + error.message);
}
function debugAssert(condition, messqge) {
if (!condition) {
debugLog("ASSERT FAILED: " + messqge);
}
}
function dumpObject(object, name) {
debugLog(name + " BEGIN");
if (!object) {
debugLog("NULL");
}
for (var property in object) {
try {
var value = object[property];
var type = typeof(value);
if (type != 'function') {
debugLog(type + " " + property + " " + value);
}
}
catch (error) {
debugLog(property +" "+error);
}
}
debugLog(name + " END");
}
function dumpEpubReadingSystemFeatures() {
debugLog("epubReadingSystem FEATURES BEGIN");
if (navigator.epubReadingSystem) {
var featureArray = ["dom-manipulation", "layout-changes", "touch-events", "mouse-events", "keyboard-events", "spine-scripting"];
featureArray.forEach(function(feature) {
var supported = navigator.epubReadingSystem.hasFeature(feature);
debugLog(feature +":"+ supported);
});
}
debugLog("epubReadingSystem FEATURES END");
}
function isKobo() {
return 'koboApp' in window;
}
function isADE() {
var epubReadingSystem = navigator.epubReadingSystem;
if (epubReadingSystem) {
return epubReadingSystem.name == 'RMSDK';
}
return false;
}
function isIOS() {
var platform = navigator.platform;
if (["iPad", "iPod", "iPhone"].includes(platform)) {
return true;
}
return false;
}
function useMouselessButtons() {
return (isADE() || isKobo()) && isIOS();
}
function stringForRect (rect) {
return "{ " + rect.left + ", " + rect.top + ", " + rect.width + ", " + rect.height + " }";
}
function stringForEventTargetElement(target) {
return "{tag:" + target.tagName + ";class:" + target.className + ";ID:" + target.id + "}";
}
function dumpEvent (event) {
//event.type;
//event.target;
//event.currentTarget;
}
function dumpMouseEvent (event) {
/*
debugLog("");
debugLog(event.type);
debugLog("client = " + event.clientX + ", " + event.clientY);
debugLog("layer = " + event.layerX + ", " + event.layerY);
debugLog("movement = " + event.movementX + ", " + event.movementY);
debugLog("offset = " + event.offsetX + ", " + event.offsetY);
debugLog("screen = " + event.screenX + ", " + event.screenY);
debugLog("plain = " + event.x + ", " + event.y);
debugLog("");
*/
}
function dumpTouch(touch) {
debugLog(" touch: " + "ID:" + touch.identifier + ";page:"+touch.pageX+","+touch.pageY+";radius:"+touch.radiusX+","+touch.radiusY+";rotation:"+touch.rotationAngle+";force:"+touch.force+";altitude:"+touch.altitudeAngle+";azimuth:"+touch.azimuthAngle + ";target:" + stringForEventTargetElement(touch.target)+";");
}
function dumpTouchList(touchListName, touchList) {
if (touchList) {
var count = touchList.length;
debugLog(" "+touchListName + " (" + count +")");
for (var index = 0; index < count; index++) {
dumpTouch(touchList.item(index));
}
}
}
function dumpTouchEvent(event) {
debugLog("event:"+event.type+";page:"+event.pageX+","+event.pageY+";scale:"+event.scale+";rotation:"+event.rotation+";target:"+stringForEventTargetElement(event.target)+";currentTarget:"+stringForEventTargetElement(event.currentTarget)+";");
dumpTouchList("touches", event.touches);
dumpTouchList("targetTouches", event.targetTouches);
dumpTouchList("changedTouches", event.changedTouches);
}
function stopEventPropagation(event) {
event.stopPropagation();
}
const ViewfinderAction = {
none : -1,
maximize : 0,
goToPrev : 1,
goToNext : 2,
count : 3
};
class GalleryViewfinderObserver {
constructor(owner) {
this.owner = owner;
this.galleryObject = owner.galleryObject;
this.galleryElement = owner.galleryElement;
this.viewfinderElement = owner.viewfinderElement;
}
onCurrentItemChange(oldItemIndex, newItemIndex) {}
onMouseMoveInViewfinder(point) {
}
onMouseEnterViewfinder(point) {
}
onMouseLeaveViewfinder(point) {
}
onClickInViewfinder(point) {
}
onPageShow() {
}
onPageHide() {
}
onMouseEnterViewfinderChild(viewfinderChildElement) {
}
onMouseLeaveViewfinderChild(viewfinderChildElement) {
}
}
class GalleryButtonsViewfinderManager extends GalleryViewfinderObserver {
constructor(owner) {
super(owner);
var viewfinderElement = this.viewfinderElement;
this.goToPrevButtonElement = viewfinderElement.getElementsByClassName("gallery-button-goToPrev")[0];
this.goToNextButtonElement = viewfinderElement.getElementsByClassName("gallery-button-goToNext")[0];
this.maximizeButtonElement = viewfinderElement.getElementsByClassName("gallery-button-maximize")[0];
this.buttonsTimeout = null;
this.buttonUnderMouseCursor = null;
this.setButtonMouseEnterLeaveHandlers(this.goToPrevButtonElement);
this.setButtonFocusHandlers(this.goToPrevButtonElement);
this.setButtonKeyupHandlers(this.goToPrevButtonElement);
this.setButtonMouseEnterLeaveHandlers(this.goToNextButtonElement);
this.setButtonFocusHandlers(this.goToNextButtonElement);
this.setButtonKeyupHandlers(this.goToNextButtonElement);
if (this.maximizeButtonElement) {
this.setButtonMouseEnterLeaveHandlers(this.maximizeButtonElement);
this.setButtonFocusHandlers(this.maximizeButtonElement);
}
}
handleNextPreviousButtonKeyUpEvent(e) {
var movePrevious = false;
var moveNext = false;
if (e.keyCode == 13 || e.keyCode == 32) /* Spacebar or Enter */ {
e.preventDefault();
if (e.target == this.goToPrevButtonElement) {
movePrevious = true;
}
else if(e.target == this.goToNextButtonElement) {
moveNext = true;
}
}
else if (e.keyCode == 37) /* Left Arrow */ {
movePrevious = true;
}
else if (e.keyCode == 39) /* Right Arrow */ {
moveNext = true;
}
if (movePrevious) {
if (this.galleryObject.currentItemIndex > 0) {
this.galleryObject.goToPrevFrame();
if (this.galleryObject.currentItemIndex == 0) {
this.goToNextButtonElement.focus();
}
}
}
if (moveNext) {
if (this.galleryObject.currentItemIndex < this.galleryObject.itemCount - 1) {
this.galleryObject.goToNextFrame();
if (this.galleryObject.currentItemIndex == this.galleryObject.itemCount - 1) {
this.goToPrevButtonElement.focus();
}
}
}
if (movePrevious || moveNext) {
this.updateButtonsDisplayState();
}
}
setButtonMouseEnterLeaveHandlers(buttonElement) {
buttonElement.onmouseenter = this.onMouseEnterButton.bind(this, buttonElement);
buttonElement.onmouseleave = this.onMouseLeaveButton.bind(this, buttonElement);
}
setButtonFocusHandlers(buttonElement) {
buttonElement.onfocus = this.onButtonGainedFocus.bind(this, buttonElement);
buttonElement.onblur = this.onButtonLostFocus.bind(this, buttonElement);
}
setButtonKeyupHandlers(buttonElement) {
buttonElement.onkeyup = this.handleNextPreviousButtonKeyUpEvent.bind(this);
}
setButtonsVisibility(showPrev, showNext, showMaximize) {
Gallery.setButtonVisibility(this.goToPrevButtonElement, showPrev);
Gallery.setButtonVisibility(this.goToNextButtonElement, showNext);
Gallery.setButtonVisibility(this.maximizeButtonElement, showMaximize);
}
hideButtonsNotUnderMouseCursor() {
var showPrev = this.buttonUnderMouseCursor == this.goToPrevButtonElement;
var showNext = this.buttonUnderMouseCursor == this.goToNextButtonElement;
var showMaximize = this.buttonUnderMouseCursor == this.maximizeButtonElement;
this.setButtonsVisibility(showPrev, showNext, showMaximize);
}
startButtonsTimeout() {
this.buttonsTimeout = setTimeout(function() { this.hideButtonsNotUnderMouseCursor() }.bind(this), 2500);
}
killButtonsTimeout() {
if (this.buttonsTimeout) {
clearTimeout(this.buttonsTimeout);
this.buttonsTimeout = null;
}
}
hideButtonsWithoutDelay() {
this.killButtonsTimeout();
this.setButtonsVisibility(false, false, false);
}
viewfinderActionForMousePosition(point) {
var itemCount = this.galleryObject.itemCount;
var currentItemIndex = this.galleryObject.currentItemIndex;
var viewfinderWidth = this.viewfinderElement.getBoundingClientRect().width;
var x = point.x;
const adjacentSlideActiveMargin = 0.2;
if (currentItemIndex > 0) {
if (x < adjacentSlideActiveMargin * viewfinderWidth) {
return ViewfinderAction.goToPrev;
}
}
var showNext = false;
if (currentItemIndex + 1 < itemCount) {
if (viewfinderWidth - x < adjacentSlideActiveMargin * viewfinderWidth) {
return ViewfinderAction.goToNext;
}
}
if (this.maximizeButtonElement) {
return ViewfinderAction.maximize;
}
return ViewfinderAction.none;
}
updateButtonsVisibility(point) {
var action = this.viewfinderActionForMousePosition(point);
var showPrev = action == ViewfinderAction.goToPrev;
var showNext = action == ViewfinderAction.goToNext;
var showMaximize = true;
if (!this.maximizeButtonElement) {
this.viewfinderElement.style.cursor = (showPrev || showNext) ? 'pointer' : 'default';
}
this.setButtonsVisibility(showPrev, showNext, showMaximize);
this.updateButtonsDisplayState();
}
updateButtonsDisplayState() {
// Update display style of the next/previous buttons so that they are present/removed from the
// focus loop at the correct indexes.
var itemCount = this.galleryObject.itemCount;
var currentIndex = this.galleryObject.currentItemIndex;
if (currentIndex == 0) {
this.goToPrevButtonElement.tabIndex = -1;
this.goToPrevButtonElement.style.display = 'none';
}
else {
this.goToPrevButtonElement.tabIndex = 0;
this.goToPrevButtonElement.style.display = 'block';
}
if (currentIndex == itemCount - 1) {
this.goToNextButtonElement.tabIndex = -1;
this.goToNextButtonElement.style.display = 'none';
}
else {
this.goToNextButtonElement.tabIndex = 0;
this.goToNextButtonElement.style.display = 'block';
}
}
onMouseMoveInViewfinder(point) {
this.killButtonsTimeout();
this.updateButtonsVisibility(point);
this.startButtonsTimeout();
}
onMouseEnterViewfinder(point) {
debugAssert(this.buttonsTimeout == null, "buttonsTimeout not null on onMouseEnterViewfinder");
}
onMouseLeaveViewfinder(point) {
this.hideButtonsWithoutDelay();
}
onClickInViewfinder(point) {
this.killButtonsTimeout();
var action = this.viewfinderActionForMousePosition(point);
switch (action) {
case ViewfinderAction.goToPrev:
this.galleryObject.goToPrevFrame();
break;
case ViewfinderAction.goToNext:
this.galleryObject.goToNextFrame();
break;
case ViewfinderAction.maximize:
if (this.maximizeButtonElement) {
this.galleryObject.maximizeFrame();
}
break;
}
this.updateButtonsVisibility(point);
this.startButtonsTimeout();
}
onPageShow() {
this.hideButtonsWithoutDelay();
}
onPageHide() {
this.hideButtonsWithoutDelay();
}
onMouseEnterButton(buttonElement) {
this.buttonUnderMouseCursor = buttonElement;
}
onMouseLeaveButton(buttonElement) {
this.buttonUnderMouseCursor = null;
}
onButtonGainedFocus(buttonElement) {
Gallery.setButtonVisibility(buttonElement, true);
}
onButtonLostFocus(buttonElement) {
Gallery.setButtonVisibility(buttonElement, false);
}
}
class GalleryCurrentItemObserver {
constructor(galleryObject) {
this.galleryObject = galleryObject;
}
onCurrentItemChange(oldItemIndex, newItemIndex, animate) {
}
}
class GalleryImageRollManager {
constructor(galleryObject) {
this.galleryObject = galleryObject;
this.rollElement = galleryObject.galleryElement.getElementsByClassName("gallery-image-roll")[0];
}
removeTransition() {
this.rollElement.classList.remove("gallery-image-roll-transition")
}
onCurrentItemChange(oldItemIndex, newItemIndex, animate) {
this.removeTransition();
if (animate) {
this.rollElement.classList.add("gallery-image-roll-transition");
this.rollElement.addEventListener("transitionend", this.removeTransition.bind(this));
}
this.rollElement.style.left = -(newItemIndex * 100) + "%";
}
}
class GalleryCaptionRollManager extends GalleryCurrentItemObserver {
constructor(galleryObject) {
super(galleryObject);
this.rollElement = galleryObject.galleryElement.getElementsByClassName("gallery-caption-roll")[0];
this.initializeCaptionIDs();
}
getFirstParagraphElementOfCaption(caption) {
var paragraphTagNameArray = ["p", "li" ];
for (var index = 0; index < paragraphTagNameArray.length; index++) {
var paragraphTagName = paragraphTagNameArray[index];
var paragraphElementList = caption.getElementsByTagName(paragraphTagName);
if (paragraphElementList.length > 0) {
return paragraphElementList[0];
}
}
// no paragraphs/list items
return null;
}
initializeCaptionIDs() {
var captions = Array.prototype.slice.call(this.rollElement.getElementsByClassName("gallery-caption"));
var galleryObject = this.galleryObject;
captions.forEach(function(caption, index) {
var captionTextElement = this.getFirstParagraphElementOfCaption(caption);
if (captionTextElement) {
captionTextElement.id = galleryObject.getCaptionElementIDForIndex(index);
}
}, this);
}
onCurrentItemChange(oldItemIndex, newItemIndex, animate) {
this.rollElement.style.left = -(newItemIndex * 100) + "%";
var captions = Array.prototype.slice.call(this.rollElement.getElementsByClassName("gallery-caption"));
captions.forEach(function(caption, index) {
var captionTextElement = this.getFirstParagraphElementOfCaption(caption);
if (captionTextElement) {
captionTextElement.setAttribute("aria-hidden", newItemIndex == index ? "false" : "true");
}
}, this);
}
}
class GalleryDotManager extends GalleryCurrentItemObserver {
constructor(galleryObject) {
super(galleryObject);
this.dotContainerElement = galleryObject.galleryElement.getElementsByClassName("gallery-dot-container")[0];
this.setupDotElementKeyupHandlers();
}
setupDotElementKeyupHandlers() {
var dotElements = Array.prototype.slice.call(this.dotContainerElement.getElementsByClassName("gallery-dot-selectable"));
dotElements.concat(Array.prototype.slice.call(this.dotContainerElement.getElementsByClassName("gallery-dot-current")));
var handler = this.handleDotElementKeyUpEvent.bind(this);
dotElements.forEach(function(dotElement) {
dotElement.onkeyup = handler;
});
}
handleDotElementKeyUpEvent(e) {
var element = e.target;
var currentIndex = this.galleryObject.currentItemIndex;
var itemCount = this.galleryObject.itemCount;
if (e.keyCode == 37) /* Left Arrow */ {
if (currentIndex > 0) {
this.galleryObject.goToPrevFrame();
var selectedDotElement = Array.prototype.slice.call(this.dotContainerElement.getElementsByClassName("gallery-dot-current"))[0];
selectedDotElement.focus();
}
}
else if (e.keyCode == 39) /* Right Arrow */ {
if (currentIndex < itemCount - 1) {
this.galleryObject.goToNextFrame();
var selectedDotElement = Array.prototype.slice.call(this.dotContainerElement.getElementsByClassName("gallery-dot-current"))[0];
selectedDotElement.focus();
}
}
}
deselectCurrentDot() {
var currentDotGroupCollection = this.dotContainerElement.getElementsByClassName("gallery-dot-current");
if (currentDotGroupCollection.length > 0) {
currentDotGroupCollection[0].setAttribute("aria-checked", "false");
currentDotGroupCollection[0].tabIndex = -1;
currentDotGroupCollection[0].className = "gallery-dot-selectable";
}
}
onCurrentItemChange(oldItemIndex, newItemIndex, animate) {
this.deselectCurrentDot();
var selectableDotGroupCollection = this.dotContainerElement.getElementsByClassName("gallery-dot-selectable");
selectableDotGroupCollection[newItemIndex].setAttribute("aria-checked", "true");
selectableDotGroupCollection[newItemIndex].tabIndex = 0;
selectableDotGroupCollection[newItemIndex].className = "gallery-dot-current";
}
}
class GalleryMouselessButtonsManager extends GalleryCurrentItemObserver {
constructor(galleryObject) {
super(galleryObject);
var viewfinderElement = galleryObject.viewfinderElement;
this.goToPrevButtonElement = viewfinderElement.getElementsByClassName("gallery-button-goToPrev")[0];
this.goToPrevButtonElement.onclick = galleryObject.goToPrevFrame.bind(galleryObject);
this.goToPrevButtonElement.onkeyup = this.handleNextPreviousButtonKeyUpEvent;
this.goToNextButtonElement = viewfinderElement.getElementsByClassName("gallery-button-goToNext")[0];
this.goToNextButtonElement.onclick = galleryObject.goToNextFrame.bind(galleryObject);
this.goToNextButtonElement.onkeyup = this.handleNextPreviousButtonKeyUpEvent;
this.maximizeButtonElement = viewfinderElement.getElementsByClassName("gallery-button-maximize")[0];
if (this.maximizeButtonElement) {
this.maximizeButtonElement.onclick = galleryObject.maximizeFrame.bind(galleryObject);
}
}
onCurrentItemChange(oldItemIndex, newItemIndex, animate) {
var itemCount = this.galleryObject.itemCount;
var showNext = newItemIndex + 1 < this.galleryObject.itemCount;
var showPrev = newItemIndex > 0;
Gallery.setButtonVisibility(this.goToPrevButtonElement, showPrev);
Gallery.setButtonVisibility(this.goToNextButtonElement, showNext);
Gallery.setButtonVisibility(this.maximizeButtonElement, true);
}
}
class GalleryViewfinderManager {
addViewfinderHandlers() {
this.viewfinderElement.onclick = this.onClickInViewfinder.bind(this);
this.viewfinderElement.onmouseenter = this.onMouseEnterViewfinder.bind(this);
this.viewfinderElement.onmouseleave = this.onMouseLeaveViewfinder.bind(this);
this.viewfinderElement.onmousemove = this.onMouseMoveInViewfinder.bind(this);
}
addObservers() {
this.viewfinderObserverArray = [];
if (!useMouselessButtons()) {
this.viewfinderObserverArray.push(new GalleryButtonsViewfinderManager(this));
}
}
constructor (galleryObject) {
this.galleryObject = galleryObject;
this.galleryElement = galleryObject.galleryElement;
this.viewfinderElement = this.galleryElement.getElementsByClassName("gallery-image-viewfinder")[0];
this.addViewfinderHandlers();
this.addObservers();
}
viewfinderMouseEventCoordinates(event) {
var viewfinderBounds = this.viewfinderElement.getBoundingClientRect();
var point = { "x" : event.clientX - viewfinderBounds.left, "y" : event.clientY - viewfinderBounds.top };
return point;
}
onMouseEventInViewfinder(event, handlerName) {
try {
//dumpMouseEvent(event);
var point = this.viewfinderMouseEventCoordinates(event);
this.viewfinderObserverArray.forEach(function (observer) {
observer[handlerName](point);
});
stopEventPropagation(event);
}
catch (error) {
debugLogError(error);
}
}
onMouseMoveInViewfinder(event) {
this.onMouseEventInViewfinder(event, "onMouseMoveInViewfinder");
}
onMouseEnterViewfinder(event) {
this.onMouseEventInViewfinder(event, "onMouseEnterViewfinder");
}
onMouseLeaveViewfinder(event) {
this.onMouseEventInViewfinder(event, "onMouseLeaveViewfinder");
}
onClickInViewfinder(event) {
this.onMouseEventInViewfinder(event, "onClickInViewfinder");
}
onPageShow() {
this.viewfinderObserverArray.forEach(function (observer) {
observer.onPageShow();
});
}
onPageHide() {
this.viewfinderObserverArray.forEach(function (observer) {
observer.onPageHide();
});
}
onCurrentItemChange(oldItemIndex, newItemIndex) {
this.viewfinderObserverArray.forEach(function(observer) {
observer.onCurrentItemChange(oldItemIndex, newItemIndex);
});
}
}
class TouchManager {
constructor(galleryObject) {
this.galleryObject = galleryObject;
this.viewfinderElement = galleryObject.viewfinderElement;
//debugLog("Create TouchManager");
var element = this.viewfinderElement;
//debugLog("viewfinderElement = " + element);
element.addEventListener("touchstart", this.onTouchStart.bind(this), true);
element.addEventListener("touchmove", this.onTouchMove.bind(this), true);
element.addEventListener("touchend", this.onTouchEnd.bind(this), true);
element.addEventListener("touchcancel", this.onTouchCancel.bind(this), true);
}
viewfinderTouchEventCoordinates(event) {
var viewfinderBounds = this.viewfinderElement.getBoundingClientRect();
var point = { "x" : event.pageX - viewfinderBounds.left, "y" : event.pageY - viewfinderBounds.top };
//debugLog("touch point x:"+point.x+", y:"+point.y+"");
return point;
}
onTouchEvent(event) {
//dumpTouchEvent(event);
stopEventPropagation(event);
event.preventDefault();
}
onTouchStart(event) {
try {
this.onTouchEvent(event);
this.frameWidth = this.viewfinderElement.getBoundingClientRect().width;
this.dragStartPoint = this.viewfinderTouchEventCoordinates(event);
this.dragStartTime = new Date().getTime();
this.dragStartX = this.dragStartPoint.x;
this.dragStartItemIndex = this.galleryObject.currentItemIndex;
debugLog("onTouchStart: frameWidth:"+this.frameWidth+";dragStartItemIndex:"+this.dragStartItemIndex+";dragStartX:"+this.dragStartX);
}
catch (error) {
debugLogError(error);
}
}
onTouchMove(event) {
try {
this.onTouchEvent(event);
var dragCurrX = this.viewfinderTouchEventCoordinates(event).x;
var deltaX = dragCurrX - this.dragStartX;
var relativeDeltaX = deltaX / this.frameWidth;
var newItemIndex = this.dragStartItemIndex - relativeDeltaX;
debugLog("onTouchMove: frameWidth:"+this.frameWidth+";dragStartItemIndex:"+this.dragStartItemIndex+";dragStartX:"+this.dragStartX+";dragCurrX:"+dragCurrX+";deltaX:"+deltaX+";relativeDeltaX:"+relativeDeltaX+";newItemIndex:"+newItemIndex+"this.galleryObject.currentItemIndex:" + this.galleryObject.currentItemIndex);
if (newItemIndex >= 0 && newItemIndex <= this.galleryObject.itemCount - 1) {
this.galleryObject.changeCurrentItemIndex(newItemIndex, false);
}
}
catch (error) {
debugLogError(error);
}
}
onTouchEnd(event) {
try {
this.onTouchEvent(event);
var dragEndPoint = this.viewfinderTouchEventCoordinates(event);
var dragEndTime = new Date().getTime();
var endItemIndex = this.galleryObject.currentItemIndex;
var intEndItemIndex = Math.round(endItemIndex);
var deltaT = dragEndTime - this.dragStartTime;
// If duration short enough.
if (deltaT < 250) {
// If it hasn't resulted in a current item change.
if (intEndItemIndex == this.dragStartItemIndex) {
var absDeltaX = Math.abs(dragEndPoint.x-this.dragStartPoint.x);
var absDeltaY = Math.abs(dragEndPoint.y-this.dragStartPoint.y);
// If absDeltaX is not trivially small
// and absDeltaY is no larger than a fraction of absDeltaX.
if (absDeltaX >= 50 && absDeltaY <= 0.4 * absDeltaX) {
if (endItemIndex > intEndItemIndex) {
if (intEndItemIndex < this.galleryObject.itemCount - 1) {
intEndItemIndex++;
}
} else if (endItemIndex < intEndItemIndex) {
if (intEndItemIndex > 0) {
intEndItemIndex--;
}
}
}
}
}
debugLog("onTouchEnd: deltaT:"+deltaT+";deltaX="+(dragEndPoint.x-this.dragStartPoint.x)+";deltaY="+(dragEndPoint.y-this.dragStartPoint.y)+";endItemIndex="+endItemIndex+";intEndItemIndex="+intEndItemIndex);
this.galleryObject.changeCurrentItemIndex(intEndItemIndex, true);
this.dragStartPoint = undefined;
this.dragStartTime = undefined;
this.dragStartX = undefined;
this.dragStartItemIndex = undefined;
}
catch (error) {
debugLogError(error);
}
}
onTouchCancel(event) {
try {
this.onTouchEvent(event);
}
catch (error) {
debugLogError(error);
}
}
}
class Gallery {
createImageRollElement() {
this.viewfinderElement = this.galleryElement.getElementsByClassName("gallery-image-viewfinder")[0];
this.imageRollElement = this.viewfinderElement.getElementsByClassName("gallery-image-roll")[0];
var imageFrameElementArray = Array.prototype.slice.call(this.viewfinderElement.getElementsByClassName("gallery-image-cropper"));
this.itemCount = imageFrameElementArray.length;
}
completeItemCaptionElements() {
//this.itemCaptionRolodexElement = this.galleryElement.getElementsByClassName("gallery-item-caption-rolodex")[0];
//this.itemCaptionRolodexElement.onclick = stopEventPropagation;
}
addSelectionDots() {
this.dotContainerElement = this.galleryElement.getElementsByClassName("gallery-dot-container")[0];
this.innerDotContainerElement = this.dotContainerElement.getElementsByClassName("gallery-dot-inner-container")[0];
if (this.innerDotContainerElement.getBoundingClientRect().width < this.dotContainerElement.getBoundingClientRect().width) {
var dotExtenderElementArray = Array.prototype.slice.call(this.innerDotContainerElement.getElementsByClassName("gallery-dot-extender"));
for (var itemIndex = 0; itemIndex < this.itemCount; itemIndex++) {
var dotExtenderElement = dotExtenderElementArray[itemIndex];
dotExtenderElement.onclick = this.selectFrame.bind(this, itemIndex);
var captionID = this.getCaptionElementIDForIndex(itemIndex);
var dotElement = dotExtenderElement.getElementsByTagName("span")[0];
dotElement.setAttribute("aria-describedby", captionID);
}
} else {
this.innerDotContainerElement.style.display = 'none';
}
}
completeTree() {
this.createImageRollElement();
this.completeItemCaptionElements();
if (!this.isFullscreen()) {
this.addSelectionDots();
}
}
addWindowEventListeners() {
window.addEventListener("pageshow", this.onPageShow.bind(this));
window.addEventListener("pagehide", this.onPageHide.bind(this));
}
createObservers() {
this.currentItemObserverArray = [];
if (this.galleryElement.getElementsByClassName("gallery-caption").length > 1) {
this.currentItemObserverArray.push(new GalleryCaptionRollManager(this));
}
if (!this.isFullscreen()) {
this.currentItemObserverArray.push(new GalleryDotManager(this));
if (useMouselessButtons()) {
this.currentItemObserverArray.push(new GalleryMouselessButtonsManager(this));
}
}
}
startUp() {
this.currentItemIndex = -1;
var newItemIndex = parseInt(this.galleryElement.getAttribute("data-current-item-index"));
this.changeCurrentItemIndex(newItemIndex, false);
}
constructor (galleryElement) {
this.galleryElement = galleryElement;
this.completeTree();
this.viewfinderManager = new GalleryViewfinderManager(this);
this.addWindowEventListeners();
this.createObservers();
this.imageRollManager = new GalleryImageRollManager(this);
if (!useMouselessButtons()) {
this.touchManager = new TouchManager(this);
}
debugLog("Creating gallery " + galleryElement.id);
this.startUp();
}
isFullscreen() {
return false;
}
changeCurrentItemIndex(newItemIndex, animate) {
if (this.currentItemIndex != newItemIndex) {
if (Math.abs(newItemIndex - this.currentItemIndex) > 1.0) {
// Animation is supported only between neighbouring frames.
animate = false;
}
this.imageRollManager.onCurrentItemChange(this.currentItemIndex, newItemIndex, animate);
var intCurrentItemIndex = Math.round(this.currentItemIndex);
var intNewItemIndex = Math.round(newItemIndex);
if (intNewItemIndex != intCurrentItemIndex) {
this.onCurrentItemChange(intCurrentItemIndex, intNewItemIndex, animate);
this.galleryElement.setAttribute("data-current-item-index", intNewItemIndex);
}
this.currentItemIndex = newItemIndex;
this.updateImagesAXVisibility();
}
}
updateImagesAXVisibility() {
var currentIndex = this.currentItemIndex;
var images = Array.prototype.slice.call(document.getElementsByClassName("gallery-full-image"));
images.forEach(function(image, index) {
image.setAttribute("aria-hidden", index == currentIndex ? "false" : "true");
});
}
goToPrevFrame() {
var currentItemIndex = this.currentItemIndex;
this.changeCurrentItemIndex(currentItemIndex-1, true);
}
goToNextFrame() {
var currentItemIndex = this.currentItemIndex;
this.changeCurrentItemIndex(currentItemIndex+1, true);
}
selectFrame(newItemIndex) {
this.changeCurrentItemIndex(newItemIndex, true);
}
maximizeFrame() {
}
onCurrentItemChange(oldItemIndex, newItemIndex, animate) {
this.currentItemObserverArray.forEach(function(observer) {
observer.onCurrentItemChange(oldItemIndex, newItemIndex, animate);
});
this.viewfinderManager.onCurrentItemChange(oldItemIndex, newItemIndex);
}
onPageShow() {
this.viewfinderManager.onPageShow();
}
onPageHide() {
this.viewfinderManager.onPageHide();
}
getCaptionElementIDForIndex(index) {
var captionIndex = index+1;
return this.galleryElement.id + "-caption-" + captionIndex;
}
static setButtonVisibility(buttonElement, visible) {
if (buttonElement) {
buttonElement.style.opacity = visible ? 1.0 : 0.0;
}
}
}
class RegularGallery extends Gallery {
static setDisplayToNoneForElementsOfClass(className) {
var elementArray = Array.prototype.slice.call(document.getElementsByClassName(className));
elementArray.forEach(
function(element) {
element.style.display = 'none';
});
}
static loadGalleries() {
this.setDisplayToNoneForElementsOfClass("gallery-fallback");
this.setDisplayToNoneForElementsOfClass("gallery-fallback-separator");
var galleryElementArray = Array.prototype.slice.call(document.getElementsByClassName("gallery"));
galleryElementArray.forEach(function(galleryElement) {
galleryElement.style.display = '';
new RegularGallery(galleryElement);
});
}
}
function Body_onLoad() {
RegularGallery.loadGalleries();
}
@JayPanoz
Copy link
Author

JayPanoz commented Apr 5, 2018

So can confirm JS file is for interactive image galleries on iOS (slider). Will fail on Android/Desktop. Sniffing ADE and Kobo app on iOS is for disabling touch drag, and replacing it with buttons to navigate the gallery.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment