diff --git a/README.md b/README.md index b2c5d1e4..1ddabf86 100644 --- a/README.md +++ b/README.md @@ -75,6 +75,8 @@ When fixing bugs and adding features, when appropriate please also: If you're new to the project, check out our [good first bug](https://github.com/openseadragon/openseadragon/issues?labels=good+first+bug&page=1&state=open) issues for some places to dip your toe in the water. +If you're new to open source in general, check out [GitHub's open source intro guide](https://guides.github.com/overviews/os-contributing/). + ## License OpenSeadragon is released under the New BSD license. For details, see the file LICENSE.txt. diff --git a/changelog.txt b/changelog.txt index e8dbe41b..d61e154f 100644 --- a/changelog.txt +++ b/changelog.txt @@ -20,6 +20,7 @@ OPENSEADRAGON CHANGELOG * Added ControlAnchor options for default controls (#304) * Enabled basic cross-domain tile loading without tainting canvas (works in Chrome and Firefox) (#308) * Added crossOriginPolicy drawer configuration to enable or disable CORS image requests (#364) +* Disabled CORS by default (#377) * Added a ControlAnchor.ABSOLUTE enumeration. Enables absolute positioning of control elements in the viewer (#310) * Added a 'navigator-scroll' event to Navigator. Fired when mousewheel events occur in the navigator (#310) * Added a navigatorMaintainSizeRatio option. If set to true, the navigator minimap resizes when the viewer element is resized (#310) @@ -31,6 +32,9 @@ OPENSEADRAGON CHANGELOG * Added optional Rotate Left/Right buttons to standard controls (#341) * Added optimization for large numbers of overlays: `checkResize = false` option for OpenSeadragon.Overlay (#365) * Updated full screen API, adding support for Opera and IE11 and allowing keyboard input in Chrome (#358) +* Various fixes to bring OpenSeadragon into W3C compliance (#375) +* Added separate flags for turning off each of the nav buttons (#376) +* Added support for query parameters in DZI tileSource URL (#378) * Enhanced MouseTracker for multi-touch (#369) * Added support for tracking multiple touch-points on multiple/simultaneous pointing devices * Added support for the W3C Pointer Events event model. Enables touch/multi-touch on IE10+ diff --git a/src/button.js b/src/button.js index 23b51c17..a83d40a6 100644 --- a/src/button.js +++ b/src/button.js @@ -120,18 +120,23 @@ $.Button = function( options ) { * @member {Element} element * @memberof OpenSeadragon.Button# */ - this.element = options.element || $.makeNeutralElement( "button" ); + this.element = options.element || $.makeNeutralElement( "div" ); //if the user has specified the element to bind the control to explicitly //then do not add the default control images - if( !options.element ){ + if ( !options.element ) { this.imgRest = $.makeTransparentImage( this.srcRest ); this.imgGroup = $.makeTransparentImage( this.srcGroup ); this.imgHover = $.makeTransparentImage( this.srcHover ); this.imgDown = $.makeTransparentImage( this.srcDown ); - this.imgDiv = $.makeNeutralElement( "div" ); - this.imgDiv.style.position = "relative"; + this.imgRest.alt = + this.imgGroup.alt = + this.imgHover.alt = + this.imgDown.alt = + this.tooltip; + + this.element.style.position = "relative"; this.imgGroup.style.position = this.imgHover.style.position = @@ -159,11 +164,10 @@ $.Button = function( options ) { ""; } - this.imgDiv.appendChild( this.imgRest ); - this.imgDiv.appendChild( this.imgGroup ); - this.imgDiv.appendChild( this.imgHover ); - this.imgDiv.appendChild( this.imgDown ); - this.element.appendChild( this.imgDiv ); + this.element.appendChild( this.imgRest ); + this.element.appendChild( this.imgGroup ); + this.element.appendChild( this.imgHover ); + this.element.appendChild( this.imgDown ); } diff --git a/src/buttongroup.js b/src/buttongroup.js index 22535571..b8e92119 100644 --- a/src/buttongroup.js +++ b/src/buttongroup.js @@ -66,7 +66,7 @@ $.ButtonGroup = function( options ) { * @member {Element} element * @memberof OpenSeadragon.ButtonGroup# */ - this.element = options.element || $.makeNeutralElement( "fieldgroup" ); + this.element = options.element || $.makeNeutralElement( "div" ); // TODO What if there IS an options.group specified? if( !options.group ){ diff --git a/src/control.js b/src/control.js index c6010399..f563ac58 100644 --- a/src/control.js +++ b/src/control.js @@ -128,7 +128,7 @@ $.Control = function ( element, options, container ) { this.element.style.height = "100%"; this.element.style.width = "100%"; } else { - this.wrapper = $.makeNeutralElement( "span" ); + this.wrapper = $.makeNeutralElement( "div" ); this.wrapper.style.display = "inline-block"; if ( this.anchor == $.ControlAnchor.NONE ) { // IE6 fix diff --git a/src/controldock.js b/src/controldock.js index 183890c7..e7753743 100644 --- a/src/controldock.js +++ b/src/controldock.js @@ -46,7 +46,7 @@ $.extend( true, this, { id: 'controldock-'+$.now()+'-'+Math.floor(Math.random()*1000000), - container: $.makeNeutralElement('form'), + container: $.makeNeutralElement( 'div' ), controls: [] }, options ); diff --git a/src/drawer.js b/src/drawer.js index b24bd3f6..1c7ad229 100644 --- a/src/drawer.js +++ b/src/drawer.js @@ -327,8 +327,8 @@ $.Drawer.prototype = /** @lends OpenSeadragon.Drawer.prototype */{ image = new Image(); - if (_this.crossOriginPolicy !== false) { - image.crossOrigin = _this.crossOriginPolicy; + if ( _this.crossOriginPolicy !== false ) { + image.crossOrigin = _this.crossOriginPolicy; } complete = function( imagesrc, resultingImage ){ diff --git a/src/dzitilesource.js b/src/dzitilesource.js index 9a3b1d03..daed278e 100644 --- a/src/dzitilesource.js +++ b/src/dzitilesource.js @@ -137,7 +137,8 @@ $.extend( $.DziTileSource.prototype, $.TileSource.prototype, /** @lends OpenSead } if (url && !options.tilesUrl) { - options.tilesUrl = url.replace(/([^\/]+)\.(dzi|xml|js)$/, '$1_files/'); + options.tilesUrl = url.replace(/([^\/]+)\.(dzi|xml|js)(\?.*|$)/, '$1_files/'); + options.queryParams = url.match(/\?.*/); } return options; @@ -151,7 +152,7 @@ $.extend( $.DziTileSource.prototype, $.TileSource.prototype, /** @lends OpenSead * @param {Number} y */ getTileUrl: function( level, x, y ) { - return [ this.tilesUrl, level, '/', x, '_', y, '.', this.fileFormat ].join( '' ); + return [ this.tilesUrl, level, '/', x, '_', y, '.', this.fileFormat, this.queryParams ].join( '' ); }, diff --git a/src/navigator.js b/src/navigator.js index ffb7102f..f2d751a1 100644 --- a/src/navigator.js +++ b/src/navigator.js @@ -201,7 +201,7 @@ $.Navigator = function( options ){ $.Viewer.apply( this, [ options ] ); - this.element.getElementsByTagName('form')[0].appendChild( this.displayRegion ); + this.element.getElementsByTagName( 'div' )[0].appendChild( this.displayRegion ); unneededElement = this.element.getElementsByTagName('textarea')[0]; if (unneededElement) { unneededElement.parentNode.removeChild(unneededElement); diff --git a/src/openseadragon.js b/src/openseadragon.js index e55cf3d7..b42162bb 100644 --- a/src/openseadragon.js +++ b/src/openseadragon.js @@ -321,12 +321,6 @@ * @property {Number} [zoomPerSecond=1.0] * The number of seconds to animate a single zoom event over. * - * @property {Boolean} [showNavigationControl=true] - * Set to false to prevent the appearance of the default navigation controls. - * - * @property {OpenSeadragon.ControlAnchor} [navigationControlAnchor=TOP_LEFT] - * Placement of the default navigation controls. - * * @property {Boolean} [showNavigator=false] * Set to true to make the navigator minimap appear. * @@ -391,15 +385,39 @@ * interactions include draging the image in a plane, and zooming in toward * and away from the image. * - * @property {Boolean} [navPrevNextWrap=false] - * If the 'previous' button will wrap to the last image when viewing the first - * image and if the 'next' button will wrap to the first image when viewing - * the last image. + * @property {Boolean} [showNavigationControl=true] + * Set to false to prevent the appearance of the default navigation controls.
+ * Note that if set to false, the customs buttons set by the options + * zoomInButton, zoomOutButton etc, are rendered inactive. + * + * @property {OpenSeadragon.ControlAnchor} [navigationControlAnchor=TOP_LEFT] + * Placement of the default navigation controls. + * To set the placement of the sequence controls, see the + * sequenceControlAnchor option. + * + * @property {Boolean} [showZoomControl=true] + * If true then + and - buttons to zoom in and out are displayed.
+ * Note: {@link OpenSeadragon.Options.showNavigationControl} is overriding + * this setting when set to false. + * + * @property {Boolean} [showHomeControl=true] + * If true then the 'Go home' button is displayed to go back to the original + * zoom and pan.
+ * Note: {@link OpenSeadragon.Options.showNavigationControl} is overriding + * this setting when set to false. + * + * @property {Boolean} [showFullPageControl=true] + * If true then the 'Toggle full page' button is displayed to switch + * between full page and normal mode.
+ * Note: {@link OpenSeadragon.Options.showNavigationControl} is overriding + * this setting when set to false. * * @property {Boolean} [showRotationControl=false] * If true then the rotate left/right controls will be displayed as part of the * standard controls. This is also subject to the browser support for rotate - * (e.g. viewer.drawer.canRotate()). + * (e.g. viewer.drawer.canRotate()).
+ * Note: {@link OpenSeadragon.Options.showNavigationControl} is overriding + * this setting when set to false. * * @property {Boolean} [showSequenceControl=true] * If the viewer has been configured with a sequence of tile sources, then @@ -408,6 +426,59 @@ * @property {OpenSeadragon.ControlAnchor} [sequenceControlAnchor=TOP_LEFT] * Placement of the default sequence controls. * + * @property {Boolean} [navPrevNextWrap=false] + * If true then the 'previous' button will wrap to the last image when + * viewing the first image and the 'next' button will wrap to the first + * image when viewing the last image. + * + * @property {String} zoomInButton + * Set the id of the custom 'Zoom in' button to use. + * This is useful to have a custom button anywhere in the web page.
+ * To only change the button images, consider using + * {@link OpenSeadragon.Options.navImages} + * + * @property {String} zoomOutButton + * Set the id of the custom 'Zoom out' button to use. + * This is useful to have a custom button anywhere in the web page.
+ * To only change the button images, consider using + * {@link OpenSeadragon.Options.navImages} + * + * @property {String} homeButton + * Set the id of the custom 'Go home' button to use. + * This is useful to have a custom button anywhere in the web page.
+ * To only change the button images, consider using + * {@link OpenSeadragon.Options.navImages} + * + * @property {String} fullPageButton + * Set the id of the custom 'Toggle full page' button to use. + * This is useful to have a custom button anywhere in the web page.
+ * To only change the button images, consider using + * {@link OpenSeadragon.Options.navImages} + * + * @property {String} rotateLeftButton + * Set the id of the custom 'Rotate left' button to use. + * This is useful to have a custom button anywhere in the web page.
+ * To only change the button images, consider using + * {@link OpenSeadragon.Options.navImages} + * + * @property {String} rotateRightButton + * Set the id of the custom 'Rotate right' button to use. + * This is useful to have a custom button anywhere in the web page.
+ * To only change the button images, consider using + * {@link OpenSeadragon.Options.navImages} + * + * @property {String} previousButton + * Set the id of the custom 'Previous page' button to use. + * This is useful to have a custom button anywhere in the web page.
+ * To only change the button images, consider using + * {@link OpenSeadragon.Options.navImages} + * + * @property {String} nextButton + * Set the id of the custom 'Next page' button to use. + * This is useful to have a custom button anywhere in the web page.
+ * To only change the button images, consider using + * {@link OpenSeadragon.Options.navImages} + * * @property {Number} [initialPage=0] * If the viewer has been configured with a sequence of tile sources, display this page initially. * @@ -441,7 +512,7 @@ * * @property {Number} [collectionTileSize=800] * - * @property {String} [crossOriginPolicy='Anonymous'] + * @property {String|Boolean} [crossOriginPolicy=false] * Valid values are 'Anonymous', 'use-credentials', and false. If false, canvas requests will * not use CORS, and the canvas will be tainted. * @@ -502,6 +573,18 @@ * @property {String} fullpage.HOVER * @property {String} fullpage.DOWN * + * @property {Object} rotateleft - Images for the rotate left button. + * @property {String} rotateleft.REST + * @property {String} rotateleft.GROUP + * @property {String} rotateleft.HOVER + * @property {String} rotateleft.DOWN + * + * @property {Object} rotateright - Images for the rotate right button. + * @property {String} rotateright.REST + * @property {String} rotateright.GROUP + * @property {String} rotateright.HOVER + * @property {String} rotateright.DOWN + * * @property {Object} previous - Images for the previous button. * @property {String} previous.REST * @property {String} previous.GROUP @@ -784,8 +867,8 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){ tileSources: null, tileHost: null, initialPage: 0, - crossOriginPolicy: 'Anonymous', - + crossOriginPolicy: false, + //PAN AND ZOOM SETTINGS AND CONSTRAINTS panHorizontal: true, panVertical: true, @@ -823,8 +906,13 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){ showSequenceControl: true, //SEQUENCE sequenceControlAnchor: null, //SEQUENCE preserveViewport: false, //SEQUENCE - showNavigationControl: true, //ZOOM/HOME/FULL/SEQUENCE - navigationControlAnchor: null, //ZOOM/HOME/FULL + navPrevNextWrap: false, //SEQUENCE + showNavigationControl: true, //ZOOM/HOME/FULL/ROTATION + navigationControlAnchor: null, //ZOOM/HOME/FULL/ROTATION + showZoomControl: true, //ZOOM + showHomeControl: true, //HOME + showFullPageControl: true, //FULL + showRotationControl: false, //ROTATION controlsFadeDelay: 2000, //ZOOM/HOME/FULL/SEQUENCE controlsFadeLength: 1500, //ZOOM/HOME/FULL/SEQUENCE mouseNavEnabled: true, //GENERAL MOUSE INTERACTIVITY @@ -923,8 +1011,6 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){ DOWN: 'next_pressed.png' } }, - navPrevNextWrap: false, - showRotationControl: false, //DEVELOPER SETTINGS debugMode: false, diff --git a/src/referencestrip.js b/src/referencestrip.js index fc9bcc73..b7192517 100644 --- a/src/referencestrip.js +++ b/src/referencestrip.js @@ -447,7 +447,7 @@ function loadPanels( strip, viewerSize, scroll ) { element: miniViewer.displayRegion } ); - element.getElementsByTagName( 'form' )[0].appendChild( + element.getElementsByTagName( 'div' )[0].appendChild( miniViewer.displayRegion ); diff --git a/src/viewer.js b/src/viewer.js index 9285a501..c451dace 100644 --- a/src/viewer.js +++ b/src/viewer.js @@ -102,7 +102,7 @@ $.Viewer = function( options ) { */ element: null, /** - * A <form> element (provided by {@link OpenSeadragon.ControlDock}), the base element of this Viewer instance.

+ * A <div> element (provided by {@link OpenSeadragon.ControlDock}), the base element of this Viewer instance.

* Child element of {@link OpenSeadragon.Viewer#element}. * @member {Element} container * @memberof OpenSeadragon.Viewer# @@ -1371,80 +1371,88 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype, useGroup = true ; - if( this.showNavigationControl ){ + if ( this.showNavigationControl ) { - if( this.zoomInButton || this.zoomOutButton || this.homeButton || this.fullPageButton ){ + if( this.zoomInButton || this.zoomOutButton || + this.homeButton || this.fullPageButton || + this.rotateLeftButton || this.rotateRightButton ) { //if we are binding to custom buttons then layout and //grouping is the responsibility of the page author useGroup = false; } - buttons.push( this.zoomInButton = new $.Button({ - element: this.zoomInButton ? $.getElement( this.zoomInButton ) : null, - clickTimeThreshold: this.clickTimeThreshold, - clickDistThreshold: this.clickDistThreshold, - tooltip: $.getString( "Tooltips.ZoomIn" ), - srcRest: resolveUrl( this.prefixUrl, navImages.zoomIn.REST ), - srcGroup: resolveUrl( this.prefixUrl, navImages.zoomIn.GROUP ), - srcHover: resolveUrl( this.prefixUrl, navImages.zoomIn.HOVER ), - srcDown: resolveUrl( this.prefixUrl, navImages.zoomIn.DOWN ), - onPress: beginZoomingInHandler, - onRelease: endZoomingHandler, - onClick: doSingleZoomInHandler, - onEnter: beginZoomingInHandler, - onExit: endZoomingHandler, - onFocus: onFocusHandler, - onBlur: onBlurHandler - })); + if ( this.showZoomControl ) { + buttons.push( this.zoomInButton = new $.Button({ + element: this.zoomInButton ? $.getElement( this.zoomInButton ) : null, + clickTimeThreshold: this.clickTimeThreshold, + clickDistThreshold: this.clickDistThreshold, + tooltip: $.getString( "Tooltips.ZoomIn" ), + srcRest: resolveUrl( this.prefixUrl, navImages.zoomIn.REST ), + srcGroup: resolveUrl( this.prefixUrl, navImages.zoomIn.GROUP ), + srcHover: resolveUrl( this.prefixUrl, navImages.zoomIn.HOVER ), + srcDown: resolveUrl( this.prefixUrl, navImages.zoomIn.DOWN ), + onPress: beginZoomingInHandler, + onRelease: endZoomingHandler, + onClick: doSingleZoomInHandler, + onEnter: beginZoomingInHandler, + onExit: endZoomingHandler, + onFocus: onFocusHandler, + onBlur: onBlurHandler + })); - buttons.push( this.zoomOutButton = new $.Button({ - element: this.zoomOutButton ? $.getElement( this.zoomOutButton ) : null, - clickTimeThreshold: this.clickTimeThreshold, - clickDistThreshold: this.clickDistThreshold, - tooltip: $.getString( "Tooltips.ZoomOut" ), - srcRest: resolveUrl( this.prefixUrl, navImages.zoomOut.REST ), - srcGroup: resolveUrl( this.prefixUrl, navImages.zoomOut.GROUP ), - srcHover: resolveUrl( this.prefixUrl, navImages.zoomOut.HOVER ), - srcDown: resolveUrl( this.prefixUrl, navImages.zoomOut.DOWN ), - onPress: beginZoomingOutHandler, - onRelease: endZoomingHandler, - onClick: doSingleZoomOutHandler, - onEnter: beginZoomingOutHandler, - onExit: endZoomingHandler, - onFocus: onFocusHandler, - onBlur: onBlurHandler - })); + buttons.push( this.zoomOutButton = new $.Button({ + element: this.zoomOutButton ? $.getElement( this.zoomOutButton ) : null, + clickTimeThreshold: this.clickTimeThreshold, + clickDistThreshold: this.clickDistThreshold, + tooltip: $.getString( "Tooltips.ZoomOut" ), + srcRest: resolveUrl( this.prefixUrl, navImages.zoomOut.REST ), + srcGroup: resolveUrl( this.prefixUrl, navImages.zoomOut.GROUP ), + srcHover: resolveUrl( this.prefixUrl, navImages.zoomOut.HOVER ), + srcDown: resolveUrl( this.prefixUrl, navImages.zoomOut.DOWN ), + onPress: beginZoomingOutHandler, + onRelease: endZoomingHandler, + onClick: doSingleZoomOutHandler, + onEnter: beginZoomingOutHandler, + onExit: endZoomingHandler, + onFocus: onFocusHandler, + onBlur: onBlurHandler + })); + } - buttons.push( this.homeButton = new $.Button({ - element: this.homeButton ? $.getElement( this.homeButton ) : null, - clickTimeThreshold: this.clickTimeThreshold, - clickDistThreshold: this.clickDistThreshold, - tooltip: $.getString( "Tooltips.Home" ), - srcRest: resolveUrl( this.prefixUrl, navImages.home.REST ), - srcGroup: resolveUrl( this.prefixUrl, navImages.home.GROUP ), - srcHover: resolveUrl( this.prefixUrl, navImages.home.HOVER ), - srcDown: resolveUrl( this.prefixUrl, navImages.home.DOWN ), - onRelease: onHomeHandler, - onFocus: onFocusHandler, - onBlur: onBlurHandler - })); + if ( this.showHomeControl ) { + buttons.push( this.homeButton = new $.Button({ + element: this.homeButton ? $.getElement( this.homeButton ) : null, + clickTimeThreshold: this.clickTimeThreshold, + clickDistThreshold: this.clickDistThreshold, + tooltip: $.getString( "Tooltips.Home" ), + srcRest: resolveUrl( this.prefixUrl, navImages.home.REST ), + srcGroup: resolveUrl( this.prefixUrl, navImages.home.GROUP ), + srcHover: resolveUrl( this.prefixUrl, navImages.home.HOVER ), + srcDown: resolveUrl( this.prefixUrl, navImages.home.DOWN ), + onRelease: onHomeHandler, + onFocus: onFocusHandler, + onBlur: onBlurHandler + })); + } - buttons.push( this.fullPageButton = new $.Button({ - element: this.fullPageButton ? $.getElement( this.fullPageButton ) : null, - clickTimeThreshold: this.clickTimeThreshold, - clickDistThreshold: this.clickDistThreshold, - tooltip: $.getString( "Tooltips.FullPage" ), - srcRest: resolveUrl( this.prefixUrl, navImages.fullpage.REST ), - srcGroup: resolveUrl( this.prefixUrl, navImages.fullpage.GROUP ), - srcHover: resolveUrl( this.prefixUrl, navImages.fullpage.HOVER ), - srcDown: resolveUrl( this.prefixUrl, navImages.fullpage.DOWN ), - onRelease: onFullScreenHandler, - onFocus: onFocusHandler, - onBlur: onBlurHandler - })); + if ( this.showFullPageControl ) { + buttons.push( this.fullPageButton = new $.Button({ + element: this.fullPageButton ? $.getElement( this.fullPageButton ) : null, + clickTimeThreshold: this.clickTimeThreshold, + clickDistThreshold: this.clickDistThreshold, + tooltip: $.getString( "Tooltips.FullPage" ), + srcRest: resolveUrl( this.prefixUrl, navImages.fullpage.REST ), + srcGroup: resolveUrl( this.prefixUrl, navImages.fullpage.GROUP ), + srcHover: resolveUrl( this.prefixUrl, navImages.fullpage.HOVER ), + srcDown: resolveUrl( this.prefixUrl, navImages.fullpage.DOWN ), + onRelease: onFullScreenHandler, + onFocus: onFocusHandler, + onBlur: onBlurHandler + })); + } - if (this.showRotationControl) { - buttons.push( this.rotateLeft = new $.Button({ + if ( this.showRotationControl ) { + buttons.push( this.rotateLeftButton = new $.Button({ element: this.rotateLeftButton ? $.getElement( this.rotateLeftButton ) : null, clickTimeThreshold: this.clickTimeThreshold, clickDistThreshold: this.clickDistThreshold, @@ -1458,7 +1466,7 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype, onBlur: onBlurHandler })); - buttons.push( this.rotateRight = new $.Button({ + buttons.push( this.rotateRightButton = new $.Button({ element: this.rotateRightButton ? $.getElement( this.rotateRightButton ) : null, clickTimeThreshold: this.clickTimeThreshold, clickDistThreshold: this.clickDistThreshold, @@ -1474,7 +1482,7 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype, } - if( useGroup ){ + if ( useGroup ) { this.buttons = new $.ButtonGroup({ buttons: buttons, clickTimeThreshold: this.clickTimeThreshold, @@ -1489,7 +1497,7 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype, this.navControl, {anchor: $.ControlAnchor.TOP_LEFT} ); - }else{ + } else { this.addControl( this.navControl, {anchor: this.navigationControlAnchor || $.ControlAnchor.TOP_LEFT} @@ -1506,9 +1514,9 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype, * @function * @return {Number} */ - currentPage: function () { + currentPage: function() { return THIS[ this.hash ].sequence; - }, + }, /** * @function @@ -1716,24 +1724,24 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype, * @private * @param {Number} Sequence Value */ - _updateSequenceButtons: function (page) { + _updateSequenceButtons: function( page ) { - if( this.nextButton ){ - if( ( this.tileSources.length - 1 ) === page ){ + if ( this.nextButton ) { + if( ( this.tileSources.length - 1 ) === page ) { //Disable next button - if(!this.navPrevNextWrap){ + if ( !this.navPrevNextWrap ) { this.nextButton.disable(); } } else { this.nextButton.enable(); } } - if( this.previousButton ){ - if( page > 0 ){ + if ( this.previousButton ) { + if ( page > 0 ) { //Enable previous button this.previousButton.enable(); } else { - if(!this.navPrevNextWrap){ + if ( !this.navPrevNextWrap ) { this.previousButton.disable(); } } diff --git a/test/controls.js b/test/controls.js new file mode 100644 index 00000000..a2d7d998 --- /dev/null +++ b/test/controls.js @@ -0,0 +1,383 @@ +/* global module, asyncTest, $, ok, equal, notEqual, start, test, Util, testLog */ + +(function () { + var viewer; + + module('Controls', { + setup: function () { + var example = $('
').appendTo("#qunit-fixture"); + + testLog.reset(); + + }, + teardown: function () { + if (viewer && viewer.close) { + viewer.close(); + } + + viewer = null; + } + }); + + asyncTest('ZoomControlOff', function () { + + var openHandler = function () { + viewer.removeHandler('open', openHandler); + ok(!viewer.showZoomControl, 'showZoomControl should be off'); + ok(!viewer.zoomInButton, "zoomIn button should be null"); + ok(!viewer.zoomOutButton, "zoomOut button should be null"); + + viewer.close(); + start(); + }; + + viewer = OpenSeadragon({ + id: 'controlsTests', + prefixUrl: '/build/openseadragon/images/', + springStiffness: 100, // Faster animation = faster tests + showZoomControl: false + }); + viewer.addHandler('open', openHandler); + viewer.open('/test/data/testpattern.dzi'); + }); + + asyncTest('ZoomControlOn', function () { + + var openHandler = function () { + viewer.removeHandler('open', openHandler); + ok(viewer.showZoomControl, 'showZoomControl should be on'); + ok(!!viewer.zoomInButton, "zoomIn button should not be null"); + ok(!!viewer.zoomOutButton, "zoomOut button should not be null"); + notEqual(viewer.buttons.buttons.indexOf(viewer.zoomInButton), -1, + "The zoomIn button should be present"); + notEqual(viewer.buttons.buttons.indexOf(viewer.zoomOutButton), -1, + "The zoomOut button should be present"); + + var oldZoom = viewer.viewport.getZoom(); + viewer.zoomInButton.onClick(); + var newZoom = viewer.viewport.getZoom(); + ok(oldZoom < newZoom, "OSD should have zoomed in."); + oldZoom = newZoom; + viewer.zoomOutButton.onClick(); + newZoom = viewer.viewport.getZoom(); + ok(oldZoom > newZoom, "OSD should have zoomed out."); + + viewer.close(); + start(); + }; + + viewer = OpenSeadragon({ + id: 'controlsTests', + prefixUrl: '/build/openseadragon/images/', + springStiffness: 100, // Faster animation = faster tests + showZoomControl: true + }); + viewer.addHandler('open', openHandler); + viewer.open('/test/data/testpattern.dzi'); + }); + + asyncTest('HomeControlOff', function () { + + var openHandler = function () { + viewer.removeHandler('open', openHandler); + ok(!viewer.showHomeControl, 'showHomeControl should be off'); + ok(!viewer.homeButton, "Home button should be null"); + + viewer.close(); + start(); + }; + + viewer = OpenSeadragon({ + id: 'controlsTests', + prefixUrl: '/build/openseadragon/images/', + springStiffness: 100, // Faster animation = faster tests + showHomeControl: false + }); + viewer.addHandler('open', openHandler); + viewer.open('/test/data/testpattern.dzi'); + }); + + asyncTest('HomeControlOn', function () { + + var openHandler = function () { + viewer.removeHandler('open', openHandler); + ok(viewer.showHomeControl, 'showHomeControl should be on'); + ok(!!viewer.homeButton, "Home button should not be null"); + notEqual(viewer.buttons.buttons.indexOf(viewer.homeButton), -1, + "The home button should be present"); + + viewer.viewport.zoomBy(1.1); + var bounds = viewer.viewport.getBounds(); + var homeBounds = viewer.viewport.getHomeBounds(); + ok(bounds.x !== homeBounds.x || + bounds.y !== homeBounds.y || + bounds.width !== homeBounds.width || + bounds.height !== homeBounds.height, + "OSD should not be at home."); + viewer.homeButton.onRelease(); + bounds = viewer.viewport.getBounds(); + ok(bounds.x === homeBounds.x && + bounds.y === homeBounds.y && + bounds.width === homeBounds.width && + bounds.height === homeBounds.height, "OSD should have get home."); + + viewer.close(); + start(); + }; + + viewer = OpenSeadragon({ + id: 'controlsTests', + prefixUrl: '/build/openseadragon/images/', + springStiffness: 100, // Faster animation = faster tests + showHomeControl: true + }); + viewer.addHandler('open', openHandler); + viewer.open('/test/data/testpattern.dzi'); + }); + + asyncTest('FullPageControlOff', function () { + + var openHandler = function () { + viewer.removeHandler('open', openHandler); + ok(!viewer.showFullPageControl, 'showFullPageControl should be off'); + ok(!viewer.fullPageButton, "FullPage button should be null"); + + viewer.close(); + start(); + }; + + viewer = OpenSeadragon({ + id: 'controlsTests', + prefixUrl: '/build/openseadragon/images/', + springStiffness: 100, // Faster animation = faster tests + showFullPageControl: false + }); + viewer.addHandler('open', openHandler); + viewer.open('/test/data/testpattern.dzi'); + }); + + asyncTest('FullPageControlOn', function () { + + var openHandler = function () { + viewer.removeHandler('open', openHandler); + ok(viewer.showHomeControl, 'showFullPageControl should be on'); + ok(!!viewer.fullPageButton, "FullPage button should not be null"); + notEqual(viewer.buttons.buttons.indexOf(viewer.fullPageButton), -1, + "The full page button should be present"); + + ok(!viewer.isFullPage(), "OSD should not be in full page."); + viewer.fullPageButton.onRelease(); + ok(viewer.isFullPage(), "OSD should be in full page."); + viewer.fullPageButton.onRelease(); + ok(!viewer.isFullPage(), "OSD should not be in full page."); + + viewer.close(); + start(); + }; + + viewer = OpenSeadragon({ + id: 'controlsTests', + prefixUrl: '/build/openseadragon/images/', + springStiffness: 100, // Faster animation = faster tests + showHomeControl: true + }); + viewer.addHandler('open', openHandler); + viewer.open('/test/data/testpattern.dzi'); + }); + + asyncTest('RotateControlOff', function () { + + var openHandler = function (event) { + viewer.removeHandler('open', openHandler); + ok(true, 'Open event was sent'); + ok(viewer.drawer, 'Drawer exists'); + ok(viewer.drawer.canRotate(), 'drawer.canRotate needs to be true'); + ok(!viewer.showRotationControl, 'showRotationControl should be off'); + ok(!viewer.rotateLeftButton, "rotateLeft button should be null"); + ok(!viewer.rotateRightButton, "rotateRight button should be null"); + + viewer.close(); + start(); + }; + + viewer = OpenSeadragon({ + id: 'controlsTests', + prefixUrl: '/build/openseadragon/images/', + springStiffness: 100, // Faster animation = faster tests + showRotationControl: false + }); + viewer.addHandler('open', openHandler); + viewer.open('/test/data/testpattern.dzi'); + }); + + asyncTest('RotateControlOn', function () { + + var openHandler = function (event) { + viewer.removeHandler('open', openHandler); + ok(true, 'Open event was sent'); + ok(viewer.drawer, 'Drawer exists'); + ok(viewer.drawer.canRotate(), 'drawer.canRotate needs to be true'); + ok(viewer.showRotationControl, 'showRotationControl should be true'); + notEqual(viewer.buttons.buttons.indexOf(viewer.rotateLeftButton), -1, + "rotateLeft should be found"); + notEqual(viewer.buttons.buttons.indexOf(viewer.rotateRightButton), -1, + "rotateRight should be found"); + + // Now simulate the left/right button clicks. + // TODO: re-factor simulateViewerClickWithDrag so it'll accept any element, and use that. + equal(viewer.viewport.degrees, 0, "Image should start at 0 degrees rotation"); + viewer.rotateLeftButton.onRelease(); + equal(viewer.viewport.degrees, 270, "Image should be 270 degrees rotation (left)"); + viewer.rotateRightButton.onRelease(); + equal(viewer.viewport.degrees, 0, "Image should be 270 degrees rotation (right)"); + + viewer.close(); + start(); + }; + + viewer = OpenSeadragon({ + id: 'controlsTests', + prefixUrl: '/build/openseadragon/images/', + springStiffness: 100, // Faster animation = faster tests + showRotationControl: true + }); + viewer.addHandler('open', openHandler); + viewer.open('/test/data/testpattern.dzi'); + }); + + asyncTest('SequenceControlOff', function () { + + var openHandler = function () { + viewer.removeHandler('open', openHandler); + ok(!viewer.showSequenceControl, 'showSequenceControl should be off'); + ok(!viewer.previousButton, "Previous button should be null"); + ok(!viewer.nextButton, "Next button should be null"); + + viewer.close(); + start(); + }; + + viewer = OpenSeadragon({ + id: 'controlsTests', + prefixUrl: '/build/openseadragon/images/', + tileSources: [ + '/test/data/testpattern.dzi', + '/test/data/testpattern.dzi', + '/test/data/testpattern.dzi' + ], + springStiffness: 100, // Faster animation = faster tests + showSequenceControl: false + }); + viewer.addHandler('open', openHandler); + }); + + asyncTest('SequenceControlOnPrevNextWrapOff', function () { + + var openHandler = function () { + viewer.removeHandler('open', openHandler); + ok(viewer.showSequenceControl, 'showSequenceControl should be on'); + ok(!!viewer.previousButton, "Previous button should not be null"); + ok(!!viewer.nextButton, "Next button should not be null"); + notEqual(viewer.paging.buttons.indexOf(viewer.previousButton), -1, + "The previous button should be present"); + notEqual(viewer.paging.buttons.indexOf(viewer.nextButton), -1, + "The next button should be present"); + + equal(viewer.currentPage(), 0, "OSD should open on first page."); + ok(viewer.previousButton.element.disabled, + "Previous should be disabled on first page."); + ok(!viewer.nextButton.element.disabled, + "Next should be enabled on first page."); + + viewer.nextButton.onRelease(); + equal(viewer.currentPage(), 1, "OSD should be on second page."); + ok(!viewer.previousButton.element.disabled, + "Previous should be enabled on second page."); + ok(!viewer.nextButton.element.disabled, + "Next should be enabled on second page."); + + viewer.nextButton.onRelease(); + equal(viewer.currentPage(), 2, "OSD should be on third page."); + ok(!viewer.previousButton.element.disabled, + "Previous should be enabled on third page."); + ok(viewer.nextButton.element.disabled, + "Next should be disabled on third page."); + + viewer.previousButton.onRelease(); + equal(viewer.currentPage(), 1, "OSD should be on second page."); + ok(!viewer.previousButton.element.disabled, + "Previous should be enabled on second page."); + ok(!viewer.nextButton.element.disabled, + "Next should be enabled on second page."); + + viewer.close(); + start(); + }; + + viewer = OpenSeadragon({ + id: 'controlsTests', + prefixUrl: '/build/openseadragon/images/', + tileSources: [ + '/test/data/testpattern.dzi', + '/test/data/testpattern.dzi', + '/test/data/testpattern.dzi' + ], + springStiffness: 100, // Faster animation = faster tests + showSequenceControl: true, + navPrevNextWrap: false + }); + viewer.addHandler('open', openHandler); + }); + + asyncTest('SequenceControlOnPrevNextWrapOn', function () { + + var openHandler = function () { + viewer.removeHandler('open', openHandler); + ok(viewer.showSequenceControl, 'showSequenceControl should be on'); + ok(!!viewer.previousButton, "Previous button should not be null"); + ok(!!viewer.nextButton, "Next button should not be null"); + notEqual(viewer.paging.buttons.indexOf(viewer.previousButton), -1, + "The previous button should be present"); + notEqual(viewer.paging.buttons.indexOf(viewer.nextButton), -1, + "The next button should be present"); + + equal(viewer.currentPage(), 0, "OSD should open on first page."); + ok(!viewer.previousButton.element.disabled, + "Previous should be enabled on first page."); + ok(!viewer.nextButton.element.disabled, + "Next should be enabled on first page."); + + viewer.previousButton.onRelease(); + equal(viewer.currentPage(), 2, "OSD should be on third page."); + ok(!viewer.previousButton.element.disabled, + "Previous should be enabled on third page."); + ok(!viewer.nextButton.element.disabled, + "Next should be enabled on third page."); + + viewer.nextButton.onRelease(); + equal(viewer.currentPage(), 0, "OSD should be on first page."); + ok(!viewer.previousButton.element.disabled, + "Previous should be enabled on first page."); + ok(!viewer.nextButton.element.disabled, + "Next should be enabled on first page."); + + viewer.close(); + start(); + }; + + viewer = OpenSeadragon({ + id: 'controlsTests', + prefixUrl: '/build/openseadragon/images/', + tileSources: [ + '/test/data/testpattern.dzi', + '/test/data/testpattern.dzi', + '/test/data/testpattern.dzi' + ], + springStiffness: 100, // Faster animation = faster tests + showSequenceControl: true, + navPrevNextWrap: true + }); + viewer.addHandler('open', openHandler); + }); + +})(); diff --git a/test/formats.js b/test/formats.js index 7a54048f..c3653123 100644 --- a/test/formats.js +++ b/test/formats.js @@ -66,6 +66,11 @@ }); // ---------- + asyncTest('DZI XML with query parameter', function() { + testOpen('testpattern.xml?param=value'); + }); + + // ---------- asyncTest('IIIF 1.0 JSON', function() { testOpen('iiif1_0.json'); }); diff --git a/test/rotate.js b/test/rotate.js deleted file mode 100644 index 9128d7fa..00000000 --- a/test/rotate.js +++ /dev/null @@ -1,77 +0,0 @@ -/* global module, asyncTest, $, ok, equal, notEqual, start, test, Util, testLog */ - -(function () { - var viewer; - - module('Basic', { - setup: function () { - var example = $('
').appendTo("#qunit-fixture"); - - testLog.reset(); - - }, - teardown: function () { - if (viewer && viewer.close) { - viewer.close(); - } - - viewer = null; - } - }); - - asyncTest('RotateControlOff', function () { - - var openHandler = function (event) { - viewer.removeHandler('open', openHandler); - ok(true, 'Open event was sent'); - ok(viewer.drawer, 'Drawer exists'); - ok(viewer.drawer.canRotate(), 'drawer.canRotate needs to be true'); - ok(!viewer.showRotationControl, 'showRotationControl should be off'); - ok(!viewer.rotateLeft, "rotateLeft button should be null"); - ok(!viewer.rotateRight, "rotateRight button should be null"); - start(); - }; - - viewer = OpenSeadragon({ - id: 'rotateTests', - prefixUrl: '/build/openseadragon/images/', - springStiffness: 100, // Faster animation = faster tests - showRotationControl: false - }); - viewer.addHandler('open', openHandler); - viewer.open('/test/data/testpattern.dzi'); - }); - - asyncTest('RotateControlOn', function () { - - var openHandler = function (event) { - viewer.removeHandler('open', openHandler); - ok(true, 'Open event was sent'); - ok(viewer.drawer, 'Drawer exists'); - ok(viewer.drawer.canRotate(), 'drawer.canRotate needs to be true'); - ok(viewer.showRotationControl, 'showRotationControl should be true'); - ok(-1 != viewer.buttons.buttons.indexOf(viewer.rotateLeft), "rotateLeft should be found"); - ok(-1 != viewer.buttons.buttons.indexOf(viewer.rotateRight), "rotateRight should be found"); - - // Now simulate the left/right button clicks. - // TODO: re-factor simulateViewerClickWithDrag so it'll accept any element, and use that. - ok(viewer.viewport.degrees === 0, "Image should start at 0 degrees rotation"); - viewer.rotateLeft.onRelease(); - ok(viewer.viewport.degrees === 270, "Image should be 270 degrees rotation (left)"); - viewer.rotateRight.onRelease(); - ok(viewer.viewport.degrees === 0, "Image should be 270 degrees rotation (right)"); - - start(); - }; - - viewer = OpenSeadragon({ - id: 'rotateTests', - prefixUrl: '/build/openseadragon/images/', - springStiffness: 100, // Faster animation = faster tests - showRotationControl: true - }); - viewer.addHandler('open', openHandler); - viewer.open('/test/data/testpattern.dzi'); - }); - -})(); diff --git a/test/test.html b/test/test.html index c6159545..64062197 100644 --- a/test/test.html +++ b/test/test.html @@ -30,6 +30,6 @@ - +