Пример #1
0
        private void CollectCssDeclarations(INode rootNode, ResourceResolver resourceResolver)
        {
            this.css = new CssStyleSheet();
            LinkedList <INode> q = new LinkedList <INode>();

            if (rootNode != null)
            {
                q.Add(rootNode);
            }
            while (!q.IsEmpty())
            {
                INode currentNode = q.JRemoveFirst();
                if (currentNode is IElementNode)
                {
                    IElementNode headChildElement = (IElementNode)currentNode;
                    if (SvgConstants.Tags.STYLE.Equals(headChildElement.Name()))
                    {
                        //XML parser will parse style tag contents as text nodes
                        if (!currentNode.ChildNodes().IsEmpty() && (currentNode.ChildNodes()[0] is IDataNode || currentNode.ChildNodes
                                                                        ()[0] is ITextNode))
                        {
                            String styleData;
                            if (currentNode.ChildNodes()[0] is IDataNode)
                            {
                                styleData = ((IDataNode)currentNode.ChildNodes()[0]).GetWholeData();
                            }
                            else
                            {
                                styleData = ((ITextNode)currentNode.ChildNodes()[0]).WholeText();
                            }
                            CssStyleSheet styleSheet = CssStyleSheetParser.Parse(styleData);
                            //TODO (DEVSIX-2263): media query wrap
                            //styleSheet = wrapStyleSheetInMediaQueryIfNecessary(headChildElement, styleSheet);
                            this.css.AppendCssStyleSheet(styleSheet);
                        }
                    }
                    else
                    {
                        if (SvgCssUtils.IsStyleSheetLink(headChildElement))
                        {
                            String styleSheetUri = headChildElement.GetAttribute(SvgConstants.Attributes.HREF);
                            try {
                                Stream        stream     = resourceResolver.RetrieveStyleSheet(styleSheetUri);
                                byte[]        bytes      = StreamUtil.InputStreamToArray(stream);
                                CssStyleSheet styleSheet = CssStyleSheetParser.Parse(new MemoryStream(bytes), resourceResolver.ResolveAgainstBaseUri
                                                                                         (styleSheetUri).ToExternalForm());
                                this.css.AppendCssStyleSheet(styleSheet);
                            }
                            catch (System.IO.IOException exc) {
                                ILog logger = LogManager.GetLogger(typeof(iText.Svg.Css.Impl.SvgStyleResolver));
                                logger.Error(iText.StyledXmlParser.LogMessageConstant.UNABLE_TO_PROCESS_EXTERNAL_CSS_FILE, exc);
                            }
                        }
                    }
                }
                foreach (INode child in currentNode.ChildNodes())
                {
                    if (child is IElementNode)
                    {
                        q.Add(child);
                    }
                }
            }
        }
