/**
* uiUtil.js : Utility functions for the User Interface
*
* Copyright 2013-2014 Mossroy and contributors
* License GPL v3:
*
* This file is part of Kiwix.
*
* Kiwix 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.
*
* Kiwix 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 Kiwix (file LICENSE-GPLv3.txt). If not, see
*/
'use strict';
define([], function() {
/**
* Creates a Blob from the given content, then a URL from this Blob
* And put this URL in the attribute of the DOM node
*
* This is useful to inject images (and other dependencies) inside an article
*
* @param {Object} jQueryNode
* @param {String} nodeAttribute
* @param {Uint8Array} content
* @param {String} mimeType
*/
function feedNodeWithBlob(node, nodeAttribute, content, mimeType) {
var blob = new Blob([content], { type: mimeType }, {oneTimeOnly: true});
var url = URL.createObjectURL(blob);
/*jQueryNode.on('load', function () {
URL.revokeObjectURL(url);
});*/
node.setAttribute(nodeAttribute, url);
}
var regexpRemoveUrlParameters = new RegExp(/([^\?]+)\?.*$/);
function removeUrlParameters(url) {
if (regexpRemoveUrlParameters.test(url)) {
return regexpRemoveUrlParameters.exec(url)[1];
} else {
return url;
}
}
function TableOfContents(articleDoc) {
this.doc = articleDoc;
this.headings = this.doc.querySelectorAll("h1, h2, h3, h4, h5, h6");
this.getHeadingObjects = function () {
var headings = [];
for (var i = 0; i < this.headings.length; i++) {
var element = this.headings[i];
var obj = {};
obj.id = element.id;
var objectId = element.innerHTML.match(/\bid\s*=\s*["']\s*([^"']+?)\s*["']/i);
obj.id = obj.id ? obj.id : objectId && objectId.length > 1 ? objectId[1] : "";
obj.index = i;
obj.textContent = element.textContent;
obj.tagName = element.tagName;
headings.push(obj);
}
return headings;
}
}
/**
* Checks whether an element is fully or partially in view
* This is useful for progressive download of images inside an article
*
* @param {Object} el
* @param {Boolean} fully
*/
function isElementInView(el, fully) {
var elemTop = el.getBoundingClientRect().top;
var elemBottom = el.getBoundingClientRect().bottom;
var isVisible = fully ? elemTop < window.innerHeight && elemBottom >= 0 :
elemTop >= 0 && elemBottom <= window.innerHeight;
return isVisible;
}
function makeReturnLink(title) {
//Abbreviate title if necessary
var shortTitle = title.substring(0, 25);
shortTitle = shortTitle == title ? shortTitle : shortTitle + "...";
var link = '
';
var rtnFunction = "(function () { setTab(); \
if (params.themeChanged) { \
params.themeChanged = false; \
if (history.state !== null) { \
var thisURL = decodeURIComponent(history.state.title); \
goToArticle(thisURL); \
} \
} \
})";
var returnDivs = document.getElementsByClassName("returntoArticle");
for (var i = 0; i < returnDivs.length; i++) {
returnDivs[i].innerHTML = link;
}
return rtnFunction;
}
function poll(msg) {
document.getElementById('searchingArticles').style.display = 'block';
document.getElementById('progressMessage').innerHTML = msg;
document.getElementById('progressMessage').style.display = 'block';
}
function clear() {
document.getElementById('progressMessage').innerHTML = '';
document.getElementById('progressMessage').style.display = 'none';
}
/**
* Initiates XMLHttpRequest
* Can be used for loading local files in app context
*
* @param {String} file
* @param {Function} callback
* @returns responseText, status
*/
function XHR(file, callback) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function (e) {
if (this.readyState == 4) {
callback(this.responseText, this.status);
}
};
var err = false;
try {
xhr.open('GET', file, true);
}
catch (e) {
console.log("Exception during GET request: " + e);
err = true;
}
if (!err) {
xhr.send();
} else {
callback("Error", 500);
}
}
function printCustomElements() {
var innerDocument = window.frames[0].frameElement.contentDocument;
//Add any missing classes
innerDocument.body.innerHTML = innerDocument.body.innerHTML.replace(/(class\s*=\s*["'][^"']*vcard\b[^>]+>\s*/ig, '$1 class="map-pin">');
innerDocument.body.innerHTML = innerDocument.body.innerHTML.replace(/(]+>\s+This article is issued from)/i, '$1class="copyLeft" $2');
var printOptions = innerDocument.getElementById("printOptions");
//If there is no printOptions style block in the iframe, create it
if (!printOptions) {
var printStyle = innerDocument.createElement("style");
printStyle.id = "printOptions";
innerDocument.head.appendChild(printStyle);
printOptions = innerDocument.getElementById("printOptions");
}
var printStyleInnerHTML = "@media print { ";
printStyleInnerHTML += document.getElementById("printNavBoxCheck").checked ? "" : ".navbox, .vertical-navbox { display: none; } ";
printStyleInnerHTML += document.getElementById("printEndNoteCheck").checked ? "" : ".reflist { display: none; } ";
printStyleInnerHTML += document.getElementById("externalLinkCheck").checked ? "" : ".externalLinks { display: none; } ";
printStyleInnerHTML += document.getElementById("seeAlsoLinkCheck").checked ? "" : ".seeAlso { display: none; } ";
printStyleInnerHTML += document.getElementById("printInfoboxCheck").checked ? "" : ".mw-stack, .infobox, .infobox_v2, .infobox_v3, .qbRight, .qbRightDiv, .wv-quickbar, .wikitable { display: none; } ";
printStyleInnerHTML += document.getElementById("printImageCheck").checked ? "" : "img { display: none; } ";
printStyleInnerHTML += ".copyLeft { display: none } ";
printStyleInnerHTML += ".map-pin { display: none } ";
printStyleInnerHTML += ".external { padding-right: 0 !important } ";
var sliderVal = document.getElementById("documentZoomSlider").value;
sliderVal = ~~sliderVal;
sliderVal = Math.floor(sliderVal * (Math.max(window.screen.width, window.screen.height) / 1440));
printStyleInnerHTML += "body { font-size: " + sliderVal + "% !important; } ";
printStyleInnerHTML += "}";
printOptions.innerHTML = printStyleInnerHTML;
}
/**
* Functions and classes exposed by this module
*/
return {
feedNodeWithBlob: feedNodeWithBlob,
removeUrlParameters: removeUrlParameters,
toc: TableOfContents,
isElementInView: isElementInView,
makeReturnLink: makeReturnLink,
poll: poll,
clear: clear,
XHR: XHR,
printCustomElements: printCustomElements
};
});