mirror of
https://github.com/black7375/Firefox-UI-Fix.git
synced 2026-01-10 11:12:30 -08:00
Clean: Tab Hover Effect - Refactoring modulize, Performance(Reduce offset, Single Element)
This commit is contained in:
parent
faab566ec4
commit
d8363ff984
1 changed files with 358 additions and 301 deletions
|
|
@ -1,301 +1,358 @@
|
|||
// == UserScript ==
|
||||
// @include chrome : //browser/content/places/places.xhtml
|
||||
// == / UserScript ==
|
||||
|
||||
// -- WARNNING!!!!! ------------------------------------------------------------
|
||||
// It's very experimental
|
||||
// Side effects such as performance may occur, and even if a problem occurs, we do not support it.
|
||||
|
||||
// -- Reveal Effect Library ----------------------------------------------------
|
||||
/*
|
||||
Reveal Effect
|
||||
https://github.com/d2phap/fluent-reveal-effect
|
||||
MIT License
|
||||
Copyright (c) 2018 Duong Dieu Phap
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
function getOffset(element) {
|
||||
return {
|
||||
top: element.el.getBoundingClientRect().top,
|
||||
left: element.el.getBoundingClientRect().left
|
||||
};
|
||||
}
|
||||
|
||||
function drawEffect(
|
||||
element,
|
||||
x,
|
||||
y,
|
||||
lightColor,
|
||||
gradientSize,
|
||||
cssLightEffect = null
|
||||
) {
|
||||
let lightBg;
|
||||
|
||||
if (cssLightEffect === null) {
|
||||
lightBg = `radial-gradient(circle ${gradientSize}px at ${x}px ${y}px, ${lightColor}, rgba(255,255,255,0))`;
|
||||
} else {
|
||||
lightBg = cssLightEffect;
|
||||
}
|
||||
|
||||
element.el.style.backgroundImage = lightBg;
|
||||
}
|
||||
|
||||
function preProcessElements(elements) {
|
||||
const res = [];
|
||||
|
||||
elements.forEach(el => {
|
||||
res.push({
|
||||
oriBg: getComputedStyle(el)["background-image"],
|
||||
el: el
|
||||
});
|
||||
});
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
function isIntersected(element, cursor_x, cursor_y, gradientSize) {
|
||||
const cursor_area = {
|
||||
left: cursor_x - gradientSize,
|
||||
right: cursor_x + gradientSize,
|
||||
top: cursor_y - gradientSize,
|
||||
bottom: cursor_y + gradientSize
|
||||
}
|
||||
|
||||
const el_area = {
|
||||
left: element.el.getBoundingClientRect().left,
|
||||
right: element.el.getBoundingClientRect().right,
|
||||
top: element.el.getBoundingClientRect().top,
|
||||
bottom: element.el.getBoundingClientRect().bottom
|
||||
}
|
||||
|
||||
function intersectRect(r1, r2) {
|
||||
return !(
|
||||
r2.left > r1.right ||
|
||||
r2.right < r1.left ||
|
||||
r2.top > r1.bottom ||
|
||||
r2.bottom < r1.top
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
const result = intersectRect(cursor_area, el_area)
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
|
||||
|
||||
function applyEffect(selector, options = {}) {
|
||||
|
||||
let is_pressed = false
|
||||
|
||||
let _options = {
|
||||
lightColor: "rgba(255,255,255,0.25)",
|
||||
gradientSize: 150,
|
||||
clickEffect: false,
|
||||
isContainer: false,
|
||||
children: {
|
||||
borderSelector: ".eff-reveal-border",
|
||||
elementSelector: ".eff-reveal",
|
||||
lightColor: "rgba(255,255,255,0.25)",
|
||||
gradientSize: 150
|
||||
}
|
||||
}
|
||||
|
||||
// update options
|
||||
_options = Object.assign(_options, options)
|
||||
const els = preProcessElements(document.querySelectorAll(selector))
|
||||
|
||||
|
||||
|
||||
|
||||
function clearEffect(element) {
|
||||
is_pressed = false
|
||||
element.el.style.backgroundImage = element.oriBg
|
||||
}
|
||||
|
||||
|
||||
function enableBackgroundEffects(element, lightColor, gradientSize) {
|
||||
|
||||
//element background effect --------------------
|
||||
element.el.addEventListener("mousemove", (e) => {
|
||||
let x = e.pageX - getOffset(element).left - window.scrollX
|
||||
let y = e.pageY - getOffset(element).top - window.scrollY
|
||||
|
||||
if (_options.clickEffect && is_pressed) {
|
||||
|
||||
let cssLightEffect = `radial-gradient(circle ${gradientSize}px at ${x}px ${y}px, ${lightColor}, rgba(255,255,255,0)), radial-gradient(circle ${70}px at ${x}px ${y}px, rgba(255,255,255,0), ${lightColor}, rgba(255,255,255,0), rgba(255,255,255,0))`
|
||||
|
||||
drawEffect(element, x, y, lightColor, gradientSize, cssLightEffect)
|
||||
}
|
||||
else {
|
||||
drawEffect(element, x, y, lightColor, gradientSize)
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
element.el.addEventListener("mouseleave", (e) => {
|
||||
clearEffect(element)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
function enableClickEffects(element, lightColor, gradientSize) {
|
||||
element.el.addEventListener("mousedown", (e) => {
|
||||
is_pressed = true
|
||||
const x = e.pageX - getOffset(element).left - window.scrollX
|
||||
const y = e.pageY - getOffset(element).top - window.scrollY
|
||||
|
||||
const cssLightEffect = `radial-gradient(circle ${gradientSize}px at ${x}px ${y}px, ${lightColor}, rgba(255,255,255,0)), radial-gradient(circle ${70}px at ${x}px ${y}px, rgba(255,255,255,0), ${lightColor}, rgba(255,255,255,0), rgba(255,255,255,0))`
|
||||
|
||||
drawEffect(element, x, y, lightColor, gradientSize, cssLightEffect)
|
||||
})
|
||||
|
||||
element.el.addEventListener("mouseup", (e) => {
|
||||
is_pressed = false
|
||||
const x = e.pageX - getOffset(element).left - window.scrollX
|
||||
const y = e.pageY - getOffset(element).top - window.scrollY
|
||||
|
||||
drawEffect(element, x, y, lightColor, gradientSize)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//Children *********************************************
|
||||
if (!_options.isContainer) {
|
||||
|
||||
//element background effect
|
||||
els.forEach(element => {
|
||||
enableBackgroundEffects(element, _options.lightColor, _options.gradientSize)
|
||||
|
||||
//element click effect
|
||||
if (_options.clickEffect) {
|
||||
enableClickEffects(element, _options.lightColor, _options.gradientSize)
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
//Container *********************************************
|
||||
else {
|
||||
|
||||
els.forEach(element => {
|
||||
|
||||
// get border items list
|
||||
const childrenBorder = _options.isContainer ? preProcessElements(document.querySelectorAll(_options.children.borderSelector)) : []
|
||||
|
||||
|
||||
//Container *********************************************
|
||||
//add border effect
|
||||
element.el.addEventListener("mousemove", (e) => {
|
||||
for (let i = 0; i < childrenBorder.length; i++) {
|
||||
const x = e.pageX - getOffset(childrenBorder[i]).left - window.scrollX
|
||||
const y = e.pageY - getOffset(childrenBorder[i]).top - window.scrollY
|
||||
|
||||
if (isIntersected(childrenBorder[i], e.clientX, e.clientY, _options.gradientSize)) {
|
||||
drawEffect(childrenBorder[i], x, y, _options.lightColor, _options.gradientSize)
|
||||
}
|
||||
else {
|
||||
clearEffect(childrenBorder[i])
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
//clear border light effect
|
||||
element.el.addEventListener("mouseleave", (e) => {
|
||||
for (let i = 0; i < childrenBorder.length; i++) {
|
||||
clearEffect(childrenBorder[i])
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
//Children *********************************************
|
||||
const children = preProcessElements(element.el.querySelectorAll(_options.children.elementSelector))
|
||||
// console.log(children)
|
||||
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
|
||||
//element background effect
|
||||
enableBackgroundEffects(children[i], _options.children.lightColor, _options.children.gradientSize)
|
||||
|
||||
//element click effect
|
||||
if (_options.clickEffect) {
|
||||
enableClickEffects(children[i], _options.children.lightColor, _options.children.gradientSize)
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// -- Apply Effect -------------------------------------------------------------
|
||||
// https://github.com/mozilla/gecko-dev/blob/1465ef37f27584b00b70587d18a3c2f96c9dae78/browser/themes/shared/tabs.inc.css#L841
|
||||
applyEffect(".tabbrowser-tab", {
|
||||
clickEffect: true,
|
||||
lightColor: "color-mix(in srgb, currentColor 11%, transparent)",
|
||||
gradientSize: 150
|
||||
});
|
||||
|
||||
// Redefine Handler
|
||||
// https://github.com/mozilla/gecko-dev/blob/6b099d836c882bc155d2ef285e0ad0ab9f5038f6/browser/base/content/tabbrowser-tabs.js#L1945
|
||||
document.querySelector("#tabbrowser-tabs")._handleNewTab = (tab) => {
|
||||
applyEffect(".tabbrowser-tab", {
|
||||
clickEffect: true,
|
||||
lightColor: "color-mix(in srgb, currentColor 11%, transparent)",
|
||||
gradientSize: 150
|
||||
});
|
||||
|
||||
if (tab.container != this) {
|
||||
return;
|
||||
}
|
||||
console.log("newtab");
|
||||
tab._fullyOpen = true;
|
||||
gBrowser.tabAnimationsInProgress--;
|
||||
|
||||
this._updateCloseButtons();
|
||||
|
||||
if (tab.getAttribute("selected") == "true") {
|
||||
this._handleTabSelect();
|
||||
} else if (!tab.hasAttribute("skipbackgroundnotify")) {
|
||||
this._notifyBackgroundTab(tab);
|
||||
}
|
||||
|
||||
// XXXmano: this is a temporary workaround for bug 345399
|
||||
// We need to manually update the scroll buttons disabled state
|
||||
// if a tab was inserted to the overflow area or removed from it
|
||||
// without any scrolling and when the tabbar has already
|
||||
// overflowed.
|
||||
this.arrowScrollbox._updateScrollButtonsDisabledState();
|
||||
|
||||
// If this browser isn't lazy (indicating it's probably created by
|
||||
// session restore), preload the next about:newtab if we don't
|
||||
// already have a preloaded browser.
|
||||
if (tab.linkedPanel) {
|
||||
NewTabPagePreloading.maybeCreatePreloadedBrowser(window);
|
||||
}
|
||||
|
||||
if (UserInteraction.running("browser.tabs.opening", window)) {
|
||||
UserInteraction.finish("browser.tabs.opening", window);
|
||||
};
|
||||
}
|
||||
// == UserScript ==
|
||||
// @include chrome : //browser/content/places/places.xhtml
|
||||
// == / UserScript ==
|
||||
|
||||
// -- WARNNING!!!!! ------------------------------------------------------------
|
||||
// It's very experimental
|
||||
// Side effects such as performance may occur, and even if a problem occurs, we do not support it.
|
||||
|
||||
// Todo:
|
||||
// - Slim: Remove leaving only the required code
|
||||
// - Load Optimize: Lazy initialization, asynchronous application
|
||||
// - Avoid redefinition: _handleNewTab
|
||||
|
||||
// Done:
|
||||
// - Refactoring: Modulize, Reduce offset
|
||||
// - Single Element: Add a function that applies only to one element
|
||||
|
||||
// -- Reveal Effect Library ----------------------------------------------------
|
||||
/*
|
||||
Reveal Effect
|
||||
https://github.com/d2phap/fluent-reveal-effect
|
||||
MIT License
|
||||
Copyright (c) 2018 Duong Dieu Phap
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
// TS Version
|
||||
// https://gist.github.com/black7375/381950352a76f0336f2abe9eb6b1fff1
|
||||
|
||||
// ** Postion ******************************************************************
|
||||
function getOffset(element) {
|
||||
const bounding = element.getBoundingClientRect();
|
||||
|
||||
return ({
|
||||
top: bounding.top,
|
||||
left: bounding.left
|
||||
});
|
||||
}
|
||||
|
||||
// with Mouse
|
||||
function getXY(element, e) {
|
||||
const offset = getOffset(element);
|
||||
const x = e.pageX - offset.left - window.scrollX;
|
||||
const y = e.pageY - offset.top - window.scrollY;
|
||||
|
||||
return [x, y];
|
||||
}
|
||||
|
||||
// for Container
|
||||
function intersectRect(r1, r2) {
|
||||
return !(
|
||||
r2.left > r1.right ||
|
||||
r2.right < r1.left ||
|
||||
r2.top > r1.bottom ||
|
||||
r2.bottom < r1.top
|
||||
);
|
||||
}
|
||||
function isIntersected(element, cursor_x, cursor_y, gradientSize) {
|
||||
const cursor_area = {
|
||||
left: cursor_x - gradientSize,
|
||||
right: cursor_x + gradientSize,
|
||||
top: cursor_y - gradientSize,
|
||||
bottom: cursor_y + gradientSize
|
||||
};
|
||||
|
||||
const bounding = element.getBoundingClientRect();
|
||||
const el_area = {
|
||||
left: bounding.left,
|
||||
right: bounding.right,
|
||||
top: bounding.top,
|
||||
bottom: bounding.bottom
|
||||
};
|
||||
|
||||
const result = intersectRect(cursor_area, el_area);
|
||||
return result;
|
||||
}
|
||||
|
||||
// ** CSS Effect ***************************************************************
|
||||
function lightHoverEffect(gradientSize, x, y, lightColor) {
|
||||
return `radial-gradient(circle ${gradientSize}px at ${x}px ${y}px, ${lightColor}, rgba(255,255,255,0))`;
|
||||
}
|
||||
|
||||
function lightClickEffect(gradientSize, x, y, lightColor) {
|
||||
return `${lightHoverEffect(gradientSize, x, y, lightColor)}, radial-gradient(circle ${70}px at ${x}px ${y}px, rgba(255,255,255,0), ${lightColor}, rgba(255,255,255,0), rgba(255,255,255,0))`;
|
||||
}
|
||||
|
||||
// ** Basic Draw Effect ********************************************************
|
||||
function drawEffect(element, x, y, lightColor, gradientSize, cssLightEffect = null) {
|
||||
const lightBg = cssLightEffect === null
|
||||
? lightHoverEffect(gradientSize, x, y, lightColor)
|
||||
: cssLightEffect;
|
||||
element.style.backgroundImage = lightBg;
|
||||
}
|
||||
|
||||
// with Mouse
|
||||
function drawHoverEffect(element, lightColor, gradientSize, e) {
|
||||
const [x, y] = getXY(element, e);
|
||||
drawEffect(element, x, y, lightColor, gradientSize);
|
||||
}
|
||||
|
||||
function drawClickEffect(element, lightColor, gradientSize, e) {
|
||||
const [x, y] = getXY(element, e);
|
||||
|
||||
const cssLightEffect = lightClickEffect(gradientSize, x, y, lightColor);
|
||||
drawEffect(element, x, y, lightColor, gradientSize, cssLightEffect);
|
||||
}
|
||||
|
||||
// ** SideEffect Draw Effect ***************************************************
|
||||
function clearEffect(resource, is_pressed) {
|
||||
is_pressed[0] = false;
|
||||
resource.el.style.backgroundImage = resource.oriBg;
|
||||
}
|
||||
|
||||
function drawContainerHoverEffect(resource, lightColor, gradientSize, is_pressed, e) {
|
||||
const element = resource.el;
|
||||
|
||||
if (isIntersected(element, e.clientX, e.clientY, gradientSize)) {
|
||||
drawHoverEffect(element, lightColor, gradientSize, e);
|
||||
}
|
||||
else {
|
||||
clearEffect(resource, is_pressed);
|
||||
}
|
||||
}
|
||||
|
||||
// Wrapper
|
||||
function enableBackgroundEffects(resource, lightColor, gradientSize, clickEffect, is_pressed) {
|
||||
const element = resource.el;
|
||||
element.addEventListener("mousemove", (e) => {
|
||||
if (clickEffect && is_pressed[0]) {
|
||||
drawClickEffect(element, lightColor, gradientSize, e);
|
||||
}
|
||||
else {
|
||||
drawHoverEffect(element, lightColor, gradientSize, e);
|
||||
}
|
||||
});
|
||||
|
||||
element.addEventListener("mouseleave", (e) => {
|
||||
clearEffect(resource, is_pressed);
|
||||
});
|
||||
}
|
||||
|
||||
function enableBorderEffects(resource, childrenBorders, options, is_pressed) {
|
||||
const element = resource.el;
|
||||
const childrenBorderL = childrenBorders.length;
|
||||
|
||||
element.addEventListener("mousemove", (e) => {
|
||||
for (let i = 0; i < childrenBorderL; i++) {
|
||||
drawContainerHoverEffect(childrenBorders[i], options.lightColor, options.gradientSize, is_pressed, e);
|
||||
}
|
||||
});
|
||||
|
||||
element.addEventListener("mouseleave", (e) => {
|
||||
for (let i = 0; i < childrenBorderL; i++) {
|
||||
clearEffect(childrenBorders[i], is_pressed);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function enableClickEffects(resource, lightColor, gradientSize, is_pressed) {
|
||||
const element = resource.el;
|
||||
element.addEventListener("mousedown", (e) => {
|
||||
is_pressed[0] = true;
|
||||
drawClickEffect(element, lightColor, gradientSize, e);
|
||||
});
|
||||
|
||||
element.addEventListener("mouseup", (e) => {
|
||||
is_pressed[0] = false;
|
||||
drawHoverEffect(element, lightColor, gradientSize, e);
|
||||
});
|
||||
}
|
||||
|
||||
// Interface
|
||||
function enableNormalBackgroundEffetcs(resource, options, is_pressed) {
|
||||
enableBackgroundEffects(resource, options.lightColor, options.gradientSize, options.clickEffect, is_pressed);
|
||||
}
|
||||
function enableChildrenBackgroundEffetcs(resource, options, is_pressed) {
|
||||
enableBackgroundEffects(resource, options.children.lightColor, options.children.gradientSize, options.clickEffect, is_pressed);
|
||||
}
|
||||
function enableNormalClickEffects(resource, options, is_pressed) {
|
||||
enableClickEffects(resource, options.lightColor, options.gradientSize, is_pressed);
|
||||
}
|
||||
function enableChildrenClickEffects(resource, options, is_pressed) {
|
||||
enableClickEffects(resource, options.children.lightColor, options.children.gradientSize, is_pressed);
|
||||
}
|
||||
|
||||
// ** Element Processing *******************************************************
|
||||
function preProcessElement(element) {
|
||||
return ({
|
||||
oriBg: getComputedStyle(element).backgroundImage,
|
||||
el: element
|
||||
});
|
||||
}
|
||||
|
||||
function preProcessElements(elements) {
|
||||
const ressources = [];
|
||||
const elementsL = elements.length;
|
||||
for (let i = 0; i < elementsL; i++) {
|
||||
const element = elements[i];
|
||||
ressources.push(preProcessElement(element));
|
||||
}
|
||||
|
||||
return ressources;
|
||||
}
|
||||
|
||||
function preProcessSelector(selector) {
|
||||
return preProcessElements(document.querySelectorAll(selector));
|
||||
}
|
||||
|
||||
// ** ApplyEffect **************************************************************
|
||||
// Option
|
||||
function applyEffectOption(userOptions) {
|
||||
const defaultOptions = {
|
||||
lightColor: "rgba(255,255,255,0.25)",
|
||||
gradientSize: 150,
|
||||
clickEffect: false,
|
||||
isContainer: false,
|
||||
children: {
|
||||
borderSelector: ".eff-reveal-border",
|
||||
elementSelector: ".eff-reveal",
|
||||
lightColor: "rgba(255,255,255,0.25)",
|
||||
gradientSize: 150
|
||||
}
|
||||
};
|
||||
|
||||
return Object.assign(defaultOptions, userOptions);
|
||||
}
|
||||
|
||||
// Children Effect
|
||||
function applySingleChildrenEffect(resource, options, is_pressed, enableBackgroundEffectsFunc, enableClickEffectsFunc) {
|
||||
enableBackgroundEffectsFunc(resource, options, is_pressed);
|
||||
if (options.clickEffect) {
|
||||
enableClickEffectsFunc(resource, options, is_pressed);
|
||||
}
|
||||
}
|
||||
function applyChildrenEffect(resources, options, is_pressed, enableBackgroundEffectsFunc, enableClickEffectsFunc) {
|
||||
const resourceL = resources.length;
|
||||
for (let i = 0; i < resourceL; i++) {
|
||||
const resource = resources[i];
|
||||
applySingleChildrenEffect(resource, options, is_pressed, enableBackgroundEffectsFunc, enableClickEffectsFunc);
|
||||
}
|
||||
}
|
||||
|
||||
// Container Effect
|
||||
function applySingleContainerEffect(resource, options, is_pressed, enableBackgroundEffectsFunc, enableClickEffectsFunc) {
|
||||
// Container
|
||||
const childrenBorders = preProcessSelector(options.children.borderSelector);
|
||||
enableBorderEffects(resource, childrenBorders, options, is_pressed);
|
||||
|
||||
// Children
|
||||
const childrens = preProcessSelector(options.children.elementSelector);
|
||||
applyChildrenEffect(childrens, options, is_pressed, enableBackgroundEffectsFunc, enableClickEffectsFunc);
|
||||
}
|
||||
function applyContainerEffect(resources, options, is_pressed, enableBackgroundEffectsFunc, enableClickEffectsFunc) {
|
||||
const resourceL = resources.length;
|
||||
|
||||
for (let i = 0; i < resourceL; i++) {
|
||||
const resource = resources[i];
|
||||
applySingleContainerEffect(resource, options, is_pressed, enableBackgroundEffectsFunc, enableClickEffectsFunc);
|
||||
}
|
||||
}
|
||||
|
||||
// Apply Effect
|
||||
function applySingleEffect(element, userOptions = {}) {
|
||||
const is_pressed = [false];
|
||||
const options = applyEffectOption(userOptions);
|
||||
const resource = preProcessElement(element);
|
||||
|
||||
if (!options.isContainer) {
|
||||
const enableBackgroundEffectsFunc = enableNormalBackgroundEffetcs;
|
||||
const enableClickEffectsFunc = enableNormalClickEffects;
|
||||
applySingleChildrenEffect(resource, options, is_pressed, enableBackgroundEffectsFunc, enableClickEffectsFunc);
|
||||
}
|
||||
else {
|
||||
const enableBackgroundEffectsFunc = enableChildrenBackgroundEffetcs;
|
||||
const enableClickEffectsFunc = enableChildrenClickEffects;
|
||||
applySingleContainerEffect(resource, options, is_pressed, enableBackgroundEffectsFunc, enableClickEffectsFunc);
|
||||
}
|
||||
}
|
||||
function applyEffect(selector, userOptions = {}) {
|
||||
const is_pressed = [false];
|
||||
const options = applyEffectOption(userOptions);
|
||||
const resoures = preProcessSelector(selector);
|
||||
|
||||
if (!options.isContainer) {
|
||||
const enableBackgroundEffectsFunc = enableNormalBackgroundEffetcs;
|
||||
const enableClickEffectsFunc = enableNormalClickEffects;
|
||||
applyChildrenEffect(resoures, options, is_pressed, enableBackgroundEffectsFunc, enableClickEffectsFunc);
|
||||
}
|
||||
else {
|
||||
const enableBackgroundEffectsFunc = enableChildrenBackgroundEffetcs;
|
||||
const enableClickEffectsFunc = enableChildrenClickEffects;
|
||||
applyContainerEffect(resoures, options, is_pressed, enableBackgroundEffectsFunc, enableClickEffectsFunc);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// -- Hover Effect -------------------------------------------------------------
|
||||
const hoverEffectOption = {
|
||||
clickEffect: true,
|
||||
lightColor: "color-mix(in srgb, currentColor 11%, transparent)",
|
||||
gradientSize: 150
|
||||
}
|
||||
|
||||
// https://github.com/mozilla/gecko-dev/blob/1465ef37f27584b00b70587d18a3c2f96c9dae78/browser/themes/shared/tabs.inc.css#L841
|
||||
applyEffect(".tabbrowser-tab", hoverEffectOption);
|
||||
|
||||
// Redefine Handler
|
||||
// https://github.com/mozilla/gecko-dev/blob/6b099d836c882bc155d2ef285e0ad0ab9f5038f6/browser/base/content/tabbrowser-tabs.js#L1945
|
||||
document.querySelector("#tabbrowser-tabs")._handleNewTab = (tab) => {
|
||||
applySingleEffect(tab, hoverEffectOption);
|
||||
|
||||
if (tab.container != this) {
|
||||
return;
|
||||
}
|
||||
console.log("newtab");
|
||||
tab._fullyOpen = true;
|
||||
gBrowser.tabAnimationsInProgress--;
|
||||
|
||||
this._updateCloseButtons();
|
||||
|
||||
if (tab.getAttribute("selected") == "true") {
|
||||
this._handleTabSelect();
|
||||
} else if (!tab.hasAttribute("skipbackgroundnotify")) {
|
||||
this._notifyBackgroundTab(tab);
|
||||
}
|
||||
|
||||
// XXXmano: this is a temporary workaround for bug 345399
|
||||
// We need to manually update the scroll buttons disabled state
|
||||
// if a tab was inserted to the overflow area or removed from it
|
||||
// without any scrolling and when the tabbar has already
|
||||
// overflowed.
|
||||
this.arrowScrollbox._updateScrollButtonsDisabledState();
|
||||
|
||||
// If this browser isn't lazy (indicating it's probably created by
|
||||
// session restore), preload the next about:newtab if we don't
|
||||
// already have a preloaded browser.
|
||||
if (tab.linkedPanel) {
|
||||
NewTabPagePreloading.maybeCreatePreloadedBrowser(window);
|
||||
}
|
||||
|
||||
if (UserInteraction.running("browser.tabs.opening", window)) {
|
||||
UserInteraction.finish("browser.tabs.opening", window);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue