Jump to content
GreenSock

Search In
  • More options...
Find results that contain...
Find results in...
OxXxigen

draggable with friendly iframe cause error

Warning: Please note

This thread was started before GSAP 3 was released. Some information, especially the syntax, may be out of date for GSAP 3. Please see the GSAP 3 migration guide and release notes for more information about how to update the code to GSAP 3's syntax. 

Recommended Posts

i have friendly iframes on the page, and don't want load draggable in every iframe, it loads only on top, and when i try to create draggable element in iframe it cause error.

See the Pen MXGqZv by anon (@anon) on CodePen

Link to comment
Share on other sites

Draggable does a lot of calculations under the hood to manage bounds and collisions (even inside transformed parents). I'm almost positive Draggable was not designed to be injected into an iframe from a parent. iframes are usually bad news when it comes to any sort of communication between the iframe and its parent as browsers have all sorts of security measure in place to prevent malicious activity.

 

We'll see if there is a reasonable fix, but I'm doubtful this will be considered a legitimate bug. 

 

If you are loading Draggable from the same location it will most likely be cached and really not impact load performance at all.

 

Thanks for posting and for creating the demo. If we find this is something that can be fixed we will post back here.

  • Like 3
Link to comment
Share on other sites

_getOffset2DMatrix = function(e, offsetOrigin, parentOffsetOrigin, zeroOrigin, isBase) {
				if (e === window || !e || !e.style || !e.parentNode) {
					return [1,0,0,1,0,0];
				}
				var cache = e._dCache || _cache(e),
					parent = e.parentNode,
					parentCache = parent._dCache || _cache(parent),
                   
_cache = function(e) {
				if (Draggable.cacheSVGData !== false && e._dCache && e._dCache.lastUpdate === TweenLite.ticker.frame) {
					return e._dCache;
				}
				var cache = e._dCache = e._dCache || {},
					cs = _getComputedStyle(e),


as we can see, function "_getOffset2DMatrix" has check for "!e.style" but into function "_cache" we send "e.parentNode". "_cache" function has no checks 

and try to get computed style. in this case

e.nodeName === 'HTML' && e.style && !e.parentNode.style
// e.parentNode is frame.contentWindow.document

 

Link to comment
Share on other sites

Sorry, but Draggable wasn't intended to be used in this manner (content inside a child iframe). There are quite a few security issues that arise in cases like that, and I think it'd be much cleaner to just use Draggable inside of the iframe itself instead. 

  • Like 3
Link to comment
Share on other sites

I have an issue similar to @OxXxigen which I think should be investigated. Draggable creates the same error when inside a Shadow DOM, which works a lot like an iframe. However, one difference is that when inside a Shadow DOM, the parentNode might be a document fragment, so the host element might be the actual parent.

 

draggableTarget.parentNode.host;

 


See the error in this demo. If you remove the "create-shadow" attribute, it won't create a shadowRoot, and everything works fine.

 

<!-- Has shadowRoot, creates error -->
<my-draggable create-shadow></my-draggable>

<!-- No shadowRoot, no error -->
<my-draggable></my-draggable>

 

 

See the Pen Wyyoro by osublake (@osublake) on CodePen

 

 

And check out the ES6 import in that demo. Look ma, no webpack! ?

 

  • Like 1
Link to comment
Share on other sites

@OSUblake, I think we could probably support the ShadowDom thing, but I don't think it's realistic to support iframes because it'd impact the codebase more extensively and there are security "gotchas" and it's quite an edge case.

 

Does this updated Draggable work the way you'd expect for the ShadowDom stuff?: 

https://s3-us-west-2.amazonaws.com/s.cdpn.io/16327/Draggable-latest-beta.js

Link to comment
Share on other sites

Hi @OxXxigen did you consider using Cross Document Messaging to emit whatever data you want from draggable to be shared between the page and the iFrame?

 

I think you can use Draggable in whatever place you need, track the necessary information and pass it as a message down to whoever needs to react to it. Never done it myself but from what I understand of the theory, it should be possible.

 

https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage

  • Like 2
Link to comment
Share on other sites

On 6/27/2018 at 3:30 PM, GreenSock said:

Does this updated Draggable work the way you'd expect for the ShadowDom stuff?: 

 

It's looking good with HTML. SVG is a different story.

 

An <svg> element can be made draggable, but throws an error with a bounds.

const svg = this.shadowRoot.querySelector("#svg");  
    
// OK
Draggable.create(svg);

// ERROR
Draggable.create(svg, {
  bounds: this
});

 

 

Trying to make anything inside an SVG draggable will create an error, regardless of bounds.

const ball = this.shadowRoot.querySelector("#ball");  
    
// ERROR
Draggable.create(ball);

// ERROR
Draggable.create(ball, {
  bounds: this
});

 

 

See the Pen LrqmvP by osublake (@osublake) on CodePen

 

  • Like 1
Link to comment
Share on other sites

Great catch, @OSUblake. I just updated the beta version and it seems to resolve things. You might need to clear your cache. Notice anything else that isn't working as you'd expect? 

Link to comment
Share on other sites

Looking good! 

?

 

  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×