protected virtual object MapRichText(RichTextData richTextData, Type targetType, ILocalization localization)
        {
            IList <IRichTextFragment> fragments = new List <IRichTextFragment>();

            foreach (object fragment in richTextData.Fragments)
            {
                string htmlFragment = fragment as string;
                if (htmlFragment == null)
                {
                    // Embedded Entity Model (for Media Items)
                    MediaItem mediaItem = (MediaItem)ModelBuilderPipeline.CreateEntityModel((EntityModelData)fragment, typeof(MediaItem), localization);
                    mediaItem.IsEmbedded = true;
                    if (mediaItem.MvcData == null)
                    {
                        mediaItem.MvcData = mediaItem.GetDefaultView(localization);
                    }
                    fragments.Add(mediaItem);
                }
                else
                {
                    // HTML fragment.
                    fragments.Add(new RichTextFragment(htmlFragment));
                }
            }
            RichText richText = new RichText(fragments);

            if (targetType == typeof(RichText))
            {
                return(richText);
            }

            return(richText.ToString());
        }
예제 #2
0
        private RichText ResolveRichText(XmlDocument doc, Localization localization)
        {
            const string xlinkNamespaceUri = "http://www.w3.org/1999/xlink";

            XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);

            nsmgr.AddNamespace("xhtml", "http://www.w3.org/1999/xhtml");
            nsmgr.AddNamespace("xlink", xlinkNamespaceUri);

            // Process/resolve hyperlinks with XLink attributes
            ILinkResolver linkResolver = SiteConfiguration.LinkResolver;

            foreach (XmlElement linkElement in doc.SelectNodes("//a[@xlink:href]", nsmgr))
            {
                // DD4T BinaryPublisher may have resolved a href attribute already (for links to MM Components)
                string linkUrl = linkElement.GetAttribute("href");
                if (string.IsNullOrEmpty(linkUrl))
                {
                    // No href attribute found. Apparently the XLink refers to a regular Component; we resolve it to a URL here.
                    string tcmUri = linkElement.GetAttribute("href", xlinkNamespaceUri);
                    if (!string.IsNullOrEmpty(tcmUri))
                    {
                        // Try to resolve directly to Binary content of MM Component.
                        linkUrl = linkResolver.ResolveLink(tcmUri, resolveToBinary: true);
                    }
                }
                if (!string.IsNullOrEmpty(linkUrl))
                {
                    // The link was resolved; set HTML href attribute
                    linkElement.SetAttribute("href", linkUrl);
                    ApplyHashIfApplicable(linkElement, localization);

                    // Remove all XLink and data- attributes
                    IEnumerable <XmlAttribute> attributesToRemove = linkElement.Attributes.Cast <XmlAttribute>()
                                                                    .Where(a => a.NamespaceURI == xlinkNamespaceUri || a.LocalName == "xlink" || a.LocalName.StartsWith("data-")).ToArray();
                    foreach (XmlAttribute attr in attributesToRemove)
                    {
                        linkElement.Attributes.Remove(attr);
                    }
                }
                else
                {
                    // The link was not resolved; remove the hyperlink.
                    XmlNode parentNode = linkElement.ParentNode;
                    foreach (XmlNode childNode in linkElement.ChildNodes)
                    {
                        parentNode.InsertBefore(childNode, linkElement);
                    }
                    parentNode.RemoveChild(linkElement);
                }
            }

            // Resolve embedded media items
            List <EntityModel> embeddedEntities = new List <EntityModel>();

            foreach (XmlElement imgElement in doc.SelectNodes("//img[@data-schemaUri]", nsmgr))
            {
                string[]       schemaTcmUriParts = imgElement.GetAttribute("data-schemaUri").Split('-');
                SemanticSchema semanticSchema    = SemanticMapping.GetSchema(schemaTcmUriParts[1], localization);

                // The semantic mapping may resolve to a more specific model type than specified here (e.g. YouTubeVideo instead of just MediaItem)
                Type      modelType = semanticSchema.GetModelTypeFromSemanticMapping(typeof(MediaItem));
                MediaItem mediaItem = (MediaItem)modelType.CreateInstance();
                mediaItem.ReadFromXhtmlElement(imgElement);
                if (mediaItem.MvcData == null)
                {
                    // In DXA 1.1 MediaItem.ReadFromXhtmlElement was expected to set MvcData.
                    // In DXA 1.2 this should be done in a GetDefaultView override (which is also used for other embedded Entities)
                    mediaItem.MvcData = mediaItem.GetDefaultView(localization);
                }
                embeddedEntities.Add(mediaItem);

                // Replace img element with marker XML processing instruction
                imgElement.ParentNode.ReplaceChild(
                    doc.CreateProcessingInstruction(EmbeddedEntityProcessingInstructionName, String.Empty),
                    imgElement
                    );
            }

            // Split the XHTML into fragments based on marker XML processing instructions.
            string xhtml = doc.DocumentElement.InnerXml;
            IList <IRichTextFragment> richTextFragments = new List <IRichTextFragment>();
            int lastFragmentIndex = 0;
            int i = 0;

            foreach (Match embeddedEntityMatch in EmbeddedEntityProcessingInstructionRegex.Matches(xhtml))
            {
                int embeddedEntityIndex = embeddedEntityMatch.Index;
                if (embeddedEntityIndex > lastFragmentIndex)
                {
                    richTextFragments.Add(new RichTextFragment(xhtml.Substring(lastFragmentIndex, embeddedEntityIndex - lastFragmentIndex)));
                }
                richTextFragments.Add(embeddedEntities[i++]);
                lastFragmentIndex = embeddedEntityIndex + embeddedEntityMatch.Length;
            }
            if (lastFragmentIndex < xhtml.Length)
            {
                // Final text fragment
                richTextFragments.Add(new RichTextFragment(xhtml.Substring(lastFragmentIndex)));
            }

            return(new RichText(richTextFragments));
        }