#java #gwt
#java #gwt
Вопрос:
Есть ли способ поместить необработанный HTML-код внутри Label
виджета с помощью GWT? Конструктор и setText()
методы автоматически экранируют текст для HTML (so <
отображается как amp;<
, и т.д.).
Что мне нужно, так это что-то вроде:
String matched = "two";
List<String> values = Arrays.asList("one", "two", "three");
StringBuilder sb = new StringBuilder();
for (String v : values){
if (v.equals(matched)){
sb.append("<b>" v "<b>");
} else {
sb.append(v);
}
sb.append(", ");
}
Label label = new Label();
label.setRawText(sb.toString());
//div contains the following HTML: "one, <b>two</b>, three, "
Я хочу вывести список строк, разделенных запятыми, но я хочу, чтобы одна из этих строк была выделена жирным шрифтом. Спасибо.
Ответ №1:
Используйте класс HTML (или, что более вероятно: класс InlineHTML вместо класса Label. InlineHTML работает как label, за исключением того, что вы можете присвоить ему html.
И просто предупреждение безопасности: если часть входных данных для вашего объекта InlineHTML вводится пользователем, не забудьте удалить html из этой части, чтобы пользователи не могли вставлять свои собственные скрипты в ваш код.
Комментарии:
1. Label ↔ HTML, InlineLabel ↔ InlineHTML. Первые — это
div
s, последниеspan
— s.2. Как мне избежать частей, которые поступают от пользователя, но не избежать
<b>
тега? Пожалуйста, посмотрите мой отредактированный вопрос с обновленным примером кода — что я должен сделать для метода «htmlEscape»?
Ответ №2:
Извините, я собираюсь ответить на свой собственный вопрос, потому что я нашел то, что искал.
SafeHtmlBuilder
Класс идеально подходит для этого. Вы сообщаете ему, какие строки вы хотите экранировать, а какие строки вы не хотите экранировать. Это работает так StringBuilder
, потому что вы вызываете append
методы:
String matched = "two";
List<String> values = Arrays.asList("one", "two", "three <escape-me>");
SafeHtmlBuilder builder = new SafeHtmlBuilder();
for (String v : values){
if (v.equals(matched)){
builder.appendHtmlConstant("<b>");
builder.appendEscaped(v);
builder.appendHtmlConstant("</b>");
} else {
builder.appendEscaped(v);
}
builder.appendEscaped(", ");
}
HTML widget = new HTML();
widget.setHTML(builder.toSafeHtml());
//div contains the following HTML: "one, <b>two</b>, three amp;<escape-meamp;>, "
Обратите внимание, что appendHtmlConstant
метод ожидает полного тега. Поэтому, если вы хотите добавить атрибуты к тегу, значения которого меняются во время выполнения, это не сработает. Например, это не сработает (оно выдает IllegalArgumentException
):
String url = //...
SafeHtmlBuilder builder = new SafeHtmlBuilder();
builder.appendHtmlConstant("<a href=""); //throws IllegalArgumentException
builder.appendEscaped(url);
builder.appendHtmlConstant("">link</a>");
Ответ №3:
Либо создайте метку и выделите ее жирным шрифтом:
Label label = new Label("text");
label.getElement().getStyle().setFontWeight(FontWeight.BOLD);
Или вы можете создать SpanElement
и установить его innerHTML.
Комментарии:
1. Но я хочу выделить жирным шрифтом только часть текста метки. Могу ли я использовать
SpanElement
для этого?2.
SpanElement
ваш текст не будет экранирован. Просто вызовитеSpanElement#setInnerHTML
3. Что, если я хочу экранировать часть текста, но оставить
<b>
теги нетронутыми? (см. Обновленный пример кода, о котором идет речь) Спасибо.
Ответ №4:
Вот пример размещения пробела в виджете, например, Label:
public void setTextNbsp( final Widget w ) {
w.getElement().setInnerHTML( "amp;nbsp;" );
}
Также можно использовать другие объекты HTML. Позаботьтесь об этом, чтобы не открыть дыры в безопасности. SafeHtml и т. Д. Могут потребовать рассмотрения, Если делать что-то более динамичное.
Ответ №5:
Я думаю, вам следует использовать SpanElement, где вы не хотите, чтобы html экранировался, и помечать, где вы хотите, чтобы затем экранировался, и помещать их на вертикальную панель, чтобы они отображались в виде одной строки текста.
Комментарии:
1. Мне это кажется излишним. Есть ли другой способ?