Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ module.exports = {
SyntheticMouseEvent: false,
TimeoutID: false,
"$Diff": false,
"$ReadOnly": false,
"$ReadOnlyArray": false,
"React$Element": false,
},
Expand Down
333 changes: 333 additions & 0 deletions frontend/flow-typed/fluentDef.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,333 @@
/* @flow */

declare module '@fluent/bundle' {
declare export class FluentResource {
constructor(source: string): this;
}
declare export type TextTransform = (text: string) => string;
declare export class FluentBundle {
constructor(
locales: string | Array<string>,
opts?: {
useIsolating?: boolean,
transform?: TextTransform,
},
): this;
addResource(
res: FluentResource,
opts?: {
allowOverrides?: boolean,
},
): Array<Error>;
}
}

declare module '@fluent/langneg' {
declare interface NegotiateLanguagesOptions {
strategy?: 'filtering' | 'matching' | 'lookup';
defaultLocale?: string;
}
declare export function negotiateLanguages(
requestedLocales: $ReadOnlyArray<string>,
availableLocales: $ReadOnlyArray<string>,
opts?: NegotiateLanguagesOptions,
): Array<string>;
}

declare module '@fluent/react' {
declare export class ReactLocalization {
constructor(Array<any>): ReactLocalization;
}

declare export function LocalizationProvider(
props: any,
): React$Element<any>;

declare export interface LocalizedProps {
id: string;
attrs?: { [string]: boolean };
children?: React$Node;
vars?: { [string]: any };
elems?: { [string]: ?React$Element<any> };
}
declare export function Localized(
props: LocalizedProps,
): React$Element<any>;
}

