source: trunk/phpgwapi/js/htmlarea/plugins/ContextMenu/context-menu.js @ 2

Revision 2, 12.7 KB checked in by niltonneto, 17 years ago (diff)

Removida todas as tags usadas pelo CVS ($Id, $Source).
Primeira versão no CVS externo.

  • Property svn:eol-style set to native
  • Property svn:executable set to *
Line 
1// Context Menu Plugin for HTMLArea-3.0
2// Sponsored by www.americanbible.org
3// Implementation by Mihai Bazon, http://dynarch.com/mishoo/
4//
5// (c) dynarch.com 2003.
6// Distributed under the same terms as HTMLArea itself.
7// This notice MUST stay intact for use (see license.txt).
8//
9
10HTMLArea.loadStyle("menu.css", "ContextMenu");
11
12function ContextMenu(editor) {
13        this.editor = editor;
14};
15
16ContextMenu._pluginInfo = {
17        name          : "ContextMenu",
18        version       : "1.0",
19        developer     : "Mihai Bazon",
20        developer_url : "http://dynarch.com/mishoo/",
21        c_owner       : "dynarch.com",
22        sponsor       : "American Bible Society",
23        sponsor_url   : "http://www.americanbible.org",
24        license       : "htmlArea"
25};
26
27ContextMenu.prototype.onGenerate = function() {
28        var self = this;
29        var doc = this.editordoc = this.editor._iframe.contentWindow.document;
30        HTMLArea._addEvents(doc, ["contextmenu"],
31                            function (event) {
32                                    return self.popupMenu(HTMLArea.is_ie ? self.editor._iframe.contentWindow.event : event);
33                            });
34        this.currentMenu = null;
35};
36
37ContextMenu.prototype.getContextMenu = function(target) {
38        var self = this;
39        var editor = this.editor;
40        var config = editor.config;
41        var menu = [];
42        var tbo = this.editor.plugins.TableOperations;
43        if (tbo) tbo = tbo.instance;
44        var i18n = ContextMenu.I18N;
45
46        var selection = editor.hasSelectedText();
47        if (selection)
48                menu.push([ i18n["Cut"], function() { editor.execCommand("cut"); }, null, config.btnList["cut"][1] ],
49                          [ i18n["Copy"], function() { editor.execCommand("copy"); }, null, config.btnList["copy"][1] ]);
50        menu.push([ i18n["Paste"], function() { editor.execCommand("paste"); }, null, config.btnList["paste"][1] ]);
51
52        var currentTarget = target;
53        var elmenus = [];
54
55        var link = null;
56        var table = null;
57        var tr = null;
58        var td = null;
59        var img = null;
60
61        function tableOperation(opcode) {
62                tbo.buttonPress(editor, opcode);
63        };
64
65        for (; target; target = target.parentNode) {
66                var tag = target.tagName;
67                if (!tag)
68                        continue;
69                tag = tag.toLowerCase();
70                switch (tag) {
71                    case "img":
72                        img = target;
73                        elmenus.push(null,
74                                     [ i18n["Image Properties"],
75                                       function() {
76                                               editor._insertImage(img);
77                                       },
78                                       i18n["Show the image properties dialog"],
79                                       config.btnList["insertimage"][1] ]
80                                );
81                        break;
82                    case "a":
83                        link = target;
84                        elmenus.push(null,
85                                     [ i18n["Modify Link"],
86                                       function() { editor.execCommand("createlink", true); },
87                                       i18n["Current URL is"] + ': ' + link.href,
88                                       config.btnList["createlink"][1] ],
89
90                                     [ i18n["Check Link"],
91                                       function() { window.open(link.href); },
92                                       i18n["Opens this link in a new window"] ],
93
94                                     [ i18n["Remove Link"],
95                                       function() {
96                                               if (confirm(i18n["Please confirm that you want to unlink this element."] + "\n" +
97                                                           i18n["Link points to:"] + " " + link.href)) {
98                                                       while (link.firstChild)
99                                                               link.parentNode.insertBefore(link.firstChild, link);
100                                                       link.parentNode.removeChild(link);
101                                               }
102                                       },
103                                       i18n["Unlink the current element"] ]
104                                );
105                        break;
106                    case "td":
107                        td = target;
108                        if (!tbo) break;
109                        elmenus.push(null,
110                                     [ i18n["Cell Properties"],
111                                       function() { tableOperation("TO-cell-prop"); },
112                                       i18n["Show the Table Cell Properties dialog"],
113                                       config.btnList["TO-cell-prop"][1] ]
114                                );
115                        break;
116                    case "tr":
117                        tr = target;
118                        if (!tbo) break;
119                        elmenus.push(null,
120                                     [ i18n["Row Properties"],
121                                       function() { tableOperation("TO-row-prop"); },
122                                       i18n["Show the Table Row Properties dialog"],
123                                       config.btnList["TO-row-prop"][1] ],
124
125                                     [ i18n["Insert Row Before"],
126                                       function() { tableOperation("TO-row-insert-above"); },
127                                       i18n["Insert a new row before the current one"],
128                                       config.btnList["TO-row-insert-above"][1] ],
129
130                                     [ i18n["Insert Row After"],
131                                       function() { tableOperation("TO-row-insert-under"); },
132                                       i18n["Insert a new row after the current one"],
133                                       config.btnList["TO-row-insert-under"][1] ],
134
135                                     [ i18n["Delete Row"],
136                                       function() { tableOperation("TO-row-delete"); },
137                                       i18n["Delete the current row"],
138                                       config.btnList["TO-row-delete"][1] ]
139                                );
140                        break;
141                    case "table":
142                        table = target;
143                        if (!tbo) break;
144                        elmenus.push(null,
145                                     [ i18n["Table Properties"],
146                                       function() { tableOperation("TO-table-prop"); },
147                                       i18n["Show the Table Properties dialog"],
148                                       config.btnList["TO-table-prop"][1] ],
149
150                                     [ i18n["Insert Column Before"],
151                                       function() { tableOperation("TO-col-insert-before"); },
152                                       i18n["Insert a new column before the current one"],
153                                       config.btnList["TO-col-insert-before"][1] ],
154
155                                     [ i18n["Insert Column After"],
156                                       function() { tableOperation("TO-col-insert-after"); },
157                                       i18n["Insert a new column after the current one"],
158                                       config.btnList["TO-col-insert-after"][1] ],
159
160                                     [ i18n["Delete Column"],
161                                       function() { tableOperation("TO-col-delete"); },
162                                       i18n["Delete the current column"],
163                                       config.btnList["TO-col-delete"][1] ]
164                                );
165                        break;
166                    case "body":
167                        elmenus.push(null,
168                                     [ i18n["Justify Left"],
169                                       function() { editor.execCommand("justifyleft"); }, null,
170                                       config.btnList["justifyleft"][1] ],
171                                     [ i18n["Justify Center"],
172                                       function() { editor.execCommand("justifycenter"); }, null,
173                                       config.btnList["justifycenter"][1] ],
174                                     [ i18n["Justify Right"],
175                                       function() { editor.execCommand("justifyright"); }, null,
176                                       config.btnList["justifyright"][1] ],
177                                     [ i18n["Justify Full"],
178                                       function() { editor.execCommand("justifyfull"); }, null,
179                                       config.btnList["justifyfull"][1] ]
180                                );
181                        break;
182                }
183        }
184
185        if (selection && !link)
186                menu.push(null, [ i18n["Make link"],
187                                  function() { editor.execCommand("createlink", true); },
188                                  i18n["Create a link"],
189                                  config.btnList["createlink"][1] ]);
190
191        for (var i in elmenus)
192                menu.push(elmenus[i]);
193
194        menu.push(null,
195                  [ i18n["Remove the"] + " <" + currentTarget.tagName + "> " + i18n["Element"],
196                    function() {
197                            if (confirm(i18n["Please confirm that you want to remove this element:"] + " " + currentTarget.tagName)) {
198                                    var el = currentTarget;
199                                    var p = el.parentNode;
200                                    p.removeChild(el);
201                                    if (HTMLArea.is_gecko) {
202                                            if (p.tagName.toLowerCase() == "td" && !p.hasChildNodes())
203                                                    p.appendChild(editor._doc.createElement("br"));
204                                            editor.forceRedraw();
205                                            editor.focusEditor();
206                                            editor.updateToolbar();
207                                            if (table) {
208                                                    var save_collapse = table.style.borderCollapse;
209                                                    table.style.borderCollapse = "collapse";
210                                                    table.style.borderCollapse = "separate";
211                                                    table.style.borderCollapse = save_collapse;
212                                            }
213                                    }
214                            }
215                    },
216                    i18n["Remove this node from the document"] ]);
217        return menu;
218};
219
220ContextMenu.prototype.popupMenu = function(ev) {
221        var self = this;
222        var i18n = ContextMenu.I18N;
223        if (this.currentMenu)
224                this.currentMenu.parentNode.removeChild(this.currentMenu);
225        function getPos(el) {
226                var r = { x: el.offsetLeft, y: el.offsetTop };
227                if (el.offsetParent) {
228                        var tmp = getPos(el.offsetParent);
229                        r.x += tmp.x;
230                        r.y += tmp.y;
231                }
232                return r;
233        };
234        function documentClick(ev) {
235                ev || (ev = window.event);
236                if (!self.currentMenu) {
237                        alert(i18n["How did you get here? (Please report!)"]);
238                        return false;
239                }
240                var el = HTMLArea.is_ie ? ev.srcElement : ev.target;
241                for (; el != null && el != self.currentMenu; el = el.parentNode);
242                if (el == null)
243                        self.closeMenu();
244                //HTMLArea._stopEvent(ev);
245                //return false;
246        };
247        var keys = [];
248        function keyPress(ev) {
249                ev || (ev = window.event);
250                HTMLArea._stopEvent(ev);
251                if (ev.keyCode == 27) {
252                        self.closeMenu();
253                        return false;
254                }
255                var key = String.fromCharCode(HTMLArea.is_ie ? ev.keyCode : ev.charCode).toLowerCase();
256                for (var i = keys.length; --i >= 0;) {
257                        var k = keys[i];
258                        if (k[0].toLowerCase() == key)
259                                k[1].__msh.activate();
260                }
261        };
262        self.closeMenu = function() {
263                self.currentMenu.parentNode.removeChild(self.currentMenu);
264                self.currentMenu = null;
265                HTMLArea._removeEvent(document, "mousedown", documentClick);
266                HTMLArea._removeEvent(self.editordoc, "mousedown", documentClick);
267                if (keys.length > 0)
268                        HTMLArea._removeEvent(self.editordoc, "keypress", keyPress);
269                if (HTMLArea.is_ie)
270                        self.iePopup.hide();
271        };
272        var target = HTMLArea.is_ie ? ev.srcElement : ev.target;
273        var ifpos = getPos(self.editor._iframe);
274        var x = ev.clientX + ifpos.x;
275        var y = ev.clientY + ifpos.y;
276
277        var div;
278        var doc;
279        if (!HTMLArea.is_ie) {
280                doc = document;
281        } else {
282                // IE stinks
283                var popup = this.iePopup = window.createPopup();
284                doc = popup.document;
285                doc.open();
286                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>");
287                doc.close();
288        }
289        div = doc.createElement("div");
290        if (HTMLArea.is_ie)
291                div.unselectable = "on";
292        div.oncontextmenu = function() { return false; };
293        div.className = "htmlarea-context-menu";
294        if (!HTMLArea.is_ie)
295                div.style.left = div.style.top = "0px";
296        doc.body.appendChild(div);
297
298        var table = doc.createElement("table");
299        div.appendChild(table);
300        table.cellSpacing = 0;
301        table.cellPadding = 0;
302        var parent = doc.createElement("tbody");
303        table.appendChild(parent);
304
305        var options = this.getContextMenu(target);
306        for (var i = 0; i < options.length; ++i) {
307                var option = options[i];
308                var item = doc.createElement("tr");
309                parent.appendChild(item);
310                if (HTMLArea.is_ie)
311                        item.unselectable = "on";
312                else item.onmousedown = function(ev) {
313                        HTMLArea._stopEvent(ev);
314                        return false;
315                };
316                if (!option) {
317                        item.className = "separator";
318                        var td = doc.createElement("td");
319                        td.className = "icon";
320                        var IE_IS_A_FUCKING_SHIT = '>';
321                        if (HTMLArea.is_ie) {
322                                td.unselectable = "on";
323                                IE_IS_A_FUCKING_SHIT = " unselectable='on' style='height=1px'>&nbsp;";
324                        }
325                        td.innerHTML = "<div" + IE_IS_A_FUCKING_SHIT + "</div>";
326                        var td1 = td.cloneNode(true);
327                        td1.className = "label";
328                        item.appendChild(td);
329                        item.appendChild(td1);
330                } else {
331                        var label = option[0];
332                        item.className = "item";
333                        item.__msh = {
334                                item: item,
335                                label: label,
336                                action: option[1],
337                                tooltip: option[2] || null,
338                                icon: option[3] || null,
339                                activate: function() {
340                                        self.closeMenu();
341                                        self.editor.focusEditor();
342                                        this.action();
343                                }
344                        };
345                        label = label.replace(/_([a-zA-Z0-9])/, "<u>$1</u>");
346                        if (label != option[0])
347                                keys.push([ RegExp.$1, item ]);
348                        label = label.replace(/__/, "_");
349                        var td1 = doc.createElement("td");
350                        if (HTMLArea.is_ie)
351                                td1.unselectable = "on";
352                        item.appendChild(td1);
353                        td1.className = "icon";
354                        if (item.__msh.icon)
355                                td1.innerHTML = "<img align='middle' src='" + item.__msh.icon + "' />";
356                        var td2 = doc.createElement("td");
357                        if (HTMLArea.is_ie)
358                                td2.unselectable = "on";
359                        item.appendChild(td2);
360                        td2.className = "label";
361                        td2.innerHTML = label;
362                        item.onmouseover = function() {
363                                this.className += " hover";
364                                self.editor._statusBarTree.innerHTML = this.__msh.tooltip || '&nbsp;';
365                        };
366                        item.onmouseout = function() { this.className = "item"; };
367                        item.oncontextmenu = function(ev) {
368                                this.__msh.activate();
369                                if (!HTMLArea.is_ie)
370                                        HTMLArea._stopEvent(ev);
371                                return false;
372                        };
373                        item.onmouseup = function(ev) {
374                                var timeStamp = (new Date()).getTime();
375                                if (timeStamp - self.timeStamp > 500)
376                                        this.__msh.activate();
377                                if (!HTMLArea.is_ie)
378                                        HTMLArea._stopEvent(ev);
379                                return false;
380                        };
381                        //if (typeof option[2] == "string")
382                        //item.title = option[2];
383                }
384        }
385
386        if (!HTMLArea.is_ie) {
387                var dx = x + div.offsetWidth - window.innerWidth + 4;
388                var dy = y + div.offsetHeight - window.innerHeight + 4;
389                if (dx > 0) x -= dx;
390                if (dy > 0) y -= dy;
391                div.style.left = x + "px";
392                div.style.top = y + "px";
393        } else {
394                // determine the size (did I mention that IE stinks?)
395                var foobar = document.createElement("div");
396                foobar.className = "htmlarea-context-menu";
397                foobar.innerHTML = div.innerHTML;
398                document.body.appendChild(foobar);
399                var w = foobar.offsetWidth;
400                var h = foobar.offsetHeight;
401                document.body.removeChild(foobar);
402                this.iePopup.show(ev.screenX, ev.screenY, w, h);
403        }
404
405        this.currentMenu = div;
406        this.timeStamp = (new Date()).getTime();
407
408        HTMLArea._addEvent(document, "mousedown", documentClick);
409        HTMLArea._addEvent(this.editordoc, "mousedown", documentClick);
410        if (keys.length > 0)
411                HTMLArea._addEvent(this.editordoc, "keypress", keyPress);
412
413        HTMLArea._stopEvent(ev);
414        return false;
415};
Note: See TracBrowser for help on using the repository browser.