UNPKG

@hippy/debug-server-next

Version:
189 lines (188 loc) 7.55 kB
"use strict"; /* * Tencent is pleased to support the open source community by making * Hippy available. * * Copyright (C) 2017-2019 THL A29 Limited, a Tencent company. * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.CssDomainAdapter = exports.cssMiddleWareManager = void 0; const tslib_1 = require("tslib"); const color_normalize_1 = tslib_1.__importDefault(require("color-normalize")); const enum_chrome_mapping_1 = require("@hippy/devtools-protocol/dist/types/enum-chrome-mapping"); exports.cssMiddleWareManager = { downwardMiddleWareListMap: { [enum_chrome_mapping_1.ChromeCommand.CSSGetMatchedStylesForNode]: ({ msg, sendToDevtools }) => { // narrow down type const commandRes = msg; commandRes.result.inlineStyle = CssDomainAdapter.conversionInlineStyle(commandRes.result.inlineStyle); return sendToDevtools(commandRes); }, [enum_chrome_mapping_1.ChromeCommand.CSSGetComputedStyleForNode]: ({ msg, sendToDevtools }) => { const commandRes = msg; commandRes.result.computedStyle = CssDomainAdapter.conversionComputedStyle(commandRes.result.computedStyle); return sendToDevtools(commandRes); }, [enum_chrome_mapping_1.ChromeCommand.CSSSetStyleTexts]: ({ msg, sendToDevtools }) => { const commandRes = msg; commandRes.result.styles = commandRes.result.styles.map((style) => CssDomainAdapter.conversionInlineStyle(style)); return sendToDevtools(commandRes); }, }, upwardMiddleWareListMap: { [enum_chrome_mapping_1.ChromeCommand.CSSSetStyleTexts]: ({ msg, sendToApp }) => { const req = msg; req.params.edits = req.params.edits.map((data) => { const textList = data.text .trim() .split(';') .reduce((ret, styleItem) => { if (!styleItem.trim()) return ret; const styleItems = styleItem.split(':'); const [name] = styleItems; let [, ...values] = styleItems; if (!CssDomainAdapter.shouldSkipStyle(name)) { values[0] = values[0].trim(); if (name.toLowerCase().includes('color') && !/^\d+$/.test(values[0])) { const rgba = CssDomainAdapter.transformRGBA(values[0]); values = [String(CssDomainAdapter.rgbaToInt(rgba))]; } ret.push(`${name}: ${values.join(':').trim()}`); } return ret; }, []); const totalCSSText = textList.join(';'); return { ...data, range: { ...data.range, endColumn: totalCSSText.length, }, text: totalCSSText, }; }); return sendToApp(req); }, }, }; class CssDomainAdapter { static intToRGBA(int32Color) { const int = int32Color << 0; // Converts 0xaarrggbb into 0xrrggbbaa const int32 = ((int << 8) | (int >>> 24)) >>> 0; const int8 = new Uint8Array(new Uint32Array([int32]).buffer).reverse(); const r = int8[0]; const g = int8[1]; const b = int8[2]; const a = Math.round((int8[3] / 255) * 100) / 100; return `rgba(${r}, ${g}, ${b}, ${a})`; } static rgbaToInt(stringColor) { const uint8 = (0, color_normalize_1.default)(stringColor, 'uint8'); const int = Buffer.from(uint8).readUInt32BE(0); // Converts 0xrrggbbaa into 0xaarrggbb return ((int << 24) | (int >>> 8)) >>> 0; } static shouldSkipStyle(styleName) { return CssDomainAdapter.skipStyleList.some((name) => name.toString().trim().toLowerCase() === styleName.toString().trim().toLowerCase()); } static conversionInlineStyle(style) { if (!style) return {}; let totalCSSText = ''; style.cssProperties = (style.cssProperties || []).reduce((ret, item) => { if (CssDomainAdapter.shouldSkipStyle(item.name)) return ret; const cssText = `${item.name}: ${item.value}`; if (item.name.toLowerCase().includes('color')) { item.value = CssDomainAdapter.intToRGBA(parseInt(item.value, 10)); } item.range = { ...item.range, startColumn: totalCSSText.length, endColumn: totalCSSText.length + cssText.length + 1, }; totalCSSText += `${cssText}; `; ret.push(item); return ret; }, []); style.cssText = totalCSSText; style.range = { ...style.range, endColumn: totalCSSText.length, }; return style; } static conversionComputedStyle(style) { if (!style) return []; return style.reduce((ret, item) => { if (!CssDomainAdapter.shouldSkipStyle(item.name)) { if (item.name.toLowerCase().includes('color')) { item.value = CssDomainAdapter.intToRGBA(parseInt(item.value, 10)); } ret.push(item); } return ret; }, []); } /** * input: * rgb(165 21 21) * rgb(183 12 12 / 95%) * rgb(100% 0% 0% / 50%) * rgba(0 0 255 / 50%) * rgba(2, 0, 0, 0) * rgba(100%, 0%, 0%, 50%) * * output: rgba(r, g, b, a) * r, g, b, a are int number */ static transformRGBA(colorText) { return colorText.trim().replace(/^rgba?\(([^()]+)\)$/i, (s, p1) => { let r; let g; let b; let a; if (p1.includes('/')) { const [rgb, alpha] = p1.split(/\s*\/\s*/); a = alpha; [r, g, b] = rgb.split(' '); } else { const spliter = p1.includes(',') ? ',' : ' '; [r, g, b, a] = p1.split(spliter); } a || (a = '1'); [r, g, b] = [r, g, b].map((value) => { if (value.toString().includes('%')) { return Math.floor((parseInt(value, 10) / 100) * 255).toString(); } return value.trim(); }); if (a.toString().includes('%')) { a = (parseInt(a, 10) / 100).toString(); } else { a = a.trim(); } return `rgba(${r}, ${g}, ${b}, ${a})`; }); } } exports.CssDomainAdapter = CssDomainAdapter; CssDomainAdapter.skipStyleList = ['backgroundImage', 'transform', 'shadowOffset'];