aboutsummaryrefslogtreecommitdiff
path: root/pdf-as-web/src/main/webapp/assets/js
diff options
context:
space:
mode:
Diffstat (limited to 'pdf-as-web/src/main/webapp/assets/js')
-rw-r--r--pdf-as-web/src/main/webapp/assets/js/dragNdrop.js192
-rw-r--r--pdf-as-web/src/main/webapp/assets/js/jquery-lang.js622
-rw-r--r--pdf-as-web/src/main/webapp/assets/js/js.cookie.js139
-rw-r--r--pdf-as-web/src/main/webapp/assets/js/langpack/nonDynamic.js76
-rw-r--r--pdf-as-web/src/main/webapp/assets/js/langpack/th.json33
-rw-r--r--pdf-as-web/src/main/webapp/assets/js/pdf.js/build/pdf.js1
-rw-r--r--pdf-as-web/src/main/webapp/assets/js/pdf.js/web/app.js265
-rw-r--r--pdf-as-web/src/main/webapp/assets/js/pdf.js/web/en.json34
-rw-r--r--pdf-as-web/src/main/webapp/assets/js/pdf.js/web/jquery-lang.js622
-rw-r--r--pdf-as-web/src/main/webapp/assets/js/pdf.js/web/viewer.css108
-rw-r--r--pdf-as-web/src/main/webapp/assets/js/pdf.js/web/viewer.html36
-rw-r--r--pdf-as-web/src/main/webapp/assets/js/pdf.js/web/viewer.js89
12 files changed, 2074 insertions, 143 deletions
diff --git a/pdf-as-web/src/main/webapp/assets/js/dragNdrop.js b/pdf-as-web/src/main/webapp/assets/js/dragNdrop.js
index 799b4dd6..7a5f580c 100644
--- a/pdf-as-web/src/main/webapp/assets/js/dragNdrop.js
+++ b/pdf-as-web/src/main/webapp/assets/js/dragNdrop.js
@@ -1,19 +1,22 @@
-var file = null;
+// custom insertAt Stringmethod
+String.prototype.insertAt=function(index, string) {
+ return this.substr(0, index) + string + this.substr(index);
+}
-$(document).ready(function() {
- registerEventListeners();
-});
+var default_language = "en";
+var file = null;
$(window).unload(function() {
- console.log("REFRESHED");
$("#uploadContinue").prop("disabled", true);
+ $("#uploadContinueQuick").prop("disabled", true);
$("#FileNamePreview").val("");
});
var mobile_success = false;
var local_success = false;
var keystore_success = false;
+var place_on_new_page = false;
function registerEventListeners() {
var locale = "EN";
@@ -63,6 +66,7 @@ function registerEventListeners() {
$("#FileNamePreview").val(files[0].name);
$("uploadContinue").prop("disabled", true);
+ $("uploadContinueQuick").prop("disabled", true);
file = files[0];
checkPDF(file);
@@ -74,6 +78,7 @@ function registerEventListeners() {
});
$("#PlaceStepButton").bind("click", function(evt) {
+ place_on_new_page = false;
toggleView("place");
});
$("#SignStepButton").bind("click", function(evt) {
@@ -83,6 +88,14 @@ function registerEventListeners() {
local_success = false;
keystore_success = false;
toggleView("sign");
+
+ $("#DownloadResultButton").removeAttr("disabled");
+ $("#DownloadResultButton").attr("title", "Download your Document");
+ $("#DownloadResultButton").css("pointer-events", "auto");
+
+
+
+
});
$("#FinishStepButton").bind("click", function(evt) {
@@ -94,65 +107,31 @@ function registerEventListeners() {
$("#PlaceStepButton").click();
});
-
- $("#placeContinue").bind("click", function(evt) {
+ $("#uploadContinueQuick").bind("click", function(evt) {
+ $("#iFrame").contents().find("#QuickSign").click();
+ $("#iFrame").contents().find("#delSignature").click();
+ place_on_new_page = false;
$("#SignStepButton").click();
});
- $(document).bind("keypress", function(evt) {
-
- if(evt.which == 13)
- {
- if($("#UploadStepButton").hasClass("active") && !$("#uploadContinue").prop("disabled"))
- {
- $("#PlaceStepButton").click();
- }
- else if($("#PlaceStepButton").hasClass("active"))
- {
- $("#SignStepButton").click();
- }
- }
- else if(evt.which == 8)
- {
- $("#BackBox").click();
- }
+ $("#DownloadResultButton").bind("click", function(evt) {
+ $("#DownloadResultButton").attr("disabled", "disabled");
+ $("#DownloadResultButton").attr("title", "The download is valid only once!");
+ $("#DownloadResultButton").css("pointer-events", "none");
});
- $("#QuickSign").bind("click", function(evt) {
+
+ $("#LanguageDisplay").on("click", function(evt){
- console.log("quick sign..")
- $("#iFrame").contents().find("#delSignature").click();
- $("#SignStepButton").click();
- // If you are going back from Finish to Place there should be a Signature again!
- // Maybe even where you left it before!!
+ toggleLanguage();
});
- $("#delSignatureExtern").bind("click", function(evt) {
-
- $("#iFrame").contents().find("#delSignature").click();
- })
- $("#BackBox").bind("click", function(evt) {
-
- if($("#PlaceStepButton").hasClass("active"))
- {
- $("#UploadStepButton").click();
- }
- else if($("#SignStepButton").hasClass("active"))
- {
- $("#PlaceStepButton").click();
- }
- else if($("#FinishStepButton").hasClass("active"))
- {
- $("#SignStepButton").click();
- }
- });
function toggleView(input)
{
- console.log("toggleView : " + input);
$("#DropContainer").hide();
$("#ViewContainer").hide();
@@ -174,6 +153,9 @@ function registerEventListeners() {
$("#signNavText").hide();
$("#downloadNavText").hide();
+ $("#BackBox").removeAttr("disabled");
+ $("#BackBox").css("pointer-events", "auto");
+
switch(input)
{
@@ -184,6 +166,8 @@ function registerEventListeners() {
$("#SignStepButton").css("pointer-events", "none");
$("#FinishStepButton").css("pointer-events", "none");
$("#uploadNavText").show();
+ $("#BackBox").attr("disabled", "disabled");
+ $("#BackBox").css("pointer-events", "none");
break;
case "place":
@@ -223,7 +207,11 @@ function registerEventListeners() {
$("body").addClass("wait");
$("#FileNamePreview").val(files[0].name);
- $("uploadContinue").prop("disabled", true);
+
+ $("#uploadContinue").prop("disabled", true);
+ $("#uploadContinueQuick").prop("disabled", true);
+ $("#ContinueButtonText").hide();
+ $("#MobileSpinner").show();
file = files[0];
@@ -257,7 +245,6 @@ function registerEventListeners() {
is_pdf = false;
}
- console.log("setting view now..");
setFeedbackView(is_pdf);
};
@@ -290,6 +277,9 @@ function registerEventListeners() {
$("#FormDefine").css("margin-bottom", "2.2em");
$("#uploadContinue").prop("disabled", true);
+ $("#uploadContinueQuick").prop("disabled", true);
+ $("#ContinueButtonText").show();
+ $("#MobileSpinner").hide();
}
else // if it is pdf
@@ -311,12 +301,13 @@ function registerEventListeners() {
$("#FormDefine").css("margin-bottom", "");
- $("#uploadContinue").prop("disabled", false);
+ //$("#uploadContinue").prop("disabled", false);
+ //$("#uploadContinueQuick").prop("disabled", false);
previewFile(file);
}
- $("body").removeClass("wait");
+ //$("body").removeClass("wait");
}
$("input[name='connector']").bind("change", function(evt) {
@@ -355,6 +346,8 @@ function registerEventListeners() {
$("body").addClass("wait");
sign(file, connector, locale);
});
+
+ $('[data-toggle="tooltip"]').tooltip();
}
//
@@ -388,6 +381,16 @@ function sign(file, connector, locale) {
fd.append("sig-pos-y", ifr.global_status.getSignature().posy);
fd.append("sig-pos-p", ifr.global_status.getSignature().page);
}
+ else if(place_on_new_page)
+ {
+ console.log("signature will be placed on a new page");
+ fd.append("sig-pos-p", "new");
+ place_on_new_page = false;
+ }
+ else
+ {
+ console.log("signature will be placed on bottom");
+ }
$.ajax({
url: "Sign",
@@ -423,7 +426,13 @@ function sign(file, connector, locale) {
else if(keystore_success)
{
console.log("keystore success...now switch html");
- $("#DownloadResultButton").attr("onclick", "window.open('" + response + "')");
+ $("#DownloadResultButton").attr("href", response);
+
+ var insertIndex = file.name.indexOf(".pdf");
+
+ var download_name = file.name.insertAt(insertIndex, "_signed");
+ $("#DownloadResultButton").attr("download", download_name);
+
$("#FinishStepButton").click();
keystore_success = false;
}
@@ -484,3 +493,76 @@ function clearContentDiv() {
function createIframe() {
$("#content").append("<iframe src='assets/js/pdf.js/web/viewer.html' height='863px' width='800px' id='iFrame'></iframe>");
}
+
+$(document).ready(function() {
+ window.lang = new Lang('en'); // set default language
+ window.lang.dynamic('th', 'assets/js/langpack/th.json'); // define language pack to load dynamically
+
+ // check for language cookie
+
+ var cookie_language = Cookies.get("language");
+
+ if(cookie_language && cookie_language !== default_language)
+ {
+ toggleLanguage();
+ }
+
+ registerEventListeners();
+});
+
+
+function toggleLanguage()
+{
+ if(default_language === "de")
+ {
+ $("#LanguageDisplay").html
+ (
+ "<span class='label label-info'><span class='flag-icon flag-icon-de'></span> DE</span>"
+ );
+
+ default_language = "en";
+ window.lang.change('en');
+
+ if($("#iFrame").get(0) != null) // check if ready
+ {
+ $("#iFrame").get(0).contentWindow.switchLanguage("en");
+ }
+ }
+ else
+ {
+ $("#LanguageDisplay").html
+ (
+ "<span class='label label-info'><span class='flag-icon flag-icon-gb'></span> EN</span>"
+ );
+
+ default_language = "de";
+ window.lang.change('th');
+
+ if($("#iFrame").get(0) != null)
+ {
+ $("#iFrame").get(0).contentWindow.switchLanguage("de");
+ }
+
+ }
+
+ // set Cookie
+ Cookies.set("language", default_language);
+}
+
+function GoBack() {
+
+ if($("#PlaceStepButton").hasClass("active"))
+ {
+ $("#UploadStepButton").click();
+ }
+ else if($("#SignStepButton").hasClass("active"))
+ {
+ $("#PlaceStepButton").click();
+ }
+ else if($("#FinishStepButton").hasClass("active"))
+ {
+
+ $("#SignStepButton").click();
+ }
+
+} \ No newline at end of file
diff --git a/pdf-as-web/src/main/webapp/assets/js/jquery-lang.js b/pdf-as-web/src/main/webapp/assets/js/jquery-lang.js
new file mode 100644
index 00000000..7708b6a3
--- /dev/null
+++ b/pdf-as-web/src/main/webapp/assets/js/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/js.cookie.js b/pdf-as-web/src/main/webapp/assets/js/js.cookie.js
new file mode 100644
index 00000000..c8f5b51f
--- /dev/null
+++ b/pdf-as-web/src/main/webapp/assets/js/js.cookie.js
@@ -0,0 +1,139 @@
+/*!
+ * JavaScript Cookie v2.0.3
+ * https://github.com/js-cookie/js-cookie
+ *
+ * Copyright 2006, 2015 Klaus Hartl & Fagner Brack
+ * Released under the MIT license
+ */
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(factory);
+ } else if (typeof exports === 'object') {
+ module.exports = factory();
+ } else {
+ var _OldCookies = window.Cookies;
+ var api = window.Cookies = factory();
+ api.noConflict = function () {
+ window.Cookies = _OldCookies;
+ return api;
+ };
+ }
+}(function () {
+ function extend () {
+ var i = 0;
+ var result = {};
+ for (; i < arguments.length; i++) {
+ var attributes = arguments[ i ];
+ for (var key in attributes) {
+ result[key] = attributes[key];
+ }
+ }
+ return result;
+ }
+
+ function init (converter) {
+ function api (key, value, attributes) {
+ var result;
+
+ // Write
+
+ if (arguments.length > 1) {
+ attributes = extend({
+ path: '/'
+ }, api.defaults, attributes);
+
+ if (typeof attributes.expires === 'number') {
+ var expires = new Date();
+ expires.setMilliseconds(expires.getMilliseconds() + attributes.expires * 864e+5);
+ attributes.expires = expires;
+ }
+
+ try {
+ result = JSON.stringify(value);
+ if (/^[\{\[]/.test(result)) {
+ value = result;
+ }
+ } catch (e) {}
+
+ value = encodeURIComponent(String(value));
+ value = value.replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g, decodeURIComponent);
+
+ key = encodeURIComponent(String(key));
+ key = key.replace(/%(23|24|26|2B|5E|60|7C)/g, decodeURIComponent);
+ key = key.replace(/[\(\)]/g, escape);
+
+ return (document.cookie = [
+ key, '=', value,
+ attributes.expires && '; expires=' + attributes.expires.toUTCString(), // use expires attribute, max-age is not supported by IE
+ attributes.path && '; path=' + attributes.path,
+ attributes.domain && '; domain=' + attributes.domain,
+ attributes.secure ? '; secure' : ''
+ ].join(''));
+ }
+
+ // Read
+
+ if (!key) {
+ result = {};
+ }
+
+ // To prevent the for loop in the first place assign an empty array
+ // in case there are no cookies at all. Also prevents odd result when
+ // calling "get()"
+ var cookies = document.cookie ? document.cookie.split('; ') : [];
+ var rdecode = /(%[0-9A-Z]{2})+/g;
+ var i = 0;
+
+ for (; i < cookies.length; i++) {
+ var parts = cookies[i].split('=');
+ var name = parts[0].replace(rdecode, decodeURIComponent);
+ var cookie = parts.slice(1).join('=');
+
+ if (cookie.charAt(0) === '"') {
+ cookie = cookie.slice(1, -1);
+ }
+
+ try {
+ cookie = converter && converter(cookie, name) || cookie.replace(rdecode, decodeURIComponent);
+
+ if (this.json) {
+ try {
+ cookie = JSON.parse(cookie);
+ } catch (e) {}
+ }
+
+ if (key === name) {
+ result = cookie;
+ break;
+ }
+
+ if (!key) {
+ result[name] = cookie;
+ }
+ } catch (e) {}
+ }
+
+ return result;
+ }
+
+ api.get = api.set = api;
+ api.getJSON = function () {
+ return api.apply({
+ json: true
+ }, [].slice.call(arguments));
+ };
+ api.defaults = {};
+
+ api.remove = function (key, attributes) {
+ api(key, '', extend(attributes, {
+ expires: -1
+ }));
+ };
+
+ api.withConverter = init;
+
+ return api;
+ }
+
+ return init();
+}));
diff --git a/pdf-as-web/src/main/webapp/assets/js/langpack/nonDynamic.js b/pdf-as-web/src/main/webapp/assets/js/langpack/nonDynamic.js
new file mode 100644
index 00000000..bda3e78c
--- /dev/null
+++ b/pdf-as-web/src/main/webapp/assets/js/langpack/nonDynamic.js
@@ -0,0 +1,76 @@
+Lang.prototype.pack.th = {
+ "token": {
+ "Property Search":"ค้นหา",
+ "Location":"สถานที่ตั้ง",
+ "Min Beds":"จำนวนห้องนอน",
+ "Property Type":"ชนิดที่อยู่อาศัย",
+ "Added In":"ลงประกาศเมื่อ",
+ "Show All":"แสดงผลทั้งหมด",
+ "House":"บ้าน",
+ "Town House":"ทาวน์เฮ้าส์",
+ "Apartment":"อพาร์ทเม้นท์",
+ "Condominium":"คอนโดมิเนียม",
+ "Commercial":"อาคารพาณิชย์",
+ "Office":"ออฟฟิศ",
+ "Storage":"โกดังเก็บของ",
+ "Land":"ที่ดินว่างเปล่า",
+ "Anytime":"แสดงผลทั้งหมด",
+ "Last 24 Hours":"ชั่วโมงที่ผ่านมา",
+ "Last 3 Days":"วันที่ผ่านมา",
+ "Last Week":"สัปดาห์ที่ผ่านมา",
+ "Last Month":"เดือนที่ผ่านมา",
+ "Loading":"กำลังประมวลผล",
+ "My Saved Searches":"การค้นหาที่ถูกเก็บไว้",
+ "My Listings":"รายการของฉัน",
+ "My Analytics":"สถิติผู้เข้าชมประกาศของฉัน",
+ "Search Buy":"ซื้อ",
+ "Search Rent":"เช่า",
+ "Create New Listing":"ลงประกาศ",
+ "View My Account":"ดูข้อมูลของฉัน",
+ "Property Listing Details":"รายละเอียดประกาศ",
+ "Listing Type":"ชนิดของประกาศ",
+ "Sell":"ขาย",
+ "Let":"เช่า",
+ "Lease":"เซ้ง",
+ "Floors":"ชั้น",
+ "Rooms Total":"จำนวนห้องทั้งหมด",
+ "Bedrooms":"ห้องนอน",
+ "Bathrooms":"ห้องน้ำ",
+ "Kitchens":"ครัว",
+ "Property Price and Terms":"ราคาและรูปแบบสัญญา",
+ "Price":"ราคา",
+ "Term":"สัญญา",
+ "Freehold":"มีกรรมสิทธิ์",
+ "Leasehold":"มีระยะสัญญา",
+ "Possession":"บ้านว่างหรือไม่",
+ "Onward Chain":"มีผู้อาศัยอยู่",
+ "Vacant Possession":"บ้านว่างพร้อมเข้าอยู่ทันที",
+ "Property Location":"สถานที่ตั้ง",
+ "Country":"ประเทศ",
+ "Post/Zip Code":"รหัสไปรษณีย์",
+ "No.":"เลขที่",
+ "Road Name":"ชื่อถนน",
+ "County/Province":"จังหวัด",
+ "Town/City":"อำเภอ",
+ "Lease Years Remaining":"จำนวนปีของสัญญาที่เหลือ",
+ "day":"วัน",
+ "week":"สัปดาห์",
+ "month":"เดือน",
+ "quarter":"3 เดือน",
+ "year":"ปี",
+ "Submit Your Listing":"ลงประกาศ",
+ "Upload Image":"ใส่รูป",
+ "Finish":"เสร็จเรียบร้อย",
+ "Search":"ค้นหา",
+ "Search...":"ค้นหา",
+ "Property Description":"รายละเอียดของประกาศ",
+ "Synopsis":"รายละเอียดย่อในประกาศ",
+ "Full Description":"รายละเอียดเพิ่มเติมสำหรับผู้สนใจประกาศ",
+ "Property Photos":"รูปภาพสถานที่"
+ },
+ "regex": [
+ [/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/langpack/th.json b/pdf-as-web/src/main/webapp/assets/js/langpack/th.json
new file mode 100644
index 00000000..10dfdaca
--- /dev/null
+++ b/pdf-as-web/src/main/webapp/assets/js/langpack/th.json
@@ -0,0 +1,33 @@
+{
+ "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",
+ "Finish": "Fertig",
+ "Back": "Zurück",
+ "The file type must be PDF!": "Das Dokument muss PDF Format haben!",
+ "Continue": "Weiter",
+ "Quick Sign": "Automatische Positionierung",
+ "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:",
+ "The signature will be automatically placed on the bottom": "Die Signatur wird automatisch so weit unten wie möglich platziert",
+ "Place your Signature by yourself": "Signatur manuell platzieren",
+ "Download": "Herunterladen",
+ "Auto": "Auto",
+ "Signature will be placed at the bottom of your document": "Die Signatur wird automatisch so weit unten wie möglich platziert",
+ "PDF-Signature Online": "PDF-Signatur Online",
+ "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/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