I see that theres is no build in way for doing tabs/indents in MarkItUp? So I did something like
onTab: {
keepDefault: false,
replaceWith: function(markItUp) {
return miu.openEachLineWith(markItUp, ' ');
}
},
openEachLineWith: function(markItUp, openingStr) {
var textarea = markItUp.textarea,
selStart = textarea.selectionStart,
selEnd = textarea.selectionEnd,
selText = textarea.value.substring(selStart, selEnd),
lines = [],
charsAdded = 0;
lines = selText.split(/\r?\n/);
for (var i = 0, len = lines.length; i < len; i++) {
lines[i] = openingStr + lines[i];
charsAdded += openingStr.length;
}
textarea.selectionEnd = selEnd + charsAdded;
return lines.join('\n');
}
which works but, how can I set the selection after replacing the the text, I want it to select the tabbed text, also I prefer the way the editor here on SO works where when I bold some text, it selects the bolded text instead of moving the cursor to the end, can I do that with markItUp too?
I've been working on a script to do this. Here's an example: http://jsfiddle.net/timdown/dp2WL/2/
It indents when Tab is pressed and outdents when Shift + Tab is pressed and doesn't require any library. It hasn't had as much testing as I'd like, but seems to work well in all major browsers, including IE 6. The main code comes from an open source project I'm working on. The bit that enables tab indentation is at the bottom:
window.onload = function() {
rangyInputs.init();
rangyInputs.enableTabIndentation(document.getElementById("test"), " ");
};
You must set the selection in the afterInsert callback (not in replaceWith)
Related
In the content scripts of my chrome extension I am trying to inject code that highlights a specific word in the page.
In this instance, I am viewing espn.com and would like to have all instances of 'bryant' highlighted in the text immediately as the page is loaded.
This is the current code I have customized after viewing several questions similar to mine:
var all = document.getElementsByTagName("*");
highlight_words('Bryant', all);
function highlight_words(keywords, element) {
if(keywords) {
var textNodes;
keywords = keywords.replace(/\W/g, '');
var str = keywords.split(" ");
$(str).each(function() {
var term = this;
var textNodes = $(element).contents().filter(function() { return this.nodeType === 3 });
textNodes.each(function() {
var content = $(this).text();
var regex = new RegExp(term, "gi");
content = content.replace(regex, '<span class="highlight">' + term + '</span>');
$(this).replaceWith(content);
});
});
}
}
In my jquery-ui.css I have the following code. I understand it does not highlight at this moment but I am just trying to get a proof of concept:
.highlight {
font-weight: bold;
}
At this time everything loads properly but no iteration of 'bryant' is read in bold.
Thanks!
The fastest way to do this is to define the what are you want to search for highlight, for example:
You have 3 parts on site, the navbar on left, the title on the top and the content.
Lets attach .foo class to article.
var list = document.getElementsByClassName("foo")
var search_word = ""
var contents = []
for(var i = 0; i < list.length; i++){
var contents = list[i].textContext.split(search_word)
list[i].textContext = contents.join('<span class="heighlight\">'+search_word+'</span>')
}
Hope it will help.
(The highlight is bound to elements that have .foo class)
some example: https://jsfiddle.net/Danielduel/0842qntu/2/
I have a function that I want to change the font color of the user entered string if it is equal to a certain word located in an array.. So far when I step through it it says that it changes the font color but it actually never updates it to the screen and I don't know why. Here is what I have so far
function getLastWord() {
var input = document.getElementById("my_text");
//var input = document.getElementById(textArea.value);
//var lineIn = document.getElementById(my_text).innerHTML;
var inputValue = input.value;
var lastWordTyped
var changeColorOfWord;
if (input == null) {
input == " ";
}
//lastWordTyped = input.substr(input.trim().lastIndexOf(" ") + 1);
lastWordTyped = inputValue.substr(inputValue.trim().lastIndexOf(" ") + 1);
if (input != null) {
for (var i = 0; i < reservedKeyWords.length; i++) {
if (reservedKeyWords[i] === lastWordTyped) {
lastWordTyped = lastWordTyped.fontcolor("blue");
my_text.replace(inputValue, lastWordTyped);
} else {
}
}
}
}
I see two issues with the code thus far.
You are using 'fontcolor("blue")' parameter on the lastWordTyped. The proper syntax to change color is element.style.color="#CCC".
You will need to wrap the last typed word in a span so you can target it and apply the color to just that word.
string.fontcolor is legacy, and should not be used even though I could see it as a viable option in this case
Essentially, what you are doing is adding font tags around the word:
var txt = 'hello world';
txt = txt.fontcolor('blue');
//txt = '<font color="blue">hello world</font>';
You do not show what you do with the result, but if you actually put it in an HTML element it should work, even though instead of using fontcolor, I'd rather use element.style.color. This would require slightly more work though:
var ele = document.querySelector('#my_text');
ele.style.color = 'blue';
ele.innerHTML = lastWordTyped;
If you still want to go with the .fontcolor method, you could just keep what you have in the question and add
input.innerHTML = my_text;
I am designing a language learning site. I want to have it when someone enters text into the text box it starts to roll over certain images. Take a look at my sample below
http://imageshack.us/photo/my-images/827/hiraganaquiz2.jpg/
So, when the user enters "na" the first symbol highlights as you see in my sample. When he enters "ma" the second symbol should highlight/rollover. I want all the symbols to stay rolled over while the correct text is entered. so if the user types "nama" the first two symbols should be rolled over to show they got it correct and once the last correct text is entered all three will be rolled over.
Can this by done? I will accept advanced and simple methods.
$(document).ready(function() {
var text = ['na', 'ma', 'ba'];
$("#elemID").on('keyup', function() {
var typed = this.value;
$.each(text, function(index, item) {
if (typed.indexOf(item)!=-1) {
$('li', 'ul').eq(index).find('img').addClass('correct');
}else{
$('li', 'ul').eq(index).find('img').removeClass('correct');
}
});
});
});
FIDDLE
EDIT:
At the top of your page, in the <head> section, add:
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
Then wrap the code in document.ready, see the edited code above on how to do that ?
On change of the input box, you could do something like this: (totally untested)
var parts = ["na", "ma", "blah"];
var start = 0;
for (var i = 0; i < parts.length; i++) {
var currentPart = parts[i];
var $img = $(".images img:nth-child(" + i + ")");
var end = start + currentPart.length;
if (str.length >= end && str.slice(start, start + currentPart.length) == currentPart) {
$img.addClass("highlight");
} else {
$img.removeClass("highlight");
}
start += currentPart.length;
}
I have a VS2010,C# ASP.NET web app, I've written a JavaScript (in aspx page) that works perfect in firefox but almost does nothing in chrome or IE, it is my function:
<script type="text/javascript" >
function onRadioChange(rowIndex, value, myHref) {
var q = document.getElementById('HF').value.toString();
var q2 = q.split(',');
var new_HF = '';
for (var i = 0; i < rowIndex; i++) {
new_HF += q2[i] + ',';
}
new_HF += value.toString() + ',';
for (var j = rowIndex; j < q2.length - 1; j++) {
if (j > rowIndex) {
new_HF += q2[j] + ',';
}
}
document.getElementById('HF').value = new_HF;
//user has voted all questions? enable hpAccept so that he can go to next questionnaire
var q5 = new_HF.split(',');
var all_ok = true;
for (var g = 0; g < q5.length; g++) {
if (q5[g] == '0')
all_ok = false;
}
if (all_ok) {
document.getElementById('hpAccept').disabled = false;
document.getElementById('hpAccept').href = myHref;
}
}
it seems that this function does nothing in IE or chrome, I placed and alert to display some info but nothing was displayed in chrome or IE, what is wrong with them?
another problem is on the last parts, the hyperlink is initially disabled, but it is enabled in firefox no luck in IE or chrome, what is the problem here? how can I make this function cross-browser?
[EDIT] I put an alert('1') exactly after function definition line and I saw nothing in chrome and IE, it seems that this function is not called in these browsers, I use r.Attributes.Add("onChange", "return onRadioChange('" + (i - 1).ToString() + "','1','" + myHref + "');"); for calling this function in codebehind, r is a dynamically created radiobutton.
You are not supposed to disable the a tag.
The following elements support the disabled attribute: BUTTON, INPUT,
OPTGROUP, OPTION, SELECT, and TEXTAREA.
Source: http://www.w3.org/TR/html4/interact/forms.html#adef-disabled
That´s why document.getElementById('myLink').disabled returns undefined.
Duplicate of Radio Button change event not working in chrome or safari
Solution: For Radiobuttons, use the onClick event instead of onChanged
I am using a 'contenteditable' <div/> and enabling PASTE.
It is amazing the amount of markup code that gets pasted in from a clipboard copy from Microsoft Word. I am battling this, and have gotten about 1/2 way there using Prototypes' stripTags() function (which unfortunately does not seem to enable me to keep some tags).
However, even after that, I wind up with a mind-blowing amount of unneeded markup code.
So my question is, is there some function (using JavaScript), or approach I can use that will clean up the majority of this unneeded markup?
Here is the function I wound up writing that does the job fairly well (as far as I can tell anyway).
I am certainly open for improvement suggestions if anyone has any. Thanks.
function cleanWordPaste( in_word_text ) {
var tmp = document.createElement("DIV");
tmp.innerHTML = in_word_text;
var newString = tmp.textContent||tmp.innerText;
// this next piece converts line breaks into break tags
// and removes the seemingly endless crap code
newString = newString.replace(/\n\n/g, "<br />").replace(/.*<!--.*-->/g,"");
// this next piece removes any break tags (up to 10) at beginning
for ( i=0; i<10; i++ ) {
if ( newString.substr(0,6)=="<br />" ) {
newString = newString.replace("<br />", "");
}
}
return newString;
}
Hope this is helpful to some of you.
You can either use the full CKEditor which cleans on paste, or look at the source.
I am using this:
$(body_doc).find('body').bind('paste',function(e){
var rte = $(this);
_activeRTEData = $(rte).html();
beginLen = $.trim($(rte).html()).length;
setTimeout(function(){
var text = $(rte).html();
var newLen = $.trim(text).length;
//identify the first char that changed to determine caret location
caret = 0;
for(i=0;i < newLen; i++){
if(_activeRTEData[i] != text[i]){
caret = i-1;
break;
}
}
var origText = text.slice(0,caret);
var newText = text.slice(caret, newLen - beginLen + caret + 4);
var tailText = text.slice(newLen - beginLen + caret + 4, newLen);
var newText = newText.replace(/(.*(?:endif-->))|([ ]?<[^>]*>[ ]?)|( )|([^}]*})/g,'');
newText = newText.replace(/[·]/g,'');
$(rte).html(origText + newText + tailText);
$(rte).contents().last().focus();
},100);
});
body_doc is the editable iframe, if you are using an editable div you could drop out the .find('body') part. Basically it detects a paste event, checks the location cleans the new text and then places the cleaned text back where it was pasted. (Sounds confusing... but it's not really as bad as it sounds.
The setTimeout is needed because you can't grab the text until it is actually pasted into the element, paste events fire as soon as the paste begins.
How about having a "paste as plain text" button which displays a <textarea>, allowing the user to paste the text in there? that way, all tags will be stripped for you. That's what I do with my CMS; I gave up trying to clean up Word's mess.
You can do it with regex
Remove head tag
Remove script tags
Remove styles tag
let clipboardData = event.clipboardData || window.clipboardData;
let pastedText = clipboardData.getData('text/html');
pastedText = pastedText.replace(/\<head[^>]*\>([^]*)\<\/head/g, '');
pastedText = pastedText.replace(/\<script[^>]*\>([^]*)\<\/script/g, '');
pastedText = pastedText.replace(/\<style[^>]*\>([^]*)\<\/style/g, '');
// pastedText = pastedText.replace(/<(?!(\/\s*)?(b|i|u)[>,\s])([^>])*>/g, '');
here the sample : https://stackblitz.com/edit/angular-u9vprc
I did something like that long ago, where i totally cleaned up the stuff in a rich text editor and converted font tags to styles, brs to p's, etc, to keep it consistant between browsers and prevent certain ugly things from getting in via paste. I took my recursive function and ripped out most of it except for the core logic, this might be a good starting point ("result" is an object that accumulates the result, which probably takes a second pass to convert to a string), if that is what you need:
var cleanDom = function(result, n) {
var nn = n.nodeName;
if(nn=="#text") {
var text = n.nodeValue;
}
else {
if(nn=="A" && n.href)
...;
else if(nn=="IMG" & n.src) {
....
}
else if(nn=="DIV") {
if(n.className=="indent")
...
}
else if(nn=="FONT") {
}
else if(nn=="BR") {
}
if(!UNSUPPORTED_ELEMENTS[nn]) {
if(n.childNodes.length > 0)
for(var i=0; i<n.childNodes.length; i++)
cleanDom(result, n.childNodes[i]);
}
}
}
This works great to remove any comments from HTML text, including those from Word:
function CleanWordPastedHTML(sTextHTML) {
var sStartComment = "<!--", sEndComment = "-->";
while (true) {
var iStart = sTextHTML.indexOf(sStartComment);
if (iStart == -1) break;
var iEnd = sTextHTML.indexOf(sEndComment, iStart);
if (iEnd == -1) break;
sTextHTML = sTextHTML.substring(0, iStart) + sTextHTML.substring(iEnd + sEndComment.length);
}
return sTextHTML;
}
Had a similar issue with line-breaks being counted as characters and I had to remove them.
$(document).ready(function(){
$(".section-overview textarea").bind({
paste : function(){
setTimeout(function(){
//textarea
var text = $(".section-overview textarea").val();
// look for any "\n" occurences and replace them
var newString = text.replace(/\n/g, '');
// print new string
$(".section-overview textarea").val(newString);
},100);
}
});
});
Could you paste to a hidden textarea, copy from same textarea, and paste to your target?
Hate to say it, but I eventually gave up making TinyMCE handle Word crap the way I want. Now I just have an email sent to me every time a user's input contains certain HTML (look for <span lang="en-US"> for example) and I correct it manually.