How to add a wrapper content in CKEditor - javascript

all. As you know that, CKEditor starts with an empty editable body tag like that:
<body contenteditable="true" class="someclasses">
</body>
I am trying to start CKEditor with an empty editable div in this body tag and wrap all content of editor by this div like that:
<body class="someclasses">
<div contenteditable="true">
</div>
</body>
So far, I customized ckeditor.js and achieved to do this when I add a template from the editor but this is not a proper solution because any other event can refresh editor's source code and place an empty body tag again. Also, I have to customize nearly all functions to wrap HTML content by this div tag.
Is there any way to define a default wrapper other than body tag of CKEditor? Thank you.
Edit: To be more clear, I want to define a div inside body section of CKEditor and any content must be placed into this automaticaly like added templates, text, images etc...

There is no easy solution. If you need editable wrapped by some other element maybe consider using inline editor?

Related

prettifying innerHTML from Contenteditable div

I am trying to make an editor using contenteditible div(this div will show the rendered content but will also allow user to make changes by typing and other toolbar tools like bold, italic and so on), lets call this editor renditor, I also want to show the innerHTML of contenteditible div in another div for which I am using ace-editor for angular(https://github.com/fxmontigny/ng2-ace-editor) with mode html(lets call it coditor) but the problem I am facing is when I toggle from renditor to coditor(I take innerHTML of renditor div and plug it into coditor div) the renditor changes the look of innerHTML in its own mysterious way which results in overflows in coditor.
I have tried to use a pipe in angular with code provided from this answer (https://stackoverflow.com/a/43794051/4961540) but that even worsen the issue by breaking the html. I also feel renditor div is responsible for this because in past I didn't used separate div like coditor to show the code rather I just toggled in the same div using tags like pre and some other helper functions even then the html looked like it is looking now in coditor. Also it feels like renditor is responsible for it because I have observed when I set innerHTML of renditor to full html page source, it strips out html tags and some other tags so it is indeed making some changes to innerHTML and also how it looks.
<div class="mat-typography textBox editable" style="margin: 16px;"
[hidden]="isSourceVisible"
(input)="mSimpleTask.html=$event.target.innerHTML"contenteditable="true">
</div>
<div class="ace_tooltip" [hidden]="!isSourceVisible" ace-editor
[(text)]="mSimpleTask.html"
[mode]="'html'"
class="textBox ace-editor"
[theme]="'eclipse'"
[readOnly]="false"
[autoUpdateContent]="true"
[durationBeforeCallback]="1000"
(textChanged)="this.mSimpleTask.html=$event;"
style="overflow-wrap: break-word;margin: 16px">
</div>
I am looking to convert/extract innerHTML from renditor in such a way that html looks neat with proper line breaks and no overflows in coditor. Can you throw some light on how I can achieve that or even better if you can provide code with your implementation in the past ?

tinymce and prism issue

tinymce use prism as default for highlighting code. it wraps sample codes in <pre><code>sample code</code></pre> tags.
<pre><code>
<div> this is a container </div>
</code></pre>
if i need to put a div tag inside this block (for learning purpose) , tinymce will clean it up itself once loading content next time i try to edit that saved content and my div tag will be removed because it is not valid html syntax . how can i preserve my content ?
only wrap content in htmlentities() before hit tinymce
as written here

Inserting CSS for an Element from a input field

Is there any easy way to take in a block of CSS from the user from an textarea and add this styling to the styling for a specific div?
See I'm creating a simple code preview tool like codePen, so far I have two textarea inputs, one for Html and one for CSS, as the user types in the Html input this updates the preview pane, this works, now I want to do it for CSS.
CSS textarea could contain a few blocks like:
h1 {
font-size:23px;
}
.myClass {
//Somestyle
}
Now I want this CSS to be contained in the
<div id="preview"></div>
So it doesnt effect the rest of the page, so a manual example would be
$('preview h1').css('font-size','23px');
Anyway to automate this?
Do it like this. Hope it works.
Add a style block for dynamic styling.
<style id="dynamicCss">
</style>
on the apply button click handler, set the style
$('#btnApplyStyle').click(function(){
$('#dynamicCss').html('').html($('#txtaCustomCss').val());
});
See the Fiddle here.
Please use developer tools to see the new style tag added to head section.
This script simply adds rule to the document. If you don't want that behavior, you can use this plugin in combination with my logic to set scope for rule. You will need to place the style tag inside of the container and add a scoped attribute to style for it to work. Please see the documentation.
If you want to use the iframe approach instead, you'll first need an HTML document to host inside of the iframe. The iframe document should be loaded for the same origin (protocol + domain) as the host document (cross-document cross-domain stuff is tricky otherwise). With your application, this is probably not an issue.
Host page:
<iframe id="preview" src="preview.html"></iframe>
To make things easier on yourself, this iframe document could load a script with convenience functions for injecting the HTML and CSS from the host.
preview.html:
<html>
<head>
<script src="preview.js"></script>
<style type="text/css" id="page-css"></style>
</head>
<body></body>
</html>
preview.js:
function setHTML(html) {
document.querySelector('body').innerHTML = html;
}
function setCSS(css) {
var stylesheet = document.querySelector('#page-css');
// Empty the stylesheet
while (stylesheet.firstChild) {
stylesheet.removeChild(stylesheet.firstChild);
}
// Inject new CSS
stylesheet.appendChild(document.createTextNode(css));
}
Now, from the host page, you can call these functions whenever your text inputs change:
document.querySelector('#preview').contentWindow.setCSS(someCSS);
This plugin may come in handy: https://github.com/websanova/wJSNova/downloads .
Edited
Insert the text of the rules in one of the existing cssStyleSheets you have.
It will be something like
window.document.styleSheets[0].insertRule("a{color:red;}",window.document.styleSheets[0].cssRules.length)
The first parameter is the rule to insert and the second is the index.
Fiddle
The only problem here is that this will affect all the DOM on the page maybe looking for a way to add the #preview before each css rule to get something like
#preview h1{}

div in headline tag autocloses

I've got this HTML-Content. I knew that this is not correct HTML but I can't change it because it's user generated by a WYSIWG-Editor and this mistake was done hundered of times by users:
<div>
<H2 style="COLOR: #0000ff"> <DIV align=left>TEXT<br /></H2></STRONG>
</DIV>
</div><br />
Problem is that the Div AFTER the H2 Tag is closed AFTER the closing Tag from the H2.
What happens is that the H2 autocloses the enclosed DIV and the original closes the Div above.
As I can't change the Sourcecode in those masses of Content-Files, is there a way to prevent this behaviour with CSS???
CSS won't fix this. If this is generated by the editor specifically then you need a new editor. If you're setting content in JavaScript based on the content of an editable region you might be in luck. Browsers auto-close tags as the content is assigned. Say you have JavaScript to handle that content, and you're assigning that HTML to an element. When it's assigned to the element it will add the closing tag, and then when you go to programmatically close the tag at the correct time you'll get the duplicate close. I found when I do this I need to store the HTML into a string var temporarily, and then assign the HTML when it's all complete. If you need a quick lightweight html5 editor I have one at http://www.makrit.net/5edit

BODY tag disappear when using Jquery.Load()

Im trying to make a pop-up like window using jquery and its modal box. First I load the content from a html file:
$("#test").load("test.htm");
Then I load the popup:
$("#test").dialog("open");
This works like it should, the content of test.html is injectet into the modal pop-up. There is only one think that is wrong, and that is the BODY tags are gone from the source of the pop-up. I need the BODY tag to be there because I do some formatting based on the BODY tag.
Does anyone know why jQuery.Load() removes the BODY tag? And are there any workarounds?
A page can only have one body tag. If you already have one on the page, the second will be ignored.
In your case, it sounds like the browser is ignoring the duplicate body (nothing specific to jquery). Rather than use the body for styling, use a containing <div> with an id or class which will be retained.
It probably removes the body tag because it's not allowed! Each document can only have one body. Rather than force everyone to redo all their HTML pages, jQuery probably just grabs the contents of the body to use when you call load().
Have you thought about perhaps wrapping everything in a containing element? eg: <div class="body"> You can then apply the exact same styles to that element.
/* change this: */
body { color: #f0f; etc }
/* to this: */
body, div.body { color: #f0f; }
You are loading the HTML into an existing document that already has a body tag. A document can only have one so it automatically filters anything and extracts only the HTML inside the body tag when using load. You should wrap your HTML in a div with a specific class and do your formatting based on that class.
From the load docs (emphasis mine):
In jQuery 1.2 you can now specify a
jQuery selector in the URL. Doing so
will filter the incoming HTML
document, only injecting the elements
that match the selector. The syntax
looks something like "url #some >
selector". Default selector "body>*"
always applies. If the URL contains a
space it should be escape()d. See the
examples for more information.
You might dynamically create the body tag using document.write of js as an alternative.
I had the same issue, and solved it more or less as the following:
instead of using load(), you can use get(), and do some smart string replacement:
var content = get("test.htm")
.replace("<body>", "<body><div class='body'>")
.replace("</body>", "</body>");
$("#test").replace($(content).filter(".body"));

Categories