12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504 |
- /*------------------------------------------------------------------------------
- Function: eCSStender()
- Author: Aaron Gustafson (aaron at easy-designs dot net)
- Creation Date: 2006-12-03
- Version: 1.2.6.4
- Homepage: http://eCSStender.org
- License: MIT License (see homepage)
- ------------------------------------------------------------------------------*/
- (function(){
-
- var
- // common references
- UNDEFINED,
- TRUE = true,
- FALSE = false,
- NULL = null,
- STRING = 'string',
- NUMBER = 'number',
- OBJECT = 'object',
- ARRAY = Array,
- FUNCTION = Function,
- REGEXP = RegExp,
- DOCUMENT = document,
- WINDOW = window,
- LOCATION = WINDOW.location.href,
- EMPTY_FN = function(){},
-
- // Common Strings
- ECSSTENDER = 'eCSStender',
- EXTENSION = 'extension',
- SELECTOR = 'selector',
- PROPERTY = 'property',
- SPECIFICITY = 'specificity',
- SCREEN = 'screen',
- ALL = 'all',
- MEDIA = 'media',
- FIND_BY = 'find_by',
- TEST = 'test',
- LOOKUP = 'lookup',
- FRAGMENT = 'fragment',
- PREFIX = 'prefix',
- PROPERTIES = 'properties',
- CALLBACK = 'callback',
- FILTER = 'filter',
- PROCESSED = 'processed',
- FINGERPRINT = 'fingerprint',
- PIPES = '||||',
- EMPTY = '',
- SPACE = ' ',
- STAR = '*',
- SLASH = '/',
- COLON = ':',
- SEMICOLON = ';',
- HYPHEN = '-',
- OPEN_CURLY = '{',
- CLOSE_CURLY = '}',
- DIV = 'div',
- TYPE = 'type',
- COMPLETE = 'complete',
-
- // Regex Bits
- ANYTHING = '.*?',
- HYPHEN_ANYTHING = '-.*',
- CAPTURE = '$1',
-
- // placeholders
- PH_ATMEDIA = '!' + ECSSTENDER + '-media-placeholder!',
-
- // internals
- __eCSStensions = {}, // eCSStensions for parsing
- __e_count = 0, // count of registered extensions
- __t_count = 0, // count of triggered extensions
- __stylesheets = [], // stylesheets to parse
- __s = 0, // index of current stylesheet
- __style_objects = {}, // style rules to track
- __media_groups = {},
- __xhr = NULL,
- __initialized = FALSE,
- __ignored_css = [],
- __ignored_props = [ SELECTOR, SPECIFICITY ],
- __location = LOCATION.replace( /^\w+:\/\/\/?(.*?)\/.*/, CAPTURE ),
- __local = ( LOCATION.indexOf( 'http' ) !== 0 ),
- __delayed = {}, // delayed stylesheets to write
- __on_complete = [],
-
- // expando handling (for IE)
- __expando = DOCUMENT.expando,
- toggleExpando = EMPTY_FN,
-
- // for embedding stylesheets
- __head = DOCUMENT.getElementsByTagName( 'head' )[0],
- __body = NULL,
- __style = newElement( 'style' ),
- __embedded_css = [],
- addRules = EMPTY_FN,
-
- // caching
- COUNT = '-count',
- __modified = {},
- __no_cache = FALSE,
- __cached_out = FALSE,
- __local_cache = {
- xhr: {},
- extension: {},
- selector: {},
- property: {}
- },
- __headers = {},
- __cache_object,
- readFromBrowserCache = EMPTY_FN,
- writeToBrowserCache = EMPTY_FN,
- clearBrowserCache = EMPTY_FN,
-
- // other stuff
- __script = newElement( 'script' ),
-
- // useful RegExps
- // for breaking on commas
- REGEXP_COMMA = /\s*,\s*/,
- // for getting file names
- REGEXP_FILE = /.*\/(.*?\..*?)(?:\?.*)?$/,
- // generalized @ rules
- REGEXP_ATRULE = /@([\w-]+)(.*?)\{([^}]*)\}/ig,
- // for splitting properties from values
- REGEXP_P_V = /:(?!\/\/)/,
-
- // eCSStender Object
- eCSStender = {
- name: ECSSTENDER,
- version: '1.2.6.4',
- fonts: [],
- pages: {},
- at: {},
- methods: {},
- cache: FALSE,
- exec_time: 0
- };
-
- // window object
- WINDOW.eCSStender = eCSStender;
-
- /*------------------------------------*
- * Private Methods *
- *------------------------------------*/
- function initialize()
- {
- // keep us from going off more than 1x
- if ( __initialized ){ return; }
- __initialized = TRUE;
- // performance logging
- eCSStender.exec_time = now();
- // DOM Access
- __body = DOCUMENT.getElementsByTagName( 'body' )[0];
- // innards
- readBrowserCache();
- getActiveStylesheets();
- parseStyles();
- }
- function wrapUp()
- {
- validateCache();
- runTests();
- eCSStend();
- triggerCallbacks();
- writeBrowserCache();
- // performance logging
- eCSStender.exec_time = ( now() - eCSStender.exec_time ) * .001;
- triggerOnCompletes();
- }
- function getActiveStylesheets()
- {
- var
- stylesheets = DOCUMENT.styleSheets,
- s = 0, sLen = stylesheets.length;
- for ( ; s<sLen; s++ )
- {
- // add the stylesheet
- addStyleSheet( stylesheets[s] );
- }
- // cssText is truly unreliable, we need to rely on XHR
- if ( sLen > 0 )
- {
- __xhr = TRUE;
- }
- }
- function parseStyles()
- {
- var s=0, sLen=__stylesheets.length, media, m, mLen;
- for ( ; s<sLen; s++ )
- {
- // determine the media type
- media = determineMedia( __stylesheets[s] );
- createMediaContainers( media );
- determinePath( __stylesheets[s] );
- }
- getCSSFiles();
- }
- function validateCache()
- {
- if ( __no_cache || __local ){ return; }
- // check the xhr headers against what we read from the cache
- var key, cached = __local_cache.xhr, i=0, j=0;
- eCSStender.cache = TRUE;
- for ( key in __modified )
- {
- i++;
- if ( ! isInheritedProperty( __modified, key ) &&
- __modified[key] != NULL )
- {
- j++;
- if ( ! defined( cached[key] ) ||
- cached[key] != __modified[key] )
- {
- eCSStender.cache = FALSE;
- }
- // update the cache
- __local_cache.xhr[key] = __modified[key];
- }
- }
- if ( i>j || ( i === 0 && j === 0 ) ){ eCSStender.cache = FALSE; }
- }
- function runTests()
- {
- if ( eCSStender.cache ){ return; }
- var temp = {}, e, count=0, extension_test;
- for ( e in __eCSStensions )
- {
- if ( ! isInheritedProperty( __eCSStensions, e ) )
- {
- extension_test = __eCSStensions[e][TEST];
- // verify test (if any)
- if ( ! defined( extension_test ) ||
- ( is( extension_test, FUNCTION ) &&
- extension_test() ) )
- {
- // if no test or test is passed, push to the temp array
- temp[e] = __eCSStensions[e];
- count++;
- }
- }
- }
- // reset the __eCSStensions array
- __eCSStensions = temp;
- __e_count = count;
- }
- function eCSStend()
- {
- // see if there's anything to do
- if ( __e_count < 1 ){ return; }
- var
- medium, styles, sorted_styles, s, sLen, selector,
- eLoop, e, e_media, e_lookup, e_find_by,
- lookups, l, lLen, temp, t, lookup,
- property;
- // no cache
- if ( ! eCSStender.cache )
- {
- // parse by medium
- for ( medium in __style_objects )
- {
- // safety for users who are using Prototype or any code that extends Object
- if ( ! isInheritedProperty( __style_objects, medium ) )
- {
- // start the processing in earnest
- styles = __style_objects[medium];
- sorted_styles = getSortedArray( styles );
- for ( s=0, sLen=sorted_styles.length; s<sLen; s++ )
- {
- selector = sorted_styles[s][SELECTOR];
- // loop the extensions
- eLoop:
- for ( e in __eCSStensions )
- {
- // safety for users who are using Prototype or any code that extends Object
- if ( ! isInheritedProperty( __eCSStensions, e ) )
- {
- e_media = __eCSStensions[e][MEDIA];
- // verify any media restrictions
- if ( defined( e_media ) &&
- e_media != ALL )
- {
- e_media = e_media.split(REGEXP_COMMA);
- if ( medium != ALL &&
- ! in_object( medium, e_media ) ){
- continue;
- }
- }
- e_find_by = __eCSStensions[e][FIND_BY];
- e_lookup = __eCSStensions[e][LOOKUP];
- lLen = e_lookup.length;
- // eCSStension is triggered by a selector
- if ( e_find_by == SELECTOR )
- {
- for ( l=0; l<lLen; l++ )
- {
- if ( selectorMatches( selector, e_lookup[l] ) )
- {
- trackCallback( e, medium, selector );
- continue eLoop;
- }
- }
- }
- // eCSStension uses a property
- else if ( e_find_by == PROPERTY )
- {
- for ( l=0; l<lLen; l++ )
- {
- if ( defined( styles[selector][e_lookup[l]] ) )
- {
- trackCallback( e, medium, selector );
- continue eLoop;
- }
- }
- }
- // eCSStension uses a fragment or prefix
- else if ( e_find_by == FRAGMENT ||
- e_find_by == PREFIX )
- {
- lookup = ( e_find_by == FRAGMENT ) ? ANYTHING + e_lookup + ANYTHING
- : HYPHEN + e_lookup + HYPHEN_ANYTHING;
- lookup = newRegExp( lookup );
- for ( property in styles[selector] )
- {
- if ( ! isInheritedProperty( styles, selector ) && // fix for tainted Object
- ! in_object( property, __ignored_props ) &&
- property.match( lookup ) )
- {
- trackCallback( e, medium, selector );
- continue eLoop;
- }
- }
- } // end if eCSStension uses a fragment or prefix
- } // end extended object test
- } // end eCSStensions loop
- } // end styles loop
- } // end extended object test
- } // end medium loop
- } // end if no cache
- }
- // log callbacks
- function trackCallback( fingerprint, medium, selector )
- {
- var selector_id = medium + PIPES + selector;
- writeToLocalCache( EXTENSION, EXTENSION + ( __t_count++ ), fingerprint + PIPES + selector_id, FALSE );
- }
- // callback functionality
- function triggerCallbacks()
- {
- var s = 0, e, extension, style_rule, selector_id, properties, specificity, oLen, result;
- for ( ; s<__t_count; s++ )
- {
- e = __local_cache[EXTENSION][EXTENSION+s].split(PIPES);
- extension = __eCSStensions[e[0]];
- if ( defined( __style_objects[e[1]] ) )
- {
- style_rule = __style_objects[e[1]][e[2]];
- selector_id = e[1] + PIPES + e[2];
- if ( ! defined( extension ) ||
- ! defined( style_rule ) ||
- in_object( selector_id, extension[PROCESSED] ) ||
- // apply any filters
- ( defined( extension[FILTER] ) &&
- ! filtersMatched( style_rule, extension[FILTER] ) ) ) { continue; }
- specificity = ( ! eCSStender.cache ) ? style_rule[SPECIFICITY]
- : getSpecificity( e[2] );
- properties = extractProperties( e[1], e[2], extension[PROPERTIES] );
- result = extension[CALLBACK]( e[2], properties, e[1], specificity );
- // allow on-the-fly re-definition of callback
- if ( is( result, FUNCTION ) )
- {
- __eCSStensions[e[0]][CALLBACK] = result;
- }
- __eCSStensions[e[0]][PROCESSED].push( selector_id );
- }
- }
- }
- function triggerOnCompletes()
- {
- var o = __on_complete.length;
- while ( o-- )
- {
- __on_complete[o]();
- }
- }
- /*------------------------------------*
- * Private Utils *
- *------------------------------------*/
- function findImportedStylesheets( stylesheet )
- {
- // W3C
- if ( ! defined( stylesheet.imports ) )
- {
- findImportedStylesheets = function( stylesheet ){
- var
- blocks = stylesheet.cssRules || stylesheet.rules,
- i = 0, iLen;
- // for a strange Chrome error
- if ( blocks === NULL ){ return; }
- for ( iLen = blocks.length; i<iLen; i++ )
- {
- // imports must come first, so when we don't find one, return
- if ( blocks[i].type != 3 ){ return; }
- // add the stylesheet
- addStyleSheet( blocks[i].styleSheet );
- }
- // no need to XHR stylesheets that only import other stylesheets
- if ( i === iLen &&
- stylesheet.href )
- {
- __ignored_css.push( stylesheet.href.replace( REGEXP_FILE, CAPTURE ) );
- }
- };
- }
- // IE (old)
- else
- {
- findImportedStylesheets = function( stylesheet ){
- var imports = stylesheet.imports,
- i = 0, iLen = imports.length;
- for ( ; i<iLen; i++ )
- {
- // add the stylesheet
- addStyleSheet( imports[i] );
- }
- };
- }
- findImportedStylesheets( stylesheet );
- }
- function addStyleSheet( stylesheet )
- {
- var href = stylesheet.href;
- // skip if disabled
- if ( stylesheet.disabled ||
- ( href &&
- // or foreign
- ( determinePath( stylesheet ).indexOf( __location ) == -1 ||
- // or ignored
- in_object( href.replace( REGEXP_FILE, CAPTURE ), __ignored_css ) ) ) ){ return; }
- // does it have imports?
- findImportedStylesheets( stylesheet );
- // push the current stylesheet to the collection
- __stylesheets.push( stylesheet );
- }
- function getSortedArray( styles )
- {
- var arr = [], temp, selector;
- for ( selector in styles )
- {
- // fix for tainated Object
- if ( ! isInheritedProperty( styles, selector ) )
- {
- // continue
- temp = styles[selector];
- temp[SELECTOR] = selector;
- temp[SPECIFICITY] = getSpecificity( selector );
- arr.push( temp );
- }
- }
- arr.sort( sortBySpecificity );
- return arr;
- }
- function sortBySpecificity( a, b )
- {
- var x = a[SPECIFICITY], y = b[SPECIFICITY];
- return ( ( x < y ) ? -1 : ( ( x > y ) ? 1 : 0 ) );
- }
- function getSpecificity( selector )
- {
- var s = 0, matches;
- // replace all child and adjascent sibling selectors
- selector = selector.replace( /\s*\+\s*|\s*\>\s*/, SPACE );
- // adjust :not() to simplify calculations (since it counts toward specificity, as do its contents)
- selector = selector.replace( /(:not)\((.*)\)/, '$1 $2' );
- // match id selectors (weight: 100)
- matches = selector.match( /#/ );
- if ( matches != NULL ) s += ( matches.length * 100 );
- selector = selector.replace( /#[\w-_]+/, EMPTY ); // remove (to keep the regexs simple)
- // match class, pseudo-class, and attribute selectors (weight: 10)
- matches = selector.match( /::|:|\.|\[.*?\]/ );
- if ( matches != NULL ) s += ( matches.length * 10 );
- selector = selector.replace( /(?:::|:|\.)[\w-_()]+|\[.*?\]/, EMPTY ); // remove
- // match element selectors (weight: 1) - they should be all that's left
- matches = trim( selector ) != EMPTY ? selector.split( SPACE ) : [];
- s += matches.length;
- return s;
- }
- function determinePath( stylesheet )
- {
- var
- // for determining if it's a fully-executed path
- REGEXP_URL = /\w+?\:\/\//,
- actual_path = stylesheet.actual_path,
- css_path = actual_path || stylesheet.href,
- parent = stylesheet.parentStyleSheet,
- parent_path = EMPTY,
- prefix = EMPTY,
- full_url = FALSE,
- curr_path, path_last_slash, file_name;
- if ( ! css_path )
- {
- css_path = NULL;
- }
- else
- {
- full_url = css_path.match( REGEXP_URL );
- if ( is( full_url, ARRAY ) )
- {
- full_url = ( full_url.length > 0 );
- }
- }
- // we only want sheets
- if ( ! actual_path && // that don't already have a path
- ! full_url ) // that don't have a full URL
- {
- if ( css_path.indexOf( SLASH ) === 0 ) { css_path = css_path.substring( 1 ); }
- curr_path = LOCATION.substring( 0, LOCATION.lastIndexOf( SLASH ) );
- path_last_slash = css_path.lastIndexOf( SLASH );
- file_name = css_path.substring( path_last_slash + 1 );
- // check for an owner
- if ( parent == NULL )
- {
- if ( defined( stylesheet.ownerNode ) &&
- defined( CSSImportRule ) &&
- is( stylesheet.ownerRule, CSSImportRule ) )
- {
- parent = stylesheet.ownerRule.parentStyleSheet;
- }
- }
- // still no parent, use the css path itself
- if ( parent == NULL )
- {
- prefix = curr_path + SLASH + css_path.substring( 0, path_last_slash );
- }
- // get the owner's path
- else
- {
- parent_path = determinePath( parent );
- prefix = parent_path.substring( 0, parent_path.lastIndexOf( SLASH ) );
- }
- css_path = prefix + SLASH + file_name;
- }
- stylesheet.actual_path = css_path;
- return css_path;
- }
- function determineMedia( stylesheet )
- {
- var media = stylesheet.media;
- // W3C compliant
- if ( ! is( media, STRING ) )
- {
- determineMedia = function( stylesheet ){
- var
- media = stylesheet.media,
- owner = stylesheet.ownerRule,
- mediaText = FALSE;
- if ( ! is( media, STRING ) )
- {
- // imported
- if ( owner != NULL )
- {
- // media assignment in the import
- mediaText = owner.media.mediaText;
- if ( ! mediaText )
- {
- // no media assignment... inherit
- mediaText = determineMedia( owner.parentStyleSheet );
- }
- }
- // media is defined
- else
- {
- mediaText = media.mediaText;
- }
- }
- // default = screen
- stylesheet.actual_media = mediaText ? mediaText : SCREEN;
- if ( is( stylesheet.actual_media, STRING ) )
- {
- stylesheet.actual_media = stylesheet.actual_media.split( REGEXP_COMMA );
- }
- return stylesheet.actual_media;
- };
- }
- // old school
- else
- {
- determineMedia = function( stylesheet ){
- var mediaText = stylesheet.media;
- // default = screen
- stylesheet.actual_media = mediaText ? mediaText : SCREEN;
- if ( is( stylesheet.actual_media, STRING ) )
- {
- stylesheet.actual_media = stylesheet.actual_media.split( REGEXP_COMMA );
- }
- return stylesheet.actual_media;
- };
- }
- return determineMedia( stylesheet );
- }
- function extractAtBlocks( css )
- {
- // extract @font-face
- css = extractFonts( css );
- // extract @page
- css = extractPages( css );
- // handle @media
- css = handleMediaGroups( css );
- // extract other @ rules
- css = extractOtherAtRules( css );
- // return the string
- return css;
- }
- function extractFonts( css )
- {
- var
- REGEXP_FONTS = /@font-face\s*?\{(.*?)\s*?\}/ig,
- match;
- while ( ( match = REGEXP_FONTS.exec( css ) ) != NULL )
- {
- eCSStender.fonts.push( gatherProperties( match[1] ) );
- }
- return css.replace( REGEXP_FONTS, EMPTY );
- }
- function extractPages( css )
- {
- // TODO: make pages media-aware
- var
- PAGES = 'pages', AT = '@',
- match, page, box, content, group, props, prop,
- /* Regex must match all of the following
- @page { ... }
- @page :left { ... }
- @page :right { ... }
- @page LandscapeTable { ... }
- @page CompanyLetterHead:first { ... }
- @page:first { ... }
- Plus margin boxes inside:
- @top-left-corner, @top-left, @top-center, @top-right, @top-right-corner,
- @bottom-left-corner, @bottom-left, @bottom-center, @bottom-right, @bottom-right-corner,
- @left-top, @left-middle, @left-bottom, @right-top, @right-middle, @right-bottom
- For example
- @page{margin:0;@top-left{content:title}padding:2px;} */
- REGEXP_PAGES = /@page\s*?([\w:]*){0,1}\{\s*?((?:@[\w-]+\{[^\}]*\}|[\w-]+:[^;]+;)*)\s*?\}/ig;
- while ( ( match = REGEXP_PAGES.exec( css ) ) != NULL )
- {
- page = match[1];
- if ( ! defined( page ) || page == EMPTY )
- {
- page = ALL;
- }
- else if ( page.indexOf(COLON) == 0 )
- {
- page = page.replace( COLON, EMPTY );
- }
- content = match[2];
- if ( ! defined( eCSStender[PAGES][page] ) )
- {
- eCSStender[PAGES][page] = {};
- }
- // Margin boxes
- while ( ( box = REGEXP_ATRULE.exec( content ) ) != NULL )
- {
- group = box[1];
- props = gatherProperties( box[3] );
- if ( ! defined( eCSStender[PAGES][page][AT] ) )
- {
- eCSStender[PAGES][page][AT] = {};
- }
- if ( ! defined( eCSStender[PAGES][page][AT][group] ) )
- {
- eCSStender[PAGES][page][AT][group] = props;
- }
- else
- {
- for ( prop in props )
- {
- if ( ! isInheritedProperty( props, prop ) )
- {
- eCSStender[PAGES][page][AT][group][prop] = props[prop];
- }
- }
- }
- content = content.replace( box[0], EMPTY );
- }
- // properties
- props = gatherProperties( content );
- for ( prop in props )
- {
- if ( ! isInheritedProperty( props, prop ) )
- {
- eCSStender[PAGES][page][prop] = props[prop];
- }
- }
- }
- return css.replace( REGEXP_PAGES, EMPTY );
- }
- function handleMediaGroups( css )
- {
- // TODO: @media can contain @page, not just declaration blocks.
- var
- REGEXP_MEDIA = /@media\s*(.*?)\s*\{(.*?})\}/ig,
- match, media, m, mLen, styles, id = 0;
- while ( ( match = REGEXP_MEDIA.exec( css ) ) != NULL )
- {
- css = collapseAtMedia( css, match, id );
- id++;
- }
- return css;
- }
- function extractOtherAtRules( css )
- {
- var
- match, group, keys, k, props, prop;
- while ( ( match = REGEXP_ATRULE.exec( css ) ) != NULL )
- {
- group = match[1];
- keys = trim( match[2] );
- keys = ( keys == EMPTY ) ? FALSE : keys.split( REGEXP_COMMA );
- props = gatherProperties( match[3] );
- if ( ! defined( eCSStender.at[group] ) )
- {
- eCSStender.at[group] = ! keys ? addPush( [] ) : {};
- }
- if ( ! keys )
- {
- eCSStender.at[group].push( props );
- }
- else
- {
- k = keys.length;
- while ( k-- )
- {
- if ( ! defined( eCSStender.at[group][keys[k]] ) )
- {
- eCSStender.at[group][keys[k]] = props;
- }
- else
- {
- for ( prop in props )
- {
- if ( ! isInheritedProperty( props, prop ) )
- {
- eCSStender.at[group][keys[k]][prop] = props[prop];
- }
- }
- }
- }
- }
- }
- return css.replace( REGEXP_ATRULE, EMPTY );
- }
- function collapseAtMedia( css, match, id )
- {
- var
- media = match[1].split(REGEXP_COMMA),
- styles = match[2];
- createMediaContainers( media );
- __media_groups[id] = {
- media: media,
- styles: styles
- };
- return css.replace( match[0], PH_ATMEDIA + '{id:' + id + CLOSE_CURLY );
- }
- function expandAtMedia( id )
- {
- var media_group = __media_groups[id];
- extractStyleBlocks( media_group.media, media_group.styles );
- __media_groups[id] = NULL;
- }
- function extractStyleBlocks( media, css, delayed_id )
- {
- media = arrayify(media);
- // parse it into blocks & remove the last item (which is empty)
- var blocks = css.split(CLOSE_CURLY),
- b=0, m=0, a=0, bLen, mLen = media.length,
- props, prop, selector, medium, arr, aLen;
- blocks.pop();
- // loop
- for ( bLen=blocks.length; b<bLen; b++ )
- {
- // separate the selector and the properties
- blocks[b] = blocks[b].split(OPEN_CURLY);
- // gather the properties
- props = gatherProperties( blocks[b][1] );
- // build the selectors (which are part of the master object)
- selector = blocks[b][0];
-
- // single selector
- if ( selector.indexOf( PH_ATMEDIA ) != -1 )
- {
- expandAtMedia( props.id );
- }
- else
- {
- arr = selector.split(REGEXP_COMMA);
- for ( a=0, aLen=arr.length; a<aLen; a++ )
- {
- selector = trim( arr[a] );
- for ( m=0; m<mLen; m++ )
- {
- medium = media[m];
- // normal run
- if ( ! defined( delayed_id ) )
- {
- if ( ! defined( __style_objects[medium][selector] ) )
- {
- __style_objects[medium][selector] = {};
- }
- for ( prop in props )
- {
- if ( ! isInheritedProperty( props, prop ) )
- {
- __style_objects[medium][selector][prop] = props[prop];
- }
- }
- }
- // delayed run
- else
- {
- if ( ! defined( __delayed[delayed_id][selector] ) )
- {
- __delayed[delayed_id][selector] = {};
- }
- for ( prop in props )
- {
- if ( ! isInheritedProperty( props, prop ) )
- {
- __delayed[delayed_id][selector][prop] = props[prop];
- }
- }
- }
- }
- }
- }
- }
- }
- function gatherProperties( properties )
- {
- if ( ! is( properties, STRING ) ){ return {}; }
- properties = properties.split(SEMICOLON);
- var props = {},
- p = 0, pLen = properties.length,
- property, arr, prop, val;
- for ( ; p<pLen; p++ )
- {
- property = trim( properties[p] );
- // skip empties
- if ( property == EMPTY ){ continue; }
- arr = property.split(REGEXP_P_V);
- prop = arr.shift();
- val = arr.join(COLON);
- props[trim(prop)] = trim( val );
- }
- return props;
- }
- function determineProperties( lookup, requested_properties )
- {
- var properties = [], property, fragment, prefix, i, iLen;
- // properties is set
- if ( ! is_false( requested_properties ) )
- {
- // user doesn't want everything
- if ( requested_properties != STAR )
- {
- // gather requested properties
- if ( is( requested_properties, STRING ) )
- {
- properties.push( requested_properties );
- }
- else if ( is( requested_properties, ARRAY ) )
- {
- for ( i=0, iLen=requested_properties.length; i<iLen; i++ )
- {
- properties.push( requested_properties[i] );
- }
- }
- }
- else
- {
- properties = requested_properties;
- }
- }
- // now for the remainder
- if ( requested_properties != STAR )
- {
- // retrieve properties that were explicitly looked up
- property = lookup[PROPERTY];
- fragment = lookup[FRAGMENT];
- prefix = lookup[PREFIX];
- if ( defined( property ) )
- {
- if ( is( property, STRING ) )
- {
- properties.push( property );
- }
- else if ( is( property, ARRAY ) )
- {
- for ( i=0, iLen=property.length; i<iLen; i++ )
- {
- properties.push( property[i] );
- }
- }
- }
- // retrieve fragment matches
- else if ( defined( fragment ) )
- {
- properties.push( newRegExp( ANYTHING + fragment + ANYTHING ) );
- }
- // retrieve prefix matches
- else if ( defined( prefix ) )
- {
- properties.push( newRegExp( HYPHEN + prefix + HYPHEN_ANYTHING ) );
- }
- }
- return properties;
- }
- function extractProperties( medium, selector, requested_properties )
- {
- var requested_property, property, properties = {}, p = 0, pLen,
- style_rule = __style_objects[medium][selector];
- // grab the requested properties
- if ( is( requested_properties, ARRAY ) )
- {
- for ( pLen=requested_properties.length; p<pLen; p++ )
- {
- requested_property = requested_properties[p];
- if ( is( requested_property, REGEXP ) )
- {
- for ( property in style_rule )
- {
- if ( ! isInheritedProperty( style_rule, property ) && // fix for tainted Object
- ! in_object( property, __ignored_props ) &&
- property.match( requested_property ) != NULL )
- {
- properties[property] = style_rule[property];
- }
- }
- }
- else if ( is( requested_property, STRING ) &&
- defined( style_rule[requested_property] ) )
- {
- properties[requested_property] = style_rule[requested_property];
- }
- }
- }
- // all properties (*)
- else
- {
- for ( property in style_rule )
- {
- if ( ! isInheritedProperty( style_rule, property ) &&
- ! in_object( property, __ignored_props ) )
- {
- properties[property] = style_rule[property];
- }
- }
- }
- return properties;
- }
- function arrayify( something )
- {
- var arr=addPush([]), i=0, iLen, temp, t, tLen;
- if ( ! is( something, ARRAY ) )
- {
- if ( is( something, OBJECT ) &&
- ! is( something, REGEXP ) )
- {
- for ( i in something )
- {
- if ( ! isInheritedProperty( something, i ) )
- {
- arr.push( something[i] );
- }
- }
- }
- else if ( is( something, STRING ) &&
- something.indexOf(',') != -1 )
- {
- temp = something.split( REGEXP_COMMA );
- for ( iLen=temp.length; i<iLen; i++ )
- {
- arr.push( temp[i] );
- }
- }
- else
- {
- arr = [ something ];
- }
- }
- else
- {
- for ( iLen=something.length; i<iLen; i++ )
- {
- if ( is( something[i], STRING ) &&
- something[i].indexOf(',') != -1 )
- {
- temp = something[i].split( REGEXP_COMMA );
- for ( t=0, tLen=temp.length; t<tLen; t++ )
- {
- arr.push( temp[t] );
- }
- }
- else
- {
- arr.push( something[i] );
- }
- }
- }
- return arr;
- }
- function createMediaContainers( media )
- {
- if ( ! is( media, ARRAY ) )
- {
- media = ( media + EMPTY ).split( REGEXP_COMMA );
- }
- for ( var m=0, mLen=media.length; m<mLen; m++ )
- {
- if ( ! defined( __style_objects[media[m]] ) )
- {
- __style_objects[media[m]] = {};
- }
- }
- }
- function selectorMatches( selector, test )
- {
- var useless = /\*(?!\s|>|\+)/g;
- return ( ( is( test, REGEXP ) &&
- selector.match( test ) != NULL ) ||
- ( is( test, FUNCTION ) &&
- test.call( selector ) === TRUE ) ||
- ( is( test, STRING ) &&
- selector.indexOf( trim( test.replace( useless, EMPTY ) ) ) != -1 ) );
- }
- function filtersMatched( properties, filters )
- {
- var count, required_count, prop, filter;
- for ( prop in properties )
- {
- if ( ! isInheritedProperty( properties, prop ) &&
- ! in_object( prop, __ignored_props ) )
- {
- count = required_count = 0;
- for ( filter in filters )
- {
- if ( ! isInheritedProperty( filters, filter ) )
- {
- required_count++;
- if ( filter == PROPERTY )
- {
- if ( prop.match( filters[filter] ) ){ count++; }
- }
- else if ( filter == 'value' )
- {
- if ( properties[prop].match( filters[filter] ) ){ count++; }
- }
- }
- }
- }
- if ( count == required_count ){ return TRUE; }
- }
- return FALSE;
- }
- function clean( css )
- {
- var
- // IE returns all uppercase tags and property names (except on XHR)
- // low_function = low,
- // lowercase = /(?:\s?([^.#:]+).*?[,{]|\s?([^:]+):)/ig,
- html_comments = /\s*(?:\<\!--|--\>)\s*/g, // strip HTML comments
- css_comments = /\/\*(?:.|\s)*?\*\//g, // strip CSS comments
- // remove returns and indenting whitespace (not not spaces before pseudo-element & pseudo-class selectors)
- whitespace = /\s*([,{};]|:(?!nth|first|last|only|empty|checked|(dis|en)abled))\s*/g,
- at_imports = /@import.*?;/g; // axe imports
- return css.replace( html_comments, EMPTY )
- .replace( css_comments, EMPTY )
- .replace( whitespace, CAPTURE )
- .replace( at_imports, EMPTY );
- // removed with removal of IE's cssText
- // .replace( lowercase, low_function );
- }
- function in_object( needle, haystack )
- {
- for ( var key in haystack )
- {
- if ( haystack[key] == needle ){ return TRUE; }
- }
- return FALSE;
- }
- function now()
- {
- return new Date().getTime();
- }
- function is( obj, test )
- {
- var r = FALSE;
- try
- {
- r = obj instanceof test;
- }
- catch ( e )
- {
- r = ( typeof( test ) == STRING &&
- typeof( obj ) == test );
- }
- return r;
- }
- function is_false( a )
- {
- return a === FALSE;
- }
- function defined( a )
- {
- return a != UNDEFINED;
- }
- function charAt( str )
- {
- return String.fromCharCode( str );
- }
- function getCSSFiles()
- {
- if ( __xhr )
- {
- getCSSFiles = function()
- {
- var stylesheet, file, css, status;
- if ( stylesheet = __stylesheets[__s] )
- {
- if ( file = stylesheet.actual_path )
- {
- if ( file === NULL ||
- in_object( file.replace( REGEXP_FILE, CAPTURE ), __ignored_css ) )
- {
- __s++;
- getCSSFiles();
- }
- else
- {
- __xhr = new XHR();
- __xhr.onreadystatechange = xhrHandler;
- __xhr.open( 'GET', file, FALSE );
- __xhr.send( NULL );
- try {
- if ( __xhr.onreadystatechange != xhrHandler )
- {
- __xhr.onreadystatechange = xhrHandler();
- }
- } catch ( e ) { }
- }
- }
- else
- {
- readCSS( extract( stylesheet ), stylesheet.actual_media );
- __s++;
- getCSSFiles();
- }
- }
- else
- {
- wrapUp();
- }
- };
- getCSSFiles();
- }
- else
- {
- for ( var i=0, iLen=__stylesheets; i<iLen; i++ )
- {
- if ( ! in_object( __stylesheets[i].actual_path.replace( REGEXP_FILE, CAPTURE ), __ignored_css ) )
- {
- readCSS( __stylesheets[i].cssText, __stylesheets[i].actual_media );
- }
- }
- }
- }
- function xhrHandler( e )
- {
- if ( __xhr.readyState == 4 )
- {
- var status = __xhr.status;
- if ( status == 0 || // local
- ( status >= 200 && status < 300 ) || // good
- status == 304 ) // cached
- {
- readCSS( __xhr.responseText, __stylesheets[__s].actual_media );
- __modified[fingerprint( __stylesheets[__s].actual_path )] = __xhr.getResponseHeader('Last-Modified');
- }
- __s++;
- getCSSFiles();
- }
- }
- function readCSS( css, media )
- {
- css = clean( css );
- css = extractAtBlocks( css );
- // handle remaining rules
- extractStyleBlocks( media, css );
- }
- function extract( stylesheet )
- {
- var r;
- try {
- r = stylesheet.ownerNode.innerHTML;
- extract = function( stylesheet )
- {
- return stylesheet.ownerNode.innerHTML;
- };
- }
- catch ( e )
- {
- r = stylesheet.owningElement.innerHTML;
- extract = function( stylesheet )
- {
- return stylesheet.owningElement.innerHTML;
- };
- }
- return r;
- }
- function low( w )
- {
- return is( w, STRING ) ? w.toLowerCase() : w;
- }
- function camelize( str )
- {
- var
- bits = str.split(HYPHEN), len = bits.length, new_str, i = 1;
- if ( len == 1 ) { return bits[0]; }
- if ( str.charAt(0) == HYPHEN ) {
- new_str = bits[0].charAt(0).toUpperCase() + bits[0].substring(1);
- } else {
- new_str = bits[0];
- }
- while ( i < len ) {
- new_str += bits[i].charAt(0).toUpperCase() + bits[i].substring(1);
- i++;
- }
- return new_str;
- }
- function zero_out( str )
- {
- if ( is( str, STRING ) )
- {
- str = str.replace( /(\s0)px/g, CAPTURE );
- }
- return str;
- }
- function addInlineStyle( el, property, value )
- {
- try {
- el.style[property] = value;
- el.style[camelize( property )] = value;
- } catch( e ){
- return FALSE;
- }
- return TRUE;
- }
- function XHR()
- {
- var connection;
- try { connection = new XMLHttpRequest(); }
- catch( e ){
- try { connection = new ActiveXObject('Msxml2.XMLHTTP'); }
- catch( e ){
- try { connection = new ActiveXObject('Microsoft.XMLHTTP'); }
- catch( e ){
- connection = FALSE;
- }
- }
- }
- return ( ! connection ) ? NULL : connection;
- }
- function newElement( el )
- {
- return DOCUMENT.createElement( el );
- }
- function newRegExp( rxp )
- {
- return new RegExp( rxp );
- }
- function makeClassRegExp( the_class )
- {
- return newRegExp( '(\\s|^)' + the_class + '(\\s|$)' );
- }
- // push handling
- function addPush( arr )
- {
- return arr;
- }
- if ( Array.prototype.push == NULL )
- {
- var push = function( obj )
- {
- this[this.length] = obj;
- return this.length;
- };
- eCSStender.fonts.push = __eCSStensions.push = __stylesheets.push = __embedded_css.push = __on_complete.push = push;
- addPush = function( arr )
- {
- if ( typeof( arr ) == ARRAY )
- {
- arr.push = push;
- }
- return arr;
- };
- }
- // expando handling
- if ( defined( __expando ) )
- {
- toggleExpando = function()
- {
- if ( ! defined( DOCUMENT.old_expando ) ||
- DOCUMENT.old_expando == NULL )
- {
- DOCUMENT.old_expando = DOCUMENT.expando;
- DOCUMENT.expando = FALSE;
- }
- else
- {
- DOCUMENT.expando = DOCUMENT.old_expando;
- DOCUMENT.old_expando = NULL;
- }
- };
- }
-
- /*-------------------------------------*
- * Delayed Writing
- *-------------------------------------*/
- function writeStyleSheets()
- {
- var id, style, styles, selector;
- for ( id in __delayed )
- {
- if ( ! isInheritedProperty( __delayed, id ) )
- {
- style = DOCUMENT.getElementById( id );
- styles = '';
- for ( selector in __delayed[id] )
- {
- if ( ! isInheritedProperty( __delayed, id ) )
- {
- styles += selector + OPEN_CURLY + styleObjToString( __delayed[id][selector], selector ) + CLOSE_CURLY;
- }
- }
- addRules( style, styles );
- }
- }
- }
- __on_complete.push( writeStyleSheets );
-
- /*-------------------------------------*
- * Caching
- *-------------------------------------*/
- function enableCache()
- {
- // HTML5 and/or Mozilla
- if ( defined( WINDOW.localStorage ) )
- {
- __cache_object = WINDOW.localStorage;
- clearBrowserCache = function()
- {
- var i = __cache_object.length, key;
- // cherry-pick only our own items in the cache
- while ( i-- )
- {
- key = __cache_object.key(i);
- if ( key &&
- key.indexOf( ECSSTENDER ) === 0 )
- {
- delete( __cache_object[key] );
- }
- }
- };
- readFromBrowserCache = function( cache, key )
- {
- // make sure our cached objects are prefixed
- if ( cache != ECSSTENDER )
- {
- cache = ECSSTENDER + HYPHEN + cache;
- }
- return __cache_object.getItem( cache + HYPHEN + key );
- };
- writeToBrowserCache = function( cache, key, value )
- {
- // make sure our cached objects are prefixed
- if ( cache != ECSSTENDER )
- {
- cache = ECSSTENDER + HYPHEN + cache;
- }
- __cache_object.setItem( cache + HYPHEN + key, value );
- };
- }
- // IE (old school)
- else
- {
- var
- div = newElement(DIV),
- tomorrow = new Date();
- div.style.behavior = 'url(#default#userData)';
- __body.appendChild(div);
- if ( defined( div.XMLDocument ) )
- {
- __cache_object = div;
- __cache_object.load( ECSSTENDER );
- // set the expiration for 1 week
- tomorrow.setMinutes( tomorrow.getMinutes() + 10080 );
- tomorrow = tomorrow.toUTCString();
- __cache_object.expires = tomorrow;
- clearBrowserCache = function()
- {
- var
- attr = __cache_object.XMLDocument.firstChild.attributes,
- i = attr.length;
- while ( i-- )
- {
- __cache_object.removeAttribute( attr[i].nodeName );
- }
- __cache_object.save( ECSSTENDER );
- };
- readFromBrowserCache = function( cache, key )
- {
- return __cache_object.getAttribute( cache + HYPHEN + key );
- };
- writeToBrowserCache = function( cache, key, value )
- {
- __cache_object.setAttribute( cache + HYPHEN + key, value );
- __cache_object.save( ECSSTENDER );
- };
- }
- }
- }
- function readBrowserCache()
- {
- if ( __no_cache || __local ){ return; }
- enableCache();
- var cache_group, item, count,
- version = 'version',
- cache_version = readFromBrowserCache( ECSSTENDER, version );
- // only use the cache if it was created from the same version of eCSStender
- // this allows us to tweak the cache going forward
- if ( cache_version == eCSStender[version] )
- {
- for ( cache_group in __local_cache )
- {
- if ( ! isInheritedProperty( __local_cache, cache_group ) &&
- defined( cache_group ) )
- {
- count = readFromBrowserCache( ECSSTENDER, cache_group + COUNT );
- if ( defined( count ) )
- {
- if ( cache_group == EXTENSION )
- {
- __t_count = count;
- if ( count < 1 ){ eCSStender.cache = FALSE; }
- }
- while ( count >= 0 )
- {
- item = readFromBrowserCache( cache_group, count );
- if ( item != NULL )
- {
- if ( cache_group == EXTENSION )
- {
- __local_cache[cache_group][EXTENSION+count] = item;
- }
- else
- {
- item = item.split(PIPES);
- if ( item[1] == 'true' ){ item[1] = TRUE; }
- if ( item[1] == 'false' ){ item[1] = FALSE; }
- __local_cache[cache_group][item[0]] = item[1];
- }
- }
- count--;
- }
- }
- }
- }
- }
- clearBrowserCache();
- }
- function writeBrowserCache()
- {
- if ( __no_cache || __local ){ return; }
- var cache_group, key, count, extension;
- for ( cache_group in __local_cache )
- {
- if ( ! isInheritedProperty( __local_cache, cache_group ) &&
- defined( cache_group ) )
- {
- count = 0;
- for ( key in __local_cache[cache_group] )
- {
- if ( ! isInheritedProperty( __local_cache[cache_group], key ) &&
- defined( cache_group ) )
- {
- if ( cache_group == EXTENSION )
- {
- extension = __local_cache[cache_group][key];
- extension[PROCESSED] = [];
- writeToBrowserCache( cache_group, count, extension );
- }
- else
- {
- writeToBrowserCache( cache_group, count, key + PIPES + __local_cache[cache_group][key] );
- }
- count++;
- }
- }
- writeToBrowserCache( ECSSTENDER, cache_group + COUNT, count );
- }
- }
- writeToBrowserCache( ECSSTENDER, 'version', eCSStender.version );
- __cached_out = TRUE;
- }
- function styleObjToString( obj )
- {
- var str = EMPTY, key;
- for ( key in obj )
- {
- if ( ! isInheritedProperty( obj, key ) )
- {
- str += key + COLON + obj[key] + SEMICOLON;
- }
- }
- return str;
- }
- function stringToStyleObj( str )
- {
- var matches, obj = FALSE;
- if ( ( matches = str.exec( /^\{(.*?)\}$/ ) ) != NULL )
- {
- obj = gatherProperties( matches[1] );
- }
- return obj;
- }
- function fingerprint( str )
- {
- // UTF8 encode
- str = str.replace(/\r\n/g,'\n');
- var
- keystr = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',
- i, iLen = str.length, newstr = EMPTY, c1, c2, c3, e1, e2, e3, e4;
- for ( i=0; i<iLen; i++ )
- {
- c1 = str.charCodeAt(i);
- if ( c1 < 128 )
- {
- newstr += charAt( c1 );
- }
- else if ( (c1 > 127) && (c1 < 2048) )
- {
- newstr += charAt( (c1 >> 6) | 192 );
- newstr += charAt( (c1 & 63) | 128 );
- }
- else
- {
- newstr += charAt( (c1 >> 12) | 224 );
- newstr += charAt( ((c1 >> 6) & 63) | 128 );
- newstr += charAt( (c1 & 63) | 128 );
- }
- }
- str = newstr;
- newstr = EMPTY;
- // base64
- i = 0;
- iLen = str.length;
- while ( i < iLen )
- {
- c1 = str.charCodeAt(i++);
- c2 = str.charCodeAt(i++);
- c3 = str.charCodeAt(i++);
-
- e1 = c1 >> 2;
- e2 = ((c1 & 3) << 4) | (c2 >> 4);
- e3 = ((c2 & 15) << 2) | (c3 >> 6);
- e4 = c3 & 63;
- if ( isNaN(c2) )
- {
- e3 = e4 = 64;
- }
- else if ( isNaN(c3) )
- {
- e4 = 64;
- }
- newstr += keystr.charAt(e1) + keystr.charAt(e2) +
- keystr.charAt(e3) + keystr.charAt(e4);
- }
- return newstr;
- }
- function writeToLocalCache( group, key, value, encode )
- {
- encode = ! defined( encode ) ? TRUE : encode;
- if ( ! is_false( encode ) ){
- key = fingerprint(key);
- }
- __local_cache[group][key] = value;
- if ( __cached_out )
- {
- writeToBrowserCache( group, key, value );
- }
- }
- function readFromLocalCache( group, key, encode )
- {
- encode = ! defined( encode ) ? TRUE : encode;
- if ( ! is_false( encode ) ){
- key = fingerprint(key);
- }
- var value = __local_cache[group][key];
- return ! defined( value ) ? UNDEFINED : value;
- }
- /*-------------------------------------*
- * Public Methods *
- *-------------------------------------*/
- /**
- * eCSStender::register()
- * registers an extension
- *
- * @param obj keys - define the lookup; supports the following properties:
- * * Mutually exclusive lookup methods:
- * * 'fragment' (str) - a portion of the property to look up
- * * 'prefix' (str) - to lookup by vendor-specific prefix
- * * 'property' (mixed)
- * * to lookup by property, use a string
- * * to lookup by multiple, use an array of strings
- * * 'selector' (mixed) - to find by selector; accepts
- * * compound selectors in a string, separated by commas
- * * a RegExp to match
- * * an array of selector strings or RegExp objects to match
- * * 'filter' (obj) - allows you to filter the lookup results by property name or value
- * * 'property' (mixed) - string or regex to match for the extension to apply
- * * 'value' (mixed) - string or regex to match for the extension to apply
- * * 'media' (str) - restricts the media to which you want to
- * restrict the extension
- * * 'test' (fn) - a test function to run that will determine
- * whether or not the extension should run; should return
- * TRUE if the extension SHOULD run, FALSE if it SHOULD NOT.
- * * 'fingerprint' (str) - a unique ID for the extension (not required)
- * @param mixed properties - the properties you want back; supports for:
- * * FALSE - returns only the looked-up property or properties with
- * the given fragment or prefix
- * * '*' (str) - returns all properties of the selected elements
- * * single property (str) - returns the supplied property
- * * multiple properties (arr) - returns the requested properties
- * @param fn callback - the function to be called when the extension
- * finds a subject
- */
- eCSStender.register = function( keys, properties, callback )
- {
- var eCSStension = {}, lookups, l, temp, t, props=[], key, id=EMPTY;
- // set the lookup type
- if ( defined( keys[SELECTOR] ) )
- {
- eCSStension[FIND_BY] = SELECTOR;
- eCSStension[LOOKUP] = keys[SELECTOR];
- }
- else if ( defined( keys[PROPERTY] ) )
- {
- eCSStension[FIND_BY] = PROPERTY;
- eCSStension[LOOKUP] = keys[PROPERTY];
- }
- else if ( defined( keys[FRAGMENT] ) )
- {
- eCSStension[FIND_BY] = FRAGMENT;
- eCSStension[LOOKUP] = keys[FRAGMENT];
- }
- else if ( defined( keys[PREFIX] ) )
- {
- eCSStension[FIND_BY] = PREFIX;
- eCSStension[LOOKUP] = keys[PREFIX];
- }
-
- // convert some lookups to arrays to simplify things later on
- if ( eCSStension[FIND_BY] == SELECTOR ||
- eCSStension[FIND_BY] == PROPERTY )
- {
- eCSStension[LOOKUP] = arrayify( eCSStension[LOOKUP] );
- }
- // filter?
- if ( defined( keys[FILTER] ) )
- {
- eCSStension[FILTER] = keys[FILTER];
- }
-
- // media restriction?
- if ( defined( keys[MEDIA] ) )
- {
- eCSStension[MEDIA] = keys[MEDIA];
- }
-
- // test first?
- if ( defined( keys[TEST] ) )
- {
- eCSStension[TEST] = keys[TEST];
- }
-
- // set the properties to capture
- eCSStension[PROPERTIES] = determineProperties( keys, properties );
-
- // create the fingerprint
- if ( ! defined( keys[FINGERPRINT] ) )
- {
- for ( key in eCSStension )
- {
- if ( ! isInheritedProperty( eCSStension, key ) )
- {
- id += key + COLON + eCSStension[key].toString() + SEMICOLON;
- }
- }
- id = fingerprint(id+'::'+__e_count);
- }
- else
- {
- id = keys[FINGERPRINT];
- }
- // set the callback
- eCSStension[CALLBACK] = callback;
- // create the processed array
- eCSStension[PROCESSED] = [];
- // save the extension
- __eCSStensions[id] = eCSStension;
- __e_count++;
- };
- /**
- * eCSStender::lookup()
- * looks up and returns styles based on the supplied info
- *
- * @param obj lookup - define the lookup; supports the following properties:
- * * Mutually exclusive lookup methods:
- * * FRAGMENT (str) - a portion of the property to look up
- * * PREFIX (str) - to lookup by vendor-specific prefix
- * * PROPERTY (mixed)
- * * to lookup by property, use a string
- * * to lookup by multiple, use an array of strings
- * * SELECTOR (mixed) - to find by selector; accepts
- * * compound selectors in a string, separated by commas
- * * a RegExp to match
- * * an array of selector strings or RegExp objects to match
- * * a function that returns TRUE for a positive match
- * * MEDIA (str) - restricts the media within which you want to search
- * * SPECIFICITY (mixed) - the desired specificity parameters
- * * if an integer, implies maximum specificity
- * * if an object, use keys to set the thresholds:
- * * 'max' (int) - maximum specificity to match
- * * 'min' (int) - minimum specificity to match
- * @param mixed properties - the properties you want back; support for:
- * * FALSE - returns only the looked-up property or properties with
- * the given fragment or prefix
- * * '*' (str) - returns all properties of the selected elements
- * * single property (str) - returns the supplied property
- * * multiple properties (arr) - returns the requested properties
- *
- * @return arr of style objects, each with the following keys:
- * * 'medium' - the medium of the match
- * * PROPERTIES - the properties requested
- * * SELECTOR - the selector matched
- * * SPECIFICITY - the specificity of the selector
- */
- eCSStender.lookup = function( lookup, properties )
- {
- var
- l_specificity = lookup[SPECIFICITY],
- l_selector = lookup[SELECTOR],
- l_property = lookup[PROPERTY],
- l_fragment = lookup[FRAGMENT],
- l_prefix = lookup[PREFIX],
- l_media = lookup[MEDIA],
- props, property,
- min, max,
- medium, e_media,
- sLoop, styles, sorted_styles,
- s, sLen, selector, block, found,
- i, iLen, test, matches = [];
- // figure out specificity params
- if ( defined( l_specificity ) )
- {
- if ( is( l_specificity, NUMBER ) )
- {
- max = l_specificity;
- min = 0;
- }
- else if ( is( l_specificity, OBJECT ) )
- {
- max = l_specificity['max'];
- min = l_specificity['min'];
- }
- }
- // make the selector setup consistent
- if ( defined( l_selector ) )
- {
- l_selector = arrayify( l_selector );
- }
- else if ( defined( l_property ) )
- {
- l_property = arrayify( l_property );
- }
- // figure out properties to return
- props = determineProperties( lookup, properties );
- // loop
- for ( medium in __style_objects )
- {
- // safety for users who are using Prototype or any code that extends Object
- if ( ! isInheritedProperty( __style_objects, medium ) )
- {
- // verify any media restrictions
- if ( defined( l_media ) &&
- l_media != ALL )
- {
- e_media = l_media.split(REGEXP_COMMA);
- if ( medium != ALL &&
- ! in_object( medium, e_media ) )
- {
- continue;
- }
- }
- // start the processing in earnest
- styles = __style_objects[medium];
- sorted_styles = getSortedArray( styles );
- sLoop:
- for ( s=0, sLen=sorted_styles.length; s<sLen; s++ )
- {
- // check the selector
- selector = sorted_styles[s][SELECTOR];
- block = styles[selector];
- if ( defined( l_selector ) )
- {
- found = FALSE;
- for ( i=0, iLen=l_selector.length; i<iLen; i++ )
- {
- if ( selectorMatches( selector, l_selector[i] ) )
- {
- found = TRUE;
- break;
- }
- }
- if ( is_false( found ) )
- {
- continue;
- }
- }
- // check properties
- else if ( defined( l_property ) )
- {
- found = FALSE;
- for ( i=0, iLen=l_property.length; i<iLen; i++ )
- {
- if ( defined( block[l_property[i]] ) )
- {
- found = TRUE;
- break;
- }
- }
- if ( is_false( found ) )
- {
- continue;
- }
- }
- // check fragments, and/or prefixes
- else if ( defined( l_fragment ) ||
- defined( l_prefix ) )
- {
- found = FALSE;
- test = ( defined( l_fragment ) ) ? ANYTHING + l_fragment + ANYTHING
- : HYPHEN + l_prefix + HYPHEN_ANYTHING;
- test = newRegExp( test );
- for ( property in block )
- {
- if ( ! isInheritedProperty( styles, selector ) && // fix for tainted Object
- ! in_object( property, __ignored_props ) &&
- property.match( test ) )
- {
- found = TRUE;
- break;
- }
- }
- if ( is_false( found ) )
- {
- continue;
- }
- }
- // check the specificity
- if ( defined( l_specificity ) )
- {
- if ( block[SPECIFICITY] < min ||
- block[SPECIFICITY] > max )
- {
- continue;
- }
- }
- // if you made it this far, you passed the tests
- matches.push({
- medium: medium,
- properties: extractProperties( medium, selector, props ),
- selector: selector,
- specificity: block[SPECIFICITY]
- });
- } // end styles loop
- }
- } // end medium loop
-
- // back what we found
- return matches;
- };
- /**
- * eCSStender::addMethod()
- * sets a custom JavaScript method in eCSStender's methods object
- *
- * @param str name - a name for the method
- * @param func the_function - the function to store
- */
- eCSStender.addMethod = function( name, the_function )
- {
- if ( ! defined( eCSStender.methods[name] ) )
- {
- eCSStender.methods[name] = the_function;
- }
- };
- /**
- * eCSStender::onComplete()
- * adds a function to be called on completion of eCSStender's run
- *
- * @param func the_function - the function to store
- */
- eCSStender.onComplete = function( the_function )
- {
- __on_complete.push( the_function );
- };
- /**
- * eCSStender::embedCSS()
- * embeds styles to the appropriate media
- *
- * @param str styles - the styles to embed
- * @param str media - the media to apply the stylesheet to (optional)
- * @param bool delay - whether or not to delay the writing of the stylesheet (default = true)
- *
- * @return obj - the STYLE element
- */
- eCSStender.embedCSS = function( styles, media, delay )
- {
- // determine the medium
- media = media || ALL;
- // determine whether to delay the write or not
- delay = defined( delay ) ? delay : TRUE;
- // determine the id
- var id = 'eCSStension-' + media, style;
- // find or create the embedded stylesheet
- if ( ! in_object( media, __embedded_css ) )
- {
- // make the new style element
- style = newStyleElement( media, id, delay );
- // store the medium
- __embedded_css.push( media );
- }
- else
- {
- style = DOCUMENT.getElementById( id );
- }
- // add the rules to the sheet
- if ( style != NULL )
- {
- if ( ! delay )
- {
- addRules( style, styles );
- }
- else
- {
- extractStyleBlocks( media, styles, id );
- }
- }
- // return the style element
- return style;
- };
- /**
- * eCSStender::newStyleElement()
- * adds a new stylesheet to the document
- *
- * @param str media - the media to apply the stylesheet to
- * @param str id - the id to give the stylesheet (optional)
- * @param bool delay - whether or not to delay the writing of the stylesheet (default = true)
- *
- * @return obj - the STYLE element
- */
- function newStyleElement( media, id, delay )
- {
- // clone the model style element
- var style = __style.cloneNode( TRUE );
- // set the media type & id
- media = media || ALL;
- style.setAttribute( MEDIA, media );
- id = id || 'temp-' + Math.round( Math.random() * 2 + 1 );
- style.setAttribute( 'id', id );
- // determine whether to delay the write or not
- delay = defined( delay ) ? delay : TRUE;
- if ( delay )
- {
- __delayed[id] = {};
- //style.disabled = TRUE;
- }
- __head.appendChild( style );
- // return the element reference
- return style;
- }
- eCSStender.newStyleElement = newStyleElement;
- /**
- * eCSStender::addRules()
- * adds rules to a specific stylesheet
- *
- * @param obj el - the stylesheet
- * @param str styles - the style rules to add
- */
- __style.setAttribute( TYPE, 'text/css' );
- if ( defined( __style.styleSheet ) )
- {
- addRules = function( el, styles )
- {
- el.styleSheet.cssText += styles;
- };
- }
- else
- {
- addRules = function( el, styles )
- {
- el.appendChild( DOCUMENT.createTextNode( styles ) );
- };
- }
- eCSStender.addRules = addRules;
- /**
- * eCSStender::isSupported()
- * tests support for properties and selectors
- *
- * Option 1: Selector test
- * eCSStender::isSupported( type, selector, html, el )
- * @param str type - 'property'
- * @param str selector - the selector
- * @param obj html - HTML to test against
- * @param obj el - the element the selector should select
- * @return bool - TRUE for success, FALSE for failure
- *
- * Option 2: Property Test (simple)
- * eCSStender::isSupported( type, test )
- * @param str type - 'selector'
- * @param str test - the property: value pair to test
- * @return bool - TRUE for success, FALSE for failure
- *
- * Option 3: Property Test (complex)
- * eCSStender::isSupported( type, property, value )
- * @param str type - 'selector'
- * @param str property - the property to test
- * @param mixed value - the string value or an array of possible values
- * @return bool - TRUE for success, FALSE for failure
- *
- * Option 3: Storage
- * eCSStender::isSupported( type, what, result )
- * @param str type - 'selector'
- * @param str what - the key to store
- * @param bool result - the result of the test you want stored
- * @return bool - the result you passed in
- */
- eCSStender.isSupported = function( type )
- {
- var result,
- arg = arguments,
- aLen = arg.length,
- // global test vars
- what = arg[1],
- value = arg[2] || NULL,
- html = value,
- el = arg[3] || NULL,
- // property test vars
- property, settable = TRUE, i,
- computed = WINDOW.getComputedStyle,
- VISIBILITY = 'visibility',
- HIDDEN = 'hidden',
- // selector test vars
- style;
- // check for cached value
- if ( defined( result = readFromLocalCache( type, what ) ) )
- {
- // we'll return the result at the end
- }
- // actual tests
- else
- {
- result = FALSE;
- // just caching the value for later
- if ( is( value, 'boolean' ) )
- {
- result = value;
- }
- // property test
- else if ( type == PROPERTY )
- {
- // test element
- el = newElement(DIV);
- // are property and value flowing in separately?
- if ( value )
- {
- property = what;
- value = arrayify( value );
- }
- else
- {
- what = what.split(REGEXP_P_V);
- property = what[0];
- value = [ trim( what[1] ) ];
- // reset what for the cache
- what = arg[1];
- }
- __body.appendChild( el );
- toggleExpando();
- if ( ! addInlineStyle( el, property, value[0] ) )
- {
- settable = FALSE;
- }
- toggleExpando();
- if ( settable )
- {
- i = value.length;
- while ( i-- &&
- ! result )
- {
- result = ( zero_out( getCSSValue( el, property ) ) == value[i] );
- }
- }
- // cleanup
- __body.removeChild( el );
- }
- // selector test
- else if ( type == SELECTOR )
- {
- // append the test markup (if it exists) and the test style element
- if ( html )
- {
- __body.appendChild( html );
- }
- style = newStyleElement( SCREEN, FALSE, FALSE );
- // if the browser doesn't support the selector, it should error out
- try {
- addRules( style, what + OPEN_CURLY + VISIBILITY + COLON + HIDDEN + SEMICOLON + CLOSE_CURLY );
- // if it succeeds, we don't want to run the eCSStension
- if ( getCSSValue( el, VISIBILITY ) == HIDDEN )
- {
- result = TRUE;
- }
- } catch( e ){}
- // cleanup
- if ( html )
- {
- __body.removeChild( html );
- }
- style.parentNode.removeChild( style );
- }
- // write it to the cache and clean up
- writeToLocalCache( type, what, result );
- value = html = el = style = NULL;
- }
- return result;
- };
- /**
- * eCSStender::applyWeightedStyle()
- * apply a weighted inline style (based on specificity)
- *
- * @param obj el - the element to apply the property to
- * @param obj properties - a hash of the properties to assign
- * @param int specificity - the specificity of the selector
- */
- eCSStender.applyWeightedStyle = function( el, properties, specificity )
- {
- if ( ! defined( el.inlineStyles ) )
- {
- el.inlineStyles = {};
- }
- var prop, styles = el.inlineStyles;
- for ( prop in properties )
- {
- if ( ! isInheritedProperty( properties, prop ) &&
- ( ! defined( styles[prop] ) ||
- styles[prop] <= specificity ) )
- {
- addInlineStyle( el, prop, properties[prop] );
- el.inlineStyles[prop] = specificity;
- }
- }
- };
- /**
- * eCSStender::ignore()
- * tells eCSStendet to ignore a file or files
- *
- * @param mixed sheets - a string or array of stylesheet paths to ignore
- */
- eCSStender.ignore = function( sheets )
- {
- if ( is( sheets, STRING ) )
- {
- sheets = [ sheets ];
- }
- else if ( ! is( sheets, ARRAY ) )
- {
- return;
- }
- for ( var i=0, iLen=sheets.length; i<iLen; i++ )
- {
- __ignored_css.push( sheets[i] );
- }
- };
- /**
- * eCSStender::disableCache()
- * tells eCSStender not to cache or work from the cache
- */
- eCSStender.disableCache = function()
- {
- __no_cache = TRUE;
- };
- /**
- * eCSStender::trim()
- * trims a string
- *
- * @param str str - the string to trim
- *
- * @return str - the trimmed string
- */
- function trim( str )
- {
- if ( is( str, STRING ) )
- {
- return str.replace( /^\s+|\s+$/g, EMPTY );
- }
- return str;
- }
- eCSStender.trim = trim;
- /**
- * eCSStender::loadScript()
- * dynamically loads a JavaScript file without loading the same one twice
- *
- * @param str src - the path to the JavaScript
- * @param fn callback - optional callback to run when script is loaded
- */
- __script.setAttribute( TYPE, 'text/javascript' );
- eCSStender.loadScript = function( src, callback )
- {
- var
- scripts = DOCUMENT.getElementsByTagName('script'),
- i = scripts.length,
- script = __script.cloneNode( TRUE ),
- loaded = FALSE;
- callback = callback || EMPTY_FN;
- while ( i-- )
- {
- if ( scripts[i].src == src )
- {
- script = FALSE;
- }
- }
- if ( script )
- {
- script.onload = script.onreadystatechange = function(){
- if ( ! loaded &&
- ( ! defined( script.readyState ) ||
- script.readyState == 'loaded' ||
- script.readyState == COMPLETE ) )
- {
- loaded = TRUE;
- script.onload = script.onreadystatechange = NULL;
- callback();
- }
- };
- script.setAttribute( 'src', src );
- __head.appendChild( script );
- }
- else
- {
- setTimeout( callback, 100 );
- }
- };
- /**
- * eCSStender::isInheritedProperty()
- * tests whether the given property is inherited
- *
- * @param obj obj - the object to test
- * @param str prop - the property to look for
- *
- * @return bool - TRUE is property is inherited, FALSE is it isn't
- */
- function isInheritedProperty( obj, prop )
- {
- if ( obj.hasOwnProperty )
- {
- isInheritedProperty = function( obj, prop )
- {
- return ! obj.hasOwnProperty(prop);
- };
- }
- else
- {
- isInheritedProperty = function( obj, prop )
- {
- var c = obj.constructor;
- if ( c &&
- c.prototype )
- {
- return obj[prop] === c.prototype[prop];
- }
- return TRUE;
- };
- }
- eCSStender.isInheritedProperty = isInheritedProperty;
- return isInheritedProperty( obj, prop );
- }
- /**
- * eCSStender::getCSSValue()
- * gets the computed value of a CSS property
- *
- * @param obj el - the element
- * @param str prop - the property name
- *
- * @return str - the value
- */
- function getCSSValue( el, prop )
- {
- var computed = WINDOW.getComputedStyle;
- if ( el.currentStyle )
- {
- getCSSValue = function( el, prop )
- {
- return el.currentStyle[camelize( prop )];
- };
- }
- else if ( computed )
- {
- getCSSValue = function( el, prop )
- {
- return computed( el, NULL ).getPropertyValue( prop );
- };
- }
- else
- {
- getCSSValue = function()
- {
- return FALSE;
- };
- }
- eCSStender.getCSSValue = getCSSValue;
- return getCSSValue( el, prop );
- }
- /**
- * eCSStender::makeUniqueClass()
- * creates a unique class for an element
- *
- * @return str - the unique class
- */
- eCSStender.makeUniqueClass = function()
- {
- var start = new Date();
- start = start.getTime();
- function init()
- {
- return ECSSTENDER + HYPHEN + start++;
- }
- eCSStender.makeUniqueClass = init;
- return init();
- };
- /**
- * eCSStender::addClass()
- * adds a class to an element
- *
- * @param obj el - the element to have its class augmented
- * @param str the_class - the class to add
- * @param RegExp re - a regular expression to match the class (optional)
- */
- function addClass( el, the_class, re )
- {
- re = re || makeClassRegExp( the_class );
- if ( ! hasClass( el, the_class, re ) )
- {
- el.className += SPACE + the_class;
- }
- }
- eCSStender.addClass = addClass;
- /**
- * eCSStender::removeClass()
- * removes a class from an element
- *
- * @param obj el - the element to have its class augmented
- * @param str the_class - the class to add
- * @param RegExp re - a regular expression to match the class (optional)
- */
- function removeClass( el, the_class, re )
- {
- re = re || makeClassRegExp( the_class );
- if ( hasClass( el, the_class, re ) )
- {
- el.className = trim( el.className.replace( re, SPACE ) );
- }
- };
- eCSStender.removeClass = removeClass;
- /**
- * eCSStender::hasClass()
- * checks to see if an element has the given class
- *
- * @param obj el - the element to have its class augmented
- * @param str the_class - the class to add
- * @param RegExp re - a regular expression to match the class (optional)
- */
- function hasClass( el, the_class, re )
- {
- re = re || makeClassRegExp( the_class );
- return el.className.match( re );
- };
- eCSStender.hasClass = hasClass;
- /**
- * eCSStender::toggleClass()
- * adds or removes a class based on whether it's already there
- *
- * @param obj el - the element to have its class augmented
- * @param str the_class - the class to add
- */
- function toggleClass( el, the_class )
- {
- var re = makeClassRegExp( the_class );
- if ( hasClass( el, the_class, re ) )
- {
- removeClass( el, the_class, re );
- }
- else
- {
- addClass( el, the_class, re );
- }
- };
- eCSStender.toggleClass = toggleClass;
-
- /*-------------------------------------*
- * DOM Loaded Trigger *
- * Based on jQuery's *
- *-------------------------------------*/
- (function(){
- var
- DCL = 'DOMContentLoaded',
- ORC = 'onreadystatechange',
- __old_onload = WINDOW.onload,
- doScroll = DOCUMENT.documentElement.doScroll;
-
- // for Mozilla/Safari/Opera9
- if ( DOCUMENT.addEventListener )
- {
- DOCUMENT.addEventListener( DCL, function(){
- DOCUMENT.removeEventListener( DCL, arguments.callee, FALSE );
- initialize();
- }, FALSE );
- }
- // If IE event model is used
- else if ( DOCUMENT.attachEvent )
- {
- // ensure firing before onload, maybe late but safe also for iframes
- DOCUMENT.attachEvent( ORC, function(){
- if ( DOCUMENT.readyState === COMPLETE ) {
- DOCUMENT.detachEvent( ORC, arguments.callee );
- initialize();
- }
- });
- // If IE and not an iframe, continually check to see if the document is ready
- if ( doScroll &&
- WINDOW == WINDOW.top )
- {
- (function(){
- try {
- // If IE is used, use the trick by Diego Perini
- // http://javascript.nwbox.com/IEContentLoaded/
- doScroll('left');
- }
- catch( error )
- {
- setTimeout( arguments.callee, 0 );
- return;
- }
- // and execute any waiting functions
- initialize();
- })();
- }
- }
- })();
-
- })();
|