2017-08-01 00:05:18 +03:00
/ *
2013-05-01 08:46:16 +04:00
* OpenSeadragon
*
* Copyright ( C ) 2009 CodePlex Foundation
2013-05-14 07:32:09 +04:00
* Copyright ( C ) 2010 - 2013 OpenSeadragon contributors
2013-05-01 08:46:16 +04:00
*
* Redistribution and use in source and binary forms , with or without
* modification , are permitted provided that the following conditions are
* met :
*
* - Redistributions of source code must retain the above copyright notice ,
* this list of conditions and the following disclaimer .
*
* - Redistributions in binary form must reproduce the above copyright
* notice , this list of conditions and the following disclaimer in the
* documentation and / or other materials provided with the distribution .
*
* - Neither the name of CodePlex Foundation nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission .
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT
* LIMITED TO , THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED . IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT , INDIRECT , INCIDENTAL ,
* SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING , BUT NOT LIMITED
* TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE , DATA , OR
* PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT ( INCLUDING
* NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
* /
2013-05-10 08:57:49 +04:00
/ *
* Portions of this source file taken from jQuery :
*
* Copyright 2011 John Resig
*
* Permission is hereby granted , free of charge , to any person obtaining
* a copy of this software and associated documentation files ( the
* "Software" ) , to deal in the Software without restriction , including
* without limitation the rights to use , copy , modify , merge , publish ,
* distribute , sublicense , and / or sell copies of the Software , and to
* permit persons to whom the Software is furnished to do so , subject to
* the following conditions :
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software .
*
* THE SOFTWARE IS PROVIDED "AS IS" , WITHOUT WARRANTY OF ANY KIND ,
* EXPRESS OR IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY , FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT . IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM , DAMAGES OR OTHER LIABILITY , WHETHER IN AN ACTION
* OF CONTRACT , TORT OR OTHERWISE , ARISING FROM , OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE .
* /
/ *
* Portions of this source file taken from mattsnider . com :
*
* Copyright ( c ) 2006 - 2013 Matt Snider
*
* Permission is hereby granted , free of charge , to any person obtaining a
* copy of this software and associated documentation files ( the "Software" ) ,
* to deal in the Software without restriction , including without limitation
* the rights to use , copy , modify , merge , publish , distribute , sublicense ,
* and / or sell copies of the Software , and to permit persons to whom the
* Software is furnished to do so , subject to the following conditions :
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software .
*
* THE SOFTWARE IS PROVIDED "AS IS" , WITHOUT WARRANTY OF ANY KIND , EXPRESS
* OR IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY , FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT .
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM , DAMAGES OR OTHER LIABILITY , WHETHER IN AN ACTION OF CONTRACT , TORT
* OR OTHERWISE , ARISING FROM , OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
* THE USE OR OTHER DEALINGS IN THE SOFTWARE .
* /
2013-11-19 22:08:04 +04:00
/ * *
* @ namespace OpenSeadragon
2016-04-09 17:15:02 +03:00
* @ version < %= pkg . name % > < %= pkg . version % >
2013-11-30 00:10:15 +04:00
* @ classdesc The root namespace for OpenSeadragon . All utility methods
* and classes are defined on or below this namespace .
*
2013-11-19 22:08:04 +04:00
* /
2011-12-06 07:50:25 +04:00
2013-11-19 22:08:04 +04:00
// Typedefs
2013-05-14 21:28:44 +04:00
/ * *
2013-11-18 22:06:38 +04:00
* All required and optional settings for instantiating a new instance of an OpenSeadragon image viewer .
2012-03-01 17:38:15 +04:00
*
2013-11-18 22:06:38 +04:00
* @ typedef { Object } Options
* @ memberof OpenSeadragon
2012-03-01 17:38:15 +04:00
*
2013-11-25 20:48:44 +04:00
* @ property { String } id
* Id of the element to append the viewer 's container element to. If not provided, the ' element ' property must be provided .
* If both the element and id properties are specified , the viewer is appended to the element provided in the element property .
*
* @ property { Element } element
* The element to append the viewer 's container element to. If not provided, the ' id ' property must be provided .
* If both the element and id properties are specified , the viewer is appended to the element provided in the element property .
*
2014-10-30 03:06:14 +03:00
* @ property { Array | String | Function | Object } [ tileSources = null ]
* Tile source ( s ) to open initially . This is a complex parameter ; see
* { @ link OpenSeadragon . Viewer # open } for details .
2012-03-01 17:38:15 +04:00
*
2015-01-21 23:47:42 +03:00
* @ property { Number } [ tabIndex = 0 ]
2015-01-22 22:15:45 +03:00
* Tabbing order index to assign to the viewer element . Positive values are selected in increasing order . When tabIndex is 0
2015-01-21 23:47:42 +03:00
* source order is used . A negative value omits the viewer from the tabbing order .
*
2014-03-15 19:20:33 +04:00
* @ property { Array } overlays Array of objects defining permanent overlays of
2014-03-18 21:05:21 +04:00
* the viewer . The overlays added via this option and later removed with
2014-03-15 19:20:33 +04:00
* { @ link OpenSeadragon . Viewer # removeOverlay } will be added back when a new
* image is opened .
2014-03-18 21:05:21 +04:00
* To add overlays which can be definitively removed , one must use
2014-03-15 19:20:33 +04:00
* { @ link OpenSeadragon . Viewer # addOverlay }
* If displaying a sequence of images , the overlays can be associated
* with a specific page by passing the overlays array to the page ' s
* tile source configuration .
* Expected properties :
* * x , y , ( or px , py for pixel coordinates ) to define the location .
* * width , height in point if using x , y or in pixels if using px , py . If width
* and height are specified , the overlay size is adjusted when zooming ,
2014-03-18 21:05:21 +04:00
* otherwise the size stays the size of the content ( or the size defined by CSS ) .
2014-03-15 19:20:33 +04:00
* * className to associate a class to the overlay
* * id to set the overlay element . If an element with this id already exists ,
* it is reused , otherwise it is created . If not specified , a new element is
* created .
* * placement a string to define the relative position to the viewport .
2014-03-18 21:05:21 +04:00
* Only used if no width and height are specified . Default : 'TOP_LEFT' .
2016-03-22 22:50:48 +03:00
* See { @ link OpenSeadragon . Placement } for possible values .
2014-03-15 19:20:33 +04:00
*
2013-11-19 22:08:04 +04:00
* @ property { String } [ xmlPath = null ]
2013-11-22 00:19:07 +04:00
* < strong > DEPRECATED < / s t r o n g > . A r e l a t i v e p a t h t o l o a d a D Z I f i l e f r o m t h e s e r v e r .
2013-11-19 22:08:04 +04:00
* Prefer the newer Options . tileSources .
2012-03-01 17:38:15 +04:00
*
2013-11-19 22:08:04 +04:00
* @ property { String } [ prefixUrl = '/images/' ]
* Prepends the prefixUrl to navImages paths , which is very useful
* since the default paths are rarely useful for production
* environments .
*
* @ property { OpenSeadragon . NavImages } [ navImages ]
* An object with a property for each button or other built - in navigation
* control , eg the current 'zoomIn' , 'zoomOut' , 'home' , and 'fullpage' .
2013-11-25 22:38:50 +04:00
* Each of those in turn provides an image path for each state of the button
2013-11-19 22:08:04 +04:00
* or navigation control , eg 'REST' , 'GROUP' , 'HOVER' , 'PRESS' . Finally the
* image paths , by default assume there is a folder on the servers root path
* called '/images' , eg '/images/zoomin_rest.png' . If you need to adjust
* these paths , prefer setting the option . prefixUrl rather than overriding
* every image path directly through this setting .
*
2013-11-18 22:06:38 +04:00
* @ property { Boolean } [ debugMode = false ]
2013-11-18 21:44:54 +04:00
* TODO : provide an in - screen panel providing event detail feedback .
*
2017-08-01 00:36:25 +03:00
* @ property { String } [ debugGridColor = [ '#437AB2' , '#1B9E77' , '#D95F02' , '#7570B3' , '#E7298A' , '#66A61E' , '#E6AB02' , '#A6761D' , '#666666' ] ]
* The colors of grids in debug mode . Each tiled image ' s grid uses a consecutive color .
* If there are more tiled images than provided colors , the color vector is recycled .
2013-11-18 21:44:54 +04:00
*
2013-11-18 22:06:38 +04:00
* @ property { Number } [ blendTime = 0 ]
2012-03-01 17:38:15 +04:00
* Specifies the duration of animation as higher or lower level tiles are
* replacing the existing tile .
*
2013-11-18 22:06:38 +04:00
* @ property { Boolean } [ alwaysBlend = false ]
2012-03-01 17:38:15 +04:00
* Forces the tile to always blend . By default the tiles skip blending
* when the blendTime is surpassed and the current animation frame would
* not complete the blend .
*
2013-11-18 22:06:38 +04:00
* @ property { Boolean } [ autoHideControls = true ]
2013-06-19 21:33:25 +04:00
* If the user stops interacting with the viewport , fade the navigation
2012-03-01 17:38:15 +04:00
* controls . Useful for presentation since the controls are by default
* floated on top of the image the user is viewing .
*
2013-11-18 22:06:38 +04:00
* @ property { Boolean } [ immediateRender = false ]
2012-03-07 07:20:00 +04:00
* Render the best closest level first , ignoring the lowering levels which
2013-06-19 21:33:25 +04:00
* provide the effect of very blurry to sharp . It is recommended to change
2012-03-07 07:20:00 +04:00
* setting to true for mobile devices .
2012-03-01 17:38:15 +04:00
*
2013-11-18 22:06:38 +04:00
* @ property { Number } [ defaultZoomLevel = 0 ]
2013-11-18 21:44:54 +04:00
* Zoom level to use when image is first opened or the home button is clicked .
* If 0 , adjusts to fit viewer .
*
2013-12-09 18:26:36 +04:00
* @ property { Number } [ opacity = 1 ]
2016-11-04 05:39:00 +03:00
* Default proportional opacity of the tiled images ( 1 = opaque , 0 = hidden )
* Hidden images do not draw and only load when preloading is allowed .
2013-12-09 18:26:36 +04:00
*
2016-11-03 03:45:33 +03:00
* @ property { Boolean } [ preload = false ]
2016-11-04 05:39:00 +03:00
* Default switch for loading hidden images ( true loads , false blocks )
2016-11-03 03:45:33 +03:00
*
2016-01-20 01:17:52 +03:00
* @ property { String } [ compositeOperation = null ]
* Valid values are 'source-over' , 'source-atop' , 'source-in' , 'source-out' ,
Update to allow setting of globalCompositeOperation when
html <canvas> is used to process multiple tiledImages to blend
is a specific way.
(special handling,
when compositeOperation is 'source-over' and opacity is 1,
useSketch is false, otherwise useSketch is true
)
Valid values are 'source-atop', 'source-in', 'source-out',
'destination-over', 'destination-atop', 'destination-in',
'destination-out', 'lighter', 'copy' or 'xor'
http://www.w3schools.com/tags/canvas_globalcompositeoperation.asp
2016-01-06 18:58:36 +03:00
* 'destination-over' , 'destination-atop' , 'destination-in' ,
2016-01-07 23:47:17 +03:00
* 'destination-out' , 'lighter' , 'copy' or 'xor'
Update to allow setting of globalCompositeOperation when
html <canvas> is used to process multiple tiledImages to blend
is a specific way.
(special handling,
when compositeOperation is 'source-over' and opacity is 1,
useSketch is false, otherwise useSketch is true
)
Valid values are 'source-atop', 'source-in', 'source-out',
'destination-over', 'destination-atop', 'destination-in',
'destination-out', 'lighter', 'copy' or 'xor'
http://www.w3schools.com/tags/canvas_globalcompositeoperation.asp
2016-01-06 18:58:36 +03:00
*
2015-04-10 15:31:08 +03:00
* @ property { String | CanvasGradient | CanvasPattern | Function } [ placeholderFillStyle = null ]
2015-04-09 14:44:55 +03:00
* Draws a colored rectangle behind the tile if it is not loaded yet .
2015-04-11 20:01:09 +03:00
* You can pass a CSS color value like "#FF8800" .
2015-04-15 14:32:41 +03:00
* When passing a function the tiledImage and canvas context are available as argument which is useful when you draw a gradient or pattern .
2015-04-09 14:44:55 +03:00
*
2013-11-18 22:06:38 +04:00
* @ property { Number } [ degrees = 0 ]
2013-11-18 21:44:54 +04:00
* Initial rotation .
*
2013-11-18 22:06:38 +04:00
* @ property { Number } [ minZoomLevel = null ]
2013-11-18 21:44:54 +04:00
*
2013-11-18 22:06:38 +04:00
* @ property { Number } [ maxZoomLevel = null ]
2013-11-18 21:44:54 +04:00
*
2014-09-13 01:50:43 +04:00
* @ property { Boolean } [ homeFillsViewer = false ]
* Make the 'home' button fill the viewer and clip the image , instead
* of fitting the image to the viewer and letterboxing .
*
2013-11-18 22:06:38 +04:00
* @ property { Boolean } [ panHorizontal = true ]
2013-11-18 21:44:54 +04:00
* Allow horizontal pan .
*
2013-11-18 22:06:38 +04:00
* @ property { Boolean } [ panVertical = true ]
2013-11-18 21:44:54 +04:00
* Allow vertical pan .
*
2013-11-18 22:06:38 +04:00
* @ property { Boolean } [ constrainDuringPan = false ]
2013-11-18 21:44:54 +04:00
*
2013-11-18 22:06:38 +04:00
* @ property { Boolean } [ wrapHorizontal = false ]
2012-03-07 07:20:00 +04:00
* Set to true to force the image to wrap horizontally within the viewport .
* Useful for maps or images representing the surface of a sphere or cylinder .
2012-03-01 17:38:15 +04:00
*
2013-11-18 22:06:38 +04:00
* @ property { Boolean } [ wrapVertical = false ]
2012-03-07 07:20:00 +04:00
* Set to true to force the image to wrap vertically within the viewport .
* Useful for maps or images representing the surface of a sphere or cylinder .
2012-03-01 17:38:15 +04:00
*
2013-11-18 22:06:38 +04:00
* @ property { Number } [ minZoomImageRatio = 0.9 ]
2013-06-19 21:33:25 +04:00
* The minimum percentage ( expressed as a number between 0 and 1 ) of
2012-03-07 07:20:00 +04:00
* the viewport height or width at which the zoom out will be constrained .
2015-09-03 19:24:15 +03:00
* Setting it to 0 , for example will allow you to zoom out infinity .
2012-03-07 07:20:00 +04:00
*
2013-11-18 22:06:38 +04:00
* @ property { Number } [ maxZoomPixelRatio = 1.1 ]
2012-03-07 07:20:00 +04:00
* The maximum ratio to allow a zoom - in to affect the highest level pixel
* ratio . This can be set to Infinity to allow 'infinite' zooming into the
2013-06-19 21:33:25 +04:00
* image though it is less effective visually if the HTML5 Canvas is not
2012-03-07 07:20:00 +04:00
* availble on the viewing device .
2012-03-01 17:38:15 +04:00
*
2015-11-04 18:04:50 +03:00
* @ property { Number } [ smoothTileEdgesMinZoom = 1.1 ]
2015-11-05 17:19:56 +03:00
* A zoom percentage ( where 1 is 100 % ) of the highest resolution level .
* When zoomed in beyond this value alternative compositing will be used to
* smooth out the edges between tiles . This will have a performance impact .
2016-06-17 20:09:19 +03:00
* Can be set to Infinity to turn it off .
* Note : This setting is ignored on iOS devices due to a known bug ( See { @ link https : //github.com/openseadragon/openseadragon/issues/952})
2015-11-04 18:04:50 +03:00
*
2016-06-17 09:32:50 +03:00
* @ property { Boolean } [ iOSDevice = ? ]
* True if running on an iOS device , false otherwise .
* Used to disable certain features that behave differently on iOS devices .
*
2013-11-26 22:21:59 +04:00
* @ property { Boolean } [ autoResize = true ]
2013-11-26 00:10:19 +04:00
* Set to false to prevent polling for viewer size changes . Useful for providing custom resize behavior .
2013-11-23 05:07:44 +04:00
*
2015-06-23 19:55:57 +03:00
* @ property { Boolean } [ preserveImageSizeOnResize = false ]
2015-06-24 19:48:00 +03:00
* Set to true to have the image size preserved when the viewer is resized . This requires autoResize = true ( default ) .
2015-06-23 19:55:57 +03:00
*
2015-10-29 02:07:51 +03:00
* @ property { Number } [ minScrollDeltaTime = 50 ]
2015-10-27 23:00:45 +03:00
* Number of milliseconds between canvas - scroll events . This value helps normalize the rate of canvas - scroll
* events between different devices , causing the faster devices to slow down enough to make the zoom control
* more manageable .
*
2013-11-18 22:06:38 +04:00
* @ property { Number } [ pixelsPerWheelLine = 40 ]
2013-11-18 21:44:54 +04:00
* For pixel - resolution scrolling devices , the number of pixels equal to one scroll line .
*
2017-12-14 19:10:10 +03:00
* @ property { Number } [ pixelsPerArrowPress = 40 ]
* The number of pixels viewport moves when an arrow key is pressed .
*
2013-11-18 22:06:38 +04:00
* @ property { Number } [ visibilityRatio = 0.5 ]
2012-03-01 17:38:15 +04:00
* The percentage ( as a number from 0 to 1 ) of the source image which
* must be kept within the viewport . If the image is dragged beyond that
2014-08-27 02:12:49 +04:00
* limit , it will 'bounce' back until the minimum visibility ratio is
2012-03-01 17:38:15 +04:00
* achieved . Setting this to 0 and wrapHorizontal ( or wrapVertical ) to
* true will provide the effect of an infinitely scrolling viewport .
*
2014-10-17 02:19:05 +04:00
* @ property { Object } [ viewportMargins = { } ]
* Pushes the "home" region in from the sides by the specified amounts .
* Possible subproperties ( Numbers , in screen coordinates ) : left , top , right , bottom .
*
2013-11-18 22:06:38 +04:00
* @ property { Number } [ imageLoaderLimit = 0 ]
2015-04-09 14:44:55 +03:00
* The maximum number of image requests to make concurrently . By default
2012-03-07 07:20:00 +04:00
* it is set to 0 allowing the browser to make the maximum number of
* image requests in parallel as allowed by the browsers policy .
*
2013-11-18 22:06:38 +04:00
* @ property { Number } [ clickTimeThreshold = 300 ]
2014-04-22 20:23:56 +04:00
* The number of milliseconds within which a pointer down - up event combination
* will be treated as a click gesture .
2012-03-07 07:20:00 +04:00
*
2013-11-18 22:06:38 +04:00
* @ property { Number } [ clickDistThreshold = 5 ]
2014-04-22 20:23:56 +04:00
* The maximum distance allowed between a pointer down event and a pointer up event
* to be treated as a click gesture .
*
* @ property { Number } [ dblClickTimeThreshold = 300 ]
* The number of milliseconds within which two pointer down - up event combinations
* will be treated as a double - click gesture .
*
* @ property { Number } [ dblClickDistThreshold = 20 ]
* The maximum distance allowed between two pointer click events
* to be treated as a double - click gesture .
2012-03-07 07:20:00 +04:00
*
2014-04-21 08:25:29 +04:00
* @ property { Number } [ springStiffness = 6.5 ]
2014-04-03 19:50:25 +04:00
*
* @ property { Number } [ animationTime = 1.2 ]
* Specifies the animation duration per each { @ link OpenSeadragon . Spring }
* which occur when the image is dragged or zoomed .
*
* @ property { OpenSeadragon . GestureSettings } [ gestureSettingsMouse ]
* Settings for gestures generated by a mouse pointer device . ( See { @ link OpenSeadragon . GestureSettings } )
2014-04-03 21:06:12 +04:00
* @ property { Boolean } [ gestureSettingsMouse . scrollToZoom = true ] - Zoom on scroll gesture
2014-04-03 19:50:25 +04:00
* @ property { Boolean } [ gestureSettingsMouse . clickToZoom = true ] - Zoom on click gesture
2014-04-22 20:41:29 +04:00
* @ property { Boolean } [ gestureSettingsMouse . dblClickToZoom = false ] - Zoom on double - click gesture . Note : If set to true
* then clickToZoom should be set to false to prevent multiple zooms .
2014-04-16 06:19:47 +04:00
* @ property { Boolean } [ gestureSettingsMouse . pinchToZoom = false ] - Zoom on pinch gesture
2018-03-16 13:44:42 +03:00
* @ property { Boolean } [ gestureSettingsMouse . zoomToRefPoint = true ] - If zoomToRefPoint is true , the zoom is centered at the pointer position . Otherwise ,
2018-03-16 13:29:16 +03:00
* the zoom is centered at the canvas center .
2014-04-03 19:50:25 +04:00
* @ property { Boolean } [ gestureSettingsMouse . flickEnabled = false ] - Enable flick gesture
2014-04-21 05:19:32 +04:00
* @ property { Number } [ gestureSettingsMouse . flickMinSpeed = 120 ] - If flickEnabled is true , the minimum speed to initiate a flick gesture ( pixels - per - second )
* @ property { Number } [ gestureSettingsMouse . flickMomentum = 0.25 ] - If flickEnabled is true , the momentum factor for the flick gesture
2014-08-22 18:22:00 +04:00
* @ property { Boolean } [ gestureSettingsMouse . pinchRotate = false ] - If pinchRotate is true , the user will have the ability to rotate the image using their fingers .
2014-04-03 19:50:25 +04:00
*
* @ property { OpenSeadragon . GestureSettings } [ gestureSettingsTouch ]
* Settings for gestures generated by a touch pointer device . ( See { @ link OpenSeadragon . GestureSettings } )
2014-04-03 21:06:12 +04:00
* @ property { Boolean } [ gestureSettingsTouch . scrollToZoom = false ] - Zoom on scroll gesture
2014-04-03 19:50:25 +04:00
* @ property { Boolean } [ gestureSettingsTouch . clickToZoom = false ] - Zoom on click gesture
2014-04-22 20:41:29 +04:00
* @ property { Boolean } [ gestureSettingsTouch . dblClickToZoom = true ] - Zoom on double - click gesture . Note : If set to true
* then clickToZoom should be set to false to prevent multiple zooms .
2014-04-16 06:19:47 +04:00
* @ property { Boolean } [ gestureSettingsTouch . pinchToZoom = true ] - Zoom on pinch gesture
2018-03-16 13:44:42 +03:00
* @ property { Boolean } [ gestureSettingsTouch . zoomToRefPoint = true ] - If zoomToRefPoint is true , the zoom is centered at the pointer position . Otherwise ,
2018-03-16 13:29:16 +03:00
* the zoom is centered at the canvas center .
2014-04-03 19:50:25 +04:00
* @ property { Boolean } [ gestureSettingsTouch . flickEnabled = true ] - Enable flick gesture
2014-04-21 05:19:32 +04:00
* @ property { Number } [ gestureSettingsTouch . flickMinSpeed = 120 ] - If flickEnabled is true , the minimum speed to initiate a flick gesture ( pixels - per - second )
* @ property { Number } [ gestureSettingsTouch . flickMomentum = 0.25 ] - If flickEnabled is true , the momentum factor for the flick gesture
2014-08-22 18:22:00 +04:00
* @ property { Boolean } [ gestureSettingsTouch . pinchRotate = false ] - If pinchRotate is true , the user will have the ability to rotate the image using their fingers .
2014-04-03 19:50:25 +04:00
*
* @ property { OpenSeadragon . GestureSettings } [ gestureSettingsPen ]
* Settings for gestures generated by a pen pointer device . ( See { @ link OpenSeadragon . GestureSettings } )
2014-04-03 21:06:12 +04:00
* @ property { Boolean } [ gestureSettingsPen . scrollToZoom = false ] - Zoom on scroll gesture
2014-04-03 19:50:25 +04:00
* @ property { Boolean } [ gestureSettingsPen . clickToZoom = true ] - Zoom on click gesture
2014-04-22 20:41:29 +04:00
* @ property { Boolean } [ gestureSettingsPen . dblClickToZoom = false ] - Zoom on double - click gesture . Note : If set to true
* then clickToZoom should be set to false to prevent multiple zooms .
2014-04-16 06:19:47 +04:00
* @ property { Boolean } [ gestureSettingsPen . pinchToZoom = false ] - Zoom on pinch gesture
2018-03-16 13:44:42 +03:00
* @ property { Boolean } [ gestureSettingsPan . zoomToRefPoint = true ] - If zoomToRefPoint is true , the zoom is centered at the pointer position . Otherwise ,
2018-03-16 13:29:16 +03:00
* the zoom is centered at the canvas center .
2014-04-03 19:50:25 +04:00
* @ property { Boolean } [ gestureSettingsPen . flickEnabled = false ] - Enable flick gesture
2014-04-21 05:19:32 +04:00
* @ property { Number } [ gestureSettingsPen . flickMinSpeed = 120 ] - If flickEnabled is true , the minimum speed to initiate a flick gesture ( pixels - per - second )
* @ property { Number } [ gestureSettingsPen . flickMomentum = 0.25 ] - If flickEnabled is true , the momentum factor for the flick gesture
2014-08-22 18:22:00 +04:00
* @ property { Boolean } [ gestureSettingsPen . pinchRotate = false ] - If pinchRotate is true , the user will have the ability to rotate the image using their fingers .
2014-04-15 05:17:18 +04:00
*
* @ property { OpenSeadragon . GestureSettings } [ gestureSettingsUnknown ]
* Settings for gestures generated by unknown pointer devices . ( See { @ link OpenSeadragon . GestureSettings } )
* @ property { Boolean } [ gestureSettingsUnknown . scrollToZoom = true ] - Zoom on scroll gesture
* @ property { Boolean } [ gestureSettingsUnknown . clickToZoom = false ] - Zoom on click gesture
2014-04-22 20:41:29 +04:00
* @ property { Boolean } [ gestureSettingsUnknown . dblClickToZoom = true ] - Zoom on double - click gesture . Note : If set to true
* then clickToZoom should be set to false to prevent multiple zooms .
2014-04-16 06:19:47 +04:00
* @ property { Boolean } [ gestureSettingsUnknown . pinchToZoom = true ] - Zoom on pinch gesture
2018-03-16 13:44:42 +03:00
* @ property { Boolean } [ gestureSettingsUnknown . zoomToRefPoint = true ] - If zoomToRefPoint is true , the zoom is centered at the pointer position . Otherwise ,
2018-03-16 13:29:16 +03:00
* the zoom is centered at the canvas center .
2014-04-15 05:17:18 +04:00
* @ property { Boolean } [ gestureSettingsUnknown . flickEnabled = true ] - Enable flick gesture
2014-04-21 05:19:32 +04:00
* @ property { Number } [ gestureSettingsUnknown . flickMinSpeed = 120 ] - If flickEnabled is true , the minimum speed to initiate a flick gesture ( pixels - per - second )
* @ property { Number } [ gestureSettingsUnknown . flickMomentum = 0.25 ] - If flickEnabled is true , the momentum factor for the flick gesture
2014-08-22 18:22:00 +04:00
* @ property { Boolean } [ gestureSettingsUnknown . pinchRotate = false ] - If pinchRotate is true , the user will have the ability to rotate the image using their fingers .
2014-04-03 19:50:25 +04:00
*
2013-11-18 22:06:38 +04:00
* @ property { Number } [ zoomPerClick = 2.0 ]
2014-04-22 20:23:56 +04:00
* The "zoom distance" per mouse click or touch tap . < em > < strong > Note : < / s t r o n g > S e t t i n g t h i s t o 1 . 0 e f f e c t i v e l y d i s a b l e s t h e c l i c k - t o - z o o m f e a t u r e ( a l s o s e e g e s t u r e S e t t i n g s [ M o u s e | T o u c h | P e n ] . c l i c k T o Z o o m / d b l C l i c k T o Z o o m ) . < / e m >
2012-03-07 07:20:00 +04:00
*
2013-11-18 22:06:38 +04:00
* @ property { Number } [ zoomPerScroll = 1.2 ]
2014-04-03 21:06:12 +04:00
* The "zoom distance" per mouse scroll or touch pinch . < em > < strong > Note : < / s t r o n g > S e t t i n g t h i s t o 1 . 0 e f f e c t i v e l y d i s a b l e s t h e m o u s e - w h e e l z o o m f e a t u r e ( a l s o s e e g e s t u r e S e t t i n g s [ M o u s e | T o u c h | P e n ] . s c r o l l T o Z o o m } ) . < / e m >
2012-03-07 07:20:00 +04:00
*
2013-11-18 22:06:38 +04:00
* @ property { Number } [ zoomPerSecond = 1.0 ]
2012-03-07 07:20:00 +04:00
* The number of seconds to animate a single zoom event over .
2012-03-01 17:38:15 +04:00
*
2013-11-18 22:06:38 +04:00
* @ property { Boolean } [ showNavigator = false ]
2013-05-27 05:16:56 +04:00
* Set to true to make the navigator minimap appear .
*
2015-09-03 19:24:15 +03:00
* @ property { String } [ navigatorId = navigator - GENERATED DATE ]
Enhanced Navigator Resizability (#280, #296)
New navigator options:
* @property {Boolean} [showNavigator=false]
* Set to true to make the navigator minimap appear.
*
* @property {Boolean} [navigatorId=navigator-GENERATED DATE]
* The ID of a div to hold the navigator minimap.
* If an ID is specified, the navigatorPosition, navigatorSizeRatio,
navigatorMaintainSizeRatio, and navigatorTop|Left|Height|Width options
will be ignored.
* If an ID is not specified, a div element will be generated and
placed on top of the main image.
*
* @property {String} [navigatorPosition='TOP_RIGHT']
* Valid values are 'TOP_LEFT', 'TOP_RIGHT', 'BOTTOM_LEFT',
'BOTTOM_RIGHT', or 'ABSOLUTE'.<br>
* If 'ABSOLUTE' is specified, then navigatorTop|Left|Height|Width
determines the size and position of the navigator minimap in the viewer,
and navigatorSizeRatio and navigatorMaintainSizeRatio are ignored.<br>
* For 'TOP_LEFT', 'TOP_RIGHT', 'BOTTOM_LEFT', and 'BOTTOM_RIGHT',
the navigatorSizeRatio or navigatorHeight|Width values determine the
size of the navigator minimap.
*
* @property {Number} [navigatorSizeRatio=0.2]
* Ratio of navigator size to viewer size. Ignored if
navigatorHeight|Width are specified.
*
* @property {Boolean} [navigatorMaintainSizeRatio=false]
* If true, the navigator minimap is resized (using
navigatorSizeRatio) when the viewer size changes.
*
* @property {Number|String} [navigatorTop=null]
* Specifies the location of the navigator minimap (see
navigatorPosition).
*
* @property {Number|String} [navigatorLeft=null]
* Specifies the location of the navigator minimap (see
navigatorPosition).
*
* @property {Number|String} [navigatorHeight=null]
* Specifies the size of the navigator minimap (see
navigatorPosition).
* If specified, navigatorSizeRatio and navigatorMaintainSizeRatio
are ignored.
*
* @property {Number|String} [navigatorWidth=null]
* Specifies the size of the navigator minimap (see
navigatorPosition).
* If specified, navigatorSizeRatio and navigatorMaintainSizeRatio
are ignored.
Fixes #280 and #296
2013-12-13 21:23:56 +04:00
* The ID of a div to hold the navigator minimap .
2016-05-06 04:00:01 +03:00
* If an ID is specified , the navigatorPosition , navigatorSizeRatio , navigatorMaintainSizeRatio , navigator [ Top | Left | Height | Width ] and navigatorAutoFade options will be ignored .
Enhanced Navigator Resizability (#280, #296)
New navigator options:
* @property {Boolean} [showNavigator=false]
* Set to true to make the navigator minimap appear.
*
* @property {Boolean} [navigatorId=navigator-GENERATED DATE]
* The ID of a div to hold the navigator minimap.
* If an ID is specified, the navigatorPosition, navigatorSizeRatio,
navigatorMaintainSizeRatio, and navigatorTop|Left|Height|Width options
will be ignored.
* If an ID is not specified, a div element will be generated and
placed on top of the main image.
*
* @property {String} [navigatorPosition='TOP_RIGHT']
* Valid values are 'TOP_LEFT', 'TOP_RIGHT', 'BOTTOM_LEFT',
'BOTTOM_RIGHT', or 'ABSOLUTE'.<br>
* If 'ABSOLUTE' is specified, then navigatorTop|Left|Height|Width
determines the size and position of the navigator minimap in the viewer,
and navigatorSizeRatio and navigatorMaintainSizeRatio are ignored.<br>
* For 'TOP_LEFT', 'TOP_RIGHT', 'BOTTOM_LEFT', and 'BOTTOM_RIGHT',
the navigatorSizeRatio or navigatorHeight|Width values determine the
size of the navigator minimap.
*
* @property {Number} [navigatorSizeRatio=0.2]
* Ratio of navigator size to viewer size. Ignored if
navigatorHeight|Width are specified.
*
* @property {Boolean} [navigatorMaintainSizeRatio=false]
* If true, the navigator minimap is resized (using
navigatorSizeRatio) when the viewer size changes.
*
* @property {Number|String} [navigatorTop=null]
* Specifies the location of the navigator minimap (see
navigatorPosition).
*
* @property {Number|String} [navigatorLeft=null]
* Specifies the location of the navigator minimap (see
navigatorPosition).
*
* @property {Number|String} [navigatorHeight=null]
* Specifies the size of the navigator minimap (see
navigatorPosition).
* If specified, navigatorSizeRatio and navigatorMaintainSizeRatio
are ignored.
*
* @property {Number|String} [navigatorWidth=null]
* Specifies the size of the navigator minimap (see
navigatorPosition).
* If specified, navigatorSizeRatio and navigatorMaintainSizeRatio
are ignored.
Fixes #280 and #296
2013-12-13 21:23:56 +04:00
* If an ID is not specified , a div element will be generated and placed on top of the main image .
2013-05-27 05:16:56 +04:00
*
Enhanced Navigator Resizability (#280, #296)
New navigator options:
* @property {Boolean} [showNavigator=false]
* Set to true to make the navigator minimap appear.
*
* @property {Boolean} [navigatorId=navigator-GENERATED DATE]
* The ID of a div to hold the navigator minimap.
* If an ID is specified, the navigatorPosition, navigatorSizeRatio,
navigatorMaintainSizeRatio, and navigatorTop|Left|Height|Width options
will be ignored.
* If an ID is not specified, a div element will be generated and
placed on top of the main image.
*
* @property {String} [navigatorPosition='TOP_RIGHT']
* Valid values are 'TOP_LEFT', 'TOP_RIGHT', 'BOTTOM_LEFT',
'BOTTOM_RIGHT', or 'ABSOLUTE'.<br>
* If 'ABSOLUTE' is specified, then navigatorTop|Left|Height|Width
determines the size and position of the navigator minimap in the viewer,
and navigatorSizeRatio and navigatorMaintainSizeRatio are ignored.<br>
* For 'TOP_LEFT', 'TOP_RIGHT', 'BOTTOM_LEFT', and 'BOTTOM_RIGHT',
the navigatorSizeRatio or navigatorHeight|Width values determine the
size of the navigator minimap.
*
* @property {Number} [navigatorSizeRatio=0.2]
* Ratio of navigator size to viewer size. Ignored if
navigatorHeight|Width are specified.
*
* @property {Boolean} [navigatorMaintainSizeRatio=false]
* If true, the navigator minimap is resized (using
navigatorSizeRatio) when the viewer size changes.
*
* @property {Number|String} [navigatorTop=null]
* Specifies the location of the navigator minimap (see
navigatorPosition).
*
* @property {Number|String} [navigatorLeft=null]
* Specifies the location of the navigator minimap (see
navigatorPosition).
*
* @property {Number|String} [navigatorHeight=null]
* Specifies the size of the navigator minimap (see
navigatorPosition).
* If specified, navigatorSizeRatio and navigatorMaintainSizeRatio
are ignored.
*
* @property {Number|String} [navigatorWidth=null]
* Specifies the size of the navigator minimap (see
navigatorPosition).
* If specified, navigatorSizeRatio and navigatorMaintainSizeRatio
are ignored.
Fixes #280 and #296
2013-12-13 21:23:56 +04:00
* @ property { String } [ navigatorPosition = 'TOP_RIGHT' ]
* Valid values are 'TOP_LEFT' , 'TOP_RIGHT' , 'BOTTOM_LEFT' , 'BOTTOM_RIGHT' , or 'ABSOLUTE' . < br >
2016-05-06 04:00:01 +03:00
* If 'ABSOLUTE' is specified , then navigator [ Top | Left | Height | Width ] determines the size and position of the navigator minimap in the viewer , and navigatorSizeRatio and navigatorMaintainSizeRatio are ignored . < br >
* For 'TOP_LEFT' , 'TOP_RIGHT' , 'BOTTOM_LEFT' , and 'BOTTOM_RIGHT' , the navigatorSizeRatio or navigator [ Height | Width ] values determine the size of the navigator minimap .
2013-11-18 21:44:54 +04:00
*
Enhanced Navigator Resizability (#280, #296)
New navigator options:
* @property {Boolean} [showNavigator=false]
* Set to true to make the navigator minimap appear.
*
* @property {Boolean} [navigatorId=navigator-GENERATED DATE]
* The ID of a div to hold the navigator minimap.
* If an ID is specified, the navigatorPosition, navigatorSizeRatio,
navigatorMaintainSizeRatio, and navigatorTop|Left|Height|Width options
will be ignored.
* If an ID is not specified, a div element will be generated and
placed on top of the main image.
*
* @property {String} [navigatorPosition='TOP_RIGHT']
* Valid values are 'TOP_LEFT', 'TOP_RIGHT', 'BOTTOM_LEFT',
'BOTTOM_RIGHT', or 'ABSOLUTE'.<br>
* If 'ABSOLUTE' is specified, then navigatorTop|Left|Height|Width
determines the size and position of the navigator minimap in the viewer,
and navigatorSizeRatio and navigatorMaintainSizeRatio are ignored.<br>
* For 'TOP_LEFT', 'TOP_RIGHT', 'BOTTOM_LEFT', and 'BOTTOM_RIGHT',
the navigatorSizeRatio or navigatorHeight|Width values determine the
size of the navigator minimap.
*
* @property {Number} [navigatorSizeRatio=0.2]
* Ratio of navigator size to viewer size. Ignored if
navigatorHeight|Width are specified.
*
* @property {Boolean} [navigatorMaintainSizeRatio=false]
* If true, the navigator minimap is resized (using
navigatorSizeRatio) when the viewer size changes.
*
* @property {Number|String} [navigatorTop=null]
* Specifies the location of the navigator minimap (see
navigatorPosition).
*
* @property {Number|String} [navigatorLeft=null]
* Specifies the location of the navigator minimap (see
navigatorPosition).
*
* @property {Number|String} [navigatorHeight=null]
* Specifies the size of the navigator minimap (see
navigatorPosition).
* If specified, navigatorSizeRatio and navigatorMaintainSizeRatio
are ignored.
*
* @property {Number|String} [navigatorWidth=null]
* Specifies the size of the navigator minimap (see
navigatorPosition).
* If specified, navigatorSizeRatio and navigatorMaintainSizeRatio
are ignored.
Fixes #280 and #296
2013-12-13 21:23:56 +04:00
* @ property { Number } [ navigatorSizeRatio = 0.2 ]
2016-05-06 04:00:01 +03:00
* Ratio of navigator size to viewer size . Ignored if navigator [ Height | Width ] are specified .
2013-11-18 21:44:54 +04:00
*
Enhanced Navigator Resizability (#280, #296)
New navigator options:
* @property {Boolean} [showNavigator=false]
* Set to true to make the navigator minimap appear.
*
* @property {Boolean} [navigatorId=navigator-GENERATED DATE]
* The ID of a div to hold the navigator minimap.
* If an ID is specified, the navigatorPosition, navigatorSizeRatio,
navigatorMaintainSizeRatio, and navigatorTop|Left|Height|Width options
will be ignored.
* If an ID is not specified, a div element will be generated and
placed on top of the main image.
*
* @property {String} [navigatorPosition='TOP_RIGHT']
* Valid values are 'TOP_LEFT', 'TOP_RIGHT', 'BOTTOM_LEFT',
'BOTTOM_RIGHT', or 'ABSOLUTE'.<br>
* If 'ABSOLUTE' is specified, then navigatorTop|Left|Height|Width
determines the size and position of the navigator minimap in the viewer,
and navigatorSizeRatio and navigatorMaintainSizeRatio are ignored.<br>
* For 'TOP_LEFT', 'TOP_RIGHT', 'BOTTOM_LEFT', and 'BOTTOM_RIGHT',
the navigatorSizeRatio or navigatorHeight|Width values determine the
size of the navigator minimap.
*
* @property {Number} [navigatorSizeRatio=0.2]
* Ratio of navigator size to viewer size. Ignored if
navigatorHeight|Width are specified.
*
* @property {Boolean} [navigatorMaintainSizeRatio=false]
* If true, the navigator minimap is resized (using
navigatorSizeRatio) when the viewer size changes.
*
* @property {Number|String} [navigatorTop=null]
* Specifies the location of the navigator minimap (see
navigatorPosition).
*
* @property {Number|String} [navigatorLeft=null]
* Specifies the location of the navigator minimap (see
navigatorPosition).
*
* @property {Number|String} [navigatorHeight=null]
* Specifies the size of the navigator minimap (see
navigatorPosition).
* If specified, navigatorSizeRatio and navigatorMaintainSizeRatio
are ignored.
*
* @property {Number|String} [navigatorWidth=null]
* Specifies the size of the navigator minimap (see
navigatorPosition).
* If specified, navigatorSizeRatio and navigatorMaintainSizeRatio
are ignored.
Fixes #280 and #296
2013-12-13 21:23:56 +04:00
* @ property { Boolean } [ navigatorMaintainSizeRatio = false ]
* If true , the navigator minimap is resized ( using navigatorSizeRatio ) when the viewer size changes .
2013-11-18 21:44:54 +04:00
*
Enhanced Navigator Resizability (#280, #296)
New navigator options:
* @property {Boolean} [showNavigator=false]
* Set to true to make the navigator minimap appear.
*
* @property {Boolean} [navigatorId=navigator-GENERATED DATE]
* The ID of a div to hold the navigator minimap.
* If an ID is specified, the navigatorPosition, navigatorSizeRatio,
navigatorMaintainSizeRatio, and navigatorTop|Left|Height|Width options
will be ignored.
* If an ID is not specified, a div element will be generated and
placed on top of the main image.
*
* @property {String} [navigatorPosition='TOP_RIGHT']
* Valid values are 'TOP_LEFT', 'TOP_RIGHT', 'BOTTOM_LEFT',
'BOTTOM_RIGHT', or 'ABSOLUTE'.<br>
* If 'ABSOLUTE' is specified, then navigatorTop|Left|Height|Width
determines the size and position of the navigator minimap in the viewer,
and navigatorSizeRatio and navigatorMaintainSizeRatio are ignored.<br>
* For 'TOP_LEFT', 'TOP_RIGHT', 'BOTTOM_LEFT', and 'BOTTOM_RIGHT',
the navigatorSizeRatio or navigatorHeight|Width values determine the
size of the navigator minimap.
*
* @property {Number} [navigatorSizeRatio=0.2]
* Ratio of navigator size to viewer size. Ignored if
navigatorHeight|Width are specified.
*
* @property {Boolean} [navigatorMaintainSizeRatio=false]
* If true, the navigator minimap is resized (using
navigatorSizeRatio) when the viewer size changes.
*
* @property {Number|String} [navigatorTop=null]
* Specifies the location of the navigator minimap (see
navigatorPosition).
*
* @property {Number|String} [navigatorLeft=null]
* Specifies the location of the navigator minimap (see
navigatorPosition).
*
* @property {Number|String} [navigatorHeight=null]
* Specifies the size of the navigator minimap (see
navigatorPosition).
* If specified, navigatorSizeRatio and navigatorMaintainSizeRatio
are ignored.
*
* @property {Number|String} [navigatorWidth=null]
* Specifies the size of the navigator minimap (see
navigatorPosition).
* If specified, navigatorSizeRatio and navigatorMaintainSizeRatio
are ignored.
Fixes #280 and #296
2013-12-13 21:23:56 +04:00
* @ property { Number | String } [ navigatorTop = null ]
* Specifies the location of the navigator minimap ( see navigatorPosition ) .
*
* @ property { Number | String } [ navigatorLeft = null ]
* Specifies the location of the navigator minimap ( see navigatorPosition ) .
*
* @ property { Number | String } [ navigatorHeight = null ]
* Specifies the size of the navigator minimap ( see navigatorPosition ) .
* If specified , navigatorSizeRatio and navigatorMaintainSizeRatio are ignored .
*
* @ property { Number | String } [ navigatorWidth = null ]
* Specifies the size of the navigator minimap ( see navigatorPosition ) .
* If specified , navigatorSizeRatio and navigatorMaintainSizeRatio are ignored .
2013-11-18 21:44:54 +04:00
*
2013-12-15 02:45:11 +04:00
* @ property { Boolean } [ navigatorAutoResize = true ]
* Set to false to prevent polling for navigator size changes . Useful for providing custom resize behavior .
* Setting to false can also improve performance when the navigator is configured to a fixed size .
*
2016-05-06 04:00:01 +03:00
* @ property { Boolean } [ navigatorAutoFade = true ]
* If the user stops interacting with the viewport , fade the navigator minimap .
* Setting to false will make the navigator minimap always visible .
*
2014-08-12 18:27:16 +04:00
* @ property { Boolean } [ navigatorRotate = true ]
* If true , the navigator will be rotated together with the viewer .
*
2013-11-18 22:06:38 +04:00
* @ property { Number } [ controlsFadeDelay = 2000 ]
2012-03-01 17:38:15 +04:00
* The number of milliseconds to wait once the user has stopped interacting
* with the interface before begining to fade the controls . Assumes
* showNavigationControl and autoHideControls are both true .
*
2013-11-18 22:06:38 +04:00
* @ property { Number } [ controlsFadeLength = 1500 ]
2012-03-01 17:38:15 +04:00
* The number of milliseconds to animate the controls fading out .
*
2013-11-18 22:06:38 +04:00
* @ property { Number } [ maxImageCacheCount = 200 ]
2012-03-01 17:38:15 +04:00
* The max number of images we should keep in memory ( per drawer ) .
*
2013-11-18 22:06:38 +04:00
* @ property { Number } [ timeout = 30000 ]
2017-05-12 07:36:27 +03:00
* The max number of milliseconds that an image job may take to complete .
2013-11-18 21:44:54 +04:00
*
2013-11-18 22:06:38 +04:00
* @ property { Boolean } [ useCanvas = true ]
2013-11-02 00:02:28 +04:00
* Set to false to not use an HTML canvas element for image rendering even if canvas is supported .
*
2013-11-18 22:06:38 +04:00
* @ property { Number } [ minPixelRatio = 0.5 ]
2012-03-01 17:38:15 +04:00
* The higher the minPixelRatio , the lower the quality of the image that
* is considered sufficient to stop rendering a given zoom level . For
2013-06-19 21:33:25 +04:00
* example , if you are targeting mobile devices with less bandwith you may
2012-03-01 17:38:15 +04:00
* try setting this to 1.5 or higher .
*
2013-11-18 22:06:38 +04:00
* @ property { Boolean } [ mouseNavEnabled = true ]
2013-06-19 21:33:25 +04:00
* Is the user able to interact with the image via mouse or touch . Default
2012-03-01 17:38:15 +04:00
* interactions include draging the image in a plane , and zooming in toward
* and away from the image .
*
2014-04-07 22:11:33 +04:00
* @ property { Boolean } [ showNavigationControl = true ]
2014-04-09 18:18:51 +04:00
* Set to false to prevent the appearance of the default navigation controls . < br >
* Note that if set to false , the customs buttons set by the options
2014-04-07 22:11:33 +04:00
* 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 ]
2014-04-09 18:18:51 +04:00
* If true then + and - buttons to zoom in and out are displayed . < br >
* Note : { @ link OpenSeadragon . Options . showNavigationControl } is overriding
* this setting when set to false .
2014-04-07 22:11:33 +04:00
*
* @ property { Boolean } [ showHomeControl = true ]
* If true then the 'Go home' button is displayed to go back to the original
2014-04-09 18:18:51 +04:00
* zoom and pan . < br >
* Note : { @ link OpenSeadragon . Options . showNavigationControl } is overriding
* this setting when set to false .
2014-04-07 22:11:33 +04:00
*
* @ property { Boolean } [ showFullPageControl = true ]
* If true then the 'Toggle full page' button is displayed to switch
2014-04-09 18:18:51 +04:00
* between full page and normal mode . < br >
* Note : { @ link OpenSeadragon . Options . showNavigationControl } is overriding
* this setting when set to false .
2013-11-19 22:08:04 +04:00
*
2014-03-03 20:28:28 +04:00
* @ 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
2014-04-09 18:18:51 +04:00
* ( e . g . viewer . drawer . canRotate ( ) ) . < br >
* Note : { @ link OpenSeadragon . Options . showNavigationControl } is overriding
* this setting when set to false .
2014-03-03 20:28:28 +04:00
*
2018-04-04 13:31:18 +03:00
* @ property { Boolean } [ showFlipControl = false ]
* If true then the flip controls will be displayed as part of the
* standard controls .
*
2013-11-18 22:06:38 +04:00
* @ property { Boolean } [ showSequenceControl = true ]
2014-11-17 22:50:20 +03:00
* If sequenceMode is true , then provide buttons for navigating forward and
* backward through the images .
2013-11-18 21:44:54 +04:00
*
2013-12-07 10:48:49 +04:00
* @ property { OpenSeadragon . ControlAnchor } [ sequenceControlAnchor = TOP _LEFT ]
* Placement of the default sequence controls .
*
2014-04-07 22:11:33 +04:00
* @ property { Boolean } [ navPrevNextWrap = false ]
2014-04-09 18:18:51 +04:00
* 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 .
2014-04-07 22:11:33 +04:00
*
* @ property { String } zoomInButton
* Set the id of the custom 'Zoom in' button to use .
2014-04-09 20:06:46 +04:00
* This is useful to have a custom button anywhere in the web page . < br >
2014-04-09 18:18:51 +04:00
* To only change the button images , consider using
* { @ link OpenSeadragon . Options . navImages }
2014-04-07 22:11:33 +04:00
*
* @ property { String } zoomOutButton
* Set the id of the custom 'Zoom out' button to use .
2014-04-09 20:06:46 +04:00
* This is useful to have a custom button anywhere in the web page . < br >
2014-04-09 18:18:51 +04:00
* To only change the button images , consider using
* { @ link OpenSeadragon . Options . navImages }
2014-04-07 22:11:33 +04:00
*
* @ property { String } homeButton
* Set the id of the custom 'Go home' button to use .
2014-04-09 20:06:46 +04:00
* This is useful to have a custom button anywhere in the web page . < br >
2014-04-09 18:18:51 +04:00
* To only change the button images , consider using
* { @ link OpenSeadragon . Options . navImages }
2014-04-07 22:11:33 +04:00
*
* @ property { String } fullPageButton
* Set the id of the custom 'Toggle full page' button to use .
2014-04-09 20:06:46 +04:00
* This is useful to have a custom button anywhere in the web page . < br >
2014-04-09 18:18:51 +04:00
* To only change the button images , consider using
* { @ link OpenSeadragon . Options . navImages }
2014-04-07 22:11:33 +04:00
*
* @ property { String } rotateLeftButton
* Set the id of the custom 'Rotate left' button to use .
2014-04-09 20:06:46 +04:00
* This is useful to have a custom button anywhere in the web page . < br >
2014-04-09 18:18:51 +04:00
* To only change the button images , consider using
* { @ link OpenSeadragon . Options . navImages }
2014-04-07 22:11:33 +04:00
*
* @ property { String } rotateRightButton
* Set the id of the custom 'Rotate right' button to use .
2014-04-09 20:06:46 +04:00
* This is useful to have a custom button anywhere in the web page . < br >
2014-04-09 18:18:51 +04:00
* To only change the button images , consider using
* { @ link OpenSeadragon . Options . navImages }
2014-04-07 22:11:33 +04:00
*
* @ property { String } previousButton
* Set the id of the custom 'Previous page' button to use .
2014-04-09 20:06:46 +04:00
* This is useful to have a custom button anywhere in the web page . < br >
2014-04-09 18:18:51 +04:00
* To only change the button images , consider using
* { @ link OpenSeadragon . Options . navImages }
2014-04-07 22:11:33 +04:00
*
* @ property { String } nextButton
* Set the id of the custom 'Next page' button to use .
2014-04-09 20:06:46 +04:00
* This is useful to have a custom button anywhere in the web page . < br >
2014-04-09 18:18:51 +04:00
* To only change the button images , consider using
* { @ link OpenSeadragon . Options . navImages }
2014-04-07 22:11:33 +04:00
*
2014-11-17 22:50:20 +03:00
* @ property { Boolean } [ sequenceMode = false ]
* Set to true to have the viewer treat your tilesources as a sequence of images to
* be opened one at a time rather than all at once .
*
2013-11-18 22:06:38 +04:00
* @ property { Number } [ initialPage = 0 ]
2014-11-17 22:50:20 +03:00
* If sequenceMode is true , display this page initially .
2013-11-18 21:44:54 +04:00
*
2013-11-18 22:06:38 +04:00
* @ property { Boolean } [ preserveViewport = false ]
2015-02-14 00:26:44 +03:00
* If sequenceMode is true , then normally navigating through each image resets the
2014-11-17 22:50:20 +03:00
* viewport to 'home' position . If preserveViewport is set to true , then the viewport
* position is preserved when navigating between images in the sequence .
2012-04-03 11:08:27 +04:00
*
2015-01-09 05:21:16 +03:00
* @ property { Boolean } [ preserveOverlays = false ]
2015-02-14 00:26:44 +03:00
* If sequenceMode is true , then normally navigating through each image
2015-01-13 01:31:20 +03:00
* resets the overlays .
2015-02-14 00:26:44 +03:00
* If preserveOverlays is set to true , then the overlays added with { @ link OpenSeadragon . Viewer # addOverlay }
2015-01-09 05:21:16 +03:00
* are preserved when navigating between images in the sequence .
2015-02-14 00:26:44 +03:00
* Note : setting preserveOverlays overrides any overlays specified in the global
* "overlays" option for the Viewer . It ' s also not compatible with specifying
* per - tileSource overlays via the options , as those overlays will persist
* even after the tileSource is closed .
2015-01-09 05:21:16 +03:00
*
2013-11-19 22:08:04 +04:00
* @ property { Boolean } [ showReferenceStrip = false ]
2014-11-17 22:50:20 +03:00
* If sequenceMode is true , then display a scrolling strip of image thumbnails for
* navigating through the images .
2012-03-01 17:38:15 +04:00
*
2013-11-19 22:08:04 +04:00
* @ property { String } [ referenceStripScroll = 'horizontal' ]
2012-03-01 17:38:15 +04:00
*
2013-11-19 22:08:04 +04:00
* @ property { Element } [ referenceStripElement = null ]
*
* @ property { Number } [ referenceStripHeight = null ]
*
* @ property { Number } [ referenceStripWidth = null ]
*
* @ property { String } [ referenceStripPosition = 'BOTTOM_LEFT' ]
*
* @ property { Number } [ referenceStripSizeRatio = 0.2 ]
*
* @ property { Boolean } [ collectionMode = false ]
2014-11-13 03:31:46 +03:00
* Set to true to have the viewer arrange your TiledImages in a grid or line .
2013-11-19 22:08:04 +04:00
*
* @ property { Number } [ collectionRows = 3 ]
2014-11-13 03:31:46 +03:00
* If collectionMode is true , specifies how many rows the grid should have . Use 1 to make a line .
* If collectionLayout is 'vertical' , specifies how many columns instead .
2013-11-19 22:08:04 +04:00
*
2015-07-02 22:20:57 +03:00
* @ property { Number } [ collectionColumns = 0 ]
* If collectionMode is true , specifies how many columns the grid should have . Use 1 to make a line .
* If collectionLayout is 'vertical' , specifies how many rows instead . Ignored if collectionRows is not set to a falsy value .
*
2013-11-19 22:08:04 +04:00
* @ property { String } [ collectionLayout = 'horizontal' ]
2014-11-13 03:31:46 +03:00
* If collectionMode is true , specifies whether to arrange vertically or horizontally .
2013-05-30 22:46:54 +04:00
*
2013-11-19 22:08:04 +04:00
* @ property { Number } [ collectionTileSize = 800 ]
2014-11-24 22:59:06 +03:00
* If collectionMode is true , specifies the size , in viewport coordinates , for each TiledImage to fit into .
2014-11-13 03:31:46 +03:00
* The TiledImage will be centered within a square of the specified size .
2013-05-30 22:46:54 +04:00
*
2014-11-13 02:48:38 +03:00
* @ property { Number } [ collectionTileMargin = 80 ]
2014-11-24 22:59:06 +03:00
* If collectionMode is true , specifies the margin , in viewport coordinates , between each TiledImage .
2014-11-13 02:48:38 +03:00
*
2014-04-08 00:59:48 +04:00
* @ property { String | Boolean } [ crossOriginPolicy = false ]
2015-01-03 02:45:46 +03:00
* Valid values are 'Anonymous' , 'use-credentials' , and false . If false , canvas requests will
* not use CORS , and the canvas will be tainted .
*
* @ property { Boolean } [ ajaxWithCredentials = false ]
2016-10-22 00:28:12 +03:00
* Whether to set the withCredentials XHR flag for AJAX requests .
2015-01-03 03:07:11 +03:00
* Note that this can be overridden at the { @ link OpenSeadragon . TileSource } level .
2014-03-20 21:30:46 +04:00
*
2016-10-22 00:28:12 +03:00
* @ property { Boolean } [ loadTilesWithAjax = false ]
* Whether to load tile data using AJAX requests .
* Note that this can be overridden at the { @ link OpenSeadragon . TileSource } level .
*
2016-11-08 20:27:30 +03:00
* @ property { Object } [ ajaxHeaders = { } ]
2016-10-22 00:28:12 +03:00
* A set of headers to include when making AJAX requests for tile sources or tiles .
*
2013-11-18 22:06:38 +04:00
* /
2014-04-03 19:50:25 +04:00
/ * *
* Settings for gestures generated by a pointer device .
*
* @ typedef { Object } GestureSettings
* @ memberof OpenSeadragon
*
2014-04-03 21:06:12 +04:00
* @ property { Boolean } scrollToZoom
* Set to false to disable zooming on scroll gestures .
*
2014-04-03 19:50:25 +04:00
* @ property { Boolean } clickToZoom
* Set to false to disable zooming on click gestures .
*
2014-04-22 20:23:56 +04:00
* @ property { Boolean } dblClickToZoom
2014-04-22 20:41:29 +04:00
* Set to false to disable zooming on double - click gestures . Note : If set to true
* then clickToZoom should be set to false to prevent multiple zooms .
2014-04-22 20:23:56 +04:00
*
2014-04-16 06:19:47 +04:00
* @ property { Boolean } pinchToZoom
* Set to false to disable zooming on pinch gestures .
*
2014-04-03 19:50:25 +04:00
* @ property { Boolean } flickEnabled
* Set to false to disable the kinetic panning effect ( flick ) at the end of a drag gesture .
*
* @ property { Number } flickMinSpeed
2014-04-15 05:17:18 +04:00
* If flickEnabled is true , the minimum speed ( in pixels - per - second ) required to cause the kinetic panning effect ( flick ) at the end of a drag gesture .
2014-04-03 19:50:25 +04:00
*
* @ property { Number } flickMomentum
2014-04-15 05:17:18 +04:00
* If flickEnabled is true , a constant multiplied by the velocity to determine the distance of the kinetic panning effect ( flick ) at the end of a drag gesture .
2014-04-03 19:50:25 +04:00
* A larger value will make the flick feel "lighter" , while a smaller value will make the flick feel "heavier" .
2014-04-15 05:17:18 +04:00
* Note : springStiffness and animationTime also affect the "spring" used to stop the flick animation .
2014-04-03 19:50:25 +04:00
*
* /
2013-11-19 22:08:04 +04:00
/ * *
* The names for the image resources used for the image navigation buttons .
*
* @ typedef { Object } NavImages
* @ memberof OpenSeadragon
*
* @ property { Object } zoomIn - Images for the zoom - in button .
* @ property { String } zoomIn . REST
* @ property { String } zoomIn . GROUP
* @ property { String } zoomIn . HOVER
* @ property { String } zoomIn . DOWN
*
* @ property { Object } zoomOut - Images for the zoom - out button .
* @ property { String } zoomOut . REST
* @ property { String } zoomOut . GROUP
* @ property { String } zoomOut . HOVER
* @ property { String } zoomOut . DOWN
*
* @ property { Object } home - Images for the home button .
* @ property { String } home . REST
* @ property { String } home . GROUP
* @ property { String } home . HOVER
* @ property { String } home . DOWN
*
* @ property { Object } fullpage - Images for the full - page button .
* @ property { String } fullpage . REST
* @ property { String } fullpage . GROUP
* @ property { String } fullpage . HOVER
* @ property { String } fullpage . DOWN
*
2014-04-07 22:11:33 +04:00
* @ 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
*
2018-04-04 13:31:18 +03:00
* @ property { Object } flip - Images for the flip button .
* @ property { String } flip . REST
* @ property { String } flip . GROUP
* @ property { String } flip . HOVER
* @ property { String } flip . DOWN
*
2013-11-19 22:08:04 +04:00
* @ property { Object } previous - Images for the previous button .
* @ property { String } previous . REST
* @ property { String } previous . GROUP
* @ property { String } previous . HOVER
* @ property { String } previous . DOWN
*
* @ property { Object } next - Images for the next button .
* @ property { String } next . REST
* @ property { String } next . GROUP
* @ property { String } next . HOVER
* @ property { String } next . DOWN
*
* /
2016-07-25 21:27:53 +03:00
function OpenSeadragon ( options ) {
2012-03-01 17:38:15 +04:00
return new OpenSeadragon . Viewer ( options ) ;
2015-09-02 02:10:53 +03:00
}
2012-03-01 17:38:15 +04:00
( function ( $ ) {
2013-06-19 21:33:25 +04:00
2012-01-25 23:14:02 +04:00
2013-11-23 22:39:37 +04:00
/ * *
* The OpenSeadragon version .
*
2013-11-25 21:30:49 +04:00
* @ member { Object } OpenSeadragon . version
2013-11-23 22:39:37 +04:00
* @ property { String } versionStr - The version number as a string ( 'major.minor.revision' ) .
* @ property { Number } major - The major version number .
* @ property { Number } minor - The minor version number .
* @ property { Number } revision - The revision number .
2013-11-25 23:51:36 +04:00
* @ since 1.0 . 0
2013-11-23 22:39:37 +04:00
* /
2013-11-25 21:19:50 +04:00
$ . version = {
2013-11-25 21:30:49 +04:00
versionStr : '<%= osdVersion.versionStr %>' ,
2014-06-02 22:02:22 +04:00
major : parseInt ( '<%= osdVersion.major %>' , 10 ) ,
minor : parseInt ( '<%= osdVersion.minor %>' , 10 ) ,
revision : parseInt ( '<%= osdVersion.revision %>' , 10 )
2013-11-25 21:19:50 +04:00
} ;
2013-11-23 22:39:37 +04:00
2012-03-01 17:38:15 +04:00
/ * *
* Taken from jquery 1.6 . 1
* [ [ Class ] ] - > type pairs
* @ private
* /
2011-12-07 05:26:06 +04:00
var class2type = {
2013-11-25 21:19:50 +04:00
'[object Boolean]' : 'boolean' ,
'[object Number]' : 'number' ,
'[object String]' : 'string' ,
'[object Function]' : 'function' ,
'[object Array]' : 'array' ,
'[object Date]' : 'date' ,
'[object RegExp]' : 'regexp' ,
'[object Object]' : 'object'
} ,
// Save a reference to some core methods
toString = Object . prototype . toString ,
hasOwn = Object . prototype . hasOwnProperty ;
2011-12-07 05:26:06 +04:00
2012-03-01 17:38:15 +04:00
/ * *
* Taken from jQuery 1.6 . 1
2013-11-16 10:19:53 +04:00
* @ function isFunction
* @ memberof OpenSeadragon
* @ see { @ link http : //www.jquery.com/ jQuery}
2012-03-01 17:38:15 +04:00
* /
$ . isFunction = function ( obj ) {
return $ . type ( obj ) === "function" ;
} ;
2011-12-07 05:26:06 +04:00
2012-03-01 17:38:15 +04:00
/ * *
* Taken from jQuery 1.6 . 1
2013-11-16 10:19:53 +04:00
* @ function isArray
* @ memberof OpenSeadragon
* @ see { @ link http : //www.jquery.com/ jQuery}
2012-03-01 17:38:15 +04:00
* /
$ . isArray = Array . isArray || function ( obj ) {
return $ . type ( obj ) === "array" ;
} ;
2011-12-07 05:26:06 +04:00
2012-03-01 17:38:15 +04:00
/ * *
* A crude way of determining if an object is a window .
* Taken from jQuery 1.6 . 1
2013-11-16 10:19:53 +04:00
* @ function isWindow
* @ memberof OpenSeadragon
* @ see { @ link http : //www.jquery.com/ jQuery}
2012-03-01 17:38:15 +04:00
* /
$ . isWindow = function ( obj ) {
return obj && typeof obj === "object" && "setInterval" in obj ;
} ;
2011-12-07 05:26:06 +04:00
2012-03-01 17:38:15 +04:00
/ * *
* Taken from jQuery 1.6 . 1
2013-11-16 10:19:53 +04:00
* @ function type
* @ memberof OpenSeadragon
* @ see { @ link http : //www.jquery.com/ jQuery}
2012-03-01 17:38:15 +04:00
* /
$ . type = function ( obj ) {
2013-02-13 07:40:08 +04:00
return ( obj === null ) || ( obj === undefined ) ?
2012-03-01 17:38:15 +04:00
String ( obj ) :
class2type [ toString . call ( obj ) ] || "object" ;
} ;
2011-12-07 05:26:06 +04:00
2012-03-01 17:38:15 +04:00
/ * *
* Taken from jQuery 1.6 . 1
2013-11-16 10:19:53 +04:00
* @ function isPlainObject
* @ memberof OpenSeadragon
* @ see { @ link http : //www.jquery.com/ jQuery}
2012-03-01 17:38:15 +04:00
* /
$ . isPlainObject = function ( obj ) {
// Must be an Object.
// Because of IE, we also have to check the presence of the constructor property.
// Make sure that DOM nodes and window objects don't pass through, as well
if ( ! obj || OpenSeadragon . type ( obj ) !== "object" || obj . nodeType || $ . isWindow ( obj ) ) {
return false ;
}
2011-12-07 05:26:06 +04:00
2012-03-01 17:38:15 +04:00
// Not own constructor property must be Object
if ( obj . constructor &&
! hasOwn . call ( obj , "constructor" ) &&
! hasOwn . call ( obj . constructor . prototype , "isPrototypeOf" ) ) {
return false ;
2011-12-07 05:26:06 +04:00
}
2012-03-01 17:38:15 +04:00
// Own properties are enumerated firstly, so to speed up,
// if last one is own, then all properties are own.
2011-12-07 05:26:06 +04:00
2015-09-18 00:45:39 +03:00
var lastKey ;
for ( var key in obj ) {
lastKey = key ;
}
2011-12-06 07:50:25 +04:00
2015-09-18 00:45:39 +03:00
return lastKey === undefined || hasOwn . call ( obj , lastKey ) ;
2012-03-01 17:38:15 +04:00
} ;
2012-01-25 23:14:02 +04:00
2011-12-06 07:50:25 +04:00
2012-01-25 23:14:02 +04:00
/ * *
2012-03-01 17:38:15 +04:00
* Taken from jQuery 1.6 . 1
2013-11-16 10:19:53 +04:00
* @ function isEmptyObject
* @ memberof OpenSeadragon
* @ see { @ link http : //www.jquery.com/ jQuery}
2012-01-25 23:14:02 +04:00
* /
2012-03-01 17:38:15 +04:00
$ . isEmptyObject = function ( obj ) {
for ( var name in obj ) {
return false ;
}
return true ;
2011-12-06 07:50:25 +04:00
} ;
2012-03-01 17:38:15 +04:00
2016-03-22 22:50:48 +03:00
/ * *
* Shim around Object . freeze . Does nothing if Object . freeze is not supported .
* @ param { Object } obj The object to freeze .
* @ return { Object } obj The frozen object .
* /
$ . freezeObject = function ( obj ) {
if ( Object . freeze ) {
$ . freezeObject = Object . freeze ;
} else {
$ . freezeObject = function ( obj ) {
return obj ;
} ;
}
return $ . freezeObject ( obj ) ;
} ;
2012-03-01 17:38:15 +04:00
2013-11-02 00:02:28 +04:00
/ * *
* True if the browser supports the HTML5 canvas element
2013-11-16 10:19:53 +04:00
* @ member { Boolean } supportsCanvas
* @ memberof OpenSeadragon
2013-11-02 00:02:28 +04:00
* /
2013-11-12 01:33:27 +04:00
$ . supportsCanvas = ( function ( ) {
var canvasElement = document . createElement ( 'canvas' ) ;
return ! ! ( $ . isFunction ( canvasElement . getContext ) &&
canvasElement . getContext ( '2d' ) ) ;
} ( ) ) ;
2013-10-23 23:58:36 +04:00
2015-11-03 02:35:11 +03:00
/ * *
* Test whether the submitted canvas is tainted or not .
* @ argument { Canvas } canvas The canvas to test .
* @ returns { Boolean } True if the canvas is tainted .
* /
$ . isCanvasTainted = function ( canvas ) {
var isTainted = false ;
try {
// We test if the canvas is tainted by retrieving data from it.
// An exception will be raised if the canvas is tainted.
2017-01-08 17:52:57 +03:00
canvas . getContext ( '2d' ) . getImageData ( 0 , 0 , 1 , 1 ) ;
2015-11-03 02:35:11 +03:00
} catch ( e ) {
isTainted = true ;
}
return isTainted ;
} ;
2015-01-29 19:19:49 +03:00
/ * *
2017-05-19 20:06:48 +03:00
* A ratio comparing the device screen 's pixel density to the canvas' s backing store pixel density ,
* clamped to a minimum of 1. Defaults to 1 if canvas isn ' t supported by the browser .
2015-01-29 23:14:41 +03:00
* @ member { Number } pixelDensityRatio
* @ memberof OpenSeadragon
2015-01-29 19:19:49 +03:00
* /
$ . pixelDensityRatio = ( function ( ) {
if ( $ . supportsCanvas ) {
var context = document . createElement ( 'canvas' ) . getContext ( '2d' ) ;
var devicePixelRatio = window . devicePixelRatio || 1 ;
var backingStoreRatio = context . webkitBackingStorePixelRatio ||
context . mozBackingStorePixelRatio ||
context . msBackingStorePixelRatio ||
context . oBackingStorePixelRatio ||
context . backingStorePixelRatio || 1 ;
2017-05-19 00:17:02 +03:00
return Math . max ( devicePixelRatio , 1 ) / backingStoreRatio ;
2015-01-29 19:19:49 +03:00
} else {
return 1 ;
}
} ( ) ) ;
2013-10-23 23:58:36 +04:00
2012-03-01 17:38:15 +04:00
} ( OpenSeadragon ) ) ;
/ * *
* This closure defines all static methods available to the OpenSeadragon
* namespace . Many , if not most , are taked directly from jQuery for use
2013-06-19 21:33:25 +04:00
* to simplify and reduce common programming patterns . More static methods
2012-03-01 17:38:15 +04:00
* from jQuery may eventually make their way into this though we are
2013-05-10 08:57:49 +04:00
* attempting to avoid an explicit dependency on jQuery only because
* OpenSeadragon is a broadly useful code base and would be made less broad
* by requiring jQuery fully .
2012-03-01 17:38:15 +04:00
*
2013-06-19 21:33:25 +04:00
* Some static methods have also been refactored from the original OpenSeadragon
2012-03-01 17:38:15 +04:00
* project .
* /
( function ( $ ) {
2012-01-25 23:14:02 +04:00
/ * *
2012-03-01 17:38:15 +04:00
* Taken from jQuery 1.6 . 1
2013-11-16 10:19:53 +04:00
* @ function extend
* @ memberof OpenSeadragon
* @ see { @ link http : //www.jquery.com/ jQuery}
2012-01-25 23:14:02 +04:00
* /
2011-12-07 05:26:06 +04:00
$ . extend = function ( ) {
2013-06-19 21:33:25 +04:00
var options ,
name ,
src ,
copy ,
copyIsArray ,
2012-01-25 23:14:02 +04:00
clone ,
target = arguments [ 0 ] || { } ,
length = arguments . length ,
deep = false ,
i = 1 ;
2011-12-07 05:26:06 +04:00
// Handle a deep copy situation
if ( typeof target === "boolean" ) {
2012-01-25 23:14:02 +04:00
deep = target ;
target = arguments [ 1 ] || { } ;
2011-12-07 05:26:06 +04:00
// skip the boolean and the target
i = 2 ;
}
// Handle case when target is a string or something (possible in deep copy)
2012-01-25 23:14:02 +04:00
if ( typeof target !== "object" && ! OpenSeadragon . isFunction ( target ) ) {
2011-12-07 05:26:06 +04:00
target = { } ;
}
// extend jQuery itself if only one argument is passed
if ( length === i ) {
target = this ;
-- i ;
}
for ( ; i < length ; i ++ ) {
// Only deal with non-null/undefined values
2013-02-13 07:40:08 +04:00
options = arguments [ i ] ;
if ( options !== null || options !== undefined ) {
2011-12-07 05:26:06 +04:00
// Extend the base object
for ( name in options ) {
src = target [ name ] ;
copy = options [ name ] ;
// Prevent never-ending loop
if ( target === copy ) {
continue ;
}
// Recurse if we're merging plain objects or arrays
2012-01-25 23:14:02 +04:00
if ( deep && copy && ( OpenSeadragon . isPlainObject ( copy ) || ( copyIsArray = OpenSeadragon . isArray ( copy ) ) ) ) {
2011-12-07 05:26:06 +04:00
if ( copyIsArray ) {
copyIsArray = false ;
2012-01-25 23:14:02 +04:00
clone = src && OpenSeadragon . isArray ( src ) ? src : [ ] ;
2011-12-07 05:26:06 +04:00
} else {
2012-01-25 23:14:02 +04:00
clone = src && OpenSeadragon . isPlainObject ( src ) ? src : { } ;
2011-12-07 05:26:06 +04:00
}
// Never move original objects, clone them
target [ name ] = OpenSeadragon . extend ( deep , clone , copy ) ;
// Don't bring in undefined values
} else if ( copy !== undefined ) {
target [ name ] = copy ;
}
}
}
}
// Return the modified object
return target ;
} ;
2013-06-19 21:33:25 +04:00
2016-06-17 09:32:50 +03:00
var isIOSDevice = function ( ) {
2016-06-17 20:09:19 +03:00
if ( typeof navigator !== 'object' ) {
return false ;
}
var userAgent = navigator . userAgent ;
if ( typeof userAgent !== 'string' ) {
return false ;
}
return userAgent . indexOf ( 'iPhone' ) !== - 1 ||
userAgent . indexOf ( 'iPad' ) !== - 1 ||
userAgent . indexOf ( 'iPod' ) !== - 1 ;
2016-06-17 09:32:50 +03:00
} ;
2012-01-18 03:30:41 +04:00
2013-11-16 10:19:53 +04:00
$ . extend ( $ , /** @lends OpenSeadragon */ {
2012-03-01 17:38:15 +04:00
/ * *
2013-11-25 20:48:44 +04:00
* The default values for the optional settings documented at { @ link OpenSeadragon . Options } .
2012-03-01 17:38:15 +04:00
* @ static
2013-11-25 20:48:44 +04:00
* @ type { Object }
2012-03-01 17:38:15 +04:00
* /
DEFAULT _SETTINGS : {
2012-04-03 11:08:27 +04:00
//DATA SOURCE DETAILS
xmlPath : null ,
2013-06-19 21:33:25 +04:00
tileSources : null ,
2012-04-03 11:08:27 +04:00
tileHost : null ,
2013-10-10 23:05:05 +04:00
initialPage : 0 ,
2014-04-08 00:59:48 +04:00
crossOriginPolicy : false ,
2015-01-03 02:45:46 +03:00
ajaxWithCredentials : false ,
2016-10-22 00:28:12 +03:00
loadTilesWithAjax : false ,
2016-11-08 20:27:30 +03:00
ajaxHeaders : { } ,
2014-04-09 20:06:46 +04:00
2013-02-06 06:26:40 +04:00
//PAN AND ZOOM SETTINGS AND CONSTRAINTS
2012-04-03 11:08:27 +04:00
panHorizontal : true ,
panVertical : true ,
2013-02-13 07:40:08 +04:00
constrainDuringPan : false ,
2013-02-06 06:26:40 +04:00
wrapHorizontal : false ,
wrapVertical : false ,
2013-03-14 16:12:01 +04:00
visibilityRatio : 0.5 , //-> how much of the viewer can be negative space
2013-05-30 21:07:34 +04:00
minPixelRatio : 0.5 , //->closer to 0 draws tiles meant for a higher zoom at this zoom
2013-02-06 06:26:40 +04:00
defaultZoomLevel : 0 ,
minZoomLevel : null ,
2013-06-19 21:33:25 +04:00
maxZoomLevel : null ,
2014-09-12 21:33:48 +04:00
homeFillsViewer : false ,
2013-02-06 06:26:40 +04:00
//UI RESPONSIVENESS AND FEEL
2012-08-29 22:46:34 +04:00
clickTimeThreshold : 300 ,
2012-04-03 11:08:27 +04:00
clickDistThreshold : 5 ,
2014-04-22 20:23:56 +04:00
dblClickTimeThreshold : 300 ,
dblClickDistThreshold : 20 ,
2014-04-21 08:25:29 +04:00
springStiffness : 6.5 ,
2014-04-03 19:50:25 +04:00
animationTime : 1.2 ,
2017-01-08 17:52:57 +03:00
gestureSettingsMouse : {
scrollToZoom : true ,
clickToZoom : true ,
dblClickToZoom : false ,
pinchToZoom : false ,
2018-03-16 13:29:16 +03:00
zoomToRefPoint : true ,
2017-01-08 17:52:57 +03:00
flickEnabled : false ,
flickMinSpeed : 120 ,
flickMomentum : 0.25 ,
pinchRotate : false
} ,
gestureSettingsTouch : {
scrollToZoom : false ,
clickToZoom : false ,
dblClickToZoom : true ,
pinchToZoom : true ,
2018-03-16 13:29:16 +03:00
zoomToRefPoint : true ,
2017-01-08 17:52:57 +03:00
flickEnabled : true ,
flickMinSpeed : 120 ,
flickMomentum : 0.25 ,
pinchRotate : false
} ,
gestureSettingsPen : {
scrollToZoom : false ,
clickToZoom : true ,
dblClickToZoom : false ,
pinchToZoom : false ,
2018-03-16 13:29:16 +03:00
zoomToRefPoint : true ,
2017-01-08 17:52:57 +03:00
flickEnabled : false ,
flickMinSpeed : 120 ,
flickMomentum : 0.25 ,
pinchRotate : false
} ,
gestureSettingsUnknown : {
scrollToZoom : false ,
clickToZoom : false ,
dblClickToZoom : true ,
pinchToZoom : true ,
2018-03-16 13:29:16 +03:00
zoomToRefPoint : true ,
2017-01-08 17:52:57 +03:00
flickEnabled : true ,
flickMinSpeed : 120 ,
flickMomentum : 0.25 ,
pinchRotate : false
} ,
2013-03-06 16:43:12 +04:00
zoomPerClick : 2 ,
2012-04-03 11:08:27 +04:00
zoomPerScroll : 1.2 ,
2013-03-06 16:43:12 +04:00
zoomPerSecond : 1.0 ,
2013-03-14 16:12:01 +04:00
blendTime : 0 ,
2013-02-06 06:26:40 +04:00
alwaysBlend : false ,
2013-02-27 08:23:48 +04:00
autoHideControls : true ,
immediateRender : false ,
2013-03-14 16:12:01 +04:00
minZoomImageRatio : 0.9 , //-> closer to 0 allows zoom out to infinity
maxZoomPixelRatio : 1.1 , //-> higher allows 'over zoom' into pixels
2015-11-04 18:04:50 +03:00
smoothTileEdgesMinZoom : 1.1 , //-> higher than maxZoomPixelRatio disables it
2016-06-17 09:32:50 +03:00
iOSDevice : isIOSDevice ( ) ,
2013-10-23 23:58:36 +04:00
pixelsPerWheelLine : 40 ,
2017-12-14 19:10:10 +03:00
pixelsPerArrowPress : 40 ,
2013-11-25 22:27:03 +04:00
autoResize : true ,
2015-06-25 23:14:05 +03:00
preserveImageSizeOnResize : false , // requires autoResize=true
2015-10-29 02:07:51 +03:00
minScrollDeltaTime : 50 ,
2013-01-31 01:51:37 +04:00
2013-02-06 06:26:40 +04:00
//DEFAULT CONTROL SETTINGS
2013-12-07 10:48:49 +04:00
showSequenceControl : true , //SEQUENCE
sequenceControlAnchor : null , //SEQUENCE
preserveViewport : false , //SEQUENCE
2015-01-09 05:21:16 +03:00
preserveOverlays : false , //SEQUENCE
2014-04-07 22:11:33 +04:00
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
2018-04-09 17:09:29 +03:00
showFlipControl : false , //FLIP
2013-12-07 10:48:49 +04:00
controlsFadeDelay : 2000 , //ZOOM/HOME/FULL/SEQUENCE
controlsFadeLength : 1500 , //ZOOM/HOME/FULL/SEQUENCE
mouseNavEnabled : true , //GENERAL MOUSE INTERACTIVITY
2013-06-19 21:33:25 +04:00
2013-02-06 06:26:40 +04:00
//VIEWPORT NAVIGATOR SETTINGS
2018-04-09 17:09:29 +03:00
showNavigator : false ,
Enhanced Navigator Resizability (#280, #296)
New navigator options:
* @property {Boolean} [showNavigator=false]
* Set to true to make the navigator minimap appear.
*
* @property {Boolean} [navigatorId=navigator-GENERATED DATE]
* The ID of a div to hold the navigator minimap.
* If an ID is specified, the navigatorPosition, navigatorSizeRatio,
navigatorMaintainSizeRatio, and navigatorTop|Left|Height|Width options
will be ignored.
* If an ID is not specified, a div element will be generated and
placed on top of the main image.
*
* @property {String} [navigatorPosition='TOP_RIGHT']
* Valid values are 'TOP_LEFT', 'TOP_RIGHT', 'BOTTOM_LEFT',
'BOTTOM_RIGHT', or 'ABSOLUTE'.<br>
* If 'ABSOLUTE' is specified, then navigatorTop|Left|Height|Width
determines the size and position of the navigator minimap in the viewer,
and navigatorSizeRatio and navigatorMaintainSizeRatio are ignored.<br>
* For 'TOP_LEFT', 'TOP_RIGHT', 'BOTTOM_LEFT', and 'BOTTOM_RIGHT',
the navigatorSizeRatio or navigatorHeight|Width values determine the
size of the navigator minimap.
*
* @property {Number} [navigatorSizeRatio=0.2]
* Ratio of navigator size to viewer size. Ignored if
navigatorHeight|Width are specified.
*
* @property {Boolean} [navigatorMaintainSizeRatio=false]
* If true, the navigator minimap is resized (using
navigatorSizeRatio) when the viewer size changes.
*
* @property {Number|String} [navigatorTop=null]
* Specifies the location of the navigator minimap (see
navigatorPosition).
*
* @property {Number|String} [navigatorLeft=null]
* Specifies the location of the navigator minimap (see
navigatorPosition).
*
* @property {Number|String} [navigatorHeight=null]
* Specifies the size of the navigator minimap (see
navigatorPosition).
* If specified, navigatorSizeRatio and navigatorMaintainSizeRatio
are ignored.
*
* @property {Number|String} [navigatorWidth=null]
* Specifies the size of the navigator minimap (see
navigatorPosition).
* If specified, navigatorSizeRatio and navigatorMaintainSizeRatio
are ignored.
Fixes #280 and #296
2013-12-13 21:23:56 +04:00
navigatorId : null ,
navigatorPosition : null ,
navigatorSizeRatio : 0.2 ,
navigatorMaintainSizeRatio : false ,
navigatorTop : null ,
navigatorLeft : null ,
navigatorHeight : null ,
navigatorWidth : null ,
2013-12-15 02:45:11 +04:00
navigatorAutoResize : true ,
2016-05-06 04:00:01 +03:00
navigatorAutoFade : true ,
2014-08-12 18:27:16 +04:00
navigatorRotate : true ,
2012-06-05 15:52:00 +04:00
2013-08-14 01:39:22 +04:00
// INITIAL ROTATION
2015-04-11 20:01:09 +03:00
degrees : 0 ,
2013-08-14 01:39:22 +04:00
2018-04-04 13:31:18 +03:00
// INITIAL FLIP STATE
2018-04-06 14:02:45 +03:00
flipped : false ,
2018-04-04 13:31:18 +03:00
2013-12-09 18:26:36 +04:00
// APPEARANCE
2015-04-11 20:01:09 +03:00
opacity : 1 ,
2016-11-03 03:45:33 +03:00
preload : false ,
2016-01-20 01:17:52 +03:00
compositeOperation : null ,
2015-04-09 14:44:55 +03:00
placeholderFillStyle : null ,
2013-12-09 18:26:36 +04:00
2013-02-06 06:26:40 +04:00
//REFERENCE STRIP SETTINGS
2013-06-19 21:33:25 +04:00
showReferenceStrip : false ,
2012-08-29 22:46:34 +04:00
referenceStripScroll : 'horizontal' ,
referenceStripElement : null ,
referenceStripHeight : null ,
referenceStripWidth : null ,
referenceStripPosition : 'BOTTOM_LEFT' ,
2012-09-07 16:55:19 +04:00
referenceStripSizeRatio : 0.2 ,
2012-08-29 22:46:34 +04:00
//COLLECTION VISUALIZATION SETTINGS
2013-01-24 08:00:11 +04:00
collectionRows : 3 , //or columns depending on layout
2015-07-02 22:20:57 +03:00
collectionColumns : 0 , //columns in horizontal layout, rows in vertical layout
2013-01-24 08:00:11 +04:00
collectionLayout : 'horizontal' , //vertical
collectionMode : false ,
collectionTileSize : 800 ,
2014-11-13 02:48:38 +03:00
collectionTileMargin : 80 ,
2012-08-29 22:46:34 +04:00
2012-04-03 11:08:27 +04:00
//PERFORMANCE SETTINGS
imageLoaderLimit : 0 ,
maxImageCacheCount : 200 ,
2013-03-06 14:51:31 +04:00
timeout : 30000 ,
2013-11-01 21:19:47 +04:00
useCanvas : true , // Use canvas element for drawing if available
2012-04-03 11:08:27 +04:00
//INTERFACE RESOURCE SETTINGS
2012-09-28 22:02:22 +04:00
prefixUrl : "/images/" ,
2012-03-01 17:38:15 +04:00
navImages : {
zoomIn : {
2012-09-28 22:02:22 +04:00
REST : 'zoomin_rest.png' ,
GROUP : 'zoomin_grouphover.png' ,
HOVER : 'zoomin_hover.png' ,
DOWN : 'zoomin_pressed.png'
2012-03-01 17:38:15 +04:00
} ,
zoomOut : {
2012-09-28 22:02:22 +04:00
REST : 'zoomout_rest.png' ,
GROUP : 'zoomout_grouphover.png' ,
HOVER : 'zoomout_hover.png' ,
DOWN : 'zoomout_pressed.png'
2012-03-01 17:38:15 +04:00
} ,
home : {
2012-09-28 22:02:22 +04:00
REST : 'home_rest.png' ,
GROUP : 'home_grouphover.png' ,
HOVER : 'home_hover.png' ,
DOWN : 'home_pressed.png'
2012-03-01 17:38:15 +04:00
} ,
fullpage : {
2012-09-28 22:02:22 +04:00
REST : 'fullpage_rest.png' ,
GROUP : 'fullpage_grouphover.png' ,
HOVER : 'fullpage_hover.png' ,
DOWN : 'fullpage_pressed.png'
2012-04-03 11:08:27 +04:00
} ,
2014-03-04 01:45:30 +04:00
rotateleft : {
REST : 'rotateleft_rest.png' ,
GROUP : 'rotateleft_grouphover.png' ,
HOVER : 'rotateleft_hover.png' ,
DOWN : 'rotateleft_pressed.png'
} ,
rotateright : {
REST : 'rotateright_rest.png' ,
GROUP : 'rotateright_grouphover.png' ,
HOVER : 'rotateright_hover.png' ,
DOWN : 'rotateright_pressed.png'
} ,
2018-04-06 13:52:10 +03:00
flip : { // Flip icon designed by Yaroslav Samoylov from the Noun Project and modified by Nelson Campos ncampos@criteriamarathon.com, https://thenounproject.com/term/flip/136289/
2018-04-04 13:31:18 +03:00
REST : 'flip_rest.png' ,
GROUP : 'flip_grouphover.png' ,
HOVER : 'flip_hover.png' ,
DOWN : 'flip_pressed.png'
} ,
2012-04-03 11:08:27 +04:00
previous : {
2012-09-28 22:02:22 +04:00
REST : 'previous_rest.png' ,
GROUP : 'previous_grouphover.png' ,
HOVER : 'previous_hover.png' ,
DOWN : 'previous_pressed.png'
2012-04-03 11:08:27 +04:00
} ,
next : {
2012-09-28 22:02:22 +04:00
REST : 'next_rest.png' ,
GROUP : 'next_grouphover.png' ,
HOVER : 'next_hover.png' ,
DOWN : 'next_pressed.png'
2012-01-18 03:30:41 +04:00
}
2013-01-24 08:00:11 +04:00
} ,
//DEVELOPER SETTINGS
debugMode : false ,
2017-08-01 00:36:25 +03:00
debugGridColor : [ '#437AB2' , '#1B9E77' , '#D95F02' , '#7570B3' , '#E7298A' , '#66A61E' , '#E6AB02' , '#A6761D' , '#666666' ]
2012-03-01 17:38:15 +04:00
} ,
2012-01-18 03:30:41 +04:00
2012-03-01 17:38:15 +04:00
/ * *
* TODO : get rid of this . I can 't see how it' s required at all . Looks
* like an early legacy code artifact .
* @ static
* @ ignore
* /
SIGNAL : "----seadragon----" ,
2012-01-18 03:30:41 +04:00
2012-03-01 17:38:15 +04:00
/ * *
2013-11-25 20:48:44 +04:00
* Returns a function which invokes the method as if it were a method belonging to the object .
2012-03-01 17:38:15 +04:00
* @ function
2013-06-19 21:33:25 +04:00
* @ param { Object } object
2012-03-01 17:38:15 +04:00
* @ param { Function } method
2013-11-25 20:48:44 +04:00
* @ returns { Function }
2012-03-01 17:38:15 +04:00
* /
delegate : function ( object , method ) {
2013-02-13 07:40:08 +04:00
return function ( ) {
var args = arguments ;
if ( args === undefined ) {
args = [ ] ;
}
return method . apply ( object , args ) ;
2012-03-01 17:38:15 +04:00
} ;
} ,
2013-06-19 21:33:25 +04:00
2012-03-01 17:38:15 +04:00
/ * *
2013-11-22 00:19:07 +04:00
* An enumeration of Browser vendors .
2012-03-01 17:38:15 +04:00
* @ static
2013-11-22 00:19:07 +04:00
* @ type { Object }
* @ property { Number } UNKNOWN
* @ property { Number } IE
* @ property { Number } FIREFOX
* @ property { Number } SAFARI
* @ property { Number } CHROME
* @ property { Number } OPERA
2012-03-01 17:38:15 +04:00
* /
BROWSERS : {
UNKNOWN : 0 ,
IE : 1 ,
FIREFOX : 2 ,
SAFARI : 3 ,
CHROME : 4 ,
OPERA : 5
} ,
2012-01-18 03:30:41 +04:00
2012-01-25 23:14:02 +04:00
/ * *
* Returns a DOM Element for the given id or element .
* @ function
* @ param { String | Element } element Accepts an id or element .
* @ returns { Element } The element with the given id , null , or the element itself .
* /
2013-06-19 21:33:25 +04:00
getElement : function ( element ) {
2012-02-10 07:16:09 +04:00
if ( typeof ( element ) == "string" ) {
2012-01-18 03:30:41 +04:00
element = document . getElementById ( element ) ;
}
return element ;
} ,
2012-03-01 17:38:15 +04:00
2012-01-25 23:14:02 +04:00
/ * *
2012-02-01 00:59:09 +04:00
* Determines the position of the upper - left corner of the element .
2012-01-25 23:14:02 +04:00
* @ function
2012-02-01 00:59:09 +04:00
* @ param { Element | String } element - the elemenet we want the position for .
2013-11-18 22:30:48 +04:00
* @ returns { OpenSeadragon . Point } - the position of the upper left corner of the element .
2012-01-25 23:14:02 +04:00
* /
2012-01-18 03:30:41 +04:00
getElementPosition : function ( element ) {
2012-01-19 05:15:54 +04:00
var result = new $ . Point ( ) ,
isFixed ,
offsetParent ;
2012-01-18 03:30:41 +04:00
2012-01-19 05:15:54 +04:00
element = $ . getElement ( element ) ;
isFixed = $ . getElementStyle ( element ) . position == "fixed" ;
2012-02-01 00:59:09 +04:00
offsetParent = getOffsetParent ( element , isFixed ) ;
2012-01-18 03:30:41 +04:00
while ( offsetParent ) {
result . x += element . offsetLeft ;
result . y += element . offsetTop ;
if ( isFixed ) {
result = result . plus ( $ . getPageScroll ( ) ) ;
}
element = offsetParent ;
isFixed = $ . getElementStyle ( element ) . position == "fixed" ;
2012-02-01 00:59:09 +04:00
offsetParent = getOffsetParent ( element , isFixed ) ;
2012-01-18 03:30:41 +04:00
}
return result ;
} ,
2012-03-01 17:38:15 +04:00
2013-09-06 04:20:17 +04:00
/ * *
* Determines the position of the upper - left corner of the element adjusted for current page and / or element scroll .
* @ function
* @ param { Element | String } element - the element we want the position for .
2013-11-18 22:30:48 +04:00
* @ returns { OpenSeadragon . Point } - the position of the upper left corner of the element adjusted for current page and / or element scroll .
2013-09-06 04:20:17 +04:00
* /
getElementOffset : function ( element ) {
2013-09-10 01:27:58 +04:00
element = $ . getElement ( element ) ;
2013-09-06 04:20:17 +04:00
var doc = element && element . ownerDocument ,
docElement ,
win ,
boundingRect = { top : 0 , left : 0 } ;
if ( ! doc ) {
return new $ . Point ( ) ;
}
docElement = doc . documentElement ;
if ( typeof element . getBoundingClientRect !== typeof undefined ) {
boundingRect = element . getBoundingClientRect ( ) ;
}
win = ( doc == doc . window ) ?
doc :
( doc . nodeType === 9 ) ?
doc . defaultView || doc . parentWindow :
false ;
return new $ . Point (
boundingRect . left + ( win . pageXOffset || docElement . scrollLeft ) - ( docElement . clientLeft || 0 ) ,
boundingRect . top + ( win . pageYOffset || docElement . scrollTop ) - ( docElement . clientTop || 0 )
) ;
} ,
2012-01-25 23:14:02 +04:00
/ * *
2012-02-01 00:59:09 +04:00
* Determines the height and width of the given element .
2012-01-25 23:14:02 +04:00
* @ function
* @ param { Element | String } element
2013-11-18 22:30:48 +04:00
* @ returns { OpenSeadragon . Point }
2012-01-25 23:14:02 +04:00
* /
2012-01-18 03:30:41 +04:00
getElementSize : function ( element ) {
2012-01-19 05:15:54 +04:00
element = $ . getElement ( element ) ;
2012-01-18 03:30:41 +04:00
return new $ . Point (
2013-06-19 21:33:25 +04:00
element . clientWidth ,
2012-01-18 03:30:41 +04:00
element . clientHeight
) ;
} ,
2012-03-01 17:38:15 +04:00
2012-01-25 23:14:02 +04:00
/ * *
2012-02-01 00:59:09 +04:00
* Returns the CSSStyle object for the given element .
2012-01-25 23:14:02 +04:00
* @ function
* @ param { Element | String } element
* @ returns { CSSStyle }
* /
2013-06-19 21:33:25 +04:00
getElementStyle :
document . documentElement . currentStyle ?
2012-04-11 01:02:24 +04:00
function ( element ) {
element = $ . getElement ( element ) ;
2012-01-18 03:30:41 +04:00
return element . currentStyle ;
2013-06-19 21:33:25 +04:00
} :
2012-04-11 01:02:24 +04:00
function ( element ) {
element = $ . getElement ( element ) ;
2012-01-18 03:30:41 +04:00
return window . getComputedStyle ( element , "" ) ;
2012-04-11 01:02:24 +04:00
} ,
2012-01-18 03:30:41 +04:00
2016-03-30 18:16:29 +03:00
/ * *
* Returns the property with the correct vendor prefix appended .
* @ param { String } property the property name
* @ returns { String } the property with the correct prefix or null if not
* supported .
* /
getCssPropertyWithVendorPrefix : function ( property ) {
var memo = { } ;
$ . getCssPropertyWithVendorPrefix = function ( property ) {
if ( memo [ property ] !== undefined ) {
return memo [ property ] ;
}
var style = document . createElement ( 'div' ) . style ;
var result = null ;
if ( style [ property ] !== undefined ) {
result = property ;
} else {
var prefixes = [ 'Webkit' , 'Moz' , 'MS' , 'O' ,
'webkit' , 'moz' , 'ms' , 'o' ] ;
var suffix = $ . capitalizeFirstLetter ( property ) ;
for ( var i = 0 ; i < prefixes . length ; i ++ ) {
var prop = prefixes [ i ] + suffix ;
if ( style [ prop ] !== undefined ) {
result = prop ;
break ;
}
}
}
memo [ property ] = result ;
return result ;
} ;
return $ . getCssPropertyWithVendorPrefix ( property ) ;
} ,
/ * *
* Capitalizes the first letter of a string
* @ param { String } string
* @ returns { String } The string with the first letter capitalized
* /
capitalizeFirstLetter : function ( string ) {
return string . charAt ( 0 ) . toUpperCase ( ) + string . slice ( 1 ) ;
} ,
2012-03-01 17:38:15 +04:00
2016-08-17 16:43:08 +03:00
/ * *
* Compute the modulo of a number but makes sure to always return
* a positive value .
* @ param { Number } number the number to computes the modulo of
* @ param { Number } modulo the modulo
* @ returns { Number } the result of the modulo of number
* /
positiveModulo : function ( number , modulo ) {
var result = number % modulo ;
if ( result < 0 ) {
result += modulo ;
}
return result ;
} ,
2014-03-10 22:49:51 +04:00
/ * *
* Determines if a point is within the bounding rectangle of the given element ( hit - test ) .
* @ function
* @ param { Element | String } element
* @ param { OpenSeadragon . Point } point
* @ returns { Boolean }
* /
pointInElement : function ( element , point ) {
element = $ . getElement ( element ) ;
var offset = $ . getElementOffset ( element ) ,
size = $ . getElementSize ( element ) ;
return point . x >= offset . x && point . x < offset . x + size . x && point . y < offset . y + size . y && point . y >= offset . y ;
} ,
2012-01-25 23:14:02 +04:00
/ * *
2013-06-19 21:33:25 +04:00
* Gets the latest event , really only useful internally since its
2013-11-25 20:48:44 +04:00
* specific to IE behavior .
2012-01-25 23:14:02 +04:00
* @ function
* @ param { Event } [ event ]
* @ returns { Event }
2013-11-22 00:19:07 +04:00
* @ deprecated For internal use only
2013-11-25 20:48:44 +04:00
* @ private
2012-01-25 23:14:02 +04:00
* /
2012-01-18 03:30:41 +04:00
getEvent : function ( event ) {
2012-04-11 01:02:24 +04:00
if ( event ) {
2013-06-19 01:55:19 +04:00
$ . getEvent = function ( event ) {
2012-04-11 01:02:24 +04:00
return event ;
} ;
} else {
2013-06-19 01:55:19 +04:00
$ . getEvent = function ( ) {
2012-04-11 01:02:24 +04:00
return window . event ;
} ;
}
return $ . getEvent ( event ) ;
2012-01-18 03:30:41 +04:00
} ,
2012-03-01 17:38:15 +04:00
2012-01-25 23:14:02 +04:00
/ * *
2012-02-01 00:59:09 +04:00
* Gets the position of the mouse on the screen for a given event .
2012-01-25 23:14:02 +04:00
* @ function
* @ param { Event } [ event ]
2013-11-18 22:30:48 +04:00
* @ returns { OpenSeadragon . Point }
2012-01-25 23:14:02 +04:00
* /
2012-01-18 03:30:41 +04:00
getMousePosition : function ( event ) {
2012-01-19 05:15:54 +04:00
2012-01-18 03:30:41 +04:00
if ( typeof ( event . pageX ) == "number" ) {
2012-04-11 01:02:24 +04:00
$ . getMousePosition = function ( event ) {
var result = new $ . Point ( ) ;
event = $ . getEvent ( event ) ;
result . x = event . pageX ;
result . y = event . pageY ;
return result ;
} ;
2012-01-18 03:30:41 +04:00
} else if ( typeof ( event . clientX ) == "number" ) {
2012-04-11 01:02:24 +04:00
$ . getMousePosition = function ( event ) {
var result = new $ . Point ( ) ;
event = $ . getEvent ( event ) ;
2013-06-19 21:33:25 +04:00
result . x =
event . clientX +
document . body . scrollLeft +
2012-04-11 01:02:24 +04:00
document . documentElement . scrollLeft ;
2013-06-19 21:33:25 +04:00
result . y =
event . clientY +
document . body . scrollTop +
2012-04-11 01:02:24 +04:00
document . documentElement . scrollTop ;
return result ;
} ;
2012-01-18 03:30:41 +04:00
} else {
throw new Error (
"Unknown event mouse position, no known technique."
) ;
}
2012-01-18 08:13:29 +04:00
2012-04-11 01:02:24 +04:00
return $ . getMousePosition ( event ) ;
2012-01-18 03:30:41 +04:00
} ,
2012-03-01 17:38:15 +04:00
2012-01-25 23:14:02 +04:00
/ * *
2013-11-02 01:37:19 +04:00
* Determines the page ' s current scroll position .
2012-01-25 23:14:02 +04:00
* @ function
2013-11-18 22:30:48 +04:00
* @ returns { OpenSeadragon . Point }
2012-01-25 23:14:02 +04:00
* /
2012-01-18 03:30:41 +04:00
getPageScroll : function ( ) {
2012-04-11 01:02:24 +04:00
var docElement = document . documentElement || { } ,
body = document . body || { } ;
2012-01-18 03:30:41 +04:00
if ( typeof ( window . pageXOffset ) == "number" ) {
2012-04-11 01:02:24 +04:00
$ . getPageScroll = function ( ) {
return new $ . Point (
window . pageXOffset ,
window . pageYOffset
) ;
} ;
2012-01-18 03:30:41 +04:00
} else if ( body . scrollLeft || body . scrollTop ) {
2012-04-11 01:02:24 +04:00
$ . getPageScroll = function ( ) {
return new $ . Point (
document . body . scrollLeft ,
document . body . scrollTop
) ;
} ;
2012-02-02 01:56:04 +04:00
} else if ( docElement . scrollLeft || docElement . scrollTop ) {
2012-04-11 01:02:24 +04:00
$ . getPageScroll = function ( ) {
return new $ . Point (
document . documentElement . scrollLeft ,
document . documentElement . scrollTop
) ;
} ;
2012-04-12 21:20:24 +04:00
} else {
2013-11-01 06:19:22 +04:00
// We can't reassign the function yet, as there was no scroll.
2017-01-08 17:52:57 +03:00
return new $ . Point ( 0 , 0 ) ;
2012-01-18 03:30:41 +04:00
}
2012-04-11 01:02:24 +04:00
return $ . getPageScroll ( ) ;
2012-01-18 03:30:41 +04:00
} ,
2013-11-01 06:19:22 +04:00
/ * *
* Set the page scroll position .
* @ function
2013-11-18 22:30:48 +04:00
* @ returns { OpenSeadragon . Point }
2013-11-01 06:19:22 +04:00
* /
setPageScroll : function ( scroll ) {
if ( typeof ( window . scrollTo ) !== "undefined" ) {
$ . setPageScroll = function ( scroll ) {
window . scrollTo ( scroll . x , scroll . y ) ;
} ;
} else {
2013-11-02 01:37:19 +04:00
var originalScroll = $ . getPageScroll ( ) ;
if ( originalScroll . x === scroll . x &&
originalScroll . y === scroll . y ) {
2013-11-01 06:19:22 +04:00
// We are already correctly positioned and there
// is no way to detect the correct method.
return ;
}
document . body . scrollLeft = scroll . x ;
document . body . scrollTop = scroll . y ;
2013-11-02 01:37:19 +04:00
var currentScroll = $ . getPageScroll ( ) ;
if ( currentScroll . x !== originalScroll . x &&
currentScroll . y !== originalScroll . y ) {
2013-11-01 06:19:22 +04:00
$ . setPageScroll = function ( scroll ) {
document . body . scrollLeft = scroll . x ;
document . body . scrollTop = scroll . y ;
} ;
return ;
}
document . documentElement . scrollLeft = scroll . x ;
document . documentElement . scrollTop = scroll . y ;
currentScroll = $ . getPageScroll ( ) ;
2013-11-02 01:37:19 +04:00
if ( currentScroll . x !== originalScroll . x &&
currentScroll . y !== originalScroll . y ) {
2013-11-01 06:19:22 +04:00
$ . setPageScroll = function ( scroll ) {
document . documentElement . scrollLeft = scroll . x ;
document . documentElement . scrollTop = scroll . y ;
} ;
return ;
}
// We can't find anything working, so we do nothing.
$ . setPageScroll = function ( scroll ) {
} ;
}
return $ . setPageScroll ( scroll ) ;
} ,
2012-03-01 17:38:15 +04:00
2012-01-25 23:14:02 +04:00
/ * *
2012-02-01 00:59:09 +04:00
* Determines the size of the browsers window .
2012-01-25 23:14:02 +04:00
* @ function
2013-11-18 22:30:48 +04:00
* @ returns { OpenSeadragon . Point }
2012-01-25 23:14:02 +04:00
* /
2012-01-18 03:30:41 +04:00
getWindowSize : function ( ) {
2012-04-11 01:02:24 +04:00
var docElement = document . documentElement || { } ,
2012-01-18 03:30:41 +04:00
body = document . body || { } ;
if ( typeof ( window . innerWidth ) == 'number' ) {
2012-04-11 01:02:24 +04:00
$ . getWindowSize = function ( ) {
return new $ . Point (
window . innerWidth ,
window . innerHeight
) ;
2013-02-13 07:40:08 +04:00
} ;
2012-02-02 01:56:04 +04:00
} else if ( docElement . clientWidth || docElement . clientHeight ) {
2012-04-11 01:02:24 +04:00
$ . getWindowSize = function ( ) {
return new $ . Point (
document . documentElement . clientWidth ,
document . documentElement . clientHeight
) ;
2013-02-13 07:40:08 +04:00
} ;
2012-01-18 03:30:41 +04:00
} else if ( body . clientWidth || body . clientHeight ) {
2012-04-11 01:02:24 +04:00
$ . getWindowSize = function ( ) {
return new $ . Point (
document . body . clientWidth ,
document . body . clientHeight
) ;
2013-02-13 07:40:08 +04:00
} ;
2012-01-18 03:30:41 +04:00
} else {
throw new Error ( "Unknown window size, no known technique." ) ;
}
2012-04-11 01:02:24 +04:00
return $ . getWindowSize ( ) ;
2012-01-18 03:30:41 +04:00
} ,
2012-01-25 23:14:02 +04:00
/ * *
2012-02-01 00:59:09 +04:00
* Wraps the given element in a nest of divs so that the element can
2013-06-28 23:52:48 +04:00
* be easily centered using CSS tables
2012-01-25 23:14:02 +04:00
* @ function
* @ param { Element | String } element
2013-06-28 23:52:48 +04:00
* @ returns { Element } outermost wrapper element
2012-01-25 23:14:02 +04:00
* /
2012-01-18 03:30:41 +04:00
makeCenteredNode : function ( element ) {
2013-06-28 23:52:48 +04:00
// Convert a possible ID to an actual HTMLElement
2012-01-19 05:15:54 +04:00
element = $ . getElement ( element ) ;
2013-06-28 23:52:48 +04:00
/ *
CSS tables require you to have a display : table / row / cell hierarchy so we need to create
three nested wrapper divs :
* /
var wrappers = [
$ . makeNeutralElement ( 'div' ) ,
$ . makeNeutralElement ( 'div' ) ,
$ . makeNeutralElement ( 'div' )
] ;
// It feels like we should be able to pass style dicts to makeNeutralElement:
$ . extend ( wrappers [ 0 ] . style , {
display : "table" ,
height : "100%" ,
width : "100%"
} ) ;
$ . extend ( wrappers [ 1 ] . style , {
display : "table-row"
} ) ;
$ . extend ( wrappers [ 2 ] . style , {
display : "table-cell" ,
verticalAlign : "middle" ,
textAlign : "center"
} ) ;
wrappers [ 0 ] . appendChild ( wrappers [ 1 ] ) ;
wrappers [ 1 ] . appendChild ( wrappers [ 2 ] ) ;
wrappers [ 2 ] . appendChild ( element ) ;
return wrappers [ 0 ] ;
2012-01-18 03:30:41 +04:00
} ,
2012-03-01 17:38:15 +04:00
2012-01-25 23:14:02 +04:00
/ * *
2012-02-01 00:59:09 +04:00
* Creates an easily positionable element of the given type that therefor
* serves as an excellent container element .
2012-01-25 23:14:02 +04:00
* @ function
* @ param { String } tagName
* @ returns { Element }
* /
2012-01-18 03:30:41 +04:00
makeNeutralElement : function ( tagName ) {
var element = document . createElement ( tagName ) ,
style = element . style ;
style . background = "transparent none" ;
style . border = "none" ;
style . margin = "0px" ;
style . padding = "0px" ;
style . position = "static" ;
return element ;
} ,
2012-03-01 17:38:15 +04:00
2013-06-19 22:16:45 +04:00
/ * *
* Returns the current milliseconds , using Date . now ( ) if available
* @ function
* /
now : function ( ) {
2017-01-08 17:52:57 +03:00
if ( Date . now ) {
$ . now = Date . now ;
} else {
$ . now = function ( ) {
return new Date ( ) . getTime ( ) ;
} ;
}
2013-07-10 20:31:22 +04:00
2017-01-08 17:52:57 +03:00
return $ . now ( ) ;
2013-06-19 22:16:45 +04:00
} ,
2012-01-25 23:14:02 +04:00
/ * *
2012-02-01 00:59:09 +04:00
* Ensures an image is loaded correctly to support alpha transparency .
2013-06-19 21:33:25 +04:00
* Generally only IE has issues doing this correctly for formats like
2012-02-01 00:59:09 +04:00
* png .
2012-01-25 23:14:02 +04:00
* @ function
* @ param { String } src
* @ returns { Element }
* /
2012-01-18 03:30:41 +04:00
makeTransparentImage : function ( src ) {
2012-04-11 01:02:24 +04:00
$ . makeTransparentImage = function ( src ) {
var img = $ . makeNeutralElement ( "img" ) ;
2013-06-19 21:33:25 +04:00
2012-04-11 01:02:24 +04:00
img . src = src ;
2013-06-19 21:33:25 +04:00
2012-04-11 01:02:24 +04:00
return img ;
} ;
2012-01-18 03:30:41 +04:00
2012-04-11 01:02:24 +04:00
if ( $ . Browser . vendor == $ . BROWSERS . IE && $ . Browser . version < 7 ) {
2012-01-18 03:30:41 +04:00
2012-04-11 01:02:24 +04:00
$ . makeTransparentImage = function ( src ) {
var img = $ . makeNeutralElement ( "img" ) ,
element = null ;
2012-01-18 03:30:41 +04:00
2012-04-11 01:02:24 +04:00
element = $ . makeNeutralElement ( "span" ) ;
element . style . display = "inline-block" ;
2012-01-18 03:30:41 +04:00
2012-04-11 01:02:24 +04:00
img . onload = function ( ) {
element . style . width = element . style . width || img . width + "px" ;
element . style . height = element . style . height || img . height + "px" ;
2012-01-18 03:30:41 +04:00
2012-04-11 01:02:24 +04:00
img . onload = null ;
img = null ; // to prevent memory leaks in IE
} ;
2012-01-18 03:30:41 +04:00
2012-04-11 01:02:24 +04:00
img . src = src ;
element . style . filter =
"progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" +
2013-06-19 21:33:25 +04:00
src +
2012-04-11 01:02:24 +04:00
"', sizingMethod='scale')" ;
2012-01-18 03:30:41 +04:00
2012-04-11 01:02:24 +04:00
return element ;
} ;
2012-01-18 03:30:41 +04:00
2013-06-19 21:33:25 +04:00
}
2012-04-11 01:02:24 +04:00
return $ . makeTransparentImage ( src ) ;
2012-01-18 03:30:41 +04:00
} ,
2012-03-01 17:38:15 +04:00
2012-01-25 23:14:02 +04:00
/ * *
2012-02-01 00:59:09 +04:00
* Sets the opacity of the specified element .
2012-01-25 23:14:02 +04:00
* @ function
* @ param { Element | String } element
* @ param { Number } opacity
* @ param { Boolean } [ usesAlpha ]
* /
2012-01-18 03:30:41 +04:00
setElementOpacity : function ( element , opacity , usesAlpha ) {
2013-06-07 02:34:09 +04:00
var ieOpacity ,
2012-01-18 03:30:41 +04:00
ieFilter ;
2012-01-19 05:15:54 +04:00
element = $ . getElement ( element ) ;
2012-01-18 03:30:41 +04:00
if ( usesAlpha && ! $ . Browser . alpha ) {
opacity = Math . round ( opacity ) ;
}
2013-06-07 02:34:09 +04:00
if ( $ . Browser . opacity ) {
element . style . opacity = opacity < 1 ? opacity : "" ;
2012-01-18 03:30:41 +04:00
} else {
2013-06-07 02:34:09 +04:00
if ( opacity < 1 ) {
ieOpacity = Math . round ( 100 * opacity ) ;
ieFilter = "alpha(opacity=" + ieOpacity + ")" ;
element . style . filter = ieFilter ;
2012-01-18 03:30:41 +04:00
} else {
2013-06-07 02:34:09 +04:00
element . style . filter = "" ;
2012-01-18 03:30:41 +04:00
}
}
} ,
2012-03-01 17:38:15 +04:00
2014-08-06 03:57:54 +04:00
/ * *
* Sets the specified element 's touch-action style attribute to ' none ' .
* @ function
* @ param { Element | String } element
* /
setElementTouchActionNone : function ( element ) {
element = $ . getElement ( element ) ;
if ( typeof element . style . touchAction !== 'undefined' ) {
element . style . touchAction = 'none' ;
} else if ( typeof element . style . msTouchAction !== 'undefined' ) {
element . style . msTouchAction = 'none' ;
}
} ,
2013-05-13 06:53:41 +04:00
/ * *
* Add the specified CSS class to the element if not present .
* @ function
* @ param { Element | String } element
* @ param { String } className
* /
addClass : function ( element , className ) {
element = $ . getElement ( element ) ;
2017-01-08 17:52:57 +03:00
if ( ! element . className ) {
2013-05-13 06:53:41 +04:00
element . className = className ;
} else if ( ( ' ' + element . className + ' ' ) .
indexOf ( ' ' + className + ' ' ) === - 1 ) {
element . className += ' ' + className ;
}
} ,
2013-12-11 04:22:15 +04:00
/ * *
* Find the first index at which an element is found in an array or - 1
* if not present .
*
* Code taken and adapted from
* https : //developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf#Compatibility
*
* @ function
* @ param { Array } array The array from which to find the element
* @ param { Object } searchElement The element to find
* @ param { Number } [ fromIndex = 0 ] Index to start research .
* @ returns { Number } The index of the element in the array .
* /
indexOf : function ( array , searchElement , fromIndex ) {
if ( Array . prototype . indexOf ) {
2014-01-06 04:20:45 +04:00
this . indexOf = function ( array , searchElement , fromIndex ) {
return array . indexOf ( searchElement , fromIndex ) ;
} ;
2013-12-11 04:22:15 +04:00
} else {
this . indexOf = function ( array , searchElement , fromIndex ) {
var i ,
pivot = ( fromIndex ) ? fromIndex : 0 ,
length ;
if ( ! array ) {
throw new TypeError ( ) ;
}
length = array . length ;
if ( length === 0 || pivot >= length ) {
return - 1 ;
}
if ( pivot < 0 ) {
pivot = length - Math . abs ( pivot ) ;
}
for ( i = pivot ; i < length ; i ++ ) {
if ( array [ i ] === searchElement ) {
return i ;
}
}
return - 1 ;
} ;
}
return this . indexOf ( array , searchElement , fromIndex ) ;
} ,
2013-05-13 06:53:41 +04:00
/ * *
* Remove the specified CSS class from the element .
* @ function
* @ param { Element | String } element
* @ param { String } className
* /
removeClass : function ( element , className ) {
var oldClasses ,
newClasses = [ ] ,
i ;
element = $ . getElement ( element ) ;
oldClasses = element . className . split ( /\s+/ ) ;
for ( i = 0 ; i < oldClasses . length ; i ++ ) {
if ( oldClasses [ i ] && oldClasses [ i ] !== className ) {
newClasses . push ( oldClasses [ i ] ) ;
}
}
element . className = newClasses . join ( ' ' ) ;
} ,
2012-01-25 23:14:02 +04:00
/ * *
2012-02-01 00:59:09 +04:00
* Adds an event listener for the given element , eventName and handler .
2012-01-25 23:14:02 +04:00
* @ function
* @ param { Element | String } element
* @ param { String } eventName
* @ param { Function } handler
* @ param { Boolean } [ useCapture ]
* /
2013-11-12 01:33:27 +04:00
addEvent : ( function ( ) {
if ( window . addEventListener ) {
return function ( element , eventName , handler , useCapture ) {
element = $ . getElement ( element ) ;
element . addEventListener ( eventName , handler , useCapture ) ;
} ;
} else if ( window . attachEvent ) {
return function ( element , eventName , handler , useCapture ) {
element = $ . getElement ( element ) ;
element . attachEvent ( 'on' + eventName , handler ) ;
} ;
} else {
throw new Error ( "No known event model." ) ;
}
} ( ) ) ,
2012-01-18 03:30:41 +04:00
2012-03-01 17:38:15 +04:00
2012-01-25 23:14:02 +04:00
/ * *
2013-06-19 21:33:25 +04:00
* Remove a given event listener for the given element , event type and
2012-02-01 00:59:09 +04:00
* handler .
2012-01-25 23:14:02 +04:00
* @ function
* @ param { Element | String } element
* @ param { String } eventName
* @ param { Function } handler
* @ param { Boolean } [ useCapture ]
* /
2013-11-12 01:33:27 +04:00
removeEvent : ( function ( ) {
if ( window . removeEventListener ) {
return function ( element , eventName , handler , useCapture ) {
element = $ . getElement ( element ) ;
element . removeEventListener ( eventName , handler , useCapture ) ;
} ;
} else if ( window . detachEvent ) {
return function ( element , eventName , handler , useCapture ) {
element = $ . getElement ( element ) ;
element . detachEvent ( 'on' + eventName , handler ) ;
} ;
} else {
throw new Error ( "No known event model." ) ;
}
} ( ) ) ,
2012-01-18 03:30:41 +04:00
2012-03-01 17:38:15 +04:00
2012-01-25 23:14:02 +04:00
/ * *
2012-02-01 00:59:09 +04:00
* Cancels the default browser behavior had the event propagated all
* the way up the DOM to the window object .
2012-01-25 23:14:02 +04:00
* @ function
* @ param { Event } [ event ]
* /
2012-01-18 03:30:41 +04:00
cancelEvent : function ( event ) {
2012-01-19 05:15:54 +04:00
event = $ . getEvent ( event ) ;
2012-01-18 03:30:41 +04:00
if ( event . preventDefault ) {
2012-04-11 01:02:24 +04:00
$ . cancelEvent = function ( event ) {
// W3C for preventing default
event . preventDefault ( ) ;
2013-02-13 07:40:08 +04:00
} ;
2012-04-11 01:02:24 +04:00
} else {
$ . cancelEvent = function ( event ) {
event = $ . getEvent ( event ) ;
// legacy for preventing default
event . cancel = true ;
// IE for preventing default
event . returnValue = false ;
} ;
2012-01-18 03:30:41 +04:00
}
2012-04-11 01:02:24 +04:00
$ . cancelEvent ( event ) ;
2012-01-18 03:30:41 +04:00
} ,
2012-03-01 17:38:15 +04:00
2012-01-25 23:14:02 +04:00
/ * *
2012-02-01 00:59:09 +04:00
* Stops the propagation of the event up the DOM .
2012-01-25 23:14:02 +04:00
* @ function
* @ param { Event } [ event ]
* /
2012-01-18 03:30:41 +04:00
stopEvent : function ( event ) {
2012-01-19 05:15:54 +04:00
event = $ . getEvent ( event ) ;
2012-01-18 03:30:41 +04:00
2013-06-19 21:33:25 +04:00
if ( event . stopPropagation ) {
2012-04-11 01:02:24 +04:00
// W3C for stopping propagation
$ . stopEvent = function ( event ) {
event . stopPropagation ( ) ;
} ;
2013-06-19 21:33:25 +04:00
} else {
2012-04-11 01:02:24 +04:00
// IE for stopping propagation
$ . stopEvent = function ( event ) {
event = $ . getEvent ( event ) ;
event . cancelBubble = true ;
} ;
2013-06-19 21:33:25 +04:00
2012-01-18 03:30:41 +04:00
}
2012-04-11 01:02:24 +04:00
$ . stopEvent ( event ) ;
2012-01-18 03:30:41 +04:00
} ,
2012-03-01 17:38:15 +04:00
2012-01-25 23:14:02 +04:00
/ * *
2013-06-19 21:33:25 +04:00
* Similar to OpenSeadragon . delegate , but it does not immediately call
2012-02-01 00:59:09 +04:00
* the method on the object , returning a function which can be called
* repeatedly to delegate the method . It also allows additonal arguments
* to be passed during construction which will be added during each
* invocation , and each invocation can add additional arguments as well .
2013-06-19 21:33:25 +04:00
*
2012-01-25 23:14:02 +04:00
* @ function
* @ param { Object } object
* @ param { Function } method
2013-06-19 21:33:25 +04:00
* @ param [ args ] any additional arguments are passed as arguments to the
2012-02-01 00:59:09 +04:00
* created callback
2012-01-25 23:14:02 +04:00
* @ returns { Function }
* /
2012-01-18 03:30:41 +04:00
createCallback : function ( object , method ) {
//TODO: This pattern is painful to use and debug. It's much cleaner
// to use pinning plus anonymous functions. Get rid of this
// pattern!
var initialArgs = [ ] ,
i ;
for ( i = 2 ; i < arguments . length ; i ++ ) {
initialArgs . push ( arguments [ i ] ) ;
}
return function ( ) {
var args = initialArgs . concat ( [ ] ) ,
i ;
for ( i = 0 ; i < arguments . length ; i ++ ) {
args . push ( arguments [ i ] ) ;
}
return method . apply ( object , args ) ;
} ;
} ,
2012-03-01 17:38:15 +04:00
2012-01-25 23:14:02 +04:00
/ * *
2012-02-01 00:59:09 +04:00
* Retreives the value of a url parameter from the window . location string .
2012-01-25 23:14:02 +04:00
* @ function
* @ param { String } key
* @ returns { String } The value of the url parameter or null if no param matches .
* /
2012-01-18 03:30:41 +04:00
getUrlParameter : function ( key ) {
2017-01-08 17:52:57 +03:00
// eslint-disable-next-line no-use-before-define
2012-01-18 03:30:41 +04:00
var value = URLPARAMS [ key ] ;
return value ? value : null ;
} ,
2014-04-15 20:55:32 +04:00
/ * *
* Retrieves the protocol used by the url . The url can either be absolute
* or relative .
* @ function
2014-04-19 00:59:47 +04:00
* @ private
2014-04-15 20:55:32 +04:00
* @ param { String } url The url to retrieve the protocol from .
* @ return { String } The protocol ( http : , https : , file : , ftp : ... )
* /
getUrlProtocol : function ( url ) {
var match = url . match ( /^([a-z]+:)\/\//i ) ;
if ( match === null ) {
// Relative URL, retrive the protocol from window.location
return window . location . protocol ;
}
return match [ 1 ] . toLowerCase ( ) ;
} ,
2012-03-01 17:38:15 +04:00
2014-04-18 00:13:26 +04:00
/ * *
* Create an XHR object
2014-04-19 00:59:47 +04:00
* @ private
2014-04-18 00:13:26 +04:00
* @ param { type } [ local ] If set to true , the XHR will be file : protocol
* compatible if possible ( but may raise a warning in the browser ) .
* @ returns { XMLHttpRequest }
* /
createAjaxRequest : function ( local ) {
2014-04-18 01:20:04 +04:00
// IE11 does not support window.ActiveXObject so we just try to
// create one to see if it is supported.
// See: http://msdn.microsoft.com/en-us/library/ie/dn423948%28v=vs.85%29.aspx
var supportActiveX ;
try {
2013-06-19 02:05:00 +04:00
/* global ActiveXObject:true */
2014-04-18 01:20:04 +04:00
supportActiveX = ! ! new ActiveXObject ( "Microsoft.XMLHTTP" ) ;
} catch ( e ) {
supportActiveX = false ;
2012-01-18 03:30:41 +04:00
}
2014-04-18 01:20:04 +04:00
if ( supportActiveX ) {
2014-04-18 00:13:26 +04:00
if ( window . XMLHttpRequest ) {
$ . createAjaxRequest = function ( local ) {
if ( local ) {
return new ActiveXObject ( "Microsoft.XMLHTTP" ) ;
}
return new XMLHttpRequest ( ) ;
} ;
} else {
$ . createAjaxRequest = function ( ) {
return new ActiveXObject ( "Microsoft.XMLHTTP" ) ;
} ;
}
} else if ( window . XMLHttpRequest ) {
$ . createAjaxRequest = function ( ) {
2013-05-21 21:39:10 +04:00
return new XMLHttpRequest ( ) ;
} ;
2014-04-18 00:13:26 +04:00
} else {
2012-01-18 03:30:41 +04:00
throw new Error ( "Browser doesn't support XMLHttpRequest." ) ;
}
2014-04-18 00:13:26 +04:00
return $ . createAjaxRequest ( local ) ;
2012-04-11 01:02:24 +04:00
} ,
2013-05-21 21:39:10 +04:00
2012-04-11 01:02:24 +04:00
/ * *
* Makes an AJAX request .
2015-01-03 03:07:11 +03:00
* @ param { Object } options
* @ param { String } options . url - the url to request
* @ param { Function } options . success - a function to call on a successful response
* @ param { Function } options . error - a function to call on when an error occurs
2016-10-22 00:28:12 +03:00
* @ param { Object } options . headers - headers to add to the AJAX request
* @ param { String } options . responseType - the response type of the the AJAX request
2015-01-03 03:07:11 +03:00
* @ param { Boolean } [ options . withCredentials = false ] - whether to set the XHR ' s withCredentials
2012-04-11 01:02:24 +04:00
* @ throws { Error }
2016-10-22 00:28:12 +03:00
* @ returns { XMLHttpRequest }
2012-04-11 01:02:24 +04:00
* /
2013-06-27 00:27:52 +04:00
makeAjaxRequest : function ( url , onSuccess , onError ) {
2015-01-03 02:45:46 +03:00
var withCredentials ;
2016-10-22 00:28:12 +03:00
var headers ;
var responseType ;
2015-01-03 02:45:46 +03:00
2015-01-03 03:07:11 +03:00
// Note that our preferred API is that you pass in a single object; the named
// arguments are for legacy support.
2015-01-03 02:45:46 +03:00
if ( $ . isPlainObject ( url ) ) {
onSuccess = url . success ;
onError = url . error ;
withCredentials = url . withCredentials ;
2016-10-22 00:28:12 +03:00
headers = url . headers ;
responseType = url . responseType || null ;
2015-01-03 02:45:46 +03:00
url = url . url ;
}
2014-04-18 00:13:26 +04:00
var protocol = $ . getUrlProtocol ( url ) ;
var request = $ . createAjaxRequest ( protocol === "file:" ) ;
2013-06-27 00:27:52 +04:00
2013-06-28 22:54:44 +04:00
if ( ! $ . isFunction ( onSuccess ) ) {
2013-06-28 00:02:17 +04:00
throw new Error ( "makeAjaxRequest requires a success callback" ) ;
}
2013-06-27 00:27:52 +04:00
request . onreadystatechange = function ( ) {
// 4 = DONE (https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#Properties)
2013-06-27 01:07:37 +04:00
if ( request . readyState == 4 ) {
2013-06-27 00:27:52 +04:00
request . onreadystatechange = function ( ) { } ;
2016-11-08 20:27:30 +03:00
// With protocols other than http/https, a successful request status is in
// the 200's on Firefox and 0 on other browsers
2016-10-22 00:28:12 +03:00
if ( ( request . status >= 200 && request . status < 300 ) ||
2015-02-11 02:28:05 +03:00
( request . status === 0 &&
protocol !== "http:" &&
protocol !== "https:" ) ) {
2013-06-27 00:27:52 +04:00
onSuccess ( request ) ;
} else {
2014-04-15 20:55:32 +04:00
$ . console . log ( "AJAX request returned %d: %s" , request . status , url ) ;
2013-06-27 01:17:50 +04:00
2013-06-28 22:54:44 +04:00
if ( $ . isFunction ( onError ) ) {
2013-06-27 01:17:50 +04:00
onError ( request ) ;
}
2012-01-18 03:30:41 +04:00
}
2013-06-27 00:27:52 +04:00
}
} ;
2012-01-18 03:30:41 +04:00
try {
2013-06-27 00:27:52 +04:00
request . open ( "GET" , url , true ) ;
2016-06-22 14:51:14 +03:00
2016-10-22 00:28:12 +03:00
if ( responseType ) {
request . responseType = responseType ;
}
if ( headers ) {
2017-01-23 21:44:39 +03:00
for ( var headerName in headers ) {
if ( headers . hasOwnProperty ( headerName ) && headers [ headerName ] ) {
2016-12-19 08:39:32 +03:00
request . setRequestHeader ( headerName , headers [ headerName ] ) ;
}
2017-01-23 21:44:39 +03:00
}
2016-10-22 00:28:12 +03:00
}
2016-06-22 14:51:14 +03:00
if ( withCredentials ) {
request . withCredentials = true ;
}
2016-10-22 00:28:12 +03:00
request . send ( null ) ;
2012-01-18 03:30:41 +04:00
} catch ( e ) {
2013-08-30 00:13:13 +04:00
var msg = e . message ;
/ *
IE < 10 does not support CORS and an XHR request to a different origin will fail as soon
as send ( ) is called . This is particularly easy to miss during development and appear in
production if you use a CDN or domain sharding and the security policy is likely to break
exception handlers since any attempt to access a property of the request object will
raise an access denied TypeError inside the catch block .
To be friendlier , we ' ll check for this specific error and add a documentation pointer
to point developers in the right direction . We test the exception number because IE ' s
error messages are localized .
* /
var oldIE = $ . Browser . vendor == $ . BROWSERS . IE && $ . Browser . version < 10 ;
if ( oldIE && typeof ( e . number ) != "undefined" && e . number == - 2147024891 ) {
msg += "\nSee http://msdn.microsoft.com/en-us/library/ms537505(v=vs.85).aspx#xdomain" ;
}
$ . console . log ( "%s while making AJAX request: %s" , e . name , msg ) ;
2012-01-18 03:30:41 +04:00
2013-06-25 22:12:29 +04:00
request . onreadystatechange = function ( ) { } ;
2012-01-18 03:30:41 +04:00
2015-07-29 18:16:19 +03:00
if ( window . XDomainRequest ) { // IE9 or IE8 might as well try to use XDomainRequest
var xdr = new XDomainRequest ( ) ;
if ( xdr ) {
xdr . onload = function ( e ) {
if ( $ . isFunction ( onSuccess ) ) {
onSuccess ( { // Faking an xhr object
responseText : xdr . responseText ,
status : 200 , // XDomainRequest doesn't support status codes, so we just fake one! :/
statusText : 'OK'
} ) ;
}
2015-07-29 19:19:45 +03:00
} ;
2015-07-29 18:16:19 +03:00
xdr . onerror = function ( e ) {
2017-01-08 17:52:57 +03:00
if ( $ . isFunction ( onError ) ) {
2015-07-29 18:16:19 +03:00
onError ( { // Faking an xhr object
responseText : xdr . responseText ,
status : 444 , // 444 No Response
statusText : 'An error happened. Due to an XDomainRequest deficiency we can not extract any information about this error. Upgrade your browser.'
} ) ;
}
2015-07-29 19:19:45 +03:00
} ;
2015-07-29 18:16:19 +03:00
try {
xdr . open ( 'GET' , url ) ;
xdr . send ( ) ;
2015-07-29 19:27:23 +03:00
} catch ( e2 ) {
2015-07-29 18:16:19 +03:00
if ( $ . isFunction ( onError ) ) {
onError ( request , e ) ;
}
}
}
} else {
if ( $ . isFunction ( onError ) ) {
onError ( request , e ) ;
}
2013-06-27 01:17:50 +04:00
}
2012-06-05 15:52:00 +04:00
}
2016-10-22 00:28:12 +03:00
return request ;
2012-01-18 03:30:41 +04:00
} ,
2012-03-07 07:20:00 +04:00
/ * *
* Taken from jQuery 1.6 . 1
2012-04-11 01:02:24 +04:00
* @ function
* @ param { Object } options
* @ param { String } options . url
* @ param { Function } options . callback
* @ param { String } [ options . param = 'callback' ] The name of the url parameter
2012-03-07 07:20:00 +04:00
* to request the jsonp provider with .
2012-04-11 01:02:24 +04:00
* @ param { String } [ options . callbackName = ] The name of the callback to
2012-03-07 07:20:00 +04:00
* request the jsonp provider with .
* /
jsonp : function ( options ) {
var script ,
url = options . url ,
2013-06-19 21:33:25 +04:00
head = document . head ||
document . getElementsByTagName ( "head" ) [ 0 ] ||
2012-03-07 07:20:00 +04:00
document . documentElement ,
2013-06-21 00:31:04 +04:00
jsonpCallback = options . callbackName || 'openseadragon' + $ . now ( ) ,
2012-03-07 07:20:00 +04:00
previous = window [ jsonpCallback ] ,
replace = "$1" + jsonpCallback + "$2" ,
callbackParam = options . param || 'callback' ,
callback = options . callback ;
url = url . replace ( /(\=)\?(&|$)|\?\?/i , replace ) ;
// Add callback manually
url += ( /\?/ . test ( url ) ? "&" : "?" ) + callbackParam + "=" + jsonpCallback ;
// Install callback
window [ jsonpCallback ] = function ( response ) {
if ( ! previous ) {
2012-04-12 21:20:24 +04:00
try {
delete window [ jsonpCallback ] ;
} catch ( e ) {
//swallow
}
2012-03-07 07:20:00 +04:00
} else {
window [ jsonpCallback ] = previous ;
}
if ( callback && $ . isFunction ( callback ) ) {
callback ( response ) ;
}
} ;
script = document . createElement ( "script" ) ;
2012-06-05 15:52:00 +04:00
//TODO: having an issue with async info requests
if ( undefined !== options . async || false !== options . async ) {
script . async = "async" ;
}
2012-03-07 07:20:00 +04:00
if ( options . scriptCharset ) {
script . charset = options . scriptCharset ;
}
script . src = url ;
// Attach handlers for all browsers
script . onload = script . onreadystatechange = function ( _ , isAbort ) {
if ( isAbort || ! script . readyState || /loaded|complete/ . test ( script . readyState ) ) {
// Handle memory leak in IE
script . onload = script . onreadystatechange = null ;
// Remove the script
if ( head && script . parentNode ) {
head . removeChild ( script ) ;
}
// Dereference the script
script = undefined ;
}
} ;
// Use insertBefore instead of appendChild to circumvent an IE6 bug.
// This arises when a base node is used (#2709 and #4378).
head . insertBefore ( script , head . firstChild ) ;
2013-06-19 21:33:25 +04:00
2012-03-07 07:20:00 +04:00
} ,
2012-01-25 23:14:02 +04:00
/ * *
2013-03-26 17:25:56 +04:00
* Fully deprecated . Will throw an error .
2012-01-25 23:14:02 +04:00
* @ function
2013-11-22 00:19:07 +04:00
* @ deprecated use { @ link OpenSeadragon . Viewer # open }
2012-01-25 23:14:02 +04:00
* /
2013-06-19 01:55:19 +04:00
createFromDZI : function ( ) {
2013-03-26 17:25:56 +04:00
throw "OpenSeadragon.createFromDZI is deprecated, use Viewer.open." ;
2012-06-05 15:52:00 +04:00
} ,
/ * *
* Parses an XML string into a DOM Document .
* @ function
* @ param { String } string
* @ returns { Document }
* /
parseXml : function ( string ) {
2014-04-21 17:23:17 +04:00
if ( window . DOMParser ) {
2012-06-05 15:52:00 +04:00
2014-04-21 17:23:17 +04:00
$ . parseXml = function ( string ) {
var xmlDoc = null ,
parser ;
2012-06-05 15:52:00 +04:00
2014-04-21 17:23:17 +04:00
parser = new DOMParser ( ) ;
xmlDoc = parser . parseFromString ( string , "text/xml" ) ;
2012-06-05 15:52:00 +04:00
return xmlDoc ;
} ;
2014-04-21 17:23:17 +04:00
} else if ( window . ActiveXObject ) {
2013-06-19 21:33:25 +04:00
2014-04-21 17:23:17 +04:00
$ . parseXml = function ( string ) {
var xmlDoc = null ;
2012-06-05 15:52:00 +04:00
2014-04-21 17:23:17 +04:00
xmlDoc = new ActiveXObject ( "Microsoft.XMLDOM" ) ;
xmlDoc . async = false ;
xmlDoc . loadXML ( string ) ;
2012-06-05 15:52:00 +04:00
return xmlDoc ;
} ;
} else {
throw new Error ( "Browser doesn't support XML DOM." ) ;
}
return $ . parseXml ( string ) ;
} ,
2015-07-30 23:21:59 +03:00
/ * *
* Parses a JSON string into a Javascript object .
* @ function
* @ param { String } string
* @ returns { Object }
* /
parseJSON : function ( string ) {
if ( window . JSON && window . JSON . parse ) {
$ . parseJSON = window . JSON . parse ;
} else {
// Should only be used by IE8 in non standards mode
$ . parseJSON = function ( string ) {
/*jshint evil:true*/
2017-01-08 17:52:57 +03:00
//eslint-disable-next-line no-eval
2015-07-30 23:21:59 +03:00
return eval ( '(' + string + ')' ) ;
} ;
}
return $ . parseJSON ( string ) ;
} ,
2012-06-05 15:52:00 +04:00
/ * *
* Reports whether the image format is supported for tiling in this
* version .
* @ function
* @ param { String } [ extension ]
* @ returns { Boolean }
* /
imageFormatSupported : function ( extension ) {
extension = extension ? extension : "" ;
2017-01-08 17:52:57 +03:00
// eslint-disable-next-line no-use-before-define
2012-06-05 15:52:00 +04:00
return ! ! FILEFORMATS [ extension . toLowerCase ( ) ] ;
2012-01-18 03:30:41 +04:00
}
2012-02-01 00:59:09 +04:00
2012-01-18 03:30:41 +04:00
} ) ;
2012-03-01 17:38:15 +04:00
/ * *
2013-11-25 20:48:44 +04:00
* The current browser vendor , version , and related information regarding detected features .
2013-11-16 10:19:53 +04:00
* @ member { Object } Browser
* @ memberof OpenSeadragon
2012-03-01 17:38:15 +04:00
* @ static
2013-11-25 20:48:44 +04:00
* @ type { Object }
* @ property { OpenSeadragon . BROWSERS } vendor - One of the { @ link OpenSeadragon . BROWSERS } enumeration values .
* @ property { Number } version
* @ property { Boolean } alpha - Does the browser support image alpha transparency .
2012-03-01 17:38:15 +04:00
* /
$ . Browser = {
vendor : $ . BROWSERS . UNKNOWN ,
version : 0 ,
alpha : true
} ;
2014-04-18 01:20:04 +04:00
var FILEFORMATS = {
2012-03-01 17:38:15 +04:00
"bmp" : false ,
"jpeg" : true ,
"jpg" : true ,
"png" : true ,
"tif" : false ,
"wdp" : false
} ,
URLPARAMS = { } ;
( function ( ) {
2013-06-19 21:33:25 +04:00
//A small auto-executing routine to determine the browser vendor,
2012-03-01 17:38:15 +04:00
//version and supporting feature sets.
2017-01-08 17:52:57 +03:00
var ver = navigator . appVersion ,
2014-04-19 23:10:48 +04:00
ua = navigator . userAgent ,
regex ;
2012-03-01 17:38:15 +04:00
//console.error( 'appName: ' + navigator.appName );
//console.error( 'appVersion: ' + navigator.appVersion );
//console.error( 'userAgent: ' + navigator.userAgent );
switch ( navigator . appName ) {
case "Microsoft Internet Explorer" :
2013-06-19 21:33:25 +04:00
if ( ! ! window . attachEvent &&
2012-03-01 17:38:15 +04:00
! ! window . ActiveXObject ) {
$ . Browser . vendor = $ . BROWSERS . IE ;
$ . Browser . version = parseFloat (
2013-06-19 21:33:25 +04:00
ua . substring (
ua . indexOf ( "MSIE" ) + 5 ,
2012-03-01 17:38:15 +04:00
ua . indexOf ( ";" , ua . indexOf ( "MSIE" ) ) )
) ;
}
break ;
case "Netscape" :
2017-01-08 17:52:57 +03:00
if ( window . addEventListener ) {
2012-03-01 17:38:15 +04:00
if ( ua . indexOf ( "Firefox" ) >= 0 ) {
$ . Browser . vendor = $ . BROWSERS . FIREFOX ;
$ . Browser . version = parseFloat (
ua . substring ( ua . indexOf ( "Firefox" ) + 8 )
) ;
} else if ( ua . indexOf ( "Safari" ) >= 0 ) {
2013-06-19 21:33:25 +04:00
$ . Browser . vendor = ua . indexOf ( "Chrome" ) >= 0 ?
$ . BROWSERS . CHROME :
2012-03-01 17:38:15 +04:00
$ . BROWSERS . SAFARI ;
$ . Browser . version = parseFloat (
2013-06-19 21:33:25 +04:00
ua . substring (
ua . substring ( 0 , ua . indexOf ( "Safari" ) ) . lastIndexOf ( "/" ) + 1 ,
2012-03-01 17:38:15 +04:00
ua . indexOf ( "Safari" )
)
) ;
2014-04-19 23:10:48 +04:00
} else {
2014-08-05 08:41:07 +04:00
regex = new RegExp ( "Trident/.*rv:([0-9]{1,}[.0-9]{0,})" ) ;
2014-04-19 23:10:48 +04:00
if ( regex . exec ( ua ) !== null ) {
$ . Browser . vendor = $ . BROWSERS . IE ;
$ . Browser . version = parseFloat ( RegExp . $1 ) ;
}
2012-03-01 17:38:15 +04:00
}
}
break ;
case "Opera" :
$ . Browser . vendor = $ . BROWSERS . OPERA ;
$ . Browser . version = parseFloat ( ver ) ;
break ;
}
// ignore '?' portion of query string
var query = window . location . search . substring ( 1 ) ,
parts = query . split ( '&' ) ,
part ,
sep ,
i ;
for ( i = 0 ; i < parts . length ; i ++ ) {
part = parts [ i ] ;
sep = part . indexOf ( '=' ) ;
if ( sep > 0 ) {
URLPARAMS [ part . substring ( 0 , sep ) ] =
decodeURIComponent ( part . substring ( sep + 1 ) ) ;
}
}
//determine if this browser supports image alpha transparency
2013-06-19 21:33:25 +04:00
$ . Browser . alpha = ! (
(
$ . Browser . vendor == $ . BROWSERS . IE &&
2012-04-11 01:02:24 +04:00
$ . Browser . version < 9
) || (
2013-06-19 21:33:25 +04:00
$ . Browser . vendor == $ . BROWSERS . CHROME &&
2012-03-01 17:38:15 +04:00
$ . Browser . version < 2
)
) ;
2013-06-07 02:34:09 +04:00
//determine if this browser supports element.style.opacity
$ . Browser . opacity = ! (
$ . Browser . vendor == $ . BROWSERS . IE &&
$ . Browser . version < 9
) ;
2012-03-01 17:38:15 +04:00
} ) ( ) ;
2013-02-28 23:28:05 +04:00
2012-03-01 17:38:15 +04:00
//TODO: $.console is often used inside a try/catch block which generally
// prevents allowings errors to occur with detection until a debugger
// is attached. Although I've been guilty of the same anti-pattern
// I eventually was convinced that errors should naturally propogate in
// all but the most special cases.
/ * *
2013-06-19 21:33:25 +04:00
* A convenient alias for console when available , and a simple null
2012-03-01 17:38:15 +04:00
* function when console is unavailable .
* @ static
* @ private
* /
var nullfunction = function ( msg ) {
//document.location.hash = msg;
} ;
$ . console = window . console || {
log : nullfunction ,
debug : nullfunction ,
info : nullfunction ,
warn : nullfunction ,
2014-08-07 00:48:18 +04:00
error : nullfunction ,
2014-11-04 22:53:39 +03:00
assert : nullfunction
2012-03-01 17:38:15 +04:00
} ;
2013-06-19 21:33:25 +04:00
2012-03-01 17:38:15 +04:00
2013-05-23 20:48:38 +04:00
// Adding support for HTML5's requestAnimationFrame as suggested by acdha.
// Implementation taken from matt synder's post here:
2013-02-26 19:19:48 +04:00
// http://mattsnider.com/cross-browser-and-legacy-supported-requestframeanimation/
( function ( w ) {
// most browsers have an implementation
2013-05-23 20:48:38 +04:00
var requestAnimationFrame = w . requestAnimationFrame ||
2013-06-19 21:33:25 +04:00
w . mozRequestAnimationFrame ||
2013-02-26 19:19:48 +04:00
w . webkitRequestAnimationFrame ||
w . msRequestAnimationFrame ;
2013-05-23 20:48:38 +04:00
var cancelAnimationFrame = w . cancelAnimationFrame ||
2013-06-19 21:33:25 +04:00
w . mozCancelAnimationFrame ||
2013-02-26 19:19:48 +04:00
w . webkitCancelAnimationFrame ||
w . msCancelAnimationFrame ;
// polyfill, when necessary
2013-05-23 20:48:38 +04:00
if ( requestAnimationFrame && cancelAnimationFrame ) {
// We can't assign these window methods directly to $ because they
// expect their "this" to be "window", so we call them in wrappers.
2013-05-24 20:17:26 +04:00
$ . requestAnimationFrame = function ( ) {
2013-05-23 20:48:38 +04:00
return requestAnimationFrame . apply ( w , arguments ) ;
2013-02-26 19:19:48 +04:00
} ;
2013-05-24 20:17:26 +04:00
$ . cancelAnimationFrame = function ( ) {
2013-05-23 20:48:38 +04:00
return cancelAnimationFrame . apply ( w , arguments ) ;
2013-02-26 19:19:48 +04:00
} ;
} else {
var aAnimQueue = [ ] ,
2013-06-17 22:28:42 +04:00
processing = [ ] ,
2013-02-26 19:19:48 +04:00
iRequestId = 0 ,
iIntervalId ;
// create a mock requestAnimationFrame function
$ . requestAnimationFrame = function ( callback ) {
aAnimQueue . push ( [ ++ iRequestId , callback ] ) ;
if ( ! iIntervalId ) {
iIntervalId = setInterval ( function ( ) {
if ( aAnimQueue . length ) {
2013-06-21 00:15:04 +04:00
var time = $ . now ( ) ;
2013-06-17 22:28:42 +04:00
// Process all of the currently outstanding frame
2013-06-20 00:33:01 +04:00
// requests, but none that get added during the
2013-06-17 22:28:42 +04:00
// processing.
2013-06-19 20:58:22 +04:00
// Swap the arrays so we don't have to create a new
// array every frame.
var temp = processing ;
2013-06-17 22:28:42 +04:00
processing = aAnimQueue ;
2013-06-19 20:58:22 +04:00
aAnimQueue = temp ;
2013-06-17 22:28:42 +04:00
while ( processing . length ) {
processing . shift ( ) [ 1 ] ( time ) ;
}
2013-02-26 19:19:48 +04:00
} else {
// don't continue the interval, if unnecessary
clearInterval ( iIntervalId ) ;
iIntervalId = undefined ;
}
} , 1000 / 50 ) ; // estimating support for 50 frames per second
}
return iRequestId ;
} ;
// create a mock cancelAnimationFrame function
$ . cancelAnimationFrame = function ( requestId ) {
// find the request ID and remove it
2013-06-17 22:28:42 +04:00
var i , j ;
for ( i = 0 , j = aAnimQueue . length ; i < j ; i += 1 ) {
2013-02-26 19:19:48 +04:00
if ( aAnimQueue [ i ] [ 0 ] === requestId ) {
aAnimQueue . splice ( i , 1 ) ;
return ;
}
2013-06-17 22:28:42 +04:00
}
// If it's not in the queue, it may be in the set we're currently
2013-06-20 00:33:01 +04:00
// processing (if cancelAnimationFrame is called from within a
2013-06-19 20:58:22 +04:00
// requestAnimationFrame callback).
2013-06-17 22:28:42 +04:00
for ( i = 0 , j = processing . length ; i < j ; i += 1 ) {
if ( processing [ i ] [ 0 ] === requestId ) {
processing . splice ( i , 1 ) ;
return ;
2013-02-26 19:19:48 +04:00
}
}
} ;
}
} ) ( window ) ;
2012-02-01 00:59:09 +04:00
/ * *
* @ private
* @ inner
* @ function
2013-06-19 21:33:25 +04:00
* @ param { Element } element
2012-02-01 00:59:09 +04:00
* @ param { Boolean } [ isFixed ]
* @ returns { Element }
* /
function getOffsetParent ( element , isFixed ) {
if ( isFixed && element != document . body ) {
return document . body ;
} else {
return element . offsetParent ;
}
2013-02-13 07:40:08 +04:00
}
2012-02-01 00:59:09 +04:00
2016-04-03 14:59:10 +03:00
} ( OpenSeadragon ) ) ;
2016-07-25 21:27:53 +03:00
// Universal Module Definition, supports CommonJS, AMD and simple script tag
( function ( root , factory ) {
if ( typeof define === 'function' && define . amd ) {
// expose as amd module
define ( [ ] , factory ) ;
} else if ( typeof module === 'object' && module . exports ) {
// expose as commonjs module
module . exports = factory ( ) ;
} else {
// expose as window.OpenSeadragon
root . OpenSeadragon = factory ( ) ;
}
} ( this , function ( ) {
return OpenSeadragon ;
} ) ) ;