1
0

embed.js 19 KB

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