001package Torello.CSS;
002
003import java.util.Vector;
004
005import Torello.Java.Additional.ByRef;
006
007import java.util.stream.IntStream;
008import java.util.function.Consumer;
009
010/**
011 * It has been patently decided that neither {@code 'BadStr'} nor {@code 'BadURL'} will have
012 * constructors.
013 */
014@Torello.JavaDoc.JDHeaderBackgroundImg(EmbedTagFileID="CSS_TOK")
015public class BadURL extends CSSToken
016    implements CharSequence, java.io.Serializable, Comparable<CharSequence>
017{
018    /** <EMBED CLASS='external-html' DATA-FILE-ID=SVUID> */
019    protected static final long serialVersionUID = 1;
020
021
022    // ********************************************************************************************
023    // ********************************************************************************************
024    // Private Constructor, API "is" and "if" Methods
025    // ********************************************************************************************
026    // ********************************************************************************************
027
028
029    BadURL(final int[] css, final int sPos, final int ePos)
030    { super(css, sPos, ePos); }
031
032    @Override 
033    public final boolean isBadURL () { return true; }
034
035    @Override
036    public final BadURL ifBadURL () { return this; }
037
038
039    // ********************************************************************************************
040    // ********************************************************************************************
041    // CONSUME
042    // ********************************************************************************************
043    // ********************************************************************************************
044
045
046    // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
047    // Copied from: 
048    // https://drafts.csswg.org/css-syntax-3/#consume-the-remnants-of-a-bad-url
049    // April 2024
050    // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
051    // 
052    // 4.3.15. Consume the remnants of a bad url
053    // 
054    // This section describes how to consume the remnants of a bad url from a stream of code
055    // points, "cleaning up" after the tokenizer realizes that it’s in the middle of a
056    // <bad-url-token> rather than a <url-token>. It returns nothing; its sole use is to consume
057    // enough of the input stream to reach a recovery point where normal tokenizing can resume.
058    // 
059    // Repeatedly consume the next input code point from the stream:
060    // 
061    // **   U+0029 RIGHT PARENTHESIS ())
062    //      EOF
063    //      ==> Return.
064    // 
065    // **   the input stream starts with a valid escape
066    //      ==> Consume an escaped code point. This allows an escaped right parenthesis ("\)") to
067    //          be encountered without ending the <bad-url-token>. This is otherwise identical to
068    //          the "anything else" clause.
069    // 
070    // **   anything else
071    //      Do nothing.
072
073    /**
074     * This is a tokenizer method which <B>"consumes"</B> the next {@code BadURL}-Token from the
075     * input Code-Point Array.
076     * 
077     * <EMBED CLASS=defs DATA-TOK=BadURL-Token DATA-URL=consume-the-remnants-of-a-bad-url
078     *  DATA-OP=Consume>
079     * <EMBED CLASS=external-html DATA-FILE-ID=COPIED_CSS_WG>
080     * <EMBED CLASS=external-html DATA-FILE-ID=BAD_URL_TOKEN>
081     */
082    protected static void consume(                          // When invoked from 'CSSTokenizer'
083            final int[]                 css,                // C, int[] css
084            final ByRef<Integer>        POS,                // P, array-pos loop-variable
085            final Consumer<CSSToken>    returnParsedToken,  // T, Vector<CSSToken>.add
086            final int                   sPos
087        )
088    {
089        int pos;
090        for (pos=sPos; pos < css.length; pos++)
091
092            if (css[pos] == ')')
093                { pos++; break; }
094
095            else if ((css[pos] == '\\') && ((pos+1) < css.length) && (css[pos+1] == ')'))
096                pos++;
097
098        returnParsedToken.accept(new BadURL(css, sPos, pos));
099        POS.f = pos;
100    }
101}