Created
March 13, 2009 20:34
-
-
Save Inviz/78744 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" | |
| "http://www.w3.org/TR/html4/loose.dtd"> | |
| <html lang="en"> | |
| <head> | |
| <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> | |
| <title>PDF Annotator</title> | |
| <script src="mootools.js"></script> | |
| <script src="pdfviewer.js"></script> | |
| <script> | |
| window.addEvent('domready', function() { | |
| $viewer = new PDFViewer(document.body, { | |
| path: 'pdfviewer.swf', | |
| height: "100%", | |
| width: "100%", | |
| onLoad: function() { | |
| this.load("pngs/", 4, "currentAuthor"); | |
| }, | |
| onReady: function() { | |
| for(var i=0; i<5; i++){ | |
| this.annotate(i,100*(i+0.5),100*(i+1),"Automatic annotation...","Dmitry"+i); | |
| } | |
| this.filter("Dmitry0", "Dmitry2") | |
| } | |
| }) | |
| }) | |
| </script> | |
| <!-- Date: 2009-03-14 --> | |
| </head> | |
| <body> | |
| </body> | |
| </html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| Script: Core.js | |
| MooTools - My Object Oriented JavaScript Tools. | |
| License: | |
| MIT-style license. | |
| Copyright: | |
| Copyright (c) 2006-2008 [Valerio Proietti](http://mad4milk.net/). | |
| Code & Documentation: | |
| [The MooTools production team](http://mootools.net/developers/). | |
| Inspiration: | |
| - Class implementation inspired by [Base.js](http://dean.edwards.name/weblog/2006/03/base/) Copyright (c) 2006 Dean Edwards, [GNU Lesser General Public License](http://opensource.org/licenses/lgpl-license.php) | |
| - Some functionality inspired by [Prototype.js](http://prototypejs.org) Copyright (c) 2005-2007 Sam Stephenson, [MIT License](http://opensource.org/licenses/mit-license.php) | |
| */ | |
| var MooTools = { | |
| 'version': '1.2.1', | |
| 'build': '0d4845aab3d9a4fdee2f0d4a6dd59210e4b697cf' | |
| }; | |
| var Native = function(options){ | |
| options = options || {}; | |
| var name = options.name; | |
| var legacy = options.legacy; | |
| var protect = options.protect; | |
| var methods = options.implement; | |
| var generics = options.generics; | |
| var initialize = options.initialize; | |
| var afterImplement = options.afterImplement || function(){}; | |
| var object = initialize || legacy; | |
| generics = generics !== false; | |
| object.constructor = Native; | |
| object.$family = {name: 'native'}; | |
| if (legacy && initialize) object.prototype = legacy.prototype; | |
| object.prototype.constructor = object; | |
| if (name){ | |
| var family = name.toLowerCase(); | |
| object.prototype.$family = {name: family}; | |
| Native.typize(object, family); | |
| } | |
| var add = function(obj, name, method, force){ | |
| if (!protect || force || !obj.prototype[name]) obj.prototype[name] = method; | |
| if (generics) Native.genericize(obj, name, protect); | |
| afterImplement.call(obj, name, method); | |
| return obj; | |
| }; | |
| object.alias = function(a1, a2, a3){ | |
| if (typeof a1 == 'string'){ | |
| if ((a1 = this.prototype[a1])) return add(this, a2, a1, a3); | |
| } | |
| for (var a in a1) this.alias(a, a1[a], a2); | |
| return this; | |
| }; | |
| object.implement = function(a1, a2, a3){ | |
| if (typeof a1 == 'string') return add(this, a1, a2, a3); | |
| for (var p in a1) add(this, p, a1[p], a2); | |
| return this; | |
| }; | |
| if (methods) object.implement(methods); | |
| return object; | |
| }; | |
| Native.genericize = function(object, property, check){ | |
| if ((!check || !object[property]) && typeof object.prototype[property] == 'function') object[property] = function(){ | |
| var args = Array.prototype.slice.call(arguments); | |
| return object.prototype[property].apply(args.shift(), args); | |
| }; | |
| }; | |
| Native.implement = function(objects, properties){ | |
| for (var i = 0, l = objects.length; i < l; i++) objects[i].implement(properties); | |
| }; | |
| Native.typize = function(object, family){ | |
| if (!object.type) object.type = function(item){ | |
| return ($type(item) === family); | |
| }; | |
| }; | |
| (function(){ | |
| var natives = {'Array': Array, 'Date': Date, 'Function': Function, 'Number': Number, 'RegExp': RegExp, 'String': String}; | |
| for (var n in natives) new Native({name: n, initialize: natives[n], protect: true}); | |
| var types = {'boolean': Boolean, 'native': Native, 'object': Object}; | |
| for (var t in types) Native.typize(types[t], t); | |
| var generics = { | |
| 'Array': ["concat", "indexOf", "join", "lastIndexOf", "pop", "push", "reverse", "shift", "slice", "sort", "splice", "toString", "unshift", "valueOf"], | |
| 'String': ["charAt", "charCodeAt", "concat", "indexOf", "lastIndexOf", "match", "replace", "search", "slice", "split", "substr", "substring", "toLowerCase", "toUpperCase", "valueOf"] | |
| }; | |
| for (var g in generics){ | |
| for (var i = generics[g].length; i--;) Native.genericize(window[g], generics[g][i], true); | |
| }; | |
| })(); | |
| var Hash = new Native({ | |
| name: 'Hash', | |
| initialize: function(object){ | |
| if ($type(object) == 'hash') object = $unlink(object.getClean()); | |
| for (var key in object) this[key] = object[key]; | |
| return this; | |
| } | |
| }); | |
| Hash.implement({ | |
| forEach: function(fn, bind){ | |
| for (var key in this){ | |
| if (this.hasOwnProperty(key)) fn.call(bind, this[key], key, this); | |
| } | |
| }, | |
| getClean: function(){ | |
| var clean = {}; | |
| for (var key in this){ | |
| if (this.hasOwnProperty(key)) clean[key] = this[key]; | |
| } | |
| return clean; | |
| }, | |
| getLength: function(){ | |
| var length = 0; | |
| for (var key in this){ | |
| if (this.hasOwnProperty(key)) length++; | |
| } | |
| return length; | |
| } | |
| }); | |
| Hash.alias('forEach', 'each'); | |
| Array.implement({ | |
| forEach: function(fn, bind){ | |
| for (var i = 0, l = this.length; i < l; i++) fn.call(bind, this[i], i, this); | |
| } | |
| }); | |
| Array.alias('forEach', 'each'); | |
| function $A(iterable){ | |
| if (iterable.item){ | |
| var array = []; | |
| for (var i = 0, l = iterable.length; i < l; i++) array[i] = iterable[i]; | |
| return array; | |
| } | |
| return Array.prototype.slice.call(iterable); | |
| }; | |
| function $arguments(i){ | |
| return function(){ | |
| return arguments[i]; | |
| }; | |
| }; | |
| function $chk(obj){ | |
| return !!(obj || obj === 0); | |
| }; | |
| function $clear(timer){ | |
| clearTimeout(timer); | |
| clearInterval(timer); | |
| return null; | |
| }; | |
| function $defined(obj){ | |
| return (obj != undefined); | |
| }; | |
| function $each(iterable, fn, bind){ | |
| var type = $type(iterable); | |
| ((type == 'arguments' || type == 'collection' || type == 'array') ? Array : Hash).each(iterable, fn, bind); | |
| }; | |
| function $empty(){}; | |
| function $extend(original, extended){ | |
| for (var key in (extended || {})) original[key] = extended[key]; | |
| return original; | |
| }; | |
| function $H(object){ | |
| return new Hash(object); | |
| }; | |
| function $lambda(value){ | |
| return (typeof value == 'function') ? value : function(){ | |
| return value; | |
| }; | |
| }; | |
| function $merge(){ | |
| var mix = {}; | |
| for (var i = 0, l = arguments.length; i < l; i++){ | |
| var object = arguments[i]; | |
| if ($type(object) != 'object') continue; | |
| for (var key in object){ | |
| var op = object[key], mp = mix[key]; | |
| mix[key] = (mp && $type(op) == 'object' && $type(mp) == 'object') ? $merge(mp, op) : $unlink(op); | |
| } | |
| } | |
| return mix; | |
| }; | |
| function $pick(){ | |
| for (var i = 0, l = arguments.length; i < l; i++){ | |
| if (arguments[i] != undefined) return arguments[i]; | |
| } | |
| return null; | |
| }; | |
| function $random(min, max){ | |
| return Math.floor(Math.random() * (max - min + 1) + min); | |
| }; | |
| function $splat(obj){ | |
| var type = $type(obj); | |
| return (type) ? ((type != 'array' && type != 'arguments') ? [obj] : obj) : []; | |
| }; | |
| var $time = Date.now || function(){ | |
| return +new Date; | |
| }; | |
| function $try(){ | |
| for (var i = 0, l = arguments.length; i < l; i++){ | |
| try { | |
| return arguments[i](); | |
| } catch(e){} | |
| } | |
| return null; | |
| }; | |
| function $type(obj){ | |
| if (obj == undefined) return false; | |
| if (obj.$family) return (obj.$family.name == 'number' && !isFinite(obj)) ? false : obj.$family.name; | |
| if (obj.nodeName){ | |
| switch (obj.nodeType){ | |
| case 1: return 'element'; | |
| case 3: return (/\S/).test(obj.nodeValue) ? 'textnode' : 'whitespace'; | |
| } | |
| } else if (typeof obj.length == 'number'){ | |
| if (obj.callee) return 'arguments'; | |
| else if (obj.item) return 'collection'; | |
| } | |
| return typeof obj; | |
| }; | |
| function $unlink(object){ | |
| var unlinked; | |
| switch ($type(object)){ | |
| case 'object': | |
| unlinked = {}; | |
| for (var p in object) unlinked[p] = $unlink(object[p]); | |
| break; | |
| case 'hash': | |
| unlinked = new Hash(object); | |
| break; | |
| case 'array': | |
| unlinked = []; | |
| for (var i = 0, l = object.length; i < l; i++) unlinked[i] = $unlink(object[i]); | |
| break; | |
| default: return object; | |
| } | |
| return unlinked; | |
| }; | |
| /* | |
| Script: Browser.js | |
| The Browser Core. Contains Browser initialization, Window and Document, and the Browser Hash. | |
| License: | |
| MIT-style license. | |
| */ | |
| var Browser = $merge({ | |
| Engine: {name: 'unknown', version: 0}, | |
| Platform: {name: (window.orientation != undefined) ? 'ipod' : (navigator.platform.match(/mac|win|linux/i) || ['other'])[0].toLowerCase()}, | |
| Features: {xpath: !!(document.evaluate), air: !!(window.runtime), query: !!(document.querySelector)}, | |
| Plugins: {}, | |
| Engines: { | |
| presto: function(){ | |
| return (!window.opera) ? false : ((arguments.callee.caller) ? 960 : ((document.getElementsByClassName) ? 950 : 925)); | |
| }, | |
| trident: function(){ | |
| return (!window.ActiveXObject) ? false : ((window.XMLHttpRequest) ? 5 : 4); | |
| }, | |
| webkit: function(){ | |
| return (navigator.taintEnabled) ? false : ((Browser.Features.xpath) ? ((Browser.Features.query) ? 525 : 420) : 419); | |
| }, | |
| gecko: function(){ | |
| return (document.getBoxObjectFor == undefined) ? false : ((document.getElementsByClassName) ? 19 : 18); | |
| } | |
| } | |
| }, Browser || {}); | |
| Browser.Platform[Browser.Platform.name] = true; | |
| Browser.detect = function(){ | |
| for (var engine in this.Engines){ | |
| var version = this.Engines[engine](); | |
| if (version){ | |
| this.Engine = {name: engine, version: version}; | |
| this.Engine[engine] = this.Engine[engine + version] = true; | |
| break; | |
| } | |
| } | |
| return {name: engine, version: version}; | |
| }; | |
| Browser.detect(); | |
| Browser.Request = function(){ | |
| return $try(function(){ | |
| return new XMLHttpRequest(); | |
| }, function(){ | |
| return new ActiveXObject('MSXML2.XMLHTTP'); | |
| }); | |
| }; | |
| Browser.Features.xhr = !!(Browser.Request()); | |
| Browser.Plugins.Flash = (function(){ | |
| var version = ($try(function(){ | |
| return navigator.plugins['Shockwave Flash'].description; | |
| }, function(){ | |
| return new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version'); | |
| }) || '0 r0').match(/\d+/g); | |
| return {version: parseInt(version[0] || 0 + '.' + version[1] || 0), build: parseInt(version[2] || 0)}; | |
| })(); | |
| function $exec(text){ | |
| if (!text) return text; | |
| if (window.execScript){ | |
| window.execScript(text); | |
| } else { | |
| var script = document.createElement('script'); | |
| script.setAttribute('type', 'text/javascript'); | |
| script[(Browser.Engine.webkit && Browser.Engine.version < 420) ? 'innerText' : 'text'] = text; | |
| document.head.appendChild(script); | |
| document.head.removeChild(script); | |
| } | |
| return text; | |
| }; | |
| Native.UID = 1; | |
| var $uid = (Browser.Engine.trident) ? function(item){ | |
| return (item.uid || (item.uid = [Native.UID++]))[0]; | |
| } : function(item){ | |
| return item.uid || (item.uid = Native.UID++); | |
| }; | |
| var Window = new Native({ | |
| name: 'Window', | |
| legacy: (Browser.Engine.trident) ? null: window.Window, | |
| initialize: function(win){ | |
| $uid(win); | |
| if (!win.Element){ | |
| win.Element = $empty; | |
| if (Browser.Engine.webkit) win.document.createElement("iframe"); //fixes safari 2 | |
| win.Element.prototype = (Browser.Engine.webkit) ? window["[[DOMElement.prototype]]"] : {}; | |
| } | |
| win.document.window = win; | |
| return $extend(win, Window.Prototype); | |
| }, | |
| afterImplement: function(property, value){ | |
| window[property] = Window.Prototype[property] = value; | |
| } | |
| }); | |
| Window.Prototype = {$family: {name: 'window'}}; | |
| new Window(window); | |
| var Document = new Native({ | |
| name: 'Document', | |
| legacy: (Browser.Engine.trident) ? null: window.Document, | |
| initialize: function(doc){ | |
| $uid(doc); | |
| doc.head = doc.getElementsByTagName('head')[0]; | |
| doc.html = doc.getElementsByTagName('html')[0]; | |
| if (Browser.Engine.trident && Browser.Engine.version <= 4) $try(function(){ | |
| doc.execCommand("BackgroundImageCache", false, true); | |
| }); | |
| if (Browser.Engine.trident) doc.window.attachEvent('onunload', function() { | |
| doc.window.detachEvent('onunload', arguments.callee); | |
| doc.head = doc.html = doc.window = null; | |
| }); | |
| return $extend(doc, Document.Prototype); | |
| }, | |
| afterImplement: function(property, value){ | |
| document[property] = Document.Prototype[property] = value; | |
| } | |
| }); | |
| Document.Prototype = {$family: {name: 'document'}}; | |
| new Document(document); | |
| /* | |
| Script: Array.js | |
| Contains Array Prototypes like each, contains, and erase. | |
| License: | |
| MIT-style license. | |
| */ | |
| Array.implement({ | |
| every: function(fn, bind){ | |
| for (var i = 0, l = this.length; i < l; i++){ | |
| if (!fn.call(bind, this[i], i, this)) return false; | |
| } | |
| return true; | |
| }, | |
| filter: function(fn, bind){ | |
| var results = []; | |
| for (var i = 0, l = this.length; i < l; i++){ | |
| if (fn.call(bind, this[i], i, this)) results.push(this[i]); | |
| } | |
| return results; | |
| }, | |
| clean: function() { | |
| return this.filter($defined); | |
| }, | |
| indexOf: function(item, from){ | |
| var len = this.length; | |
| for (var i = (from < 0) ? Math.max(0, len + from) : from || 0; i < len; i++){ | |
| if (this[i] === item) return i; | |
| } | |
| return -1; | |
| }, | |
| map: function(fn, bind){ | |
| var results = []; | |
| for (var i = 0, l = this.length; i < l; i++) results[i] = fn.call(bind, this[i], i, this); | |
| return results; | |
| }, | |
| some: function(fn, bind){ | |
| for (var i = 0, l = this.length; i < l; i++){ | |
| if (fn.call(bind, this[i], i, this)) return true; | |
| } | |
| return false; | |
| }, | |
| associate: function(keys){ | |
| var obj = {}, length = Math.min(this.length, keys.length); | |
| for (var i = 0; i < length; i++) obj[keys[i]] = this[i]; | |
| return obj; | |
| }, | |
| link: function(object){ | |
| var result = {}; | |
| for (var i = 0, l = this.length; i < l; i++){ | |
| for (var key in object){ | |
| if (object[key](this[i])){ | |
| result[key] = this[i]; | |
| delete object[key]; | |
| break; | |
| } | |
| } | |
| } | |
| return result; | |
| }, | |
| contains: function(item, from){ | |
| return this.indexOf(item, from) != -1; | |
| }, | |
| extend: function(array){ | |
| for (var i = 0, j = array.length; i < j; i++) this.push(array[i]); | |
| return this; | |
| }, | |
| getLast: function(){ | |
| return (this.length) ? this[this.length - 1] : null; | |
| }, | |
| getRandom: function(){ | |
| return (this.length) ? this[$random(0, this.length - 1)] : null; | |
| }, | |
| include: function(item){ | |
| if (!this.contains(item)) this.push(item); | |
| return this; | |
| }, | |
| combine: function(array){ | |
| for (var i = 0, l = array.length; i < l; i++) this.include(array[i]); | |
| return this; | |
| }, | |
| erase: function(item){ | |
| for (var i = this.length; i--; i){ | |
| if (this[i] === item) this.splice(i, 1); | |
| } | |
| return this; | |
| }, | |
| empty: function(){ | |
| this.length = 0; | |
| return this; | |
| }, | |
| flatten: function(){ | |
| var array = []; | |
| for (var i = 0, l = this.length; i < l; i++){ | |
| var type = $type(this[i]); | |
| if (!type) continue; | |
| array = array.concat((type == 'array' || type == 'collection' || type == 'arguments') ? Array.flatten(this[i]) : this[i]); | |
| } | |
| return array; | |
| }, | |
| hexToRgb: function(array){ | |
| if (this.length != 3) return null; | |
| var rgb = this.map(function(value){ | |
| if (value.length == 1) value += value; | |
| return value.toInt(16); | |
| }); | |
| return (array) ? rgb : 'rgb(' + rgb + ')'; | |
| }, | |
| rgbToHex: function(array){ | |
| if (this.length < 3) return null; | |
| if (this.length == 4 && this[3] == 0 && !array) return 'transparent'; | |
| var hex = []; | |
| for (var i = 0; i < 3; i++){ | |
| var bit = (this[i] - 0).toString(16); | |
| hex.push((bit.length == 1) ? '0' + bit : bit); | |
| } | |
| return (array) ? hex : '#' + hex.join(''); | |
| } | |
| }); | |
| /* | |
| Script: Function.js | |
| Contains Function Prototypes like create, bind, pass, and delay. | |
| License: | |
| MIT-style license. | |
| */ | |
| Function.implement({ | |
| extend: function(properties){ | |
| for (var property in properties) this[property] = properties[property]; | |
| return this; | |
| }, | |
| create: function(options){ | |
| var self = this; | |
| options = options || {}; | |
| return function(event){ | |
| var args = options.arguments; | |
| args = (args != undefined) ? $splat(args) : Array.slice(arguments, (options.event) ? 1 : 0); | |
| if (options.event) args = [event || window.event].extend(args); | |
| var returns = function(){ | |
| return self.apply(options.bind || null, args); | |
| }; | |
| if (options.delay) return setTimeout(returns, options.delay); | |
| if (options.periodical) return setInterval(returns, options.periodical); | |
| if (options.attempt) return $try(returns); | |
| return returns(); | |
| }; | |
| }, | |
| run: function(args, bind){ | |
| return this.apply(bind, $splat(args)); | |
| }, | |
| pass: function(args, bind){ | |
| return this.create({bind: bind, arguments: args}); | |
| }, | |
| bind: function(bind, args){ | |
| return this.create({bind: bind, arguments: args}); | |
| }, | |
| bindWithEvent: function(bind, args){ | |
| return this.create({bind: bind, arguments: args, event: true}); | |
| }, | |
| attempt: function(args, bind){ | |
| return this.create({bind: bind, arguments: args, attempt: true})(); | |
| }, | |
| delay: function(delay, bind, args){ | |
| return this.create({bind: bind, arguments: args, delay: delay})(); | |
| }, | |
| periodical: function(periodical, bind, args){ | |
| return this.create({bind: bind, arguments: args, periodical: periodical})(); | |
| } | |
| }); | |
| /* | |
| Script: Number.js | |
| Contains Number Prototypes like limit, round, times, and ceil. | |
| License: | |
| MIT-style license. | |
| */ | |
| Number.implement({ | |
| limit: function(min, max){ | |
| return Math.min(max, Math.max(min, this)); | |
| }, | |
| round: function(precision){ | |
| precision = Math.pow(10, precision || 0); | |
| return Math.round(this * precision) / precision; | |
| }, | |
| times: function(fn, bind){ | |
| for (var i = 0; i < this; i++) fn.call(bind, i, this); | |
| }, | |
| toFloat: function(){ | |
| return parseFloat(this); | |
| }, | |
| toInt: function(base){ | |
| return parseInt(this, base || 10); | |
| } | |
| }); | |
| Number.alias('times', 'each'); | |
| (function(math){ | |
| var methods = {}; | |
| math.each(function(name){ | |
| if (!Number[name]) methods[name] = function(){ | |
| return Math[name].apply(null, [this].concat($A(arguments))); | |
| }; | |
| }); | |
| Number.implement(methods); | |
| })(['abs', 'acos', 'asin', 'atan', 'atan2', 'ceil', 'cos', 'exp', 'floor', 'log', 'max', 'min', 'pow', 'sin', 'sqrt', 'tan']); | |
| /* | |
| Script: String.js | |
| Contains String Prototypes like camelCase, capitalize, test, and toInt. | |
| License: | |
| MIT-style license. | |
| */ | |
| String.implement({ | |
| test: function(regex, params){ | |
| return ((typeof regex == 'string') ? new RegExp(regex, params) : regex).test(this); | |
| }, | |
| contains: function(string, separator){ | |
| return (separator) ? (separator + this + separator).indexOf(separator + string + separator) > -1 : this.indexOf(string) > -1; | |
| }, | |
| trim: function(){ | |
| return this.replace(/^\s+|\s+$/g, ''); | |
| }, | |
| clean: function(){ | |
| return this.replace(/\s+/g, ' ').trim(); | |
| }, | |
| camelCase: function(){ | |
| return this.replace(/-\D/g, function(match){ | |
| return match.charAt(1).toUpperCase(); | |
| }); | |
| }, | |
| hyphenate: function(){ | |
| return this.replace(/[A-Z]/g, function(match){ | |
| return ('-' + match.charAt(0).toLowerCase()); | |
| }); | |
| }, | |
| capitalize: function(){ | |
| return this.replace(/\b[a-z]/g, function(match){ | |
| return match.toUpperCase(); | |
| }); | |
| }, | |
| escapeRegExp: function(){ | |
| return this.replace(/([-.*+?^${}()|[\]\/\\])/g, '\\$1'); | |
| }, | |
| toInt: function(base){ | |
| return parseInt(this, base || 10); | |
| }, | |
| toFloat: function(){ | |
| return parseFloat(this); | |
| }, | |
| hexToRgb: function(array){ | |
| var hex = this.match(/^#?(\w{1,2})(\w{1,2})(\w{1,2})$/); | |
| return (hex) ? hex.slice(1).hexToRgb(array) : null; | |
| }, | |
| rgbToHex: function(array){ | |
| var rgb = this.match(/\d{1,3}/g); | |
| return (rgb) ? rgb.rgbToHex(array) : null; | |
| }, | |
| stripScripts: function(option){ | |
| var scripts = ''; | |
| var text = this.replace(/<script[^>]*>([\s\S]*?)<\/script>/gi, function(){ | |
| scripts += arguments[1] + '\n'; | |
| return ''; | |
| }); | |
| if (option === true) $exec(scripts); | |
| else if ($type(option) == 'function') option(scripts, text); | |
| return text; | |
| }, | |
| substitute: function(object, regexp){ | |
| return this.replace(regexp || (/\\?\{([^{}]+)\}/g), function(match, name){ | |
| if (match.charAt(0) == '\\') return match.slice(1); | |
| return (object[name] != undefined) ? object[name] : ''; | |
| }); | |
| } | |
| }); | |
| /* | |
| Script: Hash.js | |
| Contains Hash Prototypes. Provides a means for overcoming the JavaScript practical impossibility of extending native Objects. | |
| License: | |
| MIT-style license. | |
| */ | |
| Hash.implement({ | |
| has: Object.prototype.hasOwnProperty, | |
| keyOf: function(value){ | |
| for (var key in this){ | |
| if (this.hasOwnProperty(key) && this[key] === value) return key; | |
| } | |
| return null; | |
| }, | |
| hasValue: function(value){ | |
| return (Hash.keyOf(this, value) !== null); | |
| }, | |
| extend: function(properties){ | |
| Hash.each(properties, function(value, key){ | |
| Hash.set(this, key, value); | |
| }, this); | |
| return this; | |
| }, | |
| combine: function(properties){ | |
| Hash.each(properties, function(value, key){ | |
| Hash.include(this, key, value); | |
| }, this); | |
| return this; | |
| }, | |
| erase: function(key){ | |
| if (this.hasOwnProperty(key)) delete this[key]; | |
| return this; | |
| }, | |
| get: function(key){ | |
| return (this.hasOwnProperty(key)) ? this[key] : null; | |
| }, | |
| set: function(key, value){ | |
| if (!this[key] || this.hasOwnProperty(key)) this[key] = value; | |
| return this; | |
| }, | |
| empty: function(){ | |
| Hash.each(this, function(value, key){ | |
| delete this[key]; | |
| }, this); | |
| return this; | |
| }, | |
| include: function(key, value){ | |
| var k = this[key]; | |
| if (k == undefined) this[key] = value; | |
| return this; | |
| }, | |
| map: function(fn, bind){ | |
| var results = new Hash; | |
| Hash.each(this, function(value, key){ | |
| results.set(key, fn.call(bind, value, key, this)); | |
| }, this); | |
| return results; | |
| }, | |
| filter: function(fn, bind){ | |
| var results = new Hash; | |
| Hash.each(this, function(value, key){ | |
| if (fn.call(bind, value, key, this)) results.set(key, value); | |
| }, this); | |
| return results; | |
| }, | |
| every: function(fn, bind){ | |
| for (var key in this){ | |
| if (this.hasOwnProperty(key) && !fn.call(bind, this[key], key)) return false; | |
| } | |
| return true; | |
| }, | |
| some: function(fn, bind){ | |
| for (var key in this){ | |
| if (this.hasOwnProperty(key) && fn.call(bind, this[key], key)) return true; | |
| } | |
| return false; | |
| }, | |
| getKeys: function(){ | |
| var keys = []; | |
| Hash.each(this, function(value, key){ | |
| keys.push(key); | |
| }); | |
| return keys; | |
| }, | |
| getValues: function(){ | |
| var values = []; | |
| Hash.each(this, function(value){ | |
| values.push(value); | |
| }); | |
| return values; | |
| }, | |
| toQueryString: function(base){ | |
| var queryString = []; | |
| Hash.each(this, function(value, key){ | |
| if (base) key = base + '[' + key + ']'; | |
| var result; | |
| switch ($type(value)){ | |
| case 'object': result = Hash.toQueryString(value, key); break; | |
| case 'array': | |
| var qs = {}; | |
| value.each(function(val, i){ | |
| qs[i] = val; | |
| }); | |
| result = Hash.toQueryString(qs, key); | |
| break; | |
| default: result = key + '=' + encodeURIComponent(value); | |
| } | |
| if (value != undefined) queryString.push(result); | |
| }); | |
| return queryString.join('&'); | |
| } | |
| }); | |
| Hash.alias({keyOf: 'indexOf', hasValue: 'contains'}); | |
| /* | |
| Script: Event.js | |
| Contains the Event Native, to make the event object completely crossbrowser. | |
| License: | |
| MIT-style license. | |
| */ | |
| var Event = new Native({ | |
| name: 'Event', | |
| initialize: function(event, win){ | |
| win = win || window; | |
| var doc = win.document; | |
| event = event || win.event; | |
| if (event.$extended) return event; | |
| this.$extended = true; | |
| var type = event.type; | |
| var target = event.target || event.srcElement; | |
| while (target && target.nodeType == 3) target = target.parentNode; | |
| if (type.test(/key/)){ | |
| var code = event.which || event.keyCode; | |
| var key = Event.Keys.keyOf(code); | |
| if (type == 'keydown'){ | |
| var fKey = code - 111; | |
| if (fKey > 0 && fKey < 13) key = 'f' + fKey; | |
| } | |
| key = key || String.fromCharCode(code).toLowerCase(); | |
| } else if (type.match(/(click|mouse|menu)/i)){ | |
| doc = (!doc.compatMode || doc.compatMode == 'CSS1Compat') ? doc.html : doc.body; | |
| var page = { | |
| x: event.pageX || event.clientX + doc.scrollLeft, | |
| y: event.pageY || event.clientY + doc.scrollTop | |
| }; | |
| var client = { | |
| x: (event.pageX) ? event.pageX - win.pageXOffset : event.clientX, | |
| y: (event.pageY) ? event.pageY - win.pageYOffset : event.clientY | |
| }; | |
| if (type.match(/DOMMouseScroll|mousewheel/)){ | |
| var wheel = (event.wheelDelta) ? event.wheelDelta / 120 : -(event.detail || 0) / 3; | |
| } | |
| var rightClick = (event.which == 3) || (event.button == 2); | |
| var related = null; | |
| if (type.match(/over|out/)){ | |
| switch (type){ | |
| case 'mouseover': related = event.relatedTarget || event.fromElement; break; | |
| case 'mouseout': related = event.relatedTarget || event.toElement; | |
| } | |
| if (!(function(){ | |
| while (related && related.nodeType == 3) related = related.parentNode; | |
| return true; | |
| }).create({attempt: Browser.Engine.gecko})()) related = false; | |
| } | |
| } | |
| return $extend(this, { | |
| event: event, | |
| type: type, | |
| page: page, | |
| client: client, | |
| rightClick: rightClick, | |
| wheel: wheel, | |
| relatedTarget: related, | |
| target: target, | |
| code: code, | |
| key: key, | |
| shift: event.shiftKey, | |
| control: event.ctrlKey, | |
| alt: event.altKey, | |
| meta: event.metaKey | |
| }); | |
| } | |
| }); | |
| Event.Keys = new Hash({ | |
| 'enter': 13, | |
| 'up': 38, | |
| 'down': 40, | |
| 'left': 37, | |
| 'right': 39, | |
| 'esc': 27, | |
| 'space': 32, | |
| 'backspace': 8, | |
| 'tab': 9, | |
| 'delete': 46 | |
| }); | |
| Event.implement({ | |
| stop: function(){ | |
| return this.stopPropagation().preventDefault(); | |
| }, | |
| stopPropagation: function(){ | |
| if (this.event.stopPropagation) this.event.stopPropagation(); | |
| else this.event.cancelBubble = true; | |
| return this; | |
| }, | |
| preventDefault: function(){ | |
| if (this.event.preventDefault) this.event.preventDefault(); | |
| else this.event.returnValue = false; | |
| return this; | |
| } | |
| }); | |
| /* | |
| Script: Class.js | |
| Contains the Class Function for easily creating, extending, and implementing reusable Classes. | |
| License: | |
| MIT-style license. | |
| */ | |
| var Class = new Native({ | |
| name: 'Class', | |
| initialize: function(properties){ | |
| properties = properties || {}; | |
| var klass = function(){ | |
| for (var key in this){ | |
| if ($type(this[key]) != 'function') this[key] = $unlink(this[key]); | |
| } | |
| this.constructor = klass; | |
| if (Class.prototyping) return this; | |
| var instance = (this.initialize) ? this.initialize.apply(this, arguments) : this; | |
| if (this.options && this.options.initialize) this.options.initialize.call(this); | |
| return instance; | |
| }; | |
| for (var mutator in Class.Mutators){ | |
| if (!properties[mutator]) continue; | |
| properties = Class.Mutators[mutator](properties, properties[mutator]); | |
| delete properties[mutator]; | |
| } | |
| $extend(klass, this); | |
| klass.constructor = Class; | |
| klass.prototype = properties; | |
| return klass; | |
| } | |
| }); | |
| Class.Mutators = { | |
| Extends: function(self, klass){ | |
| Class.prototyping = klass.prototype; | |
| var subclass = new klass; | |
| delete subclass.parent; | |
| subclass = Class.inherit(subclass, self); | |
| delete Class.prototyping; | |
| return subclass; | |
| }, | |
| Implements: function(self, klasses){ | |
| $splat(klasses).each(function(klass){ | |
| Class.prototying = klass; | |
| $extend(self, ($type(klass) == 'class') ? new klass : klass); | |
| delete Class.prototyping; | |
| }); | |
| return self; | |
| } | |
| }; | |
| Class.extend({ | |
| inherit: function(object, properties){ | |
| var caller = arguments.callee.caller; | |
| for (var key in properties){ | |
| var override = properties[key]; | |
| var previous = object[key]; | |
| var type = $type(override); | |
| if (previous && type == 'function'){ | |
| if (override != previous){ | |
| if (caller){ | |
| override.__parent = previous; | |
| object[key] = override; | |
| } else { | |
| Class.override(object, key, override); | |
| } | |
| } | |
| } else if(type == 'object'){ | |
| object[key] = $merge(previous, override); | |
| } else { | |
| object[key] = override; | |
| } | |
| } | |
| if (caller) object.parent = function(){ | |
| return arguments.callee.caller.__parent.apply(this, arguments); | |
| }; | |
| return object; | |
| }, | |
| override: function(object, name, method){ | |
| var parent = Class.prototyping; | |
| if (parent && object[name] != parent[name]) parent = null; | |
| var override = function(){ | |
| var previous = this.parent; | |
| this.parent = parent ? parent[name] : object[name]; | |
| var value = method.apply(this, arguments); | |
| this.parent = previous; | |
| return value; | |
| }; | |
| object[name] = override; | |
| } | |
| }); | |
| Class.implement({ | |
| implement: function(){ | |
| var proto = this.prototype; | |
| $each(arguments, function(properties){ | |
| Class.inherit(proto, properties); | |
| }); | |
| return this; | |
| } | |
| }); | |
| /* | |
| Script: Class.Extras.js | |
| Contains Utility Classes that can be implemented into your own Classes to ease the execution of many common tasks. | |
| License: | |
| MIT-style license. | |
| */ | |
| var Chain = new Class({ | |
| $chain: [], | |
| chain: function(){ | |
| this.$chain.extend(Array.flatten(arguments)); | |
| return this; | |
| }, | |
| callChain: function(){ | |
| return (this.$chain.length) ? this.$chain.shift().apply(this, arguments) : false; | |
| }, | |
| clearChain: function(){ | |
| this.$chain.empty(); | |
| return this; | |
| } | |
| }); | |
| var Events = new Class({ | |
| $events: {}, | |
| addEvent: function(type, fn, internal){ | |
| type = Events.removeOn(type); | |
| if (fn != $empty){ | |
| this.$events[type] = this.$events[type] || []; | |
| this.$events[type].include(fn); | |
| if (internal) fn.internal = true; | |
| } | |
| return this; | |
| }, | |
| addEvents: function(events){ | |
| for (var type in events) this.addEvent(type, events[type]); | |
| return this; | |
| }, | |
| fireEvent: function(type, args, delay){ | |
| type = Events.removeOn(type); | |
| if (!this.$events || !this.$events[type]) return this; | |
| this.$events[type].each(function(fn){ | |
| fn.create({'bind': this, 'delay': delay, 'arguments': args})(); | |
| }, this); | |
| return this; | |
| }, | |
| removeEvent: function(type, fn){ | |
| type = Events.removeOn(type); | |
| if (!this.$events[type]) return this; | |
| if (!fn.internal) this.$events[type].erase(fn); | |
| return this; | |
| }, | |
| removeEvents: function(events){ | |
| if ($type(events) == 'object'){ | |
| for (var type in events) this.removeEvent(type, events[type]); | |
| return this; | |
| } | |
| if (events) events = Events.removeOn(events); | |
| for (var type in this.$events){ | |
| if (events && events != type) continue; | |
| var fns = this.$events[type]; | |
| for (var i = fns.length; i--; i) this.removeEvent(type, fns[i]); | |
| } | |
| return this; | |
| } | |
| }); | |
| Events.removeOn = function(string){ | |
| return string.replace(/^on([A-Z])/, function(full, first) { | |
| return first.toLowerCase(); | |
| }); | |
| }; | |
| var Options = new Class({ | |
| setOptions: function(){ | |
| this.options = $merge.run([this.options].extend(arguments)); | |
| if (!this.addEvent) return this; | |
| for (var option in this.options){ | |
| if ($type(this.options[option]) != 'function' || !(/^on[A-Z]/).test(option)) continue; | |
| this.addEvent(option, this.options[option]); | |
| delete this.options[option]; | |
| } | |
| return this; | |
| } | |
| }); | |
| /* | |
| Script: Element.js | |
| One of the most important items in MooTools. Contains the dollar function, the dollars function, and an handful of cross-browser, | |
| time-saver methods to let you easily work with HTML Elements. | |
| License: | |
| MIT-style license. | |
| */ | |
| var Element = new Native({ | |
| name: 'Element', | |
| legacy: window.Element, | |
| initialize: function(tag, props){ | |
| var konstructor = Element.Constructors.get(tag); | |
| if (konstructor) return konstructor(props); | |
| if (typeof tag == 'string') return document.newElement(tag, props); | |
| return $(tag).set(props); | |
| }, | |
| afterImplement: function(key, value){ | |
| Element.Prototype[key] = value; | |
| if (Array[key]) return; | |
| Elements.implement(key, function(){ | |
| var items = [], elements = true; | |
| for (var i = 0, j = this.length; i < j; i++){ | |
| var returns = this[i][key].apply(this[i], arguments); | |
| items.push(returns); | |
| if (elements) elements = ($type(returns) == 'element'); | |
| } | |
| return (elements) ? new Elements(items) : items; | |
| }); | |
| } | |
| }); | |
| Element.Prototype = {$family: {name: 'element'}}; | |
| Element.Constructors = new Hash; | |
| var IFrame = new Native({ | |
| name: 'IFrame', | |
| generics: false, | |
| initialize: function(){ | |
| var params = Array.link(arguments, {properties: Object.type, iframe: $defined}); | |
| var props = params.properties || {}; | |
| var iframe = $(params.iframe) || false; | |
| var onload = props.onload || $empty; | |
| delete props.onload; | |
| props.id = props.name = $pick(props.id, props.name, iframe.id, iframe.name, 'IFrame_' + $time()); | |
| iframe = new Element(iframe || 'iframe', props); | |
| var onFrameLoad = function(){ | |
| var host = $try(function(){ | |
| return iframe.contentWindow.location.host; | |
| }); | |
| if (host && host == window.location.host){ | |
| var win = new Window(iframe.contentWindow); | |
| new Document(iframe.contentWindow.document); | |
| $extend(win.Element.prototype, Element.Prototype); | |
| } | |
| onload.call(iframe.contentWindow, iframe.contentWindow.document); | |
| }; | |
| (window.frames[props.id]) ? onFrameLoad() : iframe.addListener('load', onFrameLoad); | |
| return iframe; | |
| } | |
| }); | |
| var Elements = new Native({ | |
| initialize: function(elements, options){ | |
| options = $extend({ddup: true, cash: true}, options); | |
| elements = elements || []; | |
| if (options.ddup || options.cash){ | |
| var uniques = {}, returned = []; | |
| for (var i = 0, l = elements.length; i < l; i++){ | |
| var el = $.element(elements[i], !options.cash); | |
| if (options.ddup){ | |
| if (uniques[el.uid]) continue; | |
| uniques[el.uid] = true; | |
| } | |
| returned.push(el); | |
| } | |
| elements = returned; | |
| } | |
| return (options.cash) ? $extend(elements, this) : elements; | |
| } | |
| }); | |
| Elements.implement({ | |
| filter: function(filter, bind){ | |
| if (!filter) return this; | |
| return new Elements(Array.filter(this, (typeof filter == 'string') ? function(item){ | |
| return item.match(filter); | |
| } : filter, bind)); | |
| } | |
| }); | |
| Document.implement({ | |
| newElement: function(tag, props){ | |
| if (Browser.Engine.trident && props){ | |
| ['name', 'type', 'checked'].each(function(attribute){ | |
| if (!props[attribute]) return; | |
| tag += ' ' + attribute + '="' + props[attribute] + '"'; | |
| if (attribute != 'checked') delete props[attribute]; | |
| }); | |
| tag = '<' + tag + '>'; | |
| } | |
| return $.element(this.createElement(tag)).set(props); | |
| }, | |
| newTextNode: function(text){ | |
| return this.createTextNode(text); | |
| }, | |
| getDocument: function(){ | |
| return this; | |
| }, | |
| getWindow: function(){ | |
| return this.window; | |
| } | |
| }); | |
| Window.implement({ | |
| $: function(el, nocash){ | |
| if (el && el.$family && el.uid) return el; | |
| var type = $type(el); | |
| return ($[type]) ? $[type](el, nocash, this.document) : null; | |
| }, | |
| $$: function(selector){ | |
| if (arguments.length == 1 && typeof selector == 'string') return this.document.getElements(selector); | |
| var elements = []; | |
| var args = Array.flatten(arguments); | |
| for (var i = 0, l = args.length; i < l; i++){ | |
| var item = args[i]; | |
| switch ($type(item)){ | |
| case 'element': elements.push(item); break; | |
| case 'string': elements.extend(this.document.getElements(item, true)); | |
| } | |
| } | |
| return new Elements(elements); | |
| }, | |
| getDocument: function(){ | |
| return this.document; | |
| }, | |
| getWindow: function(){ | |
| return this; | |
| } | |
| }); | |
| $.string = function(id, nocash, doc){ | |
| id = doc.getElementById(id); | |
| return (id) ? $.element(id, nocash) : null; | |
| }; | |
| $.element = function(el, nocash){ | |
| $uid(el); | |
| if (!nocash && !el.$family && !(/^object|embed$/i).test(el.tagName)){ | |
| var proto = Element.Prototype; | |
| for (var p in proto) el[p] = proto[p]; | |
| }; | |
| return el; | |
| }; | |
| $.object = function(obj, nocash, doc){ | |
| if (obj.toElement) return $.element(obj.toElement(doc), nocash); | |
| return null; | |
| }; | |
| $.textnode = $.whitespace = $.window = $.document = $arguments(0); | |
| Native.implement([Element, Document], { | |
| getElement: function(selector, nocash){ | |
| return $(this.getElements(selector, true)[0] || null, nocash); | |
| }, | |
| getElements: function(tags, nocash){ | |
| tags = tags.split(','); | |
| var elements = []; | |
| var ddup = (tags.length > 1); | |
| tags.each(function(tag){ | |
| var partial = this.getElementsByTagName(tag.trim()); | |
| (ddup) ? elements.extend(partial) : elements = partial; | |
| }, this); | |
| return new Elements(elements, {ddup: ddup, cash: !nocash}); | |
| } | |
| }); | |
| (function(){ | |
| var collected = {}, storage = {}; | |
| var props = {input: 'checked', option: 'selected', textarea: (Browser.Engine.webkit && Browser.Engine.version < 420) ? 'innerHTML' : 'value'}; | |
| var get = function(uid){ | |
| return (storage[uid] || (storage[uid] = {})); | |
| }; | |
| var clean = function(item, retain){ | |
| if (!item) return; | |
| var uid = item.uid; | |
| if (Browser.Engine.trident){ | |
| if (item.clearAttributes){ | |
| var clone = retain && item.cloneNode(false); | |
| item.clearAttributes(); | |
| if (clone) item.mergeAttributes(clone); | |
| } else if (item.removeEvents){ | |
| item.removeEvents(); | |
| } | |
| if ((/object/i).test(item.tagName)){ | |
| for (var p in item){ | |
| if (typeof item[p] == 'function') item[p] = $empty; | |
| } | |
| Element.dispose(item); | |
| } | |
| } | |
| if (!uid) return; | |
| collected[uid] = storage[uid] = null; | |
| }; | |
| var purge = function(){ | |
| Hash.each(collected, clean); | |
| if (Browser.Engine.trident) $A(document.getElementsByTagName('object')).each(clean); | |
| if (window.CollectGarbage) CollectGarbage(); | |
| collected = storage = null; | |
| }; | |
| var walk = function(element, walk, start, match, all, nocash){ | |
| var el = element[start || walk]; | |
| var elements = []; | |
| while (el){ | |
| if (el.nodeType == 1 && (!match || Element.match(el, match))){ | |
| if (!all) return $(el, nocash); | |
| elements.push(el); | |
| } | |
| el = el[walk]; | |
| } | |
| return (all) ? new Elements(elements, {ddup: false, cash: !nocash}) : null; | |
| }; | |
| var attributes = { | |
| 'html': 'innerHTML', | |
| 'class': 'className', | |
| 'for': 'htmlFor', | |
| 'text': (Browser.Engine.trident || (Browser.Engine.webkit && Browser.Engine.version < 420)) ? 'innerText' : 'textContent' | |
| }; | |
| var bools = ['compact', 'nowrap', 'ismap', 'declare', 'noshade', 'checked', 'disabled', 'readonly', 'multiple', 'selected', 'noresize', 'defer']; | |
| var camels = ['value', 'accessKey', 'cellPadding', 'cellSpacing', 'colSpan', 'frameBorder', 'maxLength', 'readOnly', 'rowSpan', 'tabIndex', 'useMap']; | |
| Hash.extend(attributes, bools.associate(bools)); | |
| Hash.extend(attributes, camels.associate(camels.map(String.toLowerCase))); | |
| var inserters = { | |
| before: function(context, element){ | |
| if (element.parentNode) element.parentNode.insertBefore(context, element); | |
| }, | |
| after: function(context, element){ | |
| if (!element.parentNode) return; | |
| var next = element.nextSibling; | |
| (next) ? element.parentNode.insertBefore(context, next) : element.parentNode.appendChild(context); | |
| }, | |
| bottom: function(context, element){ | |
| element.appendChild(context); | |
| }, | |
| top: function(context, element){ | |
| var first = element.firstChild; | |
| (first) ? element.insertBefore(context, first) : element.appendChild(context); | |
| } | |
| }; | |
| inserters.inside = inserters.bottom; | |
| Hash.each(inserters, function(inserter, where){ | |
| where = where.capitalize(); | |
| Element.implement('inject' + where, function(el){ | |
| inserter(this, $(el, true)); | |
| return this; | |
| }); | |
| Element.implement('grab' + where, function(el){ | |
| inserter($(el, true), this); | |
| return this; | |
| }); | |
| }); | |
| Element.implement({ | |
| set: function(prop, value){ | |
| switch ($type(prop)){ | |
| case 'object': | |
| for (var p in prop) this.set(p, prop[p]); | |
| break; | |
| case 'string': | |
| var property = Element.Properties.get(prop); | |
| (property && property.set) ? property.set.apply(this, Array.slice(arguments, 1)) : this.setProperty(prop, value); | |
| } | |
| return this; | |
| }, | |
| get: function(prop){ | |
| var property = Element.Properties.get(prop); | |
| return (property && property.get) ? property.get.apply(this, Array.slice(arguments, 1)) : this.getProperty(prop); | |
| }, | |
| erase: function(prop){ | |
| var property = Element.Properties.get(prop); | |
| (property && property.erase) ? property.erase.apply(this) : this.removeProperty(prop); | |
| return this; | |
| }, | |
| setProperty: function(attribute, value){ | |
| var key = attributes[attribute]; | |
| if (value == undefined) return this.removeProperty(attribute); | |
| if (key && bools[attribute]) value = !!value; | |
| (key) ? this[key] = value : this.setAttribute(attribute, '' + value); | |
| return this; | |
| }, | |
| setProperties: function(attributes){ | |
| for (var attribute in attributes) this.setProperty(attribute, attributes[attribute]); | |
| return this; | |
| }, | |
| getProperty: function(attribute){ | |
| var key = attributes[attribute]; | |
| var value = (key) ? this[key] : this.getAttribute(attribute, 2); | |
| return (bools[attribute]) ? !!value : (key) ? value : value || null; | |
| }, | |
| getProperties: function(){ | |
| var args = $A(arguments); | |
| return args.map(this.getProperty, this).associate(args); | |
| }, | |
| removeProperty: function(attribute){ | |
| var key = attributes[attribute]; | |
| (key) ? this[key] = (key && bools[attribute]) ? false : '' : this.removeAttribute(attribute); | |
| return this; | |
| }, | |
| removeProperties: function(){ | |
| Array.each(arguments, this.removeProperty, this); | |
| return this; | |
| }, | |
| hasClass: function(className){ | |
| return this.className.contains(className, ' '); | |
| }, | |
| addClass: function(className){ | |
| if (!this.hasClass(className)) this.className = (this.className + ' ' + className).clean(); | |
| return this; | |
| }, | |
| removeClass: function(className){ | |
| this.className = this.className.replace(new RegExp('(^|\\s)' + className + '(?:\\s|$)'), '$1'); | |
| return this; | |
| }, | |
| toggleClass: function(className){ | |
| return this.hasClass(className) ? this.removeClass(className) : this.addClass(className); | |
| }, | |
| adopt: function(){ | |
| Array.flatten(arguments).each(function(element){ | |
| element = $(element, true); | |
| if (element) this.appendChild(element); | |
| }, this); | |
| return this; | |
| }, | |
| appendText: function(text, where){ | |
| return this.grab(this.getDocument().newTextNode(text), where); | |
| }, | |
| grab: function(el, where){ | |
| inserters[where || 'bottom']($(el, true), this); | |
| return this; | |
| }, | |
| inject: function(el, where){ | |
| inserters[where || 'bottom'](this, $(el, true)); | |
| return this; | |
| }, | |
| replaces: function(el){ | |
| el = $(el, true); | |
| el.parentNode.replaceChild(this, el); | |
| return this; | |
| }, | |
| wraps: function(el, where){ | |
| el = $(el, true); | |
| return this.replaces(el).grab(el, where); | |
| }, | |
| getPrevious: function(match, nocash){ | |
| return walk(this, 'previousSibling', null, match, false, nocash); | |
| }, | |
| getAllPrevious: function(match, nocash){ | |
| return walk(this, 'previousSibling', null, match, true, nocash); | |
| }, | |
| getNext: function(match, nocash){ | |
| return walk(this, 'nextSibling', null, match, false, nocash); | |
| }, | |
| getAllNext: function(match, nocash){ | |
| return walk(this, 'nextSibling', null, match, true, nocash); | |
| }, | |
| getFirst: function(match, nocash){ | |
| return walk(this, 'nextSibling', 'firstChild', match, false, nocash); | |
| }, | |
| getLast: function(match, nocash){ | |
| return walk(this, 'previousSibling', 'lastChild', match, false, nocash); | |
| }, | |
| getParent: function(match, nocash){ | |
| return walk(this, 'parentNode', null, match, false, nocash); | |
| }, | |
| getParents: function(match, nocash){ | |
| return walk(this, 'parentNode', null, match, true, nocash); | |
| }, | |
| getChildren: function(match, nocash){ | |
| return walk(this, 'nextSibling', 'firstChild', match, true, nocash); | |
| }, | |
| getWindow: function(){ | |
| return this.ownerDocument.window; | |
| }, | |
| getDocument: function(){ | |
| return this.ownerDocument; | |
| }, | |
| getElementById: function(id, nocash){ | |
| var el = this.ownerDocument.getElementById(id); | |
| if (!el) return null; | |
| for (var parent = el.parentNode; parent != this; parent = parent.parentNode){ | |
| if (!parent) return null; | |
| } | |
| return $.element(el, nocash); | |
| }, | |
| getSelected: function(){ | |
| return new Elements($A(this.options).filter(function(option){ | |
| return option.selected; | |
| })); | |
| }, | |
| getComputedStyle: function(property){ | |
| if (this.currentStyle) return this.currentStyle[property.camelCase()]; | |
| var computed = this.getDocument().defaultView.getComputedStyle(this, null); | |
| return (computed) ? computed.getPropertyValue([property.hyphenate()]) : null; | |
| }, | |
| toQueryString: function(){ | |
| var queryString = []; | |
| this.getElements('input, select, textarea', true).each(function(el){ | |
| if (!el.name || el.disabled) return; | |
| var value = (el.tagName.toLowerCase() == 'select') ? Element.getSelected(el).map(function(opt){ | |
| return opt.value; | |
| }) : ((el.type == 'radio' || el.type == 'checkbox') && !el.checked) ? null : el.value; | |
| $splat(value).each(function(val){ | |
| if (typeof val != 'undefined') queryString.push(el.name + '=' + encodeURIComponent(val)); | |
| }); | |
| }); | |
| return queryString.join('&'); | |
| }, | |
| clone: function(contents, keepid){ | |
| contents = contents !== false; | |
| var clone = this.cloneNode(contents); | |
| var clean = function(node, element){ | |
| if (!keepid) node.removeAttribute('id'); | |
| if (Browser.Engine.trident){ | |
| node.clearAttributes(); | |
| node.mergeAttributes(element); | |
| node.removeAttribute('uid'); | |
| if (node.options){ | |
| var no = node.options, eo = element.options; | |
| for (var j = no.length; j--;) no[j].selected = eo[j].selected; | |
| } | |
| } | |
| var prop = props[element.tagName.toLowerCase()]; | |
| if (prop && element[prop]) node[prop] = element[prop]; | |
| }; | |
| if (contents){ | |
| var ce = clone.getElementsByTagName('*'), te = this.getElementsByTagName('*'); | |
| for (var i = ce.length; i--;) clean(ce[i], te[i]); | |
| } | |
| clean(clone, this); | |
| return $(clone); | |
| }, | |
| destroy: function(){ | |
| Element.empty(this); | |
| Element.dispose(this); | |
| clean(this, true); | |
| return null; | |
| }, | |
| empty: function(){ | |
| $A(this.childNodes).each(function(node){ | |
| Element.destroy(node); | |
| }); | |
| return this; | |
| }, | |
| dispose: function(){ | |
| return (this.parentNode) ? this.parentNode.removeChild(this) : this; | |
| }, | |
| hasChild: function(el){ | |
| el = $(el, true); | |
| if (!el) return false; | |
| if (Browser.Engine.webkit && Browser.Engine.version < 420) return $A(this.getElementsByTagName(el.tagName)).contains(el); | |
| return (this.contains) ? (this != el && this.contains(el)) : !!(this.compareDocumentPosition(el) & 16); | |
| }, | |
| match: function(tag){ | |
| return (!tag || (tag == this) || (Element.get(this, 'tag') == tag)); | |
| } | |
| }); | |
| Native.implement([Element, Window, Document], { | |
| addListener: function(type, fn){ | |
| if (type == 'unload'){ | |
| var old = fn, self = this; | |
| fn = function(){ | |
| self.removeListener('unload', fn); | |
| old(); | |
| }; | |
| } else { | |
| collected[this.uid] = this; | |
| } | |
| if (this.addEventListener) this.addEventListener(type, fn, false); | |
| else this.attachEvent('on' + type, fn); | |
| return this; | |
| }, | |
| removeListener: function(type, fn){ | |
| if (this.removeEventListener) this.removeEventListener(type, fn, false); | |
| else this.detachEvent('on' + type, fn); | |
| return this; | |
| }, | |
| retrieve: function(property, dflt){ | |
| var storage = get(this.uid), prop = storage[property]; | |
| if (dflt != undefined && prop == undefined) prop = storage[property] = dflt; | |
| return $pick(prop); | |
| }, | |
| store: function(property, value){ | |
| var storage = get(this.uid); | |
| storage[property] = value; | |
| return this; | |
| }, | |
| eliminate: function(property){ | |
| var storage = get(this.uid); | |
| delete storage[property]; | |
| return this; | |
| } | |
| }); | |
| window.addListener('unload', purge); | |
| })(); | |
| Element.Properties = new Hash; | |
| Element.Properties.style = { | |
| set: function(style){ | |
| this.style.cssText = style; | |
| }, | |
| get: function(){ | |
| return this.style.cssText; | |
| }, | |
| erase: function(){ | |
| this.style.cssText = ''; | |
| } | |
| }; | |
| Element.Properties.tag = { | |
| get: function(){ | |
| return this.tagName.toLowerCase(); | |
| } | |
| }; | |
| Element.Properties.html = (function(){ | |
| var wrapper = document.createElement('div'); | |
| var translations = { | |
| table: [1, '<table>', '</table>'], | |
| select: [1, '<select>', '</select>'], | |
| tbody: [2, '<table><tbody>', '</tbody></table>'], | |
| tr: [3, '<table><tbody><tr>', '</tr></tbody></table>'] | |
| }; | |
| translations.thead = translations.tfoot = translations.tbody; | |
| var html = { | |
| set: function(){ | |
| var html = Array.flatten(arguments).join(''); | |
| var wrap = Browser.Engine.trident && translations[this.get('tag')]; | |
| if (wrap){ | |
| var first = wrapper; | |
| first.innerHTML = wrap[1] + html + wrap[2]; | |
| for (var i = wrap[0]; i--;) first = first.firstChild; | |
| this.empty().adopt(first.childNodes); | |
| } else { | |
| this.innerHTML = html; | |
| } | |
| } | |
| }; | |
| html.erase = html.set; | |
| return html; | |
| })(); | |
| if (Browser.Engine.webkit && Browser.Engine.version < 420) Element.Properties.text = { | |
| get: function(){ | |
| if (this.innerText) return this.innerText; | |
| var temp = this.ownerDocument.newElement('div', {html: this.innerHTML}).inject(this.ownerDocument.body); | |
| var text = temp.innerText; | |
| temp.destroy(); | |
| return text; | |
| } | |
| }; | |
| /* | |
| Script: Element.Event.js | |
| Contains Element methods for dealing with events, and custom Events. | |
| License: | |
| MIT-style license. | |
| */ | |
| Element.Properties.events = {set: function(events){ | |
| this.addEvents(events); | |
| }}; | |
| Native.implement([Element, Window, Document], { | |
| addEvent: function(type, fn){ | |
| var events = this.retrieve('events', {}); | |
| events[type] = events[type] || {'keys': [], 'values': []}; | |
| if (events[type].keys.contains(fn)) return this; | |
| events[type].keys.push(fn); | |
| var realType = type, custom = Element.Events.get(type), condition = fn, self = this; | |
| if (custom){ | |
| if (custom.onAdd) custom.onAdd.call(this, fn); | |
| if (custom.condition){ | |
| condition = function(event){ | |
| if (custom.condition.call(this, event)) return fn.call(this, event); | |
| return true; | |
| }; | |
| } | |
| realType = custom.base || realType; | |
| } | |
| var defn = function(){ | |
| return fn.call(self); | |
| }; | |
| var nativeEvent = Element.NativeEvents[realType]; | |
| if (nativeEvent){ | |
| if (nativeEvent == 2){ | |
| defn = function(event){ | |
| event = new Event(event, self.getWindow()); | |
| if (condition.call(self, event) === false) event.stop(); | |
| }; | |
| } | |
| this.addListener(realType, defn); | |
| } | |
| events[type].values.push(defn); | |
| return this; | |
| }, | |
| removeEvent: function(type, fn){ | |
| var events = this.retrieve('events'); | |
| if (!events || !events[type]) return this; | |
| var pos = events[type].keys.indexOf(fn); | |
| if (pos == -1) return this; | |
| events[type].keys.splice(pos, 1); | |
| var value = events[type].values.splice(pos, 1)[0]; | |
| var custom = Element.Events.get(type); | |
| if (custom){ | |
| if (custom.onRemove) custom.onRemove.call(this, fn); | |
| type = custom.base || type; | |
| } | |
| return (Element.NativeEvents[type]) ? this.removeListener(type, value) : this; | |
| }, | |
| addEvents: function(events){ | |
| for (var event in events) this.addEvent(event, events[event]); | |
| return this; | |
| }, | |
| removeEvents: function(events){ | |
| if ($type(events) == 'object'){ | |
| for (var type in events) this.removeEvent(type, events[type]); | |
| return this; | |
| } | |
| var attached = this.retrieve('events'); | |
| if (!attached) return this; | |
| if (!events){ | |
| for (var type in attached) this.removeEvents(type); | |
| this.eliminate('events'); | |
| } else if (attached[events]){ | |
| while (attached[events].keys[0]) this.removeEvent(events, attached[events].keys[0]); | |
| attached[events] = null; | |
| } | |
| return this; | |
| }, | |
| fireEvent: function(type, args, delay){ | |
| var events = this.retrieve('events'); | |
| if (!events || !events[type]) return this; | |
| events[type].keys.each(function(fn){ | |
| fn.create({'bind': this, 'delay': delay, 'arguments': args})(); | |
| }, this); | |
| return this; | |
| }, | |
| cloneEvents: function(from, type){ | |
| from = $(from); | |
| var fevents = from.retrieve('events'); | |
| if (!fevents) return this; | |
| if (!type){ | |
| for (var evType in fevents) this.cloneEvents(from, evType); | |
| } else if (fevents[type]){ | |
| fevents[type].keys.each(function(fn){ | |
| this.addEvent(type, fn); | |
| }, this); | |
| } | |
| return this; | |
| } | |
| }); | |
| Element.NativeEvents = { | |
| click: 2, dblclick: 2, mouseup: 2, mousedown: 2, contextmenu: 2, //mouse buttons | |
| mousewheel: 2, DOMMouseScroll: 2, //mouse wheel | |
| mouseover: 2, mouseout: 2, mousemove: 2, selectstart: 2, selectend: 2, //mouse movement | |
| keydown: 2, keypress: 2, keyup: 2, //keyboard | |
| focus: 2, blur: 2, change: 2, reset: 2, select: 2, submit: 2, //form elements | |
| load: 1, unload: 1, beforeunload: 2, resize: 1, move: 1, DOMContentLoaded: 1, readystatechange: 1, //window | |
| error: 1, abort: 1, scroll: 1 //misc | |
| }; | |
| (function(){ | |
| var $check = function(event){ | |
| var related = event.relatedTarget; | |
| if (related == undefined) return true; | |
| if (related === false) return false; | |
| return ($type(this) != 'document' && related != this && related.prefix != 'xul' && !this.hasChild(related)); | |
| }; | |
| Element.Events = new Hash({ | |
| mouseenter: { | |
| base: 'mouseover', | |
| condition: $check | |
| }, | |
| mouseleave: { | |
| base: 'mouseout', | |
| condition: $check | |
| }, | |
| mousewheel: { | |
| base: (Browser.Engine.gecko) ? 'DOMMouseScroll' : 'mousewheel' | |
| } | |
| }); | |
| })(); | |
| /* | |
| Script: Domready.js | |
| Contains the domready custom event. | |
| License: | |
| MIT-style license. | |
| */ | |
| Element.Events.domready = { | |
| onAdd: function(fn){ | |
| if (Browser.loaded) fn.call(this); | |
| } | |
| }; | |
| (function(){ | |
| var domready = function(){ | |
| if (Browser.loaded) return; | |
| Browser.loaded = true; | |
| window.fireEvent('domready'); | |
| document.fireEvent('domready'); | |
| }; | |
| if (Browser.Engine.trident){ | |
| var temp = document.createElement('div'); | |
| (function(){ | |
| ($try(function(){ | |
| temp.doScroll('left'); | |
| return $(temp).inject(document.body).set('html', 'temp').dispose(); | |
| })) ? domready() : arguments.callee.delay(50); | |
| })(); | |
| } else if (Browser.Engine.webkit && Browser.Engine.version < 525){ | |
| (function(){ | |
| (['loaded', 'complete'].contains(document.readyState)) ? domready() : arguments.callee.delay(50); | |
| })(); | |
| } else { | |
| window.addEvent('load', domready); | |
| document.addEvent('DOMContentLoaded', domready); | |
| } | |
| })(); | |
| /* | |
| Script: Swiff.js | |
| Wrapper for embedding SWF movies. Supports (and fixes) External Interface Communication. | |
| License: | |
| MIT-style license. | |
| Credits: | |
| Flash detection & Internet Explorer + Flash Player 9 fix inspired by SWFObject. | |
| */ | |
| var Swiff = new Class({ | |
| Implements: [Options], | |
| options: { | |
| id: null, | |
| height: 1, | |
| width: 1, | |
| container: null, | |
| properties: {}, | |
| params: { | |
| quality: 'high', | |
| allowScriptAccess: 'always', | |
| wMode: 'transparent', | |
| swLiveConnect: true | |
| }, | |
| callBacks: {}, | |
| vars: {} | |
| }, | |
| toElement: function(){ | |
| return this.object; | |
| }, | |
| initialize: function(path, options){ | |
| this.instance = 'Swiff_' + $time(); | |
| this.setOptions(options); | |
| options = this.options; | |
| var id = this.id = options.id || this.instance; | |
| var container = $(options.container); | |
| Swiff.CallBacks[this.instance] = {}; | |
| var params = options.params, vars = options.vars, callBacks = options.callBacks; | |
| var properties = $extend({height: options.height, width: options.width}, options.properties); | |
| var self = this; | |
| for (var callBack in callBacks){ | |
| Swiff.CallBacks[this.instance][callBack] = (function(option){ | |
| return function(){ | |
| return option.apply(self.object, arguments); | |
| }; | |
| })(callBacks[callBack]); | |
| vars[callBack] = 'Swiff.CallBacks.' + this.instance + '.' + callBack; | |
| } | |
| params.flashVars = Hash.toQueryString(vars); | |
| if (Browser.Engine.trident){ | |
| properties.classid = 'clsid:D27CDB6E-AE6D-11cf-96B8-444553540000'; | |
| params.movie = path; | |
| } else { | |
| properties.type = 'application/x-shockwave-flash'; | |
| properties.data = path; | |
| } | |
| var build = '<object id="' + id + '"'; | |
| for (var property in properties) build += ' ' + property + '="' + properties[property] + '"'; | |
| build += '>'; | |
| for (var param in params){ | |
| if (params[param]) build += '<param name="' + param + '" value="' + params[param] + '" />'; | |
| } | |
| build += '</object>'; | |
| this.object = ((container) ? container.empty() : new Element('div')).set('html', build).firstChild; | |
| }, | |
| replaces: function(element){ | |
| element = $(element, true); | |
| element.parentNode.replaceChild(this.toElement(), element); | |
| return this; | |
| }, | |
| inject: function(element){ | |
| $(element, true).appendChild(this.toElement()); | |
| return this; | |
| }, | |
| remote: function(){ | |
| return Swiff.remote.apply(Swiff, [this.toElement()].extend(arguments)); | |
| } | |
| }); | |
| Swiff.CallBacks = {}; | |
| Swiff.remote = function(obj, fn){ | |
| var rs = obj.CallFunction('<invoke name="' + fn + '" returntype="javascript">' + __flash__argumentsToXML(arguments, 2) + '</invoke>'); | |
| return eval(rs); | |
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| var PDFViewer = new Class({ | |
| Extends: Swiff, | |
| options: { | |
| path: "/flashes/pdfviewer.swf", | |
| /* | |
| Events: | |
| onLoad: fires on swf load | |
| onReady: viewer is ready and loaded first few pages (happens on startup) | |
| onRequest: started loading something (e.g. starting a new page) (viewer is busy), | |
| onComplete: finished all current requests (viewer is idle), | |
| onZoom(new_zoom_value): user zoomed in or out something. Required for knob position update. | |
| onShow(page_number): "page_number" page appeared in viewpoint | |
| onChange(page_number): user jumped to "page_number". | |
| onAnnotateStart(x, y): user clicked at x,y to add a new comment | |
| onAnnotateFinish(x, y, text): user typed in comment (new annotation interface is in flash) | |
| onAnnotate(x, y, text): annotation added at x, y, text | |
| onDeannotate(x, y, text): annotation removed from x, y. text was text | |
| onScroll(x, y): viewport got scrolled to x, y. To be fired rapidly when user scrolls using scrollbar | |
| onFilter(person, another_author, third_author...): user chose to show annotations only by given authors | |
| SWF Methods (external interface): | |
| load(path, pages): load pages from path (e.g. path is: /articles/%.png, pages is: 20. It loads /articles/1.png to /articles/20.png) | |
| goTo(page): go to page numbered "page". Fires onChange, onReady | |
| annotate(x, y, text, author): render annotation with text at x, y. Author is a string. Fires onAnnotate | |
| deannotate(x, y): remove annotation at x, y. Fires onDeannotate | |
| scrollTo(x, y): scroll canvas to x, y, Fires onScroll | |
| zoom(measure = 1): zooms document to the given measure (1 is 100% and is default value). Fires onZoom | |
| refresh(n = false): refresh nth page (if n == false, refresh all). Fires onRequest for each page refreshing, onComplete on each, onReady when everything is done. | |
| forward(n = 1): scroll forward by n screens | |
| back(n = 1): scroll back by n screens | |
| next(n = 1): navigate forward by n pages | |
| previous(n = 1): navigate back by n pages | |
| filter(author, another_author, third_author...): Show only annotations by given authors (match any of strings). Fires onFilter | |
| Settings: | |
| annotatable(default: true). allows user to add an annotation on click | |
| scrollbars(default: true). shows scrollbars | |
| interface(default: true). shows interface (in case if there will be any other buttons or controls) | |
| multiuser(default: true). shows author filter bar | |
| Sample flash implementation: | |
| Firing events: ExternalInterface.call(root.loaderInfo.parameters.onLoad, param1, param2); | |
| Registering external interface function: | |
| ExternalInterface.addCallback('goTo', goTo); | |
| ExternalInterface.addCallback('scrollTo', scrollTo); | |
| Getting options: | |
| */ | |
| params: { | |
| annotatable: true, | |
| scrollbars: true, | |
| 'interface': true | |
| }, | |
| callBacks: null | |
| }, | |
| initialize: function(wrapper, options) { | |
| this.setOptions(options); | |
| var callBacks = this.options.callBacks || this; | |
| if (callBacks.onLoad) this.addEvent('onLoad', callBacks.onLoad); | |
| var prepare = {}, self = this; | |
| ["onLoad", "onReady", "onRequest", "onComplete", "onZoom", "onShow", "onChange", "onAnnotateStart", "onAnnotateFinish", "onAnnotate", "onDeannotate"].each(function(index) { | |
| var fn = callBacks[index] || self[index] || $empty; | |
| prepare[index] = function() { | |
| self.fireEvent(index, arguments, 10); | |
| return fn.apply(self, arguments); | |
| }; | |
| }); | |
| prepare.onLoad = this.load.create({delay: 10, bind: this}); | |
| this.options.callBacks = prepare | |
| this.parent(this.options.path); | |
| this.inject(wrapper) | |
| }, | |
| //below are methods which I expect to be registered and used via ExternalInterface | |
| load: function(path, pages) { | |
| this.remote('load', path, pages) | |
| }, | |
| goTo: function(page) { | |
| this.remote('goTo', page) | |
| }, | |
| annotate: function(x, y, text) { | |
| this.remote('annotate', x, y, text) | |
| }, | |
| deannotate: function(x, y) { | |
| this.remote('deannotate', x, y) | |
| }, | |
| forward: function(x) { | |
| this.remote('forward', x || 1) | |
| }, | |
| backward: function(x) { | |
| this.remote('backward', x || 1) | |
| }, | |
| next: function(x) { | |
| this.remote('next', x || 1) | |
| }, | |
| previous: function(x) { | |
| this.remote('previous', x || 1) | |
| }, | |
| scrollTo: function(x, y) { | |
| this.remote('scrollTo', x, y) | |
| }, | |
| zoom: function(measure) { | |
| this.remote('zoom', measure || 1) | |
| } | |
| }) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment