Less.js: Less échoue à analyser les valeurs de propriété personnalisée valides (ex: @apply polyfill)

Créé le 21 oct. 2015  ·  34Commentaires  ·  Source: less/less.js

Ce code casse:

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

Les accolades dans la valeur de la propriété interrompent l'analyseur.

J'aimerais que LESS prenne en charge la syntaxe @apply , telle qu'utilisée par Polymer.
https://www.polymer-project.org/1.0/docs/devguide/styling.html#custom -css-mixins

Également essayé:

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

Il n'a pas cassé l'analyseur mais livré:

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

ce qui n’est manifestement pas un comportement souhaitable.

bug feature request

Commentaire le plus utile

Nous avons une spécification pour cela; un polyfill existe; Chrome l'a implémenté; Polymer l'utilise déjà dans une version 1.0; et les sites Web utilisent déjà Polymer.

Je pense que c'est une attente parfaitement raisonnable pour Less pour prendre en charge la syntaxe à un niveau minimum.

Less passe déjà par @apply , --foo: bar; et var(--foo) . La seule chose qui manque est de faire passer Less à travers le { ... } dans --foo: { property: value; } avec le même traitement de base donné aux autres blocs css; au lieu de s'arrêter dur et de lancer une erreur d'analyse.

Tous les 34 commentaires

J'ai peur que la prise en charge de la syntaxe non-CSS dépasse la portée de Less. Donc mon -1.

Dans tous les cas, notez que vous pouvez émettre n'importe quel code dans la sortie avec échappement. Par exemple:

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

Ou d'une manière multiligne plus hackish:

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

Dans des situations plus complexes, il est également toujours possible d'utiliser <strong i="13">@import</strong> (inline) .


En ce qui concerne les tentatives comme %(~"%d", @ruleset); - Non, Less variables ne sont pas des macros, elles ne sont pas développées quel que soit le contexte, et spécifiquement pour les ensembles de règles sans nom, la seule syntaxe correcte est @ruleset() dans le corps d'un ensemble de règles et _pas_ comme une valeur de propriété.

Eh bien, je suis d'accord avec vous que la syntaxe non standard ne devrait généralement pas être prise en charge.

Cependant, cela signifie que LESS est incompatible avec Polymer dans de nombreux cas.

En tous cas merci de votre réponse. : +1:

Je ne sais pas si cela fait une différence dans votre décision @ seven-phases-max, mais il existe une spécification ouverte pour une règle @apply , http://tabatkins.github.io/specs/css-apply-rule/ #issue -882293bd.

Voir également https://github.com/Polymer/polymer/issues/1373 car cela ressemble à quelque chose que Google va vraiment pousser à travers le processus.

Et SASS semble résoudre ce problème https://github.com/sass/sass/issues/1128

