Ограничить значения примесей и создать исключение, если указано недопустимое значение.

У меня есть следующий Less mixin:

.box-sizing(@value) {
    -webkit-box-sizing: @value;
    -moz-box-sizing: @value;
    box-sizing: @value;
}

и я хотел бы разрешить только значения 'border-box' и 'content-box' в качестве параметра, иначе движок Less должен генерировать исключение. Как я могу этого добиться? Потому что без этой проверки я могу написать любое значение в миксин, и он будет работать, но он также будет генерировать неверный CSS, и никто не заметит, что есть ошибка.


person user1613797    schedule 31.05.2015    source источник


Ответы (2)


Насколько я знаю, нет способа заставить компилятор Less выдавать ошибку для недопустимого значения, как описано в вопросе. Однако вы можете сделать так, чтобы компилятор Less вообще не выдавал никаких выходных данных, когда предоставляется недопустимое значение, используя функция охраны.

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

.box-sizing(@value){
    & when (@value=content-box) , (@value=border-box){ /* comma is the or operator */
        -webkit-box-sizing: @value;
        -moz-box-sizing: @value;
        box-sizing: @value;
    }
}
#demo{
    .box-sizing(content-box);
}

В Less также есть несколько встроенных функций типов, которые можно использовать вместе с охранниками для проверки значение допустимо или нет (например, если ввод является числом или цветом и т. д.). Существует также функция iskeyword, но ни одна из них не проверяет недопустимое значение CSS.


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

@valid-values: content-box, border-box, padding-box;
.box-sizing(@value){
    .loop-valid-values(@index) when (@index > 0){
        @valid-value: extract(@valid-values, @index);
        & when (@value= @valid-value){
            -webkit-box-sizing: @value;
            -moz-box-sizing: @value;
            box-sizing: @value;
        }
        .loop-valid-values(@index - 1);
    }
    .loop-valid-values(length(@valid-values));
}
#demo{
    .box-sizing(content-box);
}

Строго не рекомендуется, но если вы настаиваете на том, чтобы компилятор генерировал то или иное исключение, когда предоставляется недопустимое значение, вы можете намеренно ввести ошибку в недопустимое-значение часть.

.box-sizing(@value){
    & when (@value= content-box), (@value= border-box){
        -webkit-box-sizing: @value;
        -moz-box-sizing: @value;
        box-sizing: @value;
    }
    & when not (@value= content-box), (@value= border-box){
        output: @bwahahaha; /* there is no such variable and hence when the input value is not valid, compiler will complain that variable is undefined */
    }
}
#demo{
    .box-sizing(conten-box);
}
person Harry    schedule 31.05.2015

Вы можете скрыть фактическую реализацию миксина под другим именем и предоставить только content-box/border-box перегрузки для .box-sizing:

// impl.:

.box-sizing(border-box)  {.box-sizing-impl(border-box)}
.box-sizing(content-box) {.box-sizing-impl(content-box)}
.box-sizing-impl(@value) {
    -webkit-box-sizing: @value;
    -moz-box-sizing: @value;
    box-sizing: @value;
}

// usage:

usage {
    .box-sizing(content-box); // OK
    .box-sizing(content-foo); // Error: No matching definition was found for `.box-sizing(content-foo)`
}

(В отличие от охранников, "сопоставление шаблона аргумента" (также известное как перегрузка) не пропускать молча, если не совпадают).

Немного менее повторяющийся вариант выше:

.box-sizing(@value) {
    .-(@value);
    .-(border-box)  {.ok}
    .-(content-box) {.ok}

    .ok() {
        -webkit-box-sizing: @value;
        -moz-box-sizing: @value;
        box-sizing: @value;
    }
}

Сообщение об ошибке менее описательно: No matching definition was found for '.-(content-foo)', поэтому лучше использовать .box-sizing_ или около того вместо .-.

-

Хотя идея тестировать каждый параметр миксина и выдавать ошибки, если он не подходит, довольно странная. (Собираетесь ли вы делать это для каждого миксина, который вы пишете? Это очень скучно...) Вместо этого вам лучше добавить какой-нибудь CSS-валидатор/lint в вашу цепочку сборки.

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

person seven-phases-max    schedule 31.05.2015
comment
Это интересно :) - person Harry; 31.05.2015
comment
Это должен быть принятый ответ. Это фантастика, и позволяет моей команде очень легко проверять ошибки, использует ли инженер правильные семейства шрифтов и веса!! - person Jason T Featheringham; 23.03.2017