jakiestfu / Medium.js

A tiny JavaScript library for making contenteditable beautiful (Like Medium's editor)
http://jakiestfu.github.io/Medium.js/
4.39k stars 404 forks source link

Pasting in iframes #180

Closed kevinulrich closed 8 years ago

kevinulrich commented 8 years ago

I'm building an application where my Medium editor is within an iframe. I am so far facing no particular problems, but pasting content seems to be borked. A look at the source makes the problem pretty obvious, the injector is not targeting the element's window and document but the global document and window which is wrong in this case.

var wedge = d.getElementById('Medium-wedge')

I've patched around a little bit and have given the injector a reference to the current elements window and document and just replaced all occurences of w. and d.

Medium.Injector = function (medium) {
    this.documentContext = medium.element.ownerDocument; 
    this.windowContext = this.documentContext.defaultView || this.documentContext.parentWindow;
};

However, each time i now paste something, everything i get is a new line, regardless of type of content.

If anyone could help me out with a few pointers here it'd be much appreciated.

robertleeplummerjr commented 8 years ago

Ping me tomorrow or Friday, and I can spend a couple minutes with you on a hangout to get it resolved. My email is robertleeplummerjr at gmail.com

On Wed, Jan 13, 2016 at 1:23 PM, kevinulrich notifications@github.com wrote:

I'm building an application where my Medium editor is within an iframe. I am so far facing no particular problems, but pasting content seems to be borked. A look at the source makes the problem pretty obvious, the injector is not targeting the element's window and document but the global document and window which is wrong in this case.

var wedge = d.getElementById('Medium-wedge')

I've patched around a little bit and have given the injector a reference to the current elements window and document and just replaced all occurences of w. and d.

Medium.Injector = function (medium) { this.documentContext = medium.element.ownerDocument; this.windowContext = this.documentContext.defaultView || this.documentContext.parentWindow; };

However, each time i now paste something, everything i get is a new line, regardless of type of content.

If anyone could help me out with a few pointers here it'd be much appreciated.

— Reply to this email directly or view it on GitHub https://github.com/jakiestfu/Medium.js/issues/180.

Robert Plummer

kevinulrich commented 8 years ago

Just want to give a quick heads up for anyone else looking at this problem. Robert seems to be in a vastly different timezone and we couldn't really make it happen so i found a better way to monkey patch your medium.js if you are running in a single iframe.

The wrapper injects the current document and window into medium.js, so i just made a quick and dirty fix right there. This will only work if you're working on a single iframe you can reference from the start.

Grab the document and window of your iframe:

var mediumDoc = document.querySelector('.my-iframe').contentDocument || document.querySelector('.my-iframe').contentWindow.document;
var mediumWin = mediumDoc.parentWindow || mediumDoc.defaultView;

And just replace the respective arguments on the call on the end of the file:

[...]}).call(this, mediumWin, mediumDoc);

Obviously this is a terribly dirty solution, be aware of that.

robertleeplummerjr commented 8 years ago

I think it would be ideal to provide a context setting, or something like it. A single argument that can override the default document and window object.

On Mon, Jan 25, 2016 at 2:54 PM, kevinulrich notifications@github.com wrote:

Just want to give a quick heads up for anyone else looking at this problem. Robert seems to be in a vastly different timezone and we couldn't really make it happen so i found a better way to monkey patch your medium.js if you are running in a single iframe.

The wrapper injects the current document and window into medium.js, so i just made a quick and dirty fix right there. This will only work if you're working on a single iframe you can reference from the start.

Grab the document and window of your iframe:

var mediumDoc = document.querySelector('.my-iframe').contentDocument || document.querySelector('.my-iframe').contentWindow.document;var mediumWin = mediumDoc.parentWindow || mediumDoc.defaultView;

And just replace the respective arguments on the call on the end of the file:

[...]}).call(this, mediumWin, mediumDoc);

Obviously this is a terribly dirty solution, be aware of that.

— Reply to this email directly or view it on GitHub https://github.com/jakiestfu/Medium.js/issues/180#issuecomment-174639304 .

Robert Plummer

robertleeplummerjr commented 8 years ago

window has the global document. We could simply have a window settings, that would be the context window.

kevinulrich commented 8 years ago

Would that be necessary though? The window/document can also be gotten straight from the element itself:

el.ownerDocument
robertleeplummerjr commented 8 years ago

In the mean time, I provided a means of overriding the document and window here: https://github.com/jakiestfu/Medium.js/commit/87f09cacab7dce6746c3d39f7d24d68139df7bf5

Medium.Utilities.setWindow(window);
Medium.Utilities.setDocument(document);

or

Medium.Utilities
  .setWindow(window)
  .setDocument(document);
kevinulrich commented 8 years ago

Brilliant, thank you!