libreoffice-online/loleaflet
Weblate 6f90eb96a1 update translations
LibreOffice Online/loleaflet-help (Kabyle)
Currently translated at 34.4% (143 of 416 strings)

Change-Id: I6ce9f0bb8f42490431a7a23b93ff5e4c82122723

update translations

LibreOffice Online/loleaflet-ui (Portuguese)
Currently translated at 100.0% (310 of 310 strings)

Change-Id: Ie09455b7ffc3c427c66781a32f015665c0545703

update translations

LibreOffice Online/loleaflet-help (Ukrainian)
Currently translated at 61.8% (257 of 416 strings)

Change-Id: I2a3d14d3b58dbe66231f9bbab9639d675a45ca1f

update translations

LibreOffice Online/loleaflet-ui (Ukrainian)
Currently translated at 96.5% (299 of 310 strings)

Change-Id: I0a6b36a8e79551df82f094760df382b8942e6660

update translations

LibreOffice Online/android-app (Ukrainian)
Currently translated at 100.0% (102 of 102 strings)

Change-Id: Ib1bb76ebff66fce951dd2be03a5da1c3c17bf3fb

update translations

LibreOffice Online/loleaflet-ui (Ukrainian)
Currently translated at 92.6% (287 of 310 strings)

Change-Id: I4edcfd872ecf9cd4bd1e1efcfb4516415a8eb9be

update translations

LibreOffice Online/loleaflet-ui (Danish)
Currently translated at 75.8% (235 of 310 strings)

Change-Id: Ia665d109743e6ef00a6b5e509b2f126928b72c28

update translations

LibreOffice Online/ios (Bosnian)
Currently translated at 100.0% (5 of 5 strings)

Change-Id: I2fbba21e2a80f4e6ffb12a5651affd8ffbb2fb72

update translations

LibreOffice Online/loleaflet-help (Chinese (Simplified))
Currently translated at 68.8% (286 of 416 strings)

Change-Id: Idb9c518cb5e2c68bc550489ca50d3d43b2c2e576

update translations

LibreOffice Online/loleaflet-help (Catalan)
Currently translated at 100.0% (416 of 416 strings)

Change-Id: I3eb2ae88b732a3742af4944596b0f4f7122180d3

update translations

LibreOffice Online/android-lib (Asturian)
Currently translated at 66.7% (8 of 12 strings)

Change-Id: I713913b024033fa9e8e06edc243e532a382ac4f0

update translations

LibreOffice Online/loleaflet-ui (German)
Currently translated at 100.0% (310 of 310 strings)

Change-Id: Ife17fbfb627fa2c173d6d3cc33fb50a3c784fca5

update translations

LibreOffice Online/loleaflet-ui (Bulgarian)
Currently translated at 100.0% (310 of 310 strings)

Change-Id: I383adf870d21c2e9b6e939294aec7c11258425c8

update translations

LibreOffice Online/android-app (Aragonese)
Currently translated at 15.7% (16 of 102 strings)

Change-Id: I8ee54ee85e93bca217b4d4b5544bada5c4d9a41d

update translations

LibreOffice Online/loleaflet-help (Norwegian Bokmål)
Currently translated at 100.0% (416 of 416 strings)

Change-Id: I66dc80932af86f79beb935fb2eb12a9e04b4b433

update translations

LibreOffice Online/loleaflet-help (Catalan)
Currently translated at 99.3% (413 of 416 strings)

Change-Id: I6272c80011ca1814ccca4ee82f59448d65abf8dd

update translations

LibreOffice Online/loleaflet-help (Norwegian Bokmål)
Currently translated at 100.0% (416 of 416 strings)

Change-Id: I1c401adac23717f6fbcc0d0de5a216ef6ab7fef6

update translations

LibreOffice Online/loleaflet-help (Norwegian Bokmål)
Currently translated at 91.8% (382 of 416 strings)

Change-Id: I52fc7b25e082065d64de41a37d5077c2befbacc6

update translations

LibreOffice Online/loleaflet-help (Norwegian Bokmål)
Currently translated at 91.6% (381 of 416 strings)

Change-Id: If5aecd97151209fb75ed2cea33dcac7051e60c63

update translations

LibreOffice Online/android-app (Galician)
Currently translated at 100.0% (102 of 102 strings)

Change-Id: Iffeb20081b0293474345fd687e9a4cf13b2d948b

