CSSShadowModel.js 5.2 KB

1234567891011121314151617181920212223242526272829303132333435
  1. export class CSSShadowModel{constructor(isBoxShadow){this._isBoxShadow=isBoxShadow;this._inset=false;this._offsetX=InlineEditor.CSSLength.zero();this._offsetY=InlineEditor.CSSLength.zero();this._blurRadius=InlineEditor.CSSLength.zero();this._spreadRadius=InlineEditor.CSSLength.zero();this._color=(Common.Color.parse('black'));this._format=[_Part.OffsetX,_Part.OffsetY];}
  2. static parseTextShadow(text){return CSSShadowModel._parseShadow(text,false);}
  3. static parseBoxShadow(text){return CSSShadowModel._parseShadow(text,true);}
  4. static _parseShadow(text,isBoxShadow){const shadowTexts=[];const splits=TextUtils.TextUtils.splitStringByRegexes(text,[Common.Color.Regex,/,/g]);let currentIndex=0;for(let i=0;i<splits.length;i++){if(splits[i].regexIndex===1){const comma=splits[i];shadowTexts.push(text.substring(currentIndex,comma.position));currentIndex=comma.position+1;}}
  5. shadowTexts.push(text.substring(currentIndex,text.length));const shadows=[];for(let i=0;i<shadowTexts.length;i++){const shadow=new CSSShadowModel(isBoxShadow);shadow._format=[];let nextPartAllowed=true;const regexes=[/inset/gi,Common.Color.Regex,InlineEditor.CSSLength.Regex];const results=TextUtils.TextUtils.splitStringByRegexes(shadowTexts[i],regexes);for(let j=0;j<results.length;j++){const result=results[j];if(result.regexIndex===-1){if(/\S/.test(result.value)){return[];}
  6. nextPartAllowed=true;}else{if(!nextPartAllowed){return[];}
  7. nextPartAllowed=false;if(result.regexIndex===0){shadow._inset=true;shadow._format.push(_Part.Inset);}else if(result.regexIndex===1){const color=Common.Color.parse(result.value);if(!color){return[];}
  8. shadow._color=color;shadow._format.push(_Part.Color);}else if(result.regexIndex===2){const length=InlineEditor.CSSLength.parse(result.value);if(!length){return[];}
  9. const previousPart=shadow._format.length>0?shadow._format[shadow._format.length-1]:'';if(previousPart===_Part.OffsetX){shadow._offsetY=length;shadow._format.push(_Part.OffsetY);}else if(previousPart===_Part.OffsetY){shadow._blurRadius=length;shadow._format.push(_Part.BlurRadius);}else if(previousPart===_Part.BlurRadius){shadow._spreadRadius=length;shadow._format.push(_Part.SpreadRadius);}else{shadow._offsetX=length;shadow._format.push(_Part.OffsetX);}}}}
  10. if(invalidCount(shadow,_Part.OffsetX,1,1)||invalidCount(shadow,_Part.OffsetY,1,1)||invalidCount(shadow,_Part.Color,0,1)||invalidCount(shadow,_Part.BlurRadius,0,1)||invalidCount(shadow,_Part.Inset,0,isBoxShadow?1:0)||invalidCount(shadow,_Part.SpreadRadius,0,isBoxShadow?1:0)){return[];}
  11. shadows.push(shadow);}
  12. return shadows;function invalidCount(shadow,part,min,max){let count=0;for(let i=0;i<shadow._format.length;i++){if(shadow._format[i]===part){count++;}}
  13. return count<min||count>max;}}
  14. setInset(inset){this._inset=inset;if(this._format.indexOf(_Part.Inset)===-1){this._format.unshift(_Part.Inset);}}
  15. setOffsetX(offsetX){this._offsetX=offsetX;}
  16. setOffsetY(offsetY){this._offsetY=offsetY;}
  17. setBlurRadius(blurRadius){this._blurRadius=blurRadius;if(this._format.indexOf(_Part.BlurRadius)===-1){const yIndex=this._format.indexOf(_Part.OffsetY);this._format.splice(yIndex+1,0,_Part.BlurRadius);}}
  18. setSpreadRadius(spreadRadius){this._spreadRadius=spreadRadius;if(this._format.indexOf(_Part.SpreadRadius)===-1){this.setBlurRadius(this._blurRadius);const blurIndex=this._format.indexOf(_Part.BlurRadius);this._format.splice(blurIndex+1,0,_Part.SpreadRadius);}}
  19. setColor(color){this._color=color;if(this._format.indexOf(_Part.Color)===-1){this._format.push(_Part.Color);}}
  20. isBoxShadow(){return this._isBoxShadow;}
  21. inset(){return this._inset;}
  22. offsetX(){return this._offsetX;}
  23. offsetY(){return this._offsetY;}
  24. blurRadius(){return this._blurRadius;}
  25. spreadRadius(){return this._spreadRadius;}
  26. color(){return this._color;}
  27. asCSSText(){const parts=[];for(let i=0;i<this._format.length;i++){const part=this._format[i];if(part===_Part.Inset&&this._inset){parts.push('inset');}else if(part===_Part.OffsetX){parts.push(this._offsetX.asCSSText());}else if(part===_Part.OffsetY){parts.push(this._offsetY.asCSSText());}else if(part===_Part.BlurRadius){parts.push(this._blurRadius.asCSSText());}else if(part===_Part.SpreadRadius){parts.push(this._spreadRadius.asCSSText());}else if(part===_Part.Color){parts.push(this._color.asString(this._color.format()));}}
  28. return parts.join(' ');}}
  29. export const _Part={Inset:'I',OffsetX:'X',OffsetY:'Y',BlurRadius:'B',SpreadRadius:'S',Color:'C'};export class CSSLength{constructor(amount,unit){this.amount=amount;this.unit=unit;}
  30. static parse(text){const lengthRegex=new RegExp('^(?:'+InlineEditor.CSSLength.Regex.source+')$','i');const match=text.match(lengthRegex);if(!match){return null;}
  31. if(match.length>2&&match[2]){return new InlineEditor.CSSLength(parseFloat(match[1]),match[2]);}
  32. return InlineEditor.CSSLength.zero();}
  33. static zero(){return new InlineEditor.CSSLength(0,'');}
  34. asCSSText(){return this.amount+this.unit;}}
  35. CSSLength.Regex=(function(){const number='([+-]?(?:[0-9]*[.])?[0-9]+(?:[eE][+-]?[0-9]+)?)';const unit='(ch|cm|em|ex|in|mm|pc|pt|px|rem|vh|vmax|vmin|vw)';const zero='[+-]?(?:0*[.])?0+(?:[eE][+-]?[0-9]+)?';return new RegExp(number+unit+'|'+zero,'gi');})();self.InlineEditor=self.InlineEditor||{};InlineEditor=InlineEditor||{};InlineEditor.CSSShadowModel=CSSShadowModel;InlineEditor.CSSShadowModel._Part=_Part;InlineEditor.CSSLength=CSSLength;