Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@replit/codemirror-interact

Package Overview
Dependencies
Maintainers
23
Versions
12
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@replit/codemirror-interact - npm Package Compare versions

Comparing version 6.0.3 to 6.0.4

9

dist/index.d.ts
import * as _codemirror_state from '@codemirror/state';
import { Facet } from '@codemirror/state';
import { Facet, StateField } from '@codemirror/state';
interface Target {
pos: number;
text: string;
rule: InteractRule;
}
interface InteractRule {

@@ -38,4 +43,4 @@ regexp: RegExp;

}
declare const interact: (cfg?: InteractConfig) => _codemirror_state.Extension[];
declare const interact: (cfg?: InteractConfig) => (_codemirror_state.Extension | StateField<Target | null>)[];
export { InteractRule, interact as default, interactModKey, interactRule };

@@ -1,7 +0,50 @@

import { Decoration, EditorView, ViewPlugin } from '@codemirror/view';
import { StateEffect, Facet, Compartment, Prec } from '@codemirror/state';
import { EditorView, Decoration, ViewPlugin } from '@codemirror/view';
import { StateField, MapMode, StateEffect, Facet } from '@codemirror/state';
// TODO: custom style
const interactField = /*@__PURE__*/StateField.define({
create: () => null,
update: (value, tr) => {
for (const e of tr.effects) {
if (e.is(setInteract)) {
return e.value;
}
}
if (!value) {
return null;
}
if (!tr.changes.empty) {
const newPos = tr.changes.mapPos(value.pos, -1, MapMode.TrackDel);
const newEnd = tr.changes.mapPos(value.pos + value.text.length, -1, MapMode.TrackDel);
if (newPos === null || newEnd === null) {
return null;
}
// if the text doesn't match anymore, we'll just return null
// rather than checking if the rule matches again
if (tr.newDoc.sliceString(newPos, newEnd) !== value.text) {
return null;
}
return Object.assign(Object.assign({}, value), { pos: newPos });
}
return value;
},
provide: (field) => [
EditorView.decorations.from(field, (target) => {
if (!target) {
return Decoration.none;
}
const from = target.pos;
const to = target.pos + target.text.length;
return Decoration.set(mark.range(from, to));
}),
EditorView.contentAttributes.from(field, (target) => {
if (!target || !target.rule.cursor) {
return { style: '' };
}
return { style: `cursor: ${target.rule.cursor}` };
}),
]
});
const setInteract = /*@__PURE__*/StateEffect.define();
const mark = /*@__PURE__*/Decoration.mark({ class: 'cm-interact' });
const setInteract = /*@__PURE__*/StateEffect.define();
const interactTheme = /*@__PURE__*/EditorView.theme({

@@ -37,14 +80,7 @@ '.cm-interact': {

});
const setStyle = (style = '') => EditorView.contentAttributes.of({ style });
const normalCursor = /*@__PURE__*/setStyle();
const cursorCompartment = /*@__PURE__*/new Compartment();
const cursorRule = /*@__PURE__*/Prec.highest(/*@__PURE__*/cursorCompartment.of(normalCursor));
const clearCursor = () => cursorCompartment.reconfigure(normalCursor);
const setCursor = (cursor) => cursor ? [cursorCompartment.reconfigure(setStyle(`cursor: ${cursor}`))] : [];
const interactViewPlugin = /*@__PURE__*/ViewPlugin.define((view) => ({
dragging: null,
hovering: null,
target: null,
dragging: false,
mouseX: 0,
mouseY: 0,
deco: Decoration.none,
// Get current match under cursor from all rules

@@ -85,2 +121,3 @@ getMatch() {

view.dispatch({
effects: setInteract.of(Object.assign(Object.assign({}, target), { text })),
changes: {

@@ -92,16 +129,8 @@ from: target.pos,

});
target.text = text;
};
},
// highlight a target (e.g. currently dragging or hovering)
highlight(target) {
view.dispatch({
effects: [setInteract.of(target), ...setCursor(target.rule.cursor)],
});
setTarget(target) {
this.target = target;
view.dispatch({ effects: setInteract.of(target) });
},
unhighlight() {
view.dispatch({
effects: [setInteract.of(null), clearCursor()],
});
},
isModKeyDown(e) {

@@ -118,8 +147,11 @@ const modkey = view.state.facet(interactModKey);

update(update) {
for (const tr of update.transactions) {
for (const e of tr.effects) {
if (e.is(setInteract)) {
const decos = e.value ? mark.range(e.value.pos, e.value.pos + e.value.text.length) : [];
this.deco = Decoration.set(decos);
}
const target = update.state.field(interactField, false);
// the field isn't mounted
if (target === undefined) {
return;
}
if (this.target !== target) {
this.target = target;
if (target === null) {
this.dragging = false;
}

@@ -129,5 +161,4 @@ }

}), {
decorations: (v) => v.deco,
eventHandlers: {
mousedown(e, view) {
mousedown(e, _view) {
if (!this.isModKeyDown(e))

@@ -143,52 +174,49 @@ return;

if (match.rule.onDrag) {
this.dragging = {
rule: match.rule,
pos: match.pos,
text: match.text,
};
this.dragging = true;
}
},
mousemove(e, view) {
mousemove(e, _view) {
this.mouseX = e.clientX;
this.mouseY = e.clientY;
if (!this.isModKeyDown(e))
if (!this.isModKeyDown(e)) {
if (this.target) {
this.setTarget(null);
}
return;
if (this.dragging) {
this.highlight(this.dragging);
if (this.dragging.rule.onDrag) {
this.dragging.rule.onDrag(this.dragging.text, this.updateText(this.dragging), e);
}
if (this.target && this.dragging) {
if (this.target.rule.onDrag) {
this.target.rule.onDrag(this.target.text, this.updateText(this.target), e);
}
}
else {
this.hovering = this.getMatch();
if (this.hovering) {
this.highlight(this.hovering);
}
else {
this.unhighlight();
}
this.setTarget(this.getMatch());
}
},
mouseup(e, view) {
this.dragging = null;
if (!this.hovering) {
this.unhighlight();
mouseup(e, _view) {
this.dragging = false;
if (this.target && !this.isModKeyDown(e)) {
this.setTarget(null);
}
if (this.isModKeyDown(e)) {
this.setTarget(this.getMatch());
}
},
mouseleave(e, view) {
this.hovering = null;
this.dragging = null;
this.unhighlight();
mouseleave(_e, _view) {
this.dragging = false;
if (this.target) {
this.setTarget(null);
}
},
keydown(e, view) {
if (!this.isModKeyDown(e))
return;
this.hovering = this.getMatch();
if (this.hovering) {
this.highlight(this.hovering);
// TODO: fix these keybindings
// these currently don't do anything because CodeMirror's keybinding
// system prevents these events from firing.
keydown(e, _view) {
if (!this.target && this.isModKeyDown(e)) {
this.setTarget(this.getMatch());
}
},
keyup(e, view) {
if (!this.isModKeyDown(e)) {
this.unhighlight();
keyup(e, _view) {
if (this.target && !this.isModKeyDown(e)) {
this.setTarget(null);
}

@@ -201,6 +229,6 @@ },

return [
interactField,
interactTheme,
interactViewPlugin,
interactModKey.of((_a = cfg.key) !== null && _a !== void 0 ? _a : "alt"),
cursorRule,
((_b = cfg.rules) !== null && _b !== void 0 ? _b : []).map((r) => interactRule.of(r)),

@@ -207,0 +235,0 @@ ];

{
"name": "@replit/codemirror-interact",
"description": "Interact with custom values",
"version": "6.0.3",
"version": "6.0.4",
"license": "MIT",

@@ -6,0 +6,0 @@ "author": {

@@ -7,3 +7,2 @@ // TODO: custom style

PluginValue,
DecorationSet,
Decoration,

@@ -13,5 +12,5 @@ } from '@codemirror/view'

StateEffect,
StateField,
Facet,
Prec,
Compartment,
MapMode,
} from '@codemirror/state'

@@ -33,5 +32,60 @@

const mark = Decoration.mark({ class: 'cm-interact'});
const interactField = StateField.define<Target | null>({
create: () => null,
update: (value, tr) => {
for (const e of tr.effects) {
if (e.is(setInteract)) {
return e.value;
}
}
if (!value) {
return null
}
if (!tr.changes.empty) {
const newPos = tr.changes.mapPos(value.pos, -1, MapMode.TrackDel)
const newEnd = tr.changes.mapPos(value.pos + value.text.length, -1, MapMode.TrackDel)
if (newPos === null || newEnd === null) {
return null
}
// if the text doesn't match anymore, we'll just return null
// rather than checking if the rule matches again
if (tr.newDoc.sliceString(newPos, newEnd) !== value.text) {
return null
}
return { ...value, pos: newPos }
}
return value
},
provide: (field) => [
EditorView.decorations.from(field, (target) => {
if (!target) {
return Decoration.none
}
const from = target.pos;
const to = target.pos + target.text.length;
return Decoration.set(mark.range(from, to))
}),
EditorView.contentAttributes.from(field, (target) => {
if (!target || !target.rule.cursor) {
return { style: '' }
}
return { style: `cursor: ${target.rule.cursor}` }
}),
]
})
const setInteract = StateEffect.define<Target | null>();
const mark = Decoration.mark({ class: 'cm-interact' });
const interactTheme = EditorView.theme({

@@ -70,24 +124,10 @@ '.cm-interact': {

const setStyle = (style = '') =>
EditorView.contentAttributes.of({ style });
const normalCursor = setStyle();
const cursorCompartment = new Compartment();
const cursorRule = Prec.highest(cursorCompartment.of(normalCursor));
const clearCursor = () => cursorCompartment.reconfigure(normalCursor);
const setCursor = (cursor?: string) =>
cursor ? [cursorCompartment.reconfigure(setStyle(`cursor: ${cursor}`))] : [];
interface ViewState extends PluginValue {
dragging: Target | null,
hovering: Target | null,
target: Target | null,
dragging: boolean,
mouseX: number,
mouseY: number,
deco: DecorationSet,
getMatch(): Target | null,
updateText(target: Target): (text: string) => void,
highlight(target: Target): void,
unhighlight(): void,
setTarget(target: Target | null): void,
isModKeyDown(e: KeyboardEvent | MouseEvent): boolean,

@@ -98,7 +138,6 @@ }

dragging: null,
hovering: null,
target: null,
dragging: false,
mouseX: 0,
mouseY: 0,
deco: Decoration.none,

@@ -135,3 +174,2 @@ // Get current match under cursor from all rules

return match;
},

@@ -142,2 +180,3 @@

view.dispatch({
effects: setInteract.of({ ...target, text }),
changes: {

@@ -149,21 +188,13 @@ from: target.pos,

});
target.text = text;
};
},
// highlight a target (e.g. currently dragging or hovering)
highlight(target) {
view.dispatch({
effects: [setInteract.of(target), ...setCursor(target.rule.cursor)],
});
setTarget(target) {
this.target = target;
view.dispatch({ effects: setInteract.of(target) });
},
unhighlight() {
view.dispatch({
effects: [setInteract.of(null), clearCursor()],
});
},
isModKeyDown(e) {
const modkey = view.state.facet(interactModKey);
switch (modkey) {

@@ -175,2 +206,3 @@ case "alt": return e.altKey;

}
throw new Error(`Invalid mod key: ${modkey}`)

@@ -180,11 +212,13 @@ },

update(update) {
for (const tr of update.transactions) {
for (const e of tr.effects) {
if (e.is(setInteract)) {
const decos = e.value ? mark.range(
e.value.pos,
e.value.pos + e.value.text.length
) : [];
this.deco = Decoration.set(decos);
}
const target = update.state.field(interactField, false)
// the field isn't mounted
if (target === undefined) {
return
}
if (this.target !== target) {
this.target = target
if (target === null) {
this.dragging = false
}

@@ -195,12 +229,9 @@ }

}), {
decorations: (v) => v.deco,
eventHandlers: {
mousedown(e, _view) {
if (!this.isModKeyDown(e)) return;
mousedown(e, view) {
if (!this.isModKeyDown(e)) return;
const match = this.getMatch();
if (!match) return;
e.preventDefault();

@@ -213,30 +244,24 @@

if (match.rule.onDrag) {
this.dragging = {
rule: match.rule,
pos: match.pos,
text: match.text,
};
this.dragging = true
}
},
mousemove(e, view) {
mousemove(e, _view) {
this.mouseX = e.clientX;
this.mouseY = e.clientY;
if (!this.isModKeyDown(e)) return;
if (!this.isModKeyDown(e)) {
if (this.target) {
this.setTarget(null);
}
if (this.dragging) {
this.highlight(this.dragging);
if (this.dragging.rule.onDrag) {
this.dragging.rule.onDrag(this.dragging.text, this.updateText(this.dragging), e);
return
}
if (this.target && this.dragging) {
if (this.target.rule.onDrag) {
this.target.rule.onDrag(this.target.text, this.updateText(this.target), e);
}
} else {
this.hovering = this.getMatch();
if (this.hovering) {
this.highlight(this.hovering);
} else {
this.unhighlight();
}
this.setTarget(this.getMatch());
}

@@ -246,26 +271,34 @@

mouseup(e, view) {
this.dragging = null;
if (!this.hovering) {
this.unhighlight();
mouseup(e, _view) {
this.dragging = false
if (this.target && !this.isModKeyDown(e)) {
this.setTarget(null)
}
if (this.isModKeyDown(e)) {
this.setTarget(this.getMatch());
}
},
mouseleave(e, view) {
this.hovering = null;
this.dragging = null;
this.unhighlight();
mouseleave(_e, _view) {
this.dragging = false;
if (this.target) {
this.setTarget(null)
}
},
keydown(e, view) {
if (!this.isModKeyDown(e)) return;
this.hovering = this.getMatch();
if (this.hovering) {
this.highlight(this.hovering);
// TODO: fix these keybindings
// these currently don't do anything because CodeMirror's keybinding
// system prevents these events from firing.
keydown(e, _view) {
if (!this.target && this.isModKeyDown(e)) {
this.setTarget(this.getMatch());
}
},
keyup(e, view) {
if (!this.isModKeyDown(e)) {
this.unhighlight();
keyup(e, _view) {
if (this.target && !this.isModKeyDown(e)) {
this.setTarget(null)
}

@@ -289,6 +322,6 @@ },

const interact = (cfg: InteractConfig = {}) => [
interactField,
interactTheme,
interactViewPlugin,
interactModKey.of(cfg.key ?? "alt"),
cursorRule,
(cfg.rules ?? []).map((r) => interactRule.of(r)),

@@ -295,0 +328,0 @@ ];

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc