Flash pages no longer kill the daemon; a crash is no longer a loop; whole pages stay painted
Owner: "I can't click any links on lite.duckduckgo.com". The taps arrived - the daemon log shows each one landing on its <A> and the navigation starting. Both pages tapped were Flash pages, and loading either killed the daemon; the card then reconnected to the new daemon and reopened its last address, so to the user the results page just blinked and stayed. Engine (third_party/uxp 0048d50fa9 and 628ee50c99): a plugin embedded the ordinary way (wmode=window, the default) is "windowed"; the engine then creates a child-window widget and calls into it unchecked, and this offscreen build has none - null dereference, SIGSEGV. With no window to give, the instance is now windowless. Every Flash test of ours had wmode=opaque. Also: the Flash child no longer passes the bundled library path on to the shell Flash spawns (one crash report per Flash page). Daemon, crash guard (JihadCrashGuard.h): every top-level load that starts is noted in the state directory with how many daemons in a row died on that address; a clean exit removes the note. An address that took two daemons down within ten minutes is not opened a third time on the card's request - a short page says so and offers Try again. One refusal; the link, a reload or the address bar loads it. The loop this breaks produced about forty crash reports in a few minutes. Daemon, paint region (owner: "pages only load when observed ... the entire page should stay rendered at once unless it's very long"): the headroom around the viewport was a fraction of the viewport, whatever the buffer could hold. Now a page that fits the row budget is painted whole, so a scroll never uncovers anything and needs no repaint, and a longer page gets the full budget, most of it ahead of the pan. The 2048-row cap and the viewport-wide region are unchanged; lifting them needs an adapter change and is next. push-engine-update.sh also pushes plugin-container, and has --daemon-only. Test hooks: page:<steps> runs steps on the launched page; zZ,X,Y zooms/scrolls through the adapter. On the device, all three variants on libxul ddf8cc70, daemon 70796680, plugin-container 0c0e15d2: both Flash pages render their movies with the daemon keeping its PID and no crash report; killing the daemon twice mid-load gets the "This page stopped the browser" page on the third open; a 1583-row page is painted as one 768x1583 frame and scripted scrolling over it logs no uncovered rows. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LcrVQFRMC2ANGDfVaRG9Ed
This commit is contained in:
1 parent
b38a87fcd9
commit
3218caadd7
8 files changed
+227
-22
No files matched your search
@@ -17,8 +17,12 @@
|
||||
# (A changed script is picked up at the next start: the daemon drops the engine's compiled-
|
||||
# script cache when the bundle's files change. See DropStaleStartupCache in EngineHost.cpp.)
|
||||
#
|
||||
# Usage: build/webos-oe/push-engine-update.sh [enyo] [mochi] [mojo]
|
||||
# Usage: build/webos-oe/push-engine-update.sh [--daemon-only] [enyo] [mochi] [mojo]
|
||||
# --daemon-only push just the daemon binary (and this project's chrome scripts): the loop
|
||||
# after a daemon-only rebuild, without re-sending 45 MB of libxul per variant.
|
||||
set -euo pipefail
|
||||
DAEMON_ONLY=0
|
||||
if [ "${1:-}" = "--daemon-only" ]; then DAEMON_ONLY=1; shift; fi
|
||||
|
||||
HERE=$(cd "$(dirname "$0")" && pwd)
|
||||
DIST="$HERE/out-arm/obj-jihad-goanna-arm/dist"
|
||||
@@ -57,7 +61,12 @@ for f in libmozavutil.so libmozavcodec.so; do
|
||||
[ -e "$DIST/bin/$f" ] || die "no $f at $DIST/bin — run build-goanna-arm.sh build"
|
||||
cp -L "$DIST/bin/$f" "$TMP/$f"
|
||||
done
|
||||
"$STRIP" "$TMP/libxul.so" "$TMP/jihad-browserserver" "$TMP/libmozavutil.so" "$TMP/libmozavcodec.so" 2>/dev/null || true
|
||||
# plugin-container is the NPAPI (Flash) child process: its own binary, built with the engine.
|
||||
# It was not pushed until 2026-10-05, when a fix in it would otherwise have stayed on the host.
|
||||
[ -e "$DIST/bin/plugin-container" ] || die "no plugin-container at $DIST/bin — run build-goanna-arm.sh build"
|
||||
cp -L "$DIST/bin/plugin-container" "$TMP/plugin-container"
|
||||
"$STRIP" "$TMP/libxul.so" "$TMP/jihad-browserserver" "$TMP/libmozavutil.so" "$TMP/libmozavcodec.so" "$TMP/plugin-container" 2>/dev/null || true
|
||||
PC_MD5=$(md5sum "$TMP/plugin-container" | cut -c1-32)
|
||||
AVU_MD5=$(md5sum "$TMP/libmozavutil.so" | cut -c1-32)
|
||||
AVC_MD5=$(md5sum "$TMP/libmozavcodec.so" | cut -c1-32)
|
||||
XUL_MD5=$(md5sum "$TMP/libxul.so" | cut -c1-32)
|
||||
@@ -93,21 +102,27 @@ for v in $VARIANTS; do
|
||||
novacom run file://sbin/stop -- "$J" >/dev/null 2>&1 || true
|
||||
# Push to a temp name then move: the daemon may respawn mid-push; an atomic-ish rename keeps
|
||||
# a half-written libxul from ever being what upstart execs.
|
||||
say "[$v] pushing libxul.so"
|
||||
push_verified "$TMP/libxul.so" "$HL/.libxul.so.new" "$XUL_MD5"
|
||||
say "[$v] pushing jihad-browserserver"
|
||||
push_verified "$TMP/jihad-browserserver" "$HL/.jihad-browserserver.new" "$BS_MD5"
|
||||
say "[$v] pushing goanna.js"
|
||||
push_verified "$TMP/goanna.js" "$HL/.goanna.js.new" "$PREFS_MD5"
|
||||
say "[$v] pushing ffvpx (libmozavutil, libmozavcodec)"
|
||||
push_verified "$TMP/libmozavutil.so" "$HL/.libmozavutil.so.new" "$AVU_MD5"
|
||||
push_verified "$TMP/libmozavcodec.so" "$HL/.libmozavcodec.so.new" "$AVC_MD5"
|
||||
novacom run file://bin/mv -- "$HL/.libxul.so.new" "$HL/libxul.so"
|
||||
if [ "$DAEMON_ONLY" = 0 ]; then
|
||||
say "[$v] pushing libxul.so"
|
||||
push_verified "$TMP/libxul.so" "$HL/.libxul.so.new" "$XUL_MD5"
|
||||
say "[$v] pushing goanna.js"
|
||||
push_verified "$TMP/goanna.js" "$HL/.goanna.js.new" "$PREFS_MD5"
|
||||
say "[$v] pushing ffvpx (libmozavutil, libmozavcodec)"
|
||||
push_verified "$TMP/libmozavutil.so" "$HL/.libmozavutil.so.new" "$AVU_MD5"
|
||||
push_verified "$TMP/libmozavcodec.so" "$HL/.libmozavcodec.so.new" "$AVC_MD5"
|
||||
say "[$v] pushing plugin-container"
|
||||
push_verified "$TMP/plugin-container" "$HL/.plugin-container.new" "$PC_MD5"
|
||||
novacom run file://bin/mv -- "$HL/.libxul.so.new" "$HL/libxul.so"
|
||||
novacom run file://bin/mv -- "$HL/.goanna.js.new" "$HL/goanna.js"
|
||||
novacom run file://bin/mv -- "$HL/.libmozavutil.so.new" "$HL/libmozavutil.so"
|
||||
novacom run file://bin/mv -- "$HL/.libmozavcodec.so.new" "$HL/libmozavcodec.so"
|
||||
novacom run file://bin/mv -- "$HL/.plugin-container.new" "$HL/plugin-container"
|
||||
novacom run file://bin/chmod -- 755 "$HL/plugin-container"
|
||||
novacom run file://bin/chmod -- 755 "$HL/libmozavutil.so" "$HL/libmozavcodec.so"
|
||||
fi
|
||||
novacom run file://bin/mv -- "$HL/.jihad-browserserver.new" "$HL/jihad-browserserver"
|
||||
novacom run file://bin/mv -- "$HL/.goanna.js.new" "$HL/goanna.js"
|
||||
novacom run file://bin/mv -- "$HL/.libmozavutil.so.new" "$HL/libmozavutil.so"
|
||||
novacom run file://bin/mv -- "$HL/.libmozavcodec.so.new" "$HL/libmozavcodec.so"
|
||||
novacom run file://bin/chmod -- 755 "$HL/libmozavutil.so" "$HL/libmozavcodec.so"
|
||||
novacom run file://bin/chmod -- 755 "$HL/jihad-browserserver"
|
||||
say "[$v] pushing this project's chrome scripts ($(echo $OWN | wc -w) files)"
|
||||
for f in $OWN; do
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "../goanna/JihadRuntimePaths.h" // the ONE runtime-state dir (T-057 / R8)
|
||||
#include "../goanna/JihadCrashReport.h" // self-reporting fatal-signal dump
|
||||
#include "JihadLunaService.h" // this variant's own palm:// service (IPC R4)
|
||||
#include "../goanna/JihadCrashGuard.h" // a clean exit clears the crash guard's note
|
||||
|
||||
static JihadBrowserServer* g_server = nullptr;
|
||||
|
||||
@@ -352,6 +353,8 @@ int main(int argc, char** argv) {
|
||||
server.run(); // GLib main loop (patched YapServer::run)
|
||||
if (g_termSignal)
|
||||
printf("[jihad-bs] signal %d — shutting the engine down cleanly\n", (int)g_termSignal);
|
||||
// Leaving on purpose: whatever was loading is not to blame for this exit.
|
||||
jihad::CrashGuardCleanExit();
|
||||
jihad::LunaServiceStop();
|
||||
g_server = nullptr;
|
||||
} // every page destroyed here, before the runtime goes away
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "BrowserOffscreenInfo.h" // isis shmem header (from render/browserserver/Src)
|
||||
#include "JihadLogo.h" // JIHAD_LOGO_B64 (app icon for about: pages)
|
||||
#include "JihadRuntimePaths.h" // the ONE runtime-state dir (T-057 / R8)
|
||||
#include "JihadCrashGuard.h" // do not reopen a page that just killed the daemon twice
|
||||
#include "JihadCertStore.h" // webOS platform certificate store (R5)
|
||||
|
||||
#include <cstdio>
|
||||
@@ -1012,6 +1013,47 @@ void BrowserPageGoanna::openUrl(const char* url) {
|
||||
return;
|
||||
}
|
||||
mAliasUrl.clear();
|
||||
// A page that took the last two daemons down is not opened a third time by itself: the
|
||||
// card reopens its address whenever a daemon comes back, and that made a crash a loop
|
||||
// (JihadCrashGuard.h). Shown once; the link on it, a reload or the address bar loads it.
|
||||
if (jihad::CrashGuardShouldRefuse(url)) {
|
||||
std::string safe;
|
||||
for (const char* c = url; *c && safe.size() < 1200; ++c) {
|
||||
switch (*c) {
|
||||
case '&': safe += "&"; break; case '<': safe += "<"; break;
|
||||
case '>': safe += ">"; break; case '"': safe += """; break;
|
||||
default: safe += *c;
|
||||
}
|
||||
}
|
||||
const std::string html =
|
||||
"<!DOCTYPE html><html><head><meta charset=utf-8><title>Page stopped</title>"
|
||||
"<meta name=viewport content='width=device-width, initial-scale=1'>"
|
||||
"<style>body{font:18px/1.5 sans-serif;background:#1c1c1c;color:#e6e6e6;margin:0;padding:48px 36px}"
|
||||
"h1{font-size:24px;margin:0 0 14px}p{margin:0 0 16px;color:#bdbdbd}"
|
||||
"a{color:#7fb2e6}.u{word-wrap:break-word;color:#8cafbe;font-size:15px}</style></head><body>"
|
||||
"<h1>This page stopped the browser</h1>"
|
||||
"<p>It did so twice in a row, so it was not opened again automatically.</p>"
|
||||
"<p class=u>" + safe + "</p>"
|
||||
"<p><a id=retry href=\"" + safe + "\">Try again</a></p></body></html>";
|
||||
// setHTML appends its argument to "data:text/html," as it is, so a '#' would start a
|
||||
// fragment and cut the page off there (the first version of this page was blank for
|
||||
// exactly that reason: its colours), and a '%' in the address would be decoded. Escape
|
||||
// everything that is not plainly safe.
|
||||
std::string enc; enc.reserve(html.size() * 2);
|
||||
static const char* kHex = "0123456789ABCDEF";
|
||||
for (unsigned char c : html) {
|
||||
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') ||
|
||||
c == '-' || c == '_' || c == '.' || c == '~') {
|
||||
enc += (char)c;
|
||||
} else {
|
||||
enc += '%'; enc += kHex[c >> 4]; enc += kHex[c & 15];
|
||||
}
|
||||
}
|
||||
mAliasUrl = url;
|
||||
setHTML(url, enc.c_str());
|
||||
return;
|
||||
}
|
||||
jihad::CrashGuardNoteLoad(url);
|
||||
// R6: a matching redirect rule hands the URL to the client (msgUrlRedirected)
|
||||
// and, if it is a redirect, is not loaded in the browser at all.
|
||||
if (applyRedirectRules(url)) return;
|
||||
@@ -2990,14 +3032,30 @@ void BrowserPageGoanna::paintToSharedBuffer() {
|
||||
// Bias the headroom toward the pan DIRECTION ("content blips in and out when I scroll",
|
||||
// device 2026-08-02): the strip behind the pan is dead weight; the strip ahead is what
|
||||
// the user is about to expose. Direction from the adapter scroll delta since last paint.
|
||||
long ovAbove = h / 2, ovBelow = h;
|
||||
if (adY > mPrevPaintScrollY + 8) { ovAbove = h / 8; ovBelow = h + h / 2; }
|
||||
else if (adY < mPrevPaintScrollY - 8) { ovAbove = h + h / 2; ovBelow = h / 8; }
|
||||
//
|
||||
// HOW MUCH (owner, 2026-10-05: "pages only load when observed … the entire page should
|
||||
// stay rendered at once unless it's very long"). The headroom used to be a fraction of the
|
||||
// VIEWPORT (half above, one below), whatever the buffer could hold — so a page a screen
|
||||
// and a half long was painted as a window that followed the finger, repainted on the way,
|
||||
// and showed undrawn rows whenever the finger won. Now the whole row budget is spent:
|
||||
// - a page that fits the budget is painted WHOLE, top to bottom. Nothing is ever
|
||||
// uncovered and a scroll needs no repaint at all (setScrollPosition's coverage test
|
||||
// finds every position covered) — the adapter just pans the frame it has;
|
||||
// - a longer page gets the full budget around the viewport, most of it ahead of the pan.
|
||||
long slackRows = maxRows - (long)h; if (slackRows < 0) slackRows = 0;
|
||||
long ovAbove = slackRows / 3, ovBelow = slackRows - slackRows / 3;
|
||||
if (adY > mPrevPaintScrollY + 8) { ovAbove = slackRows / 6; ovBelow = slackRows - ovAbove; }
|
||||
else if (adY < mPrevPaintScrollY - 8) { ovBelow = slackRows / 6; ovAbove = slackRows - ovBelow; }
|
||||
mPrevPaintScrollY = adY;
|
||||
long lo = (bandY < adY ? bandY : adY) - ovAbove;
|
||||
long hi = (bandY > adY ? bandY : adY) + h + ovBelow;
|
||||
if (lo < 0) lo = 0;
|
||||
if (contentRows > 0 && hi > contentRows) hi = contentRows;
|
||||
if (contentRows > 0 && contentRows <= maxRows) {
|
||||
lo = 0; hi = contentRows; // the whole page
|
||||
} else {
|
||||
// Headroom that falls off one end of the page is given to the other end.
|
||||
if (lo < 0) { hi -= lo; lo = 0; }
|
||||
if (contentRows > 0 && hi > contentRows) { lo -= (hi - contentRows); hi = contentRows; if (lo < 0) lo = 0; }
|
||||
}
|
||||
if (hi < lo + h) hi = lo + h; // never less than one viewport
|
||||
if (hi - lo > maxRows) { // over budget: trim overscan…
|
||||
lo = bandY - (maxRows - (long)h) / 3; // keep ~2/3 of the slack below the band
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "nsIWebProgressListener.h"
|
||||
#include "nsIURI.h"
|
||||
#include "JihadRuntimePaths.h" // RuntimeProfileDir (Flash availability)
|
||||
#include "JihadCrashGuard.h" // note each top-level load that starts
|
||||
#include "nsIObserverService.h" // NotifyChrome: hand a page to a bundled JS component
|
||||
#include "imgIEncoder.h" // PNG out of a frame (bookmark thumbnails)
|
||||
#include "nsComponentManagerUtils.h" // do_CreateInstance
|
||||
@@ -360,6 +361,9 @@ NS_IMETHODIMP PageChrome::OnStateChange(nsIWebProgress* aWebProgress, nsIRequest
|
||||
nsCOMPtr<nsIChannel> ch = do_QueryInterface(aRequest);
|
||||
if (ch) {
|
||||
nsCOMPtr<nsIURI> u; ch->GetURI(getter_AddRefs(u)); if (u) u->GetSpec(mLinkUrl);
|
||||
// A load the PAGE started (a tapped link, a redirect, script): the crash guard has to
|
||||
// know about these too, or it would blame the address the card last asked for.
|
||||
if (u && !mLinkUrl.IsEmpty()) jihad::CrashGuardNoteLoad(mLinkUrl.get());
|
||||
// Capture the method: a POST content-nav is NOT re-driven (the body may already be on the
|
||||
// wire — re-issuing would double the request, Codex F-262); only GET-class navs get the
|
||||
// re-drive. The engine completes POSTs; the load watchdog clears the overlay if one stalls.
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
#ifndef JIHAD_CRASH_GUARD_H
|
||||
#define JIHAD_CRASH_GUARD_H
|
||||
|
||||
// A page that kills the daemon must not be reopened forever.
|
||||
//
|
||||
// WHAT HAPPENED (2026-10-05). Two pages crashed the daemon while loading (a null dereference
|
||||
// in the plugin code, since fixed). When the daemon dies the card reconnects to the new one
|
||||
// and opens its address again — which is right for an ordinary restart, and here meant: load,
|
||||
// crash, restart, load, crash … for as long as the card stayed open. About forty crash
|
||||
// reports in a few minutes, and nothing on screen but a spinner.
|
||||
//
|
||||
// THE GUARD. Every top-level load that starts is noted in a small file in the state
|
||||
// directory, with how many daemons in a row have died while that same address was the last
|
||||
// one started. A clean shutdown removes the file. So a file found at start means the previous
|
||||
// daemon did NOT exit cleanly, and names what it was loading. When the card then asks for an
|
||||
// address that has already taken two daemons down within the last ten minutes, the daemon
|
||||
// does not load it: it shows a short page saying so, with a link to try again. The refusal
|
||||
// is used up by being shown — the link, a reload or a typed address loads the page for real.
|
||||
//
|
||||
// What it is not: a judgement about the page. One death is allowed to be coincidence (the
|
||||
// second attempt is automatic); two in a row with the same address is a pattern.
|
||||
|
||||
#include "JihadRuntimePaths.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
namespace jihad {
|
||||
|
||||
struct CrashGuardState {
|
||||
bool loaded = false;
|
||||
std::string prevUrl; // what the previous daemon was loading when it died uncleanly
|
||||
int prevCount = 0; // how many daemons in a row died on it
|
||||
long prevTime = 0;
|
||||
bool refused = false; // the one refusal has been shown
|
||||
};
|
||||
|
||||
inline CrashGuardState& CrashGuardGet() {
|
||||
static CrashGuardState s;
|
||||
if (!s.loaded) {
|
||||
s.loaded = true;
|
||||
const std::string path = RuntimeStatePath("last-load");
|
||||
if (!path.empty()) {
|
||||
if (FILE* f = fopen(path.c_str(), "r")) {
|
||||
char head[64] = "", url[2048] = "";
|
||||
if (fgets(head, sizeof head, f) && fgets(url, sizeof url, f)) {
|
||||
url[strcspn(url, "\r\n")] = 0;
|
||||
int n = 0; long t = 0;
|
||||
if (sscanf(head, "%d %ld", &n, &t) == 2 && n > 0 && url[0]) {
|
||||
s.prevUrl = url; s.prevCount = n; s.prevTime = t;
|
||||
fprintf(stderr, "[jihad-bs] crash guard: the previous daemon did not exit cleanly; "
|
||||
"it was loading a page (%d in a row on that address)\n", n);
|
||||
}
|
||||
}
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
// A top-level load of `url` is starting. Records it as "what this daemon dies with, if it
|
||||
// dies now". Never the fragment: the settings page rewrites its own.
|
||||
inline void CrashGuardNoteLoad(const char* url) {
|
||||
if (!url || !*url) return;
|
||||
CrashGuardState& s = CrashGuardGet();
|
||||
const std::string path = RuntimeStatePath("last-load");
|
||||
if (path.empty()) return;
|
||||
std::string u(url);
|
||||
const size_t hash = u.find('#');
|
||||
if (hash != std::string::npos) u.erase(hash);
|
||||
if (u.size() > 2000) u.resize(2000);
|
||||
const int n = (u == s.prevUrl) ? s.prevCount + 1 : 1;
|
||||
if (FILE* f = fopen(path.c_str(), "w")) {
|
||||
fprintf(f, "%d %ld\n%s\n", n, (long)time(nullptr), u.c_str());
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
|
||||
// Should the card's request for `url` be refused this once?
|
||||
inline bool CrashGuardShouldRefuse(const char* url) {
|
||||
if (!url || !*url) return false;
|
||||
CrashGuardState& s = CrashGuardGet();
|
||||
if (s.refused || s.prevCount < 2) return false;
|
||||
std::string u(url);
|
||||
const size_t hash = u.find('#');
|
||||
if (hash != std::string::npos) u.erase(hash);
|
||||
if (u != s.prevUrl) return false;
|
||||
if ((long)time(nullptr) - s.prevTime > 600) return false;
|
||||
s.refused = true;
|
||||
fprintf(stderr, "[jihad-bs] crash guard: NOT reopening a page that stopped the browser %d times in a row\n",
|
||||
s.prevCount);
|
||||
return true;
|
||||
}
|
||||
|
||||
// The daemon is exiting on purpose: nothing it had open is to blame.
|
||||
inline void CrashGuardCleanExit() {
|
||||
const std::string path = RuntimeStatePath("last-load");
|
||||
if (!path.empty()) unlink(path.c_str());
|
||||
}
|
||||
|
||||
} // namespace jihad
|
||||
|
||||
#endif // JIHAD_CRASH_GUARD_H
|
||||
@@ -59,6 +59,11 @@
|
||||
bb.call("palm://com.palm.db/put", enyo.json.stringify({objects: [{_kind: "net.riverstonerelay.jihad-browser.bookmarks:1", title: "jihad test bookmark", url: "http://example.invalid/jihad-test", date: (new Date()).getTime()}]}));
|
||||
window.__jihadTestBridges.push(bb);
|
||||
log(name, "test bookmark added");
|
||||
} else if (st.charAt(0) === "z") { // zZOOM,X,Y: zoom and scroll, as a pinch or a pan ends up
|
||||
var zs = st.slice(1).split(",");
|
||||
view.callBrowserAdapter("pageScaleAndScroll", [parseFloat(zs[0]), parseInt(zs[1], 10), parseInt(zs[2], 10)]);
|
||||
log(name, "zoom/scroll " + st.slice(1));
|
||||
wait = 1200;
|
||||
} else if (st === "?") { // report the state now
|
||||
state("now", function() {});
|
||||
} else if (st.charAt(0) === "s") {
|
||||
@@ -75,7 +80,9 @@
|
||||
}
|
||||
later(wait, function() { step(i + 1); });
|
||||
}
|
||||
app.openSettings();
|
||||
// `page:<steps>` runs the same steps on the page the card was launched on, without
|
||||
// opening the settings page first.
|
||||
if (String(name).indexOf("page") !== 0) { app.openSettings(); }
|
||||
later(8000, function() { state("opened", function() { step(0); }); });
|
||||
},
|
||||
// Print: open the dialog from the menu and report what the daemon finds. With an
|
||||
@@ -124,6 +131,7 @@
|
||||
later(12000, function() { try { app.$.appMenu.close(); } catch (e) {} look("12s"); log(name, "DONE"); });
|
||||
}
|
||||
};
|
||||
scenarios.page = scenarios.settings;
|
||||
function run() {
|
||||
var p = enyo.windowParams || null;
|
||||
if (!p || !p.jihadTest) { try { p = enyo.json.parse(window.PalmSystem.launchParams); } catch (e) { p = null; } }
|
||||
|
||||
@@ -50,6 +50,11 @@
|
||||
} else if (st === "b") { // a bookmark of the test's own, to have one to clear
|
||||
enyo.jihad.dbPut([{_kind: enyo.jihad.kinds.bookmarks, title: "jihad test bookmark", url: "http://example.invalid/jihad-test", date: (new Date()).getTime()}]);
|
||||
log(name, "test bookmark added");
|
||||
} else if (st.charAt(0) === "z") { // zZOOM,X,Y: zoom and scroll, as a pinch or a pan ends up
|
||||
var zs = st.slice(1).split(",");
|
||||
app.$.view.callBrowserAdapter("pageScaleAndScroll", [parseFloat(zs[0]), parseInt(zs[1], 10), parseInt(zs[2], 10)]);
|
||||
log(name, "zoom/scroll " + st.slice(1));
|
||||
wait = 1200;
|
||||
} else if (st === "?") { // report the state now
|
||||
state("now", function() {});
|
||||
} else if (st.charAt(0) === "s") {
|
||||
@@ -64,7 +69,9 @@
|
||||
}
|
||||
later(wait, function() { step(i + 1); });
|
||||
}
|
||||
app.menuSettings();
|
||||
// `page:<steps>` runs the same steps on the page the card was launched on, without
|
||||
// opening the settings page first.
|
||||
if (String(name).indexOf("page") !== 0) { app.menuSettings(); }
|
||||
later(8000, function() { state("opened", function() { step(0); }); });
|
||||
},
|
||||
|
||||
@@ -346,6 +353,7 @@
|
||||
}
|
||||
};
|
||||
|
||||
scenarios.page = scenarios.settings;
|
||||
function run() {
|
||||
var p = null;
|
||||
try { p = enyo.json.parse(window.PalmSystem.launchParams); } catch (e) { p = null; }
|
||||
|
||||
Vendored
+1
-1
Submodule third_party/uxp updated: 9dedcd5fe5...628ee50c99.
Reference in new issue
Block a user