Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#286: Remove percent sign for zero-values percentages when safe #361

Closed
wants to merge 10 commits into from

Conversation

RubaXa
Copy link
Contributor

@RubaXa RubaXa commented Oct 31, 2017

Короче, суть: isEqualValuePair — отстой и решает проблему только частично, потому что дальше код всё равно проходит через require('css-tree').translate, который делает всё правильно и сохраняет единицы измерения, но... а данном случае они не нужны, единицы должен отбрасывать CSSO.

Поэтому мне кажется, сравнивать через isEqualValuePair не такой уж и отстой, осталось только как-то добавить в 4-restructShorthand.js, что если свойство из MAIN_PROPERTY и оно === '0', то поменять (или заменить) тип ноды на Number.

Ну или «Миша, всё не очень, давай по новой»...

@coveralls
Copy link

coveralls commented Oct 31, 2017

Coverage Status

Coverage increased (+0.0005%) to 99.368% when pulling 38f8d03 on RubaXa:ugly-zero-value-workaround into c360782 on css:master.

// Zero-value workaround
(left.node.value === '0' && left.node.value === right.node.value) ||
// Because `CSSTree` returning `0%`, `0px` and etc, but must just `0`
(translate(left.node) === translate(right.node))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Всё же мне кажется, что тут совсем не нужен CSSTree, а проверка должна быть такой:

return (
  (left.node.value === right.node.value) &&
  (left.node.value === '0' || left.node.type === right.node.type)
);

Copy link
Member

@lahmatiy lahmatiy Nov 1, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Думаю нужно в CSSTree реализовать функцию compare(node, node) ;)
Сравнивать через translate не очень круто в целом

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

compare(node, node) всё же нет, ноды-то разные, просто ноль исключение.

@lahmatiy
Copy link
Member

lahmatiy commented Nov 1, 2017

Привет! Спасибо за PR!
Но решение не в том месте. Проблема не только с TRLB свойствами, а в целом – остаются проценты со значением 0, что местами мешает мержу.

// Because `CSSTree` returning `0%`, `0px` and etc, but must just `0`

CSSTree возвращает то, что написали в CSS ;) А вот CSSO уже выкидывает ненужное. Собственно он откидывает единицы измерения у дименшенов с нулем, если эта единица измерения про длину – это относительно несложно. А вот процент откинуть сложнее, для этого нужно знать про что этот процент про длину, а он может быть про что угодно.
Было бы правильно решить проблему "раз и навсегда", использовав возможность CSSTree по вычислению назначения ноды в значении (то есть ее роль). Я тут понял, что просто забыл про этот issue, когда его создавали еще не было CSSTree как отдельного проекта, и матчинга в нем не было – теперь есть :)
Тем не менее матчинг пока мало поможет. Потому как сложно определить, что процент про длину: в синтаксисах он указывается, например для длины, [<length> || <percentage> || auto]. То есть нужно искать в каких группах встречается percentage вместе с length и если матчится группа, то процент засчитывать про длину. Но на данный момент это нетривиальная задача.
Думаю более простым решением будет закостылять набор свойств (типа margin/padding/width/height/etc), и убирать процент хотя бы в них. Возможно так и нужно пока сделать. Другими словами, нужно: добавить в replace новый обработчик на Percent, который конвертит ноду в Number, если value равно нулю и this.property.name одно из списка. Список можно подобрать из словарей CSSTree (см в секции Used by элементы вида <'property-name'> – с кавычками это свойства, без – типы):

Если откинуть проценты у нулей, то изменения в 4-restructShorthand будут не нужны.

@@ -0,0 +1 @@
.a,.b{margin:0%}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Правильный ответ должен быть margin:0

@RubaXa
Copy link
Contributor Author

RubaXa commented Nov 1, 2017

@lahmatiy Всё так, но я считаю, CSSTree всё правильно сделал, оптимизировать и тем более что-то отбрасывать задача csso, так что то по-моему тут всё же надо просто выпилить обработку через CSSTree и restructShorthand.js добавить логику для нулей, как и сделано с TLBR

@lahmatiy
Copy link
Member

lahmatiy commented Nov 1, 2017

Я наверное плохо донес мысль

добавить в replace новый обработчик на Percent, который конвертит ноду в Number, если value равно нулю и this.property.name одно из списка

Имелось ввиду сделать аналог https://github.com/css/csso/blob/master/lib/replace/Dimension.js, но для Percent – тогда restructShorthand трогать не придется, он и так справится

