-
Notifications
You must be signed in to change notification settings - Fork 3.9k
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
Install global submit listener only when amp-form extension is registered #17246
Conversation
src/document-submit.js
Outdated
ampdoc.getRootNode().addEventListener('submit', onDocumentFormSubmit_, true); | ||
// Register global submit event listener only if the amp-form | ||
// extension is used. Allowing the usage of native forms, otherwise. | ||
return getElementServiceIfAvailableForDoc(ampdoc, 'amp-form', 'amp-form') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will delay installation of the event listener until amp-form
extension is installed. We should instead simply check if the extension will be installed and synchronously install or skip the event listener.
I think we can add a new function to element-service.js that uses extensionScriptsInNode()
and rework waitForExtensionIfPresent
to use it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done. Thanks
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you update the PR description with how you tested this change?
src/element-service.js
Outdated
* installation. | ||
* @param {HTMLHeadElement|Element|ShadowRoot} head | ||
* @param {string} extensionId | ||
* return {!Promise<boolean>} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@return
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
src/element-service.js
Outdated
@@ -222,7 +233,7 @@ function waitForExtensionIfPresent(win, extension, head) { | |||
|
|||
// TODO(jpettitt) investigate registerExtension to short circuit | |||
// the dom call in extensionScriptsInNode() | |||
if (!extensionScriptsInNode(head).includes(extension)) { | |||
if (!isExtensionScriptInNode(head)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should pass extension
here right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd assume tests started to fail given this change. Might want to add some tests if not!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
right. gulp check-types task did catch this. Thanks all.
}; | ||
}); | ||
|
||
afterEach(() => sandbox.reset()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't be necessary if you don't create the sandbox in beforeEach()
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed
src/document-submit.js
Outdated
ampdoc.getRootNode().addEventListener('submit', onDocumentFormSubmit_, true); | ||
// Register global submit event listener only if the amp-form | ||
// extension is used. Allowing the usage of native forms, otherwise. | ||
if (isExtensionScriptInNode(ampdoc.getHeadNode(), 'amp-form')) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So installGlobalSubmitListenerForDoc
get called super early in the AMP runtime (just after styles are installed). I don't know if <head>
's children will be fully parsed by then, meaning we may miss that <script src="amp-form.js">
is included in the head.
That's the reason getElementServiceIfAvailableForDoc
waits for whenBodyAvailable
first.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As discussed offline yesterday. Modified new isExtensionScriptInNode method to wait for body before making checking that the script is present in head. Thanks
src/document-submit.js
Outdated
ampdoc.win, | ||
ampdoc.getHeadNode(), | ||
'amp-form') | ||
.then(isAmpFormExtension => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: ampFormInstalled
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
src/element-service.js
Outdated
* @return {!Promise<boolean>} | ||
*/ | ||
export function isExtensionScriptInNode(win, head, extensionId) { | ||
return dom.waitForBodyPromise(win.document) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this will do the right thing in PWA, since win.document.body
!= ampdoc.getBody()
. 😓
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
sandbox.spy(rootNode, 'addEventListener'); | ||
installGlobalSubmitListenerForDoc(ampDoc); | ||
expect(rootNode.addEventListener).called; | ||
installGlobalSubmitListenerForDoc(ampdoc).then(() => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You have to return the promise in order for Mocha to wait for it. Otherwise, the nested expect()
may not be called.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
Codecov Report
@@ Coverage Diff @@
## master #17246 +/- ##
==========================================
+ Coverage 77.45% 77.46% +<.01%
==========================================
Files 565 565
Lines 41439 41510 +71
==========================================
+ Hits 32097 32155 +58
- Misses 9342 9355 +13
Continue to review full report at Codecov.
|
src/element-service.js
Outdated
* @return {!Promise<boolean>} | ||
*/ | ||
export function isExtensionScriptInNode( | ||
whenbodyAvailPromise, head, extensionId) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pass in the ampdoc
instead of them providing the whenBody
and head
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done.
@choumx @jridgewell note the comment in test-document-submit.js. I tried fixing the test but was not able too and was spending too much time figuring out why my fix wasn't working so i left a comment in the meantime. I'll have to revisit. Let me know if I can follow up in a separate PR or if i should just fix it. Thanks |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@alabiaga Fixed the recursive test issue. Previously, the global submit listener installed in _init_tests.js was picking up the submit
event. With your change, it was no longer adding the event listener since the amp-form
script is not present in the document head.
To fix it, we needed to add the amp-form
script to the test window's document head and install the global submit listener given the correct AmpDoc
.
@choumx thanks for the fix. As discussed offline I actually did this very same change and yet it wasn't passing for me. |
@choumx oh i see you installed the global submit event listener in the beforeEach which I didn't do. Thanks again |
…ered (ampproject#17246) * install global submit listener only when amp-form extension is registered * fix tests * address comments * fixes * wait for body before checking for script in head * fix test * add comment * address comments * Fix form recursive submit test. * Remove comment.
…ered (ampproject#17246) * install global submit listener only when amp-form extension is registered * fix tests * address comments * fixes * wait for body before checking for script in head * fix test * add comment * address comments * Fix form recursive submit test. * Remove comment.
fixes #16761
Next steps is to possibly move some of the logic from document-submit to the amp-form component. I still think this is possible, with some additional code changes and checks in the amp-form extension.
Tested by running the local gulp server and looking at examples/forms.amp.html. I then edited that file and removed the amp-form script and verified that the xhr service (xhr-impl) and this document-submit global event did not intercept any submits from the form via debug statements.