I'm working on a WYSIWYG text editor and I'm working on the ability to switch between the WYSIWYG mode and BBcode mode. I'm having trouble getting it to display back in WYSIWYG mode after you make the switch.
function editormode()
{
var html;
var bbcode = new Array();
var htmlcode = new Array();
htmlcode[0] = "<b>"; bbcode[0] = "[b]";
htmlcode[1] = "</b>"; bbcode[1] = "[/b]";
htmlcode[2] = "<i>"; bbcode[2] = "[i]";
htmlcode[3] = "</i>"; bbcode[3] = "[/i]";
htmlcode[4] = "<u>"; bbcode[4] = "[u]";
htmlcode[5] = "</u>"; bbcode[5] = "[/u]";
htmlcode[6] = "<strike>"; bbcode[6] = "[strike]";
htmlcode[7] = "</strike>"; bbcode[7] = "[/strike]";
htmlcode[8] = "<sub>"; bbcode[8] = "[sub]";
htmlcode[9] = "</sub>"; bbcode[9] = "[/sub]";
htmlcode[10] = "<sup>"; bbcode[10] = "[sup]";
htmlcode[11] = "</sup>"; bbcode[11] = "[/sup]";
if (editormode == "true") {
htmltext = document.getElementById('editor').contentWindow.document.body.innerHTML;
for(i = 0; i < 12; i++){
searchtext = htmltext.search(htmlcode[i]);
if(searchtext != -1) {
htmltext = htmltext.replace(htmlcode[i], bbcode[i]);
}
}
html = document.createTextNode(htmltext);
document.getElemen开发者_C百科tById('editor').contentWindow.document.body.innerHTML = "";
html = document.getElementById('editor').contentWindow.document.importNode(html,false);
document.getElementById('editor').contentWindow.document.body.appendChild(html);
editormode = "false";
} else {
htmltext = document.getElementById('editor').contentWindow.document.body.innerHTML;
for(i = 0; i < 12; i++){
searchtext = htmltext.search(bbcode[i]);
if(searchtext != -1) {
htmltext = htmltext.replace(bbcode[i], htmlcode[i]);
}
}
html = document.createTextNode(htmltext);
document.getElementById('editor').contentWindow.document.body.innerHTML = "";
html = document.getElementById('editor').contentWindow.document.importNode(html,false);
document.getElementById('editor').contentWindow.document.body.appendChild(html);
editormode = "true";
}
}
If what I'm seeing is right, it looks like you're doing String.replace()
, on the entire body of text, and only using a string to find a target to replace.
What I suspect is happening, is that you're then only replacing the first instance of the tag you're trying to find and replace. When using String.replace()
while passing a string, as the search parameter, it will only find and replace the first instance of the matching substring.
"hello".replace('l', 'r'); // returns "herlo" and not "herro"
Try changing the search strings into global regex before preforming the replace:
var tagEx = new RegExp(htmlcode[i], 'g');
htmltext.replace(tagEx, bbcode[i]);
I believe that will fix your problem. Also, when doing that, you probably don't need to bother calling String.search()
beforehand. Nothing bad comes from calling String.replace()
on a string that has no matches. So, getting rid of that check, might even save you some computation time.
Another thing worth mentioning, and I'm not sure if this may be conflicting with the rest of your code, is that when you do your array-loops you aren't using var
to instantiate your increment variable. As in var i=0
, which can sometimes cause issues, since not using var
will create a global variable, which may conflict with code elsewhere.
Hope that helps.
There's a couple problems with your function but, the string replacement issue is probably the bug that makes it look like it's not converting anything. Here's a smaller version of your function that works for me:
function editormode(is_editor_mode) {
var replaceTagsByMode = function(html, is_editor_mode) {
var tags = {};
for (var i=0, a=['b', 'i', 'u', 'strike', 'sub', 'sup']; i<a.length; i++) {
tags[['<', a[i], '>'].join('')] = ['[', a[i], ']'].join('');
tags[['</', a[i], '>'].join('')] = ['[/', a[i], ']'].join('');
}
for (var html_tag in tags) {
if (tags.hasOwnProperty(html_tag)) {
html = html.replace.apply(
html, is_editor_mode ? [html_tag, tags[html_tag], 'g'] : [tags[html_tag], html_tag, 'g']);
}
}
return html;
};
var editor_body = document.getElementById('editor').contentWindow.document.body;
editor_body.innerHTML = replaceTagsByMode(editor_body.innerHTML, is_editor_mode);
}
It might be best to use existing code that does this, such as bbc2html (for just converting bbcode to HTML) or bbeditor (for the whole editor). See also Simple WYSIWYG BBCode editor for JavaScript?.
If you would rather write it yourself, converting these tags could be as simple as:
html = bbcode.replace(/\[(\/?(b|i|u|strike|sub|sup))\]/gi, '<$1>');
bbcode = html.replace(/<(\/?(b|i|u|strike|sub|sup))>/gi, '[$1]');
精彩评论