Less.js: Less не может проанализировать допустимые значения настраиваемых свойств (например, @apply polyfill)

Созданный на 21 окт. 2015  ·  34Комментарии  ·  Источник: less/less.js

Этот код ломается:

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

Фигурные скобки в значении свойства прерывают работу анализатора.

Я бы хотел, чтобы LESS поддерживал синтаксис @apply , используемый Polymer.
https://www.polymer-project.org/1.0/docs/devguide/styling.html#custom -css-mixins

Также пробовал:

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

Он не сломал парсер, но доставил:

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

что явно нежелательно.

bug feature request

Самый полезный комментарий

У нас есть спецификация для этого; полифилл существует; Chrome реализовал это; Polymer уже использует его в версии 1.0; и веб-сайты уже используют Polymer.

Я думаю, что от Less вполне разумно ожидать поддержки синтаксиса на минимальном уровне.

Less уже проходит через @apply , --foo: bar; и var(--foo) . Единственное, чего не хватает, - это заставить Less пройти через { ... } в --foo: { property: value; } с той же базовой обработкой, что и другие блоки css; вместо того, чтобы резко остановиться и выдать ошибку синтаксического анализа.

Все 34 Комментарий

Боюсь, что поддержка синтаксиса, отличного от CSS, выходит за рамки Less. Итак, мой -1.

В любом случае обратите внимание, что вы можете выдавать любой код в вывод с экранированием. Например:

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

Или более хакерским многострочным способом:

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

В более сложных ситуациях всегда можно использовать <strong i="13">@import</strong> (inline) .


Что касается таких попыток, как %(~"%d", @ruleset); - Нет, переменные Less не являются макросами, они не раскрываются независимо от контекста, и специально для безымянных наборов правил единственный правильный синтаксис - @ruleset() в теле набора правил и _not_ как стоимость собственности.

Что ж, я согласен с вами, что нестандартный синтаксис вообще не должен поддерживаться.

Однако это означает, что LESS во многих случаях несовместим с полимером.

В любом случае спасибо за ответ. : +1:

Не уверен, что это влияет на ваше решение @ seven-phase-max, но есть открытая спецификация для правила @apply , http://tabatkins.github.io/specs/css-apply-rule/ #issue -882293bd.

Также см. Https://github.com/Polymer/polymer/issues/1373, поскольку похоже, что Google действительно собирается продвинуть этот процесс.

И SASS, похоже, обращается к этому https://github.com/sass/sass/issues/1128

@ donny-dont Заметьте, я ничего не решаю (не закрыл предложение) - я всего лишь критик.

Таб Аткинс создал _tens_ стандартных предложений CSS (названных "идеями"), и хотя ребята из Google могут отправить это в свой браузер даже завтра, это еще слишком далеко от того, чтобы стать даже черновиком CSS (помните, CSS vars not входит в мир CSS около десяти лет?).

@ seven-phase-max извиняюсь за подтекст. Я просто хотел отметить, что Polymer продвигает предложение о миксине, и Chrome, вероятно, реализует его, как только он будет сформирован, что было чем-то, о чем @Jamtis на самом деле не сообщал.

Я новичок в использовании LESS, есть ли какая-либо система плагинов для парсера в таких сценариях? Что-то вроде экспериментального флажка можно включать и выключать?

Я снова открываю это, чтобы иметь возможность перенаправлять сюда повторяющиеся запросы.

/ sub

У нас есть спецификация для этого; полифилл существует; Chrome реализовал это; Polymer уже использует его в версии 1.0; и веб-сайты уже используют Polymer.

Я думаю, что от Less вполне разумно ожидать поддержки синтаксиса на минимальном уровне.

Less уже проходит через @apply , --foo: bar; и var(--foo) . Единственное, чего не хватает, - это заставить Less пройти через { ... } в --foo: { property: value; } с той же базовой обработкой, что и другие блоки css; вместо того, чтобы резко остановиться и выдать ошибку синтаксического анализа.

Я думаю, что полная спецификация переменных CSS должна поддерживаться LESS. Хотелось бы, чтобы это случилось!

@dantman

У нас есть спецификация для этого; полифилл существует; Chrome реализовал это; Polymer уже использует его в версии 1.0; и веб-сайты уже используют Polymer.

Для меня это все еще не очень веская причина. Это означает: Google, Google и Google используют это. Больше нигде не было интереса, и нет никаких признаков того, что когда-либо будет.

@ donny-dont

Я новичок в использовании LESS, есть ли какая-либо система плагинов для парсера в таких сценариях? Что-то вроде экспериментального флажка можно включать и выключать?

Есть система плагинов, но нет прямой поддержки для изменения парсинга. Так что это было бы нетривиально.

