/// <summary> /// Set fyout coordinates given information about the viewing area in the screen, the launching control and the flyout dimensions. /// </summary> /// <param name="flyOut">The flyout to be launched.</param> /// <param name="dimensions">Position information on the screen viewing area, lauching control and flyout.</param> internal void SetFlyOutCoordinates(HtmlElement flyOut, Dictionary<string, int> dimensions, bool horizontal) { // reusable boolean to check whether the dom element must be edited or not bool changed = false; if (CUIUtility.IsNullOrUndefined(flyOut) || CUIUtility.IsNullOrUndefined(dimensions)) { return; } // Create default coordinates int flyOutLeft; int flyOutTop; // Cache dimensions for performance int launcherLeft = dimensions["launcherLeft"]; int launcherTop = dimensions["launcherTop"]; int launcherWidth = dimensions["launcherWidth"]; int launcherHeight = dimensions["launcherHeight"]; int flyOutWidth = dimensions["flyOutWidth"]; int flyOutHeight = dimensions["flyOutHeight"]; int flyOutRealHeight = dimensions["flyOutRealHeight"]; int viewportWidth = dimensions["viewportWidth"]; int viewportHeight = dimensions["viewportHeight"]; int viewableLeft = dimensions["viewableLeft"]; int viewableTop = dimensions["viewableTop"]; bool isLTR = Root.TextDirection == Direction.LTR; bool buttedToRightEdge = false, buttedToLeftEdge = false; string objScrollable = flyOut.GetAttribute("mscui:scrollable"); bool wasScrollable = Utility.IsTrue(objScrollable); if (horizontal) { if (isLTR) { // Left-to-right method flyOutLeft = launcherLeft + launcherWidth; flyOutLeft += 2; // styling: make the borders of the menus align } else // Right-to-left method { flyOutLeft = launcherLeft - flyOutWidth; } flyOutTop = launcherTop; } else { if (isLTR) { // Left-to-right method flyOutLeft = launcherLeft; } else // Right-to-left method { flyOutLeft = launcherLeft + launcherWidth - flyOutWidth; } flyOutTop = launcherTop + launcherHeight; int minWidth = launcherWidth >= 2 ? launcherWidth - 2 : launcherWidth /* borders */; // O14:389872 - flyout should be at least as wide as the launcher if (minWidth > flyOutWidth) flyOutWidth = minWidth; flyOut.Style.MinWidth = minWidth + "px"; } // If the root is fixed positioned, then we need to take scroll offset into account (O14:28297) if (FixedPositioningEnabled) { flyOutTop += viewableTop; flyOutLeft += viewableLeft; } flyOut.Style.Top = flyOutTop + "px"; flyOut.Style.Left = flyOutLeft + "px"; // Horizonal Positioning // If the flyOut can fit in the viewport at all, then try positioning logic if (flyOutWidth <= viewportWidth) { // If the flyOut is too close to the right side of the viewport if (flyOutLeft + flyOutWidth > viewableLeft + viewportWidth) { // If we're positioning horizontally and the flyout can fit // launching the other way, try that if (horizontal && isLTR && (launcherLeft - flyOutWidth) > viewableLeft) { flyOutLeft = launcherLeft - flyOutWidth; } // Otherwise, just align along the edge of the viewport else { flyOutLeft = viewableLeft + viewportWidth - flyOutWidth - 5; buttedToRightEdge = true; } changed = true; } // If the flyOut is too close to the left side of the viewport else if (flyOutLeft < viewableLeft) { // If we're positioning horizontally and the flyout can fit // launching the other way, try that if (horizontal && !isLTR && (launcherLeft + launcherWidth + flyOutWidth) < (viewableLeft + viewportWidth)) { flyOutLeft = launcherLeft + launcherWidth; } // Otherwise, just align along the edge of the viewport else { flyOutLeft = viewableLeft + 5; buttedToLeftEdge = true; } changed = true; } else { changed = false; } } // If the flyOut can't fit into the viewport, just align against the appropriate edge else { if (isLTR) { flyOutLeft = viewableLeft; changed = true; } else // RTL { flyOutLeft = viewableLeft + viewportWidth - flyOutWidth; changed = true; } } // If changed, set the styles accordingly if (changed) { flyOut.Style.Left = flyOutLeft + "px"; changed = false; } // Vertical Positioning (not affected by Text Direction) // If the flyOut is too close to the bottom of the viewport, launch the flyOut upwards // We work with the real height of the flyout's content here so that even if it is // currently scrollable, we can see if it still needs to be scrollable if (flyOutTop + flyOutRealHeight > viewableTop + viewportHeight) { // store initial value and viewableHeight int oldflyOutTop = flyOutTop; int oldflyOutViewableHeight = viewableTop + viewportHeight - flyOutTop; flyOutTop = launcherTop - flyOutRealHeight; if (FixedPositioningEnabled) flyOutTop += viewableTop; int newflyOutViewableHeight = launcherTop; if (!FixedPositioningEnabled) newflyOutViewableHeight -= viewableTop; changed = true; // If launching upwards is worse than before, go back to launching downwards if (newflyOutViewableHeight < flyOutRealHeight) { int flyOutWidthWithScrollbar = flyOutWidth + 22; if (newflyOutViewableHeight < oldflyOutViewableHeight) { flyOutTop = oldflyOutTop; // O14:45827 - Enable scrolling and change the height of the menu to fit in the space available flyOut.Style.MaxHeight = (oldflyOutViewableHeight - 5) + "px"; if (!wasScrollable) { flyOut.Style.OverflowY = "scroll"; flyOut.Style.Width = flyOutWidthWithScrollbar + "px"; } if (buttedToRightEdge && isLTR) { flyOutLeft -= 27; // compensate for the added scrollbar flyOut.Style.Left = flyOutLeft + "px"; } else if (buttedToLeftEdge && !isLTR) { flyOutLeft += 27; // compensate for the added scrollbar flyOut.Style.Left = flyOutLeft + "px"; } changed = false; } else { // Can't fit in either direction, but launching upwards is better // Still need to resize the menu and enable scrolling flyOut.Style.MaxHeight = (newflyOutViewableHeight - 5) + "px"; if (!wasScrollable) { flyOut.Style.OverflowY = "scroll"; flyOut.Style.Width = flyOutWidthWithScrollbar + "px"; } if (buttedToRightEdge && isLTR) { flyOutLeft -= 27; // compensate for the added scrollbar flyOut.Style.Left = flyOutLeft + "px"; } else if (buttedToLeftEdge && !isLTR) { flyOutLeft += 27; // compensate for the added scrollbar flyOut.Style.Left = flyOutLeft + "px"; } } if (!wasScrollable) flyOut.SetAttribute("mscui:scrollable", "true"); } else // fits fine when launching upwards { // Revert auto-scroll styles to default if not needed if (wasScrollable) { flyOut.Style.MaxHeight = "none"; flyOut.Style.OverflowY = "visible"; flyOut.Style.Width = "auto"; flyOut.SetAttribute("mscui:scrollable", "false"); } } } else // fits fine vertically { // Revert auto-scroll styles to default if not needed if (wasScrollable) { flyOut.Style.MaxHeight = "none"; flyOut.Style.OverflowY = "visible"; flyOut.Style.Width = "auto"; flyOut.SetAttribute("mscui:scrollable", "false"); } changed = false; } // If changed, set the styles accordingly if (changed) { flyOut.Style.Top = flyOutTop + "px"; changed = false; } }
private void HandleHighlightingAndPreview(HtmlElement cell) { int newIndex = Int32.Parse(cell.GetAttribute("arrayPosition")); // If the cell with the focus has not changed since the last time then there // nothing to change. if (_focusedIndex == newIndex) { return; } // Save the new index _focusedIndex = newIndex; // We should not revert preview. SendClickPreviewCommand(cell); // Adjust the highliting AdjustHighlighting(cell); }
private string CompareNodeAttributes(HtmlElement elm1, HtmlElement elm2) { if (CUIUtility.IsNullOrUndefined(elm1.Attributes)) { if (elm1.InnerText != elm2.InnerText) return ConstructCompareErrorMessage(elm1, elm2, "Text node text mismatched."); else return ""; } for (int i = 0; i < elm1.Attributes.Length; i++) { DomAttribute attr1 = elm1.Attributes[i]; DomAttribute attr2 = elm2.Attributes.GetNamedItem(attr1.Name); // For the unselectable attribute, the client rendered ribbon adds this as an asynchronous // task so it does not appear in this attribute collection. if (CUIUtility.IsNullOrUndefined(attr2) && attr1.Name != "unselectable") { // The exceptions to this: // The "_events" attribute is used by Microsoft Ajax to attach events to the DOM node so it will // not be present in the server rendered DOM. if (attr1.Name != "_events") return ConstructCompareErrorMessage(elm1, elm2, "Attribute: \"" + attr1.Name + "\" is only present in one node."); else continue; } else if (attr1.Name == "unselectable") { string field = elm2.GetAttribute("unselectable"); if (string.IsNullOrEmpty(field) || field != attr1.Value) return ConstructCompareErrorMessage(elm1, elm2, "Attribute values for \"unselectable\" does not match."); } if (attr1.Name.ToLower() != attr2.Name.ToLower()) return ConstructCompareErrorMessage(elm1, elm2, "Attributes at index " + i.ToString() + " have different names: \"" + attr1.Name + "\" and \"" + attr2.Name + "\""); if (attr1.Value.Trim() != attr2.Value.Trim()) { // Handle exceptions here // We ignore the oncontextmenu attribute because this one is attached in the client // via a MicrosoftAjax event handler. if (attr1.Name == "oncontextmenu" && !string.IsNullOrEmpty(elm1.ClassName) && elm1.ClassName.IndexOf("ms-cui-ribbon") != -1) { } else if (attr1.Name == "class" && attr1.Value.Replace("ms-cui-disabled", "").Trim() == attr2.Value.Replace("ms-cui-disabled", "").Trim()) { } // Some elements need unique ids to function correctly. If the only difference is "-client" // then we can ignore the issue. else if (attr1.Name == "id" && attr1.Value.Replace("-client", "").Trim() == attr2.Value.Replace("-client", "").Trim()) { } // We ignore the case where images are not the same size because the image sizes // are not set until the <img> tag is actually rendered so one of these will be "0" // because it has not been put into the DOM. else if (elm1.TagName.ToLower() == "img" && (attr1.Name == "height" || attr1.Name == "width")) { } else if (elm1.TagName.ToLower() == "label" && attr1.Name == "for") { } else if (elm1.TagName.ToLower() == "input" && attr1.Name.ToLower() == "maxlength") { } else { return ConstructCompareErrorMessage(elm1, elm2, "Attribute: \"" + attr1.Name + "\" has different values: \"" + attr1.Value + "\" and \"" + attr2.Value + "\""); } } } return ""; }
private ColorPickerResult GetColorPickerResultFromSelectedCell(HtmlElement cell) { ColorStyle style = (ColorStyle)((JSObject)(object)cell).GetField<object>(ColorInformation); ColorPickerResult result = new ColorPickerResult(); result.Color = cell.GetAttribute(ColorInformation + "Color"); result.Style = cell.GetAttribute(ColorInformation + "Style"); return result; }