source: trunk/plugins/SuperClean/super-clean.js @ 744

Last change on this file since 744 was 744, checked in by ray, 12 years ago

SuperClean?: Ticket #905 Problems with compression / List of incompatible files

  • Property svn:eol-style set to native
  • Property svn:keywords set to LastChangedDate LastChangedRevision LastChangedBy HeadURL Id
File size: 10.0 KB
Line 
1// Make our right side panel and insert appropriatly
2function SuperClean(editor, args)
3{
4  this.editor = editor;
5  var superclean = this;
6  editor._superclean_on = false;
7  editor.config.registerButton('superclean', this._lc("Clean up HTML"), editor.imgURL('ed_superclean.gif', 'SuperClean'), true, function(e, objname, obj) { superclean._superClean(null, obj); });
8
9  // See if we can find 'killword' and replace it with superclean
10  editor.config.addToolbarElement("superclean", "killword", 0);
11}
12
13SuperClean._pluginInfo =
14{
15  name     : "SuperClean",
16  version  : "1.0",
17  developer: "James Sleeman, Niko Sams",
18  developer_url: "http://www.gogo.co.nz/",
19  c_owner      : "Gogo Internet Services",
20  license      : "htmlArea",
21  sponsor      : "Gogo Internet Services",
22  sponsor_url  : "http://www.gogo.co.nz/"
23};
24
25SuperClean.prototype._lc = function(string) {
26    return Xinha._lc(string, 'SuperClean');
27};
28
29/** superClean combines HTMLTidy, Word Cleaning and font stripping into a single function
30 *  it works a bit differently in how it asks for parameters */
31
32SuperClean.prototype._superClean = function(opts, obj)
33{
34  var superclean = this;
35
36  // Do the clean if we got options
37  var doOK = function()
38  {
39    var opts = superclean._dialog.hide();
40    var editor = superclean.editor;
41
42    if(opts.word_clean) editor._wordClean();
43    var D = editor.getInnerHTML();
44
45    for(var filter in editor.config.SuperClean.filters)
46    {
47      if(filter=='tidy' || filter=='word_clean') continue;
48      if(opts[filter])
49      {
50        D = SuperClean.filterFunctions[filter](D, editor);
51      }
52    }
53
54    D = D.replace(/(style|class)="\s*"/gi, '');
55    D = D.replace(/<(font|span)\s*>/gi, '');
56
57    editor.setHTML(D);
58
59    if(opts.tidy)
60    {
61      var callback = function(javascriptResponse)
62      {
63        eval("var response = " + javascriptResponse);
64        switch (response.action)
65        {
66          case 'setHTML':
67            editor.setHTML(response.value);
68          break;
69          case 'alert':
70            alert(superclean._lc(response.value));
71          break;
72        }
73      }
74      Xinha._postback(editor.config.SuperClean.tidy_handler, {'content' : editor.getInnerHTML()},callback);
75    }
76    return true;
77  }
78
79  if(this.editor.config.SuperClean.show_dialog)
80  {
81    var inputs = {};
82    this._dialog.show(inputs, doOK);
83  }
84  else
85  {
86    var editor = this.editor;
87    var html = editor.getInnerHTML();
88    for(var filter in editor.config.SuperClean.filters)
89    {
90      if(filter=='tidy') continue; //call tidy last
91      html = SuperClean.filterFunctions[filter](html, editor);
92    }
93
94    html = html.replace(/(style|class)="\s*"/gi, '');
95    html = html.replace(/<(font|span)\s*>/gi, '');
96
97    editor.setHTML(html);
98
99    if(editor.config.SuperClean.filters.tidy)
100    {
101      SuperClean.filterFunctions.tidy(html, editor);
102    }
103  }
104};
105
106Xinha.Config.prototype.SuperClean =
107{
108  // set to the URL of a handler for html tidy, this handler
109  //  (see tidy.php for an example) must that a single post variable
110  //  "content" which contains the HTML to tidy, and return javascript like
111  //  editor.setHTML('<strong>Tidied Html</strong>')
112  // it's called through XMLHTTPRequest
113  'tidy_handler': _editor_url + 'plugins/SuperClean/tidy.php',
114
115  //avaliable filters (these are built-in filters)
116  // You can either use
117  //    'filter_name' : "Label/Description String"
118  // or 'filter_name' : {label: "Label", checked: true/false, filterFunction: function(html) { ... return html;} }
119  // filterFunction in the second format above is optional.
120
121  'filters': { 'tidy': Xinha._lc('General tidy up and correction of some problems.', 'SuperClean'),
122               'word_clean': Xinha._lc('Clean bad HTML from Microsoft Word', 'SuperClean'),
123               'remove_faces': Xinha._lc('Remove custom typefaces (font "styles").', 'SuperClean'),
124               'remove_sizes': Xinha._lc('Remove custom font sizes.', 'SuperClean'),
125               'remove_colors': Xinha._lc('Remove custom text colors.', 'SuperClean'),
126               'remove_lang': Xinha._lc('Remove lang attributes.', 'SuperClean'),
127               'remove_fancy_quotes': {label:Xinha._lc('Replace directional quote marks with non-directional quote marks.', 'SuperClean'), checked:false}
128  //additional custom filters (defined in plugins/SuperClean/filters/word.js)
129               //'paragraph': 'remove paragraphs'},
130               //'word': 'exteded Word-Filter' },
131              },
132  //if false all filters are applied, if true a dialog asks what filters should be used
133  'show_dialog': true
134};
135
136SuperClean.filterFunctions = { };
137SuperClean.filterFunctions.remove_colors = function(D)
138{
139  D = D.replace(/color="?[^" >]*"?/gi, '');
140  // { (stops jedit's fold breaking)
141  D = D.replace(/([^-])color:[^;}"']+;?/gi, '$1');
142  return(D);
143};
144SuperClean.filterFunctions.remove_sizes = function(D)
145{
146  D = D.replace(/size="?[^" >]*"?/gi, '');
147  // { (stops jedit's fold breaking)
148  D = D.replace(/font-size:[^;}"']+;?/gi, '');
149  return(D);
150};
151SuperClean.filterFunctions.remove_faces = function(D)
152{
153  D = D.replace(/face="?[^" >]*"?/gi, '');
154  // { (stops jedit's fold breaking)
155  D = D.replace(/font-family:[^;}"']+;?/gi, '');
156  return(D);
157};
158SuperClean.filterFunctions.remove_lang = function(D)
159{
160  D = D.replace(/lang="?[^" >]*"?/gi, '');
161  return(D);
162};
163SuperClean.filterFunctions.word_clean = function(html, editor)
164{
165  editor.setHTML(html);
166  editor._wordClean();
167  return editor.getInnerHTML();
168};
169
170SuperClean.filterFunctions.remove_fancy_quotes = function(D)
171{
172  D = D.replace(new RegExp(String.fromCharCode(8216),"g"),"'");
173  D = D.replace(new RegExp(String.fromCharCode(8217),"g"),"'");
174  D = D.replace(new RegExp(String.fromCharCode(8218),"g"),"'");
175  D = D.replace(new RegExp(String.fromCharCode(8219),"g"),"'");
176  D = D.replace(new RegExp(String.fromCharCode(8220),"g"),"\"");
177  D = D.replace(new RegExp(String.fromCharCode(8221),"g"),"\"");
178  D = D.replace(new RegExp(String.fromCharCode(8222),"g"),"\"");
179  D = D.replace(new RegExp(String.fromCharCode(8223),"g"),"\"");
180  return D;
181};
182
183SuperClean.filterFunctions.tidy = function(html, editor)
184{
185  Xinha._postback(editor.config.SuperClean.tidy_handler, {'content' : html},
186                      function(javascriptResponse) { eval(javascriptResponse) });
187};
188
189
190
191SuperClean.prototype.onGenerate = function()
192{
193  if(this.editor.config.SuperClean.show_dialog && !this._dialog)
194  {
195    this._dialog = new SuperClean.Dialog(this);
196  }
197  if(this.editor.config.tidy_handler)
198  {
199    //for backwards compatibility
200    this.editor.config.SuperClean.tidy_handler = this.editor.config.tidy_handler;
201    this.editor.config.tidy_handler = null;
202  }
203  if(!this.editor.config.SuperClean.tidy_handler && this.editor.config.filters.tidy) {
204    //unset tidy-filter if no tidy_handler
205    this.editor.config.filters.tidy = null;
206  }
207
208  var sc = this;
209  //load the filter-functions
210  for(var filter in this.editor.config.SuperClean.filters)
211  {
212    if(!SuperClean.filterFunctions[filter])
213    {
214      var filtDetail = this.editor.config.SuperClean.filters[filter];
215      if(typeof filtDetail.filterFunction != 'undefined')
216      {
217        SuperClean.filterFunctions[filter] = filterFunction;
218      }
219      else
220      {
221        Xinha._getback(_editor_url + 'plugins/SuperClean/filters/'+filter+'.js',
222                      function(func) {
223                        eval('SuperClean.filterFunctions.'+filter+'='+func+';');
224                        sc.onGenerate();
225                      });
226      }
227      return;
228    }
229  }
230};
231// Inline Dialog for SuperClean
232
233
234SuperClean.Dialog = function (SuperClean)
235{
236  var  lDialog = this;
237  this.Dialog_nxtid = 0;
238  this.SuperClean = SuperClean;
239  this.id = { }; // This will be filled below with a replace, nifty
240
241  this.ready = false;
242  this.files  = false;
243  this.html   = false;
244  this.dialog = false;
245
246  // load the dTree script
247  this._prepareDialog();
248
249};
250
251SuperClean.Dialog.prototype._prepareDialog = function()
252{
253  var lDialog = this;
254  var SuperClean = this.SuperClean;
255
256  if(this.html == false)
257  {
258    Xinha._getback(_editor_url + 'plugins/SuperClean/dialog.html', function(txt) { lDialog.html = txt; lDialog._prepareDialog(); });
259    return;
260  }
261
262  var htmlFilters = "";
263  for(var filter in this.SuperClean.editor.config.SuperClean.filters)
264  {
265    htmlFilters += "    <div>\n";
266    var filtDetail = this.SuperClean.editor.config.SuperClean.filters[filter];
267    if(typeof filtDetail.label == 'undefined')
268    {
269      htmlFilters += "        <input type=\"checkbox\" name=\"["+filter+"]\" id=\"["+filter+"]\" checked />\n";
270      htmlFilters += "        <label for=\"["+filter+"]\">"+this.SuperClean.editor.config.SuperClean.filters[filter]+"</label>\n";
271    }
272    else
273    {
274      htmlFilters += "        <input type=\"checkbox\" name=\"["+filter+"]\" id=\"["+filter+"]\" " + (filtDetail.checked ? "checked" : "") + " />\n";
275      htmlFilters += "        <label for=\"["+filter+"]\">"+filtDetail.label+"</label>\n";
276    }
277    htmlFilters += "    </div>\n";
278  }
279  this.html = this.html.replace('<!--filters-->', htmlFilters);
280
281  var html = this.html;
282
283  // Now we have everything we need, so we can build the dialog.
284  var dialog = this.dialog = new Xinha.Dialog(SuperClean.editor, this.html, 'SuperClean');
285
286  this.ready = true;
287};
288
289SuperClean.Dialog.prototype._lc = SuperClean.prototype._lc;
290
291SuperClean.Dialog.prototype.show = function(inputs, ok, cancel)
292{
293  if(!this.ready)
294  {
295    var lDialog = this;
296    window.setTimeout(function() {lDialog.show(inputs,ok,cancel);},100);
297    return;
298  }
299
300  // Connect the OK and Cancel buttons
301  var dialog = this.dialog;
302  var lDialog = this;
303  if(ok)
304  {
305    this.dialog.getElementById('ok').onclick = ok;
306  }
307  else
308  {
309    this.dialog.getElementById('ok').onclick = function() {lDialog.hide();};
310  }
311
312  if(cancel)
313  {
314    this.dialog.getElementById('cancel').onclick = cancel;
315  }
316  else
317  {
318    this.dialog.getElementById('cancel').onclick = function() { lDialog.hide()};
319  }
320
321  // Show the dialog
322  this.SuperClean.editor.disableToolbar(['fullscreen','SuperClean']);
323
324  this.dialog.show(inputs);
325
326  // Init the sizes
327  this.dialog.onresize();
328};
329
330SuperClean.Dialog.prototype.hide = function()
331{
332  this.SuperClean.editor.enableToolbar();
333  return this.dialog.hide();
334};
Note: See TracBrowser for help on using the repository browser.