GWT: помещение необработанного HTML-кода внутри метки

#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. Мне это кажется излишним. Есть ли другой способ?