Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
.min.js
*.min.js
node_modules/
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,8 @@ Obs.js exposes the following classes under the following conditions:
| Class | Meaning | Computed/derived from |
| --------------------------------------- | ------------------------ | --------------------------------------------------------------- |
| `.has-data-saver` | User enabled Data Saver | `navigator.connection.saveData === true` |
| `.has-battery-critical` | Battery ≤ 5% | `battery.level ≤ 0.05` |
| `.has-battery-low` | 5% < battery ≤ 20% | `0.05 < battery.level ≤ 0.2` (mutually exclusive with critical) |
| `.has-battery-low` | Battery ≤ 20% | `battery.level ≤ 0.2` |
| `.has-battery-critical` | Battery ≤ 5% | `battery.level ≤ 0.05` (added **alongside** `.has-battery-low`) |
| `.has-battery-charging` | On charge | `battery.charging === true` |
| `.has-latency-low` | Low RTT | `rtt < 75ms` |
| `.has-latency-medium` | Medium RTT | `75–275ms` |
Expand All @@ -172,14 +172,14 @@ Obs.js also stores the following properties on the `window.obs` object:
| `config.observeChanges` | boolean | Whether Obs.js attaches change listeners | **Default `false`**; set by you _before_ Obs.js runs | Opt-in for SPAs or long-lived pages |
| `dataSaver` | boolean | User enabled Data Saver | `navigator.connection.saveData` | — |
| `rttBucket` | number (ms) | RTT bucketed to **ceil** 25 ms (e.g. 101→125) | `navigator.connection.rtt` | Undefined if Connection API missing |
| `rttCategory` | `'low' \| 'medium' \| 'high'` | CrUX tri-bin: `<75`, `75–275`, `>275` | Derived from `rtt` | Drives latency classes |
| `rttCategory` | `'low' \| 'medium' \| 'high'` | CrUX tri-bin: <75, 75–275, >275 | Derived from `rtt` | Drives latency classes |
| `downlinkBucket` | number (Mbps) | Downlink bucketed to **ceil** 1 Mbps | `navigator.connection.downlink` | Low/High thresholds: `≤5` / `≥8` |
| `downlinkMax` | number (Mbps) | Max estimated downlink (if exposed) | `navigator.connection.downlinkMax` | Not used for Stances; informational only |
| `connectionCapability` | `'strong' \| 'moderate' \| 'weak'` | Transport assessment | Derived from `rttCategory` and `downlinkBucket` | Strong = low RTT **and** high BW; Weak = high RTT **or** low BW |
| `conservationPreference` | `'conserve' \| 'neutral'` | Frugality signal | `dataSaver === true` **or** `batteryLow === true` → `conserve` | — |
| `deliveryMode` | `'rich' \| 'cautious' \| 'lite'` | How “heavy” you should go | Derived from capability and conservation | Rich if **strong** and **not** conserving; Lite if **weak** or **conserve**; else Cautious |
| `canShowRichMedia` | boolean | Convenience: `deliveryMode === 'rich'` | Derived from `deliveryMode` | Shorthand for “go big” |
| `shouldAvoidRichMedia` | boolean | Convenience: `deliveryMode === 'lite'` | Derived from `deliveryMode` | Shorthand for “be frugal” |
| `batteryCritical` | boolean \| null | Battery `≤ 5%` | Battery API | Mutually exclusive with `batteryLow`; `null` if unknown |
| `batteryLow` | boolean \| null | `5% < level ≤ 20%` | Battery API | `true` only when not `batteryCritical` |
| `batteryLow` | boolean \| null | Battery ≤20% | Battery API | `true` when battery level is ≤20%; `null` if unknown |
| `batteryCritical` | boolean \| null | Battery ≤5% | Battery API | `true` when battery level is ≤5%; `true` in addition to `batteryLow` |
| `batteryCharging` | boolean \| null | On charge | Battery API | `null` if unknown |
13 changes: 5 additions & 8 deletions obs.js
Original file line number Diff line number Diff line change
Expand Up @@ -228,14 +228,12 @@
const low = Number.isFinite(level) ? level <= 0.2 : null;
window.obs.batteryLow = low;

// Add most urgent battery class, removing any classes left over.
// E.g. `<html class="has-battery-critical">`
// Add battery classes (subset model): at ≤5% we want BOTH low and critical.
// First remove leftovers, then add any that apply.
// E.g. `<html class="has-battery-low has-battery-critical">`
['critical','low'].forEach(t => html.classList.remove(`has-battery-${t}`));
if (critical) {
html.classList.add('has-battery-critical');
} else if (low) {
html.classList.add('has-battery-low');
}
if (low) html.classList.add('has-battery-low');
if (critical) html.classList.add('has-battery-critical');

// Add a class to the `<html>` element if the device is currently charging.
// E.g. `<html class="has-battery-charging">`
Expand Down Expand Up @@ -269,4 +267,3 @@
.catch(() => { /* no‑op */ });
}
})();
//# sourceURL=obs.js