Example #1
0
        /// <summary>Processes counters.</summary>
        /// <param name="cssProps">the CSS properties</param>
        /// <param name="context">the processor context</param>
        /// <param name="scope">the scope</param>
        public static void ProcessCounters(IDictionary <String, String> cssProps, CssContext context, INode scope)
        {
            String counterReset = cssProps.Get(CssConstants.COUNTER_RESET);

            if (counterReset != null)
            {
                CssCounterManager counterManager = context.GetCounterManager();
                String[]          @params        = iText.IO.Util.StringUtil.Split(counterReset, " ");
                for (int i = 0; i < @params.Length; i++)
                {
                    String counterName = @params[i];
                    int?   possibleCounterValue;
                    if (i + 1 < @params.Length && (possibleCounterValue = CssUtils.ParseInteger(@params[i + 1])) != null)
                    {
                        counterManager.ResetCounter(counterName, (int)possibleCounterValue, scope);
                        i++;
                    }
                    else
                    {
                        counterManager.ResetCounter(counterName, scope);
                    }
                }
            }
            String counterIncrement = cssProps.Get(CssConstants.COUNTER_INCREMENT);

            if (counterIncrement != null)
            {
                CssCounterManager counterManager = context.GetCounterManager();
                String[]          @params        = iText.IO.Util.StringUtil.Split(counterIncrement, " ");
                for (int i = 0; i < @params.Length; i++)
                {
                    String counterName = @params[i];
                    int?   possibleIncrementValue;
                    if (i + 1 < @params.Length && (possibleIncrementValue = CssUtils.ParseInteger(@params[i + 1])) != null)
                    {
                        counterManager.IncrementCounter(counterName, (int)possibleIncrementValue, scope);
                        i++;
                    }
                    else
                    {
                        counterManager.IncrementCounter(counterName, scope);
                    }
                }
            }
        }
 private static void ProcessIncrement(String counterIncrement, CssContext context)
 {
     if (counterIncrement != null)
     {
         CssCounterManager counterManager = context.GetCounterManager();
         String[]          @params        = iText.IO.Util.StringUtil.Split(counterIncrement, " ");
         for (int i = 0; i < @params.Length; i++)
         {
             String counterName = @params[i];
             int?   possibleIncrementValue;
             if (i + 1 < @params.Length && (possibleIncrementValue = CssDimensionParsingUtils.ParseInteger(@params[i +
                                                                                                                   1])) != null)
             {
                 counterManager.IncrementCounter(counterName, (int)possibleIncrementValue);
                 i++;
             }
             else
             {
                 counterManager.IncrementCounter(counterName);
             }
         }
     }
 }
