// Copyright (c) 2010-2018 Quadralay Corporation. All rights reserved.
//
// ePublisher 2018.1
//
// Validated with JSLint
//
/*jslint maxerr: 50, for: true, this: true */
/*global window */
/*global MutationObserver */
/*global DocumentTouch */
// Message
//
var Message = {};
Message.Determine_Origin = function (param_window) {
'use strict';
var result, start_prefix_minimum, start_index, end_index;
if (param_window.location.protocol === 'file:') {
result = '*';
} else {
// Ensure start index starts after protocol and host info
//
start_prefix_minimum = param_window.location.protocol + '//' + param_window.location.host;
start_index = start_prefix_minimum.length;
end_index = param_window.location.href.indexOf(param_window.location.pathname, start_index);
result = param_window.location.href.substring(0, end_index);
}
return result;
};
Message.Listen = function (param_window, param_function) {
'use strict';
var origin, middleware;
// Use appropriate browser method
//
if ((param_window.postMessage !== undefined) && (param_window.JSON !== undefined)) {
// Wrap function to ensure security
//
origin = Message.Determine_Origin(param_window);
middleware = function (param_event) {
var accept, event, key;
// Ensure origin matches
//
accept = (param_event.origin === origin);
if (!accept) {
if (param_window.location.protocol === 'file:') {
accept = (param_event.origin.indexOf('file:') === 0);
if (!accept) {
accept = (param_event.origin === 'null');
}
}
}
// Invoke function if message acceptable
//
if (accept) {
// Copy existing event
//
event = {};
for (key in param_event) {
if (param_event[key] !== undefined) {
event[key] = param_event[key];
}
}
// Expand JSON data
//
try {
event.data = param_window.JSON.parse(param_event.data);
param_function(event);
} catch (ignore) {
// Apparently, this message wasn't meant for us
//
}
}
};
if (param_window.addEventListener !== undefined) {
// Via postMessage
//
param_window.addEventListener('message', middleware, false);
} else if (param_window.attachEvent !== undefined) {
// Via postMessage
//
param_window.attachEvent('onmessage', middleware, false);
}
} else {
// Direct send
//
if (!param_window.POSTMESSAGE_message) {
param_window.POSTMESSAGE_message = param_function;
}
}
};
Message.Post = function (param_to_window, param_data, param_from_window) {
'use strict';
var data, origin, event;
// Use appropriate browser method
//
if ((param_from_window.postMessage !== undefined) && (param_from_window.JSON !== undefined)) {
// Via postMessage
//
data = param_from_window.JSON.stringify(param_data);
origin = Message.Determine_Origin(param_from_window);
param_to_window.postMessage(data, origin);
} else {
// Direct send
//
if (param_to_window.POSTMESSAGE_message) {
event = { 'origin': origin, 'source': param_from_window, 'data': param_data };
param_from_window.setTimeout(function () {
param_to_window.POSTMESSAGE_message(event);
}, 1);
}
}
};
// ExecuteWithDelay
//
function ExecuteWithDelay(param_window, param_callback, param_delay) {
'use strict';
var this_executewithdelay;
this_executewithdelay = this;
this.timeout = null;
this.Execute = function () {
// Pending invocation?
//
if (this_executewithdelay.timeout !== null) {
// Reset timer and prepare to start over
//
param_window.clearTimeout(this_executewithdelay.timeout);
}
// Start timer
//
this_executewithdelay.timeout = param_window.setTimeout(this_executewithdelay.Invoke, param_delay);
};
this.Invoke = function () {
try {
// Clear timeout tracker and invoke callback
//
this_executewithdelay.timeout = null;
param_callback();
} catch (ignore) {
// Ignore callback exceptions
//
}
};
}
// Tracker
//
function Tracker(param_window, param_element, param_callback) {
'use strict';
var this_tracker;
this.element = param_element;
this.snapshot = param_element.innerHTML;
this.snapshot_growing = false;
this_tracker = this;
this.Execute = function () {
var snapshot;
try {
// Snapshot changed?
//
snapshot = this_tracker.element.innerHTML;
if (snapshot !== this_tracker.snapshot) {
this_tracker.snapshot = snapshot;
this_tracker.snapshot_growing = true;
} else {
// Previously growing?
//
if (this_tracker.snapshot_growing) {
this_tracker.snapshot_growing = false;
// Invoke callback
//
try {
param_callback();
} catch (ignore) {
// Ignore callback exceptions
//
}
}
}
// Continue
//
param_window.setTimeout(function () {
this_tracker.Execute();
}, 200);
} catch (ignore) {
// Element must no longer be valid
//
}
};
}
// Browser
//
var Browser = {};
Browser.ScrollingSupported = function () {
'use strict';
var result, safari_match, mobile_match, version_match;
// Initialize return value
//
result = true;
// Older mobile browsers, such as Safari under iOS 5 and earlier
// do not support scrolling of nested overflowed divs or iframes
//
// Mozilla/5.0 (iPhone; CPU iPhone OS 6_1_3 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10B329 Safari/8536.25
//
safari_match = window.navigator.userAgent.match(/ Safari\//);
mobile_match = window.navigator.userAgent.match(/ Mobile\//);
version_match = window.navigator.userAgent.match(/ Version\/(\d+)\.(\d+) /);
if ((safari_match !== null) && (mobile_match !== null) && (version_match !== null) && (parseInt(version_match[1], 10) < 6)) {
result = false;
}
return result;
};
Browser.GetAJAX = function (param_window) {
'use strict';
var result;
try {
// Firefox, Opera, Safari, Chrome
//
result = new param_window.XMLHttpRequest();
} catch (e1) {
// IE
//
try {
result = new param_window.ActiveXObject('Msxml2.XMLHTTP');
} catch (e2) {
result = new param_window.ActiveXObject('Microsoft.XMLHTTP');
}
}
return result;
};
Browser.ContainsClass = function (param_className, param_class) {
'use strict';
var result, index;
result = false;
if ((param_className !== undefined) && (param_className.length > 0) && (param_class.length > 0)) {
// Exact match?
//
if (param_class === param_className) {
result = true;
} else {
// Contains?
//
index = param_className.indexOf(param_class);
if (index >= 0) {
if (index === 0) {
result = (param_className.charAt(param_class.length) === ' ');
} else if (index === (param_className.length - param_class.length)) {
result = (param_className.charAt(index - 1) === ' ');
} else {
result = ((param_className.charAt(index - 1) === ' ') && (param_className.charAt(index + param_class.length) === ' '));
}
}
}
}
return result;
};
Browser.AddClass = function (param_className, param_class) {
'use strict';
var result;
result = param_className;
if (!Browser.ContainsClass(param_className, param_class)) {
result = param_className + ' ' + param_class;
}
return result;
};
Browser.RemoveClass = function (param_className, param_class) {
'use strict';
var result, index;
result = param_className;
if ((param_className !== undefined) && (param_className.length > 0) && (param_class.length > 0)) {
// Exact match?
//
if (param_class === param_className) {
result = '';
} else {
// Contains?
//
index = param_className.indexOf(param_class);
if (index >= 0) {
if (index === 0) {
if (param_className.charAt(param_class.length) === ' ') {
result = param_className.substring(param_class.length + 1);
}
} else if (index === (param_className.length - param_class.length)) {
if (param_className.charAt(index - 1) === ' ') {
result = param_className.substring(0, index - 1);
}
} else {
if ((param_className.charAt(index - 1) === ' ') && (param_className.charAt(index + param_class.length) === ' ')) {
result = param_className.substring(0, index - 1) + param_className.substring(index + param_class.length);
}
}
}
}
}
return result;
};
Browser.ReplaceClass = function (param_className, param_existing_class, param_new_class) {
'use strict';
var result;
result = Browser.RemoveClass(param_className, param_existing_class);
result = Browser.AddClass(result, param_new_class);
return result;
};
Browser.SameDocument = function (param_url_1, param_url_2) {
'use strict';
var result, current_path, desired_path;
result = false;
if (param_url_1 === param_url_2) {
// Quick and dirty check
//
result = true;
} else {
// Try more in-depth test
//
current_path = param_url_1;
desired_path = param_url_2;
// Decompose hrefs
//
if (current_path.indexOf('#') !== -1) {
current_path = current_path.substring(0, current_path.indexOf('#'));
}
if (desired_path.indexOf('#') !== -1) {
desired_path = desired_path.substring(0, desired_path.indexOf('#'));
}
// Same document?
//
if ((desired_path === current_path) || (decodeURIComponent(desired_path) === current_path) || (desired_path === decodeURIComponent(current_path)) || (decodeURIComponent(desired_path) === decodeURIComponent(current_path))) {
result = true;
}
}
return result;
};
Browser.SameHierarchy = function (param_base_url, param_test_url) {
'use strict';
var result, decoded_base_url, decoded_test_url;
result = false;
if (param_test_url.indexOf(param_base_url) === 0) {
if (param_base_url.indexOf(".html", param_base_url.length - 5) == -1) {
if (param_base_url[param_base_url.length - 1] != '/') {
if (param_test_url.indexOf(param_base_url + '/') === 0)
result = true;
}
else { result = true; }
}
else {
result = true;
}
} else {
decoded_base_url = decodeURIComponent(param_base_url);
if (param_test_url.indexOf(decoded_base_url) === 0) {
result = true;
} else {
decoded_test_url = decodeURIComponent(param_test_url);
if (decoded_test_url.indexOf(param_base_url) === 0) {
result = true;
} else {
if (decoded_test_url.indexOf(decoded_base_url) === 0) {
result = true;
}
}
}
}
return result;
};
Browser.RelativePath = function (param_base_url, param_test_url) {
'use strict';
var result, decoded_base_url, decoded_test_url;
result = '';
if (param_test_url.indexOf(param_base_url) === 0) {
result = param_test_url.substring(param_base_url.length);
} else {
decoded_base_url = decodeURIComponent(param_base_url);
if (param_test_url.indexOf(decoded_base_url) === 0) {
result = param_test_url.substring(decoded_base_url.length);
} else {
decoded_test_url = decodeURIComponent(param_test_url);
if (decoded_test_url.indexOf(param_base_url) === 0) {
result = decoded_test_url.substring(param_base_url.length);
} else {
if (decoded_test_url.indexOf(decoded_base_url) === 0) {
result = decoded_test_url.substring(decoded_base_url.length);
}
}
}
}
return result;
};
Browser.ResolveURL = function (param_reference_page_url, param_url) {
'use strict';
var result, url_parts, resolved_url_parts, url_component;
// Absolute URL?
//
if (param_url.indexOf('//') >= 0) {
// Absolute URL
//
result = param_url;
} else {
// Relative URL
//
// Expand URL into components
//
if (param_url.indexOf('/') >= 0) {
url_parts = param_url.split('/');
} else {
url_parts = [param_url];
}
resolved_url_parts = param_reference_page_url.split('/');
resolved_url_parts.length = resolved_url_parts.length - 1;
// Process URL components
//
while (url_parts.length > 0) {
url_component = url_parts.shift();
if ((url_component !== '') && (url_component !== '.')) {
if (url_component === '..') {
resolved_url_parts.pop();
} else {
resolved_url_parts.push(url_component);
}
}
}
// Build resolved URL
//
result = resolved_url_parts.join('/');
}
return result;
};
Browser.GetDocument = function (param_iframe_or_window) {
'use strict';
var result;
try {
//