declare module '@fluent/syntax' {
declare export class BaseNode {
[name: string]: mixed;
equals(other: BaseNode, ignoredFields?: Array<string>): boolean;
clone(): this;
}
declare export class SyntaxNode extends BaseNode {
span?: Span;
addSpan(start: number, end: number): void;
}
declare export class Resource extends SyntaxNode {
type: 'Resource';
body: Array<Entry>;
constructor(body?: Array<Entry>): this;
}
declare export type Entry = Message | Term | Comments | Junk;
declare export class Message extends SyntaxNode {
type: 'Message';
id: Identifier;
value: Pattern | null;
attributes: Array<Attribute>;
comment: Comment | null;
constructor(
id: Identifier,
value?: Pattern | null,
attributes?: Array<Attribute>,
comment?: Comment | null,
): this;
}
declare export class Term extends SyntaxNode {
type: 'Term';
id: Identifier;
value: Pattern;
attributes: Array<Attribute>;
comment: Comment | null;
constructor(
id: Identifier,
value: Pattern,
attributes?: Array<Attribute>,
comment?: Comment | null,
): this;
}
declare export class Pattern extends SyntaxNode {
type: 'Pattern';
elements: Array<PatternElement>;
constructor(elements: Array<PatternElement>): this;
}
declare export type PatternElement = TextElement | Placeable;
declare export class TextElement extends SyntaxNode {
type: 'TextElement';
value: string;
constructor(value: string): this;
}
declare export class Placeable extends SyntaxNode {
type: 'Placeable';
expression: Expression;
constructor(expression: Expression): this;
}
/**
* A subset of expressions which can be used as outside of Placeables.
*/
declare export type InlineExpression =
| StringLiteral
| NumberLiteral
| FunctionReference
| MessageReference
| TermReference
| VariableReference
| Placeable;
declare export type Expression = InlineExpression | SelectExpression;
declare export class BaseLiteral extends SyntaxNode {
value: string;
constructor(value: string): this;
parse(): {
value: any,
};
}
declare export class StringLiteral extends BaseLiteral {
type: 'StringLiteral';
parse(): {
value: string,
};
}
declare export class NumberLiteral extends BaseLiteral {
type: 'NumberLiteral';
parse(): {
value: number,
precision: number,
};
}
declare export type Literal = StringLiteral | NumberLiteral;
declare export class MessageReference extends SyntaxNode {
type: 'MessageReference';
id: Identifier;
attribute: Identifier | null;
constructor(id: Identifier, attribute?: Identifier | null): this;
}
declare export class TermReference extends SyntaxNode {
type: 'TermReference';
id: Identifier;
attribute: Identifier | null;
arguments: CallArguments | null;
constructor(
id: Identifier,
attribute?: Identifier | null,
args?: CallArguments | null,
): this;
}
declare export class VariableReference extends SyntaxNode {
type: 'VariableReference';
id: Identifier;
constructor(id: Identifier): this;
}
declare export class FunctionReference extends SyntaxNode {
type: 'FunctionReference';
id: Identifier;
arguments: CallArguments;
constructor(id: Identifier, args: CallArguments): this;
}
declare export class SelectExpression extends SyntaxNode {
type: 'SelectExpression';
selector: InlineExpression;
variants: Array<Variant>;
constructor(selector: InlineExpression, variants: Array<Variant>): this;
}
declare export class CallArguments extends SyntaxNode {
type: 'CallArguments';
positional: Array<InlineExpression>;
named: Array<NamedArgument>;
constructor(
positional?: Array<InlineExpression>,
named?: Array<NamedArgument>,
): this;
}
declare export class Attribute extends SyntaxNode {
type: 'Attribute';
id: Identifier;
value: Pattern;
constructor(id: Identifier, value: Pattern): this;
}
declare export class Variant extends SyntaxNode {
type: 'Variant';
key: Identifier | NumberLiteral;
value: Pattern;
default: boolean;
constructor(
key: Identifier | NumberLiteral,
value: Pattern,
def: boolean,
): this;
}
declare export class NamedArgument extends SyntaxNode {
type: 'NamedArgument';
name: Identifier;
value: Literal;
constructor(name: Identifier, value: Literal): this;
}
declare export class Identifier extends SyntaxNode {
type: 'Identifier';
name: string;
constructor(name: string): this;
}
declare export class BaseComment extends SyntaxNode {
content: string;
constructor(content: string): this;
}
declare export class Comment extends BaseComment {
type: 'Comment';
}
declare export class GroupComment extends BaseComment {
type: 'GroupComment';
}
declare export class ResourceComment extends BaseComment {
type: 'ResourceComment';
}
declare export type Comments = Comment | GroupComment | ResourceComment;
declare export class Junk extends SyntaxNode {
type: 'Junk';
annotations: Array<Annotation>;
content: string;
constructor(content: string): this;
addAnnotation(annotation: Annotation): void;
}
declare export class Span extends BaseNode {
type: 'Span';
start: number;
end: number;
constructor(start: number, end: number): this;
}
declare export class Annotation extends SyntaxNode {
type: 'Annotation';
code: string;
arguments: Array<mixed>;
message: string;
constructor(code: string, args: mixed[] | void, message: string): this;
}

/**
* Parsers
*/
declare export interface FluentParserOptions {
withSpans?: boolean;
}
declare export class FluentParser {
withSpans: boolean;
constructor(opts?: FluentParserOptions): this;
parse(source: string): Resource;
parseEntry(source: string): Entry;
}

/**
* Serializers
*/
declare export interface FluentSerializerOptions {
withJunk?: boolean;
}
declare export class FluentSerializer {
withJunk: boolean;
constructor(opts?: FluentSerializerOptions): this;
serialize(resource: Resource): string;
serializeEntry(entry: Entry, state?: number): string;
}
declare export function serializeExpression(
expr: Expression | Placeable,
): string;
declare export function serializeVariantKey(
key: Identifier | NumberLiteral,
): string;

/**
* A read-and-write visitor.
*
* Subclasses can be used to modify an AST in-place.
*
* To handle specific node types add methods like `visitPattern`.
* Then, to descend into children call `genericVisit`.
*
* Visiting methods must implement the following interface:
*
* interface TransformingMethod {
* (this: Transformer, node: BaseNode): BaseNode | void;
* }
*
* The returned node will replace the original one in the AST. Return
* `undefined` to remove the node instead.
*/
declare export class Transformer {
[prop: string]: mixed;
visit(node: BaseNode): BaseNode | void;
genericVisit(node: BaseNode): BaseNode;
+visitResource?: (node: Resource) => BaseNode | void;
+visitMessage?: (node: Message) => BaseNode | void;
+visitTerm?: (node: Term) => BaseNode | void;
+visitPattern?: (node: Pattern) => BaseNode | void;
+visitTextElement?: (node: TextElement) => BaseNode | void;
+visitPlaceable?: (node: Placeable) => BaseNode | void;
+visitStringLiteral?: (node: StringLiteral) => BaseNode | void;
+visitNumberLiteral?: (node: NumberLiteral) => BaseNode | void;
+visitMessageReference?: (node: MessageReference) => BaseNode | void;
+visitTermReference?: (node: TermReference) => BaseNode | void;
+visitVariableReference?: (node: VariableReference) => BaseNode | void;
+visitFunctionReference?: (node: FunctionReference) => BaseNode | void;
+visitSelectExpression?: (node: SelectExpression) => BaseNode | void;
+visitCallArguments?: (node: CallArguments) => BaseNode | void;
+visitAttribute?: (node: Attribute) => BaseNode | void;
+visitVariant?: (node: Variant) => BaseNode | void;
+visitNamedArgument?: (node: NamedArgument) => BaseNode | void;
+visitIdentifier?: (node: Identifier) => BaseNode | void;
+visitComment?: (node: Comment) => BaseNode | void;
+visitGroupComment?: (node: GroupComment) => BaseNode | void;
+visitResourceComment?: (node: ResourceComment) => BaseNode | void;
+visitJunk?: (node: Junk) => BaseNode | void;
+visitSpan?: (node: Span) => BaseNode | void;
+visitAnnotation?: (node: Annotation) => BaseNode | void;
}
}
21 changes: 0 additions & 21 deletions frontend/flow-typed/myLibDef.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,3 @@
declare module '@fluent/react' {
declare export class ReactLocalization {
constructor(Array<any>): ReactLocalization;
}

declare export function LocalizationProvider(
props: any,
): React$Element<any>;

declare export interface LocalizedProps {
id: string;
attrs?: { [string]: boolean };
children?: React$Node;
vars?: { [string]: any };
elems?: { [string]: ?React$Element<any> };
}
declare export function Localized(
props: LocalizedProps,
): React$Element<any>;
}

declare module 'react-content-marker' {
declare export type TagFunction = (input: string) => React$Element<any>;
declare export interface Parser {
Expand Down
8 changes: 4 additions & 4 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@fluent/bundle": "0.16.0",
"@fluent/langneg": "0.5.0",
"@fluent/react": "0.13.0",
"@fluent/syntax": "0.16.1",
"@fluent/bundle": "0.16.1",
"@fluent/langneg": "0.5.1",
"@fluent/react": "0.13.1",
"@fluent/syntax": "0.17.0",
"abortcontroller-polyfill": "1.3.0",
"connected-react-router": "6.8.0",
"date-and-time": "0.14.2",
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/core/editor/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import * as unsavedchanges from 'modules/unsavedchanges';

import type { Entity, SourceType } from 'core/api';
import type { Locale } from 'core/locale';
import type { FluentMessage } from 'core/utils/fluent/types';
import type { Entry } from '@fluent/syntax';

export const END_UPDATE_TRANSLATION: 'editor/END_UPDATE_TRANSLATION' =
'editor/END_UPDATE_TRANSLATION';
Expand All @@ -40,7 +40,7 @@ export const UPDATE_SELECTION: 'editor/UPDATE_SELECTION' =
export const UPDATE_MACHINERY_SOURCES: 'editor/UPDATE_MACHINERY_SOURCES' =
'editor/UPDATE_MACHINERY_SOURCES';

export type Translation = string | FluentMessage;
export type Translation = string | Entry;

/**
* Update the current translation of the selected entity.
Expand Down
Loading