// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License.txt in the project root for license information.
///
///
module Helper._CommandingSurface {
"use strict";
var _Constants = Helper.require("WinJS/Controls/CommandingSurface/_Constants");
var _CommandingSurface = Helper.require("WinJS/Controls/CommandingSurface/_CommandingSurface")._CommandingSurface;
export interface ISizeForCommandsArgs {
closedDisplayMode: string;
numStandardCommandsShownInActionArea: number;
numSeparatorsShownInActionArea: number;
widthOfContentCommandsShownInActionArea: number;
isACommandVisbleInTheOverflowArea: boolean;
/*
* Any additonal free space that we would like available in the action area.
*/
additionalFreeSpace: number;
};
export function sizeForCommands(controlElement: HTMLElement, args: ISizeForCommandsArgs) {
// Sizes the width of the control to have enough available space in the
// action area to be able to fit the values specified in args.
// Automatically detects whether or not an overflow button will be needed
// and adds additional space inside the controlElement to cover it.
var closedDisplayMode = args.closedDisplayMode;
var widthForStandardCommands = (args.numStandardCommandsShownInActionArea || 0) * _Constants.actionAreaCommandWidth;
var widthForSeparators = (args.numSeparatorsShownInActionArea || 0) * _Constants.actionAreaSeparatorWidth;
var widthForContentCommands = (args.widthOfContentCommandsShownInActionArea || 0);
var additionalFreeSpace = args.additionalFreeSpace || 0;
var isACommandVisbleInTheOverflowArea = args.isACommandVisbleInTheOverflowArea || false;
var widthForPrimaryCommands = widthForStandardCommands + widthForSeparators + widthForContentCommands;
// Determine if the control will want to display an overflowButton.
var needsOverflowButton = (isACommandVisbleInTheOverflowArea ||
Helper._CommandingSurface.isActionAreaExpandable(closedDisplayMode) && widthForPrimaryCommands > 0);
var widthForOverflowButton = needsOverflowButton ? _Constants.actionAreaOverflowButtonWidth : 0;
var totalWidth = widthForPrimaryCommands + widthForOverflowButton + additionalFreeSpace;
controlElement.style.width = totalWidth + "px";
}
export function isActionAreaExpandable(closedDisplayMode: string): boolean {
var result;
var mode = closedDisplayMode;
switch (mode) {
case _CommandingSurface.ClosedDisplayMode.none:
case _CommandingSurface.ClosedDisplayMode.minimal:
case _CommandingSurface.ClosedDisplayMode.compact:
// These ClosedDisplayModes have an expandable actionarea when shown.
result = true;
break;
case _CommandingSurface.ClosedDisplayMode.full:
// These ClosedDisplayModes do not have an expandable actionarea when shown.
result = false;
break;
default:
LiveUnit.Assert.fail("TEST ERROR: Unknown ClosedDisplayMode enum value: " + mode);
break;
}
return result;
}
export function useSynchronousAnimations(commandingSurface: WinJS.UI.PrivateCommandingSurface) {
commandingSurface.createOpenAnimation = function () {
return {
execute(): WinJS.Promise {
return WinJS.Promise.wrap();
}
};
};
commandingSurface.createCloseAnimation = function () {
return {
execute(): WinJS.Promise {
return WinJS.Promise.wrap();
}
};
};
}
export function useSynchronousDataRendering(commandingSurface: WinJS.UI.PrivateCommandingSurface) {
// Remove delay for batching edits, and render changes synchronously.
commandingSurface._batchDataUpdates = (updateFn) => {
updateFn();
}
}
export function getVisibleCommandsInElement(element: HTMLElement) {
var result: HTMLElement[] = [];
var commands = element.querySelectorAll(_Constants.commandSelector);
for (var i = 0, len = commands.length; i < len; i++) {
if (getComputedStyle(commands[i]).display !== "none") {
result.push(commands[i]);
}
}
return result;
}
export function getProjectedCommandFromOriginalCommand(commandingSurface, originalCommand: WinJS.UI.ICommand): WinJS.UI.PrivateMenuCommand {
// Given an ICommand in the CommandingSurface, find and return its MenuCommand projection from the overflowarea, if such a projection exists.
var projectedCommands = getVisibleCommandsInElement(commandingSurface._dom.overflowArea).map(function (element) {
return element.winControl;
});
var matches = projectedCommands.filter(function (projection) {
return originalCommand === projection["_originalICommand"];
});
if (matches.length > 1) {
LiveUnit.Assert.fail("TEST ERROR: CommandingSurface should not project more than 1 MenuCommand into the overflowarea for each ICommand in the actionarea.");
}
return matches[0];
};
export function verifyOverflowMenuContent(visibleElements: HTMLElement[], expectedLabels: string[]): void {
var labelIndex = 0;
for (var i = 0, len = visibleElements.length; i < len; i++) {
if (visibleElements[i]["winControl"].type === _Constants.typeSeparator) {
LiveUnit.Assert.areEqual(expectedLabels[labelIndex], _Constants.typeSeparator);
} else {
LiveUnit.Assert.areEqual(expectedLabels[labelIndex], visibleElements[i]["winControl"].label);
}
labelIndex++;
}
}
export function verifyActionAreaVisibleCommandsLabels(commandingSurface: WinJS.UI.PrivateCommandingSurface, labels: string[]) {
var commands = getVisibleCommandsInElement((commandingSurface.element.winControl)._dom.actionArea);
LiveUnit.Assert.areEqual(labels.length, commands.length);
labels.forEach((label, index) => {
LiveUnit.Assert.areEqual(label, commands[index].winControl.label);
});
}
export function verifyOverflowAreaCommandsLabels(commandingSurface: WinJS.UI.PrivateCommandingSurface, labels: string[]) {
var control = commandingSurface.element.winControl;
var commands = getVisibleCommandsInElement(control._dom.overflowArea);
LiveUnit.Assert.areEqual(labels.length, commands.length);
labels.forEach((label, index) => {
LiveUnit.Assert.areEqual(label, commands[index].winControl.label);
});
}
//
// Verify correct rendered states for opened and closed _CommandingSurface
//
function verifyActionArea_FullyExpanded(commandingSurface: WinJS.UI.PrivateCommandingSurface){
// We expect the action area to be fully expanded whenever the _CommandingSurface is closed with closedDisplayMode: full,
// or whenever the _CommandingSurface is opened, regardless of closedDidsplayMode.
var commandElements = Helper._CommandingSurface.getVisibleCommandsInElement(commandingSurface._dom.actionArea);
var commandingSurfaceTotalHeight = WinJS.Utilities._getPreciseTotalHeight(commandingSurface.element);
var actionAreaTotalHeight = WinJS.Utilities._getPreciseTotalHeight(commandingSurface._dom.actionArea);
var actionAreaContentBoxHeight = WinJS.Utilities._getPreciseContentHeight(commandingSurface._dom.actionArea);
var isOverflowButtonVisible = (commandingSurface._dom.overflowButton.style.display === "none") ? false : true;
var overflowButtonTotalHeight = WinJS.Utilities._getPreciseTotalHeight(commandingSurface._dom.overflowButton);
var heightOfTallestChildElement: number = Array.prototype.reduce.call(commandingSurface._dom.actionArea.children, function (tallest, element) {
return Math.max(tallest, WinJS.Utilities._getPreciseTotalHeight(element));
}, 0);
LiveUnit.Assert.areEqual(actionAreaTotalHeight, commandingSurfaceTotalHeight, "Height of CommandingSurface should size to its actionarea.");
LiveUnit.Assert.areEqual(heightOfTallestChildElement, actionAreaContentBoxHeight, "Actionarea height should be fully expanded and size to the heights of its content");
if (isOverflowButtonVisible) {
LiveUnit.Assert.areEqual(actionAreaTotalHeight, overflowButtonTotalHeight, "overflowButton should stretch to the height of the actionarea");
}
// Verify commands are displayed.
if (Array.prototype.some.call(commandElements, function (commandEl) {
return getComputedStyle(commandEl).display === "none";
})) {
LiveUnit.Assert.fail("Opened actionarea should always display primary commands.");
}
// Verify command labels are displayed.
if (Array.prototype.some.call(commandElements, function (commandEl) {
var label = commandEl.querySelector(".win-label");
return (label && getComputedStyle(label).display == "none");
})) {
LiveUnit.Assert.fail("Opened actionarea should display primary command labels");
}
}
export function verifyRenderedOpened(commandingSurface: WinJS.UI.PrivateCommandingSurface) {
// Verifies actionarea and overflowarea are opened.
// Currently only works if there is at least one command in the actionarea and overflow area.
verifyOpened_actionArea(commandingSurface);
verifyOpened_overflowArea(commandingSurface);
};
function verifyOpened_actionArea(commandingSurface: WinJS.UI.PrivateCommandingSurface) {
verifyActionArea_FullyExpanded(commandingSurface);
// Verify overflow button aria-expanded
var overflowButton_AriaExpanded = commandingSurface._dom.overflowButton.getAttribute("aria-expanded");
LiveUnit.Assert.areEqual("true", overflowButton_AriaExpanded);
};
function verifyOpened_overflowArea(commandingSurface: WinJS.UI.PrivateCommandingSurface) {
LiveUnit.Assert.areNotEqual("none", getComputedStyle(commandingSurface._dom.overflowArea).display);
var overflowAreaTotalHeight = WinJS.Utilities._getPreciseTotalHeight(commandingSurface._dom.overflowArea);
var overflowCommands = getVisibleCommandsInElement(commandingSurface._dom.overflowArea);
if (overflowCommands.length) {
LiveUnit.Assert.isTrue(0 < overflowAreaTotalHeight);
} else {
LiveUnit.Assert.isTrue(0 === overflowAreaTotalHeight, "Opened overflowArea should not be visible if there are no overflow commands");
}
};
export function verifyRenderedClosed(commandingSurface: WinJS.UI.PrivateCommandingSurface) {
// Verifies actionarea and overflowarea are closed.
// Currently only works if their is at least one command in the actionarea and overflow area.
verifyClosed_actionArea(commandingSurface);
verifyClosed_oveflowArea(commandingSurface);
};
function verifyClosed_actionArea(commandingSurface: WinJS.UI.PrivateCommandingSurface) {
var closedDisplayMode = commandingSurface.closedDisplayMode;
var commandElements = Helper._CommandingSurface.getVisibleCommandsInElement(commandingSurface._dom.actionArea),
commandingSurfaceTotalHeight = WinJS.Utilities._getPreciseTotalHeight(commandingSurface.element),
actionAreaTotalHeight = WinJS.Utilities._getPreciseTotalHeight(commandingSurface._dom.actionArea),
actionAreaContentBoxHeight = WinJS.Utilities._getPreciseContentHeight(commandingSurface._dom.actionArea),
overflowButtonTotalHeight = WinJS.Utilities._getPreciseTotalHeight(commandingSurface._dom.overflowButton);
switch (closedDisplayMode) {
case _CommandingSurface.ClosedDisplayMode.none:
LiveUnit.Assert.areEqual("none", getComputedStyle(commandingSurface.element).display);
LiveUnit.Assert.areEqual(0, actionAreaTotalHeight);
LiveUnit.Assert.areEqual(0, overflowButtonTotalHeight);
break;
case _CommandingSurface.ClosedDisplayMode.minimal:
LiveUnit.Assert.areEqual(actionAreaTotalHeight, commandingSurfaceTotalHeight, "Height of CommandingSurface should size to its actionarea.");
LiveUnit.Assert.areEqual(_Constants.heightOfMinimal, actionAreaContentBoxHeight, "invalid ActionArea content height for 'minimal' closedDisplayMode");
LiveUnit.Assert.areEqual(actionAreaContentBoxHeight, overflowButtonTotalHeight, "overflowButton should stretch to the height of the actionarea");
// Verify commands are not displayed.
if (Array.prototype.some.call(commandElements, function (commandEl) {
return getComputedStyle(commandEl).display !== "none";
})) {
LiveUnit.Assert.fail("CommandingSurface with 'minimal' closedDisplayMode should not display primary commands.");
}
break;
case _CommandingSurface.ClosedDisplayMode.compact:
LiveUnit.Assert.areEqual(actionAreaTotalHeight, commandingSurfaceTotalHeight, "Height of CommandingSurface should size to its actionarea.");
LiveUnit.Assert.areEqual(_Constants.heightOfCompact, actionAreaContentBoxHeight, "invalid ActionArea content height for 'compact' closedDisplayMode");
LiveUnit.Assert.areEqual(actionAreaContentBoxHeight, overflowButtonTotalHeight, "overflowButton should stretch to the height of the actionarea");
// Verify commands are displayed.
if (Array.prototype.some.call(commandElements, function (commandEl) {
return getComputedStyle(commandEl).display === "none";
})) {
LiveUnit.Assert.fail("CommandingSurface with 'compact' closedDisplayMode should display primary commands.");
}
// Verify command labels are not displayed.
if (Array.prototype.some.call(commandElements, function (commandEl) {
var label = commandEl.querySelector(".win-label");
return (label && getComputedStyle(label).display !== "none");
})) {
LiveUnit.Assert.fail("CommandingSurface with 'compact' closedDisplayMode should not display primary command labels.");
}
break;
case _CommandingSurface.ClosedDisplayMode.full:
// closedDisplayMode: full should render the action area fully expanded.
verifyActionArea_FullyExpanded(commandingSurface);
break;
default:
LiveUnit.Assert.fail("TEST ERROR: Encountered unknown ClosedDisplayMode enum value: " + closedDisplayMode);
break;
}
// Verify overflow button aria-expanded
var overflowButton_AriaExpanded = commandingSurface._dom.overflowButton.getAttribute("aria-expanded");
LiveUnit.Assert.areEqual("false", overflowButton_AriaExpanded)
}
function verifyClosed_oveflowArea(commandingSurface: WinJS.UI.PrivateCommandingSurface) {
var overflowAreaTotalHeight = WinJS.Utilities._getPreciseTotalHeight(commandingSurface._dom.overflowArea);
LiveUnit.Assert.areEqual(0, overflowAreaTotalHeight);
};
};