// Copyright (c) 2010-2016 Quadralay Corporation. All rights reserved. // // ePublisher 2016.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) { 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 { // '; }; FAJAX.OnLoad = function (param_document) { 'use strict'; var iframe_container; iframe_container = param_document.getElementById('fajax_iframe_container'); iframe_container.fajax.HandleLoad(); }; FAJAX.HandleLoad = function () { 'use strict'; var iframe, iframe_document, data; // Access iframe's content directly // try { iframe = this.iframe_container.getElementsByTagName('iframe')[0]; iframe_document = Browser.GetDocument(iframe); data = iframe_document.body.innerHTML; } catch (ignore) { // No luck! // } // Try session storage // if (data === null || data === undefined || data === '') { if (this.window.Storage !== undefined) { data = this.window.sessionStorage['WebWorks_Connect_Data']; delete this.window.sessionStorage['WebWorks_Connect_Data']; } } this.window.document.body.removeChild(this.iframe_container); if (data !== null && data !== undefined) { this.readyState = 4; this.status = 200; this.responseText = data; this.onreadystatechange(); } else { this.readyState = 4; this.status = 404; this.responseText = ''; this.onreadystatechange(); } }; FAJAX.Object = function (param_window) { 'use strict'; this.window = param_window; this.readyState = 1; this.status = 404; this.responseText = ''; this.iframe = undefined; this.url = ''; this.open = FAJAX.Open; this.send = FAJAX.Send; this.HandleLoad = FAJAX.HandleLoad; }; // Parcels // var Parcels = {}; Parcels.KnownParcelURL = function (param_parcel_prefixes, param_url) { 'use strict'; var result, parcel_base_url; result = false; for (parcel_base_url in param_parcel_prefixes) { if (typeof param_parcel_prefixes[parcel_base_url] === 'boolean') { if (Browser.SameHierarchy(parcel_base_url, param_url)) { result = true; break; } } } return result; }; Parcels.KnownParcelBaggageURL = function (param_parcel_prefixes, param_url) { 'use strict'; var result, parcel_base_url, baggage_url; result = false; for (parcel_base_url in param_parcel_prefixes) { if (typeof param_parcel_prefixes[parcel_base_url] === 'boolean') { if (Browser.SameHierarchy(parcel_base_url, param_url)) { baggage_url = parcel_base_url + '/baggage/'; result = Browser.SameHierarchy(baggage_url, param_url); break; } } } return result; }; // Progress // function Progress_Reset() { 'use strict'; var progress_bar_div; // Reset progress // this.progress = 0; // Indicate indeterminate progress // progress_bar_div = Browser.FirstChildElementContainingClass(this.progress_div, 'ww_skin_progress_bar'); if (progress_bar_div !== null) { progress_bar_div.className = Browser.AddClass(progress_bar_div.className, 'ww_skin_progress_indeterminate'); // Reset segments // Browser.ApplyToChildElementsContainingClass(progress_bar_div, 'ww_skin_progress_segment', function (param_element) { param_element.className = Browser.ReplaceClass(param_element.className, 'ww_skin_progress_segment_complete', 'ww_skin_progress_segment_pending'); }); } } function Progress_Update(param_progress) { 'use strict'; var progress_goal, progress_bar_div, started, this_reference, current_progress; // Validate progress goal // progress_goal = param_progress; if (progress_goal > 100) { progress_goal = 100; } else if (progress_goal < 0) { progress_goal = 0; } // Update necessary? // if (progress_goal > this.progress) { // Locate progress bar // progress_bar_div = Browser.FirstChildElementContainingClass(this.progress_div, 'ww_skin_progress_bar'); if (progress_bar_div !== null) { // Started progress? // started = (this.progress === 0); // Update progress // while ((this.progress + 10) <= progress_goal) { this.progress += 10; } if (this.progress > 0) { // Started progress updates? // if (started) { // Remove indeterminate progress indicator // progress_bar_div.className = Browser.RemoveClass(progress_bar_div.className, 'ww_skin_progress_indeterminate'); } // Mark progress // current_progress = 0; this_reference = this; Browser.ApplyToChildElementsContainingClass(progress_bar_div, 'ww_skin_progress_segment', function (param_element) { // Count segments // current_progress += 10; if (current_progress <= this_reference.progress) { param_element.className = Browser.ReplaceClass(param_element.className, 'ww_skin_progress_segment_pending', 'ww_skin_progress_segment_complete'); } }); } } } } function Progress_Complete() { 'use strict'; this.Hide(); } function Progress_Done() { 'use strict'; return (this.progress === 100); } function Progress_Show() { 'use strict'; this.progress_div.style.display = 'block'; } function Progress_Hide() { 'use strict'; this.progress_div.style.display = 'none'; } function Progress_Object(param_progress_div) { 'use strict'; this.progress = 0; this.progress_div = param_progress_div; this.Reset = Progress_Reset; this.Update = Progress_Update; this.Complete = Progress_Complete; this.Done = Progress_Done; this.Show = Progress_Show; this.Hide = Progress_Hide; }