Annotation of kupu/common/kupucontextmenu.js, revision 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>