Commit ccd2f459 authored by commit-queue@webkit.org's avatar commit-queue@webkit.org
Browse files

Improve srcset parser

https://bugs.webkit.org/show_bug.cgi?id=119423

Patch by Romain Perier <romain.perier@gmail.com> on 2013-09-17
Reviewed by Benjamin Poulain.

Source/WebCore:

Added new tests and covered by existing ones.

* html/parser/HTMLParserIdioms.cpp:
(WebCore::isHTMLSpaceOrComma): Add a new predicate function used by String::find()
to get the first space or comma character from the input string.
(WebCore::parseImagesWithScaleFromSrcSetAttribute): Add a new static function to parse
and extract images with scale from the srcset attribute. All valid candidates are
returned to the caller through a list. This parsing function also adds support
for data URI schemes as described by the specification.
(WebCore::bestFitSourceForImageAttributes): Remove intermediate arrays of string
when parsing. That is more efficient and avoids trashing the data cache
(varying between 20 and 65% faster depending of the amount of data)
The parser now walks along the attribute value and extracts the candidates directly.

LayoutTests:

* fast/hidpi/image-srcset-data-srcset-invalid-inputs.html: Ensures that a various invalid
  form of data uri schemes are supported by the srcset attribute.
* fast/hidpi/image-srcset-data-srcset-valid-inputs.html: Ensures that a various valid
  form of data uri schemes are supported by the srcset attribute.
* fast/hidpi/image-srcset-data-srcset.html: Use comma instead of %.
* fast/hidpi/image-srcset-fraction-1.5x.html: Added.
* fast/hidpi/image-srcset-invalid-inputs-except-one.html: Missing srcset-helper.js. Adding more invalid cases.
* fast/hidpi/image-srcset-invalid-inputs.html: Adding more invalid cases.
* fast/hidpi/image-srcset-nomodifier.html: Updated output as behaviour changed for this case.
* fast/hidpi/image-srcset-space-suffix-nomodifier.html: Ensures that a single candidate with no scale modifier
  is supported by the srcset attribute, even if a space is left at the end.
* fast/hidpi/image-srcset-space-prefix-nomodifier.html: Ensures that a single candidate with no scale modifier
  is supported by the srcset attribute, even if a space is left at the beginning.
* fast/hidpi/image-srcset-space-surrounded-nomodifier.html: Ensures that a single candidate with no scale modifier
  is supported by the srcset attribute, even if it is surrounded by spaces.
* fast/hidpi/image-srcset-data-escaped-srcset.html: Ensures that data uri schemes with escaped characters
  are supported by the srcset attribute.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@155988 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 69f655e7
2013-09-17 Romain Perier <romain.perier@gmail.com>
Improve srcset parser
https://bugs.webkit.org/show_bug.cgi?id=119423
Reviewed by Benjamin Poulain.
* fast/hidpi/image-srcset-data-srcset-invalid-inputs.html: Ensures that a various invalid
form of data uri schemes are supported by the srcset attribute.
* fast/hidpi/image-srcset-data-srcset-valid-inputs.html: Ensures that a various valid
form of data uri schemes are supported by the srcset attribute.
* fast/hidpi/image-srcset-data-srcset.html: Use comma instead of %.
* fast/hidpi/image-srcset-fraction-1.5x.html: Added.
* fast/hidpi/image-srcset-invalid-inputs-except-one.html: Missing srcset-helper.js. Adding more invalid cases.
* fast/hidpi/image-srcset-invalid-inputs.html: Adding more invalid cases.
* fast/hidpi/image-srcset-nomodifier.html: Updated output as behaviour changed for this case.
* fast/hidpi/image-srcset-space-suffix-nomodifier.html: Ensures that a single candidate with no scale modifier
is supported by the srcset attribute, even if a space is left at the end.
* fast/hidpi/image-srcset-space-prefix-nomodifier.html: Ensures that a single candidate with no scale modifier
is supported by the srcset attribute, even if a space is left at the beginning.
* fast/hidpi/image-srcset-space-surrounded-nomodifier.html: Ensures that a single candidate with no scale modifier
is supported by the srcset attribute, even if it is surrounded by spaces.
* fast/hidpi/image-srcset-data-escaped-srcset.html: Ensures that data uri schemes with escaped characters
are supported by the srcset attribute.
2013-09-17 Brent Fulgham <bfulgham@apple.com>
 