Пример #2
0
        /* (non-Javadoc)
         * @see com.itextpdf.html2pdf.css.resolve.ICssResolver#resolveStyles(com.itextpdf.html2pdf.html.node.INode, com.itextpdf.html2pdf.css.resolve.CssContext)
         */
        private IDictionary <String, String> ResolveStyles(INode element, CssContext context)
        {
            IList <CssRuleSet> ruleSets = new List <CssRuleSet>();

            ruleSets.Add(new CssRuleSet(null, UserAgentCss.GetStyles(element)));
            if (element is IElementNode)
            {
                ruleSets.Add(new CssRuleSet(null, HtmlStylesToCssConverter.Convert((IElementNode)element)));
            }
            ruleSets.AddAll(cssStyleSheet.GetCssRuleSets(element, deviceDescription));
            if (element is IElementNode)
            {
                String styleAttribute = ((IElementNode)element).GetAttribute(AttributeConstants.STYLE);
                if (styleAttribute != null)
                {
                    ruleSets.Add(new CssRuleSet(null, CssRuleSetParser.ParsePropertyDeclarations(styleAttribute)));
                }
            }
            IDictionary <String, String> elementStyles = CssStyleSheet.ExtractStylesFromRuleSets(ruleSets);

            if (CssConstants.CURRENTCOLOR.Equals(elementStyles.Get(CssConstants.COLOR)))
            {
                // css-color-3/#currentcolor:
                // If the ‘currentColor’ keyword is set on the ‘color’ property itself, it is treated as ‘color: inherit’.
                elementStyles.Put(CssConstants.COLOR, CssConstants.INHERIT);
            }
            String parentFontSizeStr = null;

            if (element.ParentNode() is IStylesContainer)
            {
                IStylesContainer             parentNode   = (IStylesContainer)element.ParentNode();
                IDictionary <String, String> parentStyles = parentNode.GetStyles();
                if (parentStyles == null && !(element.ParentNode() is IDocumentNode))
                {
                    ILog logger = LogManager.GetLogger(typeof(iText.Html2pdf.Css.Resolve.DefaultCssResolver));
                    logger.Error(iText.Html2pdf.LogMessageConstant.ERROR_RESOLVING_PARENT_STYLES);
                }
                if (parentStyles != null)
                {
                    foreach (KeyValuePair <String, String> entry in parentStyles)
                    {
                        MergeParentCssDeclaration(elementStyles, entry.Key, entry.Value, parentStyles);
                    }
                    parentFontSizeStr = parentStyles.Get(CssConstants.FONT_SIZE);
                }
            }
            String elementFontSize = elementStyles.Get(CssConstants.FONT_SIZE);

            if (CssUtils.IsRelativeValue(elementFontSize) || CssConstants.LARGER.Equals(elementFontSize) || CssConstants
                .SMALLER.Equals(elementFontSize))
            {
                float baseFontSize;
                if (CssUtils.IsRemValue(elementFontSize))
                {
                    baseFontSize = context.GetRootFontSize();
                }
                else
                {
                    if (parentFontSizeStr == null)
                    {
                        baseFontSize = FontStyleApplierUtil.ParseAbsoluteFontSize(CssDefaults.GetDefaultValue(CssConstants.FONT_SIZE
                                                                                                              ));
                    }
                    else
                    {
                        baseFontSize = CssUtils.ParseAbsoluteLength(parentFontSizeStr);
                    }
                }
                float absoluteFontSize = FontStyleApplierUtil.ParseRelativeFontSize(elementFontSize, baseFontSize);
                // Format to 4 decimal places to prevent differences between Java and C#
                elementStyles.Put(CssConstants.FONT_SIZE, DecimalFormatUtil.FormatNumber(absoluteFontSize, "0.####") + CssConstants
                                  .PT);
            }
            else
            {
                elementStyles.Put(CssConstants.FONT_SIZE, Convert.ToString(FontStyleApplierUtil.ParseAbsoluteFontSize(elementFontSize
                                                                                                                      ), System.Globalization.CultureInfo.InvariantCulture) + CssConstants.PT);
            }
            // Update root font size
            if (element is IElementNode && TagConstants.HTML.Equals(((IElementNode)element).Name()))
            {
                context.SetRootFontSize(elementStyles.Get(CssConstants.FONT_SIZE));
            }
            ICollection <String> keys = new HashSet <String>();

            foreach (KeyValuePair <String, String> entry in elementStyles)
            {
                if (CssConstants.INITIAL.Equals(entry.Value) || CssConstants.INHERIT.Equals(entry.Value))
                {
                    // if "inherit" is not resolved till now, parents don't have it
                    keys.Add(entry.Key);
                }
            }
            foreach (String key in keys)
            {
                elementStyles.Put(key, CssDefaults.GetDefaultValue(key));
            }
            // This is needed for correct resolving of content property, so doing it right here
            CounterProcessorUtil.ProcessCounters(elementStyles, context, element);
            ResolveContentProperty(elementStyles, element, context);
            return(elementStyles);
        }
