diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 0000000..6bdaa99
--- /dev/null
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,6 @@
+*Issue #, if available:*
+
+*Description of changes:*
+
+
+By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.
diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml
new file mode 100644
index 0000000..5d4138f
--- /dev/null
+++ b/.github/workflows/nodejs.yml
@@ -0,0 +1,33 @@
+# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
+# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
+
+name: CI
+
+on:
+ push:
+ branches: [ master ]
+ pull_request:
+ branches: [ master ]
+
+permissions:
+ contents: read # to fetch code (actions/checkout)
+
+jobs:
+ build:
+
+ runs-on: ubuntu-latest
+
+ strategy:
+ matrix:
+ node-version: [16.x]
+
+ steps:
+ - uses: actions/checkout@v2
+ - name: Use Node.js ${{ matrix.node-version }}
+ uses: actions/setup-node@v1
+ with:
+ node-version: ${{ matrix.node-version }}
+ - run: npm i
+ - run: npm run build
+ - run: npm run start-test-server && npm run test
+
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 00016c0..8d0854f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -25,4 +25,5 @@ npm-debug.log
deps/
dist
-lib/ace
\ No newline at end of file
+lib/ace
+samples/*/build
\ No newline at end of file
diff --git a/package.json b/package.json
index 44daf15..5563a2c 100644
--- a/package.json
+++ b/package.json
@@ -1,14 +1,26 @@
{
"name": "ace-samples",
"version": "1.0.0",
+ "scripts": {
+ "build": "npm run build -w samples",
+ "start-test-server": "http-server --cors='*' samples",
+ "test": "mocha --timeout=5000"
+ },
"workspaces": [
"./samples/*"
],
"dependencies": {
- "ace-builds": "^1.15.3",
- "ace-code": "^1.15.3"
+ "ace-builds": "^1.31.2",
+ "ace-code": "^1.31.2",
+ "typescript": "^5.3.2"
},
"devDependencies": {
- "process": "^0.11.10"
+ "@types/chai": "^4.3.4",
+ "@types/mocha": "^5.2.7",
+ "chai": "^4.3.7",
+ "mocha": "^10.2.0",
+ "process": "^0.11.10",
+ "puppeteer": "^19.9.1",
+ "rimraf": "^5.0.1"
}
}
diff --git a/samples/ace-builds-parcel/package.json b/samples/ace-builds-parcel/package.json
index e470dea..b2e872e 100644
--- a/samples/ace-builds-parcel/package.json
+++ b/samples/ace-builds-parcel/package.json
@@ -2,6 +2,7 @@
"name": "ace-builds-parcel",
"version": "1.0.0",
"scripts": {
+ "build": "parcel build ./index.html --public-url ./",
"start": "parcel ./index.html"
},
"devDependencies": {
diff --git a/samples/ace-builds-vitejs/vite.config.js b/samples/ace-builds-vitejs/vite.config.js
index 3043bcd..866a437 100644
--- a/samples/ace-builds-vitejs/vite.config.js
+++ b/samples/ace-builds-vitejs/vite.config.js
@@ -1,5 +1,8 @@
-import { defineConfig } from 'vite'
+import {defineConfig} from 'vite'
export default defineConfig({
- base: '',
+ base: '',
+ worker: {
+ format: "es",
+ }
})
\ No newline at end of file
diff --git a/samples/ace-code-parcel/package.json b/samples/ace-code-parcel/package.json
index f1ac19f..8a7834a 100644
--- a/samples/ace-code-parcel/package.json
+++ b/samples/ace-code-parcel/package.json
@@ -2,6 +2,7 @@
"name": "ace-code-parcel",
"version": "1.0.0",
"scripts": {
+ "build": "parcel build ./index.html --public-url ./",
"start": "parcel ./index.html"
},
"devDependencies": {
diff --git a/samples/ace-code-vitejs-typescript/index.html b/samples/ace-code-vitejs-typescript/index.html
new file mode 100644
index 0000000..795f1ec
--- /dev/null
+++ b/samples/ace-code-vitejs-typescript/index.html
@@ -0,0 +1,12 @@
+
+
+
+
+
+ ace-builds-vitejs
+
+
+
+
+
+
diff --git a/samples/ace-code-vitejs-typescript/package.json b/samples/ace-code-vitejs-typescript/package.json
new file mode 100644
index 0000000..905f2cf
--- /dev/null
+++ b/samples/ace-code-vitejs-typescript/package.json
@@ -0,0 +1,15 @@
+{
+ "name": "ace-code-vitejs-typescript",
+ "version": "1.0.0",
+ "scripts": {
+ "dev": "vite",
+ "build": "vite build",
+ "test:tsc": "tsc --project tsconfig.json"
+ },
+ "devDependencies": {
+ "ace-linters": "^0.4.1",
+ "ace-code": "^1.15.3",
+ "vite": "^4.0.3"
+ },
+ "type": "module"
+}
diff --git a/samples/ace-code-vitejs-typescript/src/index.ts b/samples/ace-code-vitejs-typescript/src/index.ts
new file mode 100644
index 0000000..206b913
--- /dev/null
+++ b/samples/ace-code-vitejs-typescript/src/index.ts
@@ -0,0 +1,33 @@
+
+import {tokenize} from "ace-code/src/ext/simple_tokenizer";
+import type {Ace} from "ace-code";
+
+import ace from 'ace-code';
+import 'ace-code/esm-resolver';
+
+let editor = ace.edit("container", {
+ useWorker: false
+});
+editor.session.setValue("\n Hello world!
\n");
+editor.setTheme("ace/theme/eclipse");
+editor.session.setMode("ace/mode/html");
+
+import JavaScriptHighlightRules from "ace-code/src/mode/javascript_highlight_rules"
+const tokens = tokenize(document.body.innerHTML, JavaScriptHighlightRules as unknown as Ace.HighlightRules);
+console.log(tokens)
+
+
+export class WeirdEditSession extends ace.EditSession {
+ declare $modeId: string;
+
+ constructor(public uri: string, document: Ace.Document, mode: Ace.SyntaxMode) {
+ super(document, mode);
+ this.selection.on("changeCursor", this.handleCursorChange.bind(this));
+ this.on("changeTabSize", this.handleCursorChange.bind(this));
+ }
+
+ private handleCursorChange() {
+ const cursor = this.selection.getCursor();
+ console.log(cursor)
+ }
+}
diff --git a/samples/ace-code-vitejs-typescript/tsconfig.json b/samples/ace-code-vitejs-typescript/tsconfig.json
new file mode 100644
index 0000000..189abe2
--- /dev/null
+++ b/samples/ace-code-vitejs-typescript/tsconfig.json
@@ -0,0 +1,37 @@
+{
+ "compilerOptions": {
+ // Recommended by the documentation
+ "alwaysStrict": true,
+ // "exactOptionalPropertyTypes": true, // Good in theory, bad in practice
+ "strict": true,
+ "esModuleInterop": true,
+ "forceConsistentCasingInFileNames": true,
+ "skipLibCheck": true,
+
+ // Others
+ "lib": ["DOM"],
+ "target": "ES6", // output ES Modules
+ // "isolatedModules": true, // "Setting the isolatedModules flag tells TypeScript to warn you if you write certain code that can’t be correctly interpreted by a single-file transpilation process."
+ "experimentalDecorators": true,
+ "emitDecoratorMetadata": true,
+ "declaration": true, // emit *.d.ts files
+ "declarationMap": true,
+ "sourceMap": true,
+ "jsx": "react",
+ "outDir": ".lib/",
+ "moduleResolution": "node",
+ "baseUrl": ".",
+ "paths": {
+ "src/*": [
+ "src/*"
+ ],
+ "tests/*": [
+ "tests/*"
+ ]
+ }
+ },
+ "include": [ "src/**/*" ],
+ "exclude": [
+ "node_modules/**/*"
+ ]
+}
\ No newline at end of file
diff --git a/samples/ace-code-vitejs-typescript/vite.config.js b/samples/ace-code-vitejs-typescript/vite.config.js
new file mode 100644
index 0000000..3043bcd
--- /dev/null
+++ b/samples/ace-code-vitejs-typescript/vite.config.js
@@ -0,0 +1,5 @@
+import { defineConfig } from 'vite'
+
+export default defineConfig({
+ base: '',
+})
\ No newline at end of file
diff --git a/samples/ace-code-vitejs/src/index.js b/samples/ace-code-vitejs/src/index.js
index 8d59d6b..61b62c0 100644
--- a/samples/ace-code-vitejs/src/index.js
+++ b/samples/ace-code-vitejs/src/index.js
@@ -1,6 +1,6 @@
-import ace from 'ace-builds';
-import 'ace-builds/esm-resolver';
-import "./chrome.css.js"
+import ace from 'ace-code';
+import 'ace-code/esm-resolver';
+
//^ you could use direct imports instead like
//import 'ace-builds/src-noconflict/mode-html'; for HTML mode
//or import "ace-builds/src-noconflict/theme-eclipse.js"; for theme
diff --git a/samples/ace-code-vitejs/vite.config.js b/samples/ace-code-vitejs/vite.config.js
index 3043bcd..ce7b98c 100644
--- a/samples/ace-code-vitejs/vite.config.js
+++ b/samples/ace-code-vitejs/vite.config.js
@@ -2,4 +2,7 @@ import { defineConfig } from 'vite'
export default defineConfig({
base: '',
+ worker: {
+ format: "es",
+ }
})
\ No newline at end of file
diff --git a/samples/index.html b/samples/index.html
new file mode 100644
index 0000000..39a2214
--- /dev/null
+++ b/samples/index.html
@@ -0,0 +1,44 @@
+
+
+
+
+ Ace samples demo
+
+
+
+
+
+
+
diff --git a/samples/react-ace-example/package.json b/samples/react-ace-example/package.json
index d8608da..4809eab 100644
--- a/samples/react-ace-example/package.json
+++ b/samples/react-ace-example/package.json
@@ -3,7 +3,7 @@
"version": "1.0.0",
"scripts": {
"dev": "vite",
- "build": "vite build"
+ "build": "vite build --base ./"
},
"devDependencies": {
"ace-linters": "^0.4.1",
diff --git a/test/general-ui.tests.js b/test/general-ui.tests.js
new file mode 100644
index 0000000..2237577
--- /dev/null
+++ b/test/general-ui.tests.js
@@ -0,0 +1,99 @@
+var {expect} = require("chai");
+var puppeteer = require("puppeteer");
+
+const opts = {
+ headless: "new"
+};
+
+describe("General ui tests", function () {
+ let browser;
+ let page;
+ let errors = [];
+ let sampleSelectorIDs = [
+ "ace-builds-cdn",
+ "ace-builds-parcel",
+ "ace-builds-vitejs",
+ "ace-builds-webpack",
+ "ace-code-parcel",
+ "ace-code-vitejs",
+ "ace-code-webpack",
+ "react-ace-example"
+ ];
+
+ before(async function () {
+ browser = await puppeteer.launch(opts);
+ page = (await browser.pages())[0];
+ page.on("console", function(err) {
+ if (err.type() == "error" && err.location().url != "http://localhost:8080/favicon.ico")
+ errors.push(err.text());
+ }).on('pageerror', ({message}) => errors.push(message));
+ await page.goto("http://localhost:8080", {
+ waitUntil: 'domcontentloaded',
+ });
+
+ shouldNotHaveErrors();
+ });
+
+ function shouldNotHaveErrors() {
+ try {
+ expect(errors.length).to.eql(0);
+ } catch (e) {
+ errors.length = 0;
+ throw e;
+ }
+ }
+
+ function checkSampleResponse(response) {
+ shouldNotHaveErrors();
+ }
+
+ async function shouldGoToSamplePage(href) {
+ var response = await page.goto("http://localhost:8080/" + href, {
+ waitUntil: 'domcontentloaded',
+ });
+
+ try {
+ checkSampleResponse(response);
+ await page.goto("http://localhost:8080", {
+ waitUntil: 'domcontentloaded',
+ });
+ } catch (e) {
+ await page.goto("http://localhost:8080", {
+ waitUntil: 'domcontentloaded',
+ });
+ throw e;
+ }
+ }
+
+ async function shouldOpenClickedLink(hrefSelectorID) {
+ const navigationPromise = page.waitForNavigation();
+
+ hrefSelectorID = "#" + hrefSelectorID;
+ await page.waitForSelector(hrefSelectorID)
+ await page.click(hrefSelectorID);
+
+ var response = await navigationPromise;
+
+ try {
+ checkSampleResponse(response);
+ await page.goBack({
+ waitUntil: 'domcontentloaded',
+ });
+ } catch (e) {
+ await page.goBack({
+ waitUntil: 'domcontentloaded',
+ });
+ throw e;
+ }
+ }
+
+ sampleSelectorIDs.forEach((selectorID) => {
+ it(selectorID, async function () {
+ await shouldOpenClickedLink(selectorID);
+ })
+ })
+
+ after(async function () {
+ await browser.close();
+ });
+});
\ No newline at end of file