diff options
author | fschneider <florian.schneider@student.tugraz.at> | 2015-09-01 11:34:36 +0200 |
---|---|---|
committer | fschneider <florian.schneider@student.tugraz.at> | 2015-09-01 11:34:36 +0200 |
commit | 5a807a74663dcf7ea1eae8f37589072bdad1f036 (patch) | |
tree | 1bfc650f729da5442a3c9aa885651be8e5a25fe8 /pdf-as-web/src/main/webapp/assets/js/pdf.js | |
parent | be395099139640b820dfd1e6bc06d8dbcb14a415 (diff) | |
download | pdf-as-4-5a807a74663dcf7ea1eae8f37589072bdad1f036.tar.gz pdf-as-4-5a807a74663dcf7ea1eae8f37589072bdad1f036.tar.bz2 pdf-as-4-5a807a74663dcf7ea1eae8f37589072bdad1f036.zip |
User Interface nearly finished
Diffstat (limited to 'pdf-as-web/src/main/webapp/assets/js/pdf.js')
7 files changed, 1067 insertions, 88 deletions
diff --git a/pdf-as-web/src/main/webapp/assets/js/pdf.js/build/pdf.js b/pdf-as-web/src/main/webapp/assets/js/pdf.js/build/pdf.js index 16033d83..0d76fd2f 100644 --- a/pdf-as-web/src/main/webapp/assets/js/pdf.js/build/pdf.js +++ b/pdf-as-web/src/main/webapp/assets/js/pdf.js/build/pdf.js @@ -2028,6 +2028,7 @@ var PDFDocumentProxy = (function PDFDocumentProxyClosure() { * @return {number} Total number of pages the PDF contains. */ get numPages() { + return this.pdfInfo.numPages; }, /** diff --git a/pdf-as-web/src/main/webapp/assets/js/pdf.js/web/app.js b/pdf-as-web/src/main/webapp/assets/js/pdf.js/web/app.js index be33e35d..5e286df8 100644 --- a/pdf-as-web/src/main/webapp/assets/js/pdf.js/web/app.js +++ b/pdf-as-web/src/main/webapp/assets/js/pdf.js/web/app.js @@ -3,6 +3,123 @@ // var global_status = new statusObject(); +/* + * Convert touch to mouse + */ + +/* + * picked from http://stackoverflow.com/questions/5186441/javascript-drag-and-drop-for-touch-devices + * + */ +function touchHandler(event) +{ + // trick to add support for touch event to elements/widgets that do not support it + // by convetting convert touchevents into mouseevents + + // only apply this trick to ui-draggable elements + if ( ! $(event.target).hasClass('ui-draggable') ) { + return; + } + + var touches = event.changedTouches, + first = touches[0], + type = ""; + + switch(event.type) { + case "touchstart": type = "mousedown"; break; + case "touchmove": type="mousemove"; break; + case "touchend": type="mouseup"; break; + default: return; + } + + // convert touchevents into mouseevents + var simulatedEvent = document.createEvent("MouseEvent"); + simulatedEvent.initMouseEvent(type, true, true, window, 1, + first.screenX, first.screenY, + first.clientX, first.clientY, false, + false, false, false, 0/*left*/, null); + + first.target.dispatchEvent(simulatedEvent); + event.preventDefault(); +} + +function init() { + console.log("init touchconverter"); + if (Modernizr.touch){ + // faster links for touch devices + // by wiring directly touchend event as if it was a click (and disabling click handler) + var links = document.getElementsByTagName("a"); + for (var i=0; i < links.length; i++) { + var link = links[i]; + if ( link.href !== undefined && link.href !== '') { + link.addEventListener("click", function(e) { + e.preventDefault(); + }); + link.addEventListener("touchend", function() { + document.location = this.href; + }); + } + }; + + // listen to touch events and provide support to them where needed + document.addEventListener("touchstart", touchHandler, true); + document.addEventListener("touchmove", touchHandler, true); + document.addEventListener("touchend", touchHandler, true); + document.addEventListener("touchcancel", touchHandler, true); + } +} + +$(document).ready(function(){ + + init(); // initialize the touch converter + window.lang = new Lang('en'); // set default language + window.lang.dynamic('th', 'en.json'); // define language pack to load dynamically + + // check the language of the webapp , WEBAPP ONLY + + var webapp_language = window.parent.default_language; + console.log("parent default lang: " + webapp_language); + + switchLanguage(webapp_language); + + $("#placeContinue").bind("click", function(evt) { + + $(window.parent.document).find("#SignStepButton").click(); + }); + + $("#BackBox").on("click", function(evt){ + + window.parent.GoBack(); + }); + + $("#PlaceOnNewPage").on("click", function(evt) { + + $("#delSignature").click(); + console.log("setting placeonnewpage from " + window.parent.place_on_new_page); + window.parent.place_on_new_page = true; + console.log("to " + window.parent.place_on_new_page); + $(window.parent.document).find("#SignStepButton").click(); + + }); + +}); + +function switchLanguage(language) +{ + switch(language) + { + case "en": + window.lang.change("en"); + break; + case "de": + window.lang.change("th"); + break; + default: + console.log("The viewer does not support the language '" + language + "'"); + break; + } +} + // //statusObject Definition // @@ -145,12 +262,29 @@ function registerSignaturePlacementEventHandlers() { //is in the DOM tree. If thats true, we can restore the signature on that page. // document.addEventListener('pagerendered', function(evt) { + var page; if(!isSignatureInDomTree() && isSignaturePlaced()) { - var page = global_status.getSignature().page; + page = global_status.getSignature().page; if(isPageInDomTree(page)) { placeSignature(null, page, global_status.getSignature().sig[0].outerHTML); } + } + page = global_status.getSignature().page; + // every time when a page is rendered we have to make the children clickthrough + console.log("page is rendered: " + page); + // disabled pointer events on given page + $("#pageContainer" + page + " .textLayer").children().css("pointer-events", "none"); + $("#pageContainer" + page + " .annotationLayer").children().css("pointer-events", "none"); + + // resize img signature to adapt to a resized window + var current_scale = PDFViewerApplication.pdfViewer.currentScale; + var sig_size = Math.floor(96 * current_scale); + console.log("Signature resizing: " + sig_size); + var image_source = global_status.applicationContext + "/visblock?r=" + sig_size.toString(); + + $("#img_signature").attr("src", image_source); + }); } @@ -201,32 +335,26 @@ function placeSignature(evt, page_to_place, s) { var left_pos; var top_pos; - - //console.log("last left: " + last_left + " last top: " + last_top); - + if(typeof last_left != 'undefined') { - //console.log("not undefined"); left_pos = last_left; top_pos = last_top; } else // otherwise set default position { - //console.log("first time set left and top"); left_pos = "30%"; top_pos = "20%"; } - var image_width = "30%"; - var image_height = "9%"; - - var current_scale = PDFViewerApplication.pdfViewer.currentScale; var sig_size = Math.floor(96 * current_scale); - //var image_source = global_status.applicationContext + "/visblock?r=" + sig_size.toString(); - var image_source = '../../../img/signature.png'; + //sig_size = 300; + console.log("Signature resolution: " + sig_size); + var image_source = global_status.applicationContext + "/visblock?r=" + sig_size.toString(); var defaultSignature = "<img src='" + image_source + "' alt='Signature' id='img_signature' class='cl_signature' draggable='true' style='position: absolute; z-index:4; " + - "cursor:move; left:" + left_pos + "; top:" + top_pos + "; width:" + image_width + "; height:" + image_height + ";'>"; + "cursor:move; left:" + left_pos + "; top:" + top_pos + ";'>"; + if (typeof page_to_place === 'undefined') { page_to_place = PDFView.page;} if (typeof s === 'undefined') { s = defaultSignature} @@ -241,12 +369,56 @@ function placeSignature(evt, page_to_place, s) { posy: (s === defaultSignature) ? "0" : global_status.getSignature().posy, sig: $(".cl_signature") }); - updateSignaturePosition(global_status.getSignature(), null, null, false); + updateSignaturePosition(global_status.getSignature()); makeSignatureDraggable(global_status.getSignature()); + $("#img_signature").on("mousedown", function(evt) { + evt.stopPropagation(); + }); + + $("#img_signature").on("mousedown", function(evt){ + + if($(this).closest(".textLayer").children().css("pointer-events") !== "none" && + $(this).closest(".annotationLayer").children().css("pointer-events") !== "none") + { + $(this).closest(".textLayer").children().css("pointer-events", "none"); + $(this).closest(".annotationLayer").children().css("pointer-events", "none"); + + return; + } + + }); + + $(".page").on("mousedown", function(evt){ + + // check if there is already pointerevents: none on all page children, if not -> apply + + if($(this).find(".textLayer").children().css("pointer-events") !== "none" && + $(this).find(".annotationLayer").children().css("pointer-events") !== "none") + { + $(this).find(".textLayer").children().css("pointer-events", "none"); + $(this).find(".annotationLayer").children().css("pointer-events", "none"); + return; + } + + if($(this).find("#img_signature").length) + { + + // let the signature jump to the event position + $("#img_signature").css("left", evt.offsetX + "px"); + $("#img_signature").css("top", evt.offsetY + "px"); + + // update position + updateSignaturePosition(global_status.getSignature()); + + // start dragging signature + $("#img_signature").trigger(evt); + + } + }); + $("#pageFitOption").click(); $("#scaleSelect").change(); -//console.log("left: " + $("#img_signature").css("left") + " top: " + $("#img_signature").css("top")); } @@ -258,21 +430,20 @@ function placeSignature(evt, page_to_place, s) { function makeSignatureDraggable(signature) { signature.sig.draggable({ drag: function() { - console.log("drag"); - updateSignaturePosition(signature, null, null, false) + updateSignaturePosition(signature) }, containment: "parent" }); - $("#img_signature").on("touchmove", function(e) { - console.log("signature touchmove... x: " + e.originalEvent.touches[0].pageX + " y: " +e.originalEvent.touches[0].pageY); - updateSignaturePosition(signature, e.originalEvent.touches[0].pageX, e.originalEvent.touches[0].pageY, true); - - }); - $(window).on("touchmove", function(e) { - console.log("preventing default!"); - e.preventDefault(); + + // only if we are on the page we prevent the default scroll + var target = e.target; + + if($(target).hasClass("textLayer") || $(target).parents('.left').length || $(target).parents('.page').length) + { + e.preventDefault(); + } }); $("#img_signature").on("contextmenu", function(e) { @@ -285,7 +456,7 @@ function makeSignatureDraggable(signature) { //The position is is saved in the html attributes 'data-pos-x' and 'data-pos-y' of the //signature element. // -function updateSignaturePosition(signature, xpos, ypos, mobile) { +function updateSignaturePosition(signature) { var page = signature.page; var canvas_height = $("#page" + page.toString()).attr("height"); var current_scale = PDFViewerApplication.pdfViewer.currentScale; @@ -293,45 +464,13 @@ function updateSignaturePosition(signature, xpos, ypos, mobile) { var x; var y; - var mobile_x_offset = -parseInt($("#img_signature").css("width")) / 1.5; - var mobile_y_offset = -parseInt($("#img_signature").css("height")); - - //console.log("canvas-height: " + parseInt(canvas_height)); - if(mobile) - { - - x = xpos; - y = ypos;// (parseInt(canvas_height) - ypos); - //console.log("changing x: " + x + " y: "+ y); - } - else - { - x = thisPos.left; - y = thisPos.top; - } - - if(mobile) - { - signature.posx = (x + mobile_x_offset).toString(); - signature.posy = (y + mobile_y_offset).toString(); - } - else - { - signature.posx = Math.floor(x / current_scale / (4.0/3.0)).toString(); - signature.posy = Math.floor((parseInt(canvas_height) - (y)) / current_scale / (4.0/3.0)).toString(); - } - - + x = thisPos.left; + y = thisPos.top; - - if(mobile) - { - $("#img_signature").css("left", signature.posx + "px"); - $("#img_signature").css("top", signature.posy + "px"); - } - - console.log("signature. posx: " + signature.posx + " posy: " + signature.posy); + signature.posx = Math.floor(x / current_scale / (4.0/3.0)).toString(); + signature.posy = Math.floor((parseInt(canvas_height) - (y)) / current_scale / (4.0/3.0)).toString(); + //console.log("last x: last y: " + $("#img_signature").css("left") + " " + $("#img_signature").css("top")); diff --git a/pdf-as-web/src/main/webapp/assets/js/pdf.js/web/en.json b/pdf-as-web/src/main/webapp/assets/js/pdf.js/web/en.json new file mode 100644 index 00000000..13b5541d --- /dev/null +++ b/pdf-as-web/src/main/webapp/assets/js/pdf.js/web/en.json @@ -0,0 +1,34 @@ +{ + "token": { + "Drop or select your file here": "Wählen sie Ihre Datei zum Hochladen aus oder ziehen Sie sie herein", + "Upload your File": "Laden Sie Ihr Dokument hoch", + "Browse...": "Durchsuchen...", + "Upload": "Hochladen", + "Place": "Platzieren", + "Sign": "Signieren", + "Finished": "Fertig", + "Back": "Zurück", + "The file type must be PDF!": "Das Dokument muss PDF Format haben!", + "Continue": "Weiter", + "Quick Sign": "Schnell Signatur", + "Loading your PDF, please wait...": "Ihr PDF wird geladen...", + "Mobile": "Handy", + "Card": "Karte", + "You can download your signed document here:": "Sie können ihr signiertes Dokument jetzt herunterladen:", + "Download": "Herunterladen", + "Signature will be placed at the bottom of your document": "Die Signatur wird automatisch so weit unten wie möglich platziert", + "Place your Signature by yourself": "Signatur manuell platzieren", + "The signature will be automatically placed on the bottom": "Die Signatur wird automatisch so weit unten wie möglich platziert", + "Auto": "Auto", + "English": "Deutsch", + "English": "Deutsch", + "English": "Deutsch", + "English": "Deutsch", + "English": "Deutsch" + }, + "regex": [ + ["Budget", "Budget"], + ["^Something at start of text", ""], + ["This will be case insensitive", "i", ""] + ] +}
\ No newline at end of file diff --git a/pdf-as-web/src/main/webapp/assets/js/pdf.js/web/jquery-lang.js b/pdf-as-web/src/main/webapp/assets/js/pdf.js/web/jquery-lang.js new file mode 100644 index 00000000..7708b6a3 --- /dev/null +++ b/pdf-as-web/src/main/webapp/assets/js/pdf.js/web/jquery-lang.js @@ -0,0 +1,622 @@ +/* + The MIT License (MIT) + + Copyright (c) 2014 Irrelon Software Limited + http://www.irrelon.com + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice, url and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + + Source: https://github.com/coolbloke1324/jquery-lang-js + + Changelog: + Version 2.0.0 - Complete re-write. + */ +var Lang = (function () { + var Lang = function (defaultLang, currentLang, allowCookieOverride) { + var self = this, + cookieLang; + + // Enable firing events + this._fireEvents = true; + + // Allow storage of dynamic language pack data + this._dynamic = {}; + + // Store existing mutation methods so we can auto-run + // translations when new data is added to the page + this._mutationCopies = { + append: $.fn.append, + appendTo: $.fn.appendTo, + prepend: $.fn.prepend, + before: $.fn.before, + after: $.fn.after, + html: $.fn.html + }; + + // Now override the existing mutation methods with our own + $.fn.append = function () { return self._mutation(this, 'append', arguments) }; + $.fn.appendTo = function () { return self._mutation(this, 'appendTo', arguments) }; + $.fn.prepend = function () { return self._mutation(this, 'prepend', arguments) }; + $.fn.before = function () { return self._mutation(this, 'before', arguments) }; + $.fn.after = function () { return self._mutation(this, 'after', arguments) }; + $.fn.html = function () { return self._mutation(this, 'html', arguments) }; + + // Set default and current language to the default one + // to start with + this.defaultLang = defaultLang || 'en'; + this.currentLang = defaultLang || 'en'; + + // Check for cookie support when no current language is specified + if ((allowCookieOverride || !currentLang) && $.cookie) { + // Check for an existing language cookie + cookieLang = $.cookie('langCookie'); + + if (cookieLang) { + // We have a cookie language, set the current language + currentLang = cookieLang; + } + } + + $(function () { + // Setup data on the language items + self._start(); + + // Check if the current language is not the same as our default + if (currentLang && currentLang !== self.defaultLang) { + // Switch to the current language + self.change(currentLang); + } + }) + }; + + /** + * Object that holds the language packs. + * @type {{}} + */ + Lang.prototype.pack = {}; + + /** + * Array of translatable attributes to check for on elements. + * @type {string[]} + */ + Lang.prototype.attrList = [ + 'title', + 'alt', + 'placeholder' + ]; + + /** + * Defines a language pack that can be dynamically loaded and the + * path to use when doing so. + * @param {String} lang The language two-letter iso-code. + * @param {String} path The path to the language pack js file. + */ + Lang.prototype.dynamic = function (lang, path) { + if (lang !== undefined && path !== undefined) { + this._dynamic[lang] = path; + } + }; + + /** + * Loads a new language pack for the given language. + * @param {string} lang The language to load the pack for. + * @param {Function=} callback Optional callback when the file has loaded. + */ + Lang.prototype.loadPack = function (lang, callback) { + var self = this; + + if (lang && self._dynamic[lang]) { + $.ajax({ + dataType: "json", + url: self._dynamic[lang], + success: function (data) { + self.pack[lang] = data; + + // Process the regex list + if (self.pack[lang].regex) { + var packRegex = self.pack[lang].regex, + regex, + i; + + for (i = 0; i < packRegex.length; i++) { + regex = packRegex[i]; + if (regex.length === 2) { + // String, value + regex[0] = new RegExp(regex[0]); + } else if (regex.length === 3) { + // String, modifiers, value + regex[0] = new RegExp(regex[0], regex[1]); + + // Remove modifier + regex.splice(1, 1); + } + } + } + + console.log('Loaded language pack: ' + self._dynamic[lang]); + if (callback) { callback(false, lang, self._dynamic[lang]); } + }, + error: function () { + console.log('Error loading language pack' + self._dynamic[lang]); + if (callback) { callback(true, lang, self._dynamic[lang]); } + } + }); + } else { + throw('Cannot load language pack, no file path specified!'); + } + }; + + /** + * Scans the DOM for elements with [lang] selector and saves translate data + * for them for later use. + * @private + */ + Lang.prototype._start = function (selector) { + // Get the page HTML + var arr = selector !== undefined ? $(selector).find('[lang]') : $(':not(html)[lang]'), + arrCount = arr.length, + elem; + + while (arrCount--) { + elem = $(arr[arrCount]); + this._processElement(elem); + } + }; + + Lang.prototype._processElement = function (elem) { + // Only store data if the element is set to our default language + if (elem.attr('lang') === this.defaultLang) { + // Store translatable attributes + this._storeAttribs(elem); + + // Store translatable content + this._storeContent(elem); + } + }; + + /** + * Stores the translatable attribute values in their default language. + * @param {object} elem The jQuery selected element. + * @private + */ + Lang.prototype._storeAttribs = function (elem) { + var attrIndex, + attr, + attrObj; + + for (attrIndex = 0; attrIndex < this.attrList.length; attrIndex++) { + attr = this.attrList[attrIndex]; + if (elem.attr(attr)) { + // Grab the existing attribute store or create a new object + attrObj = elem.data('lang-attr') || {}; + + // Add the attribute and value to the store + attrObj[attr] = elem.attr(attr); + + // Save the attribute data to the store + elem.data('lang-attr', attrObj); + } + } + }; + + /** + * Reads the existing content from the element and stores it for + * later use in translation. + * @param elem + * @private + */ + Lang.prototype._storeContent = function (elem) { + // Check if the element is an input element + if (elem.is('input')) { + switch (elem.attr('type')) { + case 'button': + case 'submit': + case 'reset': + elem.data('lang-val', elem.val()); + break; + } + } else { + // Get the text nodes immediately inside this element + var nodes = this._getTextNodes(elem); + if (nodes) { + elem.data('lang-text', nodes); + } + } + }; + + /** + * Retrieves the text nodes from an element and returns them in array wrap into + * object with two properties: + * - node - which corespondes to text node, + * - langDefaultText - wich remember current data of text node + * @param elem + * @returns {Array|*} + * @private + */ + Lang.prototype._getTextNodes = function (elem) { + var nodes = elem.contents(), nodeObjArray = [], nodeObj = {}, + nodeArr, that = this, map = Array.prototype.map; + + $.each(nodes, function (index, node) { + if ( node.nodeType !== 3 ) { + return; + } + + nodeObj = { + node : node, + langDefaultText : node.data + }; + + nodeObjArray.push(nodeObj); + }); + + return nodeObjArray; + }; + + /** + * Sets text nodes of an element translated based on the passed language. + * @param elem + * @param {Array|*} nodes array of objecs with text node and defaultText returned from _getTextNodes + * @param lang + * @private + */ + Lang.prototype._setTextNodes = function (elem, nodes, lang) { + var index, + textNode, + defaultText, + translation, + langNotDefault = lang !== this.defaultLang; + + for (index = 0; index < nodes.length; index++) { + textNode = nodes[index]; + + if (langNotDefault) { + defaultText = $.trim(textNode.langDefaultText); + + if (defaultText) { + // Translate the langDefaultText + translation = this.translate(defaultText, lang); + + if (translation) { + try { + // Replace the text with the translated version + textNode.node.data = textNode.node.data.split($.trim(textNode.node.data)).join(translation); + } catch (e) { + + } + } else { + console.log('Translation for "' + defaultText + '" not found!'); + } + } + } else { + // Replace with original text + try { + textNode.node.data = textNode.langDefaultText; + } catch (e) { + + } + } + } + }; + + /** + * Translates and sets the attributes of an element to the passed language. + * @param elem + * @param lang + * @private + */ + Lang.prototype._translateAttribs = function (elem, lang) { + var attr, + attrObj = elem.data('lang-attr') || {}, + translation; + + for (attr in attrObj) { + if (attrObj.hasOwnProperty(attr)) { + // Check the element still has the attribute + if (elem.attr(attr)) { + if (lang !== this.defaultLang) { + // Get the translated value + translation = this.translate(attrObj[attr], lang); + + // Check we actually HAVE a translation + if (translation) { + // Change the attribute to the translated value + elem.attr(attr, translation); + } + } else { + // Set default language value + elem.attr(attr, attrObj[attr]); + } + } + } + } + }; + + /** + * Translates and sets the contents of an element to the passed language. + * @param elem + * @param lang + * @private + */ + Lang.prototype._translateContent = function (elem, lang) { + var langNotDefault = lang !== this.defaultLang, + translation, + nodes; + + // Check if the element is an input element + if (elem.is('input')) { + switch (elem.attr('type')) { + case 'button': + case 'submit': + case 'reset': + if (langNotDefault) { + // Get the translated value + translation = this.translate(elem.data('lang-val'), lang); + + // Check we actually HAVE a translation + if (translation) { + // Set translated value + elem.val(translation); + } + } else { + // Set default language value + elem.val(elem.data('lang-val')); + } + break; + } + } else { + // Set text node translated text + nodes = elem.data('lang-text'); + if (nodes) { + this._setTextNodes(elem, nodes, lang); + } + } + }; + + /** + * Call this to change the current language on the page. + * @param {String} lang The new two-letter language code to change to. + * @param {String=} selector Optional selector to find language-based + * elements for updating. + * @param {Function=} callback Optional callback function that will be + * called once the language change has been successfully processed. This + * is especially useful if you are using dynamic language pack loading + * since you will get a callback once it has been loaded and changed. + * Your callback will be passed three arguments, a boolean to denote if + * there was an error (true if error), the second will be the language + * you passed in the change call (the lang argument) and the third will + * be the selector used in the change update. + */ + Lang.prototype.change = function (lang, selector, callback) { + var self = this; + + if (lang === this.defaultLang || this.pack[lang] || this._dynamic[lang]) { + // Check if the language pack is currently loaded + if (lang !== this.defaultLang) { + if (!this.pack[lang] && this._dynamic[lang]) { + // The language pack needs loading first + console.log('Loading dynamic language pack: ' + this._dynamic[lang] + '...'); + this.loadPack(lang, function (err, loadingLang, fromUrl) { + if (!err) { + // Process the change language request + self.change.call(self, lang, selector, callback); + } else { + // Call the callback with the error + if (callback) { callback('Language pack could not load from: ' + fromUrl, lang, selector); } + } + }); + + return; + } else if (!this.pack[lang] && !this._dynamic[lang]) { + // Pack not loaded and no dynamic entry + console.log('Could not change language to ' + lang + ' because no language pack for this language exists!'); + if (callback) { callback('Language pack not defined for: ' + lang, lang, selector); } + } + } + + var fireAfterUpdate = false, + currLang = this.currentLang; + + if (this.currentLang != lang) { + this.beforeUpdate(currLang, lang); + fireAfterUpdate = true; + } + + this.currentLang = lang; + + // Get the page HTML + var arr = selector !== undefined ? $(selector).find('[lang]') : $(':not(html)[lang]'), + arrCount = arr.length, + elem; + + while (arrCount--) { + elem = $(arr[arrCount]); + + if (elem.attr('lang') !== lang) { + this._translateElement(elem, lang); + } + } + + if (fireAfterUpdate) { + this.afterUpdate(currLang, lang); + } + + // Check for cookie support + if ($.cookie) { + // Set a cookie to remember this language setting with 1 year expiry + $.cookie('langCookie', lang, { + expires: 365, + path: '/' + }); + } + + if (callback) { callback(false, lang, selector); } + } else { + console.log('Attempt to change language to "' + lang + '" but no language pack for that language is loaded!'); + if (callback) { callback('No language pack defined for: ' + lang, lang, selector); } + } + }; + + Lang.prototype._translateElement = function (elem, lang) { + // Translate attributes + this._translateAttribs(elem, lang); + + // Translate content + if (elem.attr('data-lang-content') != 'false') { + this._translateContent(elem, lang); + } + + // Update the element's current language + elem.attr('lang', lang); + }; + + /** + * Translates text from the default language into the passed language. + * @param {String} text The text to translate. + * @param {String} lang The two-letter language code to translate to. + * @returns {*} + */ + Lang.prototype.translate = function (text, lang) { + lang = lang || this.currentLang; + + if (this.pack[lang]) { + var translation = ''; + + if (lang != this.defaultLang) { + // Check for a direct token translation + translation = this.pack[lang].token[text]; + + if (!translation) { + // No token translation was found, test for regex match + translation = this._regexMatch(text, lang); + } + + if (!translation) { + console.log('Translation for "' + text + '" not found in language pack: ' + lang); + } + + return translation || text; + } else { + return text; + } + } else { + return text; + } + }; + + /** + * Checks the regex items for a match against the passed text and + * if a match is made, translates to the given replacement. + * @param {String} text The text to test regex matches against. + * @param {String} lang The two-letter language code to translate to. + * @returns {string} + * @private + */ + Lang.prototype._regexMatch = function (text, lang) { + // Loop the regex array and test them against the text + var arr, + arrCount, + arrIndex, + item, + regex, + expressionResult; + + arr = this.pack[lang].regex; + + if (arr) { + arrCount = arr.length; + + for (arrIndex = 0; arrIndex < arrCount; arrIndex++) { + item = arr[arrIndex]; + regex = item[0]; + + // Test regex + expressionResult = regex.exec(text); + + if (expressionResult && expressionResult[0]) { + return text.split(expressionResult[0]).join(item[1]); + } + } + } + + return ''; + }; + + Lang.prototype.beforeUpdate = function (currentLang, newLang) { + if (this._fireEvents) { + $(this).triggerHandler('beforeUpdate', [currentLang, newLang, this.pack[currentLang], this.pack[newLang]]); + } + }; + + Lang.prototype.afterUpdate = function (currentLang, newLang) { + if (this._fireEvents) { + $(this).triggerHandler('afterUpdate', [currentLang, newLang, this.pack[currentLang], this.pack[newLang]]); + } + }; + + Lang.prototype.refresh = function () { + // Process refresh on the page + this._fireEvents = false; + this.change(this.currentLang); + this._fireEvents = true; + }; + + //////////////////////////////////////////////////// + // Mutation overrides + //////////////////////////////////////////////////// + Lang.prototype._mutation = function (context, method, args) { + var result = this._mutationCopies[method].apply(context, args), + currLang = this.currentLang, + rootElem = $(context); + + if (rootElem.attr('lang')) { + // Switch off events for the moment + this._fireEvents = false; + + // Check if the root element is currently set to another language from current + //if (rootElem.attr('lang') !== this.currentLang) { + this._translateElement(rootElem, this.defaultLang); + this.change(this.defaultLang, rootElem); + + // Calling change above sets the global currentLang but this is supposed to be + // an isolated change so reset the global value back to what it was before + this.currentLang = currLang; + + // Record data on the default language from the root element + this._processElement(rootElem); + + // Translate the root element + this._translateElement(rootElem, this.currentLang); + //} + } + + // Record data on the default language from the root's children + this._start(rootElem); + + // Process translation on any child elements of this element + this.change(this.currentLang, rootElem); + + // Switch events back on + this._fireEvents = true; + + return result; + }; + + return Lang; +})();
\ No newline at end of file diff --git a/pdf-as-web/src/main/webapp/assets/js/pdf.js/web/viewer.css b/pdf-as-web/src/main/webapp/assets/js/pdf.js/web/viewer.css index 8cf1a6a4..cae4eeb2 100644 --- a/pdf-as-web/src/main/webapp/assets/js/pdf.js/web/viewer.css +++ b/pdf-as-web/src/main/webapp/assets/js/pdf.js/web/viewer.css @@ -70,7 +70,7 @@ direction: ltr; width: 51em; height: 66em; - margin: 0.063em auto -0.5em auto; + margin: 1em auto -0.5em auto; position: relative; overflow: visible; border: 9px solid transparent; @@ -183,8 +183,8 @@ html { body { height: 100%; - background-color: #404040; - background-image: url(images/texture.png); + background-color: transparent; + /* background-image: url(images/texture.png); */ } body, @@ -361,7 +361,21 @@ html[dir='rtl'] #outerContainer.sidebarOpen > #sidebarContainer { -webkit-transition-timing-function: ease; transition-duration: 200ms; transition-timing-function: ease; + + background-color: #E8F4FF; +} + +input[type=number]::-webkit-outer-spin-button, +input[type=number]::-webkit-inner-spin-button { + -webkit-appearance: none; + margin: 0; } + +input[type=number] { + -moz-appearance:textfield; +} + + html[dir='ltr'] #outerContainer.sidebarOpen > #mainContainer { -webkit-transition-property: left; transition-property: left; @@ -392,7 +406,7 @@ html[dir='rtl'] #sidebarContent { } #viewerContainer { - overflow: auto; + overflow-y: hidden; /* hide or show Scrollbar in Viewer*/ -webkit-overflow-scrolling: touch; position: absolute; top: 2em; @@ -417,7 +431,70 @@ html[dir='rtl'] #viewerContainer { } #toolbarContainer { - width: 100%; + + margin: 1em; + width: calc(100% - 2em); /* To include the margin of 1em */ +} + +#viewerContainer { + + margin-top: 2em; + } + +#PageInput { + width: 8.6em; + margin-bottom:-3em; + padding-left: 0.5em; +} + +#pageNumber { + width: 3.5em; +} + +@media screen and (max-width: 474px) { /* This is the width where it collapses */ + #ContinueToSignText { + display: none; + } + + #PlaceOnNewPageText { + display: none; + } + + #BackBoxText { + display: none; + } +} + +@media screen and (min-width: 475px) { /* This is the width where it collapses */ + + #ContinueToSignIcon { + display: none; + } + + #PlaceOnNewPageIcon { + display: none; + } + + #BackBoxIcon { + display: none; + } +} + +#ContinueToSignText, #BackBoxText { + margin: 0; +} + +#placeContinue { + margin-top:0; +} + +#BackBox { + margin-right: 0.5em; +} + +#PlaceOnNewPage { + margin-left: 0.5em; + height: 34px; } #toolbarSidebar { @@ -443,10 +520,12 @@ html[dir='rtl'] #toolbarSidebar { #toolbarContainer, .findbar, .secondaryToolbar { position: relative; height: 2em; - background-color: #474747; /* fallback */ - background-image: url(images/texture.png), - linear-gradient(hsla(0,0%,32%,.99), hsla(0,0%,27%,.95)); + background-color: transparent; /*#474747;*/ /* fallback */ + /*background-image: url(images/texture.png), + linear-gradient(hsla(0,0%,32%,.99), hsla(0,0%,27%,.95));*/ + } +/* html[dir='ltr'] #toolbarContainer, .findbar, .secondaryToolbar { box-shadow: inset 0.063em 0 0 hsla(0,0%,100%,.08), inset 0 0.063em 0.063em hsla(0,0%,0%,.15), @@ -461,10 +540,12 @@ html[dir='rtl'] #toolbarContainer, .findbar, .secondaryToolbar { 0 0.063em 0 hsla(0,0%,0%,.15), 0 0.063em 0.063em hsla(0,0%,0%,.1); } +*/ #toolbarViewer { height: 2em; min-width: 5em; + display: none; } #loadingBar { @@ -1232,7 +1313,7 @@ html[dir='rtl'] .verticalToolbarSeparator { } .toolbarField.pageNumber { - -moz-appearance: textfield; /* hides the spinner in moz */ + -moz-appearance: none; /* hides the spinner in moz */ min-width: 16px; text-align: right; width: 40px; @@ -1646,9 +1727,13 @@ html[dir='rtl'] #documentPropertiesOverlay .row > * { font-size: 10px; } +#viewer { + background-color: transparent; +} + #viewer.textLayer-visible .textLayer > div, #viewer.textLayer-hover .textLayer > div:hover { - background-color: white; + background-color: transparent; color: black; } @@ -1868,8 +1953,9 @@ html[dir='rtl'] #documentPropertiesOverlay .row > * { #sidebarContainer, #secondaryToolbar, .toolbar, #loadingBox, #errorWrapper, .textLayer { display: none; } + #viewerContainer { - overflow: visible; + } diff --git a/pdf-as-web/src/main/webapp/assets/js/pdf.js/web/viewer.html b/pdf-as-web/src/main/webapp/assets/js/pdf.js/web/viewer.html index e44b78c5..6d0e507a 100644 --- a/pdf-as-web/src/main/webapp/assets/js/pdf.js/web/viewer.html +++ b/pdf-as-web/src/main/webapp/assets/js/pdf.js/web/viewer.html @@ -34,12 +34,20 @@ http://sourceforge.net/adobe/cmap/wiki/License/ <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.3/jquery-ui.min.js"></script> + <!-- Bootstrap includes --> + <link rel="stylesheet" href="../../../../assets/bootstrap/css/bootstrap.css"> + <link rel="stylesheet" href="../../../../assets/bootstrap/css/bootstrap.min.css"> + <script src="../../../../assets/bootstrap/js/bootstrap.js"></script> + <script src="../../../../assets/bootstrap/js/bootstrap.min.js"></script> + <script src="l10n.js"></script> <script src="../build/pdf.js"></script> <script src="debugger.js"></script> <script src="viewer.js"></script> + <script src="https://cdnjs.cloudflare.com/ajax/libs/modernizr/2.8.3/modernizr.min.js"></script> <!-- Used for touchvonverter in app.js --> <script src="app.js"></script> + <script src="jquery-lang.js"></script> <style> .black_overlay{ display: inline-block; @@ -196,28 +204,42 @@ http://sourceforge.net/adobe/cmap/wiki/License/ </div> <!-- secondaryToolbar --> <div class="toolbar"> - <div id="toolbarContainer"> + <div id="toolbarContainer" class="pull-right"> + <!-- new toolbar --> + <button id="previous" class="btn btn-primary pull-left" title="Go one page up"><span class="glyphicon glyphicon-triangle-top" aria-hidden="true"></span></button> + <button id="next" class="btn btn-primary pull-left" title="Go one page down"><span class="glyphicon glyphicon-triangle-bottom" aria-hidden="true"></span></button> + <div class="input-group" id="PageInput"> + <input type="number" id="pageNumber" class="form-control" placeholder="..." aria-describedby="PageNumberExtern" value=".."> + <span class="input-group-addon" id="numPages">...</span> + <button id="PlaceOnNewPage" class="btn btn-primary pull-left" title="The signature will be automatically placed on a new page"><p id="PlaceOnNewPageText" lang="en">Auto</p><span class="glyphicon glyphicon-paste" id="PlaceOnNewPageIcon" aria-hidden="true"></span></button> + </div> + <button id="placeContinue" class="btn btn-success pull-right" title="Continue signing your document"><p id="ContinueToSignText" lang="en">Continue</p><span class="glyphicon glyphicon-ok" id="ContinueToSignIcon" aria-hidden="true"></span></button> + <button id="BackBox" class="btn btn-primary pull-right"><p id="BackBoxText" lang="en">Back</p><span class="glyphicon glyphicon-chevron-left" id="BackBoxIcon" aria-hidden="true"></span></button> + + + <!-- Old toolbar --> + <div id="toolbarViewer"> <div id="toolbarViewerLeft"> <button id="sidebarToggle" class="toolbarButton" style="display:none" title="Toggle Sidebar" tabindex="11" data-l10n-id="toggle_sidebar"> <span data-l10n-id="toggle_sidebar_label">Toggle Sidebar</span> </button> - <div class="toolbarButtonSpacer"></div> - <button id="viewFind" class="toolbarButton group hiddenSmallView" title="Find in Document" tabindex="12" data-l10n-id="findbar"> + <div style="display:none;" class="toolbarButtonSpacer"></div> + <button style="display:none;" id="viewFind" class="toolbarButton group hiddenSmallView" title="Find in Document" tabindex="12" data-l10n-id="findbar"> <span data-l10n-id="findbar_label">Find</span> </button> <div class="splitToolbarButton"> - <button class="toolbarButton pageUp" title="Previous Page" id="previous" tabindex="13" data-l10n-id="previous"> + <button class="toolbarButton pageUp" title="Previous Page" id="previousOLD!!" tabindex="13" data-l10n-id="previous"> <span data-l10n-id="previous_label">Previous</span> </button> <div class="splitToolbarButtonSeparator"></div> - <button class="toolbarButton pageDown" title="Next Page" id="next" tabindex="14" data-l10n-id="next"> + <button class="toolbarButton pageDown" title="Next Page" id="nextOLD!!" tabindex="14" data-l10n-id="next"> <span data-l10n-id="next_label">Next</span> </button> </div> <label id="pageNumberLabel" class="toolbarLabel" for="pageNumber" data-l10n-id="page_label">Page: </label> - <input type="number" id="pageNumber" class="toolbarField pageNumber" value="1" size="4" min="1" tabindex="15"> - <span id="numPages" class="toolbarLabel"></span> + <input type="number" id="pageNumberOLD!!" class="toolbarField pageNumber" value="1" size="4" min="1" tabindex="15"> + <span id="numPagesOLD!!" class="toolbarLabel"></span> </div> <div id="toolbarViewerRight" style="display:none;"> diff --git a/pdf-as-web/src/main/webapp/assets/js/pdf.js/web/viewer.js b/pdf-as-web/src/main/webapp/assets/js/pdf.js/web/viewer.js index e26d544a..f93cedfe 100644 --- a/pdf-as-web/src/main/webapp/assets/js/pdf.js/web/viewer.js +++ b/pdf-as-web/src/main/webapp/assets/js/pdf.js/web/viewer.js @@ -53,6 +53,21 @@ var SCROLLBAR_PADDING = 40; var VERTICAL_PADDING = 5; +$(document).ready(function(){ + + // Redirect scroll event from main container to outer Document so that only the page is scrolled + + $("mainContainer").bind("scroll", function(evt) { + + console.log("scrolled mainContainer"); + $(window.parent.document).trigger(evt); + + }); + +}); + + + // preventing from using arrow keys or page keys to scroll $(document).on('keypress', function(e) { switch(e.which) @@ -93,6 +108,7 @@ function replaceSignature() $("#img_signature").prop("top", previous_top); } + // optimised CSS custom property getter/setter var CustomStyle = (function CustomStyleClosure() { @@ -223,11 +239,14 @@ function watchScroll(viewAreaElement, callback) { var debounceScroll = function debounceScroll(evt) { if (rAF) { + return; } // schedule an invocation of scroll for next animation frame. rAF = window.requestAnimationFrame(function viewAreaElementScrolled() { rAF = null; + + console.log("scrolled!"); var currentY = viewAreaElement.scrollTop; var lastY = state.lastY; @@ -239,8 +258,14 @@ function watchScroll(viewAreaElement, callback) { // place the signature again on current page + console.log("replace signature"); + $("#placeSignature").click(); + // update pageNumberExtern + + $(window.parent.document).find("#PageNumberExtern").val($("#pageNumber").val()); + callback(state); }); @@ -3239,6 +3264,7 @@ var PDFPageView = (function PDFPageViewClosure() { var div = this.div; canvas.style.width = canvas.parentNode.style.width = div.style.width = Math.floor(width) + 'px'; + canvas.style.height = canvas.parentNode.style.height = div.style.height = Math.floor(height) + 'px'; // The canvas may have been originally rotated, rotate relative to that. @@ -4547,6 +4573,8 @@ var PDFViewer = (function pdfViewer() { */ scrollPageIntoView: function PDFViewer_scrollPageIntoView(pageNumber, dest) { + + var pageView = this.pages[pageNumber - 1]; @@ -4565,6 +4593,8 @@ var PDFViewer = (function pdfViewer() { scrollIntoView(pageView.div); return; } + + var x = 0, y = 0; var width = 0, height = 0, widthScale, heightScale; @@ -6203,8 +6233,19 @@ var PDFViewerApplication = { var pagesCount = pdfDocument.numPages; document.getElementById('numPages').textContent = - mozL10n.get('page_of', {pageCount: pagesCount}, 'of {{pageCount}}'); + mozL10n.get('', {pageCount: pagesCount}, '{{pageCount}}'); // page_of in '' before, it generated the "von" / "of" document.getElementById('pageNumber').max = pagesCount; + + console.log("hide page navs when there is only 1 page.."); + + if(pagesCount < 2) + { + console.log("only 1 page -> hiding page navs"); + $("#previous, #next, #pageNumber, #numPages").hide(); + $("#placeContinue").css("margin-top", "8px"); + $("#BackBox").css("margin-top", "8px"); + } + var id = this.documentFingerprint = pdfDocument.fingerprint; var store = this.store = new ViewHistory(id); @@ -6372,9 +6413,25 @@ var PDFViewerApplication = { self.fallback(PDFJS.UNSUPPORTED_FEATURES.forms); } - console.log("pdfview just finished loading"); - $("#pageFitOption").click(); - $("#scaleSelect").change(); + console.log("pdfview just finished loading"); + + + + // WEB APP ONLY + + $(window.parent.document).find("#uploadContinue").prop("disabled", false); + $(window.parent.document).find("#uploadContinueQuick").prop("disabled", false); + $(window.parent.document).find("body").removeClass("wait"); + $(window.parent.document).find("#ContinueButtonText").show(); + $(window.parent.document).find("#MobileSpinner").hide(); + + // ----------------------------------------------------- + + + console.log("Initialize Page Number: " + pageNumber); + $(window.parent.document).find("#PageNumberExtern").val($("#pageNumber").val()); + $("#pageFitOption").click(); + $("#scaleSelect").change(); }); @@ -7184,6 +7241,8 @@ window.addEventListener('pagechange', function pagechange(evt) { PDFViewerApplication.pdfThumbnailViewer.scrollThumbnailIntoView(page); } } + + var numPages = PDFViewerApplication.pagesCount; document.getElementById('previous').disabled = (page <= 1); @@ -7227,13 +7286,29 @@ function handleMouseWheel(evt) { PDFViewerApplication[direction](Math.abs(ticks)); } */ - if(ticks > 0) + // get target of event + var target = evt.target; + + console.log("you scrolled on " + $(target).attr('class')); + + // WEB APP ONLY ... ? + if($(target).hasClass("textLayer") || $(target).parents('.left').length || $(target).parents('.page').length) { - PDFViewerApplication.page--; + console.log("react"); + + if(ticks > 0) + { + PDFViewerApplication.page--; + } + else + { + PDFViewerApplication.page++; + } } else { - PDFViewerApplication.page++; + // redirect scroll event // WEB APP ONLY ... ? + $(window.parent.document).trigger(evt); } if (evt.preventDefault) //disable default wheel action of scrolling page |