Less.js: Menos falha ao analisar os valores válidos da propriedade personalizada (ex: @apply polyfill)

Criado em 21 out. 2015  ·  34Comentários  ·  Fonte: less/less.js

Este código quebra:

paper-drawer-panel {
  --paper-drawer-panel-left-drawer: {
    background-color: red;
  };
}

As chaves no valor da propriedade quebram o analisador.

Eu gostaria que MENOS suportasse a sintaxe @apply , conforme usada pelo Polymer.
https://www.polymer-project.org/1.0/docs/devguide/styling.html#custom -css-mixins

Também tentei:

paper-drawer-panel {
  <strong i="14">@ruleset</strong>: {
    prop: value;
  };
  --paper-drawer-panel-left-drawer: %(~"%d", @ruleset);
}

Não quebrou o analisador, mas entregou:

paper-drawer-panel {
  --paper-drawer-panel-left-drawer: ;
}

o que claramente não é um comportamento desejável.

bug feature request

Comentários muito úteis

Temos uma especificação para isso; existe um polyfill; O Chrome o implementou; A Polymer já o está usando em uma versão 1.0; e sites já estão usando o Polymer.

Eu acho que é uma expectativa perfeitamente razoável para Less suportar a sintaxe em um nível mínimo.

Menos já passou @apply , --foo: bar; e var(--foo) . A única coisa que falta é fazer com que Less passe pelo { ... } em --foo: { property: value; } com o mesmo processamento básico dado a outros blocos css; em vez de parar bruscamente e gerar um erro de análise.

Todos 34 comentários

Receio que o suporte à sintaxe não CSS está além do escopo do Less. Então meu -1.

De qualquer forma, observe que você pode emitir qualquer código na saída com escape. Por exemplo:

xpaper-drawer-panel {
  --paper-drawer-panel-left-drawer: ~"{background-color: red;}";
}

Ou de uma maneira mais hackeada de várias linhas:

paper-drawer-panel {
  -:~";--paper-drawer-panel-left-drawer: {";
    background-color: red;
    color: blue;
  -:~";}";
}

Em situações mais complexas, também é sempre possível usar <strong i="13">@import</strong> (inline) .


Quanto a tentativas como %(~"%d", @ruleset); - Não, menos variáveis ​​não são macros, não são expandidas independentemente do contexto e, especificamente para conjuntos de regras não nomeados, a única sintaxe adequada é @ruleset() dentro de um corpo de conjunto de regras e _não_ como um valor de propriedade.

Bem, eu concordo com você que a sintaxe não padrão geralmente não deve ser suportada.

No entanto, isso significa que MENOS é incompatível com o polímero em muitos casos.

Obrigado pela resposta de qualquer maneira. : +1:

Não tenho certeza se isso faz diferença em sua decisão @ seven-phase-max, mas há uma especificação aberta para uma regra @apply , http://tabatkins.github.io/specs/css-apply-rule/ #issue -882293bd.

Veja também https://github.com/Polymer/polymer/issues/1373 , pois parece algo que o Google vai realmente empurrar no processo.

E o SASS parece estar tratando disso https://github.com/sass/sass/issues/1128

@ donny-dont Nota Eu não decido nada (não fechei a proposta) - sou apenas um crítico.

Bem, Tab Atkins gerou _tens_ de propostas padrão de CSS (chamadas de "ideias") e, embora os caras do Google possam empurrar isso para seus navegadores amanhã, ainda está muito longe de se tornar uma coisa de rascunho de CSS (lembre-se de CSS vars not entrando no mundo CSS há cerca de dez anos?).

@ seven-phase-max desculpas para a implicação. Eu só queria observar que a Polymer está empurrando a proposta do mixin e o Chrome provavelmente irá implementá-la assim que for formada, o que foi algo que @Jamtis realmente não comunicou.

Eu sou bastante novo no uso de LESS. Existe algum tipo de sistema de plug-in para o analisador nesses tipos de cenários? Algo como um sinalizador experimental que você pode ativar e desativar?

Estou reabrindo isso para poder redirecionar solicitações duplicadas aqui.

/sub

