1
0
mirror of https://github.com/flarum/core.git synced 2025-08-15 12:54:47 +02:00

Compare commits

..

3 Commits

Author SHA1 Message Date
Alexander Skvortsov
dd5c516156 Release v1.2.1 2022-03-10 15:47:26 -05:00
Alexander Skvortsov
085c44ec63 chore: rebuild dist js 2022-03-10 15:44:30 -05:00
Alexander Skvortsov
60600f4d2b chore: bump rich text ICU Message formatter
This fixes https://discuss.flarum.org/d/29914-utf-encoding-error-in-title/6
2022-03-10 15:37:44 -05:00
43 changed files with 974 additions and 2141 deletions

1
.gitattributes vendored
View File

@@ -14,6 +14,5 @@ js/dist/* -diff
js/dist/* linguist-generated
js/dist-typings/* linguist-generated
js/yarn.lock -diff
js/package-lock.json -diff
* text=auto eol=lf

View File

@@ -12,4 +12,4 @@ jobs:
with:
enable_backend_testing: true
backend_directory: .
backend_directory: .

View File

@@ -15,9 +15,7 @@ jobs:
enable_typescript: true
frontend_directory: ./js
backend_directory: .
js_package_manager: yarn
main_git_branch: master
secrets:
bundlewatch_github_token: ${{ secrets.BUNDLEWATCH_GITHUB_TOKEN }}
bundlewatch_github_token: ${{ secrets.BUNDLEWATCH_GITHUB_TOKEN }}

View File

@@ -1,5 +1,10 @@
# Changelog
## [1.2.1](https://github.com/flarum/core/compare/v1.2.0...v1.2.1)
### Fixed
- Don't escape single quotes in discussion title meta tags (60600f4d2b8f0c5dac94c329041427a0a08fad42)
## [1.2.0](https://github.com/flarum/core/compare/v1.1.1...v1.2.0)
### Added

View File

@@ -1,517 +0,0 @@
// Type definitions for Mithril 2.0
// Project: https://mithril.js.org/, https://github.com/mithriljs/mithril.js
// Definitions by: Mike Linkovich <https://github.com/spacejack>, András Parditka <https://github.com/andraaspar>, Isiah Meadows <https://github.com/isiahmeadows>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
// TypeScript Version: 3.2
/** Renders a vnode structure into a DOM element. */
declare function render(el: Element, vnodes: Mithril.Children): void;
/** Mounts a component to a DOM element, enabling it to autoredraw on user events. */
declare function mount(element: Element, component: Mithril.ComponentTypes<any, any>): void;
/** Unmounts a component from a DOM element. */
declare function mount(element: Element, component: null): void; // tslint:disable-line unified-signatures
/** Makes an XHR request and returns a promise. */
declare function request<T>(options: Mithril.RequestOptions<T> & { url: string }): Promise<T>;
/** Makes an XHR request and returns a promise. */
declare function request<T>(url: string, options?: Mithril.RequestOptions<T>): Promise<T>;
/** Makes a JSON-P request and returns a promise. */
declare function jsonp<T>(options: Mithril.JsonpOptions & { url: string }): Promise<T>; // tslint:disable-line:no-unnecessary-generics
/** Makes a JSON-P request and returns a promise. */
declare function jsonp<T>(url: string, options?: Mithril.JsonpOptions): Promise<T>; // tslint:disable-line:no-unnecessary-generics
declare namespace Mithril {
interface CommonAttributes<Attrs, State> {
/** The oninit hook is called before a vnode is touched by the virtual DOM engine. */
oninit?(this: State, vnode: Vnode<Attrs, State>): any;
/** The oncreate hook is called after a DOM element is created and attached to the document. */
oncreate?(this: State, vnode: VnodeDOM<Attrs, State>): any;
/** The onbeforeremove hook is called before a DOM element is detached from the document. If a Promise is returned, Mithril only detaches the DOM element after the promise completes. */
onbeforeremove?(this: State, vnode: VnodeDOM<Attrs, State>): Promise<any> | void;
/** The onremove hook is called before a DOM element is removed from the document. */
onremove?(this: State, vnode: VnodeDOM<Attrs, State>): any;
/** The onbeforeupdate hook is called before a vnode is diffed in a update. */
onbeforeupdate?(this: State, vnode: Vnode<Attrs, State>, old: VnodeDOM<Attrs, State>): boolean | void;
/** The onupdate hook is called after a DOM element is updated, while attached to the document. */
onupdate?(this: State, vnode: VnodeDOM<Attrs, State>): any;
/** A key to optionally associate with this element. */
key?: string | number | undefined;
}
interface Hyperscript {
/** Creates a virtual element (Vnode). */
(selector: string, ...children: Children[]): Vnode<any, any>;
/** Creates a virtual element (Vnode). */
(selector: string, attributes: Attributes, ...children: Children[]): Vnode<any, any>;
/** Creates a virtual element (Vnode). */
<Attrs, State>(component: ComponentTypes<Attrs, State>, ...args: Children[]): Vnode<Attrs, State>;
/** Creates a virtual element (Vnode). */
<Attrs, State>(
component: ComponentTypes<Attrs, State>,
attributes: Attrs & CommonAttributes<Attrs, State>,
...args: Children[]
): Vnode<Attrs, State>;
/** Creates a fragment virtual element (Vnode). */
fragment(attrs: CommonAttributes<any, any> & { [key: string]: any }, children: ChildArrayOrPrimitive): Vnode<any, any>;
/** Turns an HTML string into a virtual element (Vnode). Do not use trust on unsanitized user input. */
trust(html: string): Vnode<any, any>;
}
interface RouteResolver<Attrs = {}, State = {}> {
/** The onmatch hook is called when the router needs to find a component to render. */
onmatch?(
this: this,
args: Attrs,
requestedPath: string,
route: string,
): ComponentTypes<any, any> | Promise<any> | void;
/** The render method is called on every redraw for a matching route. */
render?(this: this, vnode: Vnode<Attrs, State>): Children;
}
/** This represents a key-value mapping linking routes to components. */
interface RouteDefs {
/** The key represents the route. The value represents the corresponding component. */
[url: string]: ComponentTypes<any, any> | RouteResolver<any, any>;
}
interface RouteOptions {
/** Routing parameters. If path has routing parameter slots, the properties of this object are interpolated into the path string. */
replace?: boolean | undefined;
/** The state object to pass to the underlying history.pushState / history.replaceState call. */
state?: any;
/** The title string to pass to the underlying history.pushState / history.replaceState call. */
title?: string | undefined;
}
interface RouteLinkAttrs extends Attributes {
href: string;
selector?: string | ComponentTypes<any> | undefined;
options?: RouteOptions | undefined;
}
interface Route {
/** Creates application routes and mounts Components and/or RouteResolvers to a DOM element. */
(element: Element, defaultRoute: string, routes: RouteDefs): void;
/** Returns the last fully resolved routing path, without the prefix. */
get(): string;
/** Redirects to a matching route or to the default route if no matching routes can be found. */
set(route: string, data?: any, options?: RouteOptions): void;
/** Defines a router prefix which is a fragment of the URL that dictates the underlying strategy used by the router. */
prefix: string;
/** This Component renders a link <a href> that will use the current routing strategy */
Link: Component<RouteLinkAttrs>;
/** Returns the named parameter value from the current route. */
param(name: string): string;
/** Gets all route parameters. */
param(): any;
}
interface RequestOptions<T> {
/** The HTTP method to use. */
method?: string | undefined;
/** The data to be interpolated into the URL and serialized into the querystring. */
params?: { [key: string]: any } | undefined;
/** The data to be serialized into the request body. */
body?: (XMLHttpRequest['send'] extends (x: infer R) => any ? R : never) | (object & { [id: string]: any }) | undefined;
/** Whether the request should be asynchronous. Defaults to true. */
async?: boolean | undefined;
/** A username for HTTP authorization. */
user?: string | undefined;
/** A password for HTTP authorization. */
password?: string | undefined;
/** Whether to send cookies to 3rd party domains. */
withCredentials?: boolean | undefined;
/** Exposes the underlying XMLHttpRequest object for low-level configuration. */
config?(xhr: XMLHttpRequest, options: this): XMLHttpRequest | void;
/** Headers to append to the request before sending it. */
headers?: { [key: string]: string } | undefined;
/** A constructor to be applied to each object in the response. */
type?: new (o: any) => any;
/** A serialization method to be applied to data. Defaults to JSON.stringify, or if options.data is an instance of FormData, defaults to the identity function. */
serialize?(data: any): any;
/** A deserialization method to be applied to the response. Defaults to a small wrapper around JSON.parse that returns null for empty responses. */
deserialize?(data: string): T;
/** A hook to specify how the XMLHttpRequest response should be read. Useful for reading response headers and cookies. Defaults to a function that returns xhr.responseText */
extract?(xhr: XMLHttpRequest, options: this): T;
/**
* Force the use of the HTTP body section for data in GET requests when set to true,
* or the use of querystring for other HTTP methods when set to false.
* Defaults to false for GET requests and true for other methods.
*/
useBody?: boolean | undefined;
/** If false, redraws mounted components upon completion of the request. If true, it does not. */
background?: boolean | undefined;
/** Milliseconds a request can take before automatically being terminated. */
timeout?: number | undefined;
/** The expected type of the response, as a legal value of XMLHttpRequest.responseType. */
responseType?: '' | 'arraybuffer' | 'blob' | 'document' | 'json' | 'text' | undefined;
}
interface JsonpOptions {
/** The data to be interpolated into the URL and serialized into the querystring. */
params?: { [id: string]: any } | undefined;
/** The data to be serialized into the request body. */
body?: any;
/** A constructor to be applied to each object in the response. */
type?: new (o: any) => any;
/** The name of the function that will be called as the callback. */
callbackName?: string | undefined;
/** The name of the querystring parameter name that specifies the callback name. */
callbackKey?: string | undefined;
/** If false, redraws mounted components upon completion of the request. If true, it does not. */
background?: boolean | undefined;
}
interface Redraw {
/** Manually triggers an asynchronous redraw of mounted components. */
(): void;
/** Manually triggers a synchronous redraw of mounted components. */
sync(): void;
}
type Params = object & ParamsRec;
interface ParamsRec {
// Ideally, it'd be this:
// `[key: string | number]: Params | !symbol & !object`
[key: string]: string | number | boolean | null | undefined | Params;
}
interface Static extends Hyperscript {
route: Route;
mount: typeof mount;
render: typeof render;
redraw: Redraw;
request: typeof request;
jsonp: typeof jsonp;
/** Returns an object with key/value pairs parsed from a string of the form: ?a=1&b=2 */
parseQueryString(queryString: string): Params;
/** Turns the key/value pairs of an object into a string of the form: a=1&b=2 */
buildQueryString(values: Params): string;
/** Parse path name */
parsePathname(url: string): { path: string; params: Params };
/** Build path name */
buildPathname(template: string, params?: Params): string;
}
// Vnode children types
type Child = Vnode<any, any> | string | number | boolean | null | undefined;
interface ChildArray extends Array<Children> {}
type Children = Child | ChildArray;
type ChildArrayOrPrimitive = ChildArray | string | number | boolean;
/** Virtual DOM nodes, or vnodes, are Javascript objects that represent an element (or parts of the DOM). */
interface Vnode<Attrs = {}, State = {}> {
/** The nodeName of a DOM element. It may also be the string [ if a vnode is a fragment, # if it's a text vnode, or < if it's a trusted HTML vnode. Additionally, it may be a component. */
tag: string | ComponentTypes<Attrs, State>;
/** A hashmap of DOM attributes, events, properties and lifecycle methods. */
attrs: Attrs;
/** An object that is persisted between redraws. In component vnodes, state is a shallow clone of the component object. */
state: State;
/** The value used to map a DOM element to its respective item in an array of data. */
key?: string | number | undefined;
/** In most vnode types, the children property is an array of vnodes. For text and trusted HTML vnodes, The children property is either a string, a number or a boolean. */
children?: ChildArrayOrPrimitive | undefined;
/**
* This is used instead of children if a vnode contains a text node as its only child.
* This is done for performance reasons.
* Component vnodes never use the text property even if they have a text node as their only child.
*/
text?: string | number | boolean | undefined;
}
// In some lifecycle methods, Vnode will have a dom property
// and possibly a domSize property.
interface VnodeDOM<Attrs = {}, State = {}> extends Vnode<Attrs, State> {
/** Points to the element that corresponds to the vnode. */
dom: Element;
/** This defines the number of DOM elements that the vnode represents (starting from the element referenced by the dom property). */
domSize?: number | undefined;
}
type _NoLifecycle<T> = Omit<T, keyof Component>;
interface CVnode<A = {}> extends Vnode<A, ClassComponent<A>> {}
interface CVnodeDOM<A = {}> extends VnodeDOM<A, ClassComponent<A>> {}
/**
* Components are a mechanism to encapsulate parts of a view to make code easier to organize and/or reuse.
* Any Javascript object that has a view method can be used as a Mithril component.
* Components can be consumed via the m() utility.
*/
interface Component<Attrs = {}, State = {}> {
/** The oninit hook is called before a vnode is touched by the virtual DOM engine. */
oninit?(this: _NoLifecycle<this & State>, vnode: Vnode<Attrs, _NoLifecycle<this & State>>): any;
/** The oncreate hook is called after a DOM element is created and attached to the document. */
oncreate?(this: _NoLifecycle<this & State>, vnode: VnodeDOM<Attrs, _NoLifecycle<this & State>>): any;
/** The onbeforeremove hook is called before a DOM element is detached from the document. If a Promise is returned, Mithril only detaches the DOM element after the promise completes. */
onbeforeremove?(this: _NoLifecycle<this & State>, vnode: VnodeDOM<Attrs, _NoLifecycle<this & State>>): Promise<any> | void;
/** The onremove hook is called before a DOM element is removed from the document. */
onremove?(this: _NoLifecycle<this & State>, vnode: VnodeDOM<Attrs, _NoLifecycle<this & State>>): any;
/** The onbeforeupdate hook is called before a vnode is diffed in a update. */
onbeforeupdate?(this: _NoLifecycle<this & State>, vnode: Vnode<Attrs, _NoLifecycle<this & State>>, old: VnodeDOM<Attrs, _NoLifecycle<this & State>>): boolean | void;
/** The onupdate hook is called after a DOM element is updated, while attached to the document. */
onupdate?(this: _NoLifecycle<this & State>, vnode: VnodeDOM<Attrs, _NoLifecycle<this & State>>): any;
/** Creates a view out of virtual elements. */
view(this: _NoLifecycle<this & State>, vnode: Vnode<Attrs, _NoLifecycle<this & State>>): Children | null | void;
}
/**
* Components are a mechanism to encapsulate parts of a view to make code easier to organize and/or reuse.
* Any class that implements a view method can be used as a Mithril component.
* Components can be consumed via the m() utility.
*/
interface ClassComponent<A = {}> {
/** The oninit hook is called before a vnode is touched by the virtual DOM engine. */
oninit?(vnode: Vnode<A, this>): any;
/** The oncreate hook is called after a DOM element is created and attached to the document. */
oncreate?(vnode: VnodeDOM<A, this>): any;
/** The onbeforeremove hook is called before a DOM element is detached from the document. If a Promise is returned, Mithril only detaches the DOM element after the promise completes. */
onbeforeremove?(vnode: VnodeDOM<A, this>): Promise<any> | void;
/** The onremove hook is called before a DOM element is removed from the document. */
onremove?(vnode: VnodeDOM<A, this>): any;
/** The onbeforeupdate hook is called before a vnode is diffed in a update. */
onbeforeupdate?(vnode: Vnode<A, this>, old: VnodeDOM<A, this>): boolean | void;
/** The onupdate hook is called after a DOM element is updated, while attached to the document. */
onupdate?(vnode: VnodeDOM<A, this>): any;
/** Creates a view out of virtual elements. */
view(vnode: Vnode<A, this>): Children | null | void;
}
/**
* Components are a mechanism to encapsulate parts of a view to make code easier to organize and/or reuse.
* Any function that returns an object with a view method can be used as a Mithril component.
* Components can be consumed via the m() utility.
*/
type FactoryComponent<A = {}> = (vnode: Vnode<A>) => Component<A>;
/**
* Components are a mechanism to encapsulate parts of a view to make code easier to organize and/or reuse.
* Any function that returns an object with a view method can be used as a Mithril component.
* Components can be consumed via the m() utility.
*/
type ClosureComponent<A = {}> = FactoryComponent<A>;
/**
* Components are a mechanism to encapsulate parts of a view to make code easier to organize and/or reuse.
* Any Javascript object that has a view method is a Mithril component. Components can be consumed via the m() utility.
*/
type Comp<Attrs = {}, State = {}> = _NoLifecycle<State> & Component<Attrs, _NoLifecycle<State>>;
/** Components are a mechanism to encapsulate parts of a view to make code easier to organize and/or reuse. Components can be consumed via the m() utility. */
type ComponentTypes<A = {}, S = {}> =
| Component<A, S>
| { new (vnode: CVnode<A>): ClassComponent<A> }
| FactoryComponent<A>;
/** This represents the attributes available for configuring virtual elements, beyond the applicable DOM attributes. */
interface Attributes extends CommonAttributes<any, any> {
/** The class name(s) for this virtual element, as a space-separated list. */
className?: string | undefined;
/** The class name(s) for this virtual element, as a space-separated list. */
class?: string | undefined;
/** Any other virtual element properties, including attributes and event handlers. */
[property: string]: any;
}
}
declare global {
namespace JSX {
// tslint:disable-next-line:no-empty-interface
interface Element extends Mithril.Vnode {}
// tslint:disable-next-line:no-empty-interface
interface IntrinsicAttributes extends Mithril.Attributes {}
// tslint:disable-next-line:no-empty-interface
interface IntrinsicClassAttributes extends Mithril.Attributes {}
interface IntrinsicElements {
// HTML
a: Mithril.Attributes;
abbr: Mithril.Attributes;
address: Mithril.Attributes;
area: Mithril.Attributes;
article: Mithril.Attributes;
aside: Mithril.Attributes;
audio: Mithril.Attributes;
b: Mithril.Attributes;
base: Mithril.Attributes;
bdi: Mithril.Attributes;
bdo: Mithril.Attributes;
big: Mithril.Attributes;
blockquote: Mithril.Attributes;
body: Mithril.Attributes;
br: Mithril.Attributes;
button: Mithril.Attributes;
canvas: Mithril.Attributes;
caption: Mithril.Attributes;
cite: Mithril.Attributes;
code: Mithril.Attributes;
col: Mithril.Attributes;
colgroup: Mithril.Attributes;
data: Mithril.Attributes;
datalist: Mithril.Attributes;
dd: Mithril.Attributes;
del: Mithril.Attributes;
details: Mithril.Attributes;
dfn: Mithril.Attributes;
dialog: Mithril.Attributes;
div: Mithril.Attributes;
dl: Mithril.Attributes;
dt: Mithril.Attributes;
em: Mithril.Attributes;
embed: Mithril.Attributes;
fieldset: Mithril.Attributes;
figcaption: Mithril.Attributes;
figure: Mithril.Attributes;
footer: Mithril.Attributes;
form: Mithril.Attributes;
h1: Mithril.Attributes;
h2: Mithril.Attributes;
h3: Mithril.Attributes;
h4: Mithril.Attributes;
h5: Mithril.Attributes;
h6: Mithril.Attributes;
head: Mithril.Attributes;
header: Mithril.Attributes;
hgroup: Mithril.Attributes;
hr: Mithril.Attributes;
html: Mithril.Attributes;
i: Mithril.Attributes;
iframe: Mithril.Attributes;
img: Mithril.Attributes;
input: Mithril.Attributes;
ins: Mithril.Attributes;
kbd: Mithril.Attributes;
keygen: Mithril.Attributes;
label: Mithril.Attributes;
legend: Mithril.Attributes;
li: Mithril.Attributes;
link: Mithril.Attributes;
main: Mithril.Attributes;
map: Mithril.Attributes;
mark: Mithril.Attributes;
menu: Mithril.Attributes;
menuitem: Mithril.Attributes;
meta: Mithril.Attributes;
meter: Mithril.Attributes;
nav: Mithril.Attributes;
noindex: Mithril.Attributes;
noscript: Mithril.Attributes;
object: Mithril.Attributes;
ol: Mithril.Attributes;
optgroup: Mithril.Attributes;
option: Mithril.Attributes;
output: Mithril.Attributes;
p: Mithril.Attributes;
param: Mithril.Attributes;
picture: Mithril.Attributes;
pre: Mithril.Attributes;
progress: Mithril.Attributes;
q: Mithril.Attributes;
rp: Mithril.Attributes;
rt: Mithril.Attributes;
ruby: Mithril.Attributes;
s: Mithril.Attributes;
samp: Mithril.Attributes;
script: Mithril.Attributes;
section: Mithril.Attributes;
select: Mithril.Attributes;
small: Mithril.Attributes;
source: Mithril.Attributes;
span: Mithril.Attributes;
strong: Mithril.Attributes;
style: Mithril.Attributes;
sub: Mithril.Attributes;
summary: Mithril.Attributes;
sup: Mithril.Attributes;
table: Mithril.Attributes;
template: Mithril.Attributes;
tbody: Mithril.Attributes;
td: Mithril.Attributes;
textarea: Mithril.Attributes;
tfoot: Mithril.Attributes;
th: Mithril.Attributes;
thead: Mithril.Attributes;
time: Mithril.Attributes;
title: Mithril.Attributes;
tr: Mithril.Attributes;
track: Mithril.Attributes;
u: Mithril.Attributes;
ul: Mithril.Attributes;
var: Mithril.Attributes;
video: Mithril.Attributes;
wbr: Mithril.Attributes;
webview: Mithril.Attributes;
// SVG
svg: Mithril.Attributes;
animate: Mithril.Attributes;
animateMotion: Mithril.Attributes;
animateTransform: Mithril.Attributes;
circle: Mithril.Attributes;
clipPath: Mithril.Attributes;
defs: Mithril.Attributes;
desc: Mithril.Attributes;
ellipse: Mithril.Attributes;
feBlend: Mithril.Attributes;
feColorMatrix: Mithril.Attributes;
feComponentTransfer: Mithril.Attributes;
feComposite: Mithril.Attributes;
feConvolveMatrix: Mithril.Attributes;
feDiffuseLighting: Mithril.Attributes;
feDisplacementMap: Mithril.Attributes;
feDistantLight: Mithril.Attributes;
feDropShadow: Mithril.Attributes;
feFlood: Mithril.Attributes;
feFuncA: Mithril.Attributes;
feFuncB: Mithril.Attributes;
feFuncG: Mithril.Attributes;
feFuncR: Mithril.Attributes;
feGaussianBlur: Mithril.Attributes;
feImage: Mithril.Attributes;
feMerge: Mithril.Attributes;
feMergeNode: Mithril.Attributes;
feMorphology: Mithril.Attributes;
feOffset: Mithril.Attributes;
fePointLight: Mithril.Attributes;
feSpecularLighting: Mithril.Attributes;
feSpotLight: Mithril.Attributes;
feTile: Mithril.Attributes;
feTurbulence: Mithril.Attributes;
filter: Mithril.Attributes;
foreignObject: Mithril.Attributes;
g: Mithril.Attributes;
image: Mithril.Attributes;
line: Mithril.Attributes;
linearGradient: Mithril.Attributes;
marker: Mithril.Attributes;
mask: Mithril.Attributes;
metadata: Mithril.Attributes;
mpath: Mithril.Attributes;
path: Mithril.Attributes;
pattern: Mithril.Attributes;
polygon: Mithril.Attributes;
polyline: Mithril.Attributes;
radialGradient: Mithril.Attributes;
rect: Mithril.Attributes;
stop: Mithril.Attributes;
switch: Mithril.Attributes;
symbol: Mithril.Attributes;
text: Mithril.Attributes;
textPath: Mithril.Attributes;
tspan: Mithril.Attributes;
use: Mithril.Attributes;
view: Mithril.Attributes;
// Special Mithril types
'[': Mithril.Attributes;
}
}
}
declare const Mithril: Mithril.Static;
export = Mithril;

