diff options
Diffstat (limited to 'src/data/things')
| -rw-r--r-- | src/data/things/language.js | 49 | ||||
| -rw-r--r-- | src/data/things/track.js | 23 |
2 files changed, 55 insertions, 17 deletions
diff --git a/src/data/things/language.js b/src/data/things/language.js index 997cf31e..43f69f3d 100644 --- a/src/data/things/language.js +++ b/src/data/things/language.js @@ -4,16 +4,16 @@ import {withAggregate} from '#aggregate'; import CacheableObject from '#cacheable-object'; import {input} from '#composite'; import * as html from '#html'; -import {empty, withEntries} from '#sugar'; +import {accumulateSum, empty, withEntries} from '#sugar'; import {isLanguageCode} from '#validators'; import Thing from '#thing'; import {languageOptionRegex} from '#wiki-data'; import { + externalLinkSpec, getExternalLinkStringOfStyleFromDescriptors, getExternalLinkStringsFromDescriptors, isExternalLinkContext, - isExternalLinkSpec, isExternalLinkStyle, } from '#external-links'; @@ -82,13 +82,6 @@ export class Language extends Thing { update: {validate: (t) => typeof t === 'object'}, }, - // List of descriptors for providing to external link utilities when using - // language.formatExternalLink - refer to #external-links for info. - externalLinkSpec: { - flags: {update: true, expose: true}, - update: {validate: isExternalLinkSpec}, - }, - // Expose only isLanguage: [ @@ -106,12 +99,14 @@ export class Language extends Thing { intl_date: this.#intlHelper(Intl.DateTimeFormat, {full: true}), intl_dateYear: this.#intlHelper(Intl.DateTimeFormat, {year: 'numeric'}), + intl_dateMonthDay: this.#intlHelper(Intl.DateTimeFormat, {month: 'numeric', day: 'numeric'}), intl_number: this.#intlHelper(Intl.NumberFormat), intl_listConjunction: this.#intlHelper(Intl.ListFormat, {type: 'conjunction'}), intl_listDisjunction: this.#intlHelper(Intl.ListFormat, {type: 'disjunction'}), intl_listUnit: this.#intlHelper(Intl.ListFormat, {type: 'unit'}), intl_pluralCardinal: this.#intlHelper(Intl.PluralRules, {type: 'cardinal'}), intl_pluralOrdinal: this.#intlHelper(Intl.PluralRules, {type: 'ordinal'}), + intl_wordSegmenter: this.#intlHelper(Intl.Segmenter, {granularity: 'word'}), validKeys: { flags: {expose: true}, @@ -169,6 +164,15 @@ export class Language extends Thing { } } + countWords(text) { + this.assertIntlAvailable('intl_wordSegmenter'); + + const string = html.resolve(text, {normalize: 'plain'}); + const segments = this.intl_wordSegmenter.segment(string); + + return accumulateSum(segments, segment => segment.isWordLike ? 1 : 0); + } + getUnitForm(value) { this.assertIntlAvailable('intl_pluralCardinal'); return this.intl_pluralCardinal.select(value); @@ -350,13 +354,19 @@ export class Language extends Thing { partInProgress += template.slice(lastIndex, match.index); - for (const insertionItem of html.smush(insertion).content) { + const insertionItems = html.smush(insertion).content; + if (insertionItems.length === 1 && typeof insertionItems[0] !== 'string') { + // Push the insertion exactly as it is, rather than manipulating. + if (partInProgress) outputParts.push(partInProgress); + outputParts.push(insertion); + partInProgress = ''; + } else for (const insertionItem of insertionItems) { if (typeof insertionItem === 'string') { // Join consecutive strings together. partInProgress += insertionItem; } else { // Push the string part in progress, then the insertion as-is. - outputParts.push(partInProgress); + if (partInProgress) outputParts.push(partInProgress); outputParts.push(insertionItem); partInProgress = ''; } @@ -470,6 +480,15 @@ export class Language extends Thing { return this.intl_dateYear.format(date); } + formatMonthDay(date) { + if (date === null || date === undefined) { + return html.blank(); + } + + this.assertIntlAvailable('intl_dateMonthDay'); + return this.intl_dateMonthDay.format(date); + } + formatYearRange(startDate, endDate) { // formatYearRange expects both values to be present, but if both are null // or both are undefined, that's just blank content. @@ -648,10 +667,6 @@ export class Language extends Thing { style = 'platform', context = 'generic', } = {}) { - if (!this.externalLinkSpec) { - throw new TypeError(`externalLinkSpec unavailable`); - } - // Null or undefined url is blank content. if (url === null || url === undefined) { return html.blank(); @@ -660,7 +675,7 @@ export class Language extends Thing { isExternalLinkContext(context); if (style === 'all') { - return getExternalLinkStringsFromDescriptors(url, this.externalLinkSpec, { + return getExternalLinkStringsFromDescriptors(url, externalLinkSpec, { language: this, context, }); @@ -669,7 +684,7 @@ export class Language extends Thing { isExternalLinkStyle(style); const result = - getExternalLinkStringOfStyleFromDescriptors(url, style, this.externalLinkSpec, { + getExternalLinkStringOfStyleFromDescriptors(url, style, externalLinkSpec, { language: this, context, }); diff --git a/src/data/things/track.js b/src/data/things/track.js index 93193b6a..64790a61 100644 --- a/src/data/things/track.js +++ b/src/data/things/track.js @@ -393,6 +393,17 @@ export class Track extends Thing { // > Update & expose - Referenced tracks + previousProductionTracks: [ + inheritFromMainRelease({ + notFoundValue: input.value([]), + }), + + referenceList({ + class: input.value(Track), + find: soupyFind.input('trackMainReleasesOnly'), + }), + ], + referencedTracks: [ inheritFromMainRelease({ notFoundValue: input.value([]), @@ -563,6 +574,10 @@ export class Track extends Thing { }), ], + followingProductionTracks: reverseReferenceList({ + reverse: soupyReverse.input('tracksWhichAreFollowingProductionsOf'), + }), + referencedByTracks: reverseReferenceList({ reverse: soupyReverse.input('tracksWhichReference'), }), @@ -701,6 +716,7 @@ export class Track extends Thing { // Referenced tracks + 'Previous Productions': {property: 'previousProductionTracks'}, 'Referenced Tracks': {property: 'referencedTracks'}, 'Sampled Tracks': {property: 'sampledTracks'}, @@ -912,6 +928,13 @@ export class Track extends Thing { referencing: track => track.isSecondaryRelease ? [track] : [], referenced: track => [track.mainReleaseTrack], }, + + tracksWhichAreFollowingProductionsOf: { + bindTo: 'trackData', + + referencing: track => track, + referenced: track => track.previousProductionTracks, + }, }; // Track YAML loading is handled in album.js. |