Export (0) Print
Expand All

Our Three Rs

As of December 2011, this topic has been archived. As a result, it is no longer actively maintained. For more information, see Archived Content. For information, recommendations, and guidance regarding the current version of Internet Explorer, see Internet Explorer Developer Center.

Mark Davis, Heidi Housten, Dan Mohr, and Kusuma Vellanki
Microsoft Corporation

April 2, 2001

While Kusuma is off sunning herself, the rest of the team is working hard through the hailstorms and much needed drizzle of the Pacific Northwest. We don't mind. When we get that one month of glorious sun here in the Seattle area, we'll (well, Mark at any rate) be out climbing Mt. Rainier and Kusuma can stay in and write—after all she prefers careening across snow covered mountains. We are just hoping she'll bring us back something yummy to eat so we can start on next month's questions.

By the way, there is a handy dandy little link at the very bottom of our columns called List of Web Team Topics which pops up an impressive list of subjects we have covered over the last few years. Before you get out your keyboard to start writing to the Web Team, check through that list to be sure we haven't covered your question already—you might get your answer sooner than you thought! Now there is service for you!

Well dear readers, we're off to the airport to get Kusuma, and our lunch! Enjoy the three Rs and other tidbits we have for you this month!

Contents

Reduce, Reuse, and Recycle—reusing common code
Getting Cut Short in Internet Explorer 5.5?—printing, text boxes, and page breaks
The Log Less Traveled—rewriting history

Web Team in Short

Reduce, Reuse, and Recycle

Dear Web Team:

Hi, I'm building a Web site that has a table of contents on every page. How do I insert commonly used HTML from a secondary file?

Steve Goldman

The Web Team replies:

The three Rs, reduce, reuse and recycle, are just as applicable for Web development as they are for protecting our environment. If you have HTML or script that implements a user interface element, form validation or other common features, then it makes sense to reuse this information. Recycling common code into a reusable form will speed up your development time and improve maintenance. Using common files will also reduce the amount of data that your users need to download.

There are several ways to reuse HTML and script, depending on the software used by your Web server and client.

Reuse on the server can be implemented by using the ASP (Active Server Programming) #INCLUDE directive. This directive inserts the contents of the specified file at the current location and can be used to merge HTML or script. You cannot use this directive inside a loop, or recursively include files.

<!-- #INCLUDE FILE="common.inc" -->

Script functions can be reused on the client by placing them in a common file and including them by using the HTML SCRIPT element. These included files are great for sharing common script functions and constant definitions between Web pages.

<SCRIPT SRC="common.js">
</SCRIPT>

The HTML LINK element can be used to share a common style sheet, as the following example demonstrates. Storing all your style rules in one file can provide an easy way to change the style of your Web pages in a single step—impress your friends by changing the look of your site in a moments notice!

<LINK REL="stylesheet" HREF="common.css">

Wouldn't it be great to have a #include directive on the client? Well now you can—just use the download default behavior provided with Internet Explorer 5. This behavior downloads text from a URL and returns a string that can then be rendered in the document. The following HTML demonstrates how to use the download behavior to insert a common section of HTML into a Web page.

<HTML>
<HEAD>
<SCRIPT LANGUAGE="JScript">
function include(url)
{ // Download the requested file (onDownloadDone will fire when done)
  oDownload.startDownload( url, onDownloadDone );
}
function onDownloadDone(s)
{ // Content of file is returned as a string
  oDownload.innerHTML = s;
}
</SCRIPT>
</HEAD>
<BODY ONLOAD="include('table.htm')" STYLE="font-family:verdana">
  <DIV ID="oDownload" STYLE="behavior:url(#default#download);border:1px 
solid black;float:left;height:100%"></DIV>
  <DIV><HR>Welcome to our web site !<HR></DIV>
</BODY>
</HTML>

Microsoft Internet Explorer 5 supports DHTML behaviors, and these behaviors can be a great way of reusing script. You can write DHTML behaviors that encapsulate functionality that your Web authors can use on a Web page as easy as applying a CSS style. For more information, please see the DHTML behavior overview on MSDN Online. So, let's get clever and write a simple behavior to hide the previous code from the Web author. Here is the behavior implementation (you'd save this to a file named include.htc):

<PUBLIC:COMPONENT TAGNAME="include">
  <PUBLIC:PROPERTY NAME="file" />
  <PUBLIC:METHOD NAME="onDownloadDone" />
  <PUBLIC:ATTACH EVENT="oncontentready" ONEVENT="init()" />
  <PUBLIC:ATTACH EVENT="onpropertychange" ONEVENT="onPropertyChange()" />
  <SCRIPT LANGUAGE="JScript">
  var file;
  function init()
  {
    element.addBehavior( "#default#download" );
    download();
  }
  function onPropertyChange()
  {
    if ( "file" == window.event.propertyName )
      download();
  }
  function download()
  {
    element.startDownload( file, onDownloadDone );
  }
  function onDownloadDone(s)
  {
    element.innerHTML = s;
  }
  </SCRIPT>