View File

@@ -1,43 +0,0 @@
// tslint:disable:rulename strict-export-declare-modifiers
/** Creates an empty stream. */
declare function Stream<T>(): Stream<T>; // tslint:disable-line no-unnecessary-generics
/** Creates a stream with an initial value. */
declare function Stream<T>(value: T): Stream<T>; // tslint:disable-line unified-signatures
declare interface Stream<T> {
/** Returns the value of the stream. */
(): T;
/** Sets the value of the stream. */
(value: T): this;
/** Creates a dependent stream whose value is set to the result of the callback function. */
map<U>(f: (current: T) => U | typeof Stream.SKIP): Stream<U>;
/** This method is functionally identical to stream. It exists to conform to Fantasy Land's Applicative specification. */
of(val: T): Stream<T>;
/** Apply. */
ap<U>(f: Stream<(value: T) => U>): Stream<U>;
/** A co-dependent stream that unregisters dependent streams when set to true. */
end: Stream<boolean>;
/** When a stream is passed as the argument to JSON.stringify(), the value of the stream is serialized. */
toJSON(): string;
/** Returns the value of the stream. */
valueOf(): T;
}
declare namespace Stream {
/** Creates a computed stream that reactively updates if any of its upstreams are updated. */
export function combine<T>(combiner: (...streams: any[]) => T, streams: Array<Stream<any>>): Stream<T>;
/** Combines the values of one or more streams into a single stream that is updated whenever one or more of the sources are updated */
export function lift<S extends any[], T>(fn: (...values: S) => T, ...streams: {[I in keyof S]: Stream<S[I]>}): Stream<T>;
/** Creates a stream whose value is the array of values from an array of streams. */
export function merge<S extends any[]>(streams: {[I in keyof S]: Stream<S[I]>}): Stream<{[I in keyof S]: S[I]}>;
/** Creates a new stream with the results of calling the function on every incoming stream with and accumulator and the incoming value. */
export function scan<T, U>(fn: (acc: U, value: T) => U, acc: U, stream: Stream<T>): Stream<U>;
/** Takes an array of pairs of streams and scan functions and merges all those streams using the given functions into a single stream. */
export function scanMerge<T, U>(pairs: Array<[Stream<T>, (acc: U, value: T) => U]>, acc: U): Stream<U>;
/** Takes an array of pairs of streams and scan functions and merges all those streams using the given functions into a single stream. */
export function scanMerge<U>(pairs: Array<[Stream<any>, (acc: U, value: any) => U]>, acc: U): Stream<U>;
/** A special value that can be returned to stream callbacks to skip execution of downstreams. */
export const SKIP: unique symbol;
}
export = Stream;

