media.js 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503
  1. (function() {
  2. var url;
  3. if (url = tinyMCEPopup.getParam("media_external_list_url"))
  4. document.write('<script language="javascript" type="text/javascript" src="' + tinyMCEPopup.editor.documentBaseURI.toAbsolute(url) + '"></script>');
  5. function get(id) {
  6. return document.getElementById(id);
  7. }
  8. function clone(obj) {
  9. var i, len, copy, attr;
  10. if (null == obj || "object" != typeof obj)
  11. return obj;
  12. // Handle Array
  13. if ('length' in obj) {
  14. copy = [];
  15. for (i = 0, len = obj.length; i < len; ++i) {
  16. copy[i] = clone(obj[i]);
  17. }
  18. return copy;
  19. }
  20. // Handle Object
  21. copy = {};
  22. for (attr in obj) {
  23. if (obj.hasOwnProperty(attr))
  24. copy[attr] = clone(obj[attr]);
  25. }
  26. return copy;
  27. }
  28. function getVal(id) {
  29. var elm = get(id);
  30. if (elm.nodeName == "SELECT")
  31. return elm.options[elm.selectedIndex].value;
  32. if (elm.type == "checkbox")
  33. return elm.checked;
  34. return elm.value;
  35. }
  36. function setVal(id, value, name) {
  37. if (typeof(value) != 'undefined' && value != null) {
  38. var elm = get(id);
  39. if (elm.nodeName == "SELECT")
  40. selectByValue(document.forms[0], id, value);
  41. else if (elm.type == "checkbox") {
  42. if (typeof(value) == 'string') {
  43. value = value.toLowerCase();
  44. value = (!name && value === 'true') || (name && value === name.toLowerCase());
  45. }
  46. elm.checked = !!value;
  47. } else
  48. elm.value = value;
  49. }
  50. }
  51. window.Media = {
  52. init : function() {
  53. var html, editor, self = this;
  54. self.editor = editor = tinyMCEPopup.editor;
  55. // Setup file browsers and color pickers
  56. get('filebrowsercontainer').innerHTML = getBrowserHTML('filebrowser','src','media','media');
  57. get('qtsrcfilebrowsercontainer').innerHTML = getBrowserHTML('qtsrcfilebrowser','quicktime_qtsrc','media','media');
  58. get('bgcolor_pickcontainer').innerHTML = getColorPickerHTML('bgcolor_pick','bgcolor');
  59. get('video_altsource1_filebrowser').innerHTML = getBrowserHTML('video_filebrowser_altsource1','video_altsource1','media','media');
  60. get('video_altsource2_filebrowser').innerHTML = getBrowserHTML('video_filebrowser_altsource2','video_altsource2','media','media');
  61. get('audio_altsource1_filebrowser').innerHTML = getBrowserHTML('audio_filebrowser_altsource1','audio_altsource1','media','media');
  62. get('audio_altsource2_filebrowser').innerHTML = getBrowserHTML('audio_filebrowser_altsource2','audio_altsource2','media','media');
  63. get('video_poster_filebrowser').innerHTML = getBrowserHTML('filebrowser_poster','video_poster','image','media');
  64. html = self.getMediaListHTML('medialist', 'src', 'media', 'media');
  65. if (html == "")
  66. get("linklistrow").style.display = 'none';
  67. else
  68. get("linklistcontainer").innerHTML = html;
  69. if (isVisible('filebrowser'))
  70. get('src').style.width = '230px';
  71. if (isVisible('video_filebrowser_altsource1'))
  72. get('video_altsource1').style.width = '220px';
  73. if (isVisible('video_filebrowser_altsource2'))
  74. get('video_altsource2').style.width = '220px';
  75. if (isVisible('audio_filebrowser_altsource1'))
  76. get('audio_altsource1').style.width = '220px';
  77. if (isVisible('audio_filebrowser_altsource2'))
  78. get('audio_altsource2').style.width = '220px';
  79. if (isVisible('filebrowser_poster'))
  80. get('video_poster').style.width = '220px';
  81. editor.dom.setOuterHTML(get('media_type'), self.getMediaTypeHTML(editor));
  82. self.setDefaultDialogSettings(editor);
  83. self.data = clone(tinyMCEPopup.getWindowArg('data'));
  84. self.dataToForm();
  85. self.preview();
  86. updateColor('bgcolor_pick', 'bgcolor');
  87. },
  88. insert : function() {
  89. var editor = tinyMCEPopup.editor;
  90. this.formToData();
  91. editor.execCommand('mceRepaint');
  92. tinyMCEPopup.restoreSelection();
  93. editor.selection.setNode(editor.plugins.media.dataToImg(this.data));
  94. tinyMCEPopup.close();
  95. },
  96. preview : function() {
  97. get('prev').innerHTML = this.editor.plugins.media.dataToHtml(this.data, true);
  98. },
  99. moveStates : function(to_form, field) {
  100. var data = this.data, editor = this.editor,
  101. mediaPlugin = editor.plugins.media, ext, src, typeInfo, defaultStates, src;
  102. defaultStates = {
  103. // QuickTime
  104. quicktime_autoplay : true,
  105. quicktime_controller : true,
  106. // Flash
  107. flash_play : true,
  108. flash_loop : true,
  109. flash_menu : true,
  110. // WindowsMedia
  111. windowsmedia_autostart : true,
  112. windowsmedia_enablecontextmenu : true,
  113. windowsmedia_invokeurls : true,
  114. // RealMedia
  115. realmedia_autogotourl : true,
  116. realmedia_imagestatus : true
  117. };
  118. function parseQueryParams(str) {
  119. var out = {};
  120. if (str) {
  121. tinymce.each(str.split('&'), function(item) {
  122. var parts = item.split('=');
  123. out[unescape(parts[0])] = unescape(parts[1]);
  124. });
  125. }
  126. return out;
  127. };
  128. function setOptions(type, names) {
  129. var i, name, formItemName, value, list;
  130. if (type == data.type || type == 'global') {
  131. names = tinymce.explode(names);
  132. for (i = 0; i < names.length; i++) {
  133. name = names[i];
  134. formItemName = type == 'global' ? name : type + '_' + name;
  135. if (type == 'global')
  136. list = data;
  137. else if (type == 'video' || type == 'audio') {
  138. list = data.video.attrs;
  139. if (!list && !to_form)
  140. data.video.attrs = list = {};
  141. } else
  142. list = data.params;
  143. if (list) {
  144. if (to_form) {
  145. setVal(formItemName, list[name], type == 'video' || type == 'audio' ? name : '');
  146. } else {
  147. delete list[name];
  148. value = getVal(formItemName);
  149. if ((type == 'video' || type == 'audio') && value === true)
  150. value = name;
  151. if (defaultStates[formItemName]) {
  152. if (value !== defaultStates[formItemName]) {
  153. value = "" + value;
  154. list[name] = value;
  155. }
  156. } else if (value) {
  157. value = "" + value;
  158. list[name] = value;
  159. }
  160. }
  161. }
  162. }
  163. }
  164. }
  165. if (!to_form) {
  166. data.type = get('media_type').options[get('media_type').selectedIndex].value;
  167. data.width = getVal('width');
  168. data.height = getVal('height');
  169. // Switch type based on extension
  170. src = getVal('src');
  171. if (field == 'src') {
  172. ext = src.replace(/^.*\.([^.]+)$/, '$1');
  173. if (typeInfo = mediaPlugin.getType(ext))
  174. data.type = typeInfo.name.toLowerCase();
  175. setVal('media_type', data.type);
  176. }
  177. if (data.type == "video" || data.type == "audio") {
  178. if (!data.video.sources)
  179. data.video.sources = [];
  180. data.video.sources[0] = {src: getVal('src')};
  181. }
  182. }
  183. // Hide all fieldsets and show the one active
  184. get('video_options').style.display = 'none';
  185. get('audio_options').style.display = 'none';
  186. get('flash_options').style.display = 'none';
  187. get('quicktime_options').style.display = 'none';
  188. get('shockwave_options').style.display = 'none';
  189. get('windowsmedia_options').style.display = 'none';
  190. get('realmedia_options').style.display = 'none';
  191. get('embeddedaudio_options').style.display = 'none';
  192. if (get(data.type + '_options'))
  193. get(data.type + '_options').style.display = 'block';
  194. setVal('media_type', data.type);
  195. setOptions('flash', 'play,loop,menu,swliveconnect,quality,scale,salign,wmode,base,flashvars');
  196. setOptions('quicktime', 'loop,autoplay,cache,controller,correction,enablejavascript,kioskmode,autohref,playeveryframe,targetcache,scale,starttime,endtime,target,qtsrcchokespeed,volume,qtsrc');
  197. setOptions('shockwave', 'sound,progress,autostart,swliveconnect,swvolume,swstretchstyle,swstretchhalign,swstretchvalign');
  198. setOptions('windowsmedia', 'autostart,enabled,enablecontextmenu,fullscreen,invokeurls,mute,stretchtofit,windowlessvideo,balance,baseurl,captioningid,currentmarker,currentposition,defaultframe,playcount,rate,uimode,volume');
  199. setOptions('realmedia', 'autostart,loop,autogotourl,center,imagestatus,maintainaspect,nojava,prefetch,shuffle,console,controls,numloop,scriptcallbacks');
  200. setOptions('video', 'poster,autoplay,loop,muted,preload,controls');
  201. setOptions('audio', 'autoplay,loop,preload,controls');
  202. setOptions('embeddedaudio', 'autoplay,loop,controls');
  203. setOptions('global', 'id,name,vspace,hspace,bgcolor,align,width,height');
  204. if (to_form) {
  205. if (data.type == 'video') {
  206. if (data.video.sources[0])
  207. setVal('src', data.video.sources[0].src);
  208. src = data.video.sources[1];
  209. if (src)
  210. setVal('video_altsource1', src.src);
  211. src = data.video.sources[2];
  212. if (src)
  213. setVal('video_altsource2', src.src);
  214. } else if (data.type == 'audio') {
  215. if (data.video.sources[0])
  216. setVal('src', data.video.sources[0].src);
  217. src = data.video.sources[1];
  218. if (src)
  219. setVal('audio_altsource1', src.src);
  220. src = data.video.sources[2];
  221. if (src)
  222. setVal('audio_altsource2', src.src);
  223. } else {
  224. // Check flash vars
  225. if (data.type == 'flash') {
  226. tinymce.each(editor.getParam('flash_video_player_flashvars', {url : '$url', poster : '$poster'}), function(value, name) {
  227. if (value == '$url')
  228. data.params.src = parseQueryParams(data.params.flashvars)[name] || data.params.src || '';
  229. });
  230. }
  231. setVal('src', data.params.src);
  232. }
  233. } else {
  234. src = getVal("src");
  235. // YouTube *NEW*
  236. if (src.match(/youtu.be\/[a-z1-9.-_]+/)) {
  237. data.width = 425;
  238. data.height = 350;
  239. data.params.frameborder = '0';
  240. data.type = 'iframe';
  241. src = 'http://www.youtube.com/embed/' + src.match(/youtu.be\/([a-z1-9.-_]+)/)[1];
  242. setVal('src', src);
  243. setVal('media_type', data.type);
  244. }
  245. // YouTube
  246. if (src.match(/youtube.com(.+)v=([^&]+)/)) {
  247. data.width = 425;
  248. data.height = 350;
  249. data.params.frameborder = '0';
  250. data.type = 'iframe';
  251. src = 'http://www.youtube.com/embed/' + src.match(/v=([^&]+)/)[1];
  252. setVal('src', src);
  253. setVal('media_type', data.type);
  254. }
  255. // Google video
  256. if (src.match(/video.google.com(.+)docid=([^&]+)/)) {
  257. data.width = 425;
  258. data.height = 326;
  259. data.type = 'flash';
  260. src = 'http://video.google.com/googleplayer.swf?docId=' + src.match(/docid=([^&]+)/)[1] + '&hl=en';
  261. setVal('src', src);
  262. setVal('media_type', data.type);
  263. }
  264. // Vimeo
  265. if (src.match(/vimeo.com\/([0-9]+)/)) {
  266. data.width = 425;
  267. data.height = 350;
  268. data.params.frameborder = '0';
  269. data.type = 'iframe';
  270. src = 'http://player.vimeo.com/video/' + src.match(/vimeo.com\/([0-9]+)/)[1];
  271. setVal('src', src);
  272. setVal('media_type', data.type);
  273. }
  274. // stream.cz
  275. if (src.match(/stream.cz\/((?!object).)*\/([0-9]+)/)) {
  276. data.width = 425;
  277. data.height = 350;
  278. data.params.frameborder = '0';
  279. data.type = 'iframe';
  280. src = 'http://www.stream.cz/object/' + src.match(/stream.cz\/[^/]+\/([0-9]+)/)[1];
  281. setVal('src', src);
  282. setVal('media_type', data.type);
  283. }
  284. // Google maps
  285. if (src.match(/maps.google.([a-z]{2,3})\/maps\/(.+)msid=(.+)/)) {
  286. data.width = 425;
  287. data.height = 350;
  288. data.params.frameborder = '0';
  289. data.type = 'iframe';
  290. src = 'http://maps.google.com/maps/ms?msid=' + src.match(/msid=(.+)/)[1] + "&output=embed";
  291. setVal('src', src);
  292. setVal('media_type', data.type);
  293. }
  294. if (data.type == 'video') {
  295. if (!data.video.sources)
  296. data.video.sources = [];
  297. data.video.sources[0] = {src : src};
  298. src = getVal("video_altsource1");
  299. if (src)
  300. data.video.sources[1] = {src : src};
  301. src = getVal("video_altsource2");
  302. if (src)
  303. data.video.sources[2] = {src : src};
  304. } else if (data.type == 'audio') {
  305. if (!data.video.sources)
  306. data.video.sources = [];
  307. data.video.sources[0] = {src : src};
  308. src = getVal("audio_altsource1");
  309. if (src)
  310. data.video.sources[1] = {src : src};
  311. src = getVal("audio_altsource2");
  312. if (src)
  313. data.video.sources[2] = {src : src};
  314. } else
  315. data.params.src = src;
  316. // Set default size
  317. setVal('width', data.width || (data.type == 'audio' ? 300 : 320));
  318. setVal('height', data.height || (data.type == 'audio' ? 32 : 240));
  319. }
  320. },
  321. dataToForm : function() {
  322. this.moveStates(true);
  323. },
  324. formToData : function(field) {
  325. if (field == "width" || field == "height")
  326. this.changeSize(field);
  327. if (field == 'source') {
  328. this.moveStates(false, field);
  329. setVal('source', this.editor.plugins.media.dataToHtml(this.data));
  330. this.panel = 'source';
  331. } else {
  332. if (this.panel == 'source') {
  333. this.data = clone(this.editor.plugins.media.htmlToData(getVal('source')));
  334. this.dataToForm();
  335. this.panel = '';
  336. }
  337. this.moveStates(false, field);
  338. this.preview();
  339. }
  340. },
  341. beforeResize : function() {
  342. this.width = parseInt(getVal('width') || (this.data.type == 'audio' ? "300" : "320"), 10);
  343. this.height = parseInt(getVal('height') || (this.data.type == 'audio' ? "32" : "240"), 10);
  344. },
  345. changeSize : function(type) {
  346. var width, height, scale, size;
  347. if (get('constrain').checked) {
  348. width = parseInt(getVal('width') || (this.data.type == 'audio' ? "300" : "320"), 10);
  349. height = parseInt(getVal('height') || (this.data.type == 'audio' ? "32" : "240"), 10);
  350. if (type == 'width') {
  351. this.height = Math.round((width / this.width) * height);
  352. setVal('height', this.height);
  353. } else {
  354. this.width = Math.round((height / this.height) * width);
  355. setVal('width', this.width);
  356. }
  357. }
  358. },
  359. getMediaListHTML : function() {
  360. if (typeof(tinyMCEMediaList) != "undefined" && tinyMCEMediaList.length > 0) {
  361. var html = "";
  362. html += '<select id="linklist" name="linklist" style="width: 250px" onchange="this.form.src.value=this.options[this.selectedIndex].value;Media.formToData(\'src\');">';
  363. html += '<option value="">---</option>';
  364. for (var i=0; i<tinyMCEMediaList.length; i++)
  365. html += '<option value="' + tinyMCEMediaList[i][1] + '">' + tinyMCEMediaList[i][0] + '</option>';
  366. html += '</select>';
  367. return html;
  368. }
  369. return "";
  370. },
  371. getMediaTypeHTML : function(editor) {
  372. function option(media_type, element) {
  373. if (!editor.schema.getElementRule(element || media_type)) {
  374. return '';
  375. }
  376. return '<option value="'+media_type+'">'+tinyMCEPopup.editor.translate("media_dlg."+media_type)+'</option>'
  377. }
  378. var html = "";
  379. html += '<select id="media_type" name="media_type" onchange="Media.formToData(\'type\');">';
  380. html += option("video");
  381. html += option("audio");
  382. html += option("flash", "object");
  383. html += option("quicktime", "object");
  384. html += option("shockwave", "object");
  385. html += option("windowsmedia", "object");
  386. html += option("realmedia", "object");
  387. html += option("iframe");
  388. if (editor.getParam('media_embedded_audio', false)) {
  389. html += option('embeddedaudio', "object");
  390. }
  391. html += '</select>';
  392. return html;
  393. },
  394. setDefaultDialogSettings : function(editor) {
  395. var defaultDialogSettings = editor.getParam("media_dialog_defaults", {});
  396. tinymce.each(defaultDialogSettings, function(v, k) {
  397. setVal(k, v);
  398. });
  399. }
  400. };
  401. tinyMCEPopup.requireLangPack();
  402. tinyMCEPopup.onInit.add(function() {
  403. Media.init();
  404. });
  405. })();