Exemple #1
0
        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);
        }
Exemple #2
0
        private GalleryButton BuildGalleryButton(object data, BuildContext bc, string strElmDims)
        {
            GalleryElementDimensions elmDims;

            // If elmDims is null, try to get the value from data
            if (string.IsNullOrEmpty(strElmDims))
            {
                JSObject attrs = DataNodeWrapper.GetNodeAttributes(data);
                strElmDims = DataNodeWrapper.GetAttribute(attrs, DataNodeWrapper.ELEMENTDIMENSIONS);
            }
            // If elmDims is still null (no value defined in data), default to 32x32
            if (string.IsNullOrEmpty(strElmDims))
            {
                elmDims = GalleryElementDimensions.Size32by32;
            }
            else
            {
                elmDims = Gallery.ConvertStringToGalleryElementDimensions(strElmDims);
            }

            GalleryButtonProperties properties =
                DataNodeWrapper.GetNodeAttributes(data).To <GalleryButtonProperties>();
            GalleryButton gb = new GalleryButton(Root,
                                                 properties.Id,
                                                 properties,
                                                 elmDims);

            return(gb);
        }
Exemple #3
0
        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);
        }
Exemple #4
0
        internal ButtonDock CreateButtonDock(object data, ToolbarBuildContext buildContext)
        {
            ButtonDockProperties properties =
                DataNodeWrapper.GetNodeAttributes(data).To <ButtonDockProperties>();
            ButtonDock dock = new ButtonDock(Root, properties.Id, properties);

            return(dock);
        }
Exemple #5
0
        private SPButton BuildButton(object data, BuildContext bc)
        {
            ButtonProperties properties =
                DataNodeWrapper.GetNodeAttributes(data).To <ButtonProperties>();
            SPButton fsea = new SPButton(Root,
                                         properties.Id,
                                         properties);

            return(fsea);
        }
Exemple #6
0
        private TextBox BuildTextBox(object data, BuildContext bc)
        {
            TextBoxProperties properties =
                DataNodeWrapper.GetNodeAttributes(data).To <TextBoxProperties>();
            TextBox fstb = new TextBox(Root,
                                       properties.Id,
                                       properties);

            return(fstb);
        }
Exemple #7
0
        private Separator BuildSeparator(object data, BuildContext bc)
        {
            SeparatorProperties properties =
                DataNodeWrapper.GetNodeAttributes(data).To <SeparatorProperties>();
            Separator sep = new Separator(Root,
                                          properties.Id,
                                          properties);

            return(sep);
        }
Exemple #8
0
        private SPLabel BuildLabel(object data, BuildContext bc)
        {
            LabelProperties properties =
                DataNodeWrapper.GetNodeAttributes(data).To <LabelProperties>();
            SPLabel fslb = new SPLabel(Root,
                                       properties.Id,
                                       properties);

            return(fslb);
        }
Exemple #9
0
        private CheckBox BuildCheckBox(object data, BuildContext bc)
        {
            CheckBoxProperties properties =
                DataNodeWrapper.GetNodeAttributes(data).To <CheckBoxProperties>();
            CheckBox cb = new CheckBox(Root,
                                       properties.Id,
                                       properties);

            return(cb);
        }
Exemple #10
0
        private InsertTable BuildInsertTable(object data, BuildContext bc)
        {
            InsertTableProperties properties =
                DataNodeWrapper.GetNodeAttributes(data).To <InsertTableProperties>();
            InsertTable fsit = new InsertTable(Root,
                                               properties.Id,
                                               properties);

            return(fsit);
        }
Exemple #11
0
        private ToggleButton BuildToggleButton(object data, BuildContext bc)
        {
            ToggleButtonProperties properties =
                DataNodeWrapper.GetNodeAttributes(data).To <ToggleButtonProperties>();
            ToggleButton fsbc = new ToggleButton(Root,
                                                 properties.Id,
                                                 properties);

            return(fsbc);
        }
Exemple #12
0
        private Spinner BuildSpinner(object data, BuildContext bc)
        {
            SpinnerProperties properties =
                DataNodeWrapper.GetNodeAttributes(data).To <SpinnerProperties>();
            Spinner fssp = new Spinner(Root,
                                       properties.Id,
                                       properties,
                                       BuildUnits(data));

            return(fssp);
        }
Exemple #13
0
        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);
        }
