Socket
Socket
Sign inDemoInstall

@codemirror/autocomplete

Package Overview
Dependencies
Maintainers
2
Versions
77
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@codemirror/autocomplete - npm Package Compare versions

Comparing version 0.19.2 to 0.19.3

16

CHANGELOG.md

@@ -0,1 +1,17 @@

## 0.19.3 (2021-08-31)
### Bug fixes
Improve the sorting of completions by using `localeCompare`.
Fix reading of autocompletions in NVDA screen reader.
### New features
The new `icons` option can be used to turn off icons in the completion list.
The `optionClass` option can now be used to add CSS classes to the options in the completion list.
It is now possible to inject additional content into rendered completion options with the `addToOptions` configuration option.
## 0.19.2 (2021-08-25)

@@ -2,0 +18,0 @@

@@ -30,2 +30,26 @@ import { EditorState, Transaction, StateCommand, Facet, Extension } from '@codemirror/state';

defaultKeymap?: boolean;
/**
This can be used to add additional CSS classes to completion
options.
*/
optionClass?: (completion: Completion) => string;
/**
By default, the library will render icons based on the
completion's [type](https://codemirror.net/6/docs/ref/#autocomplete.Completion.type) in front of
each option. Set this to false to turn that off.
*/
icons?: boolean;
/**
This option can be used to inject additional content into
options. The `render` function will be called for each visible
completion, and should produce a DOM node to show. `position`
determines where in the DOM the result appears, relative to
other added widgets and the standard content. The default icons
have position 20, the label position 50, and the detail position
70.
*/
addToOptions?: {
render: (completion: Completion, state: EditorState) => Node | null;
position: number;
}[];
}

@@ -32,0 +56,0 @@

138

dist/index.js

@@ -300,8 +300,17 @@ import { Facet, combineConfig, StateEffect, StateField, Text, EditorSelection, Prec } from '@codemirror/state';

maxRenderedOptions: 100,
defaultKeymap: true
defaultKeymap: true,
optionClass: () => "",
icons: true,
addToOptions: []
}, {
defaultKeymap: (a, b) => a && b
defaultKeymap: (a, b) => a && b,
icons: (a, b) => a && b,
optionClass: (a, b) => c => joinClass(a(c), b(c)),
addToOptions: (a, b) => a.concat(b)
});
}
});
function joinClass(a, b) {
return a ? b ? a + " " + b : a : b;
}

@@ -407,42 +416,47 @@ const MaxInfoWidth = 300;

