qmarkersrolls.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388
  1. /**
  2. * Plugin created by BeezNest Latino S.A.C
  3. *
  4. * For licensing terms, see /license.txt
  5. *
  6. * This plugin allows set quizzes markers in video with mediaelement.
  7. */
  8. CKEDITOR.dialog.add('qMarkersrollsDialog', function (editor) {
  9. var lang = editor.lang.qmarkersrolls,
  10. player = null,
  11. pgbProgress = null,
  12. fakeImage = null,
  13. videoNode = null,
  14. quizzesList = [],
  15. currentMarkers = [],
  16. colorDialog = editor.plugins.colordialog;
  17. function initPlayer(selectedElement) {
  18. fakeImage = selectedElement;
  19. if (!fakeImage ||
  20. !fakeImage.data( 'cke-real-element-type' ) ||
  21. fakeImage.data( 'cke-real-element-type' ) != 'video'
  22. ) {
  23. return;
  24. }
  25. videoNode = editor.restoreRealElement(fakeImage);
  26. var sourcesList = videoNode.getElementsByTag('source', '');
  27. if (sourcesList.count() === 0) {
  28. sourcesList = videoNode.getElementsByTag('source', 'cke');
  29. }
  30. if (sourcesList.count() === 0) {
  31. return;
  32. }
  33. var sourceNode = sourcesList.getItem(0);
  34. if (!sourceNode) {
  35. return;
  36. }
  37. pgbProgress = document.getElementById('ck-qmr-progress');
  38. pgbProgress.value = 0;
  39. pgbProgress.min = 0;
  40. pgbProgress.step = 1;
  41. pgbProgress.onchange = function () {
  42. player.currentTime = this.value;
  43. document.getElementById('ck-qmr-current-time').textContent = encodeTime(this.value);
  44. };
  45. var playerContainer = document.getElementById('ck-qmr-player-container');
  46. playerContainer.innerHTML = '';
  47. player = document.createElement('video');
  48. player.className = 'skip';
  49. player.controls = false;
  50. player.style.maxWidth = '100%';
  51. player.style.minWidth = '100%';
  52. player.onloadedmetadata = function () {
  53. pgbProgress.max = Math.floor(player.duration);
  54. playerContainer.appendChild(player);
  55. };
  56. player.src = sourceNode.getAttribute('src');
  57. }
  58. function decodeTime(time) {
  59. var parts = time.split(':');
  60. if (parts.length != 3) {
  61. return 0;
  62. }
  63. var hours = parseInt(parts[0]),
  64. minutes = parseInt(parts[1]),
  65. seconds = parseInt(parts[2]);
  66. if (seconds > 59 || minutes > 59) {
  67. return 0;
  68. }
  69. hours *= 60 * 60;
  70. minutes *= 60;
  71. return hours + minutes + seconds;
  72. }
  73. function encodeTime(time) {
  74. if (time < 60) {
  75. if (time < 10) {
  76. time = '0' + time;
  77. }
  78. return '00:00:' + time;
  79. }
  80. var hours = 0,
  81. minutes = Math.floor(time / 60),
  82. seconds = Math.floor(time % 60);
  83. if (minutes > 60) {
  84. hours = Math.floor(minutes / 60);
  85. minutes = minutes - (hours * 60);
  86. }
  87. return (hours < 10 ? '0' + hours : hours) + ':'
  88. + (minutes < 10 ? '0' + minutes : minutes) + ':'
  89. + (seconds < 10 ? '0' + seconds : seconds);
  90. }
  91. function displayQuizzes() {
  92. var container = document.getElementById('ck-qmr-quizzes-container');
  93. container.innerHTML = '';
  94. quizzesList.forEach(function (quiz) {
  95. var alreadyAdded = false;
  96. currentMarkers.forEach(function (markerRoll) {
  97. if (quiz.id == markerRoll[1]) {
  98. alreadyAdded = true;
  99. }
  100. });
  101. if (alreadyAdded) {
  102. return;
  103. }
  104. var label = document.createElement('label');
  105. label.textContent = quiz.title;
  106. label.htmlFor = 'ck-qmr-quiz-' + quiz.id;
  107. label.style.verticalAlign = 'super';
  108. var radio = document.createElement('input');
  109. radio.type = 'radio';
  110. radio.name = 'ck_qmr_quiz';
  111. radio.id = 'ck-qmr-quiz-' + quiz.id;
  112. radio.value = quiz.id;
  113. var row = document.createElement('div');
  114. row.appendChild(radio);
  115. row.appendChild(label);
  116. container.appendChild(row);
  117. });
  118. }
  119. function displayCurrentMarkersList() {
  120. var quizzesAddedContainer = document.getElementById('ck-qmr-quizzes-added-container');
  121. quizzesAddedContainer.innerHTML = '';
  122. currentMarkers.forEach(function (markerRoll) {
  123. var makerForQuiz = null;
  124. quizzesList.forEach(function (quiz) {
  125. if (markerRoll[1] == quiz.id) {
  126. makerForQuiz = quiz;
  127. }
  128. });
  129. if (!makerForQuiz) {
  130. return;
  131. }
  132. var btnRemove = document.createElement('a');
  133. btnRemove.className = 'cke_dialog_ui_button';
  134. btnRemove.type = 'button';
  135. btnRemove.innerHTML = '<span class="cke_dialog_ui_button">' + lang.delete + '</span>';
  136. btnRemove.setAttribute('role', 'button');
  137. btnRemove.addEventListener('click', function (e) {
  138. e.preventDefault();
  139. e.stopPropagation();
  140. for (var i = 0; i < currentMarkers.length; i++) {
  141. if (currentMarkers[i][1] == markerRoll[1]) {
  142. currentMarkers.splice(i, 1);
  143. i--;
  144. }
  145. }
  146. displayQuizzes();
  147. displayCurrentMarkersList();
  148. }, false);
  149. var divMarker = document.createElement('span');
  150. divMarker.innerHTML = ' <strong>' + encodeTime(markerRoll[0]) + '</strong> &mdash; '
  151. + makerForQuiz.title;
  152. var pMarker = document.createElement('p');
  153. pMarker.appendChild(btnRemove);
  154. pMarker.appendChild(divMarker);
  155. quizzesAddedContainer.appendChild(pMarker);
  156. });
  157. }
  158. return {
  159. title: lang.dialogTitle,
  160. minWidth: 400,
  161. minHeight: 500,
  162. resizable: CKEDITOR.DIALOG_RESIZE_NONE,
  163. contents: [
  164. {
  165. id: 'tab-markers',
  166. label: lang.markers,
  167. elements: [
  168. {
  169. type: 'vbox',
  170. width: '100%',
  171. children: [
  172. {
  173. type: 'html',
  174. id: 'html',
  175. html: '<div id="ck-qmr-player-container"></div>'
  176. },
  177. {
  178. type: 'hbox',
  179. widths: ['100%', '200px'],
  180. children: [
  181. {
  182. type: 'html',
  183. html: '<input type="range" min="0" step="1" id="ck-qmr-progress">'
  184. },
  185. {
  186. type: 'html',
  187. title: 'Current Time',
  188. html: '<span id="ck-qmr-current-time">00:00:00</span>'
  189. },
  190. ]
  191. },
  192. {
  193. type: 'hbox',
  194. widths: ['100%', '200px'],
  195. children: [
  196. {
  197. type: 'html',
  198. html: lang.embeddableQuizzes + ' '
  199. + '<div id="ck-qmr-quizzes-container" '
  200. + 'style="max-height: 110px; overflow: hidden auto;"></div>'
  201. },
  202. {
  203. type: 'button',
  204. id: 'btn-assign',
  205. label: lang.assignQuiz,
  206. title: lang.assignQuiz,
  207. onClick: function () {
  208. var radioQuizzes = document.getElementsByName('ck_qmr_quiz'),
  209. selected = null;
  210. radioQuizzes.forEach(function (radio) {
  211. if (!radio.checked) {
  212. return;
  213. }
  214. selected = radio;
  215. });
  216. if (!selected) {
  217. return;
  218. }
  219. currentMarkers.push([
  220. parseInt(pgbProgress.value),
  221. parseInt(selected.value)
  222. ]);
  223. displayCurrentMarkersList();
  224. selected.parentElement.remove();
  225. }
  226. }
  227. ]
  228. },
  229. {
  230. type: 'html',
  231. html: lang.currentMarkers + ' '
  232. + '<div id="ck-qmr-quizzes-added-container" '
  233. + 'style="max-height: 140px; overflow: hidden auto;"></div>'
  234. }
  235. ]
  236. },
  237. ]
  238. },
  239. {
  240. id: 'tab-settings',
  241. label: lang.settings,
  242. elements: [
  243. {
  244. type: 'hbox',
  245. widths: ['200px', '100%'],
  246. children: [
  247. {
  248. type: 'text',
  249. id: 'markerColor',
  250. label: lang.markerColor,
  251. 'default': '',
  252. setup: function (widget) {
  253. this.setValue(widget.getAttribute('data-q-markersrolls-color'));
  254. },
  255. commit: function (widget) {
  256. widget.setAttribute('data-q-markersrolls-color', this.getValue());
  257. }
  258. },
  259. colorDialog ? {
  260. type: 'button',
  261. id: 'markerColorChoose',
  262. 'class': 'colorChooser',
  263. label: lang.choose,
  264. onLoad: function() {
  265. // Stick the element to the bottom
  266. this.getElement()
  267. .getParent()
  268. .setStyle('vertical-align', 'bottom');
  269. },
  270. onClick: function () {
  271. editor.getColorFromDialog(function (color) {
  272. if (color) {
  273. this.getDialog()
  274. .getContentElement('tab-settings', 'markerColor')
  275. .setValue(color);
  276. }
  277. this.focus();
  278. }, this)
  279. }
  280. } : {
  281. type: 'html',
  282. html: '&nbsp;'
  283. }
  284. ]
  285. },
  286. ]
  287. },
  288. ],
  289. onShow: function () {
  290. var dialog = this;
  291. document.getElementById('ck-qmr-quizzes-container').innerHTML = '';
  292. initPlayer(
  293. dialog.getSelectedElement()
  294. );
  295. currentMarkers = JSON.parse(
  296. videoNode.getAttribute('data-q-markersrolls') || '[]'
  297. );
  298. CKEDITOR.ajax.load(
  299. editor.config.qMarkersRollsUrl,
  300. function (response) {
  301. quizzesList = JSON.parse(response);
  302. displayQuizzes();
  303. displayCurrentMarkersList();
  304. dialog.setupContent(videoNode);
  305. }
  306. );
  307. },
  308. onHide: function () {
  309. player = null;
  310. pgbProgress = null;
  311. },
  312. onOk: function () {
  313. if (!fakeImage) {
  314. return;
  315. }
  316. this.commitContent(videoNode);
  317. videoNode.setAttribute('data-q-markersrolls', JSON.stringify(currentMarkers));
  318. var newFakeImage = editor.createFakeElement(videoNode, 'cke_video', 'video', false);
  319. newFakeImage.setStyles({
  320. width: fakeImage.getStyle('width'),
  321. height: fakeImage.getStyle('height')
  322. });
  323. newFakeImage.replace(fakeImage);
  324. editor.getSelection().selectElement(newFakeImage);
  325. }
  326. };
  327. });