commit
bec7f51cd4
|
@ -0,0 +1,263 @@
|
|||
option explicit
|
||||
|
||||
' ShadowFox updater for Windows
|
||||
' author: @CarlColijn
|
||||
' version: 1.0
|
||||
|
||||
' the download urls of the files
|
||||
const chromeFileURL = "https://raw.githubusercontent.com/overdodactyl/ShadowFox/master/userChrome.css"
|
||||
const contentFileURL = "https://raw.githubusercontent.com/overdodactyl/ShadowFox/master/userContent.css"
|
||||
|
||||
' set up the common worker objects and flags
|
||||
dim vbSection: vbSection = vbNewLine & vbNewLine
|
||||
const readMode = 1
|
||||
const binaryMode = 1
|
||||
const overwriteMode = 2
|
||||
dim fso: set fso = createObject("Scripting.FileSystemObject")
|
||||
dim regEx: set regEx = createObject("VBScript.RegExp")
|
||||
regEx.global = true
|
||||
regEx.ignoreCase = true
|
||||
|
||||
' vb's IIf replacement
|
||||
function iif(condition, trueValue, falseValue)
|
||||
if condition then
|
||||
iif = trueValue
|
||||
else
|
||||
iif = falseValue
|
||||
end if
|
||||
end function
|
||||
|
||||
' does a regex newline-agnostic replacement on the given text
|
||||
function regExNLReplace(text, pattern, replaceText)
|
||||
' ensure newlines are absent, since VBScript regex can't match 'em
|
||||
dim encodedText: encodedText = replace(replace(text, vbCr, chr(1)), vbLf, chr(2))
|
||||
|
||||
' do the regex replace
|
||||
regEx.pattern = pattern
|
||||
dim replacedText: replacedText = regEx.replace(encodedText, replaceText)
|
||||
|
||||
' and decode the newlines again
|
||||
regExNLReplace = replace(replace(replacedText, chr(1), vbCr), chr(2), vbLf)
|
||||
end function
|
||||
|
||||
' left-pads the given text to the given length with the given character
|
||||
' the text is not truncated if longer than the given length
|
||||
function leftPad(text, length, padChar)
|
||||
if len(text) >= length then
|
||||
leftPad = text
|
||||
else
|
||||
leftPad = string(length - len(text), padChar) & text
|
||||
end if
|
||||
end function
|
||||
|
||||
' gets a yyyy-mm-dd_hh-mm timestamp
|
||||
function dateTimeStamp()
|
||||
dim present: present = now
|
||||
dateTimeStamp = year(present) & "-" & leftPad(month(present), 2, "0") & "-" & leftPad(day(present), 2, "0") & "_" & leftPad(hour(present), 2, "0") & "-" & leftPad(minute(present), 2, "0") & "-" & leftPad(second(present), 2, "0")
|
||||
end function
|
||||
|
||||
' backs up the given file
|
||||
' returns the used backup file name
|
||||
function backupFile(chromeFolderPath, filePath, fileBaseName)
|
||||
' backup the file
|
||||
dim backupFileName: backupFileName = fileBaseName & ".backup." & dateTimeStamp() & ".css"
|
||||
dim backupFilePath: backupFilePath = fso.buildPath(chromeFolderPath, backupFileName)
|
||||
call fso.moveFile(filePath, backupFilePath)
|
||||
|
||||
' and tell where the backup ended up
|
||||
backupFile = backupFileName
|
||||
end function
|
||||
|
||||
' downloads the given file to the given location
|
||||
' returns if the download succeeded
|
||||
function downloadFile(url, filePath)
|
||||
on error resume next
|
||||
' download the file content
|
||||
dim xmlHttp: set xmlHttp = createObject("Microsoft.XMLHTTP")
|
||||
call xmlHttp.Open("GET", url, false)
|
||||
call xmlHttp.Send()
|
||||
if err.number = 0 then
|
||||
' done -> save it
|
||||
dim stream: set stream = createobject("ADODB.Stream")
|
||||
with stream
|
||||
.type = binaryMode
|
||||
call .open
|
||||
call .write(xmlHttp.responseBody)
|
||||
call .saveToFile(filePath, overwriteMode)
|
||||
end with
|
||||
end if
|
||||
|
||||
' and tell if all is OK
|
||||
downloadFile = err.number = 0
|
||||
on error goto 0
|
||||
end function
|
||||
|
||||
' reads the given file's content
|
||||
function readFileContent(filePath)
|
||||
if fso.getFile(filePath).size = 0 then
|
||||
readFileContent = ""
|
||||
else
|
||||
readFileContent = fso.openTextFile(filePath, readMode).readAll()
|
||||
end if
|
||||
end function
|
||||
|
||||
' ensures consistent line endings in the given text (to just crLf)
|
||||
function normalizeLineEndings(text)
|
||||
normalizeLineEndings = replace(replace(text, vbCrLf, vbLf), vbCr, vbLf)
|
||||
end function
|
||||
|
||||
' ensures the given file is present
|
||||
' returns the file's content, or "" if not present
|
||||
function processCustomizationFile(filePath)
|
||||
if fso.fileExists(filePath) then
|
||||
processCustomizationFile = readFileContent(filePath)
|
||||
else
|
||||
processCustomizationFile = ""
|
||||
call fso.createTextFile(filePath, true)
|
||||
end if
|
||||
end function
|
||||
|
||||
|
||||
|
||||
' determine where the files need to go
|
||||
dim chromeFolderPath: chromeFolderPath = fso.buildPath(fso.getParentFolderName(wscript.scriptFullName), "chrome")
|
||||
dim chromeFilePath: chromeFilePath = fso.buildPath(chromeFolderPath, "userChrome.css")
|
||||
dim contentFilePath: contentFilePath = fso.buildPath(chromeFolderPath, "userContent.css")
|
||||
dim customizationsFolderPath: customizationsFolderPath = fso.buildPath(chromeFolderPath, "ShadowFox_customization")
|
||||
dim colorOverridesFilePath: colorOverridesFilePath = fso.buildPath(customizationsFolderPath, "colorOverrides.css")
|
||||
dim internalUUIDsFilePath: internalUUIDsFilePath = fso.buildPath(customizationsFolderPath, "internal_UUIDs.txt")
|
||||
dim chromeCustomizationsFilePath: chromeCustomizationsFilePath = fso.buildPath(customizationsFolderPath, "userChrome_customization.css")
|
||||
dim contentCustomizationsFilePath: contentCustomizationsFilePath = fso.buildPath(customizationsFolderPath, "userContent_customization.css")
|
||||
|
||||
' ensure the files & folders are present, creating empty files as placeholders for users to customize
|
||||
if not fso.folderExists(chromeFolderPath) then
|
||||
call fso.createFolder(chromeFolderPath)
|
||||
end if
|
||||
if not fso.folderExists(customizationsFolderPath) then
|
||||
call fso.createFolder(customizationsFolderPath)
|
||||
end if
|
||||
dim colorOverrides: colorOverrides = processCustomizationFile(colorOverridesFilePath)
|
||||
dim internalUUIDs: internalUUIDs = processCustomizationFile(internalUUIDsFilePath)
|
||||
dim chromeCustomizations: chromeCustomizations = processCustomizationFile(chromeCustomizationsFilePath)
|
||||
dim contentCustomizations: contentCustomizations = processCustomizationFile(contentCustomizationsFilePath)
|
||||
|
||||
' ask if we may continue
|
||||
dim prompt: prompt = "Updating userContent.css and userChrome.css for Firefox profile:" & vbNewLine & chromeFolderPath & vbNewLine
|
||||
if fso.fileExists(contentFilePath) then
|
||||
prompt = prompt & vbNewLine & _
|
||||
"Your current userContent.css file for this profile will be backed up and the latest ShadowFox version from github will take its place."
|
||||
else
|
||||
prompt = prompt & vbNewLine & _
|
||||
"A userContent.css file does not exist in this profile. If you continue, the latest ShadowFox version from github will be downloaded."
|
||||
end if
|
||||
if fso.fileExists(chromeFilePath) then
|
||||
prompt = prompt & vbNewLine & _
|
||||
"Your current userChrome.css file for this profile will be backed up and the latest ShadowFox version from github will take its place."
|
||||
else
|
||||
prompt = prompt & vbNewLine & _
|
||||
"A userChrome.css file does not exist in this profile. If you continue, the latest ShadowFox version from github will be downloaded."
|
||||
end if
|
||||
if vbNo = msgBox(prompt & vbSection & "Continue?", vbYesNo + vbDefaultButton2 + vbQuestion, "ShadowFox updater") then
|
||||
' no -> tell
|
||||
call msgBox("Process aborted.", vbOKOnly, "ShadowFox updater")
|
||||
else
|
||||
' yes -> backup any existing files
|
||||
prompt = "Installing new ShadowFox files."
|
||||
if fso.fileExists(contentFilePath) then
|
||||
prompt = prompt & vbNewLine & _
|
||||
"Your previous userContent.css file was backed up: " & backupFile(chromeFolderPath, contentFilePath, "userContent")
|
||||
end if
|
||||
if fso.fileExists(chromeFilePath) then
|
||||
prompt = prompt & vbNewLine & _
|
||||
"Your previous userChrome.css file was backed up: " & backupFile(chromeFolderPath, chromeFilePath, "userChrome")
|
||||
end if
|
||||
|
||||
' download the latest versions
|
||||
dim allOK
|
||||
allOK = true
|
||||
if _
|
||||
not downloadFile(chromeFileURL, chromeFilePath) or _
|
||||
not downloadFile(contentFileURL, contentFilePath) _
|
||||
then
|
||||
' error downloading -> tell
|
||||
prompt = prompt & vbSection & _
|
||||
"There was an error downloading the latest ShadowFox userContent.css and/or userChrome.css files."
|
||||
allOK = false
|
||||
else
|
||||
' done -> tell
|
||||
prompt = prompt & vbSection & _
|
||||
"ShadowFox userContent.css and userChrome.css have been downloaded."
|
||||
|
||||
' read their content to manipulate it
|
||||
dim chromeFileContent: chromeFileContent = readFileContent(chromeFilePath)
|
||||
dim contentFileContent: contentFileContent = readFileContent(contentFilePath)
|
||||
|
||||
' do any extension UUID replacements
|
||||
if len(internalUUIDs) = 0 then
|
||||
prompt = prompt & vbSection & _
|
||||
"You have not defined any internal UUIDs for webextensions." & vbNewLine & _
|
||||
"If you choose not to do so, webextensions will not be styled with a dark theme and may have compatibility issues in about:addons." & vbNewLine & _
|
||||
"For more information, see here:" & vbNewLine & _
|
||||
"https://github.com/overdodactyl/ShadowFox/wiki/Altering-webextensions"
|
||||
else
|
||||
dim internalUUID
|
||||
for each internalUUID in split(normalizeLineEndings(internalUUIDs), vbLf)
|
||||
if instr(internalUUID, "=") > 0 then
|
||||
dim replacementParts: replacementParts = split(internalUUID, "=")
|
||||
regEx.pattern = replacementParts(0)
|
||||
contentFileContent = regEx.replace(contentFileContent, replacementParts(1))
|
||||
end if
|
||||
next
|
||||
prompt = prompt & vbSection & _
|
||||
"Your internal UUIDs have been inserted."
|
||||
end if
|
||||
|
||||
' process any color overrides
|
||||
if len(colorOverrides) = 0 then
|
||||
prompt = prompt & vbSection & _
|
||||
"You are using the default colors set by ShadowFox." & vbNewLine & _
|
||||
"You can customize the colors used by editing colorOverrides.css."
|
||||
else
|
||||
const replacePattern = "(\/\*! Begin color overrides \*\/)(.*)(\/\*! End color overrides \*\/)"
|
||||
dim replaceWith: replaceWith = "$1" & vbNewLine & colorOverrides & vbNewLine & "$3"
|
||||
chromeFileContent = regExNLReplace(chromeFileContent, replacePattern, replaceWith)
|
||||
contentFileContent = regExNLReplace(contentFileContent, replacePattern, replaceWith)
|
||||
prompt = prompt & vbSection & _
|
||||
"Your custom colors have been set."
|
||||
end if
|
||||
|
||||
' add on any overrides
|
||||
if len(contentCustomizations) = 0 then
|
||||
prompt = prompt & vbSection & _
|
||||
"You do not have any custom userContent.css tweaks." & vbNewLine & _
|
||||
"You can customize userContent.css using userContent_customization.css."
|
||||
else
|
||||
contentFileContent = contentFileContent & vbSection & contentCustomizations
|
||||
prompt = prompt & vbSection & _
|
||||
"Your custom userContent.css tweaks have been applied."
|
||||
end if
|
||||
if len(chromeCustomizations) = 0 then
|
||||
prompt = prompt & vbSection & _
|
||||
"You do not have any custom userChrome.css tweaks." & vbNewLine & _
|
||||
"You can customize userChrome.css using userChrome_customization.css."
|
||||
else
|
||||
chromeFileContent = chromeFileContent & vbSection & chromeCustomizations
|
||||
prompt = prompt & vbSection & _
|
||||
"Your custom userChrome.css tweaks have been applied."
|
||||
end if
|
||||
|
||||
' write them out again
|
||||
on error resume next
|
||||
call fso.createTextFile(chromeFilePath, true).write(chromeFileContent)
|
||||
call fso.createTextFile(contentFilePath, true).write(contentFileContent)
|
||||
if err.number <> 0 then
|
||||
allOK = false
|
||||
prompt = prompt & vbSection & _
|
||||
"There was an error saving the customized versions of the userChrome.css and/or userContent.css files."
|
||||
end if
|
||||
on error goto 0
|
||||
end if
|
||||
|
||||
' and tell we're done
|
||||
call msgBox(prompt, iif(allOK, vbInformation, vbExclamation), "ShadowFox updater")
|
||||
end if
|
Loading…
Reference in New Issue