private Element handleDiv()

in jspwiki-main/src/main/java/org/apache/wiki/parser/JSPWikiMarkupParser.java [1441:1530]


    private Element handleDiv( ) throws IOException {
        int ch = nextToken();
        Element el = null;

        if( ch == '%' ) {
            String style = null;
            String clazz = null;

            ch = nextToken();

            //  Style or class?
            if( ch == '(' ) {
                style = readBraceContent('(',')');
            } else if( Character.isLetter( (char) ch ) ) {
                pushBack( ch );
                clazz = readUntil( "( \t\n\r" );
                //Note: ref.https://www.w3.org/TR/CSS21/syndata.html#characters
                //CSS Classnames can contain only the characters [a-zA-Z0-9] and
                //ISO 10646 characters U+00A0 and higher, plus the "-" and the "_".
                //They cannot start with a digit, two hyphens, or a hyphen followed by a digit.

                //(1) replace '.' by spaces, allowing multiple classnames on a div or span
                //(2) remove any invalid character
                if( clazz != null ) {
                    clazz = clazz.replace( '.', ' ' )
                                 .replaceAll( "[^\\s-_\\w\\x200-\\x377]+", "" );
                }
                ch = nextToken();

                // check for %%class1.class2( style information )
                if( ch == '(' ) {
                    style = readBraceContent( '(', ')' );
                //  Pop out only spaces, so that the upcoming EOL check does not check the next line.
                } else if( ch == '\n' || ch == '\r' ) {
                    pushBack( ch );
                }
            } else {
                // Anything else stops.
                pushBack( ch );
                try {
                    final Boolean isSpan = m_styleStack.pop();
                    if( isSpan == null ) {
                        // Fail quietly
                    } else if( isSpan ) {
                        el = popElement( "span" );
                    } else {
                        el = popElement( "div" );
                    }
                } catch( final EmptyStackException e ) {
                    LOG.debug( "Page '" + m_context.getName() + "' closes a %%-block that has not been opened." );
                    return m_currentElement;
                }
                return el;
            }

            //  Check if there is an attempt to do something nasty
            try {
                style = StringEscapeUtils.unescapeHtml4(style);
                if( style != null && style.contains( "javascript:" ) ) {
                    LOG.debug( "Attempt to output javascript within CSS: {}", style );
                    final ResourceBundle rb = Preferences.getBundle( m_context, InternationalizationManager.CORE_BUNDLE );
                    return addElement( makeError( rb.getString( "markupparser.error.javascriptattempt" ) ) );
                }
            } catch( final NumberFormatException e ) {
                //  If there are unknown entities, we don't want the parser to stop.
                final ResourceBundle rb = Preferences.getBundle( m_context, InternationalizationManager.CORE_BUNDLE );
                final String msg = MessageFormat.format( rb.getString( "markupparser.error.parserfailure"), e.getMessage() );
                return addElement( makeError( msg ) );
            }

            //  Decide if we should open a div or a span?
            final String eol = peekAheadLine();

            if( !eol.trim().isEmpty() ) {
                // There is stuff after the class
                el = new Element("span");
                m_styleStack.push( Boolean.TRUE );
            } else {
                startBlockLevel();
                el = new Element("div");
                m_styleStack.push( Boolean.FALSE );
            }

            if( style != null ) el.setAttribute("style", style);
            if( clazz != null ) el.setAttribute("class", clazz);
            return pushElement( el );
        }
        pushBack( ch );
        return el;
    }