private QAT BuildQATInternal(object data, QATBuildContext qbc) { if (CUIUtility.IsNullOrUndefined(data)) { throw new ArgumentNullException("No QAT element was present in the data"); } QAT = new QAT(DataNodeWrapper.GetAttribute(data, "Id"), DataNodeWrapper.GetNodeAttributes(data).To <QATProperties>()); // Handle the controls in the QAT // The XML structure looks like <QAT><Controls><Control></Control><Control></Control>... JSObject controlsParent = DataNodeWrapper.GetFirstChildNodeWithName(data, DataNodeWrapper.CONTROLS); JSObject[] controls = DataNodeWrapper.GetNodeChildren(controlsParent); for (int j = 0; j < controls.Length; j++) { if (!IsNodeTrimmed(controls[j])) { Control control = BuildControl(controls[j], qbc); QAT.AddChild(control.CreateComponentForDisplayMode("Small")); } } return(QAT); }
private void OnReturnJewel(DataQueryResult dqr) { JewelBuildContext jbc = (JewelBuildContext)dqr.ContextData; // Apply any extensions to the data. dqr.QueryData = ApplyDataExtensions(dqr.QueryData); JSObject jewelNode = DataNodeWrapper.GetFirstChildNodeWithName(dqr.QueryData, DataNodeWrapper.JEWEL); Jewel = BuildJewelInternal(jewelNode, jbc); Jewel.JewelBuilder = this; BuildClient.OnComponentCreated(Jewel, Jewel.Id); if (JewelBuildOptions.AttachToDOM) { Jewel.AttachInternal(true); } else { Jewel.RefreshInternal(); Placeholder.AppendChild(Jewel.ElementInternal); Utility.EnsureCSSClassOnElement(Placeholder, "loaded"); } OnRootBuilt(Jewel); BuildClient.OnComponentBuilt(Jewel, Jewel.Id); }
private ColorPicker BuildColorPicker(object data, BuildContext bc) { ColorPickerProperties properties = DataNodeWrapper.GetNodeAttributes(data).To <ColorPickerProperties>(); JSObject[] colorNodes = DataNodeWrapper.GetNodeChildren( DataNodeWrapper.GetFirstChildNodeWithName(data, DataNodeWrapper.Colors)); int numColors = colorNodes.Length; ColorStyle[] colors = new ColorStyle[numColors]; for (int i = 0; i < numColors; i++) { ColorStyle color = new ColorStyle(); JSObject dict = DataNodeWrapper.GetNodeAttributes(colorNodes[i]); string title = DataNodeWrapper.GetAttribute(dict, DataNodeWrapper.TITLE); color.Title = string.IsNullOrEmpty(title) ? DataNodeWrapper.GetAttribute(dict, DataNodeWrapper.ALT) : title; color.Color = DataNodeWrapper.GetAttribute(dict, DataNodeWrapper.COLOR); color.DisplayColor = DataNodeWrapper.GetAttribute(dict, DataNodeWrapper.DISPLAYCOLOR); color.Style = DataNodeWrapper.GetAttribute(dict, DataNodeWrapper.STYLE); colors[i] = color; } ColorPicker cp = new ColorPicker(Root, properties.Id, properties, colors); return(cp); }
public void LoadTemplates(object data) { JSObject templatesNode = DataNodeWrapper.GetFirstChildNodeWithName(data, DataNodeWrapper.RIBBONTEMPLATES); JSObject[] children = DataNodeWrapper.GetNodeChildren(templatesNode); for (int i = 0; i < children.Length; i++) { LoadGroupTemplate(children[i]); } }
private SPRibbon BuildRibbon(object data, RibbonBuildContext rbc) { JSObject ribbonElement = DataNodeWrapper.GetFirstChildNodeWithName(data, DataNodeWrapper.RIBBON); if (CUIUtility.IsNullOrUndefined(ribbonElement)) { throw new ArgumentNullException("No ribbon element was present in the data"); } Ribbon = new SPRibbon(DataNodeWrapper.GetAttribute(ribbonElement, "Id"), DataNodeWrapper.GetNodeAttributes(ribbonElement).To <RibbonProperties>()); //REVIEW(josefl) Should this be configurable? Ribbon.UseDataCookie = true; // Handle the Tabs // The XML structure that we are looking at is <Ribbon><Tabs><Tab/><Tab/>... JSObject[] tabChildren = DataNodeWrapper.GetNodeChildren( DataNodeWrapper.GetFirstChildNodeWithName(ribbonElement, DataNodeWrapper.TABS)); AddTabsToRibbon(tabChildren, "", rbc); // Handle the Contextual Tab Groups // The XML structure that we are looking at is <Ribbon><ContextualTabs><ContextualGroup>... object contextualTabs = DataNodeWrapper.GetFirstChildNodeWithName(ribbonElement, DataNodeWrapper.CONTEXTUALTABS); if (!CUIUtility.IsNullOrUndefined(contextualTabs)) { JSObject[] cgChildren = DataNodeWrapper.GetNodeChildren(contextualTabs); bool shownContextualGroupsSpecified = !CUIUtility.IsNullOrUndefined(RibbonBuildOptions.ShownContextualGroups); for (int j = 0; j < cgChildren.Length; j++) { if (shownContextualGroupsSpecified) { // Show the contextual group if it has been explicitly requested/ made available string cgId = DataNodeWrapper.GetAttribute(cgChildren[j], DataNodeWrapper.ID); if (!string.IsNullOrEmpty(cgId)) { if (!RibbonBuildOptions.ShownContextualGroups.ContainsKey(cgId) || CUIUtility.IsNullOrUndefined(RibbonBuildOptions.ShownContextualGroups[cgId])) { continue; } } } AddContextualGroup(cgChildren[j], rbc); } } return(Ribbon); }
/// <summary> /// Constructs a toolbar from its JSON data. /// </summary> private Toolbar BuildToolbarFromData(object data, ToolbarBuildContext context) { JSObject toolbarElement = DataNodeWrapper.GetFirstChildNodeWithName(data, DataNodeWrapper.TOOLBAR); if (CUIUtility.IsNullOrUndefined(toolbarElement)) { throw new ArgumentNullException("No toolbar element was present in the data"); } bool hasJewel = !CUIUtility.IsNullOrUndefined(DataNodeWrapper.GetFirstChildNodeWithName(data, DataNodeWrapper.JEWEL)); Toolbar = new Toolbar( DataNodeWrapper.GetAttribute(toolbarElement, DataNodeWrapper.ID), DataNodeWrapper.GetNodeAttributes(toolbarElement).To <ToolbarProperties>(), this, hasJewel); Toolbar.ClientID = Options.ClientID; Toolbar.UseDataCookie = true; Toolbar.RefreshInternal(); // We need to refresh before we can attach the jewel. if (hasJewel) { Toolbar.AttachAndBuildJewelFromData(data); } // Build the ButtonDocks (the Docks will build their subcontrols). JSObject docks = DataNodeWrapper.GetFirstChildNodeWithName(toolbarElement, DataNodeWrapper.BUTTONDOCKS); JSObject[] dockChildren = DataNodeWrapper.GetNodeChildren(docks); for (int i = 0; i < dockChildren.Length; i++) { ButtonDock dock = BuildButtonDock(dockChildren[i], context); Toolbar.AddChild(dock); } return(Toolbar); }
/// <summary> /// Build up a ButtonDock based on the JSON object provided. /// </summary> private ButtonDock BuildButtonDock(object data, ToolbarBuildContext buildContext) { ButtonDock dock = Toolbar.CreateButtonDock(data, buildContext); JSObject controlsNode = DataNodeWrapper.GetFirstChildNodeWithName(data, DataNodeWrapper.CONTROLS); JSObject[] controls = DataNodeWrapper.GetNodeChildren(controlsNode); for (int i = 0; i < controls.Length; i++) { // Don't build trimmed controls if (IsNodeTrimmed(controls[i])) { continue; } Component currentDisplayComponent = BuildToolbarControlComponent(controls[i], buildContext); dock.AddChild(currentDisplayComponent); } return(dock); }
private void OnReturnQAT(DataQueryResult dqr) { QATBuildContext qbc = (QATBuildContext)dqr.ContextData; // Apply any extensions to the data. dqr.QueryData = ApplyDataExtensions(dqr.QueryData); QAT = BuildQATInternal(DataNodeWrapper.GetFirstChildNodeWithName(dqr.QueryData, DataNodeWrapper.QAT), qbc); QAT.QATBuilder = this; BuildClient.OnComponentCreated(QAT, QAT.Id); if (QATBuildOptions.AttachToDOM) { QAT.AttachInternal(true); } else { QAT.RefreshInternal(); Placeholder.AppendChild(QAT.ElementInternal); Utility.EnsureCSSClassOnElement(Placeholder, "loaded"); } OnRootBuilt(QAT); BuildClient.OnComponentBuilt(QAT, QAT.Id); }
private void FillTab(Tab tab, object data, RibbonBuildContext rbc) { JSObject groupsNode = DataNodeWrapper.GetFirstChildNodeWithName(data, DataNodeWrapper.GROUPS); JSObject[] groupChildren = DataNodeWrapper.GetNodeChildren(groupsNode); Dictionary <string, string> emptyTrimmedGroupIds = new Dictionary <string, string>(); for (int i = 0; i < groupChildren.Length; i++) { if (IsNodeTrimmed(groupChildren[i])) { continue; } Group group = BuildGroup(groupChildren[i], rbc); // If the build option TrimEmptyGroups is null, and the Group is empty // then null is returned by BuildGroup() if (!CUIUtility.IsNullOrUndefined(group)) { tab.AddChild(group); } else { // If the group has an Id, then we store it so that we can ignore any scaling // information that relates it it. If it does not have an id, then any scaling info // will not work anyways and it is an invalid node. Groups must have ids. string id = DataNodeWrapper.GetAttribute(groupChildren[i], DataNodeWrapper.ID); if (!string.IsNullOrEmpty(id)) { emptyTrimmedGroupIds[id] = id; } } } JSObject scaling = DataNodeWrapper.GetFirstChildNodeWithName(data, DataNodeWrapper.SCALING); JSObject[] children = DataNodeWrapper.GetNodeChildren(scaling); string _scaleWarningMessage = ""; bool _scaleWarning = false; for (int i = 0; i < children.Length; i++) { string name = DataNodeWrapper.GetNodeName(children[i]); string groupId = DataNodeWrapper.GetAttribute(children[i], DataNodeWrapper.GROUPID); if (name == DataNodeWrapper.MAXSIZE) { // Don't include the scale step if the group that it refers to has been trimmed if (IsIdTrimmed(groupId) || (emptyTrimmedGroupIds.ContainsKey(groupId) && !CUIUtility.IsNullOrUndefined(emptyTrimmedGroupIds[groupId]))) { continue; } tab.Scaling.SetGroupMaxSize(groupId, DataNodeWrapper.GetAttribute(children[i], DataNodeWrapper.SIZE)); } else if (name == DataNodeWrapper.SCALE) { // Don't include the scale step if the group that it refers to has been trimmed if (IsIdTrimmed(groupId) || (emptyTrimmedGroupIds.ContainsKey(groupId) && !CUIUtility.IsNullOrUndefined(emptyTrimmedGroupIds[groupId]))) { continue; } tab.Scaling.AddScalingStep(new ScalingStep(groupId, DataNodeWrapper.GetAttribute(children[i], DataNodeWrapper.SIZE), DataNodeWrapper.GetAttribute(children[i], DataNodeWrapper.POPUPSIZE), _scaleWarningMessage, _scaleWarning)); _scaleWarningMessage = ""; _scaleWarning = false; } else if (name == DataNodeWrapper.LOWSCALEWARNING) { _scaleWarningMessage = DataNodeWrapper.GetAttribute(children[i], DataNodeWrapper.MESSAGE); _scaleWarning = true; } else { throw new InvalidOperationException("Was expecting a node with name MaxSize or Scale."); } } // Start at the largest scale tab.ScaleMax(); }
private void OnReturnTab(DataQueryResult res) { RibbonBuildContext rbc = (RibbonBuildContext)res.ContextData; if (res.Success) { JSObject ribbonNode = DataNodeWrapper.GetFirstChildNodeWithName(res.QueryData, DataNodeWrapper.RIBBON); JSObject tabsNode = DataNodeWrapper.GetFirstChildNodeWithName(ribbonNode, DataNodeWrapper.TABS); JSObject[] tabs = null; JSObject[] children = DataNodeWrapper.GetNodeChildren(tabsNode); if (children.Length == 0) { JSObject ctxtabsNode = DataNodeWrapper.GetFirstChildNodeWithName(ribbonNode, DataNodeWrapper.CONTEXTUALTABS); JSObject[] contextualGroups = DataNodeWrapper.GetNodeChildren(ctxtabsNode); for (int i = 0; i < contextualGroups.Length; i++) { JSObject contextualGroup = contextualGroups[i]; tabs = DataNodeWrapper.GetNodeChildren(contextualGroup); if (tabs.Length > 0) { break; } } } else { tabs = DataNodeWrapper.GetNodeChildren(tabsNode); } JSObject templatesNode = DataNodeWrapper.GetFirstChildNodeWithName(res.QueryData, DataNodeWrapper.TEMPLATES); // Apply any extensions to the template data. templatesNode = (JSObject)ApplyDataExtensions(templatesNode); TemplateManager.Instance.LoadTemplates(templatesNode); // Apply any extensions to the tab data. // In this case we do not want to apply the extensions to the whole hierarchy // including <CommandUI>, <Ribbon> etc because this query is really only for // a specific tab. object tabData = ApplyDataExtensions(tabs[0]); FillTab(rbc.InitializedTab, tabData, rbc); // This may need to be parametrized so that tabs can be inited // without automatically getting selected when the initing is done. rbc.InitializedTab.Ribbon.MakeTabSelectedInternal(rbc.InitializedTab); rbc.InitializedTab.OnDelayedInitFinished(true); } // TODO: how to handle failures #if PERF_METRICS PMetrics.PerfMark(PMarker.perfCUIRibbonTabSwitchWarmPercvdEnd); #endif }
private void OnReturnRibbonAndInitialTab(DataQueryResult res) { PMetrics.PerfMark(PMarker.perfCUIRibbonInitStart); RibbonBuildContext rbc = (RibbonBuildContext)res.ContextData; // Apply any extensions to the data. res.QueryData = ApplyDataExtensions(res.QueryData); Utility.EnsureCSSClassOnElement(Placeholder, "loaded"); JSObject templates = DataNodeWrapper.GetFirstChildNodeWithName(res.QueryData, DataNodeWrapper.TEMPLATES); if (!CUIUtility.IsNullOrUndefined(templates)) { TemplateManager.Instance.LoadTemplates(templates); } Ribbon = BuildRibbon(res.QueryData, rbc); Ribbon.RibbonBuilder = this; BuildClient.OnComponentCreated(Ribbon, Ribbon.Id); if (RibbonBuildOptions.Minimized) { Ribbon.MinimizedInternal = true; } else { Ribbon.MinimizedInternal = false; Tab firstTab = (Tab)Ribbon.GetChild(rbc.InitialTabId); if (!CUIUtility.IsNullOrUndefined(firstTab)) { // We need this in order to set the "ChangedByUser" property of the first // TabSwitch command that comes out of the ribbon correctly. firstTab.SelectedByUser = RibbonBuildOptions.InitialTabSelectedByUser; Ribbon.MakeTabSelectedInternal(firstTab); } } Ribbon.ClientID = RibbonBuildOptions.ClientID; bool shouldAttach = !RibbonBuildOptions.Minimized && RibbonBuildOptions.AttachToDOM; if (shouldAttach) { // Scale the ribbon to the scaling index that matches the ribbon that was // rendered by the server. This sets the in memory Ribbon structure to match // what was rendered by the server. This is needed so that Ribbon.AttachInternal() // will work properly. if (!((RibbonBuildOptions)Options).Minimized) { // We subtract one from this scaling index because internally // this scaling index is an entry into an array of "<ScaleStep>" so // the MaxSize for all the groups is actually index "-1" and the first // step is index 0. Ribbon.ScaleIndex(rbc.InitialScalingIndex - 1); } Ribbon.AttachInternal(true); // Attach to the QAT and Jewel if (!string.IsNullOrEmpty(RibbonBuildOptions.ShowQATId)) { Ribbon.BuildAndSetQAT(RibbonBuildOptions.ShowQATId, true, DataSource); } if (!string.IsNullOrEmpty(RibbonBuildOptions.ShowJewelId)) { Ribbon.BuildAndSetJewel(RibbonBuildOptions.ShowJewelId, true, DataSource); } #if DEBUG // Validate that the server rendered ribbon is identical to the client rendered one // for this tab. if (Options.ValidateServerRendering) { RibbonBuilder rb2 = new RibbonBuilder(this.RibbonBuildOptions, this.Placeholder, null); DataSource ds = new DataSource(this.DataSource.DataUrl, this.DataSource.Version, this.DataSource.Lcid); rb2.DataSource = ds; SPRibbon r2 = rb2.BuildRibbon(res.QueryData, rbc); r2.Id += "-client"; r2.ClientID = RibbonBuildOptions.ClientID + "-client"; r2.RibbonBuilder = this; if (!RibbonBuildOptions.Minimized) { r2.Minimized = false; } // Clone all the peripheral sections for the client-rendering version Div p_qrc = (Div)Browser.Document.GetById(RibbonBuildOptions.ClientID + "-" + RibbonPeripheralSection.QATRowCenter); Div p_qrr = (Div)Browser.Document.GetById(RibbonBuildOptions.ClientID + "-" + RibbonPeripheralSection.QATRowRight); Div p_trl = (Div)Browser.Document.GetById(RibbonBuildOptions.ClientID + "-" + RibbonPeripheralSection.TabRowLeft); Div p_trr = (Div)Browser.Document.GetById(RibbonBuildOptions.ClientID + "-" + RibbonPeripheralSection.TabRowRight); Div hiddenClonedPeripherals = new Div(); hiddenClonedPeripherals.Style.Display = "none"; Browser.Document.Body.AppendChild(hiddenClonedPeripherals); Div clone; if (null != p_qrc) { clone = (Div)p_qrc.CloneNode(true); clone.Id = clone.Id.Replace(RibbonBuildOptions.ClientID, r2.ClientID); hiddenClonedPeripherals.AppendChild(clone); } if (null != p_qrr) { clone = (Div)p_qrr.CloneNode(true); clone.Id = clone.Id.Replace(RibbonBuildOptions.ClientID, r2.ClientID); hiddenClonedPeripherals.AppendChild(clone); } if (null != p_trl) { clone = (Div)p_trl.CloneNode(true); clone.Id = clone.Id.Replace(RibbonBuildOptions.ClientID, r2.ClientID); hiddenClonedPeripherals.AppendChild(clone); } if (null != p_trr) { clone = (Div)p_trr.CloneNode(true); clone.Id = clone.Id.Replace(RibbonBuildOptions.ClientID, r2.ClientID); hiddenClonedPeripherals.AppendChild(clone); } r2.MakeTabSelectedInternal((Tab)r2.GetChild(rbc.InitialTabId)); r2.RefreshInternal(); if (!string.IsNullOrEmpty(RibbonBuildOptions.ShowQATId)) { r2.BuildAndSetQAT(RibbonBuildOptions.ShowQATId, false, ds); } if (!string.IsNullOrEmpty(RibbonBuildOptions.ShowJewelId)) { r2.BuildAndSetJewel(RibbonBuildOptions.ShowJewelId, false, ds); } r2.ScaleIndex(rbc.InitialScalingIndex - 1); r2.CompleteConstruction(); // If this returns a message it means that it found some inconsistencies // between the DOM Nodes CompareNodes(Ribbon.ElementInternal, r2.ElementInternal); } #endif } else { // Do the minimum amount of work necessary in order to be able to // get the outer ribbon element and to be able to attach the Jewel and QAT. Ribbon.EnsureDOMElement(); // Build the QAT and Jewel after the ribbon so that the placeholders // will have been created within the ribbon via Ribbon.RefreshInternal() if (!string.IsNullOrEmpty(RibbonBuildOptions.ShowQATId)) { Ribbon.BuildAndSetQAT(RibbonBuildOptions.ShowQATId, false, DataSource); } if (!string.IsNullOrEmpty(RibbonBuildOptions.ShowJewelId)) { Ribbon.BuildAndSetJewel(RibbonBuildOptions.ShowJewelId, false, DataSource); } // Remove anything else that is in the placeholder in case there is a temporary // animated gif or a static ribbon in there while the ribbon is loading. // We're doing this the slow way since partners might have a reference to this node Utility.RemoveChildNodesSlow(Placeholder); Placeholder.AppendChild(Ribbon.ElementInternal); } Ribbon.Scale(); OnRootBuilt(Ribbon); BuildClient.OnComponentBuilt(Ribbon, Ribbon.Id); if (RibbonBuildOptions.LaunchedByKeyboard) { Ribbon.SetFocusOnRibbon(); } PMetrics.PerfMark(PMarker.perfCUIRibbonInitPercvdEnd); }