Fix test messages, add doc and factorize overlay object creation

This commit is contained in:
Antoine Vandecreme 2014-03-15 11:20:33 -04:00
parent 0f43cd5a16
commit ecf10f5911
4 changed files with 114 additions and 94 deletions

View File

@ -136,6 +136,28 @@
* is an Array of objects, it is used to create a * is an Array of objects, it is used to create a
* {@link OpenSeadragon.LegacyTileSource}. * {@link OpenSeadragon.LegacyTileSource}.
* *
* @property {Array} overlays Array of objects defining permanent overlays of
* the viewer. The overlays added via this options and later removed with
* {@link OpenSeadragon.Viewer#removeOverlay} will be added back when a new
* image is opened.
* To add overlays which can be definitly removed, one must use
* {@link OpenSeadragon.Viewer#addOverlay}
* If displaying a sequence of images, the overlays can be associated
* with a specific page by passing the overlays array to the page's
* tile source configuration.
* Expected properties:
* * x, y, (or px, py for pixel coordinates) to define the location.
* * width, height in point if using x,y or in pixels if using px,py. If width
* and height are specified, the overlay size is adjusted when zooming,
* otherwise the size stay the size of the content (or the size defined by CSS).
* * className to associate a class to the overlay
* * id to set the overlay element. If an element with this id already exists,
* it is reused, otherwise it is created. If not specified, a new element is
* created.
* * placement a string to define the relative position to the viewport.
* Only used if no width and height are specified. Default: TOP_LEFT.
* See {@link OpenSeadragon.OverlayPlacement} for possible values.
*
* @property {String} [xmlPath=null] * @property {String} [xmlPath=null]
* <strong>DEPRECATED</strong>. A relative path to load a DZI file from the server. * <strong>DEPRECATED</strong>. A relative path to load a DZI file from the server.
* Prefer the newer Options.tileSources. * Prefer the newer Options.tileSources.

View File

@ -73,7 +73,7 @@
* @param {OpenSeadragon.Point|OpenSeadragon.Rect} options.location - The * @param {OpenSeadragon.Point|OpenSeadragon.Rect} options.location - The
* location of the overlay on the image. If a {@link OpenSeadragon.Point} * location of the overlay on the image. If a {@link OpenSeadragon.Point}
* is specified, the overlay will keep a constant size independently of the * is specified, the overlay will keep a constant size independently of the
* zoom. It a {@link OpenSeadragon.Rect} is specified, the overlay size will * zoom. If a {@link OpenSeadragon.Rect} is specified, the overlay size will
* be adjusted when the zoom changes. * be adjusted when the zoom changes.
* @param {OpenSeadragon.OverlayPlacement} [options.placement=OpenSeadragon.OverlayPlacement.TOP_LEFT] * @param {OpenSeadragon.OverlayPlacement} [options.placement=OpenSeadragon.OverlayPlacement.TOP_LEFT]
* Relative position to the viewport. * Relative position to the viewport.

View File

@ -127,10 +127,7 @@ $.Viewer = function( options ) {
canvas: null, canvas: null,
// Overlays list. An overlay allows to add html on top of the viewer. // Overlays list. An overlay allows to add html on top of the viewer.
// Configured overlays via viewer's options
overlays: [], overlays: [],
// Currently opened overlays
currentOverlays: [],
//private state properties //private state properties
previousBody: [], previousBody: [],
@ -212,6 +209,7 @@ $.Viewer = function( options ) {
}; };
this._updateRequestId = null; this._updateRequestId = null;
this.currentOverlays = [];
//Inherit some behaviors and properties //Inherit some behaviors and properties
$.EventSource.call( this ); $.EventSource.call( this );
@ -1303,7 +1301,8 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype,
/** /**
* Adds an html element as an overlay to the current viewport. Useful for * Adds an html element as an overlay to the current viewport. Useful for
* highlighting words or areas of interest on an image or other zoomable * highlighting words or areas of interest on an image or other zoomable
* interface. * interface. The overlays added via this method are removed when the viewport
* is closed which include when changing page.
* @method * @method
* @param {Element|String|Object} element - A reference to an element or an id for * @param {Element|String|Object} element - A reference to an element or an id for
* the element which will overlayed. Or an Object specifying the configuration for the overlay * the element which will overlayed. Or an Object specifying the configuration for the overlay
@ -1331,19 +1330,13 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype,
}; };
} }
element = $.getElement(options.element); element = $.getElement( options.element );
if ( getOverlayIndex( this.currentOverlays, element ) >= 0 ) { if ( getOverlayIndex( this.currentOverlays, element ) >= 0 ) {
// they're trying to add a duplicate overlay // they're trying to add a duplicate overlay
return this; return this;
} }
this.currentOverlays.push( getOverlayObject( this, options ) );
this.currentOverlays.push( new $.Overlay({
element: element,
location: options.location,
placement: options.placement,
onDraw: options.onDraw
}) );
THIS[ this.hash ].forceRedraw = true; THIS[ this.hash ].forceRedraw = true;
/** /**
* Raised when an overlay is added to the viewer (see {@link OpenSeadragon.Viewer#addOverlay}). * Raised when an overlay is added to the viewer (see {@link OpenSeadragon.Viewer#addOverlay}).
@ -1622,7 +1615,6 @@ function openTileSource( viewer, source ) {
source: _this.source, source: _this.source,
viewport: _this.viewport, viewport: _this.viewport,
element: _this.canvas, element: _this.canvas,
overlays: [].concat( _this.overlays ).concat( _this.source.overlays ),
maxImageCacheCount: _this.maxImageCacheCount, maxImageCacheCount: _this.maxImageCacheCount,
imageLoaderLimit: _this.imageLoaderLimit, imageLoaderLimit: _this.imageLoaderLimit,
minZoomImageRatio: _this.minZoomImageRatio, minZoomImageRatio: _this.minZoomImageRatio,
@ -1657,7 +1649,6 @@ function openTileSource( viewer, source ) {
tileSources: source, tileSources: source,
tileHost: _this.tileHost, tileHost: _this.tileHost,
prefixUrl: _this.prefixUrl, prefixUrl: _this.prefixUrl,
overlays: _this.overlays,
viewer: _this viewer: _this
}); });
} }
@ -1675,7 +1666,6 @@ function openTileSource( viewer, source ) {
tileSources: _this.tileSources, tileSources: _this.tileSources,
tileHost: _this.tileHost, tileHost: _this.tileHost,
prefixUrl: _this.prefixUrl, prefixUrl: _this.prefixUrl,
overlays: _this.overlays,
viewer: _this viewer: _this
}); });
} }
@ -1688,15 +1678,7 @@ function openTileSource( viewer, source ) {
VIEWERS[ _this.hash ] = _this; VIEWERS[ _this.hash ] = _this;
_this.currentOverlays = []; loadOverlays( _this );
var i;
for ( i = 0; i < _this.overlays.length; i++ ) {
_this.currentOverlays[ i ] = getOverlayObject( _this, _this.overlays[ i ] );
}
for ( var j = 0; j < _this.source.overlays.length; j++ ) {
_this.currentOverlays[ i + j ] =
getOverlayObject( _this, _this.source.overlays[ j ] );
}
/** /**
* Raised when the viewer has opened and loaded one or more TileSources. * Raised when the viewer has opened and loaded one or more TileSources.
@ -1713,28 +1695,33 @@ function openTileSource( viewer, source ) {
return _this; return _this;
} }
function loadOverlays( _this ) {
_this.currentOverlays = [];
for ( var i = 0; i < _this.overlays.length; i++ ) {
_this.currentOverlays[ i ] = getOverlayObject( _this, _this.overlays[ i ] );
}
for ( var j = 0; j < _this.source.overlays.length; j++ ) {
_this.currentOverlays[ i + j ] =
getOverlayObject( _this, _this.source.overlays[ j ] );
}
}
function getOverlayObject( viewer, overlay ) { function getOverlayObject( viewer, overlay ) {
if ( !$.isPlainObject( overlay ) ) { if ( overlay instanceof $.Overlay ) {
return overlay; return overlay;
} }
var element = null, var element = null;
rect = ( overlay.height && overlay.width ) ? new $.Rect( if ( overlay.element ) {
overlay.x || overlay.px, element = $.getElement( overlay.element );
overlay.y || overlay.py, } else {
overlay.width, var id = overlay.id ?
overlay.height
) : new $.Point(
overlay.x || overlay.px,
overlay.y || overlay.py
),
id = overlay.id ?
overlay.id : overlay.id :
"openseadragon-overlay-" + Math.floor( Math.random() * 10000000 ); "openseadragon-overlay-" + Math.floor( Math.random() * 10000000 );
element = $.getElement(overlay.id); element = $.getElement( overlay.id );
if ( !element ) { if ( !element ) {
element = document.createElement("a"); element = document.createElement( "a" );
element.href = "#/overlay/" + id; element.href = "#/overlay/" + id;
} }
element.id = id; element.id = id;
@ -1742,39 +1729,50 @@ function getOverlayObject( viewer, overlay ) {
overlay.className : overlay.className :
"openseadragon-overlay" "openseadragon-overlay"
); );
}
var location = overlay.location;
if ( !location ) {
var rect = ( overlay.height && overlay.width ) ? new $.Rect(
overlay.x || overlay.px,
overlay.y || overlay.py,
overlay.width,
overlay.height
) : new $.Point(
overlay.x || overlay.px,
overlay.y || overlay.py
);
if( overlay.px !== undefined ) { if( overlay.px !== undefined ) {
//if they specified 'px' so it's in pixel coordinates so //if they specified 'px' so it's in pixel coordinates so
//we need to translate to viewport coordinates //we need to translate to viewport coordinates
rect = viewer.viewport.imageToViewportRectangle( rect ); rect = viewer.viewport.imageToViewportRectangle( rect );
} }
location = overlay.placement ? viewer.viewport.pointFromPixel( rect ) :
if( overlay.placement ){ rect;
return new $.Overlay({
element: element,
location: viewer.viewport.pointFromPixel( rect ),
placement: $.OverlayPlacement[ overlay.placement.toUpperCase() ],
onDraw: overlay.onDraw
});
} else {
return new $.Overlay({
element: element,
location: rect,
onDraw: overlay.onDraw
});
} }
var placement = overlay.placement;
if ( placement && ( $.type( placement ) === "string" ) ) {
placement = $.OverlayPlacement[ overlay.placement.toUpperCase() ];
}
return new $.Overlay({
element: element,
location: location,
placement: placement,
onDraw: overlay.onDraw
});
} }
/** /**
* @private * @private
* @inner * @inner
* Determines the 'z-index' of the given overlay. Overlays are ordered in * Determines the index of the given overlay in the given overlays array.
* a z-index based on the order they are added to the Drawer.
*/ */
function getOverlayIndex( overlays, element ) { function getOverlayIndex( overlays, element ) {
var i; var i;
for ( i = overlays.length - 1; i >= 0; i-- ) { for ( i = overlays.length - 1; i >= 0; i-- ) {
if ( overlays[ i ].element == element ) { if ( overlays[ i ].element === element ) {
return i; return i;
} }
} }
@ -1782,7 +1780,7 @@ function getOverlayIndex( overlays, element ) {
return -1; return -1;
} }
function drawOverlays( viewport, overlays, container ){ function drawOverlays( viewport, overlays, container ) {
var i, var i,
length = overlays.length; length = overlays.length;
for ( i = 0; i < length; i++ ) { for ( i = 0; i < length; i++ ) {

View File

@ -71,8 +71,8 @@
function openHandler() { function openHandler() {
viewer.removeHandler( 'open', openHandler ); viewer.removeHandler( 'open', openHandler );
equal( viewer.overlays.length, 1, "Global overlay not added." ); equal( viewer.overlays.length, 1, "Global overlay should be added." );
equal( viewer.currentOverlays.length, 1, "Global overlay not opened." ); equal( viewer.currentOverlays.length, 1, "Global overlay should be open." );
viewer.addHandler( 'open', openPageHandler ); viewer.addHandler( 'open', openPageHandler );
viewer.goToPage( 1 ); viewer.goToPage( 1 );
@ -81,8 +81,8 @@
function openPageHandler() { function openPageHandler() {
viewer.removeHandler( 'open', openPageHandler ); viewer.removeHandler( 'open', openPageHandler );
equal( viewer.overlays.length, 1, "Global overlay removed after page switch." ); equal( viewer.overlays.length, 1, "Global overlay should stay after page switch." );
equal( viewer.currentOverlays.length, 1, "Global overlay not re-opened after page switch." ); equal( viewer.currentOverlays.length, 1, "Global overlay should re-open after page switch." );
viewer.addHandler( 'close', closeHandler ); viewer.addHandler( 'close', closeHandler );
viewer.close(); viewer.close();
@ -91,14 +91,14 @@
function closeHandler() { function closeHandler() {
viewer.removeHandler( 'close', closeHandler ); viewer.removeHandler( 'close', closeHandler );
equal( viewer.overlays.length, 1, "Global overlay removed on close." ); equal( viewer.overlays.length, 1, "Global overlay should not be removed on close." );
equal( viewer.currentOverlays.length, 0, "Global overlay not removed on close." ); equal( viewer.currentOverlays.length, 0, "Global overlay should be closed on close." );
start(); start();
} }
} ); } );
asyncTest( 'Overlays via addOverlay ', function() { asyncTest( 'Page Overlays via viewer options', function() {
viewer = OpenSeadragon( { viewer = OpenSeadragon( {
id: 'example-overlays', id: 'example-overlays',
@ -143,7 +143,7 @@
viewer.removeHandler( 'open', openHandler ); viewer.removeHandler( 'open', openHandler );
equal( viewer.overlays.length, 0, "No global overlay should be added." ); equal( viewer.overlays.length, 0, "No global overlay should be added." );
equal( viewer.currentOverlays.length, 1, "Tile overlay not opened." ); equal( viewer.currentOverlays.length, 1, "Page overlay should be open." );
viewer.addHandler( 'open', openPageHandler ); viewer.addHandler( 'open', openPageHandler );
viewer.goToPage( 1 ); viewer.goToPage( 1 );
@ -152,8 +152,8 @@
function openPageHandler() { function openPageHandler() {
viewer.removeHandler( 'open', openPageHandler ); viewer.removeHandler( 'open', openPageHandler );
equal( viewer.overlays.length, 0, "Global overlay added after page switch." ); equal( viewer.overlays.length, 0, "No global overlay should be added after page switch." );
equal( viewer.currentOverlays.length, 0, "Tile overlay re-opened after page switch." ); equal( viewer.currentOverlays.length, 0, "No page overlay should be opened after page switch." );
viewer.addHandler( 'close', closeHandler ); viewer.addHandler( 'close', closeHandler );
viewer.close(); viewer.close();
@ -162,8 +162,8 @@
function closeHandler() { function closeHandler() {
viewer.removeHandler( 'close', closeHandler ); viewer.removeHandler( 'close', closeHandler );
equal( viewer.overlays.length, 0, "Global overlay added on close." ); equal( viewer.overlays.length, 0, "No global overlay should be added on close." );
equal( viewer.currentOverlays.length, 0, "Tile overlay not removed on close." ); equal( viewer.currentOverlays.length, 0, "Page overlay should be closed on close." );
start(); start();
} }
@ -182,14 +182,14 @@
function openHandler() { function openHandler() {
viewer.removeHandler( 'open', openHandler ); viewer.removeHandler( 'open', openHandler );
equal( viewer.overlays.length, 0, "Global overlay added." ); equal( viewer.overlays.length, 0, "No global overlay should be added." );
equal( viewer.currentOverlays.length, 0, "Overlay opened." ); equal( viewer.currentOverlays.length, 0, "No overlay should be open." );
var rect = new OpenSeadragon.Rect( 0.1, 0.1, 0.1, 0.1 ); var rect = new OpenSeadragon.Rect( 0.1, 0.1, 0.1, 0.1 );
var overlay = $( "<div id=\"overlay\"></div>" ).get( 0 ); var overlay = $( "<div/>" ).prop("id", "overlay").get( 0 );
viewer.addOverlay( overlay, rect ); viewer.addOverlay( overlay, rect );
equal( viewer.overlays.length, 0, "Manual overlay added as global overlay." ); equal( viewer.overlays.length, 0, "No manual overlay should be added as global overlay." );
equal( viewer.currentOverlays.length, 1, "Manual overlay not opened." ); equal( viewer.currentOverlays.length, 1, "A manual overlay should be open." );
viewer.addHandler( 'open', openPageHandler ); viewer.addHandler( 'open', openPageHandler );
viewer.goToPage( 1 ); viewer.goToPage( 1 );
@ -198,8 +198,8 @@
function openPageHandler() { function openPageHandler() {
viewer.removeHandler( 'open', openPageHandler ); viewer.removeHandler( 'open', openPageHandler );
equal( viewer.overlays.length, 0, "Global overlay added after page switch." ); equal( viewer.overlays.length, 0, "No global overlay should be added after page switch." );
equal( viewer.currentOverlays.length, 0, "Manual overlay not removed after page switch." ); equal( viewer.currentOverlays.length, 0, "Manual overlay should be removed after page switch." );
viewer.addHandler( 'close', closeHandler ); viewer.addHandler( 'close', closeHandler );
viewer.close(); viewer.close();
@ -208,8 +208,8 @@
function closeHandler() { function closeHandler() {
viewer.removeHandler( 'close', closeHandler ); viewer.removeHandler( 'close', closeHandler );
equal( viewer.overlays.length, 0, "Global overlay added on close." ); equal( viewer.overlays.length, 0, "No global overlay should be added on close." );
equal( viewer.currentOverlays.length, 0, "Overlay not removed on close." ); equal( viewer.currentOverlays.length, 0, "Manual overlay should be removed on close." );
start(); start();
} }