Index: wp-includes/js/tinymce/plugins/wplink/js/wplink.dev.js
===================================================================
--- wp-includes/js/tinymce/plugins/wplink/js/wplink.dev.js	(revision 17680)
+++ wp-includes/js/tinymce/plugins/wplink/js/wplink.dev.js	(working copy)
@@ -9,6 +9,8 @@
 		riverBottomThreshold: 5,
 		keySensitivity: 100,
 		lastSearch: '',
+		textarea: edCanvas,
+
 		init : function() {
 			inputs.dialog = $('#wp-link');
 			inputs.submit = $('#wp-link-submit');
@@ -31,7 +33,7 @@
 				wpLink.update();
 				e.preventDefault();
 			});
-			$('#wp-link-cancel').click( wpLink.cancel );
+			$('#wp-link-cancel').click( wpLink.close );
 			$('#internal-toggle').click( wpLink.toggleInternalLinking );
 
 			rivers.elements.bind('river-select', wpLink.updateFields );
@@ -39,16 +41,62 @@
 			inputs.search.keyup( wpLink.searchInternalLinks );
 
 			inputs.dialog.bind('wpdialogrefresh', wpLink.refresh);
+			inputs.dialog.bind('wpdialogbeforeopen', wpLink.beforeOpen);
+			inputs.dialog.bind('wpdialogclose', wpLink.onClose);
 		},
 
+		beforeOpen : function() {
+			wpLink.range = null;
+
+			if ( ! wpLink.isMCE() && document.selection ) {
+				wpLink.textarea.focus();
+				wpLink.range = document.selection.createRange();
+			}
+		},
+
+		open : function() {
+			// Initialize the dialog if necessary (html mode).
+			if ( ! inputs.dialog.data('wpdialog') ) {
+				inputs.dialog.wpdialog({
+					title: wpLinkL10n.title,
+					width: 480,
+					height: 'auto',
+					modal: true,
+					dialogClass: 'wp-dialog',
+					zIndex: 300000
+				});
+			}
+
+			inputs.dialog.wpdialog('open');
+		},
+
+		isMCE : function() {
+			return tinyMCEPopup && ( ed = tinyMCEPopup.editor ) && ! ed.isHidden();
+		},
+
 		refresh : function() {
-			var e;
-			ed = tinyMCEPopup.editor;
-
 			// Refresh rivers (clear links, check visibility)
 			rivers.search.refresh();
 			rivers.recent.refresh();
 
+			if ( wpLink.isMCE() )
+				wpLink.mceRefresh();
+			else
+				wpLink.setDefaultValues();
+
+			// Focus the URL field and highlight its contents.
+			//     If this is moved above the selection changes,
+			//     IE will show a flashing cursor over the dialog.
+			inputs.url.focus()[0].select();
+			// Load the most recent results if this is the first time opening the panel.
+			if ( ! rivers.recent.ul.children().length )
+				rivers.recent.ajax();
+		},
+
+		mceRefresh : function() {
+			var e;
+			ed = tinyMCEPopup.editor;
+
 			tinyMCEPopup.restoreSelection();
 
 			// If link exists, select proper values.
@@ -65,31 +113,106 @@
 			// If there's no link, set the default values.
 			} else {
 				wpLink.setDefaultValues();
-				// Update save prompt.
-				inputs.submit.val( wpLinkL10n.save );
 			}
 
 			tinyMCEPopup.storeSelection();
-			// Focus the URL field and highlight its contents.
-			//     If this is moved above the selection changes,
-			//     IE will show a flashing cursor over the dialog.
-			inputs.url.focus()[0].select();
-			// Load the most recent results if this is the first time opening the panel.
-			if ( ! rivers.recent.ul.children().length )
-				rivers.recent.ajax();
 		},
 
-		cancel : function() {
-			tinyMCEPopup.close();
+		close : function() {
+			if ( wpLink.isMCE() )
+				tinyMCEPopup.close();
+			else
+				inputs.dialog.wpdialog('close');
 		},
 
+		onClose: function() {
+			if ( ! wpLink.isMCE() ) {
+				wpLink.textarea.focus();
+				if ( wpLink.range ) {
+					wpLink.range.moveToBookmark( wpLink.range.getBookmark() );
+					wpLink.range.select();
+				}
+			}
+		},
+
+		getAttrs : function() {
+			return {
+				href : inputs.url.val(),
+				title : inputs.title.val(),
+				target : inputs.openInNewTab.attr('checked') ? '_blank' : ''
+			};
+		},
+
 		update : function() {
+			if ( wpLink.isMCE() )
+				wpLink.mceUpdate();
+			else
+				wpLink.htmlUpdate();
+		},
+
+		htmlUpdate : function() {
+			var attrs, html, start, end, cursor,
+				textarea = wpLink.textarea;
+
+			if ( ! textarea )
+				return;
+
+			attrs = wpLink.getAttrs();
+
+			// If there's no href, return.
+			if ( ! attrs.href || attrs.href == 'http://' )
+				return;
+
+			// Build HTML
+			html = '<a href="' + attrs.href + '"';
+
+			if ( attrs.title )
+				html += ' title="' + attrs.title + '"';
+			if ( attrs.target )
+				html += ' target="' + attrs.target + '"';
+
+			html += '>';
+
+			// Insert HTML
+			// W3C
+			if ( typeof textarea.selectionStart !== 'undefined' ) {
+				start       = textarea.selectionStart;
+				end         = textarea.selectionEnd;
+				selection   = textarea.value.substring( start, end );
+				html        = html + selection + '</a>';
+				cursor      = start + html.length;
+
+				// If no next is selected, place the cursor inside the closing tag.
+				if ( start == end )
+					cursor -= '</a>'.length;
+
+				textarea.value = textarea.value.substring( 0, start )
+				               + html
+				               + textarea.value.substring( end, textarea.value.length );
+
+				// Update cursor position
+				textarea.selectionStart = textarea.selectionEnd = cursor;
+
+			// IE
+			// Note: If no text is selected, IE will not place the cursor
+			//       inside the closing tag.
+			} else if ( document.selection && wpLink.range ) {
+				textarea.focus();
+				wpLink.range.text = html + wpLink.range.text + '</a>';
+				wpLink.range.moveToBookmark( wpLink.range.getBookmark() );
+				wpLink.range.select();
+
+				wpLink.range = null;
+			}
+
+			wpLink.close();
+			textarea.focus();
+		},
+
+		mceUpdate : function() {
 			var ed = tinyMCEPopup.editor,
-				attrs = {
-					href : inputs.url.val(),
-					title : inputs.title.val(),
-					target : inputs.openInNewTab.attr('checked') ? '_blank' : ''
-				}, e, b;
+				attrs = wpLink.getAttrs(),
+				e, b;
 
 			tinyMCEPopup.restoreSelection();
 			e = ed.dom.getParent(ed.selection.getNode(), 'A');
@@ -102,7 +225,7 @@
 					ed.dom.remove(e, 1);
 					ed.selection.moveToBookmark(b);
 					tinyMCEPopup.execCommand("mceEndUndoLevel");
-					tinyMCEPopup.close();
+					wpLink.close();
 				}
 				return;
 			}
@@ -140,7 +263,7 @@
 			}
 
 			tinyMCEPopup.execCommand("mceEndUndoLevel");
