Changeset 4353
- Timestamp:
- Sep 27, 2008, 6:53:17 PM (16 years ago)
- Location:
- tracwysiwygplugin
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
tracwysiwygplugin/0.10/tracwysiwyg/htdocs/wysiwyg.js
r4214 r4353 438 438 439 439 TracWysiwyg.prototype.setupEditorEvents = function() { 440 var getSelfOrAncestor = TracWysiwyg.getSelfOrAncestor; 440 441 var self = this; 441 442 var d = this.contentDocument; … … 447 448 var args = null; 448 449 event = event || self.contentWindow.event; 449 if (event.keyCode == 0xe5) { 450 var keyCode = event.keyCode; 451 switch (keyCode) { 452 case 0x09: // TAB 453 var range = self.getSelectionRange(); 454 var element = getSelfOrAncestor(range.startContainer, /^(?:li|pre|table)$/); 455 if (element) { 456 switch (element.tagName.toLowerCase()) { 457 case "li": 458 self.execCommand(event.shiftKey ? "outdent" : "indent"); 459 self.selectionChanged(); 460 break; 461 case "pre": 462 self.insertHTML("\t"); 463 break; 464 case "table": 465 if (getSelfOrAncestor(range.endContainer, "table") == element) { 466 self.moveFocusInTable(!event.shiftKey); 467 self.selectionChanged(); 468 } 469 break; 470 } 471 } 472 TracWysiwyg.stopEvent(event); 473 return; 474 case 0xe5: 450 475 ime = true; 451 } 452 switch ((event.keyCode & 0x00fffff) | (event.ctrlKey ? 0x40000000 : 0) 476 break; 477 } 478 switch ((keyCode & 0x00fffff) | (event.ctrlKey ? 0x40000000 : 0) 453 479 | (event.shiftKey ? 0x20000000 : 0) | (event.altKey ? 0x10000000 : 0)) 454 480 { … … 483 509 self.selectionChanged(); 484 510 } 511 else if (keyCode) { 512 var focus = self.getFocusNode(); 513 if (!getSelfOrAncestor(focus, /^(?:p|li|h[1-6]|t[dh]|d[td]|pre|blockquote)$/)) { 514 self.execCommand("formatblock", "<p>"); 515 } 516 } 485 517 } 486 518 addEvent(d, window.opera ? "keypress" : "keydown", listenerKeydown); … … 548 580 } 549 581 var fragment = this.wikitextToFragment(this.textarea.value, d); 550 if (fragment.childNodes.length == 0) {551 var paragraph = d.createElement("p");552 this.appendBogusLineBreak(paragraph);553 fragment.appendChild(paragraph);554 }555 582 container.appendChild(fragment); 556 583 this.savedWysiwygHTML = container.innerHTML; … … 874 901 if (cellIndex < row.cells.length) { 875 902 row.deleteCell(cellIndex); 903 } 904 } 905 } 906 }; 907 908 TracWysiwyg.prototype.moveFocusInTable = function(forward) { 909 var getSelfOrAncestor = TracWysiwyg.getSelfOrAncestor; 910 var focus = this.getFocusNode(); 911 var element = getSelfOrAncestor(focus, /^(?:t[dhr]|table)$/); 912 var target, table, rows, cells; 913 switch (element.tagName.toLowerCase()) { 914 case "td": case "th": 915 focus = element; 916 var row = getSelfOrAncestor(element, "tr"); 917 cells = row.cells; 918 if (forward) { 919 if (focus.cellIndex + 1 < cells.length) { 920 target = cells[focus.cellIndex + 1]; 921 } 922 else { 923 table = getSelfOrAncestor(row, /^(?:tbody|table)$/); 924 rows = table.rows; 925 target = row.rowIndex + 1 < rows.length ? rows[row.rowIndex + 1].cells[0] : null; 926 } 927 } 928 else { 929 if (focus.cellIndex > 0) { 930 target = cells[focus.cellIndex - 1]; 931 } 932 else { 933 table = getSelfOrAncestor(row, /^(?:tbody|table)$/); 934 rows = table.rows; 935 if (row.rowIndex > 0) { 936 cells = rows[row.rowIndex - 1].cells; 937 target = cells[cells.length - 1]; 938 } 939 else { 940 target = null; 941 } 942 } 943 } 944 break; 945 case "tr": 946 cells = element.cells; 947 target = cells[forward ? 0 : cells.length - 1]; 948 break; 949 case "tbody": case "table": 950 rows = element.rows; 951 cells = rows[forward ? 0 : rows.length - 1].cells; 952 target = cells[forward ? 0 : cells.length - 1]; 953 break; 954 } 955 if (target) { 956 this.selectNodeContents(target); 957 } 958 else if (table) { 959 table = getSelfOrAncestor(table, "table"); 960 var parent = table.parentNode; 961 var elements = parent.childNodes; 962 var length = elements.length; 963 for (var offset = 0; offset < length; offset++) { 964 if (table == elements[offset]) { 965 if (forward) { 966 offset++; 967 } 968 this.selectRange(parent, offset, parent, offset); 876 969 } 877 970 } … … 2973 3066 var body = d.body; 2974 3067 d.selection.empty(); 3068 var range = endPoint(start, startOffset); 3069 if (start != end || startOffset != endOffset) { 3070 range.setEndPoint("EndToEnd", endPoint(end, endOffset)); 3071 } 3072 range.select(); 2975 3073 2976 3074 function endPoint(node, offset) { 2977 var range = body.createTextRange(); 2978 var childNodes = node.childNodes; 3075 var range; 2979 3076 if (node.nodeType == 1) { 3077 var childNodes = node.childNodes; 2980 3078 if (offset >= childNodes.length) { 3079 range = body.createTextRange(); 2981 3080 range.moveToElementText(node); 2982 3081 range.collapse(false); … … 2985 3084 node = childNodes[offset]; 2986 3085 if (node.nodeType == 1) { 3086 range = body.createTextRange(); 2987 3087 range.moveToElementText(node); 2988 3088 range.collapse(true); 3089 switch (node.tagName.toLowerCase()) { 3090 case "table": 3091 range.move("character", -1); 3092 break; 3093 } 2989 3094 return range; 2990 3095 } … … 2995 3100 } 2996 3101 3102 range = body.createTextRange(); 2997 3103 var element = node.previousSibling; 2998 3104 while (element) { … … 3012 3118 range.collapse(true); 3013 3119 } 3014 range.move("character", offset); 3120 if (offset != 0) { 3121 range.move("character", offset); 3122 } 3015 3123 return range; 3016 3124 } 3017 3018 var range = body.createTextRange();3019 range.setEndPoint("StartToStart", endPoint(start, startOffset));3020 range.setEndPoint("EndToEnd", endPoint(end, endOffset));3021 range.select();3022 3125 }; 3023 3126 TracWysiwyg.prototype.getSelectionRange = function() { 3024 3127 var body = this.contentDocument.body; 3128 var pseudo = {}; 3025 3129 var start = this.getNativeSelectionRange(); 3130 if (start.item) { 3131 var element = start.item(0); 3132 var parent = element.parentNode; 3133 var childNodes = parent.childNodes; 3134 var length = childNodes.length; 3135 for (var i = 0; i < length; i++) { 3136 if (childNodes[i] == element) { 3137 pseudo.startOffset = i; 3138 pseudo.endOffset = i + 1; 3139 break; 3140 } 3141 } 3142 pseudo.collapsed = false; 3143 pseudo.startContainer = pseudo.endContainer = parent; 3144 return pseudo; 3145 } 3026 3146 var end = start.duplicate(); 3027 var pseudo = {};3028 3147 pseudo.collapsed = start.compareEndPoints("StartToEnd", end) == 0; 3029 3148 start.collapse(true); … … 3069 3188 var index = 0; 3070 3189 var node = element ? element.previousSibling : parent.lastChild; 3071 while (node.nodeType == 3) { 3072 var length = node.nodeValue.length; 3073 var offset = nodeOffset(range, parent, element, index, length); 3190 var offset, length; 3191 while (node && node.nodeType == 3) { 3192 length = node.nodeValue.length; 3193 offset = nodeOffset(range, parent, element, index, length); 3074 3194 if (offset !== null) { 3075 3195 pseudo[containerKey] = node; … … 3079 3199 index += length; 3080 3200 node = node.previousSibling; 3201 } 3202 var childNodes = parent.childNodes; 3203 length = childNodes.length; 3204 if (length > 0) { 3205 pseudo[containerKey] = parent; 3206 pseudo[offsetKey] = containerKey == "startContainer" ? 0 : length - 1; 3207 return; 3208 } 3209 element = parent; 3210 parent = element.parentNode; 3211 childNodes = parent.childNodes; 3212 length = childNodes.length; 3213 for (offset = 0; offset < length; offset++) { 3214 if (element == childNodes[offset]) { 3215 pseudo[containerKey] = parent; 3216 pseudo[offsetKey] = offset; 3217 return; 3218 } 3081 3219 } 3082 3220 } … … 3087 3225 }; 3088 3226 TracWysiwyg.prototype.getNativeSelectionRange = function() { 3089 var range = this.contentDocument.selection.createRange(); 3090 if (range && range.item) { 3091 range = range.item(0); 3092 } 3093 return range; 3227 return this.contentDocument.selection.createRange(); 3094 3228 }; 3095 3229 TracWysiwyg.prototype.getSelectionText = function() { 3096 3230 var range = this.getNativeSelectionRange(); 3097 return range ? range.text : null; 3231 if (range) { 3232 return range.item ? range.item(0).innerText : range.text; 3233 } 3234 return null; 3098 3235 }; 3099 3236 TracWysiwyg.prototype.getSelectionHTML = function() { 3100 3237 var range = this.getNativeSelectionRange(); 3101 return range ? range.htmlText : null; 3238 if (range) { 3239 return range.item ? range.item(0).innerHTML : range.htmlText; 3240 } 3241 return null; 3102 3242 }; 3103 3243 TracWysiwyg.prototype.getSelectionFragment = function() { … … 3179 3319 TracWysiwyg.prototype.insertHTML = function(html) { 3180 3320 var range = this.contentDocument.selection.createRange(); 3181 range.pasteHTML(html); 3321 if (/^\s+$/.exec(html)) { 3322 range.text = html; 3323 } 3324 else { 3325 range.pasteHTML(html.replace(/\t/g, "	")); 3326 } 3182 3327 }; 3183 3328 } -
tracwysiwygplugin/0.11/tracwysiwyg/htdocs/wysiwyg.js
r4214 r4353 438 438 439 439 TracWysiwyg.prototype.setupEditorEvents = function() { 440 var getSelfOrAncestor = TracWysiwyg.getSelfOrAncestor; 440 441 var self = this; 441 442 var d = this.contentDocument; … … 447 448 var args = null; 448 449 event = event || self.contentWindow.event; 449 if (event.keyCode == 0xe5) { 450 var keyCode = event.keyCode; 451 switch (keyCode) { 452 case 0x09: // TAB 453 var range = self.getSelectionRange(); 454 var element = getSelfOrAncestor(range.startContainer, /^(?:li|pre|table)$/); 455 if (element) { 456 switch (element.tagName.toLowerCase()) { 457 case "li": 458 self.execCommand(event.shiftKey ? "outdent" : "indent"); 459 self.selectionChanged(); 460 break; 461 case "pre": 462 self.insertHTML("\t"); 463 break; 464 case "table": 465 if (getSelfOrAncestor(range.endContainer, "table") == element) { 466 self.moveFocusInTable(!event.shiftKey); 467 self.selectionChanged(); 468 } 469 break; 470 } 471 } 472 TracWysiwyg.stopEvent(event); 473 return; 474 case 0xe5: 450 475 ime = true; 451 } 452 switch ((event.keyCode & 0x00fffff) | (event.ctrlKey ? 0x40000000 : 0) 476 break; 477 } 478 switch ((keyCode & 0x00fffff) | (event.ctrlKey ? 0x40000000 : 0) 453 479 | (event.shiftKey ? 0x20000000 : 0) | (event.altKey ? 0x10000000 : 0)) 454 480 { … … 483 509 self.selectionChanged(); 484 510 } 511 else if (keyCode) { 512 var focus = self.getFocusNode(); 513 if (!getSelfOrAncestor(focus, /^(?:p|li|h[1-6]|t[dh]|d[td]|pre|blockquote)$/)) { 514 self.execCommand("formatblock", "<p>"); 515 } 516 } 485 517 } 486 518 addEvent(d, window.opera ? "keypress" : "keydown", listenerKeydown); … … 548 580 } 549 581 var fragment = this.wikitextToFragment(this.textarea.value, d); 550 if (fragment.childNodes.length == 0) {551 var paragraph = d.createElement("p");552 this.appendBogusLineBreak(paragraph);553 fragment.appendChild(paragraph);554 }555 582 container.appendChild(fragment); 556 583 this.savedWysiwygHTML = container.innerHTML; … … 874 901 if (cellIndex < row.cells.length) { 875 902 row.deleteCell(cellIndex); 903 } 904 } 905 } 906 }; 907 908 TracWysiwyg.prototype.moveFocusInTable = function(forward) { 909 var getSelfOrAncestor = TracWysiwyg.getSelfOrAncestor; 910 var focus = this.getFocusNode(); 911 var element = getSelfOrAncestor(focus, /^(?:t[dhr]|table)$/); 912 var target, table, rows, cells; 913 switch (element.tagName.toLowerCase()) { 914 case "td": case "th": 915 focus = element; 916 var row = getSelfOrAncestor(element, "tr"); 917 cells = row.cells; 918 if (forward) { 919 if (focus.cellIndex + 1 < cells.length) { 920 target = cells[focus.cellIndex + 1]; 921 } 922 else { 923 table = getSelfOrAncestor(row, /^(?:tbody|table)$/); 924 rows = table.rows; 925 target = row.rowIndex + 1 < rows.length ? rows[row.rowIndex + 1].cells[0] : null; 926 } 927 } 928 else { 929 if (focus.cellIndex > 0) { 930 target = cells[focus.cellIndex - 1]; 931 } 932 else { 933 table = getSelfOrAncestor(row, /^(?:tbody|table)$/); 934 rows = table.rows; 935 if (row.rowIndex > 0) { 936 cells = rows[row.rowIndex - 1].cells; 937 target = cells[cells.length - 1]; 938 } 939 else { 940 target = null; 941 } 942 } 943 } 944 break; 945 case "tr": 946 cells = element.cells; 947 target = cells[forward ? 0 : cells.length - 1]; 948 break; 949 case "tbody": case "table": 950 rows = element.rows; 951 cells = rows[forward ? 0 : rows.length - 1].cells; 952 target = cells[forward ? 0 : cells.length - 1]; 953 break; 954 } 955 if (target) { 956 this.selectNodeContents(target); 957 } 958 else if (table) { 959 table = getSelfOrAncestor(table, "table"); 960 var parent = table.parentNode; 961 var elements = parent.childNodes; 962 var length = elements.length; 963 for (var offset = 0; offset < length; offset++) { 964 if (table == elements[offset]) { 965 if (forward) { 966 offset++; 967 } 968 this.selectRange(parent, offset, parent, offset); 876 969 } 877 970 } … … 2973 3066 var body = d.body; 2974 3067 d.selection.empty(); 3068 var range = endPoint(start, startOffset); 3069 if (start != end || startOffset != endOffset) { 3070 range.setEndPoint("EndToEnd", endPoint(end, endOffset)); 3071 } 3072 range.select(); 2975 3073 2976 3074 function endPoint(node, offset) { 2977 var range = body.createTextRange(); 2978 var childNodes = node.childNodes; 3075 var range; 2979 3076 if (node.nodeType == 1) { 3077 var childNodes = node.childNodes; 2980 3078 if (offset >= childNodes.length) { 3079 range = body.createTextRange(); 2981 3080 range.moveToElementText(node); 2982 3081 range.collapse(false); … … 2985 3084 node = childNodes[offset]; 2986 3085 if (node.nodeType == 1) { 3086 range = body.createTextRange(); 2987 3087 range.moveToElementText(node); 2988 3088 range.collapse(true); 3089 switch (node.tagName.toLowerCase()) { 3090 case "table": 3091 range.move("character", -1); 3092 break; 3093 } 2989 3094 return range; 2990 3095 } … … 2995 3100 } 2996 3101 3102 range = body.createTextRange(); 2997 3103 var element = node.previousSibling; 2998 3104 while (element) { … … 3012 3118 range.collapse(true); 3013 3119 } 3014 range.move("character", offset); 3120 if (offset != 0) { 3121 range.move("character", offset); 3122 } 3015 3123 return range; 3016 3124 } 3017 3018 var range = body.createTextRange();3019 range.setEndPoint("StartToStart", endPoint(start, startOffset));3020 range.setEndPoint("EndToEnd", endPoint(end, endOffset));3021 range.select();3022 3125 }; 3023 3126 TracWysiwyg.prototype.getSelectionRange = function() { 3024 3127 var body = this.contentDocument.body; 3128 var pseudo = {}; 3025 3129 var start = this.getNativeSelectionRange(); 3130 if (start.item) { 3131 var element = start.item(0); 3132 var parent = element.parentNode; 3133 var childNodes = parent.childNodes; 3134 var length = childNodes.length; 3135 for (var i = 0; i < length; i++) { 3136 if (childNodes[i] == element) { 3137 pseudo.startOffset = i; 3138 pseudo.endOffset = i + 1; 3139 break; 3140 } 3141 } 3142 pseudo.collapsed = false; 3143 pseudo.startContainer = pseudo.endContainer = parent; 3144 return pseudo; 3145 } 3026 3146 var end = start.duplicate(); 3027 var pseudo = {};3028 3147 pseudo.collapsed = start.compareEndPoints("StartToEnd", end) == 0; 3029 3148 start.collapse(true); … … 3069 3188 var index = 0; 3070 3189 var node = element ? element.previousSibling : parent.lastChild; 3071 while (node.nodeType == 3) { 3072 var length = node.nodeValue.length; 3073 var offset = nodeOffset(range, parent, element, index, length); 3190 var offset, length; 3191 while (node && node.nodeType == 3) { 3192 length = node.nodeValue.length; 3193 offset = nodeOffset(range, parent, element, index, length); 3074 3194 if (offset !== null) { 3075 3195 pseudo[containerKey] = node; … … 3079 3199 index += length; 3080 3200 node = node.previousSibling; 3201 } 3202 var childNodes = parent.childNodes; 3203 length = childNodes.length; 3204 if (length > 0) { 3205 pseudo[containerKey] = parent; 3206 pseudo[offsetKey] = containerKey == "startContainer" ? 0 : length - 1; 3207 return; 3208 } 3209 element = parent; 3210 parent = element.parentNode; 3211 childNodes = parent.childNodes; 3212 length = childNodes.length; 3213 for (offset = 0; offset < length; offset++) { 3214 if (element == childNodes[offset]) { 3215 pseudo[containerKey] = parent; 3216 pseudo[offsetKey] = offset; 3217 return; 3218 } 3081 3219 } 3082 3220 } … … 3087 3225 }; 3088 3226 TracWysiwyg.prototype.getNativeSelectionRange = function() { 3089 var range = this.contentDocument.selection.createRange(); 3090 if (range && range.item) { 3091 range = range.item(0); 3092 } 3093 return range; 3227 return this.contentDocument.selection.createRange(); 3094 3228 }; 3095 3229 TracWysiwyg.prototype.getSelectionText = function() { 3096 3230 var range = this.getNativeSelectionRange(); 3097 return range ? range.text : null; 3231 if (range) { 3232 return range.item ? range.item(0).innerText : range.text; 3233 } 3234 return null; 3098 3235 }; 3099 3236 TracWysiwyg.prototype.getSelectionHTML = function() { 3100 3237 var range = this.getNativeSelectionRange(); 3101 return range ? range.htmlText : null; 3238 if (range) { 3239 return range.item ? range.item(0).innerHTML : range.htmlText; 3240 } 3241 return null; 3102 3242 }; 3103 3243 TracWysiwyg.prototype.getSelectionFragment = function() { … … 3179 3319 TracWysiwyg.prototype.insertHTML = function(html) { 3180 3320 var range = this.contentDocument.selection.createRange(); 3181 range.pasteHTML(html); 3321 if (/^\s+$/.exec(html)) { 3322 range.text = html; 3323 } 3324 else { 3325 range.pasteHTML(html.replace(/\t/g, "	")); 3326 } 3182 3327 }; 3183 3328 }
Note: See TracChangeset
for help on using the changeset viewer.