Skip to content

Generalize blob url handling in scriptDirectory computation to also handle workers #6894

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jul 25, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion emcc.py
Original file line number Diff line number Diff line change
Expand Up @@ -2612,8 +2612,10 @@ def modularize():

return %(EXPORT_NAME)s;
};
// When MODULARIZE, this JS may be executed later, after document.currentScript
// is gone, so we save it.
%(EXPORT_NAME)s = %(EXPORT_NAME)s.bind({
_currentScript: typeof document !== 'undefined' ? document.currentScript : undefined
_scriptDir: typeof document !== 'undefined' && document.currentScript ? document.currentScript.src : undefined
})%(instantiate)s;
''' % {
'EXPORT_NAME': shared.Settings.EXPORT_NAME,
Expand Down
27 changes: 17 additions & 10 deletions src/shell.js
Original file line number Diff line number Diff line change
Expand Up @@ -230,18 +230,25 @@ if (ENVIRONMENT_IS_SHELL) {
#if ENVIRONMENT_MAY_BE_WEB_OR_WORKER
if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) {
if (ENVIRONMENT_IS_WEB) {
if (document.currentScript) {
scriptDirectory = document.currentScript.src;
}
} else { // worker
scriptDirectory = self.location.href;
}
#if MODULARIZE
// When MODULARIZE, this JS may be executed later, after document.currentScript is gone, so we send it
// using this._currentScript.
var currentScript = this['_currentScript'] || document.currentScript;
#else
var currentScript = document.currentScript;
// When MODULARIZE, this JS may be executed later, after document.currentScript
// is gone, so we saved it, and we use it here instead of any other info.
if (this['_scriptDir']) {
scriptDirectory = this['_scriptDir'];
}
#endif
if (currentScript.src.indexOf('blob:') !== 0) {
scriptDirectory = currentScript.src.split('/').slice(0, -1).join('/') + '/';
}
} else if (ENVIRONMENT_IS_WORKER) {
scriptDirectory = self.location.href.split('/').slice(0, -1).join('/') + '/';
// blob urls look like blob:http://site.com/etc/etc and we cannot infer anything from them.
// otherwise, slice off the final part of the url to find the script directory.
if (scriptDirectory.indexOf('blob:') !== 0) {
scriptDirectory = scriptDirectory.split('/').slice(0, -1).join('/') + '/';
} else {
scriptDirectory = '';
}

#if ENVIRONMENT
Expand Down
31 changes: 31 additions & 0 deletions tests/test_browser.py
Original file line number Diff line number Diff line change
Expand Up @@ -3972,3 +3972,34 @@ def test_browser_run_from_different_directory_async(self):
''')

self.run_browser('test-subdir.html', None, '/report_result?0')

# Similar to `test_browser_run_from_different_directory`, but
# also also we eval the initial code, so currentScript is not present. That prevents us
# from finding the file in a subdir, but here we at least check we do not regress compared to the
# normal case of finding in the current dir.
# In addition, check for new Module(), which overrides the bind() and replaces the object
# which saved the _scriptDir. Again, we can't get the script dir that way, but at least we
# should not regress compared to the normal case.
def test_browser_modularize_no_current_script(self):
src = open(path_from_root('tests', 'browser_test_hello_world.c')).read()
open('test.c', 'w').write(self.with_report_result(src))
# compile the code with the modularize feature and the preload-file option enabled
Popen([PYTHON, EMCC, 'test.c', '-o', 'test.js', '-s', 'MODULARIZE=1']).communicate()
for creation in (
'Module();',
'new Module();'
):
print(creation)
open('test.html', 'w').write('''
<script>
setTimeout(function() {
var xhr = new XMLHttpRequest();
xhr.open('GET', 'test.js', false);
xhr.send(null);
eval(xhr.responseText);
%s
}, 1);
</script>
''' % creation)
self.run_browser('test.html', None, '/report_result?0')