Exemple #14
0
        private ComboBox BuildComboBox(object data, BuildContext bc)
        {
            ComboBoxProperties properties =
                DataNodeWrapper.GetNodeAttributes(data).To <ComboBoxProperties>();

            JSObject[] children = DataNodeWrapper.GetNodeChildren(data);

            Menu menu = null;

            MenuLauncherControlProperties launcherProperties =
                DataNodeWrapper.GetNodeAttributes(data).To <MenuLauncherControlProperties>();

            Dictionary <string, string> menuItems = null;

            if (!Utility.IsTrue(launcherProperties.PopulateDynamically))
            {
                // Since PopulateDynamically is not true, we pass in "false" for LazyInit
                menu = BuildMenu(children[0], bc, false);

                // Parse XML subtree to build MenuItem list for auto-complete
                menuItems = new Dictionary <string, string>();
                JSObject[] sections = DataNodeWrapper.GetNodeChildren(children[0]);
                int        l        = sections.Length;
                for (int i = 0; i < l; i++)
                {
                    // Get children of the MenuSection node
                    JSObject[] sectionChildren = DataNodeWrapper.GetNodeChildren(sections[i]);
                    // Get children of the Controls node within the MenuSection
                    // There should only be 1 Controls node within the MenuSection subtree
                    JSObject[] items = DataNodeWrapper.GetNodeChildren(sectionChildren[0]);
                    int        m     = items.Length;
                    for (int j = 0; j < m; j++)
                    {
                        string labeltext  = DataNodeWrapper.GetAttribute(items[j], DataNodeWrapper.LABELTEXT);
                        string menuitemid = DataNodeWrapper.GetAttribute(items[j], DataNodeWrapper.MENUITEMID);
                        menuItems[labeltext] = menuitemid;
                    }
                }
            }

            ComboBox fscb = new ComboBox(Root,
                                         properties.Id,
                                         properties,
                                         menu);

            fscb.MenuItems = menuItems;
            return(fscb);
        }
Exemple #15
0
        private Jewel BuildJewelInternal(object data, JewelBuildContext jbc)
        {
            if (CUIUtility.IsNullOrUndefined(data))
            {
                throw new ArgumentNullException("No Jewel element was present in the data");
            }

            Jewel = new Jewel(DataNodeWrapper.GetAttribute(data, "Id"),
                              DataNodeWrapper.GetNodeAttributes(data).To <JewelProperties>());

            // Handle the Jewel Menu Launcher control
            JewelMenuLauncher jml = BuildJewelMenuLauncher(data, jbc);

            Jewel.AddChild(jml.CreateComponentForDisplayMode("Default"));
            Jewel.JewelMenuLauncher = jml;

            return(Jewel);
        }
Exemple #16
0
        private SplitButton BuildSplitButton(object data, BuildContext bc)
        {
            SplitButtonProperties properties =
                DataNodeWrapper.GetNodeAttributes(data).To <SplitButtonProperties>();

            JSObject[] children = DataNodeWrapper.GetNodeChildren(data);
            Menu       menu     = null;

            if (!Utility.IsTrue(properties.PopulateDynamically))
            {
                menu = BuildMenu(children[0], bc, true);
            }

            SplitButton fseo =
                new SplitButton(Root,
                                properties.Id,
                                properties,
                                menu);

            return(fseo);
        }
Exemple #17
0
        /// <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);
        }
Exemple #18
0
        private Gallery BuildGallery(object data, BuildContext bc, bool isInMenu)
        {
            JSObject          attrs      = DataNodeWrapper.GetNodeAttributes(data);
            GalleryProperties properties = DataNodeWrapper.GetNodeAttributes(data).To <GalleryProperties>();
            Gallery           gallery    = Root.CreateGallery(properties.Id,
                                                              DataNodeWrapper.GetAttribute(attrs, DataNodeWrapper.TITLE),
                                                              DataNodeWrapper.GetAttribute(attrs, DataNodeWrapper.DESCRIPTION),
                                                              properties);

            string displayMode = isInMenu ? "Menu" : "Default";

            JSObject[] children = DataNodeWrapper.GetNodeChildren(data);
            int        l        = children.Length;

            for (int i = 0; i < l; i++)
            {
                JSObject child = children[i];
                if (IsNodeTrimmed(child))
                {
                    continue;
                }

                // NOTE: currently, galleries can only host GalleryButton controls.
                // In the future, the gallery could support other control types, so those should be added here.
                Control control;
                switch (DataNodeWrapper.GetNodeName(child))
                {
                case DataNodeWrapper.GalleryButton:
                    control = BuildGalleryButton(child, bc, properties.ElementDimensions);
                    break;

                default:
                    control = BuildControl(child, bc);
                    break;
                }
                gallery.AddChild(control.CreateComponentForDisplayMode(displayMode));
            }

            return(gallery);
        }
