Тема: Snakeskin
Показать сообщение отдельно
  #73 (permalink)  
Старый 07.01.2014, 18:31
Аватар для kobezzza
Быдлокодер;)
Отправить личное сообщение для kobezzza Посмотреть профиль Найти все сообщения от kobezzza
 
Регистрация: 19.11.2010
Сообщений: 4,338

Фух, почти закончил работу над новой версией, вышло дольше чем думал. На этой недели закончу, но уже предлагаю поиграться с бетой и заодно потестить : http://jsfiddle.net/NAPWB/6/.

С функциональной стороны сделано всё, что хотел, и даже больше, однако ещё нужно написать новые тесты, обновить доку и т.д.

Ну а теперь по порядку. Изначально данный апдейт планировался как эволюционное развитие ветки 2.x, однако в ходе разработки, стало ясно, что необходимы некоторые принципиальные изменения, которые повлекут за собой несовместимость с предыдущей версией, поэтому новая версия выйдет как 3.0.0.

Что изменилось по сравнению с 2.x:

1) Реализована блочная область видимости переменных вместо единой шаблонной, т.е.

{template foo()}
    {if 1}
        {var a = 1}
        {a} /// 1
    {/}

    {a} /// error, a is not defined
{/}


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

2) Переосмыслена и переделана работа с пробельными символами: теперь любой пробельный символ (будь то табуляция или переход строки) трактуются как пробел, однако смежные пробельные символы схлопываются в один, т.е.

{template foo()}
/// перевод строки даст пробел
<div
class="foo">
{/}


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

{template foo()}
   Привет{&}                 Мир! /// получится ПриветМир!
{/}


3) Директивы cut и save были убраны, а их функционал частично заменила новая директива placeholder. Эта директива имеет одинаковый синтаксис с директивой template, однако, в отличии от template, placeholder существует только на этапе трансляции, т.е.

{placeholder foo()}
   foobar
{/}


foo(); // error


Директива может участвовать в цепи наследований также, как и template.

4) Добавлен новый возможный аргумент для директив forEach и forIn (forIn отличается от forEach тем, что всегда итерирует объект, как for (key in data), причём без проверки на hasOwnProperty). Теперь порядок аргументов для forEach такой:

Для массивов:
*) Ссылка на элемент массива;
*) Индекс массива;
*) Ссылка на итерируемый массив;
*) Является ли первым;
*) Является ли последним;
*) Длина массива.

Для объектов:
*) Ссылка на свойство;
*) Ключ свойства;
*) Ссылка на итерируемый объект;
*) Номер итерации;
*) Является ли первым;
*) Является ли последним;
*) Длина объекта.

Для forIn аргументы такие же, как и у forEach для объектов. Кстати, теперь директивы forEach и forIn разворачиваются в циклы на этапе трансляции, что позволило увеличить скорость скомпилированных шаблонов, а также возможность использования новых директив break и continue.

5) Для директивы data изменено сокращение, теперь это =, т.е.
{template foo()}
   {= foo, bar}
{/}


Старое сокращение {{}} теперь используется новой директивой decl, которая вставляет текст, так как он был написан вместе со скобками директивы, т.е.:
{template foo()}
   {{foo}} /// даст {{foo}}
{/}


Также, как и в data, в decl можно прокидывать переменные из шаблона, с помощью синтаксиса ${}. Новая директива decl создана для удобного использования библиотек, которые осуществляют data binding (вроде http://www.ractivejs.org/).

6)
Костыль для console был удалён, теперь нужно использовать директиву void
{template foo()}
   {void console.log(1)}
   /// или так
   {?console.log(1)}
{/}



На этом ломающие изменения заканчиваются. Основные нововведения:


1)
Добавлена директива super, которая осуществляет вставку тела родительского блока или прототипа:

{template base()}
   <head>
       {block scripts}
           <script src="../1.js"></script>
       {/}
   </head/>
{/}

{template child() extends base}
   {block scripts}
       {super}
       <script src="../2.js"></script>
   {/}
{/}


2) Прототипы теперь поддерживают параметры и рекурсию, а также новую директиву return:
{template foo()}
   {proto bar(i)}
      {i}

      {if i === 2}
           {return}
      {/}

      {if i}
          {apply bar(--i)}
      {/}
   {/}

   {apply bar(4)} /// 4 3 2
{/}


3) Прототипы теперь можно выносить за пределы шаблона, перед декларацией
{proto foo->bar}
    1
{/}

{template foo()}
   {apply bar}
{/}


4)
Добавлена поддержка jsDoc
/**
 * Данный комментарий будет в скомпилированном JS
 * @return {string}
 */
{template foo()}
   1
{/}


5) Директива var теперь имеет сокращение : и поддерживает множественную декларацию
{template foo()}
   {:a = 1}
   {var b = 2, e = 3}
{/}


6) Новые директивы switch case (имеет сокращение >) default

{template foo()}
   {switch 1}
      {case 1} foo {/}
      {> 2} foo2 {/}
      {default} foo3 {/}
   {/}
{/}


7) Новые директивы try catch finally

{template foo()}
   {try}
       {void dddd()}
   {catch err}
        {err}
   {finally}
        bar!!!
   {/}
{/}


8) Новые директивы break и continue. Могут использоваться внутри forEach, forIn, for, while, do, repeat.
9) Для цикла repeat-until добавлен псевдоним do-while
10) Новая директива return. Может использоваться внутри прототипов или шаблона (в случае шаблона может принимать значение)

11) Новая директива attr для удобного задания атрибутов узлам в xml разметке:
{template foo()}
   <div {attr 'class', 'foo'} {attr -'bind', 'bar'}></div> /// class="foo" data-bind="bar"
{/}


12) Частично переписано АПИ добавления директив, в релизе будет иметь документацию, пример:

Snakeskin.addDirective(
	'if',

	{
		placement: 'template',
		notEmpty: true
	},

	function (command) {
		this.startDir();
		if (this.isSimpleOutput()) {
			this.save('if (' + this.prepareOutput(command, true) + ') {');
		}
	}
);

Snakeskin.addDirective(
	'else',

	{
		placement: 'template'
	},

	function () {
		if (this.structure.name !== 'if') {
			throw this.error('Directive "' + this.name + '" can only be used with a "if"');
		}

		if (this.isSimpleOutput()) {
			this.save('} else {');
		}
	}
);


13) Увеличена скорость работы транслятора и исправлено множество ошибок
14) Сильно увеличена скорость работы в "живом" режиме в браузере
15) Очень сильно доработана обработка ошибок
16) 100% code review и рефакторинг + теперь исходный код переписан на ECMAScript 6

Вроде всё
__________________
kobezzza
code monkey

Последний раз редактировалось kobezzza, 07.01.2014 в 20:37.
Ответить с цитированием