Пример #3
0
        /// <summary>
        /// Wraps a
        /// <see cref="iText.StyledXmlParser.Css.Media.CssMediaRule"/>
        /// into the style sheet if the head child element has a media attribute.
        /// </summary>
        /// <param name="headChildElement">the head child element</param>
        /// <param name="styleSheet">the style sheet</param>
        /// <returns>the css style sheet</returns>
        private CssStyleSheet WrapStyleSheetInMediaQueryIfNecessary(IElementNode headChildElement, CssStyleSheet styleSheet
                                                                    )
        {
            String mediaAttribute = headChildElement.GetAttribute(AttributeConstants.MEDIA);

            if (mediaAttribute != null && mediaAttribute.Length > 0)
            {
                CssMediaRule mediaRule = new CssMediaRule(mediaAttribute);
                mediaRule.AddStatementsToBody(styleSheet.GetStatements());
                styleSheet = new CssStyleSheet();
                styleSheet.AddStatement(mediaRule);
            }
            return(styleSheet);
        }
Пример #4
0
 /// <summary>
 /// Creates a
 /// <see cref="SvgStyleResolver"/>
 /// with a given default CSS.
 /// </summary>
 /// <param name="defaultCssStream">the default CSS</param>
 public SvgStyleResolver(Stream defaultCssStream)
 {
     this.css = CssStyleSheetParser.Parse(defaultCssStream);
 }
Пример #5
0
 internal CssRule(CssStyleSheet parentStyleSheet)
 {
     ParentStyleSheet = parentStyleSheet;
 }
Пример #6
0
        public virtual void PagesInCountersSpacesPresenceTest()
        {
            CssStyleSheet styleSheet = CssStyleSheetParser.Parse(".x::before { content: counters( pages,'.') }");

            NUnit.Framework.Assert.IsTrue(CssStyleSheetAnalyzer.CheckPagesCounterPresence(styleSheet));
        }
Пример #7
0
        public virtual void CounterWithoutPagesTest()
        {
            CssStyleSheet styleSheet = CssStyleSheetParser.Parse(".x::before { content: counter(othercounter) }");

            NUnit.Framework.Assert.IsFalse(CssStyleSheetAnalyzer.CheckPagesCounterPresence(styleSheet));
        }
Пример #8
0
        /// <summary>
        /// Takes a text source and transforms it into a CSS sheet.
        /// </summary>
        internal ICssStyleSheet ParseStylesheet(TextSource source)
        {
            var sheet = new CssStyleSheet(this);

            return(ParseStylesheet(sheet, source));
        }
Пример #9
0
        public virtual void SimpleNegativeTest()
        {
            CssStyleSheet styleSheet = CssStyleSheetParser.Parse("* { color: red; }");

            NUnit.Framework.Assert.IsFalse(CssStyleSheetAnalyzer.CheckPagesCounterPresence(styleSheet));
        }
 /// <summary>Helper method to check if non-page(s) target-counter(s) is present anywhere in the CSS.</summary>
 /// <remarks>
 /// Helper method to check if non-page(s) target-counter(s) is present anywhere in the CSS.
 /// If presence is detected, it may require additional treatment
 /// </remarks>
 /// <param name="styleSheet">CSS stylesheet to analyze</param>
 /// <returns>
 /// <c>true</c> in case any non-page(s) target-counter(s) are present in CSS declarations,
 /// or <c>false</c> otherwise
 /// </returns>
 public static bool CheckNonPagesTargetCounterPresence(CssStyleSheet styleSheet)
 {
     return(CheckNonPagesTargetCounterPresence(styleSheet.GetStatements()));
 }
 public void AddCssStyleSheet(CssStyleSheet ss)
 {
     styleSheets.Add(ss);
 }
Пример #12
0
 internal virtual void SetStyleSheet(CssStyleSheet aSheet)
 {
     mSheet = aSheet;
 }