[Windows] Disable a number of crashing tests to help the EWS system run more rapidly.
PASS document.getElementById("foo").clientWidth==100 is true
This test passes if the image below is not empty. It ensures that the srcset attribute support data URI schemes with escaped characters.
<html>
<head>
<script src="../../resources/js-test-pre.js"></script>
<script>
if (window.testRunner) {
testRunner.dumpAsText();
}
addEventListener("load", function() {
shouldBeTrue('document.getElementById("foo").clientWidth==100');
}, false);
</script>
</head>
<body id="body">
<div>This test passes if the image below is not empty. It ensures that the srcset attribute support data URI schemes with escaped characters.</div>
<img id="foo" src="" srcset="data:image/svg+xml,<svg%20xmlns='http://www.w3.org/2000/svg'%20width='100'%20height='100'><linearGradient%20id='gradient'><stop%20offset='10%'%20stop-color='#F00'/><stop%20offset='90%'%20stop-color='#fcc'/></linearGradient><rect%20fill='url(#gradient)'%20x='0'%20y='0'%20width='100%'%20height='100%'/></svg> 2x">
</body>
</html>
PASS document.getElementById("foo").clientWidth==150 is true
This test passes if the image below looks like a 2x2 grid (yellow, gray, light green, dark green). In this case the srcset attribute has a base64 url, with the comma escaped.
This test passes if the image below looks like a 2x2 grid (yellow, gray, light green, dark green). In this case the srcset attribute has a base64 url.
This test passes if this img tag below is empty and displays nothing. It ensures that the srcset attribute supports invalid data uri schemes
<html>
<head>
<script src="../js/resources/js-test-pre.js"></script>
<script>
if (window.testRunner) {
testRunner.dumpAsText();
}
</script>
</head>
<body>
<div>This test passes if this img tag below is empty and displays nothing. It ensures that the srcset attribute supports invalid data uri schemes</div>
<img src="" srcset="data:image/png;base64,ThisIsAMalFormedData%/,withForbidden,Characters:!?~&#') 2x, data: 3x, data:;charset= 4x, data:;charset=us-ASCII 5x, data:,BadData 6x, data:foo/bar,foobar 7x, data:foo/bar, 8x, data:foo/bar 9x">
</body>
</html>
This test passes if this img tag below is empty and displays nothing. It ensures that the srcset attribute supports various forms of valid data uri schemes
<html>
<head>
<script src="../js/resources/js-test-pre.js"></script>
<script>
if (window.testRunner) {
testRunner.dumpAsText();
}
</script>
</head>
<body>
<div>This test passes if this img tag below is empty and displays nothing. It ensures that the srcset attribute supports various forms of valid data uri schemes</div>
<img src="" srcset="data:,plaintext 2x, data:;charset=us-ASCII,plaintext 3x, data:text/plain;charset=us-ASCII,plaintext 4x, data:text/plain,plaintext 5x, data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJYAAAA8CAIAAAAL5NQ9AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH2woaBQc4oLEFpAAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAACMSURBVHja7dNBEYAgFEVRPhHMYgAzUIsmVnFvB/fsoQb+ObfBmzMvxneW1D1vzz2wFiEUQiFEKIRCKIQIhVAIhRChEAqhECIUQiEUQoRCKIRCiFAIhVAIEep3xTWTLzzu5oVCKIRCiFAIhVAIEQqhEAohQiEUQiFEKIRCKIQIhVAIhRChEAqhECLUZi3VEwcBMGr1NgAAAABJRU5ErkJggg== 6x">
</body>
</html>
......@@ -12,7 +12,7 @@
</script>
</head>
<body id="body">
<div>This test passes if the image below looks like a 2x2 grid (yellow, gray, light green, dark green). In this case the srcset attribute has a base64 url, with the comma escaped.</div>
<img id="foo" src="" srcset="data:image/png;base64%2CiVBORw0KGgoAAAANSUhEUgAAAJYAAAA8CAIAAAAL5NQ9AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH2woaBQc4oLEFpAAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAACMSURBVHja7dNBEYAgFEVRPhHMYgAzUIsmVnFvB/fsoQb+ObfBmzMvxneW1D1vzz2wFiEUQiFEKIRCKIQIhVAIhRChEAqhECIUQiEUQoRCKIRCiFAIhVAIEep3xTWTLzzu5oVCKIRCiFAIhVAIEQqhEAohQiEUQiFEKIRCKIQIhVAIhRChEAqhECLUZi3VEwcBMGr1NgAAAABJRU5ErkJggg== 2x, data:image/png;base64%2CiVBORw0KGgoAAAANSUhEUgAAAJYAAAA8CAIAAAAL5NQ9AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH2woaBQc4oLEFpAAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAACMSURBVHja7dNBEYAgFEVRPhHMYgAzUIsmVnFvB/fsoQb+ObfBmzMvxneW1D1vzz2wFiEUQiFEKIRCKIQIhVAIhRChEAqhECIUQiEUQoRCKIRCiFAIhVAIEep3xTWTLzzu5oVCKIRCiFAIhVAIEQqhEAohQiEUQiFEKIRCKIQIhVAIhRChEAqhECLUZi3VEwcBMGr1NgAAAABJRU5ErkJggg== 1x">
<div>This test passes if the image below looks like a 2x2 grid (yellow, gray, light green, dark green). In this case the srcset attribute has a base64 url.</div>
<img id="foo" src="" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJYAAAA8CAIAAAAL5NQ9AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH2woaBQc4oLEFpAAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAACMSURBVHja7dNBEYAgFEVRPhHMYgAzUIsmVnFvB/fsoQb+ObfBmzMvxneW1D1vzz2wFiEUQiFEKIRCKIQIhVAIhRChEAqhECIUQiEUQoRCKIRCiFAIhVAIEep3xTWTLzzu5oVCKIRCiFAIhVAIEQqhEAohQiEUQiFEKIRCKIQIhVAIhRChEAqhECLUZi3VEwcBMGr1NgAAAABJRU5ErkJggg== 2x, data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJYAAAA8CAIAAAAL5NQ9AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH2woaBQc4oLEFpAAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAACMSURBVHja7dNBEYAgFEVRPhHMYgAzUIsmVnFvB/fsoQb+ObfBmzMvxneW1D1vzz2wFiEUQiFEKIRCKIQIhVAIhRChEAqhECIUQiEUQoRCKIRCiFAIhVAIEep3xTWTLzzu5oVCKIRCiFAIhVAIEQqhEAohQiEUQiFEKIRCKIQIhVAIhRChEAqhECLUZi3VEwcBMGr1NgAAAABJRU5ErkJggg== 1x">
</body>
</html>
PASS document.getElementById("testimg").clientWidth==200 is true
This test passes if the srcset resource is loaded and displayed as the image
<html>
<head>
<script>
window.targetScaleFactor = 1.5;
</script>
<script src="resources/srcset-helper.js"></script>
<script src="../../resources/js-test-pre.js"></script>
<script>
if (window.testRunner) {
testRunner.dumpAsText();
}
addEventListener("load", function() {
if (internals)
shouldBeTrue('document.getElementById("testimg").clientWidth==200');
}, false);
</script>
</head>
<body>
<div>This test passes if the srcset resource is loaded and displayed as the image</div>
<img src="resources/blue-100-px-square.png" srcset="resources/green-200-px-square.png 2x" id="testimg">
</body>
</html>
<html>
<head>
<script src="resources/srcset-helper.js"></script>
<script src="../../resources/js-test-pre.js"></script>
<script>
if (window.testRunner) {
......@@ -15,6 +16,6 @@
<body id="body">
<div>This test passes if the img tag below is a green square regardless of the scale factor. It ensures that invalid inputs are
ignored and well-formed images are chosen regardless of their qualifiers, once they are the only candidate left</div>
<img id="foo" src="" srcset="1x,, , x , resources/green-200-px-square.png 2x, 2">
<img id="foo" src="" srcset="1x,, , x ,2x , foo.jpg, 3x, bar.jpg 4x 100h, foo.jpg 5, bar.jpg dx, resources/green-200-px-square.png 2x ,"></img>
</body>
</html>
......@@ -5,6 +5,6 @@
<body id="body">
<div>This test passes if this img tag below is empty and displays nothing. It ensures that the srcset attribute supports invalid inputs</div>
<img height="100" width="100" src="" srcset="1x,, , x ,2x "></img>
<img height="100" width="100" src="" srcset="1x,, , x ,2x , foo.jpg, 3x, bar.jpg 4x 100h, foo.jpg 5, bar.jpg dx,foo.jpg,bar.jpg,"></img>
</body>
</html>
PASS document.getElementById("foo").clientWidth==150 is true
This test passes if the image below is not empty. It ensures that a candidate without scale modifier get a default one
<html>
<head>
<script src="resources/srcset-helper.js"></script>
<script src="../../resources/js-test-pre.js"></script>
<script>
if (window.testRunner) {
testRunner.dumpAsText();
}
addEventListener("load", function() {
shouldBeTrue('document.getElementById("foo").clientWidth==150');
}, false);
</script>
</head>
<body id="body">
<div>This test passes if the image below is empty, since the srcset is invalid (does not have a scale modifier anywhere and the src attribute is empty).</div>
<img height="100" width="100" src="" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJYAAAA8CAIAAAAL5NQ9AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH2woaBQc4oLEFpAAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAACMSURBVHja7dNBEYAgFEVRPhHMYgAzUIsmVnFvB/fsoQb+ObfBmzMvxneW1D1vzz2wFiEUQiFEKIRCKIQIhVAIhRChEAqhECIUQiEUQoRCKIRCiFAIhVAIEep3xTWTLzzu5oVCKIRCiFAIhVAIEQqhEAohQiEUQiFEKIRCKIQIhVAIhRChEAqhECLUZi3VEwcBMGr1NgAAAABJRU5ErkJggg==">
<div>This test passes if the image below is not empty. It ensures that a candidate without scale modifier get a default one</div>
<img id="foo" src="" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJYAAAA8CAIAAAAL5NQ9AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH2woaBQc4oLEFpAAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAACMSURBVHja7dNBEYAgFEVRPhHMYgAzUIsmVnFvB/fsoQb+ObfBmzMvxneW1D1vzz2wFiEUQiFEKIRCKIQIhVAIhRChEAqhECIUQiEUQoRCKIRCiFAIhVAIEep3xTWTLzzu5oVCKIRCiFAIhVAIEQqhEAohQiEUQiFEKIRCKIQIhVAIhRChEAqhECLUZi3VEwcBMGr1NgAAAABJRU5ErkJggg==">
</body>
</html>
PASS document.getElementById("foo").clientWidth==150 is true
This test passes if the image below is not empty. It ensures that a candidate without scale modifier get a default one, even with space left at the beginning.
<html>
<head>
<script src="resources/srcset-helper.js"></script>
<script src="../../resources/js-test-pre.js"></script>
<script>
if (window.testRunner) {
testRunner.dumpAsText();
}
addEventListener("load", function() {
shouldBeTrue('document.getElementById("foo").clientWidth==150');
}, false);
</script>
</head>
<body id="body">
<div>This test passes if the image below is not empty. It ensures that a candidate without scale modifier get a default one, even with space left at the beginning.</div>
<img id="foo" src="" srcset=" data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJYAAAA8CAIAAAAL5NQ9AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH2woaBQc4oLEFpAAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAACMSURBVHja7dNBEYAgFEVRPhHMYgAzUIsmVnFvB/fsoQb+ObfBmzMvxneW1D1vzz2wFiEUQiFEKIRCKIQIhVAIhRChEAqhECIUQiEUQoRCKIRCiFAIhVAIEep3xTWTLzzu5oVCKIRCiFAIhVAIEQqhEAohQiEUQiFEKIRCKIQIhVAIhRChEAqhECLUZi3VEwcBMGr1NgAAAABJRU5ErkJggg==">
</body>
</html>
PASS document.getElementById("foo").clientWidth==150 is true
This test passes if the image below is not empty. It ensures that a candidate without scale modifier get a default one, even with space left at the end.
<html>
<head>
<script src="resources/srcset-helper.js"></script>
<script src="../../resources/js-test-pre.js"></script>
<script>
if (window.testRunner) {
testRunner.dumpAsText();
}
addEventListener("load", function() {
shouldBeTrue('document.getElementById("foo").clientWidth==150');
}, false);
</script>
</head>
<body id="body">
<div>This test passes if the image below is not empty. It ensures that a candidate without scale modifier get a default one, even with space left at the end.</div>
<img id="foo" src="" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJYAAAA8CAIAAAAL5NQ9AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH2woaBQc4oLEFpAAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAACMSURBVHja7dNBEYAgFEVRPhHMYgAzUIsmVnFvB/fsoQb+ObfBmzMvxneW1D1vzz2wFiEUQiFEKIRCKIQIhVAIhRChEAqhECIUQiEUQoRCKIRCiFAIhVAIEep3xTWTLzzu5oVCKIRCiFAIhVAIEQqhEAohQiEUQiFEKIRCKIQIhVAIhRChEAqhECLUZi3VEwcBMGr1NgAAAABJRU5ErkJggg== ">
</body>
</html>
PASS document.getElementById("foo").clientWidth==150 is true
This test passes if the image below is not empty. It ensures that a candidate without scale modifier get a default one, even surrounded by spaces.
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment