mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 771594. Allow preference control over what CSS properties we parse. r=dbaron,dholbert
This commit is contained in:
parent
43d3bd71ac
commit
43d45b95b9
@ -770,7 +770,8 @@ nsSMILAnimationController::GetTargetIdentifierForAnimation(
|
||||
isCSS = targetElem->GetNameSpaceID() != kNameSpaceID_SVG;
|
||||
} else {
|
||||
nsCSSProperty prop =
|
||||
nsCSSProps::LookupProperty(nsDependentAtomString(attributeName));
|
||||
nsCSSProps::LookupProperty(nsDependentAtomString(attributeName),
|
||||
nsCSSProps::eEnabled);
|
||||
isCSS = nsSMILCSSProperty::IsPropertyAnimatable(prop);
|
||||
}
|
||||
}
|
||||
|
@ -124,7 +124,8 @@ nsSMILCompositor::CreateSMILAttr()
|
||||
{
|
||||
if (mKey.mIsCSS) {
|
||||
nsCSSProperty propId =
|
||||
nsCSSProps::LookupProperty(nsDependentAtomString(mKey.mAttributeName));
|
||||
nsCSSProps::LookupProperty(nsDependentAtomString(mKey.mAttributeName),
|
||||
nsCSSProps::eEnabled);
|
||||
if (nsSMILCSSProperty::IsPropertyAnimatable(propId)) {
|
||||
return new nsSMILCSSProperty(propId, mKey.mElement.get());
|
||||
}
|
||||
|
@ -1131,7 +1131,8 @@ MappedAttrParser::ParseMappedAttrValue(nsIAtom* aMappedAttrName,
|
||||
|
||||
// Get the nsCSSProperty ID for our mapped attribute.
|
||||
nsCSSProperty propertyID =
|
||||
nsCSSProps::LookupProperty(nsDependentAtomString(aMappedAttrName));
|
||||
nsCSSProps::LookupProperty(nsDependentAtomString(aMappedAttrName),
|
||||
nsCSSProps::eEnabled);
|
||||
if (propertyID != eCSSProperty_UNKNOWN) {
|
||||
bool changed; // outparam for ParseProperty. (ignored)
|
||||
mParser.ParseProperty(propertyID, aMappedAttrValue, mDocURI, mBaseURI,
|
||||
@ -2453,7 +2454,8 @@ nsSVGElement::GetAnimatedAttr(PRInt32 aNamespaceID, nsIAtom* aName)
|
||||
// Mapped attributes:
|
||||
if (IsAttributeMapped(aName)) {
|
||||
nsCSSProperty prop =
|
||||
nsCSSProps::LookupProperty(nsDependentAtomString(aName));
|
||||
nsCSSProps::LookupProperty(nsDependentAtomString(aName),
|
||||
nsCSSProps::eEnabled);
|
||||
// Check IsPropertyAnimatable to avoid attributes that...
|
||||
// - map to explicitly unanimatable properties (e.g. 'direction')
|
||||
// - map to unsupported attributes (e.g. 'glyph-orientation-horizontal')
|
||||
|
@ -2026,7 +2026,8 @@ nsDOMWindowUtils::ComputeAnimationDistance(nsIDOMElement* aElement,
|
||||
|
||||
// Convert direction-dependent properties as appropriate, e.g.,
|
||||
// border-left to border-left-value.
|
||||
nsCSSProperty property = nsCSSProps::LookupProperty(aProperty);
|
||||
nsCSSProperty property = nsCSSProps::LookupProperty(aProperty,
|
||||
nsCSSProps::eAny);
|
||||
if (property != eCSSProperty_UNKNOWN && nsCSSProps::IsShorthand(property)) {
|
||||
nsCSSProperty subprop0 = *nsCSSProps::SubpropertyEntryFor(property);
|
||||
if (nsCSSProps::PropHasFlags(subprop0, CSS_PROPERTY_REPORT_OTHER_NAME) &&
|
||||
|
@ -224,7 +224,8 @@ NS_IMETHODIMP
|
||||
inCSSValueSearch::AddPropertyCriteria(const PRUnichar *aPropName)
|
||||
{
|
||||
nsCSSProperty prop =
|
||||
nsCSSProps::LookupProperty(nsDependentString(aPropName));
|
||||
nsCSSProps::LookupProperty(nsDependentString(aPropName),
|
||||
nsCSSProps::eAny);
|
||||
mProperties[mPropertyCount] = prop;
|
||||
mPropertyCount++;
|
||||
return NS_OK;
|
||||
|
@ -215,7 +215,8 @@ inDOMUtils::GetRuleLine(nsIDOMCSSStyleRule *aRule, PRUint32 *_retval)
|
||||
NS_IMETHODIMP
|
||||
inDOMUtils::IsInheritedProperty(const nsAString &aPropertyName, bool *_retval)
|
||||
{
|
||||
nsCSSProperty prop = nsCSSProps::LookupProperty(aPropertyName);
|
||||
nsCSSProperty prop = nsCSSProps::LookupProperty(aPropertyName,
|
||||
nsCSSProps::eAny);
|
||||
if (prop == eCSSProperty_UNKNOWN) {
|
||||
*_retval = false;
|
||||
return NS_OK;
|
||||
|
@ -823,7 +823,7 @@ Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue) const
|
||||
bool
|
||||
Declaration::GetValueIsImportant(const nsAString& aProperty) const
|
||||
{
|
||||
nsCSSProperty propID = nsCSSProps::LookupProperty(aProperty);
|
||||
nsCSSProperty propID = nsCSSProps::LookupProperty(aProperty, nsCSSProps::eAny);
|
||||
if (propID == eCSSProperty_UNKNOWN) {
|
||||
return false;
|
||||
}
|
||||
|
@ -1080,7 +1080,8 @@ CSSParserImpl::ParseProperty(const nsCSSProperty aPropID,
|
||||
|
||||
*aChanged = false;
|
||||
|
||||
if (eCSSProperty_UNKNOWN == aPropID) { // unknown property
|
||||
// Check for unknown or preffed off properties
|
||||
if (eCSSProperty_UNKNOWN == aPropID || !nsCSSProps::IsEnabled(aPropID)) {
|
||||
NS_ConvertASCIItoUTF16 propName(nsCSSProps::GetStringValue(aPropID));
|
||||
const PRUnichar *params[] = {
|
||||
propName.get()
|
||||
@ -4063,7 +4064,8 @@ CSSParserImpl::ParseDeclaration(css::Declaration* aDeclaration,
|
||||
}
|
||||
|
||||
// Map property name to its ID and then parse the property
|
||||
nsCSSProperty propID = nsCSSProps::LookupProperty(propertyName);
|
||||
nsCSSProperty propID = nsCSSProps::LookupProperty(propertyName,
|
||||
nsCSSProps::eEnabled);
|
||||
if (eCSSProperty_UNKNOWN == propID) { // unknown property
|
||||
if (!NonMozillaVendorIdentifier(propertyName)) {
|
||||
const PRUnichar *params[] = {
|
||||
|
@ -22,6 +22,8 @@
|
||||
#include "nsReadableUtils.h"
|
||||
#include "nsStaticNameTable.h"
|
||||
|
||||
#include "mozilla/Preferences.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
// required to make the symbol external, so that TestCSSPropertyLookup.cpp can link with it
|
||||
@ -72,6 +74,50 @@ SortPropertyAndCount(const void* s1, const void* s2, void *closure)
|
||||
return pc2->property - pc1->property;
|
||||
}
|
||||
|
||||
// We need eCSSAliasCount so we can make gAliases nonzero size when there
|
||||
// are no aliases.
|
||||
enum {
|
||||
#define CSS_PROP_ALIAS(aliasname_, propid_, aliasmethod_, pref_) \
|
||||
eCSSAliasCountBefore_##aliasmethod_,
|
||||
#include "nsCSSPropAliasList.h"
|
||||
#undef CSS_PROP_ALIAS
|
||||
|
||||
eCSSAliasCount
|
||||
};
|
||||
|
||||
enum {
|
||||
// We want the largest sizeof(#aliasname_). To find that, we use the
|
||||
// auto-incrementing behavior of C++ enums (a value without an
|
||||
// initializer is one larger than the previous value, or 0 at the
|
||||
// start of the enum), and for each alias we define two values:
|
||||
// eMaxCSSAliasNameSizeBefore_##aliasmethod_ is the largest
|
||||
// sizeof(#aliasname_) before that alias. The first one is
|
||||
// conveniently zero.
|
||||
// eMaxCSSAliasNameSizeWith_##aliasmethod_ is **one less than** the
|
||||
// largest sizeof(#aliasname_) before or including that alias.
|
||||
#define CSS_PROP_ALIAS(aliasname_, propid_, aliasmethod_, pref_) \
|
||||
eMaxCSSAliasNameSizeBefore_##aliasmethod_, \
|
||||
eMaxCSSAliasNameSizeWith_##aliasmethod_ = \
|
||||
PR_MAX(sizeof(#aliasname_), eMaxCSSAliasNameSizeBefore_##aliasmethod_) - 1,
|
||||
#include "nsCSSPropAliasList.h"
|
||||
#undef CSS_PROP_ALIAS
|
||||
|
||||
eMaxCSSAliasNameSize
|
||||
};
|
||||
|
||||
struct CSSPropertyAlias {
|
||||
const char name[PR_MAX(eMaxCSSAliasNameSize, 1)];
|
||||
const nsCSSProperty id;
|
||||
bool enabled;
|
||||
};
|
||||
|
||||
static CSSPropertyAlias gAliases[PR_MAX(eCSSAliasCount, 1)] = {
|
||||
#define CSS_PROP_ALIAS(aliasname_, propid_, aliasmethod_, pref_) \
|
||||
{ #aliasname_, eCSSProperty_##propid_, true },
|
||||
#include "nsCSSPropAliasList.h"
|
||||
#undef CSS_PROP_ALIAS
|
||||
};
|
||||
|
||||
void
|
||||
nsCSSProps::AddRefTable(void)
|
||||
{
|
||||
@ -116,6 +162,40 @@ nsCSSProps::AddRefTable(void)
|
||||
}
|
||||
|
||||
BuildShorthandsContainingTable();
|
||||
|
||||
static bool prefObserversInited = false;
|
||||
if (!prefObserversInited) {
|
||||
prefObserversInited = true;
|
||||
|
||||
#define OBSERVE_PROP(pref_, id_) \
|
||||
if (pref_[0]) { \
|
||||
Preferences::AddBoolVarCache(&gPropertyEnabled[eCSSProperty_##id_], \
|
||||
pref_); \
|
||||
}
|
||||
|
||||
#define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_, \
|
||||
kwtable_, stylestruct_, stylestructoffset_, animtype_) \
|
||||
OBSERVE_PROP(pref_, id_)
|
||||
#include "nsCSSPropList.h"
|
||||
#undef CSS_PROP
|
||||
|
||||
#define CSS_PROP_SHORTHAND(name_, id_, method_, flags_, pref_) \
|
||||
OBSERVE_PROP(pref_, id_)
|
||||
#include "nsCSSPropList.h"
|
||||
#undef CSS_PROP_SHORTHAND
|
||||
|
||||
#undef OBSERVE_PROP
|
||||
|
||||
size_t aliasIndex = 0;
|
||||
#define CSS_PROP_ALIAS(aliasname_, propid_, aliasmethod_, pref_) \
|
||||
if (pref_[0]) { \
|
||||
Preferences::AddBoolVarCache(&gAliases[aliasIndex].enabled, \
|
||||
pref_); \
|
||||
} \
|
||||
++aliasIndex;
|
||||
#include "nsCSSPropAliasList.h"
|
||||
#undef CSS_PROP_ALIAS
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -282,51 +362,9 @@ nsCSSProps::ReleaseTable(void)
|
||||
}
|
||||
}
|
||||
|
||||
// We need eCSSAliasCount so we can make gAliases nonzero size when there
|
||||
// are no aliases.
|
||||
enum {
|
||||
#define CSS_PROP_ALIAS(aliasname_, propid_, aliasmethod_, pref_) \
|
||||
eCSSAliasCountBefore_##aliasmethod_,
|
||||
#include "nsCSSPropAliasList.h"
|
||||
#undef CSS_PROP_ALIAS
|
||||
|
||||
eCSSAliasCount
|
||||
};
|
||||
|
||||
enum {
|
||||
// We want the largest sizeof(#aliasname_). To find that, we use the
|
||||
// auto-incrementing behavior of C++ enums (a value without an
|
||||
// initializer is one larger than the previous value, or 0 at the
|
||||
// start of the enum), and for each alias we define two values:
|
||||
// eMaxCSSAliasNameSizeBefore_##aliasmethod_ is the largest
|
||||
// sizeof(#aliasname_) before that alias. The first one is
|
||||
// conveniently zero.
|
||||
// eMaxCSSAliasNameSizeWith_##aliasmethod_ is **one less than** the
|
||||
// largest sizeof(#aliasname_) before or including that alias.
|
||||
#define CSS_PROP_ALIAS(aliasname_, propid_, aliasmethod_, pref_) \
|
||||
eMaxCSSAliasNameSizeBefore_##aliasmethod_, \
|
||||
eMaxCSSAliasNameSizeWith_##aliasmethod_ = \
|
||||
PR_MAX(sizeof(#aliasname_), eMaxCSSAliasNameSizeBefore_##aliasmethod_) - 1,
|
||||
#include "nsCSSPropAliasList.h"
|
||||
#undef CSS_PROP_ALIAS
|
||||
|
||||
eMaxCSSAliasNameSize
|
||||
};
|
||||
|
||||
struct CSSPropertyAlias {
|
||||
char name[PR_MAX(eMaxCSSAliasNameSize, 1)];
|
||||
nsCSSProperty id;
|
||||
};
|
||||
|
||||
static const CSSPropertyAlias gAliases[PR_MAX(eCSSAliasCount, 1)] = {
|
||||
#define CSS_PROP_ALIAS(aliasname_, propid_, aliasmethod_, pref_) \
|
||||
{ #aliasname_, eCSSProperty_##propid_ },
|
||||
#include "nsCSSPropAliasList.h"
|
||||
#undef CSS_PROP_ALIAS
|
||||
};
|
||||
|
||||
nsCSSProperty
|
||||
nsCSSProps::LookupProperty(const nsACString& aProperty)
|
||||
nsCSSProps::LookupProperty(const nsACString& aProperty,
|
||||
EnabledState aEnabled)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(gPropertyTable, "no lookup table, needs addref");
|
||||
|
||||
@ -337,17 +375,21 @@ nsCSSProps::LookupProperty(const nsACString& aProperty)
|
||||
for (const CSSPropertyAlias *alias = gAliases,
|
||||
*alias_end = ArrayEnd(gAliases);
|
||||
alias < alias_end; ++alias) {
|
||||
if (aProperty.LowerCaseEqualsASCII(alias->name)) {
|
||||
if (aProperty.LowerCaseEqualsASCII(alias->name) &&
|
||||
(alias->enabled || aEnabled == eAny)) {
|
||||
res = alias->id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (res != eCSSProperty_UNKNOWN && aEnabled == eEnabled && !IsEnabled(res)) {
|
||||
res = eCSSProperty_UNKNOWN;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
nsCSSProperty
|
||||
nsCSSProps::LookupProperty(const nsAString& aProperty)
|
||||
nsCSSProps::LookupProperty(const nsAString& aProperty, EnabledState aEnabled)
|
||||
{
|
||||
// This is faster than converting and calling
|
||||
// LookupProperty(nsACString&). The table will do its own
|
||||
@ -360,12 +402,16 @@ nsCSSProps::LookupProperty(const nsAString& aProperty)
|
||||
for (const CSSPropertyAlias *alias = gAliases,
|
||||
*alias_end = ArrayEnd(gAliases);
|
||||
alias < alias_end; ++alias) {
|
||||
if (aProperty.LowerCaseEqualsASCII(alias->name)) {
|
||||
if (aProperty.LowerCaseEqualsASCII(alias->name) &&
|
||||
(alias->enabled || aEnabled == eAny)) {
|
||||
res = alias->id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (res != eCSSProperty_UNKNOWN && aEnabled == eEnabled && !IsEnabled(res)) {
|
||||
res = eCSSProperty_UNKNOWN;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -2376,3 +2422,17 @@ nsCSSProps::gPropertyIndexInStruct[eCSSProperty_COUNT_no_shorthands] = {
|
||||
#undef CSS_PROP_BACKENDONLY
|
||||
|
||||
};
|
||||
|
||||
/* static */ bool
|
||||
nsCSSProps::gPropertyEnabled[eCSSProperty_COUNT] = {
|
||||
#define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_, \
|
||||
kwtable_, stylestruct_, stylestructoffset_, animtype_) \
|
||||
true,
|
||||
#include "nsCSSPropList.h"
|
||||
#undef CSS_PROP
|
||||
|
||||
#define CSS_PROP_SHORTHAND(name_, id_, method_, flags_, pref_) \
|
||||
true,
|
||||
#include "nsCSSPropList.h"
|
||||
#undef CSS_PROP_SHORTHAND
|
||||
};
|
||||
|
@ -150,8 +150,14 @@ public:
|
||||
static void ReleaseTable(void);
|
||||
|
||||
// Given a property string, return the enum value
|
||||
static nsCSSProperty LookupProperty(const nsAString& aProperty);
|
||||
static nsCSSProperty LookupProperty(const nsACString& aProperty);
|
||||
enum EnabledState {
|
||||
eEnabled,
|
||||
eAny
|
||||
};
|
||||
static nsCSSProperty LookupProperty(const nsAString& aProperty,
|
||||
EnabledState aEnabled);
|
||||
static nsCSSProperty LookupProperty(const nsACString& aProperty,
|
||||
EnabledState aEnabled);
|
||||
|
||||
static inline bool IsShorthand(nsCSSProperty aProperty) {
|
||||
NS_ABORT_IF_FALSE(0 <= aProperty && aProperty < eCSSProperty_COUNT,
|
||||
@ -295,6 +301,17 @@ public:
|
||||
return gPropertyIndexInStruct[aProperty];
|
||||
}
|
||||
|
||||
private:
|
||||
static bool gPropertyEnabled[eCSSProperty_COUNT];
|
||||
|
||||
public:
|
||||
|
||||
static bool IsEnabled(nsCSSProperty aProperty) {
|
||||
NS_ABORT_IF_FALSE(0 <= aProperty && aProperty < eCSSProperty_COUNT,
|
||||
"out of range");
|
||||
return gPropertyEnabled[aProperty];
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
#define CSSPROPS_FOR_SHORTHAND_SUBPROPERTIES(iter_, prop_) \
|
||||
|
@ -429,7 +429,8 @@ nsComputedDOMStyle::GetPropertyCSSValue(const nsAString& aPropertyName,
|
||||
NS_ENSURE_TRUE(document, NS_ERROR_NOT_AVAILABLE);
|
||||
document->FlushPendingLinkUpdates();
|
||||
|
||||
nsCSSProperty prop = nsCSSProps::LookupProperty(aPropertyName);
|
||||
nsCSSProperty prop = nsCSSProps::LookupProperty(aPropertyName,
|
||||
nsCSSProps::eEnabled);
|
||||
|
||||
const ComputedStyleMapEntry* propEntry = nsnull;
|
||||
{
|
||||
|
@ -161,7 +161,8 @@ NS_IMETHODIMP
|
||||
nsDOMCSSDeclaration::GetPropertyValue(const nsAString& aPropertyName,
|
||||
nsAString& aReturn)
|
||||
{
|
||||
const nsCSSProperty propID = nsCSSProps::LookupProperty(aPropertyName);
|
||||
const nsCSSProperty propID = nsCSSProps::LookupProperty(aPropertyName,
|
||||
nsCSSProps::eEnabled);
|
||||
if (propID == eCSSProperty_UNKNOWN) {
|
||||
aReturn.Truncate();
|
||||
return NS_OK;
|
||||
@ -190,7 +191,8 @@ nsDOMCSSDeclaration::SetProperty(const nsAString& aPropertyName,
|
||||
const nsAString& aPriority)
|
||||
{
|
||||
// In the common (and fast) cases we can use the property id
|
||||
nsCSSProperty propID = nsCSSProps::LookupProperty(aPropertyName);
|
||||
nsCSSProperty propID = nsCSSProps::LookupProperty(aPropertyName,
|
||||
nsCSSProps::eEnabled);
|
||||
if (propID == eCSSProperty_UNKNOWN) {
|
||||
return NS_OK;
|
||||
}
|
||||
@ -218,7 +220,8 @@ NS_IMETHODIMP
|
||||
nsDOMCSSDeclaration::RemoveProperty(const nsAString& aPropertyName,
|
||||
nsAString& aReturn)
|
||||
{
|
||||
const nsCSSProperty propID = nsCSSProps::LookupProperty(aPropertyName);
|
||||
const nsCSSProperty propID = nsCSSProps::LookupProperty(aPropertyName,
|
||||
nsCSSProps::eEnabled);
|
||||
if (propID == eCSSProperty_UNKNOWN) {
|
||||
aReturn.Truncate();
|
||||
return NS_OK;
|
||||
|
@ -4347,7 +4347,8 @@ nsRuleNode::ComputeDisplayData(void* aStartStruct,
|
||||
|
||||
nsDependentString
|
||||
propertyStr(property.list->mValue.GetStringBufferValue());
|
||||
nsCSSProperty prop = nsCSSProps::LookupProperty(propertyStr);
|
||||
nsCSSProperty prop = nsCSSProps::LookupProperty(propertyStr,
|
||||
nsCSSProps::eEnabled);
|
||||
if (prop == eCSSProperty_UNKNOWN) {
|
||||
transition->SetUnknownProperty(propertyStr);
|
||||
} else {
|
||||
|
@ -2101,7 +2101,8 @@ void nsTransition::SetInitialValues()
|
||||
|
||||
void nsTransition::SetUnknownProperty(const nsAString& aUnknownProperty)
|
||||
{
|
||||
NS_ASSERTION(nsCSSProps::LookupProperty(aUnknownProperty) ==
|
||||
NS_ASSERTION(nsCSSProps::LookupProperty(aUnknownProperty,
|
||||
nsCSSProps::eEnabled) ==
|
||||
eCSSProperty_UNKNOWN,
|
||||
"should be unknown property");
|
||||
mProperty = eCSSProperty_UNKNOWN;
|
||||
|
@ -40,7 +40,7 @@ TestProps()
|
||||
PL_strcpy(tagName, *et);
|
||||
index = nsCSSProperty(PRInt32(index) + 1);
|
||||
|
||||
id = nsCSSProps::LookupProperty(nsCString(tagName));
|
||||
id = nsCSSProps::LookupProperty(nsCString(tagName), nsCSSProps::eAny);
|
||||
if (id == eCSSProperty_UNKNOWN) {
|
||||
printf("bug: can't find '%s'\n", tagName);
|
||||
success = false;
|
||||
@ -54,7 +54,8 @@ TestProps()
|
||||
if (('a' <= tagName[0]) && (tagName[0] <= 'z')) {
|
||||
tagName[0] = tagName[0] - 32;
|
||||
}
|
||||
id = nsCSSProps::LookupProperty(NS_ConvertASCIItoUTF16(tagName));
|
||||
id = nsCSSProps::LookupProperty(NS_ConvertASCIItoUTF16(tagName),
|
||||
nsCSSProps::eAny);
|
||||
if (id < 0) {
|
||||
printf("bug: can't find '%s'\n", tagName);
|
||||
success = false;
|
||||
@ -69,7 +70,7 @@ TestProps()
|
||||
// Now make sure we don't find some garbage
|
||||
for (int i = 0; i < (int) (sizeof(kJunkNames) / sizeof(const char*)); i++) {
|
||||
const char* const tag = kJunkNames[i];
|
||||
id = nsCSSProps::LookupProperty(nsCAutoString(tag));
|
||||
id = nsCSSProps::LookupProperty(nsCAutoString(tag), nsCSSProps::eAny);
|
||||
if (id >= 0) {
|
||||
printf("bug: found '%s'\n", tag ? tag : "(null)");
|
||||
success = false;
|
||||
|
Loading…
Reference in New Issue
Block a user