Skip to content

Commit

Permalink
Abstract out the creation of StyleInfo classes. ~300 byte file size i…
Browse files Browse the repository at this point in the history
…mprovement. Also renamed StyleBase -> StyleInfoBase.
  • Loading branch information
Jason Johnston committed Jun 4, 2010
1 parent bf3d9f2 commit d6baacf
Show file tree
Hide file tree
Showing 8 changed files with 533 additions and 561 deletions.
2 changes: 1 addition & 1 deletion build.xml
Expand Up @@ -19,7 +19,7 @@
<fileset file="${src_dir}/Angle.js" />
<fileset file="${src_dir}/Color.js" />
<fileset file="${src_dir}/Tokenizer.js" />
<fileset file="${src_dir}/StyleBase.js" />
<fileset file="${src_dir}/StyleInfoBase.js" />
<fileset file="${src_dir}/BackgroundStyleInfo.js" />
<fileset file="${src_dir}/BorderStyleInfo.js" />
<fileset file="${src_dir}/BorderRadiusStyleInfo.js" />
Expand Down
479 changes: 236 additions & 243 deletions sources/BackgroundStyleInfo.js

Large diffs are not rendered by default.

225 changes: 109 additions & 116 deletions sources/BorderImageStyleInfo.js
Expand Up @@ -3,151 +3,144 @@
* @constructor
* @param {Element} el the target element
*/
PIE.BorderImageStyleInfo = (function() {
function BorderImageStyleInfo( el ) {
this.element = el;
}
PIE.Util.merge( BorderImageStyleInfo.prototype, PIE.StyleBase, {
PIE.BorderImageStyleInfo = PIE.StyleInfoBase.newStyleInfo( {

cssProperty: 'border-image',
styleProperty: 'borderImage',
cssProperty: 'border-image',
styleProperty: 'borderImage',

repeatIdents: { 'stretch':1, 'round':1, 'repeat':1, 'space':1 },
repeatIdents: { 'stretch':1, 'round':1, 'repeat':1, 'space':1 },

parseCss: function( css ) {
var p = null, tokenizer, token, type, value,
slices, widths, outsets,
slashCount = 0, cs,
Type = PIE.Tokenizer.Type,
IDENT = Type.IDENT,
NUMBER = Type.NUMBER,
LENGTH = Type.LENGTH,
PERCENT = Type.PERCENT;
parseCss: function( css ) {
var p = null, tokenizer, token, type, value,
slices, widths, outsets,
slashCount = 0, cs,
Type = PIE.Tokenizer.Type,
IDENT = Type.IDENT,
NUMBER = Type.NUMBER,
LENGTH = Type.LENGTH,
PERCENT = Type.PERCENT;

if( css ) {
tokenizer = new PIE.Tokenizer( css );
p = {};
if( css ) {
tokenizer = new PIE.Tokenizer( css );
p = {};

function isSlash( token ) {
return token && ( token.type & Type.OPERATOR ) && ( token.value === '/' );
}
function isSlash( token ) {
return token && ( token.type & Type.OPERATOR ) && ( token.value === '/' );
}

function isFillIdent( token ) {
return token && ( token.type & IDENT ) && ( token.value === 'fill' );
}

function isFillIdent( token ) {
return token && ( token.type & IDENT ) && ( token.value === 'fill' );
function collectSlicesEtc() {
slices = tokenizer.until( function( tok ) {
return !( tok.type & ( NUMBER | PERCENT ) );
} );

if( isFillIdent( tokenizer.next() ) && !p.fill ) {
p.fill = true;
} else {
tokenizer.prev();
}

function collectSlicesEtc() {
slices = tokenizer.until( function( tok ) {
return !( tok.type & ( NUMBER | PERCENT ) );
if( isSlash( tokenizer.next() ) ) {
slashCount++;
widths = tokenizer.until( function( tok ) {
return !( token.type & ( NUMBER | PERCENT | LENGTH ) ) && !( ( token.type & IDENT ) && token.value === 'auto' );
} );

if( isFillIdent( tokenizer.next() ) && !p.fill ) {
p.fill = true;
} else {
tokenizer.prev();
}

if( isSlash( tokenizer.next() ) ) {
slashCount++;
widths = tokenizer.until( function( tok ) {
return !( token.type & ( NUMBER | PERCENT | LENGTH ) ) && !( ( token.type & IDENT ) && token.value === 'auto' );
outsets = tokenizer.until( function( tok ) {
return !( token.type & ( NUMBER | LENGTH ) );
} );

if( isSlash( tokenizer.next() ) ) {
slashCount++;
outsets = tokenizer.until( function( tok ) {
return !( token.type & ( NUMBER | LENGTH ) );
} );
}
} else {
tokenizer.prev();
}
} else {
tokenizer.prev();
}
}

while( token = tokenizer.next() ) {
type = token.type;
value = token.value;
while( token = tokenizer.next() ) {
type = token.type;
value = token.value;

// Numbers and/or 'fill' keyword: slice values. May be followed optionally by width values, followed optionally by outset values
if( type & ( NUMBER | PERCENT ) && !slices ) {
tokenizer.prev();
collectSlicesEtc();
}
else if( isFillIdent( token ) && !p.fill ) {
p.fill = true;
collectSlicesEtc();
}
// Numbers and/or 'fill' keyword: slice values. May be followed optionally by width values, followed optionally by outset values
if( type & ( NUMBER | PERCENT ) && !slices ) {
tokenizer.prev();
collectSlicesEtc();
}
else if( isFillIdent( token ) && !p.fill ) {
p.fill = true;
collectSlicesEtc();
}

// Idents: one or values for 'repeat'
else if( ( type & IDENT ) && this.repeatIdents[value] && !p.repeat ) {
p.repeat = { h: value };
if( token = tokenizer.next() ) {
if( ( token.type & IDENT ) && this.repeatIdents[token.value] ) {
p.repeat.v = token.value;
} else {
tokenizer.prev();
}
// Idents: one or values for 'repeat'
else if( ( type & IDENT ) && this.repeatIdents[value] && !p.repeat ) {
p.repeat = { h: value };
if( token = tokenizer.next() ) {
if( ( token.type & IDENT ) && this.repeatIdents[token.value] ) {
p.repeat.v = token.value;
} else {
tokenizer.prev();
}
}

// URL of the image
else if( ( type & Type.URL ) && !p.src ) {
p.src = value;
}

// Found something unrecognized; exit.
else {
return null;
}
}

// Validate what we collected
if( !p.src || !slices || slices.length < 1 || slices.length > 4 ||
( widths && widths.length > 4 ) || ( slashCount === 1 && widths.length < 1 ) ||
( outsets && outsets.length > 4 ) || ( slashCount === 2 && outsets.length < 1 ) ) {
return null;
// URL of the image
else if( ( type & Type.URL ) && !p.src ) {
p.src = value;
}

// Fill in missing values
if( !p.repeat ) {
p.repeat = { h: 'stretch' };
}
if( !p.repeat.v ) {
p.repeat.v = p.repeat.h;
// Found something unrecognized; exit.
else {
return null;
}
}

function distributeSides( tokens, convertFn ) {
return {
t: convertFn( tokens[0] ),
r: convertFn( tokens[1] || tokens[0] ),
b: convertFn( tokens[2] || tokens[0] ),
l: convertFn( tokens[3] || tokens[1] || tokens[0] )
};
}
// Validate what we collected
if( !p.src || !slices || slices.length < 1 || slices.length > 4 ||
( widths && widths.length > 4 ) || ( slashCount === 1 && widths.length < 1 ) ||
( outsets && outsets.length > 4 ) || ( slashCount === 2 && outsets.length < 1 ) ) {
return null;
}

p.slice = distributeSides( slices, function( tok ) {
return new PIE.Length( ( tok.type & NUMBER ) ? tok.value + 'px' : tok.value );
} );
// Fill in missing values
if( !p.repeat ) {
p.repeat = { h: 'stretch' };
}
if( !p.repeat.v ) {
p.repeat.v = p.repeat.h;
}

p.width = widths && widths.length > 0 ?
distributeSides( widths, function( tok ) {
return tok.type & ( LENGTH | PERCENT ) ? new PIE.Length( tok.value ) : tok.value;
} ) :
( cs = this.element.currentStyle ) && {
t: new PIE.Length( cs.borderTopWidth ),
r: new PIE.Length( cs.borderRightWidth ),
b: new PIE.Length( cs.borderBottomWidth ),
l: new PIE.Length( cs.borderLeftWidth )
};

p.outset = distributeSides( outsets || [ 0 ], function( tok ) {
return tok.type & LENGTH ? new PIE.Length( tok.value ) : tok.value;
} );
function distributeSides( tokens, convertFn ) {
return {
t: convertFn( tokens[0] ),
r: convertFn( tokens[1] || tokens[0] ),
b: convertFn( tokens[2] || tokens[0] ),
l: convertFn( tokens[3] || tokens[1] || tokens[0] )
};
}

return p;
p.slice = distributeSides( slices, function( tok ) {
return new PIE.Length( ( tok.type & NUMBER ) ? tok.value + 'px' : tok.value );
} );

p.width = widths && widths.length > 0 ?
distributeSides( widths, function( tok ) {
return tok.type & ( LENGTH | PERCENT ) ? new PIE.Length( tok.value ) : tok.value;
} ) :
( cs = this.element.currentStyle ) && {
t: new PIE.Length( cs.borderTopWidth ),
r: new PIE.Length( cs.borderRightWidth ),
b: new PIE.Length( cs.borderBottomWidth ),
l: new PIE.Length( cs.borderLeftWidth )
};

p.outset = distributeSides( outsets || [ 0 ], function( tok ) {
return tok.type & LENGTH ? new PIE.Length( tok.value ) : tok.value;
} );
}
} );

return BorderImageStyleInfo;
})();
return p;
}
} );
97 changes: 45 additions & 52 deletions sources/BorderRadiusStyleInfo.js
Expand Up @@ -3,69 +3,62 @@
* @constructor
* @param {Element} el the target element
*/
PIE.BorderRadiusStyleInfo = (function() {
function BorderRadiusStyleInfo( el ) {
this.element = el;
}
PIE.Util.merge( BorderRadiusStyleInfo.prototype, PIE.StyleBase, {
PIE.BorderRadiusStyleInfo = PIE.StyleInfoBase.newStyleInfo( {

cssProperty: 'border-radius',
styleProperty: 'borderRadius',
cssProperty: 'border-radius',
styleProperty: 'borderRadius',

parseCss: function( css ) {
var p = null, x, y,
tokenizer, token, length,
hasNonZero = false;
parseCss: function( css ) {
var p = null, x, y,
tokenizer, token, length,
hasNonZero = false;

function newLength( v ) {
return new PIE.Length( v );
}
function newLength( v ) {
return new PIE.Length( v );
}

if( css ) {
tokenizer = new PIE.Tokenizer( css );
if( css ) {
tokenizer = new PIE.Tokenizer( css );

function collectLengths() {
var arr = [], num;
while( ( token = tokenizer.next() ) && token.isLengthOrPercent() ) {
length = newLength( token.value );
num = length.getNumber();
if( num < 0 ) {
return null;
}
if( num > 0 ) {
hasNonZero = true;
}
arr.push( length );
function collectLengths() {
var arr = [], num;
while( ( token = tokenizer.next() ) && token.isLengthOrPercent() ) {
length = newLength( token.value );
num = length.getNumber();
if( num < 0 ) {
return null;
}
return arr.length > 0 && arr.length < 5 ? {
'tl': arr[0],
'tr': arr[1] || arr[0],
'br': arr[2] || arr[0],
'bl': arr[3] || arr[1] || arr[0]
} : null;
if( num > 0 ) {
hasNonZero = true;
}
arr.push( length );
}
return arr.length > 0 && arr.length < 5 ? {
'tl': arr[0],
'tr': arr[1] || arr[0],
'br': arr[2] || arr[0],
'bl': arr[3] || arr[1] || arr[0]
} : null;
}

// Grab the initial sequence of lengths
if( x = collectLengths() ) {
// See if there is a slash followed by more lengths, for the y-axis radii
if( token ) {
if( token.type & PIE.Tokenizer.Type.OPERATOR && token.value === '/' ) {
y = collectLengths();
}
} else {
y = x;
// Grab the initial sequence of lengths
if( x = collectLengths() ) {
// See if there is a slash followed by more lengths, for the y-axis radii
if( token ) {
if( token.type & PIE.Tokenizer.Type.OPERATOR && token.value === '/' ) {
y = collectLengths();
}
} else {
y = x;
}

// Treat all-zero values the same as no value
if( hasNonZero && x && y ) {
p = { x: x, y : y };
}
// Treat all-zero values the same as no value
if( hasNonZero && x && y ) {
p = { x: x, y : y };
}
}

return p;
}
} );

return BorderRadiusStyleInfo;
})();
return p;
}
} );

0 comments on commit d6baacf

Please sign in to comment.