update translations

LibreOffice Online/ios (Galician)
Currently translated at 100.0% (5 of 5 strings)

Change-Id: If9c7f39737f3772fdf5ce2fe171208b0082a8a25

update translations

LibreOffice Online/loleaflet-help (Norwegian Bokmål)
Currently translated at 91.3% (380 of 416 strings)

Change-Id: I3caa151434e98edf0cc9183b4ed149020839f6bb

update translations

LibreOffice Online/loleaflet-ui (Galician)
Currently translated at 98.4% (305 of 310 strings)

Change-Id: I06ddd95ca3598f347f3e34ff2456379635ffce6d

update translations

LibreOffice Online/loleaflet-help (Norwegian Bokmål)
Currently translated at 57.2% (238 of 416 strings)

Change-Id: Id2ba68902ee4b6854777e84e55ab1c99946d4eab

update translations

LibreOffice Online/loleaflet-help (Norwegian Bokmål)
Currently translated at 57.0% (237 of 416 strings)

Change-Id: I541d37572571ba2da7603762d09c957ccb52f693

update translations

LibreOffice Online/loleaflet-help (Norwegian Bokmål)
Currently translated at 55.8% (232 of 416 strings)

Change-Id: I8d7f14bc8174c6ff1d6b7a429b1ac2266ecccc16

update translations

LibreOffice Online/loleaflet-ui (Norwegian Bokmål)
Currently translated at 100.0% (310 of 310 strings)

Change-Id: I319415a0d70b6d3c3c090650a6e0d62ff0882ab5

update translations

LibreOffice Online/loleaflet-help (Galician)
Currently translated at 100.0% (416 of 416 strings)

Change-Id: I5807199acdd8cd79233f7033bf6d5d89fbf7f5af

update translations

LibreOffice Online/loleaflet-ui (English (United Kingdom))
Currently translated at 100.0% (310 of 310 strings)

Change-Id: Ifde7480c5779f55dcd127a75c8fd903dd479daa5

update translations

LibreOffice Online/android-app (Aragonese)
Currently translated at 11.8% (12 of 102 strings)

Change-Id: I012b57eb90a6b16f00a6053ad7038dbe18152c4f

update translations

LibreOffice Online/loleaflet-help (Chinese (Simplified))
Currently translated at 68.0% (283 of 416 strings)

Change-Id: I38384bb1ade4521b1828e40f0dea64f9ab037e26

update translations

LibreOffice Online/loleaflet-ui (Spanish)
Currently translated at 100.0% (310 of 310 strings)

Change-Id: I6e1c37531d1f6d532a6d7c42641e71cfc916f884

update translations

LibreOffice Online/loleaflet-ui (Catalan)
Currently translated at 100.0% (310 of 310 strings)

Change-Id: I90281c9f82c0609f6f4e6de27e2f9363cfcf4e06

update translations

LibreOffice Online/loleaflet-ui (Asturian)
Currently translated at 43.9% (136 of 310 strings)

Change-Id: I3d17424e05d980dddd0c87aa055f5f5bfaa0ee9f

update translations

LibreOffice Online/loleaflet-help (Chinese (Simplified))
Currently translated at 66.8% (278 of 416 strings)

Change-Id: I2b1591c5e1f1514be5b1e6f0406151dfa985b661

update translations

LibreOffice Online/loleaflet-help (Chinese (Simplified))
Currently translated at 66.1% (275 of 416 strings)

Change-Id: Ie73286a61390be591ca3b0b1039fca3f035afbf4

update translations

LibreOffice Online/loleaflet-ui (Basque)
Currently translated at 100.0% (310 of 310 strings)

Change-Id: I712c841f5837f22df2019abe3f72f4e7763a2e69

update translations

LibreOffice Online/loleaflet-ui (Greek)
Currently translated at 100.0% (310 of 310 strings)

Change-Id: Id25ebbf8c4c0c7c00f35b934c3fd3adcd5b72461

update translations

LibreOffice Online/loleaflet-help (Chinese (Simplified))
Currently translated at 65.6% (273 of 416 strings)

Change-Id: I07b37df403e7345a5b9cad80a44ac0070ee368d8

update translations

LibreOffice Online/loleaflet-help (Chinese (Simplified))
Currently translated at 64.7% (269 of 416 strings)

Change-Id: I31a21c6600b993c266ba375a1ea93111bc65c74b

