one-box.js 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. const ytRegExp = new RegExp('^.*(?:(?:youtu\.be\/|v\/|vi\/|u\/\w\/|embed\/)|(?:(?:watch)?\?v(?:i)?=|\&v(?:i)?=))([^#\&\?]*).*');
  2. export class OneBox {
  3. constructor() {
  4. this._youtube = {};
  5. }
  6. // jshint ignore:start
  7. render = (domnode) => {
  8. if (!domnode) return;
  9. this.highlightCode(domnode);
  10. this.embedYoutubePlayers(domnode);
  11. };
  12. // jshint ignore:end
  13. highlightCode(domnode) {
  14. const codeblocks = domnode.querySelectorAll('pre>code');
  15. for(let i = 0; i < codeblocks.length; i++ ) {
  16. const code = codeblocks[i];
  17. hljs.highlightBlock(code);
  18. }
  19. }
  20. embedYoutubePlayers(domnode) {
  21. const anchors = domnode.querySelectorAll('p>a');
  22. for(let i = 0; i < anchors.length; i++ ) {
  23. const a = anchors[i];
  24. const p = a.parentNode;
  25. const onlyChild = p.childNodes.length === 1;
  26. if (!this._youtube[a.href]) {
  27. this._youtube[a.href] = parseYoutubeUrl(a.href);
  28. }
  29. const youtubeMovie = this._youtube[a.href];
  30. if (onlyChild && !!youtubeMovie && youtubeMovie.data !== false) {
  31. this.swapYoutubePlayer(a, youtubeMovie);
  32. }
  33. }
  34. }
  35. swapYoutubePlayer(element, youtube) {
  36. let url = 'https://www.youtube.com/embed/';
  37. url += youtube.video;
  38. url += '?rel=0';
  39. if (youtube.start) {
  40. url += '&start=' + youtube.start;
  41. }
  42. const player = $('<iframe class="embed-responsive-item" src="' + url + '" allowfullscreen></iframe>');
  43. $(element).replaceWith(player);
  44. player.wrap('<div class="embed-responsive embed-responsive-16by9"></div>');
  45. }
  46. }
  47. export default new OneBox();
  48. export function parseYoutubeUrl(url) {
  49. const cleanedUrl = cleanUrl(url);
  50. const video = getVideoIdFromUrl(cleanedUrl);
  51. if (!video) return null;
  52. let start = 0;
  53. if (cleanedUrl.indexOf('?') > 0){
  54. const query = cleanedUrl.substr(cleanedUrl.indexOf('?') + 1);
  55. const timebit = query.split('&').filter((i) => {
  56. return i.substr(0, 2) === 't=';
  57. })[0];
  58. if (timebit) {
  59. const bits = timebit.substr(2).split('m');
  60. if (bits[0].substr(-1) === 's') {
  61. start += parseInt(bits[0].substr(0, bits[0].length - 1));
  62. } else {
  63. start += parseInt(bits[0]) * 60;
  64. if (!!bits[1] && bits[1].substr(-1) === 's') {
  65. start += parseInt(bits[1].substr(0, bits[1].length - 1));
  66. }
  67. }
  68. }
  69. }
  70. return {
  71. start,
  72. video
  73. };
  74. }
  75. export function cleanUrl(url) {
  76. let clean = url;
  77. if (url.substr(0, 8) === 'https://') {
  78. clean = clean.substr(8);
  79. } else if (url.substr(0, 7) === 'http://') {
  80. clean = clean.substr(7);
  81. }
  82. if (clean.substr(0, 4) === 'www.') {
  83. clean = clean.substr(4);
  84. }
  85. return clean;
  86. }
  87. export function getVideoIdFromUrl(url) {
  88. if (url.indexOf('youtu') === -1) return null;
  89. const video = url.match(ytRegExp);
  90. if (video) {
  91. return video[1];
  92. }
  93. return null;
  94. }