diff --git a/packages/mdast-util-is-node/lib/main.test.ts b/packages/mdast-util-is-node/lib/main.test.ts index 802a54470..9732caf48 100644 --- a/packages/mdast-util-is-node/lib/main.test.ts +++ b/packages/mdast-util-is-node/lib/main.test.ts @@ -1,8 +1,10 @@ import {test} from "uvu" import {is} from "uvu/assert" import { + isCodeNode, isHeadingNode, isHtmlNode, + isInlineCodeNode, isLiteralNode, isNode, isParagraphNode, @@ -36,7 +38,9 @@ const p1: [Is, unknown][] = [ [isTextNode, {type: "text", value: ""}], [isHtmlNode, {type: "html", value: ""}], [isParagraphNode, {type: "paragraph", children: []}], + [isInlineCodeNode, {type: "inlineCode", value: ""}], [isHeadingNode, {type: "heading", depth: 1, children: []}], + [isCodeNode, {type: "code", value: ""}], ] for (const [xi, xn] of p1) { diff --git a/packages/mdast-util-is-node/lib/main.ts b/packages/mdast-util-is-node/lib/main.ts index 6551f0661..843c4f3f7 100644 --- a/packages/mdast-util-is-node/lib/main.ts +++ b/packages/mdast-util-is-node/lib/main.ts @@ -1,6 +1,8 @@ import { + type Code, type Heading, type Html, + type InlineCode, type Literal, type Node, type Paragraph, @@ -8,6 +10,10 @@ import { type Text, } from "mdast" +export function isCodeNode(u: unknown): u is Code { + return isLiteralNode(u) && u.type === "code" +} + export function isHeadingNode(u: unknown): u is Heading { return isParentNode(u) && u.type === "heading" && @@ -15,6 +21,10 @@ export function isHeadingNode(u: unknown): u is Heading { typeof u.depth === "number" } +export function isInlineCodeNode(u: unknown): u is InlineCode { + return isLiteralNode(u) && u.type === "inlineCode" +} + export function isParagraphNode(u: unknown): u is Paragraph { return isParentNode(u) && u.type === "paragraph" } diff --git a/packages/mdast-util-is-node/package.json b/packages/mdast-util-is-node/package.json index 9bd9695fd..81ef79622 100644 --- a/packages/mdast-util-is-node/package.json +++ b/packages/mdast-util-is-node/package.json @@ -2,21 +2,25 @@ "name": "@onlyoffice/mdast-util-is-node", "type": "module", "private": true, - "main": "lib/main.ts", + "main": "dist/main.js", "scripts": { - "clean": "rimraf coverage node_modules", + "build:code": "esbuild lib/* --outdir=dist", + "build:types": "tsc --project tsconfig.emit.json", + "build": "pnpm build:types && pnpm build:code", + "clean": "rimraf coverage dist node_modules", "test:types": "tsc", "test:unit": "c8 --config ../../c8.config.json tsx node_modules/uvu/bin.js lib ^.*\\.test\\.ts$", "test": "pnpm test:types && pnpm test:unit" }, "dependencies": { - "@types/mdast": "4.0.3", - "typescript": "5.4.5" + "@types/mdast": "4.0.3" }, "devDependencies": { "c8": "9.1.0", + "esbuild": "0.23.0", "rimraf": "6.0.1", "tsx": "4.16.5", + "typescript": "5.4.5", "uvu": "0.5.6" } } diff --git a/packages/mdast-util-is-node/tsconfig.emit.json b/packages/mdast-util-is-node/tsconfig.emit.json new file mode 100644 index 000000000..63afdafb0 --- /dev/null +++ b/packages/mdast-util-is-node/tsconfig.emit.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.emit.json", + "compilerOptions": { + "rootDir": "lib", + "outDir": "dist" + }, + "include": ["lib"] +} diff --git a/packages/remark-config/lib/main.ts b/packages/remark-config/lib/main.ts index 2349bfb10..f37ec786c 100644 --- a/packages/remark-config/lib/main.ts +++ b/packages/remark-config/lib/main.ts @@ -4,6 +4,7 @@ // https://github.com/remarkjs/remark-lint/tree/10.0.0/packages/remark-lint-no-html import {remarkLintEslint} from "@onlyoffice/remark-lint-eslint" +import {remarkLintNoUnicode} from "@onlyoffice/remark-lint-no-unicode" import remarkLint from "remark-lint" import remarkLintBlockquoteIndentation from "remark-lint-blockquote-indentation" import remarkLintCheckboxCharacterStyle from "remark-lint-checkbox-character-style" @@ -143,6 +144,123 @@ export function remarkConfig(): Preset { remarkLintNoTableIndentation, remarkLintNoTabs, remarkLintNoUndefinedReferences, + [remarkLintNoUnicode, { + hints: [ + ["0060", "Grave Accent", "0027", "Apostrophe"], + ["00A0", "No-Break Space", "0020", "Space"], + ["2013", "En Dash", "002D", "Hyphen-Minus"], + ["2019", "Right Single Quotation Mark", "0027", "Apostrophe"], + ], + codes: [ + // Basic Latin + "000A", // \n + "0020", // EMPTY SPACE + "0021", // ! + "0022", // " + "0023", // # + "0024", // $ + "0025", // % + "0026", // & + "0027", // ' + "0028", // ( + "0029", // ) + "002A", // * + "002B", // + + "002C", // , + "002D", // - + "002E", // . + "002F", // / + "0030", // 0 + "0031", // 1 + "0032", // 2 + "0033", // 3 + "0034", // 4 + "0035", // 5 + "0036", // 6 + "0037", // 7 + "0038", // 8 + "0039", // 9 + "003A", // : + "003B", // ; + "003C", // < + "003D", // = + "003E", // > + "003F", // ? + "0040", // @ + "0041", // A + "0042", // B + "0043", // C + "0044", // D + "0045", // E + "0046", // F + "0047", // G + "0048", // H + "0049", // I + "004A", // J + "004B", // K + "004C", // L + "004D", // M + "004E", // N + "004F", // O + "0050", // P + "0051", // Q + "0052", // R + "0053", // S + "0054", // T + "0055", // U + "0056", // V + "0057", // W + "0058", // X + "0059", // Y + "005A", // Z + "005B", // [ + "005C", // \ + "005D", // ] + "005E", // ^ + "005F", // _ + "0061", // a + "0062", // b + "0063", // c + "0064", // d + "0065", // e + "0066", // f + "0067", // g + "0068", // h + "0069", // i + "006A", // j + "006B", // k + "006C", // l + "006D", // m + "006E", // n + "006F", // o + "0070", // p + "0071", // q + "0072", // r + "0073", // s + "0074", // t + "0075", // u + "0076", // v + "0077", // w + "0078", // x + "0079", // y + "007A", // z + "007B", // { + "007C", // | + "007D", // } + "007E", // ~ + + // Latin-1 Supplement + "00E4", // ä + "00F6", // ö + "00FC", // ü + + // General Punctuation + "2014", // — + + // Mathematical Operators + "22EE", // ⋮ + ], + }], remarkLintNoUnusedDefinitions, [remarkLintOrderedListMarkerStyle, "."], [remarkLintOrderedListMarkerValue, "ordered"], diff --git a/packages/remark-config/package.json b/packages/remark-config/package.json index 723635047..652598466 100644 --- a/packages/remark-config/package.json +++ b/packages/remark-config/package.json @@ -14,6 +14,7 @@ }, "dependencies": { "@onlyoffice/remark-lint-eslint": "workspace:^", + "@onlyoffice/remark-lint-no-unicode": "workspace:^", "remark-lint": "10.0.0", "remark-lint-blockquote-indentation": "4.0.0", "remark-lint-checkbox-character-style": "5.0.0", diff --git a/packages/remark-lint-no-unicode/fixtures/000.txt b/packages/remark-lint-no-unicode/fixtures/000.txt new file mode 100644 index 000000000..2b3f4063f --- /dev/null +++ b/packages/remark-lint-no-unicode/fixtures/000.txt @@ -0,0 +1,9 @@ +ignores an empty document + +--- + + +--- + + +--- diff --git a/packages/remark-lint-no-unicode/fixtures/001.txt b/packages/remark-lint-no-unicode/fixtures/001.txt new file mode 100644 index 000000000..982b04878 --- /dev/null +++ b/packages/remark-lint-no-unicode/fixtures/001.txt @@ -0,0 +1,10 @@ +ignores a document that does not contain forbidden characters + +--- + +abc + +--- + + +--- diff --git a/packages/remark-lint-no-unicode/fixtures/002.txt b/packages/remark-lint-no-unicode/fixtures/002.txt new file mode 100644 index 000000000..16b180a98 --- /dev/null +++ b/packages/remark-lint-no-unicode/fixtures/002.txt @@ -0,0 +1,14 @@ +ignores forbidden characters in inline code and fenced code blocks + +--- + +`abcd` + +``` +abcd +``` + +--- + + +--- diff --git a/packages/remark-lint-no-unicode/fixtures/003.txt b/packages/remark-lint-no-unicode/fixtures/003.txt new file mode 100644 index 000000000..86c7982ea --- /dev/null +++ b/packages/remark-lint-no-unicode/fixtures/003.txt @@ -0,0 +1,16 @@ +sends an abstract message if a document contains forbidden characters + +--- + +# abcd + +abcd +abcd + +--- + +1:6-1:7: Character "d" (U+0064) is not allowed. Refer to "https://symbl.cc/en/0064/" for information regarding this character. +3:4-3:5: Character "d" (U+0064) is not allowed. Refer to "https://symbl.cc/en/0064/" for information regarding this character. +4:4-4:5: Character "d" (U+0064) is not allowed. Refer to "https://symbl.cc/en/0064/" for information regarding this character. + +--- diff --git a/packages/remark-lint-no-unicode/fixtures/004.txt b/packages/remark-lint-no-unicode/fixtures/004.txt new file mode 100644 index 000000000..58275e49e --- /dev/null +++ b/packages/remark-lint-no-unicode/fixtures/004.txt @@ -0,0 +1,11 @@ +sends a concrete message if a document contains forbidden characters + +--- + +ab c + +--- + +1:3-1:4: No-Break Space character " " (U+00A0) is not allowed. Consider replacing it with a Space character " " (U+0020). Refer to "https://symbl.cc/en/00A0/" and "https://symbl.cc/en/0020/" for information regarding these characters. + +--- diff --git a/packages/remark-lint-no-unicode/lib/main.test.ts b/packages/remark-lint-no-unicode/lib/main.test.ts new file mode 100644 index 000000000..c89a03cfd --- /dev/null +++ b/packages/remark-lint-no-unicode/lib/main.test.ts @@ -0,0 +1,53 @@ +import {readFile, readdir} from "node:fs/promises" +import path from "node:path" +import remarkLint from "remark-lint" +import remarkParse from "remark-parse" +import remarkStringify from "remark-stringify" +import {unified} from "unified" +import {test} from "uvu" +import {equal as eq} from "uvu/assert" +import {remarkLintNoUnicode} from "./main.ts" + +for (const [n, v, e] of await list()) { + test(n, async () => { + const f = await unified() + .use(remarkParse) + .use(remarkLint) + .use(remarkLintNoUnicode, { + hints: [ + ["0060", "Grave Accent", "0027", "Apostrophe"], + ["00A0", "No-Break Space", "0020", "Space"], + ], + codes: ["000A", "0061", "0062", "0063"], + }) + .use(remarkStringify) + .process(v) + const a = f.messages.map(String) + eq(a, e) + }) +} + +test.run() + +type TestCase = [string, string, string[]] + +async function list(): Promise { + const a: TestCase[] = [] + const d = await readdir("fixtures") + for (const n of d) { + const e = path.extname(n) + const p = path.basename(n, e) + const s = await readFile(`fixtures/${n}`, "utf8") + const c = create(p, s) + a.push(c) + } + return a +} + +function create(p: string, s: string): TestCase { + let [n, m, h] = s.split("\n---\n") + n = n.slice(0, -1) + m = m.slice(1).slice(0, -1) + h = h.slice(1).slice(0, -1) + return [`${p}: ${n}`, m, h.split("\n").filter((f) => f !== "")] +} diff --git a/packages/remark-lint-no-unicode/lib/main.ts b/packages/remark-lint-no-unicode/lib/main.ts new file mode 100644 index 000000000..9218509f2 --- /dev/null +++ b/packages/remark-lint-no-unicode/lib/main.ts @@ -0,0 +1,177 @@ +import { + isCodeNode, + isInlineCodeNode, + isLiteralNode, + isParentNode, +} from "@onlyoffice/mdast-util-is-node" +import {type RemarkLintRule} from "@onlyoffice/remark-lint" +import {type Node} from "mdast" +import {lintRule} from "unified-lint-rule" +import {type Position} from "unist" +import {type MessageOptions, type VFile} from "vfile" + +export interface RemarkLintNoUnicodeOptions { + hints?: RemarkLintNoUnicodeHint[] + codes?: string[] +} + +export type RemarkLintNoUnicodeHint = [string, string, string, string] + +export const remarkLintNoUnicode: RemarkLintRule = + lintRule("@onlyoffice:no-unicode", rule) + +interface Options { + hints: Hints + codes: string[] +} + +type Hints = Record + +function rule(t: Node, f: VFile, o: RemarkLintNoUnicodeOptions): void { + const r = options(o) + check(t, f, r) +} + +function options(o: RemarkLintNoUnicodeOptions): Options { + const r: Options = { + hints: {}, + codes: [], + } + + if (o.hints) { + for (const [au, an, bu, bn] of o.hints) { + r.hints[au] = concrete(au, an, bu, bn) + } + } + + if (o.codes) { + r.codes = o.codes + } + + return r +} + +function check(t: Node, f: VFile, o: Options): void { + if (isCodeNode(t) || isInlineCodeNode(t)) { + return + } + + if (isParentNode(t)) { + for (const c of t.children) { + check(c, f, o) + } + return + } + + if (!isLiteralNode(t)) { + return + } + + for (let i = 0; i < t.value.length; i += 1) { + const c = t.value[i] + + const u = unicode(c) + if (!u) { + continue + } + + if (o.codes.includes(u)) { + continue + } + + const r = reason(o.hints, u) + + const p: MessageOptions = {ancestors: [t]} + if (t.position) { + p.place = place(t.position, t.value, i) + } + + f.message(r, p) + } +} + +function unicode(s: string): string { + const p = s.codePointAt(0) + if (p === undefined) { + return "" + } + + const u = p.toString(16).toUpperCase() + + switch (u.length) { + case 1: + return `000${u}` + case 2: + return `00${u}` + case 3: + return `0${u}` + default: + return u + } +} + +function character(u: string): string { + const n = Number.parseInt(u, 16) + return String.fromCodePoint(n) +} + +function reason(h: Hints, u: string): string { + let m = h[u] + + if (!m) { + m = abstract(u) + } + + return m +} + +function place(p: Position, a: string, i: number): Position { + let l = p.start.line + let c = p.start.column + + for (let j = 0; j <= i; j += 1) { + const s = a[j] + + if (s === "\n") { + c = 0 + l += 1 + } + + c += 1 + } + + return { + start: { + line: l, + column: c - 1, + }, + end: { + line: l, + column: c, + }, + } +} + +function abstract(u: string): string { + return `Character "${character(u)}" (U+${u}) is not allowed. Refer to "${ref(u)}" for information regarding this character.` +} + +function concrete(au: string, an: string, bu: string, bn: string): string { + return `${an} character "${character(au)}" (U+${au}) is not allowed. Consider replacing it with ${article(bn)} ${bn} character "${character(bu)}" (U+${bu}). Refer to "${ref(au)}" and "${ref(bu)}" for information regarding these characters.` +} + +function article(s: string): string { + s = s.toLowerCase() + s = s.charAt(0) + + const v = ["a", "e", "i", "o", "u"] + if (v.includes(s)) { + return "an" + } + + return "a" +} + +function ref(u: string): string { + return `https://symbl.cc/en/${u}/` +} diff --git a/packages/remark-lint-no-unicode/package.json b/packages/remark-lint-no-unicode/package.json new file mode 100644 index 000000000..b643be809 --- /dev/null +++ b/packages/remark-lint-no-unicode/package.json @@ -0,0 +1,35 @@ +{ + "name": "@onlyoffice/remark-lint-no-unicode", + "type": "module", + "private": true, + "main": "dist/main.js", + "scripts": { + "build:code": "esbuild lib/* --outdir=dist", + "build:types": "tsc --project tsconfig.emit.json", + "build": "pnpm build:types && pnpm build:code", + "clean": "rimraf dist node_modules", + "test:types": "tsc", + "test:unit": "c8 --config ../../c8.config.json tsx node_modules/uvu/bin.js lib ^.*\\.test\\.ts$", + "test": "pnpm test:types && pnpm test:unit" + }, + "dependencies": { + "@onlyoffice/mdast-util-is-node": "workspace:^", + "@onlyoffice/remark-lint": "workspace:^", + "@types/mdast": "4.0.3", + "@types/unist": "3.0.3", + "unified-lint-rule": "3.0.0", + "vfile": "6.0.1" + }, + "devDependencies": { + "c8": "9.1.0", + "esbuild": "0.23.0", + "remark-lint": "10.0.0", + "remark-parse": "11.0.0", + "remark-stringify": "11.0.0", + "rimraf": "6.0.1", + "tsx": "4.16.5", + "typescript": "5.4.5", + "unified": "11.0.5", + "uvu": "0.5.6" + } +} diff --git a/packages/remark-lint-no-unicode/tsconfig.emit.json b/packages/remark-lint-no-unicode/tsconfig.emit.json new file mode 100644 index 000000000..63afdafb0 --- /dev/null +++ b/packages/remark-lint-no-unicode/tsconfig.emit.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.emit.json", + "compilerOptions": { + "rootDir": "lib", + "outDir": "dist" + }, + "include": ["lib"] +} diff --git a/packages/remark-lint-no-unicode/tsconfig.json b/packages/remark-lint-no-unicode/tsconfig.json new file mode 100644 index 000000000..f0d8cf437 --- /dev/null +++ b/packages/remark-lint-no-unicode/tsconfig.json @@ -0,0 +1,4 @@ +{ + "extends": "../../tsconfig.base.json", + "include": ["lib"] +} diff --git a/packages/remark-lint/lib/main.ts b/packages/remark-lint/lib/main.ts new file mode 100644 index 000000000..2ba197120 --- /dev/null +++ b/packages/remark-lint/lib/main.ts @@ -0,0 +1,31 @@ +import {type TransformCallback} from "unified" +import {type Label, type Severity} from "unified-lint-rule" +import {type Node} from "unist" +import {type VFile} from "vfile" + +export interface RemarkLintRule< + Tree extends Node = Node, + Option = unknown, +> { + ( + config?: + Label | + Severity | + Option | + [ + level: Label | Severity, + option?: Option | undefined, + ] | + undefined + ): + ( + ( + tree: Tree, + file: VFile, + next: TransformCallback, + ) => undefined + ) | + undefined + + readonly name: string +} diff --git a/packages/remark-lint/package.json b/packages/remark-lint/package.json new file mode 100644 index 000000000..8fb85d555 --- /dev/null +++ b/packages/remark-lint/package.json @@ -0,0 +1,17 @@ +{ + "name": "@onlyoffice/remark-lint", + "type": "module", + "private": true, + "main": "lib/main.ts", + "scripts": { + "clean": "rimraf node_modules", + "test:types": "tsc", + "test": "pnpm test:types" + }, + "dependencies": { + "@types/unist": "3.0.3", + "unified": "11.0.5", + "unified-lint-rule": "3.0.0", + "vfile": "6.0.1" + } +} diff --git a/packages/remark-lint/tsconfig.json b/packages/remark-lint/tsconfig.json new file mode 100644 index 000000000..f0d8cf437 --- /dev/null +++ b/packages/remark-lint/tsconfig.json @@ -0,0 +1,4 @@ +{ + "extends": "../../tsconfig.base.json", + "include": ["lib"] +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index eba12fddf..c8f81ba4b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1367,19 +1367,22 @@ importers: '@types/mdast': specifier: 4.0.3 version: 4.0.3 - typescript: - specifier: 5.4.5 - version: 5.4.5 devDependencies: c8: specifier: 9.1.0 version: 9.1.0 + esbuild: + specifier: 0.23.0 + version: 0.23.0 rimraf: specifier: 6.0.1 version: 6.0.1 tsx: specifier: 4.16.5 version: 4.16.5 + typescript: + specifier: 5.4.5 + version: 5.4.5 uvu: specifier: 0.5.6 version: 0.5.6 @@ -2184,6 +2187,9 @@ importers: '@onlyoffice/remark-lint-eslint': specifier: workspace:^ version: link:../remark-lint-eslint + '@onlyoffice/remark-lint-no-unicode': + specifier: workspace:^ + version: link:../remark-lint-no-unicode remark-lint: specifier: 10.0.0 version: 10.0.0 @@ -2363,6 +2369,21 @@ importers: specifier: 0.5.6 version: 0.5.6 + packages/remark-lint: + dependencies: + '@types/unist': + specifier: 3.0.3 + version: 3.0.3 + unified: + specifier: 11.0.5 + version: 11.0.5 + unified-lint-rule: + specifier: 3.0.0 + version: 3.0.0 + vfile: + specifier: 6.0.1 + version: 6.0.1 + packages/remark-lint-eslint: dependencies: '@onlyoffice/eslint-config': @@ -2397,6 +2418,58 @@ importers: specifier: 0.5.6 version: 0.5.6 + packages/remark-lint-no-unicode: + dependencies: + '@onlyoffice/mdast-util-is-node': + specifier: workspace:^ + version: link:../mdast-util-is-node + '@onlyoffice/remark-lint': + specifier: workspace:^ + version: link:../remark-lint + '@types/mdast': + specifier: 4.0.3 + version: 4.0.3 + '@types/unist': + specifier: 3.0.3 + version: 3.0.3 + unified-lint-rule: + specifier: 3.0.0 + version: 3.0.0 + vfile: + specifier: 6.0.1 + version: 6.0.1 + devDependencies: + c8: + specifier: 9.1.0 + version: 9.1.0 + esbuild: + specifier: 0.23.0 + version: 0.23.0 + remark-lint: + specifier: 10.0.0 + version: 10.0.0 + remark-parse: + specifier: 11.0.0 + version: 11.0.0 + remark-stringify: + specifier: 11.0.0 + version: 11.0.0 + rimraf: + specifier: 6.0.1 + version: 6.0.1 + tsx: + specifier: 4.16.5 + version: 4.16.5 + typescript: + specifier: 5.4.5 + version: 5.4.5 + unified: + specifier: 11.0.5 + version: 11.0.5 + uvu: + specifier: 0.5.6 + version: 0.5.6 + packages/resource: dependencies: '@types/node': diff --git a/site/pages/DocSpace/Plugins SDK/Get Started/Basic concepts/index.md b/site/pages/DocSpace/Plugins SDK/Get Started/Basic concepts/index.md index 621cdc00d..d0907f21d 100644 --- a/site/pages/DocSpace/Plugins SDK/Get Started/Basic concepts/index.md +++ b/site/pages/DocSpace/Plugins SDK/Get Started/Basic concepts/index.md @@ -17,7 +17,7 @@ This documentation describes: Here are some examples of what you can do with ONLYOFFICE DocSpace plugins: - connect third-party services, like [Draw.io](https://github.com/ONLYOFFICE/docspace-plugins/tree/master/draw-io), [Speech to Text Conversion](https://github.com/ONLYOFFICE/docspace-plugins/tree/master/speech-to-text), etc.; -- enhance the existing user experience and the editors’ functionality: [PDF-converter](https://github.com/ONLYOFFICE/docspace-plugins/tree/master/pdf-converter). +- enhance the existing user experience and the editors functionality: [PDF-converter](https://github.com/ONLYOFFICE/docspace-plugins/tree/master/pdf-converter). Code samples are available at . diff --git a/site/pages/Docs/Desktop Editors/Get Started/How It Works/Encrypting local documents/index.md b/site/pages/Docs/Desktop Editors/Get Started/How It Works/Encrypting local documents/index.md index 9ad7d0f32..e9fe056d8 100644 --- a/site/pages/Docs/Desktop Editors/Get Started/How It Works/Encrypting local documents/index.md +++ b/site/pages/Docs/Desktop Editors/Get Started/How It Works/Encrypting local documents/index.md @@ -14,7 +14,7 @@ To build the **Encryption** plugin, you need to create three files: More information about the plugin structure can be found [here](../../../../Plugin%20and%20Macros/Structure/Manifest/index.md). -Let’s have a look at the config: +Let's have a look at the config: ``` json { @@ -84,9 +84,9 @@ As we can see from the code above, all files will be encrypted with one password ## Step 2. Creating the UI plugin for the app -The **Encryption** plugin has no interface and can’t run by default. It works only within a document where it is opened (in one tab of the app). To work with all the documents opened or created in different tabs of the ONLYOFFICE desktop, the **UI** plugin for the app should be created. It helps to use the **Encryption** plugin when necessary for the whole app. +The **Encryption** plugin has no interface and can't run by default. It works only within a document where it is opened (in one tab of the app). To work with all the documents opened or created in different tabs of the ONLYOFFICE desktop, the **UI** plugin for the app should be created. It helps to use the **Encryption** plugin when necessary for the whole app. -This plugin can’t access the editing features but has almost the same config: +This plugin can't access the editing features but has almost the same config: ``` json { diff --git a/site/pages/Docs/Desktop Editors/More Information/FAQ/index.md b/site/pages/Docs/Desktop Editors/More Information/FAQ/index.md index c39f9b429..e6d5b9da9 100644 --- a/site/pages/Docs/Desktop Editors/More Information/FAQ/index.md +++ b/site/pages/Docs/Desktop Editors/More Information/FAQ/index.md @@ -66,7 +66,7 @@ There are three ways for the desktop app to be recognized: ## How to open new windows in the desktop editors? -You can’t open new windows in the desktop editors because it is blocked (for example, for *OAuth*). +You can't open new windows in the desktop editors because it is blocked (for example, for *OAuth*). To open the document in a new window / tab correctly, you need to use the `window.open("http://url.to.document")` JavaScript command or the *open:document* command of the **execCommand** method. The details on how to open documents in the desktop editors can be found [in this section](../../Usage%20API/Adding%20a%20DMS%20provider/Opening%20documents/index.md). diff --git a/site/pages/Docs/Desktop Editors/Usage API/Adding a DMS provider/Configuring the interaction/index.md b/site/pages/Docs/Desktop Editors/Usage API/Adding a DMS provider/Configuring the interaction/index.md index dd8f6caa6..c78b0be90 100644 --- a/site/pages/Docs/Desktop Editors/Usage API/Adding a DMS provider/Configuring the interaction/index.md +++ b/site/pages/Docs/Desktop Editors/Usage API/Adding a DMS provider/Configuring the interaction/index.md @@ -9,7 +9,7 @@ Once your DMS is [added](../index.md) to the connection list, configure the DMS/ - change the interface [theme](../Changing%20a%20theme/index.md), - enable end-to-end [encryption](../Encryption/index.md). -Before proceeding further, it’s highly recommended to adjust the DMS elements to be displayed when the document is opened in the desktop application. +Before proceeding further, it's highly recommended to adjust the DMS elements to be displayed when the document is opened in the desktop application. Exclude the functionality which is not related to the document manager. Hide such sections like navigation, site header and footer, etc. Remove links to the third-party resources. Other pages will open in the default browser without interacting with the desktop editors. diff --git a/site/pages/Docs/Desktop Editors/Usage API/Adding plugins/index.md b/site/pages/Docs/Desktop Editors/Usage API/Adding plugins/index.md index e41065889..ecc09af64 100644 --- a/site/pages/Docs/Desktop Editors/Usage API/Adding plugins/index.md +++ b/site/pages/Docs/Desktop Editors/Usage API/Adding plugins/index.md @@ -83,7 +83,7 @@ If you need to uninstall the default plugins, go to the *sdkjs-plugins* folder a The table below contains default plugins guids to make it easier for you to find them: -## Default plugins guid’s +## Default plugins guid's | | | | -------------- | -------------------------------------- | diff --git a/site/pages/Docs/Docs API/Get Started/How It Works/Anonymous users/index.md b/site/pages/Docs/Docs API/Get Started/How It Works/Anonymous users/index.md index 882442c23..6f469ab9c 100644 --- a/site/pages/Docs/Docs API/Get Started/How It Works/Anonymous users/index.md +++ b/site/pages/Docs/Docs API/Get Started/How It Works/Anonymous users/index.md @@ -22,13 +22,13 @@ The reference figure and the steps below explain the process of setting a name t 1. Create an *html* file to [Open the document](../Opening%20file/index.md#how-this-can-be-done-in-practice). -2. If the anonymous user’s name is specified, it is displayed on the top toolbar. +2. If the anonymous user's name is specified, it is displayed on the top toolbar. 3. If the user name is not specified, it will be requested. The request can be turned off with the *"request"=false* value of the [editorConfig.customization.anonymous](../../../Usage%20API/Config/Editor/Customization/index.md#anonymous) parameter. ![Name request](/assets/images/editor/name-request.png) -4. After the anonymous user’s name is set, the postfix is added to it via the *label* field of the *editorConfig.customization.anonymous* parameter to distinguish guests during the coediting session. By default this postfix is *"Guest"*. +4. After the anonymous user's name is set, the postfix is added to it via the *label* field of the *editorConfig.customization.anonymous* parameter to distinguish guests during the coediting session. By default this postfix is *"Guest"*. ![Label](/assets/images/editor/label.png) diff --git a/site/pages/Docs/Docs API/Get Started/How It Works/Co-editing/index.md b/site/pages/Docs/Docs API/Get Started/How It Works/Co-editing/index.md index b360545e9..0738ee149 100644 --- a/site/pages/Docs/Docs API/Get Started/How It Works/Co-editing/index.md +++ b/site/pages/Docs/Docs API/Get Started/How It Works/Co-editing/index.md @@ -92,9 +92,9 @@ In order to open a document for editing, the config initialization requires the Therefore, it is important that users have the same key to open the document for co-editing. The **document editing service** identifies the key of another user (or another tab/editing session for [inline editors](../Inline%20editors/index.md)) who is trying to open the document, and if that key matches the key of the file, the user is allowed to open it. If the key is different, then a new file, which is not related to other files and file versions, is opened. -Once the request for saving the file is sent (the *status* value is equal to *2*) and the operation completion is successful (the response value is equal *{"error":0}*), this key can’t be used to open the document for editing. The editor is loaded with an [error message](../../../More%20Information/Troubleshooting/index.md#key). However, it can be used for viewing the document from the cache if it exists. +Once the request for saving the file is sent (the *status* value is equal to *2*) and the operation completion is successful (the response value is equal *{"error":0}*), this key can't be used to open the document for editing. The editor is loaded with an [error message](../../../More%20Information/Troubleshooting/index.md#key). However, it can be used for viewing the document from the cache if it exists. -If the user saves the document before the editing is finished (the *status* value is equal to *6*), the key can’t be changed. Otherwise, the co-editing stops. Please note that after the force saving procedure the key also can’t be changed for the new users who are just entering the current editing session. +If the user saves the document before the editing is finished (the *status* value is equal to *6*), the key can't be changed. Otherwise, the co-editing stops. Please note that after the force saving procedure the key also can't be changed for the new users who are just entering the current editing session. ### Examples diff --git a/site/pages/Docs/Docs API/Get Started/Ready-to-use connectors/SharePoint integration/index.md b/site/pages/Docs/Docs API/Get Started/Ready-to-use connectors/SharePoint integration/index.md index 5915ebdcc..00249a0f8 100644 --- a/site/pages/Docs/Docs API/Get Started/Ready-to-use connectors/SharePoint integration/index.md +++ b/site/pages/Docs/Docs API/Get Started/Ready-to-use connectors/SharePoint integration/index.md @@ -50,7 +50,7 @@ To start using ONLYOFFICE Docs with SharePoint, the following steps must be perf 9. Go back to **Web Application Management** and click the **Anonymous Policy** icon. -10. Under **Anonymous Access Restrictions**, select your **Zone**, set the **Permissions** to *None – No policy* and click **Save**. +10. Under **Anonymous Access Restrictions**, select your **Zone**, set the **Permissions** to *None - No policy* and click **Save**. ## Configuring SharePoint ONLYOFFICE integration solution diff --git a/site/pages/Docs/Docs API/More Information/FAQ/Security/index.md b/site/pages/Docs/Docs API/More Information/FAQ/Security/index.md index 64ad782cc..71cf17717 100644 --- a/site/pages/Docs/Docs API/More Information/FAQ/Security/index.md +++ b/site/pages/Docs/Docs API/More Information/FAQ/Security/index.md @@ -14,7 +14,7 @@ The token can be sent both in the request [header](../../../Additional%20API/Sig ## What's the difference between sending the token in header and in body? -Starting with version 5.2 of ONLYOFFICE Docs it is possible to send token both in the request header and body. The main difference between these two methods is in the length limitation: a HTTP header has length limitation and some servers (such as some NGINX versions) do not accept the requests with the header longer than 4 kilobytes, while other servers restrict the header length to 8–48 kilobytes. In case the header length exceeds these values, the server will return the *413 Entity Too Large* error. +Starting with version 5.2 of ONLYOFFICE Docs it is possible to send token both in the request header and body. The main difference between these two methods is in the length limitation: a HTTP header has length limitation and some servers (such as some NGINX versions) do not accept the requests with the header longer than 4 kilobytes, while other servers restrict the header length to 8-48 kilobytes. In case the header length exceeds these values, the server will return the *413 Entity Too Large* error. To avoid this limitation, sending the token in the request body should be the preferred method of doing this. Starting from version 7.1, the incoming requests use the token in body if it exists. Otherwise, the header token is taken. The outgoing requests use both the token in body and token in header. They can be different. For example, the information about version history can be removed from the header token because of the size limit of the token in header. diff --git a/site/pages/Docs/Docs API/Usage API/Automation API/index.md b/site/pages/Docs/Docs API/Usage API/Automation API/index.md index 4a3fedc72..097b1fd0c 100644 --- a/site/pages/Docs/Docs API/Usage API/Automation API/index.md +++ b/site/pages/Docs/Docs API/Usage API/Automation API/index.md @@ -21,7 +21,7 @@ The connector has the same interface as plugins. Below you can find methods that - [attachEvent](#attachevent) - add an event listener. - [callCommand](#callcommand) - send the data back to the editor. - [connect](#connect) - connect the connector to the editor. -- [createWindow](#createwindow) - create the connector modal window to display the additional information inside the editor. +- [createWindow](#createwindow) - create the connector modal window to display the additional information inside the editor. - [detachEvent](#detachevent) - remove an event listener. - [disconnect](#disconnect) - disconnect the connector from the editor. - [executeMethod](#executemethod) - execute certain editor methods using the connector. @@ -45,7 +45,7 @@ Parameters: | *text* | string | The item caption. | | *data* | string | The item data (this data will be sent to the click event callback). | | *disabled* | boolean | Specifies if the current item is disabled or not. | -| *icons* | string | The item icons (see the plugins [config](../../../Plugin%20and%20Macros/Structure/Manifest/index.md#icons) documentation). | +| *icons* | string | The item icons (see the plugins [config](../../../Plugin%20and%20Macros/Structure/Manifest/index.md#icons) documentation). | | *onClick* | function | The click event callback. | | *items* | Array.\ | An array containing the context menu items for the current item. | @@ -95,7 +95,7 @@ Parameters: | *type* | [ToolbarMenuItemType](#toolbarmenuitemtype) | The item type. | | *text* | string | The item caption. If this field is "", the toolbar button is displayed only with an icon, without a caption. | | *hint* | string | The item hint. | -| *icons* | string | object | The item icons (see the plugins [config](../../../Plugin%20and%20Macros/Structure/Manifest/index.md#variationsicons) documentation). | +| *icons* | string | object | The item icons (see the plugins [config](../../../Plugin%20and%20Macros/Structure/Manifest/index.md#variationsicons) documentation). | | *disabled* | boolean | Specifies whether the current item is locked. | | *enableToggle* | boolean | Specifies whether the toolbar menu item (when *"split == false"*) or its top part (when *"split == true"*) can be toggled. | | *lockInViewMode* | boolean | Specifies whether the toolbar menu item is automatically locked in the view modes (when previewing, viewing forms, disconnecting, etc.). | @@ -204,7 +204,7 @@ connector.connect() ## createWindow -The function called to create the [connector modal window](#connector-window) to display the additional information inside the editor. +The function called to create the [connector modal window](#connector-window) to display the additional information inside the editor. Example: @@ -294,7 +294,7 @@ connector.updateContextMenuItem(items) ## Connector window -Connector window is a class that represents the connector window. To create it, use the [createWindow](#createwindow) method of the connector object. +Connector window is a class that represents the connector window. To create it, use the [createWindow](#createwindow) method of the connector object. Below you can find methods that are available for this class. diff --git a/site/pages/Docs/Docs API/Using WOPI/WOPI REST API/PutFile/index.md b/site/pages/Docs/Docs API/Using WOPI/WOPI REST API/PutFile/index.md index 754f63ee5..7197184eb 100644 --- a/site/pages/Docs/Docs API/Using WOPI/WOPI REST API/PutFile/index.md +++ b/site/pages/Docs/Docs API/Using WOPI/WOPI REST API/PutFile/index.md @@ -1,6 +1,6 @@ `POST /wopi/files/(file_id)/contents` -Updates a file’s binary contents for the `HTTP://server/<...>/wopi*/files//contents` operation. +Updates a file's binary contents for the `HTTP://server/<...>/wopi*/files//contents` operation. This operation works as follows: diff --git a/site/pages/Docs/Document Builder/Builder Framework/Builder framework samples/.Net samples guide/index.md b/site/pages/Docs/Document Builder/Builder Framework/Builder framework samples/.Net samples guide/index.md index b3bf91bf8..1204af234 100644 --- a/site/pages/Docs/Document Builder/Builder Framework/Builder framework samples/.Net samples guide/index.md +++ b/site/pages/Docs/Document Builder/Builder Framework/Builder framework samples/.Net samples guide/index.md @@ -109,9 +109,9 @@ To use `configure.py`, specify the following options: 2. Test samples with `--test TEST`. Some available options: - - `--test all` – generate projects for all samples; - - `--test cs` – generate projects only for C# samples; - - `--test cs/creating_basic_form` – generate only the project for the specified sample. + - `--test all` — generate projects for all samples; + - `--test cs` — generate projects only for C# samples; + - `--test cs/creating_basic_form` — generate only the project for the specified sample. Several test options are available at the same time. To see all available `TEST` options call `configure.py -l`. diff --git a/site/pages/Docs/Document Builder/Builder Framework/Builder framework samples/C++ samples guide/index.md b/site/pages/Docs/Document Builder/Builder Framework/Builder framework samples/C++ samples guide/index.md index 97e143f62..9e5e56415 100644 --- a/site/pages/Docs/Document Builder/Builder Framework/Builder framework samples/C++ samples guide/index.md +++ b/site/pages/Docs/Document Builder/Builder Framework/Builder framework samples/C++ samples guide/index.md @@ -101,9 +101,9 @@ To use `configure.py`, specify the following options: 2. Test samples with `--test TEST`. Some available options: - - `--test all` – generate projects for all samples; - - `--test cpp` – generate projects only for C++ samples; - - `--test cpp/creating_basic_form` – generate only the project for the specified sample. + - `--test all` — generate projects for all samples; + - `--test cpp` — generate projects only for C++ samples; + - `--test cpp/creating_basic_form` — generate only the project for the specified sample. Several test options are available at the same time. To see all available `TEST` options call `configure.py -l`. diff --git a/site/pages/Docs/Document Builder/Builder Framework/Builder framework samples/Python samples guide/index.md b/site/pages/Docs/Document Builder/Builder Framework/Builder framework samples/Python samples guide/index.md index 0bce6ffbe..eb4c30009 100644 --- a/site/pages/Docs/Document Builder/Builder Framework/Builder framework samples/Python samples guide/index.md +++ b/site/pages/Docs/Document Builder/Builder Framework/Builder framework samples/Python samples guide/index.md @@ -98,9 +98,9 @@ To use `configure.py`, specify the following options: 1. Test samples with `--test TEST`. Some available options: - - `--test all` – generate projects for all samples; - - `--test python` – generate projects only for Python samples; - - `--test python/creating_basic_form` – generate only the project for the specified sample. + - `--test all` — generate projects for all samples; + - `--test python` — generate projects only for Python samples; + - `--test python/creating_basic_form` — generate only the project for the specified sample. Several test options are available at the same time. To see all available `TEST` options call `configure.py -l`. diff --git a/site/pages/Docs/Office API/Usage API/Form API/index.md b/site/pages/Docs/Office API/Usage API/Form API/index.md index 46a65ffb6..8bc5b8f31 100644 --- a/site/pages/Docs/Office API/Usage API/Form API/index.md +++ b/site/pages/Docs/Office API/Usage API/Form API/index.md @@ -2,7 +2,7 @@ order: -2 --- -A form document has exactly the same structure as a [text document](../Text%20Document%20API/index.md). The only difference is a new *forms* entity placed with other paragraph elements – text runs, inline text content controls and hyperlinks. There are seven form types: *text field*, *combo box*, *dropdown list*, *checkbox*, *radio button*, *picture form*, and *complex field*. +A form document has exactly the same structure as a [text document](../Text%20Document%20API/index.md). The only difference is a new *forms* entity placed with other paragraph elements - text runs, inline text content controls and hyperlinks. There are seven form types: *text field*, *combo box*, *dropdown list*, *checkbox*, *radio button*, *picture form*, and *complex field*. ## Creating a new form document diff --git a/site/pages/Docs/Plugin and Macros/Customization/Buttons/index.md b/site/pages/Docs/Plugin and Macros/Customization/Buttons/index.md index 2539cd1b9..2f65f9415 100644 --- a/site/pages/Docs/Plugin and Macros/Customization/Buttons/index.md +++ b/site/pages/Docs/Plugin and Macros/Customization/Buttons/index.md @@ -8,7 +8,7 @@ To process [buttons](../../Structure/Manifest/index.md#variationsbuttons) which | Name | Type | Description | | ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| *id* | number | Defines the button index in the [buttons](../../Structure/Manifest/index.md#variationsbuttons) array of the *config.json* file. If *id == -1*, then the plugin considers that the **Close** window cross button has been clicked or its operation has been somehow interrupted. | +| *id* | number | Defines the button index in the [buttons](../../Structure/Manifest/index.md#variationsbuttons) array of the *config.json* file. If *id == -1*, then the plugin considers that the **Close** window cross button has been clicked or its operation has been somehow interrupted. | | *windowId* | number | Defines an index of the button from the modal window. | ## Example diff --git a/site/pages/Docs/Plugin and Macros/Customization/Context menu/index.md b/site/pages/Docs/Plugin and Macros/Customization/Context menu/index.md index b9e486eeb..04b1f8dc7 100644 --- a/site/pages/Docs/Plugin and Macros/Customization/Context menu/index.md +++ b/site/pages/Docs/Plugin and Macros/Customization/Context menu/index.md @@ -92,7 +92,7 @@ The plugin can be accessed via the context menu. | *text* | string | The item caption. | | *data* | string | The item data (this data will be sent to the click event callback). | | *disabled* | boolean | Specifies whether the current item is disabled or not. | - | *icons* | string | The item icons (see the plugins [config](../../Structure/Manifest/index.md) documentation). | + | *icons* | string | The item icons (see the plugins [config](../../Structure/Manifest/index.md) documentation). | | *items* | Array.\ | An array containing the context menu items for the current item. | Example: diff --git a/site/pages/Docs/Plugin and Macros/Customization/Toolbar/index.md b/site/pages/Docs/Plugin and Macros/Customization/Toolbar/index.md index 6ecfe7eea..feaedc5fc 100644 --- a/site/pages/Docs/Plugin and Macros/Customization/Toolbar/index.md +++ b/site/pages/Docs/Plugin and Macros/Customization/Toolbar/index.md @@ -104,7 +104,7 @@ Plugins can be placed on the toolbar: create their own tabs and fill them, add b | *type* | [ToolbarMenuItemType](#toolbarmenuitemtype) | The item type. | | *text* | string | The item caption. If this field is "", the toolbar button is displayed only with an icon, without a caption. | | *hint* | string | The item hint. | - | *icons* | string / object | The item icons (see the plugins [config](../../Structure/Manifest/index.md#variationsicons) documentation). | + | *icons* | string / object | The item icons (see the plugins [config](../../Structure/Manifest/index.md#variationsicons) documentation). | | *disabled* | boolean | Specifies whether the current item is locked. | | *enableToggle* | boolean | Specifies whether the toolbar menu item (when *"split == false"*) or its top part (when *"split == true"*) can be toggled. | | *lockInViewMode* | boolean | Specifies whether the toolbar menu item is automatically locked in the view modes (when previewing, viewing forms, disconnecting, etc.). | diff --git a/site/pages/Docs/Plugin and Macros/Customization/Windows and panels/index.md b/site/pages/Docs/Plugin and Macros/Customization/Windows and panels/index.md index 6fb575300..21820cdaa 100644 --- a/site/pages/Docs/Plugin and Macros/Customization/Windows and panels/index.md +++ b/site/pages/Docs/Plugin and Macros/Customization/Windows and panels/index.md @@ -21,9 +21,9 @@ To create a modal window / panel for the plugin: | Name | Type | Example | Description | | ------------------------ | --------------- | ------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | *variations* | object | | The modal window / panel settings. | - | *variations.url* | string | "settings.html" | The modal window / panel entry point, i.e. an HTML file which connects the *plugin.js* file (the base file needed for work with plugins) and launches the plugin code. See the [index.html](../../Structure/Entry%20point/index.md) section for the detailed information. | + | *variations.url* | string | "settings.html" | The modal window / panel entry point, i.e. an HTML file which connects the *plugin.js* file (the base file needed for work with plugins) and launches the plugin code. See the [index.html](../../Structure/Entry%20point/index.md) section for the detailed information. | | *variations.description* | string | "Description" | The description for the modal window / panel. | - | *variations.type* | string | "window" | The plugin [type](../../Structure/Manifest/index.md#variationstype). Use the **"window"** value for modal windows, **"panel"** for left panels and **"panelRight"** for right panels. | + | *variations.type* | string | "window" | The plugin [type](../../Structure/Manifest/index.md#variationstype). Use the **"window"** value for modal windows, **"panel"** for left panels and **"panelRight"** for right panels. | | *variations.size* | Array.\ | [343, 122] | The modal window size. This parameter is used only for modal windows. | | *variations.buttons* | Array.\