(function (w) {
var DEBUG = false;
/**
* Assert function used by API calls
* @param {boolean} condition A true or false condition
* @param {String} errorMessage The error message to display on assert failure
* @return {boolean} The same true or false condition
* @author Bruno Sabot
* @private
*/
function _assert(condition, errorMessage) {
if (condition === false && DEBUG === true) {
console.log(errorMessage);
}
return condition;
}
/**
* Assert function used by API calls to check integer numbers
* @param {mixed} value The value to test as an integer
* @param {String} errorMessage The error message to display on assert failure
* @return {boolean} A true or false condition
* @author Bruno Sabot
* @private
*/
function _assertInteger(value, errorMessage) {
return _assert(value % 1 === 0, errorMessage);
}
/**
* Assert function used by API calls to check string values
* @param {mixed} value The value to test as a string
* @param {String} errorMessage The error message to display on assert failure
* @return {boolean} A true or false condition
* @author Bruno Sabot
* @private
*/
function _assertString(value, errorMessage) {
return _assert(typeof (value) === 'string', errorMessage);
}
/**
* Assert function used by API calls to check if string values are valid json
* @param {mixed} value The value to test as a string
* @param {String} errorMessage The error message to display on assert failure
* @return {boolean} A true or false condition
* @author Bruno Sabot
* @private
*/
function _assertJson(value, errorMessage) {
if (_assert(typeof (value) === 'string', errorMessage)) {
var result = true;
try {
var json = JSON.parse(value);
} catch (e) {
result = false;
}
return _assert(result, errorMessage);
} else {
return false;
}
}
/**
* Assert function used by API calls to check if string values are valid json
* @param {mixed} value The value to find into allowed values
* @param {Array} dataSet Array of allowed values
* @param {String} errorMessage The error message to display on assert failure
* @return {boolean} A true or false condition
* @author Alessandro Cipolletti
* @private
*/
function _assertOneOf(value, dataSet, errorMessage) {
return _assert(dataSet.indexOf(value) >= 0, errorMessage);
}
/**
* Transform the rest query string to an argument list
* @param {String} data The rest query string
* @author Bruno Sabot
* @private
*/
function _getArguments(data) {
data = data.split('/');
var dataOut = [];
for (var i = 1; i < data.length; i += 2) {
dataOut[data[i]] = data[i + 1];
}
return dataOut;
}
/**
* Get the method name from the rest query string
* @param {String} data The rest query string
* @author Bruno Sabot
* @private
*/
function _getMethod(data) {
return data.split('/')[0];
}
/**
* Reader V3 web API
* @namespace
*/
w.API = {
/**
* Disable the debug mode to hide error logs
* @return {boolean} Always true
* @author Bruno Sabot
* @example
* // Disable the debug mode
* elementWindow.postMessage("debugDisable", "*");
*/
debugDisable: function () {
DEBUG = false;
return true;
},
/**
* Enable the debug mode to see error logs
* @return {boolean} Always true
* @author Bruno Sabot
* @example
* // Enable the debug mode
* elementWindow.postMessage("debugEnable", "*");
*/
debugEnable: function () {
DEBUG = true;
return true;
},
/**
* Get the current debug state
* @return {boolean} The current debug state
* @author Bruno Sabot
* @example
* // Get the current debug state
* window.addEventListener("message", function (event) {
* if (event.data.method === "debugGetState") {
* console.log("debug state is : " + event.data.result);
* }
* }, false);
* elementWindow.postMessage("debugGetState", "*");
*/
debugGetState: function () {
return DEBUG;
},
/**
* Toggle the debug mode state
* @return {boolean} Always true
* @author Bruno Sabot
* @example
* // Toggle the debug mode
* elementWindow.postMessage("debugToggle", "*");
*/
debugToggle: function () {
DEBUG = !DEBUG;
return true;
},
/**
* Display the device type
* @return {string} Device type
* @author Ronny Tite
* @since 3.18
* @example
* // Display the device type (desktop, tablet, phablet, phone, unknown)
* window.addEventListener("message", function (event) {
* if (event.data.method === "deviceType") {
* console.log("This device is a " + event.data.result);
* }
* }, false);
* elementWindow.postMessage("deviceType", "*");
*/
deviceType: function () {
return w.Param.userAgent.device.type;
},
/**
* Close the lightbox
* @author Ronny Tite
* @since 3.18
* @example
* // Close the menu
* elementWindow.postMessage("lightboxClose", "*");
*/
lightboxClose: function () {
w.Class.LightboxManager.closeAll();
},
/**
* Load a lightbox with an url in an iFrame
* Available arguments:
* * title:
* - the title of the lightbox, if title is not defined , it will be a blank title.
* * url: (Mandatory)
* - The url of the iFrame we want to load , this url need to be encoded;
* * header:
* - Define if the header is visible or not
* - By default, set to "true"
* - Set header to false to hide the header
* @param {Object} args The object list
* @return {boolean} return true on success and false on failure
* @since 3.18
* @author Ronny Tite
* @example
* // Define the arguments
* var lightboxTitle = "test";
* var lightboxUrl = encodeURIComponent('http://www.webpublication.fr');
* var header = false;
* // Open the lightbox without title
* elementWindow.postMessage("lightboxOpen/url/" + lightboxUrl,"*")
* // Open the lightbox with a title with header
* elementWindow.postMessage("lightboxOpen/title/" + lightboxTitle + "/url/" + lightboxUrl,"*")
* // Open the lightbox without header
* elementWindow.postMessage("lightboxOpen/header/false/url/" + lightboxUrl,"*")
*/
lightboxOpen: function (args) {
var popup = new w.Class.LightboxManager.getLightbox({
"id": "iframe",
"title": args.title,
"header": (args.header === "false" ? false : true),
"url": w.Main.xmlManager.resolve(decodeURIComponent(args.url)),
"onLoaded": function (popup) {
var content = popup.template.querySelector('.lightbox__content');
var iframe = document.createElement('iframe');
iframe.src = popup.url;
iframe.allowFullscreen = true;
iframe.frameBorder = "0";
iframe.style.width = "100%";
iframe.style.height = "100%";
content.appendChild(iframe);
}
});
},
/**
* Close the menu
* @return {boolean} Always true
* @author Alessandro Cipolletti
* @example
* // Close the menu
* elementWindow.postMessage("menuClose", "*");
*/
menuClose: function () {
return w.Main.menuManager.hideMenu();
},
/**
* Open the menu
* @return {boolean} Always true
* @author Alessandro Cipolletti
* @example
* // Open the menu
* elementWindow.postMessage("menuOpen", "*");
*/
menuOpen: function () {
return w.Main.menuManager.showMenu();
},
/**
* Toggle the menu state
* @return {boolean} Always true
* @author Alessandro Cipolletti
* @example
* // Toggle the menu state
* elementWindow.postMessage("menuToggle", "*");
*/
menuToggle: function () {
return w.Main.menuManager.toggleMenu();
},
/**
* Get the amount of pages in the publication
* @return {integer} The amount of pages in the publication
* @author Bruno Sabot
* @example
* // Get the current debug state
* window.addEventListener("message", function (event) {
* if (event.data.method === "pageCount") {
* console.log("There is " + event.data.result + " pages in the publication");
* }
* }, false);
* elementWindow.postMessage("pageCount", "*");
*/
pageCount: function () {
return w.Utils.prodTools.getPageLength();
},
/**
* Load a specific page on the publication
*
* The number argument is always used before the name argument
*
* Available arguments:
* * number:
* - load a page number, starting from 1 to the latest page.
* - If the number is higher than the page size, it goes to the latest
* - If the number is lower than one, it does nothing
* * name:
* - The name can be one of next, previous, first or last and goes to the associated page
* @param {Object} args The object list
* @return {boolean} return true on success and false on failure
* @author Bruno Sabot
* @example
* // Go to page 10
* elementWindow.postMessage("pageLoad/number/10", "*");
* // Go to the next page
* elementWindow.postMessage("pageLoad/name/next", "*");
* // Go to the previous page
* elementWindow.postMessage("pageLoad/name/previous", "*");
* // Go to the first page
* elementWindow.postMessage("pageLoad/name/first", "*");
* // Go to the last page
* elementWindow.postMessage("pageLoad/name/last", "*");
*/
pageLoad: function (args) {
// Handle the number argument
if (args.number) {
if (_assertInteger(args.number, "[pageLoad] The number argument must be an integer")) {
if (w.Param.newViewerVersion) {
w.Main.viewerManager.goToPage(args.number);
} else {
w.Main.controlManager.goToPage(args.number);
}
return true;
}
return false;
}
// Handle the name argument
if (args.name) {
if (args.name === 'next') {
if (w.Param.newViewerVersion) {
w.Main.viewerManager.scrollFrame("next");
} else {
w.Main.controlManager.nextPage();
}
} else if (args.name === 'previous' || args.name === 'prev') {
if (w.Param.newViewerVersion) {
w.Main.viewerManager.scrollFrame("prev");
} else {
w.Main.controlManager.prevPage();
}
} else if (args.name === 'first') {
if (w.Param.newViewerVersion) {
w.Main.viewerManager.goToPage(1);
} else {
w.Main.controlManager.goToPage(1);
}
} else if (args.name === 'last') {
if (w.Param.newViewerVersion) {
w.Main.viewerManager.goToPage(w.Utils.prodTools.getPageLength());
} else {
w.Main.controlManager.goToPage(w.Utils.prodTools.getPageLength());
}
} else {
return false;
}
return true;
}
_assert(false, "[pageLoad] The argument is missing or incorrect");
return false;
},
/**
* Send a json string to all iframes link with a postMessage
* Available arguments:
* * mode:
* - "all" send message to all iframe, also the sender
* - "others" send message to all iframe except the sender
* * data:
* - a valid json string
* @param {Object} args The object list
* @return {boolean} return true on success and false on failure
* @author Alessandro Cipolletti
* @since 3.18
* @example
* // (into an iframe link) send a json to all others iframe's links
* window.parent.postMessage('broadcast/mode/others/data/{"hello": "world"}', "*");
* // to see received json message into the target iframe
* window.addEventListener("message", function (e) {
* console.log(e.data);
* });
*/
broadcast: function (args) {
if (
_assertOneOf(args.mode, ["all", "others"], "Mode must be 'all' or 'others'") &&
_assertJson(args.data, "Data must be a valid json string")
) {
var exceptWindow = (args.mode === "others" ? this : false);
var data = JSON.parse(args.data);
data.type = "broadcast";
if (w.Param.newViewerVersion) {
w.Main.linksManagerNew.linksBroadcast(args.mode, data, exceptWindow);
} else {
w.Main.linksManager.linksBroadcast(args.mode, data, exceptWindow);
}
return true;
} else {
return false;
}
},
/**
* Simulates a click on a specific link
* For any page, also not currently displayed
* @author Alessandro Cipolletti
* @example
* // Click on first link of page 10
* elementWindow.postMessage("linkClick/page/10/index/0", "*");
*/
linkClick: function () {
var maxPage = w.Main.xmlManager.get("contents").config.pages_nr;
return function (args) {
if (
_assertInteger(args.page, "Page number must be an integer") &&
_assertInteger(args.index, "Link index must be an integer")
) {
if (args.page > 0 && args.page <= maxPage && args.index >= 0) {
w.Main.linksManagerNew.linkClick(args.page, {
index: args.index
});
}
} else {
return false;
}
};
}(),
/**
* Open the startup panel
* @return {boolean} return true on success and false on failure
* @author Bruno Sabot
* @since 3.18
* @example
* // Open the startup panel
* elementWindow.postMessage("welcomepageOpen", "*");
*/
welcomepageOpen: function () {
var panelUrl = w.Main.startupManager.get('startup.welcomepage.url');
if (panelUrl) {
w.Class.LightboxManager.getLightbox({
"id": "startupPanel",
"url": w.Main.xmlManager.resolve(panelUrl),
"header": false
});
return true;
}
return false;
},
/**
* Download the PDF
* @return {boolean} return true on success and false on failure
* @author Bruno Sabot
* @example
* // Download the PDF
* elementWindow.postMessage("pdfDownload", "*");
*/
pdfDownload: function () {
window.location.href = './publication/contents/pdfweb.pdf';
},
/**
* Get the pdf url
* @return {String} return the global url to publication's pdf
* @author Alessandro Cipolletti
* @example
* // if you want to open the pdf of the publication contained inside an iframe
* window.addEventListener("message", function (e) {
* if (e.data.method === "pdfGetUrl") {
* location.href = e.data.result;
* }
* }, false);
* iframeElement.contentWindow.postMessage("pdfGetUrl", "*");
*/
pdfGetUrl: function (args) {
return location.pathname + "publication/contents/pdfweb.pdf";
},
/**
* Share on social page
* @return {boolean} return true on success and false on failure
* @author Ronny Tite
* @example
* // Share on tacebook page
* elementWindow.postMessage("share/network/facebook", "*")
* // Share on Twitter page
* elementWindow.postMessage("share/network/twitter", "*")
* // Share on Pinterest page
* elementWindow.postMessage("share/network/pinterest", "*")
* // Share on Tumblr page
* elementWindow.postMessage("share/network/tumblr", "*")
* // Share on Google + page
* elementWindow.postMessage("share/network/googleplus", "*")
* // Share on Linkedin page
* elementWindow.postMessage("share/network/linkedin", "*")
*
*/
share: (function () {
var _socials = ["linkedin", "googleplus", "tumblr", "pinterest", "twitter", "facebook", "mail"];
var el;
return function (args) {
if (typeof (args.network) === "undefined" && _socials.indexOf(args.network) < 0) {
return false;
}
if (args.network === "mail") {
el = w.Main.menuService.get("email_btn");
} else {
el = w.Main.menuService.get(args.network + "_btn");
}
if (el) {
el.onload();
el.onclick();
}
};
})(),
/**
* Open the search panel
* @return {boolean} return true on success and false on failure
* @author Bruno Sabot
* @example
* // Open the search panel
* elementWindow.postMessage("searchOpen", "*");
*/
searchOpen: function () {
var searchButton = w.Main.menuService.get("search_btn");
searchButton.onload();
searchButton.onclick();
return true;
},
/**
* Open the thumbnails page
* @return {boolean} return true on success and false on failure
* @author Ronny Tite
* @example
* // Open the thumbnails page
* elementWindow.postMessage("thumbnailOpen", "*");
*/
thumbnailOpen: function () {
var thumbButton = w.Main.menuService.get("thumbnails_btn");
thumbButton.onload();
thumbButton.onclick();
return true;
},
/**
* Get the viewport scale value used in the publication that allows the use of retina images
* @return {float} The publication viewport scale
* @author Bruno Sabot
* @example
* // Get the viewport scale
* window.addEventListener("message", function (event) {
* if (event.data.method === "viewportGetScale") {
* console.log("The viewport scale value of the publication is " + event.data.result);
* }
* }, false);
* elementWindow.postMessage("viewportGetScale", "*");
*/
viewportGetScale: function () {
return w.Starter.defaultViewportScale;
}
};
// Listen message events
window.addEventListener("message", function (event) {
if (_assertString(event.data)) {
var method = _getMethod(event.data);
var args = _getArguments(event.data);
if (w.API.hasOwnProperty(method)) {
var result = w.API[method].call(event.source, args);
// On same window : no call
if (event.source) {
event.source.postMessage({
"method": method,
"arguments": args,
"result": result,
"queryId": args.queryId
}, event.origin);
}
}
}
}, false);
})(webpublicationNamespace);