mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 14:30:27 +00:00
import changes from `dev' branch of rmottola/Arctic-Fox:
- Bug 1248105 - Move CSSPseudoElement::GetParentObject out of header, r=boris (b851c3806d) - Bug 1248581 - Fix build bustage on WakeLock.h and CSSPseudoElement.h. r=khuey (fb47a96889) - Bug 1249230 - Prepend an extra colon to the pseudo type string. r=birtles (6af63f00de) - fix build on Mac > 10.5 (1ae9402eaf) - Bug 1241118 - Add gc = GetGeneralCategory(ch) when sc == MOZ_SCRIPT_COMMON. r=jfkthame (51dfbede47) - minor crash rep (1e7e5bc97e) - Bug 1240904 - Remove ParamTraits for NPString and NPVariant. r=bsmedberg (1850d10374) - bug 1170584 - fix PluginMessageUtils on iOS. r=jimm (c624cbe92d) - Bug 1170343 - Use release-mode asserts when plugins making NPAPI calls on the wrong thread, r=mccr8 (15c71250f4) - Bug 1239525 - Make sure async plugin initialization is off if e10s is on. r=aklotz (07e73ce74d) - Bug 1128454 - When plugin bridging fails, propagate the error back to the content process without aborting tabs. r=billm (e1547c00ab) - Bug 1222169 - remove unused function from PluginProcessChild.cpp; r=aklotz (11a8fc32e1) - Bug 1239749 - Remove extra space from PermissionSettings.js debug message. r=gwagner (abe2ac7574) - Bug 1221104 - Revoke 'midi' permission queries with TypeError. r=baku (cce673498f) - Bug 1221104 - Throw NS_ERROR_NOT_IMPLEMENTED instead of NS_ERROR_UNEXPECTED for PushPermissionDescriptor.userVisible. r=baku (face32ed7b) - Bug 1228723 - Avoid a promise worker proxy deadlock caused by synchronous Push callbacks. r=catalinb (bd564a0483) - Bug 1191931, Part 1 - Use tasks in the Push subscription tests. r=mt (3109fdf2af) - Bug 1191931, Part 2 - Test resubscribing from a worker. r=m (9527fa2672) - Bug 1243781 - Push methods called from a worker should reject with a `DOMException`. r=mt (f66818b161) - Bug 1219064 - Add test for extendable pushsubscriptionchange event. r=mt (12af4b59dd) - Bug 1176449 - Enter an update here to avoid assertions on startup. r=dbaron (1109cce81d) - Bug 1239743: Do not allow windows to be resized to sizes above the maximum texture size. We don't know how to draw to these anyway. r=jimm (694dafd544) - Remove some static_casting in CompositorParent. (bug 1245765 part 5, r=mattwoodrow) (4c7f39b18e) - Bug 1133615 - Don't assert about the contents of RestyleData::mDescendants when in a full style rebuild. r=dbaron (2b071b90d2) - Bug 1237902 (part 1) - Remove unneeded gfxContext ops in DrawTableBorderSegment(). r=roc. (8490ab67ca) - Bug 1237902 (part 2) - Pass a DrawTarget to DrawTableBorderSegment(). r=roc. (c602535af0) - Bug 1237902 (part 3) - Change the gfxContextMatrixAutoSaveRestore in PaintTableBorderBackground() to an AutoRestoreTransform. r=roc. (0b2412e7d6) - Bug 1242164 - Remove the implementation of colspan=0 (which is now dead code). r=dbaron (88555a04a4) - Bug 1235478 - Part 1: Rename eAdjustingTimer to eForceAdjustTimer. r=mchang (113a98fa28) - Bug 1235478 - Part 2: Don't update mMostRecentRefresh when nsRefreshDriver::ScheduleViewManagerFlush is called. r=mchang (7fd8599b7b) - Bug 1235478 - Part 3: Make weightmapping-12579.html fuzzy on MacOS 10.10. r=jdaggett (559683f95d) - Bug 1234049 - Ensure we always invalidate new PresShells that are created for an inactive DocShell upon reactivating them. r=smaug (aeca3e08d9) - Re-backout c216ff19d690 (bug 1059014 part 3) because the removed code is less dead than it first appears. (2cce434c50)
This commit is contained in:
@@ -31,7 +31,7 @@ class nsDOMNavigationTiming;
|
||||
[ptr] native nsDOMNavigationTimingPtr(nsDOMNavigationTiming);
|
||||
[ref] native nsIContentViewerTArray(nsTArray<nsCOMPtr<nsIContentViewer> >);
|
||||
|
||||
[scriptable, builtinclass, uuid(702e0a92-7d63-490e-b5ee-d247e6bd4588)]
|
||||
[scriptable, builtinclass, uuid(2da17016-7851-4a45-a7a8-00b360e01595)]
|
||||
interface nsIContentViewer : nsISupports
|
||||
{
|
||||
|
||||
@@ -245,6 +245,18 @@ interface nsIContentViewer : nsISupports
|
||||
*/
|
||||
[noscript] void appendSubtree(in nsIContentViewerTArray array);
|
||||
|
||||
/**
|
||||
* Instruct the refresh driver to discontinue painting until further
|
||||
* notice.
|
||||
*/
|
||||
void pausePainting();
|
||||
|
||||
/**
|
||||
* Instruct the refresh driver to resume painting after a previous call to
|
||||
* pausePainting().
|
||||
*/
|
||||
void resumePainting();
|
||||
|
||||
/*
|
||||
* Render the document as if being viewed on a device with the specified
|
||||
* media type. This will cause a reflow.
|
||||
|
||||
@@ -36,6 +36,12 @@ CSSPseudoElement::~CSSPseudoElement()
|
||||
}
|
||||
}
|
||||
|
||||
ParentObject
|
||||
CSSPseudoElement::GetParentObject() const
|
||||
{
|
||||
return mParentElement->GetParentObject();
|
||||
}
|
||||
|
||||
JSObject*
|
||||
CSSPseudoElement::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
||||
{
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "mozilla/dom/BindingDeclarations.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "nsCSSPseudoElements.h"
|
||||
#include "nsWrapperCache.h"
|
||||
@@ -32,10 +33,7 @@ protected:
|
||||
virtual ~CSSPseudoElement();
|
||||
|
||||
public:
|
||||
ParentObject GetParentObject() const
|
||||
{
|
||||
return mParentElement->GetParentObject();
|
||||
}
|
||||
ParentObject GetParentObject() const;
|
||||
|
||||
virtual JSObject* WrapObject(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) override;
|
||||
@@ -46,7 +44,12 @@ public:
|
||||
MOZ_ASSERT(nsCSSPseudoElements::GetPseudoAtom(mPseudoType),
|
||||
"All pseudo-types allowed by this class should have a"
|
||||
" corresponding atom");
|
||||
nsCSSPseudoElements::GetPseudoAtom(mPseudoType)->ToString(aRetVal);
|
||||
// Our atoms use one colon and we would like to return two colons syntax
|
||||
// for the returned pseudo type string, so serialize this to the
|
||||
// non-deprecated two colon syntax.
|
||||
aRetVal.Assign(char16_t(':'));
|
||||
aRetVal.Append(
|
||||
nsDependentAtomString(nsCSSPseudoElements::GetPseudoAtom(mPseudoType)));
|
||||
}
|
||||
already_AddRefed<Element> ParentElement() const
|
||||
{
|
||||
|
||||
@@ -3700,8 +3700,10 @@ nsDOMWindowUtils::GetContentAPZTestData(JSContext* aContext,
|
||||
|
||||
if (nsIWidget* widget = GetWidget()) {
|
||||
RefPtr<LayerManager> lm = widget->GetLayerManager();
|
||||
if (lm && lm->GetBackendType() == LayersBackend::LAYERS_CLIENT) {
|
||||
ClientLayerManager* clm = static_cast<ClientLayerManager*>(lm.get());
|
||||
if (!lm) {
|
||||
return NS_OK;
|
||||
}
|
||||
if (ClientLayerManager* clm = lm->AsClientLayerManager()) {
|
||||
if (!clm->GetAPZTestData().ToJS(aOutContentTestData, aContext)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
@@ -3719,8 +3721,10 @@ nsDOMWindowUtils::GetCompositorAPZTestData(JSContext* aContext,
|
||||
|
||||
if (nsIWidget* widget = GetWidget()) {
|
||||
RefPtr<LayerManager> lm = widget->GetLayerManager();
|
||||
if (lm && lm->GetBackendType() == LayersBackend::LAYERS_CLIENT) {
|
||||
ClientLayerManager* clm = static_cast<ClientLayerManager*>(lm.get());
|
||||
if (!lm) {
|
||||
return NS_OK;
|
||||
}
|
||||
if (ClientLayerManager* clm = lm->AsClientLayerManager()) {
|
||||
APZTestData compositorSideData;
|
||||
clm->GetCompositorSideAPZTestData(&compositorSideData);
|
||||
if (!compositorSideData.ToJS(aOutCompositorTestData, aContext)) {
|
||||
@@ -3955,9 +3959,8 @@ nsDOMWindowUtils::SetNextPaintSyncId(int32_t aSyncId)
|
||||
MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
|
||||
if (nsIWidget* widget = GetWidget()) {
|
||||
RefPtr<LayerManager> lm = widget->GetLayerManager();
|
||||
if (lm && lm->GetBackendType() == LayersBackend::LAYERS_CLIENT) {
|
||||
ClientLayerManager* clm = static_cast<ClientLayerManager*>(lm.get());
|
||||
clm->SetNextPaintSyncId(aSyncId);
|
||||
if (lm && lm->AsClientLayerManager()) {
|
||||
lm->AsClientLayerManager()->SetNextPaintSyncId(aSyncId);
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,6 +159,7 @@ CreateException(JSContext* aCx, nsresult aRv, const nsACString& aMessage)
|
||||
case NS_ERROR_MODULE_DOM_FILEHANDLE:
|
||||
case NS_ERROR_MODULE_DOM_BLUETOOTH:
|
||||
case NS_ERROR_MODULE_DOM_ANIM:
|
||||
case NS_ERROR_MODULE_DOM_PUSH:
|
||||
if (aMessage.IsEmpty()) {
|
||||
return DOMException::Create(aRv);
|
||||
}
|
||||
|
||||
@@ -2793,7 +2793,7 @@ TabChild::DidComposite(uint64_t aTransactionId,
|
||||
MOZ_ASSERT(mPuppetWidget->GetLayerManager()->GetBackendType() ==
|
||||
LayersBackend::LAYERS_CLIENT);
|
||||
|
||||
RefPtr<ClientLayerManager> manager =
|
||||
ClientLayerManager *manager =
|
||||
static_cast<ClientLayerManager*>(mPuppetWidget->GetLayerManager());
|
||||
|
||||
manager->DidComposite(aTransactionId, aCompositeStart, aCompositeEnd);
|
||||
@@ -2827,8 +2827,7 @@ TabChild::ClearCachedResources()
|
||||
MOZ_ASSERT(mPuppetWidget->GetLayerManager()->GetBackendType() ==
|
||||
LayersBackend::LAYERS_CLIENT);
|
||||
|
||||
ClientLayerManager *manager =
|
||||
static_cast<ClientLayerManager*>(mPuppetWidget->GetLayerManager());
|
||||
ClientLayerManager *manager = mPuppetWidget->GetLayerManager()->AsClientLayerManager();
|
||||
manager->ClearCachedResources();
|
||||
}
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@ PermissionSettings.prototype = {
|
||||
set: function set(aPermName, aPermValue, aManifestURL, aOrigin,
|
||||
aBrowserFlag) {
|
||||
debug("Set called with: " + aPermName + ", " + aManifestURL + ", " +
|
||||
aOrigin + ", " + aPermValue + ", " + aBrowserFlag);
|
||||
aOrigin + ", " + aPermValue + ", " + aBrowserFlag);
|
||||
let currentPermValue = this.get(aPermName, aManifestURL, aOrigin,
|
||||
aBrowserFlag);
|
||||
let action;
|
||||
|
||||
@@ -122,8 +122,8 @@ CheckPermission(JSContext* aCx,
|
||||
case PermissionName::Push:
|
||||
return CheckPushPermission(aCx, aPermission, aWindow, aResult);
|
||||
|
||||
case PermissionName::Midi:
|
||||
default:
|
||||
MOZ_ASSERT_UNREACHABLE("Unhandled type");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,9 @@
|
||||
#include "nsTArray.h"
|
||||
#include "mozilla/Logging.h"
|
||||
#include "nsHashKeys.h"
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
# include "nsExceptionHandler.h"
|
||||
#endif
|
||||
#ifdef XP_MACOSX
|
||||
#include "PluginInterposeOSX.h"
|
||||
#else
|
||||
@@ -100,7 +103,7 @@ struct NPRemoteWindow
|
||||
typedef HWND NativeWindowHandle;
|
||||
#elif defined(MOZ_X11)
|
||||
typedef XID NativeWindowHandle;
|
||||
#elif defined(XP_MACOSX) || defined(ANDROID) || defined(MOZ_WIDGET_QT)
|
||||
#elif defined(XP_DARWIN) || defined(ANDROID) || defined(MOZ_WIDGET_QT)
|
||||
typedef intptr_t NativeWindowHandle; // never actually used, will always be 0
|
||||
#else
|
||||
#error Need NativeWindowHandle for this platform
|
||||
@@ -195,7 +198,7 @@ inline bool IsPluginThread()
|
||||
|
||||
inline void AssertPluginThread()
|
||||
{
|
||||
NS_ASSERTION(IsPluginThread(), "Should be on the plugin's main thread!");
|
||||
MOZ_RELEASE_ASSERT(IsPluginThread(), "Should be on the plugin's main thread!");
|
||||
}
|
||||
|
||||
#define ENSURE_PLUGIN_THREAD(retval) \
|
||||
@@ -405,44 +408,6 @@ struct ParamTraits<mozilla::plugins::NPRemoteWindow>
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ParamTraits<NPString>
|
||||
{
|
||||
typedef NPString paramType;
|
||||
|
||||
static void Write(Message* aMsg, const paramType& aParam)
|
||||
{
|
||||
WriteParam(aMsg, aParam.UTF8Length);
|
||||
aMsg->WriteBytes(aParam.UTF8Characters,
|
||||
aParam.UTF8Length * sizeof(NPUTF8));
|
||||
}
|
||||
|
||||
static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
|
||||
{
|
||||
if (ReadParam(aMsg, aIter, &aResult->UTF8Length)) {
|
||||
int byteCount = aResult->UTF8Length * sizeof(NPUTF8);
|
||||
if (!byteCount) {
|
||||
aResult->UTF8Characters = "\0";
|
||||
return true;
|
||||
}
|
||||
|
||||
const char* messageBuffer = nullptr;
|
||||
mozilla::UniquePtr<char[]> newBuffer(new char[byteCount]);
|
||||
if (newBuffer && aMsg->ReadBytes(aIter, &messageBuffer, byteCount )) {
|
||||
memcpy((void*)messageBuffer, newBuffer.get(), byteCount);
|
||||
aResult->UTF8Characters = newBuffer.release();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void Log(const paramType& aParam, std::wstring* aLog)
|
||||
{
|
||||
aLog->append(StringPrintf(L"%s", aParam.UTF8Characters));
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
template <>
|
||||
struct ParamTraits<NPNSString*>
|
||||
@@ -608,142 +573,6 @@ struct ParamTraits<NSCursorInfo>
|
||||
};
|
||||
#endif // #ifdef XP_MACOSX
|
||||
|
||||
template <>
|
||||
struct ParamTraits<NPVariant>
|
||||
{
|
||||
typedef NPVariant paramType;
|
||||
|
||||
static void Write(Message* aMsg, const paramType& aParam)
|
||||
{
|
||||
if (NPVARIANT_IS_VOID(aParam)) {
|
||||
aMsg->WriteInt(0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (NPVARIANT_IS_NULL(aParam)) {
|
||||
aMsg->WriteInt(1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (NPVARIANT_IS_BOOLEAN(aParam)) {
|
||||
aMsg->WriteInt(2);
|
||||
WriteParam(aMsg, NPVARIANT_TO_BOOLEAN(aParam));
|
||||
return;
|
||||
}
|
||||
|
||||
if (NPVARIANT_IS_INT32(aParam)) {
|
||||
aMsg->WriteInt(3);
|
||||
WriteParam(aMsg, NPVARIANT_TO_INT32(aParam));
|
||||
return;
|
||||
}
|
||||
|
||||
if (NPVARIANT_IS_DOUBLE(aParam)) {
|
||||
aMsg->WriteInt(4);
|
||||
WriteParam(aMsg, NPVARIANT_TO_DOUBLE(aParam));
|
||||
return;
|
||||
}
|
||||
|
||||
if (NPVARIANT_IS_STRING(aParam)) {
|
||||
aMsg->WriteInt(5);
|
||||
WriteParam(aMsg, NPVARIANT_TO_STRING(aParam));
|
||||
return;
|
||||
}
|
||||
|
||||
NS_ERROR("Unsupported type!");
|
||||
}
|
||||
|
||||
static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
|
||||
{
|
||||
int type;
|
||||
if (!aMsg->ReadInt(aIter, &type)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case 0:
|
||||
VOID_TO_NPVARIANT(*aResult);
|
||||
return true;
|
||||
|
||||
case 1:
|
||||
NULL_TO_NPVARIANT(*aResult);
|
||||
return true;
|
||||
|
||||
case 2: {
|
||||
bool value;
|
||||
if (ReadParam(aMsg, aIter, &value)) {
|
||||
BOOLEAN_TO_NPVARIANT(value, *aResult);
|
||||
return true;
|
||||
}
|
||||
} break;
|
||||
|
||||
case 3: {
|
||||
int32_t value;
|
||||
if (ReadParam(aMsg, aIter, &value)) {
|
||||
INT32_TO_NPVARIANT(value, *aResult);
|
||||
return true;
|
||||
}
|
||||
} break;
|
||||
|
||||
case 4: {
|
||||
double value;
|
||||
if (ReadParam(aMsg, aIter, &value)) {
|
||||
DOUBLE_TO_NPVARIANT(value, *aResult);
|
||||
return true;
|
||||
}
|
||||
} break;
|
||||
|
||||
case 5: {
|
||||
NPString value;
|
||||
if (ReadParam(aMsg, aIter, &value)) {
|
||||
STRINGN_TO_NPVARIANT(value.UTF8Characters, value.UTF8Length,
|
||||
*aResult);
|
||||
return true;
|
||||
}
|
||||
} break;
|
||||
|
||||
default:
|
||||
NS_ERROR("Unsupported type!");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void Log(const paramType& aParam, std::wstring* aLog)
|
||||
{
|
||||
if (NPVARIANT_IS_VOID(aParam)) {
|
||||
aLog->append(L"[void]");
|
||||
return;
|
||||
}
|
||||
|
||||
if (NPVARIANT_IS_NULL(aParam)) {
|
||||
aLog->append(L"[null]");
|
||||
return;
|
||||
}
|
||||
|
||||
if (NPVARIANT_IS_BOOLEAN(aParam)) {
|
||||
LogParam(NPVARIANT_TO_BOOLEAN(aParam), aLog);
|
||||
return;
|
||||
}
|
||||
|
||||
if (NPVARIANT_IS_INT32(aParam)) {
|
||||
LogParam(NPVARIANT_TO_INT32(aParam), aLog);
|
||||
return;
|
||||
}
|
||||
|
||||
if (NPVARIANT_IS_DOUBLE(aParam)) {
|
||||
LogParam(NPVARIANT_TO_DOUBLE(aParam), aLog);
|
||||
return;
|
||||
}
|
||||
|
||||
if (NPVARIANT_IS_STRING(aParam)) {
|
||||
LogParam(NPVARIANT_TO_STRING(aParam), aLog);
|
||||
return;
|
||||
}
|
||||
|
||||
NS_ERROR("Unsupported type!");
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ParamTraits<mozilla::plugins::IPCByteRange>
|
||||
{
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "nsCRT.h"
|
||||
#include "nsIFile.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsIXULRuntime.h"
|
||||
#include "nsNPAPIPlugin.h"
|
||||
#include "nsPrintfCString.h"
|
||||
#include "prsystem.h"
|
||||
@@ -133,16 +134,6 @@ mozilla::plugins::SetupBridge(uint32_t aPluginId,
|
||||
return true;
|
||||
}
|
||||
*rv = PPluginModule::Bridge(aContentParent, chromeParent);
|
||||
if (NS_FAILED(*rv)) {
|
||||
#if defined(MOZ_CRASHREPORTER)
|
||||
// We are going to abort due to the failure, lets note the cause
|
||||
// in the report for diagnosing.
|
||||
nsAutoCString error;
|
||||
error.AppendPrintf("%X %d", *rv, chromeParent->GetIPCChannel()->GetChannelState__TotallyRacy());
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("BridgePluginError"), error);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -673,7 +664,8 @@ PluginModuleParent::PluginModuleParent(bool aIsChrome, bool aAllowAsyncInit)
|
||||
{
|
||||
#if defined(XP_WIN) || defined(XP_MACOSX) || defined(MOZ_WIDGET_GTK)
|
||||
mIsStartingAsync = aAllowAsyncInit &&
|
||||
Preferences::GetBool(kAsyncInitPref, false);
|
||||
Preferences::GetBool(kAsyncInitPref, false) &&
|
||||
!BrowserTabsRemoteAutostart();
|
||||
#if defined(MOZ_CRASHREPORTER)
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AsyncPluginInit"),
|
||||
mIsStartingAsync ?
|
||||
|
||||
@@ -35,16 +35,6 @@ using mozilla::ipc::IOThreadChild;
|
||||
#ifdef OS_WIN
|
||||
#include "nsSetDllDirectory.h"
|
||||
#include <algorithm>
|
||||
|
||||
namespace {
|
||||
|
||||
std::size_t caseInsensitiveFind(std::string aHaystack, std::string aNeedle) {
|
||||
std::transform(aHaystack.begin(), aHaystack.end(), aHaystack.begin(), ::tolower);
|
||||
std::transform(aNeedle.begin(), aNeedle.end(), aNeedle.begin(), ::tolower);
|
||||
return aHaystack.find(aNeedle);
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#include "nsWrapperCache.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
|
||||
class nsIDOMWindow;
|
||||
class nsPIDOMWindowInner;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
+28
-13
@@ -105,7 +105,7 @@ public:
|
||||
if (NS_SUCCEEDED(aStatus)) {
|
||||
mPromise->MaybeResolve(aSuccess);
|
||||
} else {
|
||||
mPromise->MaybeReject(NS_ERROR_DOM_NETWORK_ERR);
|
||||
mPromise->MaybeReject(NS_ERROR_DOM_PUSH_SERVICE_UNREACHABLE);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
@@ -403,7 +403,7 @@ public:
|
||||
if (NS_SUCCEEDED(mStatus)) {
|
||||
promise->MaybeResolve(mSuccess);
|
||||
} else {
|
||||
promise->MaybeReject(NS_ERROR_DOM_NETWORK_ERR);
|
||||
promise->MaybeReject(NS_ERROR_DOM_PUSH_SERVICE_UNREACHABLE);
|
||||
}
|
||||
|
||||
mProxy->CleanUp(aCx);
|
||||
@@ -477,10 +477,16 @@ public:
|
||||
Run() override
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
MutexAutoLock lock(mProxy->Lock());
|
||||
if (mProxy->CleanedUp()) {
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
{
|
||||
MutexAutoLock lock(mProxy->Lock());
|
||||
if (mProxy->CleanedUp()) {
|
||||
return NS_OK;
|
||||
}
|
||||
principal = mProxy->GetWorkerPrivate()->GetPrincipal();
|
||||
}
|
||||
MOZ_ASSERT(principal);
|
||||
|
||||
RefPtr<WorkerUnsubscribeResultCallback> callback =
|
||||
new WorkerUnsubscribeResultCallback(mProxy);
|
||||
@@ -492,7 +498,6 @@ public:
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPrincipal> principal = mProxy->GetWorkerPrivate()->GetPrincipal();
|
||||
if (NS_WARN_IF(NS_FAILED(service->Unsubscribe(mScope, principal, callback)))) {
|
||||
callback->OnUnsubscribe(NS_ERROR_FAILURE, false);
|
||||
return NS_OK;
|
||||
@@ -523,7 +528,7 @@ WorkerPushSubscription::Unsubscribe(ErrorResult &aRv)
|
||||
|
||||
RefPtr<PromiseWorkerProxy> proxy = PromiseWorkerProxy::Create(worker, p);
|
||||
if (!proxy) {
|
||||
p->MaybeReject(NS_ERROR_DOM_NETWORK_ERR);
|
||||
p->MaybeReject(NS_ERROR_DOM_PUSH_SERVICE_UNREACHABLE);
|
||||
return p.forget();
|
||||
}
|
||||
|
||||
@@ -593,6 +598,8 @@ public:
|
||||
mRawP256dhKey, mAuthSecret);
|
||||
promise->MaybeResolve(sub);
|
||||
}
|
||||
} else if (NS_ERROR_GET_MODULE(mStatus) == NS_ERROR_MODULE_DOM_PUSH ) {
|
||||
promise->MaybeReject(mStatus);
|
||||
} else {
|
||||
promise->MaybeReject(NS_ERROR_DOM_PUSH_ABORT_ERR);
|
||||
}
|
||||
@@ -742,15 +749,23 @@ public:
|
||||
Run() override
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
MutexAutoLock lock(mProxy->Lock());
|
||||
if (mProxy->CleanedUp()) {
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
{
|
||||
// Bug 1228723: If permission is revoked or an error occurs, the
|
||||
// subscription callback will be called synchronously. This causes
|
||||
// `GetSubscriptionCallback::OnPushSubscription` to deadlock when
|
||||
// it tries to acquire the lock.
|
||||
MutexAutoLock lock(mProxy->Lock());
|
||||
if (mProxy->CleanedUp()) {
|
||||
return NS_OK;
|
||||
}
|
||||
principal = mProxy->GetWorkerPrivate()->GetPrincipal();
|
||||
}
|
||||
MOZ_ASSERT(principal);
|
||||
|
||||
RefPtr<GetSubscriptionCallback> callback = new GetSubscriptionCallback(mProxy, mScope);
|
||||
|
||||
nsCOMPtr<nsIPrincipal> principal = mProxy->GetWorkerPrivate()->GetPrincipal();
|
||||
|
||||
PushPermissionState state;
|
||||
nsresult rv = GetPermissionState(principal, state);
|
||||
if (NS_FAILED(rv)) {
|
||||
@@ -763,7 +778,7 @@ public:
|
||||
callback->OnPushSubscriptionError(NS_OK);
|
||||
return NS_OK;
|
||||
}
|
||||
callback->OnPushSubscriptionError(NS_ERROR_FAILURE);
|
||||
callback->OnPushSubscriptionError(NS_ERROR_DOM_PUSH_DENIED_ERR);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,20 +4,18 @@
|
||||
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
|
||||
<script>
|
||||
|
||||
|
||||
function waitOnPushMessage(pushSubscription)
|
||||
{
|
||||
var p = new Promise(function(res, rej) {
|
||||
navigator.serviceWorker.onmessage = function(e) {
|
||||
if (e.data.type == "finished") {
|
||||
function waitOnWorkerMessage(type) {
|
||||
return new Promise(function(res, rej) {
|
||||
function onMessage(e) {
|
||||
if (e.data.type == type) {
|
||||
navigator.serviceWorker.removeEventListener("message", onMessage);
|
||||
(e.data.okay == "yes" ? res : rej)(e.data);
|
||||
}
|
||||
};
|
||||
}
|
||||
navigator.serviceWorker.addEventListener("message", onMessage);
|
||||
});
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@@ -6,6 +6,7 @@ support-files =
|
||||
frame.html
|
||||
webpush.js
|
||||
lifetime_worker.js
|
||||
test_utils.js
|
||||
|
||||
[test_has_permissions.html]
|
||||
skip-if = os == "android" || toolkit == "gonk"
|
||||
@@ -21,6 +22,8 @@ skip-if = os == "android" || toolkit == "gonk"
|
||||
skip-if = os == "android" || toolkit == "gonk"
|
||||
[test_multiple_register_different_scope.html]
|
||||
skip-if = os == "android" || toolkit == "gonk"
|
||||
[test_subscription_change.html]
|
||||
skip-if = os == "android" || toolkit == "gonk"
|
||||
[test_data.html]
|
||||
skip-if = os == "android" || toolkit == "gonk"
|
||||
# Disabled for too many intermittent failures (bug 1164432)
|
||||
|
||||
@@ -11,6 +11,7 @@ http://creativecommons.org/licenses/publicdomain/
|
||||
<title>Test for Bug 1185544</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
|
||||
<script type="text/javascript" src="/tests/dom/push/test/test_utils.js"></script>
|
||||
<script type="text/javascript" src="/tests/dom/push/test/webpush.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
|
||||
@@ -25,25 +26,10 @@ http://creativecommons.org/licenses/publicdomain/
|
||||
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
SimpleTest.registerCleanupFunction(() =>
|
||||
new Promise(resolve => SpecialPowers.popPermissions(resolve))
|
||||
);
|
||||
|
||||
var registration;
|
||||
add_task(function* start() {
|
||||
yield new Promise(resolve => {
|
||||
SpecialPowers.pushPermissions([
|
||||
{ type: "desktop-notification", allow: true, context: document },
|
||||
], resolve);
|
||||
});
|
||||
yield new Promise(resolve => {
|
||||
SpecialPowers.pushPrefEnv({"set": [
|
||||
["dom.push.enabled", true],
|
||||
["dom.serviceWorkers.exemptFromPerDomainMax", true],
|
||||
["dom.serviceWorkers.enabled", true],
|
||||
["dom.serviceWorkers.testing.enabled", true]
|
||||
]}, resolve);
|
||||
});
|
||||
yield setupPrefs();
|
||||
yield setPushPermission(true);
|
||||
|
||||
var url = "worker.js" + "?" + (Math.random());
|
||||
registration = yield navigator.serviceWorker.register(url, {scope: "."});
|
||||
@@ -51,15 +37,7 @@ http://creativecommons.org/licenses/publicdomain/
|
||||
|
||||
var controlledFrame;
|
||||
add_task(function* createControlledIFrame() {
|
||||
yield new Promise(function(res, rej) {
|
||||
var iframe = document.createElement('iframe');
|
||||
iframe.id = "controlledFrame";
|
||||
iframe.src = "http://mochi.test:8888/tests/dom/push/test/frame.html";
|
||||
|
||||
iframe.onload = () => res();
|
||||
controlledFrame = iframe;
|
||||
document.body.appendChild(iframe);
|
||||
});
|
||||
controlledFrame = yield injectControlledFrame();
|
||||
});
|
||||
|
||||
var pushSubscription;
|
||||
@@ -67,16 +45,6 @@ http://creativecommons.org/licenses/publicdomain/
|
||||
pushSubscription = yield registration.pushManager.subscribe();
|
||||
});
|
||||
|
||||
function sendRequestToWorker(request) {
|
||||
return new Promise((resolve, reject) => {
|
||||
var channel = new MessageChannel();
|
||||
channel.port1.onmessage = e => {
|
||||
(e.data.error ? reject : resolve)(e.data);
|
||||
};
|
||||
registration.active.postMessage(request, [channel.port2]);
|
||||
});
|
||||
}
|
||||
|
||||
function base64UrlDecode(s) {
|
||||
s = s.replace(/-/g, '+').replace(/_/g, '/');
|
||||
|
||||
@@ -138,7 +106,7 @@ http://creativecommons.org/licenses/publicdomain/
|
||||
|
||||
function waitForMessage(pushSubscription, message) {
|
||||
return Promise.all([
|
||||
controlledFrame.contentWindow.waitOnPushMessage(pushSubscription),
|
||||
controlledFrame.waitOnWorkerMessage("finished"),
|
||||
webpush(pushSubscription, message),
|
||||
]).then(([message]) => message);
|
||||
}
|
||||
@@ -190,11 +158,10 @@ http://creativecommons.org/licenses/publicdomain/
|
||||
reader.readAsText(message.data.blob);
|
||||
});
|
||||
is(text, "Hi! \ud83d\udc40", "Wrong blob data for message with emoji");
|
||||
is(text, "Hi! \ud83d\udc40", "Wrong blob data for message with emoji");
|
||||
|
||||
// Send a blank message.
|
||||
var [message] = yield Promise.all([
|
||||
controlledFrame.contentWindow.waitOnPushMessage(pushSubscription),
|
||||
controlledFrame.waitOnWorkerMessage("finished"),
|
||||
fetch("http://mochi.test:8888/tests/dom/push/test/push-server.sjs", {
|
||||
method: "PUT",
|
||||
headers: {
|
||||
@@ -207,8 +174,7 @@ http://creativecommons.org/licenses/publicdomain/
|
||||
});
|
||||
|
||||
add_task(function* unsubscribe() {
|
||||
controlledFrame.parentNode.removeChild(controlledFrame);
|
||||
controlledFrame = null;
|
||||
controlledFrame.remove();
|
||||
yield pushSubscription.unsubscribe();
|
||||
});
|
||||
|
||||
|
||||
@@ -10,6 +10,8 @@ http://creativecommons.org/licenses/publicdomain/
|
||||
<head>
|
||||
<title>Test for Bug 1038811</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
|
||||
<script type="text/javascript" src="/tests/dom/push/test/test_utils.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
|
||||
</head>
|
||||
@@ -27,111 +29,63 @@ http://creativecommons.org/licenses/publicdomain/
|
||||
// console.log(str + "\n");
|
||||
}
|
||||
|
||||
var controlledFrame;
|
||||
function createControlledIFrame(swr) {
|
||||
var p = new Promise(function(res, rej) {
|
||||
var iframe = document.createElement('iframe');
|
||||
iframe.id = "controlledFrame";
|
||||
iframe.src = "http://mochi.test:8888/tests/dom/push/test/frame.html";
|
||||
|
||||
iframe.onload = function() {
|
||||
res(swr)
|
||||
}
|
||||
controlledFrame = iframe;
|
||||
document.body.appendChild(iframe);
|
||||
});
|
||||
return p;
|
||||
}
|
||||
|
||||
function checkPermissionState(swr) {
|
||||
return swr.pushManager.permissionState().then(function(state) {
|
||||
ok(state === "granted", "permissionState() should resolve to granted.");
|
||||
return swr;
|
||||
}).catch(function(e) {
|
||||
ok(false, "permissionState() should resolve to granted.");
|
||||
return swr;
|
||||
});
|
||||
}
|
||||
|
||||
function sendPushToPushServer(pushEndpoint) {
|
||||
// Work around CORS for now.
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open('GET', "http://mochi.test:8888/tests/dom/push/test/push-server.sjs", true);
|
||||
xhr.setRequestHeader("X-Push-Server", pushEndpoint);
|
||||
xhr.onload = function(e) {
|
||||
debug("xhr : " + this.status);
|
||||
}
|
||||
xhr.onerror = function(e) {
|
||||
debug("xhr error: " + e);
|
||||
}
|
||||
xhr.send("version=24601");
|
||||
}
|
||||
|
||||
var registration;
|
||||
add_task(function* start() {
|
||||
yield setupPrefs();
|
||||
yield setPushPermission(true);
|
||||
|
||||
function start() {
|
||||
return navigator.serviceWorker.register("worker.js" + "?" + (Math.random()), {scope: "."})
|
||||
.then((swr) => registration = swr);
|
||||
}
|
||||
var url = "worker.js" + "?" + (Math.random());
|
||||
registration = yield navigator.serviceWorker.register(url, {scope: "."});
|
||||
});
|
||||
|
||||
function unregister() {
|
||||
return registration.unregister().then(function(result) {
|
||||
ok(result, "Unregister should return true.");
|
||||
}, function(e) {
|
||||
dump("Unregistering the SW failed with " + e + "\n");
|
||||
var controlledFrame;
|
||||
add_task(function* createControlledIFrame() {
|
||||
controlledFrame = yield injectControlledFrame();
|
||||
});
|
||||
|
||||
add_task(function* checkPermissionState() {
|
||||
var state = yield registration.pushManager.permissionState();
|
||||
is(state, "granted", "permissionState() should resolve to granted.");
|
||||
});
|
||||
|
||||
var pushSubscription;
|
||||
add_task(function* subscribe() {
|
||||
pushSubscription = yield registration.pushManager.subscribe();
|
||||
});
|
||||
|
||||
add_task(function* resubscribe() {
|
||||
var data = yield sendRequestToWorker({
|
||||
type: "resubscribe",
|
||||
endpoint: pushSubscription.endpoint,
|
||||
});
|
||||
}
|
||||
pushSubscription = yield registration.pushManager.getSubscription();
|
||||
is(data.endpoint, pushSubscription.endpoint,
|
||||
"Subscription endpoints should match after resubscribing in worker");
|
||||
});
|
||||
|
||||
function setupPushNotification(swr) {
|
||||
var p = new Promise(function(res, rej) {
|
||||
swr.pushManager.subscribe().then(
|
||||
function(pushSubscription) {
|
||||
ok(true, "successful registered for push notification");
|
||||
res(pushSubscription);
|
||||
}, function(error) {
|
||||
ok(false, "could not register for push notification");
|
||||
res(null);
|
||||
}
|
||||
);
|
||||
});
|
||||
return p;
|
||||
}
|
||||
add_task(function* waitForPushNotification() {
|
||||
yield Promise.all([
|
||||
controlledFrame.waitOnWorkerMessage("finished"),
|
||||
fetch("http://mochi.test:8888/tests/dom/push/test/push-server.sjs", {
|
||||
method: "PUT",
|
||||
headers: {
|
||||
"X-Push-Method": "POST",
|
||||
"X-Push-Server": pushSubscription.endpoint,
|
||||
},
|
||||
}),
|
||||
]);
|
||||
});
|
||||
|
||||
function unregisterPushNotification(pushSubscription) {
|
||||
controlledFrame.parentNode.removeChild(controlledFrame);
|
||||
controlledFrame = null;
|
||||
return pushSubscription.unsubscribe();
|
||||
}
|
||||
add_task(function* unsubscribe() {
|
||||
controlledFrame.remove();
|
||||
yield pushSubscription.unsubscribe();
|
||||
});
|
||||
|
||||
function waitForPushNotification(pushSubscription) {
|
||||
var p = controlledFrame.contentWindow.waitOnPushMessage();
|
||||
sendPushToPushServer(pushSubscription.endpoint);
|
||||
return p.then(function() {
|
||||
return pushSubscription;
|
||||
});
|
||||
}
|
||||
add_task(function* unregister() {
|
||||
var result = yield registration.unregister();
|
||||
ok(result, "Unregister should return true.");
|
||||
});
|
||||
|
||||
function runTest() {
|
||||
start()
|
||||
.then(createControlledIFrame)
|
||||
.then(checkPermissionState)
|
||||
.then(setupPushNotification)
|
||||
.then(waitForPushNotification)
|
||||
.then(unregisterPushNotification)
|
||||
.then(unregister)
|
||||
.catch(function(e) {
|
||||
ok(false, "Some test failed with error " + e);
|
||||
}).then(SimpleTest.finish);
|
||||
}
|
||||
|
||||
SpecialPowers.pushPrefEnv({"set": [
|
||||
["dom.push.enabled", true],
|
||||
["dom.serviceWorkers.exemptFromPerDomainMax", true],
|
||||
["dom.serviceWorkers.enabled", true],
|
||||
["dom.serviceWorkers.testing.enabled", true]
|
||||
]}, runTest);
|
||||
SpecialPowers.addPermission('push', true, document);
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
Bug 1205109: Make `pushsubscriptionchange` extendable.
|
||||
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/licenses/publicdomain/
|
||||
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 1205109</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
|
||||
<script type="text/javascript" src="/tests/dom/push/test/test_utils.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
|
||||
</head>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1205109">Mozilla Bug 1205109</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
var registration;
|
||||
add_task(function* start() {
|
||||
yield setupPrefs();
|
||||
yield setPushPermission(true);
|
||||
|
||||
var url = "worker.js" + "?" + (Math.random());
|
||||
registration = yield navigator.serviceWorker.register(url, {scope: "."});
|
||||
});
|
||||
|
||||
var controlledFrame;
|
||||
add_task(function* createControlledIFrame() {
|
||||
controlledFrame = yield injectControlledFrame();
|
||||
});
|
||||
|
||||
add_task(function* togglePermission() {
|
||||
var subscription = yield registration.pushManager.subscribe();
|
||||
ok(subscription, "Should create a push subscription");
|
||||
|
||||
yield setPushPermission(false);
|
||||
var permissionState = yield registration.pushManager.permissionState();
|
||||
is(permissionState, "denied", "Should deny push permission");
|
||||
|
||||
var subscription = yield registration.pushManager.getSubscription();
|
||||
is(subscription, null, "Should not return subscription when permission is revoked");
|
||||
|
||||
var changePromise = controlledFrame.waitOnWorkerMessage("changed");
|
||||
yield setPushPermission(true);
|
||||
yield changePromise;
|
||||
|
||||
subscription = yield registration.pushManager.getSubscription();
|
||||
is(subscription, null, "Should drop subscription after reinstating permission");
|
||||
});
|
||||
|
||||
add_task(function* unsubscribe() {
|
||||
controlledFrame.remove();
|
||||
yield registration.unregister();
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,60 @@
|
||||
// Remove permissions and prefs when the test finishes.
|
||||
SimpleTest.registerCleanupFunction(() =>
|
||||
new Promise(resolve => {
|
||||
SpecialPowers.flushPermissions(_ => {
|
||||
SpecialPowers.flushPrefEnv(resolve);
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
function setPushPermission(allow) {
|
||||
return new Promise(resolve => {
|
||||
SpecialPowers.pushPermissions([
|
||||
{ type: "desktop-notification", allow, context: document },
|
||||
], resolve);
|
||||
});
|
||||
}
|
||||
|
||||
function setupPrefs() {
|
||||
return new Promise(resolve => {
|
||||
SpecialPowers.pushPrefEnv({"set": [
|
||||
["dom.push.enabled", true],
|
||||
["dom.serviceWorkers.exemptFromPerDomainMax", true],
|
||||
["dom.serviceWorkers.enabled", true],
|
||||
["dom.serviceWorkers.testing.enabled", true]
|
||||
]}, resolve);
|
||||
});
|
||||
}
|
||||
|
||||
function injectControlledFrame(target = document.body) {
|
||||
return new Promise(function(res, rej) {
|
||||
var iframe = document.createElement("iframe");
|
||||
iframe.src = "/tests/dom/push/test/frame.html";
|
||||
|
||||
var controlledFrame = {
|
||||
remove() {
|
||||
target.removeChild(iframe);
|
||||
iframe = null;
|
||||
},
|
||||
waitOnWorkerMessage(type) {
|
||||
return iframe ? iframe.contentWindow.waitOnWorkerMessage(type) :
|
||||
Promise.reject(new Error("Frame removed from document"));
|
||||
},
|
||||
};
|
||||
|
||||
iframe.onload = () => res(controlledFrame);
|
||||
target.appendChild(iframe);
|
||||
});
|
||||
}
|
||||
|
||||
function sendRequestToWorker(request) {
|
||||
return navigator.serviceWorker.ready.then(registration => {
|
||||
return new Promise((resolve, reject) => {
|
||||
var channel = new MessageChannel();
|
||||
channel.port1.onmessage = e => {
|
||||
(e.data.error ? reject : resolve)(e.data);
|
||||
};
|
||||
registration.active.postMessage(request, [channel.port2]);
|
||||
});
|
||||
});
|
||||
}
|
||||
+97
-32
@@ -1,8 +1,16 @@
|
||||
// Any copyright is dedicated to the Public Domain.
|
||||
// http://creativecommons.org/licenses/publicdomain/
|
||||
|
||||
// This worker is used for two types of tests. `handlePush` sends messages to
|
||||
// `frame.html`, which verifies that the worker can receive push messages.
|
||||
|
||||
// `handleMessage` receives messages from `test_push_manager_worker.html`
|
||||
// and `test_data.html`, and verifies that `PushManager` can be used from
|
||||
// the worker.
|
||||
|
||||
this.onpush = handlePush;
|
||||
this.onmessage = handleMessage;
|
||||
this.onpushsubscriptionchange = handlePushSubscriptionChange;
|
||||
|
||||
function getJSON(data) {
|
||||
var result = {
|
||||
@@ -17,48 +25,105 @@ function getJSON(data) {
|
||||
return result;
|
||||
}
|
||||
|
||||
function handlePush(event) {
|
||||
function assert(value, message) {
|
||||
if (!value) {
|
||||
throw new Error(message);
|
||||
}
|
||||
}
|
||||
|
||||
event.waitUntil(self.clients.matchAll().then(function(result) {
|
||||
if (event instanceof PushEvent) {
|
||||
if (!('data' in event)) {
|
||||
result[0].postMessage({type: "finished", okay: "yes"});
|
||||
return;
|
||||
}
|
||||
var message = {
|
||||
type: "finished",
|
||||
okay: "yes",
|
||||
};
|
||||
if (event.data) {
|
||||
message.data = {
|
||||
text: event.data.text(),
|
||||
arrayBuffer: event.data.arrayBuffer(),
|
||||
json: getJSON(event.data),
|
||||
blob: event.data.blob(),
|
||||
};
|
||||
}
|
||||
result[0].postMessage(message);
|
||||
function broadcast(event, promise) {
|
||||
event.waitUntil(Promise.resolve(promise).then(message => {
|
||||
return self.clients.matchAll().then(clients => {
|
||||
clients.forEach(client => client.postMessage(message));
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
function reply(event, promise) {
|
||||
event.waitUntil(Promise.resolve(promise).then(result => {
|
||||
event.ports[0].postMessage(result);
|
||||
}).catch(error => {
|
||||
event.ports[0].postMessage({
|
||||
error: String(error),
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
function handlePush(event) {
|
||||
if (event instanceof PushEvent) {
|
||||
if (!('data' in event)) {
|
||||
broadcast(event, {type: "finished", okay: "yes"});
|
||||
return;
|
||||
}
|
||||
result[0].postMessage({type: "finished", okay: "no"});
|
||||
}));
|
||||
var message = {
|
||||
type: "finished",
|
||||
okay: "yes",
|
||||
};
|
||||
if (event.data) {
|
||||
message.data = {
|
||||
text: event.data.text(),
|
||||
arrayBuffer: event.data.arrayBuffer(),
|
||||
json: getJSON(event.data),
|
||||
blob: event.data.blob(),
|
||||
};
|
||||
}
|
||||
broadcast(event, message);
|
||||
return;
|
||||
}
|
||||
broadcast(event, {type: "finished", okay: "no"});
|
||||
}
|
||||
|
||||
function handleMessage(event) {
|
||||
if (event.data.type == "publicKey") {
|
||||
event.waitUntil(self.registration.pushManager.getSubscription().then(subscription => {
|
||||
event.ports[0].postMessage({
|
||||
reply(event, self.registration.pushManager.getSubscription().then(
|
||||
subscription => ({
|
||||
p256dh: subscription.getKey("p256dh"),
|
||||
auth: subscription.getKey("auth"),
|
||||
});
|
||||
}).catch(error => {
|
||||
event.ports[0].postMessage({
|
||||
error: String(error),
|
||||
});
|
||||
})
|
||||
));
|
||||
return;
|
||||
}
|
||||
if (event.data.type == "resubscribe") {
|
||||
reply(event, self.registration.pushManager.getSubscription().then(
|
||||
subscription => {
|
||||
assert(subscription.endpoint == event.data.endpoint,
|
||||
"Wrong push endpoint in worker");
|
||||
return subscription.unsubscribe();
|
||||
}
|
||||
).then(result => {
|
||||
assert(result, "Error unsubscribing in worker");
|
||||
return self.registration.pushManager.getSubscription();
|
||||
}).then(subscription => {
|
||||
assert(!subscription, "Subscription not removed in worker");
|
||||
return self.registration.pushManager.subscribe();
|
||||
}).then(subscription => {
|
||||
return {
|
||||
endpoint: subscription.endpoint,
|
||||
};
|
||||
}));
|
||||
return;
|
||||
}
|
||||
event.ports[0].postMessage({
|
||||
error: "Invalid message type: " + event.data.type,
|
||||
});
|
||||
if (event.data.type == "denySubscribe") {
|
||||
reply(event, self.registration.pushManager.getSubscription().then(
|
||||
subscription => {
|
||||
assert(!subscription,
|
||||
"Should not return worker subscription with revoked permission");
|
||||
return self.registration.pushManager.subscribe().then(_ => {
|
||||
assert(false, "Expected error subscribing with revoked permission");
|
||||
}, error => {
|
||||
return {
|
||||
isDOMException: error instanceof DOMException,
|
||||
name: error.name,
|
||||
};
|
||||
});
|
||||
}
|
||||
));
|
||||
return;
|
||||
}
|
||||
reply(event, Promise.reject(
|
||||
"Invalid message type: " + event.data.type));
|
||||
}
|
||||
|
||||
function handlePushSubscriptionChange(event) {
|
||||
broadcast(event, {type: "changed", okay: "yes"});
|
||||
}
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
enum PermissionName {
|
||||
"geolocation",
|
||||
"notifications",
|
||||
"push",
|
||||
"midi"
|
||||
"push"
|
||||
// Unsupported: "midi"
|
||||
};
|
||||
|
||||
dictionary PermissionDescriptor {
|
||||
|
||||
@@ -92,6 +92,7 @@
|
||||
#include "nsJSUtils.h"
|
||||
#include "mozilla/dom/URL.h"
|
||||
#include "nsIContentPolicy.h"
|
||||
#include "mozAutoDocUpdate.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
@@ -2967,10 +2968,14 @@ XULDocument::DoneWalking()
|
||||
// XXXldb This is where we should really be setting the chromehidden
|
||||
// attribute.
|
||||
|
||||
uint32_t count = mOverlaySheets.Length();
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
AddStyleSheet(mOverlaySheets[i]);
|
||||
{
|
||||
mozAutoDocUpdate updateBatch(this, UPDATE_STYLE, true);
|
||||
uint32_t count = mOverlaySheets.Length();
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
AddStyleSheet(mOverlaySheets[i]);
|
||||
}
|
||||
}
|
||||
|
||||
mOverlaySheets.Clear();
|
||||
|
||||
if (!mDocumentLoaded) {
|
||||
|
||||
@@ -599,6 +599,7 @@ nsHTMLEditor::InsertTableRow(int32_t aNumber, bool aAfter)
|
||||
// We are adding a new row after all others
|
||||
// If it weren't for colspan=0 effect,
|
||||
// we could simply use colCount for number of new cells...
|
||||
// XXX colspan=0 support has now been removed in table layout so maybe this can be cleaned up now? (bug 1243183)
|
||||
cellsInRow = colCount;
|
||||
|
||||
// ...but we must compensate for all cells with rowSpan = 0 in the last row
|
||||
|
||||
@@ -885,9 +885,11 @@ AsyncPanZoomController::GetSharedFrameMetricsCompositor()
|
||||
APZThreadUtils::AssertOnCompositorThread();
|
||||
|
||||
if (mSharingFrameMetricsAcrossProcesses) {
|
||||
const CompositorParent::LayerTreeState* state = CompositorParent::GetIndirectShadowTree(mLayersId);
|
||||
// |state| may be null here if the CrossProcessCompositorParent has already been destroyed.
|
||||
return state ? state->mCrossProcessParent : nullptr;
|
||||
if (const CompositorParent::LayerTreeState* state = CompositorParent::GetIndirectShadowTree(mLayersId)) {
|
||||
return state->CrossProcessPCompositor();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
return mCompositorParent.get();
|
||||
}
|
||||
|
||||
@@ -1977,6 +1977,12 @@ private:
|
||||
bool mNotifyAfterRemotePaint;
|
||||
};
|
||||
|
||||
PCompositorParent*
|
||||
CompositorParent::LayerTreeState::CrossProcessPCompositor() const
|
||||
{
|
||||
return mCrossProcessParent;
|
||||
}
|
||||
|
||||
void
|
||||
CompositorParent::DidComposite(TimeStamp& aCompositeStart,
|
||||
TimeStamp& aCompositeEnd)
|
||||
|
||||
@@ -56,6 +56,7 @@ class CompositorParent;
|
||||
class LayerManagerComposite;
|
||||
class LayerTransactionParent;
|
||||
class PAPZParent;
|
||||
class CrossProcessCompositorParent;
|
||||
|
||||
struct ScopedLayerTreeRegistration
|
||||
{
|
||||
@@ -389,7 +390,7 @@ public:
|
||||
// Pointer to the CrossProcessCompositorParent. Used by APZCs to share
|
||||
// their FrameMetrics with the corresponding child process that holds
|
||||
// the PCompositorChild
|
||||
PCompositorParent* mCrossProcessParent;
|
||||
CrossProcessCompositorParent* mCrossProcessParent;
|
||||
TargetConfig mTargetConfig;
|
||||
APZTestData mApzTestData;
|
||||
LayerTransactionParent* mLayerTree;
|
||||
@@ -397,6 +398,8 @@ public:
|
||||
bool mUpdatedPluginDataAvailable;
|
||||
RefPtr<CompositorUpdateObserver> mLayerTreeReadyObserver;
|
||||
RefPtr<CompositorUpdateObserver> mLayerTreeClearedObserver;
|
||||
|
||||
PCompositorParent* CrossProcessPCompositor() const;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -99,12 +99,14 @@ gfxPlatformMac::gfxPlatformMac()
|
||||
MacIOSurfaceLib::LoadLibrary();
|
||||
}
|
||||
|
||||
#if defined(MAC_OS_X_VERSION_10_5) && (MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_5)
|
||||
gfxPlatformMac::~gfxPlatformMac()
|
||||
{
|
||||
#if defined(MAC_OS_X_VERSION_10_6) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6)
|
||||
gfxCoreTextShaper::Shutdown();
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(MAC_OS_X_VERSION_10_5) && (MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_5)
|
||||
ByteCount
|
||||
gfxPlatformMac::GetCachedDirSizeForFont(nsString name)
|
||||
{
|
||||
|
||||
@@ -175,7 +175,7 @@ gfxScriptItemizer::Next(uint32_t& aRunStart, uint32_t& aRunLimit,
|
||||
* We only do this if the script is COMMON; for chars with
|
||||
* specific script assignments, we just use them as-is.
|
||||
*/
|
||||
GetGeneralCategory(ch);
|
||||
gc = GetGeneralCategory(ch);
|
||||
if (gc == HB_UNICODE_GENERAL_CATEGORY_OPEN_PUNCTUATION) {
|
||||
uint32_t endPairChar = mozilla::unicode::GetMirroredChar(ch);
|
||||
if (endPairChar != ch) {
|
||||
|
||||
@@ -442,6 +442,10 @@ public:
|
||||
void PostRebuildAllStyleDataEvent(nsChangeHint aExtraHint,
|
||||
nsRestyleHint aRestyleHint);
|
||||
|
||||
#ifdef DEBUG
|
||||
bool InRebuildAllStyleData() const { return mInRebuildAllStyleData; }
|
||||
#endif
|
||||
|
||||
#ifdef RESTYLE_LOGGING
|
||||
/**
|
||||
* Returns whether a restyle event currently being processed by this
|
||||
|
||||
@@ -413,8 +413,19 @@ RestyleTracker::GetRestyleData(Element* aElement, nsAutoPtr<RestyleData>& aData)
|
||||
// element. Leave it around for now, but remove the other restyle
|
||||
// hints and the change hint for it. Also unset its root bit,
|
||||
// since it's no longer a root with the new restyle data.
|
||||
NS_ASSERTION(aData->mDescendants.IsEmpty(),
|
||||
|
||||
// During a normal restyle, we should have already processed the
|
||||
// mDescendants array the last time we processed the restyle
|
||||
// for this element. But in RebuildAllStyleData, we don't initially
|
||||
// expand out eRestyle_LaterSiblings, so we can get in here the
|
||||
// first time we need to process a restyle for this element. In that
|
||||
// case, it's fine for us to have a non-empty mDescendants, since
|
||||
// we know that RebuildAllStyleData adds eRestyle_ForceDescendants
|
||||
// and we're guaranteed we'll restyle the entire tree.
|
||||
NS_ASSERTION(mRestyleManager->InRebuildAllStyleData() ||
|
||||
aData->mDescendants.IsEmpty(),
|
||||
"expected descendants to be handled by now");
|
||||
|
||||
RestyleData* newData = new RestyleData;
|
||||
newData->mChangeHint = nsChangeHint(0);
|
||||
newData->mRestyleHint = eRestyle_LaterSiblings;
|
||||
|
||||
@@ -3998,7 +3998,7 @@ GetDashInfo(nscoord aBorderLength,
|
||||
}
|
||||
|
||||
void
|
||||
nsCSSRendering::DrawTableBorderSegment(nsRenderingContext& aContext,
|
||||
nsCSSRendering::DrawTableBorderSegment(DrawTarget& aDrawTarget,
|
||||
uint8_t aBorderStyle,
|
||||
nscolor aBorderColor,
|
||||
const nsStyleBackground* aBGColor,
|
||||
@@ -4021,14 +4021,6 @@ nsCSSRendering::DrawTableBorderSegment(nsRenderingContext& aContext,
|
||||
aEndBevelOffset = 0;
|
||||
}
|
||||
|
||||
gfxContext *ctx = aContext.ThebesContext();
|
||||
AntialiasMode oldMode = ctx->CurrentAntialiasMode();
|
||||
ctx->SetAntialiasMode(AntialiasMode::NONE);
|
||||
|
||||
ctx->SetColor(Color::FromABGR(aBorderColor));
|
||||
|
||||
DrawTarget& drawTarget = *aContext.GetDrawTarget();
|
||||
|
||||
switch (aBorderStyle) {
|
||||
case NS_STYLE_BORDER_STYLE_NONE:
|
||||
case NS_STYLE_BORDER_STYLE_HIDDEN:
|
||||
@@ -4051,36 +4043,36 @@ nsCSSRendering::DrawTableBorderSegment(nsRenderingContext& aContext,
|
||||
GetDashInfo(aBorder.width, dashLength, twipsPerPixel, numDashSpaces,
|
||||
startDashLength, endDashLength);
|
||||
nsRect rect(aBorder.x, aBorder.y, startDashLength, aBorder.height);
|
||||
DrawSolidBorderSegment(drawTarget, rect, aBorderColor,
|
||||
DrawSolidBorderSegment(aDrawTarget, rect, aBorderColor,
|
||||
aAppUnitsPerDevPixel, twipsPerPixel);
|
||||
|
||||
rect.x += startDashLength + dashLength;
|
||||
rect.width = aBorder.width
|
||||
- (startDashLength + endDashLength + dashLength);
|
||||
DrawDashedSegment(drawTarget, rect, dashLength, aBorderColor,
|
||||
DrawDashedSegment(aDrawTarget, rect, dashLength, aBorderColor,
|
||||
aAppUnitsPerDevPixel, twipsPerPixel, horizontal);
|
||||
|
||||
rect.x += rect.width;
|
||||
rect.width = endDashLength;
|
||||
DrawSolidBorderSegment(drawTarget, rect, aBorderColor,
|
||||
DrawSolidBorderSegment(aDrawTarget, rect, aBorderColor,
|
||||
aAppUnitsPerDevPixel, twipsPerPixel);
|
||||
}
|
||||
else {
|
||||
GetDashInfo(aBorder.height, dashLength, twipsPerPixel, numDashSpaces,
|
||||
startDashLength, endDashLength);
|
||||
nsRect rect(aBorder.x, aBorder.y, aBorder.width, startDashLength);
|
||||
DrawSolidBorderSegment(drawTarget, rect, aBorderColor,
|
||||
DrawSolidBorderSegment(aDrawTarget, rect, aBorderColor,
|
||||
aAppUnitsPerDevPixel, twipsPerPixel);
|
||||
|
||||
rect.y += rect.height + dashLength;
|
||||
rect.height = aBorder.height
|
||||
- (startDashLength + endDashLength + dashLength);
|
||||
DrawDashedSegment(drawTarget, rect, dashLength, aBorderColor,
|
||||
DrawDashedSegment(aDrawTarget, rect, dashLength, aBorderColor,
|
||||
aAppUnitsPerDevPixel, twipsPerPixel, horizontal);
|
||||
|
||||
rect.y += rect.height;
|
||||
rect.height = endDashLength;
|
||||
DrawSolidBorderSegment(drawTarget, rect, aBorderColor,
|
||||
DrawSolidBorderSegment(aDrawTarget, rect, aBorderColor,
|
||||
aAppUnitsPerDevPixel, twipsPerPixel);
|
||||
}
|
||||
}
|
||||
@@ -4092,7 +4084,7 @@ nsCSSRendering::DrawTableBorderSegment(nsRenderingContext& aContext,
|
||||
if ((horizontal && (twipsPerPixel >= aBorder.height)) ||
|
||||
(!horizontal && (twipsPerPixel >= aBorder.width))) {
|
||||
// a one pixel border
|
||||
DrawSolidBorderSegment(drawTarget, aBorder, aBorderColor,
|
||||
DrawSolidBorderSegment(aDrawTarget, aBorder, aBorderColor,
|
||||
aAppUnitsPerDevPixel, twipsPerPixel,
|
||||
aStartBevelSide, aStartBevelOffset,
|
||||
aEndBevelSide, aEndBevelOffset);
|
||||
@@ -4108,8 +4100,6 @@ nsCSSRendering::DrawTableBorderSegment(nsRenderingContext& aContext,
|
||||
nscolor bevelColor = MakeBevelColor(ridgeGrooveSide, ridgeGroove,
|
||||
aBGColor->mBackgroundColor,
|
||||
aBorderColor);
|
||||
// XXXbz is this SetColor call still needed?
|
||||
ctx->SetColor(Color::FromABGR(bevelColor));
|
||||
nsRect rect(aBorder);
|
||||
nscoord half;
|
||||
if (horizontal) { // top, bottom
|
||||
@@ -4122,7 +4112,7 @@ nsCSSRendering::DrawTableBorderSegment(nsRenderingContext& aContext,
|
||||
if (NS_SIDE_TOP == aEndBevelSide) {
|
||||
rect.width -= endBevel;
|
||||
}
|
||||
DrawSolidBorderSegment(drawTarget, rect, bevelColor,
|
||||
DrawSolidBorderSegment(aDrawTarget, rect, bevelColor,
|
||||
aAppUnitsPerDevPixel, twipsPerPixel,
|
||||
aStartBevelSide, startBevel, aEndBevelSide,
|
||||
endBevel);
|
||||
@@ -4137,7 +4127,7 @@ nsCSSRendering::DrawTableBorderSegment(nsRenderingContext& aContext,
|
||||
if (NS_SIDE_LEFT == aEndBevelSide) {
|
||||
rect.height -= endBevel;
|
||||
}
|
||||
DrawSolidBorderSegment(drawTarget, rect, bevelColor,
|
||||
DrawSolidBorderSegment(aDrawTarget, rect, bevelColor,
|
||||
aAppUnitsPerDevPixel, twipsPerPixel,
|
||||
aStartBevelSide, startBevel, aEndBevelSide,
|
||||
endBevel);
|
||||
@@ -4149,8 +4139,6 @@ nsCSSRendering::DrawTableBorderSegment(nsRenderingContext& aContext,
|
||||
// background color, but I don't care.
|
||||
bevelColor = MakeBevelColor(ridgeGrooveSide, ridgeGroove,
|
||||
aBGColor->mBackgroundColor, aBorderColor);
|
||||
// XXXbz is this SetColor call still needed?
|
||||
ctx->SetColor(Color::FromABGR(bevelColor));
|
||||
if (horizontal) {
|
||||
rect.y = rect.y + half;
|
||||
rect.height = aBorder.height - half;
|
||||
@@ -4161,7 +4149,7 @@ nsCSSRendering::DrawTableBorderSegment(nsRenderingContext& aContext,
|
||||
if (NS_SIDE_BOTTOM == aEndBevelSide) {
|
||||
rect.width -= endBevel;
|
||||
}
|
||||
DrawSolidBorderSegment(drawTarget, rect, bevelColor,
|
||||
DrawSolidBorderSegment(aDrawTarget, rect, bevelColor,
|
||||
aAppUnitsPerDevPixel, twipsPerPixel,
|
||||
aStartBevelSide, startBevel, aEndBevelSide,
|
||||
endBevel);
|
||||
@@ -4176,7 +4164,7 @@ nsCSSRendering::DrawTableBorderSegment(nsRenderingContext& aContext,
|
||||
if (NS_SIDE_RIGHT == aEndBevelSide) {
|
||||
rect.height -= endBevel;
|
||||
}
|
||||
DrawSolidBorderSegment(drawTarget, rect, bevelColor,
|
||||
DrawSolidBorderSegment(aDrawTarget, rect, bevelColor,
|
||||
aAppUnitsPerDevPixel, twipsPerPixel,
|
||||
aStartBevelSide, startBevel, aEndBevelSide,
|
||||
endBevel);
|
||||
@@ -4205,7 +4193,7 @@ nsCSSRendering::DrawTableBorderSegment(nsRenderingContext& aContext,
|
||||
if (NS_SIDE_TOP == aEndBevelSide) {
|
||||
topRect.width -= aEndBevelOffset - endBevel;
|
||||
}
|
||||
DrawSolidBorderSegment(drawTarget, topRect, aBorderColor,
|
||||
DrawSolidBorderSegment(aDrawTarget, topRect, aBorderColor,
|
||||
aAppUnitsPerDevPixel, twipsPerPixel,
|
||||
aStartBevelSide, startBevel, aEndBevelSide,
|
||||
endBevel);
|
||||
@@ -4220,7 +4208,7 @@ nsCSSRendering::DrawTableBorderSegment(nsRenderingContext& aContext,
|
||||
if (NS_SIDE_BOTTOM == aEndBevelSide) {
|
||||
bottomRect.width -= aEndBevelOffset - endBevel;
|
||||
}
|
||||
DrawSolidBorderSegment(drawTarget, bottomRect, aBorderColor,
|
||||
DrawSolidBorderSegment(aDrawTarget, bottomRect, aBorderColor,
|
||||
aAppUnitsPerDevPixel, twipsPerPixel,
|
||||
aStartBevelSide, startBevel, aEndBevelSide,
|
||||
endBevel);
|
||||
@@ -4236,7 +4224,7 @@ nsCSSRendering::DrawTableBorderSegment(nsRenderingContext& aContext,
|
||||
if (NS_SIDE_LEFT == aEndBevelSide) {
|
||||
leftRect.height -= aEndBevelOffset - endBevel;
|
||||
}
|
||||
DrawSolidBorderSegment(drawTarget, leftRect, aBorderColor,
|
||||
DrawSolidBorderSegment(aDrawTarget, leftRect, aBorderColor,
|
||||
aAppUnitsPerDevPixel, twipsPerPixel,
|
||||
aStartBevelSide, startBevel, aEndBevelSide,
|
||||
endBevel);
|
||||
@@ -4250,7 +4238,7 @@ nsCSSRendering::DrawTableBorderSegment(nsRenderingContext& aContext,
|
||||
if (NS_SIDE_RIGHT == aEndBevelSide) {
|
||||
rightRect.height -= aEndBevelOffset - endBevel;
|
||||
}
|
||||
DrawSolidBorderSegment(drawTarget, rightRect, aBorderColor,
|
||||
DrawSolidBorderSegment(aDrawTarget, rightRect, aBorderColor,
|
||||
aAppUnitsPerDevPixel, twipsPerPixel,
|
||||
aStartBevelSide, startBevel, aEndBevelSide,
|
||||
endBevel);
|
||||
@@ -4260,7 +4248,7 @@ nsCSSRendering::DrawTableBorderSegment(nsRenderingContext& aContext,
|
||||
// else fall through to solid
|
||||
MOZ_FALLTHROUGH;
|
||||
case NS_STYLE_BORDER_STYLE_SOLID:
|
||||
DrawSolidBorderSegment(drawTarget, aBorder, aBorderColor,
|
||||
DrawSolidBorderSegment(aDrawTarget, aBorder, aBorderColor,
|
||||
aAppUnitsPerDevPixel, twipsPerPixel, aStartBevelSide,
|
||||
aStartBevelOffset, aEndBevelSide, aEndBevelOffset);
|
||||
break;
|
||||
@@ -4272,8 +4260,6 @@ nsCSSRendering::DrawTableBorderSegment(nsRenderingContext& aContext,
|
||||
NS_ASSERTION(false, "Unexpected 'auto' table border");
|
||||
break;
|
||||
}
|
||||
|
||||
ctx->SetAntialiasMode(oldMode);
|
||||
}
|
||||
|
||||
// End table border-collapsing section
|
||||
|
||||
@@ -656,8 +656,8 @@ struct nsCSSRendering {
|
||||
|
||||
// Draw a border segment in the table collapsing border model without
|
||||
// beveling corners
|
||||
static void DrawTableBorderSegment(nsRenderingContext& aContext,
|
||||
uint8_t aBorderStyle,
|
||||
static void DrawTableBorderSegment(DrawTarget& aDrawTarget,
|
||||
uint8_t aBorderStyle,
|
||||
nscolor aBorderColor,
|
||||
const nsStyleBackground* aBGColor,
|
||||
const nsRect& aBorderRect,
|
||||
|
||||
@@ -2888,6 +2888,17 @@ nsDocumentViewer::CallChildren(CallChildFunc aFunc, void* aClosure)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ChangeChildPaintingEnabled(nsIContentViewer* aChild, void* aClosure)
|
||||
{
|
||||
bool* enablePainting = (bool*) aClosure;
|
||||
if (*enablePainting) {
|
||||
aChild->ResumePainting();
|
||||
} else {
|
||||
aChild->PausePainting();
|
||||
}
|
||||
}
|
||||
|
||||
struct ZoomInfo
|
||||
{
|
||||
float mZoom;
|
||||
@@ -3317,6 +3328,34 @@ NS_IMETHODIMP nsDocumentViewer::AppendSubtree(nsTArray<nsCOMPtr<nsIContentViewer
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocumentViewer::PausePainting()
|
||||
{
|
||||
bool enablePaint = false;
|
||||
CallChildren(ChangeChildPaintingEnabled, &enablePaint);
|
||||
|
||||
nsIPresShell* presShell = GetPresShell();
|
||||
if (presShell) {
|
||||
presShell->PausePainting();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocumentViewer::ResumePainting()
|
||||
{
|
||||
bool enablePaint = true;
|
||||
CallChildren(ChangeChildPaintingEnabled, &enablePaint);
|
||||
|
||||
nsIPresShell* presShell = GetPresShell();
|
||||
if (presShell) {
|
||||
presShell->ResumePainting();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocumentViewer::GetContentSize(int32_t* aWidth, int32_t* aHeight)
|
||||
{
|
||||
|
||||
@@ -137,10 +137,10 @@ typedef struct CapturingContentInfo {
|
||||
mozilla::StaticRefPtr<nsIContent> mContent;
|
||||
} CapturingContentInfo;
|
||||
|
||||
// 6654f67f-c5aa-4934-b611-6d8d01e6193f
|
||||
// f17842ee-f1f0-4193-814f-70d706b67060
|
||||
#define NS_IPRESSHELL_IID \
|
||||
{ 0x6654f67f, 0xc5aa, 0x4934, \
|
||||
{ 0xb6, 0x11, 0x6d, 0x8d, 0x01, 0xe6, 0x19, 0x3f } }
|
||||
{ 0xf17842ee, 0xf1f0, 0x4193, \
|
||||
{ 0x81, 0x4f, 0x70, 0xd7, 0x06, 0xb6, 0x70, 0x60 } }
|
||||
|
||||
// debug VerifyReflow flags
|
||||
#define VERIFY_REFLOW_ON 0x01
|
||||
@@ -908,6 +908,20 @@ public:
|
||||
*/
|
||||
bool IsPaintingSuppressed() const { return mPaintingSuppressed; }
|
||||
|
||||
/**
|
||||
* Pause painting by freezing the refresh driver of this and all parent
|
||||
* presentations. This may not have the desired effect if this pres shell
|
||||
* has its own refresh driver.
|
||||
*/
|
||||
virtual void PausePainting() = 0;
|
||||
|
||||
/**
|
||||
* Resume painting by thawing the refresh driver of this and all parent
|
||||
* presentations. This may not have the desired effect if this pres shell
|
||||
* has its own refresh driver.
|
||||
*/
|
||||
virtual void ResumePainting() = 0;
|
||||
|
||||
/**
|
||||
* Unsuppress painting.
|
||||
*/
|
||||
@@ -1773,6 +1787,7 @@ protected:
|
||||
bool mFontSizeInflationForceEnabled;
|
||||
bool mFontSizeInflationDisabledInMasterProcess;
|
||||
bool mFontSizeInflationEnabled;
|
||||
bool mPaintingIsFrozen;
|
||||
|
||||
// Dirty bit indicating that mFontSizeInflationEnabled needs to be recomputed.
|
||||
bool mFontSizeInflationEnabledIsDirty;
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "mozilla/ToString.h"
|
||||
#include "nsHTMLReflowMetrics.h"
|
||||
#include "ImageContainer.h"
|
||||
#include "gfx2DGlue.h"
|
||||
|
||||
#include <limits>
|
||||
#include <algorithm>
|
||||
|
||||
@@ -747,6 +747,7 @@ PresShell::PresShell()
|
||||
mSelectionFlags = nsISelectionDisplay::DISPLAY_TEXT | nsISelectionDisplay::DISPLAY_IMAGES;
|
||||
mIsThemeSupportDisabled = false;
|
||||
mIsActive = true;
|
||||
mIsHidden = false;
|
||||
// FIXME/bug 735029: find a better solution to this problem
|
||||
#if defined(MOZ_WIDGET_ANDROID) && !defined(MOZ_ANDROID_APZ)
|
||||
// The java pan/zoom code uses this to mean approximately "request a
|
||||
@@ -778,6 +779,7 @@ PresShell::PresShell()
|
||||
addedPointerEventEnabled = true;
|
||||
}
|
||||
|
||||
mPaintingIsFrozen = false;
|
||||
mHasCSSBackgroundColor = true;
|
||||
mIsLastChromeOnlyEscapeKeyConsumed = false;
|
||||
mHasReceivedPaintMessage = false;
|
||||
@@ -801,6 +803,13 @@ PresShell::~PresShell()
|
||||
mLastCallbackEventRequest == nullptr,
|
||||
"post-reflow queues not empty. This means we're leaking");
|
||||
|
||||
// Verify that if painting was frozen, but we're being removed from the tree,
|
||||
// that we now re-enable painting on our refresh driver, since it may need to
|
||||
// be re-used by another presentation.
|
||||
if (mPaintingIsFrozen) {
|
||||
mPresContext->RefreshDriver()->Thaw();
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
MOZ_ASSERT(mPresArenaAllocCount == 0,
|
||||
"Some pres arena objects were not freed");
|
||||
@@ -10451,6 +10460,10 @@ void PresShell::QueryIsActive()
|
||||
if (docshell) {
|
||||
bool isActive;
|
||||
nsresult rv = docshell->GetIsActive(&isActive);
|
||||
// Even though in theory the docshell here could be "Inactive and
|
||||
// Foreground", thus implying aIsHidden=false for SetIsActive(),
|
||||
// this is a newly created PresShell so we'd like to invalidate anyway
|
||||
// upon being made active to ensure that the contents get painted.
|
||||
if (NS_SUCCEEDED(rv))
|
||||
SetIsActive(isActive);
|
||||
}
|
||||
@@ -10488,6 +10501,11 @@ PresShell::SetIsActive(bool aIsActive, bool aIsHidden)
|
||||
NS_PRECONDITION(mDocument, "should only be called with a document");
|
||||
|
||||
mIsActive = aIsActive;
|
||||
|
||||
// Keep track of whether we've called TabChild::MakeHidden() or not.
|
||||
// This can still be true even if aIsHidden is false.
|
||||
mIsHidden |= aIsHidden;
|
||||
|
||||
nsPresContext* presContext = GetPresContext();
|
||||
if (presContext &&
|
||||
presContext->RefreshDriver()->PresContext() == presContext) {
|
||||
@@ -10527,10 +10545,14 @@ PresShell::SetIsActive(bool aIsActive, bool aIsHidden)
|
||||
// and (ii) has easy access to the TabChild. So we use this
|
||||
// notification to signal the TabChild to drop its layer tree and
|
||||
// stop trying to repaint.
|
||||
if (aIsHidden) {
|
||||
if (mIsHidden) {
|
||||
if (TabChild* tab = TabChild::GetFrom(this)) {
|
||||
if (aIsActive) {
|
||||
tab->MakeVisible();
|
||||
// The only time we should set this to false is when
|
||||
// TabChild::MakeVisible() is called.
|
||||
mIsHidden = false;
|
||||
|
||||
if (!mIsZombie) {
|
||||
if (nsIFrame* root = mFrameConstructor->GetRootFrame()) {
|
||||
FrameLayerBuilder::InvalidateAllLayersForFrame(
|
||||
@@ -10750,6 +10772,26 @@ nsIPresShell::FontSizeInflationEnabled()
|
||||
return mFontSizeInflationEnabled;
|
||||
}
|
||||
|
||||
void
|
||||
PresShell::PausePainting()
|
||||
{
|
||||
if (GetPresContext()->RefreshDriver()->PresContext() != GetPresContext())
|
||||
return;
|
||||
|
||||
mPaintingIsFrozen = true;
|
||||
GetPresContext()->RefreshDriver()->Freeze();
|
||||
}
|
||||
|
||||
void
|
||||
PresShell::ResumePainting()
|
||||
{
|
||||
if (GetPresContext()->RefreshDriver()->PresContext() != GetPresContext())
|
||||
return;
|
||||
|
||||
mPaintingIsFrozen = false;
|
||||
GetPresContext()->RefreshDriver()->Thaw();
|
||||
}
|
||||
|
||||
void
|
||||
nsIPresShell::SyncWindowProperties(nsView* aView)
|
||||
{
|
||||
|
||||
@@ -494,6 +494,8 @@ protected:
|
||||
friend class nsPresShellEventCB;
|
||||
|
||||
bool mCaretEnabled;
|
||||
|
||||
bool mIsHidden;
|
||||
#ifdef DEBUG
|
||||
nsStyleSet* CloneStyleSet(nsStyleSet* aSet);
|
||||
bool VerifyIncrementalReflow();
|
||||
@@ -720,6 +722,10 @@ protected:
|
||||
#ifdef ANDROID
|
||||
virtual nsIDocument* GetTouchEventTargetDocument();
|
||||
#endif
|
||||
|
||||
virtual void PausePainting() override;
|
||||
virtual void ResumePainting() override;
|
||||
|
||||
void UpdateImageVisibility();
|
||||
void UpdateActivePointerState(mozilla::WidgetGUIEvent* aEvent);
|
||||
|
||||
|
||||
@@ -1175,7 +1175,7 @@ nsRefreshDriver::EnsureTimerStarted(EnsureTimerStartedFlags aFlags)
|
||||
return;
|
||||
|
||||
// will it already fire, and no other changes needed?
|
||||
if (mActiveTimer && !(aFlags & eAdjustingTimer))
|
||||
if (mActiveTimer && !(aFlags & eForceAdjustTimer))
|
||||
return;
|
||||
|
||||
if (IsFrozen() || !mPresContext) {
|
||||
@@ -1207,6 +1207,15 @@ nsRefreshDriver::EnsureTimerStarted(EnsureTimerStartedFlags aFlags)
|
||||
mActiveTimer->AddRefreshDriver(this);
|
||||
}
|
||||
|
||||
// When switching from an inactive timer to an active timer, the root
|
||||
// refresh driver is skipped due to being set to the content refresh
|
||||
// driver's timestamp. In case of EnsureTimerStarted is called from
|
||||
// ScheduleViewManagerFlush, we should avoid this behavior to flush
|
||||
// a paint in the same tick on the root refresh driver.
|
||||
if (aFlags & eNeverAdjustTimer) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Since the different timers are sampled at different rates, when switching
|
||||
// timers, the most recent refresh of the new timer may be *before* the
|
||||
// most recent refresh of the old timer. However, the refresh driver time
|
||||
@@ -2068,7 +2077,7 @@ nsRefreshDriver::SetThrottled(bool aThrottled)
|
||||
if (mActiveTimer) {
|
||||
// We want to switch our timer type here, so just stop and
|
||||
// restart the timer.
|
||||
EnsureTimerStarted(eAdjustingTimer);
|
||||
EnsureTimerStarted(eForceAdjustTimer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2115,7 +2124,7 @@ nsRefreshDriver::ScheduleViewManagerFlush()
|
||||
NS_ASSERTION(mPresContext->IsRoot(),
|
||||
"Should only schedule view manager flush on root prescontexts");
|
||||
mViewManagerFlushIsPending = true;
|
||||
EnsureTimerStarted();
|
||||
EnsureTimerStarted(eNeverAdjustTimer);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -331,8 +331,9 @@ private:
|
||||
|
||||
enum EnsureTimerStartedFlags {
|
||||
eNone = 0,
|
||||
eAdjustingTimer = 1 << 0,
|
||||
eAllowTimeToGoBackwards = 1 << 1
|
||||
eForceAdjustTimer = 1 << 0,
|
||||
eAllowTimeToGoBackwards = 1 << 1,
|
||||
eNeverAdjustTimer = 1 << 2,
|
||||
};
|
||||
void EnsureTimerStarted(EnsureTimerStartedFlags aFlags = eNone);
|
||||
void StopTimer();
|
||||
|
||||
@@ -106,9 +106,8 @@ RenderFrameParent::RenderFrameParent(nsFrameLoader* aFrameLoader,
|
||||
mAsyncPanZoomEnabled = lm && lm->AsyncPanZoomEnabled();
|
||||
|
||||
// Perhaps the document containing this frame currently has no presentation?
|
||||
if (lm && lm->GetBackendType() == LayersBackend::LAYERS_CLIENT) {
|
||||
*aTextureFactoryIdentifier =
|
||||
static_cast<ClientLayerManager*>(lm.get())->GetTextureFactoryIdentifier();
|
||||
if (lm && lm->AsClientLayerManager()) {
|
||||
*aTextureFactoryIdentifier = lm->AsClientLayerManager()->GetTextureFactoryIdentifier();
|
||||
} else {
|
||||
*aTextureFactoryIdentifier = TextureFactoryIdentifier();
|
||||
}
|
||||
@@ -119,10 +118,8 @@ RenderFrameParent::RenderFrameParent(nsFrameLoader* aFrameLoader,
|
||||
// and we'll keep an indirect reference to that tree.
|
||||
browser->Manager()->AsContentParent()->AllocateLayerTreeId(browser, aId);
|
||||
mLayersId = *aId;
|
||||
if (lm && lm->GetBackendType() == LayersBackend::LAYERS_CLIENT) {
|
||||
ClientLayerManager *clientManager =
|
||||
static_cast<ClientLayerManager*>(lm.get());
|
||||
clientManager->GetRemoteRenderer()->SendNotifyChildCreated(mLayersId);
|
||||
if (lm && lm->AsClientLayerManager()) {
|
||||
lm->AsClientLayerManager()->GetRemoteRenderer()->SendNotifyChildCreated(mLayersId);
|
||||
}
|
||||
} else if (XRE_IsContentProcess()) {
|
||||
ContentChild::GetSingleton()->SendAllocateLayerTreeId(browser->Manager()->ChildID(), browser->GetTabId(), aId);
|
||||
@@ -208,10 +205,8 @@ RenderFrameParent::OwnerContentChanged(nsIContent* aContent)
|
||||
|
||||
RefPtr<LayerManager> lm = mFrameLoader ? GetFrom(mFrameLoader) : nullptr;
|
||||
// Perhaps the document containing this frame currently has no presentation?
|
||||
if (lm && lm->GetBackendType() == LayersBackend::LAYERS_CLIENT) {
|
||||
ClientLayerManager *clientManager =
|
||||
static_cast<ClientLayerManager*>(lm.get());
|
||||
clientManager->GetRemoteRenderer()->SendAdoptChild(mLayersId);
|
||||
if (lm && lm->AsClientLayerManager()) {
|
||||
lm->AsClientLayerManager()->GetRemoteRenderer()->SendAdoptChild(mLayersId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -294,9 +289,8 @@ RenderFrameParent::GetTextureFactoryIdentifier(TextureFactoryIdentifier* aTextur
|
||||
{
|
||||
RefPtr<LayerManager> lm = mFrameLoader ? GetFrom(mFrameLoader) : nullptr;
|
||||
// Perhaps the document containing this frame currently has no presentation?
|
||||
if (lm && lm->GetBackendType() == LayersBackend::LAYERS_CLIENT) {
|
||||
*aTextureFactoryIdentifier =
|
||||
static_cast<ClientLayerManager*>(lm.get())->GetTextureFactoryIdentifier();
|
||||
if (lm && lm->AsClientLayerManager()) {
|
||||
*aTextureFactoryIdentifier = lm->AsClientLayerManager()->GetTextureFactoryIdentifier();
|
||||
} else {
|
||||
*aTextureFactoryIdentifier = TextureFactoryIdentifier();
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ HTTP(..) == weightmapping-45.html weightmapping-45-ref.html
|
||||
HTTP(..) == weightmapping-458.html weightmapping-458-ref.html
|
||||
HTTP(..) == weightmapping-478.html weightmapping-478-ref.html
|
||||
HTTP(..) == weightmapping-7.html weightmapping-7-ref.html
|
||||
HTTP(..) == weightmapping-12579.html weightmapping-12579-ref.html
|
||||
fuzzy-if(OSX==1010,1,30) HTTP(..) == weightmapping-12579.html weightmapping-12579-ref.html
|
||||
|
||||
skip-if(B2G||Mulet) HTTP(..) == stretchmapping-all.html stretchmapping-all-ref.html # bug 773482 # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
skip-if(B2G||Mulet) HTTP(..) == stretchmapping-reverse.html stretchmapping-reverse-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
|
||||
@@ -80,19 +80,6 @@ public:
|
||||
*/
|
||||
bool IsColSpan() const;
|
||||
|
||||
/** is the entry spanned by a zero colspan
|
||||
* zero colspans span all cells starting from the originating cell towards
|
||||
* the end of the colgroup or a cell originating in the same row
|
||||
* or a rowspanned entry
|
||||
* @return is true if the entry is spanned by a zero colspan
|
||||
*/
|
||||
bool IsZeroColSpan() const;
|
||||
|
||||
/** mark the current entry as spanned by a zero colspan
|
||||
* @param aIsZero if true mark the entry as covered by a zero colspan
|
||||
*/
|
||||
void SetZeroColSpan(bool aIsZero);
|
||||
|
||||
/** get the distance from the current entry to the corresponding origin of the colspan
|
||||
* @return containing the distance in the row to the originating cell
|
||||
*/
|
||||
@@ -250,7 +237,9 @@ public:
|
||||
|
||||
// The layout of a celldata is as follows. The top 10 bits are the colspan
|
||||
// offset (which is enough to represent our allowed values 1-1000 for colspan).
|
||||
// Then there are three bits of flags. Then 16 bits of rowspan offset (which
|
||||
// Then there are two bits of flags.
|
||||
// XXXmats Then one unused bit that we should decide how to use in bug 862624.
|
||||
// Then 16 bits of rowspan offset (which
|
||||
// lets us represent numbers up to 65535. Then another 3 bits of flags.
|
||||
|
||||
// num bits to shift right to get right aligned col span
|
||||
@@ -267,8 +256,7 @@ public:
|
||||
#define SPAN 0x00000001 // there a row or col span
|
||||
#define ROW_SPAN 0x00000002 // there is a row span
|
||||
#define ROW_SPAN_0 0x00000004 // the row span is 0
|
||||
#define COL_SPAN (1 << (COL_SPAN_SHIFT - 3)) // there is a col span
|
||||
#define COL_SPAN_0 (1 << (COL_SPAN_SHIFT - 2)) // the col span is 0
|
||||
#define COL_SPAN (1 << (COL_SPAN_SHIFT - 2)) // there is a col span
|
||||
#define OVERLAP (1 << (COL_SPAN_SHIFT - 1)) // there is a row span and
|
||||
// col span but not by
|
||||
// same cell
|
||||
@@ -348,25 +336,6 @@ inline bool CellData::IsColSpan() const
|
||||
(COL_SPAN == (COL_SPAN & mBits));
|
||||
}
|
||||
|
||||
inline bool CellData::IsZeroColSpan() const
|
||||
{
|
||||
return (SPAN == (SPAN & mBits)) &&
|
||||
(COL_SPAN == (COL_SPAN & mBits)) &&
|
||||
(COL_SPAN_0 == (COL_SPAN_0 & mBits));
|
||||
}
|
||||
|
||||
inline void CellData::SetZeroColSpan(bool aIsZeroSpan)
|
||||
{
|
||||
if (SPAN == (SPAN & mBits)) {
|
||||
if (aIsZeroSpan) {
|
||||
mBits |= COL_SPAN_0;
|
||||
}
|
||||
else {
|
||||
mBits &= ~COL_SPAN_0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline uint32_t CellData::GetColSpanOffset() const
|
||||
{
|
||||
if ((SPAN == (SPAN & mBits)) && ((COL_SPAN == (COL_SPAN & mBits)))) {
|
||||
|
||||
+9
-199
@@ -353,8 +353,7 @@ nsTableCellMap::GetEffectiveColSpan(int32_t aRowIndex,
|
||||
nsCellMap* map = mFirstMap;
|
||||
while (map) {
|
||||
if (map->GetRowCount() > rowIndex) {
|
||||
bool zeroColSpan;
|
||||
return map->GetEffectiveColSpan(*this, rowIndex, aColIndex, zeroColSpan);
|
||||
return map->GetEffectiveColSpan(*this, rowIndex, aColIndex);
|
||||
}
|
||||
rowIndex -= map->GetRowCount();
|
||||
map = map->GetNextSibling();
|
||||
@@ -899,18 +898,6 @@ bool nsTableCellMap::RowHasSpanningCells(int32_t aRowIndex,
|
||||
return false;
|
||||
}
|
||||
|
||||
void nsTableCellMap::ExpandZeroColSpans()
|
||||
{
|
||||
mTableFrame.SetNeedColSpanExpansion(false); // mark the work done
|
||||
mTableFrame.SetHasZeroColSpans(false); // reset the bit, if there is a
|
||||
// zerospan it will be set again.
|
||||
nsCellMap* cellMap = mFirstMap;
|
||||
while (cellMap) {
|
||||
cellMap->ExpandZeroColSpans(*this);
|
||||
cellMap = cellMap->GetNextSibling();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsTableCellMap::ResetBStartStart(LogicalSide aSide,
|
||||
nsCellMap& aCellMap,
|
||||
@@ -1454,15 +1441,6 @@ nsCellMap::AppendCell(nsTableCellMap& aMap,
|
||||
origData = data;
|
||||
break;
|
||||
}
|
||||
if (data->IsZeroColSpan() ) {
|
||||
// appending a cell collapses zerospans.
|
||||
CollapseZeroColSpan(aMap, data, aRowIndex, startColIndex);
|
||||
// ask again for the data as it should be modified
|
||||
origData = GetDataAt(aRowIndex, startColIndex);
|
||||
NS_ASSERTION(origData->IsDead(),
|
||||
"The cellposition should have been cleared");
|
||||
break;
|
||||
}
|
||||
}
|
||||
// We found the place to append the cell, when the next cell is appended
|
||||
// the next search does not need to duplicate the search but can start
|
||||
@@ -1470,13 +1448,7 @@ nsCellMap::AppendCell(nsTableCellMap& aMap,
|
||||
if (aColToBeginSearch)
|
||||
*aColToBeginSearch = startColIndex + 1;
|
||||
|
||||
bool zeroColSpan = false;
|
||||
int32_t colSpan = (aCellFrame) ?
|
||||
GetColSpanForNewCell(*aCellFrame, zeroColSpan) : 1;
|
||||
if (zeroColSpan) {
|
||||
aMap.mTableFrame.SetHasZeroColSpans(true);
|
||||
aMap.mTableFrame.SetNeedColSpanExpansion(true);
|
||||
}
|
||||
int32_t colSpan = aCellFrame ? aCellFrame->GetColSpan() : 1;
|
||||
|
||||
// if the new cell could potentially span into other rows and collide with
|
||||
// originating cells there, we will play it safe and just rebuild the map
|
||||
@@ -1563,10 +1535,6 @@ nsCellMap::AppendCell(nsTableCellMap& aMap,
|
||||
cellData->SetOverlap(true);
|
||||
}
|
||||
cellData->SetColSpanOffset(colX - startColIndex);
|
||||
if (zeroColSpan) {
|
||||
cellData->SetZeroColSpan(true);
|
||||
}
|
||||
|
||||
nsColInfo* colInfo = aMap.GetColInfoAt(colX);
|
||||
colInfo->mNumCellsSpan++;
|
||||
}
|
||||
@@ -1583,9 +1551,6 @@ nsCellMap::AppendCell(nsTableCellMap& aMap,
|
||||
}
|
||||
if (colX > startColIndex) {
|
||||
cellData->SetColSpanOffset(colX - startColIndex);
|
||||
if (zeroColSpan) {
|
||||
cellData->SetZeroColSpan(true);
|
||||
}
|
||||
}
|
||||
SetDataAt(aMap, *cellData, rowX, colX);
|
||||
}
|
||||
@@ -1599,50 +1564,6 @@ nsCellMap::AppendCell(nsTableCellMap& aMap,
|
||||
return origData;
|
||||
}
|
||||
|
||||
void nsCellMap::CollapseZeroColSpan(nsTableCellMap& aMap,
|
||||
CellData* aOrigData,
|
||||
int32_t aRowIndex,
|
||||
int32_t aColIndex)
|
||||
{
|
||||
// if after a colspan = 0 cell another cell is appended in a row the html 4
|
||||
// spec is already violated. In principle one should then append the cell
|
||||
// after the last column but then the zero spanning cell would also have
|
||||
// to grow. The only plausible way to break this cycle is ignore the zero
|
||||
// colspan and reset the cell to colspan = 1.
|
||||
|
||||
NS_ASSERTION(aOrigData && aOrigData->IsZeroColSpan(),
|
||||
"zero colspan should have been passed");
|
||||
// find the originating cellframe
|
||||
nsTableCellFrame* cell = GetCellFrame(aRowIndex, aColIndex, *aOrigData, true);
|
||||
NS_ASSERTION(cell, "originating cell not found");
|
||||
|
||||
// find the clearing region
|
||||
int32_t startRowIndex = aRowIndex - aOrigData->GetRowSpanOffset();
|
||||
bool zeroSpan;
|
||||
int32_t rowSpan = GetRowSpanForNewCell(cell, startRowIndex, zeroSpan);
|
||||
int32_t endRowIndex = startRowIndex + rowSpan;
|
||||
|
||||
int32_t origColIndex = aColIndex - aOrigData->GetColSpanOffset();
|
||||
int32_t endColIndex = origColIndex +
|
||||
GetEffectiveColSpan(aMap, startRowIndex,
|
||||
origColIndex, zeroSpan);
|
||||
for (int32_t colX = origColIndex +1; colX < endColIndex; colX++) {
|
||||
// Start the collapse just after the originating cell, since
|
||||
// we're basically making the originating cell act as if it
|
||||
// has colspan="1".
|
||||
nsColInfo* colInfo = aMap.GetColInfoAt(colX);
|
||||
colInfo->mNumCellsSpan -= rowSpan;
|
||||
|
||||
for (int32_t rowX = startRowIndex; rowX < endRowIndex; rowX++)
|
||||
{
|
||||
CellData* data = mRows[rowX][colX];
|
||||
NS_ASSERTION(data->IsZeroColSpan(),
|
||||
"Overwriting previous data - memory leak");
|
||||
data->Init(nullptr); // mark the cell as a dead cell.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool nsCellMap::CellsSpanOut(nsTArray<nsTableRowFrame*>& aRows) const
|
||||
{
|
||||
int32_t numNewRows = aRows.Length();
|
||||
@@ -1749,11 +1670,6 @@ void nsCellMap::InsertCells(nsTableCellMap& aMap,
|
||||
// // Not a span. Stop.
|
||||
break;
|
||||
}
|
||||
if (data->IsZeroColSpan()) {
|
||||
// Zero colspans collapse. Stop in this case too.
|
||||
CollapseZeroColSpan(aMap, data, aRowIndex, startColIndex);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// record whether inserted cells are going to cause complications due
|
||||
@@ -1863,12 +1779,7 @@ void nsCellMap::ExpandWithCells(nsTableCellMap& aMap,
|
||||
if (!origData) return;
|
||||
|
||||
// set the starting and ending col index for the new cell
|
||||
bool zeroColSpan = false;
|
||||
int32_t colSpan = GetColSpanForNewCell(*cellFrame, zeroColSpan);
|
||||
if (zeroColSpan) {
|
||||
aMap.mTableFrame.SetHasZeroColSpans(true);
|
||||
aMap.mTableFrame.SetNeedColSpanExpansion(true);
|
||||
}
|
||||
int32_t colSpan = cellFrame->GetColSpan();
|
||||
totalColSpan += colSpan;
|
||||
if (cellX == 0) {
|
||||
endColIndex = aColIndex + colSpan - 1;
|
||||
@@ -1911,9 +1822,6 @@ void nsCellMap::ExpandWithCells(nsTableCellMap& aMap,
|
||||
}
|
||||
if (colX > startColIndex) {
|
||||
data->SetColSpanOffset(colX - startColIndex);
|
||||
if (zeroColSpan) {
|
||||
data->SetZeroColSpan(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
SetDataAt(aMap, *data, rowX, colX);
|
||||
@@ -2011,25 +1919,11 @@ void nsCellMap::ShrinkWithoutRows(nsTableCellMap& aMap,
|
||||
aMap.GetRowCount() - firstDamagedRow, aDamageArea);
|
||||
}
|
||||
|
||||
int32_t nsCellMap::GetColSpanForNewCell(nsTableCellFrame& aCellFrameToAdd,
|
||||
bool& aIsZeroColSpan) const
|
||||
{
|
||||
aIsZeroColSpan = false;
|
||||
int32_t colSpan = aCellFrameToAdd.GetColSpan();
|
||||
if (0 == colSpan) {
|
||||
colSpan = 1; // set the min colspan it will be expanded later
|
||||
aIsZeroColSpan = true;
|
||||
}
|
||||
return colSpan;
|
||||
}
|
||||
|
||||
int32_t nsCellMap::GetEffectiveColSpan(const nsTableCellMap& aMap,
|
||||
int32_t aRowIndex,
|
||||
int32_t aColIndex,
|
||||
bool& aZeroColSpan) const
|
||||
int32_t aColIndex) const
|
||||
{
|
||||
int32_t numColsInTable = aMap.GetColCount();
|
||||
aZeroColSpan = false;
|
||||
int32_t colSpan = 1;
|
||||
if (uint32_t(aRowIndex) >= mRows.Length()) {
|
||||
return colSpan;
|
||||
@@ -2060,9 +1954,6 @@ int32_t nsCellMap::GetEffectiveColSpan(const nsTableCellMap& aMap,
|
||||
}
|
||||
if (data->IsColSpan()) {
|
||||
colSpan++;
|
||||
if (data->IsZeroColSpan()) {
|
||||
aZeroColSpan = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
break;
|
||||
@@ -2153,17 +2044,12 @@ void nsCellMap::ShrinkWithoutCell(nsTableCellMap& aMap,
|
||||
uint32_t colX, rowX;
|
||||
|
||||
// get the rowspan and colspan from the cell map since the content may have changed
|
||||
bool zeroColSpan;
|
||||
uint32_t numCols = aMap.GetColCount();
|
||||
int32_t rowSpan = GetRowSpan(aRowIndex, aColIndex, true);
|
||||
uint32_t colSpan = GetEffectiveColSpan(aMap, aRowIndex, aColIndex, zeroColSpan);
|
||||
uint32_t colSpan = GetEffectiveColSpan(aMap, aRowIndex, aColIndex);
|
||||
uint32_t endRowIndex = aRowIndex + rowSpan - 1;
|
||||
uint32_t endColIndex = aColIndex + colSpan - 1;
|
||||
|
||||
if (aMap.mTableFrame.HasZeroColSpans()) {
|
||||
aMap.mTableFrame.SetNeedColSpanExpansion(true);
|
||||
}
|
||||
|
||||
// adjust the col counts due to the deleted cell before removing it
|
||||
for (colX = aColIndex; colX <= endColIndex; colX++) {
|
||||
nsColInfo* colInfo = aMap.GetColInfoAt(colX);
|
||||
@@ -2455,80 +2341,6 @@ void nsCellMap::RemoveCell(nsTableCellMap& aMap,
|
||||
}
|
||||
}
|
||||
|
||||
void nsCellMap::ExpandZeroColSpans(nsTableCellMap& aMap)
|
||||
{
|
||||
NS_ASSERTION(!!aMap.mBCInfo == mIsBC, "BC state mismatch");
|
||||
uint32_t numRows = mRows.Length();
|
||||
uint32_t numCols = aMap.GetColCount();
|
||||
uint32_t rowIndex, colIndex;
|
||||
|
||||
for (rowIndex = 0; rowIndex < numRows; rowIndex++) {
|
||||
for (colIndex = 0; colIndex < numCols; colIndex++) {
|
||||
CellData* data = mRows[rowIndex].SafeElementAt(colIndex);
|
||||
if (!data || !data->IsOrig())
|
||||
continue;
|
||||
nsTableCellFrame* cell = data->GetCellFrame();
|
||||
NS_ASSERTION(cell, "There has to be a cell");
|
||||
int32_t cellRowSpan = cell->GetRowSpan();
|
||||
int32_t cellColSpan = cell->GetColSpan();
|
||||
bool rowZeroSpan = (0 == cell->GetRowSpan());
|
||||
bool colZeroSpan = (0 == cell->GetColSpan());
|
||||
if (colZeroSpan) {
|
||||
aMap.mTableFrame.SetHasZeroColSpans(true);
|
||||
// do the expansion
|
||||
NS_ASSERTION(numRows > 0, "Bogus numRows");
|
||||
NS_ASSERTION(numCols > 0, "Bogus numCols");
|
||||
uint32_t endRowIndex = rowZeroSpan ? numRows - 1 :
|
||||
rowIndex + cellRowSpan - 1;
|
||||
uint32_t endColIndex = colZeroSpan ? numCols - 1 :
|
||||
colIndex + cellColSpan - 1;
|
||||
uint32_t colX, rowX;
|
||||
colX = colIndex + 1;
|
||||
while (colX <= endColIndex) {
|
||||
// look at columns from here to our colspan. For each one, check
|
||||
// the rows from here to our rowspan to make sure there is no
|
||||
// obstacle to marking that column as a zerospanned column; if there
|
||||
// isn't, mark it so
|
||||
for (rowX = rowIndex; rowX <= endRowIndex; rowX++) {
|
||||
CellData* oldData = GetDataAt(rowX, colX);
|
||||
if (oldData) {
|
||||
if (oldData->IsOrig()) {
|
||||
break; // something is in the way
|
||||
}
|
||||
if (oldData->IsRowSpan()) {
|
||||
if ((rowX - rowIndex) != oldData->GetRowSpanOffset()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (oldData->IsColSpan()) {
|
||||
if ((colX - colIndex) != oldData->GetColSpanOffset()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (endRowIndex >= rowX)
|
||||
break;// we hit something
|
||||
for (rowX = rowIndex; rowX <= endRowIndex; rowX++) {
|
||||
CellData* newData = AllocCellData(nullptr);
|
||||
if (!newData) return;
|
||||
|
||||
newData->SetColSpanOffset(colX - colIndex);
|
||||
newData->SetZeroColSpan(true);
|
||||
|
||||
if (rowX > rowIndex) {
|
||||
newData->SetRowSpanOffset(rowX - rowIndex);
|
||||
if (rowZeroSpan)
|
||||
newData->SetZeroRowSpan(true);
|
||||
}
|
||||
SetDataAt(aMap, *newData, rowX, colX);
|
||||
}
|
||||
colX++;
|
||||
} // while (colX <= endColIndex)
|
||||
} // if zerocolspan
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG
|
||||
void nsCellMap::Dump(bool aIsBorderCollapse) const
|
||||
{
|
||||
@@ -2643,7 +2455,8 @@ nsCellMap::GetDataAt(int32_t aMapRowIndex,
|
||||
}
|
||||
|
||||
// only called if the cell at aMapRowIndex, aColIndex is null or dead
|
||||
// (the latter from ExpandZeroColSpans).
|
||||
// (the latter from ExpandZeroColSpans (XXXmats which has now been removed -
|
||||
// are there other ways cells may be dead?)).
|
||||
void nsCellMap::SetDataAt(nsTableCellMap& aMap,
|
||||
CellData& aNewCell,
|
||||
int32_t aMapRowIndex,
|
||||
@@ -2709,8 +2522,7 @@ nsCellMap::GetCellInfoAt(const nsTableCellMap& aMap,
|
||||
if (cellFrame && aColSpan) {
|
||||
int32_t initialColIndex;
|
||||
cellFrame->GetColIndex(initialColIndex);
|
||||
bool zeroSpan;
|
||||
*aColSpan = GetEffectiveColSpan(aMap, aRowX, initialColIndex, zeroSpan);
|
||||
*aColSpan = GetEffectiveColSpan(aMap, aRowX, initialColIndex);
|
||||
}
|
||||
}
|
||||
return cellFrame;
|
||||
@@ -2887,9 +2699,7 @@ nsCellMapColumnIterator::GetNextFrame(int32_t* aRow, int32_t* aColSpan)
|
||||
NS_ASSERTION(cellFrame, "Orig data without cellframe?");
|
||||
|
||||
*aRow = mCurMapStart + mCurMapRow;
|
||||
bool ignoredZeroSpan;
|
||||
*aColSpan = mCurMap->GetEffectiveColSpan(*mMap, mCurMapRow, mCol,
|
||||
ignoredZeroSpan);
|
||||
*aColSpan = mCurMap->GetEffectiveColSpan(*mMap, mCurMapRow, mCol);
|
||||
|
||||
IncrementRow(cellFrame->GetRowSpan());
|
||||
|
||||
|
||||
@@ -198,8 +198,6 @@ protected:
|
||||
TableArea& aDamageArea);
|
||||
|
||||
public:
|
||||
void ExpandZeroColSpans();
|
||||
|
||||
void ResetBStartStart(mozilla::LogicalSide aSide,
|
||||
nsCellMap& aCellMap,
|
||||
uint32_t aYPos,
|
||||
@@ -355,22 +353,6 @@ public:
|
||||
TableArea& aDamageArea,
|
||||
int32_t* aBeginSearchAtCol = nullptr);
|
||||
|
||||
/** Function to be called when a cell is added at a location which is spanned
|
||||
* to by a zero colspan. We handle this situation by collapsing the zero
|
||||
* colspan, since there is really no good way to deal with it (trying to
|
||||
* increase the number of columns to hold the new cell would just mean the
|
||||
* zero colspan needs to expand).
|
||||
|
||||
* @param aMap - reference to the table cell map
|
||||
* @param aOrigData - zero colspanned cell that will be collapsed
|
||||
* @param aRowIndex - row where the first collision appears
|
||||
* @param aColIndex - column where the first collision appears
|
||||
**/
|
||||
void CollapseZeroColSpan(nsTableCellMap& aMap,
|
||||
CellData* aOrigData,
|
||||
int32_t aRowIndex,
|
||||
int32_t aColIndex);
|
||||
|
||||
void InsertCells(nsTableCellMap& aMap,
|
||||
nsTArray<nsTableCellFrame*>& aCellFrames,
|
||||
int32_t aRowIndex,
|
||||
@@ -416,8 +398,6 @@ public:
|
||||
bool RowHasSpanningCells(int32_t aRowIndex,
|
||||
int32_t aNumEffCols) const;
|
||||
|
||||
void ExpandZeroColSpans(nsTableCellMap& aMap);
|
||||
|
||||
/** indicate whether the row has more than one cell that either originates
|
||||
* or is spanned from the rows above
|
||||
*/
|
||||
@@ -435,8 +415,7 @@ public:
|
||||
|
||||
int32_t GetEffectiveColSpan(const nsTableCellMap& aMap,
|
||||
int32_t aRowIndex,
|
||||
int32_t aColIndex,
|
||||
bool& aIsZeroColSpan) const;
|
||||
int32_t aColIndex) const;
|
||||
|
||||
typedef nsTArray<CellData*> CellDataArray;
|
||||
|
||||
@@ -540,9 +519,6 @@ protected:
|
||||
int32_t aStartColIndex,
|
||||
int32_t aEndColIndex) const;
|
||||
|
||||
void ExpandForZeroSpan(nsTableCellFrame* aCellFrame,
|
||||
int32_t aNumColsInTable);
|
||||
|
||||
bool CreateEmptyRow(int32_t aRowIndex,
|
||||
int32_t aNumCols);
|
||||
|
||||
@@ -550,9 +526,6 @@ protected:
|
||||
int32_t aRowIndex,
|
||||
bool& aIsZeroRowSpan) const;
|
||||
|
||||
int32_t GetColSpanForNewCell(nsTableCellFrame& aCellFrameToAdd,
|
||||
bool& aIsZeroColSpan) const;
|
||||
|
||||
// Destroy a CellData struct. This will handle the case of aData
|
||||
// actually being a BCCellData properly.
|
||||
void DestroyCellData(CellData* aData);
|
||||
|
||||
@@ -477,10 +477,9 @@ nsTableFrame::GetEffectiveColSpan(const nsTableCellFrame& aCell,
|
||||
int32_t colIndex, rowIndex;
|
||||
aCell.GetColIndex(colIndex);
|
||||
aCell.GetRowIndex(rowIndex);
|
||||
bool ignore;
|
||||
|
||||
if (aCellMap)
|
||||
return aCellMap->GetEffectiveColSpan(*tableCellMap, rowIndex, colIndex, ignore);
|
||||
return aCellMap->GetEffectiveColSpan(*tableCellMap, rowIndex, colIndex);
|
||||
else
|
||||
return tableCellMap->GetEffectiveColSpan(rowIndex, colIndex);
|
||||
}
|
||||
@@ -780,21 +779,6 @@ nsTableFrame::MatchCellMapToColCache(nsTableCellMap* aCellMap)
|
||||
aCellMap->AddColsAtEnd(numColsNotRemoved);
|
||||
}
|
||||
}
|
||||
if (numColsToAdd && HasZeroColSpans()) {
|
||||
SetNeedColSpanExpansion(true);
|
||||
}
|
||||
if (NeedColSpanExpansion()) {
|
||||
// This flag can be set in two ways -- either by changing
|
||||
// the number of columns (that happens in the block above),
|
||||
// or by adding a cell with colspan="0" to the cellmap. To
|
||||
// handle the latter case we need to explicitly check the
|
||||
// flag here -- it may be set even if the number of columns
|
||||
// did not change.
|
||||
//
|
||||
// @see nsCellMap::AppendCell
|
||||
|
||||
aCellMap->ExpandZeroColSpans();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1404,9 +1388,8 @@ nsTableFrame::PaintTableBorderBackground(nsDisplayListBuilder* aBuilder,
|
||||
nsCSSRendering::PaintBorder(presContext, aRenderingContext, this,
|
||||
aDirtyRect, rect, mStyleContext,
|
||||
borderFlags, skipSides);
|
||||
}
|
||||
else {
|
||||
gfxContext* ctx = aRenderingContext.ThebesContext();
|
||||
} else {
|
||||
DrawTarget* drawTarget = aRenderingContext.GetDrawTarget();
|
||||
|
||||
gfxPoint devPixelOffset =
|
||||
nsLayoutUtils::PointToGfxPoint(aPt,
|
||||
@@ -1414,10 +1397,11 @@ nsTableFrame::PaintTableBorderBackground(nsDisplayListBuilder* aBuilder,
|
||||
|
||||
// XXX we should probably get rid of this translation at some stage
|
||||
// But that would mean modifying PaintBCBorders, ugh
|
||||
gfxContextMatrixAutoSaveRestore autoSR(ctx);
|
||||
ctx->SetMatrix(ctx->CurrentMatrix().Translate(devPixelOffset));
|
||||
AutoRestoreTransform autoRestoreTransform(drawTarget);
|
||||
drawTarget->SetTransform(
|
||||
drawTarget->GetTransform().PreTranslate(ToPoint(devPixelOffset)));
|
||||
|
||||
PaintBCBorders(aRenderingContext, aDirtyRect - aPt);
|
||||
PaintBCBorders(*drawTarget, aDirtyRect - aPt);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6222,7 +6206,7 @@ struct BCBlockDirSeg
|
||||
|
||||
|
||||
void Paint(BCPaintBorderIterator& aIter,
|
||||
nsRenderingContext& aRenderingContext,
|
||||
DrawTarget& aDrawTarget,
|
||||
BCPixelSize aInlineSegBSize);
|
||||
void AdvanceOffsetB();
|
||||
void IncludeCurrentBorder(BCPaintBorderIterator& aIter);
|
||||
@@ -6272,8 +6256,7 @@ struct BCInlineDirSeg
|
||||
BCPixelSize aIStartSegISize);
|
||||
void AdvanceOffsetI();
|
||||
void IncludeCurrentBorder(BCPaintBorderIterator& aIter);
|
||||
void Paint(BCPaintBorderIterator& aIter,
|
||||
nsRenderingContext& aRenderingContext);
|
||||
void Paint(BCPaintBorderIterator& aIter, DrawTarget& aDrawTarget);
|
||||
|
||||
nscoord mOffsetI; // i-offset with respect to the table edge
|
||||
nscoord mOffsetB; // b-offset with respect to the table edge
|
||||
@@ -6317,8 +6300,8 @@ public:
|
||||
bool SetDamageArea(const nsRect& aDamageRect);
|
||||
void First();
|
||||
void Next();
|
||||
void AccumulateOrPaintInlineDirSegment(nsRenderingContext& aRenderingContext);
|
||||
void AccumulateOrPaintBlockDirSegment(nsRenderingContext& aRenderingContext);
|
||||
void AccumulateOrPaintInlineDirSegment(DrawTarget& aDrawTarget);
|
||||
void AccumulateOrPaintBlockDirSegment(DrawTarget& aDrawTarget);
|
||||
void ResetVerInfo();
|
||||
void StoreColumnWidth(int32_t aIndex);
|
||||
bool BlockDirSegmentOwnsCorner();
|
||||
@@ -6948,14 +6931,14 @@ BCBlockDirSeg::GetBEndCorner(BCPaintBorderIterator& aIter,
|
||||
|
||||
/**
|
||||
* Paint the block-dir segment
|
||||
* @param aIter - iterator containing the structural information
|
||||
* @param aRenderingContext - the rendering context
|
||||
* @param aInlineSegBSize - the width of the inline-dir segment joining the corner
|
||||
* at the start
|
||||
* @param aIter - iterator containing the structural information
|
||||
* @param aDrawTarget - the draw target
|
||||
* @param aInlineSegBSize - the width of the inline-dir segment joining the
|
||||
* corner at the start
|
||||
*/
|
||||
void
|
||||
BCBlockDirSeg::Paint(BCPaintBorderIterator& aIter,
|
||||
nsRenderingContext& aRenderingContext,
|
||||
DrawTarget& aDrawTarget,
|
||||
BCPixelSize aInlineSegBSize)
|
||||
{
|
||||
// get the border style, color and paint the segment
|
||||
@@ -7060,8 +7043,8 @@ BCBlockDirSeg::Paint(BCPaintBorderIterator& aIter,
|
||||
Swap(startBevelSide, endBevelSide);
|
||||
Swap(startBevelOffset, endBevelOffset);
|
||||
}
|
||||
nsCSSRendering::DrawTableBorderSegment(aRenderingContext, style, color,
|
||||
aIter.mTableBgColor, physicalRect,
|
||||
nsCSSRendering::DrawTableBorderSegment(aDrawTarget, style, color,
|
||||
aIter.mTableBgColor, physicalRect,
|
||||
appUnitsPerDevPixel,
|
||||
aIter.mTable->PresContext()->AppUnitsPerDevPixel(),
|
||||
startBevelSide, startBevelOffset,
|
||||
@@ -7163,12 +7146,11 @@ BCInlineDirSeg::GetIEndCorner(BCPaintBorderIterator& aIter,
|
||||
|
||||
/**
|
||||
* Paint the inline-dir segment
|
||||
* @param aIter - iterator containing the structural information
|
||||
* @param aRenderingContext - the rendering context
|
||||
* @param aIter - iterator containing the structural information
|
||||
* @param aDrawTarget - the draw target
|
||||
*/
|
||||
void
|
||||
BCInlineDirSeg::Paint(BCPaintBorderIterator& aIter,
|
||||
nsRenderingContext& aRenderingContext)
|
||||
BCInlineDirSeg::Paint(BCPaintBorderIterator& aIter, DrawTarget& aDrawTarget)
|
||||
{
|
||||
// get the border style, color and paint the segment
|
||||
LogicalSide side =
|
||||
@@ -7266,7 +7248,7 @@ BCInlineDirSeg::Paint(BCPaintBorderIterator& aIter,
|
||||
Swap(startBevelSide, endBevelSide);
|
||||
Swap(startBevelOffset, endBevelOffset);
|
||||
}
|
||||
nsCSSRendering::DrawTableBorderSegment(aRenderingContext, style, color,
|
||||
nsCSSRendering::DrawTableBorderSegment(aDrawTarget, style, color,
|
||||
aIter.mTableBgColor, physicalRect,
|
||||
appUnitsPerDevPixel,
|
||||
aIter.mTable->PresContext()->AppUnitsPerDevPixel(),
|
||||
@@ -7325,10 +7307,10 @@ BCPaintBorderIterator::BlockDirSegmentOwnsCorner()
|
||||
|
||||
/**
|
||||
* Paint if necessary an inline-dir segment, otherwise accumulate it
|
||||
* @param aRenderingContext - the rendering context
|
||||
* @param aDrawTarget - the draw target
|
||||
*/
|
||||
void
|
||||
BCPaintBorderIterator::AccumulateOrPaintInlineDirSegment(nsRenderingContext& aRenderingContext)
|
||||
BCPaintBorderIterator::AccumulateOrPaintInlineDirSegment(DrawTarget& aDrawTarget)
|
||||
{
|
||||
|
||||
int32_t relColIndex = GetRelativeColIndex();
|
||||
@@ -7361,7 +7343,7 @@ BCPaintBorderIterator::AccumulateOrPaintInlineDirSegment(nsRenderingContext& aRe
|
||||
if (mInlineSeg.mLength > 0) {
|
||||
mInlineSeg.GetIEndCorner(*this, iStartSegISize);
|
||||
if (mInlineSeg.mWidth > 0) {
|
||||
mInlineSeg.Paint(*this, aRenderingContext);
|
||||
mInlineSeg.Paint(*this, aDrawTarget);
|
||||
}
|
||||
mInlineSeg.AdvanceOffsetI();
|
||||
}
|
||||
@@ -7373,10 +7355,10 @@ BCPaintBorderIterator::AccumulateOrPaintInlineDirSegment(nsRenderingContext& aRe
|
||||
}
|
||||
/**
|
||||
* Paint if necessary a block-dir segment, otherwise accumulate it
|
||||
* @param aRenderingContext - the rendering context
|
||||
* @param aDrawTarget - the draw target
|
||||
*/
|
||||
void
|
||||
BCPaintBorderIterator::AccumulateOrPaintBlockDirSegment(nsRenderingContext& aRenderingContext)
|
||||
BCPaintBorderIterator::AccumulateOrPaintBlockDirSegment(DrawTarget& aDrawTarget)
|
||||
{
|
||||
BCBorderOwner borderOwner = eCellOwner;
|
||||
BCBorderOwner ignoreBorderOwner;
|
||||
@@ -7403,7 +7385,7 @@ BCPaintBorderIterator::AccumulateOrPaintBlockDirSegment(nsRenderingContext& aRen
|
||||
if (blockDirSeg.mLength > 0) {
|
||||
blockDirSeg.GetBEndCorner(*this, inlineSegBSize);
|
||||
if (blockDirSeg.mWidth > 0) {
|
||||
blockDirSeg.Paint(*this, aRenderingContext, inlineSegBSize);
|
||||
blockDirSeg.Paint(*this, aDrawTarget, inlineSegBSize);
|
||||
}
|
||||
blockDirSeg.AdvanceOffsetB();
|
||||
}
|
||||
@@ -7431,12 +7413,11 @@ BCPaintBorderIterator::ResetVerInfo()
|
||||
/**
|
||||
* Method to paint BCBorders, this does not use currently display lists although
|
||||
* it will do this in future
|
||||
* @param aRenderingContext - the rendering context
|
||||
* @param aDirtyRect - inside this rectangle the BC Borders will redrawn
|
||||
* @param aDrawTarget - the rendering context
|
||||
* @param aDirtyRect - inside this rectangle the BC Borders will redrawn
|
||||
*/
|
||||
void
|
||||
nsTableFrame::PaintBCBorders(nsRenderingContext& aRenderingContext,
|
||||
const nsRect& aDirtyRect)
|
||||
nsTableFrame::PaintBCBorders(DrawTarget& aDrawTarget, const nsRect& aDirtyRect)
|
||||
{
|
||||
// We first transfer the aDirtyRect into cellmap coordinates to compute which
|
||||
// cell borders need to be painted
|
||||
@@ -7455,7 +7436,7 @@ nsTableFrame::PaintBCBorders(nsRenderingContext& aRenderingContext,
|
||||
// this we the now active segment with the current border. These
|
||||
// segments are stored in mBlockDirInfo to be used on the next row
|
||||
for (iter.First(); !iter.mAtEnd; iter.Next()) {
|
||||
iter.AccumulateOrPaintBlockDirSegment(aRenderingContext);
|
||||
iter.AccumulateOrPaintBlockDirSegment(aDrawTarget);
|
||||
}
|
||||
|
||||
// Next, paint all of the inline-dir border segments from bStart to bEnd reuse
|
||||
@@ -7463,7 +7444,7 @@ nsTableFrame::PaintBCBorders(nsRenderingContext& aRenderingContext,
|
||||
// corner calculations
|
||||
iter.Reset();
|
||||
for (iter.First(); !iter.mAtEnd; iter.Next()) {
|
||||
iter.AccumulateOrPaintInlineDirSegment(aRenderingContext);
|
||||
iter.AccumulateOrPaintInlineDirSegment(aDrawTarget);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -312,8 +312,7 @@ public:
|
||||
void AddBCDamageArea(const mozilla::TableArea& aValue);
|
||||
bool BCRecalcNeeded(nsStyleContext* aOldStyleContext,
|
||||
nsStyleContext* aNewStyleContext);
|
||||
void PaintBCBorders(nsRenderingContext& aRenderingContext,
|
||||
const nsRect& aDirtyRect);
|
||||
void PaintBCBorders(DrawTarget& aDrawTarget, const nsRect& aDirtyRect);
|
||||
|
||||
virtual void MarkIntrinsicISizesDirty() override;
|
||||
// For border-collapse tables, the caller must not add padding and
|
||||
@@ -763,12 +762,6 @@ public:
|
||||
bool NeedToCollapse() const;
|
||||
void SetNeedToCollapse(bool aValue);
|
||||
|
||||
bool HasZeroColSpans() const;
|
||||
void SetHasZeroColSpans(bool aValue);
|
||||
|
||||
bool NeedColSpanExpansion() const;
|
||||
void SetNeedColSpanExpansion(bool aValue);
|
||||
|
||||
/** The GeometryDirty bit is similar to the NS_FRAME_IS_DIRTY frame
|
||||
* state bit, which implies that all descendants are dirty. The
|
||||
* GeometryDirty still implies that all the parts of the table are
|
||||
@@ -875,9 +868,7 @@ protected:
|
||||
uint32_t mNeedToCalcBCBorders:1;
|
||||
uint32_t mGeometryDirty:1;
|
||||
uint32_t mIStartContBCBorder:8;
|
||||
uint32_t mNeedToCollapse:1; // rows, cols that have visibility:collapse need to be collapsed
|
||||
uint32_t mHasZeroColSpans:1;
|
||||
uint32_t mNeedColSpanExpansion:1;
|
||||
uint32_t mNeedToCollapse:1; // rows, cols that have visibility:collapse need to be collapsed
|
||||
uint32_t mResizedColumns:1; // have we resized columns since last reflow?
|
||||
} mBits;
|
||||
|
||||
@@ -944,27 +935,6 @@ inline bool nsTableFrame::NeedToCollapse() const
|
||||
return (bool) static_cast<nsTableFrame*>(FirstInFlow())->mBits.mNeedToCollapse;
|
||||
}
|
||||
|
||||
inline void nsTableFrame::SetHasZeroColSpans(bool aValue)
|
||||
{
|
||||
mBits.mHasZeroColSpans = (unsigned)aValue;
|
||||
}
|
||||
|
||||
inline bool nsTableFrame::HasZeroColSpans() const
|
||||
{
|
||||
return (bool)mBits.mHasZeroColSpans;
|
||||
}
|
||||
|
||||
inline void nsTableFrame::SetNeedColSpanExpansion(bool aValue)
|
||||
{
|
||||
mBits.mNeedColSpanExpansion = (unsigned)aValue;
|
||||
}
|
||||
|
||||
inline bool nsTableFrame::NeedColSpanExpansion() const
|
||||
{
|
||||
return (bool)mBits.mNeedColSpanExpansion;
|
||||
}
|
||||
|
||||
|
||||
inline nsFrameList& nsTableFrame::GetColGroups()
|
||||
{
|
||||
return static_cast<nsTableFrame*>(FirstInFlow())->mColGroups;
|
||||
|
||||
@@ -190,6 +190,7 @@
|
||||
|
||||
#include "mozilla/layers/APZCTreeManager.h"
|
||||
#include "mozilla/layers/InputAPZContext.h"
|
||||
#include "ClientLayerManager.h"
|
||||
#include "InputData.h"
|
||||
|
||||
#include "mozilla/Telemetry.h"
|
||||
@@ -1402,6 +1403,17 @@ nsWindow::SetSizeConstraints(const SizeConstraints& aConstraints)
|
||||
c.mMinSize.width = std::max(int32_t(::GetSystemMetrics(SM_CXMINTRACK)), c.mMinSize.width);
|
||||
c.mMinSize.height = std::max(int32_t(::GetSystemMetrics(SM_CYMINTRACK)), c.mMinSize.height);
|
||||
}
|
||||
ClientLayerManager *clientLayerManager = GetLayerManager()->AsClientLayerManager();
|
||||
|
||||
if (clientLayerManager) {
|
||||
int32_t maxSize = clientLayerManager->GetMaxTextureSize();
|
||||
// We can't make ThebesLayers bigger than this anyway.. no point it letting
|
||||
// a window grow bigger as we won't be able to draw content there in
|
||||
// general.
|
||||
c.mMaxSize.width = std::min(c.mMaxSize.width, maxSize);
|
||||
c.mMaxSize.height = std::min(c.mMaxSize.height, maxSize);
|
||||
}
|
||||
|
||||
mSizeConstraintsScale = GetDefaultScale().scale;
|
||||
|
||||
nsBaseWidget::SetSizeConstraints(c);
|
||||
|
||||
@@ -218,10 +218,7 @@ bool nsWindow::OnPaint(HDC aDC, uint32_t aNestingLevel)
|
||||
return true;
|
||||
}
|
||||
|
||||
ClientLayerManager *clientLayerManager =
|
||||
(GetLayerManager()->GetBackendType() == LayersBackend::LAYERS_CLIENT)
|
||||
? static_cast<ClientLayerManager*>(GetLayerManager())
|
||||
: nullptr;
|
||||
ClientLayerManager *clientLayerManager = GetLayerManager()->AsClientLayerManager();
|
||||
|
||||
if (clientLayerManager && mCompositorParent &&
|
||||
!mBounds.IsEqualEdges(mLastPaintBounds))
|
||||
|
||||
Reference in New Issue
Block a user