comparison client/digitallibrary/jquery/jquery.digilib.js @ 800:65e70c03870b stream

merge from juqery branch 12f790cb30de0ac42ff62fb9921d7a3215243b7b
author robcast
date Sat, 19 Feb 2011 09:56:18 +0100
parents 12f790cb30de
children 1b1728926534
comparison
equal deleted inserted replaced
774:4568e539abd2 800:65e70c03870b
19 19
20 /** 20 /**
21 * digilib jQuery plugin 21 * digilib jQuery plugin
22 **/ 22 **/
23 23
24
25 /*jslint browser: true, debug: true, forin: true 24 /*jslint browser: true, debug: true, forin: true
26 */ 25 */
27 26
28 // fallback for console.log calls 27 // fallback for console.log calls
29 if (typeof(console) === 'undefined') { 28 if (typeof console === 'undefined') {
30 var console = { 29 var console = {
31 log : function(){}, 30 log : function(){},
32 debug : function(){}, 31 debug : function(){},
33 error : function(){} 32 error : function(){}
34 }; 33 };
35 var customConsole = true; 34 var customConsole = false; // set to true if debugging for MS IE
36 } 35 }
37 36
38 (function($) { 37 (function($) {
39 var buttons = { 38 var buttons = {
40 reference : { 39 reference : {
79 }, 78 },
80 page : { 79 page : {
81 onclick : "gotoPage", 80 onclick : "gotoPage",
82 tooltip : "goto image number", 81 tooltip : "goto image number",
83 icon : "page.png" 82 icon : "page.png"
84 },
85 bird : {
86 onclick : "showBirdDiv",
87 tooltip : "show bird's eye view",
88 icon : "birds-eye.png"
89 }, 83 },
90 help : { 84 help : {
91 onclick : "showAboutDiv", 85 onclick : "showAboutDiv",
92 tooltip : "about Digilib", 86 tooltip : "about Digilib",
93 icon : "help.png" 87 icon : "help.png"
221 // defaults for digilib buttons 215 // defaults for digilib buttons
222 'buttonSettings' : { 216 'buttonSettings' : {
223 'fullscreen' : { 217 'fullscreen' : {
224 // path to button images (must end with a slash) 218 // path to button images (must end with a slash)
225 'imagePath' : 'img/fullscreen/', 219 'imagePath' : 'img/fullscreen/',
226 'standardSet' : ["reference","zoomin","zoomout","zoomarea","zoomfull","pagewidth","back","fwd","page","bird","help","reset","toggleoptions"], 220 'standardSet' : ["reference","zoomin","zoomout","zoomarea","zoomfull","pagewidth","back","fwd","page","help","reset","toggleoptions"],
227 'specialSet' : ["mark","delmark","hmir","vmir","rot","brgt","cont","rgb","quality","size","calibrationx","scale","toggleoptions"], 221 'specialSet' : ["mark","delmark","hmir","vmir","rot","brgt","cont","rgb","quality","size","calibrationx","scale","toggleoptions"],
228 'buttonSets' : ['standardSet', 'specialSet'] 222 'buttonSets' : ['standardSet', 'specialSet']
229 }, 223 },
230 'embedded' : { 224 'embedded' : {
231 'imagePath' : 'img/embedded/16/', 225 'imagePath' : 'img/embedded/16/',
232 'standardSet' : ["reference","zoomin","zoomout","zoomarea","zoomfull","bird","help","reset","toggleoptions"], 226 'standardSet' : ["reference","zoomin","zoomout","zoomarea","zoomfull","help","reset","toggleoptions"],
233 'specialSet' : ["mark","delmark","hmir","vmir","rot","brgt","cont","rgb","quality","scale","toggleoptions"], 227 'specialSet' : ["mark","delmark","hmir","vmir","rot","brgt","cont","rgb","quality","scale","toggleoptions"],
234 'buttonSets' : ['standardSet', 'specialSet'] 228 'buttonSets' : ['standardSet', 'specialSet']
235 } 229 }
236 }, 230 },
237
238 // number of visible button groups 231 // number of visible button groups
239 'visibleButtonSets' : 1, 232 'visibleButtonSets' : 1,
240 // is birdView shown?
241 'isBirdDivVisible' : false,
242 // dimensions of bird's eye div
243 'birdDivWidth' : 200,
244 'birdDivHeight' : 200,
245 // parameters used by bird's eye div
246 'birdDivParams' : ['fn','pn','dw','dh'],
247 // style of the zoom area indicator in the bird's eye div
248 'birdIndicatorStyle' : {'border' : '2px solid #ff0000' },
249 // style of zoom area "rubber band"
250 'zoomrectStyle' : {'border' : '2px solid #ff0000' },
251 // is the "about" window shown? 233 // is the "about" window shown?
252 'isAboutDivVisible' : false, 234 'isAboutDivVisible' : false,
253 // maximum width of background image for drag-scroll 235 // default size of background image for drag-scroll (same as Bird's Eye View image)
254 'maxBgSize' : 10000 236 'bgImgWidth' : 200,
255 237 'bgImgHeight' : 200,
238 // maximum width or height of background image for drag-scroll
239 'maxBgSize' : 10000,
240 // parameters used by background image
241 'bgImgParams' : ['fn','pn','dw','dh','mo','rot'],
242 // space to be left free in full page display, default value is for scrollbar
243 'scalerInset' : 10
256 }; 244 };
257 245
258 // affine geometry classes 246 // list of plugins
259 var geom = dlGeometry(); 247 var plugins = {};
260 248 // object to export functions to plugins
261 var FULL_AREA = geom.rectangle(0, 0, 1, 1); 249 var fn;
250 // affine geometry plugin stub
251 var geom;
252
253 var FULL_AREA;
262 254
263 var actions = { 255 var actions = {
264 // init: digilib initialization 256 // init: digilib initialization
265 init : function(options) { 257 init : function(options) {
258 // import geometry classes
259 if (plugins.geometry == null) {
260 $.error("jquery.digilib.geometry plugin not found!");
261 // last straw: old version
262 geom = dlGeometry();
263 } else {
264 // geometry plugin puts classes in the shared fn
265 geom = fn.geometry;
266 }
267 FULL_AREA = geom.rectangle(0, 0, 1, 1);
268
266 // settings for this digilib instance are merged from defaults and options 269 // settings for this digilib instance are merged from defaults and options
267 var settings = $.extend({}, defaults, options); 270 var settings = $.extend({}, defaults, options);
268 var isFullscreen = settings.interactionMode === 'fullscreen'; 271 var isFullscreen = settings.interactionMode === 'fullscreen';
269 var queryParams = {}; 272 var queryParams = {};
270 if (isFullscreen) { 273 if (isFullscreen) {
292 // merge query parameters 295 // merge query parameters
293 if (isFullscreen) { 296 if (isFullscreen) {
294 params = queryParams; 297 params = queryParams;
295 } else { 298 } else {
296 params = parseImgParams($elem); 299 params = parseImgParams($elem);
297 if (jQuery.cookie) { 300 if ($.cookie) {
298 // retrieve params from cookie 301 // retrieve params from cookie
299 var ck = "digilib-embed:fn:" + escape(params.fn) + ":pn:" + (params.pn || '1'); 302 var ck = "digilib-embed:fn:" + escape(params.fn) + ":pn:" + (params.pn || '1');
300 var cs = jQuery.cookie(ck); 303 var cs = $.cookie(ck);
301 console.debug("get cookie=", ck, " value=", cs); 304 console.debug("get cookie=", ck, " value=", cs);
302 if (cs) { 305 if (cs) {
303 var cp = parseQueryString(cs); 306 var cp = parseQueryString(cs);
304 // ignore fn and pn from cookie TODO: should we keep pn? 307 // ignore fn and pn from cookie TODO: should we keep pn?
305 delete cp.fn; 308 delete cp.fn;
306 delete cp.pn; 309 delete cp.pn;
307 jQuery.extend(params, cp); 310 $.extend(params, cp);
308 } 311 }
309 } 312 }
310 } 313 }
311 // store $(this) element in the settings 314 // store $(this) element in data
312 elemSettings = jQuery.extend({}, settings, params); 315 elemSettings = $.extend({}, settings, params);
313 data = { 316 data = {
314 $elem : $elem, 317 $elem : $elem,
315 settings : elemSettings, 318 settings : elemSettings,
316 queryParams : params 319 queryParams : params,
320 // TODO: move plugins reference out of data
321 plugins : plugins
317 }; 322 };
318 // store in data element 323 // store in jQuery data element
319 $elem.data('digilib', data); 324 $elem.data('digilib', data);
320 } 325 }
321 unpackParams(data); 326 unpackParams(data);
322 // check if browser knows *background-size 327 // check if browser knows *background-size
323 for (var bs in {'':1, '-moz-':1, '-webkit-':1, '-o-':1}) { 328 for (var bs in {'':1, '-moz-':1, '-webkit-':1, '-o-':1}) {
341 var bp = url.indexOf('/servlet/Scaler'); 346 var bp = url.indexOf('/servlet/Scaler');
342 elemSettings.digilibBaseUrl = url.substring(0, bp) + '/digilib.jsp'; 347 elemSettings.digilibBaseUrl = url.substring(0, bp) + '/digilib.jsp';
343 } 348 }
344 } 349 }
345 } 350 }
351 // initialise plugins
352 for (n in plugins) {
353 var p = plugins[n];
354 if (typeof p.init === 'function') {
355 p.init(data);
356 }
357 }
346 // get image info from server if needed 358 // get image info from server if needed
347 if (data.scaleMode === 'pixel' || data.scaleMode === 'size') { 359 if (data.scaleMode === 'pixel' || data.scaleMode === 'size') {
348 loadImageInfo(data, updateDisplay); // updateDisplay(data) on completion 360 $(data).bind('imageInfo', handleImageInfo);
349 } 361 loadImageInfo(data); // triggers "imageInfo" on completion
350 // create HTML structure for scaler 362 }
351 setupScalerDiv(data); 363 // create buttons before scaler
352 // add buttons
353 for (var i = 0; i < elemSettings.visibleButtonSets; ++i) { 364 for (var i = 0; i < elemSettings.visibleButtonSets; ++i) {
354 showButtons(data, true, i); 365 showButtons(data, true, i);
355 } 366 }
367 // create HTML structure for scaler, taking width of buttons div into account
368 setupScalerDiv(data);
356 highlightButtons(data); 369 highlightButtons(data);
357 // bird's eye view creation
358 if (elemSettings.isBirdDivVisible) {
359 setupBirdDiv(data);
360 data.$birdDiv.show();
361 }
362 // about window creation - TODO: could be deferred? restrict to only one item? 370 // about window creation - TODO: could be deferred? restrict to only one item?
363 setupAboutDiv(data); 371 setupAboutDiv(data);
364 // drag zoom area around in scaler div 372 // send setup event
365 // setupZoomDrag(data); // is done in scalerImgLoadedHandler() 373 $(data).trigger('setup');
366 }); 374 });
367 }, 375 },
368 376
369 // destroy: clean up digilib 377 // destroy: clean up digilib
370 destroy : function(data) { 378 destroy : function(data) {
379 // show or hide the 'about' window 387 // show or hide the 'about' window
380 showAboutDiv : function(data, show) { 388 showAboutDiv : function(data, show) {
381 var on = showDiv(data.settings.isAboutDivVisible, data.$aboutDiv, show); 389 var on = showDiv(data.settings.isAboutDivVisible, data.$aboutDiv, show);
382 data.settings.isAboutDivVisible = on; 390 data.settings.isAboutDivVisible = on;
383 highlightButtons(data, 'help', on); 391 highlightButtons(data, 'help', on);
384 },
385
386 // event handler: toggles the visibility of the bird's eye window
387 showBirdDiv : function (data, show) {
388 var settings = data.settings;
389 if (data.$birdDiv == null) {
390 // no bird div -> create
391 setupBirdDiv(data);
392 }
393 var on = showDiv(settings.isBirdDivVisible, data.$birdDiv, show);
394 settings.isBirdDivVisible = on;
395 highlightButtons(data, 'bird', on);
396 updateBirdDiv(data);
397 storeOptions(data);
398 }, 392 },
399 393
400 // goto given page nr (+/-: relative) 394 // goto given page nr (+/-: relative)
401 gotoPage : function (data, pageNr) { 395 gotoPage : function (data, pageNr) {
402 var settings = data.settings; 396 var settings = data.settings;
612 if (res != null) { 606 if (res != null) {
613 data.settings.ddpi = res; 607 data.settings.ddpi = res;
614 redisplay(data); 608 redisplay(data);
615 } 609 }
616 }, 610 },
617 611
618 // set image scale mode 612 // set image scale mode
619 setScaleMode : function (data, mode) { 613 setScaleMode : function (data, mode) {
620 var oldM = getScaleMode(data); 614 var oldM = getScaleMode(data);
621 if (mode == null) { 615 if (mode == null) {
622 mode = window.prompt("Image scale mode (screen, pixel, size)", oldM); 616 mode = window.prompt("Image scale mode (screen, pixel, size)", oldM);
625 setScaleMode(data, mode); 619 setScaleMode(data, mode);
626 data.scaleMode = mode; 620 data.scaleMode = mode;
627 redisplay(data); 621 redisplay(data);
628 } 622 }
629 } 623 }
630 624
631 // end of actions 625 // end of actions
632 }; 626 };
633 627
634 // returns parameters from page url 628 // returns parameters from page url
635 var parseQueryParams = function() { 629 var parseQueryParams = function() {
696 var url = settings.scalerBaseUrl + '?' + queryString; 690 var url = settings.scalerBaseUrl + '?' + queryString;
697 return url; 691 return url;
698 }; 692 };
699 693
700 // returns URL for bird's eye view image 694 // returns URL for bird's eye view image
701 var getBirdImgUrl = function (data, moreParams) { 695 var getBgImgUrl = function (data, moreParams) {
702 var settings = data.settings; 696 var settings = data.settings;
703 var birdDivOptions = { 697 var bgOptions = {
704 dw : settings.birdDivWidth, 698 dw : settings.bgImgWidth,
705 dh : settings.birdDivHeight 699 dh : settings.bgImgHeight
706 }; 700 };
707 var birdSettings = jQuery.extend({}, settings, birdDivOptions); 701 var bgSettings = $.extend({}, settings, bgOptions);
708 // use only the relevant parameters 702 // filter scaler flags
709 if (moreParams == null) { 703 if (bgSettings.mo != null) {
710 var params = getParamString(birdSettings, settings.birdDivParams, defaults); 704 var mo = '';
711 } else { 705 if (data.scalerFlags.hmir != null) {
712 // filter scaler flags 706 mo += 'hmir,';
713 if (birdSettings.mo != null) { 707 }
714 var mo = ''; 708 if (data.scalerFlags.vmir != null) {
715 if (data.scalerFlags.hmir != null) { 709 mo += 'vmir';
716 mo += 'hmir,'; 710 }
717 } 711 bgSettings.mo = mo;
718 if (data.scalerFlags.vmir != null) { 712 }
719 mo += 'vmir'; 713 var params = getParamString(bgSettings, settings.bgImgParams, defaults);
720 }
721 birdSettings.mo = mo;
722 }
723 var params = getParamString(birdSettings,
724 settings.birdDivParams.concat(moreParams), defaults);
725 }
726 var url = settings.scalerBaseUrl + '?' + params; 714 var url = settings.scalerBaseUrl + '?' + params;
727 return url; 715 return url;
728 }; 716 };
729 717
730 // returns URL and query string for current digilib 718 // returns URL and query string for current digilib
733 var settings = data.settings; 721 var settings = data.settings;
734 var queryString = getParamString(settings, settings.digilibParamNames, defaults); 722 var queryString = getParamString(settings, settings.digilibParamNames, defaults);
735 return settings.digilibBaseUrl + '?' + queryString; 723 return settings.digilibBaseUrl + '?' + queryString;
736 }; 724 };
737 725
738 // loads image information from digilib server via HTTP (and calls complete-fn) 726 // loads image information from digilib server via HTTP
739 var loadImageInfo = function (data, complete) { 727 var loadImageInfo = function (data) {
740 var settings = data.settings; 728 var settings = data.settings;
741 var p = settings.scalerBaseUrl.indexOf('/servlet/Scaler'); 729 var p = settings.scalerBaseUrl.indexOf('/servlet/Scaler');
742 var url = settings.scalerBaseUrl.substring(0, p) + '/ImgInfo-json.jsp'; 730 var url = settings.scalerBaseUrl.substring(0, p) + '/ImgInfo-json.jsp';
743 url += '?' + getParamString(settings, ['fn', 'pn'], defaults); 731 url += '?' + getParamString(settings, ['fn', 'pn'], defaults);
744 // TODO: better error handling 732 // TODO: better error handling
745 jQuery.getJSON(url, function (json) { 733 $.getJSON(url, function (json) {
746 console.debug("got json data=", json); 734 console.debug("got json data=", json);
747 data.imgInfo = json; 735 data.imgInfo = json;
748 if (complete != null) { 736 // send event
749 complete.call(this, data, json); 737 $(data).trigger('imageInfo', [json]);
750 }
751 }); 738 });
752 }; 739 };
753 740
754 // processes some parameters into objects and stuff 741 // processes some parameters into objects and stuff
755 var unpackParams = function (data) { 742 var unpackParams = function (data) {
756 var settings = data.settings; 743 var settings = data.settings;
757 // zoom area 744 // zoom area
758 var zoomArea = geom.rectangle(settings.wx, settings.wy, settings.ww, settings.wh); 745 var zoomArea = geom.rectangle(settings.wx, settings.wy, settings.ww, settings.wh);
835 if (clop) { 822 if (clop) {
836 clop += '&'; 823 clop += '&';
837 } 824 }
838 clop += o + '=' + data.dlOpts[o]; 825 clop += o + '=' + data.dlOpts[o];
839 } 826 }
840 if (jQuery.cookie) { 827 if ($.cookie) {
841 var ck = "digilib:fn:" + escape(settings.fn) + ":pn:" + settings.pn; 828 var ck = "digilib:fn:" + escape(settings.fn) + ":pn:" + settings.pn;
842 console.debug("set cookie=", ck, " value=", clop); 829 console.debug("set cookie=", ck, " value=", clop);
843 jQuery.cookie(ck, clop); 830 $.cookie(ck, clop);
844 } 831 }
845 } 832 }
846 if (settings.interactionMode !== 'fullscreen' && jQuery.cookie) { 833 if (settings.interactionMode !== 'fullscreen' && $.cookie) {
847 // store normal parameters in cookie for embedded mode 834 // store normal parameters in cookie for embedded mode
848 var qs = getParamString(settings, settings.digilibParamNames, defaults); 835 var qs = getParamString(settings, settings.digilibParamNames, defaults);
849 var ck = "digilib-embed:fn:" + escape(settings.fn) + ":pn:" + settings.pn; 836 var ck = "digilib-embed:fn:" + escape(settings.fn) + ":pn:" + settings.pn;
850 console.debug("set cookie=", ck, " value=", qs); 837 console.debug("set cookie=", ck, " value=", qs);
851 jQuery.cookie(ck, qs); 838 $.cookie(ck, qs);
852 } 839 }
853 }; 840 };
854 841
855 var retrieveOptions = function (data) { 842 var retrieveOptions = function (data) {
856 // clop (digilib options) 843 // clop (digilib options)
857 var opts = {}; 844 var opts = {};
858 var settings = data.settings; 845 var settings = data.settings;
859 if (jQuery.cookie) { 846 if ($.cookie) {
860 // read from cookie 847 // read from cookie
861 var ck = "digilib:fn:" + escape(settings.fn) + ":pn:" + settings.pn; 848 var ck = "digilib:fn:" + escape(settings.fn) + ":pn:" + settings.pn;
862 var cp = jQuery.cookie(ck); 849 var cp = $.cookie(ck);
863 console.debug("get cookie=", ck, " value=", cp); 850 console.debug("get cookie=", ck, " value=", cp);
864 // in query string format 851 // in query string format
865 opts = parseQueryString(cp); 852 opts = parseQueryString(cp);
866 } 853 }
867 data.dlOpts = opts; 854 data.dlOpts = opts;
880 var settings = data.settings; 867 var settings = data.settings;
881 if (settings.interactionMode === 'fullscreen') { 868 if (settings.interactionMode === 'fullscreen') {
882 // update location.href (browser URL) in fullscreen mode 869 // update location.href (browser URL) in fullscreen mode
883 var url = getDigilibUrl(data); 870 var url = getDigilibUrl(data);
884 var history = window.history; 871 var history = window.history;
885 if (typeof(history.pushState) === 'function') { 872 if (typeof history.pushState === 'function') {
886 console.debug("we could modify history, but we don't..."); 873 console.debug("faking reload to "+url);
887 } 874 // change url without reloading (stateObj, title, url)
888 window.location = url; 875 history.pushState({}, '', url);
876 // change img src
877 var imgurl = getScalerUrl(data);
878 data.$img.attr('src', imgurl);
879 highlightButtons(data);
880 // send event
881 $(data).trigger('redisplay');
882 } else {
883 // reload window
884 window.location = url;
885 }
889 } else { 886 } else {
890 // embedded mode -- just change img src 887 // embedded mode -- just change img src
891 var url = getScalerUrl(data); 888 var url = getScalerUrl(data);
892 data.$img.attr('src', url); 889 data.$img.attr('src', url);
893 // redisplay bird img
894 updateBirdDiv(data);
895 highlightButtons(data); 890 highlightButtons(data);
891 // send event
892 $(data).trigger('redisplay');
896 } 893 }
897 }; 894 };
898 895
899 // update display (overlays etc.) 896 // update display (overlays etc.)
900 var updateDisplay = function (data) { 897 var updateDisplay = function (data) {
901 updateImgTrafo(data); 898 updateImgTrafo(data);
902 renderMarks(data); 899 renderMarks(data);
903 setupZoomDrag(data); 900 setupZoomDrag(data);
904 if (data.settings.isBirdDivVisible) { 901 // send event
905 renderBirdArea(data); 902 $(data).trigger('update');
906 setupBirdDrag(data); 903 };
907 } 904
908 // TODO: update event subscriber?
909 };
910
911 // returns maximum size for scaler img in fullscreen mode 905 // returns maximum size for scaler img in fullscreen mode
912 var getFullscreenImgSize = function ($elem) { 906 var getFullscreenImgSize = function (data) {
913 var $win = $(window); 907 var $win = $(window);
914 var winH = $win.height(); 908 var winH = $win.height();
915 var winW = $win.width(); 909 var winW = $win.width();
916 // TODO: account for borders? 910 var $body = $('body');
917 return geom.size(winW, winH); 911 // include standard body margins
912 var borderW = $body.outerWidth(true) - $body.width();
913 var borderH = $body.outerHeight(true) - $body.height();
914 // get width of first button div
915 var buttonsW = 0;
916 if (data.$buttonSets) {
917 buttonsW = data.$buttonSets[0].outerWidth();
918 }
919 // account for left/right border, body margins and additional requirements
920 var calcW = winW - borderW - buttonsW - data.settings.scalerInset;
921 var calcH = winH - borderH;
922 console.debug(winW, winH, 'winW:', $win.width(), 'border:', borderW, 'buttonsW:', buttonsW, 'calc:', calcW);
923 return geom.size(calcW, calcH);
918 }; 924 };
919 925
920 // creates HTML structure for digilib in elem 926 // creates HTML structure for digilib in elem
921 var setupScalerDiv = function (data) { 927 var setupScalerDiv = function (data) {
922 var settings = data.settings; 928 var settings = data.settings;
925 var $img; 931 var $img;
926 var scalerUrl; 932 var scalerUrl;
927 if (settings.interactionMode === 'fullscreen') { 933 if (settings.interactionMode === 'fullscreen') {
928 // fullscreen 934 // fullscreen
929 $elem.addClass('dl_fullscreen'); 935 $elem.addClass('dl_fullscreen');
930 var imgSize = getFullscreenImgSize($elem); 936 var imgSize = getFullscreenImgSize(data);
931 // fitwidth/height omits destination height/width 937 // fitwidth/height omits destination height/width
932 if (data.dlOpts.fitheight == null) { 938 if (data.dlOpts.fitheight == null) {
933 settings.dw = imgSize.width; 939 settings.dw = imgSize.width;
934 } 940 }
935 if (data.dlOpts.fitwidth == null) { 941 if (data.dlOpts.fitwidth == null) {
952 } 958 }
953 } else { 959 } else {
954 $img = $('<img/>'); 960 $img = $('<img/>');
955 } 961 }
956 } 962 }
957 // create new html 963 // create new inner html, keep buttons
958 $elem.empty(); // TODO: should we keep stuff for customization? 964 $elem.contents(":not(div.buttons)").remove();
959 var $scaler = $('<div class="scaler"/>'); 965 var $scaler = $('<div class="scaler"/>');
960 $elem.append($scaler); 966 // scaler should be the first child element?
967 $elem.prepend($scaler);
961 $scaler.append($img); 968 $scaler.append($img);
962 $img.addClass('pic'); 969 $img.addClass('pic');
963 data.$scaler = $scaler; 970 data.$scaler = $scaler;
964 data.$img = $img; 971 data.$img = $img;
965 // setup image load handler before setting the src attribute (IE bug) 972 // setup image load handler before setting the src attribute (IE bug)
1031 data.$buttonSets[buttonSetIdx] = $buttonsDiv; 1038 data.$buttonSets[buttonSetIdx] = $buttonsDiv;
1032 } 1039 }
1033 return $buttonsDiv; 1040 return $buttonsDiv;
1034 }; 1041 };
1035 1042
1036 // creates HTML structure for the bird's eye view in elem
1037 var setupBirdDiv = function (data) {
1038 var $elem = data.$elem;
1039 // the bird's eye div
1040 var $birdDiv = $('<div class="birdview" style="display:none"/>');
1041 // the detail indicator frame
1042 var $birdZoom = $('<div class="birdzoom" style="display:none; background-color:transparent;"/>');
1043 // the small image
1044 var $birdImg = $('<img class="birdimg"/>');
1045 data.$birdDiv = $birdDiv;
1046 data.$birdZoom = $birdZoom;
1047 data.$birdImg = $birdImg;
1048 $elem.append($birdDiv);
1049 $birdDiv.append($birdZoom);
1050 $birdDiv.append($birdImg);
1051 $birdZoom.css(data.settings.birdIndicatorStyle);
1052 var birdUrl = getBirdImgUrl(data);
1053 $birdImg.load(birdImgLoadedHandler(data));
1054 $birdImg.error(function () {console.error("error loading birdview image");});
1055 $birdImg.attr('src', birdUrl);
1056 };
1057
1058 // update bird's eye view
1059 var updateBirdDiv = function (data) {
1060 if (!data.settings.isBirdDivVisible) return;
1061 var $birdImg = data.$birdImg;
1062 var oldsrc = $birdImg.attr('src');
1063 var newsrc = getBirdImgUrl(data);
1064 if (oldsrc !== newsrc) {
1065 $birdImg.attr('src', newsrc);
1066 // onload handler re-renders
1067 } else {
1068 // re-render
1069 renderBirdArea(data);
1070 // enable click and drag
1071 setupBirdDrag(data);
1072 }
1073 };
1074
1075 // creates HTML structure for the about view in elem 1043 // creates HTML structure for the about view in elem
1076 var setupAboutDiv = function (data) { 1044 var setupAboutDiv = function (data) {
1077 var $elem = data.$elem; 1045 var $elem = data.$elem;
1078 var settings = data.settings; 1046 var settings = data.settings;
1079 var $aboutDiv = $('<div class="about" style="display:none"/>'); 1047 var $aboutDiv = $('<div class="about" style="display:none"/>');
1087 $aboutDiv.append($content); 1055 $aboutDiv.append($content);
1088 $link.append($logo); 1056 $link.append($logo);
1089 $logo.attr('src', settings.logoUrl); 1057 $logo.attr('src', settings.logoUrl);
1090 $link.attr('href', settings.homeUrl); 1058 $link.attr('href', settings.homeUrl);
1091 $content.text('Version: ' + settings.version); 1059 $content.text('Version: ' + settings.version);
1060 data.$aboutDiv = $aboutDiv;
1092 // click hides 1061 // click hides
1093 $aboutDiv.bind('click.digilib', function () { 1062 $aboutDiv.bind('click.digilib', function () {
1094 settings.isAboutDivVisible = showDiv(settings.isAboutDivVisible, $aboutDiv, 0); 1063 actions['showAboutDiv'](data, false);
1095 return false;
1096 }); 1064 });
1097 data.$aboutDiv = $aboutDiv;
1098 }; 1065 };
1099 1066
1100 // shows some window e.g. 'about' (toggle visibility if show is null) 1067 // shows some window e.g. 'about' (toggle visibility if show is null)
1101 var showDiv = function (isVisible, $div, show) { 1068 var showDiv = function (isVisible, $div, show) {
1102 if (show == null) { 1069 if (show == null) {
1128 $set = createButtons(data, setIdx); 1095 $set = createButtons(data, setIdx);
1129 } 1096 }
1130 if ($set == null) return false; 1097 if ($set == null) return false;
1131 // include border in calculation 1098 // include border in calculation
1132 var btnWidth = $set.outerWidth(); 1099 var btnWidth = $set.outerWidth();
1100 // console.debug("btnWidth", btnWidth);
1133 // move remaining sets left and show new set 1101 // move remaining sets left and show new set
1134 if ($otherSets.length > 0) { 1102 if ($otherSets.length > 0) {
1135 $otherSets.animate({right : '+='+btnWidth+'px'}, atime, 1103 $otherSets.animate({right : '+='+btnWidth+'px'}, atime,
1136 function () {$set.show();}); 1104 function () {$set.show();});
1137 } else { 1105 } else {
1139 } 1107 }
1140 } else { 1108 } else {
1141 // remove set 1109 // remove set
1142 var $set = data.$buttonSets[setIdx]; 1110 var $set = data.$buttonSets[setIdx];
1143 if ($set == null) return false; 1111 if ($set == null) return false;
1144 var btnWidth = $set.width(); 1112 var btnWidth = $set.outerWidth();
1145 // hide last set 1113 // hide last set
1146 $set.hide(); 1114 $set.hide();
1147 // take remaining sets and move right 1115 // take remaining sets and move right
1148 var $otherSets = data.$elem.find('div.buttons:visible'); 1116 var $otherSets = data.$elem.find('div.buttons:visible');
1149 $otherSets.animate({right : '-='+btnWidth+'px'}, atime); 1117 $otherSets.animate({right : '-='+btnWidth+'px'}, atime);
1176 highlight('hmir', flags.hmir); 1144 highlight('hmir', flags.hmir);
1177 highlight('vmir', flags.vmir); 1145 highlight('vmir', flags.vmir);
1178 highlight('quality', flags.q1 || flags.q2); 1146 highlight('quality', flags.q1 || flags.q2);
1179 highlight('zoomin', ! isFullArea(data.zoomArea)); 1147 highlight('zoomin', ! isFullArea(data.zoomArea));
1180 }; 1148 };
1181 1149
1182 // create Transform from area and $img 1150 // create Transform from area and $img
1183 var getImgTrafo = function ($img, area, rot, hmir, vmir, mode, data) { 1151 var getImgTrafo = function ($img, area, rot, hmir, vmir, mode, data) {
1184 var picrect = geom.rectangle($img); 1152 var picrect = geom.rectangle($img);
1185 if (mode != null) { 1153 if (mode != null) {
1186 var imgInfo = data.imgInfo; 1154 var imgInfo = data.imgInfo;
1243 data.settings.rot, data.scalerFlags.hmir, data.scalerFlags.vmir, 1211 data.settings.rot, data.scalerFlags.hmir, data.scalerFlags.vmir,
1244 data.scaleMode, data); 1212 data.scaleMode, data);
1245 // console.debug("imgTrafo=", data.imgTrafo); 1213 // console.debug("imgTrafo=", data.imgTrafo);
1246 } 1214 }
1247 }; 1215 };
1248 1216
1249 // returns function for load event of scaler img 1217 // returns handler for load event of scaler img
1250 var scalerImgLoadedHandler = function (data) { 1218 var scalerImgLoadedHandler = function (data) {
1251 return function () { 1219 return function () {
1252 var $img = $(this); 1220 var $img = $(this);
1253 console.debug("scaler img loaded=",$img); 1221 console.debug("scaler img loaded=",$img);
1254 var $scaler = data.$scaler; 1222 var $scaler = data.$scaler;
1261 // update display (render marks, etc.) 1229 // update display (render marks, etc.)
1262 updateDisplay(data); 1230 updateDisplay(data);
1263 }; 1231 };
1264 }; 1232 };
1265 1233
1266 // returns function for load event of bird's eye view img 1234 // handler for imageInfo loaded event
1267 var birdImgLoadedHandler = function (data) { 1235 var handleImageInfo = function (evt, json) {
1268 return function () { 1236 var data = this;
1269 var $birdImg = $(this); 1237 updateDisplay(data);
1270 var birdRect = geom.rectangle($birdImg); 1238 };
1271 console.debug("birdImg loaded!", $birdImg, "rect=", birdRect, "data=", data); 1239
1272 if (birdRect.width === 0) {
1273 // malheureusement IE7 calls load handler when there is no size info yet
1274 setTimeout(function () { $birdImg.triggerHandler('load'); }, 200);
1275 }
1276 // update display (zoom area indicator)
1277 updateDisplay(data);
1278 };
1279 };
1280
1281 // place marks on the image 1240 // place marks on the image
1282 var renderMarks = function (data) { 1241 var renderMarks = function (data) {
1283 if (data.$img == null || data.imgTrafo == null) return; 1242 if (data.$img == null || data.imgTrafo == null) return;
1284 console.debug("rendermarks img=",data.$img," imgtrafo=",data.imgTrafo); 1243 console.debug("rendermarks img=",data.$img," imgtrafo=",data.imgTrafo);
1285 var $elem = data.$elem; 1244 var $elem = data.$elem;
1298 mpos.adjustDiv($mark); 1257 mpos.adjustDiv($mark);
1299 } 1258 }
1300 } 1259 }
1301 }; 1260 };
1302 1261
1303 // show zoom area indicator on bird's eye view
1304 var renderBirdArea = function (data) {
1305 if (data.$birdImg == null || ! data.$birdImg.get(0).complete) return;
1306 var $birdZoom = data.$birdZoom;
1307 var zoomArea = data.zoomArea;
1308 var normalSize = isFullArea(zoomArea);
1309 if (normalSize) {
1310 $birdZoom.hide();
1311 return;
1312 } else {
1313 $birdZoom.show();
1314 }
1315 // create Transform from current area and picsize
1316 data.birdTrafo = getImgTrafo(data.$birdImg, FULL_AREA);
1317 var zoomRect = data.birdTrafo.transform(zoomArea);
1318 console.debug("renderBirdArea:", zoomRect, "zoomArea:", zoomArea, "$birdTrafo:", data.birdTrafo);
1319 // acount for border width
1320 zoomRect.addPosition({x : -2, y : -2});
1321 if (data.settings.interactionMode === 'fullscreen') {
1322 // no animation for fullscreen
1323 zoomRect.adjustDiv($birdZoom);
1324 } else {
1325 // nice animation for embedded mode :-)
1326 // correct offsetParent because animate doesn't use offset
1327 var ppos = $birdZoom.offsetParent().offset();
1328 var dest = {
1329 left : (zoomRect.x - ppos.left) + 'px',
1330 top : (zoomRect.y - ppos.top) + 'px',
1331 width : zoomRect.width,
1332 height : zoomRect.height
1333 };
1334 $birdZoom.animate(dest);
1335 }
1336 };
1337
1338 // zooms by the given factor 1262 // zooms by the given factor
1339 var zoomBy = function(data, factor) { 1263 var zoomBy = function(data, factor) {
1340 var area = data.zoomArea; 1264 var area = data.zoomArea;
1341 var newarea = area.copy(); 1265 var newarea = area.copy();
1342 // scale 1266 // scale
1372 $elem = data.$elem; 1296 $elem = data.$elem;
1373 $scaler = data.$scaler; 1297 $scaler = data.$scaler;
1374 var pt1, pt2; 1298 var pt1, pt2;
1375 var $zoomDiv = $('<div class="zoomrect" style="display:none"/>'); 1299 var $zoomDiv = $('<div class="zoomrect" style="display:none"/>');
1376 $elem.append($zoomDiv); 1300 $elem.append($zoomDiv);
1377 $zoomDiv.css(data.settings.zoomrectStyle); 1301 // $zoomDiv.css(data.settings.zoomrectStyle);
1378 var picRect = geom.rectangle($scaler); 1302 var picRect = geom.rectangle($scaler);
1379 // FIX ME: is there a way to query the border width from CSS info? 1303 // FIX ME: is there a way to query the border width from CSS info?
1380 // rect.x -= 2; // account for overlay borders 1304 // rect.x -= 2; // account for overlay borders
1381 // rect.y -= 2; 1305 // rect.y -= 2;
1382 1306
1429 $scaler.unbind('.dlZoomArea'); 1353 $scaler.unbind('.dlZoomArea');
1430 $scaler.unbind(".dlZoomDrag"); 1354 $scaler.unbind(".dlZoomDrag");
1431 $elem.unbind('.dlZoomArea'); 1355 $elem.unbind('.dlZoomArea');
1432 // bind start zoom handler 1356 // bind start zoom handler
1433 $scaler.one('mousedown.dlZoomArea', zoomStart); 1357 $scaler.one('mousedown.dlZoomArea', zoomStart);
1434 };
1435
1436 // bird's eye view zoom area click and drag handler
1437 var setupBirdDrag = function(data) {
1438 var $birdImg = data.$birdImg;
1439 var $birdZoom = data.$birdZoom;
1440 var $document = $(document);
1441 var $scaler = data.$scaler;
1442 var startPos, newRect, birdImgRect, birdZoomRect, fullRect, scalerPos;
1443
1444 // mousedown handler: start dragging bird zoom to a new position
1445 var birdZoomStartDrag = function(evt) {
1446 startPos = geom.position(evt);
1447 // position may have changed
1448 data.birdTrafo = getImgTrafo($birdImg, FULL_AREA);
1449 birdImgRect = geom.rectangle($birdImg);
1450 birdZoomRect = geom.rectangle($birdZoom);
1451 scalerPos = geom.position($scaler);
1452 newRect = null;
1453 fullRect = setZoomBG(data); // setup zoom background image
1454 $document.bind("mousemove.dlBirdMove", birdZoomMove);
1455 $document.bind("mouseup.dlBirdMove", birdZoomEndDrag);
1456 return false;
1457 };
1458
1459 // mousemove handler: drag
1460 var birdZoomMove = function(evt) {
1461 var pos = geom.position(evt);
1462 var delta = startPos.delta(pos);
1463 // move birdZoom div, keeping size
1464 newRect = birdZoomRect.copy();
1465 newRect.addPosition(delta);
1466 newRect.stayInside(birdImgRect);
1467 // reflect birdview zoom position in scaler image
1468 var area = data.birdTrafo.invtransform(newRect);
1469 var imgArea = data.imgTrafo.transform(area);
1470 var offset = imgArea.getPosition().neg();
1471 offset.add(scalerPos);
1472 if (fullRect) {
1473 var bgPos = fullRect.getPosition().add(offset);
1474 } else {
1475 var bgPos = offset;
1476 }
1477 // move the background image to the new position
1478 data.$scaler.css({
1479 'background-position' : bgPos.x + "px " + bgPos.y + "px"
1480 });
1481 // acount for border width
1482 newRect.addPosition({x : -2, y : -2});
1483 newRect.adjustDiv($birdZoom);
1484 return false;
1485 };
1486
1487 // mouseup handler: reload page
1488 var birdZoomEndDrag = function(evt) {
1489 var settings = data.settings;
1490 $document.unbind("mousemove.dlBirdMove", birdZoomMove);
1491 $document.unbind("mouseup.dlBirdMove", birdZoomEndDrag);
1492 if (newRect == null) {
1493 // no movement happened - set center to click position
1494 startPos = birdZoomRect.getCenter();
1495 birdZoomMove(evt);
1496 }
1497 // ugly, but needed to prevent double border width compensation
1498 newRect.addPosition({x : +2, y : +2});
1499 var newArea = data.birdTrafo.invtransform(newRect);
1500 data.zoomArea = newArea;
1501 redisplay(data);
1502 return false;
1503 };
1504
1505 // clear old handler
1506 $document.unbind(".dlBirdMove");
1507 $birdImg.unbind(".dlBirdMove");
1508 $birdZoom.unbind(".dlBirdMove");
1509 if (! isFullArea(data.zoomArea)) {
1510 // set new handler
1511 $birdImg.bind("mousedown.dlBirdMove", birdZoomStartDrag);
1512 $birdZoom.bind("mousedown.dlBirdMove", birdZoomStartDrag);
1513 }
1514 };
1515
1516 // move bird zoom indicator to reflect zoomed detail area
1517 var setBirdZoom = function(data, rect) {
1518 var part = data.imgTrafo.invtransform(rect);
1519 // area = FULL_AREA.fit(part); // no, we want to see where we transcend the borders
1520 birdTrafo = getImgTrafo(data.$birdImg, FULL_AREA);
1521 var birdRect = birdTrafo.transform(part);
1522 // acount for border width
1523 birdRect.addPosition({x : -2, y : -2});
1524 birdRect.adjustDiv(data.$birdZoom);
1525 }; 1358 };
1526 1359
1527 // set zoom background 1360 // set zoom background
1528 var setZoomBG = function(data) { 1361 var setZoomBG = function(data) {
1529 var $scaler = data.$scaler; 1362 var $scaler = data.$scaler;
1545 fullRect = data.imgTrafo.transform(FULL_AREA); 1378 fullRect = data.imgTrafo.transform(FULL_AREA);
1546 if (fullRect.height < data.settings.maxBgSize && fullRect.width < data.settings.maxBgSize) { 1379 if (fullRect.height < data.settings.maxBgSize && fullRect.width < data.settings.maxBgSize) {
1547 // correct offset because background is relative 1380 // correct offset because background is relative
1548 var scalerPos = geom.position($scaler); 1381 var scalerPos = geom.position($scaler);
1549 fullRect.addPosition(scalerPos.neg()); 1382 fullRect.addPosition(scalerPos.neg());
1550 var url = getBirdImgUrl(data, ['rot', 'mo']); 1383 var url = getBgImgUrl(data);
1551 scalerCss['background-image'] = 'url(' + url + ')'; 1384 scalerCss['background-image'] = 'url(' + url + ')';
1552 scalerCss[data.bgSizeName] = fullRect.width + 'px ' + fullRect.height + 'px'; 1385 scalerCss[data.bgSizeName] = fullRect.width + 'px ' + fullRect.height + 'px';
1553 scalerCss['background-position'] = fullRect.x + 'px '+ fullRect.y + 'px'; 1386 scalerCss['background-position'] = fullRect.x + 'px '+ fullRect.y + 'px';
1554 } else { 1387 } else {
1555 // too big 1388 // too big
1563 1396
1564 // setup handlers for dragging the zoomed image 1397 // setup handlers for dragging the zoomed image
1565 var setupZoomDrag = function(data) { 1398 var setupZoomDrag = function(data) {
1566 var startPos, delta, fullRect; 1399 var startPos, delta, fullRect;
1567 var $document = $(document); 1400 var $document = $(document);
1401 var $data = $(data);
1568 var $elem = data.$elem; 1402 var $elem = data.$elem;
1569 var $scaler = data.$scaler; 1403 var $scaler = data.$scaler;
1570 var $img = data.$img; 1404 var $img = data.$img;
1571 1405
1572 // drag the image and load a new detail on mouse up 1406 // drag the image and load a new detail on mouse up
1597 'background-position' : bgPos.x + "px " + bgPos.y + "px" 1431 'background-position' : bgPos.x + "px " + bgPos.y + "px"
1598 }); 1432 });
1599 // set birdview indicator to reflect new zoom position 1433 // set birdview indicator to reflect new zoom position
1600 var za = geom.rectangle($img); 1434 var za = geom.rectangle($img);
1601 za.addPosition(delta.neg()); 1435 za.addPosition(delta.neg());
1602 setBirdZoom(data, za); 1436 $data.trigger('dragZoom', [za]);
1437 //TODO: setBirdZoom(data, za);
1603 return false; 1438 return false;
1604 }; 1439 };
1605 1440
1606 // mouseup handler: reload zoomed image in new position 1441 // mouseup handler: reload zoomed image in new position
1607 var dragEnd = function (evt) { 1442 var dragEnd = function (evt) {
1661 return 'size'; 1496 return 'size';
1662 } 1497 }
1663 // mo=fit is default 1498 // mo=fit is default
1664 return 'screen'; 1499 return 'screen';
1665 }; 1500 };
1666 1501
1667 // set image scale mode (screen, pixel, size) 1502 // set image scale mode (screen, pixel, size)
1668 var setScaleMode = function (data, mode) { 1503 var setScaleMode = function (data, mode) {
1669 delete data.scalerFlags.fit; 1504 delete data.scalerFlags.fit;
1670 delete data.scalerFlags.clip; 1505 delete data.scalerFlags.clip;
1671 delete data.scalerFlags.osize; 1506 delete data.scalerFlags.osize;
1674 } else if (mode === 'size') { 1509 } else if (mode === 'size') {
1675 data.scalerFlags.osize = 'osize'; 1510 data.scalerFlags.osize = 'osize';
1676 } 1511 }
1677 // mo=fit is default 1512 // mo=fit is default
1678 }; 1513 };
1679 1514
1680 // sets a key to a value (relative values with +/- if relative=true) 1515 // sets a key to a value (relative values with +/- if relative=true)
1681 var setNumValue = function(settings, key, value) { 1516 var setNumValue = function(settings, key, value) {
1682 if (value == null) return null; 1517 if (value == null) return null;
1683 if (isNumber(value)) { 1518 if (isNumber(value)) {
1684 settings[key] = value; 1519 settings[key] = value;
1695 settings[key] = value; 1530 settings[key] = value;
1696 } 1531 }
1697 return settings[key]; 1532 return settings[key];
1698 }; 1533 };
1699 1534
1535 // auxiliary function, assuming equal border width on all sides
1536 var getBorderWidth = function($elem) {
1537 var border = $elem.outerWidth() - $elem.width();
1538 return border/2;
1539 };
1540
1700 // auxiliary function (from old dllib.js) 1541 // auxiliary function (from old dllib.js)
1701 var isFullArea = function(area) { 1542 var isFullArea = function (area) {
1702 return (area.width === 1.0) && (area.height === 1.0); 1543 return (area.width === 1.0) && (area.height === 1.0);
1703 }; 1544 };
1704 1545
1705 // auxiliary function (from Douglas Crockford, A.10) 1546 // auxiliary function (from Douglas Crockford, A.10)
1706 var isNumber = function isNumber(value) { 1547 var isNumber = function (value) {
1707 return typeof value === 'number' && isFinite(value); 1548 return typeof value === 'number' && isFinite(value);
1708 }; 1549 };
1709 1550
1710 // auxiliary function to crop senseless precision 1551 // auxiliary function to crop senseless precision
1711 var cropFloat = function (x) { 1552 var cropFloat = function (x) {
1729 console.log = logFunction('_log'); 1570 console.log = logFunction('_log');
1730 console.debug = logFunction('_debug'); 1571 console.debug = logFunction('_debug');
1731 console.error = logFunction('_error'); 1572 console.error = logFunction('_error');
1732 } 1573 }
1733 1574
1734 // hook plugin into jquery 1575 // functions to export to plugins
1735 $.fn.digilib = function(action, obj) { 1576 fn = {
1736 // plugin extension mechanism 1577 geometry : geom,
1737 if (action === 'extendPlugin') { 1578 parseQueryString : parseQueryString,
1738 // for each digilib $elem extend data.settings with obj.options 1579 getScalerUrl : getScalerUrl,
1739 if (obj.options) { 1580 getParamString : getParamString,
1740 this.each(function() { 1581 getDigilibUrl : getDigilibUrl,
1741 var $elem = $(this); 1582 unpackParams : unpackParams,
1742 // console.debug('extending:', $elem); 1583 packParams : packParams,
1743 var data = $elem.data('digilib'); 1584 storeOptions : storeOptions,
1744 if (!data) { 1585 redisplay : redisplay,
1745 return console.log('cannot extend digilib plugin, element not initialised!'); 1586 updateDisplay : updateDisplay,
1746 } 1587 highlightButtons : highlightButtons,
1747 var settings = data.settings; 1588 showDiv : showDiv,
1748 $.extend(settings, obj.options); 1589 setZoomBG : setZoomBG,
1749 // console.log('settings:', settings); 1590 getImgTrafo : getImgTrafo,
1750 }); 1591 getQuality : getQuality,
1751 } 1592 setQuality : setQuality,
1752 delete(obj.options); 1593 getScaleMode : getScaleMode,
1753 // extend the plugin actions (to make this useful, 1594 setScaleMode : setScaleMode,
1754 // maybe we need to expose some more internal functions) 1595 isFullArea : isFullArea,
1755 $.extend(actions, obj); 1596 getBorderWidth : getBorderWidth
1597 };
1598
1599 // hook digilib plugin into jquery
1600 $.fn.digilib = function (action) {
1601 // plugin extension mechanism, called when the plugins' code is read
1602 if (action === 'plugin') {
1603 var plugin = arguments[1];
1604 // each plugin needs a name
1605 if (plugin.name != null) {
1606 plugins[plugin.name] = plugin;
1607 // share common objects
1608 plugin.defaults = defaults;
1609 plugin.buttons = buttons;
1610 plugin.actions = actions;
1611 plugin.fn = fn;
1612 plugin.plugins = plugins;
1613 // and install
1614 if (typeof plugin.install === 'function') {
1615 plugin.install(plugin);
1616 }
1617 }
1618 // plugins will be initialised when action.init is called
1756 } else if (actions[action]) { 1619 } else if (actions[action]) {
1757 // call action on this with the remaining arguments (inserting data as first argument) 1620 // call action on this with the remaining arguments (inserting data as first argument)
1758 var $elem = $(this); 1621 var $elem = $(this);
1759 var data = $elem.data('digilib'); 1622 var data = $elem.data('digilib');
1760 var args = Array.prototype.slice.call(arguments, 1); 1623 var args = Array.prototype.slice.call(arguments, 1);
1761 args.unshift(data); 1624 args.unshift(data);
1762 return actions[action].apply(this, args); 1625 return actions[action].apply(this, args);
1763 } else if (typeof(action) === 'object' || !action) { 1626 } else if (typeof action === 'object' || !action) {
1764 // call init on this 1627 // call init on the digilib jQuery object
1765 return actions.init.apply(this, arguments); 1628 return actions.init.apply(this, arguments);
1766 } else { 1629 } else {
1767 $.error('action ' + action + ' does not exist on jQuery.digilib'); 1630 $.error('action ' + action + ' does not exist on jQuery.digilib');
1768 } 1631 }
1769 }; 1632 };