Open brandondurham opened 9 years ago
parentElement.nodeName
should do it, but there might be more to what you want to do (and I'm totally for it)
Considering you need to merge the attributes into one tag.
Is this in a single plugin or does it span multiple ones?
This comparison function will actually span multiple plugins that I'll be sharing in the not-too-distant future.
parentElement.nodeName
won't necessarily tell me if the selected text is already wrapped in a <span>
, though, right? It will just give me the nodeName
of the parent.
@brandondurham If I understand you correctly then extractContents
returns a DocumentFragment which you can check the first element of.
Thanks for your code @brandondurham , I wanted to achieve the very same thing and based it off of your code here. These are my results (these are not "production-ready" or tested thoroughly!!):
fontSizeCommand.execute = function(size) {
scribe.transactionManager.run(function () {
let selection = new scribe.api.Selection();
let range = selection.range;
// Get Range Text & Current Node Text
let selectedHtmlDocumentFragment = range.extractContents();
let tDiv = document.createElement('div');
tDiv.appendChild(selectedHtmlDocumentFragment.cloneNode(true));
let rangeText = tDiv.innerText;
let nodeText = selection.selection.focusNode.textContent;
// Determine if we need a new node
let isNewNode = true;
if (nodeText === rangeText) {
isNewNode = (selection.selection.focusNode.parentElement.nodeName === 'SPAN') ? false : true;
}
// Create / Get SPAN
let span = (!isNewNode) ? selection.selection.focusNode.parentElement : document.createElement('span');
span.appendChild(selectedHtmlDocumentFragment);
if (isNewNode) {
range.insertNode(span);
range.selectNode(span);
}
// Clear Setting for children
for (let i in span.childNodes) {
let child = span.childNodes[i];
if (child.nodeName === 'SPAN') {
child.style.fontSize = '';
if (!child.getAttribute('style')) {
scribe.node.unwrap(span,child);
}
}
}
// Apply new Font-Size
span.style.fontSize = size;
// Re-apply the range
selection.selection.removeAllRanges();
selection.selection.addRange(range);
});
};
I'd very much like to hear your thoughts / experiences since your last post.
Edit: Ok, it's not perfect yet, I'm integrating it with more options like color and font-family and it seems that some child nodes do not get removed properly yet, that should be solveable with a simple recursive lookup in the child nodes though.
Edit2: I actually threw this into its own repo, so if anyone is interested I will be happy about feedback / ideas! https://github.com/jsiebern/scribe-plugin-span-style
Hey guys, thought I'd update this thread as I've made some significant progress to get this working more reliably and even mostly cross-browser. Just check out the latest source here:
Very nice, @jsiebern! Taking a look at it now. Thanks for sharing.
My pleasure, feel free to let me know if you find any improvements or have other suggestions.
I'm working on a plugin for font sizes that just wraps the selected text in a
<span>
and appliesstyle="font-size: [n]px;"
to the span, where[n]
gets replaced by the value passed in. My code thus far:I’d like to be able to just reuse a span (or any element, for that matter) if the currently-selected text is wrapped in one. With the above code, if you select the characters “Basil Elton” in the sentence “I am Basil Elton” and apply a font size, then apply another to the same selection you will get the following output:
What is the best way to see if the currently-selected text is already wrapped in an element that can be used in this instance?