Exemple #19
0
        internal Menu BuildMenu(JSObject data, BuildContext bc, bool lazyInit)
        {
            JSObject attrs = DataNodeWrapper.GetNodeAttributes(data);

            string id          = DataNodeWrapper.GetAttribute(data, DataNodeWrapper.ID);
            string title       = DataNodeWrapper.GetAttribute(data, DataNodeWrapper.TITLE);
            string description = DataNodeWrapper.GetAttribute(data, DataNodeWrapper.DESCRIPTION);
            string maxwidth    = DataNodeWrapper.GetAttribute(data, DataNodeWrapper.MAXWIDTH);
            Menu   menu        = Root.CreateMenu(id,
                                                 title,
                                                 description,
                                                 maxwidth);

            if (_bo.LazyMenuInit && lazyInit)
            {
                menu.SetDelayedInitData(new DelayedInitHandler(this.DelayInitMenu), data, bc);
                return(menu);
            }

            FillMenu(menu, data, bc);
            return(menu);
        }
Exemple #20
0
        private JewelMenuLauncher BuildJewelMenuLauncher(object data, JewelBuildContext jbc)
        {
            JewelMenuLauncherProperties properties =
                DataNodeWrapper.GetNodeAttributes(data).To <JewelMenuLauncherProperties>();

            JSObject[] children = DataNodeWrapper.GetNodeChildren(data);

            Menu menu = null;

            MenuLauncherControlProperties launcherProperties =
                DataNodeWrapper.GetNodeAttributes(data).To <MenuLauncherControlProperties>();

            if (!Utility.IsTrue(launcherProperties.PopulateDynamically))
            {
                menu = BuildMenu(children[0], jbc, false);
            }

            JewelMenuLauncher jml = new JewelMenuLauncher(Jewel,
                                                          properties.Id,
                                                          properties,
                                                          menu);

            return(jml);
        }
Exemple #21
0
        private MRUSplitButton BuildMRUSplitButton(object data, BuildContext bc)
        {
            DropDownProperties properties =
                DataNodeWrapper.GetNodeAttributes(data).To <DropDownProperties>();

            JSObject[] children = DataNodeWrapper.GetNodeChildren(data);

            Menu menu = null;

            MenuLauncherControlProperties launcherProperties =
                DataNodeWrapper.GetNodeAttributes(data).To <MenuLauncherControlProperties>();

            if (!Utility.IsTrue(launcherProperties.PopulateDynamically))
            {
                menu = BuildMenu(children[0], bc, false);
            }

            MRUSplitButton fssb = new MRUSplitButton(Root,
                                                     properties.Id,
                                                     properties,
                                                     menu);

            return(fssb);
        }
Exemple #22
0
        private FlyoutAnchor BuildFlyoutAnchor(object data, BuildContext bc)
        {
            FlyoutAnchorProperties properties =
                DataNodeWrapper.GetNodeAttributes(data).To <FlyoutAnchorProperties>();

            JSObject[] children = DataNodeWrapper.GetNodeChildren(data);

            Menu menu = null;

            MenuLauncherControlProperties launcherProperties =
                DataNodeWrapper.GetNodeAttributes(data).To <MenuLauncherControlProperties>();

            if (!Utility.IsTrue(launcherProperties.PopulateDynamically))
            {
                menu = BuildMenu(children[0], bc, true);
            }

            FlyoutAnchor fsfa = new FlyoutAnchor(Root,
                                                 properties.Id,
                                                 properties,
                                                 menu);

            return(fsfa);
        }
