Froala v2 editor mangles my code upon retrieval - javascript

I'm using the Froala editor v2 and I'm running into a very frustrating and intermittent problem. I'm embedding a custom HTML widget (a rich preview when the user enters a URL on its own line). But when I retrieve the final HTML to be saved to our database, it seems Froala decides to "clean up" my HTML before giving it to me. When I inspect the editor instance while I'm editing the content, all the markup is in good shape. But when I call $('.froala-editor').froalaEditor('html.get') to retrieve the HTML, the HTML for the URL preview widget is completely mangled.
My suspicion is that, since the entire preview is wrapped in an <a> tag to make the whole thing linked (and I don't have any nested <a> tags in it because that's bad HTML), Froala is taking the other structural elements like the divs, h# tags, p tags, etc and placing copies of the wrapping <a> tag inside all of them (as you'll see in the code samples) because it doesn't think you're allowed to have an <a> wrapping all that stuff. But that's just a guess.
And to top it all off, sometimes Froala will give me the HTML intact and other times it won't.
I don't think it makes any difference, but I'm using React to generate the widget and then injecting the resulting HTML into the editor. I've removed all the data-reactid attributes to reduce the clutter.
Original injected HTML (the outermost <p> tags are there because Froala seems to like to wrap everything in semantic block level tags):
<p>
<a href="http://www.google.com" target="_blank" class="embedly-preview" title="http://www.google.com" data-source-url="http://www.google.com">
<span class="ui media content-item-wrapper content-summary post-body">
<span class="media-left content-summary-image post-image">
<img src="https://res.cloudinary.com/peerlyst/image/fetch/http%3A%2F%2Fwww.google.com%2Fimages%2Fbranding%2Fgooglelogo%2F1x%2Fgooglelogo_white_background_color_272x92dp.png">
</span>
<span class="media-body content-summary-body">
<h2 class="content-summary-title content-title post-title">Google</h2>
<p class="content-summary-content post-content">Search the world's information, including webpages, images, videos and more. Google has many special features to help you find exactly what you're looking for.</p>
<p class="content-summary-link">http://www.google.com</p>
</span>
</span>
</a>
</p>
What Froala gives me:
<p>
<a class="embedly-preview" data-source-url="http://www.google.com" href="http://www.google.com" target="_blank" title="http://www.google.com">
<span class="ui media content-item-wrapper content-summary post-body">
<span class="media-left content-summary-image post-image">
<img src="https://res.cloudinary.com/peerlyst/image/fetch/http%3A%2F%2Fwww.google.com…randing%2Fgooglelogo%2F1x%2Fgooglelogo_white_background_color_272x92dp.png">
</span>
<span class="media-body content-summary-body"></span>
</span>
</a>
</p>
<h2 class="content-summary-title content-title post-title">
<a class="embedly-preview" data-source-url="http://www.google.com" href="http://www.google.com" target="_blank" title="http://www.google.com">Google</a>
</h2>
<p class="content-summary-content post-content">
<a class="embedly-preview" data-source-url="http://www.google.com" href="http://www.google.com" target="_blank" title="http://www.google.com">Search the world&apos;s information, including webpages, images, videos and more. Google has many special features to help you find exactly what you&apos;re looking for.</a>
</p>
<p class="content-summary-link">
<a class="embedly-preview" data-source-url="http://www.google.com" href="http://www.google.com" target="_blank" title="http://www.google.com">http://www.google.com</a>
</p>

The problem is not the editor, but the HTML structure you have. You have used a H2 tag inside a P tag which browsers do not allow (see https://stackoverflow.com/a/8696078/1806855 for more details) You could check that in a very basic jsFiddle: https://jsfiddle.net/0jLzm2b0/.
Instead it should work just fine if you'd use a DIV tag instead: https://jsfiddle.net/0jLzm2b0/1/. You can see the output is no longer changed.

After digging into the Froala code using a breakpoint to isolate the point at which the HTML gets mangled, turns out it's actually jQuery that's mangling my HTML. Effectively, given the original HTML from above in the variable html:
$(html).html() !== html
What's even more interesting is that (taking the relevant snippet from Froala's code where it wraps the fetched HTML in a div before processing):
$('<div>' + html + '</div>').html() !== $(html).html() !== html
(Clearly, wrapping html in a <div> will make the HTML not equal to the others, but even the HTML inside the <div> that is output is mangled from the original)
So the jQuery constructor is the thing being "helpful" by retooling my HTML for me.

Related

Insert tag inside a specific range - algorithm for DOM tree modification

I need an algorithm for manipulating DOM tree.
For example I have this HTML code:
<div>
This is
<b>interesting</b>
<a href="...">
con
<i>tent</i>
</a>
. It
<i>can be</i>
edit by users
</div>
User selects text "is interesting content. It can" and presses a button on the website. An event onClick of the button calls a function insertTag('u').
After this the HTML code should look like this:
<div>
This
<u>is
<b>interesting</b>
<a href="...">
con
<i>tent</i>
</a>
. It
</u>
<i>
<u>can</u>
be
</i>
edit by users
</div>
What should insertTag() function do? I googled, but I didn't find any examples and algorithms for this problem.

Creating tool to add blog tags: when the post is submitted the dynamically added tags are ignored

