Backed out 2 changesets (bug 1911489) for causing build bustages @ FaviconHelpers.cpp CLOSED TREE
Backed out changeset 1f24313b74af (bug 1911489) Backed out changeset 6badc2766d0f (bug 1911489)
This commit is contained in:
@@ -137,15 +137,14 @@ export class LinkHandlerParent extends JSWindowActorParent {
|
||||
}
|
||||
if (canStoreIcon) {
|
||||
try {
|
||||
lazy.PlacesUtils.favicons
|
||||
.setFaviconForPage(
|
||||
lazy.PlacesUtils.favicons.setFaviconForPage(
|
||||
Services.io.newURI(pageURL),
|
||||
Services.io.newURI(originalURL),
|
||||
iconURI,
|
||||
expiration && lazy.PlacesUtils.toPRTime(expiration),
|
||||
null,
|
||||
isRichIcon
|
||||
)
|
||||
.catch(console.error);
|
||||
);
|
||||
} catch (ex) {
|
||||
console.error(ex);
|
||||
}
|
||||
|
||||
@@ -23,7 +23,15 @@ add_task(async function test_notificationClose() {
|
||||
let dataURL = makeURI(
|
||||
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVQI12P4//8/AAX+Av7czFnnAAAAAElFTkSuQmCC"
|
||||
);
|
||||
await PlacesTestUtils.setFaviconForPage(notificationURI, dataURL, dataURL);
|
||||
await new Promise(resolve => {
|
||||
PlacesUtils.favicons.setFaviconForPage(
|
||||
notificationURI,
|
||||
dataURL,
|
||||
dataURL,
|
||||
null,
|
||||
resolve
|
||||
);
|
||||
});
|
||||
|
||||
await BrowserTestUtils.withNewTab(
|
||||
{
|
||||
|
||||
@@ -247,13 +247,11 @@ DistributionCustomizer.prototype = {
|
||||
|
||||
if (item.icon && item.iconData) {
|
||||
try {
|
||||
lazy.PlacesUtils.favicons
|
||||
.setFaviconForPage(
|
||||
lazy.PlacesUtils.favicons.setFaviconForPage(
|
||||
Services.io.newURI(item.link),
|
||||
Services.io.newURI(item.icon),
|
||||
Services.io.newURI(item.iconData)
|
||||
)
|
||||
.catch(console.error);
|
||||
);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
|
||||
@@ -211,13 +211,11 @@ function setFaviconForBookmark(bookmark) {
|
||||
return;
|
||||
}
|
||||
|
||||
lazy.PlacesUtils.favicons
|
||||
.setFaviconForPage(
|
||||
lazy.PlacesUtils.favicons.setFaviconForPage(
|
||||
bookmark.URL.URI,
|
||||
Services.io.newURI("fake-favicon-uri:" + bookmark.URL.href),
|
||||
bookmark.Favicon.URI
|
||||
)
|
||||
.catch(lazy.log.error);
|
||||
);
|
||||
}
|
||||
|
||||
// Cache of folder names to guids to be used by the getParentGuid
|
||||
|
||||
@@ -886,6 +886,8 @@ class MigrationUtils {
|
||||
);
|
||||
|
||||
for (let faviconDataItem of favicons) {
|
||||
let dataURL;
|
||||
|
||||
try {
|
||||
// getMIMETypeFromContent throws error if could not get the mime type
|
||||
// from the data.
|
||||
@@ -895,7 +897,7 @@ class MigrationUtils {
|
||||
faviconDataItem.faviconData.length
|
||||
);
|
||||
|
||||
let dataURL = await new Promise((resolve, reject) => {
|
||||
dataURL = await new Promise((resolve, reject) => {
|
||||
let buffer = new Uint8ClampedArray(faviconDataItem.faviconData);
|
||||
let blob = new Blob([buffer], { type: mimeType });
|
||||
let reader = new FileReader();
|
||||
@@ -907,16 +909,15 @@ class MigrationUtils {
|
||||
let fakeFaviconURI = Services.io.newURI(
|
||||
"fake-favicon-uri:" + faviconDataItem.uri.spec
|
||||
);
|
||||
lazy.PlacesUtils.favicons
|
||||
.setFaviconForPage(
|
||||
lazy.PlacesUtils.favicons.setFaviconForPage(
|
||||
faviconDataItem.uri,
|
||||
fakeFaviconURI,
|
||||
Services.io.newURI(dataURL)
|
||||
)
|
||||
.catch(console.warn);
|
||||
);
|
||||
} catch (e) {
|
||||
// Even if error happens for favicon, continue the process.
|
||||
console.warn(e);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,15 +129,11 @@ export class FaviconFeed {
|
||||
const redirectedUri = Services.io.newURI(lastVisit.url);
|
||||
const iconInfo = await this.getFaviconInfo(redirectedUri);
|
||||
if (iconInfo?.faviconSize >= MIN_FAVICON_SIZE) {
|
||||
try {
|
||||
lazy.PlacesUtils.favicons.copyFavicons(
|
||||
redirectedUri,
|
||||
Services.io.newURI(url),
|
||||
lazy.PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE
|
||||
);
|
||||
} catch (ex) {
|
||||
console.error(`Failed to copy favicon [${ex}]`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -200,9 +196,11 @@ export class FaviconFeed {
|
||||
try {
|
||||
// If the given faviconURI is data URL, set it as is.
|
||||
if (faviconURI.schemeIs("data")) {
|
||||
lazy.PlacesUtils.favicons
|
||||
.setFaviconForPage(pageURI, faviconURI, faviconURI)
|
||||
.catch(console.error);
|
||||
lazy.PlacesUtils.favicons.setFaviconForPage(
|
||||
pageURI,
|
||||
faviconURI,
|
||||
faviconURI
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -215,13 +213,11 @@ export class FaviconFeed {
|
||||
}
|
||||
|
||||
// Otherwise, fetch from network.
|
||||
lazy.PlacesUtils.favicons
|
||||
.setFaviconForPage(
|
||||
lazy.PlacesUtils.favicons.setFaviconForPage(
|
||||
pageURI,
|
||||
faviconURI,
|
||||
await this.getFaviconDataURLFromNetwork(faviconURI)
|
||||
)
|
||||
.catch(console.error);
|
||||
);
|
||||
} catch (ex) {
|
||||
console.error(`Failed to set favicon for page:${ex}`);
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ add_task(async function test_fetchIcon_with_valid_favicon() {
|
||||
.resolves({ domain: TEST_DOMAIN, image_url: TEST_FAVICON_URL.spec });
|
||||
|
||||
info("Setup valid favicon data in DB");
|
||||
await PlacesUtils.favicons.setFaviconForPage(
|
||||
PlacesUtils.favicons.setFaviconForPage(
|
||||
TEST_PAGE_URL,
|
||||
TEST_FAVICON_URL,
|
||||
TEST_SVG_DATA_URL
|
||||
@@ -166,7 +166,7 @@ add_task(async function test_fetchIconFromRedirects_with_valid_favicon() {
|
||||
]);
|
||||
|
||||
info("Setup valid favicon data in DB");
|
||||
await PlacesUtils.favicons.setFaviconForPage(
|
||||
PlacesUtils.favicons.setFaviconForPage(
|
||||
TEST_PAGE_URL,
|
||||
TEST_FAVICON_URL,
|
||||
TEST_SVG_DATA_URL
|
||||
|
||||
@@ -41,8 +41,7 @@ add_task(async function () {
|
||||
parentGuid: PlacesUtils.bookmarks.toolbarGuid,
|
||||
});
|
||||
registerCleanupFunction(async function () {
|
||||
await PlacesUtils.bookmarks.eraseEverything();
|
||||
await PlacesUtils.history.clear();
|
||||
await PlacesUtils.bookmarks.remove(bm);
|
||||
});
|
||||
|
||||
// The icon is read asynchronously from the network, we don't have an easy way
|
||||
@@ -60,7 +59,15 @@ add_task(async function () {
|
||||
info("Sidebar: " + sidebarShot1);
|
||||
|
||||
let dataURL = await PlacesTestUtils.getFaviconDataURLFromNetwork(ICON_URI);
|
||||
await PlacesTestUtils.setFaviconForPage(PAGE_URI, ICON_URI, dataURL);
|
||||
await new Promise(resolve => {
|
||||
PlacesUtils.favicons.setFaviconForPage(
|
||||
PAGE_URI,
|
||||
ICON_URI,
|
||||
dataURL,
|
||||
null,
|
||||
resolve
|
||||
);
|
||||
});
|
||||
let dataURLInDB = await PlacesTestUtils.getFaviconDataURLFromDB(ICON_URI);
|
||||
Assert.ok(dataURLInDB.equals(dataURL), "Succesfully set the icon");
|
||||
|
||||
|
||||
@@ -827,7 +827,7 @@ BookmarkImporter.prototype = {
|
||||
bookmark => bookmark.type == PlacesUtils.bookmarks.TYPE_BOOKMARK
|
||||
).length;
|
||||
|
||||
insertFaviconsForTree(tree);
|
||||
insertFaviconsForTree(tree).catch(console.warn);
|
||||
}
|
||||
return bookmarkCount;
|
||||
},
|
||||
@@ -1080,7 +1080,7 @@ BookmarkExporter.prototype = {
|
||||
*
|
||||
* @param {Object} node The bookmark node for icons to be inserted.
|
||||
*/
|
||||
function insertFaviconForNode(node) {
|
||||
async function insertFaviconForNode(node) {
|
||||
if (!node.icon && !node.iconUri) {
|
||||
// No favicon information.
|
||||
return;
|
||||
@@ -1093,14 +1093,19 @@ function insertFaviconForNode(node) {
|
||||
return;
|
||||
}
|
||||
|
||||
PlacesUtils.favicons
|
||||
.setFaviconForPage(
|
||||
let result = await new Promise(resolve => {
|
||||
PlacesUtils.favicons.setFaviconForPage(
|
||||
Services.io.newURI(node.url),
|
||||
// Use iconUri otherwise create a fake favicon URI to use (FIXME: bug 523932)
|
||||
Services.io.newURI(node.iconUri ?? "fake-favicon-uri:" + node.url),
|
||||
faviconDataURI
|
||||
)
|
||||
.catch(console.error);
|
||||
faviconDataURI,
|
||||
null,
|
||||
resolve
|
||||
);
|
||||
});
|
||||
if (!Components.isSuccessCode(result)) {
|
||||
throw new Error("Failed to call setFaviconForPage():", node.url);
|
||||
}
|
||||
} catch (ex) {
|
||||
console.error("Failed to import favicon data:", ex);
|
||||
}
|
||||
@@ -1115,12 +1120,12 @@ function insertFaviconForNode(node) {
|
||||
*
|
||||
* @param {Object} nodeTree The bookmark node tree for icons to be inserted.
|
||||
*/
|
||||
function insertFaviconsForTree(nodeTree) {
|
||||
insertFaviconForNode(nodeTree);
|
||||
async function insertFaviconsForTree(nodeTree) {
|
||||
await insertFaviconForNode(nodeTree);
|
||||
|
||||
if (nodeTree.children) {
|
||||
for (let child of nodeTree.children) {
|
||||
insertFaviconsForTree(child);
|
||||
await insertFaviconsForTree(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -291,7 +291,7 @@ BookmarkImporter.prototype = {
|
||||
).length;
|
||||
|
||||
// Now add any favicons.
|
||||
insertFaviconsForTree(node);
|
||||
insertFaviconsForTree(node).catch(console.warn);
|
||||
}
|
||||
return bookmarkCount;
|
||||
},
|
||||
@@ -498,7 +498,7 @@ function translateTreeTypes(node) {
|
||||
*
|
||||
* @param {Object} node The bookmark node for icons to be inserted.
|
||||
*/
|
||||
function insertFaviconForNode(node) {
|
||||
async function insertFaviconForNode(node) {
|
||||
if (!node.icon && !node.iconUri) {
|
||||
// No favicon information.
|
||||
return;
|
||||
@@ -511,14 +511,19 @@ function insertFaviconForNode(node) {
|
||||
return;
|
||||
}
|
||||
|
||||
PlacesUtils.favicons
|
||||
.setFaviconForPage(
|
||||
let result = await new Promise(resolve => {
|
||||
PlacesUtils.favicons.setFaviconForPage(
|
||||
Services.io.newURI(node.url),
|
||||
// Use iconUri otherwise create a fake favicon URI to use (FIXME: bug 523932)
|
||||
Services.io.newURI(node.iconUri ?? "fake-favicon-uri:" + node.url),
|
||||
faviconDataURI
|
||||
)
|
||||
.catch(console.error);
|
||||
faviconDataURI,
|
||||
null,
|
||||
resolve
|
||||
);
|
||||
});
|
||||
if (!Components.isSuccessCode(result)) {
|
||||
throw new Error("Failed to call setFaviconForPage():", node.url);
|
||||
}
|
||||
} catch (ex) {
|
||||
console.error("Failed to import favicon data:", ex);
|
||||
}
|
||||
@@ -533,12 +538,12 @@ function insertFaviconForNode(node) {
|
||||
*
|
||||
* @param {Object} nodeTree The bookmark node tree for icons to be inserted.
|
||||
*/
|
||||
function insertFaviconsForTree(nodeTree) {
|
||||
insertFaviconForNode(nodeTree);
|
||||
async function insertFaviconsForTree(nodeTree) {
|
||||
await insertFaviconForNode(nodeTree);
|
||||
|
||||
if (nodeTree.children) {
|
||||
for (let child of nodeTree.children) {
|
||||
insertFaviconsForTree(child);
|
||||
await insertFaviconsForTree(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -649,10 +649,10 @@ AsyncAssociateIconToPage::Run() {
|
||||
|
||||
AsyncSetIconForPage::AsyncSetIconForPage(const IconData& aIcon,
|
||||
const PageData& aPage,
|
||||
dom::Promise* aPromise)
|
||||
PlacesCompletionCallback* aCallback)
|
||||
: Runnable("places::AsyncSetIconForPage"),
|
||||
mPromise(new nsMainThreadPtrHolder<dom::Promise>(
|
||||
"AsyncSetIconForPage::Promise", aPromise, false)),
|
||||
mCallback(new nsMainThreadPtrHolder<PlacesCompletionCallback>(
|
||||
"AsyncSetIconForPage::mCallback", aCallback, false)),
|
||||
mIcon(aIcon),
|
||||
mPage(aPage) {}
|
||||
|
||||
@@ -665,14 +665,13 @@ AsyncSetIconForPage::Run() {
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
auto guard = MakeScopeExit([&]() {
|
||||
NS_DispatchToMainThread(NS_NewRunnableFunction(
|
||||
"AsyncSetIconForPage::Promise", [rv, promise = std::move(mPromise)]() {
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
promise->MaybeResolveWithUndefined();
|
||||
} else {
|
||||
promise->MaybeReject(rv);
|
||||
}
|
||||
if (mCallback) {
|
||||
NS_DispatchToMainThread(
|
||||
NS_NewRunnableFunction("AsyncSetIconForPage::Callback",
|
||||
[rv, callback = std::move(mCallback)]() {
|
||||
(void)callback->Complete(rv);
|
||||
}));
|
||||
}
|
||||
});
|
||||
|
||||
// Fetch the page data.
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsProxyRelease.h"
|
||||
#include "imgLoader.h"
|
||||
#include "PlacesCompletionCallback.h"
|
||||
|
||||
class nsIPrincipal;
|
||||
|
||||
@@ -147,14 +148,14 @@ class AsyncSetIconForPage final : public Runnable {
|
||||
* Icon to be associated.
|
||||
* @param aPage
|
||||
* Page to which associate the icon.
|
||||
* @param aPromise
|
||||
* Promise that returns the result.
|
||||
* @param aCallback
|
||||
* Function to be called when the associate process finishes.
|
||||
*/
|
||||
AsyncSetIconForPage(const IconData& aIcon, const PageData& aPage,
|
||||
dom::Promise* aPromise);
|
||||
PlacesCompletionCallback* aCallback);
|
||||
|
||||
private:
|
||||
nsMainThreadPtrHandle<dom::Promise> mPromise;
|
||||
nsMainThreadPtrHandle<PlacesCompletionCallback> mCallback;
|
||||
IconData mIcon;
|
||||
PageData mPage;
|
||||
};
|
||||
|
||||
19
toolkit/components/places/PlacesCompletionCallback.idl
Normal file
19
toolkit/components/places/PlacesCompletionCallback.idl
Normal file
@@ -0,0 +1,19 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ :
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
[scriptable, function, uuid(ea26627b-d21a-4f97-b2d0-f8df7be24808)]
|
||||
interface PlacesCompletionCallback : nsISupports {
|
||||
/**
|
||||
* Indicates that the event this callback was passed in for has completed.
|
||||
*
|
||||
* @param status
|
||||
* The status of the call. Generally NS_OK if the operation
|
||||
* completed successfully.
|
||||
*/
|
||||
void complete(in nsresult status);
|
||||
};
|
||||
@@ -23,6 +23,7 @@ if CONFIG["MOZ_PLACES"]:
|
||||
"nsINavBookmarksService.idl",
|
||||
"nsIPlacesPreviewsHelperService.idl",
|
||||
"nsITaggingService.idl",
|
||||
"PlacesCompletionCallback.idl",
|
||||
]
|
||||
|
||||
EXPORTS.mozilla.places = [
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
*/
|
||||
|
||||
#include "nsFaviconService.h"
|
||||
#include "PlacesCompletionCallback.h"
|
||||
|
||||
#include "nsNavHistory.h"
|
||||
#include "nsPlacesMacros.h"
|
||||
@@ -223,41 +224,24 @@ void nsFaviconService::ClearImageCache(nsIURI* aImageURI) {
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFaviconService::SetFaviconForPage(nsIURI* aPageURI, nsIURI* aFaviconURI,
|
||||
nsIURI* aDataURL, PRTime aExpiration = 0,
|
||||
bool isRichIcon = false,
|
||||
JSContext* aContext = nullptr,
|
||||
Promise** aPromise = nullptr) {
|
||||
nsFaviconService::SetFaviconForPage(
|
||||
nsIURI* aPageURI, nsIURI* aFaviconURI, nsIURI* aDataURL,
|
||||
PRTime aExpiration = 0, PlacesCompletionCallback* aCallback = nullptr,
|
||||
bool isRichIcon = false) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
NS_ENSURE_ARG(aPageURI);
|
||||
NS_ENSURE_ARG(aFaviconURI);
|
||||
NS_ENSURE_ARG(aDataURL);
|
||||
|
||||
MOZ_DIAGNOSTIC_ASSERT(aDataURL->SchemeIs("data"));
|
||||
|
||||
ErrorResult result;
|
||||
RefPtr<Promise> promise =
|
||||
Promise::Create(xpc::CurrentNativeGlobal(aContext), result);
|
||||
if (NS_WARN_IF(result.Failed())) {
|
||||
return result.StealNSResult();
|
||||
}
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
auto guard = MakeScopeExit([&]() {
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
promise->MaybeResolveWithUndefined();
|
||||
promise.forget(aPromise);
|
||||
}
|
||||
});
|
||||
|
||||
if (!aDataURL->SchemeIs("data")) {
|
||||
return (rv = NS_ERROR_INVALID_ARG);
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
NS_ENSURE_ARG(canStoreIconForPage(aPageURI));
|
||||
|
||||
if (AppShutdown::IsInOrBeyond(ShutdownPhase::AppShutdownConfirmed)) {
|
||||
return (rv = NS_OK);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRTime now = PR_Now();
|
||||
@@ -266,6 +250,14 @@ nsFaviconService::SetFaviconForPage(nsIURI* aPageURI, nsIURI* aFaviconURI,
|
||||
aExpiration = now + MAX_FAVICON_EXPIRATION;
|
||||
}
|
||||
|
||||
// Use the data: protocol handler to convert the data.
|
||||
nsresult rv = NS_OK;
|
||||
auto guard = MakeScopeExit([&]() {
|
||||
if (aCallback) {
|
||||
aCallback->Complete(rv);
|
||||
}
|
||||
});
|
||||
|
||||
nsCOMPtr<nsIIOService> ioService = do_GetIOService(&rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsCOMPtr<nsIProtocolHandler> protocolHandler;
|
||||
@@ -403,7 +395,7 @@ nsFaviconService::SetFaviconForPage(nsIURI* aPageURI, nsIURI* aFaviconURI,
|
||||
}
|
||||
|
||||
RefPtr<AsyncSetIconForPage> event =
|
||||
new AsyncSetIconForPage(icon, page, promise);
|
||||
new AsyncSetIconForPage(icon, page, aCallback);
|
||||
RefPtr<Database> DB = Database::GetDatabase();
|
||||
if (MOZ_UNLIKELY(!DB)) {
|
||||
return (rv = NS_ERROR_UNEXPECTED);
|
||||
@@ -412,7 +404,6 @@ nsFaviconService::SetFaviconForPage(nsIURI* aPageURI, nsIURI* aFaviconURI,
|
||||
DB->DispatchToAsyncThread(event);
|
||||
|
||||
guard.release();
|
||||
promise.forget(aPromise);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ interface nsIURI;
|
||||
interface nsIPrincipal;
|
||||
interface mozIPlacesPendingOperation;
|
||||
interface nsIFaviconDataCallback;
|
||||
interface PlacesCompletionCallback;
|
||||
|
||||
[scriptable, uuid(e81e0b0c-b9f1-4c2e-8f3c-b809933cf73c)]
|
||||
interface nsIFaviconService : nsISupports
|
||||
@@ -105,18 +106,21 @@ interface nsIFaviconService : nsISupports
|
||||
* Until this time, we won't try to load it again.
|
||||
* If this argument is omitted, the expiration defaults to
|
||||
* 7 days (FaviconHelpers::MAX_FAVICON_EXPIRATION) from now.
|
||||
*
|
||||
* @return Promise that is resolved/rejected when finishing the process.
|
||||
* @param [optional] aCallback
|
||||
* Once we're done setting and/or fetching the favicon, we invoke this
|
||||
* callback.
|
||||
*
|
||||
* @throws NS_ERROR_FILE_TOO_BIG if the icon is excessively large and can not
|
||||
* be optimized internally.
|
||||
*
|
||||
* @see PlacesCompletionCallback in PlacesCompletionCallback.idl.
|
||||
*/
|
||||
[implicit_jscontext, must_use]
|
||||
Promise setFaviconForPage(
|
||||
void setFaviconForPage(
|
||||
in nsIURI aPageURI,
|
||||
in nsIURI aFaviconURI,
|
||||
in nsIURI aDataURL,
|
||||
[optional] in PRTime aExpiration,
|
||||
[optional] in PlacesCompletionCallback aCallback,
|
||||
[optional] in boolean isRichIcon
|
||||
);
|
||||
|
||||
|
||||
@@ -143,7 +143,19 @@ export var PlacesTestUtils = Object.freeze({
|
||||
}
|
||||
|
||||
faviconPromises.push(
|
||||
lazy.PlacesUtils.favicons.setFaviconForPage(uri, faviconURI, faviconURI)
|
||||
new Promise((resolve, reject) => {
|
||||
try {
|
||||
lazy.PlacesUtils.favicons.setFaviconForPage(
|
||||
uri,
|
||||
faviconURI,
|
||||
faviconURI,
|
||||
null,
|
||||
resolve
|
||||
);
|
||||
} catch (ex) {
|
||||
reject(ex);
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
await Promise.all(faviconPromises);
|
||||
@@ -167,7 +179,8 @@ export var PlacesTestUtils = Object.freeze({
|
||||
expiration = 0,
|
||||
isRichIcon = false
|
||||
) {
|
||||
return lazy.PlacesUtils.favicons.setFaviconForPage(
|
||||
return new Promise((resolve, reject) => {
|
||||
lazy.PlacesUtils.favicons.setFaviconForPage(
|
||||
pageURI instanceof Ci.nsIURI ? pageURI : Services.io.newURI(pageURI),
|
||||
faviconURI instanceof Ci.nsIURI
|
||||
? faviconURI
|
||||
@@ -176,8 +189,20 @@ export var PlacesTestUtils = Object.freeze({
|
||||
? faviconDataURL
|
||||
: Services.io.newURI(faviconDataURL),
|
||||
expiration,
|
||||
status => {
|
||||
if (Components.isSuccessCode(status)) {
|
||||
resolve(status);
|
||||
} else {
|
||||
reject(
|
||||
new Error(
|
||||
`Failed to process setFaviconForPage(): status code = ${status}`
|
||||
)
|
||||
);
|
||||
}
|
||||
},
|
||||
isRichIcon
|
||||
);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,11 +16,7 @@ add_setup(() => {
|
||||
add_task(async function test_storing_a_normal_16x16_icon() {
|
||||
const PAGE_URL = Services.io.newURI("http://places.test");
|
||||
await PlacesTestUtils.addVisits(PAGE_URL);
|
||||
await PlacesUtils.favicons.setFaviconForPage(
|
||||
PAGE_URL,
|
||||
SMALLPNG_DATA_URI,
|
||||
SMALLPNG_DATA_URI
|
||||
);
|
||||
await setFavicon(PAGE_URL, SMALLPNG_DATA_URI);
|
||||
|
||||
// Now set expiration to 0 and change the payload.
|
||||
info("Set expiration to 0 and replace favicon data");
|
||||
@@ -36,10 +32,18 @@ add_task(async function test_storing_a_normal_16x16_icon() {
|
||||
);
|
||||
|
||||
info("Refresh favicon");
|
||||
await PlacesUtils.favicons.setFaviconForPage(
|
||||
PAGE_URL,
|
||||
SMALLPNG_DATA_URI,
|
||||
SMALLPNG_DATA_URI
|
||||
);
|
||||
await setFavicon(PAGE_URL, SMALLPNG_DATA_URI);
|
||||
await compareFavicons("page-icon:" + PAGE_URL.spec, SMALLPNG_DATA_URI);
|
||||
});
|
||||
|
||||
async function setFavicon(pageURL, faviconDataURL) {
|
||||
await new Promise(resolve => {
|
||||
PlacesUtils.favicons.setFaviconForPage(
|
||||
pageURL,
|
||||
faviconDataURL,
|
||||
faviconDataURL,
|
||||
null,
|
||||
resolve
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -19,7 +19,15 @@ add_task(async function test_normal() {
|
||||
|
||||
await PlacesTestUtils.addVisits(pageURI);
|
||||
|
||||
await PlacesUtils.favicons.setFaviconForPage(pageURI, FAVICON_URI, dataURL);
|
||||
await new Promise(resolve => {
|
||||
PlacesUtils.favicons.setFaviconForPage(
|
||||
pageURI,
|
||||
FAVICON_URI,
|
||||
dataURL,
|
||||
null,
|
||||
resolve
|
||||
);
|
||||
});
|
||||
|
||||
await new Promise(resolve => {
|
||||
PlacesUtils.favicons.getFaviconDataForPage(
|
||||
|
||||
@@ -7,11 +7,16 @@ add_task(async function test_normal() {
|
||||
let pageURI = NetUtil.newURI("http://example.com/normal");
|
||||
|
||||
await PlacesTestUtils.addVisits(pageURI);
|
||||
await PlacesTestUtils.setFaviconForPage(
|
||||
|
||||
await new Promise(resolve => {
|
||||
PlacesUtils.favicons.setFaviconForPage(
|
||||
pageURI,
|
||||
SMALLPNG_DATA_URI,
|
||||
SMALLPNG_DATA_URI
|
||||
SMALLPNG_DATA_URI,
|
||||
null,
|
||||
resolve
|
||||
);
|
||||
});
|
||||
|
||||
await new Promise(resolve => {
|
||||
PlacesUtils.favicons.getFaviconDataForPage(
|
||||
|
||||
@@ -94,11 +94,15 @@ add_task(async function test_twiceReplace() {
|
||||
let secondFavicon = await createFavicon("favicon10.png");
|
||||
|
||||
let firstFaviconDataURL = await createDataURLForFavicon(firstFavicon);
|
||||
await PlacesUtils.favicons.setFaviconForPage(
|
||||
await new Promise(resolve => {
|
||||
PlacesUtils.favicons.setFaviconForPage(
|
||||
pageURI,
|
||||
firstFavicon.uri,
|
||||
firstFaviconDataURL
|
||||
firstFaviconDataURL,
|
||||
null,
|
||||
resolve
|
||||
);
|
||||
});
|
||||
|
||||
await doTestSetFaviconForPage({
|
||||
pageURI,
|
||||
@@ -153,35 +157,17 @@ add_task(async function test_invalidPageURI() {
|
||||
await PlacesTestUtils.addVisits(uri("http://example.com/"));
|
||||
let favicon = await createFavicon("favicon-invalidPageURI.png");
|
||||
|
||||
const TEST_DATA = [
|
||||
{
|
||||
pageURI: null,
|
||||
expected: "NS_ERROR_ILLEGAL_VALUE",
|
||||
},
|
||||
{
|
||||
pageURI: "",
|
||||
expected: "NS_ERROR_XPC_BAD_CONVERT_JS",
|
||||
},
|
||||
{
|
||||
pageURI: "http://example.com",
|
||||
expected: "NS_ERROR_XPC_BAD_CONVERT_JS",
|
||||
},
|
||||
];
|
||||
for (let { pageURI, expected } of TEST_DATA) {
|
||||
for (let invalidURI of [null, "", "http://example.com"]) {
|
||||
try {
|
||||
info(`Invalid page URI test for [${pageURI}]`);
|
||||
await PlacesUtils.favicons.setFaviconForPage(
|
||||
pageURI,
|
||||
info(`Invalid page URI test for [${invalidURI}]`);
|
||||
PlacesUtils.favicons.setFaviconForPage(
|
||||
invalidURI,
|
||||
favicon.uri,
|
||||
await createDataURLForFavicon(favicon)
|
||||
);
|
||||
Assert.ok(false, "Error should happened");
|
||||
} catch (e) {
|
||||
Assert.equal(
|
||||
e.name,
|
||||
expected,
|
||||
`Expected error happened for [${pageURI}]`
|
||||
);
|
||||
Assert.ok(true, `Expected error happend [${e.message}]`);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -191,36 +177,17 @@ add_task(async function test_invalidFaviconURI() {
|
||||
await PlacesTestUtils.addVisits(pageURI);
|
||||
let favicon = await createFavicon("favicon-invalidFaviconURI.png");
|
||||
|
||||
const TEST_DATA = [
|
||||
{
|
||||
faviconURI: null,
|
||||
expected: "NS_ERROR_ILLEGAL_VALUE",
|
||||
},
|
||||
{
|
||||
faviconURI: "",
|
||||
expected: "NS_ERROR_XPC_BAD_CONVERT_JS",
|
||||
},
|
||||
{
|
||||
faviconURI: "favicon.uri.spec",
|
||||
expected: "NS_ERROR_XPC_BAD_CONVERT_JS",
|
||||
},
|
||||
];
|
||||
|
||||
for (let { faviconURI, expected } of TEST_DATA) {
|
||||
for (let invalidURI of [null, "", favicon.uri.spec]) {
|
||||
try {
|
||||
info(`Invalid favicon URI test for [${faviconURI}]`);
|
||||
await PlacesUtils.favicons.setFaviconForPage(
|
||||
info(`Invalid favicon URI test for [${invalidURI}]`);
|
||||
PlacesUtils.favicons.setFaviconForPage(
|
||||
pageURI,
|
||||
faviconURI,
|
||||
invalidURI,
|
||||
await createDataURLForFavicon(favicon)
|
||||
);
|
||||
Assert.ok(false, "Error should happened");
|
||||
} catch (e) {
|
||||
Assert.equal(
|
||||
e.name,
|
||||
expected,
|
||||
`Expected error happened for [${faviconURI}]`
|
||||
);
|
||||
Assert.ok(true, `Expected error happend [${e.message}]`);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -230,67 +197,23 @@ add_task(async function test_invalidFaviconDataURI() {
|
||||
await PlacesTestUtils.addVisits(pageURI);
|
||||
let faviconURI = uri("http://example.com/favicon.svg");
|
||||
|
||||
const TEST_DATA = [
|
||||
{
|
||||
faviconDataURI: null,
|
||||
expected: "NS_ERROR_ILLEGAL_VALUE",
|
||||
},
|
||||
{
|
||||
faviconDataURI: "",
|
||||
expected: "NS_ERROR_XPC_BAD_CONVERT_JS",
|
||||
},
|
||||
{
|
||||
faviconDataURI: "data:text/plain;base64,SGVsbG8sIFdvcmxkIQ==",
|
||||
expected: "NS_ERROR_XPC_BAD_CONVERT_JS",
|
||||
},
|
||||
{
|
||||
for (let invalidURI of [
|
||||
null,
|
||||
"",
|
||||
"data:text/plain;base64,SGVsbG8sIFdvcmxkIQ==",
|
||||
// nsIFaviconService::MAX_FAVICON_BUFFER_SIZE = 65536
|
||||
faviconDataURI: uri(
|
||||
`data:image/svg+xml;utf8,<svg><text>${Array(65536)}</text></svg>`
|
||||
),
|
||||
expected: "NS_ERROR_FILE_TOO_BIG",
|
||||
},
|
||||
];
|
||||
|
||||
for (let { faviconDataURI, expected } of TEST_DATA) {
|
||||
uri(`data:image/svg+xml;utf8,<svg><text>${Array(65536)}</text></svg>`),
|
||||
]) {
|
||||
try {
|
||||
info(`Invalid favicon data URI test for [${faviconDataURI}]`);
|
||||
await PlacesUtils.favicons.setFaviconForPage(
|
||||
pageURI,
|
||||
faviconURI,
|
||||
faviconDataURI
|
||||
);
|
||||
info(`Invalid favicon data URI test for [${invalidURI}]`);
|
||||
PlacesUtils.favicons.setFaviconForPage(pageURI, faviconURI, invalidURI);
|
||||
Assert.ok(false, "Error should happened");
|
||||
} catch (e) {
|
||||
Assert.equal(
|
||||
e.name,
|
||||
expected,
|
||||
`Expected error happened for [${faviconDataURI}]`
|
||||
);
|
||||
Assert.ok(true, `Expected error happend [${e.message}]`);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Error handled by this test will fire from AsyncSetIconForPage Runnable.
|
||||
add_task(async function test_noVisitData() {
|
||||
let pageURI = uri("http://test1.bar/");
|
||||
let favicon = await createFavicon("favicon1.png");
|
||||
|
||||
try {
|
||||
await PlacesUtils.favicons.setFaviconForPage(
|
||||
pageURI,
|
||||
favicon.uri,
|
||||
await createDataURLForFavicon(favicon)
|
||||
);
|
||||
Assert.ok(false, "Error should happened");
|
||||
} catch (e) {
|
||||
Assert.equal(e.name, "NS_ERROR_NOT_AVAILABLE", "Expected error happened");
|
||||
}
|
||||
|
||||
await IOUtils.remove(favicon.file.path);
|
||||
await PlacesUtils.history.clear();
|
||||
});
|
||||
|
||||
add_task(async function test_sameHostRedirect() {
|
||||
// Add a bookmarked page that redirects to another page, set a favicon on the
|
||||
// latter and check the former gets it too, if they are in the same host.
|
||||
@@ -313,7 +236,7 @@ add_task(async function test_sameHostRedirect() {
|
||||
events.some(e => e.url == srcUrl && e.faviconUrl == SMALLPNG_DATA_URI.spec)
|
||||
);
|
||||
|
||||
await PlacesUtils.favicons.setFaviconForPage(
|
||||
PlacesUtils.favicons.setFaviconForPage(
|
||||
Services.io.newURI(destUrl),
|
||||
SMALLPNG_DATA_URI,
|
||||
SMALLPNG_DATA_URI
|
||||
@@ -374,14 +297,18 @@ async function doTestSetFaviconForPage({
|
||||
expectedFaviconData,
|
||||
expectedFaviconMimeType,
|
||||
}) {
|
||||
let result = await PlacesUtils.favicons.setFaviconForPage(
|
||||
let result = await new Promise(resolve => {
|
||||
PlacesUtils.favicons.setFaviconForPage(
|
||||
pageURI,
|
||||
faviconURI,
|
||||
dataURL
|
||||
dataURL,
|
||||
null,
|
||||
resolve
|
||||
);
|
||||
});
|
||||
|
||||
info("Check the result of setFaviconForPage");
|
||||
Assert.equal(result, null, "If succeeded, the promise has no data");
|
||||
Assert.equal(result, 0);
|
||||
|
||||
await new Promise(resolve => {
|
||||
checkFaviconDataForPage(
|
||||
@@ -423,9 +350,8 @@ add_task(async function test_pageURIProtocols() {
|
||||
"https://example.com/",
|
||||
];
|
||||
for (let pageURI of invalidPageURIs) {
|
||||
await PlacesTestUtils.addBookmarkWithDetails({ uri: pageURI });
|
||||
try {
|
||||
await PlacesUtils.favicons.setFaviconForPage(
|
||||
PlacesUtils.favicons.setFaviconForPage(
|
||||
uri(pageURI),
|
||||
favicon.uri,
|
||||
await createDataURLForFavicon(favicon)
|
||||
@@ -434,12 +360,10 @@ add_task(async function test_pageURIProtocols() {
|
||||
} catch (e) {
|
||||
Assert.ok(true, `Expected error [${e.message}]`);
|
||||
}
|
||||
await PlacesUtils.bookmarks.eraseEverything();
|
||||
}
|
||||
for (let pageURI of validPageURIs) {
|
||||
await PlacesTestUtils.addBookmarkWithDetails({ uri: pageURI });
|
||||
try {
|
||||
await PlacesUtils.favicons.setFaviconForPage(
|
||||
PlacesUtils.favicons.setFaviconForPage(
|
||||
uri(pageURI),
|
||||
favicon.uri,
|
||||
await createDataURLForFavicon(favicon)
|
||||
@@ -448,6 +372,5 @@ add_task(async function test_pageURIProtocols() {
|
||||
} catch (e) {
|
||||
Assert.ok(false, `Unexpected error [${e.message}]`);
|
||||
}
|
||||
await PlacesUtils.bookmarks.eraseEverything();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -8,11 +8,15 @@ add_task(async function () {
|
||||
visitDate: Date.now() * 1000,
|
||||
});
|
||||
|
||||
await PlacesUtils.favicons.setFaviconForPage(
|
||||
await new Promise(resolve => {
|
||||
PlacesUtils.favicons.setFaviconForPage(
|
||||
PAGEURI,
|
||||
SMALLSVG_DATA_URI,
|
||||
SMALLSVG_DATA_URI
|
||||
SMALLSVG_DATA_URI,
|
||||
null,
|
||||
resolve
|
||||
);
|
||||
});
|
||||
|
||||
await new Promise(resolve => {
|
||||
PlacesUtils.favicons.getFaviconDataForPage(
|
||||
|
||||
@@ -758,7 +758,15 @@ async function setFaviconForPage(page, icon, forceReload = true) {
|
||||
dataURL = await PlacesTestUtils.getFaviconDataURLFromNetwork(iconURI);
|
||||
}
|
||||
|
||||
await PlacesUtils.favicons.setFaviconForPage(pageURI, iconURI, dataURL);
|
||||
await new Promise(resolve => {
|
||||
PlacesUtils.favicons.setFaviconForPage(
|
||||
pageURI,
|
||||
iconURI,
|
||||
dataURL,
|
||||
null,
|
||||
resolve
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
function getFaviconUrlForPage(page, width = 0) {
|
||||
|
||||
@@ -281,11 +281,16 @@ add_task(async function test_error_cases() {
|
||||
add_task(async function test_orphans() {
|
||||
let uri = NetUtil.newURI("http://moz.org/");
|
||||
await PlacesTestUtils.addVisits({ uri });
|
||||
await PlacesTestUtils.setFaviconForPage(
|
||||
|
||||
await new Promise(resolve => {
|
||||
PlacesUtils.favicons.setFaviconForPage(
|
||||
uri,
|
||||
SMALLPNG_DATA_URI,
|
||||
SMALLPNG_DATA_URI
|
||||
SMALLPNG_DATA_URI,
|
||||
null,
|
||||
resolve
|
||||
);
|
||||
});
|
||||
|
||||
// Also create a root icon.
|
||||
let faviconURI = Services.io.newURI(uri.spec + "favicon.ico");
|
||||
|
||||
@@ -377,11 +377,16 @@ add_task(async function test_error_cases() {
|
||||
add_task(async function test_orphans() {
|
||||
let uri = NetUtil.newURI("http://moz.org/");
|
||||
await PlacesTestUtils.addVisits({ uri });
|
||||
await PlacesTestUtils.setFaviconForPage(
|
||||
|
||||
await new Promise(resolve => {
|
||||
PlacesUtils.favicons.setFaviconForPage(
|
||||
uri,
|
||||
SMALLPNG_DATA_URI,
|
||||
SMALLPNG_DATA_URI
|
||||
SMALLPNG_DATA_URI,
|
||||
null,
|
||||
resolve
|
||||
);
|
||||
});
|
||||
|
||||
await PlacesUtils.history.update({
|
||||
url: uri,
|
||||
|
||||
@@ -2610,11 +2610,15 @@ tests.push({
|
||||
});
|
||||
|
||||
PlacesUtils.tagging.tagURI(this._uri1, ["testtag"]);
|
||||
await PlacesUtils.favicons.setFaviconForPage(
|
||||
await new Promise(resolve => {
|
||||
PlacesUtils.favicons.setFaviconForPage(
|
||||
this._uri2,
|
||||
SMALLPNG_DATA_URI,
|
||||
SMALLPNG_DATA_URI
|
||||
SMALLPNG_DATA_URI,
|
||||
null,
|
||||
resolve
|
||||
);
|
||||
});
|
||||
await PlacesUtils.keywords.insert({
|
||||
url: this._uri1.spec,
|
||||
keyword: "testkeyword",
|
||||
|
||||
@@ -235,11 +235,15 @@ add_task(async function test_import_chromefavicon() {
|
||||
let dataURL = await PlacesTestUtils.getFaviconDataURLFromNetwork(
|
||||
CHROME_FAVICON_URI
|
||||
);
|
||||
await PlacesTestUtils.setFaviconForPage(
|
||||
await new Promise(resolve => {
|
||||
PlacesUtils.favicons.setFaviconForPage(
|
||||
PAGE_URI,
|
||||
CHROME_FAVICON_URI,
|
||||
dataURL
|
||||
dataURL,
|
||||
null,
|
||||
resolve
|
||||
);
|
||||
});
|
||||
|
||||
let data = await new Promise(resolve => {
|
||||
PlacesUtils.favicons.getFaviconDataForPage(
|
||||
@@ -267,11 +271,15 @@ add_task(async function test_import_chromefavicon() {
|
||||
let dataURL_2 = await PlacesTestUtils.getFaviconDataURLFromNetwork(
|
||||
CHROME_FAVICON_URI_2
|
||||
);
|
||||
await PlacesTestUtils.setFaviconForPage(
|
||||
await new Promise(resolve => {
|
||||
PlacesUtils.favicons.setFaviconForPage(
|
||||
PAGE_URI,
|
||||
CHROME_FAVICON_URI_2,
|
||||
dataURL_2
|
||||
dataURL_2,
|
||||
null,
|
||||
resolve
|
||||
);
|
||||
});
|
||||
|
||||
info("import from html");
|
||||
await PlacesUtils.bookmarks.eraseEverything();
|
||||
|
||||
@@ -68,12 +68,16 @@ add_setup(async () => {
|
||||
reader.readAsDataURL(blob);
|
||||
});
|
||||
|
||||
await PlacesUtils.favicons.setFaviconForPage(
|
||||
return new Promise(resolve => {
|
||||
PlacesUtils.favicons.setFaviconForPage(
|
||||
TEST_PAGE_URI,
|
||||
TEST_FAVICON_URI,
|
||||
Services.io.newURI(dataURL)
|
||||
Services.io.newURI(dataURL),
|
||||
undefined,
|
||||
resolve
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Test that we can populate the Windows Jump List favicon cache with a known
|
||||
|
||||
Reference in New Issue
Block a user