Temos uma especificação para isso; existe um polyfill; O Chrome o implementou; A Polymer já o está usando em uma versão 1.0; e sites já estão usando o Polymer.

Eu acho que é uma expectativa perfeitamente razoável para Less suportar a sintaxe em um nível mínimo.

Menos já passou @apply , --foo: bar; e var(--foo) . A única coisa que falta é fazer com que Less passe pelo { ... } em --foo: { property: value; } com o mesmo processamento básico dado a outros blocos css; em vez de parar bruscamente e gerar um erro de análise.

Acho que as especificações completas das variáveis ​​CSS devem ser suportadas pelo LESS. Adoraria que isso acontecesse!

@dantman

Temos uma especificação para isso; existe um polyfill; O Chrome o implementou; A Polymer já o está usando em uma versão 1.0; e sites já estão usando o Polymer.

Para mim, esse ainda não é um motivo muito convincente. Isso se traduz em: Google, Google e Google estão usando isso. Não houve interesse em nenhum outro lugar, e não há indicações de que algum dia haverá.

@ donny-dont

Eu sou bastante novo no uso de LESS. Existe algum tipo de sistema de plug-in para o analisador nesses tipos de cenários? Algo como um sinalizador experimental que você pode ativar e desativar?

Existe um sistema de plugins, mas não há suporte direto para alterar a análise. Então, isso não seria uma coisa trivial de se fazer.

@dantman
Temos uma especificação para isso; existe um polyfill; O Chrome o implementou; A Polymer já o está usando em uma versão 1.0; e sites já estão usando o Polymer.

Para mim, esse ainda não é um motivo muito convincente. Isso se traduz em: Google, Google e Google estão usando isso. Não houve interesse em nenhum outro lugar, e não há indicações de que algum dia haverá.

Essa conclusão faria sentido se estivéssemos falando sobre uma sintaxe mais proprietária e sem suporte que se desviou significativamente do css normal; mas estamos falando sobre a geração de erros de análise de Less quando Less já entende aninhamento e a sintaxe em questão se encaixa perfeitamente dentro das regras de análise baseadas em correspondência de colchetes do CSS e não quebra o CSS ao redor, e o outro pré-processador e pós-processador principal CSS estão trabalhando apoiá-lo ou já trabalhar.

Essa conclusão faria sentido se estivéssemos falando sobre uma sintaxe mais proprietária e sem suporte que se desviou significativamente do css normal; mas estamos falando sobre a geração de erros de análise de Less quando Less já entende aninhamento e a sintaxe em questão se encaixa perfeitamente dentro das regras de análise baseadas em correspondência de colchetes do CSS e não quebra o CSS ao redor, e o outro pré-processador e pós-processador principal CSS estão trabalhando apoiá-lo ou já trabalhar.

Não é irrelevante. É muito semelhante aos conjuntos de regras desanexados de Less. E há precedentes para outras coisas "pass-thru" adicionadas a Less. Portanto, não sou necessariamente contra. Apenas cético se há valor além do Polymer no momento.

O suporte oficial para variáveis ​​CSS está listado aqui: http://caniuse.com/#feat = css-variables

Versão mínima do navegador para suporte de variável CSS padrão

  • Chrome 49
  • Chrome para Android 51
  • Navegador Android 51
  • Firefox para Android 47
  • Firefox 31
  • Safari 9.1
  • iOS Safari 9.3
  • Opera 36
  • Opera Mobile 37

Sem um polyfill, isso equivale a cerca de 65% do uso global do navegador.

Com múltiplas Variáveis ​​CSS Polyfills por aí, navegadores implementando-as e grandes provedores de navegadores pressionando por elas. Parece que esse seria um recurso valioso de se ter.

Especificações oficiais: https://drafts.csswg.org/css-variables/

@stramel Isso não tem nada a ver com esse problema. Variáveis ​​CSS já são suportadas em Less. A solicitação é sobre @apply , que não faz parte dessa especificação.

EDITAR: nem todos os valores de propriedade personalizada CSS são suportados, veja abaixo.

@matthew-dean Desculpe, eu entendi mal. Independentemente disso,: +1: para mixins CSS / conjuntos de propriedades personalizadas

