CD-432 Part VI ✦ Appendixes TextRange Object Properties boundingHeight boundingLeft boundingTop boundingWidth NN2 NN3 NN4 NN6 IE3/J1 IE3/J2 IE4 IE5 IE5.5 Compatibility ✓✓ ✓ Example Listing 19-9 provides a simple playground to explore the four bounding properties (and two offset properties) of a TextRange object. As you select text in the big paragraph, the values of all six properties are displayed in the table. Values are also updated if you resize the window via an onResize event handler. Notice, for example, if you simply click in the paragraph without dragging a selec- tion, the boundingWidth property shows up as zero. This action is the equivalent of a TextRange acting as an insertion point. Listing 19-9: Exploring the Bounding TextRange Properties <HTML> <HEAD> <TITLE>TextRange Object Dimension Properties</TITLE> <STYLE TYPE=”text/css”> TD {text-align:center} .propName {font-family: Courier, monospace} </STYLE> <SCRIPT LANGUAGE=”JavaScript”> function setAndShowRangeData() { var range = document.selection.createRange() B1.innerText = range.boundingHeight B2.innerText = range.boundingWidth B3.innerText = range.boundingTop B4.innerText = range.boundingLeft B5.innerText = range.offsetTop TextRange.boundingHeight CD-433 Appendix F ✦ Examples from Parts III and IV B6.innerText = range.offsetLeft } </SCRIPT> </HEAD> <BODY onResize=”setAndShowRangeData()”> <H1>TextRange Object Dimension Properties</H1> <HR> <P>Select text in the paragraph below and observe the “bounding” property values for the TextRange object created for that selection.</P> <TABLE ID=”results” BORDER=1 CELLSPACING=2 CELLPADDING=2> <TR><TH>Property</TH><TH>Pixel Value</TH></TR> <TR> <TD CLASS=”propName”>boundingHeight</TD> <TD CLASS=”count” ID=”B1”> </TD> </TR> <TR> <TD CLASS=”propName”>boundingWidth</TD> <TD CLASS=”count” ID=”B2”> </TD> </TR> <TR> <TD CLASS=”propName”>boundingTop</TD> <TD CLASS=”count” ID=”B3”> </TD> </TR> <TR> <TD CLASS=”propName”>boundingLeft</TD> <TD CLASS=”count” ID=”B4”> </TD> </TR> <TR> <TD CLASS=”propName”>offsetTop</TD> <TD CLASS=”count” ID=”B5”> </TD> </TR> <TR> <TD CLASS=”propName”>offsetLeft</TD> <TD CLASS=”count” ID=”B6”> </TD> </TR> </TABLE> <HR> <P onMouseUp=”setAndShowRangeData()”> Lorem ipsum dolor sit amet, consectetaur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim adminim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit involuptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deseruntmollit anim id est laborum Et harumd und lookum like Greek to me, dereud facilis est er expedit. </P> </BODY> </HTML> TextRange.boundingHeight CD-434 Part VI ✦ Appendixes htmlText NN2 NN3 NN4 NN6 IE3/J1 IE3/J2 IE4 IE5 IE5.5 Compatibility ✓✓ ✓ Example Use The Evaluator (Chapter 13) to investigate values returned by the htmlText property. Use the top text box to enter the following statements and see the values in the Results box. Begin by creating a TextRange object for the entire body and store the range in local variable a: a = document.body.createTextRange() Next, use the findText() method to set the start and end points of the text range around the word “all,” which is an EM element inside the myP paragraph: a.findText(“all”) The method returns true (see the findText() method) if the text is found and the text range adjusts to surround it. To prove that the text of the text range is what you think it is, examine the text property of the range: a.text Because the text range encompasses all of the text of the element, the htmlText property contains the tags for the element as well: a.htmlText If you want to experiment by finding other chunks of text and looking at both the text and htmlText properties, first restore the text range to encompass the entire body with the following statement: a.expand(“textEdit”) You can read about the expand() method later in this chapter. In other tests, use findText() to set the range to “for all” and just “for al.” Then, see how the htmlText property exposes the EM element’s tags. TextRange.htmlText CD-435 Appendix F ✦ Examples from Parts III and IV text NN2 NN3 NN4 NN6 IE3/J1 IE3/J2 IE4 IE5 IE5.5 Compatibility ✓✓ ✓ Example See Listing 19-11 later in this chapter for the findText() method to see the text property used to perform the replace action of a search-and-replace function. Methods collapse([startBoolean]) NN2 NN3 NN4 NN6 IE3/J1 IE3/J2 IE4 IE5 IE5.5 Compatibility ✓✓ ✓ Example See Listings 19-11 and 15-14 to see the collapse() method at work. compareEndPoints(“type”, rangeRef) NN2 NN3 NN4 NN6 IE3/J1 IE3/J2 IE4 IE5 IE5.5 Compatibility ✓✓ ✓ Example The page rendered by Listing 19-10 lets you experiment with text range compar- isons. The bottom paragraph contains a SPAN element that has a TextRange object assigned to its text after the page loads (in the init() function). That fixed range becomes a solid reference point for you to use while you select text in the para- graph. After you make a selection, all four versions of the compareEndPoints() method run to compare the start and end points of the fixed range against your TextRange.compareEndPoints() CD-436 Part VI ✦ Appendixes selection. One column of the results table shows the raw value returned by the compareEndPoints() method, while the third column puts the results into plain language. To see how this page works, begin by selecting the first word of the fixed text range (double-click the word). You can see that the starting positions of both ranges are the same, because the returned value is 0. Because all of the invocations of the compareEndPoints() method are on the fixed text range, all comparisons are from the point of view of that range. Thus, the first row of the table for the StartToEnd parameter indicates that the start point of the fixed range comes before the end point of the selection, yielding a return value of -1. Other selections to make include: ✦ Text that starts before the fixed range and ends inside the range ✦ Text that starts inside the fixed range and ends beyond the range ✦ Text that starts and ends precisely at the fixed range boundaries ✦ Text that starts and ends before the fixed range ✦ Text that starts after the fixed range Study the returned values and the plain language results and see how they align with the selection you make. Listing 19-10: Lab for compareEndPoints() Method <HTML> <HEAD> <TITLE>TextRange.compareEndPoints() Method</TITLE> <STYLE TYPE=”text/css”> TD {text-align:center} .propName {font-family:Courier, monospace} #fixedRangeElem {color:red; font-weight:bold} </STYLE> <SCRIPT LANGUAGE=”JavaScript”> var fixedRange function setAndShowRangeData() { var selectedRange = document.selection.createRange() var result1 = fixedRange.compareEndPoints(“StartToEnd”, selectedRange) var result2 = fixedRange.compareEndPoints(“StartToStart”, selectedRange) var result3 = fixedRange.compareEndPoints(“EndToStart”, selectedRange) var result4 = fixedRange.compareEndPoints(“EndToEnd”, selectedRange) B1.innerText = result1 compare1.innerText = getDescription(result1) TextRange.compareEndPoints() CD-437 Appendix F ✦ Examples from Parts III and IV B2.innerText = result2 compare2.innerText = getDescription(result2) B3.innerText = result3 compare3.innerText = getDescription(result3) B4.innerText = result4 compare4.innerText = getDescription(result4) } function getDescription(comparisonValue) { switch (comparisonValue) { case -1 : return “comes before” break case 0 : return “is the same as” break case 1 : return “comes after” break default : return “vs.” } } function init() { fixedRange = document.body.createTextRange() fixedRange.moveToElementText(fixedRangeElem) } </SCRIPT> </HEAD> <BODY onLoad=”init()”> <H1>TextRange.compareEndPoints() Method</H1> <HR> <P>Select text in the paragraph in various places relative to the fixed text range (shown in red). See the relations between the fixed and selected ranges with respect to their start and end points.</P> <TABLE ID=”results” BORDER=1 CELLSPACING=2 CELLPADDING=2> <TR><TH>Property</TH><TH>Returned Value</TH><TH>Fixed Range vs. Selection</TR> <TR> <TD CLASS=”propName”>StartToEnd</TD> <TD CLASS=”count” ID=”B1”> </TD> <TD CLASS=”count” ID=”C1”>Start of Fixed <SPAN ID=”compare1”>vs.</SPAN> End of Selection</TD> </TR> <TR> <TD CLASS=”propName”>StartToStart</TD> <TD CLASS=”count” ID=”B2”> </TD> Continued TextRange.compareEndPoints() CD-438 Part VI ✦ Appendixes Listing 19-10 (continued) <TD CLASS=”count” ID=”C2”>Start of Fixed <SPAN ID=”compare2”>vs.</SPAN> Start of Selection</TD> </TR> <TR> <TD CLASS=”propName”>EndToStart</TD> <TD CLASS=”count” ID=”B3”> </TD> <TD CLASS=”count” ID=”C3”>End of Fixed <SPAN ID=”compare3”>vs.</SPAN> Start of Selection</TD> </TR> <TR> <TD CLASS=”propName”>EndToEnd</TD> <TD CLASS=”count” ID=”B4”> </TD> <TD CLASS=”count” ID=”C4”>End of Fixed <SPAN ID=”compare4”>vs.</SPAN> End of Selection</TD> </TR> </TABLE> <HR> <P onMouseUp=”setAndShowRangeData()”> Lorem ipsum dolor sit, <SPAN ID=”fixedRangeElem”>consectetaur adipisicing elit</SPAN>, sed do eiusmod tempor incididunt ut labore et dolore aliqua. Ut enim adminim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</P> </BODY> </HTML> duplicate() NN2 NN3 NN4 NN6 IE3/J1 IE3/J2 IE4 IE5 IE5.5 Compatibility ✓✓ ✓ Example Use The Evaluator (Chapter 13) to see how the duplicate() method works. Begin by creating a new TextRange object that contains the text of the myP paragraph element. a = document.body.createTextRange() a.moveToElementText(myP) Next, clone the original range and preserve the copy in variable b: TextRange.duplicate() CD-439 Appendix F ✦ Examples from Parts III and IV b = a.duplicate() The method returns no value, so don’t be alarmed by the “undefined” that appears in the Results box. Move the original range so that it is an insertion point at the end of the body by first expanding it to encompass the entire body, and then collapse it to the end: a.expand(“textedit”) a.collapse(false) Now, insert the copy at the very end of the body: a.text = b.text If you scroll to the bottom of the page, you’ll see a copy of the text. execCommand(“commandName”[, UIFlag[, value]]) NN2 NN3 NN4 NN6 IE3/J1 IE3/J2 IE4 IE5 IE5.5 Compatibility ✓✓ ✓ Example Use The Evaluator (Chapter 13) to see how to copy a text range’s text into the client computer’s Clipboard. Begin by setting the text range to the myP element: a = document.body.createTextRange() a.moveToElementText(myP) Now use execCommand() to copy the range into the Clipboard: a.execCommand(“Copy”) To prove that the text is in the Clipboard, click the bottom text field and choose Paste from the Edit menu (or type Ctrl+V). expand(“unit”) NN2 NN3 NN4 NN6 IE3/J1 IE3/J2 IE4 IE5 IE5.5 Compatibility ✓✓ ✓ TextRange.expand() CD-440 Part VI ✦ Appendixes Example You can find examples of the expand() method in Listing 15-14. findText(“searchString”[, searchScope, flags]) NN2 NN3 NN4 NN6 IE3/J1 IE3/J2 IE4 IE5 IE5.5 Compatibility ✓✓ ✓ Example Listing 19-11 implements two varieties of text search and replace operation, while showing you how to include extra parameters for case-sensitive and whole word searches. Both approaches begin by creating a TextRange for the entire body, but they immediately shift the starting point to the beginning of the DIV element that contains the text to search. One search and replace function prompts the user to accept or decline replacement for each instance of a found string. The select() and scrollIntoView() methods are invoked to help the user see what is about to be replaced. Notice that even when the user declines to accept the replacement, the text range is collapsed to the end of the found range so that the next search can begin after the previously found text. Without the collapse() method, the search can get caught in an infinite loop as it keeps finding the same text over and over (with no replacement made). Because no counting is required, this search and replace operation is implemented inside a while repeat loop. The other search and replace function goes ahead and replaces every match and then displays the number of replacements made. After the loop exits (because there are no more matches), the loop counter is used to display the number of replacements made. Listing 19-11: Two Search and Replace Approaches (with Undo) <HTML> <HEAD> <TITLE>TextRange.findText() Method</TITLE> <SCRIPT LANGUAGE=”JavaScript”> TextRange.findText() CD-441 Appendix F ✦ Examples from Parts III and IV // global range var for use with Undo var rng // return findText() third parameter arguments function getArgs(form) { var isCaseSensitive = (form.caseSensitive.checked) ? 4 : 0 var isWholeWord = (form.wholeWord.checked) ? 2 : 0 return isCaseSensitive ^ isWholeWord } // prompted search and replace function sAndR(form) { var srchString = form.searchString.value var replString = form.replaceString.value if (srchString) { var args = getArgs(form) rng = document.body.createTextRange() rng.moveToElementText(rights) clearUndoBuffer() while (rng.findText(srchString, 10000, args)) { rng.select() rng.scrollIntoView() if (confirm(“Replace?”)) { rng.text = replString pushUndoNew(rng, srchString, replString) } rng.collapse(false) } } } // unprompted search and replace with counter function sAndRCount(form) { var srchString = form.searchString.value var replString = form.replaceString.value var i if (srchString) { var args = getArgs(form) rng = document.body.createTextRange() rng.moveToElementText(rights) for (i = 0; rng.findText(srchString, 10000, args); i++) { rng.text = replString pushUndoNew(rng, srchString, replString) rng.collapse(false) } if (i > 1) { clearUndoBuffer() } } Continued TextRange.findText() . Undo) <HTML> <HEAD> <TITLE>TextRange.findText() Method</TITLE> <SCRIPT LANGUAGE= JavaScript > TextRange.findText() CD-441 Appendix F ✦ Examples from Parts III and IV // global range var for use with Undo var rng //. {text-align:center} .propName {font-family: Courier, monospace} </STYLE> <SCRIPT LANGUAGE= JavaScript > function setAndShowRangeData() { var range = document.selection.createRange() B1.innerText. range.boundingLeft B5.innerText = range.offsetTop TextRange.boundingHeight CD-433 Appendix F ✦ Examples from Parts III and IV B6.innerText = range.offsetLeft } </SCRIPT> </HEAD> <BODY onResize=”setAndShowRangeData()”> <H1>TextRange