</PUBLIC:COMPONENT>

Here is the updated HTML page. Notice how clean the HTML looks without the script section. The following example demonstrates the use of a DHTML behavior by applying a CSS style to an HTML DIV element and using an expando property that specifies the file to be included.

<HTML>
<HEAD>
<STYLE>
.include {behavior:url(include.htc)}
</STYLE>
</HEAD>
<BODY STYLE="font-family:verdana">
  <DIV CLASS="include" file="table.htm" STYLE="border:1px solid black;
    float:left;height:100%"></DIV>
  <DIV><HR>Welcome to our web site!<HR></DIV>
</BODY>
</HTML>

In this final step, we take the use of behaviors one step further and use an element behavior, which is available in Internet Explorer 5.5. The following example demonstrates the use of a custom element that includes the content of the file that is specified by the file attribute. I guess that this is about as close as you get to a client-side #include directive.

<HTML xmlns:custom>
<HEAD>
<?IMPORT NAMESPACE="custom" IMPLEMENTATION="include.htc"?>
</HEAD>
<BODY STYLE="font-family:verdana">
  <DIV STYLE="border:1px solid black;float:left;height:100%"/>
    <custom:include file="table.htm"/>
  </DIV>
  <DIV><HR>Welcome to our web site !<HR></DIV>
</BODY>
</HTML>

Getting Cut Short in Internet Explorer 5.5?

Dear Web Team,

When I try to print a pretty large TEXTAREA (longer than one page) in IE 5.5 it gets cut off at the bottom of the first page! What gives?

Thanks!
Afi Hoboots

The Web Team Replies:

Wow, that's one big TEXTAREA! What you're running into here is a limitation of the new printing work in IE 5.5. Yes, the same code that brought you such hits as Print Preview and customizable Print Templates is unfortunately also responsible for the truncation of your longer-than-a-page TEXTAREAs. IE 5.5 is currently unable to break TEXTAREAs across multiple pages, but on the up side, there's a slick workaround!

The basic workaround is to set up event handlers for the onbeforeprint and onafterprint events that substitute DIVs for the TEXTAREAs before printing occurs and remove them after printing is done, since DIVs can be broken across multiple pages. It gets a little tricky, though, because you need to substitute <BR> elements for the line breaks and add non-breaking spaces in order to preserve the formatting correctly. This is where we need to reach for the script developer's Swiss Army knife—regular expressions. What would normally have to be implemented in a clunky finite state machine can be done much faster using two simple regular expressions. Turning on the global search flag when substituting in a pair of &nbsp; elements for every pair of spaces actually catches all combinations of spaces in one shot, since HTML always gives you one space for free. Once we've constructed the DIVs, we give them IDs based on the TEXTAREAs they're replacing (so we can find them again after printing and remove them) and insert them into the document using the insertBefore method.

So after all that hype, here's the code:

<HTML>
<HEAD>
   <TITLE>IE 5.5 TEXTAREA Cropping Workaround</TITLE>
</HEAD>

<BODY ONLOAD="fillAreas();" ONBEFOREPRINT="subInDivs();" ONAFTERPRING="putBackTextAreas();">

<SCRIPT LANGUAGE="JScript">
   
function subInDivs() 
{   
   var collTextAreas = document.all.tags("TEXTAREA");
   var oNewDiv;
   var sTemp;
   var i;

   for (i = 0; i < collTextAreas.length; i++) 
   {
      oNewDiv = document.createElement("DIV");
      oNewDiv.style.width = collTextAreas(i).clientWidth;
      oNewDiv.style.height = collTextAreas(i).clientHeight;
      oNewDiv.id = collTextAreas(i).uniqueID + "_div";

      // replace all line breaks with HTML line breaks
      sTemp = collTextAreas(i).value.replace(/\n/gi,"<BR>"); 

      // match 2 spaces with to non-breaking spaces
      sTemp = sTemp.replace(/\s\s/gi,"&nbsp;&nbsp;"); 

      oNewDiv.innerHTML = sTemp;      
      collTextAreas(i).parentNode.insertBefore(oNewDiv, collTextAreas(i));
      collTextAreas(i).style.display = "none";
      oNewDiv = null;
   }
}

function putBackTextAreas()
{
   var collTextAreas = document.all.tags("TEXTAREA");
   var oDivToRemove;
   var i;

   for (i = 0; i < collTextAreas.length; i++) 
   {
      oDivToRemove = document.all(collTextAreas(i).uniqueID + "_div");
      if (oDivToRemove != null)
      {
         oDivToRemove.removeNode(true);
      }
      collTextAreas(i).style.display = "";
   }

}

function fillAreas() 
{
   var sTempLine = "";
   var collTextAreas;
   var i;

   for(i = 0; i < 250; i++)
   {
      //build string
      sTempLine += "XXXXX   XXXXXXXXXXXXXXXXXX   XXX X XXX  XX\n";
   }

   collTextAreas = document.all.tags("TEXTAREA");
   for (i = 0; i < collTextAreas.length; i++)
   {
      collTextAreas(i).value = sTempLine;
   }
}

