JSWindows (a JavaScript Inheritance Demo)' Borders Class

© 2013, Martin Rinehart

Note that the name is plural: Borders. This is a reminder that there may be four separate border specifications for a single DOM element.

Overview

Borders, and the fact that you can specify none or one or four for each element, are an issue. CSS gets around the problem by specifying width and height inside the borders (the size of the content area). This means that all the worrying is left up to the programmer. Layout requires that you know the whole size of an element. Is that width (no borders)? Or width plus twice the border width (border specified)? Or width plus the width of the left and right borders? The code is not hard, but it's messy. Borders buries the mess. The width of a Wobj is its width (content plus left and right borders). The width of the content area of Wobj is wobj.content_width a convenience for:

wobj.content_width = wobj.width - wobj.borders.get_horizontal_width().

All JSWindows (a JavaScript Inheritance Demo) visible components are Wobj objects. Each Wobj contains (composition) a Borders object. The default border for every element is set by the DEFAULTS.Border.xxx values. Other objects have other defaults. The Rect class, for example, has its own borders values.

The border is key to element content positions and sizes. The position of an element is the position of the left-top (x,y) corner of the border. The code specifies the width and height (order is always x, y—horizontal first) of each element. This size includes the size of the border. Increasing or decreasing the border width changes the size of the element's content area but not the overall position and size of the element.

The Borders object includes width, style, color and radii. When we speak of the "top-left corner" we mean, "the location of the top-left corner if the corner radius were zero."

Creating Borders Objects

Default Borders

If the SKIN specified 1px solid green borders, these would be all the same:

var borders;
borders = new jsw.Borders();
borders = new jsw.Borders( undefined );
borders = new jsw.Borders( 1 );
borders = new jsw.Borders( 1, 'solid' );
borders = new jsw.Borders( 1, 'solid',
        'green' );
borders = new jsw.Borders( [1, 'solid',
        'green'] );

More exactly, these two are the same:

var borders;
borders = new jsw.Borders();
borders = new jsw.Borders(
	jsw.DEFAULTS.Border.width,
	jsw.DEFAULTS.Border.style,
	jsw.DEFAULTS.Border.color.normal,
	jsw.DEFAULTS.Border.radii
);

This is similar to the CSS shorthand declaration:

selector { border: 1px solid green }

The last form is a convenience for creating Wobj and Wobj-based objects. The default Wobj constructor includes a Borders instance:

var rect = new jsw.Rect( ..., borders, ... );

In lieu of supplying a Borders instance, you can supply an array:

var rect =
new jsw.Rect( ..., [5, 'solid', 'gray'], ... );

Note that the width is specified as a number, interpreted as a number of pixels. Since the basic layout contract specifies that the overall size is independent of the border size, this cannot be specified in units other than pixels. Note that this restriction applies to the JSWindows (a JavaScript Inheritance Demo) system, not to applications using JSWindows (a JavaScript Inheritance Demo). JSWindows (a JavaScript Inheritance Demo) apps could use percentages, ems, points or whatever you like.

Non-Default, Uniform Borders

Any of these defaults may be replaced. For a "uniform" border (all four sides the same) this will specify a five-pixel, ridge, in cyan:

var border =
new jsw.Borders( 5, 'ridge', 'cyan' );

The same color may be specified as #0ff, #00ffff, rgb( 0, 255, 255 ) or rgba( 0, 255, 255, 1.0 ).

A five-pixel, translucent gray would be:

var border = new jsw.Borders( 5, 'solid',
'rgba(200, 200, 200, 0.5)' )

(At the time this is written, February, 2013, one major vendor's browsers do not all support translucent colors.)

Non-Uniform Borders

Any of the arguments may replace the primitive with an array of four elements. These are applied to the sides, clockwise starting from the left:

var border = new jsw.Borders( 5,
    'double',
    ['red','white','blue','white'] );

/* Same as CSS:
    selector {
        border-width: 5px;
        border-style: double;
        border-color-left: red;
        border-color-top: white;
        border-color-right: blue;
        border-color-bottom: white
    }
*/

Copying Borders Objects

var another_borders =
new jsw.Borders( existing_borders );

Convenience constructor when you want, for example, to copy a default Borders but do not want changes in one Borders to change other Borders.

Creating Wobjs' Borders

Wobjs do not need to be called with a borders argument. With an undefined borders, the DEFAULTS border will be supplied. To create a non-default border, simply supply a value for the borders argument. If you supply a number, it will be used for the border width. Style and color will be DEFAULTS. If you want full control, supply style, color and radii, too.

This example uses wider borders at top and bottom in a translucent blue-gray.

Warning: most browsers screw up mixed sizes with radiused borders in styles other than solid.

var pos_size = new jsw.Pos_size(
        100,200, 500,350 );

var border = new jsw.Borders(
        [5,10,5,10],
        'solid',
        'rgba(200,200,255,0.5)' );

var element = new jsw.Wobj(
        parent, name,
        type, pos_size, border );

Adding Border Radii

Borders objects also may specify non-zero border radii. The specification is not identical to CSS. (We recommend using corner radii only with borders of uniform thickness. The Borders object makes it easy to find out why.) Like other JSW dimensions, all radii are specified in pixels. Your specifications are numbers.

Border radii are specified by adding a fourth, optional argument. If unspecified, you get square corners. There are three ways to specify corner radii:

Border Radii: Single Number

A border radius, horizontal and vertical the same, all four corners the same, is specified with a single number. Example:

Border Radii: Array of Two Numbers

To specify horizontal and vertical radii separately, but all four corners using the same value, use an array of two numbers. Example:

Border Radii: Corners Not the Same

For four different corner radii you use an array of four elements. The elements specify the corners clockwise from top-left. Each element of the array may be a single number (horizontal and vertical radii the same) or an array of two numbers, horizontal then vertical.

Borders Instance Methods

The get_default() Method

This returns a default Borders object, initialized to the SKIN values. These are the same:

var brdrs;

brdrs = new jsw.Borders(
        jsw.CONSTANTS.Borders.shorthand );

// same as:

brdrs = jsw.CONSTANTS.Borders.get_default();

The get_styles() Method

Returns styles for CSS styling. Not minimized, but close. Will return, for example, borderColor in lieu of borderLeftColor, borderTopColor, etc. Will not compact width, style and color into a one-liner, however.

The get_width_xxx() Methods

These are documented in alphabetical order. Remember that the specification, if you specify separate values, is clockwise from left: left, top, right, bottom.

The toString() Method

This method returns a human-readable report of the styles that will be created for this border, useful in alert() or console.log() messages. An optional separator (between styles) string argument may be supplied. borders.toString( '\n\t' ) is nicely readable for complex borders.


Feedback: MartinRinehart at gmail dot com

# # #