update translations

LibreOffice Online/loleaflet-help (Chinese (Simplified))
Currently translated at 64.7% (269 of 416 strings)

Change-Id: Id661ca39ef89f1f86b3161a302db8ba4801692c5

update translations

LibreOffice Online/loleaflet-ui (Italian)
Currently translated at 100.0% (310 of 310 strings)

Change-Id: I0d7e3fd020235c71e964f4c1d7bf92ab6f176fb5

update translations

LibreOffice Online/loleaflet-help (Swedish)
Currently translated at 49.0% (204 of 416 strings)

Change-Id: I60ce386ff42bf7d3d3a2c0ae43414532cbd8f602

update translations

LibreOffice Online/loleaflet-ui (Swedish)
Currently translated at 100.0% (310 of 310 strings)

Change-Id: I6c603872a399e9296e7193d596c6e4ed04965a87

update translations

LibreOffice Online/loleaflet-ui (Welsh)
Currently translated at 100.0% (310 of 310 strings)

Change-Id: I0fefe612dc756b714810fd4e8b333b7f6262bd1e
Reviewed-on: https://gerrit.libreoffice.org/c/online/+/96056
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com>
Tested-by: Jenkins
Reviewed-by: Andras Timar <andras.timar@collabora.com>
2020-06-26 20:22:44 +02:00
..
admin leaflet: Introduce typescript. Initiate a modal library with typescript. 2020-06-09 14:33:40 +02:00
archived-packages loleaflet: update archived packages. 2020-06-12 08:11:55 +02:00
css notebookbar: set correct height for calc 2020-06-25 14:34:16 +02:00
docs
html Desktop: Set max size for document name's width 2020-06-11 12:54:38 +02:00
images notebookbar: missing icons 2020-06-19 12:40:50 +02:00
js leaflet: update jquery package. 2020-06-11 13:00:52 +02:00
l10n loleaflet: update UNO command translations 2020-06-24 09:08:35 +02:00
po update translations 2020-06-26 20:22:44 +02:00
src notebookbar: cached home tab 2020-06-26 15:25:47 +02:00
test
util
welcome
.eslintignore
.eslintrc
.gitattributes
.gitignore loleaflet: update archived-packages 2020-05-25 20:13:57 +02:00
.npmignore
.travis.yml
bundle.js.m4
LICENSE
loleaflet-src.js.m4
Makefile.am Fix dependencies of the TypeScript file. 2020-06-25 09:41:28 +02:00
npm-shrinkwrap.json.in loleaflet: update archived packages. 2020-06-12 08:11:55 +02:00
package.json leaflet: update jquery package. 2020-06-11 13:00:52 +02:00
README typo fixes in comments and code 2020-04-26 23:19:52 +02:00
reference.html typo fixes in comments and code 2020-04-26 23:19:52 +02:00
tsconfig.json leaflet: Introduce typescript. Initiate a modal library with typescript. 2020-06-09 14:33:40 +02:00

Leaflet platform for LibreOffice Online
========================================

This is the client part of LibreOffice Online.  For the server part, see the
../wsd/README, and install it first.

Build dependencies
------------------

npm is provided by the nodejs package.

npm should be at least 2.14, if not 3.x. Use `npm -v` to find the current version.
Upgrade npm (as root):

    npm install -g npm

Another way is to use npm as a user, but set its prefix to a directory where
you have write access. If you want that, you need to have an ~/.npmrc with the
line e.g.

    prefix=/opt/npm

All of the dependency tree is locked in the repository, so there is no need to fetch
data from npm registry at all. An npm install will use the tarballs in node_shrinkwrap/
directory, so build process can move forward even without an internet connection.

To update any of the dependency, process often goes like this:

1.) Change version of the dependency in package.json
2.) Do an `npm update <package_name>', which fetches the new module from npm registry. Make sure that
    only the module that you want to update is updated.
3.) `npm shrinkwrap --dev` to update npm-shrinkwrap.json with newer information. You might see
    that this tool updates path convention of tarballs inside node_shrinkwrap/ also, but this
    should get corrected in next step.
4.) Do `shrinkpack', which should remove the old tarball, add new one, and make appropriate
    changes to npm-shrinkwrap.json (removing path convention changes by step 3).

If you have not installed `shrinkpack' globally using `npm install -g shrinkpack@next', it should be
in node_modules/.bin/shrinkpack, so you can use the binary from there.

