diff --git a/Gruntfile.js b/Gruntfile.js index bd21d089..c3006fbd 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -13,6 +13,7 @@ module.exports = function(grunt) { minified = "build/openseadragon/openseadragon.min.js", sources = [ "src/openseadragon.js", + "src/fullscreen.js", "src/eventhandler.js", "src/mousetracker.js", "src/control.js", diff --git a/src/fullscreen.js b/src/fullscreen.js new file mode 100644 index 00000000..16c3a4d0 --- /dev/null +++ b/src/fullscreen.js @@ -0,0 +1,78 @@ +/** + * Determines the appropriate level of native full screen support we can get + * from the browser. + * Thanks to John Dyer for the implementation and research + * http://johndyer.name/native-fullscreen-javascript-api-plus-jquery-plugin/ + * Also includes older IE support based on + * http://stackoverflow.com/questions/1125084/how-to-make-in-javascript-full-screen-windows-stretching-all-over-the-screen/7525760 + * @name $.supportsFullScreen + */ +(function( $ ) { + var fullScreenApi = { + supportsFullScreen: false, + isFullScreen: function() { return false; }, + requestFullScreen: function() {}, + cancelFullScreen: function() {}, + fullScreenEventName: '', + prefix: '' + }, + browserPrefixes = 'webkit moz o ms khtml'.split(' '); + + // check for native support + if (typeof document.cancelFullScreen != 'undefined') { + fullScreenApi.supportsFullScreen = true; + } else { + // check for fullscreen support by vendor prefix + for (var i = 0, il = browserPrefixes.length; i < il; i++ ) { + fullScreenApi.prefix = browserPrefixes[i]; + + if (typeof document[fullScreenApi.prefix + 'CancelFullScreen' ] != 'undefined' ) { + fullScreenApi.supportsFullScreen = true; + + break; + } + } + } + + // update methods to do something useful + if (fullScreenApi.supportsFullScreen) { + fullScreenApi.fullScreenEventName = fullScreenApi.prefix + 'fullscreenchange'; + + fullScreenApi.isFullScreen = function() { + switch (this.prefix) { + case '': + return document.fullScreen; + case 'webkit': + return document.webkitIsFullScreen; + default: + return document[this.prefix + 'FullScreen']; + } + }; + fullScreenApi.requestFullScreen = function( element ) { + return (this.prefix === '') ? + element.requestFullScreen() : + element[this.prefix + 'RequestFullScreen'](); + + }; + fullScreenApi.cancelFullScreen = function( element ) { + return (this.prefix === '') ? + document.cancelFullScreen() : + document[this.prefix + 'CancelFullScreen'](); + }; + } else if ( typeof window.ActiveXObject !== "undefined" ){ + // Older IE. + fullScreenApi.requestFullScreen = function(){ + var wscript = new ActiveXObject("WScript.Shell"); + if ( wscript !== null ) { + wscript.SendKeys("{F11}"); + } + return false; + }; + fullScreenApi.cancelFullScreen = fullScreenApi.requestFullScreen; + } + + + // export api + $.extend( $, fullScreenApi ); + +})( OpenSeadragon ); \ No newline at end of file diff --git a/src/openseadragon.js b/src/openseadragon.js index c70d7a7b..0335e593 100644 --- a/src/openseadragon.js +++ b/src/openseadragon.js @@ -1655,6 +1655,7 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){ })(); + //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 diff --git a/src/viewer.js b/src/viewer.js index 2a6cf9dc..cc431d83 100644 --- a/src/viewer.js +++ b/src/viewer.js @@ -128,7 +128,8 @@ $.Viewer = function( options ) { "lastZoomTime": null, // did we decide this viewer has a sequence of tile sources "sequenced": false, - "sequence": 0 + "sequence": 0, + "onfullscreenchange": null }; //Inherit some behaviors and properties @@ -615,6 +616,7 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, $.ControlDock.prototype, docStyle = document.documentElement.style, containerStyle = this.element.style, canvasStyle = this.canvas.style, + _this = this, oldBounds, newBounds, viewer, @@ -627,6 +629,7 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, $.ControlDock.prototype, return; } + if ( fullPage ) { this.bodyOverflow = bodyStyle.overflow; @@ -674,28 +677,58 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, $.ControlDock.prototype, 'class', this.toolbar.element.className +" fullpage" ); - //this.toolbar.element.style.position = 'fixed'; - - //this.container.style.top = $.getElementSize( - // this.toolbar.element - //).y + 'px'; } + body.appendChild( this.element ); - if( this.toolbar && this.toolbar.element ){ - this.element.style.height = ( - $.getWindowSize().y - $.getElementSize( this.toolbar.element ).y - ) + 'px'; + + if( $.supportsFullScreen ){ + THIS[ this.hash ].onfullscreenchange = function( event ) { + // The event object doesn't carry information about the + // fullscreen state of the browser, but it is possible to + // retrieve it through the fullscreen API + if( $.isFullScreen() ){ + _this.setFullPage( true ); + } else { + _this.setFullPage( false ); + } + }; + + $.requestFullScreen( document.body ); + + // The target of the event is always the document, + // but it is possible to retrieve the fullscreen element through the API + // Note that the API is still vendor-prefixed in browsers implementing it + document.addEventListener( + $.fullScreenEventName, + THIS[ this.hash ].onfullscreenchange + ); + this.element.style.height = '100%'; + this.element.style.width = '100%'; }else{ this.element.style.height = $.getWindowSize().y + 'px'; + this.element.style.width = $.getWindowSize().x + 'px'; + } + + if( this.toolbar && this.toolbar.element ){ + this.element.style.height = ( + $.getElementSize( this.element ).y - $.getElementSize( this.toolbar.element ).y + ) + 'px'; } - this.element.style.width = $.getWindowSize().x + 'px'; // mouse will be inside container now - $.delegate( this, onContainerEnter )(); + $.delegate( this, onContainerEnter )(); } else { - + + if( $.supportsFullScreen ){ + document.removeEventListener( + $.fullScreenEventName, + THIS[ this.hash ].onfullscreenchange + ); + $.cancelFullScreen( document ); + } + bodyStyle.overflow = this.bodyOverflow; docStyle.overflow = this.docOverflow; @@ -744,7 +777,8 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, $.ControlDock.prototype, this.element.style.width = THIS[ this.hash ].prevElementSize.x + 'px'; // mouse will likely be outside now - $.delegate( this, onContainerExit )(); + $.delegate( this, onContainerExit )(); + } this.raiseEvent( 'fullpage', { fullpage: fullPage, viewer: this } );