Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: projectfluent/fluent.js
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: @fluent/bundle@0.19.0
Choose a base ref
...
head repository: projectfluent/fluent.js
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: @fluent/bundle@0.19.1
Choose a head ref
  • 7 commits
  • 10 files changed
  • 4 contributors

Commits on Mar 25, 2025

  1. docs: Fix redirects

    eemeli committed Mar 25, 2025
    Copy the full SHA
    dcc8dc3 View commit details
  2. docs: Add navigation links

    eemeli committed Mar 25, 2025
    Copy the full SHA
    30236ce View commit details
  3. test(bundle): Make Temporal tests locale independent (#639)

    rkh authored Mar 25, 2025
    Copy the full SHA
    92c2cbf View commit details

Commits on Mar 27, 2025

  1. fix(dom): Add aria-description as a localizable string (#640)

    calixteman authored Mar 27, 2025
    Copy the full SHA
    d986bbb View commit details
  2. chore: Publish

    - @fluent/dom@0.10.1
    eemeli committed Mar 27, 2025
    Copy the full SHA
    2c2463b View commit details

Commits on Apr 2, 2025

  1. fix(bundle): Fix FluentDateTime and FluentNumber primitive conversions (

    #641)
    
    * Do not require scope argument in FluentNumber & FluentDateTime toString() calls
    * Add FluentDateTime.p.[Symbol.toPrimitive]()
    * Add test suite using code from firefox-devtools/profiler@9c8fb55
    
    ---------
    
    Co-authored-by: Eemeli Aro <eemeli@gmail.com>
    julienw and eemeli authored Apr 2, 2025
    Copy the full SHA
    0fc166e View commit details
  2. chore: Publish

    - @fluent/bundle@0.19.1
    eemeli committed Apr 2, 2025
    Copy the full SHA
    8858219 View commit details
4 changes: 4 additions & 0 deletions fluent-bundle/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## [0.19.1](https://github.com/projectfluent/fluent.js/compare/@fluent/bundle@0.19.0...@fluent/bundle@0.19.1) (2025-04-02)

- Fix FluentDateTime and FluentNumber primitive conversions ([#641](https://github.com/projectfluent/fluent.js/issues/641))

## [0.19.0](https://github.com/projectfluent/fluent.js/compare/@fluent/bundle@0.18.0...@fluent/bundle@0.19.0) (2025-03-25)

### ⚠ Breaking Changes
2 changes: 1 addition & 1 deletion fluent-bundle/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@fluent/bundle",
"description": "Localization library for expressive translations.",
"version": "0.19.0",
"version": "0.19.1",
"homepage": "https://projectfluent.org",
"author": "Mozilla <l10n-drivers@mozilla.org>",
"license": "Apache-2.0",
44 changes: 26 additions & 18 deletions fluent-bundle/src/types.ts
Original file line number Diff line number Diff line change
@@ -108,14 +108,16 @@ export class FluentNumber extends FluentType<number> {
/**
* Format this `FluentNumber` to a string.
*/
toString(scope: Scope): string {
try {
const nf = scope.memoizeIntlObject(Intl.NumberFormat, this.opts);
return nf.format(this.value);
} catch (err) {
scope.reportError(err);
return this.value.toString(10);
toString(scope?: Scope): string {
if (scope) {
try {
const nf = scope.memoizeIntlObject(Intl.NumberFormat, this.opts);
return nf.format(this.value);
} catch (err) {
scope.reportError(err);
}
}
return this.value.toString(10);
}
}

@@ -190,6 +192,10 @@ export class FluentDateTime extends FluentType<number | Date | TemporalObject> {
this.opts = opts;
}

[Symbol.toPrimitive](hint: "number" | "string" | "default"): string | number {
return hint === "string" ? this.toString() : this.toNumber();
}

/**
* Convert this `FluentDateTime` to a number.
* Note that this isn't always possible due to the nature of Temporal objects.
@@ -214,18 +220,20 @@ export class FluentDateTime extends FluentType<number | Date | TemporalObject> {
/**
* Format this `FluentDateTime` to a string.
*/
toString(scope: Scope): string {
try {
const dtf = scope.memoizeIntlObject(Intl.DateTimeFormat, this.opts);
return dtf.format(
this.value as Parameters<Intl.DateTimeFormat["format"]>[0]
);
} catch (err) {
scope.reportError(err);
if (typeof this.value === "number" || this.value instanceof Date) {
return new Date(this.value).toISOString();
toString(scope?: Scope): string {
if (scope) {
try {
const dtf = scope.memoizeIntlObject(Intl.DateTimeFormat, this.opts);
return dtf.format(
this.value as Parameters<Intl.DateTimeFormat["format"]>[0]
);
} catch (err) {
scope.reportError(err);
}
return this.value.toString();
}
if (typeof this.value === "number" || this.value instanceof Date) {
return new Date(this.value).toISOString();
}
return this.value.toString();
}
}
91 changes: 81 additions & 10 deletions fluent-bundle/test/functions_runtime_test.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
import assert from "assert";
import ftl from "@fluent/dedent";
import assert from "assert";

import { FluentBundle } from "../esm/bundle.js";
import { FluentResource } from "../esm/resource.js";
import { FluentNumber } from "../esm/types.js";
import {
FluentBundle,
FluentDateTime,
FluentNumber,
FluentResource,
} from "../esm/index.js";

suite("Runtime-specific functions", function () {
let bundle, errs;

setup(function () {
errs = [];
});

suite("passing into the constructor", function () {
let bundle, errs;

suiteSetup(function () {
bundle = new FluentBundle("en-US", {
useIsolating: false,
@@ -33,6 +32,7 @@ suite("Runtime-specific functions", function () {
}
`)
);
errs = [];
});

test("works for strings", function () {
@@ -56,4 +56,75 @@ suite("Runtime-specific functions", function () {
assert.strictEqual(errs.length, 0);
});
});

suite("firefox-devtools/profiler@9c8fb55", () => {
/** @type {FluentBundle} */
let bundle;

suiteSetup(() => {
const ONE_DAY_IN_MS = 24 * 60 * 60 * 1000;
const ONE_YEAR_IN_MS = 365 * ONE_DAY_IN_MS;

const DATE_FORMATS = {
thisDay: { hour: "numeric", minute: "numeric" },
thisYear: {
month: "short",
day: "numeric",
hour: "numeric",
minute: "numeric",
},
ancient: {
year: "numeric",
month: "short",
day: "numeric",
},
};

const SHORTDATE = args => {
const date = args[0];
const nowTimestamp = Number(new Date("2025-02-15T12:00"));

const timeDifference = nowTimestamp - +date;
if (timeDifference < 0 || timeDifference > ONE_YEAR_IN_MS) {
return new FluentDateTime(date, DATE_FORMATS.ancient);
}
if (timeDifference > ONE_DAY_IN_MS) {
return new FluentDateTime(date, DATE_FORMATS.thisYear);
}
return new FluentDateTime(date, DATE_FORMATS.thisDay);
};

const messages = ftl`\nkey = { SHORTDATE($date) }\n`;
const resource = new FluentResource(messages);
bundle = new FluentBundle("en-US", { functions: { SHORTDATE } });
bundle.addResource(resource);
});

test("works with difference in hours", function () {
const msg = bundle.getMessage("key");
const date = new Date("2025-02-15T10:30");
const errs = [];
const val = bundle.formatPattern(msg.value, { date }, errs);
assert.strictEqual(val, "10:30 AM");
assert.strictEqual(errs.length, 0);
});

test("works with difference in days", function () {
const msg = bundle.getMessage("key");
const date = new Date("2025-02-03T10:30");
const errs = [];
const val = bundle.formatPattern(msg.value, { date }, errs);
assert.strictEqual(val, "Feb 3, 10:30 AM");
assert.strictEqual(errs.length, 0);
});

test("works with difference in years", function () {
const msg = bundle.getMessage("key");
const date = new Date("2023-02-03T10:30");
const errs = [];
const val = bundle.formatPattern(msg.value, { date }, errs);
assert.strictEqual(val, "Feb 3, 2023");
assert.strictEqual(errs.length, 0);
});
});
});
14 changes: 7 additions & 7 deletions fluent-bundle/test/temporal_test.js
Original file line number Diff line number Diff line change
@@ -47,11 +47,11 @@ suite("Temporal support", function () {
});

test("direct interpolation", function () {
assert.strictEqual(msg("direct"), arg.toLocaleString());
assert.strictEqual(msg("direct"), arg.toLocaleString("en-US"));
});

test("run through DATETIME()", function () {
assert.strictEqual(msg("dt"), arg.toLocaleString());
assert.strictEqual(msg("dt"), arg.toLocaleString("en-US"));
});

test("run through DATETIME() with month option", function () {
@@ -66,7 +66,7 @@ suite("Temporal support", function () {

test("can be converted to a number", function () {
arg = new FluentDateTime(arg);
assert.strictEqual(arg.toNumber(), 0);
assert.strictEqual(+arg, 0);
});
});

@@ -94,7 +94,7 @@ suite("Temporal support", function () {

test("can be converted to a number", function () {
arg = new FluentDateTime(arg);
assert.strictEqual(arg.toNumber(), 0);
assert.strictEqual(+arg, 0);
});
});

@@ -123,7 +123,7 @@ suite("Temporal support", function () {

test("can be converted to a number", function () {
arg = new FluentDateTime(arg);
assert.strictEqual(arg.toNumber(), 0);
assert.strictEqual(+arg, 0);
});
});
}
@@ -171,7 +171,7 @@ suite("Temporal support", function () {

test("cannot be converted to a number", function () {
arg = new FluentDateTime(arg);
assert.throws(() => arg.toNumber(), TypeError);
assert.throws(() => +arg, TypeError);
});
});

@@ -203,7 +203,7 @@ suite("Temporal support", function () {

test("cannot be converted to a number", function () {
arg = new FluentDateTime(arg);
assert.throws(() => arg.toNumber(), TypeError);
assert.throws(() => +arg, TypeError);
});
});
});
4 changes: 4 additions & 0 deletions fluent-dom/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## [0.10.1](https://github.com/projectfluent/fluent.js/compare/@fluent/dom@0.10.0...@fluent/dom@0.10.1) (2025-03-27)

- Add aria-description as a localizable string ([#640](https://github.com/projectfluent/fluent.js/issues/640))

## [0.10.0](https://github.com/projectfluent/fluent.js/compare/@fluent/dom@0.9.0...@fluent/dom@0.10.0) (2024-06-25)

### ⚠ Breaking Changes
2 changes: 1 addition & 1 deletion fluent-dom/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@fluent/dom",
"version": "0.10.0",
"version": "0.10.1",
"description": "Fluent bindings for DOM",
"repository": {
"type": "git",
2 changes: 1 addition & 1 deletion fluent-dom/src/overlay.js
Original file line number Diff line number Diff line change
@@ -45,7 +45,7 @@ const TEXT_LEVEL_ELEMENTS = {

const LOCALIZABLE_ATTRIBUTES = {
"http://www.w3.org/1999/xhtml": {
global: ["title", "aria-label", "aria-valuetext"],
global: ["title", "aria-description", "aria-label", "aria-valuetext"],
a: ["download"],
area: ["download", "alt"],
// value is special-cased in isAttrNameLocalizable
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 13 additions & 9 deletions typedoc.json
Original file line number Diff line number Diff line change
@@ -10,25 +10,29 @@
"./fluent-sequence",
"./fluent-syntax"
],
"hideGenerator": true,
"highlightLanguages": ["html", "javascript", "jsx", "typescript"],
"navigation": {
"includeCategories": true,
"includeFolders": false
},
"navigationLinks": {
"Project Fluent": "https://projectfluent.org/",
"GitHub": "https://github.com/projectfluent/fluent.js"
},
"out": "./html",
"packageOptions": {
"entryPoints": ["src/index.ts"],
"includeVersion": true
},
"plugin": ["typedoc-plugin-redirect"],
"hideGenerator": true,
"highlightLanguages": ["html", "javascript", "jsx", "typescript"],
"redirects": {
"bundle": "modules/_fluent_bundle.html",
"dedent": "modules/_fluent_dedent.html",
"dom": "modules/_fluent_dom.html",
"langneg": "modules/_fluent_langneg.html",
"react": "modules/_fluent_react.html",
"sequence": "modules/_fluent_sequence.html",
"syntax": "modules/_fluent_syntax.html"
"bundle/index.html": "modules/_fluent_bundle.html",
"dedent/index.html": "modules/_fluent_dedent.html",
"dom/index.html": "modules/_fluent_dom.html",
"langneg/index.html": "modules/_fluent_langneg.html",
"react/index.html": "modules/_fluent_react.html",
"sequence/index.html": "modules/_fluent_sequence.html",
"syntax/index.html": "modules/_fluent_syntax.html"
}
}