nsMediaFeatures.cpp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913
  1. /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* This Source Code Form is subject to the terms of the Mozilla Public
  3. * License, v. 2.0. If a copy of the MPL was not distributed with this
  4. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. /* the features that media queries can test */
  6. #include "nsMediaFeatures.h"
  7. #include "nsGkAtoms.h"
  8. #include "nsCSSKeywords.h"
  9. #include "nsStyleConsts.h"
  10. #include "nsPresContext.h"
  11. #include "nsCSSValue.h"
  12. #ifdef XP_WIN
  13. #include "mozilla/LookAndFeel.h"
  14. #endif
  15. #include "nsCSSRuleProcessor.h"
  16. #include "nsDeviceContext.h"
  17. #include "nsIBaseWindow.h"
  18. #include "nsIDocument.h"
  19. #include "nsIWidget.h"
  20. #include "nsContentUtils.h"
  21. #include "mozilla/Preferences.h"
  22. #include "mozilla/StyleSheet.h"
  23. #include "mozilla/StyleSheetInlines.h"
  24. using namespace mozilla;
  25. static const nsCSSProps::KTableEntry kOrientationKeywords[] = {
  26. { eCSSKeyword_portrait, NS_STYLE_ORIENTATION_PORTRAIT },
  27. { eCSSKeyword_landscape, NS_STYLE_ORIENTATION_LANDSCAPE },
  28. { eCSSKeyword_UNKNOWN, -1 }
  29. };
  30. static const nsCSSProps::KTableEntry kScanKeywords[] = {
  31. { eCSSKeyword_progressive, NS_STYLE_SCAN_PROGRESSIVE },
  32. { eCSSKeyword_interlace, NS_STYLE_SCAN_INTERLACE },
  33. { eCSSKeyword_UNKNOWN, -1 }
  34. };
  35. static const nsCSSProps::KTableEntry kDisplayModeKeywords[] = {
  36. { eCSSKeyword_browser, NS_STYLE_DISPLAY_MODE_BROWSER },
  37. { eCSSKeyword_minimal_ui, NS_STYLE_DISPLAY_MODE_MINIMAL_UI },
  38. { eCSSKeyword_standalone, NS_STYLE_DISPLAY_MODE_STANDALONE },
  39. { eCSSKeyword_fullscreen, NS_STYLE_DISPLAY_MODE_FULLSCREEN },
  40. { eCSSKeyword_UNKNOWN, -1 }
  41. };
  42. static const nsCSSProps::KTableEntry kPrefersColorSchemeKeywords[] = {
  43. { eCSSKeyword_light, NS_STYLE_PREFERS_COLOR_SCHEME_LIGHT },
  44. { eCSSKeyword_dark, NS_STYLE_PREFERS_COLOR_SCHEME_DARK },
  45. { eCSSKeyword_UNKNOWN, -1 },
  46. };
  47. #ifdef XP_WIN
  48. struct WindowsThemeName {
  49. LookAndFeel::WindowsTheme id;
  50. const wchar_t* name;
  51. };
  52. // Windows theme identities used in the -moz-windows-theme media query.
  53. const WindowsThemeName themeStrings[] = {
  54. { LookAndFeel::eWindowsTheme_Aero, L"aero" },
  55. { LookAndFeel::eWindowsTheme_AeroLite, L"aero-lite" },
  56. { LookAndFeel::eWindowsTheme_Generic, L"generic" }
  57. };
  58. struct OperatingSystemVersionInfo {
  59. LookAndFeel::OperatingSystemVersion id;
  60. const wchar_t* name;
  61. };
  62. // Os version identities used in the -moz-os-version media query.
  63. const OperatingSystemVersionInfo osVersionStrings[] = {
  64. { LookAndFeel::eOperatingSystemVersion_Windows7, L"windows-win7" },
  65. { LookAndFeel::eOperatingSystemVersion_Windows8, L"windows-win8" },
  66. { LookAndFeel::eOperatingSystemVersion_Windows10, L"windows-win10" }
  67. };
  68. #endif
  69. // A helper for four features below
  70. static nsSize
  71. GetSize(nsPresContext* aPresContext)
  72. {
  73. nsSize size;
  74. if (aPresContext->IsRootPaginatedDocument())
  75. // We want the page size, including unprintable areas and margins.
  76. size = aPresContext->GetPageSize();
  77. else
  78. size = aPresContext->GetVisibleArea().Size();
  79. return size;
  80. }
  81. static nsresult
  82. GetWidth(nsPresContext* aPresContext, const nsMediaFeature*,
  83. nsCSSValue& aResult)
  84. {
  85. nsSize size = GetSize(aPresContext);
  86. float pixelWidth = aPresContext->AppUnitsToFloatCSSPixels(size.width);
  87. aResult.SetFloatValue(pixelWidth, eCSSUnit_Pixel);
  88. return NS_OK;
  89. }
  90. static nsresult
  91. GetHeight(nsPresContext* aPresContext, const nsMediaFeature*,
  92. nsCSSValue& aResult)
  93. {
  94. nsSize size = GetSize(aPresContext);
  95. float pixelHeight = aPresContext->AppUnitsToFloatCSSPixels(size.height);
  96. aResult.SetFloatValue(pixelHeight, eCSSUnit_Pixel);
  97. return NS_OK;
  98. }
  99. inline static nsDeviceContext*
  100. GetDeviceContextFor(nsPresContext* aPresContext)
  101. {
  102. // It would be nice to call
  103. // nsLayoutUtils::GetDeviceContextForScreenInfo here, except for two
  104. // things: (1) it can flush, and flushing is bad here, and (2) it
  105. // doesn't really get us consistency in multi-monitor situations
  106. // *anyway*.
  107. return aPresContext->DeviceContext();
  108. }
  109. static bool
  110. ShouldResistFingerprinting(nsPresContext* aPresContext)
  111. {
  112. return nsContentUtils::ShouldResistFingerprinting(aPresContext->GetDocShell());
  113. }
  114. // A helper for three features below.
  115. static nsSize
  116. GetDeviceSize(nsPresContext* aPresContext)
  117. {
  118. nsSize size;
  119. if (ShouldResistFingerprinting(aPresContext) || aPresContext->IsDeviceSizePageSize()) {
  120. size = GetSize(aPresContext);
  121. } else if (aPresContext->IsRootPaginatedDocument()) {
  122. // We want the page size, including unprintable areas and margins.
  123. // XXX The spec actually says we want the "page sheet size", but
  124. // how is that different?
  125. size = aPresContext->GetPageSize();
  126. } else {
  127. GetDeviceContextFor(aPresContext)->
  128. GetDeviceSurfaceDimensions(size.width, size.height);
  129. }
  130. return size;
  131. }
  132. static nsresult
  133. GetDeviceWidth(nsPresContext* aPresContext, const nsMediaFeature*,
  134. nsCSSValue& aResult)
  135. {
  136. nsSize size = GetDeviceSize(aPresContext);
  137. float pixelWidth = aPresContext->AppUnitsToFloatCSSPixels(size.width);
  138. aResult.SetFloatValue(pixelWidth, eCSSUnit_Pixel);
  139. return NS_OK;
  140. }
  141. static nsresult
  142. GetDeviceHeight(nsPresContext* aPresContext, const nsMediaFeature*,
  143. nsCSSValue& aResult)
  144. {
  145. nsSize size = GetDeviceSize(aPresContext);
  146. float pixelHeight = aPresContext->AppUnitsToFloatCSSPixels(size.height);
  147. aResult.SetFloatValue(pixelHeight, eCSSUnit_Pixel);
  148. return NS_OK;
  149. }
  150. static nsresult
  151. GetOrientation(nsPresContext* aPresContext, const nsMediaFeature*,
  152. nsCSSValue& aResult)
  153. {
  154. nsSize size = GetSize(aPresContext);
  155. int32_t orientation;
  156. if (size.width > size.height) {
  157. orientation = NS_STYLE_ORIENTATION_LANDSCAPE;
  158. } else {
  159. // Per spec, square viewports should be 'portrait'
  160. orientation = NS_STYLE_ORIENTATION_PORTRAIT;
  161. }
  162. aResult.SetIntValue(orientation, eCSSUnit_Enumerated);
  163. return NS_OK;
  164. }
  165. static nsresult
  166. GetDeviceOrientation(nsPresContext* aPresContext, const nsMediaFeature*,
  167. nsCSSValue& aResult)
  168. {
  169. nsSize size = GetDeviceSize(aPresContext);
  170. int32_t orientation;
  171. if (size.width > size.height) {
  172. orientation = NS_STYLE_ORIENTATION_LANDSCAPE;
  173. } else {
  174. // Per spec, square viewports should be 'portrait'
  175. orientation = NS_STYLE_ORIENTATION_PORTRAIT;
  176. }
  177. aResult.SetIntValue(orientation, eCSSUnit_Enumerated);
  178. return NS_OK;
  179. }
  180. static nsresult
  181. GetIsResourceDocument(nsPresContext* aPresContext, const nsMediaFeature*,
  182. nsCSSValue& aResult)
  183. {
  184. nsIDocument* doc = aPresContext->Document();
  185. aResult.SetIntValue(doc && doc->IsResourceDoc() ? 1 : 0, eCSSUnit_Integer);
  186. return NS_OK;
  187. }
  188. // Helper for two features below
  189. static nsresult
  190. MakeArray(const nsSize& aSize, nsCSSValue& aResult)
  191. {
  192. RefPtr<nsCSSValue::Array> a = nsCSSValue::Array::Create(2);
  193. a->Item(0).SetIntValue(aSize.width, eCSSUnit_Integer);
  194. a->Item(1).SetIntValue(aSize.height, eCSSUnit_Integer);
  195. aResult.SetArrayValue(a, eCSSUnit_Array);
  196. return NS_OK;
  197. }
  198. static nsresult
  199. GetAspectRatio(nsPresContext* aPresContext, const nsMediaFeature*,
  200. nsCSSValue& aResult)
  201. {
  202. return MakeArray(GetSize(aPresContext), aResult);
  203. }
  204. static nsresult
  205. GetDeviceAspectRatio(nsPresContext* aPresContext, const nsMediaFeature*,
  206. nsCSSValue& aResult)
  207. {
  208. return MakeArray(GetDeviceSize(aPresContext), aResult);
  209. }
  210. static nsresult
  211. GetColor(nsPresContext* aPresContext, const nsMediaFeature*,
  212. nsCSSValue& aResult)
  213. {
  214. uint32_t depth = 24; // Use depth of 24 when resisting fingerprinting.
  215. if (!ShouldResistFingerprinting(aPresContext)) {
  216. // FIXME: This implementation is bogus. nsDeviceContext
  217. // doesn't provide reliable information (should be fixed in bug
  218. // 424386).
  219. // FIXME: On a monochrome device, return 0!
  220. nsDeviceContext *dx = GetDeviceContextFor(aPresContext);
  221. dx->GetDepth(depth);
  222. }
  223. // The spec says to use bits *per color component*, so divide by 3,
  224. // and round down, since the spec says to use the smallest when the
  225. // color components differ.
  226. depth /= 3;
  227. aResult.SetIntValue(int32_t(depth), eCSSUnit_Integer);
  228. return NS_OK;
  229. }
  230. static nsresult
  231. GetColorIndex(nsPresContext* aPresContext, const nsMediaFeature*,
  232. nsCSSValue& aResult)
  233. {
  234. // We should return zero if the device does not use a color lookup
  235. // table. Stuart says that our handling of displays with 8-bit
  236. // color is bad enough that we never change the lookup table to
  237. // match what we're trying to display, so perhaps we should always
  238. // return zero. Given that there isn't any better information
  239. // exposed, we don't have much other choice.
  240. aResult.SetIntValue(0, eCSSUnit_Integer);
  241. return NS_OK;
  242. }
  243. static nsresult
  244. GetMonochrome(nsPresContext* aPresContext, const nsMediaFeature*,
  245. nsCSSValue& aResult)
  246. {
  247. // For color devices we should return 0.
  248. // FIXME: On a monochrome device, return the actual color depth, not
  249. // 0!
  250. aResult.SetIntValue(0, eCSSUnit_Integer);
  251. return NS_OK;
  252. }
  253. static nsresult
  254. GetResolution(nsPresContext* aPresContext, const nsMediaFeature*,
  255. nsCSSValue& aResult)
  256. {
  257. float dpi = 96; // Use 96 when resisting fingerprinting.
  258. if (!ShouldResistFingerprinting(aPresContext)) {
  259. // Resolution measures device pixels per CSS (inch/cm/pixel). We
  260. // return it in device pixels per CSS inches.
  261. dpi = float(nsPresContext::AppUnitsPerCSSInch()) /
  262. float(aPresContext->AppUnitsPerDevPixel());
  263. }
  264. aResult.SetFloatValue(dpi, eCSSUnit_Inch);
  265. return NS_OK;
  266. }
  267. static nsresult
  268. GetScan(nsPresContext* aPresContext, const nsMediaFeature*,
  269. nsCSSValue& aResult)
  270. {
  271. // Since Gecko doesn't support the 'tv' media type, the 'scan'
  272. // feature is never present.
  273. aResult.Reset();
  274. return NS_OK;
  275. }
  276. static nsresult
  277. GetDisplayMode(nsPresContext* aPresContext, const nsMediaFeature*,
  278. nsCSSValue& aResult)
  279. {
  280. nsCOMPtr<nsISupports> container;
  281. if (aPresContext) {
  282. // Calling GetRootPresContext() can be slow, so make sure to call it
  283. // just once.
  284. nsRootPresContext* root = aPresContext->GetRootPresContext();
  285. if (root && root->Document()) {
  286. container = root->Document()->GetContainer();
  287. }
  288. }
  289. nsCOMPtr<nsIBaseWindow> baseWindow = do_QueryInterface(container);
  290. if (!baseWindow) {
  291. aResult.SetIntValue(NS_STYLE_DISPLAY_MODE_BROWSER, eCSSUnit_Enumerated);
  292. return NS_OK;
  293. }
  294. nsCOMPtr<nsIWidget> mainWidget;
  295. baseWindow->GetMainWidget(getter_AddRefs(mainWidget));
  296. int32_t displayMode;
  297. nsSizeMode mode = mainWidget ? mainWidget->SizeMode() : nsSizeMode_Normal;
  298. // Background tabs are always in 'browser' mode for now.
  299. // If new modes are supported, please ensure not cause the regression in
  300. // Bug 1259641.
  301. switch (mode) {
  302. case nsSizeMode_Fullscreen:
  303. displayMode = NS_STYLE_DISPLAY_MODE_FULLSCREEN;
  304. break;
  305. default:
  306. displayMode = NS_STYLE_DISPLAY_MODE_BROWSER;
  307. break;
  308. }
  309. aResult.SetIntValue(displayMode, eCSSUnit_Enumerated);
  310. return NS_OK;
  311. }
  312. static nsresult
  313. GetGrid(nsPresContext* aPresContext, const nsMediaFeature*,
  314. nsCSSValue& aResult)
  315. {
  316. // Gecko doesn't support grid devices (e.g., ttys), so the 'grid'
  317. // feature is always 0.
  318. aResult.SetIntValue(0, eCSSUnit_Integer);
  319. return NS_OK;
  320. }
  321. static nsresult
  322. GetDevicePixelRatio(nsPresContext* aPresContext, const nsMediaFeature*,
  323. nsCSSValue& aResult)
  324. {
  325. if (!ShouldResistFingerprinting(aPresContext)) {
  326. float ratio = aPresContext->CSSPixelsToDevPixels(1.0f);
  327. aResult.SetFloatValue(ratio, eCSSUnit_Number);
  328. } else {
  329. aResult.SetFloatValue(1.0, eCSSUnit_Number);
  330. }
  331. return NS_OK;
  332. }
  333. static nsresult
  334. GetTransform3d(nsPresContext* aPresContext, const nsMediaFeature*,
  335. nsCSSValue& aResult)
  336. {
  337. // Gecko supports 3d transforms, so this feature is always 1.
  338. aResult.SetIntValue(1, eCSSUnit_Integer);
  339. return NS_OK;
  340. }
  341. static nsresult
  342. GetSystemMetric(nsPresContext* aPresContext, const nsMediaFeature* aFeature,
  343. nsCSSValue& aResult)
  344. {
  345. aResult.Reset();
  346. if (ShouldResistFingerprinting(aPresContext)) {
  347. // If "privacy.resistFingerprinting" is enabled, then we simply don't
  348. // return any system-backed media feature values. (No spoofed values returned.)
  349. return NS_OK;
  350. }
  351. MOZ_ASSERT(aFeature->mValueType == nsMediaFeature::eBoolInteger,
  352. "unexpected type");
  353. nsIAtom *metricAtom = *aFeature->mData.mMetric;
  354. bool hasMetric = nsCSSRuleProcessor::HasSystemMetric(metricAtom);
  355. aResult.SetIntValue(hasMetric ? 1 : 0, eCSSUnit_Integer);
  356. return NS_OK;
  357. }
  358. static nsresult
  359. GetWindowsTheme(nsPresContext* aPresContext, const nsMediaFeature* aFeature,
  360. nsCSSValue& aResult)
  361. {
  362. aResult.Reset();
  363. if (ShouldResistFingerprinting(aPresContext)) {
  364. return NS_OK;
  365. }
  366. #ifdef XP_WIN
  367. uint8_t windowsThemeId =
  368. nsCSSRuleProcessor::GetWindowsThemeIdentifier();
  369. // Classic mode should fail to match.
  370. if (windowsThemeId == LookAndFeel::eWindowsTheme_Classic)
  371. return NS_OK;
  372. // Look up the appropriate theme string
  373. for (size_t i = 0; i < ArrayLength(themeStrings); ++i) {
  374. if (windowsThemeId == themeStrings[i].id) {
  375. aResult.SetStringValue(nsDependentString(themeStrings[i].name),
  376. eCSSUnit_Ident);
  377. break;
  378. }
  379. }
  380. #endif
  381. return NS_OK;
  382. }
  383. static nsresult
  384. GetOperatingSystemVersion(nsPresContext* aPresContext, const nsMediaFeature* aFeature,
  385. nsCSSValue& aResult)
  386. {
  387. aResult.Reset();
  388. if (ShouldResistFingerprinting(aPresContext)) {
  389. return NS_OK;
  390. }
  391. #ifdef XP_WIN
  392. int32_t metricResult;
  393. if (NS_SUCCEEDED(
  394. LookAndFeel::GetInt(LookAndFeel::eIntID_OperatingSystemVersionIdentifier,
  395. &metricResult))) {
  396. for (size_t i = 0; i < ArrayLength(osVersionStrings); ++i) {
  397. if (metricResult == osVersionStrings[i].id) {
  398. aResult.SetStringValue(nsDependentString(osVersionStrings[i].name),
  399. eCSSUnit_Ident);
  400. break;
  401. }
  402. }
  403. }
  404. #endif
  405. return NS_OK;
  406. }
  407. static nsresult
  408. GetPrefersColorScheme(nsPresContext* aPresContext, const nsMediaFeature* aFeature,
  409. nsCSSValue& aResult)
  410. {
  411. switch(Preferences::GetInt("browser.display.prefers_color_scheme", 1)) {
  412. case 1:
  413. aResult.SetIntValue(NS_STYLE_PREFERS_COLOR_SCHEME_LIGHT,
  414. eCSSUnit_Enumerated);
  415. break;
  416. case 2:
  417. aResult.SetIntValue(NS_STYLE_PREFERS_COLOR_SCHEME_DARK,
  418. eCSSUnit_Enumerated);
  419. break;
  420. case 3:
  421. // If the pref is 3, we follow ui.color_scheme instead. When following
  422. // ui.color_scheme, light theme is the fallback behavior.
  423. switch(Preferences::GetInt("ui.color_scheme", 1)) {
  424. case 2:
  425. aResult.SetIntValue(NS_STYLE_PREFERS_COLOR_SCHEME_DARK,
  426. eCSSUnit_Enumerated);
  427. break;
  428. default:
  429. aResult.SetIntValue(NS_STYLE_PREFERS_COLOR_SCHEME_LIGHT,
  430. eCSSUnit_Enumerated);
  431. }
  432. break;
  433. default:
  434. aResult.Reset();
  435. }
  436. return NS_OK;
  437. }
  438. static nsresult
  439. GetDarkTheme(nsPresContext* aPresContext, const nsMediaFeature* aFeature,
  440. nsCSSValue& aResult)
  441. {
  442. #ifdef XP_WIN
  443. // Under Windows, do nothing if High Contrast Theme is on.
  444. if (LookAndFeel::GetInt(LookAndFeel::eIntID_UseAccessibilityTheme, 0)) {
  445. aResult.Reset();
  446. return NS_OK;
  447. }
  448. #endif
  449. switch(Preferences::GetInt("ui.color_scheme", 1)) {
  450. case 1:
  451. aResult.SetIntValue(0, eCSSUnit_Integer);
  452. break;
  453. case 2:
  454. aResult.SetIntValue(1, eCSSUnit_Integer);
  455. break;
  456. default:
  457. aResult.Reset();
  458. }
  459. return NS_OK;
  460. }
  461. static nsresult
  462. GetIsGlyph(nsPresContext* aPresContext, const nsMediaFeature* aFeature,
  463. nsCSSValue& aResult)
  464. {
  465. aResult.SetIntValue(aPresContext->IsGlyph() ? 1 : 0, eCSSUnit_Integer);
  466. return NS_OK;
  467. }
  468. /*
  469. * Adding new media features requires (1) adding the new feature to this
  470. * array, with appropriate entries (and potentially any new code needed
  471. * to support new types in these entries and (2) ensuring that either
  472. * nsPresContext::MediaFeatureValuesChanged or
  473. * nsPresContext::PostMediaFeatureValuesChangedEvent is called when the
  474. * value that would be returned by the entry's mGetter changes.
  475. */
  476. /* static */ const nsMediaFeature
  477. nsMediaFeatures::features[] = {
  478. {
  479. &nsGkAtoms::width,
  480. nsMediaFeature::eMinMaxAllowed,
  481. nsMediaFeature::eLength,
  482. nsMediaFeature::eNoRequirements,
  483. { nullptr },
  484. GetWidth
  485. },
  486. {
  487. &nsGkAtoms::height,
  488. nsMediaFeature::eMinMaxAllowed,
  489. nsMediaFeature::eLength,
  490. nsMediaFeature::eNoRequirements,
  491. { nullptr },
  492. GetHeight
  493. },
  494. {
  495. &nsGkAtoms::deviceWidth,
  496. nsMediaFeature::eMinMaxAllowed,
  497. nsMediaFeature::eLength,
  498. nsMediaFeature::eNoRequirements,
  499. { nullptr },
  500. GetDeviceWidth
  501. },
  502. {
  503. &nsGkAtoms::deviceHeight,
  504. nsMediaFeature::eMinMaxAllowed,
  505. nsMediaFeature::eLength,
  506. nsMediaFeature::eNoRequirements,
  507. { nullptr },
  508. GetDeviceHeight
  509. },
  510. {
  511. &nsGkAtoms::orientation,
  512. nsMediaFeature::eMinMaxNotAllowed,
  513. nsMediaFeature::eEnumerated,
  514. nsMediaFeature::eNoRequirements,
  515. { kOrientationKeywords },
  516. GetOrientation
  517. },
  518. {
  519. &nsGkAtoms::aspectRatio,
  520. nsMediaFeature::eMinMaxAllowed,
  521. nsMediaFeature::eIntRatio,
  522. nsMediaFeature::eNoRequirements,
  523. { nullptr },
  524. GetAspectRatio
  525. },
  526. {
  527. &nsGkAtoms::deviceAspectRatio,
  528. nsMediaFeature::eMinMaxAllowed,
  529. nsMediaFeature::eIntRatio,
  530. nsMediaFeature::eNoRequirements,
  531. { nullptr },
  532. GetDeviceAspectRatio
  533. },
  534. {
  535. &nsGkAtoms::color,
  536. nsMediaFeature::eMinMaxAllowed,
  537. nsMediaFeature::eInteger,
  538. nsMediaFeature::eNoRequirements,
  539. { nullptr },
  540. GetColor
  541. },
  542. {
  543. &nsGkAtoms::colorIndex,
  544. nsMediaFeature::eMinMaxAllowed,
  545. nsMediaFeature::eInteger,
  546. nsMediaFeature::eNoRequirements,
  547. { nullptr },
  548. GetColorIndex
  549. },
  550. {
  551. &nsGkAtoms::monochrome,
  552. nsMediaFeature::eMinMaxAllowed,
  553. nsMediaFeature::eInteger,
  554. nsMediaFeature::eNoRequirements,
  555. { nullptr },
  556. GetMonochrome
  557. },
  558. {
  559. &nsGkAtoms::prefers_color_scheme,
  560. nsMediaFeature::eMinMaxNotAllowed,
  561. nsMediaFeature::eEnumerated,
  562. nsMediaFeature::eNoRequirements,
  563. { kPrefersColorSchemeKeywords },
  564. GetPrefersColorScheme
  565. },
  566. {
  567. &nsGkAtoms::resolution,
  568. nsMediaFeature::eMinMaxAllowed,
  569. nsMediaFeature::eResolution,
  570. nsMediaFeature::eNoRequirements,
  571. { nullptr },
  572. GetResolution
  573. },
  574. {
  575. &nsGkAtoms::scan,
  576. nsMediaFeature::eMinMaxNotAllowed,
  577. nsMediaFeature::eEnumerated,
  578. nsMediaFeature::eNoRequirements,
  579. { kScanKeywords },
  580. GetScan
  581. },
  582. {
  583. &nsGkAtoms::grid,
  584. nsMediaFeature::eMinMaxNotAllowed,
  585. nsMediaFeature::eBoolInteger,
  586. nsMediaFeature::eNoRequirements,
  587. { nullptr },
  588. GetGrid
  589. },
  590. {
  591. &nsGkAtoms::displayMode,
  592. nsMediaFeature::eMinMaxNotAllowed,
  593. nsMediaFeature::eEnumerated,
  594. nsMediaFeature::eNoRequirements,
  595. { kDisplayModeKeywords },
  596. GetDisplayMode
  597. },
  598. // Webkit extensions that we support for de-facto web compatibility
  599. // -webkit-{min|max}-device-pixel-ratio (controlled with its own pref):
  600. {
  601. &nsGkAtoms::devicePixelRatio,
  602. nsMediaFeature::eMinMaxAllowed,
  603. nsMediaFeature::eFloat,
  604. nsMediaFeature::eHasWebkitPrefix |
  605. nsMediaFeature::eWebkitDevicePixelRatioPrefEnabled,
  606. { nullptr },
  607. GetDevicePixelRatio
  608. },
  609. // -webkit-transform-3d:
  610. {
  611. &nsGkAtoms::transform_3d,
  612. nsMediaFeature::eMinMaxNotAllowed,
  613. nsMediaFeature::eBoolInteger,
  614. nsMediaFeature::eHasWebkitPrefix,
  615. { nullptr },
  616. GetTransform3d
  617. },
  618. // Mozilla extensions
  619. {
  620. &nsGkAtoms::_moz_dark_theme,
  621. nsMediaFeature::eMinMaxNotAllowed,
  622. nsMediaFeature::eBoolInteger,
  623. nsMediaFeature::eNoRequirements,
  624. { nullptr },
  625. GetDarkTheme
  626. },
  627. {
  628. &nsGkAtoms::_moz_device_pixel_ratio,
  629. nsMediaFeature::eMinMaxAllowed,
  630. nsMediaFeature::eFloat,
  631. nsMediaFeature::eNoRequirements,
  632. { nullptr },
  633. GetDevicePixelRatio
  634. },
  635. {
  636. &nsGkAtoms::_moz_device_orientation,
  637. nsMediaFeature::eMinMaxNotAllowed,
  638. nsMediaFeature::eEnumerated,
  639. nsMediaFeature::eNoRequirements,
  640. { kOrientationKeywords },
  641. GetDeviceOrientation
  642. },
  643. {
  644. &nsGkAtoms::_moz_is_resource_document,
  645. nsMediaFeature::eMinMaxNotAllowed,
  646. nsMediaFeature::eBoolInteger,
  647. nsMediaFeature::eNoRequirements,
  648. { nullptr },
  649. GetIsResourceDocument
  650. },
  651. {
  652. &nsGkAtoms::_moz_color_picker_available,
  653. nsMediaFeature::eMinMaxNotAllowed,
  654. nsMediaFeature::eBoolInteger,
  655. nsMediaFeature::eNoRequirements,
  656. { &nsGkAtoms::color_picker_available },
  657. GetSystemMetric
  658. },
  659. {
  660. &nsGkAtoms::_moz_scrollbar_start_backward,
  661. nsMediaFeature::eMinMaxNotAllowed,
  662. nsMediaFeature::eBoolInteger,
  663. nsMediaFeature::eNoRequirements,
  664. { &nsGkAtoms::scrollbar_start_backward },
  665. GetSystemMetric
  666. },
  667. {
  668. &nsGkAtoms::_moz_scrollbar_start_forward,
  669. nsMediaFeature::eMinMaxNotAllowed,
  670. nsMediaFeature::eBoolInteger,
  671. nsMediaFeature::eNoRequirements,
  672. { &nsGkAtoms::scrollbar_start_forward },
  673. GetSystemMetric
  674. },
  675. {
  676. &nsGkAtoms::_moz_scrollbar_end_backward,
  677. nsMediaFeature::eMinMaxNotAllowed,
  678. nsMediaFeature::eBoolInteger,
  679. nsMediaFeature::eNoRequirements,
  680. { &nsGkAtoms::scrollbar_end_backward },
  681. GetSystemMetric
  682. },
  683. {
  684. &nsGkAtoms::_moz_scrollbar_end_forward,
  685. nsMediaFeature::eMinMaxNotAllowed,
  686. nsMediaFeature::eBoolInteger,
  687. nsMediaFeature::eNoRequirements,
  688. { &nsGkAtoms::scrollbar_end_forward },
  689. GetSystemMetric
  690. },
  691. {
  692. &nsGkAtoms::_moz_scrollbar_thumb_proportional,
  693. nsMediaFeature::eMinMaxNotAllowed,
  694. nsMediaFeature::eBoolInteger,
  695. nsMediaFeature::eNoRequirements,
  696. { &nsGkAtoms::scrollbar_thumb_proportional },
  697. GetSystemMetric
  698. },
  699. {
  700. &nsGkAtoms::_moz_overlay_scrollbars,
  701. nsMediaFeature::eMinMaxNotAllowed,
  702. nsMediaFeature::eBoolInteger,
  703. nsMediaFeature::eNoRequirements,
  704. { &nsGkAtoms::overlay_scrollbars },
  705. GetSystemMetric
  706. },
  707. {
  708. &nsGkAtoms::_moz_windows_default_theme,
  709. nsMediaFeature::eMinMaxNotAllowed,
  710. nsMediaFeature::eBoolInteger,
  711. nsMediaFeature::eNoRequirements,
  712. { &nsGkAtoms::windows_default_theme },
  713. GetSystemMetric
  714. },
  715. {
  716. &nsGkAtoms::_moz_mac_graphite_theme,
  717. nsMediaFeature::eMinMaxNotAllowed,
  718. nsMediaFeature::eBoolInteger,
  719. nsMediaFeature::eNoRequirements,
  720. { &nsGkAtoms::mac_graphite_theme },
  721. GetSystemMetric
  722. },
  723. {
  724. &nsGkAtoms::_moz_mac_lion_theme,
  725. nsMediaFeature::eMinMaxNotAllowed,
  726. nsMediaFeature::eBoolInteger,
  727. nsMediaFeature::eNoRequirements,
  728. { &nsGkAtoms::mac_lion_theme },
  729. GetSystemMetric
  730. },
  731. {
  732. &nsGkAtoms::_moz_mac_yosemite_theme,
  733. nsMediaFeature::eMinMaxNotAllowed,
  734. nsMediaFeature::eBoolInteger,
  735. nsMediaFeature::eNoRequirements,
  736. { &nsGkAtoms::mac_yosemite_theme },
  737. GetSystemMetric
  738. },
  739. {
  740. &nsGkAtoms::_moz_windows_accent_color_applies,
  741. nsMediaFeature::eMinMaxNotAllowed,
  742. nsMediaFeature::eBoolInteger,
  743. nsMediaFeature::eNoRequirements,
  744. { &nsGkAtoms::windows_accent_color_applies },
  745. GetSystemMetric
  746. },
  747. {
  748. &nsGkAtoms::_moz_windows_accent_color_is_dark,
  749. nsMediaFeature::eMinMaxNotAllowed,
  750. nsMediaFeature::eBoolInteger,
  751. nsMediaFeature::eNoRequirements,
  752. { &nsGkAtoms::windows_accent_color_is_dark },
  753. GetSystemMetric
  754. },
  755. {
  756. &nsGkAtoms::_moz_windows_compositor,
  757. nsMediaFeature::eMinMaxNotAllowed,
  758. nsMediaFeature::eBoolInteger,
  759. nsMediaFeature::eNoRequirements,
  760. { &nsGkAtoms::windows_compositor },
  761. GetSystemMetric
  762. },
  763. {
  764. &nsGkAtoms::_moz_windows_classic,
  765. nsMediaFeature::eMinMaxNotAllowed,
  766. nsMediaFeature::eBoolInteger,
  767. nsMediaFeature::eNoRequirements,
  768. { &nsGkAtoms::windows_classic },
  769. GetSystemMetric
  770. },
  771. {
  772. &nsGkAtoms::_moz_windows_glass,
  773. nsMediaFeature::eMinMaxNotAllowed,
  774. nsMediaFeature::eBoolInteger,
  775. nsMediaFeature::eNoRequirements,
  776. { &nsGkAtoms::windows_glass },
  777. GetSystemMetric
  778. },
  779. {
  780. &nsGkAtoms::_moz_touch_enabled,
  781. nsMediaFeature::eMinMaxNotAllowed,
  782. nsMediaFeature::eBoolInteger,
  783. nsMediaFeature::eNoRequirements,
  784. { &nsGkAtoms::touch_enabled },
  785. GetSystemMetric
  786. },
  787. {
  788. &nsGkAtoms::_moz_menubar_drag,
  789. nsMediaFeature::eMinMaxNotAllowed,
  790. nsMediaFeature::eBoolInteger,
  791. nsMediaFeature::eNoRequirements,
  792. { &nsGkAtoms::menubar_drag },
  793. GetSystemMetric
  794. },
  795. {
  796. &nsGkAtoms::_moz_windows_theme,
  797. nsMediaFeature::eMinMaxNotAllowed,
  798. nsMediaFeature::eIdent,
  799. nsMediaFeature::eNoRequirements,
  800. { nullptr },
  801. GetWindowsTheme
  802. },
  803. {
  804. &nsGkAtoms::_moz_os_version,
  805. nsMediaFeature::eMinMaxNotAllowed,
  806. nsMediaFeature::eIdent,
  807. nsMediaFeature::eNoRequirements,
  808. { nullptr },
  809. GetOperatingSystemVersion
  810. },
  811. {
  812. &nsGkAtoms::_moz_swipe_animation_enabled,
  813. nsMediaFeature::eMinMaxNotAllowed,
  814. nsMediaFeature::eBoolInteger,
  815. nsMediaFeature::eNoRequirements,
  816. { &nsGkAtoms::swipe_animation_enabled },
  817. GetSystemMetric
  818. },
  819. {
  820. &nsGkAtoms::_moz_physical_home_button,
  821. nsMediaFeature::eMinMaxNotAllowed,
  822. nsMediaFeature::eBoolInteger,
  823. nsMediaFeature::eNoRequirements,
  824. { &nsGkAtoms::physical_home_button },
  825. GetSystemMetric
  826. },
  827. // Internal -moz-is-glyph media feature: applies only inside SVG glyphs.
  828. // Internal because it is really only useful in the user agent anyway
  829. // and therefore not worth standardizing.
  830. {
  831. &nsGkAtoms::_moz_is_glyph,
  832. nsMediaFeature::eMinMaxNotAllowed,
  833. nsMediaFeature::eBoolInteger,
  834. nsMediaFeature::eNoRequirements,
  835. { nullptr },
  836. GetIsGlyph
  837. },
  838. // Null-mName terminator:
  839. {
  840. nullptr,
  841. nsMediaFeature::eMinMaxAllowed,
  842. nsMediaFeature::eInteger,
  843. nsMediaFeature::eNoRequirements,
  844. { nullptr },
  845. nullptr
  846. },
  847. };