Tuesday, April 10, 2007
Blog Entry #72
The Script Tips #49-51 Script can actually be accessed by following the "Here's the Code" link in Script Tip #51 (but not via the corresponding links in Script Tips #49 and #50), and is reproduced in the div below:
Overview of the Script Tips #49-51 Script
The "See it in Action" links in Script Tips #50 and #51 lead to a script demo page (the corresponding link in Script Tip #49 points to the Script Tips #45-48 Script demo page). The Script Tips #49-51 Script demo page is in the form of a large two-row, four-cell table. The northwest cell holds a "1. Choose One:" heading and a series of six push buttons; when clicked, each button calls a function in the script's script element.
(1) The "2 Vertical" button calls the framesa( ) function, which contains a single assignment statement. Using the global variables at the beginning of the script element - top, nf, f, etc. - the right side of the statement pieces together and stringifies the code for a two-column frames layout:
The frameset document string is formatted/shaped with several "\r" carriage returns and then displayed in the Fillit textarea box in the table's northeast cell.
(2) The "3 Vertical" button calls the frames3v( ) function, which similarly assembles and loads into the Fillit box the code for a three-column frames layout:
(3) The "2 Horizontal" button calls the framesb( ) function, which assembles and loads into Fillit the code for a two-row frames layout:
(4) The "3 Horizontal" button calls the frames3h( ) function, which assembles and loads into Fillit the code for a three-row frames layout:
(5) The "3 Mixed" button calls the framemixa( ) function, which assembles and loads into Fillit the code for a column-row-row three-frame layout:
(6) The "4 Mixed" button calls the framemixb( ) function, which assembles and loads into Fillit the code for a four-frame layout:
Moving on to the table's second row, the southwest cell holds a "2. Copy it in:" heading and a series of three push buttons. Both the "Copy/Edit" and "Start Over" buttons use the script element's Copy( ) function to copy and paste Fillit's contents into the Pastebox textarea box in the table's southeast cell. The "Clear All" button, as you might guess, functions as a reset button.
Finally, at the bottom of the southeast cell is a "View It!" button that, via the script element's view( ) function, displays Pastebox's code in a new browser window.
The Copy( ) and view( ) functions both include some don't-leave-it-blank-type data validation, popping up an alert( ) message if Fillit or Pastebox is empty, respectively.
Frameset/frame element attributes
Joe doesn't discuss the attributes of the frameset and frame elements to any extent, so perhaps we should do that.
(1) The cols and rows attributes of the frameset element are fairly self-explanatory, but what about those asterisks, huh?
You can probably figure out that the * in the tag above is equivalent to 50%. More precisely, the * value is a relative length representing the remaining available space, as explained in the "Lengths" section of the HTML 4.01 Specification; cols="30%,*" and cols="30%,70%" are thus also equivalent.
(2) The bordercolor attribute, appearing in the global variable bc, adds color to the borders between frames; I say "adds color to" because, at least on my iMac, the bordercolor="blue" border is not solidly blue but contains blue and black regions:
The bordercolor attribute was first implemented by Netscape in Navigator 3.0, and support by MSIE followed shortly thereafter; however, bordercolor is not 'standardized': you won't find it in the HTML 4.01 Specification's Index of Attributes.
Buried in the HTML Goodies site (and shamefully no longer appearing in the Frames Tutorial sector) is a "So You Want Colored Frames, Huh?" legacy tutorial that discusses the bordercolor attribute.
(1) A frame's src attribute, much like an img src attribute, specifies a file that will load into the frame. (The frame and img elements are both 'placeholder' elements having an "EMPTY" content model.)
(2) A name attribute allows a frame to be targeted by a link in another frame - see the "Naming Cells and Using Targets" section of HTML Goodies' "So, You Want Some Frames, Huh?" tutorial for more information and a demo.
(3) The scrolling attribute has three possible values:
(a) scrolling="auto" installs vertical and horizontal scrollbars if a frame needs them (i.e., if the src file's display overflows the frame's visible area), and doesn't install scrollbars if a frame doesn't need them;
(b) scrolling="no" ensures that a frame won't have scrollbars, even if they are needed; and
(c) scrolling="yes" ensures that a frame that needs scrollbars will have them, and, depending on the browser, may (MSIE) or may not (Netscape) provide disabled (greyed-out) scrollbars for a frame that doesn't need them, or at least that's what I see on my computer.
(4) The marginwidth and marginheight attributes respectively add horizontal and vertical margin areas between a frame's boundaries and src content area. HTML Goodies' "HTML 4.01: Frames" tutorial alleges,
The[se] commands allow you to set margin height and width in pixels or percentages; however, the W3C classifies marginwidth/marginheight as a %Pixels; attribute type, for which percentages are not valid (and not a %Length; attribute type, for which percentages are acceptable). In practice, I find that MSIE acts on marginwidth/marginheight percentage values, but Netscape ignores them.
(5) The noresize attribute is set to either yes or no in the frameset functions but is actually a Boolean attribute. Putting noresize (or perhaps noresize="noresize") in a frame element's start-tag fixes the frame's width and height; if you leave it out, then the frame's interframe borders can be shifted by normal mouse-cursor dragging and dropping.
I myself would have left the scrolling, marginwidth, marginheight, and noresize attributes out of the Script Tips #49-51 Script. I don't like unresizable windows, and I don't like it when document content is pushed to a window's edges, which is what happens when marginwidth and marginheight are set to 0, as is done in the script via the global variables MW and MH (curiously, the W3C asserts that the marginwidth/marginheight value "must be greater than zero"); regarding the scrolling attribute, I see that auto is the default value - I'll take it.
Fortunately, all of the above attributes can be modified, or even deleted, right there in the Fillit/Pastebox boxes; we can similarly change the document title, the nesting of frameset elements, and also the noframes element, bringing us to...
The noframes element
Each frameset function concludes, via the global variable nf, with a noframes element, which
specifies content that should be displayed only by user agents that do not support frames or are configured not to display frames,quoting the W3C. The noframes element appears, optionally, in the content model of the frameset element
<!ELEMENT FRAMESET - - ((FRAMESET|FRAME)+ & NOFRAMES?) -- window subdivision-->
<!--As for a regular expression, ? is a quantifier that means "occurs 0 or 1 time(s)."-->
so it would seem that the noframes element should be a child, and not a sibling, of the frameset element and that nf should be placed before the last f (frameset element end-tag) in each frameset function.
And what kind of content are we talking about? The noframes element's own content-model description is somewhat confusing:
<![ %HTML.Frameset; [
<!ENTITY % noframes.content "(BODY) -(NOFRAMES)">
<!ENTITY % noframes.content "(%flow;)*">
<!ELEMENT NOFRAMES - - %noframes.content; >
Can or cannot the noframes element contain a body element? (The HTML.Frameset entity's replacement text is "IGNORE".) We can sort out the noframes element's content with a frames-disabled browser; in this regard, MSIE straightforwardly allows me to disable frames as follows:
(1) At the bottom of the Edit menu, access the Preferences pane.
(2) On the Web Browser menu, select the Web Content option.
(3) In the Page Content section, uncheck the Show frames checkbox and then click OK.
Having done this, I can confirm that
(a) it's OK if nf follows the last f in each frameset function - nf's "You need a frames capable browser to view this page" text string is rendered without incident - and
(b) the noframes element can contain
(i) a body element and
(ii) the various block and inline elements that can be descendants of the body element,
at least when using MSIE.
(I ran into trouble when I tried to configure Netscape (7.02) to not show frames. To make a long story short, I somehow botched an attempt to import a user_pref("browser.frames.enabled",false) command into my Mozilla prefs.js file; subsequently, I was unable to launch Netscape and an "Error launching browser window:no XBL binding for browser" alert( ) message would pop up - I ultimately had to uninstall and reinstall Netscape. Needless to say, I really need to upgrade my computer.)
message is popping up in my "Framed" source file, so perhaps we should finish off the remaining script issues in the next entry.