X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=webcit%2Ftiny_mce%2Fplugins%2Fmedia%2Feditor_plugin_src.js;h=219d713f29fbc4af1b0ac274a87abf4f9b2a6342;hb=eb5fb3f6c3b3e1d4d3d7ebbb92b8c60d70d13254;hp=4478ebb59eae86bce199a812255155029f90eda4;hpb=932f4feaa7b2afe4553e5e669e2312614d3f6140;p=citadel.git diff --git a/webcit/tiny_mce/plugins/media/editor_plugin_src.js b/webcit/tiny_mce/plugins/media/editor_plugin_src.js old mode 100755 new mode 100644 index 4478ebb59..219d713f2 --- a/webcit/tiny_mce/plugins/media/editor_plugin_src.js +++ b/webcit/tiny_mce/plugins/media/editor_plugin_src.js @@ -1,435 +1,822 @@ /** - * $Id: editor_plugin_src.js 275 2007-05-01 15:35:08Z spocke $ + * editor_plugin_src.js * - * @author Moxiecode - * @copyright Copyright © 2004-2007, Moxiecode Systems AB, All rights reserved. + * Copyright 2009, Moxiecode Systems AB + * Released under LGPL License. + * + * License: http://tinymce.moxiecode.com/license + * Contributing: http://tinymce.moxiecode.com/contributing */ -/* Import plugin specific language pack */ -tinyMCE.importPluginLanguagePack('media'); - -var TinyMCE_MediaPlugin = { - getInfo : function() { - return { - longname : 'Media', - author : 'Moxiecode Systems AB', - authorurl : 'http://tinymce.moxiecode.com', - infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/media', - version : tinyMCE.majorVersion + "." + tinyMCE.minorVersion - }; - }, - - initInstance : function(inst) { - // Warn if user has flash plugin and media plugin at the same time - if (inst.hasPlugin('flash') && !tinyMCE.flashWarn) { - alert('Flash plugin is deprecated and should not be used together with the media plugin.'); - tinyMCE.flashWarn = true; +(function() { + var rootAttributes = tinymce.explode('id,name,width,height,style,align,class,hspace,vspace,bgcolor,type'), excludedAttrs = tinymce.makeMap(rootAttributes.join(',')), Node = tinymce.html.Node, + mediaTypes, scriptRegExp, JSON = tinymce.util.JSON, mimeTypes; + + // Media types supported by this plugin + mediaTypes = [ + // Type, clsid:s, mime types, codebase + ["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"], + ["ShockWave", "166b1bca-3f9c-11cf-8075-444553540000", "application/x-director", "http://download.macromedia.com/pub/shockwave/cabs/director/sw.cab#version=8,5,1,0"], + ["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"], + ["QuickTime", "02bf25d5-8c17-4b23-bc80-d3488abddc6b", "video/quicktime", "http://www.apple.com/qtactivex/qtplugin.cab#version=6,0,2,0"], + ["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"], + ["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"], + ["Silverlight", "dfeaf541-f3e1-4c24-acac-99c30715084a", "application/x-silverlight-2"], + ["Iframe"], + ["Video"], + ["Audio"] + ]; + + function toArray(obj) { + var undef, out, i; + + if (obj && !obj.splice) { + out = []; + + for (i = 0; true; i++) { + if (obj[i]) + out[i] = obj[i]; + else + break; + } + + return out; } - if (!tinyMCE.settings['media_skip_plugin_css']) - tinyMCE.importCSS(inst.getDoc(), tinyMCE.baseURL + "/plugins/media/css/content.css"); - }, + return obj; + }; - getControlHTML : function(cn) { - switch (cn) { - case "media": - return tinyMCE.getButtonHTML(cn, 'lang_media_desc', '{$pluginurl}/images/media.gif', 'mceMedia'); - } + tinymce.create('tinymce.plugins.MediaPlugin', { + init : function(ed, url) { + var self = this, lookup = {}, i, y, item, name; + + function isMediaImg(node) { + return node && node.nodeName === 'IMG' && ed.dom.hasClass(node, 'mceItemMedia'); + }; + + self.editor = ed; + self.url = url; + + // Parse media types into a lookup table + scriptRegExp = ''; + for (i = 0; i < mediaTypes.length; i++) { + name = mediaTypes[i][0]; + + item = { + name : name, + clsids : tinymce.explode(mediaTypes[i][1] || ''), + mimes : tinymce.explode(mediaTypes[i][2] || ''), + codebase : mediaTypes[i][3] + }; + + for (y = 0; y < item.clsids.length; y++) + lookup['clsid:' + item.clsids[y]] = item; + + for (y = 0; y < item.mimes.length; y++) + lookup[item.mimes[y]] = item; + + lookup['mceItem' + name] = item; + lookup[name.toLowerCase()] = item; - return ""; - }, - - execCommand : function(editor_id, element, command, user_interface, value) { - // Handle commands - switch (command) { - case "mceMedia": - tinyMCE.openWindow({ - file : '../../plugins/media/media.htm', - width : 430 + tinyMCE.getLang('lang_media_delta_width', 0), - height : 470 + tinyMCE.getLang('lang_media_delta_height', 0) - }, { - editor_id : editor_id, - inline : "yes" + scriptRegExp += (scriptRegExp ? '|' : '') + name; + } + + // Handle the media_types setting + tinymce.each(ed.getParam("media_types", + "video=mp4,m4v,ogv,webm;" + + "silverlight=xap;" + + "flash=swf,flv;" + + "shockwave=dcr;" + + "quicktime=mov,qt,mpg,mpeg;" + + "shockwave=dcr;" + + "windowsmedia=avi,wmv,wm,asf,asx,wmx,wvx;" + + "realmedia=rm,ra,ram;" + + "java=jar;" + + "audio=mp3,ogg" + ).split(';'), function(item) { + var i, extensions, type; + + item = item.split(/=/); + extensions = tinymce.explode(item[1].toLowerCase()); + for (i = 0; i < extensions.length; i++) { + type = lookup[item[0].toLowerCase()]; + + if (type) + lookup[extensions[i]] = type; + } + }); + + scriptRegExp = new RegExp('write(' + scriptRegExp + ')\\(([^)]+)\\)'); + self.lookup = lookup; + + ed.onPreInit.add(function() { + // Allow video elements + ed.schema.addValidElements('object[id|style|width|height|classid|codebase|*],param[name|value],embed[id|style|width|height|type|src|*],video[*],audio[*],source[*]'); + + // Convert video elements to image placeholder + ed.parser.addNodeFilter('object,embed,video,audio,script,iframe', function(nodes) { + var i = nodes.length; + + while (i--) + self.objectToImg(nodes[i]); }); - return true; - } - - // Pass to next handler in chain - return false; - }, - - cleanup : function(type, content, inst) { - var nl, img, i, ne, d, s, ci; - - switch (type) { - case "insert_to_editor": - img = tinyMCE.getParam("theme_href") + '/images/spacer.gif'; - content = content.replace(/]*>\s*write(Flash|ShockWave|WindowsMedia|QuickTime|RealMedia)\(\{([^\)]*)\}\);\s*<\/script>/gi, ''); - content = content.replace(/]*)>/gi, '
'); - content = content.replace(/]*)>/gi, '
'); - content = content.replace(/<\/(object|embed)([^>]*)>/gi, '
'); - content = content.replace(/]*)>/gi, '
'); - content = content.replace(new RegExp('\\/ class="mceItemParam"><\\/div>', 'gi'), 'class="mceItemParam">
'); - break; - - case "insert_to_editor_dom": - d = inst.getDoc(); - nl = content.getElementsByTagName("img"); - for (i=0; i 0) + flashVarsOutput += (flashVarsOutput ? '&' : '') + name + '=' + escape(value); + }); + + if (flashVarsOutput.length) + data.params.flashvars = flashVarsOutput; + + params = editor.getParam('flash_video_player_params', { + allowfullscreen: true, + allowscriptaccess: true + }); + + tinymce.each(params, function(value, name) { + data.params[name] = "" + value; + }); } - break; + }; - case "get_from_editor": - var startPos = -1, endPos, attribs, chunkBefore, chunkAfter, embedHTML, at, pl, cb, mt, ex; + data = node.attr('data-mce-json'); + if (!data) + return; - while ((startPos = content.indexOf('', startPos); - attribs = TinyMCE_MediaPlugin._parseAttributes(content.substring(startPos + 4, endPos)); + data = JSON.parse(data); + typeItem = this.getType(node.attr('class')); - // Is not flash, skip it - if (!/mceItem(Flash|ShockWave|WindowsMedia|QuickTime|RealMedia)/.test(attribs['class'])) - continue; + style = node.attr('data-mce-style') + if (!style) { + style = node.attr('style'); - endPos += 2; + if (style) + style = editor.dom.serializeStyle(editor.dom.parseStyle(style, 'img')); + } - // Parse attributes - at = attribs['title']; - if (at) { - at = at.replace(/&(#39|apos);/g, "'"); - at = at.replace(/&#quot;/g, '"'); + // Handle iframe + if (typeItem.name === 'Iframe') { + replacement = new Node('iframe', 1); - try { - pl = eval('x={' + at + '};'); - } catch (ex) { - pl = {}; - } - } + tinymce.each(rootAttributes, function(name) { + var value = node.attr(name); - // Use object/embed - if (!tinyMCE.getParam('media_use_script', false)) { - switch (attribs['class']) { - case 'mceItemFlash': - ci = 'd27cdb6e-ae6d-11cf-96b8-444553540000'; - cb = 'http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0'; - mt = 'application/x-shockwave-flash'; - break; - - case 'mceItemShockWave': - ci = '166B1BCA-3F9C-11CF-8075-444553540000'; - cb = 'http://download.macromedia.com/pub/shockwave/cabs/director/sw.cab#version=8,5,1,0'; - mt = 'application/x-director'; - break; - - case 'mceItemWindowsMedia': - ci = tinyMCE.getParam('media_wmp6_compatible') ? '05589FA1-C356-11CE-BF01-00AA0055595A' : '6BF52A52-394A-11D3-B153-00C04F79FAA6'; - cb = 'http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=5,1,52,701'; - mt = 'application/x-mplayer2'; - break; - - case 'mceItemQuickTime': - ci = '02BF25D5-8C17-4B23-BC80-D3488ABDDC6B'; - cb = 'http://www.apple.com/qtactivex/qtplugin.cab#version=6,0,2,0'; - mt = 'video/quicktime'; - break; - - case 'mceItemRealMedia': - ci = 'CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA'; - cb = 'http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0'; - mt = 'audio/x-pn-realaudio-plugin'; - break; - } - - // Force absolute URL - if (!tinyMCE.getParam("relative_urls")) - pl.src = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'], pl.src); - - embedHTML = TinyMCE_MediaPlugin._getEmbed(ci, cb, mt, pl, attribs); - } else { - // Use script version - switch (attribs['class']) { - case 'mceItemFlash': - s = 'writeFlash'; - break; - - case 'mceItemShockWave': - s = 'writeShockWave'; - break; - - case 'mceItemWindowsMedia': - s = 'writeWindowsMedia'; - break; - - case 'mceItemQuickTime': - s = 'writeQuickTime'; - break; - - case 'mceItemRealMedia': - s = 'writeRealMedia'; - break; - } - - if (attribs.width) - at = at.replace(/width:[^0-9]?[0-9]+%?[^0-9]?/g, "width:'" + attribs.width + "'"); - - if (attribs.height) - at = at.replace(/height:[^0-9]?[0-9]+%?[^0-9]?/g, "height:'" + attribs.height + "'"); - - // Force absolute URL - if (!tinyMCE.getParam("relative_urls")) { - pl.src = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'], pl.src); - at = at.replace(new RegExp("src:'[^']*'", "g"), "src:'" + pl.src + "'"); - } - - embedHTML = ''; - } + if (name == 'class' && value) + value = value.replace(/mceItem.+ ?/g, ''); + + if (value && value.length > 0) + replacement.attr(name, value); + }); + + for (name in data.params) + replacement.attr(name, data.params[name]); + + replacement.attr({ + style: style, + src: data.params.src + }); + + node.replace(replacement); + + return; + } + + // Handle scripts + if (this.editor.settings.media_use_script) { + replacement = new Node('script', 1).attr('type', 'text/javascript'); + + value = new Node('#text', 3); + value.value = 'write' + typeItem.name + '(' + JSON.serialize(tinymce.extend(data.params, { + width: node.attr('width'), + height: node.attr('height') + })) + ');'; - // Insert embed/object chunk - chunkBefore = content.substring(0, startPos); - chunkAfter = content.substring(endPos); - content = chunkBefore + embedHTML + chunkAfter; + replacement.append(value); + node.replace(replacement); + + return; + } + + // Add HTML5 video element + if (typeItem.name === 'Video' && data.video.sources[0]) { + // Create new object element + video = new Node('video', 1).attr(tinymce.extend({ + id : node.attr('id'), + width: node.attr('width'), + height: node.attr('height'), + style : style + }, data.video.attrs)); + + // Get poster source and use that for flash fallback + if (data.video.attrs) + posterSrc = data.video.attrs.poster; + + sources = data.video.sources = toArray(data.video.sources); + for (i = 0; i < sources.length; i++) { + if (/\.mp4$/.test(sources[i].src)) + mp4Source = sources[i].src; + } + + if (!sources[0].type) { + video.attr('src', sources[0].src); + sources.splice(0, 1); } - break; - } - return content; - }, + for (i = 0; i < sources.length; i++) { + source = new Node('source', 1).attr(sources[i]); + source.shortEnded = true; + video.append(source); + } + + // Create flash fallback for video if we have a mp4 source + if (mp4Source) { + addPlayer(mp4Source, posterSrc); + typeItem = self.getType('flash'); + } else + data.params.src = ''; + } + + // Add HTML5 audio element + if (typeItem.name === 'Audio' && data.video.sources[0]) { + // Create new object element + audio = new Node('audio', 1).attr(tinymce.extend({ + id : node.attr('id'), + width: node.attr('width'), + height: node.attr('height'), + style : style + }, data.video.attrs)); + + // Get poster source and use that for flash fallback + if (data.video.attrs) + posterSrc = data.video.attrs.poster; + + sources = data.video.sources = toArray(data.video.sources); + if (!sources[0].type) { + audio.attr('src', sources[0].src); + sources.splice(0, 1); + } - handleNodeChange : function(editor_id, node, undo_index, undo_levels, visual_aid, any_selection) { - if (node == null) - return; + for (i = 0; i < sources.length; i++) { + source = new Node('source', 1).attr(sources[i]); + source.shortEnded = true; + audio.append(source); + } - do { - if (node.nodeName == "IMG" && /mceItem(Flash|ShockWave|WindowsMedia|QuickTime|RealMedia)/.test(tinyMCE.getAttrib(node, 'class'))) { - tinyMCE.switchClass(editor_id + '_media', 'mceButtonSelected'); - return true; + data.params.src = ''; } - } while ((node = node.parentNode)); - tinyMCE.switchClass(editor_id + '_media', 'mceButtonNormal'); + // Do we have a params src then we can generate object + if (data.params.src) { + // Is flv movie add player for it + if (/\.flv$/i.test(data.params.src)) + addPlayer(data.params.src, ''); + + if (args && args.force_absolute) + data.params.src = editor.documentBaseURI.toAbsolute(data.params.src); + + // Create new object element + object = new Node('object', 1).attr({ + id : node.attr('id'), + width: node.attr('width'), + height: node.attr('height'), + style : style + }); - return true; - }, + tinymce.each(rootAttributes, function(name) { + if (data[name] && name != 'type') + object.attr(name, data[name]); + }); - _createImgFromEmbed : function(n, d, cl) { - var ne, at, i, ti = '', an; + // Add params + for (name in data.params) { + param = new Node('param', 1); + param.shortEnded = true; + value = data.params[name]; - ne = d.createElement('img'); - ne.src = tinyMCE.getParam("theme_href") + '/images/spacer.gif'; - ne.width = tinyMCE.getAttrib(n, 'width'); - ne.height = tinyMCE.getAttrib(n, 'height'); - ne.className = cl; + // Windows media needs to use url instead of src for the media URL + if (name === 'src' && typeItem.name === 'WindowsMedia') + name = 'url'; - at = n.attributes; - for (i=0; i 0 ? ti.substring(0, ti.length - 1) : ti; - ne.title = ti; - - n.parentNode.replaceChild(ne, n); - }, - - _createImg : function(cl, d, n) { - var i, nl, ti = "", an, av, al = new Array(); - - ne = d.createElement('img'); - ne.src = tinyMCE.getParam("theme_href") + '/images/spacer.gif'; - ne.width = tinyMCE.getAttrib(n, 'width'); - ne.height = tinyMCE.getAttrib(n, 'height'); - ne.className = cl; - - al.id = tinyMCE.getAttrib(n, 'id'); - al.name = tinyMCE.getAttrib(n, 'name'); - al.width = tinyMCE.getAttrib(n, 'width'); - al.height = tinyMCE.getAttrib(n, 'height'); - al.bgcolor = tinyMCE.getAttrib(n, 'bgcolor'); - al.align = tinyMCE.getAttrib(n, 'align'); - al.class_name = tinyMCE.getAttrib(n, 'mce_class'); - - nl = n.getElementsByTagName('div'); - for (i=0; i + * + * The JSON structure will be like this: + * {'params':{'flashvars':'something','quality':'high','src':'someurl'}, 'video':{'sources':[{src: 'someurl', type: 'video/mp4'}]}} + */ + objectToImg : function(node) { + var object, embed, video, iframe, img, name, id, width, height, style, i, html, + param, params, source, sources, data, type, lookup = this.lookup, + matches, attrs, urlConverter = this.editor.settings.url_converter, + urlConverterScope = this.editor.settings.url_converter_scope; + + function getInnerHTML(node) { + return new tinymce.html.Serializer({ + inner: true, + validate: false + }).serialize(node); + }; + + // If node isn't in document + if (!node.parent) + return; + + // Handle media scripts + if (node.name === 'script') { + if (node.firstChild) + matches = scriptRegExp.exec(node.firstChild.value); + + if (!matches) + return; + + type = matches[1]; + data = {video : {}, params : JSON.parse(matches[2])}; + width = data.params.width; + height = data.params.height; + } - ti = ti.length > 0 ? ti.substring(0, ti.length - 1) : ti; - ne.title = ti; + // Setup data objects + data = data || { + video : {}, + params : {} + }; + + // Setup new image object + img = new Node('img', 1); + img.attr({ + src : this.editor.theme.url + '/img/trans.gif' + }); + + // Video element + name = node.name; + if (name === 'video' || name == 'audio') { + video = node; + object = node.getAll('object')[0]; + embed = node.getAll('embed')[0]; + width = video.attr('width'); + height = video.attr('height'); + id = video.attr('id'); + data.video = {attrs : {}, sources : []}; + + // Get all video attributes + attrs = data.video.attrs; + for (name in video.attributes.map) + attrs[name] = video.attributes.map[name]; + + source = node.attr('src'); + if (source) + data.video.sources.push({src : urlConverter.call(urlConverterScope, source, 'src', node.name)}); + + // Get all sources + sources = video.getAll("source"); + for (i = 0; i < sources.length; i++) { + source = sources[i].remove(); + + data.video.sources.push({ + src: urlConverter.call(urlConverterScope, source.attr('src'), 'src', 'source'), + type: source.attr('type'), + media: source.attr('media') + }); + } - return ne; - }, + // Convert the poster URL + if (attrs.poster) + attrs.poster = urlConverter.call(urlConverterScope, attrs.poster, 'poster', node.name); + } - _getEmbed : function(cls, cb, mt, p, at) { - var h = '', n; + // Object element + if (node.name === 'object') { + object = node; + embed = node.getAll('embed')[0]; + } - p.width = at.width ? at.width : p.width; - p.height = at.height ? at.height : p.height; + // Embed element + if (node.name === 'embed') + embed = node; - h += ''; + if (object) { + // Get width/height + width = width || object.attr('width'); + height = height || object.attr('height'); + style = style || object.attr('style'); + id = id || object.attr('id'); + + // Get all object params + params = object.getAll("param"); + for (i = 0; i < params.length; i++) { + param = params[i]; + name = param.remove().attr('name'); + + if (!excludedAttrs[name]) + data.params[name] = param.attr('value'); + } - // Add extra url parameter if it's an absolute URL on WMP - if (n == 'src' && p[n].indexOf('://') != -1 && mt == 'application/x-mplayer2') - h += ''; + data.params.src = data.params.src || object.attr('data'); } - } - h += '