h5p / h5p-wordpress-plugin

Adds support for H5P Content in WordPress.
https://wordpress.org/plugins/h5p/
71 stars 74 forks source link

Iframe elements do not display in Safari #104

Open pjotrsavitski opened 5 years ago

pjotrsavitski commented 5 years ago

When H5P content has been added to the page or post with short code and WP instance is running with https, H5P content iframe elements will not be initialised.

The error thrown is TypeError: null is not an object (evaluating 'this.contentDocument.open')

That seems to be Specific to Safari when showing https page. Removing the src="about:blank" seems to be resolving the issue.

Initially outlined reason seems to be incorrect, please see the comment for more information.

~Changing the code to either https://about:blank or //about:blank also seemed to do the trick.~

~It seems that Safari is preventing the script from accessing the contents of those elements for some reason. It could be a bug of Safari side or a feature that would eventually get into the codebase of other browsers.~

Tested with MacOS Safari versions: 12 and 13

icc commented 5 years ago

Thank you for reporting this issue. I'll look into it as soon as I can, before the next release of the plugin.

pjotrsavitski commented 5 years ago

I stand corrected. This does not seem to be related to src="about:blank" at all. This seems to be something specific to Safari. The way to get that resolved is to change the iframe element in question with JS code and that makes the Safari work as expected.

I did make the change to the codebase on the live system, but that did not work as expected. It seems that I got that previously working by removing or changing the src="about:blank" part of the iframe element within the developers tool prior to running the modified part of the code again from the console.

Modifying this code to make a change to the iframe element node before accessing the internal document of that element does seem to do the trick.

H5P.jQuery('iframe.h5p-iframe:not(.h5p-initialized)', target).each(function () {
    var contentId = H5P.jQuery(this).addClass('h5p-initialized').data('content-id');
    // This seems to allow contentDocument to be accessed in Safari for some reason
    H5P.jQuery(this).attr('src', 'about:blank');
    this.contentDocument.open();
    this.contentDocument.write('<!doctype html><html class="h5p-iframe"><head>' + H5P.getHeadTags(contentId) + '</head><body><div class="h5p-content" data-content-id="' + contentId + '"/></body></html>');
    this.contentDocument.close();
  });

I am not sure why it behaves like that, but the general feeling is that the code does not have access to the contents of the iframe until it changes the element itself. There could be a different reason or a better explanation for what is happening. It did not seem to behave like that in local development environment that was not using https.

3oax commented 2 years ago

Edit Line 378 in h5p/h5p-php-library/js/h5p.js after

// Insert H5Ps that should be in iframes.

H5P.jQuery('iframe.h5p-iframe:not(.h5p-initialized)', target).each(function () { var contentId = H5P.jQuery(this).addClass('h5p-initialized').data('content-id'); var self = this; H5P.jQuery(this).load(function(){ var doc = self.contentDocument; doc.open(); doc.write('<!doctype html><html class="h5p-iframe"><head>' + H5P.getHeadTags(contentId) + '</head><body><div class="h5p-content" data-content-id="' + contentId + '"/></body></html>'); doc.close(); }); });

After this it should work in Safari and mobil Safari