@RubaXa RubaXa changed the title #286: Zero-value workaround for pading, margin and etc #286: Zero-value workaround for pading and margin Nov 2, 2017
@coveralls
Copy link

coveralls commented Nov 2, 2017

Coverage Status

Coverage increased (+0.003%) to 99.371% when pulling 5890c1f on RubaXa:ugly-zero-value-workaround into c360782 on css:master.

@RubaXa
Copy link
Contributor Author

RubaXa commented Nov 2, 2017

@lahmatiy аааа, только вот если добавить обработку Percent, взрываются тесты, потому что реплейсер дляcolor проверяет, что аргументы должны быть гомогенными, а как понять, что это значение именно value от margin я не понял, у ноды нет ссылки на parent (ну либо я слеп), поэтому сделал обработку декларации:
https://github.com/css/csso/pull/361/files#diff-8392cfbdaad322e9a3d015e07457327b

ps так себе из меня помошник ;]

@coveralls
Copy link

coveralls commented Nov 2, 2017

Coverage Status

Coverage increased (+0.003%) to 99.371% when pulling 5890c1f on RubaXa:ugly-zero-value-workaround into c360782 on css:master.

@coveralls
Copy link

coveralls commented Nov 2, 2017

Coverage Status

Coverage increased (+0.005%) to 99.372% when pulling d41462a on RubaXa:ugly-zero-value-workaround into c360782 on css:master.

@lahmatiy
Copy link
Member

lahmatiy commented Nov 2, 2017

только вот если добавить обработку Percent, взрываются тесты

поэтому нужно делать только для определенных свойств и если это не внутри функции

а как понять, что это значение именно value от margin я не понял, у ноды нет ссылки на parent

Я не просто так отправлял на, там это есть: https://github.com/css/csso/blob/master/lib/replace/Dimension.js#L39 ;)
Внутри функции волкера: this.declaration ссылка на Declaration (если внутри декларации), this.function – если внутри функции (подробнее).

@RubaXa
Copy link
Contributor Author

RubaXa commented Nov 2, 2017

@lahmatiy блин, видно что-то я не так сделал и в прошлый раз у меня там declaration был null, а сейчас да, вижу :|

@@ -0,0 +1,21 @@
var INDENT_PROPS = ['margin', 'padding'].reduce(function(ind, prop) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

А как же другие свойства?

Список можно подобрать из словарей CSSTree (см в секции Used by элементы вида <'property-name'> – с кавычками это свойства, без – типы):

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

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Странно, а почему в этом списке нет left, top, но есть position?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Аааа, кажись понял ;]


node.value = value;

if (value === '0' && this.declaration !== null && this.atrulePrelude === null) {
if (node.type === 'Percentage') {
if (PERCENTAGE_LENGTH_DELC.hasOwnProperty(decl) || PERCENTAGE_LENGTH_FN.hasOwnProperty(fnName)) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lahmatiy оно?

@coveralls
Copy link

coveralls commented Nov 2, 2017

Coverage Status

Coverage increased (+0.004%) to 99.371% when pulling 0e5166e on RubaXa:ugly-zero-value-workaround into c360782 on css:master.

@lahmatiy
Copy link
Member

lahmatiy commented Nov 2, 2017

Здорово, то что нужно!
Только не стоит объединять обработчики в один. Во-первых, так сложнее в последствии искать где делает трансформация. Во-вторых, в функции появляется ненужное ветвление и она становится полиморфной. Давай сделаем оставим два модуля Dimension.js & Percentage.js?

@RubaXa
Copy link
Contributor Author

RubaXa commented Nov 2, 2017

@lahmatiy да не вопрос, только даже если тебе понравиться, не мэржди это, слишком много мусора в комитах.

@RubaXa
Copy link
Contributor Author

RubaXa commented Nov 2, 2017

Готово ;]

@coveralls
Copy link

coveralls commented Nov 2, 2017

Coverage Status

Coverage increased (+0.005%) to 99.373% when pulling 362ca2b on RubaXa:ugly-zero-value-workaround into c360782 on css:master.

@@ -0,0 +1,80 @@
var packNumber = require('./Number').pack;
var PERCENTAGE_LENGTH_DELC = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PERCENTAGE_LENGTH_DELC -> PERCENTAGE_LENGTH_PROPERTY

'transform-origin': true,
'word-spacing': true
};
var PERCENTAGE_LENGTH_FN = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PERCENTAGE_LENGTH_FN -> PERCENTAGE_LENGTH_FUNCTION


node.value = value;

