Annotation of kupuMPIWG/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>