-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
151 additions
and
0 deletions.
There are no files selected for viewing
148 changes: 148 additions & 0 deletions
148
...for-creating-and-navigating-browsing-contexts-by-name/open-features-tokenization-001.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
<!DOCTYPE html> | ||
<meta charset="utf-8"> | ||
<title>HTML: window.open `features`: tokenization -- `noopener`</title> | ||
<link rel="help" href="https://html.spec.whatwg.org/multipage/#apis-for-creating-and-navigating-browsing-contexts-by-name"> | ||
<script src="/resources/testharness.js"></script> | ||
<script src="/resources/testharnessreport.js"></script> | ||
<script> | ||
var windowURL = 'resources/close-self.html'; | ||
|
||
// Tests for how windows features are tokenized into 'name', 'value' | ||
// window features separators are ASCII whitespace, '=' and ',' | ||
|
||
test (t => { | ||
// Tokenizing `name`: initial window features separators are ignored | ||
// Each of these variants should tokenize to ('noopener', '') | ||
var featureVariants = [ | ||
' noopener', | ||
'=noopener', | ||
',,noopener', | ||
',=, noopener', | ||
'\n=noopener=', | ||
'\tnoopener', | ||
'\r,,,=noopener', | ||
'\u000Cnoopener' | ||
]; | ||
featureVariants.forEach(feature => { | ||
var win = window.open(windowURL, '', feature); | ||
assert_equals(win, null, `"${feature}" should activate feature "noopener"`); | ||
}); | ||
}, 'tokenization should skip window features separators before `name`'); | ||
|
||
test (t => { | ||
// Tokenizing `name`: lowercase conversion | ||
// Each of these variants should tokenize as feature ('noopener', '') | ||
// except where indicated | ||
// Note also that `value` is lowercased during tokenization | ||
var featureVariants = [ | ||
'NOOPENER', | ||
'noOpenER', | ||
' NOopener', | ||
'=NOOPENER', | ||
'noopener=NOOPENER', // => ('noopener', 'noopener') | ||
'NOOPENER=noopener' // => ('noopener', 'noopener') | ||
]; | ||
featureVariants.forEach(feature => { | ||
var win = window.open(windowURL, '', feature); | ||
assert_equals(win, null, `"${feature}" should activate feature "noopener"`); | ||
}); | ||
}, 'feature `name` should be converted to ASCII lowercase'); | ||
|
||
test (t => { | ||
// After `name` has been collected, ignore any window features separators until '=' | ||
// except ',' OR a non-window-features-separator — break in those cases | ||
// i.e. ignore whitespace until '=' unless a ',' is encountered first | ||
// Each of these variants should tokenize as feature ('noopener', '') | ||
var featureVariants = [ | ||
'noopener', | ||
' noopener\r', | ||
'noopener\n =', | ||
'noopener,', | ||
'noopener =,', | ||
', noopener =', | ||
'noopener,=', | ||
'noopener foo', // => ('noopener', ''), ('foo', '') | ||
'foo noopener=1', // => ('foo', ''), ('noopener', '1') | ||
'foo=\u000Cnoopener' // => ('foo', ''), ('noopener', '') | ||
]; | ||
featureVariants.forEach(feature => { | ||
var win = window.open(windowURL, '', feature); | ||
assert_equals(win, null, `"${feature}" should activate feature "noopener"`); | ||
}); | ||
}, 'after `name`, tokenization should skip window features separators that are not "=" or ","'); | ||
|
||
test (t => { | ||
// After initial '=', tokenizing should ignore all separators except ',' | ||
// before collecting `value` | ||
// Each of these variants should tokenize as feature ('noopener', '') | ||
// Except where indicated | ||
var featureVariants = [ | ||
'noopener= yes', // => ('noopener', 'yes') | ||
'noopener==,', | ||
'noopener=\n ,', | ||
'noopener = \t ,', | ||
'noopener\n=\r noopener,', // => ('noopener', 'noopener') | ||
'noopener=,yes', // => ('noopener'), ('yes') | ||
'noopener= foo=,', // => ('noopener', 'foo') | ||
'noopener = \u000Cyes' // => ('noopener', 'yes') | ||
]; | ||
featureVariants.forEach(feature => { | ||
var win = window.open(windowURL, '', feature); | ||
assert_equals(win, null, `"${feature}" should activate feature "noopener"`); | ||
}); | ||
}, 'Tokenizing should ignore window feature separators except "," after initial "=" and before value'); | ||
|
||
test (t => { | ||
// Tokenizing `value` should collect any non-separator code points until first separator | ||
var featureVariants = [ | ||
'noopener=noopener', // => ('noopener', 'noopener') | ||
'noopener=yes', // => ('noopener', 'yes') | ||
'noopener = yes ,', // => ('noopener', 'yes') | ||
'noopener=\nyes ,', // => ('noopener', 'yes') | ||
'noopener=yes yes', // => ('noopener', 'yes'), ('yes', '') | ||
'noopener=yes\ts', // => ('noopener', 'yes'), ('s', '') | ||
'noopener==', // => ('noopener', '') | ||
'noopener=0\n,', // => ('noopener', '0') | ||
'==noopener===', // => ('noopener', '') | ||
'noopener==\u000C' // => ('noopener', '') | ||
]; | ||
featureVariants.forEach(feature => { | ||
var win = window.open(windowURL, '', feature); | ||
assert_equals(win, null, `"${feature}" should set "noopener"`); | ||
}); | ||
}, 'Tokenizing should read characters until first window feature separator as `value`'); | ||
|
||
test (t => { | ||
// If tokenizedFeatures contains an entry with the key "noopener"...disown opener | ||
// i.e. `value` should be irrelevant | ||
var featureVariants = [ | ||
'noopener=false', | ||
',noopener=0, ', | ||
'foo=bar,noopener=noopener,', | ||
'noopener=true', | ||
'noopener=foo\nbar\t' | ||
]; | ||
featureVariants.forEach(feature => { | ||
var win = window.open(windowURL, '', feature); | ||
assert_equals(win, null, `"${feature}" should activate feature "noopener"`); | ||
}); | ||
}, '"noopener" should be based on name (key), not value'); | ||
|
||
test (t => { | ||
var invalidFeatureVariants = [ | ||
'-noopener', // => ('-noopener', '') | ||
'NOOPENERRRR', // => ('noopenerrr', '') | ||
'noOpenErR', // => ('noopenerr', '') | ||
'no_opener', // => ('no_opener', '') | ||
' no opener', // => ('no', ''), ('opener', '') | ||
'no\nopener', // => ('no', ''), ('opener', '') | ||
'no,opener', // => ('no', ''), ('opener', '') | ||
'\0noopener', // => ('\0noopener', '') | ||
'noopener\u0000=yes' // => ('noopener\0', 'yes') | ||
]; | ||
invalidFeatureVariants.forEach(feature => { | ||
var win = window.open(windowURL, '', feature); | ||
assert_not_equals(win, null, `"${feature}" should NOT activate feature "noopener"`); | ||
}); | ||
}, 'invalid feature names should not tokenize as "noopener"'); | ||
</script> |
3 changes: 3 additions & 0 deletions
3
...ject/apis-for-creating-and-navigating-browsing-contexts-by-name/resources/close-self.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
<script> | ||
window.close(); | ||
</script> |