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

Paste results in span tags, with weird style attributes #534

Closed
SamHellawell opened this Issue Feb 3, 2015 · 13 comments

Comments

Projects
None yet
6 participants
@SamHellawell
Contributor

SamHellawell commented Feb 3, 2015

When I type text in the editor, then select it and paste back into the editor, it wraps the text in span tags with the set colour and background colour.

See here

@SimeonC

This comment has been minimized.

Collaborator

SimeonC commented Feb 3, 2015

I think this is related to #533, theres some odd things in pasting that didn't happen in our pre-release but do happen now :(

@SimeonC SimeonC added the bug label Feb 3, 2015

@SamHellawell

This comment has been minimized.

Contributor

SamHellawell commented Feb 3, 2015

I know the feeling :(

Hey but if you wanna know where your work is being used, it'll be up on www.branded.me soon :) Awesome work btw.

@SimeonC

This comment has been minimized.

Collaborator

SimeonC commented Feb 3, 2015

Ah, I remember this now, it's a side effect of copying HTML in browsers, specifically Chrome/Webkit.
For example if I copy some HTML starting with <p><b>... what chrome puts on the paste board is this:

<p style="box-sizing: border-box; margin: 0px 0px 10px; color: rgb(85, 85, 85); font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 20px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255);"><b style="box-sizing: border-box; font-weight: 700;">...

Which is kinda understandable, but really annoying. 90% of that is stripped by the sanitizer, the others are allowed through but basically what it is is all the stylings present on that element, so when you paste it it looks the same.

I don't think I can actually fix this unless I say that styles do not copy/paste over as there's no way of telling the difference between styles set by the user or styles set by chrome.

I'm going to tag everyone whose been involved with pasting so I can get a collective opinion on it (Next Comment).

Nice site, it's always cool to know where it's being used, maybe I should setup some sort of "This is used here..." list sometime.

@SimeonC

This comment has been minimized.

Collaborator

SimeonC commented Feb 3, 2015

Sorry all for the mass ping, I've tagged a bunch of people as I need a bit of an opinion and you've all influenced the paste process as it currently stands in v1.3.0 +.

Situation in brief is that current copy-paste of HTML mainly in Webkit browsers (Haven't checked others yet but I think it's the same) brings across lot's of unnecessary style attributes due to the copy.

Short example: Copy <p><b>... will actually paste <p style="box-sizing: border-box; ... background-color: rgb(255, 255, 255);"><b style="box-sizing: border-box; font-weight: 700;">... (See previous comment for full paste).

The sanitiser is generally good at stripping these out, except as we start letting some through like color they start showing up in the paste. Due to not being able to reliably test whether a style has been set by chrome or the user the two options are:

  1. Leave it as it is and the semi irrelevant tags remain.
  2. Forcibly strip style tags on paste HTML. (Just on paste)

I think option 2 is probably the best but I'd rather get a sense of what everyone else thinks before I go ahead and change something like this which could adversely affect people.

Thanks in advance for your help!

@barathank @realdigid @dbounds (#471) @kaiqigong @anitin @diagramatics @rahul-sekhar @edouard-lopez

@diagramatics

This comment has been minimized.

Contributor

diagramatics commented Feb 3, 2015

I feel bad for not even contributing or responding to anything after my issue. I'll try and help in any way I can.

This copy-pasting issue seems very complex and rely heavily on how browsers implement copy and paste, and this gets more complex if you're dealing with contenteditable elements. So I crosschecked the behavior as much as I could and it seemed like the whole feature needs a better, rugged implementation than a simple contenteditable div.

I tested it on http://textangular.com with the predefined text mostly, using Ctrl+A when I want to get the whole text. Here's what I can pick up.

  • Chrome is confirmed to include the browser stylings, while Firefox and IE seems to (sometimes) have problems in actually showing the right thing pasted when it comes to text with lots of stylings.
  • Copying from Chrome to IE would result in the same markup you get from Chrome—the styles are included as an inline style.
  • Copying from anything to Firefox (v35 here) will result in no stylings at all, or even newline characters.
  • Copying from Firefox to anything though, results in the other browser having a clean (?) markup. Not perfect, but definitely both IE and Chrome parsed the pasted content differently.
  • Copying from IE would actually include the <title> element for some reason and the parent container elements up to the element that has ngBind in it. Chrome even displaying the outline outside of the contenteditable element, indicating an overflow.

There are also some strange behaviors during my test that had happened one or two times and after that I wasn't able to replicate at all. In short, there is little guarantee of the browsers being able to parse the HTML correctly, yet even managing to keep a standard to work together, cross-browsers or even working on only one.

All of that, I suspect are from the lack of standard on contenteditable elements. If I remember correctly there is no default AngularJS implementation on handling contenteditable as well, and that might be due to the major difference on the behaviors on each browsers. If we opted to not fix the issue (or even fix it) there might be more bugs that are related to the contenteditable behavior. Maybe another option would be like what the other text editor plugins are doing—create a hidden input to capture user inputs, process it, and output to the text editor view.

Good luck, hopefully this helps.

@SamHellawell

This comment has been minimized.

Contributor

SamHellawell commented Feb 3, 2015

Any way you could provide an option to strip ALL html from the paste? If you point out where this is parsed, I'll do it and make a pull request. This would temporarily solve this problem, anyway, atleast for myself. I'm sure some users of this would like an option to do that too, I've seen it in a few other solutions.

@SimeonC

This comment has been minimized.

Collaborator

SimeonC commented Feb 3, 2015

@diagramatics Thanks for your thoughts and extensive testing!! I never thought of trying to copy-paste between different browsers. In essence our current implementation of copy paste uses this solution: http://stackoverflow.com/a/6804718/1413689. Someone kindly contracted me to add in the ability to paste from word and persist formatting. A side effect of that was the ability to paste HTML with formatting (as word actually sends XML that either is or closely resembles HTML). Using a non-contenteditable input to catch input would make the point moot as then pastes would be without formatting bar newline characters.

@SamHellawell We could do that, we used to do this as the only option so adding it in shouldn't be too bad. Full Paste Reference taBind.js#L247-L439. FYI this would be such a simpler function if IE supported clipboardData.getData('html') like all the other browsers, but it doesn't.

I think you pointed out what might be the best solution; give options to the paste parsing: text-only, full-html, no-styles (default?). (The latter two would be required for Word paste).

@SimeonC SimeonC added this to the 1.3.X milestone Feb 3, 2015

This was referenced Feb 5, 2015

@diagramatics

This comment has been minimized.

Contributor

diagramatics commented Feb 5, 2015

Ah, that makes sense. I was thinking about how Atom handles its text input when I realised it is not a WYSIWYG editor. I guess sacrifices had to be done, I agree with @SamHellawell as well in this situation until a rewrite of the system is needed.

P.S: I tried looking for references on how contentEditable works and found this post about how Medium makes their text editor and bashes contentEditable.

pbassut added a commit that referenced this issue Jul 15, 2016

Merge pull request #1225 from JoelParke/master
Fix(textAngularSetup, factories, README, taBind): bugs #1223, #1207, #534, #1217
@JoelParke

This comment has been minimized.

Collaborator

JoelParke commented Jul 15, 2016

Fixed with release v1.5.2

@JoelParke JoelParke closed this Jul 15, 2016

@naelshawwa

This comment has been minimized.

naelshawwa commented Jan 23, 2017

Hey @JoelParke and team, I came across this bug again in version 1.5.12. I get a white background around copy/paste text:

color: rgb(77, 77, 77);background-color: rgb(255, 255, 255);

Any ideas?

@bencun

This comment has been minimized.

bencun commented May 22, 2017

Same issue here, v1.5.16. Browser: Google Chrome. If I copy and paste any text from any webpage the styling is preserved inline after pasting the text and it overrides my own styles later when rendering with ng-bind-html or ta-bind.

@naelshawwa

This comment has been minimized.

naelshawwa commented May 22, 2017

@bencun we implemented a special handler for taPaste to strip out inline styles.

@bencun

This comment has been minimized.

bencun commented May 22, 2017

@naelshawwa So how am I supposed to go around this issue, I seem to be unable to find anything?
Should I create my own filter for taPaste in order to strip inline styles or is there an existing solution that I should be using?

EDIT: Oh, I see now what you mean. I guess I'll implement it myself then. If you care to share your handler I'd be grateful.

EDIT2: I ended up using this function for taPaste, it removes all inline styles:

var stripStyles = function($html){
  return $html.replace(/(style="([^"]*)")/gi, '')
;};

I've also applied the modification to the textAngular itself mentioned in #1071 because I also had a bunch of tags when pasting the data which nowhere to be found in source material (html, body, nonexistent br tags) even when only copying and pasting a single word of text.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment