264 lines
11 KiB
Plaintext
264 lines
11 KiB
Plaintext
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
|