Exemple #23
0
        internal Control BuildControl(object data, BuildContext bc)
        {
            Control control = null;
            string  name    = DataNodeWrapper.GetNodeName(data);

            switch (name)
            {
            case DataNodeWrapper.ToggleButton:
                control = BuildToggleButton(data, bc);
                break;

            case DataNodeWrapper.ComboBox:
                control = BuildComboBox(data, bc);
                break;

            case DataNodeWrapper.DropDown:
                control = BuildDropDown(data, bc);
                break;

            case DataNodeWrapper.Button:
                control = BuildButton(data, bc);
                break;

            case DataNodeWrapper.SplitButton:
                control = BuildSplitButton(data, bc);
                break;

            case DataNodeWrapper.FlyoutAnchor:
                control = BuildFlyoutAnchor(data, bc);
                break;

            case DataNodeWrapper.GalleryButton:
                control = BuildGalleryButton(data, bc, null);
                break;

            case DataNodeWrapper.InsertTable:
                control = BuildInsertTable(data, bc);
                break;

            case DataNodeWrapper.Label:
                control = BuildLabel(data, bc);
                break;

            case DataNodeWrapper.MRUSplitButton:
                control = BuildMRUSplitButton(data, bc);
                break;

            case DataNodeWrapper.Spinner:
                control = BuildSpinner(data, bc);
                break;

            case DataNodeWrapper.TextBox:
                control = BuildTextBox(data, bc);
                break;

            case DataNodeWrapper.ColorPicker:
                control = BuildColorPicker(data, bc);
                break;

            case DataNodeWrapper.CheckBox:
                control = BuildCheckBox(data, bc);
                break;

            case DataNodeWrapper.Separator:
                control = BuildSeparator(data, bc);
                break;

            default:
                JSObject attrs     = DataNodeWrapper.GetNodeAttributes(data);
                string   className = DataNodeWrapper.GetAttribute(data, DataNodeWrapper.CLASSNAME);
                if (CUIUtility.IsNullOrUndefined(className))
                {
                    throw new InvalidOperationException("Unable to create Control with tagname: " + name);
                }
                break;
            }
            return(control);
        }
Exemple #24
0
        private Group BuildGroup(object data, RibbonBuildContext rbc)
        {
            string templateName = DataNodeWrapper.GetAttribute(data, DataNodeWrapper.TEMPLATE);

            Template template = TemplateManager.Instance.GetTemplate(templateName);

            if (CUIUtility.IsNullOrUndefined(template))
            {
                throw new ArgumentOutOfRangeException("A template with name: " + templateName + " could not be loaded.");
            }

            JSObject controlsData = null;

            JSObject[] dataChildren = DataNodeWrapper.GetNodeChildren(data);
            for (int i = 0; i < dataChildren.Length; i++)
            {
                if (DataNodeWrapper.GetNodeName(dataChildren[i]) == DataNodeWrapper.CONTROLS)
                {
                    controlsData = dataChildren[i];
                    break;
                }
            }

            if (CUIUtility.IsNullOrUndefined(controlsData))
            {
                throw new InvalidOperationException("No Controls node found in this Group tag.");
            }
            JSObject[] children = DataNodeWrapper.GetNodeChildren(controlsData);

            bool groupIsEmpty = true;
            Dictionary <string, List <Control> > controls = new Dictionary <string, List <Control> >();

            int len = children.Length;

            for (int i = 0; i < len; i++)
            {
                // Don't build controls that have been trimmed
                if (IsNodeTrimmed(children[i]))
                {
                    continue;
                }

                // The group has one or more controls in it
                groupIsEmpty = false;
                Control control = BuildControl(children[i], rbc);

                if (!controls.ContainsKey(control.TemplateAlias) ||
                    CUIUtility.IsNullOrUndefined(controls[control.TemplateAlias]))
                {
                    controls[control.TemplateAlias] = new List <Control>();
                }

                controls[control.TemplateAlias].Add(control);
            }

            if (RibbonBuildOptions.TrimEmptyGroups && groupIsEmpty)
            {
                return(null);
            }

            string id          = DataNodeWrapper.GetAttribute(data, DataNodeWrapper.ID);
            string title       = DataNodeWrapper.GetAttribute(data, DataNodeWrapper.TITLE);
            string description = DataNodeWrapper.GetAttribute(data, DataNodeWrapper.DESCRIPTION);
            string command     = DataNodeWrapper.GetAttribute(data, DataNodeWrapper.COMMAND);
            Group  group       = template.CreateGroup(Ribbon,
                                                      id,
                                                      DataNodeWrapper.GetNodeAttributes(data).To <GroupProperties>(),
                                                      title,
                                                      description,
                                                      command,
                                                      controls,
                                                      null);

            return(group);
        }
