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 | 
