range.insertNode() is not inserting text node as expected
Asked Answered
E

1

6

I am creating a chrome extension. Basically, the if the user clicks a content menu option, I want to insert HTML format tags before and after the selected text.

The tags are being added in an event page which, after adding the format tags, fires off the new value to a content script in the 'paste' key of the message object.

The code for my content script is as follows:

chrome.runtime.onMessage.addListener(handleRequest)

function handleRequest(message, sender)
{
    if (message.paste!==undefined) 
    {
        var newNode = document.createTextNode('');
        newNode.innerHTML=message.paste;   

        var cursor = window.getSelection().getRangeAt(0);       
        cursor.deleteContents();     
        cursor.insertNode(newNode);    
        alert(newNode.innerHTML);       
    }
}

I thought I was doing this correctly, because according to this

If the new node is to be added to a text Node, that Node is split at the insertion point, and the insertion occurs between the two text nodes.

However, the result of clicking the context menu option is simply the deletion whatever text was selected. The new text is never added, but no errors are printed to console.

I am aware that this will not work for stuff in input elements or text areas, right now I am just trying to get it work on regular text on the page.

The contents of the alert popup are, as expected, the selected text surrounded in formatting tags.

Can someone explain what I am doing wrong? should I not be editing the HTML of a text node? Is there some last step that I am missing to make the text appear?

Demonstration of error:

If I highlight the title of this question, the following alert box appears(I clicked the strikethrough option). Notice that the title has disappeared from the page.

enter image description here

Eleanoraeleanore answered 14/1, 2015 at 16:43 Comment(2)
I don´t kwon if I understand you correctly. You put de message, deleting all. Maybe you need to do: node.innerHTML = node.innerHTML + message.paste. Putting all messages in the same node.Anthropomorphous
There is only a single message value. It lies in the paste key. For example, If I select the text "fooBar" and click "bold" the paste key will contain "<b>fooBar</b> this is being confirmed with the alert boxEleanoraeleanore
M
5

The object created by document.createTextNode('') doesn't have an innerHTML property. If you want to replace its content, you can do as follows:

var newNode = document.createTextNode('');
newNode.replaceWholeText(message.paste);

That looks like it will probably break the rendering if you're doing it with HTML content though, so either you'd have to get the parent container and edit its innerHTML directly, or wrap your new node in an element of some kind, if appropriate, as follows:

var newNode = document.createElement('b');
newNode.innerHTML = message.paste;
Merrilee answered 14/1, 2015 at 19:32 Comment(4)
if text nodes do not have the innerHTML property, then why is it that alert(newNode.innerHTML) returns the value of message.paste as expected?Eleanoraeleanore
Also, If I choose the latter route, where can I find a list of HTML tag names that correspond to the various elements I want to create? The fact that I can not find a list is what stopped me from doing that in the first place because I don't know what to use as a parameter to create a strike through element, for exampleEleanoraeleanore
In javascript, you can easily append new properties to existing objects - which is what you've done. But it's not how the content of the node will be accessed when you add it to the DOM. To prove this, try setting an initial value in the constructor, like var newNode = document.createTextNode('FOO'); And then test it. When you add it, rather than the title being missing, I'm certain it will be replaced with FOO from the constructor.Merrilee
Sure, now addressing your second comment - I would use the elements list here: w3schools.com/jsref/default.asp Really the highlights for formatting are going to be: "i", "b", "u" for italic, bold, underline - respectively, "del" for strikethrough. I'm inclined to say "span" for either no formatting or if you want something with a style attribute so you can do colors, for example. The other thing is you could use createElement("span") and then use innerHTML on that to put in whatever you want, as long as you don't mind that in the markup the edited section will be inside a span tag.Merrilee

© 2022 - 2024 — McMap. All rights reserved.