Пример #13
0
        public virtual void SrcPropertyTest()
        {
            String        fontSrc    = "web-fonts/droid-serif-invalid.";
            CssStyleSheet styleSheet = CssStyleSheetParser.Parse(new FileStream(sourceFolder + "srcs.css", FileMode.Open
                                                                                , FileAccess.Read));
            CssFontFaceRule fontFaceRule = (CssFontFaceRule)styleSheet.GetStatements()[0];
            CssDeclaration  src          = fontFaceRule.GetProperties()[0];

            NUnit.Framework.Assert.AreEqual("src", src.GetProperty(), "src expected");
            String[] sources = iText.IO.Util.StringUtil.Split(src.GetExpression(), ",");
            NUnit.Framework.Assert.AreEqual(27, sources.Length, "27 sources expected");
            for (int i = 0; i < sources.Length; i++)
            {
                Match m = iText.IO.Util.StringUtil.Match(FontFace.FontFaceSrc.UrlPattern, sources[i]);
                NUnit.Framework.Assert.IsTrue(m.Success, "Expression doesn't match pattern: " + sources[i]);
                String format  = iText.IO.Util.StringUtil.Group(m, FontFace.FontFaceSrc.FormatGroup);
                String source2 = MessageFormatUtil.Format("{0}({1}){2}", iText.IO.Util.StringUtil.Group(m, FontFace.FontFaceSrc
                                                                                                        .TypeGroup), iText.IO.Util.StringUtil.Group(m, FontFace.FontFaceSrc.UrlGroup), format != null ? MessageFormatUtil
                                                          .Format(" format({0})", format) : "");
                String url = FontFace.FontFaceSrc.Unquote(iText.IO.Util.StringUtil.Group(m, FontFace.FontFaceSrc.UrlGroup)
                                                          );
                NUnit.Framework.Assert.IsTrue(url.StartsWith(fontSrc), "Invalid url: " + url);
                NUnit.Framework.Assert.IsTrue(format == null || FontFace.FontFaceSrc.ParseFormat(format) != FontFace.FontFormat
                                              .None, "Invalid format: " + format);
                NUnit.Framework.Assert.AreEqual(sources[i], source2, "Group check fails: ");
                FontFace.FontFaceSrc fontFaceSrc = FontFace.FontFaceSrc.Create(sources[i]);
                NUnit.Framework.Assert.IsTrue(fontFaceSrc.src.StartsWith(fontSrc), "Invalid url: " + fontSrc);
                String type = "url";
                if (fontFaceSrc.isLocal)
                {
                    type = "local";
                }
                NUnit.Framework.Assert.IsTrue(sources[i].StartsWith(type), "Type '" + type + "' expected: " + sources[i]);
                switch (fontFaceSrc.format)
                {
                case FontFace.FontFormat.OpenType: {
                    NUnit.Framework.Assert.IsTrue(sources[i].Contains("opentype"), "Format " + fontFaceSrc.format + " expected: "
                                                  + sources[i]);
                    break;
                }

                case FontFace.FontFormat.TrueType: {
                    NUnit.Framework.Assert.IsTrue(sources[i].Contains("truetype"), "Format " + fontFaceSrc.format + " expected: "
                                                  + sources[i]);
                    break;
                }

                case FontFace.FontFormat.SVG: {
                    NUnit.Framework.Assert.IsTrue(sources[i].Contains("svg"), "Format " + fontFaceSrc.format + " expected: " +
                                                  sources[i]);
                    break;
                }

                case FontFace.FontFormat.None: {
                    NUnit.Framework.Assert.IsFalse(sources[i].Contains("format("), "Format " + fontFaceSrc.format + " expected: "
                                                   + sources[i]);
                    break;
                }
                }
            }
        }
        /** -------------------------------------------------------------------- **/

        private async Task _ProcessCssPage()
        {
            MacroscopeHttpTwoClient         Client   = this.DocCollection.GetJobMaster().GetHttpClient();
            MacroscopeHttpTwoClientResponse Response = null;
            string ResponseErrorCondition            = null;

            DebugMsg(string.Format("ProcessCssPage: {0}", ""));

            try
            {
                Response = await Client.Get(
                    this.GetUri(),
                    this.ConfigureCssPageRequestHeadersCallback,
                    this.PostProcessRequestHttpHeadersCallback
                    );
            }
            catch (MacroscopeDocumentException ex)
            {
                this.DebugMsg(string.Format("_ProcessCssPage :: MacroscopeDocumentException: {0}", ex.Message));
                ResponseErrorCondition = ex.Message;
                this.SetStatusCode(HttpStatusCode.BadRequest);
                this.AddRemark("_ProcessCssPage", ex.Message);
            }
            catch (Exception ex)
            {
                this.DebugMsg(string.Format("_ProcessCssPage :: Exception: {0}", ex.Message));
                ResponseErrorCondition = ex.Message;
                this.SetStatusCode(HttpStatusCode.BadRequest);
                this.AddRemark("_ProcessCssPage", ex.Message);
            }

            /** Set Base URL ----------------------------------------------------- **/
            if (Response != null)
            {
                Uri    CssUri       = this.GetUri();
                string CssLocalPath = CssUri.LocalPath;
                string CssPath      = System.IO.Path.GetDirectoryName(CssLocalPath);
                Uri    NewCssUri    = new Uri(new UriBuilder(scheme: CssUri.Scheme, host: CssUri.Host, port: CssUri.Port, pathValue: CssPath).ToString());
                this.SetBaseHref(NewCssUri.ToString());
            }

            /** Process The Response Body ---------------------------------------- **/

            if (Response != null)
            {
                string RawData = "";

                this.ProcessResponseHttpHeaders(Response: Response);

                /** Get Response Body ---------------------------------------------- **/

                try
                {
                    DebugMsg(string.Format("MIME TYPE: {0}", this.MimeType));

                    RawData = Response.GetContentAsString();

                    this.SetContentLength(Length: RawData.Length); // May need to find bytes length

                    this.SetWasDownloaded(true);
                }
                catch (Exception ex)
                {
                    DebugMsg(string.Format("Exception: {0}", ex.Message));
                    this.SetStatusCode(HttpStatusCode.Ambiguous);
                    this.SetContentLength(Length: 0);
                }

                if (!string.IsNullOrEmpty(RawData))
                {
                    try
                    {
                        CssLoader     Parser     = new CssLoader();
                        CssStyleSheet Stylesheet = Parser.ParseSheet(RawData, this.GetUri(), this.GetUri());
                        this.ProcessCssOutlinks(Stylesheet: Stylesheet);
                    }
                    catch (Exception ex)
                    {
                        this.DebugMsg(string.Format("ProcessHtmlAttributeCssLinks: {0}", ex.Message));
                        this.AddRemark("ProcessHtmlAttributeCssLinks", ex.Message);
                    }
                }
                else
                {
                    DebugMsg(string.Format("ProcessCssPage: ERROR: {0}", this.GetUrl()));
                }

                /** Custom Filters ------------------------------------------------- **/

                if (!string.IsNullOrEmpty(RawData))
                {
                    if (
                        MacroscopePreferencesManager.GetCustomFiltersEnable() &&
                        MacroscopePreferencesManager.GetCustomFiltersApplyToCss())
                    {
                        MacroscopeCustomFilters CustomFilter = this.DocCollection.GetJobMaster().GetCustomFilter();

                        if ((CustomFilter != null) && (CustomFilter.IsEnabled()))
                        {
                            this.ProcessGenericCustomFiltered(
                                CustomFilter: CustomFilter,
                                GenericText: RawData
                                );
                        }
                    }
                }

                /** Data Extractors ------------------------------------------------ **/

                if (!string.IsNullOrEmpty(RawData))
                {
                    if (
                        MacroscopePreferencesManager.GetDataExtractorsEnable() &&
                        MacroscopePreferencesManager.GetDataExtractorsApplyToCss())
                    {
                        this.ProcessGenericDataExtractors(GenericText: RawData);
                    }
                }

                /** Title ---------------------------------------------------------- **/

                {
                    MatchCollection reMatches     = Regex.Matches(this.DocUrl, "/([^/]+)$");
                    string          DocumentTitle = null;
                    foreach (Match match in reMatches)
                    {
                        if (match.Groups[1].Value.Length > 0)
                        {
                            DocumentTitle = match.Groups[1].Value.ToString();
                            break;
                        }
                    }
                    if (DocumentTitle != null)
                    {
                        this.SetTitle(DocumentTitle, MacroscopeConstants.TextProcessingMode.NO_PROCESSING);
                        DebugMsg(string.Format("TITLE: {0}", this.GetTitle()));
                    }
                    else
                    {
                        DebugMsg(string.Format("TITLE: {0}", "MISSING"));
                    }
                }
            }

            if (ResponseErrorCondition != null)
            {
                this.ProcessErrorCondition(ResponseErrorCondition);
            }
        }
        /**************************************************************************/

        private void ProcessCssOutlinks(CssStyleSheet Stylesheet)
        {
            // https://github.com/Athari/CsCss

            // https://developer.mozilla.org/en-US/docs/Web/CSS/url

            List <string> BackgroundImageUrls = null;

            if (this.GetIsExternal())
            {
                return;
            }

            try
            {
                BackgroundImageUrls = Stylesheet.AllStyleRules
                                      .Where(StyleRule => StyleRule.Declaration.BackgroundImage != null)
                                      .SelectMany(StyleRule => StyleRule.Declaration.AllData)
                                      .SelectMany(Property => Property.Value.Unit == CssUnit.List ? Property.Value.List : new[] { Property.Value })
                                      .Where(Value => Value.Unit == CssUnit.Url)
                                      .Select(Value => Value.OriginalUri)
                                      .ToList();
            }
            catch (Exception ex)
            {
                DebugMsg(string.Format("ProcessCssOutlinks: {0}", ex.Message));
            }

            if (BackgroundImageUrls != null)
            {
                foreach (string BackgroundImageUrl in BackgroundImageUrls)
                {
                    string LinkUrlAbs = this.ProcessCssBackgroundImageUrl(BackgroundImageUrl);

                    DebugMsg(string.Format("ProcessCssOutlinks: (background-image): {0}", BackgroundImageUrl));
                    DebugMsg(string.Format("ProcessCssOutlinks: (background-image): {0}", LinkUrlAbs));

                    if (LinkUrlAbs != null)
                    {
                        MacroscopeHyperlinkOut HyperlinkOut = null;
                        MacroscopeLink         Outlink      = null;

                        HyperlinkOut = this.HyperlinksOut.Add(
                            LinkType: MacroscopeConstants.HyperlinkType.CSS,
                            UrlTarget: LinkUrlAbs
                            );

                        Outlink = this.AddDocumentOutlink(
                            AbsoluteUrl: LinkUrlAbs,
                            LinkType: MacroscopeConstants.InOutLinkType.IMAGE,
                            Follow: true
                            );

                        if (Outlink != null)
                        {
                            Outlink.SetRawTargetUrl(BackgroundImageUrl);
                        }
                    }
                }
            }

            return;
        }
Пример #16
0
 /// <summary>
 /// Creates a
 /// <see cref="SvgStyleResolver"/>
 /// with a given default CSS.
 /// </summary>
 /// <param name="defaultCssStream">the default CSS</param>
 /// <param name="context">the processor context</param>
 public SvgStyleResolver(Stream defaultCssStream, SvgProcessorContext context)
 {
     this.css = CssStyleSheetParser.Parse(defaultCssStream);
     this.resourceResolver = context.GetResourceResolver();
 }