Index: admin/js/jquery/jquery.oembed.js
===================================================================
--- admin/js/jquery/jquery.oembed.js	(revision 381)
+++ admin/js/jquery/jquery.oembed.js	(revision 381)
@@ -0,0 +1,349 @@
+/*!
+ * jquery oembed plugin
+ *
+ * Copyright (c) 2009 Richard Chamorro
+ * Licensed under the MIT license
+ * 
+ * Author: Richard Chamorro 
+ */
+ 
+(function ($) {
+    $.fn.oembed = function (url, options, embedAction) {
+
+        settings = $.extend(true, $.fn.oembed.defaults, options);
+
+        initializeProviders();
+
+        return this.each(function () {
+
+            var container = $(this),
+				resourceURL = (url != null) ? url : container.attr("href"),
+				provider;
+
+            if (embedAction) {
+                settings.onEmbed = embedAction;
+            } else {
+                settings.onEmbed = function (oembedData) {
+                    $.fn.oembed.insertCode(this, settings.embedMethod, oembedData);
+                };
+            }
+
+            if (resourceURL != null) {
+                provider = $.fn.oembed.getOEmbedProvider(resourceURL);
+
+                if (provider != null) {
+                    provider.params = getNormalizedParams(settings[provider.name]) || {};
+                    provider.maxWidth = settings.maxWidth;
+                    provider.maxHeight = settings.maxHeight;
+                    embedCode(container, resourceURL, provider);
+                } else {
+                    settings.onProviderNotFound.call(container, resourceURL);
+                }
+            }
+
+            return container;
+        });
+
+
+    };
+
+    var settings, activeProviders = [];
+
+    // Plugin defaults
+    $.fn.oembed.defaults = {
+        maxWidth: null,
+        maxHeight: null,
+        embedMethod: "replace",  	// "auto", "append", "fill"		
+        defaultOEmbedProvider: "oohembed", 	// "oohembed", "embed.ly", "none"
+        allowedProviders: null,
+        disallowedProviders: null,
+        customProviders: null, // [ new $.fn.oembed.OEmbedProvider("customprovider", null, ["customprovider\\.com/watch.+v=[\\w-]+&?"]) ]	
+        defaultProvider: null,
+        greedy: true,
+        onProviderNotFound: function () { },
+        beforeEmbed: function () { },
+        afterEmbed: function () { },
+        onEmbed: function () { },
+		onError: function() {},
+		ajaxOptions: {}
+    };
+
+    /* Private functions */
+    function getRequestUrl(provider, externalUrl) {
+
+        var url = provider.apiendpoint, qs = "", callbackparameter = provider.callbackparameter || "callback", i;
+
+        if (url.indexOf("?") <= 0)
+            url = url + "?";
+        else
+            url = url + "&";
+
+        if (provider.maxWidth != null && provider.params["maxwidth"] == null)
+            provider.params["maxwidth"] = provider.maxWidth;
+
+        if (provider.maxHeight != null && provider.params["maxheight"] == null)
+            provider.params["maxheight"] = provider.maxHeight;
+
+        for (i in provider.params) {
+            // We don't want them to jack everything up by changing the callback parameter
+            if (i == provider.callbackparameter)
+                continue;
+
+            // allows the options to be set to null, don't send null values to the server as parameters
+            if (provider.params[i] != null)
+                qs += "&" + escape(i) + "=" + provider.params[i];
+        }
+
+        url += "format=json&url=" + escape(externalUrl) +
+					qs +
+					"&" + callbackparameter + "=?";
+
+        return url;
+    };
+
+    function embedCode(container, externalUrl, embedProvider) {
+
+        var requestUrl = getRequestUrl(embedProvider, externalUrl), 		
+			ajaxopts = $.extend({
+				url: requestUrl,
+				type: 'get',
+				dataType: 'json',
+				// error: jsonp request doesnt' support error handling
+				success:  function (data) {
+					var oembedData = $.extend({}, data);
+					switch (oembedData.type) {
+						case "photo":
+							oembedData.code = $.fn.oembed.getPhotoCode(externalUrl, oembedData);
+							break;
+						case "video":
+							oembedData.code = $.fn.oembed.getVideoCode(externalUrl, oembedData);
+							break;
+						case "rich":
+							oembedData.code = $.fn.oembed.getRichCode(externalUrl, oembedData);
+							break;
+						default:
+							oembedData.code = $.fn.oembed.getGenericCode(externalUrl, oembedData);
+							break;
+					}
+					settings.beforeEmbed.call(container, oembedData);
+					settings.onEmbed.call(container, oembedData);
+					settings.afterEmbed.call(container, oembedData);
+				},
+				error: settings.onError
+			}, settings.ajaxOptions || { } );
+		
+		$.ajax( ajaxopts );        
+    };
+
+    function initializeProviders() {
+
+        activeProviders = [];
+
+        var defaultProvider, restrictedProviders = [], i, provider;
+
+        if (!isNullOrEmpty(settings.allowedProviders)) {
+            for (i = 0; i < $.fn.oembed.providers.length; i++) {
+                if ($.inArray($.fn.oembed.providers[i].name, settings.allowedProviders) >= 0)
+                    activeProviders.push($.fn.oembed.providers[i]);
+            }
+            // If there are allowed providers, jquery-oembed cannot be greedy
+            settings.greedy = false;
+
+        } else {
+            activeProviders = $.fn.oembed.providers;
+        }
+
+        if (!isNullOrEmpty(settings.disallowedProviders)) {
+            for (i = 0; i < activeProviders.length; i++) {
+                if ($.inArray(activeProviders[i].name, settings.disallowedProviders) < 0)
+                    restrictedProviders.push(activeProviders[i]);
+            }
+            activeProviders = restrictedProviders;
+            // If there are allowed providers, jquery-oembed cannot be greedy
+            settings.greedy = false;
+        }
+
+        if (!isNullOrEmpty(settings.customProviders)) {
+            $.each(settings.customProviders, function (n, customProvider) {
+                if (customProvider instanceof $.fn.oembed.OEmbedProvider) {
+                    activeProviders.push(provider);
+                } else {
+                    provider = new $.fn.oembed.OEmbedProvider();
+                    if (provider.fromJSON(customProvider))
+                        activeProviders.push(provider);
+                }
+            });
+        }
+
+        // If in greedy mode, we add the default provider
+        defaultProvider = getDefaultOEmbedProvider(settings.defaultOEmbedProvider);
+        if (settings.greedy == true) {
+            activeProviders.push(defaultProvider);
+		}
+        // If any provider has no apiendpoint, we use the default provider endpoint
+        for (i = 0; i < activeProviders.length; i++) {
+            if (activeProviders[i].apiendpoint == null)
+                activeProviders[i].apiendpoint = defaultProvider.apiendpoint;
+        }
+    }
+
+    function getDefaultOEmbedProvider(defaultOEmbedProvider) {
+        var url = "http://oohembed.com/oohembed/";
+        if (defaultOEmbedProvider == "embed.ly")
+            url = "http://api.embed.ly/v1/api/oembed?";
+        return new $.fn.oembed.OEmbedProvider(defaultOEmbedProvider, null, null, url, "callback");
+    }
+
+    function getNormalizedParams(params) {
+        if (params == null)
+            return null;
+        var key, normalizedParams = {};
+        for (key in params) {
+            if (key != null)
+                normalizedParams[key.toLowerCase()] = params[key];
+        }
+        return normalizedParams;
+    }
+
+    function isNullOrEmpty(object) {
+        if (typeof object == "undefined")
+            return true;
+        if (object == null)
+            return true;
+        if ($.isArray(object) && object.length == 0)
+            return true;
+        return false;
+    }
+
+    /* Public functions */
+    $.fn.oembed.insertCode = function (container, embedMethod, oembedData) {
+        if (oembedData == null)
+            return;
+
+        switch (embedMethod) {
+            case "auto":
+                if (container.attr("href") != null) {
+                    $.fn.oembed.insertCode(container, "append", oembedData);
+                }
+                else {
+                    $.fn.oembed.insertCode(container, "replace", oembedData);
+                };
+                break;
+            case "replace":
+                container.replaceWith(oembedData.code);
+                break;
+            case "fill":
+                container.html(oembedData.code);
+                break;
+            case "append":
+                var oembedContainer = container.next();
+                if (oembedContainer == null || !oembedContainer.hasClass("oembed-container")) {
+                    oembedContainer = container
+						.after('<div class="oembed-container"></div>')
+						.next(".oembed-container");
+                    if (oembedData != null && oembedData.provider_name != null)
+                        oembedContainer.toggleClass("oembed-container-" + oembedData.provider_name);
+                }
+                oembedContainer.html(oembedData.code);
+                break;
+        }
+    };
+
+    $.fn.oembed.getPhotoCode = function (url, oembedData) {
+        var code, alt = oembedData.title ? oembedData.title : '';
+        alt += oembedData.author_name ? ' - ' + oembedData.author_name : '';
+        alt += oembedData.provider_name ? ' - ' + oembedData.provider_name : '';
+        code = '<div><a href="' + url + '" target=\'_blank\'><img src="' + oembedData.url + '" alt="' + alt + '"/></a></div>';
+        if (oembedData.html)
+            code += "<div>" + oembedData.html + "</div>";
+        return code;
+    };
+
+    $.fn.oembed.getVideoCode = function (url, oembedData) {
+        var code = oembedData.html;
+
+        return code;
+    };
+
+    $.fn.oembed.getRichCode = function (url, oembedData) {
+        var code = oembedData.html;
+        return code;
+    };
+
+    $.fn.oembed.getGenericCode = function (url, oembedData) {
+        var title = (oembedData.title != null) ? oembedData.title : url,
+			code = '<a href="' + url + '">' + title + '</a>';
+        if (oembedData.html)
+            code += "<div>" + oembedData.html + "</div>";
+        return code;
+    };
+
+    $.fn.oembed.isProviderAvailable = function (url) {
+        var provider = getOEmbedProvider(url);
+        return (provider != null);
+    };
+
+    $.fn.oembed.getOEmbedProvider = function (url) {
+        for (var i = 0; i < activeProviders.length; i++) {
+            if (activeProviders[i].matches(url))
+                return activeProviders[i];
+        }
+        return null;
+    };
+
+    $.fn.oembed.OEmbedProvider = function (name, type, urlschemesarray, apiendpoint, callbackparameter) {
+        this.name = name;
+        this.type = type; // "photo", "video", "link", "rich", null
+        this.urlschemes = getUrlSchemes(urlschemesarray);
+        this.apiendpoint = apiendpoint;
+        this.callbackparameter = callbackparameter;
+        this.maxWidth = 500;
+        this.maxHeight = 400;
+        var i, property, regExp;
+
+        this.matches = function (externalUrl) {
+            for (i = 0; i < this.urlschemes.length; i++) {
+                regExp = new RegExp(this.urlschemes[i], "i");
+                if (externalUrl.match(regExp) != null)
+                    return true;
+            }
+            return false;
+        };
+
+        this.fromJSON = function (json) {
+            for (property in json) {
+                if (property != "urlschemes")
+                    this[property] = json[property];
+                else
+                    this[property] = getUrlSchemes(json[property]);
+            }
+            return true;
+        };
+
+        function getUrlSchemes(urls) {
+            if (isNullOrEmpty(urls))
+                return ["."];
+            if ($.isArray(urls))
+                return urls;
+            return urls.split(";");
+        }
+    };
+
+    /* Native & common providers */
+    $.fn.oembed.providers = [
+		new $.fn.oembed.OEmbedProvider("youtube", "video", ["youtube\\.com/watch.+v=[\\w-]+&?"]), // "http://www.youtube.com/oembed"	(no jsonp)
+		new $.fn.oembed.OEmbedProvider("flickr", "photo", ["flickr\\.com/photos/[-.\\w@]+/\\d+/?"], "http://flickr.com/services/oembed", "jsoncallback"),
+		new $.fn.oembed.OEmbedProvider("viddler", "video", ["viddler\.com"]), // "http://lab.viddler.com/services/oembed/" (no jsonp)
+		new $.fn.oembed.OEmbedProvider("blip", "video", ["blip\\.tv/.+"], "http://blip.tv/oembed/"),
+		new $.fn.oembed.OEmbedProvider("hulu", "video", ["hulu\\.com/watch/.*"], "http://www.hulu.com/api/oembed.json"),
+		new $.fn.oembed.OEmbedProvider("vimeo", "video", ["http:\/\/www\.vimeo\.com\/groups\/.*\/videos\/.*", "http:\/\/www\.vimeo\.com\/.*", "http:\/\/vimeo\.com\/groups\/.*\/videos\/.*", "http:\/\/vimeo\.com\/.*"], "http://vimeo.com/api/oembed.json"),
+		new $.fn.oembed.OEmbedProvider("dailymotion", "video", ["dailymotion\\.com/.+"]), // "http://www.dailymotion.com/api/oembed/" (callback parameter does not return jsonp)
+		new $.fn.oembed.OEmbedProvider("scribd", "rich", ["scribd\\.com/.+"]), // ", "http://www.scribd.com/services/oembed"" (no jsonp)		
+		new $.fn.oembed.OEmbedProvider("slideshare", "rich", ["slideshare\.net"], "http://www.slideshare.net/api/oembed/1"),
+		new $.fn.oembed.OEmbedProvider("photobucket", "photo", ["photobucket\\.com/(albums|groups)/.*"], "http://photobucket.com/oembed/")
+		// new $.fn.oembed.OEmbedProvider("vids.myspace.com", "video", ["vids\.myspace\.com"]), // "http://vids.myspace.com/index.cfm?fuseaction=oembed" (not working)
+		// new $.fn.oembed.OEmbedProvider("screenr", "rich", ["screenr\.com"], "http://screenr.com/api/oembed.json") (error)		
+		// new $.fn.oembed.OEmbedProvider("qik", "video", ["qik\\.com/\\w+"], "http://qik.com/api/oembed.json"),		
+		// new $.fn.oembed.OEmbedProvider("revision3", "video", ["revision3\.com"], "http://revision3.com/api/oembed/")
+	];
+})(jQuery);
Index: admin/js/tiny_mce/plugins/dcControls/editor_plugin.js
===================================================================
--- admin/js/tiny_mce/plugins/dcControls/editor_plugin.js	(revision 328)
+++ admin/js/tiny_mce/plugins/dcControls/editor_plugin.js	(revision 381)
@@ -6,4 +6,5 @@
 			var popup_link_url = 'popup_link.php';
 			var popup_media_url = 'media.php?popup=1';
