mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge latest green b2g-inbound changeset and mozilla-central
This commit is contained in:
commit
6cdb8fe911
@ -502,8 +502,8 @@ Element::GetScrollFrame(nsIFrame **aStyledFrame, bool aFlushLayout)
|
||||
|
||||
// menu frames implement GetScrollTargetFrame but we don't want
|
||||
// to use it here. Similar for comboboxes.
|
||||
if (frame->GetType() != nsGkAtoms::menuFrame &&
|
||||
frame->GetType() != nsGkAtoms::comboboxControlFrame) {
|
||||
nsIAtom* type = frame->GetType();
|
||||
if (type != nsGkAtoms::menuFrame && type != nsGkAtoms::comboboxControlFrame) {
|
||||
nsIScrollableFrame *scrollFrame = frame->GetScrollTargetFrame();
|
||||
if (scrollFrame)
|
||||
return scrollFrame;
|
||||
|
@ -532,9 +532,9 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void RemoveTextTrack(TextTrack* aTextTrack) {
|
||||
void RemoveTextTrack(TextTrack* aTextTrack, bool aPendingListOnly = false) {
|
||||
if (mTextTrackManager) {
|
||||
mTextTrackManager->RemoveTextTrack(aTextTrack);
|
||||
mTextTrackManager->RemoveTextTrack(aTextTrack, aPendingListOnly);
|
||||
}
|
||||
}
|
||||
|
||||
@ -862,6 +862,11 @@ protected:
|
||||
// Update the audio channel playing state
|
||||
virtual void UpdateAudioChannelPlayingState();
|
||||
|
||||
// Adds to the element's list of pending text tracks each text track
|
||||
// in the element's list of text tracks whose text track mode is not disabled
|
||||
// and whose text track readiness state is loading.
|
||||
void PopulatePendingTextTrackList();
|
||||
|
||||
// The current decoder. Load() has been called on this decoder.
|
||||
// At most one of mDecoder and mSrcStream can be non-null.
|
||||
nsRefPtr<MediaDecoder> mDecoder;
|
||||
|
@ -3920,5 +3920,13 @@ HTMLMediaElement::AddTextTrack(TextTrackKind aKind,
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
HTMLMediaElement::PopulatePendingTextTrackList()
|
||||
{
|
||||
if (mTextTrackManager) {
|
||||
mTextTrackManager->PopulatePendingList();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
@ -67,7 +67,6 @@ static const char* kKindTableDefaultString = kKindTable->tag;
|
||||
/** HTMLTrackElement */
|
||||
HTMLTrackElement::HTMLTrackElement(already_AddRefed<nsINodeInfo> aNodeInfo)
|
||||
: nsGenericHTMLElement(aNodeInfo)
|
||||
, mReadyState(NONE)
|
||||
{
|
||||
#ifdef PR_LOGGING
|
||||
if (!gTrackElementLog) {
|
||||
@ -305,5 +304,15 @@ HTMLTrackElement::UnbindFromTree(bool aDeep, bool aNullParent)
|
||||
nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
|
||||
}
|
||||
|
||||
uint16_t
|
||||
HTMLTrackElement::ReadyState() const
|
||||
{
|
||||
if (!mTrack) {
|
||||
return NONE;
|
||||
}
|
||||
|
||||
return mTrack->ReadyState();
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
@ -102,10 +102,7 @@ public:
|
||||
LOADED = 2U,
|
||||
ERROR = 3U
|
||||
};
|
||||
uint16_t ReadyState() const
|
||||
{
|
||||
return mReadyState;
|
||||
}
|
||||
uint16_t ReadyState() const;
|
||||
|
||||
TextTrack* Track();
|
||||
|
||||
@ -157,7 +154,6 @@ protected:
|
||||
nsCOMPtr<nsIChannel> mChannel;
|
||||
nsRefPtr<HTMLMediaElement> mMediaParent;
|
||||
nsRefPtr<WebVTTListener> mListener;
|
||||
uint16_t mReadyState;
|
||||
|
||||
void CreateTextTrack();
|
||||
};
|
||||
|
@ -7,11 +7,12 @@
|
||||
|
||||
#include "mozilla/dom/TextTrackManager.h"
|
||||
#include "mozilla/dom/HTMLMediaElement.h"
|
||||
#include "mozilla/dom/HTMLTrackElement.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_1(TextTrackManager, mTextTracks)
|
||||
NS_IMPL_CYCLE_COLLECTION_2(TextTrackManager, mTextTracks, mPendingTextTracks)
|
||||
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(TextTrackManager, AddRef)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(TextTrackManager, Release)
|
||||
|
||||
@ -20,6 +21,8 @@ TextTrackManager::TextTrackManager(HTMLMediaElement *aMediaElement)
|
||||
{
|
||||
MOZ_COUNT_CTOR(TextTrackManager);
|
||||
mTextTracks = new TextTrackList(mMediaElement->OwnerDoc()->GetParentObject());
|
||||
mPendingTextTracks =
|
||||
new TextTrackList(mMediaElement->OwnerDoc()->GetParentObject());
|
||||
}
|
||||
|
||||
TextTrackManager::~TextTrackManager()
|
||||
@ -37,7 +40,10 @@ already_AddRefed<TextTrack>
|
||||
TextTrackManager::AddTextTrack(TextTrackKind aKind, const nsAString& aLabel,
|
||||
const nsAString& aLanguage)
|
||||
{
|
||||
return mTextTracks->AddTextTrack(mMediaElement, aKind, aLabel, aLanguage);
|
||||
nsRefPtr<TextTrack> ttrack =
|
||||
mTextTracks->AddTextTrack(mMediaElement, aKind, aLabel, aLanguage);
|
||||
ttrack->SetReadyState(HTMLTrackElement::LOADED);
|
||||
return ttrack.forget();
|
||||
}
|
||||
|
||||
void
|
||||
@ -47,8 +53,13 @@ TextTrackManager::AddTextTrack(TextTrack* aTextTrack)
|
||||
}
|
||||
|
||||
void
|
||||
TextTrackManager::RemoveTextTrack(TextTrack* aTextTrack)
|
||||
TextTrackManager::RemoveTextTrack(TextTrack* aTextTrack, bool aPendingListOnly)
|
||||
{
|
||||
mPendingTextTracks->RemoveTextTrack(aTextTrack);
|
||||
if (aPendingListOnly) {
|
||||
return;
|
||||
}
|
||||
|
||||
mTextTracks->RemoveTextTrack(aTextTrack);
|
||||
}
|
||||
|
||||
@ -64,5 +75,19 @@ TextTrackManager::Update(double aTime)
|
||||
mTextTracks->Update(aTime);
|
||||
}
|
||||
|
||||
void
|
||||
TextTrackManager::PopulatePendingList()
|
||||
{
|
||||
uint32_t len = mTextTracks->Length();
|
||||
bool dummy;
|
||||
for (uint32_t index = 0; index < len; ++index) {
|
||||
TextTrack* ttrack = mTextTracks->IndexedGetter(index, dummy);
|
||||
if (ttrack && ttrack->Mode() != TextTrackMode::Disabled &&
|
||||
ttrack->ReadyState() == HTMLTrackElement::LOADING) {
|
||||
mPendingTextTracks->AddTextTrack(ttrack);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
@ -30,13 +30,15 @@ public:
|
||||
const nsAString& aLabel,
|
||||
const nsAString& aLanguage);
|
||||
void AddTextTrack(TextTrack* aTextTrack);
|
||||
void RemoveTextTrack(TextTrack* aTextTrack);
|
||||
void RemoveTextTrack(TextTrack* aTextTrack, bool aPendingListOnly);
|
||||
void DidSeek();
|
||||
|
||||
// Update the display of cues on the video as per the current play back time
|
||||
// of aTime.
|
||||
void Update(double aTime);
|
||||
|
||||
void PopulatePendingList();
|
||||
|
||||
private:
|
||||
// The HTMLMediaElement that this TextTrackManager manages the TextTracks of.
|
||||
// This is a weak reference as the life time of TextTrackManager is dependent
|
||||
@ -45,6 +47,8 @@ private:
|
||||
HTMLMediaElement* mMediaElement;
|
||||
// List of the TextTrackManager's owning HTMLMediaElement's TextTracks.
|
||||
nsRefPtr<TextTrackList> mTextTracks;
|
||||
// List of text track objects awaiting loading.
|
||||
nsRefPtr<TextTrackList> mPendingTextTracks;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "mozilla/dom/TextTrackRegion.h"
|
||||
#include "mozilla/dom/TextTrackRegionList.h"
|
||||
#include "mozilla/dom/HTMLMediaElement.h"
|
||||
#include "mozilla/dom/HTMLTrackElement.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
@ -68,6 +69,7 @@ TextTrack::SetDefaultSettings()
|
||||
mRegionList = new TextTrackRegionList(mParent);
|
||||
mCuePos = 0;
|
||||
mDirty = false;
|
||||
mReadyState = HTMLTrackElement::NONE;
|
||||
}
|
||||
|
||||
void
|
||||
@ -170,5 +172,21 @@ TextTrack::GetActiveCues()
|
||||
return mActiveCueList;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
TextTrack::ReadyState() const
|
||||
{
|
||||
return mReadyState;
|
||||
}
|
||||
|
||||
void
|
||||
TextTrack::SetReadyState(uint16_t aState)
|
||||
{
|
||||
mReadyState = aState;
|
||||
if (mReadyState == HTMLTrackElement::LOADED ||
|
||||
mReadyState == HTMLTrackElement::ERROR) {
|
||||
mMediaElement->RemoveTextTrack(this, true);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
@ -92,6 +92,9 @@ public:
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
uint16_t ReadyState() const;
|
||||
void SetReadyState(uint16_t aState);
|
||||
|
||||
void AddRegion(TextTrackRegion& aRegion);
|
||||
void RemoveRegion(const TextTrackRegion& aRegion, ErrorResult& aRv);
|
||||
|
||||
@ -121,6 +124,7 @@ private:
|
||||
nsRefPtr<TextTrackRegionList> mRegionList;
|
||||
|
||||
uint32_t mCuePos;
|
||||
uint16_t mReadyState;
|
||||
bool mDirty;
|
||||
};
|
||||
|
||||
|
@ -78,7 +78,7 @@ WebVTTListener::LoadResource()
|
||||
rv = mParserWrapper->Watch(this);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mElement->mReadyState = HTMLTrackElement::LOADING;
|
||||
mElement->mTrack->SetReadyState(HTMLTrackElement::LOADING);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -106,8 +106,8 @@ WebVTTListener::OnStopRequest(nsIRequest* aRequest,
|
||||
nsISupports* aContext,
|
||||
nsresult aStatus)
|
||||
{
|
||||
if (mElement->mReadyState != HTMLTrackElement::ERROR) {
|
||||
mElement->mReadyState = HTMLTrackElement::LOADED;
|
||||
if (mElement->ReadyState() != HTMLTrackElement::ERROR) {
|
||||
mElement->mTrack->SetReadyState(HTMLTrackElement::LOADED);
|
||||
}
|
||||
// Attempt to parse any final data the parser might still have.
|
||||
mParserWrapper->Flush();
|
||||
|
@ -17,9 +17,10 @@ namespace dom {
|
||||
//
|
||||
// Basic (virtual) BarProp class implementation
|
||||
//
|
||||
BarProp::BarProp(nsGlobalWindow *aWindow)
|
||||
BarProp::BarProp(nsGlobalWindow* aWindow)
|
||||
: mDOMWindow(aWindow)
|
||||
{
|
||||
MOZ_ASSERT(aWindow->IsInnerWindow());
|
||||
SetIsDOMBinding();
|
||||
}
|
||||
|
||||
|
@ -3665,7 +3665,7 @@ nsGlobalWindow::GetPrompter(nsIPrompt** aPrompt)
|
||||
NS_IMETHODIMP
|
||||
nsGlobalWindow::GetMenubar(nsISupports** aMenubar)
|
||||
{
|
||||
FORWARD_TO_OUTER(GetMenubar, (aMenubar), NS_ERROR_NOT_INITIALIZED);
|
||||
FORWARD_TO_INNER(GetMenubar, (aMenubar), NS_ERROR_NOT_INITIALIZED);
|
||||
|
||||
*aMenubar = nullptr;
|
||||
|
||||
@ -3684,7 +3684,7 @@ nsGlobalWindow::GetMenubar(nsISupports** aMenubar)
|
||||
NS_IMETHODIMP
|
||||
nsGlobalWindow::GetToolbar(nsISupports** aToolbar)
|
||||
{
|
||||
FORWARD_TO_OUTER(GetToolbar, (aToolbar), NS_ERROR_NOT_INITIALIZED);
|
||||
FORWARD_TO_INNER(GetToolbar, (aToolbar), NS_ERROR_NOT_INITIALIZED);
|
||||
|
||||
*aToolbar = nullptr;
|
||||
|
||||
@ -3703,7 +3703,7 @@ nsGlobalWindow::GetToolbar(nsISupports** aToolbar)
|
||||
NS_IMETHODIMP
|
||||
nsGlobalWindow::GetLocationbar(nsISupports** aLocationbar)
|
||||
{
|
||||
FORWARD_TO_OUTER(GetLocationbar, (aLocationbar), NS_ERROR_NOT_INITIALIZED);
|
||||
FORWARD_TO_INNER(GetLocationbar, (aLocationbar), NS_ERROR_NOT_INITIALIZED);
|
||||
|
||||
*aLocationbar = nullptr;
|
||||
|
||||
@ -3722,7 +3722,7 @@ nsGlobalWindow::GetLocationbar(nsISupports** aLocationbar)
|
||||
NS_IMETHODIMP
|
||||
nsGlobalWindow::GetPersonalbar(nsISupports** aPersonalbar)
|
||||
{
|
||||
FORWARD_TO_OUTER(GetPersonalbar, (aPersonalbar), NS_ERROR_NOT_INITIALIZED);
|
||||
FORWARD_TO_INNER(GetPersonalbar, (aPersonalbar), NS_ERROR_NOT_INITIALIZED);
|
||||
|
||||
*aPersonalbar = nullptr;
|
||||
|
||||
@ -3741,7 +3741,7 @@ nsGlobalWindow::GetPersonalbar(nsISupports** aPersonalbar)
|
||||
NS_IMETHODIMP
|
||||
nsGlobalWindow::GetStatusbar(nsISupports** aStatusbar)
|
||||
{
|
||||
FORWARD_TO_OUTER(GetStatusbar, (aStatusbar), NS_ERROR_NOT_INITIALIZED);
|
||||
FORWARD_TO_INNER(GetStatusbar, (aStatusbar), NS_ERROR_NOT_INITIALIZED);
|
||||
|
||||
*aStatusbar = nullptr;
|
||||
|
||||
@ -3758,8 +3758,9 @@ nsGlobalWindow::GetStatusbar(nsISupports** aStatusbar)
|
||||
}
|
||||
|
||||
mozilla::dom::BarProp*
|
||||
nsGlobalWindow::Scrollbars()
|
||||
nsGlobalWindow::GetScrollbars()
|
||||
{
|
||||
FORWARD_TO_INNER(GetScrollbars, (), nullptr);
|
||||
if (!mScrollbars) {
|
||||
mScrollbars = new ScrollbarsProp(this);
|
||||
}
|
||||
@ -3770,9 +3771,7 @@ nsGlobalWindow::Scrollbars()
|
||||
NS_IMETHODIMP
|
||||
nsGlobalWindow::GetScrollbars(nsISupports** aScrollbars)
|
||||
{
|
||||
FORWARD_TO_OUTER(GetScrollbars, (aScrollbars), NS_ERROR_NOT_INITIALIZED);
|
||||
|
||||
NS_ADDREF(*aScrollbars = Scrollbars());
|
||||
NS_IF_ADDREF(*aScrollbars = GetScrollbars());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -765,7 +765,7 @@ public:
|
||||
mozilla::dom::SpeechSynthesis* GetSpeechSynthesisInternal();
|
||||
#endif
|
||||
|
||||
mozilla::dom::BarProp* Scrollbars();
|
||||
mozilla::dom::BarProp* GetScrollbars();
|
||||
|
||||
protected:
|
||||
// Array of idle observers that are notified of idle events.
|
||||
|
5
js/src/jit-test/tests/ion/bug877936-2.js
Normal file
5
js/src/jit-test/tests/ion/bug877936-2.js
Normal file
@ -0,0 +1,5 @@
|
||||
rex = RegExp("()()()()()()()()()()(z)?(y)");
|
||||
a = ["sub"];
|
||||
a[230] = '' + "a"
|
||||
f = Function.apply(null, a);
|
||||
"xyz".replace(rex, f);
|
44
js/src/jit-test/tests/ion/bug877936.js
Normal file
44
js/src/jit-test/tests/ion/bug877936.js
Normal file
@ -0,0 +1,44 @@
|
||||
try{} catch(e){}
|
||||
|
||||
function test(a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
test();
|
||||
test();
|
||||
|
||||
/////////////////////
|
||||
|
||||
function test2() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
var a = 1;
|
||||
test2(a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a);
|
||||
test2(a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a);
|
||||
|
||||
/////////////////////
|
||||
|
||||
function test4() {
|
||||
test3()
|
||||
}
|
||||
|
||||
function test3(a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
test4();
|
||||
|
||||
/////////////////////
|
||||
|
||||
function test6() {
|
||||
test5.apply({}, [])
|
||||
}
|
||||
|
||||
function test5() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
test6();
|
||||
test6();
|
@ -24,6 +24,7 @@ StartArgSlot(JSScript *script, JSFunction *fun)
|
||||
// When needed:
|
||||
// Slot 2: Argumentsobject.
|
||||
|
||||
// Note: when updating this, please also update the assert in SnapshotWriter::startFrame
|
||||
return 2 + (script->argumentsHasVarBinding() ? 1 : 0);
|
||||
}
|
||||
|
||||
@ -34,6 +35,8 @@ CountArgSlots(JSScript *script, JSFunction *fun)
|
||||
// Slot x + 1: Argument 1.
|
||||
// ...
|
||||
// Slot x + n: Argument n.
|
||||
|
||||
// Note: when updating this, please also update the assert in SnapshotWriter::startFrame
|
||||
return StartArgSlot(script, fun) + (fun ? fun->nargs + 1 : 0);
|
||||
}
|
||||
|
||||
|
@ -1656,12 +1656,6 @@ IonCompile(JSContext *cx, JSScript *script,
|
||||
return success ? AbortReason_NoAbort : AbortReason_Disable;
|
||||
}
|
||||
|
||||
static bool
|
||||
TooManyArguments(unsigned nargs)
|
||||
{
|
||||
return (nargs >= SNAPSHOT_MAX_NARGS || nargs > js_IonOptions.maxStackArgs);
|
||||
}
|
||||
|
||||
static bool
|
||||
CheckFrame(BaselineFrame *frame)
|
||||
{
|
||||
@ -1902,6 +1896,12 @@ jit::CanEnter(JSContext *cx, RunState &state)
|
||||
return Method_CantCompile;
|
||||
}
|
||||
|
||||
if (TooManyArguments(invoke.args().callee().as<JSFunction>().nargs)) {
|
||||
IonSpew(IonSpew_Abort, "too many args");
|
||||
ForbidCompilation(cx, script);
|
||||
return Method_CantCompile;
|
||||
}
|
||||
|
||||
if (invoke.constructing() && invoke.args().thisv().isPrimitive()) {
|
||||
RootedScript scriptRoot(cx, script);
|
||||
RootedObject callee(cx, &invoke.args().callee());
|
||||
|
@ -384,6 +384,12 @@ IsIonInlinablePC(jsbytecode *pc) {
|
||||
return IsCallPC(pc) || IsGetPropPC(pc) || IsSetPropPC(pc);
|
||||
}
|
||||
|
||||
inline bool
|
||||
TooManyArguments(unsigned nargs)
|
||||
{
|
||||
return (nargs >= SNAPSHOT_MAX_NARGS || nargs > js_IonOptions.maxStackArgs);
|
||||
}
|
||||
|
||||
void ForbidCompilation(JSContext *cx, JSScript *script);
|
||||
void ForbidCompilation(JSContext *cx, JSScript *script, ExecutionMode mode);
|
||||
uint32_t UsesBeforeIonRecompile(JSScript *script, jsbytecode *pc);
|
||||
|
@ -266,7 +266,7 @@ IonBuilder::canEnterInlinedFunction(JSFunction *target)
|
||||
}
|
||||
|
||||
bool
|
||||
IonBuilder::canInlineTarget(JSFunction *target, bool constructing)
|
||||
IonBuilder::canInlineTarget(JSFunction *target, CallInfo &callInfo)
|
||||
{
|
||||
if (!target->isInterpreted()) {
|
||||
IonSpew(IonSpew_Inlining, "Cannot inline due to non-interpreted");
|
||||
@ -297,7 +297,7 @@ IonBuilder::canInlineTarget(JSFunction *target, bool constructing)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (constructing && !target->isInterpretedConstructor()) {
|
||||
if (callInfo.constructing() && !target->isInterpretedConstructor()) {
|
||||
IonSpew(IonSpew_Inlining, "Cannot inline because callee is not a constructor");
|
||||
return false;
|
||||
}
|
||||
@ -317,6 +317,18 @@ IonBuilder::canInlineTarget(JSFunction *target, bool constructing)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (TooManyArguments(target->nargs)) {
|
||||
IonSpew(IonSpew_Inlining, "%s:%d Cannot inline too many args",
|
||||
inlineScript->filename(), inlineScript->lineno);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (TooManyArguments(callInfo.argc())) {
|
||||
IonSpew(IonSpew_Inlining, "%s:%d Cannot inline too many args",
|
||||
inlineScript->filename(), inlineScript->lineno);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Allow inlining of recursive calls, but only one level deep.
|
||||
IonBuilder *builder = callerBuilder_;
|
||||
while (builder) {
|
||||
@ -3947,7 +3959,7 @@ IonBuilder::makeInliningDecision(JSFunction *target, CallInfo &callInfo)
|
||||
return true;
|
||||
|
||||
// Determine whether inlining is possible at callee site
|
||||
if (!canInlineTarget(target, callInfo.constructing()))
|
||||
if (!canInlineTarget(target, callInfo))
|
||||
return false;
|
||||
|
||||
// Heuristics!
|
||||
|
@ -231,7 +231,7 @@ class IonBuilder : public MIRGenerator
|
||||
JSFunction *getSingleCallTarget(types::TemporaryTypeSet *calleeTypes);
|
||||
bool getPolyCallTargets(types::TemporaryTypeSet *calleeTypes, bool constructing,
|
||||
ObjectVector &targets, uint32_t maxTargets, bool *gotLambda);
|
||||
bool canInlineTarget(JSFunction *target, bool constructing);
|
||||
bool canInlineTarget(JSFunction *target, CallInfo &callInfo);
|
||||
|
||||
void popCfgStack();
|
||||
DeferredEdge *filterDeadDeferredEdges(DeferredEdge *edge);
|
||||
|
@ -83,15 +83,19 @@ jit::IonSpewNewFunction(MIRGraph *graph, HandleScript func)
|
||||
{
|
||||
if (!OffThreadIonCompilationEnabled(GetIonContext()->runtime)) {
|
||||
ionspewer.beginFunction(graph, func);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!IonSpewEnabled(IonSpew_Logs))
|
||||
return;
|
||||
|
||||
// Ionspewer isn't threads-safe. Therefore logging is disabled for
|
||||
// off-thread spewing. Throw informative message when trying.
|
||||
if (func) {
|
||||
IonSpew(IonSpew_Logs, "Can't log script %s:%d. (Compiled on background thread.)",
|
||||
func->filename(), func->lineno);
|
||||
} else {
|
||||
if (func) {
|
||||
IonSpew(IonSpew_Logs,
|
||||
"Can't log script %s:%d. (Compiled on background thread.)",
|
||||
func->filename(), func->lineno);
|
||||
} else {
|
||||
IonSpew(IonSpew_Logs,
|
||||
"Can't log asm.js compilation. (Compiled on background thread.)");
|
||||
}
|
||||
IonSpew(IonSpew_Logs, "Can't log asm.js compilation. (Compiled on background thread.)");
|
||||
}
|
||||
}
|
||||
|
||||
@ -342,9 +346,6 @@ jit::CheckLogging()
|
||||
EnableChannel(IonSpew_BaselineBailouts);
|
||||
}
|
||||
|
||||
if (LoggingBits != 0)
|
||||
EnableIonDebugLogging();
|
||||
|
||||
IonSpewFile = stderr;
|
||||
}
|
||||
|
||||
|
@ -301,7 +301,10 @@ SnapshotWriter::startSnapshot(uint32_t frameCount, BailoutKind kind, bool resume
|
||||
void
|
||||
SnapshotWriter::startFrame(JSFunction *fun, JSScript *script, jsbytecode *pc, uint32_t exprStack)
|
||||
{
|
||||
JS_ASSERT(CountArgSlots(script, fun) < SNAPSHOT_MAX_NARGS);
|
||||
// Test if we honor the maximum of arguments at all times.
|
||||
// This is a sanity check and not an algorithm limit. So check might be a bit too loose.
|
||||
// +4 to account for scope chain, return value, this value and maybe arguments_object.
|
||||
JS_ASSERT(CountArgSlots(script, fun) < SNAPSHOT_MAX_NARGS + 4);
|
||||
|
||||
uint32_t implicit = StartArgSlot(script, fun);
|
||||
uint32_t formalArgs = CountArgSlots(script, fun);
|
||||
|
@ -3050,39 +3050,50 @@ nsCSSFrameConstructor::ConstructFieldSetFrame(nsFrameConstructorState& aState,
|
||||
nsIContent* const content = aItem.mContent;
|
||||
nsStyleContext* const styleContext = aItem.mStyleContext;
|
||||
|
||||
nsIFrame* newFrame = NS_NewFieldSetFrame(mPresShell, styleContext);
|
||||
nsIFrame* fieldsetFrame = NS_NewFieldSetFrame(mPresShell, styleContext);
|
||||
|
||||
// Initialize it
|
||||
InitAndRestoreFrame(aState, content,
|
||||
aState.GetGeometricParent(aStyleDisplay, aParentFrame),
|
||||
newFrame);
|
||||
fieldsetFrame);
|
||||
|
||||
// Resolve style and initialize the frame
|
||||
nsRefPtr<nsStyleContext> fieldsetContentStyle;
|
||||
fieldsetContentStyle = mPresShell->StyleSet()->
|
||||
ResolveAnonymousBoxStyle(nsCSSAnonBoxes::fieldsetContent, styleContext);
|
||||
|
||||
const nsStyleDisplay* fieldsetContentDisplay = fieldsetContentStyle->StyleDisplay();
|
||||
bool isScrollable = fieldsetContentDisplay->IsScrollableOverflow();
|
||||
nsIFrame* scrollFrame = nullptr;
|
||||
if (isScrollable) {
|
||||
fieldsetContentStyle =
|
||||
BeginBuildingScrollFrame(aState, content, fieldsetContentStyle,
|
||||
fieldsetFrame, nsCSSAnonBoxes::scrolledContent,
|
||||
false, scrollFrame);
|
||||
}
|
||||
|
||||
nsIFrame* blockFrame = NS_NewBlockFrame(mPresShell, fieldsetContentStyle,
|
||||
NS_BLOCK_FLOAT_MGR |
|
||||
NS_BLOCK_MARGIN_ROOT);
|
||||
InitAndRestoreFrame(aState, content, newFrame, blockFrame);
|
||||
InitAndRestoreFrame(aState, content,
|
||||
scrollFrame ? scrollFrame : fieldsetFrame, blockFrame);
|
||||
|
||||
aState.AddChild(newFrame, aFrameItems, content, styleContext, aParentFrame);
|
||||
aState.AddChild(fieldsetFrame, aFrameItems, content, styleContext, aParentFrame);
|
||||
|
||||
// Process children
|
||||
nsFrameConstructorSaveState absoluteSaveState;
|
||||
nsFrameItems childItems;
|
||||
|
||||
newFrame->AddStateBits(NS_FRAME_CAN_HAVE_ABSPOS_CHILDREN);
|
||||
if (newFrame->IsPositioned()) {
|
||||
aState.PushAbsoluteContainingBlock(newFrame, newFrame, absoluteSaveState);
|
||||
blockFrame->AddStateBits(NS_FRAME_CAN_HAVE_ABSPOS_CHILDREN);
|
||||
if (fieldsetFrame->IsPositioned()) {
|
||||
aState.PushAbsoluteContainingBlock(blockFrame, fieldsetFrame, absoluteSaveState);
|
||||
}
|
||||
|
||||
ProcessChildren(aState, content, styleContext, blockFrame, true,
|
||||
childItems, true, aItem.mPendingBinding);
|
||||
|
||||
nsFrameItems fieldsetKids;
|
||||
fieldsetKids.AddChild(blockFrame);
|
||||
fieldsetKids.AddChild(scrollFrame ? scrollFrame : blockFrame);
|
||||
|
||||
for (nsFrameList::Enumerator e(childItems); !e.AtEnd(); e.Next()) {
|
||||
nsIFrame* child = e.get();
|
||||
@ -3094,21 +3105,25 @@ nsCSSFrameConstructor::ConstructFieldSetFrame(nsFrameConstructorState& aState,
|
||||
// GetAdjustedParentFrame() below depends on this frame order.
|
||||
childItems.RemoveFrame(child);
|
||||
// Make sure to reparent the legend so it has the fieldset as the parent.
|
||||
fieldsetKids.InsertFrame(newFrame, nullptr, child);
|
||||
fieldsetKids.InsertFrame(fieldsetFrame, nullptr, child);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (isScrollable) {
|
||||
FinishBuildingScrollFrame(scrollFrame, blockFrame);
|
||||
}
|
||||
|
||||
// Set the inner frame's initial child lists
|
||||
blockFrame->SetInitialChildList(kPrincipalList, childItems);
|
||||
|
||||
// Set the outer frame's initial child list
|
||||
newFrame->SetInitialChildList(kPrincipalList, fieldsetKids);
|
||||
fieldsetFrame->SetInitialChildList(kPrincipalList, fieldsetKids);
|
||||
|
||||
newFrame->AddStateBits(NS_FRAME_MAY_HAVE_GENERATED_CONTENT);
|
||||
fieldsetFrame->AddStateBits(NS_FRAME_MAY_HAVE_GENERATED_CONTENT);
|
||||
|
||||
// Our new frame returned is the outer frame, which is the fieldset frame.
|
||||
return newFrame;
|
||||
return fieldsetFrame;
|
||||
}
|
||||
|
||||
static nsIFrame*
|
||||
@ -3262,6 +3277,17 @@ nsCSSFrameConstructor::FindDataByTag(nsIAtom* aTag,
|
||||
#define COMPLEX_TAG_CREATE(_tag, _func) \
|
||||
{ &nsGkAtoms::_tag, FULL_CTOR_FCDATA(0, _func) }
|
||||
|
||||
static bool
|
||||
IsFrameForFieldSet(nsIFrame* aFrame, nsIAtom* aFrameType)
|
||||
{
|
||||
nsIAtom* pseudo = aFrame->StyleContext()->GetPseudo();
|
||||
if (pseudo == nsCSSAnonBoxes::fieldsetContent ||
|
||||
pseudo == nsCSSAnonBoxes::scrolledContent) {
|
||||
return IsFrameForFieldSet(aFrame->GetParent(), aFrame->GetParent()->GetType());
|
||||
}
|
||||
return aFrameType == nsGkAtoms::fieldSetFrame;
|
||||
}
|
||||
|
||||
/* static */
|
||||
const nsCSSFrameConstructor::FrameConstructionData*
|
||||
nsCSSFrameConstructor::FindHTMLData(Element* aElement,
|
||||
@ -3284,9 +3310,7 @@ nsCSSFrameConstructor::FindHTMLData(Element* aElement,
|
||||
"Unexpected parent for fieldset content anon box");
|
||||
if (aTag == nsGkAtoms::legend &&
|
||||
(!aParentFrame ||
|
||||
(aParentFrame->GetType() != nsGkAtoms::fieldSetFrame &&
|
||||
aParentFrame->StyleContext()->GetPseudo() !=
|
||||
nsCSSAnonBoxes::fieldsetContent) ||
|
||||
!IsFrameForFieldSet(aParentFrame, aParentFrame->GetType()) ||
|
||||
!aElement->GetParent() ||
|
||||
!aElement->GetParent()->IsHTML(nsGkAtoms::fieldset) ||
|
||||
aStyleContext->StyleDisplay()->IsFloatingStyle() ||
|
||||
@ -5919,13 +5943,8 @@ nsCSSFrameConstructor::IsValidSibling(nsIFrame* aSibling,
|
||||
{
|
||||
nsIFrame* parentFrame = aSibling->GetParent();
|
||||
nsIAtom* parentType = nullptr;
|
||||
nsIAtom* grandparentType = nullptr;
|
||||
if (parentFrame) {
|
||||
parentType = parentFrame->GetType();
|
||||
nsIFrame* grandparentFrame = parentFrame->GetParent();
|
||||
if (grandparentFrame) {
|
||||
grandparentType = grandparentFrame->GetType();
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t siblingDisplay = aSibling->GetDisplay();
|
||||
@ -5984,9 +6003,7 @@ nsCSSFrameConstructor::IsValidSibling(nsIFrame* aSibling,
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (nsGkAtoms::fieldSetFrame == parentType ||
|
||||
(nsGkAtoms::fieldSetFrame == grandparentType &&
|
||||
nsGkAtoms::blockFrame == parentType)) {
|
||||
else if (IsFrameForFieldSet(parentFrame, parentType)) {
|
||||
// Legends can be sibling of legends but not of other content in the fieldset
|
||||
nsIAtom* sibType = aSibling->GetContentInsertionFrame()->GetType();
|
||||
bool legendContent = aContent->IsHTML(nsGkAtoms::legend);
|
||||
@ -7083,7 +7100,7 @@ nsCSSFrameConstructor::ContentRangeInserted(nsIContent* aContainer,
|
||||
// fieldsets have multiple insertion points.
|
||||
NS_ASSERTION(isSingleInsert || frameType != nsGkAtoms::fieldSetFrame,
|
||||
"Unexpected parent");
|
||||
if (frameType == nsGkAtoms::fieldSetFrame &&
|
||||
if (IsFrameForFieldSet(parentFrame, frameType) &&
|
||||
aStartChild->Tag() == nsGkAtoms::legend) {
|
||||
// Just reframe the parent, since figuring out whether this
|
||||
// should be the new legend and then handling it is too complex.
|
||||
|
@ -3922,8 +3922,15 @@ nsDisplayTransform::GetDeltaToTransformOrigin(const nsIFrame* aFrame,
|
||||
* a distance, it's already computed for us!
|
||||
*/
|
||||
const nsStyleDisplay* display = aFrame->StyleDisplay();
|
||||
nsRect boundingRect = (aBoundsOverride ? *aBoundsOverride :
|
||||
nsDisplayTransform::GetFrameBoundsForTransform(aFrame));
|
||||
nsRect boundingRect;
|
||||
if (aBoundsOverride) {
|
||||
boundingRect = *aBoundsOverride;
|
||||
} else if (display->mTransformOrigin[0].GetUnit() != eStyleUnit_Coord ||
|
||||
display->mTransformOrigin[1].GetUnit() != eStyleUnit_Coord) {
|
||||
// GetFrameBoundsForTransform is expensive for SVG frames and we don't need
|
||||
// it if the origin is coords (which it is by default for SVG).
|
||||
boundingRect = nsDisplayTransform::GetFrameBoundsForTransform(aFrame);
|
||||
}
|
||||
|
||||
/* Allows us to access named variables by index. */
|
||||
float coords[2];
|
||||
|
@ -2825,7 +2825,8 @@ static int32_t gNoiseIndent = 0;
|
||||
/* static */ nscoord
|
||||
nsLayoutUtils::IntrinsicForContainer(nsRenderingContext *aRenderingContext,
|
||||
nsIFrame *aFrame,
|
||||
IntrinsicWidthType aType)
|
||||
IntrinsicWidthType aType,
|
||||
uint32_t aFlags)
|
||||
{
|
||||
NS_PRECONDITION(aFrame, "null frame");
|
||||
NS_PRECONDITION(aType == MIN_WIDTH || aType == PREF_WIDTH, "bad type");
|
||||
@ -2919,15 +2920,17 @@ nsLayoutUtils::IntrinsicForContainer(nsRenderingContext *aRenderingContext,
|
||||
// fall through
|
||||
}
|
||||
case NS_STYLE_BOX_SIZING_PADDING: {
|
||||
const nsStylePadding* stylePadding = aFrame->StylePadding();
|
||||
nscoord pad;
|
||||
if (GetAbsoluteCoord(stylePadding->mPadding.GetTop(), pad) ||
|
||||
GetPercentHeight(stylePadding->mPadding.GetTop(), aFrame, pad)) {
|
||||
heightTakenByBoxSizing += pad;
|
||||
}
|
||||
if (GetAbsoluteCoord(stylePadding->mPadding.GetBottom(), pad) ||
|
||||
GetPercentHeight(stylePadding->mPadding.GetBottom(), aFrame, pad)) {
|
||||
heightTakenByBoxSizing += pad;
|
||||
if (!(aFlags & IGNORE_PADDING)) {
|
||||
const nsStylePadding* stylePadding = aFrame->StylePadding();
|
||||
nscoord pad;
|
||||
if (GetAbsoluteCoord(stylePadding->mPadding.GetTop(), pad) ||
|
||||
GetPercentHeight(stylePadding->mPadding.GetTop(), aFrame, pad)) {
|
||||
heightTakenByBoxSizing += pad;
|
||||
}
|
||||
if (GetAbsoluteCoord(stylePadding->mPadding.GetBottom(), pad) ||
|
||||
GetPercentHeight(stylePadding->mPadding.GetBottom(), aFrame, pad)) {
|
||||
heightTakenByBoxSizing += pad;
|
||||
}
|
||||
}
|
||||
// fall through
|
||||
}
|
||||
@ -2978,18 +2981,22 @@ nsLayoutUtils::IntrinsicForContainer(nsRenderingContext *aRenderingContext,
|
||||
// percentages do not operate linearly.
|
||||
// Doing this is ok because although percentages aren't handled
|
||||
// linearly, they are handled monotonically.
|
||||
nscoord coordOutsideWidth = offsets.hPadding;
|
||||
float pctOutsideWidth = offsets.hPctPadding;
|
||||
|
||||
nscoord coordOutsideWidth = 0;
|
||||
float pctOutsideWidth = 0;
|
||||
float pctTotal = 0.0f;
|
||||
|
||||
if (boxSizing == NS_STYLE_BOX_SIZING_PADDING) {
|
||||
min += coordOutsideWidth;
|
||||
result = NSCoordSaturatingAdd(result, coordOutsideWidth);
|
||||
pctTotal += pctOutsideWidth;
|
||||
if (!(aFlags & IGNORE_PADDING)) {
|
||||
coordOutsideWidth += offsets.hPadding;
|
||||
pctOutsideWidth += offsets.hPctPadding;
|
||||
|
||||
coordOutsideWidth = 0;
|
||||
pctOutsideWidth = 0.0f;
|
||||
if (boxSizing == NS_STYLE_BOX_SIZING_PADDING) {
|
||||
min += coordOutsideWidth;
|
||||
result = NSCoordSaturatingAdd(result, coordOutsideWidth);
|
||||
pctTotal += pctOutsideWidth;
|
||||
|
||||
coordOutsideWidth = 0;
|
||||
pctOutsideWidth = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
coordOutsideWidth += offsets.hBorder;
|
||||
|
@ -988,9 +988,13 @@ public:
|
||||
* and margin.
|
||||
*/
|
||||
enum IntrinsicWidthType { MIN_WIDTH, PREF_WIDTH };
|
||||
enum {
|
||||
IGNORE_PADDING = 0x01
|
||||
};
|
||||
static nscoord IntrinsicForContainer(nsRenderingContext* aRenderingContext,
|
||||
nsIFrame* aFrame,
|
||||
IntrinsicWidthType aType);
|
||||
IntrinsicWidthType aType,
|
||||
uint32_t aFlags = 0);
|
||||
|
||||
/*
|
||||
* Convert nsStyleCoord to nscoord when percentages depend on the
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "nsStyleConsts.h"
|
||||
#include "nsDisplayList.h"
|
||||
#include "nsRenderingContext.h"
|
||||
#include "nsIScrollableFrame.h"
|
||||
#include "mozilla/Likely.h"
|
||||
|
||||
using namespace mozilla;
|
||||
@ -78,6 +79,10 @@ public:
|
||||
return nsContainerFrame::IsFrameOfType(aFlags &
|
||||
~nsIFrame::eCanContainOverflowContainers);
|
||||
}
|
||||
virtual nsIScrollableFrame* GetScrollTargetFrame() MOZ_OVERRIDE
|
||||
{
|
||||
return do_QueryFrame(GetInner());
|
||||
}
|
||||
|
||||
#ifdef ACCESSIBILITY
|
||||
virtual mozilla::a11y::AccType AccessibleType() MOZ_OVERRIDE;
|
||||
@ -356,10 +361,14 @@ nsFieldSetFrame::GetIntrinsicWidth(nsRenderingContext* aRenderingContext,
|
||||
}
|
||||
|
||||
if (nsIFrame* inner = GetInner()) {
|
||||
// Ignore padding on the inner, since the padding will be applied to the
|
||||
// outer instead, and the padding computed for the inner is wrong
|
||||
// for percentage padding.
|
||||
contentWidth =
|
||||
nsLayoutUtils::IntrinsicForContainer(aRenderingContext, inner, aType);
|
||||
nsLayoutUtils::IntrinsicForContainer(aRenderingContext, inner, aType,
|
||||
nsLayoutUtils::IGNORE_PADDING);
|
||||
}
|
||||
|
||||
|
||||
return std::max(legendWidth, contentWidth);
|
||||
}
|
||||
|
||||
@ -444,7 +453,10 @@ nsFieldSetFrame::Reflow(nsPresContext* aPresContext,
|
||||
|
||||
// We don't allow fieldsets to break vertically. If we did, we'd
|
||||
// need logic here to push and pull overflow frames.
|
||||
nsSize availSize(aReflowState.ComputedWidth(), NS_UNCONSTRAINEDSIZE);
|
||||
// Since we're not applying our padding in this frame, we need to add it here
|
||||
// to compute the available width for our children.
|
||||
nsSize availSize(aReflowState.ComputedWidth() + aReflowState.mComputedPadding.LeftRight(),
|
||||
NS_UNCONSTRAINEDSIZE);
|
||||
NS_ASSERTION(!inner ||
|
||||
nsLayoutUtils::IntrinsicForContainer(aReflowState.rendContext,
|
||||
inner,
|
||||
@ -459,8 +471,7 @@ nsFieldSetFrame::Reflow(nsPresContext* aPresContext,
|
||||
"Bogus availSize.width; should be bigger");
|
||||
|
||||
// get our border and padding
|
||||
const nsMargin &borderPadding = aReflowState.mComputedBorderPadding;
|
||||
nsMargin border = borderPadding - aReflowState.mComputedPadding;
|
||||
nsMargin border = aReflowState.mComputedBorderPadding - aReflowState.mComputedPadding;
|
||||
|
||||
// Figure out how big the legend is if there is one.
|
||||
// get the legend's margin
|
||||
@ -481,7 +492,7 @@ nsFieldSetFrame::Reflow(nsPresContext* aPresContext,
|
||||
legendMargin = legend->GetUsedMargin();
|
||||
mLegendRect.width = legendDesiredSize.width + legendMargin.left + legendMargin.right;
|
||||
mLegendRect.height = legendDesiredSize.height + legendMargin.top + legendMargin.bottom;
|
||||
mLegendRect.x = borderPadding.left;
|
||||
mLegendRect.x = 0;
|
||||
mLegendRect.y = 0;
|
||||
|
||||
nscoord oldSpace = mLegendSpace;
|
||||
@ -513,16 +524,22 @@ nsFieldSetFrame::Reflow(nsPresContext* aPresContext,
|
||||
// reflow the content frame only if needed
|
||||
if (reflowInner) {
|
||||
nsHTMLReflowState kidReflowState(aPresContext, aReflowState, inner,
|
||||
availSize);
|
||||
availSize, -1, -1, nsHTMLReflowState::CALLER_WILL_INIT);
|
||||
// Override computed padding, in case it's percentage padding
|
||||
kidReflowState.Init(aPresContext, -1, -1, nullptr,
|
||||
&aReflowState.mComputedPadding);
|
||||
// Our child is "height:100%" but we actually want its height to be reduced
|
||||
// by the amount of content-height the legend is eating up, unless our
|
||||
// height is unconstrained (in which case the child's will be too).
|
||||
if (aReflowState.ComputedHeight() != NS_UNCONSTRAINEDSIZE) {
|
||||
kidReflowState.SetComputedHeight(std::max(0, aReflowState.ComputedHeight() - mLegendSpace));
|
||||
kidReflowState.SetComputedHeight(
|
||||
std::max(0, aReflowState.ComputedHeight() - mLegendSpace));
|
||||
}
|
||||
|
||||
kidReflowState.mComputedMinHeight =
|
||||
std::max(0, aReflowState.mComputedMinHeight - mLegendSpace);
|
||||
if (aReflowState.mComputedMinHeight > 0) {
|
||||
kidReflowState.mComputedMinHeight =
|
||||
std::max(0, aReflowState.mComputedMinHeight - mLegendSpace);
|
||||
}
|
||||
|
||||
if (aReflowState.mComputedMaxHeight != NS_UNCONSTRAINEDSIZE) {
|
||||
kidReflowState.mComputedMaxHeight =
|
||||
@ -533,7 +550,7 @@ nsFieldSetFrame::Reflow(nsPresContext* aPresContext,
|
||||
// Reflow the frame
|
||||
NS_ASSERTION(kidReflowState.mComputedMargin == nsMargin(0,0,0,0),
|
||||
"Margins on anonymous fieldset child not supported!");
|
||||
nsPoint pt(borderPadding.left, borderPadding.top + mLegendSpace);
|
||||
nsPoint pt(border.left, border.top + mLegendSpace);
|
||||
ReflowChild(inner, aPresContext, kidDesiredSize, kidReflowState,
|
||||
pt.x, pt.y, 0, aStatus);
|
||||
|
||||
@ -542,37 +559,45 @@ nsFieldSetFrame::Reflow(nsPresContext* aPresContext,
|
||||
NS_FRAME_TRACE_REFLOW_OUT("FieldSet::Reflow", aStatus);
|
||||
}
|
||||
|
||||
nsRect contentRect(0,0,0,0);
|
||||
nsRect contentRect;
|
||||
if (inner) {
|
||||
// We don't support margins on inner, so our "content rect" is just
|
||||
// its rect.
|
||||
// We don't support margins on inner, so our content rect is just the
|
||||
// inner's border-box.
|
||||
contentRect = inner->GetRect();
|
||||
}
|
||||
|
||||
// use the computed width if the inner content does not fill it
|
||||
if (aReflowState.ComputedWidth() > contentRect.width) {
|
||||
contentRect.width = aReflowState.ComputedWidth();
|
||||
// Our content rect must fill up the available width
|
||||
if (availSize.width > contentRect.width) {
|
||||
contentRect.width = availSize.width;
|
||||
}
|
||||
|
||||
if (legend) {
|
||||
// if the content rect is larger then the legend we can align the legend
|
||||
if (contentRect.width > mLegendRect.width) {
|
||||
// the legend is postioned horizontally within the inner's content rect
|
||||
// (so that padding on the fieldset affects the legend position).
|
||||
nsRect innerContentRect = contentRect;
|
||||
innerContentRect.Deflate(aReflowState.mComputedPadding);
|
||||
// if the inner content rect is larger than the legend, we can align the legend
|
||||
if (innerContentRect.width > mLegendRect.width) {
|
||||
int32_t align = static_cast<nsLegendFrame*>
|
||||
(legend->GetContentInsertionFrame())->GetAlign();
|
||||
|
||||
switch(align) {
|
||||
switch (align) {
|
||||
case NS_STYLE_TEXT_ALIGN_RIGHT:
|
||||
mLegendRect.x = contentRect.width - mLegendRect.width + borderPadding.left;
|
||||
mLegendRect.x = innerContentRect.XMost() - mLegendRect.width;
|
||||
break;
|
||||
case NS_STYLE_TEXT_ALIGN_CENTER:
|
||||
// Note: rounding removed; there doesn't seem to be any need
|
||||
mLegendRect.x = contentRect.width / 2 - mLegendRect.width / 2 + borderPadding.left;
|
||||
mLegendRect.x = innerContentRect.width / 2 - mLegendRect.width / 2 + innerContentRect.x;
|
||||
break;
|
||||
default:
|
||||
mLegendRect.x = innerContentRect.x;
|
||||
break;
|
||||
}
|
||||
|
||||
} else {
|
||||
// otherwise make place for the legend
|
||||
contentRect.width = mLegendRect.width;
|
||||
mLegendRect.x = innerContentRect.x;
|
||||
innerContentRect.width = mLegendRect.width;
|
||||
contentRect.width = mLegendRect.width + aReflowState.mComputedPadding.LeftRight();
|
||||
}
|
||||
// place the legend
|
||||
nsRect actualLegendRect(mLegendRect);
|
||||
@ -594,16 +619,16 @@ nsFieldSetFrame::Reflow(nsPresContext* aPresContext,
|
||||
// Return our size and our result
|
||||
if (aReflowState.ComputedHeight() == NS_INTRINSICSIZE) {
|
||||
aDesiredSize.height = mLegendSpace +
|
||||
borderPadding.TopBottom() +
|
||||
contentRect.height;
|
||||
border.TopBottom() +
|
||||
(inner ? inner->GetRect().height : 0);
|
||||
} else {
|
||||
nscoord min = borderPadding.TopBottom() + mLegendRect.height;
|
||||
nscoord min = border.TopBottom() + mLegendRect.height;
|
||||
aDesiredSize.height =
|
||||
aReflowState.ComputedHeight() + borderPadding.TopBottom();
|
||||
aReflowState.ComputedHeight() + aReflowState.mComputedBorderPadding.TopBottom();
|
||||
if (aDesiredSize.height < min)
|
||||
aDesiredSize.height = min;
|
||||
}
|
||||
aDesiredSize.width = contentRect.width + borderPadding.LeftRight();
|
||||
aDesiredSize.width = contentRect.width + border.LeftRight();
|
||||
aDesiredSize.SetOverflowAreasToDesiredBounds();
|
||||
if (legend)
|
||||
ConsiderChildOverflow(aDesiredSize.mOverflowAreas, legend);
|
||||
@ -681,9 +706,6 @@ nsFieldSetFrame::ReparentFrameList(const nsFrameList& aFrameList)
|
||||
nscoord
|
||||
nsFieldSetFrame::GetBaseline() const
|
||||
{
|
||||
// We know inner is a block, so calling GetBaseline() on it will do
|
||||
// the right thing (that being to return the baseline of the last line).
|
||||
nsIFrame* inner = GetInner();
|
||||
NS_ASSERTION(nsLayoutUtils::GetAsBlock(inner), "Unexpected inner");
|
||||
return inner->GetPosition().y + inner->GetBaseline();
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!DOCTYPE html>
|
||||
<html style="height: 100%">
|
||||
<html class="reftest-wait" style="height: 100%">
|
||||
<head>
|
||||
<script>
|
||||
function doIt() {
|
||||
@ -8,10 +8,12 @@
|
||||
"position: absolute; left: 0; right: 0; top: 0; " +
|
||||
"bottom: 0; background: green");
|
||||
document.getElementById("x").appendChild(d);
|
||||
document.documentElement.removeAttribute("class");
|
||||
}
|
||||
window.addEventListener("MozReftestInvalidate", doIt);
|
||||
</script>
|
||||
</head>
|
||||
<body style="height: 100%" onload="doIt()">
|
||||
<body style="height: 100%">
|
||||
<fieldset id="x" style="position: relative; display: table; width: 50%;
|
||||
height: 50%; top: 25%; left: 25%">
|
||||
</fieldset>
|
||||
|
@ -0,0 +1,24 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
fieldset {
|
||||
background:pink;
|
||||
overflow:hidden;
|
||||
height:100px;
|
||||
}
|
||||
legend::after { content:"legend"; }
|
||||
p {
|
||||
background:lime;
|
||||
height:20px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<fieldset id="f1"><legend></legend><p></p></fieldset>
|
||||
<br>
|
||||
<fieldset id="f2"><legend></legend><p></p></fieldset>
|
||||
<br>
|
||||
<fieldset id="f3"><legend></legend></fieldset>
|
||||
</body>
|
||||
</html>
|
33
layout/reftests/forms/fieldset/dynamic-legend-scroll-1.html
Normal file
33
layout/reftests/forms/fieldset/dynamic-legend-scroll-1.html
Normal file
@ -0,0 +1,33 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html class="reftest-wait">
|
||||
<head>
|
||||
<style>
|
||||
fieldset {
|
||||
background:pink;
|
||||
overflow:hidden;
|
||||
height:100px;
|
||||
}
|
||||
legend::after { content:"legend"; }
|
||||
p {
|
||||
background:lime;
|
||||
height:20px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<fieldset id="f1"><p></p></fieldset>
|
||||
<br>
|
||||
<fieldset id="f2"><p></p></fieldset>
|
||||
<br>
|
||||
<fieldset id="f3"></fieldset>
|
||||
<script>
|
||||
function doTest() {
|
||||
f1.appendChild(document.createElement('legend'));
|
||||
f2.insertBefore(document.createElement('legend'), f2.firstChild);
|
||||
f3.appendChild(document.createElement('legend'));
|
||||
document.documentElement.removeAttribute("class");
|
||||
}
|
||||
window.addEventListener("MozReftestInvalidate", doTest);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
21
layout/reftests/forms/fieldset/fieldset-hidden-1-ref.html
Normal file
21
layout/reftests/forms/fieldset/fieldset-hidden-1-ref.html
Normal file
@ -0,0 +1,21 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<body>
|
||||
<fieldset style="width:200px; height:200px; padding:0">
|
||||
<legend>Legend</legend>
|
||||
<div style="overflow:hidden; height:100%;">
|
||||
<p>Hello Kitty
|
||||
<p>Hello Kitty
|
||||
<p>Hello Kitty
|
||||
<p>Hello Kitty
|
||||
<p>Hello Kitty
|
||||
<p>Hello Kitty
|
||||
<p>Hello Kitty
|
||||
<p>Hello Kitty
|
||||
<p>Hello Kitty
|
||||
<p>Hello Kitty
|
||||
<p>Hello Kitty
|
||||
</div>
|
||||
</fieldset>
|
||||
</body>
|
||||
</html>
|
19
layout/reftests/forms/fieldset/fieldset-hidden-1.html
Normal file
19
layout/reftests/forms/fieldset/fieldset-hidden-1.html
Normal file
@ -0,0 +1,19 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<body>
|
||||
<fieldset style="overflow:hidden; width:200px; height:200px; padding:0">
|
||||
<legend>Legend</legend>
|
||||
<p>Hello Kitty
|
||||
<p>Hello Kitty
|
||||
<p>Hello Kitty
|
||||
<p>Hello Kitty
|
||||
<p>Hello Kitty
|
||||
<p>Hello Kitty
|
||||
<p>Hello Kitty
|
||||
<p>Hello Kitty
|
||||
<p>Hello Kitty
|
||||
<p>Hello Kitty
|
||||
<p>Hello Kitty
|
||||
</fieldset>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,8 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<body>
|
||||
<fieldset style="width:0; padding:0;">
|
||||
<div style="width:400px; height:200px;"></div>
|
||||
</fieldset>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,8 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<body>
|
||||
<fieldset style="padding:50px; float:left;">
|
||||
<div style="width:300px; height:100px;"></div>
|
||||
</fieldset>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,52 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html><head>
|
||||
<meta charset="utf-8">
|
||||
<title>Testcase for bug 261037</title>
|
||||
<style type="text/css">
|
||||
fieldset, div {
|
||||
background:pink;
|
||||
overflow:auto;
|
||||
height:100px;
|
||||
margin:0; padding:0; border:0;
|
||||
}
|
||||
p {
|
||||
background:blue;
|
||||
height:100px;
|
||||
margin:0; padding:0;
|
||||
}
|
||||
.overflow {
|
||||
height:110px;
|
||||
}
|
||||
.abs {
|
||||
position:absolute;
|
||||
width:100px;
|
||||
top:250px;
|
||||
}
|
||||
p.abs {
|
||||
top:0;left:0;
|
||||
}
|
||||
.b { border:10px solid black; }
|
||||
.p { padding: 7px 0; }
|
||||
.p p { height:114px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div><p></p></div>
|
||||
<br>
|
||||
<div><p class="overflow"></p></div>
|
||||
<br>
|
||||
<div class="abs"><p class="abs"></p></div>
|
||||
<br>
|
||||
<div class="abs" style="left:120px"><p class="abs overflow"></p></div>
|
||||
<br>
|
||||
<div class="abs b" style="left:240px"><p class="abs"></p></div>
|
||||
<br>
|
||||
<div class="abs b" style="left:370px"><p class="abs overflow"></p></div>
|
||||
<br>
|
||||
<div class="abs b p" style="left:510px"><p class="abs"></p></div>
|
||||
<br>
|
||||
<div class="abs b p" style="left:640px"><p class="abs overflow"></p></div>
|
||||
|
||||
</body>
|
||||
</html>
|
52
layout/reftests/forms/fieldset/fieldset-overflow-auto-1.html
Normal file
52
layout/reftests/forms/fieldset/fieldset-overflow-auto-1.html
Normal file
@ -0,0 +1,52 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html><head>
|
||||
<meta charset="utf-8">
|
||||
<title>Testcase for bug 261037</title>
|
||||
<style type="text/css">
|
||||
fieldset, div {
|
||||
background:pink;
|
||||
overflow:auto;
|
||||
height:100px;
|
||||
margin:0; padding:0; border:0;
|
||||
}
|
||||
p {
|
||||
background:blue;
|
||||
height:100px;
|
||||
margin:0; padding:0;
|
||||
}
|
||||
.overflow {
|
||||
height:110px;
|
||||
}
|
||||
.abs {
|
||||
position:absolute;
|
||||
width:100px;
|
||||
top:250px;
|
||||
}
|
||||
p.abs {
|
||||
top:0;left:0;
|
||||
}
|
||||
.b { border:10px solid black; }
|
||||
.p { padding: 7px 0; }
|
||||
.p p { height:114px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<fieldset><p></p></fieldset>
|
||||
<br>
|
||||
<fieldset><p class="overflow"></p></fieldset>
|
||||
<br>
|
||||
<fieldset class="abs"><p class="abs"></p></fieldset>
|
||||
<br>
|
||||
<fieldset class="abs" style="left:120px"><p class="abs overflow"></p></fieldset>
|
||||
<br>
|
||||
<fieldset class="abs b" style="left:240px"><p class="abs"></p></fieldset>
|
||||
<br>
|
||||
<fieldset class="abs b" style="left:370px"><p class="abs overflow"></p></fieldset>
|
||||
<br>
|
||||
<fieldset class="abs b p" style="left:510px"><p class="abs"></p></fieldset>
|
||||
<br>
|
||||
<fieldset class="abs b p" style="left:640px"><p class="abs overflow"></p></fieldset>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,19 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<body>
|
||||
<div style="width:700px; border:2px solid green; overflow:hidden">
|
||||
<fieldset style="padding:140px; width:400px;">
|
||||
<legend>Legend</legend>
|
||||
TextTextTextTextTextText
|
||||
</fieldset>
|
||||
<fieldset style="padding:140px; display:inline;">
|
||||
<legend>Legend</legend>
|
||||
TextTextTextTextTextText
|
||||
</fieldset>
|
||||
<fieldset style="padding:140px; float:left;">
|
||||
<legend>Legend</legend>
|
||||
TextTextTextTextTextText
|
||||
</fieldset>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,19 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<body>
|
||||
<div style="width:700px; border:2px solid green; overflow:hidden">
|
||||
<fieldset style="padding:20%; width:400px;">
|
||||
<legend>Legend</legend>
|
||||
TextTextTextTextTextText
|
||||
</fieldset>
|
||||
<fieldset style="padding:20%; display:inline;">
|
||||
<legend>Legend</legend>
|
||||
TextTextTextTextTextText
|
||||
</fieldset>
|
||||
<fieldset style="padding:20%; float:left;">
|
||||
<legend>Legend</legend>
|
||||
TextTextTextTextTextText
|
||||
</fieldset>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,9 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<body>
|
||||
<fieldset style="width:200px; height:200px; padding:0">
|
||||
<legend>Legend</legend>
|
||||
<div style="overflow:scroll; height:100%">
|
||||
</fieldset>
|
||||
</body>
|
||||
</html>
|
8
layout/reftests/forms/fieldset/fieldset-scroll-1.html
Normal file
8
layout/reftests/forms/fieldset/fieldset-scroll-1.html
Normal file
@ -0,0 +1,8 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<body>
|
||||
<fieldset style="overflow:scroll; width:200px; height:200px; padding:0">
|
||||
<legend>Legend</legend>
|
||||
</fieldset>
|
||||
</body>
|
||||
</html>
|
24
layout/reftests/forms/fieldset/fieldset-scrolled-1-ref.html
Normal file
24
layout/reftests/forms/fieldset/fieldset-scrolled-1-ref.html
Normal file
@ -0,0 +1,24 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<body>
|
||||
<fieldset style="width:200px; height:200px; padding:0">
|
||||
<legend style="overflow:hidden">Legend</legend>
|
||||
<div id="d" style="overflow:hidden; height:100%;">
|
||||
<p>Hello Kitty
|
||||
<p>Hello Kitty
|
||||
<p>Hello Kitty
|
||||
<p>Hello Kitty
|
||||
<p>Hello Kitty
|
||||
<p>Hello Kitty
|
||||
<p>Hello Kitty
|
||||
<p>Hello Kitty
|
||||
<p>Hello Kitty
|
||||
<p>Hello Kitty
|
||||
<p>Hello Kitty
|
||||
</div>
|
||||
</fieldset>
|
||||
<script>
|
||||
d.scrollTop = 20;
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
27
layout/reftests/forms/fieldset/fieldset-scrolled-1.html
Normal file
27
layout/reftests/forms/fieldset/fieldset-scrolled-1.html
Normal file
@ -0,0 +1,27 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html class="reftest-wait">
|
||||
<body>
|
||||
<fieldset id="f" style="overflow:hidden; width:200px; height:200px; padding:0">
|
||||
<legend style="overflow:hidden">Legend</legend>
|
||||
<p>Hello Kitty
|
||||
<p>Hello Kitty
|
||||
<p>Hello Kitty
|
||||
<p>Hello Kitty
|
||||
<p>Hello Kitty
|
||||
<p>Hello Kitty
|
||||
<p>Hello Kitty
|
||||
<p>Hello Kitty
|
||||
<p>Hello Kitty
|
||||
<p>Hello Kitty
|
||||
<p>Hello Kitty
|
||||
</fieldset>
|
||||
<script>
|
||||
f.scrollTop = 0;
|
||||
function doTest() {
|
||||
f.scrollTop = 20;
|
||||
document.documentElement.removeAttribute("class");
|
||||
}
|
||||
window.addEventListener("MozReftestInvalidate", doTest);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,11 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<body>
|
||||
<fieldset style="position:relative; overflow:hidden; width:500px; height:500px;">
|
||||
<legend>Legend</legend>
|
||||
<div style="height:1000px;">
|
||||
<div style="position:absolute; left:20px; top:20px; background:yellow;">Abs-pos</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</body>
|
||||
</html>
|
14
layout/reftests/forms/fieldset/positioned-container-1.html
Normal file
14
layout/reftests/forms/fieldset/positioned-container-1.html
Normal file
@ -0,0 +1,14 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<body>
|
||||
<fieldset id="f" style="position:relative; overflow:hidden; width:500px; height:500px;">
|
||||
<legend>Legend</legend>
|
||||
<div style="height:1000px;">
|
||||
<div style="position:absolute; left:20px; top:50px; background:yellow;">Abs-pos</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<script>
|
||||
f.scrollTop = 30;
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
8
layout/reftests/forms/fieldset/reftest.list
Normal file
8
layout/reftests/forms/fieldset/reftest.list
Normal file
@ -0,0 +1,8 @@
|
||||
== dynamic-legend-scroll-1.html dynamic-legend-scroll-1-ref.html
|
||||
== fieldset-hidden-1.html fieldset-hidden-1-ref.html
|
||||
== fieldset-intrinsic-width-1.html fieldset-intrinsic-width-1-ref.html
|
||||
== fieldset-percentage-padding-1.html fieldset-percentage-padding-1-ref.html
|
||||
== fieldset-scroll-1.html fieldset-scroll-1-ref.html
|
||||
== fieldset-scrolled-1.html fieldset-scrolled-1-ref.html
|
||||
== fieldset-overflow-auto-1.html fieldset-overflow-auto-1-ref.html
|
||||
== positioned-container-1.html positioned-container-1-ref.html
|
@ -6,6 +6,9 @@ include button/reftest.list
|
||||
# legend element
|
||||
include legend/reftest.list
|
||||
|
||||
# fieldset element
|
||||
include fieldset/reftest.list
|
||||
|
||||
# placeholder
|
||||
include placeholder/reftest.list
|
||||
|
||||
|
@ -20,3 +20,4 @@ pref(gfx.font_rendering.opentype_svg.enabled,true) fuzzy-if(cocoaWidget,255,1
|
||||
pref(gfx.font_rendering.opentype_svg.enabled,true) fails == svg-glyph-mask.svg svg-glyph-mask-ref.svg # bug 872483
|
||||
pref(gfx.font_rendering.opentype_svg.enabled,true) == svg-glyph-paint-server.svg svg-glyph-paint-server-ref.svg
|
||||
pref(gfx.font_rendering.opentype_svg.enabled,true) == svg-glyph-transform.svg svg-glyph-transform-ref.svg
|
||||
pref(gfx.font_rendering.opentype_svg.enabled,true) == svg-glyph-extents.html svg-glyph-extents-ref.html
|
||||
|
@ -36,3 +36,26 @@ sfnt2woff svg.ttf
|
||||
|
||||
[1] https://github.com/edf825/SVG-OpenType-Utils
|
||||
[2] http://people.mozilla.com/~jkew/woff/
|
||||
|
||||
|
||||
|
||||
Additional test fonts:
|
||||
======================
|
||||
|
||||
svg-glyph-extents.otf
|
||||
---------------------
|
||||
|
||||
This is a copy of Fira Sans with a simple SVG table added using the tool from
|
||||
https://github.com/rocallahan/svg-opentype-workshop. The SVG table defines four
|
||||
glyphs, corresponding to 'A' through 'D':
|
||||
|
||||
<svg xmlns='http://www.w3.org/2000/svg'>
|
||||
<rect id='glyph36' x='0' y='-1000' width='1000' height='1500' fill='red'/>
|
||||
<rect id='glyph37' x='0' y='-1000' width='1000' height='1500' fill='green' transform='scale(2)'/>
|
||||
<g id='glyph38'>
|
||||
<rect x='0' y='-1000' width='1000' height='1500' fill='red'/>
|
||||
</g>
|
||||
<g id='glyph39'>
|
||||
<rect x='0' y='-1000' width='1000' height='1500' fill='green' transform='scale(2)'/>
|
||||
</g>
|
||||
</svg>
|
||||
|
BIN
layout/reftests/text-svgglyphs/resources/svg-glyph-extents.otf
Normal file
BIN
layout/reftests/text-svgglyphs/resources/svg-glyph-extents.otf
Normal file
Binary file not shown.
27
layout/reftests/text-svgglyphs/svg-glyph-extents-ref.html
Normal file
27
layout/reftests/text-svgglyphs/svg-glyph-extents-ref.html
Normal file
@ -0,0 +1,27 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<meta charset="utf-8">
|
||||
<head>
|
||||
<style type="text/css">
|
||||
@font-face {
|
||||
font-family: foo;
|
||||
src: url(resources/svg-glyph-extents.otf);
|
||||
}
|
||||
body {
|
||||
font-family: foo;
|
||||
font-size: 10px;
|
||||
}
|
||||
div {
|
||||
display: inline-block;
|
||||
height: 100px;
|
||||
width: 100px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div>A</div>
|
||||
<div>B</div>
|
||||
<div>C</div>
|
||||
<div>D</div>
|
||||
</body>
|
||||
</html>
|
46
layout/reftests/text-svgglyphs/svg-glyph-extents.html
Normal file
46
layout/reftests/text-svgglyphs/svg-glyph-extents.html
Normal file
@ -0,0 +1,46 @@
|
||||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<meta charset="utf-8">
|
||||
<head>
|
||||
<style type="text/css">
|
||||
@font-face {
|
||||
font-family: foo;
|
||||
src: url(resources/svg-glyph-extents.otf);
|
||||
}
|
||||
body {
|
||||
font-family: foo;
|
||||
font-size: 10px;
|
||||
}
|
||||
@keyframes test {
|
||||
from {
|
||||
font-size: 100px;
|
||||
}
|
||||
to {
|
||||
font-size: 10px;
|
||||
}
|
||||
}
|
||||
div {
|
||||
display: inline-block;
|
||||
height: 100px;
|
||||
width: 100px;
|
||||
animation-duration: 3s;
|
||||
animation-name: test;
|
||||
}
|
||||
</style>
|
||||
<script type="text/javascript">
|
||||
function setup() {
|
||||
var e = document.getElementById("watchme");
|
||||
e.addEventListener("animationend", listener, false);
|
||||
}
|
||||
function listener() {
|
||||
document.documentElement.className = "";
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body onload="setup()">
|
||||
<div>A</div>
|
||||
<div id="watchme">B</div>
|
||||
<div>C</div>
|
||||
<div>D</div>
|
||||
</body>
|
||||
</html>
|
@ -14,6 +14,9 @@
|
||||
display: block;
|
||||
unicode-bidi: inherit;
|
||||
text-overflow: inherit;
|
||||
overflow: inherit;
|
||||
padding: inherit;
|
||||
position: inherit;
|
||||
height: 100%; /* Need this so percentage heights of kids work right */
|
||||
}
|
||||
|
||||
|
@ -1862,7 +1862,15 @@ nsSVGUtils::GetSVGGlyphExtents(Element* aElement,
|
||||
if (!svgFrame) {
|
||||
return false;
|
||||
}
|
||||
*aResult = svgFrame->GetBBoxContribution(aSVGToAppSpace,
|
||||
|
||||
gfxMatrix transform(aSVGToAppSpace);
|
||||
nsIContent* content = frame->GetContent();
|
||||
if (content->IsSVG()) {
|
||||
transform = static_cast<nsSVGElement*>(content)->
|
||||
PrependLocalTransformsTo(aSVGToAppSpace);
|
||||
}
|
||||
|
||||
*aResult = svgFrame->GetBBoxContribution(transform,
|
||||
nsSVGUtils::eBBoxIncludeFill | nsSVGUtils::eBBoxIncludeFillGeometry |
|
||||
nsSVGUtils::eBBoxIncludeStroke | nsSVGUtils::eBBoxIncludeStrokeGeometry |
|
||||
nsSVGUtils::eBBoxIncludeMarkers);
|
||||
|
@ -62,6 +62,7 @@ div.non-verbose pre.entries {
|
||||
h1 {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
display: inline; /* allow subsequent text to the right of the heading */
|
||||
}
|
||||
|
||||
h2 {
|
||||
@ -69,6 +70,16 @@ h2 {
|
||||
padding-left: .1em;
|
||||
}
|
||||
|
||||
h3 {
|
||||
display: inline; /* allow subsequent text to the right of the heading */
|
||||
}
|
||||
|
||||
a.upDownArrow {
|
||||
font-size: 130%;
|
||||
text-decoration: none;
|
||||
-moz-user-select: none; /* no need to include this when cutting+pasting */
|
||||
}
|
||||
|
||||
.accuracyWarning {
|
||||
color: #d22;
|
||||
}
|
||||
|
@ -885,7 +885,7 @@ function appendAboutMemoryMain(aProcessReports, aHasMozMallocUsableSize)
|
||||
let process = processes[i];
|
||||
let section = appendElement(gMain, 'div', 'section');
|
||||
|
||||
appendProcessAboutMemoryElements(section, process,
|
||||
appendProcessAboutMemoryElements(section, i, process,
|
||||
pcollsByProcess[process]._trees,
|
||||
pcollsByProcess[process]._degenerates,
|
||||
pcollsByProcess[process]._heapTotal,
|
||||
@ -1308,6 +1308,8 @@ function appendWarningElements(aP, aHasKnownHeapAllocated,
|
||||
*
|
||||
* @param aP
|
||||
* The parent DOM node.
|
||||
* @param aN
|
||||
* The number of the process, starting at 0.
|
||||
* @param aProcess
|
||||
* The name of the process.
|
||||
* @param aTrees
|
||||
@ -1318,10 +1320,34 @@ function appendWarningElements(aP, aHasKnownHeapAllocated,
|
||||
* Boolean indicating if moz_malloc_usable_size works.
|
||||
* @return The generated text.
|
||||
*/
|
||||
function appendProcessAboutMemoryElements(aP, aProcess, aTrees, aDegenerates,
|
||||
aHeapTotal, aHasMozMallocUsableSize)
|
||||
function appendProcessAboutMemoryElements(aP, aN, aProcess, aTrees,
|
||||
aDegenerates, aHeapTotal,
|
||||
aHasMozMallocUsableSize)
|
||||
{
|
||||
appendElementWithText(aP, "h1", "", aProcess + "\n\n");
|
||||
const kUpwardsArrow = "\u2191",
|
||||
kDownwardsArrow = "\u2193";
|
||||
|
||||
let appendLink = function(aHere, aThere, aArrow) {
|
||||
let link = appendElementWithText(aP, "a", "upDownArrow", aArrow);
|
||||
link.href = "#" + aThere + aN;
|
||||
link.id = aHere + aN;
|
||||
link.title = "Go to the " + aThere + " of " + aProcess;
|
||||
link.style = "text-decoration: none";
|
||||
|
||||
// This jumps to the anchor without the page location getting the anchor
|
||||
// name tacked onto its end, which is what happens with a vanilla link.
|
||||
link.addEventListener("click", function(event) {
|
||||
document.documentElement.scrollTop =
|
||||
document.querySelector(event.target.href).offsetTop;
|
||||
event.preventDefault();
|
||||
}, false);
|
||||
|
||||
// This gives nice spacing when we copy and paste.
|
||||
appendElementWithText(aP, "span", "", "\n");
|
||||
}
|
||||
|
||||
appendElementWithText(aP, "h1", "", aProcess);
|
||||
appendLink("start", "end", kDownwardsArrow);
|
||||
|
||||
// We'll fill this in later.
|
||||
let warningsDiv = appendElement(aP, "div", "accuracyWarning");
|
||||
@ -1347,7 +1373,7 @@ function appendProcessAboutMemoryElements(aP, aProcess, aTrees, aDegenerates,
|
||||
appendTreeElements(pre, t, aProcess, "");
|
||||
delete aTrees[treeName];
|
||||
}
|
||||
appendTextNode(aP, "\n"); // gives nice spacing when we cut and paste
|
||||
appendTextNode(aP, "\n"); // gives nice spacing when we copy and paste
|
||||
}
|
||||
|
||||
// Fill in and sort all the non-degenerate other trees.
|
||||
@ -1388,13 +1414,16 @@ function appendProcessAboutMemoryElements(aP, aProcess, aTrees, aDegenerates,
|
||||
let padText = pad("", maxStringLength - t.toString().length, ' ');
|
||||
appendTreeElements(pre, t, aProcess, padText);
|
||||
}
|
||||
appendTextNode(aP, "\n"); // gives nice spacing when we cut and paste
|
||||
appendTextNode(aP, "\n"); // gives nice spacing when we copy and paste
|
||||
|
||||
// Add any warnings about inaccuracies due to platform limitations.
|
||||
// These must be computed after generating all the text. The newlines give
|
||||
// nice spacing if we cut+paste into a text buffer.
|
||||
// nice spacing if we copy+paste into a text buffer.
|
||||
appendWarningElements(warningsDiv, hasKnownHeapAllocated,
|
||||
aHasMozMallocUsableSize);
|
||||
|
||||
appendElementWithText(aP, "h3", "", "End of " + aProcess);
|
||||
appendLink("end", "start", kUpwardsArrow);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1517,7 +1546,7 @@ function pad(aS, aN, aC)
|
||||
|
||||
// There's a subset of the Unicode "light" box-drawing chars that is widely
|
||||
// implemented in terminals, and this code sticks to that subset to maximize
|
||||
// the chance that cutting and pasting about:memory output to a terminal will
|
||||
// the chance that copying and pasting about:memory output to a terminal will
|
||||
// work correctly.
|
||||
const kHorizontal = "\u2500",
|
||||
kVertical = "\u2502",
|
||||
|
@ -279,6 +279,7 @@ Other Measurements\n\
|
||||
45.67% ── perc1\n\
|
||||
100.00% ── perc2\n\
|
||||
\n\
|
||||
End of Main Process\n\
|
||||
4th\n\
|
||||
\n\
|
||||
WARNING: the following values are negative or unreasonably large.\n\
|
||||
@ -314,6 +315,7 @@ Other Measurements\n\
|
||||
666.66% ── other6\n\
|
||||
200.00 MB ── resident\n\
|
||||
\n\
|
||||
End of 4th\n\
|
||||
3rd\n\
|
||||
\n\
|
||||
WARNING: the 'heap-allocated' memory reporter does not work for this platform and/or configuration. This means that 'heap-unclassified' is not shown and the 'explicit' tree shows less memory than it should.\n\
|
||||
@ -329,6 +331,7 @@ Other Measurements\n\
|
||||
1.00 MB ── other1\n\
|
||||
100.00 MB ── resident\n\
|
||||
\n\
|
||||
End of 3rd\n\
|
||||
2nd\n\
|
||||
Explicit Allocations\n\
|
||||
\n\
|
||||
@ -345,6 +348,7 @@ Other Measurements\n\
|
||||
666.00 MB ── other0\n\
|
||||
111.00 MB ── other1\n\
|
||||
\n\
|
||||
End of 2nd\n\
|
||||
5th\n\
|
||||
\n\
|
||||
WARNING: the following values are negative or unreasonably large.\n\
|
||||
@ -377,6 +381,7 @@ Other Measurements\n\
|
||||
\n\
|
||||
100.00 MB ── heap-allocated\n\
|
||||
\n\
|
||||
End of 5th\n\
|
||||
";
|
||||
|
||||
let amvExpectedText =
|
||||
@ -446,6 +451,7 @@ Other Measurements\n\
|
||||
45.67% ── perc1\n\
|
||||
100.00% ── perc2\n\
|
||||
\n\
|
||||
End of Main Process\n\
|
||||
4th\n\
|
||||
\n\
|
||||
WARNING: the following values are negative or unreasonably large.\n\
|
||||
@ -479,6 +485,7 @@ Other Measurements\n\
|
||||
666.66% ── other6\n\
|
||||
209,715,200 B ── resident\n\
|
||||
\n\
|
||||
End of 4th\n\
|
||||
3rd\n\
|
||||
\n\
|
||||
WARNING: the 'heap-allocated' memory reporter does not work for this platform and/or configuration. This means that 'heap-unclassified' is not shown and the 'explicit' tree shows less memory than it should.\n\
|
||||
@ -494,6 +501,7 @@ Other Measurements\n\
|
||||
1,048,576 B ── other1\n\
|
||||
104,857,600 B ── resident\n\
|
||||
\n\
|
||||
End of 3rd\n\
|
||||
2nd\n\
|
||||
Explicit Allocations\n\
|
||||
\n\
|
||||
@ -510,6 +518,7 @@ Other Measurements\n\
|
||||
698,351,616 B ── other0\n\
|
||||
116,391,936 B ── other1\n\
|
||||
\n\
|
||||
End of 2nd\n\
|
||||
5th\n\
|
||||
\n\
|
||||
WARNING: the following values are negative or unreasonably large.\n\
|
||||
@ -541,7 +550,8 @@ Other Measurements\n\
|
||||
\n\
|
||||
104,857,600 B ── heap-allocated\n\
|
||||
\n\
|
||||
"
|
||||
End of 5th\n\
|
||||
";
|
||||
|
||||
function finish()
|
||||
{
|
||||
@ -567,7 +577,7 @@ Other Measurements\n\
|
||||
let mostRecentActual;
|
||||
let frame = document.getElementById(aFrameId);
|
||||
frame.focus();
|
||||
|
||||
|
||||
// Set the verbose checkbox value and click the go button.
|
||||
let doc = frame.contentWindow.document;
|
||||
let measureButton = doc.getElementById("measureButton");
|
||||
@ -588,9 +598,9 @@ Other Measurements\n\
|
||||
function() {
|
||||
ok(false, "pasted text doesn't match for " + aFrameId);
|
||||
dump("******EXPECTED******\n");
|
||||
dump(aExpected);
|
||||
dump("<<<" + aExpected + ">>>\n");
|
||||
dump("*******ACTUAL*******\n");
|
||||
dump(mostRecentActual);
|
||||
dump("<<<" + mostRecentActual + ">>>\n");
|
||||
dump("********************\n");
|
||||
finish();
|
||||
}
|
||||
|
@ -177,6 +177,7 @@ Other Measurements\n\
|
||||
\n\
|
||||
250.00 MB ── heap-allocated\n\
|
||||
\n\
|
||||
End of Main Process\n\
|
||||
";
|
||||
|
||||
let acCollapsedExpected =
|
||||
@ -201,6 +202,7 @@ Other Measurements\n\
|
||||
\n\
|
||||
250.00 MB ── heap-allocated\n\
|
||||
\n\
|
||||
End of Main Process\n\
|
||||
";
|
||||
|
||||
let alExpandedExpected =
|
||||
@ -227,6 +229,7 @@ Other Measurements\n\
|
||||
\n\
|
||||
250.00 MB ── heap-allocated\n\
|
||||
\n\
|
||||
End of Main Process\n\
|
||||
";
|
||||
|
||||
let aCollapsedExpected =
|
||||
@ -247,6 +250,7 @@ Other Measurements\n\
|
||||
\n\
|
||||
250.00 MB ── heap-allocated\n\
|
||||
\n\
|
||||
End of Main Process\n\
|
||||
";
|
||||
|
||||
let hCollapsedExpected =
|
||||
@ -265,6 +269,7 @@ Other Measurements\n\
|
||||
\n\
|
||||
250.00 MB ── heap-allocated\n\
|
||||
\n\
|
||||
End of Main Process\n\
|
||||
";
|
||||
|
||||
let jExpandedExpected =
|
||||
@ -285,6 +290,7 @@ Other Measurements\n\
|
||||
\n\
|
||||
250.00 MB ── heap-allocated\n\
|
||||
\n\
|
||||
End of Main Process\n\
|
||||
";
|
||||
|
||||
// The important thing here is that two values have been swapped.
|
||||
@ -308,6 +314,7 @@ Other Measurements\n\
|
||||
\n\
|
||||
250.00 MB ── heap-allocated\n\
|
||||
\n\
|
||||
End of Main Process\n\
|
||||
";
|
||||
|
||||
let aExpandedExpected =
|
||||
@ -334,6 +341,7 @@ Other Measurements\n\
|
||||
\n\
|
||||
250.00 MB ── heap-allocated\n\
|
||||
\n\
|
||||
End of Main Process\n\
|
||||
";
|
||||
|
||||
let acExpandedExpected =
|
||||
@ -362,6 +370,7 @@ Other Measurements\n\
|
||||
\n\
|
||||
250.00 MB ── heap-allocated\n\
|
||||
\n\
|
||||
End of Main Process\n\
|
||||
";
|
||||
|
||||
let alCollapsedExpected =
|
||||
@ -388,6 +397,7 @@ Other Measurements\n\
|
||||
\n\
|
||||
250.00 MB ── heap-allocated\n\
|
||||
\n\
|
||||
End of Main Process\n\
|
||||
";
|
||||
|
||||
// Test the following cases:
|
||||
|
@ -159,7 +159,7 @@
|
||||
synthesizeKey("A", {accelKey: true});
|
||||
synthesizeKey("C", {accelKey: true});
|
||||
let actual = SpecialPowers.getClipboardData("text/unicode");
|
||||
actual = actual.replace(/\(pid \d+\)/, "(pid NNN)");
|
||||
actual = actual.replace(/\(pid \d+\)/g, "(pid NNN)");
|
||||
|
||||
if (actual === aExpected) {
|
||||
SimpleTest.ok(true, "Clipboard has the expected contents");
|
||||
@ -204,6 +204,7 @@ Explicit Allocations\n\
|
||||
\n\
|
||||
Other Measurements\n\
|
||||
\n\
|
||||
End of Explicit-only process\n\
|
||||
Main Process (pid NNN)\n\
|
||||
Explicit Allocations\n\
|
||||
\n\
|
||||
@ -237,6 +238,7 @@ Other Measurements\n\
|
||||
\n\
|
||||
262,144,000 B ── heap-allocated\n\
|
||||
\n\
|
||||
End of Main Process (pid NNN)\n\
|
||||
Other-only process\n\
|
||||
\n\
|
||||
WARNING: the 'heap-allocated' memory reporter does not work for this platform and/or configuration. This means that 'heap-unclassified' is not shown and the 'explicit' tree shows less memory than it should.\n\
|
||||
@ -250,6 +252,7 @@ Other Measurements\n\
|
||||
\n\
|
||||
500,000 B ── heap-allocated\n\
|
||||
\n\
|
||||
End of Other-only process\n\
|
||||
";
|
||||
|
||||
let expectedGood2 =
|
||||
@ -269,12 +272,14 @@ Other Measurements\n\
|
||||
\n\
|
||||
262,144,000 B ── heap-allocated\n\
|
||||
\n\
|
||||
End of Main Process (pid NNN)\n\
|
||||
";
|
||||
|
||||
// This is the output for a malformed data file.
|
||||
let expectedBad =
|
||||
"\
|
||||
Invalid memory report(s): missing 'hasMozMallocUsableSize' property";
|
||||
Invalid memory report(s): missing 'hasMozMallocUsableSize' property\
|
||||
";
|
||||
|
||||
// This is the output for a diff.
|
||||
let expectedDiff =
|
||||
@ -294,6 +299,7 @@ Other Measurements\n\
|
||||
3,000 B ── canvas-2d-pixel-bytes [2] [+]\n\
|
||||
-100 B ── foobar [-]\n\
|
||||
\n\
|
||||
End of P\n\
|
||||
P2 (pid NNN)\n\
|
||||
\n\
|
||||
WARNING: the 'heap-allocated' memory reporter does not work for this platform and/or configuration. This means that 'heap-unclassified' is not shown and the 'explicit' tree shows less memory than it should.\n\
|
||||
@ -303,6 +309,7 @@ Other Measurements\n\
|
||||
\n\
|
||||
11 B ── z 0xNNN\n\
|
||||
\n\
|
||||
End of P2 (pid NNN)\n\
|
||||
P3\n\
|
||||
\n\
|
||||
WARNING: the 'heap-allocated' memory reporter does not work for this platform and/or configuration. This means that 'heap-unclassified' is not shown and the 'explicit' tree shows less memory than it should.\n\
|
||||
@ -312,6 +319,7 @@ Other Measurements\n\
|
||||
\n\
|
||||
-55 B ── p3 [-]\n\
|
||||
\n\
|
||||
End of P3\n\
|
||||
P4\n\
|
||||
\n\
|
||||
WARNING: the 'heap-allocated' memory reporter does not work for this platform and/or configuration. This means that 'heap-unclassified' is not shown and the 'explicit' tree shows less memory than it should.\n\
|
||||
@ -321,6 +329,7 @@ Other Measurements\n\
|
||||
\n\
|
||||
66 B ── p4 [+]\n\
|
||||
\n\
|
||||
End of P4\n\
|
||||
";
|
||||
|
||||
let frames = [
|
||||
|
@ -99,6 +99,7 @@ Explicit Allocations\n\
|
||||
\n\
|
||||
Other Measurements\n\
|
||||
\n\
|
||||
End of Explicit-only process\n\
|
||||
Main Process (pid NNN)\n\
|
||||
Explicit Allocations\n\
|
||||
\n\
|
||||
@ -132,6 +133,7 @@ Other Measurements\n\
|
||||
\n\
|
||||
250.00 MB ── heap-allocated\n\
|
||||
\n\
|
||||
End of Main Process (pid NNN)\n\
|
||||
Other-only process\n\
|
||||
\n\
|
||||
WARNING: the 'heap-allocated' memory reporter does not work for this platform and/or configuration. This means that 'heap-unclassified' is not shown and the 'explicit' tree shows less memory than it should.\n\
|
||||
@ -145,6 +147,7 @@ Other Measurements\n\
|
||||
\n\
|
||||
0.48 MB ── heap-allocated\n\
|
||||
\n\
|
||||
End of Other-only process\n\
|
||||
";
|
||||
|
||||
// This is the output for a malformed data file.
|
||||
|
@ -1963,7 +1963,7 @@ void nsXULWindow::SetContentScrollbarVisibility(bool aVisible)
|
||||
nsCOMPtr<nsPIDOMWindow> contentWin(do_GetInterface(mPrimaryContentShell));
|
||||
if (contentWin) {
|
||||
nsRefPtr<nsGlobalWindow> window = static_cast<nsGlobalWindow*>(contentWin.get());
|
||||
nsRefPtr<mozilla::dom::BarProp> scrollbars = window->Scrollbars();
|
||||
nsRefPtr<mozilla::dom::BarProp> scrollbars = window->GetScrollbars();
|
||||
if (scrollbars) {
|
||||
mozilla::ErrorResult rv;
|
||||
scrollbars->SetVisible(aVisible, rv);
|
||||
|
Loading…
Reference in New Issue
Block a user