@dantman
У нас есть спецификация для этого; полифилл существует; Chrome реализовал это; Polymer уже использует его в версии 1.0; и веб-сайты уже используют Polymer.

Для меня это все еще не очень веская причина. Это означает: Google, Google и Google используют это. Больше нигде не было интереса, и нет никаких признаков того, что когда-либо будет.

Этот вывод имел бы смысл, если бы мы говорили о более проприетарном и неподдерживаемом синтаксисе, который значительно отличается от обычного css; но мы говорим о том, что Less генерирует ошибки синтаксического анализа, когда Less уже понимает вложение, а рассматриваемый синтаксис идеально подходит для правил синтаксического анализа на основе соответствия скобок CSS и не нарушает окружающий CSS, а другие основные препроцессор и постпроцессор CSS также работают поддерживающие его или уже работающие.

Этот вывод имел бы смысл, если бы мы говорили о более проприетарном и неподдерживаемом синтаксисе, который значительно отличается от обычного css; но мы говорим о том, что Less генерирует ошибки синтаксического анализа, когда Less уже понимает вложение, а рассматриваемый синтаксис идеально подходит для правил синтаксического анализа на основе соответствия скобок CSS и не нарушает окружающий CSS, а другие основные препроцессор и постпроцессор CSS также работают поддерживающие его или уже работающие.

Не имеет значения. Это очень похоже на отдельные наборы правил Less. И есть прецедент для других "сквозных" вещей, добавленных в Less. Так что я не обязательно против. Просто скептически отношусь к тому, что в настоящий момент Polymer имеет ценность.

Официальная поддержка переменных CSS указана здесь: http://caniuse.com/#feat = css-variables

Минимальная версия браузера для поддержки переменных CSS по умолчанию

  • Хром 49
  • Chrome для Android 51
  • Браузер Android 51
  • Firefox для Android 47
  • Firefox 31
  • Safari 9.1
  • iOS Safari 9.3
  • Опера 36
  • Opera Mobile 37

Без полифилла это примерно равно 65% глобального использования браузера.

Имея множество полифилов переменных CSS, браузеры реализуют это, а крупные поставщики браузеров настаивают на этом. Похоже, это была бы ценная функция.

Официальная спецификация: https://drafts.csswg.org/css-variables/

@stramel Это не имеет отношения к этой проблеме. Переменные CSS уже поддерживаются в Less. Запрос касается @apply , что не является частью этой спецификации.

РЕДАКТИРОВАТЬ: поддерживаются не все значения настраиваемых свойств CSS, см. Ниже.

@ matthew-dean Простите, я неправильно понял. В любом случае: +1: для миксинов CSS / настраиваемых наборов свойств

@ matthew-dean какова планка при меньшей поддержке? Если будет реализован другой браузер, тогда можно?

@ donny-dont Поскольку Less - это проект сообщества, особой панели нет. Но да, что-то помимо одного браузера сделало бы эту функцию более универсальной.

Просто, если кто-то ищет это (как я): вы можете поместить весь нестандартный CSS-код Polymer в отдельный файл и импортировать его с помощью ключевого слова inline в свой файл less. Файл less должен взаимодействовать между меньшим количеством переменных и настраиваемыми свойствами полимера. Но в любом случае это то, чего хочет Полимер. Согласитесь, вы не можете реализовать все отклонения от стандартов.

Чтобы вернуться к этому, я, к сожалению, имел узкое представление о масштабах проблемы.

То есть: да, @apply - это просто предложение, НО НЕЗАВИСИМО, _это_ _не_ недопустимый CSS. Уже нет.

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

Моя ошибка заключалась в том, что я думал, что @apply предлагает расширение синтаксиса настраиваемого свойства, но это не так. Вышеупомянутое _IS_ является допустимым значением настраиваемого свойства и, как таковое, должно быть добавлено в поддержку Less. Мне жаль, что я не нашел время, чтобы углубиться в спецификацию. (Здесь: https://www.w3.org/TR/css-variables/#syntax.)

Основная цель Less - поддержка действительного CSS, а синтаксис настраиваемых свойств на данный момент полностью реализован в каждом браузере. Спецификация чрезвычайно разрешительна и может потребовать серьезных изменений в способе анализа значений свойств. Вы можете положить в него что угодно. Насколько безумно можно сходить с ума со значениями и позволяют ли это браузеры, я не уверен. Но, как я читаю спецификацию, в основном все правильно, если оно правильно оформлено. Это означает, что до тех пор, пока вы не встретите токен с точкой с запятой «верхнего уровня», вы можете сходить с ума, заключая все виды вещей в фигурные скобки или круглые скобки.

Это означает, что библиотеки JavaScript, такие как Polymer, все чаще «взламывают» CSS для размещения декларативных свойств / значений там, где они читаются JS, что было действительно невозможно до появления этой функции CSS.

Итак, приступим к реализации как можно скорее.

Извините тех, кто пытался указать, что это допустимый синтаксис настраиваемого свойства.

Я отмечаю это и как ошибку, и как запрос функции, потому что а) меньше заявлений о синтаксическом анализе значений настраиваемых свойств, но иногда не удается (но неясно, когда), но б) типы значений, которые необходимо обрабатывать, выходят за рамки исходного дизайна даже сам CSS, не говоря уже о Less, так что это новая функция.

