T-525: Mojo's long-press on a link or an image gets its own commands — the shell claims those holds through the widget assistant's eventFired (the framework widget had none, so the adapter's hit test never reached it) and offers Open in New Card / Share Link / Copy URL (cavekit-mojo-ui R6); Mochi logs its clipboard copy and paste sizes (the paste reads 5 chars and still inserts nothing — under investigation)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
NotAlexNoyleandClaude Fable 5.1 committed 2026-10-24 23:35:17 -04:00
1 parent 414d284291
commit 82e086d186
4 files changed
+76 -3

No files matched your search

+4 -1
View File
@@ -1053,7 +1053,9 @@ enyo.kind({
if (done) { return; }
done = true;
window.jihadClip = null;
if (!enyo.jihad.setClipboard(String(text))) { enyo.jihad.toast("info", "The text could not be copied."); return; }
var set = enyo.jihad.setClipboard(String(text));
enyo.log("[JIHAD-CLIP] copied " + String(text).length + " chars, clipboard set: " + set);
if (!set) { enyo.jihad.toast("info", "The text could not be copied."); return; }
// True from this moment whatever the cut does; "Cut." replaces it if the engine
// confirms the deletion (the "page-cut" notification).
enyo.jihad.toast("info", "Copied.");
@@ -1077,6 +1079,7 @@ enyo.kind({
var view = this.$.view;
enyo.jihad.getClipboard(function(text) {
var parts, i;
enyo.log("[JIHAD-CLIP] paste read " + (text ? text.length : 0) + " chars");
if (!text) { enyo.jihad.toast("info", "The clipboard is empty."); }
else if (text.length > 262144) { enyo.jihad.toast("info", "The clipboard holds too much text to paste here."); }
else {
+70
View File
@@ -398,6 +398,25 @@ MainAssistant.prototype.adoptViewportModel = function () {
this.metaViewport = new Mojo.WebView.MetaViewport(initialScale, minimumScale, maximumScale,
width, height, userScalable);
};
// T-525 (the emulated finger, 2026-10-24): before the adapter acts on a tap or a hold it asks its
// eventListener — this widget assistant — `eventFired(event, info)` with the hit test; a true
// answer claims the event. Mojo.Widget.WebView has no such method, so every hold fell through to
// the engine's context event and a held link got the text commands only (Copy / Select All /
// Reload / Find on Page). As the Mochi shell's JihadWebView.eventFired: a hold on a link or an
// image is claimed and gets its own commands; a tap and any other hold fall through (claiming a
// tap would stop every tap on the page).
wa.eventFired = function (event, info) {
if (!event || event.type !== "mousehold" || !info || info.isNull) {
return false;
}
var link = info.isLink ? String(info.linkUrl || "") : "";
var image = info.isImage ? String(info.imageUrl || "") : "";
if (!link && !image) {
return false;
}
self.showHoldMenu({linkUrl: link, linkText: String(info.linkText || ""), imageUrl: image, altText: String(info.altText || "")});
return true;
};
var at = function (event) {
var node = wa.adapter, r = node.getBoundingClientRect();
return {x: Math.round(event.centerX - r.left), y: Math.round(event.centerY - r.top)};
@@ -929,6 +948,57 @@ MainAssistant.prototype.handlePageHold = function (text) {
});
};
//* The commands for a held link or image (T-525): a new card, a share, the address copied.
MainAssistant.prototype.showHoldMenu = function (held) {
var items = [];
this.held = held;
if (held.linkUrl) {
items.push({label: $L("Open in New Card"), command: "hold-open"});
items.push({label: $L("Share Link"), command: "hold-share"});
items.push({label: $L("Copy URL"), command: "hold-copy"});
}
if (held.imageUrl) {
items.push({label: $L("Open Image in New Card"), command: "hold-open-image"});
items.push({label: $L("Copy Image URL"), command: "hold-copy-image"});
}
this.controller.popupSubmenu({
onChoose: this.handleHoldChoice.bind(this),
items: items
});
};
MainAssistant.prototype.handleHoldChoice = function (command) {
var held = this.held || {}, url;
if (command === "hold-open" || command === "hold-open-image") {
// Web addresses only, as window.open is: a page's file: or data: link must not reach a new card.
url = command === "hold-open" ? held.linkUrl : held.imageUrl;
if (!/^(https?|ftp):/i.test(url)) {
JihadToast.show("info", $L("Only web addresses open in a new card."));
return;
}
this.openNewCard(url);
} else if (command === "hold-copy" || command === "hold-copy-image") {
url = command === "hold-copy" ? held.linkUrl : held.imageUrl;
try {
this.controller.stageController.setClipboard(url, false);
JihadToast.show("info", $L("Address copied."));
} catch (e) {
JihadToast.show("info", $L("The address could not be copied."));
}
} else if (command === "hold-share") {
this.controller.serviceRequest("palm://com.palm.applicationManager", {
method: "launch",
parameters: {
id: "com.palm.app.email",
params: {summary: held.linkText || $L("Check out this link..."), text: held.linkUrl}
},
onFailure: function (response) {
Mojo.Log.warn("[Jihad] share failed: %j", response);
}
});
}
};
MainAssistant.prototype.handlePageMenuChoice = function (command) {
switch (command) {
case "page-select-all":
+1 -1
View File
@@ -80,7 +80,7 @@ Reference: `app-mojo/README.md`, `docs/IPC-CONTRACT.md`, the Mojo framework docs
- [x] **Find** is in the row, as an icon (a magnifying glass), not a text item. *(Added 2026-08-05 on user report "there is no find UI", then "make find a magnifying glass instead of text": a text item is the one thing in the row that cannot be circular, and the row reads as a set of round controls.)*
- [x] **Home** sits immediately right of forward and opens the configured home page. It is never disabled — unlike back/forward it does not depend on page history. *(Added 2026-08-05 by user request. Device-verified.)*
- [x] The row **scrolls horizontally** rather than overflowing, so it can hold as many controls as the Enyo and Mochi shells. *(Device-verified 2026-08-05: 8 buttons, `client=768 scroll=768 overflowX=auto`.)*
- [~] **Long-press menu and padlock** (cavekit-ui-shell.md R7, R8): every hold goes to the engine (Mojo's web view claims none), and the card the user is in opens a `popupSubmenu` with the page's or the field's commands; the padlock is the address field's background on an https page, its tap answered with `showAlertDialog`. *(2026-10-06: driven from the Mojo test hook (`render/goanna/test/mojo-selftest.js`, `card-selftest.sh mojo`) on the device: a hold on page text opens Copy / Select All / Reload / Find on Page and Copy puts the word on the clipboard; a hold in a field opens Paste / Select All, Paste inserts the clipboard, Select All then adds Copy / Cut, and Cut leaves the text on the clipboard, the field empty and the engine saying "Cut."; the padlock tap on Wikipedia brings the Certificate alert. Found and fixed on the way: Copy and Cut had never reached the engine on Mojo — the WebView widget's `copy(callback)` hands an absent callback to the adapter as `undefined`, which the adapter refuses ("Bad arguments"), and the widget wraps no `cut` and no `pageFocused` at all. The shell now always passes a function to copy, and a method the widget does not wrap is called on the plugin element itself (R3).)* The finger on a link, and the hold's feel, are the owner's. [human at the device] — DEFERRED by the owner 2026-10-08 ("Defer additional finger tests for later")
- [~] **Long-press menu and padlock** (cavekit-ui-shell.md R7, R8): every hold goes to the engine (Mojo's web view claims none), and the card the user is in opens a `popupSubmenu` with the page's or the field's commands; the padlock is the address field's background on an https page, its tap answered with `showAlertDialog`. *(2026-10-06: driven from the Mojo test hook (`render/goanna/test/mojo-selftest.js`, `card-selftest.sh mojo`) on the device: a hold on page text opens Copy / Select All / Reload / Find on Page and Copy puts the word on the clipboard; a hold in a field opens Paste / Select All, Paste inserts the clipboard, Select All then adds Copy / Cut, and Cut leaves the text on the clipboard, the field empty and the engine saying "Cut."; the padlock tap on Wikipedia brings the Certificate alert. Found and fixed on the way: Copy and Cut had never reached the engine on Mojo — the WebView widget's `copy(callback)` hands an absent callback to the adapter as `undefined`, which the adapter refuses ("Bad arguments"), and the widget wraps no `cut` and no `pageFocused` at all. The shell now always passes a function to copy, and a method the widget does not wrap is called on the plugin element itself (R3).)* The finger on a link, and the hold's feel, are the owner's. [human at the device] — DEFERRED by the owner 2026-10-08 ("Defer additional finger tests for later") *(2026-10-24, the emulated finger (T-525): a held link got the text commands only — the Mojo widget has no `eventFired`, so the adapter's hit test (isLink, linkUrl, isImage, imageUrl) never reached the shell. Now `wa.eventFired` on the widget assistant claims link and image holds and `showHoldMenu` offers Open in New Card / Share Link / Copy URL (image: Open Image in New Card / Copy Image URL); Open in New Card verified. Text, field and other holds still go to the engine.)*
- [x] The buttons are **circular and centred** as a group, with tight spacing. *(Device-verified 2026-08-05: 50x50 each, `btn0` at x=170 — (768-8*54)/2 — i.e. centred.)*
- [x] **The other shells' upper-right menu, on the circles** (owner 2026-10-06: "the upper right menu has the same options on all 3 variants (see atlas for reference)", then "mojo should have no top toolbar icons next to url. bottom circular buttons only"). The **Share** circle opens Add Bookmark · Share Link (Email · Text Message · Copy Address) · Add to Launcher; the **Bookmarks** circle (it replaces the History circle) opens Bookmarks · History · Downloads; New Card stays a circle. Both are the framework's own command-menu `submenu` items, so the menu pops at the tapped circle. Bookmarks are the card's own capped list (`app/models/jihad-bookmarks.js`, no db8 kinds); Downloads lists what the engine saved (`app/models/jihad-downloads.js`, fed by the adapter's download callbacks). The address row carries nothing but the field. *(Device 2026-10-06, Mojo hook `Cshare`/`Clibrary` + `m`/`mN`: both menus, Add Bookmark → listed in Bookmarks, History and Downloads scenes.)*
- [x] **Reload / Stop is inside the address field's right end**, not a circle (owner 2026-10-06: "put the mojo refresh icon embedded in the right of the urlbar instead of the bottom as a circular button"): the ink glyph (the field is white whatever the theme), Stop while loading. *(Device 2026-10-06, hook `J`: refresh → tap → stop while loading → refresh.)*
+1 -1
View File
@@ -71,7 +71,7 @@ Run each item in all three variants (Enyo, Mochi, Mojo) unless it says otherwise
bookmarks/history; every app-menu entry; Mojo's new-card / share / history. (device-build R4) *(2026-10-24, the emulated finger, T-525: Enyo — back, forward, reload (the stop glyph shows), stop, home (DuckDuckGo lite), share (Add Bookmark / Share Link / Add to Launcher), bookmarks panel, padlock (the DigiCert certificate, Done), app menu (Find on Page / Settings / Print), new card — all act. Mochi — the same set acts (clear, share, Bookmarks / History / Downloads, app menu, new card; back and forward after a link). Mojo — reload, home, new card, the library and share menus, find in page, the padlock dialog, the app menu, and back and forward (`pageBackward` loads the previous page, `pageForward` the next) all act. NB the bar's hit boxes, in card px at y 930-980 (screen y ≈ 982): back 197-247, forward 251-301, home 305-355, new card 359-409, library 413-463, share 467-517, find 521-571 — a tap at the back ICON's apparent position (265) lands on the disabled forward box and does nothing; measured with elementFromPoint through the daemon's load line, `docs/rounds/finger-2026-10-24/zoom-grey.txt`.)*
- [~] Hold on text, on a field, on a link and on an image: the long-press menu offers the right
entries and each does what it says; a plain tap is unaffected. (ui-shell R7, mochi-ui R2,
mojo-ui R6) *(2026-10-24, the emulated finger: Enyo — text: the word selected, Copy / Select All / Reload / Add Bookmark / Find on Page; field: the keyboard and Paste / Select All; link: Open in New Card / Share Link / Copy URL; image (the infobox picture, a linked image): Open In New Card / Share Link / Copy URL / Copy To Photos / Share Image / Set Wallpaper; a plain tap on a link still opens it. Mochi — text: the word selected and the page-hold notified; link: the sheet Hewlett-Packard / Open in New Card / Share Link / Copy Address / Cancel. Mojo — text: Copy / Select All / Reload / Find on Page; link: the SAME text menu, the word selected, although the daemon's hit test answers isLink (the shell's hold menu is built without the hit test's link and image facts — mojo-ui R6's link commands, open). The entries' actions (Copy to the clipboard, Open in New Card, Save) and Mochi's and Mojo's image holds not yet exercised.)*
mojo-ui R6) *(2026-10-24, the emulated finger: Enyo — text: the word selected, Copy / Select All / Reload / Add Bookmark / Find on Page; field: the keyboard and Paste / Select All; link: Open in New Card / Share Link / Copy URL; image (the infobox picture, a linked image): Open In New Card / Share Link / Copy URL / Copy To Photos / Share Image / Set Wallpaper; a plain tap on a link still opens it. Mochi — text: the word selected and the page-hold notified; link: the sheet Hewlett-Packard / Open in New Card / Share Link / Copy Address / Cancel. Mojo — text: Copy / Select All / Reload / Find on Page; link: at first the SAME text menu (the framework widget has no eventFired, so the adapter's hit test never reached the shell); FIXED the same evening — the shell claims link and image holds on the widget assistant (eventFired, as Mochi's JihadWebView does) and offers Open in New Card / Share Link / Copy URL (an image: Open Image in New Card / Copy Image URL); Open in New Card opened the held link in a second card. The entries' actions (Copy to the clipboard, Open in New Card, Save) and Mochi's and Mojo's image holds not yet exercised.)*
- [x] Pick and dismiss an item in a card-side drop-down list; answer a card dialog by tap (an add-on
install confirm, an SSL confirm). (device-build R4) *(2026-10-24, Enyo: `jihad-card-events.html`'s select opens the card's list (choose one / apple / banana / cherry), a tap on banana closes it and the page reads "picked: banana"; https://self-signed.badssl.com/ raises View Certificate / Trust Always / Trust Once / Don't Trust and Trust Once loads the page. The add-on install confirm not tried.)*
- [~] about:settings: every control by finger at 1024×768, including the tabs (wrapped in Mochi) and