-			tinyMCEPopup.close();
+			wpLink.close();
 		},
 
 		updateFields : function( e, li, originalEvent ) {
@@ -154,6 +277,9 @@
 			// Leave the new tab setting as-is.
 			inputs.url.val('http://');
 			inputs.title.val('');
+
+			// Update save prompt.
+			inputs.submit.val( wpLinkL10n.save );
 		},
 
 		searchInternalLinks : function() {
@@ -210,7 +336,7 @@
 
 			switch( event.which ) {
 				case key.ESCAPE:
-					wpLink.cancel();
+					wpLink.close();
 					break;
 				case key.UP:
 				case key.DOWN:
Index: wp-includes/js/tinymce/plugins/wpdialogs/editor_plugin.js
===================================================================
--- wp-includes/js/tinymce/plugins/wpdialogs/editor_plugin.js	(revision 17680)
+++ wp-includes/js/tinymce/plugins/wpdialogs/editor_plugin.js	(working copy)
@@ -1 +1 @@
-(function(b){var a=function(c){return function(){if(this.features.wpDialog){return c.apply(this,arguments)}else{return this.parent.apply(this,arguments)}}};tinymce.create("tinymce.plugins.WPDialogs",{init:function(c,d){c.onBeforeRenderUI.add(function(){c.windowManager=new tinymce.WPWindowManager(c)})},getInfo:function(){return{longname:"WPDialogs",author:"WordPress",authorurl:"http://wordpress.org",infourl:"http://wordpress.org",version:"0.1"}}});b(document).ready(function(){b.widget("wp.wpdialog",b.ui.dialog,{open:function(){if(tinyMCEPopup){tinyMCEPopup.init()}b.ui.dialog.prototype.open.apply(this,arguments);this.element.focus();this._trigger("refresh")}})});tinymce.create("tinymce.WPWindowManager:tinymce.InlineWindowManager",{WPWindowManager:function(c){this.parent(c)},open:function(e,g){var d=this,c;if(!e.wpDialog){return this.parent(e,g)}else{if(!e.id){return}}c=b("#"+e.id);if(!c.length){return}d.features=e;d.params=g;d.onOpen.dispatch(d,e,g);d.element=d.windows[e.id]=c;d.bookmark=d.editor.selection.getBookmark(1);c.wpdialog({title:e.title,width:e.width,height:e.height,modal:true,dialogClass:"wp-dialog",zIndex:300000})},close:a(function(){this.element.wpdialog("close")})});tinymce.PluginManager.add("wpdialogs",tinymce.plugins.WPDialogs)})(jQuery);
\ No newline at end of file
+(function(){tinymce.create("tinymce.plugins.WPDialogs",{init:function(a,b){tinymce.create("tinymce.WPWindowManager:tinymce.InlineWindowManager",{WPWindowManager:function(c){this.parent(c)},open:function(e,g){var d=this,c;if(!e.wpDialog){return this.parent(e,g)}else{if(!e.id){return}}c=jQuery("#"+e.id);if(!c.length){return}d.features=e;d.params=g;d.onOpen.dispatch(d,e,g);d.element=d.windows[e.id]=c;d.bookmark=d.editor.selection.getBookmark(1);if(!c.data("wpdialog")){c.wpdialog({title:e.title,width:e.width,height:e.height,modal:true,dialogClass:"wp-dialog",zIndex:300000})}c.wpdialog("open")},close:function(){if(!this.features.wpDialog){return this.parent.apply(this,arguments)}this.element.wpdialog("close")}});a.onBeforeRenderUI.add(function(){a.windowManager=new tinymce.WPWindowManager(a)})},getInfo:function(){return{longname:"WPDialogs",author:"WordPress",authorurl:"http://wordpress.org",infourl:"http://wordpress.org",version:"0.1"}}});tinymce.PluginManager.add("wpdialogs",tinymce.plugins.WPDialogs)})();
\ No newline at end of file
Index: wp-includes/js/tinymce/plugins/wpdialogs/js/wpdialog.dev.js
===================================================================
--- wp-includes/js/tinymce/plugins/wpdialogs/js/wpdialog.dev.js	(revision 0)
+++ wp-includes/js/tinymce/plugins/wpdialogs/js/wpdialog.dev.js	(revision 0)
@@ -0,0 +1,21 @@
+(function($){
+	$.widget("wp.wpdialog", $.ui.dialog, {
+		open: function() {
+			// Initialize tinyMCEPopup if it exists and is the editor is active.
+			if ( tinyMCEPopup && typeof tinyMCE != 'undefined' && ( ed = tinyMCE.activeEditor ) && !ed.isHidden() ) {
+				tinyMCEPopup.init();
+			}
+
+			// Add beforeOpen event.
+			if ( this._isOpen || false === this._trigger('beforeOpen') ) {
+				return;
+			}
+
+			// Open the dialog.
+			$.ui.dialog.prototype.open.apply( this, arguments );
+			// WebKit leaves focus in the TinyMCE editor unless we shift focus.
+			this.element.focus();
+			this._trigger('refresh');
+		}
+	});
+})(jQuery);
\ No newline at end of file
Index: wp-includes/js/tinymce/plugins/wpdialogs/editor_plugin.dev.js
===================================================================
--- wp-includes/js/tinymce/plugins/wpdialogs/editor_plugin.dev.js	(revision 17680)
+++ wp-includes/js/tinymce/plugins/wpdialogs/editor_plugin.dev.js	(working copy)
@@ -8,18 +8,56 @@
  * Contributing: http://tinymce.moxiecode.com/contributing
  */
 
-(function($) {
-	var wpDialogFn = function( fn ) {
-		return function() {
-			if ( this.features.wpDialog )
-				return fn.apply( this, arguments );
-			else
-				return this.parent.apply( this, arguments );
-		};
-	};
-
+(function() {
 	tinymce.create('tinymce.plugins.WPDialogs', {
 		init : function(ed, url) {
+			tinymce.create('tinymce.WPWindowManager:tinymce.InlineWindowManager', {
+				WPWindowManager : function(ed) {
+					this.parent(ed);
+				},
+
+				open : function(f, p) {
+					var t = this, element;
+
+					if ( ! f.wpDialog )
+						return this.parent( f, p );
+					else if ( ! f.id )
+						return;
+
+					element = jQuery('#' + f.id);
+					if ( ! element.length )
+						return;
+
+					t.features = f;
+					t.params = p;
+					t.onOpen.dispatch(t, f, p);
+					t.element = t.windows[ f.id ] = element;
+
+					// Store selection
+					t.bookmark = t.editor.selection.getBookmark(1);
+
+					// Create the dialog if necessary
+					if ( ! element.data('wpdialog') ) {
+						element.wpdialog({
+							title: f.title,
+							width: f.width,
+							height: f.height,
+							modal: true,
+							dialogClass: 'wp-dialog',
+							zIndex: 300000
+						});
+					}
+
+					element.wpdialog('open');
+				},
+				close : function() {
+					if ( ! this.features.wpDialog )
+						return this.parent.apply( this, arguments );
+
+					this.element.wpdialog('close');
+				}
+			});
+
 			// Replace window manager
 			ed.onBeforeRenderUI.add(function() {
 				ed.windowManager = new tinymce.WPWindowManager(ed);
@@ -36,62 +74,7 @@
 			};
 		}
 	});
-	
-	$(document).ready(function() {
-		$.widget("wp.wpdialog", $.ui.dialog, {
-			open: function() {
-				// Initialize tinyMCEPopup if it exists.
-				if ( tinyMCEPopup )
-					tinyMCEPopup.init();
-				// Open the dialog.
-				$.ui.dialog.prototype.open.apply( this, arguments );
-				// WebKit leaves focus in the TinyMCE editor unless we shift focus.
-				this.element.focus();
-				this._trigger('refresh');
-			}
-		});
-	});
 
-	tinymce.create('tinymce.WPWindowManager:tinymce.InlineWindowManager', {
-		WPWindowManager : function(ed) {
-			this.parent(ed);
-		},
-
-		open : function(f, p) {
-			var t = this, element;
-			// Can't use wpDialogFn here; this.features isn't set yet.
-			if ( ! f.wpDialog )
-				return this.parent( f, p );
-			else if ( ! f.id )
-				return;
-			
-			element = $('#' + f.id);
-			if ( ! element.length )
-				return;
-			
-			t.features = f;
-			t.params = p;
-			t.onOpen.dispatch(t, f, p);
-			t.element = t.windows[ f.id ] = element;
-			
-			// Store selection
-			t.bookmark = t.editor.selection.getBookmark(1);
-			
-			element.wpdialog({
-				title: f.title,
-				width: f.width,
-				height: f.height,
-				modal: true,
-				dialogClass: 'wp-dialog',
-				zIndex: 300000
-			});
-		},
-		close : wpDialogFn(function() {
-			this.element.wpdialog('close');
-		})
-	});
-
 	// Register plugin
 	tinymce.PluginManager.add('wpdialogs', tinymce.plugins.WPDialogs);
-})(jQuery);
-
+})();
Index: wp-includes/js/quicktags.dev.js
===================================================================
--- wp-includes/js/quicktags.dev.js	(revision 17680)
+++ wp-includes/js/quicktags.dev.js	(working copy)
@@ -157,7 +157,7 @@
 		document.write('<input type="button" id="' + button.id + '" accesskey="' + button.access + '" class="ed_button" onclick="edInsertImage(edCanvas);" value="' + button.display + '" />');
 	}
 	else if (button.id == 'ed_link') {
-		document.write('<input type="button" id="' + button.id + '" accesskey="' + button.access + '" class="ed_button" onclick="edInsertLink(edCanvas, ' + i + ');" value="' + button.display + '" />');
+		document.write('<input type="button" id="' + button.id + '" accesskey="' + button.access + '" class="ed_button" onclick="wpLink.open();" value="' + button.display + '" />');
 	}
 	else {
 		document.write('<input type="button" id="' + button.id + '" accesskey="' + button.access + '" class="ed_button" onclick="edInsertTag(edCanvas, ' + i + ');" value="' + button.display + '"  />');
Index: wp-includes/script-loader.php
===================================================================
--- wp-includes/script-loader.php	(revision 17680)
+++ wp-includes/script-loader.php	(working copy)
@@ -267,8 +267,9 @@
 	$scripts->add( 'admin-bar', "/wp-includes/js/admin-bar$suffix.js", false, '20110131' );
 	$scripts->add_data( 'admin-bar', 'group', 1 );
 
-	$scripts->add( 'wplink', "/wp-includes/js/tinymce/plugins/wplink/js/wplink$suffix.js", array('jquery'), '20110111' );
+	$scripts->add( 'wplink', "/wp-includes/js/tinymce/plugins/wplink/js/wplink$suffix.js", array( 'jquery', 'wpdialogs' ), '20110421' );
 	$scripts->localize( 'wplink', 'wpLinkL10n', array(
+		'title' => __('Insert/edit link'),
 		'update' => __('Update'),
 		'save' => __('Add Link'),
 		'noTitle' => __('(no title)'),
@@ -276,7 +277,8 @@
 		'l10n_print_after' => 'try{convertEntities(wpLinkL10n);}catch(e){};',
 	) );
 
-	$scripts->add( 'wpdialogs-popup', "/wp-includes/js/tinymce/plugins/wpdialogs/js/popup$suffix.js", array( 'jquery-ui-dialog' ), '20101119' );
+	$scripts->add( 'wpdialogs', "/wp-includes/js/tinymce/plugins/wpdialogs/js/wpdialog$suffix.js", array( 'jquery-ui-dialog' ), '20110421' );
+	$scripts->add( 'wpdialogs-popup', "/wp-includes/js/tinymce/plugins/wpdialogs/js/popup$suffix.js", array( 'wpdialogs' ), '20110421' );
 
 	if ( is_admin() ) {
 		$scripts->add( 'ajaxcat', "/wp-admin/js/cat$suffix.js", array( 'wp-lists' ), '20090102' );
