react-splide
react-splide copied to clipboard
Gutenberg iframe editor error: [splide] A track/list element is missing.
Checks
- [X] Not a duplicate.
- [X] Not a question, feature request, or anything other than a bug report directly related to React Splide. Use Discussions for these topics: https://github.com/Splidejs/splide/discussions
Version
0.7.7
Description
Hi! When trying to use in Gutenberg (WordPress Block Editor) everything is fine until you open in their iframe editor. Gutenberg currently uses an iframe editor for tablet and mobile previews as well as their site builder.
The error in the console log is:
Error: [splide] A track/list element is missing.
at assert (react-splide.esm.js:246:1)
at collect (react-splide.esm.js:695:1)
at Object.setup (react-splide.esm.js:657:1)
at react-splide.esm.js:2441:1
at forOwn (react-splide.esm.js:124:1)
at _Splide2.mount (react-splide.esm.js:2438:1)
at Splide2.componentDidMount (react-splide.esm.js:2661:1)
at ir (react-dom.min.js?ver=17.0.1:9:65527)
at Br (react-dom.min.js?ver=17.0.1:9:81796)
at unstable_runWithPriority (react.min.js?ver=17.0.1:9:7431)
Upon digging into the issue I was able to find that the function isHTMLElement returns false when it should return true.
Currently isHTMLElement function is:
function isHTMLElement(subject) {
return subject instanceof HTMLElement;
}
If that is updated to:
function isHTMLElement(subject) {
return (
typeof HTMLElement === "object" ? subject instanceof HTMLElement : //DOM2
subject && typeof subject === "object" && subject !== null && subject.nodeType === 1 && typeof subject.nodeName==="string"
);
}
Then things work in the iframe editor. That code came from this stackoverflow: https://stackoverflow.com/questions/384286/how-do-you-check-if-a-javascript-object-is-a-dom-object
Thoughts on this? Would it be helpful if I added a pull request with this change, or perhaps you have another solution?
Reproduction Link
No response
Steps to Reproduce
- Create a simple block for gutenberg using any splide react example.
- Add the block in the editor.
- View the editor in tablet or mobile preview. ...
Expected Behaviour
When using splide in an iframe editor is should render correctly.
Having this very same issue while trying to run the carousel on an iframe. @kadencewp you should send a PR for this, your update works like charm in here!
I still don't understand what is the actual problem. You mean Splide does not work in an iframe element?
@NaotoshiFujita exactly, it does not. The update proposed by @kadencewp fixes it.
@marbiano How do I reproduce it? If I load my page in iframe
, it works:
https://codesandbox.io/s/iframe-jg5seg?file=/index.html
https://github.com/Splidejs/splide/issues/931
This issue is also sometimes present in Chrome when not using an iframe.
We fixed it for now with the suggested code from @kadencewp by patching the package with patch-package
.
This is our patch file (we're using react-splide):
diff --git a/node_modules/@splidejs/react-splide/dist/js/react-splide.cjs.js b/node_modules/@splidejs/react-splide/dist/js/react-splide.cjs.js
index ddf5aa5..0f2f7d9 100644
--- a/node_modules/@splidejs/react-splide/dist/js/react-splide.cjs.js
+++ b/node_modules/@splidejs/react-splide/dist/js/react-splide.cjs.js
@@ -93,7 +93,10 @@ function isNull(subject) {
return subject === null;
}
function isHTMLElement(subject) {
- return subject instanceof HTMLElement;
+ return (
+ typeof HTMLElement === "object" ? subject instanceof HTMLElement : //DOM2
+ subject && typeof subject === "object" && subject !== null && subject.nodeType === 1 && typeof subject.nodeName==="string"
+ );
}
function toArray(value) {
return isArray(value) ? value : [value];
diff --git a/node_modules/@splidejs/react-splide/dist/js/react-splide.esm.js b/node_modules/@splidejs/react-splide/dist/js/react-splide.esm.js
index daf9966..3bb87f4 100644
--- a/node_modules/@splidejs/react-splide/dist/js/react-splide.esm.js
+++ b/node_modules/@splidejs/react-splide/dist/js/react-splide.esm.js
@@ -63,7 +63,10 @@ function isNull(subject) {
return subject === null;
}
function isHTMLElement(subject) {
- return subject instanceof HTMLElement;
+ return (
+ typeof HTMLElement === "object" ? subject instanceof HTMLElement : //DOM2
+ subject && typeof subject === "object" && subject !== null && subject.nodeType === 1 && typeof subject.nodeName==="string"
+ );
}
function toArray(value) {
return isArray(value) ? value : [value];