Pull to refresh

Пишем свой первый плагин для Brackets

Reading time4 min
Views6.1K
Brackets — это бесплатный редактор от Adobe с открытым кодом, который полюбился веб-разработчикам из-за своей киллер-фичи Extract из PSD-файлов. Brackets поддерживает систему плагинов-расширений на основе JS. О процессе разработки одного из таких плагинов я и хотел бы рассказать.

Brackets поставляется с небольшим числом плагинов «из коробки». По этой причине, первое что новые пользователи обычно делают, это установка дополнительных расширений. Но через какое-то время, вы вероятно, словите себя на мысли «если бы только в Brackets была функция...». К счастью, Brackets это редактор с открытым исходным кодом. Он сам по себе является веб-приложением: он построен на любимых нами технологиях (HTML, CSS, JS) и если вы веб-разработчик, то можете помочь его развитию, написав расширение. И это гораздо проще, чем вы могли бы себе представить.

Hello World


Строго говоря, расширение это не более чем папка, содержащая JS-файл с именем main.js, который выполняется при запуске Brackets. Найти папку с расширениями можно при выборе пункта меню «Помощь — Показать директорию расширений».

Откройте папку с расширениями и внутри /user создайте новую папку «myFirstExtension». Внутри этой папки создайте файл main.js. Для быстрого старта попробуем вставить простой HelloWorld-код:

define(function (require, exports, module) {
	console.log('Hello myFirstExtension!');
});

Перезапустите Brackets через меню «Отладка — Перезагрузить» и вызовите инструменты разработчика (F12 или «Отладка — Показать инструменты разработчика») чтобы увидеть результат работы своего расширения.

JavaScript-модули в Brackets работают подобно модулям CommonJS. Понимание этого процесса выходит за рамки данного руководства, но все что нам нужно знать, это то, что весь код в теле анонимной функции внутри define() выполнится при запуске приложения.

Hello alert


Скорее всего вы хотели бы сделать расширение, которое выполняло бы некоторых код не во время загрузки Brackets, а при выборе пункта меню пользователем. Подобное поведение реализуется с помощью менеджера команд. Как и практически все в Brackets, сам диспетчер команд — это модуль. Чтобы получить доступ к модулю, нужно просто вызвать brackets.getModule().

define(function (require, exports, module) {
	var CommandManager = brackets.getModule('command/CommandManager');
	
	// Функция, выполняемая при нажатии на пункт меню
	function handleHelloWorld() {
		window.alert('Hello, world!'); 
	}

	// Во-первых, зарегистрируем команду, которая свяжет ID и функцию handleHelloWorld
	var COMMAND_ID = 'helloworld.sayhello'; // package-style для избежания коллизий
	var COMMAND_NAME = 'Hello World';
	CommandManager.register(COMMAND_NAME, COMMAND_ID, handleHelloWorld);

	// Во-вторых, создадим пункт меню и привяжем его к команде
	var Menus    = brackets.getModule('command/Menus');
	var fileMenu = Menus.getMenu(Menus.AppMenuBar.FILE_MENU);
	fileMenu.addMenuItem(COMMAND_ID);
});


Hello document


Теперь попробуем сделать что-то условно полезное. В Brackets есть замечательная функция Extract, которая позволяет нарезать картинки, получать CSS-свойства и копировать текст прямо из PSD-файла. Однако текст передается в виде HTML-сущностей, что не всегда удобно.

&# 1052;&# 1086;&# 1080; &# 1082;&# 1085;&# 1080;&# 1075;&# 1080;

Попробуем написать расширение, которое будет конвертировать эти символы в обычный текст. Декодировать будем с помощью JS-функции.

В Brackets, открытые файлы представлены в качестве экземпляров класса Document. Для получения ссылки на текущий документ (файл, открытый пользователем для редактирования), мы должны использовать модуль EditorManager.

function handleDecodeHtml() {
	var editor = EditorManager.getFocusedEditor(); // текущий документ
	var selectedText = editor.getSelectedText(); // получаем выделенный текст
	var newText = decodeHtmlEntity(selectedText); // конвертируем
	var selection = editor.getSelection();
	editor.document.replaceRange(newText, selection.start, selection.end); // заменяем
}

ReplaceRange добавляет, заменяет или удаляет текст. Если указан диапазон, то текст в этом диапазоне будет заменены на новый. Если третий аргумент не указан, то новый текст будет вставлен без замены выделенного.

На этом все. Осталось «прописаться» в меню «Правка», в контекстное меню и добавить горячие клавиши.

define(function (require, exports, module) {
	var CommandManager = brackets.getModule('command/CommandManager');
	var Menus          = brackets.getModule('command/Menus');
	var Menu           = Menus.getMenu(Menus.AppMenuBar.EDIT_MENU); // меню "Правка"
	var ContextMenu    = Menus.getContextMenu(Menus.ContextMenuIds.EDITOR_MENU);
	var KeyManager     = brackets.getModule('command/KeyBindingManager');
	
	// ...

	var COMMAND_ID = 'decodehtmlentity.convert';
	CommandManager.register('Decode HTML Entity', COMMAND_ID, handleDecodeHtml);
	
	Menu.addMenuItem(COMMAND_ID); 
	KeyManager.addBinding(COMMAND_ID, 'Ctrl-Alt-D'); // Ctrl автоматически заменяется на CMD для Mac
	ContextMenu.addMenuItem(COMMAND_ID);
});

Hello publishing


Чтобы опубликовать приложение, необходимо добавить package.json в папку с main.js. Формат package довольно простойи будет знаком тем, у кого есть опыт работы с Node.js и npm.
{
	"name": "brackets.decode-html-entity",
	"title": "Decode HTML Entity",
	"description": "This extension uses to decode any HTML-encoded string.",
	"version": "0.1.0",
	"engines": {
		"brackets": ">=1.7.0"
	},
	"license": "MIT",
	"i18n": ["en", "ru"],
	"package-i18n": {
		"ru": {
			"description": "Это расширение используется для декодирования HTML-сущностей."
		}
	}
}

Заархивируйте папку с расширением (на гитхабе есть кнопка «Download ZIP»), авторизуйтесь на сайте brackets-registry и опубликуйте свое расширение путем загрузки zip-файла в реестр.

» Исходный код плагина доступен на гитбахе.
Tags:
Hubs:
Total votes 11: ↑11 and ↓0+11
Comments7

Articles