Exemple #25
0
        /// <summary>
        /// As much as we'd like to fail gracefully in every corner case for this,
        /// we have to maintain a "garbage in garbage out policy" because this
        /// recursive set of routines is very performance sensitive since it
        /// will run on every single node in the CUI data.
        /// </summary>
        /// <param name="data"></param>
        /// <param name="extensions"></param>
        /// <returns></returns>
        protected static JSObject ApplyDataNodeExtensions(object data, Dictionary <string, List <JSObject> > extensions)
        {
            // If a data node does not have any attributes, then it cannot be extended
            if (CUIUtility.IsNullOrUndefined(DataNodeWrapper.GetNodeAttributes(data)))
            {
                return((JSObject)data);
            }

            string id = DataNodeWrapper.GetAttribute(data, "Id");

            List <JSObject> replacementData = extensions.ContainsKey(id) ? extensions[id] : null;

            // Has this data node been overridden?
            if (!CUIUtility.IsNullOrUndefined(replacementData))
            {
                JSObject winner          = null;
                int      winningSequence = Int32.MaxValue;

                // We now go through and find the correct replacement depending on sequence number.
                // We can only pick one replacement if there are multiple replacements.
                int l = replacementData.Count;
                for (int i = 0; i < l; i++)
                {
                    JSObject replacementNode = replacementData[i];

                    // If there is an entry in the array but it is null, then
                    // we remove this node from the final data by returning null.
                    // Because this means that it was basically overriden with "nothing".
                    // aka "removed".
                    if (replacementNode == null)
                    {
                        return(null);
                    }

                    string sequence = DataNodeWrapper.GetAttribute(replacementNode,
                                                                   DataNodeWrapper.SEQUENCE);

                    // If this extension does not have a sequence, then it has lowest precedence.
                    // This means that it will only be the winner if there is no previous winner.
                    if (string.IsNullOrEmpty(sequence))
                    {
                        if (CUIUtility.IsNullOrUndefined(winner))
                        {
                            winner = replacementNode;
                        }
                        continue;
                    }

                    // If this extension node has a lower sequence value than anything previously seen
                    // then it becomes the new winner.  "Lowest Sequence Wins".
                    int seq = Int32.Parse(sequence);
                    if (seq < winningSequence)
                    {
                        winner          = replacementNode;
                        winningSequence = seq;
                    }
                }

                // Set the actual data node that we will be returning to the
                // node the winner that was determined by examining all the possible extensions.
                if (!CUIUtility.IsNullOrUndefined(winner))
                {
                    data = winner;
                }
            }

            JSObject[] children = DataNodeWrapper.GetNodeChildren(data);

            // If there is not a children node, then we create one so that we can add extensions
            if (CUIUtility.IsNullOrUndefined(children))
            {
                children    = new JSObject[1];
                children[0] = new JSObject();
                ((JSObject)data).SetField <JSObject[]>("children", children);
            }

            // Now we make a temporary list where we will put the data nodes and the
            // extension nodes and then sort them according to sequence before saving
            // them back into the children array in the data node.
            List <JSObject> combinedNodes = new List <JSObject>();
            int             m             = children.Length;

            for (int i = 0; i < m; i++)
            {
                combinedNodes.Add(children[i]);
            }

            // Have any children been added to this node through this extension mechanism?
            string          extKey = id + "._children";
            List <JSObject> childrenReplacementData = extensions.ContainsKey(extKey) ? extensions[extKey] : null;

            // Add the extension nodes if there are any
            if (!CUIUtility.IsNullOrUndefined(childrenReplacementData))
            {
                int n = childrenReplacementData.Count;
                for (int i = 0; i < n; i++)
                {
                    combinedNodes.Add(childrenReplacementData[i]);
                }

                // Now do a sort over the combined list to get the final order
                combinedNodes.Sort(new CompareDataNodeOrder());
            }

            // Now that we have the maximal set of child nodes from the data and the customizations,
            // we need to allow for extensibility on each one before we finally add them to the main
            // parent node.
            int ln = combinedNodes.Count;

            JSObject[] finalChildNodes = new JSObject[ln];
            for (int i = 0; i < ln; i++)
            {
                // Recurse on this child node to get its customizations
                JSObject dataNode = ApplyDataNodeExtensions(combinedNodes[i], extensions);
                if (!CUIUtility.IsNullOrUndefined(dataNode))
                {
                    finalChildNodes[i] = dataNode;
                }
            }

            // Now insert this combined, sorted and extended list of children into the data node
            ((JSObject)data).SetField <JSObject[]>("children", finalChildNodes);
            return((JSObject)data);
        }