Rendering HTML as... HTML? In Vanilla JS - javascript

So I have what should be a simple problem: I want to render some HTML as HTML and not as a string. My code takes a list from a textarea, then alphabetizes it, then spits it out in <span> tags. But I want the HTML to actually render and not literally display "<span>Bar</span><span>Foo</span>".
I'm trying DOMParser, which seems like it should be the answer, but somehow I'm missing a step.
const mwInput = document.querySelector('.mw__input');
const mwOutput = document.querySelector('.mw__output');
var stringToHTML = function(str) {
var parser = new DOMParser();
var theParsed = parser.parseFromString(str, 'text/html');
return theParsed.body;
}
document.querySelector('#alphabetize').addEventListener('click', function(){
var theText = mwInput.value;
theText = mwInput.value.split('\n').sort();
var theOutput = '';
theText.map(
function(item, i) {
theOutput += '<span>' + item + '</span>';
}
);
mwOutput.innerHTML = stringToHTML(theOutput).innerHTML;
});

Related

How to dynamically add <a> tags given an index of HTML page's string?

I'm making a search function for my website. So far, I've found the string the user searches for in the whole website, and I'm able to print the string and the context of the string. I have achieved this by using $.get on my HTML pages, then stripping the HTML to leave the pure text I want to search in. I then find the index of the string I'm looking for, then use substr to find the context of the input string (a few indexes ahead and behind).
Now, I need to link to the original page when a user clicks on a search result. My research says to use <a> tags, but how do I dynamically insert those into the HTML page with the index I have? And the index I have isn't even the complete page; it's stripped of tags.
These are the relevant parts of my code:
JavaScript:
function getIndicesOf(searchStr, str) { //get the indices of searchStr inside of str
var searchStrLen = searchStr.length;
if (searchStrLen == 0) {
return [];
}
var startIndex = 0, index, indices = [];
str = str.toLowerCase();
searchStr = searchStr.toLowerCase();
while ((index = str.indexOf(searchStr, startIndex)) > -1) {
indices.push(index);
startIndex = index + searchStrLen;
}
return indices;
}
function search() {
obj=document.getElementById("searchButton");
obj.onclick = function() {
var searchInput = document.getElementById('searchBox').value;
var allPageContent = ['chap/telem.php', 'chap/nestor.php', 'chap/aeolus.php', 'chap/calypso.php', 'chap/circe.php', 'chap/cyclops.php', 'chap/eumaeus.php', 'chap/hades.php','chap/ithaca.php', 'chap/lestry.php', 'chap/lotus.php', 'chap/nausicaa.php', 'chap/oxen.php', 'chap/penelope.php', 'chap/proteus.php', 'chap/scylla.php', 'chap/sirens.php', 'chap/wrocks.php']; //contains all text
var allText = '';
for (var i = 0; i < allPageContent.length; i++){
$.get(allPageContent[i], function(data){
var div = document.createElement("div");
div.innerHTML = data;
//allText = div.textContent || div.innerText || ""; //gets the text to search in, stripped of html
alltext = data;
allText = allText.replace(/(\r\n\t|\n|\r\t)/gm," ");
console.log(data);
var indices = getIndicesOf(searchInput, allText); //the variable indices is the array that contains the indices of the searched text in the main text
indices.forEach(findContext);
})
}
localStorage.output = '';
function findContext(currentValue, index) {
if (currentValue <= 16) {
searchContext = "..." + allText.substr(currentValue, 100) + "...";
} else {
searchContext = "..." + allText.substr(currentValue-15, 100) + "...";
}
localStorage.output = localStorage.output + searchContext + "<br /><br />";
}
console.log(localStorage.output);
};
};
HTML:
<script>document.getElementById("output").innerHTML = localStorage.output;</script>
It's a bit confusing what you're trying to achieve, considering your HTML, but replying to this
My research says to use <a> tags, but how do I dynamically insert
those into the HTML page with the index I have?
this would do the trick
var output = document.getElementById("output");
var a = document.createElement("a");
var linkText = document.createTextNode("my linked text");
a.appendChild(linkText);
a.href = "http://example.com";
output.appendChild(a);

stop converting xml tags to lowercase - jquery

