Pull to refresh

Удобное редактирование CSS (Chrome + Save CSS + autoIt)

Reading time5 min
Views18K
Многие знают, что в Chrome Development Tools встроен удобный редактор 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




Установка


  1. Ставим расширение Save CSS в хроме из стора
  2. Возможно потребуется включить экспериментальное API в настройках хрома chrome://flags/
  3. Скачиваем и запускаем exe файл серверной части (людям со страхом к скачиванию EXE читать ниже)
  4. В хроме в Developer Tools настраиваем соответствие путей виртуального сервера и файлов на диске, например так:
  5. Профит: Теперь сразу после изменения стилей в трее всплывет уведомление о сохранении файла. Чтобы постоянно всплывающие сообщения не мешали, они всплывают только 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
Tags:
Hubs:
+15
Comments27

Articles

Change theme settings