Index: trunk/extensions/UsabilityInitiative/NavigableTOC/NavigableTOC.php |
— | — | @@ -19,7 +19,7 @@ |
20 | 20 | /* Configuration */ |
21 | 21 | |
22 | 22 | // Bump the version number every time you change any of the .css/.js files |
23 | | -$wgNavigableTOCStyleVersion = 2; |
| 23 | +$wgNavigableTOCStyleVersion = 3; |
24 | 24 | |
25 | 25 | /* Setup */ |
26 | 26 | |
Index: trunk/extensions/UsabilityInitiative/NavigableTOC/NavigableTOC.js |
— | — | @@ -18,15 +18,74 @@ |
19 | 19 | var caretPos = 0; |
20 | 20 | // IE Support |
21 | 21 | if($.browser.msie) { |
22 | | - control.focus(); |
23 | | - var sel = document.selection.createRange(); |
24 | | - var sel2 = sel.duplicate(); |
25 | | - sel2.moveToElementText(control); |
26 | | - var caretPos = -1; |
27 | | - while(sel2.inRange(sel)) { |
28 | | - sel2.moveStart('character'); |
29 | | - caretPos++; |
30 | | - } |
| 22 | + // This code was copied from |
| 23 | + // http://www.dedestruct.com/2008/03/22/howto-cross-browser-cursor-position-in-textareas/ |
| 24 | + var selection_range = document.selection.createRange().duplicate(); |
| 25 | + |
| 26 | + // Create three ranges, one containing all the text before the selection, |
| 27 | + // one containing all the text in the selection (this already exists), and one containing all |
| 28 | + // the text after the selection. |
| 29 | + var before_range = document.body.createTextRange(); |
| 30 | + before_range.moveToElementText(control); // Selects all the text |
| 31 | + before_range.setEndPoint("EndToStart", selection_range); // Moves the end where we need it |
| 32 | + |
| 33 | + var after_range = document.body.createTextRange(); |
| 34 | + after_range.moveToElementText(control); // Selects all the text |
| 35 | + after_range.setEndPoint("StartToEnd", selection_range); // Moves the start where we need it |
| 36 | + |
| 37 | + var before_finished = false, selection_finished = false, after_finished = false; |
| 38 | + var before_text, untrimmed_before_text, selection_text, untrimmed_selection_text, after_text, untrimmed_after_text; |
| 39 | + |
| 40 | + // Load the text values we need to compare |
| 41 | + before_text = untrimmed_before_text = before_range.text; |
| 42 | + selection_text = untrimmed_selection_text = selection_range.text; |
| 43 | + after_text = untrimmed_after_text = after_range.text; |
| 44 | + |
| 45 | + |
| 46 | + // Check each range for trimmed newlines by shrinking the range by 1 character and seeing |
| 47 | + // if the text property has changed. If it has not changed then we know that IE has trimmed |
| 48 | + // a \r\n from the end. |
| 49 | + do { |
| 50 | + if (!before_finished) { |
| 51 | + if (before_range.compareEndPoints("StartToEnd", before_range) == 0) { |
| 52 | + before_finished = true; |
| 53 | + } else { |
| 54 | + before_range.moveEnd("character", -1) |
| 55 | + if (before_range.text == before_text) { |
| 56 | + untrimmed_before_text += "\r\n"; |
| 57 | + } else { |
| 58 | + before_finished = true; |
| 59 | + } |
| 60 | + } |
| 61 | + } |
| 62 | + if (!selection_finished) { |
| 63 | + if (selection_range.compareEndPoints("StartToEnd", selection_range) == 0) { |
| 64 | + selection_finished = true; |
| 65 | + } else { |
| 66 | + selection_range.moveEnd("character", -1) |
| 67 | + if (selection_range.text == selection_text) { |
| 68 | + untrimmed_selection_text += "\r\n"; |
| 69 | + } else { |
| 70 | + selection_finished = true; |
| 71 | + } |
| 72 | + } |
| 73 | + } |
| 74 | + if (!after_finished) { |
| 75 | + if (after_range.compareEndPoints("StartToEnd", after_range) == 0) { |
| 76 | + after_finished = true; |
| 77 | + } else { |
| 78 | + after_range.moveEnd("character", -1) |
| 79 | + if (after_range.text == after_text) { |
| 80 | + untrimmed_after_text += "\r\n"; |
| 81 | + } else { |
| 82 | + after_finished = true; |
| 83 | + } |
| 84 | + } |
| 85 | + } |
| 86 | + |
| 87 | + } while ((!before_finished || !selection_finished || !after_finished)); |
| 88 | + |
| 89 | + caretPos = untrimmed_before_text.replace(/\r\n/g, "\n").length; |
31 | 90 | // Firefox support |
32 | 91 | } else if (control.selectionStart || control.selectionStart == '0') { |
33 | 92 | caretPos = control.selectionStart; |
— | — | @@ -145,7 +204,8 @@ |
146 | 205 | }); |
147 | 206 | |
148 | 207 | function styleCurrentSection() { |
149 | | - // TODO: optimize |
| 208 | + // FIXME: Try to dynamically adjust section offsets when user |
| 209 | + // enters/removes stuff |
150 | 210 | // Find the section we're in |
151 | 211 | bytePos = $( '#wpTextbox1' ).bytePos(); |
152 | 212 | i = 0; |