Changeset 674
- Timestamp:
- 01/19/07 15:33:17 (6 years ago)
- Location:
- trunk
- Files:
-
- 3 modified
-
XinhaCore.js (modified) (32 diffs)
-
functionsIE.js (modified) (4 diffs)
-
functionsMozilla.js (modified) (8 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/XinhaCore.js
r673 r674 2415 2415 else 2416 2416 { 2417 // FIXME - can we do this without rewriting the entire document 2418 // does the above not work for IE? 2417 2419 var reac = this.editorIsActivated(); 2418 2420 if ( reac ) … … 2428 2430 { 2429 2431 this.activateEditor(); 2430 } 2432 } 2431 2433 this.setEditorEvents(); 2432 2434 return true; … … 2462 2464 ); 2463 2465 2466 // FIXME - this needs to be cleaned up and use editor.firePluginEvent 2467 // I don't like both onGenerate and onGenerateOnce, we should only 2468 // have onGenerate and it should only be called when the editor is 2469 // generated (once and only once) 2464 2470 // check if any plugins have registered refresh handlers 2465 2471 for ( var i in editor.plugins ) … … 2659 2665 } 2660 2666 }; 2667 2668 /** Call a method of all plugins which define the method using the supplied arguments. 2669 * 2670 * Example: editor.firePluginEvent('onExecCommand', 'paste') 2671 * 2672 * The browser specific plugin (if any) is called last. The result of each call is 2673 * treated as boolean. A true return means that the event will stop, no further plugins 2674 * will get the event, a false return means the event will continue to fire. 2675 * 2676 * @param methodName 2677 * @param arguments to pass to the method, optional [2..n] 2678 */ 2679 2680 Xinha.prototype.firePluginEvent = function(methodName) 2681 { 2682 // arguments is not a real array so we can't just .shift() it unfortunatly. 2683 var argsArray = [ ]; 2684 for(var i = 1; i < arguments.length; i++) 2685 { 2686 argsArray[i-1] = arguments[i]; 2687 } 2688 2689 for ( var i in this.plugins ) 2690 { 2691 var plugin = this.plugins[i].instance; 2692 2693 // Skip the browser specific plugin 2694 if ( plugin == this._browserSpecificPlugin) continue; 2695 2696 if ( plugin && typeof plugin[methodName] == "function" ) 2697 { 2698 if ( plugin[methodName].apply(plugin, argsArray) ) 2699 { 2700 return true; 2701 } 2702 } 2703 } 2704 2705 // Now the browser speific 2706 var plugin = this._browserSpecificPlugin; 2707 if ( plugin && typeof plugin[methodName] == "function" ) 2708 { 2709 if ( plugin[methodName].apply(plugin, argsArray) ) 2710 { 2711 return true; 2712 } 2713 } 2714 2715 return false; 2716 } 2661 2717 2662 2718 Xinha.loadStyle = function(style, plugin) … … 3349 3405 } 3350 3406 3407 // FIXME: this should be using this.firePluginEvent('onUpdateToolbar') 3408 // but we have to make sure that the plugins using that event return false 3409 // if they should let the event fire on other plugins, currently the below 3410 // code doesn't take the return value into account 3411 3351 3412 // check if any plugins have registered refresh handlers 3352 3413 for ( var indexPlugin in this.plugins ) … … 3385 3446 if ( prnt === null ) 3386 3447 { 3448 // Hmm, I think Xinha.getParentElement() would do the job better?? - James 3387 3449 try 3388 3450 { … … 3728 3790 this.focusEditor(); 3729 3791 cmdID = cmdID.toLowerCase(); 3730 // useCSS deprecated & replaced by styleWithCSS 3731 if ( Xinha.is_gecko ) 3732 { 3733 try 3734 { 3735 this._doc.execCommand('useCSS', false, true); //switch useCSS off (true=off) 3736 this._doc.execCommand('styleWithCSS', false, false); //switch styleWithCSS off 3737 3738 } catch (ex) {} 3739 } 3792 3793 // See if any plugins want to do something special 3794 if(this.firePluginEvent('onExecCommand', cmdID, UI, param)) 3795 { 3796 this.updateToolbar(); 3797 return false; 3798 } 3799 3740 3800 switch (cmdID) 3741 3801 { … … 3788 3848 case "copy": 3789 3849 case "paste": 3790 try3791 {3792 3850 this._doc.execCommand(cmdID, UI, param); 3793 3851 if ( this.config.killWordOnPaste ) … … 3795 3853 this._wordClean(); 3796 3854 } 3797 }3798 catch (ex)3799 {3800 if ( Xinha.is_gecko )3801 {3802 alert(Xinha._lc("The Paste button does not work in Mozilla based web browsers (technical security reasons). Press CTRL-V on your keyboard to paste directly."));3803 }3804 }3805 3855 break; 3806 3856 case "lefttoright": … … 3870 3920 { 3871 3921 var editor = this; 3872 var keyEvent = this.isKeyEvent(ev);3873 3922 3874 3923 //call events of textarea … … 3878 3927 } 3879 3928 3880 if ( keyEvent)3929 if ( this.isKeyEvent(ev) ) 3881 3930 { 3882 3931 // Run the ordinary plugins first 3883 for ( var i in editor.plugins ) 3884 { 3885 var plugin = editor.plugins[i].instance; 3886 3887 if ( plugin == editor._browserSpecificPlugin) continue; 3888 3889 if ( plugin && typeof plugin.onKeyPress == "function" ) 3890 { 3891 if ( plugin.onKeyPress(ev) ) 3892 { 3893 return false; 3894 } 3895 } 3932 if(editor.firePluginEvent('onKeyPress', ev)) 3933 { 3934 return false; 3896 3935 } 3897 3936 3898 // Now run the browser specific one 3899 if(typeof editor._browserSpecificPlugin.onKeyPress == "function") 3900 { 3901 if(editor._browserSpecificPlugin.onKeyPress(ev)) 3902 { 3903 return false; 3904 } 3905 } 3906 } 3907 3908 if ( keyEvent && ev.ctrlKey && !ev.altKey ) 3909 { 3910 this._shortCuts(ev); 3937 // Handle the core shortcuts 3938 if ( this.isShortCut( ev ) ) 3939 { 3940 this._shortCuts(ev); 3941 } 3911 3942 } 3912 3943 … … 3928 3959 Xinha.prototype._shortCuts = function (ev) 3929 3960 { 3930 var editor = this; 3931 var sel = null; 3932 var range = null; 3933 var key = String.fromCharCode(Xinha.is_ie ? ev.keyCode : ev.charCode).toLowerCase(); 3961 var key = this.getKey(ev).toLowerCase(); 3934 3962 var cmd = null; 3935 3963 var value = null; 3936 3964 switch (key) 3937 3965 { 3938 case 'a':3939 if ( !Xinha.is_ie )3940 {3941 // KEY select all3942 sel = this._getSelection();3943 sel.removeAllRanges();3944 range = this._createRange();3945 range.selectNodeContents(this._doc.body);3946 sel.addRange(range);3947 Xinha._stopEvent(ev);3948 }3949 break;3950 3951 3966 // simple key commands follow 3952 3967 … … 3961 3976 case 'z': cmd = "undo"; break; 3962 3977 case 'y': cmd = "redo"; break; 3963 case 'v': 3964 if ( Xinha.is_ie || editor.config.htmlareaPaste ) 3965 { 3966 cmd = "paste"; 3967 } 3968 break; 3978 case 'v': cmd = "paste"; break; 3969 3979 case 'n': 3970 3980 cmd = "formatblock"; 3971 value = Xinha.is_ie ? "<p>" :"p";3981 value = "p"; 3972 3982 break; 3973 3983 … … 3983 3993 cmd = "formatblock"; 3984 3994 value = "h" + key; 3985 if ( Xinha.is_ie )3986 {3987 value = "<" + value + ">";3988 }3989 3995 break; 3990 3996 } … … 4228 4234 } 4229 4235 4230 if (1 || Xinha.is_gecko ) 4231 { 4232 var top = 0; 4233 var left = 0; 4234 while ( e ) 4235 { 4236 top += e.offsetTop; 4237 left += e.offsetLeft; 4238 if ( e.offsetParent && e.offsetParent.tagName.toLowerCase() != 'body' ) 4239 { 4240 e = e.offsetParent; 4241 } 4242 else 4243 { 4244 e = null; 4245 } 4246 } 4247 this._iframe.contentWindow.scrollTo(left, top); 4248 } 4236 // This was at one time limited to Gecko only, but I see no reason for it to be. - James 4237 var position = Xinha.getElementTopLeft(e); 4238 this._iframe.contentWindow.scrollTo(position.left, position.top); 4249 4239 }; 4250 4240 … … 4277 4267 Xinha.prototype.outwardHtml = function(html) 4278 4268 { 4269 for ( var i in this.plugins ) 4270 { 4271 var plugin = this.plugins[i].instance; 4272 if ( plugin && typeof plugin.outwardHtml == "function" ) 4273 { 4274 html = plugin.outwardHtml(html); 4275 } 4276 } 4277 4279 4278 html = html.replace(/<(\/?)b(\s|>|\/)/ig, "<$1strong$2"); 4280 4279 html = html.replace(/<(\/?)i(\s|>|\/)/ig, "<$1em$2"); … … 4288 4287 4289 4288 // IE puts this in can't figure out why 4289 // leaving this in the core instead of InternetExplorer 4290 // because it might be something we are doing so could present itself 4291 // in other browsers - James 4290 4292 html = html.replace(/https?:\/\/null\//g, serverBase); 4291 4293 … … 4303 4305 html = html.replace(/[^ -~\r\n\t]/g, function(c) { return '&#'+c.charCodeAt(0)+';'; }); 4304 4306 } 4305 4306 // ticket:56, the "greesemonkey" plugin for Firefox adds this junk, 4307 // so we strip it out. Original submitter gave a plugin, but that's 4308 // a bit much just for this IMHO - james 4309 if ( Xinha.is_gecko ) 4310 { 4311 html = html.replace(/<script[\s]*src[\s]*=[\s]*['"]chrome:\/\/.*?["']>[\s]*<\/script>/ig, ''); 4312 } 4307 4313 4308 //prevent execution of JavaScript (Ticket #685) 4314 4309 html = html.replace(/(<script[^>]*)(freezescript)/gi,"$1javascript"); … … 4319 4314 html = Xinha.stripCoreCSS(html); 4320 4315 } 4321 4322 4316 4323 4317 return html; 4324 4318 }; 4325 4319 4326 4320 Xinha.prototype.inwardHtml = function(html) 4327 { 4328 // Midas uses b and i instead of strong and em, um, hello, 4329 // mozilla, this is the 21st century calling! 4330 if ( Xinha.is_gecko ) 4331 { 4332 html = html.replace(/<(\/?)strong(\s|>|\/)/ig, "<$1b$2"); 4333 html = html.replace(/<(\/?)em(\s|>|\/)/ig, "<$1i$2"); 4334 } 4335 4321 { 4322 for ( var i in this.plugins ) 4323 { 4324 var plugin = this.plugins[i].instance; 4325 if ( plugin && typeof plugin.inwardHtml == "function" ) 4326 { 4327 html = plugin.inwardHtml(html); 4328 } 4329 } 4330 4336 4331 // Both IE and Gecko use strike instead of del (#523) 4337 4332 html = html.replace(/<(\/?)del(\s|>|\/)/ig, "<$1strike$2"); … … 4444 4439 html = html.replace(baseRe, '$1'); 4445 4440 } 4446 4447 // if ( Xinha.is_ie )4448 // {4449 // This is now done in inward & outward4450 // Don't know why but IE is doing this (putting http://null/ on links?!4451 // alert(html);4452 // var nullRE = new RegExp('https?:\/\/null\/', 'g');4453 // html = html.replace(nullRE, location.href.replace(/(https?:\/\/[^\/]*\/).*/, '$1'));4454 // alert(html);4455 // }4456 4441 4457 4442 return html; … … 5062 5047 { 5063 5048 if ( !this.borders ) 5064 { 5065 name = "bordered"; 5049 { 5066 5050 this.borders = true; 5067 5051 } 5068 5052 else 5069 5053 { 5070 name = "";5071 5054 this.borders = false; 5072 5055 } … … 5076 5059 if ( this.borders ) 5077 5060 { 5078 // flashing the display forces moz to listen (JB:18-04-2005) - #1025079 if ( Xinha.is_gecko )5080 {5081 tables[i].style.display="none";5082 tables[i].style.display="table";5083 }5084 5061 Xinha._addClass(tables[i], 'htmtableborders'); 5085 5062 } … … 5182 5159 { 5183 5160 var req = null; 5184 if ( Xinha.is_ie ) 5185 { 5186 req = new ActiveXObject("Microsoft.XMLHTTP"); 5187 } 5188 else 5189 { 5190 req = new XMLHttpRequest(); 5191 } 5161 req = Xinha.getXMLHTTPRequestObject(); 5192 5162 5193 5163 var content = ''; … … 5233 5203 { 5234 5204 var req = null; 5235 if ( Xinha.is_ie ) 5236 { 5237 req = new ActiveXObject("Microsoft.XMLHTTP"); 5238 } 5239 else 5240 { 5241 req = new XMLHttpRequest(); 5242 } 5205 req = Xinha.getXMLHTTPRequestObject(); 5243 5206 5244 5207 function callBack() … … 5265 5228 { 5266 5229 var req = null; 5267 if ( Xinha.is_ie ) 5268 { 5269 req = new ActiveXObject("Microsoft.XMLHTTP"); 5270 } 5271 else 5272 { 5273 req = new XMLHttpRequest(); 5274 } 5230 req = Xinha.getXMLHTTPRequestObject(); 5275 5231 5276 5232 // Synchronous! … … 5520 5476 /** 5521 5477 * Load a javascript file by inserting it in the HEAD tag and eventually call a function when loaded 5478 * 5479 * Note that this method cannot be abstracted into browser specific files 5480 * because this method LOADS the browser specific files. Hopefully it should work for most 5481 * browsers as it is. 5482 * 5522 5483 * @param {string} U (Url) Source url of the file to load 5523 5484 * @param {object} C {Callback} Callback function to launch once ready (optional) … … 5525 5486 * @param {object} B (Bonus} Arbitrary object send as a param to the callback function (optional) 5526 5487 * @public 5488 * 5527 5489 */ 5528 Xinha._loadback = function(U, C, O, B) 5529 { 5530 var T = Xinha.is_ie ? "onreadystatechange" : "onload"; 5490 5491 Xinha._loadback = function(Url, Callback, Scope, Bonus) 5492 { 5493 var T = !Xinha.is_ie ? "onload" : 'onreadystatechange'; 5531 5494 var S = document.createElement("script"); 5532 5495 S.type = "text/javascript"; 5533 S.src = U ;5534 if ( C )5496 S.src = Url; 5497 if ( Callback ) 5535 5498 { 5536 5499 S[T] = function() 5537 { 5538 if ( Xinha.is_ie && ! ( /loaded|complete/.test(window.event.srcElement.readyState) ) )5500 { 5501 if ( Xinha.is_ie && ( ! ( /loaded|complete/.test(window.event.srcElement.readyState) ) ) ) 5539 5502 { 5540 5503 return; 5541 5504 } 5542 C.call(O ? O : this, B); 5505 5506 Callback.call(Scope ? Scope : this, Bonus); 5543 5507 S[T] = null; 5544 5508 }; … … 5738 5702 }; 5739 5703 5704 /** 5705 * Calculate the top and left pixel position of an element in the DOM. 5706 * 5707 * @param element HTML Element DOM Node 5708 * @returns Object with integer properties top and left 5709 */ 5710 5711 Xinha.getElementTopLeft = function(element) 5712 { 5713 var position = { top:0, left:0 }; 5714 while ( element ) 5715 { 5716 position.top += element.offsetTop; 5717 position.left += element.offsetLeft; 5718 if ( element.offsetParent && element.offsetParent.tagName.toLowerCase() != 'body' ) 5719 { 5720 element = element.offsetParent; 5721 } 5722 else 5723 { 5724 element = null; 5725 } 5726 } 5727 5728 return position; 5729 } 5730 5740 5731 // find X position of an element 5741 5732 Xinha.findPosX = function(obj) … … 5744 5735 if ( obj.offsetParent ) 5745 5736 { 5746 while ( obj.offsetParent ) 5747 { 5748 curleft += obj.offsetLeft; 5749 obj = obj.offsetParent; 5750 } 5737 return Xinha.getElementTopLeft(obj).left; 5751 5738 } 5752 5739 else if ( obj.x ) … … 5763 5750 if ( obj.offsetParent ) 5764 5751 { 5765 while ( obj.offsetParent ) 5766 { 5767 curtop += obj.offsetTop; 5768 obj = obj.offsetParent; 5769 } 5752 return Xinha.getElementTopLeft(obj).top; 5770 5753 } 5771 5754 else if ( obj.y ) … … 5918 5901 Xinha.prototype.isKeyEvent = function(event) { Xinha.notImplemented("isKeyEvent"); } 5919 5902 5903 /** Determines if the given key event object represents a combination of CTRL-<key>, 5904 * which for Xinha is a shortcut. Note that CTRL-ALT-<key> is not a shortcut. 5905 * 5906 * @param keyEvent 5907 * @returns true|false 5908 */ 5909 5910 Xinha.prototype.isShortCut = function(keyEvent) 5911 { 5912 if(keyEvent.ctrlKey && !keyEvent.altKey) 5913 { 5914 return true; 5915 } 5916 5917 return false; 5918 } 5919 5920 /** Return the character (as a string) of a keyEvent - ie, press the 'a' key and 5921 * this method will return 'a', press SHIFT-a and it will return 'A'. 5922 * 5923 * @param keyEvent 5924 * @returns string 5925 */ 5926 5927 Xinha.prototype.getKey = function(keyEvent) { Xinha.notImplemented("getKey"); } 5928 5920 5929 /** Return the HTML string of the given Element, including the Element. 5921 5930 * … … 5926 5935 Xinha.getOuterHTML = function(element) { Xinha.notImplemented("getOuterHTML"); } 5927 5936 5928 5929 5937 /** Get a new XMLHTTPRequest Object ready to be used. 5938 * 5939 * @returns object XMLHTTPRequest 5940 */ 5941 5942 Xinha.getXMLHTTPRequestObject = function() 5943 { 5944 try 5945 { 5946 return new XMLHttpRequest(); 5947 } 5948 catch(e) 5949 { 5950 Xinha.notImplemented('getXMLHTTPRequestObject'); 5951 } 5952 } 5953 5930 5954 // Compatability - all these names are deprecated and will be removed in a future version 5931 5955 Xinha.prototype._activeElement = function(sel) { return this.activeElement(sel); } -
trunk/functionsIE.js
r672 r674 51 51 InternetExplorer.prototype.onKeyPress = function(ev) 52 52 { 53 // Shortcuts 54 if(this.editor.isShortCut(ev)) 55 { 56 switch(this.editor.getKey(ev).toLowerCase()) 57 { 58 case 'n': 59 { 60 this.editor.execCommand('formatblock', false, '<p>'); 61 Xinha._stopEvent(ev); 62 return true; 63 } 64 break; 65 66 case '1': 67 case '2': 68 case '3': 69 case '4': 70 case '5': 71 case '6': 72 { 73 this.editor.execCommand('formatblock', false, '<h'+this.editor.getKey(ev).toLowerCase()+'>'); 74 Xinha._stopEvent(ev); 75 return true; 76 } 77 break; 78 } 79 } 80 53 81 switch(ev.keyCode) 54 82 { … … 107 135 } 108 136 }; 137 138 InternetExplorer.prototype.inwardHtml = function(html) 139 { 140 // Both IE and Gecko use strike internally instead of del (#523) 141 // Xinha will present del externally (see Xinha.prototype.outwardHtml 142 html = html.replace(/<(\/?)del(\s|>|\/)/ig, "<$1strike$2"); 143 144 return html; 145 } 109 146 110 147 /*--------------------------------------------------------------------------*/ … … 338 375 } 339 376 377 /** Return the character (as a string) of a keyEvent - ie, press the 'a' key and 378 * this method will return 'a', press SHIFT-a and it will return 'A'. 379 * 380 * @param keyEvent 381 * @returns string 382 */ 383 384 Xinha.prototype.getKey = function(keyEvent) 385 { 386 return String.fromCharCode(keyEvent.keyCode); 387 } 388 389 340 390 /** Return the HTML string of the given Element, including the Element. 341 391 * … … 349 399 }; 350 400 401 /** Get a new XMLHTTPRequest Object ready to be used. 402 * 403 * @returns object XMLHTTPRequest 404 */ 405 406 Xinha.getXMLHTTPRequestObject = function () { return new ActiveXObject("Microsoft.XMLHTTP"); } -
trunk/functionsMozilla.js
r673 r674 52 52 { 53 53 var editor = this.editor; 54 55 if ( ev.ctrlKey && editor._unLink && editor._unlinkOnUndo )56 {57 if ( String.fromCharCode(ev.charCode).toLowerCase() == 'z' )58 {59 Xinha._stopEvent(ev);60 editor._unLink();61 editor.updateToolbar();62 return true; // Stop further63 }64 }65 66 54 var s = editor._getSelection(); 67 var autoWrap = function (textNode, tag) 68 { 69 var rightText = textNode.nextSibling; 70 if ( typeof tag == 'string') 71 { 72 tag = editor._doc.createElement(tag); 73 } 74 var a = textNode.parentNode.insertBefore(tag, rightText); 75 Xinha.removeFromParent(textNode); 76 a.appendChild(textNode); 77 rightText.data = ' ' + rightText.data; 78 79 s.collapse(rightText, 1); 80 // Xinha._stopEvent(ev); 81 82 editor._unLink = function() 83 { 84 var t = a.firstChild; 85 a.removeChild(t); 86 a.parentNode.insertBefore(t, a); 87 Xinha.removeFromParent(a); 88 editor._unLink = null; 89 editor._unlinkOnUndo = false; 90 }; 91 editor._unlinkOnUndo = true; 92 93 return a; 94 }; 95 96 switch ( ev.which ) 55 56 // Handle shortcuts 57 if(editor.isShortCut(ev)) 58 { 59 switch(editor.getKey(ev).toLowerCase()) 60 { 61 case 'z': 62 { 63 if(editor._unLink && editor._unlinkOnUndo) 64 { 65 Xinha._stopEvent(ev); 66 editor._unLink(); 67 editor.updateToolbar(); 68 return true; 69 } 70 } 71 break; 72 73 case 'a': 74 { 75 // KEY select all 76 sel = this._getSelection(); 77 sel.removeAllRanges(); 78 range = this._createRange(); 79 range.selectNodeContents(this._doc.body); 80 sel.addRange(range); 81 Xinha._stopEvent(ev); 82 return true; 83 } 84 break; 85 86 case 'v': 87 { 88 // If we are not using htmlareaPaste, don't let Xinha try and be fancy but let the 89 // event be handled normally by the browser (don't stopEvent it) 90 if(!editor.config.htmlareaPaste) 91 { 92 return true; 93 } 94 } 95 break; 96 } 97 } 98 99 // Handle normal characters 100 switch(editor.getKey(ev)) 97 101 { 98 102 // Space, see if the text just typed looks like a URL, or email address 99 103 // and link it appropriatly 100 case 32: 104 case ' ': 105 { 106 var autoWrap = function (textNode, tag) 107 { 108 var rightText = textNode.nextSibling; 109 if ( typeof tag == 'string') 110 { 111 tag = editor._doc.createElement(tag); 112 } 113 var a = textNode.parentNode.insertBefore(tag, rightText); 114 Xinha.removeFromParent(textNode); 115 a.appendChild(textNode); 116 rightText.data = ' ' + rightText.data; 117 118 s.collapse(rightText, 1); 119 120 editor._unLink = function() 121 { 122 var t = a.firstChild; 123 a.removeChild(t); 124 a.parentNode.insertBefore(t, a); 125 Xinha.removeFromParent(a); 126 editor._unLink = null; 127 editor._unlinkOnUndo = false; 128 }; 129 editor._unlinkOnUndo = true; 130 131 return a; 132 }; 133 101 134 if ( editor.config.convertUrlsToLinks && s && s.isCollapsed && s.anchorNode.nodeType == 3 && s.anchorNode.data.length > 3 && s.anchorNode.data.indexOf('.') >= 0 ) 102 135 { … … 144 177 } 145 178 } 179 } 180 break; 181 } 182 183 // Handle special keys 184 switch ( ev.keyCode ) 185 { 186 case 13: // ENTER 187 if( !ev.shiftKey && editor.config.mozParaHandler == 'dirty' ) 188 { 189 editor.dom_checkInsertP(); 190 Xinha._stopEvent(ev); 191 } 146 192 break; 147 193 194 case 27: // ESCAPE 195 { 196 if ( editor._unLink ) 197 { 198 editor._unLink(); 199 Xinha._stopEvent(ev); 200 } 201 break; 202 } 203 break; 204 205 case 8: // KEY backspace 206 case 46: // KEY delete 207 { 208 // We handle the mozilla backspace directly?? 209 if ( !ev.shiftKey && this.handleBackspace() ) 210 { 211 Xinha._stopEvent(ev); 212 } 213 } 214 148 215 default: 149 if ( ev.keyCode == 27 || ( editor._unlinkOnUndo && ev.ctrlKey && ev.which == 122 ) ) 150 { 151 if ( editor._unLink ) 152 { 153 editor._unLink(); 154 Xinha._stopEvent(ev); 155 } 156 break; 157 } 158 else if ( ev.which || ev.keyCode == 8 || ev.keyCode == 46 ) 159 { 216 { 160 217 editor._unlinkOnUndo = false; 161 218 219 // Handle the "auto-linking", specifically this bit of code sets up a handler on 220 // an self-titled anchor (eg <a href="http://www.gogo.co.nz/">www.gogo.co.nz</a>) 221 // when the text content is edited, such that it will update the href on the anchor 222 162 223 if ( s.anchorNode && s.anchorNode.nodeType == 3 ) 163 224 { … … 169 230 break; // not an anchor 170 231 } 232 171 233 if ( !a._updateAnchTimeout ) 172 234 { … … 180 242 // This lead to never ending timer if we dont remove this line 181 243 // But when removed, the email is not correctly updated 244 // 245 // - to fix this we should make fnAnchor check to see if textNode.data has 246 // stopped changing for say 5 seconds and if so we do not make this setTimeout 182 247 a._updateAnchTimeout = setTimeout(fnAnchor, 250); 183 248 }; … … 192 257 var fnUrl = function() 193 258 { 194 // @fixme: Alert, sometimes m is undefined becase the url is not an url anymore (was www.url.com and become for example www.url)259 // Sometimes m is undefined becase the url is not an url anymore (was www.url.com and become for example www.url) 195 260 m = txtNode.data.match(Xinha.RE_url); 196 a.href = (m[1] ? m[1] : 'http://') + m[2]; 261 if(m) 262 { 263 a.href = (m[1] ? m[1] : 'http://') + m[2]; 264 } 265 197 266 // @fixme: why the hell do another timeout is started ? 198 267 // This lead to never ending timer if we dont remove this line 199 268 // But when removed, the url is not correctly updated 269 // 270 // - to fix this we should make fnUrl check to see if textNode.data has 271 // stopped changing for say 5 seconds and if so we do not make this setTimeout 200 272 a._updateAnchTimeout = setTimeout(fnUrl, 250); 201 273 }; 202 274 a._updateAnchTimeout = setTimeout(fnUrl, 1000); 203 275 } 204 } 205 } 206 }276 } 277 } 278 } 207 279 break; 208 280 } 209 281 210 // other keys here211 switch (ev.keyCode)212 {213 case 13: // KEY enter214 if( !ev.shiftKey && editor.config.mozParaHandler == 'dirty' )215 {216 editor.dom_checkInsertP();217 Xinha._stopEvent(ev);218 }219 break;220 case 8: // KEY backspace221 case 46: // KEY delete222 if ( !ev.shiftKey && this.handleBackspace() )223 {224 Xinha._stopEvent(ev);225 }226 break;227 }228 229 282 return false; // Let other plugins etc continue from here. 230 283 } … … 270 323 10); 271 324 }; 325 326 Gecko.prototype.inwardHtml = function(html) 327 { 328 // Midas uses b and i internally instead of strong and em 329 // Xinha will use strong and em externally (see Xinha.prototype.outwardHtml) 330 html = html.replace(/<(\/?)strong(\s|>|\/)/ig, "<$1b$2"); 331 html = html.replace(/<(\/?)em(\s|>|\/)/ig, "<$1i$2"); 332 333 // Both IE and Gecko use strike internally instead of del (#523) 334 // Xinha will present del externally (see Xinha.prototype.outwardHtml 335 html = html.replace(/<(\/?)del(\s|>|\/)/ig, "<$1strike$2"); 336 337 return html; 338 } 339 340 Gecko.prototype.outwardHtml = function(html) 341 { 342 // ticket:56, the "greesemonkey" plugin for Firefox adds this junk, 343 // so we strip it out. Original submitter gave a plugin, but that's 344 // a bit much just for this IMHO - james 345 html = html.replace(/<script[\s]*src[\s]*=[\s]*['"]chrome:\/\/.*?["']>[\s]*<\/script>/ig, ''); 346 347 return html; 348 } 349 350 Gecko.prototype.onExecCommand = function(cmdID, UI, param) 351 { 352 try 353 { 354 // useCSS deprecated & replaced by styleWithCSS 355 this.editor._doc.execCommand('useCSS', false, true); //switch useCSS off (true=off) 356 this.editor._doc.execCommand('styleWithCSS', false, false); //switch styleWithCSS off 357 } catch (ex) {} 358 359 switch(cmdID) 360 { 361 case 'paste': 362 { 363 alert(Xinha._lc("The Paste button does not work in Mozilla based web browsers (technical security reasons). Press CTRL-V on your keyboard to paste directly.")); 364 return true; // Indicate paste is done, stop command being issued to browser by Xinha.prototype.execCommand 365 } 366 } 367 368 return false; 369 } 370 272 371 273 372 /*--------------------------------------------------------------------------*/ … … 530 629 } 531 630 631 /** Return the character (as a string) of a keyEvent - ie, press the 'a' key and 632 * this method will return 'a', press SHIFT-a and it will return 'A'. 633 * 634 * @param keyEvent 635 * @returns string 636 */ 637 638 Xinha.prototype.getKey = function(keyEvent) 639 { 640 return String.fromCharCode(keyEvent.charCode); 641 } 642 532 643 /** Return the HTML string of the given Element, including the Element. 533 644 * … … 540 651 return (new XMLSerializer()).serializeToString(element); 541 652 }; 653 654 /*--------------------------------------------------------------------------*/ 655 /*------------ EXTEND SOME STANDARD "Xinha.prototype" METHODS --------------*/ 656 /*--------------------------------------------------------------------------*/ 657 658 Xinha.prototype._standardToggleBorders = Xinha.prototype._toggleBorders; 659 Xinha.prototype._toggleBorders = function() 660 { 661 var result = Xinha.prototype._standardToggleBorders(); 662 663 // flashing the display forces moz to listen (JB:18-04-2005) - #102 664 var tables = this._doc.getElementByTagName('TABLE'); 665 for(var i = 0; i < tables.length; i++) 666 { 667 tables[i].style.display="none"; 668 tables[i].style.display="table"; 669 } 670 671 return result; 672 }