I am working on Draw.io in which I have to convert json to XML, which I successfully did, But I am facing an issue in which all my xml tags goes to lowercase auto.
Lets Say, If I create tag with <mxCell></mxCell> it will convert into <mxcell></mxcell>.
BUT for draw.io , I need to keep the same format for XML. any way to do this ?
var apple = '<mxCell />';
var $div = $('<div>');
$div.append(apple);
$("#graphXMlDiv").text($div.html());
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<div id="graphXMlDiv"></div>
Working jsfiddle
Take a look to this:
let XMLTag = function(tagName) {
this.tagName = tagName;
this.children = [];
this.padding = '';
this.parent = null;
}
XMLTag.prototype.addPadding = function() {
this.padding = this.padding + '\t';
}
XMLTag.prototype.getPadding = function() {
var current = this;
let padding = '';
while (current !== null) {
padding += current.padding;
current = current.parent;
}
return padding;
}
XMLTag.prototype.setParent = function(parent) {
this.parent = parent;
}
XMLTag.prototype.append = function(child) {
child.addPadding();
child.setParent(this);
this.children.push(child);
}
XMLTag.prototype.toText = function() {
if (this.children.length === 0) {
return `${this.getPadding()}<${this.tagName}/>`;
} else {
let childrenText = this.children.map(c => c.toText()).join(`\n`);
return `${this.getPadding()}<${this.tagName}>\n${childrenText}\n${this.getPadding()}</${this.tagName}>`
}
}
var apple = new XMLTag('mxCell');
var anotherTag = new XMLTag('anotherTag');
var anotherTag1 = new XMLTag('anotherTag1');
apple.append(anotherTag);
anotherTag.append(anotherTag1);
console.log(apple.toText());
I'm not really sure what you going for so I am assuming two possible solutions.
You are looking to insert simple string instead of XML node
In that case, just do this:
var $div = $('<div/>');
$div.text('<mxCell><mxCell/>');
$("#graphXMlDiv").text($div.text());
//Then I would add the answer to this StackOverflow question
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="graphXMlDiv"></div>
Notice I don't use $div.html() to supply the data to $('#graph....') because what you've inserted inside $div is not proper HTML, and should not be treated as such.
In case you wanted to load an XML document and then add into $div the content of what the XML node myCell has, then you can do something like this.
var apple = '<mxCell>Data inside mxCell</mxCell>',
$div = $('<div/>')
$apple_xml = $($.parseXML(apple));
$apple_xml.find('mxCell').each(function() {
$div.html($(this).text());
});
$("#graphXMlDiv").text($div.html());
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="graphXMlDiv"></div>

Remove HTML tags in script

