UNPKG

vexflow

Version:

A JavaScript library for rendering music notation and guitar tablature.

137 lines (128 loc) 5.32 kB
// [VexFlow](https://vexflow.com) - Copyright (c) Mohit Muthanna 2010. // Author: Ron B. Yeh // MIT License import { Accidental } from './accidental'; import { Annotation } from './annotation'; import { Dot } from './dot'; import { GraceNote } from './gracenote'; import { GraceNoteGroup } from './gracenotegroup'; import { Note } from './note'; import { RenderContext } from './rendercontext.js'; import { Barline } from './stavebarline'; import { StaveNote } from './stavenote'; import { StemmableNote } from './stemmablenote'; import { TabNote } from './tabnote'; /* eslint-disable @typescript-eslint/no-explicit-any */ /** * Use instead of `instanceof` as a more flexible type guard. * @param obj check if this object's CATEGORY matches the provided category. * @param category a string representing a category of VexFlow objects. * @param checkAncestors defaults to `true`, so we walk up the prototype chain to look for a matching `CATEGORY`. * If `false`, we do not check the superclass or other ancestors. * @returns true if `obj` has a static `CATEGORY` property that matches `category`. */ export function isCategory<T>(obj: any, category: string, checkAncestors: boolean = true): obj is T { // obj is undefined, a number, a primitive string, or null. if (typeof obj !== 'object' || obj === null) { return false; } // `obj.constructor` is a reference to the constructor function that created the `obj` instance. // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor let constructorFcn = obj.constructor; // Check if the object's static .CATEGORY matches the provided category. if (checkAncestors) { // Walk up the prototype chain to look for a matching obj.constructor.CATEGORY. while (obj !== null) { constructorFcn = obj.constructor; if ('CATEGORY' in constructorFcn && constructorFcn.CATEGORY === category) { return true; } obj = Object.getPrototypeOf(obj); } return false; } else { // Do not walk up the prototype chain. Just check this particular object's static .CATEGORY string. return 'CATEGORY' in constructorFcn && constructorFcn.CATEGORY === category; } } export const isAccidental = (obj: unknown): obj is Accidental => isCategory(obj, Category.Accidental); export const isAnnotation = (obj: unknown): obj is Annotation => isCategory(obj, Category.Annotation); export const isBarline = (obj: unknown): obj is Barline => isCategory(obj, Category.Barline); export const isDot = (obj: unknown): obj is Dot => isCategory(obj, Category.Dot); export const isGraceNote = (obj: unknown): obj is GraceNote => isCategory(obj, Category.GraceNote); export const isGraceNoteGroup = (obj: unknown): obj is GraceNoteGroup => isCategory(obj, Category.GraceNoteGroup); export const isNote = (obj: unknown): obj is Note => isCategory(obj, Category.Note); export const isRenderContext = (obj: unknown): obj is RenderContext => isCategory(obj, Category.RenderContext); export const isStaveNote = (obj: unknown): obj is StaveNote => isCategory(obj, Category.StaveNote); export const isStemmableNote = (obj: unknown): obj is StemmableNote => isCategory(obj, Category.StemmableNote); export const isTabNote = (obj: unknown): obj is TabNote => isCategory(obj, Category.TabNote); // 'const' enums are erased by the TypeScript compiler. The string values are inlined at all the use sites. // See: https://www.typescriptlang.org/docs/handbook/enums.html#const-enums export const enum Category { Accidental = 'Accidental', Annotation = 'Annotation', Articulation = 'Articulation', Barline = 'Barline', BarNote = 'BarNote', Beam = 'Beam', Bend = 'Bend', ChordSymbol = 'ChordSymbol', Clef = 'Clef', ClefNote = 'ClefNote', Crescendo = 'Crescendo', Curve = 'Curve', Dot = 'Dot', Element = 'Element', Fraction = 'Fraction', FretHandFinger = 'FretHandFinger', GhostNote = 'GhostNote', Glyph = 'Glyph', GlyphNote = 'GlyphNote', GraceNote = 'GraceNote', GraceNoteGroup = 'GraceNoteGroup', GraceTabNote = 'GraceTabNote', KeySignature = 'KeySignature', KeySigNote = 'KeySigNote', Modifier = 'Modifier', MultiMeasureRest = 'MultiMeasureRest', Note = 'Note', NoteHead = 'NoteHead', NoteSubGroup = 'NoteSubGroup', Ornament = 'Ornament', Parenthesis = 'Parenthesis', PedalMarking = 'PedalMarking', RenderContext = 'RenderContext', RepeatNote = 'RepeatNote', Repetition = 'Repetition', Stave = 'Stave', StaveConnector = 'StaveConnector', StaveHairpin = 'StaveHairpin', StaveLine = 'StaveLine', StaveModifier = 'StaveModifier', StaveNote = 'StaveNote', StaveSection = 'StaveSection', StaveTempo = 'StaveTempo', StaveText = 'StaveText', StaveTie = 'StaveTie', Stem = 'Stem', StemmableNote = 'StemmableNote', StringNumber = 'StringNumber', Stroke = 'Stroke', System = 'System', TabNote = 'TabNote', TabSlide = 'TabSlide', TabStave = 'TabStave', TabTie = 'TabTie', TextBracket = 'TextBracket', TextDynamics = 'TextDynamics', TextNote = 'TextNote', Tickable = 'Tickable', TimeSignature = 'TimeSignature', TimeSigNote = 'TimeSigNote', Tremolo = 'Tremolo', Tuplet = 'Tuplet', Vibrato = 'Vibrato', VibratoBracket = 'VibratoBracket', Voice = 'Voice', Volta = 'Volta', }