Merge inbound to m-c. a=merge

CLOSED TREE
This commit is contained in:
Ryan VanderMeulen 2015-03-06 16:18:04 -05:00
commit 8aaa845a81
209 changed files with 16954 additions and 8686 deletions

View File

@ -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");

View File

@ -525,7 +525,6 @@ SECKEY_ExtractPublicKey
SECKEY_GetPublicKeyType
SECKEY_ImportDERPublicKey
SECKEY_PublicKeyStrength
SECKEY_PublicKeyStrengthInBits
SECKEY_RSAPSSParamsTemplate DATA
SECKEY_SignatureLen
SECMIME_DecryptionAllowed

View File

@ -858,7 +858,7 @@ Console::Assert(JSContext* aCx, bool aCondition,
METHOD(Count, "count")
void
Console::__noSuchMethod__()
Console::NoopMethod()
{
// Nothing to do.
}

View File

@ -101,7 +101,7 @@ public:
Count(JSContext* aCx, const Sequence<JS::Value>& aData);
void
__noSuchMethod__();
NoopMethod();
private:
enum MethodName

View File

@ -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,

View File

@ -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;
}

View File

@ -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'

View File

@ -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; }

View File

@ -22,7 +22,6 @@ struct PCacheQueryParams
bool ignoreSearch;
bool ignoreMethod;
bool ignoreVary;
bool prefixMatch;
bool cacheNameSet;
nsString cacheName;
};

View File

@ -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();

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -33,7 +33,6 @@ dictionary CacheQueryOptions {
boolean ignoreSearch = false;
boolean ignoreMethod = false;
boolean ignoreVary = false;
boolean prefixMatch = false;
DOMString cacheName;
};

View File

@ -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"
};

View File

@ -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 {

View File

@ -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.

View File

@ -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);

View File

@ -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 {

View File

@ -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();
};

View File

@ -21,6 +21,7 @@ interface WorkerGlobalScope : EventTarget {
readonly attribute WorkerLocation location;
[Throws]
void close();
attribute OnErrorEventHandler onerror;

View File

@ -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;
}

View File

@ -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

View File

@ -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();
}

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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();

View File

@ -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

View File

@ -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);

View File

@ -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();

View 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();
}

View 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

View File

@ -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*

View File

@ -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();

View File

@ -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',

View File

@ -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:

View 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"});
});
}
}

View File

@ -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>

View File

@ -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);
}
});
}

View File

@ -0,0 +1,6 @@
<!DOCTYPE html>
<script>
navigator.serviceWorker.onmessage = function(e) {
window.parent.postMessage(e.data, "*");
};
</script>

View File

@ -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]

View 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
});
}
});
});

View 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>

View File

@ -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>

View File

@ -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>

View 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();
});
});
});
});
});

View File

@ -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);
}
}

View File

@ -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()
{

View File

@ -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.

View File

@ -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

View File

@ -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);
};

View File

@ -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 ||

View File

@ -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.

View File

@ -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)

View File

@ -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

View File

@ -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)
{

View File

@ -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; }

View File

@ -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
}

View File

@ -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);
};

View File

@ -252,11 +252,6 @@ struct VMFunction
}
VMFunction(const VMFunction &o) {
init(o);
}
void init(const VMFunction &o) {
MOZ_ASSERT(!wrapped);
*this = o;
addToFunctions();
}

View File

@ -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);

View File

@ -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

View File

@ -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*

View File

@ -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;

View File

@ -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),

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View File

@ -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

View File

@ -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

File diff suppressed because one or more lines are too long

View File

@ -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

View 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

View File

@ -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

View File

@ -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',

View File

@ -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));
}

View File

@ -45,6 +45,7 @@ public:
static nsresult CheckLoadAllowed(nsIPrincipal* aSourcePrincipal,
nsIURI* aTargetURI,
nsISupports* aContext);
gfxUserFontEntry* GetUserFontEntry() const { return mUserFontEntry; }
protected:
virtual ~nsFontFaceLoader();

View 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());
}

View 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_) */

View File

@ -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);

View File

@ -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_;

View File

@ -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

View File

@ -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;
};

View File

@ -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;

View File

@ -61,7 +61,7 @@ private:
/*out*/ ScopedCERTCertList& mCertChain;
void* mPinArg; // non-owning!
ScopedCERTCertificate mTrustedRoot;
unsigned int mMinimumNonECCBits;
unsigned int mMinRSABits;
};
} } // namespace mozilla::psm

View File

@ -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,

View File

@ -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;

View File

@ -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;

View File

@ -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;

View 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()

View File

@ -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.

View File

@ -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)

View File

@ -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 + '"')
}
});
}
},

View File

@ -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):

View File

@ -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