Skip to content

Commit

Permalink
Merge pull request #56 from editor-js/feature/read-only-mode
Browse files Browse the repository at this point in the history
Add read-only mode support
  • Loading branch information
neSpecc authored Sep 29, 2020
2 parents b666a0d + 13a2025 commit 5c1a73a
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 50 deletions.
2 changes: 1 addition & 1 deletion dist/bundle.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@editorjs/table",
"description": "Table for Editor.js",
"version": "1.2.2",
"version": "1.3.0",
"license": "MIT",
"main": "./dist/bundle.js",
"scripts": {
Expand Down
35 changes: 25 additions & 10 deletions src/plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,28 @@ const TableConstructor = require('./tableConstructor').TableConstructor;
const svgIcon = require('./img/toolboxIcon.svg');

const CSS = {
input: 'tc-table__inp'
input: 'tc-table__inp',
};

/**
* Tool for table's creating
*
* @typedef {object} TableData - object with the data transferred to form a table
* @property {string[][]} content - two-dimensional array which contains table content
*/
class Table {
/**
* Notify core that read-only mode is supported
*
* @returns {boolean}
*/
static get isReadOnlySupported() {
return true;
}

/**
* Allow to press Enter inside the CodeTool textarea
*
* @returns {boolean}
* @public
*/
Expand All @@ -25,29 +36,33 @@ class Table {
* icon - Tool icon's SVG
* title - title to show in toolbox
*
* @return {{icon: string, title: string}}
* @returns {{icon: string, title: string}}
*/
static get toolbox() {
return {
icon: svgIcon,
title: 'Table'
title: 'Table',
};
}

/**
* Render plugin`s main Element and fill it with saved data
*
* @param {TableData} data — previously saved data
* @param {object} config - user config for Tool
* @param {object} api - Editor.js API
* @param {boolean} readOnly - read-only mode flag
*/
constructor({data, config, api}) {
constructor({ data, config, api, readOnly }) {
this.api = api;
this.readOnly = readOnly;

this._tableConstructor = new TableConstructor(data, config, api);
this._tableConstructor = new TableConstructor(data, config, api, readOnly);
}

/**
* Return Tool's view
*
* @returns {HTMLDivElement}
* @public
*/
Expand All @@ -57,8 +72,10 @@ class Table {

/**
* Extract Tool's data from the view
*
* @param {HTMLElement} toolsContent - Tool HTML element
*
* @returns {TableData} - saved data
* @public
*/
save(toolsContent) {
const table = toolsContent.querySelector('table');
Expand All @@ -78,16 +95,14 @@ class Table {
}

return {
content: data
content: data,
};
}

/**
* @private
*
* Check input field is empty
* @param {HTMLElement} input - input field
* @return {boolean}
* @returns {boolean}
*/
_isEmpty(input) {
return !input.textContent.trim();
Expand Down
62 changes: 27 additions & 35 deletions src/table.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {create, getCoords, getSideByCoords} from './documentUtils';
import { create, getCoords, getSideByCoords } from './documentUtils';
import './styles/table.pcss';

const CSS = {
Expand All @@ -15,18 +15,24 @@ const CSS = {
export class Table {
/**
* Creates
*
* @param {boolean} readOnly - read-only mode flag
*/
constructor() {
constructor(readOnly) {
this.readOnly = readOnly;
this._numberOfColumns = 0;
this._numberOfRows = 0;
this._element = this._createTableWrapper();
this._table = this._element.querySelector('table');

this._hangEvents();
if (!this.readOnly) {
this._hangEvents();
}
}

/**
* Add column in table on index place
*
* @param {number} index - number in the array of columns, where new column to insert,-1 if insert at the end
*/
addColumn(index = -1) {
Expand All @@ -43,78 +49,75 @@ export class Table {

/**
* Add row in table on index place
*
* @param {number} index - number in the array of columns, where new column to insert,-1 if insert at the end
* @return {HTMLElement} row
* @returns {HTMLElement} row
*/
addRow(index = -1) {
this._numberOfRows++;
const row = this._table.insertRow(index);

this._fillRow(row);

return row;
};

/**
* get html element of table
* @return {HTMLElement}
*
* @returns {HTMLElement}
*/
get htmlElement() {
return this._element;
}

/**
* get real table tag
* @return {HTMLElement}
*
* @returns {HTMLElement}
*/
get body() {
return this._table;
}

/**
* returns selected/editable cell
* @return {HTMLElement}
*
* @returns {HTMLElement}
*/
get selectedCell() {
return this._selectedCell;
}

/**
* @private
*
* Creates table structure
* @return {HTMLElement} tbody - where rows will be
* @returns {HTMLElement} tbody - where rows will be
*/
_createTableWrapper() {
return create('div', [CSS.wrapper], null, [create('table', [CSS.table])]);
return create('div', [ CSS.wrapper ], null, [ create('table', [ CSS.table ]) ]);
}

/**
* @private
*
* Create editable area of cell
* @return {HTMLElement} - the area
* @returns {HTMLElement} - the area
*/
_createContenteditableArea() {
return create('div', [CSS.inputField], {contenteditable: 'true'});
return create('div', [ CSS.inputField ], { contenteditable: !this.readOnly });
}

/**
* @private
*
* Fills the empty cell of the editable area
* @param {HTMLElement} cell - empty cell
*/
_fillCell(cell) {
cell.classList.add(CSS.cell);
const content = this._createContenteditableArea();

cell.appendChild(create('div', [CSS.area], null, [content]));
cell.appendChild(create('div', [ CSS.area ], null, [ content ]));
}

/**
* @private
*
* Fills the empty row with cells in the size of numberOfColumns
* @param row = the empty row
*/
_fillRow(row) {
Expand All @@ -127,8 +130,6 @@ export class Table {

/**
* @private
*
* hang necessary events
*/
_hangEvents() {
this._table.addEventListener('focus', (event) => {
Expand All @@ -155,8 +156,6 @@ export class Table {

/**
* @private
*
* When you focus on an editable field, remembers the cell
* @param {FocusEvent} event
*/
_focusEditField(event) {
Expand All @@ -168,8 +167,6 @@ export class Table {

/**
* @private
*
* When you blur on an editable field, remembers the cell
* @param {FocusEvent} event
*/
_blurEditField(event) {
Expand All @@ -181,8 +178,6 @@ export class Table {

/**
* @private
*
* When enter is pressed when editing a field
* @param {KeyboardEvent} event
*/
_pressedEnterInEditField(event) {
Expand All @@ -196,22 +191,19 @@ export class Table {

/**
* @private
*
* When clicking on a cell
* @param {MouseEvent} event
*/
_clickedOnCell(event) {
if (!event.target.classList.contains(CSS.cell)) {
return;
}
const content = event.target.querySelector('.' + CSS.inputField);

content.focus();
}

/**
* @private
*
* When the mouse enters the detection area
* @param {MouseEvent} event
*/
_mouseEnterInDetectArea(event) {
Expand All @@ -223,10 +215,10 @@ export class Table {
const side = getSideByCoords(coordsCell, event.pageX, event.pageY);

event.target.dispatchEvent(new CustomEvent('mouseInActivatingArea', {
'detail': {
'side': side
detail: {
side: side,
},
'bubbles': true
bubbles: true,
}));
}
}
11 changes: 8 additions & 3 deletions src/tableConstructor.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,13 @@ export class TableConstructor {
* @param {TableData} data - previously saved data for insert in table
* @param {object} config - configuration of table
* @param {object} api - Editor.js API
* @param {boolean} readOnly - read-only mode flag
*/
constructor(data, config, api) {
constructor(data, config, api, readOnly) {
this.readOnly = readOnly;

/** creating table */
this._table = new Table();
this._table = new Table(readOnly);
const size = this._resizeTable(data, config);

this._fillTable(data, size);
Expand All @@ -45,7 +48,9 @@ export class TableConstructor {
this._plusButDelay = null;
this._toolbarShowDelay = null;

this._hangEvents();
if (!this.readOnly) {
this._hangEvents();
}
}

/**
Expand Down

0 comments on commit 5c1a73a

Please sign in to comment.