Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Initial commit

  • Loading branch information...
commit 25f1876a799255b217c81229c8189e9f305869fe 0 parents
Brad Dougherty authored August 26, 2012
202  LICENSE
... ...
@@ -0,0 +1,202 @@
  1
+
  2
+                                 Apache License
  3
+                           Version 2.0, January 2004
  4
+                        http://www.apache.org/licenses/
  5
+
  6
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
  7
+
  8
+   1. Definitions.
  9
+
  10
+      "License" shall mean the terms and conditions for use, reproduction,
  11
+      and distribution as defined by Sections 1 through 9 of this document.
  12
+
  13
+      "Licensor" shall mean the copyright owner or entity authorized by
  14
+      the copyright owner that is granting the License.
  15
+
  16
+      "Legal Entity" shall mean the union of the acting entity and all
  17
+      other entities that control, are controlled by, or are under common
  18
+      control with that entity. For the purposes of this definition,
  19
+      "control" means (i) the power, direct or indirect, to cause the
  20
+      direction or management of such entity, whether by contract or
  21
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
  22
+      outstanding shares, or (iii) beneficial ownership of such entity.
  23
+
  24
+      "You" (or "Your") shall mean an individual or Legal Entity
  25
+      exercising permissions granted by this License.
  26
+
  27
+      "Source" form shall mean the preferred form for making modifications,
  28
+      including but not limited to software source code, documentation
  29
+      source, and configuration files.
  30
+
  31
+      "Object" form shall mean any form resulting from mechanical
  32
+      transformation or translation of a Source form, including but
  33
+      not limited to compiled object code, generated documentation,
  34
+      and conversions to other media types.
  35
+
  36
+      "Work" shall mean the work of authorship, whether in Source or
  37
+      Object form, made available under the License, as indicated by a
  38
+      copyright notice that is included in or attached to the work
  39
+      (an example is provided in the Appendix below).
  40
+
  41
+      "Derivative Works" shall mean any work, whether in Source or Object
  42
+      form, that is based on (or derived from) the Work and for which the
  43
+      editorial revisions, annotations, elaborations, or other modifications
  44
+      represent, as a whole, an original work of authorship. For the purposes
  45
+      of this License, Derivative Works shall not include works that remain
  46
+      separable from, or merely link (or bind by name) to the interfaces of,
  47
+      the Work and Derivative Works thereof.
  48
+
  49
+      "Contribution" shall mean any work of authorship, including
  50
+      the original version of the Work and any modifications or additions
  51
+      to that Work or Derivative Works thereof, that is intentionally
  52
+      submitted to Licensor for inclusion in the Work by the copyright owner
  53
+      or by an individual or Legal Entity authorized to submit on behalf of
  54
+      the copyright owner. For the purposes of this definition, "submitted"
  55
+      means any form of electronic, verbal, or written communication sent
  56
+      to the Licensor or its representatives, including but not limited to
  57
+      communication on electronic mailing lists, source code control systems,
  58
+      and issue tracking systems that are managed by, or on behalf of, the
  59
+      Licensor for the purpose of discussing and improving the Work, but
  60
+      excluding communication that is conspicuously marked or otherwise
  61
+      designated in writing by the copyright owner as "Not a Contribution."
  62
+
  63
+      "Contributor" shall mean Licensor and any individual or Legal Entity
  64
+      on behalf of whom a Contribution has been received by Licensor and
  65
+      subsequently incorporated within the Work.
  66
+
  67
+   2. Grant of Copyright License. Subject to the terms and conditions of
  68
+      this License, each Contributor hereby grants to You a perpetual,
  69
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
  70
+      copyright license to reproduce, prepare Derivative Works of,
  71
+      publicly display, publicly perform, sublicense, and distribute the
  72
+      Work and such Derivative Works in Source or Object form.
  73
+
  74
+   3. Grant of Patent License. Subject to the terms and conditions of
  75
+      this License, each Contributor hereby grants to You a perpetual,
  76
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
  77
+      (except as stated in this section) patent license to make, have made,
  78
+      use, offer to sell, sell, import, and otherwise transfer the Work,
  79
+      where such license applies only to those patent claims licensable
  80
+      by such Contributor that are necessarily infringed by their
  81
+      Contribution(s) alone or by combination of their Contribution(s)
  82
+      with the Work to which such Contribution(s) was submitted. If You
  83
+      institute patent litigation against any entity (including a
  84
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
  85
+      or a Contribution incorporated within the Work constitutes direct
  86
+      or contributory patent infringement, then any patent licenses
  87
+      granted to You under this License for that Work shall terminate
  88
+      as of the date such litigation is filed.
  89
+
  90
+   4. Redistribution. You may reproduce and distribute copies of the
  91
+      Work or Derivative Works thereof in any medium, with or without
  92
+      modifications, and in Source or Object form, provided that You
  93
+      meet the following conditions:
  94
+
  95
+      (a) You must give any other recipients of the Work or
  96
+          Derivative Works a copy of this License; and
  97
+
  98
+      (b) You must cause any modified files to carry prominent notices
  99
+          stating that You changed the files; and
  100
+
  101
+      (c) You must retain, in the Source form of any Derivative Works
  102
+          that You distribute, all copyright, patent, trademark, and
  103
+          attribution notices from the Source form of the Work,
  104
+          excluding those notices that do not pertain to any part of
  105
+          the Derivative Works; and
  106
+
  107
+      (d) If the Work includes a "NOTICE" text file as part of its
  108
+          distribution, then any Derivative Works that You distribute must
  109
+          include a readable copy of the attribution notices contained
  110
+          within such NOTICE file, excluding those notices that do not
  111
+          pertain to any part of the Derivative Works, in at least one
  112
+          of the following places: within a NOTICE text file distributed
  113
+          as part of the Derivative Works; within the Source form or
  114
+          documentation, if provided along with the Derivative Works; or,
  115
+          within a display generated by the Derivative Works, if and
  116
+          wherever such third-party notices normally appear. The contents
  117
+          of the NOTICE file are for informational purposes only and
  118
+          do not modify the License. You may add Your own attribution
  119
+          notices within Derivative Works that You distribute, alongside
  120
+          or as an addendum to the NOTICE text from the Work, provided
  121
+          that such additional attribution notices cannot be construed
  122
+          as modifying the License.
  123
+
  124
+      You may add Your own copyright statement to Your modifications and
  125
+      may provide additional or different license terms and conditions
  126
+      for use, reproduction, or distribution of Your modifications, or
  127
+      for any such Derivative Works as a whole, provided Your use,
  128
+      reproduction, and distribution of the Work otherwise complies with
  129
+      the conditions stated in this License.
  130
+
  131
+   5. Submission of Contributions. Unless You explicitly state otherwise,
  132
+      any Contribution intentionally submitted for inclusion in the Work
  133
+      by You to the Licensor shall be under the terms and conditions of
  134
+      this License, without any additional terms or conditions.
  135
+      Notwithstanding the above, nothing herein shall supersede or modify
  136
+      the terms of any separate license agreement you may have executed
  137
+      with Licensor regarding such Contributions.
  138
+
  139
+   6. Trademarks. This License does not grant permission to use the trade
  140
+      names, trademarks, service marks, or product names of the Licensor,
  141
+      except as required for reasonable and customary use in describing the
  142
+      origin of the Work and reproducing the content of the NOTICE file.
  143
+
  144
+   7. Disclaimer of Warranty. Unless required by applicable law or
  145
+      agreed to in writing, Licensor provides the Work (and each
  146
+      Contributor provides its Contributions) on an "AS IS" BASIS,
  147
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
  148
+      implied, including, without limitation, any warranties or conditions
  149
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
  150
+      PARTICULAR PURPOSE. You are solely responsible for determining the
  151
+      appropriateness of using or redistributing the Work and assume any
  152
+      risks associated with Your exercise of permissions under this License.
  153
+
  154
+   8. Limitation of Liability. In no event and under no legal theory,
  155
+      whether in tort (including negligence), contract, or otherwise,
  156
+      unless required by applicable law (such as deliberate and grossly
  157
+      negligent acts) or agreed to in writing, shall any Contributor be
  158
+      liable to You for damages, including any direct, indirect, special,
  159
+      incidental, or consequential damages of any character arising as a
  160
+      result of this License or out of the use or inability to use the
  161
+      Work (including but not limited to damages for loss of goodwill,
  162
+      work stoppage, computer failure or malfunction, or any and all
  163
+      other commercial damages or losses), even if such Contributor
  164
+      has been advised of the possibility of such damages.
  165
+
  166
+   9. Accepting Warranty or Additional Liability. While redistributing
  167
+      the Work or Derivative Works thereof, You may choose to offer,
  168
+      and charge a fee for, acceptance of support, warranty, indemnity,
  169
+      or other liability obligations and/or rights consistent with this
  170
+      License. However, in accepting such obligations, You may act only
  171
+      on Your own behalf and on Your sole responsibility, not on behalf
  172
+      of any other Contributor, and only if You agree to indemnify,
  173
+      defend, and hold each Contributor harmless for any liability
  174
+      incurred by, or claims asserted against, such Contributor by reason
  175
+      of your accepting any such warranty or additional liability.
  176
+
  177
+   END OF TERMS AND CONDITIONS
  178
+
  179
+   APPENDIX: How to apply the Apache License to your work.
  180
+
  181
+      To apply the Apache License to your work, attach the following
  182
+      boilerplate notice, with the fields enclosed by brackets "[]"
  183
+      replaced with your own identifying information. (Don't include
  184
+      the brackets!)  The text should be enclosed in the appropriate
  185
+      comment syntax for the file format. We also recommend that a
  186
+      file or class name and description of purpose be included on the
  187
+      same "printed page" as the copyright notice for easier
  188
+      identification within third-party archives.
  189
+
  190
+   Copyright [yyyy] [name of copyright owner]
  191
+
  192
+   Licensed under the Apache License, Version 2.0 (the "License");
  193
+   you may not use this file except in compliance with the License.
  194
+   You may obtain a copy of the License at
  195
+
  196
+       http://www.apache.org/licenses/LICENSE-2.0
  197
+
  198
+   Unless required by applicable law or agreed to in writing, software
  199
+   distributed under the License is distributed on an "AS IS" BASIS,
  200
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  201
+   See the License for the specific language governing permissions and
  202
+   limitations under the License.
157  README.md
Source Rendered
... ...
@@ -0,0 +1,157 @@
  1
+# BigScreen
  2
+
  3
+A simple library for using the JavaScript Full Screen API.
  4
+
  5
+
  6
+## Why should I use it?
  7
+
  8
+### Before BigScreen
  9
+
  10
+```js
  11
+if (element.requestFullscreen) {
  12
+    element.requestFullscreen();
  13
+}
  14
+else if (element.webkitRequestFullscreen) {
  15
+    element.webkitRequestFullscreen();
  16
+}
  17
+else if (element.webkitRequestFullScreen) {
  18
+    element.webkitRequestFullScreen();
  19
+}
  20
+else if (element.mozRequestFullScreen) {
  21
+    element.mozRequestFullScreen();
  22
+}
  23
+```
  24
+
  25
+## After BigScreen
  26
+
  27
+```js
  28
+BigScreen.request(element);
  29
+```
  30
+
  31
+BigScreen also smoothes out a couple browser bugs for you (the real before code is a little more complicated).
  32
+
  33
+
  34
+## Download
  35
+
  36
+BigScreen is ~1 kb minified and gzipped. [Download it now](https://raw.github.com/bdougherty/BigScreen/master/dist/bigscreen.min.js).
  37
+
  38
+
  39
+## Supported Browsers
  40
+
  41
+* Chrome 15+
  42
+* Firefox 10+
  43
+* Safari 5.1+
  44
+
  45
+These browsers are also supported for video only:
  46
+
  47
+* Safari 5.0
  48
+
  49
+
  50
+## How do I use it?
  51
+
  52
+### Put the entire page in full screen
  53
+
  54
+```js
  55
+document.getElementById('button').addEventListener('click', function() {
  56
+	if (BigScreen.enabled) {
  57
+		BigScreen.toggle();
  58
+	}
  59
+	else {
  60
+		// fallback
  61
+	}
  62
+}, false);
  63
+```
  64
+
  65
+### Put any element in full screen
  66
+
  67
+```js
  68
+var element = document.getElementById('target');
  69
+
  70
+document.getElementById('button').addEventListener('click', function() {
  71
+	if (BigScreen.enabled) {
  72
+		BigScreen.request(element);
  73
+		// You could also use .toggle(element)
  74
+	}
  75
+	else {
  76
+		// fallback for browsers that don't support full screen
  77
+	}
  78
+}, false);
  79
+```
  80
+
  81
+### Detecting full screen changes
  82
+
  83
+```js
  84
+BigScreen.onenter = function() {
  85
+	// called when entering full screen
  86
+}
  87
+
  88
+BigScreen.onexit = function() {
  89
+	// called when exiting full screen
  90
+}
  91
+```
  92
+
  93
+
  94
+## [Demo](http://brad.is/coding/BigScreen/)
  95
+
  96
+
  97
+## Documentation
  98
+
  99
+### BigScreen.request(element)
  100
+
  101
+Request that an element go into full screen. If the element is `null` or `undefined`, the `documentElement` will be used instead.
  102
+
  103
+You can only call this from a user-initiated event, otherwise the browser will deny the request. That means click, key, or touch events.
  104
+
  105
+In addition, if your page is inside an `<iframe>` it will need to have the `allowfullscreen` (and `webkitallowfullscreen` and `mozallowfullscreen`) attribute set on the `<iframe>`.
  106
+
  107
+Finally, BigScreen will try to fall back to full screen for `<video>` if there is a child `<video>` in the element you pass and the browser supports it (see `BigScreen.videoEnabled)`). If BigScreen falls back, it will automatically load and play the video.
  108
+
  109
+### BigScreen.exit()
  110
+
  111
+Will exit full screen. Note that if there are multiple elements in full screen, only the last one will exit full screen.
  112
+
  113
+### BigScreen.toggle(element)
  114
+
  115
+Will request full screen if there is no element in full screen, otherwise it will exit full screen.
  116
+
  117
+### BigScreen.onenter()
  118
+
  119
+Override to get notified when an element enters full screen. `BigScreen.element` will be set to the element that is entering full screen.
  120
+
  121
+### BigScreen.onexit()
  122
+
  123
+Override to get notified when fully exiting full screen (there are no more elements in full screen).
  124
+
  125
+### BigScreen.element
  126
+
  127
+Set to the element that is currently displaying full screen, or `null` if no element is in full screen.
  128
+
  129
+### BigScreen.enabled
  130
+
  131
+A boolean that will tell you if it is possible to go into full screen. If your page is in an `<iframe>` it will need to have the `allowfullscreen` attribute set or this will be `false`.
  132
+
  133
+### BigScreen.videoEnabled(video)
  134
+
  135
+Safari 5.0 and iOS 4.2+ support putting `<video>` into full screen. `BigScreen.enabled` will report `false` in those browsers, but you can use this to check for `<video> `full screen support by passing the `<video>` itself, or an ancestor.
  136
+
  137
+This function will report `false` if there is no child `<video>`, or if it is not possible to put a `<video>` in full screen. It will report `'maybe'` if the video's metadata has not been loaded, and `true` if it will be able to enter full screen.
  138
+
  139
+
  140
+## Known Issues
  141
+
  142
+There is currently a bug in WebKit that causes the `webkitfullscreenchange` event to fire incorrectly when inside an `iframe`. BigScreen is able to work around the issue though. ([Chrome Bug](http://code.google.com/p/chromium/issues/detail?id=138368), Safari Bug: rdar://problem/11927884)
  143
+
  144
+Safari 6.0 does not work properly when putting multiple elements into full screen. [Open Radar bug report](http://openradar.appspot.com/radar?id=1878403).
  145
+
  146
+
  147
+## Links
  148
+
  149
+* [Using the Fullscreen API in web browsers](http://hacks.mozilla.org/2012/01/using-the-fullscreen-api-in-web-browsers/)
  150
+* [Using HTML5's Fullscreen API for Fun and Profit](http://sorcery.smugmug.com/2012/06/06/using-html5s-fullscreen-api-for-fun-and-profit/)
  151
+* [Using full-screen mode - MDN](https://developer.mozilla.org/en/DOM/Using_full-screen_mode)
  152
+* [Fullscreen Specification - W3C](http://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html)
  153
+
  154
+
  155
+## License
  156
+
  157
+BigScreen is licensed under the [Apache 2.0](http://www.apache.org/licenses/LICENSE-2.0) license. Copyright 2012 Brad Dougherty.
320  bigscreen.js
... ...
@@ -0,0 +1,320 @@
  1
+/*global self Element */
  2
+(function(window, document, iframe) {
  3
+	'use strict';
  4
+
  5
+	var keyboardAllowed = typeof Element !== 'undefined' && 'ALLOW_KEYBOARD_INPUT' in Element;
  6
+
  7
+	var fn = (function() {
  8
+		var map = [
  9
+			// spec
  10
+			{
  11
+				request: 'requestFullscreen',
  12
+				exit: 'exitFullscreen',
  13
+				enabled: 'fullscreenEnabled',
  14
+				element: 'fullscreenElement',
  15
+				change: 'fullscreenchange',
  16
+				error: 'fullscreenerror'
  17
+			},
  18
+			// new WebKit
  19
+			{
  20
+				request: 'webkitRequestFullscreen',
  21
+				exit: 'webkitExitFullscreen',
  22
+				enabled: 'webkitFullscreenEnabled',
  23
+				element: 'webkitFullscreenElement',
  24
+				change: 'webkitfullscreenchange',
  25
+				error: 'webkitfullscreenerror'
  26
+			},
  27
+			// older WebKit (Safari 5.1)
  28
+			{
  29
+				request: 'webkitRequestFullScreen',
  30
+				exit: 'webkitCancelFullScreen',
  31
+				element: 'webkitCurrentFullScreenElement',
  32
+				change: 'webkitfullscreenchange',
  33
+				error: 'webkitfullscreenerror'
  34
+			},
  35
+			// Firefox 10+
  36
+			{
  37
+				request: 'mozRequestFullScreen',
  38
+				exit: 'mozCancelFullScreen',
  39
+				enabled: 'mozFullScreenEnabled',
  40
+				element: 'mozFullScreenElement',
  41
+				change: 'mozfullscreenchange',
  42
+				error: 'mozfullscreenerror'
  43
+			}
  44
+		];
  45
+
  46
+		var fullscreen = false;
  47
+		var testElement = document.createElement('video');
  48
+
  49
+		// Loop through each one and check to see if the request function exists
  50
+		for (var i = 0; i < map.length; i++) {
  51
+			if (map[i].request in testElement) {
  52
+				fullscreen = map[i];
  53
+
  54
+				// Double-check that all functions/events exist and if not, delete them
  55
+				for (var item in fullscreen) {
  56
+					if (!('on' + fullscreen[item] in document) && !(fullscreen[item] in document) && !(fullscreen[item] in testElement)) {
  57
+						delete fullscreen[item];
  58
+					}
  59
+				}
  60
+
  61
+				break;
  62
+			}
  63
+		}
  64
+
  65
+		testElement = null;
  66
+
  67
+		return fullscreen;
  68
+	}());
  69
+
  70
+	// From Underscore.js 1.3.3
  71
+	// http://underscorejs.org
  72
+	function debounce(func, wait, immediate) {
  73
+		var timeout;
  74
+		return function() {
  75
+			var context = this, args = arguments;
  76
+			var later = function() {
  77
+				timeout = null;
  78
+				if (!immediate) {
  79
+					func.apply(context, args);
  80
+				}
  81
+			};
  82
+			var callNow = immediate && !timeout;
  83
+			clearTimeout(timeout);
  84
+			timeout = setTimeout(later, wait);
  85
+			if (callNow) {
  86
+				func.apply(context, args);
  87
+			}
  88
+		};
  89
+	}
  90
+
  91
+	// Find a child <video> in the element passed.
  92
+	function getVideo(element) {
  93
+		var videoElement = null;
  94
+
  95
+		if (element.tagName === 'VIDEO') {
  96
+			videoElement = element;
  97
+		}
  98
+		else {
  99
+			var videos = element.getElementsByTagName('video');
  100
+			if (videos[0]) {
  101
+				videoElement = videos[0];
  102
+			}
  103
+		}
  104
+
  105
+		return videoElement;
  106
+	}
  107
+
  108
+	var lastFullscreenVideo = null;
  109
+
  110
+	// Check to see if there is a <video> and if the video has webkitEnterFullscreen, try it.
  111
+	// Metadata needs to be loaded for it to work, so load() if we need to.
  112
+	function videoEnterFullscreen(element) {
  113
+		var videoElement = getVideo(element);
  114
+
  115
+		if (videoElement && videoElement.webkitEnterFullscreen) {
  116
+			try {
  117
+				if (videoElement.readyState < videoElement.HAVE_METADATA) {
  118
+					videoElement.addEventListener('loadedmetadata', function onMetadataLoaded() {
  119
+						videoElement.removeEventListener('loadedmetadata', onMetadataLoaded, false);
  120
+						videoElement.webkitEnterFullscreen();
  121
+					}, false);
  122
+					videoElement.load();
  123
+				}
  124
+				else {
  125
+					videoElement.webkitEnterFullscreen();
  126
+				}
  127
+
  128
+				lastFullscreenVideo = videoElement;
  129
+				videoElement.play();
  130
+				callOnEnter();
  131
+				setTimeout(checkDisplayingFullscreen, 500);
  132
+			}
  133
+			catch (err) {
  134
+				bigscreen.onerror.call(videoElement);
  135
+			}
  136
+
  137
+			return;
  138
+		}
  139
+
  140
+		bigscreen.onerror.call(element);
  141
+	}
  142
+
  143
+	// Poll for changes to webkitDisplayingFullscreen so that we can fire BigScreen.exit()
  144
+	// if a <video> comes out of full screen when using the webkitEnterFullscreen fallback.
  145
+	function checkDisplayingFullscreen() {
  146
+		if (lastFullscreenVideo) {
  147
+			if (lastFullscreenVideo.webkitDisplayingFullscreen === true) {
  148
+				return setTimeout(checkDisplayingFullscreen, 500);
  149
+			}
  150
+
  151
+			callOnExit();
  152
+		}
  153
+	}
  154
+
  155
+	// There is a bug in WebKit that will not fire a fullscreenchange event when the element exiting
  156
+	// is an iframe. This will listen for a window resize and fire exit if there is no current element.
  157
+	// Chrome bug: http://code.google.com/p/chromium/issues/detail?id=138368
  158
+	// Safari bug: rdar://11927884
  159
+	function resizeExitHack() {
  160
+		if (!bigscreen.element) {
  161
+			callOnExit();
  162
+			removeWindowResizeHack();
  163
+		}
  164
+	}
  165
+
  166
+	function addWindowResizeHack() {
  167
+		if (iframe && fn.change === 'webkitfullscreenchange') {
  168
+			window.addEventListener('resize', resizeExitHack, false);
  169
+		}
  170
+	}
  171
+
  172
+	function removeWindowResizeHack() {
  173
+		if (iframe && fn.change === 'webkitfullscreenchange') {
  174
+			window.removeEventListener('resize', resizeExitHack, false);
  175
+		}
  176
+	}
  177
+
  178
+	var callOnEnter = debounce(function() {
  179
+		bigscreen.onenter.call(bigscreen);
  180
+	}, 100, true);
  181
+
  182
+	var callOnExit = debounce(function() {
  183
+		bigscreen.onexit.call(bigscreen);
  184
+	}, 200, true);
  185
+
  186
+	var bigscreen = {
  187
+		request: function(element) {
  188
+			element = element || document.documentElement;
  189
+
  190
+			// iOS only supports webkitEnterFullscreen on videos.
  191
+			if (fn.request === undefined) {
  192
+				return videoEnterFullscreen(element);
  193
+			}
  194
+
  195
+			// document.fullscreenEnabled is false, so try a video if there is one.
  196
+			if (iframe && document[fn.enabled] === false) {
  197
+				return videoEnterFullscreen(element);
  198
+			}
  199
+
  200
+			// If we're in an iframe, it needs to have the allowfullscreen attribute in order for element full screen
  201
+			// to work. Safari 5.1 supports element full screen, but doesn't have document.webkitFullScreenEnabled,
  202
+			// so the only way to tell if it will work is to just try it.
  203
+			if (iframe && fn.enabled === undefined) {
  204
+				fn.enabled = 'webkitFullscreenEnabled';
  205
+
  206
+				element[fn.request]();
  207
+
  208
+				setTimeout(function() {
  209
+					if (!document[fn.element]) {
  210
+						document[fn.enabled] = false;
  211
+						videoEnterFullscreen(element);
  212
+					}
  213
+					else {
  214
+						document[fn.enabled] = true;
  215
+					}
  216
+				}, 250);
  217
+
  218
+				return;
  219
+			}
  220
+
  221
+			try {
  222
+				element[fn.request](keyboardAllowed && Element.ALLOW_KEYBOARD_INPUT);
  223
+
  224
+				// Safari 5.1 incorrectly states that it allows keyboard input when it doesn't
  225
+				if (!document[fn.element]) {
  226
+					element[fn.request]();
  227
+				}
  228
+			}
  229
+			catch (err) {
  230
+				bigscreen.onerror.call(element);
  231
+			}
  232
+		},
  233
+		exit: function() {
  234
+			removeWindowResizeHack(); // remove here if exit is called manually, so two onexit events are not fired
  235
+			document[fn.exit]();
  236
+			lastFullscreenVideo = null;
  237
+		},
  238
+		toggle: function(element) {
  239
+			if (bigscreen.element) {
  240
+				bigscreen.exit();
  241
+			}
  242
+			else {
  243
+				bigscreen.request(element);
  244
+			}
  245
+		},
  246
+
  247
+		// Mobile Safari and earlier versions of desktop Safari support sending a <video> into full screen.
  248
+		// Checks can't be performed to verify full screen capabilities unless we know about that element,
  249
+		// and it has loaded its metadata.
  250
+		videoEnabled: function(element) {
  251
+			if (bigscreen.enabled) {
  252
+				return true;
  253
+			}
  254
+
  255
+			var video = getVideo(element);
  256
+
  257
+			if (!video || video.webkitSupportsFullscreen === undefined) {
  258
+				return false;
  259
+			}
  260
+
  261
+			return video.readyState < video.HAVE_METADATA ? 'maybe' : video.webkitSupportsFullscreen;
  262
+		},
  263
+
  264
+		onenter: function() {},
  265
+		onexit: function() {},
  266
+		onerror: function() {}
  267
+	};
  268
+
  269
+	try {
  270
+		Object.defineProperties(bigscreen, {
  271
+			'element': {
  272
+				enumerable: true,
  273
+				get: function() {
  274
+					if (lastFullscreenVideo && lastFullscreenVideo.webkitDisplayingFullscreen) {
  275
+						return lastFullscreenVideo;
  276
+					}
  277
+
  278
+					return document[fn.element] || null;
  279
+				}
  280
+			},
  281
+			'enabled': {
  282
+				enumerable: true,
  283
+				get: function() {
  284
+					// Safari 5.1 supports full screen, but doesn't have a fullScreenEnabled property,
  285
+					// but it should work if not in an iframe.
  286
+					if (fn.exit === 'webkitCancelFullScreen' && !iframe) {
  287
+						return true;
  288
+					}
  289
+
  290
+					return document[fn.enabled] || false;
  291
+				}
  292
+			}
  293
+		});
  294
+	}
  295
+	catch (err) {
  296
+		bigscreen.element = null;
  297
+		bigscreen.enabled = false;
  298
+	}
  299
+
  300
+	if (fn.change) {
  301
+		document.addEventListener(fn.change, function(event) {
  302
+			if (bigscreen.element) {
  303
+				callOnEnter();
  304
+				addWindowResizeHack();
  305
+			}
  306
+			else {
  307
+				callOnExit();
  308
+			}
  309
+		}, false);
  310
+	}
  311
+
  312
+	if (fn.error) {
  313
+		document.addEventListener(fn.error, function(event) {
  314
+			bigscreen.onerror.call(event.target);
  315
+		}, false);
  316
+	}
  317
+
  318
+	window.BigScreen = bigscreen;
  319
+
  320
+}(window, document, self !== top));
327  dist/bigscreen.js
... ...
@@ -0,0 +1,327 @@
  1
+/*!
  2
+* BigScreen
  3
+* v1.0.0 - 2012-08-26
  4
+* https://github.com/bdougherty/BigScreen
  5
+* Copyright 2012 Brad Dougherty; Apache 2.0 License
  6
+*/
  7
+
  8
+/*global self Element */
  9
+(function(window, document, iframe) {
  10
+	'use strict';
  11
+
  12
+	var keyboardAllowed = typeof Element !== 'undefined' && 'ALLOW_KEYBOARD_INPUT' in Element;
  13
+
  14
+	var fn = (function() {
  15
+		var map = [
  16
+			// spec
  17
+			{
  18
+				request: 'requestFullscreen',
  19
+				exit: 'exitFullscreen',
  20
+				enabled: 'fullscreenEnabled',
  21
+				element: 'fullscreenElement',
  22
+				change: 'fullscreenchange',
  23
+				error: 'fullscreenerror'
  24
+			},
  25
+			// new WebKit
  26
+			{
  27
+				request: 'webkitRequestFullscreen',
  28
+				exit: 'webkitExitFullscreen',
  29
+				enabled: 'webkitFullscreenEnabled',
  30
+				element: 'webkitFullscreenElement',
  31
+				change: 'webkitfullscreenchange',
  32
+				error: 'webkitfullscreenerror'
  33
+			},
  34
+			// older WebKit (Safari 5.1)
  35
+			{
  36
+				request: 'webkitRequestFullScreen',
  37
+				exit: 'webkitCancelFullScreen',
  38
+				element: 'webkitCurrentFullScreenElement',
  39
+				change: 'webkitfullscreenchange',
  40
+				error: 'webkitfullscreenerror'
  41
+			},
  42
+			// Firefox 10+
  43
+			{
  44
+				request: 'mozRequestFullScreen',
  45
+				exit: 'mozCancelFullScreen',
  46
+				enabled: 'mozFullScreenEnabled',
  47
+				element: 'mozFullScreenElement',
  48
+				change: 'mozfullscreenchange',
  49
+				error: 'mozfullscreenerror'
  50
+			}
  51
+		];
  52
+
  53
+		var fullscreen = false;
  54
+		var testElement = document.createElement('video');
  55
+
  56
+		// Loop through each one and check to see if the request function exists
  57
+		for (var i = 0; i < map.length; i++) {
  58
+			if (map[i].request in testElement) {
  59
+				fullscreen = map[i];
  60
+
  61
+				// Double-check that all functions/events exist and if not, delete them
  62
+				for (var item in fullscreen) {
  63
+					if (!('on' + fullscreen[item] in document) && !(fullscreen[item] in document) && !(fullscreen[item] in testElement)) {
  64
+						delete fullscreen[item];
  65
+					}
  66
+				}
  67
+
  68
+				break;
  69
+			}
  70
+		}
  71
+
  72
+		testElement = null;
  73
+
  74
+		return fullscreen;
  75
+	}());
  76
+
  77
+	// From Underscore.js 1.3.3
  78
+	// http://underscorejs.org
  79
+	function debounce(func, wait, immediate) {
  80
+		var timeout;
  81
+		return function() {
  82
+			var context = this, args = arguments;
  83
+			var later = function() {
  84
+				timeout = null;
  85
+				if (!immediate) {
  86
+					func.apply(context, args);
  87
+				}
  88
+			};
  89
+			var callNow = immediate && !timeout;
  90
+			clearTimeout(timeout);
  91
+			timeout = setTimeout(later, wait);
  92
+			if (callNow) {
  93
+				func.apply(context, args);
  94
+			}
  95
+		};
  96
+	}
  97
+
  98
+	// Find a child <video> in the element passed.
  99
+	function getVideo(element) {
  100
+		var videoElement = null;
  101
+
  102
+		if (element.tagName === 'VIDEO') {
  103
+			videoElement = element;
  104
+		}
  105
+		else {
  106
+			var videos = element.getElementsByTagName('video');
  107
+			if (videos[0]) {
  108
+				videoElement = videos[0];
  109
+			}
  110
+		}
  111
+
  112
+		return videoElement;
  113
+	}
  114
+
  115
+	var lastFullscreenVideo = null;
  116
+
  117
+	// Check to see if there is a <video> and if the video has webkitEnterFullscreen, try it.
  118
+	// Metadata needs to be loaded for it to work, so load() if we need to.
  119
+	function videoEnterFullscreen(element) {
  120
+		var videoElement = getVideo(element);
  121
+
  122
+		if (videoElement && videoElement.webkitEnterFullscreen) {
  123
+			try {
  124
+				if (videoElement.readyState < videoElement.HAVE_METADATA) {
  125
+					videoElement.addEventListener('loadedmetadata', function onMetadataLoaded() {
  126
+						videoElement.removeEventListener('loadedmetadata', onMetadataLoaded, false);
  127
+						videoElement.webkitEnterFullscreen();
  128
+					}, false);
  129
+					videoElement.load();
  130
+				}
  131
+				else {
  132
+					videoElement.webkitEnterFullscreen();
  133
+				}
  134
+
  135
+				lastFullscreenVideo = videoElement;
  136
+				videoElement.play();
  137
+				callOnEnter();
  138
+				setTimeout(checkDisplayingFullscreen, 500);
  139
+			}
  140
+			catch (err) {
  141
+				bigscreen.onerror.call(videoElement);
  142
+			}
  143
+
  144
+			return;
  145
+		}
  146
+
  147
+		bigscreen.onerror.call(element);
  148
+	}
  149
+
  150
+	// Poll for changes to webkitDisplayingFullscreen so that we can fire BigScreen.exit()
  151
+	// if a <video> comes out of full screen when using the webkitEnterFullscreen fallback.
  152
+	function checkDisplayingFullscreen() {
  153
+		if (lastFullscreenVideo) {
  154
+			if (lastFullscreenVideo.webkitDisplayingFullscreen === true) {
  155
+				return setTimeout(checkDisplayingFullscreen, 500);
  156
+			}
  157
+
  158
+			callOnExit();
  159
+		}
  160
+	}
  161
+
  162
+	// There is a bug in WebKit that will not fire a fullscreenchange event when the element exiting
  163
+	// is an iframe. This will listen for a window resize and fire exit if there is no current element.
  164
+	// Chrome bug: http://code.google.com/p/chromium/issues/detail?id=138368
  165
+	// Safari bug: rdar://11927884
  166
+	function resizeExitHack() {
  167
+		if (!bigscreen.element) {
  168
+			callOnExit();
  169
+			removeWindowResizeHack();
  170
+		}
  171
+	}
  172
+
  173
+	function addWindowResizeHack() {
  174
+		if (iframe && fn.change === 'webkitfullscreenchange') {
  175
+			window.addEventListener('resize', resizeExitHack, false);
  176
+		}
  177
+	}
  178
+
  179
+	function removeWindowResizeHack() {
  180
+		if (iframe && fn.change === 'webkitfullscreenchange') {
  181
+			window.removeEventListener('resize', resizeExitHack, false);
  182
+		}
  183
+	}
  184
+
  185
+	var callOnEnter = debounce(function() {
  186
+		bigscreen.onenter.call(bigscreen);
  187
+	}, 100, true);
  188
+
  189
+	var callOnExit = debounce(function() {
  190
+		bigscreen.onexit.call(bigscreen);
  191
+	}, 200, true);
  192
+
  193
+	var bigscreen = {
  194
+		request: function(element) {
  195
+			element = element || document.documentElement;
  196
+
  197
+			// iOS only supports webkitEnterFullscreen on videos.
  198
+			if (fn.request === undefined) {
  199
+				return videoEnterFullscreen(element);
  200
+			}
  201
+
  202
+			// document.fullscreenEnabled is false, so try a video if there is one.
  203
+			if (iframe && document[fn.enabled] === false) {
  204
+				return videoEnterFullscreen(element);
  205
+			}
  206
+
  207
+			// If we're in an iframe, it needs to have the allowfullscreen attribute in order for element full screen
  208
+			// to work. Safari 5.1 supports element full screen, but doesn't have document.webkitFullScreenEnabled,
  209
+			// so the only way to tell if it will work is to just try it.
  210
+			if (iframe && fn.enabled === undefined) {
  211
+				fn.enabled = 'webkitFullscreenEnabled';
  212
+
  213
+				element[fn.request]();
  214
+
  215
+				setTimeout(function() {
  216
+					if (!document[fn.element]) {
  217
+						document[fn.enabled] = false;
  218
+						videoEnterFullscreen(element);
  219
+					}
  220
+					else {
  221
+						document[fn.enabled] = true;
  222
+					}
  223
+				}, 250);
  224
+
  225
+				return;
  226
+			}
  227
+
  228
+			try {
  229
+				element[fn.request](keyboardAllowed && Element.ALLOW_KEYBOARD_INPUT);
  230
+
  231
+				// Safari 5.1 incorrectly states that it allows keyboard input when it doesn't
  232
+				if (!document[fn.element]) {
  233
+					element[fn.request]();
  234
+				}
  235
+			}
  236
+			catch (err) {
  237
+				bigscreen.onerror.call(element);
  238
+			}
  239
+		},
  240
+		exit: function() {
  241
+			removeWindowResizeHack(); // remove here if exit is called manually, so two onexit events are not fired
  242
+			document[fn.exit]();
  243
+			lastFullscreenVideo = null;
  244
+		},
  245
+		toggle: function(element) {
  246
+			if (bigscreen.element) {
  247
+				bigscreen.exit();
  248
+			}
  249
+			else {
  250
+				bigscreen.request(element);
  251
+			}
  252
+		},
  253
+
  254
+		// Mobile Safari and earlier versions of desktop Safari support sending a <video> into full screen.
  255
+		// Checks can't be performed to verify full screen capabilities unless we know about that element,
  256
+		// and it has loaded its metadata.
  257
+		videoEnabled: function(element) {
  258
+			if (bigscreen.enabled) {
  259
+				return true;
  260
+			}
  261
+
  262
+			var video = getVideo(element);
  263
+
  264
+			if (!video || video.webkitSupportsFullscreen === undefined) {
  265
+				return false;
  266
+			}
  267
+
  268
+			return video.readyState < video.HAVE_METADATA ? 'maybe' : video.webkitSupportsFullscreen;
  269
+		},
  270
+
  271
+		onenter: function() {},
  272
+		onexit: function() {},
  273
+		onerror: function() {}
  274
+	};
  275
+
  276
+	try {
  277
+		Object.defineProperties(bigscreen, {
  278
+			'element': {
  279
+				enumerable: true,
  280
+				get: function() {
  281
+					if (lastFullscreenVideo && lastFullscreenVideo.webkitDisplayingFullscreen) {
  282
+						return lastFullscreenVideo;
  283
+					}
  284
+
  285
+					return document[fn.element] || null;
  286
+				}
  287
+			},
  288
+			'enabled': {
  289
+				enumerable: true,
  290
+				get: function() {
  291
+					// Safari 5.1 supports full screen, but doesn't have a fullScreenEnabled property,
  292
+					// but it should work if not in an iframe.
  293
+					if (fn.exit === 'webkitCancelFullScreen' && !iframe) {
  294
+						return true;
  295
+					}
  296
+
  297
+					return document[fn.enabled] || false;
  298
+				}
  299
+			}
  300
+		});
  301
+	}
  302
+	catch (err) {
  303
+		bigscreen.element = null;
  304
+		bigscreen.enabled = false;
  305
+	}
  306
+
  307
+	if (fn.change) {
  308
+		document.addEventListener(fn.change, function(event) {
  309
+			if (bigscreen.element) {
  310
+				callOnEnter();
  311
+				addWindowResizeHack();
  312
+			}
  313
+			else {
  314
+				callOnExit();
  315
+			}
  316
+		}, false);
  317
+	}
  318
+
  319
+	if (fn.error) {
  320
+		document.addEventListener(fn.error, function(event) {
  321
+			bigscreen.onerror.call(event.target);
  322
+		}, false);
  323
+	}
  324
+
  325
+	window.BigScreen = bigscreen;
  326
+
  327
+}(window, document, self !== top));
7  dist/bigscreen.min.js
... ...
@@ -0,0 +1,7 @@
  1
+/*!
  2
+* BigScreen
  3
+* v1.0.0 - 2012-08-26
  4
+* https://github.com/bdougherty/BigScreen
  5
+* Copyright 2012 Brad Dougherty; Apache 2.0 License
  6
+*/
  7
+(function(a,b,c){function f(a,b,c){var d;return function(){var e=this,f=arguments,g=function(){d=null,c||a.apply(e,f)},h=c&&!d;clearTimeout(d),d=setTimeout(g,b),h&&a.apply(e,f)}}function g(a){var b=null;if(a.tagName==="VIDEO")b=a;else{var c=a.getElementsByTagName("video");c[0]&&(b=c[0])}return b}function i(a){var b=g(a);if(b&&b.webkitEnterFullscreen){try{b.readyState<b.HAVE_METADATA?(b.addEventListener("loadedmetadata",function d(){b.removeEventListener("loadedmetadata",d,!1),b.webkitEnterFullscreen()},!1),b.load()):b.webkitEnterFullscreen(),h=b,b.play(),n(),setTimeout(j,500)}catch(c){p.onerror.call(b)}return}p.onerror.call(a)}function j(){if(h){if(h.webkitDisplayingFullscreen===!0)return setTimeout(j,500);o()}}function k(){p.element||(o(),m())}function l(){c&&e.change==="webkitfullscreenchange"&&a.addEventListener("resize",k,!1)}function m(){c&&e.change==="webkitfullscreenchange"&&a.removeEventListener("resize",k,!1)}"use strict";var d=typeof Element!="undefined"&&"ALLOW_KEYBOARD_INPUT"in Element,e=function(){var a=[{request:"requestFullscreen",exit:"exitFullscreen",enabled:"fullscreenEnabled",element:"fullscreenElement",change:"fullscreenchange",error:"fullscreenerror"},{request:"webkitRequestFullscreen",exit:"webkitExitFullscreen",enabled:"webkitFullscreenEnabled",element:"webkitFullscreenElement",change:"webkitfullscreenchange",error:"webkitfullscreenerror"},{request:"webkitRequestFullScreen",exit:"webkitCancelFullScreen",element:"webkitCurrentFullScreenElement",change:"webkitfullscreenchange",error:"webkitfullscreenerror"},{request:"mozRequestFullScreen",exit:"mozCancelFullScreen",enabled:"mozFullScreenEnabled",element:"mozFullScreenElement",change:"mozfullscreenchange",error:"mozfullscreenerror"}],c=!1,d=b.createElement("video");for(var e=0;e<a.length;e++)if(a[e].request in d){c=a[e];for(var f in c)!("on"+c[f]in b)&&!(c[f]in b)&&!(c[f]in d)&&delete c[f];break}return d=null,c}(),h=null,n=f(function(){p.onenter.call(p)},100,!0),o=f(function(){p.onexit.call(p)},200,!0),p={request:function(a){a=a||b.documentElement;if(e.request===undefined)return i(a);if(c&&b[e.enabled]===!1)return i(a);if(c&&e.enabled===undefined){e.enabled="webkitFullscreenEnabled",a[e.request](),setTimeout(function(){b[e.element]?b[e.enabled]=!0:(b[e.enabled]=!1,i(a))},250);return}try{a[e.request](d&&Element.ALLOW_KEYBOARD_INPUT),b[e.element]||a[e.request]()}catch(f){p.onerror.call(a)}},exit:function(){m(),b[e.exit](),h=null},toggle:function(a){p.element?p.exit():p.request(a)},videoEnabled:function(a){if(p.enabled)return!0;var b=g(a);return!b||b.webkitSupportsFullscreen===undefined?!1:b.readyState<b.HAVE_METADATA?"maybe":b.webkitSupportsFullscreen},onenter:function(){},onexit:function(){},onerror:function(){}};try{Object.defineProperties(p,{element:{enumerable:!0,get:function(){return h&&h.webkitDisplayingFullscreen?h:b[e.element]||null}},enabled:{enumerable:!0,get:function(){return e.exit==="webkitCancelFullScreen"&&!c?!0:b[e.enabled]||!1}}})}catch(q){p.element=null,p.enabled=!1}e.change&&b.addEventListener(e.change,function(a){p.element?(n(),l()):o()},!1),e.error&&b.addEventListener(e.error,function(a){p.onerror.call(a.target)},!1),a.BigScreen=p})(window,document,self!==top);
53  grunt.js
... ...
@@ -0,0 +1,53 @@
  1
+module.exports = function(grunt) {
  2
+	grunt.initConfig({
  3
+		pkg: '<json:package.json>',
  4
+		meta: {
  5
+			banner: '/*!\n' +
  6
+					'* <%= pkg.name %>\n' +
  7
+					'* v<%= pkg.version %> - ' +
  8
+					'<%= grunt.template.today("yyyy-mm-dd") %>\n' +
  9
+					'<%= pkg.homepage ? "* " + pkg.homepage + "\n" : "" %>' +
  10
+					'* Copyright <%= grunt.template.today("yyyy") %> <%= pkg.author.name %>;' +
  11
+					' <%= _.pluck(pkg.licenses, "type").join(", ") %> License\n' +
  12
+					'*/'
  13
+		},
  14
+		concat: {
  15
+			dist: {
  16
+				src: ['<banner:meta.banner>', 'bigscreen.js'],
  17
+				dest: 'dist/bigscreen.js'
  18
+			}
  19
+		},
  20
+		min: {
  21
+			dist: {
  22
+				src: ['<banner:meta.banner>', 'bigscreen.js'],
  23
+				dest: 'dist/bigscreen.min.js'
  24
+			}
  25
+		},
  26
+		lint: {
  27
+			all: ['bigscreen.js']
  28
+		},
  29
+		jshint: {
  30
+			options: {
  31
+				es5: true,
  32
+				esnext: true,
  33
+				bitwise: true,
  34
+				curly: true,
  35
+				eqeqeq: true,
  36
+				latedef: true,
  37
+				newcap: true,
  38
+				noarg: true,
  39
+				noempty: true,
  40
+				regexp: true,
  41
+				undef: true,
  42
+				strict: true,
  43
+				trailing: true,
  44
+				smarttabs: true,
  45
+				browser: true,
  46
+				nonstandard: true
  47
+			}
  48
+		}
  49
+	});
  50
+
  51
+	grunt.registerTask('default', 'lint');
  52
+    grunt.registerTask('release', 'lint concat min');
  53
+};
25  package.json
... ...
@@ -0,0 +1,25 @@
  1
+{
  2
+	"name": "BigScreen",
  3
+	"version": "1.0.0",
  4
+	"description": "A simple library for using the JavaScript Full Screen API.",
  5
+	"keywords": [
  6
+		"fullscreen"
  7
+	],
  8
+	"homepage": "https://github.com/bdougherty/BigScreen",
  9
+	"bugs": {
  10
+		"web": "https://github.com/bdougherty/BigScreen/issues"
  11
+	},
  12
+	"author": {
  13
+		"name": "Brad Dougherty",
  14
+		"email": "hi@brad.is",
  15
+		"url": "http://brad.is"
  16
+	},
  17
+	"repositories": {
  18
+		"type": "git",
  19
+		"url": "git@github.com:bdougherty/BigScreen.git"
  20
+	},
  21
+	"licenses": [{
  22
+		"type": "Apache 2.0",
  23
+		"url": "http://www.apache.org/licenses/LICENSE-2.0"
  24
+	}]
  25
+}

0 notes on commit 25f1876

Please sign in to comment.
Something went wrong with that request. Please try again.