From 27cf8d0310bd6b839b95e90b5a663c7bb300d79c Mon Sep 17 00:00:00 2001 From: abdobargush Date: Wed, 7 Jul 2021 11:26:35 +0200 Subject: [PATCH 1/3] Add support for editing meta data --- README.md | 63 +++++++++++++++---------------- src/index.css | 25 ++++++++----- src/index.js | 101 +++++++++++++++++++++++++++++++++++++------------- 3 files changed, 124 insertions(+), 65 deletions(-) diff --git a/README.md b/README.md index b78a0ff..726410d 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ npm i --save-dev @editorjs/link Include module at your application ```javascript -const LinkTool = require('@editorjs/link'); +const LinkTool = require("@editorjs/link"); ``` ### Download to your project's source dir @@ -67,33 +67,34 @@ const editor = EditorJS({ Link Tool supports these configuration parameters: -| Field | Type | Description | -| ---------|-------------|------------------------------------------------| -| endpoint | `string` | **Required:** the endpoint for link data fetching. | +| Field | Type | Description | +| ------------- | --------- | ---------------------------------------------------------- | +| endpoint | `string` | **Required:** the endpoint for link data fetching. | +| allowMetaEdit | `boolean` | **Optional:** Allow editing meta data after being fetched. | ## Output data This Tool returns `data` with following format -| Field | Type | Description | -| -------------- | --------- | ------------------------------- | -| link | `string` | Pasted link's url | -| meta | `object` | Fetched link's data. Any data got from the backend. Currently, the plugin's design supports the 'title', 'image', and 'description' fields. | +| Field | Type | Description | +| ----- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------- | +| link | `string` | Pasted link's url | +| meta | `object` | Fetched link's data. Any data got from the backend. Currently, the plugin's design supports the 'title', 'image', and 'description' fields. | ```json { - "type" : "linkTool", - "data" : { - "link" : "https://codex.so", - "meta" : { - "title" : "CodeX Team", - "site_name" : "CodeX", - "description" : "Club of web-development, design and marketing. We build team learning how to build full-valued projects on the world market.", - "image" : { - "url" : "https://codex.so/public/app/img/meta_img.png" - } - } + "type": "linkTool", + "data": { + "link": "https://codex.so", + "meta": { + "title": "CodeX Team", + "site_name": "CodeX", + "description": "Club of web-development, design and marketing. We build team learning how to build full-valued projects on the world market.", + "image": { + "url": "https://codex.so/public/app/img/meta_img.png" + } } + } } ``` @@ -106,10 +107,10 @@ Backend response **should** cover following format: ```json5 { - "success" : 1, - "meta": { - // ... any fields you want - } + "success": 1, + "meta": { + // ... any fields you want + }, } ``` @@ -121,14 +122,14 @@ Currently, the plugin's design supports the 'title', 'image', and 'description' ```json5 { - "success" : 1, - "meta": { - "title" : "CodeX Team", - "description" : "Club of web-development, design and marketing. We build team learning how to build full-valued projects on the world market.", - "image" : { - "url" : "https://codex.so/public/app/img/meta_img.png" - } - } + "success": 1, + "meta": { + "title": "CodeX Team", + "description": "Club of web-development, design and marketing. We build team learning how to build full-valued projects on the world market.", + "image": { + "url": "https://codex.so/public/app/img/meta_img.png", + }, + }, } ``` diff --git a/src/index.css b/src/index.css index e066e10..3fc1f78 100644 --- a/src/index.css +++ b/src/index.css @@ -19,28 +19,35 @@ background-color: #fff3f6; border-color: #f3e0e0; color: #a95a5a; - box-shadow: inset 0 1px 3px 0 rgba(146, 62, 62, .05); + box-shadow: inset 0 1px 3px 0 rgba(146, 62, 62, 0.05); } } } + } + + [contentEditable="true"] { + &:focus { + outline: none; + } - &[contentEditable=true][data-placeholder]::before{ + &[data-placeholder]::before { position: absolute; content: attr(data-placeholder); color: #707684; font-weight: normal; opacity: 0; + cursor: text; + pointer-events: none; } - &[contentEditable=true][data-placeholder]:empty { - + &[data-placeholder]:empty { &::before { opacity: 1; } &:focus::before { - opacity: 0; - } + opacity: 0; + } } } @@ -79,13 +86,13 @@ &--rendered { background: #fff; border: 1px solid rgba(201, 201, 204, 0.48); - box-shadow: 0 1px 3px rgba(0,0,0, .1); + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); border-radius: 6px; will-change: filter; animation: link-in 450ms 1 cubic-bezier(0.215, 0.61, 0.355, 1); &:hover { - box-shadow: 0 0 3px rgba(0,0,0, .16); + box-shadow: 0 0 3px rgba(0, 0, 0, 0.16); } } } @@ -123,7 +130,7 @@ } &__anchor { - display: block; + display: inline-block; font-size: 15px; line-height: 1em; color: #888 !important; diff --git a/src/index.js b/src/index.js index 16bbb03..c55fae0 100644 --- a/src/index.js +++ b/src/index.js @@ -14,11 +14,11 @@ */ // eslint-disable-next-line -import css from './index.css'; +import css from "./index.css"; import ToolboxIcon from './svg/toolbox.svg'; import ajax from '@codexteam/ajax'; // eslint-disable-next-line -import polyfill from 'url-polyfill'; +import polyfill from "url-polyfill"; /** * @typedef {object} UploadResponseFormat @@ -60,7 +60,7 @@ export default class LinkTool { * @public */ static get enableLineBreaks() { - return true; + return false; } /** @@ -72,12 +72,14 @@ export default class LinkTool { constructor({ data, config, api, readOnly }) { this.api = api; this.readOnly = readOnly; + this.isDataSet = false; /** * Tool's initial config */ this.config = { endpoint: config.endpoint || '', + allowMetaEdit: config.allowMetaEdit || false, }; this.nodes = { @@ -138,6 +140,11 @@ export default class LinkTool { * @returns {LinkToolData} */ save() { + if (this.config.allowMetaEdit && this.isDataSet) { + this.data.meta.title = this.nodes.linkTitle.innerHTML; + this.data.meta.description = this.nodes.linkDescription.innerHTML; + } + return this.data; } @@ -159,10 +166,13 @@ export default class LinkTool { * @param {LinkToolData} data */ set data(data) { - this._data = Object.assign({}, { - link: data.link || this._data.link, - meta: data.meta || this._data.meta, - }); + this._data = Object.assign( + {}, + { + link: data.link || this._data.link, + meta: data.meta || this._data.meta, + } + ); } /** @@ -299,15 +309,40 @@ export default class LinkTool { * @returns {HTMLElement} */ prepareLinkPreview() { - const holder = this.make('a', this.CSS.linkContent, { - target: '_blank', - rel: 'nofollow noindex noreferrer', - }); + let holder = null; + + // if edit meta is allowed add as dev + if (this.config.allowMetaEdit) { + holder = this.make('div', this.CSS.linkContent); + } else { + // add as link + holder = this.make('a', this.CSS.linkContent, { + target: '_blank', + rel: 'nofollow noindex noreferrer', + }); + } this.nodes.linkImage = this.make('div', this.CSS.linkImage); - this.nodes.linkTitle = this.make('div', this.CSS.linkTitle); - this.nodes.linkDescription = this.make('p', this.CSS.linkDescription); - this.nodes.linkText = this.make('span', this.CSS.linkText); + this.nodes.linkTitle = this.make('div', this.CSS.linkTitle, { + contentEditable: this.config.allowMetaEdit, + }); + this.nodes.linkDescription = this.make('p', this.CSS.linkDescription, { + contentEditable: this.config.allowMetaEdit, + }); + + // if edit meta is allowed add as link + if (this.config.allowMetaEdit) { + this.nodes.linkText = this.make('a', this.CSS.linkText, { + target: '_blank', + rel: 'nofollow noindex noreferrer', + }); + } else { + // add as span + this.nodes.linkText = this.make('span', this.CSS.linkText); + } + + // Mark as data is set + this.isDataSet = true; return holder; } @@ -325,22 +360,34 @@ export default class LinkTool { this.nodes.linkContent.appendChild(this.nodes.linkImage); } - if (title) { - this.nodes.linkTitle.textContent = title; + if (title || this.config.allowMetaEdit) { + this.nodes.linkTitle.innerHTML = title; + this.nodes.linkTitle.dataset.placeholder = + this.api.i18n.t('Enter link title'); this.nodes.linkContent.appendChild(this.nodes.linkTitle); } - if (description) { - this.nodes.linkDescription.textContent = description; + if (description || this.config.allowMetaEdit) { + this.nodes.linkDescription.innerHTML = description; + this.nodes.linkDescription.dataset.placeholder = this.api.i18n.t( + 'Enter link description' + ); this.nodes.linkContent.appendChild(this.nodes.linkDescription); } this.nodes.linkContent.classList.add(this.CSS.linkContentRendered); - this.nodes.linkContent.setAttribute('href', this.data.link); + // if edit meta is not allowed add href to link content holder + if (!this.allowMetaEdit) { + this.nodes.linkContent.setAttribute('href', this.data.link); + } this.nodes.linkContent.appendChild(this.nodes.linkText); + // if edit meta is allowed add href to link text + if (this.config.allowMetaEdit) { + this.nodes.linkText.setAttribute('href', this.data.link); + } try { - this.nodes.linkText.textContent = (new URL(this.data.link)).hostname; + this.nodes.linkText.textContent = new URL(this.data.link).hostname; } catch (e) { this.nodes.linkText.textContent = this.data.link; } @@ -383,16 +430,16 @@ export default class LinkTool { this.data = { link: url }; try { - const { body } = await (ajax.get({ + const { body } = await ajax.get({ url: this.config.endpoint, data: { url, }, - })); + }); this.onFetch(body); } catch (error) { - this.fetchingFailed(this.api.i18n.t('Couldn\'t fetch the link data')); + this.fetchingFailed(this.api.i18n.t("Couldn't fetch the link data")); } } @@ -403,7 +450,9 @@ export default class LinkTool { */ onFetch(response) { if (!response || !response.success) { - this.fetchingFailed(this.api.i18n.t('Couldn\'t get this link data, try the other one')); + this.fetchingFailed( + this.api.i18n.t("Couldn't get this link data, try the other one") + ); return; } @@ -413,7 +462,9 @@ export default class LinkTool { this.data = { meta: metaData }; if (!metaData) { - this.fetchingFailed(this.api.i18n.t('Wrong response format from the server')); + this.fetchingFailed( + this.api.i18n.t('Wrong response format from the server') + ); return; } From e95f159aadbeb7008dc30a7e9426c7a5bfb4e797 Mon Sep 17 00:00:00 2001 From: abdobargush Date: Sat, 7 Aug 2021 12:18:07 +0200 Subject: [PATCH 2/3] Fix by moving isDataSet to showLinkPreview() --- src/index.js | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/src/index.js b/src/index.js index c55fae0..9d4ea04 100644 --- a/src/index.js +++ b/src/index.js @@ -341,9 +341,6 @@ export default class LinkTool { this.nodes.linkText = this.make('span', this.CSS.linkText); } - // Mark as data is set - this.isDataSet = true; - return holder; } @@ -362,16 +359,13 @@ export default class LinkTool { if (title || this.config.allowMetaEdit) { this.nodes.linkTitle.innerHTML = title; - this.nodes.linkTitle.dataset.placeholder = - this.api.i18n.t('Enter link title'); + this.nodes.linkTitle.dataset.placeholder = this.api.i18n.t('Enter link title'); this.nodes.linkContent.appendChild(this.nodes.linkTitle); } if (description || this.config.allowMetaEdit) { this.nodes.linkDescription.innerHTML = description; - this.nodes.linkDescription.dataset.placeholder = this.api.i18n.t( - 'Enter link description' - ); + this.nodes.linkDescription.dataset.placeholder = this.api.i18n.t('Enter link description'); this.nodes.linkContent.appendChild(this.nodes.linkDescription); } @@ -391,6 +385,9 @@ export default class LinkTool { } catch (e) { this.nodes.linkText.textContent = this.data.link; } + + // Mark as data is set + this.isDataSet = true; } /** @@ -450,9 +447,7 @@ export default class LinkTool { */ onFetch(response) { if (!response || !response.success) { - this.fetchingFailed( - this.api.i18n.t("Couldn't get this link data, try the other one") - ); + this.fetchingFailed(this.api.i18n.t("Couldn't get this link data, try the other one")); return; } @@ -462,9 +457,7 @@ export default class LinkTool { this.data = { meta: metaData }; if (!metaData) { - this.fetchingFailed( - this.api.i18n.t('Wrong response format from the server') - ); + this.fetchingFailed(this.api.i18n.t('Wrong response format from the server')); return; } From 3feed0956954b9ae1eb76ec122dd341c7128b597 Mon Sep 17 00:00:00 2001 From: abdobargush Date: Mon, 24 Oct 2022 20:47:25 +0200 Subject: [PATCH 3/3] Format with eslint --- .editorconfig | 7 +++ .eslintrc | 12 ++-- README.md | 38 ++++++++----- package.json | 6 +- src/index.js | 151 +++++++++++++++++++++++++++----------------------- 5 files changed, 122 insertions(+), 92 deletions(-) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..eccd72a --- /dev/null +++ b/.editorconfig @@ -0,0 +1,7 @@ +[*] +charset = utf-8 +indent_style = space +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true +indent_size = 2 diff --git a/.eslintrc b/.eslintrc index 39927bf..96321a3 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,13 +1,13 @@ { + "root": true, "extends": [ "codex" ], - "settings": { - "jsdoc": { - "mode": "javascript" - } - }, "globals": { - "Range" : true + "Range" : true, + "HTMLDivElement": true, + "HTMLElement": true, + "KeyboardEvent": true, + "PasteEvent": true } } diff --git a/README.md b/README.md index 5f945db..4fa805f 100644 --- a/README.md +++ b/README.md @@ -106,13 +106,13 @@ environment and stack. Backend response **should** cover following format: -```json +```json5 { - "success": 1, - "link": "https://codex.so", // Optionally return a link to set the hyperlink URL - "meta": { + success: 1, + link: "https://codex.so", // Optionally return a link to set the hyperlink URL + meta: { // ... any fields you want - } + }, } ``` @@ -124,17 +124,27 @@ Backend response **should** cover following format: Currently, the plugin's design supports the 'title', 'image', and 'description' fields. They should have the following format in the response: -```json +```json5 { - "success": 1, - "meta": { - "title": "CodeX Team", - "description": "Club of web-development, design and marketing. We build team learning how to build full-valued projects on the world market.", - "image": { - "url": "https://codex.so/public/app/img/meta_img.png" - } - } + success: 1, + meta: { + title: "CodeX Team", + description: "Club of web-development, design and marketing. We build team learning how to build full-valued projects on the world market.", + image: { + url: "https://codex.so/public/app/img/meta_img.png", + }, + }, } ``` Also, it can contain any additional fields you want to store. + +# About CodeX + + + +CodeX is a team of digital specialists around the world interested in building high-quality open source products on a global market. We are [open](https://codex.so/join) for young people who want to constantly improve their skills and grow professionally with experiments in cutting-edge technologies. + +| 🌐 | Join 👋 | Twitter | Instagram | +| ---------------------------- | -------------------------------------- | -------------------------------------------- | ----------------------------------------------- | +| [codex.so](https://codex.so) | [codex.so/join](https://codex.so/join) | [@codex_team](http://twitter.com/codex_team) | [@codex_team](http://instagram.com/codex_team/) | diff --git a/package.json b/package.json index cfe481a..b6fe00a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@editorjs/link", - "version": "2.4.1", + "version": "2.4.2", "keywords": [ "codex editor", "tool", @@ -17,7 +17,9 @@ "main": "./dist/bundle.js", "scripts": { "build": "webpack --mode production", - "build:dev": "webpack --mode development --watch" + "build:dev": "webpack --mode development --watch", + "lint": "eslint src/", + "lint:fix": "eslint src/ --fix" }, "author": "CodeX ", "devDependencies": { diff --git a/src/index.js b/src/index.js index 1f574a9..4c3cef4 100644 --- a/src/index.js +++ b/src/index.js @@ -13,12 +13,17 @@ * @property {string} description - link's description */ -// eslint-disable-next-line -import css from "./index.css"; -import ToolboxIcon from "./svg/toolbox.svg"; -import ajax from "@codexteam/ajax"; -// eslint-disable-next-line -import polyfill from "url-polyfill"; +/** + * @typedef {object} LinkToolConfig + * @property {string} endpoint - the endpoint for link data fetching + * @property {object} headers - the headers used in the GET request + * @property {boolean} allowMetaEdit - allow editing meta data after being fetched. + */ + +import './index.css'; +import 'url-polyfill'; +import ToolboxIcon from './svg/toolbox.svg'; +import ajax from '@codexteam/ajax'; /** * @typedef {object} UploadResponseFormat @@ -49,7 +54,7 @@ export default class LinkTool { static get toolbox() { return { icon: ToolboxIcon, - title: "Link", + title: 'Link', }; } @@ -64,10 +69,11 @@ export default class LinkTool { } /** - * @param {LinkToolData} data - previously saved data - * @param {config} config - user config for Tool - * @param {object} api - Editor.js API - * @param {boolean} readOnly - read-only mode flag + * @param {object} options - Tool constructor options fot from Editor.js + * @param {LinkToolData} options.data - previously saved data + * @param {LinkToolConfig} options.config - user config for Tool + * @param {object} options.api - Editor.js API + * @param {boolean} options.readOnly - read-only mode flag */ constructor({ data, config, api, readOnly }) { this.api = api; @@ -78,7 +84,7 @@ export default class LinkTool { * Tool's initial config */ this.config = { - endpoint: config.endpoint || "", + endpoint: config.endpoint || '', allowMetaEdit: config.allowMetaEdit || false, headers: config.headers || {}, }; @@ -97,7 +103,7 @@ export default class LinkTool { }; this._data = { - link: "", + link: '', meta: {}, }; @@ -108,12 +114,11 @@ export default class LinkTool { * Renders Block content * * @public - * * @returns {HTMLDivElement} */ render() { - this.nodes.wrapper = this.make("div", this.CSS.baseClass); - this.nodes.container = this.make("div", this.CSS.container); + this.nodes.wrapper = this.make('div', this.CSS.baseClass); + this.nodes.container = this.make('div', this.CSS.container); this.nodes.inputHolder = this.makeInputHolder(); this.nodes.linkContent = this.prepareLinkPreview(); @@ -137,7 +142,6 @@ export default class LinkTool { * Return Block data * * @public - * * @returns {LinkToolData} */ save() { @@ -154,17 +158,16 @@ export default class LinkTool { * - check if given link is an empty string or not. * * @public - * * @returns {boolean} false if saved data is incorrect, otherwise true */ validate() { - return this.data.link.trim() !== ""; + return this.data.link.trim() !== ''; } /** * Stores all Tool's data * - * @param {LinkToolData} data + * @param {LinkToolData} data - data to store */ set data(data) { this._data = Object.assign( @@ -196,19 +199,19 @@ export default class LinkTool { /** * Tool's classes */ - container: "link-tool", - inputEl: "link-tool__input", - inputHolder: "link-tool__input-holder", - inputError: "link-tool__input-holder--error", - linkContent: "link-tool__content", - linkContentRendered: "link-tool__content--rendered", - linkImage: "link-tool__image", - linkTitle: "link-tool__title", - linkDescription: "link-tool__description", - linkText: "link-tool__anchor", - progress: "link-tool__progress", - progressLoading: "link-tool__progress--loading", - progressLoaded: "link-tool__progress--loaded", + container: 'link-tool', + inputEl: 'link-tool__input', + inputHolder: 'link-tool__input-holder', + inputError: 'link-tool__input-holder--error', + linkContent: 'link-tool__content', + linkContentRendered: 'link-tool__content--rendered', + linkImage: 'link-tool__image', + linkTitle: 'link-tool__title', + linkDescription: 'link-tool__description', + linkText: 'link-tool__anchor', + progress: 'link-tool__progress', + progressLoading: 'link-tool__progress--loading', + progressLoaded: 'link-tool__progress--loaded', }; } @@ -218,21 +221,21 @@ export default class LinkTool { * @returns {HTMLElement} */ makeInputHolder() { - const inputHolder = this.make("div", this.CSS.inputHolder); + const inputHolder = this.make('div', this.CSS.inputHolder); - this.nodes.progress = this.make("label", this.CSS.progress); - this.nodes.input = this.make("div", [this.CSS.input, this.CSS.inputEl], { + this.nodes.progress = this.make('label', this.CSS.progress); + this.nodes.input = this.make('div', [this.CSS.input, this.CSS.inputEl], { contentEditable: !this.readOnly, }); - this.nodes.input.dataset.placeholder = this.api.i18n.t("Link"); + this.nodes.input.dataset.placeholder = this.api.i18n.t('Link'); if (!this.readOnly) { - this.nodes.input.addEventListener("paste", (event) => { + this.nodes.input.addEventListener('paste', (event) => { this.startFetching(event); }); - this.nodes.input.addEventListener("keydown", (event) => { + this.nodes.input.addEventListener('keydown', (event) => { const [ENTER, A] = [13, 65]; const cmdPressed = event.ctrlKey || event.metaKey; @@ -261,13 +264,13 @@ export default class LinkTool { /** * Activates link data fetching by url * - * @param {PasteEvent} event + * @param {PasteEvent|KeyboardEvent} event - fetching could be fired by a pase or keydown events */ startFetching(event) { let url = this.nodes.input.textContent; - if (event.type === "paste") { - url = (event.clipboardData || window.clipboardData).getData("text"); + if (event.type === 'paste') { + url = (event.clipboardData || window.clipboardData).getData('text'); } this.removeErrorStyle(); @@ -285,7 +288,7 @@ export default class LinkTool { /** * Select LinkTool input content by CMD+A * - * @param {KeyboardEvent} event + * @param {KeyboardEvent} event - keydown */ selectLinkUrl(event) { event.preventDefault(); @@ -314,32 +317,32 @@ export default class LinkTool { // if edit meta is allowed add as dev if (this.config.allowMetaEdit) { - holder = this.make("div", this.CSS.linkContent); + holder = this.make('div', this.CSS.linkContent); } else { // add as link - holder = this.make("a", this.CSS.linkContent, { - target: "_blank", - rel: "nofollow noindex noreferrer", + holder = this.make('a', this.CSS.linkContent, { + target: '_blank', + rel: 'nofollow noindex noreferrer', }); } - this.nodes.linkImage = this.make("div", this.CSS.linkImage); - this.nodes.linkTitle = this.make("div", this.CSS.linkTitle, { + this.nodes.linkImage = this.make('div', this.CSS.linkImage); + this.nodes.linkTitle = this.make('div', this.CSS.linkTitle, { contentEditable: this.config.allowMetaEdit, }); - this.nodes.linkDescription = this.make("p", this.CSS.linkDescription, { + this.nodes.linkDescription = this.make('p', this.CSS.linkDescription, { contentEditable: this.config.allowMetaEdit, }); // if edit meta is allowed add as link if (this.config.allowMetaEdit) { - this.nodes.linkText = this.make("a", this.CSS.linkText, { - target: "_blank", - rel: "nofollow noindex noreferrer", + this.nodes.linkText = this.make('a', this.CSS.linkText, { + target: '_blank', + rel: 'nofollow noindex noreferrer', }); } else { // add as span - this.nodes.linkText = this.make("span", this.CSS.linkText); + this.nodes.linkText = this.make('span', this.CSS.linkText); } return holder; @@ -354,32 +357,35 @@ export default class LinkTool { this.nodes.container.appendChild(this.nodes.linkContent); if (image && image.url) { - this.nodes.linkImage.style.backgroundImage = "url(" + image.url + ")"; + this.nodes.linkImage.style.backgroundImage = 'url(' + image.url + ')'; this.nodes.linkContent.appendChild(this.nodes.linkImage); } if (title || this.config.allowMetaEdit) { this.nodes.linkTitle.innerHTML = title; - this.nodes.linkTitle.dataset.placeholder = this.api.i18n.t("Enter link title"); + this.nodes.linkTitle.dataset.placeholder = + this.api.i18n.t('Enter link title'); this.nodes.linkContent.appendChild(this.nodes.linkTitle); } if (description || this.config.allowMetaEdit) { this.nodes.linkDescription.innerHTML = description; - this.nodes.linkDescription.dataset.placeholder = this.api.i18n.t("Enter link description"); + this.nodes.linkDescription.dataset.placeholder = this.api.i18n.t( + 'Enter link description' + ); this.nodes.linkContent.appendChild(this.nodes.linkDescription); } this.nodes.linkContent.classList.add(this.CSS.linkContentRendered); // if edit meta is not allowed add href to link content holder if (!this.allowMetaEdit) { - this.nodes.linkContent.setAttribute("href", this.data.link); + this.nodes.linkContent.setAttribute('href', this.data.link); } this.nodes.linkContent.appendChild(this.nodes.linkText); // if edit meta is allowed add href to link text if (this.config.allowMetaEdit) { - this.nodes.linkText.setAttribute("href", this.data.link); + this.nodes.linkText.setAttribute('href', this.data.link); } try { this.nodes.linkText.textContent = new URL(this.data.link).hostname; @@ -392,14 +398,16 @@ export default class LinkTool { } /** - * Show loading progressbar + * Show loading progress bar */ showProgress() { this.nodes.progress.classList.add(this.CSS.progressLoading); } /** - * Hide loading progressbar + * Hide loading progress bar + * + * @returns {Promise} */ hideProgress() { return new Promise((resolve) => { @@ -445,11 +453,13 @@ export default class LinkTool { /** * Link data fetching callback * - * @param {UploadResponseFormat} response + * @param {UploadResponseFormat} response - backend response */ onFetch(response) { if (!response || !response.success) { - this.fetchingFailed(this.api.i18n.t("Couldn't get this link data, try the other one")); + this.fetchingFailed( + this.api.i18n.t("Couldn't get this link data, try the other one") + ); return; } @@ -464,7 +474,9 @@ export default class LinkTool { }; if (!metaData) { - this.fetchingFailed(this.api.i18n.t("Wrong response format from the server")); + this.fetchingFailed( + this.api.i18n.t('Wrong response format from the server') + ); return; } @@ -479,13 +491,12 @@ export default class LinkTool { * Handle link fetching errors * * @private - * - * @param {string} errorMessage + * @param {string} errorMessage - message to explain user what he should do */ fetchingFailed(errorMessage) { this.api.notifier.show({ message: errorMessage, - style: "error", + style: 'error', }); this.applyErrorStyle(); @@ -494,9 +505,9 @@ export default class LinkTool { /** * Helper method for elements creation * - * @param tagName - * @param classNames - * @param attributes + * @param {string} tagName - name of creating element + * @param {string|string[]} [classNames] - list of CSS classes to add + * @param {object} [attributes] - object with attributes to add * @returns {HTMLElement} */ make(tagName, classNames = null, attributes = {}) {