1
0
mirror of https://github.com/flarum/core.git synced 2025-08-13 20:04:24 +02:00

Compare commits

..

2 Commits

Author SHA1 Message Date
luceos
aea72957fd Apply fixes from StyleCI
[ci skip] [skip ci]
2021-06-28 09:37:49 +00:00
Daniel Klabbers
838d9c5106 Allow easier extensibility of page document
This allows extensions to:

- mutate the json api document sent with php documents
- override/interact with the Document

Right now extensions need to replace the complete Frontend class
in order to interact with the document. Let's abstract into ioc
so that advanced devs can interact with it.
2021-06-28 11:36:03 +02:00
348 changed files with 3146 additions and 4424 deletions

2
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1,2 @@
github: flarum
open_collective: flarum

24
.github/PULL_REQUEST_TEMPLATE.md vendored Normal file
View File

@@ -0,0 +1,24 @@
<!--
IMPORTANT: We applaud pull requests, they excite us every single time. As we have an obligation to maintain a healthy code standard and quality, we take sufficient time for reviews. Please do create a separate pull request per change/issue/feature; we will ask you to split bundled pull requests.
-->
**Fixes #0000**
**Changes proposed in this pull request:**
<!-- fill this out, mention the pages and/or components which have been impacted -->
**Reviewers should focus on:**
<!-- fill this out, ask for feedback on specific changes you are unsure about -->
**Screenshot**
<!-- include an image of the most relevant user-facing change, if any -->
**Confirmed**
- [ ] Frontend changes: tested on a local Flarum installation.
- [ ] Backend changes: tests are green (run `composer test`).
**Required changes:**
- [ ] Related documentation PR: (Remove if irrelevant)
- [ ] Related core extension PRs: (Remove if irrelevant)

13
.github/SECURITY.md vendored Normal file
View File

