Многие знают, что в Chrome Development Tools встроен удобный редактор CSS, отображающий изменения мгновенно. Единственная проблема – отсутствие возможности удобного автоматического сохранения изменений.
Для решения задачи автосохранения существуют три расширения для Chrome: DevTools Autosave, Tincr и Save CSS. Так как работа с файлами на диске у расширений невозможна, все они перехватывают событие изменения CSS, а текст измененного файла (или только фрагмент в случае DevTools autosave) отправляется запросом на localhost, на котором уже серверная программа сохраняет непосредственно в файл.
Вышеперечисленные расширения для сохранения в файл используют скрипты на Python, Node.js или Ruby. Мне же, как PHP программисту не связанному с этими языками хотелось простое One click решение для Windows, без необходимости установки ненужных мне в своей работе серверов.
Поэтому я решил написать простенькую утилиту под Windows, решающую эту задачу.
Был выбран скриптовый язык AutoIt как наиболее простой способ быстро получить результат.
# save-css-server.au3: receive CSS and JS files from Chrome extension
# and save files locally
#
# Author: Ilya Zenin
# Based on AutoIt HTTP Server by Manadar
# 18.01.2013 - Created
Local $sIP = "127.0.0.1"; ip address
Local $iPort = 8080 ; the listening port
Local $aSocket
Local $sBuffer
Local $aSavedFilepaths = ""; needed to show tray tip only once per file
Local $iStartTime = TimerInit()
TCPStartup()
$iMainSocket = TCPListen($sIP, $iPort, 1)
If @error Then
MsgBox(0x20, "Save CSS server", "Unable to create a socket on port " & $iPort & ".")
Exit
EndIf
ConsoleWrite("Save CSS server running at port " & $iPort & "..."& @CRLF)
TrayTip("Save CSS server", "Save CSS server running at port " & $iPort & "...", 0, 1)
While 1
$iNewSocket = TCPAccept($iMainSocket)
$sNewData = TCPRecv($iNewSocket, 1024*1024*100) ; 100Mb CSS is enough for anyone (C)
If $sNewData Then
If _TCP_Server_ClientIP($iNewSocket) <> "127.0.0.1" Then
TCPCloseSocket($iNewSocket) ; Kill any not local connections
Else
$sBuffer &= $sNewData
If StringInStr(StringStripCR($sBuffer),@LF&@LF) Then
$array = StringRegExp($sBuffer, 'X-origurl: (.*)', 2)
$xOrigurl = StringStripCR($array[1]);
$array = StringRegExp($sBuffer, 'X-filepath: (.*)', 2)
$xFilepath = urldecode(StringStripCR($array[1]));
$array = StringRegExp($sBuffer, 'Content-Length: (.*)', 2)
$contentLength = StringStripCR($array[1]);
$body = StringRight($sBuffer, $contentLength)
ConsoleWrite("Saving file " & $xFilepath)
Local $file = FileOpen($xFilepath, 2)
$result = FileWrite ($file, $body)
FileClose($file)
If $result == 1 Then
ConsoleWrite(" - Success " & @CRLF);
If Not StringInStr($aSavedFilepaths, $xFilepath) Then ; show tray bubble only once per file
TrayTip("Save CSS server", $xFilepath & " - saved!", 0, 1)
$aSavedFilepaths &= '|'&$xFilepath;
EndIf
TraySetIcon("info") ;
$iStartTime = TimerInit()
Else
ConsoleWrite(" - ERROR!!!"& @CRLF);
TrayTip("Save CSS server ERROR", $xFilepath & " - file save error!", 0, 3)
EndIf
$sBuffer = ""
$aSocket = -1
EndIf
EndIf
EndIf
If TimerDiff($iStartTime) > 1000 Then ;reset tray icon to standart
TraySetIcon()
EndIf
Sleep(10)
WEnd
Func urldecode($str)
Local $i, $return, $tmp
$return = ""
$str = StringReplace ($str, "+", " ")
For $i = 1 To StringLen($str)
$tmp = StringMid($str, $i, 3)
If StringRegExp($tmp, "%[0-9A-Fa-f]{2}", 0) = 1 Then
$i += 2
While StringRegExp(StringMid($str, $i+1, 3), "%[0-9A-Fa-f]{2}", 0) = 1
$tmp = $tmp & StringMid($str, $i+2, 2)
$i += 3
Wend
$return &= BinaryToString(StringRegExpReplace($tmp, "%([0-9A-Fa-f]*)", "0x$1"), 4)
Else
$return &= StringMid($str, $i, 1)
EndIf
Next
Return $return
EndFunc
; Function to return IP Address from a connected socket.
;----------------------------------------------------------------------
Func _TCP_Server_ClientIP($hSocket)
Local $pSocketAddress, $aReturn
$pSocketAddress = DllStructCreate("short;ushort;uint;char[8]")
$aReturn = DllCall("Ws2_32.dll", "int", "getpeername", "int", $hSocket, "ptr", DllStructGetPtr($pSocketAddress), "int*", DllStructGetSize($pSocketAddress))
If @error Or $aReturn[0] <> 0 Then Return 0
$aReturn = DllCall("Ws2_32.dll", "str", "inet_ntoa", "int", DllStructGetData($pSocketAddress, 3))
If @error Then Return 0
$pSocketAddress = 0
Return $aReturn[0]
EndFunc
Установка
- Ставим расширение Save CSS в хроме из стора
- Возможно потребуется включить экспериментальное API в настройках хрома chrome://flags/
- Скачиваем и запускаем exe файл серверной части (людям со страхом к скачиванию EXE читать ниже)
- В хроме в Developer Tools настраиваем соответствие путей виртуального сервера и файлов на диске, например так:
- Профит: Теперь сразу после изменения стилей в трее всплывет уведомление о сохранении файла. Чтобы постоянно всплывающие сообщения не мешали, они всплывают только 1 раз на файл, последующие автосохранения будет только моргать иконка:
Капитан Паранойя подсказывает, что вместо третьего пункта можно сделать следующее:
- Скачиваем и устанавливаем autoit (http://www.autoitscript.com/)
- Сохраняем вышеприведенный скрипт как save-css-server.au3
- Правой клавишей на файле -> compile script
- Запускаем exe
Использование
Чтобы поменять свойство CSS кликните на имя свойства или значение и введите с клавиатуры. Цифровые значения могут быть так же изменены колесом мыши или стрелочками вверх/вниз на клавиатуре |
|
Чтобы добавить новое свойство два раза щелкните на строке с символом “}” и напишите имя свойства | |
Чтобы удалить свойство сотрите его имя и нажмите enter |
Если в файле CSS есть комментарии или префиксы вендоров — они тоже сохранятся.
Автор первого фото Exey Panteleev
Текст и скриншоты раздела «Использование» взяты с сайта автора Save CSS
Автор: Rastishka