browser_discovery_styles.js 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. "use strict";
  2. function fakePref(layout) {
  3. return ["browser.newtabpage.activity-stream.discoverystream.config", JSON.stringify({
  4. enabled: true,
  5. layout_endpoint: `data:,${encodeURIComponent(JSON.stringify(layout))}`,
  6. })];
  7. }
  8. test_newtab({
  9. async before({pushPrefs}) {
  10. await pushPrefs(fakePref({
  11. layout: [{
  12. width: 12,
  13. components: [{
  14. type: "TopSites",
  15. }, {
  16. type: "HorizontalRule",
  17. styles: {
  18. "hr": "border-width: 3.14159mm",
  19. },
  20. }],
  21. }],
  22. }));
  23. },
  24. test: async function test_hr_override() {
  25. const hr = await ContentTaskUtils.waitForCondition(() => content.document.querySelector("hr"));
  26. ok(content.getComputedStyle(hr).borderTopWidth.match(/11.?\d*px/), "applied and normalized hr component width override");
  27. },
  28. });
  29. test_newtab({
  30. async before({pushPrefs}) {
  31. await pushPrefs(fakePref({
  32. layout: [{
  33. width: 12,
  34. components: [{
  35. type: "TopSites",
  36. }, {
  37. type: "HorizontalRule",
  38. styles: {
  39. "*": "color: #f00",
  40. "": "font-size: 1.2345cm",
  41. "hr": "font-weight: 12345",
  42. },
  43. }],
  44. }],
  45. }));
  46. },
  47. test: async function test_multiple_overrides() {
  48. const hr = await ContentTaskUtils.waitForCondition(() => content.document.querySelector("hr"));
  49. const styles = content.getComputedStyle(hr);
  50. is(styles.color, "rgb(255, 0, 0)", "applied and normalized color");
  51. is(styles.fontSize, "46.65px", "applied and normalized font size");
  52. is(styles.fontWeight, "400", "applied and normalized font weight");
  53. },
  54. });
  55. test_newtab({
  56. async before({pushPrefs}) {
  57. await pushPrefs(fakePref({
  58. layout: [{
  59. width: 12,
  60. components: [{
  61. type: "HorizontalRule",
  62. styles: {
  63. // NB: Use display: none to avoid network requests to unfiltered urls
  64. "hr": `display: none;
  65. background-image: url(https://example.com/background);
  66. content: url(chrome://browser/content);
  67. cursor: url( resource://activity-stream/cursor ), auto;
  68. list-style-image: url('https://img-getpocket.cdn.mozilla.net/list');`,
  69. },
  70. }],
  71. }],
  72. }));
  73. },
  74. test: async function test_url_filtering() {
  75. const hr = await ContentTaskUtils.waitForCondition(() => content.document.querySelector("hr"));
  76. const styles = content.getComputedStyle(hr);
  77. is(styles.backgroundImage, "none", "filtered out invalid background image url");
  78. is(styles.content, `url("chrome://browser/content/browser.xul")`, "applied, normalized and allowed content url");
  79. is(styles.cursor, `url("resource://activity-stream/cursor"), auto`, "applied, normalized and allowed cursor url");
  80. is(styles.listStyleImage, `url("https://img-getpocket.cdn.mozilla.net/list")`, "applied, normalized and allowed list style image url");
  81. },
  82. });
  83. test_newtab({
  84. async before({pushPrefs}) {
  85. await pushPrefs(fakePref({
  86. layout: [{
  87. width: 12,
  88. components: [{
  89. type: "HorizontalRule",
  90. styles: {
  91. "@media (min-width: 0)": "content: url(chrome://browser/content)",
  92. "@media (min-width: 0) *": "content: url(chrome://browser/content)",
  93. "@media (min-width: 0) { * }": "content: url(chrome://browser/content)",
  94. },
  95. }],
  96. }],
  97. }));
  98. },
  99. test: async function test_atrule_filtering() {
  100. const hr = await ContentTaskUtils.waitForCondition(() => content.document.querySelector("hr"));
  101. is(content.getComputedStyle(hr).content, "none", "filtered out attempted @media query");
  102. },
  103. });