@ donny-dont Remarque Je ne décide rien (je n'ai pas fermé la proposition) - Je ne suis qu'un critique.

Eh bien, Tab Atkins a généré _tens_ des propositions CSS standard (appelées « idées ») et alors que les gars de Google peuvent pousser ce dans leur navigateur même demain, cela est encore trop loin de devenir même chose projet CSS (souvenez - vous CSS vars non entrer dans le monde CSS depuis une dizaine d'années?).

@ sept phases-max excuses pour l'implication. Je voulais juste faire une note que Polymer pousse la proposition de mixin et Chrome est susceptible de l'implémenter une fois qu'il est mis en forme, ce que @Jamtis n'a pas vraiment communiqué.

Je suis assez nouveau dans l'utilisation de LESS. Existe-t-il une sorte de système de plugins pour l'analyseur dans ce genre de scénarios? Quelque chose comme un indicateur expérimental que vous pouvez activer et désactiver?

Je rouvre ceci pour pouvoir rediriger les demandes en double ici.

/sous

Nous avons une spécification pour cela; un polyfill existe; Chrome l'a implémenté; Polymer l'utilise déjà dans une version 1.0; et les sites Web utilisent déjà Polymer.

Je pense que c'est une attente parfaitement raisonnable pour Less pour prendre en charge la syntaxe à un niveau minimum.

Less passe déjà par @apply , --foo: bar; et var(--foo) . La seule chose qui manque est de faire passer Less à travers le { ... } dans --foo: { property: value; } avec le même traitement de base donné aux autres blocs css; au lieu de s'arrêter dur et de lancer une erreur d'analyse.

Je pense que la spécification complète des variables CSS devrait être prise en charge par LESS. J'adorerais que cela se produise!

@dantman

Nous avons une spécification pour cela; un polyfill existe; Chrome l'a implémenté; Polymer l'utilise déjà dans une version 1.0; et les sites Web utilisent déjà Polymer.

Pour moi, ce n'est toujours pas une raison très convaincante. Cela se traduit par: Google, Google et Google l'utilisent. Aucun intérêt n'a surgi ailleurs, et rien n'indique qu'il y en aura jamais.

@ donny-dont

Je suis assez nouveau dans l'utilisation de LESS. Existe-t-il une sorte de système de plugins pour l'analyseur dans ce genre de scénarios? Quelque chose comme un indicateur expérimental que vous pouvez activer et désactiver?

Il existe un système de plugins, mais pas de support direct pour modifier l'analyse. Donc, ce ne serait pas une chose insignifiante à faire.

@dantman
Nous avons une spécification pour cela; un polyfill existe; Chrome l'a implémenté; Polymer l'utilise déjà dans une version 1.0; et les sites Web utilisent déjà Polymer.

Pour moi, ce n'est toujours pas une raison très convaincante. Cela se traduit par: Google, Google et Google l'utilisent. Aucun intérêt n'a surgi ailleurs, et rien n'indique qu'il y en aura jamais.

Cette conclusion aurait du sens si nous parlions d'une syntaxe plus propriétaire et non prise en charge qui s'écartait considérablement du CSS normal; mais nous parlons de Moins d'erreurs d'analyse générant lorsque Less comprend déjà l'imbrication et que la syntaxe en question s'intègre parfaitement dans les règles d'analyse basées sur la correspondance des parenthèses CSS et ne rompt pas le CSS environnant, et que les autres préprocesseurs et postprocesseurs CSS majeurs travaillent sur le soutenir ou travailler déjà.

Cette conclusion aurait du sens si nous parlions d'une syntaxe plus propriétaire et non prise en charge qui s'écartait considérablement du CSS normal; mais nous parlons de Moins d'erreurs d'analyse générant lorsque Less comprend déjà l'imbrication et que la syntaxe en question s'intègre parfaitement dans les règles d'analyse basées sur la correspondance des parenthèses CSS et ne rompt pas le CSS environnant, et que les autres préprocesseurs et postprocesseurs CSS majeurs travaillent sur le soutenir ou travailler déjà.

Pas hors de propos. C'est assez similaire aux ensembles de règles détachés de Less. Et il y a un précédent pour d'autres trucs "pass-thru" ajoutés à Less. Je ne suis donc pas nécessairement contre. Juste sceptique s'il y a une valeur au-delà de Polymer pour le moment.

Le support officiel des variables CSS est répertorié ici: http://caniuse.com/#feat = css-variables

Version minimale du navigateur pour la prise en charge des variables CSS par défaut

  • Chrome 49
  • Chrome pour Android 51
  • Navigateur Android 51
  • Firefox pour Android 47
  • Firefox 31
  • Safari 9.1
  • iOS Safari 9.3
  • Opéra 36
  • Opera Mobile 37

Sans polyfill, cela équivaut à environ 65% d'utilisation globale du navigateur.

Avec plusieurs Polyfills variables CSS disponibles, les navigateurs l'implémentant et les grands fournisseurs de navigateurs qui le poussent. Il semble que ce serait une fonctionnalité précieuse à avoir.

Spécifications officielles: https://drafts.csswg.org/css-variables/

@stramel Cela n'a rien à voir avec ce problème. Les variables CSS sont déjà prises en charge dans Less. La requête est d'environ @apply , ce qui ne fait pas partie de cette spécification.

EDIT: toutes les valeurs de propriété personnalisée CSS ne sont pas prises en charge, voir ci-dessous.

@ matthew-dean Désolé, j'ai mal compris. Quoi qu'il en soit,: +1: pour les mixins CSS / les jeux de propriétés personnalisés

@ matthew-dean quelle est la barre pour moins de soutien? Si un autre navigateur est mis en œuvre, alors c'est bon?

@ donny-dont Comme Less est un projet communautaire, il n'y a pas de barre spécifique. Mais oui, quelque chose au-delà d'un seul navigateur en ferait une fonctionnalité plus générale.

Juste si quelqu'un cherche ceci (comme je l'ai fait): vous pouvez mettre tout le css non standard Polymer dans un fichier séparé et l'importer avec le mot-clé en ligne dans votre fichier less. Le moins de fichier doit s'interfacer entre moins de variables et les propriétés personnalisées du polymère. Mais c'est ce que veut Polymer, de toute façon. D'accord, vous ne pouvez pas mettre en œuvre tous les écarts par rapport aux normes.

Pour revenir sur ce point, je pense que j'avais malheureusement une vision étroite de l'ampleur du problème.

C'est-à-dire: oui, @apply est juste une proposition, MAIS IMPÉRATIVEMENT, _ce_ n'est pas_ un CSS invalide. Pas plus.

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

Mon erreur a été de penser que @apply proposait une extension de la syntaxe de la propriété personnalisée, mais ce n'est pas le cas. Le _IS_ ci-dessus est une valeur de propriété personnalisée valide et, en tant que tel, doit être ajouté à Less support. J'aurais aimé avoir pris le temps d'approfondir les spécifications. (Ici: https://www.w3.org/TR/css-variables/#syntax.)

Less a pour objectif principal de prendre en charge les CSS valides, et la syntaxe des propriétés personnalisées est entièrement implémentée dans chaque navigateur à partir de maintenant. La spécification est extrêmement permissive et peut nécessiter de grands changements dans la façon dont les valeurs de propriété sont analysées. Vous pouvez y mettre presque n'importe quoi. À quel point vous pouvez devenir fou avec les valeurs et si les navigateurs le permettent, je ne suis pas sûr. Mais, de la façon dont j'ai lu les spécifications, la plupart du temps, tout est valide s'il est bien formé. Autrement dit, jusqu'à ce que vous rencontriez un jeton point-virgule "de premier niveau", vous pouvez devenir fou, en enveloppant toutes sortes de choses entre accolades ou parenthèses.

Cela signifie que les bibliothèques JavaScript comme Polymer sont de plus en plus susceptibles de «pirater» CSS pour placer des propriétés / valeurs déclaratives là où elles sont lisibles par JS, ce qui n'était vraiment pas possible avant cette fonctionnalité CSS.

Donc, à la mise en œuvre dès que possible.

Désolé pour ceux qui ont essayé de souligner qu'il s'agit d'une syntaxe de propriété personnalisée valide.

Je marque cela à la fois comme un bogue et une demande de fonctionnalité car a) Moins de prétentions pour analyser les valeurs de propriétés personnalisées, mais échoue parfois (mais ce n'est pas clair quand), mais b) les types de valeurs Moins de besoins à gérer va au-delà de la conception originale même CSS lui-même, et encore moins Less, c'est donc une nouvelle fonctionnalité.

Un autre test qui peut être ajouté à Less tests pour l'analyse des propriétés personnalisées. C'est un CSS parfaitement valide à ce jour.

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

Essentiellement, une fois que quelque chose est dans () [] ou {} , vous pouvez vider les caractères de votre choix. Ainsi, les points-virgules passeraient dans l'exemple ci-dessus. Cela nécessite une analyse récursive jusqu'à ce que les accolades soient mises en correspondance et fermées (si / quand elles sont ouvertes) avant de pouvoir tester un point-virgule fermant.

J'ai commencé ce travail ici mais je ne sais pas encore si c'est correct. https://github.com/less/less.js/blob/edge/lib/less/parser/parser.js#L1326

_Remarque: pour clarifier si quelqu'un est confus à regarder la ligne ci-dessus, ce JavaScript ne ferait rien. CSS le considérerait simplement comme une longue valeur anonyme inconnue._

Essentiellement, une fois que quelque chose est entre () [] ou {}, vous pouvez vider les caractères de votre choix.

mm, c'est ça? Pour moi, https://www.w3.org/TR/css-variables/#syntax sonne comme n'importe quel jeton (à l'exception de ceux qui y sont répertoriés) peut être n'importe où (quel que soit le type de parenté). Ou cela est-il supposé par un autre paragraphe? Pourriez-vous, s'il vous plaît, m'indiquer où il est dit à propos d' un personnage ou de quelque chose de spécifique sur les valeurs à l' intérieur des parenthèses? (sauf si c'est url(...) bien sûr)?

En d'autres termes, est-ce que --var: ?; , --var: (?); ou --var: [¾]; réellement valides?

C'est la section pertinente en haut, que je mal interprète peut-être.

La syntaxe autorisée pour les propriétés personnalisées est extrêmement permissive. La production <declaration-value> correspond à n'importe quelle séquence d'un ou plusieurs jetons, tant que la séquence ne contient pas <bad-string-token> , <bad-url-token> , sans correspondance <)-token> , <]-token> , ou <}-token> , ou jetons <semicolon-token> niveau supérieur ou <delim-token> jetons avec une valeur de "!".