Example #3
0
        /// <summary>Resolves content.</summary>
        /// <param name="styles">the styles map</param>
        /// <param name="contentContainer">the content container</param>
        /// <param name="context">the CSS context</param>
        /// <returns>
        /// a list of
        /// <see cref="iText.StyledXmlParser.Node.INode"/>
        /// instances
        /// </returns>
        internal static IList <INode> ResolveContent(IDictionary <String, String> styles, INode contentContainer, CssContext
                                                     context)
        {
            String        contentStr = styles.Get(CssConstants.CONTENT);
            IList <INode> result     = new List <INode>();

            if (contentStr == null || CssConstants.NONE.Equals(contentStr) || CssConstants.NORMAL.Equals(contentStr))
            {
                return(null);
            }
            CssDeclarationValueTokenizer tokenizer = new CssDeclarationValueTokenizer(contentStr);

            CssDeclarationValueTokenizer.Token token;
            CssQuotes quotes = null;

            while ((token = tokenizer.GetNextValidToken()) != null)
            {
                if (token.IsString())
                {
                    result.Add(new CssContentPropertyResolver.ContentTextNode(contentContainer, token.GetValue()));
                }
                else
                {
                    if (token.GetValue().StartsWith(CssConstants.COUNTERS + "("))
                    {
                        String paramsStr = token.GetValue().JSubstring(CssConstants.COUNTERS.Length + 1, token.GetValue().Length -
                                                                       1);
                        String[] @params = iText.IO.Util.StringUtil.Split(paramsStr, ",");
                        if (@params.Length == 0)
                        {
                            return(ErrorFallback(contentStr));
                        }
                        // Counters are denoted by case-sensitive identifiers
                        String counterName          = @params[0].Trim();
                        String counterSeparationStr = @params[1].Trim();
                        counterSeparationStr = counterSeparationStr.JSubstring(1, counterSeparationStr.Length - 1);
                        String            listStyleType  = @params.Length > 2 ? @params[2].Trim() : null;
                        CssCounterManager counterManager = context.GetCounterManager();
                        INode             scope          = contentContainer;
                        if (CssConstants.PAGE.Equals(counterName))
                        {
                            result.Add(new PageCountElementNode(false, contentContainer));
                        }
                        else
                        {
                            if (CssConstants.PAGES.Equals(counterName))
                            {
                                result.Add(new PageCountElementNode(true, contentContainer));
                            }
                            else
                            {
                                String resolvedCounter = counterManager.ResolveCounters(counterName, counterSeparationStr, listStyleType,
                                                                                        scope);
                                if (resolvedCounter == null)
                                {
                                    logger.Error(MessageFormatUtil.Format(iText.Html2pdf.LogMessageConstant.UNABLE_TO_RESOLVE_COUNTER, counterName
                                                                          ));
                                }
                                else
                                {
                                    result.Add(new CssContentPropertyResolver.ContentTextNode(scope, resolvedCounter));
                                }
                            }
                        }
                    }
                    else
                    {
                        if (token.GetValue().StartsWith(CssConstants.COUNTER + "("))
                        {
                            String paramsStr = token.GetValue().JSubstring(CssConstants.COUNTER.Length + 1, token.GetValue().Length -
                                                                           1);
                            String[] @params = iText.IO.Util.StringUtil.Split(paramsStr, ",");
                            if (@params.Length == 0)
                            {
                                return(ErrorFallback(contentStr));
                            }
                            // Counters are denoted by case-sensitive identifiers
                            String            counterName    = @params[0].Trim();
                            String            listStyleType  = @params.Length > 1 ? @params[1].Trim() : null;
                            CssCounterManager counterManager = context.GetCounterManager();
                            INode             scope          = contentContainer;
                            if (CssConstants.PAGE.Equals(counterName))
                            {
                                result.Add(new PageCountElementNode(false, contentContainer));
                            }
                            else
                            {
                                if (CssConstants.PAGES.Equals(counterName))
                                {
                                    result.Add(new PageCountElementNode(true, contentContainer));
                                }
                                else
                                {
                                    String resolvedCounter = counterManager.ResolveCounter(counterName, listStyleType, scope);
                                    if (resolvedCounter == null)
                                    {
                                        logger.Error(MessageFormatUtil.Format(iText.Html2pdf.LogMessageConstant.UNABLE_TO_RESOLVE_COUNTER, counterName
                                                                              ));
                                    }
                                    else
                                    {
                                        result.Add(new CssContentPropertyResolver.ContentTextNode(scope, resolvedCounter));
                                    }
                                }
                            }
                        }
                        else
                        {
                            if (token.GetValue().StartsWith("url("))
                            {
                                IDictionary <String, String> attributes = new Dictionary <String, String>();
                                attributes.Put(AttributeConstants.SRC, CssUtils.ExtractUrl(token.GetValue()));
                                //TODO: probably should add user agent styles on CssContentElementNode creation, not here.
                                attributes.Put(AttributeConstants.STYLE, CssConstants.DISPLAY + ":" + CssConstants.INLINE_BLOCK);
                                result.Add(new CssContentElementNode(contentContainer, TagConstants.IMG, attributes));
                            }
                            else
                            {
                                if (CssGradientUtil.IsCssLinearGradientValue(token.GetValue()))
                                {
                                    IDictionary <String, String> attributes = new Dictionary <String, String>();
                                    attributes.Put(AttributeConstants.STYLE, CssConstants.BACKGROUND_IMAGE + ":" + token.GetValue() + ";" + CssConstants
                                                   .HEIGHT + ":" + CssConstants.INHERIT + ";" + CssConstants.WIDTH + ":" + CssConstants.INHERIT + ";");
                                    result.Add(new CssContentElementNode(contentContainer, TagConstants.DIV, attributes));
                                }
                                else
                                {
                                    if (token.GetValue().StartsWith("attr(") && contentContainer is CssPseudoElementNode)
                                    {
                                        int endBracket = token.GetValue().IndexOf(')');
                                        if (endBracket > 5)
                                        {
                                            String attrName = token.GetValue().JSubstring(5, endBracket);
                                            if (attrName.Contains("(") || attrName.Contains(" ") || attrName.Contains("'") || attrName.Contains("\""))
                                            {
                                                return(ErrorFallback(contentStr));
                                            }
                                            IElementNode element = (IElementNode)contentContainer.ParentNode();
                                            String       value   = element.GetAttribute(attrName);
                                            result.Add(new CssContentPropertyResolver.ContentTextNode(contentContainer, value == null ? "" : value));
                                        }
                                    }
                                    else
                                    {
                                        if (token.GetValue().EndsWith("quote") && contentContainer is IStylesContainer)
                                        {
                                            if (quotes == null)
                                            {
                                                quotes = CssQuotes.CreateQuotes(styles.Get(CssConstants.QUOTES), true);
                                            }
                                            String value = quotes.ResolveQuote(token.GetValue(), context);
                                            if (value == null)
                                            {
                                                return(ErrorFallback(contentStr));
                                            }
                                            result.Add(new CssContentPropertyResolver.ContentTextNode(contentContainer, value));
                                        }
                                        else
                                        {
                                            if (token.GetValue().StartsWith(CssConstants.ELEMENT + "(") && contentContainer is PageMarginBoxContextNode
                                                )
                                            {
                                                String paramsStr = token.GetValue().JSubstring(CssConstants.ELEMENT.Length + 1, token.GetValue().Length -
                                                                                               1);
                                                String[] @params = iText.IO.Util.StringUtil.Split(paramsStr, ",");
                                                if (@params.Length == 0)
                                                {
                                                    return(ErrorFallback(contentStr));
                                                }
                                                String name = @params[0].Trim();
                                                String runningElementOccurrence = null;
                                                if (@params.Length > 1)
                                                {
                                                    runningElementOccurrence = @params[1].Trim();
                                                }
                                                result.Add(new PageMarginRunningElementNode(name, runningElementOccurrence));
                                            }
                                            else
                                            {
                                                return(ErrorFallback(contentStr));
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            return(result);
        }
        /// <summary>Ends processing counters.</summary>
        /// <remarks>
        /// Ends processing counters. Pops values of given counter list from counters if necessary.
        /// Usually it is expected that this method should be called after processing cheldren of the element.
        /// </remarks>
        /// <param name="context">the processor context</param>
        /// <param name="element">the element which counters shall be processed</param>
        public static void EndProcessingCounters(CssContext context, IElementNode element)
        {
            CssCounterManager counterManager = context.GetCounterManager();

            counterManager.PopEveryCounterFromCounters(element);
        }
        /// <summary>Starts processing counters.</summary>
        /// <remarks>
        /// Starts processing counters. Pushes current counter values to counters if necessary.
        /// Usually it is expected that this method should be called before processing children of the element.
        /// </remarks>
        /// <param name="context">the processor context</param>
        /// <param name="element">the element which counters shall be processed</param>
        public static void StartProcessingCounters(CssContext context, IElementNode element)
        {
            CssCounterManager counterManager = context.GetCounterManager();

            counterManager.PushEveryCounterToCounters(element);
        }