</SCRIPT>

<H2>IE 5.5 TEXTAREA Cropping Workaround</H2>

<TEXTAREA ID="ta1" ROWS="253" COLS="70"></TEXTAREA>

</BODY>
</HTML>

The Log Less Traveled

Dear Web Team,

Is there a way to access and modify a WebBrowser control's session history? I need to be able to obtain (and/or change) the URL and text description of the session history entries?

Any help you can provide will be appreciated.

George Loo

The Web Team Replies:

Starting with Internet Explorer 5.5, the WebBrowser control exposes this information to its host through a family of interfaces known as the travel log interfaces ("travel log" being the IE lingo for session history). These interfaces not only give a WebBrowser control access to all the URLs and titles in the history, but also provide a nifty enumeration interface to make traversal of the list that much easier. Now why you would want to go replacing user's history entries with alternate entries is beyond us, but for the purposes of this sample, we'll assume you're trying to replace potentially embarrassing URLs with much cooler ones—like replacing all occurrences of www.starlandvocalband.com or www.ghostdad.com with the much more satisfying http://msdn.microsoft.com/ie. To this end, here is some code that goes through the URLs the user has visited so far and performs just these substitutions:

HRESULT hr = S_OK;
IServiceProvider* pISP = NULL;
ITravelLogStg* pTLStg = NULL;
ITravelLogEntry* pTLEntry = NULL;
IEnumTravelLogEntry* pTLEnum = NULL;

if (FAILED(pWB->QueryInterface(IID_IServiceProvider, (void**) &pISP)) 
    || pISP == NULL)
   goto Cleanup;

if (FAILED(pISP->QueryService(SID_STravelLogCursor, IID_ITravelLogStg, (void**) &pTLStg)) 
    || pTLStg == NULL)
   goto Cleanup;

if (SUCCEEDED(pTLStg->EnumEntries(TLEF_RELATIVE_BACK, &pTLEnum)) && pTLEnum)
{
   hr = pTLEnum->Next(1, &pTLEntry, NULL);    

   while (hr != S_FALSE)    
   {
      LPOLESTR szURL;        
      if (SUCCEEDED(pTLEntry->GetURL(&szURL)) && szURL)
      {
         if (wcsstr(szURL, L"www.starlandvocalband.com") || 
             wcsstr(szURL, L"www.ghostdad.com"))
         {
            ITravelLogEntry* pTLNewEntry = NULL;

            hr = pTLStg->CreateEntry(L"http://msdn.microsoft.com/ie",
                                     L"MSDN Online Internet Explorer Developer Center",
                                     pTLEntry,
                                     FALSE,
                                     &pTLNewEntry);
            hr = pTLStg->RemoveEntry(pTLEntry);
         }         
      }
      pTLEntry->Release();
      pTLEntry = NULL;
      hr = pTLEnum->Next(1, &pTLEntry, NULL);    
   }
}

Cleanup:

if (pTLStg)
   pTLStg->Release();

if (pTLEnum)
   pTLEnum->Release();

For the full specs on each of these interfaces, check out http://msdn.microsoft.com/library/default.asp?url=/workshop/browser/travellog/travellog.asp. "Sky rockets in flight…"

Web Team in Short

Saving XML Documents on the Client Side

Q: Dominic asked how to save an XML document on the client side.

A: Saving a document on the client side, without getting the viewer's permission, would be a major security breach. Your users can right click and save the document themselves, or you can make an ActiveX® control to provide that functionality and have your users accept installation of that control.

Custom Context Menus

Q: Fred Elber is trying to make his own context menus and stop the default Internet Explorer menu from appearing.

A: Internet Explorer 5 introduced the onContextMenu event so you can display your own menus without Internet Explorer's default popping up. The Web Team answer to a similar question a couple of years ago explains further.

Binary Behaviors

Q: Janet wants the scoop on binary behaviors.

A: Check out the Cutting Edge column from January's MSDN Magazine.

Script in Your Pocket

Q: Geoff wanted to know if script is available for Web pages on the pocket pc.

A: It sure is! Andrew Clinick shows it off in the August 2000 edition of the Scripting Clinic entitled Is That a Script in Your Pocket?.

 

The Web Team


Mark Davis is a software design engineer on the Internet Explorer SDK team. Mark originates from England and is currently training to climb the major summits in the Northwest.

Heidi Housten is on the MSDN Architectural Samples team. She came to MSDN from the Internet Client team at Microsoft Developer Support. She is convinced that her 14 years of living and working in England were just preparation for the gray and drizzle of Seattle.

Dan Mohr, an engineer with Microsoft Developer Support's Internet Client team, spends his free minutes recording bands in his basement, programming his Commodore 64, and extolling the virtues of late '70s punk rock.

Kusuma Vellanki is one of the few people who likes winters in Washington better than summers. When not working as a developer for the Internet Client team, she can be found skiing down the slopes of Washington.

The Web Team's Greatest Hits

List of Web Team Topics


  
Show:
© 2014 Microsoft