@designliquido/foles
Version:
Linguagem de folhas de estilo para documentos em geral em português
219 lines • 11.1 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Serializador = void 0;
const declaracoes_1 = require("../declaracoes");
const gerais_1 = require("../modificadores/atributos/gerais");
const seletores_1 = require("../seletores");
const seletor_espaco_reservado_1 = require("../seletores/seletor-espaco-reservado");
const metodo_1 = require("../valores/metodos/foles/metodo");
const estruturas_html_1 = __importDefault(require("../tradutores/estruturas-html"));
const superclasse_1 = require("../modificadores/superclasse");
const fontes_1 = require("../modificadores/atributos/fontes");
/**
* A classe que efetivamente traduz FolEs para CSS.
*
* Normalmente o CSS traduzido é desaninhado por uma questão de compatibilidade
* entre navegadores. Até então, CSS aninhado é uma funcionalidade nova, e
* apenas navegadores mais recentes a implementam.
*/
class Serializador {
constructor(serializarComAninhamentos = false) {
this.serializarComAninhamentos = serializarComAninhamentos;
}
// TODO @Vitor: Montar a lógica para reconhecer variáveis aqui.
serializarModificador(modificador, indentacao = 0) {
// Caso 1: Número-Quantificador ou somente Número.
if (Number(modificador.valor) || modificador.valor === "0") {
return `${" ".repeat(indentacao)}${modificador.propriedadeCss}: ${modificador.valor}${modificador.quantificador || ""};\n`;
}
// Caso 2: Tradução do valor contida no objeto 'valoresAceitos'.
if (modificador["valoresAceitos"] !== undefined &&
modificador["valoresAceitos"].hasOwnProperty(modificador.valor)) {
const objetoValores = modificador["valoresAceitos"];
const valorTraduzido = objetoValores[modificador.valor];
return `${" ".repeat(indentacao)}${modificador.propriedadeCss}: ${valorTraduzido};\n`;
}
// Caso 3: Valor é RGB, RGBA, HSL, HSLA ou HEX, ou seja, um método.
if (modificador.valor instanceof metodo_1.Metodo) {
return `${" ".repeat(indentacao)}${modificador.propriedadeCss}: ${modificador.valor.paraTexto() || ""};\n`;
}
// Caso 4: Valor com aspas - como as fontes de texto.
if (modificador.valor.includes('"')) {
if (modificador.valor.includes(",")) {
const separarValores = modificador.valor.split(", ");
const valorSemAspas = separarValores[0].replace(/["']/g, '');
// Trecho específico para tratamento de fontes com grafia
if (Object.keys(fontes_1.fontes).includes(valorSemAspas)) {
let unirValores = '';
separarValores.forEach((valorIndividual) => {
if (modificador["valoresAceitos"] !== undefined &&
modificador["valoresAceitos"].hasOwnProperty(valorIndividual)) {
const objetoValores = modificador["valoresAceitos"];
const valorTraduzido = objetoValores[valorIndividual];
separarValores[1] = valorTraduzido;
unirValores = separarValores.join(", ");
}
});
return `${" ".repeat(indentacao)}${modificador.propriedadeCss}: ${unirValores};\n`;
}
else {
return `${" ".repeat(indentacao)}${modificador.propriedadeCss}: ${modificador.valor};\n`;
}
}
else {
return `${" ".repeat(indentacao)}${modificador.propriedadeCss}: ${modificador.valor};\n`;
}
}
// Caso 5: Atribuição Abreviada | Múltiplos valores separados por vírgula, barra ou espaço
if (modificador.valor.includes(" ")) {
let separarValores = [];
if (modificador.valor.includes(",")) {
separarValores = modificador.valor.split(", ");
}
else if (modificador.valor.includes("/")) {
separarValores = modificador.valor.split(" / ");
}
else if (modificador.valor.includes(" ")) {
separarValores = modificador.valor.split(" ");
}
separarValores.forEach((valorIndividual, indexIndividual) => {
let valoresTraduzidos = "";
if (modificador["valoresAceitos"] &&
modificador["valoresAceitos"].hasOwnProperty(valorIndividual)) {
const objetoValores = modificador["valoresAceitos"];
valoresTraduzidos += objetoValores[valorIndividual];
}
else if (gerais_1.valoresGerais[valorIndividual] !== undefined) {
valoresTraduzidos += gerais_1.valoresGerais[valorIndividual];
}
if (valoresTraduzidos.length !== 0 && typeof modificador.valor === 'string') {
modificador.valor = modificador.valor.replace(valorIndividual, valoresTraduzidos);
}
});
return `${" ".repeat(indentacao)}${modificador.propriedadeCss}: ${modificador.valor};\n`;
}
// Caso 6: É um valor genérico, cuja tradução está na lista 'valoresGerais'.
const valorTraduzido = gerais_1.valoresGerais[modificador.valor];
return `${" ".repeat(indentacao)}${modificador.propriedadeCss}: ${valorTraduzido};\n`;
}
serializarBlocoDeclaracao(declaracao, indentacao, textoSeletorAnterior) {
let resultado = "";
const prefixos = [];
let deveImprimir = true;
for (const seletor of declaracao.seletores) {
// Espaços reservados não são escritos diretamente no CSS.
if (seletor instanceof seletor_espaco_reservado_1.SeletorEspacoReservado) {
deveImprimir = false;
continue;
}
let prefixo;
if (seletor instanceof seletores_1.SeletorEstrutura) {
if (seletor.pseudoclasse) {
const seletorLmht = seletor.paraTexto();
const seletorSemPseudoclasse = seletorLmht.split(":")[0];
const traducaoSeletor = estruturas_html_1.default[seletorSemPseudoclasse];
const traducaoPseudoclasse = seletor.pseudoclasse.pseudoclasseCss;
prefixo = (textoSeletorAnterior +
" " +
`${traducaoSeletor}:${traducaoPseudoclasse}`).trimStart();
}
else {
const seletorLmht = seletor.paraTexto();
const traducaoSeletor = estruturas_html_1.default[seletorLmht];
prefixo = (textoSeletorAnterior +
" " +
traducaoSeletor).trimStart();
}
}
else {
prefixo = (textoSeletorAnterior +
" " +
seletor.paraTexto()).trimStart();
}
prefixos.push(prefixo);
resultado += " ".repeat(indentacao) + prefixo + ", ";
}
if (!deveImprimir) {
return resultado;
}
resultado = resultado.slice(0, -2);
resultado += " {\n";
for (const modificador of declaracao.modificadores) {
resultado += this.serializarModificador(modificador, indentacao + 4);
}
if (this.serializarComAninhamentos) {
resultado += this.serializar(declaracao.declaracoesAninhadas, indentacao + 4);
resultado += `${" ".repeat(indentacao)}}\n\n`;
}
else {
resultado += `${" ".repeat(indentacao)}}\n\n`;
for (const prefixo of prefixos) {
resultado += this.serializar(declaracao.declaracoesAninhadas, indentacao, prefixo);
}
}
return resultado;
}
validarValoresVariaveis(declaracao) {
const nomeFolEs = declaracao.modificadores[0].nomeFoles.length > 1 &&
typeof declaracao.modificadores[0].nomeFoles === "object"
? declaracao.modificadores[0].nomeFoles[0].toString()
: declaracao.modificadores[0].nomeFoles.toString();
const valorModificador = declaracao.modificadores[0].valor.toString();
const valorVariavel = false;
new superclasse_1.SeletorModificador(nomeFolEs, valorModificador, declaracao.modificadores[0].quantificador, declaracao.modificadores[0].pragmas, valorVariavel);
}
serializarDeclaracaoVariavel(declaracaoVariavel, declaracoes, indexVariavel) {
let variavelInexistente = false;
declaracoes.forEach((declaracao, indexBlocoDeclaracao) => {
if (declaracao instanceof declaracoes_1.BlocoDeclaracao) {
declaracao.modificadores.forEach((modificador) => {
if (modificador.valor === declaracaoVariavel.nome) {
if (typeof declaracaoVariavel.valor === "string") {
modificador.valor = declaracaoVariavel.valor;
if (declaracaoVariavel.quantificador)
modificador.quantificador = declaracaoVariavel.quantificador;
this.validarValoresVariaveis(declaracao);
}
else if (declaracaoVariavel.valor instanceof metodo_1.Metodo) {
modificador.valor = declaracaoVariavel.valor;
}
if (indexVariavel > indexBlocoDeclaracao) {
variavelInexistente = true;
}
}
});
}
});
if (variavelInexistente) {
throw new Error(`A variável '${declaracaoVariavel.nome}' deve ser declarada antes da atribuição de valor.`);
}
}
/**
* O processo de tradução. É recursivo.
* @param declaracoes As declaracoes.
* @returns Uma string com o resultado da tradução.
*/
serializar(declaracoes, indentacao = 0, seletorAnterior = undefined) {
let resultado = "";
let textoSeletorAnterior = "";
if (seletorAnterior !== undefined) {
textoSeletorAnterior = seletorAnterior;
}
for (const [index, declaracao] of declaracoes.entries()) {
switch (declaracao.constructor.name) {
case "BlocoDeclaracao":
resultado += this.serializarBlocoDeclaracao(declaracao, indentacao, textoSeletorAnterior);
break;
case "DeclaracaoVariavel":
this.serializarDeclaracaoVariavel(declaracao, declaracoes, index);
break;
}
}
return resultado;
}
}
exports.Serializador = Serializador;
//# sourceMappingURL=serializador.js.map