Ultimate Nofollow - Version 1.4

Version Description

  • Official release
  • Added nofollow checkbox to individual post links
Download this release

Release Info

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

Code changes from version 0.1.3.1 to 1.4

Files changed (7) hide show
  1. nofollow.php +21 -1
  2. readme.txt +24 -20
  3. screenshot-1.png +0 -0
  4. screenshot-2.png +0 -0
  5. screenshot-3.png +0 -0
  6. wplink.js +608 -0
  7. wplink.min.js +1 -0
nofollow.php CHANGED
@@ -3,7 +3,7 @@
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: 0.1.3.1
7
  Author: bitacre
8
  Author URI: http://shinraholdings.com.com
9
  License: GPLv2
@@ -235,6 +235,23 @@ if( $ultnofo_options['nofollow_blogroll'] ) add_filter( 'get_bookmarks', 'ultnof
235
  /**********************************************
236
  * ADD LINK DIALOGUE NOFOLLOW CHECKBOX SECTION *
237
  ***********************************************/
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
238
 
239
  /************************************
240
  * NOFOLLOW ON COMMENT LINKS SECTION *
@@ -253,4 +270,7 @@ function ultnofo_comment_links( $comment ) {
253
  /* add hooks/filters */
254
  // add/remove nofollow from comment links
255
  add_filter('comment_text', 'ultnofo_comment_links', 10);
 
 
 
256
  ?>
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: 0.1.4
7
  Author: bitacre
8
  Author URI: http://shinraholdings.com.com
9
  License: GPLv2
235
  /**********************************************
236
  * ADD LINK DIALOGUE NOFOLLOW CHECKBOX SECTION *
237
  ***********************************************/
238
+ function nofollow_redo_wplink() {
239
+ wp_deregister_script( 'wplink' );
240
+
241
+ $suffix = defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? '' : '.min';
242
+
243
+ wp_register_script( 'wplink', plugins_url( 'wplink' . $suffix . '.js', __FILE__), array( 'jquery', 'wpdialogs' ), false, 1 );
244
+
245
+ wp_localize_script( 'wplink', 'wpLinkL10n', array(
246
+ 'title' => __('Insert/edit link'),
247
+ 'update' => __('Update'),
248
+ 'save' => __('Add Link'),
249
+ 'noTitle' => __('(no title)'),
250
+ 'noMatchesFound' => __('No matches found.')
251
+ ) );
252
+ }
253
+ add_action( 'admin_enqueue_scripts', 'nofollow_redo_wplink', 999 );
254
+
255
 
256
  /************************************
257
  * NOFOLLOW ON COMMENT LINKS SECTION *
270
  /* add hooks/filters */
271
  // add/remove nofollow from comment links
272
  add_filter('comment_text', 'ultnofo_comment_links', 10);
273
+
274
+ global $dddd;
275
+ var_dump( $dddd );
276
  ?>
readme.txt CHANGED
@@ -2,36 +2,35 @@
2
  Plugin URI: http://shinraholdings.com/plugins/nofollow
3
  Contributors: bitacre
4
  Donate link: http://shinraholdings.com/donate
5
- Tags: nofollow,link,meta,rel,rel nofollow,seo,link meta,nofollow links,shortcode
6
  Requires at least: 2.8
7
  Tested up to: 3.5
8
- Stable tag: 0.1.3.1
9
 
10
- A suite of tools that gives you complete control over the rel=nofollow tag on an individual link basis.
11
 
12
  == Description ==
13
- 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.
14
 
15
  The plugin's main features are:
16
 
17
- * several nofollow `shortcodes` *(added in v0.1.0)*,
18
- * a nofollow option for individual `blogroll links` *(added in v0.1.3)*,
19
- * or nofollow all `blogroll links` *(added in v0.1.3)*,
20
- * add or remove the nofollow tag from all links in `comments` *(added in v0.1.2)*,
21
- * plugin settings page *(added in v0.1.1)*.
22
-
23
- (The next version will include an option to nofollow individual links inserted in posts).
24
 
25
  == Installation ==
26
-
27
  1. Download the latest zip file and extract the `nofollow` directory.
28
  2. Upload it to your `/wp-content/plugins/` directory.
29
  3. Activate `Ultimate Nofollow` on the `Plugins` menu in WordPress.
30
 
31
  == Frequently Asked Questions ==
32
 
33
- = How do I use the shortcode? =
 
34
 
 
35
  You can use any of these shortcodes to insert a nofollowed link `[relnofollow]`, `[nofollow]`, `[nofol]`, `[nofo]`, or `[nf]` using the following format:
36
 
37
  `[nf href="http://link-url.com"]Link Text[/nf]`
@@ -41,12 +40,15 @@ You can also include the optional <a> attributes `title` and `target`. A full ex
41
  `[nf href="http://link-url.com" title="Link Title" target="_blank"]Link Text[/nf]`
42
 
43
  == Screenshots ==
44
-
45
- 1. Settings page on the Dashboard.
46
-
47
- 2. Nofollow checkbox on the add/edit blogroll link page.
48
 
49
  == Changelog ==
 
 
 
 
50
  = 0.1.3.1 =
51
  * Updates to documentation.
52
 
@@ -69,16 +71,18 @@ You can also include the optional <a> attributes `title` and `target`. A full ex
69
  * Stable, but not all functions active yet.
70
 
71
  == Upgrade Notice ==
 
 
72
  = 0.1.3.1 =
73
  Updated documentation.
74
 
75
  == Readme Generator ==
76
- * This plugin's readme.txt file was generated by the [bitacre Readme Generator](http://shinraholdings/tools/readme-gen) for WordPress Plugins.
77
 
78
  == Support ==
79
 
80
- * [Plugin Homepage](http://shinraholdings.com/plugins/nofollow)
81
- * [Help Page](http://shinraholdings.com/plugins/nofollow#help)
82
  * [plugins@shinraholdings.com](mailto:plugins@shinraholdings.com)
83
 
84
  == Donations ==
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: 3.5
8
+ Stable tag: 1.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
 
12
  == Description ==
13
+ This plugin contains several tools in one package to significantly increase your control of the rel="nofollow" tag on every link on your blog, on both an individual and categorical basis. It is designed to give you fine-grained control of linking for SEO purposes.
14
 
15
  The plugin's main features are:
16
 
17
+ * The addition of a **nofollow checkbox when inserting links in posts**
18
+ * Several **nofollow shortcodes**
19
+ * A nofollow option for **individual blogroll links**
20
+ * Or a **nofollow for all blogroll links** option
21
+ * Add or remove the nofollow tag from **all links in comments**
 
 
22
 
23
  == Installation ==
 
24
  1. Download the latest zip file and extract the `nofollow` directory.
25
  2. Upload it to your `/wp-content/plugins/` directory.
26
  3. Activate `Ultimate Nofollow` on the `Plugins` menu in WordPress.
27
 
28
  == Frequently Asked Questions ==
29
 
30
+ = How do I nofollow links I insert in my posts or pages? =
31
+ Just check the `add rel="nofollow" to link` option direction under the default `open link in a new window/tab` option.
32
 
33
+ = How do I use the shortcode? =
34
  You can use any of these shortcodes to insert a nofollowed link `[relnofollow]`, `[nofollow]`, `[nofol]`, `[nofo]`, or `[nf]` using the following format:
35
 
36
  `[nf href="http://link-url.com"]Link Text[/nf]`
40
  `[nf href="http://link-url.com" title="Link Title" target="_blank"]Link Text[/nf]`
41
 
42
  == Screenshots ==
43
+ 1. Nofollow option on the insert/edit link popup for posts and pages.
44
+ 2. Settings page on the Dashboard.
45
+ 3. Nofollow checkbox on the add/edit blogroll link page.
 
46
 
47
  == Changelog ==
48
+ = 1.4 =
49
+ * Official release
50
+ * Added nofollow checkbox to individual post links
51
+
52
  = 0.1.3.1 =
53
  * Updates to documentation.
54
 
71
  * Stable, but not all functions active yet.
72
 
73
  == Upgrade Notice ==
74
+ = 1.4 =
75
+ Strongly recommended upgrade, significant improvement in usefulness.
76
  = 0.1.3.1 =
77
  Updated documentation.
78
 
79
  == Readme Generator ==
80
+ * This plugin's readme.txt file was generated by the [bitacre Readme Generator](http://shinraholdings.com/tools/readme-gen) for WordPress Plugins.
81
 
82
  == Support ==
83
 
84
+ * [Plugin Homepage](http://shinraholdings.com/plugins/nofollow/)
85
+ * [Help Page](http://shinraholdings.com/plugins/nofollow/#help)
86
  * [plugins@shinraholdings.com](mailto:plugins@shinraholdings.com)
87
 
88
  == Donations ==
screenshot-1.png CHANGED
Binary file
screenshot-2.png CHANGED
Binary file
screenshot-3.png ADDED
Binary file
wplink.js ADDED
@@ -0,0 +1,608 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ var wpLink;
3
+
4
+ (function($){
5
+ var inputs = {}, rivers = {}, ed, River, Query;
6
+
7
+ wpLink = {
8
+ timeToTriggerRiver: 150,
9
+ minRiverAJAXDuration: 200,
10
+ riverBottomThreshold: 5,
11
+ keySensitivity: 100,
12
+ lastSearch: '',
13
+ textarea: '',
14
+
15
+ // append nofollow checkbox HTML (mod)
16
+ append : function() {
17
+ var html = '<br /><label><input type="checkbox" id="link-nofollow-checkbox" /> Add <code>rel="nofollow"</code> to link</label>';
18
+ $('#wp-link .link-target').append( html );
19
+ },
20
+
21
+ init : function() {
22
+ inputs.dialog = $('#wp-link');
23
+ inputs.submit = $('#wp-link-submit');
24
+ // URL
25
+ inputs.url = $('#url-field');
26
+ inputs.nonce = $('#_ajax_linking_nonce');
27
+ // Secondary options
28
+ inputs.title = $('#link-title-field');
29
+ // Advanced Options
30
+ inputs.openInNewTab = $('#link-target-checkbox');
31
+ inputs.relNofollow = $('#link-nofollow-checkbox'); // (mod)
32
+ inputs.search = $('#search-field');
33
+ // Build Rivers
34
+ rivers.search = new River( $('#search-results') );
35
+ rivers.recent = new River( $('#most-recent-results') );
36
+ rivers.elements = $('.query-results', inputs.dialog);
37
+
38
+ // Bind event handlers
39
+ inputs.dialog.keydown( wpLink.keydown );
40
+ inputs.dialog.keyup( wpLink.keyup );
41
+ inputs.submit.click( function(e){
42
+ e.preventDefault();
43
+ wpLink.update();
44
+ });
45
+ $('#wp-link-cancel').click( function(e){
46
+ e.preventDefault();
47
+ wpLink.close();
48
+ });
49
+ $('#internal-toggle').click( wpLink.toggleInternalLinking );
50
+
51
+ rivers.elements.bind('river-select', wpLink.updateFields );
52
+
53
+ inputs.search.keyup( wpLink.searchInternalLinks );
54
+
55
+ inputs.dialog.bind('wpdialogrefresh', wpLink.refresh);
56
+ inputs.dialog.bind('wpdialogbeforeopen', wpLink.beforeOpen);
57
+ inputs.dialog.bind('wpdialogclose', wpLink.onClose);
58
+ },
59
+
60
+ beforeOpen : function() {
61
+ wpLink.range = null;
62
+
63
+ if ( ! wpLink.isMCE() && document.selection ) {
64
+ wpLink.textarea.focus();
65
+ wpLink.range = document.selection.createRange();
66
+ }
67
+ },
68
+
69
+ open : function() {
70
+ if ( !wpActiveEditor )
71
+ return;
72
+
73
+ this.textarea = $('#'+wpActiveEditor).get(0);
74
+
75
+ // Initialize the dialog if necessary (html mode).
76
+ if ( ! inputs.dialog.data('wpdialog') ) {
77
+ inputs.dialog.wpdialog({
78
+ title: wpLinkL10n.title,
79
+ width: 480,
80
+ height: 'auto',
81
+ modal: true,
82
+ dialogClass: 'wp-dialog',
83
+ zIndex: 300000
84
+ });
85
+ }
86
+
87
+ inputs.dialog.wpdialog('open');
88
+ },
89
+
90
+ isMCE : function() {
91
+ return tinyMCEPopup && ( ed = tinyMCEPopup.editor ) && ! ed.isHidden();
92
+ },
93
+
94
+ refresh : function() {
95
+ // Refresh rivers (clear links, check visibility)
96
+ rivers.search.refresh();
97
+ rivers.recent.refresh();
98
+
99
+ if ( wpLink.isMCE() )
100
+ wpLink.mceRefresh();
101
+ else
102
+ wpLink.setDefaultValues();
103
+
104
+ // Focus the URL field and highlight its contents.
105
+ // If this is moved above the selection changes,
106
+ // IE will show a flashing cursor over the dialog.
107
+ inputs.url.focus()[0].select();
108
+ // Load the most recent results if this is the first time opening the panel.
109
+ if ( ! rivers.recent.ul.children().length )
110
+ rivers.recent.ajax();
111
+ },
112
+
113
+ mceRefresh : function() {
114
+ var e;
115
+ ed = tinyMCEPopup.editor;
116
+
117
+ tinyMCEPopup.restoreSelection();
118
+
119
+ // If link exists, select proper values.
120
+ if ( e = ed.dom.getParent(ed.selection.getNode(), 'A') ) {
121
+ // Set URL and description.
122
+ inputs.url.val( ed.dom.getAttrib(e, 'href') );
123
+ inputs.title.val( ed.dom.getAttrib(e, 'title') );
124
+ // Set open in new tab.
125
+ if ( "_blank" == ed.dom.getAttrib(e, 'target') )
126
+ inputs.openInNewTab.prop('checked', true);
127
+ // Set rel="nofollow" (mod)
128
+ if ( "nofollow" == ed.dom.getAttrib(e, 'rel' ) )
129
+ inputs.relNofollow.prop('checked', true);
130
+ // Update save prompt.
131
+ inputs.submit.val( wpLinkL10n.update );
132
+
133
+ // If there's no link, set the default values.
134
+ } else {
135
+ wpLink.setDefaultValues();
136
+ }
137
+
138
+ tinyMCEPopup.storeSelection();
139
+ },
140
+
141
+ close : function() {
142
+ if ( wpLink.isMCE() )
143
+ tinyMCEPopup.close();
144
+ else
145
+ inputs.dialog.wpdialog('close');
146
+ },
147
+
148
+ onClose: function() {
149
+ if ( ! wpLink.isMCE() ) {
150
+ wpLink.textarea.focus();
151
+ if ( wpLink.range ) {
152
+ wpLink.range.moveToBookmark( wpLink.range.getBookmark() );
153
+ wpLink.range.select();
154
+ }
155
+ }
156
+ },
157
+
158
+ getAttrs : function() {
159
+ return {
160
+ href : inputs.url.val(),
161
+ title : inputs.title.val(),
162
+ target : inputs.openInNewTab.prop('checked') ? '_blank' : '',
163
+ rel : inputs.relNofollow.prop('checked') ? 'nofollow' : '' // (mod)
164
+ };
165
+ },
166
+
167
+ update : function() {
168
+ if ( wpLink.isMCE() )
169
+ wpLink.mceUpdate();
170
+ else
171
+ wpLink.htmlUpdate();
172
+ },
173
+
174
+ htmlUpdate : function() {
175
+ var attrs, html, begin, end, cursor,
176
+ textarea = wpLink.textarea;
177
+
178
+ if ( ! textarea )
179
+ return;
180
+
181
+ attrs = wpLink.getAttrs();
182
+
183
+ // If there's no href, return.
184
+ if ( ! attrs.href || attrs.href == 'http://' )
185
+ return;
186
+
187
+ // Build HTML
188
+ html = '<a href="' + attrs.href + '"';
189
+
190
+ if ( attrs.title )
191
+ html += ' title="' + attrs.title + '"';
192
+ if ( attrs.target )
193
+ html += ' target="' + attrs.target + '"';
194
+ if( attrs.rel ) // (mod)
195
+ html += ' rel="' + attrs.rel + '"';
196
+
197
+ html += '>';
198
+
199
+ // Insert HTML
200
+ if ( document.selection && wpLink.range ) {
201
+ // IE
202
+ // Note: If no text is selected, IE will not place the cursor
203
+ // inside the closing tag.
204
+ textarea.focus();
205
+ wpLink.range.text = html + wpLink.range.text + '</a>';
206
+ wpLink.range.moveToBookmark( wpLink.range.getBookmark() );
207
+ wpLink.range.select();
208
+
209
+ wpLink.range = null;
210
+ } else if ( typeof textarea.selectionStart !== 'undefined' ) {
211
+ // W3C
212
+ begin = textarea.selectionStart;
213
+ end = textarea.selectionEnd;
214
+ selection = textarea.value.substring( begin, end );
215
+ html = html + selection + '</a>';
216
+ cursor = begin + html.length;
217
+
218
+ // If no next is selected, place the cursor inside the closing tag.
219
+ if ( begin == end )
220
+ cursor -= '</a>'.length;
221
+
222
+ textarea.value = textarea.value.substring( 0, begin )
223
+ + html
224
+ + textarea.value.substring( end, textarea.value.length );
225
+
226
+ // Update cursor position
227
+ textarea.selectionStart = textarea.selectionEnd = cursor;
228
+ }
229
+
230
+ wpLink.close();
231
+ textarea.focus();
232
+ },
233
+
234
+ mceUpdate : function() {
235
+ var ed = tinyMCEPopup.editor,
236
+ attrs = wpLink.getAttrs(),
237
+ e, b;
238
+
239
+ tinyMCEPopup.restoreSelection();
240
+ e = ed.dom.getParent(ed.selection.getNode(), 'A');
241
+
242
+ // If the values are empty, unlink and return
243
+ if ( ! attrs.href || attrs.href == 'http://' ) {
244
+ if ( e ) {
245
+ tinyMCEPopup.execCommand("mceBeginUndoLevel");
246
+ b = ed.selection.getBookmark();
247
+ ed.dom.remove(e, 1);
248
+ ed.selection.moveToBookmark(b);
249
+ tinyMCEPopup.execCommand("mceEndUndoLevel");
250
+ wpLink.close();
251
+ }
252
+ return;
253
+ }
254
+
255
+ tinyMCEPopup.execCommand("mceBeginUndoLevel");
256
+
257
+ if (e == null) {
258
+ ed.getDoc().execCommand("unlink", false, null);
259
+ tinyMCEPopup.execCommand("mceInsertLink", false, "#mce_temp_url#", {skip_undo : 1});
260
+
261
+ tinymce.each(ed.dom.select("a"), function(n) {
262
+ if (ed.dom.getAttrib(n, 'href') == '#mce_temp_url#') {
263
+ e = n;
264
+ ed.dom.setAttribs(e, attrs);
265
+ }
266
+ });
267
+
268
+ // Sometimes WebKit lets a user create a link where
269
+ // they shouldn't be able to. In this case, CreateLink
270
+ // injects "#mce_temp_url#" into their content. Fix it.
271
+ if ( $(e).text() == '#mce_temp_url#' ) {
272
+ ed.dom.remove(e);
273
+ e = null;
274
+ }
275
+ } else {
276
+ ed.dom.setAttribs(e, attrs);
277
+ }
278
+
279
+ // Don't move caret if selection was image
280
+ if ( e && (e.childNodes.length != 1 || e.firstChild.nodeName != 'IMG') ) {
281
+ ed.focus();
282
+ ed.selection.select(e);
283
+ ed.selection.collapse(0);
284
+ tinyMCEPopup.storeSelection();
285
+ }
286
+
287
+ tinyMCEPopup.execCommand("mceEndUndoLevel");
288
+ wpLink.close();
289
+ },
290
+
291
+ updateFields : function( e, li, originalEvent ) {
292
+ inputs.url.val( li.children('.item-permalink').val() );
293
+ inputs.title.val( li.hasClass('no-title') ? '' : li.children('.item-title').text() );
294
+ if ( originalEvent && originalEvent.type == "click" )
295
+ inputs.url.focus();
296
+ },
297
+ setDefaultValues : function() {
298
+ // Set URL and description to defaults.
299
+ // Leave the new tab setting as-is.
300
+ inputs.url.val('http://');
301
+ inputs.title.val('');
302
+
303
+ // Update save prompt.
304
+ inputs.submit.val( wpLinkL10n.save );
305
+ },
306
+
307
+ searchInternalLinks : function() {
308
+ var t = $(this), waiting,
309
+ search = t.val();
310
+
311
+ if ( search.length > 2 ) {
312
+ rivers.recent.hide();
313
+ rivers.search.show();
314
+
315
+ // Don't search if the keypress didn't change the title.
316
+ if ( wpLink.lastSearch == search )
317
+ return;
318
+
319
+ wpLink.lastSearch = search;
320
+ waiting = t.parent().find('.spinner').show();
321
+
322
+ rivers.search.change( search );
323
+ rivers.search.ajax( function(){ waiting.hide(); });
324
+ } else {
325
+ rivers.search.hide();
326
+ rivers.recent.show();
327
+ }
328
+ },
329
+
330
+ next : function() {
331
+ rivers.search.next();
332
+ rivers.recent.next();
333
+ },
334
+ prev : function() {
335
+ rivers.search.prev();
336
+ rivers.recent.prev();
337
+ },
338
+
339
+ keydown : function( event ) {
340
+ var fn, key = $.ui.keyCode;
341
+
342
+ switch( event.which ) {
343
+ case key.UP:
344
+ fn = 'prev';
345
+ case key.DOWN:
346
+ fn = fn || 'next';
347
+ clearInterval( wpLink.keyInterval );
348
+ wpLink[ fn ]();
349
+ wpLink.keyInterval = setInterval( wpLink[ fn ], wpLink.keySensitivity );
350
+ break;
351
+ default:
352
+ return;
353
+ }
354
+ event.preventDefault();
355
+ },
356
+ keyup: function( event ) {
357
+ var key = $.ui.keyCode;
358
+
359
+ switch( event.which ) {
360
+ case key.ESCAPE:
361
+ event.stopImmediatePropagation();
362
+ if ( ! $(document).triggerHandler( 'wp_CloseOnEscape', [{ event: event, what: 'wplink', cb: wpLink.close }] ) )
363
+ wpLink.close();
364
+
365
+ return false;
366
+ break;
367
+ case key.UP:
368
+ case key.DOWN:
369
+ clearInterval( wpLink.keyInterval );
370
+ break;
371
+ default:
372
+ return;
373
+ }
374
+ event.preventDefault();
375
+ },
376
+
377
+ delayedCallback : function( func, delay ) {
378
+ var timeoutTriggered, funcTriggered, funcArgs, funcContext;
379
+
380
+ if ( ! delay )
381
+ return func;
382
+
383
+ setTimeout( function() {
384
+ if ( funcTriggered )
385
+ return func.apply( funcContext, funcArgs );
386
+ // Otherwise, wait.
387
+ timeoutTriggered = true;
388
+ }, delay);
389
+
390
+ return function() {
391
+ if ( timeoutTriggered )
392
+ return func.apply( this, arguments );
393
+ // Otherwise, wait.
394
+ funcArgs = arguments;
395
+ funcContext = this;
396
+ funcTriggered = true;
397
+ };
398
+ },
399
+
400
+ toggleInternalLinking : function( event ) {
401
+ var panel = $('#search-panel'),
402
+ widget = inputs.dialog.wpdialog('widget'),
403
+ // We're about to toggle visibility; it's currently the opposite
404
+ visible = !panel.is(':visible'),
405
+ win = $(window);
406
+
407
+ $(this).toggleClass('toggle-arrow-active', visible);
408
+
409
+ inputs.dialog.height('auto');
410
+ panel.slideToggle( 300, function() {
411
+ setUserSetting('wplink', visible ? '1' : '0');
412
+ inputs[ visible ? 'search' : 'url' ].focus();
413
+
414
+ // Move the box if the box is now expanded, was opened in a collapsed state,
415
+ // and if it needs to be moved. (Judged by bottom not being positive or
416
+ // bottom being smaller than top.)
417
+ var scroll = win.scrollTop(),
418
+ top = widget.offset().top,
419
+ bottom = top + widget.outerHeight(),
420
+ diff = bottom - win.height();
421
+
422
+ if ( diff > scroll ) {
423
+ widget.animate({'top': diff < top ? top - diff : scroll }, 200);
424
+ }
425
+ });
426
+ event.preventDefault();
427
+ }
428
+ }
429
+
430
+ River = function( element, search ) {
431
+ var self = this;
432
+ this.element = element;
433
+ this.ul = element.children('ul');
434
+ this.waiting = element.find('.river-waiting');
435
+
436
+ this.change( search );
437
+ this.refresh();
438
+
439
+ element.scroll( function(){ self.maybeLoad(); });
440
+ element.delegate('li', 'click', function(e){ self.select( $(this), e ); });
441
+ };
442
+
443
+ $.extend( River.prototype, {
444
+ refresh: function() {
445
+ this.deselect();
446
+ this.visible = this.element.is(':visible');
447
+ },
448
+ show: function() {
449
+ if ( ! this.visible ) {
450
+ this.deselect();
451
+ this.element.show();
452
+ this.visible = true;
453
+ }
454
+ },
455
+ hide: function() {
456
+ this.element.hide();
457
+ this.visible = false;
458
+ },
459
+ // Selects a list item and triggers the river-select event.
460
+ select: function( li, event ) {
461
+ var liHeight, elHeight, liTop, elTop;
462
+
463
+ if ( li.hasClass('unselectable') || li == this.selected )
464
+ return;
465
+
466
+ this.deselect();
467
+ this.selected = li.addClass('selected');
468
+ // Make sure the element is visible
469
+ liHeight = li.outerHeight();
470
+ elHeight = this.element.height();
471
+ liTop = li.position().top;
472
+ elTop = this.element.scrollTop();
473
+
474
+ if ( liTop < 0 ) // Make first visible element
475
+ this.element.scrollTop( elTop + liTop );
476
+ else if ( liTop + liHeight > elHeight ) // Make last visible element
477
+ this.element.scrollTop( elTop + liTop - elHeight + liHeight );
478
+
479
+ // Trigger the river-select event
480
+ this.element.trigger('river-select', [ li, event, this ]);
481
+ },
482
+ deselect: function() {
483
+ if ( this.selected )
484
+ this.selected.removeClass('selected');
485
+ this.selected = false;
486
+ },
487
+ prev: function() {
488
+ if ( ! this.visible )
489
+ return;
490
+
491
+ var to;
492
+ if ( this.selected ) {
493
+ to = this.selected.prev('li');
494
+ if ( to.length )
495
+ this.select( to );
496
+ }
497
+ },
498
+ next: function() {
499
+ if ( ! this.visible )
500
+ return;
501
+
502
+ var to = this.selected ? this.selected.next('li') : $('li:not(.unselectable):first', this.element);
503
+ if ( to.length )
504
+ this.select( to );
505
+ },
506
+ ajax: function( callback ) {
507
+ var self = this,
508
+ delay = this.query.page == 1 ? 0 : wpLink.minRiverAJAXDuration,
509
+ response = wpLink.delayedCallback( function( results, params ) {
510
+ self.process( results, params );
511
+ if ( callback )
512
+ callback( results, params );
513
+ }, delay );
514
+
515
+ this.query.ajax( response );
516
+ },
517
+ change: function( search ) {
518
+ if ( this.query && this._search == search )
519
+ return;
520
+
521
+ this._search = search;
522
+ this.query = new Query( search );
523
+ this.element.scrollTop(0);
524
+ },
525
+ process: function( results, params ) {
526
+ var list = '', alt = true, classes = '',
527
+ firstPage = params.page == 1;
528
+
529
+ if ( !results ) {
530
+ if ( firstPage ) {
531
+ list += '<li class="unselectable"><span class="item-title"><em>'
532
+ + wpLinkL10n.noMatchesFound
533
+ + '</em></span></li>';
534
+ }
535
+ } else {
536
+ $.each( results, function() {
537
+ classes = alt ? 'alternate' : '';
538
+ classes += this['title'] ? '' : ' no-title';
539
+ list += classes ? '<li class="' + classes + '">' : '<li>';
540
+ list += '<input type="hidden" class="item-permalink" value="' + this['permalink'] + '" />';
541
+ list += '<span class="item-title">';
542
+ list += this['title'] ? this['title'] : wpLinkL10n.noTitle;
543
+ list += '</span><span class="item-info">' + this['info'] + '</span></li>';
544
+ alt = ! alt;
545
+ });
546
+ }
547
+
548
+ this.ul[ firstPage ? 'html' : 'append' ]( list );
549
+ },
550
+ maybeLoad: function() {
551
+ var self = this,
552
+ el = this.element,
553
+ bottom = el.scrollTop() + el.height();
554
+
555
+ if ( ! this.query.ready() || bottom < this.ul.height() - wpLink.riverBottomThreshold )
556
+ return;
557
+
558
+ setTimeout(function() {
559
+ var newTop = el.scrollTop(),
560
+ newBottom = newTop + el.height();
561
+
562
+ if ( ! self.query.ready() || newBottom < self.ul.height() - wpLink.riverBottomThreshold )
563
+ return;
564
+
565
+ self.waiting.show();
566
+ el.scrollTop( newTop + self.waiting.outerHeight() );
567
+
568
+ self.ajax( function() { self.waiting.hide(); });
569
+ }, wpLink.timeToTriggerRiver );
570
+ }
571
+ });
572
+
573
+ Query = function( search ) {
574
+ this.page = 1;
575
+ this.allLoaded = false;
576
+ this.querying = false;
577
+ this.search = search;
578
+ };
579
+
580
+ $.extend( Query.prototype, {
581
+ ready: function() {
582
+ return !( this.querying || this.allLoaded );
583
+ },
584
+ ajax: function( callback ) {
585
+ var self = this,
586
+ query = {
587
+ action : 'wp-link-ajax',
588
+ page : this.page,
589
+ '_ajax_linking_nonce' : inputs.nonce.val()
590
+ };
591
+
592
+ if ( this.search )
593
+ query.search = this.search;
594
+
595
+ this.querying = true;
596
+
597
+ $.post( ajaxurl, query, function(r) {
598
+ self.page++;
599
+ self.querying = false;
600
+ self.allLoaded = !r;
601
+ callback( r, query );
602
+ }, "json" );
603
+ }
604
+ });
605
+ $(document).ready( wpLink.append ); // (mod)
606
+ $(document).ready( wpLink.init );
607
+
608
+ })(jQuery);
wplink.min.js ADDED
@@ -0,0 +1 @@
 
1
+ var wpLink;(function(e){var t={},n={},r,i,s;wpLink={timeToTriggerRiver:150,minRiverAJAXDuration:200,riverBottomThreshold:5,keySensitivity:100,lastSearch:"",textarea:"",append:function(){var t='<br /><label><input type="checkbox" id="link-nofollow-checkbox" /> Add <code>rel="nofollow"</code> to link</label>';e("#wp-link .link-target").append(t)},init:function(){t.dialog=e("#wp-link");t.submit=e("#wp-link-submit");t.url=e("#url-field");t.nonce=e("#_ajax_linking_nonce");t.title=e("#link-title-field");t.openInNewTab=e("#link-target-checkbox");t.relNofollow=e("#link-nofollow-checkbox");t.search=e("#search-field");n.search=new i(e("#search-results"));n.recent=new i(e("#most-recent-results"));n.elements=e(".query-results",t.dialog);t.dialog.keydown(wpLink.keydown);t.dialog.keyup(wpLink.keyup);t.submit.click(function(e){e.preventDefault();wpLink.update()});e("#wp-link-cancel").click(function(e){e.preventDefault();wpLink.close()});e("#internal-toggle").click(wpLink.toggleInternalLinking);n.elements.bind("river-select",wpLink.updateFields);t.search.keyup(wpLink.searchInternalLinks);t.dialog.bind("wpdialogrefresh",wpLink.refresh);t.dialog.bind("wpdialogbeforeopen",wpLink.beforeOpen);t.dialog.bind("wpdialogclose",wpLink.onClose)},beforeOpen:function(){wpLink.range=null;if(!wpLink.isMCE()&&document.selection){wpLink.textarea.focus();wpLink.range=document.selection.createRange()}},open:function(){if(!wpActiveEditor)return;this.textarea=e("#"+wpActiveEditor).get(0);if(!t.dialog.data("wpdialog")){t.dialog.wpdialog({title:wpLinkL10n.title,width:480,height:"auto",modal:true,dialogClass:"wp-dialog",zIndex:3e5})}t.dialog.wpdialog("open")},isMCE:function(){return tinyMCEPopup&&(r=tinyMCEPopup.editor)&&!r.isHidden()},refresh:function(){n.search.refresh();n.recent.refresh();if(wpLink.isMCE())wpLink.mceRefresh();else wpLink.setDefaultValues();t.url.focus()[0].select();if(!n.recent.ul.children().length)n.recent.ajax()},mceRefresh:function(){var e;r=tinyMCEPopup.editor;tinyMCEPopup.restoreSelection();if(e=r.dom.getParent(r.selection.getNode(),"A")){t.url.val(r.dom.getAttrib(e,"href"));t.title.val(r.dom.getAttrib(e,"title"));if("_blank"==r.dom.getAttrib(e,"target"))t.openInNewTab.prop("checked",true);if("nofollow"==r.dom.getAttrib(e,"rel"))t.relNofollow.prop("checked",true);t.submit.val(wpLinkL10n.update)}else{wpLink.setDefaultValues()}tinyMCEPopup.storeSelection()},close:function(){if(wpLink.isMCE())tinyMCEPopup.close();else t.dialog.wpdialog("close")},onClose:function(){if(!wpLink.isMCE()){wpLink.textarea.focus();if(wpLink.range){wpLink.range.moveToBookmark(wpLink.range.getBookmark());wpLink.range.select()}}},getAttrs:function(){return{href:t.url.val(),title:t.title.val(),target:t.openInNewTab.prop("checked")?"_blank":"",rel:t.relNofollow.prop("checked")?"nofollow":""}},update:function(){if(wpLink.isMCE())wpLink.mceUpdate();else wpLink.htmlUpdate()},htmlUpdate:function(){var e,t,n,r,i,s=wpLink.textarea;if(!s)return;e=wpLink.getAttrs();if(!e.href||e.href=="http://")return;t='<a href="'+e.href+'"';if(e.title)t+=' title="'+e.title+'"';if(e.target)t+=' target="'+e.target+'"';if(e.rel)t+=' rel="'+e.rel+'"';t+=">";if(document.selection&&wpLink.range){s.focus();wpLink.range.text=t+wpLink.range.text+"</a>";wpLink.range.moveToBookmark(wpLink.range.getBookmark());wpLink.range.select();wpLink.range=null}else if(typeof s.selectionStart!=="undefined"){n=s.selectionStart;r=s.selectionEnd;selection=s.value.substring(n,r);t=t+selection+"</a>";i=n+t.length;if(n==r)i-="</a>".length;s.value=s.value.substring(0,n)+t+s.value.substring(r,s.value.length);s.selectionStart=s.selectionEnd=i}wpLink.close();s.focus()},mceUpdate:function(){var t=tinyMCEPopup.editor,n=wpLink.getAttrs(),r,i;tinyMCEPopup.restoreSelection();r=t.dom.getParent(t.selection.getNode(),"A");if(!n.href||n.href=="http://"){if(r){tinyMCEPopup.execCommand("mceBeginUndoLevel");i=t.selection.getBookmark();t.dom.remove(r,1);t.selection.moveToBookmark(i);tinyMCEPopup.execCommand("mceEndUndoLevel");wpLink.close()}return}tinyMCEPopup.execCommand("mceBeginUndoLevel");if(r==null){t.getDoc().execCommand("unlink",false,null);tinyMCEPopup.execCommand("mceInsertLink",false,"#mce_temp_url#",{skip_undo:1});tinymce.each(t.dom.select("a"),function(e){if(t.dom.getAttrib(e,"href")=="#mce_temp_url#"){r=e;t.dom.setAttribs(r,n)}});if(e(r).text()=="#mce_temp_url#"){t.dom.remove(r);r=null}}else{t.dom.setAttribs(r,n)}if(r&&(r.childNodes.length!=1||r.firstChild.nodeName!="IMG")){t.focus();t.selection.select(r);t.selection.collapse(0);tinyMCEPopup.storeSelection()}tinyMCEPopup.execCommand("mceEndUndoLevel");wpLink.close()},updateFields:function(e,n,r){t.url.val(n.children(".item-permalink").val());t.title.val(n.hasClass("no-title")?"":n.children(".item-title").text());if(r&&r.type=="click")t.url.focus()},setDefaultValues:function(){t.url.val("http://");t.title.val("");t.submit.val(wpLinkL10n.save)},searchInternalLinks:function(){var t=e(this),r,i=t.val();if(i.length>2){n.recent.hide();n.search.show();if(wpLink.lastSearch==i)return;wpLink.lastSearch=i;r=t.parent().find(".spinner").show();n.search.change(i);n.search.ajax(function(){r.hide()})}else{n.search.hide();n.recent.show()}},next:function(){n.search.next();n.recent.next()},prev:function(){n.search.prev();n.recent.prev()},keydown:function(t){var n,r=e.ui.keyCode;switch(t.which){case r.UP:n="prev";case r.DOWN:n=n||"next";clearInterval(wpLink.keyInterval);wpLink[n]();wpLink.keyInterval=setInterval(wpLink[n],wpLink.keySensitivity);break;default:return}t.preventDefault()},keyup:function(t){var n=e.ui.keyCode;switch(t.which){case n.ESCAPE:t.stopImmediatePropagation();if(!e(document).triggerHandler("wp_CloseOnEscape",[{event:t,what:"wplink",cb:wpLink.close}]))wpLink.close();return false;break;case n.UP:case n.DOWN:clearInterval(wpLink.keyInterval);break;default:return}t.preventDefault()},delayedCallback:function(e,t){var n,r,i,s;if(!t)return e;setTimeout(function(){if(r)return e.apply(s,i);n=true},t);return function(){if(n)return e.apply(this,arguments);i=arguments;s=this;r=true}},toggleInternalLinking:function(n){var r=e("#search-panel"),i=t.dialog.wpdialog("widget"),s=!r.is(":visible"),o=e(window);e(this).toggleClass("toggle-arrow-active",s);t.dialog.height("auto");r.slideToggle(300,function(){setUserSetting("wplink",s?"1":"0");t[s?"search":"url"].focus();var e=o.scrollTop(),n=i.offset().top,r=n+i.outerHeight(),u=r-o.height();if(u>e){i.animate({top:u<n?n-u:e},200)}});n.preventDefault()}};i=function(t,n){var r=this;this.element=t;this.ul=t.children("ul");this.waiting=t.find(".river-waiting");this.change(n);this.refresh();t.scroll(function(){r.maybeLoad()});t.delegate("li","click",function(t){r.select(e(this),t)})};e.extend(i.prototype,{refresh:function(){this.deselect();this.visible=this.element.is(":visible")},show:function(){if(!this.visible){this.deselect();this.element.show();this.visible=true}},hide:function(){this.element.hide();this.visible=false},select:function(e,t){var n,r,i,s;if(e.hasClass("unselectable")||e==this.selected)return;this.deselect();this.selected=e.addClass("selected");n=e.outerHeight();r=this.element.height();i=e.position().top;s=this.element.scrollTop();if(i<0)this.element.scrollTop(s+i);else if(i+n>r)this.element.scrollTop(s+i-r+n);this.element.trigger("river-select",[e,t,this])},deselect:function(){if(this.selected)this.selected.removeClass("selected");this.selected=false},prev:function(){if(!this.visible)return;var e;if(this.selected){e=this.selected.prev("li");if(e.length)this.select(e)}},next:function(){if(!this.visible)return;var t=this.selected?this.selected.next("li"):e("li:not(.unselectable):first",this.element);if(t.length)this.select(t)},ajax:function(e){var t=this,n=this.query.page==1?0:wpLink.minRiverAJAXDuration,r=wpLink.delayedCallback(function(n,r){t.process(n,r);if(e)e(n,r)},n);this.query.ajax(r)},change:function(e){if(this.query&&this._search==e)return;this._search=e;this.query=new s(e);this.element.scrollTop(0)},process:function(t,n){var r="",i=true,s="",o=n.page==1;if(!t){if(o){r+='<li class="unselectable"><span class="item-title"><em>'+wpLinkL10n.noMatchesFound+"</em></span></li>"}}else{e.each(t,function(){s=i?"alternate":"";s+=this["title"]?"":" no-title";r+=s?'<li class="'+s+'">':"<li>";r+='<input type="hidden" class="item-permalink" value="'+this["permalink"]+'" />';r+='<span class="item-title">';r+=this["title"]?this["title"]:wpLinkL10n.noTitle;r+='</span><span class="item-info">'+this["info"]+"</span></li>";i=!i})}this.ul[o?"html":"append"](r)},maybeLoad:function(){var e=this,t=this.element,n=t.scrollTop()+t.height();if(!this.query.ready()||n<this.ul.height()-wpLink.riverBottomThreshold)return;setTimeout(function(){var n=t.scrollTop(),r=n+t.height();if(!e.query.ready()||r<e.ul.height()-wpLink.riverBottomThreshold)return;e.waiting.show();t.scrollTop(n+e.waiting.outerHeight());e.ajax(function(){e.waiting.hide()})},wpLink.timeToTriggerRiver)}});s=function(e){this.page=1;this.allLoaded=false;this.querying=false;this.search=e};e.extend(s.prototype,{ready:function(){return!(this.querying||this.allLoaded)},ajax:function(n){var r=this,i={action:"wp-link-ajax",page:this.page,_ajax_linking_nonce:t.nonce.val()};if(this.search)i.search=this.search;this.querying=true;e.post(ajaxurl,i,function(e){r.page++;r.querying=false;r.allLoaded=!e;n(e,i)},"json")}});e(document).ready(wpLink.append);e(document).ready(wpLink.init)})(jQuery)