Yankee Web Code- Run.mrs(hoo)

by Kenneth Tibbetts

Content and Control Run.mrs(hoo) sets style properties and attributes for one or more html elements. You can highlight a single character, or change the background color of a paragraph. You can alter the source file or the width and height dimensions of an image. You can call Run.mrs(hoo) for any number of elements, and set any number of properties in one swoosh.

Come and meet the mrs

When you create new elements with Run.dr(wot), you have the option of passing arguments to set styles and attributes that are used by Run.mrs(hoo) during the act of creation.

The return value of Run.mrs(hoo) is a string. Passing Run.mrs(hoo) with an element as the only argument returns a string representing any inline styles set on the element.

Run.mrs(hoo) uses helper functions. I'll comment the helpers as they appear.

Arguments: Unlimited, 1 required

Returns: string or true

Arguments:

Run.mrs(hoo)

index required description type
(hoo) [0] yes one or more html elements string, array or object
[1] no style or attribute name-value pairs string
[2],[3],[4]... no style or attribute name-value pairs strings

Calling Run.mrs(hoo)

Run.mrs(hoo) is very flexible, and adapts nicely to different conditions. This is code that takes full advantage of the 'looseness' (or 'flexibility') of javascript, compared to stricter languages. Sending a javascript function a different type of argument, or a different number of arguments can be like having two different functions. This is similar to c++ overloading- but not quite.

Calling Run.mrs(hoo) with a single element as the only argument returns a string of the inline style properties set for the element (hoo). Note that this return value is in CSS syntax:

"font-size: xx-large; text-decoration: underline; border-top-width: thin ".

If you want to apply the style properties thus returned to some other element, you need to first convert the CSS syntax to a scriptable form. "font-size:large" becomes "fontSize:large", for example. 

I include a sample converter, deHyphen(), in "Odds & Ends" at the end of this article. You could call:

 Run.mrs(x, deHyphen(Run.mrs(y)) ); 

to give x the same inline styles as y. y is a single html element, but x can be any collection of elements. 

I most often use Run.mrs(hoo) to set or change the style properties of elements, and discard or ignore the return value.

The first argument (hoo) can be an object reference or a string id for an html element, but it can also be an array containing any number of elements to which you apply the new styles.

The second argument, and any number of additional arguments, are strings made up of style or html name-value pairs.

Run.mrs(hoo) does three things, calling helpers as needed:

  1. Splits the first argument (hoo) into an array of html elements.
  2. Concatenates all other arguments into a single string, and regroup() the string into an array of name-value pairs.
  3. Applies each property/attribute value to each element.

In the simplest form of the function, an element is passed as the sole argument:

var x= Run.mrs('head1');

This call returns the inline styles set for mr('head1') in a CSS style string:

x= "cursor: pointer; font-size: x-large; text-decoration: underline"

If mr(hoo) is not an existing element, or no inline styles have been set, the empty string is returned.


Note that the return value ignores any classNames or other attributes, and does not compute inherited styles. It only returns explicit inline style assignments associated with the element, either in the html tag or previously set by script.


You can set one property or attribute of a single element:

Run.mrs('head1','color:red')

Or:

Run.mrs(document.images[3],'src=picture.gif')

It is slightly easier on the machinery to skip Run.mrs() and directly call doMrs() for single statements like these.

doMrs('head1','color:red');
doMrs(document.images[3],'src=picture.gif');

However you must use Run.mrs() when you have more than one property value:

Run.mrs('head1','fontSize:large; textDecoration:underline; color:#ff0000'

And you must use mrs when you are changing more than one element:

var elAll=document.getElementsByTagName('p');
Run.mrs(elAll, 'fontSize:large; fontWeight:600;margin:10px'

And here:

var head=document.getElementsByTagName('h1');
for(var i =0; i< head.length; i++){
Run.mrs('head'+i, 'fontStyle:italic', 'title=Chapter '+i);
}

Run.mrs(hoo) source

function Run.mrs(hoo){

if(arguments.length==1){

var x= (mr(hoo))? mr(hoo).style.cssText: '';

return x.toLowerCase();

}

var elements=collect(hoo);



var properties=arguments[1];

if( arguments.length >2){

for(var i=2; i< arguments.length; i++)

properties+= '; '+arguments[i];

}

var allprops= properties.regroup(true);



for( var i= 0; i< elements.length; i++ ){

for( var k= 0; k< allprops.length; k++ ){

doMrs(elements[i], allprops[k]);

}

}

return true;

}

If there is only one argument, an element id or object reference, Run.mrs(hoo) returns a string consisting of the inline style properties set for the element. Usually there are arguments, and Run.mrs(hoo) begins by determining what element or group of elements it will be working on. Run.collect() is an important and useful function, called by other functions as well as by Run.mrs(), so I'll run through it next.

Run.collect(hoo)

The argument representing the element or elements (hoo) is passed to Run.collect(hoo). Collect figures out what element(s) we want. The return value is an array of html elements- it can be a single element, or any collection of elements in the document.

function Run.collect(hoo){

var collection=new Array;

var elements=new Array;

/* We start with a pair of empty Array objects */

if(typeof(hoo)== 'string') {

collection= hoo.regroup(true);

}

/* hoo can be a string of one or more ids. If more than one, they should be delimited by semi-colons: Run.mrs('head1; head2; head3', 'color:red').

regroup() is a custom method attached to the global String prototype. It splits a delimited string into an array. The 'true' argument forces an array of one element to be returned when there is no delimeter. 
The code for regroup() is shown in Odds & Ends.

Note that Run.mrs(hoo) also uses regroup() to split a string of delimited name-values into an array of name-values. */

else if(typeof(hoo)== 'object' &&hoo.length) {

collection= hoo;

}

/* If hoo is an object with a length property, hoo is ready to use. 

if hoo is document.getElementsByTagName('p'), collect returns an array of all of the <p> elements in the document.  */

else collection[0]= hoo;

/* If hoo is not a string or an array, it is probably an object. Most likely a document object reference to an html element. (document.body or document.links[3])We make it the first (and only) element in the array. */

for(var i=0; i< collection.length; i++){

if(mr(collection[i]))

elements[elements.length]=mr(collection[i]);

}

/* Test each element in the collection array with mr(hoo). If the test verifies an existing element, it becomes a member of the array that will be returned. */

return elements;

/* The value returned to Run.mrs() is the array of elements. If no elements were found, the array will be empty and have length [0], and will simply fall through mrs and return to the caller. */

}

Back to mrs

We now have an array of html elements. Next we build an array of properties and attributes and their values.

var properties=arguments[1];

if( arguments.length >2){

for(var i=2; i< arguments.length; i++)

properties+= '; '+arguments[i];

}

var allprops= properties.regroup(true);

/* All the arguments after the first are concatenated into a single string called properties. Then regroup() is called to split the string into an array of style:value or attribute=value pairs. */

for( var i= 0; i< elements.length; i++ ){

for( var k= 0; k< allprops.length; k++ ){

doMrs(elements[i],allprops[k]);

}

}

/* We have two arrays, one containing html elements, and one containing the style or attribute names and values. Loop de loop- for each element, each name-value pair is applied. The mechanics of this is in our next helper, doMrs(element, name-value). */

doMrs()

doMrs does the work. It can be called directly, when one element has one value set. Usually it is called by Run.mrs(hoo), as one of a series of calls from a loop. There are two arguments: an html element reference, and a name-value string. The name-value string gets most of doMrs' attention.

function doMrs(hoo, props){

if( !mr(hoo)) return;

var who= mr(hoo);

/* Tests if the html element actually exists, needed when doMrs() is called directly. */

var nameVals= props.split(/\s*[\:\=]\s*/ );

var namex=nameVals[0];

var valuex=nameVals[1];

/* Splits props into a [name, value] array; assign to namex and valuex. */

if( /\=/.test(props)) who.setAttribute(namex,valuex);

/* If props contained an equals sign, treat it as an html attribute and set the value. */

else{

/* Else we are dealing with a style property */

if(namex.length< 6) namex= cssAlias(namex);

/* If the namex string is 3 letters long or less, it must be a shortcut string. This is not necessary, but it is convenient. A switch statement in cssAlias converts an abbreviated property name to a "legal" name. 'bgc' will return 'backgroundColor', for example, and 'td' yields 'textDecoration'. cssAlias() will be shown in a bit, but first, let's finish up with doMrs. * /

if(valuex=='pointer' && Yankee.iz( 'IE') && ( Yankee.iz('DF')== false) ) valuex='hand';

if(/float/.test(namex){

namex=(Yankee.iz('IE'))? 'styleFloat' : 'cssFloat';

}

if(namex== 'visibility'){

valuex= (valuex.charAt(0).toLowerCase()=='v')? 'visible' : 'hidden';

}

/* The first if manages a cursor value. The statement determines the browser (using Yankee.iz(), a browser sniffer function) and branches its output accordingly. Before IE6, setting a value of 'pointer' on a cursor in IE caused an error.

The second if handles IE's incompatability with the W3 cssFloat property name, by assigning IE's version when necessary.

The third if is a shortcut for visibility values. A holdover from when Netscape used show and hide for values, I got in the habit of abbreviating "vis:v". Definitely optional.*/

if(who.style)who.style[namex]= valuex;

/* Double check that who has a style object, and apply the style*/

}

/* Control returns to mrs for the next iteration of the loop, with a new element or a new name-value pair. The last iteration returns true to whoever called Run.mrs(hoo) */

}

cssAlias()

Nothing in cssAlias is required- you can always write the full property name instead of an abbreviation. This list has grown and shrunk over the years, the ones here are the ones that I use most often. Choose your own list or leave it out entirely.

This function should speak for itself.

function cssAlias(wotName){

var wot= wotName.toLowerCase();

switch (wot){

case 'bg': return 'background';

case 'bgc': return 'backgroundColor';

case 'dis': return 'display';

case 'fs': return 'fontSize';

case 'fw': return 'fontWeight';

case 'pos': return 'position';

case 'ta' : return 'textAlign';

case 'td' : return 'textDecoration';

case 'vis': return 'visibility';

case 'z': return 'zIndex';


default: return wotName;

}

}


That wraps up Run.mrs(hoo), a most valuable member of the dom scripting library. The next section provides a sample function for converting CSS syntax to a script assignment, and shows the working parts of regroup() and the source for Yankee.iz(), both of which will get a closer look, by and by .

Odds & Ends

deHyphen()

function deHyphen(what){

var str='';

var a= what.toLowerCase();

if(/\-/.test(a)==false)return a;


var tempA=a.regroup(true);

for(var i in tempA){

na= tempA[i].split(':');

n=na[0];

var Rx=/\-\w/g;

na[0]= n.replace(Rx,function(w){

return w.substring(1).toUpperCase();

});

str+=na[0]+':' +na[1]+';';

}

str=str.slice(0,-1);

return str;

}

regroup()

String.prototype.regroup= function(boo){

var delim=/\s*[,|;]\s*/;

return (delim.test(this))? this.split(delim):

(boo)? this.split() : false;

}


Yankee.iz()

function Yankee.iz(what){

if(!what) return navigator.appName+'; '+ navigator.userAgent;

var agnt= navigator.userAgent.toLowerCase();

var wot=what.toLowerCase();


switch (wot){

case 'df': return !!(document.createDocumentFragment);

case 'dom': return !!(document.createTextNode);

case 'id': return !!(document.getElementById);

case 'ie': return !!(agnt.indexOf('msie')!=-1);

case 'moz': return !!(agnt.indexOf('gecko')!=-1);

case 'op': return !!(agnt.indexOf('opera')!=-1);

case 'agt': return agnt;


default: return !!(agnt.indexOf(wot)!=-1);

}

}



Next up: Run.doRight(): retrieving groups of elements

What Else?

    Code from the Yankee Webshop
  1. Practical Code
  2. A DOM Function Library
  3. mr(hoo)
  4. Run.dr(wot)
  5. Run.mrs(hoo)
  6. Run.doRight()
  7. Run.sayWhat()
  8. Run.zap()

Internet Resources:

e-mail: editor@yankeeweb.net

WebShop Privacy Policy