-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
[RNMobile] Update Sandbox component resizing handler #49147
Conversation
- Converts function to a literal string ( to avoid calling `.toString` ) - Uses `WebView.injectedJavaScript` to inject the resize listeners
`(${ observeAndResizeJS.toString() })();`, | ||
} } | ||
/> | ||
{ customJS && ( |
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.
Keeping the ability to inject customJS
but I haven't verified if an custom script will work on Android. I'm fine with removing this since it's not verified injecting scripts this way will work.
Instead I can add the customJS
override in the injectedJavaScript
prop although I'm not sure why we would want the core resize events to be overridden.
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.
Probably we could also inject the customJS
via the injectedJavaScript
, instead of adding it to the HTML. Especially if we know that can have issues when running on Android.
Instead I can add the customJS override in the injectedJavaScript prop although I'm not sure why we would want the core resize events to be overridden.
Actually, there's a case for WordPress embeds:
/** | |
* Checks for WordPress embed events signaling the height change when iframe | |
* content loads or iframe's window is resized. The event is sent from | |
* WordPress core via the window.postMessage API. | |
* | |
* References: | |
* window.postMessage: https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage | |
* WordPress core embed-template on load: https://github.com/WordPress/WordPress/blob/HEAD/wp-includes/js/wp-embed-template.js#L143 | |
* WordPress core embed-template on resize: https://github.com/WordPress/WordPress/blob/HEAD/wp-includes/js/wp-embed-template.js#L187 | |
*/ | |
const observeAndResizeJS = ` | |
( function() { | |
if ( ! document.body || ! window.parent ) { | |
return; | |
} | |
function sendResize( { data: { secret, message, value } = {} } ) { | |
if ( | |
[ secret, message, value ].some( | |
( attribute ) => ! attribute | |
) || | |
message !== 'height' | |
) { | |
return; | |
} | |
document | |
.querySelectorAll( 'iframe[data-secret="' + secret + '"' ) | |
.forEach( ( iframe ) => { | |
if ( +iframe.height !== value ) { | |
iframe.height = value; | |
} | |
} ); | |
// The function postMessage is exposed by the react-native-webview library | |
// to communicate between React Native and the WebView, in this case, | |
// we use it for notifying resize changes. | |
window.ReactNativeWebView.postMessage(JSON.stringify( { | |
action: 'resize', | |
height: value, | |
})); | |
} | |
window.addEventListener( 'message', sendResize ); | |
} )();`; |
customJS={ observeAndResizeJS } |
So, I understand that we'll have the same issue on Android for that type of embed.
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.
In case you want to test a WP embed, you can use the following URL: https://wordpress.org/news/2021/07/tatum/
.
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.
Actually, there's a case for WordPress embeds
Oh awesome, thanks for pointing that out.
So, I understand that we'll have the same issue on Android for that type of embed.
Good news is that custom JS does not call toScript()
. It might work in the script tag but since it seems the intent of customJS
or at least the expectation is to override the built in resize handler script. Sandbox
could probably use a better prop name like observeAndResizeScript
but we can save that for another day.
Size Change: +601 B (0%) Total Size: 1.34 MB
ℹ️ View Unchanged
|
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.
LGTM 🎊 ! Thanks for fixing this @jhnstn 🙇 !
I tested different embeds on both platforms and they were rendered properly, including when rotating the device:
- YouTube:
https://www.youtube.com/watch?v=ssfHW5lwFZg
- Vimeo:
https://vimeo.com/278150343
- Twitter:
https://twitter.com/automattic/status/1395447061336711181
- WP embed:
https://wordpress.org/news/2021/07/tatum/
`(${ observeAndResizeJS.toString() })();`, | ||
} } | ||
/> | ||
{ customJS && ( |
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.
Probably we could also inject the customJS
via the injectedJavaScript
, instead of adding it to the HTML. Especially if we know that can have issues when running on Android.
Instead I can add the customJS override in the injectedJavaScript prop although I'm not sure why we would want the core resize events to be overridden.
Actually, there's a case for WordPress embeds:
/** | |
* Checks for WordPress embed events signaling the height change when iframe | |
* content loads or iframe's window is resized. The event is sent from | |
* WordPress core via the window.postMessage API. | |
* | |
* References: | |
* window.postMessage: https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage | |
* WordPress core embed-template on load: https://github.com/WordPress/WordPress/blob/HEAD/wp-includes/js/wp-embed-template.js#L143 | |
* WordPress core embed-template on resize: https://github.com/WordPress/WordPress/blob/HEAD/wp-includes/js/wp-embed-template.js#L187 | |
*/ | |
const observeAndResizeJS = ` | |
( function() { | |
if ( ! document.body || ! window.parent ) { | |
return; | |
} | |
function sendResize( { data: { secret, message, value } = {} } ) { | |
if ( | |
[ secret, message, value ].some( | |
( attribute ) => ! attribute | |
) || | |
message !== 'height' | |
) { | |
return; | |
} | |
document | |
.querySelectorAll( 'iframe[data-secret="' + secret + '"' ) | |
.forEach( ( iframe ) => { | |
if ( +iframe.height !== value ) { | |
iframe.height = value; | |
} | |
} ); | |
// The function postMessage is exposed by the react-native-webview library | |
// to communicate between React Native and the WebView, in this case, | |
// we use it for notifying resize changes. | |
window.ReactNativeWebView.postMessage(JSON.stringify( { | |
action: 'resize', | |
height: value, | |
})); | |
} | |
window.addEventListener( 'message', sendResize ); | |
} )();`; |
customJS={ observeAndResizeJS } |
So, I understand that we'll have the same issue on Android for that type of embed.
`(${ observeAndResizeJS.toString() })();`, | ||
} } | ||
/> | ||
{ customJS && ( |
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.
In case you want to test a WP embed, you can use the following URL: https://wordpress.org/news/2021/07/tatum/
.
Flaky tests detected in 2fb6eb3. 🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/4451051580
|
// get an DOM mutations for that, so do the resize when the window is resized, too. | ||
window.addEventListener( 'resize', sendResize, true ); | ||
window.addEventListener( 'orientationchange', sendResize, true ); | ||
widow.addEventListener( 'click', sendResize, true ); |
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.
@jhnstn I've just noticed window
is misspelled here.
Updates the native
Sandbox
component to correctly handle resize events on AndroidWhat?
Updates how the native
Sandbox
component injects the resize handling script.Why?
To fix an issue with embeds not resizing correctly on Android: wordpress-mobile/gutenberg-mobile#5565
How?
toString()
. Even with theshow source
directive, the script was not firing on Android.WebView.injectedJavaScript
to set up the resize handlers in the web view. Again, the script was not running when injected via ascript
tag in the wrapper markup.Testing Instructions
Testing Instructions for Keyboard
Screenshots or screencast