我正在使用GWT RichTextArea,需要在当前光标位置插入文本。我读到了使用方法RichTextArea.getFormatter()。insertHTML()作为一种方法来做到这一点并且它工作正常。
我的一个问题是,不是将我的文本作为原始HTML插入光标位置,而是关闭当前格式化HTML标记,然后在HTML周围重新打开新标记。为了澄清,我实际上并没有插入任何类型的HTML字符串,只是文本。这是一个例子:
原始HTML:
<font size="2">Walk the dog</font>
如果我的光标位于“d”之后,并且我调用了insertHTML(“ASDF”),那么我生成的html将是:
<font size="2">Walk the d</font>ASDF<font size="2">og</font>
有没有办法可以避免这种格式转义?我需要将文本格式化为与周围文本相同的格式。当用户手动输入文本时,它会正确执行此操作。我需要在脚本中做同样的事情。
我不熟悉GWT中的原生javascript编码,但我想可能有一种简单的方法可以使用本机方法实现这一点。关于如何实现这一点的任何想法将不胜感激。我显然可以对HTML进行一些后处理以删除标签,但我想避免这种情况。
答案 0 :(得分:1)
因此,在我发布赏金之后,我想到了一个非理想但有力的方法。
我意识到在调用insertHtml之前和之后我都有完整的HTML。使用这两个HTML字符串,我可以安全地识别通过我的insertHtml调用插入的HTML块。因此,我可以轻松删除插入的HTML,并将其替换为原始文本。这是我的代码片段,以便在不清楚的情况下执行此操作。
String originalHtml = richTextArea.getHTML();
richTextArea.getFormatter().insertHTML(text);
String newHtml = richTextArea.getHTML();
int origLength = originalHtml.length();
int newLength = newHtml.length();
int startPos = -1;
int endPos = -1;
for (int i = 0; i < origLength; i++) {
if (originalHtml.charAt(i) != newHtml.charAt(i)) {
startPos = i;
break;
}
}
for (int i = 0; i < origLength; i++) {
if (originalHtml.charAt(origLength - i - 1) != newHtml.charAt(newLength - i - 1)) {
endPos = newLength - i;
break;
}
}
String finalHtml = newHtml.substring(0, startPos) + text + newHtml.substring(endPos);
richTextArea.setHTML(finalHtml);
所以这不是最干净的解决方案,但据我所知,它应该始终有效。当只需要一个插入算法时,我在RichTextArea上调用getHTML,insertHTML,getHTML和setHTML。如果有人提出更好的解决方案,我仍然更喜欢直接的解决方案。
答案 1 :(得分:1)
免责声明:我不是JavaScript专家,我的回答可能不适用于所有浏览器。请随意指出任何错误或方法来改进我的答案,使其适用于所有浏览器。
RichTextArea.getFormatter().insertHTML()
方法调用executeCommand("insertHTML", ...)
JavaScript方法,据我所知,该方法在打破父级格式的同时在当前位置创建子节点。因此,任何insertHTML
方法都不会提供所需的行为。
相反,您应该获取包含当前位置的文本对象,并使用 insertData(pos, text)
插入新文本。这可以通过扩展RichTextArea
类并添加JSNI方法轻松完成。
<小时/> 在以下示例中,我扩展了
RichTextArea
类并添加了以下JSNI方法:
public class CustomRichTextArea extends RichTextArea {
public native void insertText(String text, int pos) /*-{
var elem = this.@com.google.gwt.user.client.ui.UIObject::getElement()();
var refNode = elem.contentWindow.getSelection().getRangeAt(0).endContainer;
refNode.insertData(pos, text);
}-*/;
}
insertText
方法获取与当前选择关联的文本对象,然后将文本插入该文本对象中的指定位置。此代码提供了您想要的行为,但我仅在Chrome中对此进行了测试
此外,可以通过自动查找当前位置来改进此方法 - 获取RichTextArea的当前位置是completely different topic。
我使用以下入口点测试了上面的代码:
private CustomRichTextArea crta;
public void onModuleLoad() {
crta = new CustomRichTextArea();
crta.ensureDebugId("cwRichText-area");
crta.setSize("100%", "14em");
RichTextToolbar toolbar = new RichTextToolbar(crta);
toolbar.ensureDebugId("cwRichText-toolbar");
toolbar.setWidth("100%");
Button b = new Button();
b.setText("Insert HTML");
b.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
crta.setFocus(true);
crta.insertText("ASDF", ((int)crta.getText().length() / 2));
}
});
Grid grid = new Grid(2, 1);
grid.setStyleName("cw-RichText");
grid.setWidget(0, 0, toolbar);
grid.setWidget(1, 0, crta);
// display:
RootPanel.get().add(grid);
RootPanel.get().add(b);
}
我从GoogleCode上的项目中获得了RichTextToolbar。