# HG changeset patch # User robcast # Date 1252340574 -7200 # Node ID b21acdd1fa9d736a0a369afa73c0e30d3d9d161c # Parent a256239970f845be185f76419336e021f92d2a77 zeroth version of new js skin diff -r a256239970f8 -r b21acdd1fa9d client/digitallibrary/dlInfo-js.jsp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/digitallibrary/dlInfo-js.jsp Mon Sep 07 18:22:54 2009 +0200 @@ -0,0 +1,34 @@ +<%@ page language="java" %> +<%! +// create DocumentBean instance for all JSP requests +digilib.servlet.DocumentBean docBean = new digilib.servlet.DocumentBean(); + +// initialize DocumentBean instance in JSP init +public void jspInit() { + try { + // set servlet init-parameter + docBean.setConfig(getServletConfig()); + } catch (javax.servlet.ServletException e) { + System.out.println(e); + } +} +%><% +// parsing the query +digilib.servlet.DigilibRequest dlRequest = new digilib.servlet.DigilibRequest(request); +docBean.setRequest(dlRequest); +%> +// Automatically generated JSON-style JavaScript snippet with image parameters +{ +<% + java.util.Iterator keys = dlRequest.keySet().iterator(); + while (keys.hasNext()) { + String key = (String) keys.next(); + digilib.servlet.Parameter val = dlRequest.get(key); + if (val.getType() == 'c') { + // client parameters only (and replace ".") + %><%= key.replace('.','_') %>: "<%= val.getAsString() %>"; +<% + } + } +%> +}; diff -r a256239970f8 -r b21acdd1fa9d client/digitallibrary/jskin/digilib.jsp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/digitallibrary/jskin/digilib.jsp Mon Sep 07 18:22:54 2009 +0200 @@ -0,0 +1,517 @@ + +<%@ page language="java" pageEncoding="UTF-8"%><%! + // -- JSP init ------------- + + // create DocumentBean instance for all JSP requests + digilib.servlet.DocumentBean docBean = new digilib.servlet.DocumentBean(); + + // initialize DocumentBean instance in JSP init + public void jspInit() { + try { + // set servlet init-parameter + docBean.setConfig(getServletConfig()); + } catch (javax.servlet.ServletException e) { + System.out.println(e); + } + } + // -- end of JSP init ------------- +%><% + // -- JSP request ------------- + + // parsing the query + // ----------------- + digilib.servlet.DigilibRequest dlRequest = new digilib.servlet.DigilibRequest(request); + docBean.setRequest(dlRequest); + // check if authentication is needed and redirect if necessary + docBean.doAuthentication(response); + // add number of pages + dlRequest.setValue("pt", docBean.getNumPages()); + // store objects for jsp:include + pageContext.setAttribute("docBean", docBean, pageContext.REQUEST_SCOPE); + +%> + + + Digital Document Library JQ + + + + + + + + + +
+ huhu! +
+ + +
+
+ + +
+ + + + + +
+ + + + + + + + +
+

Digilib Graphic Viewer

+ + + +

+

+

+

+
+ + +
+
+

measure the length of this scale on your screen