I'm trying to create a simple tool to ease the addition of tags in blog posts (not sure if I can mention the website, therefore i won't do it now).
I've inspected the code and I've noticed that when a tag is added, a new span is created between the divs post-form--tag-editor and tag-input-wrapper
<div class="post-form--tag-editor" data-subview="tagEditor">
-> TAG CODE here !! <span class=""> ::before This is a tag </span> <- TAG CODE here!!!
<span class=""> ::before This is another tag </span>
<div class="tag-input-wrapper" data-js-taginputfieldwrapper="">
<div data-name="tagInput" data-subview="tagInputField">
<div data-js="editor-wrapper" class="editor-wrapper" style="position: relative;">
Right now, my tool is injecting the necessary HTML to create dynamic spans and add new tags. I can see my "injected" tags in the webpage but when I submit the post the "injected" tags do not appear in the live post.
Since I'm able to see the "injected tags" shouldn't I be able to see them too when my post is submitted and live ? Am I using the wrong approach to achieve what I want?
Thank you in advance !

How to create an HTML module angular

Learning HTML/Angular.
I have a bunch of HTML code that I want to be re-usable. Basically I write it once and modify the same code base, then just insert the dynamic data using Angular.
My question is - How do I create re-usable HTML code that can be injected into a page using Angular?
For instance, lets say I am an app developer and want to showcase 25 apps on the same page each with their own HTML component (not just a bunch of images). Rather than copying the HTML 25 times I would just like to inject that HTML snippet via some angular command, then insert the text into the corresponding divs etc. I need to stick with Angular/HTML (no other frameworks)
Or is there a better way?
(look at the image for reference - imagine inserting that layout 25 times without duplicating code)
I have tried this using ng-repeat but when I do so it throws the repeating items in the same spot on top of each other. I was hoping that for every div that is repeated it would put it underneath the other div.
<div id="apps" ng-controller="MyApps">
<div id="appsection" ng-repeat="app in applist">
<img class="rightappimg" src={{app.img}} />
<strong class="appbannertext">{{app.firstLine}}</strong>
<strong class="appbannertextsubtitle">{{app.secondLine}}</strong>
<strong class="appbannertextsubtitlesmall"><span class="ios">iOS, iPhone, iPad</span> & <span class="android"> Android</span></strong>
<strong class="appbannerdescriptiontitle">{{app.fourthLine}}</strong>
<p class="appbannerdescription">{{app.fifthLine}}</p>
</div>
</div>
Ok the answer was to us ng-repeat as such:
<div id="apps" ng-controller="MyApps">
<div id="appsection" ng-repeat="app in applist">
<img class="rightappimg" src={{app.img}} />
<strong class="appbannertext">{{app.firstLine}}</strong>
<strong class="appbannertextsubtitle">{{app.secondLine}}</strong>
<strong class="appbannertextsubtitlesmall"><span class="ios">iOS, iPhone, iPad</span> & <span class="android"> Android</span></strong>
<strong class="appbannerdescriptiontitle">{{app.fourthLine}}</strong>
<p class="appbannerdescription">{{app.fifthLine}}</p>
</div>
And then simply to specify a min-height in the div id in the CSS file so the items wouldn't overlap each other.

Way to trigger FancyBox by clicking on <div> rather then <a>?

I am having issues with my CMS - its seems it doesn't like having an <a> tag within an <a> tag as my Fancy Box 2 set up has.
To test I replaced:
<a class="fancybox" href="#popup">
with
<div class="fancybox" href="#popup">
This solved my original issue, but because its not legitimate mark up and breaks a lot of the other code.
Would anyone know a correct way to modified Fancy Box 2 to do this?
You can always bind fancybox to any element other than the <a> tag with a valid (HTML5) structure and functionality, using the special fancybox's data-* attributes like :
<div class="fancybox" data-fancybox-href="#popup">open fancybox</div>
See JSFIDDLE

How to edit text for a link that does not have an ID using Javascript

I want to change the text of a link using javascript. The problem is this particular link does not have an id. I am unable to change the html, as this is a SharePoint page, and this particular link is created by a page layout, which I do not have access to. Using IE Developer Tools, I see that the HTML surrounding the link is this:
<span id="DeltaPlaceHolderPageTitleInTitleArea">
<span>
<a href="#ctl00_PlaceHolderPageTitleInTitleArea_ctl00_SkipLink">
<img width="0" height="0" style="border-width: 0px;" alt="Skip Navigation Links" src="" /></a>
<span>
<a title="State-Compliance" href="/sites/tax/Compliance/SitePages/State-Compliance.aspx">State-Compliance</a>
</span>
<a id="ctl00_PlaceHolderPageTitleInTitleArea_ctl00_SkipLink"></a>
</span>
The link I wish to change is the second one, the one with "State-Compliance" for the tooltip.
I looked at jQuery, and found I could use $('#DeltaPlaceHolderPageTitleInTitleArea').find("a").text("Test"); to change the text, but it changes the text of all three links. How can I change just the one? Do I need to iterate through the three, or is there an easier way of getting the link I wish to change?
Sorry if this is a stupid question, I'm a c# developer, and this is my first experience using javascript.
Let me know if you need more information.
Warren
Use .eq():
$('#DeltaPlaceHolderPageTitleInTitleArea').find("a").eq(1).text("Test");
jsFiddle example
How about this, using the attribute equals selector:
$('#DeltaPlaceHolderPageTitleInTitleArea a[title="State-Compliance"]')

Categories

Resources