Les points à retenir sont donc:

  1. Seul le jeton point-virgule de niveau supérieur compte. J'interprète cela comme signifiant "pas dans une autre paire appariée"? Mais je pourrais mal interpréter ce que signifie «de haut niveau».

  2. Peut-être que l'exemple JS donné sur cette page est trompeur, ( -foo: if(x > 5) this.width = 10; est valide.) Mais un = non espacé n'est certainement pas un jeton CSS typique, pas plus que this.width . Sans clarification, et étant donné à quel point la récupération d'erreur est permissive sur les navigateurs, je ne pense pas que nous puissions supposer une erreur d'analyse pour quoi que ce soit. Nous _déjà_savons_ que la syntaxe @apply est valide (avec un ensemble de règles), même si elle a une application personnalisée. Nous savons donc que les propriétés personnalisées autorisent plusieurs points-virgules dans les limites de {} ; il est donc logique que ce langage implique quelque chose à propos de la nature permissive dans la correspondance () , [] , {} . Il y a beaucoup de choses que nous ne savons pas ici, et sans savoir ce qui peut aller dans une propriété personnalisée, je pense que nous devons supposer que tout peut y entrer, tant qu'il suit une structure particulière ("tant que la séquence ne contiennent <bad-string-token> , <bad-url-token> , inégalé <)-token> , <]-token> ou <}-token> ") et transmettez cette propriété au navigateur. Je crois que l'intention ici est de créer une flexibilité maximale pour les développeurs, tout en créant les exigences minimales minimales pour une analyse réussie.

