Got ffm.js working
This commit is contained in:
parent
814bdc4eb8
commit
1880995e06
29 changed files with 41 additions and 32 deletions
|
@ -1,5 +1,6 @@
|
||||||
import { JSDOM } from "jsdom";
|
import { JSDOM } from "jsdom";
|
||||||
import type * as mfm from "mfm-js";
|
// import type * as mfm from "mfm-js";
|
||||||
|
import type * as mfm from "ffm-js";
|
||||||
import config from "@/config/index.js";
|
import config from "@/config/index.js";
|
||||||
import { intersperse } from "@/prelude/array.js";
|
import { intersperse } from "@/prelude/array.js";
|
||||||
import type { IMentionedRemoteUsers } from "@/models/entities/note.js";
|
import type { IMentionedRemoteUsers } from "@/models/entities/note.js";
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import * as mfm from "mfm-js";
|
import * as mfm from "ffm-js";
|
||||||
import { unique } from "@/prelude/array.js";
|
import { unique } from "@/prelude/array.js";
|
||||||
|
|
||||||
export function extractCustomEmojisFromMfm(nodes: mfm.MfmNode[]): string[] {
|
export function extractCustomEmojisFromMfm(nodes: mfm.MfmNode[]): string[] {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import * as mfm from "mfm-js";
|
import * as mfm from "ffm-js";
|
||||||
import { unique } from "@/prelude/array.js";
|
import { unique } from "@/prelude/array.js";
|
||||||
|
|
||||||
export function extractHashtags(nodes: mfm.MfmNode[]): string[] {
|
export function extractHashtags(nodes: mfm.MfmNode[]): string[] {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// test is located in test/extract-mentions
|
// test is located in test/extract-mentions
|
||||||
|
|
||||||
import * as mfm from "mfm-js";
|
import * as mfm from "ffm-js";
|
||||||
|
|
||||||
export function extractMentions(
|
export function extractMentions(
|
||||||
nodes: mfm.MfmNode[],
|
nodes: mfm.MfmNode[],
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { In } from "typeorm";
|
import { In } from "typeorm";
|
||||||
import * as mfm from "mfm-js";
|
import * as mfm from "ffm-js";
|
||||||
import { Note } from "@/models/entities/note.js";
|
import { Note } from "@/models/entities/note.js";
|
||||||
import type { User } from "@/models/entities/user.js";
|
import type { User } from "@/models/entities/user.js";
|
||||||
import {
|
import {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import * as mfm from "mfm-js";
|
import * as mfm from "ffm-js";
|
||||||
import type { Note } from "@/models/entities/note.js";
|
import type { Note } from "@/models/entities/note.js";
|
||||||
import { toHtml } from "../../../mfm/to-html.js";
|
import { toHtml } from "../../../mfm/to-html.js";
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import promiseLimit from "promise-limit";
|
import promiseLimit from "promise-limit";
|
||||||
import * as mfm from "mfm-js";
|
import * as mfm from "ffm-js";
|
||||||
import config from "@/config/index.js";
|
import config from "@/config/index.js";
|
||||||
import Resolver from "../resolver.js";
|
import Resolver from "../resolver.js";
|
||||||
import post from "@/services/note/create.js";
|
import post from "@/services/note/create.js";
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { URL } from "node:url";
|
import { URL } from "node:url";
|
||||||
import * as mfm from "mfm-js";
|
import * as mfm from "ffm-js";
|
||||||
import config from "@/config/index.js";
|
import config from "@/config/index.js";
|
||||||
import type { ILocalUser } from "@/models/entities/user.js";
|
import type { ILocalUser } from "@/models/entities/user.js";
|
||||||
import { DriveFiles, UserProfiles } from "@/models/index.js";
|
import { DriveFiles, UserProfiles } from "@/models/index.js";
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import RE2 from "re2";
|
import RE2 from "re2";
|
||||||
import * as mfm from "mfm-js";
|
import * as mfm from "ffm-js";
|
||||||
import { publishMainStream, publishUserEvent } from "@/services/stream.js";
|
import { publishMainStream, publishUserEvent } from "@/services/stream.js";
|
||||||
import acceptAllFollowRequests from "@/services/following/requests/accept-all.js";
|
import acceptAllFollowRequests from "@/services/following/requests/accept-all.js";
|
||||||
import { publishToFollowers } from "@/services/i/update.js";
|
import { publishToFollowers } from "@/services/i/update.js";
|
||||||
|
|
|
@ -21,7 +21,7 @@ import define from "../../define.js";
|
||||||
import { HOUR } from "@/const.js";
|
import { HOUR } from "@/const.js";
|
||||||
import { getNote } from "../../common/getters.js";
|
import { getNote } from "../../common/getters.js";
|
||||||
import { Poll } from "@/models/entities/poll.js";
|
import { Poll } from "@/models/entities/poll.js";
|
||||||
import * as mfm from "mfm-js";
|
import * as mfm from "ffm-js";
|
||||||
import { concat } from "@/prelude/array.js";
|
import { concat } from "@/prelude/array.js";
|
||||||
import { extractHashtags } from "@/misc/extract-hashtags.js";
|
import { extractHashtags } from "@/misc/extract-hashtags.js";
|
||||||
import { extractCustomEmojisFromMfm } from "@/misc/extract-custom-emojis-from-mfm.js";
|
import { extractCustomEmojisFromMfm } from "@/misc/extract-custom-emojis-from-mfm.js";
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import * as mfm from "mfm-js";
|
import * as mfm from "ffm-js";
|
||||||
import es from "../../db/elasticsearch.js";
|
import es from "../../db/elasticsearch.js";
|
||||||
import sonic from "../../db/sonic.js";
|
import sonic from "../../db/sonic.js";
|
||||||
import {
|
import {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import * as assert from "assert";
|
import * as assert from "assert";
|
||||||
|
|
||||||
import { parse } from "mfm-js";
|
import { parse } from "ffm-js";
|
||||||
import { extractMentions } from "../src/misc/extract-mentions.js";
|
import { extractMentions } from "../src/misc/extract-mentions.js";
|
||||||
|
|
||||||
describe("Extract mentions", () => {
|
describe("Extract mentions", () => {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import * as assert from "assert";
|
import * as assert from "assert";
|
||||||
import * as mfm from "mfm-js";
|
import * as mfm from "ffm-js";
|
||||||
|
|
||||||
import { toHtml } from "../src/mfm/to-html.js";
|
import { toHtml } from "../src/mfm/to-html.js";
|
||||||
import { fromHtml } from "../src/mfm/from-html.js";
|
import { fromHtml } from "../src/mfm/from-html.js";
|
||||||
|
|
|
@ -256,7 +256,7 @@
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, inject, onMounted, ref } from "vue";
|
import { computed, inject, onMounted, ref } from "vue";
|
||||||
import * as mfm from "mfm-js";
|
import * as mfm from "ffm-js";
|
||||||
import type { Ref } from "vue";
|
import type { Ref } from "vue";
|
||||||
import type * as misskey from "firefish-js";
|
import type * as misskey from "firefish-js";
|
||||||
import MkNoteSub from "@/components/MkNoteSub.vue";
|
import MkNoteSub from "@/components/MkNoteSub.vue";
|
||||||
|
|
|
@ -242,7 +242,7 @@ import {
|
||||||
ref,
|
ref,
|
||||||
computed,
|
computed,
|
||||||
} from "vue";
|
} from "vue";
|
||||||
import * as mfm from "mfm-js";
|
import * as mfm from "ffm-js";
|
||||||
import * as misskey from "firefish-js";
|
import * as misskey from "firefish-js";
|
||||||
import autosize from "autosize";
|
import autosize from "autosize";
|
||||||
import insertTextAtCursor from "insert-text-at-cursor";
|
import insertTextAtCursor from "insert-text-at-cursor";
|
||||||
|
|
|
@ -178,7 +178,7 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref } from "vue";
|
import { ref } from "vue";
|
||||||
import * as misskey from "firefish-js";
|
import * as misskey from "firefish-js";
|
||||||
import * as mfm from "mfm-js";
|
import * as mfm from "ffm-js";
|
||||||
import * as os from "@/os";
|
import * as os from "@/os";
|
||||||
import XNoteSimple from "@/components/MkNoteSimple.vue";
|
import XNoteSimple from "@/components/MkNoteSimple.vue";
|
||||||
import XMediaList from "@/components/MkMediaList.vue";
|
import XMediaList from "@/components/MkMediaList.vue";
|
||||||
|
|
|
@ -135,7 +135,7 @@ const embedId = `embed${Math.random().toString().replace(/\D/, "")}`;
|
||||||
let tweetHeight = ref(150);
|
let tweetHeight = ref(150);
|
||||||
|
|
||||||
const requestUrl = new URL(props.url);
|
const requestUrl = new URL(props.url);
|
||||||
if (!["http:", "https:"].includes(requestUrl.protocol))
|
if (!["http:", "https:", "gopher:", "gemini:", "matrix:"].includes(requestUrl.protocol))
|
||||||
throw new Error("invalid url");
|
throw new Error("invalid url");
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
|
|
@ -11,14 +11,14 @@
|
||||||
@click.stop
|
@click.stop
|
||||||
>
|
>
|
||||||
<template v-if="!self">
|
<template v-if="!self">
|
||||||
<span class="schema">{{ schema }}//</span>
|
<span class="schema">{{ schema }}{{ hostname.trim() != '' ? '//' : '' }}</span>
|
||||||
<span class="hostname">{{ hostname }}</span>
|
<span class="hostname">{{ hostname.trim() != '' ? hostname.trim() : pathname }}</span>
|
||||||
<span v-if="port != ''" class="port">:{{ port }}</span>
|
<span v-if="port != ''" class="port">:{{ port }}</span>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="pathname === '/' && self">
|
<template v-if="pathname === '/' && self">
|
||||||
<span class="self">{{ hostname }}</span>
|
<span class="self">{{ hostname }}</span>
|
||||||
</template>
|
</template>
|
||||||
<span v-if="pathname != ''" class="pathname">{{
|
<span v-if="pathname != '' && !!hostname" class="pathname">{{
|
||||||
self ? pathname.substring(1) : pathname
|
self ? pathname.substring(1) : pathname
|
||||||
}}</span>
|
}}</span>
|
||||||
<span class="query">{{ query }}</span>
|
<span class="query">{{ query }}</span>
|
||||||
|
@ -45,7 +45,7 @@ const props = defineProps<{
|
||||||
|
|
||||||
const self = props.url.startsWith(local);
|
const self = props.url.startsWith(local);
|
||||||
const url = new URL(props.url);
|
const url = new URL(props.url);
|
||||||
if (!["http:", "https:"].includes(url.protocol)) throw new Error("invalid url");
|
if (!["http:", "https:", "gopher:", "gemini:", "matrix:"].includes(url.protocol)) throw new Error("invalid url");
|
||||||
const el = ref();
|
const el = ref();
|
||||||
|
|
||||||
useTooltip(el, (showing) => {
|
useTooltip(el, (showing) => {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { defineComponent, h } from "vue";
|
import { defineComponent, h } from "vue";
|
||||||
import * as mfm from "mfm-js";
|
import * as mfm from "ffm-js";
|
||||||
import type { VNode } from "vue";
|
import type { VNode } from "vue";
|
||||||
import MkUrl from "@/components/global/MkUrl.vue";
|
import MkUrl from "@/components/global/MkUrl.vue";
|
||||||
import MkLink from "@/components/MkLink.vue";
|
import MkLink from "@/components/MkLink.vue";
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
import { TextBlock } from "@/scripts/hpml/block";
|
import { TextBlock } from "@/scripts/hpml/block";
|
||||||
import { Hpml } from "@/scripts/hpml/evaluator";
|
import { Hpml } from "@/scripts/hpml/evaluator";
|
||||||
import { defineAsyncComponent, defineComponent, PropType } from "vue";
|
import { defineAsyncComponent, defineComponent, PropType } from "vue";
|
||||||
import * as mfm from "mfm-js";
|
import * as mfm from "ffm-js";
|
||||||
import { extractUrlFromMfm } from "@/scripts/extract-url-from-mfm";
|
import { extractUrlFromMfm } from "@/scripts/extract-url-from-mfm";
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
|
|
|
@ -85,7 +85,7 @@
|
||||||
import { computed } from "vue";
|
import { computed } from "vue";
|
||||||
|
|
||||||
import {} from "vue";
|
import {} from "vue";
|
||||||
import * as mfm from "mfm-js";
|
import * as mfm from "ffm-js";
|
||||||
import type * as Misskey from "firefish-js";
|
import type * as Misskey from "firefish-js";
|
||||||
import XMediaList from "@/components/MkMediaList.vue";
|
import XMediaList from "@/components/MkMediaList.vue";
|
||||||
import { extractUrlFromMfm } from "@/scripts/extract-url-from-mfm";
|
import { extractUrlFromMfm } from "@/scripts/extract-url-from-mfm";
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// test is located in test/extract-mentions
|
// test is located in test/extract-mentions
|
||||||
|
|
||||||
import * as mfm from "mfm-js";
|
import * as mfm from "ffm-js";
|
||||||
|
|
||||||
export function extractMentions(
|
export function extractMentions(
|
||||||
nodes: mfm.MfmNode[],
|
nodes: mfm.MfmNode[],
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import * as mfm from "mfm-js";
|
import * as mfm from "ffm-js";
|
||||||
|
|
||||||
const animatedMfm = [
|
const animatedMfm = [
|
||||||
"tada",
|
"tada",
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import * as mfm from "mfm-js";
|
import * as mfm from "ffm-js";
|
||||||
import { unique } from "@/scripts/array";
|
import { unique } from "@/scripts/array";
|
||||||
|
|
||||||
// unique without hash
|
// unique without hash
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import * as mfm from "mfm-js";
|
import * as mfm from "ffm-js";
|
||||||
import { defaultStore } from "@/store";
|
import { defaultStore } from "@/store";
|
||||||
import { expandKaTeXMacro } from "@/scripts/katex-macro";
|
import { expandKaTeXMacro } from "@/scripts/katex-macro";
|
||||||
|
|
||||||
|
|
|
@ -89,7 +89,7 @@ export default defineConfig(({ command, mode }) => {
|
||||||
sourcemap: process.env.NODE_ENV === "development",
|
sourcemap: process.env.NODE_ENV === "development",
|
||||||
reportCompressedSize: false,
|
reportCompressedSize: false,
|
||||||
commonjsOptions: {
|
commonjsOptions: {
|
||||||
include: [/firefish-js/, /node_modules/],
|
include: [/firefish-js/, /ffm-js/, /node_modules/],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
optimizeDeps: {
|
optimizeDeps: {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "ffm-js",
|
"name": "ffm-js",
|
||||||
"version": "0.23.3",
|
"version": "0.23.3",
|
||||||
"description": "An MFM parser implementation with TypeScript",
|
"description": "An FFM parser implementation with TypeScript",
|
||||||
"main": "./built/index.js",
|
"main": "./built/index.js",
|
||||||
"types": "./built/index.d.ts",
|
"types": "./built/index.d.ts",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|
|
@ -674,7 +674,7 @@ export const language = P.createLanguage({
|
||||||
]));
|
]));
|
||||||
const parser = P.seq([
|
const parser = P.seq([
|
||||||
notLinkLabel,
|
notLinkLabel,
|
||||||
P.regexp(/https?:\/\//),
|
P.regexp(/((https?)|(gemini)|(gopher)|(matrix)):\/\//),
|
||||||
innerItem.many(1).text(),
|
innerItem.many(1).text(),
|
||||||
]);
|
]);
|
||||||
return new P.Parser<M.MfmUrl | string>((input, index, state) => {
|
return new P.Parser<M.MfmUrl | string>((input, index, state) => {
|
||||||
|
@ -706,7 +706,7 @@ export const language = P.createLanguage({
|
||||||
const parser = P.seq([
|
const parser = P.seq([
|
||||||
notLinkLabel,
|
notLinkLabel,
|
||||||
open,
|
open,
|
||||||
P.regexp(/https?:\/\//),
|
P.regexp(/((https?)|(gemini)|(gopher)|(matrix)):\/\//),
|
||||||
P.seq([P.notMatch(P.alt([close, space])), P.char], 1).many(1),
|
P.seq([P.notMatch(P.alt([close, space])), P.char], 1).many(1),
|
||||||
close,
|
close,
|
||||||
]).text();
|
]).text();
|
||||||
|
|
|
@ -912,6 +912,14 @@ hoge`;
|
||||||
assert.deepStrictEqual(mfm.parse(input), output);
|
assert.deepStrictEqual(mfm.parse(input), output);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('gopher', () => {
|
||||||
|
const input = 'gopher://misskey.io/@ai';
|
||||||
|
const output = [
|
||||||
|
N_URL('gopher://misskey.io/@ai'),
|
||||||
|
];
|
||||||
|
assert.deepStrictEqual(mfm.parse(input), output);
|
||||||
|
});
|
||||||
|
|
||||||
test('with other texts', () => {
|
test('with other texts', () => {
|
||||||
const input = 'official instance: https://misskey.io/@ai.';
|
const input = 'official instance: https://misskey.io/@ai.';
|
||||||
const output = [
|
const output = [
|
||||||
|
|
Loading…
Reference in a new issue