+
+
+ + + + + + + + +
+
+
+ +
+ + + + +
+ +
+ + + + +
+ +
+ + + + +
+ +
+ + + + +
+ +
+ + + + +
+ +
+ + + + +
+ +
+ + + + +
+ +
+ + + + +
+ +
+ + + + +
+ +
+ + + + +
+ +
+
+ +
+ + + + +
+ +
+ + + + +
+ +
+
+
+ + + +
+
+
+ +
+ + + + +
+ +
+ + + + +
+ +
+ + + + +
+ +
+ + + + +
+ +
+ + + + +
+ +
+ + + + +
+ +
+ + + + +
+ +
+ + + + +
+ +
+ + + + +
+ +
+ + + + +
+ +
+ + + + +
+ +
+ + + + +
+ +
+
+ +
+ + + + +
+ +
+
+ +
+ + + + diff -r a256239970f8 -r b21acdd1fa9d client/digitallibrary/jskin/diginew.css --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/digitallibrary/jskin/diginew.css Mon Sep 07 18:22:54 2009 +0200 @@ -0,0 +1,257 @@ +/* Styles for Digilib NG */ +/* (c) 2005 by Martin Raspe */ +/* Bibliotheca Hertziana (Max-Planck-Institute for Art History), Rome */ + +body { + background-color: #E0E0E0; + color: black; + font-size: 8pt; + } + +code { + font-family: monospace; + color: blue; + } + +pre { color: #006060; } + + +a.icon { + margin: 0px; + padding: 0px; + } + +a.arrow { + display: block; + position: absolute; + border: none; + z-index: 50; + background-repeat: no-repeat; + background-position: center; + } + +a#up:hover { + background-image: url('up.png'); + } + +a#down:hover { + background-image: url('down.png'); + } + +a#left:hover { + background-image: url('left.png'); + } + +a#right:hover { + background-image: url('right.png'); + } + +/* Images */ + +img.logo { + border: none; + } + +img.png { + border: none; + } + +img.png:hover { + background-image: url('corona.png'); + } + +img#bird-image { + border: none; + position: fixed; + bottom: 10px; + right: 10px; + visibility: hidden; + z-index: 1; + } + +/* DIVs */ + +div.button { + padding: 0px; + } + +div.separator { + margin-bottom: 4px; + border-top: 2px solid lightgrey; + } + +div.mark { + position: absolute; + color: white; + background: url('mark-bg-16.png'); + font-family: Verdana, Arial, Helvetica, sans-serif; + font-weight: bold; + font-size:11px; + height: 15px; + width: 16px; + padding-top: 1px; + text-align: center; + z-index: 10; + /* filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='mark-bg-16.png') */ + } + +div#scaler { +/* position: absolute; + left: 8px; + top: 8px; + bottom: 30px; + right: 44px; +*/ /* overflow: auto; */ + } + +div#overlay, div#bird-overlay { + position: fixed; + background-color: transparent; + border: 1px solid lightgrey; + z-index: 100; + visibility: hidden; + /* box-sizing: border-box; + -moz-box-sizing: border-box; */ + } + +div#buttons { + position: fixed; + right: 5px; + top: 5px; + padding: 3px; +/* background-color: #E0E0E0; */ + background-color: lightgrey; + } + +div#dloptions { + position: fixed; + right: 5px; + top: 5px; + padding: 3px; +/* background-color: #E0E0E0; */ + background-color: lightgrey; + visibility: hidden; + } + +div#zoom { + position: absolute; + /* border: 2px solid #ffa060; */ + border: 2px solid #ff0000; + visibility: hidden; + z-index: 200; + /* box-sizing: border-box; + -moz-box-sizing: border-box; */ + } + +div#bird-area { + position: fixed; + /* border: 2px solid #ffa060; */ + border: 2px solid #ff0000; + visibility: hidden; + background-color: transparent; + /* box-sizing: border-box; + -moz-box-sizing: border-box; */ + z-index: 10; + } + +div#calibration { + background: url('blue.png'); + position: absolute; + width: 400px; + padding: 0px; + visibility: hidden; + z-index: 1000; + } + +div#calibration div { + width: 100%; + height: 100%; + margin: 0px; + padding: 0px; + font-family: Verdana, Arial, Helvetica, sans-serif; + text-align: center; + color: lightcyan; + border: 1px solid lightcyan; + background: url('ruler-top.gif') 0px -1px repeat-x; + z-index: 1001; + } + +p.cm { + font-weight: bold; + } + +div.popup-menu { + position: absolute; + padding: 0px 2px; + font-family: Verdana, Arial, Helvetica, sans-serif; + border: 2px solid lightcyan; + background-color: lightgrey; + text-align: center; + visibility: hidden; + z-index: 1005; + } + +div.popup-menu p { + margin: 2px 0px; + padding: 0px; + } + +div.popup-menu p:hover { + background-color: #ffa060; + } + +div.popup-menu a { + text-decoration: none; + color: black; + } + +div#about { + position: absolute; + width: 200px; + top: 100px; + left: 350px; + height: 200px; + padding: 0px 2px; + font-family: Verdana, Arial, Helvetica, sans-serif; + border: 2px solid lightcyan; + background-color: lightgrey; + text-align: center; + visibility: hidden; + z-index: 1000; + } + +div#about p { + margin: 6px; + } + + +/* DEBUG elements */ + +div#debug { + position: absolute; + width: 150px; + top: 50px; + right: 36px; + bottom: 50px; + overflow: auto; + padding: 0px 2px; + font-family: Verdana, Arial, Helvetica, sans-serif; + color: lightgreen; + border: 1px dotted black; + background-color: transparent; + visibility: hidden; + } + +div#debug p.debug, h1 { + font-weight: bold; + color: lightcyan; + } + +div#debug p, h1 { + margin: 0px; + padding: 2px 0px; + font-size: 9px; + background-color: black; + } + + diff -r a256239970f8 -r b21acdd1fa9d client/digitallibrary/jskin/diginew.jsp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/digitallibrary/jskin/diginew.jsp Mon Sep 07 18:22:54 2009 +0200 @@ -0,0 +1,600 @@ + +<%@ page language="java" pageEncoding="UTF-8"%><%! + // -- JSP init ------------- + + // create DocumentBean instance for all JSP requests + digilib.servlet.DocumentBean docBean = new digilib.servlet.DocumentBean(); + + // initialize DocumentBean instance in JSP init + public void jspInit() { + try { + // set servlet init-parameter + docBean.setConfig(getServletConfig()); + } catch (javax.servlet.ServletException e) { + System.out.println(e); + } + } + // -- end of JSP init ------------- +%><% + // -- JSP request ------------- + + // parsing the query + // ----------------- + digilib.servlet.DigilibRequest dlRequest = new digilib.servlet.DigilibRequest(request); + docBean.setRequest(dlRequest); + // check if authentication is needed and redirect if necessary + docBean.doAuthentication(response); + // add number of pages + dlRequest.setValue("pt", docBean.getNumPages()); + // store objects for jsp:include + pageContext.setAttribute("docBean", docBean, pageContext.REQUEST_SCOPE); + +%> + + + Digital Document Library NG + + + + + + + + + + + + + + +
+ +
+ + +
+
+ + +
+ + + + + +
+ + + + + + + + +
+

Digilib Graphic Viewer

+ + + +

+

+

+

+
+ + +
+
+

measure the length of this scale on your screen

+
+
+ + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + +
+
+
+ + + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+
+ +
+ +

Debug

+ + + + diff -r a256239970f8 -r b21acdd1fa9d client/digitallibrary/jskin/dl-baselib.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/digitallibrary/jskin/dl-baselib.js Mon Sep 07 18:22:54 2009 +0200 @@ -0,0 +1,917 @@ +/* Copyright (C) 2003-2009 IT-Group MPIWG, WTWG Uni Bern and others + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + +Authors: + Christian Luginbuehl, 01.05.2003 (first version) + DW 24.03.2004 (Changed for digiLib in Zope) + Robert Casties, 2.11.2004 (almost complete rewrite) + Martin Raspe, 12.12.2005 (changes for Digilib NG) + Robert Casties, 3.9.2009 +*/ + +// was: function base_init() { +baseLibVersion = "3.001"; +browserType = getBrowserType(); + +function getInt(n) { + // returns always an integer + n = parseInt(n); + return (isNaN(n)) ? 0 : n; +} + +function defined(x) { + // returns if x is defined + return (typeof arguments[0] != "undefined"); +} + +function cropFloat(x) { + // auxiliary function to crop senseless precision + return parseInt(10000 * x) / 10000; +} + +function getBrowserType() { + // browser sniffer + var bt = Object(); + bt.doDHTML = false; + bt.versIE = 0; + + if ((! document.cssonly && document.layers) || document.all || document.getElementById) { + var vers = navigator.appVersion.split('MSIE '); + vers = vers[vers.length - 1]; + bt.versIE = getInt(vers); + bt.isIE = navigator.userAgent.indexOf('MSIE') >= 0; + bt.isMac = navigator.platform.indexOf('Mac') >= 0; + bt.isWin = navigator.platform.indexOf('Win') >= 0; + bt.isN4 = (navigator.userAgent.indexOf('Mozilla/4.') >= 0) && ! bt.isIE; + bt.isIEWin = bt.versIE > 0 && bt.isWin; + if (navigator.appVersion.indexOf('MSIE') < 0 || ! bt.isMac || bt.versIE >= 5) { + bt.doDHTML = true; + bt.isOpera = navigator.userAgent.indexOf(' Opera ') >= 0; + bt.isKonq = navigator.userAgent.indexOf(' Konqueror') >= 0; + } + } + return bt; +} + + +/* ********************************************** + * geometry classes + * ******************************************** */ + +/* + * Size class + */ +function Size(w, h) { + this.width = parseFloat(w); + this.height = parseFloat(h); + return this; +} +Size.prototype.toString = function() { + return this.width + "x" + this.height; +} +Size.prototype.equals = function(other) { + return (this.width == other.width + && this.height == other.height) + } + +/* + * Position class + */ +function Position(x, y) { + this.x = parseFloat(x); + this.y = parseFloat(y); + return this; +} +Position.prototype.toString = function() { + return this.x + "," + this.y; +} +Position.prototype.equals = function(other) { + return (this.x == other.x + && this.y == other.y) +} +/* + * Rectangle class + */ +function Rectangle(x, y, w, h) { + if (typeof x == "object") { + // assume x and y are Position + this.x = x.x; + this.y = x.y; + this.width = y.x - x.x; + this.height = y.y - x.y; + return this; + } + this.x = parseFloat(x); + this.y = parseFloat(y); + this.width = parseFloat(w); + this.height = parseFloat(h); + return this; +} +Rectangle.prototype.toString = function() { + return this.width+"x"+this.height+"@"+this.x+","+this.y; +} +Rectangle.prototype.copy = function() { + // returns a copy of this Rectangle + return new Rectangle(this.x, this.y, this.width, this.height); +} +Rectangle.prototype.getPosition = function() { + // returns the position of this Rectangle + return new Position(this.x, this.y); +} +Rectangle.prototype.getPt1 = Rectangle.prototype.getPosition; +// returns the upper left corner position + +Rectangle.prototype.getPt2 = function() { + // returns the lower right corner position of this Rectangle + return new Position(this.x + this.width, this.y + this.height); +} +Rectangle.prototype.setPt1 = function(pos) { + // sets the upper left corner to position pos + this.x = pos.x; + this.y = pos.y; + return this; +} +Rectangle.prototype.setPt2 = function(pos) { + // sets the lower right corner to position pos + this.width = pos.x - this.x; + this.height = pos.y - this.y; + return this; +} +Rectangle.prototype.getCenter = function() { + // returns the center position of this Rectangle + return new Position(this.x + this.width / 2, this.y + this.height / 2); +} +Rectangle.prototype.setCenter = function(pos) { + // moves this Rectangle's center to position pos + this.x = pos.x - this.width / 2; + this.y = pos.y - this.height / 2; + return this; +} +Rectangle.prototype.getSize = function() { + // returns the size of this Rectangle + return new Size(this.width, this.height); +} +Rectangle.prototype.equals = function(other) { + // equal props + return (this.getPosition().equals(other.getPosition()) + && this.getSize().equals(other.getSize()) + ); +} +Rectangle.prototype.getArea = function() { + // returns the area of this Rectangle + return (this.width * this.height); +} +Rectangle.prototype.normalize = function() { + // eliminates negative width and height + var p = this.getPt2(); + this.x = Math.min(this.x, p.x); + this.y = Math.min(this.y, p.y); + this.width = Math.abs(this.width); + this.height = Math.abs(this.height); + return this; +} +Rectangle.prototype.containsPosition = function(pos) { + // returns if Position "pos" lies inside of this rectangle + return ((pos.x >= this.x) + && (pos.y >= this.y) + && (pos.x <= this.x + this.width) + && (pos.y <= this.y + this.width) + ); +} +Rectangle.prototype.containsRect = function(rect) { + // returns if rectangle "rect" is contained in this rectangle + return (this.containsPosition(rect.getPt1()) + && this.containsPosition(rect.getPt2())); +} +Rectangle.prototype.stayInside = function(rect) { + // changes this rectangle's x/y values so it stays inside of rectangle rect + // keeping the proportions + if (this.x < rect.x) this.x = rect.x; + if (this.y < rect.y) this.y = rect.y; + if (this.x + this.width > rect.x + rect.width) + this.x = rect.x + rect.width - this.width; + if (this.y + this.height > rect.y + rect.height) + this.y = rect.y + rect.height - this.height; + return this; +} +Rectangle.prototype.clipTo = function(rect) { + // clips this rectangle so it stays inside of rectangle rect + var p1 = rect.getPt1(); + var p2 = rect.getPt2(); + var this2 = this.getPt2(); + this.setPt1(new Position(Math.max(this.x, p1.x), Math.max(this.y, p1.y))); + this.setPt2(new Position(Math.min(this2.x, p2.x), Math.min(this2.y, p2.y))); + return this; +} +Rectangle.prototype.intersect = function(rect) { + // returns the intersection of the given Rectangle and this one + // FIX ME: not really, it should return null if there is no overlap + var sec = rect.copy(); + if (sec.x < this.x) { + sec.width = sec.width - (this.x - sec.x); + sec.x = this.x; + } + if (sec.y < this.y) { + sec.height = sec.height - (this.y - sec.y); + sec.y = this.y; + } + if (sec.x + sec.width > this.x + this.width) { + sec.width = (this.x + this.width) - sec.x; + } + if (sec.y + sec.height > this.y + this.height) { + sec.height = (this.y + this.height) - sec.y; + } + return sec; +} +Rectangle.prototype.fit = function(rect) { + // returns a Rectangle that fits into this one (by moving first) + var sec = rect.copy(); + sec.x = Math.max(sec.x, this.x); + sec.y = Math.max(sec.y, this.x); + if (sec.x + sec.width > this.x + this.width) { + sec.x = this.x + this.width - sec.width; + } + if (sec.y + sec.height > this.y + this.height) { + sec.y = this.y + this.height - sec.height; + } + return sec.intersect(this); +} + +/* + * Transform class + * + * defines a class of affine transformations + */ +function Transform() { + this.m00 = 1.0; + this.m01 = 0.0; + this.m02 = 0.0; + this.m10 = 0.0; + this.m11 = 1.0; + this.m12 = 0.0; + this.m20 = 0.0; + this.m21 = 0.0; + this.m22 = 1.0; + return this; +} +Transform.prototype.concat = function(traf) { + // add Transform traf to this Transform + for (var i = 0; i < 3; i++) { + for (var j = 0; j < 3; j++) { + var c = 0.0; + for (var k = 0; k < 3; k++) { + c += traf["m"+i+k] * this["m"+k+j]; + } + this["m"+i+j] = c; + } + } + return this; +} +Transform.prototype.transform = function(rect) { + // returns transformed Rectangle or Position with this Transform applied + var x = this.m00 * rect.x + this.m01 * rect.y + this.m02; + var y = this.m10 * rect.x + this.m11 * rect.y + this.m12; + if (rect.width) { + // transform the other corner points + var pt2 = rect.getPt2(); + var x2 = this.m00 * pt2.x + this.m01 * pt2.y + this.m02; + var y2 = this.m10 * pt2.x + this.m11 * pt2.y + this.m12; + var width = x2 - x; + var height = y2 - y; + return new Rectangle(x, y, width, height); + } + return new Position(x, y); +} +Transform.prototype.invtransform = function(rect) { + // returns transformed Rectangle or Position with the inverse of this Transform applied + var det = this.m00 * this.m11 - this.m01 * this.m10; + var x = (this.m11 * rect.x - this.m01 * rect.y - this.m11 * this.m02 + this.m01 * this.m12) / det; + var y = (- this.m10 * rect.x + this.m00 * rect.y + this.m10 * this.m02 - this.m00 * this.m12) / det; + if (rect.width) { + /* transforming width and height like points seems to be wrong + var width = (this.m11 * rect.width - this.m01 * rect.height - this.m11 * this.m02 + this.m01 * this.m12) / det; + var height = (- this.m10 * rect.width + this.m00 * rect.height + this.m10 * this.m02 - this.m00 * this.m12) / det; + */ + // transform the other corner points + var pt2 = rect.getPt2(); + var x2 = (this.m11 * pt2.x - this.m01 * pt2.y - this.m11 * this.m02 + this.m01 * this.m12) / det; + var y2 = (- this.m10 * pt2.x + this.m00 * pt2.y + this.m10 * this.m02 - this.m00 * this.m12) / det; + var width = x2 - x; + var height = y2 - y; + return new Rectangle(x, y, width, height); + } + return new Position(x, y); +} +function getRotation(angle, pos) { + // returns a Transform that is a rotation by angle degrees around [pos.x, pos.y] + var traf = new Transform(); + if (angle != 0) { + var t = 2.0 * Math.PI * parseFloat(angle) / 360.0; + traf.m00 = Math.cos(t); + traf.m01 = - Math.sin(t); + traf.m10 = Math.sin(t); + traf.m11 = Math.cos(t); + traf.m02 = pos.x - pos.x * Math.cos(t) + pos.y * Math.sin(t); + traf.m12 = pos.y - pos.x * Math.sin(t) - pos.y * Math.cos(t); + } + return traf; +} +Transform.prototype.getRotation = getRotation; +function getTranslation(pos) { + // returns a Transform that is a translation by [pos.x, pos,y] + var traf = new Transform(); + traf.m02 = pos.x; + traf.m12 = pos.y; + return traf; +} +Transform.prototype.getTranslation = getTranslation; +function getScale(size) { + // returns a Transform that is a scale by [size.width, size.height] + var traf = new Transform(); + traf.m00 = size.width; + traf.m11 = size.height; + return traf; +} +Transform.prototype.getScale = getScale; + + +/* + * parameters class + */ + +function Parameters() { + this.params = new Object(); + this.PARAM_ALL = 65535; + return this; +} +Parameters.prototype.define = function(name, defaultValue, detail) { + // create a new parameter with a name and a default value + if (!this.params[name]) this.params[name] = new Object(); + this.params[name].defaultValue = defaultValue; + this.params[name].hasValue = false; + this.params[name].value = defaultValue; + this.params[name].detail = detail; + return this.params[name]; +} +Parameters.prototype.reset = function(name) { + // resets the given parameter to its default value + if (!this.params[name]) { + alert("Could not reset non-existing parameter '" + name + "'"); + return false; + } + this.params[name].hasValue = false; + this.params[name].value = this.params[name].defaultValue; + return this.params[name]; +} +Parameters.prototype.resetAll = function() { + // resets all parameters to their default values + for (var p in this.params) { + this.reset(p); + } + return true; +} +Parameters.prototype.remove = function(name) { + if (!defined(this.params[name])) return false; + delete this.params[name]; + return true; +} +Parameters.prototype.get = function(name) { + // returns the named parameter value or its default value + if (!defined(this.params[name])) return null; + return this.params[name].hasValue ? this.params[name].value : this.params[name].defaultValue; +} +Parameters.prototype.set = function(name, value, relative) { + // sets parameter value (relative values with +/- if relative=true) + if (!defined(this.params[name])) return null; + var p = this.params[name]; + if (relative && value.slice) { + // value is a string -- check if it starts with +/- + var sign = value.slice(0, 1); + if (sign == '+') { + p.value = parseFloat(p.value) + parseFloat(value.slice(1)); + } else if (sign == '-') { + p.value = parseFloat(p.value) - parseFloat(value.slice(1)); + } else { + p.value = value; + } + } else { + p.value = value; + } + p.hasValue = true; + return p.value; +} +Parameters.prototype.isSet = function(name) { + // returns if the parameter's value has been set + if (!defined(this.params[name])) return null; + return this.params[name].hasValue; +} +Parameters.prototype.getAll = function(detail) { + // returns a string of all parameters in query format + if (!detail) detail = this.PARAM_ALL; + var pa = new Array(); + for (p in this.params) { + if (((this.params[p].detail & detail) > 0) + && (this.params[p].hasValue)) { + var val = this.params[p].value; + if (val != "") { + pa.push(p + "=" + val); + } + } + } + return pa.join("&"); +} +Parameters.prototype.parse = function(query) { + // gets parameter values from query format string + var pa = query.split("&"); + for (var i = 0; i < pa.length; i++) { + var keyval = pa[i].split("="); + if (keyval.length == 2) { + this.set(keyval[0], keyval[1]); + } + } +} + +/* + * Flags class + * + * Flags are (hash-) collections of unique strings. + */ +function Flags() { + this.flags = new Object(); + return this; +} +Flags.prototype.define = function(name, detail) { + // create a new flag with a name and detail level + this.flags[name] = new Object(); + this.flags[name].set = false; + this.flags[name].detail = detail; + return this.flags[name]; +} +Flags.prototype.get = function(name) { + return (this.flags[name]) ? this.flags[name].set : false; +} +Flags.prototype.set = function(name, value) { + if (!defined(value)) value = true; + if (!this.flags[name]) this.flags[name] = new Object; + this.flags[name].set = value; +} +Flags.prototype.reset = function(name) { + if (!this.flags[name]) this.flags[name] = new Object; + this.flags[name].set = false; +} +Flags.prototype.toggle = function(name) { + if (!this.flags[name]) this.flags[name] = new Object; + this.flags[name].set = !this.flags[name].set; +} +Flags.prototype.resetAll = function() { + for (var f in this.flags) { + this.flags[f].set = false; + } +} +Flags.prototype.parse = function(query, sep) { + // sets the flags from the string query + if (!sep) sep = ","; + var fa = query.split(sep); + for (var i = 0; i < fa.length ; i++) { + var f = fa[i]; + if (f != "") { + this.set(f); + } + } +} +Flags.prototype.getAll = function(detail, sep) { + // returns a string of all flags in query format + if (!detail) detail = 255; + if (!sep) sep = ","; + var fa = new Array(); + for (f in this.flags) { + if (this.flags[f].set) { + // if the flag has a detail level it must match + // otherwise we assume detail=128 + if (this.flags[f].detail) { + if ((this.flags[f].detail & detail) > 0) { + fa.push(f); + } + } else { + if ((detail & 128) > 0) { + fa.push(f); + } + } + } + } + return fa.join(sep); +} + + +/* ********************************************** + * HTML/DOM routines + * ******************************************** */ + +function getElement(tagid, quiet) { + // returns the element object with the id tagid + return $("#"+tagid); +} + +function getElementPosition(elem) { + // returns a Position with the position of the element + var x = 0; + var y = 0; + var id = elem.getId(); + return new Position(getInt(x), getInt(y)); +} + +function getElementSize(elem) { + // returns a Rectangle with the size of the element + var width = 0; + var height = 0; + if (defined(elem.offsetWidth)) { + width = elem.offsetWidth; + height = elem.offsetHeight; + } else if (defined(elem.width)) { + width = elem.width; + height = elem.height; + } else if (defined(elem.clip.width)) { + width = elem.clip.width; + height = elem.clip.height; + } else { + alert("unable to get size of " + elem + " (id:" + elem.id + ")"); + } + return new Size(getInt(width), getInt(height)); +} + +function getElementRect(elem) { + // returns a Rectangle with the size and position of the element + // FIX ME: what about borders? + var pos = getElementPosition(elem); + var size = getElementSize(elem); + return new Rectangle(pos.x, pos.y, size.width, size.height); +} + +function moveElement(elem, rect) { + // moves and sizes the element + if (elem.style) { + if (defined(rect.x)) { + elem.style.left = Math.round(rect.x) + "px"; + elem.style.top = Math.round(rect.y) + "px"; + } + if (defined(rect.width)) { + elem.style.width = Math.round(rect.width) + "px"; + elem.style.height = Math.round(rect.height) + "px"; + } + } else if (document.layers) { + if (defined(rect.x)) { + elem.pageX = getInt(rect.x); + elem.pageY = getInt(rect.y); + } + if (defined(rect.width)) { + elem.clip.width = getInt(rect.width); + elem.clip.height = getInt(rect.height); + } + } else { + alert("moveElement(): element has no style or layer property!"); + return false; + } + return true; +} + +function showElement(elem, show) { + // shows or hides the element + if (elem.style) + elem.style.visibility = show ? "visible" : "hidden"; + else if (defined(elem.visibility)) + elem.visibility = show ? "show" : "hide"; + else + alert("showElement(): element has no style or layer property!"); + return true; +} + +function evtPosition(evt) { + // returns the on-screen Position of the Event + var x; + var y; + evt = (evt) ? evt : window.event; + if (!evt) { + alert("no event found! " + evt); + return; + } + if (defined(evt.pageX)) { + x = parseInt(evt.pageX); + y = parseInt(evt.pageY); + } else if (defined(evt.clientX)) { + x = parseInt(document.body.scrollLeft + evt.clientX); + y = parseInt(document.body.scrollTop + evt.clientY); + } else { + alert("evtPosition(): don't know how to deal with " + evt); + } + return new Position(x, y); +} + +function registerEvent(type, elem, handler) { + // register the given event handler on the indicated element + if (elem.addEventListener) { + elem.addEventListener(type, handler, false); // bubble + } + else if (elem.attachEvent) { + elem.attachEvent("on" + type, handler); + } + else if (elem.captureEvents) { + if (Event) { + t = type.toUpperCase(); + elem.captureEvents(Event[t]); + elem[ "on" + type ] = handler; + } + } + else { + alert("Could not register event of type " + type); + return false; + } + return true; + } + +function unregisterEvent(type, elem, handler) { + // unregister the given event handler from the indicated element + if (elem.removeEventListener) { + elem.removeEventListener(type, handler, false); + } + else if (elem.detachEvent) { + elem.detachEvent("on" + type, handler); + } + else if (elem.releaseEvents) { + if (Event) { + t = type.toUpperCase(); + elem.releaseEvents(Event[t]); + elem[ "on" + type ] = null; + } + } + else { + alert("Could not register event of type " + type); + return false; + } + return true; +} + +function registerEventById(type, id, handler) { + registerEvent(type, getElement(id), handler); + } + +function unregisterEventById(type, id, handler) { + unregisterEvent(type, getElement(id), handler); + } + +function stopEvent(e) { + if (!e) var e = window.event; + e.cancelBubble = true; + if (e.stopPropagation) e.stopPropagation(); + return false; +} + +function getEventSrc(e) { + if (e.target) return e.target; + if (e.srcElement) return e.srcElement; +} + +// old registerXXYY API for compatibility +function registerMouseDown(elem, handler) { + return registerEvent("mousedown", elem, handler); +} +function unregisterMouseDown(elem, handler) { + return unregisterEvent("mousedown", elem, handler); +} +function registerMouseMove(elem, handler) { + return registerEvent("mousemove", elem, handler); +} +function unregisterMouseMove(elem, handler) { + return unregisterEvent("mousemove", elem, handler); +} +function registerKeyDown(handler) { + return registerEvent("keypress", elem, handler); +} + + +function getWinSize() { + // returns a Size with the current window size (mostly from www.quirksmode.org) + var wsize = new Size(100, 100); + if (defined(self.innerHeight)) { + // all except Explorer + if ((self.innerWidth == 0)||(self.innerHeight == 0)) { + // Safari 1.2 (and other) bug + if (parent) { + wsize.height = parent.innerHeight; + wsize.width = parent.innerWidth; + } + } else { + wsize.width = self.innerWidth; + wsize.height = self.innerHeight; + } + } else if (document.documentElement && document.documentElement.clientHeight) { + // Explorer 6 Strict Mode + wsize.width = document.documentElement.clientWidth; + wsize.height = document.documentElement.clientHeight; + } else if (document.body) { + // other Explorers + wsize.width = document.body.clientWidth; + wsize.height = document.body.clientHeight; + } + return wsize; +} + +function getWinRect() { + var size = getWinSize(); + return new Rectangle(0, 0, size.width, size.height); +} + +function openWin(url, name, params) { + // open browser window + var ow = window.open(url, name, params); + ow.focus(); +} + +/* ********************************************** + * cookie class + * ******************************************** */ + +function Cookie() { + return this.read(); +} + +Cookie.prototype.read = function() { + var s = document.cookie; + var lines = s.split("; "); // semicolon and space for all browsers? + for (var i in lines) { + var line = lines[i]; + var sep = line.indexOf("="); + if (sep != -1) this.add( + line.substr(0, sep), + line.substr(sep + 1) + ); + } + return this; +} + +Cookie.prototype.store = function() { + var lines = new Array(); + for (var i in this) { + var item = this[i]; + if (typeof(item) == typeof(lines)) // Array + lines.push(i + "=" + item.join(",")); + else if (typeof(item) != "function") // single item + lines.push(i + "=" + item); + } + // var s = lines.join(";") + for (line in lines) document.cookie = lines[line]; + return this; + } + +Cookie.prototype.add = function(key, value) { + value = value.toString(); + if (value.indexOf(",") == -1) + this[key] = value; // single value + else + this[key] = value.split(","); // list of values + return this[key]; + } + +Cookie.prototype.get = function(key) { + return this[key]; + } + +Cookie.prototype.addbool = function(key, value) { + this[key] = Boolean(value).toString(); + return this[key]; + } + +Cookie.prototype.getbool = function(key) { + var val = this[key]; + return (val > "") && (val != "0") && (val != "false"); + } + +Cookie.prototype.remove = function(key) { + delete this[key]; + } + +function Slider(id, valMin, valMax, valStart, stepSize, onChange) { + // a (horizontal) slider widget + this.id = id; + this.elem = getElement(id); + this.slider = getElement(id + "-slider"); // the slider handle + this.input = getElement(id + "-input", 1); // optional input field + this.bar = getElement(id + "-bar"); // the slider bar + this.barRect = getElementRect(this.bar); + this.sliderRect = getElementRect(this.slider); + this.xMin = this.barRect.x; + this.xMax = this.xMin + this.barRect.width; + this.xDiff = this.xMax - this.xMin; + this.Y = this.barRect.getCenter().y; // middle axis of bar + this.valMin = valMin; + this.valMax = valMax; + this.valDiff = Math.abs(valMax - valMin); + this.valStart = valStart; + this.value = valStart; + this.stepSize = stepSize; + this.valueLabel = getElement(id + "-value", 1); + this.valMinLabel = getElement(id + "-valmin", 1); + this.valMaxLabel = getElement(id + "-valmax", 1); + this.onChange = onChange ? onChange : function() {}; + this.update(); + this.activate(); + sliders[id + '-slider'] = this; // make a handle to the object + return this; + } + +Slider.prototype.show = function(show) { + showElement(this.elem, show); + this.activate(); + } + +Slider.prototype.activate = function() { + this.setupEvents(); + } + +Slider.prototype.deactivate = function() { + unregisterEvent("mousedown", this.slider, this.onDragStart); + } + +Slider.prototype.reset = function() { + this.setValue(this.startVal); + } + +Slider.prototype.setValue = function(newVal) { + // sets slider to new value and updates + this.value = newVal; + this.update(); + } + +Slider.prototype.calcValue = function() { + // calculates value from slider position + var xSlider = this.sliderRect.getCenter().x - this.xMin; + this.value = xSlider * this.valDiff / this.xDiff; + return this.value; + } + +Slider.prototype.update = function() { + // updates slider position to new value + var xSlider = this.value * this.xDiff / this.valDiff; + moveElement(this.slider, this.sliderRect.setCenter( + new Position(xSlider + this.xMin, this.Y))); + var strVal = this.value.toString(); + if (this.valueLabel) this.valueLabel.innerHTML = strVal; + if (this.input) this.input.value = strVal; + } + +Slider.prototype.setupEvents = function() { + // installs all event callbacks + registerEvent("mousedown", this.slider, this.onDragStart); + } + +Slider.prototype.onDragStart = function(evt) { + var slider = sliders[this.id]; + activeSlider = slider; + unregisterEvent("mousedown", slider.slider, slider.onDragStart); + registerEvent("mousemove", document, slider.onDrag); + registerEvent("mouseup", document, slider.onDragEnd); + slider.startPos = evtPosition(evt); + slider.startX = slider.sliderRect.getCenter().x; + return stopEvent(evt); + } + +Slider.prototype.onDrag = function(evt) { + var slider = activeSlider; + var pos = evtPosition(evt); + var currX = slider.slider + var newX = pos.x - slider.startPos + slider.startX; + if (newX < slider.xMin) newX = slider.xMin; + if (newX > slider.xMax) newX = slider.xMax; + moveElement(slider.slider, slider.sliderRect.setCenter( + new Position(newX, slider.Y))); + return stopEvent(evt); + } + +Slider.prototype.onDragEnd = function(evt) { + var slider = activeSlider; + unregisterEvent("mousemove", document, slider.onDrag); + unregisterEvent("mouseup", document, slider.onDragEnd); + slider.onChange(slider.calcValue()); + activeSlider = null; + return stopEvent(evt); + } + +Slider.prototype.onInputChange = function() { + var slider = activeSlider; + slider.onChange(s.value); + } + +// :tabSize=4:indentSize=4:noTabs=true: + diff -r a256239970f8 -r b21acdd1fa9d client/digitallibrary/jskin/dllib.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/digitallibrary/jskin/dllib.js Mon Sep 07 18:22:54 2009 +0200 @@ -0,0 +1,978 @@ +/* Copyright (C) 2003,2004 IT-Group MPIWG, WTWG Uni Bern and others + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + +Authors: + Christian Luginbuehl, 01.05.2003 (first version) + DW 24.03.2004 (Changed for digiLib in Zope) + Robert Casties, 8.11.2005 + Martin Raspe , 12.12.2005 + Robert Casties, 4.9.2009 + + ! Requires baselib.js ! +*/ +digilibVersion = "Digilib JQ"; +dllibVersion = "3.001"; + +function identify() { + // used for identifying a digilib instance + // Relato uses that function - lugi + return digilibVersion; +} + +function createMarkDiv(index) { + var div = document.createElement("div"); + div.className = "mark"; + div.id = "mark" + index; + div.innerHTML = index + 1; + document.body.appendChild(div); + return div; +} + +function bestPicSize(elem, inset) { + // returns a Size with the best image size for the given element + if (! defined(inset)) { + inset = 25; + } + var ws = getWinSize(); + var es = getElementPosition(elem); + if (es) { + ws.width = ws.width - es.x - inset; + ws.height = ws.height - es.y - inset; + } + return ws; +} + + +/**************************************************** + * digilib specific classes (must be defined first) + ****************************************************/ + +/* + * Marks class + */ +function DLMarks() { + return this; +} +// Marks inherits from Array +DLMarks.prototype = new Array(); +DLMarks.prototype.parse = function(query) { + this.length = 0; + if (query.indexOf(";") >= 0) { + var pa = query.split(";"); // old format with ";" + } else { + var pa = query.split(","); // new format + } + for (var i = 0; i < pa.length ; i++) { + var pos = pa[i].split("/"); + if (pos.length > 1) this.push(new Position(pos[0], pos[1])); + } +} +DLMarks.prototype.getAll = function() { + var ma = new Array(); + for (var i = 0; i < this.length; i++) { + ma.push(cropFloat(this[i].x) + "/" + cropFloat(this[i].y)); + } + return ma.join(","); +} +DLMarks.prototype.addEvent = function(evt, digilib) { + // add a mark from a screen event + if (!digilib) digilib = dl; + var pos = digilib.trafo.invtransform(evtPosition(evt)); + this.push(pos); +} + +/* + * DLParameters -- digilib parameter class + */ +function DLParameters() { + // flags for parameter sets + this.PARAM_FILE = 1; + this.PARAM_MODE = 2; + this.PARAM_DIM = 4; + this.PARAM_IMAGE = 8; + this.PARAM_DPI = 16; + this.PARAM_SIZE = 32; + this.PARAM_MARK = 64; + this.PARAM_PAGES = 128; + this.PARAM_CLIENT = 256; + /* request parameters */ + with (this) { + // file + define('fn', '', PARAM_FILE); + define('pn', '1', PARAM_FILE); + // mode + define('mo', '', PARAM_MODE); + // relative dimensions of zoomed image + define('wx', '0.0', PARAM_DIM); + define('wy', '0.0', PARAM_DIM); + define('ww', '1.0', PARAM_DIM); + define('wh', '1.0', PARAM_DIM); + // image manipulation + define('brgt', '0.0', PARAM_IMAGE); + define('cont', '0.0', PARAM_IMAGE); + define('rot', '0.0', PARAM_IMAGE); + define('rgba', '', PARAM_IMAGE); + define('rgbm', '', PARAM_IMAGE); + // resolution + define('ddpi', '', PARAM_DPI); + define('ddpix', '', PARAM_DPI); + define('ddpiy', '', PARAM_DPI); + // marks + define('mk', '', PARAM_MARK); + // pages total + define('pt', '0', PARAM_PAGES); + // size + define('ws', '1.0', PARAM_SIZE); + // client side options + define('clop', '', PARAM_CLIENT); + } + return this; +} +DLParameters.prototype = new Parameters(); +// move the inherited getAll because we need it later +DLParameters.prototype._getAll = Parameters.prototype.getAll; +DLParameters.prototype.getAll = function(paDetail, moDetail, digilib) { + if (!digilib) digilib = dl; + // get Flags and Marks first + var mo = digilib.flags.getAll(moDetail); + this.set("mo", mo); + var clop = digilib.opts.getAll(); + this.set("clop", clop); + var mk = digilib.marks.getAll(); + this.set("mk", mk); + var ret = this._getAll(paDetail); + return ret; +} + +/* + * DLModes -- digilib flags class + */ +function DLFlags() { + // flags for mode sets + this.MODE_QUAL = 1; + this.MODE_SIZE = 2; + this.MODE_MIR = 4; + this.MODE_OTHER = 128; + this.MODE_ALL = 255; + /* mode flags */ + with (this) { + define('q0', MODE_QUAL); + define('q1', MODE_QUAL); + define('q2', MODE_QUAL); + define('fit', MODE_SIZE); + define('clip', MODE_SIZE); + define('osize', MODE_SIZE); + define('vmir', MODE_MIR); + define('hmir', MODE_MIR); + } + return this; +} +// inherits from Flags +DLFlags.prototype = new Flags(); + + +/* + * Digilib -- digilib base class + */ +function Digilib() { + if (!baseLibVersion) alert("ERROR: baselib.js not loaded!"); + /* constants */ + this.MAX_AREA = new Rectangle(0.0, 0.0, 1.0, 1.0); + // default inset (for scalerImg relativ to scalerDiv + this.INSET = 40; // because of scrollbars of main window and scaler [Firefox bug?] + // mouse drag area that counts as one click + this.MIN_AREA_SIZE = 3 * 3 + 1; + // standard zoom factor + this.ZOOMFACTOR = Math.sqrt(2); + // bird's eye view dimensions + this.BIRD_MAXX = 100; + this.BIRD_MAXY = 100; + // witdh of arrow bars + this.ARROW_WIDTH = 32; + // width of calibration bar + this.CALIBRATION_WIDTH = 64; + /* variables */ + this.fitOnlyWidth = false; + this.fitOnlyHeight = false; + this.trafo = null; + // page elements + this.scalerDiv = null; + this.scalerImg = null; + this.buttons1Div = null; + this.buttons2Div = null; + /* parse parameters */ + this.params = new DLParameters(); + // put the query parameters (sans "?") in the parameters array + this.params.parse(location.search.slice(1)); + // treat special parameters + this.area = this.parseArea(); + this.marks = new Marks(); + this.marks.parse(this.params.get("mk")); + this.flags = new DLFlags(); + this.flags.parse(this.params.get("mo")); + this.opts = new Flags(); + this.opts.parse(this.params.get("clop")); + return this; +} +Digilib.prototype.setDLParam = function(e, s, relative) { + // sets parameter based on HTML event + var nam; + var val; + if (s.type && (s.type == "select-one")) { + nam = s.name; + val = s.options[s.selectedIndex].value; + } else if (s.name && s.value) { + nam = s.name; + val = s.value; + } + if (nam && val) { + dl.params.set(nam, val, relative); + display(); + } else { + alert("ERROR: unable to process event!"); + } + return true; +} +Digilib.prototype.parseArea = function() { + // returns area Rectangle from current parameters + return new Rectangle( + this.params.get("wx"), + this.params.get("wy"), + this.params.get("ww"), + this.params.get("wh")); +} +Digilib.prototype.setParamFromArea = function(rect) { + // sets digilib wx etc. from rect + this.params.set("wx", cropFloat(rect.x)); + this.params.set("wy", cropFloat(rect.y)); + this.params.set("ww", cropFloat(rect.width)); + this.params.set("wh", cropFloat(rect.height)); + return true; +} + +Digilib.prototype.parseTrafo = function(elem) { + // returns Transform from current dlArea and picsize + var picsize = getElementRect(elem); + var trafo = new Transform(); + // subtract area offset and size + trafo.concat(trafo.getTranslation(new Position(-this.area.x, -this.area.y))); + trafo.concat(trafo.getScale(new Size(1/this.area.width, 1/this.area.height))); + // scale to screen size + trafo.concat(trafo.getScale(picsize)); + trafo.concat(trafo.getTranslation(picsize)); + // FIX ME: Robert, kannst Du mal nachsehen, ob das folgende tut, was es soll? + // oder gibt es dafuer neuen Code? -- ROC: Bisher funktioniert es nicht! + // rotate + //var rot = getRotation(- dl.params.get("rot"), new Position(0.5*picsize.width, 0.5*picsize.height)); + //trafo.concat(rot); + // mirror + //if (hasFlag("hmir")) trafo.m00 = - trafo.m00; // ?? + //if (hasFlag("vmir")) trafo.m11 = - trafo.m11; // ?? + return trafo; +} + +Digilib.prototype.onLoad = function() { + // initialize digilib; called by body.onload + this.scalerDiv = getElement("scaler", true); + this.scalerImg = getElement("pic", true); + this.buttons1Div = getElement("buttons", true); + this.buttons2Div = getElement("options", true); + /* + * if (this.scalerImg == null && this.scalerDiv) { // in N4 pic is in the + * scaler layer this.scalerImg = this.scalerDiv.document.images[0]; } + */ + if ((!this.scalerImg)||(!this.scalerDiv)) { + alert("Sorry, digilib doesn't work here!"); + return false; + } + // fix fixed menus + var ms1 = getElementSize(this.buttons1Div); + var ms2 = getElementSize(this.buttons2Div); + var maxh = (ms1.height > ms2.height) ? ms1.height : ms2.height; + var wins = getWinSize(); + if ((wins.height <= maxh) || (browserType.isIE && (browserType.versIE < 7))) { + // unlock fixed menus to absolute if window is too small or IE + this.buttons1Div.style.position = "absolute"; + this.buttons2Div.style.position = "absolute"; + } + this.setScalerImage(); // setzt auch onImgLoad + this.setBirdImage(); // laedt das Bird's Eye Bild +} + +Digilib.prototype.setScalerImage = function() { + // set the scaler image source (needs the browser size) + var picsize = bestPicSize(this.scalerDiv); + var menusize = getElementSize(this.buttons1Div); + // subtract menu width + picsize.width -= menusize.width; + picsize.height -= this.INSET; + // compose Scaler URL + var src = "../servlet/Scaler?" + + this.params.getAll(this.params.PARAM_ALL & ~(this.params.PARAM_MARK | this.params.PARAM_PAGES)); + if (this.opts.get('fitwidth')) { + src += "&dw=" + picsize.width; + } else if (this.opts.get('fitheight')) { + src += "&dh=" + picsize.height; + } else { + src += "&dw=" + picsize.width + "&dh=" + picsize.height; + } + // debug(src); + this.scalerImg.onload = onImgLoad; + this.scalerImg.src = src; + + var digilib = this; + // this is a local callback function that can use the current scope + + function onImgLoad() { + if (! digilib) + return; + // make sure the image is loaded so we know its size + /* this test seems to have problems sometimes :-( + if (defined(digilib.scalerImg.complete) && !digilib.scalerImg.complete) { + alert("ERROR: the image seems not to be complete in onImgLoad!?"); + } */ + digilib.trafo = digilib.parseTrafo(digilib.scalerImg); + // display marks + digilib.renderMarks(); + digilib.showBirdDiv(isBirdDivVisible); + digilib.showArrows(); // show arrow overlays for zoom navigation + //digilib.moveCenter(true); // click to move point to center + // new Slider("sizes", 1, 5, 2); + focus(); + } +} + +Digilib.prototype.renderMarks = function() { + // make sure the image is loaded so we know its size + if (!this.trafo) { + alert("ERROR: trafo missing, cannot render marks!"); + return; + } + // debugProps(dlArea, "dlArea"); + for (var i = 0; i < this.marks.length; i++) { + var div = getElement("mark" + i, true) || createMarkDiv(i); + var mark = this.marks[i]; + // debugProps(mark, "mark"); + if (this.area.containsPosition(mark)) { + var mpos = this.trafo.transform(mark); + // debugProps(mark, "mpos"); + // better not hide the marked spot (MR) + // suboptimal to place -5 pixels and not half size of mark-image + // mpos.x = mpos.x -5; + // mpos.y = mpos.y -5; + moveElement(div, mpos); + showElement(div, true); + } else { + // hide the other marks + showElement(div, false); + } + } +} + +Digilib.prototype.display = function(detail, moDetail) { + // redisplay the page + var queryString = this.params.getAll(detail, moDetail); + location.href + = location.protocol + "//" + + location.host + + location.pathname + + "?" + queryString; +} + +/* ********************************************** + * interactive digilib functions + * ******************************************** */ + +Digilib.prototype.setMark = function() { + // add a mark where clicked + window.focus(); + this.moveCenter(false); + + // start event capturing + registerEvent("mousedown", this.scalerDiv, markEvent); + + // our own reference to this for the local function + var digilib = this; + + function markEvent(evt) { + // event handler adding a new mark + unregisterEvent("mousedown", digilib.scalerDiv, markEvent); + digilib.marks.addEvent(evt); + digilib.display(); + return stopEvent(evt); + } + +} + +Digilib.prototype.removeMark = function() { + // remove the last mark + this.marks.pop(); + this.display(); +} + +Digilib.prototype.zoomArea = function() { + var pt1, pt2; + var zoomdiv = getElement("zoom"); + var overlay = getElement("overlay"); + // use overlay div to avoid mousemove problems + var picRect = getElementRect(this.scalerImg); + // FIX ME: is there a way to query the border width from CSS info? + // rect.x -= 2; // account for overlay borders + // rect.y -= 2; + moveElement(overlay, picRect); + showElement(overlay, true); + // start event capturing + registerEvent("mousedown", overlay, zoomStart); + registerEvent("mousedown", this.scalerImg, zoomStart); + window.focus(); + + // our own reference to "this" for the local functions + var digilib = this; + + // mousedown handler: start moving + function zoomStart(evt) { + pt1 = evtPosition(evt); + unregisterEvent("mousedown", overlay, zoomStart); + unregisterEvent("mousedown", digilib.scalerImg, zoomStart); + // setup and show zoom div + moveElement(zoomdiv, Rectangle(pt1.x, pt1.y, 0, 0)); + showElement(zoomdiv, true); + // register events + registerEvent("mousemove", document, zoomMove); + registerEvent("mouseup", document, zoomEnd); + return stopEvent(evt); + } + + // mouseup handler: end moving + function zoomEnd(evt) { + pt2 = evtPosition(evt); + // assume a click if the area is too small (up to 3 x 3 pixel) + var clickRect = new Rectangle(pt1, pt2); + clickRect.normalize(); + if (clickRect.getArea() <= digilib.MIN_AREA_SIZE) { + return stopEvent(evt); + } + // hide zoom div + showElement(zoomdiv, false); + showElement(overlay, false); + // unregister events + unregisterEvent("mousemove", document, zoomMove); + unregisterEvent("mouseup", document, zoomEnd); + // clip and transform + clickRect.clipTo(picRect); + var area = digilib.trafo.invtransform(clickRect); + digilib.setParamFromArea(area); + // zoomed is always fit + digilib.params.set("ws", 1); + digilib.display(); + return stopEvent(evt); + } + + // mouse move handler + function zoomMove(evt) { + pt2 = evtPosition(evt); + var rect = new Rectangle(pt1, pt2); + rect.normalize(); + rect.clipTo(picRect); + // update zoom div + moveElement(zoomdiv, rect); + return stopEvent(evt); + } +} + +Digilib.prototype.zoomBy = function(factor) { + // zooms by the given factor + var newarea = this.area.copy(); + newarea.width /= factor; + newarea.height /= factor; + newarea.x -= 0.5 * (newarea.width - this.area.width); + newarea.y -= 0.5 * (newarea.height - this.area.height); + newarea = this.MAX_AREA.fit(newarea); + this.setParamFromArea(newarea); + this.display(); +} + + +Digilib.prototype.zoomFullpage = function(fit) { + // zooms out to show the whole image + this.params.set("wx", 0.0); + this.params.set("wy", 0.0); + this.params.set("ww", 1.0); + this.params.set("wh", 1.0); + if (fit == "width") { + this.opts.set('fitwidth'); + } else if (fit == "height") { + this.opts.set('fitheight'); + } else { + this.opts.reset('fitwidth'); + this.opts.reset('fitheight'); + } + this.display(); +} + + +Digilib.prototype.moveCenter = function(on) { + // move visible area so that it's centered around the clicked point + if (this.isFullArea()) return; // nothing to do + // starting event capture + if (on) registerEvent("mousedown", this.scalerImg, moveCenterEvent); + else unregisterEvent("mousedown", this.scalerImg, moveCenterEvent); + window.focus(); + + // our own reference to this for the local function + var digilib = this; + + function moveCenterEvent(evt) { + // move to handler + var pt = digilib.trafo.invtransform(evtPosition(evt)); + var newarea = digilib.area.copy(); + newarea.setCenter(pt); + newarea.stayInside(this.MAX_AREA); + // newarea = dlMaxArea.fit(newarea); + // debugProps(newarea, "newarea"); + // debugProps(dlArea, "dlArea"); + if (newarea.equals(digilib.area)) return; // keep event handler + unregisterEvent("mousedown", digilib.scalerImg, moveCenterEvent); + // set parameters + digilib.setParamFromArea(newarea); + digilib.display(); + } +} + +Digilib.prototype.isFullArea = function(area) { + if (!area) area = this.area; + return (area.width == 1.0) && (area.height == 1.0); +} + +Digilib.prototype.canMove = function(movx, movy) { + if (this.isFullArea()) return false; + var x2 = this.area.x + this.area.width; + var y2 = this.area.y + this.area.height; + // debugProps(dlArea); + return ((movx < 0) && (this.area.x > 0)) + || ((movx > 0) && (x2 < 1.0)) + || ((movy < 0) && (this.area.y > 0)) + || ((movy > 0) && (y2 < 1.0)) +} + +Digilib.prototype.moveBy = function(movx, movy) { + // move visible area by movx and movy (in units of ww, wh) + if (!this.canMove(movx, movy)) return; // nothing to do + var newarea = this.area.copy(); + newarea.x += parseFloat(movx)*this.area.width; + newarea.y += parseFloat(movy)*this.area.height; + newarea = this.MAX_AREA.fit(newarea); + // set parameters + this.setParamFromArea(newarea); + this.display(); +} + +Digilib.prototype.getRef = function(baseUrl) { + // returns a reference to the current digilib set + if (!baseUrl) baseUrl + = location.protocol + + "//" + + location.host + + location.pathname; + var hyperlinkRef = baseUrl; + with (this.params) { + // all without ddpi, pt + var ps = getAll(PARAM_ALL & ~(PARAM_DPI | PARAM_PAGES | PARAM_CLIENT)); + } + if (ps.length > 0) hyperlinkRef += "?" + ps; + return hyperlinkRef; +} + +Digilib.prototype.getRefWin = function(type, msg) { + // shows an alert with a reference to the current digilib set + if (! msg) msg = "URL reference to the current view"; + prompt(msg, this.getRef()); +} + +Digilib.prototype.getQuality = function() { + // returns the current q setting + for (var i = 0; i < 3; i++) { + if (this.flags.get("q"+i)) return i; + } + return 1 +} + +Digilib.prototype.setQuality = function(qual) { + // set the image quality + if ((qual < 0)||(qual > 2)) return alert("Quality setting not supported"); + for (var i = 0; i < 3; i++) this.flags.reset("q" + i); + this.flags.set("q" + qual); + this.display(); +} + +Digilib.prototype.setQualityWin = function(msg) { + // dialog for setting quality + if (! msg) msg = "Quality (0..2)"; + var q = this.getQuality(); + var newq = window.prompt(msg, q); + if (newq) this.setQuality(newq); +} + +Digilib.prototype.mirror = function(dir) { + // mirror the image horizontally or vertically + if (dir == "h") { + this.flags.toggle("hmir"); + } else { + this.flags.toggle("vmir"); + } + this.display(); +} + +Digilib.prototype.gotoPage = function(gopage, keep) { + // goto given page nr (+/-: relative) + var oldpn = parseInt(this.params.get("pn")); + // set with relative=true uses the sign + this.params.set("pn", gopage, true); + // now check the outcome + var pn = parseInt(this.params.get("pn")); + if (pn < 1) { + alert("No such page! (Page number too low)"); + this.params.set("pn", oldpn); + return; + } + if (this.params.isSet("pt")) { + pt = parseInt(this.params.get("pt")) + if (pn > pt) { + alert("No such page! (Page number too high)"); + this.params.set("pn", oldpn); + return; + } + } + if (keep) { + this.display(this.params.PARAM_ALL & ~this.params.PARAM_MARK); // all, no mark + } else { + this.display(this.params.PARAM_FILE | this.params.PARAM_MODE | this.params.PARAM_PAGES, this.params.MODE_QUAL | this.params.MODE_OTHER); // fn, pn, ws, mo + pt + } +} + +Digilib.prototype.gotoPageWin = function() { + // dialog to ask for new page nr + var pn = this.params.get("pn"); + var gopage = window.prompt("Go to page", pn); + if (gopage) this.gotoPage(gopage); +} + +Digilib.prototype.setParamWin = function(param, text, relative) { + // dialog to ask for new parameter value + var val = this.params.get(param); + var newval = window.prompt(text, val); + if (newval) { + this.params.set(param, newval, relative); + this.display(); + } +} + +Digilib.prototype.showOptions = function(show) { + // show or hide option div + var elem = getElement("dloptions"); + showElement(elem, show); + // FIX ME: get rid of the dotted line around the buttons when focused + } + +Digilib.prototype.showAboutDiv = function(show) { + // show or hide "about" div + var elem = getElement("about"); + if (elem == null) { + if (show) alert("About Digilib - dialog missing in HTML code!" + + "\nDigilib Version: " + digilibVersion + + "\JSP Version: " + jspVersion + + "\ndlLib Version: " + dllibVersion + + "\nbaseLib Version: " + baseLibVersion); + return; + } + if (show) { + getElement("digilib-version").innerHTML = "Digilib Version: " + digilibVersion; + getElement("jsp-version").innerHTML = "JSP Version: " + jspVersion; + getElement("baselib-version").innerHTML = "baseLib Version: " + baseLibVersion; + getElement("dllib-version").innerHTML = "dlLib Version: " + dllibVersion; + var aboutRect = getElementRect(elem); + aboutRect.setCenter(getWinRect().getCenter()); + moveElement(elem, aboutRect); + } + showElement(elem, show); + } + +Digilib.prototype.setBirdImage = function() { + var img = getElement("bird-image"); + var src = "../servlet/Scaler?" + + this.params.getAll(this.params.PARAM_FILE) + + "&dw=" + this.BIRD_MAXX + + "&dh=" + this.BIRD_MAXY; + img.src = src; +} + +Digilib.prototype.showBirdDiv = function(show) { + // show or hide "bird's eye" div + var startPos; // anchor for dragging + var newRect; // position after drag + var birdImg = getElement("bird-image"); + var birdArea = getElement("bird-area"); + var overlay = getElement("bird-overlay"); + showElement(birdImg, show); + // dont show selector if area has full size + if (!show || this.isFullArea()) { + // hide area + showElement(birdArea, false); + showElement(overlay, false); + return; + }; + var birdImgRect = getElementRect(birdImg); + var area = this.area; + if (this.flags.get("osize") || this.flags.get("clip")) { + // in original-size and pixel-by-pixel mode the area size is not valid + var birdAreaRect = new Rectangle( + birdImgRect.x + birdImgRect.width * area.x, + birdImgRect.y + birdImgRect.height * area.y, + 5, + 5); + } else { + // scale area down to img size + var birdAreaRect = new Rectangle( + // what about borders ?? + birdImgRect.x + birdImgRect.width * area.x, + birdImgRect.y + birdImgRect.height * area.y, + birdImgRect.width * area.width, + birdImgRect.height * area.height); + } + moveElement(birdArea, birdAreaRect); + showElement(birdArea, true); + moveElement(overlay, birdImgRect); + showElement(overlay, true); + registerEvent("mousedown", overlay, birdAreaStartDrag); + registerEvent("mousedown", birdImg, birdAreaStartDrag); + + // our own reference to this for local functions + var digilib = this; + + function birdAreaStartDrag(evt) { + // mousedown handler: start drag + startPos = evtPosition(evt); + unregisterEvent("mousedown", overlay, birdAreaStartDrag); + unregisterEvent("mousedown", birdImg, birdAreaStartDrag); + registerEvent("mousemove", document, birdAreaMove); + registerEvent("mouseup", document, birdAreaEndDrag); + // debugProps(getElementRect(bird)) + return stopEvent(evt); + } + + function birdAreaMove(evt) { + // mousemove handler: drag + var pos = evtPosition(evt); + var dx = pos.x - startPos.x; + var dy = pos.y - startPos.y; + // move birdArea div, keeping size + newRect = new Rectangle( + birdAreaRect.x + dx, + birdAreaRect.y + dy, + birdAreaRect.width, + birdAreaRect.height); + // stay within image + newRect.stayInside(birdImgRect); + moveElement(birdArea, newRect); + showElement(birdArea, true); + return stopEvent(evt); + } + + function birdAreaEndDrag(evt) { + // mouseup handler: reload page + unregisterEvent("mousemove", document, birdAreaMove); + unregisterEvent("mouseup", document, birdAreaEndDrag); + showElement(overlay, false); + if (newRect == null) { // no movement happened + startPos = birdAreaRect.getCenter(); + birdAreaMove(evt); // set center to click position + } + digilib.params.set("wx", cropFloat((newRect.x - birdImgRect.x) / birdImgRect.width)); + digilib.params.set("wy", cropFloat((newRect.y - birdImgRect.y) / birdImgRect.height)); + // zoomed is always fit + digilib.params.set("ws", 1); + digilib.display(); + return stopEvent(evt); + } +} + +Digilib.prototype.showArrow = function(name, rect, show) { + var arrow = getElement(name); + moveElement(arrow, rect); + showElement(arrow, show); +} + +Digilib.prototype.showArrows = function() { + // show the 4 arrow bars on top of scaler img according to current dlArea + var r = getElementRect(this.scalerImg); + this.showArrow('up', + new Rectangle(r.x, r.y, r.width, this.ARROW_WIDTH), + this.canMove(0, -1) + ); + this.showArrow('down', + new Rectangle(r.x, r.y + r.height - this.ARROW_WIDTH, r.width, this.ARROW_WIDTH), + this.canMove(0, 1) + ); + this.showArrow('left', + new Rectangle(r.x, r.y, this.ARROW_WIDTH, r.height), + this.canMove(-1, 0) + ); + this.showArrow('right', + new Rectangle(r.x + r.width - this.ARROW_WIDTH, r.y, this.ARROW_WIDTH, r.height), + this.canMove(1, 0) + ); + } + +Digilib.prototype.calibrate = function() { + // calibrate screen resolution + var calDiv = getElement("calibration"); + var calRect = getElementRect(calDiv); + moveCenter(false); + var wins = getWinSize(); + calRect.setCenter(new Position(wins.width / 2, wins.height / 2)); + moveElement(calDiv, calRect); + showElement(calDiv, true); + var cm = window.prompt("The length of the scale on your screen in centimeter:"); + if (cm) { + var dpi = calRect.width / parseFloat(cm) * 2.54; + this.params.set("ddpi", cropFloat(dpi)); + } + showElement(calDiv, false); +} + + +Digilib.prototype.setScale = function(scale) { + // sets original-size, pixel-by-pixel or fit-to-screen scale type + if (scale == "pixel") { + // pixel by pixel + this.flags.set("clip"); + this.flags.reset("osize"); + this.flags.reset("fit"); + } else if (scale == "original") { + // original size -- needs calibrated screen + if (!this.params.isSet("ddpi")) { + var dpi = cookie.get("ddpi"); + if (dpi == null) { + alert("Your screen has not yet been calibrated - using default value of 72 dpi"); + dpi = 72; + } + this.params.set("ddpi", dpi); + } + this.flags.set("osize"); + this.flags.reset("clip"); + this.flags.reset("fit"); + } else { + // scale to screen size (default) + this.flags.reset("clip"); + this.flags.reset("osize"); + } + this.display(); +} + +Digilib.prototype.getScale = function() { + // returns scale type + if (this.flags.get("clip")) { + return "pixel"; + } else if (this.flags.get("osize")) { + return "original"; + } else { + return "fit"; + } +} + +Digilib.prototype.pageWidth = function() { + this.zoomFullpage('width'); +} + +Digilib.prototype.setSize = function(factor) { + this.params.set("ws", factor); + this.display(); +} + +Digilib.prototype.showMenu = function(menuId, buttonId, show) { + var menu = getElement(menuId); + if (show) { + // align right side of menu with button + var buttonPos = getElementPosition(getElement(buttonId)); + var menusize = getElementSize(menu); + moveElement(menu, new Position(buttonPos.x - menusize.width - 3, buttonPos.y)); + } + showElement(menu, show); +} + + +/******************************** + * global variables + ********************************/ + +var dl = new Digilib(); + +/* old parameter function compatibility stuff */ +function newParameter(a,b,c) {return dl.params.define(a,b,c)}; +function resetParameter(a) {return dl.params.reset(a)}; +function deleteParameter(a) {return dl.params.remove(a)}; +function getParameter(a) {return dl.params.get(a)}; +function setParameter(a,b,c) {return dl.params.set(a,b,c)}; +function hasParameter(a) {return dl.params.isSet(a)}; +function getAllParameters(a) {return dl.params.getAll(a)}; +getQueryString = getAllParameters; +function parseParameters(a) {return dl.params.parse(a)}; +function getAllMarks() {return dl.marks.getAll()}; +getMarksQueryString = getAllMarks; +function addMark(evt) {return dl.marks.addEvent(evt)}; +function deleteMark() {return dl.marks.pop()}; +function deleteAllMarks() {return dl.marks = new Marks()}; +function hasFlag(mode) {return dl.flags.get(mode)}; +function addFlag(mode) {return dl.flags.set(mode)}; +function removeFlag(mode) {return dl.flags.reset(mode)}; +function toggleFlag(mode) {return dl.flags.toggle(mode)}; +function getAllFlags() {return dl.flags.getAll()}; +/* old digilib function compatibility */ +function setDLParam(e, s, relative) {dl.setDLParam(e, s, relative)}; +function display(detail, moDetail) {dl.display(detail, moDetail)}; +function setMark(reload) {dl.setMark(reload)}; +function removeMark(reload) {dl.removeMark(reload)}; +function zoomArea() {dl.zoomArea()}; +function zoomBy(factor) {dl.zoomBy(factor)}; +function zoomFullpage(a) {dl.zoomFullpage(a)}; +function moveCenter(on) {dl.moveCenter(on)}; +function isFullArea(area) {dl.isFullArea(area)}; +function canMove(movx, movy) {dl.canMove(movx, movy)}; +function moveBy(movx, movy) {dl.moveBy(movx, movy)}; +function getRef(baseURL) {dl.getRef(baseURL)}; +function getRefWin(type, msg) {dl.getRefWin(type, msg)}; +function getQuality() {dl.getQuality()}; +function setQuality(qual) {dl.setQuality(qual)}; +function setQualityWin(msg) {dl.setQualityWin(msg)}; +function mirror(dir) {dl.mirror(dir)}; +function gotoPage(gopage, keep) {dl.gotoPage(gopage, keep)}; +function gotoPageWin() {dl.gotoPageWin()}; +function setParamWin(param, text, relative) {dl.setParamWin(param, text, relative)}; +function showOptions(show) {dl.showOptions(show)}; +function showBirdDiv(show) {dl.showBirdDiv(show)}; +function showAboutDiv(show) {dl.showAboutDiv(show)}; +function calibrate(direction) {dl.calibrate(direction)}; +function setScale(a) {dl.setScale(a)}; +function getScale(a) {dl.getScale(a)}; +function originalSize(on) {dl.originalSize(on)}; +function pixelByPixel(on) {dl.pixelByPixel(on)}; +function pageWidth() {dl.pageWidth()}; +function setSize(factor) {dl.setSize(factor)}; +function showMenu(a,b,c) {dl.showMenu(a,b,c)}; + + +// :tabSize=4:indentSize=4:noTabs=true: + diff -r a256239970f8 -r b21acdd1fa9d client/digitallibrary/jskin/img/back.png Binary file client/digitallibrary/jskin/img/back.png has changed diff -r a256239970f8 -r b21acdd1fa9d client/digitallibrary/jskin/img/bg.png Binary file client/digitallibrary/jskin/img/bg.png has changed diff -r a256239970f8 -r b21acdd1fa9d client/digitallibrary/jskin/img/birds-eye.png Binary file client/digitallibrary/jskin/img/birds-eye.png has changed diff -r a256239970f8 -r b21acdd1fa9d client/digitallibrary/jskin/img/blue.png Binary file client/digitallibrary/jskin/img/blue.png has changed diff -r a256239970f8 -r b21acdd1fa9d client/digitallibrary/jskin/img/brightness-on.png Binary file client/digitallibrary/jskin/img/brightness-on.png has changed diff -r a256239970f8 -r b21acdd1fa9d client/digitallibrary/jskin/img/brightness.png Binary file client/digitallibrary/jskin/img/brightness.png has changed diff -r a256239970f8 -r b21acdd1fa9d client/digitallibrary/jskin/img/calibration-x.png Binary file client/digitallibrary/jskin/img/calibration-x.png has changed diff -r a256239970f8 -r b21acdd1fa9d client/digitallibrary/jskin/img/calibration-y.png Binary file client/digitallibrary/jskin/img/calibration-y.png has changed diff -r a256239970f8 -r b21acdd1fa9d client/digitallibrary/jskin/img/cat.png Binary file client/digitallibrary/jskin/img/cat.png has changed diff -r a256239970f8 -r b21acdd1fa9d client/digitallibrary/jskin/img/contrast-on.png Binary file client/digitallibrary/jskin/img/contrast-on.png has changed diff -r a256239970f8 -r b21acdd1fa9d client/digitallibrary/jskin/img/contrast.png Binary file client/digitallibrary/jskin/img/contrast.png has changed diff -r a256239970f8 -r b21acdd1fa9d client/digitallibrary/jskin/img/corona.png Binary file client/digitallibrary/jskin/img/corona.png has changed diff -r a256239970f8 -r b21acdd1fa9d client/digitallibrary/jskin/img/delmark.png Binary file client/digitallibrary/jskin/img/delmark.png has changed diff -r a256239970f8 -r b21acdd1fa9d client/digitallibrary/jskin/img/down.png Binary file client/digitallibrary/jskin/img/down.png has changed diff -r a256239970f8 -r b21acdd1fa9d client/digitallibrary/jskin/img/first.png Binary file client/digitallibrary/jskin/img/first.png has changed diff -r a256239970f8 -r b21acdd1fa9d client/digitallibrary/jskin/img/fwd.png Binary file client/digitallibrary/jskin/img/fwd.png has changed diff -r a256239970f8 -r b21acdd1fa9d client/digitallibrary/jskin/img/help.png Binary file client/digitallibrary/jskin/img/help.png has changed diff -r a256239970f8 -r b21acdd1fa9d client/digitallibrary/jskin/img/last.png Binary file client/digitallibrary/jskin/img/last.png has changed diff -r a256239970f8 -r b21acdd1fa9d client/digitallibrary/jskin/img/left.png Binary file client/digitallibrary/jskin/img/left.png has changed diff -r a256239970f8 -r b21acdd1fa9d client/digitallibrary/jskin/img/mark-bg.png Binary file client/digitallibrary/jskin/img/mark-bg.png has changed diff -r a256239970f8 -r b21acdd1fa9d client/digitallibrary/jskin/img/mark.png Binary file client/digitallibrary/jskin/img/mark.png has changed diff -r a256239970f8 -r b21acdd1fa9d client/digitallibrary/jskin/img/mirror-horizontal-on.png Binary file client/digitallibrary/jskin/img/mirror-horizontal-on.png has changed diff -r a256239970f8 -r b21acdd1fa9d client/digitallibrary/jskin/img/mirror-horizontal.png Binary file client/digitallibrary/jskin/img/mirror-horizontal.png has changed diff -r a256239970f8 -r b21acdd1fa9d client/digitallibrary/jskin/img/mirror-vertical-on.png Binary file client/digitallibrary/jskin/img/mirror-vertical-on.png has changed diff -r a256239970f8 -r b21acdd1fa9d client/digitallibrary/jskin/img/mirror-vertical.png Binary file client/digitallibrary/jskin/img/mirror-vertical.png has changed diff -r a256239970f8 -r b21acdd1fa9d client/digitallibrary/jskin/img/options.png Binary file client/digitallibrary/jskin/img/options.png has changed diff -r a256239970f8 -r b21acdd1fa9d client/digitallibrary/jskin/img/original-size.png Binary file client/digitallibrary/jskin/img/original-size.png has changed diff -r a256239970f8 -r b21acdd1fa9d client/digitallibrary/jskin/img/page.png Binary file client/digitallibrary/jskin/img/page.png has changed diff -r a256239970f8 -r b21acdd1fa9d client/digitallibrary/jskin/img/pagewidth.png Binary file client/digitallibrary/jskin/img/pagewidth.png has changed diff -r a256239970f8 -r b21acdd1fa9d client/digitallibrary/jskin/img/pixel-by-pixel.png Binary file client/digitallibrary/jskin/img/pixel-by-pixel.png has changed diff -r a256239970f8 -r b21acdd1fa9d client/digitallibrary/jskin/img/quality.png Binary file client/digitallibrary/jskin/img/quality.png has changed diff -r a256239970f8 -r b21acdd1fa9d client/digitallibrary/jskin/img/reference.png Binary file client/digitallibrary/jskin/img/reference.png has changed diff -r a256239970f8 -r b21acdd1fa9d client/digitallibrary/jskin/img/rgb-on.png Binary file client/digitallibrary/jskin/img/rgb-on.png has changed diff -r a256239970f8 -r b21acdd1fa9d client/digitallibrary/jskin/img/rgb.png Binary file client/digitallibrary/jskin/img/rgb.png has changed diff -r a256239970f8 -r b21acdd1fa9d client/digitallibrary/jskin/img/right.png Binary file client/digitallibrary/jskin/img/right.png has changed diff -r a256239970f8 -r b21acdd1fa9d client/digitallibrary/jskin/img/rotate-on.png Binary file client/digitallibrary/jskin/img/rotate-on.png has changed diff -r a256239970f8 -r b21acdd1fa9d client/digitallibrary/jskin/img/rotate.png Binary file client/digitallibrary/jskin/img/rotate.png has changed diff -r a256239970f8 -r b21acdd1fa9d client/digitallibrary/jskin/img/ruler-top.gif Binary file client/digitallibrary/jskin/img/ruler-top.gif has changed diff -r a256239970f8 -r b21acdd1fa9d client/digitallibrary/jskin/img/size.png Binary file client/digitallibrary/jskin/img/size.png has changed diff -r a256239970f8 -r b21acdd1fa9d client/digitallibrary/jskin/img/trans.gif Binary file client/digitallibrary/jskin/img/trans.gif has changed diff -r a256239970f8 -r b21acdd1fa9d client/digitallibrary/jskin/img/up.png Binary file client/digitallibrary/jskin/img/up.png has changed diff -r a256239970f8 -r b21acdd1fa9d client/digitallibrary/jskin/img/zoom-area.png Binary file client/digitallibrary/jskin/img/zoom-area.png has changed diff -r a256239970f8 -r b21acdd1fa9d client/digitallibrary/jskin/img/zoom-full.png Binary file client/digitallibrary/jskin/img/zoom-full.png has changed diff -r a256239970f8 -r b21acdd1fa9d client/digitallibrary/jskin/img/zoom-in.png Binary file client/digitallibrary/jskin/img/zoom-in.png has changed diff -r a256239970f8 -r b21acdd1fa9d client/digitallibrary/jskin/img/zoom-out.png Binary file client/digitallibrary/jskin/img/zoom-out.png has changed diff -r a256239970f8 -r b21acdd1fa9d client/digitallibrary/jskin/jquery.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/digitallibrary/jskin/jquery.js Mon Sep 07 18:22:54 2009 +0200 @@ -0,0 +1,4376 @@ +/*! + * jQuery JavaScript Library v1.3.2 + * http://jquery.com/ + * + * Copyright (c) 2009 John Resig + * Dual licensed under the MIT and GPL licenses. + * http://docs.jquery.com/License + * + * Date: 2009-02-19 17:34:21 -0500 (Thu, 19 Feb 2009) + * Revision: 6246 + */ +(function(){ + +var + // Will speed up references to window, and allows munging its name. + window = this, + // Will speed up references to undefined, and allows munging its name. + undefined, + // Map over jQuery in case of overwrite + _jQuery = window.jQuery, + // Map over the $ in case of overwrite + _$ = window.$, + + jQuery = window.jQuery = window.$ = function( selector, context ) { + // The jQuery object is actually just the init constructor 'enhanced' + return new jQuery.fn.init( selector, context ); + }, + + // A simple way to check for HTML strings or ID strings + // (both of which we optimize for) + quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/, + // Is it a simple selector + isSimple = /^.[^:#\[\.,]*$/; + +jQuery.fn = jQuery.prototype = { + init: function( selector, context ) { + // Make sure that a selection was provided + selector = selector || document; + + // Handle $(DOMElement) + if ( selector.nodeType ) { + this[0] = selector; + this.length = 1; + this.context = selector; + return this; + } + // Handle HTML strings + if ( typeof selector === "string" ) { + // Are we dealing with HTML string or an ID? + var match = quickExpr.exec( selector ); + + // Verify a match, and that no context was specified for #id + if ( match && (match[1] || !context) ) { + + // HANDLE: $(html) -> $(array) + if ( match[1] ) + selector = jQuery.clean( [ match[1] ], context ); + + // HANDLE: $("#id") + else { + var elem = document.getElementById( match[3] ); + + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem && elem.id != match[3] ) + return jQuery().find( selector ); + + // Otherwise, we inject the element directly into the jQuery object + var ret = jQuery( elem || [] ); + ret.context = document; + ret.selector = selector; + return ret; + } + + // HANDLE: $(expr, [context]) + // (which is just equivalent to: $(content).find(expr) + } else + return jQuery( context ).find( selector ); + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( jQuery.isFunction( selector ) ) + return jQuery( document ).ready( selector ); + + // Make sure that old selector state is passed along + if ( selector.selector && selector.context ) { + this.selector = selector.selector; + this.context = selector.context; + } + + return this.setArray(jQuery.isArray( selector ) ? + selector : + jQuery.makeArray(selector)); + }, + + // Start with an empty selector + selector: "", + + // The current version of jQuery being used + jquery: "1.3.2", + + // The number of elements contained in the matched element set + size: function() { + return this.length; + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + return num === undefined ? + + // Return a 'clean' array + Array.prototype.slice.call( this ) : + + // Return just the object + this[ num ]; + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems, name, selector ) { + // Build a new jQuery matched element set + var ret = jQuery( elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + + ret.context = this.context; + + if ( name === "find" ) + ret.selector = this.selector + (this.selector ? " " : "") + selector; + else if ( name ) + ret.selector = this.selector + "." + name + "(" + selector + ")"; + + // Return the newly-formed element set + return ret; + }, + + // Force the current matched set of elements to become + // the specified array of elements (destroying the stack in the process) + // You should use pushStack() in order to do this, but maintain the stack + setArray: function( elems ) { + // Resetting the length to 0, then using the native Array push + // is a super-fast way to populate an object with array-like properties + this.length = 0; + Array.prototype.push.apply( this, elems ); + + return this; + }, + + // Execute a callback for every element in the matched set. + // (You can seed the arguments with an array of args, but this is + // only used internally.) + each: function( callback, args ) { + return jQuery.each( this, callback, args ); + }, + + // Determine the position of an element within + // the matched set of elements + index: function( elem ) { + // Locate the position of the desired element + return jQuery.inArray( + // If it receives a jQuery object, the first element is used + elem && elem.jquery ? elem[0] : elem + , this ); + }, + + attr: function( name, value, type ) { + var options = name; + + // Look for the case where we're accessing a style value + if ( typeof name === "string" ) + if ( value === undefined ) + return this[0] && jQuery[ type || "attr" ]( this[0], name ); + + else { + options = {}; + options[ name ] = value; + } + + // Check to see if we're setting style values + return this.each(function(i){ + // Set all the styles + for ( name in options ) + jQuery.attr( + type ? + this.style : + this, + name, jQuery.prop( this, options[ name ], type, i, name ) + ); + }); + }, + + css: function( key, value ) { + // ignore negative width and height values + if ( (key == 'width' || key == 'height') && parseFloat(value) < 0 ) + value = undefined; + return this.attr( key, value, "curCSS" ); + }, + + text: function( text ) { + if ( typeof text !== "object" && text != null ) + return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) ); + + var ret = ""; + + jQuery.each( text || this, function(){ + jQuery.each( this.childNodes, function(){ + if ( this.nodeType != 8 ) + ret += this.nodeType != 1 ? + this.nodeValue : + jQuery.fn.text( [ this ] ); + }); + }); + + return ret; + }, + + wrapAll: function( html ) { + if ( this[0] ) { + // The elements to wrap the target around + var wrap = jQuery( html, this[0].ownerDocument ).clone(); + + if ( this[0].parentNode ) + wrap.insertBefore( this[0] ); + + wrap.map(function(){ + var elem = this; + + while ( elem.firstChild ) + elem = elem.firstChild; + + return elem; + }).append(this); + } + + return this; + }, + + wrapInner: function( html ) { + return this.each(function(){ + jQuery( this ).contents().wrapAll( html ); + }); + }, + + wrap: function( html ) { + return this.each(function(){ + jQuery( this ).wrapAll( html ); + }); + }, + + append: function() { + return this.domManip(arguments, true, function(elem){ + if (this.nodeType == 1) + this.appendChild( elem ); + }); + }, + + prepend: function() { + return this.domManip(arguments, true, function(elem){ + if (this.nodeType == 1) + this.insertBefore( elem, this.firstChild ); + }); + }, + + before: function() { + return this.domManip(arguments, false, function(elem){ + this.parentNode.insertBefore( elem, this ); + }); + }, + + after: function() { + return this.domManip(arguments, false, function(elem){ + this.parentNode.insertBefore( elem, this.nextSibling ); + }); + }, + + end: function() { + return this.prevObject || jQuery( [] ); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: [].push, + sort: [].sort, + splice: [].splice, + + find: function( selector ) { + if ( this.length === 1 ) { + var ret = this.pushStack( [], "find", selector ); + ret.length = 0; + jQuery.find( selector, this[0], ret ); + return ret; + } else { + return this.pushStack( jQuery.unique(jQuery.map(this, function(elem){ + return jQuery.find( selector, elem ); + })), "find", selector ); + } + }, + + clone: function( events ) { + // Do the clone + var ret = this.map(function(){ + if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) { + // IE copies events bound via attachEvent when + // using cloneNode. Calling detachEvent on the + // clone will also remove the events from the orignal + // In order to get around this, we use innerHTML. + // Unfortunately, this means some modifications to + // attributes in IE that are actually only stored + // as properties will not be copied (such as the + // the name attribute on an input). + var html = this.outerHTML; + if ( !html ) { + var div = this.ownerDocument.createElement("div"); + div.appendChild( this.cloneNode(true) ); + html = div.innerHTML; + } + + return jQuery.clean([html.replace(/ jQuery\d+="(?:\d+|null)"/g, "").replace(/^\s*/, "")])[0]; + } else + return this.cloneNode(true); + }); + + // Copy the events from the original to the clone + if ( events === true ) { + var orig = this.find("*").andSelf(), i = 0; + + ret.find("*").andSelf().each(function(){ + if ( this.nodeName !== orig[i].nodeName ) + return; + + var events = jQuery.data( orig[i], "events" ); + + for ( var type in events ) { + for ( var handler in events[ type ] ) { + jQuery.event.add( this, type, events[ type ][ handler ], events[ type ][ handler ].data ); + } + } + + i++; + }); + } + + // Return the cloned set + return ret; + }, + + filter: function( selector ) { + return this.pushStack( + jQuery.isFunction( selector ) && + jQuery.grep(this, function(elem, i){ + return selector.call( elem, i ); + }) || + + jQuery.multiFilter( selector, jQuery.grep(this, function(elem){ + return elem.nodeType === 1; + }) ), "filter", selector ); + }, + + closest: function( selector ) { + var pos = jQuery.expr.match.POS.test( selector ) ? jQuery(selector) : null, + closer = 0; + + return this.map(function(){ + var cur = this; + while ( cur && cur.ownerDocument ) { + if ( pos ? pos.index(cur) > -1 : jQuery(cur).is(selector) ) { + jQuery.data(cur, "closest", closer); + return cur; + } + cur = cur.parentNode; + closer++; + } + }); + }, + + not: function( selector ) { + if ( typeof selector === "string" ) + // test special case where just one selector is passed in + if ( isSimple.test( selector ) ) + return this.pushStack( jQuery.multiFilter( selector, this, true ), "not", selector ); + else + selector = jQuery.multiFilter( selector, this ); + + var isArrayLike = selector.length && selector[selector.length - 1] !== undefined && !selector.nodeType; + return this.filter(function() { + return isArrayLike ? jQuery.inArray( this, selector ) < 0 : this != selector; + }); + }, + + add: function( selector ) { + return this.pushStack( jQuery.unique( jQuery.merge( + this.get(), + typeof selector === "string" ? + jQuery( selector ) : + jQuery.makeArray( selector ) + ))); + }, + + is: function( selector ) { + return !!selector && jQuery.multiFilter( selector, this ).length > 0; + }, + + hasClass: function( selector ) { + return !!selector && this.is( "." + selector ); + }, + + val: function( value ) { + if ( value === undefined ) { + var elem = this[0]; + + if ( elem ) { + if( jQuery.nodeName( elem, 'option' ) ) + return (elem.attributes.value || {}).specified ? elem.value : elem.text; + + // We need to handle select boxes special + if ( jQuery.nodeName( elem, "select" ) ) { + var index = elem.selectedIndex, + values = [], + options = elem.options, + one = elem.type == "select-one"; + + // Nothing was selected + if ( index < 0 ) + return null; + + // Loop through all the selected options + for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) { + var option = options[ i ]; + + if ( option.selected ) { + // Get the specifc value for the option + value = jQuery(option).val(); + + // We don't need an array for one selects + if ( one ) + return value; + + // Multi-Selects return an array + values.push( value ); + } + } + + return values; + } + + // Everything else, we just grab the value + return (elem.value || "").replace(/\r/g, ""); + + } + + return undefined; + } + + if ( typeof value === "number" ) + value += ''; + + return this.each(function(){ + if ( this.nodeType != 1 ) + return; + + if ( jQuery.isArray(value) && /radio|checkbox/.test( this.type ) ) + this.checked = (jQuery.inArray(this.value, value) >= 0 || + jQuery.inArray(this.name, value) >= 0); + + else if ( jQuery.nodeName( this, "select" ) ) { + var values = jQuery.makeArray(value); + + jQuery( "option", this ).each(function(){ + this.selected = (jQuery.inArray( this.value, values ) >= 0 || + jQuery.inArray( this.text, values ) >= 0); + }); + + if ( !values.length ) + this.selectedIndex = -1; + + } else + this.value = value; + }); + }, + + html: function( value ) { + return value === undefined ? + (this[0] ? + this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g, "") : + null) : + this.empty().append( value ); + }, + + replaceWith: function( value ) { + return this.after( value ).remove(); + }, + + eq: function( i ) { + return this.slice( i, +i + 1 ); + }, + + slice: function() { + return this.pushStack( Array.prototype.slice.apply( this, arguments ), + "slice", Array.prototype.slice.call(arguments).join(",") ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map(this, function(elem, i){ + return callback.call( elem, i, elem ); + })); + }, + + andSelf: function() { + return this.add( this.prevObject ); + }, + + domManip: function( args, table, callback ) { + if ( this[0] ) { + var fragment = (this[0].ownerDocument || this[0]).createDocumentFragment(), + scripts = jQuery.clean( args, (this[0].ownerDocument || this[0]), fragment ), + first = fragment.firstChild; + + if ( first ) + for ( var i = 0, l = this.length; i < l; i++ ) + callback.call( root(this[i], first), this.length > 1 || i > 0 ? + fragment.cloneNode(true) : fragment ); + + if ( scripts ) + jQuery.each( scripts, evalScript ); + } + + return this; + + function root( elem, cur ) { + return table && jQuery.nodeName(elem, "table") && jQuery.nodeName(cur, "tr") ? + (elem.getElementsByTagName("tbody")[0] || + elem.appendChild(elem.ownerDocument.createElement("tbody"))) : + elem; + } + } +}; + +// Give the init function the jQuery prototype for later instantiation +jQuery.fn.init.prototype = jQuery.fn; + +function evalScript( i, elem ) { + if ( elem.src ) + jQuery.ajax({ + url: elem.src, + async: false, + dataType: "script" + }); + + else + jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" ); + + if ( elem.parentNode ) + elem.parentNode.removeChild( elem ); +} + +function now(){ + return +new Date; +} + +jQuery.extend = jQuery.fn.extend = function() { + // copy reference to target object + var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + target = arguments[1] || {}; + // skip the boolean and the target + i = 2; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !jQuery.isFunction(target) ) + target = {}; + + // extend jQuery itself if only one argument is passed + if ( length == i ) { + target = this; + --i; + } + + for ( ; i < length; i++ ) + // Only deal with non-null/undefined values + if ( (options = arguments[ i ]) != null ) + // Extend the base object + for ( var name in options ) { + var src = target[ name ], copy = options[ name ]; + + // Prevent never-ending loop + if ( target === copy ) + continue; + + // Recurse if we're merging object values + if ( deep && copy && typeof copy === "object" && !copy.nodeType ) + target[ name ] = jQuery.extend( deep, + // Never move original objects, clone them + src || ( copy.length != null ? [ ] : { } ) + , copy ); + + // Don't bring in undefined values + else if ( copy !== undefined ) + target[ name ] = copy; + + } + + // Return the modified object + return target; +}; + +// exclude the following css properties to add px +var exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i, + // cache defaultView + defaultView = document.defaultView || {}, + toString = Object.prototype.toString; + +jQuery.extend({ + noConflict: function( deep ) { + window.$ = _$; + + if ( deep ) + window.jQuery = _jQuery; + + return jQuery; + }, + + // See test/unit/core.js for details concerning isFunction. + // Since version 1.3, DOM methods and functions like alert + // aren't supported. They return false on IE (#2968). + isFunction: function( obj ) { + return toString.call(obj) === "[object Function]"; + }, + + isArray: function( obj ) { + return toString.call(obj) === "[object Array]"; + }, + + // check if an element is in a (or is an) XML document + isXMLDoc: function( elem ) { + return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" || + !!elem.ownerDocument && jQuery.isXMLDoc( elem.ownerDocument ); + }, + + // Evalulates a script in a global context + globalEval: function( data ) { + if ( data && /\S/.test(data) ) { + // Inspired by code by Andrea Giammarchi + // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html + var head = document.getElementsByTagName("head")[0] || document.documentElement, + script = document.createElement("script"); + + script.type = "text/javascript"; + if ( jQuery.support.scriptEval ) + script.appendChild( document.createTextNode( data ) ); + else + script.text = data; + + // Use insertBefore instead of appendChild to circumvent an IE6 bug. + // This arises when a base node is used (#2709). + head.insertBefore( script, head.firstChild ); + head.removeChild( script ); + } + }, + + nodeName: function( elem, name ) { + return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase(); + }, + + // args is for internal usage only + each: function( object, callback, args ) { + var name, i = 0, length = object.length; + + if ( args ) { + if ( length === undefined ) { + for ( name in object ) + if ( callback.apply( object[ name ], args ) === false ) + break; + } else + for ( ; i < length; ) + if ( callback.apply( object[ i++ ], args ) === false ) + break; + + // A special, fast, case for the most common use of each + } else { + if ( length === undefined ) { + for ( name in object ) + if ( callback.call( object[ name ], name, object[ name ] ) === false ) + break; + } else + for ( var value = object[0]; + i < length && callback.call( value, i, value ) !== false; value = object[++i] ){} + } + + return object; + }, + + prop: function( elem, value, type, i, name ) { + // Handle executable functions + if ( jQuery.isFunction( value ) ) + value = value.call( elem, i ); + + // Handle passing in a number to a CSS property + return typeof value === "number" && type == "curCSS" && !exclude.test( name ) ? + value + "px" : + value; + }, + + className: { + // internal only, use addClass("class") + add: function( elem, classNames ) { + jQuery.each((classNames || "").split(/\s+/), function(i, className){ + if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) ) + elem.className += (elem.className ? " " : "") + className; + }); + }, + + // internal only, use removeClass("class") + remove: function( elem, classNames ) { + if (elem.nodeType == 1) + elem.className = classNames !== undefined ? + jQuery.grep(elem.className.split(/\s+/), function(className){ + return !jQuery.className.has( classNames, className ); + }).join(" ") : + ""; + }, + + // internal only, use hasClass("class") + has: function( elem, className ) { + return elem && jQuery.inArray( className, (elem.className || elem).toString().split(/\s+/) ) > -1; + } + }, + + // A method for quickly swapping in/out CSS properties to get correct calculations + swap: function( elem, options, callback ) { + var old = {}; + // Remember the old values, and insert the new ones + for ( var name in options ) { + old[ name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; + } + + callback.call( elem ); + + // Revert the old values + for ( var name in options ) + elem.style[ name ] = old[ name ]; + }, + + css: function( elem, name, force, extra ) { + if ( name == "width" || name == "height" ) { + var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ]; + + function getWH() { + val = name == "width" ? elem.offsetWidth : elem.offsetHeight; + + if ( extra === "border" ) + return; + + jQuery.each( which, function() { + if ( !extra ) + val -= parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0; + if ( extra === "margin" ) + val += parseFloat(jQuery.curCSS( elem, "margin" + this, true)) || 0; + else + val -= parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0; + }); + } + + if ( elem.offsetWidth !== 0 ) + getWH(); + else + jQuery.swap( elem, props, getWH ); + + return Math.max(0, Math.round(val)); + } + + return jQuery.curCSS( elem, name, force ); + }, + + curCSS: function( elem, name, force ) { + var ret, style = elem.style; + + // We need to handle opacity special in IE + if ( name == "opacity" && !jQuery.support.opacity ) { + ret = jQuery.attr( style, "opacity" ); + + return ret == "" ? + "1" : + ret; + } + + // Make sure we're using the right name for getting the float value + if ( name.match( /float/i ) ) + name = styleFloat; + + if ( !force && style && style[ name ] ) + ret = style[ name ]; + + else if ( defaultView.getComputedStyle ) { + + // Only "float" is needed here + if ( name.match( /float/i ) ) + name = "float"; + + name = name.replace( /([A-Z])/g, "-$1" ).toLowerCase(); + + var computedStyle = defaultView.getComputedStyle( elem, null ); + + if ( computedStyle ) + ret = computedStyle.getPropertyValue( name ); + + // We should always get a number back from opacity + if ( name == "opacity" && ret == "" ) + ret = "1"; + + } else if ( elem.currentStyle ) { + var camelCase = name.replace(/\-(\w)/g, function(all, letter){ + return letter.toUpperCase(); + }); + + ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ]; + + // From the awesome hack by Dean Edwards + // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 + + // If we're not dealing with a regular pixel number + // but a number that has a weird ending, we need to convert it to pixels + if ( !/^\d+(px)?$/i.test( ret ) && /^\d/.test( ret ) ) { + // Remember the original values + var left = style.left, rsLeft = elem.runtimeStyle.left; + + // Put in the new values to get a computed value out + elem.runtimeStyle.left = elem.currentStyle.left; + style.left = ret || 0; + ret = style.pixelLeft + "px"; + + // Revert the changed values + style.left = left; + elem.runtimeStyle.left = rsLeft; + } + } + + return ret; + }, + + clean: function( elems, context, fragment ) { + context = context || document; + + // !context.createElement fails in IE with an error but returns typeof 'object' + if ( typeof context.createElement === "undefined" ) + context = context.ownerDocument || context[0] && context[0].ownerDocument || document; + + // If a single string is passed in and it's a single tag + // just do a createElement and skip the rest + if ( !fragment && elems.length === 1 && typeof elems[0] === "string" ) { + var match = /^<(\w+)\s*\/?>$/.exec(elems[0]); + if ( match ) + return [ context.createElement( match[1] ) ]; + } + + var ret = [], scripts = [], div = context.createElement("div"); + + jQuery.each(elems, function(i, elem){ + if ( typeof elem === "number" ) + elem += ''; + + if ( !elem ) + return; + + // Convert html string into DOM nodes + if ( typeof elem === "string" ) { + // Fix "XHTML"-style tags in all browsers + elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){ + return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ? + all : + front + ">"; + }); + + // Trim whitespace, otherwise indexOf won't work as expected + var tags = elem.replace(/^\s+/, "").substring(0, 10).toLowerCase(); + + var wrap = + // option or optgroup + !tags.indexOf("", "" ] || + + !tags.indexOf("", "" ] || + + tags.match(/^<(thead|tbody|tfoot|colg|cap)/) && + [ 1, "", "
" ] || + + !tags.indexOf("", "" ] || + + // matched above + (!tags.indexOf("", "" ] || + + !tags.indexOf("", "" ] || + + // IE can't serialize and