mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 11:55:49 +00:00
Merge inbound to m-c. a=merge
CLOSED TREE
This commit is contained in:
commit
8aaa845a81
@ -1024,7 +1024,7 @@ pref("apz.fling_curve_function_y1", "0.0");
|
||||
pref("apz.fling_curve_function_x2", "0.80");
|
||||
pref("apz.fling_curve_function_y2", "1.0");
|
||||
pref("apz.fling_curve_threshold_inches_per_ms", "0.01");
|
||||
pref("apz.fling_friction", "0.00238");
|
||||
pref("apz.fling_friction", "0.0019");
|
||||
pref("apz.max_velocity_inches_per_ms", "0.07");
|
||||
|
||||
// Tweak default displayport values to reduce the risk of running out of
|
||||
@ -1039,9 +1039,9 @@ pref("apz.axis_lock.mode", 2);
|
||||
|
||||
// Overscroll-related settings
|
||||
pref("apz.overscroll.enabled", true);
|
||||
pref("apz.overscroll.stretch_factor", "0.15");
|
||||
pref("apz.overscroll.spring_stiffness", "0.002");
|
||||
pref("apz.overscroll.spring_friction", "0.02");
|
||||
pref("apz.overscroll.stretch_factor", "0.35");
|
||||
pref("apz.overscroll.spring_stiffness", "0.0018");
|
||||
pref("apz.overscroll.spring_friction", "0.015");
|
||||
pref("apz.overscroll.stop_distance_threshold", "5.0");
|
||||
pref("apz.overscroll.stop_velocity_threshold", "0.01");
|
||||
|
||||
|
1
config/external/nss/nss.def
vendored
1
config/external/nss/nss.def
vendored
@ -525,7 +525,6 @@ SECKEY_ExtractPublicKey
|
||||
SECKEY_GetPublicKeyType
|
||||
SECKEY_ImportDERPublicKey
|
||||
SECKEY_PublicKeyStrength
|
||||
SECKEY_PublicKeyStrengthInBits
|
||||
SECKEY_RSAPSSParamsTemplate DATA
|
||||
SECKEY_SignatureLen
|
||||
SECMIME_DecryptionAllowed
|
||||
|
@ -858,7 +858,7 @@ Console::Assert(JSContext* aCx, bool aCondition,
|
||||
METHOD(Count, "count")
|
||||
|
||||
void
|
||||
Console::__noSuchMethod__()
|
||||
Console::NoopMethod()
|
||||
{
|
||||
// Nothing to do.
|
||||
}
|
||||
|
@ -101,7 +101,7 @@ public:
|
||||
Count(JSContext* aCx, const Sequence<JS::Value>& aData);
|
||||
|
||||
void
|
||||
__noSuchMethod__();
|
||||
NoopMethod();
|
||||
|
||||
private:
|
||||
enum MethodName
|
||||
|
@ -670,6 +670,26 @@ public:
|
||||
mCleanedUp);
|
||||
}
|
||||
|
||||
bool
|
||||
HadOriginalOpener() const
|
||||
{
|
||||
MOZ_ASSERT(IsOuterWindow());
|
||||
return mHadOriginalOpener;
|
||||
}
|
||||
|
||||
bool
|
||||
IsTopLevelWindow()
|
||||
{
|
||||
MOZ_ASSERT(IsOuterWindow());
|
||||
nsCOMPtr<nsIDOMWindow> parentWindow;
|
||||
nsresult rv = GetScriptableTop(getter_AddRefs(parentWindow));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return parentWindow == static_cast<nsIDOMWindow*>(this);
|
||||
}
|
||||
|
||||
virtual void
|
||||
FirePopupBlockedEvent(nsIDocument* aDoc,
|
||||
nsIURI* aPopupURI,
|
||||
|
@ -1783,8 +1783,8 @@ ReparentWrapper(JSContext* aCx, JS::Handle<JSObject*> aObjArg)
|
||||
// CloneExpandoChain() will use this property of |newobj| when it calls
|
||||
// preserveWrapper() via attachExpandoObject() if |aObj| has expandos set, and
|
||||
// preserveWrapper() will not do anything in this case. This is safe because
|
||||
// if expandos are present then the wrapper will already already have been
|
||||
// preserved called for this native.
|
||||
// if expandos are present then the wrapper will already have been preserved
|
||||
// for this native.
|
||||
if (!xpc::XrayUtils::CloneExpandoChain(aCx, newobj, aObj)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
@ -1270,6 +1270,11 @@ DOMInterfaces = {
|
||||
'nativeType': 'mozilla::dom::TextTrackRegion',
|
||||
},
|
||||
|
||||
'WindowClient': {
|
||||
'nativeType': 'mozilla::dom::workers::ServiceWorkerWindowClient',
|
||||
'headerFile': 'mozilla/dom/workers/bindings/ServiceWorkerWindowClient.h',
|
||||
},
|
||||
|
||||
'WebGLActiveInfo': {
|
||||
'nativeType': 'mozilla::WebGLActiveInfo',
|
||||
'headerFile': 'WebGLActiveInfo.h'
|
||||
|
18
dom/cache/DBSchema.cpp
vendored
18
dom/cache/DBSchema.cpp
vendored
@ -339,7 +339,7 @@ DBSchema::CachePut(mozIStorageConnection* aConn, CacheId aCacheId,
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(aConn);
|
||||
|
||||
PCacheQueryParams params(false, false, false, false, false,
|
||||
PCacheQueryParams params(false, false, false, false,
|
||||
NS_LITERAL_STRING(""));
|
||||
nsAutoTArray<EntryId, 256> matches;
|
||||
nsresult rv = QueryCache(aConn, aCacheId, aRequest, params, matches);
|
||||
@ -675,13 +675,7 @@ DBSchema::QueryCache(mozIStorageConnection* aConn, CacheId aCacheId,
|
||||
query.AppendLiteral("request_url");
|
||||
}
|
||||
|
||||
if (aParams.prefixMatch()) {
|
||||
query.AppendLiteral(" LIKE ?2 ESCAPE '\\'");
|
||||
} else {
|
||||
query.AppendLiteral("=?2");
|
||||
}
|
||||
|
||||
query.AppendLiteral(" GROUP BY entries.id ORDER BY entries.id;");
|
||||
query.AppendLiteral("=?2 GROUP BY entries.id ORDER BY entries.id;");
|
||||
|
||||
nsCOMPtr<mozIStorageStatement> state;
|
||||
nsresult rv = aConn->CreateStatement(query, getter_AddRefs(state));
|
||||
@ -690,14 +684,6 @@ DBSchema::QueryCache(mozIStorageConnection* aConn, CacheId aCacheId,
|
||||
rv = state->BindInt32Parameter(0, aCacheId);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
if (aParams.prefixMatch()) {
|
||||
nsAutoString escapedUrlToMatch;
|
||||
rv = state->EscapeStringForLIKE(urlToMatch, '\\', escapedUrlToMatch);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
urlToMatch = escapedUrlToMatch;
|
||||
urlToMatch.AppendLiteral("%");
|
||||
}
|
||||
|
||||
rv = state->BindStringParameter(1, urlToMatch);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
|
1
dom/cache/PCacheTypes.ipdlh
vendored
1
dom/cache/PCacheTypes.ipdlh
vendored
@ -22,7 +22,6 @@ struct PCacheQueryParams
|
||||
bool ignoreSearch;
|
||||
bool ignoreMethod;
|
||||
bool ignoreVary;
|
||||
bool prefixMatch;
|
||||
bool cacheNameSet;
|
||||
nsString cacheName;
|
||||
};
|
||||
|
1
dom/cache/TypeUtils.cpp
vendored
1
dom/cache/TypeUtils.cpp
vendored
@ -266,7 +266,6 @@ TypeUtils::ToPCacheQueryParams(PCacheQueryParams& aOut,
|
||||
aOut.ignoreSearch() = aIn.mIgnoreSearch;
|
||||
aOut.ignoreMethod() = aIn.mIgnoreMethod;
|
||||
aOut.ignoreVary() = aIn.mIgnoreVary;
|
||||
aOut.prefixMatch() = aIn.mPrefixMatch;
|
||||
aOut.cacheNameSet() = aIn.mCacheName.WasPassed();
|
||||
if (aOut.cacheNameSet()) {
|
||||
aOut.cacheName() = aIn.mCacheName.Value();
|
||||
|
@ -41,7 +41,7 @@ tests.forEach(function(e) {
|
||||
var measn = e.ac.createMediaElementSource(a);
|
||||
var sp = e.ac.createScriptProcessor(2048, 1);
|
||||
// Set a couple expandos to track the status of the test
|
||||
sp.iterationsLeft = 20;
|
||||
sp.iterationsLeft = 200;
|
||||
sp.seenSound = false;
|
||||
|
||||
measn.connect(sp);
|
||||
|
@ -76,6 +76,7 @@ GetStrokeDashData(SVGContentUtils::AutoStrokeOptions* aStrokeOptions,
|
||||
{
|
||||
size_t dashArrayLength;
|
||||
Float totalLengthOfDashes = 0.0, totalLengthOfGaps = 0.0;
|
||||
Float pathScale = 1.0;
|
||||
|
||||
if (aContextPaint && aStyleSVG->mStrokeDasharrayFromObject) {
|
||||
const FallibleTArray<gfxFloat>& dashSrc = aContextPaint->GetStrokeDashArray();
|
||||
@ -100,7 +101,6 @@ GetStrokeDashData(SVGContentUtils::AutoStrokeOptions* aStrokeOptions,
|
||||
if (dashArrayLength <= 0) {
|
||||
return eContinuousStroke;
|
||||
}
|
||||
Float pathScale = 1.0;
|
||||
if (aElement->IsSVGElement(nsGkAtoms::path)) {
|
||||
pathScale = static_cast<SVGPathElement*>(aElement)->
|
||||
GetPathLengthScale(SVGPathElement::eForStroking);
|
||||
@ -161,7 +161,8 @@ GetStrokeDashData(SVGContentUtils::AutoStrokeOptions* aStrokeOptions,
|
||||
aStrokeOptions->mDashOffset = Float(aContextPaint->GetStrokeDashOffset());
|
||||
} else {
|
||||
aStrokeOptions->mDashOffset =
|
||||
SVGContentUtils::CoordToFloat(aElement, aStyleSVG->mStrokeDashoffset);
|
||||
SVGContentUtils::CoordToFloat(aElement, aStyleSVG->mStrokeDashoffset) *
|
||||
pathScale;
|
||||
}
|
||||
|
||||
return eDashedStroke;
|
||||
|
@ -38,7 +38,12 @@ function doTest() {
|
||||
"assert": "function",
|
||||
"count": "function",
|
||||
"table": "function",
|
||||
"__noSuchMethod__": "function"
|
||||
"clear": "function",
|
||||
"dirxml": "function",
|
||||
"markTimeline": "function",
|
||||
"timeline": "function",
|
||||
"timelineEnd": "function",
|
||||
"timeStamp": "function",
|
||||
};
|
||||
|
||||
var foundProps = 0;
|
||||
|
@ -33,7 +33,6 @@ dictionary CacheQueryOptions {
|
||||
boolean ignoreSearch = false;
|
||||
boolean ignoreMethod = false;
|
||||
boolean ignoreVary = false;
|
||||
boolean prefixMatch = false;
|
||||
DOMString cacheName;
|
||||
};
|
||||
|
||||
|
@ -10,8 +10,23 @@
|
||||
|
||||
[Exposed=ServiceWorker]
|
||||
interface Client {
|
||||
readonly attribute unsigned long id;
|
||||
readonly attribute USVString url;
|
||||
|
||||
[Throws]
|
||||
void postMessage(any message, optional sequence<Transferable> transfer);
|
||||
};
|
||||
|
||||
[Exposed=ServiceWorker]
|
||||
interface WindowClient : Client {
|
||||
readonly attribute VisibilityState visibilityState;
|
||||
readonly attribute boolean focused;
|
||||
readonly attribute FrameType frameType;
|
||||
Promise<WindowClient> focus();
|
||||
};
|
||||
|
||||
enum FrameType {
|
||||
"auxiliary",
|
||||
"top-level",
|
||||
"nested",
|
||||
"none"
|
||||
};
|
||||
|
@ -10,10 +10,11 @@
|
||||
|
||||
[Exposed=ServiceWorker]
|
||||
interface Clients {
|
||||
// A list of client objects, identifiable by ID, that correspond to windows
|
||||
// (or workers) that are "controlled" by this SW
|
||||
// The objects returned will be new instances every time
|
||||
[Throws]
|
||||
Promise<sequence<Client>?> matchAll(optional ClientQueryOptions options);
|
||||
Promise<WindowClient> openWindow(USVString url);
|
||||
Promise<void> claim();
|
||||
};
|
||||
|
||||
dictionary ClientQueryOptions {
|
||||
|
@ -28,7 +28,19 @@ interface Console {
|
||||
void assert(boolean condition, any... data);
|
||||
void count(any... data);
|
||||
|
||||
void ___noSuchMethod__();
|
||||
// No-op methods for compatibility with other browsers.
|
||||
[BinaryName="noopMethod"]
|
||||
void clear();
|
||||
[BinaryName="noopMethod"]
|
||||
void dirxml();
|
||||
[BinaryName="noopMethod"]
|
||||
void markTimeline();
|
||||
[BinaryName="noopMethod"]
|
||||
void timeline();
|
||||
[BinaryName="noopMethod"]
|
||||
void timelineEnd();
|
||||
[BinaryName="noopMethod"]
|
||||
void timeStamp();
|
||||
};
|
||||
|
||||
// This is used to propagate console events to the observers.
|
||||
|
@ -12,7 +12,9 @@
|
||||
Exposed=(ServiceWorker)]
|
||||
interface FetchEvent : Event {
|
||||
readonly attribute Request request;
|
||||
readonly attribute Client client; // The window issuing the request.
|
||||
|
||||
// https://github.com/slightlyoff/ServiceWorker/issues/631
|
||||
readonly attribute Client? client; // The window issuing the request.
|
||||
readonly attribute boolean isReload;
|
||||
|
||||
[Throws] void respondWith(Promise<Response> r);
|
||||
|
@ -37,14 +37,8 @@ interface ServiceWorkerContainer : EventTarget {
|
||||
|
||||
// Testing only.
|
||||
partial interface ServiceWorkerContainer {
|
||||
[Throws,Pref="dom.serviceWorkers.testing.enabled"]
|
||||
Promise<any> clearAllServiceWorkerData();
|
||||
|
||||
[Throws,Pref="dom.serviceWorkers.testing.enabled"]
|
||||
DOMString getScopeForUrl(DOMString url);
|
||||
|
||||
[Throws,Pref="dom.serviceWorkers.testing.enabled"]
|
||||
DOMString getControllingWorkerScriptURLForPath(DOMString path);
|
||||
};
|
||||
|
||||
dictionary RegistrationOptionList {
|
||||
|
@ -13,14 +13,8 @@
|
||||
[Global=(Worker,ServiceWorker),
|
||||
Exposed=ServiceWorker]
|
||||
interface ServiceWorkerGlobalScope : WorkerGlobalScope {
|
||||
// FIXME(nsm): Bug 982725
|
||||
// readonly attribute CacheList caches;
|
||||
|
||||
readonly attribute Clients clients;
|
||||
|
||||
// FIXME(nsm): Bug 995484
|
||||
// ResponsePromise<any> fetch((Request or [EnsureUTF16] DOMString) request);
|
||||
|
||||
void update();
|
||||
|
||||
[Throws]
|
||||
@ -34,10 +28,6 @@ interface ServiceWorkerGlobalScope : WorkerGlobalScope {
|
||||
|
||||
// The event.source of these MessageEvents are instances of Client
|
||||
attribute EventHandler onmessage;
|
||||
|
||||
// close() method inherited from WorkerGlobalScope is not exposed.
|
||||
// FIXME(nsm): For now, overridden so it can be a no-op.
|
||||
void close();
|
||||
};
|
||||
|
||||
|
||||
|
@ -21,6 +21,7 @@ interface WorkerGlobalScope : EventTarget {
|
||||
|
||||
readonly attribute WorkerLocation location;
|
||||
|
||||
[Throws]
|
||||
void close();
|
||||
attribute OnErrorEventHandler onerror;
|
||||
|
||||
|
@ -9,10 +9,9 @@
|
||||
|
||||
#include "mozilla/dom/MessageEvent.h"
|
||||
#include "nsGlobalWindow.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "WorkerPrivate.h"
|
||||
|
||||
#include "mozilla/dom/ClientBinding.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
using namespace mozilla::dom::workers;
|
||||
@ -27,6 +26,31 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ServiceWorkerClient)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
ServiceWorkerClientInfo::ServiceWorkerClientInfo(nsIDocument* aDoc)
|
||||
{
|
||||
MOZ_ASSERT(aDoc);
|
||||
MOZ_ASSERT(aDoc->GetWindow());
|
||||
|
||||
nsRefPtr<nsGlobalWindow> outerWindow = static_cast<nsGlobalWindow*>(aDoc->GetWindow());
|
||||
mClientId = outerWindow->WindowID();
|
||||
aDoc->GetURL(mUrl);
|
||||
mVisibilityState = aDoc->VisibilityState();
|
||||
|
||||
ErrorResult result;
|
||||
mFocused = aDoc->HasFocus(result);
|
||||
if (result.Failed()) {
|
||||
NS_WARNING("Failed to get focus information.");
|
||||
}
|
||||
|
||||
if (!outerWindow->IsTopLevelWindow()) {
|
||||
mFrameType = FrameType::Nested;
|
||||
} else if (outerWindow->HadOriginalOpener()) {
|
||||
mFrameType = FrameType::Auxiliary;
|
||||
} else {
|
||||
mFrameType = FrameType::Top_level;
|
||||
}
|
||||
}
|
||||
|
||||
JSObject*
|
||||
ServiceWorkerClient::WrapObject(JSContext* aCx)
|
||||
{
|
||||
@ -55,7 +79,7 @@ public:
|
||||
Run()
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
nsGlobalWindow* window = nsGlobalWindow::GetInnerWindowWithId(mId);
|
||||
nsGlobalWindow* window = nsGlobalWindow::GetOuterWindowWithId(mId);
|
||||
if (!window) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
@ -11,47 +11,78 @@
|
||||
#include "nsWrapperCache.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "mozilla/dom/BindingDeclarations.h"
|
||||
#include "mozilla/dom/ClientBinding.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace workers {
|
||||
|
||||
class ServiceWorkerClient MOZ_FINAL : public nsISupports,
|
||||
public nsWrapperCache
|
||||
class ServiceWorkerClient;
|
||||
class ServiceWorkerWindowClient;
|
||||
|
||||
// Used as a container object for information needed to create
|
||||
// client objects.
|
||||
class ServiceWorkerClientInfo MOZ_FINAL
|
||||
{
|
||||
friend class ServiceWorkerClient;
|
||||
friend class ServiceWorkerWindowClient;
|
||||
|
||||
public:
|
||||
explicit ServiceWorkerClientInfo(nsIDocument* aDoc);
|
||||
|
||||
private:
|
||||
uint64_t mClientId;
|
||||
nsString mUrl;
|
||||
|
||||
// Window Clients
|
||||
VisibilityState mVisibilityState;
|
||||
bool mFocused;
|
||||
FrameType mFrameType;
|
||||
};
|
||||
|
||||
class ServiceWorkerClient : public nsISupports,
|
||||
public nsWrapperCache
|
||||
{
|
||||
public:
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(ServiceWorkerClient)
|
||||
|
||||
ServiceWorkerClient(nsISupports* aOwner, uint64_t aId)
|
||||
ServiceWorkerClient(nsISupports* aOwner,
|
||||
const ServiceWorkerClientInfo& aClientInfo)
|
||||
: mOwner(aOwner),
|
||||
mId(aId)
|
||||
mId(aClientInfo.mClientId),
|
||||
mUrl(aClientInfo.mUrl)
|
||||
{
|
||||
MOZ_ASSERT(aOwner);
|
||||
}
|
||||
|
||||
uint32_t Id() const
|
||||
{
|
||||
return mId;
|
||||
}
|
||||
|
||||
nsISupports* GetParentObject() const
|
||||
nsISupports*
|
||||
GetParentObject() const
|
||||
{
|
||||
return mOwner;
|
||||
}
|
||||
|
||||
void PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
||||
const Optional<Sequence<JS::Value>>& aTransferable,
|
||||
ErrorResult& aRv);
|
||||
void
|
||||
GetUrl(nsAString& aUrl) const
|
||||
{
|
||||
aUrl.Assign(mUrl);
|
||||
}
|
||||
|
||||
void
|
||||
PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
||||
const Optional<Sequence<JS::Value>>& aTransferable,
|
||||
ErrorResult& aRv);
|
||||
|
||||
JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
|
||||
|
||||
private:
|
||||
~ServiceWorkerClient()
|
||||
{
|
||||
}
|
||||
protected:
|
||||
virtual ~ServiceWorkerClient()
|
||||
{ }
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsISupports> mOwner;
|
||||
uint64_t mId;
|
||||
nsString mUrl;
|
||||
};
|
||||
|
||||
} // namespace workers
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "ServiceWorkerClient.h"
|
||||
#include "ServiceWorkerClients.h"
|
||||
#include "ServiceWorkerManager.h"
|
||||
#include "ServiceWorkerWindowClient.h"
|
||||
|
||||
#include "WorkerPrivate.h"
|
||||
#include "WorkerRunnable.h"
|
||||
@ -122,17 +123,17 @@ private:
|
||||
class ResolvePromiseWorkerRunnable MOZ_FINAL : public WorkerRunnable
|
||||
{
|
||||
nsRefPtr<PromiseHolder> mPromiseHolder;
|
||||
nsAutoPtr<nsTArray<uint64_t>> mValue;
|
||||
nsTArray<ServiceWorkerClientInfo> mValue;
|
||||
|
||||
public:
|
||||
ResolvePromiseWorkerRunnable(WorkerPrivate* aWorkerPrivate,
|
||||
PromiseHolder* aPromiseHolder,
|
||||
nsAutoPtr<nsTArray<uint64_t>>& aValue)
|
||||
nsTArray<ServiceWorkerClientInfo>& aValue)
|
||||
: WorkerRunnable(aWorkerPrivate, WorkerThreadModifyBusyCount),
|
||||
mPromiseHolder(aPromiseHolder),
|
||||
mValue(aValue)
|
||||
mPromiseHolder(aPromiseHolder)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
mValue.SwapElements(aValue);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -145,10 +146,10 @@ public:
|
||||
MOZ_ASSERT(promise);
|
||||
|
||||
nsTArray<nsRefPtr<ServiceWorkerClient>> ret;
|
||||
for (size_t i = 0; i < mValue->Length(); i++) {
|
||||
for (size_t i = 0; i < mValue.Length(); i++) {
|
||||
ret.AppendElement(nsRefPtr<ServiceWorkerClient>(
|
||||
new ServiceWorkerClient(promise->GetParentObject(),
|
||||
mValue->ElementAt(i))));
|
||||
new ServiceWorkerWindowClient(promise->GetParentObject(),
|
||||
mValue.ElementAt(i))));
|
||||
}
|
||||
promise->MaybeResolve(ret);
|
||||
|
||||
@ -216,7 +217,7 @@ public:
|
||||
}
|
||||
|
||||
nsRefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
||||
nsAutoPtr<nsTArray<uint64_t>> result(new nsTArray<uint64_t>());
|
||||
nsTArray<ServiceWorkerClientInfo> result;
|
||||
|
||||
swm->GetAllClients(mScope, result);
|
||||
nsRefPtr<ResolvePromiseWorkerRunnable> r =
|
||||
@ -282,3 +283,29 @@ ServiceWorkerClients::MatchAll(const ClientQueryOptions& aOptions,
|
||||
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<Promise>
|
||||
ServiceWorkerClients::OpenWindow(const nsAString& aUrl)
|
||||
{
|
||||
ErrorResult result;
|
||||
nsRefPtr<Promise> promise = Promise::Create(mWorkerScope, result);
|
||||
if (NS_WARN_IF(result.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
promise->MaybeReject(NS_ERROR_NOT_AVAILABLE);
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<Promise>
|
||||
ServiceWorkerClients::Claim()
|
||||
{
|
||||
ErrorResult result;
|
||||
nsRefPtr<Promise> promise = Promise::Create(mWorkerScope, result);
|
||||
if (NS_WARN_IF(result.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
promise->MaybeReject(NS_ERROR_NOT_AVAILABLE);
|
||||
return promise.forget();
|
||||
}
|
||||
|
@ -31,6 +31,12 @@ public:
|
||||
already_AddRefed<Promise>
|
||||
MatchAll(const ClientQueryOptions& aOptions, ErrorResult& aRv);
|
||||
|
||||
already_AddRefed<Promise>
|
||||
OpenWindow(const nsAString& aUrl);
|
||||
|
||||
already_AddRefed<Promise>
|
||||
Claim();
|
||||
|
||||
JSObject*
|
||||
WrapObject(JSContext* aCx) MOZ_OVERRIDE;
|
||||
|
||||
|
@ -181,14 +181,6 @@ ServiceWorkerContainer::GetReady(ErrorResult& aRv)
|
||||
return mReadyPromise;
|
||||
}
|
||||
|
||||
// Testing only.
|
||||
already_AddRefed<Promise>
|
||||
ServiceWorkerContainer::ClearAllServiceWorkerData(ErrorResult& aRv)
|
||||
{
|
||||
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Testing only.
|
||||
void
|
||||
ServiceWorkerContainer::GetScopeForUrl(const nsAString& aUrl,
|
||||
@ -204,14 +196,5 @@ ServiceWorkerContainer::GetScopeForUrl(const nsAString& aUrl,
|
||||
aRv = swm->GetScopeForUrl(aUrl, aScope);
|
||||
}
|
||||
|
||||
// Testing only.
|
||||
void
|
||||
ServiceWorkerContainer::GetControllingWorkerScriptURLForPath(
|
||||
const nsAString& aPath,
|
||||
nsString& aScriptURL,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||
}
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
@ -56,20 +56,10 @@ public:
|
||||
Promise*
|
||||
GetReady(ErrorResult& aRv);
|
||||
|
||||
// Testing only.
|
||||
already_AddRefed<Promise>
|
||||
ClearAllServiceWorkerData(ErrorResult& aRv);
|
||||
|
||||
// Testing only.
|
||||
void
|
||||
GetScopeForUrl(const nsAString& aUrl, nsString& aScope, ErrorResult& aRv);
|
||||
|
||||
// Testing only.
|
||||
void
|
||||
GetControllingWorkerScriptURLForPath(const nsAString& aPath,
|
||||
nsString& aScriptURL,
|
||||
ErrorResult& aRv);
|
||||
|
||||
// DOMEventTargetHelper
|
||||
void DisconnectFromOwner() MOZ_OVERRIDE;
|
||||
|
||||
|
@ -28,7 +28,6 @@ BEGIN_WORKERS_NAMESPACE
|
||||
|
||||
FetchEvent::FetchEvent(EventTarget* aOwner)
|
||||
: Event(aOwner, nullptr, nullptr)
|
||||
, mWindowId(0)
|
||||
, mIsReload(false)
|
||||
, mWaitToRespond(false)
|
||||
{
|
||||
@ -41,11 +40,11 @@ FetchEvent::~FetchEvent()
|
||||
void
|
||||
FetchEvent::PostInit(nsMainThreadPtrHandle<nsIInterceptedChannel>& aChannel,
|
||||
nsMainThreadPtrHandle<ServiceWorker>& aServiceWorker,
|
||||
uint64_t aWindowId)
|
||||
nsAutoPtr<ServiceWorkerClientInfo>& aClientInfo)
|
||||
{
|
||||
mChannel = aChannel;
|
||||
mServiceWorker = aServiceWorker;
|
||||
mWindowId = aWindowId;
|
||||
mClientInfo = aClientInfo;
|
||||
}
|
||||
|
||||
/*static*/ already_AddRefed<FetchEvent>
|
||||
@ -244,10 +243,14 @@ FetchEvent::RespondWith(Promise& aPromise, ErrorResult& aRv)
|
||||
}
|
||||
|
||||
already_AddRefed<ServiceWorkerClient>
|
||||
FetchEvent::Client()
|
||||
FetchEvent::GetClient()
|
||||
{
|
||||
if (!mClient) {
|
||||
mClient = new ServiceWorkerClient(GetParentObject(), mWindowId);
|
||||
if (!mClientInfo) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
mClient = new ServiceWorkerClient(GetParentObject(), *mClientInfo);
|
||||
}
|
||||
nsRefPtr<ServiceWorkerClient> client = mClient;
|
||||
return client.forget();
|
||||
|
@ -32,7 +32,7 @@ class FetchEvent MOZ_FINAL : public Event
|
||||
nsMainThreadPtrHandle<ServiceWorker> mServiceWorker;
|
||||
nsRefPtr<ServiceWorkerClient> mClient;
|
||||
nsRefPtr<Request> mRequest;
|
||||
uint64_t mWindowId;
|
||||
nsAutoPtr<ServiceWorkerClientInfo> mClientInfo;
|
||||
bool mIsReload;
|
||||
bool mWaitToRespond;
|
||||
protected:
|
||||
@ -51,7 +51,7 @@ public:
|
||||
|
||||
void PostInit(nsMainThreadPtrHandle<nsIInterceptedChannel>& aChannel,
|
||||
nsMainThreadPtrHandle<ServiceWorker>& aServiceWorker,
|
||||
uint64_t aWindowId);
|
||||
nsAutoPtr<ServiceWorkerClientInfo>& aClientInfo);
|
||||
|
||||
static already_AddRefed<FetchEvent>
|
||||
Constructor(const GlobalObject& aGlobal,
|
||||
@ -72,7 +72,7 @@ public:
|
||||
}
|
||||
|
||||
already_AddRefed<ServiceWorkerClient>
|
||||
Client();
|
||||
GetClient();
|
||||
|
||||
bool
|
||||
IsReload() const
|
||||
|
@ -2088,7 +2088,7 @@ class FetchEventRunnable : public WorkerRunnable
|
||||
nsMainThreadPtrHandle<ServiceWorker> mServiceWorker;
|
||||
nsTArray<nsCString> mHeaderNames;
|
||||
nsTArray<nsCString> mHeaderValues;
|
||||
uint64_t mWindowId;
|
||||
nsAutoPtr<ServiceWorkerClientInfo> mClientInfo;
|
||||
nsCString mSpec;
|
||||
nsCString mMethod;
|
||||
bool mIsReload;
|
||||
@ -2096,11 +2096,11 @@ public:
|
||||
FetchEventRunnable(WorkerPrivate* aWorkerPrivate,
|
||||
nsMainThreadPtrHandle<nsIInterceptedChannel>& aChannel,
|
||||
nsMainThreadPtrHandle<ServiceWorker>& aServiceWorker,
|
||||
uint64_t aWindowId)
|
||||
nsAutoPtr<ServiceWorkerClientInfo>& aClientInfo)
|
||||
: WorkerRunnable(aWorkerPrivate, WorkerThreadModifyBusyCount)
|
||||
, mInterceptedChannel(aChannel)
|
||||
, mServiceWorker(aServiceWorker)
|
||||
, mWindowId(aWindowId)
|
||||
, mClientInfo(aClientInfo)
|
||||
{
|
||||
MOZ_ASSERT(aWorkerPrivate);
|
||||
}
|
||||
@ -2225,7 +2225,7 @@ private:
|
||||
return false;
|
||||
}
|
||||
|
||||
event->PostInit(mInterceptedChannel, mServiceWorker, mWindowId);
|
||||
event->PostInit(mInterceptedChannel, mServiceWorker, mClientInfo);
|
||||
event->SetTrusted(true);
|
||||
|
||||
nsRefPtr<EventTarget> target = do_QueryObject(aWorkerPrivate->GlobalScope());
|
||||
@ -2250,9 +2250,12 @@ ServiceWorkerManager::DispatchFetchEvent(nsIDocument* aDoc, nsIInterceptedChanne
|
||||
nsresult rv = aChannel->GetIsNavigation(&isNavigation);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAutoPtr<ServiceWorkerClientInfo> clientInfo;
|
||||
|
||||
if (!isNavigation) {
|
||||
MOZ_ASSERT(aDoc);
|
||||
rv = GetDocumentController(aDoc->GetInnerWindow(), getter_AddRefs(serviceWorker));
|
||||
clientInfo = new ServiceWorkerClientInfo(aDoc);
|
||||
} else {
|
||||
nsCOMPtr<nsIChannel> internalChannel;
|
||||
rv = aChannel->GetChannel(getter_AddRefs(internalChannel));
|
||||
@ -2282,14 +2285,13 @@ ServiceWorkerManager::DispatchFetchEvent(nsIDocument* aDoc, nsIInterceptedChanne
|
||||
nsMainThreadPtrHandle<nsIInterceptedChannel> handle(
|
||||
new nsMainThreadPtrHolder<nsIInterceptedChannel>(aChannel, false));
|
||||
|
||||
uint64_t windowId = aDoc ? aDoc->GetInnerWindow()->WindowID() : 0;
|
||||
|
||||
nsRefPtr<ServiceWorker> sw = static_cast<ServiceWorker*>(serviceWorker.get());
|
||||
nsMainThreadPtrHandle<ServiceWorker> serviceWorkerHandle(
|
||||
new nsMainThreadPtrHolder<ServiceWorker>(sw));
|
||||
|
||||
// clientInfo is null if we don't have a controlled document
|
||||
nsRefPtr<FetchEventRunnable> event =
|
||||
new FetchEventRunnable(sw->GetWorkerPrivate(), handle, serviceWorkerHandle, windowId);
|
||||
new FetchEventRunnable(sw->GetWorkerPrivate(), handle, serviceWorkerHandle, clientInfo);
|
||||
rv = event->Init();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
@ -2519,14 +2521,14 @@ namespace {
|
||||
class MOZ_STACK_CLASS FilterRegistrationData
|
||||
{
|
||||
public:
|
||||
FilterRegistrationData(nsTArray<uint64_t>* aDocuments,
|
||||
ServiceWorkerRegistrationInfo* aRegistration)
|
||||
FilterRegistrationData(nsTArray<ServiceWorkerClientInfo>& aDocuments,
|
||||
ServiceWorkerRegistrationInfo* aRegistration)
|
||||
: mDocuments(aDocuments),
|
||||
mRegistration(aRegistration)
|
||||
{
|
||||
}
|
||||
|
||||
nsTArray<uint64_t>* mDocuments;
|
||||
nsTArray<ServiceWorkerClientInfo>& mDocuments;
|
||||
nsRefPtr<ServiceWorkerRegistrationInfo> mRegistration;
|
||||
};
|
||||
|
||||
@ -2539,12 +2541,16 @@ EnumControlledDocuments(nsISupports* aKey,
|
||||
if (data->mRegistration != aRegistration) {
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocument> document = do_QueryInterface(aKey);
|
||||
if (!document || !document->GetInnerWindow()) {
|
||||
|
||||
if (!document || !document->GetWindow()) {
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
data->mDocuments->AppendElement(document->GetInnerWindow()->WindowID());
|
||||
ServiceWorkerClientInfo clientInfo(document);
|
||||
data->mDocuments.AppendElement(clientInfo);
|
||||
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
@ -2591,7 +2597,7 @@ FireControllerChangeOnMatchingDocument(nsISupports* aKey,
|
||||
|
||||
void
|
||||
ServiceWorkerManager::GetAllClients(const nsCString& aScope,
|
||||
nsTArray<uint64_t>* aControlledDocuments)
|
||||
nsTArray<ServiceWorkerClientInfo>& aControlledDocuments)
|
||||
{
|
||||
nsRefPtr<ServiceWorkerRegistrationInfo> registration = GetRegistration(aScope);
|
||||
|
||||
|
@ -43,6 +43,7 @@ class ServiceWorkerRegistration;
|
||||
namespace workers {
|
||||
|
||||
class ServiceWorker;
|
||||
class ServiceWorkerClientInfo;
|
||||
class ServiceWorkerInfo;
|
||||
|
||||
class ServiceWorkerJobQueue;
|
||||
@ -379,7 +380,7 @@ public:
|
||||
|
||||
void
|
||||
GetAllClients(const nsCString& aScope,
|
||||
nsTArray<uint64_t>* aControlledDocuments);
|
||||
nsTArray<ServiceWorkerClientInfo>& aControlledDocuments);
|
||||
|
||||
static already_AddRefed<ServiceWorkerManager>
|
||||
GetInstance();
|
||||
|
34
dom/workers/ServiceWorkerWindowClient.cpp
Normal file
34
dom/workers/ServiceWorkerWindowClient.cpp
Normal file
@ -0,0 +1,34 @@
|
||||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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 "ServiceWorkerWindowClient.h"
|
||||
|
||||
#include "mozilla/dom/ClientBinding.h"
|
||||
|
||||
using namespace mozilla::dom;
|
||||
using namespace mozilla::dom::workers;
|
||||
|
||||
JSObject*
|
||||
ServiceWorkerWindowClient::WrapObject(JSContext* aCx)
|
||||
{
|
||||
return WindowClientBinding::Wrap(aCx, this);
|
||||
}
|
||||
|
||||
already_AddRefed<Promise>
|
||||
ServiceWorkerWindowClient::Focus() const
|
||||
{
|
||||
ErrorResult result;
|
||||
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetParentObject());
|
||||
MOZ_ASSERT(global);
|
||||
|
||||
nsRefPtr<Promise> promise = Promise::Create(global, result);
|
||||
if (NS_WARN_IF(result.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
promise->MaybeReject(NS_ERROR_NOT_AVAILABLE);
|
||||
return promise.forget();
|
||||
}
|
65
dom/workers/ServiceWorkerWindowClient.h
Normal file
65
dom/workers/ServiceWorkerWindowClient.h
Normal file
@ -0,0 +1,65 @@
|
||||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/.
|
||||
*/
|
||||
|
||||
#ifndef mozilla_dom_workers_serviceworkerwindowclient_h
|
||||
#define mozilla_dom_workers_serviceworkerwindowclient_h
|
||||
|
||||
#include "ServiceWorkerClient.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace workers {
|
||||
|
||||
class ServiceWorkerWindowClient MOZ_FINAL : public ServiceWorkerClient
|
||||
{
|
||||
public:
|
||||
ServiceWorkerWindowClient(nsISupports* aOwner,
|
||||
const ServiceWorkerClientInfo& aClientInfo)
|
||||
: ServiceWorkerClient(aOwner, aClientInfo),
|
||||
mVisibilityState(aClientInfo.mVisibilityState),
|
||||
mFocused(aClientInfo.mFocused),
|
||||
mFrameType(aClientInfo.mFrameType)
|
||||
{
|
||||
}
|
||||
|
||||
virtual JSObject*
|
||||
WrapObject(JSContext* aCx) MOZ_OVERRIDE;
|
||||
|
||||
mozilla::dom::VisibilityState
|
||||
VisibilityState() const
|
||||
{
|
||||
return mVisibilityState;
|
||||
}
|
||||
|
||||
bool
|
||||
Focused() const
|
||||
{
|
||||
return mFocused;
|
||||
}
|
||||
|
||||
mozilla::dom::FrameType
|
||||
FrameType() const
|
||||
{
|
||||
return mFrameType;
|
||||
}
|
||||
|
||||
already_AddRefed<Promise>
|
||||
Focus() const;
|
||||
|
||||
private:
|
||||
~ServiceWorkerWindowClient()
|
||||
{ }
|
||||
|
||||
mozilla::dom::VisibilityState mVisibilityState;
|
||||
bool mFocused;
|
||||
mozilla::dom::FrameType mFrameType;
|
||||
};
|
||||
|
||||
} // namespace workers
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_workers_serviceworkerwindowclient_h
|
@ -171,11 +171,15 @@ WorkerGlobalScope::GetExistingNavigator() const
|
||||
}
|
||||
|
||||
void
|
||||
WorkerGlobalScope::Close(JSContext* aCx)
|
||||
WorkerGlobalScope::Close(JSContext* aCx, ErrorResult& aRv)
|
||||
{
|
||||
mWorkerPrivate->AssertIsOnWorkerThread();
|
||||
|
||||
mWorkerPrivate->CloseInternal(aCx);
|
||||
if (mWorkerPrivate->IsServiceWorker()) {
|
||||
aRv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR);
|
||||
} else {
|
||||
mWorkerPrivate->CloseInternal(aCx);
|
||||
}
|
||||
}
|
||||
|
||||
OnErrorEventHandlerNonNull*
|
||||
|
@ -98,7 +98,7 @@ public:
|
||||
GetExistingNavigator() const;
|
||||
|
||||
void
|
||||
Close(JSContext* aCx);
|
||||
Close(JSContext* aCx, ErrorResult& aRv);
|
||||
|
||||
OnErrorEventHandlerNonNull*
|
||||
GetOnerror();
|
||||
@ -218,12 +218,6 @@ public:
|
||||
aScope = mScope;
|
||||
}
|
||||
|
||||
void
|
||||
Close() const
|
||||
{
|
||||
// no-op close.
|
||||
}
|
||||
|
||||
void
|
||||
Update();
|
||||
|
||||
|
@ -34,6 +34,7 @@ EXPORTS.mozilla.dom.workers.bindings += [
|
||||
'ServiceWorker.h',
|
||||
'ServiceWorkerClient.h',
|
||||
'ServiceWorkerClients.h',
|
||||
'ServiceWorkerWindowClient.h',
|
||||
'SharedWorker.h',
|
||||
'URL.h',
|
||||
'WorkerFeature.h',
|
||||
@ -69,6 +70,7 @@ UNIFIED_SOURCES += [
|
||||
'ServiceWorkerManager.cpp',
|
||||
'ServiceWorkerRegistrar.cpp',
|
||||
'ServiceWorkerRegistration.cpp',
|
||||
'ServiceWorkerWindowClient.cpp',
|
||||
'SharedWorker.cpp',
|
||||
'URL.cpp',
|
||||
'WorkerDebuggerManager.cpp',
|
||||
|
@ -11,10 +11,6 @@ onmessage = function(event) {
|
||||
|
||||
postMessage({event: 'trace without function', status: true, last : false});
|
||||
|
||||
for (var i = 0; i < 10; ++i) {
|
||||
console.what('1', 123, 321);
|
||||
}
|
||||
|
||||
for (var i = 0; i < 10; ++i) {
|
||||
console.log(i, i, i);
|
||||
}
|
||||
@ -81,7 +77,6 @@ function nextSteps(event) {
|
||||
namelessTimer();
|
||||
|
||||
var str = "Test Message."
|
||||
console.foobar(str); // if this throws, we don't execute following funcs
|
||||
console.log(str);
|
||||
console.info(str);
|
||||
console.warn(str);
|
||||
@ -91,6 +86,8 @@ function nextSteps(event) {
|
||||
console.assert(false, str);
|
||||
console.profile(str);
|
||||
console.profileEnd(str);
|
||||
console.timeStamp();
|
||||
console.clear();
|
||||
postMessage({event: '4 messages', status: true, last : false});
|
||||
|
||||
// Recursive:
|
||||
|
19
dom/workers/test/serviceworkers/close_test.js
Normal file
19
dom/workers/test/serviceworkers/close_test.js
Normal file
@ -0,0 +1,19 @@
|
||||
function ok(v, msg) {
|
||||
client.postMessage({status: "ok", result: !!v, message: msg});
|
||||
}
|
||||
|
||||
var client;
|
||||
onmessage = function(e) {
|
||||
if (e.data.message == "start") {
|
||||
self.clients.matchAll().then(function(clients) {
|
||||
client = clients[0];
|
||||
try {
|
||||
close();
|
||||
ok(false, "close() should throw");
|
||||
} catch (e) {
|
||||
ok(e.name === "InvalidAccessError", "close() should throw InvalidAccessError");
|
||||
}
|
||||
client.postMessage({status: "done"});
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Bug 1058311 - controlled page</title>
|
||||
<script class="testbody" type="text/javascript">
|
||||
var frameType = "none";
|
||||
var testWindow = parent;
|
||||
|
||||
if (parent != window) {
|
||||
frameType = "nested";
|
||||
} else if (opener) {
|
||||
frameType = "auxiliary";
|
||||
testWindow = opener;
|
||||
} else if (parent != window) {
|
||||
frameType = "top-level";
|
||||
} else {
|
||||
postResult(false, "Unexpected frameType");
|
||||
}
|
||||
|
||||
window.onload = function() {
|
||||
navigator.serviceWorker.ready.then(function(swr) {
|
||||
swr.active.postMessage("Start");
|
||||
});
|
||||
}
|
||||
|
||||
function postResult(result, msg) {
|
||||
response = {
|
||||
result: result,
|
||||
message: msg
|
||||
};
|
||||
|
||||
testWindow.postMessage(response, "*");
|
||||
}
|
||||
|
||||
navigator.serviceWorker.onmessage = function(msg) {
|
||||
// worker message;
|
||||
result = msg.data.url == window.location;
|
||||
postResult(result, "Client url test");
|
||||
|
||||
result = msg.data.visibilityState === document.visibilityState;
|
||||
postResult(result, "Client visibility test. expected=" +document.visibilityState);
|
||||
|
||||
result = msg.data.focused === document.hasFocus();
|
||||
postResult(result, "Client focus test. expected=" + document.hasFocus());
|
||||
|
||||
result = msg.data.frameType === frameType;
|
||||
postResult(result, "Client frameType test. expected=" + frameType);
|
||||
|
||||
postResult(true, "DONE");
|
||||
window.close();
|
||||
};
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,19 @@
|
||||
onmessage = function(e) {
|
||||
dump("MatchAllPropertiesWorker:" + e.data + "\n");
|
||||
self.clients.matchAll().then(function(res) {
|
||||
if (!res.length) {
|
||||
dump("ERROR: no clients are currently controlled.\n");
|
||||
}
|
||||
|
||||
for (i = 0; i < res.length; i++) {
|
||||
client = res[i];
|
||||
response = {
|
||||
url: client.url,
|
||||
visibilityState: client.visibilityState,
|
||||
focused: client.focused,
|
||||
frameType: client.frameType
|
||||
};
|
||||
client.postMessage(response);
|
||||
}
|
||||
});
|
||||
}
|
6
dom/workers/test/serviceworkers/message_receiver.html
Normal file
6
dom/workers/test/serviceworkers/message_receiver.html
Normal file
@ -0,0 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
<script>
|
||||
navigator.serviceWorker.onmessage = function(e) {
|
||||
window.parent.postMessage(e.data, "*");
|
||||
};
|
||||
</script>
|
@ -24,6 +24,12 @@ support-files =
|
||||
fetch/index.html
|
||||
fetch/fetch_worker_script.js
|
||||
fetch/fetch_tests.js
|
||||
match_all_properties_worker.js
|
||||
match_all_clients/match_all_controlled.html
|
||||
test_serviceworker_interfaces.js
|
||||
serviceworker_wrapper.js
|
||||
message_receiver.html
|
||||
close_test.js
|
||||
|
||||
[test_unregister.html]
|
||||
skip-if = true # Bug 1133805
|
||||
@ -33,6 +39,7 @@ skip-if = true # Bug 1133805
|
||||
[test_install_event.html]
|
||||
[test_navigator.html]
|
||||
[test_scopes.html]
|
||||
skip-if = true # Bug 1037739
|
||||
[test_controller.html]
|
||||
[test_workerUpdate.html]
|
||||
skip-if = true # Bug 1133805
|
||||
@ -40,3 +47,6 @@ skip-if = true # Bug 1133805
|
||||
skip-if = true # Bug 1133805
|
||||
[test_post_message.html]
|
||||
[test_post_message_advanced.html]
|
||||
[test_match_all_client_properties.html]
|
||||
[test_close.html]
|
||||
[test_serviceworker_interfaces.html]
|
||||
|
131
dom/workers/test/serviceworkers/serviceworker_wrapper.js
Normal file
131
dom/workers/test/serviceworkers/serviceworker_wrapper.js
Normal file
@ -0,0 +1,131 @@
|
||||
// Any copyright is dedicated to the Public Domain.
|
||||
// http://creativecommons.org/publicdomain/zero/1.0/
|
||||
//
|
||||
// ServiceWorker equivalent of worker_wrapper.js.
|
||||
|
||||
var client;
|
||||
|
||||
function ok(a, msg) {
|
||||
dump("OK: " + !!a + " => " + a + ": " + msg + "\n");
|
||||
client.postMessage({type: 'status', status: !!a, msg: a + ": " + msg });
|
||||
}
|
||||
|
||||
function is(a, b, msg) {
|
||||
dump("IS: " + (a===b) + " => " + a + " | " + b + ": " + msg + "\n");
|
||||
client.postMessage({type: 'status', status: a === b, msg: a + " === " + b + ": " + msg });
|
||||
}
|
||||
|
||||
function workerTestArrayEquals(a, b) {
|
||||
if (!Array.isArray(a) || !Array.isArray(b) || a.length != b.length) {
|
||||
return false;
|
||||
}
|
||||
for (var i = 0, n = a.length; i < n; ++i) {
|
||||
if (a[i] !== b[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function workerTestDone() {
|
||||
client.postMessage({ type: 'finish' });
|
||||
}
|
||||
|
||||
function workerTestGetPrefs(prefs, cb) {
|
||||
addEventListener('message', function workerTestGetPrefsCB(e) {
|
||||
if (e.data.type != 'returnPrefs' ||
|
||||
!workerTestArrayEquals(prefs, e.data.prefs)) {
|
||||
return;
|
||||
}
|
||||
removeEventListener('message', workerTestGetPrefsCB);
|
||||
cb(e.data.result);
|
||||
});
|
||||
client.postMessage({
|
||||
type: 'getPrefs',
|
||||
prefs: prefs
|
||||
});
|
||||
}
|
||||
|
||||
function workerTestGetPermissions(permissions, cb) {
|
||||
addEventListener('message', function workerTestGetPermissionsCB(e) {
|
||||
if (e.data.type != 'returnPermissions' ||
|
||||
!workerTestArrayEquals(permissions, e.data.permissions)) {
|
||||
return;
|
||||
}
|
||||
removeEventListener('message', workerTestGetPermissionsCB);
|
||||
cb(e.data.result);
|
||||
});
|
||||
client.postMessage({
|
||||
type: 'getPermissions',
|
||||
permissions: permissions
|
||||
});
|
||||
}
|
||||
|
||||
function workerTestGetVersion(cb) {
|
||||
addEventListener('message', function workerTestGetVersionCB(e) {
|
||||
if (e.data.type !== 'returnVersion') {
|
||||
return;
|
||||
}
|
||||
removeEventListener('message', workerTestGetVersionCB);
|
||||
cb(e.data.result);
|
||||
});
|
||||
client.postMessage({
|
||||
type: 'getVersion'
|
||||
});
|
||||
}
|
||||
|
||||
function workerTestGetUserAgent(cb) {
|
||||
addEventListener('message', function workerTestGetUserAgentCB(e) {
|
||||
if (e.data.type !== 'returnUserAgent') {
|
||||
return;
|
||||
}
|
||||
removeEventListener('message', workerTestGetUserAgentCB);
|
||||
cb(e.data.result);
|
||||
});
|
||||
client.postMessage({
|
||||
type: 'getUserAgent'
|
||||
});
|
||||
}
|
||||
|
||||
function workerTestGetOSCPU(cb) {
|
||||
addEventListener('message', function workerTestGetOSCPUCB(e) {
|
||||
if (e.data.type !== 'returnOSCPU') {
|
||||
return;
|
||||
}
|
||||
removeEventListener('message', workerTestGetOSCPUCB);
|
||||
cb(e.data.result);
|
||||
});
|
||||
client.postMessage({
|
||||
type: 'getOSCPU'
|
||||
});
|
||||
}
|
||||
|
||||
function workerTestGetIsB2G(cb) {
|
||||
addEventListener('message', function workerTestGetIsB2GCB(e) {
|
||||
if (e.data.type !== 'returnIsB2G') {
|
||||
return;
|
||||
}
|
||||
removeEventListener('message', workerTestGetIsB2GCB);
|
||||
cb(e.data.result);
|
||||
});
|
||||
client.postMessage({
|
||||
type: 'getIsB2G'
|
||||
});
|
||||
}
|
||||
|
||||
addEventListener('message', function workerWrapperOnMessage(e) {
|
||||
removeEventListener('message', workerWrapperOnMessage);
|
||||
var data = e.data;
|
||||
self.clients.matchAll().then(function(clients) {
|
||||
client = clients[0];
|
||||
try {
|
||||
importScripts(data.script);
|
||||
} catch(e) {
|
||||
client.postMessage({
|
||||
type: 'status',
|
||||
status: false,
|
||||
msg: 'worker failed to import ' + data.script + "; error: " + e.message
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
69
dom/workers/test/serviceworkers/test_close.html
Normal file
69
dom/workers/test/serviceworkers/test_close.html
Normal file
@ -0,0 +1,69 @@
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Bug 1131353 - test WorkerGlobalScope.close() on service workers</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
<iframe></iframe>
|
||||
</div>
|
||||
<pre id="test"></pre>
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
var iframe;
|
||||
function runTest() {
|
||||
navigator.serviceWorker.register("close_test.js", {scope: "."})
|
||||
.then(function(registration) {
|
||||
if (registration.installing) {
|
||||
registration.installing.onstatechange = function(e) {
|
||||
setupSW(registration);
|
||||
e.target.onstatechange = null;
|
||||
};
|
||||
} else {
|
||||
setupSW(registration);
|
||||
}
|
||||
});
|
||||
|
||||
function setupSW(registration) {
|
||||
var worker = registration.waiting ||
|
||||
registration.active;
|
||||
var iframe = document.createElement("iframe");
|
||||
iframe.src = "message_receiver.html";
|
||||
iframe.onload = function() {
|
||||
worker.postMessage({ message: "start" });
|
||||
};
|
||||
document.body.appendChild(iframe);
|
||||
}
|
||||
|
||||
window.onmessage = function(e) {
|
||||
if (e.data.status == "ok") {
|
||||
ok(e.data.result, e.data.message);
|
||||
} else if (e.data.status == "done") {
|
||||
navigator.serviceWorker.getRegistration().then(function(registration) {
|
||||
registration.unregister().then(function() {
|
||||
SimpleTest.finish();
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
onload = function() {
|
||||
SpecialPowers.pushPrefEnv({"set": [
|
||||
["dom.serviceWorkers.exemptFromPerDomainMax", true],
|
||||
["dom.serviceWorkers.enabled", true],
|
||||
["dom.serviceWorkers.testing.enabled", true],
|
||||
]}, runTest);
|
||||
};
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,93 @@
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Bug 1058311 - Test matchAll clients properties </title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
<script class="testbody" type="text/javascript">
|
||||
var registration;
|
||||
var clientURL = "match_all_clients/match_all_controlled.html";
|
||||
function start() {
|
||||
return navigator.serviceWorker.register("match_all_properties_worker.js",
|
||||
{ scope: "./match_all_clients/" })
|
||||
.then((swr) => registration = swr);
|
||||
}
|
||||
|
||||
function unregister() {
|
||||
return registration.unregister().then(function(result) {
|
||||
ok(result, "Unregister should return true.");
|
||||
});
|
||||
}
|
||||
|
||||
function getMessageListener() {
|
||||
return new Promise(function(res, rej) {
|
||||
window.onmessage = function(e) {
|
||||
if (e.data.message === undefined) {
|
||||
info("rejecting promise");
|
||||
rej();
|
||||
return;
|
||||
}
|
||||
|
||||
ok(e.data.result, e.data.message);
|
||||
|
||||
if (!e.data.result) {
|
||||
rej();
|
||||
}
|
||||
if (e.data.message == "DONE") {
|
||||
info("DONE from: " + e.source);
|
||||
res();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function testNestedWindow() {
|
||||
var p = getMessageListener();
|
||||
|
||||
var content = document.getElementById("content");
|
||||
ok(content, "Parent exists.");
|
||||
|
||||
iframe = document.createElement("iframe");
|
||||
|
||||
content.appendChild(iframe);
|
||||
iframe.setAttribute('src', clientURL);
|
||||
|
||||
return p.then(() => content.removeChild(iframe));
|
||||
}
|
||||
|
||||
function testAuxiliaryWindow() {
|
||||
var p = getMessageListener();
|
||||
var w = window.open(clientURL);
|
||||
|
||||
return p.then(() => w.close());
|
||||
}
|
||||
|
||||
function runTest() {
|
||||
info("catalin");
|
||||
info(window.opener == undefined);
|
||||
start()
|
||||
.then(testAuxiliaryWindow)
|
||||
.then(testNestedWindow)
|
||||
.catch(function(e) {
|
||||
ok(false, "Some test failed with error " + e);
|
||||
}).then(SimpleTest.finish);
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPrefEnv({"set": [
|
||||
["dom.serviceWorkers.enabled", true],
|
||||
["dom.serviceWorkers.testing.enabled", true]
|
||||
]}, runTest);
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,113 @@
|
||||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
- http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Validate Interfaces Exposed to Service Workers</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
<script type="text/javascript" src="../worker_driver.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
function setupSW(registration) {
|
||||
var worker = registration.waiting ||
|
||||
registration.active;
|
||||
window.onmessage = function(event) {
|
||||
if (event.data.type == 'finish') {
|
||||
registration.unregister().then(function(success) {
|
||||
ok(success, "The service worker should be unregistered successfully");
|
||||
|
||||
SimpleTest.finish();
|
||||
});
|
||||
} else if (event.data.type == 'status') {
|
||||
ok(event.data.status, event.data.msg);
|
||||
|
||||
} else if (event.data.type == 'getPrefs') {
|
||||
var result = {};
|
||||
event.data.prefs.forEach(function(pref) {
|
||||
result[pref] = SpecialPowers.Services.prefs.getBoolPref(pref);
|
||||
});
|
||||
worker.postMessage({
|
||||
type: 'returnPrefs',
|
||||
prefs: event.data.prefs,
|
||||
result: result
|
||||
});
|
||||
|
||||
} else if (event.data.type == 'getPermissions') {
|
||||
var result = {};
|
||||
event.data.permissions.forEach(function(permission) {
|
||||
result[permission] = SpecialPowers.hasPermission(permission, window.document);
|
||||
});
|
||||
worker.postMessage({
|
||||
type: 'returnPermissions',
|
||||
permissions: event.data.permissions,
|
||||
result: result
|
||||
});
|
||||
|
||||
} else if (event.data.type == 'getVersion') {
|
||||
var result = SpecialPowers.Cc['@mozilla.org/xre/app-info;1'].getService(SpecialPowers.Ci.nsIXULAppInfo).version;
|
||||
worker.postMessage({
|
||||
type: 'returnVersion',
|
||||
result: result
|
||||
});
|
||||
|
||||
} else if (event.data.type == 'getUserAgent') {
|
||||
worker.postMessage({
|
||||
type: 'returnUserAgent',
|
||||
result: navigator.userAgent
|
||||
});
|
||||
} else if (event.data.type == 'getOSCPU') {
|
||||
worker.postMessage({
|
||||
type: 'returnOSCPU',
|
||||
result: navigator.oscpu
|
||||
});
|
||||
} else if (event.data.type == 'getIsB2G') {
|
||||
worker.postMessage({
|
||||
type: 'returnIsB2G',
|
||||
result: SpecialPowers.isB2G
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
worker.onerror = function(event) {
|
||||
ok(false, 'Worker had an error: ' + event.data);
|
||||
SimpleTest.finish();
|
||||
};
|
||||
|
||||
var iframe = document.createElement("iframe");
|
||||
iframe.src = "message_receiver.html";
|
||||
iframe.onload = function() {
|
||||
worker.postMessage({ script: "test_serviceworker_interfaces.js" });
|
||||
};
|
||||
document.body.appendChild(iframe);
|
||||
}
|
||||
|
||||
function runTest() {
|
||||
navigator.serviceWorker.register("serviceworker_wrapper.js", {scope: "."})
|
||||
.then(function(registration) {
|
||||
if (registration.installing) {
|
||||
registration.installing.onstatechange = function(e) {
|
||||
setupSW(registration);
|
||||
e.target.onstatechange = null;
|
||||
};
|
||||
} else {
|
||||
setupSW(registration);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
onload = function() {
|
||||
SpecialPowers.pushPrefEnv({"set": [
|
||||
["dom.serviceWorkers.exemptFromPerDomainMax", true],
|
||||
["dom.serviceWorkers.enabled", true],
|
||||
["dom.serviceWorkers.testing.enabled", true],
|
||||
["dom.fetch.enabled", true],
|
||||
["dom.caches.enabled", true]
|
||||
]}, runTest);
|
||||
};
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
280
dom/workers/test/serviceworkers/test_serviceworker_interfaces.js
Normal file
280
dom/workers/test/serviceworkers/test_serviceworker_interfaces.js
Normal file
@ -0,0 +1,280 @@
|
||||
// This is a list of all interfaces that are exposed to workers.
|
||||
// Please only add things to this list with great care and proper review
|
||||
// from the associated module peers.
|
||||
|
||||
// This file lists global interfaces we want exposed and verifies they
|
||||
// are what we intend. Each entry in the arrays below can either be a
|
||||
// simple string with the interface name, or an object with a 'name'
|
||||
// property giving the interface name as a string, and additional
|
||||
// properties which qualify the exposure of that interface. For example:
|
||||
//
|
||||
// [
|
||||
// "AGlobalInterface",
|
||||
// {name: "ExperimentalThing", release: false},
|
||||
// {name: "OptionalThing", pref: "some.thing.enabled"},
|
||||
// ];
|
||||
//
|
||||
// See createInterfaceMap() below for a complete list of properties.
|
||||
|
||||
// IMPORTANT: Do not change this list without review from
|
||||
// a JavaScript Engine peer!
|
||||
var ecmaGlobals =
|
||||
[
|
||||
"Array",
|
||||
"ArrayBuffer",
|
||||
"Boolean",
|
||||
"DataView",
|
||||
"Date",
|
||||
"Error",
|
||||
"EvalError",
|
||||
"Float32Array",
|
||||
"Float64Array",
|
||||
"Function",
|
||||
"Infinity",
|
||||
"Int16Array",
|
||||
"Int32Array",
|
||||
"Int8Array",
|
||||
"InternalError",
|
||||
{name: "Intl", b2g: false, android: false},
|
||||
"Iterator",
|
||||
"JSON",
|
||||
"Map",
|
||||
"Math",
|
||||
"NaN",
|
||||
"Number",
|
||||
"Object",
|
||||
"Proxy",
|
||||
"RangeError",
|
||||
"ReferenceError",
|
||||
"RegExp",
|
||||
"Set",
|
||||
{name: "SharedArrayBuffer", nightly: true},
|
||||
{name: "SharedInt8Array", nightly: true},
|
||||
{name: "SharedUint8Array", nightly: true},
|
||||
{name: "SharedUint8ClampedArray", nightly: true},
|
||||
{name: "SharedInt16Array", nightly: true},
|
||||
{name: "SharedUint16Array", nightly: true},
|
||||
{name: "SharedInt32Array", nightly: true},
|
||||
{name: "SharedUint32Array", nightly: true},
|
||||
{name: "SharedFloat32Array", nightly: true},
|
||||
{name: "SharedFloat64Array", nightly: true},
|
||||
{name: "SIMD", nightly: true},
|
||||
{name: "Atomics", nightly: true},
|
||||
"StopIteration",
|
||||
"String",
|
||||
"Symbol",
|
||||
"SyntaxError",
|
||||
{name: "TypedObject", nightly: true},
|
||||
"TypeError",
|
||||
"Uint16Array",
|
||||
"Uint32Array",
|
||||
"Uint8Array",
|
||||
"Uint8ClampedArray",
|
||||
"URIError",
|
||||
"WeakMap",
|
||||
"WeakSet",
|
||||
];
|
||||
// IMPORTANT: Do not change the list above without review from
|
||||
// a JavaScript Engine peer!
|
||||
|
||||
// IMPORTANT: Do not change the list below without review from a DOM peer!
|
||||
var interfaceNamesInGlobalScope =
|
||||
[
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"Blob",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{ name: "BroadcastChannel", pref: "dom.broadcastChannel.enabled" },
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{ name: "Cache", pref: "dom.caches.enabled" },
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{ name: "CacheStorage", pref: "dom.caches.enabled" },
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"Client",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"Clients",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{ name: "DataStore", b2g: true },
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{ name: "DataStoreCursor", b2g: true },
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"DOMError",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"DOMException",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"DOMStringList",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"Event",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"EventTarget",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"ExtendableEvent",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"FetchEvent",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"File",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"FileReaderSync",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{ name: "Headers", pref: "dom.fetch.enabled" },
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"IDBCursor",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"IDBDatabase",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"IDBFactory",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"IDBIndex",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"IDBKeyRange",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"IDBObjectStore",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"IDBOpenDBRequest",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"IDBRequest",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"IDBTransaction",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"IDBVersionChangeEvent",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"ImageData",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"InstallEvent",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"MessageEvent",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"MessagePort",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"Performance",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"Promise",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"Request",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"Response",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"ServiceWorker",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"ServiceWorkerGlobalScope",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"TextDecoder",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"TextEncoder",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"XMLHttpRequest",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"XMLHttpRequestEventTarget",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"XMLHttpRequestUpload",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"URL",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"URLSearchParams",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{ name: "WebSocket", pref: "dom.workers.websocket.enabled" },
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"WindowClient",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"WorkerGlobalScope",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"WorkerLocation",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"WorkerNavigator",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
];
|
||||
// IMPORTANT: Do not change the list above without review from a DOM peer!
|
||||
|
||||
function createInterfaceMap(prefMap, permissionMap, version, userAgent, isB2G) {
|
||||
var isNightly = version.endsWith("a1");
|
||||
var isRelease = !version.contains("a");
|
||||
var isDesktop = !/Mobile|Tablet/.test(userAgent);
|
||||
var isAndroid = !!navigator.userAgent.contains("Android");
|
||||
|
||||
var interfaceMap = {};
|
||||
|
||||
function addInterfaces(interfaces)
|
||||
{
|
||||
for (var entry of interfaces) {
|
||||
if (typeof(entry) === "string") {
|
||||
interfaceMap[entry] = true;
|
||||
} else if ((entry.nightly === !isNightly) ||
|
||||
(entry.desktop === !isDesktop) ||
|
||||
(entry.android === !isAndroid) ||
|
||||
(entry.b2g === !isB2G) ||
|
||||
(entry.release === !isRelease) ||
|
||||
(entry.pref && !prefMap[entry.pref]) ||
|
||||
(entry.permission && !permissionMap[entry.permission])) {
|
||||
interfaceMap[entry.name] = false;
|
||||
} else {
|
||||
interfaceMap[entry.name] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
addInterfaces(ecmaGlobals);
|
||||
addInterfaces(interfaceNamesInGlobalScope);
|
||||
|
||||
return interfaceMap;
|
||||
}
|
||||
|
||||
function runTest(prefMap, permissionMap, version, userAgent, isB2G) {
|
||||
var interfaceMap = createInterfaceMap(prefMap, permissionMap, version, userAgent, isB2G);
|
||||
for (var name of Object.getOwnPropertyNames(self)) {
|
||||
// An interface name should start with an upper case character.
|
||||
if (!/^[A-Z]/.test(name)) {
|
||||
continue;
|
||||
}
|
||||
ok(interfaceMap[name],
|
||||
"If this is failing: DANGER, are you sure you want to expose the new interface " + name +
|
||||
" to all webpages as a property on the service worker? Do not make a change to this file without a " +
|
||||
" review from a DOM peer for that specific change!!! (or a JS peer for changes to ecmaGlobals)");
|
||||
delete interfaceMap[name];
|
||||
}
|
||||
for (var name of Object.keys(interfaceMap)) {
|
||||
ok(name in self === interfaceMap[name],
|
||||
name + " should " + (interfaceMap[name] ? "" : " NOT") + " be defined on the global scope");
|
||||
if (!interfaceMap[name]) {
|
||||
delete interfaceMap[name];
|
||||
}
|
||||
}
|
||||
is(Object.keys(interfaceMap).length, 0,
|
||||
"The following interface(s) are not enumerated: " + Object.keys(interfaceMap).join(", "));
|
||||
}
|
||||
|
||||
function appendPrefs(prefs, interfaces) {
|
||||
for (var entry of interfaces) {
|
||||
if (entry.pref !== undefined && prefs.indexOf(entry.pref) === -1) {
|
||||
prefs.push(entry.pref);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var prefs = [];
|
||||
appendPrefs(prefs, ecmaGlobals);
|
||||
appendPrefs(prefs, interfaceNamesInGlobalScope);
|
||||
|
||||
function appendPermissions(permissions, interfaces) {
|
||||
for (var entry of interfaces) {
|
||||
if (entry.permission !== undefined &&
|
||||
permissions.indexOf(entry.permission) === -1) {
|
||||
permissions.push(entry.permission);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var permissions = [];
|
||||
appendPermissions(permissions, ecmaGlobals);
|
||||
appendPermissions(permissions, interfaceNamesInGlobalScope);
|
||||
|
||||
workerTestGetPrefs(prefs, function(prefMap) {
|
||||
workerTestGetPermissions(permissions, function(permissionMap) {
|
||||
workerTestGetVersion(function(version) {
|
||||
workerTestGetUserAgent(function(userAgent) {
|
||||
workerTestGetIsB2G(function(isB2G) {
|
||||
runTest(prefMap, permissionMap, version, userAgent, isB2G);
|
||||
workerTestDone();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
@ -3098,7 +3098,7 @@ void AsyncPanZoomController::ShareCompositorFrameMetrics() {
|
||||
// Send the shared memory handle and cross process handle to the content
|
||||
// process by an asynchronous ipc call. Include the APZC unique ID
|
||||
// so the content process know which APZC sent this shared FrameMetrics.
|
||||
if (!compositor->SendSharedCompositorFrameMetrics(mem, handle, mAPZCId)) {
|
||||
if (!compositor->SendSharedCompositorFrameMetrics(mem, handle, mLayersId, mAPZCId)) {
|
||||
APZC_LOG("%p failed to share FrameMetrics with content process.", this);
|
||||
}
|
||||
}
|
||||
|
@ -121,14 +121,27 @@ CompositorChild::AllocPLayerTransactionChild(const nsTArray<LayersBackend>& aBac
|
||||
bool*)
|
||||
{
|
||||
MOZ_ASSERT(mCanSend);
|
||||
LayerTransactionChild* c = new LayerTransactionChild();
|
||||
LayerTransactionChild* c = new LayerTransactionChild(aId);
|
||||
c->AddIPDLReference();
|
||||
return c;
|
||||
}
|
||||
|
||||
/*static*/ PLDHashOperator
|
||||
CompositorChild::RemoveSharedMetricsForLayersId(const uint64_t& aKey,
|
||||
nsAutoPtr<SharedFrameMetricsData>& aData,
|
||||
void* aLayerTransactionChild)
|
||||
{
|
||||
uint64_t childId = static_cast<LayerTransactionChild*>(aLayerTransactionChild)->GetId();
|
||||
if (aData->GetLayersId() == childId) {
|
||||
return PLDHashOperator::PL_DHASH_REMOVE;
|
||||
}
|
||||
return PLDHashOperator::PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
bool
|
||||
CompositorChild::DeallocPLayerTransactionChild(PLayerTransactionChild* actor)
|
||||
{
|
||||
mFrameMetricsTable.Enumerate(RemoveSharedMetricsForLayersId, actor);
|
||||
static_cast<LayerTransactionChild*>(actor)->ReleaseIPDLReference();
|
||||
return true;
|
||||
}
|
||||
@ -339,9 +352,11 @@ bool
|
||||
CompositorChild::RecvSharedCompositorFrameMetrics(
|
||||
const mozilla::ipc::SharedMemoryBasic::Handle& metrics,
|
||||
const CrossProcessMutexHandle& handle,
|
||||
const uint64_t& aLayersId,
|
||||
const uint32_t& aAPZCId)
|
||||
{
|
||||
SharedFrameMetricsData* data = new SharedFrameMetricsData(metrics, handle, aAPZCId);
|
||||
SharedFrameMetricsData* data = new SharedFrameMetricsData(
|
||||
metrics, handle, aLayersId, aAPZCId);
|
||||
mFrameMetricsTable.Put(data->GetViewID(), data);
|
||||
return true;
|
||||
}
|
||||
@ -364,9 +379,11 @@ CompositorChild::RecvReleaseSharedCompositorFrameMetrics(
|
||||
CompositorChild::SharedFrameMetricsData::SharedFrameMetricsData(
|
||||
const ipc::SharedMemoryBasic::Handle& metrics,
|
||||
const CrossProcessMutexHandle& handle,
|
||||
const uint32_t& aAPZCId) :
|
||||
mMutex(nullptr),
|
||||
mAPZCId(aAPZCId)
|
||||
const uint64_t& aLayersId,
|
||||
const uint32_t& aAPZCId)
|
||||
: mMutex(nullptr)
|
||||
, mLayersId(aLayersId)
|
||||
, mAPZCId(aAPZCId)
|
||||
{
|
||||
mBuffer = new ipc::SharedMemoryBasic(metrics);
|
||||
mBuffer->Map(sizeof(FrameMetrics));
|
||||
@ -403,6 +420,12 @@ CompositorChild::SharedFrameMetricsData::GetViewID()
|
||||
return frame->GetScrollId();
|
||||
}
|
||||
|
||||
uint64_t
|
||||
CompositorChild::SharedFrameMetricsData::GetLayersId() const
|
||||
{
|
||||
return mLayersId;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
CompositorChild::SharedFrameMetricsData::GetAPZCId()
|
||||
{
|
||||
|
@ -128,6 +128,7 @@ private:
|
||||
|
||||
virtual bool RecvSharedCompositorFrameMetrics(const mozilla::ipc::SharedMemoryBasic::Handle& metrics,
|
||||
const CrossProcessMutexHandle& handle,
|
||||
const uint64_t& aLayersId,
|
||||
const uint32_t& aAPZCId) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool RecvReleaseSharedCompositorFrameMetrics(const ViewID& aId,
|
||||
@ -142,12 +143,14 @@ private:
|
||||
SharedFrameMetricsData(
|
||||
const mozilla::ipc::SharedMemoryBasic::Handle& metrics,
|
||||
const CrossProcessMutexHandle& handle,
|
||||
const uint64_t& aLayersId,
|
||||
const uint32_t& aAPZCId);
|
||||
|
||||
~SharedFrameMetricsData();
|
||||
|
||||
void CopyFrameMetrics(FrameMetrics* aFrame);
|
||||
FrameMetrics::ViewID GetViewID();
|
||||
uint64_t GetLayersId() const;
|
||||
uint32_t GetAPZCId();
|
||||
|
||||
private:
|
||||
@ -155,10 +158,15 @@ private:
|
||||
// the shared FrameMetrics
|
||||
nsRefPtr<mozilla::ipc::SharedMemoryBasic> mBuffer;
|
||||
CrossProcessMutex* mMutex;
|
||||
uint64_t mLayersId;
|
||||
// Unique ID of the APZC that is sharing the FrameMetrics
|
||||
uint32_t mAPZCId;
|
||||
};
|
||||
|
||||
static PLDHashOperator RemoveSharedMetricsForLayersId(const uint64_t& aKey,
|
||||
nsAutoPtr<SharedFrameMetricsData>& aData,
|
||||
void* aLayerTransactionChild);
|
||||
|
||||
nsRefPtr<ClientLayerManager> mLayerManager;
|
||||
|
||||
// The ViewID of the FrameMetrics is used as the key for this hash table.
|
||||
|
@ -51,11 +51,14 @@ public:
|
||||
PTextureChild* aTexture,
|
||||
const FenceHandle& aFence);
|
||||
|
||||
uint64_t GetId() const { return mId; }
|
||||
|
||||
protected:
|
||||
LayerTransactionChild()
|
||||
explicit LayerTransactionChild(const uint64_t& aId)
|
||||
: mForwarder(nullptr)
|
||||
, mIPCOpen(false)
|
||||
, mDestroyed(false)
|
||||
, mId(aId)
|
||||
{}
|
||||
~LayerTransactionChild() { }
|
||||
|
||||
@ -90,6 +93,7 @@ protected:
|
||||
ShadowLayerForwarder* mForwarder;
|
||||
bool mIPCOpen;
|
||||
bool mDestroyed;
|
||||
uint64_t mId;
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
|
@ -133,7 +133,7 @@ parent:
|
||||
child:
|
||||
// Send back Compositor Frame Metrics from APZCs so tiled layers can
|
||||
// update progressively.
|
||||
async SharedCompositorFrameMetrics(Handle metrics, CrossProcessMutexHandle mutex, uint32_t aAPZCId);
|
||||
async SharedCompositorFrameMetrics(Handle metrics, CrossProcessMutexHandle mutex, uint64_t aLayersId, uint32_t aAPZCId);
|
||||
async ReleaseSharedCompositorFrameMetrics(ViewID aId, uint32_t aAPZCId);
|
||||
};
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "nsDebug.h"
|
||||
#include "nsISupportsImpl.h"
|
||||
#include "nsString.h"
|
||||
#include "nsUnicharUtils.h"
|
||||
#include "nsTArray.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
|
||||
@ -280,6 +281,26 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
// searches for a specific non-generic name, lowercase comparison
|
||||
bool Contains(const nsAString& aFamilyName) const {
|
||||
uint32_t len = mFontlist.Length();
|
||||
nsAutoString fam(aFamilyName);
|
||||
ToLowerCase(fam);
|
||||
for (uint32_t i = 0; i < len; i++) {
|
||||
const FontFamilyName& name = mFontlist[i];
|
||||
if (name.mType != eFamily_named &&
|
||||
name.mType != eFamily_named_quoted) {
|
||||
continue;
|
||||
}
|
||||
nsAutoString listname(name.mName);
|
||||
ToLowerCase(listname);
|
||||
if (listname.Equals(fam)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
FontFamilyType GetDefaultFontType() const { return mDefaultFontType; }
|
||||
void SetDefaultFontType(FontFamilyType aType) {
|
||||
NS_ASSERTION(aType == eFamily_none || aType == eFamily_serif ||
|
||||
|
@ -63,7 +63,8 @@ gfxPlatformGtk::gfxPlatformGtk()
|
||||
if (!sFontconfigUtils)
|
||||
sFontconfigUtils = gfxFontconfigUtils::GetFontconfigUtils();
|
||||
#ifdef MOZ_X11
|
||||
sUseXRender = mozilla::Preferences::GetBool("gfx.xrender.enabled");
|
||||
sUseXRender = (GDK_IS_X11_DISPLAY(gdk_display_get_default())) ?
|
||||
mozilla::Preferences::GetBool("gfx.xrender.enabled") : false;
|
||||
#endif
|
||||
|
||||
uint32_t canvasMask = BackendTypeBit(BackendType::CAIRO) | BackendTypeBit(BackendType::SKIA);
|
||||
@ -276,11 +277,15 @@ gfxPlatformGtk::GetPlatformCMSOutputProfile(void *&mem, size_t &size)
|
||||
size = 0;
|
||||
|
||||
#ifdef MOZ_X11
|
||||
GdkDisplay *display = gdk_display_get_default();
|
||||
if (!GDK_IS_X11_DISPLAY(display))
|
||||
return;
|
||||
|
||||
const char EDID1_ATOM_NAME[] = "XFree86_DDC_EDID1_RAWDATA";
|
||||
const char ICC_PROFILE_ATOM_NAME[] = "_ICC_PROFILE";
|
||||
|
||||
Atom edidAtom, iccAtom;
|
||||
Display *dpy = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
|
||||
Display *dpy = GDK_DISPLAY_XDISPLAY(display);
|
||||
// In xpcshell tests, we never initialize X and hence don't have a Display.
|
||||
// In this case, there's no output colour management to be done, so we just
|
||||
// return with nullptr.
|
||||
|
@ -1802,6 +1802,22 @@ gfxFontGroup::FamilyFace::CheckState(bool& aSkipDrawing)
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
gfxFontGroup::FamilyFace::EqualsUserFont(const gfxUserFontEntry* aUserFont) const
|
||||
{
|
||||
gfxFontEntry* fe = FontEntry();
|
||||
// if there's a font, the entry is the underlying platform font
|
||||
if (mFontCreated) {
|
||||
gfxFontEntry* pfe = aUserFont->GetPlatformFontEntry();
|
||||
if (pfe == fe) {
|
||||
return true;
|
||||
}
|
||||
} else if (fe == aUserFont) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
gfxFontGroup::FontLoadingForFamily(gfxFontFamily* aFamily, uint32_t aCh) const
|
||||
{
|
||||
@ -3030,6 +3046,21 @@ gfxFontGroup::UpdateUserFonts()
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
gfxFontGroup::ContainsUserFont(const gfxUserFontEntry* aUserFont)
|
||||
{
|
||||
UpdateUserFonts();
|
||||
// search through the fonts list for a specific user font
|
||||
uint32_t len = mFonts.Length();
|
||||
for (uint32_t i = 0; i < len; i++) {
|
||||
FamilyFace& ff = mFonts[i];
|
||||
if (ff.EqualsUserFont(aUserFont)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
struct PrefFontCallbackData {
|
||||
explicit PrefFontCallbackData(nsTArray<nsRefPtr<gfxFontFamily> >& aFamiliesArray)
|
||||
: mPrefFamilies(aFamiliesArray)
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
class gfxContext;
|
||||
class gfxFontGroup;
|
||||
class gfxUserFontEntry;
|
||||
class gfxUserFontSet;
|
||||
class gfxTextContextPaint;
|
||||
class nsIAtom;
|
||||
@ -864,6 +865,9 @@ public:
|
||||
// caches need updating.
|
||||
virtual void UpdateUserFonts();
|
||||
|
||||
// search for a specific userfont in the list of fonts
|
||||
bool ContainsUserFont(const gfxUserFontEntry* aUserFont);
|
||||
|
||||
bool ShouldSkipDrawing() const {
|
||||
return mSkipDrawing;
|
||||
}
|
||||
@ -1002,6 +1006,8 @@ protected:
|
||||
mLoading = false;
|
||||
}
|
||||
|
||||
bool EqualsUserFont(const gfxUserFontEntry* aUserFont) const;
|
||||
|
||||
private:
|
||||
nsRefPtr<gfxFontFamily> mFamily;
|
||||
// either a font or a font entry exists
|
||||
|
@ -920,6 +920,21 @@ gfxUserFontSet::LookupFamily(const nsAString& aFamilyName) const
|
||||
return mFontFamilies.GetWeak(key);
|
||||
}
|
||||
|
||||
bool
|
||||
gfxUserFontSet::ContainsUserFontSetFonts(const FontFamilyList& aFontList) const
|
||||
{
|
||||
for (const FontFamilyName& name : aFontList.GetFontlist()) {
|
||||
if (name.mType != eFamily_named &&
|
||||
name.mType != eFamily_named_quoted) {
|
||||
continue;
|
||||
}
|
||||
if (LookupFamily(name.mName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
gfxUserFontFamily*
|
||||
gfxUserFontSet::GetFamily(const nsAString& aFamilyName)
|
||||
{
|
||||
|
@ -7,6 +7,7 @@
|
||||
#define GFX_USER_FONT_SET_H
|
||||
|
||||
#include "gfxFont.h"
|
||||
#include "gfxFontFamilyList.h"
|
||||
#include "nsRefPtrHashtable.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsCOMPtr.h"
|
||||
@ -238,6 +239,9 @@ public:
|
||||
// the given name
|
||||
gfxUserFontFamily* LookupFamily(const nsAString& aName) const;
|
||||
|
||||
// Look up names in a fontlist and return true if any are in the set
|
||||
bool ContainsUserFontSetFonts(const mozilla::FontFamilyList& aFontList) const;
|
||||
|
||||
// Lookup a font entry for a given style, returns null if not loaded.
|
||||
// aFamily must be a family returned by our LookupFamily method.
|
||||
// (only used by gfxPangoFontGroup for now)
|
||||
@ -553,7 +557,7 @@ public:
|
||||
virtual gfxFont* CreateFontInstance(const gfxFontStyle* aFontStyle,
|
||||
bool aNeedsBold);
|
||||
|
||||
gfxFontEntry* GetPlatformFontEntry() { return mPlatformFontEntry; }
|
||||
gfxFontEntry* GetPlatformFontEntry() const { return mPlatformFontEntry; }
|
||||
|
||||
// is the font loading or loaded, or did it fail?
|
||||
UserFontLoadState LoadState() const { return mUserFontLoadState; }
|
||||
|
@ -10,17 +10,6 @@
|
||||
#include "mozilla/Endian.h"
|
||||
#include <algorithm>
|
||||
|
||||
#ifdef MOZ_ENABLE_GNOMEUI
|
||||
// Older versions of these headers seem to be missing an extern "C"
|
||||
extern "C" {
|
||||
#include <libgnome/libgnome.h>
|
||||
#include <libgnomeui/gnome-icon-theme.h>
|
||||
#include <libgnomeui/gnome-icon-lookup.h>
|
||||
|
||||
#include <libgnomevfs/gnome-vfs-file-info.h>
|
||||
#include <libgnomevfs/gnome-vfs-ops.h>
|
||||
}
|
||||
#endif
|
||||
#ifdef MOZ_ENABLE_GIO
|
||||
#include <gio/gio.h>
|
||||
#endif
|
||||
@ -43,41 +32,6 @@ NS_IMPL_ISUPPORTS(nsIconChannel,
|
||||
nsIRequest,
|
||||
nsIChannel)
|
||||
|
||||
#ifdef MOZ_ENABLE_GNOMEUI
|
||||
// These let us have a soft dependency on libgnomeui rather than a hard one.
|
||||
// These are just basically the prototypes of the functions in the libraries.
|
||||
typedef char* (*_GnomeIconLookup_fn)(GtkIconTheme* icon_theme,
|
||||
GnomeThumbnailFactory* thumbnail_factory,
|
||||
const char* file_uri,
|
||||
const char* custom_icon,
|
||||
GnomeVFSFileInfo* file_info,
|
||||
const char* mime_type,
|
||||
GnomeIconLookupFlags flags,
|
||||
GnomeIconLookupResultFlags* result);
|
||||
typedef GnomeIconTheme* (*_GnomeIconThemeNew_fn)(void);
|
||||
typedef int (*_GnomeInit_fn)(const char* app_id, const char* app_version,
|
||||
int argc, char** argv,
|
||||
const struct poptOption* options,
|
||||
int flags, poptContext* return_ctx);
|
||||
typedef GnomeProgram* (*_GnomeProgramGet_fn)(void);
|
||||
typedef GnomeVFSResult (*_GnomeVFSGetFileInfo_fn)(const gchar* text_uri,
|
||||
GnomeVFSFileInfo* info,
|
||||
GnomeVFSFileInfoOptions options);
|
||||
typedef void (*_GnomeVFSFileInfoClear_fn)(GnomeVFSFileInfo* info);
|
||||
|
||||
static PRLibrary* gLibGnomeUI = nullptr;
|
||||
static PRLibrary* gLibGnome = nullptr;
|
||||
static PRLibrary* gLibGnomeVFS = nullptr;
|
||||
static bool gTriedToLoadGnomeLibs = false;
|
||||
|
||||
static _GnomeIconLookup_fn _gnome_icon_lookup = nullptr;
|
||||
static _GnomeIconThemeNew_fn _gnome_icon_theme_new = nullptr;
|
||||
static _GnomeInit_fn _gnome_init = nullptr;
|
||||
static _GnomeProgramGet_fn _gnome_program_get = nullptr;
|
||||
static _GnomeVFSGetFileInfo_fn _gnome_vfs_get_file_info = nullptr;
|
||||
static _GnomeVFSFileInfoClear_fn _gnome_vfs_file_info_clear = nullptr;
|
||||
#endif //MOZ_ENABLE_GNOMEUI
|
||||
|
||||
static nsresult
|
||||
moz_gdk_pixbuf_to_channel(GdkPixbuf* aPixbuf, nsIURI* aURI,
|
||||
nsIChannel** aChannel)
|
||||
@ -162,9 +116,6 @@ moz_gdk_pixbuf_to_channel(GdkPixbuf* aPixbuf, nsIURI* aURI,
|
||||
|
||||
static GtkWidget* gProtoWindow = nullptr;
|
||||
static GtkWidget* gStockImageWidget = nullptr;
|
||||
#ifdef MOZ_ENABLE_GNOMEUI
|
||||
static GnomeIconTheme* gIconTheme = nullptr;
|
||||
#endif //MOZ_ENABLE_GNOMEUI
|
||||
|
||||
static void
|
||||
ensure_stock_image_widget()
|
||||
@ -183,100 +134,6 @@ ensure_stock_image_widget()
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MOZ_ENABLE_GNOMEUI
|
||||
static nsresult
|
||||
ensure_libgnomeui()
|
||||
{
|
||||
// Attempt to get the libgnomeui symbol references. We do it this way
|
||||
// so that stock icons from Init() don't get held back by InitWithGnome()'s
|
||||
// libgnomeui dependency.
|
||||
if (!gTriedToLoadGnomeLibs) {
|
||||
gLibGnomeUI = PR_LoadLibrary("libgnomeui-2.so.0");
|
||||
if (!gLibGnomeUI) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
_gnome_init =
|
||||
(_GnomeInit_fn)PR_FindFunctionSymbol(gLibGnomeUI,
|
||||
"gnome_init_with_popt_table");
|
||||
_gnome_icon_theme_new =
|
||||
(_GnomeIconThemeNew_fn)PR_FindFunctionSymbol(gLibGnomeUI,
|
||||
"gnome_icon_theme_new");
|
||||
_gnome_icon_lookup =
|
||||
(_GnomeIconLookup_fn)PR_FindFunctionSymbol(gLibGnomeUI,
|
||||
"gnome_icon_lookup");
|
||||
|
||||
if (!_gnome_init || !_gnome_icon_theme_new || !_gnome_icon_lookup) {
|
||||
PR_UnloadLibrary(gLibGnomeUI);
|
||||
gLibGnomeUI = nullptr;
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!gLibGnomeUI) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static nsresult
|
||||
ensure_libgnome()
|
||||
{
|
||||
if (!gTriedToLoadGnomeLibs) {
|
||||
gLibGnome = PR_LoadLibrary("libgnome-2.so.0");
|
||||
if (!gLibGnome) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
_gnome_program_get =
|
||||
(_GnomeProgramGet_fn)PR_FindFunctionSymbol(gLibGnome,
|
||||
"gnome_program_get");
|
||||
if (!_gnome_program_get) {
|
||||
PR_UnloadLibrary(gLibGnome);
|
||||
gLibGnome = nullptr;
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!gLibGnome) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static nsresult
|
||||
ensure_libgnomevfs()
|
||||
{
|
||||
if (!gTriedToLoadGnomeLibs) {
|
||||
gLibGnomeVFS = PR_LoadLibrary("libgnomevfs-2.so.0");
|
||||
if (!gLibGnomeVFS) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
_gnome_vfs_get_file_info =
|
||||
(_GnomeVFSGetFileInfo_fn)PR_FindFunctionSymbol(gLibGnomeVFS,
|
||||
"gnome_vfs_get_file_info");
|
||||
_gnome_vfs_file_info_clear =
|
||||
(_GnomeVFSFileInfoClear_fn)PR_FindFunctionSymbol(gLibGnomeVFS,
|
||||
"gnome_vfs_file_"
|
||||
"info_clear");
|
||||
if (!_gnome_vfs_get_file_info || !_gnome_vfs_file_info_clear) {
|
||||
PR_UnloadLibrary(gLibGnomeVFS);
|
||||
gLibGnomeVFS = nullptr;
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!gLibGnomeVFS) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
#endif //MOZ_ENABLE_GNOMEUI
|
||||
|
||||
static GtkIconSize
|
||||
moz_gtk_icon_size(const char* name)
|
||||
{
|
||||
@ -307,7 +164,7 @@ moz_gtk_icon_size(const char* name)
|
||||
return GTK_ICON_SIZE_MENU;
|
||||
}
|
||||
|
||||
#if defined(MOZ_ENABLE_GNOMEUI) || defined(MOZ_ENABLE_GIO)
|
||||
#ifdef MOZ_ENABLE_GIO
|
||||
static int32_t
|
||||
GetIconSize(nsIMozIconURI* aIconURI)
|
||||
{
|
||||
@ -346,149 +203,7 @@ ScaleIconBuf(GdkPixbuf** aBuf, int32_t iconSize)
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_ENABLE_GNOMEUI
|
||||
nsresult
|
||||
nsIconChannel::InitWithGnome(nsIMozIconURI* aIconURI)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
if (NS_FAILED(ensure_libgnomeui()) || NS_FAILED(ensure_libgnome()) ||
|
||||
NS_FAILED(ensure_libgnomevfs())) {
|
||||
gTriedToLoadGnomeLibs = true;
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
gTriedToLoadGnomeLibs = true;
|
||||
|
||||
if (!_gnome_program_get()) {
|
||||
// Get the brandShortName from the string bundle to pass to GNOME
|
||||
// as the application name. This may be used for things such as
|
||||
// the title of grouped windows in the panel.
|
||||
nsCOMPtr<nsIStringBundleService> bundleService =
|
||||
do_GetService(NS_STRINGBUNDLE_CONTRACTID);
|
||||
|
||||
NS_ASSERTION(bundleService, "String bundle service must be present!");
|
||||
|
||||
nsCOMPtr<nsIStringBundle> bundle;
|
||||
bundleService->CreateBundle("chrome://branding/locale/brand.properties",
|
||||
getter_AddRefs(bundle));
|
||||
nsAutoString appName;
|
||||
|
||||
if (bundle) {
|
||||
bundle->GetStringFromName(MOZ_UTF16("brandShortName"),
|
||||
getter_Copies(appName));
|
||||
} else {
|
||||
NS_WARNING(
|
||||
"brand.properties not present, using default application name");
|
||||
appName.AssignLiteral(MOZ_UTF16("Gecko"));
|
||||
}
|
||||
|
||||
char* empty[] = { "" };
|
||||
_gnome_init(NS_ConvertUTF16toUTF8(appName).get(),
|
||||
"1.0", 1, empty, nullptr, 0, nullptr);
|
||||
}
|
||||
|
||||
uint32_t iconSize = GetIconSize(aIconURI);
|
||||
nsAutoCString type;
|
||||
aIconURI->GetContentType(type);
|
||||
|
||||
GnomeVFSFileInfo fileInfo = {0};
|
||||
fileInfo.refcount = 1; // In case some GnomeVFS function addrefs and
|
||||
// releases it
|
||||
|
||||
nsAutoCString spec;
|
||||
nsCOMPtr<nsIURL> url;
|
||||
rv = aIconURI->GetIconURL(getter_AddRefs(url));
|
||||
if (url) {
|
||||
url->GetAsciiSpec(spec);
|
||||
// Only ask gnome-vfs for a GnomeVFSFileInfo for file: uris, to avoid a
|
||||
// network request
|
||||
bool isFile;
|
||||
if (NS_SUCCEEDED(url->SchemeIs("file", &isFile)) && isFile) {
|
||||
_gnome_vfs_get_file_info(spec.get(), &fileInfo,
|
||||
GNOME_VFS_FILE_INFO_DEFAULT);
|
||||
}
|
||||
else {
|
||||
// The filename we get is UTF-8-compatible, which matches gnome
|
||||
// expectations.
|
||||
// See also:
|
||||
// http://lists.gnome.org/archives/gnome-vfs-list/2004-March/msg00049.html
|
||||
// "Whenever we can detect the charset used for the URI type we try to
|
||||
// convert it to/from utf8 automatically inside gnome-vfs."
|
||||
// I'll interpret that as "otherwise, this field is random junk".
|
||||
nsAutoCString name;
|
||||
url->GetFileName(name);
|
||||
fileInfo.name = g_strdup(name.get());
|
||||
|
||||
if (!type.IsEmpty()) {
|
||||
fileInfo.valid_fields = GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE;
|
||||
fileInfo.mime_type = g_strdup(type.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (type.IsEmpty()) {
|
||||
nsCOMPtr<nsIMIMEService> ms(do_GetService("@mozilla.org/mime;1"));
|
||||
if (ms) {
|
||||
nsAutoCString fileExt;
|
||||
aIconURI->GetFileExtension(fileExt);
|
||||
if (!fileExt.IsEmpty()) {
|
||||
ms->GetTypeFromExtension(fileExt, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Get the icon theme
|
||||
if (!gIconTheme) {
|
||||
gIconTheme = _gnome_icon_theme_new();
|
||||
|
||||
if (!gIconTheme) {
|
||||
_gnome_vfs_file_info_clear(&fileInfo);
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
}
|
||||
|
||||
char* name = _gnome_icon_lookup(gIconTheme, nullptr, spec.get(), nullptr,
|
||||
&fileInfo, type.get(),
|
||||
GNOME_ICON_LOOKUP_FLAGS_NONE, nullptr);
|
||||
|
||||
_gnome_vfs_file_info_clear(&fileInfo);
|
||||
if (!name) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
// Get the default theme associated with the screen
|
||||
// Do NOT free.
|
||||
GtkIconTheme* theme = gtk_icon_theme_get_default();
|
||||
if (!theme) {
|
||||
g_free(name);
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
GError* err = nullptr;
|
||||
GdkPixbuf* buf = gtk_icon_theme_load_icon(theme, name, iconSize,
|
||||
(GtkIconLookupFlags)0, &err);
|
||||
g_free(name);
|
||||
|
||||
if (!buf) {
|
||||
if (err) {
|
||||
g_error_free(err);
|
||||
}
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
rv = ScaleIconBuf(&buf, iconSize);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = moz_gdk_pixbuf_to_channel(buf, aIconURI,
|
||||
getter_AddRefs(mRealChannel));
|
||||
g_object_unref(buf);
|
||||
return rv;
|
||||
}
|
||||
#endif // MOZ_ENABLE_GNOMEUI
|
||||
|
||||
#ifdef MOZ_ENABLE_GIO
|
||||
nsresult
|
||||
nsIconChannel::InitWithGIO(nsIMozIconURI* aIconURI)
|
||||
{
|
||||
@ -594,14 +309,10 @@ nsIconChannel::Init(nsIURI* aURI)
|
||||
nsAutoCString stockIcon;
|
||||
iconURI->GetStockIcon(stockIcon);
|
||||
if (stockIcon.IsEmpty()) {
|
||||
#ifdef MOZ_ENABLE_GNOMEUI
|
||||
return InitWithGnome(iconURI);
|
||||
#else
|
||||
#ifdef MOZ_ENABLE_GIO
|
||||
return InitWithGIO(iconURI);
|
||||
#else
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -710,23 +421,4 @@ nsIconChannel::Shutdown() {
|
||||
gProtoWindow = nullptr;
|
||||
gStockImageWidget = nullptr;
|
||||
}
|
||||
#ifdef MOZ_ENABLE_GNOMEUI
|
||||
if (gIconTheme) {
|
||||
g_object_unref(G_OBJECT(gIconTheme));
|
||||
gIconTheme = nullptr;
|
||||
}
|
||||
gTriedToLoadGnomeLibs = false;
|
||||
if (gLibGnomeUI) {
|
||||
PR_UnloadLibrary(gLibGnomeUI);
|
||||
gLibGnomeUI = nullptr;
|
||||
}
|
||||
if (gLibGnome) {
|
||||
PR_UnloadLibrary(gLibGnome);
|
||||
gLibGnome = nullptr;
|
||||
}
|
||||
if (gLibGnomeVFS) {
|
||||
PR_UnloadLibrary(gLibGnomeVFS);
|
||||
gLibGnomeVFS = nullptr;
|
||||
}
|
||||
#endif //MOZ_ENABLE_GNOMEUI
|
||||
}
|
||||
|
@ -37,8 +37,6 @@ class nsIconChannel MOZ_FINAL : public nsIChannel
|
||||
/// Will always be non-null after a successful Init.
|
||||
nsCOMPtr<nsIChannel> mRealChannel;
|
||||
|
||||
/// Called by Init if we need to use the gnomeui library.
|
||||
nsresult InitWithGnome(nsIMozIconURI* aURI);
|
||||
nsresult InitWithGIO(nsIMozIconURI* aIconURI);
|
||||
};
|
||||
|
||||
|
@ -252,11 +252,6 @@ struct VMFunction
|
||||
}
|
||||
|
||||
VMFunction(const VMFunction &o) {
|
||||
init(o);
|
||||
}
|
||||
|
||||
void init(const VMFunction &o) {
|
||||
MOZ_ASSERT(!wrapped);
|
||||
*this = o;
|
||||
addToFunctions();
|
||||
}
|
||||
|
@ -1970,17 +1970,9 @@ ArenaList::removeRemainingArenas(ArenaHeader **arenap)
|
||||
}
|
||||
|
||||
static bool
|
||||
ShouldRelocateAllArenas(JSRuntime *runtime)
|
||||
ShouldRelocateAllArenas(JS::gcreason::Reason reason)
|
||||
{
|
||||
// In compacting zeal mode and in debug builds on 64 bit architectures, we
|
||||
// relocate all arenas. The purpose of this is to balance test coverage of
|
||||
// object moving with test coverage of the arena selection routine in
|
||||
// pickArenasToRelocate().
|
||||
#if defined(DEBUG) && defined(JS_PUNBOX64)
|
||||
return true;
|
||||
#else
|
||||
return runtime->gc.zeal() == ZealCompactValue;
|
||||
#endif
|
||||
return reason == JS::gcreason::DEBUG_GC;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2187,7 +2179,7 @@ ArenaLists::relocateArenas(ArenaHeader *&relocatedListOut, JS::gcreason::Reason
|
||||
purge();
|
||||
checkEmptyFreeLists();
|
||||
|
||||
if (ShouldRelocateAllArenas(runtime_)) {
|
||||
if (ShouldRelocateAllArenas(reason)) {
|
||||
for (size_t i = 0; i < FINALIZE_LIMIT; i++) {
|
||||
if (CanRelocateAllocKind(AllocKind(i))) {
|
||||
ArenaList &al = arenaLists[i];
|
||||
@ -5531,7 +5523,7 @@ GCRuntime::compactPhase(JS::gcreason::Reason reason)
|
||||
#ifndef DEBUG
|
||||
releaseRelocatedArenas(relocatedList);
|
||||
#else
|
||||
if (reason == JS::gcreason::DESTROY_RUNTIME || reason == JS::gcreason::LAST_DITCH) {
|
||||
if (reason != JS::gcreason::DEBUG_GC) {
|
||||
releaseRelocatedArenas(relocatedList);
|
||||
} else {
|
||||
MOZ_ASSERT(!relocatedArenasToRelease);
|
||||
|
@ -1008,17 +1008,14 @@ XrayTraits::cloneExpandoChain(JSContext *cx, HandleObject dst, HandleObject src)
|
||||
// set for |dst|. Eventually it will be set to that of |src|. This will
|
||||
// prevent attachExpandoObject() from preserving the wrapper, but this is
|
||||
// not a problem because in this case the wrapper will already have been
|
||||
// preserved when expandos were originally added to |src|. In this case
|
||||
// assert the wrapper for |src| has been preserved.
|
||||
// preserved when expandos were originally added to |src|. Assert the
|
||||
// wrapper for |src| has been preserved if it has expandos set.
|
||||
if (oldHead) {
|
||||
nsISupports *dstId = mozilla::dom::UnwrapDOMObjectToISupports(dst);
|
||||
if (!dstId) {
|
||||
nsISupports *srcId = mozilla::dom::UnwrapDOMObjectToISupports(src);
|
||||
if (srcId) {
|
||||
nsWrapperCache* cache = nullptr;
|
||||
CallQueryInterface(srcId, &cache);
|
||||
MOZ_ASSERT_IF(cache, cache->PreservingWrapper());
|
||||
}
|
||||
nsISupports *identity = mozilla::dom::UnwrapDOMObjectToISupports(src);
|
||||
if (identity) {
|
||||
nsWrapperCache* cache = nullptr;
|
||||
CallQueryInterface(identity, &cache);
|
||||
MOZ_ASSERT_IF(cache, cache->PreservingWrapper());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -66,6 +66,7 @@
|
||||
#include "nsPIWindowRoot.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "gfxTextRun.h"
|
||||
#include "nsFontFaceUtils.h"
|
||||
|
||||
// Needed for Start/Stop of Image Animation
|
||||
#include "imgIContainer.h"
|
||||
@ -1852,6 +1853,7 @@ nsPresContext::RebuildAllStyleData(nsChangeHint aExtraHint,
|
||||
}
|
||||
|
||||
mUsesRootEMUnits = false;
|
||||
mUsesExChUnits = false;
|
||||
mUsesViewportUnits = false;
|
||||
RebuildUserFontSet();
|
||||
RebuildCounterStyles();
|
||||
@ -2144,24 +2146,47 @@ nsPresContext::RebuildUserFontSet()
|
||||
}
|
||||
|
||||
void
|
||||
nsPresContext::UserFontSetUpdated()
|
||||
nsPresContext::UserFontSetUpdated(gfxUserFontEntry* aUpdatedFont)
|
||||
{
|
||||
if (!mShell)
|
||||
return;
|
||||
|
||||
// Changes to the set of available fonts can cause updates to layout by:
|
||||
//
|
||||
// 1. Changing the font used for text, which changes anything that
|
||||
// depends on text measurement, including line breaking and
|
||||
// intrinsic widths, and any other parts of layout that depend on
|
||||
// font metrics. This requires a style change reflow to update.
|
||||
//
|
||||
// 2. Changing the value of the 'ex' and 'ch' units in style data,
|
||||
// which also depend on font metrics. Updating this information
|
||||
// requires rebuilding the rule tree from the top, avoiding the
|
||||
// reuse of cached data even when no style rules have changed.
|
||||
bool usePlatformFontList = true;
|
||||
#if defined(MOZ_WIDGET_GTK) || defined(MOZ_WIDGET_QT)
|
||||
usePlatformFontList = false;
|
||||
#endif
|
||||
|
||||
PostRebuildAllStyleDataEvent(NS_STYLE_HINT_REFLOW, eRestyle_ForceDescendants);
|
||||
// xxx - until the Linux platform font list is always used, use full
|
||||
// restyle to force updates with gfxPangoFontGroup usage
|
||||
// Note: this method is called without a font when rules in the userfont set
|
||||
// are updated, which may occur during reflow as a result of the lazy
|
||||
// initialization of the userfont set. It would be better to avoid a full
|
||||
// restyle but until this method is only called outside of reflow, schedule a
|
||||
// full restyle in these cases.
|
||||
if (!usePlatformFontList || !aUpdatedFont) {
|
||||
PostRebuildAllStyleDataEvent(NS_STYLE_HINT_REFLOW, eRestyle_ForceDescendants);
|
||||
return;
|
||||
}
|
||||
|
||||
// Special case - if either the 'ex' or 'ch' units are used, these
|
||||
// depend upon font metrics. Updating this information requires
|
||||
// rebuilding the rule tree from the top, avoiding the reuse of cached
|
||||
// data even when no style rules have changed.
|
||||
|
||||
if (UsesExChUnits()) {
|
||||
// xxx - dbaron said this should work but get ex/ch related reftest failures
|
||||
// PostRebuildAllStyleDataEvent(nsChangeHint(0), eRestyle_ForceDescendants);
|
||||
PostRebuildAllStyleDataEvent(NS_STYLE_HINT_REFLOW, eRestyle_ForceDescendants);
|
||||
return;
|
||||
}
|
||||
|
||||
// Iterate over the frame tree looking for frames associated with the
|
||||
// downloadable font family in question. If a frame's nsStyleFont has
|
||||
// the name, check the font group associated with the metrics to see if
|
||||
// it contains that specific font (i.e. the one chosen within the family
|
||||
// given the weight, width, and slant from the nsStyleFont). If it does,
|
||||
// mark that frame dirty and skip inspecting its descendants.
|
||||
nsFontFaceUtils::MarkDirtyForFontChange(mShell->GetRootFrame(), aUpdatedFont);
|
||||
}
|
||||
|
||||
FontFaceSet*
|
||||
|
@ -56,6 +56,7 @@ class nsICSSPseudoComparator;
|
||||
struct nsStyleBackground;
|
||||
struct nsStyleBorder;
|
||||
class nsIRunnable;
|
||||
class gfxUserFontEntry;
|
||||
class gfxUserFontSet;
|
||||
class gfxTextPerfMetrics;
|
||||
struct nsFontFaceRuleContainer;
|
||||
@ -890,7 +891,7 @@ public:
|
||||
// Should be called whenever the set of fonts available in the user
|
||||
// font set changes (e.g., because a new font loads, or because the
|
||||
// user font set is changed and fonts become unavailable).
|
||||
void UserFontSetUpdated();
|
||||
void UserFontSetUpdated(gfxUserFontEntry* aUpdatedFont = nullptr);
|
||||
|
||||
gfxMissingFontRecorder *MissingFontRecorder() { return mMissingFonts; }
|
||||
void NotifyMissingFonts();
|
||||
@ -1026,6 +1027,14 @@ public:
|
||||
mUsesRootEMUnits = aValue;
|
||||
}
|
||||
|
||||
bool UsesExChUnits() const {
|
||||
return mUsesExChUnits;
|
||||
}
|
||||
|
||||
void SetUsesExChUnits(bool aValue) {
|
||||
mUsesExChUnits = aValue;
|
||||
}
|
||||
|
||||
bool UsesViewportUnits() const {
|
||||
return mUsesViewportUnits;
|
||||
}
|
||||
@ -1348,6 +1357,8 @@ protected:
|
||||
|
||||
// Does the associated document use root-em (rem) units?
|
||||
unsigned mUsesRootEMUnits : 1;
|
||||
// Does the associated document use ex or ch units?
|
||||
unsigned mUsesExChUnits : 1;
|
||||
// Does the associated document use viewport units (vw/vh/vmin/vmax)?
|
||||
unsigned mUsesViewportUnits : 1;
|
||||
|
||||
|
@ -231,6 +231,7 @@ nsMathMLFrame::CalcLength(nsPresContext* aPresContext,
|
||||
return NSToCoordRound(aCSSValue.GetFloatValue() * (float)font->mFont.size);
|
||||
}
|
||||
else if (eCSSUnit_XHeight == unit) {
|
||||
aPresContext->SetUsesExChUnits(true);
|
||||
nsRefPtr<nsFontMetrics> fm;
|
||||
nsLayoutUtils::GetFontMetricsForStyleContext(aStyleContext,
|
||||
getter_AddRefs(fm),
|
||||
|
54
layout/reftests/font-face/reflow-sanity-1-data.html
Normal file
54
layout/reftests/font-face/reflow-sanity-1-data.html
Normal file
@ -0,0 +1,54 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>test @font-face reflow sanity</title>
|
||||
<meta charset="utf-8">
|
||||
<style>
|
||||
body { margin: 20px }
|
||||
|
||||
@font-face {
|
||||
font-family: reflow1data;
|
||||
src: url(data:font/opentype;base64,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);
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: reflow1data;
|
||||
src: url(data:font/opentype;base64,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);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: reflow1data;
|
||||
src: url(data:font/opentype;base64,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);
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: reflow1data;
|
||||
src: url(data:font/opentype;base64,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);
|
||||
font-weight: bold;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
div#test {
|
||||
font-family: reflow1data;
|
||||
font-size: 400%;
|
||||
line-height: 1em;
|
||||
}
|
||||
|
||||
div#test p {
|
||||
margin: 0;
|
||||
display: inline-block;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id=test>
|
||||
<p>A</p>
|
||||
<p style="font-weight: bold">B</p>
|
||||
<p style="font-style: italic">C</p>
|
||||
<p style="font-style: italic; font-weight: bold">D</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
35
layout/reftests/font-face/reflow-sanity-1-ref.html
Normal file
35
layout/reftests/font-face/reflow-sanity-1-ref.html
Normal file
@ -0,0 +1,35 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>test @font-face reflow sanity</title>
|
||||
<meta charset="utf-8">
|
||||
<style>
|
||||
body { margin: 20px }
|
||||
|
||||
@font-face {
|
||||
font-family: reflow1ref;
|
||||
src: url(../fonts/markA.ttf);
|
||||
}
|
||||
|
||||
div#test {
|
||||
font-family: reflow1ref;
|
||||
font-size: 400%;
|
||||
line-height: 1em;
|
||||
}
|
||||
|
||||
div#test p {
|
||||
margin: 0;
|
||||
display: inline-block;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id=test>
|
||||
<p>A</p>
|
||||
<p>A</p>
|
||||
<p>A</p>
|
||||
<p>A</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
54
layout/reftests/font-face/reflow-sanity-1.html
Normal file
54
layout/reftests/font-face/reflow-sanity-1.html
Normal file
@ -0,0 +1,54 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>test @font-face reflow sanity</title>
|
||||
<meta charset="utf-8">
|
||||
<style>
|
||||
body { margin: 20px }
|
||||
|
||||
@font-face {
|
||||
font-family: reflow1;
|
||||
src: url(../fonts/markA.ttf);
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: reflow1;
|
||||
src: url(../fonts/markB.ttf);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: reflow1;
|
||||
src: url(../fonts/markC.ttf);
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: reflow1;
|
||||
src: url(../fonts/markD.ttf);
|
||||
font-weight: bold;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
div#test {
|
||||
font-family: reflow1;
|
||||
font-size: 400%;
|
||||
line-height: 1em;
|
||||
}
|
||||
|
||||
div#test p {
|
||||
margin: 0;
|
||||
display: inline-block;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id=test>
|
||||
<p>A</p>
|
||||
<p style="font-weight: bold">B</p>
|
||||
<p style="font-style: italic">C</p>
|
||||
<p style="font-style: italic; font-weight: bold">D</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
54
layout/reftests/font-face/reflow-sanity-delay-1-metrics.html
Normal file
54
layout/reftests/font-face/reflow-sanity-delay-1-metrics.html
Normal file
@ -0,0 +1,54 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>test @font-face reflow sanity</title>
|
||||
<meta charset="utf-8">
|
||||
<style>
|
||||
body { margin: 20px }
|
||||
|
||||
@font-face {
|
||||
font-family: reflow1metrics;
|
||||
src: url(../fonts/markfonts-delay.sjs?font=markA&delay=2500&test=delay-1-metrics);
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: reflow1metrics;
|
||||
src: url(../fonts/markfonts-delay.sjs?font=markB&delay=2200&test=delay-1-metrics);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: reflow1metrics;
|
||||
src: url(../fonts/markfonts-delay.sjs?font=markC&delay=200&test=delay-1-metrics);
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: reflow1metrics;
|
||||
src: url(../fonts/markfonts-delay.sjs?font=markD&delay=900&test=delay-1-metrics);
|
||||
font-weight: bold;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
div#test {
|
||||
font-family: reflow1metrics;
|
||||
font-size: 400%;
|
||||
line-height: 1em;
|
||||
}
|
||||
|
||||
div#test p {
|
||||
margin: 0;
|
||||
display: inline-block;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id=test>
|
||||
<p style="font-family: reflow1metrics, cursive;">A</p>
|
||||
<p style="font-family: reflow1metrics, fantasy; font-weight: bold">B</p>
|
||||
<p style="font-family: reflow1metrics, monospace; font-style: italic">C</p>
|
||||
<p style="font-family: reflow1metrics, sans-serif; font-style: italic; font-weight: bold">D</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
54
layout/reftests/font-face/reflow-sanity-delay-1a.html
Normal file
54
layout/reftests/font-face/reflow-sanity-delay-1a.html
Normal file
@ -0,0 +1,54 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>test @font-face reflow sanity</title>
|
||||
<meta charset="utf-8">
|
||||
<style>
|
||||
body { margin: 20px }
|
||||
|
||||
@font-face {
|
||||
font-family: reflow1a;
|
||||
src: url(../fonts/markfonts-delay.sjs?font=markA&delay=100&test=delay-1a);
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: reflow1a;
|
||||
src: url(../fonts/markfonts-delay.sjs?font=markB&delay=1000&test=delay-1a);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: reflow1a;
|
||||
src: url(../fonts/markfonts-delay.sjs?font=markC&delay=1500&test=delay-1a);
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: reflow1a;
|
||||
src: url(../fonts/markfonts-delay.sjs?font=markD&delay=2000&test=delay-1a);
|
||||
font-weight: bold;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
div#test {
|
||||
font-family: reflow1a;
|
||||
font-size: 400%;
|
||||
line-height: 1em;
|
||||
}
|
||||
|
||||
div#test p {
|
||||
margin: 0;
|
||||
display: inline-block;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id=test>
|
||||
<p>A</p>
|
||||
<p style="font-weight: bold">B</p>
|
||||
<p style="font-style: italic">C</p>
|
||||
<p style="font-style: italic; font-weight: bold">D</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
54
layout/reftests/font-face/reflow-sanity-delay-1b.html
Normal file
54
layout/reftests/font-face/reflow-sanity-delay-1b.html
Normal file
@ -0,0 +1,54 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>test @font-face reflow sanity</title>
|
||||
<meta charset="utf-8">
|
||||
<style>
|
||||
body { margin: 20px }
|
||||
|
||||
@font-face {
|
||||
font-family: reflow1b;
|
||||
src: url(../fonts/markfonts-delay.sjs?font=markA&delay=2500&test=delay-1b);
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: reflow1b;
|
||||
src: url(../fonts/markfonts-delay.sjs?font=markB&delay=500&test=delay-1b);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: reflow1b;
|
||||
src: url(../fonts/markfonts-delay.sjs?font=markC&delay=1100&test=delay-1b);
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: reflow1b;
|
||||
src: url(../fonts/markfonts-delay.sjs?font=markD&delay=100&test=delay-1b);
|
||||
font-weight: bold;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
div#test {
|
||||
font-family: reflow1b;
|
||||
font-size: 400%;
|
||||
line-height: 1em;
|
||||
}
|
||||
|
||||
div#test p {
|
||||
margin: 0;
|
||||
display: inline-block;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id=test>
|
||||
<p>A</p>
|
||||
<p style="font-weight: bold">B</p>
|
||||
<p style="font-style: italic">C</p>
|
||||
<p style="font-style: italic; font-weight: bold">D</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
54
layout/reftests/font-face/reflow-sanity-delay-1c.html
Normal file
54
layout/reftests/font-face/reflow-sanity-delay-1c.html
Normal file
@ -0,0 +1,54 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>test @font-face reflow sanity</title>
|
||||
<meta charset="utf-8">
|
||||
<style>
|
||||
body { margin: 20px }
|
||||
|
||||
@font-face {
|
||||
font-family: markA;
|
||||
src: url(../fonts/markfonts-delay.sjs?font=markA&delay=2500&test=delay-1c);
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: markB;
|
||||
src: url(../fonts/markfonts-delay.sjs?font=markB&delay=500&test=delay-1c);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: markC;
|
||||
src: url(../fonts/markfonts-delay.sjs?font=markC&delay=1100&test=delay-1c);
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: markD;
|
||||
src: url(../fonts/markfonts-delay.sjs?font=markD&delay=100&test=delay-1c);
|
||||
font-weight: bold;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
div#test {
|
||||
font-family: markA;
|
||||
font-size: 400%;
|
||||
line-height: 1em;
|
||||
}
|
||||
|
||||
div#test p {
|
||||
margin: 0;
|
||||
display: inline-block;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id=test>
|
||||
<p style="font-family: marka, markb, markc, markd;">A</p>
|
||||
<p style="font-family: marka, markb, markc, markd; font-weight: bold">B</p>
|
||||
<p style="font-family: marka, markb, markc, markd; font-style: italic">C</p>
|
||||
<p style="font-family: marka, markb, markc, markd; font-style: italic; font-weight: bold">D</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -169,3 +169,12 @@ HTTP(..) != color-1a.html color-1-notref.html
|
||||
HTTP(..) == color-1b.html color-1-ref.html
|
||||
|
||||
pref(gfx.downloadable_fonts.woff2.enabled,true) HTTP(..) == woff2-1.html woff2-1-ref.html
|
||||
|
||||
# sanity tests for reflow behavior with downloadable fonts
|
||||
HTTP(..) == reflow-sanity-1.html reflow-sanity-1-ref.html
|
||||
HTTP(..) == reflow-sanity-1-data.html reflow-sanity-1-ref.html
|
||||
HTTP(..) == reflow-sanity-1.html reflow-sanity-1-data.html
|
||||
HTTP(..) == reflow-sanity-delay-1a.html reflow-sanity-1-ref.html
|
||||
HTTP(..) == reflow-sanity-delay-1b.html reflow-sanity-1-ref.html
|
||||
HTTP(..) == reflow-sanity-delay-1c.html reflow-sanity-1-ref.html
|
||||
HTTP(..) == reflow-sanity-delay-1-metrics.html reflow-sanity-1-ref.html
|
||||
|
@ -109,11 +109,11 @@ HTTP(..) == caps-fallback-allsmallcaps.html caps-fallback-smcpc2sc.html
|
||||
HTTP(..) == caps-fallback-allpetitecaps.html caps-fallback-smcpc2sc.html
|
||||
|
||||
# font-variant-position fallback
|
||||
HTTP(..) == subsuper-fallback.html subsuper-fallback-ref.html
|
||||
random-if(cocoaWidget) HTTP(..) == subsuper-fallback.html subsuper-fallback-ref.html # bug 1139269
|
||||
HTTP(..) != subsuper-fallback.html subsuper-fallback-notref1.html
|
||||
HTTP(..) != subsuper-fallback.html subsuper-fallback-notref2.html
|
||||
HTTP(..) != subsuper-fallback.html subsuper-fallback-notref3.html
|
||||
HTTP(..) != subsuper-fallback-omega.html subsuper-fallback-omega-notref.html
|
||||
HTTP(..) == subsuper-nofallback.html subsuper-nofallback-ref1.html
|
||||
HTTP(..) == subsuper-nofallback.html subsuper-nofallback-ref2.html
|
||||
random-if(cocoaWidget) HTTP(..) == subsuper-nofallback.html subsuper-nofallback-ref2.html # bug 1139269
|
||||
HTTP(..) != subsuper-nofallback.html subsuper-nofallback-notref.html
|
||||
|
78
layout/reftests/fonts/markfonts-delay.sjs
Normal file
78
layout/reftests/fonts/markfonts-delay.sjs
Normal file
File diff suppressed because one or more lines are too long
@ -338,6 +338,7 @@ HTTP(..) == text-scale-03.svg text-scale-03-ref.svg
|
||||
== stroke-dasharray-and-pathLength-01.svg pass.svg
|
||||
== stroke-dasharray-and-text-01.svg stroke-dasharray-and-text-01-ref.svg
|
||||
== stroke-dashoffset-01.svg pass.svg
|
||||
== stroke-dashoffset-and-pathLength-01.svg pass.svg
|
||||
== stroke-linecap-round-w-zero-length-segs-01.svg pass.svg
|
||||
== stroke-linecap-round-w-zero-length-segs-02.svg pass.svg
|
||||
== stroke-linecap-square-w-zero-length-segs-01.svg pass.svg
|
||||
|
25
layout/reftests/svg/stroke-dashoffset-and-pathLength-01.svg
Normal file
25
layout/reftests/svg/stroke-dashoffset-and-pathLength-01.svg
Normal file
@ -0,0 +1,25 @@
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<svg xmlns="http://www.w3.org/2000/svg">
|
||||
<title>Test stroke-dashoffset with pathLength</title>
|
||||
<!--
|
||||
The path is much longer than 100 user units, so if the pathLength is not
|
||||
factored into the stroke-dashoffset calculation, the stroke will be visible.
|
||||
A correct implementation will see the first dash pushed off the end of the
|
||||
path which will mean that the path does not display at all.
|
||||
-->
|
||||
<style>
|
||||
path {
|
||||
fill: none;
|
||||
stroke-width: 5;
|
||||
stroke: red;
|
||||
stroke-dasharray: 100;
|
||||
stroke-dashoffset: 100;
|
||||
}
|
||||
</style>
|
||||
<rect width="100%" height="100%" fill="lime"/>
|
||||
|
||||
<path pathLength="100" d="M175,25 A150,150,0,1,1,175,325 A150,150,0,1,1,175,25"/>
|
||||
</svg>
|
After Width: | Height: | Size: 827 B |
@ -17,8 +17,8 @@ HTTP(..) != graphite-small-caps-1.html graphite-small-caps-1-notref.html
|
||||
== uppercase-1.html uppercase-ref.html
|
||||
== uppercase-szlig-1.html uppercase-szlig-ref.html
|
||||
# these use DejaVu Sans via @font-face for consistency of results
|
||||
skip-if(B2G) HTTP(..) == all-upper.html all-upper-ref.html # bug 773482
|
||||
skip-if(B2G) HTTP(..) == all-lower.html all-lower-ref.html # bug 773482
|
||||
skip-if(B2G) fuzzy-if(cocoaWidget,250,15) HTTP(..) == all-upper.html all-upper-ref.html # bug 773482, 1140292
|
||||
skip-if(B2G) fuzzy-if(cocoaWidget,250,15) HTTP(..) == all-lower.html all-lower-ref.html # bug 773482, 1140292
|
||||
skip-if(B2G) HTTP(..) == all-title.html all-title-ref.html # bug 773482
|
||||
== smtp-upper.html smtp-upper-ref.html
|
||||
== smtp-lower.html smtp-lower-ref.html
|
||||
|
@ -141,6 +141,7 @@ UNIFIED_SOURCES += [
|
||||
'nsDOMCSSRGBColor.cpp',
|
||||
'nsDOMCSSValueList.cpp',
|
||||
'nsFontFaceLoader.cpp',
|
||||
'nsFontFaceUtils.cpp',
|
||||
'nsHTMLCSSStyleSheet.cpp',
|
||||
'nsHTMLStyleSheet.cpp',
|
||||
'nsLayoutStylesheetCache.cpp',
|
||||
@ -184,6 +185,7 @@ FINAL_LIBRARY = 'xul'
|
||||
LOCAL_INCLUDES += [
|
||||
'../base',
|
||||
'../generic',
|
||||
'../svg',
|
||||
'../xul',
|
||||
'/dom/base',
|
||||
'/dom/html',
|
||||
|
@ -121,7 +121,7 @@ nsFontFaceLoader::LoadTimerCallback(nsITimer* aTimer, void* aClosure)
|
||||
NS_ASSERTION(ctx, "userfontset doesn't have a presContext?");
|
||||
if (ctx) {
|
||||
loader->mFontFaceSet->IncrementGeneration();
|
||||
ctx->UserFontSetUpdated();
|
||||
ctx->UserFontSetUpdated(loader->GetUserFontEntry());
|
||||
LOG(("userfonts (%p) timeout reflow\n", loader));
|
||||
}
|
||||
}
|
||||
@ -193,7 +193,7 @@ nsFontFaceLoader::OnStreamComplete(nsIStreamLoader* aLoader,
|
||||
if (fontUpdate) {
|
||||
// Update layout for the presence of the new font. Since this is
|
||||
// asynchronous, reflows will coalesce.
|
||||
ctx->UserFontSetUpdated();
|
||||
ctx->UserFontSetUpdated(mUserFontEntry);
|
||||
LOG(("userfonts (%p) reflow\n", this));
|
||||
}
|
||||
|
||||
|
@ -45,6 +45,7 @@ public:
|
||||
static nsresult CheckLoadAllowed(nsIPrincipal* aSourcePrincipal,
|
||||
nsIURI* aTargetURI,
|
||||
nsISupports* aContext);
|
||||
gfxUserFontEntry* GetUserFontEntry() const { return mUserFontEntry; }
|
||||
|
||||
protected:
|
||||
virtual ~nsFontFaceLoader();
|
||||
|
153
layout/style/nsFontFaceUtils.cpp
Normal file
153
layout/style/nsFontFaceUtils.cpp
Normal file
@ -0,0 +1,153 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
// vim:cindent:ts=2:et:sw=2:
|
||||
/* 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 "gfxUserFontSet.h"
|
||||
#include "nsFontFaceUtils.h"
|
||||
#include "nsFontMetrics.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
#include "nsPlaceholderFrame.h"
|
||||
#include "nsTArray.h"
|
||||
#include "SVGTextFrame.h"
|
||||
|
||||
static bool
|
||||
StyleContextContainsFont(nsStyleContext* aStyleContext,
|
||||
const gfxUserFontSet* aUserFontSet,
|
||||
const gfxUserFontEntry* aFont)
|
||||
{
|
||||
// if the font is null, simply check to see whether fontlist includes
|
||||
// downloadable fonts
|
||||
if (!aFont) {
|
||||
const FontFamilyList& fontlist =
|
||||
aStyleContext->StyleFont()->mFont.fontlist;
|
||||
return aUserFontSet->ContainsUserFontSetFonts(fontlist);
|
||||
}
|
||||
|
||||
// first, check if the family name is in the fontlist
|
||||
const nsString& familyName = aFont->FamilyName();
|
||||
if (!aStyleContext->StyleFont()->mFont.fontlist.Contains(familyName)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// family name is in the fontlist, check to see if the font group
|
||||
// associated with the frame includes the specific userfont
|
||||
nsRefPtr<nsFontMetrics> fm;
|
||||
nsLayoutUtils::GetFontMetricsForStyleContext(aStyleContext,
|
||||
getter_AddRefs(fm),
|
||||
1.0f);
|
||||
|
||||
if (fm->GetThebesFontGroup()->ContainsUserFont(aFont)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool
|
||||
FrameUsesFont(nsIFrame* aFrame, const gfxUserFontEntry* aFont)
|
||||
{
|
||||
// check the style context of the frame
|
||||
gfxUserFontSet* ufs = aFrame->PresContext()->GetUserFontSet();
|
||||
if (StyleContextContainsFont(aFrame->StyleContext(), ufs, aFont)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// check additional style contexts
|
||||
int32_t contextIndex = 0;
|
||||
for (nsStyleContext* extraContext;
|
||||
(extraContext = aFrame->GetAdditionalStyleContext(contextIndex));
|
||||
++contextIndex) {
|
||||
if (StyleContextContainsFont(extraContext, ufs, aFont)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void
|
||||
ScheduleReflow(nsIPresShell* aShell, nsIFrame* aFrame)
|
||||
{
|
||||
nsIFrame* f = aFrame;
|
||||
if (f->IsFrameOfType(nsIFrame::eSVG) || f->IsSVGText()) {
|
||||
// SVG frames (and the non-SVG descendants of an SVGTextFrame) need special
|
||||
// reflow handling. We need to search upwards for the first displayed
|
||||
// nsSVGOuterSVGFrame or non-SVG frame, which is the frame we can call
|
||||
// FrameNeedsReflow on. (This logic is based on
|
||||
// nsSVGUtils::ScheduleReflowSVG and
|
||||
// SVGTextFrame::ScheduleReflowSVGNonDisplayText.)
|
||||
if (f->GetStateBits() & NS_FRAME_IS_NONDISPLAY) {
|
||||
while (f) {
|
||||
if (!(f->GetStateBits() & NS_FRAME_IS_NONDISPLAY)) {
|
||||
if (NS_SUBTREE_DIRTY(f)) {
|
||||
// This is a displayed frame, so if it is already dirty, we
|
||||
// will be reflowed soon anyway. No need to call
|
||||
// FrameNeedsReflow again, then.
|
||||
return;
|
||||
}
|
||||
if (f->GetStateBits() & NS_STATE_IS_OUTER_SVG ||
|
||||
!(f->IsFrameOfType(nsIFrame::eSVG) || f->IsSVGText())) {
|
||||
break;
|
||||
}
|
||||
f->AddStateBits(NS_FRAME_HAS_DIRTY_CHILDREN);
|
||||
}
|
||||
f = f->GetParent();
|
||||
}
|
||||
MOZ_ASSERT(f, "should have found an ancestor frame to reflow");
|
||||
}
|
||||
}
|
||||
|
||||
aShell->FrameNeedsReflow(f, nsIPresShell::eStyleChange, NS_FRAME_IS_DIRTY);
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
nsFontFaceUtils::MarkDirtyForFontChange(nsIFrame* aSubtreeRoot,
|
||||
const gfxUserFontEntry* aFont)
|
||||
{
|
||||
nsAutoTArray<nsIFrame*, 4> subtrees;
|
||||
subtrees.AppendElement(aSubtreeRoot);
|
||||
|
||||
nsIPresShell* ps = aSubtreeRoot->PresContext()->PresShell();
|
||||
|
||||
// check descendants, iterating over subtrees that may include
|
||||
// additional subtrees associated with placeholders
|
||||
do {
|
||||
nsIFrame* subtreeRoot = subtrees.ElementAt(subtrees.Length() - 1);
|
||||
subtrees.RemoveElementAt(subtrees.Length() - 1);
|
||||
|
||||
// Check all descendants to see if they use the font
|
||||
nsAutoTArray<nsIFrame*, 32> stack;
|
||||
stack.AppendElement(subtreeRoot);
|
||||
|
||||
do {
|
||||
nsIFrame* f = stack.ElementAt(stack.Length() - 1);
|
||||
stack.RemoveElementAt(stack.Length() - 1);
|
||||
|
||||
// if this frame uses the font, mark its descendants dirty
|
||||
// and skip checking its children
|
||||
if (FrameUsesFont(f, aFont)) {
|
||||
ScheduleReflow(ps, f);
|
||||
} else {
|
||||
if (f->GetType() == nsGkAtoms::placeholderFrame) {
|
||||
nsIFrame* oof = nsPlaceholderFrame::GetRealFrameForPlaceholder(f);
|
||||
if (!nsLayoutUtils::IsProperAncestorFrame(subtreeRoot, oof)) {
|
||||
// We have another distinct subtree we need to mark.
|
||||
subtrees.AppendElement(oof);
|
||||
}
|
||||
}
|
||||
|
||||
nsIFrame::ChildListIterator lists(f);
|
||||
for (; !lists.IsDone(); lists.Next()) {
|
||||
nsFrameList::Enumerator childFrames(lists.CurrentList());
|
||||
for (; !childFrames.AtEnd(); childFrames.Next()) {
|
||||
nsIFrame* kid = childFrames.get();
|
||||
stack.AppendElement(kid);
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (!stack.IsEmpty());
|
||||
} while (!subtrees.IsEmpty());
|
||||
}
|
23
layout/style/nsFontFaceUtils.h
Normal file
23
layout/style/nsFontFaceUtils.h
Normal file
@ -0,0 +1,23 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
// vim:cindent:ts=2:et:sw=2:
|
||||
/* 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/. */
|
||||
|
||||
/* helper utilities for working with downloadable fonts */
|
||||
|
||||
#ifndef nsFontFaceUtils_h_
|
||||
#define nsFontFaceUtils_h_
|
||||
|
||||
class gfxUserFontEntry;
|
||||
class nsIFrame;
|
||||
|
||||
class nsFontFaceUtils
|
||||
{
|
||||
public:
|
||||
// mark dirty frames affected by a downloadable font
|
||||
static void MarkDirtyForFontChange(nsIFrame* aSubtreeRoot,
|
||||
const gfxUserFontEntry* aFont);
|
||||
};
|
||||
|
||||
#endif /* !defined(nsFontFaceUtils_h_) */
|
@ -508,12 +508,14 @@ static nscoord CalcLengthWith(const nsCSSValue& aValue,
|
||||
return ScaleCoordRound(aValue, float(aFontSize));
|
||||
}
|
||||
case eCSSUnit_XHeight: {
|
||||
aPresContext->SetUsesExChUnits(true);
|
||||
nsRefPtr<nsFontMetrics> fm =
|
||||
GetMetricsFor(aPresContext, aStyleContext, styleFont,
|
||||
aFontSize, aUseUserFontSet);
|
||||
return ScaleCoordRound(aValue, float(fm->XHeight()));
|
||||
}
|
||||
case eCSSUnit_Char: {
|
||||
aPresContext->SetUsesExChUnits(true);
|
||||
nsRefPtr<nsFontMetrics> fm =
|
||||
GetMetricsFor(aPresContext, aStyleContext, styleFont,
|
||||
aFontSize, aUseUserFontSet);
|
||||
|
@ -36,7 +36,6 @@ class DataBuffer {
|
||||
const uint8_t *data() const { return data_.get(); }
|
||||
uint8_t *data() { return data_.get(); }
|
||||
size_t len() const { return len_; }
|
||||
const bool empty() const { return len_ != 0; }
|
||||
|
||||
private:
|
||||
UniquePtr<uint8_t[]> data_;
|
||||
|
@ -25,6 +25,13 @@ namespace net {
|
||||
#define kMinMetadataRead 1024 // TODO find optimal value from telemetry
|
||||
#define kAlignSize 4096
|
||||
|
||||
// Most of the cache entries fit into one chunk due to current chunk size. Make
|
||||
// sure to tweak this value if kChunkSize is going to change.
|
||||
#define kInitialHashArraySize 1
|
||||
|
||||
// Initial elements buffer size.
|
||||
#define kInitialBufSize 64
|
||||
|
||||
#define kCacheEntryVersion 1
|
||||
|
||||
#define NOW_SECONDS() (uint32_t(PR_Now() / PR_USEC_PER_SEC))
|
||||
@ -34,7 +41,6 @@ NS_IMPL_ISUPPORTS(CacheFileMetadata, CacheFileIOListener)
|
||||
CacheFileMetadata::CacheFileMetadata(CacheFileHandle *aHandle, const nsACString &aKey)
|
||||
: CacheMemoryConsumer(NORMAL)
|
||||
, mHandle(aHandle)
|
||||
, mFirstRead(true)
|
||||
, mHashArray(nullptr)
|
||||
, mHashArraySize(0)
|
||||
, mHashCount(0)
|
||||
@ -46,6 +52,8 @@ CacheFileMetadata::CacheFileMetadata(CacheFileHandle *aHandle, const nsACString
|
||||
, mIsDirty(false)
|
||||
, mAnonymous(false)
|
||||
, mInBrowser(false)
|
||||
, mAllocExactSize(false)
|
||||
, mFirstRead(true)
|
||||
, mAppId(nsILoadContextInfo::NO_APP_ID)
|
||||
{
|
||||
LOG(("CacheFileMetadata::CacheFileMetadata() [this=%p, handle=%p, key=%s]",
|
||||
@ -65,7 +73,6 @@ CacheFileMetadata::CacheFileMetadata(CacheFileHandle *aHandle, const nsACString
|
||||
CacheFileMetadata::CacheFileMetadata(bool aMemoryOnly, const nsACString &aKey)
|
||||
: CacheMemoryConsumer(aMemoryOnly ? MEMORY_ONLY : NORMAL)
|
||||
, mHandle(nullptr)
|
||||
, mFirstRead(true)
|
||||
, mHashArray(nullptr)
|
||||
, mHashArraySize(0)
|
||||
, mHashCount(0)
|
||||
@ -77,6 +84,8 @@ CacheFileMetadata::CacheFileMetadata(bool aMemoryOnly, const nsACString &aKey)
|
||||
, mIsDirty(true)
|
||||
, mAnonymous(false)
|
||||
, mInBrowser(false)
|
||||
, mAllocExactSize(false)
|
||||
, mFirstRead(true)
|
||||
, mAppId(nsILoadContextInfo::NO_APP_ID)
|
||||
{
|
||||
LOG(("CacheFileMetadata::CacheFileMetadata() [this=%p, key=%s]",
|
||||
@ -97,7 +106,6 @@ CacheFileMetadata::CacheFileMetadata(bool aMemoryOnly, const nsACString &aKey)
|
||||
CacheFileMetadata::CacheFileMetadata()
|
||||
: CacheMemoryConsumer(DONT_REPORT /* This is a helper class */)
|
||||
, mHandle(nullptr)
|
||||
, mFirstRead(true)
|
||||
, mHashArray(nullptr)
|
||||
, mHashArraySize(0)
|
||||
, mHashCount(0)
|
||||
@ -109,6 +117,8 @@ CacheFileMetadata::CacheFileMetadata()
|
||||
, mIsDirty(false)
|
||||
, mAnonymous(false)
|
||||
, mInBrowser(false)
|
||||
, mAllocExactSize(false)
|
||||
, mFirstRead(true)
|
||||
, mAppId(nsILoadContextInfo::NO_APP_ID)
|
||||
{
|
||||
LOG(("CacheFileMetadata::CacheFileMetadata() [this=%p]", this));
|
||||
@ -485,10 +495,11 @@ CacheFileMetadata::SetHash(uint32_t aIndex, CacheHash::Hash16_t aHash)
|
||||
} else if (aIndex == mHashCount) {
|
||||
if ((aIndex + 1) * sizeof(CacheHash::Hash16_t) > mHashArraySize) {
|
||||
// reallocate hash array buffer
|
||||
if (mHashArraySize == 0)
|
||||
mHashArraySize = 32 * sizeof(CacheHash::Hash16_t);
|
||||
else
|
||||
if (mHashArraySize == 0) {
|
||||
mHashArraySize = kInitialHashArraySize * sizeof(CacheHash::Hash16_t);
|
||||
} else {
|
||||
mHashArraySize *= 2;
|
||||
}
|
||||
mHashArray = static_cast<CacheHash::Hash16_t *>(
|
||||
moz_xrealloc(mHashArray, mHashArraySize));
|
||||
}
|
||||
@ -707,9 +718,17 @@ CacheFileMetadata::OnDataRead(CacheFileHandle *aHandle, char *aBuf,
|
||||
"empty metadata. [this=%p]", this));
|
||||
InitEmptyMetadata();
|
||||
retval = NS_OK;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
retval = NS_OK;
|
||||
|
||||
// Shrink elements buffer.
|
||||
mBuf = static_cast<char *>(moz_xrealloc(mBuf, mElementsSize));
|
||||
mBufSize = mElementsSize;
|
||||
|
||||
// There is usually no or just one call to SetMetadataElement() when the
|
||||
// metadata is parsed from disk. Avoid allocating power of two sized buffer
|
||||
// which we do in case of newly created metadata.
|
||||
mAllocExactSize = true;
|
||||
}
|
||||
|
||||
mListener.swap(listener);
|
||||
@ -859,15 +878,12 @@ CacheFileMetadata::ParseMetadata(uint32_t aMetaOffset, uint32_t aBufOffset,
|
||||
memcpy(mHashArray, mBuf + hashesOffset, mHashArraySize);
|
||||
}
|
||||
|
||||
|
||||
MarkDirty();
|
||||
|
||||
mElementsSize = metaposOffset - elementsOffset;
|
||||
memmove(mBuf, mBuf + elementsOffset, mElementsSize);
|
||||
mOffset = aMetaOffset;
|
||||
|
||||
// TODO: shrink memory if buffer is too big
|
||||
|
||||
DoMemoryReport(MemoryUsage());
|
||||
|
||||
return NS_OK;
|
||||
@ -905,11 +921,30 @@ void
|
||||
CacheFileMetadata::EnsureBuffer(uint32_t aSize)
|
||||
{
|
||||
if (mBufSize < aSize) {
|
||||
if (mAllocExactSize) {
|
||||
// If this is not the only allocation, use power of two for following
|
||||
// allocations.
|
||||
mAllocExactSize = false;
|
||||
} else {
|
||||
// find smallest power of 2 greater than or equal to aSize
|
||||
--aSize;
|
||||
aSize |= aSize >> 1;
|
||||
aSize |= aSize >> 2;
|
||||
aSize |= aSize >> 4;
|
||||
aSize |= aSize >> 8;
|
||||
aSize |= aSize >> 16;
|
||||
++aSize;
|
||||
}
|
||||
|
||||
if (aSize < kInitialBufSize) {
|
||||
aSize = kInitialBufSize;
|
||||
}
|
||||
|
||||
mBufSize = aSize;
|
||||
mBuf = static_cast<char *>(moz_xrealloc(mBuf, mBufSize));
|
||||
}
|
||||
|
||||
DoMemoryReport(MemoryUsage());
|
||||
DoMemoryReport(MemoryUsage());
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -176,8 +176,6 @@ private:
|
||||
|
||||
nsRefPtr<CacheFileHandle> mHandle;
|
||||
nsCString mKey;
|
||||
bool mFirstRead;
|
||||
mozilla::TimeStamp mReadStart;
|
||||
CacheHash::Hash16_t *mHashArray;
|
||||
uint32_t mHashArraySize;
|
||||
uint32_t mHashCount;
|
||||
@ -188,9 +186,12 @@ private:
|
||||
char *mWriteBuf;
|
||||
CacheFileMetadataHeader mMetaHdr;
|
||||
uint32_t mElementsSize;
|
||||
bool mIsDirty;
|
||||
bool mAnonymous;
|
||||
bool mInBrowser;
|
||||
bool mIsDirty : 1;
|
||||
bool mAnonymous : 1;
|
||||
bool mInBrowser : 1;
|
||||
bool mAllocExactSize : 1;
|
||||
bool mFirstRead : 1;
|
||||
mozilla::TimeStamp mReadStart;
|
||||
uint32_t mAppId;
|
||||
nsCOMPtr<CacheFileMetadataListener> mListener;
|
||||
};
|
||||
|
@ -30,14 +30,14 @@ using namespace mozilla::pkix;
|
||||
extern PRLogModuleInfo* gPIPNSSLog;
|
||||
#endif
|
||||
|
||||
static const unsigned int DEFAULT_MINIMUM_NON_ECC_BITS = 2048;
|
||||
static const unsigned int DEFAULT_MIN_RSA_BITS = 2048;
|
||||
|
||||
namespace mozilla { namespace psm {
|
||||
|
||||
AppTrustDomain::AppTrustDomain(ScopedCERTCertList& certChain, void* pinArg)
|
||||
: mCertChain(certChain)
|
||||
, mPinArg(pinArg)
|
||||
, mMinimumNonECCBits(DEFAULT_MINIMUM_NON_ECC_BITS)
|
||||
, mMinRSABits(DEFAULT_MIN_RSA_BITS)
|
||||
{
|
||||
}
|
||||
|
||||
@ -75,7 +75,7 @@ AppTrustDomain::SetTrustedRoot(AppTrustedRoot trustedRoot)
|
||||
trustedDER.data = const_cast<uint8_t*>(marketplaceStageRoot);
|
||||
trustedDER.len = mozilla::ArrayLength(marketplaceStageRoot);
|
||||
// The staging root was generated with a 1024-bit key.
|
||||
mMinimumNonECCBits = 1024u;
|
||||
mMinRSABits = 1024u;
|
||||
break;
|
||||
|
||||
case nsIX509CertDB::AppXPCShellRoot:
|
||||
@ -254,7 +254,7 @@ Result
|
||||
AppTrustDomain::CheckRSAPublicKeyModulusSizeInBits(
|
||||
EndEntityOrCA /*endEntityOrCA*/, unsigned int modulusSizeInBits)
|
||||
{
|
||||
if (modulusSizeInBits < mMinimumNonECCBits) {
|
||||
if (modulusSizeInBits < mMinRSABits) {
|
||||
return Result::ERROR_INADEQUATE_KEY_SIZE;
|
||||
}
|
||||
return Success;
|
||||
|
@ -61,7 +61,7 @@ private:
|
||||
/*out*/ ScopedCERTCertList& mCertChain;
|
||||
void* mPinArg; // non-owning!
|
||||
ScopedCERTCertificate mTrustedRoot;
|
||||
unsigned int mMinimumNonECCBits;
|
||||
unsigned int mMinRSABits;
|
||||
};
|
||||
|
||||
} } // namespace mozilla::psm
|
||||
|
@ -156,8 +156,8 @@ BuildCertChainForOneKeyUsage(NSSCertDBTrustDomain& trustDomain, Input certDER,
|
||||
return rv;
|
||||
}
|
||||
|
||||
static const unsigned int MINIMUM_NON_ECC_BITS = 2048;
|
||||
static const unsigned int MINIMUM_NON_ECC_BITS_WEAK = 1024;
|
||||
static const unsigned int MIN_RSA_BITS = 2048;
|
||||
static const unsigned int MIN_RSA_BITS_WEAK = 1024;
|
||||
|
||||
SECStatus
|
||||
CertVerifier::VerifyCert(CERTCertificate* cert, SECCertificateUsage usage,
|
||||
@ -240,8 +240,7 @@ CertVerifier::VerifyCert(CERTCertificate* cert, SECCertificateUsage usage,
|
||||
// just use trustEmail as it is the closest alternative.
|
||||
NSSCertDBTrustDomain trustDomain(trustEmail, ocspFetching, mOCSPCache,
|
||||
pinArg, ocspGETConfig, pinningDisabled,
|
||||
MINIMUM_NON_ECC_BITS_WEAK, nullptr,
|
||||
builtChain);
|
||||
MIN_RSA_BITS_WEAK, nullptr, builtChain);
|
||||
rv = BuildCertChain(trustDomain, certDER, time,
|
||||
EndEntityOrCA::MustBeEndEntity,
|
||||
KeyUsage::digitalSignature,
|
||||
@ -267,7 +266,7 @@ CertVerifier::VerifyCert(CERTCertificate* cert, SECCertificateUsage usage,
|
||||
? NSSCertDBTrustDomain::LocalOnlyOCSPForEV
|
||||
: NSSCertDBTrustDomain::FetchOCSPForEV,
|
||||
mOCSPCache, pinArg, ocspGETConfig, mPinningMode,
|
||||
MINIMUM_NON_ECC_BITS, hostname, builtChain);
|
||||
MIN_RSA_BITS, hostname, builtChain);
|
||||
rv = BuildCertChainForOneKeyUsage(trustDomain, certDER, time,
|
||||
KeyUsage::digitalSignature,// (EC)DHE
|
||||
KeyUsage::keyEncipherment, // RSA
|
||||
@ -292,8 +291,7 @@ CertVerifier::VerifyCert(CERTCertificate* cert, SECCertificateUsage usage,
|
||||
// Now try non-EV.
|
||||
NSSCertDBTrustDomain trustDomain(trustSSL, ocspFetching, mOCSPCache,
|
||||
pinArg, ocspGETConfig, mPinningMode,
|
||||
MINIMUM_NON_ECC_BITS, hostname,
|
||||
builtChain);
|
||||
MIN_RSA_BITS, hostname, builtChain);
|
||||
rv = BuildCertChainForOneKeyUsage(trustDomain, certDER, time,
|
||||
KeyUsage::digitalSignature, // (EC)DHE
|
||||
KeyUsage::keyEncipherment, // RSA
|
||||
@ -312,7 +310,7 @@ CertVerifier::VerifyCert(CERTCertificate* cert, SECCertificateUsage usage,
|
||||
// If that failed, try again with a smaller minimum key size.
|
||||
NSSCertDBTrustDomain trustDomainWeak(trustSSL, ocspFetching, mOCSPCache,
|
||||
pinArg, ocspGETConfig, mPinningMode,
|
||||
MINIMUM_NON_ECC_BITS_WEAK, hostname,
|
||||
MIN_RSA_BITS_WEAK, hostname,
|
||||
builtChain);
|
||||
rv = BuildCertChainForOneKeyUsage(trustDomainWeak, certDER, time,
|
||||
KeyUsage::digitalSignature, // (EC)DHE
|
||||
@ -336,8 +334,7 @@ CertVerifier::VerifyCert(CERTCertificate* cert, SECCertificateUsage usage,
|
||||
case certificateUsageSSLCA: {
|
||||
NSSCertDBTrustDomain trustDomain(trustSSL, ocspFetching, mOCSPCache,
|
||||
pinArg, ocspGETConfig, pinningDisabled,
|
||||
MINIMUM_NON_ECC_BITS_WEAK, nullptr,
|
||||
builtChain);
|
||||
MIN_RSA_BITS_WEAK, nullptr, builtChain);
|
||||
rv = BuildCertChain(trustDomain, certDER, time,
|
||||
EndEntityOrCA::MustBeCA, KeyUsage::keyCertSign,
|
||||
KeyPurposeId::id_kp_serverAuth,
|
||||
@ -348,8 +345,7 @@ CertVerifier::VerifyCert(CERTCertificate* cert, SECCertificateUsage usage,
|
||||
case certificateUsageEmailSigner: {
|
||||
NSSCertDBTrustDomain trustDomain(trustEmail, ocspFetching, mOCSPCache,
|
||||
pinArg, ocspGETConfig, pinningDisabled,
|
||||
MINIMUM_NON_ECC_BITS_WEAK, nullptr,
|
||||
builtChain);
|
||||
MIN_RSA_BITS_WEAK, nullptr, builtChain);
|
||||
rv = BuildCertChain(trustDomain, certDER, time,
|
||||
EndEntityOrCA::MustBeEndEntity,
|
||||
KeyUsage::digitalSignature,
|
||||
@ -371,8 +367,7 @@ CertVerifier::VerifyCert(CERTCertificate* cert, SECCertificateUsage usage,
|
||||
// based on the result of the verification(s).
|
||||
NSSCertDBTrustDomain trustDomain(trustEmail, ocspFetching, mOCSPCache,
|
||||
pinArg, ocspGETConfig, pinningDisabled,
|
||||
MINIMUM_NON_ECC_BITS_WEAK, nullptr,
|
||||
builtChain);
|
||||
MIN_RSA_BITS_WEAK, nullptr, builtChain);
|
||||
rv = BuildCertChain(trustDomain, certDER, time,
|
||||
EndEntityOrCA::MustBeEndEntity,
|
||||
KeyUsage::keyEncipherment, // RSA
|
||||
@ -392,8 +387,7 @@ CertVerifier::VerifyCert(CERTCertificate* cert, SECCertificateUsage usage,
|
||||
NSSCertDBTrustDomain trustDomain(trustObjectSigning, ocspFetching,
|
||||
mOCSPCache, pinArg, ocspGETConfig,
|
||||
pinningDisabled,
|
||||
MINIMUM_NON_ECC_BITS_WEAK, nullptr,
|
||||
builtChain);
|
||||
MIN_RSA_BITS_WEAK, nullptr, builtChain);
|
||||
rv = BuildCertChain(trustDomain, certDER, time,
|
||||
EndEntityOrCA::MustBeEndEntity,
|
||||
KeyUsage::digitalSignature,
|
||||
@ -422,16 +416,14 @@ CertVerifier::VerifyCert(CERTCertificate* cert, SECCertificateUsage usage,
|
||||
|
||||
NSSCertDBTrustDomain sslTrust(trustSSL, ocspFetching, mOCSPCache, pinArg,
|
||||
ocspGETConfig, pinningDisabled,
|
||||
MINIMUM_NON_ECC_BITS_WEAK, nullptr,
|
||||
builtChain);
|
||||
MIN_RSA_BITS_WEAK, nullptr, builtChain);
|
||||
rv = BuildCertChain(sslTrust, certDER, time, endEntityOrCA,
|
||||
keyUsage, eku, CertPolicyId::anyPolicy,
|
||||
stapledOCSPResponse);
|
||||
if (rv == Result::ERROR_UNKNOWN_ISSUER) {
|
||||
NSSCertDBTrustDomain emailTrust(trustEmail, ocspFetching, mOCSPCache,
|
||||
pinArg, ocspGETConfig, pinningDisabled,
|
||||
MINIMUM_NON_ECC_BITS_WEAK, nullptr,
|
||||
builtChain);
|
||||
MIN_RSA_BITS_WEAK, nullptr, builtChain);
|
||||
rv = BuildCertChain(emailTrust, certDER, time, endEntityOrCA,
|
||||
keyUsage, eku, CertPolicyId::anyPolicy,
|
||||
stapledOCSPResponse);
|
||||
@ -440,7 +432,7 @@ CertVerifier::VerifyCert(CERTCertificate* cert, SECCertificateUsage usage,
|
||||
ocspFetching, mOCSPCache,
|
||||
pinArg, ocspGETConfig,
|
||||
pinningDisabled,
|
||||
MINIMUM_NON_ECC_BITS_WEAK,
|
||||
MIN_RSA_BITS_WEAK,
|
||||
nullptr, builtChain);
|
||||
rv = BuildCertChain(objectSigningTrust, certDER, time,
|
||||
endEntityOrCA, keyUsage, eku,
|
||||
|
@ -53,7 +53,7 @@ NSSCertDBTrustDomain::NSSCertDBTrustDomain(SECTrustType certDBTrustType,
|
||||
/*optional but shouldn't be*/ void* pinArg,
|
||||
CertVerifier::OcspGetConfig ocspGETConfig,
|
||||
CertVerifier::PinningMode pinningMode,
|
||||
unsigned int minimumNonECCKeyBits,
|
||||
unsigned int minRSABits,
|
||||
/*optional*/ const char* hostname,
|
||||
/*optional*/ ScopedCERTCertList* builtChain)
|
||||
: mCertDBTrustType(certDBTrustType)
|
||||
@ -62,7 +62,7 @@ NSSCertDBTrustDomain::NSSCertDBTrustDomain(SECTrustType certDBTrustType,
|
||||
, mPinArg(pinArg)
|
||||
, mOCSPGetConfig(ocspGETConfig)
|
||||
, mPinningMode(pinningMode)
|
||||
, mMinimumNonECCBits(minimumNonECCKeyBits)
|
||||
, mMinRSABits(minRSABits)
|
||||
, mHostname(hostname)
|
||||
, mBuiltChain(builtChain)
|
||||
, mCertBlocklist(do_GetService(NS_CERTBLOCKLIST_CONTRACTID))
|
||||
@ -720,7 +720,7 @@ Result
|
||||
NSSCertDBTrustDomain::CheckRSAPublicKeyModulusSizeInBits(
|
||||
EndEntityOrCA /*endEntityOrCA*/, unsigned int modulusSizeInBits)
|
||||
{
|
||||
if (modulusSizeInBits < mMinimumNonECCBits) {
|
||||
if (modulusSizeInBits < mMinRSABits) {
|
||||
return Result::ERROR_INADEQUATE_KEY_SIZE;
|
||||
}
|
||||
return Success;
|
||||
|
@ -56,7 +56,7 @@ public:
|
||||
OCSPCache& ocspCache, void* pinArg,
|
||||
CertVerifier::OcspGetConfig ocspGETConfig,
|
||||
CertVerifier::PinningMode pinningMode,
|
||||
unsigned int minimumNonECCKeyBits,
|
||||
unsigned int minRSABits,
|
||||
/*optional*/ const char* hostname = nullptr,
|
||||
/*optional out*/ ScopedCERTCertList* builtChain = nullptr);
|
||||
|
||||
@ -130,7 +130,7 @@ private:
|
||||
void* mPinArg; // non-owning!
|
||||
const CertVerifier::OcspGetConfig mOCSPGetConfig;
|
||||
CertVerifier::PinningMode mPinningMode;
|
||||
const unsigned int mMinimumNonECCBits;
|
||||
const unsigned int mMinRSABits;
|
||||
const char* mHostname; // non-owning - only used for pinning checks
|
||||
ScopedCERTCertList* mBuiltChain; // non-owning
|
||||
nsCOMPtr<nsICertBlocklist> mCertBlocklist;
|
||||
|
@ -256,6 +256,9 @@ function add_connection_test(aHost, aExpectedResult,
|
||||
let sts = Cc["@mozilla.org/network/socket-transport-service;1"]
|
||||
.getService(Ci.nsISocketTransportService);
|
||||
this.transport = sts.createTransport(["ssl"], 1, aHost, REMOTE_PORT, null);
|
||||
// See bug 1129771 - attempting to connect to [::1] when the server is
|
||||
// listening on 127.0.0.1 causes frequent failures on OS X 10.10.
|
||||
this.transport.connectionFlags |= Ci.nsISocketTransport.DISABLE_IPV6;
|
||||
this.transport.setEventSink(this, this.thread);
|
||||
this.inputStream = null;
|
||||
this.outputStream = null;
|
||||
|
3
security/manager/ssl/tests/unit/test_keysize/generate.py
Normal file → Executable file
3
security/manager/ssl/tests/unit/test_keysize/generate.py
Normal file → Executable file
@ -245,9 +245,6 @@ def generate_combination_chains():
|
||||
# Create a NSS DB for use by the OCSP responder.
|
||||
CertUtils.init_nss_db(srcdir)
|
||||
|
||||
# TODO(bug 636807): SECKEY_PublicKeyStrengthInBits() rounds up the number of
|
||||
# bits to the next multiple of 8 - therefore the highest key size less than 1024
|
||||
# that can be tested is 1016, less than 2048 is 2040 and so on.
|
||||
generate_rsa_chains('1016', '1024', False)
|
||||
generate_rsa_chains('2040', '2048', True)
|
||||
generate_ecc_chains()
|
||||
|
@ -85,7 +85,7 @@ function addKeySizeTestForEV(expectedNamesForOCSP,
|
||||
* none of the chains validate as EV.
|
||||
*
|
||||
* Note: This function assumes that the key size requirements for EV are greater
|
||||
* than or equal to the requirements for DV.
|
||||
* than the requirements for DV.
|
||||
*
|
||||
* @param {Number} inadequateKeySize
|
||||
* The inadequate key size of the generated certs.
|
||||
|
@ -635,10 +635,10 @@ class MarionetteTestCase(CommonTestCase):
|
||||
(self.filepath.replace('\\', '\\\\'), self.methodName))
|
||||
|
||||
def tearDown(self):
|
||||
self.marionette.check_for_crash()
|
||||
self.marionette.set_context("content")
|
||||
self.marionette.execute_script("log('TEST-END: %s:%s')" %
|
||||
(self.filepath.replace('\\', '\\\\'), self.methodName))
|
||||
if not self.marionette.check_for_crash():
|
||||
self.marionette.set_context("content")
|
||||
self.marionette.execute_script("log('TEST-END: %s:%s')" %
|
||||
(self.filepath.replace('\\', '\\\\'), self.methodName))
|
||||
self.marionette.test_name = None
|
||||
CommonTestCase.tearDown(self)
|
||||
|
||||
|
@ -207,15 +207,21 @@ MarionetteServerConnection.prototype = {
|
||||
this.logRequest(aPacket.name, aPacket);
|
||||
this.requestTypes[aPacket.name].bind(this)(aPacket);
|
||||
} catch(e) {
|
||||
this.conn.send({ error: ("error occurred while processing '" +
|
||||
aPacket.name),
|
||||
message: e.message });
|
||||
this.conn.send({from:this.actorID, error: {
|
||||
message: ("error occurred while processing '" +
|
||||
aPacket.name),
|
||||
status: 500,
|
||||
stacktrace: e.message }});
|
||||
}
|
||||
} else {
|
||||
this.conn.send({ error: "unrecognizedPacketType",
|
||||
message: ('Marionette does not ' +
|
||||
'recognize the packet type "' +
|
||||
aPacket.name + '"') });
|
||||
this.conn.send({from:this.actorID, error: {
|
||||
message: "unrecognizedPacketType",
|
||||
status: 500,
|
||||
stacktrace: ('Marionette does not ' +
|
||||
'recognize the packet type "' +
|
||||
aPacket.name + '"')
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
import sys
|
||||
import os
|
||||
import optparse
|
||||
|
||||
from collections import defaultdict
|
||||
@ -59,8 +60,11 @@ fmt_options = {
|
||||
def log_file(name):
|
||||
if name == "-":
|
||||
return sys.stdout
|
||||
else:
|
||||
return open(name, "w")
|
||||
# ensure we have a correct dirpath by using realpath
|
||||
dirpath = os.path.dirname(os.path.realpath(name))
|
||||
if not os.path.exists(dirpath):
|
||||
os.makedirs(dirpath)
|
||||
return open(name, "w")
|
||||
|
||||
|
||||
def add_logging_group(parser, include_formatters=None):
|
||||
|
4
testing/web-platform/harness/.gitignore
vendored
4
testing/web-platform/harness/.gitignore
vendored
@ -2,4 +2,6 @@
|
||||
*~
|
||||
*#
|
||||
\#*
|
||||
_virtualenv
|
||||
_virtualenv
|
||||
test/test.cfg
|
||||
test/metadata/MANIFEST.json
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user