PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 7.0.3
Jetpack – WP Security, Backup, Speed, & Growth v7.0.3
15.9-a.7 15.9-a.5 15.9-a.3 15.9-a.1 15.8 15.8-beta 15.8-a.7 15.8-a.5 5.2.5 5.3.4 5.4.4 5.5.5 5.6.5 5.7.5 5.8.4 5.9.4 6.0.4 6.1 6.1.1 6.1.2 6.1.3 6.1.4 6.1.5 6.2 6.2.1 6.2.2 6.2.3 6.2.4 6.2.5 6.3 6.3.1 6.3.2 6.3.3 6.3.4 6.3.5 6.3.6 6.3.7 6.4 6.4.1 6.4.2 6.4.3 6.4.4 6.4.5 6.4.6 6.5 6.5.1 6.5.2 6.5.3 6.5.4 6.6 6.6.1 6.6.2 6.6.3 6.6.4 6.6.5 6.7 6.7.1 6.7.2 6.7.3 6.7.4 6.8 6.8.1 6.8.2 6.8.3 6.8.4 6.8.5 6.9 6.9.1 6.9.2 6.9.3 6.9.4 7.0 7.0.1 7.0.2 7.0.3 7.0.4 7.0.5 7.1 7.1.1 7.1.2 7.1.3 7.1.4 7.1.5 7.2 7.2.1 7.2.1.1 7.2.2 7.2.3 7.2.4 7.2.5 7.3 7.3.0.1 7.3.1 7.3.1.1 7.3.2 7.3.3 7.3.4 7.3.5 7.4 7.4.1 7.4.2 7.4.3 7.4.4 7.4.5 7.5 7.5.0.1 7.5.1 7.5.2 7.5.3 7.5.4 7.5.5 7.5.6 7.5.7 7.6 7.6.1 7.6.2 7.6.3 7.6.4 7.7 7.7.1 7.7.2 7.7.3 7.7.4 7.7.5 7.7.6 7.8 7.8.1 7.8.2 7.8.3 7.8.4 7.9 7.9.1 7.9.2 7.9.3 7.9.4 8.0 8.0.1 8.0.2 8.0.3 8.1 8.1.1 8.1.2 8.1.3 8.1.4 8.2 8.2.0.1 8.2.1 8.2.2 8.2.3 8.2.4 8.2.5 8.2.6 8.3 8.3.1 8.3.2 8.3.3 8.4 8.4.1 8.4.2 8.4.3 8.4.4 8.4.5 8.5 8.5.1 8.5.2 8.5.3 8.6 8.6.1 8.6.2 8.6.3 8.6.4 8.7 8.7.0.1 8.7.1 8.7.2 8.7.3 8.7.4 8.8 8.8.1 8.8.2 8.8.3 8.8.4 8.8.5 8.9 8.9.1 8.9.2 8.9.3 8.9.4 9.0 9.0.1 9.0.2 9.0.3 9.0.4 9.0.5 9.1 9.1.1 9.1.2 9.1.3 9.2 9.2.1 9.2.2 9.2.3 9.2.4 9.3 9.3.1 9.3.2 9.3.3 9.3.4 9.3.5 9.4 9.4.1 9.4.2 9.4.3 9.4.4 9.5 9.5.1 9.5.2 9.5.3 9.5.4 9.5.5 9.6 9.6.1 9.6.2 9.6.3 9.6.4 9.7 9.7.1 9.7.2 15.7-beta.2 9.7.3 15.7.1 9.8 15.8-a.1 9.8.1 15.8-a.3 9.8.2 2.0.9 9.8.3 2.1.7 9.9 2.2.10 9.9.1 2.3.10 9.9.2 2.4.7 9.9.3 2.5.5 2.6.6 2.7.5 2.8.5 2.9.6 3.0.6 3.1.5 3.2.5 3.3.6 3.4.6 3.5.6 3.6.4 3.7.5 3.8.5 3.9.10 4.0.7 4.1.4 4.2.5 4.3.5 4.4.5 4.5.3 4.6.3 4.7.4 4.8.5 4.9.3 5.0.3 5.1.4 trunk 10.0 10.0.1 10.0.2 10.1 10.1.1 10.1.2 10.2 10.2.1 10.2.2 10.2.3 10.3 10.3.1 10.3.2 10.4 10.4.1 10.4.2 10.5 10.5.1 10.5.2 10.5.3 10.6 10.6.1 10.6.2 10.7 10.7.1 10.7.2 10.8 10.8.1 10.8.2 10.9 10.9.1 10.9.2 10.9.3 11.0 11.0.1 11.0.2 11.1 11.1.1 11.1.2 11.1.3 11.1.4 11.2 11.2.1 11.2.2 11.3 11.3.1 11.3.2 11.3.3 11.3.4 11.4 11.4.1 11.4.2 11.5 11.5.1 11.5.2 11.5.3 11.6 11.6.1 11.6.2 11.7 11.7.1 11.7.2 11.7.3 11.8 11.8.3 11.8.4 11.8.5 11.8.6 11.9 11.9.1 11.9.2 11.9.3 12.0 12.0.1 12.0.2 12.1 12.1.1 12.1.2 12.2 12.2.1 12.2.2 12.3 12.3.1 12.4 12.4.1 12.5 12.5.1 12.6 12.6.1 12.6.2 12.6.3 12.7 12.7.1 12.7.2 12.8 12.8.1 12.8.2 12.9 12.9.1 12.9.2 12.9.3 12.9.4 13.0 13.0.1 13.1 13.1.1 13.1.2 13.1.3 13.1.4 13.2 13.2.1 13.2.2 13.2.3 13.3 13.3.1 13.3.2 13.4 13.4.1 13.4.2 13.4.3 13.4.4 13.5 13.5.1 13.6 13.6.1 13.7 13.7.1 13.8 13.8.1 13.8.2 13.9 13.9.1 14.0 14.1 14.2 14.2.1 14.3 14.4 14.4.1 14.5 14.6 14.7 14.8 14.9 14.9.1 15.0 15.0.1 15.0.2 15.1 15.1.1 15.2 15.3 15.3.1 15.4 15.5 15.6 15.7 15.7-a.1 15.7-a.3 15.7-a.5 15.7-a.7 15.7-beta
jetpack / modules / after-the-deadline / jquery.atd.js
jetpack / modules / after-the-deadline Last commit date
rtl 10 years ago tinymce 7 years ago atd-autoproofread.js 10 years ago atd-nonvis-editor-plugin.js 9 years ago atd-rtl.css 9 years ago atd-rtl.min.css 9 years ago atd.core.js 9 years ago atd.css 9 years ago atd.min.css 9 years ago button.gif 15 years ago config-options.php 7 years ago config-unignore.php 7 years ago jquery.atd.js 7 years ago proxy.php 7 years ago
jquery.atd.js
437 lines
1 /*
2 * jquery.atd.js - jQuery powered writing check with After the Deadline
3 * Author : Raphael Mudge, Automattic Inc.
4 * License : LGPL or MIT License (take your pick)
5 * Project : http://www.afterthedeadline.com/development.slp
6 * Contact : raffi@automattic.com
7 *
8 * Derived from:
9 *
10 * jquery.spellchecker.js - a simple jQuery Spell Checker
11 * Copyright (c) 2008 Richard Willis
12 * MIT license : http://www.opensource.org/licenses/mit-license.php
13 * Project : http://jquery-spellchecker.googlecode.com
14 * Contact : willis.rh@gmail.com
15 */
16
17 /* jshint onevar: false, sub: true, smarttabs: true, loopfunc: true */
18 /* global AtDCore, AtD_proofread_click_count:true, CSSHttpRequest, ActiveXObject */
19
20 var AtD =
21 {
22 rpc : '', /* see the proxy.php that came with the AtD/TinyMCE plugin */
23 rpc_css : 'http://www.polishmywriting.com/atd-jquery/server/proxycss.php?data=', /* you may use this, but be nice! */
24 rpc_css_lang : 'en',
25 api_key : '',
26 i18n : {}, // Back-compat
27 listener : {}
28 };
29
30 AtD.getLang = function( key, defaultk ) {
31 return ( window.AtD_l10n_r0ar && window.AtD_l10n_r0ar[key] ) || defaultk;
32 };
33
34 AtD.addI18n = function( obj ) {
35 // Back-compat
36 window.AtD_l10n_r0ar = obj;
37 };
38
39 AtD.setIgnoreStrings = function(string) {
40 AtD.core.setIgnoreStrings(string);
41 };
42
43 AtD.showTypes = function(string) {
44 AtD.core.showTypes(string);
45 };
46
47 AtD.checkCrossAJAX = function(container_id, callback_f) {
48 /* checks if a global var for click stats exists and increments it if it does... */
49 if (typeof AtD_proofread_click_count !== 'undefined') {
50 AtD_proofread_click_count++;
51 }
52
53 AtD.callback_f = callback_f; /* remember the callback for later */
54 AtD.remove(container_id);
55 var container = jQuery('#' + container_id);
56
57 var text = jQuery.trim(container.html());
58 text = text.replace(/\&lt;/g, '<').replace(/\&gt;/g, '>').replace(/\&amp;/g, '&');
59 text = encodeURIComponent( text.replace( /\%/g, '%25' ) ); /* % not being escaped here creates problems, I don't know why. */
60
61 /* do some sanity checks based on the browser */
62 if ((text.length > 2000 && navigator.appName === 'Microsoft Internet Explorer') || text.length > 7800) {
63 if (callback_f !== undefined && callback_f.error !== undefined) {
64 callback_f.error('Maximum text length for this browser exceeded');
65 }
66
67 return;
68 }
69
70 /* do some cross-domain AJAX action with CSSHttpRequest */
71 CSSHttpRequest.get(AtD.rpc_css + text + '&lang=' + AtD.rpc_css_lang + '&nocache=' + (new Date().getTime()), function(response) {
72 /* do some magic to convert the response into an XML document */
73 var xml;
74 if (navigator.appName === 'Microsoft Internet Explorer') {
75 xml = new ActiveXObject('Microsoft.XMLDOM');
76 xml.async = false;
77 xml.loadXML(response);
78 } else {
79 xml = (new DOMParser()).parseFromString(response, 'text/xml');
80 }
81
82 /* check for and display error messages from the server */
83 if (AtD.core.hasErrorMessage(xml)) {
84 if (AtD.callback_f !== undefined && AtD.callback_f.error !== undefined) {
85 AtD.callback_f.error(AtD.core.getErrorMessage(xml));
86 }
87
88 return;
89 }
90
91 /* highlight the errors */
92
93 AtD.container = container_id;
94 var count = Number( AtD.processXML(container_id, xml) );
95
96 if (AtD.callback_f !== undefined && AtD.callback_f.ready !== undefined) {
97 AtD.callback_f.ready(count);
98 }
99
100 if (count === 0 && AtD.callback_f !== undefined && AtD.callback_f.success !== undefined) {
101 AtD.callback_f.success(count);
102 }
103
104 AtD.counter = count;
105 AtD.count = count;
106 });
107 };
108
109 /* check a div for any incorrectly spelled words */
110 AtD.check = function(container_id, callback_f) {
111 /* checks if a global var for click stats exists and increments it if it does... */
112 if (typeof AtD_proofread_click_count !== 'undefined') {
113 AtD_proofread_click_count++;
114 }
115
116 AtD.callback_f = callback_f; /* remember the callback for later */
117
118 AtD.remove(container_id);
119
120 var container = jQuery('#' + container_id);
121
122 var text = jQuery.trim(container.html());
123 text = text.replace(/\&lt;/g, '<').replace(/\&gt;/g, '>').replace(/\&amp;/g, '&');
124 text = encodeURIComponent( text ); /* re-escaping % is not necessary here. don't do it */
125
126 jQuery.ajax({
127 type : 'POST',
128 url : AtD.rpc + '/checkDocument',
129 data : 'key=' + AtD.api_key + '&data=' + text,
130 format : 'raw',
131 dataType : (jQuery.browser.msie) ? 'text' : 'xml',
132
133 error : function(XHR, status, error) {
134 if (AtD.callback_f !== undefined && AtD.callback_f.error !== undefined) {
135 AtD.callback_f.error(status + ': ' + error);
136 }
137 },
138
139 success : function(data) {
140 /* apparently IE likes to return XML as plain text-- work around from:
141 http://docs.jquery.com/Specifying_the_Data_Type_for_AJAX_Requests */
142
143 var xml;
144 if (typeof data === 'string') {
145 xml = new ActiveXObject('Microsoft.XMLDOM');
146 xml.async = false;
147 xml.loadXML(data);
148 }
149 else {
150 xml = data;
151 }
152
153 if (AtD.core.hasErrorMessage(xml)) {
154 if (AtD.callback_f !== undefined && AtD.callback_f.error !== undefined) {
155 AtD.callback_f.error(AtD.core.getErrorMessage(xml));
156 }
157
158 return;
159 }
160
161 /* on with the task of processing and highlighting errors */
162
163 AtD.container = container_id;
164 var count = Number( AtD.processXML(container_id, xml) );
165
166 if (AtD.callback_f !== undefined && AtD.callback_f.ready !== undefined) {
167 AtD.callback_f.ready(count);
168 }
169
170 if (count === 0 && AtD.callback_f !== undefined && AtD.callback_f.success !== undefined) {
171 AtD.callback_f.success(count);
172 }
173
174 AtD.counter = count;
175 AtD.count = count;
176 }
177 });
178 };
179
180 AtD.remove = function(container_id) {
181 AtD._removeWords(container_id, null);
182 };
183
184 AtD.clickListener = function(event) {
185 if (AtD.core.isMarkedNode(event.target)) {
186 AtD.suggest(event.target);
187 }
188 };
189
190 AtD.processXML = function(container_id, responseXML) {
191
192 var results = AtD.core.processXML(responseXML);
193
194 if (results.count > 0) {
195 results.count = AtD.core.markMyWords(jQuery('#' + container_id).contents(), results.errors);
196 }
197
198 jQuery('#' + container_id).unbind('click', AtD.clickListener);
199 jQuery('#' + container_id).click(AtD.clickListener);
200
201 return results.count;
202 };
203
204 AtD.useSuggestion = function(word) {
205 this.core.applySuggestion(AtD.errorElement, word);
206
207 AtD.counter --;
208 if (AtD.counter === 0 && AtD.callback_f !== undefined && AtD.callback_f.success !== undefined) {
209 AtD.callback_f.success(AtD.count);
210 }
211 };
212
213 AtD.editSelection = function() {
214 var parent = AtD.errorElement.parent();
215
216 if (AtD.callback_f !== undefined && AtD.callback_f.editSelection !== undefined) {
217 AtD.callback_f.editSelection(AtD.errorElement);
218 }
219
220 if (AtD.errorElement.parent() !== parent) {
221 AtD.counter --;
222 if (AtD.counter === 0 && AtD.callback_f !== undefined && AtD.callback_f.success !== undefined) {
223 AtD.callback_f.success(AtD.count);
224 }
225 }
226 };
227
228 AtD.ignoreSuggestion = function() {
229 AtD.core.removeParent(AtD.errorElement);
230
231 AtD.counter --;
232 if (AtD.counter === 0 && AtD.callback_f !== undefined && AtD.callback_f.success !== undefined) {
233 AtD.callback_f.success(AtD.count);
234 }
235 };
236
237 AtD.ignoreAll = function(container_id) {
238 var target = AtD.errorElement.text();
239 var removed = AtD._removeWords(container_id, target);
240
241 AtD.counter -= removed;
242
243 if (AtD.counter === 0 && AtD.callback_f !== undefined && AtD.callback_f.success !== undefined) {
244 AtD.callback_f.success(AtD.count);
245 }
246
247 if (AtD.callback_f !== undefined && AtD.callback_f.ignore !== undefined) {
248 AtD.callback_f.ignore(target);
249 AtD.core.setIgnoreStrings(target);
250 }
251 };
252
253 AtD.explainError = function() {
254 if (AtD.callback_f !== undefined && AtD.callback_f.explain !== undefined) {
255 AtD.callback_f.explain(AtD.explainURL);
256 }
257 };
258
259 AtD.suggest = function(element) {
260 /* construct the menu if it doesn't already exist */
261 var suggest;
262
263 if (jQuery('#suggestmenu').length === 0) {
264 suggest = jQuery('<div id="suggestmenu"></div>');
265 suggest.prependTo('body');
266 } else {
267 suggest = jQuery('#suggestmenu');
268 suggest.hide();
269 }
270
271 /* find the correct suggestions object */
272
273 var errorDescription = AtD.core.findSuggestion(element);
274
275 /* build up the menu y0 */
276
277 AtD.errorElement = jQuery(element);
278
279 suggest.empty();
280
281 if (errorDescription === undefined) {
282 suggest.append('<strong>' + AtD.getLang('menu_title_no_suggestions', 'No suggestions') + '</strong>');
283 } else if (errorDescription['suggestions'].length === 0) {
284 suggest.append('<strong>' + errorDescription['description'] + '</strong>');
285 } else {
286 suggest.append('<strong>' + errorDescription['description'] + '</strong>');
287
288 for (var i = 0; i < errorDescription['suggestions'].length; i++) {
289 (function(sugg) {
290 suggest.append('<a href="javascript:AtD.useSuggestion(\'' + sugg.replace(/'/, '\\\'') + '\')">' + sugg + '</a>');
291 })(errorDescription['suggestions'][i]); // jshint ignore:line
292 }
293 }
294
295 /* do the explain menu if configured */
296
297 if (AtD.callback_f !== undefined && AtD.callback_f.explain !== undefined && errorDescription['moreinfo'] !== undefined) {
298 suggest.append('<a href="javascript:AtD.explainError()" class="spell_sep_top">' + AtD.getLang('menu_option_explain', 'Explain...') + '</a>');
299 AtD.explainURL = errorDescription['moreinfo'];
300 }
301
302 /* do the ignore option */
303
304 suggest.append('<a href="javascript:AtD.ignoreSuggestion()" class="spell_sep_top">' + AtD.getLang('menu_option_ignore_once', 'Ignore suggestion') + '</a>');
305
306 /* add the edit in place and ignore always option */
307
308 if (AtD.callback_f !== undefined && AtD.callback_f.editSelection !== undefined) {
309 if (AtD.callback_f !== undefined && AtD.callback_f.ignore !== undefined) {
310 suggest.append('<a href="javascript:AtD.ignoreAll(\'' + AtD.container + '\')">' + AtD.getLang('menu_option_ignore_always', 'Ignore always') + '</a>');
311 } else {
312 suggest.append('<a href="javascript:AtD.ignoreAll(\'' + AtD.container + '\')">' + AtD.getLang('menu_option_ignore_all', 'Ignore all') + '</a>');
313 }
314
315 suggest.append('<a href="javascript:AtD.editSelection(\'' + AtD.container + '\')" class="spell_sep_bottom spell_sep_top">' + AtD.getLang('menu_option_edit_selection', 'Edit Selection...') + '</a>');
316 }
317 else {
318 if (AtD.callback_f !== undefined && AtD.callback_f.ignore !== undefined) {
319 suggest.append('<a href="javascript:AtD.ignoreAll(\'' + AtD.container + '\')" class="spell_sep_bottom">' + AtD.getLang('menu_option_ignore_always', 'Ignore always') + '</a>');
320 } else {
321 suggest.append('<a href="javascript:AtD.ignoreAll(\'' + AtD.container + '\')" class="spell_sep_bottom">' + AtD.getLang('menu_option_ignore_all', 'Ignore all') + '</a>');
322 }
323 }
324
325 /* show the menu */
326
327 var pos = jQuery(element).offset();
328 var width = jQuery(element).width();
329
330 /* a sanity check for Internet Explorer--my favorite browser in every possible way */
331 if (width > 100) {
332 width = 50;
333 }
334
335 jQuery(suggest).css({ left: (pos.left + width) + 'px', top: pos.top + 'px' });
336
337 jQuery(suggest).fadeIn(200);
338
339 /* bind events to make the menu disappear when the user clicks outside of it */
340
341 AtD.suggestShow = true;
342
343 setTimeout(function() {
344 jQuery('body').bind('click', function() {
345 if (!AtD.suggestShow) {
346 jQuery('#suggestmenu').fadeOut(200);
347 }
348 });
349 }, 1);
350
351 setTimeout(function() {
352 AtD.suggestShow = false;
353 }, 2);
354 };
355
356 AtD._removeWords = function(container_id, w) {
357 return this.core.removeWords(jQuery('#' + container_id), w);
358 };
359
360 /*
361 * Set prototypes used by AtD Core UI
362 */
363 AtD.initCoreModule = function() {
364 var core = new AtDCore();
365
366 core.hasClass = function(node, className) {
367 return jQuery(node).hasClass(className);
368 };
369
370 core.map = jQuery.map;
371
372 core.contents = function(node) {
373 return jQuery(node).contents();
374 };
375
376 core.replaceWith = function(old_node, new_node) {
377 return jQuery(old_node).replaceWith(new_node);
378 };
379
380 core.findSpans = function(parent) {
381 return jQuery.makeArray(parent.find('span'));
382 };
383
384 core.create = function(string/*, isTextNode*/) {
385 // replace out all tags with &-equivalents so that we preserve tag text.
386 string = string.replace(/\&/g, '&amp;');
387 string = string.replace(/</g, '&lt;').replace(/\>/g, '&gt;');
388
389 // find all instances of AtD-created spans
390 var matches = string.match(/\&lt;span class="hidden\w+?" pre="[^"]*"\&gt;.*?\&lt;\/span\&gt;/g);
391 var x;
392
393 // ... and fix the tags in those substrings.
394 if (matches) {
395 for (x = 0; x < matches.length; x++) {
396 string = string.replace(matches[x], matches[x].replace(/\&lt;/gi, '<').replace(/\&gt;/gi, '>'));
397 }
398 }
399
400 if (core.isIE()) {
401 // and... one more round of corrections for our friends over at the Internet Explorer
402 matches = string.match(/\&lt;span class="mceItemHidden"\&gt;\&amp;nbsp;\&lt;\/span&gt;/g, string);
403 //|&lt;BR.*?class.*?atd_remove_me.*?\&gt;/gi, string);
404 if (matches) {
405 for (x = 0; x < matches.length; x++) {
406 string = string.replace(matches[x], matches[x].replace(/\&lt;/gi, '<').replace(/\&gt;/gi, '>').replace(/\&amp;/gi, '&'));
407 }
408 }
409 }
410
411 var node = jQuery('<span class="mceItemHidden"></span>');
412 node.html(string);
413 return node;
414 };
415
416 core.remove = function(node) {
417 return jQuery(node).remove();
418 };
419
420 core.removeParent = function(node) {
421 /* unwrap exists in jQuery 1.4+ only. Thankfully because replaceWith as-used here won't work in 1.4 */
422 if (jQuery(node).unwrap) {
423 return jQuery(node).contents().unwrap();
424 } else {
425 return jQuery(node).replaceWith(jQuery(node).html());
426 }
427 };
428
429 core.getAttrib = function(node, name) {
430 return jQuery(node).attr(name);
431 };
432
433 return core;
434 };
435
436 AtD.core = AtD.initCoreModule();
437