/// <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); }
/* (non-Javadoc) * @see com.itextpdf.styledxmlparser.css.validate.ICssDataTypeValidator#isValid(java.lang.String) */ public virtual bool IsValid(String objectString) { CssQuotes quotes = CssQuotes.CreateQuotes(objectString, false); return(quotes != null); }