Еще один тест, который можно добавить в Less tests для синтаксического анализа настраиваемых свойств. Это совершенно действующий CSS на сегодняшний день.

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

По сути, как только что-то находится в () [] или {} , вы можете выгружать любые символы, которые хотите. Итак, в приведенном выше примере будут передаваться точки с запятой. Это требует некоторого рекурсивного синтаксического анализа, пока фигурные скобки не будут сопоставлены и закрыты (если / когда они открыты), прежде чем вы сможете проверить закрывающую точку с запятой.

Я начал эту работу здесь, но еще не уверен, правильно ли это. https://github.com/less/less.js/blob/edge/lib/less/parser/parser.js#L1326

_Примечание: чтобы прояснить, если кто-то запутается, глядя на приведенную выше строку, этот JavaScript ничего не ДЕЛАЕТ. CSS просто сочтет это длинным неизвестным анонимным значением.

По сути, если что-то находится в () [] или {}, вы можете добавить любые символы, которые захотите.

мм, это так? Для меня https://www.w3.org/TR/css-variables/#syntax звучит так, как будто любой токен (кроме перечисленных там) может быть где угодно (независимо от любого типа паролей). Или это предполагает какой-то другой абзац? Не могли бы вы указать мне, где говорится о каком-либо символе или что-нибудь конкретное о значениях внутри скобок? (если, конечно, это не url(...) )?

Другими словами, действительно ли действительны --var: ?; , --var: (?); или --var: [¾]; ?

Это соответствующий раздел вверху, который я могу неправильно интерпретировать.

Разрешенный синтаксис для настраиваемых свойств чрезвычайно разрешен. Результат <declaration-value> соответствует любой последовательности из одного или нескольких токенов, если последовательность не содержит <bad-string-token> , <bad-url-token> , несовпадающих <)-token> , <]-token> , или <}-token> , или токены верхнего уровня <semicolon-token> или токены <delim-token> со значением "!".

Итак, важные выводы:

  1. Только точка с запятой верхнего уровня имеет значение. Я интерпретирую это как означающее «не в какой-то другой подобранной паре»? Но я мог неверно истолковать, что означает «высший уровень».

  2. Возможно, приведенный на этой странице пример JS вводит в заблуждение (допустима -foo: if(x > 5) this.width = 10; .) Но = без пробелов определенно не является типичным токеном CSS, равно как и this.width . Без разъяснений и с учетом того, насколько разрешено восстановление ошибок в браузерах, я не думаю, что мы можем предполагать какие-либо ошибки синтаксического анализа для чего-либо. Мы _ уже знаем_, что синтаксис @apply действителен (с набором правил), даже если он имеет собственное приложение. Итак, мы знаем, что настраиваемые свойства допускают использование нескольких точек с запятой в пределах {} ; поэтому логично, что этот язык подразумевает что-то о разрешительном характере соответствия () , [] , {} . Мы многого здесь не знаем, и, не зная, _ что_ может входить в настраиваемое свойство, я думаю, мы должны предположить, что в него может входить что угодно, пока оно следует определенной структуре ("пока последовательность не содержат <bad-string-token> , <bad-url-token> , несовпадающие <)-token> , <]-token> или <}-token> ") и передают это свойство браузеру. Я считаю, что здесь цель состоит в том, чтобы создать максимальную гибкость для разработчиков, создав при этом минимальные требования для успешного синтаксического анализа.

Итак, вы не можете этого сделать:

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

... потому что синтаксис позволяет вам вводить что угодно, включая несколько точек с запятой, но он хочет знать, когда вы закончите. Вот здесь и вступают в игру соответствующие кавычки / фигурные скобки / круглые скобки / скобки. Пока вы можете указать, что вы каким-то образом «закрыли» свой синтаксис, я считаю, что намерение здесь состоит в том, что вы можете делать то, что хотите, в этом синтаксисе.

Что касается этого:

либо --var:?;, --var: (?); или --var: [¾]; действительный?

Я не знаю.

