summaryrefslogtreecommitdiffstats
path: root/devtools/client/shared/test/browser_filter-editor-01.js
blob: 106f89dbc49ade91729773792fd2e6c64a793a0f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
/* Any copyright is dedicated to the Public Domain.
   http://creativecommons.org/publicdomain/zero/1.0/ */

"use strict";

// Tests that the Filter Editor Widget parses filter values correctly (setCssValue)

const {
  CSSFilterEditorWidget,
} = require("resource://devtools/client/shared/widgets/FilterWidget.js");

const TEST_URI = CHROME_URL_ROOT + "doc_filter-editor-01.html";

// Verify that the given string consists of a valid CSS URL token.
// Return true on success, false on error.
function verifyURL(string) {
  const lexer = new InspectorCSSParser(string);

  const token = lexer.nextToken();
  if (!token || token.tokenType !== "UnquotedUrl") {
    return false;
  }

  return lexer.nextToken() === null;
}

add_task(async function () {
  const { doc } = await createHost("bottom", TEST_URI);

  const container = doc.querySelector("#filter-container");
  const widget = new CSSFilterEditorWidget(container, "none");

  info("Test parsing of a valid CSS Filter value");
  widget.setCssValue("blur(2px) contrast(200%)");
  is(
    widget.getCssValue(),
    "blur(2px) contrast(200%)",
    "setCssValue should work for computed values"
  );

  info("Test parsing of space-filled value");
  widget.setCssValue("blur(   2px  )   contrast(  2  )");
  is(
    widget.getCssValue(),
    "blur(2px) contrast(200%)",
    "setCssValue should work for spaced values"
  );

  info("Test parsing of string-typed values");
  widget.setCssValue(
    "drop-shadow( 2px  1px 5px black) url( example.svg#filter )"
  );

  is(
    widget.getCssValue(),
    "drop-shadow(2px  1px 5px black) url(example.svg#filter)",
    "setCssValue should work for string-typed values"
  );

  info("Test parsing of mixed-case function names");
  widget.setCssValue("BLUR(2px) Contrast(200%) Drop-Shadow(2px 1px 5px Black)");
  is(
    widget.getCssValue(),
    "BLUR(2px) Contrast(200%) Drop-Shadow(2px 1px 5px Black)",
    "setCssValue should work for mixed-case function names"
  );

  info("Test parsing of invalid filter value");
  widget.setCssValue("totallyinvalid");
  is(
    widget.getCssValue(),
    "none",
    "setCssValue should turn completely invalid value to 'none'"
  );

  info("Test parsing of invalid function argument");
  widget.setCssValue("blur('hello')");
  is(
    widget.getCssValue(),
    "blur(0px)",
    "setCssValue should replace invalid function argument with default"
  );

  info("Test parsing of invalid function argument #2");
  widget.setCssValue("drop-shadow(whatever)");
  is(
    widget.getCssValue(),
    "drop-shadow()",
    "setCssValue should replace invalid drop-shadow argument with empty string"
  );

  info("Test parsing of mixed invalid argument");
  widget.setCssValue("contrast(5%) whatever invert('xxx')");
  is(
    widget.getCssValue(),
    "contrast(5%) invert(0%)",
    "setCssValue should handle multiple errors"
  );

  info("Test parsing of 'unset'");
  widget.setCssValue("unset");
  is(widget.getCssValue(), "unset", "setCssValue should handle 'unset'");
  info("Test parsing of 'initial'");
  widget.setCssValue("initial");
  is(widget.getCssValue(), "initial", "setCssValue should handle 'initial'");
  info("Test parsing of 'inherit'");
  widget.setCssValue("inherit");
  is(widget.getCssValue(), "inherit", "setCssValue should handle 'inherit'");

  info("Test parsing of quoted URL");
  widget.setCssValue("url('invalid ) when ) unquoted')");
  is(
    widget.getCssValue(),
    "url('invalid ) when ) unquoted')",
    "setCssValue should re-quote single-quoted URL contents"
  );
  widget.setCssValue('url("invalid ) when ) unquoted")');
  is(
    widget.getCssValue(),
    'url("invalid ) when ) unquoted")',
    "setCssValue should re-quote double-quoted URL contents"
  );
  widget.setCssValue("url(ordinary)");
  is(
    widget.getCssValue(),
    "url(ordinary)",
    "setCssValue should not quote ordinary unquoted URL contents"
  );

  const quotedurl =
    "url(invalid\\ \\)\\ {\\\twhen\\ }\\ ;\\ \\\\unquoted\\'\\\")";
  ok(verifyURL(quotedurl), "weird URL is valid");
  widget.setCssValue(quotedurl);
  is(
    widget.getCssValue(),
    quotedurl,
    "setCssValue should re-quote weird unquoted URL contents"
  );

  const dataurl =
    "url(data:image/svg+xml;utf8,<svg\\ " +
    'xmlns=\\"http://www.w3.org/2000/svg\\"><filter\\ id=\\"blur\\">' +
    '<feGaussianBlur\\ stdDeviation=\\"3\\"/></filter></svg>#blur)';
  ok(verifyURL(dataurl), "data URL is valid");
  widget.setCssValue(dataurl);
  is(widget.getCssValue(), dataurl, "setCssValue should not mangle data urls");

  widget.destroy();
});