@@ -0,0 +1,13 @@
# Security Policy
## Versions
Due to the nature of our project - being open source - we have decided to patch only the latest major release (currently v1.x) for security vulnerabilities.
## How to disclose
Please use [huntr.dev](https://huntr.dev/) for security issues that affect our project. If you believe you have found a vulnerability, please disclose it via [this form](https://huntr.dev/bounties/disclose/?target=https://github.com/flarum/core).
This will enable us to **review** the vulnerability, **fix** it promptly, and **reward** you for your efforts.
If you have any questions about the process, feel free to reach out to security@huntr.dev or security@flarum.org.

33
.github/workflows/build.yml vendored Normal file
View File

@@ -0,0 +1,33 @@
name: JavaScript
on:
push:
branches:
- master
jobs:
build:
name: JS / Build
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v2
- name: Restore npm cache
uses: actions/cache@v2
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('js/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
# Our action will install npm, cd into `./js`, run `npm run build` and
# `npm run build-typings`, then commit and upload any changes
- name: Build production JS
uses: flarum/action-build@2
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
build_script: build
package_manager: npm
typings_script: build-typings

View File

@@ -1,91 +0,0 @@
name: JS
on: [workflow_dispatch, push, pull_request]
env:
NODE_VERSION: 16
jobs:
prettier:
name: Prettier
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v2
- name: Set up Node
uses: actions/setup-node@v2
with:
node-version: ${{ env.NODE_VERSION }}
cache: "npm"
cache-dependency-path: js/package-lock.json
- name: Install JS dependencies
run: npm ci
working-directory: ./js
- name: Check JS formatting
run: npm run format-check
working-directory: ./js
build-prod:
name: Build and commit
runs-on: ubuntu-latest
needs: [prettier]
# Only commit JS on push to master branch
# Remember to change in `build-test` job too
if: github.ref == 'refs/heads/master' && github.event_name == 'push'
steps:
- name: Check out code
uses: actions/checkout@v2
- name: Set up Node
uses: actions/setup-node@v2
with:
node-version: ${{ env.NODE_VERSION }}
cache: "npm"
cache-dependency-path: js/package-lock.json
# Our action will install npm, cd into `./js`, run `npm run build` and
# `npm run build-typings`, then commit and upload any changes
- name: Build production JS
uses: flarum/action-build@2
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
build_script: build
package_manager: npm
typings_script: build-typings
build-test:
name: Test build
runs-on: ubuntu-latest
needs: [prettier]
# Inverse check of `build-prod`
# Remember to change in `build-prod` job too
if: github.ref != 'refs/heads/master' || github.event_name != 'push'
steps:
- name: Check out code
uses: actions/checkout@v2
- name: Set up Node
uses: actions/setup-node@v2
with:
node-version: ${{ env.NODE_VERSION }}
cache: "npm"
cache-dependency-path: js/package-lock.json
# Our action will install npm, cd into `./js`, run `npm run build` and
# `npm run build-typings`, then commit and upload any changes
- name: Build production JS
uses: flarum/action-build@2
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
build_script: build
package_manager: npm
typings_script: build-typings
do_not_commit: true

28
.github/workflows/lint.yml vendored Normal file
View File

@@ -0,0 +1,28 @@
name: Lint
on:
workflow_dispatch:
push:
paths:
- 'js/src/**'
pull_request:
paths:
- 'js/src/**'
jobs:
prettier:
name: JS / Prettier
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v2
- name: Set up Node
uses: actions/setup-node@v2
with:
node-version: "14"
- name: Check JS formatting
run: npx prettier --check src
working-directory: ./js

View File

@@ -8,7 +8,7 @@ jobs:
strategy:
matrix:
php: [7.3, 7.4, '8.0', '8.1']
php: [7.3, 7.4, '8.0']
service: ['mysql:5.7', mariadb]
prefix: ['', flarum_]

View File

@@ -1,66 +1,5 @@
# Changelog
## [1.1.0](https://github.com/flarum/core/compare/v1.0.4...v1.1.0)
### Added
- Info command now displays MySQL version, queue driver, mail driver (https://github.com/flarum/core/pull/2991)
- Use organization Prettier config (https://github.com/flarum/core/pull/2967)
- Support for global typings in extensions (https://github.com/flarum/core/pull/2992)
- Typings for class component state attribute (https://github.com/flarum/core/pull/2995)
- Custom colorising with CSS custom properties (https://github.com/flarum/core/pull/3001)
- Theme Extender to allow overriding LESS files (https://github.com/flarum/core/pull/3008)
- Update lastSeenAt when authenticating via API (https://github.com/flarum/core/pull/3058)
- NoJs Admin View (https://github.com/flarum/core/pull/3059)
- Preload FontAwesome, JS and CSS, and add `preload` extender (https://github.com/flarum/core/pull/3057)
### Changed
- Move Day.js plugin types import to global typings (https://github.com/flarum/core/pull/2954)
- Avoid resolving excluded middleware on each middleware items
- Allow extra attrs provided to `<Select>` to be passed through to the DOM element (https://github.com/flarum/core/pull/2959)
- Limit height of code blocks (https://github.com/flarum/core/pull/3012)
- Update normalize.css from v3.0.2 to v8.0.1 (https://github.com/flarum/core/pull/3015)
- Permission Grid: stick the headers to handle a lot of tags (https://github.com/flarum/core/pull/2887)
- Use `ItemList` for `DiscussionPage` content (https://github.com/flarum/core/pull/3004)
- Move email confirmation to POST request (https://github.com/flarum/core/pull/3038)
- Minor CSS code cleanup (https://github.com/flarum/core/pull/3026)
- Replace username with display name in more places (https://github.com/flarum/core/pull/3040)
- Rewrite Button to Typescript (https://github.com/flarum/core/pull/2984)
- Rewrite AdminPage abstract component into Typescript (https://github.com/flarum/core/pull/2996)
- Allow adding page parameters to PaginatedListState (https://github.com/flarum/core/pull/2935)
- Pass filter params to getApiDocument (https://github.com/flarum/core/pull/3037)
- Use author filter instead of gambit to get a user's discussions (https://github.com/flarum/core/pull/3068)
- [A11Y] Accessibility improvements for the Search component (https://github.com/flarum/core/pull/3017)
- Add determinsm to extension order resolution (https://github.com/flarum/core/pull/3076)
- Add cache control headers to the admin area (https://github.com/flarum/core/pull/3097)
### Fixed
- HLJS 11 new styles resulting in double padding (https://github.com/flarum/core/pull/2909)
- Internal API client attempting to load an uninstantiated session
- Empty post footer taking visual space (https://github.com/flarum/core/pull/2926)
- Unrecognized component class custom attribute typings (https://github.com/flarum/core/pull/2962)
- User edit groups permission not visually depending on view hidden groups permission (https://github.com/flarum/core/pull/2880)
- Event post excerpt preview triggers error (https://github.com/flarum/core/pull/2964)
- Missing settings defaults for display name driver and User slug driver (https://github.com/flarum/core/pull/2971)
- [A11Y] Icons not hidden from screenreaders (https://github.com/flarum/core/pull/3027)
- [A11Y] Checkboxes not focusable (https://github.com/flarum/core/pull/3014)
- Uploading ICO favicons resulting in server errors (https://github.com/flarum/core/pull/2949)
- Missing proper validation for large avatar upload payload (https://github.com/flarum/core/pull/3042)
- [A11Y] Missing focus rings in control elements (https://github.com/flarum/core/pull/3016)
- Unsanitised integer query parameters (https://github.com/flarum/core/pull/3064)
###### Code Contributors
@lhsazevedo, @Ornanovitch, @pierres, @the-turk, @iPurpl3x
###### Issue Reporters
@uamv, @dannyuk1982, @BurnNoticeSpy, @haarp, @peopleinside, @matteocontrini
## [1.0.4](https://github.com/flarum/core/compare/v1.0.3...v1.0.4)
### Fixed
- Upgrade to v1.0 resets the "view" permission on all tags (https://github.com/flarum/core/pull/2941)
## [1.0.3](https://github.com/flarum/core/compare/v1.0.2...v1.0.3)
### Changed

View File

@@ -59,7 +59,7 @@
"illuminate/support": "^8.0",
"illuminate/validation": "^8.0",
"illuminate/view": "^8.0",
"intervention/image": "2.5.* || ^2.6.1",
"intervention/image": "^2.5.0",
"laminas/laminas-diactoros": "^2.4.1",
"laminas/laminas-httphandlerrunner": "^1.2.0",
"laminas/laminas-stratigility": "^3.2.2",

6
js/.prettierrc.json Normal file
View File

@@ -0,0 +1,6 @@
{
"printWidth": 150,
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "es5"
}

39
js/@types/global/index.d.ts vendored Normal file
View File

@@ -0,0 +1,39 @@
// Mithril
import Mithril from 'mithril';
// Other third-party libs
import * as _dayjs from 'dayjs';
import * as _$ from 'jquery';
// Globals from flarum/core
import Application from '../../src/common/Application';
import type { TooltipJQueryFunction } from '../tooltips';
/**
* flarum/core exposes several extensions globally:
*
* - jQuery for convenient DOM manipulation
* - Mithril for VDOM and components
* - dayjs for date/time operations
*
* Since these are already part of the global namespace, extensions won't need
* to (and should not) bundle these themselves.
*/
declare global {
// $ is already defined by `@types/jquery`
const m: Mithril.Static;
const dayjs: typeof _dayjs;
// Extend JQuery with our custom functions, defined with $.fn
interface JQuery {
tooltip: TooltipJQueryFunction;
}
}
/**
* All global variables owned by flarum/core.
*/
declare global {
const app: Application;
}

View File

@@ -1,82 +0,0 @@
/**
* @deprecated Please import `app` from a namespace instead of using it as a global variable.
*
* @example App in forum JS
* ```
* import app from 'flarum/forum/app';
* ```
*
* @example App in admin JS
* ```
* import app from 'flarum/admin/app';
* ```
*
* @example App in common JS
* ```
* import app from 'flarum/common/app';
* ```
*/
declare const app: never;
declare const m: import('mithril').Static;
declare const dayjs: typeof import('dayjs');
type ESModule = { __esModule: true; [key: string]: unknown };
/**
* The global `flarum` variable.
*
* Contains the compiled ES Modules for all Flarum extensions and core.
*
* @example <caption>Check if `flarum-tags` is present</captions>
* if ('flarum-tags' in flarum.extensions) {
* // Tags is installed and enabled!
* }
*/
interface FlarumObject {
/**
* Contains the compiled ES Module for Flarum's core.
*
* You shouldn't need to access this directly for any reason.
*/
core: Readonly<ESModule>;
/**
* Contains the compiled ES Modules for all Flarum extensions.
*
* @example <caption>Check if `flarum-tags` is present</captions>
* if ('flarum-tags' in flarum.extensions) {
* // Tags is installed and enabled!
* }
*/
extensions: Readonly<Record<string, ESModule>>;
}
declare const flarum: FlarumObject;
// Extend JQuery with our custom functions, defined with $.fn
interface JQuery {
/**
* Flarum's tooltip JQuery plugin.
*
* Do not use this directly. Instead use the `<Tooltip>` component that
* is exported from `flarum/common/components/Tooltip`.
*
* This will be removed in a future version of Flarum.
*
* @deprecated
*/
tooltip: import('./tooltips/index').TooltipJQueryFunction;
}
/**
* For more info, see: https://www.typescriptlang.org/docs/handbook/jsx.html#attribute-type-checking
*
* In a nutshell, we need to add `ElementAttributesProperty` to tell Typescript
* what property on component classes to look at for attribute typings. For our
* Component class, this would be `attrs` (e.g. `this.attrs...`)
*/
interface JSX {
ElementAttributesProperty: {
attrs: Record<string, unknown>;
};
}

View File

@@ -0,0 +1,39 @@
// Mithril
import Mithril from 'mithril';
// Other third-party libs
import * as _dayjs from 'dayjs';
import * as _$ from 'jquery';
// Globals from flarum/core
import Application from '../../src/common/Application';
import type { TooltipJQueryFunction } from '../tooltips';
/**
* flarum/core exposes several extensions globally:
*
* - jQuery for convenient DOM manipulation
* - Mithril for VDOM and components
* - dayjs for date/time operations
*
* Since these are already part of the global namespace, extensions won't need
* to (and should not) bundle these themselves.
*/
declare global {
// $ is already defined by `@types/jquery`
const m: Mithril.Static;
const dayjs: typeof _dayjs;
// Extend JQuery with our custom functions, defined with $.fn
interface JQuery {
tooltip: TooltipJQueryFunction;
}
}
/**
* All global variables owned by flarum/core.
*/
declare global {
const app: Application;
}

View File

@@ -96,7 +96,6 @@ declare var _default: {
'utils/ExtensionData': typeof ExtensionData;
'utils/isExtensionEnabled': typeof isExtensionEnabled;
'utils/getCategorizedExtensions': typeof getCategorizedExtensions;
'utils/generateElementId': typeof generateElementId;
'components/SettingDropdown': typeof SettingDropdown;
'components/EditCustomFooterModal': typeof EditCustomFooterModal;
'components/SessionDropdown': typeof SessionDropdown;
@@ -133,7 +132,6 @@ import saveSettings from "./utils/saveSettings";
import ExtensionData from "./utils/ExtensionData";
import isExtensionEnabled from "./utils/isExtensionEnabled";
import getCategorizedExtensions from "./utils/getCategorizedExtensions";
import generateElementId from "./utils/generateElementId";
import SettingDropdown from "./components/SettingDropdown";
import EditCustomFooterModal from "./components/EditCustomFooterModal";
import SessionDropdown from "./components/SessionDropdown";

View File

@@ -1,4 +1,4 @@
export default class AdminHeader extends Component<import("../../common/Component").ComponentAttrs, undefined> {
export default class AdminHeader extends Component<import("../../common/Component").ComponentAttrs> {
constructor();
}
import Component from "../../common/Component";

View File

@@ -1,4 +1,4 @@
export default class AdminNav extends Component<import("../../common/Component").ComponentAttrs, undefined> {
export default class AdminNav extends Component<import("../../common/Component").ComponentAttrs> {
constructor();
query: Stream<string> | undefined;
scrollToActive(): void;

View File

@@ -0,0 +1,55 @@
export default class AdminPage extends Page {
settings: {} | undefined;
loading: boolean | undefined;
content(): string;
submitButton(): JSX.Element;
header(): JSX.Element;
headerInfo(): {
className: string;
icon: string;
title: string;
description: string;
};
/**
* buildSettingComponent takes a settings object and turns it into a component.
* Depending on the type of input, you can set the type to 'bool', 'select', or
* any standard <input> type. Any values inside the 'extra' object will be added
* to the component as an attribute.
*
* Alternatively, you can pass a callback that will be executed in ExtensionPage's
* context to include custom JSX elements.
*
* @example
*
* {
* setting: 'acme.checkbox',
* label: app.translator.trans('acme.admin.setting_label'),
* type: 'bool',
* help: app.translator.trans('acme.admin.setting_help'),
* className: 'Setting-item'
* }
*
* @example
*
* {
* setting: 'acme.select',
* label: app.translator.trans('acme.admin.setting_label'),
* type: 'select',
* options: {
* 'option1': 'Option 1 label',
* 'option2': 'Option 2 label',
* },
* default: 'option1',
* }
*
* @param setting
* @returns {JSX.Element}
*/
buildSettingComponent(entry: any): JSX.Element;
onsaved(): void;
setting(key: any, fallback?: string): any;
dirty(): {};
isChanged(): number;
saveSettings(e: any): Promise<void>;
}
import Page from "../../common/components/Page";

View File

@@ -1,4 +1,3 @@
export default class AppearancePage extends AdminPage<import("../../common/components/Page").IPageAttrs> {
constructor();
export default class AppearancePage extends AdminPage {
}
import AdminPage from "./AdminPage";

View File

@@ -1,5 +1,4 @@
export default class BasicsPage extends AdminPage<import("../../common/components/Page").IPageAttrs> {
constructor();
export default class BasicsPage extends AdminPage {
localeOptions: {} | undefined;
displayNameOptions: {} | undefined;
slugDriverOptions: {} | undefined;

View File

@@ -1,5 +1,4 @@
export default class DashboardPage extends AdminPage<import("../../common/components/Page").IPageAttrs> {
constructor();
export default class DashboardPage extends AdminPage {
availableWidgets(): ItemList;
}
import AdminPage from "./AdminPage";

View File

@@ -1,4 +1,4 @@
export default class DashboardWidget extends Component<import("../../common/Component").ComponentAttrs, undefined> {
export default class DashboardWidget extends Component<import("../../common/Component").ComponentAttrs> {
constructor();
/**
* Get the class name to apply to the widget.

View File

@@ -1,5 +1,4 @@
export default class ExtensionPage extends AdminPage<import("../../common/components/Page").IPageAttrs> {
constructor();
export default class ExtensionPage extends AdminPage {
extension: any;
changingState: boolean | undefined;
infoFields: {

View File

@@ -2,7 +2,7 @@
* The `HeaderPrimary` component displays primary header controls. On the
* default skin, these are shown just to the right of the forum title.
*/
export default class HeaderPrimary extends Component<import("../../common/Component").ComponentAttrs, undefined> {
export default class HeaderPrimary extends Component<import("../../common/Component").ComponentAttrs> {
constructor();
config(isInitialized: any, context: any): void;
/**

View File

@@ -1,7 +1,7 @@
/**
* The `HeaderSecondary` component displays secondary header controls.
*/
export default class HeaderSecondary extends Component<import("../../common/Component").ComponentAttrs, undefined> {
export default class HeaderSecondary extends Component<import("../../common/Component").ComponentAttrs> {
constructor();
/**
* Build an item list for the controls.

View File

@@ -1,5 +1,4 @@
export default class MailPage extends AdminPage<import("../../common/components/Page").IPageAttrs> {
constructor();
export default class MailPage extends AdminPage {
sendingTest: boolean | undefined;
refresh(): void;
status: {

View File

@@ -1,4 +1,4 @@
export default class PermissionGrid extends Component<import("../../common/Component").ComponentAttrs, undefined> {
export default class PermissionGrid extends Component<import("../../common/Component").ComponentAttrs> {
constructor();
permissionItems(): ItemList;
viewItems(): ItemList;

View File

@@ -1,4 +1,3 @@
export default class PermissionsPage extends AdminPage<import("../../common/components/Page").IPageAttrs> {
constructor();
export default class PermissionsPage extends AdminPage {
}
import AdminPage from "./AdminPage";

View File

@@ -1,5 +1,4 @@
export default class UploadImageButton extends Button<import("../../common/components/Button").IButtonAttrs> {
constructor();
export default class UploadImageButton extends Button {
loading: boolean;
/**
* Prompt the user to upload an image.

View File

@@ -1 +0,0 @@
export { nanoid as default } from 'nanoid';

View File

@@ -1,4 +1,4 @@
import type Mithril from 'mithril';
import * as Mithril from 'mithril';
export interface ComponentAttrs extends Mithril.Attributes {
}
/**
@@ -28,7 +28,7 @@ export interface ComponentAttrs extends Mithril.Attributes {
*
* @see https://mithril.js.org/components.html
*/
export default abstract class Component<Attrs extends ComponentAttrs = ComponentAttrs, State = undefined> implements Mithril.ClassComponent<Attrs> {
export default abstract class Component<T extends ComponentAttrs = ComponentAttrs> implements Mithril.ClassComponent<T> {
/**
* The root DOM element for the component.
*/
@@ -38,47 +38,35 @@ export default abstract class Component<Attrs extends ComponentAttrs = Component
*
* @see https://mithril.js.org/components.html#passing-data-to-components
*/
protected attrs: Attrs;
/**
* Class component state that is persisted between redraws.
*
* Updating this will **not** automatically trigger a redraw, unlike
* other frameworks.
*
* This is different to Vnode state, which is always an instance of your
* class component.
*
* This is `undefined` by default.
*/
protected state: State;
protected attrs: T;
/**
* @inheritdoc
*/
abstract view(vnode: Mithril.Vnode<Attrs, this>): Mithril.Children;
abstract view(vnode: Mithril.Vnode<T, this>): Mithril.Children;
/**
* @inheritdoc
*/
oninit(vnode: Mithril.Vnode<Attrs, this>): void;
oninit(vnode: Mithril.Vnode<T, this>): void;
/**
* @inheritdoc
*/
oncreate(vnode: Mithril.VnodeDOM<Attrs, this>): void;
oncreate(vnode: Mithril.VnodeDOM<T, this>): void;
/**
* @inheritdoc
*/
onbeforeupdate(vnode: Mithril.VnodeDOM<Attrs, this>): void;
onbeforeupdate(vnode: Mithril.VnodeDOM<T, this>): void;
/**
* @inheritdoc
*/
onupdate(vnode: Mithril.VnodeDOM<Attrs, this>): void;
onupdate(vnode: Mithril.VnodeDOM<T, this>): void;
/**
* @inheritdoc
*/
onbeforeremove(vnode: Mithril.VnodeDOM<Attrs, this>): void;
onbeforeremove(vnode: Mithril.VnodeDOM<T, this>): void;
/**
* @inheritdoc
*/
onremove(vnode: Mithril.VnodeDOM<Attrs, this>): void;
onremove(vnode: Mithril.VnodeDOM<T, this>): void;
/**
* Returns a jQuery object for this component's element. If you pass in a
* selector string, this method will return a jQuery object, using the current

View File

@@ -1,4 +1,4 @@
import type Mithril from 'mithril';
import * as Mithril from 'mithril';
/**
* The `Fragment` class represents a chunk of DOM that is rendered once with Mithril and then takes
* over control of its own DOM and lifecycle.

View File

@@ -1,6 +0,0 @@
import type Application from './Application';
declare const _default: Application;
/**
* The instance of Application within the common namespace.
*/
export default _default;

View File

@@ -1,5 +1,5 @@
import Component, { ComponentAttrs } from '../Component';
import type Mithril from 'mithril';
import Mithril from 'mithril';
export interface AlertAttrs extends ComponentAttrs {
/** The type of alert this is. Will be used to give the alert a class name of `Alert--{type}`. */
type?: string;

View File

@@ -2,7 +2,8 @@
* The `AlertManager` component provides an area in which `Alert` components can
* be shown and dismissed.
*/
export default class AlertManager extends Component<import("../Component").ComponentAttrs, undefined> {
export default class AlertManager extends Component<import("../Component").ComponentAttrs> {
constructor();
state: any;
}
import Component from "../Component";

View File

@@ -11,7 +11,7 @@
*
* All other attrs will be assigned as attributes on the badge element.
*/
export default class Badge extends Component<import("../Component").ComponentAttrs, undefined> {
export default class Badge extends Component<import("../Component").ComponentAttrs> {
constructor();
}
import Component from "../Component";

View File

@@ -1,69 +1,29 @@
import type Mithril from 'mithril';
import Component, { ComponentAttrs } from '../Component';
export interface IButtonAttrs extends ComponentAttrs {
/**
* Class(es) of an optional icon to be rendered within the button.
*
* If provided, the button will gain a `has-icon` class.
*/
icon?: string;
/**
* Disables button from user input.
*
* Default: `false`
*/
disabled?: boolean;
/**
* Show a loading spinner within the button.
*
* If `true`, also disables the button.
*
* Default: `false`
*/
loading?: boolean;
/**
* **DEPRECATED:** Please use the `aria-label` attribute instead. For tooltips, use
* the `<Tooltip>` component.
*
* Accessible text for the button. This should always be present if the button only
* contains an icon.
*
* The textual content of this attribute is passed to the DOM element as `aria-label`.
*
* @deprecated
*/
title?: string | Mithril.ChildArray;
/**
* Accessible text for the button. This should always be present if the button only
* contains an icon.
*
* The textual content of this attribute is passed to the DOM element as `aria-label`.
*/
'aria-label'?: string | Mithril.ChildArray;
/**
* Button type.
*
* Default: `"button"`
*
* @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attr-type
*/
type?: string;
}
/**
* The `Button` component defines an element which, when clicked, performs an
* action.
*
* Other attrs will be assigned as attributes on the `<button>` element.
* ### Attrs
*
* - `icon` The name of the icon class. If specified, the button will be given a
* 'has-icon' class name.
* - `disabled` Whether or not the button is disabled. If truthy, the button
* will be given a 'disabled' class name, and any `onclick` handler will be
* removed.
* - `loading` Whether or not the button should be in a disabled loading state.
*
* All other attrs will be assigned as attributes on the button element.
*
* Note that a Button has no default class names. This is because a Button can
* be used to represent any generic clickable control, like a menu item. Common
* styles can be applied by providing `className="Button"` to the Button component.
* be used to represent any generic clickable control, like a menu item.
*/
export default class Button<CustomAttrs extends IButtonAttrs = IButtonAttrs> extends Component<CustomAttrs> {
view(vnode: Mithril.Vnode<IButtonAttrs, never>): JSX.Element;
oncreate(vnode: Mithril.VnodeDOM<IButtonAttrs, this>): void;
export default class Button extends Component<import("../Component").ComponentAttrs> {
constructor();
/**
* Get the template for the button's content.
*
* @return {*}
* @protected
*/
protected getButtonContent(children: Mithril.Children): Mithril.ChildArray;
protected getButtonContent(children: any): any;
}
import Component from "../Component";

View File

@@ -10,7 +10,7 @@
* - `onchange` A callback to run when the checkbox is checked/unchecked.
* - `children` A text label to display next to the checkbox.
*/
export default class Checkbox extends Component<import("../Component").ComponentAttrs, undefined> {
export default class Checkbox extends Component<import("../Component").ComponentAttrs> {
constructor();
/**
* Get the template for the checkbox's display (tick/cross icon).

View File

@@ -14,7 +14,7 @@
* another component / DOM element.)
*
*/
export default class ConfirmDocumentUnload extends Component<import("../Component").ComponentAttrs, undefined> {
export default class ConfirmDocumentUnload extends Component<import("../Component").ComponentAttrs> {
constructor();
handler(): any;
boundHandler: (() => any) | undefined;

View File

@@ -15,7 +15,7 @@
*
* The children will be displayed as a list inside of the dropdown menu.
*/
export default class Dropdown extends Component<import("../Component").ComponentAttrs, undefined> {
export default class Dropdown extends Component<import("../Component").ComponentAttrs> {
static initAttrs(attrs: any): void;
constructor();
showing: boolean | undefined;

View File

@@ -7,7 +7,7 @@
*
* The children should be an array of items to show in the fieldset.
*/
export default class FieldSet extends Component<import("../Component").ComponentAttrs, undefined> {
export default class FieldSet extends Component<import("../Component").ComponentAttrs> {
constructor();
}
import Component from "../Component";

View File

@@ -6,7 +6,7 @@
* Links will default to internal; the 'external' attr must be set to
* `true` for the link to be external.
*/
export default class Link extends Component<import("../Component").ComponentAttrs, undefined> {
export default class Link extends Component<import("../Component").ComponentAttrs> {
constructor();
}
import Component from "../Component";

View File

@@ -11,7 +11,7 @@
* the `active` prop will automatically be set to true.
* - `force` Whether the page should be fully rerendered. Defaults to `true`.
*/
export default class LinkButton extends Button<import("./Button").IButtonAttrs> {
export default class LinkButton extends Button {
static initAttrs(attrs: any): void;
/**
* Determine whether a component with the given attrs is 'active'.
@@ -20,6 +20,5 @@ export default class LinkButton extends Button<import("./Button").IButtonAttrs>
* @return {Boolean}
*/
static isActive(attrs: Object): boolean;
constructor();
}
import Button from "./Button";

View File

@@ -4,7 +4,7 @@
*
* @abstract
*/
export default class Modal extends Component<import("../Component").ComponentAttrs, undefined> {
export default class Modal extends Component<import("../Component").ComponentAttrs> {
/**
* Determine whether or not the modal should be dismissible via an 'x' button.
*/

View File

@@ -3,7 +3,7 @@
* can be shown at once; loading a new component into the ModalManager will
* overwrite the previous one.
*/
export default class ModalManager extends Component<import("../Component").ComponentAttrs, undefined> {
export default class ModalManager extends Component<import("../Component").ComponentAttrs> {
constructor();
animateShow(readyCallback: any): void;
animateHide(): void;

View File

@@ -13,7 +13,7 @@
* - `drawer` Whether or not to show a button to toggle the app's drawer if
* there is no more history to pop.
*/
export default class Navigation extends Component<import("../Component").ComponentAttrs, undefined> {
export default class Navigation extends Component<import("../Component").ComponentAttrs> {
constructor();
/**
* Get the back button.

View File

@@ -1,15 +1,27 @@
import Component from '../Component';
export interface IPageAttrs {
key?: number;
routeName: string;
}
/**
* The `Page` component
*
* @abstract
*/
export default abstract class Page<CustomAttrs extends IPageAttrs = IPageAttrs> extends Component<CustomAttrs> {
oninit(vnode: any): void;
oncreate(vnode: any): void;
onremove(vnode: any): void;
export default class Page extends Component<import("../Component").ComponentAttrs> {
constructor();
/**
* A class name to apply to the body while the route is active.
*
* @type {String}
*/
bodyClass: string | undefined;
/**
* Whether we should scroll to the top of the page when its rendered.
*
* @type {Boolean}
*/
scrollTopOnCreate: boolean | undefined;
/**
* Whether the browser should restore scroll state on refreshes.
*
* @type {Boolean}
*/
useBrowserScrollRestoration: boolean | undefined;
}
import Component from "../Component";

View File

@@ -6,7 +6,7 @@
*
* - `text`
*/
export default class Placeholder extends Component<import("../Component").ComponentAttrs, undefined> {
export default class Placeholder extends Component<import("../Component").ComponentAttrs> {
constructor();
}
import Component from "../Component";

View File

@@ -6,11 +6,8 @@
* - `onchange` A callback to run when the selected value is changed.
* - `value` The value of the selected option.
* - `disabled` Disabled state for the input.
* - `wrapperAttrs` A map of attrs to be passed to the DOM element wrapping the `<select>`
*
* Other attributes are passed directly to the `<select>` element rendered to the DOM.
*/
export default class Select extends Component<import("../Component").ComponentAttrs, undefined> {
export default class Select extends Component<import("../Component").ComponentAttrs> {
constructor();
}
import Component from "../Component";

View File

@@ -2,7 +2,7 @@ export default Separator;
/**
* The `Separator` component defines a menu separator item.
*/
declare class Separator extends Component<import("../Component").ComponentAttrs, undefined> {
declare class Separator extends Component<import("../Component").ComponentAttrs> {
constructor();
}
declare namespace Separator {

View File

@@ -11,7 +11,7 @@
* - `disabled`
* - `preview`
*/
export default class TextEditor extends Component<import("../Component").ComponentAttrs, undefined> {
export default class TextEditor extends Component<import("../Component").ComponentAttrs> {
constructor();
/**
* The value of the editor.

View File

@@ -1,14 +1,8 @@
/**
* The `TextEditorButton` component displays a button suitable for the text
* editor toolbar.
*
* Automatically creates tooltips using the Tooltip component and provided text.
*
* ## Attrs
* - `title` - Tooltip for the button
*/
export default class TextEditorButton extends Button<import("./Button").IButtonAttrs> {
export default class TextEditorButton extends Button {
static initAttrs(attrs: any): void;
constructor();
}
import Button from "./Button";

View File

@@ -1,4 +1,4 @@
import type Mithril from 'mithril';
import * as Mithril from 'mithril';
import User from '../models/User';
/**
* The `avatar` helper displays a user's avatar.

View File

@@ -1,12 +0,0 @@
/**
* Calls `console.warn` with the provided arguments, but only if the forum is in debug mode.
*
* This function is intended to provide warnings to extension developers about issues with
* their extensions that may not be easily noticed when testing, such as accessibility
* issues.
*
* These warnings should be hidden on production forums to ensure webmasters are not
* inundated with do-gooders telling them they have an issue when it isn't something they
* can fix.
*/
export default function fireDebugWarning(...args: Parameters<typeof console.warn>): void;

View File

@@ -1,4 +1,4 @@
import type Mithril from 'mithril';
import * as Mithril from 'mithril';
/**
* The `fullTime` helper displays a formatted time string wrapped in a <time>
* tag.

View File

@@ -1,4 +1,4 @@
import type Mithril from 'mithril';
import * as Mithril from 'mithril';
/**
* The `highlight` helper searches for a word phrase in a string, and wraps
* matches with the <mark> tag.

View File

@@ -1,4 +1,4 @@
import type Mithril from 'mithril';
import * as Mithril from 'mithril';
/**
* The `humanTime` helper displays a time in a human-friendly time-ago format
* (e.g. '12 days ago'), wrapped in a <time> tag with other information about

View File

@@ -1,4 +1,4 @@
import type Mithril from 'mithril';
import * as Mithril from 'mithril';
/**
* The `icon` helper displays an icon.
*

View File

@@ -1,4 +1,4 @@
import type Mithril from 'mithril';
import * as Mithril from 'mithril';
/**
* The `listItems` helper wraps a collection of components in <li> tags,
* stripping out any unnecessary `Separator` components.

View File

@@ -1,4 +1,4 @@
import type Mithril from 'mithril';
import * as Mithril from 'mithril';
import User from '../models/User';
/**
* The `useronline` helper displays a green circle if the user is online

View File

@@ -1,4 +1,4 @@
import type Mithril from 'mithril';
import * as Mithril from 'mithril';
import User from '../models/User';
/**
* The `username` helper displays a user's username in a <span class="username">

View File

@@ -1,3 +1,2 @@
export { Extend };
import * as Extend from "./extend/index";
import app from "./app";
export { Extend, app };

View File

@@ -1,4 +1,4 @@
import type Mithril from 'mithril';
import Mithril from 'mithril';
/**
* Generates a route resolver for a given component.
* In addition to regular route resolver functionality:

View File

@@ -1,4 +1,4 @@
import type Mithril from 'mithril';
import Mithril from 'mithril';
import Alert, { AlertAttrs } from '../components/Alert';
/**
* Returned by `AlertManagerState.show`. Used to dismiss alerts.

View File

@@ -1,9 +1,9 @@
/**
* The `formatNumber` utility localizes a number into a string with the
* appropriate punctuation based on the provided locale otherwise will default to the users locale.
* appropriate punctuation.
*
* @example
* formatNumber(1234);
* // 1,234
*/
export default function formatNumber(number: number, locale?: string): string;
export default function formatNumber(number: number): string;

View File

@@ -1,3 +1,4 @@
import 'dayjs/plugin/relativeTime';
/**
* The `humanTime` utility converts a date to a localized, human-readable time-
* ago string.

View File

@@ -1,4 +1,4 @@
import type Mithril from 'mithril';
import Mithril from 'mithril';
/**
* Mithril 2 does not completely rerender the page if a route change leads to the same route
* (or the same component handling a different route). This util calls m.route.set, forcing a reonit.

View File

@@ -9,7 +9,7 @@
*
* @see https://getbootstrap.com/docs/3.4/javascript/#affix
*/
export default class AffixedSidebar extends Component<import("../../common/Component").ComponentAttrs, undefined> {
export default class AffixedSidebar extends Component<import("../../common/Component").ComponentAttrs> {
constructor();
boundOnresize: (() => void) | undefined;
onresize(): void;

View File

@@ -7,7 +7,7 @@
* - `className`
* - `user`
*/
export default class AvatarEditor extends Component<import("../../common/Component").ComponentAttrs, undefined> {
export default class AvatarEditor extends Component<import("../../common/Component").ComponentAttrs> {
constructor();
/**
* Whether or not an avatar upload is in progress.

View File

@@ -24,7 +24,7 @@ export default class CommentPost extends Post {
cardVisible: boolean | undefined;
refreshContent(): void;
contentHtml: any;
isEditing(): boolean;
isEditing(): any;
/**
* Toggle the visibility of a hidden post's content.
*/

View File

@@ -3,8 +3,14 @@
* content component with `load` and then its position/state can be altered with
* `show`, `hide`, `close`, `minimize`, `fullScreen`, and `exitFullScreen`.
*/
export default class Composer extends Component<import("../../common/Component").ComponentAttrs, undefined> {
export default class Composer extends Component<import("../../common/Component").ComponentAttrs> {
constructor();
/**
* The composer's "state".
*
* @type {ComposerState}
*/
state: ComposerState | undefined;
/**
* Whether or not the composer currently has focus.
*
@@ -102,4 +108,5 @@ export default class Composer extends Component<import("../../common/Component")
changeHeight(height: any): void;
}
import Component from "../../common/Component";
import ComposerState from "../states/ComposerState";
import ItemList from "../../common/utils/ItemList";

View File

@@ -15,7 +15,7 @@
*
* @abstract
*/
export default class ComposerBody extends Component<import("../../common/Component").ComponentAttrs, undefined> {
export default class ComposerBody extends Component<import("../../common/Component").ComponentAttrs> {
constructor();
composer: any;
/**

View File

@@ -2,8 +2,7 @@
* The `ComposerButton` component displays a button suitable for the composer
* controls.
*/
export default class ComposerButton extends Button<import("../../common/components/Button").IButtonAttrs> {
export default class ComposerButton extends Button {
static initAttrs(attrs: any): void;
constructor();
}
import Button from "../../common/components/Button";

View File

@@ -10,7 +10,7 @@
* - `className` A CSS class for the element surrounding the preview.
* - `surround` A callback that can execute code before and after re-render, e.g. for scroll anchoring.
*/
export default class ComposerPostPreview extends Component<import("../../common/Component").ComponentAttrs, undefined> {
export default class ComposerPostPreview extends Component<import("../../common/Component").ComponentAttrs> {
static initAttrs(attrs: any): void;
constructor();
updateInterval: number | undefined;

View File

@@ -5,7 +5,7 @@
*
* - `discussion`
*/
export default class DiscussionHero extends Component<import("../../common/Component").ComponentAttrs, undefined> {
export default class DiscussionHero extends Component<import("../../common/Component").ComponentAttrs> {
constructor();
/**
* Build an item list for the contents of the discussion hero.

View File

@@ -5,7 +5,7 @@
*
* - `state` A DiscussionListState object that represents the discussion lists's state.
*/
export default class DiscussionList extends Component<import("../../common/Component").ComponentAttrs, undefined> {
export default class DiscussionList extends Component<import("../../common/Component").ComponentAttrs> {
constructor();
}
import Component from "../../common/Component";

View File

@@ -7,7 +7,7 @@
* - `discussion`
* - `params`
*/
export default class DiscussionListItem extends Component<import("../../common/Component").ComponentAttrs, undefined> {
export default class DiscussionListItem extends Component<import("../../common/Component").ComponentAttrs> {
constructor();
/**
* Set up a subtree retainer so that the discussion will not be redrawn

View File

@@ -7,7 +7,7 @@
*
* - `state` A DiscussionListState object that represents the discussion lists's state.
*/
export default class DiscussionListPane extends Component<import("../../common/Component").ComponentAttrs, undefined> {
export default class DiscussionListPane extends Component<import("../../common/Component").ComponentAttrs> {
constructor();
/**
* Are we on a device that's larger than we consider "mobile"?

View File

@@ -2,9 +2,7 @@
* The `DiscussionPage` component displays a whole discussion page, including
* the discussion list pane, the hero, the posts, and the sidebar.
*/
export default class DiscussionPage extends Page<import("../../common/components/Page").IPageAttrs> {
constructor();
useBrowserScrollRestoration: boolean | undefined;
export default class DiscussionPage extends Page {
/**
* The discussion that is being viewed.
*
@@ -17,37 +15,6 @@ export default class DiscussionPage extends Page<import("../../common/components
* @type {number}
*/
near: number | undefined;
bodyClass: string | undefined;
/**
* List of components shown while the discussion is loading.
*
* @returns {ItemList}
*/
loadingItems(): ItemList;
/**
* Function that renders the `sidebarItems` ItemList.
*
* @returns {import('mithril').Children}
*/
sidebar(): import('mithril').Children;
/**
* Renders the discussion's hero.
*
* @returns {import('mithril').Children}
*/
hero(): import('mithril').Children;
/**
* List of items rendered as the main page content.
*
* @returns {ItemList}
*/
pageContent(): ItemList;
/**
* List of items rendered inside the main page content container.
*
* @returns {ItemList}
*/
mainContent(): ItemList;
/**
* Load the discussion from the API or use the preloaded one.
*/
@@ -82,5 +49,5 @@ export default class DiscussionPage extends Page<import("../../common/components
positionChanged(startNumber: any, endNumber: any): void;
}
import Page from "../../common/components/Page";
import ItemList from "../../common/utils/ItemList";
import PostStreamState from "../states/PostStreamState";
import ItemList from "../../common/utils/ItemList";

View File

@@ -1,5 +1,5 @@
import { SearchSource } from './Search';
import type Mithril from 'mithril';
import Mithril from 'mithril';
/**
* The `DiscussionsSearchSource` finds and displays discussion search results in
* the search dropdown.

View File

@@ -3,5 +3,7 @@
* page.
*/
export default class DiscussionsUserPage extends UserPage {
state: DiscussionListState | undefined;
}
import UserPage from "./UserPage";
import DiscussionListState from "../states/DiscussionListState";

View File

@@ -2,7 +2,7 @@
* The `HeaderPrimary` component displays primary header controls. On the
* default skin, these are shown just to the right of the forum title.
*/
export default class HeaderPrimary extends Component<import("../../common/Component").ComponentAttrs, undefined> {
export default class HeaderPrimary extends Component<import("../../common/Component").ComponentAttrs> {
constructor();
/**
* Build an item list for the controls.

View File

@@ -3,7 +3,7 @@
* the search box and the user menu. On the default skin, these are shown on the
* right side of the header.
*/
export default class HeaderSecondary extends Component<import("../../common/Component").ComponentAttrs, undefined> {
export default class HeaderSecondary extends Component<import("../../common/Component").ComponentAttrs> {
constructor();
/**
* Build an item list for the controls.

View File

@@ -2,12 +2,9 @@
* The `IndexPage` component displays the index page, including the welcome
* hero, the sidebar, and the discussion list.
*/
export default class IndexPage extends Page<import("../../common/components/Page").IPageAttrs> {
export default class IndexPage extends Page {
static providesInitialSearch: boolean;
constructor();
lastDiscussion: any;
bodyClass: string | undefined;
scrollTopOnCreate: boolean | undefined;
setTitle(): void;
/**
* Get the component to display as the hero.

View File

@@ -2,7 +2,7 @@
* The `LoadingPost` component shows a placeholder that looks like a post,
* indicating that the post is loading.
*/
export default class LoadingPost extends Component<import("../../common/Component").ComponentAttrs, undefined> {
export default class LoadingPost extends Component<import("../../common/Component").ComponentAttrs> {
constructor();
}
import Component from "../../common/Component";

View File

@@ -6,8 +6,7 @@
*
* - `path`
*/
export default class LogInButton extends Button<import("../../common/components/Button").IButtonAttrs> {
export default class LogInButton extends Button {
static initAttrs(attrs: any): void;
constructor();
}
import Button from "../../common/components/Button";

View File

@@ -1,7 +1,7 @@
/**
* The `LogInButtons` component displays a collection of social login buttons.
*/
export default class LogInButtons extends Component<import("../../common/Component").ComponentAttrs, undefined> {
export default class LogInButtons extends Component<import("../../common/Component").ComponentAttrs> {
constructor();
/**
* Build a list of LogInButton components.

View File

@@ -8,7 +8,7 @@
*
* @abstract
*/
export default class Notification extends Component<import("../../common/Component").ComponentAttrs, undefined> {
export default class Notification extends Component<import("../../common/Component").ComponentAttrs> {
constructor();
/**
* Get the name of the icon that should be displayed in the notification.

View File

@@ -6,7 +6,7 @@
*
* - `user`
*/
export default class NotificationGrid extends Component<import("../../common/Component").ComponentAttrs, undefined> {
export default class NotificationGrid extends Component<import("../../common/Component").ComponentAttrs> {
constructor();
/**
* Information about the available notification methods.

View File

@@ -2,7 +2,7 @@
* The `NotificationList` component displays a list of the logged-in user's
* notifications, grouped by discussion.
*/
export default class NotificationList extends Component<import("../../common/Component").ComponentAttrs, undefined> {
export default class NotificationList extends Component<import("../../common/Component").ComponentAttrs> {
constructor();
content(state: any): any;
$notifications: JQuery<HTMLElement> | undefined;

View File

@@ -2,8 +2,6 @@
* The `NotificationsPage` component shows the notifications list. It is only
* used on mobile devices where the notifications dropdown is within the drawer.
*/
export default class NotificationsPage extends Page<import("../../common/components/Page").IPageAttrs> {
constructor();
bodyClass: string | undefined;
export default class NotificationsPage extends Page {
}
import Page from "../../common/components/Page";

View File

@@ -9,7 +9,7 @@
*
* @abstract
*/
export default class Post extends Component<import("../../common/Component").ComponentAttrs, undefined> {
export default class Post extends Component<import("../../common/Component").ComponentAttrs> {
constructor();
loading: boolean | undefined;
/**

View File

@@ -6,7 +6,7 @@
*
* - `post`
*/
export default class PostEdited extends Component<import("../../common/Component").ComponentAttrs, undefined> {
export default class PostEdited extends Component<import("../../common/Component").ComponentAttrs> {
constructor();
}
import Component from "../../common/Component";

View File

@@ -7,7 +7,7 @@
*
* - `post`
*/
export default class PostMeta extends Component<import("../../common/Component").ComponentAttrs, undefined> {
export default class PostMeta extends Component<import("../../common/Component").ComponentAttrs> {
constructor();
/**
* Get the permalink for the given post.

View File

@@ -6,7 +6,7 @@
*
* - `post`
*/
export default class PostPreview extends Component<import("../../common/Component").ComponentAttrs, undefined> {
export default class PostPreview extends Component<import("../../common/Component").ComponentAttrs> {
constructor();
}
import Component from "../../common/Component";

View File

@@ -9,7 +9,7 @@
* - `targetPost`
* - `onPositionChange`
*/
export default class PostStream extends Component<import("../../common/Component").ComponentAttrs, undefined> {
export default class PostStream extends Component<import("../../common/Component").ComponentAttrs> {
constructor();
discussion: any;
stream: any;

View File

@@ -7,7 +7,7 @@
* - `stream`
* - `className`
*/
export default class PostStreamScrubber extends Component<import("../../common/Component").ComponentAttrs, undefined> {
export default class PostStreamScrubber extends Component<import("../../common/Component").ComponentAttrs> {
constructor();
stream: any;
handlers: {} | undefined;

View File

@@ -5,7 +5,7 @@
*
* - `post`
*/
export default class PostUser extends Component<import("../../common/Component").ComponentAttrs, undefined> {
export default class PostUser extends Component<import("../../common/Component").ComponentAttrs> {
constructor();
/**
* Show the user card.

View File

@@ -6,7 +6,7 @@
*
* - `discussion`
*/
export default class ReplyPlaceholder extends Component<import("../../common/Component").ComponentAttrs, undefined> {
export default class ReplyPlaceholder extends Component<import("../../common/Component").ComponentAttrs> {
constructor();
anchorPreview(preview: any): void;
}

View File

@@ -2,7 +2,7 @@ import Component, { ComponentAttrs } from '../../common/Component';
import ItemList from '../../common/utils/ItemList';
import KeyboardNavigatable from '../utils/KeyboardNavigatable';
import SearchState from '../states/SearchState';
import type Mithril from 'mithril';
import Mithril from 'mithril';
/**
* The `SearchSource` interface defines a section of search results in the
* search dropdown.

Some files were not shown because too many files have changed in this diff Show More