home *** CD-ROM | disk | FTP | other *** search
- // Context Menu Plugin for HTMLArea-3.0
- // Sponsored by www.americanbible.org
- // Implementation by Mihai Bazon, http://dynarch.com/mishoo/
- //
- // (c) dynarch.com 2003.
- // Distributed under the same terms as HTMLArea itself.
- // This notice MUST stay intact for use (see license.txt).
- //
- // $Id: context-menu.js,v 1.4 2004/03/03 11:22:41 mschering Exp $
-
- HTMLArea.loadStyle("menu.css", "ContextMenu");
-
- function ContextMenu(editor) {
- this.editor = editor;
- };
-
- ContextMenu._pluginInfo = {
- name : "ContextMenu",
- version : "1.0",
- developer : "Mihai Bazon",
- developer_url : "http://dynarch.com/mishoo/",
- c_owner : "dynarch.com",
- sponsor : "American Bible Society",
- sponsor_url : "http://www.americanbible.org",
- license : "htmlArea"
- };
-
- ContextMenu.prototype.onGenerate = function() {
- var self = this;
- var doc = this.editordoc = this.editor._iframe.contentWindow.document;
- HTMLArea._addEvents(doc, ["contextmenu"],
- function (event) {
- return self.popupMenu(HTMLArea.is_ie ? self.editor._iframe.contentWindow.event : event);
- });
- this.currentMenu = null;
- };
-
- ContextMenu.prototype.getContextMenu = function(target) {
- var self = this;
- var editor = this.editor;
- var config = editor.config;
- var menu = [];
- var tbo = this.editor.plugins.TableOperations;
- if (tbo) tbo = tbo.instance;
- var i18n = ContextMenu.I18N;
-
- var selection = editor.hasSelectedText();
- if (selection)
- menu.push([ i18n["Cut"], function() { editor.execCommand("cut"); }, null, config.btnList["cut"][1] ],
- [ i18n["Copy"], function() { editor.execCommand("copy"); }, null, config.btnList["copy"][1] ]);
- menu.push([ i18n["Paste"], function() { editor.execCommand("paste"); }, null, config.btnList["paste"][1] ]);
-
- var currentTarget = target;
- var elmenus = [];
-
- var link = null;
- var table = null;
- var tr = null;
- var td = null;
- var img = null;
-
- function tableOperation(opcode) {
- tbo.buttonPress(editor, opcode);
- };
-
- for (; target; target = target.parentNode) {
- var tag = target.tagName;
- if (!tag)
- continue;
- tag = tag.toLowerCase();
- switch (tag) {
- case "img":
- img = target;
- elmenus.push(null,
- [ i18n["Image Properties"],
- function() {
- editor._insertImage(img);
- },
- i18n["Show the image properties dialog"],
- config.btnList["insertimage"][1] ]
- );
- break;
- case "a":
- link = target;
- elmenus.push(null,
- [ i18n["Modify Link"],
- function() { editor.execCommand("createlink", true); },
- i18n["Current URL is"] + ': ' + link.href,
- config.btnList["createlink"][1] ],
-
- [ i18n["Check Link"],
- function() { window.open(link.href); },
- i18n["Opens this link in a new window"] ],
-
- [ i18n["Remove Link"],
- function() {
- if (confirm(i18n["Please confirm that you want to unlink this element."] + "\n" +
- i18n["Link points to:"] + " " + link.href)) {
- while (link.firstChild)
- link.parentNode.insertBefore(link.firstChild, link);
- link.parentNode.removeChild(link);
- }
- },
- i18n["Unlink the current element"] ]
- );
- break;
- case "td":
- td = target;
- if (!tbo) break;
- elmenus.push(null,
- [ i18n["Cell Properties"],
- function() { tableOperation("TO-cell-prop"); },
- i18n["Show the Table Cell Properties dialog"],
- config.btnList["TO-cell-prop"][1] ]
- );
- break;
- case "tr":
- tr = target;
- if (!tbo) break;
- elmenus.push(null,
- [ i18n["Row Properties"],
- function() { tableOperation("TO-row-prop"); },
- i18n["Show the Table Row Properties dialog"],
- config.btnList["TO-row-prop"][1] ],
-
- [ i18n["Insert Row Before"],
- function() { tableOperation("TO-row-insert-above"); },
- i18n["Insert a new row before the current one"],
- config.btnList["TO-row-insert-above"][1] ],
-
- [ i18n["Insert Row After"],
- function() { tableOperation("TO-row-insert-under"); },
- i18n["Insert a new row after the current one"],
- config.btnList["TO-row-insert-under"][1] ],
-
- [ i18n["Delete Row"],
- function() { tableOperation("TO-row-delete"); },
- i18n["Delete the current row"],
- config.btnList["TO-row-delete"][1] ]
- );
- break;
- case "table":
- table = target;
- if (!tbo) break;
- elmenus.push(null,
- [ i18n["Table Properties"],
- function() { tableOperation("TO-table-prop"); },
- i18n["Show the Table Properties dialog"],
- config.btnList["TO-table-prop"][1] ],
-
- [ i18n["Insert Column Before"],
- function() { tableOperation("TO-col-insert-before"); },
- i18n["Insert a new column before the current one"],
- config.btnList["TO-col-insert-before"][1] ],
-
- [ i18n["Insert Column After"],
- function() { tableOperation("TO-col-insert-after"); },
- i18n["Insert a new column after the current one"],
- config.btnList["TO-col-insert-after"][1] ],
-
- [ i18n["Delete Column"],
- function() { tableOperation("TO-col-delete"); },
- i18n["Delete the current column"],
- config.btnList["TO-col-delete"][1] ]
- );
- break;
- case "body":
- elmenus.push(null,
- [ i18n["Justify Left"],
- function() { editor.execCommand("justifyleft"); }, null,
- config.btnList["justifyleft"][1] ],
- [ i18n["Justify Center"],
- function() { editor.execCommand("justifycenter"); }, null,
- config.btnList["justifycenter"][1] ],
- [ i18n["Justify Right"],
- function() { editor.execCommand("justifyright"); }, null,
- config.btnList["justifyright"][1] ],
- [ i18n["Justify Full"],
- function() { editor.execCommand("justifyfull"); }, null,
- config.btnList["justifyfull"][1] ]
- );
- break;
- }
- }
-
- if (selection && !link)
- menu.push(null, [ i18n["Make link"],
- function() { editor.execCommand("createlink", true); },
- i18n["Create a link"],
- config.btnList["createlink"][1] ]);
-
- for (var i in elmenus)
- menu.push(elmenus[i]);
-
- menu.push(null,
- [ i18n["Remove the"] + " <" + currentTarget.tagName + "> " + i18n["Element"],
- function() {
- if (confirm(i18n["Please confirm that you want to remove this element:"] + " " + currentTarget.tagName)) {
- var el = currentTarget;
- var p = el.parentNode;
- p.removeChild(el);
- if (HTMLArea.is_gecko) {
- if (p.tagName.toLowerCase() == "td" && !p.hasChildNodes())
- p.appendChild(editor._doc.createElement("br"));
- editor.forceRedraw();
- editor.focusEditor();
- editor.updateToolbar();
- if (table) {
- var save_collapse = table.style.borderCollapse;
- table.style.borderCollapse = "collapse";
- table.style.borderCollapse = "separate";
- table.style.borderCollapse = save_collapse;
- }
- }
- }
- },
- i18n["Remove this node from the document"] ]);
- return menu;
- };
-
- ContextMenu.prototype.popupMenu = function(ev) {
- var self = this;
- var i18n = ContextMenu.I18N;
- if (this.currentMenu)
- this.currentMenu.parentNode.removeChild(this.currentMenu);
- function getPos(el) {
- var r = { x: el.offsetLeft, y: el.offsetTop };
- if (el.offsetParent) {
- var tmp = getPos(el.offsetParent);
- r.x += tmp.x;
- r.y += tmp.y;
- }
- return r;
- };
- function documentClick(ev) {
- ev || (ev = window.event);
- if (!self.currentMenu) {
- alert(i18n["How did you get here? (Please report!)"]);
- return false;
- }
- var el = HTMLArea.is_ie ? ev.srcElement : ev.target;
- for (; el != null && el != self.currentMenu; el = el.parentNode);
- if (el == null)
- self.closeMenu();
- //HTMLArea._stopEvent(ev);
- //return false;
- };
- var keys = [];
- function keyPress(ev) {
- ev || (ev = window.event);
- HTMLArea._stopEvent(ev);
- if (ev.keyCode == 27) {
- self.closeMenu();
- return false;
- }
- var key = String.fromCharCode(HTMLArea.is_ie ? ev.keyCode : ev.charCode).toLowerCase();
- for (var i = keys.length; --i >= 0;) {
- var k = keys[i];
- if (k[0].toLowerCase() == key)
- k[1].__msh.activate();
- }
- };
- self.closeMenu = function() {
- self.currentMenu.parentNode.removeChild(self.currentMenu);
- self.currentMenu = null;
- HTMLArea._removeEvent(document, "mousedown", documentClick);
- HTMLArea._removeEvent(self.editordoc, "mousedown", documentClick);
- if (keys.length > 0)
- HTMLArea._removeEvent(self.editordoc, "keypress", keyPress);
- if (HTMLArea.is_ie)
- self.iePopup.hide();
- };
- var target = HTMLArea.is_ie ? ev.srcElement : ev.target;
- var ifpos = getPos(self.editor._iframe);
- var x = ev.clientX + ifpos.x;
- var y = ev.clientY + ifpos.y;
-
- var div;
- var doc;
- if (!HTMLArea.is_ie) {
- doc = document;
- } else {
- // IE stinks
- var popup = this.iePopup = window.createPopup();
- doc = popup.document;
- doc.open();
- doc.write("<html><head><style type='text/css'>@import url(" + _editor_url + "plugins/ContextMenu/menu.css); html, body { padding: 0px; margin: 0px; overflow: hidden; border: 0px; }</style></head><body unselectable='yes'></body></html>");
- doc.close();
- }
- div = doc.createElement("div");
- if (HTMLArea.is_ie)
- div.unselectable = "on";
- div.oncontextmenu = function() { return false; };
- div.className = "htmlarea-context-menu";
- if (!HTMLArea.is_ie)
- div.style.left = div.style.top = "0px";
- doc.body.appendChild(div);
-
- var table = doc.createElement("table");
- div.appendChild(table);
- table.cellSpacing = 0;
- table.cellPadding = 0;
- var parent = doc.createElement("tbody");
- table.appendChild(parent);
-
- var options = this.getContextMenu(target);
- for (var i = 0; i < options.length; ++i) {
- var option = options[i];
- var item = doc.createElement("tr");
- parent.appendChild(item);
- if (HTMLArea.is_ie)
- item.unselectable = "on";
- else item.onmousedown = function(ev) {
- HTMLArea._stopEvent(ev);
- return false;
- };
- if (!option) {
- item.className = "separator";
- var td = doc.createElement("td");
- td.className = "icon";
- var IE_IS_A_FUCKING_SHIT = '>';
- if (HTMLArea.is_ie) {
- td.unselectable = "on";
- IE_IS_A_FUCKING_SHIT = " unselectable='on' style='height=1px'> ";
- }
- td.innerHTML = "<div" + IE_IS_A_FUCKING_SHIT + "</div>";
- var td1 = td.cloneNode(true);
- td1.className = "label";
- item.appendChild(td);
- item.appendChild(td1);
- } else {
- var label = option[0];
- item.className = "item";
- item.__msh = {
- item: item,
- label: label,
- action: option[1],
- tooltip: option[2] || null,
- icon: option[3] || null,
- activate: function() {
- self.closeMenu();
- self.editor.focusEditor();
- this.action();
- }
- };
- label = label.replace(/_([a-zA-Z0-9])/, "<u>$1</u>");
- if (label != option[0])
- keys.push([ RegExp.$1, item ]);
- label = label.replace(/__/, "_");
- var td1 = doc.createElement("td");
- if (HTMLArea.is_ie)
- td1.unselectable = "on";
- item.appendChild(td1);
- td1.className = "icon";
- if (item.__msh.icon)
- td1.innerHTML = "<img align='middle' src='" + item.__msh.icon + "' />";
- var td2 = doc.createElement("td");
- if (HTMLArea.is_ie)
- td2.unselectable = "on";
- item.appendChild(td2);
- td2.className = "label";
- td2.innerHTML = label;
- item.onmouseover = function() {
- this.className += " hover";
- self.editor._statusBarTree.innerHTML = this.__msh.tooltip || ' ';
- };
- item.onmouseout = function() { this.className = "item"; };
- item.oncontextmenu = function(ev) {
- this.__msh.activate();
- if (!HTMLArea.is_ie)
- HTMLArea._stopEvent(ev);
- return false;
- };
- item.onmouseup = function(ev) {
- var timeStamp = (new Date()).getTime();
- if (timeStamp - self.timeStamp > 500)
- this.__msh.activate();
- if (!HTMLArea.is_ie)
- HTMLArea._stopEvent(ev);
- return false;
- };
- //if (typeof option[2] == "string")
- //item.title = option[2];
- }
- }
-
- if (!HTMLArea.is_ie) {
- var dx = x + div.offsetWidth - window.innerWidth + 4;
- var dy = y + div.offsetHeight - window.innerHeight + 4;
- if (dx > 0) x -= dx;
- if (dy > 0) y -= dy;
- div.style.left = x + "px";
- div.style.top = y + "px";
- } else {
- // determine the size (did I mention that IE stinks?)
- var foobar = document.createElement("div");
- foobar.className = "htmlarea-context-menu";
- foobar.innerHTML = div.innerHTML;
- document.body.appendChild(foobar);
- var w = foobar.offsetWidth;
- var h = foobar.offsetHeight;
- document.body.removeChild(foobar);
- this.iePopup.show(ev.screenX, ev.screenY, w, h);
- }
-
- this.currentMenu = div;
- this.timeStamp = (new Date()).getTime();
-
- HTMLArea._addEvent(document, "mousedown", documentClick);
- HTMLArea._addEvent(this.editordoc, "mousedown", documentClick);
- if (keys.length > 0)
- HTMLArea._addEvent(this.editordoc, "keypress", keyPress);
-
- HTMLArea._stopEvent(ev);
- return false;
- };
-