import { Settings } from "./settings" ; /**
 * Favorite type definitions.
 */ export enum FavoriteType { Folder = 0 , Note = 1 , Todo = 2 , Tag = 3 , Search = 4 } /**
 * Definition of favorite entries.
 */ export interface IFavorite { value : string ; title : string ; type : FavoriteType ; } /**
 * Definition of the favorite descriptions.
 */ interface IFavoriteDesc { readonly name : string ; readonly icon : string ; readonly dataType : string ; readonly label : string ; } /**
 * Array of favorite descriptions. Order must match with FavoriteType enum.
 */ const FavoriteDesc = [ { name : 'Notebook' , icon : 'fa-book' , dataType : 'folders' , label : 'Full path' } , { name : 'Note' , icon : 'fa-file-alt' , dataType : 'notes' , label : 'Full path' } , { name : 'To-do' , icon : 'fa-check-square' , dataType : 'notes' , label : 'Full path' } , { name : 'Tag' , icon : 'fa-tag' , dataType : 'tags' , label : 'Tag' } , { name : 'Search' , icon : 'fa-search' , dataType : 'searches' , label : 'Search query' } ] ; /**
 * Helper class to work with favorites.
 * - Read settings array once at startup.
 * - Then work on this.favorites array.
 */ export class Favorites { private _settings : Settings ; /**
     * Initialization of Favorites.
     */ constructor ( settings ) { this . _settings = settings ; } /**
     * All favorites.
     */ get favorites ( ) : IFavorite [ ] { return this . _settings . favorites ; } /**
     * Number of favorites.
     */ get length ( ) : number { return this . favorites . length ; } /**
     * Write tabs array back to settings.
     *
     * TODO: Would be better in an "onClose()" event of the plugin. Then they would only be stored once.
     */ private async store ( ) { await this . _settings . storeFavorites ( ) ; } /**
     * Gets a value whether the handled index would lead to out of bound access.
     */ private indexOutOfBounds ( index ) { return ( index < 0 || index >= this . length ) ; } /**
     * Escapes HTML special characters.
     * From https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/toc/src/index.ts
     */ private encodeHtml ( unsafe , trim ) { let val = unsafe . replace ( /&/g , "&amp;" ) . replace ( /</g , "&lt;" ) . replace ( />/g , "&gt;" ) . replace ( /"/g , "&quot;" ) . replace ( /'/g , "&#039;" ) ; return trim ? val . trim ( ) : val ; } /**
     * Decodes escaped HTML characters back.
     */ private decodeHtml ( unsafe , trim ) { let val = unsafe . replace ( /&amp;/g , "&" ) . replace ( /&lt;/g , "<" ) . replace ( /&gt;/g , ">" ) . replace ( /&quot;/g , '"' ) . replace ( /&#039;/g , "'" ) ; return trim ? val . trim ( ) : val ; } static isNote ( favorite ) { if ( favorite ) { return ( favorite . type === FavoriteType . Note ) ; } return false ; } static isTodo ( favorite ) { if ( favorite ) { return ( favorite . type === FavoriteType . Todo ) ; } return false ; } static isSearch ( favorite ) { if ( favorite ) { return ( favorite . type === FavoriteType . Search ) ; } return false ; } static getDesc ( favorite ) { if ( favorite === undefined ) return ; return FavoriteDesc [ favorite . type ] ; } /**
     * Gets the favorites with the handled value. Null if not exist.
     */ get ( index ) { if ( this . indexOutOfBounds ( index ) ) return ; return this . favorites [ index ] ; } /**
     * Gets the HTML decoded value of the handled favorite.
     * Workaround to copy search strings to clipboard.
     */ getDecodedValue ( favorite ) { if ( favorite === undefined ) return ; return this . decodeHtml ( favorite . value , ! Favorites . isSearch ( favorite ) ) ; } /**
     * Gets index of favorite with handled value. -1 if not exist.
     */ indexOf ( value ) { if ( value ) { for ( let i = 0 ; i < this . length ; i ++ ) { if ( this . favorites [ i ] [ 'value' ] === value ) return i ; } } return - 1 ; } /**
     * Gets a value whether a favorite with the handled value exists or not.
     */ hasFavorite ( value ) { return this . indexOf ( value ) < 0 ? false : true ; } /**
     * Creates new instance of IFavorite.
     */ create ( newValue , newTitle , newType ) { const newFavorite = { value : this . encodeHtml ( newValue , ( newType != FavoriteType . Search ) ) , title : this . encodeHtml ( newTitle , true ) , type : newType } ; return newFavorite ; } /**
     * Adds note as new favorite at the handled index or at the end.
     */ async add ( newValue , newTitle , newType , targetIdx ? ) { if ( newValue === undefined || newTitle === undefined || newType === undefined ) return ; const newFavorite = this . create ( newValue , newTitle , newType ) ; if ( targetIdx && targetIdx > 0 ) { this . favorites . splice ( targetIdx , 0 , newFavorite ) ; } else { this . favorites . push ( newFavorite ) ; } await this . store ( ) ; } /**
     * Changes the value of the handled favorite.
     */ async changeValue ( index , newValue ) { if ( index < 0 || newValue === undefined || newValue === '' ) return ; this . favorites [ index ] . value = this . encodeHtml ( newValue , ( this . favorites [ index ] . type != FavoriteType . Search ) ) ; await this . store ( ) ; } /**
     * Changes the title of the handled favorite.
     */ async changeTitle ( index , newTitle ) { if ( index < 0 || newTitle === undefined || newTitle === '' ) return ; this . favorites [ index ] . title = this . encodeHtml ( newTitle , true ) ; await this . store ( ) ; } /**
     * Changes the type of the handled favorite.
     */ async changeType ( index , newType ) { if ( index < 0 || newType === undefined ) return ; this . favorites [ index ] . type = newType ; await this . store ( ) ; } /**
     * Moves the favorite from source index to the target index.
     */ async moveWithIndex ( sourceIdx , targetIdx ? ) { if ( this . indexOutOfBounds ( sourceIdx ) ) return ; if ( targetIdx && this . indexOutOfBounds ( targetIdx ) ) return ; let target = this . length - 1 ; if ( targetIdx ) { target = targetIdx ; } const favorite = this . favorites [ sourceIdx ] ; this . favorites . splice ( sourceIdx , 1 ) ; this . favorites . splice ( target , 0 , favorite ) ; await this . store ( ) ; } /**
     * Removes favorite with handled index.
     */ async delete ( index ) { if ( index >= 0 ) { this . favorites . splice ( index , 1 ) ; await this . store ( ) ; } } }