View File

@@ -1,4 +1,4 @@
/// <reference path="../../@types/translator-icu-rich.d.ts" />
/// <reference path="../../../src/common/translator-icu-rich.d.ts" />
import Modal, { IInternalModalAttrs } from '../../common/components/Modal';
export interface ILoadingModalAttrs extends IInternalModalAttrs {
}

View File

@@ -1,4 +1,4 @@
/// <reference path="../../@types/translator-icu-rich.d.ts" />
/// <reference path="../../../src/common/translator-icu-rich.d.ts" />
import Modal, { IInternalModalAttrs } from '../../common/components/Modal';
import ExtensionReadme from '../models/ExtensionReadme';
import type Mithril from 'mithril';

View File

@@ -1,4 +1,4 @@
/// <reference path="../../@types/translator-icu-rich.d.ts" />
/// <reference path="../../../src/common/translator-icu-rich.d.ts" />
import type Mithril from 'mithril';
import type User from '../../common/models/User';
import ItemList from '../../common/utils/ItemList';

View File

@@ -1,4 +1,4 @@
/// <reference path="../@types/translator-icu-rich.d.ts" />
/// <reference path="../../src/common/translator-icu-rich.d.ts" />
import { RichMessageFormatter } from '@askvortsov/rich-icu-message-formatter';
import { pluralTypeHandler, selectTypeHandler } from '@ultraq/icu-message-formatter';
declare type Translations = Record<string, string>;

