mirror of
https://github.com/openseadragon/openseadragon.git
synced 2024-11-25 14:46:10 +03:00
Merge pull request #151 from acdha/overhauled-ajax-error-reporting
Overhauled AJAX error reporting
This commit is contained in:
commit
850aa14802
@ -882,47 +882,49 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Wraps the given element in a nest of divs so that the element can
|
* Wraps the given element in a nest of divs so that the element can
|
||||||
* be easily centered.
|
* be easily centered using CSS tables
|
||||||
* @function
|
* @function
|
||||||
* @name OpenSeadragon.makeCenteredNode
|
* @name OpenSeadragon.makeCenteredNode
|
||||||
* @param {Element|String} element
|
* @param {Element|String} element
|
||||||
* @returns {Element}
|
* @returns {Element} outermost wrapper element
|
||||||
*/
|
*/
|
||||||
makeCenteredNode: function( element ) {
|
makeCenteredNode: function( element ) {
|
||||||
|
// Convert a possible ID to an actual HTMLElement
|
||||||
var div = $.makeNeutralElement( "div" ),
|
|
||||||
html = [],
|
|
||||||
innerDiv,
|
|
||||||
innerDivs;
|
|
||||||
|
|
||||||
element = $.getElement( element );
|
element = $.getElement( element );
|
||||||
|
|
||||||
//TODO: I dont understand the use of # inside the style attributes
|
/*
|
||||||
// below. Invetigate the results of the constructed html in
|
CSS tables require you to have a display:table/row/cell hierarchy so we need to create
|
||||||
// the browser and clean up the mark-up to make this clearer.
|
three nested wrapper divs:
|
||||||
html.push('<div style="display:table; height:100%; width:100%;');
|
*/
|
||||||
html.push('border:none; margin:0px; padding:0px;'); // neutralizing
|
|
||||||
html.push('#position:relative; overflow:hidden; text-align:left;">');
|
|
||||||
html.push('<div style="#position:absolute; #top:50%; width:100%; ');
|
|
||||||
html.push('border:none; margin:0px; padding:0px;'); // neutralizing
|
|
||||||
html.push('display:table-cell; vertical-align:middle;">');
|
|
||||||
html.push('<div style="#position:relative; #top:-50%; width:100%; ');
|
|
||||||
html.push('border:none; margin:0px; padding:0px;'); // neutralizing
|
|
||||||
html.push('text-align:center;"></div></div></div>');
|
|
||||||
|
|
||||||
div.innerHTML = html.join( '' );
|
var wrappers = [
|
||||||
div = div.firstChild;
|
$.makeNeutralElement( 'div' ),
|
||||||
|
$.makeNeutralElement( 'div' ),
|
||||||
|
$.makeNeutralElement( 'div' )
|
||||||
|
];
|
||||||
|
|
||||||
innerDiv = div;
|
// It feels like we should be able to pass style dicts to makeNeutralElement:
|
||||||
innerDivs = div.getElementsByTagName( "div" );
|
$.extend(wrappers[0].style, {
|
||||||
while ( innerDivs.length > 0 ) {
|
display: "table",
|
||||||
innerDiv = innerDivs[ 0 ];
|
height: "100%",
|
||||||
innerDivs = innerDiv.getElementsByTagName( "div" );
|
width: "100%"
|
||||||
}
|
});
|
||||||
|
|
||||||
innerDiv.appendChild( element );
|
$.extend(wrappers[1].style, {
|
||||||
|
display: "table-row"
|
||||||
|
});
|
||||||
|
|
||||||
return div;
|
$.extend(wrappers[2].style, {
|
||||||
|
display: "table-cell",
|
||||||
|
verticalAlign: "middle",
|
||||||
|
textAlign: "center"
|
||||||
|
});
|
||||||
|
|
||||||
|
wrappers[0].appendChild(wrappers[1]);
|
||||||
|
wrappers[1].appendChild(wrappers[2]);
|
||||||
|
wrappers[2].appendChild(element);
|
||||||
|
|
||||||
|
return wrappers[0];
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
@ -1313,7 +1315,7 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
|
|||||||
makeAjaxRequest: function( url, onSuccess, onError ) {
|
makeAjaxRequest: function( url, onSuccess, onError ) {
|
||||||
var request = $.createAjaxRequest();
|
var request = $.createAjaxRequest();
|
||||||
|
|
||||||
if (!$.isFunction(onSuccess)) {
|
if ( !$.isFunction( onSuccess ) ) {
|
||||||
throw new Error( "makeAjaxRequest requires a success callback" );
|
throw new Error( "makeAjaxRequest requires a success callback" );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1325,9 +1327,9 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
|
|||||||
if ( request.status == 200 ) {
|
if ( request.status == 200 ) {
|
||||||
onSuccess( request );
|
onSuccess( request );
|
||||||
} else {
|
} else {
|
||||||
$.console.log("AJAX request returned %s: %s", request.status, url);
|
$.console.log( "AJAX request returned %s: %s", request.status, url );
|
||||||
|
|
||||||
if ($.isFunction(onError)) {
|
if ( $.isFunction( onError ) ) {
|
||||||
onError( request );
|
onError( request );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1338,11 +1340,11 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
|
|||||||
request.open( "GET", url, true );
|
request.open( "GET", url, true );
|
||||||
request.send( null );
|
request.send( null );
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
$.console.log("%s while making AJAX request: %s", e.name, e.message);
|
$.console.log( "%s while making AJAX request: %s", e.name, e.message );
|
||||||
|
|
||||||
request.onreadystatechange = function(){};
|
request.onreadystatechange = function(){};
|
||||||
|
|
||||||
if ($.isFunction(onError)) {
|
if ( $.isFunction( onError ) ) {
|
||||||
onError( request, e );
|
onError( request, e );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,8 @@ var I18N = {
|
|||||||
ImageFormat: "Sorry, we don't support {0}-based Deep Zoom Images.",
|
ImageFormat: "Sorry, we don't support {0}-based Deep Zoom Images.",
|
||||||
Security: "It looks like a security restriction stopped us from " +
|
Security: "It looks like a security restriction stopped us from " +
|
||||||
"loading this Deep Zoom Image.",
|
"loading this Deep Zoom Image.",
|
||||||
Status: "This space unintentionally left blank ({0} {1})."
|
Status: "This space unintentionally left blank ({0} {1}).",
|
||||||
|
"Open-Failed": "Unable to open {0}: {1}"
|
||||||
},
|
},
|
||||||
|
|
||||||
Tooltips: {
|
Tooltips: {
|
||||||
@ -80,7 +81,8 @@ $.extend( $, {
|
|||||||
string = container[ props[ i ] ];
|
string = container[ props[ i ] ];
|
||||||
|
|
||||||
if ( typeof( string ) != "string" ) {
|
if ( typeof( string ) != "string" ) {
|
||||||
string = "";
|
$.console.debug( "Untranslated source string:", prop );
|
||||||
|
string = ""; // FIXME: this breaks gettext()-style convention, which would return source
|
||||||
}
|
}
|
||||||
|
|
||||||
return string.replace(/\{\d+\}/g, function(capture) {
|
return string.replace(/\{\d+\}/g, function(capture) {
|
||||||
|
@ -293,6 +293,11 @@ $.TileSource.prototype = {
|
|||||||
|
|
||||||
callback = function( data ){
|
callback = function( data ){
|
||||||
var $TileSource = $.TileSource.determineType( _this, data, url );
|
var $TileSource = $.TileSource.determineType( _this, data, url );
|
||||||
|
if ( !$TileSource ) {
|
||||||
|
_this.raiseEvent( 'open-failed', { message: "Unable to load TileSource", source: url } );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
options = $TileSource.prototype.configure.apply( _this, [ data, url ]);
|
options = $TileSource.prototype.configure.apply( _this, [ data, url ]);
|
||||||
readySource = new $TileSource( options );
|
readySource = new $TileSource( options );
|
||||||
_this.ready = true;
|
_this.ready = true;
|
||||||
@ -315,6 +320,11 @@ $.TileSource.prototype = {
|
|||||||
$.makeAjaxRequest( url, function( xhr ) {
|
$.makeAjaxRequest( url, function( xhr ) {
|
||||||
var data = processResponse( xhr );
|
var data = processResponse( xhr );
|
||||||
callback( data );
|
callback( data );
|
||||||
|
}, function ( xhr ) {
|
||||||
|
_this.raiseEvent( 'open-failed', {
|
||||||
|
message: "HTTP " + xhr.status + " attempting to load TileSource",
|
||||||
|
source: url
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -458,6 +468,8 @@ $.TileSource.determineType = function( tileSource, data, url ){
|
|||||||
return OpenSeadragon[ property ];
|
return OpenSeadragon[ property ];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$.console.error( "No TileSource was able to open %s %s", url, data );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -171,6 +171,12 @@ $.Viewer = function( options ) {
|
|||||||
|
|
||||||
//Inherit some behaviors and properties
|
//Inherit some behaviors and properties
|
||||||
$.EventHandler.call( this );
|
$.EventHandler.call( this );
|
||||||
|
|
||||||
|
this.addHandler( 'open-failed', function (source, args) {
|
||||||
|
var msg = $.getString( "Errors.Open-Failed", args.source, args.message);
|
||||||
|
_this._showMessage( msg );
|
||||||
|
});
|
||||||
|
|
||||||
$.ControlDock.call( this, options );
|
$.ControlDock.call( this, options );
|
||||||
|
|
||||||
//Deal with tile sources
|
//Deal with tile sources
|
||||||
@ -417,6 +423,8 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, $.ControlDock.prototype,
|
|||||||
$TileSource,
|
$TileSource,
|
||||||
options;
|
options;
|
||||||
|
|
||||||
|
_this._hideMessage();
|
||||||
|
|
||||||
//allow plain xml strings or json strings to be parsed here
|
//allow plain xml strings or json strings to be parsed here
|
||||||
if( $.type( tileSource ) == 'string' ){
|
if( $.type( tileSource ) == 'string' ){
|
||||||
if( tileSource.match(/\s*<.*/) ){
|
if( tileSource.match(/\s*<.*/) ){
|
||||||
@ -433,6 +441,9 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, $.ControlDock.prototype,
|
|||||||
tileSource = new $.TileSource( tileSource, function( readySource ){
|
tileSource = new $.TileSource( tileSource, function( readySource ){
|
||||||
openTileSource( _this, readySource );
|
openTileSource( _this, readySource );
|
||||||
});
|
});
|
||||||
|
tileSource.addHandler( 'open-failed', function ( name, args ) {
|
||||||
|
_this.raiseEvent( 'open-failed', args );
|
||||||
|
});
|
||||||
|
|
||||||
} else if ( $.isPlainObject( tileSource ) || tileSource.nodeType ){
|
} else if ( $.isPlainObject( tileSource ) || tileSource.nodeType ){
|
||||||
if( $.isFunction( tileSource.getTileUrl ) ){
|
if( $.isFunction( tileSource.getTileUrl ) ){
|
||||||
@ -443,6 +454,13 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, $.ControlDock.prototype,
|
|||||||
} else {
|
} else {
|
||||||
//inline configuration
|
//inline configuration
|
||||||
$TileSource = $.TileSource.determineType( _this, tileSource );
|
$TileSource = $.TileSource.determineType( _this, tileSource );
|
||||||
|
if ( !$TileSource ) {
|
||||||
|
_this.raiseEvent( 'open-failed', {
|
||||||
|
message: "Unable to load TileSource",
|
||||||
|
source: tileSource
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
options = $TileSource.prototype.configure.apply( _this, [ tileSource ]);
|
options = $TileSource.prototype.configure.apply( _this, [ tileSource ]);
|
||||||
readySource = new $TileSource( options );
|
readySource = new $TileSource( options );
|
||||||
openTileSource( _this, readySource );
|
openTileSource( _this, readySource );
|
||||||
@ -1054,8 +1072,39 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, $.ControlDock.prototype,
|
|||||||
this.referenceStrip.setFocus( page );
|
this.referenceStrip.setFocus( page );
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display a message in the viewport
|
||||||
|
* @function
|
||||||
|
* @private
|
||||||
|
* @param {String} text message
|
||||||
|
*/
|
||||||
|
_showMessage: function ( message ) {
|
||||||
|
this._hideMessage();
|
||||||
|
|
||||||
|
var div = $.makeNeutralElement( "div" );
|
||||||
|
div.appendChild( document.createTextNode( message ) );
|
||||||
|
|
||||||
|
this.messageDiv = $.makeCenteredNode( div );
|
||||||
|
|
||||||
|
$.addClass(this.messageDiv, "openseadragon-message");
|
||||||
|
|
||||||
|
this.container.appendChild( this.messageDiv );
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hide any currently displayed viewport message
|
||||||
|
* @function
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_hideMessage: function () {
|
||||||
|
var div = this.messageDiv;
|
||||||
|
if (div) {
|
||||||
|
div.parentNode.removeChild(div);
|
||||||
|
delete this.messageDiv;
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
249
test/basic.js
249
test/basic.js
@ -1,144 +1,211 @@
|
|||||||
/* global module, asyncTest, $, ok, equal, notEqual, start, test, Util */
|
/* global module, asyncTest, $, ok, equal, notEqual, start, test, Util, testLog */
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
|
var viewer;
|
||||||
|
|
||||||
module('Basic');
|
module('Basic', {
|
||||||
|
setup: function () {
|
||||||
|
var example = $('<div id="example"></div>').appendTo("#qunit-fixture");
|
||||||
|
|
||||||
// TODO: Test drag
|
testLog.reset();
|
||||||
|
|
||||||
var viewer = null;
|
|
||||||
|
|
||||||
// ----------
|
|
||||||
asyncTest('Open', function() {
|
|
||||||
$(document).ready(function() {
|
|
||||||
viewer = OpenSeadragon({
|
viewer = OpenSeadragon({
|
||||||
id: 'example',
|
id: 'example',
|
||||||
prefixUrl: '/build/openseadragon/images/',
|
prefixUrl: '/build/openseadragon/images/',
|
||||||
tileSources: '/test/data/testpattern.dzi',
|
|
||||||
springStiffness: 100 // Faster animation = faster tests
|
springStiffness: 100 // Faster animation = faster tests
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
teardown: function () {
|
||||||
|
if (viewer && viewer.close) {
|
||||||
|
viewer.close();
|
||||||
|
}
|
||||||
|
|
||||||
ok(viewer, 'Viewer exists');
|
viewer = null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
var openHandler = function(eventSender, eventData) {
|
// ----------
|
||||||
viewer.removeHandler('open', openHandler);
|
asyncTest('Open', function() {
|
||||||
ok(true, 'Open event was sent');
|
ok(viewer, 'Viewer exists');
|
||||||
equal(eventSender, viewer, 'Sender of open event was viewer');
|
|
||||||
ok(eventData, 'Handler also received event data');
|
|
||||||
ok(viewer.viewport, 'Viewport exists');
|
|
||||||
ok(viewer.source, 'source exists');
|
|
||||||
ok(viewer._updateRequestId, 'timer is on');
|
|
||||||
start();
|
|
||||||
};
|
|
||||||
|
|
||||||
viewer.addHandler('open', openHandler);
|
var openHandler = function(eventSender, eventData) {
|
||||||
|
viewer.removeHandler('open', openHandler);
|
||||||
|
ok(true, 'Open event was sent');
|
||||||
|
equal(eventSender, viewer, 'Sender of open event was viewer');
|
||||||
|
ok(eventData, 'Handler also received event data');
|
||||||
|
ok(viewer.viewport, 'Viewport exists');
|
||||||
|
ok(viewer.source, 'source exists');
|
||||||
|
ok(viewer._updateRequestId, 'timer is on');
|
||||||
|
start();
|
||||||
|
};
|
||||||
|
|
||||||
|
viewer.addHandler('open', openHandler);
|
||||||
|
viewer.open('/test/data/testpattern.dzi');
|
||||||
|
});
|
||||||
|
|
||||||
|
asyncTest('Open Error Handling', function() {
|
||||||
|
ok(viewer, 'Viewer exists');
|
||||||
|
|
||||||
|
viewer.addHandler('open', function(eventSender, eventData) {
|
||||||
|
ok(false, "The open event should not fire for failed opens");
|
||||||
|
start();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
viewer.addHandler('open-failed', function(eventSender, eventData) {
|
||||||
|
ok(true, "The open-failed event should be fired when the source 404s");
|
||||||
|
|
||||||
|
equal($(".openseadragon-message").length, 1, "Open failures should display a message");
|
||||||
|
|
||||||
|
ok(testLog.log.contains('["AJAX request returned %s: %s",404,"/test/data/not-a-real-file"]'),
|
||||||
|
"AJAX failures should be logged to the console");
|
||||||
|
|
||||||
|
start();
|
||||||
|
});
|
||||||
|
|
||||||
|
viewer.open('/test/data/not-a-real-file');
|
||||||
});
|
});
|
||||||
|
|
||||||
// ----------
|
// ----------
|
||||||
asyncTest('Zoom', function() {
|
asyncTest('Zoom', function() {
|
||||||
var viewport = viewer.viewport;
|
viewer.addHandler("open", function () {
|
||||||
equal(viewport.getZoom(), 1, 'We start out unzoomed');
|
var viewport = viewer.viewport;
|
||||||
|
|
||||||
var zoomHandler = function() {
|
equal(viewport.getZoom(), 1, 'We start out unzoomed');
|
||||||
viewer.removeHandler('animationfinish', zoomHandler);
|
|
||||||
equal(viewport.getZoom(), 2, 'Zoomed correctly');
|
|
||||||
start();
|
|
||||||
};
|
|
||||||
|
|
||||||
viewer.addHandler('animationfinish', zoomHandler);
|
var zoomHandler = function() {
|
||||||
viewport.zoomTo(2);
|
viewer.removeHandler('animationfinish', zoomHandler);
|
||||||
|
equal(viewport.getZoom(), 2, 'Zoomed correctly');
|
||||||
|
start();
|
||||||
|
};
|
||||||
|
|
||||||
|
viewer.addHandler('animationfinish', zoomHandler);
|
||||||
|
viewport.zoomTo(2);
|
||||||
|
});
|
||||||
|
viewer.open('/test/data/testpattern.dzi');
|
||||||
});
|
});
|
||||||
|
|
||||||
// ----------
|
// ----------
|
||||||
asyncTest('Pan', function() {
|
asyncTest('Pan', function() {
|
||||||
var viewport = viewer.viewport;
|
viewer.addHandler("open", function () {
|
||||||
var center = viewport.getCenter();
|
var viewport = viewer.viewport,
|
||||||
ok(center.x === 0.5 && center.y === 0.5, 'We start out unpanned');
|
center = viewport.getCenter();
|
||||||
|
|
||||||
var panHandler = function() {
|
ok(center.x === 0.5 && center.y === 0.5, 'We start out unpanned');
|
||||||
viewer.removeHandler('animationfinish', panHandler);
|
|
||||||
center = viewport.getCenter();
|
|
||||||
ok(center.x === 0.1 && center.y === 0.1, 'Panned correctly');
|
|
||||||
start();
|
|
||||||
};
|
|
||||||
|
|
||||||
viewer.addHandler('animationfinish', panHandler);
|
var panHandler = function() {
|
||||||
viewport.panTo(new OpenSeadragon.Point(0.1, 0.1));
|
viewer.removeHandler('animationfinish', panHandler);
|
||||||
|
center = viewport.getCenter();
|
||||||
|
ok(center.x === 0.1 && center.y === 0.1, 'Panned correctly');
|
||||||
|
start();
|
||||||
|
};
|
||||||
|
|
||||||
|
viewer.addHandler('animationfinish', panHandler);
|
||||||
|
viewport.panTo(new OpenSeadragon.Point(0.1, 0.1));
|
||||||
|
});
|
||||||
|
|
||||||
|
viewer.open('/test/data/testpattern.dzi');
|
||||||
});
|
});
|
||||||
|
|
||||||
// ----------
|
// ----------
|
||||||
asyncTest('Home', function() {
|
asyncTest('Home', function() {
|
||||||
var viewport = viewer.viewport;
|
// Test setup:
|
||||||
var center = viewport.getCenter();
|
function opener() {
|
||||||
ok(center.x !== 0.5 && center.y !== 0.5, 'We start out panned');
|
var viewport = viewer.viewport;
|
||||||
notEqual(viewport.getZoom(), 1, 'We start out zoomed');
|
viewport.panTo(new OpenSeadragon.Point(0.1, 0.1));
|
||||||
|
viewport.zoomTo(2);
|
||||||
|
}
|
||||||
|
|
||||||
var homeHandler = function() {
|
function stage1() {
|
||||||
viewer.removeHandler('animationfinish', homeHandler);
|
var viewport = viewer.viewport,
|
||||||
center = viewport.getCenter();
|
center = viewport.getCenter();
|
||||||
ok(center.x === 0.5 && center.y === 0.5, 'We end up unpanned');
|
|
||||||
equal(viewport.getZoom(), 1, 'We end up unzoomed');
|
|
||||||
start();
|
|
||||||
};
|
|
||||||
|
|
||||||
viewer.addHandler('animationfinish', homeHandler);
|
viewer.removeHandler('animationfinish', stage1);
|
||||||
viewport.goHome(true);
|
|
||||||
|
ok(center.x !== 0.5 && center.y !== 0.5, 'We start out panned');
|
||||||
|
notEqual(viewport.getZoom(), 1, 'We start out zoomed');
|
||||||
|
|
||||||
|
var homeHandler = function() {
|
||||||
|
viewer.removeHandler('animationfinish', homeHandler);
|
||||||
|
center = viewport.getCenter();
|
||||||
|
ok(center.x === 0.5 && center.y === 0.5, 'We end up unpanned');
|
||||||
|
equal(viewport.getZoom(), 1, 'We end up unzoomed');
|
||||||
|
start();
|
||||||
|
};
|
||||||
|
|
||||||
|
viewer.addHandler('animationfinish', homeHandler);
|
||||||
|
viewport.goHome(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
viewer.addHandler("open", opener);
|
||||||
|
viewer.addHandler("animationfinish", stage1);
|
||||||
|
|
||||||
|
viewer.open('/test/data/testpattern.dzi');
|
||||||
});
|
});
|
||||||
|
|
||||||
// ----------
|
// ----------
|
||||||
asyncTest('Click', function() {
|
asyncTest('Click', function() {
|
||||||
var viewport = viewer.viewport,
|
viewer.addHandler("open", function () {
|
||||||
|
var viewport = viewer.viewport,
|
||||||
center = viewport.getCenter();
|
center = viewport.getCenter();
|
||||||
|
|
||||||
ok(center.x === 0.5 && center.y === 0.5, 'We start out unpanned');
|
ok(center.x === 0.5 && center.y === 0.5, 'We start out unpanned');
|
||||||
equal(viewport.getZoom(), 1, 'We start out unzoomed');
|
equal(viewport.getZoom(), 1, 'We start out unzoomed');
|
||||||
|
|
||||||
var clickHandler = function() {
|
var clickHandler = function() {
|
||||||
viewer.removeHandler('animationfinish', clickHandler);
|
viewer.removeHandler('animationfinish', clickHandler);
|
||||||
center = viewport.getCenter();
|
center = viewport.getCenter();
|
||||||
ok(center.x > 0.37 && center.x < 0.38 && center.y > 0.37 && center.y < 0.38, 'Panned correctly');
|
ok(center.x > 0.37 && center.x < 0.38 && center.y > 0.37 && center.y < 0.38, 'Panned correctly');
|
||||||
equal(viewport.getZoom(), 2, 'Zoomed correctly');
|
equal(viewport.getZoom(), 2, 'Zoomed correctly');
|
||||||
start();
|
start();
|
||||||
};
|
};
|
||||||
|
|
||||||
viewer.addHandler('animationfinish', clickHandler);
|
viewer.addHandler('animationfinish', clickHandler);
|
||||||
Util.simulateViewerClick(viewer, 0.25, 0.25);
|
Util.simulateViewerClick(viewer, 0.25, 0.25);
|
||||||
|
});
|
||||||
|
|
||||||
|
viewer.open('/test/data/testpattern.dzi');
|
||||||
});
|
});
|
||||||
|
|
||||||
// ----------
|
// ----------
|
||||||
test('Fullscreen', function() {
|
asyncTest('Fullscreen', function() {
|
||||||
ok(!viewer.isFullPage(), 'Started out not fullpage');
|
viewer.addHandler("open", function () {
|
||||||
ok(!$(viewer.element).hasClass('fullpage'),
|
ok(!viewer.isFullPage(), 'Started out not fullpage');
|
||||||
'No fullpage class on div');
|
ok(!$(viewer.element).hasClass('fullpage'),
|
||||||
|
'No fullpage class on div');
|
||||||
|
|
||||||
viewer.setFullPage(true);
|
viewer.setFullPage(true);
|
||||||
ok(viewer.isFullPage(), 'Enabled fullpage');
|
ok(viewer.isFullPage(), 'Enabled fullpage');
|
||||||
ok($(viewer.element).hasClass('fullpage'),
|
ok($(viewer.element).hasClass('fullpage'),
|
||||||
'Fullpage class added to div');
|
'Fullpage class added to div');
|
||||||
|
|
||||||
viewer.setFullPage(false);
|
viewer.setFullPage(false);
|
||||||
ok(!viewer.isFullPage(), 'Disabled fullpage');
|
ok(!viewer.isFullPage(), 'Disabled fullpage');
|
||||||
ok(!$(viewer.element).hasClass('fullpage'),
|
ok(!$(viewer.element).hasClass('fullpage'),
|
||||||
'Fullpage class removed from div');
|
'Fullpage class removed from div');
|
||||||
|
start();
|
||||||
|
});
|
||||||
|
|
||||||
|
viewer.open('/test/data/testpattern.dzi');
|
||||||
});
|
});
|
||||||
|
|
||||||
// ----------
|
// ----------
|
||||||
asyncTest('Close', function() {
|
asyncTest('Close', function() {
|
||||||
var closeHandler = function() {
|
viewer.addHandler("open", function () {
|
||||||
viewer.removeHandler('close', closeHandler);
|
var closeHandler = function() {
|
||||||
ok(!viewer.source, 'no source');
|
viewer.removeHandler('close', closeHandler);
|
||||||
$('#example').empty();
|
ok(!viewer.source, 'no source');
|
||||||
ok(true, 'Close event was sent');
|
ok(true, 'Close event was sent');
|
||||||
ok(!viewer._updateRequestId, 'timer is off');
|
ok(!viewer._updateRequestId, 'timer is off');
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
ok(!viewer._updateRequestId, 'timer is still off');
|
ok(!viewer._updateRequestId, 'timer is still off');
|
||||||
start();
|
start();
|
||||||
}, 100);
|
}, 100);
|
||||||
};
|
};
|
||||||
|
|
||||||
viewer.addHandler('close', closeHandler);
|
viewer.addHandler('close', closeHandler);
|
||||||
viewer.close();
|
viewer.close();
|
||||||
|
});
|
||||||
|
viewer.open('/test/data/testpattern.dzi');
|
||||||
});
|
});
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>OpenSeadragon Basic Demo</title>
|
<title>OpenSeadragon Basic Demo</title>
|
||||||
|
@ -3,7 +3,13 @@
|
|||||||
// This module tests whether our various file formats can be opened.
|
// This module tests whether our various file formats can be opened.
|
||||||
// TODO: Add more file formats (with corresponding test data).
|
// TODO: Add more file formats (with corresponding test data).
|
||||||
|
|
||||||
module('Formats');
|
module('Formats', {
|
||||||
|
setup: function () {
|
||||||
|
var example = document.createElement("div");
|
||||||
|
example.id = "example";
|
||||||
|
document.getElementById("qunit-fixture").appendChild(example);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
var viewer = null;
|
var viewer = null;
|
||||||
|
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
/* global QUnit, module, Util, $, console, test, asyncTest, start, ok, equal */
|
||||||
|
|
||||||
QUnit.config.autostart = false;
|
QUnit.config.autostart = false;
|
||||||
|
|
||||||
(function () {
|
(function () {
|
||||||
@ -14,14 +16,18 @@ QUnit.config.autostart = false;
|
|||||||
topNavigatorClickAdjustment;
|
topNavigatorClickAdjustment;
|
||||||
|
|
||||||
module("navigator", {
|
module("navigator", {
|
||||||
setup:function () {
|
setup: function () {
|
||||||
Util.resetDom();
|
Util.initializeTestDOM();
|
||||||
resetTestVariables();
|
resetTestVariables();
|
||||||
$(document).scrollTop(0);
|
$(document).scrollTop(0);
|
||||||
$(document).scrollLeft(0);
|
$(document).scrollLeft(0);
|
||||||
},
|
},
|
||||||
teardown:function () {
|
teardown: function () {
|
||||||
Util.resetDom();
|
// jQuery UI creates its controls outside the normal DOM hierarchy which QUnit cleans up:
|
||||||
|
if ($('#exampleNavigator').is(':ui-dialog')) {
|
||||||
|
$('#exampleNavigator').dialog('destroy');
|
||||||
|
}
|
||||||
|
|
||||||
resetTestVariables();
|
resetTestVariables();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -31,7 +37,7 @@ QUnit.config.autostart = false;
|
|||||||
});
|
});
|
||||||
|
|
||||||
var resetTestVariables = function () {
|
var resetTestVariables = function () {
|
||||||
if (viewer != null) {
|
if (viewer) {
|
||||||
viewer.close();
|
viewer.close();
|
||||||
}
|
}
|
||||||
displayRegion = null;
|
displayRegion = null;
|
||||||
@ -125,11 +131,11 @@ QUnit.config.autostart = false;
|
|||||||
viewerAndNavigatorDisplayReady = viewer.drawer !== null &&
|
viewerAndNavigatorDisplayReady = viewer.drawer !== null &&
|
||||||
!viewer.drawer.needsUpdate() &&
|
!viewer.drawer.needsUpdate() &&
|
||||||
currentDisplayWidth > 0 &&
|
currentDisplayWidth > 0 &&
|
||||||
Util.equalsWithVariance(lastDisplayRegionLeft, currentDisplayRegionLeft, .0001) &&
|
Util.equalsWithVariance(lastDisplayRegionLeft, currentDisplayRegionLeft, 0.0001) &&
|
||||||
Util.equalsWithVariance(lastDisplayWidth, currentDisplayWidth, .0001) &&
|
Util.equalsWithVariance(lastDisplayWidth, currentDisplayWidth, 0.0001) &&
|
||||||
Util.equalsWithVariance(viewer.viewport.getBounds(true).x, viewer.viewport.getBounds().x, .0001) &&
|
Util.equalsWithVariance(viewer.viewport.getBounds(true).x, viewer.viewport.getBounds().x, 0.0001) &&
|
||||||
Util.equalsWithVariance(viewer.viewport.getBounds(true).y, viewer.viewport.getBounds().y, .0001) &&
|
Util.equalsWithVariance(viewer.viewport.getBounds(true).y, viewer.viewport.getBounds().y, 0.0001) &&
|
||||||
Util.equalsWithVariance(viewer.viewport.getBounds(true).width, viewer.viewport.getBounds().width, .0001);
|
Util.equalsWithVariance(viewer.viewport.getBounds(true).width, viewer.viewport.getBounds().width, 0.0001);
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
//Ignore. Subsequent code will try again shortly
|
//Ignore. Subsequent code will try again shortly
|
||||||
@ -138,7 +144,7 @@ QUnit.config.autostart = false;
|
|||||||
count++;
|
count++;
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
waitForViewer(handler, count, currentDisplayRegionLeft, currentDisplayWidth);
|
waitForViewer(handler, count, currentDisplayRegionLeft, currentDisplayWidth);
|
||||||
}, 100)
|
}, 100);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (count === 40) {
|
if (count === 40) {
|
||||||
@ -201,21 +207,21 @@ QUnit.config.autostart = false;
|
|||||||
expecteYCoordinate = 1 / viewer.source.aspectRatio - viewer.viewport.getBounds().height;
|
expecteYCoordinate = 1 / viewer.source.aspectRatio - viewer.viewport.getBounds().height;
|
||||||
}
|
}
|
||||||
if (viewer.viewport.getBounds().width < 1) {
|
if (viewer.viewport.getBounds().width < 1) {
|
||||||
Util.assessNumericValue(expectedXCoordinate, viewer.viewport.getBounds().x, .04, ' Viewer at ' + theContentCorner + ', x coord');
|
Util.assessNumericValue(expectedXCoordinate, viewer.viewport.getBounds().x, 0.04, ' Viewer at ' + theContentCorner + ', x coord');
|
||||||
}
|
}
|
||||||
if (viewer.viewport.getBounds().height < 1 / viewer.source.aspectRatio) {
|
if (viewer.viewport.getBounds().height < 1 / viewer.source.aspectRatio) {
|
||||||
Util.assessNumericValue(expecteYCoordinate, viewer.viewport.getBounds().y, .04, ' Viewer at ' + theContentCorner + ', y coord');
|
Util.assessNumericValue(expecteYCoordinate, viewer.viewport.getBounds().y, 0.04, ' Viewer at ' + theContentCorner + ', y coord');
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
var assessViewerInCenter = function () {
|
var assessViewerInCenter = function () {
|
||||||
var yPositionVariance = .04;
|
var yPositionVariance = 0.04;
|
||||||
if (viewer.source.aspectRatio < 1) {
|
if (viewer.source.aspectRatio < 1) {
|
||||||
yPositionVariance = yPositionVariance / viewer.source.aspectRatio;
|
yPositionVariance = yPositionVariance / viewer.source.aspectRatio;
|
||||||
}
|
}
|
||||||
Util.assessNumericValue(1 / viewer.source.aspectRatio / 2, viewer.viewport.getCenter().y, yPositionVariance, ' Viewer at center, y coord');
|
Util.assessNumericValue(1 / viewer.source.aspectRatio / 2, viewer.viewport.getCenter().y, yPositionVariance, ' Viewer at center, y coord');
|
||||||
Util.assessNumericValue(.5, viewer.viewport.getCenter().x, .4, ' Viewer at center, x coord');
|
Util.assessNumericValue(0.5, viewer.viewport.getCenter().x, 0.4, ' Viewer at center, x coord');
|
||||||
};
|
};
|
||||||
|
|
||||||
var clickOnNavigator = function (theContentCorner) {
|
var clickOnNavigator = function (theContentCorner) {
|
||||||
@ -239,7 +245,7 @@ QUnit.config.autostart = false;
|
|||||||
yPos = contentStartFromTop + displayRegionHeight;
|
yPos = contentStartFromTop + displayRegionHeight;
|
||||||
}
|
}
|
||||||
simulateNavigatorClick(viewer.navigator, xPos, yPos);
|
simulateNavigatorClick(viewer.navigator, xPos, yPos);
|
||||||
}
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
var dragNavigatorBackToCenter = function () {
|
var dragNavigatorBackToCenter = function () {
|
||||||
@ -354,11 +360,12 @@ QUnit.config.autostart = false;
|
|||||||
clientX:1,
|
clientX:1,
|
||||||
clientY:1
|
clientY:1
|
||||||
};
|
};
|
||||||
mainViewerElement.simulate('blur', event);
|
|
||||||
|
$("#" + seadragonProperties.id).simulate('blur', event);
|
||||||
|
|
||||||
if (testProperties.expectedAutoFade) {
|
if (testProperties.expectedAutoFade) {
|
||||||
setTimeout(assessAutoFadeTriggered,autoFadeWaitTime);
|
setTimeout(assessAutoFadeTriggered,autoFadeWaitTime);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
setTimeout(assessAutoFadeDisabled,autoFadeWaitTime);
|
setTimeout(assessAutoFadeDisabled,autoFadeWaitTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,33 @@
|
|||||||
|
/* global module, asyncTest, $, ok, equal, notEqual, start, test, Util, testLog */
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
|
|
||||||
module("strings");
|
module("strings", {
|
||||||
|
setup: function () {
|
||||||
|
testLog.reset();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
test("getSubString", function() {
|
test("getSubString", function() {
|
||||||
equal(OpenSeadragon.getString("Errors.Dzi"),
|
equal(OpenSeadragon.getString("Errors.Dzi"),
|
||||||
"Hmm, this doesn't appear to be a valid Deep Zoom Image.",
|
"Hmm, this doesn't appear to be a valid Deep Zoom Image.",
|
||||||
"Read sub-string");
|
"Read sub-string");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("getStringWithPlaceholders", function() {
|
||||||
|
equal(OpenSeadragon.getString("Errors.Open-Failed", "foo", "bar"),
|
||||||
|
"Unable to open foo: bar",
|
||||||
|
"String placeholder replacement");
|
||||||
|
});
|
||||||
|
|
||||||
test("getInvalidString", function() {
|
test("getInvalidString", function() {
|
||||||
equal(OpenSeadragon.getString("Greeting"), "",
|
equal(OpenSeadragon.getString("Greeting"), "", "Handled unset string key");
|
||||||
"Handled unset string key");
|
ok(testLog.debug.contains('["Untranslated source string:","Greeting"]'),
|
||||||
equal(OpenSeadragon.getString("Errors"), "",
|
'Invalid string keys are logged');
|
||||||
"Handled requesting parent key");
|
|
||||||
|
equal(OpenSeadragon.getString("Errors"), "", "Handled requesting parent key");
|
||||||
|
ok(testLog.debug.contains('["Untranslated source string:","Errors"]'),
|
||||||
|
'Invalid string parent keys are logged');
|
||||||
});
|
});
|
||||||
|
|
||||||
test("setString", function() {
|
test("setString", function() {
|
||||||
|
@ -10,12 +10,6 @@
|
|||||||
<body>
|
<body>
|
||||||
<div id="qunit"></div>
|
<div id="qunit"></div>
|
||||||
<div id="qunit-fixture"></div>
|
<div id="qunit-fixture"></div>
|
||||||
<div>
|
|
||||||
<div id="example"></div>
|
|
||||||
<div id="exampleNavigator"></div>
|
|
||||||
</div>
|
|
||||||
<div id="wideexample"></div>
|
|
||||||
<div id="tallexample"></div>
|
|
||||||
<script src="/node_modules/grunt-contrib-qunit/test/libs/qunit.js"></script>
|
<script src="/node_modules/grunt-contrib-qunit/test/libs/qunit.js"></script>
|
||||||
<script src="/test/lib/jquery-1.9.1.min.js"></script>
|
<script src="/test/lib/jquery-1.9.1.min.js"></script>
|
||||||
<script src="/test/lib/jquery-ui-1.10.2/js/jquery-ui-1.10.2.min.js"></script>
|
<script src="/test/lib/jquery-ui-1.10.2/js/jquery-ui-1.10.2.min.js"></script>
|
||||||
|
63
test/test.js
63
test/test.js
@ -1,3 +1,5 @@
|
|||||||
|
/* global module, asyncTest, $, ok, equal, notEqual, start, test, Util */
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
|
|
||||||
// ----------
|
// ----------
|
||||||
@ -30,16 +32,11 @@
|
|||||||
.simulate('mouseup', event);
|
.simulate('mouseup', event);
|
||||||
},
|
},
|
||||||
|
|
||||||
resetDom: function () {
|
initializeTestDOM: function () {
|
||||||
if ($('#exampleNavigator').is(':ui-dialog')) {
|
$("#qunit-fixture")
|
||||||
$('#exampleNavigator').dialog('destroy');
|
.append('<div><div id="example"></div><div id="exampleNavigator"></div></div>')
|
||||||
}
|
.append('<div id="wideexample"></div>')
|
||||||
$("#exampleNavigator").remove();
|
.append('<div id="tallexample"></div>');
|
||||||
$(".navigator").remove();
|
|
||||||
$("#example").empty();
|
|
||||||
$("#tallexample").empty();
|
|
||||||
$("#wideexample").empty();
|
|
||||||
$("#example").parent().append('<div id="exampleNavigator"></div>');
|
|
||||||
},
|
},
|
||||||
|
|
||||||
equalsWithVariance: function (value1, value2, variance) {
|
equalsWithVariance: function (value1, value2, variance) {
|
||||||
@ -74,5 +71,51 @@
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Test console log capture
|
||||||
|
|
||||||
|
1. Only the OpenSeadragon.console logger is touched
|
||||||
|
2. All log messages are stored in window.testLog in arrays keyed on the logger name (e.g. log,
|
||||||
|
warning, error, etc.) as JSON-serialized strings to simplify comparisons
|
||||||
|
3. The captured log arrays have a custom contains() method for ease of testing
|
||||||
|
4. testLog.reset() will clear all of the message arrays, intended for use in test setup routines
|
||||||
|
*/
|
||||||
|
var testConsole = window.testConsole = {},
|
||||||
|
testLog = window.testLog = {
|
||||||
|
log: [],
|
||||||
|
debug: [],
|
||||||
|
info: [],
|
||||||
|
warn: [],
|
||||||
|
error: [],
|
||||||
|
reset: function () {
|
||||||
|
for (var i in testLog) {
|
||||||
|
if (testLog.hasOwnProperty(i) && 'length' in testLog[i] && 'push' in testLog[i]) {
|
||||||
|
testLog[i].length = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
for (var i in testLog) {
|
||||||
|
if (testLog.hasOwnProperty(i) && testLog[i].push) {
|
||||||
|
testConsole[i] = (function (arr) {
|
||||||
|
return function () {
|
||||||
|
var args = Array.prototype.slice.call(arguments, 0); // Coerce to true Array
|
||||||
|
arr.push(JSON.stringify(args)); // Store as JSON to avoid tedious array-equality tests
|
||||||
|
};
|
||||||
|
})(testLog[i]);
|
||||||
|
|
||||||
|
testLog[i].contains = function (needle) {
|
||||||
|
for (var i = 0; i < this.length; i++) {
|
||||||
|
if (this[i] == needle) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
OpenSeadragon.console = testConsole;
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
/* global module, asyncTest, $, ok, equal, strictEqual, notEqual, start, test, Util, testLog */
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
|
|
||||||
module("utils");
|
module("utils");
|
||||||
@ -56,10 +58,33 @@
|
|||||||
asyncTest("makeAjaxRequest", function() {
|
asyncTest("makeAjaxRequest", function() {
|
||||||
var timeWatcher = Util.timeWatcher();
|
var timeWatcher = Util.timeWatcher();
|
||||||
|
|
||||||
OpenSeadragon.makeAjaxRequest('data/testpattern.dzi', function(xhr) {
|
OpenSeadragon.makeAjaxRequest('data/testpattern.dzi',
|
||||||
ok(/deepzoom/.test(xhr.response), 'file loaded');
|
function(xhr) {
|
||||||
timeWatcher.done();
|
equal(xhr.status, 200, 'Success callback called for HTTP 200');
|
||||||
});
|
ok(/deepzoom/.test(xhr.responseText), 'Success function called');
|
||||||
|
timeWatcher.done();
|
||||||
|
},
|
||||||
|
function(xhr) {
|
||||||
|
ok(false, 'Error callback should not be called');
|
||||||
|
timeWatcher.done();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
asyncTest("makeAjaxRequest for invalid file", function() {
|
||||||
|
var timeWatcher = Util.timeWatcher();
|
||||||
|
|
||||||
|
OpenSeadragon.makeAjaxRequest('not-a-real-dzi-file',
|
||||||
|
function(xhr) {
|
||||||
|
ok(false, 'Success function should not be called for errors');
|
||||||
|
timeWatcher.done();
|
||||||
|
},
|
||||||
|
function(xhr) {
|
||||||
|
equal(xhr.status, 404, 'Error callback called for HTTP 404');
|
||||||
|
ok(true, 'Error function should be called for errors');
|
||||||
|
timeWatcher.done();
|
||||||
|
}
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
// ----------
|
// ----------
|
||||||
|
Loading…
Reference in New Issue
Block a user