rewrite parseBackgroundImage to remove RegExp

RegExp couldn't handle parens inside parens:
linear-gradient(rgb(0,0,0),rgb(255,0,0))
This commit is contained in:
Andy Edinborough 2012-12-28 16:22:43 -06:00
parent d7bef66cc5
commit b81d7473e3
2 changed files with 81 additions and 22 deletions

View File

@ -33,29 +33,81 @@ _html2canvas.Util.backgroundImage = function (src) {
_html2canvas.Util.parseBackgroundImage = function (value) { _html2canvas.Util.parseBackgroundImage = function (value) {
var rxBackgroundImage = /([a-z\-]+)\((("[^"]+)|([^)]+))\)/i, var rxBackgroundImage = /([a-z\-]+)\((("[^"]+)|([^)]+))\)/i,
match, results = [], n = 0; method, definition, prefix, prefix_i, block, results = [],
if(!value) { return results; } c, mode = 0, numParen = 0;
while( n++ < 100 && !!(match = value.match(rxBackgroundImage)) ) { var appendResult = function(){
var def = match[2], if(method) {
method = match[1], if(definition.substr( 0, 1 ) === '"') {
prefix = '', i; definition = definition.substr( 1, definition.length - 2 );
if(def.substr( 0, 1 ) === '"') {
def = def.substr( 1, def.length-2 );
} }
if(method.substr( 0, 1 ) === '-' && if(method.substr( 0, 1 ) === '-' &&
(i = method.indexOf( '-', 1 ) + 1) > 0) { (prefix_i = method.indexOf( '-', 1 ) + 1) > 0) {
prefix = method.substr( 0, i); prefix = method.substr( 0, prefix_i);
method = method.substr( i ); method = method.substr( prefix_i );
} }
results.push({ results.push({
prefix: prefix, prefix: prefix,
method: method, method: method,
definition: def, definition: definition,
value: match[0] value: block
}); });
value = value.replace( match[0], '' );
} }
method =
prefix =
definition =
block = '';
};
appendResult();
for(var i = 0, ii = value.length; i<ii; i++) {
c = value[i];
switch(c) {
case ' ':
case '\t':
case '\n':
case '\r':
if(mode == 0){
continue;
}
case '(':
if(mode === 0) {
mode = 1;
block += c;
continue;
} else {
numParen++;
}
break;
case ')':
if(mode === 1) {
if(numParen === 0) {
mode = 0;
block += c;
appendResult();
continue;
} else {
numParen--;
}
}
break;
case ',':
if(mode === 0) {
appendResult();
continue;
}
break;
}
block += c;
if(mode === 0) { method += c; }
else { definition += c; }
}
appendResult();
return results; return results;
}; };

View File

@ -174,6 +174,12 @@ $(function() {
'linear-gradient' 'linear-gradient'
); );
test_parse_background_image(
'linear-gradient(top,rgb(255,0,0),rgb(0,0,0))',
{ prefix: '', method: 'linear-gradient', definition: 'top,rgb(255,0,0),rgb(0,0,0)', value: 'linear-gradient(top,rgb(255,0,0),rgb(0,0,0))' },
'linear-gradient'
);
test_parse_background_image( test_parse_background_image(
'-webkit-linear-gradient(red,black)', '-webkit-linear-gradient(red,black)',
{ prefix: '-webkit-', method: 'linear-gradient', definition: 'red,black', value: '-webkit-linear-gradient(red,black)' }, { prefix: '-webkit-', method: 'linear-gradient', definition: 'red,black', value: '-webkit-linear-gradient(red,black)' },
@ -181,10 +187,11 @@ $(function() {
); );
test_parse_background_image( test_parse_background_image(
'linear-gradient(red,black), url(test), url("test")', [ 'linear-gradient(red,black), url(test), url("test"),\n none, ', [
{ prefix: '', method: 'linear-gradient', definition: 'red,black', value: 'linear-gradient(red,black)' }, { prefix: '', method: 'linear-gradient', definition: 'red,black', value: 'linear-gradient(red,black)' },
{ prefix: '', method: 'url', definition: 'test', value: 'url(test)' }, { prefix: '', method: 'url', definition: 'test', value: 'url(test)' },
{ prefix: '', method: 'url', definition: 'test', value: 'url("test")' } { prefix: '', method: 'url', definition: 'test', value: 'url("test")' },
{ prefix: '', method: 'none', definition: '', value: 'none' }
], ],
'multiple backgrounds' 'multiple backgrounds'
); );