/********************************************************************************************
|
| SCRIPT REACTION
| browser-detector.js
|
| Created by : Kevin Biskaborn
| Copyright (c) 2005-2015 ScriptReaction
| https://www.scriptreaction.ca
|
|-- LATEST REVISION -------------------------------------------------------------------------
|
| K. Biskaborn
|
|-- CLASSES REQUIRED ------------------------------------------------------------------------
|
| GlobalDirector
|
********************************************************************************************/
var BrowserDetector = {
CONST: {
// Browser Type Refs
BROWSER_TYPE_REF_GECKO: "gecko",
BROWSER_TYPE_REF_IE: "ie",
// CSS File Info
FILE_PATH_PREFIX_CSS: "/assets/css/",
FILE_NAME_PREFIX_VERSION_SPECIFIC_CSS: "browser-specific-"
},
settings: {
// Browser Information
browser_isIE: 0, // flag for Internet Explorer
browser_isMobile: 0, // flag for Mobile
browser_typeRef: "", // the browser type ref string
browser_version: -1, // the browser version number
// Version Specific Handling
versionSpecificCSS_enabled: 0
},
preload: function (){
// detect the client browser
BrowserDetector.detectClientBrowser();
// check if browser specific CSS is enabled
if( BrowserDetector.settings.versionSpecificCSS_enabled )
// populate the version specific CSS
this.populate.css();
},
//**************************************************************************************************************
// begin BrowserDetector.verify
verify: {
isIE: function (){
return BrowserDetector.settings.browser_isIE;
},
isMobile: function (){
return BrowserDetector.settings.browser_isMobile;
}
},
// end BrowserDetector.verify
//**************************************************************************************************************
detectClientBrowser: function (){
if( window.XMLHttpRequest ){
if( window.ActiveXObject ){
// IE 7
BrowserDetector.settings.browser_typeRef = BrowserDetector.CONST.BROWSER_TYPE_REF_IE;
BrowserDetector.settings.browser_version = 7;
}
else {
// Opera, Safari, Firefox
BrowserDetector.settings.browser_typeRef = BrowserDetector.CONST.BROWSER_TYPE_REF_GECKO;
}
}
else {
// IE6 and below
BrowserDetector.settings.browser_typeRef = BrowserDetector.CONST.BROWSER_TYPE_REF_IE;
BrowserDetector.settings.browser_version = 6;
}
// set the Internet Explorer flag
BrowserDetector.settings.browser_isIE = (
BrowserDetector.settings.browser_typeRef == BrowserDetector.CONST.BROWSER_TYPE_REF_IE
);
// set the Mobile flag
BrowserDetector.settings.browser_isMobile = BrowserDetector.detectMobile(
navigator.userAgent||navigator.vendor||window.opera
);
},
detectMobile: function ( a ){
return /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4));
},
//**************************************************************************************************************
// begin BrowserDetector.populate
populate: {
css: function (){
// check if version specific CSS is enabled
// AND that the browser is Internet Explorer
if( BrowserDetector.settings.versionSpecificCSS_enabled
&& BrowserDetector.verify.isIE() ){
// INTERNET EXPLORER
// get the browser type ref
var browserTypeRef = BrowserDetector.CONST.BROWSER_TYPE_REF_IE;
// get the version number
var versionNumber = BrowserDetector.settings.browser_version;
// check for all IE browsers ABOVE IE 6.0
if( versionNumber > 6 )
// attach the IE 7.0+ version specific CSS
BrowserDetector.populate.css_versionSpecific( browserTypeRef, 7 );
else
// IE 6.0 and below
BrowserDetector.populate.css_versionSpecific( browserTypeRef, 6 );
}
},
css_versionSpecific: function ( browserTypeRef, versionNumber ){
// attach the requested version specific CSS file
GlobalDirector.attachAsset.cssLink(
BrowserDetector.CONST.FILE_PATH_PREFIX_CSS
+ BrowserDetector.CONST.FILE_NAME_PREFIX_VERSION_SPECIFIC_CSS
+ browserTypeRef + versionNumber + ".css"
);
}
}
// end BrowserDetector.populate
//**************************************************************************************************************
}
/******** GLOBAL LAUNCH ********/
BrowserDetector.preload();
/********************************************************************************************
|
| SCRIPT REACTION
| contact-form-manager.js
|
| Created by : Kevin Biskaborn
| Copyright (c) 2005-2015 ScriptReaction
| https://www.scriptreaction.ca
|
|-- LATEST REVISION -------------------------------------------------------------------------
|
| K. Biskaborn
|
|-- CLASSES REQUIRED ------------------------------------------------------------------------
|
| BrowserDetector
| ElementAccessor
| ElementClassUtility
| LivePage
| StringUtility
|
********************************************************************************************/
var ContactFormManager = {
CONST: {
ARRAY_OF_FIELD_OBJECTS: [
{ ref: "contact-name", label: "Name" },
{ ref: "contact-email", label: "E-mail" },
{ ref: "contact-phone", label: "Phone" },
{ ref: "contact-website", label: "Web Site" },
{ ref: "contact-message", label: "What can we help you with?", isTextArea: 1 }
],
CLASS_NAME_FIELD_ERROR: "field-has-error",
ELEMENT_ID_PREFIX_FIELD_WRAPPER: "field-wrapper-",
ELEMENT_ID_PREFIX_LABEL: "label-",
ELEMENT_ID_SUBMIT_BTN: "contact-form-btn",
FORM_ID: "contact-data-form"
},
settings: {
isValid_email: 0,
isValid_message: 0,
isValid_name: 0,
isValid_phone: 0,
isValidating: 0
},
launch: function (){
// create loop containers
var fieldObject;
var ref, label, isTextArea;
var inputElement, wrapElement;
var labelId, labelElement;
// cycle through all field objects
for( var i = 0; i < ContactFormManager.CONST.ARRAY_OF_FIELD_OBJECTS.length; ++i ){
// get the next field object
fieldObject = ContactFormManager.CONST.ARRAY_OF_FIELD_OBJECTS[ i ];
// extract field properties
isTextArea = ( typeof( fieldObject.isTextArea ) == "undefined" ) ? 0 : 1;
label = fieldObject.label;
ref = fieldObject.ref;
// get the field wrapper and input elements
inputElement = ElementAccessor.get( ref );
wrapElement = $( "#" + ContactFormManager.CONST.ELEMENT_ID_PREFIX_FIELD_WRAPPER + ref );
// specify the ID to use for the label
labelId = ContactFormManager.CONST.ELEMENT_ID_PREFIX_LABEL + ref;
// add the place holder label to each field
wrapElement.append( "
" + label + "
" );
// get the newly created label element
labelElement = ContactFormManager.get.labelElementByRef( ref );
// -------------------------------------------------------------
// check for TEXT AREAS
if( isTextArea ){
// if the value of the text area matches the field label,
// then the value of the text area can be safely cleared
if( inputElement.value.toUpperCase() == label.toUpperCase() )
inputElement.value = "";
}
else
// assume TEXT LINE
// clear the original place holder
inputElement.placeholder = "";
// -------------------------------------------------------------
// add action handlers to each INPUT ELEMENT
// ON BLUR
inputElement.onblur = function (){
ContactFormManager.actions.fieldOnBlur( this.id );
}
// ON CLICK
inputElement.onclick = function (){
ContactFormManager.actions.fieldOnClick( this.id );
}
// ON FOCUS
inputElement.onfocus = function (){
ContactFormManager.actions.fieldOnFocus( this.id );
}
// ON INPUT
inputElement.oninput = function (){
ContactFormManager.actions.fieldOnInput( this.id );
}
// ON KEY UP
inputElement.onkeyup = function (){
ContactFormManager.actions.fieldOnInput( this.id );
}
// -------------------------------------------------------------
// add action handlers to each LABEL
// ON CLICK
labelElement.onclick = function (){
ContactFormManager.actions.labelOnClick( this.id );
}
// -------------------------------------------------------------
// check if the LIVE VALUE of the field is already different from the label
// IMPORTANT: the live value CANNOT be empty
// ie: following a form submission and page re-load
// get the live value
var liveValue = ContactFormManager.get.inputElementLiveValueByRef( ref ).toUpperCase();
// perform the check
if( !( liveValue == "" ) && !( liveValue == label.toUpperCase() ) )
// hide the label
ContactFormManager.actions.hideLabel( ref );
}
// get the form
},
get: {
inputElementByRef: function ( fieldRef ){
return ElementAccessor.get( fieldRef );
},
inputElementLabelByRef: function ( fieldRef ){
var label = "";
// create loop containers
var fieldObject;
// cycle through all field objects
// until all have been iterated or until a label is found
for( var i = 0; i < ContactFormManager.CONST.ARRAY_OF_FIELD_OBJECTS.length && label == ""; ++i ){
// get the next field object
fieldObject = ContactFormManager.CONST.ARRAY_OF_FIELD_OBJECTS[ i ];
// check for the requested field
if( fieldObject.ref == fieldRef )
// set output value
label = fieldObject.label;
}
return label;
},
inputElementLiveValueByRef: function ( fieldRef ){
return ContactFormManager.get.inputElementByRef( fieldRef ).value;
},
labelElementByRef: function ( fieldRef ){
return ContactFormManager.get.wrapElementByRef( fieldRef ).getElementsByTagName( "div" )[ 0 ];
},
liveValue_email: function (){ return ContactFormManager.get.inputElementLiveValueByRef( "contact-email" ); },
liveValue_message: function (){ return ContactFormManager.get.inputElementLiveValueByRef( "contact-message" ); },
liveValue_name: function (){ return ContactFormManager.get.inputElementLiveValueByRef( "contact-name" ); },
liveValue_phone: function (){ return ContactFormManager.get.inputElementLiveValueByRef( "contact-phone" ); },
liveValue_website: function (){ return ContactFormManager.get.inputElementLiveValueByRef( "contact-website" ); },
wrapElement_email: function (){ return ContactFormManager.get.wrapElementByRef( "contact-email" ); },
wrapElement_message: function (){ return ContactFormManager.get.wrapElementByRef( "contact-message" ); },
wrapElement_name: function (){ return ContactFormManager.get.wrapElementByRef( "contact-name" ); },
wrapElement_phone: function (){ return ContactFormManager.get.wrapElementByRef( "contact-phone" ); },
wrapElementByRef: function ( fieldRef ){
return ElementAccessor.get( ContactFormManager.get.wrapElementId( fieldRef ) );
},
wrapElementId: function ( fieldRef ){
return ContactFormManager.CONST.ELEMENT_ID_PREFIX_FIELD_WRAPPER + fieldRef;
}
},
set: {
inputElementLiveValueByRef: function ( fieldRef, str ){
return ContactFormManager.get.inputElementByRef( fieldRef ).value = str;
},
liveValue_email: function ( str ){ return ContactFormManager.set.inputElementLiveValueByRef( "contact-email", str ); },
liveValue_message: function ( str ){ return ContactFormManager.set.inputElementLiveValueByRef( "contact-message", str ); },
liveValue_name: function ( str ){ return ContactFormManager.set.inputElementLiveValueByRef( "contact-name", str ); },
liveValue_phone: function ( str ){ return ContactFormManager.set.inputElementLiveValueByRef( "contact-phone", str ); },
liveValue_website: function ( str ){ return ContactFormManager.set.inputElementLiveValueByRef( "contact-website", str ); }
},
actions: {
fieldOnBlur: function ( fieldRef ){
// when the field is blurred, determine if the label should be reshown
// get the LIVE value of the field
var liveValue = ContactFormManager.get.inputElementLiveValueByRef( fieldRef ).toUpperCase();
// check if the live value is EMPTY or EQUAL to the initial label value
if( liveValue == "" || liveValue == ContactFormManager.get.inputElementLabelByRef( fieldRef ).toUpperCase() ){
// live value is empty or MATCHS the initial label value
// clear the live value
ContactFormManager.set.inputElementLiveValueByRef( fieldRef, '' );
// show the label
ContactFormManager.actions.showLabel( fieldRef );
}
},
fieldOnClick: function ( fieldRef ){
// re-direct click to onFocus handler
ContactFormManager.actions.fieldOnFocus( fieldRef );
},
fieldOnFocus: function ( fieldRef ){
// BROWSER-SPECIFIC
// On the HOME PAGE on MOBILE DEVICES, pause all jQuery animations
// to release addition memory:
if( LivePage.verify.isHome() && BrowserDetector.verify.isMobile() ){
// pause the splash projects
$( "#splash-slider .project-square-holder" ).slickPause();
}
},
fieldOnInput: function ( fieldRef ){
// when input is given to the field, determine if the label should be hidden
// get the LIVE value of the field
var liveValue = ContactFormManager.get.inputElementLiveValueByRef( fieldRef ).toUpperCase();
// check if the live value is EMPTY or EQUAL to the initial label value
if( liveValue == "" || liveValue == ContactFormManager.get.inputElementLabelByRef( fieldRef ).toUpperCase() )
// no user input, show the label
ContactFormManager.actions.showLabel( fieldRef );
else {
// user input exists, hide the label
ContactFormManager.actions.hideLabel( fieldRef );
// remove the field error class when input is given
ContactFormManager.process.removeErrorClassFromField( fieldRef );
}
},
hideLabel: function ( fieldRef ){
// update label visibility
ContactFormManager.actions.updateLabelVisibility( fieldRef, 0 );
},
labelOnClick: function ( labelId ){
// extract the field ref from the incoming ID
var fieldRef = StringUtility.remove.prefix( labelId, ContactFormManager.CONST.ELEMENT_ID_PREFIX_LABEL );
// focus the input field
ContactFormManager.get.inputElementByRef( fieldRef ).focus();
},
showLabel: function ( fieldRef ){
// update label visibility
ContactFormManager.actions.updateLabelVisibility( fieldRef, 1 );
},
updateLabelVisibility: function ( fieldRef, isVisible ){
// update the hidden style on the label
ElementClassUtility.process.addOrRemoveClassUsingFlag(
ContactFormManager.get.labelElementByRef( fieldRef ),
"is-hidden",
!isVisible
);
}
},
process: {
removeAllErrorClasses: function (){
// create loop containers
var fieldObject;
// cycle through all field objects
for( var i = 0; i < ContactFormManager.CONST.ARRAY_OF_FIELD_OBJECTS.length; ++i ){
// get the next field object
fieldObject = ContactFormManager.CONST.ARRAY_OF_FIELD_OBJECTS[ i ];
// remove the error class from the field
ContactFormManager.process.removeErrorClassFromField( fieldObject.ref );
}
},
removeErrorClassFromField: function ( fieldRef ){
// get the field wrapper
var wrapElement = ContactFormManager.get.wrapElementByRef( fieldRef );
// remove the error class name from the element
ElementClassUtility.removeClass.fromElement( wrapElement, ContactFormManager.CONST.CLASS_NAME_FIELD_ERROR );
}
},
processSubmit: function (){
// verify that the form is not already validating
if( !ContactFormManager.settings.isValidating ){
// check if the form is VALID
if( ContactFormManager.validate() ){
// run re-captcha
grecaptcha.execute();
}
else {
// form is invalid
// create a visible delay before calling post validation
window.setTimeout( ContactFormManager.updatePostValidationErrors, 500 );
window.setTimeout( ContactFormManager.endValidation, 1200 );
}
}
},
executeSubmit: function (){
// submit the form
document[ ContactFormManager.CONST.FORM_ID ].submit();
},
validate: function (){
// raise the is validating flag
ContactFormManager.settings.isValidating = 1;
// add the PROCESSING state to the form btn
ElementClassUtility.addClass.toElement_byId( ContactFormManager.CONST.ELEMENT_ID_SUBMIT_BTN, "is-processing" );
// remove any previous error classes
ContactFormManager.process.removeAllErrorClasses();
// get formatted live values
var liveValue_email = StringUtility.trim.whitespace.bothEnds( ContactFormManager.get.liveValue_email() );
var liveValue_message = StringUtility.trim.whitespace.bothEnds( ContactFormManager.get.liveValue_message() );
var liveValue_name = StringUtility.trim.whitespace.bothEnds( ContactFormManager.get.liveValue_name() );
var liveValue_phone = StringUtility.trim.whitespace.bothEnds( ContactFormManager.get.liveValue_phone() );
var liveValue_website = StringUtility.trim.whitespace.bothEnds( ContactFormManager.get.liveValue_website() );
// validate each field
ContactFormManager.settings.isValid_email = ( !( liveValue_email == "" ) && StringUtility.verify.isValidEmail( liveValue_email ) );
ContactFormManager.settings.isValid_message = ( liveValue_message.length >= 8 );
ContactFormManager.settings.isValid_name = ( liveValue_name.length >= 2 );
ContactFormManager.settings.isValid_phone = ( liveValue_phone.length >= 10 );
// re-apply the formatted live values
ContactFormManager.get.liveValue_email( liveValue_email );
ContactFormManager.get.liveValue_message( liveValue_message );
ContactFormManager.get.liveValue_name( liveValue_name );
ContactFormManager.get.liveValue_phone( liveValue_phone );
ContactFormManager.get.liveValue_website( liveValue_website );
// return a boolean for if the entire form is valid
return (
ContactFormManager.settings.isValid_email
&& ContactFormManager.settings.isValid_message
&& ContactFormManager.settings.isValid_name
&& ContactFormManager.settings.isValid_phone
);
},
updatePostValidationErrors: function (){
// update error classes
// EMAIL
ElementClassUtility.process.addOrRemoveClassUsingFlag(
ContactFormManager.get.wrapElement_email(),
ContactFormManager.CONST.CLASS_NAME_FIELD_ERROR,
!ContactFormManager.settings.isValid_email
);
// MESSAGE
ElementClassUtility.process.addOrRemoveClassUsingFlag(
ContactFormManager.get.wrapElement_message(),
ContactFormManager.CONST.CLASS_NAME_FIELD_ERROR,
!ContactFormManager.settings.isValid_message
);
// NAME
ElementClassUtility.process.addOrRemoveClassUsingFlag(
ContactFormManager.get.wrapElement_name(),
ContactFormManager.CONST.CLASS_NAME_FIELD_ERROR,
!ContactFormManager.settings.isValid_name
);
// PHONE
ElementClassUtility.process.addOrRemoveClassUsingFlag(
ContactFormManager.get.wrapElement_phone(),
ContactFormManager.CONST.CLASS_NAME_FIELD_ERROR,
!ContactFormManager.settings.isValid_phone
);
},
endValidation: function (){
// lower the is validating flag
ContactFormManager.settings.isValidating = 0;
// remove the PROCESSING state
ElementClassUtility.removeClass.fromElement_byId( ContactFormManager.CONST.ELEMENT_ID_SUBMIT_BTN, "is-processing" );
}
}
/********************************************************************************************
|
| ElementAccessor
| SCRIPT REACTION LIBRARY
|
| Created by : Kevin Biskaborn
| Copyright (c) 2005-2015 ScriptReaction Ltd. All Rights Reserved.
| https://www.scriptreaction.ca
|
|-- LATEST REVISION -------------------------------------------------------------------------
|
| K. Biskaborn
|
|-- CLASSES REQUIRED ------------------------------------------------------------------------
|
| ElementClassUtility
|
|-- HISTORY ---------------------------------------------------------------------------------
|
| NOV.07.2012 : Nested tags group created.
| MAY.01.2011 : Class created.
|
********************************************************************************************/
var ElementAccessor = {
CONST: {
// AA Standard Constant Collection (v1)
ELEMENT_COUNT_ONE: 1,
ELEMENT_COUNT_ZERO: 0,
FLAG_VALUE_TRUE: 1,
FLAG_VALUE_FALSE: 0,
INDEX_FIRST_ELEMENT: 0,
INDEX_SECOND_ELEMENT: 1,
INVALID_ID: -1,
INVALID_INDEX: -1,
INVALID_OBJECT: null
},
//**************************************************************************************************************
// begin ElementAccessor.verify
verify: {
// verify if an element with the requested id exists
elementExistsById: function ( elementId ){
return ( !( elementId == "" ) && !( ElementAccessor.get( elementId ) == null ) );
}
},
// end ElementAccessor.verify
//**************************************************************************************************************
// gets the element on the page with the requested id
get: function ( elementId ){
return document.getElementById( elementId );
},
//**************************************************************************************************************
// begin ElementAccessor.getArrayOfElements
getArrayOfElements: {
byTagClass: function ( elementTagName, classNameString ){
// create the output container
var arrayOfElements = [];
// get all elements with the requested tag name
var arrayOfTagElements = ElementAccessor.getArrayOfElements.byTagName( elementTagName );
// create loop containers
var element;
// cycle through all of the tag elements
for( var i in arrayOfTagElements ){
// get the next element
element = arrayOfTagElements[ i ];
// test if the element is using the requested class
if( ElementClassUtility.verify.classExistsOnElement( element, classNameString ) )
// add the element to the output array
arrayOfElements.push( element );
}
return arrayOfElements;
},
// gets an array of all elements on the page with the requested tag name
byTagName: function ( tagName ){
return document.getElementsByTagName( tagName );
},
// gets ALL elements in a series
// running from the specified starting number to the ending number
inSeries: function ( elementIdPrefix, startNum, endNum ){
// create the output container
var arrayOfElements = [];
// cycle through the requested series
for( var i = startNum; i <= endNum; ++i )
arrayOfElements.push( ElementAccessor.get( elementIdPrefix + i ) );
return arrayOfElements;
},
// gets ALL elements in a series
// running from element ZERO to element TOTAL - 1
inSeries_fromElementZero: function ( elementIdPrefix, elementTotal ){
// verify that the number of elements is valid
return ( elementTotal > ElementAccessor.CONST.ELEMENT_COUNT_ZERO )
// return the series of elements
? ElementAccessor.getArrayOfElements.inSeries(
elementIdPrefix,
ElementAccessor.CONST.INDEX_FIRST_ELEMENT,
elementTotal - ElementAccessor.CONST.ELEMENT_COUNT_ONE
)
// return an empty array
: [];
}
},
// end ElementAccessor.getArrayOfElements
//**************************************************************************************************************
//**************************************************************************************************************
// begin ElementAccessor.getNestedTag
getNestedTag: {
// get the tag with the requested index inside the specified element
byIndex: function ( element, tagName, tagIndex ){
return ( element == null )
? null : element.getElementsByTagName( tagName )[ tagIndex ];
},
byIndex_anchor: function ( element, tagIndex ){
return ElementAccessor.getNestedTag.byIndex( element, "a", tagIndex );
},
byIndex_div: function ( element, tagIndex ){
return ElementAccessor.getNestedTag.byIndex( element, "div", tagIndex );
},
byIndex_table: function ( element, tagIndex ){
return ElementAccessor.getNestedTag.byIndex( element, "table", tagIndex );
},
byPosition: {
first: {
// gets the FIRST link ANCHOR tag inside the requested element
tag_anchor: function ( element ){
return ElementAccessor.getNestedTag.byIndex_anchor(
element, ElementAccessor.CONST.INDEX_FIRST_ELEMENT
);
},
tag_div: function ( element ){
return ElementAccessor.getNestedTag.byIndex_div(
element, ElementAccessor.CONST.INDEX_FIRST_ELEMENT
);
},
tag_table: function ( element ){
return ElementAccessor.getNestedTag.byIndex_table(
element, ElementAccessor.CONST.INDEX_FIRST_ELEMENT
);
}
}
}
}
// end ElementAccessor.getNestedTag
//**************************************************************************************************************
}
/********************************************************************************************
|
| SCRIPT REACTION
| email-embedder.js
|
| Created by : Kevin Biskaborn
| Copyright (c) 2005-2015 ScriptReaction
| https://www.scriptreaction.ca
|
|-- LATEST REVISION -------------------------------------------------------------------------
|
| K. Biskaborn
|
|-- CLASSES REQUIRED ------------------------------------------------------------------------
|
| ElementAccessor
| ElementPropUtility
| StringUtility
|
********************************************************************************************/
var EmailEmbedder = {
CONST: {
ELEMENT_ID_PREFIX_CONTAINER: "email-embed-",
ENCRYPTION_LENGTH: 3
},
register: function ( id ){
// get the container element
var element = ElementAccessor.get( EmailEmbedder.CONST.ELEMENT_ID_PREFIX_CONTAINER + id );
// get the raw email address (encrypted)
var rawEmail = ElementPropUtility.get.innerContent.by_element( element );
// remove HTML tags and reverse the string
rawEmail = StringUtility.process.reverseString( StringUtility.strip.htmlTags( rawEmail ) );
// split the email on the AT symbol
var arrayOfPieces = rawEmail.split( "@" );
// get the email pieces from the array
var userString = arrayOfPieces[ 0 ];
var domainString = arrayOfPieces[ 1 ];
// re-build the real email
var realEmail = StringUtility.trim.nchars.right( userString, EmailEmbedder.CONST.ENCRYPTION_LENGTH )
+ "@" + StringUtility.trim.nchars.left( domainString, EmailEmbedder.CONST.ENCRYPTION_LENGTH );
// replace the contents of the container
ElementPropUtility.set.innerContent.by_element(
element,
"" + realEmail + ""
);
// update the CSS text direction on the container
element.style.direction = "ltr";
}
}
/********************************************************************************************
|
| SCRIPT REACTION
| global-director.js
|
| Created by : Kevin Biskaborn
| Copyright (c) 2005-2015 ScriptReaction
| https://www.scriptreaction.ca
|
|-- LATEST REVISION -------------------------------------------------------------------------
|
| K. Biskaborn
|
|-- CLASSES REQUIRED ------------------------------------------------------------------------
|
| BrowserDetector
|
********************************************************************************************/
var GlobalDirector = {
settings: {
clearImageAltParamsOnLaunch: 1 // Flag for if the "alt" parameter of image tags
// should be cleared / emptied upon the launch of this class.
// This disables the "title" pop-up when an image is hovered over.
},
preload: function (){
GlobalDirector.addEvent( window, "load", GlobalDirector.postload );
},
postload: function (){
GlobalDirector.process.injectAnimatedAnchorScrolling();
GlobalDirector.process.formatPageImages();
},
//**************************************************************************************************************
// begin GlobalDirector.verify
verify: {
exists: function ( object ){
return !( typeof( object ) == "undefined" );
}
},
// end GlobalDirector.verify
//**************************************************************************************************************
addEvent: function ( object, eventType, functionName ){
if( object.addEventListener ){
object.addEventListener( eventType, functionName, false );
return true;
}
else if( object.attachEvent )
return object.attachEvent( "on" + eventType, functionName );
else
return false;
},
//**************************************************************************************************************
// begin GlobalDirector.attachAsset
attachAsset: {
cssLink: function ( filePath ){
output = "";
output += "";
GlobalDirector.attachAsset.toDoc( output );
},
jsLink: function ( filePath ){
output = "";
output += "";
GlobalDirector.attachAsset.toDoc( output );
},
toDoc: function ( content ){
document.writeln( content );
}
},
// end GlobalDirector.attachAsset
//**************************************************************************************************************
//**************************************************************************************************************
// begin GlobalDirector.process
process: {
formatPageImages: function (){
// verify that the detected brower is Internet Explorer
if( GlobalDirector.verify.exists( BrowserDetector )
&& BrowserDetector.verify.isIE() ){
// get the array of all page images
var arrayOfPageImages = document.images;
// create loop containers
var imgElement;
// -----------------------------------------------------------------
// cycle through all images on the page
for( var i = 0; i < arrayOfPageImages.length; i++ ){
// get the next image element
imgElement = arrayOfPageImages[ i ];
// disable the galleryimg property
imgElement.galleryimg = "no";
// check if alt params should be cleared
if( GlobalDirector.settings.clearImageAltParamsOnLaunch )
// clear the alt param of the image
imgElement.alt = "";
}
}
},
injectAnimatedAnchorScrolling: function (){
// this function requires jQuery
$(function() {
$('a[href*=#]:not([href=#])').click(function() {
// verify the anchor is on the same page
if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'') && location.hostname == this.hostname) {
var target = $(this.hash);
target = target.length ? target : $('[name=' + this.hash.slice(1) +']');
if (target.length) {
$('html,body').animate({
scrollTop: target.offset().top
}, 500);
return false;
}
}
});
});
},
scrollToPageTop: function (){
var y1 = y2 = y3 = 0;
if( document.documentElement )
y1 = document.documentElement.scrollTop || 0;
if( document.body )
y2 = document.body.scrollTop || 0;
y3 = window.scrollY || 0;
var y = Math.max( y1, Math.max( y2, y3 ) );
window.scrollTo( 0, Math.floor( y / 1.4 ) );
if( y > 0 )
window.setTimeout( "GlobalDirector.process.scrollToPageTop()", 25 );
}
}
// end GlobalDirector.process
//**************************************************************************************************************
}
// -----------------------------------------------------------------
// Class preload actions
GlobalDirector.preload();
/********************************************************************************************
|
| SCRIPT REACTION
| live-page.js
|
| Created by : Kevin Biskaborn
| Copyright (c) 2005-2015 ScriptReaction
| https://www.scriptreaction.ca
|
|-- LATEST REVISION -------------------------------------------------------------------------
|
| K. Biskaborn
|
|-- CLASSES REQUIRED ------------------------------------------------------------------------
|
|
********************************************************************************************/
var LivePage = {
CONST: {
PAGE_REF_HOME: "home"
},
settings: {
isHome: 0,
ref: ""
},
launch: function ( ref ){
// save the live page ref
LivePage.settings.ref = ref;
// set flags
LivePage.settings.isHome = ( ref == LivePage.CONST.PAGE_REF_HOME );
},
//**************************************************************************************************************
// begin LivePage.verify
verify: {
isHome: function (){ return LivePage.settings.isHome; }
},
// end LivePage.verify
//**************************************************************************************************************
}
/********************************************************************************************
|
| SCRIPT REACTION
| software-downloader.js
|
| Created by : Kevin Biskaborn
| Copyright (c) 2005-2015 ScriptReaction
| https://www.scriptreaction.ca
|
|-- LATEST REVISION -------------------------------------------------------------------------
|
| K. Biskaborn
|
|-- CLASSES REQUIRED ------------------------------------------------------------------------
|
|
********************************************************************************************/
var SoftwareDownloader = {
ask: function ( packageName, versionCode ){
var msg = "ScriptReaction.ca\n";
msg += "Software Download: " + packageName + " v" + versionCode + "\n\n\n";
msg += "TERMS OF DOWNLOAD:\n\n";
msg += "You agree that this program is provided as-is, without warranty of any kind";
msg += " (either express or implied) including, without limitation, any implied warranty";
msg += " of merchantability and fitness for a particular purpose, and any warranty of non infringement.";
msg += " In no event shall ScriptReaction Ltd., or anyone involved with this software, be liable for any direct,";
msg += " indirect, incidental, special, exemplary, or consequential damages (including, but not limited to,";
msg += " procurement of substitute goods or services; loss of use, data, or profits; or business interruption)";
msg += " however caused and on any theory of liability, whether in contract, strict liability, or tort";
msg += " (including negligence or otherwise) arising in any way out of the use of the program, even if";
msg += " advised of the possibility of such damage.";
msg += "\n\n\nBy clicking OK, you accept these terms of download.\n";
return confirm( msg );
},
request: function ( packageRef ){
// create package containers
var fileExt = "";
var fileName = "";
var filePath = "";
var packageName = "";
var versionCode = "";
// populate package properties
switch( packageRef ) {
case "fleet-timer-sailing-regatta-sequence":
packageName = "Fleet Timer";
fileName = "fleet-timer";
fileExt = "zip";
versionCode = "1.2";
break;
case "month-maker-calendars":
packageName = "monthMAKER";
fileName = "month-maker";
fileExt = "exe";
versionCode = "1.0.1";
break;
case "regatta-data-sailing-results":
packageName = "regattaDATA";
fileName = "regatta-data";
fileExt = "zip";
versionCode = "1.3";
break;
}
// prompt the user
if( SoftwareDownloader.ask( packageName, versionCode ) )
// proceed with download
SoftwareDownloader.execute( packageRef + "/" + fileName + "-v" + versionCode + "-script-reaction." + fileExt );
},
execute: function ( filePath ){
location.href = filePath;
}
}
/********************************************************************************************
|
| ArrayUtility
| SCRIPT REACTION LIBRARY
|
| Created by : Kevin Biskaborn
| Copyright (c) 2005-2015 ScriptReaction Ltd. All Rights Reserved.
| https://www.scriptreaction.ca
|
|-- LATEST REVISION -------------------------------------------------------------------------
|
| K. Biskaborn
|
|-- CLASSES REQUIRED ------------------------------------------------------------------------
|
| NumberUtility
|
|-- HISTORY ---------------------------------------------------------------------------------
|
| OCT.22.2013 : Class reorganized. Search sorted ascending integer array function added.
| SEP.18.2012 : ArrayToString{} collection created.
| MAY.01.2011 : Class created.
|
********************************************************************************************/
var ArrayUtility = {
CONST: {
// AA Standard Constant Collection (v1)
ELEMENT_COUNT_ONE: 1,
ELEMENT_COUNT_ZERO: 0,
FLAG_VALUE_TRUE: 1,
FLAG_VALUE_FALSE: 0,
INDEX_FIRST_ELEMENT: 0,
INDEX_SECOND_ELEMENT: 1,
INVALID_ID: -1,
INVALID_INDEX: -1,
INVALID_OBJECT: null
},
//**************************************************************************************************************
// begin ArrayUtility.verify
verify: {
//>>
//-> FUNCTION NAME >> ArrayUtility.verify.arrayIsEmpty
//-> DESCRIPTION >> Checks if an array is empty (contains zero elements)
//-> PARAMETERS >> inputArray [Array]: the array to check if empty
//-> RETURN >> [Boolean]: true if the array is empty; false otherwise
//<<
arrayIsEmpty: function ( inputArray ){
return ( inputArray.length == ArrayUtility.CONST.ELEMENT_COUNT_ZERO );
},
itemExistsInArray: function ( needle, haystackArray ){
// create an existence flag
var itemExists = ArrayUtility.CONST.FLAG_VALUE_FALSE;
// -----------------------------------------------------------------
// cycle through all array items
for( var i = 0; i < haystackArray.length && !itemExists; ++i ){
// check for a match
if( haystackArray[ i ] == needle )
// raise the existence flag
// this will exit the loop
itemExists = ArrayUtility.CONST.FLAG_VALUE_TRUE;
}
return itemExists;
},
//>>
//-> FUNCTION NAME >> ArrayUtility.verify.itemExistsInSortedAlphabeticalStringArray
//-> DESCRIPTION >> Checks an array of strings ALREADY SORTED in ascending order
// for the requested string value
//-> PARAMETERS >> stringNeedle [string]: the string value to search for
// >> haystackArray [Array]: the array of strings sorted in ascending order
//-> RETURN >> [Boolean]: true if the search value is found; false otherwise
//<<
itemExistsInSortedAlphabeticalStringArray: function ( stringNeedle, haystackArray ){
// create an existence flag
var itemExists = false;
// create a continue search flag
var continueSearch = true;
// create loop containers
var stringValue;
// -----------------------------------------------------------------
// cycle through all array items
for( var i = 0; i < haystackArray.length && !itemExists && continueSearch; ++i ){
// get the next string value
stringValue = haystackArray[ i ];
// check for a match
if( stringValue == stringNeedle )
// raise the existence flag
itemExists = true;
// check if the value is larger than the needle
else if( stringValue > stringNeedle )
// stop searching
// since the array is sorted, the value cannot exist
continueSearch = false;
}
return itemExists;
},
//>>
//-> FUNCTION NAME >> ArrayUtility.verify.itemExistsInSortedAscendingIntegerArray
//-> DESCRIPTION >> Checks an array of integers ALREADY SORTED in ascending order
// for the requested integer value
//-> PARAMETERS >> intNeedle [int]: the integer value to search for
// >> haystackArray [Array]: the array of integers sorted in ascending order
//-> RETURN >> [Boolean]: true if the search value is found; false otherwise
//<<
itemExistsInSortedAscendingIntegerArray: function ( intNeedle, haystackArray ){
// create an existence flag
var itemExists = false;
// create a continue search flag
var continueSearch = true;
// create loop containers
var intValue;
// -----------------------------------------------------------------
// cycle through all array items
for( var i = 0; i < haystackArray.length && !itemExists && continueSearch; ++i ){
// get the next int value
intValue = haystackArray[ i ];
// check for a match
if( intValue == intNeedle )
// raise the existence flag
itemExists = true;
// check if the value is larger than the needle
else if( intValue > intNeedle )
// stop searching
// since the array is sorted, the value cannot exist
continueSearch = false;
}
return itemExists;
}
},
// end ArrayUtility.verify
//**************************************************************************************************************
//**************************************************************************************************************
// begin ArrayUtility.get
get: {
//>>
//-> FUNCTION NAME >> ArrayUtility.get.itemIndexInArray
//-> DESCRIPTION >> Gets the index of the requested element within the submitted array
//-> PARAMETERS >> needle [value]: the value to get the index of
// >> haystackArray [Array]: the array of elements to search
//-> RETURN >> [int]: the index if the needle value is found; -1 otherwise
//<<
itemIndexInArray: function ( needle, haystackArray ){
// output an invalid index by default
var index = ArrayUtility.CONST.INVALID_INDEX;
// -----------------------------------------------------------------
// cycle through all array items until all have been checked
// OR until a match has been found
for( var i = 0; i < haystackArray.length && index == ArrayUtility.CONST.INVALID_INDEX; ++i ){
// check for a match
if( haystackArray[ i ] == needle ){
// save the matching index
// this will exit the loop
index = i;
}
}
return index;
}
},
// end ArrayUtility.get
//**************************************************************************************************************
//**************************************************************************************************************
// begin ArrayUtility.arrayToString
arrayToString: {
//>>
//-> FUNCTION NAME >> ArrayUtility.arrayToString.stringDelimited
//-> DESCRIPTION >> Returns the elements of an array as a string separated
// by the requested string delimiter
//-> PARAMETERS >> btnElementId [String]: the HTML element id of the btn
//-> RETURN >> None
//<<
stringDelimited: function ( inputArray, delimitString ){
return inputArray.join( delimitString );
},
commaDelimited: function ( inputArray ){
return ArrayUtility.arrayToString.stringDelimited( inputArray, "," );
}
},
// end ArrayUtility.arrayToString
//**************************************************************************************************************
//**************************************************************************************************************
// begin ArrayUtility.process
process: {
//>>
//-> FUNCTION NAME >> ArrayUtility.process.addUniqueItem
//-> DESCRIPTION >> Adds an item to the requested array ONLY if the
// item does not already exist in the array
//-> PARAMETERS >> itemToAdd [Generic]: the element to add
// >> haystackArray [Array]: the array to add the element to
//-> RETURN >> [Array]: the array containing one copy of the unique item
//<<
addUniqueItem: function ( itemToAdd, haystackArray ){
// verify that the element does not already exist
if( !ArrayUtility.verify.itemExistsInArray( itemToAdd, haystackArray ) )
// the item does NOT exist in the array
haystackArray.push( itemToAdd );
return haystackArray;
},
// deletes all items in an array
clearArray: function ( inputArray ){
// delete all items from the requested array
return inputArray.splice( ArrayUtility.CONST.INDEX_FIRST_ELEMENT, inputArray.length );
},
copyArray: function ( inputArray ){
// create a PASS-BY-VALUE COPY of the input array
// this is a complete new array copy of the original
// with no reference to the original array
return inputArray.slice( ArrayUtility.CONST.INDEX_FIRST_ELEMENT );
},
mergeArrays: function ( inputArray_A, inputArray_B ){
// merges two arrays into one
return inputArray_A.concat( inputArray_B );
},
// removes an item from an array (if the item exists)
removeItem: function ( itemToRemove, haystackArray ){
// cycle through all items in the array
for( var i = 0; i < haystackArray.length; ++i ){
// check for a match
if( haystackArray[ i ] == itemToRemove ){
// delete the item
haystackArray.splice( i, ArrayUtility.CONST.ELEMENT_COUNT_ONE );
// exit the loop
break;
}
}
return haystackArray;
}
},
// end ArrayUtility.process
//**************************************************************************************************************
//**************************************************************************************************************
// begin ArrayUtility.reorder
reorder: {
applySort: {
integerAscending: function ( inputArray ){
// integer ascending sort: 0, 2, 5, 10, 12
return inputArray.sort( function( a ,b ){ return a - b } );
}
},
// reverses the order of all items in an array
reverseArray: function ( inputArray ){
return inputArray.reverse();
},
// shuffles the order of all array elements
shuffle: function ( inputArray ){
var output = [];
var index;
// continue extracting items while the array has more to give
while( inputArray.length > ArrayUtility.CONST.ELEMENT_COUNT_ZERO ){
// get the next index to be extracted
index = NumberUtility.generateRandom.fromZero( inputArray.length );
// add the element at that index to the output
output.push( inputArray[ index ] );
// remove the element from the array
inputArray.splice( index, ArrayUtility.CONST.ELEMENT_COUNT_ONE );
}
return output;
}
},
// end ArrayUtility.reorder
//**************************************************************************************************************
//**************************************************************************************************************
// begin ArrayUtility.strip
strip: {
// removes the last element from the array (if it is empty)
lastElement_ifEmpty: function ( inputArray ){
// get the last index in the array
var lastIndex = inputArray.length - ArrayUtility.CONST.ELEMENT_COUNT_ONE;
// get the last element in the array
var lastElement = inputArray[ lastIndex ];
// determine if the element is empty
if( lastElement == "" || lastElement == null )
// remove the last element
inputArray.splice( lastIndex, ArrayUtility.CONST.ELEMENT_COUNT_ONE );
return inputArray;
}
}
// end ArrayUtility.strip
//**************************************************************************************************************
}
/********************************************************************************************
|
| ElementClassUtility
| SCRIPT REACTION LIBRARY
|
| Created by : Kevin Biskaborn
| Copyright (c) 2005-2015 ScriptReaction Ltd. All Rights Reserved.
| https://www.scriptreaction.ca
|
|-- LATEST REVISION -------------------------------------------------------------------------
|
| K. Biskaborn
|
|-- CLASSES REQUIRED ------------------------------------------------------------------------
|
| ArrayUtility
| ElementAccessor
|
|-- HISTORY ---------------------------------------------------------------------------------
|
| OCT.22.2013 : Class reorganized.
| APR.13.2012 : Add / remove functions by ID added.
| MAY.01.2011 : Class created.
|
********************************************************************************************/
var ElementClassUtility = {
CONST: {
ELEMENT_CLASS_NAME_SEPARATOR: " " // space character separator for element classNames
},
//**************************************************************************************************************
// begin ElementClassUtility.verify
verify: {
classExistsOnElement: function ( element, classNameToVerify ){
// create a class exists flag
var classExists = false;
// verify that the object has a className parameter
if( element.className ){
// get the string of class names on the element
var stringOfClasses = element.className;
// get an array of the individual class names
var arrayOfClassNames = stringOfClasses.split( ElementClassUtility.CONST.ELEMENT_CLASS_NAME_SEPARATOR );
// check whether the requested class exists in the array
classExists = ArrayUtility.verify.itemExistsInArray( classNameToVerify, arrayOfClassNames );
}
return classExists;
},
classExistsOnElement_byId: function ( elementId, classNameToVerify ){
return ElementClassUtility.verify.classExistsOnElement( ElementAccessor.get( elementId ), classNameToVerify );
}
},
// end ElementClassUtility.verify
//**************************************************************************************************************
//**************************************************************************************************************
// begin ElementClassUtility.set
set: {
elementClass: function ( element, stringOfClasses ){
element.className = stringOfClasses;
}
},
// end ElementClassUtility.set
//**************************************************************************************************************
//**************************************************************************************************************
// begin ElementClassUtility.addClass
addClass: {
toElement: function ( element, classToAdd ){
// verify the requested element exists
if( !( element == null ) )
// add the new class to the requested element
ElementClassUtility.set.elementClass(
element, ElementClassUtility.addClass.toStringOfClasses( classToAdd, element.className )
);
},
toElement_byId: function ( elementId, classToAdd ){
// redirect to the element function
ElementClassUtility.addClass.toElement( ElementAccessor.get( elementId ), classToAdd );
},
toStringOfClasses: function ( classToAdd, stringOfClasses ){
// get an array of the individual class names
// which are always separated by a space character
var arrayOfClassNames = stringOfClasses.split( ElementClassUtility.CONST.ELEMENT_CLASS_NAME_SEPARATOR );
// add the requested class
ArrayUtility.process.addUniqueItem( classToAdd, arrayOfClassNames );
// return the classes as ONE string
return arrayOfClassNames.join( ElementClassUtility.CONST.ELEMENT_CLASS_NAME_SEPARATOR );
}
},
// end ElementClassUtility.addClass
//**************************************************************************************************************
//**************************************************************************************************************
// begin ElementClassUtility.removeClass
removeClass: {
fromElement: function ( element, classToRemove ){
// DEBUG ERROR OUTPUT
//if( typeof( element ) == "undefined" || element == null )
//console.log( "Error removing className: " + classToRemove + " on DOMobject: " + element );
// verify the requested element exists
if( !( element == null ) )
// remove the class from the requested element
ElementClassUtility.set.elementClass(
element, ElementClassUtility.removeClass.fromStringOfClasses( classToRemove, element.className )
);
},
fromElement_byId: function ( elementId, classToRemove ){
// redirect to the element function
ElementClassUtility.removeClass.fromElement( ElementAccessor.get( elementId ), classToRemove );
},
fromStringOfClasses: function ( classToRemove, stringOfClasses ){
// get an array of the individual class names
var arrayOfClassNames = stringOfClasses.split( ElementClassUtility.CONST.ELEMENT_CLASS_NAME_SEPARATOR );
// remove the requested class
ArrayUtility.process.removeItem( classToRemove, arrayOfClassNames );
// return the classes as ONE string
return arrayOfClassNames.join( ElementClassUtility.CONST.ELEMENT_CLASS_NAME_SEPARATOR );
}
},
// end ElementClassUtility.removeClass
//**************************************************************************************************************
//**************************************************************************************************************
// begin ElementClassUtility.process
process: {
addOrRemoveClassUsingFlag: function ( element, classToAddOrRemove, addClassFlag ){
// check the add class flag
if( addClassFlag )
ElementClassUtility.addClass.toElement( element, classToAddOrRemove );
else
ElementClassUtility.removeClass.fromElement( element, classToAddOrRemove );
},
addOrRemoveClassUsingFlag_byId: function ( elementId, classToAddOrRemove, addClassFlag ){
// redirect to the element function
ElementClassUtility.process.addOrRemoveClassUsingFlag(
ElementAccessor.get( elementId ), classToAddOrRemove, addClassFlag
);
},
applyDualStateClassUsingFlag: function ( element, trueStateClass, falseStateClass, stateFlag ){
// check the state flag
if( stateFlag ){
// FLAG IS RAISED / TRUE
// remove the FALSE state
ElementClassUtility.removeClass.fromElement( element, falseStateClass );
// add the TRUE state
ElementClassUtility.addClass.toElement( element, trueStateClass );
}
else {
// FLAG IS LOWERED / FALSE
// remove the TRUE state
ElementClassUtility.removeClass.fromElement( element, trueStateClass );
// add the FALSE state
ElementClassUtility.addClass.toElement( element, falseStateClass );
}
}
}
// end ElementClassUtility.process
//**************************************************************************************************************
}
/********************************************************************************************
|
| ElementPropUtility
| SCRIPT REACTION LIBRARY
|
| Created by : Kevin Biskaborn
| Copyright (c) 2005-2015 ScriptReaction Ltd. All Rights Reserved.
| https://www.scriptreaction.ca
|
|-- LATEST REVISION -------------------------------------------------------------------------
|
| K. Biskaborn
|
|-- CLASSES REQUIRED ------------------------------------------------------------------------
|
| ElementAccessor
|
|-- HISTORY ---------------------------------------------------------------------------------
|
| OCT.22.2013 : Class renamed from "DivElementUtility" to "ElementPropUtility".
| APR.05.2012 : Class created.
|
********************************************************************************************/
var ElementPropUtility = {
CONST: {
// Property IDs
PROP_ID_STYLE_BACKGROUND_IMAGE: "backgroundImage",
PROP_ID_STYLE_DISPLAY: "display",
PROP_ID_STYLE_VISIBILITY: "visibility",
// Property Values
PROP_VALUE_STYLE_BACKGROUND_IMAGE_NONE: "none",
PROP_VALUE_STYLE_DISPLAY_BLOCK: "block",
PROP_VALUE_STYLE_DISPLAY_NONE: "none",
PROP_VALUE_STYLE_VISIBILITY_HIDDEN: "hidden",
PROP_VALUE_STYLE_VISIBILITY_VISIBLE: "visible"
},
//**************************************************************************************************************
// begin ElementPropUtility.verify
verify: {
elementDisplay_isBlock: function ( element ){
return ( ElementPropUtility.get.style.display.by_element( element )
== ElementPropUtility.CONST.PROP_VALUE_STYLE_DISPLAY_BLOCK );
}
},
// end ElementPropUtility.verify
//**************************************************************************************************************
//**************************************************************************************************************
// begin ElementPropUtility.get
get: {
innerContent: {
by_element: function ( element ){
return ( element == null ) ? null : element.innerHTML;
},
by_id: function ( elementId ){
return ElementPropUtility.get.innerContent.by_element( ElementAccessor.get( elementId ) );
}
},
style: {
display: {
by_element: function ( element ){
return ElementPropUtility.get.style.property.by_element( element, ElementPropUtility.CONST.PROP_ID_STYLE_DISPLAY );
},
by_id: function ( elementId ){
return ElementPropUtility.get.style.display.by_element( ElementAccessor.get( elementId ) );
}
},
property: {
by_element: function ( element, propId ){
return ( element == null ) ? null : element.style[ propId ];
}
}
}
},
// end ElementPropUtility.get
//**************************************************************************************************************
//**************************************************************************************************************
// begin ElementPropUtility.set
set: {
innerContent: {
as_propRefresh: function ( element ){
// refreshes the inner content of the requested element
ElementPropUtility.set.innerContent.by_element(
element, ElementPropUtility.get.innerContent.by_element( element )
);
},
by_element: function ( element, propValue ){
// verify the element exists
if( !( element == null ) )
// set the div content
element.innerHTML = propValue;
},
//>>
//-> FUNCTION NAME >> ElementPropUtility.set.innerContent.by_id
//-> DESCRIPTION >> Sets the content of the specified HTML element
//-> PARAMETERS >> elementId [String]: the ID of the target HTML element
// >> propValue [String]: the inner content to insert into the element
//-> RETURN >> None
//<<
by_id: function ( elementId, propValue ){
ElementPropUtility.set.innerContent.by_element( ElementAccessor.get( elementId ), propValue );
}
},
//**************************************************************************************************************
// begin ElementPropUtility.set.style
style: {
//**************************************************************************************************************
// begin ElementPropUtility.set.style.backgroundImage
backgroundImage: {
by_element: function ( element, propValue ){
// format the background image value
// check for NO background
propValue = ( propValue == ElementPropUtility.CONST.PROP_VALUE_STYLE_BACKGROUND_IMAGE_NONE )
// no background, maintain value
? propValue
// assume a background image path
: "url(" + propValue + ")";
// set the property value
ElementPropUtility.set.style.property.by_element( element, ElementPropUtility.CONST.PROP_ID_STYLE_BACKGROUND_IMAGE, propValue );
},
by_id: function ( elementId, propValue ){
ElementPropUtility.set.style.backgroundImage.by_element( ElementAccessor.get( elementId ), propValue );
}
},
// end ElementPropUtility.set.style.backgroundImage
//**************************************************************************************************************
//**************************************************************************************************************
// begin ElementPropUtility.set.style.display
display: {
as_block: function ( element ){
ElementPropUtility.set.style.display.by_element( element, ElementPropUtility.CONST.PROP_VALUE_STYLE_DISPLAY_BLOCK );
},
as_none: function ( element ){
ElementPropUtility.set.style.display.by_element( element, ElementPropUtility.CONST.PROP_VALUE_STYLE_DISPLAY_NONE );
},
by_element: function ( element, propValue ){
ElementPropUtility.set.style.property.by_element( element, ElementPropUtility.CONST.PROP_ID_STYLE_DISPLAY, propValue );
},
by_id: function ( elementId, propValue ){
ElementPropUtility.set.style.display.by_element( ElementAccessor.get( elementId ), propValue );
},
fromFlag_byElement: function ( element, isVisibleFlag ){
// set the display of the element as block if it visible
if( isVisibleFlag ) ElementPropUtility.set.style.display.as_block( element );
else ElementPropUtility.set.style.display.as_none( element );
},
//>>
//-> FUNCTION NAME >> ElementPropUtility.set.style.display.fromFlag_byId
//-> DESCRIPTION >> Sets the BLOCK/NONE CSS style property of the requested element
// based on the submitted flag.
//-> PARAMETERS >> elementId [String]: the HTML element id
// >> isVisibleFlag [Boolean]: true if the element is to be visible,
// false otherwise
//-> RETURN >> None
//<<
fromFlag_byId: function ( elementId, isVisibleFlag ){
ElementPropUtility.set.style.display.fromFlag_byElement( ElementAccessor.get( elementId ), isVisibleFlag );
}
},
// end ElementPropUtility.set.style.display
//**************************************************************************************************************
//**************************************************************************************************************
// begin ElementPropUtility.set.style.visibility
visibility: {
as_hidden: function ( element ){
ElementPropUtility.set.style.visibility.by_element( element, ElementPropUtility.CONST.PROP_VALUE_STYLE_VISIBILITY_HIDDEN );
},
as_visible: function ( element ){
ElementPropUtility.set.style.visibility.by_element( element, ElementPropUtility.CONST.PROP_VALUE_STYLE_VISIBILITY_VISIBLE );
},
by_element: function ( element, propValue ){
ElementPropUtility.set.style.property.by_element( element, ElementPropUtility.CONST.PROP_ID_STYLE_VISIBILITY, propValue );
},
by_id: function ( elementId, propValue ){
ElementPropUtility.set.style.visibility.by_element( ElementAccessor.get( elementId ), propValue );
},
fromFlag_byElement: function ( element, isVisibleFlag ){
// set the display of the element as block if it visible
if( isVisibleFlag ) ElementPropUtility.set.style.visibility.as_visible( element );
else ElementPropUtility.set.style.visibility.as_hidden( element );
},
//>>
//-> FUNCTION NAME >> ElementPropUtility.set.style.visibility.fromFlag_byId
//-> DESCRIPTION >> Sets the VISIBLE/HIDDEN CSS style property of the requested element
// based on the submitted flag.
//-> PARAMETERS >> elementId [String]: the HTML element id
// >> isVisibleFlag [Boolean]: true if the element is to be visible,
// false otherwise
//-> RETURN >> None
//<<
fromFlag_byId: function ( elementId, isVisibleFlag ){
ElementPropUtility.set.style.visibility.fromFlag_byElement( ElementAccessor.get( elementId ), isVisibleFlag );
}
},
// end ElementPropUtility.set.style.visibility
//**************************************************************************************************************
//**************************************************************************************************************
// begin ElementPropUtility.set.style.property
property: {
by_element: function ( element, propId, propValue ){
// verify the element exists
if( !( element == null ) )
// set the requested style property
element.style[ propId ] = propValue;
}
}
// end ElementPropUtility.set.style.property
//**************************************************************************************************************
}
}
// end ElementPropUtility.set
//**************************************************************************************************************
}
/********************************************************************************************
|
| NumberUtility
| SCRIPT REACTION LIBRARY
|
| Created by : Kevin Biskaborn
| Copyright (c) 2005-2015 ScriptReaction Ltd. All Rights Reserved.
| https://www.scriptreaction.ca
|
|-- LATEST REVISION -------------------------------------------------------------------------
|
| K. Biskaborn
|
|-- CLASSES REQUIRED ------------------------------------------------------------------------
|
| StringUtility
|
|-- HISTORY ---------------------------------------------------------------------------------
|
| NOV.07.2012 : Class created.
|
********************************************************************************************/
var NumberUtility = {
CONST: {
// AA Standard Constant Collection (v1)
ELEMENT_COUNT_ONE: 1,
ELEMENT_COUNT_ZERO: 0,
FLAG_VALUE_TRUE: 1,
FLAG_VALUE_FALSE: 0,
INDEX_FIRST_ELEMENT: 0,
INDEX_SECOND_ELEMENT: 1,
INVALID_ID: -1,
INVALID_INDEX: -1,
INVALID_OBJECT: null,
// parsing radix for decimal numbers
PARSE_INT_RADIX_DECIMAL: 10
},
//**************************************************************************************************************
// begin NumberUtility.verify
verify: {
isInteger_allowPointZero: function ( value ){
// Note:
// if 1.0 needs to be valid, use:
// verify the value IS a number,
// that the parsed int is a number,
// AND the float (decimal point) value EQUALS the int value (ie: 1 = 1.0)
return !isNaN( value )
&& !isNaN( NumberUtility.get.valueAsInteger( value ) )
&& ( parseFloat( value ) == parseInt( value ) );
},
isInteger_noDecimal: function ( value ){
// verify the value IS a number,
// that the parsed int is a number,
// AND that NO DECIMAL POINT is used
return !isNaN( value )
&& !isNaN( NumberUtility.get.valueAsInteger( value ) )
&& !StringUtility.verify.contains( value.toString(), "." );
}
},
// end NumberUtility.verify
//**************************************************************************************************************
//**************************************************************************************************************
// begin NumberUtility.get
get: {
absoluteValue: function ( value ){
return ( value < NumberUtility.CONST.ELEMENT_COUNT_ZERO )
? value * -1 : value;
},
valueAsInteger: function ( value ){
return parseInt( value, NumberUtility.CONST.PARSE_INT_RADIX_DECIMAL );
}
},
// end NumberUtility.get
//**************************************************************************************************************
//**************************************************************************************************************
// begin NumberUtility.generateRandom
generateRandom: {
fromOneToMax: function ( maximum ){
return NumberUtility.generateRandom.fromZero( maximum ) + NumberUtility.CONST.ELEMENT_COUNT_ONE;
},
fromZero: function ( maximum ){
return Math.floor( Math.random() * maximum );
}
}
// end NumberUtility.generateRandom
//**************************************************************************************************************
}
/********************************************************************************************
|
| StringUtility
| SCRIPT REACTION LIBRARY
|
| Created by : Kevin Biskaborn
| Copyright (c) 2005-2015 ScriptReaction Ltd. All Rights Reserved.
| https://www.scriptreaction.ca
|
|-- LATEST REVISION -------------------------------------------------------------------------
|
| K. Biskaborn
|
|-- CLASSES REQUIRED ------------------------------------------------------------------------
|
| ArrayUtility
|
|-- HISTORY ---------------------------------------------------------------------------------
|
| OCT.20.2014 : Reverse function and nChar left and right trim functions added.
| OCT.22.2013 : Class reorganized.
| MAR.24.2012 : Class created.
|
|-- NOTES ---------------------------------------------------------------------------------
|
| - Regular Expressions consider a string AS A WHOLE; they do NOT iterate by character.
| The expression searches a string for any matching patterns and executes from there.
}
********************************************************************************************/
var StringUtility = {
CONST: {
// AA Standard Constant Collection (v1)
ELEMENT_COUNT_ONE: 1,
ELEMENT_COUNT_ZERO: 0,
FLAG_VALUE_TRUE: 1,
FLAG_VALUE_FALSE: 0,
INDEX_FIRST_ELEMENT: 0,
INDEX_SECOND_ELEMENT: 1,
INVALID_ID: -1,
INVALID_INDEX: -1,
INVALID_OBJECT: null,
NEGATIVE_ONE: -1
},
//**************************************************************************************************************
// begin StringUtility.verify
verify: {
beginsWith: function ( inputString, prefix ){
// test if the input string begins with the requested prefix
return ( inputString.substring( StringUtility.CONST.INDEX_FIRST_ELEMENT, prefix.length ) == prefix );
},
contains: function ( inputString, searchNeedleString ){
// searches the inputString for the requested needle
// in the event the needle is a number, the var is cast to a string below
return ( inputString.indexOf( "" + searchNeedleString ) >= StringUtility.CONST.ELEMENT_COUNT_ZERO );
},
endsWith: function ( inputString, suffix ){
// test if the input string ends with the requested suffix
return ( inputString.substring( inputString.length - suffix.length, inputString.length ) == suffix );
},
isValidEmail: function ( inputString ){
var regex = /^[a-z0-9\._-]+@([a-z0-9_-]+\.)+[a-z]{2,6}$/i;
return regex.test( inputString );
}
},
// end StringUtility.verify
//**************************************************************************************************************
//**************************************************************************************************************
// begin StringUtility.get
get: {
charAtIndex: function ( inputString, charIndex ){
return inputString.charAt( charIndex );
},
firstChar: function ( inputString ){
return StringUtility.get.charAtIndex(
inputString, StringUtility.CONST.INDEX_FIRST_ELEMENT
);
},
stringLength: function ( inputString ){
return inputString.length;
}
},
// end StringUtility.get
//**************************************************************************************************************
//**************************************************************************************************************
// begin StringUtility.process
process: {
addPadding: {
prefix: function ( inputValue, padCharString, size ){
// the inputValue must be cast to a string (value may be a number)
inputString = inputValue.toString();
// pad string with requested pad character
while( inputString.length < size )
inputString = padCharString + inputString;
return inputString;
},
prefix_zero: function ( inputValue, size ){
return StringUtility.process.addPadding.prefix(
inputValue, "0", size
);
}
},
//>>
//-> FUNCTION NAME >> StringUtility.process.decodeHtmlSpecialChars
//-> DESCRIPTION >> Replaces all occurances of safe web code characters
// with HTML special characters (&,<,>,",')
//-> PARAMETERS >> inputString [String]: the string to format
//-> RETURN >> The string with UNSAFE HTML characters
//<<
decodeHtmlSpecialChars: function ( inputString ){
// Note: the amperstand replacement must occur FIRST
return inputString
.replace( /&/g, "&" )
.replace( /</g, "<" )
.replace( />/g, ">" )
.replace( /"/g, "\"" )
.replace( /'/g, "'" );
},
//>>
//-> FUNCTION NAME >> StringUtility.process.encodeHtmlSpecialChars
//-> DESCRIPTION >> Replaces all occurances of HTML special characters
// (&,<,>,",') in the submitted string with
// safe web code alternatives
//-> PARAMETERS >> inputString [String]: the string to format
//-> RETURN >> The string with safe web characters
//<<
encodeHtmlSpecialChars: function ( inputString ){
// Note: the amperstand replacement must occur FIRST
return inputString
.replace( /&/g, "&" )
.replace( //g, ">" )
.replace( /"/g, """ )
.replace( /'/g, "'" );
},
parseQueryStringToObject: function ( queryString ){
// breaks up a query string into an object representation
// For example, INPUT: ?name=AdminArea&dev=ScriptReaction
// OUTPUT: { name: "AdminArea", dev: "ScriptReaction" }
var output = new Object();
//remove the leading query string char
queryString = StringUtility.remove.prefix( queryString, "?" );
//remove the trailing query string char
queryString = StringUtility.remove.suffix( queryString, "&" );
//split the query string
//into individual data items
var dataItemArray = queryString.split( "&" );
//create variable containers
var dataItem = "";
var itemArray = [];
//cycle through all data items
for( var i = 0; i < dataItemArray.length; i++ ){
dataItem = dataItemArray[ i ];
//split the data item
//into id and value pairs
itemArray = dataItem.split( "=" );
//add the item to the output
output[ itemArray[ 0 ] ] = itemArray[ 1 ];
}
return output;
},
reverseString: function ( str ){
return str.split( "" ).reverse().join( "" );
}
},
// end StringUtility.process
//**************************************************************************************************************
//**************************************************************************************************************
// begin StringUtility.remove
remove: {
//>>
//-> FUNCTION NAME >> StringUtility.remove.prefix
//-> DESCRIPTION >> Removes the specified prefix (if it exists)
// from the specified string
//-> PARAMETERS >> inputString [String]: the string to remove the prefix from
// >> prefix [String]: the prefix to remove
//-> RETURN >> The string with the prefix removed if the prefix existed,
// else the original string
//<<
prefix: function ( inputString, prefix ){
// removes ONE INSTANCE of the prefix from the inputString
// to remove ALL instances of the prefix, use StringUtility.strip.leadingChars()
if( StringUtility.verify.beginsWith( inputString, prefix ) )
return inputString.substring( prefix.length, inputString.length );
else
return inputString;
},
suffix: function ( inputString, suffix ){
// removes ONE INSTANCE of the suffix from the inputString
// to remove ALL instances of the suffix, use StringUtility.strip.trailingChars()
if( StringUtility.verify.endsWith( inputString, suffix ) )
return inputString.substring( 0, inputString.length - suffix.length );
else
return inputString;
}
},
// end StringUtility.remove
//**************************************************************************************************************
//**************************************************************************************************************
// begin StringUtility.replaceOccurances
replaceOccurances: {
allOccurances: function ( inputString, searchNeedleString, replacementString, isCaseSensitive ){
// use a regular expression
// set the regex parameters
// g: global search (all occurances)
// i: case IN-sensitive
var regEx_param = "g";
// check for a case in-sensitive search
if( !isCaseSensitive )
regEx_param += "i";
// create the regular expression
// for the string to be search for
var regEx = new RegExp( searchNeedleString, regEx_param );
// execute the replace on the target string
return inputString.replace( regEx, replacementString );
}
},
// end StringUtility.replaceOccurances
//**************************************************************************************************************
//**************************************************************************************************************
// begin StringUtility.strip
strip: {
doubleSpaces: function ( inputString ){
return inputString.replace( /\s\s/, " " );
},
htmlSpecialCharCodes: function ( inputString ){
return inputString
.replace( /&/g, "" )
.replace( /</g, "" )
.replace( />/g, "" )
.replace( /"/g, "" )
.replace( /'/g, "" );
},
htmlTags: function ( inputString ){
return inputString.replace( /(<([^>]+)>)/ig, "" );
},
leadingChars: function ( inputString, charToStrip ){
// removes ALL OCCURANCES of the specified leading character to strip
// from the beginning of the inputString
// create the regex pattern
// new RegExp (pattern, modifiers)
var regex = new RegExp( "^" + charToStrip + "+", "g" );
// execute the replace
return inputString.replace( regex, "" );
},
nonIntegerChars_allowNegatives: function ( inputString ){
// get the first char of the string
var firstChar = StringUtility.get.firstChar( inputString );
// test for a negative value
var isNegative = ( firstChar == "-" );
// remove ALL HTML special character codes
inputString = StringUtility.strip.htmlSpecialCharCodes( inputString );
// remove ALL non-numeric characters
// (including any dashes)
inputString = StringUtility.strip.nonIntegerChars_noNegatives( inputString );
// re-attached the first char (if negative)
if( isNegative )
inputString = firstChar + inputString;
return inputString;
},
nonIntegerChars_noNegatives: function ( inputString ){
// remove ALL HTML special character codes
inputString = StringUtility.strip.htmlSpecialCharCodes( inputString );
// regex matches the chars to be REPLACED
// [^0-9] = not one of 0 through 9 (any non-numeric char)
return inputString.replace( /[^0-9]+/g, "" );
},
trailingChars: function ( inputString, charToStrip ){
// create the regex pattern
var regex = new RegExp( charToStrip + "+$", "g" );
// execute the replace
return inputString.replace( regex, "" );
},
tripleSpaces: function ( inputString ){
return inputString.replace( /\s\s\s/, " " );
}
},
// end StringUtility.strip
//**************************************************************************************************************
//**************************************************************************************************************
// begin StringUtility.trim
trim: {
nchars: {
// these functions trim a specified NUMBER of characters
left: function ( inputString, numChars ){
return inputString.slice( numChars );
},
right: function ( inputString, numChars ){
return inputString.slice(
StringUtility.CONST.ELEMENT_COUNT_ZERO,
numChars * StringUtility.CONST.NEGATIVE_ONE
);
}
},
whitespace: {
// these functions trim WHITESPACE (space / tab chars)
bothEnds: function ( inputString ){
return StringUtility.trim.whitespace.left(
StringUtility.trim.whitespace.right( inputString )
);
},
left: function ( inputString ){
// note that space character is LITERALLY entered
// in the regular expression string (\s is NOT used)
var regex = new RegExp( "^ +", "g" );
return inputString.replace( regex, "" );
},
right: function ( inputString ){
var regex = new RegExp( " +$", "g" );
return inputString.replace( regex, "" );
}
}
},
// end StringUtility.trim
//**************************************************************************************************************
//**************************************************************************************************************
// begin StringUtility.build
build: {
collapsedRangeDisplay_forArrayOfIntegers: function ( inputObject ){
var output = "";
// Accepts an array of integers and creates a compressed display of all integers present.
// Example Input: [ 4, 6, 7, 8, 10, 11, 12, 15 ]
// Example Output: "4, 6-8, 10-12, 15"
// Notes: duplicate values are ignored, negative values are allowed.
// extract incoming
var arrayOfIntegers = ( typeof( inputObject.arrayOfIntegers ) != "undefined" ) ? inputObject.arrayOfIntegers : [];
var elementList_delimiter = ( typeof( inputObject.elementList_delimiter ) != "undefined" ) ? inputObject.elementList_delimiter : ", ";
var collapsedRange_delimiter = ( typeof( inputObject.collapsedRange_delimiter ) != "undefined" ) ? inputObject.collapsedRange_delimiter : "-";
var collapsedRange_minSize = ( typeof( inputObject.collapsedRange_minSize ) != "undefined" ) ? inputObject.collapsedRange_minSize : 3;
// -------------------------------------------------------------
// get the number of elements
var numElements = arrayOfIntegers.length;
// verify integers exist
if( numElements > StringUtility.CONST.ELEMENT_COUNT_ZERO ){
// sort the collection of integers
arrayOfIntegers = ArrayUtility.reorder.applySort.integerAscending( arrayOfIntegers );
// check if the number of entries is LESS THAN the minimum size of a collapsed range
if( numElements < collapsedRange_minSize )
// use a simple list of elements
output += "" + ArrayUtility.arrayToString.stringDelimited( arrayOfIntegers, elementList_delimiter );
else {
// -------------------------------------------------------------
// enough elements exist for AT LEAST ONE collapsed range
// create an array to store range collections
var arrayOfRangeCollections = [];
// create an array to store list groups (final output)
var arrayOfListGroups = [];
// populate the range collections with nested arrays, one for each element
for( var i = StringUtility.CONST.INDEX_FIRST_ELEMENT; i < numElements; i++ )
arrayOfRangeCollections.push( [] );
// create loop containers
// active range index counter
var activeRangeIndex = StringUtility.CONST.INVALID_INDEX;
// previous numver value
// value is equal to TWO less than the first integer
// (so no previous number match occurs in the first loop execution
var prevNumber = arrayOfIntegers[ StringUtility.CONST.INDEX_FIRST_ELEMENT ] - 2;
// -------------------------------------------------------------
// create loop containers
var integerValue;
// cycle through the array of elements
for( i in arrayOfIntegers ){
// get the next int value
integerValue = arrayOfIntegers[ i ];
// verify the next number is NOT THE SAME as the previous
// duplicate values are not included
if( !( integerValue == prevNumber ) ){
// check if the next integer is NOT a number, or it is a number
// that does NOT immediately follow the previous number in sequence
if( isNaN( integerValue )
|| !( integerValue == prevNumber + StringUtility.CONST.ELEMENT_COUNT_ONE ) )
// increment the active range index
// on the first pass of the loop, this increment MUST occur
++activeRangeIndex;
// add the element to the active range
arrayOfRangeCollections[ activeRangeIndex ].push( integerValue );
// update the previous number
prevNumber = integerValue;
}
}
// -------------------------------------------------------------
// create loop containers
var rangeArray;
// cycle through the range collections
for( i in arrayOfRangeCollections ){
// get the next range array
rangeArray = arrayOfRangeCollections[ i ];
// get the number of elements in the range
rangeSize = rangeArray.length;
// verify that at least ONE element exists in the range
if( rangeSize >= StringUtility.CONST.ELEMENT_COUNT_ONE ){
// check if the range has LESS THAN the minimum size
if( rangeSize < collapsedRange_minSize )
// use a simple list of elements for that range collection
arrayOfListGroups.push(
ArrayUtility.arrayToString.stringDelimited( rangeArray, elementList_delimiter )
);
else {
// the range collection needs to be collapsed
// get the first element of the range
var firstElement = rangeArray[ StringUtility.CONST.INDEX_FIRST_ELEMENT ];
// get the last element of the range
var lastElement = rangeArray[ rangeSize - StringUtility.CONST.ELEMENT_COUNT_ONE ];
// add the collapsed range to the array of list elements
arrayOfListGroups.push(
firstElement + collapsedRange_delimiter + lastElement
);
}
}
}
// merge the list elements
output += ArrayUtility.arrayToString.stringDelimited( arrayOfListGroups, elementList_delimiter );
}
}
return output;
}
}
// end StringUtility.build
//**************************************************************************************************************
}