+			var popup_web_media_url = 'popup_web_media.php';
 			
 			t.editor = ed;
@@ -69,24 +70,44 @@
 				});
 			});
+			ed.addCommand('dcWebMedia', function() {
+				ed.windowManager.open({
+					file: popup_web_media_url,
+					width: 820,
+					height: 700,
+					inline: 1,
+					popup_css : false,
+					dc_popup: '',
+					alwaysRaised: 'yes',
+					dependent: 'yes',
+					toolbar: 'yes',
+					menubar: 'no',
+					resizable: 'yes',
+					scrollbars: 'yes',
+					status: 'no'
+				}, {
+					plugin_url : url
+				});
+			});
 			
 			// Register buttons
 			ed.addButton('inlinecode', {
 				title: 'dcControls.inlinecode_desc',
-				cmd: 'dcCode',
-				image: url + '/img/code.png'
+				cmd: 'dcCode'
 			});
 			ed.addButton('quote', {
 				title: 'dcControls.quote_desc',
-				cmd: 'dcQuote',
-				image: url + '/img/quote.png'
+				cmd: 'dcQuote'
 			});
 			ed.addButton('link', {
-				title: 'dcControls.link_desc',
+				title: 'advanced.link_desc',
 				cmd: 'dcLink'
 			});
 			ed.addButton('media', {
 				title: 'dcControls.media_desc',
-				cmd: 'dcMedia',
-				image: url + '/img/media.png'
+				cmd: 'dcMedia'
+			});
+			ed.addButton('webmedia', {
+				title: 'dcControls.webmedia_desc',
+				cmd: 'dcWebMedia'
 			});
 			
