Многие знают, что в Chrome Development Tools встроен удобный редактор CSS, отображающий изменения мгновенно. Единственная проблема – отсутствие возможности удобного автоматического сохранения изменений.
Для решения задачи автосохранения существуют три расширения для Chrome: DevTools Autosave, Tincr и Save CSS. Так как работа с файлами на диске у расширений невозможна, все они перехватывают событие изменения CSS, а текст измененного файла (или только фрагмент в случае DevTools autosave) отправляется запросом на localhost, на котором уже серверная программа сохраняет непосредственно в файл.
Вышеперечисленные расширения для сохранения в файл используют скрипты на Python, Node.js или Ruby. Мне же, как PHP программисту не связанному с этими языками хотелось простое One click решение для Windows, без необходимости установки ненужных мне в своей работе серверов.
Поэтому я решил написать простенькую утилиту под Windows, решающую эту задачу.
Был выбран скриптовый язык AutoIt как наиболее простой способ быстро получить результат.
Капитан Паранойя подсказывает, что вместо третьего пункта можно сделать следующее:
Если в файле CSS есть комментарии или префиксы вендоров — они тоже сохранятся.
Обновление 16.02.2013:
Исправлена ошибка, возникающая из за незакрытого сокета. Теперь сервер работает корректно.
Скрипт выше и exe файл по ссылке обновлены.
Обновление 18.04.2013:
Исправлена ошибка, когда CSS сохранялся вместе с http заголовком.
Скрипт выше и exe файл по ссылке обновлены.
Автор первого фото Exey Panteleev
Текст и скриншоты раздела «Использование» взяты с сайта автора Save CSS
Для решения задачи автосохранения существуют три расширения для Chrome: DevTools Autosave, Tincr и Save CSS. Так как работа с файлами на диске у расширений невозможна, все они перехватывают событие изменения CSS, а текст измененного файла (или только фрагмент в случае DevTools autosave) отправляется запросом на localhost, на котором уже серверная программа сохраняет непосредственно в файл.
Вышеперечисленные расширения для сохранения в файл используют скрипты на Python, Node.js или Ruby. Мне же, как PHP программисту не связанному с этими языками хотелось простое One click решение для Windows, без необходимости установки ненужных мне в своей работе серверов.
Поэтому я решил написать простенькую утилиту под Windows, решающую эту задачу.
Был выбран скриптовый язык AutoIt как наиболее простой способ быстро получить результат.
Текст скрипта (Обновлен 18 апреля 2013)
#cs
# 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
# 16.02.2013 - Updated
# 18.04.2013 - Updated
#ce
Local $sIP = "127.0.0.1"; ip address
Local $iPort = 8080 ; the listening port
Local $sBuffer = "";
Local $aSavedFilepaths = ""; needed to show tray tip only once per file
Local $iStartTime = TimerInit()
TCPStartup()
$iMainSocket = TCPListen($sIP, $iPort, 10)
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, 0)
While True
$iSock = TCPAccept($iMainSocket) ;Check for new connections
If TimerDiff($iStartTime) > 250 Then ;reset tray icon to standart
TraySetIcon()
EndIf
sleep(10)
If $iSock = -1 Then ContinueLoop
If _TCP_Server_ClientIP($iSock) <> "127.0.0.1" Then
ConsoleWrite("External connection! Disconnect." & @CRLF)
TCPCloseSocket($iSock) ; Kill any not local connections
ContinueLoop
EndIf
ConsoleWrite("A new client has connected!" & @CRLF)
$sBuffer = ""
$break = false;
Do
$sRecv = TCPRecv($iSock, 2048)
If $sRecv Then
$sBuffer &= $sRecv
$receivedLength = StringLen($sRecv);
$bufferLength = StringLen($sBuffer);
$headerLength = StringInStr($sBuffer, @CRLF&@CRLF) + 3
$array = StringRegExp($sBuffer, 'Content-Length: (.*)', 2)
$contentLength = StringStripCR($array[1])
If ($contentLength + $headerLength == $bufferLength) Then
$break = True
EndIf
EndIf
Until $break
ConsoleWrite("READY!" & @CRLF)
$array = StringRegExp($sBuffer, 'X-origurl: (.*)', 2)
$xOrigurl = StringStripCR($array[1]);
$array = StringRegExp($sBuffer, 'X-filepath: (.*)', 2)
$xFilepath = urldecode(StringStripCR($array[1]));
$body = StringTrimLeft($sBuffer, $headerLength)
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!", 1, 0)
$aSavedFilepaths &= '|'&$xFilepath;
EndIf
TraySetIcon("info");
$iStartTime = TimerInit()
Else
ConsoleWrite(" - ERROR!!!"& @CRLF);
TrayTip("Save CSS server ERROR", $xFilepath & " - file save error!", 0, 3)
EndIf
$sBuffer = ""
$sRecv = ""
$iSock = -1
TCPSend($iMainSocket, "HTTP/1.1 200 OK"& @CRLF)
TCPSend($iMainSocket, "Content-Length: 2"& @CRLF)
TCPSend($iMainSocket, @CRLF)
TCPSend($iMainSocket, "OK")
TCPCloseSocket($iMainSocket)
sleep(1000)
TCPShutdown ()
TCPStartup()
$iMainSocket = TCPListen($sIP, $iPort, 1)
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 есть комментарии или префиксы вендоров — они тоже сохранятся.
Обновление 16.02.2013:
Исправлена ошибка, возникающая из за незакрытого сокета. Теперь сервер работает корректно.
Скрипт выше и exe файл по ссылке обновлены.
Обновление 18.04.2013:
Исправлена ошибка, когда CSS сохранялся вместе с http заголовком.
Скрипт выше и exe файл по ссылке обновлены.
Автор первого фото Exey Panteleev
Текст и скриншоты раздела «Использование» взяты с сайта автора Save CSS