I'm writing a GUI extension that will essentially wrap selected text in a specific DIV. I have the text being encapsulated with the DIV but have hit a bit of a block...
When the user hasn't selected a specific piece of text I am assuming the intention is to wrap the nearest HTML element
htmlSelectedNode = target.editor.getSelectedHTMLElement()
This all seems to work fine and I pass the HTML element into my extension. After some manipulation I then apply the HTML but it is injecting the new HTML inside the previous element - instead of replacing it...
Is it possible to 'select' the HTML element - I can see a .focus()
and a .setCapture()
but these don't seem to do the trick - I guess the ideal would be to use the same functionality as applied when selecting an element from the "Current Element" dropdown on the ribbon bar but I've not been successful in locating the onclick/select method associated with this dropdown.
Just to clarify... with an example...
if the text was
<div class="notrelevant"><p>test1</p><p>this is an example</p></div>
and the user inserted the cursor inbetween the i and s in 'is' I want the GUI to pre-select the nearest HTML Element - in this case the end result would be...
<div class="notrelevant"><p>test1</p><div class="INJECTED_CORRECTLY"><p>this is an example</p></div></div>
EDIT: For completeness I've included the submit event that I use to (re)inject the HTML into the RTF (although I don't think it would make sense to manipulate the selection at this point and would prefer to have 'selected' the text above using a more 'standard', existing Tridion functionality...)
$evt.addEventHandler(popup, "submit",
function DateHighlighter$execute$onPopupSubmitted(event) {
var el = event.data.html;
if (el) {
if (htmlSelectedNode != null) {
var lDocument = htmlSelectedNode.ownerDocument;
var lTempContainer = lDocument.createElement("span");
try {
lTempContainer.innerHTML = el || "";
}
catch (err) {
//assigning a value to innerHTML can be sensitive to browser but the error is fine to be ignored
}
var parentNode = htmlSelectedNode.parentNode;
parentNode.replaceChild(lTempContainer, htmlSelectedNode);
//Move to the new element
var lTextRange = $dom.createTextRange(lTempContainer);
$dom.moveRangeToElement(lTextRange, lTempContainer);
//Select and remove the temporary element
$dom.selectRange(lTextRange, $dom.getSelection(lDocument));
$dom.removeNode(lTempContainer, false);
}
else {
// Insert new created element (DIV)
target.editor.applyHTML(el);
}
}
else {
//TODO: test this - it's likely not required
if (htmlSelectedNode.attributes["class"] != null)
htmlSelectedNode.removeAttribute("class");
//TODO: test this - it's likely not required
if (htmlSelectedNode.attributes["ondblclick"] != null)
htmlSelectedNode.removeAttribute("ondblclick");
//TODO: the node isn't removed - leaves the empty <div>...
// - delete the node and then apply the node2.outerHTML? - or follow parentnode pattern above!
var htmlSelectedNode2 = htmlSelectedNode.innerHTML;
htmlSelectedNode = htmlSelectedNode2;
}
//Refreshes the Design view
target.editor.setCurrentView("Source");
target.editor.setCurrentView("RichText");
target.item.closeActivePopup();
});
$evt.addEventHandler(popup, "unload", DateHighlighter$execute$onPopupCanceled);
So I located the CurrentElement
selection and saw the glaringly obvious setSelectedHTMLElement
. Not sure how I missed it but alas here is is below... as the comments note - ensure the method is available (if the user has a string of text selected that doesn't equate directly to a HTMLElement the setSelectedHTMLElement
method will fail and remove us the user selection (thus meaning the GUI Extension .aspx can't (re)inject the new HTML...
//if there's no tagname then the setSelected will fail and remove the (non-element based) select the user has done
if (htmlSelectedNode.nodeName && htmlSelectedNode.nodeName != '#text') {
//unlikely to get #text here as it's the htmlSelectedNode.commonAncestorContainer.nodeName
$log.message(logt + 'selecting the htmlSelectedNode.nodeName:' + htmlSelectedNode.nodeName);
target.editor.setSelectedHTMLElement(htmlSelectedNode);
}
else {
$log.message(logt + 'no htmlSelectedNode.nodeName - user probably selected incomplete element:');
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With