Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix the incorrect behavior of the table's row styles #75

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion formats/table/attributors/cell_config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export const cellConfig = {
name: 'cell',
allowedTags: ['TH', 'TD'],
allowedTags: ['TH', 'TD', 'TR'],
};

export const TABLE_CELL_ATTRIBUTES = [
Expand Down
2 changes: 1 addition & 1 deletion modules/clipboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ function matchAlias(format, node, delta) {
}

function matchAttributor(node, delta, scroll) {
if (['TD', 'TH', 'TABLE'].indexOf(node.tagName) === -1) {
if (['TD', 'TH', 'TR', 'TABLE'].indexOf(node.tagName) === -1) {
const attributes = Attributor.keys(node);
const classes = ClassAttributor.keys(node);
const styles = StyleAttributor.keys(node);
Expand Down
25 changes: 20 additions & 5 deletions modules/table/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,18 @@ import {
import isDefined from '../../utils/is_defined';
import { deltaEndsWith, applyFormat } from '../clipboard';
import makeTableArrowHandler from './utils/make_table_arrow_handler';
import prepareAttributeMatcher from './utils/prepare_attr_matcher';
import { TABLE_FORMATS } from '../../formats/table/attributors/table';
import { CELL_FORMATS } from '../../formats/table/attributors/cell';
import {
prepareAttributeMatcher,
prepareCellAttributeMatcher,
} from './utils/prepare_attr_matcher';
import {
TABLE_ATTRIBUTORS,
TABLE_FORMATS,
} from '../../formats/table/attributors/table';
import {
CELL_ATTRIBUTORS,
CELL_FORMATS,
} from '../../formats/table/attributors/cell';

const EMPTY_RESULT = [null, null, null, -1];

Expand Down Expand Up @@ -62,8 +71,14 @@ class Table extends Module {
});

this.quill.clipboard.addMatcher('td, th', matchCell);
this.quill.clipboard.addMatcher('table', prepareAttributeMatcher('table'));
this.quill.clipboard.addMatcher('td, th', prepareAttributeMatcher('cell'));
this.quill.clipboard.addMatcher(
'table',
prepareAttributeMatcher(TABLE_ATTRIBUTORS),
);
this.quill.clipboard.addMatcher(
'td, th',
prepareCellAttributeMatcher(CELL_ATTRIBUTORS),
);
}

addKeyboardHandlers() {
Expand Down
25 changes: 20 additions & 5 deletions modules/table/lite.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,18 @@ import makeTableArrowHandler from './utils/make_table_arrow_handler';
import insertParagraphAbove from './utils/insert_pr_below';
import insertParagraphBelow from './utils/insert_pr_above';
import tableSide from './utils/table_side';
import prepareAttributeMatcher from './utils/prepare_attr_matcher';
import { TABLE_FORMATS } from '../../formats/table/attributors/table';
import { CELL_FORMATS } from '../../formats/table/attributors/cell';
import {
prepareAttributeMatcher,
prepareCellAttributeMatcher,
} from './utils/prepare_attr_matcher';
import {
TABLE_ATTRIBUTORS,
TABLE_FORMATS,
} from '../../formats/table/attributors/table';
import {
CELL_ATTRIBUTORS,
CELL_FORMATS,
} from '../../formats/table/attributors/cell';

const EMPTY_RESULT = [null, null, null, -1];

Expand Down Expand Up @@ -58,8 +67,14 @@ class TableLite extends Module {
this.tableBlots.forEach((blotName) => this.quill.clipboard.addTableBlot(blotName));

this.quill.clipboard.addMatcher('tr', matchTable);
this.quill.clipboard.addMatcher('table', prepareAttributeMatcher('table'));
this.quill.clipboard.addMatcher('td, th', prepareAttributeMatcher('cell'));
this.quill.clipboard.addMatcher(
'table',
prepareAttributeMatcher(TABLE_ATTRIBUTORS),
);
this.quill.clipboard.addMatcher(
'td, th',
prepareCellAttributeMatcher(CELL_ATTRIBUTORS),
);
}

addKeyboardHandlers() {
Expand Down
82 changes: 62 additions & 20 deletions modules/table/utils/prepare_attr_matcher.js
Original file line number Diff line number Diff line change
@@ -1,33 +1,75 @@
import { Scope } from 'parchment';
import OverriddenAttributor from '../../../attributors/attributor';
import OverriddenStyleAttributor from '../../../attributors/style_attributor';
import { CELL_ATTRIBUTORS } from '../../../formats/table/attributors/cell';
import { TABLE_ATTRIBUTORS } from '../../../formats/table/attributors/table';
import { applyFormat } from '../../clipboard';

const ATTRIBUTORS = {
table: TABLE_ATTRIBUTORS,
cell: CELL_ATTRIBUTORS,
};
function writeToRecord(record, key, value, override) {
record[key] = !override && record[key] ? record[key] : value;
}

export default function prepareAttributeMatcher(type) {
const attributors = ATTRIBUTORS[type];
return (node, delta, scroll) => {
const attributes = OverriddenAttributor.keys(node);
const styles = OverriddenStyleAttributor.keys(node);
const formats = {};
attributes.concat(styles).forEach((name) => {
let attr = scroll.query(name, Scope.ATTRIBUTE);
if (attr != null) {
formats[attr.attrName] = attr.value(node);
if (formats[attr.attrName]) return;
function fillFormats(attributes, node, scroll, attributors, result, override) {
attributes
.filter((name) => !!name)
.forEach((name) => {
const queryAttr = scroll.query(name, Scope.ATTRIBUTE);
if (queryAttr !== null) {
const queryAttrValue = queryAttr.value(node);
if (queryAttrValue) {
writeToRecord(result, queryAttr.attrName, queryAttrValue, override);
return;
}
}
attr = attributors[name];

const attr = attributors[name];
if (attr != null && (attr.attrName === name || attr.keyName === name)) {
attr = attributors[name];
formats[attr.attrName] = attr.value(node) || undefined;
const attrValue = attr.value(node) || undefined;
writeToRecord(result, attr.attrName, attrValue, override);
}
});

return result;
}

export function prepareAttributeMatcher(attributors) {
return (node, delta, scroll) => {
const attributes = OverriddenAttributor.keys(node);
const styles = OverriddenStyleAttributor.keys(node);

const formats = {
...fillFormats(attributes, node, scroll, attributors, {}, true),
...fillFormats(styles, node, scroll, attributors, {}, true),
};

if (Object.keys(formats).length > 0) {
return applyFormat(delta, formats);
}
return delta;
};
}

export function prepareCellAttributeMatcher(attributors) {
return (node, delta, scroll) => {
const attributes = OverriddenAttributor.keys(node);
const styles = OverriddenStyleAttributor.keys(node);
const parentTrNode = node.parentNode?.tagName === 'TR' ? node.parentNode : undefined;

let formats = {
...fillFormats(attributes, node, scroll, attributors, {}, true),
...fillFormats(styles, node, scroll, attributors, {}, true),
};

if (parentTrNode) {
const parentStyles = OverriddenStyleAttributor.keys(parentTrNode);
formats = fillFormats(
parentStyles,
parentTrNode,
scroll,
attributors,
formats,
false,
);
}

if (Object.keys(formats).length > 0) {
return applyFormat(delta, formats);
}
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "devextreme-quill",
"version": "1.6.1",
"version": "1.6.2",
"description": "Core of the DevExtreme HtmlEditor",
"author": "Developer Express Inc.",
"main": "dist/dx-quill.js",
Expand Down
Loading