function createListBox(options, id, range) {
const ul = document.createElement("ul");
ul.id = id;
ul.setAttribute("role", "listbox");
ul.setAttribute("aria-expanded", "true");
for (let i = range.from; i < range.to; i++) {
let { completion, match } = options[i];
const li = ul.appendChild(document.createElement("li"));
li.id = id + "-" + i;
let icon = li.appendChild(document.createElement("div"));
icon.classList.add("cm-completionIcon");
if (completion.type)
icon.classList.add(...completion.type.split(/\s+/g).map(cls => "cm-completionIcon-" + cls));
icon.setAttribute("aria-hidden", "true");
let labelElt = li.appendChild(document.createElement("span"));
labelElt.className = "cm-completionLabel";
let { label, detail } = completion, off = 0;
for (let j = 1; j < match.length;) {
let from = match[j++], to = match[j++];
if (from > off)
labelElt.appendChild(document.createTextNode(label.slice(off, from)));
let span = labelElt.appendChild(document.createElement("span"));
span.appendChild(document.createTextNode(label.slice(from, to)));
span.className = "cm-completionMatchedText";
off = to;
}
if (off < label.length)
labelElt.appendChild(document.createTextNode(label.slice(off)));
if (detail) {
let detailElt = li.appendChild(document.createElement("span"));
function optionContent(config) {
let content = config.addToOptions.slice();
if (config.icons)
content.push({
render(completion) {
let icon = document.createElement("div");
icon.classList.add("cm-completionIcon");
if (completion.type)
icon.classList.add(...completion.type.split(/\s+/g).map(cls => "cm-completionIcon-" + cls));
icon.setAttribute("aria-hidden", "true");
return icon;
},
position: 20
});
content.push({
render(completion, _s, match) {
let labelElt = document.createElement("span");
labelElt.className = "cm-completionLabel";
let { label } = completion, off = 0;
for (let j = 1; j < match.length;) {
let from = match[j++], to = match[j++];
if (from > off)
labelElt.appendChild(document.createTextNode(label.slice(off, from)));
let span = labelElt.appendChild(document.createElement("span"));
span.appendChild(document.createTextNode(label.slice(from, to)));
span.className = "cm-completionMatchedText";
off = to;
}
if (off < label.length)
labelElt.appendChild(document.createTextNode(label.slice(off)));
return labelElt;
},
position: 50
}, {
render(completion) {
if (!completion.detail)
return null;
let detailElt = document.createElement("span");
detailElt.className = "cm-completionDetail";
detailElt.textContent = detail;
}
li.setAttribute("role", "option");
}
if (range.from)
ul.classList.add("cm-completionListIncompleteTop");
if (range.to < options.length)
ul.classList.add("cm-completionListIncompleteBottom");
return ul;
detailElt.textContent = completion.detail;
return detailElt;
},
position: 80
});
return content.sort((a, b) => a.position - b.position).map(a => a.render);
}

@@ -488,2 +502,4 @@ function createInfoDialog(option, view) {

let config = view.state.facet(completionConfig);
this.optionContent = optionContent(config);
this.optionClass = config.optionClass;
this.range = rangeAroundSelected(options.length, selected, config.maxRenderedOptions);

@@ -501,3 +517,3 @@ this.dom = document.createElement("div");

});
this.list = this.dom.appendChild(createListBox(options, cState.id, this.range));
this.list = this.dom.appendChild(this.createListBox(options, cState.id, this.range));
this.list.addEventListener("scroll", () => {

@@ -522,3 +538,3 @@ if (this.info)

this.list.remove();
this.list = this.dom.appendChild(createListBox(open.options, cState.id, this.range));
this.list = this.dom.appendChild(this.createListBox(open.options, cState.id, this.range));
this.list.addEventListener("scroll", () => {

@@ -582,2 +598,26 @@ if (this.info)

}
createListBox(options, id, range) {
const ul = document.createElement("ul");
ul.id = id;
ul.setAttribute("role", "listbox");
for (let i = range.from; i < range.to; i++) {
let { completion, match } = options[i];
const li = ul.appendChild(document.createElement("li"));
li.id = id + "-" + i;
li.setAttribute("role", "option");
let cls = this.optionClass(completion);
if (cls)
li.className = cls;
for (let source of this.optionContent) {
let node = source(completion, this.view.state, match);
if (node)
li.appendChild(node);
}
}
if (range.from)
ul.classList.add("cm-completionListIncompleteTop");
if (range.to < options.length)
ul.classList.add("cm-completionListIncompleteBottom");
return ul;
}
}

@@ -717,10 +757,15 @@ // We allocate a new function instance every time the completion

}
const baseAttrs = {
"aria-autocomplete": "list",
"aria-expanded": "false"
};
function makeAttrs(id, selected) {
return {
"aria-autocomplete": "list",
"aria-expanded": "true",
"aria-activedescendant": id + "-" + selected,
"aria-owns": id
"aria-controls": id
};
}
const baseAttrs = { "aria-autocomplete": "list" }, none = [];
const none = [];
function cmpOption(a, b) {

@@ -730,4 +775,3 @@ let dScore = b.match[0] - a.match[0];

return dScore;
let lA = a.completion.label, lB = b.completion.label;
return lA < lB ? -1 : lA == lB ? 0 : 1;
return a.completion.label.localeCompare(b.completion.label);
}

@@ -734,0 +778,0 @@ function getUserEvent(tr) {

{
"name": "@codemirror/autocomplete",
"version": "0.19.2",
"version": "0.19.3",
"description": "Autocompletion for the CodeMirror code editor",

@@ -5,0 +5,0 @@ "scripts": {

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