mirror of
https://github.com/zen-browser/desktop.git
synced 2025-09-05 19:08:18 +00:00
Merge branch 'dev' of https://github.com/zen-browser/desktop into dev
This commit is contained in:
@@ -59,7 +59,6 @@ if test "$ZEN_RELEASE"; then
|
||||
ac_add_options --disable-rust-tests
|
||||
|
||||
ac_add_options --disable-default-browser-agent
|
||||
# ac_add_options --enable-minify=js,properties
|
||||
|
||||
if ! test "$ZEN_DISABLE_LTO"; then
|
||||
# only enable full LTO when ZEN_RELEASE_BRANCH is 'release'
|
||||
|
13
src/Cargo-lock.patch
Normal file
13
src/Cargo-lock.patch
Normal file
@@ -0,0 +1,13 @@
|
||||
diff --git a/Cargo.lock b/Cargo.lock
|
||||
index da2fbe8c40fa40a86c350f8adb33e26915fecc7b..e5a571fc41cd4fa8d2cdffdc15f9ad083e6d36fb 100644
|
||||
--- a/Cargo.lock
|
||||
+++ b/Cargo.lock
|
||||
@@ -3912,8 +3912,6 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "mime_guess"
|
||||
version = "2.0.4"
|
||||
-source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
-checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef"
|
||||
dependencies = [
|
||||
"mime",
|
||||
"unicase",
|
14
src/Cargo-toml.patch
Normal file
14
src/Cargo-toml.patch
Normal file
@@ -0,0 +1,14 @@
|
||||
diff --git a/Cargo.toml b/Cargo.toml
|
||||
index 19a470608b7de28a946353d4c09a56b4dd3fd69a..37e9687c86b5725ee5d5071b632b5927ffb6bd27 100644
|
||||
--- a/Cargo.toml
|
||||
+++ b/Cargo.toml
|
||||
@@ -201,6 +201,9 @@ rure = { path = "third_party/rust/rure" }
|
||||
# Patch `plist` to work with `indexmap` 2.*
|
||||
plist = { path = "third_party/rust/plist" }
|
||||
|
||||
+# Patch mime_guess to add missing mime types
|
||||
+mime_guess = { path = "third_party/rust/mime_guess" }
|
||||
+
|
||||
# To-be-published changes.
|
||||
unicode-bidi = { git = "https://github.com/servo/unicode-bidi", rev = "ca612daf1c08c53abe07327cb3e6ef6e0a760f0c" }
|
||||
nss-gk-api = { git = "https://github.com/beurdouche/nss-gk-api", rev = "e48a946811ffd64abc78de3ee284957d8d1c0d63" }
|
@@ -121,6 +121,7 @@ pref('zen.urlbar.replace-newtab', true);
|
||||
pref('zen.urlbar.behavior', 'floating-on-type'); // default, floating-on-type, float
|
||||
pref('zen.urlbar.wait-to-clear', 45000); // in ms (default 45s)
|
||||
pref('zen.urlbar.show-domain-only-in-sidebar', true);
|
||||
pref('zen.urlbar.hide-one-offs', true);
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
// Disable for macos in the meantime until @HarryHeres finds a solution for hight DPI screens
|
||||
|
@@ -1,8 +1,8 @@
|
||||
diff --git a/browser/base/content/main-popupset.inc.xhtml b/browser/base/content/main-popupset.inc.xhtml
|
||||
index e5f3424eaeeec0ba552537f167dd99e912216d94..4bdfcdb23fe9c44ad3d4de273c64f4cc31cb4034 100644
|
||||
index 959c523b21c642f29353b9de37b3ce6b5505b01b..0d151ad345dde47467432196ed76f4320b4b92cc 100644
|
||||
--- a/browser/base/content/main-popupset.inc.xhtml
|
||||
+++ b/browser/base/content/main-popupset.inc.xhtml
|
||||
@@ -181,6 +181,10 @@
|
||||
@@ -206,6 +206,10 @@
|
||||
hidden="true"
|
||||
tabspecific="true"
|
||||
aria-labelledby="editBookmarkPanelTitle">
|
||||
@@ -13,7 +13,7 @@ index e5f3424eaeeec0ba552537f167dd99e912216d94..4bdfcdb23fe9c44ad3d4de273c64f4cc
|
||||
<box class="panel-header">
|
||||
<html:h1>
|
||||
<html:span id="editBookmarkPanelTitle"/>
|
||||
@@ -206,6 +210,7 @@
|
||||
@@ -231,6 +235,7 @@
|
||||
class="footer-button"/>
|
||||
</html:moz-button-group>
|
||||
</vbox>
|
||||
@@ -21,7 +21,7 @@ index e5f3424eaeeec0ba552537f167dd99e912216d94..4bdfcdb23fe9c44ad3d4de273c64f4cc
|
||||
</panel>
|
||||
</html:template>
|
||||
|
||||
@@ -535,6 +540,8 @@
|
||||
@@ -565,6 +570,8 @@
|
||||
|
||||
#include popup-notifications.inc.xhtml
|
||||
|
||||
|
@@ -10,7 +10,7 @@
|
||||
</hbox>
|
||||
<hbox>
|
||||
<toolbarbutton id="zen-sidebar-web-panel-home" class="toolbarbutton-1 chromeclass-toolbar-additional" oncommand="gZenBrowserManagerSidebar.home();"/>
|
||||
<toolbarbutton id="zen-sidebar-web-panel-pinned" class="toolbarbutton-1 chromeclass-toolbar-additional" oncommand="gZenBrowserManagerSidebar.togglePinned(this);"/>
|
||||
<toolbarbutton id="zen-sidebar-web-panel-pinned" class="toolbarbutton-1 chromeclass-toolbar-additional" pinned="true" oncommand="gZenBrowserManagerSidebar.togglePinned(this);"/>
|
||||
<toolbarbutton id="zen-sidebar-web-panel-close" class="toolbarbutton-1 chromeclass-toolbar-additional" oncommand="gZenBrowserManagerSidebar.close();"/>
|
||||
</hbox>
|
||||
</toolbar>
|
||||
|
@@ -248,3 +248,34 @@
|
||||
outline-color: var(--toolbarbutton-active-outline-color);
|
||||
}
|
||||
}
|
||||
|
||||
#zen-split-view-fake-browser {
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
border-radius: var(--zen-native-inner-radius);
|
||||
box-shadow: var(--zen-big-shadow);
|
||||
pointer-events: none;
|
||||
overflow: hidden;
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 3.5rem;
|
||||
height: 3.5rem;
|
||||
background: var(--zen-split-view-fake-icon);
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
opacity: 0.8;
|
||||
transition: opacity 0.2s;
|
||||
transition-delay: 0.1s;
|
||||
|
||||
@starting-style {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -435,9 +435,8 @@ button.popup-notification-dropmarker {
|
||||
font-size: 1.5em !important;
|
||||
width: min(90%, 60rem) !important;
|
||||
}
|
||||
top: 50vh !important;
|
||||
top: 25vh !important;
|
||||
transform: translateX(-50%);
|
||||
margin-top: -20%;
|
||||
left: 50% !important;
|
||||
|
||||
#urlbar-container:has(&) {
|
||||
|
@@ -9,6 +9,7 @@
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
font-size: x-small;
|
||||
|
||||
position: relative;
|
||||
|
||||
|
@@ -267,14 +267,15 @@
|
||||
.then(() => {
|
||||
this.#currentParentTab.linkedBrowser.closest('.browserSidebarContainer').removeAttribute('style');
|
||||
});
|
||||
this.browserWrapper.style.opacity = 1;
|
||||
gZenUIManager.motion
|
||||
.animate(
|
||||
this.browserWrapper,
|
||||
{
|
||||
...originalPosition,
|
||||
opacity: 0.3,
|
||||
opacity: 0,
|
||||
},
|
||||
{ type: 'spring', bounce: 0, duration: 0.4, easing: 'ease' }
|
||||
{ type: 'spring', bounce: 0, duration: 0.6, easing: 'ease-in' }
|
||||
)
|
||||
.then(() => {
|
||||
this.browserWrapper.removeAttribute('animate');
|
||||
|
@@ -33,6 +33,7 @@ class ZenBrowserManagerSidebar extends ZenDOMOperatedFeature {
|
||||
this.listenForPrefChanges();
|
||||
this.insertIntoContextMenu();
|
||||
this.addPositioningListeners();
|
||||
this.syncPinnedState();
|
||||
}
|
||||
|
||||
onlySafeWidthAndHeight() {
|
||||
@@ -98,6 +99,17 @@ class ZenBrowserManagerSidebar extends ZenDOMOperatedFeature {
|
||||
window.addEventListener('resize', this.onWindowResize.bind(this));
|
||||
}
|
||||
|
||||
syncPinnedState() {
|
||||
const sidebar = document.getElementById('zen-sidebar-web-panel');
|
||||
const pinButton = document.getElementById('zen-sidebar-web-panel-pinned');
|
||||
|
||||
if (sidebar.hasAttribute('pinned')) {
|
||||
pinButton.setAttribute('pinned', 'true');
|
||||
} else {
|
||||
pinButton.removeAttribute('pinned');
|
||||
}
|
||||
}
|
||||
|
||||
handleSplitterMouseDown(mouseDownEvent) {
|
||||
if (this._isDragging) return;
|
||||
this._isDragging = true;
|
||||
|
@@ -84,6 +84,10 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
|
||||
this.initializeContextMenu();
|
||||
this.insertPageActionButton();
|
||||
this.insertIntoContextMenu();
|
||||
|
||||
// Add drag over listener to the browser view
|
||||
this.tabBrowserPanel.addEventListener('dragenter', this.onBrowserDragOverToSplit.bind(this));
|
||||
this.tabBrowserPanel.addEventListener('dragleave', this.onBrowserDragEndToSplit.bind(this));
|
||||
}
|
||||
|
||||
insertIntoContextMenu() {
|
||||
@@ -142,6 +146,111 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
|
||||
}
|
||||
}
|
||||
|
||||
onBrowserDragOverToSplit(event) {
|
||||
var dt = event.dataTransfer;
|
||||
var draggedTab;
|
||||
if (dt.mozTypesAt(0)[0] == TAB_DROP_TYPE) {
|
||||
// tab copy or move
|
||||
draggedTab = dt.mozGetDataAt(TAB_DROP_TYPE, 0);
|
||||
// not our drop then
|
||||
if (!draggedTab || gBrowser.selectedTab.hasAttribute('zen-empty-tab')) {
|
||||
return;
|
||||
}
|
||||
draggedTab.container._finishMoveTogetherSelectedTabs(draggedTab);
|
||||
}
|
||||
if (!draggedTab || this._canDrop || this._hasAnimated || this.fakeBrowser) {
|
||||
return;
|
||||
}
|
||||
const currentView = this._data[this.currentView];
|
||||
if (currentView?.tabs.length >= this.MAX_TABS) {
|
||||
return;
|
||||
}
|
||||
this._canDrop = true;
|
||||
// wait some time before showing the split view
|
||||
this._showSplitViewTimeout = setTimeout(() => {
|
||||
this._hasAnimated = true;
|
||||
const panelsWidth = gBrowser.tabbox.getBoundingClientRect().width;
|
||||
const halfWidth = panelsWidth / 2;
|
||||
this.fakeBrowser = document.createXULElement('vbox');
|
||||
const padding = Services.prefs.getIntPref('zen.theme.content-element-separation', 0);
|
||||
this.fakeBrowser.setAttribute('flex', '1');
|
||||
this.fakeBrowser.id = 'zen-split-view-fake-browser';
|
||||
gBrowser.tabbox.appendChild(this.fakeBrowser);
|
||||
this.fakeBrowser.style.setProperty('--zen-split-view-fake-icon', `url(${draggedTab.getAttribute('image')})`);
|
||||
Promise.all([
|
||||
gZenUIManager.motion.animate(
|
||||
gBrowser.tabbox,
|
||||
{
|
||||
paddingLeft: [0, `${halfWidth}px`],
|
||||
},
|
||||
{
|
||||
duration: 0.1,
|
||||
easing: 'ease-out',
|
||||
}
|
||||
),
|
||||
gZenUIManager.motion.animate(
|
||||
this.fakeBrowser,
|
||||
{
|
||||
width: [0, `${halfWidth - padding * 2}px`],
|
||||
marginLeft: [0, `${-(halfWidth - padding)}px`],
|
||||
},
|
||||
{
|
||||
duration: 0.1,
|
||||
easing: 'ease-out',
|
||||
}
|
||||
),
|
||||
]).then(() => {});
|
||||
}, 100);
|
||||
}
|
||||
|
||||
onBrowserDragEndToSplit(event) {
|
||||
if (!this._canDrop) {
|
||||
return;
|
||||
}
|
||||
const panelsRect = gBrowser.tabbox.getBoundingClientRect();
|
||||
// this event is fired even though we are still in the "allowed" area
|
||||
if (event.target !== this.tabBrowserPanel) {
|
||||
return;
|
||||
}
|
||||
this._canDrop = false;
|
||||
if (this._showSplitViewTimeout) {
|
||||
clearTimeout(this._showSplitViewTimeout);
|
||||
}
|
||||
if (!this._hasAnimated) {
|
||||
return;
|
||||
}
|
||||
setTimeout(() => {
|
||||
const panelsWidth = panelsRect.width;
|
||||
const halfWidth = panelsWidth / 2;
|
||||
const padding = Services.prefs.getIntPref('zen.theme.content-element-separation', 0);
|
||||
Promise.all([
|
||||
gZenUIManager.motion.animate(
|
||||
gBrowser.tabbox,
|
||||
{
|
||||
paddingLeft: [`${halfWidth}px`, 0],
|
||||
},
|
||||
{
|
||||
duration: 0.1,
|
||||
easing: 'ease-out',
|
||||
}
|
||||
),
|
||||
gZenUIManager.motion.animate(
|
||||
this.fakeBrowser,
|
||||
{
|
||||
width: [`${halfWidth - padding * 2}px`, 0],
|
||||
marginLeft: [`${-(halfWidth - padding)}px`, 0],
|
||||
},
|
||||
{
|
||||
duration: 0.1,
|
||||
easing: 'ease-out',
|
||||
}
|
||||
),
|
||||
]).then(() => {
|
||||
this._mayabeRemoveFakeBrowser();
|
||||
});
|
||||
}, 100);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a SplitNode from its tree and the view
|
||||
* @param {SplitNode} toRemove
|
||||
@@ -699,6 +808,7 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
|
||||
this.updateSplitView(tab);
|
||||
tab.linkedBrowser.docShellIsActive = true;
|
||||
}
|
||||
this._mayabeRemoveFakeBrowser();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1282,6 +1392,16 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
|
||||
}
|
||||
};
|
||||
|
||||
_mayabeRemoveFakeBrowser() {
|
||||
if (this.fakeBrowser) {
|
||||
this.fakeBrowser.remove();
|
||||
this.fakeBrowser = null;
|
||||
gBrowser.tabbox.removeAttribute('style');
|
||||
delete this._canDrop;
|
||||
delete this._hasAnimated;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description moves the tab to the split view if dragged on a browser
|
||||
* @param event - The event
|
||||
@@ -1289,6 +1409,8 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
|
||||
* @returns {boolean} true if the tab was moved to the split view
|
||||
*/
|
||||
moveTabToSplitView(event, draggedTab) {
|
||||
this._mayabeRemoveFakeBrowser();
|
||||
|
||||
const dropTarget = document.elementFromPoint(event.clientX, event.clientY);
|
||||
const browser = dropTarget?.closest('browser');
|
||||
|
||||
@@ -1336,24 +1458,22 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
|
||||
}
|
||||
} else {
|
||||
// Create new split view with layout based on drop position
|
||||
let gridType;
|
||||
switch (hoverSide) {
|
||||
case 'left':
|
||||
case 'right':
|
||||
gridType = 'vsep';
|
||||
break;
|
||||
case 'top':
|
||||
case 'bottom':
|
||||
gridType = 'hsep';
|
||||
break;
|
||||
default:
|
||||
gridType = 'grid';
|
||||
}
|
||||
let gridType = 'vsep';
|
||||
//switch (hoverSide) {
|
||||
// case 'left':
|
||||
// case 'right':
|
||||
// gridType = 'vsep';
|
||||
// break;
|
||||
// case 'top':
|
||||
// case 'bottom':
|
||||
// gridType = 'hsep';
|
||||
// break;
|
||||
// default:
|
||||
// gridType = 'grid';
|
||||
//}
|
||||
|
||||
// Put tabs in correct order based on drop side
|
||||
const tabs = ['left', 'top'].includes(hoverSide) ? [draggedTab, droppedOnTab] : [droppedOnTab, draggedTab];
|
||||
|
||||
this.splitTabs(tabs, gridType);
|
||||
// Put tabs always as if it was dropped from the left
|
||||
this.splitTabs([draggedTab, droppedOnTab], gridType);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
12
src/browser/components/BrowserContentHandler-sys-mjs.patch
Normal file
12
src/browser/components/BrowserContentHandler-sys-mjs.patch
Normal file
@@ -0,0 +1,12 @@
|
||||
diff --git a/browser/components/BrowserContentHandler.sys.mjs b/browser/components/BrowserContentHandler.sys.mjs
|
||||
index 7aef091c0be1cb0ea0be52268949db17032f96d9..5e9105fa671d1b1979f204fc8d3be22771998ad7 100644
|
||||
--- a/browser/components/BrowserContentHandler.sys.mjs
|
||||
+++ b/browser/components/BrowserContentHandler.sys.mjs
|
||||
@@ -1278,6 +1278,7 @@ function maybeRecordToHandleTelemetry(uri, isLaunch) {
|
||||
".avif",
|
||||
".htm",
|
||||
".html",
|
||||
+ ".jxl",
|
||||
".pdf",
|
||||
".shtml",
|
||||
".xht",
|
@@ -0,0 +1,15 @@
|
||||
diff --git a/browser/components/extensions/parent/ext-browser.js b/browser/components/extensions/parent/ext-browser.js
|
||||
index 179816fa96ccf26604d52f71232296398dd9bdbd..c35814bae4eab774892af1f6df7465601d4f87ac 100644
|
||||
--- a/browser/components/extensions/parent/ext-browser.js
|
||||
+++ b/browser/components/extensions/parent/ext-browser.js
|
||||
@@ -1218,6 +1218,10 @@ class TabManager extends TabManagerBase {
|
||||
}
|
||||
|
||||
canAccessTab(nativeTab) {
|
||||
+ if (nativeTab.hasAttribute("zen-empty-tab")) {
|
||||
+ return false
|
||||
+ }
|
||||
+
|
||||
// Check private browsing access at browser window level.
|
||||
if (!this.extension.canAccessWindow(nativeTab.ownerGlobal)) {
|
||||
return false;
|
@@ -1,5 +1,5 @@
|
||||
diff --git a/browser/components/places/PlacesUIUtils.sys.mjs b/browser/components/places/PlacesUIUtils.sys.mjs
|
||||
index fbdd6a34b12d4d957f7a2d9d95df0bfd65ba3f61..4d27f7fc108ca76e071707a737209bf5ea4ea07e 100644
|
||||
index fbdd6a34b12d4d957f7a2d9d95df0bfd65ba3f61..baaf34536f557c69fce3cc43e6f12658514db39f 100644
|
||||
--- a/browser/components/places/PlacesUIUtils.sys.mjs
|
||||
+++ b/browser/components/places/PlacesUIUtils.sys.mjs
|
||||
@@ -58,6 +58,7 @@ class BookmarkState {
|
||||
@@ -95,7 +95,7 @@ index fbdd6a34b12d4d957f7a2d9d95df0bfd65ba3f61..4d27f7fc108ca76e071707a737209bf5
|
||||
+ const placeholders = workspacesToRemove.map(() => '?').join(',');
|
||||
+ await db.execute(`
|
||||
+ DELETE FROM zen_bookmarks_workspaces
|
||||
+ WHERE bookmark_guid = :bookmark_guid
|
||||
+ WHERE bookmark_guid = :bookmark_guid
|
||||
+ AND workspace_uuid IN (${placeholders})
|
||||
+ `, [bookmarkGuid, ...workspacesToRemove]);
|
||||
+
|
||||
@@ -157,12 +157,20 @@ index fbdd6a34b12d4d957f7a2d9d95df0bfd65ba3f61..4d27f7fc108ca76e071707a737209bf5
|
||||
/**
|
||||
* Append transactions to update tags by given information.
|
||||
*
|
||||
@@ -902,7 +1011,7 @@ export var PlacesUIUtils = {
|
||||
@@ -902,8 +1011,15 @@ export var PlacesUIUtils = {
|
||||
aNode,
|
||||
aWhere,
|
||||
aWindow,
|
||||
- { aPrivate = false, userContextId = 0 } = {}
|
||||
+ { aPrivate = false, userContextId = aWindow.ZenWorkspaces.getDefaultContainer() } = {}
|
||||
+ { aPrivate = false, userContextId = undefined } = {}
|
||||
) {
|
||||
+ if (typeof userContextId == "undefined") {
|
||||
+ try {
|
||||
+ let browserWindow = getBrowserWindow(aWindow);
|
||||
+ userContextId = browserWindow.ZenWorkspaces.getDefaultContainer();
|
||||
+ } catch {}
|
||||
+ }
|
||||
+
|
||||
if (
|
||||
aNode &&
|
||||
lazy.PlacesUtils.nodeIsURI(aNode) &&
|
||||
|
13
src/browser/components/search/SearchOneOffs-sys-mjs.patch
Normal file
13
src/browser/components/search/SearchOneOffs-sys-mjs.patch
Normal file
@@ -0,0 +1,13 @@
|
||||
diff --git a/browser/components/search/SearchOneOffs.sys.mjs b/browser/components/search/SearchOneOffs.sys.mjs
|
||||
index 6dcd68f7ec4da72f9510ac3c8ff1cecffbd70e92..f712b95d03be46f7d81bad4113f533f0515a92b9 100644
|
||||
--- a/browser/components/search/SearchOneOffs.sys.mjs
|
||||
+++ b/browser/components/search/SearchOneOffs.sys.mjs
|
||||
@@ -446,7 +446,7 @@ export class SearchOneOffs {
|
||||
// For the search-bar, always show the one-off buttons where there is an
|
||||
// option to add an engine.
|
||||
let addEngineNeeded = isSearchBar && addEngines.length;
|
||||
- let hideOneOffs = (await this.willHide()) && !addEngineNeeded;
|
||||
+ let hideOneOffs = (await this.willHide()) && !addEngineNeeded || Services.prefs.getBoolPref("zen.urlbar.hide-one-offs");
|
||||
|
||||
// The _engineInfo cache is used by more consumers, thus it is not a good
|
||||
// representation of whether this method already updated the one-off buttons
|
12
src/browser/installer/windows/msix/AppxManifest-xml-in.patch
Normal file
12
src/browser/installer/windows/msix/AppxManifest-xml-in.patch
Normal file
@@ -0,0 +1,12 @@
|
||||
diff --git a/browser/installer/windows/msix/AppxManifest.xml.in b/browser/installer/windows/msix/AppxManifest.xml.in
|
||||
index b81a73518a183b7b1d178793886c66f44651058d..89690a4177229b70013bcf35ec1d805fff7e1b26 100644
|
||||
--- a/browser/installer/windows/msix/AppxManifest.xml.in
|
||||
+++ b/browser/installer/windows/msix/AppxManifest.xml.in
|
||||
@@ -61,6 +61,7 @@
|
||||
<uap:FileType>.avif</uap:FileType>
|
||||
<uap:FileType>.htm</uap:FileType>
|
||||
<uap:FileType>.html</uap:FileType>
|
||||
+ <uap:FileType>.jxl</uap:FileType>
|
||||
<uap:FileType>.pdf</uap:FileType>
|
||||
<uap:FileType>.shtml</uap:FileType>
|
||||
<uap:FileType>.xht</uap:FileType>
|
46
src/browser/installer/windows/nsis/shared-nsh.patch
Normal file
46
src/browser/installer/windows/nsis/shared-nsh.patch
Normal file
@@ -0,0 +1,46 @@
|
||||
diff --git a/browser/installer/windows/nsis/shared.nsh b/browser/installer/windows/nsis/shared.nsh
|
||||
index b7f8e1453089ab5f1945e1a65f038e17b5273571..5297f5ed70fe3446e55be37df486fb4ad791a446 100644
|
||||
--- a/browser/installer/windows/nsis/shared.nsh
|
||||
+++ b/browser/installer/windows/nsis/shared.nsh
|
||||
@@ -513,6 +513,7 @@ ${RemoveDefaultBrowserAgentShortcut}
|
||||
${AddAssociationIfNoneExist} ".svg" "FirefoxHTML$5"
|
||||
${AddAssociationIfNoneExist} ".webp" "FirefoxHTML$5"
|
||||
${AddAssociationIfNoneExist} ".avif" "FirefoxHTML$5"
|
||||
+ ${AddAssociationIfNoneExist} ".jxl" "FirefoxHTML$5"
|
||||
|
||||
${AddAssociationIfNoneExist} ".pdf" "FirefoxPDF$5"
|
||||
|
||||
@@ -609,6 +610,7 @@ ${RemoveDefaultBrowserAgentShortcut}
|
||||
WriteRegStr ${RegKey} "$0\Capabilities\FileAssociations" ".svg" "FirefoxHTML$2"
|
||||
WriteRegStr ${RegKey} "$0\Capabilities\FileAssociations" ".webp" "FirefoxHTML$2"
|
||||
WriteRegStr ${RegKey} "$0\Capabilities\FileAssociations" ".avif" "FirefoxHTML$2"
|
||||
+ WriteRegStr ${RegKey} "$0\Capabilities\FileAssociations" ".jxl" "FirefoxHTML$2"
|
||||
|
||||
WriteRegStr ${RegKey} "$0\Capabilities\FileAssociations" ".pdf" "FirefoxPDF$2"
|
||||
|
||||
@@ -681,6 +683,7 @@ ${RemoveDefaultBrowserAgentShortcut}
|
||||
${WriteApplicationsSupportedType} ${RegKey} ".webm"
|
||||
${WriteApplicationsSupportedType} ${RegKey} ".webp"
|
||||
${WriteApplicationsSupportedType} ${RegKey} ".avif"
|
||||
+ ${WriteApplicationsSupportedType} ${RegKey} ".jxl"
|
||||
${WriteApplicationsSupportedType} ${RegKey} ".xht"
|
||||
${WriteApplicationsSupportedType} ${RegKey} ".xhtml"
|
||||
${WriteApplicationsSupportedType} ${RegKey} ".xml"
|
||||
@@ -1728,6 +1731,8 @@ Function SetAsDefaultAppUserHKCU
|
||||
Pop $0
|
||||
AppAssocReg::SetAppAsDefault "$R9" ".avif" "file"
|
||||
Pop $0
|
||||
+ AppAssocReg::SetAppAsDefault "$R9" ".jxl" "file"
|
||||
+ Pop $0
|
||||
AppAssocReg::SetAppAsDefault "$R9" ".xht" "file"
|
||||
Pop $0
|
||||
AppAssocReg::SetAppAsDefault "$R9" ".xhtml" "file"
|
||||
@@ -1857,7 +1862,7 @@ FunctionEnd
|
||||
; uninstalled.
|
||||
|
||||
; Do all of that twice, once for the local machine and once for the current user
|
||||
-
|
||||
+
|
||||
; Remove protocol handlers
|
||||
ClearErrors
|
||||
ReadRegStr $0 HKLM "Software\Classes\${_PROTOCOL}\DefaultIcon" ""
|
12
src/browser/installer/windows/nsis/uninstaller-nsi.patch
Normal file
12
src/browser/installer/windows/nsis/uninstaller-nsi.patch
Normal file
@@ -0,0 +1,12 @@
|
||||
diff --git a/browser/installer/windows/nsis/uninstaller.nsi b/browser/installer/windows/nsis/uninstaller.nsi
|
||||
index 559c8b46ee06bc42c91da49b5d9e397fe8ff6126..62094a5d98712a41a607ba01ca2adfa1e4f51ccd 100644
|
||||
--- a/browser/installer/windows/nsis/uninstaller.nsi
|
||||
+++ b/browser/installer/windows/nsis/uninstaller.nsi
|
||||
@@ -507,6 +507,7 @@ Section "Uninstall"
|
||||
${un.RegCleanFileHandler} ".svg" "FirefoxHTML-$AppUserModelID"
|
||||
${un.RegCleanFileHandler} ".webp" "FirefoxHTML-$AppUserModelID"
|
||||
${un.RegCleanFileHandler} ".avif" "FirefoxHTML-$AppUserModelID"
|
||||
+ ${un.RegCleanFileHandler} ".jxl" "FirefoxHTML-$AppUserModelID"
|
||||
|
||||
${un.RegCleanFileHandler} ".pdf" "FirefoxPDF-$AppUserModelID"
|
||||
|
@@ -1140,6 +1140,7 @@ menupopup > menuitem:is([type='checkbox']) .menu-iconic-left {
|
||||
}
|
||||
|
||||
#toolbar-context-toggle-vertical-tabs,
|
||||
#toolbar-context-customize-sidebar {
|
||||
display: none;
|
||||
#toolbar-context-customize-sidebar,
|
||||
#sidebarRevampSeparator {
|
||||
display: none !important;
|
||||
}
|
||||
|
32
src/image/DecoderFactory-cpp.patch
Normal file
32
src/image/DecoderFactory-cpp.patch
Normal file
@@ -0,0 +1,32 @@
|
||||
diff --git a/image/DecoderFactory.cpp b/image/DecoderFactory.cpp
|
||||
index f36f03c7f2..d2cdd79f70 100644
|
||||
--- a/image/DecoderFactory.cpp
|
||||
+++ b/image/DecoderFactory.cpp
|
||||
@@ -244,7 +244,12 @@ nsresult DecoderFactory::CreateAnimationDecoder(
|
||||
}
|
||||
|
||||
MOZ_ASSERT(aType == DecoderType::GIF || aType == DecoderType::PNG ||
|
||||
- aType == DecoderType::WEBP || aType == DecoderType::AVIF,
|
||||
+ aType == DecoderType::WEBP || aType == DecoderType::AVIF
|
||||
+#ifdef MOZ_JXL
|
||||
+ || aType == DecoderType::JXL,
|
||||
+#else
|
||||
+ ,
|
||||
+#endif
|
||||
"Calling CreateAnimationDecoder for non-animating DecoderType");
|
||||
|
||||
// Create an anonymous decoder. Interaction with the SurfaceCache and the
|
||||
@@ -299,7 +304,12 @@ already_AddRefed<Decoder> DecoderFactory::CloneAnimationDecoder(
|
||||
// rediscover it is animated).
|
||||
DecoderType type = aDecoder->GetType();
|
||||
MOZ_ASSERT(type == DecoderType::GIF || type == DecoderType::PNG ||
|
||||
- type == DecoderType::WEBP || type == DecoderType::AVIF,
|
||||
+ type == DecoderType::WEBP || type == DecoderType::AVIF
|
||||
+#ifdef MOZ_JXL
|
||||
+ || aType == DecoderType::JXL,
|
||||
+#else
|
||||
+ ,
|
||||
+#endif
|
||||
"Calling CloneAnimationDecoder for non-animating DecoderType");
|
||||
|
||||
RefPtr<Decoder> decoder = GetDecoder(type, nullptr, /* aIsRedecode = */ true);
|
308
src/image/decoders/nsJXLDecoder-cpp.patch
Normal file
308
src/image/decoders/nsJXLDecoder-cpp.patch
Normal file
@@ -0,0 +1,308 @@
|
||||
diff --git a/image/decoders/nsJXLDecoder.cpp b/image/decoders/nsJXLDecoder.cpp
|
||||
index ffb7f3cd51e1d0e480bf8ac5e936a90c11f0c93d..282472afe4fbab7d41adaf15928fa93c99e74452 100644
|
||||
--- a/image/decoders/nsJXLDecoder.cpp
|
||||
+++ b/image/decoders/nsJXLDecoder.cpp
|
||||
@@ -45,9 +45,20 @@ nsJXLDecoder::nsJXLDecoder(RasterImage* aImage)
|
||||
Transition::TerminateSuccess()),
|
||||
mDecoder(JxlDecoderMake(nullptr)),
|
||||
mParallelRunner(
|
||||
- JxlThreadParallelRunnerMake(nullptr, PreferredThreadCount())) {
|
||||
- JxlDecoderSubscribeEvents(mDecoder.get(),
|
||||
- JXL_DEC_BASIC_INFO | JXL_DEC_FULL_IMAGE);
|
||||
+ JxlThreadParallelRunnerMake(nullptr, PreferredThreadCount())),
|
||||
+ mUsePipeTransform(true),
|
||||
+ mCMSLine(nullptr),
|
||||
+ mNumFrames(0),
|
||||
+ mTimeout(FrameTimeout::Forever()),
|
||||
+ mSurfaceFormat(SurfaceFormat::OS_RGBX),
|
||||
+ mContinue(false) {
|
||||
+ int events = JXL_DEC_BASIC_INFO | JXL_DEC_FRAME | JXL_DEC_FULL_IMAGE;
|
||||
+
|
||||
+ if (mCMSMode != CMSMode::Off) {
|
||||
+ events |= JXL_DEC_COLOR_ENCODING;
|
||||
+ }
|
||||
+
|
||||
+ JxlDecoderSubscribeEvents(mDecoder.get(), events);
|
||||
JxlDecoderSetParallelRunner(mDecoder.get(), JxlThreadParallelRunner,
|
||||
mParallelRunner.get());
|
||||
|
||||
@@ -58,6 +69,10 @@ nsJXLDecoder::nsJXLDecoder(RasterImage* aImage)
|
||||
nsJXLDecoder::~nsJXLDecoder() {
|
||||
MOZ_LOG(sJXLLog, LogLevel::Debug,
|
||||
("[this=%p] nsJXLDecoder::~nsJXLDecoder", this));
|
||||
+
|
||||
+ if (mCMSLine) {
|
||||
+ free(mCMSLine);
|
||||
+ }
|
||||
}
|
||||
|
||||
size_t nsJXLDecoder::PreferredThreadCount() {
|
||||
@@ -86,14 +101,20 @@ LexerResult nsJXLDecoder::DoDecode(SourceBufferIterator& aIterator,
|
||||
|
||||
LexerTransition<nsJXLDecoder::State> nsJXLDecoder::ReadJXLData(
|
||||
const char* aData, size_t aLength) {
|
||||
- const uint8_t* input = (const uint8_t*)aData;
|
||||
- size_t length = aLength;
|
||||
- if (mBuffer.length() != 0) {
|
||||
- JXL_TRY_BOOL(mBuffer.append(aData, aLength));
|
||||
- input = mBuffer.begin();
|
||||
- length = mBuffer.length();
|
||||
+ // Ignore data we have already read.
|
||||
+ // This will only occur as a result of a yield for animation.
|
||||
+ if (!mContinue) {
|
||||
+ const uint8_t* input = (const uint8_t*)aData;
|
||||
+ size_t length = aLength;
|
||||
+ if (mBuffer.length() != 0) {
|
||||
+ JXL_TRY_BOOL(mBuffer.append(aData, aLength));
|
||||
+ input = mBuffer.begin();
|
||||
+ length = mBuffer.length();
|
||||
+ }
|
||||
+
|
||||
+ JXL_TRY(JxlDecoderSetInput(mDecoder.get(), input, length));
|
||||
}
|
||||
- JXL_TRY(JxlDecoderSetInput(mDecoder.get(), input, length));
|
||||
+ mContinue = false;
|
||||
|
||||
while (true) {
|
||||
JxlDecoderStatus status = JxlDecoderProcessInput(mDecoder.get());
|
||||
@@ -106,51 +127,229 @@ LexerTransition<nsJXLDecoder::State> nsJXLDecoder::ReadJXLData(
|
||||
size_t remaining = JxlDecoderReleaseInput(mDecoder.get());
|
||||
mBuffer.clear();
|
||||
JXL_TRY_BOOL(mBuffer.append(aData + aLength - remaining, remaining));
|
||||
+
|
||||
+ if (mNumFrames == 0 && InFrame()) {
|
||||
+ // If an image was flushed by JxlDecoderFlushImage, then we know that
|
||||
+ // JXL_DEC_FRAME has already been run and there is a pipe.
|
||||
+ if (JxlDecoderFlushImage(mDecoder.get()) == JXL_DEC_SUCCESS) {
|
||||
+ // A full frame partial image is written to the buffer.
|
||||
+ mPipe.ResetToFirstRow();
|
||||
+ for (uint8_t* rowPtr = mOutBuffer.begin();
|
||||
+ rowPtr < mOutBuffer.end(); rowPtr += mInfo.xsize * mChannels) {
|
||||
+ uint8_t* rowToWrite = rowPtr;
|
||||
+
|
||||
+ if (!mUsePipeTransform && mTransform) {
|
||||
+ qcms_transform_data(mTransform, rowToWrite, mCMSLine,
|
||||
+ mInfo.xsize);
|
||||
+ rowToWrite = mCMSLine;
|
||||
+ }
|
||||
+
|
||||
+ mPipe.WriteBuffer(reinterpret_cast<uint32_t*>(rowToWrite));
|
||||
+ }
|
||||
+
|
||||
+ if (Maybe<SurfaceInvalidRect> invalidRect =
|
||||
+ mPipe.TakeInvalidRect()) {
|
||||
+ PostInvalidation(invalidRect->mInputSpaceRect,
|
||||
+ Some(invalidRect->mOutputSpaceRect));
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
return Transition::ContinueUnbuffered(State::JXL_DATA);
|
||||
}
|
||||
|
||||
case JXL_DEC_BASIC_INFO: {
|
||||
JXL_TRY(JxlDecoderGetBasicInfo(mDecoder.get(), &mInfo));
|
||||
PostSize(mInfo.xsize, mInfo.ysize);
|
||||
+
|
||||
if (WantsFrameCount()) {
|
||||
PostFrameCount(/* aFrameCount */ 1);
|
||||
}
|
||||
+
|
||||
if (mInfo.alpha_bits > 0) {
|
||||
+ mSurfaceFormat = SurfaceFormat::OS_RGBA;
|
||||
PostHasTransparency();
|
||||
}
|
||||
+
|
||||
+ if (!mInfo.have_animation && IsMetadataDecode()) {
|
||||
+ return Transition::TerminateSuccess();
|
||||
+ }
|
||||
+
|
||||
+ // If CMS is off or the image is RGB, always output in RGBA.
|
||||
+ // If the image is grayscale, then the pipe transform can't be used.
|
||||
+ if (mCMSMode != CMSMode::Off) {
|
||||
+ mChannels = mInfo.num_color_channels == 1
|
||||
+ ? 1 + (mInfo.alpha_bits > 0 ? 1 : 0)
|
||||
+ : 4;
|
||||
+ } else {
|
||||
+ mChannels = 4;
|
||||
+ }
|
||||
+
|
||||
+ mFormat = {mChannels, JXL_TYPE_UINT8, JXL_LITTLE_ENDIAN, 0};
|
||||
+
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ case JXL_DEC_COLOR_ENCODING: {
|
||||
+ size_t size = 0;
|
||||
+ JXL_TRY(JxlDecoderGetICCProfileSize(
|
||||
+ mDecoder.get(), JXL_COLOR_PROFILE_TARGET_DATA, &size))
|
||||
+ std::vector<uint8_t> icc_profile(size);
|
||||
+ JXL_TRY(JxlDecoderGetColorAsICCProfile(mDecoder.get(),
|
||||
+ JXL_COLOR_PROFILE_TARGET_DATA,
|
||||
+ icc_profile.data(), size))
|
||||
+
|
||||
+ mInProfile = qcms_profile_from_memory((char*)icc_profile.data(), size);
|
||||
+
|
||||
+ uint32_t profileSpace = qcms_profile_get_color_space(mInProfile);
|
||||
+
|
||||
+ // Skip color management if color profile is not compatible with number
|
||||
+ // of channels.
|
||||
+ if (profileSpace != icSigRgbData &&
|
||||
+ (mInfo.num_color_channels == 3 || profileSpace != icSigGrayData)) {
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ mUsePipeTransform =
|
||||
+ profileSpace == icSigRgbData && mInfo.num_color_channels == 3;
|
||||
+
|
||||
+ qcms_data_type inType;
|
||||
+ if (mInfo.num_color_channels == 3) {
|
||||
+ inType = QCMS_DATA_RGBA_8;
|
||||
+ } else if (mInfo.alpha_bits > 0) {
|
||||
+ inType = QCMS_DATA_GRAYA_8;
|
||||
+ } else {
|
||||
+ inType = QCMS_DATA_GRAY_8;
|
||||
+ }
|
||||
+
|
||||
+ if (!mUsePipeTransform) {
|
||||
+ mCMSLine =
|
||||
+ static_cast<uint8_t*>(malloc(sizeof(uint32_t) * mInfo.xsize));
|
||||
+ }
|
||||
+
|
||||
+ int intent = gfxPlatform::GetRenderingIntent();
|
||||
+ if (intent == -1) {
|
||||
+ intent = qcms_profile_get_rendering_intent(mInProfile);
|
||||
+ }
|
||||
+
|
||||
+ mTransform =
|
||||
+ qcms_transform_create(mInProfile, inType, GetCMSOutputProfile(),
|
||||
+ QCMS_DATA_RGBA_8, (qcms_intent)intent);
|
||||
+
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ case JXL_DEC_FRAME: {
|
||||
+ if (mInfo.have_animation) {
|
||||
+ JXL_TRY(JxlDecoderGetFrameHeader(mDecoder.get(), &mFrameHeader));
|
||||
+ int32_t duration = (int32_t)(1000.0 * mFrameHeader.duration *
|
||||
+ mInfo.animation.tps_denominator /
|
||||
+ mInfo.animation.tps_numerator);
|
||||
+
|
||||
+ mTimeout = FrameTimeout::FromRawMilliseconds(duration);
|
||||
+
|
||||
+ if (!HasAnimation()) {
|
||||
+ PostIsAnimated(mTimeout);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ bool is_last = mInfo.have_animation ? mFrameHeader.is_last : true;
|
||||
+ MOZ_LOG(sJXLLog, LogLevel::Debug,
|
||||
+ ("[this=%p] nsJXLDecoder::ReadJXLData - frame %d, is_last %d, "
|
||||
+ "metadata decode %d, first frame decode %d\n",
|
||||
+ this, mNumFrames, is_last, IsMetadataDecode(),
|
||||
+ IsFirstFrameDecode()));
|
||||
+
|
||||
if (IsMetadataDecode()) {
|
||||
return Transition::TerminateSuccess();
|
||||
}
|
||||
+
|
||||
+ OrientedIntSize size(mInfo.xsize, mInfo.ysize);
|
||||
+
|
||||
+ Maybe<AnimationParams> animParams;
|
||||
+ if (!IsFirstFrameDecode()) {
|
||||
+ animParams.emplace(FullFrame().ToUnknownRect(), mTimeout, mNumFrames,
|
||||
+ BlendMethod::SOURCE, DisposalMethod::CLEAR);
|
||||
+ }
|
||||
+
|
||||
+ SurfacePipeFlags pipeFlags = SurfacePipeFlags();
|
||||
+ if (mNumFrames == 0) {
|
||||
+ // The first frame may be displayed progressively.
|
||||
+ pipeFlags |= SurfacePipeFlags::PROGRESSIVE_DISPLAY;
|
||||
+ }
|
||||
+ if (mSurfaceFormat == SurfaceFormat::OS_RGBA &&
|
||||
+ !(GetSurfaceFlags() & SurfaceFlags::NO_PREMULTIPLY_ALPHA)) {
|
||||
+ pipeFlags |= SurfacePipeFlags::PREMULTIPLY_ALPHA;
|
||||
+ }
|
||||
+
|
||||
+ qcms_transform* pipeTransform =
|
||||
+ mUsePipeTransform ? mTransform : nullptr;
|
||||
+
|
||||
+ Maybe<SurfacePipe> pipe = SurfacePipeFactory::CreateSurfacePipe(
|
||||
+ this, size, OutputSize(), FullFrame(), SurfaceFormat::R8G8B8A8,
|
||||
+ mSurfaceFormat, animParams, pipeTransform, pipeFlags);
|
||||
+
|
||||
+ if (!pipe) {
|
||||
+ MOZ_LOG(sJXLLog, LogLevel::Debug,
|
||||
+ ("[this=%p] nsJXLDecoder::ReadJXLData - no pipe\n", this));
|
||||
+ return Transition::TerminateFailure();
|
||||
+ }
|
||||
+
|
||||
+ mPipe = std::move(*pipe);
|
||||
+
|
||||
break;
|
||||
}
|
||||
|
||||
case JXL_DEC_NEED_IMAGE_OUT_BUFFER: {
|
||||
size_t size = 0;
|
||||
- JxlPixelFormat format{4, JXL_TYPE_UINT8, JXL_LITTLE_ENDIAN, 0};
|
||||
- JXL_TRY(JxlDecoderImageOutBufferSize(mDecoder.get(), &format, &size));
|
||||
+ JXL_TRY(JxlDecoderImageOutBufferSize(mDecoder.get(), &mFormat, &size));
|
||||
|
||||
mOutBuffer.clear();
|
||||
JXL_TRY_BOOL(mOutBuffer.growBy(size));
|
||||
- JXL_TRY(JxlDecoderSetImageOutBuffer(mDecoder.get(), &format,
|
||||
+ JXL_TRY(JxlDecoderSetImageOutBuffer(mDecoder.get(), &mFormat,
|
||||
mOutBuffer.begin(), size));
|
||||
break;
|
||||
}
|
||||
|
||||
case JXL_DEC_FULL_IMAGE: {
|
||||
- OrientedIntSize size(mInfo.xsize, mInfo.ysize);
|
||||
- Maybe<SurfacePipe> pipe = SurfacePipeFactory::CreateSurfacePipe(
|
||||
- this, size, OutputSize(), FullFrame(), SurfaceFormat::R8G8B8A8,
|
||||
- SurfaceFormat::OS_RGBA, Nothing(), nullptr, SurfacePipeFlags());
|
||||
+ mPipe.ResetToFirstRow();
|
||||
+
|
||||
for (uint8_t* rowPtr = mOutBuffer.begin(); rowPtr < mOutBuffer.end();
|
||||
- rowPtr += mInfo.xsize * 4) {
|
||||
- pipe->WriteBuffer(reinterpret_cast<uint32_t*>(rowPtr));
|
||||
+ rowPtr += mInfo.xsize * mChannels) {
|
||||
+ uint8_t* rowToWrite = rowPtr;
|
||||
+
|
||||
+ if (!mUsePipeTransform && mTransform) {
|
||||
+ qcms_transform_data(mTransform, rowToWrite, mCMSLine, mInfo.xsize);
|
||||
+ rowToWrite = mCMSLine;
|
||||
+ }
|
||||
+
|
||||
+ mPipe.WriteBuffer(reinterpret_cast<uint32_t*>(rowToWrite));
|
||||
}
|
||||
|
||||
- if (Maybe<SurfaceInvalidRect> invalidRect = pipe->TakeInvalidRect()) {
|
||||
+ if (Maybe<SurfaceInvalidRect> invalidRect = mPipe.TakeInvalidRect()) {
|
||||
PostInvalidation(invalidRect->mInputSpaceRect,
|
||||
Some(invalidRect->mOutputSpaceRect));
|
||||
}
|
||||
- PostFrameStop();
|
||||
+
|
||||
+ Opacity opacity = (mSurfaceFormat == SurfaceFormat::OS_RGBA)
|
||||
+ ? Opacity::SOME_TRANSPARENCY
|
||||
+ : Opacity::FULLY_OPAQUE;
|
||||
+ PostFrameStop(opacity);
|
||||
+
|
||||
+ if (!IsFirstFrameDecode() && mInfo.have_animation &&
|
||||
+ !mFrameHeader.is_last) {
|
||||
+ mNumFrames++;
|
||||
+ mContinue = true;
|
||||
+ // Notify for a new frame but there may be data in the current buffer
|
||||
+ // that can immediately be processed.
|
||||
+ return Transition::ToAfterYield(State::JXL_DATA);
|
||||
+ }
|
||||
+ [[fallthrough]]; // We are done.
|
||||
+ }
|
||||
+
|
||||
+ case JXL_DEC_SUCCESS: {
|
||||
+ PostLoopCount(HasAnimation() ? (int32_t)mInfo.animation.num_loops - 1
|
||||
+ : 0);
|
||||
PostDecodeDone();
|
||||
return Transition::TerminateSuccess();
|
||||
}
|
23
src/image/decoders/nsJXLDecoder-h.patch
Normal file
23
src/image/decoders/nsJXLDecoder-h.patch
Normal file
@@ -0,0 +1,23 @@
|
||||
diff --git a/image/decoders/nsJXLDecoder.h b/image/decoders/nsJXLDecoder.h
|
||||
index 6cde7456ca03f79e74401c1d215b9d50453ebf41..2f593ca3b70100c600b86e753d7a458c83b4f15c 100644
|
||||
--- a/image/decoders/nsJXLDecoder.h
|
||||
+++ b/image/decoders/nsJXLDecoder.h
|
||||
@@ -48,6 +48,18 @@ class nsJXLDecoder final : public Decoder {
|
||||
Vector<uint8_t> mBuffer;
|
||||
Vector<uint8_t> mOutBuffer;
|
||||
JxlBasicInfo mInfo{};
|
||||
+ JxlPixelFormat mFormat;
|
||||
+ JxlFrameHeader mFrameHeader;
|
||||
+
|
||||
+ bool mUsePipeTransform;
|
||||
+ uint8_t mChannels;
|
||||
+ uint8_t* mCMSLine;
|
||||
+
|
||||
+ uint32_t mNumFrames;
|
||||
+ FrameTimeout mTimeout;
|
||||
+ gfx::SurfaceFormat mSurfaceFormat;
|
||||
+ SurfacePipe mPipe;
|
||||
+ bool mContinue;
|
||||
};
|
||||
|
||||
} // namespace mozilla::image
|
31
src/third_party/rust/mime_guess/src/mime_types-rs.patch
vendored
Normal file
31
src/third_party/rust/mime_guess/src/mime_types-rs.patch
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
diff --git a/third_party/rust/mime_guess/src/mime_types.rs b/third_party/rust/mime_guess/src/mime_types.rs
|
||||
index 13c91b7bee77a0c0a4b45b8e05a25bb89daac66e..1521cd729ec78dbc51b86cf04546c4cd4ceb1163 100644
|
||||
--- a/third_party/rust/mime_guess/src/mime_types.rs
|
||||
+++ b/third_party/rust/mime_guess/src/mime_types.rs
|
||||
@@ -103,6 +103,7 @@ pub static MIME_TYPES: &[(&str, &[&str])] = &[
|
||||
("au", &["audio/basic"]),
|
||||
("avi", &["video/x-msvideo"]),
|
||||
("avif", &["image/avif"]),
|
||||
+ ("avifs", &["image/avif-sequence"]),
|
||||
("aw", &["application/applixware"]),
|
||||
("axa", &["audio/annodex"]),
|
||||
("axs", &["application/olescript"]),
|
||||
@@ -449,6 +450,10 @@ pub static MIME_TYPES: &[(&str, &[&str])] = &[
|
||||
("hdf", &["application/x-hdf"]),
|
||||
("hdml", &["text/x-hdml"]),
|
||||
("hdr", &["image/vnd.radiance"]),
|
||||
+ ("heic", &["image/heic"]),
|
||||
+ ("heics", &["image/heic-sequence"]),
|
||||
+ ("heif", &["image/heif"]),
|
||||
+ ("heifs", &["image/heif-sequence"]),
|
||||
("hh", &["text/plain"]),
|
||||
("hhc", &["application/x-oleobject"]),
|
||||
("hhk", &["application/octet-stream"]),
|
||||
@@ -567,6 +572,7 @@ pub static MIME_TYPES: &[(&str, &[&str])] = &[
|
||||
("jsonml", &["application/jsonml+json"]),
|
||||
("jsx", &["text/jscript"]),
|
||||
("jsxbin", &["text/plain"]),
|
||||
+ ("jxl", &["image/jxl"]),
|
||||
("kar", &["audio/midi"]),
|
||||
("karbon", &["application/vnd.kde.karbon"]),
|
||||
("kfo", &["application/vnd.kde.kformula"]),
|
12
src/toolkit/components/downloads/DownloadList-sys-mjs.patch
Normal file
12
src/toolkit/components/downloads/DownloadList-sys-mjs.patch
Normal file
@@ -0,0 +1,12 @@
|
||||
diff --git a/toolkit/components/downloads/DownloadList.sys.mjs b/toolkit/components/downloads/DownloadList.sys.mjs
|
||||
index c4e5776940c4cdca731a82ba91d41620c4c7b75a..d580d193bda5e932cebc849c4487de504f17b6fe 100644
|
||||
--- a/toolkit/components/downloads/DownloadList.sys.mjs
|
||||
+++ b/toolkit/components/downloads/DownloadList.sys.mjs
|
||||
@@ -50,6 +50,7 @@ const FILE_EXTENSIONS = [
|
||||
"jpg",
|
||||
"jpeg",
|
||||
"json",
|
||||
+ "jxl",
|
||||
"m4a",
|
||||
"mdb",
|
||||
"mid",
|
@@ -0,0 +1,20 @@
|
||||
diff --git a/toolkit/components/extensions/parent/ext-downloads.js b/toolkit/components/extensions/parent/ext-downloads.js
|
||||
index ea6929d23d432958def5be46e42e329bc224d3aa..942cfddc090399ef239cc34ab47682cab6a33cd4 100644
|
||||
--- a/toolkit/components/extensions/parent/ext-downloads.js
|
||||
+++ b/toolkit/components/extensions/parent/ext-downloads.js
|
||||
@@ -87,6 +87,7 @@ const FILTER_IMAGES_EXTENSIONS = [
|
||||
"jpe",
|
||||
"jpg",
|
||||
"jpeg",
|
||||
+ "jxl",
|
||||
"gif",
|
||||
"png",
|
||||
"bmp",
|
||||
@@ -104,6 +105,7 @@ const FILTER_IMAGES_EXTENSIONS = [
|
||||
"raw",
|
||||
"webp",
|
||||
"heic",
|
||||
+ "avif",
|
||||
];
|
||||
|
||||
const FILTER_XML_EXTENSIONS = ["xml"];
|
13
src/toolkit/content/filepicker-properties.patch
Normal file
13
src/toolkit/content/filepicker-properties.patch
Normal file
@@ -0,0 +1,13 @@
|
||||
diff --git a/toolkit/content/filepicker.properties b/toolkit/content/filepicker.properties
|
||||
index 03daec114c2882ed5ab7899b9b435d1cce936838..b6bd09c3c5625a1649b31dc99935bc90773d4133 100644
|
||||
--- a/toolkit/content/filepicker.properties
|
||||
+++ b/toolkit/content/filepicker.properties
|
||||
@@ -5,7 +5,7 @@
|
||||
allFilter=*
|
||||
htmlFilter=*.html; *.htm; *.shtml; *.xhtml
|
||||
textFilter=*.txt; *.text
|
||||
-imageFilter=*.jpe; *.jpg; *.jpeg; *.gif; *.png; *.bmp; *.ico; *.svg; *.svgz; *.tif; *.tiff; *.ai; *.drw; *.pct; *.psp; *.xcf; *.psd; *.raw; *.webp; *.heic
|
||||
+imageFilter=*.jpe; *.jpg; *.jpeg; *.gif; *.png; *.bmp; *.ico; *.svg; *.svgz; *.tif; *.tiff; *.ai; *.drw; *.pct; *.psp; *.xcf; *.psd; *.raw; *.webp; *.heic; *.avif; *.jxl
|
||||
xmlFilter=*.xml
|
||||
xulFilter=*.xul
|
||||
audioFilter=*.aac; *.aif; *.flac; *.iff; *.m4a; *.m4b; *.mid; *.midi; *.mp3; *.mpa; *.mpc; *.oga; *.ogg; *.opus; *.ra; *.ram; *.snd; *.wav; *.wma
|
@@ -0,0 +1,12 @@
|
||||
diff --git a/toolkit/locales/en-US/chrome/mozapps/downloads/unknownContentType.properties b/toolkit/locales/en-US/chrome/mozapps/downloads/unknownContentType.properties
|
||||
index fa3c5e389bad5abb05c86a3cb08d6c7abf34166c..1bb1f48c4d3964e4637462bb0b3d4a1e965ca5ec 100644
|
||||
--- a/toolkit/locales/en-US/chrome/mozapps/downloads/unknownContentType.properties
|
||||
+++ b/toolkit/locales/en-US/chrome/mozapps/downloads/unknownContentType.properties
|
||||
@@ -17,6 +17,7 @@ fileType=%S file
|
||||
# LOCALIZATION NOTE (orderedFileSizeWithType): first %S is type, second %S is size, and third %S is unit
|
||||
orderedFileSizeWithType=%1$S (%2$S %3$S)
|
||||
avifExtHandlerDescription=AV1 Image File (AVIF)
|
||||
+jxlExtHandlerDescription=JPEG XL Image (JXL)
|
||||
pdfExtHandlerDescription=Portable Document Format (PDF)
|
||||
svgExtHandlerDescription=Scalable Vector Graphics (SVG)
|
||||
webpExtHandlerDescription=WebP Image
|
14
src/widget/gtk/nsAppShell-cpp.patch
Normal file
14
src/widget/gtk/nsAppShell-cpp.patch
Normal file
@@ -0,0 +1,14 @@
|
||||
diff --git a/widget/gtk/nsAppShell.cpp b/widget/gtk/nsAppShell.cpp
|
||||
index eef6e76a26341d30748c6c4f054092ba0bfdd865..65b6e2583e6e6891dcbf9faeeefed21cc2d40d15 100644
|
||||
--- a/widget/gtk/nsAppShell.cpp
|
||||
+++ b/widget/gtk/nsAppShell.cpp
|
||||
@@ -419,7 +419,8 @@ nsresult nsAppShell::Init() {
|
||||
gchar* name = gdk_pixbuf_format_get_name(format);
|
||||
if (strcmp(name, "jpeg") && strcmp(name, "png") && strcmp(name, "gif") &&
|
||||
strcmp(name, "bmp") && strcmp(name, "ico") && strcmp(name, "xpm") &&
|
||||
- strcmp(name, "svg") && strcmp(name, "webp") && strcmp(name, "avif")) {
|
||||
+ strcmp(name, "svg") && strcmp(name, "webp") && strcmp(name, "avif") &&
|
||||
+ strcmp(name, "jxl")) {
|
||||
gdk_pixbuf_format_set_disabled(format, TRUE);
|
||||
}
|
||||
g_free(name);
|
Reference in New Issue
Block a user