View File

@@ -1,4 +1,4 @@
/// <reference path="../../@types/translator-icu-rich.d.ts" />
/// <reference path="../../../src/common/translator-icu-rich.d.ts" />
import Modal, { IInternalModalAttrs } from './Modal';
import ItemList from '../utils/ItemList';
import Stream from '../utils/Stream';

View File

@@ -1,3 +1,4 @@
/// <reference types="mithril" />
import Component, { ComponentAttrs } from '../Component';
export interface LoadingIndicatorAttrs extends ComponentAttrs {
/**

View File

@@ -1,3 +1,4 @@
/// <reference types="mithril" />
import type RequestError from '../utils/RequestError';
import Modal, { IInternalModalAttrs } from './Modal';
export interface IRequestErrorModalAttrs extends IInternalModalAttrs {

View File

@@ -1,4 +1,4 @@
/// <reference path="../../@types/translator-icu-rich.d.ts" />
/// <reference path="../../../src/common/translator-icu-rich.d.ts" />
import Modal, { IInternalModalAttrs } from '../../common/components/Modal';
import Stream from '../../common/utils/Stream';
import Mithril from 'mithril';

View File

@@ -1,4 +1,4 @@
/// <reference path="../../@types/translator-icu-rich.d.ts" />
/// <reference path="../../../src/common/translator-icu-rich.d.ts" />
import Modal, { IInternalModalAttrs } from '../../common/components/Modal';
import ItemList from '../../common/utils/ItemList';
import Stream from '../../common/utils/Stream';

View File

@@ -104,7 +104,6 @@ export default class Search<T extends SearchAttrs = SearchAttrs> extends Compone
selectableItems(): JQuery;
/**
* Get the position of the currently selected search result item.
* Returns zero if not found.
*/
getCurrentNumericIndex(): number;
/**

View File

@@ -1,4 +1,4 @@
/// <reference path="../../@types/translator-icu-rich.d.ts" />
/// <reference path="../../../src/common/translator-icu-rich.d.ts" />
import Modal, { IInternalModalAttrs } from '../../common/components/Modal';
import ItemList from '../../common/utils/ItemList';
import Stream from '../../common/utils/Stream';

2
js/dist/admin.js generated vendored

File diff suppressed because one or more lines are too long

2
js/dist/admin.js.LICENSE.txt generated vendored
View File

@@ -48,7 +48,7 @@
*/
/*!
* focus-trap 6.7.2
* focus-trap 6.7.1
* @license MIT, https://github.com/focus-trap/focus-trap/blob/master/LICENSE
*/

2
js/dist/admin.js.map generated vendored

File diff suppressed because one or more lines are too long

2
js/dist/forum.js generated vendored

File diff suppressed because one or more lines are too long

2
js/dist/forum.js.LICENSE.txt generated vendored
View File

@@ -48,7 +48,7 @@
*/
/*!
* focus-trap 6.7.2
* focus-trap 6.7.1
* @license MIT, https://github.com/focus-trap/focus-trap/blob/master/LICENSE
*/

2
js/dist/forum.js.map generated vendored

File diff suppressed because one or more lines are too long

View File

@@ -21,6 +21,7 @@
"devDependencies": {
"@flarum/prettier-config": "^1.0.0",
"@types/jquery": "^3.5.10",
"@types/mithril": "^2.0.8",
"@types/punycode": "^2.1.0",
"@types/textarea-caret": "^3.0.1",
"bundlewatch": "^0.3.2",
@@ -38,12 +39,11 @@
"scripts": {
"dev": "webpack --mode development --watch",
"build": "webpack --mode production",
"analyze": "cross-env ANALYZER=true yarn run build",
"analyze": "cross-env ANALYZER=true yarn build",
"format": "prettier --write src",
"format-check": "prettier --check src",
"clean-typings": "npx rimraf dist-typings && mkdir dist-typings",
"build-typings": "yarn run clean-typings && [ -e src/@types ] && cp -r src/@types dist-typings/@types && tsc && yarn run post-build-typings",
"post-build-typings": "find dist-typings -type f -name '*.d.ts' -print0 | xargs -0 sed -i 's,../src/@types,@types,g'",
"build-typings": "npm run clean-typings && tsc && [ -e src/@types ] && cp -r src/@types dist-typings/@types",
"check-typings": "tsc --noEmit --emitDeclarationOnly false",
"check-typings-coverage": "typescript-coverage-report"
},

View File

@@ -1,517 +0,0 @@
// Type definitions for Mithril 2.0
// Project: https://mithril.js.org/, https://github.com/mithriljs/mithril.js
// Definitions by: Mike Linkovich <https://github.com/spacejack>, András Parditka <https://github.com/andraaspar>, Isiah Meadows <https://github.com/isiahmeadows>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
// TypeScript Version: 3.2
/** Renders a vnode structure into a DOM element. */
declare function render(el: Element, vnodes: Mithril.Children): void;
/** Mounts a component to a DOM element, enabling it to autoredraw on user events. */
declare function mount(element: Element, component: Mithril.ComponentTypes<any, any>): void;
/** Unmounts a component from a DOM element. */
declare function mount(element: Element, component: null): void; // tslint:disable-line unified-signatures
/** Makes an XHR request and returns a promise. */
declare function request<T>(options: Mithril.RequestOptions<T> & { url: string }): Promise<T>;
/** Makes an XHR request and returns a promise. */
declare function request<T>(url: string, options?: Mithril.RequestOptions<T>): Promise<T>;
/** Makes a JSON-P request and returns a promise. */
declare function jsonp<T>(options: Mithril.JsonpOptions & { url: string }): Promise<T>; // tslint:disable-line:no-unnecessary-generics
/** Makes a JSON-P request and returns a promise. */
declare function jsonp<T>(url: string, options?: Mithril.JsonpOptions): Promise<T>; // tslint:disable-line:no-unnecessary-generics
declare namespace Mithril {
interface CommonAttributes<Attrs, State> {
/** The oninit hook is called before a vnode is touched by the virtual DOM engine. */
oninit?(this: State, vnode: Vnode<Attrs, State>): any;
/** The oncreate hook is called after a DOM element is created and attached to the document. */
oncreate?(this: State, vnode: VnodeDOM<Attrs, State>): any;
/** The onbeforeremove hook is called before a DOM element is detached from the document. If a Promise is returned, Mithril only detaches the DOM element after the promise completes. */
onbeforeremove?(this: State, vnode: VnodeDOM<Attrs, State>): Promise<any> | void;
/** The onremove hook is called before a DOM element is removed from the document. */
onremove?(this: State, vnode: VnodeDOM<Attrs, State>): any;
/** The onbeforeupdate hook is called before a vnode is diffed in a update. */
onbeforeupdate?(this: State, vnode: Vnode<Attrs, State>, old: VnodeDOM<Attrs, State>): boolean | void;
/** The onupdate hook is called after a DOM element is updated, while attached to the document. */
onupdate?(this: State, vnode: VnodeDOM<Attrs, State>): any;
/** A key to optionally associate with this element. */
key?: string | number | undefined;
}
interface Hyperscript {
/** Creates a virtual element (Vnode). */
(selector: string, ...children: Children[]): Vnode<any, any>;
/** Creates a virtual element (Vnode). */
(selector: string, attributes: Attributes, ...children: Children[]): Vnode<any, any>;
/** Creates a virtual element (Vnode). */
<Attrs, State>(component: ComponentTypes<Attrs, State>, ...args: Children[]): Vnode<Attrs, State>;
/** Creates a virtual element (Vnode). */
<Attrs, State>(
component: ComponentTypes<Attrs, State>,
attributes: Attrs & CommonAttributes<Attrs, State>,
...args: Children[]
): Vnode<Attrs, State>;
/** Creates a fragment virtual element (Vnode). */
fragment(attrs: CommonAttributes<any, any> & { [key: string]: any }, children: ChildArrayOrPrimitive): Vnode<any, any>;
/** Turns an HTML string into a virtual element (Vnode). Do not use trust on unsanitized user input. */
trust(html: string): Vnode<any, any>;
}
interface RouteResolver<Attrs = {}, State = {}> {
/** The onmatch hook is called when the router needs to find a component to render. */
onmatch?(
this: this,
args: Attrs,
requestedPath: string,
route: string,
): ComponentTypes<any, any> | Promise<any> | void;
/** The render method is called on every redraw for a matching route. */
render?(this: this, vnode: Vnode<Attrs, State>): Children;
}
/** This represents a key-value mapping linking routes to components. */
interface RouteDefs {
/** The key represents the route. The value represents the corresponding component. */
[url: string]: ComponentTypes<any, any> | RouteResolver<any, any>;
}
interface RouteOptions {
/** Routing parameters. If path has routing parameter slots, the properties of this object are interpolated into the path string. */
replace?: boolean | undefined;
/** The state object to pass to the underlying history.pushState / history.replaceState call. */
state?: any;
/** The title string to pass to the underlying history.pushState / history.replaceState call. */
title?: string | undefined;
}
interface RouteLinkAttrs extends Attributes {
href: string;
selector?: string | ComponentTypes<any> | undefined;
options?: RouteOptions | undefined;
}
interface Route {
/** Creates application routes and mounts Components and/or RouteResolvers to a DOM element. */
(element: Element, defaultRoute: string, routes: RouteDefs): void;
/** Returns the last fully resolved routing path, without the prefix. */
get(): string;
/** Redirects to a matching route or to the default route if no matching routes can be found. */
set(route: string, data?: any, options?: RouteOptions): void;
/** Defines a router prefix which is a fragment of the URL that dictates the underlying strategy used by the router. */
prefix: string;
/** This Component renders a link <a href> that will use the current routing strategy */
Link: Component<RouteLinkAttrs>;
/** Returns the named parameter value from the current route. */
param(name: string): string;
/** Gets all route parameters. */
param(): any;
}
interface RequestOptions<T> {
/** The HTTP method to use. */
method?: string | undefined;
/** The data to be interpolated into the URL and serialized into the querystring. */
params?: { [key: string]: any } | undefined;
/** The data to be serialized into the request body. */
body?: (XMLHttpRequest['send'] extends (x: infer R) => any ? R : never) | (object & { [id: string]: any }) | undefined;
/** Whether the request should be asynchronous. Defaults to true. */
async?: boolean | undefined;
/** A username for HTTP authorization. */
user?: string | undefined;
/** A password for HTTP authorization. */
password?: string | undefined;
/** Whether to send cookies to 3rd party domains. */
withCredentials?: boolean | undefined;
/** Exposes the underlying XMLHttpRequest object for low-level configuration. */
config?(xhr: XMLHttpRequest, options: this): XMLHttpRequest | void;
/** Headers to append to the request before sending it. */
headers?: { [key: string]: string } | undefined;
/** A constructor to be applied to each object in the response. */
type?: new (o: any) => any;
/** A serialization method to be applied to data. Defaults to JSON.stringify, or if options.data is an instance of FormData, defaults to the identity function. */
serialize?(data: any): any;
/** A deserialization method to be applied to the response. Defaults to a small wrapper around JSON.parse that returns null for empty responses. */
deserialize?(data: string): T;
/** A hook to specify how the XMLHttpRequest response should be read. Useful for reading response headers and cookies. Defaults to a function that returns xhr.responseText */
extract?(xhr: XMLHttpRequest, options: this): T;
/**
* Force the use of the HTTP body section for data in GET requests when set to true,
* or the use of querystring for other HTTP methods when set to false.
* Defaults to false for GET requests and true for other methods.
*/
useBody?: boolean | undefined;
/** If false, redraws mounted components upon completion of the request. If true, it does not. */
background?: boolean | undefined;
/** Milliseconds a request can take before automatically being terminated. */
timeout?: number | undefined;
/** The expected type of the response, as a legal value of XMLHttpRequest.responseType. */
responseType?: '' | 'arraybuffer' | 'blob' | 'document' | 'json' | 'text' | undefined;
}
interface JsonpOptions {
/** The data to be interpolated into the URL and serialized into the querystring. */
params?: { [id: string]: any } | undefined;
/** The data to be serialized into the request body. */
body?: any;
/** A constructor to be applied to each object in the response. */
type?: new (o: any) => any;
/** The name of the function that will be called as the callback. */
callbackName?: string | undefined;
/** The name of the querystring parameter name that specifies the callback name. */
callbackKey?: string | undefined;
/** If false, redraws mounted components upon completion of the request. If true, it does not. */
background?: boolean | undefined;
}
interface Redraw {
/** Manually triggers an asynchronous redraw of mounted components. */
(): void;
/** Manually triggers a synchronous redraw of mounted components. */
sync(): void;
}
type Params = object & ParamsRec;
interface ParamsRec {
// Ideally, it'd be this:
// `[key: string | number]: Params | !symbol & !object`
[key: string]: string | number | boolean | null | undefined | Params;
}
interface Static extends Hyperscript {
route: Route;
mount: typeof mount;
render: typeof render;
redraw: Redraw;
request: typeof request;
jsonp: typeof jsonp;
/** Returns an object with key/value pairs parsed from a string of the form: ?a=1&b=2 */
parseQueryString(queryString: string): Params;
/** Turns the key/value pairs of an object into a string of the form: a=1&b=2 */
buildQueryString(values: Params): string;
/** Parse path name */
parsePathname(url: string): { path: string; params: Params };
/** Build path name */
buildPathname(template: string, params?: Params): string;
}
// Vnode children types
type Child = Vnode<any, any> | string | number | boolean | null | undefined;
interface ChildArray extends Array<Children> {}
type Children = Child | ChildArray;
type ChildArrayOrPrimitive = ChildArray | string | number | boolean;
/** Virtual DOM nodes, or vnodes, are Javascript objects that represent an element (or parts of the DOM). */
interface Vnode<Attrs = {}, State = {}> {
/** The nodeName of a DOM element. It may also be the string [ if a vnode is a fragment, # if it's a text vnode, or < if it's a trusted HTML vnode. Additionally, it may be a component. */
tag: string | ComponentTypes<Attrs, State>;
/** A hashmap of DOM attributes, events, properties and lifecycle methods. */
attrs: Attrs;
/** An object that is persisted between redraws. In component vnodes, state is a shallow clone of the component object. */
state: State;
/** The value used to map a DOM element to its respective item in an array of data. */
key?: string | number | undefined;
/** In most vnode types, the children property is an array of vnodes. For text and trusted HTML vnodes, The children property is either a string, a number or a boolean. */
children?: ChildArrayOrPrimitive | undefined;
/**
* This is used instead of children if a vnode contains a text node as its only child.
* This is done for performance reasons.
* Component vnodes never use the text property even if they have a text node as their only child.
*/
text?: string | number | boolean | undefined;
}
// In some lifecycle methods, Vnode will have a dom property
// and possibly a domSize property.
interface VnodeDOM<Attrs = {}, State = {}> extends Vnode<Attrs, State> {
/** Points to the element that corresponds to the vnode. */
dom: Element;
/** This defines the number of DOM elements that the vnode represents (starting from the element referenced by the dom property). */
domSize?: number | undefined;
}
type _NoLifecycle<T> = Omit<T, keyof Component>;
interface CVnode<A = {}> extends Vnode<A, ClassComponent<A>> {}
interface CVnodeDOM<A = {}> extends VnodeDOM<A, ClassComponent<A>> {}
/**
* Components are a mechanism to encapsulate parts of a view to make code easier to organize and/or reuse.
* Any Javascript object that has a view method can be used as a Mithril component.
* Components can be consumed via the m() utility.
*/
interface Component<Attrs = {}, State = {}> {
/** The oninit hook is called before a vnode is touched by the virtual DOM engine. */
oninit?(this: _NoLifecycle<this & State>, vnode: Vnode<Attrs, _NoLifecycle<this & State>>): any;
/** The oncreate hook is called after a DOM element is created and attached to the document. */
oncreate?(this: _NoLifecycle<this & State>, vnode: VnodeDOM<Attrs, _NoLifecycle<this & State>>): any;
/** The onbeforeremove hook is called before a DOM element is detached from the document. If a Promise is returned, Mithril only detaches the DOM element after the promise completes. */
onbeforeremove?(this: _NoLifecycle<this & State>, vnode: VnodeDOM<Attrs, _NoLifecycle<this & State>>): Promise<any> | void;
/** The onremove hook is called before a DOM element is removed from the document. */
onremove?(this: _NoLifecycle<this & State>, vnode: VnodeDOM<Attrs, _NoLifecycle<this & State>>): any;
/** The onbeforeupdate hook is called before a vnode is diffed in a update. */
onbeforeupdate?(this: _NoLifecycle<this & State>, vnode: Vnode<Attrs, _NoLifecycle<this & State>>, old: VnodeDOM<Attrs, _NoLifecycle<this & State>>): boolean | void;
/** The onupdate hook is called after a DOM element is updated, while attached to the document. */
onupdate?(this: _NoLifecycle<this & State>, vnode: VnodeDOM<Attrs, _NoLifecycle<this & State>>): any;
/** Creates a view out of virtual elements. */
view(this: _NoLifecycle<this & State>, vnode: Vnode<Attrs, _NoLifecycle<this & State>>): Children | null | void;
}
/**
* Components are a mechanism to encapsulate parts of a view to make code easier to organize and/or reuse.
* Any class that implements a view method can be used as a Mithril component.
* Components can be consumed via the m() utility.
*/
interface ClassComponent<A = {}> {
/** The oninit hook is called before a vnode is touched by the virtual DOM engine. */
oninit?(vnode: Vnode<A, this>): any;
/** The oncreate hook is called after a DOM element is created and attached to the document. */
oncreate?(vnode: VnodeDOM<A, this>): any;
/** The onbeforeremove hook is called before a DOM element is detached from the document. If a Promise is returned, Mithril only detaches the DOM element after the promise completes. */
onbeforeremove?(vnode: VnodeDOM<A, this>): Promise<any> | void;
/** The onremove hook is called before a DOM element is removed from the document. */
onremove?(vnode: VnodeDOM<A, this>): any;
/** The onbeforeupdate hook is called before a vnode is diffed in a update. */
onbeforeupdate?(vnode: Vnode<A, this>, old: VnodeDOM<A, this>): boolean | void;
/** The onupdate hook is called after a DOM element is updated, while attached to the document. */
onupdate?(vnode: VnodeDOM<A, this>): any;
/** Creates a view out of virtual elements. */
view(vnode: Vnode<A, this>): Children | null | void;
}
/**
* Components are a mechanism to encapsulate parts of a view to make code easier to organize and/or reuse.
* Any function that returns an object with a view method can be used as a Mithril component.
* Components can be consumed via the m() utility.
*/
type FactoryComponent<A = {}> = (vnode: Vnode<A>) => Component<A>;
/**
* Components are a mechanism to encapsulate parts of a view to make code easier to organize and/or reuse.
* Any function that returns an object with a view method can be used as a Mithril component.
* Components can be consumed via the m() utility.
*/
type ClosureComponent<A = {}> = FactoryComponent<A>;
/**
* Components are a mechanism to encapsulate parts of a view to make code easier to organize and/or reuse.
* Any Javascript object that has a view method is a Mithril component. Components can be consumed via the m() utility.
*/
type Comp<Attrs = {}, State = {}> = _NoLifecycle<State> & Component<Attrs, _NoLifecycle<State>>;
/** Components are a mechanism to encapsulate parts of a view to make code easier to organize and/or reuse. Components can be consumed via the m() utility. */
type ComponentTypes<A = {}, S = {}> =
| Component<A, S>
| { new (vnode: CVnode<A>): ClassComponent<A> }
| FactoryComponent<A>;
/** This represents the attributes available for configuring virtual elements, beyond the applicable DOM attributes. */
interface Attributes extends CommonAttributes<any, any> {
/** The class name(s) for this virtual element, as a space-separated list. */
className?: string | undefined;
/** The class name(s) for this virtual element, as a space-separated list. */
class?: string | undefined;
/** Any other virtual element properties, including attributes and event handlers. */
[property: string]: any;
}
}
declare global {
namespace JSX {
// tslint:disable-next-line:no-empty-interface
interface Element extends Mithril.Vnode {}
// tslint:disable-next-line:no-empty-interface
interface IntrinsicAttributes extends Mithril.Attributes {}
// tslint:disable-next-line:no-empty-interface
interface IntrinsicClassAttributes extends Mithril.Attributes {}
interface IntrinsicElements {
// HTML
a: Mithril.Attributes;
abbr: Mithril.Attributes;
address: Mithril.Attributes;
area: Mithril.Attributes;
article: Mithril.Attributes;
aside: Mithril.Attributes;
audio: Mithril.Attributes;
b: Mithril.Attributes;
base: Mithril.Attributes;
bdi: Mithril.Attributes;
bdo: Mithril.Attributes;
big: Mithril.Attributes;
blockquote: Mithril.Attributes;
body: Mithril.Attributes;
br: Mithril.Attributes;
button: Mithril.Attributes;
canvas: Mithril.Attributes;
caption: Mithril.Attributes;
cite: Mithril.Attributes;
code: Mithril.Attributes;
col: Mithril.Attributes;
colgroup: Mithril.Attributes;
data: Mithril.Attributes;
datalist: Mithril.Attributes;
dd: Mithril.Attributes;
del: Mithril.Attributes;
details: Mithril.Attributes;
dfn: Mithril.Attributes;
dialog: Mithril.Attributes;
div: Mithril.Attributes;
dl: Mithril.Attributes;
dt: Mithril.Attributes;
em: Mithril.Attributes;
embed: Mithril.Attributes;
fieldset: Mithril.Attributes;
figcaption: Mithril.Attributes;
figure: Mithril.Attributes;
footer: Mithril.Attributes;
form: Mithril.Attributes;
h1: Mithril.Attributes;
h2: Mithril.Attributes;
h3: Mithril.Attributes;
h4: Mithril.Attributes;
h5: Mithril.Attributes;
h6: Mithril.Attributes;
head: Mithril.Attributes;
header: Mithril.Attributes;
hgroup: Mithril.Attributes;
hr: Mithril.Attributes;
html: Mithril.Attributes;
i: Mithril.Attributes;
iframe: Mithril.Attributes;
img: Mithril.Attributes;
input: Mithril.Attributes;
ins: Mithril.Attributes;
kbd: Mithril.Attributes;
keygen: Mithril.Attributes;
label: Mithril.Attributes;
legend: Mithril.Attributes;
li: Mithril.Attributes;
link: Mithril.Attributes;
main: Mithril.Attributes;
map: Mithril.Attributes;
mark: Mithril.Attributes;
menu: Mithril.Attributes;
menuitem: Mithril.Attributes;
meta: Mithril.Attributes;
meter: Mithril.Attributes;
nav: Mithril.Attributes;
noindex: Mithril.Attributes;
noscript: Mithril.Attributes;
object: Mithril.Attributes;
ol: Mithril.Attributes;
optgroup: Mithril.Attributes;
option: Mithril.Attributes;
output: Mithril.Attributes;
p: Mithril.Attributes;
param: Mithril.Attributes;
picture: Mithril.Attributes;
pre: Mithril.Attributes;
progress: Mithril.Attributes;
q: Mithril.Attributes;
rp: Mithril.Attributes;
rt: Mithril.Attributes;
ruby: Mithril.Attributes;
s: Mithril.Attributes;
samp: Mithril.Attributes;
script: Mithril.Attributes;
section: Mithril.Attributes;
select: Mithril.Attributes;
small: Mithril.Attributes;
source: Mithril.Attributes;
span: Mithril.Attributes;
strong: Mithril.Attributes;
style: Mithril.Attributes;
sub: Mithril.Attributes;
summary: Mithril.Attributes;
sup: Mithril.Attributes;
table: Mithril.Attributes;
template: Mithril.Attributes;
tbody: Mithril.Attributes;
td: Mithril.Attributes;
textarea: Mithril.Attributes;
tfoot: Mithril.Attributes;
th: Mithril.Attributes;
thead: Mithril.Attributes;
time: Mithril.Attributes;
title: Mithril.Attributes;
tr: Mithril.Attributes;
track: Mithril.Attributes;
u: Mithril.Attributes;
ul: Mithril.Attributes;
var: Mithril.Attributes;
video: Mithril.Attributes;
wbr: Mithril.Attributes;
webview: Mithril.Attributes;
// SVG
svg: Mithril.Attributes;
animate: Mithril.Attributes;
animateMotion: Mithril.Attributes;
animateTransform: Mithril.Attributes;
circle: Mithril.Attributes;
clipPath: Mithril.Attributes;
defs: Mithril.Attributes;
desc: Mithril.Attributes;
ellipse: Mithril.Attributes;
feBlend: Mithril.Attributes;
feColorMatrix: Mithril.Attributes;
feComponentTransfer: Mithril.Attributes;
feComposite: Mithril.Attributes;
feConvolveMatrix: Mithril.Attributes;
feDiffuseLighting: Mithril.Attributes;
feDisplacementMap: Mithril.Attributes;
feDistantLight: Mithril.Attributes;
feDropShadow: Mithril.Attributes;
feFlood: Mithril.Attributes;
feFuncA: Mithril.Attributes;
feFuncB: Mithril.Attributes;
feFuncG: Mithril.Attributes;
feFuncR: Mithril.Attributes;
feGaussianBlur: Mithril.Attributes;
feImage: Mithril.Attributes;
feMerge: Mithril.Attributes;
feMergeNode: Mithril.Attributes;
feMorphology: Mithril.Attributes;
feOffset: Mithril.Attributes;
fePointLight: Mithril.Attributes;
feSpecularLighting: Mithril.Attributes;
feSpotLight: Mithril.Attributes;
feTile: Mithril.Attributes;
feTurbulence: Mithril.Attributes;
filter: Mithril.Attributes;
foreignObject: Mithril.Attributes;
g: Mithril.Attributes;
image: Mithril.Attributes;
line: Mithril.Attributes;
linearGradient: Mithril.Attributes;
marker: Mithril.Attributes;
mask: Mithril.Attributes;
metadata: Mithril.Attributes;
mpath: Mithril.Attributes;
path: Mithril.Attributes;
pattern: Mithril.Attributes;
polygon: Mithril.Attributes;
polyline: Mithril.Attributes;
radialGradient: Mithril.Attributes;
rect: Mithril.Attributes;
stop: Mithril.Attributes;
switch: Mithril.Attributes;
symbol: Mithril.Attributes;
text: Mithril.Attributes;
textPath: Mithril.Attributes;
tspan: Mithril.Attributes;
use: Mithril.Attributes;
view: Mithril.Attributes;
// Special Mithril types
'[': Mithril.Attributes;
}
}
}
declare const Mithril: Mithril.Static;
export = Mithril;

View File

@@ -1,43 +0,0 @@
// tslint:disable:rulename strict-export-declare-modifiers
/** Creates an empty stream. */
declare function Stream<T>(): Stream<T>; // tslint:disable-line no-unnecessary-generics
/** Creates a stream with an initial value. */
declare function Stream<T>(value: T): Stream<T>; // tslint:disable-line unified-signatures
declare interface Stream<T> {
/** Returns the value of the stream. */
(): T;
/** Sets the value of the stream. */
(value: T): this;
/** Creates a dependent stream whose value is set to the result of the callback function. */
map<U>(f: (current: T) => U | typeof Stream.SKIP): Stream<U>;
/** This method is functionally identical to stream. It exists to conform to Fantasy Land's Applicative specification. */
of(val: T): Stream<T>;
/** Apply. */
ap<U>(f: Stream<(value: T) => U>): Stream<U>;
/** A co-dependent stream that unregisters dependent streams when set to true. */
end: Stream<boolean>;
/** When a stream is passed as the argument to JSON.stringify(), the value of the stream is serialized. */
toJSON(): string;
/** Returns the value of the stream. */
valueOf(): T;
}
declare namespace Stream {
/** Creates a computed stream that reactively updates if any of its upstreams are updated. */
export function combine<T>(combiner: (...streams: any[]) => T, streams: Array<Stream<any>>): Stream<T>;
/** Combines the values of one or more streams into a single stream that is updated whenever one or more of the sources are updated */
export function lift<S extends any[], T>(fn: (...values: S) => T, ...streams: {[I in keyof S]: Stream<S[I]>}): Stream<T>;
/** Creates a stream whose value is the array of values from an array of streams. */
export function merge<S extends any[]>(streams: {[I in keyof S]: Stream<S[I]>}): Stream<{[I in keyof S]: S[I]}>;
/** Creates a new stream with the results of calling the function on every incoming stream with and accumulator and the incoming value. */
export function scan<T, U>(fn: (acc: U, value: T) => U, acc: U, stream: Stream<T>): Stream<U>;
/** Takes an array of pairs of streams and scan functions and merges all those streams using the given functions into a single stream. */
export function scanMerge<T, U>(pairs: Array<[Stream<T>, (acc: U, value: T) => U]>, acc: U): Stream<U>;
/** Takes an array of pairs of streams and scan functions and merges all those streams using the given functions into a single stream. */
export function scanMerge<U>(pairs: Array<[Stream<any>, (acc: U, value: any) => U]>, acc: U): Stream<U>;
/** A special value that can be returned to stream callbacks to skip execution of downstreams. */
export const SKIP: unique symbol;
}
export = Stream;

View File

@@ -1,26 +0,0 @@
declare module '@askvortsov/rich-icu-message-formatter' {
type IValues = Record<string, any>;
type ITypeHandler = (
value: string,
matches: string,
locale: string,
values: IValues,
format: (message: string, values: IValues) => string
) => string;
type IRichHandler = (tag: any, values: IValues, contents: string) => any;
type ValueOrArray<T> = T | ValueOrArray<T>[];
type NestedStringArray = ValueOrArray<string>;
export class RichMessageFormatter {
locale: string | null;
constructor(locale: string | null, typeHandlers: Record<string, ITypeHandler>, richHandler: IRichHandler);
format(message: string, values: IValues): string;
process(message: string, values: IValues): NestedStringArray;
rich(message: string, values: IValues): NestedStringArray;
}
export function mithrilRichHandler(tag: any, values: IValues, contents: string): any;
}

View File

@@ -1,17 +0,0 @@
declare module '@ultraq/icu-message-formatter' {
export function pluralTypeHandler(
value: string,
matches: string,
locale: string,
values: Record<string, any>,
format: (text: string, values: Record<string, any>) => string
): string;
export function selectTypeHandler(
value: string,
matches: string,
locale: string,
values: Record<string, any>,
format: (text: string, values: Record<string, any>) => string
): string;
}

View File

@@ -61,7 +61,7 @@ export default class EditUserModal<CustomAttrs extends IEditUserModalAttrs = IEd
fields() {
const items = new ItemList();
if (this.attrs.user.canEditCredentials()) {
if (app.session.user?.canEditCredentials()) {
items.add(
'username',
<div className="Form-group">
@@ -145,7 +145,7 @@ export default class EditUserModal<CustomAttrs extends IEditUserModalAttrs = IEd
}
}
if (this.attrs.user.canEditGroups()) {
if (app.session.user?.canEditGroups()) {
items.add(
'groups',
<div className="Form-group EditUserModal-groups">

View File

@@ -49,6 +49,7 @@ export default class Drawer {
* @internal
*/
resizeHandler = ((e) => {
console.log(this, e);
if (!e.matches && this.isOpen()) {
// Drawer is open but we've made window bigger, so hide it.
this.hide();

View File

@@ -101,7 +101,7 @@ export default class DiscussionComposer extends ComposerBody {
.save(data)
.then((discussion) => {
this.composer.hide();
app.discussions.refresh();
app.discussions.refresh({ deferClear: true });
m.route.set(app.route.discussion(discussion));
}, this.loaded.bind(this));
}

View File

@@ -53,9 +53,7 @@ export default class DiscussionPage<CustomAttrs extends IDiscussionPageAttrs = I
// page, then we don't want Mithril to redraw the whole page if it did,
// then the pane would redraw which would be slow and would cause problems with
// event handlers.
// We will also enable the pane if the discussion list is empty but loading,
// because the DiscussionComposer refreshes the list and redirects to the new discussion at the same time.
if (app.discussions.hasItems() || app.discussions.isLoading()) {
if (app.discussions.hasItems()) {
app.pane?.enable();
app.pane?.hide();
}
@@ -212,7 +210,7 @@ export default class DiscussionPage<CustomAttrs extends IDiscussionPageAttrs = I
record.relationships.discussion.data.id === discussionId
)
.map((record) => app.store.getById<Post>('posts', record.id))
.sort((a?: Post, b?: Post) => (a?.number() ?? 0) - (b?.number() ?? 0))
.sort((a?: Post, b?: Post) => (a?.createdAt()?.getTime() ?? 0) - (b?.createdAt()?.getTime() ?? 0))
.slice(0, 20);
}

View File

@@ -161,7 +161,6 @@ export default class Search<T extends SearchAttrs = SearchAttrs> extends Compone
className="Search-clear Button Button--icon Button--link"
onclick={this.clear.bind(this)}
aria-label={app.translator.trans('core.forum.header.search_clear_button_accessible_label')}
type="button"
>
{icon('fas fa-times-circle')}
</button>
@@ -325,10 +324,9 @@ export default class Search<T extends SearchAttrs = SearchAttrs> extends Compone
/**
* Get the position of the currently selected search result item.
* Returns zero if not found.
*/
getCurrentNumericIndex(): number {
return Math.max(0, this.selectableItems().index(this.getItem(this.index)));
return this.selectableItems().index(this.getItem(this.index));
}
/**

View File

@@ -289,7 +289,7 @@ class PostStreamState {
if (loadIds.length) {
return app.store.find('posts', loadIds).then((newPosts) => {
return loaded.concat(newPosts).sort((a, b) => a.number() - b.number());
return loaded.concat(newPosts).sort((a, b) => a.createdAt() - b.createdAt());
});
}

File diff suppressed because it is too large Load Diff

View File

@@ -41,23 +41,18 @@
line-height: 1.5em;
color: var(--secondary-color);
&,
input,
a {
&, input, a {
font-size: 14px;
font-weight: normal;
}
input,
a {
input, a {
color: inherit;
}
input {
font-size: 16px;
width: 500px;
&,
&[disabled],
&:focus {
&, &[disabled], &:focus {
background: none;
border: 0;
padding: 0 20px 0 0;
@@ -235,8 +230,7 @@
height: 300px;
transition: background 0.2s, box-shadow 0.2s;
&.active,
&.fullScreen {
&.active, &.fullScreen {
background: var(--body-bg);
}
&.active:not(.fullScreen) {
@@ -264,16 +258,9 @@
}
}
.ComposerBody-header {
margin-right: 120px;
.fullScreen & {
margin-bottom: 20px;
}
.minimized & {
overflow: hidden;
margin-right: 32px;
}
}
.Composer-content {
padding: 20px 20px 0;
@@ -292,8 +279,7 @@
margin-bottom: -17px;
position: relative;
.minimized &,
.fullScreen & {
.minimized &, .fullScreen & {
display: none;
}
}
@@ -301,16 +287,14 @@
float: left;
.Avatar--size(64px);
.minimized &,
.fullScreen & {
.minimized &, .fullScreen & {
display: none;
}
}
.ComposerBody-content {
margin-left: 85px;
.minimized &,
.fullScreen & {
.minimized &, .fullScreen & {
margin-left: 0;
}
}

12
node_modules/.yarn-integrity generated vendored
View File

@@ -1,12 +0,0 @@
{
"systemParams": "linux-x64-93",
"modulesFolders": [
"node_modules"
],
"flags": [],
"linkedModules": [],
"topLevelPatterns": [],
"lockfileEntries": {},
"files": [],
"artifacts": {}
}

View File

@@ -41,7 +41,7 @@ class ListPostsController extends AbstractListController
/**
* {@inheritdoc}
*/
public $sortFields = ['number', 'createdAt'];
public $sortFields = ['createdAt'];
/**
* @var PostFilterer

View File

@@ -132,7 +132,7 @@ class ShowDiscussionController extends AbstractShowController
*/
private function loadPostIds(Discussion $discussion, User $actor)
{
return $discussion->posts()->whereVisibleTo($actor)->orderBy('number')->pluck('id')->all();
return $discussion->posts()->whereVisibleTo($actor)->orderBy('created_at')->pluck('id')->all();
}
/**
@@ -186,7 +186,7 @@ class ShowDiscussionController extends AbstractShowController
{
$query = $discussion->posts()->whereVisibleTo($actor);
$query->orderBy('number')->skip($offset)->take($limit)->with($include);
$query->orderBy('created_at')->skip($offset)->take($limit)->with($include);
$posts = $query->get();

View File

@@ -21,7 +21,7 @@ class Application
*
* @var string
*/
const VERSION = '1.3.0-dev';
const VERSION = '1.2.1';
/**
* The IoC container for the Flarum application.

View File

@@ -19,7 +19,6 @@
<testsuites>
<testsuite name="Flarum Integration Tests">
<directory suffix="Test.php">./integration</directory>
<exclude>./integration/tmp</exclude>
</testsuite>
</testsuites>
</phpunit>