Before this fix suggestion links were built out of fully URI-encoded
book name and article path components despite the fact that this measure
was taken against only a few dangerous symbols such as '#', '?', '"' and
'\'. However, URI-encoding the slash symbols in the path has some
undesirable side-effects (see #958).
Henceforth only the problematic symbols are encoded in the article path
component. The book name is still fully URI-encoded since I don't see
any counter-arguments.
This is a quickfix for the problem observed with external link blocking
during certain history navigation actions (when the cached iframe content is
loaded/restored before the viewer setup is completed).
Since external link blocking doesn't depend on the translations (that
are asynchronously loaded during the viewer setup) it can be performed
unconditionally. However, the current dependence of `on_content_load()`
on viewer setup has to be addressed too.
Before this fix clicking an external link in the viewer iframe had no
effect (other than an error being reported in the browser dev tools
console) because the attempt to navigate the top browser context was
suppressed due to sandboxing - the click handling code changed the
target of the link but navigating to that target was blocked. Now the
click handler works as follows:
1. Changes the target of the link to the catch page only if the
link is going to be opened in a new tab or window (in this case
sandboxing restrictions do not apply).
2. Otherwise directly navigates the viewer window to external URL
or the catch page.
An unhandled scenario is opening an external link in a new tab/window
via a middle click or context menu - such events cannot be intercepted
and therefore there is no way of blocking external links accessed in
the said way.
In firefox, when PDF content is displayed in the viewer, changing the
viewer URL in the address bar had no effect. The most prominent
manifestation of this bug was the broken book home button but the same
issue was present even if the fragment component of the viewer URL was
edited manually. The bug was a result of
1. an optimization preventing any actions if the new content URL is the
same as the old content URL (this was needed to break the infinite loop
of mutual updates of the top-window and content window/iframe URLs when
any one of them changes).
2. sandboxing of the iframe and inability to access the content URL in
iframe because of cross-origin restrictions when the content is a PDF
displayed by the builtin viewer.
Now that issue is fixed. A slight remaining defect is that the
addressbar URL is still not updated when a PDF file is loaded/displayed
in the viewer.
SeaMonkey doesn't yet support [Window.visualViewport][1]. As a result the
height of the content iframe element was initialized to the default 150
pixels and never changed. Fortunately there is [Window.innerHeight][2]
which is supported from the very first days of the Gecko layout engine.
The difference between `Window.visualViewport.height` and
`Window.innerHeight` is that the latter also includes
- the height of the horizontal scroll bar, if present (but in a correctly
implemented ZIM viewer there shouldn't be a horizontal scroll bar for the
full web-page, so it's OK)
- the height of the on-screen keyboard (which is mostly used on mobile
devices where SeaMonkey doesn't run). And it is also arguable if the
appearing on-screen keyboard should squeeze the iframe or slide over
it (in which latter case it may make more sense to always use `innerHeight`
instead of `visualViewport.height`).
[1]: https://developer.mozilla.org/en-US/docs/Web/API/Window/visualViewport
[2]: https://developer.mozilla.org/en-US/docs/Web/API/Window/innerHeight
Now that we have proper UI for user language selection, we don't need
the `?userlang=` query parameter present in the URL. If `?userlang=` is
explicitly provided in the URL, it sets the requested language and
disappears.
Known issues
- styling / placement
- language changes via the selector UI are not recorded in the
navigation history
- changing the language via the UI doesn't update the `?userlang=` URL
query parameter
ZIM viewer is now internally internationalized but the UI language
can only be set by providing the `userlang` query parameter in the URL:
Example:
/viewer?userlang=fr#wikipedia_en_climate_change_mini_2021-03/A/index
^^^^^^^^^^^^
Before this change, some of the actions related to the initialization of
the viewer were run in the global scope as a side effect of loading
/skin/viewer.js. This change moves those actions into setupViewer().
Directly pointing the suggestion link to a /content/... URL avoids
an unnecessary redirection by the server (and an associated bug
related to redirection of URLs with URI-encoded special symbols in
them that - in the current implementation - go into the target URL
in decoded form).
This change fixes two issues:
1. Presence of URL-specific special symbols (such as ? or #) in the book
and/or article name resulted in a wrong suggestion link. This is
fixed by URI-encoding the book name and the path, too.
2. Presence of a single quote symbol in the book and/or article name
resulted in invalid javascript code in the href attribute of the
suggestion link.
The single quote (') symbol is not URL-encoded (unlike its double quote
counterpart). As a result, enclosing a URL-encoded string in single
quotes may result in invalid javascript. Using double quotes instead is
safe, since both double quote (") and backslash (\) symbols (which are
the only special symbols for such quoting) undergo URL-encoding.
If `kiwix-serve` is run with the `--nosearchbar` option the toolbar is
disabled (hidden) in its viewer.
Note however that certain actions performed by the viewer merely with
the purpose of keeping the toolbar up-to-date are still carried out.
Auto hiding of the toolbars on narrow screens works only for the first
page loaded in the viewer. Navigating to other pages interferes with
autohiding as follows:
- If the toolbar was hidden, it stays hidden.
- If the toolbar was not hidden, it loses the ability to autohide.
Made the viewer respect the `--blockexternal` and `--nolibrarybutton`
options of `kiwix-serve`. Those options are passed to the viewer
via the dynamically generated resource `/viewer_settings.js`.
Before this fix there were two issues with the taskbar search box:
1. The book used for the suggestions API was resolved only once during
the page load and didn't change during navigation.
2. The current book could not be resolved from a search URL.
Now both issues are fixed.