@@ -168,6 +168,15 @@ public class HtmlPolicyBuilder {
168
168
public static final ImmutableSet <String > DEFAULT_SKIP_IF_EMPTY
169
169
= ImmutableSet .of ("a" , "font" , "img" , "input" , "span" );
170
170
171
+ static final ImmutableMap <String , HtmlTagSkipType > DEFAULT_SKIP_TAG_MAP_IF_EMPTY_ATTR ;
172
+ static {
173
+ ImmutableMap .Builder <String , HtmlTagSkipType > b = ImmutableMap .builder ();
174
+ for (String elementName : DEFAULT_SKIP_IF_EMPTY ) {
175
+ b .put (elementName , HtmlTagSkipType .SKIP_BY_DEFAULT );
176
+ }
177
+ DEFAULT_SKIP_TAG_MAP_IF_EMPTY_ATTR = b .build ();
178
+ }
179
+
171
180
/**
172
181
* These
173
182
* <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Link_types"
@@ -190,8 +199,7 @@ public class HtmlPolicyBuilder {
190
199
private final Map <String , AttributePolicy > globalAttrPolicies
191
200
= Maps .newLinkedHashMap ();
192
201
private final Set <String > allowedProtocols = Sets .newLinkedHashSet ();
193
- private final Set <String > skipIfEmpty = Sets .newLinkedHashSet (
194
- DEFAULT_SKIP_IF_EMPTY );
202
+ private final Map <String , HtmlTagSkipType > skipIssueTagMap = Maps .newLinkedHashMap (DEFAULT_SKIP_TAG_MAP_IF_EMPTY_ATTR );
195
203
private final Map <String , Boolean > textContainers = Maps .newLinkedHashMap ();
196
204
private HtmlStreamEventProcessor postprocessor =
197
205
HtmlStreamEventProcessor .Processors .IDENTITY ;
@@ -307,29 +315,29 @@ public HtmlPolicyBuilder disallowTextIn(String... elementNames) {
307
315
* Assuming the given elements are allowed, allows them to appear without
308
316
* attributes.
309
317
*
310
- * @see #DEFAULT_SKIP_IF_EMPTY
318
+ * @see #DEFAULT_SKIP_TAG_MAP_IF_EMPTY_ATTR
311
319
* @see #disallowWithoutAttributes
312
320
*/
313
321
public HtmlPolicyBuilder allowWithoutAttributes (String ... elementNames ) {
314
322
invalidateCompiledState ();
315
323
for (String elementName : elementNames ) {
316
324
elementName = HtmlLexer .canonicalName (elementName );
317
- skipIfEmpty . remove (elementName );
325
+ skipIssueTagMap . put (elementName , HtmlTagSkipType . DO_NOT_SKIP );
318
326
}
319
327
return this ;
320
328
}
321
329
322
330
/**
323
331
* Disallows the given elements from appearing without attributes.
324
332
*
325
- * @see #DEFAULT_SKIP_IF_EMPTY
333
+ * @see #DEFAULT_SKIP_TAG_MAP_IF_EMPTY_ATTR
326
334
* @see #allowWithoutAttributes
327
335
*/
328
336
public HtmlPolicyBuilder disallowWithoutAttributes (String ... elementNames ) {
329
337
invalidateCompiledState ();
330
338
for (String elementName : elementNames ) {
331
339
elementName = HtmlLexer .canonicalName (elementName );
332
- skipIfEmpty . add (elementName );
340
+ skipIssueTagMap . put (elementName , HtmlTagSkipType . SKIP );
333
341
}
334
342
return this ;
335
343
}
@@ -835,13 +843,29 @@ private CompiledState compilePolicies() {
835
843
elementName ,
836
844
new ElementAndAttributePolicies (
837
845
elementName ,
838
- elPolicy , attrs .build (), skipIfEmpty .contains (elementName )));
846
+ elPolicy , attrs .build (),
847
+ getHtmlTagSkipType (elementName )
848
+ )
849
+ );
839
850
}
840
851
compiledState = new CompiledState (
841
852
globalAttrPolicies , policiesBuilder .build ());
842
853
return compiledState ;
843
854
}
844
855
856
+ private HtmlTagSkipType getHtmlTagSkipType (String elementName ) {
857
+ HtmlTagSkipType htmlTagSkipType = skipIssueTagMap .get (elementName );
858
+ if (htmlTagSkipType == null ) {
859
+ if (DEFAULT_SKIP_TAG_MAP_IF_EMPTY_ATTR .containsKey (elementName )) {
860
+ return HtmlTagSkipType .SKIP_BY_DEFAULT ;
861
+ } else {
862
+ return HtmlTagSkipType .DO_NOT_SKIP_BY_DEFAULT ;
863
+ }
864
+ }
865
+
866
+ return htmlTagSkipType ;
867
+ }
868
+
845
869
/**
846
870
* Builds the relationship between attributes, the values that they may have,
847
871
* and the elements on which they may appear.
0 commit comments