Donc, vous ne pouvez pas faire ça:

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

... parce que la syntaxe veut vous permettre de mettre n'importe quoi, y compris plusieurs points-virgules, mais elle veut pouvoir savoir quand vous avez terminé. C'est là que les guillemets / accolades / parenthèses / crochets correspondants entrent en jeu. Tant que vous pouvez indiquer que vous avez "fermé" votre syntaxe d'une manière ou d'une autre, je crois que l'intention ici est que vous puissiez faire ce que vous voulez dans cette syntaxe.

Quant à ceci:

sont l'un ou l'autre de --var:?;, --var: (?); ou --var: [¾]; valide?

Je ne sais pas.

Devrions-nous les traiter comme valides? OMI oui. Parce que nous ne savons pas / ne pouvons pas savoir, mais nous _pouvons_ l'analyser avec succès sans trop de problèmes.

Quant à l'implémentation possible ... Ce n'est pas un gros problème de permettre quoi que ; mais nous devons tout de même gérer au moins les chaînes, les URL et les {} imbriqués (car ils peuvent contenir ; intérieur). Évidemment, cela ne signifierait pas moins de code à l' intérieur.

Une étape supplémentaire serait de le traiter (au stade de l'analyse) comme une sorte de DR (sans son {} externe) avec juste plus de jetons autorisés (bien que cela ressemble à une voie sans issue puisque vous pouvez ' t réutiliser l'analyseur DR pour quelque chose comme --var: (1 > 2) / {whatever} foo; )

Et enfin, pour quelque chose de plus pratique, je ne peux honnêtement rien voir d'autre que d'écrire un jeton CSS complet avec certaines des fonctionnalités Less (jetons et ensuite leur évaluation) autorisées. Un problème de biiiiiiiig en d'autres termes :(

Seul le jeton point-virgule de niveau supérieur compte. J'interprète cela comme signifiant "pas dans une autre paire appariée"? Mais je pourrais mal interpréter ce que signifie «de haut niveau».

Oui, je suis presque sûr qu'il s'agit de la fin de ; . Ie comme dans: --var: ";" url(;) {;}; est valide et --var: ; {} foo; ne l'est pas (le premier ; en étant "de niveau supérieur" met fin à l'instruction).
Cependant, je ne suis pas sûr de seulement (;) .

