Skip to content

Commit

Permalink
Version 0.0.1
Browse files Browse the repository at this point in the history
  • Loading branch information
FIameCaster committed Aug 7, 2023
1 parent 0064d11 commit 8e8b027
Show file tree
Hide file tree
Showing 11 changed files with 448 additions and 429 deletions.
170 changes: 86 additions & 84 deletions package/package.json
Original file line number Diff line number Diff line change
@@ -1,84 +1,86 @@
{
"name": "prism-code-editor",
"version": "0.0.0",
"type": "module",
"description": "Lightweight, extensible code editor for the web using Prism",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"exports": {
".": "./dist/index.js",
"./guides": "./dist/extensions/guides.js",
"./web-component": "./dist/webComponent.js",
"./copy-button": "./dist/extensions/copyButton/index.js",
"./copy-button.css": "./dist/copy.css",
"./scrollbar.css": "./dist/scrollbar.css",
"./setups": "./dist/setups.js",
"./layout.css": "./dist/layout.css",
"./themes/*.css": "./dist/themes/*.css",
"./themes": "./dist/themes/index.js",
"./languages": "./dist/languages/index.js",
"./languages/clike": "./dist/languages/clike.js",
"./languages/css": "./dist/languages/css.js",
"./languages/html": "./dist/languages/html.js",
"./languages/jsx": "./dist/languages/jsx.js",
"./languages/python": "./dist/languages/python.js",
"./languages/xml": "./dist/languages/xml.js",
"./match-brackets": "./dist/extensions/matchBrackets.js",
"./commands": "./dist/extensions/commands.js",
"./cursor": "./dist/extensions/cursor.js",
"./prism-core": "./dist/prismCore.js",
"./prism-markdown": "./dist/prismMarkdown.js",
"./search": "./dist/extensions/search/index.js",
"./search/api": "./dist/extensions/search/api.js",
"./search.css": "./dist/search.css"
},
"typesVersions": {
"*": {
"*": ["./dist/*"]
}
},
"files": [
"dist/*"
],
"scripts": {
"dev": "vite",
"build": "tsc && vite build && node scripts/build.mjs",
"preview": "vite preview",
"prepublish": "tsc && vite build && node scripts/build.mjs"
},
"devDependencies": {
"@types/node": "^20.3.1",
"prismjs": "^1.29.0",
"typescript": "^5.0.2",
"vite": "^4.3.9",
"vite-plugin-dts": "^2.3.0"
},
"dependencies": {
"@types/prismjs": "^1.26.0"
},
"keywords": [
"editor",
"code editor",
"textarea",
"small",
"highlight",
"prismjs"
],
"author": "FlameCaster",
"repository": {
"type": "git",
"url": "git+https://github.com/FIameCaster/prism-code-editor.git"
},
"license": "MIT",
"sideEffects": [
"*.css",
"./dist/languages/*",
"./dist/prism-core.js",
"./dist/prism-markdown.js"
],
"pnpm": {
"patchedDependencies": {
"[email protected]": "patches/[email protected]"
}
}
}
{
"name": "prism-code-editor",
"version": "0.0.1",
"type": "module",
"description": "Lightweight, extensible code editor for the web using Prism",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"exports": {
".": "./dist/index.js",
"./guides": "./dist/extensions/guides.js",
"./web-component": "./dist/webComponent.js",
"./copy-button": "./dist/extensions/copyButton/index.js",
"./copy-button.css": "./dist/copy.css",
"./scrollbar.css": "./dist/scrollbar.css",
"./setups": "./dist/setups.js",
"./layout.css": "./dist/layout.css",
"./themes/*.css": "./dist/themes/*.css",
"./themes": "./dist/themes/index.js",
"./languages": "./dist/languages/index.js",
"./languages/clike": "./dist/languages/clike.js",
"./languages/css": "./dist/languages/css.js",
"./languages/html": "./dist/languages/html.js",
"./languages/jsx": "./dist/languages/jsx.js",
"./languages/python": "./dist/languages/python.js",
"./languages/xml": "./dist/languages/xml.js",
"./match-brackets": "./dist/extensions/matchBrackets.js",
"./commands": "./dist/extensions/commands.js",
"./cursor": "./dist/extensions/cursor.js",
"./prism-core": "./dist/prismCore.js",
"./prism-markdown": "./dist/prismMarkdown.js",
"./search": "./dist/extensions/search/index.js",
"./search/api": "./dist/extensions/search/api.js",
"./search.css": "./dist/search.css"
},
"typesVersions": {
"*": {
"*": [
"./dist/*"
]
}
},
"files": [
"dist/*"
],
"scripts": {
"dev": "vite",
"build": "tsc && vite build && node scripts/build.mjs",
"preview": "vite preview",
"prepublish": "tsc && vite build && node scripts/build.mjs"
},
"devDependencies": {
"@types/node": "^20.3.1",
"prismjs": "^1.29.0",
"typescript": "^5.0.2",
"vite": "^4.3.9",
"vite-plugin-dts": "^2.3.0"
},
"dependencies": {
"@types/prismjs": "^1.26.0"
},
"keywords": [
"editor",
"code editor",
"textarea",
"small",
"highlight",
"prismjs"
],
"author": "FlameCaster",
"repository": {
"type": "git",
"url": "git+https://github.com/FIameCaster/prism-code-editor.git"
},
"license": "MIT",
"sideEffects": [
"*.css",
"./dist/languages/*",
"./dist/prism-core.js",
"./dist/prism-markdown.js"
],
"pnpm": {
"patchedDependencies": {
"[email protected]": "patches/[email protected]"
}
}
}
14 changes: 0 additions & 14 deletions package/src/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -290,19 +290,6 @@ const createEditor = (
const createTemplate = (innerHTML = "", style = "", className = ""): HTMLDivElement =>
Object.assign(document.createElement("div"), { innerHTML, style, className })

/**
* Returns a 4 bit integer where each bit represents whether
* each modifier is pressed in the order Shift, Meta, Ctrl, Alt
* ```javascript
* e.altKey && e.ctrlKey && e.shiftKey && !e.metaKey
* // is equivalent to
* getModifierCode(e) == 0b1011
* ```
*/
const getModifierCode = (
e: KeyboardEvent, // @ts-ignore
): number => e.altKey + e.ctrlKey * 2 + e.metaKey * 4 + e.shiftKey * 8

const getElement = (el?: ParentNode | string | null) =>
typeof el == "string" ? document.querySelector(el) : el

Expand Down Expand Up @@ -352,7 +339,6 @@ export {
isChrome,
isWebKit,
getElement,
getModifierCode,
preventDefault,
setSelection,
}
8 changes: 4 additions & 4 deletions package/src/extensions/commands.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { EditorOptions, Extension, InputSelection } from ".."
import { ignoreTab, isMac, preventDefault, setIgnoreTab, getModifierCode, languages } from "../core"
import { getLanguage, insertText, getLineBefore, getLines, regexEscape } from "../utils"
import { ignoreTab, isMac, preventDefault, setIgnoreTab, languages } from "../core"
import { getLanguage, insertText, getLineBefore, getLines, regexEscape, getModifierCode } from "../utils"
import { Cursor } from "./cursor"

const clipboard = navigator.clipboard

/**
* Extension that will add automatic indentation, closing of brackets,
* quotes and tags, line and block comment toggling and line moving/copying.
* quotes and tags, line- and block comment toggling and line moving/copying.
* @param cursor Cursor that will be used to keep the cursor in view when typing.
* @param selfClosePairs Pairs of self-closing brackets and quotes.
* Must be an array of strings with 2 characters each.
Expand Down Expand Up @@ -162,7 +162,7 @@ export const defaultCommands = (
indentChar.repeat(indenationCount + extraIndent) +
(extraLine ? "\n" + indentChar.repeat(indenationCount) : "")

if (newText[1]) {
if (newText[1] || selection[1] < value.length) {
insertText(
editor,
newText,
Expand Down
33 changes: 17 additions & 16 deletions package/src/extensions/search/replace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,29 @@ export interface ReplaceAPI extends SearchAPI {

const createReplaceAPI = (editor: PrismEditor): ReplaceAPI => {
const { getSelection, textarea } = editor,
search = createSearchAPI(editor)
search = createSearchAPI(editor),
closest = () => {
const caretPos = getSelection()[0],
matches = search.matches,
l = matches.length
for (let i = l; i; ) {
if (caretPos > matches[--i][1]) return i == l - 1 ? 0 : i + 1
}
return l ? 0 : -1
}

let currentLine: HTMLDivElement,
currentMatch: HTMLSpanElement,
removeHighlight: (() => void) | null

return Object.assign(search, {
next() {
const [start, end] = getSelection(),
let [start, end] = getSelection(),
matches = search.matches,
pos = end + +(start == end),
l = matches.length
if (start == end) end++
for (let i = 0; i < l; i++) {
if (matches[i][0] >= pos) return i
if (matches[i][0] >= end) return i
}
return l ? 0 : -1
},
Expand All @@ -53,15 +62,7 @@ const createReplaceAPI = (editor: PrismEditor): ReplaceAPI => {
}
return l - 1
},
closest() {
const caretPos = getSelection()[0],
matches = search.matches,
l = matches.length
for (let i = l; i; ) {
if (caretPos > matches[--i][1]) return i == l - 1 ? 0 : i + 1
}
return l ? 0 : -1
},
closest,
selectMatch(index: number, scrollPadding?: number) {
removeHighlight?.()
const match = search.matches[index]
Expand All @@ -85,15 +86,15 @@ const createReplaceAPI = (editor: PrismEditor): ReplaceAPI => {
},
replace(str: string) {
if (!search.matches[0]) return
const index = this.closest(),
const index = closest(),
[start, end] = search.matches[index],
[caretStart, caretEnd] = getSelection()

if (start == caretStart && end == caretEnd) insertText(editor, str)
else {
if (start != caretStart || end != caretEnd) {
this.selectMatch(index)
return index
}
insertText(editor, str)
},
replaceAll(str: string, selection?: [number, number]) {
const { matches, regex } = search
Expand Down
48 changes: 31 additions & 17 deletions package/src/extensions/search/search.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,22 @@ const template = createTemplate(
"",
"color:#0000;display:none;contain:strict;margin:0 var(--padding-inline) 0 var(--padding-left);",
)
template.setAttribute("aria-hidden", <any>true)

export interface SearchAPI {
/**
* Unhides the search container and highlights all matches of the specified string in the editor.
* @param str String to search for.
* @param caseSensitive Whether or not the search is case sensetive.
* @param wholeWordSearch Whether or not matches must be surrounded by word boundries (\b).
* @param wholeWord Whether or not matches must be surrounded by word boundries (\b).
* @param useRegExp If false, special characters will be escaped when creating the RegExp.
* @param selection boundries to search between. If excluded, all the code is searched.
* @param selection Boundries to search between. If excluded, all the code is searched.
* @param excludedPosition A match containing this position in the string will be excluded.
* @returns An error message if the RegExp was invalid.
*/
search(
str: string,
caseSensitive?: boolean,
wholeWordSearch?: boolean,
wholeWordh?: boolean,
useRegExp?: boolean,
selection?: [number, number],
excludedPosition?: number,
Expand All @@ -41,25 +40,37 @@ const createSearchAPI = (editor: PrismEditor): SearchAPI => {
const span = document.createElement("span"),
nodes: ChildNode[] = [new Text()],
nodeValues: string[] = [],
container = <HTMLDivElement>template.cloneNode()
container = <HTMLDivElement>template.cloneNode(),
stopSearch = () => {
if (matchPositions[0]) {
matchPositions = []
container.style.display = "none"
}
}

let matchPositions: [number, number][] = []
let regex: RegExp
span.append("")
editor.overlays.append(container)

return {
search(str, caseSensitive, wholeWordSearch, useRegExp, selection, excludedPosition = -1) {
if (!str) return this.stopSearch()
search(str, caseSensitive, wholeWord, useRegExp, selection, excludedPosition = -1) {
if (!str) return stopSearch()
if (!useRegExp) str = regexEscape(str)
if (wholeWordSearch) str = `\\b${str}\\b`
const value = editor.value,
searchStr = selection ? value.slice(...selection) : value,
offset = selection?.[0] || 0
offset = selection?.[0] || 0,
flags = `gu${caseSensitive ? "" : "i"}`

try {
matchPositions = []
regex = RegExp(str, `gu${caseSensitive ? "" : "i"}`)
regex = RegExp(str, flags)
// Reassigning the regex means error messages won't include the lookbehind or lookahead
if (wholeWord)
regex = RegExp(
supportsLookbehind ? `(?<=^|\\b|\\W)${str}(?=\\b|\\W|$)` : `\\b${str}\\b`,
flags,
)
for (
let match: RegExpExecArray | null, l: number, index: number, i = 0;
(match = regex.exec(searchStr));
Expand Down Expand Up @@ -95,7 +106,7 @@ const createSearchAPI = (editor: PrismEditor): SearchAPI => {
}

if (remainder != nodeValues[l]) (<Text>nodes[l]).data = nodeValues[l] = remainder
container.style.removeProperty("display")
container.style.display = ""
}
},
container,
Expand All @@ -105,13 +116,16 @@ const createSearchAPI = (editor: PrismEditor): SearchAPI => {
get matches() {
return matchPositions
},
stopSearch() {
if (matchPositions[0]) {
matchPositions = []
container.style.display = "none"
}
},
stopSearch,
}
}

template.setAttribute("aria-hidden", <any>true)

let supportsLookbehind: boolean
try {
RegExp("(?<=)")
supportsLookbehind = true
} catch {}

export { createSearchAPI }
Loading

0 comments on commit 8e8b027

Please sign in to comment.