📄 sync.menu.js
字号:
Core.Web.Event.add(this.element, "click", Core.method(this, this._processClick), false); Core.Web.Event.add(this.element, "mouseover", Core.method(this, this._processItemEnter), false); Core.Web.Event.add(this.element, "mouseout", Core.method(this, this._processItemExit), false); Core.Web.Event.Selection.disable(this.element); }, close: function() { Core.Web.Event.removeAll(this.element); document.body.removeChild(this.element); this.element = null; this.itemElements = null; this._activeItem = null; }, create: function() { var i, item, img, menuItemContentTd, menuItemIconTd, menuItemTr; this.element = document.createElement("div"); this.element.style.position = "absolute"; this.element.style.zIndex = Extras.Sync.Menu.MAX_Z_INDEX; var opacity = (Core.Web.Env.NOT_SUPPORTED_CSS_OPACITY ? 100 : this.component.render("menuOpacity", 100)) / 100; var menuContentDiv = document.createElement("div"); menuContentDiv.style.cssText = "position:relative;z-index:10;"; this.element.appendChild(menuContentDiv); Echo.Sync.LayoutDirection.render(this.component.getLayoutDirection(), menuContentDiv); Echo.Sync.Insets.render(Extras.Sync.Menu.RenderedMenu.defaultMenuInsets, menuContentDiv, "padding"); Echo.Sync.Border.render(this.component.render("menuBorder", Extras.Sync.Menu.DEFAULT_BORDER), menuContentDiv); var foreground; var menuForeground = this.component.render("menuForeground"); if (menuForeground) { foreground = menuForeground; } else { foreground = this.component.render("foreground", Extras.Sync.Menu.DEFAULT_FOREGROUND); } Echo.Sync.Color.render(foreground, menuContentDiv, "color"); // Apply menu font if it is set, or apply default font // if it is set and the menu font is NOT set. var font = this.component.render("menuFont"); if (!font) { font = this.component.render("font"); } if (font) { Echo.Sync.Font.render(font, menuContentDiv); } var backgroundDiv; if (opacity < 1) { backgroundDiv = document.createElement("div"); backgroundDiv.style.cssText = "position:absolute;z-index:1;width:100%;height:100%;top:0;bottom:0;"; backgroundDiv.style.opacity = opacity; this.element.appendChild(backgroundDiv); } else { backgroundDiv = this.element; } var background; var menuBackground = this.component.render("menuBackground"); if (menuBackground) { background = menuBackground; } else { background = this.component.render("background", Extras.Sync.Menu.DEFAULT_BACKGROUND); } Echo.Sync.Color.render(background, backgroundDiv, "backgroundColor"); // Apply menu background image if it is set, or apply default background // image if it is set and the menu background is NOT set. var backgroundImage; var menuBackgroundImage = this.component.render("menuBackgroundImage"); if (menuBackgroundImage) { backgroundImage = menuBackgroundImage; } else if (menuBackground == null) { backgroundImage = this.component.render("backgroundImage"); } if (backgroundImage) { Echo.Sync.FillImage.render(backgroundImage, backgroundDiv, null); } var menuTable = document.createElement("table"); menuTable.style.borderCollapse = "collapse"; menuContentDiv.appendChild(menuTable); var menuTbody = document.createElement("tbody"); menuTable.appendChild(menuTbody); var items = this.menuModel.items; // Determine if any icons are present. var hasIcons = false; for (i = 0; i < items.length; ++i) { item = items[i]; if (item.icon || item instanceof Extras.ToggleOptionModel) { hasIcons = true; break; } } var textPadding, iconPadding; if (hasIcons) { var pixelInsets = Echo.Sync.Insets.toPixels(Extras.Sync.Menu.RenderedMenu.defaultMenuItemInsets); iconPadding = "0px 0px 0px " + pixelInsets.left + "px"; textPadding = pixelInsets.top + "px " + pixelInsets.right + "px " + pixelInsets.bottom + "px " + pixelInsets.left + "px"; } else { textPadding = Extras.Sync.Menu.RenderedMenu.defaultMenuItemInsets; } for (i = 0; i < items.length; ++i) { item = items[i]; if (item instanceof Extras.OptionModel || item instanceof Extras.MenuModel) { menuItemTr = document.createElement("tr"); this.itemElements[item.id] = menuItemTr; menuItemTr.style.cursor = "pointer"; menuTbody.appendChild(menuItemTr); if (hasIcons) { menuItemIconTd = document.createElement("td"); Echo.Sync.Insets.render(iconPadding, menuItemIconTd, "padding"); if (item instanceof Extras.ToggleOptionModel) { var iconIdentifier; var selected = this.stateModel && this.stateModel.isSelected(item.modelId); if (item instanceof Extras.RadioOptionModel) { iconIdentifier = selected ? "image/menu/RadioOn.gif" : "image/menu/RadioOff.gif"; } else { iconIdentifier = selected ? "image/menu/ToggleOn.gif" : "image/menu/ToggleOff.gif"; } img = document.createElement("img"); img.src = this.client.getResourceUrl("Extras", iconIdentifier); menuItemIconTd.appendChild(img); } else if (item.icon) { img = document.createElement("img"); Echo.Sync.ImageReference.renderImg(item.icon, img); menuItemIconTd.appendChild(img); } menuItemTr.appendChild(menuItemIconTd); } menuItemContentTd = document.createElement("td"); Echo.Sync.Insets.render(textPadding, menuItemContentTd, "padding"); var lineWrap = this.component.render("lineWrap"); if (lineWrap != null && !lineWrap) { menuItemContentTd.style.whiteSpace = "nowrap"; } if (this.stateModel && !this.stateModel.isEnabled(item.modelId)) { Echo.Sync.Color.render(this.component.render("disabledForeground", Extras.Sync.Menu.DEFAULT_DISABLED_FOREGROUND), menuItemContentTd, "color"); } menuItemContentTd.appendChild(document.createTextNode(item.text)); menuItemTr.appendChild(menuItemContentTd); if (item instanceof Extras.MenuModel) { // Submenus have adjacent column containing 'expand' icons. var menuItemArrowTd = document.createElement("td"); menuItemArrowTd.style.textAlign = "right"; img = document.createElement("img"); var expandImage = this.component.render("menuExpandIcon", this.client.getResourceUrl("Extras", "image/menu/ArrowRight.gif")); img.setAttribute("src", expandImage.url ? expandImage.url : expandImage); img.setAttribute("alt", ""); menuItemArrowTd.appendChild(img); menuItemTr.appendChild(menuItemArrowTd); } else { // Menu items fill both columns. menuItemContentTd.colSpan = 2; } } else if (item instanceof Extras.SeparatorModel) { if (i === 0 || i === items.length - 1 || items[i - 1] instanceof Extras.SeparatorModel || items[i + 1] instanceof Extras.SeparatorModel) { // Ignore separators at zero position. continue; } menuItemTr = document.createElement("tr"); menuTbody.appendChild(menuItemTr); menuItemContentTd = document.createElement("td"); menuItemContentTd.colSpan = hasIcons ? 3 : 2; menuItemContentTd.style.padding = "3px 0px"; var hrDiv = document.createElement("div"); hrDiv.style.cssText = "border-top:1px solid #a7a7a7;height:0;font-size:1px;line-height:0"; menuItemContentTd.appendChild(hrDiv); menuItemTr.appendChild(menuItemContentTd); } } var bounds = new Core.Web.Measure.Bounds(this.element); this.width = bounds.width; this.height = bounds.height; }, _getItemElement: function(element) { if (element == null) { return null; } // Find TD element. while (element.nodeName.toLowerCase() != "tr") { if (element == this.element) { return null; } element = element.parentNode; } return element; }, _getItemModel: function(element) { var itemModelId = null; element = this._getItemElement(element); if (element == null) { return null; } // Find item model id of clicked element. for (var x in this.itemElements) { if (this.itemElements[x] == element) { itemModelId = x; break; } } if (itemModelId == null) { return null; } else { return this.menuModel.findItem(itemModelId); } }, getSubMenuPosition: function(menuModel, width, height) { var menuElement = this.itemElements[menuModel.id]; var itemBounds = new Core.Web.Measure.Bounds(menuElement); var menuBounds = new Core.Web.Measure.Bounds(this.element); return { x: menuBounds.left + menuBounds.width, y: itemBounds.top }; }, _processClick: function(e) { Core.Web.DOM.preventEventDefault(e); var itemModel = this._getItemModel(Core.Web.DOM.getEventTarget(e)); if (itemModel) { this._setActiveItem(itemModel, true); } }, _processItemEnter: function(e) { this._processRollover(e, true); }, _processItemExit: function(e) { this._processRollover(e, false); }, _processRollover: function(e, state) { if (!this.client || !this.client.verifyInput(this.component) || Core.Web.dragInProgress) { return true; } var element = this._getItemElement(Core.Web.DOM.getEventTarget(e)); if (!element) { return; } var itemModel = this._getItemModel(element); if (!itemModel) { return; } if (this.stateModel && !this.stateModel.isEnabled(itemModel.modelId)) { return; } if (state) { this._setActiveItem(itemModel, false); } }, _setActiveItem: function(itemModel, execute) { if (this._activeItem) { this._setItemHighlight(this._activeItem, false); this._activeItem = null; } if (itemModel instanceof Extras.MenuModel) { this.menuSync.activateItem(itemModel); } else { if (execute) { this.menuSync.activateItem(itemModel); // Executing item, menu will close: return immediately. return; } else { this.menuSync.closeDescendants(this); } } if (itemModel) { this._activeItem = itemModel; this._setItemHighlight(this._activeItem, true); } }, _setItemHighlight: function(itemModel, state) { var element = this.itemElements[itemModel.id]; if (state) { Echo.Sync.FillImage.render(this.component.render("selectionBackgroundImage"), element); Echo.Sync.Color.render(this.component.render("selectionBackground", Extras.Sync.Menu.DEFAULT_SELECTION_BACKGROUND), element, "backgroundColor"); Echo.Sync.Color.render(this.component.render("selectionForeground", Extras.Sync.Menu.DEFAULT_SELECTION_FOREGROUND), element, "color"); } else { element.style.backgroundImage = ""; element.style.backgroundColor = ""; element.style.color = ""; } }});/** * Component rendering peer: ContextMenu */Extras.Sync.ContextMenu = Core.extend(Extras.Sync.Menu, { $load: function() { Echo.Render.registerPeer("Extras.ContextMenu", this); }, _mouseX: null, _mouseY: null, getSubMenuPosition: function(menuModel, width, height) { return { x: this._mouseX, y: this._mouseY }; }, _processContextClick: function(e) { if (!this.client || !this.client.verifyInput(this.component) || Core.Web.dragInProgress) { return true; } Core.Web.DOM.preventEventDefault(e); this._mouseX = e.pageX || (e.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft)); this._mouseY = e.pageY || (e.clientY + (document.documentElement.scrollTop || document.body.scrollTop)); this.activate(); this.activateItem(this.menuModel); }, renderDispose: function(update) { Core.Web.Event.removeAll(this.element); Extras.Sync.Menu.prototype.renderDispose.call(this, update); }, renderMain: function(update) { var contextMenuDiv = document.createElement("div"); contextMenuDiv.id = this.component.renderId; var activationMode = this.component.render("activationMode", Extras.ContextMenu.ACTIVATION_MODE_CONTEXT_CLICK); if (activationMode & Extras.ContextMenu.ACTIVATION_MODE_CLICK) { Core.Web.Event.add(contextMenuDiv, "click", Core.method(this, this._processContextClick), false); } if (activationMode & Extras.ContextMenu.ACTIVATION_MODE_CONTEXT_CLICK) { Core.Web.Event.add(contextMenuDiv, "contextmenu", Core.method(this, this._processContextClick), false); } var componentCount = this.component.getComponentCount(); if (componentCount > 0) { Echo.Render.renderComponentAdd(update, this.component.getComponent(0), contextMenuDiv); } return contextMenuDiv; }, renderUpdate: function(update) { if (update.isUpdatedPropertySetIn({ stateModel: true, model: true })) { // partial update var removedChildren = update.getRemovedChildren(); if (removedChildren) { Core.Web.DOM.removeNode(this.element.firstChild); } var addedChildren = update.getAddedChildren(); if (addedChildren) { Echo.Render.renderComponentAdd(update, addedChildren[0], this.element); } var modelUpdate = update.getUpdatedProperty("model"); var stateModelUpdate = update.getUpdatedProperty("stateModel"); var reOpenMenu = this.maskDeployed && (modelUpdate || stateModelUpdate); if (reOpenMenu) { this.deactivate(); } if (modelUpdate) { this.menuModel = modelUpdate.newValue; } if (stateModelUpdate) { this.stateModel = stateModelUpdate.newValue; } if (reOpenMenu) { this.activate(); this.activateItem(this.menuModel); } return false; } // full update Extras.Sync.Menu.prototype.renderUpdate.call(this, update); return true; }});//FIXME 'selection' property should be an itemmodel id. We should have a remote peer for this path-string business./** * Component rendering peer: DropDownMenu */Extras.Sync.DropDownMenu = Core.extend(Extras.Sync.Menu, { $load: function() {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -