Merge autoland to mozilla-central. a=merge
authorMarian-Vasile Laza <mlaza@mozilla.com>
Mon, 25 Apr 2022 12:40:50 +0300
changeset 685657 9cb38db713cc2d586fee644f0820fc35861a9b62
parent 685651 f1c90dd558bb17f89cddb2d246cb42697820d662 (current diff)
parent 685652 716059caf59ef1fedbec1a534ac542c8d010535b (diff)
child 685658 1d42a10d3d0ab4b566e3dc5dfc3b021872379ff1
child 685704 1376d10cd1be397689f30c90052cbc24680837f0
push id16598
push userffxbld-merge
push dateMon, 02 May 2022 14:23:32 +0000
treeherdermozilla-beta@de86a81c7a63 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone101.0a1
first release with
nightly linux32
9cb38db713cc / 101.0a1 / 20220425094217 / files
nightly linux64
9cb38db713cc / 101.0a1 / 20220425094217 / files
nightly mac
9cb38db713cc / 101.0a1 / 20220425094217 / files
nightly win32
9cb38db713cc / 101.0a1 / 20220425094217 / files
nightly win64
9cb38db713cc / 101.0a1 / 20220425094217 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge autoland to mozilla-central. a=merge
--- a/browser/base/content/test/tabcrashed/browser_shown.js
+++ b/browser/base/content/test/tabcrashed/browser_shown.js
@@ -85,61 +85,65 @@ function crashTabTestHelper(fieldValues,
  * Tests what we send with the crash report by default. By default, we do not
  * send any comments or the URL of the crashing page.
  */
 add_task(async function test_default() {
   await crashTabTestHelper(
     {},
     {
       SubmittedFrom: "CrashedTab",
+      Throttleable: "1",
       Comments: null,
       URL: "",
     }
   );
 });
 
 /**
  * Test just sending a comment.
  */
 add_task(async function test_just_a_comment() {
   await crashTabTestHelper(
     {
       SubmittedFrom: "CrashedTab",
+      Throttleable: "1",
       comments: COMMENTS,
     },
     {
       Comments: COMMENTS,
       URL: "",
     }
   );
 });
 
 /**
  * Test that we will send the URL of the page if includeURL is checked.
  */
 add_task(async function test_send_URL() {
   await crashTabTestHelper(
     {
       SubmittedFrom: "CrashedTab",
+      Throttleable: "1",
       includeURL: true,
     },
     {
       Comments: null,
       URL: PAGE,
     }
   );
 });
 
 /**
  * Test that we can send comments and the URL
  */
 add_task(async function test_send_all() {
   await crashTabTestHelper(
     {
       SubmittedFrom: "CrashedTab",
+      Throttleable: "1",
       includeURL: true,
       comments: COMMENTS,
     },
     {
       Comments: COMMENTS,
       URL: PAGE,
     }
   );
--- a/browser/modules/test/browser/browser_UnsubmittedCrashHandler.js
+++ b/browser/modules/test/browser/browser_UnsubmittedCrashHandler.js
@@ -367,16 +367,17 @@ add_task(async function test_can_submit(
     for (const key of blockedAnnotations) {
       Assert.ok(
         !extra.hasKey(key),
         "The " + key + " annotation should have been stripped away"
       );
     }
 
     Assert.equal(extra.get("SubmittedFrom"), "Infobar");
+    Assert.equal(extra.get("Throttleable"), "1");
   }
 
   let reportIDs = await createPendingCrashReports(1);
   let notification = await UnsubmittedCrashHandler.checkForUnsubmittedCrashReports();
   Assert.ok(notification, "There should be a notification");
 
   // Attempt to submit the notification by clicking on the submit
   // button
@@ -475,16 +476,17 @@ add_task(async function test_can_submit_
   // Create another report
   reportIDs = await createPendingCrashReports(1);
   let result = await UnsubmittedCrashHandler.checkForUnsubmittedCrashReports();
 
   // Check that the crash was auto-submitted
   Assert.equal(result, null, "The notification should not be shown");
   promiseReports = await waitForSubmittedReports(reportIDs, extra => {
     Assert.equal(extra.get("SubmittedFrom"), "Auto");
+    Assert.equal(extra.get("Throttleable"), "1");
   });
 
   // And revert back to default now.
   Services.prefs.clearUserPref(pref);
 
   clearPendingCrashReports();
 });
 
--- a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
+++ b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
@@ -8,30 +8,33 @@
 
 #include "FFmpegLog.h"
 #include "ImageContainer.h"
 #include "MP4Decoder.h"
 #include "MediaInfo.h"
 #include "VideoUtils.h"
 #include "VPXDecoder.h"
 #include "mozilla/layers/KnowsCompositor.h"
-#if defined(MOZ_AV1) && defined(FFVPX_VERSION) && defined(MOZ_WAYLAND)
-#  include "AOMDecoder.h"
-#endif
 #if LIBAVCODEC_VERSION_MAJOR >= 57
 #  include "mozilla/layers/TextureClient.h"
 #endif
 #ifdef MOZ_WAYLAND_USE_VAAPI
 #  include "H264.h"
 #  include "mozilla/layers/DMABUFSurfaceImage.h"
 #  include "mozilla/widget/DMABufLibWrapper.h"
 #  include "FFmpegVideoFramePool.h"
 #  include "va/va.h"
 #endif
 
+#if defined(MOZ_AV1) && defined(MOZ_WAYLAND) && \
+    (defined(FFVPX_VERSION) || LIBAVCODEC_VERSION_MAJOR >= 59)
+#  define FFMPEG_AV1_DECODE 1
+#  include "AOMDecoder.h"
+#endif
+
 #include "libavutil/pixfmt.h"
 #if LIBAVCODEC_VERSION_MAJOR < 54
 #  define AVPixelFormat PixelFormat
 #  define AV_PIX_FMT_YUV420P PIX_FMT_YUV420P
 #  define AV_PIX_FMT_YUVJ420P PIX_FMT_YUVJ420P
 #  define AV_PIX_FMT_YUV420P10LE PIX_FMT_YUV420P10LE
 #  define AV_PIX_FMT_YUV422P PIX_FMT_YUV422P
 #  define AV_PIX_FMT_YUV422P10LE PIX_FMT_YUV422P10LE
@@ -984,17 +987,17 @@ MediaResult FFmpegVideoDecoder<LIBAV_VER
 
   b.mPlanes[0].mWidth = mFrame->width;
   b.mPlanes[0].mHeight = mFrame->height;
   if (mCodecContext->pix_fmt == AV_PIX_FMT_YUV444P ||
       mCodecContext->pix_fmt == AV_PIX_FMT_YUV444P10LE
 #if LIBAVCODEC_VERSION_MAJOR >= 57
       || mCodecContext->pix_fmt == AV_PIX_FMT_YUV444P12LE
 #endif
-#if defined(MOZ_AV1) && defined(FFVPX_VERSION) && defined(MOZ_WAYLAND)
+#if defined(FFMPEG_AV1_DECODE)
       || mCodecContext->pix_fmt == AV_PIX_FMT_GBRP
 #endif
   ) {
     b.mPlanes[1].mWidth = b.mPlanes[2].mWidth = mFrame->width;
     b.mPlanes[1].mHeight = b.mPlanes[2].mHeight = mFrame->height;
     if (mCodecContext->pix_fmt == AV_PIX_FMT_YUV444P10LE) {
       b.mColorDepth = gfx::ColorDepth::COLOR_10;
     }
@@ -1146,17 +1149,17 @@ AVCodecID FFmpegVideoDecoder<LIBAV_VER>:
 #endif
 
 #if LIBAVCODEC_VERSION_MAJOR >= 55
   if (VPXDecoder::IsVP9(aMimeType)) {
     return AV_CODEC_ID_VP9;
   }
 #endif
 
-#if defined(MOZ_AV1) && defined(FFVPX_VERSION) && defined(MOZ_WAYLAND)
+#if defined(FFMPEG_AV1_DECODE)
   if (AOMDecoder::IsAV1(aMimeType)) {
     return AV_CODEC_ID_AV1;
   }
 #endif
 
   return AV_CODEC_ID_NONE;
 }
 
--- a/dom/media/platforms/ffmpeg/FFmpegVideoFramePool.cpp
+++ b/dom/media/platforms/ffmpeg/FFmpegVideoFramePool.cpp
@@ -33,36 +33,42 @@ VideoFrameSurface<LIBAV_VER>::VideoFrame
   mSurface->GlobalRefCountCreate();
   FFMPEG_LOG("VideoFrameSurface: creating surface UID = %d",
              mSurface->GetUID());
 }
 
 void VideoFrameSurface<LIBAV_VER>::LockVAAPIData(
     AVCodecContext* aAVCodecContext, AVFrame* aAVFrame,
     FFmpegLibWrapper* aLib) {
-  FFMPEG_LOG("VideoFrameSurface: VAAPI locking dmabuf surface UID = %d",
-             mSurface->GetUID());
   mLib = aLib;
   mAVHWDeviceContext = aLib->av_buffer_ref(aAVCodecContext->hw_device_ctx);
   mHWAVBuffer = aLib->av_buffer_ref(aAVFrame->buf[0]);
+  FFMPEG_LOG(
+      "VideoFrameSurface: VAAPI locking dmabuf surface UID = %d "
+      "mAVHWDeviceContext %p mHWAVBuffer %p",
+      mSurface->GetUID(), mAVHWDeviceContext, mHWAVBuffer);
 }
 
 void VideoFrameSurface<LIBAV_VER>::ReleaseVAAPIData(bool aForFrameRecycle) {
-  FFMPEG_LOG("VideoFrameSurface: VAAPI releasing dmabuf surface UID = %d",
-             mSurface->GetUID());
+  FFMPEG_LOG(
+      "VideoFrameSurface: VAAPI releasing dmabuf surface UID = %d "
+      "aForFrameRecycle %d mLib %p mAVHWDeviceContext %p mHWAVBuffer %p",
+      mSurface->GetUID(), aForFrameRecycle, mLib, mAVHWDeviceContext,
+      mHWAVBuffer);
 
   // It's possible to unref GPU data while IsUsed() is still set.
   // It can happens when VideoFramePool is deleted while decoder shutdown
   // but related dmabuf surfaces are still used in another process.
   // In such case we don't care as the dmabuf surface will not be
   // recycled for another frame and stays here untill last fd of it
   // is closed.
   if (mLib) {
     mLib->av_buffer_unref(&mHWAVBuffer);
     mLib->av_buffer_unref(&mAVHWDeviceContext);
+    mLib = nullptr;
   }
 
   // If we want to recycle the frame, make sure it's not used
   // by gecko rendering pipeline.
   if (aForFrameRecycle) {
     MOZ_DIAGNOSTIC_ASSERT(!IsUsed());
     mSurface->ReleaseSurface();
   }
--- a/servo/components/style/gecko/media_features.rs
+++ b/servo/components/style/gecko/media_features.rs
@@ -1,18 +1,17 @@
 /* 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 https://mozilla.org/MPL/2.0/. */
 
 //! Gecko's media feature list and evaluator.
 
 use crate::gecko_bindings::bindings;
 use crate::gecko_bindings::structs;
-use crate::media_queries::media_feature::{AllowsRanges, ParsingRequirements};
-use crate::media_queries::media_feature::{Evaluator, MediaFeatureDescription};
+use crate::queries::feature::{AllowsRanges, Evaluator, ParsingRequirements, QueryFeatureDescription};
 use crate::media_queries::{Device, MediaType};
 use crate::values::computed::{Context, CSSPixelLength, Ratio, Resolution};
 use app_units::Au;
 use euclid::default::Size2D;
 
 fn device_size(device: &Device) -> Size2D<Au> {
     let mut width = 0;
     let mut height = 0;
@@ -578,17 +577,17 @@ macro_rules! bool_pref_feature {
     }};
 }
 
 /// Adding new media features requires (1) adding the new feature to this
 /// array, with appropriate entries (and potentially any new code needed
 /// to support new types in these entries and (2) ensuring that either
 /// nsPresContext::MediaFeatureValuesChanged is called when the value that
 /// would be returned by the evaluator function could change.
-pub static MEDIA_FEATURES: [MediaFeatureDescription; 60] = [
+pub static MEDIA_FEATURES: [QueryFeatureDescription; 60] = [
     feature!(
         atom!("width"),
         AllowsRanges::Yes,
         Evaluator::Length(eval_width),
         ParsingRequirements::empty(),
     ),
     feature!(
         atom!("height"),
--- a/servo/components/style/lib.rs
+++ b/servo/components/style/lib.rs
@@ -98,20 +98,21 @@ pub mod font_metrics;
 #[cfg(feature = "gecko")]
 #[allow(unsafe_code)]
 pub mod gecko_bindings;
 pub mod global_style_data;
 pub mod invalidation;
 #[allow(missing_docs)] // TODO.
 pub mod logical_geometry;
 pub mod matching;
-#[macro_use]
 pub mod media_queries;
 pub mod parallel;
 pub mod parser;
+#[macro_use]
+pub mod queries;
 pub mod rule_cache;
 pub mod rule_collector;
 pub mod rule_tree;
 pub mod scoped_tls;
 pub mod selector_map;
 pub mod selector_parser;
 pub mod shared_lock;
 pub mod sharing;
--- a/servo/components/style/media_queries/media_query.rs
+++ b/servo/components/style/media_queries/media_query.rs
@@ -1,17 +1,17 @@
 /* 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 https://mozilla.org/MPL/2.0/. */
 
 //! A media query:
 //!
 //! https://drafts.csswg.org/mediaqueries/#typedef-media-query
 
-use super::media_condition::MediaCondition;
+use crate::queries::QueryCondition;
 use crate::parser::ParserContext;
 use crate::str::string_as_ascii_lowercase;
 use crate::values::CustomIdent;
 use crate::Atom;
 use cssparser::Parser;
 use std::fmt::{self, Write};
 use style_traits::{CssWriter, ParseError, ToCss};
 
@@ -61,17 +61,17 @@ impl MediaType {
 #[derive(Clone, Debug, MallocSizeOf, PartialEq, ToShmem)]
 pub struct MediaQuery {
     /// The qualifier for this query.
     pub qualifier: Option<Qualifier>,
     /// The media type for this query, that can be known, unknown, or "all".
     pub media_type: MediaQueryType,
     /// The condition that this media query contains. This cannot have `or`
     /// in the first level.
-    pub condition: Option<MediaCondition>,
+    pub condition: Option<QueryCondition>,
 }
 
 impl ToCss for MediaQuery {
     fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
     where
         W: Write,
     {
         if let Some(qual) = self.qualifier {
@@ -129,19 +129,19 @@ impl MediaQuery {
                 let qualifier = input.try_parse(Qualifier::parse).ok();
                 let ident = input.expect_ident().map_err(|_| ())?;
                 let media_type = MediaQueryType::parse(&ident)?;
                 Ok((qualifier, Some(media_type)))
             })
             .unwrap_or_default();
 
         let condition = if explicit_media_type.is_none() {
-            Some(MediaCondition::parse(context, input)?)
+            Some(QueryCondition::parse(context, input)?)
         } else if input.try_parse(|i| i.expect_ident_matching("and")).is_ok() {
-            Some(MediaCondition::parse_disallow_or(context, input)?)
+            Some(QueryCondition::parse_disallow_or(context, input)?)
         } else {
             None
         };
 
         let media_type = explicit_media_type.unwrap_or(MediaQueryType::All);
         Ok(Self {
             qualifier,
             media_type,
--- a/servo/components/style/media_queries/mod.rs
+++ b/servo/components/style/media_queries/mod.rs
@@ -1,24 +1,18 @@
 /* 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 https://mozilla.org/MPL/2.0/. */
 
 //! [Media queries][mq].
 //!
 //! [mq]: https://drafts.csswg.org/mediaqueries/
 
-mod media_condition;
 mod media_list;
 mod media_query;
-#[macro_use]
-pub mod media_feature;
-pub mod media_feature_expression;
 
-pub use self::media_condition::MediaCondition;
-pub use self::media_feature_expression::MediaFeatureExpression;
 pub use self::media_list::MediaList;
 pub use self::media_query::{MediaQuery, MediaQueryType, MediaType, Qualifier};
 
 #[cfg(feature = "gecko")]
 pub use crate::gecko::media_queries::Device;
 #[cfg(feature = "servo")]
 pub use crate::servo::media_queries::Device;
rename from servo/components/style/media_queries/media_condition.rs
rename to servo/components/style/queries/condition.rs
--- a/servo/components/style/media_queries/media_condition.rs
+++ b/servo/components/style/queries/condition.rs
@@ -1,17 +1,18 @@
 /* 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 https://mozilla.org/MPL/2.0/. */
 
-//! A media query condition:
+//! A query condition:
 //!
 //! https://drafts.csswg.org/mediaqueries-4/#typedef-media-condition
+//! https://drafts.csswg.org/css-contain-3/#typedef-container-condition
 
-use super::MediaFeatureExpression;
+use super::QueryFeatureExpression;
 use crate::parser::ParserContext;
 use crate::values::computed;
 use cssparser::{Parser, Token};
 use std::fmt::{self, Write};
 use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss};
 
 /// A binary `and` or `or` operator.
 #[derive(Clone, Copy, Debug, Eq, MallocSizeOf, Parse, PartialEq, ToCss, ToShmem)]
@@ -23,74 +24,74 @@ pub enum Operator {
 
 /// Whether to allow an `or` condition or not during parsing.
 #[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, ToCss)]
 enum AllowOr {
     Yes,
     No,
 }
 
-/// Represents a media condition.
+/// Represents a condition.
 #[derive(Clone, Debug, MallocSizeOf, PartialEq, ToShmem)]
-pub enum MediaCondition {
-    /// A simple media feature expression, implicitly parenthesized.
-    Feature(MediaFeatureExpression),
+pub enum QueryCondition {
+    /// A simple feature expression, implicitly parenthesized.
+    Feature(QueryFeatureExpression),
     /// A negation of a condition.
-    Not(Box<MediaCondition>),
+    Not(Box<QueryCondition>),
     /// A set of joint operations.
-    Operation(Box<[MediaCondition]>, Operator),
+    Operation(Box<[QueryCondition]>, Operator),
     /// A condition wrapped in parenthesis.
-    InParens(Box<MediaCondition>),
+    InParens(Box<QueryCondition>),
 }
 
-impl ToCss for MediaCondition {
+impl ToCss for QueryCondition {
     fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
     where
         W: fmt::Write,
     {
         match *self {
-            // NOTE(emilio): MediaFeatureExpression already includes the
+            // NOTE(emilio): QueryFeatureExpression already includes the
             // parenthesis.
-            MediaCondition::Feature(ref f) => f.to_css(dest),
-            MediaCondition::Not(ref c) => {
+            QueryCondition::Feature(ref f) => f.to_css(dest),
+            QueryCondition::Not(ref c) => {
                 dest.write_str("not ")?;
                 c.to_css(dest)
             },
-            MediaCondition::InParens(ref c) => {
+            QueryCondition::InParens(ref c) => {
                 dest.write_char('(')?;
                 c.to_css(dest)?;
                 dest.write_char(')')
             },
-            MediaCondition::Operation(ref list, op) => {
+            QueryCondition::Operation(ref list, op) => {
                 let mut iter = list.iter();
                 iter.next().unwrap().to_css(dest)?;
                 for item in iter {
                     dest.write_char(' ')?;
                     op.to_css(dest)?;
                     dest.write_char(' ')?;
                     item.to_css(dest)?;
                 }
                 Ok(())
             },
         }
     }
 }
 
-impl MediaCondition {
-    /// Parse a single media condition.
+impl QueryCondition {
+    /// Parse a single condition.
     pub fn parse<'i, 't>(
         context: &ParserContext,
         input: &mut Parser<'i, 't>,
     ) -> Result<Self, ParseError<'i>> {
         Self::parse_internal(context, input, AllowOr::Yes)
     }
 
-    /// Parse a single media condition, disallowing `or` expressions.
+    /// Parse a single condition, disallowing `or` expressions.
     ///
-    /// To be used from the legacy media query syntax.
+    /// To be used from the legacy query syntax.
     pub fn parse_disallow_or<'i, 't>(
         context: &ParserContext,
         input: &mut Parser<'i, 't>,
     ) -> Result<Self, ParseError<'i>> {
         Self::parse_internal(context, input, AllowOr::No)
     }
 
     fn parse_internal<'i, 't>(
@@ -104,17 +105,17 @@ impl MediaCondition {
         let is_negation = match *input.next()? {
             Token::ParenthesisBlock => false,
             Token::Ident(ref ident) if ident.eq_ignore_ascii_case("not") => true,
             ref t => return Err(location.new_unexpected_token_error(t.clone())),
         };
 
         if is_negation {
             let inner_condition = Self::parse_in_parens(context, input)?;
-            return Ok(MediaCondition::Not(Box::new(inner_condition)));
+            return Ok(QueryCondition::Not(Box::new(inner_condition)));
         }
 
         // ParenthesisBlock.
         let first_condition = Self::parse_paren_block(context, input)?;
         let operator = match input.try_parse(Operator::parse) {
             Ok(op) => op,
             Err(..) => return Ok(first_condition),
         };
@@ -129,56 +130,56 @@ impl MediaCondition {
 
         let delim = match operator {
             Operator::And => "and",
             Operator::Or => "or",
         };
 
         loop {
             if input.try_parse(|i| i.expect_ident_matching(delim)).is_err() {
-                return Ok(MediaCondition::Operation(
+                return Ok(QueryCondition::Operation(
                     conditions.into_boxed_slice(),
                     operator,
                 ));
             }
 
             conditions.push(Self::parse_in_parens(context, input)?);
         }
     }
 
-    /// Parse a media condition in parentheses.
+    /// Parse a condition in parentheses.
     pub fn parse_in_parens<'i, 't>(
         context: &ParserContext,
         input: &mut Parser<'i, 't>,
     ) -> Result<Self, ParseError<'i>> {
         input.expect_parenthesis_block()?;
         Self::parse_paren_block(context, input)
     }
 
     fn parse_paren_block<'i, 't>(
         context: &ParserContext,
         input: &mut Parser<'i, 't>,
     ) -> Result<Self, ParseError<'i>> {
         input.parse_nested_block(|input| {
             // Base case.
             if let Ok(inner) = input.try_parse(|i| Self::parse(context, i)) {
-                return Ok(MediaCondition::InParens(Box::new(inner)));
+                return Ok(QueryCondition::InParens(Box::new(inner)));
             }
-            let expr = MediaFeatureExpression::parse_in_parenthesis_block(context, input)?;
-            Ok(MediaCondition::Feature(expr))
+            let expr = QueryFeatureExpression::parse_in_parenthesis_block(context, input)?;
+            Ok(QueryCondition::Feature(expr))
         })
     }
 
     /// Whether this condition matches the device and quirks mode.
     pub fn matches(&self, context: &computed::Context) -> bool {
         match *self {
-            MediaCondition::Feature(ref f) => f.matches(context),
-            MediaCondition::InParens(ref c) => c.matches(context),
-            MediaCondition::Not(ref c) => !c.matches(context),
-            MediaCondition::Operation(ref conditions, op) => {
+            QueryCondition::Feature(ref f) => f.matches(context),
+            QueryCondition::InParens(ref c) => c.matches(context),
+            QueryCondition::Not(ref c) => !c.matches(context),
+            QueryCondition::Operation(ref conditions, op) => {
                 let mut iter = conditions.iter();
                 match op {
                     Operator::And => iter.all(|c| c.matches(context)),
                     Operator::Or => iter.any(|c| c.matches(context)),
                 }
             },
         }
     }
rename from servo/components/style/media_queries/media_feature.rs
rename to servo/components/style/queries/feature.rs
--- a/servo/components/style/media_queries/media_feature.rs
+++ b/servo/components/style/queries/feature.rs
@@ -1,51 +1,51 @@
 /* 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 https://mozilla.org/MPL/2.0/. */
 
-//! Media features.
+//! Query features.
 
 use crate::parser::ParserContext;
 use crate::values::computed::{self, CSSPixelLength, Resolution, Ratio};
 use crate::Atom;
 use cssparser::Parser;
 use std::fmt;
 use style_traits::ParseError;
 
 /// A generic discriminant for an enum value.
 pub type KeywordDiscriminant = u8;
 
-type MediaFeatureGetter<T> = fn(device: &computed::Context) -> T;
+type QueryFeatureGetter<T> = fn(device: &computed::Context) -> T;
 
 /// Serializes a given discriminant.
 ///
 /// FIXME(emilio): we could prevent this allocation if the ToCss code would
 /// generate a method for keywords to get the static string or something.
 pub type KeywordSerializer = fn(KeywordDiscriminant) -> String;
 
 /// Parses a given identifier.
 pub type KeywordParser = for<'a, 'i, 't> fn(
     context: &'a ParserContext,
     input: &'a mut Parser<'i, 't>,
 ) -> Result<KeywordDiscriminant, ParseError<'i>>;
 
-/// An evaluator for a given media feature.
+/// An evaluator for a given feature.
 ///
 /// This determines the kind of values that get parsed, too.
 #[allow(missing_docs)]
 pub enum Evaluator {
-    Length(MediaFeatureGetter<CSSPixelLength>),
-    Integer(MediaFeatureGetter<u32>),
-    Float(MediaFeatureGetter<f32>),
-    BoolInteger(MediaFeatureGetter<bool>),
+    Length(QueryFeatureGetter<CSSPixelLength>),
+    Integer(QueryFeatureGetter<u32>),
+    Float(QueryFeatureGetter<f32>),
+    BoolInteger(QueryFeatureGetter<bool>),
     /// A non-negative number ratio, such as the one from device-pixel-ratio.
-    NumberRatio(MediaFeatureGetter<Ratio>),
+    NumberRatio(QueryFeatureGetter<Ratio>),
     /// A resolution.
-    Resolution(MediaFeatureGetter<Resolution>),
+    Resolution(QueryFeatureGetter<Resolution>),
     /// A keyword value.
     Enumerated {
         /// The parser to get a discriminant given a string.
         parser: KeywordParser,
         /// The serializer to get a string from a discriminant.
         ///
         /// This is guaranteed to be called with a keyword that `parser` has
         /// produced.
@@ -62,42 +62,42 @@ pub enum Evaluator {
 /// asserts if that's not true. As of today there's nothing like that (does that
 /// even make sense?).
 macro_rules! keyword_evaluator {
     ($actual_evaluator:ident, $keyword_type:ty) => {{
         fn __parse<'i, 't>(
             context: &$crate::parser::ParserContext,
             input: &mut $crate::cssparser::Parser<'i, 't>,
         ) -> Result<
-            $crate::media_queries::media_feature::KeywordDiscriminant,
+            $crate::queries::feature::KeywordDiscriminant,
             ::style_traits::ParseError<'i>,
         > {
             let kw = <$keyword_type as $crate::parser::Parse>::parse(context, input)?;
-            Ok(kw as $crate::media_queries::media_feature::KeywordDiscriminant)
+            Ok(kw as $crate::queries::feature::KeywordDiscriminant)
         }
 
-        fn __serialize(kw: $crate::media_queries::media_feature::KeywordDiscriminant) -> String {
+        fn __serialize(kw: $crate::queries::feature::KeywordDiscriminant) -> String {
             // This unwrap is ok because the only discriminants that get
             // back to us is the ones that `parse` produces.
             let value: $keyword_type = ::num_traits::cast::FromPrimitive::from_u8(kw).unwrap();
             <$keyword_type as ::style_traits::ToCss>::to_css_string(&value)
         }
 
         fn __evaluate(
             context: &$crate::values::computed::Context,
-            value: Option<$crate::media_queries::media_feature::KeywordDiscriminant>,
+            value: Option<$crate::queries::feature::KeywordDiscriminant>,
         ) -> bool {
             // This unwrap is ok because the only discriminants that get
             // back to us is the ones that `parse` produces.
             let value: Option<$keyword_type> =
                 value.map(|kw| ::num_traits::cast::FromPrimitive::from_u8(kw).unwrap());
             $actual_evaluator(context, value)
         }
 
-        $crate::media_queries::media_feature::Evaluator::Enumerated {
+        $crate::queries::feature::Evaluator::Enumerated {
             parser: __parse,
             serializer: __serialize,
             evaluator: __evaluate,
         }
     }};
 }
 
 bitflags! {
@@ -106,59 +106,59 @@ bitflags! {
     pub struct ParsingRequirements: u8 {
         /// The feature should only be parsed in chrome and ua sheets.
         const CHROME_AND_UA_ONLY = 1 << 0;
         /// The feature requires a -webkit- prefix.
         const WEBKIT_PREFIX = 1 << 1;
     }
 }
 
-/// Whether a media feature allows ranges or not.
+/// Whether a feature allows ranges or not.
 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
 #[allow(missing_docs)]
 pub enum AllowsRanges {
     Yes,
     No,
 }
 
-/// A description of a media feature.
-pub struct MediaFeatureDescription {
-    /// The media feature name, in ascii lowercase.
+/// A description of a feature.
+pub struct QueryFeatureDescription {
+    /// The feature name, in ascii lowercase.
     pub name: Atom,
     /// Whether min- / max- prefixes are allowed or not.
     pub allows_ranges: AllowsRanges,
     /// The evaluator, which we also use to determine which kind of value to
     /// parse.
     pub evaluator: Evaluator,
     /// Different requirements that need to hold for the feature to be
     /// successfully parsed.
     pub requirements: ParsingRequirements,
 }
 
-impl MediaFeatureDescription {
-    /// Whether this media feature allows ranges.
+impl QueryFeatureDescription {
+    /// Whether this feature allows ranges.
     #[inline]
     pub fn allows_ranges(&self) -> bool {
         self.allows_ranges == AllowsRanges::Yes
     }
 }
 
-/// A simple helper to construct a `MediaFeatureDescription`.
+/// A simple helper to construct a `QueryFeatureDescription`.
 macro_rules! feature {
     ($name:expr, $allows_ranges:expr, $evaluator:expr, $reqs:expr,) => {
-        $crate::media_queries::media_feature::MediaFeatureDescription {
+        $crate::queries::feature::QueryFeatureDescription {
             name: $name,
             allows_ranges: $allows_ranges,
             evaluator: $evaluator,
             requirements: $reqs,
         }
     };
 }
 
-impl fmt::Debug for MediaFeatureDescription {
+impl fmt::Debug for QueryFeatureDescription {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        f.debug_struct("MediaFeatureExpression")
+        f.debug_struct("QueryFeatureDescription")
             .field("name", &self.name)
             .field("allows_ranges", &self.allows_ranges)
             .field("requirements", &self.requirements)
             .finish()
     }
 }
rename from servo/components/style/media_queries/media_feature_expression.rs
rename to servo/components/style/queries/feature_expression.rs
--- a/servo/components/style/media_queries/media_feature_expression.rs
+++ b/servo/components/style/queries/feature_expression.rs
@@ -1,42 +1,42 @@
 /* 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 https://mozilla.org/MPL/2.0/. */
 
-//! Parsing for media feature expressions, like `(foo: bar)` or
+//! Parsing for query feature expressions, like `(foo: bar)` or
 //! `(width >= 400px)`.
 
-use super::media_feature::{Evaluator, MediaFeatureDescription};
-use super::media_feature::{KeywordDiscriminant, ParsingRequirements};
+use super::feature::{Evaluator, QueryFeatureDescription};
+use super::feature::{KeywordDiscriminant, ParsingRequirements};
 #[cfg(feature = "gecko")]
 use crate::gecko::media_features::MEDIA_FEATURES;
 use crate::parser::{Parse, ParserContext};
 #[cfg(feature = "servo")]
 use crate::servo::media_queries::MEDIA_FEATURES;
 use crate::str::{starts_with_ignore_ascii_case, string_as_ascii_lowercase};
 use crate::values::computed::{self, Ratio, ToComputedValue};
 use crate::values::specified::{Integer, Length, Number, Resolution};
 use crate::values::CSSFloat;
 use crate::{Atom, Zero};
 use cssparser::{Parser, Token};
 use std::cmp::{Ordering, PartialOrd};
 use std::fmt::{self, Write};
 use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss};
 
-/// The kind of matching that should be performed on a media feature value.
+/// The kind of matching that should be performed on a feature value.
 #[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, ToShmem)]
 pub enum Range {
     /// At least the specified value.
     Min,
     /// At most the specified value.
     Max,
 }
 
-/// The operator that was specified in this media feature.
+/// The operator that was specified in this feature.
 #[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, ToShmem)]
 pub enum Operator {
     /// =
     Equal,
     /// >
     GreaterThan,
     /// >=
     GreaterThanEqual,
@@ -58,18 +58,17 @@ impl ToCss for Operator {
             Operator::GreaterThan => ">",
             Operator::GreaterThanEqual => ">=",
         })
     }
 }
 
 /// Either a `Range` or an `Operator`.
 ///
-/// Ranged media features are not allowed with operations (that'd make no
-/// sense).
+/// Ranged features are not allowed with operations (that'd make no sense).
 #[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, ToShmem)]
 pub enum RangeOrOperator {
     /// A `Range`.
     Range(Range),
     /// An `Operator`.
     Operator(Operator),
 }
 
@@ -116,26 +115,26 @@ impl RangeOrOperator {
                 Operator::GreaterThanEqual => cmp == Ordering::Equal || cmp == Ordering::Greater,
                 Operator::LessThan => cmp == Ordering::Less,
                 Operator::LessThanEqual => cmp == Ordering::Equal || cmp == Ordering::Less,
             },
         }
     }
 }
 
-/// A feature expression contains a reference to the media feature, the value
-/// the media query contained, and the range to evaluate.
+/// A feature expression contains a reference to the feature, the value the
+/// query contained, and the range to evaluate.
 #[derive(Clone, Debug, MallocSizeOf, ToShmem, PartialEq)]
-pub struct MediaFeatureExpression {
+pub struct QueryFeatureExpression {
     feature_index: usize,
-    value: Option<MediaExpressionValue>,
+    value: Option<QueryExpressionValue>,
     range_or_operator: Option<RangeOrOperator>,
 }
 
-impl ToCss for MediaFeatureExpression {
+impl ToCss for QueryFeatureExpression {
     fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
     where
         W: fmt::Write,
     {
         dest.write_str("(")?;
 
         let feature = self.feature();
 
@@ -238,49 +237,48 @@ fn disabled_by_pref(feature: &Atom, cont
         if *feature == atom!("prefers-contrast") {
             return !context.in_ua_or_chrome_sheet() &&
                 !static_prefs::pref!("layout.css.prefers-contrast.enabled");
         }
     }
     false
 }
 
-impl MediaFeatureExpression {
+impl QueryFeatureExpression {
     fn new(
         feature_index: usize,
-        value: Option<MediaExpressionValue>,
+        value: Option<QueryExpressionValue>,
         range_or_operator: Option<RangeOrOperator>,
     ) -> Self {
         debug_assert!(feature_index < MEDIA_FEATURES.len());
         Self {
             feature_index,
             value,
             range_or_operator,
         }
     }
 
-    fn feature(&self) -> &'static MediaFeatureDescription {
+    fn feature(&self) -> &'static QueryFeatureDescription {
         &MEDIA_FEATURES[self.feature_index]
     }
 
-    /// Parse a media expression of the form:
+    /// Parse a feature expression of the form:
     ///
     /// ```
     /// (media-feature: media-value)
     /// ```
     pub fn parse<'i, 't>(
         context: &ParserContext,
         input: &mut Parser<'i, 't>,
     ) -> Result<Self, ParseError<'i>> {
         input.expect_parenthesis_block()?;
         input.parse_nested_block(|input| Self::parse_in_parenthesis_block(context, input))
     }
 
-    /// Parse a media feature expression where we've already consumed the
-    /// parenthesis.
+    /// Parse a feature expression where we've already consumed the parenthesis.
     pub fn parse_in_parenthesis_block<'i, 't>(
         context: &ParserContext,
         input: &mut Parser<'i, 't>,
     ) -> Result<Self, ParseError<'i>> {
         let mut requirements = ParsingRequirements::empty();
         let location = input.current_source_location();
         let ident = input.expect_ident()?;
 
@@ -327,19 +325,18 @@ impl MediaFeatureExpression {
             return Err(location.new_custom_error(
                 StyleParseErrorKind::MediaQueryExpectedFeatureName(ident.clone()),
             ));
         }
 
         let operator = input.try_parse(consume_operation_or_colon);
         let operator = match operator {
             Err(..) => {
-                // If there's no colon, this is a media query of the
-                // form '(<feature>)', that is, there's no value
-                // specified.
+                // If there's no colon, this is a query of the form
+                // '(<feature>)', that is, there's no value specified.
                 //
                 // Gecko doesn't allow ranged expressions without a
                 // value, so just reject them here too.
                 if range.is_some() {
                     return Err(
                         input.new_custom_error(StyleParseErrorKind::RangedExpressionWithNoValue)
                     );
                 }
@@ -365,33 +362,33 @@ impl MediaFeatureExpression {
                             .new_custom_error(StyleParseErrorKind::MediaQueryUnexpectedOperator));
                     }
                     Some(RangeOrOperator::Operator(operator))
                 },
                 None => None,
             },
         };
 
-        let value = MediaExpressionValue::parse(feature, context, input).map_err(|err| {
+        let value = QueryExpressionValue::parse(feature, context, input).map_err(|err| {
             err.location
                 .new_custom_error(StyleParseErrorKind::MediaQueryExpectedFeatureValue)
         })?;
 
         Ok(Self::new(feature_index, Some(value), range_or_operator))
     }
 
-    /// Returns whether this media query evaluates to true for the given device.
+    /// Returns whether this query evaluates to true for the given device.
     pub fn matches(&self, context: &computed::Context) -> bool {
         let value = self.value.as_ref();
 
         macro_rules! expect {
             ($variant:ident) => {
                 value.map(|value| match *value {
-                    MediaExpressionValue::$variant(ref v) => v,
-                    _ => unreachable!("Unexpected MediaExpressionValue"),
+                    QueryExpressionValue::$variant(ref v) => v,
+                    _ => unreachable!("Unexpected QueryExpressionValue"),
                 })
             };
         }
 
         match self.feature().evaluator {
             Evaluator::Length(eval) => {
                 let computed = expect!(Length).map(|specified| {
                     specified.to_computed_value(context)
@@ -437,26 +434,26 @@ impl MediaFeatureExpression {
                 let computed = expect!(BoolInteger).cloned();
                 let boolean = eval(context);
                 computed.map_or(boolean, |v| v == boolean)
             },
         }
     }
 }
 
-/// A value found or expected in a media expression.
+/// A value found or expected in a expression.
 ///
 /// FIXME(emilio): How should calc() serialize in the Number / Integer /
 /// BoolInteger / NumberRatio case, as computed or as specified value?
 ///
 /// If the first, this would need to store the relevant values.
 ///
 /// See: https://github.com/w3c/csswg-drafts/issues/1968
 #[derive(Clone, Debug, MallocSizeOf, PartialEq, ToShmem)]
-pub enum MediaExpressionValue {
+pub enum QueryExpressionValue {
     /// A length.
     Length(Length),
     /// A (non-negative) integer.
     Integer(u32),
     /// A floating point value.
     Float(CSSFloat),
     /// A boolean value, specified as an integer (i.e., either 0 or 1).
     BoolInteger(bool),
@@ -465,67 +462,67 @@ pub enum MediaExpressionValue {
     NumberRatio(Ratio),
     /// A resolution.
     Resolution(Resolution),
     /// An enumerated value, defined by the variant keyword table in the
     /// feature's `mData` member.
     Enumerated(KeywordDiscriminant),
 }
 
-impl MediaExpressionValue {
-    fn to_css<W>(&self, dest: &mut CssWriter<W>, for_expr: &MediaFeatureExpression) -> fmt::Result
+impl QueryExpressionValue {
+    fn to_css<W>(&self, dest: &mut CssWriter<W>, for_expr: &QueryFeatureExpression) -> fmt::Result
     where
         W: fmt::Write,
     {
         match *self {
-            MediaExpressionValue::Length(ref l) => l.to_css(dest),
-            MediaExpressionValue::Integer(v) => v.to_css(dest),
-            MediaExpressionValue::Float(v) => v.to_css(dest),
-            MediaExpressionValue::BoolInteger(v) => dest.write_str(if v { "1" } else { "0" }),
-            MediaExpressionValue::NumberRatio(ratio) => ratio.to_css(dest),
-            MediaExpressionValue::Resolution(ref r) => r.to_css(dest),
-            MediaExpressionValue::Enumerated(value) => match for_expr.feature().evaluator {
+            QueryExpressionValue::Length(ref l) => l.to_css(dest),
+            QueryExpressionValue::Integer(v) => v.to_css(dest),
+            QueryExpressionValue::Float(v) => v.to_css(dest),
+            QueryExpressionValue::BoolInteger(v) => dest.write_str(if v { "1" } else { "0" }),
+            QueryExpressionValue::NumberRatio(ratio) => ratio.to_css(dest),
+            QueryExpressionValue::Resolution(ref r) => r.to_css(dest),
+            QueryExpressionValue::Enumerated(value) => match for_expr.feature().evaluator {
                 Evaluator::Enumerated { serializer, .. } => dest.write_str(&*serializer(value)),
                 _ => unreachable!(),
             },
         }
     }
 
     fn parse<'i, 't>(
-        for_feature: &MediaFeatureDescription,
+        for_feature: &QueryFeatureDescription,
         context: &ParserContext,
         input: &mut Parser<'i, 't>,
-    ) -> Result<MediaExpressionValue, ParseError<'i>> {
+    ) -> Result<QueryExpressionValue, ParseError<'i>> {
         Ok(match for_feature.evaluator {
             Evaluator::Length(..) => {
                 let length = Length::parse_non_negative(context, input)?;
-                MediaExpressionValue::Length(length)
+                QueryExpressionValue::Length(length)
             },
             Evaluator::Integer(..) => {
                 let integer = Integer::parse_non_negative(context, input)?;
-                MediaExpressionValue::Integer(integer.value() as u32)
+                QueryExpressionValue::Integer(integer.value() as u32)
             },
             Evaluator::BoolInteger(..) => {
                 let integer = Integer::parse_non_negative(context, input)?;
                 let value = integer.value();
                 if value > 1 {
                     return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
                 }
-                MediaExpressionValue::BoolInteger(value == 1)
+                QueryExpressionValue::BoolInteger(value == 1)
             },
             Evaluator::Float(..) => {
                 let number = Number::parse(context, input)?;
-                MediaExpressionValue::Float(number.get())
+                QueryExpressionValue::Float(number.get())
             },
             Evaluator::NumberRatio(..) => {
                 use crate::values::specified::Ratio as SpecifiedRatio;
                 let ratio = SpecifiedRatio::parse(context, input)?;
-                MediaExpressionValue::NumberRatio(Ratio::new(ratio.0.get(), ratio.1.get()))
+                QueryExpressionValue::NumberRatio(Ratio::new(ratio.0.get(), ratio.1.get()))
             },
             Evaluator::Resolution(..) => {
-                MediaExpressionValue::Resolution(Resolution::parse(context, input)?)
+                QueryExpressionValue::Resolution(Resolution::parse(context, input)?)
             },
             Evaluator::Enumerated { parser, .. } => {
-                MediaExpressionValue::Enumerated(parser(context, input)?)
+                QueryExpressionValue::Enumerated(parser(context, input)?)
             },
         })
     }
 }
new file mode 100644
--- /dev/null
+++ b/servo/components/style/queries/mod.rs
@@ -0,0 +1,17 @@
+/* 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 https://mozilla.org/MPL/2.0/. */
+
+//! Code shared between [media queries][mq] and [container queries][cq].
+//!
+//! [mq]: https://drafts.csswg.org/mediaqueries/
+//! [cq]: https://drafts.csswg.org/css-contain-3/#container-rule
+
+mod condition;
+
+#[macro_use]
+pub mod feature;
+pub mod feature_expression;
+
+pub use self::condition::QueryCondition;
+pub use self::feature_expression::QueryFeatureExpression;
--- a/servo/components/style/stylesheets/container_rule.rs
+++ b/servo/components/style/stylesheets/container_rule.rs
@@ -1,17 +1,17 @@
 /* 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 https://mozilla.org/MPL/2.0/. */
 
 //! A [`@container`][container] rule.
 //!
 //! [container]: https://drafts.csswg.org/css-contain-3/#container-rule
 
-use crate::media_queries::MediaCondition;
+use crate::queries::QueryCondition;
 use crate::shared_lock::{
     DeepCloneParams, DeepCloneWithLock, Locked, SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard,
 };
 use crate::values::specified::ContainerName;
 use crate::str::CssStringWriter;
 use crate::stylesheets::CssRules;
 use cssparser::SourceLocation;
 #[cfg(feature = "gecko")]
@@ -71,9 +71,9 @@ impl ToCssWithGuard for ContainerRule {
             }
             self.condition.to_css(&mut writer)?;
         }
         self.rules.read_with(guard).to_css_block(guard, dest)
     }
 }
 
 /// TODO: Factor out the media query code to work with containers.
-pub type ContainerCondition = MediaCondition;
+pub type ContainerCondition = QueryCondition;
--- a/servo/components/style/values/specified/source_size_list.rs
+++ b/servo/components/style/values/specified/source_size_list.rs
@@ -1,42 +1,42 @@
 /* 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 https://mozilla.org/MPL/2.0/. */
 
 //! https://html.spec.whatwg.org/multipage/#source-size-list
 
 #[cfg(feature = "gecko")]
 use crate::gecko_bindings::sugar::ownership::{HasBoxFFI, HasFFI, HasSimpleFFI};
-use crate::media_queries::{Device, MediaCondition};
+use crate::media_queries::Device;
 use crate::parser::{Parse, ParserContext};
+use crate::queries::QueryCondition;
 use crate::values::computed::{self, ToComputedValue};
 use crate::values::specified::{Length, NoCalcLength, ViewportPercentageLength};
 use app_units::Au;
 use cssparser::{Delimiter, Parser, Token};
 use selectors::context::QuirksMode;
 use style_traits::ParseError;
 
 /// A value for a `<source-size>`:
 ///
 /// https://html.spec.whatwg.org/multipage/#source-size
 #[derive(Debug)]
 pub struct SourceSize {
-    condition: MediaCondition,
+    condition: QueryCondition,
     value: Length,
 }
 
 impl Parse for SourceSize {
     fn parse<'i, 't>(
         context: &ParserContext,
         input: &mut Parser<'i, 't>,
     ) -> Result<Self, ParseError<'i>> {
-        let condition = MediaCondition::parse(context, input)?;
+        let condition = QueryCondition::parse(context, input)?;
         let value = Length::parse_non_negative(context, input)?;
-
         Ok(Self { condition, value })
     }
 }
 
 /// A value for a `<source-size-list>`:
 ///
 /// https://html.spec.whatwg.org/multipage/#source-size-list
 #[derive(Debug)]
deleted file mode 100644
--- a/toolkit/crashreporter/CrashAnnotations.yaml
+++ b/toolkit/crashreporter/CrashAnnotations.yaml
@@ -890,16 +890,24 @@ TestUnicode:
   type: string
 
 TextureUsage:
   description: >
     Amount of memory in bytes consumed by textures.
   type: string
   ping: true
 
+Throttleable:
+  description: >
+    Whether Socorro can selectively discard this crash report or not. If set
+    to "0" the crash report will always be processed by Socorro. Do not set
+    this annotation within Gecko code, it's only supposed to be used by the
+    crash reporting machinery.
+  type: boolean
+
 TotalPageFile:
   description: >
     Maximum amount of memory that can be committed without extending the swap/page file.
     - Under Windows, populated with the contents of the PERFORMANCE_INFORMATION's
       structure CommitLimit field.
     - Under Linux, populated with /proc/meminfo MemTotal + SwapTotal. The swap file
       typically cannot be extended, so that's a hard limit.
     - Not available on other systems.
--- a/toolkit/crashreporter/CrashSubmit.jsm
+++ b/toolkit/crashreporter/CrashSubmit.jsm
@@ -224,22 +224,21 @@ Submitter.prototype = {
       serverURL = envOverride;
     }
 
     let xhr = new XMLHttpRequest();
     xhr.open("POST", serverURL, true);
 
     let formData = new FormData();
 
+    // tell the server not to throttle this if requested
+    this.extraKeyVals.Throttleable = this.noThrottle ? "0" : "1";
+
     // add the data
     let payload = Object.assign({}, this.extraKeyVals);
-    if (this.noThrottle) {
-      // tell the server not to throttle this, since it was manually submitted
-      payload.Throttleable = "0";
-    }
     let json = new Blob([JSON.stringify(payload)], {
       type: "application/json",
     });
     formData.append("extra", json);
 
     // add the minidumps
     let promises = [
       File.createFromFileName(this.dump, {
@@ -449,17 +448,17 @@ var CrashSubmit = {
    *        One of the SUBMITTED_FROM_* constants representing how the
    *        user submitted this crash.
    * @param params
    *        An object containing any of the following optional parameters:
    *        - recordSubmission
    *          If true, a submission event is recorded in CrashManager.
    *        - noThrottle
    *          If true, this crash report should be submitted with
-   *          an extra parameter of "Throttleable=0" indicating that
+   *          the Throttleable annotation set to "0" indicating that
    *          it should be processed right away. This should be set
    *          when the report is being submitted and the user expects
    *          to see the results immediately. Defaults to false.
    *        - extraExtraKeyVals
    *          An object whose key-value pairs will be merged with the data from
    *          the ".extra" file submitted with the report.  The properties of
    *          this object will override properties of the same name in the
    *          .extra file.