Следует ли рассматривать их как действительные? ИМО да. Потому что мы не знаем / не можем знать, но мы _ можем_ успешно проанализировать его без особых проблем.

Что касается возможной реализации ... Это не большая проблема - разрешить что-либо там до ; но тогда мы все равно должны обрабатывать как минимум строки, URL-адреса и вложенные {} (поскольку они могут содержать ; внутри). Очевидно, это будет означать, что внутри

Следующим шагом было бы рассматривать его (на этапе синтаксического анализа) как своего рода DR (без его внешнего {} ) с разрешенным только большим количеством токенов (хотя это выглядит как мертвый путь, поскольку вы можете '' t повторно использовать DR-парсер для чего-то вроде --var: (1 > 2) / {whatever} foo; )

И, наконец, для чего-то более удобного я, честно говоря, ничего не вижу, кроме написания полнофункционального CSS-токенизатора с некоторыми разрешенными функциями Less (токены и их оценка). Другими словами, проблема biiiiiiiig :(

Только точка с запятой верхнего уровня имеет значение. Я интерпретирую это как означающее «не в какой-то другой подобранной паре»? Но я мог неверно истолковать, что означает «высший уровень».

Да, я почти уверен, что речь идет о прекращении действия ; . То есть, как в: --var: ";" url(;) {;}; является допустимым, а --var: ; {} foo; - нет (первый ; , будучи «верхним уровнем», завершает оператор).
Я не уверен насчет всего (;) .

Очевидно, это будет означать отсутствие кода внутри.

Моя единственная мысль заключается в том, что мы могли бы разрешить синтаксис интерполяции, если вы хотите сгенерировать настраиваемые свойства. Но, возможно, это своего рода идея «второго раунда, если есть интерес».

Я не уверен, что просто (;).

Я тоже нет? Я считаю, что в спецификациях часто публикуются детали анализа (например, схемы путей токенов), но я не уверен, существует ли это в данном случае. В качестве этапа 1 - требуется только соответствие {} , () и кавычки, а также сброс чего-либо в анонимный узел до тех пор, пока ; верхнего уровня не покажется в порядке. Соответствующие скобки [] могут и не понадобиться, но они также упоминаются, и это довольно тривиально, когда есть все остальные части.

Я не думаю, что нам нужно что-либо специально токенизировать или смешивать это с вещами DR. В конце концов, у кого-то может получиться:

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

Другими словами, для Less было бы лучше вытереть руки, чтобы иметь дело с содержимым настраиваемых свойств.

Кроме того, для автора плагина Less технически возможно написать плагин посетителя, который берет части и отправляет соответствующие настраиваемые свойства обратно через синтаксический анализатор Less для создания новых узлов. Все, что нам действительно нужно сделать, это выгрузить содержимое в узел правила и пометить правило как настраиваемое свойство, а затем точно так же точно выгрузить вывод.

Обратите внимание, что если мы изменим приведенный выше пример, ЭТО будет считаться недействительным:

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

"Нет меньше кода"

Наверное, но это означает понижение версии - вроде теперь можно написать:
--var: darken(red, 5%) + 1;
и работает, но тогда (ради --fortran: read (*, *, iostat=ierr) radius, height; ) не будет :(

Вероятно, у нас может быть вариант (например, --oh-no-yet-another-option-for-custom-properties-to-be-parsed-one-way-or-another: on :)

Возможно, но это означает переход на более раннюю версию - как сейчас можно написать --var: darken (red, 5%); и он работает, но тогда (ради --fortran: read (*, *, iostat = ierr) radius, height;) не будет :(

🤔 Ну ... да, я понимаю, что вы имеете в виду, поэтому, возможно, может потребоваться какая-то интерполяция? Мы могли бы в парсере обрабатывать вещи примерно так:

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

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

(С вышеупомянутыми оговорками о правильном сопоставлении токенов?)

Я имею в виду .... альтернативой является то, что мы рекомендуем избегать синтаксиса. Было бы неплохо для меньшего количества модификаций кода CSS на месте.

Да, интерполяция поможет. Хотя было бы неплохо для парсинга DR-ike в качестве экспериментального варианта (я почти уверен, что многие предпочтут реальный --var: darken(red, 5%); воображаемому --javascript: 1 = 2; по крайней мере до тех пор, пока такой взлом пользовательских свойств не станет широко распространенным: )

Другими словами, меня устраивают оба способа (по отдельности или одновременно).

Я думаю, что у меня есть довольно надежная реализация / решение для этого. Я использовал несколько примеров кода из этой ветки в тестах. Таким образом, значения настраиваемых свойств и неизвестные at-правила по сути обрабатываются как экранированные значения в кавычках, чтобы разрешить интерполяцию. Проверьте № 3213.

Фиксированный.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги