Подтвердить что ты не робот

Aurelia: шаблон проверки работоспособности html?

Недавно я спросил, почему самозакрывающиеся элементы не работают в системе шаблонов Aurelia; и это было потому, что самозакрывающиеся элементы недействительны html.

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

Вопрос: Есть ли какая-нибудь проблема для очистки шаблона Aurelia html в задаче gulp?

Я пробовал использовать:

  • gulp-htmlhint: не удалось получить ошибку при самозакрывающихся элементах
  • gulp-htmllint: не удалось настроить его; с настройками по умолчанию он взрывается с ошибками.
  • gulp-html5-lint: не выглядит настраиваемым, и он ненавидит атрибуты aurelia.
4b9b3361

Ответ 1

Мы можем решить проблему поиска и представления самозакрывающихся элементов parse5. Он имеет класс SAXParser, который должен быть достаточно прочным (parse5 соответствует стандартам html5). Синтаксический анализатор вызывает событие при поиске тегов начала, которое содержит логическое значение для того, закрывается ли найденный тег.

var parser = new SAXParser();

parser.on("startTag", (name, attrs, selfClosing)=>{
    if(selfClosing){ 
        //check if name is void, if not report error       
    }
});

parser.push(html);

Чтобы использовать эту функциональность, я создал проект, который можно использовать для того, чтобы помочь дезинфицировать html, используя вышеупомянутый подход. Разработанный инструмент lint способен выполнять выбор правил, собирать любые ошибки и возвращать их в качестве обещания. Это может быть сообщено пользователю.

Vanilla Html/Шаблоны

template-lint формирует базу набора инструментов. Он состоит из Linter и нескольких основных правил:

  • SelfClose - гарантировать, что непустые элементы не будут закрываться самостоятельно
  • Parser - возвращает ошибки для незакрытых или несогласованных элементов, которые были зафиксированы во время разбора

gulp-template-lint - это оболочка gulp для шаблона-линта и может быть использована следующим образом:

var gulp = require('gulp');
var linter = require('gulp-template-lint');

gulp.task('build-html', function () {
    return gulp.src(['source/**/*.html'])
        .pipe(linter())
        .pipe(gulp.dest('output'));
});

Пример

Учитывая следующий html:

<template>
  <custom-element/> 
  <svg>
    <rect/>
  </svg>
  <div>
    <div>
    </div>
</template>

дает:

введите описание изображения здесь

Примечание: самозакрывающийся <rect/> не вызывает ошибки. Элементы svg содержат xml, а правила могут различаться в зависимости от области.

Шаблоны Aurelia

Я изначально сделал aurelia-template-lint, но решил разделить компоненты многократного использования (вне аурелии) на template-lint. Хотя оба они в настоящее время разделены, у меня будет aurelia-template-lint на template-lint в установленном порядке. В настоящее время существует несколько правил, подтверждающих концепцию:

  • SelfClose - гарантировать, что непустые элементы не будут закрываться самостоятельно
  • Parser - возвращает ошибки для незакрытых или несогласованных элементов, которые были зафиксированы во время разбора
  • Шаблон - гарантировать, что root является элементом шаблона, и не более одного элемента шаблона.
  • RouterView - не разрешить элементу представления класса роутера содержать элементы контента.
  • Требовать - убедитесь, что elments имеют атрибут 'from'

существует оболочка gulp, которая может быть установлена ​​через:

npm install gulp-aurelia-template-lint

и используется в gulp сборке:

var linter = require('gulp-aurelia-template-lint');

gulp.task('lint-template-html', function () {
    return gulp.src('**/*.html')
        .pipe(linter())
        .pipe(gulp.dest('output'));
});

это будет использовать набор правил по умолчанию.

Пример

простой тест со следующим неправильным шаблоном aurelia:

<link/>
<template bindable="items">
<require from="foo"/>
<require frm="foo"/>

<br/>
<div></div>

<router-view>
  <div/>
</router-view>

</template>
<template>
</template>

выходы:

введите описание изображения здесь

Улучшения

есть много улучшений; например, существует несколько способов определения шаблонов ванили без тега <template>. Существует также немало специфических атрибутов, введенных Aurelia, которые можно было бы дезинфицировать.

Ответ 2

Учитывая, что никто еще не ответил; Я представляю решение "Лучше, чем ничего (возможно)" ™.

var gulp = require('gulp');
var gutil = require('gulp-util');

var voidTags = [
    'area', 'base', 'br', 'col', 'embed', 'hr', 
    'img', 'input', 'keygen', 'link', 'meta', 
    'param', 'source', 'track', 'wbr'];

var checkSelfClose = function () {
  function sanitize(file, cb) { 

    var dirty = String(file.contents);

    var matches = dirty.match(/(?:\<[\/\\\-\"\'!() a-z=.]+\/\>)/g);

    var customTags = [];

    if(matches && matches.length > 0)
    {       
        matches.forEach((match)=>{
            var tag = match.match(/[a-z\-]+/)[0];

            if(voidTags.indexOf(tag) < 0)
                customTags.push(tag);   
        });                   
    };

    if(customTags.length > 0)
        gutil.log('WARNING', 'found ' + customTags.length + " non-void self-closed tags in", 
        file.path.substring(file.cwd.length, file.path.Length),
        "tags:", customTags
        );

    cb(null, file);
  }
  return require('event-stream').map(sanitize);
}

gulp.task('build-html', function () {
    return gulp.src('source/**/*.html')
    .pipe(checkSelfClose())
    .pipe(gulp.dest('output'));
});

проверено с помощью:

<template bindable="items">
  <require from="./menu-bar.css" />

  <custom-element/>  
  <custom-element click.delegate="subitem.execute()" repeat.for="item of items" /> 
  <custom-element-moo></custom-element-moo>

  <br>
  <br/>

  <div id="blahblah"/>  

  <button class="dropbtn"/>
</template>

gulp вывод:

введите описание изображения здесь

[Обновление]

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