// Copyright (c) 2010-2019 Quadralay Corporation. All rights reserved. // // ePublisher 2019.2 // // 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); }); } } }; // 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.CalcSupported = function () { 'use strict'; var result, prop_value, el; prop_value = 'width: calc(10px);'; el = document.createElement('div'); el.style.cssText = prop_value; result = !!el.style.length; 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.EncodeURIComponentIfNotEncoded = function (param_uri) { var uri; uri = param_uri || ''; uri = Browser.IsURIComponentEncoded(uri) ? uri : encodeURIComponent(uri); return uri; }; Browser.IsURIComponentEncoded = function (param_uri) { var uri, isEncoded; uri = param_uri || ''; isEncoded = uri !== decodeURIComponent(uri); return isEncoded; }; 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 { //