debug-server-next
Version:
Dev server for hippy-core.
245 lines (244 loc) • 9.38 kB
JavaScript
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/* eslint-disable rulesdir/no_underscored_properties */
import * as Common from '../../../../core/common/common.js';
import * as TextUtils from '../../../../models/text_utils/text_utils.js';
export class CSSShadowModel {
_isBoxShadow;
_inset;
_offsetX;
_offsetY;
_blurRadius;
_spreadRadius;
_color;
_format;
_important;
constructor(isBoxShadow) {
this._isBoxShadow = isBoxShadow;
this._inset = false;
this._offsetX = CSSLength.zero();
this._offsetY = CSSLength.zero();
this._blurRadius = CSSLength.zero();
this._spreadRadius = CSSLength.zero();
this._color = Common.Color.Color.parse('black');
this._format = ["X" /* OffsetX */, "Y" /* OffsetY */];
this._important = false;
}
static parseTextShadow(text) {
return CSSShadowModel._parseShadow(text, false);
}
static parseBoxShadow(text) {
return CSSShadowModel._parseShadow(text, true);
}
static _parseShadow(text, isBoxShadow) {
const shadowTexts = [];
// Split by commas that aren't inside of color values to get the individual shadow values.
const splits = TextUtils.TextUtils.Utils.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;
}
}
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 = [/!important/gi, /inset/gi, Common.Color.Regex, CSSLength.Regex];
const results = TextUtils.TextUtils.Utils.splitStringByRegexes(shadowTexts[i], regexes);
for (let j = 0; j < results.length; j++) {
const result = results[j];
if (result.regexIndex === -1) {
// Don't allow anything other than inset, color, length values, and whitespace.
if (/\S/.test(result.value)) {
return [];
}
// All parts must be separated by whitespace.
nextPartAllowed = true;
}
else {
if (!nextPartAllowed) {
return [];
}
nextPartAllowed = false;
if (result.regexIndex === 0) {
shadow._important = true;
shadow._format.push("M" /* Important */);
}
else if (result.regexIndex === 1) {
shadow._inset = true;
shadow._format.push("I" /* Inset */);
}
else if (result.regexIndex === 2) {
const color = Common.Color.Color.parse(result.value);
if (!color) {
return [];
}
shadow._color = color;
shadow._format.push("C" /* Color */);
}
else if (result.regexIndex === 3) {
const length = CSSLength.parse(result.value);
if (!length) {
return [];
}
const previousPart = shadow._format.length > 0 ? shadow._format[shadow._format.length - 1] : '';
if (previousPart === "X" /* OffsetX */) {
shadow._offsetY = length;
shadow._format.push("Y" /* OffsetY */);
}
else if (previousPart === "Y" /* OffsetY */) {
shadow._blurRadius = length;
shadow._format.push("B" /* BlurRadius */);
}
else if (previousPart === "B" /* BlurRadius */) {
shadow._spreadRadius = length;
shadow._format.push("S" /* SpreadRadius */);
}
else {
shadow._offsetX = length;
shadow._format.push("X" /* OffsetX */);
}
}
}
}
if (invalidCount(shadow, "X" /* OffsetX */, 1, 1) || invalidCount(shadow, "Y" /* OffsetY */, 1, 1) ||
invalidCount(shadow, "C" /* Color */, 0, 1) || invalidCount(shadow, "B" /* BlurRadius */, 0, 1) ||
invalidCount(shadow, "I" /* Inset */, 0, isBoxShadow ? 1 : 0) ||
invalidCount(shadow, "S" /* SpreadRadius */, 0, isBoxShadow ? 1 : 0) ||
invalidCount(shadow, "M" /* Important */, 0, 1)) {
return [];
}
shadows.push(shadow);
}
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++;
}
}
return count < min || count > max;
}
}
setInset(inset) {
this._inset = inset;
if (this._format.indexOf("I" /* Inset */) === -1) {
this._format.unshift("I" /* Inset */);
}
}
setOffsetX(offsetX) {
this._offsetX = offsetX;
}
setOffsetY(offsetY) {
this._offsetY = offsetY;
}
setBlurRadius(blurRadius) {
this._blurRadius = blurRadius;
if (this._format.indexOf("B" /* BlurRadius */) === -1) {
const yIndex = this._format.indexOf("Y" /* OffsetY */);
this._format.splice(yIndex + 1, 0, "B" /* BlurRadius */);
}
}
setSpreadRadius(spreadRadius) {
this._spreadRadius = spreadRadius;
if (this._format.indexOf("S" /* SpreadRadius */) === -1) {
this.setBlurRadius(this._blurRadius);
const blurIndex = this._format.indexOf("B" /* BlurRadius */);
this._format.splice(blurIndex + 1, 0, "S" /* SpreadRadius */);
}
}
setColor(color) {
this._color = color;
if (this._format.indexOf("C" /* Color */) === -1) {
this._format.push("C" /* Color */);
}
}
isBoxShadow() {
return this._isBoxShadow;
}
inset() {
return this._inset;
}
offsetX() {
return this._offsetX;
}
offsetY() {
return this._offsetY;
}
blurRadius() {
return this._blurRadius;
}
spreadRadius() {
return this._spreadRadius;
}
color() {
return this._color;
}
asCSSText() {
const parts = [];
for (let i = 0; i < this._format.length; i++) {
const part = this._format[i];
if (part === "I" /* Inset */ && this._inset) {
parts.push('inset');
}
else if (part === "X" /* OffsetX */) {
parts.push(this._offsetX.asCSSText());
}
else if (part === "Y" /* OffsetY */) {
parts.push(this._offsetY.asCSSText());
}
else if (part === "B" /* BlurRadius */) {
parts.push(this._blurRadius.asCSSText());
}
else if (part === "S" /* SpreadRadius */) {
parts.push(this._spreadRadius.asCSSText());
}
else if (part === "C" /* Color */) {
parts.push(this._color.asString(this._color.format()));
}
else if (part === "M" /* Important */ && this._important) {
parts.push('!important');
}
}
return parts.join(' ');
}
}
export class CSSLength {
amount;
unit;
constructor(amount, unit) {
this.amount = amount;
this.unit = unit;
}
static parse(text) {
const lengthRegex = new RegExp('^(?:' + CSSLength.Regex.source + ')$', 'i');
const match = text.match(lengthRegex);
if (!match) {
return null;
}
if (match.length > 2 && match[2]) {
return new CSSLength(parseFloat(match[1]), match[2]);
}
return CSSLength.zero();
}
static zero() {
return new CSSLength(0, '');
}
asCSSText() {
return this.amount + this.unit;
}
// eslint-disable-next-line @typescript-eslint/naming-convention
static 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');
})();
}