source: tags/1.5/XinhaEasy.js

Last change on this file was 1421, checked in by gogo, 10 months ago

Add support for using external plugins with XinhaEasy.js and add Xinha.pluginManifest to describe location of built in plugins (and modules) without needing to "ping" them.

The pluginManifest can be generated by bash script contrib/generate-plugin-manifest.sh and should be done and updated before release.

For external/custom plugins when using XinhaEasy.js simply set the xinha_plugins option thusly...

xinha_plugins: [ 'BuiltInPlugin1', { from: '/path/to/custom/plugins', load: 'CustomPlugin1' } ]

It works even for the PHP plugins, MootoolsFileManager? and Linker when using Xinha from a CDN etc, as long of course as they have the contrib php-xinha.php available to them.

  • Property svn:executable set to *
File size: 24.5 KB
Line 
1/* This script is used to provide a super-simple loading method for Xinha
2 *
3 * For just "defaults", you can be as simple as
4 *
5 * <script src="XinhaEasy.js"></script>
6 *
7 * And it will convert all textareas on the page.
8 *
9 * See examples/Newbie.html for a complete configuration example
10 *
11 */
12
13_editor_url   = typeof _editor_url   != 'undefined' ? _editor_url  : null;
14_editor_lang  = typeof _editor_lang  != 'undefined' ? _editor_lang : 'en';
15_editor_skin  = typeof _editor_skin  != 'undefined' ? _editor_skin : 'silva';
16_editor_icons = typeof _editor_icons != 'undefined' ? _editor_icons : null;
17_editor_css   = typeof _editor_css   != 'undefined' ? _editor_css : null;
18
19xinha_init    = null;
20xinha_editors = null;
21xinha_config  = null;
22xinha_toolbar = null;
23xinha_plugins = null;
24
25// Auto detect _editor_url if it's not set.
26(function() // wrap this in an ad-hoc function to avoid unecessary pollution of global namespace
27{
28  // Because of the way the DOM is loaded, this is guaranteed to always pull our script tag.
29  var scripts = document.getElementsByTagName('script');
30  var this_script = scripts[scripts.length - 1];
31
32  var xinha_options = null;
33 
34  // We can grab the script innerHTML and execute that to cut down on script
35  // tags.  Thanks John Resig!
36  // http://ejohn.org/blog/degrading-script-tags/ 
37  if (this_script.innerHTML.replace(/\s+/, ''))
38  {
39    try // DEBUGGING: Comment out this line and the catch(e) below
40    {
41      eval(this_script.innerHTML);
42     
43     
44      // Because the setup options might reference _editor_url, we treat that first...
45      // Chop off any query string.  Chop the filename off of the URL
46      // Leave exactly one backslash at the end of _editor_url
47      _editor_url = xinha_options._editor_url || this_script.src.split('?')[0].split('/').slice(0, -1).join('/').replace(/\x2f*$/, '/');
48     
49      // then reload the options...
50      xinha_options = eval(this_script.innerHTML);
51      delete xinha_options.editor_url;
52    }
53    catch(e) // DEBUGGING: Comment out this line and the try below
54    {     
55      if(typeof console != 'undefined' && typeof console.log == 'function')
56      {
57        var warn = typeof console.error == 'function' ? function(w){console.error(w);} : function(w){console.log(w);};
58        warn(e);
59        warn("Xinha: There is a problem loading your configuration data.");
60        warn("Xinha: Check for common problems like a missing comma after a configuration section, or semicolons instead of commas after configuration sections.");
61        warn("Xinha: If you get really stuck, comment the try and catch lines around here and the native error might be more useful.");       
62        warn("Xinha: Default configuration is being used.");
63      }
64      else
65      {
66        throw e;
67      }
68      xinha_options = null;     
69    }
70  }
71 
72  if(_editor_url == null)
73  {
74    _editor_url = this_script.src.split('?')[0].split('/').slice(0, -1).join('/');
75  }
76 
77  // Default values
78  if(xinha_options != null)
79  {
80    for(var i in xinha_options)
81    {
82      if(xinha_options[i] !== null)
83      {
84        window[i] = xinha_options[i];
85      }
86    }
87  }
88})()
89
90_editor_url = _editor_url.replace(/\x2f*$/, '/');
91
92// It may be that we already have the XinhaCore.js loaded, if so, we don't need this stuff
93// and setting it would override the proper stuff.
94if(typeof Xinha == 'undefined')
95{
96  var Xinha = {};
97
98  Xinha.agt       = navigator.userAgent.toLowerCase();
99  Xinha.is_ie    = ((Xinha.agt.indexOf("msie") != -1) && (Xinha.agt.indexOf("opera") == -1));
100  Xinha.ie_version= parseFloat(Xinha.agt.substring(Xinha.agt.indexOf("msie")+5));
101  Xinha.is_opera  = (Xinha.agt.indexOf("opera") != -1);
102  Xinha.is_khtml  = (Xinha.agt.indexOf("khtml") != -1);
103  Xinha.is_webkit  = (Xinha.agt.indexOf("applewebkit") != -1);
104  Xinha.is_safari  = (Xinha.agt.indexOf("safari") != -1);
105  Xinha.opera_version = navigator.appVersion.substring(0, navigator.appVersion.indexOf(" "))*1;
106  Xinha.is_mac   = (Xinha.agt.indexOf("mac") != -1);
107  Xinha.is_mac_ie = (Xinha.is_ie && Xinha.is_mac);
108  Xinha.is_win_ie = (Xinha.is_ie && !Xinha.is_mac);
109  Xinha.is_gecko  = (navigator.product == "Gecko" && !Xinha.is_safari); // Safari lies!
110  Xinha.isRunLocally = document.URL.toLowerCase().search(/^file:/) != -1;
111  Xinha.is_designMode = (typeof document.designMode != 'undefined' && !Xinha.is_ie); // IE has designMode, but we're not using it
112  Xinha.isSupportedBrowser = Xinha.is_gecko || (Xinha.is_opera && Xinha.opera_version >= 9.1) || Xinha.ie_version >= 5.5 || Xinha.is_safari;
113
114  Xinha.loadPlugins = function(plugins, callbackIfNotReady)
115  {
116    if ( !Xinha.isSupportedBrowser ) return;
117   
118    Xinha.loadStyle(typeof _editor_css == "string" ? _editor_css : "Xinha.css","XinhaCoreDesign");
119    Xinha.createLoadingMessages(xinha_editors);
120    var loadingMessages = Xinha.loadingMessages;
121    Xinha._loadback(_editor_url + "XinhaCore.js",function () {
122  //    Xinha.removeLoadingMessages(xinha_editors); 
123  //    Xinha.createLoadingMessages(xinha_editors); 
124      callbackIfNotReady()
125    });
126    return false;
127  }
128
129  Xinha._loadback = function(Url, Callback, Scope, Bonus)
130  { 
131    var T = !Xinha.is_ie ? "onload" : 'onreadystatechange';
132    var S = document.createElement("script");
133    S.type = "text/javascript";
134    S.src = Url;
135    if ( Callback )
136    {
137      S[T] = function()
138      {     
139        if ( Xinha.is_ie && ( ! ( /loaded|complete/.test(window.event.srcElement.readyState) ) ) )
140        {
141          return;
142        }
143       
144        Callback.call(Scope ? Scope : this, Bonus);
145        S[T] = null;
146      };
147    }
148    document.getElementsByTagName("head")[0].appendChild(S);
149  };
150
151  Xinha.getElementTopLeft = function(element)
152  {
153    var curleft = 0;
154    var curtop = 0;
155    if (element.offsetParent)
156    {
157      curleft = element.offsetLeft
158      curtop = element.offsetTop
159      while (element = element.offsetParent)
160      {
161        curleft += element.offsetLeft
162        curtop += element.offsetTop
163      }
164    }
165    return { top:curtop, left:curleft };
166  }
167
168  // find X position of an element
169  Xinha.findPosX = function(obj)
170  {
171    var curleft = 0;
172    if ( obj.offsetParent )
173    {
174      return Xinha.getElementTopLeft(obj).left;   
175    }
176    else if ( obj.x )
177    {
178      curleft += obj.x;
179    }
180    return curleft;
181  };
182
183  // find Y position of an element
184  Xinha.findPosY = function(obj)
185  {
186    var curtop = 0;
187    if ( obj.offsetParent )
188    {
189      return Xinha.getElementTopLeft(obj).top;   
190    }
191    else if ( obj.y )
192    {
193      curtop += obj.y;
194    }
195    return curtop;
196  };
197
198  Xinha.createLoadingMessages = function(xinha_editors)
199  {
200    if ( Xinha.loadingMessages || !Xinha.isSupportedBrowser )
201    {
202      return;
203    }
204    Xinha.loadingMessages = [];
205   
206    for (var i=0;i<xinha_editors.length;i++)
207    {
208      var e = typeof xinha_editors[i] == 'string' ? document.getElementById(xinha_editors[i]) : xinha_editors[i];
209      if (!e)
210      {
211        continue;
212      }
213      Xinha.loadingMessages.push(Xinha.createLoadingMessage(e));
214    }
215  }
216
217  Xinha.createLoadingMessage = function(textarea,text)
218  {
219    if ( document.getElementById("loading_" + textarea.id) || !Xinha.isSupportedBrowser)
220    {
221      return;
222    }
223    // Create and show the main loading message and the sub loading message for details of loading actions
224    // global element
225    var loading_message = document.createElement("div");
226    loading_message.id = "loading_" + textarea.id;
227    loading_message.className = "loading";
228   
229    loading_message.style.left = (Xinha.findPosX(textarea) + textarea.offsetWidth / 2) - 106 +  'px';
230    loading_message.style.top = (Xinha.findPosY(textarea) + textarea.offsetHeight / 2) - 50 +  'px';
231    // main static message
232    var loading_main = document.createElement("div");
233    loading_main.className = "loading_main";
234    loading_main.id = "loading_main_" + textarea.id;
235    loading_main.appendChild(document.createTextNode(Xinha._lc("Loading in progress. Please wait!")));
236    // sub dynamic message
237    var loading_sub = document.createElement("div");
238    loading_sub.className = "loading_sub";
239    loading_sub.id = "loading_sub_" + textarea.id;
240    text = text ? text : Xinha._lc("Loading Core");
241    loading_sub.appendChild(document.createTextNode(text));
242    loading_message.appendChild(loading_main);
243    loading_message.appendChild(loading_sub);
244    document.body.appendChild(loading_message);
245   
246    return loading_sub;
247  }
248
249  Xinha.loadStyle = function(style, id)
250  {
251    var url = _editor_url || '';
252   
253    url += style;
254 
255    var head = document.getElementsByTagName("head")[0];
256    var link = document.createElement("link");
257    link.rel = "stylesheet";
258    link.href = url;
259    if (id) link.id = id;
260    head.appendChild(link);
261  };
262
263  Xinha._lc = function(string) {return string;}
264
265  Xinha._addEvent = function(el, evname, func)
266  {
267    if ( document.addEventListener )
268    {
269      el.addEventListener(evname, func, true);
270    }
271    else
272    {
273      el.attachEvent("on" + evname, func);
274    }
275  }
276
277  Xinha.addOnloadHandler = function (func)
278  {
279    // Dean Edwards/Matthias Miller/John Resig
280    // http://dean.edwards.name/weblog/2006/06/again/
281    // IE part from jQuery
282   
283   
284    var init = function ()
285    {
286      // quit if this function has already been called
287      if (arguments.callee.done) return;
288      // flag this function so we don't do the same thing twice
289      arguments.callee.done = true;
290      // kill the timer
291      if (Xinha.onloadTimer) clearInterval(Xinha.onloadTimer);
292     
293      func.call();
294    }
295    if (Xinha.is_ie)
296    {
297      // ensure firing before onload,
298      // maybe late but safe also for iframes
299      document.attachEvent("onreadystatechange", function(){
300        if ( document.readyState === "complete" ) {
301          document.detachEvent( "onreadystatechange", arguments.callee );
302          init();
303        }
304      });
305      if ( document.documentElement.doScroll && typeof window.frameElement === "undefined" ) (function(){
306        if (arguments.callee.done) return;
307        try {
308          // If IE is used, use the trick by Diego Perini
309          // http://javascript.nwbox.com/IEContentLoaded/
310          document.documentElement.doScroll("left");
311        } catch( error ) {
312          setTimeout( arguments.callee, 0 );
313          return;
314        }
315        // and execute any waiting functions
316        init();
317      })();
318    }
319    else if (/WebKit/i.test(navigator.userAgent))
320    {
321      Xinha.onloadTimer = setInterval(function()
322      {
323        if (/loaded|complete/.test(document.readyState))
324        {
325          init(); // call the onload handler
326        }
327      }, 10);
328    }
329    else /* for Mozilla/Opera9 */
330    {
331      document.addEventListener("DOMContentLoaded", init, false); 
332    }
333  }
334}
335
336xinha_init = xinha_init ? xinha_init : function()
337{
338  // IE7 support for querySelectorAll. Supports multiple / grouped selectors
339  // and the attribute selector with a "for" attribute. http://www.codecouch.com/
340  // http://www.codecouch.com/2012/05/adding-document-queryselectorall-support-to-ie-7/
341  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
342  if (!document.querySelectorAll)
343  {
344    (function(d, s) {
345      d=document, s=d.createStyleSheet();
346      d.querySelectorAll = function(r, c, i, j, a) {
347        a=d.all, c=[], r = r.replace(/\[for\b/gi, '[htmlFor').split(',');
348        for (i=r.length; i--;) {
349          s.addRule(r[i], 'k:v');
350          for (j=a.length; j--;) a[j].currentStyle.k && c.push(a[j]);
351          s.removeRule(0);
352        }
353        return c;
354      }
355    })();
356  }
357
358  if (!document.querySelector)
359  {
360    document.querySelector = function(selectors) {
361      var elements = document.querySelectorAll(selectors);
362      return (elements.length) ? elements[0] : null;
363    };
364  }
365  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
366
367
368   /** STEP 1 ***************************************************************
369   * First, specify the textareas that shall be turned into Xinhas.
370   * For each one add the respective id to the xinha_editors array.
371   * I you want add more than on textarea, keep in mind that these
372   * values are comma seperated BUT there is no comma after the last value.
373   * If you are going to use this configuration on several pages with different
374   * textarea ids, you can add them all. The ones that are not found on the
375   * current page will just be skipped.
376   ************************************************************************/
377
378  if(xinha_editors == null)
379  {
380    // BY default, change all textareas into Xinha
381    xinha_editors = 'textarea';
382  }
383 
384  if(typeof xinha_editors == 'string')
385  {
386    // A raw ID like we used to do
387    if(document.getElementById(xinha_editors))
388    {
389      xinha_editors = [ document.getElementById(xinha_editors) ];
390    }
391   
392    // Must be a selector, this is not supported for IE7 or lower!
393    else
394    {
395      var selected = document.querySelectorAll(xinha_editors);
396      xinha_editors = [ ];
397      for(var i = 0; i < selected.length; i++)
398      {
399        xinha_editors.push(selected[i]);
400      }
401    }
402  }
403 
404  /** STEP 2 ***************************************************************
405   * Now, what are the plugins you will be using in the editors on this
406   * page.  List all the plugins you will need, even if not all the editors
407   * will use all the plugins.
408   *
409   * The list of plugins below is a good starting point, but if you prefer
410   * a simpler editor to start with then you can use the following
411   *
412   * xinha_plugins = xinha_plugins ? xinha_plugins : [ ];
413   *
414   * which will load no extra plugins at all.
415   ************************************************************************/
416
417  function parse_plugins(xinha_plugins)
418  {
419    var remove_plugins = [ ];
420       
421    if(xinha_plugins === null)
422    {
423      xinha_plugins = 'common';
424    }
425   
426    if(typeof xinha_plugins == 'string')
427    {
428      xinha_plugins = [ xinha_plugins ];
429    }
430   
431    var load_plugins = xinha_plugins;
432    xinha_plugins = [ ];
433    for(var i = 0; i < load_plugins.length; i++)
434    {
435      // In case of { from: '/path/to/plugins', load: ['MootoolsFileManager'] }
436      if(typeof load_plugins[i] == 'object' && typeof load_plugins[i].from == 'string')
437      {
438        // Resolve the "load" into a list of plugins
439        var externs = parse_plugins(load_plugins[i].load);
440       
441        // MPush them into plugins as external plugin objects
442        for(var ii = 0; ii < externs.length; ii++)
443        {
444          // In case you want to specify a non-default plugin file naming
445          if(externs[ii].match(/\//))
446          {
447            xinha_plugins.push({ url: load_plugins[i].from + '/' + externs[ii] , plugin: externs[ii].replace(/.*\/([^.]+)\..*$/, '$1') });
448          }
449          else
450          {
451            xinha_plugins.push({ url: load_plugins[i].from + '/' + externs[ii] + '/' + externs[ii] + '.js', plugin: externs[ii]});
452          }
453        }
454        continue;
455      }
456     
457      // External plugin definition
458      if(typeof load_plugins[i] == 'object' && typeof load_plugins[i].url == 'string')
459      {
460        xinha_plugins.push(load_plugins[i]);
461        continue;
462      }
463     
464      // In case of [ 'Plugin1', ['Plugin1', 'Plugin3'] ]
465      if(typeof load_plugins[i] != 'string')
466      {
467        Array.prototype.push.apply(load_plugins, load_plugins[i]);
468        continue;
469      }
470     
471      // Provide some simple plugin defintion shortcuts
472      switch(load_plugins[i])
473      {
474        case 'loaded':
475        {
476          Array.prototype.push.apply(xinha_plugins,  ['CharacterMap', 'ContextMenu', 'FancySelects', 'SmartReplace', 'SuperClean', 'TableOperations', 'ListOperations', 'PreserveScripts', 'PreserveSelection', 'WebKitResize', 'Stylist', 'UnsavedChanges','QuickTag', 'PasteText', 'MootoolsFileManager', 'ListType', 'Linker', 'LangMarks', 'InsertWords', 'InsertSnppet2', 'InsertSmiley','InsertPagebreak', 'InsertNote', 'InsertAnchor', 'HtmlEntities', 'HorizontalRule', 'FindReplace', 'DefinitionList', 'CharCounter','Abbreviation'] );
477        }
478        break;
479       
480        case 'minimal':
481        {
482          Array.prototype.push.apply(xinha_plugins, [ 'FancySelects', 'ListOperations', 'PreserveSelection', 'WebKitResize' ]);
483        }
484        break;
485       
486        case 'common':
487        {
488          Array.prototype.push.apply(xinha_plugins, [ 'CharacterMap', 'ContextMenu', 'FancySelects', 'SmartReplace', 'SuperClean', 'TableOperations', 'ListOperations', 'PreserveScripts', 'PreserveSelection', 'WebKitResize' ]);
489
490         
491        }
492        break;
493       
494        default:
495          if(load_plugins[i].match(/^!/))
496          {
497            Array.prototype.push.apply(remove_plugins, parse_plugins(load_plugins[i].replace(/^!/, '')));
498          }
499          else
500          {
501            xinha_plugins.push(load_plugins[i]);
502          }
503          break;
504      }
505    }
506   
507    // Strip out the remove plugins, and duplicates
508    var return_plugins = [ ];
509    for(var i = 0; i < xinha_plugins.length; i++)
510    {
511      var OK = true;
512     
513      if(OK) for(var j = 0; j < remove_plugins.length; j++)
514      {
515        if(remove_plugins[j] == xinha_plugins[i]) { OK = false; break; }
516      }
517     
518      if(OK) for(var j = 0; j < return_plugins.length; j++)
519      {
520        if(return_plugins[j] == xinha_plugins[i]) { OK = false; break; }
521      }
522     
523      if(OK)
524      {
525        return_plugins.push(xinha_plugins[i]);
526      }
527    }
528    xinha_plugins = return_plugins;
529   
530    return xinha_plugins;
531  }
532 
533  xinha_plugins = parse_plugins(xinha_plugins);
534 
535 
536         // THIS BIT OF JAVASCRIPT LOADS THE PLUGINS, NO TOUCHING  :)
537         if(!Xinha.loadPlugins(xinha_plugins, xinha_init)) return;
538
539
540  /** STEP 3 ***************************************************************
541   * We create a default configuration to be used by all the editors.
542   * If you wish to configure some of the editors differently this will be
543   * done in step 5.
544   *
545   * If you want to modify the default config you might do something like this.
546   *
547   *   xinha_config = new Xinha.Config();
548   *   xinha_config.width  = '640px';
549   *   xinha_config.height = '420px';
550   *
551   *
552   * For a list of the available configuration options, see:
553   * http://trac.xinha.org/wiki/Documentation/ConfigVariablesList
554   *
555   *************************************************************************/
556
557  var new_config      = new Xinha.Config();
558  if(typeof xinha_config == 'function')
559  {
560    // If it doesn't return an object, that should still be fine
561    //  due to references and such
562    var returned_config = xinha_config(new_config);
563    if(typeof returned_config == 'object')
564    {
565      new_config = returned_config;
566    }     
567  }
568  xinha_config = new_config;
569
570  Xinha.Config.prototype.setToolbar = function(xinha_toolbar)
571  {
572    var xinha_config = this;
573    if(typeof xinha_toolbar == 'string' || xinha_toolbar === null)
574    {
575      switch(xinha_toolbar)
576      {         
577        case 'minimal+fonts':
578          xinha_config.toolbar = [
579              ["popupeditor"],
580              ["separator","formatblock","fontname","fontsize","bold","italic","underline","strikethrough","superscript"],
581              ["separator","forecolor","hilitecolor"],
582              ["separator","justifyleft","justifycenter","justifyright"],
583              ["separator","insertorderedlist","insertunorderedlist","outdent","indent"],
584              ["separator","createlink","insertimage"],
585            ];
586        break;
587       
588        case 'minimal':
589            xinha_config.toolbar = [
590              ["popupeditor"],
591              ["separator","bold","italic","underline","strikethrough","superscript"],
592              ["separator","forecolor","hilitecolor"],
593              ["separator","justifyleft","justifycenter","justifyright"],
594              ["separator","insertorderedlist","insertunorderedlist","outdent","indent"],
595              ["separator","createlink","insertimage"],
596            ];
597          break;     
598         
599        case 'supermini':
600          xinha_config.toolbar = [
601             
602              ["separator","bold","italic","underline","strikethrough","superscript"],
603             
604            ];
605          break;
606      }
607    }
608    else if(typeof xinha_toolbar == 'object')
609    {
610      xinha_config.toolbar = xinha_toolbar;
611    }
612  }
613
614  // Alias because I know I wil; type this differently
615  Xinha.Config.prototype.setToolBar = Xinha.Config.prototype.setToolbar;
616 
617  xinha_config.setToolbar(xinha_toolbar);
618
619  if(typeof xinha_stylesheet == 'string' && xinha_stylesheet.length )
620  {
621    xinha_config.pageStyleSheets = [ xinha_stylesheet ];
622  }
623  else if(typeof xinha_stylesheet == 'object')
624  {
625    xinha_config.pageStyleSheets = xinha_stylesheet ;
626  }
627   
628
629  /** STEP 4 ***************************************************************
630   * We first create editors for the textareas.
631   *
632   * You can do this in two ways, either
633   *
634   *   xinha_editors   = Xinha.makeEditors(xinha_editors, xinha_config, xinha_plugins);
635   *
636   * if you want all the editor objects to use the same set of plugins, OR;
637   *
638   *   xinha_editors = Xinha.makeEditors(xinha_editors, xinha_config);
639   *   xinha_editors.myTextArea.registerPlugins(['Stylist']);
640   *   xinha_editors.anotherOne.registerPlugins(['CSS','SuperClean']);
641   *
642   * if you want to use a different set of plugins for one or more of the
643   * editors.
644   ************************************************************************/
645
646  if(typeof xinha_plugins_specific == 'function')
647  {
648    xinha_editors   = Xinha.makeEditors(xinha_editors, xinha_config);
649   
650    // To make it clearer for people provide a "remove" function on the array
651    PluginsArray = function(arr)
652    {
653      PluginsArray.parentConstructor.call(this);
654      for(var i = 0; i < arr.length; i++) this.push(arr[i]);
655    };
656   
657    // Note important, extending must happen before adding more functions
658    // to the prototype.
659    Xinha.extend(PluginsArray, Array);
660   
661    PluginsArray.prototype.remove = function(p)
662    {
663      if(typeof p == 'object')
664      {
665        for(var i = 0; i < p.length; i++)
666        {
667          this.remove(p[i]);
668        }
669       
670        return this;
671      }
672     
673      var idx = -1;
674      for(var i = 0; i < this.length; i++)
675      {
676       
677        if(p == this[i]) { idx = i; break; }       
678       
679      }
680     
681      if(idx >= 0)
682      {
683        this.splice(idx, 1);
684      }
685     
686      return this;
687    };
688   
689    PluginsArray.prototype.only    = function(p)
690    {
691      // Enpty ourself
692      if(this.length)
693      {
694        this.splice(0,this.length);
695      }
696     
697      // Add them in
698      if(typeof p == 'string')
699      {
700        p = [ p ];
701      }
702     
703      for(var i = 0; i < p.length; i++)
704      {
705        this.push(p[i]);
706      }
707    }
708   
709    for(var i in xinha_editors)
710    {
711      var specific_plugins = new PluginsArray(xinha_plugins);
712      var plugins_returned = xinha_plugins_specific(specific_plugins, xinha_editors[i]._textArea, xinha_editors[i]);
713     
714      // Note that if they don't return anything, it will probably still work
715      // due to references and such
716      if(typeof plugins_returned == 'object')
717      {
718        specific_plugins = plugins_returned;
719      }
720      xinha_editors[i].registerPlugins(parse_plugins(specific_plugins));
721    }
722  }
723  else
724  {
725    xinha_editors   = Xinha.makeEditors(xinha_editors, xinha_config, xinha_plugins);
726  }
727 
728
729  /** STEP 5 ***************************************************************
730   * If you want to change the configuration variables of any of the
731   * editors,  this is the place to do that, for example you might want to
732   * change the width and height of one of the editors, like this...
733   *
734   *   xinha_editors.myTextArea.config.width  = '640px';
735   *   xinha_editors.myTextArea.config.height = '480px';
736   *
737   ************************************************************************/
738 
739  if(typeof xinha_config_specific == 'function')
740  {
741    for(var i in xinha_editors)
742    {
743      var returned_config =  xinha_config_specific(xinha_editors[i].config, xinha_editors[i]._textArea, xinha_editors[i]);
744     
745      // If the function doesn't return an object, it will stil work probably
746      // as xinha_config.XXX in the function will be working on a reference
747      if(typeof returned_config == 'object')
748      {
749        xinha_editors[i].config = returned_config;
750      }
751    }
752  }
753 
754 
755  /** STEP 6 ***************************************************************
756   * Finally we "start" the editors, this turns the textareas into
757   * Xinha editors.
758   ************************************************************************/
759
760  Xinha.startEditors(xinha_editors);
761}
762
763Xinha.addOnloadHandler(xinha_init); // this executes the xinha_init function on page load
764                                     // and does not interfere with window.onload properties set by other scripts
765
766
767
Note: See TracBrowser for help on using the repository browser.