Некоторое время назад я писал о последних обновлениях редактора скобок. Brackets — это проект с открытым исходным кодом, ориентированный на веб-стандарты и построенный с использованием веб-технологий. Он имеет узкую направленность и поэтому может не иметь конкретной функции, от которой вы зависите. К счастью, Brackets поставляется с мощным расширением API, которое позволяет добавлять любое количество новых функций. В этой статье я собираюсь обсудить этот API и продемонстрировать, как вы можете создавать свои собственные расширения.
Важно помнить, что Brackets находится в активной разработке. Эта статья написана в декабре 2013 года. Вполне возможно, что приведенный ниже код устарел. Имейте это в виду и обязательно проверяйте вики на наличие последних обновлений API расширения.
Начиная
Я предполагаю, что вы прочитали мою последнюю статью и уже знакомы с менеджером расширений. Это обеспечивает простой способ установки расширений одним щелчком мыши. Один из лучших способов научиться писать расширения — это смотреть на работу, проделанную другими (вот как я узнал). Я бы порекомендовал взять несколько расширений (сейчас их доступно почти 200) и разорвать их код. Не бойтесь сломать несколько, пока вы на это.
Скобки помещают все установленные расширения в одну основную папку. Чтобы найти эту папку, перейдите в меню « Справка» и выберите « Показать папку расширений ». Для моей установки OS X это было в / Users / ray / Library / Application Support / Brackets / extensions / user . Если вы зайдете из этой папки, вы также заметите отключенную папку. Скобки приложат смелые усилия для загрузки несмотря ни на что, но если вы когда-нибудь окажетесь в ситуации, когда Скобки полностью сломали кровать и просто не будут работать, рассмотрите возможность перемещения потенциально плохих расширений в отключенную папку. Позже в этой статье я расскажу, как вы можете отслеживать и отлаживать расширения, чтобы в первую очередь предотвратить подобные проблемы.
Начните с перехода в свою пользовательскую папку и создания новой папки helloworld1
. Да, несмотря на то, что он полностью хромает, мы собираемся создать расширение HelloWorld. Не ненавидь меня, я люблю просто. Внутри этой папки создайте новый файл с именем main.js
В листинге 1 показано, каким должно быть содержимое этого файла. Обратите внимание, что в этой статье я рассмотрю несколько разных итераций расширения helloworld
. Каждый будет назван с прогрессивно более высоким номером. Итак, наш первый пример из helloworld1
, следующий helloworld2
и так далее. Для вас имеет смысл просто скопировать код в одну папку helloworld
, а не копировать каждую из них по отдельности. Если вы это сделаете, у вас будет запущено несколько связанных расширений одновременно, и это может определенно запутать вещи.
Листинг 1: helloworld1 / main.js define (функция (требуется, экспорт, модуль) { журнал (ы) функций { console.log ("[helloworld]" + s); } log («Привет из HelloWorld.»); });
Первая строка определяет наше расширение как модуль, который автоматически выбирается Brackets при загрузке приложения. Остальная часть расширения представляет собой настраиваемое сообщение журнала (вы поймете почему через секунду) и вызов этого регистратора. После сохранения этого файла вернитесь в скобки, выберите меню «Отладка» и нажмите «Перезагрузить». (Вы также можете использовать Command / Control + R для перезагрузки.)
Скобки перезагрузятся и … больше ничего не случится. Расширение, которое мы создали, на самом деле не делало ничего, что мы могли видеть, но оно регистрировало консоль. Но где эта консоль? Кронштейны обеспечивают простой способ просмотра консоли. Просто вернитесь в меню « Отладка» и выберите « Показать инструменты разработчика» . Это откроет новую вкладку в Chrome со знакомым пользовательским интерфейсом Dev Tools. На снимке экрана ниже я выделил наш журнал. Другие расширения и сами Brackets также будут регистрировать сообщения на этом экране. Префикс моих сообщений в журнале [helloworld]
позволяет мне легче находить свои собственные материалы.
Обратите внимание, что полный Chrome console.api
работает здесь. Вы можете сделать что-то подобное для форматирования сообщений консоли:
журнал (ы) функций { console.log ("% c [helloworld]" + s, "цвет: синий; размер шрифта: большой"); }
Сойти с ума, но попробуйте удалить эти сообщения, прежде чем поделиться своим кодом с остальным миром. Если вам интересно, вы не можете использовать инструменты разработки в другом браузере, например Firefox, в настоящее время.
Точки интеграции
Теперь, когда вы знаете (очень) основы, давайте поговорим о том, что расширения Brackets могут сделать с редактором:
- Они могут создавать сочетания клавиш, позволяя им реагировать на пользовательские нажатия клавиш.
- Их можно добавить в меню верхнего уровня.
- Они могут добавлять контекстные меню (и в определенную область, такую как список файлов или окно редактора).
- Они могут создавать элементы пользовательского интерфейса. Это может быть модальный диалог или даже панель. (В настоящее время панель заблокирована в нижней части экрана).
- Они могут создать провайдера linting (по сути, они могут зарегистрироваться как средство проверки кода для типа файла).
- Они могут создавать свои собственные встроенные редакторы (главная особенность скобок).
- Они могут зарегистрироваться в качестве поставщика документации (например, добавив поддержку MDN для документов).
- Они могут интегрироваться с Quick Find и Quick Open.
- Они могут добавлять собственные подсказки кода и цвета синтаксиса.
- Они могут читать текущий файл, открытый в редакторе, а также изменять его. (Они также могут видеть текущий выбранный текст, если есть.)
Здесь описывается, как расширения могут изменять скобки, но что могут делать расширения с точки зрения кода? Помня о том, что вы пишете расширения в чистых веб-стандартах (HTML, JavaScript и CSS), у вас действительно есть немного силы. Единственные реальные ограничения относятся к двоичным данным. Существует API файловой системы, который дает вам контроль над файлами, но ограничен только текстовыми данными. К счастью, у вас есть выход.
Любое расширение Brackets может интегрироваться с Node.js. Если у вас есть существующий пакет Node.js, ваше расширение может делать вызовы к нему и делать, что угодно, что может делать Node.js.
Давайте обновим наше расширение для лучшей интеграции с редактором. Я начну с простого добавления пункта меню для расширения.
Листинг 2: helloworld2 / main.js / * Частично на основе примера расширения HelloWorld на вики-сайте Brackets: https://github.com/adobe/brackets/wiki/Simple-%22Hello-World%22-extension * / define (функция (требуется, экспорт, модуль) { var CommandManager = brackets.getModule ("command / CommandManager"), Menus = brackets.getModule ("команда / Меню"), AppInit = brackets.getModule ("utils / AppInit"); журнал (ы) функций { console.log ("[helloworld2]" + s); } function handleHelloWorld () { alert («Ты меня побежал, спасибо!»); } AppInit.appReady (function () { log («Привет от HelloWorld2.»); var HELLOWORLD_EXECUTE = "helloworld.execute"; CommandManager.register («Запустите HelloWorld», HELLOWORLD_EXECUTE, handleHelloWorld); var menu = Menus.getMenu (Menus.AppMenuBar.VIEW_MENU); menu.addMenuItem (HELLOWORLD_EXECUTE); }); });
У нас здесь есть несколько изменений, поэтому давайте разберемся с ними один за другим. Вы заметите, что расширение начинается с трех вызовов brackets.getModule. Все расширения имеют доступ к объекту скобок, который предоставляет API, где мы можем загрузить основные функции из редактора. В этом случае расширение загрузило две библиотеки, которые нам понадобятся для меню (CommandManager и Menus), и одну, которая будет использоваться для инициализации расширения (AppInit).
Давайте поговорим о AppInit. Вы можете видеть, что большая часть расширения теперь загружена с обратным вызовом appReady. Этот обратный вызов запускается, когда Brackets завершил загрузку, и обычно считается «наилучшей практикой» для использования расширений.
Регистрация пункта меню занимает несколько шагов. Я начинаю с определения «идентификатора команды», уникального идентификатора элемента, который я добавлю в пользовательский интерфейс. Типичный способ сделать это с помощью формата extensionname.someaction
. В моем случае я использовал helloworld.execute
. Затем я могу зарегистрировать эту команду вместе с функцией ( handleHelloWorld
), которая должна вызываться при handleHelloWorld
команды.
Последний шаг — добавить эту команду в меню. Вероятно, вы можете догадаться, что мой пункт меню будет добавлен в меню «Вид» на основе этого значения: Menus.AppMenuBar.VIEW_MENU. Как я узнал это значение? Просто, я видел, как другие расширения делают это. Серьезно, пока нет конкретного списка таких вещей, как этот. Не забывайте, что скобки с открытым исходным кодом. Я могу легко зайти в репозиторий GitHub и проверить его. В данном случае это файл Menus.js
, расположенный на Github . Там я вижу, где определены различные основные меню:
/ ** * Константы меню приложения в скобках * @enum {строка} * / var AppMenuBar = { FILE_MENU: "файл-меню", EDIT_MENU: "edit-menu", VIEW_MENU: "view-menu", NAVIGATE_MENU: "навигационное меню", HELP_MENU: «Справка-меню» };
Как общее практическое правило, имеет смысл по крайней мере поверхностное понимание того, что доступно в самих скобках. Ваши расширения будут время от времени использовать несколько различных функций, поэтому, безусловно, в ваших интересах, по крайней мере, знать расположение земли.
После перезагрузки брекетов вы увидите пункт меню в меню « Вид» . Точно, где это может быть немного случайным, поскольку у вас могут быть установлены другие расширения.
На самом деле вы можете быть более конкретным в своей позиции. Опять же, именно здесь вам поможет исходный код. Тот же файл, на который я ссылался выше, также содержит определение addMenuItem.
Положите немного помады на эту свинью
Теперь, когда вы увидели простой пример того, как расширение может интегрироваться в скобки, давайте посмотрим, как мы обновляем интерфейс. В предыдущей версии нашего кода для отправки сообщения использовалось предупреждение. Хотя это работает, это не очень красиво. Ваш код может получить доступ к редактору скобок, как и любой другой код модификации DOM. Хотя вы можете делать все, что угодно, есть несколько стандартных способов, которыми расширения обновляют пользовательский интерфейс в скобках. (Как предупреждение, как правило, вы не хотите прикасаться к DOM основного интерфейса редактора. Вы можете, но с будущими обновлениями, ваш код может сломаться. Кроме того, пользователи могут не быть довольны, если ваше расширение меняет ядро на Brackets. )
Первый метод, который мы рассмотрим, использует модальные диалоги. Скобки уже используют это и имеют API, доступный для расширений для вызова. В качестве простого примера давайте просто обновим расширение HelloWorld, чтобы вместо него использовать модальное.
Листинг 3: helloworld3 / main.js / * Частично на основе примера расширения HelloWorld на вики-сайте Brackets: https://github.com/adobe/brackets/wiki/Simple-%22Hello-World%22-extension * / define (функция (требуется, экспорт, модуль) { var CommandManager = brackets.getModule ("command / CommandManager"), Menus = brackets.getModule ("команда / Меню"), Dialogs = brackets.getModule ("widgets / Dialogs"), DefaultDialogs = brackets.getModule ("widgets / DefaultDialogs"), AppInit = brackets.getModule ("utils / AppInit"); журнал (ы) функций { console.log ("[helloworld3]" + s); } function handleHelloWorld () { Dialogs.showModalDialog (DefaultDialogs.DIALOG_ID_INFO, «Hello World», «То же важное сообщение»); } AppInit.appReady (function () { log («Привет из HelloWorld3.»); var HELLOWORLD_EXECUTE = "helloworld.execute"; CommandManager.register («Запустите HelloWorld», HELLOWORLD_EXECUTE, handleHelloWorld); var menu = Menus.getMenu (Menus.AppMenuBar.VIEW_MENU); menu.addMenuItem (HELLOWORLD_EXECUTE); }); });
Обратите внимание на добавление двух дополнительных модулей Brackets: DefaultDialogs
и DefaultDialogs
. Следующее изменение в handleHelloWorld
. Одним из методов в библиотеке Dialog является возможность показывать диалог (я полагаю, нет ничего удивительного). Метод хочет класс, заголовок и тело, и все. С диалогами можно делать больше, но пока это демонстрирует эту функцию. Теперь, когда мы запускаем команду, мы получаем гораздо более симпатичный интерфейс. (Наряду со стандартными кнопками и поведением для закрытия диалогового окна.)
Это один пример, теперь давайте посмотрим на другой: создание нижней панели. Как и в случае с диалогами, у нас есть поддержка Brackets, чтобы упростить процесс. Давайте рассмотрим пример, а затем я объясню изменения.
Листинг 4: helloworld4 / main.js / * Частично на основе примера расширения HelloWorld на вики-сайте Brackets: https://github.com/adobe/brackets/wiki/Simple-%22Hello-World%22-extension * / define (функция (требуется, экспорт, модуль) { var CommandManager = brackets.getModule ("command / CommandManager"), Menus = brackets.getModule ("команда / Меню"), PanelManager = brackets.getModule ("view / PanelManager"), AppInit = brackets.getModule ("utils / AppInit"); var HELLOWORLD_EXECUTE = "helloworld.execute"; вар панель; журнал (ы) функций { console.log ("[helloworld4]" + s); } function handleHelloWorld () { if (panel.isVisible ()) { panel.hide (); CommandManager.get (HELLOWORLD_EXECUTE) .setChecked (ложь); } еще { panel.show (); CommandManager.get (HELLOWORLD_EXECUTE) .setChecked (истина); } } AppInit.appReady (function () { log («Привет из HelloWorld4.»); CommandManager.register («Запустите HelloWorld», HELLOWORLD_EXECUTE, handleHelloWorld); var menu = Menus.getMenu (Menus.AppMenuBar.VIEW_MENU); menu.addMenuItem (HELLOWORLD_EXECUTE); panel = PanelManager.createBottomPanel (HELLOWORLD_EXECUTE, $ ("<div class = 'bottom-panel'> HTML для моей панели </ div>"), 200); }); });
Давайте сосредоточимся на изменениях. Во-первых, я удалил модули Dialog, так как больше не использую их. Вместо этого мы загружаем PanelManager. Внизу в блоке appReady я определил новую панель, используя метод API PanelManager createBottomPanel. Как и команда меню, она принимает уникальный идентификатор, поэтому я просто повторно использую HELLOWORLD_EXECUTE
. Второй аргумент — это блок HTML в JQuery (и если вам интересно, да, мы можем сделать это лучше), и, наконец, минимальный размер. Это настраивает панель, но фактически не выполняет ее.
В обработчике событий мы привязали меню, можем спросить панель, видимо ли оно, а затем либо скрыть, либо показать его. Эта часть должна быть довольно тривиальной. Ради интереса я добавил немного больше сложности. Обратите внимание, что CommandManager
позволяет нам получить пункт меню и установить проверенное свойство. Это может быть ненужным, так как пользователь может достаточно легко увидеть панель, но добавление галочки делает вещи немного более очевидными. На снимке экрана ниже вы можете увидеть панель в видимом состоянии.
Сразу же вы можете спросить о панели HTML. Есть ли лучший способ предоставить HTML? В любом случае, чтобы украсить это? Да, давайте посмотрим на более продвинутую версию.
Листинг 5: helloworld5 / main.js / * Частично на основе примера расширения HelloWorld на вики-сайте Brackets: https://github.com/adobe/brackets/wiki/Simple-%22Hello-World%22-extension * / define (функция (требуется, экспорт, модуль) { var CommandManager = brackets.getModule ("command / CommandManager"), Menus = brackets.getModule ("команда / Меню"), PanelManager = brackets.getModule ("view / PanelManager"), ExtensionUtils = brackets.getModule ("utils / ExtensionUtils"), AppInit = brackets.getModule ("utils / AppInit"); var HELLOWORLD_EXECUTE = "helloworld.execute"; вар панель; var panelHtml = require ("text! panel.html"); журнал (ы) функций { console.log ("[helloworld5]" + s); } function handleHelloWorld () { if (panel.isVisible ()) { panel.hide (); CommandManager.get (HELLOWORLD_EXECUTE) .setChecked (ложь); } еще { panel.show (); CommandManager.get (HELLOWORLD_EXECUTE) .setChecked (истина); } } AppInit.appReady (function () { log («Привет из HelloWorld5.»); ExtensionUtils.loadStyleSheet (модуль, "helloworld.css"); CommandManager.register («Запустите HelloWorld», HELLOWORLD_EXECUTE, handleHelloWorld); var menu = Menus.getMenu (Menus.AppMenuBar.VIEW_MENU); menu.addMenuItem (HELLOWORLD_EXECUTE); panel = PanelManager.createBottomPanel (HELLOWORLD_EXECUTE, $ (panelHtml), 200); }); });
Как и прежде, я собираюсь сосредоточиться на изменениях. Сначала обратите внимание, что я включил переменную с именем panelHtml
которая загружается через require. Это позволяет мне определять мой HTML вне моего кода JavaScript. (Вы также можете использовать движки шаблонов. Кронштейны поставляются с усами.) HTML-код панели довольно прост.
01
02
03
04
05
06
07
08
09
10
11
12
13
|
Listing 6: helloworld5/panel.html
<div class=»bottom-panel helloworld-panel» id=»helloworldPanel»>
<h1>My Panel</h1>
<p>
My panel brings all the boys to the yard,<br/>
And they’re like<br/>
It’s better than yours,<br/>
Damn right it’s better than yours,<br/>
I can teach you,<br/>
But I have to charge
</p>
</div>
|
Возвращаясь к main.js
, я продемонстрировал еще одну функцию — loadStyleSheet. Это позволяет загружать таблицу стилей для конкретного расширения. Я создал файл helloworld.css
с несколькими простыми (но со вкусом) стилями CSS.
1
2
3
4
5
6
7
8
9
|
Listing 7: helloworld5/helloworld.css
.helloworld-panel h1 {
color: red;
}
.helloworld-panel p {
color: blue;
font-weight: bold;
}
|
Обратите внимание, что я добавил к своим стилям уникальное имя. Это помогает гарантировать, что мои занятия не конфликтуют ни с чем, встроенным в скобки. Благодаря этим простым изменениям моя панель теперь выглядит намного лучше, и вы можете понять, почему я известен во всем мире своими превосходными дизайнерскими навыками.
Упаковка и совместное использование удлинителя
Конечно, просто создать самое классное расширение Brackets недостаточно. Вы, вероятно (надеюсь!) Хотите поделиться этим с другими. Один из вариантов — просто заархивировать каталог и разместить его на своем сайте. Люди могут скачать zip-архив, распаковать его и скопировать в папку расширений Brackets.
Но это не круто. Вы хотите быть крутым, верно? Чтобы поделиться своим расширением и сделать его доступным через менеджер расширений Brackets, вам просто нужно добавить файл package.json
в ваше расширение. Если вы когда-либо использовали Node.js, то это покажется вам знакомым. Вот пример для нашего расширения.
Листинг 8: helloworld6 / package.json { "имя": "camden.helloworld", "title": "HelloWorld", "description": "Добавляет поддержку HelloWorld в скобки.", "домашняя страница": "https://github.com/cfjedimaster/something real here", "версия": "1.0.0", «автор»: «Рэймонд Камден <[email protected]> (http://www.raymondcamden.com)», «лицензия»: «MIT», "двигатели": { «скобки»: «<= 0,34,0» } }
Большая часть этого не требует пояснений, но реальная важная часть — блок двигателей. Скобки обновляются довольно быстро. Если Brackets добавил определенную функцию в какой-то момент, от которого зависит ваше расширение, вы можете добавить здесь простое условие, чтобы люди не пытались установить ваше расширение на несовместимую версию. (Вы можете найти полный список возможных настроек в вики .)
Как только вы это сделаете, следующая часть — загрузить его в реестр скобок . Вам нужно будет войти через свою учетную запись GitHub, но как только вы это сделаете, вы можете просто загрузить свой почтовый индекс. Ваше расширение будет тогда доступно любому, кто использует скобки. Еще лучше, если вы обновите свое расширение, менеджер расширений сможет пометить это пользователю, чтобы он знал, что обновление доступно.
Что еще?
Надеюсь, вы видели, как легко расширить скобки. Мы не рассмотрели еще кое-что, например интеграцию Linting API и NodeJS , но этой статьи должно быть более чем достаточно для начала работы. Как напоминание, не забывайте, что есть большая коллекция расширений, с которыми вы можете начать играть прямо сейчас. Удачи!