diff --git a/app/assets/javascripts/@types/app/assets/javascripts/directives/views/actionsMenu.d.ts b/app/assets/javascripts/@types/app/assets/javascripts/directives/views/actionsMenu.d.ts index ebebe4c52..762a1eea1 100644 --- a/app/assets/javascripts/@types/app/assets/javascripts/directives/views/actionsMenu.d.ts +++ b/app/assets/javascripts/@types/app/assets/javascripts/directives/views/actionsMenu.d.ts @@ -1,25 +1,4 @@ -/// -export class ActionsMenu { - restrict: string; - template: import("pug").compileTemplate; - replace: boolean; - controller: typeof ActionsMenuCtrl; - controllerAs: string; - bindToController: boolean; - scope: { - item: string; - application: string; - }; +import { WebDirective } from './../../types'; +export declare class ActionsMenu extends WebDirective { + constructor(); } -declare class ActionsMenuCtrl { - constructor($timeout: any); - state: { - extensions: never[]; - }; - $onInit(): void; - loadExtensions(): Promise; - executeAction(action: any, extension: any): Promise; - handleActionResult(action: any, result: any): void; - subRowsForAction(parentAction: any, extension: any): any; -} -export {}; diff --git a/app/assets/javascripts/@types/app/assets/javascripts/directives/views/challengeModal.d.ts b/app/assets/javascripts/@types/app/assets/javascripts/directives/views/challengeModal.d.ts index e4a762891..39de84ea0 100644 --- a/app/assets/javascripts/@types/app/assets/javascripts/directives/views/challengeModal.d.ts +++ b/app/assets/javascripts/@types/app/assets/javascripts/directives/views/challengeModal.d.ts @@ -1,30 +1,4 @@ -/// -export class ChallengeModal { - restrict: string; - template: import("pug").compileTemplate; - controller: typeof ChallengeModalCtrl; - controllerAs: string; - bindToController: { - challenge: string; - orchestrator: string; - application: string; - }; +import { WebDirective } from './../../types'; +export declare class ChallengeModal extends WebDirective { + constructor(); } -declare class ChallengeModalCtrl { - constructor($element: any, $timeout: any); - $element: any; - processingTypes: any[]; - $onInit(): void; - deinit(): void; - application: any; - orchestrator: any; - challenge: any; - reloadProcessingStatus(): void; - promptForChallenge(challenge: any): "Enter your application passcode" | "Enter your account password"; - cancel(): void; - onTextValueChange(challenge: any): void; - validate(): boolean; - submit(): Promise; - dismiss(): void; -} -export {}; diff --git a/app/assets/javascripts/@types/app/assets/javascripts/directives/views/componentModal.d.ts b/app/assets/javascripts/@types/app/assets/javascripts/directives/views/componentModal.d.ts index 7aaa7db24..26990bbf7 100644 --- a/app/assets/javascripts/@types/app/assets/javascripts/directives/views/componentModal.d.ts +++ b/app/assets/javascripts/@types/app/assets/javascripts/directives/views/componentModal.d.ts @@ -1,20 +1,22 @@ -/// -export class ComponentModalCtrl { - constructor($element: any); - $element: any; +import { WebApplication } from './../../application'; +import { SNComponent } from 'snjs'; +import { WebDirective } from './../../types'; +declare type ComponentModalScope = { + component: SNComponent; + callback: () => void; + onDismiss: (component: SNComponent) => void; + application: WebApplication; +}; +export declare class ComponentModalCtrl implements ComponentModalScope { + $element: JQLite; + component: SNComponent; + callback: () => void; + onDismiss: (component: SNComponent) => void; + application: WebApplication; + constructor($element: JQLite); dismiss(): void; } -export class ComponentModal { - restrict: string; - template: import("pug").compileTemplate; - controller: typeof ComponentModalCtrl; - controllerAs: string; - bindToController: boolean; - scope: { - show: string; - component: string; - callback: string; - onDismiss: string; - application: string; - }; +export declare class ComponentModal extends WebDirective { + constructor(); } +export {}; diff --git a/app/assets/javascripts/@types/app/assets/javascripts/directives/views/componentView.d.ts b/app/assets/javascripts/@types/app/assets/javascripts/directives/views/componentView.d.ts index b744fa335..7d100b1c9 100644 --- a/app/assets/javascripts/@types/app/assets/javascripts/directives/views/componentView.d.ts +++ b/app/assets/javascripts/@types/app/assets/javascripts/directives/views/componentView.d.ts @@ -1,48 +1,4 @@ -/// -export class ComponentView { - restrict: string; - template: import("pug").compileTemplate; - scope: { - component: string; - onLoad: string; - manualDealloc: string; - application: string; - }; - controller: typeof ComponentViewCtrl; - controllerAs: string; - bindToController: boolean; +import { WebDirective } from './../../types'; +export declare class ComponentView extends WebDirective { + constructor(); } -declare class ComponentViewCtrl { - constructor($scope: any, $rootScope: any, $timeout: any); - $rootScope: any; - $timeout: any; - componentValid: boolean; - cleanUpOn: any; - onVisibilityChange(): void; - $onDestroy(): void; - unregisterComponentHandler: any; - unregisterDesktopObserver: any; - component: any; - onLoad: any; - application: any; - $onChanges(): void; - didRegisterObservers: boolean | undefined; - lastComponentValue: any; - registerPackageUpdateObserver(): void; - registerComponentHandlers(): void; - reloadComponent(): Promise; - reloadStatus(doManualReload?: boolean): void; - reloading: boolean | undefined; - expired: boolean | undefined; - loading: boolean | undefined; - error: string | null | undefined; - handleActivation(): void; - loadTimeout: any; - handleIframeLoadTimeout(): Promise; - issueLoading: boolean | undefined; - didAttemptReload: boolean | undefined; - handleIframeLoad(iframe: any): Promise; - disableActiveTheme(): void; - getUrl(): any; -} -export {}; diff --git a/app/assets/javascripts/@types/app/assets/javascripts/directives/views/editorMenu.d.ts b/app/assets/javascripts/@types/app/assets/javascripts/directives/views/editorMenu.d.ts index 501d22c7b..f2b01fbb5 100644 --- a/app/assets/javascripts/@types/app/assets/javascripts/directives/views/editorMenu.d.ts +++ b/app/assets/javascripts/@types/app/assets/javascripts/directives/views/editorMenu.d.ts @@ -12,17 +12,16 @@ export class EditorMenu { application: string; }; } -declare class EditorMenuCtrl { +declare class EditorMenuCtrl extends PureCtrl { constructor($timeout: any); state: { isDesktop: any; }; - $onInit(): void; selectComponent(component: any): void; toggleDefaultForEditor(editor: any): void; offlineAvailableForComponent(component: any): any; makeEditorDefault(component: any): void; removeEditorDefault(component: any): void; - shouldDisplayRunningLocallyLabel(component: any): boolean; } +import { PureCtrl } from "../../controllers/abstract/pure_ctrl"; export {}; diff --git a/app/assets/javascripts/@types/app/assets/javascripts/directives/views/index.d.ts b/app/assets/javascripts/@types/app/assets/javascripts/directives/views/index.d.ts index f3f785f9f..f043f106a 100644 --- a/app/assets/javascripts/@types/app/assets/javascripts/directives/views/index.d.ts +++ b/app/assets/javascripts/@types/app/assets/javascripts/directives/views/index.d.ts @@ -1,17 +1,16 @@ -export { AccountMenu } from "./accountMenu"; -export { ActionsMenu } from "./actionsMenu"; -export { ChallengeModal } from "./challengeModal"; -export { ComponentModal } from "./componentModal"; -export { ComponentView } from "./componentView"; -export { ConflictResolutionModal } from "./conflictResolutionModal"; -export { EditorMenu } from "./editorMenu"; -export { InputModal } from "./inputModal"; -export { MenuRow } from "./menuRow"; -export { PanelResizer } from "./panelResizer"; -export { PasswordWizard } from "./passwordWizard"; -export { PermissionsModal } from "./permissionsModal"; -export { PrivilegesAuthModal } from "./privilegesAuthModal"; -export { PrivilegesManagementModal } from "./privilegesManagementModal"; -export { RevisionPreviewModal } from "./revisionPreviewModal"; -export { SessionHistoryMenu } from "./sessionHistoryMenu"; -export { SyncResolutionMenu } from "./syncResolutionMenu"; +export { AccountMenu } from './accountMenu'; +export { ActionsMenu } from './actionsMenu'; +export { ChallengeModal } from './challengeModal'; +export { ComponentModal } from './componentModal'; +export { ComponentView } from './componentView'; +export { EditorMenu } from './editorMenu'; +export { InputModal } from './inputModal'; +export { MenuRow } from './menuRow'; +export { PanelResizer } from './panelResizer'; +export { PasswordWizard } from './passwordWizard'; +export { PermissionsModal } from './permissionsModal'; +export { PrivilegesAuthModal } from './privilegesAuthModal'; +export { PrivilegesManagementModal } from './privilegesManagementModal'; +export { RevisionPreviewModal } from './revisionPreviewModal'; +export { SessionHistoryMenu } from './sessionHistoryMenu'; +export { SyncResolutionMenu } from './syncResolutionMenu'; diff --git a/app/assets/javascripts/@types/app/assets/javascripts/directives/views/inputModal.d.ts b/app/assets/javascripts/@types/app/assets/javascripts/directives/views/inputModal.d.ts index b285d98c8..525268f99 100644 --- a/app/assets/javascripts/@types/app/assets/javascripts/directives/views/inputModal.d.ts +++ b/app/assets/javascripts/@types/app/assets/javascripts/directives/views/inputModal.d.ts @@ -1,23 +1,10 @@ -/// -export class InputModal { - restrict: string; - template: import("pug").compileTemplate; - controller: typeof InputModalCtrl; - controllerAs: string; - bindToController: boolean; - scope: { - type: string; - title: string; - message: string; - placeholder: string; - callback: string; - }; +import { WebDirective } from './../../types'; +export interface InputModalScope extends Partial { + type: string; + title: string; + message: string; + callback: (value: string) => void; } -declare class InputModalCtrl { - constructor($element: any); - $element: any; - formData: {}; - dismiss(): void; - submit(): void; +export declare class InputModal extends WebDirective { + constructor(); } -export {}; diff --git a/app/assets/javascripts/@types/app/assets/javascripts/directives/views/menuRow.d.ts b/app/assets/javascripts/@types/app/assets/javascripts/directives/views/menuRow.d.ts index 7cae3ec79..266f26a15 100644 --- a/app/assets/javascripts/@types/app/assets/javascripts/directives/views/menuRow.d.ts +++ b/app/assets/javascripts/@types/app/assets/javascripts/directives/views/menuRow.d.ts @@ -1,31 +1,4 @@ -/// -export class MenuRow { - restrict: string; - transclude: boolean; - template: import("pug").compileTemplate; - controller: typeof MenuRowCtrl; - controllerAs: string; - bindToController: boolean; - scope: { - action: string; - buttonAction: string; - buttonClass: string; - buttonText: string; - desc: string; - disabled: string; - circle: string; - circleAlign: string; - faded: string; - hasButton: string; - label: string; - spinnerClass: string; - stylekitClass: string; - subRows: string; - subtitle: string; - }; +import { WebDirective } from './../../types'; +export declare class MenuRow extends WebDirective { + constructor(); } -declare class MenuRowCtrl { - onClick($event: any): void; - clickAccessoryButton($event: any): void; -} -export {}; diff --git a/app/assets/javascripts/@types/app/assets/javascripts/directives/views/permissionsModal.d.ts b/app/assets/javascripts/@types/app/assets/javascripts/directives/views/permissionsModal.d.ts index 8ee970a9e..6ff96fbc2 100644 --- a/app/assets/javascripts/@types/app/assets/javascripts/directives/views/permissionsModal.d.ts +++ b/app/assets/javascripts/@types/app/assets/javascripts/directives/views/permissionsModal.d.ts @@ -1,22 +1,4 @@ -/// -export class PermissionsModal { - restrict: string; - template: import("pug").compileTemplate; - controller: typeof PermissionsModalCtrl; - controllerAs: string; - bindToController: boolean; - scope: { - show: string; - component: string; - permissionsString: string; - callback: string; - }; +import { WebDirective } from './../../types'; +export declare class PermissionsModal extends WebDirective { + constructor(); } -declare class PermissionsModalCtrl { - constructor($element: any); - $element: any; - dismiss(): void; - accept(): void; - deny(): void; -} -export {}; diff --git a/app/assets/javascripts/@types/app/assets/javascripts/directives/views/privilegesAuthModal.d.ts b/app/assets/javascripts/@types/app/assets/javascripts/directives/views/privilegesAuthModal.d.ts index 7aa934a19..ac3ad1254 100644 --- a/app/assets/javascripts/@types/app/assets/javascripts/directives/views/privilegesAuthModal.d.ts +++ b/app/assets/javascripts/@types/app/assets/javascripts/directives/views/privilegesAuthModal.d.ts @@ -1,33 +1,4 @@ -/// -export class PrivilegesAuthModal { - restrict: string; - template: import("pug").compileTemplate; - controller: typeof PrivilegesAuthModalCtrl; - controllerAs: string; - bindToController: boolean; - scope: { - action: string; - onSuccess: string; - onCancel: string; - application: string; - }; +import { WebDirective } from './../../types'; +export declare class PrivilegesAuthModal extends WebDirective { + constructor(); } -declare class PrivilegesAuthModalCtrl { - constructor($element: any, $timeout: any); - $element: any; - $timeout: any; - $onInit(): void; - authParameters: {} | undefined; - sessionLengthOptions: any; - selectedSessionLength: any; - requiredCredentials: any; - selectSessionLength(length: any): void; - promptForCredential(credential: any): any; - cancel(): void; - isCredentialInFailureState(credential: any): boolean; - validate(): boolean; - failedCredentials: any; - submit(): Promise; - dismiss(): void; -} -export {}; diff --git a/app/assets/javascripts/@types/app/assets/javascripts/directives/views/privilegesManagementModal.d.ts b/app/assets/javascripts/@types/app/assets/javascripts/directives/views/privilegesManagementModal.d.ts index 7f83187c5..0b86ff190 100644 --- a/app/assets/javascripts/@types/app/assets/javascripts/directives/views/privilegesManagementModal.d.ts +++ b/app/assets/javascripts/@types/app/assets/javascripts/directives/views/privilegesManagementModal.d.ts @@ -1,33 +1,4 @@ -/// -export class PrivilegesManagementModal { - restrict: string; - template: import("pug").compileTemplate; - controller: typeof PrivilegesManagementModalCtrl; - controllerAs: string; - bindToController: boolean; - scope: { - application: string; - }; +import { WebDirective } from './../../types'; +export declare class PrivilegesManagementModal extends WebDirective { + constructor(); } -declare class PrivilegesManagementModalCtrl { - constructor($timeout: any, $element: any); - $element: any; - onAppLaunch(): void; - hasPasscode: any; - hasAccount: boolean | undefined; - displayInfoForCredential(credential: any): any; - displayInfoForAction(action: any): any; - isCredentialRequiredForAction(action: any, credential: any): any; - clearSession(): Promise; - reloadPrivileges(): Promise; - availableActions: any; - availableCredentials: any; - sessionExpirey: any; - sessionExpired: boolean | undefined; - credentialDisplayInfo: {} | undefined; - privileges: any; - checkboxValueChanged(action: any, credential: any): void; - cancel(): void; - dismiss(): void; -} -export {}; diff --git a/app/assets/javascripts/@types/app/assets/javascripts/directives/views/revisionPreviewModal.d.ts b/app/assets/javascripts/@types/app/assets/javascripts/directives/views/revisionPreviewModal.d.ts index a0a7c7f5f..21a54ae68 100644 --- a/app/assets/javascripts/@types/app/assets/javascripts/directives/views/revisionPreviewModal.d.ts +++ b/app/assets/javascripts/@types/app/assets/javascripts/directives/views/revisionPreviewModal.d.ts @@ -1,27 +1,4 @@ -/// -export class RevisionPreviewModal { - restrict: string; - template: import("pug").compileTemplate; - controller: typeof RevisionPreviewModalCtrl; - controllerAs: string; - bindToController: boolean; - scope: { - uuid: string; - content: string; - application: string; - }; +import { WebDirective } from './../../types'; +export declare class RevisionPreviewModal extends WebDirective { + constructor(); } -declare class RevisionPreviewModalCtrl { - constructor($element: any, $timeout: any); - $element: any; - $timeout: any; - $onInit(): void; - $onDestroy(): void; - unregisterComponent: any; - configure(): Promise; - note: any; - editor: any; - restore(asCopy: any): void; - dismiss(): void; -} -export {}; diff --git a/app/assets/javascripts/@types/app/assets/javascripts/directives/views/sessionHistoryMenu.d.ts b/app/assets/javascripts/@types/app/assets/javascripts/directives/views/sessionHistoryMenu.d.ts index 9b23a2ccf..44adc2d36 100644 --- a/app/assets/javascripts/@types/app/assets/javascripts/directives/views/sessionHistoryMenu.d.ts +++ b/app/assets/javascripts/@types/app/assets/javascripts/directives/views/sessionHistoryMenu.d.ts @@ -1,29 +1,4 @@ -/// -export class SessionHistoryMenu { - restrict: string; - template: import("pug").compileTemplate; - controller: typeof SessionHistoryMenuCtrl; - controllerAs: string; - bindToController: boolean; - scope: { - item: string; - application: string; - }; +import { WebDirective } from './../../types'; +export declare class SessionHistoryMenu extends WebDirective { + constructor(); } -declare class SessionHistoryMenuCtrl { - constructor($timeout: any); - $timeout: any; - $onInit(): void; - diskEnabled: any; - autoOptimize: any; - reloadHistory(): void; - entries: any; - history: any; - openRevision(revision: any): void; - classForRevision(revision: any): "default" | "success" | "danger" | undefined; - clearItemHistory(): void; - clearAllHistory(): void; - toggleDiskSaving(): void; - toggleAutoOptimize(): void; -} -export {}; diff --git a/app/assets/javascripts/@types/app/assets/javascripts/directives/views/syncResolutionMenu.d.ts b/app/assets/javascripts/@types/app/assets/javascripts/directives/views/syncResolutionMenu.d.ts index 85dc59f55..6e3fdcf04 100644 --- a/app/assets/javascripts/@types/app/assets/javascripts/directives/views/syncResolutionMenu.d.ts +++ b/app/assets/javascripts/@types/app/assets/javascripts/directives/views/syncResolutionMenu.d.ts @@ -1,22 +1,4 @@ -/// -export class SyncResolutionMenu { - restrict: string; - template: import("pug").compileTemplate; - controller: typeof SyncResolutionMenuCtrl; - controllerAs: string; - bindToController: boolean; - scope: { - closeFunction: string; - application: string; - }; +import { WebDirective } from './../../types'; +export declare class SyncResolutionMenu extends WebDirective { + constructor(); } -declare class SyncResolutionMenuCtrl { - constructor($timeout: any); - $timeout: any; - status: {}; - downloadBackup(encrypted: any): void; - skipBackup(): void; - performSyncResolution(): Promise; - close(): void; -} -export {}; diff --git a/app/assets/javascripts/@types/app/assets/javascripts/types.d.ts b/app/assets/javascripts/@types/app/assets/javascripts/types.d.ts index b97c536da..45be0441d 100644 --- a/app/assets/javascripts/@types/app/assets/javascripts/types.d.ts +++ b/app/assets/javascripts/@types/app/assets/javascripts/types.d.ts @@ -11,6 +11,7 @@ export declare class WebDirective implements ng.IDirective { [boundProperty: string]: string; }; template?: string | ((tElement: any, tAttrs: any) => string); + transclude?: boolean; } export declare enum PasswordWizardType { ChangePassword = 1, diff --git a/app/assets/javascripts/directives/views/editorMenu.js b/app/assets/javascripts/directives/views/editorMenu.js deleted file mode 100644 index be6c4b4bc..000000000 --- a/app/assets/javascripts/directives/views/editorMenu.js +++ /dev/null @@ -1,91 +0,0 @@ -import { isDesktopApplication } from '@/utils'; -import template from '%/directives/editor-menu.pug'; -import { PureCtrl } from '@Controllers/abstract/pure_ctrl'; - -class EditorMenuCtrl extends PureCtrl { - /* @ngInject */ - constructor( - $timeout, - ) { - super($timeout); - this.state = { - isDesktop: isDesktopApplication() - }; - } - - $onInit() { - super.$onInit(); - const editors = this.application.componentManager.componentsForArea('editor-editor') - .sort((a, b) => { - return a.name.toLowerCase() < b.name.toLowerCase() ? -1 : 1; - }); - const defaultEditor = editors.filter((e) => e.isDefaultEditor())[0]; - this.setState({ - editors: editors, - defaultEditor: defaultEditor - }); - }; - - selectComponent(component) { - if(component) { - if(component.content.conflict_of) { - component.content.conflict_of = null; - this.application.saveItem({item: component}); - } - } - this.$timeout(() => { - this.callback()(component); - }); - } - - toggleDefaultForEditor(editor) { - if(this.state.defaultEditor === editor) { - this.removeEditorDefault(editor); - } else { - this.makeEditorDefault(editor); - } - } - - offlineAvailableForComponent(component) { - return component.local_url && this.state.isDesktop; - } - - makeEditorDefault(component) { - const currentDefault = this.application.componentManager - .componentsForArea('editor-editor') - .filter((e) => e.isDefaultEditor())[0]; - if(currentDefault) { - currentDefault.setAppDataItem('defaultEditor', false); - this.application.setItemsNeedsSync({item: currentDefault}); - } - component.setAppDataItem('defaultEditor', true); - this.application.saveItem({ item: component }); - this.setState({ - defaultEditor: component - }); - } - - removeEditorDefault(component) { - component.setAppDataItem('defaultEditor', false); - this.application.saveItem({ item: component }); - this.setState({ - defaultEditor: null - }); - } -} - -export class EditorMenu { - constructor() { - this.restrict = 'E'; - this.template = template; - this.controller = EditorMenuCtrl; - this.controllerAs = 'self'; - this.bindToController = true; - this.scope = { - callback: '&', - selectedEditor: '=', - currentItem: '=', - application: '=' - }; - } -} diff --git a/app/assets/javascripts/directives/views/editorMenu.ts b/app/assets/javascripts/directives/views/editorMenu.ts new file mode 100644 index 000000000..e49b3c4ad --- /dev/null +++ b/app/assets/javascripts/directives/views/editorMenu.ts @@ -0,0 +1,116 @@ +import { WebDirective } from './../../types'; +import { WebApplication } from '@/application'; +import { SNComponent, SNItem, ComponentArea } from 'snjs'; +import { isDesktopApplication } from '@/utils'; +import template from '%/directives/editor-menu.pug'; +import { PureCtrl } from '@Controllers/abstract/pure_ctrl'; +import { ComponentMutator } from '@/../../../../snjs/dist/@types/models'; + +interface EditorMenuScope { + callback: (component: SNComponent) => void + selectedEditor: SNComponent + currentItem: SNItem + application: WebApplication +} + +class EditorMenuCtrl extends PureCtrl implements EditorMenuScope { + + callback!: (component: SNComponent) => void + selectedEditor!: SNComponent + currentItem!: SNItem + application!: WebApplication + + /* @ngInject */ + constructor( + $timeout: ng.ITimeoutService, + ) { + super($timeout); + this.state = { + isDesktop: isDesktopApplication() + }; + } + + $onInit() { + super.$onInit(); + const editors = this.application.componentManager!.componentsForArea(ComponentArea.Editor) + .sort((a, b) => { + return a.name.toLowerCase() < b.name.toLowerCase() ? -1 : 1; + }); + const defaultEditor = editors.filter((e) => e.isDefaultEditor())[0]; + this.setState({ + editors: editors, + defaultEditor: defaultEditor + }); + }; + + selectComponent(component: SNComponent) { + if (component) { + if (component.conflictOf) { + this.application.changeAndSaveItem(component.uuid, (mutator) => { + mutator.conflictOf = undefined; + }) + } + } + this.$timeout(() => { + this.callback(component); + }); + } + + toggleDefaultForEditor(editor: SNComponent) { + if (this.state.defaultEditor === editor) { + this.removeEditorDefault(editor); + } else { + this.makeEditorDefault(editor); + } + } + + offlineAvailableForComponent(component: SNComponent) { + return component.local_url && this.state.isDesktop; + } + + makeEditorDefault(component: SNComponent) { + const currentDefault = this.application.componentManager! + .componentsForArea(ComponentArea.Editor) + .filter((e) => e.isDefaultEditor())[0]; + if (currentDefault) { + this.application.changeItem(currentDefault.uuid, (m) => { + const mutator = m as ComponentMutator; + mutator.defaultEditor = false; + }) + } + this.application.changeAndSaveItem(component.uuid, (m) => { + const mutator = m as ComponentMutator; + mutator.defaultEditor = true; + }); + this.setState({ + defaultEditor: component + }); + } + + removeEditorDefault(component: SNComponent) { + this.application.changeAndSaveItem(component.uuid, (m) => { + const mutator = m as ComponentMutator; + mutator.defaultEditor = false; + }); + this.setState({ + defaultEditor: null + }); + } +} + +export class EditorMenu extends WebDirective { + constructor() { + super(); + this.restrict = 'E'; + this.template = template; + this.controller = EditorMenuCtrl; + this.controllerAs = 'self'; + this.bindToController = true; + this.scope = { + callback: '&', + selectedEditor: '=', + currentItem: '=', + application: '=' + }; + } +} diff --git a/app/assets/javascripts/directives/views/panelResizer.js b/app/assets/javascripts/directives/views/panelResizer.ts similarity index 65% rename from app/assets/javascripts/directives/views/panelResizer.js rename to app/assets/javascripts/directives/views/panelResizer.ts index 10d360205..740139dc5 100644 --- a/app/assets/javascripts/directives/views/panelResizer.js +++ b/app/assets/javascripts/directives/views/panelResizer.ts @@ -1,32 +1,83 @@ +import { PanelPuppet, WebDirective } from './../../types'; import angular from 'angular'; import template from '%/directives/panel-resizer.pug'; import { debounce } from '@/utils'; -const PanelSides = { - Right: 'right', - Left: 'left' +enum PanelSide { + Right = 'right', + Left = 'left' }; -const MouseEvents = { - Move: 'mousemove', - Down: 'mousedown', - Up: 'mouseup' +enum MouseEventType { + Move = 'mousemove', + Down = 'mousedown', + Up = 'mouseup' }; -const CssClasses = { - Hoverable: 'hoverable', - AlwaysVisible: 'always-visible', - Dragging: 'dragging', - NoSelection: 'no-selection', - Collapsed: 'collapsed', - AnimateOpacity: 'animate-opacity', +enum CssClass { + Hoverable = 'hoverable', + AlwaysVisible = 'always-visible', + Dragging = 'dragging', + NoSelection = 'no-selection', + Collapsed = 'collapsed', + AnimateOpacity = 'animate-opacity', }; const WINDOW_EVENT_RESIZE = 'resize'; -class PanelResizerCtrl { +type ResizeFinishCallback = ( + lastWidth: number, + lastLeft: number, + isMaxWidth: boolean, + isCollapsed: boolean +) => void + +interface PanelResizerScope { + alwaysVisible: boolean + collapsable: boolean + control: PanelPuppet + defaultWidth: number + hoverable: boolean + index: number + minWidth: number + onResizeFinish: ResizeFinishCallback + panelId: string + property: PanelSide +} + +class PanelResizerCtrl implements PanelResizerScope { + + /** @scope */ + alwaysVisible!: boolean + collapsable!: boolean + control!: PanelPuppet + defaultWidth!: number + hoverable!: boolean + index!: number + minWidth!: number + onResizeFinish!: ResizeFinishCallback + panelId!: string + property!: PanelSide + + $compile: ng.ICompileService + $element: JQLite + $timeout: ng.ITimeoutService + panel!: HTMLElement + resizerColumn!: HTMLElement + currentMinWidth = 0 + pressed = false + startWidth = 0 + lastDownX = 0 + collapsed = false + lastWidth = 0 + startLeft = 0 + lastLeft = 0 + appFrame?: DOMRect + widthBeforeLastDblClick = 0 + overlay?: JQLite + /* @ngInject */ constructor( - $compile, - $element, - $timeout, + $compile: ng.ICompileService, + $element: JQLite, + $timeout: ng.ITimeoutService, ) { this.$compile = $compile; this.$element = $element; @@ -44,51 +95,47 @@ class PanelResizerCtrl { this.reloadDefaultValues(); this.configureControl(); this.addDoubleClickHandler(); - this.addMouseDownListener(); - this.addMouseMoveListener(); - this.addMouseUpListener(); + this.resizerColumn.addEventListener(MouseEventType.Down, this.onMouseDown); + document.addEventListener(MouseEventType.Move, this.onMouseMove); + document.addEventListener(MouseEventType.Up, this.onMouseUp); } $onDestroy() { - this.onResizeFinish = null; - this.control = null; + (this.onResizeFinish as any) = undefined; + (this.control as any) = undefined; window.removeEventListener(WINDOW_EVENT_RESIZE, this.handleResize); - document.removeEventListener(MouseEvents.Move, this.onMouseMove); - document.removeEventListener(MouseEvents.Up, this.onMouseUp); - this.resizerColumn.removeEventListener(MouseEvents.Down, this.onMouseDown); - this.handleResize = null; - this.onMouseMove = null; - this.onMouseUp = null; - this.onMouseDown = null; + document.removeEventListener(MouseEventType.Move, this.onMouseMove); + document.removeEventListener(MouseEventType.Up, this.onMouseUp); + this.resizerColumn.removeEventListener(MouseEventType.Down, this.onMouseDown); + (this.handleResize as any) = undefined; + (this.onMouseMove as any) = undefined; + (this.onMouseUp as any) = undefined; + (this.onMouseDown as any) = undefined; } configureControl() { this.control.setWidth = (value) => { this.setWidth(value, true); }; - this.control.setLeft = (value) => { this.setLeft(value); }; - this.control.flash = () => { this.flash(); }; - this.control.isCollapsed = () => { return this.isCollapsed(); }; - this.control.ready = true; - this.control.onReady(); + this.control.onReady!(); } configureDefaults() { - this.panel = document.getElementById(this.panelId); + this.panel = document.getElementById(this.panelId)!; if (!this.panel) { console.error('Panel not found for', this.panelId); + return; } - this.resizerColumn = this.$element[0]; this.currentMinWidth = this.minWidth || this.resizerColumn.offsetWidth; this.pressed = false; @@ -98,17 +145,16 @@ class PanelResizerCtrl { this.lastWidth = this.startWidth; this.startLeft = this.panel.offsetLeft; this.lastLeft = this.startLeft; - this.appFrame = null; + this.appFrame = undefined; this.widthBeforeLastDblClick = 0; - - if (this.property === PanelSides.Right) { + if (this.property === PanelSide.Right) { this.configureRightPanel(); } if (this.alwaysVisible) { - this.resizerColumn.classList.add(CssClasses.AlwaysVisible); + this.resizerColumn.classList.add(CssClass.AlwaysVisible); } if (this.hoverable) { - this.resizerColumn.classList.add(CssClasses.Hoverable); + this.resizerColumn.classList.add(CssClass.Hoverable); } } @@ -117,7 +163,7 @@ class PanelResizerCtrl { } handleResize() { - debounce(this, () => { + debounce(() => { this.reloadDefaultValues(); this.handleWidthEvent(); this.$timeout(() => { @@ -127,7 +173,8 @@ class PanelResizerCtrl { } getParentRect() { - return this.panel.parentNode.getBoundingClientRect(); + const node = this.panel!.parentNode! as HTMLElement; + return node.getBoundingClientRect(); } reloadDefaultValues() { @@ -135,7 +182,7 @@ class PanelResizerCtrl { ? this.getParentRect().width : this.panel.scrollWidth; this.lastWidth = this.startWidth; - this.appFrame = document.getElementById('app').getBoundingClientRect(); + this.appFrame = document.getElementById('app')!.getBoundingClientRect(); } addDoubleClickHandler() { @@ -148,9 +195,7 @@ class PanelResizerCtrl { this.widthBeforeLastDblClick = this.lastWidth; this.setWidth(this.currentMinWidth); } - this.finishSettingWidth(); - const newCollapseState = !preClickCollapseState; this.onResizeFinish( this.lastWidth, @@ -162,54 +207,65 @@ class PanelResizerCtrl { }; } - addMouseDownListener() { - this.resizerColumn.addEventListener(MouseEvents.Down, this.onMouseDown); - } - - onMouseDown(event) { + onMouseDown(event: MouseEvent) { this.addInvisibleOverlay(); this.pressed = true; this.lastDownX = event.clientX; this.startWidth = this.panel.scrollWidth; this.startLeft = this.panel.offsetLeft; - this.panel.classList.add(CssClasses.NoSelection); + this.panel.classList.add(CssClass.NoSelection); if (this.hoverable) { - this.resizerColumn.classList.add(CssClasses.Dragging); + this.resizerColumn.classList.add(CssClass.Dragging); } } - addMouseMoveListener() { - document.addEventListener(MouseEvents.Move, this.onMouseMove); + onMouseUp() { + this.removeInvisibleOverlay(); + if (!this.pressed) { + return; + } + this.pressed = false; + this.resizerColumn.classList.remove(CssClass.Dragging); + this.panel.classList.remove(CssClass.NoSelection); + const isMaxWidth = this.isAtMaxWidth(); + if (this.onResizeFinish) { + this.onResizeFinish( + this.lastWidth, + this.lastLeft, + isMaxWidth, + this.isCollapsed() + ); + } + this.finishSettingWidth(); } - onMouseMove(event) { + onMouseMove(event: MouseEvent) { if (!this.pressed) { return; } event.preventDefault(); - if (this.property && this.property === PanelSides.Left) { + if (this.property && this.property === PanelSide.Left) { this.handleLeftEvent(event); } else { this.handleWidthEvent(event); } } - handleWidthEvent(event) { + handleWidthEvent(event?: MouseEvent) { let x; if (event) { - x = event.clientX; + x = event!.clientX; } else { /** Coming from resize event */ x = 0; this.lastDownX = 0; } - const deltaX = x - this.lastDownX; const newWidth = this.startWidth + deltaX; this.setWidth(newWidth, false); } - handleLeftEvent(event) { + handleLeftEvent(event: MouseEvent) { const panelRect = this.panel.getBoundingClientRect(); const x = event.clientX || panelRect.x; let deltaX = x - this.lastDownX; @@ -229,34 +285,10 @@ class PanelResizerCtrl { if (newLeft + newWidth > parentRect.width) { newLeft = parentRect.width - newWidth; } - this.setLeft(newLeft, false); + this.setLeft(newLeft); this.setWidth(newWidth, false); } - addMouseUpListener() { - document.addEventListener(MouseEvents.Up, this.onMouseUp); - } - - onMouseUp() { - this.removeInvisibleOverlay(); - if (!this.pressed) { - return; - } - this.pressed = false; - this.resizerColumn.classList.remove(CssClasses.Dragging); - this.panel.classList.remove(CssClasses.NoSelection); - const isMaxWidth = this.isAtMaxWidth(); - if (this.onResizeFinish) { - this.onResizeFinish( - this.lastWidth, - this.lastLeft, - isMaxWidth, - this.isCollapsed() - ); - } - this.finishSettingWidth(); - } - isAtMaxWidth() { return ( Math.round(this.lastWidth + this.lastLeft) === @@ -268,7 +300,7 @@ class PanelResizerCtrl { return this.lastWidth <= this.currentMinWidth; } - setWidth(width, finish) { + setWidth(width: number, finish = false) { if (width < this.currentMinWidth) { width = this.currentMinWidth; } @@ -277,7 +309,7 @@ class PanelResizerCtrl { width = parentRect.width; } - const maxWidth = this.appFrame.width - this.panel.getBoundingClientRect().x; + const maxWidth = this.appFrame!.width - this.panel.getBoundingClientRect().x; if (width > maxWidth) { width = maxWidth; } @@ -294,7 +326,7 @@ class PanelResizerCtrl { } } - setLeft(left) { + setLeft(left: number) { this.panel.style.left = left + 'px'; this.lastLeft = left; } @@ -306,9 +338,9 @@ class PanelResizerCtrl { this.collapsed = this.isCollapsed(); if (this.collapsed) { - this.resizerColumn.classList.add(CssClasses.Collapsed); + this.resizerColumn.classList.add(CssClass.Collapsed); } else { - this.resizerColumn.classList.remove(CssClasses.Collapsed); + this.resizerColumn.classList.remove(CssClass.Collapsed); } } @@ -322,28 +354,29 @@ class PanelResizerCtrl { if (this.overlay) { return; } - this.overlay = this.$compile(`
`)(this); + this.overlay = this.$compile(`
`)(this as any); angular.element(document.body).prepend(this.overlay); } removeInvisibleOverlay() { if (this.overlay) { this.overlay.remove(); - this.overlay = null; + this.overlay = undefined; } } flash() { const FLASH_DURATION = 3000; - this.resizerColumn.classList.add(CssClasses.AnimateOpacity); + this.resizerColumn.classList.add(CssClass.AnimateOpacity); this.$timeout(() => { - this.resizerColumn.classList.remove(CssClasses.AnimateOpacity); + this.resizerColumn.classList.remove(CssClass.AnimateOpacity); }, FLASH_DURATION); } } -export class PanelResizer { +export class PanelResizer extends WebDirective { constructor() { + super(); this.restrict = 'E'; this.template = template; this.controller = PanelResizerCtrl; diff --git a/app/assets/javascripts/tsconfig.json b/app/assets/javascripts/tsconfig.json index 1ae41e36e..cff6270cc 100644 --- a/app/assets/javascripts/tsconfig.json +++ b/app/assets/javascripts/tsconfig.json @@ -11,10 +11,16 @@ "declarationDir": "@types", "emitDeclarationOnly": true, "baseUrl": ".", + "typeRoots": [ + "node_modules/@types", + "node_modules/snjs/dist/@types/index.d.ts" + ], "paths": { "%/*": ["../templates/*"], "@/*": ["./*"], "@Controllers/*": ["./controllers/*"] } - } + }, + "include": ["."], + "exclude": ["node_modules", "dist", "./@types"] } diff --git a/app/assets/javascripts/utils.ts b/app/assets/javascripts/utils.ts index 1344dffdf..858d58ac4 100644 --- a/app/assets/javascripts/utils.ts +++ b/app/assets/javascripts/utils.ts @@ -60,7 +60,7 @@ export function dateToLocalizedString(date: Date) { } /** Via https://davidwalsh.name/javascript-debounce-function */ -export function debounce(this: any, func: any, wait: number, immediate: boolean) { +export function debounce(this: any, func: any, wait: number, immediate = false) { let timeout: any; return () => { const context = this; diff --git a/app/assets/templates/editor.pug b/app/assets/templates/editor.pug index 7cc05d44c..4ceae319a 100644 --- a/app/assets/templates/editor.pug +++ b/app/assets/templates/editor.pug @@ -163,7 +163,7 @@ ) .sk-label Editor editor-menu( - callback='self.editorMenuOnSelect', + callback='self.editorMenuOnSelect()', current-item='self.state.note', ng-if='self.state.showEditorMenu', selected-editor='self.state.selectedEditor',