998 lines
27 KiB
PowerShell
998 lines
27 KiB
PowerShell
<#
|
|
|
|
.SYNOPSIS
|
|
Installer for Lepton
|
|
|
|
.DESCRIPTION
|
|
Installs Lepton onto selected Firefox profiles
|
|
|
|
.INPUTS
|
|
TODO: input directories for installation?
|
|
Would need to discuss a non-interactive install system
|
|
|
|
.OUTPUTS
|
|
TODO: output directories that Lepton has been installed to?
|
|
|
|
.PARAMETER u
|
|
Specifies whether to update a current installation
|
|
Defaults to false
|
|
|
|
.PARAMETER f
|
|
Specifies a custom path to look for Firefox profiles in
|
|
|
|
.PARAMETER p
|
|
Specifies a custom name to use when creating a profile
|
|
|
|
.PARAMETER h
|
|
Shows this help message
|
|
|
|
.PARAMETER ?
|
|
Shows this help message
|
|
|
|
.PARAMETER WhatIf
|
|
Runs the installer without actioning any file copies/moves
|
|
Equivalent to a dry-run
|
|
|
|
.EXAMPLE
|
|
PS> .\Install.ps1 -u -f C:\Users\someone\ff-profiles
|
|
Updates current installations in the profile directory 'C:\Users\someone\ff-profiles'
|
|
|
|
.LINK
|
|
https://github.com/black7375/Firefox-UI-Fix#readme
|
|
|
|
#>
|
|
|
|
[CmdletBinding(
|
|
SupportsShouldProcess = $true,
|
|
PositionalBinding = $false
|
|
)]
|
|
|
|
param(
|
|
[Alias("u")]
|
|
[switch]$updateMode,
|
|
[Alias("f")]
|
|
[string]$profileDir,
|
|
[Alias("p")]
|
|
[string]$profileName,
|
|
[Alias("h")]
|
|
[switch]$help = $false
|
|
)
|
|
|
|
#** Helper Utils ***************************************************************
|
|
#== Message ====================================================================
|
|
function Lepton-ErrorMessage() {
|
|
Write-Error "FAILED: ${args}"
|
|
exit -1
|
|
}
|
|
|
|
function Lepton-OKMessage() {
|
|
$local:SIZE = 50
|
|
$local:FILLED = ""
|
|
for ($i = 0; $i -le ($SIZE - 2); $i++) {
|
|
$FILLED += "."
|
|
}
|
|
$FILLED += "OK"
|
|
|
|
$local:message = "${args}"
|
|
Write-Host ${message}(${FILLED}.Substring(${message}.Length))
|
|
}
|
|
|
|
$PSMinSupportedVersion = 2
|
|
function Verify-PowerShellVersion {
|
|
Write-Host -NoNewline "Checking PowerShell version... "
|
|
$PSVersion = [int](Select-Object -Property Major -First 1 -ExpandProperty Major -InputObject $PSVersionTable.PSVersion)
|
|
|
|
Write-Host "[$PSVersion]"
|
|
if ($PSVersion -lt $PSMinSupportedVersion) {
|
|
Write-Error -Category NotInstalled "You need a minimum PowerShell version of [$PSMinSupportedVersion] to use this installer"
|
|
exit -1
|
|
}
|
|
}
|
|
|
|
#== Required Tools =============================================================
|
|
function Install-Choco() {
|
|
# https://chocolatey.org/install
|
|
# https://docs.chocolatey.org/en-us/choco/setup#non-administrative-install
|
|
$InstallDir='C:\ProgramData\chocoportable'
|
|
$env:ChocolateyInstall="$InstallDir"
|
|
|
|
Set-ExecutionPolicy Bypass -Scope Process -Force
|
|
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072
|
|
iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
|
|
$env:Path += ";C:\ProgramData\chocoportable" # Adimin: ";C:\ProgramData\chocolatey"
|
|
refreshenv
|
|
}
|
|
|
|
function Check-Git() {
|
|
if ( -Not (Get-Command git -errorAction SilentlyContinue) ) {
|
|
if ( -Not (Get-Command choco -errorAction SilentlyContinue) ) {
|
|
Install-Choco
|
|
}
|
|
choco install git.commandline -y
|
|
$env:Path += ";C:\tools\git\bin" # Adimin: ";C:\Program Files\Git\bin"
|
|
refreshenv
|
|
}
|
|
|
|
Lepton-OKMessage "Required - git"
|
|
}
|
|
|
|
#== PATH / File ================================================================
|
|
$PSDefaultParameterValues['Out-File:Encoding'] = 'utf8'
|
|
|
|
$currentDir = (Get-Location).path
|
|
|
|
function Filter-Path() {
|
|
Param (
|
|
[Parameter(Mandatory=$true, Position=0)]
|
|
[string[]] $pathList,
|
|
[Parameter(Position=1)]
|
|
[string] $option = "Any"
|
|
)
|
|
|
|
return $pathList.Where({ Test-Path -Path "$_" -PathType "${option}" })
|
|
}
|
|
|
|
function Copy-Auto() {
|
|
Param (
|
|
[Parameter(Mandatory=$true, Position=0)]
|
|
[string] $file,
|
|
[Parameter(Mandatory=$true, Position=1)]
|
|
[string] $target
|
|
)
|
|
|
|
if ( "${file}" -eq "${target}" ) {
|
|
Write-Host "'${file}' and ${target} are same file"
|
|
return 0
|
|
}
|
|
|
|
if ( Test-Path -Path "${target}" ) {
|
|
Write-Host "${target} already exists."
|
|
Write-Host "Now making a backup.."
|
|
Copy-Auto "${target}" "${target}.bak"
|
|
Remove-Item "${target}" -Recurse -Force
|
|
Write-Host ""
|
|
}
|
|
|
|
Copy-Item -Path "${file}" -Destination "${target}" -Force -Recurse
|
|
}
|
|
|
|
function Move-Auto() {
|
|
Param (
|
|
[Parameter(Mandatory=$true, Position=0)]
|
|
[string] $file,
|
|
[Parameter(Mandatory=$true, Position=1)]
|
|
[string] $target
|
|
)
|
|
|
|
if ( "${file}" -eq "${target}" ) {
|
|
Write-Host "'${file}' and ${target} are same file"
|
|
return 0
|
|
}
|
|
|
|
if ( Test-Path -Path "${target}" ) {
|
|
Write-Host "${target} already exists."
|
|
Write-Host "Now making a backup.."
|
|
Move-Auto "${target}" "${target}.bak"
|
|
Write-Host ""
|
|
}
|
|
|
|
Get-ChildItem -Path "${target}" -Recurse | Move-Item -Path "${file}" -Destination "${target}" -Force
|
|
}
|
|
|
|
function Restore-Auto() {
|
|
Param (
|
|
[Parameter(Mandatory=$true, Position=0)]
|
|
[string] $file
|
|
)
|
|
$local:target = "${file}.bak"
|
|
|
|
if ( Test-Path -Path "${file}" ) {
|
|
Remove-Item "${file}" -Recurse -Force
|
|
}
|
|
Get-ChildItem -Path "${target}" -Recurse | Move-Item -Destination "${file}" -Force
|
|
|
|
$local:lookupTarget = "${target}.bak"
|
|
if ( Test-Path -Path "${lookupTarget}" ) {
|
|
Restore-Auto "${target}"
|
|
}
|
|
}
|
|
|
|
function Write-File() {
|
|
Param (
|
|
[Parameter(Mandatory=$true, Position=0)]
|
|
[string] $filePath,
|
|
[Parameter(Position=1)]
|
|
[string] $fileContent = ""
|
|
)
|
|
|
|
if ( "${fileContent}" -eq "" ) {
|
|
New-Item -Path "${filePath}" -Force
|
|
}
|
|
else {
|
|
Out-File -FilePath "${filePath}" -InputObject "${fileContent}" -Force
|
|
}
|
|
}
|
|
|
|
#== INI File ================================================================
|
|
# https://devblogs.microsoft.com/scripting/use-powershell-to-work-with-any-ini-file/
|
|
function Get-IniContent () {
|
|
Param (
|
|
[Parameter(Mandatory=$true, Position=0)]
|
|
[string] $filePath
|
|
)
|
|
|
|
$ini = @{}
|
|
switch -regex -file $filePath {
|
|
"^\[(.+)\]" {
|
|
# Section
|
|
$section = $matches[1]
|
|
$ini[$section] = @{}
|
|
$CommentCount = 0
|
|
}
|
|
"^(;.*)$" {
|
|
# Comment
|
|
$value = $matches[1]
|
|
$CommentCount = $CommentCount + 1
|
|
$name = “Comment” + $CommentCount
|
|
$ini[$section][$name] = $value
|
|
}
|
|
"(.+?)\s*=(.*)" {
|
|
# For compatibility
|
|
if ( $section -eq $null ) {
|
|
$section = "Info"
|
|
$ini[$section] = @{}
|
|
}
|
|
|
|
# Key
|
|
$name,$value = $matches[1..2]
|
|
$ini[$section][$name] = $value
|
|
}
|
|
}
|
|
return $ini
|
|
}
|
|
|
|
function Out-IniFile() {
|
|
Param (
|
|
[Parameter(Mandatory=$true, Position=0)]
|
|
[string] $filePath,
|
|
[Parameter(Position=1)]
|
|
[hashtable] $iniObject = @{}
|
|
)
|
|
|
|
# Create new file
|
|
$local:outFile = New-Item -ItemType file -Path "${filepath}" -Force
|
|
|
|
foreach ($i in $iniObject.keys) {
|
|
if (!($($iniObject[$i].GetType().Name) -eq "Hashtable")) {
|
|
#No Sections
|
|
Add-Content -Path $outFile -Value "$i=$($iniObject[$i])"
|
|
}
|
|
else {
|
|
#Sections
|
|
Add-Content -Path $outFile -Value "[$i]"
|
|
Foreach ($j in ($iniObject[$i].keys | Sort-Object)) {
|
|
if ($j -match "^Comment[\d]+") {
|
|
Add-Content -Path $outFile -Value "$($iniObject[$i][$j])"
|
|
}
|
|
else {
|
|
Add-Content -Path $outFile -Value "$j=$($iniObject[$i][$j])"
|
|
}
|
|
|
|
}
|
|
Add-Content -Path $outFile -Value ""
|
|
}
|
|
}
|
|
}
|
|
|
|
#** Select Menu ****************************************************************
|
|
# https://github.com/chrisseroka/ps-menu
|
|
function Check-PsMenu() {
|
|
if(-Not (Get-InstalledModule ps-menu -ErrorAction silentlycontinue)) {
|
|
Set-PSRepository PSGallery -InstallationPolicy Trusted
|
|
Install-Module -Name ps-menu -Confirm:$False -Force
|
|
}
|
|
}
|
|
|
|
function DrawMenu {
|
|
param ($menuItems, $menuPosition, $Multiselect, $selection)
|
|
$l = $menuItems.length
|
|
for ($i = 0; $i -le $l; $i++) {
|
|
if ($menuItems[$i] -ne $null){
|
|
$item = $menuItems[$i]
|
|
if ($Multiselect) {
|
|
if ($selection -contains $i){
|
|
$item = '[x] ' + $item
|
|
}
|
|
else {
|
|
$item = '[ ] ' + $item
|
|
}
|
|
}
|
|
if ($i -eq $menuPosition) {
|
|
Write-Host "> $($item)" -ForegroundColor Green
|
|
}
|
|
else {
|
|
Write-Host " $($item)"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function Toggle-Selection {
|
|
param ($pos, [array]$selection)
|
|
if ($selection -contains $pos){
|
|
$result = $selection | where {$_ -ne $pos}
|
|
}
|
|
else {
|
|
$selection += $pos
|
|
$result = $selection
|
|
}
|
|
$result
|
|
}
|
|
|
|
function Menu {
|
|
param ([array]$menuItems, [switch]$ReturnIndex=$false, [switch]$Multiselect)
|
|
$vkeycode = 0
|
|
$pos = 0
|
|
$selection = @()
|
|
if ($menuItems.Length -gt 0) {
|
|
try {
|
|
[console]::CursorVisible=$false #prevents cursor flickering
|
|
DrawMenu $menuItems $pos $Multiselect $selection
|
|
While ($vkeycode -ne 13 -and $vkeycode -ne 27) {
|
|
$press = $host.ui.rawui.readkey("NoEcho,IncludeKeyDown")
|
|
$vkeycode = $press.virtualkeycode
|
|
If ($vkeycode -eq 38 -or $press.Character -eq 'k') {$pos--}
|
|
If ($vkeycode -eq 40 -or $press.Character -eq 'j') {$pos++}
|
|
If ($vkeycode -eq 36) { $pos = 0 }
|
|
If ($vkeycode -eq 35) { $pos = $menuItems.length - 1 }
|
|
If ($press.Character -eq ' ') { $selection = Toggle-Selection $pos $selection }
|
|
if ($pos -lt 0) {$pos = 0}
|
|
If ($vkeycode -eq 27) {$pos = $null }
|
|
if ($pos -ge $menuItems.length) {$pos = $menuItems.length -1}
|
|
if ($vkeycode -ne 27) {
|
|
$startPos = [System.Console]::CursorTop - $menuItems.Length
|
|
[System.Console]::SetCursorPosition(0, $startPos)
|
|
DrawMenu $menuItems $pos $Multiselect $selection
|
|
}
|
|
}
|
|
}
|
|
finally {
|
|
[System.Console]::SetCursorPosition(0, $startPos + $menuItems.Length)
|
|
[console]::CursorVisible = $true
|
|
}
|
|
}
|
|
else {
|
|
$pos = $null
|
|
}
|
|
|
|
if ($ReturnIndex -eq $false -and $pos -ne $null) {
|
|
if ($Multiselect){
|
|
return $menuItems[$selection]
|
|
}
|
|
else {
|
|
return $menuItems[$pos]
|
|
}
|
|
}
|
|
else {
|
|
if ($Multiselect) {
|
|
return $selection
|
|
}
|
|
else {
|
|
return $pos
|
|
}
|
|
}
|
|
}
|
|
|
|
#** Profile ********************************************************************
|
|
#== Profile Dir ================================================================
|
|
# $HOME = (get-psprovider 'FileSystem').Home
|
|
$firefoxProfileDirPaths = @(
|
|
"${HOME}\AppData\Roaming\Mozilla\Firefox",
|
|
"${HOME}\AppData\Roaming\Waterfox",
|
|
"${HOME}\AppData\Roaming\librewolf",
|
|
"${HOME}\AppData\Roaming\Ghostery Browser",
|
|
"${HOME}\Desktop\Tor Browser\Browser\TorBrowser\Data\Browser"
|
|
)
|
|
|
|
function Check-ProfileDir() {
|
|
Param (
|
|
[Parameter(Position=0)]
|
|
[string] $profileDir = ""
|
|
)
|
|
|
|
if ( "${profileDir}" -ne "" ) {
|
|
$global:firefoxProfileDirPaths = @("${profileDir}")
|
|
}
|
|
|
|
|
|
$global:firefoxProfileDirPaths = Filter-Path $global:firefoxProfileDirPaths "Container"
|
|
|
|
if ( $firefoxProfileDirPaths.Length -eq 0 ) {
|
|
Lepton-ErrorMessage "Unable to find firefox profile dir."
|
|
}
|
|
|
|
Lepton-OKMessage "Profiles dir found"
|
|
}
|
|
|
|
#== Profile Info ===============================================================
|
|
$PROFILEINFOFILE="profiles.ini"
|
|
function Check-ProfileIni() {
|
|
foreach ( $profileDir in $global:firefoxProfileDirPaths ) {
|
|
if ( -Not (Test-Path -Path "${profileDir}\${PROFILEINFOFILE}" -PathType "Leaf") ) {
|
|
Lepton-ErrorMessage "Unable to find ${PROFILEINFOFILE} at ${profileDir}"
|
|
}
|
|
}
|
|
|
|
Lepton-OKMessage "Profiles info file found"
|
|
}
|
|
|
|
#== Profile PATH ===============================================================
|
|
$firefoxProfilePaths = @()
|
|
function Update-ProfilePaths() {
|
|
foreach ( $profileDir in $global:firefoxProfileDirPaths ) {
|
|
$local:iniContent = Get-IniContent "${profileDir}\${PROFILEINFOFILE}"
|
|
$global:firefoxProfilePaths += $iniContent.Values.Path | ForEach-Object { "${profileDir}\${PSItem}" }
|
|
}
|
|
|
|
if ( $firefoxProfilePaths.Length -ne 0 ) {
|
|
Lepton-OkMessage "Profile paths updated"
|
|
}
|
|
else {
|
|
Lepton-ErrorMessage "Doesn't exist profiles"
|
|
}
|
|
}
|
|
|
|
# TODO: Multi select support
|
|
function Select-Profile() {
|
|
Param (
|
|
[Parameter(Position=0)]
|
|
[string] $profileName = ""
|
|
)
|
|
|
|
if ( "${profileName}" -ne "" ) {
|
|
$local:targetPath = ""
|
|
foreach ( $profilePath in $global:firefoxProfilePaths ) {
|
|
if ( "${profilePath}" -like "*${profileName}" ) {
|
|
$targetPath = "${profilePath}"
|
|
break
|
|
}
|
|
}
|
|
|
|
if ( "${targetPath}" -ne "" ) {
|
|
Lepton-OkMessage "Profile, `"${profileName}`" found"
|
|
$global:firefoxProfilePaths = @("${targetPath}")
|
|
}
|
|
else {
|
|
Lepton-ErrorMessage "Unable to find ${profileName}"
|
|
}
|
|
}
|
|
else {
|
|
if ( $firefoxProfilePaths.Length -eq 1 ) {
|
|
Lepton-OkMessage "Auto detected profile"
|
|
}
|
|
else {
|
|
$global:firefoxProfilePaths = Menu $firefoxProfilePaths
|
|
|
|
if ( $firefoxProfilePaths.Length -eq 0 ) {
|
|
Lepton-ErrorMessage "Please select profiles"
|
|
}
|
|
|
|
Lepton-OkMessage "Selected profile"
|
|
}
|
|
}
|
|
}
|
|
|
|
#** Lepton Info File ***********************************************************
|
|
# If you interst RFC, see install.sh
|
|
|
|
#== Lepton Info ================================================================
|
|
$LEPTONINFOFILE ="lepton.ini"
|
|
function Check-LeptonIni() {
|
|
foreach ( $profileDir in $global:firefoxProfileDirPaths ) {
|
|
if ( -Not (Test-Path -Path "${profileDir}\${LEPTONINFOFILE}") ) {
|
|
Lepton-ErrorMessage "Unable to find ${LEPTONINFOFILE} at ${profileDir}"
|
|
}
|
|
}
|
|
|
|
Lepton-OkMessage "Lepton info file found"
|
|
}
|
|
|
|
#== Create info file ===========================================================
|
|
# We should always create a new one, as it also takes into account the possibility of setting it manually.
|
|
# Updates happen infrequently, so the creation overhead is less significant.
|
|
|
|
function Get-ProfileDir() {
|
|
Param (
|
|
[Parameter(Mandatory=$true, Position=0)]
|
|
[string] $profilePath
|
|
)
|
|
foreach ( $profileDir in $firefoxProfileDirPaths ) {
|
|
if ( "$profilePath" -like "${profileDir}*" ) {
|
|
return "$profileDir"
|
|
}
|
|
}
|
|
}
|
|
|
|
$CHROMEINFOFILE="LEPTON"
|
|
function Write-LeptonInfo() {
|
|
# Init info
|
|
$local:output = @{}
|
|
$local:prevDir = $firefoxProfileDirPaths[0]
|
|
$local:latestPath = ( $firefoxProfilePaths | Select-Object -Last 1 )
|
|
foreach ( $profilePath in $global:firefoxProfilePaths ) {
|
|
$local:LEPTONINFOPATH = "${profilePath}\chrome\${CHROMEINFOFILE}"
|
|
$local:LEPTONGITPATH = "${profilePath}\chrome\.git"
|
|
|
|
# Profile info
|
|
$local:Type = ""
|
|
$local:Ver = ""
|
|
$local:Branch = ""
|
|
$local:Path = ""
|
|
if ( Test-Path -Path "${LEPTONINFOPATH}" ) {
|
|
if ( Test-Path -Path "${LEPTONGITPATH}" -PathType "Container" ) {
|
|
$Type = "Git"
|
|
$Ver = $(git --git-dir "${LEPTONGITPATH}" rev-parse HEAD)
|
|
$Branch = $(git --git-dir "${LEPTONGITPATH}" rev-parse --abbrev-ref HEAD)
|
|
}
|
|
else {
|
|
$local:iniContent = Get-IniContent "${LEPTONINFOPATH}"
|
|
$Type = $iniContent["Info"]["Type"]
|
|
$Ver = $iniContent["Info"]["Ver"]
|
|
$Branch = $iniContent["Info"]["Branch"]
|
|
|
|
if ( "${Type}" -eq "" ) {
|
|
$Type = "Local"
|
|
}
|
|
}
|
|
|
|
$Path = "${profilePath}"
|
|
}
|
|
|
|
# Flushing
|
|
$local:profileDir = Get-ProfileDir "${profilePath}"
|
|
$local:profileName = Split-Path "${profilePath}" -Leaf
|
|
if ( "${prevDir}" -ne "${profileDir}" ) {
|
|
Out-IniFile "${prevDir}\${LEPTONINFOFILE}" $output
|
|
$output = @{}
|
|
}
|
|
|
|
# Make output contents
|
|
foreach ( $key in @("Type", "Branch", "Ver", "Path") ) {
|
|
$local:value = (Get-Variable -Name "${key}").Value
|
|
if ( "$value" -ne "" ) {
|
|
$output["${profileName}"] += @{"${key}" = "${value}"}
|
|
}
|
|
}
|
|
|
|
# Latest element flushing
|
|
if ( "${profilePath}" -eq "${latestPath}" ) {
|
|
Out-IniFile "${profileDir}\${LEPTONINFOFILE}" $output
|
|
}
|
|
$prevDir = "${profileDir}"
|
|
}
|
|
|
|
# Verify
|
|
Check-LeptonIni
|
|
Lepton-OkMessage "Lepton info file created"
|
|
}
|
|
|
|
#** Install ********************************************************************
|
|
#== Install Types ==============================================================
|
|
$updateMode = $false
|
|
$leptonBranch = "master"
|
|
function Select-Distribution() {
|
|
while ( $true ) {
|
|
$local:selected = $false
|
|
$local:selectedDistribution = Menu @("Original(default)", "Photon-Style", "Proton-Style", "Update")
|
|
switch ( $selectedDistribution ) {
|
|
"Original(default)" { $global:leptonBranch = "master" ; $selected = $true }
|
|
"Photon-Style" { $global:leptonBranch = "photon-style"; $selected = $true }
|
|
"Proton-Style" { $global:leptonBranch = "proton-style"; $selected = $true }
|
|
"Update" { $global:updateMode = $true ; $selected = $true }
|
|
default { Write-Host "Invalid option, reselect please." }
|
|
}
|
|
|
|
if ( $selected -eq $true ) {
|
|
break
|
|
}
|
|
}
|
|
Lepton-OkMessage "Selected ${selectedDistribution}"
|
|
}
|
|
|
|
$leptonInstallType = "Network" # Other types: Local, Release
|
|
function Check-InstallType() {
|
|
Param (
|
|
[Parameter(Mandatory=$true, Position=0)]
|
|
[string[]] $targetList,
|
|
[Parameter(Mandatory=$true, Position=1)]
|
|
[string] $installType
|
|
)
|
|
|
|
$local:targetCount = $targetList.Length
|
|
$local:foundCount = (Filter-Path $targetList ).Length
|
|
|
|
if ( "${targetCount}" -eq "${foundCount}" ) {
|
|
$global:leptonInstallType="${installType}"
|
|
}
|
|
}
|
|
|
|
$checkLocalFiles = @(
|
|
"userChrome.css",
|
|
"userContent.css",
|
|
"icons"
|
|
)
|
|
$checkReleaseFiles = @(
|
|
"user.js"
|
|
"chrome\userChrome.css"
|
|
"chrome\userContent.css"
|
|
"chrome\icons"
|
|
)
|
|
function Check-InstallTypes() {
|
|
Check-InstallType $checkLocalFiles "Local"
|
|
Check-InstallType $checkReleaseFiles "Release"
|
|
|
|
Lepton-OkMessage "Checked install type: ${leptonInstallType}"
|
|
if ( "${leptonInstallType}" -eq "Network" ) {
|
|
Select-Distribution
|
|
}
|
|
if ( "${leptonInstallType}" -eq "Local" ) {
|
|
if ( Test-Path -Path ".git" -PathType "Container" ) {
|
|
Select-Distribution
|
|
git checkout "${leptonBranch}"
|
|
}
|
|
}
|
|
}
|
|
|
|
#== Custom Install =============================================================
|
|
$customFiles = @(
|
|
"user-overrides.js",
|
|
"userChrome-overrides.css",
|
|
"userContent-overrides.css"
|
|
)
|
|
$localCustomFiles = $customFiles.Clone()
|
|
|
|
$customFileExist = $false
|
|
function Check-CustomFiles() {
|
|
$global:localCustomFiles = Filter-Path $localCustomFiles
|
|
|
|
if ( $global:localCustomFiles.Length -gt 0 ) {
|
|
$global:customFileExist = $true
|
|
Lepton-OKMessage "Check custom file detected"
|
|
|
|
foreach ( $customFile in $global:localCustomFiles ) {
|
|
Write-Host "- ${customFile}"
|
|
}
|
|
}
|
|
}
|
|
|
|
function Copy-CustomFiles() {
|
|
if ( "${customFileExist}" -eq $true ) {
|
|
# If Release or Network mode, Local is passed (Already copied)
|
|
if ( "${leptonInstallType}" -ne "Local" ) {
|
|
foreach ( $profilePath in $global:firefoxProfilePaths ) {
|
|
foreach ( $customFile in $global:localCustomFiles ) {
|
|
if ( "${customFile}" -eq "user-overrides.js" ) {
|
|
Copy-Auto "${customFile}" "${profilePath}\${customFile}"
|
|
}
|
|
else {
|
|
Copy-Auto "${customFile}" "${profilePath}\chrome\${customFile}"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Lepton-OKMessage "End custom file copy"
|
|
}
|
|
}
|
|
|
|
$customMethod = ""
|
|
$customReset = $false
|
|
$customAppend = $false
|
|
function Set-CustomMethod() {
|
|
$local:menuAppend="Append - Maintain changes in existing files and apply custom"
|
|
$local:menuOverwrite="Overwrite - After initializing the change, apply only custom"
|
|
$local:menuNone="None - Maintain changes in existing files"
|
|
$local:menuReset="Reset- Reset to pure lepton theme without custom"
|
|
|
|
Write-Host "Select custom method"
|
|
while ( "${customMethod}" -eq "" ) {
|
|
$local:applyMethod = Menu @("${menuAppend}", "${menuOverwrite}", "${menuNone}", "${menuReset}")
|
|
switch ( $applyMethod ) {
|
|
"${menuAppend}" {
|
|
$global:customMethod = "Append"
|
|
$global:customAppend = $true
|
|
}
|
|
"${menuOverwrite}" {
|
|
$global:customMethod = "Overwrite"
|
|
$global:customReset = $true
|
|
$global:customAppend = $true
|
|
}
|
|
"${menuNone}" {
|
|
$global:customMethod = "None"
|
|
}
|
|
"${menuReset}" {
|
|
$global:customMethod = "Reset"
|
|
$global:customReset = $true
|
|
}
|
|
default { Write-Host "Invalid option, reselect please." }
|
|
}
|
|
}
|
|
|
|
Lepton-OKMessage "Selected ${customMethod}"
|
|
}
|
|
|
|
$customFileApplied = $false
|
|
function Apply-CustomFile() {
|
|
Param (
|
|
[Parameter(Mandatory=$true, Position=0)]
|
|
[string] $profilePath,
|
|
[Parameter(Mandatory=$true, Position=1)]
|
|
[string] $targetPath,
|
|
[Parameter(Mandatory=$true, Position=2)]
|
|
[string] $customPath,
|
|
[Parameter(Position=3)]
|
|
[string] $otherCustomPath = ""
|
|
)
|
|
|
|
$local:leptonDir = "${profilePath}\chrome"
|
|
$local:gitDir = "${leptonDir}\.git"
|
|
if ( Test-Path -Path "${customPath}" -PathType leaf ) {
|
|
$global:customFileApplied = $true
|
|
|
|
if ( "${customMethod}" -eq "" ) {
|
|
Set-CustomMethod
|
|
}
|
|
|
|
if ( "${customReset}" -eq $true ) {
|
|
if ( "${targetPath}" -like "*user.js" ) {
|
|
Copy-Item -Path "${leptonDir}\user.js" -Destination "${targetPath}" -Force
|
|
}
|
|
else {
|
|
git --git-dir "${gitDir}" --work-tree "${leptonDir}" checkout HEAD -- "${targetPath}"
|
|
}
|
|
}
|
|
if ( "${customAppend}" -eq $true ) {
|
|
# Apply without duplication
|
|
if ( -not (Write-Output "$(Write-Output $(Get-Content -Path "${targetPath}"))" | Select-String -Pattern "$(Write-Output $(Get-Content -Path "${customPath}"))" -SimpleMatch -Quiet) ) {
|
|
Get-Content -Path "${customPath}" | Out-File -FilePath "${targetPath}" -Append
|
|
}
|
|
}
|
|
}
|
|
elseif ( "${otherCustomPath}" -ne "" ) {
|
|
Apply-CustomFile "${profilePath}" "${targetPath}" "${otherCustomPath}"
|
|
}
|
|
}
|
|
|
|
function Apply-CustomFiles() {
|
|
foreach ( $profilePath in $global:firefoxProfilePaths ) {
|
|
foreach ( $customFile in $global:customFiles ) {
|
|
$local:targetFile = $customFile.Replace("-overrides", "")
|
|
if ( "${customFile}" -eq "user-overrides.js" ) {
|
|
$local:targetPath = "${profilePath}\${targetFile}"
|
|
$local:customPath = "${profilePath}\user-overrides.js"
|
|
$local:otherCustomPath = "${profilePath}\chrome\user-overrides.js"
|
|
Apply-CustomFile "${profilePath}" "${targetPath}" "${customPath}" "${otherCustomPath}"
|
|
}
|
|
else {
|
|
Apply-CustomFile "${profilePath}" "${profilePath}\chrome\${targetFile}" "${profilePath}\chrome\${customFile}"
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( "${customFileApplied}" -eq $true ) {
|
|
Lepton-OKMessage "End custom file applied"
|
|
}
|
|
}
|
|
|
|
#== Install Helpers ============================================================
|
|
$chromeDuplicate = $false
|
|
function Check-ChromeExist() {
|
|
if ( (Test-Path -Path "chrome") -and (-Not (Test-Path -Path "chrome\${LEPTONINFOFILE}")) ) {
|
|
$global:chromeDuplicate = $true
|
|
Move-Auto "chrome" "chrome.bak"
|
|
Lepton-OkMessage "Backup files"
|
|
}
|
|
}
|
|
function Check-ChromeRestore() {
|
|
if ( "${chromeDuplicate}" -eq $true ) {
|
|
Restore-Auto "chrome"
|
|
Lepton-OkMessage "End restore files"
|
|
}
|
|
Lepton-OkMessage "End check restore files"
|
|
}
|
|
|
|
function Clean-Lepton() {
|
|
if ( ($chromeDuplicate -ne $true) -and (Test-Path -Path "chrome") ) {
|
|
Remove-Item -Path "chrome" -Recurse -Force
|
|
}
|
|
Lepton-OkMessage "End clean files"
|
|
}
|
|
function Clone-Lepton() {
|
|
Param (
|
|
[Parameter(Position=0)]
|
|
[string] $branch = ""
|
|
)
|
|
|
|
if ( "${branch}" -eq "" ) {
|
|
$branch = "${leptonBranch}"
|
|
}
|
|
|
|
git clone -b "${branch}" https://github.com/black7375/Firefox-UI-Fix.git chrome
|
|
if ( -Not (Test-Path -Path "chrome" -PathType "Container") ) {
|
|
Lepton-ErrorMessage "Unable to find downloaded files"
|
|
}
|
|
}
|
|
|
|
function Copy-Lepton() {
|
|
Param (
|
|
[Parameter(Position=0)]
|
|
[string] $chromeDir = "chrome",
|
|
[Parameter(Position=1)]
|
|
[string] $userJSPath = "${chromeDir}\user.js"
|
|
)
|
|
|
|
foreach ( $profilePath in $global:firefoxProfilePaths ) {
|
|
Copy-Auto "${userJSPath}" "${profilePath}\user.js"
|
|
Copy-Auto "${chromeDir}" "${profilePath}\chrome"
|
|
}
|
|
|
|
Lepton-OkMessage "End profile copy"
|
|
}
|
|
|
|
#== Each Install ===============================================================
|
|
function Install-Local() {
|
|
Copy-Lepton "${currentDir}" "user.js"
|
|
Copy-CustomFiles
|
|
|
|
Apply-CustomFiles
|
|
}
|
|
|
|
function Install-Release() {
|
|
Copy-Lepton "chrome" "user.js"
|
|
Copy-CustomFiles
|
|
|
|
Apply-CustomFiles
|
|
}
|
|
|
|
function Install-Network() {
|
|
Check-ChromeExist
|
|
Check-Git
|
|
|
|
Clone-Lepton
|
|
Copy-Lepton
|
|
Copy-CustomFiles
|
|
|
|
Clean-Lepton
|
|
Check-ChromeRestore
|
|
|
|
Apply-CustomFiles
|
|
}
|
|
|
|
function Install-Profile() {
|
|
Lepton-OkMessage "Started install"
|
|
|
|
switch ( "${leptonInstallType}" ) {
|
|
"Local" { Install-Local }
|
|
"Release" { Install-Release }
|
|
"Network" { Install-Network }
|
|
}
|
|
|
|
Lepton-OkMessage "End install"
|
|
}
|
|
|
|
#** Update *********************************************************************
|
|
function Stash-File() {
|
|
Param (
|
|
[Parameter(Mandatory=$true, Position=0)]
|
|
[string] $leptonDir,
|
|
[Parameter(Mandatory=$true, Position=1)]
|
|
[string] $gitDir
|
|
)
|
|
|
|
if ( "$(git --git-dir "${gitDir}" --work-tree "${leptonDir}" diff --stat)" -ne '' ) {
|
|
git --git-dir "${gitDir}" --work-tree "${leptonDir}" stash --quiet
|
|
return $true
|
|
}
|
|
return $false
|
|
}
|
|
function Restore-File() {
|
|
Param (
|
|
[Parameter(Mandatory=$true, Position=0)]
|
|
[string] $leptonDir,
|
|
[Parameter(Mandatory=$true, Position=1)]
|
|
[string] $gitDir,
|
|
[Parameter(Position=2)]
|
|
[string] $gitDirty = "$false"
|
|
)
|
|
|
|
if ( "${gitDirty}" -eq $true ) {
|
|
git --git-dir "${gitDir}" --work-tree "${leptonDir}" stash pop --quiet
|
|
}
|
|
}
|
|
|
|
function Update-Profile() {
|
|
Check-Git
|
|
foreach ( $profileDir in $global:firefoxProfileDirPaths ) {
|
|
$local:LEPTONINFOPATH = "${profileDir}\${LEPTONINFOFILE}"
|
|
$local:LEPTONINFO = Get-IniContent "${LEPTONINFOPATH}"
|
|
$local:sections = $LEPTONINFO.Keys
|
|
if ( $sections.Length -ne 0 ) {
|
|
foreach ( $section in $sections ) {
|
|
$local:Type = $LEPTONINFO["${section}"]["Type"]
|
|
$local:Branch = $LEPTONINFO["${section}"]["Branch"]
|
|
$local:Path = $LEPTONINFO["${section}"]["Path"]
|
|
|
|
$local:leptonDir = "${Path}\chrome"
|
|
$local:gitDir = "${leptonDir}\.git"
|
|
if ( "${Type}" -eq "Git" ) {
|
|
$local:gitDirty = $(Stash-File "${leptonDir}" "${gitDir}")
|
|
|
|
git --git-dir "${gitDir}" --work-tree "${leptonDir}" checkout "${Branch}"
|
|
git --git-dir "${gitDir}" --work-tree "${leptonDir}" pull --no-edit
|
|
|
|
Restore-File "${leptonDir}" "${gitDir}" "$gitDirty"
|
|
}
|
|
elseif ( "${Type}" -eq "Local" -or "${Type}" -eq "Release" ) {
|
|
Check-ChromeExist
|
|
Clone-Lepton
|
|
|
|
$firefoxProfilePaths = @("${Path}")
|
|
Copy-Lepton
|
|
|
|
if ( "${Branch}" -eq $null ) {
|
|
$Branch = "${leptonBranch}"
|
|
}
|
|
git --git-dir "${gitDir}" --work-tree "${leptonDir}" checkout "${Branch}"
|
|
|
|
if ( "${Type}" -eq "Release" ) {
|
|
$local:Ver=$(git --git-dir "${gitDir}" describe --tags --abbrev=0)
|
|
git --git-dir "${gitDir}" --work-tree "${leptonDir}" checkout "tags/${Ver}"
|
|
}
|
|
|
|
Clean-Lepton
|
|
Check-ChromeRestore
|
|
}
|
|
else {
|
|
Lepton-ErrorMessage "Unable to find update type, ${Type} at ${section}"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Apply-CustomFiles
|
|
}
|
|
|
|
#** Main ***********************************************************************
|
|
function Check-Help {
|
|
# Cheap and dirty way of getting the same output as '-?' for '-h' and '-Help'
|
|
if ($help) {
|
|
Get-Help "$PSCommandPath"
|
|
exit 0
|
|
}
|
|
}
|
|
|
|
function Install-Lepton {
|
|
Verify-PowerShellVersion # Check installed version meets minimum
|
|
Check-InstallTypes
|
|
|
|
Check-ProfileDir $profileDir
|
|
Check-ProfileIni
|
|
Update-ProfilePaths
|
|
Write-LeptonInfo
|
|
|
|
Check-CustomFiles
|
|
|
|
if ( $updateMode ) {
|
|
Update-Profile
|
|
}
|
|
else {
|
|
Select-Profile $profileName
|
|
Install-Profile
|
|
}
|
|
|
|
Write-LeptonInfo
|
|
}
|
|
|
|
Check-Help
|
|
Install-Lepton
|