Annotation of kupuMPIWG/common/kupucontextmenu.js, revision 1.1.1.1

1.1       dwinter     1: /*****************************************************************************
                      2:  *
                      3:  * Copyright (c) 2003-2005 Kupu Contributors. All rights reserved.
                      4:  *
                      5:  * This software is distributed under the terms of the Kupu
                      6:  * License. See LICENSE.txt for license text. For a list of Kupu
                      7:  * Contributors see CREDITS.txt.
                      8:  *
                      9:  *****************************************************************************/
                     10: 
                     11: // $Id: kupucontextmenu.js 9879 2005-03-18 12:04:00Z yuppie $
                     12: 
                     13: 
                     14: //----------------------------------------------------------------------------
                     15: // ContextMenu
                     16: //----------------------------------------------------------------------------
                     17: 
                     18: function ContextMenu() {
                     19:     /* the contextmenu */
                     20:     this.contextmenu = null;
                     21:     this.seperator = 1;
                     22: 
                     23:     this.initialize = function(editor) {
                     24:         /* set the event handlers and such */
                     25:         this.editor = editor;
                     26:         // needs some work since it won't work for more than one editor
                     27:         addEventHandler(this.editor.getInnerDocument(), "contextmenu", this.createContextMenu, this);
                     28:         //addEventHandler(editor.getInnerDocument(), "focus", this.hideContextMenu, this);
                     29:         addEventHandler(document, "focus", this.hideContextMenu, this);
                     30:         addEventHandler(editor.getInnerDocument(), "mousedown", this.hideContextMenu, this);
                     31:         addEventHandler(document, "mousedown", this.hideContextMenu, this);
                     32:     };
                     33: 
                     34:     this.createContextMenu = function(event) {
                     35:         /* Create and show the context menu 
                     36:         
                     37:             The method will ask all tools for any (optional) elements they
                     38:             want to add the menu and when done render it
                     39:         */
                     40:         if (event.stopPropagation) {
                     41:             event.stopPropagation();
                     42:         };
                     43:         event.returnValue = false;
                     44:         if (this.editor.getBrowserName() == 'IE') {
                     45:             this.editor._saveSelection();
                     46:         };
                     47:         // somehow Mozilla on Windows seems to generate the oncontextmenu event
                     48:         // several times on each rightclick, here's a workaround
                     49:         if (this.editor.getBrowserName() == 'Mozilla' && this.contextmenu) {
                     50:             return false;
                     51:         };
                     52:         this.hideContextMenu();
                     53:         var selNode = this.editor.getSelectedNode();
                     54:         var elements = new Array();
                     55:         for (var id in this.editor.tools) {
                     56:             var tool = this.editor.tools[id];
                     57:             // alas, some people seem to want backward compatibility ;)
                     58:             if (tool.createContextMenuElements) {
                     59:                 var els = tool.createContextMenuElements(selNode, event);
                     60:                 elements = elements.concat(els);
                     61:             };
                     62:         };
                     63:         // remove the last seperator
                     64:         this._createNewContextMenu(elements, event);
                     65:         this.last_event = event;
                     66:         return false;
                     67:     };
                     68: 
                     69:     this.hideContextMenu = function(event) {
                     70:         /* remove the context menu from view */
                     71:         if (this.contextmenu) {
                     72:             try {
                     73:                 window.document.getElementsByTagName('body')[0].removeChild(this.contextmenu);
                     74:             } catch (e) {
                     75:                 // after some commands, the contextmenu will be removed by 
                     76:                 // the browser, ignore those cases
                     77:             };
                     78:             this.contextmenu = null;
                     79:         };
                     80:     };
                     81: 
                     82:     this._createNewContextMenu = function(elements, event) {
                     83:         /* add the elements to the contextmenu and show it */
                     84:         var doc = window.document;
                     85:         var menu = doc.createElement('div');
                     86:         menu.contentEditable = false;
                     87:         menu.designMode = 'Off';
                     88:         this._setMenuStyle(menu);
                     89:         for (var i=0; i < elements.length; i++) {
                     90:             var element = elements[i];
                     91:             if (element !== this.seperator) {
                     92:                 var div = doc.createElement('div');
                     93:                 div.style.width = '100%';
                     94:                 var label = doc.createTextNode('\u00a0' + element.label);
                     95:                 div.appendChild(label);
                     96:                 menu.appendChild(div);
                     97:                 // set a reference to the div on the element
                     98:                 element.element = div;
                     99:                 addEventHandler(div, "mousedown", element.action, element.context);
                    100:                 addEventHandler(div, "mouseover", element.changeOverStyle, element);
                    101:                 addEventHandler(div, "mouseout", element.changeNormalStyle, element);
                    102:                 addEventHandler(div, "mouseup", this.hideContextMenu, this);
                    103:             } else {
                    104:                 var hr = doc.createElement('hr');
                    105:                 menu.appendChild(hr);
                    106:             };
                    107:         };
                    108:         // now move the menu to the right position
                    109:         var iframe = this.editor.getDocument().getEditable();
                    110:         var left = event.clientX;
                    111:         var top = event.clientY;
                    112:         var currnode = iframe;
                    113:         if (this.editor.getBrowserName() == 'IE') {
                    114:             while (currnode) {
                    115:                 left += currnode.offsetLeft + currnode.clientLeft;
                    116:                 top += currnode.offsetTop + currnode.clientTop;
                    117:                 currnode = currnode.offsetParent;
                    118:             };
                    119:         } else {
                    120:             while (currnode) {
                    121:                 left += currnode.offsetLeft;
                    122:                 top += currnode.offsetTop;
                    123:                 currnode = currnode.offsetParent;
                    124:             };
                    125:         };
                    126:         menu.style.left = left + 'px';
                    127:         menu.style.top = top + 'px';
                    128:         menu.style.visibility = 'visible';
                    129:         addEventHandler(menu, 'focus', function() {this.blur}, menu)
                    130:         doc.getElementsByTagName('body')[0].appendChild(menu);
                    131:         this.contextmenu = menu;
                    132:     };
                    133:     
                    134:     this._setMenuStyle = function(menu) {
                    135:         /* set the styles for the menu
                    136: 
                    137:             to change the menu style, override this method
                    138:         */
                    139:         menu.style.position = 'absolute';
                    140:         menu.style.backgroundColor = 'white';
                    141:         menu.style.fontFamily = 'Verdana, Arial, Helvetica, sans-serif';
                    142:         menu.style.fontSize = '12px';
                    143:         menu.style.lineHeight = '16px';
                    144:         menu.style.borderWidth = '1px';
                    145:         menu.style.borderStyle = 'solid';
                    146:         menu.style.borderColor = 'black';
                    147:         menu.style.cursor = 'default';
                    148:         menu.style.width = "8em";
                    149:     };
                    150: 
                    151:     this._showOriginalMenu = function(event) {
                    152:         window.document.dispatchEvent(this._last_event);
                    153:     };
                    154: };
                    155: 
                    156: function ContextMenuElement(label, action, context) {
                    157:     /* context menu element struct
                    158:     
                    159:         should be returned (optionally in a list) by the tools' 
                    160:         createContextMenuElements methods
                    161:     */
                    162:     this.label = label; // the text shown in the menu
                    163:     this.action = action; // a reference to the method that should be called
                    164:     this.context = context; // a reference to the object on which the method
                    165:                             //  is defined
                    166:     this.element = null; // the contextmenu machinery will add a reference 
                    167:                             // to the element here
                    168: 
                    169:     this.changeOverStyle = function(event) {
                    170:         /* set the background of the element to 'mouseover' style
                    171: 
                    172:             override only for the prototype, not for individual elements
                    173:             so every element looks the same
                    174:         */
                    175:         this.element.style.backgroundColor = 'blue';
                    176:     };
                    177: 
                    178:     this.changeNormalStyle = function(event) {
                    179:         /* set the background of the element back to 'normal' style
                    180: 
                    181:             override only for the prototype, not for individual elements
                    182:             so every element looks the same
                    183:         */
                    184:         this.element.style.backgroundColor = 'white';
                    185:     };
                    186: };
                    187: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>