vttcue.js 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. /**
  2. * Copyright 2013 vtt.js Contributors
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. var autoKeyword = "auto";
  17. var directionSetting = {
  18. "": true,
  19. "lr": true,
  20. "rl": true
  21. };
  22. var alignSetting = {
  23. "start": true,
  24. "middle": true,
  25. "end": true,
  26. "left": true,
  27. "right": true
  28. };
  29. function findDirectionSetting(value) {
  30. if (typeof value !== "string") {
  31. return false;
  32. }
  33. var dir = directionSetting[value.toLowerCase()];
  34. return dir ? value.toLowerCase() : false;
  35. }
  36. function findAlignSetting(value) {
  37. if (typeof value !== "string") {
  38. return false;
  39. }
  40. var align = alignSetting[value.toLowerCase()];
  41. return align ? value.toLowerCase() : false;
  42. }
  43. function extend(obj) {
  44. var i = 1;
  45. for (; i < arguments.length; i++) {
  46. var cobj = arguments[i];
  47. for (var p in cobj) {
  48. obj[p] = cobj[p];
  49. }
  50. }
  51. return obj;
  52. }
  53. function VTTCue(startTime, endTime, text) {
  54. var cue = this;
  55. var isIE8 = (/MSIE\s8\.0/).test(navigator.userAgent);
  56. var baseObj = {};
  57. if (isIE8) {
  58. cue = document.createElement('custom');
  59. } else {
  60. baseObj.enumerable = true;
  61. }
  62. /**
  63. * Shim implementation specific properties. These properties are not in
  64. * the spec.
  65. */
  66. // Lets us know when the VTTCue's data has changed in such a way that we need
  67. // to recompute its display state. This lets us compute its display state
  68. // lazily.
  69. cue.hasBeenReset = false;
  70. /**
  71. * VTTCue and TextTrackCue properties
  72. * http://dev.w3.org/html5/webvtt/#vttcue-interface
  73. */
  74. var _id = "";
  75. var _pauseOnExit = false;
  76. var _startTime = startTime;
  77. var _endTime = endTime;
  78. var _text = text;
  79. var _region = null;
  80. var _vertical = "";
  81. var _snapToLines = true;
  82. var _line = "auto";
  83. var _lineAlign = "start";
  84. var _position = 50;
  85. var _positionAlign = "middle";
  86. var _size = 50;
  87. var _align = "middle";
  88. Object.defineProperty(cue,
  89. "id", extend({}, baseObj, {
  90. get: function() {
  91. return _id;
  92. },
  93. set: function(value) {
  94. _id = "" + value;
  95. }
  96. }));
  97. Object.defineProperty(cue,
  98. "pauseOnExit", extend({}, baseObj, {
  99. get: function() {
  100. return _pauseOnExit;
  101. },
  102. set: function(value) {
  103. _pauseOnExit = !!value;
  104. }
  105. }));
  106. Object.defineProperty(cue,
  107. "startTime", extend({}, baseObj, {
  108. get: function() {
  109. return _startTime;
  110. },
  111. set: function(value) {
  112. if (typeof value !== "number") {
  113. throw new TypeError("Start time must be set to a number.");
  114. }
  115. _startTime = value;
  116. this.hasBeenReset = true;
  117. }
  118. }));
  119. Object.defineProperty(cue,
  120. "endTime", extend({}, baseObj, {
  121. get: function() {
  122. return _endTime;
  123. },
  124. set: function(value) {
  125. if (typeof value !== "number") {
  126. throw new TypeError("End time must be set to a number.");
  127. }
  128. _endTime = value;
  129. this.hasBeenReset = true;
  130. }
  131. }));
  132. Object.defineProperty(cue,
  133. "text", extend({}, baseObj, {
  134. get: function() {
  135. return _text;
  136. },
  137. set: function(value) {
  138. _text = "" + value;
  139. this.hasBeenReset = true;
  140. }
  141. }));
  142. Object.defineProperty(cue,
  143. "region", extend({}, baseObj, {
  144. get: function() {
  145. return _region;
  146. },
  147. set: function(value) {
  148. _region = value;
  149. this.hasBeenReset = true;
  150. }
  151. }));
  152. Object.defineProperty(cue,
  153. "vertical", extend({}, baseObj, {
  154. get: function() {
  155. return _vertical;
  156. },
  157. set: function(value) {
  158. var setting = findDirectionSetting(value);
  159. // Have to check for false because the setting an be an empty string.
  160. if (setting === false) {
  161. throw new SyntaxError("An invalid or illegal string was specified.");
  162. }
  163. _vertical = setting;
  164. this.hasBeenReset = true;
  165. }
  166. }));
  167. Object.defineProperty(cue,
  168. "snapToLines", extend({}, baseObj, {
  169. get: function() {
  170. return _snapToLines;
  171. },
  172. set: function(value) {
  173. _snapToLines = !!value;
  174. this.hasBeenReset = true;
  175. }
  176. }));
  177. Object.defineProperty(cue,
  178. "line", extend({}, baseObj, {
  179. get: function() {
  180. return _line;
  181. },
  182. set: function(value) {
  183. if (typeof value !== "number" && value !== autoKeyword) {
  184. throw new SyntaxError("An invalid number or illegal string was specified.");
  185. }
  186. _line = value;
  187. this.hasBeenReset = true;
  188. }
  189. }));
  190. Object.defineProperty(cue,
  191. "lineAlign", extend({}, baseObj, {
  192. get: function() {
  193. return _lineAlign;
  194. },
  195. set: function(value) {
  196. var setting = findAlignSetting(value);
  197. if (!setting) {
  198. throw new SyntaxError("An invalid or illegal string was specified.");
  199. }
  200. _lineAlign = setting;
  201. this.hasBeenReset = true;
  202. }
  203. }));
  204. Object.defineProperty(cue,
  205. "position", extend({}, baseObj, {
  206. get: function() {
  207. return _position;
  208. },
  209. set: function(value) {
  210. if (value < 0 || value > 100) {
  211. throw new Error("Position must be between 0 and 100.");
  212. }
  213. _position = value;
  214. this.hasBeenReset = true;
  215. }
  216. }));
  217. Object.defineProperty(cue,
  218. "positionAlign", extend({}, baseObj, {
  219. get: function() {
  220. return _positionAlign;
  221. },
  222. set: function(value) {
  223. var setting = findAlignSetting(value);
  224. if (!setting) {
  225. throw new SyntaxError("An invalid or illegal string was specified.");
  226. }
  227. _positionAlign = setting;
  228. this.hasBeenReset = true;
  229. }
  230. }));
  231. Object.defineProperty(cue,
  232. "size", extend({}, baseObj, {
  233. get: function() {
  234. return _size;
  235. },
  236. set: function(value) {
  237. if (value < 0 || value > 100) {
  238. throw new Error("Size must be between 0 and 100.");
  239. }
  240. _size = value;
  241. this.hasBeenReset = true;
  242. }
  243. }));
  244. Object.defineProperty(cue,
  245. "align", extend({}, baseObj, {
  246. get: function() {
  247. return _align;
  248. },
  249. set: function(value) {
  250. var setting = findAlignSetting(value);
  251. if (!setting) {
  252. throw new SyntaxError("An invalid or illegal string was specified.");
  253. }
  254. _align = setting;
  255. this.hasBeenReset = true;
  256. }
  257. }));
  258. /**
  259. * Other <track> spec defined properties
  260. */
  261. // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#text-track-cue-display-state
  262. cue.displayState = undefined;
  263. if (isIE8) {
  264. return cue;
  265. }
  266. }
  267. /**
  268. * VTTCue methods
  269. */
  270. VTTCue.prototype.getCueAsHTML = function() {
  271. // Assume WebVTT.convertCueToDOMTree is on the global.
  272. return WebVTT.convertCueToDOMTree(window, this.text);
  273. };
  274. module.exports = VTTCue;