@modusoperandi/licit-capco 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CapcoPlugin.d.ts CHANGED
@@ -1,3 +1,7 @@
1
+ /**
2
+ * @license MIT
3
+ * @copyright Copyright 2025 Modus Operandi Inc. All Rights Reserved.
4
+ */
1
5
  import { Schema, Slice, ResolvedPos, Node, Attrs, Node as PMNode } from 'prosemirror-model';
2
6
  import { EditorState, Plugin, Transaction } from 'prosemirror-state';
3
7
  import { CAPCOMODE } from './editorSchema';
@@ -35,7 +39,7 @@ export declare class CapcoPlugin extends Plugin<CapcoPluginState> {
35
39
  getPendingTransactions(transactions: readonly Transaction[], _oldState: EditorState, newState: EditorState): Transaction;
36
40
  getDecorations(state: any): DecorationSet;
37
41
  private addBlockDecoratoration;
38
- enhancedTableFigureCapco(capco: string): string;
42
+ enhancedTableFigureCapco(capco: string, isFigureBlock: boolean): string;
39
43
  handleOnEnter(view: EditorView, _event: KeyboardEvent): boolean;
40
44
  getCursorPosition(e: MouseEvent): {
41
45
  x: number;
package/CapcoPlugin.js CHANGED
@@ -1,3 +1,7 @@
1
+ /**
2
+ * @license MIT
3
+ * @copyright Copyright 2025 Modus Operandi Inc. All Rights Reserved.
4
+ */
1
5
  import { Plugin } from 'prosemirror-state';
2
6
  import { CAPCOMODE, effectiveSchema, SYSTEMCAPCO } from './editorSchema';
3
7
  import { CAPCOKEY, CAPCOMODEKEY, CAPCOMODESTEPKEY, CAPCO_PLUGIN_KEY, PARAGRAPH, TABLE, TABLE_FIGURE, TABLE_FIGURE_CAPCO, } from './constants';
@@ -147,7 +151,7 @@ export class CapcoPlugin extends Plugin {
147
151
  : tr;
148
152
  }
149
153
  processCapcoMode(trx, state) {
150
- if (undefined !== this.mode && state.doc.attrs[CAPCOMODEKEY] != this.mode) {
154
+ if (undefined !== this.mode && undefined !== state.doc.attrs[CAPCOMODEKEY] && state.doc.attrs[CAPCOMODEKEY] != this.mode) {
151
155
  const docAttrStep = new SetDocAttrStep(CAPCOMODESTEPKEY, this.mode, 'SetDocAttr');
152
156
  trx = trx.step(docAttrStep);
153
157
  }
@@ -240,14 +244,14 @@ export class CapcoPlugin extends Plugin {
240
244
  decorations.push(Decoration.widget(node.nodeSize + pos, needValidate, { side: 1 }));
241
245
  }
242
246
  }
243
- enhancedTableFigureCapco(capco) {
247
+ enhancedTableFigureCapco(capco, isFigureBlock) {
244
248
  const capcoString = {
245
- TBD: 'To be Determined',
249
+ TBD: isFigureBlock ? 'TBD' : 'To be Determined',
246
250
  U: 'Unclassified',
247
- C: 'Confidential',
248
- S: 'Secret',
249
- TS: 'Top Secret',
250
- CUI: 'Controlled Unclassified Information',
251
+ C: isFigureBlock ? 'C' : 'Confidential',
252
+ S: isFigureBlock ? 'S' : 'Secret',
253
+ TS: isFigureBlock ? 'TS' : 'Top Secret',
254
+ CUI: isFigureBlock ? 'CUI' : 'Controlled Unclassified Information',
251
255
  };
252
256
  return capcoString[capco] || capco;
253
257
  }
@@ -262,7 +266,7 @@ export class CapcoPlugin extends Plugin {
262
266
  const node = view.state.doc.nodeAt(pos);
263
267
  // Default CAPCO value based on CAPCO mode
264
268
  let capco = SYSTEMCAPCO.TBD;
265
- if (parseInt(view.state.doc.attrs[CAPCOMODEKEY]) ===
269
+ if (Number.parseInt(view.state.doc.attrs[CAPCOMODEKEY]) ===
266
270
  CAPCOMODE.FORCED.valueOf()) {
267
271
  capco = node.attrs.capco;
268
272
  }
@@ -370,8 +374,8 @@ export class CapcoPlugin extends Plugin {
370
374
  const pmLeft = pm?.getBoundingClientRect()?.left ?? 0;
371
375
  // CAPCO mouse tool displayed on left portion of para that is same width as CAPCO
372
376
  // Get line height from computed styles
373
- const computedStyles = window.getComputedStyle(pm);
374
- const lineHeight = parseFloat(computedStyles.lineHeight) || 20; // Default to 20px if unavailable
377
+ const computedStyles = globalThis.getComputedStyle(pm);
378
+ const lineHeight = Number.parseFloat(computedStyles.lineHeight) || 20; // Default to 20px if unavailable
375
379
  // Check if the mouse is within the first line of the paragraph
376
380
  const isFirstLine = e.clientY >= startCoords.top && e.clientY <= startCoords.top + lineHeight;
377
381
  if (isFirstLine &&
@@ -451,7 +455,7 @@ export class CapcoPlugin extends Plugin {
451
455
  getCapcoFromSlice(view, slice) {
452
456
  let capco = null;
453
457
  if (CAPCOMODE.NONE.valueOf() !==
454
- parseInt(view.state.doc.attrs[CAPCOMODEKEY]) &&
458
+ Number.parseInt(view.state.doc.attrs[CAPCOMODEKEY]) &&
455
459
  slice.content?.childCount !== 0) {
456
460
  // Copy full paragraph, the pasted paragraph shall have same CAPCO.
457
461
  // target line is in length - 3 always.
@@ -531,19 +535,26 @@ export class CapcoPlugin extends Plugin {
531
535
  const capcoColors = {
532
536
  UNCLASSIFIED: '#006E3A', // green
533
537
  CONFIDENTIAL: '#0000FF', // blue
538
+ C: '#0000FF', // blue
534
539
  'CONTROLLED UNCLASSIFIED INFORMATION': '#990099', // purple
540
+ CUI: '#990099', // purple
535
541
  SECRET: '#FF0000', // red
542
+ S: '#FF0000', // red
536
543
  'TOP SECRET': '#FFC20E', // yellow-orange
544
+ TS: '#FFC20E', // yellow-orange
537
545
  'TO BE DETERMINED': '#454545', // dark gray
546
+ TBD: '#454545', // dark gray
538
547
  };
539
- switch (parseInt(state.doc.attrs[CAPCOMODEKEY])) {
548
+ switch (Number.parseInt(state.doc.attrs[CAPCOMODEKEY])) {
540
549
  case CAPCOMODE.FORCED.valueOf(): {
541
550
  let capcoText = '';
551
+ const parentNode = state.doc.resolve(pos);
542
552
  if ([TABLE_FIGURE_CAPCO, TABLE_FIGURE].includes(nodeType)) {
543
553
  capco = state.doc.nodeAt(getBlockControlCapco(state, pos))?.attrs
544
554
  ?.capco;
555
+ const isFigureBlock = parentNode.parent.type.name === TABLE_FIGURE && parentNode.parent.attrs.figureType === 'figure';
545
556
  capcoText = getCapcoString(capco, this.defaultCapco);
546
- capcoText = this.enhancedTableFigureCapco(capcoText);
557
+ capcoText = this.enhancedTableFigureCapco(capcoText, isFigureBlock);
547
558
  capcoMark.textContent = capcoText;
548
559
  capcoMark.style.color = '#6A5ACD';
549
560
  }
@@ -552,7 +563,7 @@ export class CapcoPlugin extends Plugin {
552
563
  capcoMark.textContent = '(' + capcoText + ') ';
553
564
  }
554
565
  const colorKey = capcoText?.replace(/[()]/g, '').trim().toUpperCase();
555
- if (capcoColors[colorKey]) {
566
+ if (parentNode.parent.type.name === TABLE_FIGURE && capcoColors[colorKey]) {
556
567
  capcoMark.style.color = capcoColors[colorKey];
557
568
  capcoMark.style.textTransform = 'uppercase';
558
569
  }
@@ -569,7 +580,7 @@ export class CapcoPlugin extends Plugin {
569
580
  value = NONE;
570
581
  }
571
582
  else {
572
- switch (parseInt(state.doc.attrs[CAPCOMODEKEY])) {
583
+ switch (Number.parseInt(state.doc.attrs[CAPCOMODEKEY])) {
573
584
  case CAPCOMODE.NONE.valueOf():
574
585
  value = NONE;
575
586
  break;
@@ -1,3 +1,7 @@
1
+ /**
2
+ * @license MIT
3
+ * @copyright Copyright 2025 Modus Operandi Inc. All Rights Reserved.
4
+ */
1
5
  import * as React from 'react';
2
6
  import type { CapcoEle } from './contextMenu';
3
7
  import { EditorView } from 'prosemirror-view';
@@ -1,3 +1,7 @@
1
+ /**
2
+ * @license MIT
3
+ * @copyright Copyright 2025 Modus Operandi Inc. All Rights Reserved.
4
+ */
1
5
  import * as React from 'react';
2
6
  import { CAPCOKEY, CAPCO_PLUGIN_KEY, METADATAKEY, TABLE, TABLE_FIGURE_CAPCO, } from './constants';
3
7
  import { SYSTEMCAPCO } from './editorSchema';
@@ -1,3 +1,7 @@
1
+ /**
2
+ * @license MIT
3
+ * @copyright Copyright 2025 Modus Operandi Inc. All Rights Reserved.
4
+ */
1
5
  import { Node } from 'prosemirror-model';
2
6
  import { type KeyValuePair } from './constants';
3
7
  export type toDOMFn = (_node: Node) => [string, Record<string, unknown>, number];
package/capcoNodeSpec.js CHANGED
@@ -1,3 +1,7 @@
1
+ /**
2
+ * @license MIT
3
+ * @copyright Copyright 2025 Modus Operandi Inc. All Rights Reserved.
4
+ */
1
5
  import { CAPCOKEY, METADATAKEY } from './constants';
2
6
  import { safeCapcoParse } from './utils';
3
7
  const ISVALIDATE = 'isValidate';
package/capcoView.d.ts CHANGED
@@ -1,3 +1,7 @@
1
+ /**
2
+ * @license MIT
3
+ * @copyright Copyright 2025 Modus Operandi Inc. All Rights Reserved.
4
+ */
1
5
  import { Node } from 'prosemirror-model';
2
6
  import { EditorView, NodeView } from 'prosemirror-view';
3
7
  export declare class CapcoView implements NodeView {
package/capcoView.js CHANGED
@@ -1,3 +1,7 @@
1
+ /**
2
+ * @license MIT
3
+ * @copyright Copyright 2025 Modus Operandi Inc. All Rights Reserved.
4
+ */
1
5
  /*
2
6
  * File: capcoView.ts
3
7
  * Project: @mo/licit-capco
package/compartment.d.ts CHANGED
@@ -1,3 +1,7 @@
1
+ /**
2
+ * @license MIT
3
+ * @copyright Copyright 2025 Modus Operandi Inc. All Rights Reserved.
4
+ */
1
5
  import { Item } from './item';
2
6
  export declare class Compartment {
3
7
  name: string;
package/compartment.js CHANGED
@@ -1,3 +1,7 @@
1
+ /**
2
+ * @license MIT
3
+ * @copyright Copyright 2025 Modus Operandi Inc. All Rights Reserved.
4
+ */
1
5
  import { getAnItem, removeAnItem } from './item';
2
6
  // Supporting class for CapcoEmbeddedActionsParser
3
7
  // A generic class to handle all compartment types.
package/constants.d.ts CHANGED
@@ -1,3 +1,7 @@
1
+ /**
2
+ * @license MIT
3
+ * @copyright Copyright 2025 Modus Operandi Inc. All Rights Reserved.
4
+ */
1
5
  import { PluginKey } from 'prosemirror-state';
2
6
  export declare const PARAGRAPH = "paragraph";
3
7
  export declare const TABLE = "table";
package/constants.js CHANGED
@@ -1,3 +1,7 @@
1
+ /**
2
+ * @license MIT
3
+ * @copyright Copyright 2025 Modus Operandi Inc. All Rights Reserved.
4
+ */
1
5
  import { PluginKey } from 'prosemirror-state';
2
6
  export const PARAGRAPH = 'paragraph';
3
7
  export const TABLE = 'table';
package/contextMenu.d.ts CHANGED
@@ -1,3 +1,7 @@
1
+ /**
2
+ * @license MIT
3
+ * @copyright Copyright 2025 Modus Operandi Inc. All Rights Reserved.
4
+ */
1
5
  export type CapcoEle = {
2
6
  name?: string;
3
7
  isSimpleItem?: boolean;
package/contextMenu.js CHANGED
@@ -1 +1,5 @@
1
+ /**
2
+ * @license MIT
3
+ * @copyright Copyright 2025 Modus Operandi Inc. All Rights Reserved.
4
+ */
1
5
  export {};
package/customCapco.d.ts CHANGED
@@ -1,3 +1,7 @@
1
+ /**
2
+ * @license MIT
3
+ * @copyright Copyright 2025 Modus Operandi Inc. All Rights Reserved.
4
+ */
1
5
  import { EditorView } from 'prosemirror-view';
2
6
  export type CList = {
3
7
  key: string;
package/customCapco.js CHANGED
@@ -1,3 +1,7 @@
1
+ /**
2
+ * @license MIT
3
+ * @copyright Copyright 2025 Modus Operandi Inc. All Rights Reserved.
4
+ */
1
5
  // Local storage of CAPCO
2
6
  import { CAPCOKEY } from './constants';
3
7
  export function updateDocument(capco, updatedCapco, view) {
package/editorSchema.d.ts CHANGED
@@ -1,3 +1,7 @@
1
+ /**
2
+ * @license MIT
3
+ * @copyright Copyright 2025 Modus Operandi Inc. All Rights Reserved.
4
+ */
1
5
  import { Schema } from 'prosemirror-model';
2
6
  import type { getAttrsExFn, toDOMExFn } from './capcoNodeSpec';
3
7
  export declare enum CAPCOMODE {
package/editorSchema.js CHANGED
@@ -1,3 +1,7 @@
1
+ /**
2
+ * @license MIT
3
+ * @copyright Copyright 2025 Modus Operandi Inc. All Rights Reserved.
4
+ */
1
5
  import { toParagraphDOM, getParagraphNodeAttrs, toHeadingDOM, } from './capcoNodeSpec';
2
6
  import { CAPCOKEY, CAPCOMODEKEY, PARAGRAPH, HEADING, TABLE, TABLE_FIGURE, } from './constants';
3
7
  export var CAPCOMODE;
@@ -79,7 +83,9 @@ function createCapcoNodeAttributes(schema) {
79
83
  ];
80
84
  const NEWATTRS = [CAPCOKEY, 'isValidate'];
81
85
  contentArr.forEach((content) => {
82
- createAttribute(content, NEWATTRS, null);
86
+ if (content !== undefined) {
87
+ createAttribute(content, NEWATTRS, null);
88
+ }
83
89
  });
84
90
  }
85
91
  function createCapcoDocAttributes(schema, mode) {
@@ -92,7 +98,9 @@ function createCapcoDocAttributes(schema, mode) {
92
98
  }
93
99
  function createCapcoModeDocAttributes(contentArr, mode) {
94
100
  contentArr.forEach((content) => {
95
- createAttribute(content, [CAPCOMODEKEY], mode || CAPCOMODE.NONE);
101
+ if (content !== undefined) {
102
+ createAttribute(content, [CAPCOMODEKEY], mode || CAPCOMODE.NONE);
103
+ }
96
104
  });
97
105
  }
98
106
  export const applyEffectiveSchema = effectiveSchema;
package/index.d.ts CHANGED
@@ -1,3 +1,7 @@
1
+ /**
2
+ * @license MIT
3
+ * @copyright Copyright 2025 Modus Operandi Inc. All Rights Reserved.
4
+ */
1
5
  export * from './CapcoPlugin';
2
6
  export * from './capcoContextMenu';
3
7
  export * from './capcoNodeSpec';
package/index.js CHANGED
@@ -1,3 +1,7 @@
1
+ /**
2
+ * @license MIT
3
+ * @copyright Copyright 2025 Modus Operandi Inc. All Rights Reserved.
4
+ */
1
5
  export * from './CapcoPlugin';
2
6
  export * from './capcoContextMenu';
3
7
  export * from './capcoNodeSpec';
package/item.d.ts CHANGED
@@ -1,3 +1,7 @@
1
+ /**
2
+ * @license MIT
3
+ * @copyright Copyright 2025 Modus Operandi Inc. All Rights Reserved.
4
+ */
1
5
  export declare class Item {
2
6
  code: string;
3
7
  description: string;
package/item.js CHANGED
@@ -1,3 +1,7 @@
1
+ /**
2
+ * @license MIT
3
+ * @copyright Copyright 2025 Modus Operandi Inc. All Rights Reserved.
4
+ */
1
5
  // Supporting class for CapcoEmbeddedActionsParser
2
6
  // Represents each code - description row in the compartment.
3
7
  export class Item {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@modusoperandi/licit-capco",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "type": "module",
5
5
  "description": "MO's Capco ProseMirror Plugin",
6
6
  "main": "index.js",
@@ -39,25 +39,23 @@
39
39
  "tippy.js": "^6.3.7"
40
40
  },
41
41
  "devDependencies": {
42
- "@testing-library/jest-dom": "^6.6.4",
43
- "@testing-library/react": "^16.3.0",
44
42
  "@types/jest": "^30.0.0",
45
- "@types/react": "^19.2.2",
46
- "@types/react-dom": "^19.2.1",
47
- "@modusoperandi/eslint-config": "^2.1.4",
43
+ "@types/react": "^18.3.27",
44
+ "@types/react-dom": "^18.3.7",
45
+ "@modusoperandi/eslint-config": "^3.0.3",
48
46
  "copyfiles": "^2.4.1",
49
- "eslint": "^9.37.0",
47
+ "eslint": "^9.39.2",
50
48
  "identity-obj-proxy": "^3.0.0",
51
49
  "jest": "^30.2.0",
52
50
  "jest-environment-jsdom": "^30.2.0",
53
51
  "jest-junit": "^14.0.1",
54
52
  "jest-prosemirror": "^3.0.1",
55
53
  "jest-sonar-reporter": "^2.0.0",
56
- "prettier": "^3.6.2",
54
+ "prettier": "^3.7.4",
57
55
  "prosemirror-test-builder": "^1.1.1",
58
- "react-dom": "^18.0.0",
59
- "ts-jest": "^29.4.0",
56
+ "react-dom": "^18.3.1",
57
+ "ts-jest": "^29.4.6",
60
58
  "ts-node": "^10.9.2",
61
59
  "typescript": "^5.9.3"
62
60
  }
63
- }
61
+ }
package/types.d.ts CHANGED
@@ -1,3 +1,7 @@
1
+ /**
2
+ * @license MIT
3
+ * @copyright Copyright 2025 Modus Operandi Inc. All Rights Reserved.
4
+ */
1
5
  export declare const CAPCO = "capco";
2
6
  export interface CapcoState {
3
7
  portionMarking?: string;
package/types.js CHANGED
@@ -1,3 +1,7 @@
1
+ /**
2
+ * @license MIT
3
+ * @copyright Copyright 2025 Modus Operandi Inc. All Rights Reserved.
4
+ */
1
5
  /*
2
6
  * File: types.ts
3
7
  * Project: @mo/licit-capco
package/utils.d.ts CHANGED
@@ -1,3 +1,7 @@
1
+ /**
2
+ * @license MIT
3
+ * @copyright Copyright 2025 Modus Operandi Inc. All Rights Reserved.
4
+ */
1
5
  import { Compartment } from './compartment';
2
6
  import { CapcoState } from './types';
3
7
  import { EditorState } from 'prosemirror-state';
package/utils.js CHANGED
@@ -1,3 +1,7 @@
1
+ /**
2
+ * @license MIT
3
+ * @copyright Copyright 2025 Modus Operandi Inc. All Rights Reserved.
4
+ */
1
5
  export function getValueWithoutSlash(markerInputvalue) {
2
6
  if (markerInputvalue.endsWith('/')) {
3
7
  markerInputvalue = markerInputvalue.substring(0, markerInputvalue.length - 1);