mirror of
https://github.com/servo/servo.git
synced 2025-06-25 09:34:32 +01:00
DevTools: sources for HTML files should be the whole HTML file (#37456)
To show the contents of inline scripts in the Sources panel, we need to send the whole HTML file from script to devtools, not just the script code. This is trickier than the external script case, but we can look to [how Firefox does it](https://servo.zulipchat.com/#narrow/channel/263398-general/topic/Getting.20the.20original.20page.20HTML.20from.20script/near/524392861) for some inspiration. The process is as follows: - when we execute a script - notify devtools to create the source actor - if it’s an external script, send the script code to the devtools server - if it’s an inline script, don’t send any source contents yet - devtools stores the contents in the source actor - while loading a new document - buffer the markup, so we can send it to devtools - when we finish loading a new document - send the buffered markup to the devtools server - devtools stores the contents in any source actors with no contents yet - when a source actor gets a `source` request - if we have the contents, send those contents to the client - if we don’t have the contents (inline script that loaded while devtools was closed) - FUTURE: try to fetch the markup out of cache - otherwise send `<!-- not available; please reload! -->` Testing: Several tests added to test the changes, also updates an existing test with correct assertion Fixes: https://github.com/servo/servo/issues/36874 --------- Signed-off-by: atbrakhi <atbrakhi@igalia.com> Signed-off-by: Delan Azabani <dazabani@igalia.com> Co-authored-by: Delan Azabani <dazabani@igalia.com>
This commit is contained in:
parent
3feec90528
commit
c8ee11fe77
10 changed files with 177 additions and 29 deletions
|
@ -96,9 +96,9 @@ class DevtoolsTests(unittest.IsolatedAsyncioTestCase):
|
|||
self.assert_sources_list(1, set([tuple(["data:text/html,<script type=module>;</script>"])]))
|
||||
|
||||
def test_source_content_inline_script(self):
|
||||
script_content = "console.log('Hello, world!');"
|
||||
self.run_servoshell(url=f"data:text/html,<script>{script_content}</script>")
|
||||
self.assert_source_content("data:text/html,<script>console.log('Hello, world!');</script>", script_content)
|
||||
script_tag = "<script>console.log('Hello, world!')</script>"
|
||||
self.run_servoshell(url=f"data:text/html,{script_tag}")
|
||||
self.assert_source_content(f"data:text/html,{script_tag}", script_tag)
|
||||
|
||||
def test_source_content_external_script(self):
|
||||
self.start_web_server(test_dir=os.path.join(DevtoolsTests.script_path, "devtools_tests/sources"))
|
||||
|
@ -106,6 +106,41 @@ class DevtoolsTests(unittest.IsolatedAsyncioTestCase):
|
|||
expected_content = 'console.log("external classic");\n'
|
||||
self.assert_source_content(f"{self.base_url}/classic.js", expected_content)
|
||||
|
||||
def test_source_content_html_file(self):
|
||||
self.start_web_server(test_dir=self.get_test_path("sources"))
|
||||
self.run_servoshell()
|
||||
expected_content = open(self.get_test_path("sources/test.html")).read()
|
||||
self.assert_source_content(f"{self.base_url}/test.html", expected_content)
|
||||
|
||||
# Test case that uses innerHTML and would actually need the HTML parser
|
||||
# (innerHTML has a fast path for values that don’t contain b'&' | b'\0' | b'<' | b'\r')
|
||||
def test_source_content_inline_script_with_inner_html(self):
|
||||
script_tag = '<div id="el"></div><script>el.innerHTML="<p>test"</script>'
|
||||
self.run_servoshell(url=f"data:text/html,{script_tag}")
|
||||
self.assert_source_content(f"data:text/html,{script_tag}", script_tag)
|
||||
|
||||
# Test case that uses outerHTML and would actually need the HTML parser
|
||||
# (innerHTML has a fast path for values that don’t contain b'&' | b'\0' | b'<' | b'\r')
|
||||
def test_source_content_inline_script_with_outer_html(self):
|
||||
script_tag = '<div id="el"></div><script>el.outerHTML="<p>test"</script>'
|
||||
self.run_servoshell(url=f"data:text/html,{script_tag}")
|
||||
self.assert_source_content(f"data:text/html,{script_tag}", script_tag)
|
||||
|
||||
# Test case that uses DOMParser and would actually need the HTML parser
|
||||
# (innerHTML has a fast path for values that don’t contain b'&' | b'\0' | b'<' | b'\r')
|
||||
def test_source_content_inline_script_with_domparser(self):
|
||||
script_tag = '<script>(new DOMParser).parseFromString("<p>test","text/html")</script>'
|
||||
self.run_servoshell(url=f"data:text/html,{script_tag}")
|
||||
self.assert_source_content(f"data:text/html,{script_tag}", script_tag)
|
||||
|
||||
# Test case that uses XMLHttpRequest#responseXML and would actually need the HTML parser
|
||||
# (innerHTML has a fast path for values that don’t contain b'&' | b'\0' | b'<' | b'\r')
|
||||
def test_source_content_inline_script_with_responsexml(self):
|
||||
self.start_web_server(test_dir=self.get_test_path("sources_content_with_responsexml"))
|
||||
self.run_servoshell()
|
||||
expected_content = open(self.get_test_path("sources_content_with_responsexml/test.html")).read()
|
||||
self.assert_source_content(f"{self.base_url}/test.html", expected_content)
|
||||
|
||||
# Sets `base_url` and `web_server` and `web_server_thread`.
|
||||
def start_web_server(self, *, test_dir=None):
|
||||
if test_dir is None:
|
||||
|
@ -270,6 +305,9 @@ class DevtoolsTests(unittest.IsolatedAsyncioTestCase):
|
|||
|
||||
client.disconnect()
|
||||
|
||||
def get_test_path(self, path: str) -> str:
|
||||
return os.path.join(DevtoolsTests.script_path, os.path.join("devtools_tests", path))
|
||||
|
||||
|
||||
def run_tests(script_path, build_type: BuildType):
|
||||
DevtoolsTests.script_path = script_path
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
<!doctype html><meta charset=utf-8>
|
|
@ -0,0 +1,11 @@
|
|||
<!doctype html><meta charset=utf-8>
|
||||
<script>
|
||||
const req = new XMLHttpRequest;
|
||||
req.responseType = "document";
|
||||
req.open("GET", "empty.html");
|
||||
req.send(null);
|
||||
req.onreadystatechange = () => {
|
||||
if (req.readyState == XMLHttpRequest.DONE)
|
||||
console.log(req.responseXML);
|
||||
};
|
||||
</script>
|
Loading…
Add table
Add a link
Reference in a new issue