src/pyams_skin/resources/js/ext/tinymce/dev/plugins/link/plugin.js
changeset 557 bca7a7e058a3
equal deleted inserted replaced
-1:000000000000 557:bca7a7e058a3
       
     1 /**
       
     2  * plugin.js
       
     3  *
       
     4  * Copyright, Moxiecode Systems AB
       
     5  * Released under LGPL License.
       
     6  *
       
     7  * License: http://www.tinymce.com/license
       
     8  * Contributing: http://www.tinymce.com/contributing
       
     9  */
       
    10 
       
    11 /*global tinymce:true */
       
    12 
       
    13 tinymce.PluginManager.add('link', function(editor) {
       
    14 	function createLinkList(callback) {
       
    15 		return function() {
       
    16 			var linkList = editor.settings.link_list;
       
    17 
       
    18 			if (typeof linkList == "string") {
       
    19 				tinymce.util.XHR.send({
       
    20 					url: linkList,
       
    21 					success: function(text) {
       
    22 						callback(tinymce.util.JSON.parse(text));
       
    23 					}
       
    24 				});
       
    25 			} else if (typeof linkList == "function") {
       
    26 				linkList(callback);
       
    27 			} else {
       
    28 				callback(linkList);
       
    29 			}
       
    30 		};
       
    31 	}
       
    32 
       
    33 	function buildListItems(inputList, itemCallback, startItems) {
       
    34 		function appendItems(values, output) {
       
    35 			output = output || [];
       
    36 
       
    37 			tinymce.each(values, function(item) {
       
    38 				var menuItem = {text: item.text || item.title};
       
    39 
       
    40 				if (item.menu) {
       
    41 					menuItem.menu = appendItems(item.menu);
       
    42 				} else {
       
    43 					menuItem.value = item.value;
       
    44 
       
    45 					if (itemCallback) {
       
    46 						itemCallback(menuItem);
       
    47 					}
       
    48 				}
       
    49 
       
    50 				output.push(menuItem);
       
    51 			});
       
    52 
       
    53 			return output;
       
    54 		}
       
    55 
       
    56 		return appendItems(inputList, startItems || []);
       
    57 	}
       
    58 
       
    59 	function showDialog(linkList) {
       
    60 		var data = {}, selection = editor.selection, dom = editor.dom, selectedElm, anchorElm, initialText;
       
    61 		var win, onlyText, textListCtrl, linkListCtrl, relListCtrl, targetListCtrl, classListCtrl, linkTitleCtrl, value;
       
    62 
       
    63 		function linkListChangeHandler(e) {
       
    64 			var textCtrl = win.find('#text');
       
    65 
       
    66 			if (!textCtrl.value() || (e.lastControl && textCtrl.value() == e.lastControl.text())) {
       
    67 				textCtrl.value(e.control.text());
       
    68 			}
       
    69 
       
    70 			win.find('#href').value(e.control.value());
       
    71 		}
       
    72 
       
    73 		function buildAnchorListControl(url) {
       
    74 			var anchorList = [];
       
    75 
       
    76 			tinymce.each(editor.dom.select('a:not([href])'), function(anchor) {
       
    77 				var id = anchor.name || anchor.id;
       
    78 
       
    79 				if (id) {
       
    80 					anchorList.push({
       
    81 						text: id,
       
    82 						value: '#' + id,
       
    83 						selected: url.indexOf('#' + id) != -1
       
    84 					});
       
    85 				}
       
    86 			});
       
    87 
       
    88 			if (anchorList.length) {
       
    89 				anchorList.unshift({text: 'None', value: ''});
       
    90 
       
    91 				return {
       
    92 					name: 'anchor',
       
    93 					type: 'listbox',
       
    94 					label: 'Anchors',
       
    95 					values: anchorList,
       
    96 					onselect: linkListChangeHandler
       
    97 				};
       
    98 			}
       
    99 		}
       
   100 
       
   101 		function updateText() {
       
   102 			if (!initialText && data.text.length === 0 && onlyText) {
       
   103 				this.parent().parent().find('#text')[0].value(this.value());
       
   104 			}
       
   105 		}
       
   106 
       
   107 		function urlChange(e) {
       
   108 			var meta = e.meta || {};
       
   109 
       
   110 			if (linkListCtrl) {
       
   111 				linkListCtrl.value(editor.convertURL(this.value(), 'href'));
       
   112 			}
       
   113 
       
   114 			tinymce.each(e.meta, function(value, key) {
       
   115 				win.find('#' + key).value(value);
       
   116 			});
       
   117 
       
   118 			if (!meta.text) {
       
   119 				updateText.call(this);
       
   120 			}
       
   121 		}
       
   122 
       
   123 		function isOnlyTextSelected(anchorElm) {
       
   124 			var html = selection.getContent();
       
   125 
       
   126 			// Partial html and not a fully selected anchor element
       
   127 			if (/</.test(html) && (!/^<a [^>]+>[^<]+<\/a>$/.test(html) || html.indexOf('href=') == -1)) {
       
   128 				return false;
       
   129 			}
       
   130 
       
   131 			if (anchorElm) {
       
   132 				var nodes = anchorElm.childNodes, i;
       
   133 
       
   134 				if (nodes.length === 0) {
       
   135 					return false;
       
   136 				}
       
   137 
       
   138 				for (i = nodes.length - 1; i >= 0; i--) {
       
   139 					if (nodes[i].nodeType != 3) {
       
   140 						return false;
       
   141 					}
       
   142 				}
       
   143 			}
       
   144 
       
   145 			return true;
       
   146 		}
       
   147 
       
   148 		selectedElm = selection.getNode();
       
   149 		anchorElm = dom.getParent(selectedElm, 'a[href]');
       
   150 		onlyText = isOnlyTextSelected();
       
   151 
       
   152 		data.text = initialText = anchorElm ? (anchorElm.innerText || anchorElm.textContent) : selection.getContent({format: 'text'});
       
   153 		data.href = anchorElm ? dom.getAttrib(anchorElm, 'href') : '';
       
   154 
       
   155 		if (anchorElm) {
       
   156 			data.target = dom.getAttrib(anchorElm, 'target');
       
   157 		} else if (editor.settings.default_link_target) {
       
   158 			data.target = editor.settings.default_link_target;
       
   159 		}
       
   160 
       
   161 		if ((value = dom.getAttrib(anchorElm, 'rel'))) {
       
   162 			data.rel = value;
       
   163 		}
       
   164 
       
   165 		if ((value = dom.getAttrib(anchorElm, 'class'))) {
       
   166 			data['class'] = value;
       
   167 		}
       
   168 
       
   169 		if ((value = dom.getAttrib(anchorElm, 'title'))) {
       
   170 			data.title = value;
       
   171 		}
       
   172 
       
   173 		if (onlyText) {
       
   174 			textListCtrl = {
       
   175 				name: 'text',
       
   176 				type: 'textbox',
       
   177 				size: 40,
       
   178 				label: 'Text to display',
       
   179 				onchange: function() {
       
   180 					data.text = this.value();
       
   181 				}
       
   182 			};
       
   183 		}
       
   184 
       
   185 		if (linkList) {
       
   186 			linkListCtrl = {
       
   187 				type: 'listbox',
       
   188 				label: 'Link list',
       
   189 				values: buildListItems(
       
   190 					linkList,
       
   191 					function(item) {
       
   192 						item.value = editor.convertURL(item.value || item.url, 'href');
       
   193 					},
       
   194 					[{text: 'None', value: ''}]
       
   195 				),
       
   196 				onselect: linkListChangeHandler,
       
   197 				value: editor.convertURL(data.href, 'href'),
       
   198 				onPostRender: function() {
       
   199 					linkListCtrl = this;
       
   200 				}
       
   201 			};
       
   202 		}
       
   203 
       
   204 		if (editor.settings.target_list !== false) {
       
   205 			if (!editor.settings.target_list) {
       
   206 				editor.settings.target_list = [
       
   207 					{text: 'None', value: ''},
       
   208 					{text: 'New window', value: '_blank'}
       
   209 				];
       
   210 			}
       
   211 
       
   212 			targetListCtrl = {
       
   213 				name: 'target',
       
   214 				type: 'listbox',
       
   215 				label: 'Target',
       
   216 				values: buildListItems(editor.settings.target_list)
       
   217 			};
       
   218 		}
       
   219 
       
   220 		if (editor.settings.rel_list) {
       
   221 			relListCtrl = {
       
   222 				name: 'rel',
       
   223 				type: 'listbox',
       
   224 				label: 'Rel',
       
   225 				values: buildListItems(editor.settings.rel_list)
       
   226 			};
       
   227 		}
       
   228 
       
   229 		if (editor.settings.link_class_list) {
       
   230 			classListCtrl = {
       
   231 				name: 'class',
       
   232 				type: 'listbox',
       
   233 				label: 'Class',
       
   234 				values: buildListItems(
       
   235 					editor.settings.link_class_list,
       
   236 					function(item) {
       
   237 						if (item.value) {
       
   238 							item.textStyle = function() {
       
   239 								return editor.formatter.getCssText({inline: 'a', classes: [item.value]});
       
   240 							};
       
   241 						}
       
   242 					}
       
   243 				)
       
   244 			};
       
   245 		}
       
   246 
       
   247 		if (editor.settings.link_title !== false) {
       
   248 			linkTitleCtrl = {
       
   249 				name: 'title',
       
   250 				type: 'textbox',
       
   251 				label: 'Title',
       
   252 				value: data.title
       
   253 			};
       
   254 		}
       
   255 
       
   256 		win = editor.windowManager.open({
       
   257 			title: 'Insert link',
       
   258 			data: data,
       
   259 			body: [
       
   260 				{
       
   261 					name: 'href',
       
   262 					type: 'filepicker',
       
   263 					filetype: 'file',
       
   264 					size: 40,
       
   265 					autofocus: true,
       
   266 					label: 'Url',
       
   267 					onchange: urlChange,
       
   268 					onkeyup: updateText
       
   269 				},
       
   270 				textListCtrl,
       
   271 				linkTitleCtrl,
       
   272 				buildAnchorListControl(data.href),
       
   273 				linkListCtrl,
       
   274 				relListCtrl,
       
   275 				targetListCtrl,
       
   276 				classListCtrl
       
   277 			],
       
   278 			onSubmit: function(e) {
       
   279 				/*eslint dot-notation: 0*/
       
   280 				var href;
       
   281 
       
   282 				data = tinymce.extend(data, e.data);
       
   283 				href = data.href;
       
   284 
       
   285 				// Delay confirm since onSubmit will move focus
       
   286 				function delayedConfirm(message, callback) {
       
   287 					var rng = editor.selection.getRng();
       
   288 
       
   289 					window.setTimeout(function() {
       
   290 						editor.windowManager.confirm(message, function(state) {
       
   291 							editor.selection.setRng(rng);
       
   292 							callback(state);
       
   293 						});
       
   294 					}, 0);
       
   295 				}
       
   296 
       
   297 				function insertLink() {
       
   298 					var linkAttrs = {
       
   299 						href: href,
       
   300 						target: data.target ? data.target : null,
       
   301 						rel: data.rel ? data.rel : null,
       
   302 						"class": data["class"] ? data["class"] : null,
       
   303 						title: data.title ? data.title : null
       
   304 					};
       
   305 
       
   306 					if (anchorElm) {
       
   307 						editor.focus();
       
   308 
       
   309 						if (onlyText && data.text != initialText) {
       
   310 							if ("innerText" in anchorElm) {
       
   311 								anchorElm.innerText = data.text;
       
   312 							} else {
       
   313 								anchorElm.textContent = data.text;
       
   314 							}
       
   315 						}
       
   316 
       
   317 						dom.setAttribs(anchorElm, linkAttrs);
       
   318 
       
   319 						selection.select(anchorElm);
       
   320 						editor.undoManager.add();
       
   321 					} else {
       
   322 						if (onlyText) {
       
   323 							editor.insertContent(dom.createHTML('a', linkAttrs, dom.encode(data.text)));
       
   324 						} else {
       
   325 							editor.execCommand('mceInsertLink', false, linkAttrs);
       
   326 						}
       
   327 					}
       
   328 				}
       
   329 
       
   330 				if (!href) {
       
   331 					editor.execCommand('unlink');
       
   332 					return;
       
   333 				}
       
   334 
       
   335 				// Is email and not //user@domain.com
       
   336 				if (href.indexOf('@') > 0 && href.indexOf('//') == -1 && href.indexOf('mailto:') == -1) {
       
   337 					delayedConfirm(
       
   338 						'The URL you entered seems to be an email address. Do you want to add the required mailto: prefix?',
       
   339 						function(state) {
       
   340 							if (state) {
       
   341 								href = 'mailto:' + href;
       
   342 							}
       
   343 
       
   344 							insertLink();
       
   345 						}
       
   346 					);
       
   347 
       
   348 					return;
       
   349 				}
       
   350 
       
   351 				// Is not protocol prefixed
       
   352 				if ((editor.settings.link_assume_external_targets && !/^\w+:/i.test(href)) ||
       
   353 					(!editor.settings.link_assume_external_targets && /^\s*www\./i.test(href))) {
       
   354 					delayedConfirm(
       
   355 						'The URL you entered seems to be an external link. Do you want to add the required http:// prefix?',
       
   356 						function(state) {
       
   357 							if (state) {
       
   358 								href = 'http://' + href;
       
   359 							}
       
   360 
       
   361 							insertLink();
       
   362 						}
       
   363 					);
       
   364 
       
   365 					return;
       
   366 				}
       
   367 
       
   368 				insertLink();
       
   369 			}
       
   370 		});
       
   371 	}
       
   372 
       
   373 	editor.addButton('link', {
       
   374 		icon: 'link',
       
   375 		tooltip: 'Insert/edit link',
       
   376 		shortcut: 'Meta+K',
       
   377 		onclick: createLinkList(showDialog),
       
   378 		stateSelector: 'a[href]'
       
   379 	});
       
   380 
       
   381 	editor.addButton('unlink', {
       
   382 		icon: 'unlink',
       
   383 		tooltip: 'Remove link',
       
   384 		cmd: 'unlink',
       
   385 		stateSelector: 'a[href]'
       
   386 	});
       
   387 
       
   388 	editor.addShortcut('Meta+K', '', createLinkList(showDialog));
       
   389 	editor.addCommand('mceLink', createLinkList(showDialog));
       
   390 
       
   391 	this.showDialog = showDialog;
       
   392 
       
   393 	editor.addMenuItem('link', {
       
   394 		icon: 'link',
       
   395 		text: 'Insert/edit link',
       
   396 		shortcut: 'Meta+K',
       
   397 		onclick: createLinkList(showDialog),
       
   398 		stateSelector: 'a[href]',
       
   399 		context: 'insert',
       
   400 		prependToContext: true
       
   401 	});
       
   402 });