if (PERCENTAGE_LENGTH_DELC.hasOwnProperty(decl) || PERCENTAGE_LENGTH_FN.hasOwnProperty(fnName)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Нужно поменять местами условия, сначала проверяем на ноль, а потом контекст. Проверка по словарю гораздо дороже, и нужна только для нулей, которые в целом не так часто встречаются.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Кста, я в своё время сравнивал hasOwnProperty vs obj[name] !== void 0 и второй выиграл, а Егоров (оочень давно) говорил мне, что v8 строгое сравнение с void 0 по особому выполняет, поэтому и быстро.

node.value = value;

if (PERCENTAGE_LENGTH_DELC.hasOwnProperty(decl) || PERCENTAGE_LENGTH_FN.hasOwnProperty(fnName)) {
// Zero-value workaround
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Комментарий не нужен – это решение, а не workaround ;)

@lahmatiy
Copy link
Member

lahmatiy commented Nov 2, 2017

Было бы круто добавить пару тестов – на проверку свойств в которых делается подмена, и проверку функций. То есть:

.test {
    width: 0%;
    height: 0%;
    ...
}

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

Для этого есть Squash and merge – все комиты объединятся в один ;)

@coveralls
Copy link

coveralls commented Nov 2, 2017

Coverage Status

Coverage increased (+0.005%) to 99.373% when pulling 3ce2933 on RubaXa:ugly-zero-value-workaround into c360782 on css:master.

@RubaXa
Copy link
Contributor Author

RubaXa commented Nov 2, 2017

Было бы круто добавить пару тестов

Это да, это тоже одна из причин не брать ветку, а squash нафиг, название ветки, тоже надо сменить ;]

Обновил PR, добавил проверку на null

PS Слушай, а ведь можно выкинуть проверку на hasOwnProp совсем и перейти на кода генерацию, просто развернуть словарь в функцию, типа:

var PERCENTAGE_LENGTH_DELC = {...};
var isPercentageLengthDecl = generateIsMethodByMap(PERCENTAGE_LENGTH_DELC);

function generateByDict(dict) {
  var body = Object.keys(dict).map(function(key) {
      return 'case ' + JSON.stringify(key) + ': return true;';
  }).join('\n');

  return Function('prop', 'switch (prop){' + body + ';} return false;');
}

м? я вот люблю кодогенерацию ;]

@lahmatiy
Copy link
Member

lahmatiy commented Nov 2, 2017

Я думал о таком решении, да. Имхо лучше генерировать код статически, чем динамически.
Но в любом случае, на данный момент кодогенерация это оверкилл.

@coveralls
Copy link

coveralls commented Nov 2, 2017

Coverage Status

Coverage increased (+0.005%) to 99.373% when pulling f314bfb on RubaXa:ugly-zero-value-workaround into c360782 on css:master.


module.exports = function compressPercentage(node, item) {
var value = packNumber(node.value, item);
var decl = this.declaration !== null ? this.declaration.property : null;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

decl -> property

@lahmatiy
Copy link
Member

lahmatiy commented Nov 2, 2017

Тесты добавишь? :)

@RubaXa
Copy link
Contributor Author

RubaXa commented Nov 2, 2017

Конечно, только скажи куда или по какому принципу?
Свойств много, все они разные.

@lahmatiy
Copy link
Member

lahmatiy commented Nov 2, 2017

Я тут обнаружил, что для height, max-height, width и max-width нельзя удалять %
clean-css/clean-css#957
Хотя у тебя почему то их и нет в списке...

Тест с перечнем всех свойств и функций, для которых убираем процент

@RubaXa
Copy link
Contributor Author

RubaXa commented Nov 2, 2017

Тест с перечнем всех свойств и функций, для которых убираем процент
окей

Я тут обнаружил, что для height, max-height, width и max-width нельзя удалять %
clean-css/clean-css#957

Чест говоря, это из серии css is awesome

@RubaXa
Copy link
Contributor Author

RubaXa commented Nov 2, 2017

Хотя если подумать, это даже логично :|

@lahmatiy lahmatiy changed the title #286: Zero-value workaround for pading and margin #286: Remove percentage for zero-values when safe Nov 2, 2017
@lahmatiy lahmatiy changed the title #286: Remove percentage for zero-values when safe #286: Remove percent sign for zero-values percentages when safe Nov 2, 2017
@RubaXa
Copy link
Contributor Author

RubaXa commented Nov 2, 2017

#363

@RubaXa RubaXa closed this Nov 2, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants