You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

337 lines
8.0KB

  1. /*
  2. * full-screen-helper.js 1.0.5
  3. *
  4. * Copyright (c) 2020 Guilherme Nascimento (brcontainer@yahoo.com.br)
  5. *
  6. * Released under the MIT license
  7. */
  8. (function (u) {
  9. "use strict";
  10. var html, body, timer,
  11. w = typeof window !== 'undefined' ? window : {},
  12. d = w.document || {},
  13. $ = w.$ || {},
  14. current = null,
  15. wsso, wssoc = false, escEvt = false,
  16. useviewport = false, allowviewport = true, state = false,
  17. sc = !!d.exitFullscreen,
  18. mozc = !!d.mozCancelFullScreen,
  19. wkc = !!(d.webkitExitFullscreen || d.webkitCancelFullScreen),
  20. wkco = !!d.webkitCancelFullScreen,
  21. wkcn = !!d.webkitExitFullscreen,
  22. msc = !!d.msExitFullscreen,
  23. reRoot = /(^|\s+)fsh-infullscreen($|\s+)/i,
  24. reElement = /(^|\s+)full-screen-helper($|\s+)/i,
  25. changeEvents = [],
  26. events = [
  27. "webkitfullscreenchange", "mozfullscreenchange",
  28. "fullscreenchange", "MSFullscreenChange"
  29. ];
  30. var realsupport = sc || mozc || wkc || msc;
  31. function change(callback, remove) {
  32. if (typeof callback !== "function") return;
  33. if (!remove) {
  34. changeEvents.push(callback);
  35. return;
  36. }
  37. if (!remove) {
  38. changeEvents.push(callback);
  39. return;
  40. }
  41. var relist = [];
  42. for (var i = 0, j = changeEvents.length; i < j; i++) {
  43. if (changeEvents[i] !== callback) relist.push(callback);
  44. }
  45. changeEvents = relist;
  46. relist = null;
  47. }
  48. function isValid(obj) {
  49. if (current) return false;
  50. if (obj === u || obj === d) return d.body;
  51. if (typeof obj === "string") return d.querySelector(obj);
  52. if (w.HTMLElement) {
  53. if (!obj || !(obj instanceof w.HTMLElement && obj.ownerDocument === d)) return false;
  54. }
  55. if (!obj || obj.nodeType !== 1 || obj.ownerDocument !== d) return false;
  56. return obj;
  57. }
  58. function addEvt(obj, type, callback) {
  59. if (obj.addEventListener) {
  60. obj.addEventListener(type, callback);
  61. } else {
  62. obj.attachEvent("on" + type, callback);
  63. }
  64. }
  65. function isFS1() {
  66. return getElements() &&
  67. (w.outerWidth || w.innerWidth || html.clientWidth) == w.screen.width;
  68. }
  69. function isFS2() {
  70. var element = d.fullscreenElement || d.mozFullScreenElement ||
  71. d.webkitFullscreenElement || d.msFullscreenElement;
  72. if (!element) return false;
  73. if (element !== current) current = element;
  74. return true;
  75. }
  76. function getWSSO() {
  77. if (wssoc) return wssoc;
  78. if (wsso === false || w.ActiveXObject === u) {
  79. wsso = false;
  80. } else if (wsso === u) {
  81. try {
  82. wsso = new w.ActiveXObject("WScript.Shell");
  83. wssoc = true;
  84. addEvt(w, "resize", resizeObserver);
  85. } catch (ee) {
  86. wsso = false;
  87. }
  88. }
  89. return wssoc;
  90. }
  91. function escObserver(e) {
  92. e = e || w.event;
  93. if ((e.wich || e.keyCode) == 27) exit();
  94. }
  95. function toggleClass() {
  96. active(wssoc ? isFS1() : isFS2());
  97. }
  98. function resizeObserver(e) {
  99. clearTimeout(timer);
  100. timer = setTimeout(toggleClass, wssoc ? 100 : 10);
  101. }
  102. function getElements() {
  103. if (html) return true;
  104. body = d.body;
  105. html = d.documentElement || (body && body.parentNode);
  106. return !!html;
  107. }
  108. function fallbackRequest(element) {
  109. console.debug("fallbackRequest");
  110. if (!escEvt) {
  111. escEvt = true;
  112. addEvt(d, "keydown", escObserver);
  113. }
  114. if (getWSSO()) {
  115. if (!isFS1()) {
  116. current = element;
  117. active(true);
  118. wsso.SendKeys("{F11}");
  119. }
  120. return;
  121. }
  122. useviewport = allowviewport;
  123. console.debug("fallbackReqeust.userviewport");
  124. if (useviewport) request(element);
  125. }
  126. function active(enable) {
  127. if (state === enable || !current) return;
  128. if (!getElements()) {
  129. current = null;
  130. return;
  131. }
  132. if (enable) {
  133. if (!reRoot.test(html.className)) html.className += " fsh-infullscreen";
  134. if (!reElement.test(current.className)) current.className += " full-screen-helper";
  135. } else {
  136. html.className = html.className.replace(reRoot, " ");
  137. current.className = current.className.replace(reElement, " ");
  138. current = null;
  139. }
  140. state = enable;
  141. setTimeout(triggerEvents, 1);
  142. }
  143. function triggerEvents() {
  144. for (var i = 0; i < changeEvents.length; i++) changeEvents[i]();
  145. }
  146. function supported() {
  147. return realsupport || getWSSO();
  148. }
  149. function request(element) {
  150. element = isValid(element);
  151. if (!element) return;
  152. console.debug("element is valid");
  153. if (sc) {
  154. element.requestFullscreen();
  155. } else if (mozc) {
  156. element.mozRequestFullScreen();
  157. } else if (wkc) {
  158. element.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
  159. } else if (msc) {
  160. element.msRequestFullscreen();
  161. } else if (!useviewport) {
  162. fallbackRequest(element);
  163. return;
  164. }
  165. current = element;
  166. active(true);
  167. }
  168. function exit() {
  169. if (!current) return;
  170. if (sc) {
  171. d.exitFullscreen();
  172. } else if (mozc) {
  173. d.mozCancelFullScreen();
  174. } else if (wkcn) {
  175. d.webkitExitFullscreen();
  176. } else if (wkco) {
  177. d.webkitCancelFullScreen();
  178. } else if (msc) {
  179. d.msExitFullscreen();
  180. } else if (!useviewport) {
  181. if (isFS1() && wssoc) {
  182. active(false);
  183. wsso.SendKeys("{F11}");
  184. }
  185. return;
  186. }
  187. active(false);
  188. }
  189. function toggle(element) {
  190. if (current === (element || d.body)) {
  191. exit();
  192. } else {
  193. request(element);
  194. }
  195. }
  196. if (realsupport) {
  197. for (var i = events.length - 1; i >= 0; i--) addEvt(d, events[i], resizeObserver);
  198. addEvt(w, "resize", resizeObserver);
  199. }
  200. var main = {
  201. "supported": supported,
  202. "request": request,
  203. "toggle": toggle,
  204. "exit": exit,
  205. "current": function () {
  206. return current;
  207. },
  208. "state": function () {
  209. return state;
  210. },
  211. "viewport": function (enable) {
  212. allowviewport = !!enable;
  213. },
  214. "on": function (callback) {
  215. change(callback);
  216. },
  217. "off": function (callback) {
  218. change(callback, true);
  219. }
  220. };
  221. if ($ && $.extend && $.expr) {
  222. $.fn.fullScreenHelper = function (action) {
  223. var element = this[0];
  224. if (!element) return;
  225. switch (action) {
  226. case "toggle":
  227. toggle(element);
  228. break;
  229. case "request":
  230. case u:
  231. request(element);
  232. break;
  233. }
  234. };
  235. $.fullScreenHelper = function (action) {
  236. switch (action) {
  237. case "exit":
  238. exit();
  239. break;
  240. case "supported":
  241. return supported();
  242. break;
  243. case "state":
  244. return state;
  245. }
  246. };
  247. $.expr[":"].fullscreen = function (element) {
  248. return reElement.test(element.className);
  249. };
  250. if (!("onfullscreenchange" in d)) {
  251. var $d = $(d);
  252. change(function () {
  253. $d.trigger("fullscreenchange");
  254. });
  255. }
  256. }
  257. w.FullScreenHelper = main;
  258. // CommonJS
  259. if (typeof module !== "undefined" && module.exports) module.exports = main;
  260. // RequireJS
  261. if (typeof define !== "undefined") define(function () { return main; });
  262. })();