🚀 Big News: Socket Acquires Coana to Bring Reachability Analysis to Every Appsec Team.Learn more
Socket
DemoInstallSign in
Socket

simple-csv-editor

Package Overview
Dependencies
Maintainers
1
Versions
10
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

simple-csv-editor - npm Package Compare versions

Comparing version

to
1.2.0

2

package.json
{
"name": "simple-csv-editor",
"version": "1.1.0",
"version": "1.2.0",
"description": "A table editor for easily editing and retrieving CSV data.",

@@ -5,0 +5,0 @@ "main": "src/simple-csv-editor.js",

class SimpleCsvEditor {
static controlsClassName = 'controls';
controlDefinitions = new Map([
['addRowBtn', () => { this.addRow(); }],
['addColumnBtn', () => { this.addColumn(); }],
['deleteRowBtn', () => { this.deleteRow(); }],
['deleteColumnBtn', () => { this.deleteColumn(); }],
['clearBtn', () => { this.setCsv(''); }],
]);
constructor({

@@ -18,4 +8,2 @@ id,

quoteChar = '"',
controls = null,
enableDefaultControls = false,
}) {

@@ -33,3 +21,2 @@ if (Papa == null) {

this.#registerControls(controls, enableDefaultControls);
this.table = this.editor.appendChild(document.createElement('table'));

@@ -52,35 +39,95 @@

#registerControls(controlsParam, enableDefaultControls) {
const controlsElement = this.editor.appendChild(document.createElement('div'));
controlsElement.className = SimpleCsvEditor.controlsClassName;
#triggerOnChange() {
if (this.onChange == null) {
return;
}
this.onChange(this.getCsv());
}
const controls = controlsParam ?? (enableDefaultControls
? Array.from(this.controlDefinitions.keys()).map((className) => ({
className,
label: className,
}))
: []);
static #checkCursorPosition(cell) {
const selection = window.getSelection();
if (selection.rangeCount === 0) {
return null;
}
for (const control of controls) {
const newButton = controlsElement.appendChild(document.createElement('button'));
newButton.className = control.className;
newButton.textContent = control.label;
const range = selection.getRangeAt(0);
const startNode = range.startContainer;
const { startOffset } = range;
const endNode = range.endContainer;
const { endOffset } = range;
newButton.addEventListener('click', () => {
this.controlDefinitions.get(newButton.className)();
if (this.onChange != null) {
this.onChange(this.getCsv());
}
});
if (startNode === cell.firstChild && startOffset === 0) {
return 'start';
}
if (endNode === cell.lastChild && endOffset === cell.lastChild.textContent.length) {
return 'end';
}
return 'middle';
}
static #jumpToPositionInCellGeneric(cell, idx) {
if (cell == null) {
return;
}
if (cell.firstChild == null) {
cell.appendChild(document.createTextNode(''));
}
const textNode = cell.firstChild;
const range = document.createRange();
range.setStart(textNode, idx);
range.collapse(true);
const selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(range);
}
static #jumpToStartOfCell(cell) {
this.#jumpToPositionInCellGeneric(cell, 0);
}
static #jumpToEndOfCell(cell) {
this.#jumpToPositionInCellGeneric(cell, cell?.firstChild?.textContent.length);
}
#addCellToRow(row, cellIdx = -1) {
const newCell = row.insertCell(cellIdx);
newCell.contentEditable = true;
if (this.onChange != null) {
newCell.addEventListener('input', () => {
this.onChange(this.getCsv());
});
}
newCell.addEventListener('input', () => {
this.#triggerOnChange();
});
newCell.addEventListener('keydown', (event) => {
const rowIdx = event.target.parentElement.rowIndex;
const { rows } = row.parentElement;
switch (event.key) {
case 'Enter': {
event.preventDefault();
const newRowIdx = (event.shiftKey) ? rowIdx : rowIdx + 1;
this.addRow(newRowIdx);
rows[newRowIdx].cells[newCell.cellIndex].focus();
this.#triggerOnChange();
break;
}
case 'ArrowUp':
event.preventDefault();
SimpleCsvEditor.#jumpToEndOfCell(rows[rowIdx - 1]?.cells[newCell.cellIndex]);
break;
case 'ArrowDown':
event.preventDefault();
SimpleCsvEditor.#jumpToEndOfCell(rows[rowIdx + 1]?.cells[newCell.cellIndex]);
break;
case 'ArrowLeft':
if (SimpleCsvEditor.#checkCursorPosition(newCell) === 'start') {
event.preventDefault();
SimpleCsvEditor.#jumpToEndOfCell(row.cells[newCell.cellIndex - 1]);
}
break;
case 'ArrowRight':
if (SimpleCsvEditor.#checkCursorPosition(newCell) === 'end') {
event.preventDefault();
SimpleCsvEditor.#jumpToStartOfCell(row.cells[newCell.cellIndex + 1]);
}
break;
default: // Do nothing
}
});
}

@@ -124,4 +171,5 @@

addRow(rowIdx = -1) {
const firstRow = (this.table.rows.length > 0) ? this.table.rows[0] : null;
const newRow = this.table.insertRow(rowIdx);
for (let cellIdx = 0; cellIdx < this.table.rows[0].cells.length; cellIdx += 1) {
for (let cellIdx = 0; cellIdx < (firstRow ?? newRow).cells.length; cellIdx += 1) {
this.#addCellToRow(newRow);

@@ -128,0 +176,0 @@ }

Sorry, the diff of this file is not supported yet