internal override void FromHtml(IElement element) { base.FromHtml(element); // Set/update dataVersion if it was provided as html attribute var webPartDataVersion = element.GetAttribute(WebPartDataVersionAttribute); if (!string.IsNullOrEmpty(webPartDataVersion)) { this.dataVersion = element.GetAttribute(WebPartDataVersionAttribute); } // load data from the data-sp-controldata attribute var jsonSerializerSettings = new JsonSerializerSettings() { MissingMemberHandling = MissingMemberHandling.Ignore }; this.spControlData = JsonConvert.DeserializeObject <ClientSideWebPartControlData>(element.GetAttribute(CanvasControl.ControlDataAttribute), jsonSerializerSettings); this.controlType = this.spControlData.ControlType; var wpDiv = element.GetElementsByTagName("div").Where(a => a.HasAttribute(ClientSideWebPart.WebPartDataAttribute)).FirstOrDefault(); // Some components on the page (e.g. web parts configured with isDomainIsolated = true) are rendered differently in the HTML if (wpDiv == null) { JObject wpJObject = JObject.Parse(element.GetAttribute(CanvasControl.ControlDataAttribute)); if (wpJObject["webPartData"] != null) { if (wpJObject["webPartData"] != null && wpJObject["webPartData"]["title"] != null) { this.title = wpJObject["webPartData"]["title"].Value <string>(); } if (wpJObject["webPartData"] != null && wpJObject["webPartData"]["description"] != null) { this.description = wpJObject["webPartData"]["description"].Value <string>(); } if (wpJObject["webPartData"] != null && wpJObject["webPartData"]["properties"] != null) { this.PropertiesJson = wpJObject["webPartData"]["properties"].ToString(Formatting.None); } // Check for fullbleed supporting web parts if (wpJObject["webPartData"] != null && wpJObject["webPartData"]["properties"] != null && wpJObject["webPartData"]["properties"]["isFullWidth"] != null) { this.supportsFullBleed = wpJObject["webPartData"]["properties"]["isFullWidth"].Value <Boolean>(); } // Store the server processed content as that's needed for full fidelity if (wpJObject["webPartData"] != null && wpJObject["webPartData"]["serverProcessedContent"] != null && wpJObject["webPartData"]["serverProcessedContent"].ToString() != "") { this.serverProcessedContent = (JObject)wpJObject["webPartData"]["serverProcessedContent"]; } if (wpJObject["webPartData"] != null && wpJObject["webPartData"]["dynamicDataPaths"] != null) { this.dynamicDataPaths = (JObject)wpJObject["webPartData"]["dynamicDataPaths"]; } if (wpJObject["webPartData"] != null && wpJObject["webPartData"]["dynamicDataValues"] != null) { this.dynamicDataValues = (JObject)wpJObject["webPartData"]["dynamicDataValues"]; } if (wpJObject["webPartData"] != null && wpJObject["webPartData"]["id"] != null) { this.webPartId = wpJObject["webPartData"]["id"].Value <string>(); } } else { // Header controls (like in topic pages) if (wpJObject["title"] != null) { this.title = wpJObject["title"].Value <string>(); } if (wpJObject["description"] != null) { this.description = wpJObject["description"].Value <string>(); } if (wpJObject["properties"] != null) { this.PropertiesJson = wpJObject["properties"].ToString(Formatting.None); } // Check for fullbleed supporting web parts if (wpJObject["properties"] != null && wpJObject["properties"]["isFullWidth"] != null) { this.supportsFullBleed = wpJObject["properties"]["isFullWidth"].Value <Boolean>(); } // Store the server processed content as that's needed for full fidelity if (wpJObject["serverProcessedContent"] != null && wpJObject["serverProcessedContent"].ToString() != "") { this.serverProcessedContent = (JObject)wpJObject["serverProcessedContent"]; } // Set/update dataVersion if it was set in the json data if (wpJObject["dataVersion"] != null && !string.IsNullOrEmpty(wpJObject["dataVersion"].ToString(Formatting.None))) { this.dataVersion = wpJObject["dataVersion"].ToString(Formatting.None).Trim('"'); } if (wpJObject["id"] != null) { this.webPartId = wpJObject["id"].Value <string>(); } if (wpJObject["instanceId"] != null) { if (Guid.TryParse(wpJObject["instanceId"].Value <string>(), out Guid instanceGuid)) { this.instanceId = instanceGuid; } } } this.usingSpControlDataOnly = true; } else { this.webPartData = wpDiv.GetAttribute(ClientSideWebPart.WebPartAttribute); // Decode the html encoded string var decoded = WebUtility.HtmlDecode(wpDiv.GetAttribute(ClientSideWebPart.WebPartDataAttribute)); JObject wpJObject = JObject.Parse(decoded); this.title = wpJObject["title"] != null ? wpJObject["title"].Value <string>() : ""; this.description = wpJObject["description"] != null ? wpJObject["description"].Value <string>() : ""; // Set property to trigger correct loading of properties this.PropertiesJson = wpJObject["properties"].ToString(Formatting.None); // Set/update dataVersion if it was set in the json data if (!string.IsNullOrEmpty(wpJObject["dataVersion"].ToString(Formatting.None))) { this.dataVersion = wpJObject["dataVersion"].ToString(Formatting.None).Trim('"'); } // Check for fullbleed supporting web parts if (wpJObject["properties"] != null && wpJObject["properties"]["isFullWidth"] != null) { this.supportsFullBleed = wpJObject["properties"]["isFullWidth"].Value <Boolean>(); } // Store the server processed content as that's needed for full fidelity if (wpJObject["serverProcessedContent"] != null && wpJObject["serverProcessedContent"].ToString() != "") { this.serverProcessedContent = (JObject)wpJObject["serverProcessedContent"]; } if (wpJObject["dynamicDataPaths"] != null) { this.dynamicDataPaths = (JObject)wpJObject["dynamicDataPaths"]; } if (wpJObject["dynamicDataValues"] != null) { this.dynamicDataValues = (JObject)wpJObject["dynamicDataValues"]; } this.webPartId = wpJObject["id"].Value <string>(); var wpHtmlProperties = wpDiv.GetElementsByTagName("div").Where(a => a.HasAttribute(ClientSideWebPart.WebPartHtmlPropertiesAttribute)).FirstOrDefault(); this.htmlPropertiesData = wpHtmlProperties.InnerHtml; this.htmlProperties = wpHtmlProperties.GetAttribute(ClientSideWebPart.WebPartHtmlPropertiesAttribute); } }
/// <summary> /// Returns a HTML representation of the client side web part /// </summary> /// <param name="controlIndex">The sequence of the control inside the section</param> /// <returns>HTML representation of the client side web part</returns> public override string ToHtml(float controlIndex) { if (!IsHeaderControl) { // Can this control be hosted in this section type? if (this.Section.Type == CanvasSectionTemplate.OneColumnFullWidth) { if (!this.SupportsFullBleed) { throw new Exception("You cannot host this web part inside a one column full width section, only webparts that support full bleed are allowed"); } } ClientSideWebPartControlData controlData = null; if (this.usingSpControlDataOnly) { controlData = new ClientSideWebPartControlDataOnly(); } else { controlData = new ClientSideWebPartControlData(); } // Obtain the json data controlData.ControlType = this.ControlType; controlData.Id = this.InstanceId.ToString("D"); controlData.WebPartId = this.WebPartId; controlData.Position = new ClientSideCanvasControlPosition() { ZoneIndex = this.Section.Order, SectionIndex = this.Column.Order, SectionFactor = this.Column.ColumnFactor, LayoutIndex = this.Column.LayoutIndex, ControlIndex = controlIndex, }; if (this.section.Type == CanvasSectionTemplate.OneColumnVerticalSection) { if (this.section.Columns.First().Equals(this.Column)) { controlData.Position.SectionFactor = 12; } } controlData.Emphasis = new ClientSideSectionEmphasis() { ZoneEmphasis = this.Column.VerticalSectionEmphasis.HasValue ? this.Column.VerticalSectionEmphasis.Value : this.Section.ZoneEmphasis, }; // Set the control's data version to the latest version...default was 1.0, but some controls use a higher version var webPartType = ClientSidePage.NameToClientSideWebPartEnum(controlData.WebPartId); // if we read the control from the page then the value might already be set to something different than 1.0...if so, leave as is if (this.DataVersion == "1.0") { if (webPartType == DefaultClientSideWebParts.Image) { this.dataVersion = "1.8"; } else if (webPartType == DefaultClientSideWebParts.ImageGallery) { this.dataVersion = "1.6"; } else if (webPartType == DefaultClientSideWebParts.People) { this.dataVersion = "1.2"; } else if (webPartType == DefaultClientSideWebParts.DocumentEmbed) { this.dataVersion = "1.1"; } else if (webPartType == DefaultClientSideWebParts.ContentRollup) { this.dataVersion = "2.1"; } else if (webPartType == DefaultClientSideWebParts.QuickLinks) { this.dataVersion = "2.0"; } } // Set the web part preview image url if (this.ServerProcessedContent != null && this.ServerProcessedContent["imageSources"] != null) { foreach (JProperty property in this.ServerProcessedContent["imageSources"]) { if (!string.IsNullOrEmpty(property.Value.ToString())) { this.webPartPreviewImage = property.Value.ToString().ToLower(); break; } } } ClientSideWebPartData webpartData = new ClientSideWebPartData() { Id = controlData.WebPartId, InstanceId = controlData.Id, Title = this.Title, Description = this.Description, DataVersion = this.DataVersion, Properties = "jsonPropsToReplacePnPRules", DynamicDataPaths = "jsonDynamicDataPathsToReplacePnPRules", DynamicDataValues = "jsonDynamicDataValuesToReplacePnPRules", ServerProcessedContent = "jsonServerProcessedContentToReplacePnPRules" }; if (this.usingSpControlDataOnly) { (controlData as ClientSideWebPartControlDataOnly).WebPartData = "jsonWebPartDataToReplacePnPRules"; this.jsonControlData = JsonConvert.SerializeObject(controlData); this.jsonWebPartData = JsonConvert.SerializeObject(webpartData); this.jsonWebPartData = this.jsonWebPartData.Replace("\"jsonPropsToReplacePnPRules\"", this.Properties.ToString(Formatting.None)); this.jsonWebPartData = this.jsonWebPartData.Replace("\"jsonServerProcessedContentToReplacePnPRules\"", this.ServerProcessedContent.ToString(Formatting.None)); this.jsonWebPartData = this.jsonWebPartData.Replace("\"jsonDynamicDataPathsToReplacePnPRules\"", this.DynamicDataPaths.ToString(Formatting.None)); this.jsonWebPartData = this.jsonWebPartData.Replace("\"jsonDynamicDataValuesToReplacePnPRules\"", this.DynamicDataValues.ToString(Formatting.None)); this.jsonControlData = this.jsonControlData.Replace("\"jsonWebPartDataToReplacePnPRules\"", this.jsonWebPartData); } else { this.jsonControlData = JsonConvert.SerializeObject(controlData); this.jsonWebPartData = JsonConvert.SerializeObject(webpartData); this.jsonWebPartData = this.jsonWebPartData.Replace("\"jsonPropsToReplacePnPRules\"", this.Properties.ToString(Formatting.None)); this.jsonWebPartData = this.jsonWebPartData.Replace("\"jsonServerProcessedContentToReplacePnPRules\"", this.ServerProcessedContent.ToString(Formatting.None)); this.jsonWebPartData = this.jsonWebPartData.Replace("\"jsonDynamicDataPathsToReplacePnPRules\"", this.DynamicDataPaths.ToString(Formatting.None)); this.jsonWebPartData = this.jsonWebPartData.Replace("\"jsonDynamicDataValuesToReplacePnPRules\"", this.DynamicDataValues.ToString(Formatting.None)); } } else { HeaderControlData webpartData = new HeaderControlData() { Id = this.WebPartId, InstanceId = this.InstanceId.ToString("D"), Title = this.Title, Description = this.Description, DataVersion = this.DataVersion, Properties = "jsonPropsToReplacePnPRules", ServerProcessedContent = "jsonServerProcessedContentToReplacePnPRules" }; this.canvasDataVersion = this.DataVersion; this.jsonWebPartData = JsonConvert.SerializeObject(webpartData); this.jsonWebPartData = this.jsonWebPartData.Replace("\"jsonPropsToReplacePnPRules\"", this.Properties.ToString(Formatting.None)); this.jsonWebPartData = this.jsonWebPartData.Replace("\"jsonServerProcessedContentToReplacePnPRules\"", this.ServerProcessedContent.ToString(Formatting.None)); this.jsonControlData = this.jsonWebPartData; } StringBuilder html = new StringBuilder(100); if (this.usingSpControlDataOnly || IsHeaderControl) { html.Append($@"<div {CanvasControlAttribute}=""{this.CanvasControlData}"" {CanvasDataVersionAttribute}=""{this.DataVersion}"" {ControlDataAttribute}=""{this.JsonControlData.Replace("\"", """)}""></div>"); } else { html.Append($@"<div {CanvasControlAttribute}=""{this.CanvasControlData}"" {CanvasDataVersionAttribute}=""{this.DataVersion}"" {ControlDataAttribute}=""{this.JsonControlData.Replace("\"", """)}"">"); html.Append($@"<div {WebPartAttribute}=""{this.WebPartData}"" {WebPartDataVersionAttribute}=""{this.DataVersion}"" {WebPartDataAttribute}=""{this.JsonWebPartData.Replace("\"", """).Replace("<", "<").Replace(">", ">")}"">"); html.Append($@"<div {WebPartComponentIdAttribute}="""">"); html.Append(this.WebPartId); html.Append("</div>"); html.Append($@"<div {WebPartHtmlPropertiesAttribute}=""{this.HtmlProperties}"">"); RenderHtmlProperties(ref html); html.Append("</div>"); html.Append("</div>"); html.Append("</div>"); } return(html.ToString()); }