diff --git a/.gitattributes b/.gitattributes index ed814f1..498a943 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,4 +1,5 @@ /.gitattributes export-ignore +/.gitignore export-ignore /.github export-ignore /CODE_OF_CONDUCT.md export-ignore -/README.org export-ignore \ No newline at end of file +/README.org export-ignore diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index bb80eae..9a6637a 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -2,7 +2,7 @@ name: Bug report about: Create a report to help us improve title: '' -labels: bug +labels: Issue::Bug assignees: '' --- @@ -17,6 +17,10 @@ A clear and concise description of what you expected to happen. If applicable, add screenshots to help explain your problem. **Environment (please complete the following information):** +Check like `- [x]`. + - Distribution + - [ ] [Original Lepton](https://github.com/black7375/Firefox-UI-Fix) + - [ ] [Lepton's photon style](https://github.com/black7375/Firefox-UI-Fix/tree/photon-style) - Firefox Version: [write from `about:support` - `version`] - OS: - [ ] Linux diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ce5e692..8d5270c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -18,14 +18,24 @@ jobs: with: ref: ${{ matrix.branch }} + - name: Info file Creation + run: | + rm -f LEPTON + + # or BRANCH=$(git rev-parse --abbrev-ref HEAD) + BRANCH=${{ matrix.branch }} + TAGVER=$(git describe --tags --abbrev=0) + + echo -e "Ver=${TAGVER}\nBranch=${BRANCH}" > LEPTON + - name: Release Structure run: | mkdir -v chrome shopt -s extglob - mv -v !(chrome|user.js) chrome/ + mv -v !(chrome|user.js|install.sh) chrome/ - zip -rv ${{ matrix.name }}.zip chrome user.js + zip -rv ${{ matrix.name }}.zip chrome user.js install.sh - uses: softprops/action-gh-release@v1 # actions/create-release, actions/upload-release-asset is deprecated if: startsWith(github.ref, 'refs/tags/') diff --git a/.github/workflows/shellcheck.yml b/.github/workflows/shellcheck.yml deleted file mode 100644 index c1c8c94..0000000 --- a/.github/workflows/shellcheck.yml +++ /dev/null @@ -1,18 +0,0 @@ -on: - push: - branches: - - master - - photon-style - pull_request: - branches: - - master -name: 'ShellCheck' - -jobs: - shellcheck: - name: Shellcheck - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Run ShellCheck - uses: ludeeus/action-shellcheck@master diff --git a/CREDITS b/CREDITS index b9a608b..bd5eea3 100644 --- a/CREDITS +++ b/CREDITS @@ -1,9 +1,9 @@ This is at least a partial credits-file of people that have contributed to the 'Firefox-UI-Fix' project. It is sorted by name. - The fields are: name (N), email (E), web-address(W), license(L). + The fields are: name (N), email (E), web-address(W), license(L). Thanks, - black7375 + black7375 ---------- Reference Projects & Resources @@ -22,6 +22,10 @@ N: firefox-csshacks W: https://github.com/MrOtherGuy/firefox-csshacks L: MPL 2.0 +N: Fluent UI System Icons +W: https://github.com/microsoft/fluentui-system-icons +L: MIT + N: gecko-dev W: https://hg.mozilla.org/ L: MPL 2.0 @@ -87,6 +91,9 @@ W: https://github.com/Nyubis N: SanderTheDragon E: sanderthedragon@zoho.com +N: Sylvain +E: B00ze64@hotmail.com + N: Yunsup Sim E: pedogunu@gmail.com W: https://ethansup.net diff --git a/LEPTON b/LEPTON new file mode 100644 index 0000000..1e76b9c --- /dev/null +++ b/LEPTON @@ -0,0 +1 @@ +Branch=master diff --git a/icons/arrow-repeat-all.svg b/icons/arrow-repeat-all.svg new file mode 100644 index 0000000..04d35f3 --- /dev/null +++ b/icons/arrow-repeat-all.svg @@ -0,0 +1,3 @@ + + + diff --git a/icons/arrow-sort-down-lines.svg b/icons/arrow-sort-down-lines.svg new file mode 100644 index 0000000..c3efd48 --- /dev/null +++ b/icons/arrow-sort-down-lines.svg @@ -0,0 +1,3 @@ + + + diff --git a/icons/arrow-swap.svg b/icons/arrow-swap.svg new file mode 100644 index 0000000..3e9cd87 --- /dev/null +++ b/icons/arrow-swap.svg @@ -0,0 +1,4 @@ + + + + diff --git a/icons/book-add.svg b/icons/book-add.svg new file mode 100644 index 0000000..701f923 --- /dev/null +++ b/icons/book-add.svg @@ -0,0 +1,3 @@ + + + diff --git a/icons/book.svg b/icons/book.svg new file mode 100644 index 0000000..e60114d --- /dev/null +++ b/icons/book.svg @@ -0,0 +1,4 @@ + + + + diff --git a/icons/broom.svg b/icons/broom.svg new file mode 100644 index 0000000..7428fad --- /dev/null +++ b/icons/broom.svg @@ -0,0 +1,3 @@ + + + diff --git a/icons/calendar-agenda.svg b/icons/calendar-agenda.svg new file mode 100644 index 0000000..dd6470c --- /dev/null +++ b/icons/calendar-agenda.svg @@ -0,0 +1,3 @@ + + + diff --git a/icons/checkmark-circle.svg b/icons/checkmark-circle.svg new file mode 100644 index 0000000..accc8e0 --- /dev/null +++ b/icons/checkmark-circle.svg @@ -0,0 +1,3 @@ + + + diff --git a/icons/code.svg b/icons/code.svg new file mode 100644 index 0000000..e9aa4fc --- /dev/null +++ b/icons/code.svg @@ -0,0 +1,3 @@ + + + diff --git a/icons/copy-select.svg b/icons/copy-select.svg new file mode 100644 index 0000000..0d56800 --- /dev/null +++ b/icons/copy-select.svg @@ -0,0 +1,3 @@ + + + diff --git a/icons/document-landscape-split-hint.svg b/icons/document-landscape-split-hint.svg new file mode 100644 index 0000000..fc9f621 --- /dev/null +++ b/icons/document-landscape-split-hint.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/icons/eye-hide.svg b/icons/eye-hide.svg new file mode 100644 index 0000000..2b64e30 --- /dev/null +++ b/icons/eye-hide.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/icons/eye-show.svg b/icons/eye-show.svg new file mode 100644 index 0000000..51e4fb5 --- /dev/null +++ b/icons/eye-show.svg @@ -0,0 +1,4 @@ + + + + diff --git a/icons/image-add.svg b/icons/image-add.svg new file mode 100644 index 0000000..871abf8 --- /dev/null +++ b/icons/image-add.svg @@ -0,0 +1,3 @@ + + + diff --git a/icons/image-alt-text.svg b/icons/image-alt-text.svg new file mode 100644 index 0000000..f568344 --- /dev/null +++ b/icons/image-alt-text.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/icons/image-arrow-counterclockwise.svg b/icons/image-arrow-counterclockwise.svg new file mode 100644 index 0000000..782ff9c --- /dev/null +++ b/icons/image-arrow-counterclockwise.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/icons/image-copy.svg b/icons/image-copy.svg new file mode 100644 index 0000000..6140e6f --- /dev/null +++ b/icons/image-copy.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/icons/image.svg b/icons/image.svg new file mode 100644 index 0000000..863c9d7 --- /dev/null +++ b/icons/image.svg @@ -0,0 +1,9 @@ + + + + + + + diff --git a/icons/key-multiple.svg b/icons/key-multiple.svg new file mode 100644 index 0000000..36f5121 --- /dev/null +++ b/icons/key-multiple.svg @@ -0,0 +1,3 @@ + + + diff --git a/icons/link-square.svg b/icons/link-square.svg new file mode 100644 index 0000000..36362fe --- /dev/null +++ b/icons/link-square.svg @@ -0,0 +1,4 @@ + + + + diff --git a/icons/password.svg b/icons/password.svg new file mode 100644 index 0000000..a485de7 --- /dev/null +++ b/icons/password.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/icons/paste.svg b/icons/paste.svg new file mode 100644 index 0000000..339916a --- /dev/null +++ b/icons/paste.svg @@ -0,0 +1,9 @@ + + + + + + + diff --git a/icons/pin-tab.svg b/icons/pin-tab.svg new file mode 100644 index 0000000..1f951a3 --- /dev/null +++ b/icons/pin-tab.svg @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/icons/play.svg b/icons/play.svg new file mode 100644 index 0000000..756dcc2 --- /dev/null +++ b/icons/play.svg @@ -0,0 +1,3 @@ + + + diff --git a/icons/resize-image.svg b/icons/resize-image.svg new file mode 100644 index 0000000..c68de66 --- /dev/null +++ b/icons/resize-image.svg @@ -0,0 +1,3 @@ + + + diff --git a/icons/select-all-on.svg b/icons/select-all-on.svg new file mode 100644 index 0000000..88c9496 --- /dev/null +++ b/icons/select-all-on.svg @@ -0,0 +1,3 @@ + + + diff --git a/icons/star-line-horizontal.svg b/icons/star-line-horizontal.svg new file mode 100644 index 0000000..734beba --- /dev/null +++ b/icons/star-line-horizontal.svg @@ -0,0 +1,3 @@ + + + diff --git a/icons/tab-copy.svg b/icons/tab-copy.svg new file mode 100644 index 0000000..427332b --- /dev/null +++ b/icons/tab-copy.svg @@ -0,0 +1,4 @@ + + + + diff --git a/icons/tab-multiple.svg b/icons/tab-multiple.svg new file mode 100644 index 0000000..f77d817 --- /dev/null +++ b/icons/tab-multiple.svg @@ -0,0 +1,4 @@ + + + + diff --git a/icons/tab.svg b/icons/tab.svg new file mode 100644 index 0000000..1d13dd1 --- /dev/null +++ b/icons/tab.svg @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/icons/text-direction-horizontal-ltr.svg b/icons/text-direction-horizontal-ltr.svg new file mode 100644 index 0000000..e5ad45e --- /dev/null +++ b/icons/text-direction-horizontal-ltr.svg @@ -0,0 +1,3 @@ + + + diff --git a/icons/text-number-format.svg b/icons/text-number-format.svg new file mode 100644 index 0000000..fb4d19b --- /dev/null +++ b/icons/text-number-format.svg @@ -0,0 +1,3 @@ + + + diff --git a/icons/text-proofing-tools.svg b/icons/text-proofing-tools.svg new file mode 100644 index 0000000..038e9e1 --- /dev/null +++ b/icons/text-proofing-tools.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/icons/text-sort-ascending.svg b/icons/text-sort-ascending.svg new file mode 100644 index 0000000..d5613d1 --- /dev/null +++ b/icons/text-sort-ascending.svg @@ -0,0 +1,3 @@ + + + diff --git a/icons/time-picker.svg b/icons/time-picker.svg new file mode 100644 index 0000000..75cf3d4 --- /dev/null +++ b/icons/time-picker.svg @@ -0,0 +1,3 @@ + + + diff --git a/icons/unpin-tab.svg b/icons/unpin-tab.svg new file mode 100644 index 0000000..bd2b382 --- /dev/null +++ b/icons/unpin-tab.svg @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/icons/vertical-line.svg b/icons/vertical-line.svg new file mode 100644 index 0000000..c8d4ad4 --- /dev/null +++ b/icons/vertical-line.svg @@ -0,0 +1 @@ + diff --git a/icons/video-clip.svg b/icons/video-clip.svg new file mode 100644 index 0000000..8be8616 --- /dev/null +++ b/icons/video-clip.svg @@ -0,0 +1,3 @@ + + + diff --git a/icons/video-snapshot.svg b/icons/video-snapshot.svg new file mode 100644 index 0000000..be15181 --- /dev/null +++ b/icons/video-snapshot.svg @@ -0,0 +1,3 @@ + + + diff --git a/icons/video.svg b/icons/video.svg new file mode 100644 index 0000000..4d1fd9e --- /dev/null +++ b/icons/video.svg @@ -0,0 +1,3 @@ + + + diff --git a/install.sh b/install.sh old mode 100644 new mode 100755 index ce0f73b..afa661c --- a/install.sh +++ b/install.sh @@ -1,107 +1,766 @@ #!/usr/bin/env bash -# shellcheck disable=SC2185 -function copychrome(){ - \cp -f userChrome.css ~/.mozilla/firefox/"$1"/chrome/userChrome.css - \cp -f userContent.css ~/.mozilla/firefox/"$1"/chrome/userContent.css - \cp -f -r icons ~/.mozilla/firefox/"$1"/chrome/ + +#** Helper Utils *************************************************************** +#== Message ==================================================================== +lepton_error_message() { + >&2 echo "FAILED: ${@}" + exit 1 } -function backupchrome(){ - if [ -f ~/.mozilla/firefox/"$1"/chrome/userChrome.css ];then - \mv -f ~/.mozilla/firefox/"$1"/chrome/userChrome.css ~/.mozilla/firefox/"$1"/chrome/userChrome.css.bak - \mv -f ~/.mozilla/firefox/"$1"/chrome/userContent.css ~/.mozilla/firefox/"$1"/chrome/userContent.css.bak + +lepton_ok_message() { + local SIZE=50 + local FILLED="" + for ((i=0; i<=$((SIZE - 2)); i++)); do + FILLED+="." + done + FILLED+="OK" + + local message="${@}" + echo "${message}${FILLED:${#message}}" +} + +lepton_spinner() { + local chars="/-\|" + + for (( i=0; i<${#chars}; i++ )); do + sleep 0.5 + echo -en "${chars:$i:1}" "\r" + done +} + +#== Required Tools ============================================================= +PACAPT_PATH="/usr/local/bin/pacapt" +PACAPT_INSTALLED=true +pacapt_install() { + if ! [ -x "$(command -v pacapt)" ]; then + echo "Universal Package Manager(icy/pacapt) Download && Install(need sudo permission)" + echo "It is installed temporarily and will be removed when installation is complete." + sudo curl https://github.com/icy/pacapt/raw/ng/pacapt -Lo "${PACAPT_PATH}" + sudo chmod 755 "${PACAPT_PATH}" + sudo ln -sv "${PACAPT_PATH}" /usr/local/bin/pacman || true + PACAPT_INSTALLED=false fi - cd ~/.mozilla/firefox/"$1"/chrome/icons || exit - if [ -f ~/.mozilla/firefox/"$1"/chrome/icons/bug.svg ];then - for file in * - do - \mv -f "$file" "${file/.svg/.svg.bak}" + sudo pacapt -Sy +} + +pacapt_uninstall() { + if [[ "${PACAPT_INSTALLED}" == false ]]; then + sudo rm -rf "${PACAPT}" + fi +} + +mac_command_line_developer_tools() { + # https://unix.stackexchange.com/questions/408280/until-statement-waiting-for-process-to-finish-being-ignored + XCODE_MESSAGE="$(osascript -e 'tell app "System Events" to display dialog "Please click install when Command Line Developer Tools appears"')" + if [ "$XCODE_MESSAGE" = "button returned:OK" ]; then + xcode-select --install + else + lepton_error_message "You have cancelled the installation, please rerun the installer." + fi + + until [ "$(xcode-select -p 1>/dev/null 2>&1; echo $?)" -eq 0 ]; do + lepton_spinner + done + echo "" + lepton_ok_message "Installed Command Line Developer Tools" +} + +check_git() { + if ! [ -x "$(command -v git)" ]; then + if [ "${OSTYPE}" == "linux-gnu" ] || [ "${OSTYPE}" == "FreeBSD" ]; then + pacapt_install + sudo pacapt -S git + pacapt_uninstall + elif [[ "${OSTYPE}" == "darwin"* ]]; then + mac_command_line_developer_tools + else + lepton_error_message "OS NOT DETECTED, couldn't install required packages" + fi + fi + + if [[ "${OSTYPE}" == "darwin"* ]]; then + if ! [ "$(git --help 1>/dev/null 2>&1; echo $?)" -eq 0 ]; then + mac_command_line_developer_tools + fi + fi + lepton_ok_message "Required - git" +} + +#== PATH / File ================================================================ +currentDir=$( cd "$(dirname $0)" ; pwd ) + +paths_filter() { + local pathListName="$1" # array name + local option="$2" + + # Set array + eval "local pathList=(\"\${${pathListName}[@]}\")" + + # Set default option + if [ -z "$option" ]; then + option="-e" + fi + + # Check path + local foundedTargets=() + for checkTarget in "${pathList[@]}"; do + if [ "$option" "$checkTarget" ]; then + foundedTargets+=("$checkTarget") + fi + done + + # Replace + eval "${pathListName}=(\"\${foundedTargets[@]}\")" +} + +autocopy() { + local file="${1}" + local target="${2}" + + if [ "${file}" == "${target}" ]; then + echo "'${file}' and ${target} are same file" + return 0 + fi + + if [ -e "${target}" ]; then + echo "${target} alreay exist." + echo "Now Backup.." + autocopy "${target}" "${target}.bak" + echo "" + fi + + cp -rf "${file}" "${target}" +} + +automv() { + local file="${1}" + local target="${2}" + + if [ "${file}" == "${target}" ]; then + echo "'${file}' and ${target} are same file" + return 0 + fi + + if [ -e "${target}" ]; then + echo "${target} alreay exist." + echo "Now Backup.." + automv "${target}" "${target}.bak" + echo "" + fi + + mv -f "${file}" "${target}" +} + +autorestore() { + local file="${1}" + local target="${file}.bak" + + if [ -e "${file}" ]; then + rm -rf "${file}" + fi + mv -f "${target}" "${file}" + + local lookupTarget="${target}.bak" + if [ -e "${lookupTarget}" ]; then + autorestore "${target}" + fi +} + +write_file() { + local filePath="$1" + local fileContent="$2" + + if [ -z "${fileContent}" ]; then + if [ -e "${filePath}" ]; then + rm -rf "${filePath}" + fi + touch "${filePath}" + else + echo -e "${fileContent}" | tee "${filePath}" > /dev/null + fi +} + +#== INI File ================================================================ +get_ini_section() { + local filePath="$1" + + local ouput=$(grep -E "^\[" "${filePath}" |sed -e "s/^\[//g" -e "s/\]$//g") + echo "${ouput}" +} +get_ini_value() { + local filePath="$1" + local key="$2" + local section="$3" + + local output="" + if [ "${section}" == "" ]; then + output=$(grep -E "^${key}" "${filePath}" | cut -f 2 -d"=") + echo "${output}" + else + local sectionStart="" + for line in $(cat "${filePath}"); do + if [[ "${sectionStart}" == "true" && "${line}" == "["* ]]; then + return 0 + fi + + if [ "${line}" == "[${section}]" ]; then + sectionStart="true" + fi + + if [ "${sectionStart}" == "true" ]; then + output=$(echo "${line}" | grep -E "^${key}" | cut -f 2 -d"=" ) + if [ "${output}" != "" ]; then + echo "${output}" + fi + fi done fi - cd "$wherewasi" || exit } -function backupjs(){ - \mv -f ~/.mozilla/firefox/"$1"/user.js ~/.mozilla/firefox/"$1"/user.js.bak + +set_ini_section() { + local section="$1" + echo "[${section}]\n" } -function copyjs(){ - \cp -f user.js ~/.mozilla/firefox/"$1"/user.js +set_ini_value() { + local key="$1" + local value="$2" + + if [ "${value}" == "" ]; then + echo "" + else + echo "${key}=${value}\n" + fi } -function doneinstall() -{ - echo "Installation finished." + +#== Multiselect ================================================================ +# https://stackoverflow.com/questions/45382472/bash-select-multiple-answers-at-once/54261882 +multiselect() { + echo 'Select with , Done with !!!' + + # little helpers for terminal print control and key input + ESC=$( printf "\033") + cursor_blink_on() { printf "$ESC[?25h"; } + cursor_blink_off() { printf "$ESC[?25l"; } + cursor_to() { printf "$ESC[$1;${2:-1}H"; } + print_inactive() { printf "$2 $1 "; } + print_active() { printf "$2 $ESC[7m $1 $ESC[27m"; } + get_cursor_row() { IFS=';' read -sdR -p $'\E[6n' ROW COL; echo ${ROW#*[}; } + key_input() { + local key + IFS= read -rsn1 key 2>/dev/null >&2 + if [[ $key = "" ]]; then echo enter; fi; + if [[ $key = $'\x20' ]]; then echo space; fi; + if [[ $key = $'\x1b' ]]; then + read -rsn2 key + if [[ $key = [A ]]; then echo up; fi; + if [[ $key = [B ]]; then echo down; fi; + fi + } + toggle_option() { + local arr_name=$1 + eval "local arr=(\"\${${arr_name}[@]}\")" + local option=$2 + if [[ ${arr[option]} == true ]]; then + arr[option]= + else + arr[option]=true + fi + eval $arr_name='("${arr[@]}")' + } + + local retval=$1 + local options + local defaults + + IFS=';' read -r -a options <<< "$2" + if [[ -z $3 ]]; then + defaults=() + else + IFS=';' read -r -a defaults <<< "$3" + fi + local selected=() + + for ((i=0; i<${#options[@]}; i++)); do + selected+=("${defaults[i]}") + printf "\n" + done + + # determine current screen position for overwriting the options + local lastrow=`get_cursor_row` + local startrow=$(($lastrow - ${#options[@]})) + + # ensure cursor and input echoing back on upon a ctrl+c during read -s + trap "cursor_blink_on; stty echo; printf '\n'; exit" 2 + cursor_blink_off + + local active=0 + while true; do + # print options by overwriting the last lines + local idx=0 + for option in "${options[@]}"; do + local prefix="[ ]" + if [[ ${selected[idx]} == true ]]; then + prefix="[x]" + fi + + cursor_to $(($startrow + $idx)) + if [ $idx -eq $active ]; then + print_active "$option" "$prefix" + else + print_inactive "$option" "$prefix" + fi + ((idx++)) + done + + # user key control + case `key_input` in + space) toggle_option selected $active;; + enter) break;; + up) ((active--)); + if [ $active -lt 0 ]; then active=$((${#options[@]} - 1)); fi;; + down) ((active++)); + if [ $active -ge ${#options[@]} ]; then active=0; fi;; + esac + done + + # cursor position back to normal + cursor_to $lastrow + printf "\n" + cursor_blink_on + + eval $retval='("${selected[@]}")' } -function install_lepton(){ -if [ -f ~/.mozilla/firefox/"$1"/user.js ]; then - printf "user.js exists. Do you want to make a backup of it?(Y/n): " - read -r - case $REPLY in - [Nn]* ) printf "Overwriting...\n";copyjs "$1";; - * )printf "Making a backup...\n";backupjs "$1";copyjs "$1";; + +#** Profile ******************************************************************** +#== Profile Dir ================================================================ +firefoxProfileDirPaths=( + "${HOME}/.mozilla/firefox" + "${HOME}/.var/app/org.mozilla.firefox/.mozilla/firefox" + "${HOME}/Library/Application Support/Firefox" +) + +check_profile_dir() { + local profileDir="$1" + if [ "${profileDir}" != "" ]; then + firefoxProfileDirPaths=("${profileDir}") + fi + + paths_filter firefoxProfileDirPaths -d + + local foundCount="${#firefoxProfileDirPaths[@]}" + if [ "${foundCount}" -eq 0 ]; then + lepton_error_message "Unable to find firefox profile dir." + fi + + lepton_ok_message "Profiles dir found" +} + +#== Profile Info =============================================================== +PROFILEINFOFILE="profiles.ini" +check_profile_ini() { + for profileDir in "${firefoxProfileDirPaths[@]}"; do + if [ ! -f "${profileDir}/${PROFILEINFOFILE}" ]; then + lepton_error_message "Unable to find ${PROFILEINFOFILE} at ${profileDir}" + fi + done + + lepton_ok_message "Profiles info file found" +} + +#== Profile PATH =============================================================== +firefoxProfilePaths=() +update_profile_paths() { + local IFS=$'\n' + for profileDir in "${firefoxProfileDirPaths[@]}"; do + local escapeDir=$(echo "${profileDir}" | sed "s|\/|\\\/|g") + firefoxProfilePaths+=($( + get_ini_value "${profileDir}/${PROFILEINFOFILE}" "Path" | + sed "s/^/${escapeDir}\//" + )) + done + + local foundCount="${#firefoxProfilePaths[@]}" + if ! [ "${foundCount}" -eq 0 ]; then + lepton_ok_message "Profile paths updated" + else + lepton_error_message "Doesn't exist profiles" + fi +} + +select_profile() { + local profileName="$1" + + if [ "${profileName}" != "" ]; then + local targetPath="" + for profilePath in "${firefoxProfilePaths[@]}"; do + if [[ "${profilePath}" == *"${profileName}" ]]; then + targetPath="${profilePath}" + break + fi + done + + if [ "${targetPath}" != "" ]; then + lepton_ok_message "Profile, \"${profileName}\" found" + firefoxProfilePaths=("${targetPath}") + else + lepton_error_message "Unable to find ${profileName}" + fi + else + local foundCount="${#firefoxProfilePaths[@]}" + if [ "${foundCount}" -eq 1 ]; then + lepton_ok_message "Auto detected profile" + else + local multiPaths="" + for profilePath in "${firefoxProfilePaths[@]}"; do + multiPaths+="${profilePath};" + done + multiselect profileSelected "${multiPaths}" + + local targetPaths=() + for ((i=0; i<"${#profileSelected[@]}"; i++)); do + local result="${profileSelected[${i}]}" + if [ "$result" == "true" ]; then + targetPaths+=("${firefoxProfilePaths[${i}]}") + fi + done + + firefoxProfilePaths=("${targetPaths[@]}") + foundCount="${#firefoxProfilePaths[@]}" + if [ "${foundCount}" -eq 0 ]; then + lepton_error_message "Please select profiles" + fi + + lepton_ok_message "Multi selected profiles" + fi + fi +} + +#** Install ******************************************************************** +#== Install Types ============================================================== +leptonBranch="master" +select_distribution() { + select distribution in "Original(default)" "Photon-Style"; do + case "${distribution}" in + "Original") leptonBranch="master" ;; + "Photon-Style") leptonBranch="photon-style" ;; esac -else - copyjs "$1" -fi -if [ -d "$HOME/.mozilla/firefox/$1/chrome" ]; then - printf "The directory chrome/ exists. Do you want to make a backup of it?(Y/n): " - read -r - case $REPLY in - [Nn]* ) printf "Overwriting...\n";copychrome "$1";doneinstall;; - * )printf "Making a backup...\n";backupchrome "$1";copychrome "$1";doneinstall;; - esac -else - mkdir ~/.mozilla/firefox/"$1"/chrome/ - copychrome "$1" - doneinstall -fi + lepton_ok_message "Selected ${distribution}" + break + done } -function multipleinstall(){ - echo "You have more than 1 profile for your install. What will you use? Pick a number." - grep "$1" ~/.mozilla/firefox/profiles.ini | grep 'Default=' | cut -f 2 -d'=' > .installs - cat --number .installs - read -r - profiledir="$(head -"${REPLY}" .installs | tail +"${REPLY}")" - install_lepton "$profiledir" - rm -rf .installs +leptonInstallType="Network" # Other types: Local, Release +check_install_type() { + local targetListName="${1}" + local installType="${2}" + + eval "local targetCount=\${#${targetListName}[@]}" + paths_filter "${targetListName}" + eval "local foundCount=\${#${targetListName}[@]}" + + if [ "${targetCount}" -eq "${foundCount}" ]; then + leptonInstallType="${installType}" + fi } -function install_option(){ - if [ "$(grep -c "$1" ~/.mozilla/firefox/.folders)" == "1" ]; then - profiledir="$(grep "$1" ~/.mozilla/firefox/profiles.ini | grep 'Default=' | cut -f 2 -d'=')" - install_lepton "$profiledir" - else - multipleinstall "$1" +checkLocalFiles=( + userChrome.css + userContent.css + icons +) +checkReleaseFiles=( + user.js + chrome/userChrome.css + chrome/userContent.css + chrome/icons +) +check_install_types() { + check_install_type checkLocalFiles "Local" + check_install_type checkReleaseFiles "Release" + + lepton_ok_message "Checked install type: ${leptonInstallType}" + if [ "${leptonInstallType}" == "Network" ]; then + select_distribution + fi + if [ "${leptonInstallType}" == "Local" ]; then + if [ -d ".git" ]; then + select_distribution + git checkout "${leptonBranch}" + fi fi - rm -rf ~/.mozilla/firefox/.folders } -function askinstall(){ - printf "Will you install for ESR, Default, Dev, Nightly?(ESR/Default/Dev/Nightly): " - read -r - case $REPLY in - [Ee][Ss][Rr]) install_option .default-esr;; - [Dd][Ee][Ff][Aa][Uu][Ll][Tt]) install_option .default-release;; - [Dd][Ee][Vv]) install_option .dev-edition-default;; - [Nn][Ii][Gg][Hh][Tt][Ll][Yy]) install_option .default-nightly;; - *) echo "Unspecified.";exit;; + +#== Install Helpers ============================================================ +chromeDuplicate="" +check_chrome_exist() { + if [ -e "chrome" ] && [ ! -f "chrome/${LEPTONINFOFILE}" ]; then + chromeDuplicate="true" + automv chrome chrome.bak + lepton_ok_message "Backup files" + fi +} +check_chrome_restore() { + if [ "${chromeDuplicate}" == "true" ]; then + autorestore chrome + lepton_ok_message "End restore files" + fi + lepton_ok_message "End check restore files" +} + +clean_lepton() { + if [ ! "${chromeDuplicate}" == "true" ]; then + rm -rf chrome + fi + lepton_ok_message "End clean files" +} +clone_lepton() { + local branch="$1" + + if [ -z "${branch}" ]; then + branch="${leptonBranch}" + fi + + git clone -b "${branch}" https://github.com/black7375/Firefox-UI-Fix.git chrome + if ! [ -d "chrome" ]; then + lepton_error_message "Unable to find downloaded files" + fi +} + +copy_lepton() { + local chromeDir="$1" + local userJSPath="$2" + + if [ -z "${chromeDir}" ]; then + chromeDir="chrome" + fi + if [ -z "${userJSPath}" ]; then + userJSPath="${chromeDir}/user.js" + fi + + for profilePath in "${firefoxProfilePaths[@]}"; do + autocopy "${userJSPath}" "${profilePath}/user.js" + autocopy "${chromeDir}" "${profilePath}/chrome" + done + lepton_ok_message "End profile copy" +} + +#== Each Install =============================================================== +install_local() { + copy_lepton "${currentDir}" "user.js" +} + +install_release() { + copy_lepton "chrome" "user.js" +} + +install_network() { + check_chrome_exist + check_git + + clone_lepton + copy_lepton + + clean_lepton + check_chrome_restore +} + +install_profile() { + lepton_ok_message "Started install" + + case "${leptonInstallType}" in + "Local") install_local ;; + "Release") install_release ;; + "Network") install_network ;; esac + + lepton_ok_message "End install" } -wherewasi="$(pwd)" -cd ~/.mozilla/firefox/ || exit -find -maxdepth 1 | cut -f 2 -d"/" | sed -n '1!p' > .folders -cd "$wherewasi" || exit -if [ "$(grep -c "Default=" ~/.mozilla/firefox/installs.ini)" == "1" ]; then - #I have no idea how to sort this out. You fix it please. - if [ "$(grep -c ".dev-edition-default" ~/.mozilla/firefox/.folders)" == "1" ] || [ "$(grep -c ".dev-edition-default" ~/.mozilla/firefox/.folders)" -gt "1" ]; then - install_option .dev-edition-default - elif [ "$(grep -c ".default-release" ~/.mozilla/firefox/.folders)" == "1" ] || [ "$(grep -c ".default-release" ~/.mozilla/firefox/.folders)" -gt "1" ]; then - install_option .default-release - elif [ "$(grep -c ".default-nightly" ~/.mozilla/firefox/.folders)" == "1" ] || [ "$(grep -c ".default-nightly" ~/.mozilla/firefox/.folders)" -gt "1" ]; then - install_option .default-nightly - elif [ "$(grep -c ".default-esr" ~/.mozilla/firefox/.folders)" == "1" ] || [ "$(grep -c ".default-esr" ~/.mozilla/firefox/.folders)" == "1" ]; then - install_option .default-esr - else - echo "No Firefox profile found. Maybe you have never started FireFox. Please run at least 1 time to create a profile." - exit + +#** Lepton Info File *********************************************************** +#== Info File format & update policy =========================================== +## `LEPTON` file format +# If this file exist in same directory as the `userChrome.css` file, +# it is recognized as the "Lepton" installation directory. +# Branch=master | photon-style +# Ver= | | [NULL] + +## `lepton.ini` file Format +# [Profile Name] +# Type=Local | Release | Git +# Branch=master | photon-style +# Ver= | | [NULL] +# Path= + +## Update Policy +# Type +# - Local(unknown): force latest commit update +# - Release(): force latest tag update +# - Git: latest commit update + +#== Lepton Info ================================================================ +LEPTONINFOFILE="lepton.ini" +check_lepton_ini() { + for profileDir in "${firefoxProfileDirPaths[@]}"; do + if [ ! -f "${profileDir}/${LEPTONINFOFILE}" ]; then + lepton_error_message "Unable to find ${LEPTONINFOFILE} at ${profileDir}" + fi + done + + lepton_ok_message "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. + +CHROMEINFOFILE="LEPTON" +write_lepton_info() { + # Init info + local output="" + local prevDir=$(dirname "${firefoxProfilePaths[0]}") + local latestPath="${firefoxProfilePaths[${#firefoxProfilePaths[@]} - 1]}" + for profilePath in "${firefoxProfilePaths[@]}"; do + local LEPTONINFOPATH="${profilePath}/chrome/${CHROMEINFOFILE}" + local LEPTONGITPATH="${profilePath}/chrome/.git" + + # Profile info + local Type="" + local Ver="" + local Branch="" + local Path="" + if [ -f "${LEPTONINFOPATH}" ]; then + if [ -d "${LEPTONGITPATH}" ]; then + Type="Git" + Ver=$( git --git-dir "${LEPTONGITPATH}" rev-parse HEAD) + Branch=$(git --git-dir "${LEPTONGITPATH}" rev-parse --abbrev-ref HEAD) + else + Type=$( get_ini_value "${LEPTONINFOPATH}" "TYPE" ) + Ver=$( get_ini_value "${LEPTONINFOPATH}" "Ver" ) + Branch=$(get_ini_value "${LEPTONINFOPATH}" "Branch") + + if [ "${Type}" == "" ]; then + Type="Local" + fi + fi + + Path="${profilePath}" + fi + + # Flushing + local profileDir=$(dirname "${profilePath}") + local profileName=$(basename "${profilePath}") + if [ "${prevDir}" != "${profileDir}" ]; then + write_file "${prevDir}/${LEPTONINFOFILE}" "${output}" + output="" + fi + + # Make output contents + if [ -f "${LEPTONINFOPATH}" ]; then + output="${output}$(set_ini_section ${profileName})" + fi + for key in "Type" "Branch" "Ver" "Path"; do + eval "local value=\${${key}}" + output="${output}$(set_ini_value ${key} ${value})" + done + + # Latest element flushing + if [ "${profilePath}" == "${latestPath}" ]; then + write_file "${profileDir}/${LEPTONINFOFILE}" "${output}" + fi + prevDir="${profileDir}" + done + + # Verify + check_lepton_ini + lepton_ok_message "Lepton info file created" +} + +#** Update ********************************************************************* +update_profile() { + check_git + for profileDir in "${firefoxProfileDirPaths[@]}"; do + local LEPTONINFOPATH="${profileDir}/${LEPTONINFOFILE}" + local sections=$(get_ini_section "${LEPTONINFOPATH}") + if [ ! -z "${sections}" ]; then + for section in "${sections[@]}"; do + local Type=$( get_ini_value "${LEPTONINFOPATH}" "Type" "${section}") + local Branch=$(get_ini_value "${LEPTONINFOPATH}" "Branch" "${section}") + local Path=$( get_ini_value "${LEPTONINFOPATH}" "Path" "${section}") + + local LEPTONGITPATH="${Path}/chrome/.git" + if [ "${Type}" == "Git" ]; then + git --git-dir "${LEPTONGITPATH}" checkout "${Branch}" + git --git-dir "${LEPTONGITPATH}" pull --no-edit + elif [ "${Type}" == "Local" ] || [ "${Type}" == "Release" ]; then + check_chrome_exist + if [ ! -d "chrome" ]; then + clone_lepton + fi + + firefoxProfilePaths=("${Path}") + copy_lepton + + if [ -z "${Branch}" ]; then + Branch="${leptonBranch}" + fi + git --git-dir "${LEPTONGITPATH}" checkout "${Branch}" + + if [ "${Type}" == "Release" ]; then + local Ver=$(git --git-dir "${LEPTONINFOFILE}" describe --tags --abbrev=0) + git --git-dir "${LEPTONGITPATH}" checkout "tags/${Ver}" + fi + else + lepton_error_message "Unable to find update type, ${Type}" + fi + done + fi + done + clean_lepton + check_chrome_restore +} + +#** Main *********************************************************************** +install_lepton() { + local updateMode="" + local profileDir="" + local profileName="" + + # Get options. + while getopts 'u:f:p:h' flag; do + case "${flag}" in + u) updateMode="true" ;; + f) profileDir="${OPTARG}" ;; + p) profileName="${OPTARG}" ;; + h) + echo "Lepton Theme Install Script:" + echo " -u run to update mode" + echo " -f . Set custom Firefox profile folder path." + echo " -p . Set custom profile name." + echo " -h to show this message." + exit 0 + ;; + esac + done + + check_install_types + + check_profile_dir "${profileDir}" + check_profile_ini + update_profile_paths + + # Install Mode + if [ ! "${updateMode}" == true ]; then + select_profile "${profileName}" + install_profile fi -else - askinstall -fi + + write_lepton_info + + # Update Mode + if [ ! "${updateMode}" == true ]; then + update_profile + write_lepton_info + fi +} + +install_lepton "$@" diff --git a/userChrome.css b/userChrome.css index 9f1a546..e980743 100644 --- a/userChrome.css +++ b/userChrome.css @@ -1,7 +1,6 @@ @media (-moz-proton) { /** Darkmode - Color lighter ************************************************/ - :root[style*="--lwt-accent-color:rgb(12, 12, 13); --lwt-text-color:rgba(249, 249, 250);"], - :root[style*="--lwt-accent-color:rgb(28, 27, 34); --lwt-text-color:rgba(251, 251, 254);"] { + :root[lwtheme-mozlightdark][lwthemetextcolor="bright"] { --toolbar-bgcolor: rgba(43, 42, 51, 5) !important; /* Original: rgba(43, 42, 51, 1) */ } @@ -19,6 +18,11 @@ background-color: unset !important; /* Original: var(--lwt-accent-color) */ } + /* Navbar Border */ + #navigator-toolbox:-moz-lwtheme { + --tabs-border-color: rgba(0,0,0,.3); + } + /** Windows 7 - Compatibility ***********************************************/ @media (-moz-os-version: windows-win7) { /* Header Color */ @@ -152,6 +156,7 @@ } /** Tab Bar - Reduce Height, Show more contents *****************************/ + /* Toolbar Height */ :root:not([uidensity=touch]) #TabsToolbar { --toolbarbutton-inner-padding: 9px; /* Original: calc((var(--tab-min-height) - 16px) / 2) = 10px */ } @@ -166,8 +171,11 @@ max-height: unset; } + /* Scroll Button - Size Fix */ :root:not([uidensity=touch]) #tabbrowser-arrowscrollbox { --scrollbtn-vertical-padding: 3px; + --scrollbtn-vertical-border: 2px; + --scrollbtn-border-radius: 7px; } #scrollbutton-up, #scrollbutton-down { @@ -175,6 +183,12 @@ /* https://github.com/mozilla/gecko-dev/blob/71b1259afd1cdaf41871ae675c2dadb967ea5b34/browser/themes/shared/toolbarbuttons.inc.css#L142 */ padding-top: var(--scrollbtn-vertical-padding, var(--toolbarbutton-inner-padding)) !important; padding-bottom: var(--scrollbtn-vertical-padding, var(--toolbarbutton-inner-padding)) !important; + + /* Original: 4px */ + border-top-width: var(--scrollbtn-vertical-border, 4px) !important; + border-bottom-width: var(--scrollbtn-vertical-border, 4px) !important; + /* Original: calc(var(--tab-border-radius) + 4px) = 8px */ + border-radius: var(--scrollbtn-border-radius, calc(var(--tab-border-radius) + 4px)) !important; } :root[tabsintitlebar]:not([uidensity=compact]) #toolbar-menubar[autohide="true"] { @@ -369,7 +383,11 @@ padding-inline-start: 8px !important; } - #tabbrowser-tabs[closebuttons=activetab] .tabbrowser-tab:not([visuallyselected]) .tab-close-button { + #tabbrowser-tabs[closebuttons="activetab"] > #tabbrowser-arrowscrollbox > .tabbrowser-tab:not([pinned]) > .tab-stack > .tab-content > .tab-close-button:not([selected="true"]) { + display: -moz-inline-box !important; + } + + #tabbrowser-tabs[closebuttons=activetab] .tabbrowser-tab:not([visuallyselected], :hover) .tab-close-button { visibility: collapse !important; } @@ -576,28 +594,37 @@ } /** Menu - Reduce Padding ***************************************************/ - :root:not([uidensity=touch]) menupopup > menuitem, menupopup > menu { - padding-block: 0.35em !important; /* Original: 0.5em */ + :root { + --menu-padding: 0.35em; } - :root:not([uidensity=touch]) .menu-text, .menu-iconic-text { - padding-inline-end: 0 !important; /* Original: 2px */ + :root[uidensity=compact] { + --menu-padding: 0.25em; } - :root:not([uidensity=touch]) .menupopup-arrowscrollbox { - padding-block: 1px !important; /* Original: 4px*/ + :root[uidensity=touch] { + --menu-padding: 0.5em; } - :root:not([uidensity=touch]) #context-navigation:not([hidden]) { - padding: 0 0 1px !important; /* Original: 0 0 4px*/ - } - :root:not([uidensity=touch]) .menu-right { - margin-right: 6px !important; /* Original: 12px */ + menupopup > menuitem, menupopup > menu { + /* Original: 0.5em */ + padding-block: var(--menu-padding) !important; } - :root[uidensity=compact] menupopup > menuitem, menupopup > menu { - padding-block: 0.25em !important; /* Original: 0.5em */ + @supports not -moz-bool-pref("layout.css.osx-font-smoothing.enabled") { + :root:not([uidensity=touch]) .menu-text, .menu-iconic-text { + padding-inline-end: 0 !important; /* Original: 2px */ + } + :root:not([uidensity=touch]) .menupopup-arrowscrollbox { + padding-block: 1px !important; /* Original: 4px*/ + } + :root:not([uidensity=touch]) #context-navigation:not([hidden]) { + padding: 0 0 1px !important; /* Original: 0 0 4px*/ + } + :root:not([uidensity=touch]) .menu-right { + margin-right: 6px !important; /* Original: 12px */ + } } /** Panel - Icons ***********************************************************/ - /* Padding */ + /*= Padding ================================================================*/ :root { --arrowpanel-menublank-padding: calc(var(--arrowpanel-menuicon-padding) * 2 + 8px) !important; --arrowpanel-menuimageblank-padding: calc(var(--arrowpanel-menuitem-padding) - 2px) !important; @@ -648,7 +675,12 @@ -moz-context-properties: fill !important; } - /* Panel - Main */ + .subviewbutton[disabled=true] > image { + /* Ghost icons when disabled */ + opacity: 0.4; + } + + /*= Panel - Main ===========================================================*/ #appMenu-proton-addon-banners > .addon-banner-item > .toolbarbutton-icon { display: -moz-inline-box !important; margin-inline-start: var(--arrowpanel-menuicon-padding); @@ -725,7 +757,7 @@ list-style-image: url(chrome://browser/skin/quit.svg); } - /* Panel - Account */ + /*= Panel - Account ========================================================*/ #PanelUI-fxa-menu-connect-device-button .toolbarbutton-icon, #PanelUI-fxa-menu-account-signout-button .toolbarbutton-icon { width: 16px !important; @@ -735,7 +767,7 @@ /* Default */ #fxa-menu-avatar { display: -moz-inline-box !important; - margin-inline-end: var(--arrowpanel-menuitem-padding); + margin-inline-end: var(--arrowpanel-menuicon-padding); } .syncNowBtn { @@ -787,7 +819,7 @@ list-style-image: url(chrome://global/skin/icons/settings.svg); } - /* Panel - Bookmark */ + /*= Panel - Bookmark =======================================================*/ #panelMenuBookmarkThisPage { list-style-image: url(chrome://browser/skin/bookmark-hollow.svg); } @@ -806,7 +838,7 @@ list-style-image: url(chrome://browser/skin/bookmark-star-on-tray.svg); } - /* Panel - History */ + /*= Panel - History ========================================================*/ #appMenuRecentlyClosedTabs { list-style-image: url(chrome://browser/skin/tab.svg); } @@ -831,7 +863,7 @@ list-style-image: url(chrome://browser/skin/restore-session.svg); } - /* Panel - More tools */ + /*= Panel - More tools =====================================================*/ #appmenu-moreTools-button { list-style-image: url(chrome://browser/skin/customize.svg); } @@ -870,7 +902,7 @@ margin-bottom: 6px !important; } - /* Panel - Help */ + /*= Panel - Help ===========================================================*/ #appMenu_menu_openHelp { list-style-image: url(chrome://global/skin/icons/help.svg); } @@ -893,7 +925,7 @@ list-style-image: url(chrome://global/skin/icons/info.svg); } - /* Panel - Library */ + /*= Panel - Library ========================================================*/ #appMenu-library-bookmarks-button { list-style-image: url(chrome://browser/skin/bookmark.svg); } @@ -904,17 +936,20 @@ list-style-image: url(chrome://browser/skin/downloads/downloads.svg); } - /* Panel - Downloads */ + /*= Panel - Downloads ======================================================*/ #downloadsHistory { list-style-image: url(chrome://browser/skin/downloads/downloads.svg); } + #downloadsHistory .box-inherit.button-box { + display: -moz-inline-box !important; + } - /* Toolbar - Overflow Menu */ + /*= Toolbar - Overflow Menu ================================================*/ #overflowMenu-customize-button { list-style-image: url(chrome://browser/skin/customize.svg); } - /* All Tab Menu */ + /*= Tabbar - All Tab Menu ==================================================*/ #allTabsMenu-undoCloseTab { list-style-image: url(chrome://global/skin/icons/undo.svg); } @@ -932,4 +967,677 @@ #allTabsMenu-containerTabsView .subviewbutton:last-child { list-style-image: url(chrome://global/skin/icons/settings.svg); } + + /** Context Menu - Icons ****************************************************/ + /*= Layout =================================================================*/ + menupopup menuitem:not([type="checkbox"]), + menupopup menu:not([type="checkbox"]) { + -moz-appearance: none !important; /* Linux: menulist */ + } + + /* Icon */ + :not(menu, #ContentSelectDropdown) > menupopup > menuitem:not(.menuitem-iconic, [type="checkbox"], .in-menulist), + :not(menu, #ContentSelectDropdown) > menupopup > menu:not(.menu-iconic, [type="checkbox"], .in-menulist), + #blockedPopupDontShowMessage { + /* Color */ + -moz-context-properties: fill, fill-opacity !important; + fill: currentColor !important; + + /* Layout */ + background-size: 16px !important; + background-repeat: no-repeat !important; + background-image: var(--menuitem-image); + } + + /* For native context menus on macOS */ + @supports -moz-bool-pref("widget.macos.native-context-menus") { + :not(menu, #ContentSelectDropdown) > menupopup > menuitem:not(.menuitem-iconic, [type="checkbox"], .in-menulist), + :not(menu, #ContentSelectDropdown) > menupopup > menu:not(.menu-iconic, [type="checkbox"], .in-menulist) { + list-style-image: var(--menuitem-image); + } + } + + /* Padding */ + :root { + --context-menu-background-padding-default: 5px; + --context-menu-background-padding: var(--context-menu-background-padding-default); + } + :not(menu, #ContentSelectDropdown, #context-navigation) > menupopup > menuitem, + :not(menu, #ContentSelectDropdown, #context-navigation) > menupopup > menu, + #blockedPopupDontShowMessage { + background-position: left var(--context-menu-background-padding) center !important; + padding-inline-start: var(--context-menu-background-padding) !important; + } + + /* Padding - Windows */ + @media (-moz-os-version: windows-win7 ), + (-moz-os-version: windows-win8 ), + (-moz-os-version: windows-win10) { + :root { + --context-menu-background-padding: 1em; + --context-menu-text-padding: calc(var(--menu-padding) + var(--context-menu-background-padding-default) + 16px); + } + + :not(menu, #ContentSelectDropdown, #context-navigation) > menupopup > menuitem:not(.menuitem-iconic, [type="checkbox"], .in-menulist), + :not(menu, #ContentSelectDropdown, #context-navigation) > menupopup > menu:not(.menu-iconic, [type="checkbox"], .in-menulist), + #blockedPopupDontShowMessage { + padding-inline-start: calc(var(--context-menu-background-padding) + var(--context-menu-text-padding)) !important; + } + + /* Checkbox */ + :not(menu, #ContentSelectDropdown, #context-navigation) > menupopup > menuitem[type="checkbox"][checked="false"] > .menu-iconic-left { + padding-inline-start: var(--context-menu-text-padding); + } + } + + /* Padding Mac */ + @supports -moz-bool-pref("layout.css.osx-font-smoothing.enabled") { + :root { + --context-menu-background-padding-default: 10px; + --context-menu-mac-padding: 21px; + } + + /* context menu width */ + :not(menu, #ContentSelectDropdown, #context-navigation) > menupopup > menuitem:not(.menuitem-iconic, [type="checkbox"], .in-menulist), + :not(menu, #ContentSelectDropdown, #context-navigation) > menupopup > menu:not(.menu-iconic, [type="checkbox"], .in-menulist), + #blockedPopupDontShowMessage { + padding-inline-end: var(--context-menu-background-padding) !important; + } + + /* text position */ + :not(menu, #ContentSelectDropdown, #context-navigation) > menupopup > menuitem > .menu-text, + :not(menu, #ContentSelectDropdown, #context-navigation) > menupopup > menu > menu-text { + padding-inline-start: var(--context-menu-mac-padding) !important; + } + + /* Checkbox menuitem, None iconic menu */ + :not(menu, #ContentSelectDropdown, #context-navigation) > menupopup > menuitem[type="checkbox"], + :not(menu, #ContentSelectDropdown, #context-navigation) > menupopup > menu:not(.menu-iconic) { + padding-inline-start: calc(var(--context-menu-background-padding) + var(--context-menu-mac-padding)) !important; + } + } + + /*= tabContextMenu =========================================================*/ + #context_openANewTab { + --menuitem-image: url(chrome://browser/skin/new-tab.svg); + } + + #context_reloadTab, + #context_reloadSelectedTabs { + --menuitem-image: url(chrome://browser/skin/reload.svg); + } + #context_toggleMuteTab, + #context_toggleMuteSelectedTabs { + --menuitem-image: url(chrome://browser/skin/tabbrowser/tab-audio-muted-small.svg); + } + #context_toggleMuteTab[muted], + #context_toggleMuteSelectedTabs[muted] { + --menuitem-image: url(chrome://browser/skin/tabbrowser/tab-audio-playing-small.svg); + } + #context_pinTab, + #context_pinSelectedTabs { + --menuitem-image: url(./icons/pin-tab.svg); + } + #context_unpinTab, + #context_unpinSelectedTabs { + --menuitem-image: url(./icons/unpin-tab.svg); + } + #context_duplicateTab, + #context_duplicateTabs { + --menuitem-image: url(./icons/tab-copy.svg); + } + + #context_bookmarkTab, + #context_bookmarkSelectedTabs { + --menuitem-image: url(chrome://browser/skin/bookmark.svg); + } + #context_moveTabOptions { + --menuitem-image: url(./icons/arrow-swap.svg); + } + #context_sendTabToDevice { + --menuitem-image: url(chrome://browser/skin/send-to-device.svg); + } + #context_reopenInContainer { + --menuitem-image: url(./icons/container-openin-16.svg); + } + #context_selectAllTabs { + --menuitem-image: url(./icons/tab-multiple.svg); + } + + #context_closeTab { + --menuitem-image: url(chrome://global/skin/icons/close.svg); + } + #context_closeTabOptions { + } + #context_undoCloseTab { + --menuitem-image: url(chrome://global/skin/icons/undo.svg); + } + + /*= new-tab-button-popup ===================================================*/ + #new-tab-button-popup > menuitem[command="Browser:OpenAboutContainers"] { + --menuitem-image: url(chrome://global/skin/icons/settings.svg); + } + + /*= toolbar-context-menu ===================================================*/ + .customize-context-manageExtension { + --menuitem-image: url(chrome://global/skin/icons/settings.svg); + } + .customize-context-removeExtension { + --menuitem-image: url(chrome://global/skin/icons/delete.svg); + } + .customize-context-reportExtension { + --menuitem-image: url(./icons/send.svg); + } + + .customize-context-moveToPanel { + --menuitem-image: url(chrome://browser/skin/pin-12.svg); + } + .toolbar-context-autohide-downloads-button { + --menuitem-image: url(./icons/password-hide.svg); + } + .customize-context-removeFromToolbar { + --menuitem-image: url(chrome://global/skin/icons/delete.svg); + } + #toolbar-context-openANewTab { + --menuitem-image: url(chrome://browser/skin/new-tab.svg); + } + + #toolbar-context-reloadSelectedTab, + #toolbar-context-reloadSelectedTabs { + --menuitem-image: url(chrome://browser/skin/reload.svg); + } + #toolbar-context-bookmarkSelectedTab, + #toolbar-context-bookmarkSelectedTabs { + --menuitem-image: url(chrome://browser/skin/bookmark.svg); + } + #toolbar-context-selectAllTabs { + --menuitem-image: url(./icons/tab-multiple.svg); + } + #toolbar-context-undoCloseTab { + --menuitem-image: url(chrome://global/skin/icons/undo.svg); + } + + #toggle_toolbar-menubar { /* checkbox */ + /* --menuitem-image: url(./icons/calendar-agenda.svg); */ + } + #toggle_PersonalToolbar { /* Also placeContext */ + --menuitem-image: url(chrome://browser/skin/bookmarks-toolbar.svg); + } + + menuitem.viewCustomizeToolbar { + --menuitem-image: url(chrome://browser/skin/customize.svg); + } + + /*= blockedPopupOptions ====================================================*/ + #blockedPopupAllowSite { + --menuitem-image: url("chrome://global/skin/icons/check.svg"); + } + #blockedPopupOptions > menuitem[oncommand="gPopupBlockerObserver.editPopupSettings();"] { + --menuitem-image: url("chrome://global/skin/icons/edit.svg"); + } + #blockedPopupDontShowMessage { /* checkbox */ + --menuitem-image: url("chrome://global/skin/icons/blocked.svg"); + } + + /*= autohide-context =======================================================*/ + #autohide-context > menuitem[data-l10n-id="full-screen-autohide"] { /* checkbox */ + } + + #autohide-context > menuitem[data-l10n-id="full-screen-exit"] { + --menuitem-image: url(chrome://browser/skin/fullscreen-exit.svg); + } + + /*= contentAreaContextMenu =================================================*/ + #context-viewsource-goToLine { + --menuitem-image: url(./icons/text-number-format.svg); + } + #context-viewsource-wrapLongLines { /* checkbox */ + /* --menuitem-image: url(./icons/arrow-sort-down-lines.svg); */ + } + + #context-viewsource-highlightSyntax { /* checkbox */ + /* --menuitem-image: url(./icons/code.svg); */ + } + + #spell-no-suggestions { + --menuitem-image: url(./icons/text-proofing-tools.svg); + } + #spell-add-to-dictionary { + --menuitem-image: url(./icons/book-add.svg); + } + #spell-undo-add-to-dictionary { + --menuitem-image: url(chrome://global/skin/icons/undo.svg); + } + + #context-openlinkincurrent { + --menuitem-image: url(./icons/link-square.svg); + } + #context-openlinkincontainertab { + --menuitem-image: url(chrome://browser/skin/new-tab.svg); + } + #context-openlinkintab { + --menuitem-image: url(chrome://browser/skin/new-tab.svg); + } + #context-openlinkinusercontext-menu { + --menuitem-image: url(./icons/container-openin-16.svg); + } + #context-openlink { + --menuitem-image: url(chrome://browser/skin/window.svg); + } + #context-openlinkprivate { + --menuitem-image: url(chrome://browser/skin/privateBrowsing.svg); + } + + #context-bookmarklink { + --menuitem-image: url(chrome://browser/skin/bookmark.svg); + } + #context-savelink { + --menuitem-image: url(chrome://browser/skin/save.svg); + } + #context-savelinktopocket { + --menuitem-image: url(chrome://browser/skin/pocket-outline.svg); + } + #context-copyemail { + --menuitem-image: url(chrome://browser/skin/mail.svg); + } + #context-copylink { + --menuitem-image: url(chrome://browser/skin/link.svg); + } + #context-sendlinktodevice { + --menuitem-image: url(chrome://browser/skin/send-to-device.svg); + } + + #context-media-play { + --menuitem-image: url(chrome://global/skin/media/play-fill.svg); + } + #context-media-pause { + --menuitem-image: url(chrome://global/skin/media/pause-fill.svg); + } + #context-media-mute { + --menuitem-image: url(chrome://global/skin/media/audio-muted.svg); + } + #context-media-unmute { + --menuitem-image: url(chrome://global/skin/media/audio.svg); + } + #context-media-playbackrate { + --menuitem-image: url(./icons/time-picker.svg); + } + #context-media-loop { /* checkbox */ + /* --menuitem-image: url(./icons/arrow-repeat-all.svg); */ + } + #context-leave-dom-fullscreen { + --menuitem-image: url(chrome://global/skin/media/fullscreenExitButton.svg); + } + #context-video-fullscreen { + --menuitem-image: url(chrome://global/skin/media/fullscreenEnterButton.svg); + } + #context-media-hidecontrols { + --menuitem-image: url(./icons/eye-hide.svg); + } + #context-media-showcontrols { + --menuitem-image: url(./icons/eye-show.svg); + } + + #context-viewvideo { + --menuitem-image: url(./icons/video.svg); + } + #context-video-pictureinpicture { /* checkbox */ + /* --menuitem-image: url(chrome://global/skin/media/picture-in-picture-open.svg); */ + } + + #context-reloadimage { + --menuitem-image: url(./icons/image-arrow-counterclockwise.svg); + } + #context-viewimage { + --menuitem-image: url(./icons/image-add.svg); + } + #context-saveimage { + --menuitem-image: url(./icons/image.svg); + } + #context-video-saveimage { + --menuitem-image: url(./icons/video-snapshot.svg); + } + #context-savevideo { + --menuitem-image: url(./icons/video.svg); + } + #context-saveaudio { + --menuitem-image: url(chrome://global/skin/media/audio.svg); + } + #context-copyimage-contents { + --menuitem-image: url(./icons/image-copy.svg); + } + #context-copyimage, + #context-copyvideourl, + #context-copyaudiourl { + --menuitem-image: url(chrome://browser/skin/link.svg); + } + #context-sendimage, + #context-sendvideo, + #context-sendaudio { + --menuitem-image: url(chrome://browser/skin/mail.svg); + } + #context-viewimageinfo { + --menuitem-image: url(chrome://global/skin/icons/info.svg); + } + #context-viewimagedesc { + --menuitem-image: url(./icons/image-alt-text.svg); + } + #context-setDesktopBackground { + --menuitem-image: url(./icons/resize-image.svg); + } + #context-ctp-play { + --menuitem-image: url(chrome://global/skin/icons/plugin.svg); + } + #context-ctp-hide { + --menuitem-image: url(chrome://global/skin/icons/plugin-blocked.svg); + } + + #context-savepage { + --menuitem-image: url(chrome://browser/skin/save.svg); + } + #context-pocket { + --menuitem-image: url(chrome://browser/skin/pocket-outline.svg); + } + #context-sendpagetodevice { + --menuitem-image: url(chrome://browser/skin/send-to-device.svg); + } + #fill-login { + --menuitem-image: url(./icons/password.svg); + } + #fill-login-generated-password { + --menuitem-image: url(chrome://browser/skin/login.svg); + } + #manage-saved-logins { + --menuitem-image: url(./icons/key-multiple.svg); + } + + #context-undo { + --menuitem-image: url(chrome://global/skin/icons/undo.svg); + } + #context-redo { + } + + #context-cut { + --menuitem-image: url(chrome://browser/skin/edit-cut.svg); + } + #context-copy { + --menuitem-image: url(chrome://browser/skin/edit-copy.svg); + } + #context-paste { + --menuitem-image: url(chrome://browser/skin/edit-paste.svg); + } + #context-delete { + --menuitem-image: url(chrome://global/skin/icons/delete.svg); + } + #context-selectall { + --menuitem-image: url(./icons/select-all-on.svg); + } + #context-print-selection { + --menuitem-image: url(chrome://global/skin/icons/print.svg); + } + + #context-take-screenshot { + --menuitem-image: url(chrome://browser/skin/screenshot.svg); + } + + #context-keywordfield { + --menuitem-image: url(chrome://browser/skin/bookmark.svg); + } + #context-searchselect, + #context-searchselect-private { + --menuitem-image: url(chrome://global/skin/icons/search-glass.svg); + } + + #frame { + --menuitem-image: url(./icons/command-frames.svg); + } + + #spell-check-enabled { /* checkbox */ + } + #spell-add-dictionaries-main { + --menuitem-image: url(./icons/book-add.svg); + } + #spell-dictionaries { + --menuitem-image: url(./icons/book.svg); + } + + #context-bidi-text-direction-toggle { + --menuitem-image: url(./icons/text-direction-horizontal-ltr.svg); + } + #context-bidi-page-direction-toggle { + --menuitem-image: url(./icons/document-landscape-split-hint.svg); + } + + #context-viewpartialsource-selection, + #context-viewsource { + --menuitem-image: url(./icons/search-file.svg); + } + #context-inspect-a11y { + --menuitem-image: url(chrome://devtools/skin/images/tool-accessibility.svg); + } + #context-inspect { + --menuitem-image: url(chrome://devtools/skin/images/command-pick.svg) + } + + #context-media-eme-learnmore { /* iconic */ + } + + @supports -moz-bool-pref("layout.css.osx-font-smoothing.enabled") { + #context-back { + --menuitem-image: url(chrome://browser/skin/back.svg); + } + #context-forward { + --menuitem-image: url(chrome://browser/skin/forward.svg); + } + #context-reload { + --menuitem-image: url(chrome://browser/skin/reload.svg); + } + #context-stop { + --menuitem-image: url(chrome://global/skin/icons/close.svg); + } + + #context-bookmarkpage { + --menuitem-image: url(chrome://browser/skin/bookmark.svg); + } + } + + /*= pictureInPictureToggleContextMenu ======================================*/ + #pictureInPictureToggleContextMenu > menuitem[oncommand="PictureInPicture.hideToggle();"] { + --menuitem-image: url(./icons/eye-hide.svg); + } + + /*= placeContext ===========================================================*/ + #placesContext_open { + --menuitem-image: url(./icons/link-square.svg); + } + #placesContext_openBookmarkContainer\:tabs, + #placesContext_openBookmarkLinks\:tabs { + --menuitem-image: url(./icons/movetowindow-16.svg); + } + #placesContext_open\:newtab, + #placesContext_openContainer\:tabs, + #placesContext_openLinks\:tabs { + --menuitem-image: url(chrome://browser/skin/new-tab.svg); + } + #placesContext_open\:newwindow { + --menuitem-image: url(chrome://browser/skin/window.svg); + } + #placesContext_open\:newprivatewindow { + --menuitem-image: url(chrome://browser/skin/privateBrowsing.svg); + } + + #placesContext_show_bookmark\:info, + #placesContext_show\:info, + #placesContext_show_folder\:info { + --menuitem-image: url(chrome://global/skin/icons/edit.svg); + } + #placesContext_deleteBookmark, + #placesContext_deleteFolder, + #placesContext_delete, + #placesContext_delete_history { + --menuitem-image: url(chrome://global/skin/icons/delete.svg); + } + #placesContext_deleteHost { + --menuitem-image: url(./icons/eye-hide.svg); + } + #placesContext_sortBy\:name { + --menuitem-image: url(./icons/text-sort-ascending.svg); + } + + #placesContext_cut { + --menuitem-image: url(chrome://browser/skin/edit-cut.svg); + } + #placesContext_copy { + --menuitem-image: url(chrome://browser/skin/edit-copy.svg); + } + #placesContext_paste_group { + --menuitem-image: url(chrome://browser/skin/edit-paste.svg); + } + + #placesContext_new\:bookmark { + --menuitem-image: url(chrome://browser/skin/bookmark.svg); + } + #placesContext_new\:folder { + --menuitem-image: url(chrome://global/skin/icons/folder.svg); + } + #placesContext_new\:separator { + --menuitem-image: url(./icons/vertical-line.svg); + } + + #placesContext_paste { + --menuitem-image: url(chrome://browser/skin/edit-paste.svg); + } + + #placesContext_createBookmark { + --menuitem-image: url(chrome://browser/skin/bookmark.svg); + } + #show-other-bookmarks_PersonalToolbar { /* checkbox */ + /* --menuitem-image: url(./icons/star-line-horizontal.svg); */ + } + #placesContext_showAllBookmarks { + --menuitem-image: url(chrome://browser/skin/bookmark-star-on-tray.svg); + } + + /*= pageActionContextMenu ==================================================*/ + .pageActionContextMenuItem.extensionPinned.extensionUnpinned.manageExtensionItem { + --menuitem-image: url(chrome://global/skin/icons/settings.svg); + } + .pageActionContextMenuItem.extensionPinned.extensionUnpinned.removeExtensionItem { + --menuitem-image: url(chrome://global/skin/icons/delete.svg); + } + + /*= customizationPanelItemContextMenu ======================================*/ + #customizationPanelItemContextMenuUnpin { + --menuitem-image: url(./icons/unpin-tab.svg); + } + .customize-context-removeFromPanel { + --menuitem-image: url(chrome://global/skin/icons/delete.svg); + } + + /*= customizationPaletteItemContextMenu ====================================*/ + .customize-context-addToToolbar { + --menuitem-image: url(chrome://devtools/skin/images/dock-bottom.svg); + } + .customize-context-addToPanel { + --menuitem-image: url(chrome://browser/skin/menu.svg); + } + + /*= customizationPanelContextMenu ==========================================*/ + #customizationPanelContextMenu > menuitem[command="cmd_CustomizeToolbars"] { + --menuitem-image: url(chrome://browser/skin/customize.svg); + } + + /*= downloads-button-autohide-panel ========================================*/ + #downloads-button-autohide-checkbox { /* checkbox */ + } + + /*= downloadsContextMenu ===================================================*/ + .downloadPauseMenuItem { + --menuitem-image: url(chrome://global/skin/media/pause-fill.svg); + } + .downloadResumeMenuItem { + --menuitem-image: url(chrome://global/skin/media/play-fill.svg); + } + .downloadUnblockMenuItem { + --menuitem-image: url(./icons/checkmark-circle.svg); + } + .downloadUseSystemDefaultMenuItem { + --menuitem-image: url(chrome://browser/skin/open.svg); + } + .downloadAlwaysUseSystemDefaultMenuItem { /* checkbox */ + } + .downloadShowMenuItem { + --menuitem-image: url(chrome://global/skin/icons/folder.svg); + } + + #downloadsContextMenu > menuitem[command="downloadsCmd_openReferrer"] { + --menuitem-image: url(./icons/link-square.svg); + } + #downloadsContextMenu > menuitem[command="downloadsCmd_copyLocation"] { + --menuitem-image: url(chrome://browser/skin/link.svg); + } + + .downloadRemoveFromHistoryMenuItem { + --menuitem-image: url(chrome://global/skin/icons/delete.svg); + } + #downloadsContextMenu > menuitem[command="downloadsCmd_clearList"], + #downloadsContextMenu > menuitem[command="downloadsCmd_clearDownloads"] { + --menuitem-image: url(./icons/broom.svg); + } + + /*= SyncedTabsSidebarContext ===============================================*/ + #syncedTabsOpenSelected { + --menuitem-image: url(./icons/link-square.svg); + } + #syncedTabsOpenSelectedInTab { + --menuitem-image: url(chrome://browser/skin/new-tab.svg); + } + #syncedTabsOpenSelectedInWindow { + --menuitem-image: url(chrome://browser/skin/window.svg); + } + #syncedTabsOpenSelectedInPrivateWindow { + --menuitem-image: url(chrome://browser/skin/privateBrowsing.svg); + } + + #syncedTabsBookmarkSelected { + --menuitem-image: url(chrome://browser/skin/bookmark.svg); + } + #syncedTabsCopySelected { + --menuitem-image: url(chrome://browser/skin/link.svg); + } + + #syncedTabsOpenAllInTabs { + --menuitem-image: url(./icons/movetowindow-16.svg); + } + #syncedTabsManageDevices { + --menuitem-image: url(chrome://global/skin/icons/settings.svg); + } + #syncedTabsRefresh { + --menuitem-image: url(chrome://browser/skin/sync.svg); + } + + /*= SyncedTabsSidebarTabsFilterContext =====================================*/ + #SyncedTabsSidebarTabsFilterContext > menuitem[cmd="cmd_undo"] { + --menuitem-image: url(chrome://global/skin/icons/undo.svg); + } + #SyncedTabsSidebarTabsFilterContext > menuitem[cmd="cmd_cut"] { + --menuitem-image: url(chrome://browser/skin/edit-cut.svg); + } + #SyncedTabsSidebarTabsFilterContext > menuitem[cmd="cmd_copy"]{ + --menuitem-image: url(chrome://browser/skin/edit-copy.svg); + } + #SyncedTabsSidebarTabsFilterContext > menuitem[cmd="cmd_paste"]{ + --menuitem-image: url(chrome://browser/skin/edit-paste.svg); + } + #SyncedTabsSidebarTabsFilterContext > menuitem[cmd="cmd_delete"]{ + --menuitem-image: url(chrome://global/skin/icons/delete.svg); + } + + #SyncedTabsSidebarTabsFilterContext > menuitem[cmd="cmd_selectAll"]{ + --menuitem-image: url(./icons/select-all-on.svg); + } + + #syncedTabsRefreshFilter { + --menuitem-image: url(chrome://browser/skin/sync.svg); + } }