Tridion RTF文本选择
我正在编写一个GUI扩展,它基本上会将选定的文本包装到一个特定的DIV中。我用DIV封装了文本,但遇到了一点障碍 当用户没有选择一段特定的文本时,我假设其意图是包装最近的HTML元素Tridion RTF文本选择,tridion,tridion-2011,Tridion,Tridion 2011,我正在编写一个GUI扩展,它基本上会将选定的文本包装到一个特定的DIV中。我用DIV封装了文本,但遇到了一点障碍 当用户没有选择一段特定的文本时,我假设其意图是包装最近的HTML元素 htmlSelectedNode = target.editor.getSelectedHTMLElement() 这一切似乎都很好,我将HTML元素传递到扩展中。在一些操作之后,我应用了HTML,但是它将新的HTML注入到前面的元素中,而不是替换它 可以“选择”HTML元素吗?我可以看到一个.focus()和一
htmlSelectedNode = target.editor.getSelectedHTMLElement()
这一切似乎都很好,我将HTML元素传递到扩展中。在一些操作之后,我应用了HTML,但是它将新的HTML注入到前面的元素中,而不是替换它
可以“选择”HTML元素吗?我可以看到一个.focus()
和一个.setCapture()
,但这些似乎不起作用-我想理想的做法是使用与从“当前元素”中选择元素时应用的相同功能功能区栏上的下拉列表,但我尚未成功找到与此下拉列表关联的onclick/select方法
只是想澄清一下。。。举个例子
如果文本是
<div class="notrelevant"><p>test1</p><p>this is an example</p></div>
test1这是一个示例
用户将光标插入“is”中的i和s之间,我希望GUI预先选择最近的HTML元素-在这种情况下,最终结果将是
<div class="notrelevant"><p>test1</p><div class="INJECTED_CORRECTLY"><p>this is an example</p></div></div>
test1这是一个示例
编辑:
为了完整性,我加入了提交事件,我使用它(重新)将HTML注入RTF(尽管我认为此时操纵选择没有意义,我更希望使用更“标准”的现有Tridion功能来“选择”上面的文本…)
$evt.addEventHandler(弹出“提交”,
函数DateHighlighter$execute$OnPopusSubmitted(事件){
var el=event.data.html;
如果(el){
如果(htmlSelectedNode!=null){
var lDocument=htmlSelectedNode.ownerDocument;
var lTempContainer=lDocument.createElement(“span”);
试一试{
lTempContainer.innerHTML=el | |“”;
}
捕捉(错误){
//为innerHTML指定值可能对浏览器敏感,但可以忽略该错误
}
var parentNode=htmlSelectedNode.parentNode;
replaceChild(lTempContainer,htmlSelectedNode);
//移到新元素
var lTextRange=$dom.createTextRange(lTempContainer);
$dom.moveRangeToElement(lTextRange、lTempContainer);
//选择并删除临时图元
$dom.selectRange(lTextRange,$dom.getSelection(lDocument));
$dom.removeNode(lTempContainer,false);
}
否则{
//插入新创建的元素(DIV)
target.editor.applyHTML(el);
}
}
否则{
//TODO:测试这个-它可能不是必需的
if(htmlSelectedNode.attributes[“class”!=null)
htmlSelectedNode.removeAttribute(“类”);
//TODO:测试这个-它可能不是必需的
if(htmlSelectedNode.attributes[“ondblclick”]!=null)
htmlSelectedNode.removeAttribute(“ondblclick”);
//TODO:节点未被删除-保留为空。。。
//-删除节点,然后应用node2.outerHTML?-或遵循上面的parentnode模式!
var htmlSelectedNode2=htmlSelectedNode.innerHTML;
htmlSelectedNode=htmlSelectedNode2;
}
//刷新设计视图
target.editor.setCurrentView(“源”);
target.editor.setCurrentView(“RichText”);
target.item.closeActivePopup();
});
$evt.addEventHandler(弹出“卸载”,DateHighlighter$execute$OnPopupCancelled);
因此我找到了CurrentElement
选项,看到了非常明显的SetSelectedHtmleElement
。不知道我是怎么错过的,但是,唉,下面是。。。如注释所示-确保方法可用(如果用户选择的文本字符串不直接等同于HtmleElement,SetSelectedHtmleElement
方法将失败,并删除用户选择(因此意味着GUI扩展.aspx无法(重新)注入新的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:');
}
这是一个棘手的问题。您需要检查所有可能的场景。一年前,我们必须实现一个自定义的“超链接”功能作为GUI扩展。问题是相同的:“我怎么知道选择了什么?”,“如果用户选择了一个文本和一半html节点怎么办?”“如果选择只是文本怎么办?”基本上和你面临的问题是一样的
如果我理解正确,你想用一个给定的(自定义的)div来包装选定的文本,对吗?你还需要考虑的东西(如果你还没有)是:“如果用户选择了一个已经被你的自定义div包裹的文本,会发生什么?”“如果他选择了一个用自定义div包装的文本加上div之后或之前的一段文本,该怎么办?”
正如我前面提到的,这并不容易,或者至少不直接。下面是一些关于我们所做工作的提示,在我们的例子中,我们必须用超链接标记而不是div来包装文本,但是从“获取/设置选定的html”的观点来看,这应该会有所帮助: 第一:初始化元素节点并获取所选html:var element = null;
var htmlSelectedNode = target.editor.getSelectedHTMLElement() || {};
第二:看看到底有什么:
if (htmlSelectedNode != null && htmlSelectedNode.tagName != null && htmlSelectedNode.tagName == "A") { //In your case you might wanna check if it is a div, instead
...
...
}
注意:在我们的例子中,我们还必须检查图像和跨度标记,因为锚元素会有点不同,因为我们需要从这些元素中获取一些信息
第三:如果所选文本是元素(未选择额外文本),则设置元素变量
第四:如果htmlSelectedNode包含一个节点加上之前或之后的原始文本,则我们使用范围(进一步读取)
if (htmlSelectedNode != null && htmlSelectedNode.tagName != null && htmlSelectedNode.tagName == "A") { //In your case you might wanna check if it is a div, instead
...
...
}
element = htmlSelectedNode;
var selectedText = "";
// Chrome & Firefox
if (htmlSelectedNode != null && htmlSelectedNode.startContainer != null && htmlSelectedNode.startOffset != null) {
selectedText = htmlSelectedNode.toString();
}
// IE Range
else if (htmlSelectedNode != null && htmlSelectedNode.htmlText != null && htmlSelectedNode.text != null) {
selectedText = htmlSelectedNode.text;
}
// IE DIV
else if (htmlSelectedNode != null && (htmlSelectedNode.tagName == "DIV" || htmlSelectedNode.tagName == "P") && htmlSelectedNode.innerText != null) {
selectedText = htmlSelectedNode.innerText;
}
// If there is a link, delete it
if (htmlSelectedNode != null) {
var lDocument = htmlSelectedNode.ownerDocument;
var lTempContainer = lDocument.createElement("span");
try {
lTempContainer.innerHTML = el || "";
}
catch (err) {
//assigning a value to innerHTML might fail -> ignore it then
}
var parentNode = htmlSelectedNode.parentNode;
parentNode.replaceChild(lTempContainer, htmlSelectedNode);
//move to new element
var lTextRange = $dom.createTextRange(lTempContainer);
$dom.moveRangeToElement(lTextRange, lTempContainer);
//select and remove temp element
$dom.selectRange(lTextRange, $dom.getSelection(lDocument));
$dom.removeNode(lTempContainer, false);
}
// Insert new created link
target.editor.applyHTML(el); //el == element
//Refreshes the Design view
target.editor.setCurrentView("Source");
target.editor.setCurrentView("RichText");