mirror of
https://github.com/openseadragon/openseadragon.git
synced 2024-11-21 20:56:09 +03:00
Merge branch 'master' into ig-seams
This commit is contained in:
commit
2a84ce365e
@ -278,8 +278,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"globals": {
|
"globals": {
|
||||||
"OpenSeadragon": true,
|
"OpenSeadragon": "writable",
|
||||||
"define": false,
|
"define": "readonly",
|
||||||
"module": false
|
"module": "readonly",
|
||||||
|
"Map": "readonly"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,34 @@
|
|||||||
{
|
{
|
||||||
|
"root": true,
|
||||||
|
"extends": [
|
||||||
|
"eslint:recommended"
|
||||||
|
],
|
||||||
"env": {
|
"env": {
|
||||||
|
"es6": false,
|
||||||
"browser": true
|
"browser": true
|
||||||
},
|
},
|
||||||
"extends": "eslint:recommended",
|
"parserOptions": {
|
||||||
|
"ecmaVersion": 5,
|
||||||
|
"sourceType": "script",
|
||||||
|
"ecmaFeatures": {
|
||||||
|
"globalReturn": false,
|
||||||
|
"impliedStrict": false,
|
||||||
|
"jsx": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"globals": {
|
||||||
|
"OpenSeadragon": "writable",
|
||||||
|
"define": "readonly",
|
||||||
|
"module": "readonly",
|
||||||
|
"Map": "readonly"
|
||||||
|
},
|
||||||
"rules": {
|
"rules": {
|
||||||
|
"no-unused-vars": [
|
||||||
|
"error",
|
||||||
|
{
|
||||||
|
"args": "none"
|
||||||
|
}
|
||||||
|
],
|
||||||
"indent": [
|
"indent": [
|
||||||
"off",
|
"off",
|
||||||
4
|
4
|
||||||
@ -16,24 +41,18 @@
|
|||||||
"error",
|
"error",
|
||||||
"always"
|
"always"
|
||||||
],
|
],
|
||||||
"no-unused-vars": [
|
|
||||||
"error",
|
|
||||||
{
|
|
||||||
"args": "none"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"block-scoped-var": [
|
"block-scoped-var": [
|
||||||
"error"
|
"error"
|
||||||
],
|
],
|
||||||
"consistent-return": [
|
"consistent-return": [
|
||||||
"off"
|
"error"
|
||||||
],
|
],
|
||||||
"curly": [
|
"curly": [
|
||||||
"error",
|
"error",
|
||||||
"all"
|
"all"
|
||||||
],
|
],
|
||||||
"eqeqeq": [
|
"eqeqeq": [
|
||||||
"off"
|
"error"
|
||||||
],
|
],
|
||||||
"no-eval": [
|
"no-eval": [
|
||||||
"error"
|
"error"
|
||||||
@ -83,7 +102,7 @@
|
|||||||
"error"
|
"error"
|
||||||
],
|
],
|
||||||
"no-useless-escape": [
|
"no-useless-escape": [
|
||||||
"off"
|
"error"
|
||||||
],
|
],
|
||||||
"no-useless-return": [
|
"no-useless-return": [
|
||||||
"error"
|
"error"
|
||||||
@ -103,7 +122,9 @@
|
|||||||
"no-use-before-define": [
|
"no-use-before-define": [
|
||||||
"error",
|
"error",
|
||||||
{
|
{
|
||||||
"functions": false
|
"functions": false,
|
||||||
|
"classes": true,
|
||||||
|
"variables": true
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"array-bracket-spacing": [
|
"array-bracket-spacing": [
|
||||||
@ -237,7 +258,7 @@
|
|||||||
"after"
|
"after"
|
||||||
],
|
],
|
||||||
"quote-props": [
|
"quote-props": [
|
||||||
"off",
|
"error",
|
||||||
"as-needed"
|
"as-needed"
|
||||||
],
|
],
|
||||||
"semi-spacing": [
|
"semi-spacing": [
|
||||||
@ -273,10 +294,5 @@
|
|||||||
"no-loop-func": [
|
"no-loop-func": [
|
||||||
"error"
|
"error"
|
||||||
]
|
]
|
||||||
},
|
|
||||||
"globals": {
|
|
||||||
"OpenSeadragon": true,
|
|
||||||
"define": false,
|
|
||||||
"module": false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
12
.github/FUNDING.yml
vendored
Normal file
12
.github/FUNDING.yml
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
# These are supported funding model platforms
|
||||||
|
|
||||||
|
github: # iangilman
|
||||||
|
patreon: # iangilman
|
||||||
|
open_collective: openseadragon
|
||||||
|
ko_fi: # iangilman
|
||||||
|
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||||
|
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||||
|
liberapay: # Replace with a single Liberapay username
|
||||||
|
issuehunt: # Replace with a single IssueHunt username
|
||||||
|
otechie: # Replace with a single Otechie username
|
||||||
|
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -7,4 +7,4 @@ instrumented/
|
|||||||
.idea
|
.idea
|
||||||
/nbproject/private/
|
/nbproject/private/
|
||||||
.directory
|
.directory
|
||||||
test/demo/temp
|
local-test
|
||||||
|
21
.vscode/tasks.json
vendored
21
.vscode/tasks.json
vendored
@ -1,25 +1,26 @@
|
|||||||
{
|
{
|
||||||
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
||||||
// for the documentation about the tasks.json format
|
// for the documentation about the tasks.json format
|
||||||
"version": "0.1.0",
|
"version": "2.0.0",
|
||||||
"command": "grunt",
|
"command": "grunt",
|
||||||
"isShellCommand": true,
|
|
||||||
"tasks": [
|
"tasks": [
|
||||||
{
|
{
|
||||||
"taskName": "build",
|
"label": "build",
|
||||||
"args": [],
|
"type": "grunt",
|
||||||
"isBuildCommand": true,
|
"task": "build",
|
||||||
"isWatching": false,
|
|
||||||
"problemMatcher": [
|
"problemMatcher": [
|
||||||
"$lessCompile",
|
"$lessCompile",
|
||||||
"$tsc",
|
"$tsc",
|
||||||
"$jshint"
|
"$jshint"
|
||||||
]
|
],
|
||||||
|
"group": "build"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"taskName": "test",
|
"label": "test",
|
||||||
"args": [],
|
"type": "grunt",
|
||||||
"isTestCommand": true
|
"task": "test",
|
||||||
|
"problemMatcher": [],
|
||||||
|
"group": "test"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
25
.vscode/tasks.json.old
vendored
Normal file
25
.vscode/tasks.json.old
vendored
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
||||||
|
// for the documentation about the tasks.json format
|
||||||
|
"version": "0.1.0",
|
||||||
|
"command": "grunt",
|
||||||
|
"isShellCommand": true,
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"taskName": "build",
|
||||||
|
"args": [],
|
||||||
|
"isBuildCommand": true,
|
||||||
|
"isWatching": false,
|
||||||
|
"problemMatcher": [
|
||||||
|
"$lessCompile",
|
||||||
|
"$tsc",
|
||||||
|
"$jshint"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"taskName": "test",
|
||||||
|
"args": [],
|
||||||
|
"isTestCommand": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -1,6 +1,8 @@
|
|||||||
|
/* eslint-disable no-redeclare */
|
||||||
/* global module */
|
/* global module */
|
||||||
|
|
||||||
module.exports = function(grunt) {
|
module.exports = function(grunt) {
|
||||||
|
/* eslint-disable no-undef */
|
||||||
var dateFormat = require('dateformat');
|
var dateFormat = require('dateformat');
|
||||||
|
|
||||||
// ----------
|
// ----------
|
||||||
@ -123,6 +125,7 @@ module.exports = function(grunt) {
|
|||||||
banner: banner,
|
banner: banner,
|
||||||
compress: {
|
compress: {
|
||||||
sequences: false,
|
sequences: false,
|
||||||
|
/* eslint-disable camelcase */
|
||||||
join_vars: false
|
join_vars: false
|
||||||
},
|
},
|
||||||
sourceMap: true,
|
sourceMap: true,
|
||||||
@ -199,7 +202,7 @@ module.exports = function(grunt) {
|
|||||||
target: sources
|
target: sources
|
||||||
},
|
},
|
||||||
"git-describe": {
|
"git-describe": {
|
||||||
"options": {
|
options: {
|
||||||
failOnError: false
|
failOnError: false
|
||||||
},
|
},
|
||||||
build: {}
|
build: {}
|
||||||
|
@ -1,13 +1,78 @@
|
|||||||
OPENSEADRAGON CHANGELOG
|
OPENSEADRAGON CHANGELOG
|
||||||
=======================
|
=======================
|
||||||
|
|
||||||
2.4.2: (In Progress)
|
3.0.0: (In progress)
|
||||||
|
|
||||||
|
* BREAKING CHANGE: Dropped support for older browsers (IE < 11) (#1872 #1949 #1951 @msalsbery, #1950 @rmontroy)
|
||||||
|
* BREAKING CHANGE: Removed deprecated OpenSeadragon.getEvent function (#1949 @msalsbery)
|
||||||
|
* DEPRECATION: MouseTracker exitHandler deprecated for name change to leaveHandler for consistency with DOM event names (#1872 @msalsbery)
|
||||||
|
* Now when "simple image" tile sources are removed from the viewer, they free the memory used by the pyramid they create (#1789 @TakumaKira)
|
||||||
|
* Improvements to docs (#1814 @kenanchristian, #1872 @msalsbery, #1996 @tdiprima)
|
||||||
|
* Better cleanup on destruction, to avoid memory leaks (#1832 @JoFrMueller)
|
||||||
|
* Better handle destruction when navigator in custom location (#1884 @woodchuck)
|
||||||
|
* Miscellaneous code cleanup (#1840 @msalsbery)
|
||||||
|
* You can now specify tileSize for the Zoomify Tile Source (#1868 @abrlam)
|
||||||
|
* Better use of IIIF "max" and "full" URL parameters (#1871 @MImranAsghar)
|
||||||
|
* You can now specify the file format of the tiles in the Zoomify tile source (#1889 @abrlam)
|
||||||
|
* Improved browser sniffing - detect EDGE and CHROMEEDGE browsers (#1872 @msalsbery)
|
||||||
|
* Improved DOM event model feature detection (#1872 @msalsbery)
|
||||||
|
* Added support for options parameter on addEvent()/removeEvent (to support passive option) (#1872 @msalsbery)
|
||||||
|
* Added OpenSeadragon.eventIsCanceled() function for defaultPrevented detection on DOM events (#1872 @msalsbery)
|
||||||
|
* MouseTracker: better PointerEvent model detection - removed use of deprecated window.navigator.pointerEnabled (#1872 @msalsbery)
|
||||||
|
* MouseTracker: added overHandler/outHandler options for handling corresponding pointerover/pointerout events (#1872 @msalsbery)
|
||||||
|
* MouseTracker: changed enterHandler/leaveHandler to use DOM pointerenter/pointerleave events instead of simulating using pointerover/pointerout (#1872 @msalsbery)
|
||||||
|
* All internal uses of MouseTracker use pointerenter/pointerleave events instead of pointerover/pointerout events for more consistent pointer tracking (#1872 @msalsbery)
|
||||||
|
* Fixed bug in Button class where two MouseTracker event handlers used an invalid "this" causing issues in some browsers (#1872 @msalsbery)
|
||||||
|
* Added pointerType property to Viewer container-enter, container-exit, canvas-drag, canvas-drag-end, canvas-pinch events (#1872 @msalsbery)
|
||||||
|
* MouseTracker: Fire dragEndHandler event even if release point same as initial contact point (#1872 @msalsbery)
|
||||||
|
* MouseTracker: Pointer capture implemented with capture APIs where available. Only fallback to emulated capture on extremely old browsers (#1872 @msalsbery)
|
||||||
|
* MouseTracker: Added preProcessEventHandler option to allow MouseTracker instances to control bubbling and default behavior of events on their associated element (#1872 @msalsbery)
|
||||||
|
* MouseTracker: Improved handling of canceled events (#1872 @msalsbery)
|
||||||
|
* MouseTracker: Improved releasing of tracked pointers on destroy()/stopTracking() (#1872 @msalsbery)
|
||||||
|
* Updated Viewer, Button, Drawer, Navigator, ReferenceStrip DOM for proper DOM event handling (#1872 @msalsbery)
|
||||||
|
* Added OpenSeadragon.setElementPointerEventsNone() for setting pointer-events:'none' on DOM elements (#1872 @msalsbery)
|
||||||
|
* MouseTracker: added contextMenuHandler option for handling contextmenu events (#1872 @msalsbery)
|
||||||
|
* Viewer: added a canvas-contextmenu event (#1872 @msalsbery)
|
||||||
|
* Fixed simulated drag events in navigator tests (#1949 @msalsbery)
|
||||||
|
* Added preventDefault option to MouseTracker.contextMenuHandler and Viewer 'canvas-contextmenu' event args (#1951 @msalsbery)
|
||||||
|
* MouseTracker: Added preProcessEventHandler for keydown, keyup, keypress, focus, blur Events (#1951 @msalsbery)
|
||||||
|
* Fixed preventDefaultAction functionality in viewer events (#1953 @msalsbery)
|
||||||
|
* Added setImageFormatsSupported function (#1954 @pandaxtc)
|
||||||
|
* Added dragToPan to the GestureSettings class, implemented in Viewer (#1956 @msalsbery)
|
||||||
|
* Added preventDefault option to MouseTracker handlers: scrollHandler, keyDownHandler, keyUpHandler, keyHandler (#1957 @msalsbery)
|
||||||
|
* Fixed test "Events: Viewer: preventDefaultAction in dblClickHandler". Fixes #1372 (#1960 @msalsbery)
|
||||||
|
* ReferenceStrip: Fixed issue where its element was being removed from its parent element twice on destroy, causing an exception (#1958 @msalsbery)
|
||||||
|
* ReferenceStrip: Made its element focusable for keyboard navigation (#1958 @msalsbery)
|
||||||
|
* You can now flip individual images (not just the whole viewport) (#1903 @ali1234)
|
||||||
|
* Accessibility: we now take the browser's zoom into account when choosing what detail level to draw (#1937 @ronnymikalsen)
|
||||||
|
* Fixed a bug causing overlays to disappear in Sequence Mode (#1865 @gunmiosb)
|
||||||
|
* Fixed a bug where the ajaxHeaders provided per-image were not being used for image requests (#1968 @maxshuty)
|
||||||
|
* MouseTracker: Added workaround for WebKit Pointer Event Implicit Capture Bug (#1972 @msalsbery)
|
||||||
|
* Removed test for move-leave (fly-over, no enter event)...not a valid, handleable event state, no longer supported (#1972 @msalsbery)
|
||||||
|
* Added OpenSeadragon.setElementPointerEvents() for setting pointer-events to other values besides 'none' on DOM elements (#1972 @msalsbery)
|
||||||
|
* Now ensuring the page body is display:block when in fullscreen (#1995 @thewilkybarkid)
|
||||||
|
* Added a static method in OpenSeadragon to get an existing viewer (#2000 @HerCerM)
|
||||||
|
* Now ensuring that the new item is already in the navigator when the "add-item" event fires (#2005 @RammasEchor)
|
||||||
|
* Added keys to change image in sequence mode (j: previous, k: next) (#2007 @RammasEchor)
|
||||||
|
* Fixed a bug where the navigator wouldn't pick up opacity/composite changes made while it is loading (#2018 @crydell)
|
||||||
|
* Explicitly set passive:false for wheel event handlers to suppress console warnings. Fixes #1669 (#2043 @msalsbery)
|
||||||
|
* Viewer's canvas-click events now include an originalTarget property so you can know which element received the click (#2037 @iangilman)
|
||||||
|
* Added method for getting the size of an image in window coordinates (#2049 @superbland)
|
||||||
|
|
||||||
|
2.4.2:
|
||||||
|
|
||||||
|
* Add support for IIIF Image API 3.0 beta (#1764)
|
||||||
|
* You can now crop an image with arbitrary polygons (#1772)
|
||||||
* Improved support for using the Reference Strip in an OpenSeadragon Viewer inside a Web Component (#1676)
|
* Improved support for using the Reference Strip in an OpenSeadragon Viewer inside a Web Component (#1676)
|
||||||
* Added setWidth and setHeight methods to Navigator (#1686)
|
* Added setWidth and setHeight methods to Navigator (#1686)
|
||||||
* Fixed: Navigator was still resizing after you explicitly set its width and height with navigatorWidth and navigatorHeight (#1686)
|
* Improvements to docs (#1696, #1698, #1716, #1719)
|
||||||
* Improvements to docs (#1696, #1698)
|
|
||||||
* Now passing Viewer AJAX configs down to ReferenceStrip thumbnails (#1701)
|
* Now passing Viewer AJAX configs down to ReferenceStrip thumbnails (#1701)
|
||||||
|
* The ReferenceStrip now honors the useCanvas option from the Viewer (#1742)
|
||||||
|
* Fixed: Navigator was still resizing after you explicitly set its width and height with navigatorWidth and navigatorHeight (#1686)
|
||||||
|
* Fixed issues with touches on iOS 13 and iPad (#1754, #1756)
|
||||||
|
* No longer throwing an exception on pages that have malformed URL parameters (#1758)
|
||||||
|
* Fixed an issue with flipping the viewport on high pixel density screens (#1779)
|
||||||
|
* Removed use of deprecated imageSmoothingEnabled prefixes (#1740)
|
||||||
|
|
||||||
2.4.1:
|
2.4.1:
|
||||||
|
|
||||||
@ -40,7 +105,7 @@ OPENSEADRAGON CHANGELOG
|
|||||||
* You can now prevent canvas-click events on the navigator (#1416)
|
* You can now prevent canvas-click events on the navigator (#1416)
|
||||||
* The navigator can now be restricted to just horizontal or just vertical panning (#1416)
|
* The navigator can now be restricted to just horizontal or just vertical panning (#1416)
|
||||||
* Fixed DziTileSource so it doesn't load levels above maxLevel or below minLevel, if set (#1492)
|
* Fixed DziTileSource so it doesn't load levels above maxLevel or below minLevel, if set (#1492)
|
||||||
|
|
||||||
2.3.1:
|
2.3.1:
|
||||||
|
|
||||||
* Debug mode now uses different colors for different tiled images (customizable via debugGridColor) (#1271)
|
* Debug mode now uses different colors for different tiled images (customizable via debugGridColor) (#1271)
|
||||||
|
7210
package-lock.json
generated
7210
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
17
package.json
17
package.json
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "openseadragon",
|
"name": "openseadragon",
|
||||||
"version": "2.4.1",
|
"version": "2.4.2",
|
||||||
"description": "Provides a smooth, zoomable user interface for HTML/Javascript.",
|
"description": "Provides a smooth, zoomable user interface for HTML/Javascript.",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"image",
|
"image",
|
||||||
@ -14,7 +14,8 @@
|
|||||||
"osm",
|
"osm",
|
||||||
"tms"
|
"tms"
|
||||||
],
|
],
|
||||||
"homepage": "http://openseadragon.github.io/",
|
"homepage": "https://openseadragon.github.io/",
|
||||||
|
"funding": "https://opencollective.com/openseadragon",
|
||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/openseadragon/openseadragon/issues"
|
"url": "https://github.com/openseadragon/openseadragon/issues"
|
||||||
},
|
},
|
||||||
@ -28,15 +29,15 @@
|
|||||||
"url": "https://github.com/openseadragon/openseadragon.git"
|
"url": "https://github.com/openseadragon/openseadragon.git"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"grunt": "^1.0.4",
|
"grunt": "^1.1.0",
|
||||||
"grunt-contrib-clean": "^1.1.0",
|
"grunt-contrib-clean": "^2.0.0",
|
||||||
"grunt-contrib-compress": "^1.5.0",
|
"grunt-contrib-compress": "^1.6.0",
|
||||||
"grunt-contrib-concat": "^1.0.1",
|
"grunt-contrib-concat": "^1.0.1",
|
||||||
"grunt-contrib-connect": "^1.0.2",
|
"grunt-contrib-connect": "^2.1.0",
|
||||||
"grunt-contrib-qunit": "^3.1.0",
|
"grunt-contrib-qunit": "^3.1.0",
|
||||||
"grunt-contrib-uglify": "^3.4.0",
|
"grunt-contrib-uglify": "^4.0.1",
|
||||||
"grunt-contrib-watch": "^1.1.0",
|
"grunt-contrib-watch": "^1.1.0",
|
||||||
"grunt-eslint": "^20.2.0",
|
"grunt-eslint": "^23.0.0",
|
||||||
"grunt-git-describe": "^2.4.4",
|
"grunt-git-describe": "^2.4.4",
|
||||||
"grunt-istanbul": "^0.8.0",
|
"grunt-istanbul": "^0.8.0",
|
||||||
"grunt-text-replace": "^0.4.0",
|
"grunt-text-replace": "^0.4.0",
|
||||||
|
@ -77,6 +77,7 @@ $.ButtonState = {
|
|||||||
* @param {OpenSeadragon.EventHandler} [options.onExit=null] Event handler callback for {@link OpenSeadragon.Button.event:exit}.
|
* @param {OpenSeadragon.EventHandler} [options.onExit=null] Event handler callback for {@link OpenSeadragon.Button.event:exit}.
|
||||||
* @param {OpenSeadragon.EventHandler} [options.onFocus=null] Event handler callback for {@link OpenSeadragon.Button.event:focus}.
|
* @param {OpenSeadragon.EventHandler} [options.onFocus=null] Event handler callback for {@link OpenSeadragon.Button.event:focus}.
|
||||||
* @param {OpenSeadragon.EventHandler} [options.onBlur=null] Event handler callback for {@link OpenSeadragon.Button.event:blur}.
|
* @param {OpenSeadragon.EventHandler} [options.onBlur=null] Event handler callback for {@link OpenSeadragon.Button.event:blur}.
|
||||||
|
* @param {Object} [options.userData=null] Arbitrary object to be passed unchanged to any attached handler methods.
|
||||||
*/
|
*/
|
||||||
$.Button = function( options ) {
|
$.Button = function( options ) {
|
||||||
|
|
||||||
@ -111,7 +112,8 @@ $.Button = function( options ) {
|
|||||||
onEnter: null,
|
onEnter: null,
|
||||||
onExit: null,
|
onExit: null,
|
||||||
onFocus: null,
|
onFocus: null,
|
||||||
onBlur: null
|
onBlur: null,
|
||||||
|
userData: null
|
||||||
|
|
||||||
}, options );
|
}, options );
|
||||||
|
|
||||||
@ -136,6 +138,13 @@ $.Button = function( options ) {
|
|||||||
this.imgDown.alt =
|
this.imgDown.alt =
|
||||||
this.tooltip;
|
this.tooltip;
|
||||||
|
|
||||||
|
// Allow pointer events to pass through the img elements so implicit
|
||||||
|
// pointer capture works on touch devices
|
||||||
|
$.setElementPointerEventsNone( this.imgRest );
|
||||||
|
$.setElementPointerEventsNone( this.imgGroup );
|
||||||
|
$.setElementPointerEventsNone( this.imgHover );
|
||||||
|
$.setElementPointerEventsNone( this.imgDown );
|
||||||
|
|
||||||
this.element.style.position = "relative";
|
this.element.style.position = "relative";
|
||||||
$.setElementTouchActionNone( this.element );
|
$.setElementTouchActionNone( this.element );
|
||||||
|
|
||||||
@ -158,7 +167,7 @@ $.Button = function( options ) {
|
|||||||
this.imgDown.style.visibility =
|
this.imgDown.style.visibility =
|
||||||
"hidden";
|
"hidden";
|
||||||
|
|
||||||
if ($.Browser.vendor == $.BROWSERS.FIREFOX && $.Browser.version < 3) {
|
if ($.Browser.vendor === $.BROWSERS.FIREFOX && $.Browser.version < 3) {
|
||||||
this.imgGroup.style.top =
|
this.imgGroup.style.top =
|
||||||
this.imgHover.style.top =
|
this.imgHover.style.top =
|
||||||
this.imgDown.style.top =
|
this.imgDown.style.top =
|
||||||
@ -203,6 +212,7 @@ $.Button = function( options ) {
|
|||||||
*/
|
*/
|
||||||
this.tracker = new $.MouseTracker({
|
this.tracker = new $.MouseTracker({
|
||||||
|
|
||||||
|
userData: 'Button.tracker',
|
||||||
element: this.element,
|
element: this.element,
|
||||||
clickTimeThreshold: this.clickTimeThreshold,
|
clickTimeThreshold: this.clickTimeThreshold,
|
||||||
clickDistThreshold: this.clickDistThreshold,
|
clickDistThreshold: this.clickDistThreshold,
|
||||||
@ -227,7 +237,7 @@ $.Button = function( options ) {
|
|||||||
},
|
},
|
||||||
|
|
||||||
focusHandler: function ( event ) {
|
focusHandler: function ( event ) {
|
||||||
this.enterHandler( event );
|
_this.tracker.enterHandler( event );
|
||||||
/**
|
/**
|
||||||
* Raised when the Button element receives focus.
|
* Raised when the Button element receives focus.
|
||||||
*
|
*
|
||||||
@ -241,7 +251,7 @@ $.Button = function( options ) {
|
|||||||
_this.raiseEvent( "focus", { originalEvent: event.originalEvent } );
|
_this.raiseEvent( "focus", { originalEvent: event.originalEvent } );
|
||||||
},
|
},
|
||||||
|
|
||||||
exitHandler: function( event ) {
|
leaveHandler: function( event ) {
|
||||||
outTo( _this, $.ButtonState.GROUP );
|
outTo( _this, $.ButtonState.GROUP );
|
||||||
if ( event.insideElementPressed ) {
|
if ( event.insideElementPressed ) {
|
||||||
/**
|
/**
|
||||||
@ -259,7 +269,7 @@ $.Button = function( options ) {
|
|||||||
},
|
},
|
||||||
|
|
||||||
blurHandler: function ( event ) {
|
blurHandler: function ( event ) {
|
||||||
this.exitHandler( event );
|
_this.tracker.leaveHandler( event );
|
||||||
/**
|
/**
|
||||||
* Raised when the Button element loses focus.
|
* Raised when the Button element loses focus.
|
||||||
*
|
*
|
||||||
@ -350,9 +360,11 @@ $.Button = function( options ) {
|
|||||||
* @property {?Object} userData - Arbitrary subscriber-defined object.
|
* @property {?Object} userData - Arbitrary subscriber-defined object.
|
||||||
*/
|
*/
|
||||||
_this.raiseEvent( "release", { originalEvent: event.originalEvent } );
|
_this.raiseEvent( "release", { originalEvent: event.originalEvent } );
|
||||||
return false;
|
|
||||||
|
event.preventDefault = true;
|
||||||
|
} else{
|
||||||
|
event.preventDefault = false;
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
@ -363,8 +375,8 @@ $.Button = function( options ) {
|
|||||||
$.extend( $.Button.prototype, $.EventSource.prototype, /** @lends OpenSeadragon.Button.prototype */{
|
$.extend( $.Button.prototype, $.EventSource.prototype, /** @lends OpenSeadragon.Button.prototype */{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO: Determine what this function is intended to do and if it's actually
|
* Used by a button container element (e.g. a ButtonGroup) to transition the button state
|
||||||
* useful as an API point.
|
* to ButtonState.GROUP.
|
||||||
* @function
|
* @function
|
||||||
*/
|
*/
|
||||||
notifyGroupEnter: function() {
|
notifyGroupEnter: function() {
|
||||||
@ -372,8 +384,8 @@ $.extend( $.Button.prototype, $.EventSource.prototype, /** @lends OpenSeadragon.
|
|||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO: Determine what this function is intended to do and if it's actually
|
* Used by a button container element (e.g. a ButtonGroup) to transition the button state
|
||||||
* useful as an API point.
|
* to ButtonState.REST.
|
||||||
* @function
|
* @function
|
||||||
*/
|
*/
|
||||||
notifyGroupExit: function() {
|
notifyGroupExit: function() {
|
||||||
@ -396,6 +408,28 @@ $.extend( $.Button.prototype, $.EventSource.prototype, /** @lends OpenSeadragon.
|
|||||||
this.element.disabled = false;
|
this.element.disabled = false;
|
||||||
$.setElementOpacity( this.element, 1.0, true );
|
$.setElementOpacity( this.element, 1.0, true );
|
||||||
this.notifyGroupEnter();
|
this.notifyGroupEnter();
|
||||||
|
},
|
||||||
|
|
||||||
|
destroy: function() {
|
||||||
|
if (this.imgRest) {
|
||||||
|
this.element.removeChild(this.imgRest);
|
||||||
|
this.imgRest = null;
|
||||||
|
}
|
||||||
|
if (this.imgGroup) {
|
||||||
|
this.element.removeChild(this.imgGroup);
|
||||||
|
this.imgGroup = null;
|
||||||
|
}
|
||||||
|
if (this.imgHover) {
|
||||||
|
this.element.removeChild(this.imgHover);
|
||||||
|
this.imgHover = null;
|
||||||
|
}
|
||||||
|
if (this.imgDown) {
|
||||||
|
this.element.removeChild(this.imgDown);
|
||||||
|
this.imgDown = null;
|
||||||
|
}
|
||||||
|
this.removeAllHandlers();
|
||||||
|
this.tracker.destroy();
|
||||||
|
this.element = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
@ -451,13 +485,13 @@ function inTo( button, newState ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ( newState >= $.ButtonState.GROUP &&
|
if ( newState >= $.ButtonState.GROUP &&
|
||||||
button.currentState == $.ButtonState.REST ) {
|
button.currentState === $.ButtonState.REST ) {
|
||||||
stopFading( button );
|
stopFading( button );
|
||||||
button.currentState = $.ButtonState.GROUP;
|
button.currentState = $.ButtonState.GROUP;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( newState >= $.ButtonState.HOVER &&
|
if ( newState >= $.ButtonState.HOVER &&
|
||||||
button.currentState == $.ButtonState.GROUP ) {
|
button.currentState === $.ButtonState.GROUP ) {
|
||||||
if( button.imgHover ){
|
if( button.imgHover ){
|
||||||
button.imgHover.style.visibility = "";
|
button.imgHover.style.visibility = "";
|
||||||
}
|
}
|
||||||
@ -465,7 +499,7 @@ function inTo( button, newState ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ( newState >= $.ButtonState.DOWN &&
|
if ( newState >= $.ButtonState.DOWN &&
|
||||||
button.currentState == $.ButtonState.HOVER ) {
|
button.currentState === $.ButtonState.HOVER ) {
|
||||||
if( button.imgDown ){
|
if( button.imgDown ){
|
||||||
button.imgDown.style.visibility = "";
|
button.imgDown.style.visibility = "";
|
||||||
}
|
}
|
||||||
@ -481,7 +515,7 @@ function outTo( button, newState ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ( newState <= $.ButtonState.HOVER &&
|
if ( newState <= $.ButtonState.HOVER &&
|
||||||
button.currentState == $.ButtonState.DOWN ) {
|
button.currentState === $.ButtonState.DOWN ) {
|
||||||
if( button.imgDown ){
|
if( button.imgDown ){
|
||||||
button.imgDown.style.visibility = "hidden";
|
button.imgDown.style.visibility = "hidden";
|
||||||
}
|
}
|
||||||
@ -489,7 +523,7 @@ function outTo( button, newState ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ( newState <= $.ButtonState.GROUP &&
|
if ( newState <= $.ButtonState.GROUP &&
|
||||||
button.currentState == $.ButtonState.HOVER ) {
|
button.currentState === $.ButtonState.HOVER ) {
|
||||||
if( button.imgHover ){
|
if( button.imgHover ){
|
||||||
button.imgHover.style.visibility = "hidden";
|
button.imgHover.style.visibility = "hidden";
|
||||||
}
|
}
|
||||||
@ -497,7 +531,7 @@ function outTo( button, newState ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ( newState <= $.ButtonState.REST &&
|
if ( newState <= $.ButtonState.REST &&
|
||||||
button.currentState == $.ButtonState.GROUP ) {
|
button.currentState === $.ButtonState.GROUP ) {
|
||||||
beginFading( button );
|
beginFading( button );
|
||||||
button.currentState = $.ButtonState.REST;
|
button.currentState = $.ButtonState.REST;
|
||||||
}
|
}
|
||||||
|
@ -88,6 +88,7 @@ $.ButtonGroup = function( options ) {
|
|||||||
* @memberof OpenSeadragon.ButtonGroup#
|
* @memberof OpenSeadragon.ButtonGroup#
|
||||||
*/
|
*/
|
||||||
this.tracker = new $.MouseTracker({
|
this.tracker = new $.MouseTracker({
|
||||||
|
userData: 'ButtonGroup.tracker',
|
||||||
element: this.element,
|
element: this.element,
|
||||||
clickTimeThreshold: this.clickTimeThreshold,
|
clickTimeThreshold: this.clickTimeThreshold,
|
||||||
clickDistThreshold: this.clickDistThreshold,
|
clickDistThreshold: this.clickDistThreshold,
|
||||||
@ -97,7 +98,7 @@ $.ButtonGroup = function( options ) {
|
|||||||
_this.buttons[ i ].notifyGroupEnter();
|
_this.buttons[ i ].notifyGroupEnter();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
exitHandler: function ( event ) {
|
leaveHandler: function ( event ) {
|
||||||
var i;
|
var i;
|
||||||
if ( !event.insideElementPressed ) {
|
if ( !event.insideElementPressed ) {
|
||||||
for ( i = 0; i < _this.buttons.length; i++ ) {
|
for ( i = 0; i < _this.buttons.length; i++ ) {
|
||||||
@ -127,8 +128,18 @@ $.ButtonGroup.prototype = {
|
|||||||
* @function
|
* @function
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
emulateExit: function() {
|
emulateLeave: function() {
|
||||||
this.tracker.exitHandler( { eventSource: this.tracker } );
|
this.tracker.leaveHandler( { eventSource: this.tracker } );
|
||||||
|
},
|
||||||
|
|
||||||
|
destroy: function() {
|
||||||
|
while (this.buttons.length) {
|
||||||
|
var button = this.buttons.pop();
|
||||||
|
this.element.removeChild(button.element);
|
||||||
|
button.destroy();
|
||||||
|
}
|
||||||
|
this.tracker.destroy();
|
||||||
|
this.element = null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -112,13 +112,13 @@ $.Control = function ( element, options, container ) {
|
|||||||
* @member {Element} wrapper
|
* @member {Element} wrapper
|
||||||
* @memberof OpenSeadragon.Control#
|
* @memberof OpenSeadragon.Control#
|
||||||
*/
|
*/
|
||||||
if ( this.anchor == $.ControlAnchor.ABSOLUTE ) {
|
if ( this.anchor === $.ControlAnchor.ABSOLUTE ) {
|
||||||
this.wrapper = $.makeNeutralElement( "div" );
|
this.wrapper = $.makeNeutralElement( "div" );
|
||||||
this.wrapper.style.position = "absolute";
|
this.wrapper.style.position = "absolute";
|
||||||
this.wrapper.style.top = typeof (options.top) == "number" ? (options.top + 'px') : options.top;
|
this.wrapper.style.top = typeof (options.top) === "number" ? (options.top + 'px') : options.top;
|
||||||
this.wrapper.style.left = typeof (options.left) == "number" ? (options.left + 'px') : options.left;
|
this.wrapper.style.left = typeof (options.left) === "number" ? (options.left + 'px') : options.left;
|
||||||
this.wrapper.style.height = typeof (options.height) == "number" ? (options.height + 'px') : options.height;
|
this.wrapper.style.height = typeof (options.height) === "number" ? (options.height + 'px') : options.height;
|
||||||
this.wrapper.style.width = typeof (options.width) == "number" ? (options.width + 'px') : options.width;
|
this.wrapper.style.width = typeof (options.width) === "number" ? (options.width + 'px') : options.width;
|
||||||
this.wrapper.style.margin = "0px";
|
this.wrapper.style.margin = "0px";
|
||||||
this.wrapper.style.padding = "0px";
|
this.wrapper.style.padding = "0px";
|
||||||
|
|
||||||
@ -130,7 +130,7 @@ $.Control = function ( element, options, container ) {
|
|||||||
} else {
|
} else {
|
||||||
this.wrapper = $.makeNeutralElement( "div" );
|
this.wrapper = $.makeNeutralElement( "div" );
|
||||||
this.wrapper.style.display = "inline-block";
|
this.wrapper.style.display = "inline-block";
|
||||||
if ( this.anchor == $.ControlAnchor.NONE ) {
|
if ( this.anchor === $.ControlAnchor.NONE ) {
|
||||||
// IE6 fix
|
// IE6 fix
|
||||||
this.wrapper.style.width = this.wrapper.style.height = "100%";
|
this.wrapper.style.width = this.wrapper.style.height = "100%";
|
||||||
}
|
}
|
||||||
@ -138,8 +138,8 @@ $.Control = function ( element, options, container ) {
|
|||||||
this.wrapper.appendChild( this.element );
|
this.wrapper.appendChild( this.element );
|
||||||
|
|
||||||
if (options.attachToViewer ) {
|
if (options.attachToViewer ) {
|
||||||
if ( this.anchor == $.ControlAnchor.TOP_RIGHT ||
|
if ( this.anchor === $.ControlAnchor.TOP_RIGHT ||
|
||||||
this.anchor == $.ControlAnchor.BOTTOM_RIGHT ) {
|
this.anchor === $.ControlAnchor.BOTTOM_RIGHT ) {
|
||||||
this.container.insertBefore(
|
this.container.insertBefore(
|
||||||
this.wrapper,
|
this.wrapper,
|
||||||
this.container.firstChild
|
this.container.firstChild
|
||||||
@ -161,7 +161,9 @@ $.Control.prototype = {
|
|||||||
*/
|
*/
|
||||||
destroy: function() {
|
destroy: function() {
|
||||||
this.wrapper.removeChild( this.element );
|
this.wrapper.removeChild( this.element );
|
||||||
this.container.removeChild( this.wrapper );
|
if (this.anchor !== $.ControlAnchor.NONE) {
|
||||||
|
this.container.removeChild(this.wrapper);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -170,7 +172,7 @@ $.Control.prototype = {
|
|||||||
* @return {Boolean} true if currently visible, false otherwise.
|
* @return {Boolean} true if currently visible, false otherwise.
|
||||||
*/
|
*/
|
||||||
isVisible: function() {
|
isVisible: function() {
|
||||||
return this.wrapper.style.display != "none";
|
return this.wrapper.style.display !== "none";
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -180,7 +182,7 @@ $.Control.prototype = {
|
|||||||
*/
|
*/
|
||||||
setVisible: function( visible ) {
|
setVisible: function( visible ) {
|
||||||
this.wrapper.style.display = visible ?
|
this.wrapper.style.display = visible ?
|
||||||
( this.anchor == $.ControlAnchor.ABSOLUTE ? 'block' : 'inline-block' ) :
|
( this.anchor === $.ControlAnchor.ABSOLUTE ? 'block' : 'inline-block' ) :
|
||||||
"none";
|
"none";
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -190,7 +192,7 @@ $.Control.prototype = {
|
|||||||
* @param {Number} opactiy - a value between 1 and 0 inclusively.
|
* @param {Number} opactiy - a value between 1 and 0 inclusively.
|
||||||
*/
|
*/
|
||||||
setOpacity: function( opacity ) {
|
setOpacity: function( opacity ) {
|
||||||
if ( this.element[ $.SIGNAL ] && $.Browser.vendor == $.BROWSERS.IE ) {
|
if ( this.element[ $.SIGNAL ] && $.Browser.vendor === $.BROWSERS.IE ) {
|
||||||
$.setElementOpacity( this.element, opacity, true );
|
$.setElementOpacity( this.element, opacity, true );
|
||||||
} else {
|
} else {
|
||||||
$.setElementOpacity( this.wrapper, opacity, true );
|
$.setElementOpacity( this.wrapper, opacity, true );
|
||||||
|
@ -218,7 +218,7 @@
|
|||||||
i;
|
i;
|
||||||
|
|
||||||
for ( i = controls.length - 1; i >= 0; i-- ) {
|
for ( i = controls.length - 1; i >= 0; i-- ) {
|
||||||
if ( controls[ i ].element == element ) {
|
if ( controls[ i ].element === element ) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -126,6 +126,10 @@ $.Drawer = function( options ) {
|
|||||||
this.canvas.style.height = "100%";
|
this.canvas.style.height = "100%";
|
||||||
this.canvas.style.position = "absolute";
|
this.canvas.style.position = "absolute";
|
||||||
$.setElementOpacity( this.canvas, this.opacity, true );
|
$.setElementOpacity( this.canvas, this.opacity, true );
|
||||||
|
// Allow pointer events to pass through the canvas element so implicit
|
||||||
|
// pointer capture works on touch devices
|
||||||
|
$.setElementPointerEventsNone( this.canvas );
|
||||||
|
$.setElementTouchActionNone( this.canvas );
|
||||||
|
|
||||||
// explicit left-align
|
// explicit left-align
|
||||||
this.container.style.textAlign = "left";
|
this.container.style.textAlign = "left";
|
||||||
@ -166,6 +170,41 @@ $.Drawer.prototype = {
|
|||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function converts the given point from to the drawer coordinate by
|
||||||
|
* multiplying it with the pixel density.
|
||||||
|
* This function does not take rotation into account, thus assuming provided
|
||||||
|
* point is at 0 degree.
|
||||||
|
* @param {OpenSeadragon.Point} point - the pixel point to convert
|
||||||
|
*/
|
||||||
|
viewportCoordToDrawerCoord: function(point) {
|
||||||
|
var vpPoint = this.viewport.pixelFromPointNoRotate(point, true);
|
||||||
|
return new $.Point(
|
||||||
|
vpPoint.x * $.pixelDensityRatio,
|
||||||
|
vpPoint.y * $.pixelDensityRatio
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will create multiple polygon paths on the drawing context by provided polygons,
|
||||||
|
* then clip the context to the paths.
|
||||||
|
* @param {OpenSeadragon.Point[][]} polygons - an array of polygons. A polygon is an array of OpenSeadragon.Point
|
||||||
|
* @param {Boolean} useSketch - Whether to use the sketch canvas or not.
|
||||||
|
*/
|
||||||
|
clipWithPolygons: function (polygons, useSketch) {
|
||||||
|
if (!this.useCanvas) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var context = this._getContext(useSketch);
|
||||||
|
context.beginPath();
|
||||||
|
polygons.forEach(function (polygon) {
|
||||||
|
polygon.forEach(function (coord, i) {
|
||||||
|
context[i === 0 ? 'moveTo' : 'lineTo'](coord.x, coord.y);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
context.clip();
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the opacity of the drawer.
|
* Set the opacity of the drawer.
|
||||||
* @param {Number} opacity
|
* @param {Number} opacity
|
||||||
@ -249,8 +288,8 @@ $.Drawer.prototype = {
|
|||||||
this.canvas.innerHTML = "";
|
this.canvas.innerHTML = "";
|
||||||
if ( this.useCanvas ) {
|
if ( this.useCanvas ) {
|
||||||
var viewportSize = this._calculateCanvasSize();
|
var viewportSize = this._calculateCanvasSize();
|
||||||
if( this.canvas.width != viewportSize.x ||
|
if( this.canvas.width !== viewportSize.x ||
|
||||||
this.canvas.height != viewportSize.y ) {
|
this.canvas.height !== viewportSize.y ) {
|
||||||
this.canvas.width = viewportSize.x;
|
this.canvas.width = viewportSize.x;
|
||||||
this.canvas.height = viewportSize.y;
|
this.canvas.height = viewportSize.y;
|
||||||
this._updateImageSmoothingEnabled(this.context);
|
this._updateImageSmoothingEnabled(this.context);
|
||||||
@ -633,8 +672,6 @@ $.Drawer.prototype = {
|
|||||||
|
|
||||||
// private
|
// private
|
||||||
_updateImageSmoothingEnabled: function(context){
|
_updateImageSmoothingEnabled: function(context){
|
||||||
context.mozImageSmoothingEnabled = this._imageSmoothingEnabled;
|
|
||||||
context.webkitImageSmoothingEnabled = this._imageSmoothingEnabled;
|
|
||||||
context.msImageSmoothingEnabled = this._imageSmoothingEnabled;
|
context.msImageSmoothingEnabled = this._imageSmoothingEnabled;
|
||||||
context.imageSmoothingEnabled = this._imageSmoothingEnabled;
|
context.imageSmoothingEnabled = this._imageSmoothingEnabled;
|
||||||
},
|
},
|
||||||
|
@ -108,7 +108,7 @@ $.extend( $.DziTileSource.prototype, $.TileSource.prototype, /** @lends OpenSead
|
|||||||
if ( data.Image ) {
|
if ( data.Image ) {
|
||||||
ns = data.Image.xmlns;
|
ns = data.Image.xmlns;
|
||||||
} else if ( data.documentElement) {
|
} else if ( data.documentElement) {
|
||||||
if ("Image" == data.documentElement.localName || "Image" == data.documentElement.tagName) {
|
if ("Image" === data.documentElement.localName || "Image" === data.documentElement.tagName) {
|
||||||
ns = data.documentElement.namespaceURI;
|
ns = data.documentElement.namespaceURI;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -142,9 +142,9 @@ $.extend( $.DziTileSource.prototype, $.TileSource.prototype, /** @lends OpenSead
|
|||||||
|
|
||||||
if (url && !options.tilesUrl) {
|
if (url && !options.tilesUrl) {
|
||||||
options.tilesUrl = url.replace(
|
options.tilesUrl = url.replace(
|
||||||
/([^\/]+?)(\.(dzi|xml|js)?(\?[^\/]*)?)?\/?$/, '$1_files/');
|
/([^/]+?)(\.(dzi|xml|js)?(\?[^/]*)?)?\/?$/, '$1_files/');
|
||||||
|
|
||||||
if (url.search(/\.(dzi|xml|js)\?/) != -1) {
|
if (url.search(/\.(dzi|xml|js)\?/) !== -1) {
|
||||||
options.queryParams = url.match(/\?.*/);
|
options.queryParams = url.match(/\?.*/);
|
||||||
}else{
|
}else{
|
||||||
options.queryParams = '';
|
options.queryParams = '';
|
||||||
@ -240,7 +240,7 @@ function configureFromXML( tileSource, xmlDoc ){
|
|||||||
sizeNode,
|
sizeNode,
|
||||||
i;
|
i;
|
||||||
|
|
||||||
if ( rootName == "Image" ) {
|
if ( rootName === "Image" ) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
sizeNode = root.getElementsByTagName("Size" )[ 0 ];
|
sizeNode = root.getElementsByTagName("Size" )[ 0 ];
|
||||||
@ -304,9 +304,9 @@ function configureFromXML( tileSource, xmlDoc ){
|
|||||||
e :
|
e :
|
||||||
new Error( $.getString("Errors.Dzi") );
|
new Error( $.getString("Errors.Dzi") );
|
||||||
}
|
}
|
||||||
} else if ( rootName == "Collection" ) {
|
} else if ( rootName === "Collection" ) {
|
||||||
throw new Error( $.getString( "Errors.Dzc" ) );
|
throw new Error( $.getString( "Errors.Dzc" ) );
|
||||||
} else if ( rootName == "Error" ) {
|
} else if ( rootName === "Error" ) {
|
||||||
var messageNode = root.getElementsByTagName("Message")[0];
|
var messageNode = root.getElementsByTagName("Message")[0];
|
||||||
var message = messageNode.firstChild.nodeValue;
|
var message = messageNode.firstChild.nodeValue;
|
||||||
throw new Error(message);
|
throw new Error(message);
|
||||||
|
@ -59,6 +59,8 @@ $.IIIFTileSource = function( options ){
|
|||||||
|
|
||||||
this.tileFormat = this.tileFormat || 'jpg';
|
this.tileFormat = this.tileFormat || 'jpg';
|
||||||
|
|
||||||
|
this.version = options.version;
|
||||||
|
|
||||||
// N.B. 2.0 renamed scale_factors to scaleFactors
|
// N.B. 2.0 renamed scale_factors to scaleFactors
|
||||||
if ( this.tile_width && this.tile_height ) {
|
if ( this.tile_width && this.tile_height ) {
|
||||||
options.tileWidth = this.tile_width;
|
options.tileWidth = this.tile_width;
|
||||||
@ -69,7 +71,7 @@ $.IIIFTileSource = function( options ){
|
|||||||
options.tileSize = this.tile_height;
|
options.tileSize = this.tile_height;
|
||||||
} else if ( this.tiles ) {
|
} else if ( this.tiles ) {
|
||||||
// Version 2.0 forwards
|
// Version 2.0 forwards
|
||||||
if ( this.tiles.length == 1 ) {
|
if ( this.tiles.length === 1 ) {
|
||||||
options.tileWidth = this.tiles[0].width;
|
options.tileWidth = this.tiles[0].width;
|
||||||
// Use height if provided, otherwise assume square tiles and use width.
|
// Use height if provided, otherwise assume square tiles and use width.
|
||||||
options.tileHeight = this.tiles[0].height || this.tiles[0].width;
|
options.tileHeight = this.tiles[0].height || this.tiles[0].width;
|
||||||
@ -88,7 +90,7 @@ $.IIIFTileSource = function( options ){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if ( canBeTiled(options.profile) ) {
|
} else if ( canBeTiled(options) ) {
|
||||||
// use the largest of tileOptions that is smaller than the short dimension
|
// use the largest of tileOptions that is smaller than the short dimension
|
||||||
var shortDim = Math.min( this.height, this.width ),
|
var shortDim = Math.min( this.height, this.width ),
|
||||||
tileOptions = [256, 512, 1024],
|
tileOptions = [256, 512, 1024],
|
||||||
@ -150,12 +152,12 @@ $.extend( $.IIIFTileSource.prototype, $.TileSource.prototype, /** @lends OpenSea
|
|||||||
|
|
||||||
supports: function( data, url ) {
|
supports: function( data, url ) {
|
||||||
// Version 2.0 and forwards
|
// Version 2.0 and forwards
|
||||||
if (data.protocol && data.protocol == 'http://iiif.io/api/image') {
|
if (data.protocol && data.protocol === 'http://iiif.io/api/image') {
|
||||||
return true;
|
return true;
|
||||||
// Version 1.1
|
// Version 1.1
|
||||||
} else if ( data['@context'] && (
|
} else if ( data['@context'] && (
|
||||||
data['@context'] == "http://library.stanford.edu/iiif/image-api/1.1/context.json" ||
|
data['@context'] === "http://library.stanford.edu/iiif/image-api/1.1/context.json" ||
|
||||||
data['@context'] == "http://iiif.io/api/image/1/context.json") ) {
|
data['@context'] === "http://iiif.io/api/image/1/context.json") ) {
|
||||||
// N.B. the iiif.io context is wrong, but where the representation lives so likely to be used
|
// N.B. the iiif.io context is wrong, but where the representation lives so likely to be used
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@ -166,8 +168,8 @@ $.extend( $.IIIFTileSource.prototype, $.TileSource.prototype, /** @lends OpenSea
|
|||||||
} else if ( data.identifier && data.width && data.height ) {
|
} else if ( data.identifier && data.width && data.height ) {
|
||||||
return true;
|
return true;
|
||||||
} else if ( data.documentElement &&
|
} else if ( data.documentElement &&
|
||||||
"info" == data.documentElement.tagName &&
|
"info" === data.documentElement.tagName &&
|
||||||
"http://library.stanford.edu/iiif/image-api/ns/" ==
|
"http://library.stanford.edu/iiif/image-api/ns/" ===
|
||||||
data.documentElement.namespaceURI) {
|
data.documentElement.namespaceURI) {
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@ -201,11 +203,42 @@ $.extend( $.IIIFTileSource.prototype, $.TileSource.prototype, /** @lends OpenSea
|
|||||||
var options = configureFromXml10( data );
|
var options = configureFromXml10( data );
|
||||||
options['@context'] = "http://iiif.io/api/image/1.0/context.json";
|
options['@context'] = "http://iiif.io/api/image/1.0/context.json";
|
||||||
options['@id'] = url.replace('/info.xml', '');
|
options['@id'] = url.replace('/info.xml', '');
|
||||||
|
options.version = 1;
|
||||||
return options;
|
return options;
|
||||||
} else {
|
} else {
|
||||||
if ( !data['@context'] ) {
|
if ( !data['@context'] ) {
|
||||||
data['@context'] = 'http://iiif.io/api/image/1.0/context.json';
|
data['@context'] = 'http://iiif.io/api/image/1.0/context.json';
|
||||||
data['@id'] = url.replace('/info.json', '');
|
data['@id'] = url.replace('/info.json', '');
|
||||||
|
data.version = 1;
|
||||||
|
} else {
|
||||||
|
var context = data['@context'];
|
||||||
|
if (Array.isArray(context)) {
|
||||||
|
for (var i = 0; i < context.length; i++) {
|
||||||
|
if (typeof context[i] === 'string' &&
|
||||||
|
( /^http:\/\/iiif\.io\/api\/image\/[1-3]\/context\.json$/.test(context[i]) ||
|
||||||
|
context[i] === 'http://library.stanford.edu/iiif/image-api/1.1/context.json' ) ) {
|
||||||
|
context = context[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch (context) {
|
||||||
|
case 'http://iiif.io/api/image/1/context.json':
|
||||||
|
case 'http://library.stanford.edu/iiif/image-api/1.1/context.json':
|
||||||
|
data.version = 1;
|
||||||
|
break;
|
||||||
|
case 'http://iiif.io/api/image/2/context.json':
|
||||||
|
data.version = 2;
|
||||||
|
break;
|
||||||
|
case 'http://iiif.io/api/image/3/context.json':
|
||||||
|
data.version = 3;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$.console.error('Data has a @context property which contains no known IIIF context URI.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( !data['@id'] && data['id'] ) {
|
||||||
|
data['@id'] = data['id'];
|
||||||
}
|
}
|
||||||
if(data.preferredFormats) {
|
if(data.preferredFormats) {
|
||||||
for (var f = 0; f < data.preferredFormats.length; f++ ) {
|
for (var f = 0; f < data.preferredFormats.length; f++ ) {
|
||||||
@ -350,27 +383,28 @@ $.extend( $.IIIFTileSource.prototype, $.TileSource.prototype, /** @lends OpenSea
|
|||||||
iiifTileH,
|
iiifTileH,
|
||||||
iiifSize,
|
iiifSize,
|
||||||
iiifSizeW,
|
iiifSizeW,
|
||||||
|
iiifSizeH,
|
||||||
iiifQuality,
|
iiifQuality,
|
||||||
uri,
|
uri;
|
||||||
isv1;
|
|
||||||
|
|
||||||
tileWidth = this.getTileWidth(level);
|
tileWidth = this.getTileWidth(level);
|
||||||
tileHeight = this.getTileHeight(level);
|
tileHeight = this.getTileHeight(level);
|
||||||
iiifTileSizeWidth = Math.ceil( tileWidth / scale );
|
iiifTileSizeWidth = Math.ceil( tileWidth / scale );
|
||||||
iiifTileSizeHeight = Math.ceil( tileHeight / scale );
|
iiifTileSizeHeight = Math.ceil( tileHeight / scale );
|
||||||
isv1 = ( this['@context'].indexOf('/1.0/context.json') > -1 ||
|
if (this.version === 1) {
|
||||||
this['@context'].indexOf('/1.1/context.json') > -1 ||
|
|
||||||
this['@context'].indexOf('/1/context.json') > -1 );
|
|
||||||
if (isv1) {
|
|
||||||
iiifQuality = "native." + this.tileFormat;
|
iiifQuality = "native." + this.tileFormat;
|
||||||
} else {
|
} else {
|
||||||
iiifQuality = "default." + this.tileFormat;
|
iiifQuality = "default." + this.tileFormat;
|
||||||
}
|
}
|
||||||
if ( levelWidth < tileWidth && levelHeight < tileHeight ){
|
if ( levelWidth < tileWidth && levelHeight < tileHeight ){
|
||||||
if ( isv1 || levelWidth !== this.width ) {
|
if ( this.version === 2 && levelWidth === this.width ) {
|
||||||
iiifSize = levelWidth + ",";
|
iiifSize = "full";
|
||||||
} else {
|
} else if ( this.version === 3 && levelWidth === this.width && levelHeight === this.height ) {
|
||||||
iiifSize = "max";
|
iiifSize = "max";
|
||||||
|
} else if ( this.version === 3 ) {
|
||||||
|
iiifSize = levelWidth + "," + levelHeight;
|
||||||
|
} else {
|
||||||
|
iiifSize = levelWidth + ",";
|
||||||
}
|
}
|
||||||
iiifRegion = 'full';
|
iiifRegion = 'full';
|
||||||
} else {
|
} else {
|
||||||
@ -384,8 +418,13 @@ $.extend( $.IIIFTileSource.prototype, $.TileSource.prototype, /** @lends OpenSea
|
|||||||
iiifRegion = [ iiifTileX, iiifTileY, iiifTileW, iiifTileH ].join( ',' );
|
iiifRegion = [ iiifTileX, iiifTileY, iiifTileW, iiifTileH ].join( ',' );
|
||||||
}
|
}
|
||||||
iiifSizeW = Math.ceil( iiifTileW * scale );
|
iiifSizeW = Math.ceil( iiifTileW * scale );
|
||||||
if ( (!isv1) && iiifSizeW === this.width ) {
|
iiifSizeH = Math.ceil( iiifTileH * scale );
|
||||||
|
if ( this.version === 2 && iiifSizeW === this.width ) {
|
||||||
|
iiifSize = "full";
|
||||||
|
} else if ( this.version === 3 && iiifSizeW === this.width && iiifSizeH === this.height ) {
|
||||||
iiifSize = "max";
|
iiifSize = "max";
|
||||||
|
} else if (this.version === 3) {
|
||||||
|
iiifSize = iiifSizeW + "," + iiifSizeH;
|
||||||
} else {
|
} else {
|
||||||
iiifSize = iiifSizeW + ",";
|
iiifSize = iiifSizeW + ",";
|
||||||
}
|
}
|
||||||
@ -393,6 +432,11 @@ $.extend( $.IIIFTileSource.prototype, $.TileSource.prototype, /** @lends OpenSea
|
|||||||
uri = [ this['@id'], iiifRegion, iiifSize, IIIF_ROTATION, iiifQuality ].join( '/' );
|
uri = [ this['@id'], iiifRegion, iiifSize, IIIF_ROTATION, iiifQuality ].join( '/' );
|
||||||
|
|
||||||
return uri;
|
return uri;
|
||||||
|
},
|
||||||
|
|
||||||
|
__testonly__: {
|
||||||
|
canBeTiled: canBeTiled,
|
||||||
|
constructLevels: constructLevels
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
@ -403,18 +447,24 @@ $.extend( $.IIIFTileSource.prototype, $.TileSource.prototype, /** @lends OpenSea
|
|||||||
* @param {array} profile - IIIF profile array
|
* @param {array} profile - IIIF profile array
|
||||||
* @throws {Error}
|
* @throws {Error}
|
||||||
*/
|
*/
|
||||||
function canBeTiled ( profile ) {
|
function canBeTiled ( options ) {
|
||||||
var level0Profiles = [
|
var level0Profiles = [
|
||||||
"http://library.stanford.edu/iiif/image-api/compliance.html#level0",
|
"http://library.stanford.edu/iiif/image-api/compliance.html#level0",
|
||||||
"http://library.stanford.edu/iiif/image-api/1.1/compliance.html#level0",
|
"http://library.stanford.edu/iiif/image-api/1.1/compliance.html#level0",
|
||||||
"http://iiif.io/api/image/2/level0.json"
|
"http://iiif.io/api/image/2/level0.json",
|
||||||
|
"level0",
|
||||||
|
"https://iiif.io/api/image/3/level0.json"
|
||||||
];
|
];
|
||||||
var isLevel0 = (level0Profiles.indexOf(profile[0]) !== -1);
|
var profileLevel = Array.isArray(options.profile) ? options.profile[0] : options.profile;
|
||||||
var hasSizeByW = false;
|
var isLevel0 = (level0Profiles.indexOf(profileLevel) !== -1);
|
||||||
if ( profile.length > 1 && profile[1].supports ) {
|
var hasCanoncicalSizeFeature = false;
|
||||||
hasSizeByW = profile[1].supports.indexOf( "sizeByW" ) !== -1;
|
if ( options.version === 2 && options.profile.length > 1 && options.profile[1].supports ) {
|
||||||
|
hasCanoncicalSizeFeature = options.profile[1].supports.indexOf( "sizeByW" ) !== -1;
|
||||||
}
|
}
|
||||||
return !isLevel0 || hasSizeByW;
|
if ( options.version === 3 && options.extraFeatures ) {
|
||||||
|
hasCanoncicalSizeFeature = options.extraFeatures.indexOf( "sizeByWh" ) !== -1;
|
||||||
|
}
|
||||||
|
return !isLevel0 || hasCanoncicalSizeFeature;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -427,7 +477,9 @@ $.extend( $.IIIFTileSource.prototype, $.TileSource.prototype, /** @lends OpenSea
|
|||||||
var levels = [];
|
var levels = [];
|
||||||
for(var i = 0; i < options.sizes.length; i++) {
|
for(var i = 0; i < options.sizes.length; i++) {
|
||||||
levels.push({
|
levels.push({
|
||||||
url: options['@id'] + '/full/' + options.sizes[i].width + ',/0/default.' + options.tileFormat,
|
url: options['@id'] + '/full/' + options.sizes[i].width + ',' +
|
||||||
|
(options.version === 3 ? options.sizes[i].height : '') +
|
||||||
|
'/0/default.' + options.tileFormat,
|
||||||
width: options.sizes[i].width,
|
width: options.sizes[i].width,
|
||||||
height: options.sizes[i].height
|
height: options.sizes[i].height
|
||||||
});
|
});
|
||||||
@ -448,7 +500,7 @@ $.extend( $.IIIFTileSource.prototype, $.TileSource.prototype, /** @lends OpenSea
|
|||||||
rootName = root.tagName,
|
rootName = root.tagName,
|
||||||
configuration = null;
|
configuration = null;
|
||||||
|
|
||||||
if ( rootName == "info" ) {
|
if ( rootName === "info" ) {
|
||||||
try {
|
try {
|
||||||
configuration = {};
|
configuration = {};
|
||||||
parseXML10( root, configuration );
|
parseXML10( root, configuration );
|
||||||
@ -466,7 +518,7 @@ $.extend( $.IIIFTileSource.prototype, $.TileSource.prototype, /** @lends OpenSea
|
|||||||
function parseXML10( node, configuration, property ) {
|
function parseXML10( node, configuration, property ) {
|
||||||
var i,
|
var i,
|
||||||
value;
|
value;
|
||||||
if ( node.nodeType == 3 && property ) {//text node
|
if ( node.nodeType === 3 && property ) {//text node
|
||||||
value = node.nodeValue.trim();
|
value = node.nodeValue.trim();
|
||||||
if( value.match(/^\d*$/)){
|
if( value.match(/^\d*$/)){
|
||||||
value = Number( value );
|
value = Number( value );
|
||||||
@ -479,7 +531,7 @@ $.extend( $.IIIFTileSource.prototype, $.TileSource.prototype, /** @lends OpenSea
|
|||||||
}
|
}
|
||||||
configuration[ property ].push( value );
|
configuration[ property ].push( value );
|
||||||
}
|
}
|
||||||
} else if( node.nodeType == 1 ){
|
} else if( node.nodeType === 1 ){
|
||||||
for( i = 0; i < node.childNodes.length; i++ ){
|
for( i = 0; i < node.childNodes.length; i++ ){
|
||||||
parseXML10( node.childNodes[ i ], configuration, node.nodeName );
|
parseXML10( node.childNodes[ i ], configuration, node.nodeName );
|
||||||
}
|
}
|
||||||
|
@ -114,9 +114,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
$.addEvent(image, 'load', function () {
|
$.addEvent(image, 'load', function () {
|
||||||
/* IE8 fix since it has no naturalWidth and naturalHeight */
|
_this.width = image.naturalWidth;
|
||||||
_this.width = Object.prototype.hasOwnProperty.call(image, 'naturalWidth') ? image.naturalWidth : image.width;
|
_this.height = image.naturalHeight;
|
||||||
_this.height = Object.prototype.hasOwnProperty.call(image, 'naturalHeight') ? image.naturalHeight : image.height;
|
|
||||||
_this.aspectRatio = _this.width / _this.height;
|
_this.aspectRatio = _this.width / _this.height;
|
||||||
_this.dimensions = new $.Point(_this.width, _this.height);
|
_this.dimensions = new $.Point(_this.width, _this.height);
|
||||||
_this._tileWidth = _this.width;
|
_this._tileWidth = _this.width;
|
||||||
@ -195,6 +194,13 @@
|
|||||||
}
|
}
|
||||||
return context;
|
return context;
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* Destroys ImageTileSource
|
||||||
|
* @function
|
||||||
|
*/
|
||||||
|
destroy: function () {
|
||||||
|
this._freeupCanvasMemory();
|
||||||
|
},
|
||||||
|
|
||||||
// private
|
// private
|
||||||
//
|
//
|
||||||
@ -203,9 +209,8 @@
|
|||||||
_buildLevels: function () {
|
_buildLevels: function () {
|
||||||
var levels = [{
|
var levels = [{
|
||||||
url: this._image.src,
|
url: this._image.src,
|
||||||
/* IE8 fix since it has no naturalWidth and naturalHeight */
|
width: this._image.naturalWidth,
|
||||||
width: Object.prototype.hasOwnProperty.call(this._image, 'naturalWidth') ? this._image.naturalWidth : this._image.width,
|
height: this._image.naturalHeight
|
||||||
height: Object.prototype.hasOwnProperty.call(this._image, 'naturalHeight') ? this._image.naturalHeight : this._image.height
|
|
||||||
}];
|
}];
|
||||||
|
|
||||||
if (!this.buildPyramid || !$.supportsCanvas || !this.useCanvas) {
|
if (!this.buildPyramid || !$.supportsCanvas || !this.useCanvas) {
|
||||||
@ -214,9 +219,8 @@
|
|||||||
return levels;
|
return levels;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* IE8 fix since it has no naturalWidth and naturalHeight */
|
var currentWidth = this._image.naturalWidth;
|
||||||
var currentWidth = Object.prototype.hasOwnProperty.call(this._image, 'naturalWidth') ? this._image.naturalWidth : this._image.width;
|
var currentHeight = this._image.naturalHeight;
|
||||||
var currentHeight = Object.prototype.hasOwnProperty.call(this._image, 'naturalHeight') ? this._image.naturalHeight : this._image.height;
|
|
||||||
|
|
||||||
|
|
||||||
var bigCanvas = document.createElement("canvas");
|
var bigCanvas = document.createElement("canvas");
|
||||||
@ -258,7 +262,19 @@
|
|||||||
bigContext = smallContext;
|
bigContext = smallContext;
|
||||||
}
|
}
|
||||||
return levels;
|
return levels;
|
||||||
}
|
},
|
||||||
|
/**
|
||||||
|
* Free up canvas memory
|
||||||
|
* (iOS 12 or higher on 2GB RAM device has only 224MB canvas memory,
|
||||||
|
* and Safari keeps canvas until its height and width will be set to 0).
|
||||||
|
* @function
|
||||||
|
*/
|
||||||
|
_freeupCanvasMemory: function () {
|
||||||
|
for (var i = 0; i < this.levels.length; i++) {
|
||||||
|
this.levels[i].context2D.canvas.height = 0;
|
||||||
|
this.levels[i].context2D.canvas.width = 0;
|
||||||
|
}
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
}(OpenSeadragon));
|
}(OpenSeadragon));
|
||||||
|
@ -109,10 +109,10 @@ $.extend( $.LegacyTileSource.prototype, $.TileSource.prototype, /** @lends OpenS
|
|||||||
supports: function( data, url ){
|
supports: function( data, url ){
|
||||||
return (
|
return (
|
||||||
data.type &&
|
data.type &&
|
||||||
"legacy-image-pyramid" == data.type
|
"legacy-image-pyramid" === data.type
|
||||||
) || (
|
) || (
|
||||||
data.documentElement &&
|
data.documentElement &&
|
||||||
"legacy-image-pyramid" == data.documentElement.getAttribute('type')
|
"legacy-image-pyramid" === data.documentElement.getAttribute('type')
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -241,7 +241,7 @@ function configureFromXML( tileSource, xmlDoc ){
|
|||||||
level,
|
level,
|
||||||
i;
|
i;
|
||||||
|
|
||||||
if ( rootName == "image" ) {
|
if ( rootName === "image" ) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
conf = {
|
conf = {
|
||||||
@ -267,9 +267,9 @@ function configureFromXML( tileSource, xmlDoc ){
|
|||||||
e :
|
e :
|
||||||
new Error( 'Unknown error parsing Legacy Image Pyramid XML.' );
|
new Error( 'Unknown error parsing Legacy Image Pyramid XML.' );
|
||||||
}
|
}
|
||||||
} else if ( rootName == "collection" ) {
|
} else if ( rootName === "collection" ) {
|
||||||
throw new Error( 'Legacy Image Pyramid Collections not yet supported.' );
|
throw new Error( 'Legacy Image Pyramid Collections not yet supported.' );
|
||||||
} else if ( rootName == "error" ) {
|
} else if ( rootName === "error" ) {
|
||||||
throw new Error( 'Error: ' + xmlDoc );
|
throw new Error( 'Error: ' + xmlDoc );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
3069
src/mousetracker.js
3069
src/mousetracker.js
File diff suppressed because it is too large
Load Diff
@ -66,15 +66,15 @@ $.Navigator = function( options ){
|
|||||||
};
|
};
|
||||||
|
|
||||||
if( options.position ){
|
if( options.position ){
|
||||||
if( 'BOTTOM_RIGHT' == options.position ){
|
if( 'BOTTOM_RIGHT' === options.position ){
|
||||||
options.controlOptions.anchor = $.ControlAnchor.BOTTOM_RIGHT;
|
options.controlOptions.anchor = $.ControlAnchor.BOTTOM_RIGHT;
|
||||||
} else if( 'BOTTOM_LEFT' == options.position ){
|
} else if( 'BOTTOM_LEFT' === options.position ){
|
||||||
options.controlOptions.anchor = $.ControlAnchor.BOTTOM_LEFT;
|
options.controlOptions.anchor = $.ControlAnchor.BOTTOM_LEFT;
|
||||||
} else if( 'TOP_RIGHT' == options.position ){
|
} else if( 'TOP_RIGHT' === options.position ){
|
||||||
options.controlOptions.anchor = $.ControlAnchor.TOP_RIGHT;
|
options.controlOptions.anchor = $.ControlAnchor.TOP_RIGHT;
|
||||||
} else if( 'TOP_LEFT' == options.position ){
|
} else if( 'TOP_LEFT' === options.position ){
|
||||||
options.controlOptions.anchor = $.ControlAnchor.TOP_LEFT;
|
options.controlOptions.anchor = $.ControlAnchor.TOP_LEFT;
|
||||||
} else if( 'ABSOLUTE' == options.position ){
|
} else if( 'ABSOLUTE' === options.position ){
|
||||||
options.controlOptions.anchor = $.ControlAnchor.ABSOLUTE;
|
options.controlOptions.anchor = $.ControlAnchor.ABSOLUTE;
|
||||||
options.controlOptions.top = options.top;
|
options.controlOptions.top = options.top;
|
||||||
options.controlOptions.left = options.left;
|
options.controlOptions.left = options.left;
|
||||||
@ -128,7 +128,7 @@ $.Navigator = function( options ){
|
|||||||
this.totalBorderWidths = new $.Point(this.borderWidth * 2, this.borderWidth * 2).minus(this.fudge);
|
this.totalBorderWidths = new $.Point(this.borderWidth * 2, this.borderWidth * 2).minus(this.fudge);
|
||||||
|
|
||||||
|
|
||||||
if ( options.controlOptions.anchor != $.ControlAnchor.NONE ) {
|
if ( options.controlOptions.anchor !== $.ControlAnchor.NONE ) {
|
||||||
(function( style, borderWidth ){
|
(function( style, borderWidth ){
|
||||||
style.margin = '0px';
|
style.margin = '0px';
|
||||||
style.border = borderWidth + 'px solid ' + options.borderColor;
|
style.border = borderWidth + 'px solid ' + options.borderColor;
|
||||||
@ -167,20 +167,24 @@ $.Navigator = function( options ){
|
|||||||
style.zIndex = 999999999;
|
style.zIndex = 999999999;
|
||||||
style.cursor = 'default';
|
style.cursor = 'default';
|
||||||
}( this.displayRegion.style, this.borderWidth ));
|
}( this.displayRegion.style, this.borderWidth ));
|
||||||
|
$.setElementPointerEventsNone( this.displayRegion );
|
||||||
|
$.setElementTouchActionNone( this.displayRegion );
|
||||||
|
|
||||||
this.displayRegionContainer = $.makeNeutralElement("div");
|
this.displayRegionContainer = $.makeNeutralElement("div");
|
||||||
this.displayRegionContainer.id = this.element.id + '-displayregioncontainer';
|
this.displayRegionContainer.id = this.element.id + '-displayregioncontainer';
|
||||||
this.displayRegionContainer.className = "displayregioncontainer";
|
this.displayRegionContainer.className = "displayregioncontainer";
|
||||||
this.displayRegionContainer.style.width = "100%";
|
this.displayRegionContainer.style.width = "100%";
|
||||||
this.displayRegionContainer.style.height = "100%";
|
this.displayRegionContainer.style.height = "100%";
|
||||||
|
$.setElementPointerEventsNone( this.displayRegionContainer );
|
||||||
|
$.setElementTouchActionNone( this.displayRegionContainer );
|
||||||
|
|
||||||
viewer.addControl(
|
viewer.addControl(
|
||||||
this.element,
|
this.element,
|
||||||
options.controlOptions
|
options.controlOptions
|
||||||
);
|
);
|
||||||
|
|
||||||
this._resizeWithViewer = options.controlOptions.anchor != $.ControlAnchor.ABSOLUTE &&
|
this._resizeWithViewer = options.controlOptions.anchor !== $.ControlAnchor.ABSOLUTE &&
|
||||||
options.controlOptions.anchor != $.ControlAnchor.NONE;
|
options.controlOptions.anchor !== $.ControlAnchor.NONE;
|
||||||
|
|
||||||
if (options.width && options.height) {
|
if (options.width && options.height) {
|
||||||
this.setWidth(options.width);
|
this.setWidth(options.width);
|
||||||
@ -221,12 +225,29 @@ $.Navigator = function( options ){
|
|||||||
// Remove the base class' (Viewer's) innerTracker and replace it with our own
|
// Remove the base class' (Viewer's) innerTracker and replace it with our own
|
||||||
this.innerTracker.destroy();
|
this.innerTracker.destroy();
|
||||||
this.innerTracker = new $.MouseTracker({
|
this.innerTracker = new $.MouseTracker({
|
||||||
element: this.element,
|
userData: 'Navigator.innerTracker',
|
||||||
|
element: this.element, //this.canvas,
|
||||||
dragHandler: $.delegate( this, onCanvasDrag ),
|
dragHandler: $.delegate( this, onCanvasDrag ),
|
||||||
clickHandler: $.delegate( this, onCanvasClick ),
|
clickHandler: $.delegate( this, onCanvasClick ),
|
||||||
releaseHandler: $.delegate( this, onCanvasRelease ),
|
releaseHandler: $.delegate( this, onCanvasRelease ),
|
||||||
scrollHandler: $.delegate( this, onCanvasScroll )
|
scrollHandler: $.delegate( this, onCanvasScroll ),
|
||||||
|
preProcessEventHandler: function (eventInfo) {
|
||||||
|
if (eventInfo.eventType === 'wheel') {
|
||||||
|
//don't scroll the page up and down if the user is scrolling
|
||||||
|
//in the navigator
|
||||||
|
eventInfo.preventDefault = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
this.outerTracker.userData = 'Navigator.outerTracker';
|
||||||
|
|
||||||
|
// this.innerTracker is attached to this.element...we need to allow pointer
|
||||||
|
// events to pass through this Viewer's canvas/container elements so implicit
|
||||||
|
// pointer capture works on touch devices
|
||||||
|
//TODO an alternative is to attach the new MouseTracker to this.canvas...not
|
||||||
|
// sure why it isn't already (see MouseTracker constructor call above)
|
||||||
|
$.setElementPointerEventsNone( this.canvas );
|
||||||
|
$.setElementPointerEventsNone( this.container );
|
||||||
|
|
||||||
this.addHandler("reset-size", function() {
|
this.addHandler("reset-size", function() {
|
||||||
if (_this.viewport) {
|
if (_this.viewport) {
|
||||||
@ -282,7 +303,7 @@ $.extend( $.Navigator.prototype, $.EventSource.prototype, $.Viewer.prototype, /*
|
|||||||
*/
|
*/
|
||||||
setWidth: function(width) {
|
setWidth: function(width) {
|
||||||
this.width = width;
|
this.width = width;
|
||||||
this.element.style.width = typeof (width) == "number" ? (width + 'px') : width;
|
this.element.style.width = typeof (width) === "number" ? (width + 'px') : width;
|
||||||
this._resizeWithViewer = false;
|
this._resizeWithViewer = false;
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -292,7 +313,7 @@ $.extend( $.Navigator.prototype, $.EventSource.prototype, $.Viewer.prototype, /*
|
|||||||
*/
|
*/
|
||||||
setHeight: function(height) {
|
setHeight: function(height) {
|
||||||
this.height = height;
|
this.height = height;
|
||||||
this.element.style.height = typeof (height) == "number" ? (height + 'px') : height;
|
this.element.style.height = typeof (height) === "number" ? (height + 'px') : height;
|
||||||
this._resizeWithViewer = false;
|
this._resizeWithViewer = false;
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -383,6 +404,8 @@ $.extend( $.Navigator.prototype, $.EventSource.prototype, $.Viewer.prototype, /*
|
|||||||
var myItem = event.item;
|
var myItem = event.item;
|
||||||
myItem._originalForNavigator = original;
|
myItem._originalForNavigator = original;
|
||||||
_this._matchBounds(myItem, original, true);
|
_this._matchBounds(myItem, original, true);
|
||||||
|
_this._matchOpacity(myItem, original);
|
||||||
|
_this._matchCompositeOperation(myItem, original);
|
||||||
|
|
||||||
function matchBounds() {
|
function matchBounds() {
|
||||||
_this._matchBounds(myItem, original);
|
_this._matchBounds(myItem, original);
|
||||||
@ -406,6 +429,10 @@ $.extend( $.Navigator.prototype, $.EventSource.prototype, $.Viewer.prototype, /*
|
|||||||
return $.Viewer.prototype.addTiledImage.apply(this, [optionsClone]);
|
return $.Viewer.prototype.addTiledImage.apply(this, [optionsClone]);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
destroy: function() {
|
||||||
|
return $.Viewer.prototype.destroy.apply(this);
|
||||||
|
},
|
||||||
|
|
||||||
// private
|
// private
|
||||||
_getMatchingItem: function(theirItem) {
|
_getMatchingItem: function(theirItem) {
|
||||||
var count = this.world.getItemCount();
|
var count = this.world.getItemCount();
|
||||||
@ -427,6 +454,7 @@ $.extend( $.Navigator.prototype, $.EventSource.prototype, $.Viewer.prototype, /*
|
|||||||
myItem.setWidth(bounds.width, immediately);
|
myItem.setWidth(bounds.width, immediately);
|
||||||
myItem.setRotation(theirItem.getRotation(), immediately);
|
myItem.setRotation(theirItem.getRotation(), immediately);
|
||||||
myItem.setClip(theirItem.getClip());
|
myItem.setClip(theirItem.getClip());
|
||||||
|
myItem.setFlip(theirItem.getFlip());
|
||||||
},
|
},
|
||||||
|
|
||||||
// private
|
// private
|
||||||
@ -453,7 +481,7 @@ function onCanvasClick( event ) {
|
|||||||
quick: event.quick,
|
quick: event.quick,
|
||||||
shift: event.shift,
|
shift: event.shift,
|
||||||
originalEvent: event.originalEvent,
|
originalEvent: event.originalEvent,
|
||||||
preventDefaultAction: event.preventDefaultAction
|
preventDefaultAction: false
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* Raised when a click event occurs on the {@link OpenSeadragon.Viewer#navigator} element.
|
* Raised when a click event occurs on the {@link OpenSeadragon.Viewer#navigator} element.
|
||||||
@ -505,7 +533,7 @@ function onCanvasDrag( event ) {
|
|||||||
direction: event.direction,
|
direction: event.direction,
|
||||||
shift: event.shift,
|
shift: event.shift,
|
||||||
originalEvent: event.originalEvent,
|
originalEvent: event.originalEvent,
|
||||||
preventDefaultAction: event.preventDefaultAction
|
preventDefaultAction: false
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* Raised when a drag event occurs on the {@link OpenSeadragon.Viewer#navigator} element.
|
* Raised when a drag event occurs on the {@link OpenSeadragon.Viewer#navigator} element.
|
||||||
@ -522,7 +550,7 @@ function onCanvasDrag( event ) {
|
|||||||
* @property {Boolean} shift - True if the shift key was pressed during this event.
|
* @property {Boolean} shift - True if the shift key was pressed during this event.
|
||||||
* @property {Object} originalEvent - The original DOM event.
|
* @property {Object} originalEvent - The original DOM event.
|
||||||
* @property {?Object} userData - Arbitrary subscriber-defined object.
|
* @property {?Object} userData - Arbitrary subscriber-defined object.
|
||||||
* @property {Boolean} preventDefaultAction - Set to true to prevent default click to zoom behaviour. Default: false.
|
* @property {Boolean} preventDefaultAction - Set to true to prevent default drag to pan behaviour. Default: false.
|
||||||
*/
|
*/
|
||||||
this.viewer.raiseEvent('navigator-drag', canvasDragEventArgs);
|
this.viewer.raiseEvent('navigator-drag', canvasDragEventArgs);
|
||||||
|
|
||||||
@ -568,6 +596,15 @@ function onCanvasRelease( event ) {
|
|||||||
* @function
|
* @function
|
||||||
*/
|
*/
|
||||||
function onCanvasScroll( event ) {
|
function onCanvasScroll( event ) {
|
||||||
|
var eventArgs = {
|
||||||
|
tracker: event.eventSource,
|
||||||
|
position: event.position,
|
||||||
|
scroll: event.scroll,
|
||||||
|
shift: event.shift,
|
||||||
|
originalEvent: event.originalEvent,
|
||||||
|
preventDefault: event.preventDefault
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Raised when a scroll event occurs on the {@link OpenSeadragon.Viewer#navigator} element (mouse wheel, touch pinch, etc.).
|
* Raised when a scroll event occurs on the {@link OpenSeadragon.Viewer#navigator} element (mouse wheel, touch pinch, etc.).
|
||||||
*
|
*
|
||||||
@ -580,19 +617,12 @@ function onCanvasScroll( event ) {
|
|||||||
* @property {Number} scroll - The scroll delta for the event.
|
* @property {Number} scroll - The scroll delta for the event.
|
||||||
* @property {Boolean} shift - True if the shift key was pressed during this event.
|
* @property {Boolean} shift - True if the shift key was pressed during this event.
|
||||||
* @property {Object} originalEvent - The original DOM event.
|
* @property {Object} originalEvent - The original DOM event.
|
||||||
|
* @property {Boolean} preventDefault - Set to true to prevent the default user-agent's handling of the wheel event.
|
||||||
* @property {?Object} userData - Arbitrary subscriber-defined object.
|
* @property {?Object} userData - Arbitrary subscriber-defined object.
|
||||||
*/
|
*/
|
||||||
this.viewer.raiseEvent( 'navigator-scroll', {
|
this.viewer.raiseEvent( 'navigator-scroll', eventArgs );
|
||||||
tracker: event.eventSource,
|
|
||||||
position: event.position,
|
|
||||||
scroll: event.scroll,
|
|
||||||
shift: event.shift,
|
|
||||||
originalEvent: event.originalEvent
|
|
||||||
});
|
|
||||||
|
|
||||||
//don't scroll the page up and down if the user is scrolling
|
event.preventDefault = eventArgs.preventDefault;
|
||||||
//in the navigator
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -195,8 +195,9 @@
|
|||||||
*
|
*
|
||||||
* @property {String} [compositeOperation=null]
|
* @property {String} [compositeOperation=null]
|
||||||
* Valid values are 'source-over', 'source-atop', 'source-in', 'source-out',
|
* Valid values are 'source-over', 'source-atop', 'source-in', 'source-out',
|
||||||
* 'destination-over', 'destination-atop', 'destination-in',
|
* 'destination-over', 'destination-atop', 'destination-in', 'destination-out',
|
||||||
* 'destination-out', 'lighter', 'copy' or 'xor'
|
* 'lighter', 'difference', 'copy', 'xor', etc.
|
||||||
|
* For complete list of modes, please @see {@link https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation/ globalCompositeOperation}
|
||||||
*
|
*
|
||||||
* @property {Boolean} [imageSmoothingEnabled=true]
|
* @property {Boolean} [imageSmoothingEnabled=true]
|
||||||
* Image smoothing for canvas rendering (only if canvas is used). Note: Ignored
|
* Image smoothing for canvas rendering (only if canvas is used). Note: Ignored
|
||||||
@ -320,6 +321,7 @@
|
|||||||
*
|
*
|
||||||
* @property {OpenSeadragon.GestureSettings} [gestureSettingsMouse]
|
* @property {OpenSeadragon.GestureSettings} [gestureSettingsMouse]
|
||||||
* Settings for gestures generated by a mouse pointer device. (See {@link OpenSeadragon.GestureSettings})
|
* Settings for gestures generated by a mouse pointer device. (See {@link OpenSeadragon.GestureSettings})
|
||||||
|
* @property {Boolean} [gestureSettingsMouse.dragToPan=true] - Pan on drag gesture
|
||||||
* @property {Boolean} [gestureSettingsMouse.scrollToZoom=true] - Zoom on scroll gesture
|
* @property {Boolean} [gestureSettingsMouse.scrollToZoom=true] - Zoom on scroll gesture
|
||||||
* @property {Boolean} [gestureSettingsMouse.clickToZoom=true] - Zoom on click gesture
|
* @property {Boolean} [gestureSettingsMouse.clickToZoom=true] - Zoom on click gesture
|
||||||
* @property {Boolean} [gestureSettingsMouse.dblClickToZoom=false] - Zoom on double-click gesture. Note: If set to true
|
* @property {Boolean} [gestureSettingsMouse.dblClickToZoom=false] - Zoom on double-click gesture. Note: If set to true
|
||||||
@ -334,6 +336,7 @@
|
|||||||
*
|
*
|
||||||
* @property {OpenSeadragon.GestureSettings} [gestureSettingsTouch]
|
* @property {OpenSeadragon.GestureSettings} [gestureSettingsTouch]
|
||||||
* Settings for gestures generated by a touch pointer device. (See {@link OpenSeadragon.GestureSettings})
|
* Settings for gestures generated by a touch pointer device. (See {@link OpenSeadragon.GestureSettings})
|
||||||
|
* @property {Boolean} [gestureSettingsMouse.dragToPan=true] - Pan on drag gesture
|
||||||
* @property {Boolean} [gestureSettingsTouch.scrollToZoom=false] - Zoom on scroll gesture
|
* @property {Boolean} [gestureSettingsTouch.scrollToZoom=false] - Zoom on scroll gesture
|
||||||
* @property {Boolean} [gestureSettingsTouch.clickToZoom=false] - Zoom on click gesture
|
* @property {Boolean} [gestureSettingsTouch.clickToZoom=false] - Zoom on click gesture
|
||||||
* @property {Boolean} [gestureSettingsTouch.dblClickToZoom=true] - Zoom on double-click gesture. Note: If set to true
|
* @property {Boolean} [gestureSettingsTouch.dblClickToZoom=true] - Zoom on double-click gesture. Note: If set to true
|
||||||
@ -348,12 +351,13 @@
|
|||||||
*
|
*
|
||||||
* @property {OpenSeadragon.GestureSettings} [gestureSettingsPen]
|
* @property {OpenSeadragon.GestureSettings} [gestureSettingsPen]
|
||||||
* Settings for gestures generated by a pen pointer device. (See {@link OpenSeadragon.GestureSettings})
|
* Settings for gestures generated by a pen pointer device. (See {@link OpenSeadragon.GestureSettings})
|
||||||
|
* @property {Boolean} [gestureSettingsMouse.dragToPan=true] - Pan on drag gesture
|
||||||
* @property {Boolean} [gestureSettingsPen.scrollToZoom=false] - Zoom on scroll gesture
|
* @property {Boolean} [gestureSettingsPen.scrollToZoom=false] - Zoom on scroll gesture
|
||||||
* @property {Boolean} [gestureSettingsPen.clickToZoom=true] - Zoom on click gesture
|
* @property {Boolean} [gestureSettingsPen.clickToZoom=true] - Zoom on click gesture
|
||||||
* @property {Boolean} [gestureSettingsPen.dblClickToZoom=false] - Zoom on double-click gesture. Note: If set to true
|
* @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.
|
* then clickToZoom should be set to false to prevent multiple zooms.
|
||||||
* @property {Boolean} [gestureSettingsPen.pinchToZoom=false] - Zoom on pinch gesture
|
* @property {Boolean} [gestureSettingsPen.pinchToZoom=false] - Zoom on pinch gesture
|
||||||
* @property {Boolean} [gestureSettingsPan.zoomToRefPoint=true] - If zoomToRefPoint is true, the zoom is centered at the pointer position. Otherwise,
|
* @property {Boolean} [gestureSettingsPen.zoomToRefPoint=true] - If zoomToRefPoint is true, the zoom is centered at the pointer position. Otherwise,
|
||||||
* the zoom is centered at the canvas center.
|
* the zoom is centered at the canvas center.
|
||||||
* @property {Boolean} [gestureSettingsPen.flickEnabled=false] - Enable flick gesture
|
* @property {Boolean} [gestureSettingsPen.flickEnabled=false] - Enable flick gesture
|
||||||
* @property {Number} [gestureSettingsPen.flickMinSpeed=120] - If flickEnabled is true, the minimum speed to initiate a flick gesture (pixels-per-second)
|
* @property {Number} [gestureSettingsPen.flickMinSpeed=120] - If flickEnabled is true, the minimum speed to initiate a flick gesture (pixels-per-second)
|
||||||
@ -362,6 +366,7 @@
|
|||||||
*
|
*
|
||||||
* @property {OpenSeadragon.GestureSettings} [gestureSettingsUnknown]
|
* @property {OpenSeadragon.GestureSettings} [gestureSettingsUnknown]
|
||||||
* Settings for gestures generated by unknown pointer devices. (See {@link OpenSeadragon.GestureSettings})
|
* Settings for gestures generated by unknown pointer devices. (See {@link OpenSeadragon.GestureSettings})
|
||||||
|
* @property {Boolean} [gestureSettingsMouse.dragToPan=true] - Pan on drag gesture
|
||||||
* @property {Boolean} [gestureSettingsUnknown.scrollToZoom=true] - Zoom on scroll gesture
|
* @property {Boolean} [gestureSettingsUnknown.scrollToZoom=true] - Zoom on scroll gesture
|
||||||
* @property {Boolean} [gestureSettingsUnknown.clickToZoom=false] - Zoom on click gesture
|
* @property {Boolean} [gestureSettingsUnknown.clickToZoom=false] - Zoom on click gesture
|
||||||
* @property {Boolean} [gestureSettingsUnknown.dblClickToZoom=true] - Zoom on double-click gesture. Note: If set to true
|
* @property {Boolean} [gestureSettingsUnknown.dblClickToZoom=true] - Zoom on double-click gesture. Note: If set to true
|
||||||
@ -381,7 +386,11 @@
|
|||||||
* The "zoom distance" per mouse scroll or touch pinch. <em><strong>Note:</strong> Setting this to 1.0 effectively disables the mouse-wheel zoom feature (also see gestureSettings[Mouse|Touch|Pen].scrollToZoom}).</em>
|
* The "zoom distance" per mouse scroll or touch pinch. <em><strong>Note:</strong> Setting this to 1.0 effectively disables the mouse-wheel zoom feature (also see gestureSettings[Mouse|Touch|Pen].scrollToZoom}).</em>
|
||||||
*
|
*
|
||||||
* @property {Number} [zoomPerSecond=1.0]
|
* @property {Number} [zoomPerSecond=1.0]
|
||||||
* The number of seconds to animate a single zoom event over.
|
* Sets the zoom amount per second when zoomIn/zoomOut buttons are pressed and held.
|
||||||
|
* The value is a factor of the current zoom, so 1.0 (the default) disables zooming when the zoomIn/zoomOut buttons
|
||||||
|
* are held. Higher values will increase the rate of zoom when the zoomIn/zoomOut buttons are held. Note that values
|
||||||
|
* < 1.0 will reverse the operation of the zoomIn/zoomOut buttons (zoomIn button will decrease the zoom, zoomOut will
|
||||||
|
* increase the zoom).
|
||||||
*
|
*
|
||||||
* @property {Boolean} [showNavigator=false]
|
* @property {Boolean} [showNavigator=false]
|
||||||
* Set to true to make the navigator minimap appear.
|
* Set to true to make the navigator minimap appear.
|
||||||
@ -647,6 +656,9 @@
|
|||||||
* @typedef {Object} GestureSettings
|
* @typedef {Object} GestureSettings
|
||||||
* @memberof OpenSeadragon
|
* @memberof OpenSeadragon
|
||||||
*
|
*
|
||||||
|
* @property {Boolean} dragToPan
|
||||||
|
* Set to false to disable panning on drag gestures.
|
||||||
|
*
|
||||||
* @property {Boolean} scrollToZoom
|
* @property {Boolean} scrollToZoom
|
||||||
* Set to false to disable zooming on scroll gestures.
|
* Set to false to disable zooming on scroll gestures.
|
||||||
*
|
*
|
||||||
@ -735,7 +747,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* eslint-disable no-redeclare */
|
||||||
function OpenSeadragon( options ){
|
function OpenSeadragon( options ){
|
||||||
return new OpenSeadragon.Viewer( options );
|
return new OpenSeadragon.Viewer( options );
|
||||||
}
|
}
|
||||||
@ -917,13 +929,65 @@ function OpenSeadragon( options ){
|
|||||||
return isTainted;
|
return isTainted;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* True if the browser supports the EventTarget.addEventListener() method
|
||||||
|
* @member {Boolean} supportsAddEventListener
|
||||||
|
* @memberof OpenSeadragon
|
||||||
|
*/
|
||||||
|
$.supportsAddEventListener = (function () {
|
||||||
|
return !!(document.documentElement.addEventListener && document.addEventListener);
|
||||||
|
}());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* True if the browser supports the EventTarget.removeEventListener() method
|
||||||
|
* @member {Boolean} supportsRemoveEventListener
|
||||||
|
* @memberof OpenSeadragon
|
||||||
|
*/
|
||||||
|
$.supportsRemoveEventListener = (function () {
|
||||||
|
return !!(document.documentElement.removeEventListener && document.removeEventListener);
|
||||||
|
}());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* True if the browser supports the newer EventTarget.addEventListener options argument
|
||||||
|
* @member {Boolean} supportsEventListenerOptions
|
||||||
|
* @memberof OpenSeadragon
|
||||||
|
*/
|
||||||
|
$.supportsEventListenerOptions = (function () {
|
||||||
|
var supported = 0;
|
||||||
|
|
||||||
|
if ( $.supportsAddEventListener ) {
|
||||||
|
try {
|
||||||
|
var options = {
|
||||||
|
get capture() {
|
||||||
|
supported++;
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
get once() {
|
||||||
|
supported++;
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
get passive() {
|
||||||
|
supported++;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
window.addEventListener("test", null, options);
|
||||||
|
window.removeEventListener("test", null, options);
|
||||||
|
} catch ( e ) {
|
||||||
|
supported = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return supported >= 3;
|
||||||
|
}());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A ratio comparing the device screen's pixel density to the canvas's backing store pixel density,
|
* 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.
|
* clamped to a minimum of 1. Defaults to 1 if canvas isn't supported by the browser.
|
||||||
* @member {Number} pixelDensityRatio
|
* @member {Number} pixelDensityRatio
|
||||||
* @memberof OpenSeadragon
|
* @memberof OpenSeadragon
|
||||||
*/
|
*/
|
||||||
$.pixelDensityRatio = (function () {
|
$.getCurrentPixelDensityRatio = function() {
|
||||||
if ( $.supportsCanvas ) {
|
if ( $.supportsCanvas ) {
|
||||||
var context = document.createElement('canvas').getContext('2d');
|
var context = document.createElement('canvas').getContext('2d');
|
||||||
var devicePixelRatio = window.devicePixelRatio || 1;
|
var devicePixelRatio = window.devicePixelRatio || 1;
|
||||||
@ -936,13 +1000,19 @@ function OpenSeadragon( options ){
|
|||||||
} else {
|
} else {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}());
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @member {Number} pixelDensityRatio
|
||||||
|
* @memberof OpenSeadragon
|
||||||
|
*/
|
||||||
|
$.pixelDensityRatio = $.getCurrentPixelDensityRatio();
|
||||||
|
|
||||||
}( OpenSeadragon ));
|
}( OpenSeadragon ));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This closure defines all static methods available to the OpenSeadragon
|
* This closure defines all static methods available to the OpenSeadragon
|
||||||
* namespace. Many, if not most, are taked directly from jQuery for use
|
* namespace. Many, if not most, are taken directly from jQuery for use
|
||||||
* to simplify and reduce common programming patterns. More static methods
|
* to simplify and reduce common programming patterns. More static methods
|
||||||
* from jQuery may eventually make their way into this though we are
|
* from jQuery may eventually make their way into this though we are
|
||||||
* attempting to avoid an explicit dependency on jQuery only because
|
* attempting to avoid an explicit dependency on jQuery only because
|
||||||
@ -1081,6 +1151,7 @@ function OpenSeadragon( options ){
|
|||||||
springStiffness: 6.5,
|
springStiffness: 6.5,
|
||||||
animationTime: 1.2,
|
animationTime: 1.2,
|
||||||
gestureSettingsMouse: {
|
gestureSettingsMouse: {
|
||||||
|
dragToPan: true,
|
||||||
scrollToZoom: true,
|
scrollToZoom: true,
|
||||||
clickToZoom: true,
|
clickToZoom: true,
|
||||||
dblClickToZoom: false,
|
dblClickToZoom: false,
|
||||||
@ -1092,6 +1163,7 @@ function OpenSeadragon( options ){
|
|||||||
pinchRotate: false
|
pinchRotate: false
|
||||||
},
|
},
|
||||||
gestureSettingsTouch: {
|
gestureSettingsTouch: {
|
||||||
|
dragToPan: true,
|
||||||
scrollToZoom: false,
|
scrollToZoom: false,
|
||||||
clickToZoom: false,
|
clickToZoom: false,
|
||||||
dblClickToZoom: true,
|
dblClickToZoom: true,
|
||||||
@ -1103,6 +1175,7 @@ function OpenSeadragon( options ){
|
|||||||
pinchRotate: false
|
pinchRotate: false
|
||||||
},
|
},
|
||||||
gestureSettingsPen: {
|
gestureSettingsPen: {
|
||||||
|
dragToPan: true,
|
||||||
scrollToZoom: false,
|
scrollToZoom: false,
|
||||||
clickToZoom: true,
|
clickToZoom: true,
|
||||||
dblClickToZoom: false,
|
dblClickToZoom: false,
|
||||||
@ -1114,6 +1187,7 @@ function OpenSeadragon( options ){
|
|||||||
pinchRotate: false
|
pinchRotate: false
|
||||||
},
|
},
|
||||||
gestureSettingsUnknown: {
|
gestureSettingsUnknown: {
|
||||||
|
dragToPan: true,
|
||||||
scrollToZoom: false,
|
scrollToZoom: false,
|
||||||
clickToZoom: false,
|
clickToZoom: false,
|
||||||
dblClickToZoom: true,
|
dblClickToZoom: true,
|
||||||
@ -1315,6 +1389,8 @@ function OpenSeadragon( options ){
|
|||||||
* @property {Number} SAFARI
|
* @property {Number} SAFARI
|
||||||
* @property {Number} CHROME
|
* @property {Number} CHROME
|
||||||
* @property {Number} OPERA
|
* @property {Number} OPERA
|
||||||
|
* @property {Number} EDGE
|
||||||
|
* @property {Number} CHROMEEDGE
|
||||||
*/
|
*/
|
||||||
BROWSERS: {
|
BROWSERS: {
|
||||||
UNKNOWN: 0,
|
UNKNOWN: 0,
|
||||||
@ -1322,9 +1398,31 @@ function OpenSeadragon( options ){
|
|||||||
FIREFOX: 2,
|
FIREFOX: 2,
|
||||||
SAFARI: 3,
|
SAFARI: 3,
|
||||||
CHROME: 4,
|
CHROME: 4,
|
||||||
OPERA: 5
|
OPERA: 5,
|
||||||
|
EDGE: 6,
|
||||||
|
CHROMEEDGE: 7
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Keep track of which {@link Viewer}s have been created.
|
||||||
|
* - Key: {@link Element} to which a Viewer is attached.
|
||||||
|
* - Value: {@link Viewer} of the element defined by the key.
|
||||||
|
* @private
|
||||||
|
* @static
|
||||||
|
* @type {Object}
|
||||||
|
*/
|
||||||
|
_viewers: new Map(),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the {@link Viewer} attached to a given DOM element. If there is
|
||||||
|
* no viewer attached to the provided element, undefined is returned.
|
||||||
|
* @function
|
||||||
|
* @param {String|Element} element Accepts an id or element.
|
||||||
|
* @returns {Viewer} The viewer attached to the given element, or undefined.
|
||||||
|
*/
|
||||||
|
getViewer: function(element) {
|
||||||
|
return $._viewers.get(this.getElement(element));
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a DOM Element for the given id or element.
|
* Returns a DOM Element for the given id or element.
|
||||||
@ -1333,7 +1431,7 @@ function OpenSeadragon( options ){
|
|||||||
* @returns {Element} The element with the given id, null, or the element itself.
|
* @returns {Element} The element with the given id, null, or the element itself.
|
||||||
*/
|
*/
|
||||||
getElement: function( element ) {
|
getElement: function( element ) {
|
||||||
if ( typeof ( element ) == "string" ) {
|
if ( typeof ( element ) === "string" ) {
|
||||||
element = document.getElementById( element );
|
element = document.getElementById( element );
|
||||||
}
|
}
|
||||||
return element;
|
return element;
|
||||||
@ -1352,7 +1450,7 @@ function OpenSeadragon( options ){
|
|||||||
offsetParent;
|
offsetParent;
|
||||||
|
|
||||||
element = $.getElement( element );
|
element = $.getElement( element );
|
||||||
isFixed = $.getElementStyle( element ).position == "fixed";
|
isFixed = $.getElementStyle( element ).position === "fixed";
|
||||||
offsetParent = getOffsetParent( element, isFixed );
|
offsetParent = getOffsetParent( element, isFixed );
|
||||||
|
|
||||||
while ( offsetParent ) {
|
while ( offsetParent ) {
|
||||||
@ -1365,7 +1463,7 @@ function OpenSeadragon( options ){
|
|||||||
}
|
}
|
||||||
|
|
||||||
element = offsetParent;
|
element = offsetParent;
|
||||||
isFixed = $.getElementStyle( element ).position == "fixed";
|
isFixed = $.getElementStyle( element ).position === "fixed";
|
||||||
offsetParent = getOffsetParent( element, isFixed );
|
offsetParent = getOffsetParent( element, isFixed );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1397,7 +1495,7 @@ function OpenSeadragon( options ){
|
|||||||
boundingRect = element.getBoundingClientRect();
|
boundingRect = element.getBoundingClientRect();
|
||||||
}
|
}
|
||||||
|
|
||||||
win = ( doc == doc.window ) ?
|
win = ( doc === doc.window ) ?
|
||||||
doc :
|
doc :
|
||||||
( doc.nodeType === 9 ) ?
|
( doc.nodeType === 9 ) ?
|
||||||
doc.defaultView || doc.parentWindow :
|
doc.defaultView || doc.parentWindow :
|
||||||
@ -1517,29 +1615,6 @@ function OpenSeadragon( options ){
|
|||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the latest event, really only useful internally since its
|
|
||||||
* specific to IE behavior.
|
|
||||||
* @function
|
|
||||||
* @param {Event} [event]
|
|
||||||
* @returns {Event}
|
|
||||||
* @deprecated For internal use only
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
getEvent: function( event ) {
|
|
||||||
if( event ){
|
|
||||||
$.getEvent = function( event ) {
|
|
||||||
return event;
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
$.getEvent = function() {
|
|
||||||
return window.event;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return $.getEvent( event );
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the position of the mouse on the screen for a given event.
|
* Gets the position of the mouse on the screen for a given event.
|
||||||
* @function
|
* @function
|
||||||
@ -1548,21 +1623,19 @@ function OpenSeadragon( options ){
|
|||||||
*/
|
*/
|
||||||
getMousePosition: function( event ) {
|
getMousePosition: function( event ) {
|
||||||
|
|
||||||
if ( typeof ( event.pageX ) == "number" ) {
|
if ( typeof ( event.pageX ) === "number" ) {
|
||||||
$.getMousePosition = function( event ){
|
$.getMousePosition = function( event ){
|
||||||
var result = new $.Point();
|
var result = new $.Point();
|
||||||
|
|
||||||
event = $.getEvent( event );
|
|
||||||
result.x = event.pageX;
|
result.x = event.pageX;
|
||||||
result.y = event.pageY;
|
result.y = event.pageY;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
} else if ( typeof ( event.clientX ) == "number" ) {
|
} else if ( typeof ( event.clientX ) === "number" ) {
|
||||||
$.getMousePosition = function( event ){
|
$.getMousePosition = function( event ){
|
||||||
var result = new $.Point();
|
var result = new $.Point();
|
||||||
|
|
||||||
event = $.getEvent( event );
|
|
||||||
result.x =
|
result.x =
|
||||||
event.clientX +
|
event.clientX +
|
||||||
document.body.scrollLeft +
|
document.body.scrollLeft +
|
||||||
@ -1593,7 +1666,7 @@ function OpenSeadragon( options ){
|
|||||||
var docElement = document.documentElement || {},
|
var docElement = document.documentElement || {},
|
||||||
body = document.body || {};
|
body = document.body || {};
|
||||||
|
|
||||||
if ( typeof ( window.pageXOffset ) == "number" ) {
|
if ( typeof ( window.pageXOffset ) === "number" ) {
|
||||||
$.getPageScroll = function(){
|
$.getPageScroll = function(){
|
||||||
return new $.Point(
|
return new $.Point(
|
||||||
window.pageXOffset,
|
window.pageXOffset,
|
||||||
@ -1670,7 +1743,7 @@ function OpenSeadragon( options ){
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return $.setPageScroll( scroll );
|
$.setPageScroll( scroll );
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1682,7 +1755,7 @@ function OpenSeadragon( options ){
|
|||||||
var docElement = document.documentElement || {},
|
var docElement = document.documentElement || {},
|
||||||
body = document.body || {};
|
body = document.body || {};
|
||||||
|
|
||||||
if ( typeof ( window.innerWidth ) == 'number' ) {
|
if ( typeof ( window.innerWidth ) === 'number' ) {
|
||||||
$.getWindowSize = function(){
|
$.getWindowSize = function(){
|
||||||
return new $.Point(
|
return new $.Point(
|
||||||
window.innerWidth,
|
window.innerWidth,
|
||||||
@ -1798,51 +1871,16 @@ function OpenSeadragon( options ){
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Ensures an image is loaded correctly to support alpha transparency.
|
* Ensures an image is loaded correctly to support alpha transparency.
|
||||||
* Generally only IE has issues doing this correctly for formats like
|
|
||||||
* png.
|
|
||||||
* @function
|
* @function
|
||||||
* @param {String} src
|
* @param {String} src
|
||||||
* @returns {Element}
|
* @returns {Element}
|
||||||
*/
|
*/
|
||||||
makeTransparentImage: function( src ) {
|
makeTransparentImage: function( src ) {
|
||||||
|
var img = $.makeNeutralElement( "img" );
|
||||||
|
|
||||||
$.makeTransparentImage = function( src ){
|
img.src = src;
|
||||||
var img = $.makeNeutralElement( "img" );
|
|
||||||
|
|
||||||
img.src = src;
|
return img;
|
||||||
|
|
||||||
return img;
|
|
||||||
};
|
|
||||||
|
|
||||||
if ( $.Browser.vendor == $.BROWSERS.IE && $.Browser.version < 7 ) {
|
|
||||||
|
|
||||||
$.makeTransparentImage = function( src ){
|
|
||||||
var img = $.makeNeutralElement( "img" ),
|
|
||||||
element = null;
|
|
||||||
|
|
||||||
element = $.makeNeutralElement("span");
|
|
||||||
element.style.display = "inline-block";
|
|
||||||
|
|
||||||
img.onload = function() {
|
|
||||||
element.style.width = element.style.width || img.width + "px";
|
|
||||||
element.style.height = element.style.height || img.height + "px";
|
|
||||||
|
|
||||||
img.onload = null;
|
|
||||||
img = null; // to prevent memory leaks in IE
|
|
||||||
};
|
|
||||||
|
|
||||||
img.src = src;
|
|
||||||
element.style.filter =
|
|
||||||
"progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" +
|
|
||||||
src +
|
|
||||||
"', sizingMethod='scale')";
|
|
||||||
|
|
||||||
return element;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return $.makeTransparentImage( src );
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
@ -1893,6 +1931,30 @@ function OpenSeadragon( options ){
|
|||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the specified element's pointer-events style attribute to the passed value.
|
||||||
|
* @function
|
||||||
|
* @param {Element|String} element
|
||||||
|
* @param {String} value
|
||||||
|
*/
|
||||||
|
setElementPointerEvents: function( element, value ) {
|
||||||
|
element = $.getElement( element );
|
||||||
|
if ( typeof element.style.pointerEvents !== 'undefined' ) {
|
||||||
|
element.style.pointerEvents = value;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the specified element's pointer-events style attribute to 'none'.
|
||||||
|
* @function
|
||||||
|
* @param {Element|String} element
|
||||||
|
*/
|
||||||
|
setElementPointerEventsNone: function( element ) {
|
||||||
|
$.setElementPointerEvents( element, 'none' );
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add the specified CSS class to the element if not present.
|
* Add the specified CSS class to the element if not present.
|
||||||
* @function
|
* @function
|
||||||
@ -1978,6 +2040,34 @@ function OpenSeadragon( options ){
|
|||||||
element.className = newClasses.join(' ');
|
element.className = newClasses.join(' ');
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert passed addEventListener() options to boolean or options object,
|
||||||
|
* depending on browser support.
|
||||||
|
* @function
|
||||||
|
* @param {Boolean|Object} [options] Boolean useCapture, or if [supportsEventListenerOptions]{@link OpenSeadragon.supportsEventListenerOptions}, can be an object
|
||||||
|
* @param {Boolean} [options.capture]
|
||||||
|
* @param {Boolean} [options.passive]
|
||||||
|
* @param {Boolean} [options.once]
|
||||||
|
* @return {String} The protocol (http:, https:, file:, ftp: ...)
|
||||||
|
*/
|
||||||
|
normalizeEventListenerOptions: function (options) {
|
||||||
|
var opts;
|
||||||
|
if ( typeof options !== 'undefined' ) {
|
||||||
|
if ( typeof options === 'boolean' ) {
|
||||||
|
// Legacy Boolean useCapture
|
||||||
|
opts = $.supportsEventListenerOptions ? { capture: options } : options;
|
||||||
|
} else {
|
||||||
|
// Options object
|
||||||
|
opts = $.supportsEventListenerOptions ? options :
|
||||||
|
( ( typeof options.capture !== 'undefined' ) ? options.capture : false );
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// No options specified - Legacy optional useCapture argument
|
||||||
|
// (for IE, first supported on version 9, so we'll pass a Boolean)
|
||||||
|
opts = $.supportsEventListenerOptions ? { capture: false } : false;
|
||||||
|
}
|
||||||
|
return opts;
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds an event listener for the given element, eventName and handler.
|
* Adds an event listener for the given element, eventName and handler.
|
||||||
@ -1985,16 +2075,20 @@ function OpenSeadragon( options ){
|
|||||||
* @param {Element|String} element
|
* @param {Element|String} element
|
||||||
* @param {String} eventName
|
* @param {String} eventName
|
||||||
* @param {Function} handler
|
* @param {Function} handler
|
||||||
* @param {Boolean} [useCapture]
|
* @param {Boolean|Object} [options] Boolean useCapture, or if [supportsEventListenerOptions]{@link OpenSeadragon.supportsEventListenerOptions}, can be an object
|
||||||
|
* @param {Boolean} [options.capture]
|
||||||
|
* @param {Boolean} [options.passive]
|
||||||
|
* @param {Boolean} [options.once]
|
||||||
*/
|
*/
|
||||||
addEvent: (function () {
|
addEvent: (function () {
|
||||||
if ( window.addEventListener ) {
|
if ( $.supportsAddEventListener ) {
|
||||||
return function ( element, eventName, handler, useCapture ) {
|
return function ( element, eventName, handler, options ) {
|
||||||
|
options = $.normalizeEventListenerOptions(options);
|
||||||
element = $.getElement( element );
|
element = $.getElement( element );
|
||||||
element.addEventListener( eventName, handler, useCapture );
|
element.addEventListener( eventName, handler, options );
|
||||||
};
|
};
|
||||||
} else if ( window.attachEvent ) {
|
} else if ( document.documentElement.attachEvent && document.attachEvent ) {
|
||||||
return function ( element, eventName, handler, useCapture ) {
|
return function ( element, eventName, handler ) {
|
||||||
element = $.getElement( element );
|
element = $.getElement( element );
|
||||||
element.attachEvent( 'on' + eventName, handler );
|
element.attachEvent( 'on' + eventName, handler );
|
||||||
};
|
};
|
||||||
@ -2011,16 +2105,18 @@ function OpenSeadragon( options ){
|
|||||||
* @param {Element|String} element
|
* @param {Element|String} element
|
||||||
* @param {String} eventName
|
* @param {String} eventName
|
||||||
* @param {Function} handler
|
* @param {Function} handler
|
||||||
* @param {Boolean} [useCapture]
|
* @param {Boolean|Object} [options] Boolean useCapture, or if [supportsEventListenerOptions]{@link OpenSeadragon.supportsEventListenerOptions}, can be an object
|
||||||
|
* @param {Boolean} [options.capture]
|
||||||
*/
|
*/
|
||||||
removeEvent: (function () {
|
removeEvent: (function () {
|
||||||
if ( window.removeEventListener ) {
|
if ( $.supportsRemoveEventListener ) {
|
||||||
return function ( element, eventName, handler, useCapture ) {
|
return function ( element, eventName, handler, options ) {
|
||||||
|
options = $.normalizeEventListenerOptions(options);
|
||||||
element = $.getElement( element );
|
element = $.getElement( element );
|
||||||
element.removeEventListener( eventName, handler, useCapture );
|
element.removeEventListener( eventName, handler, options );
|
||||||
};
|
};
|
||||||
} else if ( window.detachEvent ) {
|
} else if ( document.documentElement.detachEvent && document.detachEvent ) {
|
||||||
return function( element, eventName, handler, useCapture ) {
|
return function( element, eventName, handler ) {
|
||||||
element = $.getElement( element );
|
element = $.getElement( element );
|
||||||
element.detachEvent( 'on' + eventName, handler );
|
element.detachEvent( 'on' + eventName, handler );
|
||||||
};
|
};
|
||||||
@ -2037,49 +2133,28 @@ function OpenSeadragon( options ){
|
|||||||
* @param {Event} [event]
|
* @param {Event} [event]
|
||||||
*/
|
*/
|
||||||
cancelEvent: function( event ) {
|
cancelEvent: function( event ) {
|
||||||
event = $.getEvent( event );
|
event.preventDefault();
|
||||||
|
|
||||||
if ( event.preventDefault ) {
|
|
||||||
$.cancelEvent = function( event ){
|
|
||||||
// W3C for preventing default
|
|
||||||
event.preventDefault();
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
$.cancelEvent = function( event ){
|
|
||||||
event = $.getEvent( event );
|
|
||||||
// legacy for preventing default
|
|
||||||
event.cancel = true;
|
|
||||||
// IE for preventing default
|
|
||||||
event.returnValue = false;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
$.cancelEvent( event );
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stops the propagation of the event up the DOM.
|
* Returns true if {@link OpenSeadragon.cancelEvent|cancelEvent} has been called on
|
||||||
|
* the event, otherwise returns false.
|
||||||
|
* @function
|
||||||
|
* @param {Event} [event]
|
||||||
|
*/
|
||||||
|
eventIsCanceled: function( event ) {
|
||||||
|
return event.defaultPrevented;
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stops the propagation of the event through the DOM in the capturing and bubbling phases.
|
||||||
* @function
|
* @function
|
||||||
* @param {Event} [event]
|
* @param {Event} [event]
|
||||||
*/
|
*/
|
||||||
stopEvent: function( event ) {
|
stopEvent: function( event ) {
|
||||||
event = $.getEvent( event );
|
event.stopPropagation();
|
||||||
|
|
||||||
if ( event.stopPropagation ) {
|
|
||||||
// W3C for stopping propagation
|
|
||||||
$.stopEvent = function( event ){
|
|
||||||
event.stopPropagation();
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
// IE for stopping propagation
|
|
||||||
$.stopEvent = function( event ){
|
|
||||||
event = $.getEvent( event );
|
|
||||||
event.cancelBubble = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
$.stopEvent( event );
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
@ -2227,7 +2302,7 @@ function OpenSeadragon( options ){
|
|||||||
|
|
||||||
request.onreadystatechange = function() {
|
request.onreadystatechange = function() {
|
||||||
// 4 = DONE (https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#Properties)
|
// 4 = DONE (https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#Properties)
|
||||||
if ( request.readyState == 4 ) {
|
if ( request.readyState === 4 ) {
|
||||||
request.onreadystatechange = function(){};
|
request.onreadystatechange = function(){};
|
||||||
|
|
||||||
// With protocols other than http/https, a successful request status is in
|
// With protocols other than http/https, a successful request status is in
|
||||||
@ -2256,7 +2331,7 @@ function OpenSeadragon( options ){
|
|||||||
|
|
||||||
if (headers) {
|
if (headers) {
|
||||||
for (var headerName in headers) {
|
for (var headerName in headers) {
|
||||||
if (headers.hasOwnProperty(headerName) && headers[headerName]) {
|
if (Object.prototype.hasOwnProperty.call(headers, headerName) && headers[headerName]) {
|
||||||
request.setRequestHeader(headerName, headers[headerName]);
|
request.setRequestHeader(headerName, headers[headerName]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2268,62 +2343,12 @@ function OpenSeadragon( options ){
|
|||||||
|
|
||||||
request.send(null);
|
request.send(null);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
var msg = e.message;
|
$.console.log( "%s while making AJAX request: %s", e.name, 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 );
|
|
||||||
|
|
||||||
request.onreadystatechange = function(){};
|
request.onreadystatechange = function(){};
|
||||||
|
|
||||||
if (window.XDomainRequest) { // IE9 or IE8 might as well try to use XDomainRequest
|
if ( $.isFunction( onError ) ) {
|
||||||
var xdr = new XDomainRequest();
|
onError( request, e );
|
||||||
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'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
xdr.onerror = function (e) {
|
|
||||||
if ($.isFunction(onError)) {
|
|
||||||
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.'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
try {
|
|
||||||
xdr.open('GET', url);
|
|
||||||
xdr.send();
|
|
||||||
} catch (e2) {
|
|
||||||
if ( $.isFunction( onError ) ) {
|
|
||||||
onError( request, e );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if ( $.isFunction( onError ) ) {
|
|
||||||
onError( request, e );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2353,7 +2378,7 @@ function OpenSeadragon( options ){
|
|||||||
callbackParam = options.param || 'callback',
|
callbackParam = options.param || 'callback',
|
||||||
callback = options.callback;
|
callback = options.callback;
|
||||||
|
|
||||||
url = url.replace( /(\=)\?(&|$)|\?\?/i, replace );
|
url = url.replace( /(=)\?(&|$)|\?\?/i, replace );
|
||||||
// Add callback manually
|
// Add callback manually
|
||||||
url += (/\?/.test( url ) ? "&" : "?") + callbackParam + "=" + jsonpCallback;
|
url += (/\?/.test( url ) ? "&" : "?") + callbackParam + "=" + jsonpCallback;
|
||||||
|
|
||||||
@ -2462,16 +2487,7 @@ function OpenSeadragon( options ){
|
|||||||
* @returns {Object}
|
* @returns {Object}
|
||||||
*/
|
*/
|
||||||
parseJSON: function(string) {
|
parseJSON: function(string) {
|
||||||
if (window.JSON && window.JSON.parse) {
|
$.parseJSON = window.JSON.parse;
|
||||||
$.parseJSON = window.JSON.parse;
|
|
||||||
} else {
|
|
||||||
// Should only be used by IE8 in non standards mode
|
|
||||||
$.parseJSON = function(string) {
|
|
||||||
/*jshint evil:true*/
|
|
||||||
//eslint-disable-next-line no-eval
|
|
||||||
return eval('(' + string + ')');
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return $.parseJSON(string);
|
return $.parseJSON(string);
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -2486,11 +2502,61 @@ function OpenSeadragon( options ){
|
|||||||
extension = extension ? extension : "";
|
extension = extension ? extension : "";
|
||||||
// eslint-disable-next-line no-use-before-define
|
// eslint-disable-next-line no-use-before-define
|
||||||
return !!FILEFORMATS[ extension.toLowerCase() ];
|
return !!FILEFORMATS[ extension.toLowerCase() ];
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates supported image formats with user-specified values.
|
||||||
|
* Preexisting formats that are not being updated are left unchanged.
|
||||||
|
* By default, the defined formats are
|
||||||
|
* <pre><code>{
|
||||||
|
* bmp: false,
|
||||||
|
* jpeg: true,
|
||||||
|
* jpg: true,
|
||||||
|
* png: true,
|
||||||
|
* tif: false,
|
||||||
|
* wdp: false
|
||||||
|
* }
|
||||||
|
* </code></pre>
|
||||||
|
* @function
|
||||||
|
* @example
|
||||||
|
* // sets webp as supported and png as unsupported
|
||||||
|
* setImageFormatsSupported({webp: true, png: false});
|
||||||
|
* @param {Object} formats An object containing format extensions as
|
||||||
|
* keys and booleans as values.
|
||||||
|
*/
|
||||||
|
setImageFormatsSupported: function(formats) {
|
||||||
|
// eslint-disable-next-line no-use-before-define
|
||||||
|
$.extend(FILEFORMATS, formats);
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
//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 propagate in
|
||||||
|
// all but the most special cases.
|
||||||
|
/**
|
||||||
|
* A convenient alias for console when available, and a simple null
|
||||||
|
* 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,
|
||||||
|
error: nullfunction,
|
||||||
|
assert: nullfunction
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The current browser vendor, version, and related information regarding detected features.
|
* The current browser vendor, version, and related information regarding detected features.
|
||||||
* @member {Object} Browser
|
* @member {Object} Browser
|
||||||
@ -2509,12 +2575,12 @@ function OpenSeadragon( options ){
|
|||||||
|
|
||||||
|
|
||||||
var FILEFORMATS = {
|
var FILEFORMATS = {
|
||||||
"bmp": false,
|
bmp: false,
|
||||||
"jpeg": true,
|
jpeg: true,
|
||||||
"jpg": true,
|
jpg: true,
|
||||||
"png": true,
|
png: true,
|
||||||
"tif": false,
|
tif: false,
|
||||||
"wdp": false
|
wdp: false
|
||||||
},
|
},
|
||||||
URLPARAMS = {};
|
URLPARAMS = {};
|
||||||
|
|
||||||
@ -2544,7 +2610,17 @@ function OpenSeadragon( options ){
|
|||||||
break;
|
break;
|
||||||
case "Netscape":
|
case "Netscape":
|
||||||
if (window.addEventListener) {
|
if (window.addEventListener) {
|
||||||
if ( ua.indexOf( "Firefox" ) >= 0 ) {
|
if ( ua.indexOf( "Edge" ) >= 0 ) {
|
||||||
|
$.Browser.vendor = $.BROWSERS.EDGE;
|
||||||
|
$.Browser.version = parseFloat(
|
||||||
|
ua.substring( ua.indexOf( "Edge" ) + 5 )
|
||||||
|
);
|
||||||
|
} else if ( ua.indexOf( "Edg" ) >= 0 ) {
|
||||||
|
$.Browser.vendor = $.BROWSERS.CHROMEEDGE;
|
||||||
|
$.Browser.version = parseFloat(
|
||||||
|
ua.substring( ua.indexOf( "Edg" ) + 4 )
|
||||||
|
);
|
||||||
|
} else if ( ua.indexOf( "Firefox" ) >= 0 ) {
|
||||||
$.Browser.vendor = $.BROWSERS.FIREFOX;
|
$.Browser.vendor = $.BROWSERS.FIREFOX;
|
||||||
$.Browser.version = parseFloat(
|
$.Browser.version = parseFloat(
|
||||||
ua.substring( ua.indexOf( "Firefox" ) + 8 )
|
ua.substring( ua.indexOf( "Firefox" ) + 8 )
|
||||||
@ -2586,56 +2662,30 @@ function OpenSeadragon( options ){
|
|||||||
sep = part.indexOf( '=' );
|
sep = part.indexOf( '=' );
|
||||||
|
|
||||||
if ( sep > 0 ) {
|
if ( sep > 0 ) {
|
||||||
URLPARAMS[ part.substring( 0, sep ) ] =
|
var key = part.substring( 0, sep ),
|
||||||
decodeURIComponent( part.substring( sep + 1 ) );
|
value = part.substring( sep + 1 );
|
||||||
|
try {
|
||||||
|
URLPARAMS[ key ] = decodeURIComponent( value );
|
||||||
|
} catch (e) {
|
||||||
|
$.console.error( "Ignoring malformed URL parameter: %s=%s", key, value );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//determine if this browser supports image alpha transparency
|
//determine if this browser supports image alpha transparency
|
||||||
$.Browser.alpha = !(
|
$.Browser.alpha = !(
|
||||||
(
|
$.Browser.vendor === $.BROWSERS.CHROME && $.Browser.version < 2
|
||||||
$.Browser.vendor == $.BROWSERS.IE &&
|
|
||||||
$.Browser.version < 9
|
|
||||||
) || (
|
|
||||||
$.Browser.vendor == $.BROWSERS.CHROME &&
|
|
||||||
$.Browser.version < 2
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
//determine if this browser supports element.style.opacity
|
//determine if this browser supports element.style.opacity
|
||||||
$.Browser.opacity = !(
|
$.Browser.opacity = true;
|
||||||
$.Browser.vendor == $.BROWSERS.IE &&
|
|
||||||
$.Browser.version < 9
|
|
||||||
);
|
|
||||||
|
|
||||||
|
if ( $.Browser.vendor === $.BROWSERS.IE && $.Browser.version < 11 ) {
|
||||||
|
$.console.error('Internet Explorer versions < 11 are not supported by OpenSeadragon');
|
||||||
|
}
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
|
||||||
//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 propagate in
|
|
||||||
// all but the most special cases.
|
|
||||||
/**
|
|
||||||
* A convenient alias for console when available, and a simple null
|
|
||||||
* 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,
|
|
||||||
error: nullfunction,
|
|
||||||
assert: nullfunction
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// Adding support for HTML5's requestAnimationFrame as suggested by acdha.
|
// Adding support for HTML5's requestAnimationFrame as suggested by acdha.
|
||||||
// Implementation taken from matt synder's post here:
|
// Implementation taken from matt synder's post here:
|
||||||
// http://mattsnider.com/cross-browser-and-legacy-supported-requestframeanimation/
|
// http://mattsnider.com/cross-browser-and-legacy-supported-requestframeanimation/
|
||||||
@ -2731,7 +2781,7 @@ function OpenSeadragon( options ){
|
|||||||
* @returns {Element}
|
* @returns {Element}
|
||||||
*/
|
*/
|
||||||
function getOffsetParent( element, isFixed ) {
|
function getOffsetParent( element, isFixed ) {
|
||||||
if ( isFixed && element != document.body ) {
|
if ( isFixed && element !== document.body ) {
|
||||||
return document.body;
|
return document.body;
|
||||||
} else {
|
} else {
|
||||||
return element.offsetParent;
|
return element.offsetParent;
|
||||||
|
@ -113,7 +113,7 @@ $.extend( $.OsmTileSource.prototype, $.TileSource.prototype, /** @lends OpenSead
|
|||||||
supports: function( data, url ){
|
supports: function( data, url ){
|
||||||
return (
|
return (
|
||||||
data.type &&
|
data.type &&
|
||||||
"openstreetmaps" == data.type
|
"openstreetmaps" === data.type
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -288,10 +288,7 @@
|
|||||||
style[transformProp] = "";
|
style[transformProp] = "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
style.display = 'block';
|
||||||
if (style.display !== 'none') {
|
|
||||||
style.display = 'block';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -50,13 +50,13 @@ $.Point = function( x, y ) {
|
|||||||
* @member {Number} x
|
* @member {Number} x
|
||||||
* @memberof OpenSeadragon.Point#
|
* @memberof OpenSeadragon.Point#
|
||||||
*/
|
*/
|
||||||
this.x = typeof ( x ) == "number" ? x : 0;
|
this.x = typeof ( x ) === "number" ? x : 0;
|
||||||
/**
|
/**
|
||||||
* The vector component 'y'.
|
* The vector component 'y'.
|
||||||
* @member {Number} y
|
* @member {Number} y
|
||||||
* @memberof OpenSeadragon.Point#
|
* @memberof OpenSeadragon.Point#
|
||||||
*/
|
*/
|
||||||
this.y = typeof ( y ) == "number" ? y : 0;
|
this.y = typeof ( y ) === "number" ? y : 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** @lends OpenSeadragon.Point.prototype */
|
/** @lends OpenSeadragon.Point.prototype */
|
||||||
|
@ -85,24 +85,19 @@ $.ReferenceStrip = function ( options ) {
|
|||||||
scroll: $.DEFAULT_SETTINGS.referenceStripScroll,
|
scroll: $.DEFAULT_SETTINGS.referenceStripScroll,
|
||||||
clickTimeThreshold: $.DEFAULT_SETTINGS.clickTimeThreshold
|
clickTimeThreshold: $.DEFAULT_SETTINGS.clickTimeThreshold
|
||||||
}, options, {
|
}, options, {
|
||||||
//required overrides
|
element: this.element
|
||||||
element: this.element,
|
|
||||||
//These need to be overridden to prevent recursion since
|
|
||||||
//the navigator is a viewer and a viewer has a navigator
|
|
||||||
showNavigator: false,
|
|
||||||
mouseNavEnabled: false,
|
|
||||||
showNavigationControl: false,
|
|
||||||
showSequenceControl: false
|
|
||||||
} );
|
} );
|
||||||
|
|
||||||
$.extend( this, options );
|
$.extend( this, options );
|
||||||
//Private state properties
|
//Private state properties
|
||||||
THIS[this.id] = {
|
THIS[this.id] = {
|
||||||
"animating": false
|
animating: false
|
||||||
};
|
};
|
||||||
|
|
||||||
this.minPixelRatio = this.viewer.minPixelRatio;
|
this.minPixelRatio = this.viewer.minPixelRatio;
|
||||||
|
|
||||||
|
this.element.tabIndex = 0;
|
||||||
|
|
||||||
style = this.element.style;
|
style = this.element.style;
|
||||||
style.marginTop = '0px';
|
style.marginTop = '0px';
|
||||||
style.marginRight = '0px';
|
style.marginRight = '0px';
|
||||||
@ -119,14 +114,21 @@ $.ReferenceStrip = function ( options ) {
|
|||||||
$.setElementOpacity( this.element, 0.8 );
|
$.setElementOpacity( this.element, 0.8 );
|
||||||
|
|
||||||
this.viewer = viewer;
|
this.viewer = viewer;
|
||||||
this.innerTracker = new $.MouseTracker( {
|
this.tracker = new $.MouseTracker( {
|
||||||
|
userData: 'ReferenceStrip.tracker',
|
||||||
element: this.element,
|
element: this.element,
|
||||||
|
clickHandler: $.delegate( this, onStripClick ),
|
||||||
dragHandler: $.delegate( this, onStripDrag ),
|
dragHandler: $.delegate( this, onStripDrag ),
|
||||||
scrollHandler: $.delegate( this, onStripScroll ),
|
scrollHandler: $.delegate( this, onStripScroll ),
|
||||||
enterHandler: $.delegate( this, onStripEnter ),
|
enterHandler: $.delegate( this, onStripEnter ),
|
||||||
exitHandler: $.delegate( this, onStripExit ),
|
leaveHandler: $.delegate( this, onStripLeave ),
|
||||||
keyDownHandler: $.delegate( this, onKeyDown ),
|
keyDownHandler: $.delegate( this, onKeyDown ),
|
||||||
keyHandler: $.delegate( this, onKeyPress )
|
keyHandler: $.delegate( this, onKeyPress ),
|
||||||
|
preProcessEventHandler: function (eventInfo) {
|
||||||
|
if (eventInfo.eventType === 'wheel') {
|
||||||
|
eventInfo.preventDefault = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
} );
|
} );
|
||||||
|
|
||||||
//Controls the position and orientation of the reference strip and sets the
|
//Controls the position and orientation of the reference strip and sets the
|
||||||
@ -139,7 +141,7 @@ $.ReferenceStrip = function ( options ) {
|
|||||||
{ anchor: $.ControlAnchor.BOTTOM_LEFT }
|
{ anchor: $.ControlAnchor.BOTTOM_LEFT }
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
if ( "horizontal" == options.scroll ) {
|
if ( "horizontal" === options.scroll ) {
|
||||||
this.element.style.width = (
|
this.element.style.width = (
|
||||||
viewerSize.x *
|
viewerSize.x *
|
||||||
options.sizeRatio *
|
options.sizeRatio *
|
||||||
@ -189,34 +191,12 @@ $.ReferenceStrip = function ( options ) {
|
|||||||
element.style.width = _this.panelWidth + 'px';
|
element.style.width = _this.panelWidth + 'px';
|
||||||
element.style.height = _this.panelHeight + 'px';
|
element.style.height = _this.panelHeight + 'px';
|
||||||
element.style.display = 'inline';
|
element.style.display = 'inline';
|
||||||
element.style.float = 'left'; //Webkit
|
element.style['float'] = 'left'; //Webkit
|
||||||
element.style.cssFloat = 'left'; //Firefox
|
element.style.cssFloat = 'left'; //Firefox
|
||||||
element.style.styleFloat = 'left'; //IE
|
element.style.styleFloat = 'left'; //IE
|
||||||
element.style.padding = '2px';
|
element.style.padding = '2px';
|
||||||
$.setElementTouchActionNone( element );
|
$.setElementTouchActionNone( element );
|
||||||
|
$.setElementPointerEventsNone( element );
|
||||||
element.innerTracker = new $.MouseTracker( {
|
|
||||||
element: element,
|
|
||||||
clickTimeThreshold: this.clickTimeThreshold,
|
|
||||||
clickDistThreshold: this.clickDistThreshold,
|
|
||||||
pressHandler: function ( event ) {
|
|
||||||
event.eventSource.dragging = $.now();
|
|
||||||
},
|
|
||||||
releaseHandler: function ( event ) {
|
|
||||||
var tracker = event.eventSource,
|
|
||||||
id = tracker.element.id,
|
|
||||||
page = Number( id.split( '-' )[2] ),
|
|
||||||
now = $.now();
|
|
||||||
|
|
||||||
if ( event.insideElementPressed &&
|
|
||||||
event.insideElementReleased &&
|
|
||||||
tracker.dragging &&
|
|
||||||
( now - tracker.dragging ) < tracker.clickTimeThreshold ) {
|
|
||||||
tracker.dragging = null;
|
|
||||||
viewer.goToPage( page );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
|
|
||||||
this.element.appendChild( element );
|
this.element.appendChild( element );
|
||||||
|
|
||||||
@ -225,12 +205,13 @@ $.ReferenceStrip = function ( options ) {
|
|||||||
this.panels.push( element );
|
this.panels.push( element );
|
||||||
|
|
||||||
}
|
}
|
||||||
loadPanels( this, this.scroll == 'vertical' ? viewerSize.y : viewerSize.x, 0 );
|
loadPanels( this, this.scroll === 'vertical' ? viewerSize.y : viewerSize.x, 0 );
|
||||||
this.setFocus( 0 );
|
this.setFocus( 0 );
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
$.extend( $.ReferenceStrip.prototype, $.EventSource.prototype, $.Viewer.prototype, /** @lends OpenSeadragon.ReferenceStrip.prototype */{
|
/** @lends OpenSeadragon.ReferenceStrip.prototype */
|
||||||
|
$.ReferenceStrip.prototype = {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @function
|
* @function
|
||||||
@ -251,7 +232,7 @@ $.extend( $.ReferenceStrip.prototype, $.EventSource.prototype, $.Viewer.prototyp
|
|||||||
this.currentSelected = element;
|
this.currentSelected = element;
|
||||||
this.currentSelected.style.background = '#999';
|
this.currentSelected.style.background = '#999';
|
||||||
|
|
||||||
if ( 'horizontal' == this.scroll ) {
|
if ( 'horizontal' === this.scroll ) {
|
||||||
//right left
|
//right left
|
||||||
offset = ( Number( page ) ) * ( this.panelWidth + 3 );
|
offset = ( Number( page ) ) * ( this.panelWidth + 3 );
|
||||||
if ( offset > offsetLeft + viewerSize.x - this.panelWidth ) {
|
if ( offset > offsetLeft + viewerSize.x - this.panelWidth ) {
|
||||||
@ -277,7 +258,7 @@ $.extend( $.ReferenceStrip.prototype, $.EventSource.prototype, $.Viewer.prototyp
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.currentPage = page;
|
this.currentPage = page;
|
||||||
onStripEnter.call( this, { eventSource: this.innerTracker } );
|
onStripEnter.call( this, { eventSource: this.tracker } );
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -292,7 +273,6 @@ $.extend( $.ReferenceStrip.prototype, $.EventSource.prototype, $.Viewer.prototyp
|
|||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
|
|
||||||
// Overrides Viewer.destroy
|
|
||||||
destroy: function() {
|
destroy: function() {
|
||||||
if (this.miniViewers) {
|
if (this.miniViewers) {
|
||||||
for (var key in this.miniViewers) {
|
for (var key in this.miniViewers) {
|
||||||
@ -300,14 +280,36 @@ $.extend( $.ReferenceStrip.prototype, $.EventSource.prototype, $.Viewer.prototyp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.tracker.destroy();
|
||||||
|
|
||||||
if (this.element) {
|
if (this.element) {
|
||||||
this.element.parentNode.removeChild(this.element);
|
this.viewer.removeControl( this.element );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} );
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @inner
|
||||||
|
* @function
|
||||||
|
*/
|
||||||
|
function onStripClick( event ) {
|
||||||
|
if ( event.quick ) {
|
||||||
|
var page;
|
||||||
|
|
||||||
|
if ( 'horizontal' === this.scroll ) {
|
||||||
|
page = Math.floor(event.position.x / this.panelWidth);
|
||||||
|
} else {
|
||||||
|
page = Math.floor(event.position.y / this.panelHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.viewer.goToPage( page );
|
||||||
|
}
|
||||||
|
|
||||||
|
this.element.focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -317,14 +319,15 @@ $.extend( $.ReferenceStrip.prototype, $.EventSource.prototype, $.Viewer.prototyp
|
|||||||
*/
|
*/
|
||||||
function onStripDrag( event ) {
|
function onStripDrag( event ) {
|
||||||
|
|
||||||
var offsetLeft = Number( this.element.style.marginLeft.replace( 'px', '' ) ),
|
this.dragging = true;
|
||||||
|
if ( this.element ) {
|
||||||
|
var offsetLeft = Number( this.element.style.marginLeft.replace( 'px', '' ) ),
|
||||||
offsetTop = Number( this.element.style.marginTop.replace( 'px', '' ) ),
|
offsetTop = Number( this.element.style.marginTop.replace( 'px', '' ) ),
|
||||||
scrollWidth = Number( this.element.style.width.replace( 'px', '' ) ),
|
scrollWidth = Number( this.element.style.width.replace( 'px', '' ) ),
|
||||||
scrollHeight = Number( this.element.style.height.replace( 'px', '' ) ),
|
scrollHeight = Number( this.element.style.height.replace( 'px', '' ) ),
|
||||||
viewerSize = $.getElementSize( this.viewer.canvas );
|
viewerSize = $.getElementSize( this.viewer.canvas );
|
||||||
this.dragging = true;
|
|
||||||
if ( this.element ) {
|
if ( 'horizontal' === this.scroll ) {
|
||||||
if ( 'horizontal' == this.scroll ) {
|
|
||||||
if ( -event.delta.x > 0 ) {
|
if ( -event.delta.x > 0 ) {
|
||||||
//forward
|
//forward
|
||||||
if ( offsetLeft > -( scrollWidth - viewerSize.x ) ) {
|
if ( offsetLeft > -( scrollWidth - viewerSize.x ) ) {
|
||||||
@ -354,7 +357,6 @@ function onStripDrag( event ) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -366,13 +368,14 @@ function onStripDrag( event ) {
|
|||||||
* @function
|
* @function
|
||||||
*/
|
*/
|
||||||
function onStripScroll( event ) {
|
function onStripScroll( event ) {
|
||||||
var offsetLeft = Number( this.element.style.marginLeft.replace( 'px', '' ) ),
|
if ( this.element ) {
|
||||||
|
var offsetLeft = Number( this.element.style.marginLeft.replace( 'px', '' ) ),
|
||||||
offsetTop = Number( this.element.style.marginTop.replace( 'px', '' ) ),
|
offsetTop = Number( this.element.style.marginTop.replace( 'px', '' ) ),
|
||||||
scrollWidth = Number( this.element.style.width.replace( 'px', '' ) ),
|
scrollWidth = Number( this.element.style.width.replace( 'px', '' ) ),
|
||||||
scrollHeight = Number( this.element.style.height.replace( 'px', '' ) ),
|
scrollHeight = Number( this.element.style.height.replace( 'px', '' ) ),
|
||||||
viewerSize = $.getElementSize( this.viewer.canvas );
|
viewerSize = $.getElementSize( this.viewer.canvas );
|
||||||
if ( this.element ) {
|
|
||||||
if ( 'horizontal' == this.scroll ) {
|
if ( 'horizontal' === this.scroll ) {
|
||||||
if ( event.scroll > 0 ) {
|
if ( event.scroll > 0 ) {
|
||||||
//forward
|
//forward
|
||||||
if ( offsetLeft > -( scrollWidth - viewerSize.x ) ) {
|
if ( offsetLeft > -( scrollWidth - viewerSize.x ) ) {
|
||||||
@ -401,9 +404,9 @@ function onStripScroll( event ) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
event.preventDefault = true;
|
||||||
}
|
}
|
||||||
//cancels event
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -412,10 +415,9 @@ function loadPanels( strip, viewerSize, scroll ) {
|
|||||||
activePanelsStart,
|
activePanelsStart,
|
||||||
activePanelsEnd,
|
activePanelsEnd,
|
||||||
miniViewer,
|
miniViewer,
|
||||||
style,
|
|
||||||
i,
|
i,
|
||||||
element;
|
element;
|
||||||
if ( 'horizontal' == strip.scroll ) {
|
if ( 'horizontal' === strip.scroll ) {
|
||||||
panelSize = strip.panelWidth;
|
panelSize = strip.panelWidth;
|
||||||
} else {
|
} else {
|
||||||
panelSize = strip.panelHeight;
|
panelSize = strip.panelHeight;
|
||||||
@ -451,36 +453,17 @@ function loadPanels( strip, viewerSize, scroll ) {
|
|||||||
blendTime: 0,
|
blendTime: 0,
|
||||||
animationTime: 0,
|
animationTime: 0,
|
||||||
loadTilesWithAjax: strip.viewer.loadTilesWithAjax,
|
loadTilesWithAjax: strip.viewer.loadTilesWithAjax,
|
||||||
ajaxHeaders: strip.viewer.ajaxHeaders
|
ajaxHeaders: strip.viewer.ajaxHeaders,
|
||||||
|
useCanvas: strip.useCanvas
|
||||||
} );
|
} );
|
||||||
|
// Allow pointer events to pass through miniViewer's canvas/container
|
||||||
miniViewer.displayRegion = $.makeNeutralElement( "div" );
|
// elements so implicit pointer capture works on touch devices
|
||||||
miniViewer.displayRegion.id = element.id + '-displayregion';
|
$.setElementPointerEventsNone( miniViewer.canvas );
|
||||||
miniViewer.displayRegion.className = 'displayregion';
|
$.setElementPointerEventsNone( miniViewer.container );
|
||||||
|
// We'll use event delegation from the reference strip element instead of
|
||||||
style = miniViewer.displayRegion.style;
|
// handling events on every miniViewer
|
||||||
style.position = 'relative';
|
miniViewer.innerTracker.setTracking( false );
|
||||||
style.top = '0px';
|
miniViewer.outerTracker.setTracking( false );
|
||||||
style.left = '0px';
|
|
||||||
style.fontSize = '0px';
|
|
||||||
style.overflow = 'hidden';
|
|
||||||
style.float = 'left'; //Webkit
|
|
||||||
style.cssFloat = 'left'; //Firefox
|
|
||||||
style.styleFloat = 'left'; //IE
|
|
||||||
style.zIndex = 999999999;
|
|
||||||
style.cursor = 'default';
|
|
||||||
style.width = ( strip.panelWidth - 4 ) + 'px';
|
|
||||||
style.height = ( strip.panelHeight - 4 ) + 'px';
|
|
||||||
|
|
||||||
// TODO: What is this for? Future keyboard navigation support?
|
|
||||||
miniViewer.displayRegion.innerTracker = new $.MouseTracker( {
|
|
||||||
element: miniViewer.displayRegion,
|
|
||||||
startDisabled: true
|
|
||||||
} );
|
|
||||||
|
|
||||||
element.getElementsByTagName( 'div' )[0].appendChild(
|
|
||||||
miniViewer.displayRegion
|
|
||||||
);
|
|
||||||
|
|
||||||
strip.miniViewers[element.id] = miniViewer;
|
strip.miniViewers[element.id] = miniViewer;
|
||||||
|
|
||||||
@ -503,7 +486,7 @@ function onStripEnter( event ) {
|
|||||||
//element.style.border = '1px solid #555';
|
//element.style.border = '1px solid #555';
|
||||||
//element.style.background = '#000';
|
//element.style.background = '#000';
|
||||||
|
|
||||||
if ( 'horizontal' == this.scroll ) {
|
if ( 'horizontal' === this.scroll ) {
|
||||||
|
|
||||||
//element.style.paddingTop = "0px";
|
//element.style.paddingTop = "0px";
|
||||||
element.style.marginBottom = "0px";
|
element.style.marginBottom = "0px";
|
||||||
@ -514,7 +497,6 @@ function onStripEnter( event ) {
|
|||||||
element.style.marginLeft = "0px";
|
element.style.marginLeft = "0px";
|
||||||
|
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -523,10 +505,10 @@ function onStripEnter( event ) {
|
|||||||
* @inner
|
* @inner
|
||||||
* @function
|
* @function
|
||||||
*/
|
*/
|
||||||
function onStripExit( event ) {
|
function onStripLeave( event ) {
|
||||||
var element = event.eventSource.element;
|
var element = event.eventSource.element;
|
||||||
|
|
||||||
if ( 'horizontal' == this.scroll ) {
|
if ( 'horizontal' === this.scroll ) {
|
||||||
|
|
||||||
//element.style.paddingTop = "10px";
|
//element.style.paddingTop = "10px";
|
||||||
element.style.marginBottom = "-" + ( $.getElementSize( element ).y / 2 ) + "px";
|
element.style.marginBottom = "-" + ( $.getElementSize( element ).y / 2 ) + "px";
|
||||||
@ -537,7 +519,6 @@ function onStripExit( event ) {
|
|||||||
element.style.marginLeft = "-" + ( $.getElementSize( element ).x / 2 ) + "px";
|
element.style.marginLeft = "-" + ( $.getElementSize( element ).x / 2 ) + "px";
|
||||||
|
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -549,26 +530,31 @@ function onStripExit( event ) {
|
|||||||
function onKeyDown( event ) {
|
function onKeyDown( event ) {
|
||||||
//console.log( event.keyCode );
|
//console.log( event.keyCode );
|
||||||
|
|
||||||
if ( !event.preventDefaultAction && !event.ctrl && !event.alt && !event.meta ) {
|
if ( !event.ctrl && !event.alt && !event.meta ) {
|
||||||
switch ( event.keyCode ) {
|
switch ( event.keyCode ) {
|
||||||
case 38: //up arrow
|
case 38: //up arrow
|
||||||
onStripScroll.call( this, { eventSource: this.tracker, position: null, scroll: 1, shift: null } );
|
onStripScroll.call( this, { eventSource: this.tracker, position: null, scroll: 1, shift: null } );
|
||||||
return false;
|
event.preventDefault = true;
|
||||||
|
break;
|
||||||
case 40: //down arrow
|
case 40: //down arrow
|
||||||
onStripScroll.call( this, { eventSource: this.tracker, position: null, scroll: -1, shift: null } );
|
onStripScroll.call( this, { eventSource: this.tracker, position: null, scroll: -1, shift: null } );
|
||||||
return false;
|
event.preventDefault = true;
|
||||||
|
break;
|
||||||
case 37: //left arrow
|
case 37: //left arrow
|
||||||
onStripScroll.call( this, { eventSource: this.tracker, position: null, scroll: -1, shift: null } );
|
onStripScroll.call( this, { eventSource: this.tracker, position: null, scroll: -1, shift: null } );
|
||||||
return false;
|
event.preventDefault = true;
|
||||||
|
break;
|
||||||
case 39: //right arrow
|
case 39: //right arrow
|
||||||
onStripScroll.call( this, { eventSource: this.tracker, position: null, scroll: 1, shift: null } );
|
onStripScroll.call( this, { eventSource: this.tracker, position: null, scroll: 1, shift: null } );
|
||||||
return false;
|
event.preventDefault = true;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
//console.log( 'navigator keycode %s', event.keyCode );
|
//console.log( 'navigator keycode %s', event.keyCode );
|
||||||
return true;
|
event.preventDefault = false;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return true;
|
event.preventDefault = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -581,35 +567,42 @@ function onKeyDown( event ) {
|
|||||||
function onKeyPress( event ) {
|
function onKeyPress( event ) {
|
||||||
//console.log( event.keyCode );
|
//console.log( event.keyCode );
|
||||||
|
|
||||||
if ( !event.preventDefaultAction && !event.ctrl && !event.alt && !event.meta ) {
|
if ( !event.ctrl && !event.alt && !event.meta ) {
|
||||||
switch ( event.keyCode ) {
|
switch ( event.keyCode ) {
|
||||||
case 61: //=|+
|
case 61: //=|+
|
||||||
onStripScroll.call( this, { eventSource: this.tracker, position: null, scroll: 1, shift: null } );
|
onStripScroll.call( this, { eventSource: this.tracker, position: null, scroll: 1, shift: null } );
|
||||||
return false;
|
event.preventDefault = true;
|
||||||
|
break;
|
||||||
case 45: //-|_
|
case 45: //-|_
|
||||||
onStripScroll.call( this, { eventSource: this.tracker, position: null, scroll: -1, shift: null } );
|
onStripScroll.call( this, { eventSource: this.tracker, position: null, scroll: -1, shift: null } );
|
||||||
return false;
|
event.preventDefault = true;
|
||||||
|
break;
|
||||||
case 48: //0|)
|
case 48: //0|)
|
||||||
case 119: //w
|
case 119: //w
|
||||||
case 87: //W
|
case 87: //W
|
||||||
onStripScroll.call( this, { eventSource: this.tracker, position: null, scroll: 1, shift: null } );
|
onStripScroll.call( this, { eventSource: this.tracker, position: null, scroll: 1, shift: null } );
|
||||||
return false;
|
event.preventDefault = true;
|
||||||
|
break;
|
||||||
case 115: //s
|
case 115: //s
|
||||||
case 83: //S
|
case 83: //S
|
||||||
onStripScroll.call( this, { eventSource: this.tracker, position: null, scroll: -1, shift: null } );
|
onStripScroll.call( this, { eventSource: this.tracker, position: null, scroll: -1, shift: null } );
|
||||||
return false;
|
event.preventDefault = true;
|
||||||
|
break;
|
||||||
case 97: //a
|
case 97: //a
|
||||||
onStripScroll.call( this, { eventSource: this.tracker, position: null, scroll: -1, shift: null } );
|
onStripScroll.call( this, { eventSource: this.tracker, position: null, scroll: -1, shift: null } );
|
||||||
return false;
|
event.preventDefault = true;
|
||||||
|
break;
|
||||||
case 100: //d
|
case 100: //d
|
||||||
onStripScroll.call( this, { eventSource: this.tracker, position: null, scroll: 1, shift: null } );
|
onStripScroll.call( this, { eventSource: this.tracker, position: null, scroll: 1, shift: null } );
|
||||||
return false;
|
event.preventDefault = true;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
//console.log( 'navigator keycode %s', event.keyCode );
|
//console.log( 'navigator keycode %s', event.keyCode );
|
||||||
return true;
|
event.preventDefault = false;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return true;
|
event.preventDefault = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,11 +50,11 @@
|
|||||||
$.Spring = function( options ) {
|
$.Spring = function( options ) {
|
||||||
var args = arguments;
|
var args = arguments;
|
||||||
|
|
||||||
if( typeof ( options ) != 'object' ){
|
if( typeof ( options ) !== 'object' ){
|
||||||
//allows backward compatible use of ( initialValue, config ) as
|
//allows backward compatible use of ( initialValue, config ) as
|
||||||
//constructor parameters
|
//constructor parameters
|
||||||
options = {
|
options = {
|
||||||
initial: args.length && typeof ( args[ 0 ] ) == "number" ?
|
initial: args.length && typeof ( args[ 0 ] ) === "number" ?
|
||||||
args[ 0 ] :
|
args[ 0 ] :
|
||||||
undefined,
|
undefined,
|
||||||
/**
|
/**
|
||||||
@ -96,7 +96,7 @@ $.Spring = function( options ) {
|
|||||||
* @property {Number} time
|
* @property {Number} time
|
||||||
*/
|
*/
|
||||||
this.current = {
|
this.current = {
|
||||||
value: typeof ( this.initial ) == "number" ?
|
value: typeof ( this.initial ) === "number" ?
|
||||||
this.initial :
|
this.initial :
|
||||||
(this._exponential ? 0 : 1),
|
(this._exponential ? 0 : 1),
|
||||||
time: $.now() // always work in milliseconds
|
time: $.now() // always work in milliseconds
|
||||||
@ -237,7 +237,7 @@ $.Spring.prototype = {
|
|||||||
this.current.value = currentValue;
|
this.current.value = currentValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
return oldValue != this.current.value;
|
return oldValue !== this.current.value;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -82,7 +82,7 @@ $.extend( $, /** @lends OpenSeadragon */{
|
|||||||
}
|
}
|
||||||
string = container[ props[ i ] ];
|
string = container[ props[ i ] ];
|
||||||
|
|
||||||
if ( typeof ( string ) != "string" ) {
|
if ( typeof ( string ) !== "string" ) {
|
||||||
$.console.log( "Untranslated source string:", prop );
|
$.console.log( "Untranslated source string:", prop );
|
||||||
string = ""; // FIXME: this breaks gettext()-style convention, which would return source
|
string = ""; // FIXME: this breaks gettext()-style convention, which would return source
|
||||||
}
|
}
|
||||||
|
20
src/tile.js
20
src/tile.js
@ -176,6 +176,12 @@ $.Tile = function(level, x, y, bounds, exists, url, context2D, loadWithAjax, aja
|
|||||||
* @memberof OpenSeadragon.Tile#
|
* @memberof OpenSeadragon.Tile#
|
||||||
*/
|
*/
|
||||||
this.size = null;
|
this.size = null;
|
||||||
|
/**
|
||||||
|
* Whether to flip the tile when rendering.
|
||||||
|
* @member {Boolean} flipped
|
||||||
|
* @memberof OpenSeadragon.Tile#
|
||||||
|
*/
|
||||||
|
this.flipped = false;
|
||||||
/**
|
/**
|
||||||
* The start time of this tile's blending.
|
* The start time of this tile's blending.
|
||||||
* @member {Number} blendStart
|
* @member {Number} blendStart
|
||||||
@ -284,10 +290,10 @@ $.Tile.prototype = {
|
|||||||
this.style = this.element.style;
|
this.style = this.element.style;
|
||||||
this.style.position = "absolute";
|
this.style.position = "absolute";
|
||||||
}
|
}
|
||||||
if ( this.element.parentNode != container ) {
|
if ( this.element.parentNode !== container ) {
|
||||||
container.appendChild( this.element );
|
container.appendChild( this.element );
|
||||||
}
|
}
|
||||||
if ( this.imgElement.parentNode != this.element ) {
|
if ( this.imgElement.parentNode !== this.element ) {
|
||||||
this.element.appendChild( this.imgElement );
|
this.element.appendChild( this.imgElement );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -296,6 +302,10 @@ $.Tile.prototype = {
|
|||||||
this.style.height = this.size.y + "px";
|
this.style.height = this.size.y + "px";
|
||||||
this.style.width = this.size.x + "px";
|
this.style.width = this.size.x + "px";
|
||||||
|
|
||||||
|
if (this.flipped) {
|
||||||
|
this.style.transform = "scaleX(-1)";
|
||||||
|
}
|
||||||
|
|
||||||
$.setElementOpacity( this.element, this.opacity );
|
$.setElementOpacity( this.element, this.opacity );
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -383,13 +393,17 @@ $.Tile.prototype = {
|
|||||||
sourceHeight = rendered.canvas.height;
|
sourceHeight = rendered.canvas.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
context.translate(position.x + size.x / 2, 0);
|
||||||
|
if (this.flipped) {
|
||||||
|
context.scale(-1, 1);
|
||||||
|
}
|
||||||
context.drawImage(
|
context.drawImage(
|
||||||
rendered.canvas,
|
rendered.canvas,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
sourceWidth,
|
sourceWidth,
|
||||||
sourceHeight,
|
sourceHeight,
|
||||||
position.x,
|
-size.x / 2,
|
||||||
position.y,
|
position.y,
|
||||||
size.x,
|
size.x,
|
||||||
size.y
|
size.y
|
||||||
|
@ -196,7 +196,7 @@ $.TileCache.prototype = {
|
|||||||
worstLevel = worstTile.level;
|
worstLevel = worstTile.level;
|
||||||
|
|
||||||
if ( prevTime < worstTime ||
|
if ( prevTime < worstTime ||
|
||||||
( prevTime == worstTime && prevLevel > worstLevel ) ) {
|
( prevTime === worstTime && prevLevel > worstLevel ) ) {
|
||||||
worstTile = prevTile;
|
worstTile = prevTile;
|
||||||
worstTileIndex = i;
|
worstTileIndex = i;
|
||||||
worstTileRecord = prevTileRecord;
|
worstTileRecord = prevTileRecord;
|
||||||
|
@ -326,6 +326,10 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
|
|||||||
*/
|
*/
|
||||||
destroy: function() {
|
destroy: function() {
|
||||||
this.reset();
|
this.reset();
|
||||||
|
|
||||||
|
if (this.source.destroy) {
|
||||||
|
this.source.destroy();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -388,6 +392,26 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
|
|||||||
return bounds.rotate(this.getRotation(current), this._getRotationPoint(current));
|
return bounds.rotate(this.getRotation(current), this._getRotationPoint(current));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @function
|
||||||
|
* @param {Number} level
|
||||||
|
* @param {Number} x
|
||||||
|
* @param {Number} y
|
||||||
|
* @returns {OpenSeadragon.Rect} Where this tile fits (in normalized coordinates).
|
||||||
|
*/
|
||||||
|
getTileBounds: function( level, x, y ) {
|
||||||
|
var numTiles = this.source.getNumTiles(level);
|
||||||
|
var xMod = ( numTiles.x + ( x % numTiles.x ) ) % numTiles.x;
|
||||||
|
var yMod = ( numTiles.y + ( y % numTiles.y ) ) % numTiles.y;
|
||||||
|
var bounds = this.source.getTileBounds(level, xMod, yMod);
|
||||||
|
if (this.getFlip()) {
|
||||||
|
bounds.x = 1 - bounds.x - bounds.width;
|
||||||
|
}
|
||||||
|
bounds.x += (x - xMod) / numTiles.x;
|
||||||
|
bounds.y += (this._worldHeightCurrent / this._worldWidthCurrent) * ((y - yMod) / numTiles.y);
|
||||||
|
return bounds;
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns {OpenSeadragon.Point} This TiledImage's content size, in original pixels.
|
* @returns {OpenSeadragon.Point} This TiledImage's content size, in original pixels.
|
||||||
*/
|
*/
|
||||||
@ -395,6 +419,15 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
|
|||||||
return new $.Point(this.source.dimensions.x, this.source.dimensions.y);
|
return new $.Point(this.source.dimensions.x, this.source.dimensions.y);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {OpenSeadragon.Point} The TiledImage's content size, in window coordinates.
|
||||||
|
*/
|
||||||
|
getSizeInWindowCoordinates: function() {
|
||||||
|
var topLeft = this.imageToWindowCoordinates(new $.Point(0, 0));
|
||||||
|
var bottomRight = this.imageToWindowCoordinates(this.getContentSize());
|
||||||
|
return new $.Point(bottomRight.x - topLeft.x, bottomRight.y - topLeft.y);
|
||||||
|
},
|
||||||
|
|
||||||
// private
|
// private
|
||||||
_viewportToImageDelta: function( viewerX, viewerY, current ) {
|
_viewportToImageDelta: function( viewerX, viewerY, current ) {
|
||||||
var scale = (current ? this._scaleSpring.current.value : this._scaleSpring.target.value);
|
var scale = (current ? this._scaleSpring.current.value : this._scaleSpring.target.value);
|
||||||
@ -674,6 +707,58 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
|
|||||||
this._setScale(height / this.normHeight, immediately);
|
this._setScale(height / this.normHeight, immediately);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets an array of polygons to crop the TiledImage during draw tiles.
|
||||||
|
* The render function will use the default non-zero winding rule.
|
||||||
|
* @param {OpenSeadragon.Point[][]} polygons - represented in an array of point object in image coordinates.
|
||||||
|
* Example format: [
|
||||||
|
* [{x: 197, y:172}, {x: 226, y:172}, {x: 226, y:198}, {x: 197, y:198}], // First polygon
|
||||||
|
* [{x: 328, y:200}, {x: 330, y:199}, {x: 332, y:201}, {x: 329, y:202}] // Second polygon
|
||||||
|
* [{x: 321, y:201}, {x: 356, y:205}, {x: 341, y:250}] // Third polygon
|
||||||
|
* ]
|
||||||
|
*/
|
||||||
|
setCroppingPolygons: function( polygons ) {
|
||||||
|
|
||||||
|
var isXYObject = function(obj) {
|
||||||
|
return obj instanceof $.Point || (typeof obj.x === 'number' && typeof obj.y === 'number');
|
||||||
|
};
|
||||||
|
|
||||||
|
var objectToSimpleXYObject = function(objs) {
|
||||||
|
return objs.map(function(obj) {
|
||||||
|
try {
|
||||||
|
if (isXYObject(obj)) {
|
||||||
|
return { x: obj.x, y: obj.y };
|
||||||
|
} else {
|
||||||
|
throw new Error();
|
||||||
|
}
|
||||||
|
} catch(e) {
|
||||||
|
throw new Error('A Provided cropping polygon point is not supported');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (!$.isArray(polygons)) {
|
||||||
|
throw new Error('Provided cropping polygon is not an array');
|
||||||
|
}
|
||||||
|
this._croppingPolygons = polygons.map(function(polygon){
|
||||||
|
return objectToSimpleXYObject(polygon);
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
$.console.error('[TiledImage.setCroppingPolygons] Cropping polygon format not supported');
|
||||||
|
$.console.error(e);
|
||||||
|
this._croppingPolygons = null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets the cropping polygons, thus next render will remove all cropping
|
||||||
|
* polygon effects.
|
||||||
|
*/
|
||||||
|
resetCroppingPolygons: function() {
|
||||||
|
this._croppingPolygons = null;
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Positions and scales the TiledImage to fit in the specified bounds.
|
* Positions and scales the TiledImage to fit in the specified bounds.
|
||||||
* Note: this method fires OpenSeadragon.TiledImage.event:bounds-change
|
* Note: this method fires OpenSeadragon.TiledImage.event:bounds-change
|
||||||
@ -776,6 +861,23 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
|
|||||||
this.raiseEvent('clip-change');
|
this.raiseEvent('clip-change');
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {Boolean} Whether the TiledImage should be flipped before rendering.
|
||||||
|
*/
|
||||||
|
getFlip: function() {
|
||||||
|
return !!this.flipped;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Boolean} flip Whether the TiledImage should be flipped before rendering.
|
||||||
|
* @fires OpenSeadragon.TiledImage.event:bounds-change
|
||||||
|
*/
|
||||||
|
setFlip: function(flip) {
|
||||||
|
this.flipped = !!flip;
|
||||||
|
this._needsDraw = true;
|
||||||
|
this._raiseBoundsChange();
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns {Number} The TiledImage's current opacity.
|
* @returns {Number} The TiledImage's current opacity.
|
||||||
*/
|
*/
|
||||||
@ -1199,24 +1301,41 @@ function updateLevel(tiledImage, haveDrawn, drawLevel, level, levelOpacity,
|
|||||||
|
|
||||||
var viewportCenter = tiledImage.viewport.pixelFromPoint(
|
var viewportCenter = tiledImage.viewport.pixelFromPoint(
|
||||||
tiledImage.viewport.getCenter());
|
tiledImage.viewport.getCenter());
|
||||||
|
|
||||||
|
if (tiledImage.getFlip()) {
|
||||||
|
// The right-most tile can be narrower than the others. When flipped,
|
||||||
|
// this tile is now on the left. Because it is narrower than the normal
|
||||||
|
// left-most tile, the subsequent tiles may not be wide enough to completely
|
||||||
|
// fill the viewport. Fix this by rendering an extra column of tiles. If we
|
||||||
|
// are not wrapping, make sure we never render more than the number of tiles
|
||||||
|
// in the image.
|
||||||
|
bottomRightTile.x += 1;
|
||||||
|
if (!tiledImage.wrapHorizontal) {
|
||||||
|
bottomRightTile.x = Math.min(bottomRightTile.x, numberOfTiles.x - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (var x = topLeftTile.x; x <= bottomRightTile.x; x++) {
|
for (var x = topLeftTile.x; x <= bottomRightTile.x; x++) {
|
||||||
for (var y = topLeftTile.y; y <= bottomRightTile.y; y++) {
|
for (var y = topLeftTile.y; y <= bottomRightTile.y; y++) {
|
||||||
|
|
||||||
// Optimisation disabled with wrapping because getTileBounds does not
|
var flippedX;
|
||||||
// work correctly with x and y outside of the number of tiles
|
if (tiledImage.getFlip()) {
|
||||||
if (!tiledImage.wrapHorizontal && !tiledImage.wrapVertical) {
|
var xMod = ( numberOfTiles.x + ( x % numberOfTiles.x ) ) % numberOfTiles.x;
|
||||||
var tileBounds = tiledImage.source.getTileBounds(level, x, y);
|
flippedX = x + numberOfTiles.x - xMod - xMod - 1;
|
||||||
if (drawArea.intersection(tileBounds) === null) {
|
} else {
|
||||||
// This tile is outside of the viewport, no need to draw it
|
flippedX = x;
|
||||||
continue;
|
}
|
||||||
}
|
|
||||||
|
if (drawArea.intersection(tiledImage.getTileBounds(level, flippedX, y)) === null) {
|
||||||
|
// This tile is outside of the viewport, no need to draw it
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
best = updateTile(
|
best = updateTile(
|
||||||
tiledImage,
|
tiledImage,
|
||||||
drawLevel,
|
drawLevel,
|
||||||
haveDrawn,
|
haveDrawn,
|
||||||
x, y,
|
flippedX, y,
|
||||||
level,
|
level,
|
||||||
levelOpacity,
|
levelOpacity,
|
||||||
levelVisibility,
|
levelVisibility,
|
||||||
@ -1391,10 +1510,10 @@ function getTile(
|
|||||||
tilesMatrix[ level ][ x ] = {};
|
tilesMatrix[ level ][ x ] = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !tilesMatrix[ level ][ x ][ y ] ) {
|
if ( !tilesMatrix[ level ][ x ][ y ] || !tilesMatrix[ level ][ x ][ y ].flipped !== !tiledImage.flipped ) {
|
||||||
xMod = ( numTiles.x + ( x % numTiles.x ) ) % numTiles.x;
|
xMod = ( numTiles.x + ( x % numTiles.x ) ) % numTiles.x;
|
||||||
yMod = ( numTiles.y + ( y % numTiles.y ) ) % numTiles.y;
|
yMod = ( numTiles.y + ( y % numTiles.y ) ) % numTiles.y;
|
||||||
bounds = tileSource.getTileBounds( level, xMod, yMod );
|
bounds = tiledImage.getTileBounds( level, x, y );
|
||||||
sourceBounds = tileSource.getTileBounds( level, xMod, yMod, true );
|
sourceBounds = tileSource.getTileBounds( level, xMod, yMod, true );
|
||||||
exists = tileSource.tileExists( level, xMod, yMod );
|
exists = tileSource.tileExists( level, xMod, yMod );
|
||||||
url = tileSource.getTileUrl( level, xMod, yMod );
|
url = tileSource.getTileUrl( level, xMod, yMod );
|
||||||
@ -1413,9 +1532,6 @@ function getTile(
|
|||||||
context2D = tileSource.getContext2D ?
|
context2D = tileSource.getContext2D ?
|
||||||
tileSource.getContext2D(level, xMod, yMod) : undefined;
|
tileSource.getContext2D(level, xMod, yMod) : undefined;
|
||||||
|
|
||||||
bounds.x += ( x - xMod ) / numTiles.x;
|
|
||||||
bounds.y += (worldHeight / worldWidth) * (( y - yMod ) / numTiles.y);
|
|
||||||
|
|
||||||
tile = new $.Tile(
|
tile = new $.Tile(
|
||||||
level,
|
level,
|
||||||
x,
|
x,
|
||||||
@ -1429,14 +1545,22 @@ function getTile(
|
|||||||
sourceBounds
|
sourceBounds
|
||||||
);
|
);
|
||||||
|
|
||||||
if (xMod === numTiles.x - 1) {
|
if (tiledImage.getFlip()) {
|
||||||
tile.isRightMost = true;
|
if (xMod === 0) {
|
||||||
|
tile.isRightMost = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (xMod === numTiles.x - 1) {
|
||||||
|
tile.isRightMost = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (yMod === numTiles.y - 1) {
|
if (yMod === numTiles.y - 1) {
|
||||||
tile.isBottomMost = true;
|
tile.isBottomMost = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tile.flipped = tiledImage.flipped;
|
||||||
|
|
||||||
tilesMatrix[ level ][ x ][ y ] = tile;
|
tilesMatrix[ level ][ x ][ y ] = tile;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1573,7 +1697,7 @@ function setTileLoaded(tiledImage, tile, image, cutoff, tileRequest) {
|
|||||||
* @property {Image} image - The image of the tile.
|
* @property {Image} image - The image of the tile.
|
||||||
* @property {OpenSeadragon.TiledImage} tiledImage - The tiled image of the loaded tile.
|
* @property {OpenSeadragon.TiledImage} tiledImage - The tiled image of the loaded tile.
|
||||||
* @property {OpenSeadragon.Tile} tile - The tile which has been loaded.
|
* @property {OpenSeadragon.Tile} tile - The tile which has been loaded.
|
||||||
* @property {XMLHttpRequest} tiledImage - The AJAX request that loaded this tile (if applicable).
|
* @property {XMLHttpRequest} tileRequest - The AJAX request that loaded this tile (if applicable).
|
||||||
* @property {function} getCompletionCallback - A function giving a callback to call
|
* @property {function} getCompletionCallback - A function giving a callback to call
|
||||||
* when the asynchronous processing of the image is done. The image will be
|
* when the asynchronous processing of the image is done. The image will be
|
||||||
* marked as entirely loaded when the callback has been called once for each
|
* marked as entirely loaded when the callback has been called once for each
|
||||||
@ -1714,10 +1838,10 @@ function providesCoverage( coverage, level, x, y ) {
|
|||||||
if ( x === undefined || y === undefined ) {
|
if ( x === undefined || y === undefined ) {
|
||||||
rows = coverage[ level ];
|
rows = coverage[ level ];
|
||||||
for ( i in rows ) {
|
for ( i in rows ) {
|
||||||
if ( rows.hasOwnProperty( i ) ) {
|
if ( Object.prototype.hasOwnProperty.call( rows, i ) ) {
|
||||||
cols = rows[ i ];
|
cols = rows[ i ];
|
||||||
for ( j in cols ) {
|
for ( j in cols ) {
|
||||||
if ( cols.hasOwnProperty( j ) && !cols[ j ] ) {
|
if ( Object.prototype.hasOwnProperty.call( cols, j ) && !cols[ j ] ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1818,7 +1942,7 @@ function compareTiles( previousBest, tile ) {
|
|||||||
|
|
||||||
if ( tile.visibility > previousBest.visibility ) {
|
if ( tile.visibility > previousBest.visibility ) {
|
||||||
return tile;
|
return tile;
|
||||||
} else if ( tile.visibility == previousBest.visibility ) {
|
} else if ( tile.visibility === previousBest.visibility ) {
|
||||||
if ( tile.squaredDistance < previousBest.squaredDistance ) {
|
if ( tile.squaredDistance < previousBest.squaredDistance ) {
|
||||||
return tile;
|
return tile;
|
||||||
}
|
}
|
||||||
@ -1877,14 +2001,15 @@ function drawTiles( tiledImage, lastDrawn ) {
|
|||||||
// sketch canvas we are going to use for performance reasons.
|
// sketch canvas we are going to use for performance reasons.
|
||||||
bounds = tiledImage.viewport.viewportToViewerElementRectangle(
|
bounds = tiledImage.viewport.viewportToViewerElementRectangle(
|
||||||
tiledImage.getClippedBounds(true))
|
tiledImage.getClippedBounds(true))
|
||||||
.getIntegerBoundingBox()
|
.getIntegerBoundingBox();
|
||||||
.times($.pixelDensityRatio);
|
|
||||||
|
|
||||||
if(tiledImage._drawer.viewer.viewport.getFlip()) {
|
if(tiledImage._drawer.viewer.viewport.getFlip()) {
|
||||||
if (tiledImage.viewport.degrees !== 0 || tiledImage.getRotation(true) % 360 !== 0){
|
if (tiledImage.viewport.degrees !== 0 || tiledImage.getRotation(true) % 360 !== 0){
|
||||||
bounds.x = tiledImage._drawer.viewer.container.clientWidth - (bounds.x + bounds.width);
|
bounds.x = tiledImage._drawer.viewer.container.clientWidth - (bounds.x + bounds.width);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bounds = bounds.times($.pixelDensityRatio);
|
||||||
}
|
}
|
||||||
tiledImage._drawer._clear(true, bounds);
|
tiledImage._drawer._clear(true, bounds);
|
||||||
}
|
}
|
||||||
@ -1932,6 +2057,28 @@ function drawTiles( tiledImage, lastDrawn ) {
|
|||||||
usedClip = true;
|
usedClip = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tiledImage._croppingPolygons) {
|
||||||
|
tiledImage._drawer.saveContext(useSketch);
|
||||||
|
try {
|
||||||
|
var polygons = tiledImage._croppingPolygons.map(function (polygon) {
|
||||||
|
return polygon.map(function (coord) {
|
||||||
|
var point = tiledImage
|
||||||
|
.imageToViewportCoordinates(coord.x, coord.y, true)
|
||||||
|
.rotate(-tiledImage.getRotation(true), tiledImage._getRotationPoint(true));
|
||||||
|
var clipPoint = tiledImage._drawer.viewportCoordToDrawerCoord(point);
|
||||||
|
if (sketchScale) {
|
||||||
|
clipPoint = clipPoint.times(sketchScale);
|
||||||
|
}
|
||||||
|
return clipPoint;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
tiledImage._drawer.clipWithPolygons(polygons, useSketch);
|
||||||
|
} catch (e) {
|
||||||
|
$.console.error(e);
|
||||||
|
}
|
||||||
|
usedClip = true;
|
||||||
|
}
|
||||||
|
|
||||||
if ( tiledImage.placeholderFillStyle && tiledImage._hasOpaqueTile === false ) {
|
if ( tiledImage.placeholderFillStyle && tiledImage._hasOpaqueTile === false ) {
|
||||||
var placeholderRect = tiledImage._drawer.viewportToDrawerRectangle(tiledImage.getBounds(true));
|
var placeholderRect = tiledImage._drawer.viewportToDrawerRectangle(tiledImage.getBounds(true));
|
||||||
if (sketchScale) {
|
if (sketchScale) {
|
||||||
|
@ -167,7 +167,7 @@ $.TileSource = function( width, height, tileSize, tileOverlap, minLevel, maxLeve
|
|||||||
* @memberof OpenSeadragon.TileSource#
|
* @memberof OpenSeadragon.TileSource#
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if( 'string' == $.type( arguments[ 0 ] ) ){
|
if( 'string' === $.type( arguments[ 0 ] ) ){
|
||||||
this.url = arguments[0];
|
this.url = arguments[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -313,8 +313,8 @@ $.TileSource.prototype = {
|
|||||||
*/
|
*/
|
||||||
getPixelRatio: function( level ) {
|
getPixelRatio: function( level ) {
|
||||||
var imageSizeScaled = this.dimensions.times( this.getLevelScale( level ) ),
|
var imageSizeScaled = this.dimensions.times( this.getLevelScale( level ) ),
|
||||||
rx = 1.0 / imageSizeScaled.x,
|
rx = 1.0 / imageSizeScaled.x * $.pixelDensityRatio,
|
||||||
ry = 1.0 / imageSizeScaled.y;
|
ry = 1.0 / imageSizeScaled.y * $.pixelDensityRatio;
|
||||||
|
|
||||||
return new $.Point(rx, ry);
|
return new $.Point(rx, ry);
|
||||||
},
|
},
|
||||||
@ -500,7 +500,7 @@ $.TileSource.prototype = {
|
|||||||
msg = "HTTP " + xhr.status + " attempting to load TileSource";
|
msg = "HTTP " + xhr.status + " attempting to load TileSource";
|
||||||
} catch ( e ) {
|
} catch ( e ) {
|
||||||
var formattedExc;
|
var formattedExc;
|
||||||
if ( typeof ( exc ) == "undefined" || !exc.toString ) {
|
if ( typeof ( exc ) === "undefined" || !exc.toString ) {
|
||||||
formattedExc = "Unknown error";
|
formattedExc = "Unknown error";
|
||||||
} else {
|
} else {
|
||||||
formattedExc = exc.toString();
|
formattedExc = exc.toString();
|
||||||
@ -640,7 +640,7 @@ function processResponse( xhr ){
|
|||||||
throw new Error( $.getString( "Errors.Security" ) );
|
throw new Error( $.getString( "Errors.Security" ) );
|
||||||
} else if ( xhr.status !== 200 && xhr.status !== 0 ) {
|
} else if ( xhr.status !== 200 && xhr.status !== 0 ) {
|
||||||
status = xhr.status;
|
status = xhr.status;
|
||||||
statusText = ( status == 404 ) ?
|
statusText = ( status === 404 ) ?
|
||||||
"Not Found" :
|
"Not Found" :
|
||||||
xhr.statusText;
|
xhr.statusText;
|
||||||
throw new Error( $.getString( "Errors.Status", status, statusText ) );
|
throw new Error( $.getString( "Errors.Status", status, statusText ) );
|
||||||
@ -654,7 +654,7 @@ function processResponse( xhr ){
|
|||||||
} catch (e){
|
} catch (e){
|
||||||
data = xhr.responseText;
|
data = xhr.responseText;
|
||||||
}
|
}
|
||||||
}else if( responseText.match(/\s*[\{\[].*/) ){
|
}else if( responseText.match(/\s*[{[].*/) ){
|
||||||
try{
|
try{
|
||||||
data = $.parseJSON(responseText);
|
data = $.parseJSON(responseText);
|
||||||
} catch(e){
|
} catch(e){
|
||||||
@ -690,6 +690,8 @@ $.TileSource.determineType = function( tileSource, data, url ){
|
|||||||
}
|
}
|
||||||
|
|
||||||
$.console.error( "No TileSource was able to open %s %s", url, data );
|
$.console.error( "No TileSource was able to open %s %s", url, data );
|
||||||
|
|
||||||
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -103,7 +103,7 @@ $.extend( $.TmsTileSource.prototype, $.TileSource.prototype, /** @lends OpenSead
|
|||||||
* @param {String} optional - url
|
* @param {String} optional - url
|
||||||
*/
|
*/
|
||||||
supports: function( data, url ){
|
supports: function( data, url ){
|
||||||
return ( data.type && "tiledmapservice" == data.type );
|
return ( data.type && "tiledmapservice" === data.type );
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
570
src/viewer.js
570
src/viewer.js
File diff suppressed because it is too large
Load Diff
@ -898,7 +898,7 @@ $.Viewport.prototype = {
|
|||||||
* @property {Number} degrees - The number of degrees the rotation was set to.
|
* @property {Number} degrees - The number of degrees the rotation was set to.
|
||||||
* @property {?Object} userData - Arbitrary subscriber-defined object.
|
* @property {?Object} userData - Arbitrary subscriber-defined object.
|
||||||
*/
|
*/
|
||||||
this.viewer.raiseEvent('rotate', {"degrees": degrees});
|
this.viewer.raiseEvent('rotate', {degrees: degrees});
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -1567,7 +1567,7 @@ $.Viewport.prototype = {
|
|||||||
* @property {Number} flipped - The flip state after this change.
|
* @property {Number} flipped - The flip state after this change.
|
||||||
* @property {?Object} userData - Arbitrary subscriber-defined object.
|
* @property {?Object} userData - Arbitrary subscriber-defined object.
|
||||||
*/
|
*/
|
||||||
this.viewer.raiseEvent('flip', {"flipped": state});
|
this.viewer.raiseEvent('flip', {flipped: state});
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
* tilesUrl: "/test/data/zoomify/"
|
* tilesUrl: "/test/data/zoomify/"
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
* The tileSize is currently hardcoded to 256 (the usual Zoomify default). The tileUrl must the path to the image _directory_.
|
* The tileSize is set to 256 (the usual Zoomify default) when it is not defined. The tileUrl must the path to the image _directory_.
|
||||||
*
|
*
|
||||||
* 2) Loading image metadata from xml file: (CURRENTLY NOT SUPPORTED)
|
* 2) Loading image metadata from xml file: (CURRENTLY NOT SUPPORTED)
|
||||||
*
|
*
|
||||||
@ -44,7 +44,14 @@
|
|||||||
* @param {String} tilesUrl
|
* @param {String} tilesUrl
|
||||||
*/
|
*/
|
||||||
$.ZoomifyTileSource = function(options) {
|
$.ZoomifyTileSource = function(options) {
|
||||||
options.tileSize = 256;
|
if(typeof options.tileSize === 'undefined'){
|
||||||
|
options.tileSize = 256;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(typeof options.fileFormat === 'undefined'){
|
||||||
|
options.fileFormat = 'jpg';
|
||||||
|
this.fileFormat = options.fileFormat;
|
||||||
|
}
|
||||||
|
|
||||||
var currentImageSize = {
|
var currentImageSize = {
|
||||||
x: options.width,
|
x: options.width,
|
||||||
@ -107,7 +114,7 @@
|
|||||||
* @param {String} optional - url
|
* @param {String} optional - url
|
||||||
*/
|
*/
|
||||||
supports: function(data, url) {
|
supports: function(data, url) {
|
||||||
return (data.type && "zoomifytileservice" == data.type);
|
return (data.type && "zoomifytileservice" === data.type);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -133,7 +140,7 @@
|
|||||||
var result = 0;
|
var result = 0;
|
||||||
var num = this._calculateAbsoluteTileNumber(level, x, y);
|
var num = this._calculateAbsoluteTileNumber(level, x, y);
|
||||||
result = Math.floor(num / 256);
|
result = Math.floor(num / 256);
|
||||||
return this.tilesUrl + 'TileGroup' + result + '/' + level + '-' + x + '-' + y + '.jpg';
|
return this.tilesUrl + 'TileGroup' + result + '/' + level + '-' + x + '-' + y + '.' + this.fileFormat;
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -87,6 +87,7 @@
|
|||||||
<script src="/test/modules/rectangle.js"></script>
|
<script src="/test/modules/rectangle.js"></script>
|
||||||
<script src="/test/modules/ajax-tiles.js"></script>
|
<script src="/test/modules/ajax-tiles.js"></script>
|
||||||
<script src="/test/modules/imageloader.js"></script>
|
<script src="/test/modules/imageloader.js"></script>
|
||||||
|
<script src="/test/modules/iiif.js"></script>
|
||||||
<!-- The navigator tests are the slowest (for now; hopefully they can be sped up)
|
<!-- The navigator tests are the slowest (for now; hopefully they can be sped up)
|
||||||
so we put them last. -->
|
so we put them last. -->
|
||||||
<script src="/test/modules/navigator.js"></script>
|
<script src="/test/modules/navigator.js"></script>
|
||||||
|
165
test/demo/cropping-polygons.html
Normal file
165
test/demo/cropping-polygons.html
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>OpenSeadragon Cropping PolygonList Demo</title>
|
||||||
|
<script type="text/javascript" src='../../build/openseadragon/openseadragon.js'></script>
|
||||||
|
<script type="text/javascript" src='../lib/jquery-1.9.1.min.js'></script>
|
||||||
|
<style type="text/css">
|
||||||
|
|
||||||
|
.openseadragon1 {
|
||||||
|
width: 800px;
|
||||||
|
height: 600px;
|
||||||
|
background: lightgreen;
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea {
|
||||||
|
width: 215px;
|
||||||
|
height: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box-with-title {
|
||||||
|
padding-top: 1em;
|
||||||
|
display: inline-block;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.buttons {
|
||||||
|
width: 215px;
|
||||||
|
}
|
||||||
|
|
||||||
|
*:focus {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h3>
|
||||||
|
Simple demo page to show cropping with polygonList in a OpenSeadragon viewer.
|
||||||
|
</h3>
|
||||||
|
<div id="contentDiv" class="openseadragon1"></div>
|
||||||
|
<span>Click on Viewer to save polygon points</span>
|
||||||
|
<div>
|
||||||
|
<button id='resetBtn'>Reset</button>
|
||||||
|
<button id='exampleBtn'>Load Example</button>
|
||||||
|
</div>
|
||||||
|
<div class='box-with-title'>
|
||||||
|
<div class="buttons">
|
||||||
|
<button id="addPointBtn">Add Points as Polygon</button>
|
||||||
|
<button onclick="emptyElement('polygonPointEl')">Clear</button>
|
||||||
|
</div>
|
||||||
|
<textarea id="polygonPointEl"></textarea>
|
||||||
|
</div>
|
||||||
|
<div class='box-with-title'>
|
||||||
|
<div class="buttons">
|
||||||
|
<button id="cropBtn">Crop With Polygon</button>
|
||||||
|
<button onclick="emptyElement('previewEl')">Clear</button>
|
||||||
|
</div>
|
||||||
|
<textarea id='previewEl'></textarea>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Setup Viewer -->
|
||||||
|
<script type="text/javascript">
|
||||||
|
var viewer = OpenSeadragon({
|
||||||
|
// debugMode: true,
|
||||||
|
id: "contentDiv",
|
||||||
|
prefixUrl: "../../build/openseadragon/images/",
|
||||||
|
tileSources: "../data/testpattern.dzi",
|
||||||
|
showNavigator: false,
|
||||||
|
gestureSettingsMouse: {
|
||||||
|
clickToZoom: false
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// Global Variables
|
||||||
|
var previewEl = document.getElementById('previewEl');
|
||||||
|
var polygonPointEl = document.getElementById('polygonPointEl');
|
||||||
|
|
||||||
|
var examples = [
|
||||||
|
[{x: 480, y: 300},{x: 300, y: 420},{x: 600, y: 420}], // Triangle
|
||||||
|
[{x: 300, y: 550},{x: 300, y: 750},{x: 600, y: 750},{x: 600, y: 550}] // Rectangle
|
||||||
|
];
|
||||||
|
|
||||||
|
// Load default examples
|
||||||
|
function loadExample(){
|
||||||
|
previewEl.value = JSON.stringify(examples);
|
||||||
|
}
|
||||||
|
loadExample();
|
||||||
|
|
||||||
|
// Set a given element's value to empty string
|
||||||
|
function emptyElement(elementId) {
|
||||||
|
document.getElementById(elementId).value = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
// JSON parse a given object, then insert object assuming parsed value is array.
|
||||||
|
function insertObjectToElement(object, element) {
|
||||||
|
var parsed = []; // Default to empty array
|
||||||
|
try {
|
||||||
|
parsed = JSON.parse(element.value);
|
||||||
|
} catch(error) { }
|
||||||
|
parsed.push(object);
|
||||||
|
element.value = JSON.stringify(parsed)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add click handler to clicked point tracker
|
||||||
|
viewer.addHandler('canvas-click', function(event) {
|
||||||
|
var viewportPoint = viewer.viewport.pointFromPixel(event.position);
|
||||||
|
var p = viewer.viewport.viewportToImageCoordinates(viewportPoint);
|
||||||
|
p.x = Math.round((p.x + Number.EPSILON) * 100) / 100
|
||||||
|
p.y = Math.round((p.y + Number.EPSILON) * 100) / 100
|
||||||
|
insertObjectToElement({x:p.x, y:p.y}, polygonPointEl);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Evaluate give element in JavaScript variable, default to empty array.
|
||||||
|
function readElementValueDefaultToEmptyArray(elementId) {
|
||||||
|
try {
|
||||||
|
var val = document.getElementById(elementId).value;
|
||||||
|
if (val === '') { return []; }
|
||||||
|
return eval(val); // If using JSON.parse, user must put quotes [{"x": 123, "y":12}]
|
||||||
|
} catch (e) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert value from given element into preview element
|
||||||
|
function insertValueFromElementToPreviewElement(element) {
|
||||||
|
try {
|
||||||
|
if (element.value === '') { return; }
|
||||||
|
var polygon = eval(element.value);
|
||||||
|
var polygonList = readElementValueDefaultToEmptyArray('previewEl');
|
||||||
|
polygonList.push(polygon);
|
||||||
|
element.value = '';
|
||||||
|
previewEl.value = JSON.stringify(polygonList);
|
||||||
|
} catch(error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add clicked points to polygon tracker variable as point objects
|
||||||
|
document.getElementById('addPointBtn').onclick = function(){
|
||||||
|
insertValueFromElementToPreviewElement(polygonPointEl);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Crop image with value in the preview element
|
||||||
|
document.getElementById('cropBtn').onclick = function(){
|
||||||
|
var polygonList = eval(previewEl.value);
|
||||||
|
var tiledImage = viewer.world.getItemAt(0);
|
||||||
|
tiledImage.setCroppingPolygons(polygonList);
|
||||||
|
viewer.forceRedraw();
|
||||||
|
emptyElement('previewEl');
|
||||||
|
};
|
||||||
|
|
||||||
|
document.getElementById('resetBtn').onclick = function(){
|
||||||
|
emptyElement('polygonPointEl');
|
||||||
|
emptyElement('previewEl');
|
||||||
|
var tiledImage = viewer.world.getItemAt(0);
|
||||||
|
tiledImage.resetCroppingPolygons();
|
||||||
|
viewer.forceRedraw();
|
||||||
|
};
|
||||||
|
|
||||||
|
document.getElementById('exampleBtn').onclick = loadExample;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
113
test/demo/flipping.html
Normal file
113
test/demo/flipping.html
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>OpenSeadragon Flipping Demo</title>
|
||||||
|
<script type="text/javascript" src='../../build/openseadragon/openseadragon.js'></script>
|
||||||
|
<script type="text/javascript" src='../lib/jquery-1.9.1.min.js'></script>
|
||||||
|
<style type="text/css">
|
||||||
|
|
||||||
|
.openseadragon1 {
|
||||||
|
width: 800px;
|
||||||
|
height: 600px;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.options {
|
||||||
|
margin: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
margin: 0.3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div>
|
||||||
|
Simple demo page to show image flipping.
|
||||||
|
</div>
|
||||||
|
<div id="contentDiv" class="openseadragon1">
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="options">
|
||||||
|
First
|
||||||
|
<div class="button">
|
||||||
|
<input type="checkbox" id="ffirst" onchange="flip(0, this.checked)">
|
||||||
|
<label for="ffirst">Flip</label>
|
||||||
|
</div>
|
||||||
|
<div class="button">
|
||||||
|
<input type="checkbox" id="rfirst" onchange="rotate(0, this.checked * 45)">
|
||||||
|
<label for="rfirst">Rotate</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="options">
|
||||||
|
Second
|
||||||
|
<div class="button">
|
||||||
|
<input type="checkbox" id="fsecond" onchange="flip(1, this.checked)" checked>
|
||||||
|
<label for="fsecond">Flip</label>
|
||||||
|
</div>
|
||||||
|
<div class="button">
|
||||||
|
<input type="checkbox" id="rsecond" onchange="rotate(1, this.checked * 45)">
|
||||||
|
<label for="rsecond">Rotate</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="options">
|
||||||
|
Viewport
|
||||||
|
<div class="button">
|
||||||
|
<input type="checkbox" id="fview" onchange="flipViewport(this.checked)">
|
||||||
|
<label for="fview">Flip Viewport</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="button">
|
||||||
|
<input type="checkbox" id="debug" onchange="debug(this.checked)">
|
||||||
|
<label for="debug">Debug Mode</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script type="text/javascript">
|
||||||
|
|
||||||
|
var viewer = OpenSeadragon({
|
||||||
|
// debugMode: true,
|
||||||
|
id: "contentDiv",
|
||||||
|
prefixUrl: "../../build/openseadragon/images/",
|
||||||
|
showNavigator:true,
|
||||||
|
tileSources: [
|
||||||
|
{
|
||||||
|
tileSource: "../data/testpattern.dzi",
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
flipped: document.getElementById("ffirst").checked,
|
||||||
|
degrees: document.getElementById("rfirst").checked * 45,
|
||||||
|
}, {
|
||||||
|
tileSource: "../data/testpattern.dzi",
|
||||||
|
x: 1,
|
||||||
|
y: 0,
|
||||||
|
flipped: document.getElementById("fsecond").checked,
|
||||||
|
degrees: document.getElementById("rsecond").checked * 45,
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
viewer.viewport.setFlip(document.getElementById("fview").checked);
|
||||||
|
|
||||||
|
function debug(v) {
|
||||||
|
viewer.setDebugMode(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
function flip(n, v) {
|
||||||
|
viewer.world.getItemAt(n).setFlip(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
function rotate(n, v) {
|
||||||
|
viewer.world.getItemAt(n).setRotation(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
function flipViewport(v) {
|
||||||
|
viewer.viewport.setFlip(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
55
test/demo/memorycheck-with-simple-image.html
Normal file
55
test/demo/memorycheck-with-simple-image.html
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>OpenSeadragon Memory Check With Simple Image Demo</title>
|
||||||
|
<script type="text/javascript" src='../../build/openseadragon/openseadragon.js'></script>
|
||||||
|
<style type="text/css">
|
||||||
|
|
||||||
|
.openseadragon1 {
|
||||||
|
width: 800px;
|
||||||
|
height: 600px;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div>
|
||||||
|
Simple demo page to monitor OpenSeadragon Memory Usage.
|
||||||
|
</div>
|
||||||
|
<!-- To get "Total canvas memory use exceeds the maximum limit" warning and then "null is not an object (evaluating 'smallContext.drawImage')" error,
|
||||||
|
disable _freeupCanvasMemory method in ImageTileSource,
|
||||||
|
then click Create button below 12 times on "iPad Air (3rd generation) -- 13.3" Simulator on Mac with Web Inspector by Safari. -->
|
||||||
|
<button onclick="createViewer()">Create</button>
|
||||||
|
<button onclick="destroyViewer()">Destroy</button>
|
||||||
|
|
||||||
|
<div id="contentDiv" class="openseadragon1"></div>
|
||||||
|
<script type="text/javascript">
|
||||||
|
|
||||||
|
var _viewer;
|
||||||
|
|
||||||
|
function createViewer() {
|
||||||
|
if ( _viewer ) {
|
||||||
|
destroyViewer();
|
||||||
|
}
|
||||||
|
|
||||||
|
_viewer = OpenSeadragon({
|
||||||
|
element: document.getElementById("contentDiv"),
|
||||||
|
showNavigationControl: false,
|
||||||
|
prefixUrl: "../../build/openseadragon/images/",
|
||||||
|
tileSources: {
|
||||||
|
type: "image",
|
||||||
|
url: "../data/CCyan.png"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function destroyViewer() {
|
||||||
|
if ( _viewer ) {
|
||||||
|
_viewer.destroy();
|
||||||
|
}
|
||||||
|
_viewer = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -6,20 +6,22 @@
|
|||||||
|
|
||||||
$.MouseTracker.subscribeEvents = [ "click", "dblclick", "keypress", "focus", "blur", $.MouseTracker.wheelEventName ];
|
$.MouseTracker.subscribeEvents = [ "click", "dblclick", "keypress", "focus", "blur", $.MouseTracker.wheelEventName ];
|
||||||
|
|
||||||
if( $.MouseTracker.wheelEventName == "DOMMouseScroll" ) {
|
if( $.MouseTracker.wheelEventName === "DOMMouseScroll" ) {
|
||||||
// Older Firefox
|
// Older Firefox
|
||||||
$.MouseTracker.subscribeEvents.push( "MozMousePixelScroll" );
|
$.MouseTracker.subscribeEvents.push( "MozMousePixelScroll" );
|
||||||
}
|
}
|
||||||
|
|
||||||
$.MouseTracker.havePointerEvents = false;
|
$.MouseTracker.havePointerEvents = false;
|
||||||
if ( $.Browser.vendor === $.BROWSERS.IE && $.Browser.version < 9 ) {
|
$.MouseTracker.subscribeEvents.push( "mouseenter", "mouseleave", "mouseover", "mouseout", "mousedown", "mouseup", "mousemove" );
|
||||||
$.MouseTracker.subscribeEvents.push( "mouseenter", "mouseleave" );
|
$.MouseTracker.mousePointerId = "legacy-mouse";
|
||||||
$.MouseTracker.haveMouseEnter = true;
|
// Legacy mouse events capture support (IE/Firefox only?)
|
||||||
} else {
|
$.MouseTracker.havePointerCapture = (function () {
|
||||||
$.MouseTracker.subscribeEvents.push( "mouseover", "mouseout" );
|
var divElement = document.createElement( 'div' );
|
||||||
$.MouseTracker.haveMouseEnter = false;
|
return $.isFunction( divElement.setCapture ) && $.isFunction( divElement.releaseCapture );
|
||||||
|
}());
|
||||||
|
if ( $.MouseTracker.havePointerCapture ) {
|
||||||
|
$.MouseTracker.subscribeEvents.push( "losecapture" );
|
||||||
}
|
}
|
||||||
$.MouseTracker.subscribeEvents.push( "mousedown", "mouseup", "mousemove" );
|
|
||||||
if ( 'ontouchstart' in window ) {
|
if ( 'ontouchstart' in window ) {
|
||||||
// iOS, Android, and other W3c Touch Event implementations
|
// iOS, Android, and other W3c Touch Event implementations
|
||||||
// (see http://www.w3.org/TR/touch-events/)
|
// (see http://www.w3.org/TR/touch-events/)
|
||||||
@ -32,8 +34,5 @@
|
|||||||
// Subscribe to these to prevent default gesture handling
|
// Subscribe to these to prevent default gesture handling
|
||||||
$.MouseTracker.subscribeEvents.push( "gesturestart", "gesturechange" );
|
$.MouseTracker.subscribeEvents.push( "gesturestart", "gesturechange" );
|
||||||
}
|
}
|
||||||
$.MouseTracker.mousePointerId = "legacy-mouse";
|
|
||||||
$.MouseTracker.maxTouchPoints = 10;
|
|
||||||
|
|
||||||
|
|
||||||
}(OpenSeadragon));
|
}(OpenSeadragon));
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
$canvas
|
$canvas
|
||||||
.simulate( OpenSeadragon.MouseTracker.haveMouseEnter ? 'mouseenter' : 'mouseover', event )
|
.simulate( 'mouseenter', event )
|
||||||
.simulate( 'mousedown', event );
|
.simulate( 'mousedown', event );
|
||||||
for ( var i = 0; i < args.dragCount; i++ ) {
|
for ( var i = 0; i < args.dragCount; i++ ) {
|
||||||
event.clientX += args.dragDx;
|
event.clientX += args.dragDx;
|
||||||
@ -47,7 +47,7 @@
|
|||||||
}
|
}
|
||||||
$canvas
|
$canvas
|
||||||
.simulate( 'mouseup', event )
|
.simulate( 'mouseup', event )
|
||||||
.simulate( OpenSeadragon.MouseTracker.haveMouseEnter ? 'mouseleave' : 'mouseout', event );
|
.simulate( 'mouseleave', event );
|
||||||
},
|
},
|
||||||
|
|
||||||
// ----------
|
// ----------
|
||||||
|
12
test/modules/controls.js
vendored
12
test/modules/controls.js
vendored
@ -53,9 +53,9 @@
|
|||||||
assert.ok(viewer.showZoomControl, 'showZoomControl should be on');
|
assert.ok(viewer.showZoomControl, 'showZoomControl should be on');
|
||||||
assert.ok(!!viewer.zoomInButton, "zoomIn button should not be null");
|
assert.ok(!!viewer.zoomInButton, "zoomIn button should not be null");
|
||||||
assert.ok(!!viewer.zoomOutButton, "zoomOut button should not be null");
|
assert.ok(!!viewer.zoomOutButton, "zoomOut button should not be null");
|
||||||
assert.notEqual(viewer.buttons.buttons.indexOf(viewer.zoomInButton), -1,
|
assert.notEqual(viewer.buttonGroup.buttons.indexOf(viewer.zoomInButton), -1,
|
||||||
"The zoomIn button should be present");
|
"The zoomIn button should be present");
|
||||||
assert.notEqual(viewer.buttons.buttons.indexOf(viewer.zoomOutButton), -1,
|
assert.notEqual(viewer.buttonGroup.buttons.indexOf(viewer.zoomOutButton), -1,
|
||||||
"The zoomOut button should be present");
|
"The zoomOut button should be present");
|
||||||
|
|
||||||
var oldZoom = viewer.viewport.getZoom();
|
var oldZoom = viewer.viewport.getZoom();
|
||||||
@ -108,7 +108,7 @@
|
|||||||
viewer.removeHandler('open', openHandler);
|
viewer.removeHandler('open', openHandler);
|
||||||
assert.ok(viewer.showHomeControl, 'showHomeControl should be on');
|
assert.ok(viewer.showHomeControl, 'showHomeControl should be on');
|
||||||
assert.ok(!!viewer.homeButton, "Home button should not be null");
|
assert.ok(!!viewer.homeButton, "Home button should not be null");
|
||||||
assert.notEqual(viewer.buttons.buttons.indexOf(viewer.homeButton), -1,
|
assert.notEqual(viewer.buttonGroup.buttons.indexOf(viewer.homeButton), -1,
|
||||||
"The home button should be present");
|
"The home button should be present");
|
||||||
|
|
||||||
viewer.viewport.zoomBy(1.1);
|
viewer.viewport.zoomBy(1.1);
|
||||||
@ -167,7 +167,7 @@
|
|||||||
viewer.removeHandler('open', openHandler);
|
viewer.removeHandler('open', openHandler);
|
||||||
assert.ok(viewer.showHomeControl, 'showFullPageControl should be on');
|
assert.ok(viewer.showHomeControl, 'showFullPageControl should be on');
|
||||||
assert.ok(!!viewer.fullPageButton, "FullPage button should not be null");
|
assert.ok(!!viewer.fullPageButton, "FullPage button should not be null");
|
||||||
assert.notEqual(viewer.buttons.buttons.indexOf(viewer.fullPageButton), -1,
|
assert.notEqual(viewer.buttonGroup.buttons.indexOf(viewer.fullPageButton), -1,
|
||||||
"The full page button should be present");
|
"The full page button should be present");
|
||||||
|
|
||||||
assert.ok(!viewer.isFullPage(), "OSD should not be in full page.");
|
assert.ok(!viewer.isFullPage(), "OSD should not be in full page.");
|
||||||
@ -223,9 +223,9 @@
|
|||||||
assert.ok(viewer.drawer, 'Drawer exists');
|
assert.ok(viewer.drawer, 'Drawer exists');
|
||||||
assert.ok(viewer.drawer.canRotate(), 'drawer.canRotate needs to be true');
|
assert.ok(viewer.drawer.canRotate(), 'drawer.canRotate needs to be true');
|
||||||
assert.ok(viewer.showRotationControl, 'showRotationControl should be true');
|
assert.ok(viewer.showRotationControl, 'showRotationControl should be true');
|
||||||
assert.notEqual(viewer.buttons.buttons.indexOf(viewer.rotateLeftButton), -1,
|
assert.notEqual(viewer.buttonGroup.buttons.indexOf(viewer.rotateLeftButton), -1,
|
||||||
"rotateLeft should be found");
|
"rotateLeft should be found");
|
||||||
assert.notEqual(viewer.buttons.buttons.indexOf(viewer.rotateRightButton), -1,
|
assert.notEqual(viewer.buttonGroup.buttons.indexOf(viewer.rotateRightButton), -1,
|
||||||
"rotateRight should be found");
|
"rotateRight should be found");
|
||||||
|
|
||||||
// Now simulate the left/right button clicks.
|
// Now simulate the left/right button clicks.
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
offset = $canvas.offset(),
|
offset = $canvas.offset(),
|
||||||
tracker = viewer.innerTracker,
|
tracker = viewer.innerTracker,
|
||||||
origEnterHandler,
|
origEnterHandler,
|
||||||
origExitHandler,
|
origLeaveHandler,
|
||||||
origPressHandler,
|
origPressHandler,
|
||||||
origReleaseHandler,
|
origReleaseHandler,
|
||||||
origNonPrimaryPressHandler,
|
origNonPrimaryPressHandler,
|
||||||
@ -43,7 +43,7 @@
|
|||||||
origDragHandler,
|
origDragHandler,
|
||||||
origDragEndHandler,
|
origDragEndHandler,
|
||||||
enterCount,
|
enterCount,
|
||||||
exitCount,
|
leaveCount,
|
||||||
pressCount,
|
pressCount,
|
||||||
releaseCount,
|
releaseCount,
|
||||||
rightPressCount,
|
rightPressCount,
|
||||||
@ -71,11 +71,11 @@
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
origExitHandler = tracker.exitHandler;
|
origLeaveHandler = tracker.leaveHandler;
|
||||||
tracker.exitHandler = function ( event ) {
|
tracker.leaveHandler = function ( event ) {
|
||||||
exitCount++;
|
leaveCount++;
|
||||||
if (origExitHandler) {
|
if (origLeaveHandler) {
|
||||||
return origExitHandler( event );
|
return origLeaveHandler( event );
|
||||||
} else {
|
} else {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -182,7 +182,7 @@
|
|||||||
|
|
||||||
var unhookViewerHandlers = function () {
|
var unhookViewerHandlers = function () {
|
||||||
tracker.enterHandler = origEnterHandler;
|
tracker.enterHandler = origEnterHandler;
|
||||||
tracker.exitHandler = origExitHandler;
|
tracker.leaveHandler = origLeaveHandler;
|
||||||
tracker.pressHandler = origPressHandler;
|
tracker.pressHandler = origPressHandler;
|
||||||
tracker.releaseHandler = origReleaseHandler;
|
tracker.releaseHandler = origReleaseHandler;
|
||||||
tracker.moveHandler = origMoveHandler;
|
tracker.moveHandler = origMoveHandler;
|
||||||
@ -195,21 +195,21 @@
|
|||||||
var simulateEnter = function (x, y) {
|
var simulateEnter = function (x, y) {
|
||||||
simEvent.clientX = offset.left + x;
|
simEvent.clientX = offset.left + x;
|
||||||
simEvent.clientY = offset.top + y;
|
simEvent.clientY = offset.top + y;
|
||||||
$canvas.simulate( OpenSeadragon.MouseTracker.haveMouseEnter ? 'mouseenter' : 'mouseover', simEvent );
|
$canvas.simulate( 'mouseenter', simEvent );
|
||||||
};
|
};
|
||||||
|
|
||||||
var simulateLeave = function (x, y) {
|
var simulateLeave = function (x, y) {
|
||||||
simEvent.clientX = offset.left + x;
|
simEvent.clientX = offset.left + x;
|
||||||
simEvent.clientY = offset.top + y;
|
simEvent.clientY = offset.top + y;
|
||||||
simEvent.relatedTarget = document.body;
|
simEvent.relatedTarget = document.body;
|
||||||
$canvas.simulate( OpenSeadragon.MouseTracker.haveMouseEnter ? 'mouseleave' : 'mouseout', simEvent );
|
$canvas.simulate( 'mouseleave', simEvent );
|
||||||
};
|
};
|
||||||
|
|
||||||
//var simulateLeaveFrame = function (x, y) {
|
//var simulateLeaveFrame = function (x, y) {
|
||||||
// simEvent.clientX = offset.left + x;
|
// simEvent.clientX = offset.left + x;
|
||||||
// simEvent.clientY = offset.top + y;
|
// simEvent.clientY = offset.top + y;
|
||||||
// simEvent.relatedTarget = document.getElementsByTagName("html")[0];
|
// simEvent.relatedTarget = document.getElementsByTagName("html")[0];
|
||||||
// $canvas.simulate( OpenSeadragon.MouseTracker.haveMouseEnter ? 'mouseleave' : 'mouseout', simEvent );
|
// $canvas.simulate( 'mouseleave', simEvent );
|
||||||
//};
|
//};
|
||||||
|
|
||||||
var simulateDown = function (x, y) {
|
var simulateDown = function (x, y) {
|
||||||
@ -256,7 +256,7 @@
|
|||||||
clientY: offset.top
|
clientY: offset.top
|
||||||
};
|
};
|
||||||
enterCount = 0;
|
enterCount = 0;
|
||||||
exitCount = 0;
|
leaveCount = 0;
|
||||||
pressCount = 0;
|
pressCount = 0;
|
||||||
releaseCount = 0;
|
releaseCount = 0;
|
||||||
rightPressCount = 0;
|
rightPressCount = 0;
|
||||||
@ -280,8 +280,8 @@
|
|||||||
if ('enterCount' in expected) {
|
if ('enterCount' in expected) {
|
||||||
assert.equal( enterCount, expected.enterCount, expected.description + 'enterHandler event count matches expected (' + expected.enterCount + ')' );
|
assert.equal( enterCount, expected.enterCount, expected.description + 'enterHandler event count matches expected (' + expected.enterCount + ')' );
|
||||||
}
|
}
|
||||||
if ('exitCount' in expected) {
|
if ('leaveCount' in expected) {
|
||||||
assert.equal( exitCount, expected.exitCount, expected.description + 'exitHandler event count matches expected (' + expected.exitCount + ')' );
|
assert.equal( leaveCount, expected.leaveCount, expected.description + 'leaveHandler event count matches expected (' + expected.leaveCount + ')' );
|
||||||
}
|
}
|
||||||
if ('pressCount' in expected) {
|
if ('pressCount' in expected) {
|
||||||
assert.equal( pressCount, expected.pressCount, expected.description + 'pressHandler event count matches expected (' + expected.pressCount + ')' );
|
assert.equal( pressCount, expected.pressCount, expected.description + 'pressHandler event count matches expected (' + expected.pressCount + ')' );
|
||||||
@ -355,7 +355,7 @@
|
|||||||
assessGestureExpectations({
|
assessGestureExpectations({
|
||||||
description: 'enter-move-release (release in tracked element, press in unknown element): ',
|
description: 'enter-move-release (release in tracked element, press in unknown element): ',
|
||||||
enterCount: 1,
|
enterCount: 1,
|
||||||
exitCount: 0,
|
leaveCount: 0,
|
||||||
pressCount: 0,
|
pressCount: 0,
|
||||||
releaseCount: 1,
|
releaseCount: 1,
|
||||||
rightPressCount: 0,
|
rightPressCount: 0,
|
||||||
@ -375,16 +375,16 @@
|
|||||||
});
|
});
|
||||||
simulateLeave(-1, -1); // flush tracked pointer
|
simulateLeave(-1, -1); // flush tracked pointer
|
||||||
|
|
||||||
// enter-move-exit (fly-over)
|
// enter-move-leave (fly-over)
|
||||||
resetForAssessment();
|
resetForAssessment();
|
||||||
simulateEnter(0, 0);
|
simulateEnter(0, 0);
|
||||||
simulateMove(1, 1, 10);
|
simulateMove(1, 1, 10);
|
||||||
simulateMove(-1, -1, 10);
|
simulateMove(-1, -1, 10);
|
||||||
simulateLeave(-1, -1);
|
simulateLeave(-1, -1);
|
||||||
assessGestureExpectations({
|
assessGestureExpectations({
|
||||||
description: 'enter-move-exit (fly-over): ',
|
description: 'enter-move-leave (fly-over): ',
|
||||||
enterCount: 1,
|
enterCount: 1,
|
||||||
exitCount: 1,
|
leaveCount: 1,
|
||||||
pressCount: 0,
|
pressCount: 0,
|
||||||
releaseCount: 0,
|
releaseCount: 0,
|
||||||
rightPressCount: 0,
|
rightPressCount: 0,
|
||||||
@ -403,34 +403,7 @@
|
|||||||
//quickClick: false
|
//quickClick: false
|
||||||
});
|
});
|
||||||
|
|
||||||
// move-exit (fly-over, no enter event)
|
// enter-press-release-press-release-leave (primary/left double click)
|
||||||
resetForAssessment();
|
|
||||||
simulateMove(1, 1, 10);
|
|
||||||
simulateMove(-1, -1, 10);
|
|
||||||
simulateLeave(-1, -1);
|
|
||||||
assessGestureExpectations({
|
|
||||||
description: 'move-exit (fly-over, no enter event): ',
|
|
||||||
enterCount: 0,
|
|
||||||
exitCount: 1,
|
|
||||||
pressCount: 0,
|
|
||||||
releaseCount: 0,
|
|
||||||
rightPressCount: 0,
|
|
||||||
rightReleaseCount: 0,
|
|
||||||
middlePressCount: 0,
|
|
||||||
middleReleaseCount: 0,
|
|
||||||
moveCount: 20,
|
|
||||||
clickCount: 0,
|
|
||||||
dblClickCount: 0,
|
|
||||||
dragCount: 0,
|
|
||||||
dragEndCount: 0,
|
|
||||||
//insideElementPressed: false,
|
|
||||||
//insideElementReleased: false,
|
|
||||||
contacts: 0,
|
|
||||||
trackedPointers: 0
|
|
||||||
//quickClick: false
|
|
||||||
});
|
|
||||||
|
|
||||||
// enter-press-release-press-release-exit (primary/left double click)
|
|
||||||
resetForAssessment();
|
resetForAssessment();
|
||||||
simulateEnter(0, 0);
|
simulateEnter(0, 0);
|
||||||
simulateDown(0, 0);
|
simulateDown(0, 0);
|
||||||
@ -439,9 +412,9 @@
|
|||||||
simulateUp(0, 0);
|
simulateUp(0, 0);
|
||||||
simulateLeave(-1, -1);
|
simulateLeave(-1, -1);
|
||||||
assessGestureExpectations({
|
assessGestureExpectations({
|
||||||
description: 'enter-press-release-press-release-exit (primary/left double click): ',
|
description: 'enter-press-release-press-release-leave (primary/left double click): ',
|
||||||
enterCount: 1,
|
enterCount: 1,
|
||||||
exitCount: 1,
|
leaveCount: 1,
|
||||||
pressCount: 2,
|
pressCount: 2,
|
||||||
releaseCount: 2,
|
releaseCount: 2,
|
||||||
rightPressCount: 0,
|
rightPressCount: 0,
|
||||||
@ -452,7 +425,7 @@
|
|||||||
clickCount: 2,
|
clickCount: 2,
|
||||||
dblClickCount: 1,
|
dblClickCount: 1,
|
||||||
dragCount: 0,
|
dragCount: 0,
|
||||||
dragEndCount: 0,
|
dragEndCount: 2, // v2.5.0+ drag-end event now fired even if pointer didn't move (#1459)
|
||||||
insideElementPressed: true,
|
insideElementPressed: true,
|
||||||
insideElementReleased: true,
|
insideElementReleased: true,
|
||||||
contacts: 0,
|
contacts: 0,
|
||||||
@ -460,16 +433,16 @@
|
|||||||
//quickClick: true
|
//quickClick: true
|
||||||
});
|
});
|
||||||
|
|
||||||
// enter-press-release-exit (primary/left click)
|
// enter-press-release-leave (primary/left click)
|
||||||
resetForAssessment();
|
resetForAssessment();
|
||||||
simulateEnter(0, 0);
|
simulateEnter(0, 0);
|
||||||
simulateDown(0, 0);
|
simulateDown(0, 0);
|
||||||
simulateUp(0, 0);
|
simulateUp(0, 0);
|
||||||
simulateLeave(-1, -1);
|
simulateLeave(-1, -1);
|
||||||
assessGestureExpectations({
|
assessGestureExpectations({
|
||||||
description: 'enter-press-release-exit (primary/left click): ',
|
description: 'enter-press-release-leave (primary/left click): ',
|
||||||
enterCount: 1,
|
enterCount: 1,
|
||||||
exitCount: 1,
|
leaveCount: 1,
|
||||||
pressCount: 1,
|
pressCount: 1,
|
||||||
releaseCount: 1,
|
releaseCount: 1,
|
||||||
rightPressCount: 0,
|
rightPressCount: 0,
|
||||||
@ -480,7 +453,7 @@
|
|||||||
clickCount: 1,
|
clickCount: 1,
|
||||||
dblClickCount: 0,
|
dblClickCount: 0,
|
||||||
dragCount: 0,
|
dragCount: 0,
|
||||||
dragEndCount: 0,
|
dragEndCount: 1, // v2.5.0+ drag-end event now fired even if pointer didn't move (#1459)
|
||||||
insideElementPressed: true,
|
insideElementPressed: true,
|
||||||
insideElementReleased: true,
|
insideElementReleased: true,
|
||||||
contacts: 0,
|
contacts: 0,
|
||||||
@ -488,16 +461,16 @@
|
|||||||
quickClick: true
|
quickClick: true
|
||||||
});
|
});
|
||||||
|
|
||||||
// enter-nonprimarypress-nonprimaryrelease-exit (secondary/right click)
|
// enter-nonprimarypress-nonprimaryrelease-leave (secondary/right click)
|
||||||
resetForAssessment();
|
resetForAssessment();
|
||||||
simulateEnter(0, 0);
|
simulateEnter(0, 0);
|
||||||
simulateNonPrimaryDown(0, 0, 2);
|
simulateNonPrimaryDown(0, 0, 2);
|
||||||
simulateNonPrimaryUp(0, 0, 2);
|
simulateNonPrimaryUp(0, 0, 2);
|
||||||
simulateLeave(-1, -1);
|
simulateLeave(-1, -1);
|
||||||
assessGestureExpectations({
|
assessGestureExpectations({
|
||||||
description: 'enter-nonprimarypress-nonprimaryrelease-exit (secondary/right click): ',
|
description: 'enter-nonprimarypress-nonprimaryrelease-leave (secondary/right click): ',
|
||||||
enterCount: 1,
|
enterCount: 1,
|
||||||
exitCount: 1,
|
leaveCount: 1,
|
||||||
pressCount: 0,
|
pressCount: 0,
|
||||||
releaseCount: 0,
|
releaseCount: 0,
|
||||||
rightPressCount: 1,
|
rightPressCount: 1,
|
||||||
@ -516,16 +489,16 @@
|
|||||||
//quickClick: true
|
//quickClick: true
|
||||||
});
|
});
|
||||||
|
|
||||||
// enter-nonprimarypress-nonprimaryrelease-exit (aux/middle click)
|
// enter-nonprimarypress-nonprimaryrelease-leave (aux/middle click)
|
||||||
resetForAssessment();
|
resetForAssessment();
|
||||||
simulateEnter(0, 0);
|
simulateEnter(0, 0);
|
||||||
simulateNonPrimaryDown(0, 0, 1);
|
simulateNonPrimaryDown(0, 0, 1);
|
||||||
simulateNonPrimaryUp(0, 0, 1);
|
simulateNonPrimaryUp(0, 0, 1);
|
||||||
simulateLeave(-1, -1);
|
simulateLeave(-1, -1);
|
||||||
assessGestureExpectations({
|
assessGestureExpectations({
|
||||||
description: 'enter-nonprimarypress-nonprimaryrelease-exit (aux/middle click): ',
|
description: 'enter-nonprimarypress-nonprimaryrelease-leave (aux/middle click): ',
|
||||||
enterCount: 1,
|
enterCount: 1,
|
||||||
exitCount: 1,
|
leaveCount: 1,
|
||||||
pressCount: 0,
|
pressCount: 0,
|
||||||
releaseCount: 0,
|
releaseCount: 0,
|
||||||
rightPressCount: 0,
|
rightPressCount: 0,
|
||||||
@ -544,7 +517,7 @@
|
|||||||
//quickClick: true
|
//quickClick: true
|
||||||
});
|
});
|
||||||
|
|
||||||
// enter-nonprimarypress-move-nonprimaryrelease-move-exit (secondary/right button drag, release in tracked element)
|
// enter-nonprimarypress-move-nonprimaryrelease-move-leave (secondary/right button drag, release in tracked element)
|
||||||
resetForAssessment();
|
resetForAssessment();
|
||||||
simulateEnter(0, 0);
|
simulateEnter(0, 0);
|
||||||
simulateNonPrimaryDown(0, 0, 2);
|
simulateNonPrimaryDown(0, 0, 2);
|
||||||
@ -553,9 +526,9 @@
|
|||||||
simulateMove(-1, -1, 100);
|
simulateMove(-1, -1, 100);
|
||||||
simulateLeave(-1, -1);
|
simulateLeave(-1, -1);
|
||||||
assessGestureExpectations({
|
assessGestureExpectations({
|
||||||
description: 'enter-nonprimarypress-move-nonprimaryrelease-move-exit (secondary/right button drag, release in tracked element): ',
|
description: 'enter-nonprimarypress-move-nonprimaryrelease-move-leave (secondary/right button drag, release in tracked element): ',
|
||||||
enterCount: 1,
|
enterCount: 1,
|
||||||
exitCount: 1,
|
leaveCount: 1,
|
||||||
pressCount: 0,
|
pressCount: 0,
|
||||||
releaseCount: 0,
|
releaseCount: 0,
|
||||||
rightPressCount: 1,
|
rightPressCount: 1,
|
||||||
@ -574,7 +547,7 @@
|
|||||||
//quickClick: false
|
//quickClick: false
|
||||||
});
|
});
|
||||||
|
|
||||||
// enter-press-move-release-move-exit (drag, release in tracked element)
|
// enter-press-move-release-move-leave (drag, release in tracked element)
|
||||||
resetForAssessment();
|
resetForAssessment();
|
||||||
simulateEnter(0, 0);
|
simulateEnter(0, 0);
|
||||||
simulateDown(0, 0);
|
simulateDown(0, 0);
|
||||||
@ -583,9 +556,9 @@
|
|||||||
simulateMove(-1, -1, 100);
|
simulateMove(-1, -1, 100);
|
||||||
simulateLeave(-1, -1);
|
simulateLeave(-1, -1);
|
||||||
assessGestureExpectations({
|
assessGestureExpectations({
|
||||||
description: 'enter-press-move-release-move-exit (drag, release in tracked element): ',
|
description: 'enter-press-move-release-move-leave (drag, release in tracked element): ',
|
||||||
enterCount: 1,
|
enterCount: 1,
|
||||||
exitCount: 1,
|
leaveCount: 1,
|
||||||
pressCount: 1,
|
pressCount: 1,
|
||||||
releaseCount: 1,
|
releaseCount: 1,
|
||||||
rightPressCount: 0,
|
rightPressCount: 0,
|
||||||
@ -604,7 +577,7 @@
|
|||||||
quickClick: false
|
quickClick: false
|
||||||
});
|
});
|
||||||
|
|
||||||
// enter-press-move-exit-move-release (drag, release outside tracked element)
|
// enter-press-move-leave-move-release (drag, release outside tracked element)
|
||||||
resetForAssessment();
|
resetForAssessment();
|
||||||
simulateEnter(0, 0);
|
simulateEnter(0, 0);
|
||||||
simulateDown(0, 0);
|
simulateDown(0, 0);
|
||||||
@ -614,9 +587,9 @@
|
|||||||
simulateMove(-1, -1, 5);
|
simulateMove(-1, -1, 5);
|
||||||
simulateUp(-5, -5);
|
simulateUp(-5, -5);
|
||||||
assessGestureExpectations({
|
assessGestureExpectations({
|
||||||
description: 'enter-press-move-exit-move-release (drag, release outside tracked element): ',
|
description: 'enter-press-move-leave-move-release (drag, release outside tracked element): ',
|
||||||
enterCount: 1,
|
enterCount: 1,
|
||||||
exitCount: 1,
|
leaveCount: 1,
|
||||||
pressCount: 1,
|
pressCount: 1,
|
||||||
releaseCount: 1,
|
releaseCount: 1,
|
||||||
rightPressCount: 0,
|
rightPressCount: 0,
|
||||||
@ -635,7 +608,7 @@
|
|||||||
quickClick: false
|
quickClick: false
|
||||||
});
|
});
|
||||||
|
|
||||||
//// enter-press-move-exit-move-release-outside (drag, release outside iframe)
|
//// enter-press-move-leave-move-release-outside (drag, release outside iframe)
|
||||||
//resetForAssessment();
|
//resetForAssessment();
|
||||||
//simulateEnter(0, 0);
|
//simulateEnter(0, 0);
|
||||||
//simulateDown(0, 0);
|
//simulateDown(0, 0);
|
||||||
@ -644,9 +617,9 @@
|
|||||||
//simulateLeaveFrame(-1, -1);
|
//simulateLeaveFrame(-1, -1);
|
||||||
//// you don't actually receive the mouseup if you mouseup outside of the document
|
//// you don't actually receive the mouseup if you mouseup outside of the document
|
||||||
//assessGestureExpectations({
|
//assessGestureExpectations({
|
||||||
// description: 'enter-press-move-exit-move-release-outside (drag, release outside iframe): ',
|
// description: 'enter-press-move-leave-move-release-outside (drag, release outside iframe): ',
|
||||||
// enterCount: 1,
|
// enterCount: 1,
|
||||||
// exitCount: 1,
|
// leaveCount: 1,
|
||||||
// pressCount: 1,
|
// pressCount: 1,
|
||||||
// releaseCount: 1,
|
// releaseCount: 1,
|
||||||
// rightPressCount: 0,
|
// rightPressCount: 0,
|
||||||
@ -679,8 +652,7 @@
|
|||||||
if ('TouchEvent' in window) {
|
if ('TouchEvent' in window) {
|
||||||
QUnit.test( 'MouseTracker: touch events', function (assert) {
|
QUnit.test( 'MouseTracker: touch events', function (assert) {
|
||||||
var done = assert.async();
|
var done = assert.async();
|
||||||
var $canvas = $( viewer.element ).find( '.openseadragon-canvas' ).not( '.navigator .openseadragon-canvas' ),
|
var tracker = viewer.innerTracker,
|
||||||
tracker = viewer.innerTracker,
|
|
||||||
touches;
|
touches;
|
||||||
|
|
||||||
var reset = function () {
|
var reset = function () {
|
||||||
@ -757,7 +729,6 @@
|
|||||||
var done = assert.async();
|
var done = assert.async();
|
||||||
var $canvas = $(viewer.element).find('.openseadragon-canvas')
|
var $canvas = $(viewer.element).find('.openseadragon-canvas')
|
||||||
.not('.navigator .openseadragon-canvas');
|
.not('.navigator .openseadragon-canvas');
|
||||||
var tracker = viewer.innerTracker;
|
|
||||||
var epsilon = 0.0000001;
|
var epsilon = 0.0000001;
|
||||||
|
|
||||||
function simulateClickAndDrag() {
|
function simulateClickAndDrag() {
|
||||||
@ -787,16 +758,14 @@
|
|||||||
viewer.removeHandler('open', onOpen);
|
viewer.removeHandler('open', onOpen);
|
||||||
|
|
||||||
// Hook viewer events to set preventDefaultAction
|
// Hook viewer events to set preventDefaultAction
|
||||||
var origClickHandler = tracker.clickHandler;
|
var onCanvasClick = function (event) {
|
||||||
tracker.clickHandler = function(event) {
|
|
||||||
event.preventDefaultAction = true;
|
event.preventDefaultAction = true;
|
||||||
return origClickHandler(event);
|
|
||||||
};
|
};
|
||||||
var origDragHandler = tracker.dragHandler;
|
var onCanvasDrag = function (event) {
|
||||||
tracker.dragHandler = function(event) {
|
|
||||||
event.preventDefaultAction = true;
|
event.preventDefaultAction = true;
|
||||||
return origDragHandler(event);
|
|
||||||
};
|
};
|
||||||
|
viewer.addHandler("canvas-click", onCanvasClick);
|
||||||
|
viewer.addHandler("canvas-drag", onCanvasDrag);
|
||||||
|
|
||||||
var originalZoom = viewer.viewport.getZoom();
|
var originalZoom = viewer.viewport.getZoom();
|
||||||
var originalBounds = viewer.viewport.getBounds();
|
var originalBounds = viewer.viewport.getBounds();
|
||||||
@ -810,8 +779,8 @@
|
|||||||
Util.assertRectangleEquals(assert, bounds, originalBounds, epsilon,
|
Util.assertRectangleEquals(assert, bounds, originalBounds, epsilon,
|
||||||
'Pan should be prevented');
|
'Pan should be prevented');
|
||||||
|
|
||||||
tracker.clickHandler = origClickHandler;
|
viewer.removeHandler("canvas-click", onCanvasClick);
|
||||||
tracker.dragHandler = origDragHandler;
|
viewer.removeHandler("canvas-drag", onCanvasDrag);
|
||||||
|
|
||||||
simulateClickAndDrag();
|
simulateClickAndDrag();
|
||||||
|
|
||||||
@ -837,31 +806,64 @@
|
|||||||
// ----------
|
// ----------
|
||||||
QUnit.test('Viewer: preventDefaultAction in dblClickHandler', function(assert) {
|
QUnit.test('Viewer: preventDefaultAction in dblClickHandler', function(assert) {
|
||||||
var done = assert.async();
|
var done = assert.async();
|
||||||
var tracker = viewer.innerTracker;
|
|
||||||
var epsilon = 0.0000001;
|
var epsilon = 0.0000001;
|
||||||
|
var $canvas = $( viewer.element ).find( '.openseadragon-canvas' ).not( '.navigator .openseadragon-canvas' ),
|
||||||
|
simEvent = {},
|
||||||
|
offset = $canvas.offset();
|
||||||
|
|
||||||
|
var simulateEnter = function (x, y) {
|
||||||
|
simEvent.clientX = offset.left + x;
|
||||||
|
simEvent.clientY = offset.top + y;
|
||||||
|
$canvas.simulate( 'mouseenter', simEvent );
|
||||||
|
};
|
||||||
|
|
||||||
|
var simulateLeave = function (x, y) {
|
||||||
|
simEvent.clientX = offset.left + x;
|
||||||
|
simEvent.clientY = offset.top + y;
|
||||||
|
simEvent.relatedTarget = document.body;
|
||||||
|
$canvas.simulate( 'mouseleave', simEvent );
|
||||||
|
};
|
||||||
|
|
||||||
|
var simulateDown = function (x, y) {
|
||||||
|
simEvent.button = 0;
|
||||||
|
simEvent.clientX = offset.left + x;
|
||||||
|
simEvent.clientY = offset.top + y;
|
||||||
|
$canvas.simulate( 'mousedown', simEvent );
|
||||||
|
};
|
||||||
|
|
||||||
|
var simulateUp = function (x, y) {
|
||||||
|
simEvent.button = 0;
|
||||||
|
simEvent.clientX = offset.left + x;
|
||||||
|
simEvent.clientY = offset.top + y;
|
||||||
|
$canvas.simulate( 'mouseup', simEvent );
|
||||||
|
};
|
||||||
|
|
||||||
function simulateDblTap() {
|
function simulateDblTap() {
|
||||||
var touches = [];
|
simulateEnter(2, 2);
|
||||||
TouchUtil.reset();
|
simulateDown(2, 2);
|
||||||
|
simulateUp(2, 2);
|
||||||
touches.push(TouchUtil.start([0,0]));
|
simulateDown(2, 2);
|
||||||
TouchUtil.end( touches[0] );
|
simulateUp(2, 2);
|
||||||
touches.push(TouchUtil.start([0,0]));
|
simulateLeave(-1, -1);
|
||||||
TouchUtil.end( touches[1] );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var onOpen = function() {
|
var onOpen = function() {
|
||||||
viewer.removeHandler('open', onOpen);
|
viewer.removeHandler('open', onOpen);
|
||||||
|
|
||||||
|
var origClickSetting = viewer.gestureSettingsMouse.clickToZoom;
|
||||||
|
var origDblClickSetting = viewer.gestureSettingsMouse.dblClickToZoom;
|
||||||
|
|
||||||
|
viewer.gestureSettingsMouse.clickToZoom = false;
|
||||||
|
viewer.gestureSettingsMouse.dblClickToZoom = true;
|
||||||
|
|
||||||
var originalZoom = viewer.viewport.getZoom();
|
var originalZoom = viewer.viewport.getZoom();
|
||||||
|
|
||||||
var origDblClickHandler = tracker.dblClickHandler;
|
var onCanvasDblClick = function (event) {
|
||||||
tracker.dblClickHandler = function(event) {
|
|
||||||
event.preventDefaultAction = true;
|
event.preventDefaultAction = true;
|
||||||
return origDblClickHandler(event);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
TouchUtil.initTracker(tracker);
|
viewer.addHandler('canvas-double-click', onCanvasDblClick);
|
||||||
|
|
||||||
simulateDblTap();
|
simulateDblTap();
|
||||||
|
|
||||||
var zoom = viewer.viewport.getZoom();
|
var zoom = viewer.viewport.getZoom();
|
||||||
@ -869,37 +871,19 @@
|
|||||||
"Zoom on double tap should be prevented");
|
"Zoom on double tap should be prevented");
|
||||||
|
|
||||||
// Reset event handler to original
|
// Reset event handler to original
|
||||||
tracker.dblClickHandler = origDblClickHandler;
|
viewer.removeHandler("canvas-double-click", onCanvasDblClick);
|
||||||
|
|
||||||
simulateDblTap();
|
simulateDblTap();
|
||||||
originalZoom = originalZoom * viewer.zoomPerClick;
|
originalZoom *= viewer.zoomPerClick;
|
||||||
|
|
||||||
zoom = viewer.viewport.getZoom();
|
zoom = viewer.viewport.getZoom();
|
||||||
Util.assessNumericValue(assert, originalZoom, zoom, epsilon,
|
Util.assessNumericValue(assert, originalZoom, zoom, epsilon,
|
||||||
"Zoom on double tap should not be prevented");
|
"Zoom on double tap should not be prevented");
|
||||||
|
|
||||||
|
|
||||||
var dblClickHandler = function(event) {
|
viewer.gestureSettingsMouse.clickToZoom = origClickSetting;
|
||||||
event.preventDefaultAction = true;
|
viewer.gestureSettingsMouse.dblClickToZoom = origDblClickSetting;
|
||||||
};
|
|
||||||
|
|
||||||
viewer.addHandler('canvas-double-click', dblClickHandler);
|
|
||||||
|
|
||||||
zoom = viewer.viewport.getZoom();
|
|
||||||
Util.assessNumericValue(assert, originalZoom, zoom, epsilon,
|
|
||||||
"Zoom on double tap should be prevented");
|
|
||||||
|
|
||||||
// Remove custom event handler
|
|
||||||
viewer.removeHandler('canvas-double-click', dblClickHandler);
|
|
||||||
|
|
||||||
simulateDblTap();
|
|
||||||
originalZoom = originalZoom * viewer.zoomPerClick;
|
|
||||||
|
|
||||||
zoom = viewer.viewport.getZoom();
|
|
||||||
Util.assessNumericValue(assert, originalZoom, zoom, epsilon,
|
|
||||||
"Zoom on double tap should not be prevented");
|
|
||||||
|
|
||||||
TouchUtil.resetTracker(tracker);
|
|
||||||
viewer.close();
|
viewer.close();
|
||||||
done();
|
done();
|
||||||
};
|
};
|
||||||
@ -926,10 +910,9 @@
|
|||||||
eventsHandledViewer = 0,
|
eventsHandledViewer = 0,
|
||||||
originalEventsPassedViewer = 0,
|
originalEventsPassedViewer = 0,
|
||||||
dragEndsExpected = 1,
|
dragEndsExpected = 1,
|
||||||
releasesExpected = 1,
|
releasesExpected = 1;
|
||||||
clicksExpected = 1;
|
|
||||||
|
|
||||||
var onOpen = function ( event ) {
|
var onOpen = function ( ) {
|
||||||
viewer.removeHandler( 'open', onOpen );
|
viewer.removeHandler( 'open', onOpen );
|
||||||
|
|
||||||
viewer.addHandler( 'canvas-drag', onEventSourceDrag );
|
viewer.addHandler( 'canvas-drag', onEventSourceDrag );
|
||||||
@ -953,7 +936,7 @@
|
|||||||
dragEndHandler: onMouseTrackerDragEnd,
|
dragEndHandler: onMouseTrackerDragEnd,
|
||||||
releaseHandler: onMouseTrackerRelease,
|
releaseHandler: onMouseTrackerRelease,
|
||||||
clickHandler: onMouseTrackerClick,
|
clickHandler: onMouseTrackerClick,
|
||||||
exitHandler: onMouseTrackerExit
|
leaveHandler: onMouseTrackerLeave
|
||||||
} );
|
} );
|
||||||
|
|
||||||
var event = {
|
var event = {
|
||||||
@ -1050,7 +1033,7 @@
|
|||||||
checkOriginalEventReceived( event );
|
checkOriginalEventReceived( event );
|
||||||
};
|
};
|
||||||
|
|
||||||
var onMouseTrackerExit = function ( event ) {
|
var onMouseTrackerLeave = function ( event ) {
|
||||||
checkOriginalEventReceived( event );
|
checkOriginalEventReceived( event );
|
||||||
|
|
||||||
mouseTracker.destroy();
|
mouseTracker.destroy();
|
||||||
|
249
test/modules/iiif.js
Normal file
249
test/modules/iiif.js
Normal file
@ -0,0 +1,249 @@
|
|||||||
|
(function() {
|
||||||
|
|
||||||
|
var id = "http://example.com/identifier";
|
||||||
|
|
||||||
|
var configure = function(data) {
|
||||||
|
return OpenSeadragon.IIIFTileSource.prototype.configure.apply(
|
||||||
|
new OpenSeadragon.TileSource(), [ data, 'http://example.com/identifier' ]
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
var getSource = function( data ) {
|
||||||
|
var options = configure( data );
|
||||||
|
return new OpenSeadragon.IIIFTileSource( options );
|
||||||
|
};
|
||||||
|
|
||||||
|
var infoXml10level0 = new DOMParser().parseFromString('<?xml version="1.0" encoding="UTF-8"?>' +
|
||||||
|
'<info xmlns="http://library.stanford.edu/iiif/image-api/ns/">' +
|
||||||
|
'<identifier>http://example.com/identifier</identifier>' +
|
||||||
|
'<width>6000</width>' +
|
||||||
|
'<height>4000</height>' +
|
||||||
|
'<scale_factors>' +
|
||||||
|
'<scale_factor>1</scale_factor>' +
|
||||||
|
'<scale_factor>2</scale_factor>' +
|
||||||
|
'<scale_factor>4</scale_factor>' +
|
||||||
|
'</scale_factors>' +
|
||||||
|
'<profile>http://library.stanford.edu/iiif/image-api/compliance.html#level0</profile>' +
|
||||||
|
'</info>',
|
||||||
|
'text/xml'
|
||||||
|
),
|
||||||
|
infoXml10level1 = new DOMParser().parseFromString('<?xml version="1.0" encoding="UTF-8"?>' +
|
||||||
|
'<info xmlns="http://library.stanford.edu/iiif/image-api/ns/">' +
|
||||||
|
'<identifier>http://example.com/identifier</identifier>' +
|
||||||
|
'<width>6000</width>' +
|
||||||
|
'<height>4000</height>' +
|
||||||
|
'<profile>http://library.stanford.edu/iiif/image-api/compliance.html#level1</profile>' +
|
||||||
|
'</info>',
|
||||||
|
'text/xml'
|
||||||
|
),
|
||||||
|
infoJson10level0 = {
|
||||||
|
"identifier": id,
|
||||||
|
"width": 2000,
|
||||||
|
"height": 1000,
|
||||||
|
"profile" : "http://library.stanford.edu/iiif/image-api/compliance.html#level0"
|
||||||
|
},
|
||||||
|
infoJson10level1 = {
|
||||||
|
"identifier": id,
|
||||||
|
"width": 2000,
|
||||||
|
"height": 1000,
|
||||||
|
"profile" : "http://library.stanford.edu/iiif/image-api/compliance.html#level1"
|
||||||
|
},
|
||||||
|
infoJson11level0 = {
|
||||||
|
"@context": "http://library.stanford.edu/iiif/image-api/1.1/context.json",
|
||||||
|
"@id": id,
|
||||||
|
"width": 2000,
|
||||||
|
"height": 1000,
|
||||||
|
"profile": "http://library.stanford.edu/iiif/image-api/1.1/compliance.html#level0"
|
||||||
|
},
|
||||||
|
infoJson11level1 = {
|
||||||
|
"@context": "http://library.stanford.edu/iiif/image-api/1.1/context.json",
|
||||||
|
"@id": id,
|
||||||
|
"width": 2000,
|
||||||
|
"height": 1000,
|
||||||
|
"profile": "http://library.stanford.edu/iiif/image-api/1.1/compliance.html#level1"
|
||||||
|
},
|
||||||
|
infoJson11level1WithTiles = {
|
||||||
|
"@context": "http://library.stanford.edu/iiif/image-api/1.1/context.json",
|
||||||
|
"@id": id,
|
||||||
|
"width": 2000,
|
||||||
|
"height": 1000,
|
||||||
|
"tile_width": 512,
|
||||||
|
"tile_height": 256,
|
||||||
|
"profile": "http://library.stanford.edu/iiif/image-api/1.1/compliance.html#level1"
|
||||||
|
},
|
||||||
|
infoJson2level0 = {
|
||||||
|
"@context": "http://iiif.io/api/image/2/context.json",
|
||||||
|
"@id": id,
|
||||||
|
"width": 2000,
|
||||||
|
"height": 1000,
|
||||||
|
"sizes": [
|
||||||
|
{ width: 2000, height: 1000 },
|
||||||
|
{ width: 1000, height: 500 }
|
||||||
|
],
|
||||||
|
"profile": ["http://iiif.io/api/image/2/level0.json"]
|
||||||
|
},
|
||||||
|
infoJson2level0sizeByW = {
|
||||||
|
"@context": "http://iiif.io/api/image/2/context.json",
|
||||||
|
"@id": id,
|
||||||
|
"width": 2000,
|
||||||
|
"height": 1000,
|
||||||
|
"profile": ["http://iiif.io/api/image/2/level0.json", {"supports": "sizeByW"} ]
|
||||||
|
},
|
||||||
|
infoJson2level1 = {
|
||||||
|
"@context": "http://iiif.io/api/image/2/context.json",
|
||||||
|
"@id": id,
|
||||||
|
"width": 2000,
|
||||||
|
"height": 1000,
|
||||||
|
"profile": ["http://iiif.io/api/image/2/level1.json"]
|
||||||
|
},
|
||||||
|
infoJson3level0 = {
|
||||||
|
"@context": "http://iiif.io/api/image/3/context.json",
|
||||||
|
"id": id,
|
||||||
|
"width": 2000,
|
||||||
|
"height": 1000,
|
||||||
|
"sizes": [
|
||||||
|
{ width: 2000, height: 1000 },
|
||||||
|
{ width: 1000, height: 500 }
|
||||||
|
],
|
||||||
|
"profile": "level0"
|
||||||
|
},
|
||||||
|
infoJson3level0ContextExtension = {
|
||||||
|
"@context": [
|
||||||
|
"http://iiif.io/api/image/3/context.json",
|
||||||
|
{
|
||||||
|
"example": "http://example.com/vocab"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"id": id,
|
||||||
|
"width": 2000,
|
||||||
|
"height": 1000,
|
||||||
|
"profile": "level0"
|
||||||
|
},
|
||||||
|
infoJson3level0sizeByW = {
|
||||||
|
"@context": "http://iiif.io/api/image/3/context.json",
|
||||||
|
"id": id,
|
||||||
|
"width": 2000,
|
||||||
|
"height": 1000,
|
||||||
|
"profile": "level0",
|
||||||
|
"extraFeatures": "sizeByW"
|
||||||
|
},
|
||||||
|
infoJson3level0sizeByWh = {
|
||||||
|
"@context": "http://iiif.io/api/image/3/context.json",
|
||||||
|
"id": id,
|
||||||
|
"width": 2000,
|
||||||
|
"height": 1000,
|
||||||
|
"profile": "level0",
|
||||||
|
"extraFeatures": "sizeByWh"
|
||||||
|
},
|
||||||
|
infoJson3level1 = {
|
||||||
|
"@context": "http://iiif.io/api/image/3/context.json",
|
||||||
|
"id": id,
|
||||||
|
"width": 2000,
|
||||||
|
"height": 1000,
|
||||||
|
"profile": "level1"
|
||||||
|
};
|
||||||
|
|
||||||
|
QUnit.test('IIIFTileSource.configure determins correct version', function(assert) {
|
||||||
|
var options1_0xml = configure(infoXml10level0);
|
||||||
|
assert.ok(options1_0xml.version);
|
||||||
|
assert.equal(options1_0xml.version, 1, 'Version is 1 for version 1.0 info.xml');
|
||||||
|
|
||||||
|
var options1_0 = configure(infoJson10level0);
|
||||||
|
assert.ok(options1_0.version);
|
||||||
|
assert.equal(options1_0.version, 1, 'Version is 1 for version 1.0 info.json');
|
||||||
|
|
||||||
|
var options1_1 = configure(infoJson11level0);
|
||||||
|
assert.ok(options1_1.version);
|
||||||
|
assert.equal(options1_1.version, 1, 'Version is 1 for version 1.1 info.json');
|
||||||
|
|
||||||
|
var options2 = configure(infoJson2level0);
|
||||||
|
assert.ok(options2.version);
|
||||||
|
assert.equal(options2.version, 2, 'Version is 2 for version 2 info.json');
|
||||||
|
|
||||||
|
var options3 = configure(infoJson3level0);
|
||||||
|
assert.ok(options3.version);
|
||||||
|
assert.equal(options3.version, 3, 'Version is 3 for version 3 info.json');
|
||||||
|
|
||||||
|
var options3withContextExtension = configure(infoJson3level0ContextExtension);
|
||||||
|
assert.ok(options3withContextExtension.version);
|
||||||
|
assert.equal(options3withContextExtension.version, 3, 'Version is 3 for version 3 info.json');
|
||||||
|
});
|
||||||
|
|
||||||
|
QUnit.test('IIIFTileSource private function canBeTiled works as expected', function(assert) {
|
||||||
|
var canBeTiled = function( data ) {
|
||||||
|
var source = getSource( data );
|
||||||
|
return source.__testonly__.canBeTiled( source );
|
||||||
|
};
|
||||||
|
|
||||||
|
assert.notOk(canBeTiled(infoXml10level0));
|
||||||
|
assert.ok(canBeTiled(infoXml10level1));
|
||||||
|
assert.notOk(canBeTiled(infoJson10level0));
|
||||||
|
assert.ok(canBeTiled(infoJson10level1));
|
||||||
|
assert.notOk(canBeTiled(infoJson11level0));
|
||||||
|
assert.ok(canBeTiled(infoJson11level1));
|
||||||
|
assert.notOk(canBeTiled(infoJson2level0));
|
||||||
|
assert.ok(canBeTiled(infoJson2level0sizeByW));
|
||||||
|
assert.ok(canBeTiled(infoJson2level1));
|
||||||
|
assert.notOk(canBeTiled(infoJson3level0));
|
||||||
|
assert.notOk(canBeTiled(infoJson3level0sizeByW));
|
||||||
|
assert.ok(canBeTiled(infoJson3level0sizeByWh));
|
||||||
|
assert.ok(canBeTiled(infoJson3level1));
|
||||||
|
});
|
||||||
|
|
||||||
|
QUnit.test('IIIFTileSource private function constructLevels creates correct URLs for legacy pyramid', function( assert ) {
|
||||||
|
var constructLevels = function( data ) {
|
||||||
|
var source = getSource( data );
|
||||||
|
return source.__testonly__.constructLevels( source );
|
||||||
|
};
|
||||||
|
var levelsVersion2 = constructLevels(infoJson2level0);
|
||||||
|
assert.ok(Array.isArray(levelsVersion2));
|
||||||
|
assert.equal(levelsVersion2.length, 2, 'Constructed levels contain 2 entries');
|
||||||
|
assert.equal(levelsVersion2[0].url, 'http://example.com/identifier/full/1000,/0/default.jpg');
|
||||||
|
assert.equal(levelsVersion2[1].url, 'http://example.com/identifier/full/2000,/0/default.jpg');
|
||||||
|
// FIXME see below
|
||||||
|
// assert.equal(levelsVersion2[1].url, 'http://example.com/identifier/full/full/0/default.jpg');
|
||||||
|
|
||||||
|
var levelsVersion3 = constructLevels(infoJson3level0);
|
||||||
|
assert.ok(Array.isArray(levelsVersion3));
|
||||||
|
assert.equal(levelsVersion3.length, 2, 'Constructed levels contain 2 entries');
|
||||||
|
assert.equal(levelsVersion3[0].url, 'http://example.com/identifier/full/1000,500/0/default.jpg');
|
||||||
|
assert.equal(levelsVersion3[1].url, 'http://example.com/identifier/full/2000,1000/0/default.jpg');
|
||||||
|
/*
|
||||||
|
* FIXME: following https://iiif.io/api/image/3.0/#47-canonical-uri-syntax and
|
||||||
|
* https://iiif.io/api/image/2.1/#canonical-uri-syntax, I'd expect 'max' to be required to
|
||||||
|
* be served by a level 0 compliant service instead of 'w,h', 'full' instead of 'w,' respectivley.
|
||||||
|
*/
|
||||||
|
//assert.equal(levelsVersion3[1].url, 'http://example.com/identifier/full/max/0/default.jpg');
|
||||||
|
});
|
||||||
|
|
||||||
|
QUnit.test('IIIFTileSource.getTileUrl returns the correct URLs', function( assert ) {
|
||||||
|
var source11Level1 = getSource(infoJson11level1);
|
||||||
|
assert.equal(source11Level1.getTileUrl(0, 0, 0), "http://example.com/identifier/full/8,/0/native.jpg");
|
||||||
|
assert.equal(source11Level1.getTileUrl(7, 0, 0), "http://example.com/identifier/0,0,1024,1000/512,/0/native.jpg");
|
||||||
|
assert.equal(source11Level1.getTileUrl(7, 1, 0), "http://example.com/identifier/1024,0,976,1000/488,/0/native.jpg");
|
||||||
|
assert.equal(source11Level1.getTileUrl(8, 0, 0), "http://example.com/identifier/0,0,512,512/512,/0/native.jpg");
|
||||||
|
|
||||||
|
var source2Level1 = getSource(infoJson2level1);
|
||||||
|
assert.equal(source2Level1.getTileUrl(0, 0, 0), "http://example.com/identifier/full/8,/0/default.jpg");
|
||||||
|
assert.equal(source2Level1.getTileUrl(7, 0, 0), "http://example.com/identifier/0,0,1024,1000/512,/0/default.jpg");
|
||||||
|
assert.equal(source2Level1.getTileUrl(7, 1, 0), "http://example.com/identifier/1024,0,976,1000/488,/0/default.jpg");
|
||||||
|
assert.equal(source2Level1.getTileUrl(8, 0, 0), "http://example.com/identifier/0,0,512,512/512,/0/default.jpg");
|
||||||
|
assert.equal(source2Level1.getTileUrl(8, 3, 0), "http://example.com/identifier/1536,0,464,512/464,/0/default.jpg");
|
||||||
|
assert.equal(source2Level1.getTileUrl(8, 0, 1), "http://example.com/identifier/0,512,512,488/512,/0/default.jpg");
|
||||||
|
assert.equal(source2Level1.getTileUrl(8, 3, 1), "http://example.com/identifier/1536,512,464,488/464,/0/default.jpg");
|
||||||
|
|
||||||
|
var source2Level0 = getSource(infoJson2level0);
|
||||||
|
assert.equal(source2Level0.getTileUrl(0, 0, 0), "http://example.com/identifier/full/1000,/0/default.jpg");
|
||||||
|
assert.equal(source2Level0.getTileUrl(1, 0, 0), "http://example.com/identifier/full/2000,/0/default.jpg");
|
||||||
|
|
||||||
|
var source3Level1 = getSource(infoJson3level1);
|
||||||
|
assert.equal(source3Level1.getTileUrl(0, 0, 0), "http://example.com/identifier/full/8,4/0/default.jpg");
|
||||||
|
assert.equal(source3Level1.getTileUrl(7, 0, 0), "http://example.com/identifier/0,0,1024,1000/512,500/0/default.jpg");
|
||||||
|
assert.equal(source3Level1.getTileUrl(7, 1, 0), "http://example.com/identifier/1024,0,976,1000/488,500/0/default.jpg");
|
||||||
|
assert.equal(source3Level1.getTileUrl(8, 0, 0), "http://example.com/identifier/0,0,512,512/512,512/0/default.jpg");
|
||||||
|
assert.equal(source3Level1.getTileUrl(8, 3, 0), "http://example.com/identifier/1536,0,464,512/464,512/0/default.jpg");
|
||||||
|
assert.equal(source3Level1.getTileUrl(8, 0, 1), "http://example.com/identifier/0,512,512,488/512,488/0/default.jpg");
|
||||||
|
assert.equal(source3Level1.getTileUrl(8, 3, 1), "http://example.com/identifier/1536,512,464,488/464,488/0/default.jpg");
|
||||||
|
});
|
||||||
|
|
||||||
|
})();
|
@ -216,19 +216,34 @@
|
|||||||
clientY: offset.top + locationY
|
clientY: offset.top + locationY
|
||||||
};
|
};
|
||||||
$canvas
|
$canvas
|
||||||
.simulate(OpenSeadragon.MouseTracker.haveMouseEnter ? 'mouseenter' : 'mouseover', event)
|
.simulate('mouseenter', event)
|
||||||
.simulate('mousedown', event)
|
.simulate('mousedown', event)
|
||||||
.simulate('mouseup', event);
|
.simulate('mouseup', event);
|
||||||
};
|
};
|
||||||
|
|
||||||
var simulateNavigatorDrag = function (viewer, distanceX, distanceY) {
|
var simulateNavigatorDrag = function (viewer, distanceX, distanceY) {
|
||||||
var $canvas = $(viewer.element).find('.displayregion'),
|
var $canvas = $(viewer.element).find('.openseadragon-canvas'),
|
||||||
event = {
|
offset = $canvas.offset(),
|
||||||
dx: Math.floor(distanceX),
|
event = {};
|
||||||
dy: Math.floor(distanceY)
|
|
||||||
};
|
event.clientX = offset.left + 1;
|
||||||
$canvas
|
event.clientY = offset.top + 1;
|
||||||
.simulate('drag', event);
|
$canvas.simulate( 'mouseenter', event );
|
||||||
|
|
||||||
|
event.button = 0;
|
||||||
|
$canvas.simulate( 'mousedown', event );
|
||||||
|
|
||||||
|
event.clientX += distanceX;
|
||||||
|
event.clientY += distanceY;
|
||||||
|
$canvas.simulate( 'mousemove', event );
|
||||||
|
|
||||||
|
event.button = 0;
|
||||||
|
$canvas.simulate( 'mouseup', event );
|
||||||
|
|
||||||
|
event.clientX = offset.left - 1;
|
||||||
|
event.clientY = offset.top - 1;
|
||||||
|
event.relatedTarget = document.body;
|
||||||
|
$canvas.simulate( 'mouseleave', event );
|
||||||
};
|
};
|
||||||
|
|
||||||
var dragNavigatorBackToCenter = function () {
|
var dragNavigatorBackToCenter = function () {
|
||||||
|
@ -41,8 +41,11 @@
|
|||||||
viewer.addHandler('open', function(event) {
|
viewer.addHandler('open', function(event) {
|
||||||
var image = viewer.world.getItemAt(0);
|
var image = viewer.world.getItemAt(0);
|
||||||
var contentSize = image.getContentSize();
|
var contentSize = image.getContentSize();
|
||||||
|
var sizeInWindowCoords = image.getSizeInWindowCoordinates();
|
||||||
assert.equal(contentSize.x, 500, 'contentSize.x');
|
assert.equal(contentSize.x, 500, 'contentSize.x');
|
||||||
assert.equal(contentSize.y, 2000, 'contentSize.y');
|
assert.equal(contentSize.y, 2000, 'contentSize.y');
|
||||||
|
assert.equal(sizeInWindowCoords.x, 125, 'sizeInWindowCoords.x');
|
||||||
|
assert.equal(sizeInWindowCoords.y, 500, 'sizeInWindowCoords.y');
|
||||||
|
|
||||||
checkBounds(assert, image, new OpenSeadragon.Rect(5, 6, 10, 40), 'initial bounds');
|
checkBounds(assert, image, new OpenSeadragon.Rect(5, 6, 10, 40), 'initial bounds');
|
||||||
|
|
||||||
@ -74,7 +77,18 @@
|
|||||||
image.setHeight(4);
|
image.setHeight(4);
|
||||||
checkBounds(assert, image, new OpenSeadragon.Rect(7, 8, 1, 4), 'bounds after width');
|
checkBounds(assert, image, new OpenSeadragon.Rect(7, 8, 1, 4), 'bounds after width');
|
||||||
|
|
||||||
assert.equal(handlerCount, 1, 'correct number of handlers called');
|
viewer.addHandler('zoom', function zoomHandler(event) {
|
||||||
|
var sizeInWindowCoords = image.getSizeInWindowCoordinates();
|
||||||
|
viewer.removeHandler('zoom', zoomHandler);
|
||||||
|
handlerCount++;
|
||||||
|
assert.equal(sizeInWindowCoords.x, 4000, 'sizeInWindowCoords.x after zoom');
|
||||||
|
assert.equal(sizeInWindowCoords.y, 16000, 'sizeInWindowCoords.y after zoom');
|
||||||
|
});
|
||||||
|
|
||||||
|
viewer.viewport.zoomTo(8, null, true);
|
||||||
|
|
||||||
|
assert.equal(handlerCount, 2, 'correct number of handlers called');
|
||||||
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
93
test/modules/viewerretrieval.js
Normal file
93
test/modules/viewerretrieval.js
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
/* global QUnit, $, testLog */
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
var viewer1;
|
||||||
|
var viewer2;
|
||||||
|
|
||||||
|
QUnit.module('ViewerRetrieval', {
|
||||||
|
beforeEach: function () {
|
||||||
|
$('<div id="example1"></div><div id="example2"></div>')
|
||||||
|
.appendTo("#qunit-fixture");
|
||||||
|
|
||||||
|
testLog.reset();
|
||||||
|
|
||||||
|
viewer1 = OpenSeadragon({
|
||||||
|
id: 'example1',
|
||||||
|
prefixUrl: 'build/openseadragon/images/',
|
||||||
|
springStiffness: 100 // Faster animation = faster tests
|
||||||
|
});
|
||||||
|
|
||||||
|
viewer2 = OpenSeadragon({
|
||||||
|
id: 'example2',
|
||||||
|
prefixUrl: 'build/openseadragon/images/',
|
||||||
|
springStiffness: 100
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
afterEach: function () {
|
||||||
|
if (viewer1 && viewer1.destroy) {
|
||||||
|
viewer1.destroy();
|
||||||
|
}
|
||||||
|
if (viewer2 && viewer2.destroy) {
|
||||||
|
viewer2.destroy();
|
||||||
|
}
|
||||||
|
viewer1 = viewer2 = null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
QUnit.test('Get Viewers by Id', function(assert) {
|
||||||
|
var retrievedViewer1 = OpenSeadragon.getViewer('example1');
|
||||||
|
assert.ok(retrievedViewer1, 'Attached viewer retrieved');
|
||||||
|
assert.equal(retrievedViewer1, viewer1, 'Viewers are same instance');
|
||||||
|
|
||||||
|
var retrievedViewer2 = OpenSeadragon.getViewer('example2');
|
||||||
|
assert.ok(retrievedViewer2, 'Attached viewer retrieved');
|
||||||
|
assert.equal(retrievedViewer2, viewer2, 'Viewers are same instance');
|
||||||
|
|
||||||
|
// Internal state
|
||||||
|
assert.equal(OpenSeadragon._viewers.size, 2, 'Correct amount of viewers');
|
||||||
|
});
|
||||||
|
|
||||||
|
QUnit.test('Get Viewers by Element', function(assert) {
|
||||||
|
var retrievedViewer1 = OpenSeadragon.getViewer(
|
||||||
|
document.getElementById('example1'));
|
||||||
|
assert.ok(retrievedViewer1, 'Attached viewer retrieved');
|
||||||
|
assert.equal(retrievedViewer1, viewer1, 'Viewers are same instance');
|
||||||
|
|
||||||
|
var retrievedViewer2 = OpenSeadragon.getViewer(
|
||||||
|
document.getElementById('example2'));
|
||||||
|
assert.ok(retrievedViewer2, 'Attached viewer retrieved');
|
||||||
|
assert.equal(retrievedViewer2, viewer2, 'Viewers are same instance');
|
||||||
|
|
||||||
|
// Internal state
|
||||||
|
assert.equal(OpenSeadragon._viewers.size, 2, 'Correct amount of viewers');
|
||||||
|
});
|
||||||
|
|
||||||
|
QUnit.test('Undefined on Get Non-Existent Viewer by Id', function(assert) {
|
||||||
|
var notFoundViewer = OpenSeadragon.getViewer('no-viewer');
|
||||||
|
assert.equal(notFoundViewer, undefined, "Not found viewer is undefined");
|
||||||
|
});
|
||||||
|
|
||||||
|
QUnit.test('Undefined on Get Non-Existent Viewer by Element', function(assert) {
|
||||||
|
var element = document.createElement('div');
|
||||||
|
element.id = 'no-viewer';
|
||||||
|
document.body.appendChild(element);
|
||||||
|
|
||||||
|
var notFoundViewer = OpenSeadragon.getViewer(element);
|
||||||
|
assert.equal(notFoundViewer, undefined, "Not found viewer is undefined");
|
||||||
|
});
|
||||||
|
|
||||||
|
QUnit.test('Cleanup Viewers Registration', function(assert) {
|
||||||
|
viewer1.destroy();
|
||||||
|
viewer2.destroy();
|
||||||
|
viewer1 = viewer2 = null;
|
||||||
|
|
||||||
|
var retrievedViewer1 = OpenSeadragon.getViewer('example1');
|
||||||
|
var retrievedViewer2 = OpenSeadragon.getViewer('example2');
|
||||||
|
assert.equal(retrievedViewer1, undefined, 'Viewer was destroyed');
|
||||||
|
assert.equal(retrievedViewer2, undefined, 'Viewer was destroyed');
|
||||||
|
|
||||||
|
// Internal state
|
||||||
|
assert.equal(OpenSeadragon._viewers.size, 0, 'No viewers are registered');
|
||||||
|
});
|
||||||
|
})();
|
@ -22,6 +22,7 @@
|
|||||||
<!-- Polyfill must be inserted first because it is testing functions
|
<!-- Polyfill must be inserted first because it is testing functions
|
||||||
reassignments which could be done by other test. -->
|
reassignments which could be done by other test. -->
|
||||||
<script src="/test/modules/polyfills.js"></script>
|
<script src="/test/modules/polyfills.js"></script>
|
||||||
|
<script src="/test/modules/viewerretrieval.js"></script>
|
||||||
<script src="/test/modules/basic.js"></script>
|
<script src="/test/modules/basic.js"></script>
|
||||||
<script src="/test/modules/strings.js"></script>
|
<script src="/test/modules/strings.js"></script>
|
||||||
<script src="/test/modules/formats.js"></script>
|
<script src="/test/modules/formats.js"></script>
|
||||||
@ -44,6 +45,7 @@
|
|||||||
<script src="/test/modules/rectangle.js"></script>
|
<script src="/test/modules/rectangle.js"></script>
|
||||||
<script src="/test/modules/ajax-tiles.js"></script>
|
<script src="/test/modules/ajax-tiles.js"></script>
|
||||||
<script src="/test/modules/imageloader.js"></script>
|
<script src="/test/modules/imageloader.js"></script>
|
||||||
|
<script src="/test/modules/iiif.js"></script>
|
||||||
<!--The navigator tests are the slowest (for now; hopefully they can be sped up)
|
<!--The navigator tests are the slowest (for now; hopefully they can be sped up)
|
||||||
so we put them last. -->
|
so we put them last. -->
|
||||||
<script src="/test/modules/navigator.js"></script>
|
<script src="/test/modules/navigator.js"></script>
|
||||||
|
Loading…
Reference in New Issue
Block a user