+function X_TextRange_select( v ){\r
+ \r
+};\r
+\r
+// http://www.studio-freesky.net/programming/javascript/3/\r
+// それは、IEのTextRangeオブジェクトで取得した範囲にもしラストに改行コード¥r¥nがあった場合それが含まれないのです。(視覚的な選択範囲には含まれています)\r
+\r
+// https://web.archive.org/web/20090904134938/http://www.dedestruct.com/2008/03/22/howto-cross-browser-cursor-position-in-textareas/\r
+ // https://web.archive.org/web/20090904183807/http://www.dedestruct.com/cursorPosition.html\r
+ function cursorPosition( textarea ){\r
+\r
+ var selection_range = document.selection.createRange().duplicate();\r
+ \r
+\r
+ if (selection_range.parentElement() !== textarea) {\r
+ // TODO 正しくはカーソル位置・選択範囲の復帰\r
+ \r
+ X_EventDispatcher_ignoreActualEvent = 'focus';\r
+ textarea.focus();\r
+ X_EventDispatcher_ignoreActualEvent = '';\r
+ \r
+ // BODY要素のテキスト範囲を作成する\r
+ selection_range = X_elmBody.createTextRange();\r
+ \r
+ // BODY要素のテキスト範囲をeのテキスト範囲に移動する\r
+ // これはe.createTextRange()とほぼ同等\r
+ selection_range.moveToElementText( textarea );\r
+ \r
+ selection_range.collapse( true ); // 末美に移動\r
+ selection_range.select();\r
+ };\r
+\r
+ //if (selection_range.parentElement() == textarea) {// Check that the selection is actually in our textarea\r
+ // Create three ranges, one containing all the text before the selection,\r
+ // one containing all the text in the selection (this already exists), and one containing all\r
+ // the text after the selection.\r
+ var before_range = X_elmBody.createTextRange();\r
+ before_range.moveToElementText(textarea);\r
+ // Selects all the text\r
+ before_range.setEndPoint('EndToStart', selection_range);\r
+ // Moves the end where we need it\r
+ \r
+ var after_range = X_elmBody.createTextRange();\r
+ after_range.moveToElementText(textarea);\r
+ // Selects all the text\r
+ after_range.setEndPoint('StartToEnd', selection_range);\r
+ // Moves the start where we need it\r
+ \r
+ var before_finished = false, selection_finished = false, after_finished = false;\r
+ var before_text, untrimmed_before_text, selection_text, untrimmed_selection_text, after_text, untrimmed_after_text;\r
+ \r
+ // Load the text values we need to compare\r
+ before_text = untrimmed_before_text = before_range.text;\r
+ selection_text = untrimmed_selection_text = selection_range.text;\r
+ after_text = untrimmed_after_text = after_range.text;\r
+ \r
+ // Check each range for trimmed newlines by shrinking the range by 1 character and seeing\r
+ // if the text property has changed. If it has not changed then we know that IE has trimmed\r
+ // a \r\n from the end.\r
+ do {\r
+ if (!before_finished) {\r
+ if (before_range.compareEndPoints('StartToEnd', before_range) == 0) {\r
+ before_finished = true;\r
+ } else {\r
+ before_range.moveEnd('character', -1);\r
+ if (before_range.text == before_text) {\r
+ untrimmed_before_text += '\r\n';\r
+ } else {\r
+ before_finished = true;\r
+ }\r
+ }\r
+ }\r
+ if (!selection_finished) {\r
+ if (selection_range.compareEndPoints('StartToEnd', selection_range) == 0) {\r
+ selection_finished = true;\r
+ } else {\r
+ selection_range.moveEnd('character', -1);\r
+ if (selection_range.text == selection_text) {\r
+ untrimmed_selection_text += '\r\n';\r
+ } else {\r
+ selection_finished = true;\r
+ }\r
+ }\r
+ }\r
+ if (!after_finished) {\r
+ if (after_range.compareEndPoints('StartToEnd', after_range) == 0) {\r
+ after_finished = true;\r
+ } else {\r
+ after_range.moveEnd('character', -1);\r
+ if (after_range.text == after_text) {\r
+ untrimmed_after_text += '\r\n';\r
+ } else {\r
+ after_finished = true;\r
+ }\r
+ }\r
+ }\r
+ \r
+ } while ((!before_finished || !selection_finished || !after_finished));\r
+ \r
+ // Untrimmed success test to make sure our results match what is actually in the textarea\r
+ // This can be removed once you're confident it's working correctly\r
+ /*\r
+ var untrimmed_text = untrimmed_before_text + untrimmed_selection_text + untrimmed_after_text;\r
+ var untrimmed_successful = false;\r
+ if (textarea.value == untrimmed_text) {\r
+ untrimmed_successful = true;\r
+ } */\r
+ // ** END Untrimmed success test\r
+ \r
+ var startPoint = untrimmed_before_text.split( '\r' ).join( '' ).length;\r
+ // alert(startPoint);\r
+ return {\r
+ 'from' : this.v1 = startPoint,\r
+ 'to' : this.v2 = startPoint + untrimmed_selection_text.split( '\r' ).join( '' ).length\r
+ };\r
+ //}\r
+ }\r
+ \r