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.

662 lines
19 KiB

  1. /*!
  2. * # Semantic UI 2.0.0 - Video
  3. * http://github.com/semantic-org/semantic-ui/
  4. *
  5. *
  6. * Copyright 2015 Contributors
  7. * Released under the MIT license
  8. * http://opensource.org/licenses/MIT
  9. *
  10. */
  11. ;(function ($, window, document, undefined) {
  12. "use strict";
  13. $.fn.embed = function(parameters) {
  14. var
  15. $allModules = $(this),
  16. moduleSelector = $allModules.selector || '',
  17. time = new Date().getTime(),
  18. performance = [],
  19. query = arguments[0],
  20. methodInvoked = (typeof query == 'string'),
  21. queryArguments = [].slice.call(arguments, 1),
  22. returnedValue
  23. ;
  24. $allModules
  25. .each(function() {
  26. var
  27. settings = ( $.isPlainObject(parameters) )
  28. ? $.extend(true, {}, $.fn.embed.settings, parameters)
  29. : $.extend({}, $.fn.embed.settings),
  30. selector = settings.selector,
  31. className = settings.className,
  32. sources = settings.sources,
  33. error = settings.error,
  34. metadata = settings.metadata,
  35. namespace = settings.namespace,
  36. templates = settings.templates,
  37. eventNamespace = '.' + namespace,
  38. moduleNamespace = 'module-' + namespace,
  39. $window = $(window),
  40. $module = $(this),
  41. $placeholder = $module.find(selector.placeholder),
  42. $icon = $module.find(selector.icon),
  43. $embed = $module.find(selector.embed),
  44. element = this,
  45. instance = $module.data(moduleNamespace),
  46. module
  47. ;
  48. module = {
  49. initialize: function() {
  50. module.debug('Initializing embed');
  51. module.determine.autoplay();
  52. module.create();
  53. module.bind.events();
  54. module.instantiate();
  55. },
  56. instantiate: function() {
  57. module.verbose('Storing instance of module', module);
  58. instance = module;
  59. $module
  60. .data(moduleNamespace, module)
  61. ;
  62. },
  63. destroy: function() {
  64. module.verbose('Destroying previous instance of embed');
  65. module.reset();
  66. $module
  67. .removeData(moduleNamespace)
  68. .off(eventNamespace)
  69. ;
  70. },
  71. refresh: function() {
  72. module.verbose('Refreshing selector cache');
  73. $placeholder = $module.find(selector.placeholder);
  74. $icon = $module.find(selector.icon);
  75. $embed = $module.find(selector.embed);
  76. },
  77. bind: {
  78. events: function() {
  79. if( module.has.placeholder() ) {
  80. module.debug('Adding placeholder events');
  81. console.log($module, selector.placeholder);
  82. $module
  83. .on('click' + eventNamespace, selector.placeholder, module.createAndShow)
  84. .on('click' + eventNamespace, selector.icon, module.createAndShow)
  85. ;
  86. }
  87. }
  88. },
  89. create: function() {
  90. var
  91. placeholder = module.get.placeholder()
  92. ;
  93. if(placeholder) {
  94. module.createPlaceholder();
  95. }
  96. else {
  97. module.createAndShow();
  98. }
  99. },
  100. createPlaceholder: function(placeholder) {
  101. var
  102. icon = module.get.icon(),
  103. url = module.get.url(),
  104. embed = module.generate.embed(url)
  105. ;
  106. placeholder = placeholder || module.get.placeholder();
  107. $module.html( templates.placeholder(placeholder, icon) );
  108. module.debug('Creating placeholder for embed', placeholder, icon);
  109. },
  110. createEmbed: function(url) {
  111. module.refresh();
  112. url = url || module.get.url();
  113. console.log(url);
  114. $embed = $('<div/>')
  115. .addClass(className.embed)
  116. .html( module.generate.embed(url) )
  117. .appendTo($module)
  118. ;
  119. settings.onCreate.call(element, url);
  120. module.debug('Creating embed object', $embed);
  121. },
  122. createAndShow: function() {
  123. console.log('cands');
  124. module.createEmbed();
  125. module.show();
  126. },
  127. // sets new embed
  128. change: function(source, id, url) {
  129. module.debug('Changing video to ', source, id, url);
  130. $module
  131. .data(metadata.source, source)
  132. .data(metadata.id, id)
  133. .data(metadata.url, url)
  134. ;
  135. module.create();
  136. },
  137. // clears embed
  138. reset: function() {
  139. module.debug('Clearing embed and showing placeholder');
  140. module.remove.active();
  141. module.remove.embed();
  142. module.showPlaceholder();
  143. settings.onReset.call(element);
  144. },
  145. // shows current embed
  146. show: function() {
  147. module.debug('Showing embed');
  148. module.set.active();
  149. settings.onDisplay.call(element);
  150. },
  151. hide: function() {
  152. module.debug('Hiding embed');
  153. module.showPlaceholder();
  154. },
  155. showPlaceholder: function() {
  156. module.debug('Showing placeholder image');
  157. module.remove.active();
  158. settings.onPlaceholderDisplay.call(element);
  159. },
  160. get: {
  161. id: function() {
  162. return settings.id || $module.data(metadata.id);
  163. },
  164. placeholder: function() {
  165. return settings.placeholder || $module.data(metadata.placeholder);
  166. },
  167. icon: function() {
  168. return (settings.icon)
  169. ? settings.icon
  170. : ($module.data(metadata.icon) !== undefined)
  171. ? $module.data(metadata.icon)
  172. : module.determine.icon()
  173. ;
  174. },
  175. source: function(url) {
  176. return (settings.source)
  177. ? settings.source
  178. : ($module.data(metadata.source) !== undefined)
  179. ? $module.data(metadata.source)
  180. : module.determine.source()
  181. ;
  182. },
  183. type: function() {
  184. var source = module.get.source();
  185. return (sources[source] !== undefined)
  186. ? sources[source].type
  187. : false
  188. ;
  189. },
  190. url: function() {
  191. return (settings.url)
  192. ? settings.url
  193. : ($module.data(metadata.url) !== undefined)
  194. ? $module.data(metadata.url)
  195. : module.determine.url()
  196. ;
  197. }
  198. },
  199. determine: {
  200. autoplay: function() {
  201. if(module.should.autoplay()) {
  202. settings.autoplay = true;
  203. }
  204. },
  205. source: function(url) {
  206. var
  207. matchedSource = false
  208. ;
  209. url = url || module.get.url();
  210. if(url) {
  211. $.each(sources, function(name, source) {
  212. if(url.search(source.domain) !== -1) {
  213. matchedSource = name;
  214. return false;
  215. }
  216. });
  217. }
  218. return matchedSource;
  219. },
  220. icon: function() {
  221. var
  222. source = module.get.source()
  223. ;
  224. return (sources[source] !== undefined)
  225. ? sources[source].icon
  226. : false
  227. ;
  228. },
  229. url: function() {
  230. var
  231. id = settings.id || $module.data(metadata.id),
  232. source = settings.source || $module.data(metadata.source),
  233. url
  234. ;
  235. url = (sources[source] !== undefined)
  236. ? sources[source].url.replace('{id}', id)
  237. : false
  238. ;
  239. if(url) {
  240. $module.data(metadata.url, url);
  241. }
  242. return url;
  243. }
  244. },
  245. set: {
  246. active: function() {
  247. $module.addClass(className.active);
  248. }
  249. },
  250. remove: {
  251. active: function() {
  252. $module.removeClass(className.active);
  253. },
  254. embed: function() {
  255. $embed.empty();
  256. }
  257. },
  258. encode: {
  259. parameters: function(parameters) {
  260. var
  261. urlString = [],
  262. index
  263. ;
  264. for (index in parameters) {
  265. urlString.push( encodeURIComponent(index) + '=' + encodeURIComponent( parameters[index] ) );
  266. }
  267. return urlString.join('&amp;');
  268. }
  269. },
  270. generate: {
  271. embed: function(url) {
  272. module.debug('Generating embed html');
  273. var
  274. source = module.get.source(),
  275. html,
  276. parameters
  277. ;
  278. url = module.get.url(url);
  279. if(url) {
  280. parameters = module.generate.parameters(source);
  281. html = templates.iframe(url, parameters);
  282. }
  283. else {
  284. module.error(error.noURL, $module);
  285. }
  286. return html;
  287. },
  288. parameters: function(source, extraParameters) {
  289. var
  290. parameters = (sources[source] && sources[source].parameters !== undefined)
  291. ? sources[source].parameters(settings)
  292. : {}
  293. ;
  294. extraParameters = extraParameters || settings.parameters;
  295. if(extraParameters) {
  296. parameters = $.extend({}, parameters, extraParameters);
  297. }
  298. parameters = settings.onEmbed(parameters);
  299. return module.encode.parameters(parameters);
  300. }
  301. },
  302. has: {
  303. placeholder: function() {
  304. return settings.placeholder || $module.data(metadata.placeholder);
  305. }
  306. },
  307. should: {
  308. autoplay: function() {
  309. return (settings.autoplay === 'auto')
  310. ? (settings.placeholder || $module.data(metadata.placeholder) !== undefined)
  311. : settings.autoplay
  312. ;
  313. }
  314. },
  315. is: {
  316. video: function() {
  317. return module.get.type() == 'video';
  318. }
  319. },
  320. setting: function(name, value) {
  321. module.debug('Changing setting', name, value);
  322. if( $.isPlainObject(name) ) {
  323. $.extend(true, settings, name);
  324. }
  325. else if(value !== undefined) {
  326. settings[name] = value;
  327. }
  328. else {
  329. return settings[name];
  330. }
  331. },
  332. internal: function(name, value) {
  333. if( $.isPlainObject(name) ) {
  334. $.extend(true, module, name);
  335. }
  336. else if(value !== undefined) {
  337. module[name] = value;
  338. }
  339. else {
  340. return module[name];
  341. }
  342. },
  343. debug: function() {
  344. if(settings.debug) {
  345. if(settings.performance) {
  346. module.performance.log(arguments);
  347. }
  348. else {
  349. module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  350. module.debug.apply(console, arguments);
  351. }
  352. }
  353. },
  354. verbose: function() {
  355. if(settings.verbose && settings.debug) {
  356. if(settings.performance) {
  357. module.performance.log(arguments);
  358. }
  359. else {
  360. module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  361. module.verbose.apply(console, arguments);
  362. }
  363. }
  364. },
  365. error: function() {
  366. module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  367. module.error.apply(console, arguments);
  368. },
  369. performance: {
  370. log: function(message) {
  371. var
  372. currentTime,
  373. executionTime,
  374. previousTime
  375. ;
  376. if(settings.performance) {
  377. currentTime = new Date().getTime();
  378. previousTime = time || currentTime;
  379. executionTime = currentTime - previousTime;
  380. time = currentTime;
  381. performance.push({
  382. 'Name' : message[0],
  383. 'Arguments' : [].slice.call(message, 1) || '',
  384. 'Element' : element,
  385. 'Execution Time' : executionTime
  386. });
  387. }
  388. clearTimeout(module.performance.timer);
  389. module.performance.timer = setTimeout(module.performance.display, 500);
  390. },
  391. display: function() {
  392. var
  393. title = settings.name + ':',
  394. totalTime = 0
  395. ;
  396. time = false;
  397. clearTimeout(module.performance.timer);
  398. $.each(performance, function(index, data) {
  399. totalTime += data['Execution Time'];
  400. });
  401. title += ' ' + totalTime + 'ms';
  402. if(moduleSelector) {
  403. title += ' \'' + moduleSelector + '\'';
  404. }
  405. if($allModules.length > 1) {
  406. title += ' ' + '(' + $allModules.length + ')';
  407. }
  408. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  409. console.groupCollapsed(title);
  410. if(console.table) {
  411. console.table(performance);
  412. }
  413. else {
  414. $.each(performance, function(index, data) {
  415. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  416. });
  417. }
  418. console.groupEnd();
  419. }
  420. performance = [];
  421. }
  422. },
  423. invoke: function(query, passedArguments, context) {
  424. var
  425. object = instance,
  426. maxDepth,
  427. found,
  428. response
  429. ;
  430. passedArguments = passedArguments || queryArguments;
  431. context = element || context;
  432. if(typeof query == 'string' && object !== undefined) {
  433. query = query.split(/[\. ]/);
  434. maxDepth = query.length - 1;
  435. $.each(query, function(depth, value) {
  436. var camelCaseValue = (depth != maxDepth)
  437. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  438. : query
  439. ;
  440. if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  441. object = object[camelCaseValue];
  442. }
  443. else if( object[camelCaseValue] !== undefined ) {
  444. found = object[camelCaseValue];
  445. return false;
  446. }
  447. else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  448. object = object[value];
  449. }
  450. else if( object[value] !== undefined ) {
  451. found = object[value];
  452. return false;
  453. }
  454. else {
  455. module.error(error.method, query);
  456. return false;
  457. }
  458. });
  459. }
  460. if ( $.isFunction( found ) ) {
  461. response = found.apply(context, passedArguments);
  462. }
  463. else if(found !== undefined) {
  464. response = found;
  465. }
  466. if($.isArray(returnedValue)) {
  467. returnedValue.push(response);
  468. }
  469. else if(returnedValue !== undefined) {
  470. returnedValue = [returnedValue, response];
  471. }
  472. else if(response !== undefined) {
  473. returnedValue = response;
  474. }
  475. return found;
  476. }
  477. };
  478. if(methodInvoked) {
  479. if(instance === undefined) {
  480. module.initialize();
  481. }
  482. module.invoke(query);
  483. }
  484. else {
  485. if(instance !== undefined) {
  486. instance.invoke('destroy');
  487. }
  488. module.initialize();
  489. }
  490. })
  491. ;
  492. return (returnedValue !== undefined)
  493. ? returnedValue
  494. : this
  495. ;
  496. };
  497. $.fn.embed.settings = {
  498. name : 'Embed',
  499. namespace : 'embed',
  500. debug : false,
  501. verbose : false,
  502. performance : true,
  503. icon : false,
  504. source : false,
  505. url : false,
  506. id : false,
  507. // standard video settings
  508. autoplay : 'auto',
  509. color : '#444444',
  510. hd : true,
  511. brandedUI : false,
  512. // additional parameters to include with the embed
  513. parameters: false,
  514. onDisplay : function() {},
  515. onPlaceholderDisplay : function() {},
  516. onReset : function() {},
  517. onCreate : function(url) {},
  518. onEmbed : function(parameters) {
  519. return parameters;
  520. },
  521. metadata : {
  522. id : 'id',
  523. icon : 'icon',
  524. placeholder : 'placeholder',
  525. source : 'source',
  526. url : 'url'
  527. },
  528. error : {
  529. noURL : 'No URL specified',
  530. method : 'The method you called is not defined'
  531. },
  532. className : {
  533. active : 'active',
  534. embed : 'embed'
  535. },
  536. selector : {
  537. embed : '.embed',
  538. placeholder : '.placeholder',
  539. icon : '.icon'
  540. },
  541. sources: {
  542. youtube: {
  543. name : 'youtube',
  544. type : 'video',
  545. icon : 'video play',
  546. domain : 'youtube.com',
  547. url : '//www.youtube.com/embed/{id}',
  548. parameters: function(settings) {
  549. return {
  550. autohide : !settings.brandedUI,
  551. autoplay : settings.autoplay,
  552. color : settings.colors || undefined,
  553. hq : settings.hd,
  554. jsapi : settings.api,
  555. modestbranding : !settings.brandedUI
  556. };
  557. }
  558. },
  559. vimeo: {
  560. name : 'vimeo',
  561. type : 'video',
  562. icon : 'video play',
  563. domain : 'vimeo.com',
  564. url : '//player.vimeo.com/video/{id}',
  565. parameters: function(settings) {
  566. return {
  567. api : settings.api,
  568. autoplay : settings.autoplay,
  569. byline : settings.brandedUI,
  570. color : settings.colors || undefined,
  571. portrait : settings.brandedUI,
  572. title : settings.brandedUI
  573. };
  574. }
  575. }
  576. },
  577. templates: {
  578. iframe : function(url, parameters) {
  579. return ''
  580. + '<iframe src="' + url + '?=' + parameters + '"'
  581. + ' width="100%" height="100%"'
  582. + ' frameborder="0" scrolling="no" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>'
  583. ;
  584. },
  585. placeholder : function(image, icon) {
  586. var
  587. html = ''
  588. ;
  589. if(icon) {
  590. html += '<i class="' + icon + ' icon"></i>';
  591. }
  592. if(image) {
  593. html += '<img class="placeholder" src="' + image + '">';
  594. }
  595. return html;
  596. }
  597. },
  598. // NOT YET IMPLEMENTED
  599. api : true,
  600. onPause : function() {},
  601. onPlay : function() {},
  602. onStop : function() {}
  603. };
  604. })( jQuery, window , document );