mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 14:25:44 +00:00
import changes from `dev' branch of rmottola/Arctic-Fox:
- Bug 1175810 (part 1) - Remove PL_DHashTableEnumerator() use from nsScriptNameSpaceManager. r=bz. (e9ab9ba0a) - Bug 1176160 (part 1) - Remove simple uses of PL_DHashTableEnumerator() from rdf/. r=bsmedberg. (4c97b159f) - Bug 1176160 (part 2) - Remove uses of PL_DHashTableEnumerator() involving VisitorClosure from rdf/. r=bsmedberg. (170ee22a9) - Bug 1176160 (part 3) - Remove uses of PL_DHashTableEnumerator() from SweepForwardArcsEntries(). r=pike. (2442d92c5) - Bug 1175810 (part 2) - Remove PL_DHashTableEnumerate() uses from nsJSNPRuntime. r=bz. (58d6b5fbe) - Bug 1155836: Template on aComputeData in the DoGetStyle* helpers. r=dbaron f=bz (4f951a66b) - Bug 1144885 - Treat font-size-adjust: none as separate from font-size-adjust: 0. r=jdaggett (e7327b7db) - Bug 1144885 - Add reftests for font-size:0 and font-size-adjust:0. r=jdaggett (fb9d997c0) - Bug 1144885 followup - Remove spec links from reference, which the CSS test suite validator treats as an error. (40f92e039) - Bug 1147423 part 1 - [css-grid] Use a signed integer type for some line variables in preparation for negative implicit lines. r=dholbert (b810f12bf) - Bug 1147423 part 2 - [css-grid] Clamp grid lines to the -10000 .. 10000 range. r=dholbert (001e1f0bd) - Bug 1161325 - Make nsStyleVariables copy constructor behave more traditionally. r=dbaron (f612b94c1)
This commit is contained in:
+8
-31
@@ -2293,35 +2293,6 @@ Navigator::MayResolve(jsid aId)
|
||||
return nameSpaceManager->LookupNavigatorName(name);
|
||||
}
|
||||
|
||||
struct NavigatorNameEnumeratorClosure
|
||||
{
|
||||
NavigatorNameEnumeratorClosure(JSContext* aCx, JSObject* aWrapper,
|
||||
nsTArray<nsString>& aNames)
|
||||
: mCx(aCx),
|
||||
mWrapper(aCx, aWrapper),
|
||||
mNames(aNames)
|
||||
{
|
||||
}
|
||||
|
||||
JSContext* mCx;
|
||||
JS::Rooted<JSObject*> mWrapper;
|
||||
nsTArray<nsString>& mNames;
|
||||
};
|
||||
|
||||
static PLDHashOperator
|
||||
SaveNavigatorName(const nsAString& aName,
|
||||
const nsGlobalNameStruct& aNameStruct,
|
||||
void* aClosure)
|
||||
{
|
||||
NavigatorNameEnumeratorClosure* closure =
|
||||
static_cast<NavigatorNameEnumeratorClosure*>(aClosure);
|
||||
if (!aNameStruct.mConstructorEnabled ||
|
||||
aNameStruct.mConstructorEnabled(closure->mCx, closure->mWrapper)) {
|
||||
closure->mNames.AppendElement(aName);
|
||||
}
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
void
|
||||
Navigator::GetOwnPropertyNames(JSContext* aCx, nsTArray<nsString>& aNames,
|
||||
ErrorResult& aRv)
|
||||
@@ -2333,8 +2304,14 @@ Navigator::GetOwnPropertyNames(JSContext* aCx, nsTArray<nsString>& aNames,
|
||||
return;
|
||||
}
|
||||
|
||||
NavigatorNameEnumeratorClosure closure(aCx, GetWrapper(), aNames);
|
||||
nameSpaceManager->EnumerateNavigatorNames(SaveNavigatorName, &closure);
|
||||
JS::Rooted<JSObject*> wrapper(aCx, GetWrapper());
|
||||
for (auto i = nameSpaceManager->NavigatorNameIter(); !i.Done(); i.Next()) {
|
||||
const GlobalNameMapEntry* entry = i.Get();
|
||||
if (!entry->mGlobalName.mConstructorEnabled ||
|
||||
entry->mGlobalName.mConstructorEnabled(aCx, wrapper)) {
|
||||
aNames.AppendElement(entry->mKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
JSObject*
|
||||
|
||||
+10
-36
@@ -4328,40 +4328,6 @@ nsGlobalWindow::MayResolve(jsid aId)
|
||||
return name_struct;
|
||||
}
|
||||
|
||||
struct GlobalNameEnumeratorClosure
|
||||
{
|
||||
GlobalNameEnumeratorClosure(JSContext* aCx, nsGlobalWindow* aWindow,
|
||||
nsTArray<nsString>& aNames)
|
||||
: mCx(aCx),
|
||||
mWindow(aWindow),
|
||||
mWrapper(aCx, aWindow->GetWrapper()),
|
||||
mNames(aNames)
|
||||
{
|
||||
}
|
||||
|
||||
JSContext* mCx;
|
||||
nsGlobalWindow* mWindow;
|
||||
JS::Rooted<JSObject*> mWrapper;
|
||||
nsTArray<nsString>& mNames;
|
||||
};
|
||||
|
||||
static PLDHashOperator
|
||||
EnumerateGlobalName(const nsAString& aName,
|
||||
const nsGlobalNameStruct& aNameStruct,
|
||||
void* aClosure)
|
||||
{
|
||||
GlobalNameEnumeratorClosure* closure =
|
||||
static_cast<GlobalNameEnumeratorClosure*>(aClosure);
|
||||
|
||||
if (nsWindowSH::NameStructEnabled(closure->mCx, closure->mWindow, aName,
|
||||
aNameStruct) &&
|
||||
(!aNameStruct.mConstructorEnabled ||
|
||||
aNameStruct.mConstructorEnabled(closure->mCx, closure->mWrapper))) {
|
||||
closure->mNames.AppendElement(aName);
|
||||
}
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
void
|
||||
nsGlobalWindow::GetOwnPropertyNames(JSContext* aCx, nsTArray<nsString>& aNames,
|
||||
ErrorResult& aRv)
|
||||
@@ -4371,8 +4337,16 @@ nsGlobalWindow::GetOwnPropertyNames(JSContext* aCx, nsTArray<nsString>& aNames,
|
||||
|
||||
nsScriptNameSpaceManager* nameSpaceManager = GetNameSpaceManager();
|
||||
if (nameSpaceManager) {
|
||||
GlobalNameEnumeratorClosure closure(aCx, this, aNames);
|
||||
nameSpaceManager->EnumerateGlobalNames(EnumerateGlobalName, &closure);
|
||||
JS::Rooted<JSObject*> wrapper(aCx, GetWrapper());
|
||||
for (auto i = nameSpaceManager->GlobalNameIter(); !i.Done(); i.Next()) {
|
||||
const GlobalNameMapEntry* entry = i.Get();
|
||||
if (nsWindowSH::NameStructEnabled(aCx, this, entry->mKey,
|
||||
entry->mGlobalName) &&
|
||||
(!entry->mGlobalName.mConstructorEnabled ||
|
||||
entry->mGlobalName.mConstructorEnabled(aCx, wrapper))) {
|
||||
aNames.AppendElement(entry->mKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -35,23 +35,6 @@
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
// Our extended PLDHashEntryHdr
|
||||
class GlobalNameMapEntry : public PLDHashEntryHdr
|
||||
{
|
||||
public:
|
||||
// Our hash table ops don't care about the order of these members
|
||||
nsString mKey;
|
||||
nsGlobalNameStruct mGlobalName;
|
||||
|
||||
size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) {
|
||||
// Measurement of the following members may be added later if DMD finds it
|
||||
// is worthwhile:
|
||||
// - mGlobalName
|
||||
return mKey.SizeOfExcludingThisMustBeUnshared(aMallocSizeOf);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
static PLDHashNumber
|
||||
GlobalNameHashHashKey(PLDHashTable *table, const void *key)
|
||||
{
|
||||
@@ -742,36 +725,6 @@ nsScriptNameSpaceManager::RegisterNavigatorDOMConstructor(
|
||||
}
|
||||
}
|
||||
|
||||
struct NameClosure
|
||||
{
|
||||
nsScriptNameSpaceManager::NameEnumerator enumerator;
|
||||
void* closure;
|
||||
};
|
||||
|
||||
static PLDHashOperator
|
||||
EnumerateName(PLDHashTable*, PLDHashEntryHdr *hdr, uint32_t, void* aClosure)
|
||||
{
|
||||
GlobalNameMapEntry *entry = static_cast<GlobalNameMapEntry *>(hdr);
|
||||
NameClosure* closure = static_cast<NameClosure*>(aClosure);
|
||||
return closure->enumerator(entry->mKey, entry->mGlobalName, closure->closure);
|
||||
}
|
||||
|
||||
void
|
||||
nsScriptNameSpaceManager::EnumerateGlobalNames(NameEnumerator aEnumerator,
|
||||
void* aClosure)
|
||||
{
|
||||
NameClosure closure = { aEnumerator, aClosure };
|
||||
PL_DHashTableEnumerate(&mGlobalNames, EnumerateName, &closure);
|
||||
}
|
||||
|
||||
void
|
||||
nsScriptNameSpaceManager::EnumerateNavigatorNames(NameEnumerator aEnumerator,
|
||||
void* aClosure)
|
||||
{
|
||||
NameClosure closure = { aEnumerator, aClosure };
|
||||
PL_DHashTableEnumerate(&mNavigatorNames, EnumerateName, &closure);
|
||||
}
|
||||
|
||||
static size_t
|
||||
SizeOfEntryExcludingThis(PLDHashEntryHdr *aHdr, MallocSizeOf aMallocSizeOf,
|
||||
void *aArg)
|
||||
|
||||
@@ -79,6 +79,21 @@ struct nsGlobalNameStruct
|
||||
mozilla::dom::ConstructorEnabled* mConstructorEnabled;
|
||||
};
|
||||
|
||||
class GlobalNameMapEntry : public PLDHashEntryHdr
|
||||
{
|
||||
public:
|
||||
// Our hash table ops don't care about the order of these members.
|
||||
nsString mKey;
|
||||
nsGlobalNameStruct mGlobalName;
|
||||
|
||||
size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const {
|
||||
// Measurement of the following members may be added later if DMD finds it
|
||||
// is worthwhile:
|
||||
// - mGlobalName
|
||||
return mKey.SizeOfExcludingThisMustBeUnshared(aMallocSizeOf);
|
||||
}
|
||||
};
|
||||
|
||||
class nsICategoryManager;
|
||||
|
||||
class nsScriptNameSpaceManager : public nsIObserver,
|
||||
@@ -169,10 +184,27 @@ public:
|
||||
const nsGlobalNameStruct& aGlobalNameStruct,
|
||||
void* aClosure);
|
||||
|
||||
void EnumerateGlobalNames(NameEnumerator aEnumerator,
|
||||
void* aClosure);
|
||||
void EnumerateNavigatorNames(NameEnumerator aEnumerator,
|
||||
void* aClosure);
|
||||
class NameIterator : public PLDHashTable::Iterator
|
||||
{
|
||||
public:
|
||||
typedef PLDHashTable::Iterator Base;
|
||||
explicit NameIterator(PLDHashTable* aTable) : Base(aTable) {}
|
||||
NameIterator(NameIterator&& aOther) : Base(mozilla::Move(aOther.mTable)) {}
|
||||
|
||||
const GlobalNameMapEntry* Get() const
|
||||
{
|
||||
return static_cast<const GlobalNameMapEntry*>(Base::Get());
|
||||
}
|
||||
|
||||
private:
|
||||
NameIterator() = delete;
|
||||
NameIterator(const NameIterator&) = delete;
|
||||
NameIterator& operator=(const NameIterator&) = delete;
|
||||
NameIterator& operator=(const NameIterator&&) = delete;
|
||||
};
|
||||
|
||||
NameIterator GlobalNameIter() { return NameIterator(&mGlobalNames); }
|
||||
NameIterator NavigatorNameIter() { return NameIterator(&mNavigatorNames); }
|
||||
|
||||
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf);
|
||||
|
||||
|
||||
@@ -1947,66 +1947,6 @@ nsNPObjWrapper::GetNewOrUsed(NPP npp, JSContext* cx, NPObject* npobj)
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
// Struct for passing an NPP and a JSContext to
|
||||
// NPObjWrapperPluginDestroyedCallback
|
||||
struct NppAndCx
|
||||
{
|
||||
NPP npp;
|
||||
JSContext* cx;
|
||||
};
|
||||
|
||||
static PLDHashOperator
|
||||
NPObjWrapperPluginDestroyedCallback(PLDHashTable* table, PLDHashEntryHdr* hdr,
|
||||
uint32_t number, void* arg)
|
||||
{
|
||||
NPObjWrapperHashEntry* entry = (NPObjWrapperHashEntry*)hdr;
|
||||
NppAndCx* nppcx = reinterpret_cast<NppAndCx*>(arg);
|
||||
|
||||
if (entry->mNpp == nppcx->npp) {
|
||||
// HACK: temporarily hide the hash we're enumerating so that invalidate()
|
||||
// and deallocate() don't touch it.
|
||||
PLDHashTable* tmp = static_cast<PLDHashTable*>(table);
|
||||
sNPObjWrappers = nullptr;
|
||||
|
||||
NPObject* npobj = entry->mNPObj;
|
||||
|
||||
if (npobj->_class && npobj->_class->invalidate) {
|
||||
npobj->_class->invalidate(npobj);
|
||||
}
|
||||
|
||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
||||
{
|
||||
int32_t refCnt = npobj->referenceCount;
|
||||
while (refCnt) {
|
||||
--refCnt;
|
||||
NS_LOG_RELEASE(npobj, refCnt, "BrowserNPObject");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Force deallocation of plugin objects since the plugin they came
|
||||
// from is being torn down.
|
||||
if (npobj->_class && npobj->_class->deallocate) {
|
||||
npobj->_class->deallocate(npobj);
|
||||
} else {
|
||||
PR_Free(npobj);
|
||||
}
|
||||
|
||||
::JS_SetPrivate(entry->mJSObj, nullptr);
|
||||
|
||||
sNPObjWrappers = tmp;
|
||||
|
||||
if (sDelayedReleases && sDelayedReleases->RemoveElement(npobj)) {
|
||||
OnWrapperDestroyed();
|
||||
}
|
||||
|
||||
return PL_DHASH_REMOVE;
|
||||
}
|
||||
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
// static
|
||||
void
|
||||
nsJSNPRuntime::OnPluginDestroy(NPP npp)
|
||||
@@ -2033,13 +1973,51 @@ nsJSNPRuntime::OnPluginDestroy(NPP npp)
|
||||
sJSObjWrappersAccessible = true;
|
||||
}
|
||||
|
||||
// Use the safe JSContext here as we're not always able to find the
|
||||
// JSContext associated with the NPP any more.
|
||||
AutoSafeJSContext cx;
|
||||
if (sNPObjWrappers) {
|
||||
NppAndCx nppcx = { npp, cx };
|
||||
PL_DHashTableEnumerate(sNPObjWrappers,
|
||||
NPObjWrapperPluginDestroyedCallback, &nppcx);
|
||||
for (auto i = sNPObjWrappers->RemovingIter(); !i.Done(); i.Next()) {
|
||||
auto entry = static_cast<NPObjWrapperHashEntry*>(i.Get());
|
||||
|
||||
if (entry->mNpp == npp) {
|
||||
// HACK: temporarily hide the table we're enumerating so that
|
||||
// invalidate() and deallocate() don't touch it.
|
||||
PLDHashTable *tmp = sNPObjWrappers;
|
||||
sNPObjWrappers = nullptr;
|
||||
|
||||
NPObject *npobj = entry->mNPObj;
|
||||
|
||||
if (npobj->_class && npobj->_class->invalidate) {
|
||||
npobj->_class->invalidate(npobj);
|
||||
}
|
||||
|
||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
||||
{
|
||||
int32_t refCnt = npobj->referenceCount;
|
||||
while (refCnt) {
|
||||
--refCnt;
|
||||
NS_LOG_RELEASE(npobj, refCnt, "BrowserNPObject");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Force deallocation of plugin objects since the plugin they came
|
||||
// from is being torn down.
|
||||
if (npobj->_class && npobj->_class->deallocate) {
|
||||
npobj->_class->deallocate(npobj);
|
||||
} else {
|
||||
PR_Free(npobj);
|
||||
}
|
||||
|
||||
::JS_SetPrivate(entry->mJSObj, nullptr);
|
||||
|
||||
sNPObjWrappers = tmp;
|
||||
|
||||
if (sDelayedReleases && sDelayedReleases->RemoveElement(npobj)) {
|
||||
OnWrapperDestroyed();
|
||||
}
|
||||
|
||||
i.Remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -49,7 +49,7 @@ nsFont::Init()
|
||||
{
|
||||
systemFont = false;
|
||||
smoothing = NS_FONT_SMOOTHING_AUTO;
|
||||
sizeAdjust = 0.0;
|
||||
sizeAdjust = -1.0f;
|
||||
kerning = NS_FONT_KERNING_AUTO;
|
||||
synthesis = NS_FONT_SYNTHESIS_WEIGHT | NS_FONT_SYNTHESIS_STYLE;
|
||||
|
||||
|
||||
+2
-2
@@ -92,8 +92,8 @@ struct NS_GFX nsFont {
|
||||
|
||||
// The aspect-value (ie., the ratio actualsize:actualxheight) that any
|
||||
// actual physical font created from this font structure must have when
|
||||
// rendering or measuring a string. A value of 0 means no adjustment
|
||||
// needs to be done.
|
||||
// rendering or measuring a string. A value of -1.0 means no adjustment
|
||||
// needs to be done; otherwise the value must be nonnegative.
|
||||
float sizeAdjust;
|
||||
|
||||
// -- list of value tags for font-specific alternate features
|
||||
|
||||
@@ -162,7 +162,7 @@ gfxDWriteFont::ComputeMetrics(AntialiasOption anAAOption)
|
||||
mFontFace->GetMetrics(&fontMetrics);
|
||||
}
|
||||
|
||||
if (mStyle.sizeAdjust != 0.0) {
|
||||
if (mStyle.sizeAdjust >= 0.0) {
|
||||
gfxFloat aspect = (gfxFloat)fontMetrics.xHeight /
|
||||
fontMetrics.designUnitsPerEm;
|
||||
mAdjustedSize = mStyle.GetAdjustedSize(aspect);
|
||||
|
||||
@@ -114,7 +114,8 @@ gfxFT2FontBase::GetHorizontalMetrics()
|
||||
if (mHasMetrics)
|
||||
return mMetrics;
|
||||
|
||||
if (MOZ_UNLIKELY(GetStyle()->size <= 0.0)) {
|
||||
if (MOZ_UNLIKELY(GetStyle()->size <= 0.0) ||
|
||||
MOZ_UNLIKELY(GetStyle()->sizeAdjust == 0.0)) {
|
||||
new(&mMetrics) gfxFont::Metrics(); // zero initialize
|
||||
mSpaceGlyph = GetGlyph(' ');
|
||||
} else {
|
||||
|
||||
@@ -2201,6 +2201,7 @@ gfxFont::Measure(gfxTextRun *aTextRun,
|
||||
((aBoundingBoxType == LOOSE_INK_EXTENTS &&
|
||||
!needsGlyphExtents &&
|
||||
!aTextRun->HasDetailedGlyphs()) ||
|
||||
(MOZ_UNLIKELY(GetStyle()->sizeAdjust == 0.0)) ||
|
||||
(MOZ_UNLIKELY(GetStyle()->size == 0))) ? nullptr
|
||||
: GetOrCreateGlyphExtents(aTextRun->GetAppUnitsPerDevUnit());
|
||||
double x = 0;
|
||||
@@ -3341,7 +3342,7 @@ gfxFont::SanitizeMetrics(gfxFont::Metrics *aMetrics, bool aIsBadUnderlineFont)
|
||||
{
|
||||
// Even if this font size is zero, this font is created with non-zero size.
|
||||
// However, for layout and others, we should return the metrics of zero size font.
|
||||
if (mStyle.size == 0.0) {
|
||||
if (mStyle.size == 0.0 || mStyle.sizeAdjust == 0.0) {
|
||||
memset(aMetrics, 0, sizeof(gfxFont::Metrics));
|
||||
return;
|
||||
}
|
||||
@@ -3656,7 +3657,7 @@ gfxFontStyle::ParseFontLanguageOverride(const nsString& aLangTag)
|
||||
|
||||
gfxFontStyle::gfxFontStyle() :
|
||||
language(nsGkAtoms::x_western),
|
||||
size(DEFAULT_PIXEL_FONT_SIZE), sizeAdjust(0.0f), baselineOffset(0.0f),
|
||||
size(DEFAULT_PIXEL_FONT_SIZE), sizeAdjust(-1.0f), baselineOffset(0.0f),
|
||||
languageOverride(NO_FONT_LANGUAGE_OVERRIDE),
|
||||
weight(NS_FONT_WEIGHT_NORMAL), stretch(NS_FONT_STRETCH_NORMAL),
|
||||
systemFont(true), printerFont(false), useGrayscaleAntialiasing(false),
|
||||
@@ -3701,7 +3702,7 @@ gfxFontStyle::gfxFontStyle(uint8_t aStyle, uint16_t aWeight, int16_t aStretch,
|
||||
|
||||
if (size >= FONT_MAX_SIZE) {
|
||||
size = FONT_MAX_SIZE;
|
||||
sizeAdjust = 0.0;
|
||||
sizeAdjust = -1.0f;
|
||||
} else if (size < 0.0) {
|
||||
NS_WARNING("negative font size");
|
||||
size = 0.0;
|
||||
|
||||
@@ -105,8 +105,8 @@ struct gfxFontStyle {
|
||||
|
||||
// The aspect-value (ie., the ratio actualsize:actualxheight) that any
|
||||
// actual physical font created from this font structure must have when
|
||||
// rendering or measuring a string. A value of 0 means no adjustment
|
||||
// needs to be done.
|
||||
// rendering or measuring a string. A value of -1.0 means no adjustment
|
||||
// needs to be done; otherwise the value must be nonnegative.
|
||||
float sizeAdjust;
|
||||
|
||||
// baseline offset, used when simulating sub/superscript glyphs
|
||||
@@ -164,9 +164,9 @@ struct gfxFontStyle {
|
||||
uint8_t variantSubSuper;
|
||||
|
||||
// Return the final adjusted font size for the given aspect ratio.
|
||||
// Not meant to be called when sizeAdjust = 0.
|
||||
// Not meant to be called when sizeAdjust = -1.0.
|
||||
gfxFloat GetAdjustedSize(gfxFloat aspect) const {
|
||||
NS_ASSERTION(sizeAdjust != 0.0, "Not meant to be called when sizeAdjust = 0");
|
||||
NS_ASSERTION(sizeAdjust >= 0.0, "Not meant to be called when sizeAdjust = -1.0");
|
||||
gfxFloat adjustedSize = std::max(NS_round(size*(sizeAdjust/aspect)), 1.0);
|
||||
return std::min(adjustedSize, FONT_MAX_SIZE);
|
||||
}
|
||||
@@ -1389,7 +1389,9 @@ public:
|
||||
}
|
||||
|
||||
virtual gfxFloat GetAdjustedSize() const {
|
||||
return mAdjustedSize > 0.0 ? mAdjustedSize : mStyle.size;
|
||||
return mAdjustedSize > 0.0
|
||||
? mAdjustedSize
|
||||
: (mStyle.sizeAdjust == 0.0 ? 0.0 : mStyle.size);
|
||||
}
|
||||
|
||||
float FUnitsToDevUnitsFactor() const {
|
||||
|
||||
@@ -194,7 +194,7 @@ gfxGDIFont::Initialize()
|
||||
|
||||
if (mAdjustedSize == 0.0) {
|
||||
mAdjustedSize = mStyle.size;
|
||||
if (mStyle.sizeAdjust != 0.0 && mAdjustedSize > 0.0) {
|
||||
if (mStyle.sizeAdjust > 0.0 && mAdjustedSize > 0.0) {
|
||||
// to implement font-size-adjust, we first create the "unadjusted" font
|
||||
FillLogFont(logFont, mAdjustedSize,
|
||||
wantFakeItalic && !useCairoFakeItalic);
|
||||
@@ -213,6 +213,8 @@ gfxGDIFont::Initialize()
|
||||
mFont = nullptr;
|
||||
delete mMetrics;
|
||||
mMetrics = nullptr;
|
||||
} else if (mStyle.sizeAdjust == 0.0) {
|
||||
mAdjustedSize = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -254,7 +254,7 @@ gfxMacFont::InitMetrics()
|
||||
mMetrics.xHeight = ::CGFontGetXHeight(mCGFont) * cgConvFactor;
|
||||
}
|
||||
|
||||
if (mStyle.sizeAdjust != 0.0 && mStyle.size > 0.0 &&
|
||||
if (mStyle.sizeAdjust > 0.0 && mStyle.size > 0.0 &&
|
||||
mMetrics.xHeight > 0.0) {
|
||||
// apply font-size-adjust, and recalculate metrics
|
||||
gfxFloat aspect = mMetrics.xHeight / mStyle.size;
|
||||
|
||||
@@ -1854,7 +1854,7 @@ gfxPangoFontGroup::GetBaseFontSet()
|
||||
MakeFontSet(mPangoLanguage, mSizeAdjustFactor, &pattern);
|
||||
|
||||
double size = GetPixelSize(pattern);
|
||||
if (size != 0.0 && mStyle.sizeAdjust != 0.0) {
|
||||
if (size != 0.0 && mStyle.sizeAdjust > 0.0) {
|
||||
gfxFcFont *font = fontSet->GetFontAt(0, GetStyle());
|
||||
if (font) {
|
||||
const gfxFont::Metrics& metrics =
|
||||
|
||||
@@ -1353,7 +1353,8 @@ gfxTextRun::FetchGlyphExtents(gfxContext *aRefContext)
|
||||
for (i = 0; i < runCount; ++i) {
|
||||
const GlyphRun& run = mGlyphRuns[i];
|
||||
gfxFont *font = run.mFont;
|
||||
if (MOZ_UNLIKELY(font->GetStyle()->size == 0)) {
|
||||
if (MOZ_UNLIKELY(font->GetStyle()->size == 0) ||
|
||||
MOZ_UNLIKELY(font->GetStyle()->sizeAdjust == 0.0f)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -2010,7 +2011,8 @@ gfxFontGroup::MakeSpaceTextRun(const Parameters *aParams, uint32_t aFlags)
|
||||
}
|
||||
|
||||
gfxFont *font = GetFirstValidFont();
|
||||
if (MOZ_UNLIKELY(GetStyle()->size == 0)) {
|
||||
if (MOZ_UNLIKELY(GetStyle()->size == 0) ||
|
||||
MOZ_UNLIKELY(GetStyle()->sizeAdjust == 0.0f)) {
|
||||
// Short-circuit for size-0 fonts, as Windows and ATSUI can't handle
|
||||
// them, and always create at least size 1 fonts, i.e. they still
|
||||
// render something for size 0 fonts.
|
||||
@@ -2109,7 +2111,8 @@ gfxFontGroup::MakeTextRun(const uint8_t *aString, uint32_t aLength,
|
||||
|
||||
aFlags |= TEXT_IS_8BIT;
|
||||
|
||||
if (GetStyle()->size == 0) {
|
||||
if (MOZ_UNLIKELY(GetStyle()->size == 0) ||
|
||||
MOZ_UNLIKELY(GetStyle()->sizeAdjust == 0.0f)) {
|
||||
// Short-circuit for size-0 fonts, as Windows and ATSUI can't handle
|
||||
// them, and always create at least size 1 fonts, i.e. they still
|
||||
// render something for size 0 fonts.
|
||||
@@ -2140,7 +2143,8 @@ gfxFontGroup::MakeTextRun(const char16_t *aString, uint32_t aLength,
|
||||
if (aLength == 1 && aString[0] == ' ') {
|
||||
return MakeSpaceTextRun(aParams, aFlags);
|
||||
}
|
||||
if (GetStyle()->size == 0) {
|
||||
if (MOZ_UNLIKELY(GetStyle()->size == 0) ||
|
||||
MOZ_UNLIKELY(GetStyle()->sizeAdjust == 0.0f)) {
|
||||
return MakeBlankTextRun(aLength, aParams, aFlags);
|
||||
}
|
||||
|
||||
|
||||
@@ -333,7 +333,8 @@ nsGridContainerFrame::AddImplicitNamedAreas(
|
||||
// (x-start) 0 (x-start) 0 (x-end)
|
||||
// (x-end) 0 (x-start) 0 (x-end)
|
||||
// (x-start) 0 (x-end) 0 (x-start) 0 (x-end)
|
||||
const uint32_t len = aLineNameLists.Length();
|
||||
const uint32_t len =
|
||||
std::min(aLineNameLists.Length(), size_t(nsStyleGridLine::kMaxLine));
|
||||
nsTHashtable<nsStringHashKey> currentStarts;
|
||||
ImplicitNamedAreas* areas = GetImplicitNamedAreas();
|
||||
for (uint32_t i = 0; i < len; ++i) {
|
||||
@@ -374,7 +375,7 @@ nsGridContainerFrame::InitImplicitNamedAreas(const nsStylePosition* aStyle)
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t
|
||||
int32_t
|
||||
nsGridContainerFrame::ResolveLine(
|
||||
const nsStyleGridLine& aLine,
|
||||
int32_t aNth,
|
||||
@@ -387,7 +388,7 @@ nsGridContainerFrame::ResolveLine(
|
||||
const nsStylePosition* aStyle)
|
||||
{
|
||||
MOZ_ASSERT(!aLine.IsAuto());
|
||||
uint32_t line = 0;
|
||||
int32_t line = 0;
|
||||
if (aLine.mLineName.IsEmpty()) {
|
||||
MOZ_ASSERT(aNth != 0, "css-grid 9.2: <integer> must not be zero.");
|
||||
line = std::max(int32_t(aFromIndex) + aNth, 1);
|
||||
@@ -460,7 +461,7 @@ nsGridContainerFrame::ResolveLine(
|
||||
// <custom-ident> (without <integer> or 'span') which wasn't found.
|
||||
MOZ_ASSERT(line != 0 || (!aLine.mHasSpan && aLine.mInteger == 0),
|
||||
"Given a <integer> or 'span' the result should never be auto");
|
||||
return line;
|
||||
return clamped(line, nsStyleGridLine::kMinLine, nsStyleGridLine::kMaxLine);
|
||||
}
|
||||
|
||||
nsGridContainerFrame::LinePair
|
||||
@@ -501,7 +502,7 @@ nsGridContainerFrame::ResolveLineRangeHelper(
|
||||
return LinePair(start, end);
|
||||
}
|
||||
|
||||
uint32_t start = 0;
|
||||
int32_t start = 0;
|
||||
if (!aStart.IsAuto()) {
|
||||
start = ResolveLine(aStart, aStart.mInteger, 0, aLineNameList, aAreaStart,
|
||||
aAreaEnd, aExplicitGridEnd, eLineRangeSideStart,
|
||||
@@ -530,7 +531,7 @@ nsGridContainerFrame::ResolveLineRangeHelper(
|
||||
end = 1; // XXX subgrid explicit size instead of 1?
|
||||
} else if (start == 0) {
|
||||
// auto (or not found <custom-ident>) / definite line
|
||||
start = std::max(1U, end - 1);
|
||||
start = std::max(1, end - 1);
|
||||
}
|
||||
return LinePair(start, end);
|
||||
}
|
||||
@@ -549,8 +550,16 @@ nsGridContainerFrame::ResolveLineRange(
|
||||
aAreaEnd, aExplicitGridEnd, aStyle);
|
||||
MOZ_ASSERT(r.second != 0);
|
||||
|
||||
// http://dev.w3.org/csswg/css-grid/#grid-placement-errors
|
||||
if (r.second <= r.first) {
|
||||
if (r.first == 0) {
|
||||
// r.second is a span, clamp it to kMaxLine - 1 so that the returned
|
||||
// range has a HypotheticalEnd <= kMaxLine.
|
||||
// http://dev.w3.org/csswg/css-grid/#overlarge-grids
|
||||
r.second = std::min(r.second, nsStyleGridLine::kMaxLine - 1);
|
||||
} else if (r.second <= r.first) {
|
||||
// http://dev.w3.org/csswg/css-grid/#grid-placement-errors
|
||||
if (MOZ_UNLIKELY(r.first == nsStyleGridLine::kMaxLine)) {
|
||||
r.first = nsStyleGridLine::kMaxLine - 1;
|
||||
}
|
||||
r.second = r.first + 1;
|
||||
}
|
||||
return LineRange(r.first, r.second);
|
||||
@@ -587,25 +596,25 @@ nsGridContainerFrame::ResolveAbsPosLineRange(
|
||||
if (aEnd.IsAuto()) {
|
||||
return LineRange(0, 0);
|
||||
}
|
||||
uint32_t end = ResolveLine(aEnd, aEnd.mInteger, 0, aLineNameList, aAreaStart,
|
||||
aAreaEnd, aExplicitGridEnd, eLineRangeSideEnd,
|
||||
aStyle);
|
||||
int32_t end = ResolveLine(aEnd, aEnd.mInteger, 0, aLineNameList, aAreaStart,
|
||||
aAreaEnd, aExplicitGridEnd, eLineRangeSideEnd,
|
||||
aStyle);
|
||||
MOZ_ASSERT(end != 0, "resolving non-auto line shouldn't result in auto");
|
||||
if (aEnd.mHasSpan) {
|
||||
++end;
|
||||
}
|
||||
return LineRange(0, clamped(end, 1U, aGridEnd));
|
||||
return LineRange(0, clamped(end, 1, int32_t(aGridEnd)));
|
||||
}
|
||||
|
||||
if (aEnd.IsAuto()) {
|
||||
uint32_t start =
|
||||
int32_t start =
|
||||
ResolveLine(aStart, aStart.mInteger, 0, aLineNameList, aAreaStart,
|
||||
aAreaEnd, aExplicitGridEnd, eLineRangeSideStart, aStyle);
|
||||
MOZ_ASSERT(start != 0, "resolving non-auto line shouldn't result in auto");
|
||||
if (aStart.mHasSpan) {
|
||||
start = std::max(int32_t(aGridEnd) - int32_t(start), 1);
|
||||
start = std::max(int32_t(aGridEnd) - start, 1);
|
||||
}
|
||||
return LineRange(clamped(start, 1U, aGridEnd), 0);
|
||||
return LineRange(clamped(start, 1, int32_t(aGridEnd)), 0);
|
||||
}
|
||||
|
||||
LineRange r = ResolveLineRange(aStart, aEnd, aLineNameList, aAreaStart,
|
||||
@@ -613,8 +622,8 @@ nsGridContainerFrame::ResolveAbsPosLineRange(
|
||||
MOZ_ASSERT(!r.IsAuto(), "resolving definite lines shouldn't result in auto");
|
||||
// Clamp definite lines to be within the implicit grid.
|
||||
// Note that this implies mStart may be equal to mEnd.
|
||||
r.mStart = clamped(r.mStart, 1U, aGridEnd);
|
||||
r.mEnd = clamped(r.mEnd, 1U, aGridEnd);
|
||||
r.mStart = clamped(r.mStart, 1, int32_t(aGridEnd));
|
||||
r.mEnd = clamped(r.mEnd, 1, int32_t(aGridEnd));
|
||||
MOZ_ASSERT(r.mStart <= r.mEnd);
|
||||
return r;
|
||||
}
|
||||
@@ -788,6 +797,10 @@ nsGridContainerFrame::InitializeGridBounds(const nsStylePosition* aStyle)
|
||||
auto areas = aStyle->mGridTemplateAreas.get();
|
||||
mExplicitGridColEnd = std::max(colEnd, areas ? areas->mNColumns + 1 : 1);
|
||||
mExplicitGridRowEnd = std::max(rowEnd, areas ? areas->NRows() + 1 : 1);
|
||||
mExplicitGridColEnd =
|
||||
std::min(mExplicitGridColEnd, uint32_t(nsStyleGridLine::kMaxLine));
|
||||
mExplicitGridRowEnd =
|
||||
std::min(mExplicitGridRowEnd, uint32_t(nsStyleGridLine::kMaxLine));
|
||||
mGridColEnd = mExplicitGridColEnd;
|
||||
mGridRowEnd = mExplicitGridRowEnd;
|
||||
}
|
||||
@@ -875,7 +888,7 @@ nsGridContainerFrame::PlaceGridItems(GridItemCSSOrderIterator& aIter,
|
||||
if (minor.IsDefinite()) {
|
||||
// Items with 'auto' in the major dimension only.
|
||||
if (isSparse) {
|
||||
if (minor.mStart < cursorMinor) {
|
||||
if (minor.mStart < int32_t(cursorMinor)) {
|
||||
++cursorMajor;
|
||||
}
|
||||
cursorMinor = minor.mStart;
|
||||
|
||||
@@ -83,7 +83,7 @@ protected:
|
||||
* i.e. the invariant is slightly relaxed compared to normal flow items.
|
||||
*/
|
||||
struct LineRange {
|
||||
LineRange(uint32_t aStart, uint32_t aEnd)
|
||||
LineRange(int32_t aStart, int32_t aEnd)
|
||||
: mStart(aStart), mEnd(aEnd) {}
|
||||
bool IsAuto() const { return mStart == 0; }
|
||||
bool IsDefinite() const { return mStart != 0; }
|
||||
@@ -92,11 +92,11 @@ protected:
|
||||
* Resolve this auto range to start at aStart, making it definite.
|
||||
* Precondition: this range IsAuto()
|
||||
*/
|
||||
void ResolveAutoPosition(uint32_t aStart)
|
||||
void ResolveAutoPosition(int32_t aStart)
|
||||
{
|
||||
MOZ_ASSERT(IsAuto(), "Why call me?");
|
||||
MOZ_ASSERT(aStart > 0, "expected a 1-based line number");
|
||||
MOZ_ASSERT(Extent() == mEnd, "'auto' representation changed?");
|
||||
MOZ_ASSERT(int32_t(Extent()) == mEnd, "'auto' representation changed?");
|
||||
mStart = aStart;
|
||||
mEnd += aStart;
|
||||
}
|
||||
@@ -121,8 +121,8 @@ protected:
|
||||
nscoord aGridOrigin,
|
||||
nscoord* aPos, nscoord* aLength) const;
|
||||
|
||||
uint32_t mStart; // the start line, or zero for 'auto'
|
||||
uint32_t mEnd; // the end line, or the span length for 'auto'
|
||||
int32_t mStart; // the start line, or zero for 'auto'
|
||||
int32_t mEnd; // the end line, or the span length for 'auto'
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -181,15 +181,15 @@ protected:
|
||||
* @return a definite line number, or zero in case aLine is a <custom-ident>
|
||||
* that can't be found.
|
||||
*/
|
||||
uint32_t ResolveLine(const nsStyleGridLine& aLine,
|
||||
int32_t aNth,
|
||||
uint32_t aFromIndex,
|
||||
const nsTArray<nsTArray<nsString>>& aLineNameList,
|
||||
uint32_t GridNamedArea::* aAreaStart,
|
||||
uint32_t GridNamedArea::* aAreaEnd,
|
||||
uint32_t aExplicitGridEnd,
|
||||
LineRangeSide aEdge,
|
||||
const nsStylePosition* aStyle);
|
||||
int32_t ResolveLine(const nsStyleGridLine& aLine,
|
||||
int32_t aNth,
|
||||
uint32_t aFromIndex,
|
||||
const nsTArray<nsTArray<nsString>>& aLineNameList,
|
||||
uint32_t GridNamedArea::* aAreaStart,
|
||||
uint32_t GridNamedArea::* aAreaEnd,
|
||||
uint32_t aExplicitGridEnd,
|
||||
LineRangeSide aEdge,
|
||||
const nsStylePosition* aStyle);
|
||||
/**
|
||||
* Return a LineRange based on the given style data. Non-auto lines
|
||||
* are resolved to a definite line number per:
|
||||
@@ -342,7 +342,7 @@ protected:
|
||||
* @see ResolveLineRange
|
||||
* @return a pair (start,end) of lines
|
||||
*/
|
||||
typedef std::pair<uint32_t, uint32_t> LinePair;
|
||||
typedef std::pair<int32_t, int32_t> LinePair;
|
||||
LinePair ResolveLineRangeHelper(const nsStyleGridLine& aStart,
|
||||
const nsStyleGridLine& aEnd,
|
||||
const nsTArray<nsTArray<nsString>>& aLineNameList,
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
<!DOCTYPE HTML>
|
||||
<title>CSS Test: font-size-adjust: 0</title>
|
||||
<link rel="author" title="L. David Baron" href="http://dbaron.org/">
|
||||
<link rel="author" title="Mozilla" href="http://www.mozilla.org/">
|
||||
<link rel="help" href="http://www.w3.org/TR/css3-fonts/#font-size-adjust-prop">
|
||||
<link rel="help" href="http://www.w3.org/TR/CSS21/box.html#collapsing-margins">
|
||||
<link rel="match" href="font-size-zero-2-ref.html">
|
||||
<meta name="flags" content="">
|
||||
<style>
|
||||
/* spec ambiguous whether font-size-adjust influences line-height: normal */
|
||||
body { line-height: 1.2 }
|
||||
|
||||
p { margin: 1em 0 }
|
||||
p.zero { font-size-adjust: 0 }
|
||||
</style>
|
||||
|
||||
<p>before</p>
|
||||
<p class="zero">zero</p>
|
||||
<p>after</p>
|
||||
@@ -0,0 +1,20 @@
|
||||
<!DOCTYPE HTML>
|
||||
<title>CSS Test: font-size-adjust: 0</title>
|
||||
<link rel="author" title="L. David Baron" href="http://dbaron.org/">
|
||||
<link rel="author" title="Mozilla" href="http://www.mozilla.org/">
|
||||
<link rel="help" href="http://www.w3.org/TR/css3-fonts/#font-size-adjust-prop">
|
||||
<link rel="help" href="http://www.w3.org/TR/CSS21/box.html#collapsing-margins">
|
||||
<link rel="match" href="font-size-zero-2-ref.html">
|
||||
<meta name="flags" content="">
|
||||
<style>
|
||||
/* spec ambiguous whether font-size-adjust influences line-height: normal */
|
||||
body { line-height: 1.2 }
|
||||
span { line-height: 0 }
|
||||
|
||||
p { margin: 1em 0 }
|
||||
span.zero { font-size-adjust: 0 }
|
||||
</style>
|
||||
|
||||
<p>before</p>
|
||||
<p><span class="zero">zero</span></p>
|
||||
<p>after</p>
|
||||
@@ -0,0 +1,13 @@
|
||||
<!DOCTYPE HTML>
|
||||
<title>CSS Test Reference</title>
|
||||
<link rel="author" title="L. David Baron" href="http://dbaron.org/">
|
||||
<link rel="author" title="Mozilla" href="http://www.mozilla.org/">
|
||||
<meta name="flags" content="">
|
||||
<style>
|
||||
/* spec ambiguous whether font-size-adjust influences line-height: normal */
|
||||
body { line-height: 1.2 }
|
||||
</style>
|
||||
|
||||
<p>before</p>
|
||||
<p>zero</p>
|
||||
<p>after</p>
|
||||
@@ -0,0 +1,16 @@
|
||||
<!DOCTYPE HTML>
|
||||
<title>CSS Test Reference</title>
|
||||
<link rel="author" title="L. David Baron" href="http://dbaron.org/">
|
||||
<link rel="author" title="Mozilla" href="http://www.mozilla.org/">
|
||||
<link rel="mismatch" href="font-size-zero-1-notref.html">
|
||||
<meta name="flags" content="">
|
||||
<style>
|
||||
/* spec ambiguous whether font-size-adjust influences line-height: normal */
|
||||
body { line-height: 1.2 }
|
||||
|
||||
p { margin: 1em 0 }
|
||||
p.first { margin-bottom: 2em }
|
||||
</style>
|
||||
|
||||
<p class="first">before</p>
|
||||
<p>after</p>
|
||||
@@ -0,0 +1,19 @@
|
||||
<!DOCTYPE HTML>
|
||||
<title>CSS Test: font-size: 0</title>
|
||||
<link rel="author" title="L. David Baron" href="http://dbaron.org/">
|
||||
<link rel="author" title="Mozilla" href="http://www.mozilla.org/">
|
||||
<link rel="help" href="http://www.w3.org/TR/css3-fonts/#font-size-prop">
|
||||
<link rel="help" href="http://www.w3.org/TR/CSS21/box.html#collapsing-margins">
|
||||
<link rel="match" href="font-size-zero-1-ref.html">
|
||||
<meta name="flags" content="">
|
||||
<style>
|
||||
/* spec ambiguous whether font-size-adjust influences line-height: normal */
|
||||
body { line-height: 1.2 }
|
||||
|
||||
p { margin: 1em 0 }
|
||||
p.zero { font-size: 0 }
|
||||
</style>
|
||||
|
||||
<p>before</p>
|
||||
<p class="zero">zero</p>
|
||||
<p>after</p>
|
||||
@@ -0,0 +1,13 @@
|
||||
<!DOCTYPE HTML>
|
||||
<title>CSS Test Reference</title>
|
||||
<link rel="author" title="L. David Baron" href="http://dbaron.org/">
|
||||
<link rel="author" title="Mozilla" href="http://www.mozilla.org/">
|
||||
<meta name="flags" content="">
|
||||
<style>
|
||||
/* spec ambiguous whether font-size-adjust influences line-height: normal */
|
||||
body { line-height: 1.2 }
|
||||
</style>
|
||||
|
||||
<p>before</p>
|
||||
<p> </p>
|
||||
<p>after</p>
|
||||
@@ -0,0 +1,19 @@
|
||||
<!DOCTYPE HTML>
|
||||
<title>CSS Test: font-size: 0</title>
|
||||
<link rel="author" title="L. David Baron" href="http://dbaron.org/">
|
||||
<link rel="author" title="Mozilla" href="http://www.mozilla.org/">
|
||||
<link rel="help" href="http://www.w3.org/TR/css3-fonts/#font-size-prop">
|
||||
<link rel="help" href="http://www.w3.org/TR/CSS21/box.html#collapsing-margins">
|
||||
<link rel="match" href="font-size-zero-2-ref.html">
|
||||
<meta name="flags" content="">
|
||||
<style>
|
||||
/* spec ambiguous whether font-size-adjust influences line-height: normal */
|
||||
body { line-height: 1.2 }
|
||||
|
||||
p { margin: 1em 0 }
|
||||
span.zero { font-size: 0 }
|
||||
</style>
|
||||
|
||||
<p>before</p>
|
||||
<p><span class="zero">zero</span></p>
|
||||
<p>after</p>
|
||||
@@ -0,0 +1,5 @@
|
||||
== font-size-zero-1.html font-size-zero-1-ref.html
|
||||
!= font-size-zero-1-ref.html font-size-zero-1-notref.html
|
||||
== font-size-zero-2.html font-size-zero-2-ref.html
|
||||
== font-size-adjust-zero-1.html font-size-zero-2-ref.html
|
||||
== font-size-adjust-zero-2.html font-size-zero-2-ref.html
|
||||
@@ -23,7 +23,7 @@ include conditional3/reftest.list
|
||||
include flexbox/reftest.list
|
||||
|
||||
# Fonts Level 3
|
||||
# include fonts3/reftest.list
|
||||
include fonts3/reftest.list
|
||||
|
||||
# Image Values and Replaced Content Level 3
|
||||
include images3/reftest.list
|
||||
|
||||
@@ -3448,8 +3448,8 @@ StyleAnimationValue::ExtractComputedValue(nsCSSProperty aProperty,
|
||||
aComputedValue.SetFloatValue(*static_cast<const float*>(
|
||||
StyleDataAtOffset(styleStruct, ssOffset)));
|
||||
if (aProperty == eCSSProperty_font_size_adjust &&
|
||||
aComputedValue.GetFloatValue() == 0.0f) {
|
||||
// In nsStyleFont, we set mFont.sizeAdjust to 0 to represent
|
||||
aComputedValue.GetFloatValue() == -1.0f) {
|
||||
// In nsStyleFont, we set mFont.sizeAdjust to -1.0 to represent
|
||||
// font-size-adjust: none. Here, we have to treat this as a keyword
|
||||
// instead of a float value, to make sure we don't end up doing
|
||||
// interpolation with it.
|
||||
|
||||
@@ -1435,7 +1435,7 @@ nsComputedDOMStyle::DoGetFontSizeAdjust()
|
||||
|
||||
const nsStyleFont *font = StyleFont();
|
||||
|
||||
if (font->mFont.sizeAdjust) {
|
||||
if (font->mFont.sizeAdjust >= 0.0f) {
|
||||
val->SetNumber(font->mFont.sizeAdjust);
|
||||
} else {
|
||||
val->SetIdent(eCSSKeyword_none);
|
||||
|
||||
+11
-32
@@ -17,7 +17,7 @@
|
||||
#include "mozilla/Likely.h"
|
||||
#include "mozilla/LookAndFeel.h"
|
||||
|
||||
#include "nsDeviceContext.h"
|
||||
#include "nsAlgorithm.h" // for clamped()
|
||||
#include "nsRuleNode.h"
|
||||
#include "nscore.h"
|
||||
#include "nsIWidget.h"
|
||||
@@ -2612,7 +2612,12 @@ nsRuleNode::SetDefaultOnRoot(const nsStyleStructID aSID, nsStyleContext* aContex
|
||||
parentdata_ = maybeFakeParentData.ptr(); \
|
||||
} \
|
||||
} \
|
||||
if (aStartStruct) \
|
||||
if (eStyleStruct_##type_ == eStyleStruct_Variables) \
|
||||
/* no need to copy construct an nsStyleVariables, as we will copy */ \
|
||||
/* inherited variables (and set canStoreInRuleTree to false) in */ \
|
||||
/* ComputeVariablesData */ \
|
||||
data_ = new (mPresContext) nsStyle##type_ ctorargs_; \
|
||||
else if (aStartStruct) \
|
||||
/* We only need to compute the delta between this computed data and */ \
|
||||
/* our computed data. */ \
|
||||
data_ = new (mPresContext) \
|
||||
@@ -3795,7 +3800,7 @@ nsRuleNode::SetFont(nsPresContext* aPresContext, nsStyleContext* aContext,
|
||||
aFont->mFont.sizeAdjust = systemFont.sizeAdjust;
|
||||
} else
|
||||
SetFactor(*sizeAdjustValue, aFont->mFont.sizeAdjust,
|
||||
aCanStoreInRuleTree, aParentFont->mFont.sizeAdjust, 0.0f,
|
||||
aCanStoreInRuleTree, aParentFont->mFont.sizeAdjust, -1.0f,
|
||||
SETFCT_NONE | SETFCT_UNSET_INHERIT);
|
||||
}
|
||||
|
||||
@@ -7284,7 +7289,9 @@ SetGridLine(const nsCSSValue& aValue,
|
||||
if (item->mValue.GetUnit() == eCSSUnit_Enumerated) {
|
||||
aResult.mHasSpan = true;
|
||||
} else if (item->mValue.GetUnit() == eCSSUnit_Integer) {
|
||||
aResult.mInteger = item->mValue.GetIntValue();
|
||||
aResult.mInteger = clamped(item->mValue.GetIntValue(),
|
||||
nsStyleGridLine::kMinLine,
|
||||
nsStyleGridLine::kMaxLine);
|
||||
} else if (item->mValue.GetUnit() == eCSSUnit_Ident) {
|
||||
item->mValue.GetStringValue(aResult.mLineName);
|
||||
} else {
|
||||
@@ -9316,34 +9323,6 @@ nsRuleNode::GetStyleData(nsStyleStructID aSID,
|
||||
return data;
|
||||
}
|
||||
|
||||
// See comments above in GetStyleData for an explanation of what the
|
||||
// code below does.
|
||||
#define STYLE_STRUCT(name_, checkdata_cb_) \
|
||||
const nsStyle##name_* \
|
||||
nsRuleNode::GetStyle##name_(nsStyleContext* aContext, bool aComputeData) \
|
||||
{ \
|
||||
NS_ASSERTION(IsUsedDirectly(), \
|
||||
"if we ever call this on rule nodes that aren't used " \
|
||||
"directly, we should adjust handling of mDependentBits " \
|
||||
"in some way."); \
|
||||
\
|
||||
const nsStyle##name_ *data; \
|
||||
data = mStyleData.GetStyle##name_(); \
|
||||
if (MOZ_LIKELY(data != nullptr)) \
|
||||
return data; \
|
||||
\
|
||||
if (MOZ_UNLIKELY(!aComputeData)) \
|
||||
return nullptr; \
|
||||
\
|
||||
data = static_cast<const nsStyle##name_ *> \
|
||||
(WalkRuleTree(eStyleStruct_##name_, aContext)); \
|
||||
\
|
||||
MOZ_ASSERT(data, "should have aborted on out-of-memory"); \
|
||||
return data; \
|
||||
}
|
||||
#include "nsStyleStructList.h"
|
||||
#undef STYLE_STRUCT
|
||||
|
||||
void
|
||||
nsRuleNode::Mark()
|
||||
{
|
||||
|
||||
@@ -715,9 +715,33 @@ public:
|
||||
nsStyleContext* aContext,
|
||||
bool aComputeData);
|
||||
|
||||
|
||||
// See comments in GetStyleData for an explanation of what the
|
||||
// code below does.
|
||||
#define STYLE_STRUCT(name_, checkdata_cb_) \
|
||||
const nsStyle##name_* GetStyle##name_(nsStyleContext* aContext, \
|
||||
bool aComputeData);
|
||||
template<bool aComputeData> \
|
||||
const nsStyle##name_* \
|
||||
GetStyle##name_(nsStyleContext* aContext) \
|
||||
{ \
|
||||
NS_ASSERTION(IsUsedDirectly(), \
|
||||
"if we ever call this on rule nodes that aren't used " \
|
||||
"directly, we should adjust handling of mDependentBits " \
|
||||
"in some way."); \
|
||||
\
|
||||
const nsStyle##name_ *data; \
|
||||
data = mStyleData.GetStyle##name_(); \
|
||||
if (MOZ_LIKELY(data != nullptr)) \
|
||||
return data; \
|
||||
\
|
||||
if (!aComputeData) \
|
||||
return nullptr; \
|
||||
\
|
||||
data = static_cast<const nsStyle##name_ *> \
|
||||
(WalkRuleTree(eStyleStruct_##name_, aContext)); \
|
||||
\
|
||||
MOZ_ASSERT(data, "should have aborted on out-of-memory"); \
|
||||
return data; \
|
||||
}
|
||||
#include "nsStyleStructList.h"
|
||||
#undef STYLE_STRUCT
|
||||
|
||||
|
||||
@@ -311,7 +311,7 @@ public:
|
||||
*/
|
||||
#define STYLE_STRUCT(name_, checkdata_cb_) \
|
||||
const nsStyle##name_ * Style##name_() { \
|
||||
return DoGetStyle##name_(true); \
|
||||
return DoGetStyle##name_<true>(); \
|
||||
}
|
||||
#include "nsStyleStructList.h"
|
||||
#undef STYLE_STRUCT
|
||||
@@ -325,7 +325,7 @@ public:
|
||||
*/
|
||||
#define STYLE_STRUCT(name_, checkdata_cb_) \
|
||||
const nsStyle##name_ * PeekStyle##name_() { \
|
||||
return DoGetStyle##name_(false); \
|
||||
return DoGetStyle##name_<false>(); \
|
||||
}
|
||||
#include "nsStyleStructList.h"
|
||||
#undef STYLE_STRUCT
|
||||
@@ -490,7 +490,8 @@ private:
|
||||
|
||||
// Helper functions for GetStyle* and PeekStyle*
|
||||
#define STYLE_STRUCT_INHERITED(name_, checkdata_cb_) \
|
||||
const nsStyle##name_ * DoGetStyle##name_(bool aComputeData) { \
|
||||
template<bool aComputeData> \
|
||||
const nsStyle##name_ * DoGetStyle##name_() { \
|
||||
const nsStyle##name_ * cachedData = \
|
||||
static_cast<nsStyle##name_*>( \
|
||||
mCachedInheritedData.mStyleStructs[eStyleStruct_##name_]); \
|
||||
@@ -498,19 +499,21 @@ private:
|
||||
return cachedData; \
|
||||
/* Have the rulenode deal */ \
|
||||
AUTO_CHECK_DEPENDENCY(eStyleStruct_##name_); \
|
||||
return mRuleNode->GetStyle##name_(this, aComputeData); \
|
||||
return mRuleNode->GetStyle##name_<aComputeData>(this); \
|
||||
}
|
||||
#define STYLE_STRUCT_RESET(name_, checkdata_cb_) \
|
||||
const nsStyle##name_ * DoGetStyle##name_(bool aComputeData) { \
|
||||
const nsStyle##name_ * cachedData = mCachedResetData \
|
||||
? static_cast<nsStyle##name_*>( \
|
||||
mCachedResetData->mStyleStructs[eStyleStruct_##name_]) \
|
||||
: nullptr; \
|
||||
if (cachedData) /* Have it cached already, yay */ \
|
||||
return cachedData; \
|
||||
template<bool aComputeData> \
|
||||
const nsStyle##name_ * DoGetStyle##name_() { \
|
||||
if (mCachedResetData) { \
|
||||
const nsStyle##name_ * cachedData = \
|
||||
static_cast<nsStyle##name_*>( \
|
||||
mCachedResetData->mStyleStructs[eStyleStruct_##name_]); \
|
||||
if (cachedData) /* Have it cached already, yay */ \
|
||||
return cachedData; \
|
||||
} \
|
||||
/* Have the rulenode deal */ \
|
||||
AUTO_CHECK_DEPENDENCY(eStyleStruct_##name_); \
|
||||
return mRuleNode->GetStyle##name_(this, aComputeData); \
|
||||
return mRuleNode->GetStyle##name_<aComputeData>(this); \
|
||||
}
|
||||
#include "nsStyleStructList.h"
|
||||
#undef STYLE_STRUCT_RESET
|
||||
|
||||
@@ -36,6 +36,11 @@ static_assert((((1 << nsStyleStructID_Length) - 1) &
|
||||
~(NS_STYLE_INHERIT_MASK)) == 0,
|
||||
"Not enough bits in NS_STYLE_INHERIT_MASK");
|
||||
|
||||
// These are the limits that we choose to clamp grid line numbers to.
|
||||
// http://dev.w3.org/csswg/css-grid/#overlarge-grids
|
||||
const int32_t nsStyleGridLine::kMinLine = -10000;
|
||||
const int32_t nsStyleGridLine::kMaxLine = 10000;
|
||||
|
||||
inline bool IsFixedUnit(const nsStyleCoord& aCoord, bool aEnumOK)
|
||||
{
|
||||
return aCoord.ConvertsToLength() ||
|
||||
@@ -3669,6 +3674,7 @@ nsStyleVariables::nsStyleVariables()
|
||||
nsStyleVariables::nsStyleVariables(const nsStyleVariables& aSource)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsStyleVariables);
|
||||
mVariables = aSource.mVariables;
|
||||
}
|
||||
|
||||
nsStyleVariables::~nsStyleVariables(void)
|
||||
|
||||
@@ -1270,10 +1270,15 @@ struct nsStyleGridTemplate {
|
||||
|
||||
struct nsStyleGridLine {
|
||||
// http://dev.w3.org/csswg/css-grid/#typedef-grid-line
|
||||
// XXXmats we could optimize memory size here
|
||||
bool mHasSpan;
|
||||
int32_t mInteger; // 0 means not provided
|
||||
nsString mLineName; // Empty string means not provided.
|
||||
|
||||
// mInteger is clamped to this range:
|
||||
static const int32_t kMinLine;
|
||||
static const int32_t kMaxLine;
|
||||
|
||||
nsStyleGridLine()
|
||||
: mHasSpan(false)
|
||||
, mInteger(0)
|
||||
|
||||
@@ -2563,8 +2563,8 @@ var gCSSProperties = {
|
||||
inherited: true,
|
||||
type: CSS_TYPE_LONGHAND,
|
||||
initial_values: [ "none" ],
|
||||
other_values: [ "0.3", "0.5", "0.7" ],
|
||||
invalid_values: []
|
||||
other_values: [ "0.3", "0.5", "0.7", "0.0", "0", "3" ],
|
||||
invalid_values: [ "-0.3", "-1" ]
|
||||
},
|
||||
"font-stretch": {
|
||||
domProp: "fontStretch",
|
||||
|
||||
+176
-266
@@ -79,10 +79,6 @@
|
||||
class Assertion
|
||||
{
|
||||
public:
|
||||
static PLDHashOperator
|
||||
DeletePropertyHashEntry(PLDHashTable* aTable, PLDHashEntryHdr* aHdr,
|
||||
uint32_t aNumber, void* aArg);
|
||||
|
||||
Assertion(nsIRDFResource* aSource, // normal assertion
|
||||
nsIRDFResource* aProperty,
|
||||
nsIRDFNode* aTarget,
|
||||
@@ -192,8 +188,18 @@ Assertion::Assertion(nsIRDFResource* aSource,
|
||||
Assertion::~Assertion()
|
||||
{
|
||||
if (mHashEntry && u.hash.mPropertyHash) {
|
||||
PL_DHashTableEnumerate(u.hash.mPropertyHash, DeletePropertyHashEntry,
|
||||
nullptr);
|
||||
for (auto i = u.hash.mPropertyHash->Iter(); !i.Done(); i.Next()) {
|
||||
auto entry = static_cast<Entry*>(i.Get());
|
||||
Assertion* as = entry->mAssertions;
|
||||
while (as) {
|
||||
Assertion* doomed = as;
|
||||
as = as->mNext;
|
||||
|
||||
// Unlink, and release the datasource's reference.
|
||||
doomed->mNext = doomed->u.as.mInvNext = nullptr;
|
||||
doomed->Release();
|
||||
}
|
||||
}
|
||||
delete u.hash.mPropertyHash;
|
||||
u.hash.mPropertyHash = nullptr;
|
||||
}
|
||||
@@ -212,26 +218,6 @@ Assertion::~Assertion()
|
||||
}
|
||||
}
|
||||
|
||||
PLDHashOperator
|
||||
Assertion::DeletePropertyHashEntry(PLDHashTable* aTable, PLDHashEntryHdr* aHdr,
|
||||
uint32_t aNumber, void* aArg)
|
||||
{
|
||||
Entry* entry = static_cast<Entry*>(aHdr);
|
||||
|
||||
Assertion* as = entry->mAssertions;
|
||||
while (as) {
|
||||
Assertion* doomed = as;
|
||||
as = as->mNext;
|
||||
|
||||
// Unlink, and release the datasource's reference.
|
||||
doomed->mNext = doomed->u.as.mInvNext = nullptr;
|
||||
doomed->Release();
|
||||
}
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// InMemoryDataSource
|
||||
class InMemoryArcsEnumeratorImpl;
|
||||
@@ -260,14 +246,6 @@ protected:
|
||||
// during mReadCount == 0
|
||||
uint32_t mReadCount;
|
||||
|
||||
static PLDHashOperator
|
||||
DeleteForwardArcsEntry(PLDHashTable* aTable, PLDHashEntryHdr* aHdr,
|
||||
uint32_t aNumber, void* aArg);
|
||||
|
||||
static PLDHashOperator
|
||||
ResourceEnumerator(PLDHashTable* aTable, PLDHashEntryHdr* aHdr,
|
||||
uint32_t aNumber, void* aArg);
|
||||
|
||||
friend class InMemoryArcsEnumeratorImpl;
|
||||
friend class InMemoryAssertionEnumeratorImpl;
|
||||
friend class InMemoryResourceEnumeratorImpl; // b/c it needs to enumerate mForwardArcs
|
||||
@@ -310,9 +288,13 @@ public:
|
||||
NS_DECL_RDFIDATASOURCE
|
||||
|
||||
protected:
|
||||
static PLDHashOperator
|
||||
SweepForwardArcsEntries(PLDHashTable* aTable, PLDHashEntryHdr* aHdr,
|
||||
uint32_t aNumber, void* aArg);
|
||||
struct SweepInfo {
|
||||
Assertion* mUnassertList;
|
||||
PLDHashTable* mReverseArcs;
|
||||
};
|
||||
|
||||
static void
|
||||
SweepForwardArcsEntries(PLDHashTable* aTable, SweepInfo* aArg);
|
||||
|
||||
public:
|
||||
// Implementation methods
|
||||
@@ -561,10 +543,6 @@ private:
|
||||
Assertion* mAssertion;
|
||||
nsCOMPtr<nsISupportsArray> mHashArcs;
|
||||
|
||||
static PLDHashOperator
|
||||
ArcEnumerator(PLDHashTable* aTable, PLDHashEntryHdr* aHdr,
|
||||
uint32_t aNumber, void* aArg);
|
||||
|
||||
virtual ~InMemoryArcsEnumeratorImpl();
|
||||
|
||||
public:
|
||||
@@ -580,19 +558,6 @@ public:
|
||||
};
|
||||
|
||||
|
||||
PLDHashOperator
|
||||
InMemoryArcsEnumeratorImpl::ArcEnumerator(PLDHashTable* aTable,
|
||||
PLDHashEntryHdr* aHdr,
|
||||
uint32_t aNumber, void* aArg)
|
||||
{
|
||||
Entry* entry = static_cast<Entry*>(aHdr);
|
||||
nsISupportsArray* resources = static_cast<nsISupportsArray*>(aArg);
|
||||
|
||||
resources->AppendElement(entry->mNode);
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
|
||||
InMemoryArcsEnumeratorImpl::InMemoryArcsEnumeratorImpl(InMemoryDataSource* aDataSource,
|
||||
nsIRDFResource* aSource,
|
||||
nsIRDFNode* aTarget)
|
||||
@@ -613,8 +578,13 @@ InMemoryArcsEnumeratorImpl::InMemoryArcsEnumeratorImpl(InMemoryDataSource* aData
|
||||
// its our magical HASH_ENTRY forward hash for assertions
|
||||
nsresult rv = NS_NewISupportsArray(getter_AddRefs(mHashArcs));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
PL_DHashTableEnumerate(mAssertion->u.hash.mPropertyHash,
|
||||
ArcEnumerator, mHashArcs.get());
|
||||
nsISupportsArray* resources = mHashArcs.get();
|
||||
for (auto i = mAssertion->u.hash.mPropertyHash->Iter();
|
||||
!i.Done();
|
||||
i.Next()) {
|
||||
auto entry = static_cast<Entry*>(i.Get());
|
||||
resources->AppendElement(entry->mNode);
|
||||
}
|
||||
}
|
||||
mAssertion = nullptr;
|
||||
}
|
||||
@@ -790,7 +760,18 @@ InMemoryDataSource::~InMemoryDataSource()
|
||||
// associated with this data source. We only need to do this
|
||||
// for the forward arcs, because the reverse arcs table
|
||||
// indexes the exact same set of resources.
|
||||
PL_DHashTableEnumerate(&mForwardArcs, DeleteForwardArcsEntry, nullptr);
|
||||
for (auto iter = mForwardArcs.Iter(); !iter.Done(); iter.Next()) {
|
||||
auto entry = static_cast<Entry*>(iter.Get());
|
||||
Assertion* as = entry->mAssertions;
|
||||
while (as) {
|
||||
Assertion* doomed = as;
|
||||
as = as->mNext;
|
||||
|
||||
// Unlink, and release the datasource's reference.
|
||||
doomed->mNext = doomed->u.as.mInvNext = nullptr;
|
||||
doomed->Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PR_LOG(gLog, PR_LOG_NOTICE,
|
||||
@@ -799,24 +780,6 @@ InMemoryDataSource::~InMemoryDataSource()
|
||||
MOZ_COUNT_DTOR(InMemoryDataSource);
|
||||
}
|
||||
|
||||
PLDHashOperator
|
||||
InMemoryDataSource::DeleteForwardArcsEntry(PLDHashTable* aTable, PLDHashEntryHdr* aHdr,
|
||||
uint32_t aNumber, void* aArg)
|
||||
{
|
||||
Entry* entry = static_cast<Entry*>(aHdr);
|
||||
|
||||
Assertion* as = entry->mAssertions;
|
||||
while (as) {
|
||||
Assertion* doomed = as;
|
||||
as = as->mNext;
|
||||
|
||||
// Unlink, and release the datasource's reference.
|
||||
doomed->mNext = doomed->u.as.mInvNext = nullptr;
|
||||
doomed->Release();
|
||||
}
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -1607,16 +1570,6 @@ InMemoryDataSource::ArcLabelsOut(nsIRDFResource* aSource, nsISimpleEnumerator**
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PLDHashOperator
|
||||
InMemoryDataSource::ResourceEnumerator(PLDHashTable* aTable,
|
||||
PLDHashEntryHdr* aHdr,
|
||||
uint32_t aNumber, void* aArg)
|
||||
{
|
||||
Entry* entry = static_cast<Entry*>(aHdr);
|
||||
static_cast<nsCOMArray<nsIRDFNode>*>(aArg)->AppendObject(entry->mNode);
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
InMemoryDataSource::GetAllResources(nsISimpleEnumerator** aResult)
|
||||
@@ -1624,9 +1577,11 @@ InMemoryDataSource::GetAllResources(nsISimpleEnumerator** aResult)
|
||||
nsCOMArray<nsIRDFNode> nodes;
|
||||
nodes.SetCapacity(mForwardArcs.EntryCount());
|
||||
|
||||
// Enumerate all of our entries into an nsCOMArray
|
||||
PL_DHashTableEnumerate(&mForwardArcs, ResourceEnumerator, &nodes);
|
||||
|
||||
// Get all of our entries into an nsCOMArray
|
||||
for (auto iter = mForwardArcs.Iter(); !iter.Done(); iter.Next()) {
|
||||
auto entry = static_cast<Entry*>(iter.Get());
|
||||
nodes.AppendObject(entry->mNode);
|
||||
}
|
||||
return NS_NewArrayEnumerator(aResult, nodes);
|
||||
}
|
||||
|
||||
@@ -1813,19 +1768,13 @@ InMemoryDataSource::Mark(nsIRDFResource* aSource,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
struct SweepInfo {
|
||||
Assertion* mUnassertList;
|
||||
PLDHashTable* mReverseArcs;
|
||||
};
|
||||
|
||||
NS_IMETHODIMP
|
||||
InMemoryDataSource::Sweep()
|
||||
{
|
||||
SweepInfo info = { nullptr, &mReverseArcs };
|
||||
|
||||
// Remove all the assertions, but don't notify anyone.
|
||||
PL_DHashTableEnumerate(&mForwardArcs, SweepForwardArcsEntries, &info);
|
||||
SweepForwardArcsEntries(&mForwardArcs, &info);
|
||||
|
||||
// Now do the notification.
|
||||
Assertion* as = info.mUnassertList;
|
||||
@@ -1853,126 +1802,92 @@ InMemoryDataSource::Sweep()
|
||||
}
|
||||
|
||||
|
||||
PLDHashOperator
|
||||
void
|
||||
InMemoryDataSource::SweepForwardArcsEntries(PLDHashTable* aTable,
|
||||
PLDHashEntryHdr* aHdr,
|
||||
uint32_t aNumber, void* aArg)
|
||||
SweepInfo* aInfo)
|
||||
{
|
||||
PLDHashOperator result = PL_DHASH_NEXT;
|
||||
Entry* entry = static_cast<Entry*>(aHdr);
|
||||
SweepInfo* info = static_cast<SweepInfo*>(aArg);
|
||||
for (auto iter = aTable->RemovingIter(); !iter.Done(); iter.Next()) {
|
||||
auto entry = static_cast<Entry*>(iter.Get());
|
||||
|
||||
Assertion* as = entry->mAssertions;
|
||||
if (as && (as->mHashEntry))
|
||||
{
|
||||
// Stuff in sub-hashes must be swept recursively (max depth: 1)
|
||||
PL_DHashTableEnumerate(as->u.hash.mPropertyHash,
|
||||
SweepForwardArcsEntries, info);
|
||||
Assertion* as = entry->mAssertions;
|
||||
if (as && (as->mHashEntry)) {
|
||||
// Stuff in sub-hashes must be swept recursively (max depth: 1)
|
||||
SweepForwardArcsEntries(as->u.hash.mPropertyHash, aInfo);
|
||||
|
||||
// If the sub-hash is now empty, clean it up.
|
||||
if (!as->u.hash.mPropertyHash->EntryCount()) {
|
||||
as->Release();
|
||||
result = PL_DHASH_REMOVE;
|
||||
// If the sub-hash is now empty, clean it up.
|
||||
if (!as->u.hash.mPropertyHash->EntryCount()) {
|
||||
as->Release();
|
||||
iter.Remove();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Assertion* prev = nullptr;
|
||||
while (as) {
|
||||
if (as->IsMarked()) {
|
||||
prev = as;
|
||||
as->Unmark();
|
||||
as = as->mNext;
|
||||
}
|
||||
else {
|
||||
// remove from the list of assertions in the datasource
|
||||
Assertion* next = as->mNext;
|
||||
if (prev) {
|
||||
prev->mNext = next;
|
||||
Assertion* prev = nullptr;
|
||||
while (as) {
|
||||
if (as->IsMarked()) {
|
||||
prev = as;
|
||||
as->Unmark();
|
||||
as = as->mNext;
|
||||
}
|
||||
else {
|
||||
// it's the first one. update the hashtable entry.
|
||||
entry->mAssertions = next;
|
||||
}
|
||||
|
||||
// remove from the reverse arcs
|
||||
PLDHashEntryHdr* hdr =
|
||||
PL_DHashTableSearch(info->mReverseArcs, as->u.as.mTarget);
|
||||
NS_ASSERTION(hdr, "no assertion in reverse arcs");
|
||||
|
||||
Entry* rentry = static_cast<Entry*>(hdr);
|
||||
Assertion* ras = rentry->mAssertions;
|
||||
Assertion* rprev = nullptr;
|
||||
while (ras) {
|
||||
if (ras == as) {
|
||||
if (rprev) {
|
||||
rprev->u.as.mInvNext = ras->u.as.mInvNext;
|
||||
}
|
||||
else {
|
||||
// it's the first one. update the hashtable entry.
|
||||
rentry->mAssertions = ras->u.as.mInvNext;
|
||||
}
|
||||
as->u.as.mInvNext = nullptr; // for my sanity.
|
||||
break;
|
||||
// remove from the list of assertions in the datasource
|
||||
Assertion* next = as->mNext;
|
||||
if (prev) {
|
||||
prev->mNext = next;
|
||||
}
|
||||
rprev = ras;
|
||||
ras = ras->u.as.mInvNext;
|
||||
else {
|
||||
// it's the first one. update the hashtable entry.
|
||||
entry->mAssertions = next;
|
||||
}
|
||||
|
||||
// remove from the reverse arcs
|
||||
PLDHashEntryHdr* hdr =
|
||||
PL_DHashTableSearch(aInfo->mReverseArcs, as->u.as.mTarget);
|
||||
NS_ASSERTION(hdr, "no assertion in reverse arcs");
|
||||
|
||||
Entry* rentry = static_cast<Entry*>(hdr);
|
||||
Assertion* ras = rentry->mAssertions;
|
||||
Assertion* rprev = nullptr;
|
||||
while (ras) {
|
||||
if (ras == as) {
|
||||
if (rprev) {
|
||||
rprev->u.as.mInvNext = ras->u.as.mInvNext;
|
||||
}
|
||||
else {
|
||||
// it's the first one. update the hashtable entry.
|
||||
rentry->mAssertions = ras->u.as.mInvNext;
|
||||
}
|
||||
as->u.as.mInvNext = nullptr; // for my sanity.
|
||||
break;
|
||||
}
|
||||
rprev = ras;
|
||||
ras = ras->u.as.mInvNext;
|
||||
}
|
||||
|
||||
// Wow, it was the _only_ one. Unhash it.
|
||||
if (! rentry->mAssertions) {
|
||||
PL_DHashTableRawRemove(aInfo->mReverseArcs, hdr);
|
||||
}
|
||||
|
||||
// add to the list of assertions to unassert
|
||||
as->mNext = aInfo->mUnassertList;
|
||||
aInfo->mUnassertList = as;
|
||||
|
||||
// Advance to the next assertion
|
||||
as = next;
|
||||
}
|
||||
}
|
||||
|
||||
// Wow, it was the _only_ one. Unhash it.
|
||||
if (! rentry->mAssertions)
|
||||
{
|
||||
PL_DHashTableRawRemove(info->mReverseArcs, hdr);
|
||||
}
|
||||
|
||||
// add to the list of assertions to unassert
|
||||
as->mNext = info->mUnassertList;
|
||||
info->mUnassertList = as;
|
||||
|
||||
// Advance to the next assertion
|
||||
as = next;
|
||||
// if no more assertions exist for this resource, then unhash it.
|
||||
if (! entry->mAssertions) {
|
||||
iter.Remove();
|
||||
}
|
||||
}
|
||||
|
||||
// if no more assertions exist for this resource, then unhash it.
|
||||
if (! entry->mAssertions)
|
||||
result = PL_DHASH_REMOVE;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// rdfIDataSource methods
|
||||
|
||||
class VisitorClosure
|
||||
{
|
||||
public:
|
||||
explicit VisitorClosure(rdfITripleVisitor* aVisitor) :
|
||||
mVisitor(aVisitor),
|
||||
mRv(NS_OK)
|
||||
{}
|
||||
rdfITripleVisitor* mVisitor;
|
||||
nsresult mRv;
|
||||
};
|
||||
|
||||
PLDHashOperator
|
||||
SubjectEnumerator(PLDHashTable* aTable, PLDHashEntryHdr* aHdr,
|
||||
uint32_t aNumber, void* aArg) {
|
||||
Entry* entry = static_cast<Entry*>(aHdr);
|
||||
VisitorClosure* closure = static_cast<VisitorClosure*>(aArg);
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIRDFNode> subject = do_QueryInterface(entry->mNode, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, PL_DHASH_NEXT);
|
||||
|
||||
closure->mRv = closure->mVisitor->Visit(subject, nullptr, nullptr, true);
|
||||
if (NS_FAILED(closure->mRv) || closure->mRv == NS_RDF_STOP_VISIT)
|
||||
return PL_DHASH_STOP;
|
||||
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
InMemoryDataSource::VisitAllSubjects(rdfITripleVisitor *aVisitor)
|
||||
{
|
||||
@@ -1980,78 +1895,27 @@ InMemoryDataSource::VisitAllSubjects(rdfITripleVisitor *aVisitor)
|
||||
++mReadCount;
|
||||
|
||||
// Enumerate all of our entries into an nsISupportsArray.
|
||||
VisitorClosure cls(aVisitor);
|
||||
PL_DHashTableEnumerate(&mForwardArcs, SubjectEnumerator, &cls);
|
||||
nsresult rv = NS_OK;
|
||||
for (auto iter = mForwardArcs.Iter(); !iter.Done(); iter.Next()) {
|
||||
auto entry = static_cast<Entry*>(iter.Get());
|
||||
nsresult rv2;
|
||||
nsCOMPtr<nsIRDFNode> subject = do_QueryInterface(entry->mNode, &rv2);
|
||||
if (NS_FAILED(rv2)) {
|
||||
NS_WARNING("QI to nsIRDFNode failed");
|
||||
continue;
|
||||
}
|
||||
rv = aVisitor->Visit(subject, nullptr, nullptr, true);
|
||||
if (NS_FAILED(rv) || rv == NS_RDF_STOP_VISIT) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Unlock datasource
|
||||
--mReadCount;
|
||||
|
||||
return cls.mRv;
|
||||
}
|
||||
|
||||
class TriplesInnerClosure
|
||||
{
|
||||
public:
|
||||
TriplesInnerClosure(nsIRDFNode* aSubject, VisitorClosure* aClosure) :
|
||||
mSubject(aSubject), mOuter(aClosure) {}
|
||||
nsIRDFNode* mSubject;
|
||||
VisitorClosure* mOuter;
|
||||
};
|
||||
|
||||
PLDHashOperator
|
||||
TriplesInnerEnumerator(PLDHashTable* aTable, PLDHashEntryHdr* aHdr,
|
||||
uint32_t aNumber, void* aArg) {
|
||||
Entry* entry = static_cast<Entry*>(aHdr);
|
||||
Assertion* assertion = entry->mAssertions;
|
||||
TriplesInnerClosure* closure =
|
||||
static_cast<TriplesInnerClosure*>(aArg);
|
||||
while (assertion) {
|
||||
NS_ASSERTION(!assertion->mHashEntry, "shouldn't have to hashes");
|
||||
VisitorClosure* cls = closure->mOuter;
|
||||
cls->mRv = cls->mVisitor->Visit(closure->mSubject,
|
||||
assertion->u.as.mProperty,
|
||||
assertion->u.as.mTarget,
|
||||
assertion->u.as.mTruthValue);
|
||||
if (NS_FAILED(cls->mRv) || cls->mRv == NS_RDF_STOP_VISIT) {
|
||||
return PL_DHASH_STOP;
|
||||
}
|
||||
assertion = assertion->mNext;
|
||||
}
|
||||
return PL_DHASH_NEXT;
|
||||
return rv;
|
||||
}
|
||||
PLDHashOperator
|
||||
TriplesEnumerator(PLDHashTable* aTable, PLDHashEntryHdr* aHdr,
|
||||
uint32_t aNumber, void* aArg) {
|
||||
Entry* entry = static_cast<Entry*>(aHdr);
|
||||
VisitorClosure* closure = static_cast<VisitorClosure*>(aArg);
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIRDFNode> subject = do_QueryInterface(entry->mNode, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, PL_DHASH_NEXT);
|
||||
|
||||
if (entry->mAssertions->mHashEntry) {
|
||||
TriplesInnerClosure cls(subject, closure);
|
||||
PL_DHashTableEnumerate(entry->mAssertions->u.hash.mPropertyHash,
|
||||
TriplesInnerEnumerator, &cls);
|
||||
if (NS_FAILED(closure->mRv)) {
|
||||
return PL_DHASH_STOP;
|
||||
}
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
Assertion* assertion = entry->mAssertions;
|
||||
while (assertion) {
|
||||
NS_ASSERTION(!assertion->mHashEntry, "shouldn't have to hashes");
|
||||
closure->mRv = closure->mVisitor->Visit(subject,
|
||||
assertion->u.as.mProperty,
|
||||
assertion->u.as.mTarget,
|
||||
assertion->u.as.mTruthValue);
|
||||
if (NS_FAILED(closure->mRv) || closure->mRv == NS_RDF_STOP_VISIT) {
|
||||
return PL_DHASH_STOP;
|
||||
}
|
||||
assertion = assertion->mNext;
|
||||
}
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
NS_IMETHODIMP
|
||||
InMemoryDataSource::VisitAllTriples(rdfITripleVisitor *aVisitor)
|
||||
{
|
||||
@@ -2059,13 +1923,59 @@ InMemoryDataSource::VisitAllTriples(rdfITripleVisitor *aVisitor)
|
||||
++mReadCount;
|
||||
|
||||
// Enumerate all of our entries into an nsISupportsArray.
|
||||
VisitorClosure cls(aVisitor);
|
||||
PL_DHashTableEnumerate(&mForwardArcs, TriplesEnumerator, &cls);
|
||||
nsresult rv = NS_OK;
|
||||
for (auto iter = mForwardArcs.Iter(); !iter.Done(); iter.Next()) {
|
||||
auto entry = static_cast<Entry*>(iter.Get());
|
||||
|
||||
nsresult rv2;
|
||||
nsCOMPtr<nsIRDFNode> subject = do_QueryInterface(entry->mNode, &rv2);
|
||||
if (NS_FAILED(rv2)) {
|
||||
NS_WARNING("QI to nsIRDFNode failed");
|
||||
|
||||
} else if (entry->mAssertions->mHashEntry) {
|
||||
for (auto iter = entry->mAssertions->u.hash.mPropertyHash->Iter();
|
||||
!iter.Done();
|
||||
iter.Next()) {
|
||||
auto entry = static_cast<Entry*>(iter.Get());
|
||||
Assertion* assertion = entry->mAssertions;
|
||||
while (assertion) {
|
||||
NS_ASSERTION(!assertion->mHashEntry, "shouldn't have to hashes");
|
||||
rv = aVisitor->Visit(subject, assertion->u.as.mProperty,
|
||||
assertion->u.as.mTarget,
|
||||
assertion->u.as.mTruthValue);
|
||||
if (NS_FAILED(rv)) {
|
||||
goto end;
|
||||
}
|
||||
if (rv == NS_RDF_STOP_VISIT) {
|
||||
goto inner_end;
|
||||
}
|
||||
assertion = assertion->mNext;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
Assertion* assertion = entry->mAssertions;
|
||||
while (assertion) {
|
||||
NS_ASSERTION(!assertion->mHashEntry, "shouldn't have to hashes");
|
||||
rv = aVisitor->Visit(subject, assertion->u.as.mProperty,
|
||||
assertion->u.as.mTarget,
|
||||
assertion->u.as.mTruthValue);
|
||||
if (NS_FAILED(rv) || rv == NS_RDF_STOP_VISIT) {
|
||||
goto end;
|
||||
}
|
||||
assertion = assertion->mNext;
|
||||
}
|
||||
}
|
||||
|
||||
inner_end:
|
||||
(void) 0;
|
||||
}
|
||||
|
||||
end:
|
||||
// Unlock datasource
|
||||
--mReadCount;
|
||||
|
||||
return cls.mRv;
|
||||
return rv;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Reference in New Issue
Block a user