If you need to get the sources:
	make libs

To bundle the file sanitize-url.js
	browserify braintree-sanitize-url/index.js --standalone sanitizeUrl > sanitize-url.js

Building
--------

Just do:

    make

Above step would create a non-minified bundle.js and admin-bundle.js without source-maps in dist/ for main loleaflet and admin console
respectively.

To build with debug-info, i.e with sourcemaps:

    make DEBUG=true

Above will produce source-map files, bundle.js.map and admin-bundle.js.map, for bundle.js and admin-bundle.js respectively.
It will also link existing bundle.js and admin-bundle.js to their map files by adding a sourceMappingURL to them. While debugging,
these .map files will be fetched from the server if present in dist/, otherwise there is no way to debug while browsing without these
source-map files.

To minify our bundle.js and admin-bundle.js passing a MINIFY=true flag to 'make' will minify it. This can be helpful in production
environments.

    make MINIFY=true

'make dist' forces minifying.

Running
-------

To see an example:

* run loolwsd, like:

    ./loolwsd --o:sys_template_path=${SYSTEMPLATE} --o:child_root_path=${ROOTFORJAILS}

Note that this will, by default, set the loolwsd's file server's root to the parent directory of loolwsd,
which means you can access all the files in loleaflet using /loleaflet/ path. It is advised to set
file_server_root_path manually for more control. See wsd/README for more information.

* open dist/loleaflet.html through loolwsd's fileserver

    https://localhost:9980/loleaflet/dist/loleaflet.html?file_path=file:///PATH/TO_DOC&host=wss://localhost:9980

and you should see the document in the browser.
Note that accessing local storage is disabled by default for security reasons. You need to explicitly enable it
with the --o:storage.filesystem[@allow]=true option of loolwsd. In case anything goes wrong, check the loolwsd console for
the debugging output. You might be asked to confirm the certificate if you are using self-signed certificate
for loolwsd.

Development
-----------

For faster development you might want to install browser-sync which can reload app in your browsers automatically
after you edit and save the source code (so for .css only):

npm install -g browser-sync

Remember to add '--enable-browsersync' argument for './configure' script and delete `dist` directory.

Run server and start browser-sync:

LOOL_SERVE_FROM_FS=1 make run

and in the second terminal:

make sync-[writer|calc|impress]

Your browser will open example document and now you can edit .css files and see the result without server restart.

To run another document use:
browser-sync start --config browsersync-config.js --startPath "loleaflet/96c23f663/loleaflet.html?file_path=file:///path/to/the/file.ods"

Admin Panel
-----------

You can do live monitoring of all the user sessions running on loolwsd instance. To access the admin
console you need to ask for admin.html file from loolwsd which resides in dist/admin/admin.html.

For example:

    https://localhost:9980/loleaflet/dist/admin/admin.html

It will ask for username and password which is set by the admin_console options of loolwsd. For example you can
pass --o:admin_console.username=admin --o:admin_console.password=admin in command line, or set these values in
loolwsd.xml. After entering the correct password you should be able to monitor the live documents opened, total
users, memory consumption, document URLs with number of users viewing that document etc. You can also kill the
documents directly from the panel which would result in closing the socket connection to the respective document.

API & events
------------

#######################################################################
# See /loleaflet/reference.html for a better formatted documentation. #
# See /wsd/reference.md for the HTTP API documentation.               #
#######################################################################

Search:
    - API:
        map.search(text, [backward])
        map.highlightAll(text)
    - events:
        map.on('search', function (e) {}) (currently only fired when no search result is found) where:
            + e.originalPhrase = the phrase that has been searched for
            + e.count = number of results
            + e.results = [SearchResult], where SearchResult = {part: part, rectangles: [Bounds]}

Zoom:
    - API:
        map.zoomIn(amount)
        map.zoomOut(amount)
        map.getMinZoom()
        map.getMaxZoom()
    - events:
        map.on('zoomend zoomlevelschange', function)

Edit, view, readOnly:
    - API:
        map.setPermission('edit' | 'view' | 'readonly')
    - events:
        map.on('updatepermission', function (e) {}) where:
            + e.perm == 'edit' | 'view' | 'readonly'

Buttons like Bold, Italic, Strike through etc.
    - API:
        map.toggleCommandState('.uno:' + 'Bold' | 'Italic' | 'Underline' | 'Strikeout' |
            'LeftPara' | 'CenterPara' | 'RightPara' | 'JustifyPara' |
            'IncrementIndent' | 'DecrementIndent'
    - events:
        map.on('commandstatechanged', function (e) {}) where:
            + e.commandName == '.uno:' + 'Bold' | 'Italic' | 'StyleApply' | 'CharFontName' | 'FontHeight' etc.
            + e.state = 'true' | 'false'
            + e.state = fontName | fontSize | styleName
        map.on('commandresult', function (e) {}) where:
            + e.commandName == '.uno:' + 'Bold' | 'Italic' | 'StyleApply' | 'CharFontName' | 'FontHeight' etc.
            + e.success = true | false | undefined

Parts (like slides in presentation, or sheets in spreadsheets):
    - API:
        map.setPart('next' | 'prev' | partNumber)
        map.getNumberOfParts()
        map.getCurrentPartNumber()
        map.getPreview(id, index, maxWidth, maxHeight, [options], forAllClients)
            + id = the ID of the request so that the response can be identified
            + index = the part / page 's number
            + maxWidth / maxHeight = max dimensions so that the ratio is preserved
            + options = {autoUpdate: <boolean>, broadcast: <boolean>} -
	      + autoUpdate - boolean, automatically updates the previews
	      + broadcast - boolean, whether the response (a preview of a slide) should be sent to all clients
                viewing the same presentation
        map.getCustomPreview(id, part, width, height, tilePosX, tilePosY, tileWidth, tileHeight, [options])
            + id = the ID of the request so that the response can be identified
            + part = the part containing the desired preview
            + width / height = the preview's size in pixels
            + tilePosX / tilePosY = the rectangles's starting position in twips
            + tileWidth / tileHeight = the rectangle's dimension in twips
            + options = {autoUpdate: true} - automatically updates the previews
        map.removePreviewUpdate(id)
            + id = the preview's id

    - events:
        map.on('updateparts', function (e) {}) where:
            + e.selectedPart is the current part
            + e.parts == the number of parts that the document has
            + e.docType == 'text' | 'spreadsheet' | 'presentation' | 'drawing' | 'other'
            + [e.partNames] if present, part names (e.g. sheet names)
        map.on('tilepreview', function (e) {}) where:
            + e.tile - the preview image
            + e.id - the preview id
            + e.width - width of the image
            + e.height - height of the image
            + [e.part] - if the preview is for a part
            + e.docType

Statusindicator (when the document is loading):
    - events
        map.on('statusindicator', function (e) {}) where:
            + e.statusType = 'start' | 'setvalue' | 'finish' | 'loleafletloaded' | 'alltilesloaded'
            + e.value == a value from 0 to 100 indicating the status
              if the statusType is 'setvalue
            + 'loleafletloaded' is fired when the JS code is initialized and the document
                load request is sent and we're waiting for the tiles
            + 'alltilesloaded' is fired when all newly requested (empty tiles) have been loaded
                it is not fired during pre-fetching and during editing

Save:
    - API:
        map.saveAs(url, [format, options])
        map.downloadAs(name, [format, options])

Scroll (the following are measured in pixels):
    - API:
            + options = An object with members: update (type: Boolean, default: false)
                like {update: true}
        map.scroll(x,y, options)
            + scroll right by 'x' and down by 'y' (or left and up if negative)
        map.scrollDown(y, options)
            + scroll down by 'y' (or up if negative)
        map.scrollRight(x, options)
            + scroll right by 'x' (or left if negative)
        map.scrollTop(y, options)
            + scroll to 'y' offset relative to the beginning of the document
        map.scrollLeft(x, options)
            + scroll to 'x' offset relative to the beginning of the document
        map.scrollOffset()
            + returns the scroll offset relative to the beginning of the document
        map.getDocSize()
            + returns the document's size in pixels
        map.getDocType()
            + returns 'text' | 'spreadsheet' | 'presentation' | 'drawing' | 'other'
    - events
        map.on('docsize', function (e) {}) where:
            + e.x = document width
            + e.y = document height
        map.on('updatescrolloffset', function (e) {}) where:
            + e.x = difference between document's left and current view's left
                (how much has the document been scrolled right)
            + e.y = difference between document's top and current view's top
                (how much has the document been scrolled down)
            - this event is fired when zooming and the current view is maintained but the
                document shrinks or grow OR when the document is panned OR when the container is resized
        map.on('scrollto', function (e) {}) where:
            + e.x = view's left position (so that the cursor/search result is in the center)
            + e.y = view's top position (so that the cursor/search result is in the center)
        map.on('scrollby', function (e) {}) where:
            + e.x = the amount scrolled to the right (or left if negative)
            + e.y = the amount scrolled to the bottom (or top if negative)

Writer pages:
    - API:
        map.goToPage(page)
        map.getNumberOfPages()
        map.getCurrentPageNumber()
        map.getPreview(id, index, maxWidth, maxHeight, [options])
            + id = the ID of the request so that the response can be identified
            + index = the part / page 's number
            + maxWidth / maxHeight = max dimensions so that the ratio is preserved
            + options = {autoUpdate: true} - automatically updates the previews
        map.getCustomPreview(id, part, width, height, tilePosX, tilePosY, tileWidth, tileHeight, [options])
            + id = the ID of the request so that the response can be identified
            + part = the part containing the desired preview
            + width / height = the preview's size in pixels
            + tilePosX / tilePosY = the rectangles's starting position in twips
            + tileWidth / tileHeight = the rectangle's dimension in twips
            + options = {autoUpdate: true} - automatically updates the previews
        map.removePreviewUpdate(id)
            + id = the preview's id
        map.getPageSizes()
            + returns {twips: [Bounds], pixels: [Bounds]}

    - events
        map.on('pagenumberchanged', function (e) {}) where:
            + e.currentPage = the page on which the cursor lies
            + e.pages = number of pages
            + e.docType = document type, should be 'text'

Error:
    - events
        map.on('error', function (e) {}) where
            + [e.msg] = a message describing the error
            + [e.cmd] = the command that caused the error
            + [e.kind] = the kind of error

Infobars:
    - events
        map.on('infobar', function (e) {}) where
            + [e.msg] = a message
            + [e.actionlabel] = Label for the action button
            + [e.action] = A link (starting with http).
                           Please extend to allow other actions when needed.

CommandValues:
    - api:
        map.getToolbarCommandValues(command)
            + returns a JSON mapping of all possible values for the command
        map.applyFont(fontName)
        map.applyFontSize(fontSize)
        map.applyStyle(style, styleFamily)
    - events
        map.on('updatetoolbarcommandvalues', function (e) {}) where
            + e.commandName = '.uno:StyleApply', etc
            + e.commandValues = a JSON mapping of all possible values for the command

Print:
    - events
        map.on('print', function (e) {}) where
            + e.url = file download url

Contributing
------------

Code conventions:

    * files should have unix line terminators (LF)
    * tools to convert files: dos2unix or fromdos

Implementation details
----------------------

Loading a document:
    The map should have the following options:
        - server address
        - doc - path to the document that will be loaded
        - edit = the initial permission
        - readOnly - whether the document is read only
        - [timestamp] - optionally provided for remote documents

How zooming works:
    The zoom level goes from 1 to 20 (those limits can be changed) and the initial
    level is 10, which represents the 100% zoom level. The zoom factor is 1.2

Controls are added above the map in a div called "controls" is intended to be used as a toolbar.
There is no leaflet method of adding them in a separate div, so for now this is done in the html
document after the map initialization.

To enable scrollbars the map is placed above a div that contains a bigger div of
the document's size (a mock document). So the div under the map gets scrollbars which
are independent of the map's div, thus enabling us to link them to the map as needed.
When the user scrolls, the map is panned by the same amount as it would've been scrolled.
Also, some custom jquery scrollbars are used, to trigger the same scroll events across
browsers.

Z-index values:
-------------------------------------------
		leaflet
-------------------------------------------
10			map
11			ruler
-------------------------------------------
		under menu
-------------------------------------------
990			sidebar
999			toolbar-up
-------------------------------------------
		menu items
-------------------------------------------
1000			main-menu(desktop-only), toolbar-down
1050			closebuttonwrapper (not being used currently)
-------------------------------------------
		on the top
-------------------------------------------
1105			dialogs
1001			mobile-edit-button
1500			mobile-wizard (with class=menuwizard)
1501			toolbar-hamburger (with class=menuwizard-opened)
2000			vex-overlay
2001			vex dialog (vex-content)
-------------------------------------------