video.js 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. CKEDITOR.dialog.add( 'video', function ( editor )
  2. {
  3. var lang = editor.lang.video;
  4. function commitValue( videoNode, extraStyles )
  5. {
  6. var value=this.getValue();
  7. if ( !value && this.id=='id' )
  8. value = generateId();
  9. videoNode.setAttribute( this.id, value);
  10. if ( !value )
  11. return;
  12. switch( this.id )
  13. {
  14. case 'poster':
  15. extraStyles.backgroundImage = 'url(' + value + ')';
  16. break;
  17. case 'width':
  18. extraStyles.width = value + 'px';
  19. break;
  20. case 'height':
  21. extraStyles.height = value + 'px';
  22. break;
  23. }
  24. }
  25. function commitSrc( videoNode, extraStyles, videos )
  26. {
  27. var match = this.id.match(/(\w+)(\d)/),
  28. id = match[1],
  29. number = parseInt(match[2], 10);
  30. var video = videos[number] || (videos[number]={});
  31. video[id] = this.getValue();
  32. }
  33. function loadValue( videoNode )
  34. {
  35. if ( videoNode )
  36. this.setValue( videoNode.getAttribute( this.id ) );
  37. else
  38. {
  39. if ( this.id == 'id')
  40. this.setValue( generateId() );
  41. }
  42. }
  43. function loadSrc( videoNode, videos )
  44. {
  45. var match = this.id.match(/(\w+)(\d)/),
  46. id = match[1],
  47. number = parseInt(match[2], 10);
  48. var video = videos[number];
  49. if (!video)
  50. return;
  51. this.setValue( video[ id ] );
  52. }
  53. function generateId()
  54. {
  55. var now = new Date();
  56. return 'video' + now.getFullYear() + now.getMonth() + now.getDate() + now.getHours() + now.getMinutes() + now.getSeconds();
  57. }
  58. // To automatically get the dimensions of the poster image
  59. var onImgLoadEvent = function()
  60. {
  61. // Image is ready.
  62. var preview = this.previewImage;
  63. preview.removeListener( 'load', onImgLoadEvent );
  64. preview.removeListener( 'error', onImgLoadErrorEvent );
  65. preview.removeListener( 'abort', onImgLoadErrorEvent );
  66. this.setValueOf( 'info', 'width', preview.$.width );
  67. this.setValueOf( 'info', 'height', preview.$.height );
  68. };
  69. var onImgLoadErrorEvent = function()
  70. {
  71. // Error. Image is not loaded.
  72. var preview = this.previewImage;
  73. preview.removeListener( 'load', onImgLoadEvent );
  74. preview.removeListener( 'error', onImgLoadErrorEvent );
  75. preview.removeListener( 'abort', onImgLoadErrorEvent );
  76. };
  77. return {
  78. title : lang.dialogTitle,
  79. minWidth : 400,
  80. minHeight : 200,
  81. onShow : function()
  82. {
  83. // Clear previously saved elements.
  84. this.fakeImage = this.videoNode = null;
  85. // To get dimensions of poster image
  86. this.previewImage = editor.document.createElement( 'img' );
  87. var fakeImage = this.getSelectedElement();
  88. if ( fakeImage && fakeImage.data( 'cke-real-element-type' ) && fakeImage.data( 'cke-real-element-type' ) == 'video' )
  89. {
  90. this.fakeImage = fakeImage;
  91. var videoNode = editor.restoreRealElement( fakeImage ),
  92. videos = [],
  93. sourceList = videoNode.getElementsByTag( 'source', '' );
  94. if (sourceList.count()==0)
  95. sourceList = videoNode.getElementsByTag( 'source', 'cke' );
  96. for ( var i = 0, length = sourceList.count() ; i < length ; i++ )
  97. {
  98. var item = sourceList.getItem( i );
  99. videos.push( {src : item.getAttribute( 'src' ), type: item.getAttribute( 'type' )} );
  100. }
  101. this.videoNode = videoNode;
  102. this.setupContent( videoNode, videos );
  103. }
  104. else
  105. this.setupContent( null, [] );
  106. },
  107. onOk : function()
  108. {
  109. // If there's no selected element create one. Otherwise, reuse it
  110. var videoNode = null;
  111. if ( !this.fakeImage )
  112. {
  113. videoNode = CKEDITOR.dom.element.createFromHtml( '<cke:video></cke:video>', editor.document );
  114. videoNode.setAttributes(
  115. {
  116. controls : 'controls'
  117. } );
  118. }
  119. else
  120. {
  121. videoNode = this.videoNode;
  122. }
  123. var extraStyles = {}, videos = [];
  124. this.commitContent( videoNode, extraStyles, videos );
  125. var innerHtml = '', links = '',
  126. link = lang.linkTemplate || '',
  127. fallbackTemplate = lang.fallbackTemplate || '';
  128. for(var i=0; i<videos.length; i++)
  129. {
  130. var video = videos[i];
  131. if ( !video || !video.src )
  132. continue;
  133. innerHtml += '<cke:source src="' + video.src + '" type="' + video.type + '" />';
  134. links += link.replace('%src%', video.src).replace('%type%', video.type);
  135. }
  136. videoNode.setHtml( innerHtml + fallbackTemplate.replace( '%links%', links ) );
  137. // Refresh the fake image.
  138. var newFakeImage = editor.createFakeElement( videoNode, 'cke_video', 'video', false );
  139. newFakeImage.setStyles( extraStyles );
  140. if ( this.fakeImage )
  141. {
  142. newFakeImage.replace( this.fakeImage );
  143. editor.getSelection().selectElement( newFakeImage );
  144. }
  145. else
  146. {
  147. // Insert it in a div
  148. var div = new CKEDITOR.dom.element( 'DIV', editor.document );
  149. editor.insertElement( div );
  150. div.append( newFakeImage );
  151. }
  152. },
  153. onHide : function()
  154. {
  155. if ( this.previewImage )
  156. {
  157. this.previewImage.removeListener( 'load', onImgLoadEvent );
  158. this.previewImage.removeListener( 'error', onImgLoadErrorEvent );
  159. this.previewImage.removeListener( 'abort', onImgLoadErrorEvent );
  160. this.previewImage.remove();
  161. this.previewImage = null; // Dialog is closed.
  162. }
  163. },
  164. contents :
  165. [
  166. {
  167. id : 'info',
  168. elements :
  169. [
  170. {
  171. type : 'hbox',
  172. widths: [ '', '100px'],
  173. children : [
  174. {
  175. type : 'text',
  176. id : 'poster',
  177. label : lang.poster,
  178. commit : commitValue,
  179. setup : loadValue,
  180. onChange : function()
  181. {
  182. var dialog = this.getDialog(),
  183. newUrl = this.getValue();
  184. //Update preview image
  185. if ( newUrl.length > 0 ) //Prevent from load before onShow
  186. {
  187. dialog = this.getDialog();
  188. var preview = dialog.previewImage;
  189. preview.on( 'load', onImgLoadEvent, dialog );
  190. preview.on( 'error', onImgLoadErrorEvent, dialog );
  191. preview.on( 'abort', onImgLoadErrorEvent, dialog );
  192. preview.setAttribute( 'src', newUrl );
  193. }
  194. }
  195. },
  196. {
  197. type : 'button',
  198. id : 'browse',
  199. hidden : 'true',
  200. style : 'display:inline-block;margin-top:10px;',
  201. filebrowser :
  202. {
  203. action : 'Browse',
  204. target: 'info:poster',
  205. url: editor.config.filebrowserImageBrowseUrl || editor.config.filebrowserBrowseUrl
  206. },
  207. label : editor.lang.common.browseServer
  208. }]
  209. },
  210. {
  211. type : 'hbox',
  212. widths: [ '33%', '33%', '33%'],
  213. children : [
  214. {
  215. type : 'text',
  216. id : 'width',
  217. label : editor.lang.common.width,
  218. 'default' : 400,
  219. validate : CKEDITOR.dialog.validate.notEmpty( lang.widthRequired ),
  220. commit : commitValue,
  221. setup : loadValue
  222. },
  223. {
  224. type : 'text',
  225. id : 'height',
  226. label : editor.lang.common.height,
  227. 'default' : 300,
  228. validate : CKEDITOR.dialog.validate.notEmpty(lang.heightRequired ),
  229. commit : commitValue,
  230. setup : loadValue
  231. },
  232. {
  233. type : 'text',
  234. id : 'id',
  235. label : 'Id',
  236. commit : commitValue,
  237. setup : loadValue
  238. }
  239. ]
  240. },
  241. {
  242. type : 'hbox',
  243. widths: [ '', '100px', '75px'],
  244. children : [
  245. {
  246. type : 'text',
  247. id : 'src0',
  248. label : lang.sourceVideo,
  249. commit : commitSrc,
  250. setup : loadSrc
  251. },
  252. {
  253. type : 'button',
  254. id : 'browse',
  255. hidden : 'true',
  256. style : 'display:inline-block;margin-top:10px;',
  257. filebrowser :
  258. {
  259. action : 'Browse',
  260. target: 'info:src0',
  261. url: editor.config.filebrowserVideoBrowseUrl || editor.config.filebrowserBrowseUrl
  262. },
  263. label : editor.lang.common.browseServer
  264. },
  265. {
  266. id : 'type0',
  267. label : lang.sourceType,
  268. type : 'select',
  269. 'default' : 'video/mp4',
  270. items :
  271. [
  272. [ 'MP4', 'video/mp4' ],
  273. [ 'WebM', 'video/webm' ]
  274. ],
  275. commit : commitSrc,
  276. setup : loadSrc
  277. }]
  278. },
  279. {
  280. type : 'hbox',
  281. widths: [ '', '100px', '75px'],
  282. children : [
  283. {
  284. type : 'text',
  285. id : 'src1',
  286. label : lang.sourceVideo,
  287. commit : commitSrc,
  288. setup : loadSrc
  289. },
  290. {
  291. type : 'button',
  292. id : 'browse',
  293. hidden : 'true',
  294. style : 'display:inline-block;margin-top:10px;',
  295. filebrowser :
  296. {
  297. action : 'Browse',
  298. target: 'info:src1',
  299. url: editor.config.filebrowserVideoBrowseUrl || editor.config.filebrowserBrowseUrl
  300. },
  301. label : editor.lang.common.browseServer
  302. },
  303. {
  304. id : 'type1',
  305. label : lang.sourceType,
  306. type : 'select',
  307. 'default':'video/webm',
  308. items :
  309. [
  310. [ 'MP4', 'video/mp4' ],
  311. [ 'WebM', 'video/webm' ]
  312. ],
  313. commit : commitSrc,
  314. setup : loadSrc
  315. }]
  316. }
  317. ]
  318. }
  319. ]
  320. };
  321. } );