Tridion RTF文本选择

Tridion RTF文本选择,tridion,tridion-2011,Tridion,Tridion 2011,我正在编写一个GUI扩展,它基本上会将选定的文本包装到一个特定的DIV中。我用DIV封装了文本,但遇到了一点障碍 当用户没有选择一段特定的文本时,我假设其意图是包装最近的HTML元素 htmlSelectedNode = target.editor.getSelectedHTMLElement() 这一切似乎都很好,我将HTML元素传递到扩展中。在一些操作之后,我应用了HTML,但是它将新的HTML注入到前面的元素中,而不是替换它 可以“选择”HTML元素吗?我可以看到一个.focus()和一

我正在编写一个GUI扩展,它基本上会将选定的文本包装到一个特定的DIV中。我用DIV封装了文本,但遇到了一点障碍

当用户没有选择一段特定的文本时,我假设其意图是包装最近的HTML元素

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");