PageRenderTime 49ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 1ms

/BlogEngine/BlogEngine.NET/editors/tiny_mce_3_4_3_1/plugins/media/editor_plugin_src.js

#
JavaScript | 777 lines | 535 code | 146 blank | 96 comment | 148 complexity | 0fb95a737ee31355d8f663617b5904b3 MD5 | raw file
Possible License(s): LGPL-2.1, Apache-2.0, BSD-3-Clause
  1. /**
  2. * editor_plugin_src.js
  3. *
  4. * Copyright 2009, Moxiecode Systems AB
  5. * Released under LGPL License.
  6. *
  7. * License: http://tinymce.moxiecode.com/license
  8. * Contributing: http://tinymce.moxiecode.com/contributing
  9. */
  10. (function() {
  11. var rootAttributes = tinymce.explode('id,name,width,height,style,align,class,hspace,vspace,bgcolor,type'), excludedAttrs = tinymce.makeMap(rootAttributes.join(',')), Node = tinymce.html.Node,
  12. mediaTypes, scriptRegExp, JSON = tinymce.util.JSON, mimeTypes;
  13. // Media types supported by this plugin
  14. mediaTypes = [
  15. // Type, clsid:s, mime types, codebase
  16. ["Flash", "d27cdb6e-ae6d-11cf-96b8-444553540000", "application/x-shockwave-flash", "http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"],
  17. ["ShockWave", "166b1bca-3f9c-11cf-8075-444553540000", "application/x-director", "http://download.macromedia.com/pub/shockwave/cabs/director/sw.cab#version=8,5,1,0"],
  18. ["WindowsMedia", "6bf52a52-394a-11d3-b153-00c04f79faa6,22d6f312-b0f6-11d0-94ab-0080c74c7e95,05589fa1-c356-11ce-bf01-00aa0055595a", "application/x-mplayer2", "http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=5,1,52,701"],
  19. ["QuickTime", "02bf25d5-8c17-4b23-bc80-d3488abddc6b", "video/quicktime", "http://www.apple.com/qtactivex/qtplugin.cab#version=6,0,2,0"],
  20. ["RealMedia", "cfcdaa03-8be4-11cf-b84b-0020afbbccfa", "audio/x-pn-realaudio-plugin", "http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"],
  21. ["Java", "8ad9c840-044e-11d1-b3e9-00805f499d93", "application/x-java-applet", "http://java.sun.com/products/plugin/autodl/jinstall-1_5_0-windows-i586.cab#Version=1,5,0,0"],
  22. ["Silverlight", "dfeaf541-f3e1-4c24-acac-99c30715084a", "application/x-silverlight-2"],
  23. ["Iframe"],
  24. ["Video"]
  25. ];
  26. function toArray(obj) {
  27. var undef, out, i;
  28. if (obj && !obj.splice) {
  29. out = [];
  30. for (i = 0; true; i++) {
  31. if (obj[i])
  32. out[i] = obj[i];
  33. else
  34. break;
  35. }
  36. return out;
  37. }
  38. return obj;
  39. };
  40. tinymce.create('tinymce.plugins.MediaPlugin', {
  41. init : function(ed, url) {
  42. var self = this, lookup = {}, i, y, item, name;
  43. function isMediaImg(node) {
  44. return node && node.nodeName === 'IMG' && ed.dom.hasClass(node, 'mceItemMedia');
  45. };
  46. self.editor = ed;
  47. self.url = url;
  48. // Parse media types into a lookup table
  49. scriptRegExp = '';
  50. for (i = 0; i < mediaTypes.length; i++) {
  51. name = mediaTypes[i][0];
  52. item = {
  53. name : name,
  54. clsids : tinymce.explode(mediaTypes[i][1] || ''),
  55. mimes : tinymce.explode(mediaTypes[i][2] || ''),
  56. codebase : mediaTypes[i][3]
  57. };
  58. for (y = 0; y < item.clsids.length; y++)
  59. lookup['clsid:' + item.clsids[y]] = item;
  60. for (y = 0; y < item.mimes.length; y++)
  61. lookup[item.mimes[y]] = item;
  62. lookup['mceItem' + name] = item;
  63. lookup[name.toLowerCase()] = item;
  64. scriptRegExp += (scriptRegExp ? '|' : '') + name;
  65. }
  66. // Handle the media_types setting
  67. tinymce.each(ed.getParam("media_types",
  68. "video=mp4,m4v,ogv,webm;" +
  69. "silverlight=xap;" +
  70. "flash=swf,flv;" +
  71. "shockwave=dcr;" +
  72. "quicktime=mov,qt,mpg,mp3,mpeg;" +
  73. "shockwave=dcr;" +
  74. "windowsmedia=avi,wmv,wm,asf,asx,wmx,wvx;" +
  75. "realmedia=rm,ra,ram;" +
  76. "java=jar"
  77. ).split(';'), function(item) {
  78. var i, extensions, type;
  79. item = item.split(/=/);
  80. extensions = tinymce.explode(item[1].toLowerCase());
  81. for (i = 0; i < extensions.length; i++) {
  82. type = lookup[item[0].toLowerCase()];
  83. if (type)
  84. lookup[extensions[i]] = type;
  85. }
  86. });
  87. scriptRegExp = new RegExp('write(' + scriptRegExp + ')\\(([^)]+)\\)');
  88. self.lookup = lookup;
  89. ed.onPreInit.add(function() {
  90. // Allow video elements
  91. ed.schema.addValidElements('object[id|style|width|height|classid|codebase|*],param[name|value],embed[id|style|width|height|type|src|*],video[*],audio[*],source[*]');
  92. // Convert video elements to image placeholder
  93. ed.parser.addNodeFilter('object,embed,video,audio,script,iframe', function(nodes) {
  94. var i = nodes.length;
  95. while (i--)
  96. self.objectToImg(nodes[i]);
  97. });
  98. // Convert image placeholders to video elements
  99. ed.serializer.addNodeFilter('img', function(nodes, name, args) {
  100. var i = nodes.length, node;
  101. while (i--) {
  102. node = nodes[i];
  103. if ((node.attr('class') || '').indexOf('mceItemMedia') !== -1)
  104. self.imgToObject(node, args);
  105. }
  106. });
  107. });
  108. ed.onInit.add(function() {
  109. // Display "media" instead of "img" in element path
  110. if (ed.theme && ed.theme.onResolveName) {
  111. ed.theme.onResolveName.add(function(theme, path_object) {
  112. if (path_object.name === 'img' && ed.dom.hasClass(path_object.node, 'mceItemMedia'))
  113. path_object.name = 'media';
  114. });
  115. }
  116. // Add contect menu if it's loaded
  117. if (ed && ed.plugins.contextmenu) {
  118. ed.plugins.contextmenu.onContextMenu.add(function(plugin, menu, element) {
  119. if (element.nodeName === 'IMG' && element.className.indexOf('mceItemMedia') !== -1)
  120. menu.add({title : 'media.edit', icon : 'media', cmd : 'mceMedia'});
  121. });
  122. }
  123. });
  124. // Register commands
  125. ed.addCommand('mceMedia', function() {
  126. var data, img;
  127. img = ed.selection.getNode();
  128. if (isMediaImg(img)) {
  129. data = ed.dom.getAttrib(img, 'data-mce-json');
  130. if (data) {
  131. data = JSON.parse(data);
  132. // Add some extra properties to the data object
  133. tinymce.each(rootAttributes, function(name) {
  134. var value = ed.dom.getAttrib(img, name);
  135. if (value)
  136. data[name] = value;
  137. });
  138. data.type = self.getType(img.className).name.toLowerCase();
  139. }
  140. }
  141. if (!data) {
  142. data = {
  143. type : 'flash',
  144. video: {sources:[]},
  145. params: {}
  146. };
  147. }
  148. ed.windowManager.open({
  149. file : url + '/media.htm',
  150. width : 430 + parseInt(ed.getLang('media.delta_width', 0)),
  151. height : 500 + parseInt(ed.getLang('media.delta_height', 0)),
  152. inline : 1
  153. }, {
  154. plugin_url : url,
  155. data : data
  156. });
  157. });
  158. // Register buttons
  159. ed.addButton('media', {title : 'media.desc', cmd : 'mceMedia'});
  160. // Update media selection status
  161. ed.onNodeChange.add(function(ed, cm, node) {
  162. cm.setActive('media', isMediaImg(node));
  163. });
  164. },
  165. convertUrl : function(url, force_absolute) {
  166. var self = this, editor = self.editor, settings = editor.settings,
  167. urlConverter = settings.url_converter,
  168. urlConverterScope = settings.url_converter_scope || self;
  169. if (!url)
  170. return url;
  171. if (force_absolute)
  172. return editor.documentBaseURI.toAbsolute(url);
  173. return urlConverter.call(urlConverterScope, url, 'src', 'object');
  174. },
  175. getInfo : function() {
  176. return {
  177. longname : 'Media',
  178. author : 'Moxiecode Systems AB',
  179. authorurl : 'http://tinymce.moxiecode.com',
  180. infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/media',
  181. version : tinymce.majorVersion + "." + tinymce.minorVersion
  182. };
  183. },
  184. /**
  185. * Converts the JSON data object to an img node.
  186. */
  187. dataToImg : function(data, force_absolute) {
  188. var self = this, editor = self.editor, baseUri = editor.documentBaseURI, sources, attrs, img, i;
  189. data.params.src = self.convertUrl(data.params.src, force_absolute);
  190. attrs = data.video.attrs;
  191. if (attrs)
  192. attrs.src = self.convertUrl(attrs.src, force_absolute);
  193. if (attrs)
  194. attrs.poster = self.convertUrl(attrs.poster, force_absolute);
  195. sources = toArray(data.video.sources);
  196. if (sources) {
  197. for (i = 0; i < sources.length; i++)
  198. sources[i].src = self.convertUrl(sources[i].src, force_absolute);
  199. }
  200. img = self.editor.dom.create('img', {
  201. id : data.id,
  202. style : data.style,
  203. align : data.align,
  204. src : self.editor.theme.url + '/img/trans.gif',
  205. 'class' : 'mceItemMedia mceItem' + self.getType(data.type).name,
  206. 'data-mce-json' : JSON.serialize(data, "'")
  207. });
  208. img.width = data.width || "320";
  209. img.height = data.height || "240";
  210. return img;
  211. },
  212. /**
  213. * Converts the JSON data object to a HTML string.
  214. */
  215. dataToHtml : function(data, force_absolute) {
  216. return this.editor.serializer.serialize(this.dataToImg(data, force_absolute), {forced_root_block : '', force_absolute : force_absolute});
  217. },
  218. /**
  219. * Converts the JSON data object to a HTML string.
  220. */
  221. htmlToData : function(html) {
  222. var fragment, img, data;
  223. data = {
  224. type : 'flash',
  225. video: {sources:[]},
  226. params: {}
  227. };
  228. fragment = this.editor.parser.parse(html);
  229. img = fragment.getAll('img')[0];
  230. if (img) {
  231. data = JSON.parse(img.attr('data-mce-json'));
  232. data.type = this.getType(img.attr('class')).name.toLowerCase();
  233. // Add some extra properties to the data object
  234. tinymce.each(rootAttributes, function(name) {
  235. var value = img.attr(name);
  236. if (value)
  237. data[name] = value;
  238. });
  239. }
  240. return data;
  241. },
  242. /**
  243. * Get type item by extension, class, clsid or mime type.
  244. *
  245. * @method getType
  246. * @param {String} value Value to get type item by.
  247. * @return {Object} Type item object or undefined.
  248. */
  249. getType : function(value) {
  250. var i, values, typeItem;
  251. // Find type by checking the classes
  252. values = tinymce.explode(value, ' ');
  253. for (i = 0; i < values.length; i++) {
  254. typeItem = this.lookup[values[i]];
  255. if (typeItem)
  256. return typeItem;
  257. }
  258. },
  259. /**
  260. * Converts a tinymce.html.Node image element to video/object/embed.
  261. */
  262. imgToObject : function(node, args) {
  263. var self = this, editor = self.editor, video, object, embed, iframe, name, value, data,
  264. source, sources, params, param, typeItem, i, item, mp4Source, replacement,
  265. posterSrc, style;
  266. // Adds the flash player
  267. function addPlayer(video_src, poster_src) {
  268. var baseUri, flashVars, flashVarsOutput, params, flashPlayer;
  269. flashPlayer = editor.getParam('flash_video_player_url', self.convertUrl(self.url + '/moxieplayer.swf'));
  270. if (flashPlayer) {
  271. baseUri = editor.documentBaseURI;
  272. data.params.src = flashPlayer;
  273. // Convert the movie url to absolute urls
  274. if (editor.getParam('flash_video_player_absvideourl', true)) {
  275. video_src = baseUri.toAbsolute(video_src || '', true);
  276. poster_src = baseUri.toAbsolute(poster_src || '', true);
  277. }
  278. // Generate flash vars
  279. flashVarsOutput = '';
  280. flashVars = editor.getParam('flash_video_player_flashvars', {url : '$url', poster : '$poster'});
  281. tinymce.each(flashVars, function(value, name) {
  282. // Replace $url and $poster variables in flashvars value
  283. value = value.replace(/\$url/, video_src || '');
  284. value = value.replace(/\$poster/, poster_src || '');
  285. if (value.length > 0)
  286. flashVarsOutput += (flashVarsOutput ? '&' : '') + name + '=' + escape(value);
  287. });
  288. if (flashVarsOutput.length)
  289. data.params.flashvars = flashVarsOutput;
  290. params = editor.getParam('flash_video_player_params', {
  291. allowfullscreen: true,
  292. allowscriptaccess: true
  293. });
  294. tinymce.each(params, function(value, name) {
  295. data.params[name] = "" + value;
  296. });
  297. }
  298. };
  299. data = node.attr('data-mce-json');
  300. if (!data)
  301. return;
  302. data = JSON.parse(data);
  303. typeItem = this.getType(node.attr('class'));
  304. style = node.attr('data-mce-style')
  305. if (!style) {
  306. style = node.attr('style');
  307. if (style)
  308. style = editor.dom.serializeStyle(editor.dom.parseStyle(style, 'img'));
  309. }
  310. // Handle iframe
  311. if (typeItem.name === 'Iframe') {
  312. replacement = new Node('iframe', 1);
  313. tinymce.each(rootAttributes, function(name) {
  314. var value = node.attr(name);
  315. if (name == 'class' && value)
  316. value = value.replace(/mceItem.+ ?/g, '');
  317. if (value && value.length > 0)
  318. replacement.attr(name, value);
  319. });
  320. for (name in data.params)
  321. replacement.attr(name, data.params[name]);
  322. replacement.attr({
  323. style: style,
  324. src: data.params.src
  325. });
  326. node.replace(replacement);
  327. return;
  328. }
  329. // Handle scripts
  330. if (this.editor.settings.media_use_script) {
  331. replacement = new Node('script', 1).attr('type', 'text/javascript');
  332. value = new Node('#text', 3);
  333. value.value = 'write' + typeItem.name + '(' + JSON.serialize(tinymce.extend(data.params, {
  334. width: node.attr('width'),
  335. height: node.attr('height')
  336. })) + ');';
  337. replacement.append(value);
  338. node.replace(replacement);
  339. return;
  340. }
  341. // Add HTML5 video element
  342. if (typeItem.name === 'Video' && data.video.sources[0]) {
  343. // Create new object element
  344. video = new Node('video', 1).attr(tinymce.extend({
  345. id : node.attr('id'),
  346. width: node.attr('width'),
  347. height: node.attr('height'),
  348. style : style
  349. }, data.video.attrs));
  350. // Get poster source and use that for flash fallback
  351. if (data.video.attrs)
  352. posterSrc = data.video.attrs.poster;
  353. sources = data.video.sources = toArray(data.video.sources);
  354. for (i = 0; i < sources.length; i++) {
  355. if (/\.mp4$/.test(sources[i].src))
  356. mp4Source = sources[i].src;
  357. }
  358. if (!sources[0].type) {
  359. video.attr('src', sources[0].src);
  360. sources.splice(0, 1);
  361. }
  362. for (i = 0; i < sources.length; i++) {
  363. source = new Node('source', 1).attr(sources[i]);
  364. source.shortEnded = true;
  365. video.append(source);
  366. }
  367. // Create flash fallback for video if we have a mp4 source
  368. if (mp4Source) {
  369. addPlayer(mp4Source, posterSrc);
  370. typeItem = self.getType('flash');
  371. } else
  372. data.params.src = '';
  373. }
  374. // Do we have a params src then we can generate object
  375. if (data.params.src) {
  376. // Is flv movie add player for it
  377. if (/\.flv$/i.test(data.params.src))
  378. addPlayer(data.params.src, '');
  379. if (args && args.force_absolute)
  380. data.params.src = editor.documentBaseURI.toAbsolute(data.params.src);
  381. // Create new object element
  382. object = new Node('object', 1).attr({
  383. id : node.attr('id'),
  384. width: node.attr('width'),
  385. height: node.attr('height'),
  386. style : style
  387. });
  388. tinymce.each(rootAttributes, function(name) {
  389. if (data[name] && name != 'type')
  390. object.attr(name, data[name]);
  391. });
  392. // Add params
  393. for (name in data.params) {
  394. param = new Node('param', 1);
  395. param.shortEnded = true;
  396. value = data.params[name];
  397. // Windows media needs to use url instead of src for the media URL
  398. if (name === 'src' && typeItem.name === 'WindowsMedia')
  399. name = 'url';
  400. param.attr({name: name, value: value});
  401. object.append(param);
  402. }
  403. // Setup add type and classid if strict is disabled
  404. if (this.editor.getParam('media_strict', true)) {
  405. object.attr({
  406. data: data.params.src,
  407. type: typeItem.mimes[0]
  408. });
  409. } else {
  410. object.attr({
  411. classid: "clsid:" + typeItem.clsids[0],
  412. codebase: typeItem.codebase
  413. });
  414. embed = new Node('embed', 1);
  415. embed.shortEnded = true;
  416. embed.attr({
  417. id: node.attr('id'),
  418. width: node.attr('width'),
  419. height: node.attr('height'),
  420. style : style,
  421. type: typeItem.mimes[0]
  422. });
  423. for (name in data.params)
  424. embed.attr(name, data.params[name]);
  425. tinymce.each(rootAttributes, function(name) {
  426. if (data[name] && name != 'type')
  427. embed.attr(name, data[name]);
  428. });
  429. object.append(embed);
  430. }
  431. // Insert raw HTML
  432. if (data.object_html) {
  433. value = new Node('#text', 3);
  434. value.raw = true;
  435. value.value = data.object_html;
  436. object.append(value);
  437. }
  438. // Append object to video element if it exists
  439. if (video)
  440. video.append(object);
  441. }
  442. if (video) {
  443. // Insert raw HTML
  444. if (data.video_html) {
  445. value = new Node('#text', 3);
  446. value.raw = true;
  447. value.value = data.video_html;
  448. video.append(value);
  449. }
  450. }
  451. if (video || object)
  452. node.replace(video || object);
  453. else
  454. node.remove();
  455. },
  456. /**
  457. * Converts a tinymce.html.Node video/object/embed to an img element.
  458. *
  459. * The video/object/embed will be converted into an image placeholder with a JSON data attribute like this:
  460. * <img class="mceItemMedia mceItemFlash" width="100" height="100" data-mce-json="{..}" />
  461. *
  462. * The JSON structure will be like this:
  463. * {'params':{'flashvars':'something','quality':'high','src':'someurl'}, 'video':{'sources':[{src: 'someurl', type: 'video/mp4'}]}}
  464. */
  465. objectToImg : function(node) {
  466. var object, embed, video, iframe, img, name, id, width, height, style, i, html,
  467. param, params, source, sources, data, type, lookup = this.lookup,
  468. matches, attrs, urlConverter = this.editor.settings.url_converter,
  469. urlConverterScope = this.editor.settings.url_converter_scope;
  470. function getInnerHTML(node) {
  471. return new tinymce.html.Serializer({
  472. inner: true,
  473. validate: false
  474. }).serialize(node);
  475. };
  476. // If node isn't in document
  477. if (!node.parent)
  478. return;
  479. // Handle media scripts
  480. if (node.name === 'script') {
  481. if (node.firstChild)
  482. matches = scriptRegExp.exec(node.firstChild.value);
  483. if (!matches)
  484. return;
  485. type = matches[1];
  486. data = {video : {}, params : JSON.parse(matches[2])};
  487. width = data.params.width;
  488. height = data.params.height;
  489. }
  490. // Setup data objects
  491. data = data || {
  492. video : {},
  493. params : {}
  494. };
  495. // Setup new image object
  496. img = new Node('img', 1);
  497. img.attr({
  498. src : this.editor.theme.url + '/img/trans.gif'
  499. });
  500. // Video element
  501. name = node.name;
  502. if (name === 'video') {
  503. video = node;
  504. object = node.getAll('object')[0];
  505. embed = node.getAll('embed')[0];
  506. width = video.attr('width');
  507. height = video.attr('height');
  508. id = video.attr('id');
  509. data.video = {attrs : {}, sources : []};
  510. // Get all video attributes
  511. attrs = data.video.attrs;
  512. for (name in video.attributes.map)
  513. attrs[name] = video.attributes.map[name];
  514. source = node.attr('src');
  515. if (source)
  516. data.video.sources.push({src : urlConverter.call(urlConverterScope, source, 'src', 'video')});
  517. // Get all sources
  518. sources = video.getAll("source");
  519. for (i = 0; i < sources.length; i++) {
  520. source = sources[i].remove();
  521. data.video.sources.push({
  522. src: urlConverter.call(urlConverterScope, source.attr('src'), 'src', 'source'),
  523. type: source.attr('type'),
  524. media: source.attr('media')
  525. });
  526. }
  527. // Convert the poster URL
  528. if (attrs.poster)
  529. attrs.poster = urlConverter.call(urlConverterScope, attrs.poster, 'poster', 'video');
  530. }
  531. // Object element
  532. if (node.name === 'object') {
  533. object = node;
  534. embed = node.getAll('embed')[0];
  535. }
  536. // Embed element
  537. if (node.name === 'embed')
  538. embed = node;
  539. // Iframe element
  540. if (node.name === 'iframe') {
  541. iframe = node;
  542. type = 'Iframe';
  543. }
  544. if (object) {
  545. // Get width/height
  546. width = width || object.attr('width');
  547. height = height || object.attr('height');
  548. style = style || object.attr('style');
  549. id = id || object.attr('id');
  550. // Get all object params
  551. params = object.getAll("param");
  552. for (i = 0; i < params.length; i++) {
  553. param = params[i];
  554. name = param.remove().attr('name');
  555. if (!excludedAttrs[name])
  556. data.params[name] = param.attr('value');
  557. }
  558. data.params.src = data.params.src || object.attr('data');
  559. }
  560. if (embed) {
  561. // Get width/height
  562. width = width || embed.attr('width');
  563. height = height || embed.attr('height');
  564. style = style || embed.attr('style');
  565. id = id || embed.attr('id');
  566. // Get all embed attributes
  567. for (name in embed.attributes.map) {
  568. if (!excludedAttrs[name] && !data.params[name])
  569. data.params[name] = embed.attributes.map[name];
  570. }
  571. }
  572. if (iframe) {
  573. // Get width/height
  574. width = iframe.attr('width');
  575. height = iframe.attr('height');
  576. style = style || iframe.attr('style');
  577. id = iframe.attr('id');
  578. tinymce.each(rootAttributes, function(name) {
  579. img.attr(name, iframe.attr(name));
  580. });
  581. // Get all iframe attributes
  582. for (name in iframe.attributes.map) {
  583. if (!excludedAttrs[name] && !data.params[name])
  584. data.params[name] = iframe.attributes.map[name];
  585. }
  586. }
  587. // Use src not movie
  588. if (data.params.movie) {
  589. data.params.src = data.params.src || data.params.movie;
  590. delete data.params.movie;
  591. }
  592. // Convert the URL to relative/absolute depending on configuration
  593. if (data.params.src)
  594. data.params.src = urlConverter.call(urlConverterScope, data.params.src, 'src', 'object');
  595. if (video)
  596. type = lookup.video.name;
  597. if (object && !type)
  598. type = (lookup[(object.attr('clsid') || '').toLowerCase()] || lookup[(object.attr('type') || '').toLowerCase()] || {}).name;
  599. if (embed && !type)
  600. type = (lookup[(embed.attr('type') || '').toLowerCase()] || {}).name;
  601. // Replace the video/object/embed element with a placeholder image containing the data
  602. node.replace(img);
  603. // Remove embed
  604. if (embed)
  605. embed.remove();
  606. // Serialize the inner HTML of the object element
  607. if (object) {
  608. html = getInnerHTML(object.remove());
  609. if (html)
  610. data.object_html = html;
  611. }
  612. // Serialize the inner HTML of the video element
  613. if (video) {
  614. html = getInnerHTML(video.remove());
  615. if (html)
  616. data.video_html = html;
  617. }
  618. // Set width/height of placeholder
  619. img.attr({
  620. id : id,
  621. 'class' : 'mceItemMedia mceItem' + (type || 'Flash'),
  622. style : style,
  623. width : width || "320",
  624. height : height || "240",
  625. "data-mce-json" : JSON.serialize(data, "'")
  626. });
  627. }
  628. });
  629. // Register plugin
  630. tinymce.PluginManager.add('media', tinymce.plugins.MediaPlugin);
  631. })();