/* Copyright(c) 2013-2018 Rhizome and Ilya Kreymer. Released under the GNU General Public License. This file is part of pywb, https://github.com/webrecorder/pywb pywb is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. pywb is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with pywb. If not, see . */ // Creates the default pywb banner. (function() { try { if (window.parent !== window && window.parent.wbinfo) { return; } } catch (e) { } /** * The default banner class */ function DefaultBanner() { if (!(this instanceof DefaultBanner)) return new DefaultBanner(); this.banner = null; this.captureInfo = null; this.last_state = {}; this.state = null; this.title = ''; this.bannerUrlSet = false; this.onMessage = this.onMessage.bind(this); } // Functions required to be exposed by all banners /** * @desc Initialize (display) the banner */ DefaultBanner.prototype.init = function() { this.createBanner('_wb_frame_top_banner'); if (window.wbinfo) { this.set_banner( window.wbinfo.url, window.wbinfo.timestamp, window.wbinfo.is_live, window.wbinfo.is_framed ? '' : document.title ); } }; /** * @desc Called by ContentFrame to detect if the banner is still showing * that the page is loading * @returns {boolean} */ DefaultBanner.prototype.stillIndicatesLoading = function() { return !this.bannerUrlSet; }; /** * @param {string} url - The URL of the replayed page * @param {?string} ts - The timestamp of the replayed page. * If we are in live mode this is undefined/empty string * @param {boolean} is_live - A bool indicating if we are operating in live mode */ DefaultBanner.prototype.updateCaptureInfo = function(url, ts, is_live) { if (is_live && !ts) { ts = new Date().toISOString().replace(/[-T:.Z]/g, ''); } this.set_banner(url, ts, is_live, null); }; /** * @desc Called by ContentFrame when a message is received from the replay iframe * @param {MessageEvent} event - The message event containing the message received * from the replayed page */ DefaultBanner.prototype.onMessage = function(event) { var type = event.data.wb_type; if (type === 'load' || type === 'replace-url') { this.state = event.data; this.last_state = this.state; this.title = event.data.title || this.title; } else if (type === 'title') { this.state = this.last_state; this.title = event.data.title; } else { return; } // favicon update if (type === 'load') { var head = document.querySelector('head'); var oldLink = document.querySelectorAll("link[rel*='icon']"); var i = 0; for (; i < oldLink.length; i++) { head.removeChild(oldLink[i]); } if (this.state.icons) { for (i = 0; i < this.state.icons.length; i++) { var icon = this.state.icons[i]; var link = document.createElement('link'); link.rel = icon.rel; link.href = icon.href; head.appendChild(link); } } } this.set_banner( this.state.url, this.state.ts, this.state.is_live, this.title ); }; // Functions internal to the default banner /** * @desc Navigate to different language, if available */ DefaultBanner.prototype.changeLanguage = function(lang, evt) { evt.preventDefault(); var path = window.location.href; if (path.indexOf(window.banner_info.prefix) == 0) { path = path.substring(window.banner_info.prefix.length); if (window.banner_info.locale_prefixes && window.banner_info.locale_prefixes[lang]) { window.location.pathname = window.banner_info.locale_prefixes[lang] + path; } } } /** * @desc Creates the underlying HTML elements comprising the banner * @param {string} bid - The id for the banner */ DefaultBanner.prototype.createBanner = function(bid) { this.banner = document.createElement('wb_div', true); this.banner.setAttribute('id', bid); this.banner.setAttribute('lang', 'en'); if (window.banner_info.logoImg) { var logo = document.createElement("a"); logo.setAttribute("href", "/" + (window.banner_info.locale ? window.banner_info.locale + "/" : "")); logo.setAttribute("class", "_wb_linked_logo"); var logoContents = ""; var logoUrl = window.banner_info.staticPrefix + "/" + window.banner_info.logoImg; logoContents += "" + window.banner_info.logoAlt + ""; logoContents += "" + window.banner_info.logoAlt + ""; logo.innerHTML = logoContents; this.banner.appendChild(logo); } this.captureInfo = document.createElement("span"); this.captureInfo.setAttribute("id", "_wb_capture_info"); this.captureInfo.innerHTML = window.banner_info.loadingLabel; this.banner.appendChild(this.captureInfo); var ancillaryLinks = document.createElement("div"); ancillaryLinks.setAttribute("id", "_wb_ancillary_links"); var calendarImg = window.banner_info.calendarImg || window.banner_info.staticPrefix + "/calendar.svg"; var calendarLink = document.createElement("a"); calendarLink.setAttribute("id", "calendarLink"); calendarLink.setAttribute("href", "#"); calendarLink.innerHTML = "" + window.banner_info.calendarAlt + " " +window.banner_info.calendarLabel + ""; ancillaryLinks.appendChild(calendarLink); this.calendarLink = calendarLink; if (typeof window.banner_info.locales !== "undefined" && window.banner_info.locales.length > 1) { var locales = window.banner_info.locales; var languages = document.createElement("div"); var label = document.createElement("span"); label.setAttribute("class", "_wb_no-mobile"); label.appendChild(document.createTextNode(window.banner_info.choiceLabel + " ")); languages.appendChild(label); for(var i = 0; i < locales.length; i++) { var locale = locales[i]; var langLink = document.createElement("a"); langLink.setAttribute("href", "#"); langLink.addEventListener("click", this.changeLanguage.bind(this, locale)); langLink.appendChild(document.createTextNode(locale)); languages.appendChild(langLink); if (i !== locales.length - 1) { languages.appendChild(document.createTextNode(" / ")); } } ancillaryLinks.appendChild(languages); } this.banner.appendChild(ancillaryLinks); document.body.insertBefore(this.banner, document.body.firstChild); }; /** * @desc Converts a timestamp to a date string. If is_gmt is truthy then * the returned data string will be the results of date.toGMTString otherwise * its date.toLocaleString() * @param {?string} ts - The timestamp to receive the correct date string for * @param {boolean} is_gmt - Is the returned date string to be in GMT time * @returns {string} */ DefaultBanner.prototype.ts_to_date = function(ts, is_gmt) { if (!ts) { return ''; } if (ts.length < 14) { ts += '00000000000000'.substr(ts.length); } var datestr = ts.substring(0, 4) + '-' + ts.substring(4, 6) + '-' + ts.substring(6, 8) + 'T' + ts.substring(8, 10) + ':' + ts.substring(10, 12) + ':' + ts.substring(12, 14) + '-00:00'; var date = new Date(datestr); if (is_gmt) { return date.toGMTString(); } else { return date.toLocaleString(window.banner_info.locale); } }; /** * @desc Updates the contents displayed by the banner * @param {?string} url - The URL of the replayed page to be displayed in the banner * @param {?string} ts - A timestamp to be displayed in the banner * @param {boolean} is_live - Are we in live mode * @param {?string} title - The title of the replayed page to be displayed in the banner */ DefaultBanner.prototype.set_banner = function(url, ts, is_live, title) { var capture_str; var title_str; if (!url) { this.captureInfo.innerHTML = window.banner_info.loadingLabel; this.bannerUrlSet = false; return; } if (!ts) { return; } if (title) { capture_str = title; } else { capture_str = url; } title_str = capture_str; capture_str = "" + capture_str + ""; capture_str += ""; if (is_live) { title_str = window.banner_info.liveMsg + " " + title_str; capture_str += "" + window.banner_info.liveMsg + " "; } capture_str += this.ts_to_date(ts, window.banner_info.is_gmt); capture_str += ""; this.calendarLink.setAttribute("href", window.banner_info.prefix + "*/" + url); this.calendarLink.style.display = is_live ? "none" : ""; this.captureInfo.innerHTML = capture_str; window.document.title = title_str; this.bannerUrlSet = true; }; // all banners will expose themselves by adding themselves as WBBanner on window window.WBBanner = new DefaultBanner(); // if wbinfo.url is set and not-framed, init banner in content frame if (window.wbinfo && window.wbinfo.url && !window.wbinfo.is_framed) { if (document.readyState === "loading") { document.addEventListener("DOMContentLoaded", function() { window.WBBanner.init(); }); } else { window.WBBanner.init(); } } })();