I've found this piece of code on the internet. It takes a sentence and makes every single word into link with this word. But it has weak side: if a sentence has HTML in it, this script doesn't remove it.
For example: it replaces '<b>asserted</b>' with 'http://www.merriam-webster.com/dictionary/<b>asserted</b>'
Could you please tell me what to change in this code for it to change '<b>asserted</b>' to 'http://www.merriam-webster.com/dictionary/asserted'.
var content = document.getElementById("sentence").innerHTML;
var punctuationless = content.replace(/[.,\/#!$%\؟^?&\*;:{}=\-_`~()”“"]/g, "");
var mixedCase = punctuationless.replace(/\s{2,}/g);
var finalString = mixedCase.toLowerCase();
var words = (finalString).split(" ");
var punctuatedWords = (content).split(" ");
var processed = "";
for (i = 0; i < words.length; i++) {
processed += "<a href = \"http://www.merriam-webster.com/dictionary/" + words[i] + "\">";
processed += punctuatedWords[i];
processed += "</a> ";
}
document.getElementById("sentence").innerHTML = processed;
This regex /<{1}[^<>]{1,}>{1}/g should replace any text in a string that is between two of these <> and the brackets themselves with a white space. This
var str = "<hi>How are you<hi><table><tr>I<tr><table>love cake<g>"
str = str.replace(/<{1}[^<>]{1,}>{1}/g," ")
document.writeln(str);
will give back " How are you I love cake".
If you paste this
var stripHTML = str.mixedCase(/<{1}[^<>]{1,}>{1}/g,"")
just below this
var mixedCase = punctuationless.replace(/\s{2,}/g);
and replace mixedCase with stripHTML in the line after, it will probably work
function stripAllHtml(str) {
if (!str || !str.length) return ''
str = str.replace(/<script.*?>.*?<\/script>/igm, '')
let tmp = document.createElement("DIV");
tmp.innerHTML = str;
return tmp.textContent || tmp.innerText || "";
}
stripAllHtml('<a>test</a>')
This function will strip all the HTML and return only text.
Hopefully, this will work for you
if you need to remove HTML tags And HTML Entities You can use
const text = '<p>test content </p><p><strong>test bold</strong> </p>'
text.replace(/<[^>]*(>|$)| |‌|»|«|>/g, '');
the result will be "test content test bold"

bbcode ckeditor justify plugin

i install ckeditor and after i install that code (bbcode plugin):
https://github.com/ckeditor/ckeditor-dev/blob/master/plugins/bbcode/plugin.js
and i install that code (justify plugin):
https://github.com/ckeditor/ckeditor-dev/blob/master/plugins/justify/plugin.js
and after i install that plugins all work but when i click center or right or left in the justify plugin - the bbcode plugin not support the justify mod.
anybody can help me build a simple code in the bbcode plugin support the justify mod?
its for forum and i need only bbcode.
i need code like :
if <span style=\"text-align: center;\">texthere</span>
its replace to [center]texthere[/center]
or something like that.
thx for the help.
i try this code:
(function() {
CKEDITOR.plugins.add('bbcode',
{
requires: ['htmlwriter'],
init: function(editor) {
editor.dataProcessor = new CKEDITOR.htmlDataProcessor(editor);
editor.dataProcessor.toHtml = toHtml;
editor.dataProcessor.toDataFormat = toDataFormat;
}
});
var toHtml = function(data, fixForBody) {
// Convert < and > to their HTML entities.
data = data.replace(/</g, '<');
data = data.replace(/>/g, '>');
// Convert line breaks to <br>.
data = data.replace(/(?:\r\n|\n|\r)/g, '<br>');
// [url]
data = data.replace(/\[url\](.+?)\[\/url]/gi, '$1');
data = data.replace(/\[url\=([^\]]+)](.+?)\[\/url]/gi, '$2');
// [b]
data = data.replace(/\[b\](.*?)\[\/b]/gi, '<b>$1</b>');
// [i]
data = data.replace(/\[i\](.*?)\[\/i]/gi, '<i>$1</i>');
// [u]
data = data.replace(/\[u\](.*?)\[\/u]/gi, '<u>$1</u>');
// [h3]
data = data.replace(/\[h3\](.*?)\[\/h3](?:<br ?\/?>|\n)?/gi, '<h3>$1</h3>');
// [img]
data = data.replace(/\[img\](.*?)\[\/img\]/gi,'<img src="$1" />');
data = data.replace(/\[img class=([\w-]+)\](.*?)\[\/img\]/gi,'<img class="$1" src="$2" />');
// [quote]
data = data.replace(/\[quote\]/gi, '<blockquote>');
data = data.replace(/\[\/quote]/gi, '</blockquote>');
// [poster]
data = data.replace(/\[poster\](.+?)\[\/poster]/gi, '<div class="text-poster">$1</div>');
// [code]
data = data.replace(/\[code\]/gi,'<code>');
data = data.replace(/\[\/code\]/gi,'</code>');
// [size]
data = data.replace(/\[size=(\d+)\](.*?)\[\/size\]/gi,'<span style="font-size: $1px">$2</span>');
// [color]
data = data.replace(/\[color=(.*?)\](.*?)\[\/color\]/gi,'<span style="color: $1">$2</span>');
// [center]
data = data.replace(/\[align=(.*?)\](.*?)\[\/align\]/gi,'<span style="align: center">$2</span>');
// [right]
data = data.replace(/\[align=(.*?)\](.*?)\[\/align\]/gi,'<span style="align: right">$2</span>');
// [left]
data = data.replace(/\[align=(.*?)\](.*?)\[\/align\]/gi,'<span style="align: left">$2</span>');
// smileys
for (var i = 0; i < this.editor.config.smiley_images.length; i++) {
var smiley = this.editor.config.smiley_images[i].replace('.gif', '');
if (data.indexOf(smiley) != -1) {
data = data.split(smiley).join('<img src="'+ this.editor.config.smiley_path + this.editor.config.smiley_images[i] + '" class="smiley" />');
}
}
return data;
};
var toDataFormat = function(html, fixForBody ) {
if (html == '<br>' || html == '<p><br></p>') {
return "";
}
// Convert <br> to line breaks.
html = html.replace(/<br><\/p>/gi,"\n");
html = html.replace(/<br(?=[ \/>]).*?>/gi, '\r\n');
html = html.replace(/<p>/gi,"");
html = html.replace(/<\/p>/gi,"\n");
html = html.replace(/ /gi," ");
// [url]
html = html.replace(/<a .*?href=(["'])(.+?)\1.*?>(.+?)<\/a>/gi, '[url=$2]$3[/url]');
// [b]
html = html.replace(/<(?:b|strong)>/gi, '[b]');
html = html.replace(/<\/(?:b|strong)>/gi, '[/b]');
// [i]
html = html.replace(/<(?:i|em)>/gi, '[i]');
html = html.replace(/<\/(?:i|em)>/gi, '[/i]');
// [u]
html = html.replace(/<u>/gi, '[u]');
html = html.replace(/<\/u>/gi, '[/u]');
// [h3]
html = html.replace(/<h3>/gi, '[h3]');
html = html.replace(/<\/h3>/gi, '[/h3]\n');
// smileys
html = html.replace(/<img .*?src=(["']).+?(:.+?:?|(\W)_\3).gif\1.*?>/gi, '$2');
// [img]
html = html.replace(/<img .*?class=(["'])([\w-]+)\1.*?src=(["'])(.+?)\3.*?>/gi, '[img class=$2]$4[/img]');
html = html.replace(/<img .*?src=(["'])(.+?)\1.*?class=(["'])([\w-]+)\3.*?>/gi, '[img class=$4]$2[/img]');
html = html.replace(/<img .*?src=(["'])(.+?)\1.*?>/gi, '[img]$2[/img]');
// [quote]
html = html.replace(/<blockquote>/gi, '[quote]');
html = html.replace(/\n*<\/blockquote>/gi, '[/quote]');
// [poster]
html = html.replace(/<div class="text-poster">([\s\S]+?)<\/div>/gi, '[poster]$1[/poster]');
// [code]
html = html.replace(/<code>/gi, '[code]');
html = html.replace(/<\/code>/gi, '[/code]');
// [color]
html = html.replace(/<span style="color: ?(.*?);?">(.*?)<\/span>/gi,"[color=$1]$2[/color]");
// [size]
html = html.replace(/<span style="font-size: ?(\d+)px;?">(.*?)<\/span>/gi,"[size=$1]$2[/size]");
// Remove remaining tags.
html = html.replace(/<[^>]+>/g, '');
// Restore < and >
html = html.replace(/</g, '<');
html = html.replace(/>/g, '>');
// Restore (and )
html = html.replace(/%28/g, '(');
html = html.replace(/%29/g, ')');
// Restore %20
html = html.replace(/%20/g, ' ');
return html;
}
})();
but this code not work.
i think this code for ckeditor 3 or something ..
I meet the same problem today and I managed to make it work by modifying the plugin.js in the bbcode plugin folder
Line 29:
var bbcodeMap = { b: 'strong', u: 'u', i: 'em', color: 'span', size: 'span', quote: 'blockquote', code: 'code', url: 'a', email: 'span', img: 'span', '*': 'li', list: 'ol',center:'div',left:'div',right:'div'},
and Line around 151-160:
// as "span" with an attribute marker.
if ( part == 'email' || part == 'img' )
attribs[ 'bbcode' ] = part;
//adding this to deal with the align issues
if (part == 'center' || part == 'left' || part == 'right'){
styles ['text-align'] = part;
attribs.style = serializeStyleText( styles );
}
this.onTagOpen( tagName, attribs, CKEDITOR.dtd.$empty[ tagName ] );
And finally line start from 658:
if ( tagName in convertMap )
tagName = convertMap[ tagName ];
//adding div element
else if (tagName == 'div'){
if ( ( value = style['text-align'] ) ) {
tagName = value;
value = '';
}
}
else if ( tagName == 'span' ) {
if ( ( value = style.color ) ) {
tagName = 'color';
value = CKEDITOR.tools.convertRgbToHex( value );
....
At least this works for me.
This is kind of weired because the Justify Plugin is adding 'div' elements instead of 'span'. Maybe you can also modify it to satisfy your 'span' requirement.

Adding a span to a particular word in a contendEditable div?

I have a div which is content editable, and JS function to search the input for certain words. If a match is found, the content od the div turns blue, but I want only the matched word to turn blue. How can I do this?
Here is my JS...
function init() {
window.setInterval(function() {
var div = document.getElementById("texty");
var html = div.innerHTML;
var buzzword = ["function","()","{", "}","[", "]",".getElementById", ".getElementsByClassName",".style","$"];
for(var i = 0; i < buzzword.length; i++)
{
var regex = new RegExp(buzzword[i], 'g');
html = html.replace(regex, "<span style='color:blue'>" + buzzword[i] + "</span>");
}
div.innerHTML = html;
}, 100);
}
and my HTML is this...
<div id="texty" contenteditable="true" onfocus="init()"></div>
Get the html of the div then do a regex replace and add a span around the word. Code would look something like this:
var escape= function(s) {
return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')
};
var div = document.getElementById("texty");
var html = div.innerHTML;
var buzzword = ["function","()","{", "}","[", "]",".getElementById", ".getElementsByClassName",".style","$"];
for(var i = 0; i < buzzword.length; i++)
{
var regex = new RegExp(escape(buzzword[i]), 'g');
html = html.replace(regex, "<span style='color:blue'>" + buzzword[i] + "</span>");
}
div.innerHTML = html;

Categories

Resources