Index: xword/ContentFiltering/ContentFiltering.csproj =================================================================== --- xword/ContentFiltering/ContentFiltering.csproj (revision 22406) +++ xword/ContentFiltering/ContentFiltering.csproj (working copy) @@ -90,6 +90,7 @@ + Index: xword/ContentFiltering/Html/CSSUtil.cs =================================================================== --- xword/ContentFiltering/Html/CSSUtil.cs (revision 22406) +++ xword/ContentFiltering/Html/CSSUtil.cs (working copy) @@ -87,17 +87,35 @@ continue; } properties = cssClass.Substring(firstBrace + 1).Replace('"', '\''); + + //clean whitespaces (spaces, tabs, new lines) from CSS properites + Regex whiteSpaceRegex = new Regex("\\s+", RegexOptions.Singleline | RegexOptions.Multiline); + properties = whiteSpaceRegex.Replace(properties, ""); + char[] comma = { ',' }; string[] cssNames = cssClass.Substring(0, firstBrace).Split(comma); foreach (string className in cssNames) { - //do not include the dot in the CSS class name or the pound in CSS id - classesNames.Add(className.Trim().Substring(1)); + string cname=className.Trim(); + //only if it's a CSS class name or CSS id, and does not have pseudoselectors + if ((cname.IndexOf('.') == 0 || cname.IndexOf('#') == 0) && cname.IndexOf(':')<0) + { + //do not include the dot in the CSS class name or the pound in CSS id + classesNames.Add(cname.Substring(1)); + } } foreach (string identifiedClassName in classesNames) { - identifiedCSSClassesAndIDs.Add(identifiedClassName, properties); + string currentProperties = ""; + if (identifiedCSSClassesAndIDs.Contains(identifiedClassName)) + { + currentProperties = identifiedCSSClassesAndIDs[identifiedClassName].ToString(); + } + + currentProperties += properties; + identifiedCSSClassesAndIDs.Remove(identifiedClassName); + identifiedCSSClassesAndIDs.Add(identifiedClassName, currentProperties); } } } Index: xword/ContentFiltering/Office/Word/Filters/WebToLocalStyleFilter.cs =================================================================== --- xword/ContentFiltering/Office/Word/Filters/WebToLocalStyleFilter.cs (revision 0) +++ xword/ContentFiltering/Office/Word/Filters/WebToLocalStyleFilter.cs (revision 0) @@ -0,0 +1,80 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using XWiki.Office.Word; +using System.Xml; +using ContentFiltering.Html; +using ContentFiltering.StyleSheetExtensions; + +namespace ContentFiltering.Office.Word.Filters +{ + /// + /// Gets the StyleSheetExtensions objects for a page and inserts the CSS in the XmlDocument. + /// + public class WebToLocalStyleFilter:IDOMFilter + { + private ConversionManager manager; + + public WebToLocalStyleFilter(ConversionManager manager) + { + this.manager = manager; + } + + #region IDOMFilter Members + + public void Filter(ref XmlDocument xmlDoc) + { + XmlNode styleNode = GetStyleNode(ref xmlDoc); + string cssContent = ExtractCSSFromStyleSheetExtensions(); + styleNode.InnerText = cssContent; + + CSSUtil.InlineCSS(ref xmlDoc); + + } + + #endregion IDOMFilter Members + + + /// + /// Gets or creates a style node in the XmlDocument. + /// + /// A reference to the XmlDocument. + /// Existing or created style node. + private XmlNode GetStyleNode(ref XmlDocument xmlDoc) + { + XmlNode bodyNode = xmlDoc.GetElementsByTagName("body")[0]; + if (bodyNode == null) + { + bodyNode = xmlDoc.CreateElement("body"); + xmlDoc.InsertBefore(bodyNode, xmlDoc.ChildNodes[0]); + } + XmlNode headNode = xmlDoc.GetElementsByTagName("head")[0]; + if (headNode == null) + { + headNode = xmlDoc.CreateElement("head"); + bodyNode.ParentNode.InsertBefore(headNode, bodyNode); + } + XmlNode styleNode = xmlDoc.GetElementsByTagName("style")[0]; + if (styleNode == null) + { + styleNode = xmlDoc.CreateElement("style"); + headNode.AppendChild(styleNode); + } + + return styleNode; + } + + + /// + /// Extracts the CSS from StyleSheetExtension objects. + /// + /// + private string ExtractCSSFromStyleSheetExtensions() + { + SSXManager ssxManager = SSXManager.BuildFromServerPage(manager); + return ssxManager.PageCSSContent; + } + + } +} Index: xword/ContentFiltering/Office/Word/WebToLocalHTML.cs =================================================================== --- xword/ContentFiltering/Office/Word/WebToLocalHTML.cs (revision 22406) +++ xword/ContentFiltering/Office/Word/WebToLocalHTML.cs (working copy) @@ -111,7 +111,8 @@ { new WebMacrosAdaptorFilter(manager), new WebImageAdaptorFilter(manager), - new WebListsAdaptorFilter(manager) + new WebListsAdaptorFilter(manager), + new WebToLocalStyleFilter(manager) }; foreach (IDOMFilter webToLocalFilter in webToLocalFilters)