Évidemment, cela ne signifierait pas moins de code à l'intérieur.

Ma seule pensée est que nous pourrions peut-être autoriser la syntaxe d'interpolation, au cas où vous voudriez générer des propriétés personnalisées. Mais peut-être que c'est une sorte d'idée "ronde 2 s'il y a de l'intérêt".

Je ne suis pas sûr de juste (;).

Je ne le suis pas non plus? Je pense que les spécifications ont souvent des détails d'analyse publiés quelque part (comme des diagrammes de chemin de jetons), mais je ne suis pas sûr que cela existe dans ce cas. En tant qu'étape 1 - ne nécessitant que la correspondance de {} , () , et des guillemets, et de déposer quoi que ce soit dans un nœud anonyme jusqu'à ce qu'un ; niveau supérieur semble correct. Les parenthèses correspondantes [] peuvent ne pas être nécessaires, mais elles sont également mentionnées et c'est assez trivial une fois que toutes les autres pièces sont là.

Je ne pense pas que nous ayons besoin de tokeniser quoi que ce soit, ou de mélanger cela avec des trucs DR. Après tout, quelqu'un pourrait se retrouver avec:

.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;
    }
  }];
}

En d'autres termes, il vaudrait mieux que Less essuie ses mains pour s'occuper du contenu des propriétés personnalisées.

En outre, il est techniquement possible pour un auteur de plugin Less d'écrire un plugin visiteur qui prend des morceaux et renvoie les propriétés personnalisées correspondantes via l'analyseur Less pour créer de nouveaux nœuds. Tout ce que nous devons vraiment faire est de vider le contenu dans un nœud de règle et de marquer la règle comme une propriété personnalisée, puis de vider tout aussi fidèlement la sortie.

Notez que si nous modifions l'exemple ci-dessus, CECI devrait être considéré comme invalide:

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

"pas de code Less"

Probablement, mais cela signifie une rétrogradation - comme maintenant on peut écrire:
--var: darken(red, 5%) + 1;
et ça marche, mais alors (pour le bien de --fortran: read (*, *, iostat=ierr) radius, height; ) ça ne fonctionnera pas :(

Nous pouvons probablement avoir une option pour cela (comme --oh-no-yet-another-option-for-custom-properties-to-be-parsed-one-way-or-another: on :)

Probablement, mais cela signifie une rétrogradation - comme maintenant on peut écrire --var: darken (rouge, 5%); et ça marche, mais alors (pour le bien de --fortran: read (*, *, iostat = ierr) radius, height;) ça ne sera pas :(

🤔 Eh bien ..... oui je vois ce que tu veux dire, c'est pourquoi peut-être qu'une interpolation quelconque pourrait être nécessaire? Nous pourrions fondamentalement, au niveau de l'analyseur, traiter des choses similaires à:

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

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

(Avec les mises en garde susmentionnées concernant les jetons correspondants?)

Je veux dire ... l'alternative est que nous recommandons essentiellement d'échapper à la syntaxe. Ce serait bien pour moins de modifications du code CSS en place.

Oui, l'interpolation fera l'affaire. Bien que ce serait toujours bien d'utiliser une analyse DR-ike comme option expérimentale (je suis à peu près sûr que beaucoup préféreront le vrai --var: darken(red, 5%); à l'imaginaire --javascript: 1 = 2; au moins jusqu'à ce qu'un tel piratage de propriété personnalisée devienne généralisé: )

En d'autres termes, je suis d'accord dans les deux sens (séparément ou simultanément).

Je pense que j'ai une implémentation / solution assez robuste pour cela. J'ai utilisé un certain nombre d'exemples de code de ce fil dans les tests. Ainsi, les valeurs de propriété personnalisées et les règles at inconnues sont essentiellement traitées comme des valeurs échappées entre guillemets pour permettre l'interpolation. Découvrez # 3213.

Fixé.

Cette page vous a été utile?
0 / 5 - 0 notes

Questions connexes

bassjobsen picture bassjobsen  ·  6Commentaires

vecerek picture vecerek  ·  5Commentaires

rejas picture rejas  ·  6Commentaires

xblakestone picture xblakestone  ·  3Commentaires

Oskariok picture Oskariok  ·  6Commentaires