Skip to content

Commit ab8c589

Browse files
committed
Merge remote-tracking branch 'origin/main' into ai-agent
2 parents 04facd6 + 71d2fef commit ab8c589

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+1328
-382
lines changed

config.xml

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -46,17 +46,7 @@
4646
<action android:name="android.intent.action.EDIT" />
4747
<category android:name="android.intent.category.DEFAULT" />
4848
<category android:name="android.intent.category.LAUNCHER" />
49-
<data android:mimeType="text/*"/>
50-
<data android:mimeType="xml/*" />
51-
<data android:mimeType="application/text" />
52-
<data android:mimeType="application/xml" />
53-
<data android:mimeType="application/json" />
54-
<data android:mimeType="application/javascript" />
55-
<data android:mimeType="application/x-sh" />
56-
<data android:mimeType="application/octet-stream"/>
57-
<data pathPattern=".*\.txt"/>
58-
<data pathPattern=".*\.xml"/>
59-
<data pathPattern=".*\.json"/>
49+
<data android:mimeType="*/*"/>
6050
</intent-filter>
6151
<!-- Allow app to open using url from browser -->
6252
<intent-filter android:autoVerify="true">

src/ace/modelist.js

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,44 @@ export function initModes() {
66
"ace/ext/modelist",
77
["require", "exports", "module"],
88
function (require, exports, module) {
9+
/**
10+
* Calculates a specificity score for a mode.
11+
* Higher score means more specific.
12+
* - Anchored patterns (e.g., "^Dockerfile") get a base score of 1000.
13+
* - Non-anchored patterns (extensions) are scored by length.
14+
*/
15+
function getModeSpecificityScore(modeInstance) {
16+
const extensionsStr = modeInstance.extensions;
17+
if (!extensionsStr) return 0;
18+
19+
const patterns = extensionsStr.split("|");
20+
let maxScore = 0;
21+
22+
for (const pattern of patterns) {
23+
let currentScore = 0;
24+
if (pattern.startsWith("^")) {
25+
// Exact filename match or anchored pattern
26+
currentScore = 1000 + (pattern.length - 1); // Subtract 1 for '^'
27+
} else {
28+
// Extension match
29+
currentScore = pattern.length;
30+
}
31+
if (currentScore > maxScore) {
32+
maxScore = currentScore;
33+
}
34+
}
35+
return maxScore;
36+
}
937
module.exports = {
1038
getModeForPath(path) {
1139
let mode = modesByName.text;
1240
let fileName = path.split(/[\/\\]/).pop();
13-
for (const iMode of modes) {
41+
// Sort modes by specificity (descending) to check most specific first
42+
const sortedModes = [...modes].sort((a, b) => {
43+
return getModeSpecificityScore(b) - getModeSpecificityScore(a);
44+
});
45+
46+
for (const iMode of sortedModes) {
1447
if (iMode.supportsFile?.(fileName)) {
1548
mode = iMode;
1649
break;

src/components/quickTools/items.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,17 @@ export default [
3434
item("command-palette", "keyboard_control", "command", "openCommandPalette"),
3535
item("alt-key", "letters", "alt", undefined, "alt", false),
3636
item("meta-key", "letters", "meta", undefined, "meta", false),
37+
item("home-key", "letters", "key", 36, "home", true),
38+
item("end-key", "letters", "key", 35, "end", true),
39+
item("pageup-key", "letters", "key", 33, "pgup", true),
40+
item("pagedown-key", "letters", "key", 34, "pgdn", true),
41+
item("delete-key", "letters", "key", 46, "del", true),
42+
item("tilde", "letters", "insert", "~", "~"),
43+
item("backtick", "letters", "insert", "`", "`"),
44+
item("hash", "letters", "insert", "#", "#"),
45+
item("dollar", "letters", "insert", "$", "$"),
46+
item("modulo", "letters", "insert", "%", "%"),
47+
item("caret", "letters", "insert", "^", "^"),
3748
];
3849

3950
/**

src/components/sidebar/style.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,10 @@ body.no-animation {
124124
width: 100%;
125125
height: 100%;
126126

127+
&.files {
128+
overflow-x: auto;
129+
}
130+
127131
> .list {
128132
width: 100%;
129133
max-width: 100%;

src/dialogs/select.js

Lines changed: 64 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import Checkbox from "components/checkbox";
22
import tile from "components/tile";
3+
import DOMPurify from "dompurify";
34
import actionStack from "lib/actionStack";
45
import restoreTheme from "lib/restoreTheme";
56

@@ -20,6 +21,8 @@ import restoreTheme from "lib/restoreTheme";
2021
* @property {boolean} [disabled]
2122
* @property {string} [letters]
2223
* @property {boolean} [checkbox]
24+
* @property {HTMLElement} [tailElement]
25+
* @property {function(Event):void} [ontailclick]
2326
*/
2427

2528
/**
@@ -43,33 +46,45 @@ function select(title, items, options = {}) {
4346
// elements
4447
const $mask = <span className="mask" onclick={cancel}></span>;
4548
const $list = tag("ul", {
46-
className: "scroll" + !textTransform ? " no-text-transform" : "",
49+
className: `scroll${!textTransform ? " no-text-transform" : ""}`,
4750
});
51+
const $titleSpan = title ? (
52+
<strong className="title">{title}</strong>
53+
) : null;
4854
const $select = (
4955
<div className="prompt select">
50-
{title ? <strong className="title">{title}</strong> : ""}
51-
{$list}
56+
{$titleSpan ? [$titleSpan, $list] : $list}
5257
</div>
5358
);
5459

60+
// Track tail click handlers for cleanup
61+
const tailClickHandlers = new Map();
62+
5563
items.map((item) => {
5664
let lead,
57-
tail,
65+
tail = null,
5866
itemOptions = {
5967
value: null,
6068
text: null,
6169
icon: null,
6270
disabled: false,
6371
letters: "",
6472
checkbox: null,
73+
tailElement: null,
74+
ontailclick: null,
6575
};
6676

6777
// init item options
6878
if (typeof item === "object") {
6979
if (Array.isArray(item)) {
80+
// This format does NOT support custom tail or handlers so pass object :)
7081
Object.keys(itemOptions).forEach(
7182
(key, i) => (itemOptions[key] = item[i]),
7283
);
84+
85+
item.map((o, i) => {
86+
if (typeof o === "boolean" && i > 1) itemOptions.disabled = !o;
87+
});
7388
} else {
7489
itemOptions = Object.assign({}, itemOptions, item);
7590
}
@@ -78,7 +93,7 @@ function select(title, items, options = {}) {
7893
itemOptions.text = item;
7994
}
8095

81-
// handle icon
96+
// handle icon (lead)
8297
if (itemOptions.icon) {
8398
if (itemOptions.icon === "letters" && !!itemOptions.letters) {
8499
lead = (
@@ -89,8 +104,10 @@ function select(title, items, options = {}) {
89104
}
90105
}
91106

92-
// handle checkbox
93-
if (itemOptions.checkbox != null) {
107+
// handle tail (checkbox or custom element)
108+
if (itemOptions.tailElement) {
109+
tail = itemOptions.tailElement;
110+
} else if (itemOptions.checkbox != null) {
94111
tail = Checkbox({
95112
checked: itemOptions.checkbox,
96113
});
@@ -99,7 +116,12 @@ function select(title, items, options = {}) {
99116
const $item = tile({
100117
lead,
101118
tail,
102-
text: <span className="text" innerHTML={itemOptions.text}></span>,
119+
text: (
120+
<span
121+
className="text"
122+
innerHTML={DOMPurify.sanitize(itemOptions.text)}
123+
></span>
124+
),
103125
});
104126

105127
$item.tabIndex = "0";
@@ -109,13 +131,39 @@ function select(title, items, options = {}) {
109131
$defaultVal = $item;
110132
}
111133

112-
// handle events
113-
$item.onclick = function () {
134+
$item.onclick = function (e) {
135+
// Check if clicked element or any parent up to the item has data-action
136+
let target = e.target;
137+
while (target && target !== $item) {
138+
if (target.hasAttribute("data-action")) {
139+
// Stop propagation and prevent default
140+
e.stopPropagation();
141+
e.preventDefault();
142+
return false;
143+
}
144+
target = target.parentElement;
145+
}
146+
114147
if (!itemOptions.value) return;
115148
if (hideOnSelect) hide();
116149
res(itemOptions.value);
117150
};
118151

152+
// Handle tail click event if a custom tail and handler are provided
153+
if (itemOptions.tailElement && itemOptions.ontailclick && tail) {
154+
// Apply the pointer-events: all directly to the tail element
155+
tail.style.pointerEvents = "all";
156+
157+
const tailClickHandler = function (e) {
158+
e.stopPropagation();
159+
e.preventDefault();
160+
itemOptions.ontailclick.call($item, e);
161+
};
162+
163+
tail.addEventListener("click", tailClickHandler);
164+
tailClickHandlers.set(tail, tailClickHandler);
165+
}
166+
119167
$list.append($item);
120168
});
121169

@@ -134,7 +182,7 @@ function select(title, items, options = {}) {
134182
function cancel() {
135183
hide();
136184
if (typeof options.onCancel === "function") options.onCancel();
137-
if (rejectOnCancel) reject();
185+
if (rejectOnCancel) rej();
138186
}
139187

140188
function hideSelect() {
@@ -152,6 +200,11 @@ function select(title, items, options = {}) {
152200
hideSelect();
153201
let listItems = [...$list.children];
154202
listItems.map((item) => (item.onclick = null));
203+
// Clean up tail click handlers
204+
tailClickHandlers.forEach((handler, element) => {
205+
element.removeEventListener("click", handler);
206+
});
207+
tailClickHandlers.clear();
155208
}
156209
});
157210
}

src/lang/ar-ye.json

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -392,5 +392,16 @@
392392
"notifications": "Notifications",
393393
"no_unread_notifications": "No unread notifications",
394394
"should_use_current_file_for_preview": "Should use Current File For preview instead of default (index.html)",
395-
"fade fold widgets": "Fade Fold Widgets"
395+
"fade fold widgets": "Fade Fold Widgets",
396+
"quicktools:home-key": "Home Key",
397+
"quicktools:end-key": "End Key",
398+
"quicktools:pageup-key": "PageUp Key",
399+
"quicktools:pagedown-key": "PageDown Key",
400+
"quicktools:delete-key": "Delete Key",
401+
"quicktools:tilde": "Insert tilde symbol",
402+
"quicktools:backtick": "Insert backtick",
403+
"quicktools:hash": "Insert Hash symbol",
404+
"quicktools:dollar": "Insert dollar symbol",
405+
"quicktools:modulo": "Insert modulo/percent symbol",
406+
"quicktools:caret": "Insert caret symbol"
396407
}

src/lang/be-by.json

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -393,5 +393,16 @@
393393
"notifications": "Апавяшчэнні",
394394
"no_unread_notifications": "Няма непрачытаных апавяшчэнняў",
395395
"should_use_current_file_for_preview": "Should use Current File For preview instead of default (index.html)",
396-
"fade fold widgets": "Fade Fold Widgets"
396+
"fade fold widgets": "Fade Fold Widgets",
397+
"quicktools:home-key": "Home Key",
398+
"quicktools:end-key": "End Key",
399+
"quicktools:pageup-key": "PageUp Key",
400+
"quicktools:pagedown-key": "PageDown Key",
401+
"quicktools:delete-key": "Delete Key",
402+
"quicktools:tilde": "Insert tilde symbol",
403+
"quicktools:backtick": "Insert backtick",
404+
"quicktools:hash": "Insert Hash symbol",
405+
"quicktools:dollar": "Insert dollar symbol",
406+
"quicktools:modulo": "Insert modulo/percent symbol",
407+
"quicktools:caret": "Insert caret symbol"
397408
}

src/lang/bn-bd.json

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -392,5 +392,16 @@
392392
"notifications": "Notifications",
393393
"no_unread_notifications": "No unread notifications",
394394
"should_use_current_file_for_preview": "Should use Current File For preview instead of default (index.html)",
395-
"fade fold widgets": "Fade Fold Widgets"
395+
"fade fold widgets": "Fade Fold Widgets",
396+
"quicktools:home-key": "Home Key",
397+
"quicktools:end-key": "End Key",
398+
"quicktools:pageup-key": "PageUp Key",
399+
"quicktools:pagedown-key": "PageDown Key",
400+
"quicktools:delete-key": "Delete Key",
401+
"quicktools:tilde": "Insert tilde symbol",
402+
"quicktools:backtick": "Insert backtick",
403+
"quicktools:hash": "Insert Hash symbol",
404+
"quicktools:dollar": "Insert dollar symbol",
405+
"quicktools:modulo": "Insert modulo/percent symbol",
406+
"quicktools:caret": "Insert caret symbol"
396407
}

src/lang/cs-cz.json

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -392,5 +392,16 @@
392392
"notifications": "Notifications",
393393
"no_unread_notifications": "No unread notifications",
394394
"should_use_current_file_for_preview": "Should use Current File For preview instead of default (index.html)",
395-
"fade fold widgets": "Fade Fold Widgets"
395+
"fade fold widgets": "Fade Fold Widgets",
396+
"quicktools:home-key": "Home Key",
397+
"quicktools:end-key": "End Key",
398+
"quicktools:pageup-key": "PageUp Key",
399+
"quicktools:pagedown-key": "PageDown Key",
400+
"quicktools:delete-key": "Delete Key",
401+
"quicktools:tilde": "Insert tilde symbol",
402+
"quicktools:backtick": "Insert backtick",
403+
"quicktools:hash": "Insert Hash symbol",
404+
"quicktools:dollar": "Insert dollar symbol",
405+
"quicktools:modulo": "Insert modulo/percent symbol",
406+
"quicktools:caret": "Insert caret symbol"
396407
}

src/lang/de-de.json

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -392,5 +392,16 @@
392392
"notifications": "Benachrichtigungen",
393393
"no_unread_notifications": "Keine ungelesenen Benachrichtigungen",
394394
"should_use_current_file_for_preview": "Sollte die aktuelle Datei für die Vorschau verwenden, anstatt dem Standard (index.html)",
395-
"fade fold widgets": "Fade Fold Widgets"
395+
"fade fold widgets": "Fade Fold Widgets",
396+
"quicktools:home-key": "Home Key",
397+
"quicktools:end-key": "End Key",
398+
"quicktools:pageup-key": "PageUp Key",
399+
"quicktools:pagedown-key": "PageDown Key",
400+
"quicktools:delete-key": "Delete Key",
401+
"quicktools:tilde": "Insert tilde symbol",
402+
"quicktools:backtick": "Insert backtick",
403+
"quicktools:hash": "Insert Hash symbol",
404+
"quicktools:dollar": "Insert dollar symbol",
405+
"quicktools:modulo": "Insert modulo/percent symbol",
406+
"quicktools:caret": "Insert caret symbol"
396407
}

0 commit comments

Comments
 (0)