| Conditions | 16 |
| Paths | > 20000 |
| Total Lines | 367 |
| Lines | 0 |
| Ratio | 0 % |
| Changes | 0 | ||
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
Complex classes like tinymce.PluginManager.add(ꞌlinkꞌ) often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
| 1 | /** |
||
| 179 | function showDialog(linkList) { |
||
| 180 | var data = {}, selection = editor.selection, dom = editor.dom, selectedElm, anchorElm, initialText; |
||
| 181 | var win, onlyText, textListCtrl, linkListCtrl, relListCtrl, targetListCtrl, classListCtrl, linkTitleCtrl, value; |
||
| 182 | |||
| 183 | function linkListChangeHandler(e) { |
||
| 184 | var textCtrl = win.find('#text'); |
||
| 185 | |||
| 186 | if (!textCtrl.value() || (e.lastControl && textCtrl.value() == e.lastControl.text())) { |
||
| 187 | textCtrl.value(e.control.text()); |
||
| 188 | } |
||
| 189 | |||
| 190 | win.find('#href').value(e.control.value()); |
||
| 191 | } |
||
| 192 | |||
| 193 | function buildAnchorListControl(url) { |
||
| 194 | var anchorList = []; |
||
| 195 | |||
| 196 | tinymce.each(editor.dom.select('a:not([href])'), function(anchor) { |
||
| 197 | var id = anchor.name || anchor.id; |
||
| 198 | |||
| 199 | if (id) { |
||
| 200 | anchorList.push({ |
||
| 201 | text: id, |
||
| 202 | value: '#' + id, |
||
| 203 | selected: url.indexOf('#' + id) != -1 |
||
| 204 | }); |
||
| 205 | } |
||
| 206 | }); |
||
| 207 | |||
| 208 | if (anchorList.length) { |
||
| 209 | anchorList.unshift({text: 'None', value: ''}); |
||
| 210 | |||
| 211 | return { |
||
| 212 | name: 'anchor', |
||
| 213 | type: 'listbox', |
||
| 214 | label: 'Anchors', |
||
| 215 | values: anchorList, |
||
| 216 | onselect: linkListChangeHandler |
||
| 217 | }; |
||
| 218 | } |
||
| 219 | } |
||
| 220 | |||
| 221 | function updateText() { |
||
| 222 | if (!initialText && data.text.length === 0 && onlyText) { |
||
| 223 | this.parent().parent().find('#text')[0].value(this.value()); |
||
| 224 | } |
||
| 225 | } |
||
| 226 | |||
| 227 | function urlChange(e) { |
||
| 228 | var meta = e.meta || {}; |
||
| 229 | |||
| 230 | if (linkListCtrl) { |
||
| 231 | linkListCtrl.value(editor.convertURL(this.value(), 'href')); |
||
| 232 | } |
||
| 233 | |||
| 234 | tinymce.each(e.meta, function(value, key) { |
||
| 235 | var inp = win.find('#' + key); |
||
| 236 | |||
| 237 | if (key === 'text') { |
||
| 238 | if (initialText.length === 0) { |
||
| 239 | inp.value(value); |
||
| 240 | data.text = value; |
||
| 241 | } |
||
| 242 | } else { |
||
| 243 | inp.value(value); |
||
| 244 | } |
||
| 245 | }); |
||
| 246 | |||
| 247 | if (meta.attach) { |
||
| 248 | attachState = { |
||
| 249 | href: this.value(), |
||
| 250 | attach: meta.attach |
||
| 251 | }; |
||
| 252 | } |
||
| 253 | |||
| 254 | if (!meta.text) { |
||
| 255 | updateText.call(this); |
||
| 256 | } |
||
| 257 | } |
||
| 258 | |||
| 259 | function isOnlyTextSelected(anchorElm) { |
||
| 260 | var html = selection.getContent(); |
||
| 261 | |||
| 262 | // Partial html and not a fully selected anchor element |
||
| 263 | if (/</.test(html) && (!/^<a [^>]+>[^<]+<\/a>$/.test(html) || html.indexOf('href=') == -1)) { |
||
| 264 | return false; |
||
| 265 | } |
||
| 266 | |||
| 267 | if (anchorElm) { |
||
| 268 | var nodes = anchorElm.childNodes, i; |
||
| 269 | |||
| 270 | if (nodes.length === 0) { |
||
| 271 | return false; |
||
| 272 | } |
||
| 273 | |||
| 274 | for (i = nodes.length - 1; i >= 0; i--) { |
||
| 275 | if (nodes[i].nodeType != 3) { |
||
| 276 | return false; |
||
| 277 | } |
||
| 278 | } |
||
| 279 | } |
||
| 280 | |||
| 281 | return true; |
||
| 282 | } |
||
| 283 | |||
| 284 | function onBeforeCall(e) { |
||
| 285 | e.meta = win.toJSON(); |
||
| 286 | } |
||
| 287 | |||
| 288 | selectedElm = selection.getNode(); |
||
| 289 | anchorElm = dom.getParent(selectedElm, 'a[href]'); |
||
| 290 | onlyText = isOnlyTextSelected(); |
||
| 291 | |||
| 292 | data.text = initialText = anchorElm ? (anchorElm.innerText || anchorElm.textContent) : selection.getContent({format: 'text'}); |
||
| 293 | data.href = anchorElm ? dom.getAttrib(anchorElm, 'href') : ''; |
||
| 294 | |||
| 295 | if (anchorElm) { |
||
| 296 | data.target = dom.getAttrib(anchorElm, 'target'); |
||
| 297 | } else if (editor.settings.default_link_target) { |
||
| 298 | data.target = editor.settings.default_link_target; |
||
| 299 | } |
||
| 300 | |||
| 301 | if ((value = dom.getAttrib(anchorElm, 'rel'))) { |
||
| 302 | data.rel = value; |
||
| 303 | } |
||
| 304 | |||
| 305 | if ((value = dom.getAttrib(anchorElm, 'class'))) { |
||
| 306 | data['class'] = value; |
||
| 307 | } |
||
| 308 | |||
| 309 | if ((value = dom.getAttrib(anchorElm, 'title'))) { |
||
| 310 | data.title = value; |
||
| 311 | } |
||
| 312 | |||
| 313 | if (onlyText) { |
||
| 314 | textListCtrl = { |
||
| 315 | name: 'text', |
||
| 316 | type: 'textbox', |
||
| 317 | size: 40, |
||
| 318 | label: 'Text to display', |
||
| 319 | onchange: function() { |
||
| 320 | data.text = this.value(); |
||
| 321 | } |
||
| 322 | }; |
||
| 323 | } |
||
| 324 | |||
| 325 | if (linkList) { |
||
| 326 | linkListCtrl = { |
||
| 327 | type: 'listbox', |
||
| 328 | label: 'Link list', |
||
| 329 | values: buildListItems( |
||
| 330 | linkList, |
||
| 331 | function(item) { |
||
| 332 | item.value = editor.convertURL(item.value || item.url, 'href'); |
||
| 333 | }, |
||
| 334 | [{text: 'None', value: ''}] |
||
| 335 | ), |
||
| 336 | onselect: linkListChangeHandler, |
||
| 337 | value: editor.convertURL(data.href, 'href'), |
||
| 338 | onPostRender: function() { |
||
| 339 | /*eslint consistent-this:0*/ |
||
| 340 | linkListCtrl = this; |
||
| 341 | } |
||
| 342 | }; |
||
| 343 | } |
||
| 344 | |||
| 345 | if (editor.settings.target_list !== false) { |
||
| 346 | if (!editor.settings.target_list) { |
||
| 347 | editor.settings.target_list = [ |
||
| 348 | {text: 'None', value: ''}, |
||
| 349 | {text: 'New window', value: '_blank'} |
||
| 350 | ]; |
||
| 351 | } |
||
| 352 | |||
| 353 | targetListCtrl = { |
||
| 354 | name: 'target', |
||
| 355 | type: 'listbox', |
||
| 356 | label: 'Target', |
||
| 357 | values: buildListItems(editor.settings.target_list) |
||
| 358 | }; |
||
| 359 | } |
||
| 360 | |||
| 361 | if (editor.settings.rel_list) { |
||
| 362 | relListCtrl = { |
||
| 363 | name: 'rel', |
||
| 364 | type: 'listbox', |
||
| 365 | label: 'Rel', |
||
| 366 | values: buildListItems(editor.settings.rel_list) |
||
| 367 | }; |
||
| 368 | } |
||
| 369 | |||
| 370 | if (editor.settings.link_class_list) { |
||
| 371 | classListCtrl = { |
||
| 372 | name: 'class', |
||
| 373 | type: 'listbox', |
||
| 374 | label: 'Class', |
||
| 375 | values: buildListItems( |
||
| 376 | editor.settings.link_class_list, |
||
| 377 | function(item) { |
||
| 378 | if (item.value) { |
||
| 379 | item.textStyle = function() { |
||
| 380 | return editor.formatter.getCssText({inline: 'a', classes: [item.value]}); |
||
| 381 | }; |
||
| 382 | } |
||
| 383 | } |
||
| 384 | ) |
||
| 385 | }; |
||
| 386 | } |
||
| 387 | |||
| 388 | if (editor.settings.link_title !== false) { |
||
| 389 | linkTitleCtrl = { |
||
| 390 | name: 'title', |
||
| 391 | type: 'textbox', |
||
| 392 | label: 'Title', |
||
| 393 | value: data.title |
||
| 394 | }; |
||
| 395 | } |
||
| 396 | |||
| 397 | win = editor.windowManager.open({ |
||
| 398 | title: 'Insert link', |
||
| 399 | data: data, |
||
| 400 | body: [ |
||
| 401 | { |
||
| 402 | name: 'href', |
||
| 403 | type: 'filepicker', |
||
| 404 | filetype: 'file', |
||
| 405 | size: 40, |
||
| 406 | autofocus: true, |
||
| 407 | label: 'Url', |
||
| 408 | onchange: urlChange, |
||
| 409 | onkeyup: updateText, |
||
| 410 | onbeforecall: onBeforeCall |
||
| 411 | }, |
||
| 412 | textListCtrl, |
||
| 413 | linkTitleCtrl, |
||
| 414 | buildAnchorListControl(data.href), |
||
| 415 | linkListCtrl, |
||
| 416 | relListCtrl, |
||
| 417 | targetListCtrl, |
||
| 418 | classListCtrl |
||
| 419 | ], |
||
| 420 | onSubmit: function(e) { |
||
| 421 | /*eslint dot-notation: 0*/ |
||
| 422 | var href; |
||
| 423 | |||
| 424 | data = tinymce.extend(data, e.data); |
||
| 425 | href = data.href; |
||
| 426 | |||
| 427 | // Delay confirm since onSubmit will move focus |
||
| 428 | function delayedConfirm(message, callback) { |
||
| 429 | var rng = editor.selection.getRng(); |
||
| 430 | |||
| 431 | tinymce.util.Delay.setEditorTimeout(editor, function() { |
||
| 432 | editor.windowManager.confirm(message, function(state) { |
||
| 433 | editor.selection.setRng(rng); |
||
| 434 | callback(state); |
||
| 435 | }); |
||
| 436 | }); |
||
| 437 | } |
||
| 438 | |||
| 439 | function toggleTargetRules(rel, isUnsafe) { |
||
| 440 | var rules = 'noopener noreferrer'; |
||
| 441 | |||
| 442 | function addTargetRules(rel) { |
||
| 443 | rel = removeTargetRules(rel); |
||
| 444 | return rel ? [rel, rules].join(' ') : rules; |
||
| 445 | } |
||
| 446 | |||
| 447 | function removeTargetRules(rel) { |
||
| 448 | var regExp = new RegExp('(' + rules.replace(' ', '|') + ')', 'g'); |
||
| 449 | if (rel) { |
||
| 450 | rel = tinymce.trim(rel.replace(regExp, '')); |
||
| 451 | } |
||
| 452 | return rel ? rel : null; |
||
| 453 | } |
||
| 454 | |||
| 455 | return isUnsafe ? addTargetRules(rel) : removeTargetRules(rel); |
||
| 456 | } |
||
| 457 | |||
| 458 | function createLink() { |
||
| 459 | var linkAttrs = { |
||
| 460 | href: href, |
||
| 461 | target: data.target ? data.target : null, |
||
| 462 | rel: data.rel ? data.rel : null, |
||
| 463 | "class": data["class"] ? data["class"] : null, |
||
| 464 | title: data.title ? data.title : null |
||
| 465 | }; |
||
| 466 | |||
| 467 | if (!editor.settings.allow_unsafe_link_target) { |
||
| 468 | linkAttrs.rel = toggleTargetRules(linkAttrs.rel, linkAttrs.target == '_blank'); |
||
| 469 | } |
||
| 470 | |||
| 471 | if (href === attachState.href) { |
||
| 472 | attachState.attach(); |
||
| 473 | attachState = {}; |
||
| 474 | } |
||
| 475 | |||
| 476 | if (anchorElm) { |
||
| 477 | editor.focus(); |
||
| 478 | |||
| 479 | if (onlyText && data.text != initialText) { |
||
| 480 | if ("innerText" in anchorElm) { |
||
| 481 | anchorElm.innerText = data.text; |
||
| 482 | } else { |
||
| 483 | anchorElm.textContent = data.text; |
||
| 484 | } |
||
| 485 | } |
||
| 486 | |||
| 487 | dom.setAttribs(anchorElm, linkAttrs); |
||
| 488 | |||
| 489 | selection.select(anchorElm); |
||
| 490 | editor.undoManager.add(); |
||
| 491 | } else { |
||
| 492 | if (onlyText) { |
||
| 493 | editor.insertContent(dom.createHTML('a', linkAttrs, dom.encode(data.text))); |
||
| 494 | } else { |
||
| 495 | editor.execCommand('mceInsertLink', false, linkAttrs); |
||
| 496 | } |
||
| 497 | } |
||
| 498 | } |
||
| 499 | |||
| 500 | function insertLink() { |
||
| 501 | editor.undoManager.transact(createLink); |
||
| 502 | } |
||
| 503 | |||
| 504 | if (!href) { |
||
| 505 | editor.execCommand('unlink'); |
||
| 506 | return; |
||
| 507 | } |
||
| 508 | |||
| 509 | // Is email and not //[email protected] |
||
| 510 | if (href.indexOf('@') > 0 && href.indexOf('//') == -1 && href.indexOf('mailto:') == -1) { |
||
| 511 | delayedConfirm( |
||
| 512 | 'The URL you entered seems to be an email address. Do you want to add the required mailto: prefix?', |
||
| 513 | function(state) { |
||
| 514 | if (state) { |
||
| 515 | href = 'mailto:' + href; |
||
| 516 | } |
||
| 517 | |||
| 518 | insertLink(); |
||
| 519 | } |
||
| 520 | ); |
||
| 521 | |||
| 522 | return; |
||
| 523 | } |
||
| 524 | |||
| 525 | // Is not protocol prefixed |
||
| 526 | if ((editor.settings.link_assume_external_targets && !/^\w+:/i.test(href)) || |
||
| 527 | (!editor.settings.link_assume_external_targets && /^\s*www[\.|\d\.]/i.test(href))) { |
||
| 528 | delayedConfirm( |
||
| 529 | 'The URL you entered seems to be an external link. Do you want to add the required http:// prefix?', |
||
| 530 | function(state) { |
||
| 531 | if (state) { |
||
| 532 | href = 'http://' + href; |
||
| 533 | } |
||
| 534 | |||
| 535 | insertLink(); |
||
| 536 | } |
||
| 537 | ); |
||
| 538 | |||
| 539 | return; |
||
| 540 | } |
||
| 541 | |||
| 542 | insertLink(); |
||
| 543 | } |
||
| 544 | }); |
||
| 545 | } |
||
| 546 | |||
| 616 |
This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.
To learn more about declaring variables in Javascript, see the MDN.