@progress/kendo-angular-menu
Version:
Kendo UI Angular Menu component
193 lines (192 loc) • 5.98 kB
JavaScript
/**-----------------------------------------------------------------------------------------
* Copyright © 2025 Progress Software Corporation. All rights reserved.
* Licensed under commercial license. See LICENSE.md in the project root for more information
*-------------------------------------------------------------------------------------------*/
import { NgZone, Injectable } from '@angular/core';
import { ItemsService } from './items.service';
import { hasObservers, PreventableEvent } from '@progress/kendo-angular-common';
import * as i0 from "@angular/core";
import * as i1 from "./items.service";
const canPerformAction = (item, action) => !((action === 'open' && item.opened) || (action === 'close' && !item.opened));
/**
* Used to remove cyclic dependency error. Dublicates MenuEvent
* @hidden
*/
export class MenuStateEvent extends PreventableEvent {
/**
* The MenuComponent that triggered the event.
*/
sender;
/**
* The item data of the event.
*/
item;
/**
* The item index of the event.
*/
index;
constructor(args) {
super();
Object.assign(this, args);
}
}
/**
* @hidden
*/
export class ActionsService {
ngZone;
items;
owner;
actions = [];
constructor(ngZone, items) {
this.ngZone = ngZone;
this.items = items;
}
open(item, finished) {
if (item.disabled) {
return;
}
if (item.hasContent && !item.opened) {
this.actions.push({
name: 'open',
requiresZone: item.hasContentTemplates(),
item,
finished
});
}
else if (finished) {
finished();
}
}
close(item) {
this.closeChildren(item);
this.closeItem(item);
}
closeItem(item) {
if (item.opened) {
this.actions.push({
name: 'close',
item
});
}
}
closeToRoot(item) {
this.closeChildren(item);
let current = item;
do {
this.closeItem(current);
current = this.items.parent(current);
} while (current);
}
closeOthers(item) {
this.closeChildren(item);
let current = item;
while (current) {
const siblings = this.items.otherSiblings(current);
this.closeItems(siblings);
current = this.items.parent(current);
}
}
closeAll() {
this.items.forEach((item) => {
if (item.opened && item.level === 0) {
this.close(item);
}
});
}
select(item, domEvent, prevented, finished) {
this.actions.push({
name: 'select',
item,
prevented,
finished,
domEvent
});
}
emit(name, item, domEvent) {
const owner = this.owner;
const eventArgs = new MenuStateEvent({
sender: owner,
item: item.item,
index: item.index,
originalEvent: domEvent,
hasContent: item.hasContent
});
owner[name].emit(eventArgs);
if (owner.contextService) {
owner.contextService.emit(name, eventArgs);
}
return eventArgs.isDefaultPrevented();
}
get hasPending() {
return this.actions.length > 0;
}
execute(toExecute) {
if (!this.hasPending && !toExecute) {
return;
}
const actions = toExecute || this.clear();
if (!NgZone.isInAngularZone() && this.requiresZone(actions)) {
this.ngZone.run(() => {
this.executeActions(actions);
});
}
else {
this.executeActions(actions);
}
}
clear() {
const actions = this.actions;
this.actions = [];
return actions;
}
executeActions(actions) {
for (let idx = 0; idx < actions.length; idx++) {
const { item, name, prevented, finished, domEvent } = actions[idx];
if (!canPerformAction(item, name)) {
continue;
}
if (!this.emit(name, item, domEvent)) {
if (item[name]) {
item[name]();
}
if (finished) {
finished();
}
}
else if (prevented) {
prevented();
}
}
}
requiresZone(toExecute) {
const actions = toExecute || this.actions;
const owner = this.owner;
const contextService = owner.contextService;
for (let idx = 0; idx < actions.length; idx++) {
const action = actions[idx];
const name = action.name;
if (action.requiresZone || (name && (hasObservers(owner[name]) || (contextService && contextService.hasObservers(name))))) {
return true;
}
}
return false;
}
closeChildren(item) {
if (!item.opened) {
return;
}
const children = this.items.children(item);
this.closeItems(children);
}
closeItems(items) {
for (let idx = 0; idx < items.length; idx++) {
this.close(items[idx]);
}
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ActionsService, deps: [{ token: i0.NgZone }, { token: i1.ItemsService }], target: i0.ɵɵFactoryTarget.Injectable });
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ActionsService });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ActionsService, decorators: [{
type: Injectable
}], ctorParameters: function () { return [{ type: i0.NgZone }, { type: i1.ItemsService }]; } });