@ matthew-dean qual é a barreira para menos suporte? Se outro navegador for implementado, está pronto para prosseguir?

@ donny-dont Como o Less é um projeto comunitário, não há uma barra específica. Mas sim, algo além de um único navegador o tornaria um recurso de uso mais geral.

Apenas se alguém estiver pesquisando isso (como eu fiz): você pode colocar todos os css não padrão do Polymer em um arquivo separado e importá-lo com a palavra-chave inline em seu arquivo less. O menos arquivo tem de interface entre menos variáveis ​​e propriedades personalizadas de polímero. Mas é assim que a Polymer quer, de qualquer maneira. Concordo que você não pode implementar todos os desvios dos padrões.

Só para revisitar isso, acho que, infelizmente, tive uma visão limitada do escopo do problema.

Isto é: sim, @apply é apenas uma proposta, MAS INDEPENDENTEMENTE, _isso_ _não_ é CSS inválido. Não mais.

paper-drawer-panel {
  --paper-drawer-panel-left-drawer: {
    background-color: red;
  };
}

Meu erro foi pensar que @apply estava propondo uma extensão para a sintaxe da propriedade personalizada, mas não é. O _IS_ acima é um valor de propriedade customizado válido e, como tal, deve ser adicionado ao suporte Less. Eu gostaria de ter dedicado um tempo para cavar mais fundo nas especificações. (Aqui: https://www.w3.org/TR/css-variables/#syntax.)

Less tem o objetivo principal de oferecer suporte a CSS válido, e a sintaxe de propriedade personalizada está totalmente implementada em todos os navegadores a partir de agora. A especificação é extremamente permissiva e pode exigir algumas grandes mudanças na maneira como os valores das propriedades são analisados. Você pode colocar quase qualquer coisa nele. O quão louco você pode ficar com valores e se os navegadores permitirão isso, não tenho certeza. Mas, da forma como li as especificações, quase tudo é válido se estiver bem formado. Ou seja, até encontrar um token de ponto-e-vírgula de "nível superior", você pode enlouquecer, envolvendo todos os tipos de coisas entre chaves ou parênteses.

Isso significa que as bibliotecas JavaScript como o Polymer estão cada vez mais propensas a "hackear" CSS para colocar propriedades / valores declarativos onde podem ser lidos por JS, o que realmente não era possível antes desse recurso CSS.

Portanto, 👍 para implementar o mais rápido possível.

Lamentamos aqueles que tentaram apontar que esta é a sintaxe de propriedade customizada válida.

Estou marcando isso como bug e solicitação de recurso porque a) Menos declarações para analisar valores de propriedades personalizadas, mas falha às vezes (mas não está claro quando), mas b) os tipos de valores que menos precisa lidar estão além do design original até mesmo o próprio CSS, quanto mais Less, por isso é um novo recurso.

Outro teste que pode ser adicionado a menos testes para análise de propriedade customizada. Este CSS é perfeitamente válido a partir de hoje.

.test {
  --custom-function: () => { let x = 1; window['NAMESPACE'].doSomething(x); };
}

Essencialmente, uma vez que algo está em () [] ou {} , você pode inserir quaisquer caracteres que desejar. Portanto, o ponto e vírgula passaria no exemplo acima. Requer alguma análise recursiva até que os colchetes sejam correspondidos e fechados (se / quando eles forem abertos) antes de você poder testar um ponto-e-vírgula de fechamento.

Comecei esse trabalho aqui, mas ainda não tenho certeza se isso está correto. https://github.com/less/less.js/blob/edge/lib/less/parser/parser.js#L1326

_Observação: para esclarecer se alguém está confuso ao olhar para a linha acima, este JavaScript não faria nada. CSS apenas o consideraria um valor anônimo longo e desconhecido._

Essencialmente, uma vez que algo está entre () [] ou {}, você pode inserir quaisquer caracteres que desejar.

mm, é isso? Para mim, https://www.w3.org/TR/css-variables/#syntax soa como qualquer token (exceto aqueles listados lá) pode estar em qualquer lugar lá (independentemente de qualquer tipo de parênteses). Ou isso é assumido por algum outro parágrafo? Poderia, por favor me aponte, onde ele diz sobre qualquer personagem, ou específica nada sobre valores dentro parens? (a menos que seja url(...) claro)?

Em outras palavras, --var: ?; , --var: (?); ou --var: [¾]; realmente válidos?

Esta é a seção relevante no topo, que posso estar interpretando mal.

A sintaxe permitida para propriedades customizadas é extremamente permissiva. A produção de <declaration-value> corresponde a qualquer sequência de um ou mais tokens, desde que a sequência não contenha <bad-string-token> , <bad-url-token> , <)-token> , <]-token> , ou <}-token> , ou tokens de nível superior <semicolon-token> ou <delim-token> tokens com um valor de "!".

Então, lições importantes são:

  1. Apenas o token de ponto-e-vírgula de nível superior é importante. Eu interpreto que significa "não está dentro de algum outro par compatível"? Mas posso estar interpretando mal o que significa "nível superior".

  2. Talvez o exemplo JS dado naquela página seja enganoso, ( -foo: if(x > 5) this.width = 10; é válido.) Mas um = espaçamento certamente não é um token CSS típico, nem this.width . Sem esclarecimento, e considerando o quão permissiva é a recuperação de erros em navegadores, não acho que podemos presumir qualquer erro de análise para nada. _Já sabemos_ que a sintaxe @apply é válida (com um conjunto de regras), mesmo que tenha um aplicativo personalizado. Portanto, sabemos que as propriedades personalizadas permitem vários pontos-e-vírgulas em {} ; portanto, é lógico que esta linguagem implique algo sobre a natureza permissiva dentro da correspondência () , [] , {} . Há muitas coisas que não sabemos aqui, e sem saber _o que_ pode ir em uma propriedade personalizada, acho que devemos assumir que qualquer coisa pode ir nela, contanto que siga uma estrutura particular ("contanto que a sequência não contém <bad-string-token> , <bad-url-token> , <)-token> , <]-token> , ou <}-token> "não correspondentes e passe essa propriedade para o navegador. Acredito que a intenção aqui é criar o máximo de flexibilidade para os desenvolvedores, enquanto cria os requisitos mínimos para uma análise bem-sucedida.

Então, você não pode fazer isso:

.bar {
  --foo: {;
  --baz: ";
}

... porque a sintaxe deseja permitir que você insira qualquer coisa, incluindo vários pontos-e-vírgulas, mas deseja saber quando terminar. É aí que as aspas / colchetes / parênteses / colchetes entram em jogo. Contanto que você possa indicar que "fechou" sua sintaxe de alguma forma, acredito que a intenção aqui é que você possa fazer o que quiser dentro dessa sintaxe.

Quanto a isso:

são qualquer um de --var:?;, --var: (?); ou --var: [¾]; válido?

Não sei.

Devemos tratá-los como válidos? IMO sim. Porque não sabemos / não podemos saber, mas _podemos_ analisá-lo com sucesso sem muitos problemas.

Quanto à possível implementação ... Não é um grande problema permitir qualquer coisa lá até ; mas então ainda devemos lidar com pelo menos strings, urls e {} aninhados (pois podem conter ; dentro). Obviamente, isso significaria nenhum código Less dentro.

Um passo adiante seria tratá-lo (no estágio de análise) como uma espécie de DR (sem seu {} externo) com apenas mais tokens permitidos (embora pareça um caminho morto, já que você pode ' t reutilize o analisador DR para algo como --var: (1 > 2) / {whatever} foo; )

E, finalmente, para algo mais conveniente, honestamente, não consigo ver nada além de escrever um tokeniser CSS completo com alguns dos recursos do Less (tokens e sua avaliação) permitidos. Um problema biiiiiiiig em outras palavras :(

Apenas o token de ponto-e-vírgula de nível superior é importante. Eu interpreto que significa "não está dentro de algum outro par compatível"? Mas posso estar interpretando mal o que significa "nível superior".

Sim, tenho quase certeza de que é sobre o encerramento de ; . Ou seja, como em: --var: ";" url(;) {;}; é válido e --var: ; {} foo; não (o primeiro ; por ser de "nível superior" encerra a instrução).
Não tenho certeza sobre apenas (;) embora.

Obviamente, isso significaria nenhum código Less dentro.

Meu único pensamento é que podemos permitir a sintaxe de interpolação, caso você queira gerar propriedades personalizadas. Mas talvez seja uma espécie de ideia do tipo "rodada 2 se houver interesse".

Não tenho certeza sobre apenas (;) embora.

Eu também não sou? Acredito que as especificações geralmente têm detalhes de análise publicados em algum lugar (como diagramas de caminho de token), mas não tenho certeza se existe neste caso. Como um estágio 1 - requer apenas a correspondência de {} , () e aspas, e despejando qualquer coisa em um nó anônimo até que um ; pareça bom. Os colchetes [] podem não ser necessários, mas eles também são mencionados e são bastante triviais, uma vez que todas as outras peças estão lá.

Não acho que precisamos tokenizar nada especialmente, ou misturar isso com o material de DR. Afinal, alguém pode acabar com:

.weird {
  --php: ($x = 5 /* + 15 */ + 5; echo $x;);
  --example: [My DR will be --this: { 
    blah: nope;
    --never mind i gave up;
    no wait here it --is: {
      lol: cats;
    }
  }];
}

Em outras palavras, seria melhor para Less limpar suas mãos para não lidar com o conteúdo das propriedades personalizadas.

Além disso, é tecnicamente viável para um autor de plug-in Less escrever um plug-in de visitante que pega partes e envia propriedades personalizadas correspondentes de volta por meio do analisador Less para criar novos nós. Tudo o que realmente devemos fazer é despejar o conteúdo em um nó de regra e marcar a regra como uma propriedade customizada, em seguida, despejar a saída com a mesma fidelidade.

Observe que, se modificarmos o exemplo acima, ISTO deve ser considerado inválido:

.weird {
  --example: [My DR will be --this: { 
    blah: nope;
    --never mind i gave up;
    no wait here it --is: {
      lol: cats;
   // missing matching }
  }];
}

"sem menos código"

Provavelmente, mas isso significa um downgrade - como agora se pode escrever:
--var: darken(red, 5%) + 1;
e funciona, mas (por causa de --fortran: read (*, *, iostat=ierr) radius, height; ) não :(

Podemos ter uma opção para isso provavelmente (como --oh-no-yet-another-option-for-custom-properties-to-be-parsed-one-way-or-another: on :)

Provavelmente, mas isso significa um downgrade - como agora pode-se escrever --var: darken (red, 5%); e funciona, mas então (por causa de --fortran: read (*, *, iostat = ierr) radius, height;) não irá :(

🤔 Bem ... sim, entendo o que você quer dizer, e é por isso que talvez seja necessário algum tipo de interpolação? Podemos basicamente no analisador tratar as coisas de maneira semelhante a:

<strong i="8">@iostat</strong>: ierr;
--fortran: read (*, *, iostat=@{iostat}) radius, height;

// treat similar to:
--fortran: ~"read (*, *, iostat=@{iostat}) radius, height";

(Com as advertências mencionadas de tokens de correspondência adequados?)

Quer dizer ... a alternativa é que essencialmente recomendamos a sintaxe de escape. Seria bom menos modificações no código CSS local.

Sim, a interpolação resolverá o problema. Embora ainda seria bom para um DR-ike analisar como uma opção experimental (eu tenho certeza que muitos vão preferir verdadeira --var: darken(red, 5%); a imaginária --javascript: 1 = 2; , pelo menos até que tal propriedade personalizada hackers se torna generalizado: )

Em outras palavras, estou bem com as duas formas (separadamente ou simultaneamente).

Acho que tenho uma implementação / solução bastante robusta para isso. Usei vários exemplos de código deste segmento em testes. Portanto, valores de propriedade customizada e regras at desconhecidas são essencialmente tratados como valores entre aspas de escape para permitir a interpolação. Confira # 3213.

Fixo.

Esta página foi útil?
0 / 5 - 0 avaliações