Skip to content

Commit a0cfaae

Browse files
committed
Project reviewed. xss bug fixed.
1 parent 72c5ec9 commit a0cfaae

8 files changed

Lines changed: 45 additions & 9 deletions

File tree

DEVELOPMENT.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,16 @@
22

33
This project has a small local build step for generating distributable artifacts without requiring a MediaWiki instance.
44

5+
Documentation exists in three places:
6+
* [README.md](README.md), [specifications.md](specifications.md), and [DEVELOPMENT.md](DEVELOPMENT.md)
7+
* [Template:InlineDateTime/doc](gadget/Template_InlineDateTime_doc.wikitext)
8+
* The demo page
9+
10+
Testing has three available parts:
11+
* The demo page
12+
* Lua test suite
13+
* Manual integration testing with a prepared docker file
14+
515
## Build artifacts
616

717
Run:

README.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ This is a Mediawiki gadget for game wikis with a few game servers in different t
44

55
This gadget will format times and timespans as inline text with a tooltip (accessible on hover or tap) that translates the time to the user's local time. The information is kept minimal for compactness but expansion occurs as needed for precision.
66

7-
[Demo page](https://solidkalium.github.io/inline-datetime/)
7+
**[See our demo page!](https://solidkalium.github.io/inline-datetime/)**
88

99
Example tooltip:
1010

@@ -20,7 +20,7 @@ Example tooltip:
2020
* Single moment across servers (e.g. `04:00 +8`): usually server maintenance
2121
* Inline text: user's timezone
2222
* Tooltip: servers' timezones
23-
* Same server time across servers (e.g. `04:00 server`): usually daily & weekly resets
23+
* Same server time across servers (e.g. `04:00`): usually daily & weekly resets
2424
* Inline text: the server-relative time
2525
* Tooltip: when each server observes that time, according to the user's timezone
2626
* Single times or timespans (can mix and match date kinds)
@@ -30,10 +30,12 @@ Example tooltip:
3030
* Basic default text to display when Javascript is disabled
3131
* Basic semantic HTML classes to enable custom css
3232
* Auto-deduplicating things like the year or day when it is the same for the whole timespan in the user's timezone.
33-
* Provides [[Category:Pages with InlineDateTime errors]]
33+
* Dynamic content added via `mw.hook('wikipage.content')` is handled automatically
34+
* Provides `[[Category:Pages with InlineDateTime errors]]`
3435

3536
**Known issues:**
3637
* The no-JS fallback text is not styled and doesn't deduplicate as well as the JS code.
38+
* The server agnostic description isn't moved into the tooltip when there is a raw text override.
3739

3840
**Not supported:**
3941
* Languages other than English
@@ -50,6 +52,8 @@ Example tooltip:
5052
* But: you can use a raw text override
5153
* Disable tooltip (other than by disabling js)
5254
* Support for showing seconds. We assume everything is minute-aligned.
55+
* Support for entering days without hours and minutes.
56+
* Support for compact inline text that removes the hours and minutes but leaves them in the tooltip.
5357
* Tooling for locating date-like entries on pages that haven't been wrapped in the template.
5458
* PHP time parsing `{{time:}}`
5559
* This is intentional to prevent silent errors. If someone writes something like "from maintenance until Mar 29 reset" would likely be collapsed to March 29 of either the current or next year. If there's a good reason to support "second tuesday of last month + 10 seconds" then this could change.

TODO.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
* Include style classes?
77
* This could interfere with the current no-JS demo
88
* audit code for readability and obviousness
9+
* Re-organize "supported" and "not-supported" notes in README
910

1011
## Later
1112

gadget/Module_InlineDateTime.lua

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ local function formatFallback(parsed)
9393
local parts = {}
9494
table.insert(parts, monthStr .. ' ' .. d)
9595
-- Include year only if it's not the current year
96+
-- '!' gives UTC time; the year may differ from local wiki time around UTC midnight
97+
-- on Jan 1, but this is acceptable for a no-JS fallback.
9698
local currentYear = os.date('!%Y')
9799
if y ~= currentYear then
98100
table.insert(parts, y)
@@ -219,7 +221,7 @@ function p.main(frame)
219221

220222
-- Assemble the span
221223
local attrStr = table.concat(dataAttrs, ' ')
222-
return '<span class="dt-inline" ' .. attrStr .. '>' .. display .. '</span>'
224+
return '<span class="dt-inline" ' .. attrStr .. '>' .. htmlEscape(display) .. '</span>'
223225
end
224226

225227
return p

gadget/inline-datetime.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,10 @@
101101
function getFormatter(cacheKey, options, locale) {
102102
if (!FORMATTER_CACHE[cacheKey]) {
103103
FORMATTER_CACHE[cacheKey] = new Intl.DateTimeFormat(
104+
// Use arguments.length rather than `locale || 'en-US'` because
105+
// passing explicit undefined still satisfies ||, so the browser
106+
// locale would never be reached. Callers omit the argument for
107+
// en-US and pass undefined for the browser's locale.
104108
arguments.length < 3 ? 'en-US' : locale,
105109
options
106110
);

scripts/build_artifacts.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -220,8 +220,8 @@ def render_test_cases() -> tuple[str, str]:
220220

221221

222222
def mw_code_from_args(args: dict) -> str:
223-
"""Build a {{dt|...}} template call string from an args dict."""
224-
parts = ["{{dt"]
223+
"""Build a {{IDT|...}} template call string from an args dict."""
224+
parts = ["{{IDT"]
225225
for k, v in args.items():
226226
parts.append(f"|{k}={v}")
227227
parts.append("}}")

test/run_lua_tests.lua

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,21 @@ run('soft error: html entities escaped in start input',
8686
'dt-error-soft',
8787
'&lt;script&gt;xss&lt;/script&gt;')
8888

89+
run('soft error: html entities escaped in end input',
90+
{ start = '2026-03-12 06:00', ['end'] = '<script>xss</script>' },
91+
'dt-error-soft',
92+
'&lt;script&gt;xss&lt;/script&gt;')
93+
94+
run('soft error: html entities escaped in raw input',
95+
{ start = 'bad-date', raw = '<script>xss</script>' },
96+
'dt-error-soft',
97+
'&lt;script&gt;xss&lt;/script&gt;')
98+
99+
run('valid: html entities escaped in raw input',
100+
{ start = '2026-03-12 06:00', raw = '<script>xss</script>' },
101+
'class="dt-inline"',
102+
'&lt;script&gt;xss&lt;/script&gt;')
103+
89104
-- ── Valid output: data attributes ─────────────────────────────────────────────
90105

91106
run('valid: server time emits correct attributes',

test/test-cases.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"description_before": "Combat Drills for Tangtang is available from",
99
"description_after": ".",
1010
"args": { "start": "2026-03-12 12:00", "end": "2026-03-29 12:00" },
11-
"code": "{{dt|start=2026-03-12 12:00|end=2026-03-29 12:00}}",
11+
"code": "{{IDT|start=2026-03-12 12:00|end=2026-03-29 12:00}}",
1212
"note": "Inline text shows \"(server)\" once at the end. Tooltip shows your local time per server."
1313
},
1414
{
@@ -57,14 +57,14 @@
5757
"end": "2026-03-29 04:00",
5858
"raw": "After maintenance until Mar 29 reset"
5959
},
60-
"code": "{{dt|start=2026-03-12 12:00 +8|end=2026-03-29 04:00|raw=After maintenance until Mar 29 reset}}",
60+
"code": "{{IDT|start=2026-03-12 12:00 +8|end=2026-03-29 04:00|raw=After maintenance until Mar 29 reset}}",
6161
"note": "Inline text stays exactly as provided. Tooltip should still be built from the datetime parameters."
6262
},
6363
{
6464
"title": "Raw text + single time + server filter",
6565
"description_before": "Asia-only schedule note:",
6666
"args": { "start": "2026-03-29 04:00", "server": "asia", "raw": "Asia server daily reset" },
67-
"code": "{{dt|start=2026-03-29 04:00|server=asia|raw=Asia server daily reset}}",
67+
"code": "{{IDT|start=2026-03-29 04:00|server=asia|raw=Asia server daily reset}}",
6868
"note": "Inline text should remain raw, and the tooltip should be limited to the specified server."
6969
}
7070
]

0 commit comments

Comments
 (0)