mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-13 13:25:37 +00:00
Merge mozilla-central to mozilla-inbound
This commit is contained in:
commit
83c5e2b93a
@ -823,7 +823,6 @@ html|*#fullscreen-exit-button {
|
||||
.popup-anchor {
|
||||
/* should occupy space but not be visible */
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
pointer-events: none;
|
||||
-moz-stack-sizing: ignore;
|
||||
}
|
||||
|
@ -33,11 +33,12 @@
|
||||
<path d="M11.5,3.5L9,5.9V3L6,6H4C3.4,6,3,6.4,3,7v2c0,0.6,0.4,1,1,1h0.9l-2.5,2.5l1.1,1.1l9-9L11.5,3.5z M9,13V9.7l-1.7,1.7L9,13z"/>
|
||||
</g>
|
||||
<g id="tab-audio-blocked" class="icon">
|
||||
<path class="outline" d="M8,1.2C4.3,1.2,1.2,4.3,1.2,8s3.1,6.8,6.8,6.8s6.8-3.1,6.8-6.8S11.7,1.2,8,1.2z M8,11.9
|
||||
c-2.1,0-3.9-1.7-3.9-3.9c0-2.1,1.7-3.9,3.9-3.9s3.9,1.7,3.9,3.9C11.9,10.1,10.1,11.9,8,11.9z M11.1,7.3L6.6,4.6L5.4,3.9v1.4v5.3V12
|
||||
l1.2-0.7L11,8.6L12.2,8L11.1,7.3z"/>
|
||||
<path d="M8,2C4.7,2,2,4.7,2,8s2.7,6,6,6s6-2.7,6-6S11.3,2,8,2z M8,12.7c-2.6,0-4.7-2.1-4.7-4.7
|
||||
S5.4,3.3,8,3.3s4.7,2.1,4.7,4.7S10.6,12.7,8,12.7z M10.7,8L6.2,5.3v5.4L10.7,8z"/>
|
||||
<path class="outline" d="M8,2c3.3,0,6,2.7,6,6s-2.7,6-6,6s-6-2.7-6-6S4.7,2,8,2 M8,12.5c2.4,0,4.5-2,4.5-4.5S10.4,3.5,8,3.5
|
||||
S3.5,5.5,3.5,8S5.6,12.5,8,12.5 M6,5l5,3l-5,3V5 M8,1C4.1,1,1,4.1,1,8s3.1,7,7,7s7-3.1,7-7S11.9,1,8,1L8,1z M7.3,4.6
|
||||
C7.5,4.5,7.7,4.5,8,4.5c1.5,0,2.9,1.1,3.4,2.5L7.3,4.6L7.3,4.6z M5,9.7C4.7,9.2,4.5,8.6,4.5,8S4.7,6.8,5,6.3V9.7L5,9.7z M7.3,11.4
|
||||
L11.4,9c-0.4,1.4-1.8,2.5-3.4,2.5C7.7,11.5,7.5,11.5,7.3,11.4L7.3,11.4z"/>
|
||||
<path d="M8,2C4.7,2,2,4.7,2,8s2.7,6,6,6s6-2.7,6-6S11.3,2,8,2z M8,12.5c-2.4,0-4.5-2-4.5-4.5S5.6,3.5,8,3.5
|
||||
s4.5,2,4.5,4.5S10.4,12.5,8,12.5z M6,5v6l5-3L6,5z"/>
|
||||
</g>
|
||||
|
||||
<g id="tab-audio-white" class="icon white">
|
||||
@ -49,11 +50,11 @@
|
||||
<path d="M11.5,3.5L9,5.9V3L6,6H4C3.4,6,3,6.4,3,7v2c0,0.6,0.4,1,1,1h0.9l-2.5,2.5l1.1,1.1l9-9L11.5,3.5z M9,13V9.7l-1.7,1.7L9,13z"/>
|
||||
</g>
|
||||
<g id="tab-audio-white-blocked" class="icon white">
|
||||
<path class="outline" d="M8,2c3.3,0,6,2.7,6,6s-2.7,6-6,6s-6-2.7-6-6S4.7,2,8,2 M8,12.6c2.6,0,4.6-2.1,4.6-4.6s-2-4.6-4.6-4.6
|
||||
S3.3,5.4,3.3,8S5.4,12.6,8,12.6 M6.2,5.3L10.7,8l-4.5,2.7V5.3 M8,1C4.1,1,1,4.1,1,8s3.1,7,7,7s7-3.1,7-7S11.9,1,8,1L8,1z M6.9,4.5
|
||||
C7.2,4.4,7.6,4.4,8,4.4c1.8,0,3.3,1.3,3.6,3l-0.4-0.2L6.9,4.5L6.9,4.5z M5.2,10.3C4.7,9.7,4.3,8.9,4.3,8s0.3-1.7,0.8-2.3L5.2,10.3
|
||||
L5.2,10.3z M6.9,11.5l4.4-2.6l0.4-0.2c-0.3,1.7-1.8,3-3.6,3C7.6,11.6,7.2,11.6,6.9,11.5L6.9,11.5z"/>
|
||||
<path d="M8,2C4.7,2,2,4.7,2,8s2.7,6,6,6s6-2.7,6-6S11.3,2,8,2z M6.2,5.3v5.4L10.7,8L6.2,5.3z M8,12.7
|
||||
c-2.5,0-4.7-2.1-4.7-4.7S5.5,3.3,8,3.3s4.7,2.1,4.7,4.7S10.5,12.7,8,12.7z"/>
|
||||
<path class="outline" d="M8,2c3.3,0,6,2.7,6,6s-2.7,6-6,6s-6-2.7-6-6S4.7,2,8,2 M8,12.5c2.4,0,4.5-2,4.5-4.5S10.4,3.5,8,3.5
|
||||
S3.5,5.5,3.5,8S5.6,12.5,8,12.5 M6,5l5,3l-5,3V5 M8,1C4.1,1,1,4.1,1,8s3.1,7,7,7s7-3.1,7-7S11.9,1,8,1L8,1z M7.3,4.6
|
||||
C7.5,4.5,7.7,4.5,8,4.5c1.5,0,2.9,1.1,3.4,2.5L7.3,4.6L7.3,4.6z M5,9.7C4.7,9.2,4.5,8.6,4.5,8S4.7,6.8,5,6.3V9.7L5,9.7z M7.3,11.4
|
||||
L11.4,9c-0.4,1.4-1.8,2.5-3.4,2.5C7.7,11.5,7.5,11.5,7.3,11.4L7.3,11.4z"/>
|
||||
<path d="M8,2C4.7,2,2,4.7,2,8s2.7,6,6,6s6-2.7,6-6S11.3,2,8,2z M8,12.5c-2.4,0-4.5-2-4.5-4.5S5.6,3.5,8,3.5
|
||||
s4.5,2,4.5,4.5S10.4,12.5,8,12.5z M6,5v6l5-3L6,5z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.1 KiB |
@ -373,12 +373,11 @@ EffectCompositor::MaybeUpdateAnimationRule(dom::Element* aElement,
|
||||
auto& elementsToRestyle = mElementsToRestyle[aCascadeLevel];
|
||||
PseudoElementHashEntry::KeyType key = { aElement, aPseudoType };
|
||||
|
||||
if (!mPresContext || !elementsToRestyle.Contains(key)) {
|
||||
if (!elementsToRestyle.Contains(key)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ComposeAnimationRule(aElement, aPseudoType, aCascadeLevel,
|
||||
mPresContext->RefreshDriver()->MostRecentRefresh());
|
||||
ComposeAnimationRule(aElement, aPseudoType, aCascadeLevel);
|
||||
|
||||
elementsToRestyle.Remove(key);
|
||||
}
|
||||
@ -493,8 +492,6 @@ EffectCompositor::GetServoAnimationRule(const dom::Element* aElement,
|
||||
MOZ_ASSERT(effectSet == EffectSet::GetEffectSet(aElement, aPseudoType),
|
||||
"EffectSet should not change while composing style");
|
||||
|
||||
effectSet->UpdateAnimationRuleRefreshTime(
|
||||
aCascadeLevel, mPresContext->RefreshDriver()->MostRecentRefresh());
|
||||
return animRule.mServo;
|
||||
}
|
||||
|
||||
@ -596,8 +593,7 @@ EffectCompositor::AddStyleUpdatesTo(RestyleTracker& aTracker)
|
||||
|
||||
ComposeAnimationRule(pseudoElem.mElement,
|
||||
pseudoElem.mPseudoType,
|
||||
cascadeLevel,
|
||||
mPresContext->RefreshDriver()->MostRecentRefresh());
|
||||
cascadeLevel);
|
||||
|
||||
dom::Element* elementToRestyle =
|
||||
GetElementToRestyle(pseudoElem.mElement, pseudoElem.mPseudoType);
|
||||
@ -729,8 +725,7 @@ EffectCompositor::GetAnimationElementAndPseudoForFrame(const nsIFrame* aFrame)
|
||||
/* static */ void
|
||||
EffectCompositor::ComposeAnimationRule(dom::Element* aElement,
|
||||
CSSPseudoElementType aPseudoType,
|
||||
CascadeLevel aCascadeLevel,
|
||||
TimeStamp aRefreshTime)
|
||||
CascadeLevel aCascadeLevel)
|
||||
{
|
||||
EffectSet* effects = EffectSet::GetEffectSet(aElement, aPseudoType);
|
||||
if (!effects) {
|
||||
@ -764,8 +759,6 @@ EffectCompositor::ComposeAnimationRule(dom::Element* aElement,
|
||||
|
||||
MOZ_ASSERT(effects == EffectSet::GetEffectSet(aElement, aPseudoType),
|
||||
"EffectSet should not change while composing style");
|
||||
|
||||
effects->UpdateAnimationRuleRefreshTime(aCascadeLevel, aRefreshTime);
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
|
@ -240,8 +240,7 @@ private:
|
||||
// EffectSet associated with the specified (pseudo-)element.
|
||||
static void ComposeAnimationRule(dom::Element* aElement,
|
||||
CSSPseudoElementType aPseudoType,
|
||||
CascadeLevel aCascadeLevel,
|
||||
TimeStamp aRefreshTime);
|
||||
CascadeLevel aCascadeLevel);
|
||||
|
||||
static dom::Element* GetElementToRestyle(dom::Element* aElement,
|
||||
CSSPseudoElementType
|
||||
|
@ -169,16 +169,13 @@ public:
|
||||
return mAnimationRule[aCascadeLevel];
|
||||
}
|
||||
|
||||
const TimeStamp& AnimationRuleRefreshTime(EffectCompositor::CascadeLevel
|
||||
aCascadeLevel) const
|
||||
const TimeStamp& LastTransformSyncTime() const
|
||||
{
|
||||
return mAnimationRuleRefreshTime[aCascadeLevel];
|
||||
return mLastTransformSyncTime;
|
||||
}
|
||||
void UpdateAnimationRuleRefreshTime(EffectCompositor::CascadeLevel
|
||||
aCascadeLevel,
|
||||
const TimeStamp& aRefreshTime)
|
||||
void UpdateLastTransformSyncTime(const TimeStamp& aRefreshTime)
|
||||
{
|
||||
mAnimationRuleRefreshTime[aCascadeLevel] = aRefreshTime;
|
||||
mLastTransformSyncTime = aRefreshTime;
|
||||
}
|
||||
|
||||
bool CascadeNeedsUpdate() const { return mCascadeNeedsUpdate; }
|
||||
@ -214,14 +211,11 @@ private:
|
||||
EffectCompositor::kCascadeLevelCount),
|
||||
mozilla::AnimationRule> mAnimationRule;
|
||||
|
||||
// A parallel array to mAnimationRule that records the refresh driver
|
||||
// timestamp when the rule was last updated. This is used for certain
|
||||
// animations which are updated only periodically (e.g. transform animations
|
||||
// running on the compositor that affect the scrollable overflow region).
|
||||
EnumeratedArray<EffectCompositor::CascadeLevel,
|
||||
EffectCompositor::CascadeLevel(
|
||||
EffectCompositor::kCascadeLevelCount),
|
||||
TimeStamp> mAnimationRuleRefreshTime;
|
||||
// Refresh driver timestamp from the moment when transform animations in this
|
||||
// effect set were last updated and sent to the compositor. This is used for
|
||||
// transform animations that run on the compositor but need to be updated on
|
||||
// the main thread periodically (e.g. so scrollbars can be updated).
|
||||
TimeStamp mLastTransformSyncTime;
|
||||
|
||||
// Dirty flag to represent when the mPropertiesWithImportantRules and
|
||||
// mPropertiesForAnimationsLevel on effects in this set might need to be
|
||||
|
@ -1360,13 +1360,7 @@ KeyframeEffectReadOnly::CanThrottleTransformChanges(nsIFrame& aFrame) const
|
||||
return true;
|
||||
}
|
||||
|
||||
nsPresContext* presContext = GetPresContext();
|
||||
// CanThrottleTransformChanges is only called as part of a refresh driver tick
|
||||
// in which case we expect to has a pres context.
|
||||
MOZ_ASSERT(presContext);
|
||||
|
||||
TimeStamp now =
|
||||
presContext->RefreshDriver()->MostRecentRefresh();
|
||||
TimeStamp now = aFrame.PresContext()->RefreshDriver()->MostRecentRefresh();
|
||||
|
||||
EffectSet* effectSet = EffectSet::GetEffectSet(mTarget->mElement,
|
||||
mTarget->mPseudoType);
|
||||
@ -1374,11 +1368,10 @@ KeyframeEffectReadOnly::CanThrottleTransformChanges(nsIFrame& aFrame) const
|
||||
" on an effect in an effect set");
|
||||
MOZ_ASSERT(mAnimation, "CanThrottleTransformChanges is expected to be called"
|
||||
" on an effect with a parent animation");
|
||||
TimeStamp animationRuleRefreshTime =
|
||||
effectSet->AnimationRuleRefreshTime(mAnimation->CascadeLevel());
|
||||
TimeStamp lastSyncTime = effectSet->LastTransformSyncTime();
|
||||
// If this animation can cause overflow, we can throttle some of the ticks.
|
||||
if (!animationRuleRefreshTime.IsNull() &&
|
||||
(now - animationRuleRefreshTime) < OverflowRegionRefreshInterval()) {
|
||||
if (!lastSyncTime.IsNull() &&
|
||||
(now - lastSyncTime) < OverflowRegionRefreshInterval()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,7 @@ html_template = textwrap.dedent("""\
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<script type="application/javascript;version=1.7" src="browserElement_{test}.js">
|
||||
<script type="application/javascript" src="browserElement_{test}.js">
|
||||
</script>
|
||||
</body>
|
||||
</html>""")
|
||||
|
@ -349,7 +349,7 @@ MediaDocument::LinkScript(const nsAString& aScript)
|
||||
NS_ENSURE_TRUE(script, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
script->SetAttr(kNameSpaceID_None, nsGkAtoms::type,
|
||||
NS_LITERAL_STRING("text/javascript;version=1.8"), true);
|
||||
NS_LITERAL_STRING("text/javascript"), true);
|
||||
|
||||
script->SetAttr(kNameSpaceID_None, nsGkAtoms::src, aScript, true);
|
||||
|
||||
|
@ -595,9 +595,10 @@ AddAnimationsForProperty(nsIFrame* aFrame, nsCSSPropertyID aProperty,
|
||||
CSS_PROPERTY_CAN_ANIMATE_ON_COMPOSITOR),
|
||||
"inconsistent property flags");
|
||||
|
||||
DebugOnly<EffectSet*> effects = EffectSet::GetEffectSet(aFrame);
|
||||
EffectSet* effects = EffectSet::GetEffectSet(aFrame);
|
||||
MOZ_ASSERT(effects);
|
||||
|
||||
bool sentAnimations = false;
|
||||
// Add from first to last (since last overrides)
|
||||
for (size_t animIdx = 0; animIdx < aAnimations.Length(); animIdx++) {
|
||||
dom::Animation* anim = aAnimations[animIdx];
|
||||
@ -644,6 +645,12 @@ AddAnimationsForProperty(nsIFrame* aFrame, nsCSSPropertyID aProperty,
|
||||
|
||||
AddAnimationForProperty(aFrame, *property, anim, aLayer, aData, aPending);
|
||||
keyframeEffect->SetIsRunningOnCompositor(aProperty, true);
|
||||
sentAnimations = true;
|
||||
}
|
||||
|
||||
if (sentAnimations && aProperty == eCSSProperty_transform) {
|
||||
TimeStamp now = aFrame->PresContext()->RefreshDriver()->MostRecentRefresh();
|
||||
effects->UpdateLastTransformSyncTime(now);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -468,14 +468,6 @@ nsAnimationManager::UpdateAnimations(nsStyleContext* aStyleContext,
|
||||
for (size_t newAnimIdx = newAnimations.Length(); newAnimIdx-- != 0; ) {
|
||||
newAnimations[newAnimIdx]->CancelFromStyle();
|
||||
}
|
||||
|
||||
// We don't actually dispatch the pending events now. We'll either
|
||||
// dispatch them the next time we get a refresh driver notification
|
||||
// or the next time somebody calls
|
||||
// nsPresShell::FlushPendingNotifications.
|
||||
if (mEventDispatcher.HasQueuedEvents()) {
|
||||
mPresContext->PresShell()->SetNeedStyleFlush();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -107,7 +107,7 @@ Any line which doesn't follow the format above would be ignored like comment.
|
||||
* test_transitions_computed_values.html [10]
|
||||
* test_transitions_dynamic_changes.html [10]
|
||||
* test_transitions_step_functions.html [24]
|
||||
* test_value_storage.html `transition` [635]
|
||||
* test_value_storage.html `transition` [620]
|
||||
* test_bug798843_pref.html: conditional opentype svg support [7]
|
||||
* test_computed_style.html `gradient`: -moz-prefixed radient value [9]
|
||||
* url value in style attribute bug 1310886
|
||||
@ -139,7 +139,7 @@ Any line which doesn't follow the format above would be ignored like comment.
|
||||
* test_namespace_rule.html [17]
|
||||
* test_dont_use_document_colors.html: support of disabling document color [21]
|
||||
* test_exposed_prop_accessors.html: mainly various unsupported properties [*]
|
||||
* test_extra_inherit_initial.html: CSS-wide keywords are accepted as part of value servo/servo#15054 [930]
|
||||
* test_extra_inherit_initial.html: CSS-wide keywords are accepted as part of value servo/servo#15054 [822]
|
||||
* flex-basis glue not implemented bug 1331529
|
||||
* test_flexbox_flex_shorthand.html `flex-basis` [28]
|
||||
* test_flexbox_layout.html [355]
|
||||
@ -218,7 +218,7 @@ Any line which doesn't follow the format above would be ignored like comment.
|
||||
* test_inherit_storage.html `transform`: for -moz-transform [3]
|
||||
* test_initial_computation.html `-moz-transform`: need different parsing rules [4]
|
||||
* test_initial_storage.html `transform`: for -moz-transform [6]
|
||||
* test_value_storage.html `-moz-transform`: need different parsing rules [280]
|
||||
* test_value_storage.html `-moz-transform`: need different parsing rules [284]
|
||||
* test_variables.html `var(--var6)`: -x-system-font [1]
|
||||
* Unimplemented CSS properties:
|
||||
* will-change longhand property
|
||||
@ -424,12 +424,12 @@ Any line which doesn't follow the format above would be ignored like comment.
|
||||
* ... `circle(at ` [2]
|
||||
* ... `ellipse(at ` [2]
|
||||
* accepts rubbish for second part of value:
|
||||
* {transform,perspective}-origin servo/servo#15487
|
||||
* test_property_syntax_errors.html `transform-origin'` [50]
|
||||
* ... `perspective-origin'` [30]
|
||||
* test_property_syntax_errors.html `'text-overflow'`: servo/servo#15491 [8]
|
||||
* -moz-alt-content parsing is wrong: servo/servo#15726
|
||||
* test_property_syntax_errors.html `-moz-alt-content` [4]
|
||||
* {transform,perspective}-origin fail to parse 'center left' and 'center right' servo/servo#15750
|
||||
* test_value_storage.html `'center left'` [8]
|
||||
* ... `'center right'` [8]
|
||||
* Incorrect serialization
|
||||
* border-radius and -moz-outline-radius shorthand servo/servo#15169
|
||||
* test_priority_preservation.html `border-radius` [4]
|
||||
@ -457,8 +457,6 @@ Any line which doesn't follow the format above would be ignored like comment.
|
||||
* test_shorthand_property_getters.html `should not be able to serialize border` [7]
|
||||
* color value not canonicalized servo/servo#15397
|
||||
* test_shorthand_property_getters.html `should condense to canonical case` [2]
|
||||
* animation and transition shorthand serialization is wrong servo/servo#15398
|
||||
* test_shorthand_property_getters.html `transition` [5]
|
||||
* background-position invalid 3-value form **issue to be filed**
|
||||
* test_shorthand_property_getters.html `should serialize to 4-value` [2]
|
||||
* test_variables.html `--weird`: name of custom property is not escaped properly servo/servo#15399 [1]
|
||||
|
@ -10,20 +10,22 @@ import android.support.annotation.CheckResult;
|
||||
|
||||
import org.mozilla.gecko.GeckoAppShell;
|
||||
|
||||
import java.util.TreeSet;
|
||||
|
||||
import ch.boye.httpclientandroidlib.util.TextUtils;
|
||||
|
||||
/**
|
||||
* Builder for creating a request to load an icon.
|
||||
*/
|
||||
public class IconRequestBuilder {
|
||||
private final IconRequest request;
|
||||
private final IconRequest internal;
|
||||
|
||||
/* package-private */ IconRequestBuilder(Context context) {
|
||||
this(new IconRequest(context));
|
||||
internal = new IconRequest(context);
|
||||
}
|
||||
|
||||
/* package-private */ IconRequestBuilder(IconRequest request) {
|
||||
this.request = request;
|
||||
internal = request;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -31,7 +33,7 @@ public class IconRequestBuilder {
|
||||
*/
|
||||
@CheckResult
|
||||
public IconRequestBuilder pageUrl(String pageUrl) {
|
||||
request.pageUrl = pageUrl;
|
||||
internal.pageUrl = pageUrl;
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -43,7 +45,7 @@ public class IconRequestBuilder {
|
||||
*/
|
||||
@CheckResult
|
||||
public IconRequestBuilder privileged(boolean privileged) {
|
||||
request.privileged = privileged;
|
||||
internal.privileged = privileged;
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -54,7 +56,7 @@ public class IconRequestBuilder {
|
||||
*/
|
||||
@CheckResult
|
||||
public IconRequestBuilder icon(IconDescriptor descriptor) {
|
||||
request.icons.add(descriptor);
|
||||
internal.icons.add(descriptor);
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -63,7 +65,7 @@ public class IconRequestBuilder {
|
||||
*/
|
||||
@CheckResult
|
||||
public IconRequestBuilder skipNetwork() {
|
||||
request.skipNetwork = true;
|
||||
internal.skipNetwork = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -72,7 +74,7 @@ public class IconRequestBuilder {
|
||||
*/
|
||||
@CheckResult
|
||||
public IconRequestBuilder skipNetworkIf(boolean shouldSkipNetwork) {
|
||||
request.skipNetwork = shouldSkipNetwork;
|
||||
internal.skipNetwork = shouldSkipNetwork;
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -81,7 +83,7 @@ public class IconRequestBuilder {
|
||||
*/
|
||||
@CheckResult
|
||||
public IconRequestBuilder skipDisk() {
|
||||
request.skipDisk = true;
|
||||
internal.skipDisk = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -90,7 +92,7 @@ public class IconRequestBuilder {
|
||||
*/
|
||||
@CheckResult
|
||||
public IconRequestBuilder skipMemory() {
|
||||
request.skipMemory = true;
|
||||
internal.skipMemory = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -99,7 +101,7 @@ public class IconRequestBuilder {
|
||||
* preferred Android launcher icon size.
|
||||
*/
|
||||
public IconRequestBuilder forLauncherIcon() {
|
||||
request.targetSize = GeckoAppShell.getPreferredIconSize();
|
||||
internal.targetSize = GeckoAppShell.getPreferredIconSize();
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -109,7 +111,7 @@ public class IconRequestBuilder {
|
||||
*/
|
||||
@CheckResult
|
||||
public IconRequestBuilder executeCallbackOnBackgroundThread() {
|
||||
request.backgroundThread = true;
|
||||
internal.backgroundThread = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -119,7 +121,7 @@ public class IconRequestBuilder {
|
||||
* perform a lookup of the URL but doesn't want to load the icon yet.
|
||||
*/
|
||||
public IconRequestBuilder prepareOnly() {
|
||||
request.prepareOnly = true;
|
||||
internal.prepareOnly = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -128,10 +130,20 @@ public class IconRequestBuilder {
|
||||
*/
|
||||
@CheckResult
|
||||
public IconRequest build() {
|
||||
if (TextUtils.isEmpty(request.pageUrl)) {
|
||||
if (TextUtils.isEmpty(internal.pageUrl)) {
|
||||
throw new IllegalStateException("Page URL is required");
|
||||
}
|
||||
|
||||
IconRequest request = new IconRequest(internal.getContext());
|
||||
request.pageUrl = internal.pageUrl;
|
||||
request.privileged = internal.privileged;
|
||||
request.icons = new TreeSet<>(internal.icons);
|
||||
request.skipNetwork = internal.skipNetwork;
|
||||
request.backgroundThread = internal.backgroundThread;
|
||||
request.skipDisk = internal.skipDisk;
|
||||
request.skipMemory = internal.skipMemory;
|
||||
request.targetSize = internal.targetSize;
|
||||
request.prepareOnly = internal.prepareOnly;
|
||||
return request;
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,11 @@ import org.mozilla.gecko.GeckoAppShell;
|
||||
import org.mozilla.gecko.background.testhelpers.TestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
import java.util.ConcurrentModificationException;
|
||||
import java.util.Iterator;
|
||||
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
@RunWith(TestRunner.class)
|
||||
public class TestIconRequestBuilder {
|
||||
private static final String TEST_PAGE_URL_1 = "http://www.mozilla.org";
|
||||
@ -177,4 +182,38 @@ public class TestIconRequestBuilder {
|
||||
|
||||
Assert.assertEquals(48, request.getTargetSize());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConcurrentAccess() {
|
||||
IconRequestBuilder builder = Icons.with(RuntimeEnvironment.application)
|
||||
.pageUrl(TEST_PAGE_URL_1)
|
||||
.icon(IconDescriptor.createGenericIcon(TEST_ICON_URL_1))
|
||||
.icon(IconDescriptor.createGenericIcon(TEST_ICON_URL_2));
|
||||
|
||||
// Call build() twice on a builder and verify that the two objects are not the same
|
||||
IconRequest request = builder.build();
|
||||
IconRequest compare = builder.build();
|
||||
Assert.assertNotSame(request, compare);
|
||||
Assert.assertNotSame(request.icons, compare.icons);
|
||||
|
||||
// After building call methods on the builder and verify that the previously build object is not changed
|
||||
int iconCount = request.getIconCount();
|
||||
builder.icon(IconDescriptor.createGenericIcon(TEST_PAGE_URL_2))
|
||||
.deferBuild();
|
||||
int iconCountAfterBuild = request.getIconCount();
|
||||
Assert.assertEquals(iconCount, iconCountAfterBuild);
|
||||
|
||||
// Iterate the TreeSet and call methods on the builder
|
||||
try {
|
||||
final Iterator<IconDescriptor> iterator = request.icons.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
iterator.next();
|
||||
builder.icon(IconDescriptor.createGenericIcon(TEST_PAGE_URL_2))
|
||||
.deferBuild();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
fail("Got exception.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -166,7 +166,7 @@ DoOCSPRequest(const UniquePLArenaPool& arena, const char* url,
|
||||
if (!StringEndsWith(path, NS_LITERAL_CSTRING("/"))) {
|
||||
path.Append("/");
|
||||
}
|
||||
nsresult nsrv = AppendEscapedBase64Item(encodedRequest, path);
|
||||
nsrv = AppendEscapedBase64Item(encodedRequest, path);
|
||||
if (NS_WARN_IF(NS_FAILED(nsrv))) {
|
||||
return Result::FATAL_ERROR_LIBRARY_FAILURE;
|
||||
}
|
||||
|
@ -53,52 +53,60 @@ TEST_DIRS += [
|
||||
|
||||
CXXFLAGS += ['-Wall']
|
||||
if CONFIG['_MSC_VER']:
|
||||
# -Wall with Visual C++ enables too many problematic warnings
|
||||
CXXFLAGS += [
|
||||
'-wd4355', # 'this' used in base member initializer list
|
||||
'-wd4464', # relative include path contains '..'
|
||||
'-wd4480', # nonstandard extension used: specifying underlying type for
|
||||
# enum 'enum'
|
||||
'-wd4481', # nonstandard extension used: override specifier 'keyword'
|
||||
'-wd4510', # default constructor could not be generated
|
||||
'-wd4512', # assignment operator could not be generated
|
||||
'-wd4514', # 'function': unreferenced inline function has been removed
|
||||
'-wd4610', # struct 'symbol' can never be instantiated - user defined
|
||||
# constructor required
|
||||
'-wd4619', # pragma warning: there is no warning 'warning'
|
||||
'-wd4623', # default constructor could not be generated because a base
|
||||
# class default constructor is inaccessible or deleted
|
||||
'-wd4625', # copy constructor could not be generated because a base
|
||||
# class copy constructor is inaccessible or deleted
|
||||
'-wd4626', # assignment operator could not be generated because a base
|
||||
# class assignment operator is inaccessible or deleted
|
||||
'-wd4640', # construction of local static object is not thread-safe
|
||||
'-wd4710', # 'function': function not inlined
|
||||
'-wd4711', # function 'function' selected for inline expansion
|
||||
'-wd4820', # 'bytes' bytes padding added after construct 'member_name'
|
||||
]
|
||||
# -Wall with Visual C++ enables too many problematic warnings
|
||||
CXXFLAGS += [
|
||||
'-wd4355', # 'this' used in base member initializer list
|
||||
'-wd4464', # relative include path contains '..'
|
||||
'-wd4480', # nonstandard extension used: specifying underlying type for
|
||||
# enum 'enum'
|
||||
'-wd4481', # nonstandard extension used: override specifier 'keyword'
|
||||
'-wd4510', # default constructor could not be generated
|
||||
'-wd4512', # assignment operator could not be generated
|
||||
'-wd4514', # 'function': unreferenced inline function has been removed
|
||||
'-wd4610', # struct 'symbol' can never be instantiated - user defined
|
||||
# constructor required
|
||||
'-wd4619', # pragma warning: there is no warning 'warning'
|
||||
'-wd4623', # default constructor could not be generated because a base
|
||||
# class default constructor is inaccessible or deleted
|
||||
'-wd4625', # copy constructor could not be generated because a base
|
||||
# class copy constructor is inaccessible or deleted
|
||||
'-wd4626', # assignment operator could not be generated because a base
|
||||
# class assignment operator is inaccessible or deleted
|
||||
'-wd4640', # construction of local static object is not thread-safe
|
||||
'-wd4710', # 'function': function not inlined
|
||||
'-wd4711', # function 'function' selected for inline expansion
|
||||
'-wd4820', # 'bytes' bytes padding added after construct 'member_name'
|
||||
]
|
||||
|
||||
# MSVC 2010's headers trigger these
|
||||
CXXFLAGS += [
|
||||
'-wd4548', # expression before comma has no effect; ...
|
||||
'-wd4668', # 'symbol' is not defined as a preprocessor macro...
|
||||
'-wd4987', # nonstandard extension used
|
||||
]
|
||||
# MSVC 2010's headers trigger these
|
||||
CXXFLAGS += [
|
||||
'-wd4548', # expression before comma has no effect; ...
|
||||
'-wd4668', # 'symbol' is not defined as a preprocessor macro...
|
||||
'-wd4987', # nonstandard extension used
|
||||
]
|
||||
|
||||
# MSVC 2015 triggers these
|
||||
CXXFLAGS += [
|
||||
'-wd4456', # declaration of 'rv' hides previous local declaration
|
||||
'-wd4458', # declaration of 'input' hides class member
|
||||
]
|
||||
# MSVC 2015 triggers these
|
||||
CXXFLAGS += [
|
||||
'-wd4456', # declaration of 'rv' hides previous local declaration
|
||||
'-wd4458', # declaration of 'input' hides class member
|
||||
]
|
||||
|
||||
# Gecko headers aren't warning-free enough for us to enable these warnings
|
||||
CXXFLAGS += [
|
||||
'-wd4100', # 'symbol' : unreferenced formal parameter
|
||||
'-wd4127', # conditional expression is constant
|
||||
'-wd4946', # reinterpret_cast used between related types
|
||||
]
|
||||
# Gecko headers aren't warning-free enough for us to enable these warnings
|
||||
CXXFLAGS += [
|
||||
'-wd4100', # 'symbol' : unreferenced formal parameter
|
||||
'-wd4127', # conditional expression is constant
|
||||
'-wd4946', # reinterpret_cast used between related types
|
||||
]
|
||||
|
||||
if CONFIG['GNU_CXX']:
|
||||
CXXFLAGS += ['-Wno-error=shadow']
|
||||
CXXFLAGS += [
|
||||
'-Wextra',
|
||||
'-Wunreachable-code',
|
||||
]
|
||||
|
||||
# Gecko headers aren't warning-free enough for us to enable these warnings.
|
||||
CXXFLAGS += [
|
||||
'-Wno-unused-parameter',
|
||||
]
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
|
@ -23,7 +23,6 @@
|
||||
#include "nsNSSCertificate.h"
|
||||
#include "nsNSSComponent.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsPromiseFlatString.h"
|
||||
#include "nsStreamUtils.h"
|
||||
#include "nsStringBuffer.h"
|
||||
#include "nsThreadUtils.h"
|
||||
@ -35,45 +34,44 @@ using namespace mozilla::psm;
|
||||
#define CERT_OVERRIDE_FILE_NAME "cert_override.txt"
|
||||
|
||||
void
|
||||
nsCertOverride::convertBitsToString(OverrideBits ob, nsACString &str)
|
||||
nsCertOverride::convertBitsToString(OverrideBits ob, /*out*/ nsACString& str)
|
||||
{
|
||||
str.Truncate();
|
||||
|
||||
if (ob & ob_Mismatch)
|
||||
if (ob & OverrideBits::Mismatch) {
|
||||
str.Append('M');
|
||||
}
|
||||
|
||||
if (ob & ob_Untrusted)
|
||||
if (ob & OverrideBits::Untrusted) {
|
||||
str.Append('U');
|
||||
}
|
||||
|
||||
if (ob & ob_Time_error)
|
||||
if (ob & OverrideBits::Time) {
|
||||
str.Append('T');
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsCertOverride::convertStringToBits(const nsACString &str, OverrideBits &ob)
|
||||
nsCertOverride::convertStringToBits(const nsACString& str,
|
||||
/*out*/ OverrideBits& ob)
|
||||
{
|
||||
const nsPromiseFlatCString &flat = PromiseFlatCString(str);
|
||||
const char *walk = flat.get();
|
||||
ob = OverrideBits::None;
|
||||
|
||||
ob = ob_None;
|
||||
|
||||
for ( ; *walk; ++walk)
|
||||
{
|
||||
switch (*walk)
|
||||
{
|
||||
for (uint32_t i = 0; i < str.Length(); i++) {
|
||||
switch (str.CharAt(i)) {
|
||||
case 'm':
|
||||
case 'M':
|
||||
ob = (OverrideBits)(ob | ob_Mismatch);
|
||||
ob |= OverrideBits::Mismatch;
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
case 'U':
|
||||
ob = (OverrideBits)(ob | ob_Untrusted);
|
||||
ob |= OverrideBits::Untrusted;
|
||||
break;
|
||||
|
||||
case 't':
|
||||
case 'T':
|
||||
ob = (OverrideBits)(ob | ob_Time_error);
|
||||
ob |= OverrideBits::Time;
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -459,7 +457,7 @@ nsCertOverrideService::HasMatchingOverride(const nsACString & aHostName, int32_t
|
||||
NS_ENSURE_ARG_POINTER(aIsTemporary);
|
||||
NS_ENSURE_ARG_POINTER(_retval);
|
||||
*_retval = false;
|
||||
*aOverrideBits = nsCertOverride::ob_None;
|
||||
*aOverrideBits = static_cast<uint32_t>(nsCertOverride::OverrideBits::None);
|
||||
|
||||
nsAutoCString hostPort;
|
||||
GetHostWithPort(aHostName, aPort, hostPort);
|
||||
@ -475,7 +473,7 @@ nsCertOverrideService::HasMatchingOverride(const nsACString & aHostName, int32_t
|
||||
settings = entry->mSettings; // copy
|
||||
}
|
||||
|
||||
*aOverrideBits = settings.mOverrideBits;
|
||||
*aOverrideBits = static_cast<uint32_t>(settings.mOverrideBits);
|
||||
*aIsTemporary = settings.mIsTemporary;
|
||||
|
||||
nsAutoCString fpStr;
|
||||
@ -509,7 +507,7 @@ nsCertOverrideService::GetValidityOverride(const nsACString & aHostName, int32_t
|
||||
NS_ENSURE_ARG_POINTER(aIsTemporary);
|
||||
NS_ENSURE_ARG_POINTER(aOverrideBits);
|
||||
*_found = false;
|
||||
*aOverrideBits = nsCertOverride::ob_None;
|
||||
*aOverrideBits = static_cast<uint32_t>(nsCertOverride::OverrideBits::None);
|
||||
|
||||
nsAutoCString hostPort;
|
||||
GetHostWithPort(aHostName, aPort, hostPort);
|
||||
@ -526,7 +524,7 @@ nsCertOverrideService::GetValidityOverride(const nsACString & aHostName, int32_t
|
||||
}
|
||||
|
||||
if (*_found) {
|
||||
*aOverrideBits = settings.mOverrideBits;
|
||||
*aOverrideBits = static_cast<uint32_t>(settings.mOverrideBits);
|
||||
*aIsTemporary = settings.mIsTemporary;
|
||||
aFingerprint = settings.mFingerprint;
|
||||
aHashAlg = settings.mFingerprintAlgOID;
|
||||
|
@ -4,29 +4,32 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef __NSCERTOVERRIDESERVICE_H__
|
||||
#define __NSCERTOVERRIDESERVICE_H__
|
||||
#ifndef nsCertOverrideService_h
|
||||
#define nsCertOverrideService_h
|
||||
|
||||
#include "mozilla/ReentrantMonitor.h"
|
||||
#include "mozilla/TypedEnumBits.h"
|
||||
#include "nsICertOverrideService.h"
|
||||
#include "nsTHashtable.h"
|
||||
#include "nsIFile.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsString.h"
|
||||
#include "nsIFile.h"
|
||||
#include "secoidt.h"
|
||||
#include "nsTHashtable.h"
|
||||
#include "nsWeakReference.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "secoidt.h"
|
||||
|
||||
class nsCertOverride
|
||||
{
|
||||
public:
|
||||
|
||||
enum OverrideBits { ob_None=0, ob_Untrusted=1, ob_Mismatch=2,
|
||||
ob_Time_error=4 };
|
||||
enum class OverrideBits {
|
||||
None = 0,
|
||||
Untrusted = nsICertOverrideService::ERROR_UNTRUSTED,
|
||||
Mismatch = nsICertOverrideService::ERROR_MISMATCH,
|
||||
Time = nsICertOverrideService::ERROR_TIME,
|
||||
};
|
||||
|
||||
nsCertOverride()
|
||||
:mPort(-1)
|
||||
,mOverrideBits(ob_None)
|
||||
: mPort(-1)
|
||||
, mOverrideBits(OverrideBits::None)
|
||||
{
|
||||
}
|
||||
|
||||
@ -61,6 +64,7 @@ public:
|
||||
static void convertStringToBits(const nsACString &str, OverrideBits &ob);
|
||||
};
|
||||
|
||||
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(nsCertOverride::OverrideBits)
|
||||
|
||||
// hash entry class
|
||||
class nsCertOverrideEntry final : public PLDHashEntryHdr
|
||||
@ -184,4 +188,4 @@ protected:
|
||||
{0x95, 0x2c, 0x2e, 0xe3, 0x37, 0xff, 0xdc, 0xd6} \
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif // nsCertOverrideService_h
|
||||
|
@ -95,11 +95,11 @@ NS_IMPL_ISUPPORTS0(nsCertAddonInfo)
|
||||
NS_IMPL_ISUPPORTS(nsCertTreeDispInfo, nsICertTreeItem)
|
||||
|
||||
nsCertTreeDispInfo::nsCertTreeDispInfo()
|
||||
:mAddonInfo(nullptr)
|
||||
,mTypeOfEntry(direct_db)
|
||||
,mPort(-1)
|
||||
,mOverrideBits(nsCertOverride::ob_None)
|
||||
,mIsTemporary(true)
|
||||
: mAddonInfo(nullptr)
|
||||
, mTypeOfEntry(direct_db)
|
||||
, mPort(-1)
|
||||
, mOverrideBits(nsCertOverride::OverrideBits::None)
|
||||
, mIsTemporary(true)
|
||||
{
|
||||
}
|
||||
|
||||
@ -572,7 +572,7 @@ nsCertTree::GetCertsByTypeFromCertList(CERTCertList *aCertList,
|
||||
certai->mUsageCount++;
|
||||
certdi->mTypeOfEntry = nsCertTreeDispInfo::direct_db;
|
||||
// not necessary: certdi->mAsciiHost.Clear(); certdi->mPort = -1;
|
||||
certdi->mOverrideBits = nsCertOverride::ob_None;
|
||||
certdi->mOverrideBits = nsCertOverride::OverrideBits::None;
|
||||
certdi->mIsTemporary = false;
|
||||
mDispInfo.InsertElementAt(InsertPosition, certdi);
|
||||
++count;
|
||||
|
66
servo/Cargo.lock
generated
66
servo/Cargo.lock
generated
@ -283,7 +283,7 @@ dependencies = [
|
||||
"num-traits 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"offscreen_gl_context 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"servo_config 0.0.1",
|
||||
"webrender_traits 0.18.0 (git+https://github.com/servo/webrender)",
|
||||
"webrender_traits 0.20.0 (git+https://github.com/servo/webrender)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -297,7 +297,7 @@ dependencies = [
|
||||
"ipc-channel 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"webrender_traits 0.18.0 (git+https://github.com/servo/webrender)",
|
||||
"webrender_traits 0.20.0 (git+https://github.com/servo/webrender)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -418,8 +418,8 @@ dependencies = [
|
||||
"servo_url 0.0.1",
|
||||
"style_traits 0.0.1",
|
||||
"time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"webrender 0.18.0 (git+https://github.com/servo/webrender)",
|
||||
"webrender_traits 0.18.0 (git+https://github.com/servo/webrender)",
|
||||
"webrender 0.19.0 (git+https://github.com/servo/webrender)",
|
||||
"webrender_traits 0.20.0 (git+https://github.com/servo/webrender)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -452,7 +452,7 @@ dependencies = [
|
||||
"servo_remutex 0.0.1",
|
||||
"servo_url 0.0.1",
|
||||
"style_traits 0.0.1",
|
||||
"webrender_traits 0.18.0 (git+https://github.com/servo/webrender)",
|
||||
"webrender_traits 0.20.0 (git+https://github.com/servo/webrender)",
|
||||
"webvr_traits 0.0.1",
|
||||
]
|
||||
|
||||
@ -569,7 +569,7 @@ name = "debugger"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ws 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ws 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -586,7 +586,7 @@ name = "deny_public_fields"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"syn 0.10.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"synstructure 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"synstructure 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -691,7 +691,7 @@ dependencies = [
|
||||
"servo_geometry 0.0.1",
|
||||
"servo_url 0.0.1",
|
||||
"style_traits 0.0.1",
|
||||
"webrender_traits 0.18.0 (git+https://github.com/servo/webrender)",
|
||||
"webrender_traits 0.20.0 (git+https://github.com/servo/webrender)",
|
||||
"x11 2.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@ -978,7 +978,7 @@ dependencies = [
|
||||
"time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"truetype 0.26.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-script 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"webrender_traits 0.18.0 (git+https://github.com/servo/webrender)",
|
||||
"webrender_traits 0.20.0 (git+https://github.com/servo/webrender)",
|
||||
"xi-unicode 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@ -1057,7 +1057,7 @@ dependencies = [
|
||||
"servo_url 0.0.1",
|
||||
"style_traits 0.0.1",
|
||||
"user32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"webrender_traits 0.18.0 (git+https://github.com/servo/webrender)",
|
||||
"webrender_traits 0.20.0 (git+https://github.com/servo/webrender)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"x11 2.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@ -1097,7 +1097,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"quote 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.10.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"synstructure 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"synstructure 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1298,7 +1298,7 @@ version = "0.0.1"
|
||||
dependencies = [
|
||||
"quote 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.10.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"synstructure 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"synstructure 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1359,7 +1359,7 @@ dependencies = [
|
||||
"style_traits 0.0.1",
|
||||
"unicode-bidi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-script 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"webrender_traits 0.18.0 (git+https://github.com/servo/webrender)",
|
||||
"webrender_traits 0.20.0 (git+https://github.com/servo/webrender)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1399,7 +1399,7 @@ dependencies = [
|
||||
"servo_geometry 0.0.1",
|
||||
"servo_url 0.0.1",
|
||||
"style 0.0.1",
|
||||
"webrender_traits 0.18.0 (git+https://github.com/servo/webrender)",
|
||||
"webrender_traits 0.20.0 (git+https://github.com/servo/webrender)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1413,7 +1413,7 @@ dependencies = [
|
||||
"profile_traits 0.0.1",
|
||||
"script_traits 0.0.1",
|
||||
"servo_url 0.0.1",
|
||||
"webrender_traits 0.18.0 (git+https://github.com/servo/webrender)",
|
||||
"webrender_traits 0.20.0 (git+https://github.com/servo/webrender)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1498,8 +1498,8 @@ dependencies = [
|
||||
"style 0.0.1",
|
||||
"style_traits 0.0.1",
|
||||
"webdriver_server 0.0.1",
|
||||
"webrender 0.18.0 (git+https://github.com/servo/webrender)",
|
||||
"webrender_traits 0.18.0 (git+https://github.com/servo/webrender)",
|
||||
"webrender 0.19.0 (git+https://github.com/servo/webrender)",
|
||||
"webrender_traits 0.20.0 (git+https://github.com/servo/webrender)",
|
||||
"webvr 0.0.1",
|
||||
"webvr_traits 0.0.1",
|
||||
]
|
||||
@ -1646,7 +1646,7 @@ dependencies = [
|
||||
"heapsize_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"webrender_traits 0.18.0 (git+https://github.com/servo/webrender)",
|
||||
"webrender_traits 0.20.0 (git+https://github.com/servo/webrender)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1684,7 +1684,7 @@ dependencies = [
|
||||
"unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"url 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"uuid 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"webrender_traits 0.18.0 (git+https://github.com/servo/webrender)",
|
||||
"webrender_traits 0.20.0 (git+https://github.com/servo/webrender)",
|
||||
"websocket 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@ -1743,7 +1743,7 @@ dependencies = [
|
||||
"servo_url 0.0.1",
|
||||
"url 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"uuid 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"webrender_traits 0.18.0 (git+https://github.com/servo/webrender)",
|
||||
"webrender_traits 0.20.0 (git+https://github.com/servo/webrender)",
|
||||
"websocket 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@ -2277,7 +2277,7 @@ dependencies = [
|
||||
"tinyfiledialogs 2.5.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"url 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"uuid 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"webrender_traits 0.18.0 (git+https://github.com/servo/webrender)",
|
||||
"webrender_traits 0.20.0 (git+https://github.com/servo/webrender)",
|
||||
"websocket 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"webvr 0.0.1",
|
||||
"webvr_traits 0.0.1",
|
||||
@ -2851,7 +2851,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "synstructure"
|
||||
version = "0.4.1"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"quote 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -3187,8 +3187,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "webrender"
|
||||
version = "0.18.0"
|
||||
source = "git+https://github.com/servo/webrender#e41f1413222d0b9f594649ac993a3e9e0ba35cbe"
|
||||
version = "0.19.0"
|
||||
source = "git+https://github.com/servo/webrender#fc720d070f4af24a1def4a6510cee10aaad0a280"
|
||||
dependencies = [
|
||||
"app_units 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bincode 1.0.0-alpha2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -3210,13 +3210,13 @@ dependencies = [
|
||||
"thread_profiler 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"threadpool 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"webrender_traits 0.18.0 (git+https://github.com/servo/webrender)",
|
||||
"webrender_traits 0.20.0 (git+https://github.com/servo/webrender)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "webrender_traits"
|
||||
version = "0.18.0"
|
||||
source = "git+https://github.com/servo/webrender#e41f1413222d0b9f594649ac993a3e9e0ba35cbe"
|
||||
version = "0.20.0"
|
||||
source = "git+https://github.com/servo/webrender#fc720d070f4af24a1def4a6510cee10aaad0a280"
|
||||
dependencies = [
|
||||
"app_units 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -3256,7 +3256,7 @@ dependencies = [
|
||||
"msg 0.0.1",
|
||||
"script_traits 0.0.1",
|
||||
"servo_config 0.0.1",
|
||||
"webrender_traits 0.18.0 (git+https://github.com/servo/webrender)",
|
||||
"webrender_traits 0.20.0 (git+https://github.com/servo/webrender)",
|
||||
"webvr_traits 0.0.1",
|
||||
]
|
||||
|
||||
@ -3272,7 +3272,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "ws"
|
||||
version = "0.5.4"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bytes 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -3559,7 +3559,7 @@ dependencies = [
|
||||
"checksum syn 0.10.8 (registry+https://github.com/rust-lang/crates.io-index)" = "58fd09df59565db3399efbba34ba8a2fec1307511ebd245d0061ff9d42691673"
|
||||
"checksum syn 0.11.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0e28da8d02d75d1e58b89258e0741128f0b0d8a8309fb5c627be0fbd37a76c67"
|
||||
"checksum synom 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8fece1853fb872b0acdc3ff88f37c474018e125ef81cd4cb8c0ca515746b62ed"
|
||||
"checksum synstructure 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a811f8e51453cada27c033be6b5fdac6e4e63981983702eb85b4c897a25ecc6c"
|
||||
"checksum synstructure 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e13808dc5a739d5ff1cff4a2361afdf4ec52d42221c7ddc1d8c438f5a53746a7"
|
||||
"checksum syntex 0.54.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb3f52553a966675982404dc34028291b347e0c9a9c0b0b34f2da6be8a0443f8"
|
||||
"checksum syntex_errors 0.54.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dee2f6e49c075f71332bb775219d5982bee6732d26227fa1ae1b53cdb12f5cc5"
|
||||
"checksum syntex_pos 0.54.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8df3921c7945dfb9ffc53aa35adb2cf4313b5ab5f079c3619b3d4eb82a0efc2b"
|
||||
@ -3597,12 +3597,12 @@ dependencies = [
|
||||
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
|
||||
"checksum walkdir 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "bb08f9e670fab86099470b97cd2b252d6527f0b3cc1401acdb595ffc9dd288ff"
|
||||
"checksum webdriver 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cdc28802daddee94267a657ffeac2593a33881fb7a3a44fedd320b1319efcaf6"
|
||||
"checksum webrender 0.18.0 (git+https://github.com/servo/webrender)" = "<none>"
|
||||
"checksum webrender_traits 0.18.0 (git+https://github.com/servo/webrender)" = "<none>"
|
||||
"checksum webrender 0.19.0 (git+https://github.com/servo/webrender)" = "<none>"
|
||||
"checksum webrender_traits 0.20.0 (git+https://github.com/servo/webrender)" = "<none>"
|
||||
"checksum websocket 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4a1a6ea5ed0367f32eb3d94dcc58859ef4294b5f75ba983dbf56ac314af45d"
|
||||
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
|
||||
"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
|
||||
"checksum ws 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "97d37277cc93aa9f313a6e2363576988714f0e7f147179bb8f272ceb3e4a83b1"
|
||||
"checksum ws 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "04614a58714f3fd4a8b1da4bcae9f031c532d35988c3d39627619248113f8be8"
|
||||
"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"
|
||||
"checksum x11 2.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "124eb405bf0262a54e1a982d4ffe4cd1c24261bdb306e49996e2ce7d492284a8"
|
||||
"checksum x11-dl 2.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bf1f9986368c9bbdd8191a783a7ceb42e0c9c6d3348616c873f829b3288a139c"
|
||||
|
@ -106,7 +106,7 @@ impl<'a> CanvasPaintThread<'a> {
|
||||
let draw_target = CanvasPaintThread::create(size);
|
||||
let path_builder = draw_target.create_path_builder();
|
||||
let webrender_api = webrender_api_sender.create_api();
|
||||
let webrender_image_key = webrender_api.alloc_image();
|
||||
let webrender_image_key = webrender_api.generate_image_key();
|
||||
CanvasPaintThread {
|
||||
drawtarget: draw_target,
|
||||
path_builder: path_builder,
|
||||
@ -564,6 +564,7 @@ impl<'a> CanvasPaintThread<'a> {
|
||||
height: size.height as u32,
|
||||
stride: None,
|
||||
format: webrender_traits::ImageFormat::RGBA8,
|
||||
offset: 0,
|
||||
is_opaque: false,
|
||||
},
|
||||
element.into());
|
||||
|
@ -101,7 +101,7 @@ fn create_readback_painter(size: Size2D<i32>,
|
||||
-> Result<(WebGLPaintThread, GLLimits), String> {
|
||||
let context = try!(GLContextWrapper::new(size, attrs));
|
||||
let limits = context.get_limits();
|
||||
let image_key = webrender_api.alloc_image();
|
||||
let image_key = webrender_api.generate_image_key();
|
||||
let painter = WebGLPaintThread {
|
||||
size: size,
|
||||
data: WebGLPaintTaskData::Readback(context, webrender_api, image_key)
|
||||
@ -241,6 +241,7 @@ impl WebGLPaintThread {
|
||||
height: height as u32,
|
||||
stride: None,
|
||||
format: webrender_traits::ImageFormat::RGBA8,
|
||||
offset: 0,
|
||||
is_opaque: false,
|
||||
},
|
||||
pixels.clone());
|
||||
|
@ -14,4 +14,4 @@ crate_type = ["rlib"]
|
||||
log = "0.3.5"
|
||||
|
||||
[target.'cfg(not(target_os = "android"))'.dependencies]
|
||||
ws = "0.5.3"
|
||||
ws = "0.6"
|
||||
|
@ -346,11 +346,13 @@ impl FontCache {
|
||||
if let Some(ref webrender_api) = self.webrender_api {
|
||||
let webrender_fonts = &mut self.webrender_fonts;
|
||||
font_key = Some(*webrender_fonts.entry(template.identifier.clone()).or_insert_with(|| {
|
||||
let font_key = webrender_api.generate_font_key();
|
||||
match (template.bytes_if_in_memory(), template.native_font()) {
|
||||
(Some(bytes), _) => webrender_api.add_raw_font(bytes),
|
||||
(None, Some(native_font)) => webrender_api.add_native_font(native_font),
|
||||
(None, None) => webrender_api.add_raw_font(template.bytes().clone()),
|
||||
(Some(bytes), _) => webrender_api.add_raw_font(font_key, bytes),
|
||||
(None, Some(native_font)) => webrender_api.add_native_font(font_key, native_font),
|
||||
(None, None) => webrender_api.add_raw_font(font_key, template.bytes().clone()),
|
||||
}
|
||||
font_key
|
||||
}));
|
||||
}
|
||||
|
||||
|
@ -934,7 +934,7 @@ impl LayoutThread {
|
||||
Some(get_root_flow_background_color(layout_root)),
|
||||
webrender_traits::Epoch(epoch_number),
|
||||
viewport_size,
|
||||
builder,
|
||||
builder.finalize(),
|
||||
true);
|
||||
self.webrender_api.generate_frame(None);
|
||||
});
|
||||
|
@ -326,10 +326,13 @@ fn get_placeholder_image(webrender_api: &webrender_traits::RenderApi) -> io::Res
|
||||
height: image.height,
|
||||
stride: None,
|
||||
format: format,
|
||||
offset: 0,
|
||||
is_opaque: is_image_opaque(format, &bytes),
|
||||
};
|
||||
let data = webrender_traits::ImageData::new(bytes);
|
||||
image.id = Some(webrender_api.add_image(descriptor, data));
|
||||
let image_key = webrender_api.generate_image_key();
|
||||
webrender_api.add_image(image_key, descriptor, data, None);
|
||||
image.id = Some(image_key);
|
||||
Ok(Arc::new(image))
|
||||
}
|
||||
|
||||
@ -486,10 +489,13 @@ impl ImageCache {
|
||||
height: image.height,
|
||||
stride: None,
|
||||
format: format,
|
||||
offset: 0,
|
||||
is_opaque: is_image_opaque(format, &bytes),
|
||||
};
|
||||
let data = webrender_traits::ImageData::new(bytes);
|
||||
image.id = Some(self.webrender_api.add_image(descriptor, data));
|
||||
let image_key = self.webrender_api.generate_image_key();
|
||||
self.webrender_api.add_image(image_key, descriptor, data, None);
|
||||
image.id = Some(image_key);
|
||||
}
|
||||
LoadResult::PlaceholderLoaded(..) | LoadResult::None => {}
|
||||
}
|
||||
|
@ -218,7 +218,7 @@ impl CSSStyleDeclaration {
|
||||
|
||||
let mut string = String::new();
|
||||
|
||||
self.owner.with_block(|ref pdb| {
|
||||
self.owner.with_block(|pdb| {
|
||||
pdb.property_value_to_css(&id, &mut string).unwrap();
|
||||
});
|
||||
|
||||
@ -281,7 +281,7 @@ impl CSSStyleDeclaration {
|
||||
impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
|
||||
// https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-length
|
||||
fn Length(&self) -> u32 {
|
||||
self.owner.with_block(|ref pdb| {
|
||||
self.owner.with_block(|pdb| {
|
||||
pdb.declarations.len() as u32
|
||||
})
|
||||
}
|
||||
@ -311,7 +311,7 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
|
||||
return DOMString::new()
|
||||
};
|
||||
|
||||
self.owner.with_block(|ref pdb| {
|
||||
self.owner.with_block(|pdb| {
|
||||
if pdb.property_priority(&id).important() {
|
||||
DOMString::from("important")
|
||||
} else {
|
||||
@ -406,7 +406,7 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
|
||||
|
||||
// https://dev.w3.org/csswg/cssom/#the-cssstyledeclaration-interface
|
||||
fn IndexedGetter(&self, index: u32) -> Option<DOMString> {
|
||||
self.owner.with_block(|ref pdb| {
|
||||
self.owner.with_block(|pdb| {
|
||||
pdb.declarations.get(index as usize).map(|entry| {
|
||||
let (ref declaration, importance) = *entry;
|
||||
let mut css = declaration.to_css_string();
|
||||
@ -420,7 +420,7 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
|
||||
|
||||
// https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-csstext
|
||||
fn CssText(&self) -> DOMString {
|
||||
self.owner.with_block(|ref pdb| {
|
||||
self.owner.with_block(|pdb| {
|
||||
DOMString::from(pdb.to_css_string())
|
||||
})
|
||||
}
|
||||
|
@ -1,53 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use rustc::lint::{EarlyContext, LintPass, LintArray, EarlyLintPass, LintContext};
|
||||
use syntax::ast::Ty;
|
||||
use utils::match_ty_unwrap;
|
||||
|
||||
declare_lint!(BANNED_TYPE, Deny,
|
||||
"Ban various unsafe type combinations");
|
||||
|
||||
/// Lint for banning various unsafe types
|
||||
///
|
||||
/// Banned types:
|
||||
///
|
||||
/// - `Cell<JSVal>`
|
||||
/// - `Cell<JS<T>>`
|
||||
pub struct BanPass;
|
||||
|
||||
impl LintPass for BanPass {
|
||||
fn get_lints(&self) -> LintArray {
|
||||
lint_array!(BANNED_TYPE)
|
||||
}
|
||||
}
|
||||
|
||||
impl EarlyLintPass for BanPass {
|
||||
fn check_ty(&mut self, cx: &EarlyContext, ty: &Ty) {
|
||||
if match_ty_unwrap(ty, &["std", "cell", "Cell"])
|
||||
.and_then(|t| t.get(0))
|
||||
.and_then(|t| match_ty_unwrap(&**t, &["dom", "bindings", "js", "JS"]))
|
||||
.is_some() {
|
||||
cx.span_lint(BANNED_TYPE, ty.span, "Banned type Cell<JS<T>> detected. Use MutJS<JS<T>> instead")
|
||||
}
|
||||
if match_ty_unwrap(ty, &["std", "cell", "Cell"])
|
||||
.and_then(|t| t.get(0))
|
||||
.and_then(|t| match_ty_unwrap(&**t, &["js", "jsval", "JSVal"]))
|
||||
.is_some() {
|
||||
cx.span_lint(BANNED_TYPE, ty.span, "Banned type Cell<JSVal> detected. Use MutJS<JSVal> instead")
|
||||
}
|
||||
if match_ty_unwrap(ty, &["dom", "bindings", "cell", "DOMRefCell"])
|
||||
.and_then(|t| t.get(0))
|
||||
.and_then(|t| match_ty_unwrap(&**t, &["dom", "bindings", "js", "JS"]))
|
||||
.is_some() {
|
||||
cx.span_lint(BANNED_TYPE, ty.span, "Banned type DOMRefCell<JS<T>> detected. Use MutJS<JS<T>> instead")
|
||||
}
|
||||
if match_ty_unwrap(ty, &["dom", "bindings", "cell", "DOMRefCell"])
|
||||
.and_then(|t| t.get(0))
|
||||
.and_then(|t| match_ty_unwrap(&**t, &["js", "jsapi", "Heap"]))
|
||||
.is_some() {
|
||||
cx.span_lint(BANNED_TYPE, ty.span, "Banned type DOMRefCell<Heap<T>> detected. Use Heap<T> directly instead")
|
||||
}
|
||||
}
|
||||
}
|
@ -25,7 +25,6 @@ extern crate syntax;
|
||||
use rustc_plugin::Registry;
|
||||
use syntax::feature_gate::AttributeType::Whitelisted;
|
||||
|
||||
mod ban;
|
||||
mod unrooted_must_root;
|
||||
/// Utilities for writing plugins
|
||||
mod utils;
|
||||
@ -33,7 +32,6 @@ mod utils;
|
||||
#[plugin_registrar]
|
||||
pub fn plugin_registrar(reg: &mut Registry) {
|
||||
reg.register_late_lint_pass(box unrooted_must_root::UnrootedPass::new());
|
||||
reg.register_early_lint_pass(box ban::BanPass);
|
||||
reg.register_attribute("allow_unrooted_interior".to_string(), Whitelisted);
|
||||
reg.register_attribute("must_root".to_string(), Whitelisted);
|
||||
}
|
||||
|
@ -12,10 +12,10 @@ use parking_lot::RwLock;
|
||||
use parser::{ParserContext, ParserContextExtraData, log_css_error};
|
||||
use properties::{Importance, PropertyDeclaration, PropertyDeclarationBlock, PropertyId};
|
||||
use properties::{PropertyDeclarationId, LonghandId, DeclaredValue};
|
||||
use properties::LonghandIdSet;
|
||||
use properties::PropertyDeclarationParseResult;
|
||||
use properties::animated_properties::TransitionProperty;
|
||||
use properties::longhands::transition_timing_function::single_value::SpecifiedValue as SpecifiedTimingFunction;
|
||||
use properties::property_bit_field::PropertyBitField;
|
||||
use std::fmt;
|
||||
use std::sync::Arc;
|
||||
use style_traits::ToCss;
|
||||
@ -248,7 +248,7 @@ pub struct KeyframesAnimation {
|
||||
/// Get all the animated properties in a keyframes animation.
|
||||
fn get_animated_properties(keyframes: &[Arc<RwLock<Keyframe>>]) -> Vec<TransitionProperty> {
|
||||
let mut ret = vec![];
|
||||
let mut seen = PropertyBitField::new();
|
||||
let mut seen = LonghandIdSet::new();
|
||||
// NB: declarations are already deduplicated, so we don't have to check for
|
||||
// it here.
|
||||
for keyframe in keyframes {
|
||||
|
@ -274,6 +274,39 @@ impl PropertyDeclarationBlock {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Only keep the "winning" declaration for any given property, by importance then source order.
|
||||
pub fn deduplicate(&mut self) {
|
||||
let mut deduplicated = Vec::with_capacity(self.declarations.len());
|
||||
let mut seen_normal = PropertyDeclarationIdSet::new();
|
||||
let mut seen_important = PropertyDeclarationIdSet::new();
|
||||
|
||||
for (declaration, importance) in self.declarations.drain(..).rev() {
|
||||
if importance.important() {
|
||||
let id = declaration.id();
|
||||
if seen_important.contains(id) {
|
||||
self.important_count -= 1;
|
||||
continue
|
||||
}
|
||||
if seen_normal.contains(id) {
|
||||
let previous_len = deduplicated.len();
|
||||
deduplicated.retain(|&(ref d, _)| PropertyDeclaration::id(d) != id);
|
||||
debug_assert_eq!(deduplicated.len(), previous_len - 1);
|
||||
}
|
||||
seen_important.insert(id);
|
||||
} else {
|
||||
let id = declaration.id();
|
||||
if seen_normal.contains(id) ||
|
||||
seen_important.contains(id) {
|
||||
continue
|
||||
}
|
||||
seen_normal.insert(id)
|
||||
}
|
||||
deduplicated.push((declaration, importance))
|
||||
}
|
||||
deduplicated.reverse();
|
||||
self.declarations = deduplicated;
|
||||
}
|
||||
}
|
||||
|
||||
impl ToCss for PropertyDeclarationBlock {
|
||||
@ -612,6 +645,6 @@ pub fn parse_property_declaration_list(context: &ParserContext,
|
||||
declarations: iter.parser.declarations,
|
||||
important_count: important_count,
|
||||
};
|
||||
super::deduplicate_property_declarations(&mut block);
|
||||
block.deduplicate();
|
||||
block
|
||||
}
|
||||
|
@ -159,10 +159,6 @@ impl ComputedValues {
|
||||
!self.get_box().gecko.mBinding.mRawPtr.is_null()
|
||||
}
|
||||
|
||||
pub fn root_font_size(&self) -> Au { self.root_font_size }
|
||||
pub fn set_root_font_size(&mut self, s: Au) { self.root_font_size = s; }
|
||||
pub fn set_writing_mode(&mut self, mode: WritingMode) { self.writing_mode = mode; }
|
||||
|
||||
// FIXME(bholley): Implement this properly.
|
||||
#[inline]
|
||||
pub fn is_multicol(&self) -> bool { false }
|
||||
@ -1247,9 +1243,6 @@ fn static_assert() {
|
||||
unsafe { transmute(self.gecko.mFont.weight) }
|
||||
}
|
||||
|
||||
// This is used for PartialEq, which we don't implement for gecko style structs.
|
||||
pub fn compute_font_hash(&mut self) {}
|
||||
|
||||
pub fn set_font_synthesis(&mut self, v: longhands::font_synthesis::computed_value::T) {
|
||||
use gecko_bindings::structs::{NS_FONT_SYNTHESIS_WEIGHT, NS_FONT_SYNTHESIS_STYLE};
|
||||
|
||||
|
@ -230,7 +230,7 @@
|
||||
use cascade_info::CascadeInfo;
|
||||
use error_reporting::ParseErrorReporter;
|
||||
use properties::longhands;
|
||||
use properties::property_bit_field::PropertyBitField;
|
||||
use properties::LonghandIdSet;
|
||||
use properties::{ComputedValues, PropertyDeclaration};
|
||||
use properties::style_structs;
|
||||
use std::boxed::Box as StdBox;
|
||||
@ -245,7 +245,6 @@
|
||||
inherited_style: &ComputedValues,
|
||||
default_style: &Arc<ComputedValues>,
|
||||
context: &mut computed::Context,
|
||||
seen: &mut PropertyBitField,
|
||||
cacheable: &mut bool,
|
||||
cascade_info: &mut Option<<&mut CascadeInfo>,
|
||||
error_reporter: &mut StdBox<ParseErrorReporter + Send>) {
|
||||
@ -256,16 +255,7 @@
|
||||
_ => panic!("entered the wrong cascade_property() implementation"),
|
||||
};
|
||||
|
||||
% if property.logical:
|
||||
let wm = context.style.writing_mode;
|
||||
% endif
|
||||
<% maybe_wm = "wm" if property.logical else "" %>
|
||||
<% maybe_physical = "_physical" if property.logical else "" %>
|
||||
% if not property.derived_from:
|
||||
if seen.get${maybe_physical}_${property.ident}(${maybe_wm}) {
|
||||
return
|
||||
}
|
||||
seen.set${maybe_physical}_${property.ident}(${maybe_wm});
|
||||
{
|
||||
let custom_props = context.style().custom_properties();
|
||||
::properties::substitute_variables_${property.ident}(
|
||||
@ -275,6 +265,9 @@
|
||||
cascade_info.on_cascade_property(&declaration,
|
||||
&value);
|
||||
}
|
||||
% if property.logical:
|
||||
let wm = context.style.writing_mode;
|
||||
% endif
|
||||
<% maybe_wm = ", wm" if property.logical else "" %>
|
||||
match *value {
|
||||
DeclaredValue::Value(ref specified_value) => {
|
||||
@ -321,7 +314,6 @@
|
||||
cascade_property_custom(declaration,
|
||||
inherited_style,
|
||||
context,
|
||||
seen,
|
||||
cacheable,
|
||||
error_reporter);
|
||||
% endif
|
||||
|
@ -84,7 +84,6 @@
|
||||
fn cascade_property_custom(_declaration: &PropertyDeclaration,
|
||||
_inherited_style: &ComputedValues,
|
||||
context: &mut computed::Context,
|
||||
_seen: &mut PropertyBitField,
|
||||
_cacheable: &mut bool,
|
||||
_error_reporter: &mut StdBox<ParseErrorReporter + Send>) {
|
||||
longhands::_servo_display_for_hypothetical_box::derive_from_display(context);
|
||||
|
@ -487,7 +487,7 @@ pub fn parse_origin(context: &ParserContext, input: &mut Parser) -> Result<Origi
|
||||
}
|
||||
Ok(())
|
||||
}) {
|
||||
match LengthOrPercentage::parse(context, input) {
|
||||
match input.try(|input| LengthOrPercentage::parse(context, input)) {
|
||||
Ok(value) => {
|
||||
if horizontal.is_none() {
|
||||
horizontal = Some(value);
|
||||
|
@ -6,8 +6,7 @@
|
||||
<% from data import Method %>
|
||||
|
||||
<% data.new_style_struct("Font",
|
||||
inherited=True,
|
||||
additional_methods=[Method("compute_font_hash", is_mut=True)]) %>
|
||||
inherited=True) %>
|
||||
<%helpers:longhand name="font-family" animatable="False" need_index="True"
|
||||
spec="https://drafts.csswg.org/css-fonts/#propdef-font-family">
|
||||
use self::computed_value::{FontFamily, FamilyName};
|
||||
|
@ -204,7 +204,6 @@ ${helpers.single_keyword("unicode-bidi",
|
||||
fn cascade_property_custom(_declaration: &PropertyDeclaration,
|
||||
_inherited_style: &ComputedValues,
|
||||
context: &mut computed::Context,
|
||||
_seen: &mut PropertyBitField,
|
||||
_cacheable: &mut bool,
|
||||
_error_reporter: &mut StdBox<ParseErrorReporter + Send>) {
|
||||
longhands::_servo_text_decorations_in_effect::derive_from_text_decoration(context);
|
||||
|
@ -29,6 +29,7 @@ use font_metrics::FontMetricsProvider;
|
||||
#[cfg(feature = "servo")] use logical_geometry::{LogicalMargin, PhysicalSide};
|
||||
use logical_geometry::WritingMode;
|
||||
use parser::{Parse, ParserContext, ParserContextExtraData};
|
||||
use properties::animated_properties::TransitionProperty;
|
||||
#[cfg(feature = "servo")] use servo_config::prefs::PREFS;
|
||||
use servo_url::ServoUrl;
|
||||
use style_traits::ToCss;
|
||||
@ -39,7 +40,6 @@ use cascade_info::CascadeInfo;
|
||||
use rule_tree::StrongRuleNode;
|
||||
#[cfg(feature = "servo")] use values::specified::BorderStyle;
|
||||
|
||||
use self::property_bit_field::PropertyBitField;
|
||||
pub use self::declaration_block::*;
|
||||
|
||||
#[cfg(feature = "gecko")]
|
||||
@ -178,92 +178,92 @@ pub mod animated_properties {
|
||||
<%include file="/helpers/animated_properties.mako.rs" />
|
||||
}
|
||||
|
||||
/// A set of longhand properties
|
||||
pub struct LonghandIdSet {
|
||||
storage: [u32; (${len(data.longhands)} - 1 + 32) / 32]
|
||||
}
|
||||
|
||||
// TODO(SimonSapin): Convert this to a syntax extension rather than a Mako template.
|
||||
// Maybe submit for inclusion in libstd?
|
||||
#[allow(missing_docs)]
|
||||
pub mod property_bit_field {
|
||||
use logical_geometry::WritingMode;
|
||||
use properties::animated_properties::TransitionProperty;
|
||||
|
||||
/// A bitfield for all longhand properties, in order to quickly test whether
|
||||
/// we've seen one of them.
|
||||
pub struct PropertyBitField {
|
||||
storage: [u32; (${len(data.longhands)} - 1 + 32) / 32]
|
||||
impl LonghandIdSet {
|
||||
/// Create an empty set
|
||||
#[inline]
|
||||
pub fn new() -> LonghandIdSet {
|
||||
LonghandIdSet { storage: [0; (${len(data.longhands)} - 1 + 32) / 32] }
|
||||
}
|
||||
|
||||
impl PropertyBitField {
|
||||
/// Create a new `PropertyBitField`, with all the bits set to zero.
|
||||
#[inline]
|
||||
pub fn new() -> PropertyBitField {
|
||||
PropertyBitField { storage: [0; (${len(data.longhands)} - 1 + 32) / 32] }
|
||||
}
|
||||
/// Return whether the given property is in the set
|
||||
#[inline]
|
||||
pub fn contains(&self, id: LonghandId) -> bool {
|
||||
let bit = id as usize;
|
||||
(self.storage[bit / 32] & (1 << (bit % 32))) != 0
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn get(&self, bit: usize) -> bool {
|
||||
(self.storage[bit / 32] & (1 << (bit % 32))) != 0
|
||||
}
|
||||
/// Add the given property to the set
|
||||
#[inline]
|
||||
pub fn insert(&mut self, id: LonghandId) {
|
||||
let bit = id as usize;
|
||||
self.storage[bit / 32] |= 1 << (bit % 32);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set(&mut self, bit: usize) {
|
||||
self.storage[bit / 32] |= 1 << (bit % 32)
|
||||
/// Set the corresponding bit of TransitionProperty.
|
||||
/// This function will panic if TransitionProperty::All is given.
|
||||
pub fn set_transition_property_bit(&mut self, property: &TransitionProperty) {
|
||||
match *property {
|
||||
% for prop in data.longhands:
|
||||
% if prop.animatable:
|
||||
TransitionProperty::${prop.camel_case} => self.insert(LonghandId::${prop.camel_case}),
|
||||
% endif
|
||||
% endfor
|
||||
TransitionProperty::All => unreachable!("Tried to set TransitionProperty::All in a PropertyBitfield"),
|
||||
}
|
||||
% for i, property in enumerate(data.longhands):
|
||||
% if not property.derived_from:
|
||||
#[allow(non_snake_case, missing_docs)]
|
||||
#[inline]
|
||||
pub fn get_${property.ident}(&self) -> bool {
|
||||
self.get(${i})
|
||||
}
|
||||
#[allow(non_snake_case, missing_docs)]
|
||||
#[inline]
|
||||
pub fn set_${property.ident}(&mut self) {
|
||||
self.set(${i})
|
||||
}
|
||||
% endif
|
||||
% if property.logical:
|
||||
#[allow(non_snake_case, missing_docs)]
|
||||
pub fn get_physical_${property.ident}(&self, wm: WritingMode) -> bool {
|
||||
<%helpers:logical_setter_helper name="${property.name}">
|
||||
<%def name="inner(physical_ident)">
|
||||
self.get_${physical_ident}()
|
||||
</%def>
|
||||
</%helpers:logical_setter_helper>
|
||||
}
|
||||
#[allow(non_snake_case, missing_docs)]
|
||||
pub fn set_physical_${property.ident}(&mut self, wm: WritingMode) {
|
||||
<%helpers:logical_setter_helper name="${property.name}">
|
||||
<%def name="inner(physical_ident)">
|
||||
self.set_${physical_ident}()
|
||||
</%def>
|
||||
</%helpers:logical_setter_helper>
|
||||
}
|
||||
% endif
|
||||
% endfor
|
||||
}
|
||||
|
||||
/// Set the corresponding bit of TransitionProperty.
|
||||
/// This function will panic if TransitionProperty::All is given.
|
||||
pub fn set_transition_property_bit(&mut self, property: &TransitionProperty) {
|
||||
match *property {
|
||||
% for i, prop in enumerate(data.longhands):
|
||||
% if prop.animatable:
|
||||
TransitionProperty::${prop.camel_case} => self.set(${i}),
|
||||
% endif
|
||||
% endfor
|
||||
TransitionProperty::All => unreachable!("Tried to set TransitionProperty::All in a PropertyBitfield"),
|
||||
}
|
||||
/// Return true if the corresponding bit of TransitionProperty is set.
|
||||
/// This function will panic if TransitionProperty::All is given.
|
||||
pub fn has_transition_property_bit(&self, property: &TransitionProperty) -> bool {
|
||||
match *property {
|
||||
% for prop in data.longhands:
|
||||
% if prop.animatable:
|
||||
TransitionProperty::${prop.camel_case} => self.contains(LonghandId::${prop.camel_case}),
|
||||
% endif
|
||||
% endfor
|
||||
TransitionProperty::All => unreachable!("Tried to get TransitionProperty::All in a PropertyBitfield"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Return true if the corresponding bit of TransitionProperty is set.
|
||||
/// This function will panic if TransitionProperty::All is given.
|
||||
pub fn has_transition_property_bit(&self, property: &TransitionProperty) -> bool {
|
||||
match *property {
|
||||
% for i, prop in enumerate(data.longhands):
|
||||
% if prop.animatable:
|
||||
TransitionProperty::${prop.camel_case} => self.get(${i}),
|
||||
% endif
|
||||
% endfor
|
||||
TransitionProperty::All => unreachable!("Tried to get TransitionProperty::All in a PropertyBitfield"),
|
||||
/// A specialized set of PropertyDeclarationId
|
||||
pub struct PropertyDeclarationIdSet {
|
||||
longhands: LonghandIdSet,
|
||||
|
||||
// FIXME: Use a HashSet instead? This Vec is usually small, so linear scan might be ok.
|
||||
custom: Vec<::custom_properties::Name>,
|
||||
}
|
||||
|
||||
impl PropertyDeclarationIdSet {
|
||||
/// Empty set
|
||||
pub fn new() -> Self {
|
||||
PropertyDeclarationIdSet {
|
||||
longhands: LonghandIdSet::new(),
|
||||
custom: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns whether the given ID is in the set
|
||||
pub fn contains(&mut self, id: PropertyDeclarationId) -> bool {
|
||||
match id {
|
||||
PropertyDeclarationId::Longhand(id) => self.longhands.contains(id),
|
||||
PropertyDeclarationId::Custom(name) => self.custom.contains(name),
|
||||
}
|
||||
}
|
||||
|
||||
/// Insert the given ID in the set
|
||||
pub fn insert(&mut self, id: PropertyDeclarationId) {
|
||||
match id {
|
||||
PropertyDeclarationId::Longhand(id) => self.longhands.insert(id),
|
||||
PropertyDeclarationId::Custom(name) => {
|
||||
if !self.custom.contains(name) {
|
||||
self.custom.push(name.clone())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -367,79 +367,6 @@ pub mod property_bit_field {
|
||||
% endif
|
||||
% endfor
|
||||
|
||||
/// Given a property declaration block, only keep the "winning" declaration for
|
||||
/// any given property, by importance then source order.
|
||||
///
|
||||
/// The input and output are in source order
|
||||
fn deduplicate_property_declarations(block: &mut PropertyDeclarationBlock) {
|
||||
let mut deduplicated = Vec::with_capacity(block.declarations.len());
|
||||
let mut seen_normal = PropertyBitField::new();
|
||||
let mut seen_important = PropertyBitField::new();
|
||||
let mut seen_custom_normal = Vec::new();
|
||||
let mut seen_custom_important = Vec::new();
|
||||
|
||||
for (declaration, importance) in block.declarations.drain(..).rev() {
|
||||
match declaration {
|
||||
% for property in data.longhands:
|
||||
PropertyDeclaration::${property.camel_case}(..) => {
|
||||
% if not property.derived_from:
|
||||
if importance.important() {
|
||||
if seen_important.get_${property.ident}() {
|
||||
block.important_count -= 1;
|
||||
continue
|
||||
}
|
||||
if seen_normal.get_${property.ident}() {
|
||||
remove_one(&mut deduplicated, |d| {
|
||||
matches!(d, &(PropertyDeclaration::${property.camel_case}(..), _))
|
||||
});
|
||||
}
|
||||
seen_important.set_${property.ident}()
|
||||
} else {
|
||||
if seen_normal.get_${property.ident}() ||
|
||||
seen_important.get_${property.ident}() {
|
||||
continue
|
||||
}
|
||||
seen_normal.set_${property.ident}()
|
||||
}
|
||||
% else:
|
||||
unreachable!();
|
||||
% endif
|
||||
},
|
||||
% endfor
|
||||
PropertyDeclaration::Custom(ref name, _) => {
|
||||
if importance.important() {
|
||||
if seen_custom_important.contains(name) {
|
||||
block.important_count -= 1;
|
||||
continue
|
||||
}
|
||||
if seen_custom_normal.contains(name) {
|
||||
remove_one(&mut deduplicated, |d| {
|
||||
matches!(d, &(PropertyDeclaration::Custom(ref n, _), _) if n == name)
|
||||
});
|
||||
}
|
||||
seen_custom_important.push(name.clone())
|
||||
} else {
|
||||
if seen_custom_normal.contains(name) ||
|
||||
seen_custom_important.contains(name) {
|
||||
continue
|
||||
}
|
||||
seen_custom_normal.push(name.clone())
|
||||
}
|
||||
}
|
||||
}
|
||||
deduplicated.push((declaration, importance))
|
||||
}
|
||||
deduplicated.reverse();
|
||||
block.declarations = deduplicated;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn remove_one<T, F: FnMut(&T) -> bool>(v: &mut Vec<T>, mut remove_this: F) {
|
||||
let previous_len = v.len();
|
||||
v.retain(|x| !remove_this(x));
|
||||
debug_assert_eq!(v.len(), previous_len - 1);
|
||||
}
|
||||
|
||||
/// An enum to represent a CSS Wide keyword.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
||||
pub enum CSSWideKeyword {
|
||||
@ -483,6 +410,25 @@ impl LonghandId {
|
||||
% endfor
|
||||
}
|
||||
}
|
||||
|
||||
/// If this is a logical property, return the corresponding physical one in the given writing mode.
|
||||
/// Otherwise, return unchanged.
|
||||
pub fn to_physical(&self, wm: WritingMode) -> Self {
|
||||
match *self {
|
||||
% for property in data.longhands:
|
||||
% if property.logical:
|
||||
LonghandId::${property.camel_case} => {
|
||||
<%helpers:logical_setter_helper name="${property.name}">
|
||||
<%def name="inner(physical_ident)">
|
||||
LonghandId::${to_camel_case(physical_ident)}
|
||||
</%def>
|
||||
</%helpers:logical_setter_helper>
|
||||
}
|
||||
% endif
|
||||
% endfor
|
||||
_ => *self
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An identifier for a given shorthand property.
|
||||
@ -653,7 +599,7 @@ impl<T: ToCss> ToCss for DeclaredValue<T> {
|
||||
|
||||
/// An identifier for a given property declaration, which can be either a
|
||||
/// longhand or a custom property.
|
||||
#[derive(PartialEq, Clone)]
|
||||
#[derive(PartialEq, Clone, Copy)]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
pub enum PropertyDeclarationId<'a> {
|
||||
/// A longhand.
|
||||
@ -1438,14 +1384,6 @@ impl ComputedValues {
|
||||
/// Since this isn't supported in Servo, this is always false for Servo.
|
||||
pub fn is_display_contents(&self) -> bool { false }
|
||||
|
||||
/// Get the root font size.
|
||||
fn root_font_size(&self) -> Au { self.root_font_size }
|
||||
|
||||
/// Set the root font size.
|
||||
fn set_root_font_size(&mut self, size: Au) { self.root_font_size = size }
|
||||
/// Set the writing mode for this style.
|
||||
pub fn set_writing_mode(&mut self, mode: WritingMode) { self.writing_mode = mode; }
|
||||
|
||||
/// Whether the current style is multicolumn.
|
||||
#[inline]
|
||||
pub fn is_multicol(&self) -> bool {
|
||||
@ -1730,7 +1668,6 @@ pub type CascadePropertyFn =
|
||||
inherited_style: &ComputedValues,
|
||||
default_style: &Arc<ComputedValues>,
|
||||
context: &mut computed::Context,
|
||||
seen: &mut PropertyBitField,
|
||||
cacheable: &mut bool,
|
||||
cascade_info: &mut Option<<&mut CascadeInfo>,
|
||||
error_reporter: &mut StdBox<ParseErrorReporter + Send>);
|
||||
@ -1855,7 +1792,7 @@ pub fn apply_declarations<'a, F, I>(viewport_size: Size2D<Au>,
|
||||
ComputedValues::new(custom_properties,
|
||||
flags.contains(SHAREABLE),
|
||||
WritingMode::empty(),
|
||||
inherited_style.root_font_size(),
|
||||
inherited_style.root_font_size,
|
||||
% for style_struct in data.active_style_structs():
|
||||
% if style_struct.inherited:
|
||||
inherited_style.clone_${style_struct.name_lower}(),
|
||||
@ -1868,7 +1805,7 @@ pub fn apply_declarations<'a, F, I>(viewport_size: Size2D<Au>,
|
||||
ComputedValues::new(custom_properties,
|
||||
flags.contains(SHAREABLE),
|
||||
WritingMode::empty(),
|
||||
inherited_style.root_font_size(),
|
||||
inherited_style.root_font_size,
|
||||
% for style_struct in data.active_style_structs():
|
||||
inherited_style.clone_${style_struct.name_lower}(),
|
||||
% endfor
|
||||
@ -1890,7 +1827,7 @@ pub fn apply_declarations<'a, F, I>(viewport_size: Size2D<Au>,
|
||||
// NB: The cacheable boolean is not used right now, but will be once we
|
||||
// start caching computed values in the rule nodes.
|
||||
let mut cacheable = true;
|
||||
let mut seen = PropertyBitField::new();
|
||||
let mut seen = LonghandIdSet::new();
|
||||
|
||||
// Declaration blocks are stored in increasing precedence order, we want
|
||||
// them in decreasing order here.
|
||||
@ -1940,19 +1877,25 @@ pub fn apply_declarations<'a, F, I>(viewport_size: Size2D<Au>,
|
||||
continue
|
||||
}
|
||||
|
||||
<% maybe_to_physical = ".to_physical(writing_mode)" if category_to_cascade_now != "early" else "" %>
|
||||
let physical_longhand_id = longhand_id ${maybe_to_physical};
|
||||
if seen.contains(physical_longhand_id) {
|
||||
continue
|
||||
}
|
||||
seen.insert(physical_longhand_id);
|
||||
|
||||
let discriminant = longhand_id as usize;
|
||||
(CASCADE_PROPERTY[discriminant])(declaration,
|
||||
inherited_style,
|
||||
default_style,
|
||||
&mut context,
|
||||
&mut seen,
|
||||
&mut cacheable,
|
||||
&mut cascade_info,
|
||||
&mut error_reporter);
|
||||
}
|
||||
% if category_to_cascade_now == "early":
|
||||
let mode = get_writing_mode(context.style.get_inheritedbox());
|
||||
context.style.set_writing_mode(mode);
|
||||
let writing_mode = get_writing_mode(context.style.get_inheritedbox());
|
||||
context.style.writing_mode = writing_mode;
|
||||
% endif
|
||||
% endfor
|
||||
|
||||
@ -2090,13 +2033,17 @@ pub fn apply_declarations<'a, F, I>(viewport_size: Size2D<Au>,
|
||||
|
||||
if is_root_element {
|
||||
let s = style.get_font().clone_font_size();
|
||||
style.set_root_font_size(s);
|
||||
style.root_font_size = s;
|
||||
}
|
||||
|
||||
if seen.get_font_style() || seen.get_font_weight() || seen.get_font_stretch() ||
|
||||
seen.get_font_family() {
|
||||
style.mutate_font().compute_font_hash();
|
||||
}
|
||||
% if product == "servo":
|
||||
if seen.contains(LonghandId::FontStyle) ||
|
||||
seen.contains(LonghandId::FontWeight) ||
|
||||
seen.contains(LonghandId::FontStretch) ||
|
||||
seen.contains(LonghandId::FontFamily) {
|
||||
style.mutate_font().compute_font_hash();
|
||||
}
|
||||
% endif
|
||||
|
||||
style
|
||||
}
|
||||
|
@ -13,6 +13,8 @@
|
||||
use properties::longhands::{background_color, background_position_x, background_position_y, background_repeat};
|
||||
use properties::longhands::{background_attachment, background_image, background_size, background_origin};
|
||||
use properties::longhands::background_clip;
|
||||
use properties::longhands::background_clip::single_value::computed_value::T as Clip;
|
||||
use properties::longhands::background_origin::single_value::computed_value::T as Origin;
|
||||
use values::specified::position::Position;
|
||||
use parser::Parse;
|
||||
|
||||
@ -134,27 +136,32 @@
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
use std::cmp;
|
||||
let mut len = 0;
|
||||
% for name in "image position_x position_y repeat size attachment origin clip".split():
|
||||
len = cmp::max(len, extract_value(self.background_${name}).map(|i| i.0.len())
|
||||
.unwrap_or(0));
|
||||
% endfor
|
||||
|
||||
let len = extract_value(self.background_image).map(|i| i.0.len()).unwrap_or(0);
|
||||
// There should be at least one declared value
|
||||
if len == 0 {
|
||||
return dest.write_str("")
|
||||
}
|
||||
|
||||
// If a value list length is differs then we don't do a shorthand serialization.
|
||||
// The exceptions to this is color which appears once only and is serialized
|
||||
// with the last item.
|
||||
% for name in "image position_x position_y size repeat origin clip attachment".split():
|
||||
if len != extract_value(self.background_${name}).map(|i| i.0.len()).unwrap_or(0) {
|
||||
return dest.write_str("")
|
||||
}
|
||||
% endfor
|
||||
|
||||
let mut first = true;
|
||||
for i in 0..len {
|
||||
% for name in "image position_x position_y repeat size attachment origin clip".split():
|
||||
let ${name} = if let DeclaredValue::Value(ref arr) = *self.background_${name} {
|
||||
arr.0.get(i % arr.0.len())
|
||||
&arr.0[i]
|
||||
} else {
|
||||
None
|
||||
unreachable!()
|
||||
};
|
||||
% endfor
|
||||
|
||||
let color = if i == len - 1 {
|
||||
Some(self.background_color)
|
||||
} else {
|
||||
@ -178,75 +185,33 @@
|
||||
None => ()
|
||||
};
|
||||
|
||||
% for name in "image repeat attachment position_x position_y".split():
|
||||
try!(${name}.to_css(dest));
|
||||
try!(write!(dest, " "));
|
||||
% endfor
|
||||
|
||||
if let Some(image) = image {
|
||||
try!(image.to_css(dest));
|
||||
} else {
|
||||
try!(write!(dest, "none"));
|
||||
}
|
||||
|
||||
try!(write!(dest, "/ "));
|
||||
try!(size.to_css(dest));
|
||||
try!(write!(dest, " "));
|
||||
|
||||
if let Some(repeat) = repeat {
|
||||
try!(repeat.to_css(dest));
|
||||
} else {
|
||||
try!(write!(dest, "repeat"));
|
||||
}
|
||||
|
||||
try!(write!(dest, " "));
|
||||
|
||||
if let Some(attachment) = attachment {
|
||||
try!(attachment.to_css(dest));
|
||||
} else {
|
||||
try!(write!(dest, "scroll"));
|
||||
}
|
||||
|
||||
try!(write!(dest, " "));
|
||||
|
||||
try!(position_x.unwrap_or(&background_position_x::single_value
|
||||
::get_initial_position_value())
|
||||
.to_css(dest));
|
||||
|
||||
try!(write!(dest, " "));
|
||||
|
||||
try!(position_y.unwrap_or(&background_position_y::single_value
|
||||
::get_initial_position_value())
|
||||
.to_css(dest));
|
||||
|
||||
if let Some(size) = size {
|
||||
try!(write!(dest, " / "));
|
||||
try!(size.to_css(dest));
|
||||
}
|
||||
|
||||
match (origin, clip) {
|
||||
(Some(origin), Some(clip)) => {
|
||||
use properties::longhands::background_origin::single_value::computed_value::T as Origin;
|
||||
use properties::longhands::background_clip::single_value::computed_value::T as Clip;
|
||||
|
||||
try!(write!(dest, " "));
|
||||
|
||||
match (origin, clip) {
|
||||
(&Origin::padding_box, &Clip::padding_box) => {
|
||||
try!(origin.to_css(dest));
|
||||
},
|
||||
(&Origin::border_box, &Clip::border_box) => {
|
||||
try!(origin.to_css(dest));
|
||||
},
|
||||
(&Origin::content_box, &Clip::content_box) => {
|
||||
try!(origin.to_css(dest));
|
||||
},
|
||||
_ => {
|
||||
try!(origin.to_css(dest));
|
||||
try!(write!(dest, " "));
|
||||
try!(clip.to_css(dest));
|
||||
}
|
||||
}
|
||||
(&Origin::padding_box, &Clip::padding_box) => {
|
||||
try!(origin.to_css(dest));
|
||||
},
|
||||
_ => {}
|
||||
(&Origin::border_box, &Clip::border_box) => {
|
||||
try!(origin.to_css(dest));
|
||||
},
|
||||
(&Origin::content_box, &Clip::content_box) => {
|
||||
try!(origin.to_css(dest));
|
||||
},
|
||||
_ => {
|
||||
try!(origin.to_css(dest));
|
||||
try!(write!(dest, " "));
|
||||
try!(clip.to_css(dest));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -133,16 +133,51 @@ macro_rules! try_parse_one {
|
||||
|
||||
impl<'a> LonghandsToSerialize<'a> {
|
||||
fn to_css_declared<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||
try!(self.transition_property.to_css(dest));
|
||||
try!(write!(dest, " "));
|
||||
fn extract_value<T>(x: &DeclaredValue<T>) -> Option< &T> {
|
||||
match *x {
|
||||
DeclaredValue::Value(ref val) => Some(val),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
try!(self.transition_duration.to_css(dest));
|
||||
try!(write!(dest, " "));
|
||||
let len = extract_value(self.transition_property).map(|i| i.0.len()).unwrap_or(0);
|
||||
// There should be at least one declared value
|
||||
if len == 0 {
|
||||
return dest.write_str("")
|
||||
}
|
||||
|
||||
try!(self.transition_timing_function.to_css(dest));
|
||||
try!(write!(dest, " "));
|
||||
// If any value list length is differs then we don't do a shorthand serialization
|
||||
// either.
|
||||
% for name in "property duration delay timing_function".split():
|
||||
if len != extract_value(self.transition_${name}).map(|i| i.0.len()).unwrap_or(0) {
|
||||
return dest.write_str("")
|
||||
}
|
||||
% endfor
|
||||
|
||||
self.transition_delay.to_css(dest)
|
||||
let mut first = true;
|
||||
for i in 0..len {
|
||||
% for name in "property duration delay timing_function".split():
|
||||
let ${name} = if let DeclaredValue::Value(ref arr) = *self.transition_${name} {
|
||||
&arr.0[i]
|
||||
} else {
|
||||
unreachable!()
|
||||
};
|
||||
% endfor
|
||||
|
||||
if first {
|
||||
first = false;
|
||||
} else {
|
||||
try!(write!(dest, ", "));
|
||||
}
|
||||
|
||||
try!(property.to_css(dest));
|
||||
|
||||
% for name in "duration timing_function delay".split():
|
||||
try!(write!(dest, " "));
|
||||
try!(${name}.to_css(dest));
|
||||
% endfor
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
</%helpers:shorthand>
|
||||
|
@ -1338,8 +1338,8 @@ pub extern "C" fn Servo_GetComputedKeyframeValues(keyframes: RawGeckoKeyframeLis
|
||||
pres_context: RawGeckoPresContextBorrowed,
|
||||
computed_keyframes: RawGeckoComputedKeyframeValuesListBorrowedMut)
|
||||
{
|
||||
use style::properties::LonghandIdSet;
|
||||
use style::properties::declaration_block::Importance;
|
||||
use style::properties::property_bit_field::PropertyBitField;
|
||||
use style::values::computed::Context;
|
||||
|
||||
let style = ComputedValues::as_arc(&style);
|
||||
@ -1359,7 +1359,7 @@ pub extern "C" fn Servo_GetComputedKeyframeValues(keyframes: RawGeckoKeyframeLis
|
||||
for (index, keyframe) in keyframes.iter().enumerate() {
|
||||
let ref mut animation_values = computed_keyframes[index];
|
||||
|
||||
let mut seen = PropertyBitField::new();
|
||||
let mut seen = LonghandIdSet::new();
|
||||
|
||||
// mServoDeclarationBlock is null in the case where we have an invalid css property.
|
||||
let iter = keyframe.mPropertyValues.iter()
|
||||
@ -1429,7 +1429,7 @@ pub extern "C" fn Servo_StyleSet_FillKeyframesForName(raw_data: RawServoStyleSet
|
||||
style: ServoComputedValuesBorrowed,
|
||||
keyframes: RawGeckoKeyframeListBorrowedMut) -> bool {
|
||||
use style::gecko_bindings::structs::Keyframe;
|
||||
use style::properties::property_bit_field::PropertyBitField;
|
||||
use style::properties::LonghandIdSet;
|
||||
|
||||
let data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut();
|
||||
let name = unsafe { Atom::from(name.as_ref().unwrap().as_str_unchecked()) };
|
||||
@ -1482,7 +1482,7 @@ pub extern "C" fn Servo_StyleSet_FillKeyframesForName(raw_data: RawServoStyleSet
|
||||
declaration.is_animatable()
|
||||
});
|
||||
|
||||
let mut seen = PropertyBitField::new();
|
||||
let mut seen = LonghandIdSet::new();
|
||||
|
||||
for (index, &(ref declaration, _)) in animatable.enumerate() {
|
||||
unsafe {
|
||||
|
@ -549,6 +549,12 @@ def check_rust(file_name, lines):
|
||||
(r": &Vec<", "use &[T] instead of &Vec<T>", no_filter),
|
||||
# No benefit over using &str
|
||||
(r": &String", "use &str instead of &String", no_filter),
|
||||
# There should be any use of banned types:
|
||||
# Cell<JSVal>, Cell<JS<T>>, DOMRefCell<JS<T>>, DOMRefCell<HEAP<T>>
|
||||
(r"(\s|:)+Cell<JSVal>", "Banned type Cell<JSVal> detected. Use MutJS<JSVal> instead", no_filter),
|
||||
(r"(\s|:)+Cell<JS<.+>>", "Banned type Cell<JS<T>> detected. Use MutJS<JS<T>> instead", no_filter),
|
||||
(r"DOMRefCell<JS<.+>>", "Banned type DOMRefCell<JS<T>> detected. Use MutJS<JS<T>> instead", no_filter),
|
||||
(r"DOMRefCell<Heap<.+>>", "Banned type DOMRefCell<Heap<T>> detected. Use MutJS<JS<T>> instead", no_filter),
|
||||
# No benefit to using &Root<T>
|
||||
(r": &Root<", "use &T instead of &Root<T>", no_filter),
|
||||
(r"^&&", "operators should go at the end of the first line", no_filter),
|
||||
|
@ -9,10 +9,13 @@ extern crate js;
|
||||
|
||||
use js::jsval::JSVal;
|
||||
use std::cell::Cell;
|
||||
use std::cell::UnsafeCell;
|
||||
|
||||
struct Foo {
|
||||
bar: Cell<JSVal>
|
||||
bar: Cell<JSVal>,
|
||||
//~^ ERROR Banned type Cell<JSVal> detected. Use MutJS<JSVal> instead
|
||||
foo: UnsafeCell<JSVal>
|
||||
//~^ NOT AN ERROR
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -140,6 +140,14 @@ class CheckTidiness(unittest.TestCase):
|
||||
self.assertTrue('feature attribute is not in alphabetical order' in feature_errors.next()[2])
|
||||
self.assertNoMoreErrors(feature_errors)
|
||||
|
||||
ban_errors = tidy.collect_errors_for_files(iterFile('ban.rs'), [], [tidy.check_rust], print_text=False)
|
||||
self.assertEqual('Banned type Cell<JSVal> detected. Use MutJS<JSVal> instead', ban_errors.next()[2])
|
||||
self.assertNoMoreErrors(ban_errors)
|
||||
|
||||
ban_errors = tidy.collect_errors_for_files(iterFile('ban-domrefcell.rs'), [], [tidy.check_rust], print_text=False)
|
||||
self.assertEqual('Banned type DOMRefCell<JS<T>> detected. Use MutJS<JS<T>> instead', ban_errors.next()[2])
|
||||
self.assertNoMoreErrors(ban_errors)
|
||||
|
||||
def test_spec_link(self):
|
||||
tidy.SPEC_BASE_PATH = base_path
|
||||
errors = tidy.collect_errors_for_files(iterFile('speclink.rs'), [], [tidy.check_spec], print_text=False)
|
||||
|
@ -6,6 +6,7 @@ use cssparser::Parser;
|
||||
use media_queries::CSSErrorReporterTest;
|
||||
use servo_url::ServoUrl;
|
||||
use style::parser::ParserContext;
|
||||
use style::properties::longhands::{self, perspective_origin, transform_origin};
|
||||
use style::stylesheets::Origin;
|
||||
use style_traits::ToCss;
|
||||
|
||||
@ -33,3 +34,32 @@ fn test_clip() {
|
||||
"rect(auto, auto, auto, auto)");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_longhands_parse_origin() {
|
||||
let url = ServoUrl::parse("http://localhost").unwrap();
|
||||
let context = ParserContext::new(Origin::Author, &url, Box::new(CSSErrorReporterTest));
|
||||
|
||||
let mut parser = Parser::new("1px some-rubbish");
|
||||
let parsed = longhands::parse_origin(&context, &mut parser);
|
||||
assert!(parsed.is_ok());
|
||||
assert_eq!(parser.is_exhausted(), false);
|
||||
|
||||
let mut parser = Parser::new("1px 2px");
|
||||
let parsed = longhands::parse_origin(&context, &mut parser);
|
||||
assert!(parsed.is_ok());
|
||||
assert_eq!(parser.is_exhausted(), true);
|
||||
|
||||
let mut parser = Parser::new("1px");
|
||||
let parsed = longhands::parse_origin(&context, &mut parser);
|
||||
assert!(parsed.is_ok());
|
||||
assert_eq!(parser.is_exhausted(), true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_effects_parser_exhaustion() {
|
||||
assert_parser_exhausted!(perspective_origin, "1px 1px", true);
|
||||
assert_parser_exhausted!(transform_origin, "1px 1px", true);
|
||||
|
||||
assert_parser_exhausted!(perspective_origin, "1px some-rubbish", false);
|
||||
assert_parser_exhausted!(transform_origin, "1px some-rubbish", false);
|
||||
}
|
||||
|
@ -2,16 +2,27 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
pub use std::sync::Arc;
|
||||
pub use style::computed_values::display::T::inline_block;
|
||||
pub use style::properties::{DeclaredValue, PropertyDeclaration, PropertyDeclarationBlock, Importance, PropertyId};
|
||||
pub use style::values::specified::{BorderStyle, BorderWidth, CSSColor, Length, NoCalcLength};
|
||||
pub use style::values::specified::{LengthOrPercentage, LengthOrPercentageOrAuto, LengthOrPercentageOrAutoOrContent};
|
||||
pub use style::properties::longhands::outline_color::computed_value::T as ComputedColor;
|
||||
pub use style::properties::longhands::outline_style::SpecifiedValue as OutlineStyle;
|
||||
pub use style::values::{RGBA, Auto};
|
||||
pub use style::values::specified::url::{UrlExtraData, SpecifiedUrl};
|
||||
pub use style_traits::ToCss;
|
||||
use cssparser::Parser;
|
||||
use media_queries::CSSErrorReporterTest;
|
||||
use servo_url::ServoUrl;
|
||||
use style::computed_values::display::T::inline_block;
|
||||
use style::parser::ParserContext;
|
||||
use style::properties::{DeclaredValue, PropertyDeclaration, PropertyDeclarationBlock, Importance, PropertyId};
|
||||
use style::properties::longhands::outline_color::computed_value::T as ComputedColor;
|
||||
use style::properties::parse_property_declaration_list;
|
||||
use style::stylesheets::Origin;
|
||||
use style::values::{RGBA, Auto};
|
||||
use style::values::specified::{BorderStyle, BorderWidth, CSSColor, Length, NoCalcLength};
|
||||
use style::values::specified::{LengthOrPercentage, LengthOrPercentageOrAuto, LengthOrPercentageOrAutoOrContent};
|
||||
use style::values::specified::url::SpecifiedUrl;
|
||||
use style_traits::ToCss;
|
||||
|
||||
fn parse_declaration_block(css_properties: &str) -> PropertyDeclarationBlock {
|
||||
let url = ServoUrl::parse("http://localhost").unwrap();
|
||||
let context = ParserContext::new(Origin::Author, &url, Box::new(CSSErrorReporterTest));
|
||||
let mut parser = Parser::new(css_properties);
|
||||
parse_property_declaration_list(&context, &mut parser)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn property_declaration_block_should_serialize_correctly() {
|
||||
@ -552,46 +563,6 @@ mod shorthand_serialization {
|
||||
assert_eq!(serialization, "columns: auto auto;");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn transition_should_serialize_all_available_properties() {
|
||||
use euclid::point::Point2D;
|
||||
use style::properties::animated_properties::TransitionProperty;
|
||||
use style::properties::longhands::transition_delay::SpecifiedValue as DelayContainer;
|
||||
use style::properties::longhands::transition_duration::SpecifiedValue as DurationContainer;
|
||||
use style::properties::longhands::transition_property::SpecifiedValue as PropertyContainer;
|
||||
use style::properties::longhands::transition_timing_function;
|
||||
use style::values::specified::Time as TimeContainer;
|
||||
|
||||
let property_name = DeclaredValue::Value(
|
||||
PropertyContainer(vec![TransitionProperty::MarginLeft])
|
||||
);
|
||||
|
||||
let duration = DeclaredValue::Value(
|
||||
DurationContainer(vec![TimeContainer(3f32)])
|
||||
);
|
||||
|
||||
let delay = DeclaredValue::Value(
|
||||
DelayContainer(vec![TimeContainer(4f32)])
|
||||
);
|
||||
|
||||
let timing_function = DeclaredValue::Value(
|
||||
transition_timing_function::SpecifiedValue(vec![
|
||||
transition_timing_function::single_value::SpecifiedValue::CubicBezier(
|
||||
Point2D::new(0f32, 5f32), Point2D::new(5f32, 10f32))
|
||||
])
|
||||
);
|
||||
|
||||
let mut properties = Vec::new();
|
||||
|
||||
properties.push(PropertyDeclaration::TransitionProperty(property_name));
|
||||
properties.push(PropertyDeclaration::TransitionDelay(delay));
|
||||
properties.push(PropertyDeclaration::TransitionDuration(duration));
|
||||
properties.push(PropertyDeclaration::TransitionTimingFunction(timing_function));
|
||||
|
||||
let serialization = shorthand_properties_to_string(properties);
|
||||
assert_eq!(serialization, "transition: margin-left 3s cubic-bezier(0, 5, 5, 10) 4s;");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn flex_should_serialize_all_available_properties() {
|
||||
use style::values::specified::Number as NumberContainer;
|
||||
@ -676,108 +647,24 @@ mod shorthand_serialization {
|
||||
}
|
||||
*/
|
||||
|
||||
// TODO: Populate Atom Cache for testing so that the animation shorthand can be tested
|
||||
/*
|
||||
#[test]
|
||||
fn animation_should_serialize_all_available_properties() {
|
||||
let mut properties = Vec::new();
|
||||
|
||||
assert_eq!(serialization, "animation;");
|
||||
}
|
||||
*/
|
||||
|
||||
mod background {
|
||||
use style::properties::longhands::background_attachment as attachment;
|
||||
use style::properties::longhands::background_clip as clip;
|
||||
use style::properties::longhands::background_image as image;
|
||||
use style::properties::longhands::background_origin as origin;
|
||||
use style::properties::longhands::background_position_x as position_x;
|
||||
use style::properties::longhands::background_position_y as position_y;
|
||||
use style::properties::longhands::background_repeat as repeat;
|
||||
use style::properties::longhands::background_size as size;
|
||||
use style::values::specified::Image;
|
||||
use style::values::specified::position::{HorizontalPosition, VerticalPosition};
|
||||
use super::*;
|
||||
macro_rules! single_vec_value_typedef {
|
||||
($name:ident, $path:expr) => {
|
||||
DeclaredValue::Value($name::SpecifiedValue(
|
||||
vec![$path]
|
||||
))
|
||||
};
|
||||
}
|
||||
macro_rules! single_vec_value {
|
||||
($name:ident, $path:expr) => {
|
||||
DeclaredValue::Value($name::SpecifiedValue(
|
||||
vec![$name::single_value::SpecifiedValue($path)]
|
||||
))
|
||||
};
|
||||
}
|
||||
macro_rules! single_vec_keyword_value {
|
||||
($name:ident, $kw:ident) => {
|
||||
DeclaredValue::Value($name::SpecifiedValue(
|
||||
vec![$name::single_value::SpecifiedValue::$kw]
|
||||
))
|
||||
};
|
||||
}
|
||||
macro_rules! single_vec_variant_value {
|
||||
($name:ident, $variant:expr) => {
|
||||
DeclaredValue::Value($name::SpecifiedValue(
|
||||
vec![$variant]
|
||||
))
|
||||
};
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn background_should_serialize_all_available_properties_when_specified() {
|
||||
let mut properties = Vec::new();
|
||||
let block_text = "\
|
||||
background-color: rgb(255, 0, 0); \
|
||||
background-image: url(\"http://servo/test.png\"); \
|
||||
background-repeat: repeat-x; \
|
||||
background-attachment: scroll; \
|
||||
background-size: 70px 50px; \
|
||||
background-position-x: 7px; \
|
||||
background-position-y: 4px; \
|
||||
background-origin: border-box; \
|
||||
background-clip: padding-box;";
|
||||
let block = parse_declaration_block(block_text);
|
||||
|
||||
let color = DeclaredValue::Value(CSSColor {
|
||||
parsed: ComputedColor::RGBA(RGBA::new(255, 0, 0, 255)),
|
||||
authored: None
|
||||
});
|
||||
|
||||
let position_x = single_vec_value_typedef!(position_x,
|
||||
HorizontalPosition {
|
||||
keyword: None,
|
||||
position: Some(LengthOrPercentage::Length(NoCalcLength::from_px(7f32))),
|
||||
}
|
||||
);
|
||||
|
||||
let position_y = single_vec_value_typedef!(position_y,
|
||||
VerticalPosition {
|
||||
keyword: None,
|
||||
position: Some(LengthOrPercentage::Length(NoCalcLength::from_px(4f32))),
|
||||
}
|
||||
);
|
||||
|
||||
let repeat = single_vec_keyword_value!(repeat, repeat_x);
|
||||
let attachment = single_vec_keyword_value!(attachment, scroll);
|
||||
|
||||
let image = single_vec_value!(image,
|
||||
Some(Image::Url(SpecifiedUrl::new_for_testing("http://servo/test.png"))));
|
||||
|
||||
let size = single_vec_variant_value!(size,
|
||||
size::single_value::SpecifiedValue::Explicit(
|
||||
size::single_value::ExplicitSize {
|
||||
width: LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(70f32)),
|
||||
height: LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(50f32))
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
let origin = single_vec_keyword_value!(origin, border_box);
|
||||
let clip = single_vec_keyword_value!(clip, padding_box);
|
||||
|
||||
properties.push(PropertyDeclaration::BackgroundColor(color));
|
||||
properties.push(PropertyDeclaration::BackgroundPositionX(position_x));
|
||||
properties.push(PropertyDeclaration::BackgroundPositionY(position_y));
|
||||
properties.push(PropertyDeclaration::BackgroundRepeat(repeat));
|
||||
properties.push(PropertyDeclaration::BackgroundAttachment(attachment));
|
||||
properties.push(PropertyDeclaration::BackgroundImage(image));
|
||||
properties.push(PropertyDeclaration::BackgroundSize(size));
|
||||
properties.push(PropertyDeclaration::BackgroundOrigin(origin));
|
||||
properties.push(PropertyDeclaration::BackgroundClip(clip));
|
||||
|
||||
let serialization = shorthand_properties_to_string(properties);
|
||||
let serialization = block.to_css_string();
|
||||
|
||||
assert_eq!(
|
||||
serialization,
|
||||
@ -788,56 +675,20 @@ mod shorthand_serialization {
|
||||
|
||||
#[test]
|
||||
fn background_should_combine_origin_and_clip_properties_when_equal() {
|
||||
let mut properties = Vec::new();
|
||||
let block_text = "\
|
||||
background-color: rgb(255, 0, 0); \
|
||||
background-image: url(\"http://servo/test.png\"); \
|
||||
background-repeat: repeat-x; \
|
||||
background-attachment: scroll; \
|
||||
background-size: 70px 50px; \
|
||||
background-position-x: 7px; \
|
||||
background-position-y: 4px; \
|
||||
background-origin: padding-box; \
|
||||
background-clip: padding-box;";
|
||||
let block = parse_declaration_block(block_text);
|
||||
|
||||
let color = DeclaredValue::Value(CSSColor {
|
||||
parsed: ComputedColor::RGBA(RGBA::new(255, 0, 0, 255)),
|
||||
authored: None
|
||||
});
|
||||
let serialization = block.to_css_string();
|
||||
|
||||
let position_x = single_vec_value_typedef!(position_x,
|
||||
HorizontalPosition {
|
||||
keyword: None,
|
||||
position: Some(LengthOrPercentage::Length(NoCalcLength::from_px(7f32))),
|
||||
}
|
||||
);
|
||||
|
||||
let position_y = single_vec_value_typedef!(position_y,
|
||||
VerticalPosition {
|
||||
keyword: None,
|
||||
position: Some(LengthOrPercentage::Length(NoCalcLength::from_px(4f32))),
|
||||
}
|
||||
);
|
||||
|
||||
let repeat = single_vec_keyword_value!(repeat, repeat_x);
|
||||
let attachment = single_vec_keyword_value!(attachment, scroll);
|
||||
|
||||
let image = single_vec_value!(image,
|
||||
Some(Image::Url(SpecifiedUrl::new_for_testing("http://servo/test.png"))));
|
||||
|
||||
let size = single_vec_variant_value!(size,
|
||||
size::single_value::SpecifiedValue::Explicit(
|
||||
size::single_value::ExplicitSize {
|
||||
width: LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(70f32)),
|
||||
height: LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(50f32))
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
let origin = single_vec_keyword_value!(origin, padding_box);
|
||||
let clip = single_vec_keyword_value!(clip, padding_box);
|
||||
|
||||
properties.push(PropertyDeclaration::BackgroundColor(color));
|
||||
properties.push(PropertyDeclaration::BackgroundPositionX(position_x));
|
||||
properties.push(PropertyDeclaration::BackgroundPositionY(position_y));
|
||||
properties.push(PropertyDeclaration::BackgroundRepeat(repeat));
|
||||
properties.push(PropertyDeclaration::BackgroundAttachment(attachment));
|
||||
properties.push(PropertyDeclaration::BackgroundImage(image));
|
||||
properties.push(PropertyDeclaration::BackgroundSize(size));
|
||||
properties.push(PropertyDeclaration::BackgroundOrigin(origin));
|
||||
properties.push(PropertyDeclaration::BackgroundClip(clip));
|
||||
|
||||
let serialization = shorthand_properties_to_string(properties);
|
||||
assert_eq!(
|
||||
serialization,
|
||||
"background: rgb(255, 0, 0) url(\"http://servo/test.png\") repeat-x \
|
||||
@ -846,50 +697,52 @@ mod shorthand_serialization {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn background_should_always_print_color_and_url_and_repeat_and_attachment_and_position() {
|
||||
let mut properties = Vec::new();
|
||||
fn serialize_multiple_backgrounds() {
|
||||
let block_text = "\
|
||||
background-color: rgb(0, 0, 255); \
|
||||
background-image: url(\"http://servo/test.png\"), none; \
|
||||
background-repeat: repeat-x, repeat-y; \
|
||||
background-attachment: scroll, scroll; \
|
||||
background-size: 70px 50px, 20px 30px; \
|
||||
background-position-x: 7px, 70px; \
|
||||
background-position-y: 4px, 40px; \
|
||||
background-origin: border-box, padding-box; \
|
||||
background-clip: padding-box, padding-box;";
|
||||
let block = parse_declaration_block(block_text);
|
||||
|
||||
let color = DeclaredValue::Value(CSSColor {
|
||||
parsed: ComputedColor::RGBA(RGBA::new(255, 0, 0, 255)),
|
||||
authored: None
|
||||
});
|
||||
let serialization = block.to_css_string();
|
||||
|
||||
let position_x = single_vec_value_typedef!(position_x,
|
||||
HorizontalPosition {
|
||||
keyword: None,
|
||||
position: Some(LengthOrPercentage::Length(NoCalcLength::from_px(0f32))),
|
||||
}
|
||||
assert_eq!(
|
||||
serialization, "background: \
|
||||
url(\"http://servo/test.png\") repeat-x scroll 7px 4px / 70px 50px border-box padding-box, \
|
||||
rgb(0, 0, 255) none repeat-y scroll 70px 40px / 20px 30px padding-box;"
|
||||
);
|
||||
}
|
||||
|
||||
let position_y = single_vec_value_typedef!(position_y,
|
||||
VerticalPosition {
|
||||
keyword: None,
|
||||
position: Some(LengthOrPercentage::Length(NoCalcLength::from_px(0f32))),
|
||||
}
|
||||
);
|
||||
#[test]
|
||||
fn serialize_multiple_backgrounds_unequal_property_lists() {
|
||||
// When the lengths of property values are different, the shorthand serialization
|
||||
// should not be used. Previously the implementation cycled values if the lists were
|
||||
// uneven. This is incorrect, in that we should serialize to a shorthand only when the
|
||||
// lists have the same length (this affects background, transition and animation).
|
||||
// https://github.com/servo/servo/issues/15398 )
|
||||
// With background, the color is one exception as it should only appear once for
|
||||
// multiple backgrounds.
|
||||
// Below, background-position and background-origin only have one value.
|
||||
let block_text = "\
|
||||
background-color: rgb(0, 0, 255); \
|
||||
background-image: url(\"http://servo/test.png\"), none; \
|
||||
background-repeat: repeat-x, repeat-y; \
|
||||
background-attachment: scroll, scroll; \
|
||||
background-size: 70px 50px, 20px 30px; \
|
||||
background-position: 7px 4px; \
|
||||
background-origin: border-box; \
|
||||
background-clip: padding-box, padding-box;";
|
||||
let block = parse_declaration_block(block_text);
|
||||
|
||||
let repeat = single_vec_keyword_value!(repeat, repeat_x);
|
||||
let attachment = single_vec_keyword_value!(attachment, scroll);
|
||||
let serialization = block.to_css_string();
|
||||
|
||||
let image = single_vec_value!(image, None);
|
||||
|
||||
let size = DeclaredValue::Initial;
|
||||
|
||||
let origin = DeclaredValue::Initial;
|
||||
let clip = DeclaredValue::Initial;
|
||||
|
||||
properties.push(PropertyDeclaration::BackgroundColor(color));
|
||||
properties.push(PropertyDeclaration::BackgroundPositionX(position_x));
|
||||
properties.push(PropertyDeclaration::BackgroundPositionY(position_y));
|
||||
properties.push(PropertyDeclaration::BackgroundRepeat(repeat));
|
||||
properties.push(PropertyDeclaration::BackgroundAttachment(attachment));
|
||||
properties.push(PropertyDeclaration::BackgroundImage(image));
|
||||
properties.push(PropertyDeclaration::BackgroundSize(size));
|
||||
properties.push(PropertyDeclaration::BackgroundOrigin(origin));
|
||||
properties.push(PropertyDeclaration::BackgroundClip(clip));
|
||||
|
||||
let serialization = shorthand_properties_to_string(properties);
|
||||
assert_eq!(serialization, "background: rgb(255, 0, 0) none repeat-x scroll 0px 0px;");
|
||||
assert_eq!(serialization, block_text);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1140,23 +993,10 @@ mod shorthand_serialization {
|
||||
|
||||
mod animation {
|
||||
pub use super::*;
|
||||
use cssparser::Parser;
|
||||
use media_queries::CSSErrorReporterTest;
|
||||
use servo_url::ServoUrl;
|
||||
use style::parser::ParserContext;
|
||||
use style::properties::{parse_property_declaration_list, PropertyDeclarationBlock};
|
||||
use style::stylesheets::Origin;
|
||||
|
||||
fn property_declaration_block(css_properties: &str) -> PropertyDeclarationBlock {
|
||||
let url = ServoUrl::parse("http://localhost").unwrap();
|
||||
let context = ParserContext::new(Origin::Author, &url, Box::new(CSSErrorReporterTest));
|
||||
let mut parser = Parser::new(css_properties);
|
||||
parse_property_declaration_list(&context, &mut parser)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn serialize_single_animation() {
|
||||
let block = property_declaration_block("\
|
||||
let block = parse_declaration_block("\
|
||||
animation-name: bounce;\
|
||||
animation-duration: 1s;\
|
||||
animation-timing-function: ease-in;\
|
||||
@ -1173,7 +1013,7 @@ mod shorthand_serialization {
|
||||
|
||||
#[test]
|
||||
fn serialize_multiple_animations() {
|
||||
let block = property_declaration_block("\
|
||||
let block = parse_declaration_block("\
|
||||
animation-name: bounce, roll;\
|
||||
animation-duration: 1s, 0.2s;\
|
||||
animation-timing-function: ease-in, linear;\
|
||||
@ -1195,7 +1035,7 @@ mod shorthand_serialization {
|
||||
// When the lengths of property values are different, the shorthand serialization
|
||||
// should not be used. Previously the implementation cycled values if the lists were
|
||||
// uneven. This is incorrect, in that we should serialize to a shorthand only when the
|
||||
// lists have the same length (both here and for background and transition. See
|
||||
// lists have the same length (this affects background, transition and animation).
|
||||
// https://github.com/servo/servo/issues/15398 )
|
||||
let block_text = "\
|
||||
animation-name: bounce, roll, flip, jump; \
|
||||
@ -1206,7 +1046,7 @@ mod shorthand_serialization {
|
||||
animation-fill-mode: forwards, backwards; \
|
||||
animation-iteration-count: infinite, 2; \
|
||||
animation-play-state: paused, running;";
|
||||
let block = property_declaration_block(block_text);
|
||||
let block = parse_declaration_block(block_text);
|
||||
|
||||
let serialization = block.to_css_string();
|
||||
|
||||
@ -1222,7 +1062,58 @@ mod shorthand_serialization {
|
||||
animation-fill-mode: forwards, backwards; \
|
||||
animation-iteration-count: infinite, 2; \
|
||||
animation-play-state: paused, running;";
|
||||
let block = property_declaration_block(block_text);
|
||||
let block = parse_declaration_block(block_text);
|
||||
|
||||
let serialization = block.to_css_string();
|
||||
|
||||
assert_eq!(serialization, block_text);
|
||||
}
|
||||
}
|
||||
|
||||
mod transition {
|
||||
pub use super::*;
|
||||
|
||||
#[test]
|
||||
fn transition_should_serialize_all_available_properties() {
|
||||
let block_text = "transition-property: margin-left; \
|
||||
transition-duration: 3s; \
|
||||
transition-delay: 4s; \
|
||||
transition-timing-function: cubic-bezier(0.2, 5, 0.5, 2);";
|
||||
let block = parse_declaration_block(block_text);
|
||||
|
||||
let serialization = block.to_css_string();
|
||||
|
||||
assert_eq!(serialization, "transition: margin-left 3s cubic-bezier(0.2, 5, 0.5, 2) 4s;");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn serialize_multiple_transitions() {
|
||||
let block_text = "transition-property: margin-left, width; \
|
||||
transition-duration: 3s, 2s; \
|
||||
transition-delay: 4s, 5s; \
|
||||
transition-timing-function: cubic-bezier(0.2, 5, 0.5, 2), ease;";
|
||||
let block = parse_declaration_block(block_text);
|
||||
|
||||
let serialization = block.to_css_string();
|
||||
|
||||
assert_eq!(serialization, "transition: \
|
||||
margin-left 3s cubic-bezier(0.2, 5, 0.5, 2) 4s, \
|
||||
width 2s ease 5s;");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn serialize_multiple_transitions_unequal_property_lists() {
|
||||
// When the lengths of property values are different, the shorthand serialization
|
||||
// should not be used. Previously the implementation cycled values if the lists were
|
||||
// uneven. This is incorrect, in that we should serialize to a shorthand only when the
|
||||
// lists have the same length (this affects background, transition and animation).
|
||||
// https://github.com/servo/servo/issues/15398 )
|
||||
// The duration below has 1 extra value.
|
||||
let block_text = "transition-property: margin-left, width; \
|
||||
transition-duration: 3s, 2s, 4s; \
|
||||
transition-delay: 4s, 5s; \
|
||||
transition-timing-function: cubic-bezier(0.2, 5, 0.5, 2), ease;";
|
||||
let block = parse_declaration_block(block_text);
|
||||
|
||||
let serialization = block.to_css_string();
|
||||
|
||||
|
@ -209,9 +209,11 @@ Service::getSingleton()
|
||||
if (ps) {
|
||||
nsAutoString title, message;
|
||||
title.AppendLiteral("SQLite Version Error");
|
||||
message.AppendLiteral("The application has been updated, but your version "
|
||||
"of SQLite is too old and the application cannot "
|
||||
"run.");
|
||||
message.AppendLiteral("The application has been updated, but the SQLite "
|
||||
"library wasn't updated properly and the application "
|
||||
"cannot run. Please try to launch the application again. "
|
||||
"If that should still fail, please try reinstalling "
|
||||
"it, or visit https://support.mozilla.org/.");
|
||||
(void)ps->Alert(nullptr, title.get(), message.get());
|
||||
}
|
||||
MOZ_CRASH("SQLite Version Error");
|
||||
|
@ -130,12 +130,12 @@ add_task(function* test_data_file() {
|
||||
|
||||
let lastSite = sites.pop();
|
||||
let uri = NetUtil.newURI(lastSite[0]);
|
||||
let title = lastSite[1];
|
||||
|
||||
do_print("Storage is populated from JSON correctly");
|
||||
yield check_autocomplete({
|
||||
search: uri.host.slice(1), // omit 1st letter to avoid style:"autofill" result
|
||||
matches: [ { uri, title, style: ["prefill-site"] } ],
|
||||
search: uri.host,
|
||||
autofilled: stripPrefix(uri.spec),
|
||||
completed: uri.spec,
|
||||
});
|
||||
|
||||
yield cleanup();
|
||||
|
Loading…
Reference in New Issue
Block a user