@@ -95,5 +116,7 @@
 			ed.addShortcut('alt+shift+q', 'dcControls.quote_desc', 'dcQuote');
 			ed.addShortcut('alt+shift+l', 'dcControls.link_desc', 'dcLink');
+			ed.addShortcut('alt+shift+i', 'dcControls.imglink_desc', 'dcImgLink');
 			ed.addShortcut('alt+shift+m', 'dcControls.media_desc', 'dcMedia');
+			ed.addShortcut('alt+shift+w', 'dcControls.media_desc', 'dcWebMedia');
 			
 			// Register changes management
Index: admin/js/tiny_mce/plugins/dcControls/js/popup_web_media.js
===================================================================
--- admin/js/tiny_mce/plugins/dcControls/js/popup_web_media.js	(revision 381)
+++ admin/js/tiny_mce/plugins/dcControls/js/popup_web_media.js	(revision 381)
@@ -0,0 +1,150 @@
+tinyMCEPopup.requireLangPack();
+
+var popup_web_media = {
+	oembed_opts: {
+		maxWidth: 480,
+		maxHeight: 400,
+		defaultOEmbedProvider: 'embed.ly',
+		greedy: false,
+		embedMethod: 'fill',
+		onProviderNotFound: function(url) {
+			$('#src').removeClass().addClass('error');
+			alert('Provider not supported');
+		},
+		beforeEmbed: function(data) {
+			if (data.type == 'error') {
+				$('#src').removeClass().addClass('error');
+			} else {
+				$('#src').removeClass().addClass('success');
+				if (!data.thumbnail_url) {
+					$('input[value="thumbnail"]').attr('disabled',true);
+				} else {
+					$('input[value="thumbnail"]').attr('disabled',false);
+				}
+				$('div.two-cols').slideDown();
+			}
+		},
+		afterEmbed: function(data) {
+			if (data.type != 'error') {
+				var attr = new Array();
+				if (data.provider_name) attr.push(data.provider_name);
+				if (data.author_name) attr.push(data.author_name);
+				if (data.title) attr.push(data.title);
+				
+				$('#alt').val(attr.join(' - '));
+				$('#title').val(data.title);
+				
+				if (data.width) $('#width').val(data.width);
+				if (data.height) $('#height').val(data.height);
+				
+				if (!data.thumbnail_url) {
+					$('input[name="insertion" value="thumbnail"]').attr('disabled', 'disabled');
+				}
+				
+				$(this).data('code',popup_web_media.getValidXHTMLCode(data.html));
+			}
+		},
+		onEmbed: function(data) {
+			$(this).data('code',popup_web_media.getValidXHTMLCode(data.html));
+		},
+		onError: function(xhr,status,error) {
+			$('#src').removeClass().addClass('error');
+		},
+		ajaxOptions: {
+			cache: false,
+			timeout: 5000
+		}
+	},
+	
+	init: function() {
+		$('#src').focusin(function() {
+			$(this).removeClass();
+		});
+		
+		$('#webmedia-insert-search').click(function() {
+			if ($('#src').val() == '') {
+				return;
+			}
+			
+			$('div.two-cols').slideUp();
+			
+			$('#src').removeClass().addClass('loading');
+			
+			$('#alt,#title').val('');
+			
+			$('div.preview').data('code',null);
+			$('div.preview').oembed($('#src').val(),popup_web_media.oembed_opts);
+		});
+		
+		$('#webmedia-insert-ok').click(function(){
+			var ed = tinyMCEPopup.editor;
+			var xhtml = $('div.preview').data('code');
+			
+			if (xhtml != null) {
+				ed.execCommand('mceInsertContent',false,xhtml.get(0).outerHTML)
+				tinyMCEPopup.close();
+			} else {
+				alert('provide a valide media');
+			}
+		});
+		
+		$('#webmedia-insert-cancel').click(function(){
+			tinyMCEPopup.close();
+		});
+	},
+	
+	getOEmbedListInfo: function(data,attr) {
+		var info = $('<ul>');
+		for (i in data) {
+			if (attr.hasOwnProperty(i)) {
+				info.append($('<li>').append(attr[i] + ': ' + data[i]));
+			}
+			
+		}
+		return info;
+	},
+	
+	getValidXHTMLCode: function(html) {
+		var xhtml = $(html);
+		var type = xhtml.get(0).tagName;
+		
+		if (type == 'IFRAME') {
+			var attr = {
+				'src': 'data',
+				'width': 'width',
+				'height': 'height'
+			};
+			var attributes = xhtml.get(0).attributes;
+			xhtml = $('<object>');
+			xhtml.attr('type','text/html');
+			for (i in attributes) {
+				if (attr.hasOwnProperty(attributes[i].name)) {
+					xhtml.attr(attr[attributes[i].name],attributes[i].value);
+				}
+			}
+		} 
+		else if (type == 'OBJECT') {
+			if (xhtml.find('embed').size() > 0) {
+				var embed = xhtml.find('embed').get(0);
+				if ($.inArray('src',embed.attributes)) {
+					xhtml.attr('data',embed.attributes.src.nodeValue);
+				}
+				if ($.inArray('type',embed.attributes)) {
+					xhtml.attr('type',embed.attributes.type.nodeValue);
+				}
+				xhtml.find('embed').remove();
+			}
+		}
+		else {
+			xhtml = this.getValidXHTMLCode(xhtml.find('iframe,object').get(0).outerHTML);
+		}
+		
+		return xhtml;
+	}
+};
+
+function plop(data) {
+	alert(data.type);
+}
+
+tinyMCEPopup.onInit.add(popup_web_media.init, popup_web_media);
