Changeset 4135
- Timestamp:
- 08/12/08 12:03:40 (3 months ago)
- Files:
-
- tracwysiwygplugin/0.10/tests/index.html (modified) (1 diff)
- tracwysiwygplugin/0.10/tests/testcase.js (modified) (9 diffs)
- tracwysiwygplugin/0.10/tracwysiwyg/htdocs/wysiwyg.js (modified) (16 diffs)
- tracwysiwygplugin/0.11/tests/index.html (modified) (1 diff)
- tracwysiwygplugin/0.11/tests/testcase.js (modified) (9 diffs)
- tracwysiwygplugin/0.11/tracwysiwyg/htdocs/wysiwyg.js (modified) (16 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
tracwysiwygplugin/0.10/tests/index.html
r2759 r4135 12 12 html { font-size: 13px; *font-size: small; } 13 13 body { font-family: Arial, Helvetica, sans-serif; font-size: 100%; } 14 textarea { font-size: 11px; }14 textarea { font-size: 11px; width: 100%; border: 1px solid #999; } 15 15 #testunit .current { background-color: #FFFF80; } 16 16 #testunit .success { background-color: #33dd88; } 17 17 #testunit .failure textarea { background-color: #ff3333; border-style: none; } 18 #wysiwyg-html { 19 width: 100%; 20 border: 1px solid #999; 21 font-size: 11px; 22 white-space: -moz-pre-wrap; 23 white-space: -pre-wrap; 24 white-space: -o-pre-wrap; 25 white-space: pre-wrap; 26 word-wrap: break-word; 27 } 18 28 </style> 19 29 </head> 20 30 <body> 21 31 <form method="post"> 22 <textarea id="textarea" class="wikitext" cols="50" rows="5" wrap="off"></textarea> 32 <textarea id="textarea" class="wikitext" cols="50" rows="20" wrap="off"></textarea> 33 <div> 34 <label><input type="checkbox" id="show-wysiwyg-html" value="1" 35 onclick="document.getElementById('wysiwyg-html').style.display=this.checked?'':'none'" 36 />show html</label> 37 <textarea id="wysiwyg-html" cols="50" rows="12" style="display:none;"></textarea> 38 </div> 23 39 </form> 24 40 </body> tracwysiwygplugin/0.10/tests/testcase.js
r3847 r4135 3 3 var instance = new TracWysiwyg(document.getElementById("textarea")); 4 4 var contentDocument = instance.contentDocument; 5 6 var d = document; 7 var wysiwygHtml = d.getElementById("wysiwyg-html"); 8 var showWysiwygHtml = d.getElementById("show-wysiwyg-html"); 9 setTimeout(function() { 10 if (showWysiwygHtml.checked) { 11 var body = contentDocument.body; 12 var browserIE = body.attachEvent ? true : false; 13 var elements = body.getElementsByTagName("br"); 14 var count = 0; 15 var html = body.innerHTML.replace(/<[Bb][Rr] *[^>\/]*/g, function(value) { 16 var element = elements[count++]; 17 var attributes = element.attributes; 18 var length = attributes.length; 19 if (length == 0) 20 return value; 21 var texts = [ value ]; 22 for (var i = 0; i < length; i++) { 23 var attr = attributes[i]; 24 if (!browserIE || !!element[attr.name]) { 25 texts.push(' ', attr.name, '="', attr.value, '"'); 26 } 27 } 28 return texts.join(""); 29 }); 30 if (wysiwygHtml.value != html) { 31 wysiwygHtml.value = html; 32 } 33 } 34 setTimeout(arguments.callee, 500); 35 }, 500); 5 36 6 37 function generate(dom, wikitext, withoutDomToWikitext, withoutWikitextToFragment) { … … 674 705 unit.add("block + br", function() { 675 706 function br() { return element("br"); } 676 function br_moz() { return element("br", { "type": "_moz" }); }677 707 var wikitext = [ 678 "text, br {_moz}",708 "text, br", 679 709 "", 680 710 "text'', br[[BR]]''", … … 684 714 "", 685 715 " * list, br[[BR]]", 686 " * list, br {_moz}",716 " * list, br", 687 717 " * ", 688 718 "", … … 690 720 generateWikitext.call(this, 691 721 fragment( 692 element("p", "text, br {_moz}", br_moz()),693 element("p", "text", element("i", ", br", br()), br _moz()),722 element("p", "text, br", br()), 723 element("p", "text", element("i", ", br", br()), br()), 694 724 element("table", { "class": "wiki" }, 695 725 element("tbody", 696 726 element("tr", 697 element("td", "1,1", br(), br _moz()),698 element("td", br _moz()),699 element("td", "1,3", br _moz())),727 element("td", "1,1", br(), br()), 728 element("td", br()), 729 element("td", "1,3", br())), 700 730 element("tr", 701 element("td", br _moz()),702 element("td", "2,2", br(), br(), br _moz())))),731 element("td", br()), 732 element("td", "2,2", br(), br(), br())))), 703 733 element("ul", 734 element("li", "list, br", br(), br()), 704 735 element("li", "list, br", br()), 705 element("li", "list, br{_moz}", br_moz()),706 736 element("li")), 707 element("p", "text, br", br() )),737 element("p", "text, br", br(), br())), 708 738 wikitext); 709 739 generateFragment.call(this, 710 740 fragment( 711 element("p", "text, br {_moz}"),712 element("p", "text", element("i", ", br", br()), br _moz()),741 element("p", "text, br"), 742 element("p", "text", element("i", ", br", br()), br()), 713 743 element("table", { "class": "wiki" }, 714 744 element("tbody", 715 745 element("tr", 716 element("td", "1,1", br(), br _moz()),717 element("td", br _moz()),746 element("td", "1,1", br(), br()), 747 element("td", br()), 718 748 element("td", "1,3")), 719 749 element("tr", 720 element("td", br _moz()),721 element("td", "2,2", br(), br(), br _moz())))),750 element("td", br()), 751 element("td", "2,2", br(), br(), br())))), 722 752 element("ul", 723 element("li", "list, br", br(), br _moz()),724 element("li", "list, br {_moz}"),725 element("li", br _moz())),726 element("p", "text, br", br(), br _moz())),753 element("li", "list, br", br(), br()), 754 element("li", "list, br"), 755 element("li", br())), 756 element("p", "text, br", br(), br())), 727 757 wikitext); 728 758 }); … … 732 762 function br() { return element("br"); } 733 763 var wikitext = [ 734 "text, br {_moz}",764 "text, br", 735 765 "", 736 766 "text'', br[[BR]]''", … … 740 770 "", 741 771 " * list, br[[BR]]", 742 " * list, br {_moz}",772 " * list, br", 743 773 " * ", 744 774 "", … … 746 776 generate.call(this, 747 777 fragment( 748 element("p", "text, br {_moz}"),778 element("p", "text, br"), 749 779 element("p", "text", element("i", ", br", br())), 750 780 element("table", { "class": "wiki" }, … … 759 789 element("ul", 760 790 element("li", "list, br", br()), 761 element("li", "list, br {_moz}"),791 element("li", "list, br"), 762 792 element("li")), 763 793 element("p", "text, br", br())), … … 1364 1394 } 1365 1395 var body = d.body; 1396 while (body.childNodes.length > 0) { 1397 body.removeChild(body.lastChild); 1398 } 1366 1399 body.appendChild(fragment(d, 1367 1400 _element("p", tracwysiwygplugin/0.10/tracwysiwyg/htdocs/wysiwyg.js
r3856 r4135 347 347 case "quote": return [ self.formatQuoteBlock ]; 348 348 case "hr": return [ self.insertHorizontalRule ]; 349 case "br": return [ self.insert HTML, "<br />"];349 case "br": return [ self.insertLineBreak ]; 350 350 } 351 351 return null; … … 403 403 var position = this.getSelectionPosition(); 404 404 var ancestor = {}; 405 ancestor.start = getSelfOrAncestor(position.start, "a") || getSelfOrAncestor(position.start, "tt");406 ancestor.end = getSelfOrAncestor(position.end, "a") || getSelfOrAncestor(position.end, "tt");405 ancestor.start = getSelfOrAncestor(position.start, /^(?:a|tt)$/); 406 ancestor.end = getSelfOrAncestor(position.end, /^(?:a|tt)$/); 407 407 this.expandSelectionToElement(ancestor); 408 408 … … 488 488 function listenerKeypress(event) { 489 489 event = event || self.contentWindow.event; 490 var modifier = (event.ctrlKey ? 0x40000000 : 0) 491 | (event.shiftKey ? 0x20000000 : 0) | (event.altKey ? 0x10000000 : 0); 490 492 switch (event.charCode || event.keyCode) { 491 493 case 0x20: // SPACE … … 494 496 case 0x0d: // ENTER 495 497 self.detectTracLink(event); 498 switch (modifier) { 499 case 0: 500 if (self.insertParagraphOnEnter) { 501 self.insertParagraphOnEnter(event); 502 } 503 break; 504 case 0x20000000: // Shift 505 if (self.insertLineBreakOnShiftEnter) { 506 self.insertLineBreakOnShiftEnter(event); 507 } 508 break; 509 } 496 510 return; 497 511 } … … 500 514 501 515 function listenerKeyup(event) { 516 var keyCode = event.keyCode; 502 517 if (ime) { 503 switch ( event.keyCode) {518 switch (keyCode) { 504 519 case 0x20: // SPACE 505 520 self.detectTracLink(event); … … 626 641 } 627 642 var getSelfOrAncestor = TracWysiwyg.getSelfOrAncestor; 628 if (getSelfOrAncestor(node, "a") || getSelfOrAncestor(node, "tt") || getSelfOrAncestor(node, "pre")) {643 if (getSelfOrAncestor(node, /^(?:a|tt|pre)$/)) { 629 644 return; 630 645 } … … 710 725 if (event.shiftKey) { 711 726 if (window.opera || !anonymous.addEventListener) { 712 this.insertHTML(html + "<br />");727 this.insertHTML(html + "<br>"); 713 728 if (window.opera) { 714 729 anchor = this.contentDocument.getElementById(id); … … 810 825 var hash = { node: null, cell: null, row: null, table: null }; 811 826 hash.node = this.getFocusNode(); 812 hash.cell = hash.node 813 ? TracWysiwyg.getSelfOrAncestor(hash.node, "td") || TracWysiwyg.getSelfOrAncestor(hash.node, "th") 814 : null; 827 hash.cell = hash.node ? TracWysiwyg.getSelfOrAncestor(hash.node, /^t[dh]$/) : null; 815 828 hash.row = hash.cell ? TracWysiwyg.getSelfOrAncestor(hash.cell, "tr") : null; 816 829 hash.table = hash.row ? TracWysiwyg.getSelfOrAncestor(hash.row, "table") : null; … … 1242 1255 }; 1243 1256 1257 (function() { 1258 var blocks = { 1259 p: true, blockquote: true, div: true, 1260 li: true, ul: true, ol: true, 1261 dl: true, dt: true, dd: true, 1262 h1: true, h2: true, h3: true, h4: true, h5: true, h6: true, 1263 table: true, thead: true, tbody: true, tr: true, td: true, th: true }; 1264 1265 function generator(prop, blocks) { 1266 return function (node) { 1267 if (!node) { 1268 return false; 1269 } 1270 for ( ; ; ) { 1271 if (node[prop]) { 1272 return false; 1273 } 1274 node = node.parentNode; 1275 if (!node) { 1276 return false; 1277 } 1278 if (node.tagName.toLowerCase() in blocks) { 1279 return true; 1280 } 1281 } 1282 return false; 1283 }; 1284 } 1285 1286 TracWysiwyg.prototype.isLastChildInBlockNode = generator("nextSibling", blocks); 1287 TracWysiwyg.prototype.isFirstChildInBlockNode = generator("previousSibling", blocks); 1288 })(); 1289 1244 1290 TracWysiwyg.prototype.wikitextToFragment = function(wikitext, contentDocument) { 1245 1291 var getSelfOrAncestor = TracWysiwyg.getSelfOrAncestor; … … 2381 2427 break; 2382 2428 case "br": 2383 if ( node.getAttribute("type") != "_moz") {2429 if (!self.isBogusLineBreak(node)) { 2384 2430 var value; 2385 2431 if (inCodeBlock) { … … 2647 2693 } 2648 2694 var name = last.tagName.toLowerCase(); 2649 if (name == "br" && last.getAttribute("type") != "_moz") {2695 if (name == "br") { 2650 2696 break; 2651 2697 } … … 2656 2702 } 2657 2703 var br = this.contentDocument.createElement("br"); 2658 br.setAttribute("type", "_moz");2659 2704 element.appendChild(br); 2705 }; 2706 TracWysiwyg.prototype.isBogusLineBreak = TracWysiwyg.prototype.isLastChildInBlockNode; 2707 TracWysiwyg.prototype.insertParagraphOnEnter = function(event) { 2708 var range = this.getSelectionRange(); 2709 var node = range.endContainer; 2710 var header = null; 2711 if (node && node.nodeType == 3 && range.endOffset == node.nodeValue.length) { 2712 var nextSibling = node.nextSibling; 2713 if (!nextSibling || nextSibling.tagName.toLowerCase() == "br") { 2714 while (node) { 2715 if (node.nodeType == 1 && /^h[1-6]$/i.exec(node.tagName)) { 2716 header = node; 2717 break; 2718 } 2719 node = node.parentNode; 2720 } 2721 if (header) { 2722 var parent = header.parentNode; 2723 var childNodes = parent.childNodes; 2724 var length = childNodes.length; 2725 for (var offset = 0; offset < length; offset++) { 2726 if (childNodes[offset] == header) { 2727 offset++; 2728 break; 2729 } 2730 } 2731 this.selectRange(parent, offset, parent, offset); 2732 this.insertHTML('<p><br></p>'); 2733 TracWysiwyg.stopEvent(event); 2734 } 2735 } 2736 } 2660 2737 }; 2661 2738 TracWysiwyg.prototype.tableHTML = function(id, row, col) { 2662 2739 var html = this._tableHTML(row, col); 2663 return html.replace(/<td><\/td>/g, '<td><br type="_moz" /></td>').replace(/<td>/, '<td id="' + id + '">');2740 return html.replace(/<td><\/td>/g, '<td><br></td>').replace(/<td>/, '<td id="' + id + '">'); 2664 2741 }; 2665 2742 TracWysiwyg.prototype.insertTableCell = function(row, index) { … … 2671 2748 return this.contentWindow.getSelection().focusNode; 2672 2749 }; 2750 if (window.opera) { 2751 TracWysiwyg.prototype.insertLineBreak = function() { 2752 this.execCommand("inserthtml", "<br>"); 2753 }; 2754 TracWysiwyg.prototype.insertLineBreakOnShiftEnter = null; 2755 } 2756 else if (window.getSelection().setBaseAndExtent) { // Safari 2+ 2757 TracWysiwyg.prototype.insertLineBreak = function() { 2758 this.execCommand("insertlinebreak"); 2759 }; 2760 TracWysiwyg.prototype.insertLineBreakOnShiftEnter = function(event) { 2761 this.insertLineBreak(); 2762 TracWysiwyg.stopEvent(event); 2763 }; 2764 } 2765 else { // Firefox 2+ 2766 TracWysiwyg.prototype.insertLineBreak = function() { 2767 var d = this.contentDocument; 2768 var event = d.createEvent("KeyboardEvent"); 2769 event.initKeyEvent("keypress", true, true, null, false, false, true, false, 0x000d, 0); 2770 d.body.dispatchEvent(event); 2771 }; 2772 TracWysiwyg.prototype.insertLineBreakOnShiftEnter = null; 2773 } 2673 2774 if (window.getSelection().removeAllRanges) { 2674 2775 TracWysiwyg.prototype.selectNode = function(node) { … … 2826 2927 else if (document.selection) { 2827 2928 TracWysiwyg.prototype.appendBogusLineBreak = function(element) { }; 2929 TracWysiwyg.prototype.isBogusLineBreak = function(node) { return false }; 2930 TracWysiwyg.prototype.insertParagraphOnEnter = null; 2931 TracWysiwyg.prototype.insertLineBreak = function() { 2932 this.insertHTML("<br>"); 2933 }; 2934 TracWysiwyg.prototype.insertLineBreakOnShiftEnter = null; 2828 2935 TracWysiwyg.prototype.tableHTML = function(id, row, col) { 2829 2936 var html = this._tableHTML(row, col); … … 3077 3184 else { 3078 3185 TracWysiwyg.prototype.appendBogusLineBreak = function(element) { }; 3186 TracWysiwyg.prototype.insertParagraphOnEnter = null; 3187 TracWysiwyg.prototype.insertLineBreak = function() { }; 3079 3188 TracWysiwyg.prototype.insertTableCell = function(row, index) { return null }; 3080 3189 TracWysiwyg.prototype.getFocusNode = function() { return null }; … … 3285 3394 TracWysiwyg.getSelfOrAncestor = function(element, name) { 3286 3395 var target = element; 3287 name = name.toLowerCase(); 3288 if ((target.tagName || "").toLowerCase() != name) { 3289 target = getAncestorByTagName(element, name); 3290 } 3291 return target; 3396 var d = element.ownerDocument; 3397 if (name instanceof RegExp) { 3398 while (target && target != d) { 3399 switch (target.nodeType) { 3400 case 1: // element 3401 if (name.test(target.tagName.toLowerCase())) { 3402 return target; 3403 } 3404 break; 3405 case 11: // fragment 3406 return null; 3407 } 3408 target = target.parentNode; 3409 } 3410 } 3411 else { 3412 name = name.toLowerCase(); 3413 while (target && target != d) { 3414 switch (target.nodeType) { 3415 case 1: // element 3416 if (target.tagName.toLowerCase() == name) { 3417 return target; 3418 } 3419 break; 3420 case 11: // fragment 3421 return null; 3422 } 3423 target = target.parentNode; 3424 } 3425 } 3426 return null; 3292 3427 }; 3293 3428 tracwysiwygplugin/0.11/tests/index.html
r2761 r4135 12 12 html { font-size: 13px; *font-size: small; } 13 13 body { font-family: Arial, Helvetica, sans-serif; font-size: 100%; } 14 textarea { font-size: 11px; }14 textarea { font-size: 11px; width: 100%; border: 1px solid #999; } 15 15 #testunit .current { background-color: #FFFF80; } 16 16 #testunit .success { background-color: #33dd88; } 17 17 #testunit .failure textarea { background-color: #ff3333; border-style: none; } 18 #wysiwyg-html { 19 width: 100%; 20 border: 1px solid #999; 21 font-size: 11px; 22 white-space: -moz-pre-wrap; 23 white-space: -pre-wrap; 24 white-space: -o-pre-wrap; 25 white-space: pre-wrap; 26 word-wrap: break-word; 27 } 18 28 </style> 19 29 </head> 20 30 <body> 21 31 <form method="post"> 22 <textarea id="textarea" class="wikitext" cols="50" rows="5" wrap="off"></textarea> 32 <textarea id="textarea" class="wikitext" cols="50" rows="20" wrap="off"></textarea> 33 <div> 34 <label><input type="checkbox" id="show-wysiwyg-html" value="1" 35 onclick="document.getElementById('wysiwyg-html').style.display=this.checked?'':'none'" 36 />show html</label> 37 <textarea id="wysiwyg-html" cols="50" rows="12" style="display:none;"></textarea> 38 </div> 23 39 </form> 24 40 </body> tracwysiwygplugin/0.11/tests/testcase.js
r3847 r4135 3 3 var instance = new TracWysiwyg(document.getElementById("textarea")); 4 4 var contentDocument = instance.contentDocument; 5 6 var d = document; 7 var wysiwygHtml = d.getElementById("wysiwyg-html"); 8 var showWysiwygHtml = d.getElementById("show-wysiwyg-html"); 9 setTimeout(function() { 10 if (showWysiwygHtml.checked) { 11 var body = contentDocument.body; 12 var browserIE = body.attachEvent ? true : false; 13 var elements = body.getElementsByTagName("br"); 14 var count = 0; 15 var html = body.innerHTML.replace(/<[Bb][Rr] *[^>\/]*/g, function(value) { 16 var element = elements[count++]; 17 var attributes = element.attributes; 18 var length = attributes.length; 19 if (length == 0) 20 return value; 21 var texts = [ value ]; 22 for (var i = 0; i < length; i++) { 23 var attr = attributes[i]; 24 if (!browserIE || !!element[attr.name]) { 25 texts.push(' ', attr.name, '="', attr.value, '"'); 26 } 27 } 28 return texts.join(""); 29 }); 30 if (wysiwygHtml.value != html) { 31 wysiwygHtml.value = html; 32 } 33 } 34 setTimeout(arguments.callee, 500); 35 }, 500); 5 36 6 37 function generate(dom, wikitext, withoutDomToWikitext, withoutWikitextToFragment) { … … 674 705 unit.add("block + br", function() { 675 706 function br() { return element("br"); } 676 function br_moz() { return element("br", { "type": "_moz" }); }677 707 var wikitext = [ 678 "text, br {_moz}",708 "text, br", 679 709 "", 680 710 "text'', br[[BR]]''", … … 684 714 "", 685 715 " * list, br[[BR]]", 686 " * list, br {_moz}",716 " * list, br", 687 717 " * ", 688 718 "", … … 690 720 generateWikitext.call(this, 691 721 fragment( 692 element("p", "text, br {_moz}", br_moz()),693 element("p", "text", element("i", ", br", br()), br _moz()),722 element("p", "text, br", br()), 723 element("p", "text", element("i", ", br", br()), br()), 694 724 element("table", { "class": "wiki" }, 695 725 element("tbody", 696 726 element("tr", 697 element("td", "1,1", br(), br _moz()),698 element("td", br _moz()),699 element("td", "1,3", br _moz())),727 element("td", "1,1", br(), br()), 728 element("td", br()), 729 element("td", "1,3", br())), 700 730 element("tr", 701 element("td", br _moz()),702 element("td", "2,2", br(), br(), br _moz())))),731 element("td", br()), 732 element("td", "2,2", br(), br(), br())))), 703 733 element("ul", 734 element("li", "list, br", br(), br()), 704 735 element("li", "list, br", br()), 705 element("li", "list, br{_moz}", br_moz()),706 736 element("li")), 707 element("p", "text, br", br() )),737 element("p", "text, br", br(), br())), 708 738 wikitext); 709 739 generateFragment.call(this, 710 740 fragment( 711 element("p", "text, br {_moz}"),712 element("p", "text", element("i", ", br", br()), br _moz()),741 element("p", "text, br"), 742 element("p", "text", element("i", ", br", br()), br()), 713 743 element("table", { "class": "wiki" }, 714 744 element("tbody", 715 745 element("tr", 716 element("td", "1,1", br(), br _moz()),717 element("td", br _moz()),746 element("td", "1,1", br(), br()), 747 element("td", br()), 718 748 element("td", "1,3")), 719 749 element("tr", 720 element("td", br _moz()),721 element("td", "2,2", br(), br(), br _moz())))),750 element("td", br()), 751 element("td", "2,2", br(), br(), br())))), 722 752 element("ul", 723 element("li", "list, br", br(), br _moz()),724 element("li", "list, br {_moz}"),725 element("li", br _moz())),726 element("p", "text, br", br(), br _moz())),753 element("li", "list, br", br(), br()), 754 element("li", "list, br"), 755 element("li", br())), 756 element("p", "text, br", br(), br())), 727 757 wikitext); 728 758 }); … … 732 762 function br() { return element("br"); } 733 763 var wikitext = [ 734 "text, br {_moz}",764 "text, br", 735 765 "", 736 766 "text'', br[[BR]]''", … … 740 770 "", 741 771 " * list, br[[BR]]", 742 " * list, br {_moz}",772 " * list, br", 743 773 " * ", 744 774 "", … … 746 776 generate.call(this, 747 777 fragment( 748 element("p", "text, br {_moz}"),778 element("p", "text, br"), 749 779 element("p", "text", element("i", ", br", br())), 750 780 element("table", { "class": "wiki" }, … … 759 789 element("ul", 760 790 element("li", "list, br", br()), 761 element("li", "list, br {_moz}"),791 element("li", "list, br"), 762 792 element("li")), 763 793 element("p", "text, br", br())), … … 1364 1394 } 1365 1395 var body = d.body; 1396 while (body.childNodes.length > 0) { 1397 body.removeChild(body.lastChild); 1398 } 1366 1399 body.appendChild(fragment(d, 1367 1400 _element("p", tracwysiwygplugin/0.11/tracwysiwyg/htdocs/wysiwyg.js
r3856 r4135 347 347 case "quote": return [ self.formatQuoteBlock ]; 348 348 case "hr": return [ self.insertHorizontalRule ]; 349 case "br": return [ self.insert HTML, "<br />"];349 case "br": return [ self.insertLineBreak ]; 350 350 } 351 351 return null; … … 403 403 var position = this.getSelectionPosition(); 404 404 var ancestor = {}; 405 ancestor.start = getSelfOrAncestor(position.start, "a") || getSelfOrAncestor(position.start, "tt");406 ancestor.end = getSelfOrAncestor(position.end, "a") || getSelfOrAncestor(position.end, "tt");405 ancestor.start = getSelfOrAncestor(position.start, /^(?:a|tt)$/); 406 ancestor.end = getSelfOrAncestor(position.end, /^(?:a|tt)$/); 407 407 this.expandSelectionToElement(ancestor); 408 408 … … 488 488 function listenerKeypress(event) { 489 489 event = event || self.contentWindow.event; 490 var modifier = (event.ctrlKey ? 0x40000000 : 0) 491 | (event.shiftKey ? 0x20000000 : 0) | (event.altKey ? 0x10000000 : 0); 490 492 switch (event.charCode || event.keyCode) { 491 493 case 0x20: // SPACE … … 494 496 case 0x0d: // ENTER 495 497 self.detectTracLink(event); 498 switch (modifier) { 499 case 0: 500 if (self.insertParagraphOnEnter) { 501 self.insertParagraphOnEnter(event); 502 } 503 break; 504 case 0x20000000: // Shift 505 if (self.insertLineBreakOnShiftEnter) { 506 self.insertLineBreakOnShiftEnter(event); 507 } 508 break; 509 } 496 510 return; 497 511 } … … 500 514 501 515 function listenerKeyup(event) { 516 var keyCode = event.keyCode; 502 517 if (ime) { 503 switch ( event.keyCode) {518 switch (keyCode) { 504 519 case 0x20: // SPACE 505 520 self.detectTracLink(event); … … 626 641 } 627 642 var getSelfOrAncestor = TracWysiwyg.getSelfOrAncestor; 628 if (getSelfOrAncestor(node, "a") || getSelfOrAncestor(node, "tt") || getSelfOrAncestor(node, "pre")) {643 if (getSelfOrAncestor(node, /^(?:a|tt|pre)$/)) { 629 644 return; 630 645 } … … 710 725 if (event.shiftKey) { 711 726 if (window.opera || !anonymous.addEventListener) { 712 this.insertHTML(html + "<br />");727 this.insertHTML(html + "<br>"); 713 728 if (window.opera) { 714 729 anchor = this.contentDocument.getElementById(id); … … 810 825 var hash = { node: null, cell: null, row: null, table: null }; 811 826 hash.node = this.getFocusNode(); 812 hash.cell = hash.node 813 ? TracWysiwyg.getSelfOrAncestor(hash.node, "td") || TracWysiwyg.getSelfOrAncestor(hash.node, "th") 814 : null; 827 hash.cell = hash.node ? TracWysiwyg.getSelfOrAncestor(hash.node, /^t[dh]$/) : null; 815 828 hash.row = hash.cell ? TracWysiwyg.getSelfOrAncestor(hash.cell, "tr") : null; 816 829 hash.table = hash.row ? TracWysiwyg.getSelfOrAncestor(hash.row, "table") : null; … … 1242 1255 }; 1243 1256 1257 (function() { 1258 var blocks = { 1259 p: true, blockquote: true, div: true, 1260 li: true, ul: true, ol: true, 1261 dl: true, dt: true, dd: true, 1262 h1: true, h2: true, h3: true, h4: true, h5: true, h6: true, 1263 table: true, thead: true, tbody: true, tr: true, td: true, th: true }; 1264 1265 function generator(prop, blocks) { 1266 return function (node) { 1267 if (!node) { 1268 return false; 1269 } 1270 for ( ; ; ) { 1271 if (node[prop]) { 1272 return false; 1273 } 1274 node = node.parentNode; 1275 if (!node) { 1276 return false; 1277 } 1278 if (node.tagName.toLowerCase() in blocks) { 1279 return true; 1280 } 1281 } 1282 return false; 1283 }; 1284 } 1285 1286 TracWysiwyg.prototype.isLastChildInBlockNode = generator("nextSibling", blocks); 1287 TracWysiwyg.prototype.isFirstChildInBlockNode = generator("previousSibling", blocks); 1288 })(); 1289 1244 1290 TracWysiwyg.prototype.wikitextToFragment = function(wikitext, contentDocument) { 1245 1291 var getSelfOrAncestor = TracWysiwyg.getSelfOrAncestor; … … 2381 2427 break; 2382 2428 case "br": 2383 if ( node.getAttribute("type") != "_moz") {2429 if (!self.isBogusLineBreak(node)) { 2384 2430 var value; 2385 2431 if (inCodeBlock) { … … 2647 2693 } 2648 2694 var name = last.tagName.toLowerCase(); 2649 if (name == "br" && last.getAttribute("type") != "_moz") {2695 if (name == "br") { 2650 2696 break; 2651 2697 } … … 2656 2702 } 2657 2703 var br = this.contentDocument.createElement("br"); 2658 br.setAttribute("type", "_moz");2659 2704 element.appendChild(br); 2705 }; 2706 TracWysiwyg.prototype.isBogusLineBreak = TracWysiwyg.prototype.isLastChildInBlockNode; 2707 TracWysiwyg.prototype.insertParagraphOnEnter = function(event) { 2708 var range = this.getSelectionRange(); 2709 var node = range.endContainer; 2710 var header = null; 2711 if (node && node.nodeType == 3 && range.endOffset == node.nodeValue.length) { 2712 var nextSibling = node.nextSibling; 2713 if (!nextSibling || nextSibling.tagName.toLowerCase() == "br") { 2714 while (node) { 2715 if (node.nodeType == 1 && /^h[1-6]$/i.exec(node.tagName)) { 2716 header = node; 2717 break; 2718 } 2719 node = node.parentNode; 2720 } 2721 if (header) { 2722 var parent = header.parentNode; 2723 var childNodes = parent.childNodes; 2724 var length = childNodes.length; 2725 for (var offset = 0; offset < length; offset++) { 2726 if (childNodes[offset] == header) { 2727
