[ Index ]
 

Code source de PHP NUKE 7.9

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/modules/Journal/ -> editor.js (source)

   1  //

   2  // htmlArea v2.03 - Copyright (c) 2002 interactivetools.com, inc.

   3  // This copyright notice MUST stay intact for use (see license.txt).

   4  //

   5  // A free WYSIWYG editor replacement for <textarea> fields.

   6  // For full source code and docs, visit http://www.interactivetools.com/

   7  //

   8  
   9  // write out styles for UI buttons

  10  document.write('<style type="text/css">\n');
  11  document.write('.btn     { width: 22px; height: 22px; border: 1px solid buttonface; margin: 0; padding: 0; }\n');
  12  document.write('.btnOver { width: 22px; height: 22px; border: 1px outset; }\n');
  13  document.write('.btnDown { width: 22px; height: 22px; border: 1px inset; background-color: buttonhighlight; }\n');
  14  document.write('.btnNA   { width: 22px; height: 22px; border: 1px solid buttonface; filter: alpha(opacity=25); }\n');
  15  document.write('.cMenu     { background-color: threedface; color: menutext; cursor: Default; font-family: MS Sans Serif; font-size: 8pt; padding: 2 12 2 16; }');
  16  document.write('.cMenuOver { background-color: highlight; color: highlighttext; cursor: Default; font-family: MS Sans Serif; font-size: 8pt; padding: 2 12 2 16; }');
  17  document.write('.cMenuDivOuter { background-color: threedface; height: 9 }');
  18  document.write('.cMenuDivInner { margin: 0 4 0 4; border-width: 1; border-style: solid; border-color: threedshadow threedhighlight threedhighlight threedshadow; }');
  19  document.write('</style>\n');
  20  
  21  
  22  /* ---------------------------------------------------------------------- *\

  23    Function    : editor_defaultConfig

  24    Description : default configuration settings for wysiwyg editor

  25  \* ---------------------------------------------------------------------- */
  26  
  27  function editor_defaultConfig(objname) {
  28  
  29  this.version = "2.03"
  30  
  31  this.width =  "auto";
  32  this.height = "auto";
  33  this.bodyStyle = 'background-color: #FFFFFF; font-family: "Verdana"; font-size: x-small;';
  34  this.imgURL = _editor_url + 'images/';
  35  this.debug  = 0;
  36  
  37  this.replaceNextlines = 0; // replace nextlines from spaces (on output)

  38  this.plaintextInput = 0;   // replace nextlines with breaks (on input)

  39  
  40  this.toolbar = [
  41      ['fontname'],
  42      ['fontsize'],
  43  //    ['fontstyle'],

  44  //    ['linebreak'],

  45      ['bold','italic','underline','separator'],
  46  //  ['strikethrough','subscript','superscript','separator'],

  47      ['justifyleft','justifycenter','justifyright','separator'],
  48      ['OrderedList','UnOrderedList','Outdent','Indent','separator'],
  49      ['forecolor','separator'],
  50      ['HorizontalRule','Createlink','InsertImage','InsertTable','htmlmode','separator'],
  51  //  ['custom1','custom2','custom3','separator'],

  52      ['popupeditor','about']];
  53  
  54  this.fontnames = {
  55      "Arial":           "arial, helvetica, sans-serif",
  56      "Courier New":     "courier new, courier, mono",
  57      "Georgia":         "Georgia, Times New Roman, Times, Serif",
  58      "Tahoma":          "Tahoma, Arial, Helvetica, sans-serif",
  59      "Times New Roman": "times new roman, times, serif",
  60      "Verdana":         "Verdana, Arial, Helvetica, sans-serif",
  61      "impact":          "impact",
  62      "WingDings":       "WingDings"};
  63  
  64  this.fontsizes = {
  65      "1 (8 pt)":  "1",
  66      "2 (10 pt)": "2",
  67      "3 (12 pt)": "3",
  68      "4 (14 pt)": "4",
  69      "5 (18 pt)": "5",
  70      "6 (24 pt)": "6",
  71      "7 (36 pt)": "7"
  72    };
  73  
  74  //this.stylesheet = "http://www.domain.com/sample.css"; // full URL to stylesheet

  75  
  76  this.fontstyles = [     // make sure these exist in the header of page the content is being display as well in or they won't work!
  77  //    { name: "headline",     className: "headline",  classStyle: "font-family: arial black, arial; font-size: 28px; letter-spacing: -2px;" },

  78  //    { name: "arial red",    className: "headline2", classStyle: "font-family: arial black, arial; font-size: 12px; letter-spacing: -2px; color:red" },

  79  //    { name: "verdana blue", className: "headline4", classStyle: "font-family: verdana; font-size: 18px; letter-spacing: -2px; color:blue" },

  80  ];
  81  
  82  this.btnList = {
  83      // buttonName:    commandID,               title,                onclick,                   image,             

  84      "bold":           ['Bold',                 'Bold',               'editor_action(this.id)',  'ed_format_bold.gif'],
  85      "italic":         ['Italic',               'Italic',             'editor_action(this.id)',  'ed_format_italic.gif'],
  86      "underline":      ['Underline',            'Underline',          'editor_action(this.id)',  'ed_format_underline.gif'],
  87      "strikethrough":  ['StrikeThrough',        'Strikethrough',      'editor_action(this.id)',  'ed_format_strike.gif'],
  88      "subscript":      ['SubScript',            'Subscript',          'editor_action(this.id)',  'ed_format_sub.gif'],
  89      "superscript":    ['SuperScript',          'Superscript',        'editor_action(this.id)',  'ed_format_sup.gif'],
  90      "justifyleft":    ['JustifyLeft',          'Justify Left',       'editor_action(this.id)',  'ed_align_left.gif'],
  91      "justifycenter":  ['JustifyCenter',        'Justify Center',     'editor_action(this.id)',  'ed_align_center.gif'],
  92      "justifyright":   ['JustifyRight',         'Justify Right',      'editor_action(this.id)',  'ed_align_right.gif'],
  93      "orderedlist":    ['InsertOrderedList',    'Ordered List',       'editor_action(this.id)',  'ed_list_num.gif'],
  94      "unorderedlist":  ['InsertUnorderedList',  'Bulleted List',      'editor_action(this.id)',  'ed_list_bullet.gif'],
  95      "outdent":        ['Outdent',              'Decrease Indent',    'editor_action(this.id)',  'ed_indent_less.gif'],
  96      "indent":         ['Indent',               'Increase Indent',    'editor_action(this.id)',  'ed_indent_more.gif'],
  97      "forecolor":      ['ForeColor',            'Font Color',         'editor_action(this.id)',  'ed_color_fg.gif'],
  98   //   "backcolor":      ['BackColor',            'Disabled',   '',  'ed_color_bg.gif'],

  99      "horizontalrule": ['InsertHorizontalRule', 'Horizontal Rule',    'editor_action(this.id)',  'ed_hr.gif'],
 100      "createlink":     ['CreateLink',           'Insert Web Link',    'editor_action(this.id)',  'ed_link.gif'],
 101      "insertimage":    ['InsertImage',          'Insert Image',       'editor_action(this.id)',  'ed_image.gif'],
 102      "inserttable":    ['InsertTable',          'Insert Table',       'editor_action(this.id)',  'insert_table.gif'],
 103      "htmlmode":       ['HtmlMode',             'View HTML Source',   'editor_setmode(\''+objname+'\')', 'ed_html.gif'],
 104      "popupeditor":    ['popupeditor',          'Enlarge Editor',     'editor_action(this.id)',  'fullscreen_maximize.gif'],
 105      "about":          ['about',                'About this editor',  'editor_about(\''+objname+'\')',  'ed_about.gif'],
 106  
 107      // Add custom buttons here:

 108      "custom1":           ['custom1',         'Purpose of button 1',  'editor_action(this.id)',  'ed_custom.gif'],
 109      "custom2":           ['custom2',         'Purpose of button 2',  'editor_action(this.id)',  'ed_custom.gif'],
 110      "custom3":           ['custom3',         'Purpose of button 3',  'editor_action(this.id)',  'ed_custom.gif'],
 111     // end: custom buttons

 112  
 113      "help":           ['showhelp',             'Help using editor',  'editor_action(this.id)',  'ed_help.gif']};
 114  
 115  
 116  }
 117  
 118  /* ---------------------------------------------------------------------- *\

 119    Function    : editor_generate

 120    Description : replace textarea with wysiwyg editor

 121    Usage       : editor_generate("textarea_id",[height],[width]);

 122    Arguments   : objname - ID of textarea to replace

 123                  w       - width of wysiwyg editor

 124                  h       - height of wysiwyg editor

 125  \* ---------------------------------------------------------------------- */
 126  
 127  
 128  function editor_generate(objname,userConfig) {
 129  
 130    // Default Settings

 131    var config = new editor_defaultConfig(objname);
 132    if (userConfig) { 
 133      for (var thisName in userConfig) {
 134        if (userConfig[thisName]) { config[thisName] = userConfig[thisName]; }
 135      }
 136    }
 137    document.all[objname].config = config;                  // store config settings

 138  
 139    // set size to specified size or size of original object

 140    var obj    = document.all[objname];
 141    if (!config.width || config.width == "auto") {
 142      if      (obj.style.width) { config.width = obj.style.width; }      // use css style

 143      else if (obj.cols)        { config.width = (obj.cols * 8) + 22; }  // col width + toolbar

 144      else                      { config.width = '100%'; }               // default

 145    }
 146    if (!config.height || config.height == "auto") {
 147      if      (obj.style.height) { config.height = obj.style.height; }   // use css style

 148      else if (obj.rows)         { config.height = obj.rows * 17 }       // row height

 149      else                       { config.height = '200'; }              // default

 150    }
 151  
 152    var tblOpen  = '<table border=0 cellspacing=0 cellpadding=0 style="float: left;"  unselectable="on"><tr><td style="border: none; padding: 1 0 0 0"><nobr>';
 153    var tblClose = '</nobr></td></tr></table>\n';
 154  
 155    // build button toolbar

 156  
 157    var toolbar = '';
 158    var btnGroup, btnItem, aboutEditor;
 159    for (var btnGroup in config.toolbar) {
 160  
 161      // linebreak

 162      if (config.toolbar[btnGroup].length == 1 &&
 163          config.toolbar[btnGroup][0].toLowerCase() == "linebreak") {
 164        toolbar += '<br clear="all">';
 165        continue;
 166      }
 167  
 168      toolbar += tblOpen;
 169      for (var btnItem in config.toolbar[btnGroup]) {
 170        var btnName = config.toolbar[btnGroup][btnItem].toLowerCase();
 171  
 172        // fontname

 173        if (btnName == "fontname") {
 174          toolbar += '<select id="_' +objname+ '_FontName" onChange="editor_action(this.id)" unselectable="on" style="margin: 1 2 0 2; font-size: 12px;">';
 175          for (var fontname in config.fontnames) {
 176            toolbar += '<option value="' +config.fontnames[fontname]+ '">' +fontname+ '</option>'
 177          }
 178          toolbar += '</select>';
 179          continue;
 180        }
 181  
 182        // fontsize

 183        if (btnName == "fontsize") {
 184          toolbar += '<select id="_' +objname+ '_FontSize" onChange="editor_action(this.id)" unselectable="on" style="margin: 1 2 0 0; font-size: 12px;">';
 185          for (var fontsize in config.fontsizes) {
 186            toolbar += '<option value="' +config.fontsizes[fontsize]+ '">' +fontsize+ '</option>'
 187          }
 188          toolbar += '</select>\n';
 189          continue;
 190        }
 191  
 192        // font style

 193        if (btnName == "fontstyle") {
 194          toolbar += '<select id="_' +objname+ '_FontStyle" onChange="editor_action(this.id)" unselectable="on" style="margin: 1 2 0 0; font-size: 12px;">';
 195          + '<option value="">Font Style</option>';
 196          for (var i in config.fontstyles) {
 197            var fontstyle = config.fontstyles[i];
 198            toolbar += '<option value="' +fontstyle.className+ '">' +fontstyle.name+ '</option>'
 199          }
 200          toolbar += '</select>';
 201          continue;
 202        }
 203  
 204        // separator

 205        if (btnName == "separator") {
 206          toolbar += '<span style="border: 1px inset; width: 1px; font-size: 16px; height: 16px; margin: 0 3 0 3"></span>';
 207          continue;
 208        }
 209  
 210        // buttons

 211        var btnObj = config.btnList[btnName];
 212        if (btnName == 'linebreak') { alert("htmlArea error: 'linebreak' must be in a subgroup by itself, not with other buttons.\n\nhtmlArea wysiwyg editor not created."); return; }
 213        if (!btnObj) { alert("htmlArea error: button '" +btnName+ "' not found in button list when creating the wysiwyg editor for '"+objname+"'.\nPlease make sure you entered the button name correctly.\n\nhtmlArea wysiwyg editor not created."); return; }
 214        var btnCmdID   = btnObj[0];
 215        var btnTitle   = btnObj[1];
 216        var btnOnClick = btnObj[2];
 217        var btnImage   = btnObj[3];
 218        toolbar += '<button title="' +btnTitle+ '" id="_' +objname+ '_' +btnCmdID+ '" class="btn" onClick="' +btnOnClick+ '" onmouseover="if(this.className==\'btn\'){this.className=\'btnOver\'}" onmouseout="if(this.className==\'btnOver\'){this.className=\'btn\'}" unselectable="on"><img src="' +config.imgURL + btnImage+ '" border=0 unselectable="on"></button>';
 219  
 220  
 221      } // end of button sub-group

 222      toolbar += tblClose;
 223    } // end of entire button set

 224  
 225    // build editor

 226  
 227    var editor = '<span id="_editor_toolbar"><table border=0 cellspacing=0 cellpadding=0 bgcolor="buttonface" style="padding: 1 0 0 2" width=' + config.width + ' unselectable="on"><tr><td>\n'
 228    + toolbar
 229    + '</td></tr></table>\n'
 230    + '</td></tr></table></span>\n'
 231    + '<textarea ID="_' +objname + '_editor" style="width:' +config.width+ '; height:' +config.height+ '; margin-top: -1px; margin-bottom: -1px;" wrap=soft></textarea>';
 232  
 233    // add context menu

 234    editor += '<div id="_' +objname + '_cMenu" style="position: absolute; visibility: hidden;"></div>';
 235  
 236    //  hide original textarea and insert htmlarea after it

 237    if (!config.debug) { document.all[objname].style.display = "none"; }
 238  
 239    if (config.plaintextInput) {     // replace nextlines with breaks
 240      var contents = document.all[objname].value;
 241      contents = contents.replace(/\r\n/g, '<br>');
 242      contents = contents.replace(/\n/g, '<br>');
 243      contents = contents.replace(/\r/g, '<br>');
 244      document.all[objname].value = contents;
 245    }
 246  
 247    // insert wysiwyg

 248    document.all[objname].insertAdjacentHTML('afterEnd', editor)
 249  
 250    // convert htmlarea from textarea to wysiwyg editor

 251    editor_setmode(objname, 'init');
 252  
 253    // call filterOutput when user submits form

 254    for (var idx=0; idx < document.forms.length; idx++) {
 255      var r = document.forms[idx].attachEvent('onsubmit', function() { editor_filterOutput(objname); });
 256      if (!r) { alert("Error attaching event to form!"); }
 257    }
 258  
 259  return true;
 260  
 261  }
 262  
 263  /* ---------------------------------------------------------------------- *\

 264    Function    : editor_action

 265    Description : perform an editor command on selected editor content

 266    Usage       :

 267    Arguments   : button_id - button id string with editor and action name

 268  \* ---------------------------------------------------------------------- */
 269  
 270  function editor_action(button_id) {
 271  
 272    // split up button name into "editorID" and "cmdID"

 273    var BtnParts = Array();
 274    BtnParts = button_id.split("_");
 275    var objname    = button_id.replace(/^_(.*)_[^_]*$/, '$1');
 276    var cmdID      = BtnParts[ BtnParts.length-1 ];
 277    var button_obj = document.all[button_id];
 278    var editor_obj = document.all["_" +objname + "_editor"];
 279    var config     = document.all[objname].config;
 280  
 281    // help popup

 282    if (cmdID == 'showhelp') {
 283      window.open(_editor_url + "popups/editor_help.html", 'EditorHelp');
 284      return;
 285    }
 286  
 287    // popup editor

 288    if (cmdID == 'popupeditor') {
 289      window.open(_editor_url + "popups/fullscreen.html?"+objname,
 290                  'FullScreen',
 291                  'toolbar=no,location=no,directories=no,status=yes,menubar=no,scrollbars=yes,resizable=yes,width=640,height=480');
 292      return;
 293    }
 294  
 295    // check editor mode (don't perform actions in textedit mode)

 296    if (editor_obj.tagName.toLowerCase() == 'textarea') { return; }
 297  
 298    var editdoc = editor_obj.contentWindow.document;
 299    editor_focus(editor_obj);
 300  
 301    // get index and value for pulldowns

 302    var idx = button_obj.selectedIndex;
 303    var val = (idx != null) ? button_obj[ idx ].value : null;
 304  
 305    if (0) {}   // use else if for easy cutting and pasting

 306  
 307    //

 308    // CUSTOM BUTTONS START HERE

 309    //

 310  
 311    // Custom1

 312    else if (cmdID == 'custom1') {
 313      alert("Hello, I am custom button 1!");
 314    }
 315  
 316    // Custom2

 317    else if (cmdID == 'custom2') {  // insert some text from a popup window
 318      var myTitle = "This is a custom title";
 319      var myText = showModalDialog(_editor_url + "popups/custom2.html",
 320                                   myTitle,      // str or obj specified here can be read from dialog as "window.dialogArguments"
 321                                   "resizable: yes; help: no; status: no; scroll: no; ");
 322      if (myText) { editor_insertHTML(objname, myText); }
 323    }
 324  
 325    // Custom3

 326    else if (cmdID == 'custom3') {  // insert some text
 327      editor_insertHTML(objname, "It's easy to add buttons that insert text!");
 328    }
 329  
 330    //

 331    // END OF CUSTOM BUTTONS

 332    //

 333  
 334    // FontName

 335    else if (cmdID == 'FontName' && val) {
 336      editdoc.execCommand(cmdID,0,val);
 337    }
 338  
 339    // FontSize

 340    else if (cmdID == 'FontSize' && val) {
 341      editdoc.execCommand(cmdID,0,val);
 342    }
 343  
 344    // FontStyle (change CSS className)

 345    else if (cmdID == 'FontStyle' && val) {
 346      editdoc.execCommand('RemoveFormat');
 347      editdoc.execCommand('FontName',0,'636c6173734e616d6520706c616365686f6c646572');
 348      var fontArray = editdoc.all.tags("FONT");
 349      for (i=0; i<fontArray.length; i++) {
 350        if (fontArray[i].face == '636c6173734e616d6520706c616365686f6c646572') {
 351          fontArray[i].face = "";
 352          fontArray[i].className = val;
 353          fontArray[i].outerHTML = fontArray[i].outerHTML.replace(/face=['"]+/, "");
 354          }
 355      }
 356      button_obj.selectedIndex =0;
 357    }
 358  
 359    // fgColor and bgColor

 360      else if (cmdID == 'ForeColor') {
 361      var oldcolor = _dec_to_rgb(editdoc.queryCommandValue(cmdID));
 362      var newcolor = showModalDialog(_editor_url + "popups/select_color.html", oldcolor, "resizable: no; help: no; status: no; scroll: no;");
 363      if (newcolor != null) { editdoc.execCommand(cmdID, false, "#"+newcolor); }
 364    }
 365  
 366    // execute command for buttons - if we didn't catch the cmdID by here we'll assume it's a

 367    // commandID and pass it to execCommand().   See http://msdn.microsoft.com/workshop/author/dhtml/reference/commandids.asp

 368    else {
 369      // subscript & superscript, disable one before enabling the other

 370      if (cmdID.toLowerCase() == 'subscript' && editdoc.queryCommandState('superscript')) { editdoc.execCommand('superscript'); }
 371      if (cmdID.toLowerCase() == 'superscript' && editdoc.queryCommandState('subscript')) { editdoc.execCommand('subscript'); }
 372  
 373      // insert link

 374      if (cmdID.toLowerCase() == 'createlink'){
 375        editdoc.execCommand(cmdID,1);
 376      }
 377  
 378      // insert image

 379      else if (cmdID.toLowerCase() == 'insertimage'){
 380        showModalDialog(_editor_url + "popups/insert_image.html", editdoc, "resizable: no; help: no; status: no; scroll: no; ");
 381      }
 382  
 383      // insert table

 384      else if (cmdID.toLowerCase() == 'inserttable'){
 385        showModalDialog(_editor_url + "popups/insert_table.html?"+objname,
 386                                   window,
 387                                   "resizable: yes; help: no; status: no; scroll: no; ");
 388      }
 389  
 390      // all other commands microsoft Command Identifiers

 391      else { editdoc.execCommand(cmdID); }
 392    }
 393  
 394    editor_event(objname);
 395  }
 396  
 397  /* ---------------------------------------------------------------------- *\

 398    Function    : editor_event

 399    Description : called everytime an editor event occurs

 400    Usage       : editor_event(objname, runDelay, eventName)

 401    Arguments   : objname - ID of textarea to replace

 402                  runDelay: -1 = run now, no matter what

 403                            0  = run now, if allowed

 404                          1000 = run in 1 sec, if allowed at that point

 405  \* ---------------------------------------------------------------------- */
 406  
 407  function editor_event(objname,runDelay) {
 408    var config = document.all[objname].config;
 409    var editor_obj  = document.all["_" +objname+  "_editor"];       // html editor object

 410    if (runDelay == null) { runDelay = 0; }
 411    var editdoc;
 412    var editEvent = editor_obj.contentWindow ? editor_obj.contentWindow.event : event;
 413  
 414    // catch keypress events

 415      if (editEvent && editEvent.keyCode) {
 416        var ord       = editEvent.keyCode;    // ascii order of key pressed

 417        var ctrlKey   = editEvent.ctrlKey;
 418        var altKey    = editEvent.altKey;
 419        var shiftKey  = editEvent.shiftKey;
 420  
 421        if (ord == 16) { return; }  // ignore shift key by itself

 422        if (ord == 17) { return; }  // ignore ctrl key by itself

 423        if (ord == 18) { return; }  // ignore alt key by itself

 424  
 425  
 426         // cancel ENTER key and insert <BR> instead

 427  //       if (ord == 13 && editEvent.type == 'keypress') {

 428  //         editEvent.returnValue = false;

 429  //         editor_insertHTML(objname, "<br>");

 430  //         return;

 431  //       }

 432  
 433        if (ctrlKey && (ord == 122 || ord == 90)) {     // catch ctrl-z (UNDO)
 434  //      TODO: Add our own undo/redo functionality

 435  //        editEvent.cancelBubble = true;

 436          return;
 437        }
 438        if ((ctrlKey && (ord == 121 || ord == 89)) ||
 439            ctrlKey && shiftKey && (ord == 122 || ord == 90)) {     // catch ctrl-y, ctrl-shift-z (REDO)
 440  //      TODO: Add our own undo/redo functionality

 441          return;
 442        }
 443      }
 444  
 445    // setup timer for delayed updates (some events take time to complete)

 446    if (runDelay > 0) { return setTimeout(function(){ editor_event(objname); }, runDelay); }
 447  
 448    // don't execute more than 3 times a second (eg: too soon after last execution)

 449    if (this.tooSoon == 1 && runDelay >= 0) { this.queue = 1; return; } // queue all but urgent events

 450    this.tooSoon = 1;
 451    setTimeout(function(){
 452      this.tooSoon = 0;
 453      if (this.queue) { editor_event(objname,-1); };
 454      this.queue = 0;
 455      }, 333);  // 1/3 second

 456  
 457  
 458    editor_updateOutput(objname);
 459    editor_updateToolbar(objname);
 460  
 461  }
 462  
 463  /* ---------------------------------------------------------------------- *\

 464    Function    : editor_updateToolbar

 465    Description : update toolbar state

 466    Usage       :

 467    Arguments   : objname - ID of textarea to replace

 468                  action  - enable, disable, or update (default action)

 469  \* ---------------------------------------------------------------------- */
 470  
 471  function editor_updateToolbar(objname,action) {
 472    var config = document.all[objname].config;
 473    var editor_obj  = document.all["_" +objname+  "_editor"];
 474  
 475    // disable or enable toolbar

 476  
 477    if (action == "enable" || action == "disable") {
 478      var tbItems = new Array('FontName','FontSize','FontStyle');                           // add pulldowns

 479      for (var btnName in config.btnList) { tbItems.push(config.btnList[btnName][0]); } // add buttons

 480  
 481      for (var idxN in tbItems) {
 482        var cmdID = tbItems[idxN].toLowerCase();
 483        var tbObj = document.all["_" +objname+ "_" +tbItems[idxN]];
 484        if (cmdID == "htmlmode" || cmdID == "about" || cmdID == "showhelp" || cmdID == "popupeditor") { continue; } // don't change these buttons

 485        if (tbObj == null) { continue; }
 486        var isBtn = (tbObj.tagName.toLowerCase() == "button") ? true : false;
 487  
 488        if (action == "enable")  { tbObj.disabled = false; if (isBtn) { tbObj.className = 'btn' }}
 489        if (action == "disable") { tbObj.disabled = true;  if (isBtn) { tbObj.className = 'btnNA' }}
 490      }
 491      return;
 492    }
 493  
 494    // update toolbar state

 495  
 496    if (editor_obj.tagName.toLowerCase() == 'textarea') { return; }   // don't update state in textedit mode

 497    var editdoc = editor_obj.contentWindow.document;
 498  
 499    // Set FontName pulldown

 500    var fontname_obj = document.all["_" +objname+ "_FontName"];
 501    if (fontname_obj) {
 502      var fontname = editdoc.queryCommandValue('FontName');
 503      if (fontname == null) { fontname_obj.value = null; }
 504      else {
 505        var found = 0;
 506        for (i=0; i<fontname_obj.length; i++) {
 507          if (fontname.toLowerCase() == fontname_obj[i].text.toLowerCase()) {
 508            fontname_obj.selectedIndex = i;
 509            found = 1;
 510          }
 511        }
 512        if (found != 1) { fontname_obj.value = null; }     // for fonts not in list

 513      }
 514    }
 515  
 516    // Set FontSize pulldown

 517    var fontsize_obj = document.all["_" +objname+ "_FontSize"];
 518    if (fontsize_obj) {
 519      var fontsize = editdoc.queryCommandValue('FontSize');
 520      if (fontsize == null) { fontsize_obj.value = null; }
 521      else {
 522        var found = 0;
 523        for (i=0; i<fontsize_obj.length; i++) {
 524          if (fontsize == fontsize_obj[i].value) { fontsize_obj.selectedIndex = i; found=1; }
 525        }
 526        if (found != 1) { fontsize_obj.value = null; }     // for sizes not in list

 527      }
 528    }
 529  
 530    // Set FontStyle pulldown

 531    var classname_obj = document.all["_" +objname+ "_FontStyle"];
 532    if (classname_obj) {
 533      var curRange = editdoc.selection.createRange();
 534  
 535      // check element and element parents for class names

 536      var pElement;
 537      if (curRange.length) { pElement = curRange[0]; }              // control tange

 538      else                 { pElement = curRange.parentElement(); } // text range

 539      while (pElement && !pElement.className) { pElement = pElement.parentElement; }  // keep going up

 540  
 541      var thisClass = pElement ? pElement.className.toLowerCase() : "";
 542      if (!thisClass && classname_obj.value) { classname_obj.value = null; }
 543      else {
 544        var found = 0;
 545        for (i=0; i<classname_obj.length; i++) {
 546          if (thisClass == classname_obj[i].value.toLowerCase()) {
 547            classname_obj.selectedIndex = i;
 548            found=1;
 549          }
 550        }
 551        if (found != 1) { classname_obj.value = null; }     // for classes not in list

 552      }
 553    }
 554  
 555    // update button states

 556    var IDList = Array('Bold','Italic','Underline','StrikeThrough','SubScript','SuperScript','JustifyLeft','JustifyCenter','JustifyRight','InsertOrderedList','InsertUnorderedList');
 557    for (i=0; i<IDList.length; i++) {
 558      var btnObj = document.all["_" +objname+ "_" +IDList[i]];
 559      if (btnObj == null) { continue; }
 560      var cmdActive = editdoc.queryCommandState( IDList[i] );
 561  
 562      if (!cmdActive)  {                                  // option is OK
 563        if (btnObj.className != 'btn') { btnObj.className = 'btn'; }
 564        if (btnObj.disabled  != false) { btnObj.disabled = false; }
 565      } else if (cmdActive)  {                            // option already applied or mixed content
 566        if (btnObj.className != 'btnDown') { btnObj.className = 'btnDown'; }
 567        if (btnObj.disabled  != false)   { btnObj.disabled = false; }
 568      }
 569    }
 570  }
 571  
 572  /* ---------------------------------------------------------------------- *\

 573    Function    : editor_updateOutput

 574    Description : update hidden output field with data from wysiwg

 575  \* ---------------------------------------------------------------------- */
 576  
 577  function editor_updateOutput(objname) {
 578    var config     = document.all[objname].config;
 579    var editor_obj  = document.all["_" +objname+  "_editor"];       // html editor object

 580    var editEvent = editor_obj.contentWindow ? editor_obj.contentWindow.event : event;
 581    var isTextarea = (editor_obj.tagName.toLowerCase() == 'textarea');
 582    var editdoc = isTextarea ? null : editor_obj.contentWindow.document;
 583  
 584    // get contents of edit field

 585    var contents;
 586    if (isTextarea) { contents = editor_obj.value; }
 587    else            { contents = editdoc.body.innerHTML; }
 588  
 589    // check if contents has changed since the last time we ran this routine

 590    if (config.lastUpdateOutput && config.lastUpdateOutput == contents) { return; }
 591    else { config.lastUpdateOutput = contents; }
 592  
 593    // update hidden output field

 594    document.all[objname].value = contents;
 595  
 596  }
 597  
 598  /* ---------------------------------------------------------------------- *\

 599    Function    : editor_filterOutput

 600    Description :

 601  \* ---------------------------------------------------------------------- */
 602  
 603  function editor_filterOutput(objname) {
 604    editor_updateOutput(objname);
 605    var contents = document.all[objname].value;
 606    var config   = document.all[objname].config;
 607  
 608    // ignore blank contents

 609    if (contents.toLowerCase() == '<p>&nbsp;</p>') { contents = ""; }
 610  
 611    // filter tag - this code is run for each HTML tag matched

 612    var filterTag = function(tagBody,tagName,tagAttr) {
 613      tagName = tagName.toLowerCase();
 614      var closingTag = (tagBody.match(/^<\//)) ? true : false;
 615  
 616      // fix placeholder URLS - remove absolute paths that IE adds

 617      if (tagName == 'img') { tagBody = tagBody.replace(/(src\s*=\s*.)[^*]*(\*\*\*)/, "$1$2"); }
 618      if (tagName == 'a')   { tagBody = tagBody.replace(/(href\s*=\s*.)[^*]*(\*\*\*)/, "$1$2"); }
 619  
 620      // add additional tag filtering here

 621  
 622      // convert to vbCode

 623  //    if      (tagName == 'b' || tagName == 'strong') {

 624  //      if (closingTag) { tagBody = "[/b]"; } else { tagBody = "[b]"; }

 625  //    }

 626  //    else if (tagName == 'i' || tagName == 'em') {

 627  //      if (closingTag) { tagBody = "[/i]"; } else { tagBody = "[i]"; }

 628  //    }

 629  //    else if (tagName == 'u') {

 630  //      if (closingTag) { tagBody = "[/u]"; } else { tagBody = "[u]"; }

 631  //    }

 632  //    else {

 633  //      tagBody = ""; // disallow all other tags!

 634  //    }

 635  
 636      return tagBody;
 637    };
 638  
 639    // match tags and call filterTag

 640    RegExp.lastIndex = 0;
 641      var matchTag = /<\/?(\w+)((?:[^'">]*|'[^']*'|"[^"]*")*)>/g;   // this will match tags, but still doesn't handle container tags (textarea, comments, etc)

 642  
 643    contents = contents.replace(matchTag, filterTag);
 644  
 645    // remove nextlines from output (if requested)

 646    if (config.replaceNextlines) { 
 647      contents = contents.replace(/\r\n/g, ' ');
 648      contents = contents.replace(/\n/g, ' ');
 649      contents = contents.replace(/\r/g, ' ');
 650    }
 651  
 652    // update output with filtered content

 653    document.all[objname].value = contents;
 654  
 655  }
 656  
 657  /* ---------------------------------------------------------------------- *\

 658    Function    : editor_setmode

 659    Description : change mode between WYSIWYG and HTML editor

 660    Usage       : editor_setmode(objname, mode);

 661    Arguments   : objname - button id string with editor and action name

 662                  mode      - init, textedit, or wysiwyg

 663  \* ---------------------------------------------------------------------- */
 664  
 665  function editor_setmode(objname, mode) {
 666    var config     = document.all[objname].config;
 667    var editor_obj = document.all["_" +objname + "_editor"];
 668  
 669    // wait until document is fully loaded

 670    if (document.readyState != 'complete') {
 671      setTimeout(function() { editor_setmode(objname,mode) }, 25);
 672      return;
 673    }
 674  
 675    // define different editors

 676    var TextEdit   = '<textarea ID="_' +objname + '_editor" style="width:' +editor_obj.style.width+ '; height:' +editor_obj.style.height+ '; margin-top: -1px; margin-bottom: -1px;"></textarea>';
 677    var RichEdit   = '<iframe ID="_' +objname+ '_editor"    style="width:' +editor_obj.style.width+ '; height:' +editor_obj.style.height+ ';"></iframe>';
 678  
 679   // src="' +_editor_url+ 'popups/blank.html"

 680  
 681    //

 682    // Switch to TEXTEDIT mode

 683    //

 684  
 685    if (mode == "textedit" || editor_obj.tagName.toLowerCase() == 'iframe') {
 686      config.mode = "textedit";
 687      var editdoc = editor_obj.contentWindow.document;
 688      var contents = editdoc.body.createTextRange().htmlText;
 689      editor_obj.outerHTML = TextEdit;
 690      editor_obj = document.all["_" +objname + "_editor"];
 691      editor_obj.value = contents;
 692      editor_event(objname);
 693  
 694      editor_updateToolbar(objname, "disable");  // disable toolbar items

 695  
 696      // set event handlers

 697      editor_obj.onkeydown   = function() { editor_event(objname); }
 698      editor_obj.onkeypress  = function() { editor_event(objname); }
 699      editor_obj.onkeyup     = function() { editor_event(objname); }
 700      editor_obj.onmouseup   = function() { editor_event(objname); }
 701      editor_obj.ondrop      = function() { editor_event(objname, 100); }     // these events fire before they occur

 702      editor_obj.oncut       = function() { editor_event(objname, 100); }
 703      editor_obj.onpaste     = function() { editor_event(objname, 100); }
 704      editor_obj.onblur      = function() { editor_event(objname, -1); }
 705  
 706      editor_updateOutput(objname);
 707      editor_focus(editor_obj);
 708    }
 709  
 710    //

 711    // Switch to WYSIWYG mode

 712    //

 713  
 714    else {
 715      config.mode = "wysiwyg";
 716      var contents = editor_obj.value;
 717      if (mode == 'init') { contents = document.all[objname].value; } // on init use original textarea content

 718  
 719      // create editor

 720      editor_obj.outerHTML = RichEdit;
 721      editor_obj = document.all["_" +objname + "_editor"];
 722  
 723      // get iframe document object

 724  
 725      // create editor contents (and default styles for editor)

 726      var html = "";
 727      html += '<html><head>\n';
 728      if (config.stylesheet) {
 729        html += '<link href="' +config.stylesheet+ '" rel="stylesheet" type="text/css">\n';
 730      }
 731      html += '<style>\n';
 732      html += 'body {' +config.bodyStyle+ '} \n';
 733      for (var i in config.fontstyles) {
 734        var fontstyle = config.fontstyles[i];
 735        if (fontstyle.classStyle) {
 736          html += '.' +fontstyle.className+ ' {' +fontstyle.classStyle+ '}\n';
 737        }
 738      }
 739      html += '</style>\n'
 740        + '</head>\n'
 741        + '<body contenteditable="true" topmargin=1 leftmargin=1'
 742  
 743  // still working on this

 744  //      + ' oncontextmenu="parent.editor_cMenu_generate(window,\'' +objname+ '\');"'

 745        +'>'
 746        + contents
 747        + '</body>\n'
 748        + '</html>\n';
 749  
 750      // write to editor window

 751      var editdoc = editor_obj.contentWindow.document;
 752  
 753      editdoc.open();
 754      editdoc.write(html);
 755      editdoc.close();
 756  
 757      editor_updateToolbar(objname, "enable");  // enable toolbar items

 758  
 759      // store objname under editdoc

 760      editdoc.objname = objname;
 761  
 762      // set event handlers

 763      editdoc.onkeydown      = function() { editor_event(objname); }
 764      editdoc.onkeypress     = function() { editor_event(objname); }
 765      editdoc.onkeyup        = function() { editor_event(objname); }
 766      editdoc.onmouseup      = function() { editor_event(objname); }
 767      editdoc.body.ondrop    = function() { editor_event(objname, 100); }     // these events fire before they occur

 768      editdoc.body.oncut     = function() { editor_event(objname, 100); }
 769      editdoc.body.onpaste   = function() { editor_event(objname, 100); }
 770      editdoc.body.onblur    = function() { editor_event(objname, -1); }
 771  
 772      // bring focus to editor

 773      if (mode != 'init') {             // don't focus on page load, only on mode switch
 774        editor_focus(editor_obj);
 775      }
 776  
 777    }
 778  
 779    // Call update UI

 780    if (mode != 'init') {             // don't update UI on page load, only on mode switch
 781      editor_event(objname);
 782    }
 783  
 784  }
 785  
 786  /* ---------------------------------------------------------------------- *\

 787    Function    : editor_focus

 788    Description : bring focus to the editor

 789    Usage       : editor_focus(editor_obj);

 790    Arguments   : editor_obj - editor object

 791  \* ---------------------------------------------------------------------- */
 792  
 793  function editor_focus(editor_obj) {
 794  
 795    // check editor mode

 796    if (editor_obj.tagName.toLowerCase() == 'textarea') {         // textarea
 797      var myfunc = function() { editor_obj.focus(); };
 798      setTimeout(myfunc,100);                                     // doesn't work all the time without delay

 799    }
 800  
 801    else {                                                        // wysiwyg
 802      var editdoc = editor_obj.contentWindow.document;            // get iframe editor document object

 803      var editorRange = editdoc.body.createTextRange();           // editor range

 804      var curRange    = editdoc.selection.createRange();          // selection range

 805  
 806      if (curRange.length == null &&                              // make sure it's not a controlRange
 807          !editorRange.inRange(curRange)) {                       // is selection in editor range
 808        editorRange.collapse();                                   // move to start of range

 809        editorRange.select();                                     // select

 810        curRange = editorRange;
 811      }
 812    }
 813  
 814  }
 815  
 816  /* ---------------------------------------------------------------------- *\

 817    Function    : editor_about

 818    Description : display "about this editor" popup

 819  \* ---------------------------------------------------------------------- */
 820  
 821  function editor_about(objname) {
 822    showModalDialog(_editor_url + "popups/about.html", window, "resizable: yes; help: no; status: no; scroll: no; ");
 823  }
 824  
 825  /* ---------------------------------------------------------------------- *\

 826    Function    : _dec_to_rgb

 827    Description : convert dec color value to rgb hex

 828    Usage       : var hex = _dec_to_rgb('65535');   // returns FFFF00

 829    Arguments   : value   - dec value

 830  \* ---------------------------------------------------------------------- */
 831  
 832  function _dec_to_rgb(value) {
 833    var hex_string = "";
 834    for (var hexpair = 0; hexpair < 3; hexpair++) {
 835      var myByte = value & 0xFF;            // get low byte

 836      value >>= 8;                        // drop low byte

 837      var nybble2 = myByte & 0x0F;          // get low nybble (4 bits)

 838      var nybble1 = (myByte >> 4) & 0x0F;   // get high nybble

 839      hex_string += nybble1.toString(16); // convert nybble to hex

 840      hex_string += nybble2.toString(16); // convert nybble to hex

 841    }
 842    return hex_string.toUpperCase();
 843  }
 844  
 845  /* ---------------------------------------------------------------------- *\

 846    Function    : editor_insertHTML

 847    Description : insert string at current cursor position in editor.  If

 848                  two strings are specifed, surround selected text with them.

 849    Usage       : editor_insertHTML(objname, str1, [str2], reqSelection)

 850    Arguments   : objname - ID of textarea

 851                  str1 - HTML or text to insert

 852                  str2 - HTML or text to insert (optional argument)

 853                  reqSelection - (1 or 0) give error if no text selected

 854  \* ---------------------------------------------------------------------- */
 855  
 856  function editor_insertHTML(objname, str1,str2, reqSel) {
 857    var config     = document.all[objname].config;
 858    var editor_obj = document.all["_" +objname + "_editor"];    // editor object

 859    if (str1 == null) { str1 = ''; }
 860    if (str2 == null) { str2 = ''; }
 861  
 862    // for non-wysiwyg capable browsers just add to end of textbox

 863    if (document.all[objname] && editor_obj == null) {
 864      document.all[objname].focus();
 865      document.all[objname].value = document.all[objname].value + str1 + str2;
 866      return;
 867    }
 868  
 869    // error checking

 870    if (editor_obj == null) { return alert("Unable to insert HTML.  Invalid object name '" +objname+ "'."); }
 871  
 872    editor_focus(editor_obj);
 873  
 874    var tagname = editor_obj.tagName.toLowerCase();
 875    var sRange;
 876  
 877   // insertHTML for wysiwyg iframe

 878    if (tagname == 'iframe') {
 879      var editdoc = editor_obj.contentWindow.document;
 880      sRange  = editdoc.selection.createRange();
 881      var sHtml   = sRange.htmlText;
 882  
 883      // check for control ranges

 884      if (sRange.length) { return alert("Unable to insert HTML.  Try highlighting content instead of selecting it."); }
 885  
 886      // insert HTML

 887      var oldHandler = window.onerror;
 888      window.onerror = function() { alert("Unable to insert HTML for current selection."); return true; } // partial table selections cause errors

 889      if (sHtml.length) {                                 // if content selected
 890        if (str2) { sRange.pasteHTML(str1 +sHtml+ str2) } // surround

 891        else      { sRange.pasteHTML(str1); }             // overwrite

 892      } else {                                            // if insertion point only
 893        if (reqSel) { return alert("Unable to insert HTML.  You must select something first."); }
 894        sRange.pasteHTML(str1 + str2);                    // insert strings

 895      }
 896      window.onerror = oldHandler;
 897    }
 898  
 899    // insertHTML for plaintext textarea

 900    else if (tagname == 'textarea') {
 901      editor_obj.focus();
 902      sRange  = document.selection.createRange();
 903      var sText   = sRange.text;
 904  
 905      // insert HTML

 906      if (sText.length) {                                 // if content selected
 907        if (str2) { sRange.text = str1 +sText+ str2; }  // surround

 908        else      { sRange.text = str1; }               // overwrite

 909      } else {                                            // if insertion point only
 910        if (reqSel) { return alert("Unable to insert HTML.  You must select something first."); }
 911        sRange.text = str1 + str2;                        // insert strings

 912      }
 913    }
 914    else { alert("Unable to insert HTML.  Unknown object tag type '" +tagname+ "'."); }
 915  
 916    // move to end of new content

 917    sRange.collapse(false); // move to end of range

 918    sRange.select();        // re-select

 919  
 920  }
 921  
 922  /* ---------------------------------------------------------------------- *\

 923    Function    : editor_getHTML

 924    Description : return HTML contents of editor (in either wywisyg or html mode)

 925    Usage       : var myHTML = editor_getHTML('objname');

 926  \* ---------------------------------------------------------------------- */
 927  
 928  function editor_getHTML(objname) {
 929    var editor_obj = document.all["_" +objname + "_editor"];
 930    var isTextarea = (editor_obj.tagName.toLowerCase() == 'textarea');
 931  
 932    if (isTextarea) { return editor_obj.value; }
 933    else            { return editor_obj.contentWindow.document.body.innerHTML; }
 934  }
 935  
 936  /* ---------------------------------------------------------------------- *\

 937    Function    : editor_setHTML

 938    Description : set HTML contents of editor (in either wywisyg or html mode)

 939    Usage       : editor_setHTML('objname',"<b>html</b> <u>here</u>");

 940  \* ---------------------------------------------------------------------- */
 941  
 942  function editor_setHTML(objname, html) {
 943    var editor_obj = document.all["_" +objname + "_editor"];
 944    var isTextarea = (editor_obj.tagName.toLowerCase() == 'textarea');
 945  
 946    if (isTextarea) { editor_obj.value = html; }
 947    else            { editor_obj.contentWindow.document.body.innerHTML = html; }
 948  }
 949  
 950  /* ---------------------------------------------------------------------- *\

 951    Function    : editor_appendHTML

 952    Description : append HTML contents to editor (in either wywisyg or html mode)

 953    Usage       : editor_appendHTML('objname',"<b>html</b> <u>here</u>");

 954  \* ---------------------------------------------------------------------- */
 955  
 956  function editor_appendHTML(objname, html) {
 957    var editor_obj = document.all["_" +objname + "_editor"];
 958    var isTextarea = (editor_obj.tagName.toLowerCase() == 'textarea');
 959  
 960    if (isTextarea) { editor_obj.value += html; }
 961    else            { editor_obj.contentWindow.document.body.innerHTML += html; }
 962  }
 963  
 964  /* ---------------------------------------------------------------- */

 965  
 966  function _isMouseOver(obj,event) {       // determine if mouse is over object
 967    var mouseX    = event.clientX;
 968    var mouseY    = event.clientY;
 969  
 970    var objTop    = obj.offsetTop;
 971    var objBottom = obj.offsetTop + obj.offsetHeight;
 972    var objLeft   = obj.offsetLeft;
 973    var objRight  = obj.offsetLeft + obj.offsetWidth;
 974  
 975    if (mouseX >= objLeft && mouseX <= objRight &&
 976        mouseY >= objTop  && mouseY <= objBottom) { return true; }
 977  
 978    return false;
 979  }
 980  
 981  /* ---------------------------------------------------------------- */

 982  
 983  function editor_cMenu_generate(editorWin,objname) {
 984    var parentWin = window;
 985    editorWin.event.returnValue = false;  // cancel default context menu

 986  
 987    // define content menu options

 988    var cMenuOptions = [ // menu name, shortcut displayed, javascript code
 989      ['Cut', 'Ctrl-X', function() {}],
 990      ['Copy', 'Ctrl-C', function() {}],
 991      ['Paste', 'Ctrl-C', function() {}],
 992      ['Delete', 'DEL', function() {}],
 993      ['---', null, null],
 994      ['Select All', 'Ctrl-A', function() {}],
 995      ['Clear All', '', function() {}],
 996      ['---', null, null],
 997      ['About this editor...', '', function() {
 998        alert("about this editor");
 999      }]];
1000      editor_cMenu.options = cMenuOptions; // save options

1001  
1002    // generate context menu

1003    var cMenuHeader = ''
1004      + '<div id="_'+objname+'_cMenu" onblur="editor_cMenu(this);" oncontextmenu="return false;" onselectstart="return false"'
1005      + '  style="position: absolute; visibility: hidden; cursor: default; width: 167px; background-color: threedface;'
1006      + '         border: solid 1px; border-color: threedlightshadow threeddarkshadow threeddarkshadow threedlightshadow;">'
1007      + '<table border=0 cellspacing=0 cellpadding=0 width="100%" style="width: 167px; background-color: threedface; border: solid 1px; border-color: threedhighlight threedshadow threedshadow threedhighlight;">'
1008      + ' <tr><td colspan=2 height=1></td></tr>';
1009  
1010    var cMenuList = '';
1011  
1012    var cMenuFooter = ''
1013      + ' <tr><td colspan=2 height=1></td></tr>'
1014      + '</table></div>';
1015  
1016    for (var menuIdx in editor_cMenu.options) {
1017      var menuName = editor_cMenu.options[menuIdx][0];
1018      var menuKey  = editor_cMenu.options[menuIdx][1];
1019      var menuCode = editor_cMenu.options[menuIdx][2];
1020  
1021      // separator

1022      if (menuName == "---" || menuName == "separator") {
1023        cMenuList += ' <tr><td colspan=2 class="cMenuDivOuter"><div class="cMenuDivInner"></div></td></tr>';
1024      }
1025  
1026      // menu option

1027      else {
1028        cMenuList += '<tr class="cMenu" onMouseOver="editor_cMenu(this)" onMouseOut="editor_cMenu(this)" onClick="editor_cMenu(this, \'' +menuIdx+ '\',\'' +objname+ '\')">';
1029        if (menuKey) { cMenuList += ' <td align=left class="cMenu">' +menuName+ '</td><td align=right class="cMenu">' +menuKey+ '</td>'; }
1030        else         { cMenuList += ' <td colspan=2 class="cMenu">' +menuName+ '</td>'; }
1031        cMenuList += '</tr>';
1032      }
1033    }
1034  
1035    var cMenuHTML = cMenuHeader + cMenuList + cMenuFooter;
1036  
1037  
1038    document.all['_'+objname+'_cMenu'].outerHTML = cMenuHTML;
1039  
1040    editor_cMenu_setPosition(parentWin, editorWin, objname);
1041  
1042    parentWin['_'+objname+'_cMenu'].style.visibility = 'visible';
1043    parentWin['_'+objname+'_cMenu'].focus();
1044  
1045  }
1046  
1047  /* ---------------------------------------------------------------- */

1048  
1049  function editor_cMenu_setPosition(parentWin, editorWin, objname) {      // set object position that won't overlap window edge
1050    var event    = editorWin.event;
1051    var cMenuObj = parentWin['_'+objname+'_cMenu'];
1052    var mouseX   = event.clientX + parentWin.document.all['_'+objname+'_editor'].offsetLeft;
1053    var mouseY   = event.clientY + parentWin.document.all['_'+objname+'_editor'].offsetTop;
1054    var cMenuH   = cMenuObj.offsetHeight;
1055    var cMenuW   = cMenuObj.offsetWidth;
1056    var pageH    = document.body.clientHeight + document.body.scrollTop;
1057    var pageW    = document.body.clientWidth + document.body.scrollLeft;
1058  
1059    // set horzontal position

1060    if (mouseX + 5 + cMenuW > pageW) { var left = mouseX - cMenuW - 5; } // too far right

1061    else                            { var left = mouseX + 5; }
1062  
1063    // set vertical position

1064    if (mouseY + 5 + cMenuH > pageH) { var top = mouseY - cMenuH + 5; } // too far down

1065    else                            { var top = mouseY + 5; }
1066  
1067    cMenuObj.style.top = top;
1068    cMenuObj.style.left = left;
1069  
1070  }
1071  
1072  /* ---------------------------------------------------------------- */

1073  
1074  function editor_cMenu(obj,menuIdx,objname) {
1075    var action = event.type;
1076    if      (action == "mouseover" && !obj.disabled && obj.tagName.toLowerCase() == 'tr') {
1077      obj.className = 'cMenuOver';
1078      for (var i=0; i < obj.cells.length; i++) { obj.cells[i].className = 'cMenuOver'; }
1079    }
1080    else if (action == "mouseout" && !obj.disabled && obj.tagName.toLowerCase() == 'tr')  {
1081      obj.className = 'cMenu';
1082      for (var i=0; i < obj.cells.length; i++) { obj.cells[i].className = 'cMenu'; }
1083    }
1084    else if (action == "click" && !obj.disabled) {
1085      document.all['_'+objname+'_cMenu'].style.visibility = "hidden";
1086      var menucode = editor_cMenu.options[menuIdx][2];
1087      menucode();
1088    }
1089    else if (action == "blur") {
1090      if (!_isMouseOver(obj,event)) { obj.style.visibility = 'hidden'; }
1091      else {
1092        if (obj.style.visibility != "hidden") { obj.focus(); }
1093      }
1094    }
1095    else { alert("editor_cMenu, unknown action: " + action); }
1096  }
1097  
1098  /* ---------------------------------------------------------------------- */


Généré le : Sun Apr 1 11:11:59 2007 par Balluche grâce à PHPXref 0.7