Ultimate Nofollow - Version 1.4.5

Version Description

  • Fixed checkbox bug, thanks keesromkes
Download this release

Release Info

Developer bitacre
Plugin Icon wp plugin Ultimate Nofollow
Version 1.4.5
Comparing to
See all releases

Code changes from version 1.4.4 to 1.4.5

Files changed (4) hide show
  1. nofollow.php +3 -3
  2. readme.txt +9 -3
  3. wplink.js +724 -724
  4. wplink.min.js +1 -1
nofollow.php CHANGED
@@ -3,10 +3,10 @@
3
  Plugin Name: Ultimate Nofollow
4
  Plugin URI: http://shinraholdings.com/plugins/nofollow
5
  Description: A suite of tools that gives you complete control over the rel=nofollow tag on an individual link basis.
6
- Version: 1.4.4
7
  Author: bitacre
8
- Author URI: http://shinraholdings.com.com
9
- License: GPLv2
10
  Copyright 2016 Shinra Web Holdings (shinraholdings.com)
11
 
12
  This plugin contains several tools in one to significantly increase your control of the nofollow rel tag on every link on your blog, on both an individual and type basis. It is designed to give you fine-grained control of linking for SEO purposes.
3
  Plugin Name: Ultimate Nofollow
4
  Plugin URI: http://shinraholdings.com/plugins/nofollow
5
  Description: A suite of tools that gives you complete control over the rel=nofollow tag on an individual link basis.
6
+ Version: 1.4.5
7
  Author: bitacre
8
+ Author URI: http://shinraholdings.com
9
+ License: GPLv2
10
  Copyright 2016 Shinra Web Holdings (shinraholdings.com)
11
 
12
  This plugin contains several tools in one to significantly increase your control of the nofollow rel tag on every link on your blog, on both an individual and type basis. It is designed to give you fine-grained control of linking for SEO purposes.
readme.txt CHANGED
@@ -1,11 +1,11 @@
1
  === Ultimate Nofollow ===
2
  Plugin URI: http://shinraholdings.com/plugins/nofollow
3
- Contributors: bitacre
4
  Donate link: http://shinraholdings.com/donate
5
  Tags: nofollow,link,links,meta,insert,rel nofollow,seo,checkbox,popup,shortcode,blogroll
6
  Requires at least: 2.8
7
- Tested up to: 4.4
8
- Stable tag: 1.4.4
9
 
10
  Adds a checkbox in the insert link popup box for including rel="nofollow" in links as you create them; as well as other tools that provides complete control over the rel="nofollow" tag on your blogroll links and comments.
11
 
@@ -45,6 +45,9 @@ You can also include the optional <a> attributes `title` and `target`. A full ex
45
  3. Nofollow checkbox on the add/edit blogroll link page.
46
 
47
  == Changelog ==
 
 
 
48
  = 1.4.4 =
49
  * Purely cosmetic WordPress 4.4 update
50
 
@@ -84,6 +87,9 @@ You can also include the optional <a> attributes `title` and `target`. A full ex
84
  * Stable, but not all functions active yet.
85
 
86
  == Upgrade Notice ==
 
 
 
87
  = 1.4.4 =
88
  Purely cosmetic WordPress 4.4 update. Happy New Year.
89
 
1
  === Ultimate Nofollow ===
2
  Plugin URI: http://shinraholdings.com/plugins/nofollow
3
+ Contributors: bitacre, keesromkes
4
  Donate link: http://shinraholdings.com/donate
5
  Tags: nofollow,link,links,meta,insert,rel nofollow,seo,checkbox,popup,shortcode,blogroll
6
  Requires at least: 2.8
7
+ Tested up to: 4.5
8
+ Stable tag: 1.4.5
9
 
10
  Adds a checkbox in the insert link popup box for including rel="nofollow" in links as you create them; as well as other tools that provides complete control over the rel="nofollow" tag on your blogroll links and comments.
11
 
45
  3. Nofollow checkbox on the add/edit blogroll link page.
46
 
47
  == Changelog ==
48
+ = 1.4.5 =
49
+ * Fixed checkbox bug, thanks [keesromkes](https://wordpress.org/support/profile/keesromkes)
50
+
51
  = 1.4.4 =
52
  * Purely cosmetic WordPress 4.4 update
53
 
87
  * Stable, but not all functions active yet.
88
 
89
  == Upgrade Notice ==
90
+ = 1.4.5 =
91
+ Fixes checkbox bug introducef in WP 4.5.
92
+
93
  = 1.4.4 =
94
  Purely cosmetic WordPress 4.4 update. Happy New Year.
95
 
wplink.js CHANGED
@@ -1,724 +1,724 @@
1
- /* global ajaxurl, tinymce, wpLinkL10n, setUserSetting, wpActiveEditor */
2
- /* Thanks to zoecorkhill for the 4.2 fix */
3
- var wpLink;
4
-
5
- ( function( $ ) {
6
- var editor, searchTimer, River, Query, correctedURL,
7
- inputs = {},
8
- rivers = {},
9
- isTouch = ( 'ontouchend' in document );
10
-
11
- function getLink() {
12
- return editor.dom.getParent( editor.selection.getNode(), 'a' );
13
- }
14
-
15
- wpLink = {
16
- timeToTriggerRiver: 150,
17
- minRiverAJAXDuration: 200,
18
- riverBottomThreshold: 5,
19
- keySensitivity: 100,
20
- lastSearch: '',
21
- textarea: '',
22
-
23
- // append nofollow checkbox HTML (mod)
24
- append : function() {
25
- var html = '<br /><label><span> </span><input type="checkbox" id="link-nofollow-checkbox" /> Add <code>rel="nofollow"</code> to link</label>';
26
- $('#wp-link .link-target').append( html );
27
- },
28
-
29
- init: function() {
30
- inputs.wrap = $('#wp-link-wrap');
31
- inputs.dialog = $( '#wp-link' );
32
- inputs.backdrop = $( '#wp-link-backdrop' );
33
- inputs.submit = $( '#wp-link-submit' );
34
- inputs.close = $( '#wp-link-close' );
35
-
36
- // Input
37
- inputs.text = $( '#wp-link-text' );
38
- inputs.url = $( '#wp-link-url' );
39
- inputs.nonce = $( '#_ajax_linking_nonce' );
40
- inputs.openInNewTab = $( '#wp-link-target' );
41
- inputs.relNofollow = $( '#link-nofollow-checkbox' ); // (mod)
42
- inputs.search = $( '#wp-link-search' );
43
-
44
- // Build Rivers
45
- rivers.search = new River( $( '#search-results' ) );
46
- rivers.recent = new River( $( '#most-recent-results' ) );
47
- rivers.elements = inputs.dialog.find( '.query-results' );
48
-
49
- // Get search notice text
50
- inputs.queryNotice = $( '#query-notice-message' );
51
- inputs.queryNoticeTextDefault = inputs.queryNotice.find( '.query-notice-default' );
52
- inputs.queryNoticeTextHint = inputs.queryNotice.find( '.query-notice-hint' );
53
-
54
- // Bind event handlers
55
- inputs.dialog.keydown( wpLink.keydown );
56
- inputs.dialog.keyup( wpLink.keyup );
57
- inputs.submit.click( function( event ) {
58
- event.preventDefault();
59
- wpLink.update();
60
- });
61
- inputs.close.add( inputs.backdrop ).add( '#wp-link-cancel a' ).click( function( event ) {
62
- event.preventDefault();
63
- wpLink.close();
64
- });
65
-
66
- $( '#wp-link-search-toggle' ).on( 'click', wpLink.toggleInternalLinking );
67
-
68
- rivers.elements.on( 'river-select', wpLink.updateFields );
69
-
70
- // Display 'hint' message when search field or 'query-results' box are focused
71
- inputs.search.on( 'focus.wplink', function() {
72
- inputs.queryNoticeTextDefault.hide();
73
- inputs.queryNoticeTextHint.removeClass( 'screen-reader-text' ).show();
74
- } ).on( 'blur.wplink', function() {
75
- inputs.queryNoticeTextDefault.show();
76
- inputs.queryNoticeTextHint.addClass( 'screen-reader-text' ).hide();
77
- } );
78
-
79
- inputs.search.keyup( function() {
80
- var self = this;
81
-
82
- window.clearTimeout( searchTimer );
83
- searchTimer = window.setTimeout( function() {
84
- wpLink.searchInternalLinks.call( self );
85
- }, 500 );
86
- });
87
-
88
- function correctURL() {
89
- var url = $.trim( inputs.url.val() );
90
-
91
- if ( url && correctedURL !== url && ! /^(?:[a-z]+:|#|\?|\.|\/)/.test( url ) ) {
92
- inputs.url.val( 'http://' + url );
93
- correctedURL = url;
94
- }
95
- }
96
-
97
- inputs.url.on( 'paste', function() {
98
- setTimeout( correctURL, 0 );
99
- } );
100
-
101
- inputs.url.on( 'blur', correctURL );
102
- },
103
-
104
- open: function( editorId ) {
105
- var ed;
106
-
107
- $( document.body ).addClass( 'modal-open' );
108
-
109
- wpLink.range = null;
110
-
111
- if ( editorId ) {
112
- window.wpActiveEditor = editorId;
113
- }
114
-
115
- if ( ! window.wpActiveEditor ) {
116
- return;
117
- }
118
-
119
- this.textarea = $( '#' + window.wpActiveEditor ).get( 0 );
120
-
121
- if ( typeof tinymce !== 'undefined' ) {
122
- ed = tinymce.get( wpActiveEditor );
123
-
124
- if ( ed && ! ed.isHidden() ) {
125
- editor = ed;
126
- } else {
127
- editor = null;
128
- }
129
-
130
- if ( editor && tinymce.isIE ) {
131
- editor.windowManager.bookmark = editor.selection.getBookmark();
132
- }
133
- }
134
-
135
- if ( ! wpLink.isMCE() && document.selection ) {
136
- this.textarea.focus();
137
- this.range = document.selection.createRange();
138
- }
139
-
140
- inputs.wrap.show();
141
- inputs.backdrop.show();
142
-
143
- wpLink.refresh();
144
-
145
- $( document ).trigger( 'wplink-open', inputs.wrap );
146
- },
147
-
148
- isMCE: function() {
149
- return editor && ! editor.isHidden();
150
- },
151
-
152
- refresh: function() {
153
- var text = '';
154
-
155
- // Refresh rivers (clear links, check visibility)
156
- rivers.search.refresh();
157
- rivers.recent.refresh();
158
-
159
- if ( wpLink.isMCE() ) {
160
- wpLink.mceRefresh();
161
- } else {
162
- // For the Text editor the "Link text" field is always shown
163
- if ( ! inputs.wrap.hasClass( 'has-text-field' ) ) {
164
- inputs.wrap.addClass( 'has-text-field' );
165
- }
166
-
167
- if ( document.selection ) {
168
- // Old IE
169
- text = document.selection.createRange().text || '';
170
- } else if ( typeof this.textarea.selectionStart !== 'undefined' &&
171
- ( this.textarea.selectionStart !== this.textarea.selectionEnd ) ) {
172
- // W3C
173
- text = this.textarea.value.substring( this.textarea.selectionStart, this.textarea.selectionEnd ) || '';
174
- }
175
-
176
- inputs.text.val( text );
177
- wpLink.setDefaultValues();
178
- }
179
-
180
- if ( isTouch ) {
181
- // Close the onscreen keyboard
182
- inputs.url.focus().blur();
183
- } else {
184
- // Focus the URL field and highlight its contents.
185
- // If this is moved above the selection changes,
186
- // IE will show a flashing cursor over the dialog.
187
- inputs.url.focus()[0].select();
188
- }
189
-
190
- // Load the most recent results if this is the first time opening the panel.
191
- if ( ! rivers.recent.ul.children().length ) {
192
- rivers.recent.ajax();
193
- }
194
-
195
- correctedURL = inputs.url.val().replace( /^http:\/\//, '' );
196
- },
197
-
198
- hasSelectedText: function( linkNode ) {
199
- var html = editor.selection.getContent();
200
-
201
- // Partial html and not a fully selected anchor element
202
- if ( /</.test( html ) && ( ! /^<a [^>]+>[^<]+<\/a>$/.test( html ) || html.indexOf('href=') === -1 ) ) {
203
- return false;
204
- }
205
-
206
- if ( linkNode ) {
207
- var nodes = linkNode.childNodes, i;
208
-
209
- if ( nodes.length === 0 ) {
210
- return false;
211
- }
212
-
213
- for ( i = nodes.length - 1; i >= 0; i-- ) {
214
- if ( nodes[i].nodeType != 3 ) {
215
- return false;
216
- }
217
- }
218
- }
219
-
220
- return true;
221
- },
222
-
223
- mceRefresh: function() {
224
- var text,
225
- selectedNode = editor.selection.getNode(),
226
- linkNode = editor.dom.getParent( selectedNode, 'a[href]' ),
227
- onlyText = this.hasSelectedText( linkNode );
228
-
229
- if ( linkNode ) {
230
- text = linkNode.innerText || linkNode.textContent;
231
- inputs.url.val( editor.dom.getAttrib( linkNode, 'href' ) );
232
- inputs.openInNewTab.prop( 'checked', '_blank' === editor.dom.getAttrib( linkNode, 'target' ) );
233
- // Set rel="nofollow" (mod)
234
- if ( "nofollow" == ed.dom.getAttrib(e, 'rel' ) )
235
- inputs.relNofollow.prop('checked', true);
236
- inputs.submit.val( wpLinkL10n.update );
237
- } else {
238
- text = editor.selection.getContent({ format: 'text' });
239
- this.setDefaultValues();
240
- }
241
-
242
- if ( onlyText ) {
243
- inputs.text.val( text || '' );
244
- inputs.wrap.addClass( 'has-text-field' );
245
- } else {
246
- inputs.text.val( '' );
247
- inputs.wrap.removeClass( 'has-text-field' );
248
- }
249
- },
250
-
251
- close: function() {
252
- $( document.body ).removeClass( 'modal-open' );
253
-
254
- if ( ! wpLink.isMCE() ) {
255
- wpLink.textarea.focus();
256
-
257
- if ( wpLink.range ) {
258
- wpLink.range.moveToBookmark( wpLink.range.getBookmark() );
259
- wpLink.range.select();
260
- }
261
- } else {
262
- editor.focus();
263
- }
264
-
265
- inputs.backdrop.hide();
266
- inputs.wrap.hide();
267
-
268
- correctedURL = false;
269
-
270
- $( document ).trigger( 'wplink-close', inputs.wrap );
271
- },
272
-
273
- getAttrs: function() {
274
- return {
275
- href: $.trim( inputs.url.val() ),
276
- target: inputs.openInNewTab.prop( 'checked' ) ? '_blank' : '',
277
- rel: inputs.relNofollow.prop( 'checked' ) ? 'nofollow' : '' // (mod)
278
- };
279
- },
280
-
281
- update: function() {
282
- if ( wpLink.isMCE() ) {
283
- wpLink.mceUpdate();
284
- } else {
285
- wpLink.htmlUpdate();
286
- }
287
- },
288
-
289
- htmlUpdate: function() {
290
- var attrs, text, html, begin, end, cursor, selection,
291
- textarea = wpLink.textarea;
292
-
293
- if ( ! textarea ) {
294
- return;
295
- }
296
-
297
- attrs = wpLink.getAttrs();
298
- text = inputs.text.val();
299
-
300
- // If there's no href, return.
301
- if ( ! attrs.href ) {
302
- return;
303
- }
304
-
305
- // Build HTML
306
- html = '<a href="' + attrs.href + '"';
307
-
308
- if ( attrs.target ) {
309
- html += ' target="' + attrs.target + '"';
310
- }
311
-
312
- if ( attrs.rel ) { // (mod)
313
- html += ' rel="' + attrs.rel + '"';
314
- }
315
-
316
- html += '>';
317
-
318
- // Insert HTML
319
- if ( document.selection && wpLink.range ) {
320
- // IE
321
- // Note: If no text is selected, IE will not place the cursor
322
- // inside the closing tag.
323
- textarea.focus();
324
- wpLink.range.text = html + ( text || wpLink.range.text ) + '</a>';
325
- wpLink.range.moveToBookmark( wpLink.range.getBookmark() );
326
- wpLink.range.select();
327
-
328
- wpLink.range = null;
329
- } else if ( typeof textarea.selectionStart !== 'undefined' ) {
330
- // W3C
331
- begin = textarea.selectionStart;
332
- end = textarea.selectionEnd;
333
- selection = text || textarea.value.substring( begin, end );
334
- html = html + selection + '</a>';
335
- cursor = begin + html.length;
336
-
337
- // If no text is selected, place the cursor inside the closing tag.
338
- if ( begin === end && ! selection ) {
339
- cursor -= 4;
340
- }
341
-
342
- textarea.value = (
343
- textarea.value.substring( 0, begin ) +
344
- html +
345
- textarea.value.substring( end, textarea.value.length )
346
- );
347
-
348
- // Update cursor position
349
- textarea.selectionStart = textarea.selectionEnd = cursor;
350
- }
351
-
352
- wpLink.close();
353
- textarea.focus();
354
- },
355
-
356
- mceUpdate: function() {
357
- var attrs = wpLink.getAttrs(),
358
- link, text;
359
-
360
- wpLink.close();
361
- editor.focus();
362
-
363
- if ( tinymce.isIE ) {
364
- editor.selection.moveToBookmark( editor.windowManager.bookmark );
365
- }
366
-
367
- if ( ! attrs.href ) {
368
- editor.execCommand( 'unlink' );
369
- return;
370
- }
371
-
372
- link = getLink();
373
- text = inputs.text.val();
374
-
375
- if ( link ) {
376
- if ( text ) {
377
- if ( 'innerText' in link ) {
378
- link.innerText = text;
379
- } else {
380
- link.textContent = text;
381
- }
382
- }
383
-
384
- editor.dom.setAttribs( link, attrs );
385
- } else {
386
- if ( text ) {
387
- editor.selection.setNode( editor.dom.create( 'a', attrs, text ) );
388
- } else {
389
- editor.execCommand( 'mceInsertLink', false, attrs );
390
- }
391
- }
392
- },
393
-
394
- updateFields: function( e, li ) {
395
- inputs.url.val( li.children( '.item-permalink' ).val() );
396
- },
397
-
398
- setDefaultValues: function() {
399
- var selection,
400
- emailRegexp = /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i,
401
- urlRegexp = /^(https?|ftp):\/\/[A-Z0-9.-]+\.[A-Z]{2,4}[^ "]*$/i;
402
-
403
- if ( this.isMCE() ) {
404
- selection = editor.selection.getContent();
405
- } else if ( document.selection && wpLink.range ) {
406
- selection = wpLink.range.text;
407
- } else if ( typeof this.textarea.selectionStart !== 'undefined' ) {
408
- selection = this.textarea.value.substring( this.textarea.selectionStart, this.textarea.selectionEnd );
409
- }
410
-
411
- if ( selection && emailRegexp.test( selection ) ) {
412
- // Selection is email address
413
- inputs.url.val( 'mailto:' + selection );
414
- } else if ( selection && urlRegexp.test( selection ) ) {
415
- // Selection is URL
416
- inputs.url.val( selection.replace( /&amp;|&#0?38;/gi, '&' ) );
417
- } else {
418
- // Set URL to default.
419
- inputs.url.val( '' );
420
- }
421
-
422
- // Update save prompt.
423
- inputs.submit.val( wpLinkL10n.save );
424
- },
425
-
426
- searchInternalLinks: function() {
427
- var t = $( this ), waiting,
428
- search = t.val();
429
-
430
- if ( search.length > 2 ) {
431
- rivers.recent.hide();
432
- rivers.search.show();
433
-
434
- // Don't search if the keypress didn't change the title.
435
- if ( wpLink.lastSearch == search )
436
- return;
437
-
438
- wpLink.lastSearch = search;
439
- waiting = t.parent().find( '.spinner' ).addClass( 'is-active' );
440
-
441
- rivers.search.change( search );
442
- rivers.search.ajax( function() {
443
- waiting.removeClass( 'is-active' );
444
- });
445
- } else {
446
- rivers.search.hide();
447
- rivers.recent.show();
448
- }
449
- },
450
-
451
- next: function() {
452
- rivers.search.next();
453
- rivers.recent.next();
454
- },
455
-
456
- prev: function() {
457
- rivers.search.prev();
458
- rivers.recent.prev();
459
- },
460
-
461
- keydown: function( event ) {
462
- var fn, id,
463
- key = $.ui.keyCode;
464
-
465
- if ( key.ESCAPE === event.keyCode ) {
466
- wpLink.close();
467
- event.stopImmediatePropagation();
468
- } else if ( key.TAB === event.keyCode ) {
469
- id = event.target.id;
470
-
471
- // wp-link-submit must always be the last focusable element in the dialog.
472
- // following focusable elements will be skipped on keyboard navigation.
473
- if ( id === 'wp-link-submit' && ! event.shiftKey ) {
474
- inputs.close.focus();
475
- event.preventDefault();
476
- } else if ( id === 'wp-link-close' && event.shiftKey ) {
477
- inputs.submit.focus();
478
- event.preventDefault();
479
- }
480
- }
481
-
482
- if ( event.keyCode !== key.UP && event.keyCode !== key.DOWN ) {
483
- return;
484
- }
485
-
486
- if ( document.activeElement &&
487
- ( document.activeElement.id === 'link-title-field' || document.activeElement.id === 'url-field' ) ) {
488
- return;
489
- }
490
-
491
- fn = event.keyCode === key.UP ? 'prev' : 'next';
492
- clearInterval( wpLink.keyInterval );
493
- wpLink[ fn ]();
494
- wpLink.keyInterval = setInterval( wpLink[ fn ], wpLink.keySensitivity );
495
- event.preventDefault();
496
- },
497
-
498
- keyup: function( event ) {
499
- var key = $.ui.keyCode;
500
-
501
- if ( event.which === key.UP || event.which === key.DOWN ) {
502
- clearInterval( wpLink.keyInterval );
503
- event.preventDefault();
504
- }
505
- },
506
-
507
- delayedCallback: function( func, delay ) {
508
- var timeoutTriggered, funcTriggered, funcArgs, funcContext;
509
-
510
- if ( ! delay )
511
- return func;
512
-
513
- setTimeout( function() {
514
- if ( funcTriggered )
515
- return func.apply( funcContext, funcArgs );
516
- // Otherwise, wait.
517
- timeoutTriggered = true;
518
- }, delay );
519
-
520
- return function() {
521
- if ( timeoutTriggered )
522
- return func.apply( this, arguments );
523
- // Otherwise, wait.
524
- funcArgs = arguments;
525
- funcContext = this;
526
- funcTriggered = true;
527
- };
528
- },
529
-
530
- toggleInternalLinking: function( event ) {
531
- var visible = inputs.wrap.hasClass( 'search-panel-visible' );
532
-
533
- inputs.wrap.toggleClass( 'search-panel-visible', ! visible );
534
- setUserSetting( 'wplink', visible ? '0' : '1' );
535
- inputs[ ! visible ? 'search' : 'url' ].focus();
536
- event.preventDefault();
537
- }
538
- };
539
-
540
- River = function( element, search ) {
541
- var self = this;
542
- this.element = element;
543
- this.ul = element.children( 'ul' );
544
- this.contentHeight = element.children( '#link-selector-height' );
545
- this.waiting = element.find('.river-waiting');
546
-
547
- this.change( search );
548
- this.refresh();
549
-
550
- $( '#wp-link .query-results, #wp-link #link-selector' ).scroll( function() {
551
- self.maybeLoad();
552
- });
553
- element.on( 'click', 'li', function( event ) {
554
- self.select( $( this ), event );
555
- });
556
- };
557
-
558
- $.extend( River.prototype, {
559
- refresh: function() {
560
- this.deselect();
561
- this.visible = this.element.is( ':visible' );
562
- },
563
- show: function() {
564
- if ( ! this.visible ) {
565
- this.deselect();
566
- this.element.show();
567
- this.visible = true;
568
- }
569
- },
570
- hide: function() {
571
- this.element.hide();
572
- this.visible = false;
573
- },
574
- // Selects a list item and triggers the river-select event.
575
- select: function( li, event ) {
576
- var liHeight, elHeight, liTop, elTop;
577
-
578
- if ( li.hasClass( 'unselectable' ) || li == this.selected )
579
- return;
580
-
581
- this.deselect();
582
- this.selected = li.addClass( 'selected' );
583
- // Make sure the element is visible
584
- liHeight = li.outerHeight();
585
- elHeight = this.element.height();
586
- liTop = li.position().top;
587
- elTop = this.element.scrollTop();
588
-
589
- if ( liTop < 0 ) // Make first visible element
590
- this.element.scrollTop( elTop + liTop );
591
- else if ( liTop + liHeight > elHeight ) // Make last visible element
592
- this.element.scrollTop( elTop + liTop - elHeight + liHeight );
593
-
594
- // Trigger the river-select event
595
- this.element.trigger( 'river-select', [ li, event, this ] );
596
- },
597
- deselect: function() {
598
- if ( this.selected )
599
- this.selected.removeClass( 'selected' );
600
- this.selected = false;
601
- },
602
- prev: function() {
603
- if ( ! this.visible )
604
- return;
605
-
606
- var to;
607
- if ( this.selected ) {
608
- to = this.selected.prev( 'li' );
609
- if ( to.length )
610
- this.select( to );
611
- }
612
- },
613
- next: function() {
614
- if ( ! this.visible )
615
- return;
616
-
617
- var to = this.selected ? this.selected.next( 'li' ) : $( 'li:not(.unselectable):first', this.element );
618
- if ( to.length )
619
- this.select( to );
620
- },
621
- ajax: function( callback ) {
622
- var self = this,
623
- delay = this.query.page == 1 ? 0 : wpLink.minRiverAJAXDuration,
624
- response = wpLink.delayedCallback( function( results, params ) {
625
- self.process( results, params );
626
- if ( callback )
627
- callback( results, params );
628
- }, delay );
629
-
630
- this.query.ajax( response );
631
- },
632
- change: function( search ) {
633
- if ( this.query && this._search == search )
634
- return;
635
-
636
- this._search = search;
637
- this.query = new Query( search );
638
- this.element.scrollTop( 0 );
639
- },
640
- process: function( results, params ) {
641
- var list = '', alt = true, classes = '',
642
- firstPage = params.page == 1;
643
-
644
- if ( ! results ) {
645
- if ( firstPage ) {
646
- list += '<li class="unselectable no-matches-found"><span class="item-title"><em>' +
647
- wpLinkL10n.noMatchesFound + '</em></span></li>';
648
- }
649
- } else {
650
- $.each( results, function() {
651
- classes = alt ? 'alternate' : '';
652
- classes += this.title ? '' : ' no-title';
653
- list += classes ? '<li class="' + classes + '">' : '<li>';
654
- list += '<input type="hidden" class="item-permalink" value="' + this.permalink + '" />';
655
- list += '<span class="item-title">';
656
- list += this.title ? this.title : wpLinkL10n.noTitle;
657
- list += '</span><span class="item-info">' + this.info + '</span></li>';
658
- alt = ! alt;
659
- });
660
- }
661
-
662
- this.ul[ firstPage ? 'html' : 'append' ]( list );
663
- },
664
- maybeLoad: function() {
665
- var self = this,
666
- el = this.element,
667
- bottom = el.scrollTop() + el.height();
668
-
669
- if ( ! this.query.ready() || bottom < this.contentHeight.height() - wpLink.riverBottomThreshold )
670
- return;
671
-
672
- setTimeout(function() {
673
- var newTop = el.scrollTop(),
674
- newBottom = newTop + el.height();
675
-
676
- if ( ! self.query.ready() || newBottom < self.contentHeight.height() - wpLink.riverBottomThreshold )
677
- return;
678
-
679
- self.waiting.addClass( 'is-active' );
680
- el.scrollTop( newTop + self.waiting.outerHeight() );
681
-
682
- self.ajax( function() {
683
- self.waiting.removeClass( 'is-active' );
684
- });
685
- }, wpLink.timeToTriggerRiver );
686
- }
687
- });
688
-
689
- Query = function( search ) {
690
- this.page = 1;
691
- this.allLoaded = false;
692
- this.querying = false;
693
- this.search = search;
694
- };
695
-
696
- $.extend( Query.prototype, {
697
- ready: function() {
698
- return ! ( this.querying || this.allLoaded );
699
- },
700
- ajax: function( callback ) {
701
- var self = this,
702
- query = {
703
- action : 'wp-link-ajax',
704
- page : this.page,
705
- '_ajax_linking_nonce' : inputs.nonce.val()
706
- };
707
-
708
- if ( this.search )
709
- query.search = this.search;
710
-
711
- this.querying = true;
712
-
713
- $.post( ajaxurl, query, function( r ) {
714
- self.page++;
715
- self.querying = false;
716
- self.allLoaded = ! r;
717
- callback( r, query );
718
- }, 'json' );
719
- }
720
- });
721
-
722
- $( document ).ready( wpLink.append ); // (mod)
723
- $( document ).ready( wpLink.init );
724
- })( jQuery );
1
+ /* global ajaxurl, tinymce, wpLinkL10n, setUserSetting, wpActiveEditor */
2
+ /* Thanks to zoecorkhill for the 4.2 fix */
3
+ var wpLink;
4
+
5
+ ( function( $ ) {
6
+ var editor, searchTimer, River, Query, correctedURL,
7
+ inputs = {},
8
+ rivers = {},
9
+ isTouch = ( 'ontouchend' in document );
10
+
11
+ function getLink() {
12
+ return editor.dom.getParent( editor.selection.getNode(), 'a' );
13
+ }
14
+
15
+ wpLink = {
16
+ timeToTriggerRiver: 150,
17
+ minRiverAJAXDuration: 200,
18
+ riverBottomThreshold: 5,
19
+ keySensitivity: 100,
20
+ lastSearch: '',
21
+ textarea: '',
22
+
23
+ // append nofollow checkbox HTML (mod)
24
+ append : function() {
25
+ var html = '<br /><label><span> </span><input type="checkbox" id="link-nofollow-checkbox" /> Add <code>rel="nofollow"</code> to link</label>';
26
+ $('#wp-link .link-target').append( html );
27
+ },
28
+
29
+ init: function() {
30
+ inputs.wrap = $('#wp-link-wrap');
31
+ inputs.dialog = $( '#wp-link' );
32
+ inputs.backdrop = $( '#wp-link-backdrop' );
33
+ inputs.submit = $( '#wp-link-submit' );
34
+ inputs.close = $( '#wp-link-close' );
35
+
36
+ // Input
37
+ inputs.text = $( '#wp-link-text' );
38
+ inputs.url = $( '#wp-link-url' );
39
+ inputs.nonce = $( '#_ajax_linking_nonce' );
40
+ inputs.openInNewTab = $( '#wp-link-target' );
41
+ inputs.relNofollow = $( '#link-nofollow-checkbox' ); // (mod)
42
+ inputs.search = $( '#wp-link-search' );
43
+
44
+ // Build Rivers
45
+ rivers.search = new River( $( '#search-results' ) );
46
+ rivers.recent = new River( $( '#most-recent-results' ) );
47
+ rivers.elements = inputs.dialog.find( '.query-results' );
48
+
49
+ // Get search notice text
50
+ inputs.queryNotice = $( '#query-notice-message' );
51
+ inputs.queryNoticeTextDefault = inputs.queryNotice.find( '.query-notice-default' );
52
+ inputs.queryNoticeTextHint = inputs.queryNotice.find( '.query-notice-hint' );
53
+
54
+ // Bind event handlers
55
+ inputs.dialog.keydown( wpLink.keydown );
56
+ inputs.dialog.keyup( wpLink.keyup );
57
+ inputs.submit.click( function( event ) {
58
+ event.preventDefault();
59
+ wpLink.update();
60
+ });
61
+ inputs.close.add( inputs.backdrop ).add( '#wp-link-cancel a' ).click( function( event ) {
62
+ event.preventDefault();
63
+ wpLink.close();
64
+ });
65
+
66
+ $( '#wp-link-search-toggle' ).on( 'click', wpLink.toggleInternalLinking );
67
+
68
+ rivers.elements.on( 'river-select', wpLink.updateFields );
69
+
70
+ // Display 'hint' message when search field or 'query-results' box are focused
71
+ inputs.search.on( 'focus.wplink', function() {
72
+ inputs.queryNoticeTextDefault.hide();
73
+ inputs.queryNoticeTextHint.removeClass( 'screen-reader-text' ).show();
74
+ } ).on( 'blur.wplink', function() {
75
+ inputs.queryNoticeTextDefault.show();
76
+ inputs.queryNoticeTextHint.addClass( 'screen-reader-text' ).hide();
77
+ } );
78
+
79
+ inputs.search.keyup( function() {
80
+ var self = this;
81
+
82
+ window.clearTimeout( searchTimer );
83
+ searchTimer = window.setTimeout( function() {
84
+ wpLink.searchInternalLinks.call( self );
85
+ }, 500 );
86
+ });
87
+
88
+ function correctURL() {
89
+ var url = $.trim( inputs.url.val() );
90
+
91
+ if ( url && correctedURL !== url && ! /^(?:[a-z]+:|#|\?|\.|\/)/.test( url ) ) {
92
+ inputs.url.val( 'http://' + url );
93
+ correctedURL = url;
94
+ }
95
+ }
96
+
97
+ inputs.url.on( 'paste', function() {
98
+ setTimeout( correctURL, 0 );
99
+ } );
100
+
101
+ inputs.url.on( 'blur', correctURL );
102
+ },
103
+
104
+ open: function( editorId ) {
105
+ var ed;
106
+
107
+ $( document.body ).addClass( 'modal-open' );
108
+
109
+ wpLink.range = null;
110
+
111
+ if ( editorId ) {
112
+ window.wpActiveEditor = editorId;
113
+ }
114
+
115
+ if ( ! window.wpActiveEditor ) {
116
+ return;
117
+ }
118
+
119
+ this.textarea = $( '#' + window.wpActiveEditor ).get( 0 );
120
+
121
+ if ( typeof tinymce !== 'undefined' ) {
122
+ ed = tinymce.get( wpActiveEditor );
123
+
124
+ if ( ed && ! ed.isHidden() ) {
125
+ editor = ed;
126
+ } else {
127
+ editor = null;
128
+ }
129
+
130
+ if ( editor && tinymce.isIE ) {
131
+ editor.windowManager.bookmark = editor.selection.getBookmark();
132
+ }
133
+ }
134
+
135
+ if ( ! wpLink.isMCE() && document.selection ) {
136
+ this.textarea.focus();
137
+ this.range = document.selection.createRange();
138
+ }
139
+
140
+ inputs.wrap.show();
141
+ inputs.backdrop.show();
142
+
143
+ wpLink.refresh();
144
+
145
+ $( document ).trigger( 'wplink-open', inputs.wrap );
146
+ },
147
+
148
+ isMCE: function() {
149
+ return editor && ! editor.isHidden();
150
+ },
151
+
152
+ refresh: function() {
153
+ var text = '';
154
+
155
+ // Refresh rivers (clear links, check visibility)
156
+ rivers.search.refresh();
157
+ rivers.recent.refresh();
158
+
159
+ if ( wpLink.isMCE() ) {
160
+ wpLink.mceRefresh();
161
+ } else {
162
+ // For the Text editor the "Link text" field is always shown
163
+ if ( ! inputs.wrap.hasClass( 'has-text-field' ) ) {
164
+ inputs.wrap.addClass( 'has-text-field' );
165
+ }
166
+
167
+ if ( document.selection ) {
168
+ // Old IE
169
+ text = document.selection.createRange().text || '';
170
+ } else if ( typeof this.textarea.selectionStart !== 'undefined' &&
171
+ ( this.textarea.selectionStart !== this.textarea.selectionEnd ) ) {
172
+ // W3C
173
+ text = this.textarea.value.substring( this.textarea.selectionStart, this.textarea.selectionEnd ) || '';
174
+ }
175
+
176
+ inputs.text.val( text );
177
+ wpLink.setDefaultValues();
178
+ }
179
+
180
+ if ( isTouch ) {
181
+ // Close the onscreen keyboard
182
+ inputs.url.focus().blur();
183
+ } else {
184
+ // Focus the URL field and highlight its contents.
185
+ // If this is moved above the selection changes,
186
+ // IE will show a flashing cursor over the dialog.
187
+ inputs.url.focus()[0].select();
188
+ }
189
+
190
+ // Load the most recent results if this is the first time opening the panel.
191
+ if ( ! rivers.recent.ul.children().length ) {
192
+ rivers.recent.ajax();
193
+ }
194
+
195
+ correctedURL = inputs.url.val().replace( /^http:\/\//, '' );
196
+ },
197
+
198
+ hasSelectedText: function( linkNode ) {
199
+ var html = editor.selection.getContent();
200
+
201
+ // Partial html and not a fully selected anchor element
202
+ if ( /</.test( html ) && ( ! /^<a [^>]+>[^<]+<\/a>$/.test( html ) || html.indexOf('href=') === -1 ) ) {
203
+ return false;
204
+ }
205
+
206
+ if ( linkNode ) {
207
+ var nodes = linkNode.childNodes, i;
208
+
209
+ if ( nodes.length === 0 ) {
210
+ return false;
211
+ }
212
+
213
+ for ( i = nodes.length - 1; i >= 0; i-- ) {
214
+ if ( nodes[i].nodeType != 3 ) {
215
+ return false;
216
+ }
217
+ }
218
+ }
219
+
220
+ return true;
221
+ },
222
+
223
+ mceRefresh: function() {
224
+ var text,
225
+ selectedNode = editor.selection.getNode(),
226
+ linkNode = editor.dom.getParent( selectedNode, 'a[href]' ),
227
+ onlyText = this.hasSelectedText( linkNode );
228
+
229
+ if ( linkNode ) {
230
+ text = linkNode.innerText || linkNode.textContent;
231
+ inputs.url.val( editor.dom.getAttrib( linkNode, 'href' ) );
232
+ inputs.openInNewTab.prop( 'checked', '_blank' === editor.dom.getAttrib( linkNode, 'target' ) );
233
+ // Set rel="nofollow" (mod)
234
+ if ( "nofollow" == ed.dom.getAttrib(e, 'rel' ) )
235
+ inputs.relNofollow.prop('checked', true);
236
+ inputs.submit.val( wpLinkL10n.update );
237
+ } else {
238
+ text = editor.selection.getContent({ format: 'text' });
239
+ this.setDefaultValues();
240
+ }
241
+
242
+ if ( onlyText ) {
243
+ inputs.text.val( text || '' );
244
+ inputs.wrap.addClass( 'has-text-field' );
245
+ } else {
246
+ inputs.text.val( '' );
247
+ inputs.wrap.removeClass( 'has-text-field' );
248
+ }
249
+ },
250
+
251
+ close: function() {
252
+ $( document.body ).removeClass( 'modal-open' );
253
+
254
+ if ( ! wpLink.isMCE() ) {
255
+ wpLink.textarea.focus();
256
+
257
+ if ( wpLink.range ) {
258
+ wpLink.range.moveToBookmark( wpLink.range.getBookmark() );
259
+ wpLink.range.select();
260
+ }
261
+ } else {
262
+ editor.focus();
263
+ }
264
+
265
+ inputs.backdrop.hide();
266
+ inputs.wrap.hide();
267
+
268
+ correctedURL = false;
269
+
270
+ $( document ).trigger( 'wplink-close', inputs.wrap );
271
+ },
272
+
273
+ getAttrs: function() {
274
+ return {
275
+ href: $.trim( inputs.url.val() ),
276
+ target: inputs.openInNewTab.prop( 'checked' ) ? '_blank' : '',
277
+ rel: inputs.relNofollow.prop( 'checked' ) ? 'nofollow' : '' // (mod)
278
+ };
279
+ },
280
+
281
+ update: function() {
282
+ if ( wpLink.isMCE() ) {
283
+ wpLink.mceUpdate();
284
+ } else {
285
+ wpLink.htmlUpdate();
286
+ }
287
+ },
288
+
289
+ htmlUpdate: function() {
290
+ var attrs, text, html, begin, end, cursor, selection,
291
+ textarea = wpLink.textarea;
292
+
293
+ if ( ! textarea ) {
294
+ return;
295
+ }
296
+
297
+ attrs = wpLink.getAttrs();
298
+ text = inputs.text.val();
299
+
300
+ // If there's no href, return.
301
+ if ( ! attrs.href ) {
302
+ return;
303
+ }
304
+
305
+ // Build HTML
306
+ html = '<a href="' + attrs.href + '"';
307
+
308
+ if ( attrs.target ) {
309
+ html += ' target="' + attrs.target + '"';
310
+ }
311
+
312
+ if ( attrs.rel ) { // (mod)
313
+ html += ' rel="' + attrs.rel + '"';
314
+ }
315
+
316
+ html += '>';
317
+
318
+ // Insert HTML
319
+ if ( document.selection && wpLink.range ) {
320
+ // IE
321
+ // Note: If no text is selected, IE will not place the cursor
322
+ // inside the closing tag.
323
+ textarea.focus();
324
+ wpLink.range.text = html + ( text || wpLink.range.text ) + '</a>';
325
+ wpLink.range.moveToBookmark( wpLink.range.getBookmark() );
326
+ wpLink.range.select();
327
+
328
+ wpLink.range = null;
329
+ } else if ( typeof textarea.selectionStart !== 'undefined' ) {
330
+ // W3C
331
+ begin = textarea.selectionStart;
332
+ end = textarea.selectionEnd;
333
+ selection = text || textarea.value.substring( begin, end );
334
+ html = html + selection + '</a>';
335
+ cursor = begin + html.length;
336
+
337
+ // If no text is selected, place the cursor inside the closing tag.
338
+ if ( begin === end && ! selection ) {
339
+ cursor -= 4;
340
+ }
341
+
342
+ textarea.value = (
343
+ textarea.value.substring( 0, begin ) +
344
+ html +
345
+ textarea.value.substring( end, textarea.value.length )
346
+ );
347
+
348
+ // Update cursor position
349
+ textarea.selectionStart = textarea.selectionEnd = cursor;
350
+ }
351
+
352
+ wpLink.close();
353
+ textarea.focus();
354
+ },
355
+
356
+ mceUpdate: function() {
357
+ var attrs = wpLink.getAttrs(),
358
+ link, text;
359
+
360
+ wpLink.close();
361
+ editor.focus();
362
+
363
+ if ( tinymce.isIE ) {
364
+ editor.selection.moveToBookmark( editor.windowManager.bookmark );
365
+ }
366
+
367
+ if ( ! attrs.href ) {
368
+ editor.execCommand( 'unlink' );
369
+ return;
370
+ }
371
+
372
+ link = getLink();
373
+ text = inputs.text.val();
374
+
375
+ if ( link ) {
376
+ if ( text ) {
377
+ if ( 'innerText' in link ) {
378
+ link.innerText = text;
379
+ } else {
380
+ link.textContent = text;
381
+ }
382
+ }
383
+
384
+ editor.dom.setAttribs( link, attrs );
385
+ } else {
386
+ if ( text ) {
387
+ editor.selection.setNode( editor.dom.create( 'a', attrs, text ) );
388
+ } else {
389
+ editor.execCommand( 'mceInsertLink', false, attrs );
390
+ }
391
+ }
392
+ },
393
+
394
+ updateFields: function( e, li ) {
395
+ inputs.url.val( li.children( '.item-permalink' ).val() );
396
+ },
397
+
398
+ setDefaultValues: function() {
399
+ var selection,
400
+ emailRegexp = /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i,
401
+ urlRegexp = /^(https?|ftp):\/\/[A-Z0-9.-]+\.[A-Z]{2,4}[^ "]*$/i;
402
+
403
+ if ( this.isMCE() ) {
404
+ selection = editor.selection.getContent();
405
+ } else if ( document.selection && wpLink.range ) {
406
+ selection = wpLink.range.text;
407
+ } else if ( typeof this.textarea.selectionStart !== 'undefined' ) {
408
+ selection = this.textarea.value.substring( this.textarea.selectionStart, this.textarea.selectionEnd );
409
+ }
410
+
411
+ if ( selection && emailRegexp.test( selection ) ) {
412
+ // Selection is email address
413
+ inputs.url.val( 'mailto:' + selection );
414
+ } else if ( selection && urlRegexp.test( selection ) ) {
415
+ // Selection is URL
416
+ inputs.url.val( selection.replace( /&amp;|&#0?38;/gi, '&' ) );
417
+ } else {
418
+ // Set URL to default.
419
+ inputs.url.val( '' );
420
+ }
421
+
422
+ // Update save prompt.
423
+ inputs.submit.val( wpLinkL10n.save );
424
+ },
425
+
426
+ searchInternalLinks: function() {
427
+ var t = $( this ), waiting,
428
+ search = t.val();
429
+
430
+ if ( search.length > 2 ) {
431
+ rivers.recent.hide();
432
+ rivers.search.show();
433
+
434
+ // Don't search if the keypress didn't change the title.
435
+ if ( wpLink.lastSearch == search )
436
+ return;
437
+
438
+ wpLink.lastSearch = search;
439
+ waiting = t.parent().find( '.spinner' ).addClass( 'is-active' );
440
+
441
+ rivers.search.change( search );
442
+ rivers.search.ajax( function() {
443
+ waiting.removeClass( 'is-active' );
444
+ });
445
+ } else {
446
+ rivers.search.hide();
447
+ rivers.recent.show();
448
+ }
449
+ },
450
+
451
+ next: function() {
452
+ rivers.search.next();
453
+ rivers.recent.next();
454
+ },
455
+
456
+ prev: function() {
457
+ rivers.search.prev();
458
+ rivers.recent.prev();
459
+ },
460
+
461
+ keydown: function( event ) {
462
+ var fn, id,
463
+ key = $.ui.keyCode;
464
+
465
+ if ( key.ESCAPE === event.keyCode ) {
466
+ wpLink.close();
467
+ event.stopImmediatePropagation();
468
+ } else if ( key.TAB === event.keyCode ) {
469
+ id = event.target.id;
470
+
471
+ // wp-link-submit must always be the last focusable element in the dialog.
472
+ // following focusable elements will be skipped on keyboard navigation.
473
+ if ( id === 'wp-link-submit' && ! event.shiftKey ) {
474
+ inputs.close.focus();
475
+ event.preventDefault();
476
+ } else if ( id === 'wp-link-close' && event.shiftKey ) {
477
+ inputs.submit.focus();
478
+ event.preventDefault();
479
+ }
480
+ }
481
+
482
+ if ( event.keyCode !== key.UP && event.keyCode !== key.DOWN ) {
483
+ return;
484
+ }
485
+
486
+ if ( document.activeElement &&
487
+ ( document.activeElement.id === 'link-title-field' || document.activeElement.id === 'url-field' ) ) {
488
+ return;
489
+ }
490
+
491
+ fn = event.keyCode === key.UP ? 'prev' : 'next';
492
+ clearInterval( wpLink.keyInterval );
493
+ wpLink[ fn ]();
494
+ wpLink.keyInterval = setInterval( wpLink[ fn ], wpLink.keySensitivity );
495
+ event.preventDefault();
496
+ },
497
+
498
+ keyup: function( event ) {
499
+ var key = $.ui.keyCode;
500
+
501
+ if ( event.which === key.UP || event.which === key.DOWN ) {
502
+ clearInterval( wpLink.keyInterval );
503
+ event.preventDefault();
504
+ }
505
+ },
506
+
507
+ delayedCallback: function( func, delay ) {
508
+ var timeoutTriggered, funcTriggered, funcArgs, funcContext;
509
+
510
+ if ( ! delay )
511
+ return func;
512
+
513
+ setTimeout( function() {
514
+ if ( funcTriggered )
515
+ return func.apply( funcContext, funcArgs );
516
+ // Otherwise, wait.
517
+ timeoutTriggered = true;
518
+ }, delay );
519
+
520
+ return function() {
521
+ if ( timeoutTriggered )
522
+ return func.apply( this, arguments );
523
+ // Otherwise, wait.
524
+ funcArgs = arguments;
525
+ funcContext = this;
526
+ funcTriggered = true;
527
+ };
528
+ },
529
+
530
+ toggleInternalLinking: function( event ) {
531
+ var visible = inputs.wrap.hasClass( 'search-panel-visible' );
532
+
533
+ inputs.wrap.toggleClass( 'search-panel-visible', ! visible );
534
+ setUserSetting( 'wplink', visible ? '0' : '1' );
535
+ inputs[ ! visible ? 'search' : 'url' ].focus();
536
+ event.preventDefault();
537
+ }
538
+ };
539
+
540
+ River = function( element, search ) {
541
+ var self = this;
542
+ this.element = element;
543
+ this.ul = element.children( 'ul' );
544
+ this.contentHeight = element.children( '#link-selector-height' );
545
+ this.waiting = element.find('.river-waiting');
546
+
547
+ this.change( search );
548
+ this.refresh();
549
+
550
+ $( '#wp-link .query-results, #wp-link #link-selector' ).scroll( function() {
551
+ self.maybeLoad();
552
+ });
553
+ element.on( 'click', 'li', function( event ) {
554
+ self.select( $( this ), event );
555
+ });
556
+ };
557
+
558
+ $.extend( River.prototype, {
559
+ refresh: function() {
560
+ this.deselect();
561
+ this.visible = this.element.is( ':visible' );
562
+ },
563
+ show: function() {
564
+ if ( ! this.visible ) {
565
+ this.deselect();
566
+ this.element.show();
567
+ this.visible = true;
568
+ }
569
+ },
570
+ hide: function() {
571
+ this.element.hide();
572
+ this.visible = false;
573
+ },
574
+ // Selects a list item and triggers the river-select event.
575
+ select: function( li, event ) {
576
+ var liHeight, elHeight, liTop, elTop;
577
+
578
+ if ( li.hasClass( 'unselectable' ) || li == this.selected )
579
+ return;
580
+
581
+ this.deselect();
582
+ this.selected = li.addClass( 'selected' );
583
+ // Make sure the element is visible
584
+ liHeight = li.outerHeight();
585
+ elHeight = this.element.height();
586
+ liTop = li.position().top;
587
+ elTop = this.element.scrollTop();
588
+
589
+ if ( liTop < 0 ) // Make first visible element
590
+ this.element.scrollTop( elTop + liTop );
591
+ else if ( liTop + liHeight > elHeight ) // Make last visible element
592
+ this.element.scrollTop( elTop + liTop - elHeight + liHeight );
593
+
594
+ // Trigger the river-select event
595
+ this.element.trigger( 'river-select', [ li, event, this ] );
596
+ },
597
+ deselect: function() {
598
+ if ( this.selected )
599
+ this.selected.removeClass( 'selected' );
600
+ this.selected = false;
601
+ },
602
+ prev: function() {
603
+ if ( ! this.visible )
604
+ return;
605
+
606
+ var to;
607
+ if ( this.selected ) {
608
+ to = this.selected.prev( 'li' );
609
+ if ( to.length )
610
+ this.select( to );
611
+ }
612
+ },
613
+ next: function() {
614
+ if ( ! this.visible )
615
+ return;
616
+
617
+ var to = this.selected ? this.selected.next( 'li' ) : $( 'li:not(.unselectable):first', this.element );
618
+ if ( to.length )
619
+ this.select( to );
620
+ },
621
+ ajax: function( callback ) {
622
+ var self = this,
623
+ delay = this.query.page == 1 ? 0 : wpLink.minRiverAJAXDuration,
624
+ response = wpLink.delayedCallback( function( results, params ) {
625
+ self.process( results, params );
626
+ if ( callback )
627
+ callback( results, params );
628
+ }, delay );
629
+
630
+ this.query.ajax( response );
631
+ },
632
+ change: function( search ) {
633
+ if ( this.query && this._search == search )
634
+ return;
635
+
636
+ this._search = search;
637
+ this.query = new Query( search );
638
+ this.element.scrollTop( 0 );
639
+ },
640
+ process: function( results, params ) {
641
+ var list = '', alt = true, classes = '',
642
+ firstPage = params.page == 1;
643
+
644
+ if ( ! results ) {
645
+ if ( firstPage ) {
646
+ list += '<li class="unselectable no-matches-found"><span class="item-title"><em>' +
647
+ wpLinkL10n.noMatchesFound + '</em></span></li>';
648
+ }
649
+ } else {
650
+ $.each( results, function() {
651
+ classes = alt ? 'alternate' : '';
652
+ classes += this.title ? '' : ' no-title';
653
+ list += classes ? '<li class="' + classes + '">' : '<li>';
654
+ list += '<input type="hidden" class="item-permalink" value="' + this.permalink + '" />';
655
+ list += '<span class="item-title">';
656
+ list += this.title ? this.title : wpLinkL10n.noTitle;
657
+ list += '</span><span class="item-info">' + this.info + '</span></li>';
658
+ alt = ! alt;
659
+ });
660
+ }
661
+
662
+ this.ul[ firstPage ? 'html' : 'append' ]( list );
663
+ },
664
+ maybeLoad: function() {
665
+ var self = this,
666
+ el = this.element,
667
+ bottom = el.scrollTop() + el.height();
668
+
669
+ if ( ! this.query.ready() || bottom < this.contentHeight.height() - wpLink.riverBottomThreshold )
670
+ return;
671
+
672
+ setTimeout(function() {
673
+ var newTop = el.scrollTop(),
674
+ newBottom = newTop + el.height();
675
+
676
+ if ( ! self.query.ready() || newBottom < self.contentHeight.height() - wpLink.riverBottomThreshold )
677
+ return;
678
+
679
+ self.waiting.addClass( 'is-active' );
680
+ el.scrollTop( newTop + self.waiting.outerHeight() );
681
+
682
+ self.ajax( function() {
683
+ self.waiting.removeClass( 'is-active' );
684
+ });
685
+ }, wpLink.timeToTriggerRiver );
686
+ }
687
+ });
688
+
689
+ Query = function( search ) {
690
+ this.page = 1;
691
+ this.allLoaded = false;
692
+ this.querying = false;
693
+ this.search = search;
694
+ };
695
+
696
+ $.extend( Query.prototype, {
697
+ ready: function() {
698
+ return ! ( this.querying || this.allLoaded );
699
+ },
700
+ ajax: function( callback ) {
701
+ var self = this,
702
+ query = {
703
+ action : 'wp-link-ajax',
704
+ page : this.page,
705
+ '_ajax_linking_nonce' : inputs.nonce.val()
706
+ };
707
+
708
+ if ( this.search )
709
+ query.search = this.search;
710
+
711
+ this.querying = true;
712
+
713
+ $.post( ajaxurl, query, function( r ) {
714
+ self.page++;
715
+ self.querying = false;
716
+ self.allLoaded = ! r;
717
+ callback( r, query );
718
+ }, 'json' );
719
+ }
720
+ });
721
+
722
+ $( document ).ready( wpLink.append ); // (mod)
723
+ $( document ).ready( wpLink.init );
724
+ })( jQuery );
wplink.min.js CHANGED
@@ -1 +1 @@
1
- var wpLink;!function(t){function n(){return i.dom.getParent(i.selection.getNode(),"a")}var i,a,s,r,l,o={},c={},u="ontouchend"in document;wpLink={timeToTriggerRiver:150,minRiverAJAXDuration:200,riverBottomThreshold:5,keySensitivity:100,lastSearch:"",textarea:"",append:function(){var e='<br /><label><span> </span><input type="checkbox" id="link-nofollow-checkbox" /> Add <code>rel="nofollow"</code> to link</label>';t("#wp-link .link-target").append(e)},init:function(){function e(){var e=t.trim(o.url.val());e&&l!==e&&!/^(?:[a-z]+:|#|\?|\.|\/)/.test(e)&&(o.url.val("http://"+e),l=e)}o.wrap=t("#wp-link-wrap"),o.dialog=t("#wp-link"),o.backdrop=t("#wp-link-backdrop"),o.submit=t("#wp-link-submit"),o.close=t("#wp-link-close"),o.text=t("#wp-link-text"),o.url=t("#wp-link-url"),o.nonce=t("#_ajax_linking_nonce"),o.openInNewTab=t("#wp-link-target"),o.relNofollow=t("#link-nofollow-checkbox"),o.search=t("#wp-link-search"),c.search=new s(t("#search-results")),c.recent=new s(t("#most-recent-results")),c.elements=o.dialog.find(".query-results"),o.queryNotice=t("#query-notice-message"),o.queryNoticeTextDefault=o.queryNotice.find(".query-notice-default"),o.queryNoticeTextHint=o.queryNotice.find(".query-notice-hint"),o.dialog.keydown(wpLink.keydown),o.dialog.keyup(wpLink.keyup),o.submit.click(function(e){e.preventDefault(),wpLink.update()}),o.close.add(o.backdrop).add("#wp-link-cancel a").click(function(e){e.preventDefault(),wpLink.close()}),t("#wp-link-search-toggle").on("click",wpLink.toggleInternalLinking),c.elements.on("river-select",wpLink.updateFields),o.search.on("focus.wplink",function(){o.queryNoticeTextDefault.hide(),o.queryNoticeTextHint.removeClass("screen-reader-text").show()}).on("blur.wplink",function(){o.queryNoticeTextDefault.show(),o.queryNoticeTextHint.addClass("screen-reader-text").hide()}),o.search.keyup(function(){var e=this;window.clearTimeout(a),a=window.setTimeout(function(){wpLink.searchInternalLinks.call(e)},500)}),o.url.on("paste",function(){setTimeout(e,0)}),o.url.on("blur",e)},open:function(e){var n;t(document.body).addClass("modal-open"),wpLink.range=null,e&&(window.wpActiveEditor=e),window.wpActiveEditor&&(this.textarea=t("#"+window.wpActiveEditor).get(0),"undefined"!=typeof tinymce&&(n=tinymce.get(wpActiveEditor),i=n&&!n.isHidden()?n:null,i&&tinymce.isIE&&(i.windowManager.bookmark=i.selection.getBookmark())),!wpLink.isMCE()&&document.selection&&(this.textarea.focus(),this.range=document.selection.createRange()),o.wrap.show(),o.backdrop.show(),wpLink.refresh(),t(document).trigger("wplink-open",o.wrap))},isMCE:function(){return i&&!i.isHidden()},refresh:function(){var e="";c.search.refresh(),c.recent.refresh(),wpLink.isMCE()?wpLink.mceRefresh():(o.wrap.hasClass("has-text-field")||o.wrap.addClass("has-text-field"),document.selection?e=document.selection.createRange().text||"":"undefined"!=typeof this.textarea.selectionStart&&this.textarea.selectionStart!==this.textarea.selectionEnd&&(e=this.textarea.value.substring(this.textarea.selectionStart,this.textarea.selectionEnd)||""),o.text.val(e),wpLink.setDefaultValues()),u?o.url.focus().blur():o.url.focus()[0].select(),c.recent.ul.children().length||c.recent.ajax(),l=o.url.val().replace(/^http:\/\//,"")},hasSelectedText:function(e){var t=i.selection.getContent();if(/</.test(t)&&(!/^<a [^>]+>[^<]+<\/a>$/.test(t)||-1===t.indexOf("href=")))return!1;if(e){var n,a=e.childNodes;if(0===a.length)return!1;for(n=a.length-1;n>=0;n--)if(3!=a[n].nodeType)return!1}return!0},mceRefresh:function(){var t,n=i.selection.getNode(),a=i.dom.getParent(n,"a[href]"),s=this.hasSelectedText(a);a?(t=a.innerText||a.textContent,o.url.val(i.dom.getAttrib(a,"href")),o.openInNewTab.prop("checked","_blank"===i.dom.getAttrib(a,"target")),"nofollow"==ed.dom.getAttrib(e,"rel")&&o.relNofollow.prop("checked",!0),o.submit.val(wpLinkL10n.update)):(t=i.selection.getContent({format:"text"}),this.setDefaultValues()),s?(o.text.val(t||""),o.wrap.addClass("has-text-field")):(o.text.val(""),o.wrap.removeClass("has-text-field"))},close:function(){t(document.body).removeClass("modal-open"),wpLink.isMCE()?i.focus():(wpLink.textarea.focus(),wpLink.range&&(wpLink.range.moveToBookmark(wpLink.range.getBookmark()),wpLink.range.select())),o.backdrop.hide(),o.wrap.hide(),l=!1,t(document).trigger("wplink-close",o.wrap)},getAttrs:function(){return{href:t.trim(o.url.val()),target:o.openInNewTab.prop("checked")?"_blank":"",rel:o.relNofollow.prop("checked")?"nofollow":""}},update:function(){wpLink.isMCE()?wpLink.mceUpdate():wpLink.htmlUpdate()},htmlUpdate:function(){var e,t,n,i,a,s,r,l=wpLink.textarea;l&&(e=wpLink.getAttrs(),t=o.text.val(),e.href&&(n='<a href="'+e.href+'"',e.target&&(n+=' target="'+e.target+'"'),e.rel&&(n+=' rel="'+e.rel+'"'),n+=">",document.selection&&wpLink.range?(l.focus(),wpLink.range.text=n+(t||wpLink.range.text)+"</a>",wpLink.range.moveToBookmark(wpLink.range.getBookmark()),wpLink.range.select(),wpLink.range=null):"undefined"!=typeof l.selectionStart&&(i=l.selectionStart,a=l.selectionEnd,r=t||l.value.substring(i,a),n=n+r+"</a>",s=i+n.length,i!==a||r||(s-=4),l.value=l.value.substring(0,i)+n+l.value.substring(a,l.value.length),l.selectionStart=l.selectionEnd=s),wpLink.close(),l.focus()))},mceUpdate:function(){var e,t,a=wpLink.getAttrs();return wpLink.close(),i.focus(),tinymce.isIE&&i.selection.moveToBookmark(i.windowManager.bookmark),a.href?(e=n(),t=o.text.val(),void(e?(t&&("innerText"in e?e.innerText=t:e.textContent=t),i.dom.setAttribs(e,a)):t?i.selection.setNode(i.dom.create("a",a,t)):i.execCommand("mceInsertLink",!1,a))):void i.execCommand("unlink")},updateFields:function(e,t){o.url.val(t.children(".item-permalink").val())},setDefaultValues:function(){var e,t=/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i,n=/^(https?|ftp):\/\/[A-Z0-9.-]+\.[A-Z]{2,4}[^ "]*$/i;this.isMCE()?e=i.selection.getContent():document.selection&&wpLink.range?e=wpLink.range.text:"undefined"!=typeof this.textarea.selectionStart&&(e=this.textarea.value.substring(this.textarea.selectionStart,this.textarea.selectionEnd)),o.url.val(e&&t.test(e)?"mailto:"+e:e&&n.test(e)?e.replace(/&|&#0?38;/gi,"&"):""),o.submit.val(wpLinkL10n.save)},searchInternalLinks:function(){var e,n=t(this),i=n.val();if(i.length>2){if(c.recent.hide(),c.search.show(),wpLink.lastSearch==i)return;wpLink.lastSearch=i,e=n.parent().find(".spinner").addClass("is-active"),c.search.change(i),c.search.ajax(function(){e.removeClass("is-active")})}else c.search.hide(),c.recent.show()},next:function(){c.search.next(),c.recent.next()},prev:function(){c.search.prev(),c.recent.prev()},keydown:function(e){var n,i,a=t.ui.keyCode;a.ESCAPE===e.keyCode?(wpLink.close(),e.stopImmediatePropagation()):a.TAB===e.keyCode&&(i=e.target.id,"wp-link-submit"!==i||e.shiftKey?"wp-link-close"===i&&e.shiftKey&&(o.submit.focus(),e.preventDefault()):(o.close.focus(),e.preventDefault())),(e.keyCode===a.UP||e.keyCode===a.DOWN)&&(!document.activeElement||"link-title-field"!==document.activeElement.id&&"url-field"!==document.activeElement.id)&&(n=e.keyCode===a.UP?"prev":"next",clearInterval(wpLink.keyInterval),wpLink[n](),wpLink.keyInterval=setInterval(wpLink[n],wpLink.keySensitivity),e.preventDefault())},keyup:function(e){var n=t.ui.keyCode;(e.which===n.UP||e.which===n.DOWN)&&(clearInterval(wpLink.keyInterval),e.preventDefault())},delayedCallback:function(e,t){var n,i,a,s;return t?(setTimeout(function(){return i?e.apply(s,a):void(n=!0)},t),function(){return n?e.apply(this,arguments):(a=arguments,s=this,void(i=!0))}):e},toggleInternalLinking:function(e){var t=o.wrap.hasClass("search-panel-visible");o.wrap.toggleClass("search-panel-visible",!t),setUserSetting("wplink",t?"0":"1"),o[t?"url":"search"].focus(),e.preventDefault()}},s=function(e,n){var i=this;this.element=e,this.ul=e.children("ul"),this.contentHeight=e.children("#link-selector-height"),this.waiting=e.find(".river-waiting"),this.change(n),this.refresh(),t("#wp-link .query-results, #wp-link #link-selector").scroll(function(){i.maybeLoad()}),e.on("click","li",function(e){i.select(t(this),e)})},t.extend(s.prototype,{refresh:function(){this.deselect(),this.visible=this.element.is(":visible")},show:function(){this.visible||(this.deselect(),this.element.show(),this.visible=!0)},hide:function(){this.element.hide(),this.visible=!1},select:function(e,t){var n,i,a,s;e.hasClass("unselectable")||e==this.selected||(this.deselect(),this.selected=e.addClass("selected"),n=e.outerHeight(),i=this.element.height(),a=e.position().top,s=this.element.scrollTop(),0>a?this.element.scrollTop(s+a):a+n>i&&this.element.scrollTop(s+a-i+n),this.element.trigger("river-select",[e,t,this]))},deselect:function(){this.selected&&this.selected.removeClass("selected"),this.selected=!1},prev:function(){if(this.visible){var e;this.selected&&(e=this.selected.prev("li"),e.length&&this.select(e))}},next:function(){if(this.visible){var e=this.selected?this.selected.next("li"):t("li:not(.unselectable):first",this.element);e.length&&this.select(e)}},ajax:function(e){var t=this,n=1==this.query.page?0:wpLink.minRiverAJAXDuration,i=wpLink.delayedCallback(function(n,i){t.process(n,i),e&&e(n,i)},n);this.query.ajax(i)},change:function(e){this.query&&this._search==e||(this._search=e,this.query=new r(e),this.element.scrollTop(0))},process:function(e,n){var i="",a=!0,s="",r=1==n.page;e?t.each(e,function(){s=a?"alternate":"",s+=this.title?"":" no-title",i+=s?'<li class="'+s+'">':"<li>",i+='<input type="hidden" class="item-permalink" value="'+this.permalink+'" />',i+='<span class="item-title">',i+=this.title?this.title:wpLinkL10n.noTitle,i+='</span><span class="item-info">'+this.info+"</span></li>",a=!a}):r&&(i+='<li class="unselectable no-matches-found"><span class="item-title"><em>'+wpLinkL10n.noMatchesFound+"</em></span></li>"),this.ul[r?"html":"append"](i)},maybeLoad:function(){var e=this,t=this.element,n=t.scrollTop()+t.height();!this.query.ready()||n<this.contentHeight.height()-wpLink.riverBottomThreshold||setTimeout(function(){var n=t.scrollTop(),i=n+t.height();!e.query.ready()||i<e.contentHeight.height()-wpLink.riverBottomThreshold||(e.waiting.addClass("is-active"),t.scrollTop(n+e.waiting.outerHeight()),e.ajax(function(){e.waiting.removeClass("is-active")}))},wpLink.timeToTriggerRiver)}}),r=function(e){this.page=1,this.allLoaded=!1,this.querying=!1,this.search=e},t.extend(r.prototype,{ready:function(){return!(this.querying||this.allLoaded)},ajax:function(e){var n=this,i={action:"wp-link-ajax",page:this.page,_ajax_linking_nonce:o.nonce.val()};this.search&&(i.search=this.search),this.querying=!0,t.post(ajaxurl,i,function(t){n.page++,n.querying=!1,n.allLoaded=!t,e(t,i)},"json")}}),t(document).ready(wpLink.append),t(document).ready(wpLink.init)}(jQuery);
1
+ var wpLink;!function(t){function n(){return i.dom.getParent(i.selection.getNode(),"a")}var i,a,s,r,l,o={},c={},u="ontouchend"in document;wpLink={timeToTriggerRiver:150,minRiverAJAXDuration:200,riverBottomThreshold:5,keySensitivity:100,lastSearch:"",textarea:"",append:function(){var e='<br /><label><span> </span><input type="checkbox" id="link-nofollow-checkbox" /> Add <code>rel="nofollow"</code> to link</label>';t("#wp-link .link-target").append(e)},init:function(){function e(){var e=t.trim(o.url.val());e&&l!==e&&!/^(?:[a-z]+:|#|\?|\.|\/)/.test(e)&&(o.url.val("http://"+e),l=e)}o.wrap=t("#wp-link-wrap"),o.dialog=t("#wp-link"),o.backdrop=t("#wp-link-backdrop"),o.submit=t("#wp-link-submit"),o.close=t("#wp-link-close"),o.text=t("#wp-link-text"),o.url=t("#wp-link-url"),o.nonce=t("#_ajax_linking_nonce"),o.openInNewTab=t("#wp-link-target"),o.relNofollow=t("#link-nofollow-checkbox"),o.search=t("#wp-link-search"),c.search=new s(t("#search-results")),c.recent=new s(t("#most-recent-results")),c.elements=o.dialog.find(".query-results"),o.queryNotice=t("#query-notice-message"),o.queryNoticeTextDefault=o.queryNotice.find(".query-notice-default"),o.queryNoticeTextHint=o.queryNotice.find(".query-notice-hint"),o.dialog.keydown(wpLink.keydown),o.dialog.keyup(wpLink.keyup),o.submit.click(function(e){e.preventDefault(),wpLink.update()}),o.close.add(o.backdrop).add("#wp-link-cancel a").click(function(e){e.preventDefault(),wpLink.close()}),t("#wp-link-search-toggle").on("click",wpLink.toggleInternalLinking),c.elements.on("river-select",wpLink.updateFields),o.search.on("focus.wplink",function(){o.queryNoticeTextDefault.hide(),o.queryNoticeTextHint.removeClass("screen-reader-text").show()}).on("blur.wplink",function(){o.queryNoticeTextDefault.show(),o.queryNoticeTextHint.addClass("screen-reader-text").hide()}),o.search.keyup(function(){var e=this;window.clearTimeout(a),a=window.setTimeout(function(){wpLink.searchInternalLinks.call(e)},500)}),o.url.on("paste",function(){setTimeout(e,0)}),o.url.on("blur",e)},open:function(e){var n;t(document.body).addClass("modal-open"),wpLink.range=null,e&&(window.wpActiveEditor=e),window.wpActiveEditor&&(this.textarea=t("#"+window.wpActiveEditor).get(0),"undefined"!=typeof tinymce&&(n=tinymce.get(wpActiveEditor),i=n&&!n.isHidden()?n:null,i&&tinymce.isIE&&(i.windowManager.bookmark=i.selection.getBookmark())),!wpLink.isMCE()&&document.selection&&(this.textarea.focus(),this.range=document.selection.createRange()),o.wrap.show(),o.backdrop.show(),wpLink.refresh(),t(document).trigger("wplink-open",o.wrap))},isMCE:function(){return i&&!i.isHidden()},refresh:function(){var e="";c.search.refresh(),c.recent.refresh(),wpLink.isMCE()?wpLink.mceRefresh():(o.wrap.hasClass("has-text-field")||o.wrap.addClass("has-text-field"),document.selection?e=document.selection.createRange().text||"":"undefined"!=typeof this.textarea.selectionStart&&this.textarea.selectionStart!==this.textarea.selectionEnd&&(e=this.textarea.value.substring(this.textarea.selectionStart,this.textarea.selectionEnd)||""),o.text.val(e),wpLink.setDefaultValues()),u?o.url.focus().blur():o.url.focus()[0].select(),c.recent.ul.children().length||c.recent.ajax(),l=o.url.val().replace(/^http:\/\//,"")},hasSelectedText:function(e){var t=i.selection.getContent();if(/</.test(t)&&(!/^<a [^>]+>[^<]+<\/a>$/.test(t)||-1===t.indexOf("href=")))return!1;if(e){var n,a=e.childNodes;if(0===a.length)return!1;for(n=a.length-1;n>=0;n--)if(3!=a[n].nodeType)return!1}return!0},mceRefresh:function(){var t,n=i.selection.getNode(),a=i.dom.getParent(n,"a[href]"),s=this.hasSelectedText(a);a?(t=a.innerText||a.textContent,o.url.val(i.dom.getAttrib(a,"href")),o.openInNewTab.prop("checked","_blank"===i.dom.getAttrib(a,"target")),"nofollow"==ed.dom.getAttrib(e,"rel")&&o.relNofollow.prop("checked",!0),o.submit.val(wpLinkL10n.update)):(t=i.selection.getContent({format:"text"}),this.setDefaultValues()),s?(o.text.val(t||""),o.wrap.addClass("has-text-field")):(o.text.val(""),o.wrap.removeClass("has-text-field"))},close:function(){t(document.body).removeClass("modal-open"),wpLink.isMCE()?i.focus():(wpLink.textarea.focus(),wpLink.range&&(wpLink.range.moveToBookmark(wpLink.range.getBookmark()),wpLink.range.select())),o.backdrop.hide(),o.wrap.hide(),l=!1,t(document).trigger("wplink-close",o.wrap)},getAttrs:function(){return{href:t.trim(o.url.val()),target:o.openInNewTab.prop("checked")?"_blank":"",rel:o.relNofollow.prop("checked")?"nofollow":""}},update:function(){wpLink.isMCE()?wpLink.mceUpdate():wpLink.htmlUpdate()},htmlUpdate:function(){var e,t,n,i,a,s,r,l=wpLink.textarea;l&&(e=wpLink.getAttrs(),t=o.text.val(),e.href&&(n='<a href="'+e.href+'"',e.target&&(n+=' target="'+e.target+'"'),e.rel&&(n+=' rel="'+e.rel+'"'),n+=">",document.selection&&wpLink.range?(l.focus(),wpLink.range.text=n+(t||wpLink.range.text)+"</a>",wpLink.range.moveToBookmark(wpLink.range.getBookmark()),wpLink.range.select(),wpLink.range=null):"undefined"!=typeof l.selectionStart&&(i=l.selectionStart,a=l.selectionEnd,r=t||l.value.substring(i,a),n=n+r+"</a>",s=i+n.length,i!==a||r||(s-=4),l.value=l.value.substring(0,i)+n+l.value.substring(a,l.value.length),l.selectionStart=l.selectionEnd=s),wpLink.close(),l.focus()))},mceUpdate:function(){var e,t,a=wpLink.getAttrs();return wpLink.close(),i.focus(),tinymce.isIE&&i.selection.moveToBookmark(i.windowManager.bookmark),a.href?(e=n(),t=o.text.val(),void(e?(t&&("innerText"in e?e.innerText=t:e.textContent=t),i.dom.setAttribs(e,a)):t?i.selection.setNode(i.dom.create("a",a,t)):i.execCommand("mceInsertLink",!1,a))):void i.execCommand("unlink")},updateFields:function(e,t){o.url.val(t.children(".item-permalink").val())},setDefaultValues:function(){var e,t=/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i,n=/^(https?|ftp):\/\/[A-Z0-9.-]+\.[A-Z]{2,4}[^ "]*$/i;this.isMCE()?e=i.selection.getContent():document.selection&&wpLink.range?e=wpLink.range.text:"undefined"!=typeof this.textarea.selectionStart&&(e=this.textarea.value.substring(this.textarea.selectionStart,this.textarea.selectionEnd)),e&&t.test(e)?o.url.val("mailto:"+e):e&&n.test(e)?o.url.val(e.replace(/&amp;|&#0?38;/gi,"&")):o.url.val(""),o.submit.val(wpLinkL10n.save)},searchInternalLinks:function(){var e,n=t(this),i=n.val();if(i.length>2){if(c.recent.hide(),c.search.show(),wpLink.lastSearch==i)return;wpLink.lastSearch=i,e=n.parent().find(".spinner").addClass("is-active"),c.search.change(i),c.search.ajax(function(){e.removeClass("is-active")})}else c.search.hide(),c.recent.show()},next:function(){c.search.next(),c.recent.next()},prev:function(){c.search.prev(),c.recent.prev()},keydown:function(e){var n,i,a=t.ui.keyCode;a.ESCAPE===e.keyCode?(wpLink.close(),e.stopImmediatePropagation()):a.TAB===e.keyCode&&(i=e.target.id,"wp-link-submit"!==i||e.shiftKey?"wp-link-close"===i&&e.shiftKey&&(o.submit.focus(),e.preventDefault()):(o.close.focus(),e.preventDefault())),(e.keyCode===a.UP||e.keyCode===a.DOWN)&&(!document.activeElement||"link-title-field"!==document.activeElement.id&&"url-field"!==document.activeElement.id)&&(n=e.keyCode===a.UP?"prev":"next",clearInterval(wpLink.keyInterval),wpLink[n](),wpLink.keyInterval=setInterval(wpLink[n],wpLink.keySensitivity),e.preventDefault())},keyup:function(e){var n=t.ui.keyCode;(e.which===n.UP||e.which===n.DOWN)&&(clearInterval(wpLink.keyInterval),e.preventDefault())},delayedCallback:function(e,t){var n,i,a,s;return t?(setTimeout(function(){return i?e.apply(s,a):void(n=!0)},t),function(){return n?e.apply(this,arguments):(a=arguments,s=this,void(i=!0))}):e},toggleInternalLinking:function(e){var t=o.wrap.hasClass("search-panel-visible");o.wrap.toggleClass("search-panel-visible",!t),setUserSetting("wplink",t?"0":"1"),o[t?"url":"search"].focus(),e.preventDefault()}},s=function(e,n){var i=this;this.element=e,this.ul=e.children("ul"),this.contentHeight=e.children("#link-selector-height"),this.waiting=e.find(".river-waiting"),this.change(n),this.refresh(),t("#wp-link .query-results, #wp-link #link-selector").scroll(function(){i.maybeLoad()}),e.on("click","li",function(e){i.select(t(this),e)})},t.extend(s.prototype,{refresh:function(){this.deselect(),this.visible=this.element.is(":visible")},show:function(){this.visible||(this.deselect(),this.element.show(),this.visible=!0)},hide:function(){this.element.hide(),this.visible=!1},select:function(e,t){var n,i,a,s;e.hasClass("unselectable")||e==this.selected||(this.deselect(),this.selected=e.addClass("selected"),n=e.outerHeight(),i=this.element.height(),a=e.position().top,s=this.element.scrollTop(),0>a?this.element.scrollTop(s+a):a+n>i&&this.element.scrollTop(s+a-i+n),this.element.trigger("river-select",[e,t,this]))},deselect:function(){this.selected&&this.selected.removeClass("selected"),this.selected=!1},prev:function(){if(this.visible){var e;this.selected&&(e=this.selected.prev("li"),e.length&&this.select(e))}},next:function(){if(this.visible){var e=this.selected?this.selected.next("li"):t("li:not(.unselectable):first",this.element);e.length&&this.select(e)}},ajax:function(e){var t=this,n=1==this.query.page?0:wpLink.minRiverAJAXDuration,i=wpLink.delayedCallback(function(n,i){t.process(n,i),e&&e(n,i)},n);this.query.ajax(i)},change:function(e){this.query&&this._search==e||(this._search=e,this.query=new r(e),this.element.scrollTop(0))},process:function(e,n){var i="",a=!0,s="",r=1==n.page;e?t.each(e,function(){s=a?"alternate":"",s+=this.title?"":" no-title",i+=s?'<li class="'+s+'">':"<li>",i+='<input type="hidden" class="item-permalink" value="'+this.permalink+'" />',i+='<span class="item-title">',i+=this.title?this.title:wpLinkL10n.noTitle,i+='</span><span class="item-info">'+this.info+"</span></li>",a=!a}):r&&(i+='<li class="unselectable no-matches-found"><span class="item-title"><em>'+wpLinkL10n.noMatchesFound+"</em></span></li>"),this.ul[r?"html":"append"](i)},maybeLoad:function(){var e=this,t=this.element,n=t.scrollTop()+t.height();!this.query.ready()||n<this.contentHeight.height()-wpLink.riverBottomThreshold||setTimeout(function(){var n=t.scrollTop(),i=n+t.height();!e.query.ready()||i<e.contentHeight.height()-wpLink.riverBottomThreshold||(e.waiting.addClass("is-active"),t.scrollTop(n+e.waiting.outerHeight()),e.ajax(function(){e.waiting.removeClass("is-active")}))},wpLink.timeToTriggerRiver)}}),r=function(e){this.page=1,this.allLoaded=!1,this.querying=!1,this.search=e},t.extend(r.prototype,{ready:function(){return!(this.querying||this.allLoaded)},ajax:function(e){var n=this,i={action:"wp-link-ajax",page:this.page,_ajax_linking_nonce:o.nonce.val()};this.search&&(i.search=this.search),this.querying=!0,t.post(ajaxurl,i,function(t){n.page++,n.querying=!1,n.allLoaded=!t,e(t,i)},"json")}}),t(document).ready(wpLink.append),t(document).ready(wpLink.init)}(jQuery);