Метод внедряемых настроек в JavaScript

Воскресенье, 24 января 2010 года, 19:11. Напечатано в категориях JavaScript, jQuery, Кодекс8

Привет дорогие друзья!
Вчера не было поста, так как я верстал кое-что и работал над codeEvaluator`ом :)
Ну что же, работа в обоих случаях была успешной и сегодня я бы хотел рассказать про “Метод внедряемых настроек”, пост про который я обещал ещё вчера :)

Метод внедряемых настроек основан на полезном использовании содержимого тега script, пост про который был опубликован позавчера.
Почему такое название? Потому что пока лучше не придумал ;)
Если предложите лучше, пожалуйста =)

Итак, представьте, что у нас есть какой то JS файлик. Пусть это будет скрипт, который что то делает и который пользователь может настраивать. Под словом “настраивать” подразумевается включение в документ ещё одного тега script и написания там настроек:

<script type="text/javascript">
var ScriptOptions = {
  delay: 100,
  speed: 200
};
</script>
<script type="text/javascript" src="path/to/script.js"></script>

Наш подключаемый скрипт ищет переменную ScriptOptions и обрабатывает её.
Но дело в том, что у такого метода есть куча недостатков:

  1. Засоряем глобальный объект window своими переменные
  2. На странице появляется ещё один тег script. А если таких скриптов как наш и таких методов настроек много, то на странице образуется абсолютная каша

Можно было бы заключить настройки в HTML комментарий и из скрипта искать его:

<!--
var ScriptOptions = {
 delay: 100,
 speed: 200
};
-->
<script type="text/javascript" src="path/to/script.js"></script>

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

Итак! А теперь давайте используем метод применения полезного использовании содержимого тега script и засунем настройки в наш тег script:

<script type="text/javascript" src="path/to/script.js">
({
  delay: 100,
  speed: 200
})
</script>

Очень просто и понятно :)
И вдобавок при этом мы не используем какие лишние теги и комментарии ;)

Импорт таких настроек в нашем файле path/to/script.js осуществляем очень просто:

// Дефолтные опции нашего скрипта
var options = { speed: 500 };

/*
** Метод внедряемых настроек
** @More: http://vl.vg/24.01.2010/method-introduced-by-setting/
*/

// Используем конструкцию try...catch для предотвращения ошибок
try{
  var scripts = document.getElementsByTagName( 'script' ), code;
  // Если нащ скрипт был подключен через тег script
  // То мы обязательно его засекём
  if( scripts.length != 0 ){
    // Извлекаем внутреннее содержимое последнего тега script
    code = scripts[ scripts.length - 1 ].text.replace( /^\s*|\s*$/, '' );
    // Вырезаем все комментарии из начала и конца
    // Если вы уверены, что комментариев не будет,
    // то можете не использовать этот метод
    code = code.split( '' ).reverse().join( '' )
      .replace( /^((\/\*(.|\s)*?\*\/)|(\n.*\/\/)|\s)*/, '')
      .split( '' ).reverse().join( '' )
      .replace( /^((\/\*(.|\s)*?\*\/)|(\/\/.*\n)|\s)*/, '' );
    // Проверяем, является ли наш код объектом(не пустым)
    if( /^\s*\(?\s*{(.|\s)+}\s*\)?\s*$/.test( code ) ){
      // Превращаем код в объект
      code = eval( '(' + code + ')' );
      // Скрещиваем опции
      for( var name in code )
        options[ name ] = code[ name ];
    };
  };
}
catch( e ){};

// Наш микс опций получен! Выполняем стандартные действия
alert( 'Скорость конвейера: ' + options.speed + ' печенек' );

Вот и всё :)
В случае, если вы используете jQuery, можно использовать такой код:

// Дефолтные опции нашего скрипта
var options = { speed: 500 };

/*
** Метод внедряемых настроек
** @More: http://vl.vg/24.01.2010/method-introduced-by-setting/
*/

try{
  var script = jQuery( 'script:last' );
  if( ( script = script.length > 0 && script[ 0 ].text ) && /^\s*\(?\s*{(.|\s)+}\s*\)?\s*$/.test( script ) )
    $.extend( options, eval( '(' + script + ')' ) );
}
catch( e ){};

// Наш микс опций получен! Выполняем стандартные действия
alert( 'Скорость конвейера: ' + options.speed + ' печенек' );

Надеюсь, свою задачу на сегодня я выполнил…
… и вы поняли, как использовать “Метод внедряемых настроек” :D

P. S. Я наконец таки выпустил codeEvaluator 0.0.3rc1, который при благополучных условиях обещает скоро стать релизом версии 0.0.3!)
И теперь я хочу попросить вас потестить новый браузер кода ceBrowser. Если возникнут ошибки, отписывайтесь здесь в комментариях. Вместе мы их найдём и приблизим выпуск CE :)
Также хочу вас попросить протестировать юзабилити браузера кода.
Всех изменений называть не буду, но хочу затронуть несколько главных:

  1. Плавное появление/исчезание браузера кода. Это позволяет больше понять ситуацию, которая произошла при клике на кнопку “Запустить код!” и даёт понимать пользователю, что появилась не новая страница, а некая “фича”.
  2. Сохранение позиции скролла при выходе из браузера кода(раньше при выходе позиция скролла была равна нулю и ставила страницу в начало).
  3. Введена система встроенных скинов браузера кода и контрольной панели кода(это где кнопки “Запустить код!” и т. д.).
  4. Существенно оптимизирован исходный код плагина.
  5. Поддержка jQuery 1.3.2

Итак, кликайте на кнопки “Запустить код!” ;)
1. Выполнение JavaScript кода в браузере кода ceBrowser:

document.write( 'Вкусный апельсин' );
document.write( '<br>Подтверждаю! Так как вы сидите из браузера <b>' + navigator.appName + '</b>' );

2. Выполнение HTML кода в браузере кода ceBrowser:

<h1>Закон браузеров гласит:</h1>
<b style="color:red;">Каждый браузер должен иметь окно!</b>

2. Выполнение XHTML кода в браузере кода ceBrowser:

<div>
  <h1>Это пример XHTML документа</h1>
</div>
<strong style="color:green;">А вы уже перешли на XHTML?</strong>


Комментарии(8)

deerua пишет в понедельник, 25.01.2010 в 10:17 Ответить
xhtml и алигн=центер ))) посмешил ;)))
зы: красивая кнопка "обратно" уже лучше %)
ззы: скины будут в 0.0.3.1а? )
deerua пишет в понедельник, 25.01.2010 в 10:19 Ответить
Хорошо когда есть пример и для ДжиКвери и для нейтив ДжС ;)
зы: цеБрозер будет без ДжикВери? )
Regent пишет в понедельник, 25.01.2010 в 10:25 Ответить
@deerua, ceBrowser будет с jQuery
Без неё никуда

CE 0.0.3.1а уже не будет, так как ты видишь на этой страничке первый релиз кандидат
Возможно будет codeEvaluator 0.0.3rc2 или сразу 0.0.3

Скины будут Надо только написать ещё пару

Спасибо
Дмитрий пишет во вторник, 26.01.2010 в 20:53 Ответить
Давай меняться постовыми? Тоже пишу о javascript
Regent пишет во вторник, 26.01.2010 в 21:24 Ответить
@Дмитрий, с удовольствием =)
Можете даже принять участие в акции - http://vl.vg/19.01.2010/free-links/
Чистяков Денис пишет в понедельник, 08.02.2010 в 15:50 Ответить
Спасибо за интересный прием. Я правильно понимаю, что jQuery как то хитро убирает лишнее, раз регэкспов нету в варианте с ним?
По поводу codeEvaluator:
1) В Opere 10.10 не заменился бекграунд и все пишется на основном фоне блога, получается черным по черному -- читать не удобно ) сначала подумал, что вообще не сработало что то.
2) Просто необходимо что бы кнопка "назад" работала правильно, несколько раз нажал бекспейс что бы вернуться -- это быстрее чем мышкой.
Чистяков Денис пишет в понедельник, 08.02.2010 в 15:51 Ответить
3) Подсветка исходников, тоже была бы весьма к кстати.
Regent пишет в понедельник, 08.02.2010 в 17:39 Ответить
@Чистяков Денис,нет, в примере с jQuery не показан код для вырезания комментариев. Вот он родимый
code = code.split( '' ).reverse().join( '' )
  .replace( /^((\/\*(.|\s)*?\*\/)|(\n.*\/\/)|\s)*/, '')
  .split( '' ).reverse().join( '' )
  .replace( /^((\/\*(.|\s)*?\*\/)|(\/\/.*\n)|\s)*/, '' );


1. В Опере это скорее всего из-за синхронизации бекграундов тега body и страницы. Надо будет назначать на body и html чистящие стили...
2. На бекспейс повешу кнопку назад, спасибо за подсказку
3. Здесь уже надо думать, откуда подсвеченный код брать. Либо в CE встраивать подсветку(+10-20 КБ кода), либо из источника брать полный HTML(там чего только может не быть...)

Спасибо!
Уведомлять меня о новых комментариях по почте
Для корректной работы отправки комментариев необходимо включить JavaScript
Либо скачать новый нормальный браузер