@@ -168,6 +168,15 @@ public class HtmlPolicyBuilder {
168168 public static final ImmutableSet <String > DEFAULT_SKIP_IF_EMPTY
169169 = ImmutableSet .of ("a" , "font" , "img" , "input" , "span" );
170170
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+
171180 /**
172181 * These
173182 * <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Link_types"
@@ -190,8 +199,7 @@ public class HtmlPolicyBuilder {
190199 private final Map <String , AttributePolicy > globalAttrPolicies
191200 = Maps .newLinkedHashMap ();
192201 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 );
195203 private final Map <String , Boolean > textContainers = Maps .newLinkedHashMap ();
196204 private HtmlStreamEventProcessor postprocessor =
197205 HtmlStreamEventProcessor .Processors .IDENTITY ;
@@ -307,29 +315,29 @@ public HtmlPolicyBuilder disallowTextIn(String... elementNames) {
307315 * Assuming the given elements are allowed, allows them to appear without
308316 * attributes.
309317 *
310- * @see #DEFAULT_SKIP_IF_EMPTY
318+ * @see #DEFAULT_SKIP_TAG_MAP_IF_EMPTY_ATTR
311319 * @see #disallowWithoutAttributes
312320 */
313321 public HtmlPolicyBuilder allowWithoutAttributes (String ... elementNames ) {
314322 invalidateCompiledState ();
315323 for (String elementName : elementNames ) {
316324 elementName = HtmlLexer .canonicalName (elementName );
317- skipIfEmpty . remove (elementName );
325+ skipIssueTagMap . put (elementName , HtmlTagSkipType . DO_NOT_SKIP );
318326 }
319327 return this ;
320328 }
321329
322330 /**
323331 * Disallows the given elements from appearing without attributes.
324332 *
325- * @see #DEFAULT_SKIP_IF_EMPTY
333+ * @see #DEFAULT_SKIP_TAG_MAP_IF_EMPTY_ATTR
326334 * @see #allowWithoutAttributes
327335 */
328336 public HtmlPolicyBuilder disallowWithoutAttributes (String ... elementNames ) {
329337 invalidateCompiledState ();
330338 for (String elementName : elementNames ) {
331339 elementName = HtmlLexer .canonicalName (elementName );
332- skipIfEmpty . add (elementName );
340+ skipIssueTagMap . put (elementName , HtmlTagSkipType . SKIP );
333341 }
334342 return this ;
335343 }
@@ -835,13 +843,29 @@ private CompiledState compilePolicies() {
835843 elementName ,
836844 new ElementAndAttributePolicies (
837845 elementName ,
838- elPolicy , attrs .build (), skipIfEmpty .contains (elementName )));
846+ elPolicy , attrs .build (),
847+ getHtmlTagSkipType (elementName )
848+ )
849+ );
839850 }
840851 compiledState = new CompiledState (
841852 globalAttrPolicies , policiesBuilder .build ());
842853 return compiledState ;
843854 }
844855
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+
845869 /**
846870 * Builds the relationship between attributes, the values that they may have,
847871 * and the elements on which they may appear.
0 commit comments