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