diff --git a/.devcontainer/devcontainer-lock.json b/.devcontainer/devcontainer-lock.json new file mode 100644 index 000000000..dfe2dfb8a --- /dev/null +++ b/.devcontainer/devcontainer-lock.json @@ -0,0 +1,14 @@ +{ + "features": { + "ghcr.io/devcontainers/features/node:2.0": { + "version": "2.0.0", + "resolved": "ghcr.io/devcontainers/features/node@sha256:fedd4c11f7adfb64283b578dddc7da906728daa25fa293351c9d913231acf12f", + "integrity": "sha256:fedd4c11f7adfb64283b578dddc7da906728daa25fa293351c9d913231acf12f" + }, + "ghcr.io/nordcominc/devcontainer-features/android-sdk:1": { + "version": "1.2.0", + "resolved": "ghcr.io/nordcominc/devcontainer-features/android-sdk@sha256:c3e0c7e1b12fce18a257e163ade8515e534e58a7edad10dfb6d1fb1a250a307e", + "integrity": "sha256:c3e0c7e1b12fce18a257e163ade8515e534e58a7edad10dfb6d1fb1a250a307e" + } + } +} \ No newline at end of file diff --git a/.gitignore b/.gitignore index 861840531..5892773b0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,16 +1,20 @@ -node_modules -/build.json -/www/build -/plugins -/platforms -/keystore.jks -/platforms/android/debug-signing.properties -/platforms/android/release-signing.properties -**/*/.DS_Store -.DS_Store -pnpm-lock.yaml -.zed -.idea -ace-builds -fdroid.bool -tsconfig.tsbuildinfo \ No newline at end of file +/node_modules +/build.json +/www/build +/plugins +/platforms +/keystore.jks +/platforms/android/debug-signing.properties +/platforms/android/release-signing.properties +**/*/.DS_Store +.DS_Store +pnpm-lock.yaml +.zed +.idea +ace-builds +fdroid.bool +CLAUDE.md +graphify-out/ +.graphify_python +.gradle/ +local.properties diff --git a/gradle/gradle-daemon-jvm.properties b/gradle/gradle-daemon-jvm.properties new file mode 100644 index 000000000..235c26157 --- /dev/null +++ b/gradle/gradle-daemon-jvm.properties @@ -0,0 +1,12 @@ +#This file is generated by updateDaemonJvm +toolchainUrl.FREE_BSD.AARCH64=https\://api.foojay.io/disco/v3.0/ids/491f83666ae7f4d6ebb28fee72ebb035/redirect +toolchainUrl.FREE_BSD.X86_64=https\://api.foojay.io/disco/v3.0/ids/0d1a1acdc708062093673f65aa9aba4b/redirect +toolchainUrl.LINUX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/491f83666ae7f4d6ebb28fee72ebb035/redirect +toolchainUrl.LINUX.X86_64=https\://api.foojay.io/disco/v3.0/ids/0d1a1acdc708062093673f65aa9aba4b/redirect +toolchainUrl.MAC_OS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/7083b89563e7ce20943037b8cd2b8cc2/redirect +toolchainUrl.MAC_OS.X86_64=https\://api.foojay.io/disco/v3.0/ids/060bbb778a1f55ea705fdebd2ccfeab9/redirect +toolchainUrl.UNIX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/491f83666ae7f4d6ebb28fee72ebb035/redirect +toolchainUrl.UNIX.X86_64=https\://api.foojay.io/disco/v3.0/ids/0d1a1acdc708062093673f65aa9aba4b/redirect +toolchainUrl.WINDOWS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/d09679dc60fe5aa05ef7d03efdefac20/redirect +toolchainUrl.WINDOWS.X86_64=https\://api.foojay.io/disco/v3.0/ids/ed4e3bf2f5e7c5d9aabc4cbd8acd555e/redirect +toolchainVersion=21 diff --git a/package-lock.json b/package-lock.json index a512fe0a0..e06b2361d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -95,6 +95,7 @@ "@rspack/cli": "^2.0.0", "@rspack/core": "^2.0.0", "@types/ace": "^0.0.52", + "@types/cordova": "^11.0.3", "@types/url-parse": "^1.4.11", "autoprefixer": "^10.5.0", "babel-loader": "^10.1.1", @@ -3815,6 +3816,13 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/cordova": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@types/cordova/-/cordova-11.0.3.tgz", + "integrity": "sha512-kyuRQ40/NWQVhqGIHq78Ehu2Bf9Mlg0LhmSmis6ZFJK7z933FRfYi8tHe/k/0fB+PGfCf95rJC6TO7dopaFvAg==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/d3": { "version": "7.4.3", "resolved": "https://registry.npmjs.org/@types/d3/-/d3-7.4.3.tgz", diff --git a/package.json b/package.json index 09ec587b0..337f4539b 100644 --- a/package.json +++ b/package.json @@ -70,6 +70,7 @@ "@rspack/cli": "^2.0.0", "@rspack/core": "^2.0.0", "@types/ace": "^0.0.52", + "@types/cordova": "^11.0.3", "@types/url-parse": "^1.4.11", "autoprefixer": "^10.5.0", "babel-loader": "^10.1.1", diff --git a/src/cm/lineBreakMarker.ts b/src/cm/lineBreakMarker.ts new file mode 100644 index 000000000..ea8eda65e --- /dev/null +++ b/src/cm/lineBreakMarker.ts @@ -0,0 +1,68 @@ +import { Decoration, DecorationSet, ViewPlugin, WidgetType, EditorView, ViewUpdate } from "@codemirror/view"; +import { RangeSetBuilder } from "@codemirror/state"; + +class NewlineWidget extends WidgetType { + toDOM(): HTMLElement { + let span = document.createElement("span"); + span.textContent = "¬"; + span.className = "cm-newline-marker"; + return span; + } + eq(other: WidgetType): boolean { + return other instanceof NewlineWidget; + } +} + +export const lineBreakMarkerPlugin = ViewPlugin.fromClass( + class { + decorations: DecorationSet; + + constructor(view: EditorView) { + this.decorations = this.getDecorations(view); + } + + update(update: ViewUpdate) { + if (update.docChanged || update.viewportChanged) { + this.decorations = this.getDecorations(update.view); + } + } + + getDecorations(view: EditorView): DecorationSet { + let builder = new RangeSetBuilder(); + let lastLineNumber = -1; + + for (let { from, to } of view.visibleRanges) { + for (let pos = from; pos <= to; ) { + let line = view.state.doc.lineAt(pos); + + if (line.number > lastLineNumber && line.number < view.state.doc.lines) { + let deco = Decoration.widget({ + widget: new NewlineWidget(), + side: 1, + }); + builder.add(line.to, line.to, deco); + lastLineNumber = line.number; + } + + pos = line.to + 1; + } + } + return builder.finish(); + } + }, + { + decorations: (v) => v.decorations, + }, +); + +export const lineBreakMarkerTheme = EditorView.theme({ + ".cm-newline-marker": { + color: "var(--cm-space-marker-color, rgba(127, 127, 127, 0.6))", + pointerEvents: "none", + userSelect: "none", + }, +}); + +export const lineBreakMarker = [lineBreakMarkerPlugin, lineBreakMarkerTheme]; + +export default lineBreakMarker; diff --git a/src/cordova-custom.d.ts b/src/cordova-custom.d.ts new file mode 100644 index 000000000..e78a47913 --- /dev/null +++ b/src/cordova-custom.d.ts @@ -0,0 +1,5 @@ +declare module 'cordova/channel'; +declare module 'cordova/exec'; +interface Cordova { + fireDocumentEvent(eventName: string, data?: any): void; +} diff --git a/src/lang/en-us.json b/src/lang/en-us.json index 4430a21da..f5dee6470 100644 --- a/src/lang/en-us.json +++ b/src/lang/en-us.json @@ -677,7 +677,7 @@ "settings-info-editor-scroll-settings": "Adjust scrollbar size, speed, and gesture behavior.", "settings-info-editor-shift-click-selection": "Extend selection with Shift + tap or click.", "settings-info-editor-show-share-button": "Show share button in selection menu.", - "settings-info-editor-show-spaces": "Display visible whitespace markers.", + "settings-info-editor-show-spaces": "Display visible whitespace and line break markers.", "settings-info-editor-soft-tab": "Insert spaces instead of tab characters.", "settings-info-editor-tab-size": "Set how many spaces each tab step uses.", "settings-info-editor-teardrop-size": "Set the cursor handle size for touch editing.", diff --git a/src/lang/hu-hu.json b/src/lang/hu-hu.json index 2c78d6bcc..6505db2c3 100644 --- a/src/lang/hu-hu.json +++ b/src/lang/hu-hu.json @@ -660,7 +660,7 @@ "settings-info-editor-rtl-text": "Jobbról balra haladó viselkedés váltása soronként.", "settings-info-editor-scroll-settings": "Görgetősáv méretének, sebességének és az ujjmozdulatok viselkedésének beállítása.", "settings-info-editor-shift-click-selection": "Kijelölés kiterjesztése a Shift + érintés vagy kattintás használatával.", - "settings-info-editor-show-spaces": "Látható szóközjelölők megjelenítése.", + "settings-info-editor-show-spaces": "Látható szóköz- és sortörésjelölők megjelenítése.", "settings-info-editor-soft-tab": "Szóközök beszúrása tabulátorkarakterek helyett.", "settings-info-editor-tab-size": "Állítsa be, hány szóközt használjon egy tabulátorlépés.", "settings-info-editor-teardrop-size": "Kurzorfogantyú méretének beállítása az érintéses szerkesztéshez.", diff --git a/src/lib/editorManager.js b/src/lib/editorManager.js index 444afe505..b37f8dc80 100644 --- a/src/lib/editorManager.js +++ b/src/lib/editorManager.js @@ -62,6 +62,7 @@ import { setScrollPosition, } from "cm/editorUtils"; import indentGuides from "cm/indentGuides"; +import { lineBreakMarker } from "cm/lineBreakMarker"; import rainbowBrackets, { getRainbowBracketColors } from "cm/rainbowBrackets"; import { getThemeConfig, getThemeExtensions } from "cm/themes"; import list from "components/collapsableList"; @@ -256,6 +257,8 @@ async function EditorManager($header, $body) { const rainbowCompartment = new Compartment(); // Compartment for indent guides const indentGuidesCompartment = new Compartment(); + // Compartment for line break marker + const lineBreakMarkerCompartment = new Compartment(); // Compartment for read-only toggling const readOnlyCompartment = new Compartment(); // Compartment for language mode (allows async loading/reconfigure) @@ -450,6 +453,15 @@ async function EditorManager($header, $body) { : []; }, }, + { + keys: ["showSpaces", "textWrap"], + compartments: [lineBreakMarkerCompartment], + build() { + const showSpaces = !!appSettings?.value?.showSpaces; + const textWrap = !!appSettings?.value?.textWrap; + return showSpaces && textWrap ? lineBreakMarker : []; + }, + }, { keys: ["fadeFoldWidgets"], compartments: [foldThemeCompartment], diff --git a/src/plugins/admob/src/www/ads/index.ts b/src/plugins/admob/src/www/ads/index.ts index 1009d4a66..3c0886481 100644 --- a/src/plugins/admob/src/www/ads/index.ts +++ b/src/plugins/admob/src/www/ads/index.ts @@ -1,6 +1,7 @@ export * from "./app-open"; export * from "./banner"; -export { MobileAd, MobileAdOptions } from "./base"; +export { MobileAd } from "./base"; +export type { MobileAdOptions } from "./base"; export * from "./interstitial"; export * from "./native"; export * from "./rewarded"; diff --git a/src/plugins/admob/src/www/ads/webview.ts b/src/plugins/admob/src/www/ads/webview.ts index d444d6d6c..b5bf43a52 100644 --- a/src/plugins/admob/src/www/ads/webview.ts +++ b/src/plugins/admob/src/www/ads/webview.ts @@ -107,7 +107,7 @@ export class WebViewAd extends MobileAd { return false; } - private nodeScriptReplace(node) { + private nodeScriptReplace(node: any) { if (this.isNodeScript(node) === true) { node.parentNode.replaceChild(this.nodeScriptClone(node), node); } else { @@ -119,7 +119,7 @@ export class WebViewAd extends MobileAd { return node; } - private nodeScriptClone(node) { + private nodeScriptClone(node: any) { const script = document.createElement("script"); script.text = node.innerHTML; const attrs = node.attributes; @@ -129,7 +129,7 @@ export class WebViewAd extends MobileAd { return script; } - private isNodeScript(node) { + private isNodeScript(node: any) { return node.tagName === "SCRIPT"; } @@ -142,7 +142,7 @@ export class WebViewAd extends MobileAd { } } - private historySetPage(page: string, parameters = {}) { + private historySetPage(page: string, parameters: Record = {}) { const _parameters: string[] = []; for (const name in parameters) { _parameters.push(`${name}=${encodeURI(parameters[name])}`);