File size: 3,567 Bytes
bc20498 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
import * as util from '../util';
import Selector from '../selector';
let styfn = {};
styfn.appendFromString = function( string ){
let self = this;
let style = this;
let remaining = '' + string;
let selAndBlockStr;
let blockRem;
let propAndValStr;
// remove comments from the style string
remaining = remaining.replace( /[/][*](\s|.)+?[*][/]/g, '' );
function removeSelAndBlockFromRemaining(){
// remove the parsed selector and block from the remaining text to parse
if( remaining.length > selAndBlockStr.length ){
remaining = remaining.substr( selAndBlockStr.length );
} else {
remaining = '';
}
}
function removePropAndValFromRem(){
// remove the parsed property and value from the remaining block text to parse
if( blockRem.length > propAndValStr.length ){
blockRem = blockRem.substr( propAndValStr.length );
} else {
blockRem = '';
}
}
for(;;){
let nothingLeftToParse = remaining.match( /^\s*$/ );
if( nothingLeftToParse ){ break; }
let selAndBlock = remaining.match( /^\s*((?:.|\s)+?)\s*\{((?:.|\s)+?)\}/ );
if( !selAndBlock ){
util.warn( 'Halting stylesheet parsing: String stylesheet contains more to parse but no selector and block found in: ' + remaining );
break;
}
selAndBlockStr = selAndBlock[0];
// parse the selector
let selectorStr = selAndBlock[1];
if( selectorStr !== 'core' ){
let selector = new Selector( selectorStr );
if( selector.invalid ){
util.warn( 'Skipping parsing of block: Invalid selector found in string stylesheet: ' + selectorStr );
// skip this selector and block
removeSelAndBlockFromRemaining();
continue;
}
}
// parse the block of properties and values
let blockStr = selAndBlock[2];
let invalidBlock = false;
blockRem = blockStr;
let props = [];
for(;;){
let nothingLeftToParse = blockRem.match( /^\s*$/ );
if( nothingLeftToParse ){ break; }
let propAndVal = blockRem.match( /^\s*(.+?)\s*:\s*(.+?)(?:\s*;|\s*$)/ );
if( !propAndVal ){
util.warn( 'Skipping parsing of block: Invalid formatting of style property and value definitions found in:' + blockStr );
invalidBlock = true;
break;
}
propAndValStr = propAndVal[0];
let propStr = propAndVal[1];
let valStr = propAndVal[2];
let prop = self.properties[ propStr ];
if( !prop ){
util.warn( 'Skipping property: Invalid property name in: ' + propAndValStr );
// skip this property in the block
removePropAndValFromRem();
continue;
}
let parsedProp = style.parse( propStr, valStr );
if( !parsedProp ){
util.warn( 'Skipping property: Invalid property definition in: ' + propAndValStr );
// skip this property in the block
removePropAndValFromRem();
continue;
}
props.push( {
name: propStr,
val: valStr
} );
removePropAndValFromRem();
}
if( invalidBlock ){
removeSelAndBlockFromRemaining();
break;
}
// put the parsed block in the style
style.selector( selectorStr );
for( let i = 0; i < props.length; i++ ){
let prop = props[ i ];
style.css( prop.name, prop.val );
}
removeSelAndBlockFromRemaining();
}
return style;
};
styfn.fromString = function( string ){
let style = this;
style.resetToDefault();
style.appendFromString( string );
return style;
};
export default styfn;
|