зеркало из https://github.com/mozilla/gecko-dev.git
Merge autoland to mozilla-central. a=merge
This commit is contained in:
Коммит
20a70f9169
|
@ -1282,11 +1282,7 @@ pref("browser.newtabpage.activity-stream.fxaccounts.endpoint", "https://accounts
|
|||
pref("browser.newtabpage.activity-stream.improvesearch.topSiteSearchShortcuts", true);
|
||||
|
||||
// ASRouter provider configuration
|
||||
#if defined(NIGHTLY_BUILD)
|
||||
pref("browser.newtabpage.activity-stream.asrouter.providers.cfr", "{\"id\":\"cfr\",\"enabled\":true,\"type\":\"local\",\"localProvider\":\"CFRMessageProvider\",\"frequency\":{\"custom\":[{\"period\":\"daily\",\"cap\":1}]}}");
|
||||
#else
|
||||
pref("browser.newtabpage.activity-stream.asrouter.providers.cfr", "{\"id\":\"cfr\",\"enabled\":false,\"type\":\"local\",\"localProvider\":\"CFRMessageProvider\",\"frequency\":{\"custom\":[{\"period\":\"daily\",\"cap\":1}]}}");
|
||||
#endif
|
||||
|
||||
#ifdef EARLY_BETA_OR_EARLIER
|
||||
pref("browser.newtabpage.activity-stream.asrouter.providers.snippets", "{\"id\":\"snippets\",\"enabled\":true,\"type\":\"remote\",\"url\":\"https://snippets.cdn.mozilla.net/%STARTPAGE_VERSION%/%NAME%/%VERSION%/%APPBUILDID%/%BUILD_TARGET%/%LOCALE%/%CHANNEL%/%OS_VERSION%/%DISTRIBUTION%/%DISTRIBUTION_VERSION%/\",\"updateCycleInMs\":14400000}");
|
||||
|
|
|
@ -14,6 +14,9 @@ XPCOMUtils.defineLazyModuleGetters(this, {
|
|||
UrlbarProvidersManager: "resource:///modules/UrlbarProvidersManager.jsm",
|
||||
});
|
||||
|
||||
const TELEMETRY_1ST_RESULT = "PLACES_AUTOCOMPLETE_1ST_RESULT_TIME_MS";
|
||||
const TELEMETRY_6_FIRST_RESULTS = "PLACES_AUTOCOMPLETE_6_FIRST_RESULTS_TIME_MS";
|
||||
|
||||
/**
|
||||
* The address bar controller handles queries from the address bar, obtains
|
||||
* results and returns them to the UI for display.
|
||||
|
@ -88,6 +91,10 @@ class UrlbarController {
|
|||
|
||||
queryContext.autoFill = UrlbarPrefs.get("autoFill");
|
||||
|
||||
queryContext.lastTelemetryResultCount = 0;
|
||||
TelemetryStopwatch.start(TELEMETRY_1ST_RESULT, queryContext);
|
||||
TelemetryStopwatch.start(TELEMETRY_6_FIRST_RESULTS, queryContext);
|
||||
|
||||
this._notify("onQueryStarted", queryContext);
|
||||
await this.manager.startQuery(queryContext, this);
|
||||
this._notify("onQueryFinished", queryContext);
|
||||
|
@ -103,6 +110,10 @@ class UrlbarController {
|
|||
if (queryContext === this._lastQueryContext) {
|
||||
delete this._lastQueryContext;
|
||||
}
|
||||
|
||||
TelemetryStopwatch.cancel(TELEMETRY_1ST_RESULT, queryContext);
|
||||
TelemetryStopwatch.cancel(TELEMETRY_6_FIRST_RESULTS, queryContext);
|
||||
|
||||
this.manager.cancelQuery(queryContext);
|
||||
this._notify("onQueryCancelled", queryContext);
|
||||
}
|
||||
|
@ -113,6 +124,16 @@ class UrlbarController {
|
|||
* @param {QueryContext} queryContext The query details.
|
||||
*/
|
||||
receiveResults(queryContext) {
|
||||
if (queryContext.lastTelemetryResultCount < 1 &&
|
||||
queryContext.results.length >= 1) {
|
||||
TelemetryStopwatch.finish(TELEMETRY_1ST_RESULT, queryContext);
|
||||
}
|
||||
if (queryContext.lastTelemetryResultCount < 6 &&
|
||||
queryContext.results.length >= 6) {
|
||||
TelemetryStopwatch.finish(TELEMETRY_6_FIRST_RESULTS, queryContext);
|
||||
}
|
||||
queryContext.lastTelemetryResultCount = queryContext.results.length;
|
||||
|
||||
this._notify("onQueryResults", queryContext);
|
||||
}
|
||||
|
||||
|
|
|
@ -96,6 +96,9 @@ class ProviderUnifiedComplete extends UrlbarProvider {
|
|||
// This is necessary because we insert matches one by one, thus we don't
|
||||
// want UnifiedComplete to reuse results.
|
||||
params.push(`insert-method:${UrlbarUtils.INSERTMETHOD.APPEND}`);
|
||||
// The Quantum Bar has its own telemetry measurement, thus disable old
|
||||
// telemetry logged by UnifiedComplete.
|
||||
params.push("disable-telemetry");
|
||||
if (queryContext.isPrivate) {
|
||||
params.push("private-window");
|
||||
if (!PrivateBrowsingUtils.permanentPrivateBrowsing) {
|
||||
|
|
|
@ -87,7 +87,7 @@ class TestProvider extends UrlbarProvider {
|
|||
constructor(matches, cancelCallback) {
|
||||
super();
|
||||
this._name = "TestProvider" + Math.floor(Math.random() * 100000);
|
||||
this._cancel = cancelCallback;
|
||||
this._cancelCallback = cancelCallback;
|
||||
this._matches = matches;
|
||||
}
|
||||
get name() {
|
||||
|
|
|
@ -61,12 +61,12 @@ add_task(async function test_basic_search() {
|
|||
});
|
||||
|
||||
add_task(async function test_cancel_search() {
|
||||
let providerCanceledPromise = PromiseUtils.defer();
|
||||
let providerName = registerBasicTestProvider([match], providerCanceledPromise.resolve);
|
||||
let providerCanceledDeferred = PromiseUtils.defer();
|
||||
let providerName = registerBasicTestProvider([match], providerCanceledDeferred.resolve);
|
||||
const context = createContext(TEST_URL, {providers: [providerName]});
|
||||
|
||||
let startedPromise = promiseControllerNotification(controller, "onQueryStarted");
|
||||
let cancelPromise = promiseControllerNotification(controller, "onQueryResults");
|
||||
let cancelPromise = promiseControllerNotification(controller, "onQueryCancelled");
|
||||
|
||||
await controller.startQuery(context);
|
||||
|
||||
|
@ -77,7 +77,7 @@ add_task(async function test_cancel_search() {
|
|||
Assert.equal(params[0], context);
|
||||
|
||||
info("Should tell the provider the query is canceled");
|
||||
await providerCanceledPromise;
|
||||
await providerCanceledDeferred.promise;
|
||||
|
||||
params = await cancelPromise;
|
||||
});
|
||||
|
|
|
@ -0,0 +1,193 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* These tests unit test the functionality of UrlbarController by stubbing out the
|
||||
* model and providing stubs to be called.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URL = "http://example.com";
|
||||
const MATCH = new UrlbarMatch(UrlbarUtils.MATCH_TYPE.TAB_SWITCH,
|
||||
UrlbarUtils.MATCH_SOURCE.TABS,
|
||||
{ url: TEST_URL });
|
||||
const TELEMETRY_1ST_RESULT = "PLACES_AUTOCOMPLETE_1ST_RESULT_TIME_MS";
|
||||
const TELEMETRY_6_FIRST_RESULTS = "PLACES_AUTOCOMPLETE_6_FIRST_RESULTS_TIME_MS";
|
||||
|
||||
let controller;
|
||||
let firstHistogram;
|
||||
let sixthHistogram;
|
||||
|
||||
/**
|
||||
* A delayed test provider, allowing the query to be delayed for an amount of time.
|
||||
*/
|
||||
class DelayedProvider extends UrlbarProvider {
|
||||
constructor() {
|
||||
super();
|
||||
this._name = "TestProvider" + Math.floor(Math.random() * 100000);
|
||||
}
|
||||
get name() {
|
||||
return this._name;
|
||||
}
|
||||
get type() {
|
||||
return UrlbarUtils.PROVIDER_TYPE.PROFILE;
|
||||
}
|
||||
get sources() {
|
||||
return [UrlbarUtils.MATCH_SOURCE.TABS];
|
||||
}
|
||||
async startQuery(context, add) {
|
||||
Assert.ok(context, "context is passed-in");
|
||||
Assert.equal(typeof add, "function", "add is a callback");
|
||||
this._context = context;
|
||||
this._add = add;
|
||||
}
|
||||
cancelQuery(context) {
|
||||
Assert.ok(false, "cancelQuery should not be called");
|
||||
}
|
||||
addResults(matches) {
|
||||
for (const match of matches) {
|
||||
this._add(this, match);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of reports sent recorded within the histogram results.
|
||||
*
|
||||
* @param {object} results a snapshot of histogram results to check.
|
||||
* @returns {number} The count of reports recorded in the histogram.
|
||||
*/
|
||||
function getHistogramReportsCount(results) {
|
||||
let sum = 0;
|
||||
for (let [, value] of Object.entries(results.values)) {
|
||||
sum += value;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
add_task(function setup() {
|
||||
controller = new UrlbarController({
|
||||
browserWindow: {
|
||||
location: {
|
||||
href: AppConstants.BROWSER_CHROME_URL,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
firstHistogram = Services.telemetry.getHistogramById(TELEMETRY_1ST_RESULT);
|
||||
sixthHistogram = Services.telemetry.getHistogramById(TELEMETRY_6_FIRST_RESULTS);
|
||||
});
|
||||
|
||||
add_task(async function test_n_autocomplete_cancel() {
|
||||
firstHistogram.clear();
|
||||
sixthHistogram.clear();
|
||||
|
||||
let providerCanceledDeferred = PromiseUtils.defer();
|
||||
let provider = new TestProvider([], providerCanceledDeferred.resolve);
|
||||
UrlbarProvidersManager.registerProvider(provider);
|
||||
const context = createContext(TEST_URL, {providers: [provider.name]});
|
||||
|
||||
Assert.ok(!TelemetryStopwatch.running(TELEMETRY_1ST_RESULT, context),
|
||||
"Should not have started first result stopwatch");
|
||||
Assert.ok(!TelemetryStopwatch.running(TELEMETRY_6_FIRST_RESULTS, context),
|
||||
"Should not have started first 6 results stopwatch");
|
||||
|
||||
await controller.startQuery(context);
|
||||
|
||||
Assert.ok(TelemetryStopwatch.running(TELEMETRY_1ST_RESULT, context),
|
||||
"Should have started first result stopwatch");
|
||||
Assert.ok(TelemetryStopwatch.running(TELEMETRY_6_FIRST_RESULTS, context),
|
||||
"Should have started first 6 results stopwatch");
|
||||
|
||||
controller.cancelQuery(context);
|
||||
|
||||
await providerCanceledDeferred.promise;
|
||||
|
||||
Assert.ok(!TelemetryStopwatch.running(TELEMETRY_1ST_RESULT, context),
|
||||
"Should have canceled first result stopwatch");
|
||||
Assert.ok(!TelemetryStopwatch.running(TELEMETRY_6_FIRST_RESULTS, context),
|
||||
"Should have canceled first 6 results stopwatch");
|
||||
|
||||
let results = firstHistogram.snapshot();
|
||||
Assert.equal(results.sum, 0, "Should not have recorded any times (first result)");
|
||||
results = sixthHistogram.snapshot();
|
||||
Assert.equal(results.sum, 0, "Should not have recorded any times (first 6 results)");
|
||||
});
|
||||
|
||||
add_task(async function test_n_autocomplete_results() {
|
||||
firstHistogram.clear();
|
||||
sixthHistogram.clear();
|
||||
|
||||
let provider = new DelayedProvider();
|
||||
UrlbarProvidersManager.registerProvider(provider);
|
||||
const context = createContext(TEST_URL, {providers: [provider.name]});
|
||||
|
||||
let resultsPromise = promiseControllerNotification(controller, "onQueryResults");
|
||||
|
||||
Assert.ok(!TelemetryStopwatch.running(TELEMETRY_1ST_RESULT, context),
|
||||
"Should not have started first result stopwatch");
|
||||
Assert.ok(!TelemetryStopwatch.running(TELEMETRY_6_FIRST_RESULTS, context),
|
||||
"Should not have started first 6 results stopwatch");
|
||||
|
||||
await controller.startQuery(context);
|
||||
|
||||
Assert.ok(TelemetryStopwatch.running(TELEMETRY_1ST_RESULT, context),
|
||||
"Should have started first result stopwatch");
|
||||
Assert.ok(TelemetryStopwatch.running(TELEMETRY_6_FIRST_RESULTS, context),
|
||||
"Should have started first 6 results stopwatch");
|
||||
|
||||
provider.addResults([MATCH]);
|
||||
await resultsPromise;
|
||||
|
||||
Assert.ok(!TelemetryStopwatch.running(TELEMETRY_1ST_RESULT, context),
|
||||
"Should have stopped the first stopwatch");
|
||||
Assert.ok(TelemetryStopwatch.running(TELEMETRY_6_FIRST_RESULTS, context),
|
||||
"Should have kept the first 6 results stopwatch running");
|
||||
|
||||
let firstResults = firstHistogram.snapshot();
|
||||
let first6Results = sixthHistogram.snapshot();
|
||||
Assert.equal(getHistogramReportsCount(firstResults), 1,
|
||||
"Should have recorded one time for the first result");
|
||||
Assert.equal(getHistogramReportsCount(first6Results), 0,
|
||||
"Should not have recorded any times (first 6 results)");
|
||||
|
||||
// Now add 5 more results, so that the first 6 results is triggered.
|
||||
for (let i = 0; i < 5; i++) {
|
||||
resultsPromise = promiseControllerNotification(controller, "onQueryResults");
|
||||
provider.addResults([
|
||||
new UrlbarMatch(UrlbarUtils.MATCH_TYPE.TAB_SWITCH,
|
||||
UrlbarUtils.MATCH_SOURCE.TABS,
|
||||
{ url: TEST_URL + "/i" }),
|
||||
]);
|
||||
await resultsPromise;
|
||||
}
|
||||
|
||||
Assert.ok(!TelemetryStopwatch.running(TELEMETRY_1ST_RESULT, context),
|
||||
"Should have stopped the first stopwatch");
|
||||
Assert.ok(!TelemetryStopwatch.running(TELEMETRY_6_FIRST_RESULTS, context),
|
||||
"Should have stopped the first 6 results stopwatch");
|
||||
|
||||
let updatedResults = firstHistogram.snapshot();
|
||||
let updated6Results = sixthHistogram.snapshot();
|
||||
Assert.deepEqual(updatedResults, firstResults,
|
||||
"Should not have changed the histogram for the first result");
|
||||
Assert.equal(getHistogramReportsCount(updated6Results), 1,
|
||||
"Should have recorded one time for the first 6 results");
|
||||
|
||||
// Add one more, to check neither are updated.
|
||||
resultsPromise = promiseControllerNotification(controller, "onQueryResults");
|
||||
provider.addResults([
|
||||
new UrlbarMatch(UrlbarUtils.MATCH_TYPE.TAB_SWITCH,
|
||||
UrlbarUtils.MATCH_SOURCE.TABS,
|
||||
{ url: TEST_URL + "/6" }),
|
||||
]);
|
||||
await resultsPromise;
|
||||
|
||||
let secondUpdateResults = firstHistogram.snapshot();
|
||||
let secondUpdate6Results = sixthHistogram.snapshot();
|
||||
Assert.deepEqual(secondUpdateResults, firstResults,
|
||||
"Should not have changed the histogram for the first result");
|
||||
Assert.equal(getHistogramReportsCount(secondUpdate6Results), 1,
|
||||
"Should not have changed the histogram for the first 6 results");
|
||||
});
|
|
@ -192,6 +192,7 @@ add_task(function test_cancel_query() {
|
|||
|
||||
add_task(function test_receiveResults() {
|
||||
const context = createContext();
|
||||
context.results = [];
|
||||
controller.receiveResults(context);
|
||||
|
||||
Assert.equal(generalListener.onQueryResults.callCount, 1,
|
||||
|
@ -204,6 +205,7 @@ add_task(function test_receiveResults() {
|
|||
|
||||
add_task(function test_autocomplete_enabled() {
|
||||
const context = createContext();
|
||||
context.results = [];
|
||||
controller.receiveResults(context);
|
||||
|
||||
Assert.equal(generalListener.onQueryResults.callCount, 1,
|
||||
|
@ -213,4 +215,3 @@ add_task(function test_autocomplete_enabled() {
|
|||
|
||||
sandbox.resetHistory();
|
||||
});
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ support-files =
|
|||
[test_QueryContext.js]
|
||||
[test_tokenizer.js]
|
||||
[test_UrlbarController_unit.js]
|
||||
[test_UrlbarController_telemetry.js]
|
||||
[test_UrlbarController_integration.js]
|
||||
[test_UrlbarUtils_addToUrlbarHistory.js]
|
||||
[test_UrlbarUtils_getShortcutOrURIAndPostData.js]
|
||||
|
|
|
@ -102,8 +102,8 @@ bool WrapResult(JSContext* aCx, JS::Handle<JSObject*> aProxy,
|
|||
if (!ToJSValue(aCx, WindowProxyHolder(aResult), &v)) {
|
||||
return false;
|
||||
}
|
||||
aDesc.object().set(aProxy);
|
||||
aDesc.setDataDescriptor(v, attrs);
|
||||
aDesc.object().set(aProxy);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -1407,12 +1407,11 @@ bool nsImageLoadingContent::HaveSize(imgIRequest* aImage) {
|
|||
|
||||
void nsImageLoadingContent::BindToTree(Document* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent) {
|
||||
// We may be entering the document, so if our image should be tracked,
|
||||
// track it.
|
||||
if (!aDocument) return;
|
||||
|
||||
TrackImage(mCurrentRequest);
|
||||
TrackImage(mPendingRequest);
|
||||
// We may be getting connected, if so our image should be tracked,
|
||||
if (GetOurCurrentDoc()) {
|
||||
TrackImage(mCurrentRequest);
|
||||
TrackImage(mPendingRequest);
|
||||
}
|
||||
}
|
||||
|
||||
void nsImageLoadingContent::UnbindFromTree(bool aDeep, bool aNullParent) {
|
||||
|
|
|
@ -1559,25 +1559,6 @@ nsresult HTMLFormElement::GetActionURL(nsIURI** aActionURL,
|
|||
NodePrincipal(), actionURL, nsIScriptSecurityManager::STANDARD);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Check if CSP allows this form-action
|
||||
nsCOMPtr<nsIContentSecurityPolicy> csp;
|
||||
rv = NodePrincipal()->GetCsp(getter_AddRefs(csp));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (csp) {
|
||||
bool permitsFormAction = true;
|
||||
|
||||
// form-action is only enforced if explicitly defined in the
|
||||
// policy - do *not* consult default-src, see:
|
||||
// http://www.w3.org/TR/CSP2/#directive-default-src
|
||||
rv = csp->Permits(this, nullptr /* nsICSPEventListener */, actionURL,
|
||||
nsIContentSecurityPolicy::FORM_ACTION_DIRECTIVE, true,
|
||||
&permitsFormAction);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (!permitsFormAction) {
|
||||
return NS_ERROR_CSP_FORM_ACTION_VIOLATION;
|
||||
}
|
||||
}
|
||||
|
||||
// Potentially the page uses the CSP directive 'upgrade-insecure-requests'. In
|
||||
// such a case we have to upgrade the action url from http:// to https://.
|
||||
// If the actionURL is not http, then there is nothing to do.
|
||||
|
|
|
@ -823,6 +823,25 @@ void GetEnumAttr(nsGenericHTMLElement* aContent, nsAtom* atom,
|
|||
rv = aForm->GetActionURL(getter_AddRefs(actionURL), aOriginatingElement);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Check if CSP allows this form-action
|
||||
nsCOMPtr<nsIContentSecurityPolicy> csp;
|
||||
rv = aForm->NodePrincipal()->GetCsp(getter_AddRefs(csp));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (csp) {
|
||||
bool permitsFormAction = true;
|
||||
|
||||
// form-action is only enforced if explicitly defined in the
|
||||
// policy - do *not* consult default-src, see:
|
||||
// http://www.w3.org/TR/CSP2/#directive-default-src
|
||||
rv = csp->Permits(aForm, nullptr /* nsICSPEventListener */, actionURL,
|
||||
nsIContentSecurityPolicy::FORM_ACTION_DIRECTIVE, true,
|
||||
&permitsFormAction);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (!permitsFormAction) {
|
||||
return NS_ERROR_CSP_FORM_ACTION_VIOLATION;
|
||||
}
|
||||
}
|
||||
|
||||
// Get target
|
||||
// The target is the originating element formtarget attribute if the element
|
||||
// is a submit control and has such an attribute.
|
||||
|
|
|
@ -500,8 +500,9 @@ nsresult HTMLImageElement::BindToTree(Document* aDocument, nsIContent* aParent,
|
|||
}
|
||||
|
||||
if (HaveSrcsetOrInPicture()) {
|
||||
if (aDocument && !mInDocResponsiveContent) {
|
||||
aDocument->AddResponsiveContent(this);
|
||||
Document* doc = GetComposedDoc();
|
||||
if (doc && !mInDocResponsiveContent) {
|
||||
doc->AddResponsiveContent(this);
|
||||
mInDocResponsiveContent = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -98,9 +98,8 @@ void ProfilerScreenshots::SubmitScreenshot(
|
|||
// Encode surf to a JPEG data URL.
|
||||
nsCString dataURL;
|
||||
nsresult rv = gfxUtils::EncodeSourceSurface(
|
||||
surf, NS_LITERAL_CSTRING("image/jpeg"),
|
||||
NS_LITERAL_STRING("quality=85"), gfxUtils::eDataURIEncode,
|
||||
nullptr, &dataURL);
|
||||
surf, ImageType::JPEG, NS_LITERAL_STRING("quality=85"),
|
||||
gfxUtils::eDataURIEncode, nullptr, &dataURL);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// Add a marker with the data URL.
|
||||
profiler_add_marker_for_thread(
|
||||
|
|
|
@ -23,6 +23,10 @@
|
|||
#include "mozilla/gfx/PathHelpers.h"
|
||||
#include "mozilla/gfx/Swizzle.h"
|
||||
#include "mozilla/gfx/gfxVars.h"
|
||||
#include "mozilla/image/nsBMPEncoder.h"
|
||||
#include "mozilla/image/nsICOEncoder.h"
|
||||
#include "mozilla/image/nsJPEGEncoder.h"
|
||||
#include "mozilla/image/nsPNGEncoder.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/UniquePtrExtensions.h"
|
||||
|
@ -35,6 +39,7 @@
|
|||
#include "nsIFile.h"
|
||||
#include "nsIGfxInfo.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsMimeTypes.h"
|
||||
#include "nsPresContext.h"
|
||||
#include "nsRegion.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
|
@ -896,7 +901,7 @@ const uint32_t gfxUtils::sNumFrameColors = 8;
|
|||
}
|
||||
|
||||
/* static */ nsresult gfxUtils::EncodeSourceSurface(
|
||||
SourceSurface* aSurface, const nsACString& aMimeType,
|
||||
SourceSurface* aSurface, const ImageType aImageType,
|
||||
const nsAString& aOutputOptions, BinaryOrData aBinaryOrData, FILE* aFile,
|
||||
nsACString* aStrOut) {
|
||||
MOZ_ASSERT(aBinaryOrData == gfxUtils::eDataURIEncode || aFile || aStrOut,
|
||||
|
@ -925,25 +930,31 @@ const uint32_t gfxUtils::sNumFrameColors = 8;
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsAutoCString encoderCID(
|
||||
NS_LITERAL_CSTRING("@mozilla.org/image/encoder;2?type=") + aMimeType);
|
||||
nsCOMPtr<imgIEncoder> encoder = do_CreateInstance(encoderCID.get());
|
||||
if (!encoder) {
|
||||
#ifdef DEBUG
|
||||
int32_t w = std::min(size.width, 8);
|
||||
int32_t h = std::min(size.height, 8);
|
||||
printf("Could not create encoder. Top-left %dx%d pixels contain:\n", w, h);
|
||||
for (int32_t y = 0; y < h; ++y) {
|
||||
for (int32_t x = 0; x < w; ++x) {
|
||||
printf("%x ",
|
||||
reinterpret_cast<uint32_t*>(map.mData)[y * map.mStride + x]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
dataSurface->Unmap();
|
||||
return NS_ERROR_FAILURE;
|
||||
RefPtr<imgIEncoder> encoder = nullptr;
|
||||
|
||||
switch (aImageType) {
|
||||
case ImageType::BMP:
|
||||
encoder = MakeRefPtr<nsBMPEncoder>();
|
||||
break;
|
||||
|
||||
case ImageType::ICO:
|
||||
encoder = MakeRefPtr<nsICOEncoder>();
|
||||
break;
|
||||
|
||||
case ImageType::JPEG:
|
||||
encoder = MakeRefPtr<nsJPEGEncoder>();
|
||||
break;
|
||||
|
||||
case ImageType::PNG:
|
||||
encoder = MakeRefPtr<nsPNGEncoder>();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
MOZ_RELEASE_ASSERT(encoder != nullptr);
|
||||
|
||||
nsresult rv = encoder->InitFromData(
|
||||
map.mData, BufferSizeFromStrideAndHeight(map.mStride, size.height),
|
||||
size.width, size.height, map.mStride, imgIEncoder::INPUT_FORMAT_HOSTARGB,
|
||||
|
@ -1006,17 +1017,37 @@ const uint32_t gfxUtils::sNumFrameColors = 8;
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCString stringBuf;
|
||||
nsACString& string = aStrOut ? *aStrOut : stringBuf;
|
||||
string.AppendLiteral("data:");
|
||||
string.Append(aMimeType);
|
||||
string.AppendLiteral(";base64,");
|
||||
string.Append(encodedImg);
|
||||
nsACString& dataURI = aStrOut ? *aStrOut : stringBuf;
|
||||
dataURI.AppendLiteral("data:");
|
||||
|
||||
switch (aImageType) {
|
||||
case ImageType::BMP:
|
||||
dataURI.AppendLiteral(IMAGE_BMP);
|
||||
break;
|
||||
|
||||
case ImageType::ICO:
|
||||
dataURI.AppendLiteral(IMAGE_ICO_MS);
|
||||
break;
|
||||
case ImageType::JPEG:
|
||||
dataURI.AppendLiteral(IMAGE_JPEG);
|
||||
break;
|
||||
|
||||
case ImageType::PNG:
|
||||
dataURI.AppendLiteral(IMAGE_PNG);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
dataURI.AppendLiteral(";base64,");
|
||||
dataURI.Append(encodedImg);
|
||||
|
||||
if (aFile) {
|
||||
#ifdef ANDROID
|
||||
if (aFile == stdout || aFile == stderr) {
|
||||
// ADB logcat cuts off long strings so we will break it down
|
||||
const char* cStr = string.BeginReading();
|
||||
const char* cStr = dataURI.BeginReading();
|
||||
size_t len = strlen(cStr);
|
||||
while (true) {
|
||||
printf_stderr("IMG: %.140s\n", cStr);
|
||||
|
@ -1026,12 +1057,12 @@ const uint32_t gfxUtils::sNumFrameColors = 8;
|
|||
}
|
||||
}
|
||||
#endif
|
||||
fprintf(aFile, "%s", string.BeginReading());
|
||||
fprintf(aFile, "%s", dataURI.BeginReading());
|
||||
} else if (!aStrOut) {
|
||||
nsCOMPtr<nsIClipboardHelper> clipboard(
|
||||
do_GetService("@mozilla.org/widget/clipboardhelper;1", &rv));
|
||||
if (clipboard) {
|
||||
clipboard->CopyString(NS_ConvertASCIItoUTF16(string));
|
||||
clipboard->CopyString(NS_ConvertASCIItoUTF16(dataURI));
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
|
@ -1039,9 +1070,8 @@ const uint32_t gfxUtils::sNumFrameColors = 8;
|
|||
|
||||
static nsCString EncodeSourceSurfaceAsPNGURI(SourceSurface* aSurface) {
|
||||
nsCString string;
|
||||
gfxUtils::EncodeSourceSurface(aSurface, NS_LITERAL_CSTRING("image/png"),
|
||||
EmptyString(), gfxUtils::eDataURIEncode,
|
||||
nullptr, &string);
|
||||
gfxUtils::EncodeSourceSurface(aSurface, ImageType::PNG, EmptyString(),
|
||||
gfxUtils::eDataURIEncode, nullptr, &string);
|
||||
return string;
|
||||
}
|
||||
|
||||
|
@ -1154,8 +1184,8 @@ const float kBT709NarrowYCbCrToRGB_RowMajor[16] = {
|
|||
}
|
||||
}
|
||||
|
||||
EncodeSourceSurface(aSurface, NS_LITERAL_CSTRING("image/png"), EmptyString(),
|
||||
eBinaryEncode, file);
|
||||
EncodeSourceSurface(aSurface, ImageType::PNG, EmptyString(), eBinaryEncode,
|
||||
file);
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
|
@ -1192,8 +1222,8 @@ const float kBT709NarrowYCbCrToRGB_RowMajor[16] = {
|
|||
|
||||
/* static */ void gfxUtils::DumpAsDataURI(SourceSurface* aSurface,
|
||||
FILE* aFile) {
|
||||
EncodeSourceSurface(aSurface, NS_LITERAL_CSTRING("image/png"), EmptyString(),
|
||||
eDataURIEncode, aFile);
|
||||
EncodeSourceSurface(aSurface, ImageType::PNG, EmptyString(), eDataURIEncode,
|
||||
aFile);
|
||||
}
|
||||
|
||||
/* static */ nsCString gfxUtils::GetAsDataURI(SourceSurface* aSurface) {
|
||||
|
@ -1245,8 +1275,8 @@ const float kBT709NarrowYCbCrToRGB_RowMajor[16] = {
|
|||
}
|
||||
|
||||
/* static */ void gfxUtils::CopyAsDataURI(SourceSurface* aSurface) {
|
||||
EncodeSourceSurface(aSurface, NS_LITERAL_CSTRING("image/png"), EmptyString(),
|
||||
eDataURIEncode, nullptr);
|
||||
EncodeSourceSurface(aSurface, ImageType::PNG, EmptyString(), eDataURIEncode,
|
||||
nullptr);
|
||||
}
|
||||
|
||||
/* static */ void gfxUtils::CopyAsDataURI(DrawTarget* aDT) {
|
||||
|
|
|
@ -41,6 +41,13 @@ class DisplayListBuilder;
|
|||
} // namespace wr
|
||||
} // namespace mozilla
|
||||
|
||||
enum class ImageType {
|
||||
BMP,
|
||||
ICO,
|
||||
JPEG,
|
||||
PNG,
|
||||
};
|
||||
|
||||
class gfxUtils {
|
||||
public:
|
||||
typedef mozilla::gfx::DataSourceSurface DataSourceSurface;
|
||||
|
@ -225,9 +232,8 @@ class gfxUtils {
|
|||
* If both aFile and aString are null, the encoded data is copied to the
|
||||
* clipboard.
|
||||
*
|
||||
* @param aMimeType The MIME-type of the image type that the surface is to
|
||||
* be encoded to. Used to create an appropriate imgIEncoder instance to
|
||||
* do the encoding.
|
||||
* @param aImageType The image type that the surface is to be encoded to.
|
||||
* Used to create an appropriate imgIEncoder instance to do the encoding.
|
||||
*
|
||||
* @param aOutputOptions Passed directly to imgIEncoder::InitFromData as
|
||||
* the value of the |outputOptions| parameter. Callers are responsible
|
||||
|
@ -246,7 +252,7 @@ class gfxUtils {
|
|||
* supported.
|
||||
*/
|
||||
static nsresult EncodeSourceSurface(SourceSurface* aSurface,
|
||||
const nsACString& aMimeType,
|
||||
const ImageType aImageType,
|
||||
const nsAString& aOutputOptions,
|
||||
BinaryOrData aBinaryOrData, FILE* aFile,
|
||||
nsACString* aString = nullptr);
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "nsStreamUtils.h"
|
||||
#include "nsTArray.h"
|
||||
#include "mozilla/CheckedInt.h"
|
||||
#include "BMPHeaders.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::image;
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
#include "mozilla/UniquePtr.h"
|
||||
|
||||
#include "imgIEncoder.h"
|
||||
#include "BMPHeaders.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "nsCRT.h"
|
||||
#include "mozilla/EndianUtils.h"
|
||||
#include "nsBMPEncoder.h"
|
||||
#include "BMPHeaders.h"
|
||||
#include "nsPNGEncoder.h"
|
||||
#include "nsICOEncoder.h"
|
||||
#include "nsString.h"
|
||||
|
|
|
@ -7,11 +7,11 @@
|
|||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/ReentrantMonitor.h"
|
||||
#include "mozilla/image/ICOFileHeaders.h"
|
||||
|
||||
#include "imgIEncoder.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "ICOFileHeaders.h"
|
||||
|
||||
#define NS_ICOENCODER_CID \
|
||||
{ /*92AE3AB2-8968-41B1-8709-B6123BCEAF21 */ \
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
* 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/. */
|
||||
|
||||
#ifndef nsPNGEncoder_h
|
||||
#ifndef mozilla_image_encoders_png_nsPNGEncoder_h
|
||||
#define mozilla_image_encoders_png_nsPNGEncoder_h
|
||||
|
||||
#include <png.h>
|
||||
|
||||
|
@ -74,4 +75,4 @@ class nsPNGEncoder final : public imgIEncoder {
|
|||
// AsyncWait.
|
||||
ReentrantMonitor mReentrantMonitor;
|
||||
};
|
||||
#endif // nsPNGEncoder_h
|
||||
#endif // mozilla_image_encoders_png_nsPNGEncoder_h
|
||||
|
|
|
@ -54,7 +54,11 @@ EXPORTS += [
|
|||
]
|
||||
|
||||
EXPORTS.mozilla.image += [
|
||||
'encoders/bmp/nsBMPEncoder.h',
|
||||
'encoders/ico/nsICOEncoder.h',
|
||||
'encoders/jpeg/nsJPEGEncoder.h',
|
||||
'encoders/png/nsPNGEncoder.h',
|
||||
'ICOFileHeaders.h',
|
||||
'ImageMemoryReporter.h',
|
||||
'RecyclingSourceSurface.h',
|
||||
]
|
||||
|
|
|
@ -957,7 +957,8 @@ pref("gfx.webrender.debug.show-overdraw", false);
|
|||
pref("gfx.webrender.debug.slow-frame-indicator", false);
|
||||
pref("gfx.webrender.dl.dump-parent", false);
|
||||
pref("gfx.webrender.dl.dump-content", false);
|
||||
pref("gfx.webrender.picture-caching", false);
|
||||
|
||||
pref("gfx.webrender.picture-caching", true);
|
||||
|
||||
#ifdef EARLY_BETA_OR_EARLIER
|
||||
pref("performance.adjust_to_machine", true);
|
||||
|
@ -1080,6 +1081,8 @@ pref("toolkit.scrollbox.verticalScrollDistance", 3);
|
|||
pref("toolkit.scrollbox.horizontalScrollDistance", 5);
|
||||
pref("toolkit.scrollbox.clickToScroll.scrollDelay", 150);
|
||||
|
||||
pref("toolkit.tabbox.switchByScrolling", false);
|
||||
|
||||
// Telemetry settings.
|
||||
// Server to submit telemetry pings to.
|
||||
pref("toolkit.telemetry.server", "https://incoming.telemetry.mozilla.org");
|
||||
|
|
|
@ -164,7 +164,12 @@ linux64-clang-tidy:
|
|||
using: toolchain-script
|
||||
script: build-clang-tidy-linux.sh
|
||||
resources:
|
||||
- 'build/clang-plugin/**'
|
||||
- 'build/clang-plugin/**/*.cpp'
|
||||
- 'build/clang-plugin/**/*.h'
|
||||
- 'build/clang-plugin/*.inc'
|
||||
- 'build/clang-plugin/*.py'
|
||||
- 'build/clang-plugin/moz.build'
|
||||
- 'build/clang-plugin/Makefile.in'
|
||||
- 'build/build-clang/build-clang.py'
|
||||
- 'build/build-clang/clang-tidy-linux64.json'
|
||||
- 'taskcluster/scripts/misc/tooltool-download.sh'
|
||||
|
|
|
@ -56,7 +56,12 @@ macosx64-clang-tidy:
|
|||
script: build-clang-tidy-macosx.sh
|
||||
tooltool-downloads: internal
|
||||
resources:
|
||||
- 'build/clang-plugin/**'
|
||||
- 'build/clang-plugin/**/*.cpp'
|
||||
- 'build/clang-plugin/**/*.h'
|
||||
- 'build/clang-plugin/*.inc'
|
||||
- 'build/clang-plugin/*.py'
|
||||
- 'build/clang-plugin/moz.build'
|
||||
- 'build/clang-plugin/Makefile.in'
|
||||
- 'build/build-clang/build-clang.py'
|
||||
- 'build/build-clang/clang-tidy-macosx64.json'
|
||||
- 'taskcluster/scripts/misc/tooltool-download.sh'
|
||||
|
|
|
@ -42,7 +42,12 @@ win32-clang-tidy:
|
|||
using: toolchain-script
|
||||
script: build-clang-tidy32-windows.sh
|
||||
resources:
|
||||
- 'build/clang-plugin/**'
|
||||
- 'build/clang-plugin/**/*.cpp'
|
||||
- 'build/clang-plugin/**/*.h'
|
||||
- 'build/clang-plugin/*.inc'
|
||||
- 'build/clang-plugin/*.py'
|
||||
- 'build/clang-plugin/moz.build'
|
||||
- 'build/clang-plugin/Makefile.in'
|
||||
- 'build/build-clang/build-clang.py'
|
||||
- 'build/build-clang/clang-tidy-win32.json'
|
||||
- 'taskcluster/scripts/misc/build-clang-windows-helper32.sh'
|
||||
|
@ -70,7 +75,12 @@ win64-clang-tidy:
|
|||
using: toolchain-script
|
||||
script: build-clang-tidy64-windows.sh
|
||||
resources:
|
||||
- 'build/clang-plugin/**'
|
||||
- 'build/clang-plugin/**/*.cpp'
|
||||
- 'build/clang-plugin/**/*.h'
|
||||
- 'build/clang-plugin/*.inc'
|
||||
- 'build/clang-plugin/*.py'
|
||||
- 'build/clang-plugin/moz.build'
|
||||
- 'build/clang-plugin/Makefile.in'
|
||||
- 'build/build-clang/build-clang.py'
|
||||
- 'build/build-clang/clang-tidy-win32.json'
|
||||
- 'taskcluster/scripts/misc/build-clang-windows-helper64.sh'
|
||||
|
|
|
@ -1400,7 +1400,14 @@ function switchToFrame(msg) {
|
|||
if (typeof msg.json.element != "undefined") {
|
||||
webEl = WebElement.fromUUID(msg.json.element, "content");
|
||||
}
|
||||
if (webEl && seenEls.has(webEl)) {
|
||||
|
||||
if (webEl) {
|
||||
if (!seenEls.has(webEl)) {
|
||||
let err = new NoSuchElementError(`Unable to locate element: ${webEl}`);
|
||||
sendError(err, commandID);
|
||||
return;
|
||||
}
|
||||
|
||||
let wantedFrame;
|
||||
try {
|
||||
wantedFrame = seenEls.get(webEl, curContainer.frame);
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
[focus-autofocus.html]
|
||||
disabled: https://bugzilla.mozilla.org/show_bug.cgi?id=1273247
|
|
@ -0,0 +1,46 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<meta http-equiv="Content-Security-Policy" content="form-action 'none'; script-src 'self' 'nonce-noncynonce'; connect-src 'self';">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<form action='/content-security-policy/support/postmessage-pass-to-opener.html'
|
||||
id='form_id'
|
||||
target="_blank">
|
||||
<input type="submit" />
|
||||
</form>
|
||||
|
||||
<p>
|
||||
Test that "form-action 'none'" doesn't create a violation report if the event was prevented.
|
||||
</p>
|
||||
</body>
|
||||
|
||||
<script nonce='noncynonce'>
|
||||
async_test(t => {
|
||||
document.addEventListener('securitypolicyviolation', function(e) {
|
||||
assert_unreached('Form submission was blocked.');
|
||||
});
|
||||
|
||||
window.addEventListener('message', function(event) {
|
||||
assert_unreached('Form submission was blocked.');
|
||||
})
|
||||
|
||||
window.addEventListener("load", function() {
|
||||
let form = document.getElementById("form_id");
|
||||
form.addEventListener("submit", e => {
|
||||
e.preventDefault();
|
||||
setTimeout(() => {
|
||||
t.done();
|
||||
}, 0);
|
||||
});
|
||||
// clicking the input is used here as form.submit() will submit a form without an event and should also be blocked.
|
||||
form.querySelector("input").click();
|
||||
});
|
||||
}, "The form submission should not be blocked by when javascript prevents the load.");
|
||||
</script>
|
||||
|
||||
</html>
|
|
@ -0,0 +1,33 @@
|
|||
<!doctype html>
|
||||
<html class="reftest-wait">
|
||||
<title>Image intrinsic size specified via sizes attribute reacts properly to media changes in Shadow DOM</title>
|
||||
<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
|
||||
<link rel="match" href="sizes-dynamic-001-ref.html">
|
||||
<link rel="help" href="https://html.spec.whatwg.org/#sizes-attributes">
|
||||
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1149357">
|
||||
<script>
|
||||
function frameLoaded(frame) {
|
||||
let doc = frame.contentDocument;
|
||||
let shadow = doc.getElementById("host").attachShadow({ mode: "open" });
|
||||
|
||||
let img = doc.createElement("img");
|
||||
img.srcset = "/images/green-256x256.png 100w";
|
||||
img.style.maxWidth = "100%";
|
||||
img.setAttribute("sizes", "(min-width: 400px) 10px, 20px");
|
||||
|
||||
img.onload = function() {
|
||||
img.offsetWidth; // Flush layout.
|
||||
|
||||
frame.width = "500";
|
||||
|
||||
// Trigger the viewport resize, which will trigger the image load task.
|
||||
img.offsetWidth;
|
||||
|
||||
// Wait for the image load task to run.
|
||||
setTimeout(() => document.documentElement.removeAttribute("class"), 0);
|
||||
};
|
||||
|
||||
shadow.appendChild(img);
|
||||
}
|
||||
</script>
|
||||
<iframe onload="frameLoaded(this)" width="200" height="500" srcdoc='<!doctype html><div id="host"></div>'></iframe>
|
|
@ -474,6 +474,7 @@ def setup_logging(kwargs, default_config=None):
|
|||
default_config = {default_formatter: sys.stdout}
|
||||
wptrunner.setup_logging(kwargs, default_config)
|
||||
logger = wptrunner.logger
|
||||
return logger
|
||||
|
||||
|
||||
def setup_wptrunner(venv, prompt=True, install_browser=False, **kwargs):
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
import pytest
|
||||
|
||||
import webdriver.protocol as protocol
|
||||
|
||||
from webdriver import StaleElementReferenceException
|
||||
from webdriver.transport import Response
|
||||
|
||||
from tests.support.asserts import assert_error, assert_success
|
||||
from tests.support.asserts import assert_error, assert_same_element, assert_success
|
||||
from tests.support.inline import inline, iframe
|
||||
|
||||
|
||||
|
@ -13,6 +17,11 @@ def switch_to_frame(session, frame):
|
|||
session=session)
|
||||
|
||||
|
||||
def frameset(*docs):
|
||||
frames = map(lambda doc: "<frame src='{}'></frame>".format(inline(doc)), docs)
|
||||
return "<frameset rows='{}'>\n{}</frameset>".format(len(frames) * "*,", "\n".join(frames))
|
||||
|
||||
|
||||
def test_null_parameter_value(session, http):
|
||||
path = "/session/{session_id}/frame".format(**vars(session))
|
||||
with http.post(path, None) as response:
|
||||
|
@ -21,13 +30,120 @@ def test_null_parameter_value(session, http):
|
|||
|
||||
def test_null_response_value(session):
|
||||
session.url = inline(iframe("<p>foo"))
|
||||
frame_element = session.find.css("iframe", all=False)
|
||||
frame = session.find.css("iframe", all=False)
|
||||
|
||||
response = switch_to_frame(session, frame_element)
|
||||
response = switch_to_frame(session, frame)
|
||||
value = assert_success(response)
|
||||
assert value is None
|
||||
|
||||
|
||||
@pytest.mark.parametrize("value", ["foo", True, [], {}])
|
||||
def test_frame_id_invalid_types(session, value):
|
||||
response = switch_to_frame(session, value)
|
||||
assert_error(response, "invalid argument")
|
||||
|
||||
|
||||
@pytest.mark.parametrize("value", [-1, 2**16])
|
||||
def test_frame_id_out_of_bounds(session, value):
|
||||
response = switch_to_frame(session, value)
|
||||
assert_error(response, "invalid argument")
|
||||
|
||||
|
||||
def test_no_browsing_context(session, closed_window):
|
||||
response = switch_to_frame(session, 1)
|
||||
assert_error(response, "no such window")
|
||||
|
||||
|
||||
def test_frame_id_null(session):
|
||||
session.url = inline(iframe("{}<div>foo".format(iframe("<p>bar"))))
|
||||
|
||||
frame1 = session.find.css("iframe", all=False)
|
||||
session.switch_frame(frame1)
|
||||
frame1_element = session.find.css("div", all=False)
|
||||
|
||||
frame2 = session.find.css("iframe", all=False)
|
||||
session.switch_frame(frame2)
|
||||
frame2_element = session.find.css("p", all=False)
|
||||
|
||||
# Switch to top-level browsing context
|
||||
response = switch_to_frame(session, None)
|
||||
assert_success(response)
|
||||
|
||||
with pytest.raises(StaleElementReferenceException):
|
||||
frame2_element.text
|
||||
with pytest.raises(StaleElementReferenceException):
|
||||
frame1_element.text
|
||||
|
||||
frame = session.find.css("iframe", all=False)
|
||||
assert_same_element(session, frame, frame1)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("index, value", [[0, "foo"], [1, "bar"]])
|
||||
def test_frame_id_number_index(session, index, value):
|
||||
session.url = inline("{}{}".format(iframe("<p>foo"), iframe("<p>bar")))
|
||||
|
||||
response = switch_to_frame(session, index)
|
||||
assert_success(response)
|
||||
|
||||
frame_element = session.find.css("p", all=False)
|
||||
assert frame_element.text == value
|
||||
|
||||
|
||||
def test_frame_id_number_index_out_of_bounds(session):
|
||||
session.url = inline(iframe("<p>foo"))
|
||||
|
||||
response = switch_to_frame(session, 1)
|
||||
assert_error(response, "no such frame")
|
||||
|
||||
|
||||
@pytest.mark.parametrize("index, value", [[0, "foo"], [1, "bar"]])
|
||||
def test_frame_id_webelement_frame(session, index, value):
|
||||
session.url = inline(frameset("<p>foo", "<p>bar"))
|
||||
frames = session.find.css("frame")
|
||||
assert len(frames) == 2
|
||||
|
||||
response = switch_to_frame(session, frames[index])
|
||||
assert_success(response)
|
||||
|
||||
frame_element = session.find.css("p", all=False)
|
||||
assert frame_element.text == value
|
||||
|
||||
|
||||
@pytest.mark.parametrize("index, value", [[0, "foo"], [1, "bar"]])
|
||||
def test_frame_id_webelement_iframe(session, index, value):
|
||||
session.url = inline("{}{}".format(iframe("<p>foo"), iframe("<p>bar")))
|
||||
frames = session.find.css("iframe")
|
||||
assert len(frames) == 2
|
||||
|
||||
response = switch_to_frame(session, frames[index])
|
||||
assert_success(response)
|
||||
|
||||
frame_element = session.find.css("p", all=False)
|
||||
assert frame_element.text == value
|
||||
|
||||
|
||||
def test_frame_id_webelement_no_element_reference(session):
|
||||
session.url = inline(iframe("<p>foo"))
|
||||
frame = session.find.css("iframe", all=False)
|
||||
frame.id = "bar"
|
||||
|
||||
response = switch_to_frame(session, frame)
|
||||
assert_error(response, "no such element")
|
||||
|
||||
|
||||
def test_frame_id_webelement_stale_reference(session):
|
||||
session.url = inline(iframe("<p>foo"))
|
||||
frame = session.find.css("iframe", all=False)
|
||||
|
||||
session.switch_frame(frame)
|
||||
|
||||
response = switch_to_frame(session, frame)
|
||||
assert_error(response, "stale element reference")
|
||||
|
||||
|
||||
def test_frame_id_webelement_no_frame_element(session):
|
||||
session.url = inline("<p>foo")
|
||||
no_frame = session.find.css("p", all=False)
|
||||
|
||||
response = switch_to_frame(session, no_frame)
|
||||
assert_error(response, "no such frame")
|
||||
|
|
|
@ -989,7 +989,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_json_switch_to_frame_parameters_with_invalid_id_field() {
|
||||
let json = r#"{"id":"3""#;
|
||||
let json = r#"{"id":"3"}"#;
|
||||
|
||||
assert!(serde_json::from_str::<SwitchToFrameParameters>(&json).is_err());
|
||||
}
|
||||
|
|
|
@ -614,6 +614,7 @@ function Search(searchString, searchParam, autocompleteListener,
|
|||
this._disablePrivateActions = params.has("disable-private-actions");
|
||||
this._inPrivateWindow = params.has("private-window");
|
||||
this._prohibitAutoFill = params.has("prohibit-autofill");
|
||||
this._disableTelemetry = params.has("disable-telemetry");
|
||||
|
||||
// Extract the max-results param.
|
||||
let maxResults = searchParam.match(REGEXP_MAX_RESULTS);
|
||||
|
@ -856,8 +857,10 @@ Search.prototype = {
|
|||
}
|
||||
};
|
||||
|
||||
TelemetryStopwatch.start(TELEMETRY_1ST_RESULT, this);
|
||||
TelemetryStopwatch.start(TELEMETRY_6_FIRST_RESULTS, this);
|
||||
if (!this._disableTelemetry) {
|
||||
TelemetryStopwatch.start(TELEMETRY_1ST_RESULT, this);
|
||||
TelemetryStopwatch.start(TELEMETRY_6_FIRST_RESULTS, this);
|
||||
}
|
||||
|
||||
// Since we call the synchronous parseSubmissionURL function later, we must
|
||||
// wait for the initialization of PlacesSearchAutocompleteProvider first.
|
||||
|
@ -1934,10 +1937,12 @@ Search.prototype = {
|
|||
this._currentMatchCount++;
|
||||
this._counts[match.type]++;
|
||||
|
||||
if (this._currentMatchCount == 1)
|
||||
TelemetryStopwatch.finish(TELEMETRY_1ST_RESULT, this);
|
||||
if (this._currentMatchCount == 6)
|
||||
TelemetryStopwatch.finish(TELEMETRY_6_FIRST_RESULTS, this);
|
||||
if (!this._disableTelemetry) {
|
||||
if (this._currentMatchCount == 1)
|
||||
TelemetryStopwatch.finish(TELEMETRY_1ST_RESULT, this);
|
||||
if (this._currentMatchCount == 6)
|
||||
TelemetryStopwatch.finish(TELEMETRY_6_FIRST_RESULTS, this);
|
||||
}
|
||||
this.notifyResult(true, match.type == UrlbarUtils.MATCH_GROUP.HEURISTIC);
|
||||
},
|
||||
|
||||
|
@ -2685,8 +2690,10 @@ UnifiedComplete.prototype = {
|
|||
* results or not.
|
||||
*/
|
||||
finishSearch(notify = false) {
|
||||
TelemetryStopwatch.cancel(TELEMETRY_1ST_RESULT, this);
|
||||
TelemetryStopwatch.cancel(TELEMETRY_6_FIRST_RESULTS, this);
|
||||
if (!this._disableTelemetry) {
|
||||
TelemetryStopwatch.cancel(TELEMETRY_1ST_RESULT, this);
|
||||
TelemetryStopwatch.cancel(TELEMETRY_6_FIRST_RESULTS, this);
|
||||
}
|
||||
// Clear state now to avoid race conditions, see below.
|
||||
let search = this._currentSearch;
|
||||
if (!search)
|
||||
|
|
|
@ -17,7 +17,6 @@ var histograms = {
|
|||
PLACES_DATABASE_PAGESIZE_B: val => Assert.equal(val, 32768),
|
||||
PLACES_DATABASE_SIZE_PER_PAGE_B: val => Assert.ok(val > 0),
|
||||
PLACES_EXPIRATION_STEPS_TO_CLEAN2: val => Assert.ok(val > 1),
|
||||
// PLACES_AUTOCOMPLETE_1ST_RESULT_TIME_MS: val => do_check_true(val > 1),
|
||||
PLACES_IDLE_FRECENCY_DECAY_TIME_MS: val => Assert.ok(val >= 0),
|
||||
PLACES_IDLE_MAINTENANCE_TIME_MS: val => Assert.ok(val > 0),
|
||||
PLACES_ANNOS_BOOKMARKS_COUNT: val => Assert.equal(val, 1),
|
||||
|
@ -121,42 +120,6 @@ add_task(async function test_execute() {
|
|||
await promiseForceExpirationStep(2);
|
||||
await promiseForceExpirationStep(2);
|
||||
|
||||
// Test autocomplete probes.
|
||||
/*
|
||||
// This is useful for manual testing by changing the minimum time for
|
||||
// autocomplete telemetry to 0, but there is no way to artificially delay
|
||||
// autocomplete by more than 50ms in a realiable way.
|
||||
Services.prefs.setIntPref("browser.urlbar.search.sources", 3);
|
||||
Services.prefs.setIntPref("browser.urlbar.default.behavior", 0);
|
||||
function AutoCompleteInput(aSearches) {
|
||||
this.searches = aSearches;
|
||||
}
|
||||
AutoCompleteInput.prototype = {
|
||||
timeout: 10,
|
||||
textValue: "",
|
||||
searchParam: "",
|
||||
popupOpen: false,
|
||||
minResultsForPopup: 0,
|
||||
invalidate: function() {},
|
||||
disableAutoComplete: false,
|
||||
completeDefaultIndex: false,
|
||||
get popup() { return this; },
|
||||
onSearchBegin: function() {},
|
||||
onSearchComplete: function() {},
|
||||
setSelectedIndex: function() {},
|
||||
get searchCount() { return this.searches.length; },
|
||||
getSearchAt: function(aIndex) { return this.searches[aIndex]; },
|
||||
QueryInterface: ChromeUtils.generateQI([
|
||||
Ci.nsIAutoCompleteInput,
|
||||
Ci.nsIAutoCompletePopup,
|
||||
])
|
||||
};
|
||||
let controller = Cc["@mozilla.org/autocomplete/controller;1"].
|
||||
getService(Ci.nsIAutoCompleteController);
|
||||
controller.input = new AutoCompleteInput(["unifiedcomplete"]);
|
||||
controller.startSearch("moz");
|
||||
*/
|
||||
|
||||
// Test idle probes.
|
||||
PlacesUtils.history.QueryInterface(Ci.nsIObserver)
|
||||
.observe(null, "idle-daily", null);
|
||||
|
|
|
@ -80,7 +80,7 @@ toolkit.jar:
|
|||
content/global/bindings/richlistbox.xml (widgets/richlistbox.xml)
|
||||
content/global/bindings/scrollbox.xml (widgets/scrollbox.xml)
|
||||
content/global/bindings/spinner.js (widgets/spinner.js)
|
||||
* content/global/bindings/tabbox.xml (widgets/tabbox.xml)
|
||||
content/global/bindings/tabbox.xml (widgets/tabbox.xml)
|
||||
content/global/bindings/text.xml (widgets/text.xml)
|
||||
* content/global/bindings/textbox.xml (widgets/textbox.xml)
|
||||
content/global/bindings/timekeeper.js (widgets/timekeeper.js)
|
||||
|
|
|
@ -138,6 +138,10 @@
|
|||
this.tabbox;
|
||||
]]></field>
|
||||
|
||||
<field name="_prefService" readonly="true"><![CDATA[
|
||||
Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
|
||||
]]></field>
|
||||
|
||||
<property name="selectedIndex">
|
||||
<getter>
|
||||
<![CDATA[
|
||||
|
@ -354,20 +358,20 @@
|
|||
</method>
|
||||
</implementation>
|
||||
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
<handlers>
|
||||
<handler event="DOMMouseScroll">
|
||||
<![CDATA[
|
||||
if (event.detail > 0)
|
||||
this.advanceSelectedTab(1, false);
|
||||
else
|
||||
this.advanceSelectedTab(-1, false);
|
||||
|
||||
event.stopPropagation();
|
||||
if (this._prefService.getBoolPref("toolkit.tabbox.switchByScrolling")) {
|
||||
if (event.detail > 0) {
|
||||
this.advanceSelectedTab(1, false);
|
||||
} else {
|
||||
this.advanceSelectedTab(-1, false);
|
||||
}
|
||||
event.stopPropagation();
|
||||
}
|
||||
]]>
|
||||
</handler>
|
||||
</handlers>
|
||||
#endif
|
||||
</binding>
|
||||
|
||||
<binding id="tab"
|
||||
|
|
|
@ -1300,8 +1300,7 @@ NS_IMETHODIMP AsyncEncodeAndWriteIcon::Run() {
|
|||
}
|
||||
}
|
||||
nsresult rv = gfxUtils::EncodeSourceSurface(
|
||||
surface, NS_LITERAL_CSTRING("image/vnd.microsoft.icon"), EmptyString(),
|
||||
gfxUtils::eBinaryEncode, file);
|
||||
surface, ImageType::ICO, EmptyString(), gfxUtils::eBinaryEncode, file);
|
||||
fclose(file);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче