This is an interesting product. You might want to hear more about it. This is an interesting product. You might want to hear more about it.
This is an interesting product. You might want to hear more about it. This is an interesting product. You might want to hear more about it.Documentation for Kicksecure Wiki Devs
Layout, Skin, CSS, JavaScript, Links, Header, Footer, CodeSelect, Mobile Frontend, Miscellaneous
Getting Started - MediaWiki Setup (meta)[edit]
- This documentation is meant for developers helping with the maintenance and improvement of this wiki. Editors please read Dev/wiki instead.
- This Wiki is a MediaWiki instance. We use a MediaWiki standard, stable installation, which is held up-to-date.
- Why did we choose MediaWiki: Dev/About_Infrastructure#MediaWiki
- Icons: We use Font-Awesome, locally hosted https://www.kicksecure.com/libs/Font-Awesome/
- Font: We use Roboto, locally hosted https://www.kicksecure.com/libs/Roboto/
Extension CSS Fork[edit]
- We use the MediaWiki Extension:CSS, but a fork which we wrote ourselves.
- The extension and the fork in general have 3 options: One to write page specific inline CSS in the MediaWiki page itself. The second option allows to link locally hosted CSS files. The third option allows to link internal CSS pages raw as files
- Caution: The first option of this ORIGINAL extension (not our fork) for a page specific CSS seems experimental to us, because the CSS text is encoded as a base64 string and imported link so
<link rel="stylesheet" href="data:text/css;charset=UTF-8;base64,I3Np...Q7Cn0=">
. This is not widely supported in all browsers so this options does not seem reliable and therefore is not recommended for production use!
- Caution: The first option of this ORIGINAL extension (not our fork) for a page specific CSS seems experimental to us, because the CSS text is encoded as a base64 string and imported link so
- Our fork
- Usage option 1 - locally hosted: You can reference locally hosted files, e. g.
{{#css:/src-copy/Page_Homepage.min.css}}
. NOTE: For this the file has to be hosted in the locally allowed folder. In our case this is set to/mw-autogen
in localSettings.php via the variable $wgCSSPath which belongs to the Extension:CSS . This means our example{{#css:/src-copy/Page_Homepage.min.css}}
actually (relatively) references the local file/mw-autogen/src-copy/Page_Homepage.min.css
- NOTE: Please ALWAYS use the postfix
. This ensures that files are always loaded in their currect up-to-date version
- NOTE: Please ALWAYS use the postfix
- Usage option 2 - from the DB: You can reference files hosted in the DB, e.g.
{{#css:Mediawiki:Your-local-styles.css}}
. This calls the file from the wiki. In our fork we allow the admin to set allowed namespaces, so CSS files in these namespaces are not "sanitized" by Mediawiki which sometimes leads to unexpected problems. In our case we set the namespace "MediaWiki:" to be not sanitized - [Generally deprecated] Usage option 3 - inline: [This option should only be used for testing or specific use cases where an interaction with wiki content like templates is strictly necessary] You can write inline code, e.g.
{{#css: body { background-color: green; } }}
. Our fork implements this as a style-tag (instead of a link tag with base64 like the original extension, see above)
- Usage option 1 - locally hosted: You can reference locally hosted files, e. g.
- MediaWiki upstream: mediawiki-extension-css feature requests and patches:
- feature request: Enable unsanitized CSS namespaces
- patch / pull request: Some CSS stripped by MediaWiki parser CSS sanitizer
- feature request: MediaWiki-extensions-CSS: minify CSS
Extension HeadScript[edit]
- We use the MediaWiki Extension:HeadScript to circumvent the usual code inclusion into the
<head>
area. This is only used where MediaWiki doesn't offer a realistic option to realize a solution otherwise. See LocalSettings.php for the implementation of Headscript - See the bottom of this chapter for a current snapshot of the content that we include via Headscript
- Solved by this
- Font-Awesome is included that way
- Other libraries are included
- Our general minified css included
- Our general minified JavaScript included
- Our favicon is included
- MediaWiki Common.js dependent and core JS dependent scripts and libraries are triggered
- Additional info : In the top comment there are multiple relevant variables printed in their current state
server-type
indicates if it's production or developmentPath to scripts
: The path where CSS and JS files are situatedWiki page
: The actual url page name for the wiki page. This variable can be used in the scriptdebug
: This query parameter determines if the minified version or the readable version is printed (ifdebug = true
)dontload
: This parameter offers to not load our auto-generated js or css files. There are 3 options:?dontload=js
?dontload=css
and?dontload=jscss
$wgResourceLoaderDebug
is a setting forLocalSettings.php
where the whole wiki can go into debug mode. Similar to the url parameter debug
Current snapshot of the content that we include via Headscript
<!-- Begin Extension:HeadScript ------------------------------- * server-type : production * Path to scripts : /mw-autogen * Wiki page: Dev/mediawiki * Url query parameter "debug" : undefined * Url query parameter "dontload" : undefined * $wgResourceLoaderDebug : "" (empty string) --> <link rel="icon" type="image/svg+xml" href="/favicon.svg?hsversion=2" sizes="any"> <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png?hsversion=2"> <link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png?hsversion=2"> <link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png?hsversion=2"> <link rel="manifest" href="/site.webmanifest?hsversion=2"> <link rel="mask-icon" href="/safari-pinned-tab.svg?hsversion=2" color="#5bbad5"> <meta name="theme-color" content="#ffffff"> <meta name="msapplication-TileColor" content="#da532c"> <link rel="preload" href="/libs/Roboto_2023-08-03/Roboto-Regular-webfont.woff" as="font" crossorigin fetchpriority="low"> <link rel="preload" href="/libs/Roboto_2023-08-03/Roboto-Light-webfont.woff" as="font" crossorigin fetchpriority="low"> <link rel="preload" href="/libs/Cousine_2023-08-03/Cousine-Regular.woff" as="font" crossorigin fetchpriority="low"> <link rel="preload" href="/libs/Font-Awesome_2023-08-03/webfonts/fa-solid-900.woff2" as="font" crossorigin fetchpriority="low"> <link rel="preload" href="/libs/Font-Awesome_2023-08-03/webfonts/fa-regular-400.woff2" as="font" crossorigin fetchpriority="low"> <link rel="preload" href="/libs/Font-Awesome_2023-08-03/webfonts/fa-brands-400.woff2" as="font" crossorigin fetchpriority="low"> <style> @font-face { font-family: Roboto; src: url(/libs/Roboto_2023-08-03/Roboto-Regular-webfont.woff); font-display: swap; } @font-face { font-family: Roboto; font-weight: 300; src: url(/libs/Roboto_2023-08-03/Roboto-Light-webfont.woff); font-display: swap; } @font-face { font-family: Cousine; src: url(/libs/Cousine_2023-08-03/Cousine-Regular.woff); font-display: swap; } </style> <link rel="stylesheet" media="print" onload="this.media='all'" href="/libs/Font-Awesome_2023-08-03/css/fontawesome.min.css" fetchpriority="low"> <link rel="stylesheet" media="print" onload="this.media='all'" href="/libs/Font-Awesome_2023-08-03/css/solid.min.css" fetchpriority="low"> <link rel="stylesheet" media="print" onload="this.media='all'" href="/libs/Font-Awesome_2023-08-03/css/regular.min.css" fetchpriority="low"> <link rel="stylesheet" media="print" onload="this.media='all'" href="/libs/Font-Awesome_2023-08-03/css/brands.min.css" fetchpriority="low"> <script id="js-cookie-script" defer fetchpriority="low" src="/libs/jscookie/js.cookie.min.js?hsversion=2"></script> <link rel="stylesheet" fetchpriority="low" media="print" onload="this.media='all'" href="/libs/Prism/prism.css?hsversion=2" > <script id="highlight-code-script" defer fetchpriority="low" src="/libs/Prism/prism.js?hsversion=2" data-manual></script> <script type="module" defer src="/libs/instant.page/instantpage.min.js?hsversion=2"></script> <script type="text/javascript" defer id="core-dependent-libs"> (function() { const coreDependentLibs = ["\/libs\/jquery-tinyscrollbar_2024-08-21\/jquery.tinyscrollbar.min.js"]; function triggerWhenReady() { let deferred = []; for( const i in coreDependentLibs ) deferred.push( $.getScript( coreDependentLibs[i] ) ); $.when.apply($, deferred).done(function() { window.mediaWikiCommonJsAndHeadscriptcoreDependentLibsAreLoaded = true; window.dispatchEvent( new Event("mediaWikiCommonJsAndHeadscriptcoreDependentLibsAreLoaded") ); }); } if( window.mediaWikiCommonJsIsLoaded ) triggerWhenReady(); else window.addEventListener( "mediaWikiCommonJsIsLoaded", triggerWhenReady ); })(); </script> <link rel="stylesheet" href="/mw-autogen/mw-combined-wikicss.min.css?hsversion=2&version=1726479024"> <script defer src="/mw-autogen/mw-combined-wikijs.min.js?hsversion=2&version=1726479024"></script> <!-- ------------------------ /End Extension:HeadScript -->
Fonts[edit]
- Our fonts are now also referenced and loaded with
preload
this way for better performance. This includes Roboto (regular font), Cousine (monospace font for pre, code etc) and Font Awesome (Icons)- Regarding preload a good article as a resource is this: https://www.debugbear.com/blog/rel-preload-problems
- If crossorigin is omitted the fonts are loaded twice due to the crossorigin settings on the server
- Only
preload
is possible.defer
orasync
is only supported by browsers for scripts but not for fonts.
- No hsversion: All files called in Headscript usually have a headscript version number (exact parameter
hsversion_from_server_replacement_unixtime
) added to the URL so it can be controlled when the user browser has should fetch the files again so the user is up-to-date with the most recent file versions.- However FontAwesome loads its webfonts via the CSS file already. So if the URL for the font-preloading that we're doing is not the same URL as in the CSS then the webfont file is loaded twice which negatively impacts performance. This was the case previously as we were using the headscript version number, because the CSS file references the webfont without a headscript version number. And this cannot be changed.
- So now we removed the headscript version number from all fonts and the double loading bug is fixed.
- We also changed the FontAwesome folder name and the other font folder names to include the a date when we added them. This way when a new version is available the folder can be changed reflecting the then-current date and the user browser will fetch the newest version
BUILD: File auto-generation, Combine, Minify, Host Locally, mw-autogen, src-copy[edit]
- We use #Extension HeadScript to include our own auto-generated files in the wiki page
- These files are generated from our repository files, through a specific process using our own scripts
- We created the file config-build-(shared and specific).json /tree/master/mediawiki-shared/build config-build-(shared and specific).json. In this file we describe a build order for all JavaScript files. And also for all CSS files.
- Note that this file has to have a specific structure. Top level are the keywords "wikijs" (JS applied to the whole wiki), "wikicss" (CSS applied to the whole wiki), "skincss" (CSS only if the custom header is present) and "justcopy" (files that will just by copied, not combined). Also there can be the keyword "__comments" at the top which will be ignored by the parse.
- Every of those keywords has an array of strings below them. These string should all be callable wiki file pages like "MediaWiki:Header.css" etc. Exception: You can use comments if a string STARTS with "//"
- Then we created a php build script which has to be executed and combines all files which are mentioned in config-build-(shared and specific).json /tree/master/mediawiki-shared/build config-build-(shared and specific).json and which are then loaded from the wiki files pages. After that the build script combines all files and saves them to the folder /mw-autogen as a - what we call - "mw-combined"-file and minifies it and saves it to a second file "mw-combined.min" etc.
- These files are then called via #Extension_HeadScript and can also be called in their human readable form if the URL has the parameter ?debug=true
- The source files are also copied to a subfolder /mw-autogen/src-copy/ for optional use by other software (e. g. forums) on the same web domain. And for each file a minified version is also created in the same folder [filename.ext] + [filename.min.ext]
- We created the file config-build-(shared and specific).json /tree/master/mediawiki-shared/build config-build-(shared and specific).json. In this file we describe a build order for all JavaScript files. And also for all CSS files.
- specific locations
- Kicksecure autogen folder : https://www.kicksecure.com/mw-autogen
- Whonix autogen folder : https://www.whonix.org/mw-autogen
- Kicksecure combine script : https://admin.kicksecure.com/mw-combine.php (Admin access needed)
- Whonix combine script : https://admin.whonix.org/mw-combine.php (Admin access needed)
- By these measures we drastically improved the load time of the wiki, made it really stable and functional again and circumvented the use of Common.js as also suggested by Wikipedia
- NOTE: By using this solution the source files (css js etc) are not directly called when the page is loaded. They are merely the source which the combined, minified files are rendered from. So every time there is a change in the source files it first has to be rendered to the output files.
- One exception is the use of Extension:CSS where we want to use scripts only on specific pages like so
{{#css:/src-copy/Page_Homepage.min.css}}
. In this case the source copy folder is very useful
- One exception is the use of Extension:CSS where we want to use scripts only on specific pages like so
build.sh, build-mw-combine.php, deploy-to-servers-or-locally.sh[edit]
- The build process explained
- On the server
- First the server pulls the current state of the
mediawiki-customized-dist
repository. build.sh
is called. This script determines on which server it is executed and calls build-mw-combine.php with this information as its first parameter (currently:kicksecure
orwhonix
)build-mw-combine.php
reads all source files and renders them into theautogen-src-copy-folder
and combines them into minified files and writes them to theautogen-folder
. Furthermore a log file is written
- First the server pulls the current state of the
- For the local dev
- Local dev calls
deploy-to-servers-or-locally.sh
- This script first prompt if he wants to use a local path. If so then the
build.sh
is called with the local path and renders the files (like described above) for every keyword available currently:kicksecure
orwhonix
). The script ends then. No git or server actions are performed. - If dev does not give a local path then git actions are performed (checking if up-to-date etc). Then dev is prompted for a commit message (empty=exit) and current changes are committed and pushed.
- This script first prompt if he wants to use a local path. If so then the
- Finally
request-servers-to-fetch-and-deploy.sh
is called with user credentials for kicksecure and whonix to trigger both servers to update. All urls, paths and credentials are secret to protect server security and are located in a file calledsecrets-for-request-servers-to-fetch-and-deploy.sh
.- On the server the process is as described above.
- Local dev calls
- On the server
- Files specifically
- Build files to study: /tree/master/mediawiki-shared/build
build.sh
is a wrapper for build-mw-combine.php that tests the needed commands, checks or constructs paths and calls mw-combine for all needed keywords. It is used by the servers to render the combined production files and by the local dev for the same purpose locally as well- Parameter 1 (basePath), optional: This parameter represents a base path for where the rendered combined productions files are written
build-mw-combine.php
is called by build.sh to perform its core purpose while doing the heavy lifting in more feature rich PHP- Parameter 1 (server keyword), optional, default:'kicksecure': This parameter represents they keyword for which server this script is executed on to fetch the correct source files for this specific server
- Parameter 2 (basePath), optional, default:[emptyString]: This parameter represents a base path for where the rendered combined productions files are written. This path is used as a prefix to all rendering paths
config-build-kicksecure.json
andconfig-build-shared.json
andconfig-build-whonix.json
are the config files for the build process. They have an equal structure. More info on these files here BUILD:_File_auto-generation...deploy-to-servers-or-locally.sh
is a script only used by the local dev either to locally build from his current local state or to git push and trigger the servers to updaterequest-servers-to-fetch-and-deploy.sh
is a script that calls secrets-for-request-servers-to-fetch-and-deploy.sh for credentials, urls and paths. It then triggers all servers to fetch the current git data and update via build.shsecrets-for-request-servers-to-fetch-and-deploy.sh
(NOT part of the repo) has all the credentials, paths and urls for request-servers-to-fetch-and-deploy.sh as variables.
Javascript specific[edit]
- We decided to not use Mediawiki:Common.js to implement a lot of JavaScript.
- Calling a lot of JavaScript files via Common.js lead to unexplainable errors in MediaWiki, even small crashes (site not available even when it was) and considerably longer load times.
- Our speculation is that Common.js or the mw.loader.load uses some pre-parsing to check if JS-files are safe. Other speculation is that it just creates to much load if JavaScript files are always freshly loaded from the wiki db
- Even Wikipedia states in their
MediaWiki:Common.js
:
- Keep code in MediaWiki:Common.js to a minimum as it is unconditionally
- loaded for all users on every wiki page. If possible create a gadget that is
- enabled by default instead of adding it here (since gadgets are fully optimized ResourceLoader modules with possibility to add dependencies etc.)
- Since custom scripts offer additional functionality but might degrade performance or break unrelated functionality (even noJS functionality such as session handling) they have to be handled with care.
- As earlier discussed in this chapter Mediawiki:Common.js cannot be used to integrate scripts. However we want to know when Common.js is loaded so we can be sure that the core modules are loaded - specifically jQuery and others
- Therefore we introduced a Javascript specific wrapper which is used only in generated files for Javascript. This wrapper is not listed in the config-build-(shared and specific).json /tree/master/mediawiki-shared/build config-build-(shared and specific).json under "generaljswrapper". This file is currently MwCombineJsWrapper.js. The file will be pulled and then split at the keyword "/*WRAPPEDCONTENT*/". The first part comes before all other Javascript. the second part comes after all Javascript.
- In the Wrapper you will find that we listen to an event called "mediaWikiCommonJsIsLoaded". This event is triggerd in Common.js and is the only use that we have for Common.js
- The wrapper also introduces the property mwDev globally into the window object. This is basically a variable for us to share data between scripts and other dev strategies. The data is shared in the sub property mwDev.info
- Also we use this wrapper for the dontload functionality which you can learn more about in our convenience tool Dev/mediawiki#Debug-via-url-modal for this purpose
Javascript source mapping[edit]
- In order to be very transparent and debug more easily we decided to use a source map for our combined wiki js file
- Here is the documentation for source maps https://firefox-source-docs.mozilla.org/devtools-user/debugger/how_to/use_a_source_map/index.html
- Our wiki-JS is combined and rendered into https://www.kicksecure.com/mw-autogen/mw-combined-wikijs.js and minified to https://www.kicksecure.com/mw-autogen/mw-combined-wikijs.min.js
- For all other purposes we use
minify
, but for Javascript we useuglifyjs
for its source map capabilities - In addition to the minified JS file uglify creates a source map https://www.kicksecure.com/mw-autogen/mw-combined-wikijs.min.js.map that references the combined source file (from which the minified file is created)
- Also the comment
//# sourceMappingURL=/mw-autogen/mw-combined-wikijs.js
is automatically added to the minified file
- This way developers can find problems and study the source code even though the minified JS file is loaded for normal users
- Some information on uglify
- This is the official documentation https://www.npmjs.com/package/uglify-js . But it might be a bit confusing
- This is the command we're using (only [file-dir] is a placeholder)
uglifyjs '/[file-dir]/mw-autogen/mw-combined-wikijs.js' --output '/[file-dir]/mw-autogen/mw-combined-wikijs.min.js' --source-map "base='/[file-dir]/mw-autogen',root='/mw-autogen',url='/mw-autogen/mw-combined-wikijs.min.js.map'"
- The first parameter is the source file
- --output or -o specifies the target file
- [DEPRECATED-BY-US] --compress removes unnecessary the code. We don't use this anymore because this led to errors of variables being removed that we actually needed. See https://stackoverflow.com/questions/54119790/prevent-gulp-uglify-from-stripping-out-es6
- [DEPRECATED-BY-US] --mangle "minifies" the names in the code (renames to shorter names if possible and if not accessible to external functions). We don't use this anymore because it's error prone linke --compress
- --source-map creates the source map
- All it's sub parameters have to be wrapped in one big quote.
- base - this sub parameter specifies the base path in the file system. This path will be OMITTED in the source map "sources" property. Example: If a file has
/[file-dir]/file1.js
andbase='/[file-dir]'
then in sources it will be listed as"sources":["file1.js"]
else it would have its full path - root - this sub parameter specifies the url route (path) that the browser needs to find the file. This will be added to sourcesRoot in the source map. Example: If a file has
/[file-dir]/file1.js
andbase='/[file-dir]/'
(see description above for this part) androot='/public'
then in source map it will be listed as"sourceRoot":"/public","sources":["file1.js"]
and the browser would find the source file under/public/file1.js
- url - the url sub parameter is the browser route (path) to the source map. It tells the browser where the source map is located in case the user (most likely developer) requests the source code
Exceptions[edit]
- Header CSS files : This is also done for general CSS files. The header CSS files however are not included via #Extension_HeadScript but in the Template:Header via our #Extension_CSS_Fork
For contributors: editor setup[edit]
- All repository files can be edited using every professional editor on the market
- However contributors are asked to follow specific rules
- Especially you are asked to configure your editor to adhere to these specific style requirements when saving a file
- Remove trailing whitespaces
- Remove multiple trailing newlines
- Add exactly one final newline at the end of a file
- With VSCode for example you can insert these three lines into your settings.json
"files.trimTrailingWhitespace": true, "files.insertFinalNewline": true, "files.trimFinalNewlines": true,
jQuery dependent and other wiki core dependent libraries and scripts[edit]
- Normally all project scripts are executed DIRECTLY AFTER the mediawiki core is ready as described above
- Sometimes we need to use libraries which are dependent on the wiki core. And then we have project scripts dependent on these (core dependent) libraries
- These dependencies can be securly guaranteed via a functionality in headscript, done via a script tag with the id core-dependent-libs which is triggered when the core (including jquery) is ready. After loading the libraries an event is triggered that can be used by scripts dependent on these libraries
- For Devs
- To add wiki core (and jquery) dependent libraries devs can add the library as a url in headscript in the
$coreDependentLibs
array - To add core-dependent-library-dependent scripts devs can use
mwDev.tools.wikiCoreDependentLibsReady( function() {...});
as a wrapper around project files instead of the usual(function(){...})();
wrapper- And example can be found in CustomScrollbar.js
- To add wiki core (and jquery) dependent libraries devs can add the library as a url in headscript in the
Extension CookieToBodyClass[edit]
- We created our own Mediawiki extension CookieToBodyClass.
- This extension passes cookies through the server back to a CSS class in the body tag
- This is especially useful for cookies written with Javascript which then in turn can activate CSS styling AS SOON as the page is loaded and NOT JUST when Javascript is finally loaded. This simplifies styling in some cases extremely because there's no need to wait for Javascript to add some crucial class
- Usage
- It's as simple as writing a cookie - via Server or Javascript
- The cookie HAS TO have the prefix "ctbc_" (which stands for CookieToBodyClass). For example "ctbc_myTestCookie"
- The value given to the cookie has to be CSS class compatible, a regexp representing this is:
/^-?[_a-zA-Z]+[_a-zA-Z0-9-]$/
. For example "my-testValue" - When the page is loaded the next time this will result in a combination of cookie name and value as a body class. For example
<body class="ctbc_myTestCookie_my-testValue ...
- When the dev has chosen a value that is not CSS friendly, for example "my/testValue", the body class will be a CSS compatible error for the dev. For example
<body class="ctbc_myTestCookie_ctbc-error_cookie-value-not-css-compatible ...
- This error is a compromise so the user does not see any error on the site, but also so the dev has a change to identify and / or catch errors
- Other use cases
- This is also an excellent tool for testing: The dev can create a cookie just in his own browser like "ctbc_mycookie" and set it to whatever he likes e. g. "2". Not he can write CSS and JS cases to just react conditionally on this cookie existing. CSS
body.ctbc_mycookie_2 .my-class{...}
. JSif( Cookies.get('ctbc_mycookie') == '2' ) {...}
- This is also an excellent tool for testing: The dev can create a cookie just in his own browser like "ctbc_mycookie" and set it to whatever he likes e. g. "2". Not he can write CSS and JS cases to just react conditionally on this cookie existing. CSS
Extension BodyScript2 - not in use[edit]
- We created an extension based on the outdated BodyScript-extension and the still active HeadScript extension BodyScript2
- With the variable $wgBodyScript2Code in LocalSettings.php we can insert Code at the end of <body> with the help of the hook onSkinAfterContent
Extension Flagged Revisions[edit]
- We use the Extension Flagged Revisions to manage content on our wikis. As our content is security and privacy relevant it would not be acceptable to have unexamined content be shown to visitors. However we are always thankful for good content contributions which are mostly accepted. Flagged revisions prevents unchecked content from being shown to visitors and gives a practical way to manage revisions.
- The top bar will only be shown to admins if there is a pending revision which the admin then can easily accept
- The bottom bar is always present and gives admins the opportunity to directly accept and unaccept a revision, give a comment and rate the revision in question for accuracy
- The bottom bar is optically modified via CSS due to our usage of the footer. See #MediaWiki_limitations
Extension Dark Mode[edit]
- We use the extension https://www.mediawiki.org/wiki/Extension:DarkMode to offer our users a dark mode experience on our Wikis
- The extension uses a css filter to invert all colors on the page to dark - except images. We add our own CSS to make the look consistent.
- At the current time (2022-10-25) Tor Browser does not support this mode fully (some weird color glitches) because Tor Browser is currently based on an older Firefox version which had problems with this filter. In the future this will probably be fixed
- We added a custom button to our custom footer to activate dark mode. This button uses the normal functionality of the extension.
Retired Extension Dark Mode fork (until 2024-09)[edit]
- In the past we forked the extension because we needed an anon-user mode which was not provided. This has been fixed now, so we reverted to using the up-to-date upstream version with quality of life fixes and especially with the now added anon-user mode
- Past documentation for the fork
- Our fork enhances the extension by adding a mode for anonymous users. The original extension saves the "dark mode preference" to the personal user settings of a registered user. Non-registered or non-logged-in users (the majority) therefore have no ability to use dark mode. They can activate it, but once they reload or navigate to another page the dark mode is gone. We fix this by saving the dark mode setting to a cookie with the name "usedarkmode" which is ONLY saved if the user is anonymous and is either "0" (off) or "1" (on). Our fork of the extension will check if this cookie is set to one and activate dark mode - but again ONLY if the user is anonymous. Therefore the basic idea of the extension is kept alive, we just enhanced it for another use case.
- upstreaming: https://gerrit.wikimedia.org/r/c/mediawiki/extensions/DarkMode/+/849628
MultiWiki[edit]
- We maintain multiple wikis for different projects which are very similar in some ways, in particular Kicksecure and Whonix at the moment. We therefore decided to reuse general code on all wikis to avoid code duplication, have consistency and simplify maintenance. "General code" means our own small libraries, usually CSS and JavaScript which are hosted within a separate GIT repository
- As there is no practical import option for pages, templates and widgets in MediaWiki for our purpose we use a "cascading multi-wiki" approach with the assistance of automated scripting.
JS and CSS files - GIT repo and server deploy[edit]
- Javascript and CSS files are managed in a GIT repository. These files are called source files and are in differen source folders. The shared folder and one folder for each wiki - at the moment Whonix and Kicksecure
- Note: One single JS file and one CSS files are not managed in this GIT repository: Mediawiki:Common.js and Mediawiki:Common.css. These files are MediaWiki specific files that cannot be managed outside. Their usage is described in the chapter Dev/mediawiki#Structure_of_our_wikis_.28How_to_build.29
- The development and deployment cycle work as follows
- The GIT repository is locally pulled
- The files are edited locally
- If there are new files or file dependencies change then the local config build json files are edited to reflect the changes
- The changes are pushed to the online GIT repository
- On the online GIT repo files a build script is executed on the server which does the following for each wiki
- Reads the shared config build file and loads the mentioned source files seperated by categories in their given order
- Reads the wiki specific config build file and loads the mentioned source files seperated by categories in their given order and adds them after the shared source files
- Renders combined Javascript and combined CSS files for each category and then also a minified version for each
- All source files are also copied into a src-copy folder
- Finally for each wiki the "distribution" files (combined files and src-copy folder files) are then deployed onto the corresponding wiki server
- Build logs : Note, you can check the automatically generated build log files after deployment
- The GIT repo folder structure is as follows
- build/
- build.sh
- build-and-deploy-to-servers.sh
- build-mw-combine.php
- config-build-kicksecure.json
- config-build-shared.json
- config-build-whonix.json
- src/
- kicksecure/
- shared/
- whonix/
- README.md
- build/
- The autogen folder for the rendered files on each server have the following folder structure
- [wiki-autogen-folder]
- src-copy/* -- copied source files
- build-log.htm
- * // combined files
- [wiki-autogen-folder]
- Our main scripts are in the src/shared/ source files. These will always be loaded first and come first in the combined files which are generated by the build script
- Every wiki also has their own source files which will be loaded and combined later than the shared files by the build script
- Every wiki source folder and shared folder also has a build config file which determins which file is rendered into which combined file and at which position
Pages, Templates and Widgets - publisher subscriber mechanism[edit]
- Content pages and wiki internal functionality like templates and widgets cannot be stored outside of the wiki.
- For this reason we use another strategy and another deployment methode utilizing the category Category:MultiWiki.
- Specifically we use a deploy script that cascades changes from multiwiki files from the publisher wiki (Kicksecure) to all other subscriber wikis.
- The whole life cycle
- Multiwiki pages are given the category multiwiki (how this is done read below)
- Multiwiki pages are added, deleted and edited only on the publisher wiki
- To avoid confusion and losses due to edits in the subscriber wikis which are later overwritten by "multi wiki deploy cascade" from the publisher wiki there is Dev/mediawiki#EditorMultiwikiNotice which is an indicator for all editors warning if edits of a multiwiki file are not done in the publisher wiki.
- The deployment from the publisher wiki to all the other wikis is done by running
mw-multi-wiki
(ask admin for directions). This copies all pages, templates and widgets in the Category:MultiWiki from the publisher wiki to all the subscriber wikis and overwrites their previous files
-
To add a wiki page to Category:MultiWiki the following text needs to be added to that wiki page. By convention, it should be in the footnotes or section or very bottom the footer of the wiki page.
- If it is a wiki page, add:
[[Category:MultiWiki]]
-
If it is a wiki template or a widget, add:
<noinclude> [[Category:MultiWiki]] </noinclude>
- If it is a wiki page, add:
- Examples
- wiki pages that have been added to
Category
MultiWiki
:Contact
, chapterFootnotes
- wiki templates that have been added to
Category
MultiWiki
: Template:Gpg_key - The full list of wiki pages, templates and widgets currently in
Category
MultiWiki
can be found on the category page: Category:MultiWiki
- wiki pages that have been added to
- Practical example instructions for practice : to start mirroring (cascading), from the publisher wiki (Kicksecure wiki) to a subscriber wiki (Whonix wiki), run: mw-multi-wiki
. How to test:
- Modify a page that is already in Category:MultiWiki such as Testpage in the source wiki.
- Then run
mw-multi-wiki
- Check for example if Testpage was modified in the destination wiki by looking at its content or Testpage history.
- Note : Pages that have not been changed in the source wiki will not result in a recorded change (null edit) in the destination wiki.
Multiwiki definitions[edit]
There are basically 3 categories for files on our wikis
- LocalWiki means: for the local wiki only. This file is not part of the cascading MultiWiki auto deploy
- LocalSkin means: for the local skin augmentation only. The skin is also influenced by the "LocalWiki" files, but local skin is even more specific
- MultiWiki means: for all wikis, but as general as "LocalWiki".
Structure of our wikis (How to build)[edit]
- Our wikis rely on a specific methodology to separate the "backend" from "frontend" look which would usually be the same in other MediaWikis. For page visitors we want to show a "local skin augmentation" which is a more optically pleasing look. This is our own "skin" but not realized as a true MediaWiki skin, but as an augmentation via CSS and JS. But as soon as you edit or go on a special page you get the "common look" of our current MediaWiki skin. This is accomplished by using the Template:Header. Only wiki pages which have
{{Header}}
will have the special look of our local skin augmentation - Entry points / categories
- The relevant files are all found in the wiki build files in the git repository. These files have multiple sections. So these files is a great way to see the application structure. Sections:
- wikijs : These files will be combined into one file whose methods will be available on the whole wiki even without the skin applied
- wikicss : These files will be combined into one file whose styles will be available on the whole wiki even without the skin applied
- skincss : These files will be combined into one file whose styles will only be available of the {{Header}} template is included in a page
- NOTE: All of the files in these categories are also copied into a separate source file folder and also a minified version of them. Read more here #File_auto-generation.2C_Combine.2C_Minify.2C_Host_Locally.2C_mw-autogen.2C_src-copy
- justcopy : These files will NOT be combined in any way. They will just be copied as described above. Note that these files can be mixed and don't need to be exclusively Javascript or CSS
- #Extension_HeadScript - Import combined files This extension is used to import the combined files which were rendered from in the JS and CSS build process
- Template:Header / LocalSkin - Import CSS files for local skin pages. This template has a double function. It introduces the "local skin augmentation" as well as its header. Files are loaded using #Extension CSS Fork
- The relevant files are all found in the wiki build files in the git repository. These files have multiple sections. So these files is a great way to see the application structure. Sections:
- Important CSS files
- Mediawiki:Common.css / MultiWiki - not in use, but MultiWiki, because it's an important system file
- Utility.css / MultiWiki - Define styles which can be used like tools on the site. This file has styles which can be used for all of our wikis. It's general styles which can be used like tools and boilerplate setup styles for things in all wikis which we need to fix
- Boilerplate.css / MultiWiki - Define styles which make up our "basic" style on all our wikis. This file has styles which can be used for all of our wikis. Boilerplate.css is what all our local wikis skins have in common. It is like LocalSkin.css but for all our wikis. It's also only available if the Header (and therefore LocalSkin) is active
- LocalSkin.css /blob/master/mediawiki-shared/src/kicksecure/LocalSkin.css LocalSkin.css / LocalSkin - Define styles for local skin. This file has styles which will only be active on local skin pages
- Important JavaScript files
- Mediawiki:Common.js / MultiWiki - Trigger / hook to notify our JS that MediaWiki is ready
Creating a new wiki[edit]
When we create a new subscriber wiki we usually do this
- We copy the publisher wiki with all files and later delete what is not necessary
- We create a new folder in src with the new wiki name in the GIT repository
- We create a new build config json file in the build folder of the GIT repository
- We modify the build scripts with the new server IP
- We modify the mw-multi-wiki script
- Then we can start developing the new wiki
Skin: Legacy Vector, New Vector Skin 2022 and Skin Preferences[edit]
- MediaWiki states:
Over the next few years, we will be gradually updating the Vector skin. Legacy Vector will allow you to view the old version of Vector (as of December 2019). To learn more about the updates, go to our project page.
That's why we use the new vector skin Vector 2022 WITHOUT the wgVectorResponsive option already and developed the wiki on top of the new Vector skin- Learn more about Vector 2022 vs Legacy vector here: https://www.mediawiki.org/wiki/Skin:Vector/de
- We decided to use Legacy Vector specifically because it is not developed further as a base for our own layout ("skin augmentation")
- Skin preference is normally deactivated. This is done like described here MediaWiki disable skin preference. Explanation:
- Normally logged in users of MediaWiki can choose different "skins" to display the wiki, like
- This sometimes means that the page will be displayed differently and that even sometimes the functionality will differ, for example that different API urls are used by different skins. This can lead to serious problems because the devs would have to customized (and bloat) the page for every optional skin available
- That's why we don't offer skin preferences
For the admin in general[edit]
Here are the MediaWiki settings to remove the skin preference choices
- Under https://www.kicksecure.com/wiki/Special:Preferences#mw-prefsection-rendering:
- remove "Enable responsive mode"
- remove "Adapt layout to screen size on mobile"
$wgHiddenPrefs = array( "skin-responsive", );
- Under https://www.kicksecure.com/wiki/Special:Preferences#mw-prefsection-rendering:
- remove "Vector legacy (2010) (Preview)"
- hide 'Vector legacy (2010)'
- keep 'Vector 2022'
$wgSkipSkins = [ 'vector', ];
For the admin regarding MediaWiki updates[edit]
- MediaWiki updates sometimes come with changes in HTML. Legacy Vector is not protected against this as these changes are not directly in the skin but in the core HTML rendering
- This documented here https://m.mediawiki.org/wiki/Stable_interface_policy/Frontend
- And this was indirectly confirmed by our rejected ticket https://phabricator.wikimedia.org/T344681
- This means for us for every MediaWiki update
- Check for HTML updates with every MediaWiki update
- Reserve Dev time for possible changes
- Change our skin augmentation to address HTML changed if needed
Layout on top of Legacy Vector - skin augmentation[edit]
- We use MediaWiki's "Legacy Vector" skin as a base.
- We avoid custom MediaWiki skins as these break every now and then which then would force us to stick with MediaWiki oldstable or LTS, unable to update to MediaWiki stable. [1]
- We create Template:Footer and a Template:Header which is manually included at the top (header) or bottom (footer) in all relevant content pages such as Documentation, Download, FAQ and so forth.
- The header template completely replaces the navigation of the Vector skin and has its own style and JavaScript functionality.
- The footer template also has its own style and JavaScript functionality.
- The Header template injects CSS styles from internal MediaWiki:CSS files via our Extension:CSS fork.
- Example:
{{#css:/mw-combined-skincss.min.css }}
- So only on pages where the header is present these CSS files will apply.
- This means that for example on Special:SpecialPages the unchanged Vector style will be shown.
- This solution gives us the opportunity to have an appearance like a new skin while also having the fallback to a clean Vector skin.
- Example:
Vector Legacy Maintenance by MediaWiki[edit]
- Open investigation: We try to determine if bug reporting for Legacy Vector is off limits and that pull requests would be rejected. The name "legacy" indicates that further development might be rejected but it is unclear.
- Our probe is this bug report Legacy Vector TOC Lighthouse bugs due to toggle collapse (duplicate), which describes a real bug that we have found in Legacy Vector.
- At the moment there is no reaction from the MediaWiki team yet.
Pages.js[edit]
- Sometimes Javascript is only needed on specific pages for specific tasks. This happens very rarely.
- So we created Pages.js - a LocalWiki file where the page specific JS functions are combined
jscookie[edit]
Within headscript we use:
<script id="js-cookie-script" defer fetchpriority="low" src="/libs/jscookie/js.cookie.min.js"></script>
jscookie
is a simple small cookie library for all our cookie control needs and is only 2kb in size. So it's very practical and we couldn't program it ourselves any smaller.- We use it for
DebugViaUrlModal
,FlyinNotification
,SiteNotice
andTocLevelSwitcher
.
FontAwesome[edit]
- FontAwesome is used as a local webfont to make the site more beautiful.
- We use our own implementation via mediawiki extension HeadScript. (See #Extension HeadScript)
- Therefore it is available on all pages.
- Only works when JavaScript is enabled.
- Has a graceful no-JS fallback, in that case simply no symbols will be shown.
- Loaded using CSS (async). Not loaded using JS. Loading using JS would require a different syntax to use FontAwesome.
Usage Examples[edit]
- FontAwesome is used on all wiki pages because the supermenu symbols use it.
- Donors cards are using it.
- Whonix homepage VPN table is using it.
Development details[edit]
Versioning in Headscript[edit]
All files called in Headscript usually have a headscript version number, but not our fonts including FontAwesome. Read here about our Fonts
Subsetting[edit]
- We tried using subsetting to only serve the needed icons and there saving bandwidth and improving performance on 2024-08-15
- But subsetting is now a FontAwesome service only available to Premium members which collides with our freedom software approach
- Therefore subsetting is rejected until it's free again in the future maybe
- Below are all the FontAwesome icons currently in use in our wikis
FontAwesome Icons currently in use
fa-solid fa-1 fa-solid fa-2 fa-solid fa-3 fa-solid fa-4 fa-solid fa-5 fa-solid fa-6 fa-solid fa-7 fa-solid fa-8 fa-solid fa-9 fa-solid fa-arrow-right-arrow-left fa-solid fa-asterisk fa-solid fa-ban fa-solid fa-binoculars fa-solid fa-bolt fa-solid fa-book fa-solid fa-bullhorn fa-solid fa-chart-line fa-solid fa-check fa-solid fa-check-circle fa-solid fa-check-double fa-solid fa-chevron-down fa-solid fa-chevron-up fa-solid fa-clock-rotate-left fa-solid fa-code fa-solid fa-compact-disc fa-solid fa-compress-alt fa-solid fa-crown fa-solid fa-cube fa-solid fa-display fa-solid fa-dollar-sign fa-solid fa-download fa-solid fa-droplet fa-solid fa-dumbbell fa-solid fa-envelope fa-solid fa-exclamation fa-solid fa-exclamation-circle fa-solid fa-expand fa-solid fa-external-link-alt fa-solid fa-feather fa-solid fa-fire-flame-curved fa-solid fa-flask fa-solid fa-gears fa-solid fa-gift fa-solid fa-hand fa-solid fa-hand-holding-medical fa-solid fa-hdd fa-solid fa-house fa-solid fa-info fa-solid fa-info-circle fa-solid fa-key fa-solid fa-keyboard fa-solid fa-laptop fa-solid fa-laptop-code fa-solid fa-lightbulb fa-solid fa-link fa-solid fa-list-ol fa-solid fa-lock fa-solid fa-mask fa-solid fa-medal fa-solid fa-minus fa-solid fa-mountain-sun fa-solid fa-mouse-pointer fa-solid fa-pause fa-solid fa-pen fa-solid fa-pen fa-solid fa-pen-nib fa-solid fa-people-group fa-solid fa-person-digging fa-solid fa-phone-slash fa-solid fa-play fa-solid fa-plus fa-solid fa-print fa-solid fa-question fa-solid fa-right-to-bracket fa-solid fa-rocket fa-solid fa-rotate fa-solid fa-seedling fa-solid fa-share fa-solid fa-share-alt fa-solid fa-share-nodes fa-solid fa-shield fa-solid fa-shield-alt fa-solid fa-shield-halved fa-solid fa-smile fa-solid fa-star fa-solid fa-sun fa-solid fa-thumbs-up fa-solid fa-times fa-solid fa-tint fa-solid fa-toggle-off fa-solid fa-toolbox fa-solid fa-trash-can fa-solid fa-triangle-exclamation fa-solid fa-unlock fa-solid fa-unlock-keyhole fa-solid fa-upload fa-solid fa-user fa-solid fa-user-secret fa-solid fa-user-shield fa-solid fa-virus fa-solid fa-wand-magic-sparkles fa-solid fa-water fa-solid fa-window-restore fa-brands fa-apple fa-brands fa-debian fa-brands fa-linux fa-brands fa-osi fa-brands fa-usb fa-brands fa-windows fa-regular fa-clock fa-regular fa-comments fa-regular fa-envelope-open fa-regular fa-hand fa-regular fa-save fa-regular fa-star Also the additional functional classes fa-fw
fontawsome font-display: swap[edit]
https://www.webpagetest.org/result/230123_AiDcPZ_55N/1/experiments/ says
When fonts are loaded with default display settings, like font-display="block", browsers will hide text entirely for several seconds instead of showing text with a fallback font. Font Awesome 5 Free 900 normal Add font-display: swap
What we currently have:
<link rel="stylesheet" type="text/css" href="/libs/Font-Awesome/css/all.min.css"> <link rel="stylesheet" type="text/css" href="/mw-autogen/mw-combined-wikicss.min.css"> <style type="text/css"> @font-face { font-family: Roboto; src: url(/libs/Roboto/Roboto-Regular-webfont.woff); font-display: swap; } @font-face { font-family: Roboto; font-weight: 300; src: url(/libs/Roboto/Roboto-Light-webfont.woff); font-display: swap; } @font-face { font-family: Cousine; src: url(/libs/Cousine/Cousine-Regular.woff); font-display: swap; } </style> <link rel="preload" href="/libs/Roboto/Roboto-Regular-webfont.woff" as="font" crossorigin fetchpriority=low> <link rel="preload" href="/libs/Roboto/Roboto-Light-webfont.woff" as="font" crossorigin fetchpriority=low> <link rel="preload" href="/libs/Cousine/Cousine-Regular.woff" as="font" crossorigin fetchpriority=low>
There are two different ways we currently add fonts.
- 1) link rel="stylesheet" for font awesome
- 2) <style type="text/css"> for Roboto / Cousine
Would it make sense to load font awesome the way Roboto is load?
DEV
- The problem is that fontAwesome is loaded in its own CSS file .../Font-Awesome/css/all.min.css - this means that adding and preloading the font is already done by the CSS. It's probably hard to separate this step from
- There is a very good post about it here https://github.com/FortAwesome/Font-Awesome/issues/14387 with probably the best quote
You cannot mark it swap by default - this will cause random characters to appear (or in the best case squares). This is a very bad UX.
See the explanation from Google: swap gives the font face a zero second block period and an infinite swap period. This means the browser draws text immediately with a fallback if the font face isn’t loaded, but swaps the font face in as soon as it loads.
This behavior is desired for small blocks of text (e.g. headings). For big chunks of texts you should use fallback for big blocks (e.g. article contents). The block setting gives the user no icons on load and loads them as soon as possible, which is better than broken icons blinking into proper icons.
- 5 - Font Awesome false positive - yes and no. Font Awesome is using explicitly the standard option font-display:block which Lighthouse does not like because it tolerates invisible text up to 3 seconds. But font-display:swap is not really an option, because in this case a standard font is loaded and only when the special font is ready the standard font is replaced. This is terrible for icons because then you have a lot of ugly box-symbols, that are the replaced by real symbols. Dev could however change to font-display:swap which would make Lighthouse happy. Maybe the box placeholder symbols are not as bad as having no icons at all?
- Patrick: Font Awesome is not used above the fold. Therefore not important to use placeholders.
MediaWiki Default Links - LinkToArchive Fork[edit]
- External links in MediaWiki (starting with http or https) were previously enhanced on our wikis by using the MediaWiki LinkToArchive extension, see also their GitHub repository
- With this extension an external link ("main link") get an additional link following it. This additional link is slighly elevated and says
[archive]
and points to an archived version of the main link - However we created our own fork of this extension to address our specific needs, see LinkToArchive fork
- We wanted an icon instead of the text
[archive]
to represent the archive link - We used a couple of different HTML constructions and added a class "ext-link-to-archive" to be consistent with our other modules on the website
- We wanted to analyse if the link is already an archive link (
web.archive.com/web
) or an.onion
link. In those cases the additional link changes in some significant ways- In the normal case: The additional link is set to the web archive with the whole main url as a suffix. The additional link icon is the archive icon. The additional link title becomes "Link to archived version".
- In the archive case: The additional link gets just the main url (because it's already an archive link). The additional link icon is the archive icon. The additional link title becomes "This is a web.archive.org link".
- In the onion case: The additional link gets just the main onion link (because it's not compatible with web archive). The additional link icon is the onion icon. The additional link title becomes "This is an .onion link".
- We wanted an icon instead of the text
backport mediawiki-link-to-archive from upstream[edit]
September 2024
Backport the new changes implemented by https://github.com/Archi-Strasbourg/mediawiki-link-to-archive in our already existing fork, if sensible.
DEV
- New changes by the original author were checked
- The only noteworthy changed was checking for
action=edit
in the url, original comment:// Check if the URL ends with "action=edit"
- This however seems strange considering that this extension is for external links only, underlined by the fact that we are checking of HTTP(S) at the very beginning.
- So this basically prevents urls from having an "archived" link icon that have the "action=edit" parameter in the URL. This however just reliably applies to external MediaWiki links. Other pages could use "action=edit" in a different way and might therefore still be justifiably archivable
- Analysis: Dev thinks that the original author solves a very very specific use case for himself here and that this is not needed, nor would it be an improvement to our extension
- Question to admin: Dev had the idea that our fork could be improved by moving the archive icon image and the onion icon image to the extension in an image folder. Then our extension would also be standalone. Now you need to have the 2 images that we are using on your server
- Patrick: Not needed.
Wiki editor software enhancements[edit]
- The standard wiki editor software is enhanced in multiple ways
- Extensions
- We use the extension CodeEditor which improves coding in JavaScript, CSS and Lua significantly
- We also use the extension CodeMirror which adds syntax highlighting and bigger text to wikitext editing
- In-wiki improvements
- We created a Fullscreen mode for the editor, see #EditorFullscreen
- We created a saving mode which doesn't reload the page, see #Editor SaveAndContinue
- We created an auto-backup for wikitext which automatically saves your edits to the browser's localStorage, so you don't lose progress when something goes wrong, see #EditorAutoBackup
MediaWiki limitations[edit]
- Not everything is easily implemented with MediaWiki. One problem we found is that the page content will always be delivered in div#content
- This leads to problems when elements need repositioning with CSS especially regarding div#mw-data-after-content which will always be rendered after the div#content and which is inconvenient in our case because the footer should be the last thing which can be seen
- We solved this in the file Utility.css where we put the whole div#mw-data-after-content with position absolute "above" the footer so it (and for example the Revision bottom bar) is still usable and not hidden by the footer
- This might be considered a "harmless" hack. Still it can be deactivated by commenting out the lines in the chapter "Flagged revisions Bottom bar" in Utility.css
Mediawiki parsing - images and links[edit]
- Mediawiki is evolving and this sometimes leads to legacy breaking changes
- One very important development is the move from Mediawiki legacy parser to Parsoid, see https://www.mediawiki.org/wiki/Parsoid and https://www.mediawiki.org/wiki/Parsoid/Parser_Unification/Media_structure/FAQ
- This involves changes in how element are rendered which in turn forces Mediawiki users to change CSS and Javascript, possibly also widgets and templates to accomodate the new structures
- For example thumbnails e.g.
[[File:DALL·E 2023-10-24.png]]
were previously rendered as simpler<img>
tags and are now enclosed in a more elaborate<figure>, <figcation>
structure - The team of Kicksecure tried to point out flaws with this approach, especially the problem of legacy breaking updates but were pointed to commit messages at least informing wiki users https://phabricator.wikimedia.org/T345866
- Link inconsistency between links and images also seems to be a problem - with the legacy parser but also with Parsoid
- The Kicksecure team pointed out that images with a self reference and links the a self reference are handled differently. While a link is rendered to an a-lement with the classes "selflink mw-selflink", there is no such thing with images which are not identifiable as linking to the very page they're on https://phabricator.wikimedia.org/T336256 - a contributor said they could prove different on their own system. But this can be demonstrated on this system
- Self link Dev/mediawiki
- Compare to link to
[[Homepage]]
(avoiding link for SEO) - Image link to image source
- Image link to About
- Image link to this page (self link)
- The images have links and the syntax is correct as the links work, but there is no "selflink mw-selflink" classes present
- Parsoid is bound to take over in the future. But currently they are working on applying selflink to normal links. So it will probably still take a lot of time for Parsoid to replace the legacy parser https://phabricator.wikimedia.org/T69486 - in this issue there was a reference to the image selflink problem that our team brought up. There seems to be current progress however https://gerrit.wikimedia.org/r/c/mediawiki/services/parsoid/+/991827
- The Kicksecure team pointed out that images with a self reference and links the a self reference are handled differently. While a link is rendered to an a-lement with the classes "selflink mw-selflink", there is no such thing with images which are not identifiable as linking to the very page they're on https://phabricator.wikimedia.org/T336256 - a contributor said they could prove different on their own system. But this can be demonstrated on this system
Implementation Details (in-wiki)[edit]
Crypto QR Code Image Templates[edit]
- QR codes are used for the payment of donations. These codes and urls are outsourced to these templates
Header[edit]
- The Header is composed of MultiWiki and LocalWiki elements (see Dev/mediawiki#Multiwiki_definitions)
- To implement the header (and the skin) into a page simply template header is implemented
{{Header}}
- Also Template:Header the widgets Header (Multiwiki) and HeaderLocalWiki are called. They are split in parts and multiple parts are called
- Header.js is always called
- In side the Template:Header /mw-combined-skincss.min.css which combines header.css and localSkin.css
- To implement the header (and the skin) into a page simply template header is implemented
- Relevant files
[edit]
- Footer is implemented in Template:Footer (localWiki). This calls a widget that is multiWiki. Footer.js and Footer.css enrich the footer and there are some slight color variations in LocalSkin.css (see Dev/mediawiki#Multiwiki_definitions)
- There was an old implementation for the footer which is currently not in use via BodyScript2 MediaWiki Extension
<div class="our-special-own-footer"></div>
- related Links when editing footer
- Relevant files
[edit]
The footer is structually (html) positioned in the main content area. The vector skin footer is made invisible so there is no overlap. If references are auto-generated by mediawiki then they are below the footer structure and so they are overlapped, this is not desirable. Therefore it is common practice to always write the "references..." keyword in the page so the references headline is generated above the footer structure
RandomNews[edit]
- Deprecated. Reasons: causes issues with caching, keeps MediaWiki busy, might confuse search engines.
- RandomNews in the footer shows random whonix wews which are fed from Template:RandomNews
- The Template is not directly imported into the footer widget, because widgets can take Templates as parameters.
- The RandomNews template is included in the Template:Footer and made display:none via CSS. If Javascript is present then the RandomNews will be moved to the footer and replace the standard text which is in the RandomNews box in the footer. This happens via Footer.js
Homepage (/wiki/Homepage
)[edit]
- The
[[Homepage]]
(avoiding link for SEO) is an improved version of the old Kicksecure plain HTML/CSS based homepage - It is realized via Widget:Page_Homepage and Page_Homepage.css /blob/master/mediawiki-shared/src/kicksecure/Page_Homepage.css Page_Homepage.css
- Visitors can view it under
https://www.kicksecure.com
.https://www.kicksecure.com
is the canonical domain name.- Implemented using
https://www.kicksecure.com
/wiki/Homepage
. - https://www.kicksecure.com/robots.txt uses
Disallow: /wiki/Homepage
to avoid duplicate search engine indexing.https://www.kicksecure.com
can of course be index normally.
https://www.kicksecure.com
/wiki/Homepage
while far from being a secret, a technical implementation detail, should not be shown to users as it would confusing.- Editing
https://www.kicksecure.com
/wiki/Homepage
will result in making changes tohttps://www.kicksecure.com
.
- Structure
- The page is wrapped in div with the class
section-wrapper
- Right below there are the sections which can be CSS references via
.section-wrapper > div
. They all have classes as names that start withsection-
, e. g.section-banner
,section-download
,section-press
- Inside every section there is a
div
directly below the parent which has the classinner-wrapper
, which wraps the inner content and helps with positioning. It is also a resource for future designers to design the content via CSS - Right below the section-wrapper there can also be other elements
h2
is the standard tag for headlines
- The page is wrapped in div with the class
- Hero image
- The hero image is optimized for page load speed and minimal content shift while also adressing limited bandwidth of the Whonix servers
- First we tried a very small preview image scaled up to size and blurred, shortly after being replaced by the fully loaded hero image. The problem was that Lighthouse / Pagespeed output the error "Serves images with low resolution".
- Then we removed this preview image (class "overview-image-preview") and instead placed the preview image url in the src-attribute of ".overview-image > img". We hoped that the src image should always be loaded and would be initially shown. But the browser immediately fetched a larger image from srcset which slowed the performance metric. The src attribute is just a fallback option.
- Now we use an SVG image as the preview image which solves the "Serves images with low resolution" Lighthouse issue. SVGs are NOT seen as too small by Lighthouse because they can scale. This SVG image was losely generated from the small preview image because it has little detail which creates an SVG with a small file size.
- Explainer Video (only Whonix homepage)
- We have a Whonix explainer video ready for all users clicking the hero image
- To save bandwidth this video is not preloaded. The source-src-attribute is not set to prevent the browser from preloading.
- Instead an attribute "data-src" is set containing the source. If the user clicks on the hero image then the source from data-src is used to set the src-attribute and the video is reloaded and starts to play
- This is done in the Whonix LocalPages.js file
- Also no poster (video thumbnail) is set, because the video player is hidden behind the hero image until the image is clicked
- There are special classes for sections which can be used give those sections a special look
dark-section
: a dark section has a dark background. It can be combined with row-3- and row-5-sections. The dark section spans over the whole page, while the inner content is max 960pxrow-3-section
: These sections have 3 elements on wide displays, 2 on medium displays and 1 on small displays. They are used for testimonials, features or other text heavy tasksrow-5-section
: The sections have 5 elements on wide displays, 3 on medium displays and 2 on small displays. They are used for icons and low information items
- There is also a special class for images
image-contain
which is optional. By default images are in the background withbackground-size: cover;
so the image always fills the whole area but because of the some parts might a cut. While withimage-contain
the image hasbackground-size: contain;
so the image will be fully visible but not cover the whole area. See example below
Creating a new section
- copy the following structure inside of
<div class="section-wrapper"></div>
and exchangeyourSectionName
by something of your choice
<div class="section-yourSectionName"> <div class="inner-wrapper"> </div> </div>
- put all your content inside of the
div
withinner-wrapper
- if you want to use one of the special classes, put them behind
section-yourSectionName
in the class attribute
row-3-section
- If you used row-3-section the direct children of inner-wrapper need to look like this
<div> <i style="background-image:url('/w/images/thumb/path-to-your-image.bmp');" title="Your title"></i> <span> Your text and possibly links </span> </div>
or
<div> <a class="image image-contain" href="/your-link" target="_blank" title="Your title" style="background-image:url('/w/images/thumb/path-to-your-image.bmp');"></a> <h4>Headline</h4> <p> Your text and possibly links </p> </div>
- As you can see: The image can be either realized with an i-tag or an a-tag. But if you use an a-tag it needs to have the class "image"
- Also note there is an example here for the optional use of
image-contain
, see the explanation of image-contain from above - It is also important to note: You can use
h4
,p
andspan
elements as content
row-5-section
- If you used row-5-section the direct children of inner-wrapper need to look like this
<a href="/your-link" target="_blank" rel="noopener"> <img src="/w/images/thumb/path-to-your-image.bmp" alt="Alt description" /> <span>Your text</span> </a>
Fixed Header Overlap for anchors[edit]
- We have a fixed header because this is a modern solution which works good for mobile and desktor alike
- A usual problem with fixed headers however is that the overlap "jump points" / inner page links / anchor links within the page.
- So you click a link with # and you jump within the current page to the position.
- However the fixed header appears on top of the element (e.g. a headline) which you therefore can't see
- We know 3 solutions to this problem
- The first one is to position and anchor-element (usually <a> but any element with id-attribute works) enough pixels BEFORE the point where you want to jump
- This is not possible for us, because were using Vector skin and therefore cannot decide the HTML structure
- The second solution is to use the CSS property scroll-padding-top. This works in most modern browsers but not always reliably when you have a URL with the # jump point already in it
- The third solution is to give the element a top padding via CSS and counter via the top margin in the other direction (e.g. padding-top: 50px; margin-top: -50px)
- The first one is to position and anchor-element (usually <a> but any element with id-attribute works) enough pixels BEFORE the point where you want to jump
- Because of the structure of mediawiki and vector skin we use solution two: scroll-padding-top and a version of solution three where we give the headline subelement .mw-headline a padding top which does not show up in the content the element is display inline, but most browser jump to the top position
CSS: Chrome anchor bug with special chars[edit]
- For the fixed header to work we add a padding to the id-element with the class .mw-headline within the headline (h1-h6), so when jumping the header does not overlay on the headline
- however this is not working with Chrome when there are special characters in the ID at the moment (2022-02-02) and this [bug seems to be known but ignored] by the dev team
- to be fair, Mediawiki ultimately causes the problem itself by generating anchor IDs with special characters which is forbidden in HTML. Headline: "What is up?" - ID: #what_is_up?
- Maybe this can be changed by an extension or by a setting in localsettings.php ?
CSS: Replacing Hovering vanishing scrollbars in some cases[edit]
- Motivation
- Scrollbars come in different shapes and sizes. But a more recent development is "Hovering vanishing scrollbars"
- These have been introduced by mobile devices, but some desktop browser now also use these kinds of scrollbars
- They don't take any space, they are rather slim, they hover over the content and they vanish (or never appear) if the user does not scroll this particular area that has an overflow (which can be scrolled)
- The problem with these scrollbars is that they are vanishing. They are hardly visible to begin with when they appear. But as they are not visibile automatically they can lead to heavy confusion. Users may not know that a content area is much longer and might be missing out on valuable information. Users might also be confused if the suddently cannot scroll further or if their viewport changes because they are suddenly in a scrollable area which they knew nothing about before because there was no scrollbar visible
- Solution
- For these reasons we decided that - not for all but - in very confusing cases we replace the native scrollbars with a custom scrollbar solution that we control the visibility and the styling of
- These custom scrollbars are documented here: CustomScrollbar
Table of Contents[edit]
- toc is auto-generated on top of a page or explicitely by markup in the body
- we modified toc in its looks and appearance (expand/collapse instead of show/hide)
- we also prevent selection of the toc numbering. This means the text in span.tocnumber will not be selected and copied. This is useful when copying parts of the toc to post somewhere
- CAUTION: This unfortunately doesn't complete work in Chrome. If you mark a little bit more than one toc bullet point and have a space, newline or a part of the next bullet point then the tocnumber in between will be copied to clipboard by Chrome. This is undesired behaviour but tolerated
[edit]
- The supermenu template Template:Header passes 2 parameters to the widget Widget:Header : $page and $revision
- By that the edit link is constructed: /w/index.php?title=<!--{$page}-->&action=edit&oldid=<!--{$revision}-->
- This means that even the current revision has the "oldid" url query parameter which is not necessary, but at the moment (2022-02-02) and for the foreseeable future will not cause any problems.
- However if there will be a problem in the future simply go to Widget:Header and change the line to /w/index.php?title=<!--{$page}-->&action=edit
- Upgrade via JS (2023-02-06) in Header.js
- Via Javascipt it is checked whether in the URL there is a query parameter oldid.
- The presence of this oldid parameter would indicate that the user visits and old page and therefore if he clicks "edit" he wants to edit based on this old version of the page. In this case the edit link in the super menu will stay as described above.
- For NoJS users this is the only case.
- On the other hand if the oldid url query parameter is NOT present then the user would not want to edit an oldid version - even if this version happens to be the current one. This is due to us using the Extension Flagged Revisions. If the extension is late (which it sometmes is) then editing with oldid can cause problems.
- So if the oldid query parameter is not present in the current page url then via Javascript the href attribut of the "edit" link in the super menu will be manipulated. The oldid parameter will be completely deleted while all the other parameters will stay untouched. Therefore making this link a standard edit link for the page
Combined New Custom Header with MediaWiki Custom Header[edit]
For demonstrative purposes only: https://web.archive.org/web/20220204103725/https://www.kicksecure.com/wiki/Documentation
Images, Files and usage of thumb[edit]
Best Practices[edit]
- Thumbnails have a specific look to them, but sometimes it is unnecessary to have an enlarge button. Therefore we create hide-enlarge, see #hide-enlarge and thumb-hide-enlarge class
- We first tried to use frame instead of thumb, as in
[[File:abc.png|frame|50px]]
, but the option frame ignores the forced size by design, see https://www.mediawiki.org/wiki/Help:Images#Size_and_frame - Next we tried border as in
[[File:abc.png|border|50px]]
. This might be useful in some cases, because it does not ignore forced size. But to make it look like thumb is very time consuming
- We first tried to use frame instead of thumb, as in
- MediaWiki auto-generates thumbs when give specific links. We use this features for HTML pages (widgets) within the wiki. However there is a problem that these images do not upscale or upscale unpreditably.
- NOTE: We're talking about the thumb link autogen - not the Mediawiki autogen (wrapper) where mediawiki delivers the original if thumb generation does not work like with
[[File:...]]
- Example: Version 1280px works while Version 1281px doesn't. The original is 1280px large
- Now it would be great if thumbs would just always work either by upscaling or by just delivering the original image if the thumb is larger than the original. But as it seems with upscaling (AND the original size too) the thumb does not work
- We solve this problem with the following best practice
- Upload all images way larger than needed
- If an existing image does not have a large version try to use an AI image upscaling online tool or create a new representative image
- Always use thumb-autogen and give the size in which an image is needed. That way bandwidth is saved and we never need to later applay thumb-autogen selectively
- Check if the thumb was successfully generated if not you probably need to upload a larger version
- NOTE: We're talking about the thumb link autogen - not the Mediawiki autogen (wrapper) where mediawiki delivers the original if thumb generation does not work like with
Responsive Thumbnails[edit]
- Thumbnails are by default made responsive. This leads to a cleaner and more predictable look for users and is also better to handle for editors
- Thumbnails in this context are defined as
- all images that are generated by the
[[File...|thumb]]
syntax in wikitext. - They have the predictable structure: .thumb > .thumbinner [> a.image] > img
- They can be in all parts of the document, not just at the top
- all images that are generated by the
- The responsive behavior of thumbnails is the following
- Normally a thumbnail floats at the right side of the document
- It can have as much size at it needs. But it can only take 100% width of the screen to prevent over-width problems in the page. (In practical applications thumbs will be much smaller than this to allow content floating left of the thumbnails. Default is 300px.)
- Once a certain threshold is reached (and below) the thumbnail switches to 100% screen size (and a bit of spacing) and loses floating
- NOTE: Because of this behavior thumbnails do NOT need to be wrapped in Dev/mediawiki#ContentImage_.28Template.29_-_image_wrapper_for_overlenght_images
Back To Top Button[edit]
Figure: Back to the Top Button
- Back to Top Button is realized via BackToTopButton.css and BackToTopButton.js which are imported in Common.css and Common.js and thereby available for all pages, including Vector styled pages
- The button is automatically integrated in all pages and created a button which only becomes visible when the user is scrolling and offers the feature to "jump" to the top
- BackToTopButton.js has one implicit (but not critical) dependency of FontAwesome for its symbol
- suggestion: If FontAwesome is removed the
<i class="fa-solid fa-chevron-up"></i>
can be replaced by<span>UP</span>
- suggestion: If FontAwesome is removed the
Printing pages[edit]
- We made some effort to make all pages printable (physically with a browser)
- Simply press Ctrl+P or select "Print page" in your browser to print the wiki page to your printer or as a PDF file
- We added some print specific styles in Boilerplate.css
- Especially important: Usually the browser optimizes the web page for printing and does for example not print background-images. We force the browser to print background-images for all elements with the class "image", because those are basically images, just embedded differently via background-image
- The CSS command for this is "print-color-adjust: exact;" and "-webkit-print-color-adjust: exact;" for @media print.
- Elements with "image" often have their own style attached to it. So if there are elements which also need to be printed because they are background-images, but cannot have the specific image styles, then we use "bg-image" (e. g.
<i class="bg-image" style="background-image:url(...)"></i>
) which has no other style attached to it other than being visible in @media print
- Especially important: Usually the browser optimizes the web page for printing and does for example not print background-images. We force the browser to print background-images for all elements with the class "image", because those are basically images, just embedded differently via background-image
[edit]
- We use the Javascript library instantpage to speed up the internal page navigation. For Nojs users everything stays the same.
- Normally a user would navigate to an internal page on the wiki and have the browser load the new page when they click the link
- With instantpage the new page is automatically preloaded (via Ajax) once the user hovers over the link for some milliseconds
- This way the new page renders very quickly making navigation and staying on the site much more attractive
- There's a couple of variations for the usage
- Normally the preloading would start 65ms (hard coded preset) after hovering (so the user does not load every link which he does not click) to save bandwidth
- By using the attribute
data-instant-intensity="mousedown-only"
the developer can make the linked page only preload after mouse button was pressed (but already before it was released) being more reliable to only load links that the user really wants to visit - On some pages with many links the wait time for hovering may need to be increased like
data-instant-intensity="150"
to preload only after the given amount of milliseconds - Elements can be shown as soon as they're visible - good for smartphones - by using
data-instant-intensity="viewport"
to the BODY tag (the value can also be "viewport-all" which is even more liberal)
- The official repository is https://github.com/instantpage/instant.page and there are some forks.
- Whonix admin suggested setting link rel attribute to "prerender" instead of "prefetch" (like it is currently in the library). This would result in an even faster page load experience, since not only are the elements already fetch ("prefetch") they are also readily rendered ("prerender") and will seemlessly replace the page once the link is clicked possibly result in an "instant navigation experience" https://github.com/instantpage/instant.page/issues/118
Cookie Handling via JS Cookies[edit]
- We are using js-cookie for Cookie Handling https://github.com/js-cookie/js-cookie
- We have been using $.cookie and mw.cookie for cookie handling. Both of which are Mediawiki handlers, mw.cookie is the wrapper for the jQuery plugin. However both of them in some cases are not reliably loaded in time. This leads to this error message "$.cookie is not a function" in the browser console or another message that mw.cookie.get / set is undefined.
- There is a discussion about this issues here https://phabricator.wikimedia.org/T276368 but there seems to be no willingness to further investigate by the mediawiki team.
- That's why we settled for using js-cookie which is small, fast, very well tested and stable
- In short there are (1) The main object Cookies (2) The method Cookies.get (3) The method Cookies.set (4) The method Cookies.remove → further documentation here https://github.com/js-cookie/js-cookie
Exclusion of text parts from search engine indexing[edit]
- Some parts of the page are not good for indexing in search engines. This pertains especially to temporary or functional text or donation requests
- For this we use the three techniques found here https://stackoverflow.com/questions/6588438/how-can-i-hide-certain-text-from-search-engines/18356829#18356829 as a combined wrapper
<div class="robots-nocontent"><!--googleoff: index--><!--noindex-->CONTENT<!--/noindex--><!--googleon: index--></div>
Wiki Load Cascade : HTML, CSS, Javascript[edit]
- The wiki is loaded like normal with its HTML, CSS and Javascript files
- At the same time our libraries (JS, CSS) are loaded
- And our combined, minified files are loaded too, learn more BUILD: File auto-generation, Combine, Minify, Host Locally, mw-autogen, src-copy
- Execution of files in dependency order, learn more jQuery dependent and other wiki core dependent libraries and scripts
- The only wiki file with our own code is MediaWiki:Common.js. The contained script triggers an event for the window
mediaWikiCommonJsIsLoaded
. This signals that the Mediawiki JS is fully loaded. Our combined Javascript scripts are now executed - specifically only those which are just MediaWiki core dependent - In Extension HeadScript scripts are now triggered that are not only dependent on the MediaWiki core but also on other libraries to be loaded
- The only wiki file with our own code is MediaWiki:Common.js. The contained script triggers an event for the window
- The synchronous execution of our many JS scripts can block the Dom main threat of the browser for a long time on large and complex pages
- For this reason we execute our scripts wrapped within setTimout callbacks to make them asynchronous. This gives the browser "room to breathe" and to render changes to the Dom in between executing scripts
- On a micro-level we use this setTimeout async method for some "load expensive" scripts between the calls of each individual element in a set that is being enriched with functionality: CodeSelect.js, ShareToolitp.js and ScrollAutoWrapper.js
Javascript: Ajax Loading for special cases[edit]
- Explanation / motivation
- Sometimes it is necessary (or highly preferred) to load pages via AJAX. This is the case when a functional module
- is too large (HTML, CSS) or too performance heavy (Javascript) to always load it with the normal content
- rather seldomly used or used only in special cases
- needs a lot of MediaWiki data - template or widget data etc - so it cannot be structured in solely in the Javascript file (HTML in Javascript)
- In these cases we can load a MediaWiki page / template / widget via AJAX to get the HTML structure and parse it either completely or fetch the data that we specifically need
- This is also very advantageous so we don't have duplicated data which might be prone to inconsistencies (e. g. data stored in templates which are hard coded duplicates in the Javascript files)
- Sometimes it is necessary (or highly preferred) to load pages via AJAX. This is the case when a functional module
- Example
- We use this technique in Download_Button.js
- There we create a modal if at least one of the Download Buttons on the page has the modal-parameter set to true
- The modal has its own structure but also loads via AJAX the HTML from the Template:Payments template
- It then parses the URL for the Donation_Panel.css and adds it to the page
- And it also adds the crypto area to the modal and the "other payments" area
Development Rules[edit]
Every developer please follow these rules and consult with the admin. A wiki is a collaborative process so compliance with the rules makes everyone's life easier. Thank you.
General[edit]
- no external libraries hosted on third party servers
- locally running Open Source code: yes
- external libraries preferred from packages.debian.org bookworm
- non-javascript fallbacks required for any new developments
- Whonix vs Kicksecure website should look different
- improve from now ~30% design to ~80% design if the remaining ~20% would take \80% of the time
- keep Dev/CSS in mind
- screenshot before / after major changes (will be used for public reports)
- svg is nice as base format but incompatible with Tor Browser maximum security slider setting
- keep relative link support
MediaWiki Upstream Bugs Reports and Feature Requests[edit]
- These are requests to MediaWiki which we sent upstream
- Check in regularly if there was any activity.
- https://phabricator.wikimedia.org/p/adrelanos/
- MediaWiki upstream: mediawiki-extension-css feature requests and patches:
- feature request: Enable unsanitized CSS namespaces
- patch / pull request: Some CSS stripped by MediaWiki parser CSS sanitizer
- Widgets extension: add Widgets extension compatibility with $wgCSPHeader CSP Content Security Policy
- Pagespeed performance dropped significantly due to total blocking time issue.
- TOC toctogglecheckbox breaks form label rule by not being labelled (duplicate)
- Inconsistent behavior regarding plain links and links in images
- Multiline tags in lists should be output more intelligently
- extraneous newlines caused by templates
- Wikitext Parser Bug when using template inside list
- Publicly visible section edit buttons are indexable by search engines
- Extension:TextExtracts feature request: Explicit Definition for TextExtracts Content
- Add Wikitext capabilities to cookiewarning-info for Extension:CookieWarning
- re-enable `"responsive": true,` in Vector legacy OR honor `$wgVectorResponsive = true;`
- FlaggedRevs: API broken, action=review API function broke
- please keep Vector Legacy skin unchanged
- document how to add custom footer links using SkinComponentMenuLink::getTemplateData
- Include important Core / HTML / CSS / JS changes into future MediaWiki changelogs
archived:
- grabbers: grabFiles.php broken in MediaWiki 1.38 due to MediaWiki API changes
- Heading elements are not in a sequentially-descending order (wontfix)
- Allow API editing
- $wgCSPHeader CSP Content Security Policy compatibility with $wgUseFileCache file cache
- mediawiki-extensions-widgets: PHP Warning: call_user_func() expects parameter 1 / class 'WidgetRenderer' does not have a method 'initRandomString'
- Bootstrap extension: ParserOutput::addModuleStyles with non-array argument was deprecated in MediaWiki 1.38 #62
- Widgets extension: InvalidArgumentException: NamespaceInfo::isTalk called with non-integer (string) namespace 'NS_WIDGET'
- Widgets extension: $wgWidgetsUseFlaggedRevs broken
Widgets[edit]
Using a really small fork:
Whonix-Wiki
source code folder (MediaWiki including all extensions) (Whonix-Wiki
should be renamed to be more generic) contains apatches
subfolder which contains all files which are patched. (LocalSettings.php
,robots.txt
,mediawiki-widgets-extension.json
.)- The script
wiki-fix-permissions
on the server deletes the originalextensions/Widgets/extension.json
file and replaces it with a symlink in thepatches
folder, filemediawiki-widgets-extension.json
. - This patch would be no longer required if Allow API editing (allow API editing pull request) gets merged.
Wiki convention regarding Widgets:
- Widgets shall always be wrapped / encapsulated in Templates and (if possible) never be used except via this Template (or another Template using this widget)
- Reasons
- Templates are easier to use for wiki editors.
- Templates support Special:WhatLinksHere, widgets do not. So we can see where a module is used which makes testing and debugging easier
- Exception:: In some Widgets we use arrays over which we can loop. This works with Widgets but does not work with Templates. This is also how the Extension:Widgets suggests using arrays. See https://www.mediawiki.org/wiki/Extension:Widgets . Moreover the Extension:Widgets does not allow the modifier "explode" which would usually be used to convert a string to an array in the Smarty template engine. That is why we sometimes use widgets instead of templates. To bypass the "findability" problem of widgets you can search
#widget:widget_name
to find all Widget instances
Templates - in MediaWiki in General[edit]
Developing templates[edit]
When developing templates there are a couple of rules and best practices to go by
- Templates with HTML : In MediaWiki it can happen that a template which uses the limited allowed HTML in wikitext works fine on a plain level. But once the template is deployed in special circumstances, for example as a list item, it not only not works but is "ripped apart", meaning the inner elements are rendered not inside but AFTER their parents. This happens due to mediawikis template parser and might even be considered a bug. -> Wikitext Parser Bug when using template inside list
- Example Code # TemplateTest1 <span class="parent"> <span class="child"> Text </span> </span> # Page * Bullet Point 1 * ((TemplateTest1)) (but with real syntax) * Bullet Point 3
- This results in span.child being rendered after span.parent. But this only happens in special contexts like as a list item. In normal wikitext this works
- Solution for the time being: Spare all line breaks and unnecessary spaces. The latter because sometimes a space is interpreted as an indentation and leads to rendering as a pre element. Solution example: <span class="parent"><span class="child">Text</span></span>
Testing[edit]
- You can use Testpages in the following style
- Testpage1
- Testpage2
- Testpage3
- Testpage11
- Widget:Testwidget
Performance Testing[edit]
- We have implemented a couple of performance testing measures
- The test results are documented here: PerformanceTests
- The relevant Files are
- MwCombineJsWrapper there are the functions
window.mwDev.test.pageLoading()
andmwDev.tools.test.pageLoadingExpectedEvents()
which are used to measure different (manually triggered) events. When the last event is triggered then a report is shown in the consolemwDev.tools.test.pageLoadingExpectedEvents()
is used to register expected events. This is crucial, so the report only waits for the events that have been registered to occur. This is necessary because our Javascript execution is not strictly synchronous but asynchronous to deliver a much better performace to the user, learn more: Wiki Load Cascade : HTML, CSS, Javascript- The events always occur:
page-load-start
(before the scripts get initiated) andpage-load-all-scripts-initiated
(after all scripts have been initiated, but NOT completed) - These additional events are registered
page-load-code-select-enriched
gets registered before the page wide init of CodeSelect and occurs when the last CodeSelect is initiatedpage-load-share-tooltip-enriched
gets registered before the page wide init of ShareTooltip and occurs when the last ShareTooltip is initiatedpage-load-scroll-auto-wrapper-enriched
gets registered before the page wide init of customScrollbar compatible elements and occurs when the last customScrollbar compatible elements is initiated
- In MwCombineJsWrapper there is also a functionality which gets activated if the url query parameter ?delayedPageLoad=true is used
- This hides the page for 20 seconds after it is loaded and then makes the page reappear
- This is done to test whether gtmetrix and pagespeed ignore Javascript or really reander the pages property. Our research from 2022-10-15 shows the both testing pages correctly hid the page and therefore reacted to the javascript correctly
- In JsPerformanceTests there are these functions. The can be called in the browser console or in other scripts. mwDev is in the global namespace
- mwDev.test.jsJammer = function( bursts = 10, pause = 300, runs = 100 ) : This method will create 1 millions times bursts (of heavy processor load) with pauses in milliseconds for given amount of runs (repetitions). This is to slow down the browser and create a low performance browser scenario for testing reasons.
- mwDev.test.scrollPageTest = function( time = 600, runs = 10 ) : This method will scroll the whole page up and down in the give time milliseconds for the given amount of runs (repetitions). One run down will take time to complete. The measurement however is down and up again, so time * 2. Against this will be measured the time it actually took to scroll the page. The difference should give a hint if the page is performing well or not
Development: use files only if needed[edit]
- These files are optional for your use in development
Bug report to upstream[edit]
Sometimes (seldomly) there needs to be a bug report or feature request or suggestion to upstream. Below are the necessary steps for this, demonstrated on a real request which we sent
Example: gerrit patch compare https://gerrit.wikimedia.org/r/c/mediawiki/extensions/CSS/+/759196/
git clone https://gerrit.wikimedia.org/r/mediawiki/extensions/CSS mediawiki-extension-css
cd mediawiki-extension-css
git fetch https://gerrit.wikimedia.org/r/mediawiki/extensions/CSS refs/changes/96/759196/1
git checkout -b change-759196 FETCH_HEAD
git remote add adre https://github.com/adrelanos/mediawiki-extensions-CSS.git
git fetch adre
git diff -C adre/all-css
Image Optimizations[edit]
Image Optimizations Installation[edit]
sudo apt update sudo apt install mat2 optipng jpegoptim webp
mat2 - strip of metadata[edit]
To strip files of meta data use mat2 on linux.
Strip images of metadata in place - in the directory where you're in. Caution: Might reduce quality or totally break images in case of SVGs!
mat2 image-file-name
If that fails, try:
- mat2 --lightweight image-file-name
- Minor space saving effect on images that have been created using
gimp
. - Removes metadata.
- Minor space saving effect on images that have been created using
Check:
- mat2 --show original-file-name
- mat2 --show cleaned-file-name
PNG Optimizations[edit]
Specifically for PNG.
optipng -quiet -o7 -zm9 -zc9 -zm9 -zs3 -f5 --strip all -preserve image-file-name
JPG and JPEG Optimizations[edit]
Specifically for JPG and JPEG.
jpegoptim --quiet -o --strip-all image-file-name
Convert to WEBP[edit]
Convert to WEBP.
cwebp -mt -lossless -z 9 input-file-name -o output-file-name.webp
SVG Optimizations[edit]
SVG Optimizations - Introduction[edit]
WARNING: SVG is particularity vulnerable to metadata!
1. Saving the SVG as "optimized" in inkscape
as this might be more reliable than scour.
2. Try scour
(documented below).
3. Check image quality. If unchanged, keep changes by scour
. Otherwise, revert.
4. Try svgo
(documented below).
5. Check image quality. If unchanged, keep changes by svgo
. Otherwise, revert.
6. Check image for metadata using text editor.
Open in a text editor and search for file paths containing Linux user account name.
7. Check image for metadata using other tool.
TODO: Did we use any? If not, skip.
8. Upload.
9. Done
SVG Optimizations - scour[edit]
WARNING: scour
can break the SVG!
scour --enable-viewboxing --enable-id-stripping --enable-comment-stripping --shorten-ids --indent=none -i input-file-name -o output-file-name
SVG Optimizations - svgo[edit]
info:
SVG Optimizer is a (Node.js-based) tool for optimizing SVG vector graphics files.
install:
Install re.sonny.OhMySVG
via flatpak.
1. Add a Flatpak repository.
A : Kicksecure
===Already enabled by default. (system-wide). No additional stepss needed to enable the Flathub repository.
B : Kicksecure-Qubes Template
===kicksecure-17
)Already enabled by default. (system-wide). No additional stepss needed to enable the Flathub repository.
C : Kicksecure-Qubes App Qube
kicksecure
)The user needs to Enable the Flathub Repository . Must be enabled per-user.
2. Install the flatpak re.sonny.OhMySVG
package.
B : Kicksecure-Qubes Template
===Kicksecure-Qubes Template (kicksecure-17
) [3]
Note: Advanced users that uninstalled the qubes-core-agent-passwordless-sudo
package should see forum thread Warning: Flatpak system operation Deploy not allowed for user.
http_proxy=http://127.0.0.1:8082 https_proxy=$http_proxy flatpak install flathub re.sonny.OhMySVG
C : Kicksecure-Qubes App Qube
Kicksecure-Qubes App Qube (kicksecure
) [4]
flatpak --user remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
flatpak --user install flathub re.sonny.OhMySVG
3. Done.
The procedure of installing re.sonny.OhMySVG
is complete.
4. Upgrades notice.
Note: this procedure will not keep the software up-to-date. How to update installation installed by flatpak is also documented on the Operating System Software and Updates wiki page.
run:
flatpak run re.sonny.OhMySVG
usage:
https://github.com/svg/svgo#cli-usage
Using HTML comments as spacers in Templates[edit]
- We realized that MediaWiki seems to render (seemingly) unnecessary p-paragraphs if there is a gap between templates used in a page. This leads to unwanted spacing. But if we do not use newlines then the code is very hard to read
- This seems to be standard behavior and not a bug, as also reported here, especially when dealing with div-elements https://www.mediawiki.org/wiki/Topic:V6leoh5syqlya4kg
- In this link there is also a suggestion to deal with the problem: adding HTML comments as spacing like so
<div>something</div><!-- --><div>something</div><!-- --><div>something</div>
- This would also apply for using templates like so
{{template1}}<!-- -->{{template2}}<!-- -->
- This is not the most beautiful solution, but better than the alternative having to write everything in the same line
{{template1 |param1=value1 }}{{template2 |param1=value1 }}
- This should not be used permanently. We occasionally use this as a workaround until this is fixed by MediaWiki
Debug Images Cache[edit]
webp
images are automatically created from jpg
, jpeg
and png
once per day on the server. Modern web browser are sending the accept
HTTP header. The browser is using that header to advertise that the browser supports for example the webp
image format. If the HTML markup contains a request for a jpg
, jpeg
and png
but a a webp
is already available and the browser supports it, the webp
will be delivered instead.
This can sometimes be confusing.
To explicit download the original image format it is the easiest to use a command line downloader such as wget. This works because command line downloaders are in the experience of the author not sending the accept
HTTP header. Hence, the server will deliver the actual file and not "upgrade" to webp
. For example:
wget 'https://www.kicksecure.com/w/images/2/25/Magnifying-glass.png'
Or
curl -O 'https://www.kicksecure.com/w/images/2/25/Magnifying-glass.png'
To debug if the image is a jpg
, webp
or otherwise use the commands.
Examples:
curl --silent --head 'https://www.kicksecure.com/w/images/2/25/Magnifying-glass.png' | grep content-type:
content-type: image/jpeg
curl --silent -H 'accept: image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8' --head 'https://www.kicksecure.com/w/images/2/25/Magnifying-glass.png' | grep content-type:
content-type: image/webp
Stage / Staging Server Testing[edit]
- For each Whonix and for Kicksecure there are staging servers to test new developments and new wiki version as close to production as possible
- Devs, please ask the admin for details about the IPs and how to setup your system to reach the staged servers
- If you're on a Linux system admin will ask you to add to lines to your
/etc/hosts
. Admin also has a shell script available to simplify this process. - After that the URLs kicksecure.com and whonix.com will point to the staging servers, not to the production servers.
- Possible errors : BEWARE however that some browsers that use special proxies or DNS over HTTPS (like Waterfox) will ignore the
/etc/hosts
file. - Please use the following verify method to check whether your system connects to the staging servers correctly
- And also learn how to use the Dev/mediawiki#StageServerNotice to identify that your browser really shows the staging server
- If you're on a Linux system admin will ask you to add to lines to your
- Verify IP: To verify whether your switching to the staging server is successful, execute this command on the shell curl --silent --head --header "nocache: true" "https://www.whonix.org"
- If you're on the staging server the expected outcome is
x-server-type: stage
, if you're on the production server the expected output isx-server-type: production
- Note: Linux distribution specific: On Linux systems you can also use nslookup [domain]
or dig [domain] +short
, for example
dig kicksecure.com +short
to check the URL that your system associates the URL with. - Be aware that none of these systems are perfect, so be sure to double check
- Broken on Debian. Both dig and nslookup are ignoring /etc/hosts. Double checked by Patrick.
- If you're on the staging server the expected outcome is
Code Resources for MediaWiki[edit]
As inspiration or directly as a code source.
- https://dev.fandom.com/wiki/Category:JavaScript/Site_enhancements
- https://dev.fandom.com/wiki/Category:CSS
- https://dev.fandom.com/wiki/Fandom_Developers_Wiki
- https://en.m.wikipedia.org/wiki/Wikipedia:User_scripts/List
Example Pages for CSS Enhancements[edit]
- Here you can find examples for module usage and applied CSS classes
- Tor Browser - long table of contents, lots of thumb images and images
- Windows Hosts - lots of tables
- Comparison with Others - lots of tables and footnotes
- VirtualBox
- VirtualBox - example for breadcrumbs navigation (to VirtualBox)
- Download - images table is not responsive on mobile
- KVM - has table of contents (TOC), Template:Contributor (
About this KVM Page
) and illustrative image thumbnail (inofficial KVM logo) - Troubleshooting - uses mini navigation
- Tor - example of using CodeSelect for user command and pre tag for expected output style
BIMI Images[edit]
- To create BIMI compliant logos follow these resources
- Examples how other BIMI images look:
- https://www.valimail.com/wp-content/uploads/2021/04/Amplify-1-920x517-c-default.png
- https://media.emailonacid.com/wp-content/uploads/2019/08/BIMI-before-and-after-EOA2019.jpg
- https://web.archive.org/web/20220510001045/https://public-assets.postmarkapp.com/blog/_630x273_crop_center-center_10_none/BIMI_before_after.png
- Resources:
- requirements
- needs to be < 32 kb in size
- must be square
Instructions to create a bimi logo from an inkspace svg (tested method)
- open logo in inkscape
- Save as ->
optimized SVG
, choose "remove meta information" - open logo in gedit (or similar)
- in svg-tag remove x= and y= attributes and use version="1.2" attribute and add (if not present) baseProfile="tiny-ps" attribute
- add title="your-title" attribute directly under svg tag. your-title can be your company or product name
- optionally add desc="your-description" directly after title tag. your-description can be a description of your company or product
- remove all animations from logo (if present, usally not)
- Upload to wiki
- Check with https://easydmarc.com/tools/bimi-record-generator
Cache[edit]
- Cache is a complex topic, that has a lot of benefits but also a lot of pitfalls. For websites there are multiple relevant caches, e. g. php cache on the server, CDN cache, static html cache (e. g. generated by apache / nginx) and browser cache on the client. For us the server static html cache and browser client cache is relevant
- server static html cache : Our server generates a static html cache for a wiki page once the first time a wiki pages is loaded. After that only the static cache will be server. This happens until a cache-clear is executed and all cache files are deleted and the process starts new
- Benefits: This cache saves a lot of computing power for the wiki and improves load times for users
- Drawbacks: Once a new feature is introduced cache-clear has to be executed. Otherwise users will get the old version
- Cache bypass methods
- Cookie nocache=true : If you have a cookie set to
nocache=true
then the server will always deliver the newest page content and not the cache. This cookie can be set by using the Debug Helper, learn more: Debug-via-url-modal - query ?nocache=true : If you have the url query parameter
?nocache=true
then the same is achieved as with the nocache cookie (see above) - request header nocache:true : If you call the page with the request header
nocache: true
then the same is achieved as with the nocache cookie (see above)
- Cookie nocache=true : If you have a cookie set to
- Cache clear methods
- Clear cache scripts on server : On the server there are clear cache scripts for admins. Execute one of these scripts to clear the server cache.
- NOTE: This action also changes the
hsversion_from_server_replacement_unixtime
value, which is neede for the browser client cache clear methods
- NOTE: This action also changes the
- Mediawiki purge : Use the MediaWiki purge method (more infos below) to clear the server cache for a single page in the wiki.
- Clear cache scripts on server : On the server there are clear cache scripts for admins. Execute one of these scripts to clear the server cache.
- browser client cache
- Browsers cache scripts, files and whole pages locally to save time and bandwidth. So when a page is loaded that has been visited before chances are large parts of the page are loaded from cache and not from the internet
- Mobile browsers are (understandably) especially aggressive with this behavior. They might even not call a page (the main document) but just the headers to see if changes have happened based on the cache directive headers
- Benefits: This saves a lot of bandwidth and load time for the user
- Drawbacks: The user might not get the newest version of the website because the browser prevents it
- Cache bypass methods
- Developer tools disable cache: Open the browser developer tools dialog, choose "Network" and click "disable cache" (or something similar). Now the browser will not cache the page or its elements
- Arbitrary query parameter: Use an arbitrary (unused!) query parameter like
?x=1
to bypass the browser cache. With a new query parameter the browser is forced to reload the document and also the server will not have a cached version because the server caches only per exact URL.
- Cache clear methods
- Clear cache button: There are plugins and browser specific settings to clear the whole cache of the browser or just for the page. This depends on the browser and can be researched on the internet
- Force Cache clear methods by the server
- Header settings: The header
cache-control: s-maxage=86400, must-revalidate, max-age=0
is set by the server and forces the browser to revalidate the document. However not all browsers do this- NOTE: Big platforms also use aggressive (no-)cache headers. In this article there are header examples from some big platforms.
- Automatic method hsversion parameter: For all our important scripts, styles, images etc we use a query parameter
hsversion_from_server_replacement_unixtime
. This parameter is appended to all our scripts and guarantees that the browser has to reload the script once the hsversion changes. Such a change happens when the cache clear script on the server is executed - Rename library path method: For all our libraries (functional js/css libraries like FontAwesome, instant.page etc) we do not use hsversion because the browser would have to reload them even though they very rarely if ever change. If the DO change then we simple change the folder in this manner
library-name_date-reverse
, e. g. "Font-Awesome_2023-08-03". This way the browser is forced to reload the library. We do not use the library version number because for us it's more important when we changed the version
- Header settings: The header
Server cache clear : MediaWiki Purge - deleting cached file[edit]
This method clears the server cache (HTML) for a specific page.
If you click purge on page or use the respective urls (examples below) then the cached file on the server is deleted and you should get the newest version
mediawiki cache purge:
- https://www.kicksecure.com/wiki/FAQ?action=purge
- https://www.kicksecure.com/wiki/FAQ?useformat=mobile?action=purge
Server Cache Bypass methods[edit]
These methods can be used to bypass the server cache.
nginx bypass cache example (not really deleting the cache either yet):
A query parameter:
https://www.kicksecure.com/wiki/FAQ?nocache=true
https://www.kicksecure.com/wiki/FAQ?nocache=true
B HTTP request header:
curl --head --header "nocache: true" "https://www.kicksecure.com/wiki/Documentation"
B HTTP cookie:
curl --head --cookie "nocache=true" "https://www.kicksecure.com/wiki/Documentation"
If successful, the HTTP response header x-cache-status
will show BYPASS
.
x-cache-status: BYPASS
MediaWiki special resources[edit]
Those are hard to find via Google, so they are listed here
- MediaWiki:Signupstart
- MediaWiki:Anoneditwarning
- MediaWiki:Shoutwiki-loginform-tos
- MediaWiki:shoutwiki-must-accept-tos
- MediaWiki:Useragreement
- MediaWiki:Cookiewarning-info
- MediaWiki:Cookiewarning-moreinfo-label
- MediaWiki:Cookiewarning-more-link
- MediaWiki:Cookiewarning-ok-label
Special code resources (possibly outdated)[edit]
Debugging CSS JS mw-autogen[edit]
1. Check: https://www.kicksecure.com/mw-autogen
Are all files there?
2. MIME type issues? / content-type: text/html
?
Is the file even there?
3. Custom CSS JavaScript Debugging
Debugging Browser Console Errors[edit]
It is useful to enable MediaWiki (JavaScript) debug mode. To do so...
1. go to https://www.whonix.org/wiki/FAQ
2. click edit
3. the link being opened will be: https://www.whonix.org/w/index.php?title=FAQ&action=edit
4. replace action=edit
with debug=true
5. press enter to load the page
5. or skip the previous steps and direclty to to https://www.whonix.org/w/index.php?title=FAQ&debug=true
6. consider FAQ
with Testpage16
or so
In result in the browser console the scripts in the Debugger part are no longer minified and easier to read.
Search Suggestions Debugging[edit]
- Vector legacy uses:
- curl --head https://www.kicksecure.com/w/api.php?action=opensearch&format=json&formatversion=2&search=test&namespace=0&limit=10
- Vector 2022 uses:
- curl --head https://www.kicksecure.com/w/rest.php/v1/search/title?q=test&limit=10
- This was broken in past due to an nginx configuration issue.
rest.php
was reachable butrest.php/v1/
etc. was not.
Check if scripts are loaded[edit]
These scripts were used for debugging scripts while es special MediaWiki skin was applied
Using a desktop browser with mobile skin these scripts get loaded:
* https://www.{{project_clearnet}}/w/load.php?debug=false&lang=en&modules=jquery%2Cmediawiki&only=scripts&skin=minerva&version=obJk0fES * https://www.{{project_clearnet}}/w/load.php?debug=false&lang=en&modules=jquery.accessKeyLabel%2Cclient%7Cmediawiki.RegExp%2Cnotify%2Ctemplate%2Cutil%7Cmediawiki.page.startup%7Cmediawiki.template.hogan%7Cmobile.browser%2CmainMenu%2Cmodules%2Coo%2Cview%7Cmobile.loggingSchemas.mobileWebMainMenuClickTracking%7Coojs%7Cskins.minerva.scripts.top&skin=minerva&version=2bcd7ee968a7 * '''https://www.{{project_clearnet}}/w/load.php?debug=false&lang=en&modules=jquery.cookie%2Cthrottle-debounce%7Cmediawiki.api%2Ccldr%2Ccookie%2Cexperiments%2CjqueryMsg%2Clanguage%2Cstorage%2Ctoc%2Cuser%2Cviewport%7Cmediawiki.api.user%7Cmediawiki.language.data%2Cinit%7Cmediawiki.libs.pluralruleparser%7Cmediawiki.ui.input%7Cmobile.ajax%2Cbetaoptin%2Ccontext%2Cdrawers%2Cissues%2CmodifiedBar%2Coverlays%2Cpagelist%2Creferences%2Csearch%2Csettings%2Csite%2Cstartup%2Ctoast%2Ctoggle%2Cuser%2Cwatchstar%7Cmobile.editor.api%7Cmobile.issues.images%7Cmobile.loggingSchemas.edit%2CmobileWebLanguageSwitcher%2CmobileWebSearch%7Cmobile.overlay.images%7Cmobile.pagelist.scripts%2Cstyles%7Cmobile.pagesummary.styles%7Cmobile.references.gateway%2Cimages%7Cmobile.toggle.images%7Cskins.minerva.editor%2Cscripts%2Ctoggling%2Cwatchstar%7Cskins.minerva.icons.images.scripts%7Cuser.defaults&skin=minerva&version=4409fb4608cb''' * https://www.{{project_clearnet}}/w/load.php?debug=false&lang=en&modules=mobile.toc%7Cmobile.toc.images%7Cskins.minerva.tablet.scripts&skin=minerva&version=6b1c9eeeb881 * https://www.{{project_clearnet}}/w/load.php?debug=false&lang=en&modules=startup&only=scripts&skin=minerva&target=mobile
But using the emulated mobile device with the same skin only these get loaded:
- https://www.kicksecure.com/w/load.php?debug=false&lang=en&modules=jquery%2Cmediawiki&only=scripts&skin=minerva&version=obJk0fES
- https://www.kicksecure.com/w/load.php?debug=false&lang=en&modules=startup&only=scripts&skin=minerva&target=mobile
search for
sdShowDetailed
the error only occurs when a mobile device is used and the mobile theme is active
Test user agents[edit]
Test which different responses the server sends to different user agents
curl https://www.kicksecure.com/wiki/FAQ?useformat=mobile > 1
curl --user-agent "android.mobile" https://www.kicksecure.com/wiki/FAQ?useformat=mobile > 2
curl https://www.kicksecure.com/wiki/FAQ?useformat=mobile > 3
curl --user-agent "android.mobile" https://www.kicksecure.com/wiki/FAQ > 4
curl --user-agent "android.mobile" https://www.kicksecure.com/wiki/FAQ?useformat=mobile > 5
curl https://www.kicksecure.com/wiki/FAQ?useformat=mobile?useformat=mobile > 6
meld 1 2
Caching or not caching[edit]
We send a cookie to the server. If the server sends back the same header for both request then caching is off
curl --head --cookie cookie_name=cookie_content https://www.kicksecure.com/wiki/FAQ
curl --head https://www.kicksecure.com/wiki/FAQ
TOR browser testing of Javascript scripts to prevent NoScript bugs[edit]
- It is strongly suggested to to test all new Javascript scripts and modifications with Tor browser or a browser that has NoScript installed but with lowest / off settings
- NoScript sometimes influences the execution of scripts even if it's set to "not interfere". This can maybe be considered a NoScript Bug. But it is essential to test for NoScript bugs and optimize our scripts to that effect anyways because NoScript is standard on Tor browser and Tor users are a large target community using Whonix and Kicksecure
- So every time a new script is written or a script is modified check with Tor browser Standard security setting if everything is still working
Using JSHint and other Javascript analysis tools[edit]
- Our custom Javascript may need to be analysed from time to time
- Tools that can be used for this purpose. Recommendation: use in the listed order
- To start analysing
- open this url https://www.kicksecure.com/mw-autogen/mw-combined-wikijs.js
- copy all content
- paste into into the respective javascript validator
- Some tools may find too many duplicates (which might be invalid). To reduce the amount of "noise"
- output / copy the content of the javascript validator into a text file
- use the bash script below to exclude contents
Bash script to remove duplicates
#!/bin/bash #set -x set -e test -r js.txt skip_values=( "Prism" "Cookies" "debugjsDom" "Prism" '$' "mwDev" "ace" "mw" "'let' is available in ES6 (use 'esversion: 6') or Mozilla JS extensions (use moz)." ) trim_all() { # Usage: trim_all " example string " set -f set -- $* printf '%s\n' "$*" set +f } while read -r line ; do trimmed_line=$(trim_all "$line") first_word="${trimmed_line%% *}" rest_of_line=$(echo "$trimmed_line" | cut -d' ' -f2-) break_now=false for val in "${skip_values[@]}"; do if [ "$rest_of_line" = "$val" ]; then continue 2 fi done echo "'$rest_of_line'" done < js.txt
Parser Function Special constructions for if, ifeq, ifexpr and more[edit]
We use MediaWiki Parser Functions in a lot of templates. Specifically if-constructions. However, Parser Functions are not as easy to use as in programming languages. Sometimes more complex constructions are needed to achieve the desired logical conditions. In this chapter we document such constructions that we use as a reference for developers and to give inspiration how to achieve the desired outcome. This is also needed because online searches are very sparse regarding these problems.
Converting if into a string result to be used in ifeq[edit]
{{#ifeq: {{#if: {{{project|}}} | {{{project|}}} | {{project_name_short_lowercase}}}} | {{project_name_short_lowercase}} | yes | no }}
- The construction above is used in Template:DonorCard and basically says "either the project parameter is NOT set or the project parameter equals the content of the project_name_short_lowercase template".
- This is normally hard to do because
{{#if ...}}
would be the right construction to check whether the variable is set and{{#ifeq: ...}}
is correct for comparing strings. The whole expression cannot be modelled in either of them. - What we do is convert the boolean of the if construction into a string where a given parameter outputs itself again to be compared while a not-given parameter outputs the correct second condition and therefore always leads to true.
Replacement instructions[edit]
In this chapter some specific wiki wide text replacements are documented so they can later be reproduced safely if needed.
Double empty line replacement[edit]
For a wiki wide replacement of double empty lines this procedure was successfully tested on 2024-09-05
- Go to the ReplaceText Special Page
- Use this RegExp (\n{2})\n+ and this replacing text $1 . This will find any double empty lines (or more) and replace them with a single empty line
- Check "Use regular expressions" checkbox and click "Check All" to search in all namespaces and Click "Continue"
- Repeat if necessary (sometimes due to nested templates the replacement is not fully effective)
- Check Recent Changes and confirm that all changes were as desired
Replace all image wiki tags with file tags[edit]
MediaWiki has shifted from the [[image: ...]]
syntax to the [[File: ...]]
syntax. This is explained here https://www.mediawiki.org/wiki/Help:Images . All examples are with the new file syntax and also the intro paragraph is very clear:
Images that are stored on a MediaWiki server are usually rendered by using the File: namespace prefix (but the legacy Image: namespace prefix is still supported as a synonym) as the target of a MediaWiki link.
On 2024-09-06 we have replaced all [[Image: [[image: [[file:
syntaxes with the upper case [[File: ...]]
syntax. Here is an instruction to reproduce this process if needed in the future
- Go to the ReplaceText Special Page
- Use this RegExp
\[\[(image|Image|file)\:
and this replacing text[[File:
. This will find all legacy image tags and lowercase file tags and replace them with the uppercase file synax. - Check "Use regular expressions" checkbox and click "Check All" to search in all namespaces and Click "Continue"
- Repeat if necessary (sometimes due to nested templates the replacement is not fully effective)
- Check Recent Changes and confirm that all changes were as desired
Replace old images with new ones[edit]
- The Dev and Admin team agreed on new naming schemes for project internal images like logos or graphical components. These are documented here Dev/Logo.
- On 2024-09-06 therefore the existing images were renamed and replace in all wikitext (and possible wiki project source files, but there were none) with the new file names
- To not interrupt running wikis by temporarely having unfunctioning images, follow these instructions
- Document all image names to replace in a table on your local computer in one row and write all the desired new names in a second row
- Go to the wiki pages of all images (structure
wiki.domain/wiki/File:image.bmp
) and click "move". Enter the new file name from your second row of the table as new name inNew title:
. Important: Keep the checkboxLeave a redirect behind
checked! - Go to the ReplaceText Special Page
- Use the old filename for each image as the search and the new file name as the replacement text
- Click "Check All" to search in all namespaces and Click "Continue"
- Check Recent Changes and confirm that all changes were as desired
- Now visit all wiki pages of the old images again but with the query parameter
?redirect=no
. Now delete this page (More → Delete)
Pagespeed and Lighthouse[edit]
- Lighthouse is a performance testing tool by Google for websites that is widely used and highly regarded: https://developers.google.com/web/tools/lighthouse/
- Pagespeed is a google website for developers incorporating Lighthouse and also delivering real world and "lab" data for developers to evaluate their websites' performance objectively: https://pagespeed.web.dev/
- We strive to reach close to perfect scores for the most important pages of this wiki
- Below is a collections of important information that we learned regarding MediaWiki, third party vendor code and our our code during the process
Error "Links do not have a discernible name" for thumbnail images with link parameter[edit]
- We get the Lighthouse error "Links do not have a discernible name" for images of this structure <code>[[File:image.jpg|thumb|link=Page]]</code>
- Crucial about this is the use of the thumb parameter in combination with the link parameter. This leads to MediaWiki rendering an empty link with the class mw-file-magnify that links to the image description page and has an icon inserted via CSS which is not accepted by Lighthouse
- We consider this a bug by MediaWiki and therefore a report for MediaWiki was written https://phabricator.wikimedia.org/T372222
Error 'Values assigned to role="" are not valid ARIA roles'[edit]
- Lighthouse error report
Values assigned to role="" are not valid ARIA roles
- This error is found in our TOC rendering because of the Legacy vector skin. This skin is rendered with HTML non-conformities.
- Specifically here an input-box with
type="checkbox"
is givenrole="button"
. This combination is not valid. - A MediaWiki upstream bug report was filed: Legacy Vector TOC Lighthouse bugs due to toggle collapse (duplicate)
Error "Form elements do not have associated labels"[edit]
- Lighthouse error report
Form elements do not have associated labels
- This error is found in our TOC rendering because of the Legacy vector skin. This skin is rendered with HTML non-conformities.
- Specifically
label.toctogglelabel
is an empty label element which is not valid and which triggers the error for theinput#toctogglecheckbox
element - A MediaWiki upstream bug report was filed: Legacy Vector TOC Lighthouse bugs due to toggle collapse (duplicate)
Error "Links do not have a discernible name"[edit]
- Lighthouse error report
Links do not have a discernible name
- This error is found a.mw-file-magnify. Thumbnails with the syntax
File:image.jpg|thumb|link=Page
are rendered as a link with neither a link text nor a link image (because the icon is added via CSS). This is highly problematic for screen readers and therefore reported as an error - A MediaWiki upstream bug report was filed: Lighthouse empty link problem for thumbnail images with link parameter
Error "Links are not crawlable"[edit]
- Lighthouse error report
Links are not crawlable
- This error is found with
a.mw-selflink.selflink
. These are rendered when an internal wiki link with the[[Page_Title]]
syntax is pointing to the exact page the user in on. However selflinks don't have an href- oder name-attribute and are therefore not functional links and are therefore not crawlable. Search engine crawlers and Lighthouse see this as a conflict. It would be better and it would solve the problem if at leastrole="presentation"
was added via the MediaWiki core to thea.mw-selflink.selflink
to clarify its role as a non-link - A MediaWiki upstream bug report was filed: Lighthouse error "Links are not crawlable" for selflink links
- This bug can also affect all Mini Navigation elements because they are relying on standard MediaWiki elements, especially internal wiki links with the
[[Page_Title]]
syntax
Error "Links rely on color to be distinguishable."[edit]
- Lighthouse error report
Links rely on color to be distinguishable.
- This error can be found in various places whenever the only differentiating quality of a link from the text is its color: same font, same size, same font weight, same font style, just different color. This is not enough for Lighthouse in some cases
- So whenever this error occurs, you have the (not limited to) following options: change font-family, change font-size, change font-weight (e. g. bold), change font style (e. G. italic), underline link, use letter-spacing etc.
Error "Failed to load resource: net::ERR_ACCESS_DENIED"[edit]
One issue Failed to load resource: net::ERR_ACCESS_DENIED
can not be reproduced in local Lighthouse, only on Pagespeed (PS). This might be a timing issue or a CORS issue. But for testing admin would have to enable cross-origin-resource-policy: cross-site on the server. This might however be a (small) security risk and therefore not a long term solution. DEV thinks it might be a timing issue with PS loading the files too late and therefore being rejected by the server. Maybe a longer server timeout could solve this problem.
Pagespeed "Reduce unused CSS"[edit]
- This issue refers to CSS files or commands that are loaded but cannot be applied to any element on the page. So they are "unused" and therefore unnecessary. More information on this page https://developer.chrome.com/docs/lighthouse/performance/unused-css-rules
- To check which files are exactly affected use e. g. Chrome Developer Tools, open the command menu (Ctrl+Shift+P) and type "Coverage" to open the coverage sub menu. More information here https://developer.chrome.com/docs/devtools/css/reference?hl=de#coverage
- This tool is a good orientation / indicator, but can also be confusing. For example a CSS rule that has an impact on an element, but is ultimately not needed (because another rule does the same thing), is also considered "unused", although it technically overrides the other rule (with the same effect)
- CSS styles that are not used are in read, while files that are completely unused are at the bottom having "0%" use
- In our case almost all unused CSS files are auto-loaded by wiki and therefore mostly out of our control
EXPORT to new wiki[edit]
If new wiki shall be created which is similar to the current master (Kicksecure) you can use the Export function to export all necessary pages and files (e. g. images) and then import those files in the new clean slate wiki.
CAUTION: This export is different from the export cascade from Kicksecure (master) to the "slave" wikis. All new design and code inventions on the Kicksecure wiki will be mirrored towards the "slave" wikis once they are finalized and tested. See #MultiWiki for more information. But this export here is for creating completely new wikis as a copy of the Kicksecure wiki.
In the last main export event (2022-03-19) the following files were exported. To repeat this process
- copy the following files
- insert into Special:Export and save the resulting XML-file
- go to [new_wiki_domain]/wiki/Special:Import
- Use the following Interwiki prefix: en
- copy the following list and paste into the import list on the
Special:Import
page
CAUTION: This list does not claim to be complete or accurate or up-to-date. If you want to be sure you have to check the complete list and remove old files and add new ones. This list is just meant to save you time. Also be so kind to update the list if you have created a new more accurate up-to-date list.
Show Export List
MediaWiki:Common.js MediaWiki:Common.css MediaWiki:BackToTopButton.js MediaWiki:BackToTopButton.css Template:Download Button Widget:Download Button MediaWiki:Download Button.css MediaWiki:Download Button.js Template:CodeSelect Widget:CodeSelect MediaWiki:CodeSelect.js MediaWiki:CodeSelect.css Template:Archive_link Widget:Archive_link MediaWiki:Archive_link.css MediaWiki:Bootstrap Fixes.css Widget:Subdomain link Template:Subdomain link File:Magnifying-glass.png File:Support-premium.png File:Support-plus.png File:Support-free.png File:Mastodon-logo.png File:Twitter-logo.png File:Reddit-logo.png File:Facebook-logo.png File:Donate-banner.png File:Evolution-host.png MediaWiki:SaveAndContinue.css MediaWiki:SaveAndContinue.js File:Chevron.png File:X.png MediaWiki:Vector.css MediaWiki:EditorFullscreen.js MediaWiki:EditorFullscreen.css MediaWiki:LocalWiki.css MediaWiki:Dev.css MediaWiki:Fonts.css Template:Header Widget:Header MediaWiki:Header.js MediaWiki:Header.css Template:Footer Widget:Footer MediaWiki:Footer.js MediaWiki:Footer.css MediaWiki:ScrollableIndicator.js MediaWiki:Mininav.css MediaWiki:Sitenotice Widget:Sitenotice MediaWiki:Sitenotice_id MediaWiki:Sitenotice.css MediaWiki:Sitenotice.js MediaWiki:Hide siteNotice.css File:Grow-symbol.png File:Qr-logo-v2.png MediaWiki:Donation_Panel.css MediaWiki:Donation_Panel.js Widget:Donation_Panel File:Affiliate 128.png File:CAD 128.png File:CHAPS 128.png File:BACS 128.png File:FasterPay 128.png File:WireTransfer 128.png File:ACH 128.png File:Swift 128.png File:DirectDebit-card-dark 128.png File:Sepa-Last 128.png File:Sepa-card-dark 128.png File:IBAN 128.png File:AUD 128.png File:GBP 128.png File:Discover-card-dark 128.png File:UnionPay-card-dark 128.png File:AmericanExpress-dark 128.png File:Dollar 128.png File:Euro 128.png File:Bank-dark 128.png File:MasterCard-dark 128.png File:Visa-card-dark 128.png MediaWiki:PayViaPaypal.css MediaWiki:PayViaPaypal.js File:Payment-generic-symbol.png File:Crypto-generic-symbol.png File:Credit-card-generic.png File:GiroPay-card-dark-enlarged 128.png Widget:Expand_or_Collapse_All MediaWiki:ExpandOrCollapseAll.js Widget:FlyInNotification MediaWiki:FlyInNotification.css MediaWiki:FlyInNotification.js MediaWiki:Hide flyInNotification.css Template:Pay bitcoin qr Template:Pay bitcoin qr imgurl Template:Pay monero qr Template:Pay monero qr imgurl Template:Pay ethereum qr Template:Pay ethereum qr imgurl Template:Legal documents Template:Hide all banners Template:Support Choice Donate Template:Payments Donate/Affiliate Link Donate/Bank Wire Donate/Bitcoin Donate/Credit Card Donate/Crypto Donate/EUR Donate/Ethereum Donate/GBP Donate/Monero Donate/PayPal Donate/Tax-Deductible Donate/USD Donate Bitcoin Donate Ethereum Donate Monero Donate by Affiliate Link Template:Donation mininav
USAGE : Module Documentation (Alphabetical order)[edit]
AddMessageToCopiedText (Copyright text injection)[edit]
- Message injection via javascript has legitimate applications, like original source websites injecting their copyright.
- Using this hidden text attacks are a less frequent than other attacks but are still relevant attacks on users in the context of phishing and malware. You can read more about them here Shell
- The Whonix and Kicksecure team uses message injection to insert copyright into copied text from the website (with protected elements like CodeSelect, pre, quotations and others being exempt)
- This is also intended to be a demonstration of the dangers of "mindless" text copying from websites as described in Shell
- Details
- The script is executed on all non-internal pages, meaning all pages NOT starting with
/w/index.php
- The currently protected (exempt from copyright injection) elements are by their selectors
pre,code,blockquote,.pre,.code-select,.code-select-target,textarea,.wikiEditor-ui-text,.mw-headline
- When any other element is selected and ctrl+c is pressed or context-menu>copy is clicked the text that is copied to clipboard gets our copyright message added at the end
- Mixed selections, like starting in a protected element but in a not-protected element - will also get the copyright injection
- The script is executed on all non-internal pages, meaning all pages NOT starting with
- Relevant files
Anchor - manually placed anchors[edit]
- Template:Anchor is a span element with the class "manually-placed-anchor"
- It has 1 anonymous parameter which sets the id attribute for the span element
- CSS: The element has no dimension and is relatively positioned above it's normal position about the amount that the Header is high. That way if the anchor is called the header does not overlap the anchored position. This is especially useful when referencing headlines
- It is usually used to manually set anchors to make old links work with new headlines
- Example:
{{Anchor|my_id}}
creates<span class="manually-placed-anchor" id="my_id"></span>
- Relevant files
Anti-Spam email tooltip[edit]
- Contact emails are sometimes abused by spammers. To deter some of them the template for the email contact has been upgraded to show a tooltip when hovering over it.
- The tooltip itself can be hovered over too to copy information or click links
- Icons can be used, instead dots will be used as bullet points as default
- USAGE :
{{Template:Name-email}}
- Example (hover to see tooltip):
adrelanos(at)kicksecure.com
(Replace(at)
with@
.)Please DO NOT use e-mail for one of the following reasons: Private Contact: Please avoid e-mail whenever possible. (Private Communications Policy) User Support Questions: No. (See Support.) Leaks Submissions: No. (No Leaks Policy) Sponsored posts: No. Paid links: No. SEO reviews: No.
- Example (hover to see tooltip):
- USAGE DEV / EDITOR
- If a dev or editor wants to change the template, empty
<i></i>
elements will create dot bullet points, font awesome i-elements will create icon bullet points. For font awesome be sure to use fa-fw for unified widths
- If a dev or editor wants to change the template, empty
- Relevant files
Archive_link (Template)[edit]
- Archive_link creates a custom absolute link with an auto-created link to web archive and multiple options. It structurally mimics the MediaWiki extension "Link to archive"
- Documentation for wiki editors: Dev/wiki#Links
- It is realized via the files
- Detailed Documentation
- Don't use the widget directly, only the template
- There is a widget and a template. ONLY use the template
- The template internally uses the widget Archive_link and uses styles from Archive_Link.css .
- It is designed to display an external link in different ways: (A) as link without any additions (B) as a link with small logo links behind it symbolizing alternative addresses (onion or archive)
- Parameters
- url | string, default: "" - the url you want to link to
- text | string, default: "" - the link text displayed in the main link
- archive | string, default: "auto" - if not "none" then there will be a logo link to an archive page of the given url. Options are (A) "auto" - where the archive link is auto-generated from the url (B) "copy" - where the link is exactly copied from the url (useful when url is already from web.archive.org) and (C) none - where no logo link is shown
- onion | string, default: "none" - if not "none" then there will be a logo link to an onion url. Options are (A) none - no logos is generated (B) "copy" - where the url is copied to the logo link (useful if url is already onion link) and (C) [onion-url] - a real onion url which is an alternative url to the main url. Note: If onion is an url or onion is "copy" then the link will have rel="nofollow" to prevent broken links for search engines. In the case of "copy" the main link will also get "nofollow" because it then is obviously an onion url too
- Don't use the widget directly, only the template
- NOTES
- target="_blank": As all links are external, the target attribute will be set to "_blank"
- Line breaks: There is a small tradeoff for having additional icons (archive, onion) at the end, namely that icons can break and be shown on the next line, separate from the main link. We tried fixing this by making the whole link white-space:nowrap. But then overlong links can occur which break our design. Only breaking the words in the main link but not breaking the connection of the last word to the additional icons was found to not work in multiple browsers. So we accept the tradeoff of having occasional line breaks before the icons.
Example Usage
{{Archive_link|text=Whonix Clearnet|url=https://www.whonix.org}}
Box and MBox[edit]
- These are 2 templates which are used to create special text boxes
- Template:Box is a container usually for text. Template:Mbox uses Box and integrates an image into it
- Box uses the design class "info box", see #info-box class
- Box has these parameters:
|text=
: text can have every text (including html)|addToClass
: addToClass can have every legitimate CSS class to style the class- Box can also have one anonymous parameter instead of text {{Box|text=Hello World}} has the same result as {{Box|Hello World}}
- MBox has the parameters like Box plus:
|image=
: using an image called via [[File:...]] - NOTE: We highly suggest using the link-parameter of File, because it is rarely sensible to use the link to the image file in this context|icon=
: instead of an icon a Fontawesome icon can be used. Here you only have to give the class names name "fa-solid fa-info" or extra classes that will be added to the<i>
element like our #Color schemes
- special class "ib-for-thumb" : This can and should be used for info-box elements (Box and MBox) that are next to the thumbnail. If these have the class "ib-for-thumb" then the info-box will not be very thin and unreadable for small devices but will be cleared and moved to its own line. Examples
{{mbox | image = [[File:Kicksecure-image-seal.svg|40px|alt=Test]] | icon = fa-solid fa-info cs-red-light | addToClass = ib-for-thumb | text = My Text here }}
In the above example icon and image are both used which is not very sensible. Mostly either image OR icon is used
{{box | addToClass = ib-for-thumb | text = My Text here }}
My Text here
ClearLine (Template)[edit]
- A simple template with no parameters
- If an area is floating (for example next to a thumbnail) and instead should be full size, add this template BEFORE the area that should not float
- USAGE: Simply add <span class="clearline-separator"></span> to the wikitext, before an area that should NOT float anymore
- Relevant files
CodeSelect[edit]
- CodeSelect creates a multiline text area or an inline text field to display code or technical information
- It has a button to copy all text to the clipboard
- Also all text will be marked if the user clicks into the text area
- Is NoJS (no-JavaScript) compatible. In NoJS mode the copying button is not shown but text is markable and copyable. In NoJS CodeSelect in icon mode (data-button-image-src) will completely be hidden.
- CodeSelect auto-highlights text which is in specific languages. Supported languages: bash, markup (includes html,xml,svg,mathml,ssml,atom,rss), shell session
- These are the files for CodeSelect
- USAGE, parameters :
- code (mandatory, wikitext) : This parameter can be text of all kinds. It can even be HTML (in HTML mode)
- Example :
{{CodeSelect|code=echo "Hello World"}}
renders to echo "Hello World"
- Example :
- inline (optional, boolean) : This parameter makes the CodeSelect box an inline element which flows with the text instead of a block which it usually is
- Example :
{{CodeSelect|code=echo "Hello World"|inline=true}}
renders to echo "Hello World"
- Example :
- breaklines (optional, boolean) : This parameter changes the way line breaks are handled. If true then lines will NOT be visually preserved like a in a pre-element (this would be normal CodeSelect behaviour), but will be broken if the width limit of the container element is reached. This mostly affects very long lines, which would then visually be broken. The copied content however is not affected, meaning there will be no line breaks there.
- Example :
{{CodeSelect|code=abcdefghijklmnopqrstuvwxyzabc...}}
renders to abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz - Example :
{{CodeSelect|breaklines=true|code=abcdefghijklmnopqrstuvwxyzabc...}}
renders to abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz
- Example :
- lang (optional, string, default: "bash") : When specified this parameter can select a specific language which should be highlighted in the CodeSelect box (for example: bash). A specific keyword is "none" meaning no highlighting will take place
- Example :
{{CodeSelect|code=echo "Hello World"|lang=none}}
renders to echo "Hello World"
- Example :
- buttonImage (optional, string) : We introduced a mode to now make CodeSelect a simple button to copy code or text to the clipboard. Use buttonImage and the code box changes to a simple button. Add the buttonImage-parameter specifying the image source url.
- Note: Don't use the
[[File:...]]
call, just a url, for example a relative url like/w/images/a/bc/def.jpg
- Note: The image gets an automatic hover effect (= -3% brightness), but all is controllable via CSS
- Note: buttonImage is usually loaded lazily, meaning the image has the attributes
decoding="async" loading="lazy"
. If you want to prevent this use the parameter buttonImageEager - Example :
{{CodeSelect|code=echo "Hello World"|buttonImage=/w/images/8/8c/Supermenu3.png}}
renders to echo "Hello World" - Note: buttonImage can also be used with an empty String or just as an empty attribute. In this case the usual copy icon will be shown.
- Example :
{{CodeSelect|code=echo "Hello World"|buttonImage=}}
renders to echo "Hello World"
- Example :
- Note: Don't use the
- buttonImageEager (optional, boolean) : Normally buttonImages are loaded lazily. Use this parameter to force eager loading (this omits the attributes
decoding="async" loading="lazy"
- Example :
{{CodeSelect|code=echo "Hello World"|buttonImage=/w/images/8/8c/Supermenu3.png|buttonImageEager=true}}
renders to echo "Hello World"
- Example :
- target (optional, string) : This parameter takes a selector of an element in the DOM (id, class, complex selector). If the element is found then CodeSelect will become a button to copy this elements content to clipboard. NOTE: Always be sure to select a specific target where the selector only finds 1 element. Otherwise the first element which is found will be chosen by the algorithm.
- Detailed functionality
- CodeSelect will be MOVED from its current location in the DOM BELOW the target and inside a helper DIV.
- CodeSelect will be in button form, which means it will get the attribute data-button-image-src, but with an empty string (except if this parameter is already specified then this will not be overridden).
- CodeSelect will be positioned via CSS over the target element on the top right side.
- HIGHLIGHT: Usually the code box of CodeSelect is syntax highlighted. With a target the target gets highlighted instead. This can be prevented by setting the "lang" parameter to "none". NOTE If the target gets highlighted the style of the target might change - for example a pre-element will look more like a code box
- Clicking CodeSelect will EITHER select the TEXT content of the target. This is only if the parameter code is NOT GIVEN. OR it will ALWAYS select the content of the code-parameter IF GIVEN. The latter option is optimal for the use case IF the target has some formatting going on and it may be not clear if all browsers will select the text correctly despite the formatting. In this case simply put the correct text into the CodeSelect code and give the element as target. The element's actual content will be ignored in this case.
- Clicking on the target element will mark all the text in the target element (but not copy automatically). This mimics the normal behavior of the CodeSelect code area
- NOTE: If the target-parameter is used the insertHtmlMode will be ignored (because it's always only text) and the inline parameter will be ignored (because it's positioned and not in the text flow).
- Example :
{{CodeSelect|target=#my-codeselect-target-example1}}
will render to see below
- Detailed functionality
- code (mandatory, wikitext) : This parameter can be text of all kinds. It can even be HTML (in HTML mode)
This is example 1 $ sudo apt "example1"
- DEVELOPER NOTES
- CodeSelect is realized as a jQuery extension. This is availabe after CodeSelect.js has been initialized (see build order in config-build-(shared and specific).json /tree/master/mediawiki-shared/build config-build-(shared and specific).json
- You can call $(selection).codeSelect(action) - with action currently only allowed as 'init'. This will initialized all CodeSelect boxes in the selection. Double initializations are prevented
- CodeSelect is semi-dependent on Prism-JS. For highlighting functionality CodeSelect depends on Prism, but CodeSelect can run without
- Currently the default is bash. If you want to change the default go to CodeSelect.js and change defaultLang at the top of the file
- The standard bash language definition by Prism was modified by us using the extension syntax
Prism.languages['bash'] = Prism.languages.extend('bash', { ... } );
. The ".extend" function creates a deep copy of the grammar and assigning it to "Prism.languages['your-language']" creates a new grammar, that will be used. We copied the grammar pattern for the "function" construct from the prism.js file and extended it by some other keywords, see CodeSelect.js for our application and https://prismjs.com/docs/Prism.languages.html#.extend for more information. If you just want to add more keywords go to CodeSelect.js to the linevar highlightBashAdditionalFunctionNames = [...]
at the top and add more function names to the array. NOTE: Be sure to NOT set the async (second) parameter to true when using the "highlightElement" function as it may cause errors due to a likely bug in the Prism software - For a download of newer version in the future go to https://prismjs.com/download.html and choose the languages we support (see above). Ask admin how to implement those files.
- insertHtmlMode : This gives the opportunity for Devs to insert structured HTML into the code box, not just text. This is useful if CodeSelect is used in another widget or for special demonstrations. To use it reconstruct the codeSelect widget and just add the class insert-html-mode. NOTE: This parameter sets the parameter lang to "none" because it does not work with highlighting
- Example.
<span class="code-select">More <b>Info</b> here</span>
More Info here vs<span class="code-select insert-mode-html">More <b>Info</b> here</span>
More Info here
- Example.
- custom scrollbars: For js users the codeSelect boxes are initialized with CustomScollbar
- feature class cs-no-custom-scrollbars: The initilization with custom scrollbars can be prevented by adding the class
cs-no-custom-scrollbars
to the code-select parent element. Then codeSelect will revert back to standard overflow behavior (but prone to content shift e. g. in Firefox)
- feature class cs-no-custom-scrollbars: The initilization with custom scrollbars can be prevented by adding the class
- CodeSelect is realized as a jQuery extension. This is availabe after CodeSelect.js has been initialized (see build order in config-build-(shared and specific).json /tree/master/mediawiki-shared/build config-build-(shared and specific).json
CollapsibleGlobalMods[edit]
- We needed to mofiy our
.mw-collapsible
elements globally. All settings are achieved in one script - Current settings
- Button labels
data-expandtext="Learn More"
anddata-collapsetext="Show Less"
- NOTE This settings does NOT override if these attributes were manually set
- Button labels
- Relevant files
Collapsible Template[edit]
- To use the mw-collapsible functionality can be a bit too verbose and unpractical having multiple nested elements, see https://www.mediawiki.org/wiki/Manual:Collapsible_elements
- Until new we were using this verbose syntax for most of our needs
<div class="mw-collapsible mw-collapsed"><div class="mw-collapsible-content">...</div></div>
- Therefore we introduced our own Template:Collapsible the have a short hand for this.
- This template is a little bit less feature rich than the verbose syntax, but it is therefore tighter and more practical
- The standard setting is collapsed (mw-collapsed) and standard colors of the TOC (toccolours)
- Parameters
- title | wikitext, mandatory : This text will be seen always, even if the content box is collapsed
- content | wikitext, mandatory : The hidden content that is only seen if the content box is expanded
- smallTitle | boolean, optional, default: false : If true then the title will not be shown in the style of a headline, but in the style of normal text
- addToClass | string, optional, default: "" : If set then the outer mw-collapsbile wrapper will get this parameter added to its class attribute
- Example {{Collapsible |title=My interesting title |smallTitle=true |addToClass=your-style-class |content=My interesting content }}
- Tests: Collapsible Template
- Relevant files
Community Support Template[edit]
- To clarify for users that a section or a whole page is not supported by Kicksecure developers there is the Template:Community_Support which renders an info box describing that either the page or the chapter are only supported by the Kicksecure community, not the developers.
- USAGE
{{Community_Support}}
- scope (page|chapter, default:page) : The parameter scope determines the scope of the message. scope=page (default) is red and more pronounces, scope=chapter is more suble
- See examples below
- Relevant files
CustomRepo (Template)[edit]
- In our documentation we often reference files in our mediawiki-customized-dist repository where the project files are located. This is a long link that always has to be looked up (problem 1). And also this link might change in the future, so this could be a replace-text-mess (problem 2). Therefore we introduced the CustomRepo template
- Parameters
- 1 (unnamed) | string : Just the filename. This will be set the link name AND to the last file part of the url. The subpath under the repo is set to "/blob/master/mediawiki-shared/src/shared/"
- alt | optional, string : Specifically set the subpath and link text SEPARATED by ONE space. All spaces after this are interpreted as link text. Parameter has to start with a slash "/" for the url subpath
- Syntax
{{CustomRepo|File.txt}}
{{CustomRepo|alt=/subpath-url Link text with optional spaces}}
- Tests, Examples
- Relevant files
CustomScrollbar[edit]
- This is a developer feature
- Sometimes it is needed to realized custom scollbars with javascript. For this we are using the library tinyscrollbar. Specifically for CodeSelect and WikitableAutoWrapper and ScrollableIndicator because we want to prevent content shift and guarantee best accessibility - for users to always know if an element is scrollable - specifically on Firefox and on mobile devices where the scrollbar gets hidden automatically. For a more detailled motivation read CSS: Replacing Hovering vanishing scrollbars in some cases
- USAGE
- To make use of it your element needs the following structure<span class="custom-scrollbar-container"> <span class="viewport"> <span class="overview"></span> </span> <span class="scrollbar"> <span class="track"> <span class="thumb"></span> </span> </span> </span>
- Your content needs to be placed in "overview"
- More classes can be added if needed
- There are also
globalSettings
in the CustomScrollbar.js file. These are applied to ALL instances of CustomScrollbar and are overridden only by individual settings - finally initialized like this mwDev.tools.addCustomScrollbar( $('.custom-scrollbar-container'), options );
- For more documentation read here: https://baijs.com/tinyscrollbar/
- Relevant files
Debug-via-url-modal[edit]
- This modal is a tool to conveniently generate URLs to debug the page for developers and also to be transparent about script use for page visitors
- The user can generate a link where scripts are activated and deactivated. You can de/activate selected scripts. But you can also deactivate all (custom) js or all (custom) css or all js and all css
- These are the relevant files
- Here you can see the modal
- (A) is the CodeSelect-Box where you can copy the generated link
- (B) is a button where you can directly open the generated link
- (C) is the navigation. Only if you choose "Select JS" you will see (D) the selection of all current scripts. Otherwise you will deactivate all js/css/js+css
- (D) If you choose "Select JS" you will see all loaded scripts. Click on them to toggle if they should be active or not. You will see that the CodeSelect box will be immediately updated with the new link. Also the button (B) will be immediately updated according to your selection
- The modal can be conveniently called like any other miniModal, see #Mini_Modal
- It's dom-id reference is #debug-via-url-modal
The modal also has a toggle button at the top now which de/actives the cookie nocache with the value true. Clicking this button again will delete the cookie again.
- The cookie communicates to the server that no server cache shall be sent but the fresh current version
DevTools[edit]
- In this library there are multiple functions which a dev can use as tools.
- They are saved to the global object mwDev.tool
- Relevant file: DevTools.js
fileRefsToLinks( selector, linkAttr, query )[edit]
- mwDev.tool.fileRefsToLinks(...) can be called in the console or every other js and css file
- It goes through a set of elements and its children, checks the textnodes and replaces texts of the nature /Media(W|w)iki:[^\.]+.(js|css)/ with actual links to the pages while keeping the rest of the text intact
- selector | jQueryCollection | default $("#mw-content-text *") : This is a jQueryCollection of DOM elements. Only selected elements will be transformed. That's a great way to for example just transform the elements inside one DIV by selecting the DIV descendants with an asterisk '*'
- linkAttr | object | default { target: '_blank' } : All key-value pairs will be transformed to HTML attribute strings and added to the file links
- query | object | default { action: 'edit' } : All key-value pairs will be transformed to URL query key-value pairs and added to the URL
DiscoverHiddenElements (Hash anchors)[edit]
- General overview
- Sometimes elements, that have ids and are meant as hash anchors, are hidden inside elements that hide content - namely Dev/mediawiki#Tab_Template_.2F_Tab_Content_Controller and mw-collapsible (MediaWiki system element). Hidden elements can be for example citations, the footnotes themselves, headlines and Dev/mediawiki#Anchor_-_manually_placed_anchors, basically all elements that are used as hash anchors. In normal behavior if a hash anchor is referenced by hash, then the page jumps / scrolls to this anchor. However if the anchor is hidden inside another element, there is no jumping / scrolling
- Discover Hidden Elements is a JS script that fixes this behavior for JS users
- For NoJS users this problem does not exist as these "partially hiding" elements are fully visible for NoJS users
- Functionality
- This script is controlled via hash. All headlines, manual anchors, citations (meaning both, citations to the reflist with "cite_note-..." ids and reverse citations from reflist to the reference with "cite_ref-..." ids) are registered with Dev/mediawiki#Hash_Controller
- If the hash changes to a hash for an anchor element that is hidden, then all parent elements are activated (all tabs inside tab controllers, all expands in mw-collapsibles) so that the "visibility route" to this hash anchor is activated.
- Then scrolling is activated and the page scrolls to this hash anchor element
- Tests and examples: Dev/wikitest#DiscoverHiddenElements
- Relevant files: DiscoverHiddenElements.js
Donation Panel[edit]
- The donation panel is an all-in-one payment tool for donations. It can be implemented in different pages. Usually it will be present in Donate
- The relevant files are
- Usage: It is implemented into a page lik so
{{Payments}}
using the Template:Payments which uses the following files automatically. These files need to be present for the donation panel to work: Template:Pay_Bitcoin, Template:Pay_bitcoin_qr_imgurl, Template:Pay_Monero, Template:Pay_monero_qr_imgurl, Template:Pay_Ethereum, Template:Pay_ethereum_qr_imgurl, Template:project_name_long, Template:project_name_short
DonorCard[edit]
- Kicksecure and Whonix survive on donations and services we provide. To thank our donors we opened the Donor recognition program. It is a voluntary opt-in program only if requested by the donors. For this page we need cards to appropriately thank our donors. Therefore the template DonorCard was developed.
- The template has 6 levels which are: xs, s, m, l, xl and dis (discreet donor with confidential amount)
- The cards are designed to be responsive meaning they will take as much space as given
- To see examples look here: Testpage_Donors
- Parameters
- name | string, mandatory : inserts the donor name or name of organization
- range | string, mandatory : there are 6 options:
xs
,s
,m
,l
,xl
anddis
. See how each options looks on Testpage_Donors - logo | string optional : is an image file name representing the donor which is implemented internally using the name parameter in the [[File:...]] Syntax
- link | string, optional : using link to a url changes the image to a link image. If link is used then a link indicator image is also inserted to let the user know that the image is clickable
- date | string, optional : simply outputs the date of the donation
- message | string, optional : outputs a message, usually a thank you message
- project | string, optional : Specifies the project that this donation is going to. Omit the project parameter then the card will show up on ALL project wikis. Specify a project by setting the parameter in lower case (e. g. whonix or kicksecure) then the card will show up only on the specified project. Set the parameter with wrong spelling (case sensitive) and the card will show up in no project wiki at all (so typos are easily visible).
- Syntax
- {{DonorCard |name=John Doe |range=xs |logo=Kicksecure-logo-icon.svg |link=Donors |date=2019-01-01 |message=Thank you very much |project=whonix }}
- Relevant files
Download Button[edit]
- The download button template offers a convinient way to show a graphically pleasing download button
- The relevant files are
- Usage call the Widget
{{#widget:Download_Button...}}
- Parameters
- text | string, mandatory - Visible text on the button
- url | string, mandatory - The complete url for the download button
- os | string/array, optional - Will show all the logos of the named operating systems. Options: linux, windows, osx, qubes, kvm, debian, virtualbox, usb. Multiple logos example: |os=linux|os=windows will generate an array
- icon | string (sig|sha|sigf), optional - changes the download icon at the very left of the button to one of 3 options: sig (stands for signature) will display this icon , sha (stands for sha512) will display this icon and sigf (stands for signify) will display this icon . The default is the download icon
- onion | string, optional - The url for the onion download. Will be generated as an extra HTML element behind download button
- addToClass | string, optional - Will be added to class attribute of wrapper
- fontsize | string, optional - If present will be added to style attribute of wrapper as style="font-size: {{{fontsize}}};"
- targetBlank | boolean, optional, default: false - If true will be filling the target attribute with "_blank"
- redirectUrl | string, optional - If set then after clicking Download and after 1 second the page will be redirected to the given URL
- modal | boolean, optional - If set to true, then the "pay-as-you-go-modal" will be opened. This modal has a donation appeal, a paypal, crypto and other payments module and the download is delayed for a couple of settings (can be set in Download_Button.js). This modal uses this special loading technique for parts of its HTML and data: Javascript: Ajax Loading for special cases
- NOTE: We tried using a template to track all usage of the Download_Button. Unfortunately this is technically very unfavorable for this use case. Read Widget:Download_Button for further information. To find the uses of Download_Button, type into search
#widget:Download_Button
EditorAddNewEditButtons[edit]
- The WikiEditor is already very capable, but sometimes more functionality is needed
- We added the ability to easily add buttons for more functionality.
- For this we use the official WikiEditor toolbar customization interface https://www.mediawiki.org/wiki/Extension:WikiEditor/Toolbar_customization
- New buttons can be set and customized in the settings section of EditorAddNewEditButtons.js
- For ease of use we limit the buttons
- to appear in the "format" group in the "main" section of the editor,
- to the type "button" and
- to the action type "encapsulate" (meaning: set a string before and another string after the current text selection)
- Currently there are 3 buttons set
- "nowiki code" which wraps the text selection in
<code><nowiki>$textSelection</nowiki></code>
- "code" which wraps the text selection in
<code>$textSelection</code>
- "CodeSelect" which wraps the text selection in
{{CodeSelect|code=$textSelection}}
- "nowiki code" which wraps the text selection in
- The relevant files are
EditorAutoBackup[edit]
- EditorAutoBackup is an in-wiki modification (augmentation) of the wikitext editor. It creates a green "saved icon" in the top right corner of the wikitext editor software toolbar. When clicked there will be the wikitext shown of the last edits of this file and other saved files
- Functionality is based on JavaScript and on the localStorage of the browser
- Every 15 seconds (is adjustable in settings) after you started typing something, there will be an auto-save IF the content has changed compared to the last save (if there is one). The saves are file specific and are ordered by dates.
- The saving is also triggered when the file is saved either by "Save changes" (the standard wiki save mechnism) or our "Save continue" mechanism.
- This save mechanismus is compatible with all 3 editors used on our wikis: ace editor (for js and css files and alike), codeMirror (syntax highlighted wiki editor) and the base wiki editor. It also keeps working when switching from wiki editor to codeMirror and back.
- The data is saved in localStorage, so NONE of this "draft" data is sent to any server whatsoever. As long as the browser doesn't delete the localStorage (be careful TorBrowser might do that when closing the browser) the saved text will be kept intact
- When "saved icon" is clicked the data is loaded from localStorage and rendered into our auto-save-display modal. This modal uses our Tab Template / Tab Content Controller to display the available saves for files in the first navigation and then for the selected file the available dates that the content was saved. The latest save for the current file is pre-selected
- For every file there is a maximum of 25 saves (is adjustable in settings) to not clutter the navigation too much. It is just a failsafe after all. And for all files there is a maximum of 100 saves (is adjustable in settings)
- Failsaves
- Failsafe for too much kilobytes being used (because localStorage is limited). If a file is larger than the maximum allowed bytesize (maxKbPerFile devided by maxDatesPerFile, currently 600 / 20 = 30KB, is adjustable in settings) than the "large file mode" is activated where the file gets less allowed "save slots" to accomodate for the larger file size. To compensate, the save interval changes from 15 seconds to 30 seconds (is adjustable in settings), so there is still enough "history" of a file left in case of a problem
- Failsafe for general problems with the saving process is also implemented
- In case of a problem all necessary information is written to the console and the green EditorAutoBackup icon is changed to red and a warning notice is shown in the modal when it's opened
- The process is also desgined to still work if the editor is switching between multiple windows and editing multiple documents at the same time
- The relevant files are
EditorFullscreen[edit]
- EditorFullscreen is an in-wiki modification (augmentation) of the wikitext editor. Instead of working in a small window the editor has the option to click on the green fullscreen icon on the upper right in the editing line of the editor and set the wikitext editor to fullscreen. If the wikitext editor is in fullscreen mode at the same position there will be the shrink item which restores the wikitext editor to its original windowed size
- Relevant files:
EditorMultiwikiNotice[edit]
- The EditorMultiwikiNotice is an addition to edit pages. The user on an edit page will be notified if he is on a Category:MultiWiki page.
- If this page is on the master wiki (currently the Kicksecure wiki). Then he will be warned to act with caution because these changes will affect all wikis.
- If the user is on a slave wiki he is discourages to edit on the page and go to the master wiki instead
- A link to the multi wiki info page and a direct link to the master edit page are also provided
- The links tor compatible, meaning: If the user uses and onion domain he will be redirected to the master wiki onion domains, if he uses clearnet the clearnet domain he will be redirected to the master wiki clearnet domain.
- See Dev/mediawiki#Multiwiki for more information
- Relevant files:
Editor SaveAndContinue[edit]
- Editor SaveAndContinue an in-wiki modification (augmentation) of the wikitext editor. It adds a new green button "Save continue" to the form which usually just has a "Save Changes" button. But the standard "Save Changes" button reloads the page and disrupts the workflow. The "Save continue" button saves the form via an AJAX request. After that it shows the resulting page for the editor (person) the check if the page really was successfully saved
- The relevant files are
EnhanceHeadlines[edit]
- The important headlines (h1,h2,h3) are enhanced to give the user a better usability experience
- The edit button is changed from a Text button to an optical button while retaining the original dom structure
- Also an automatic shareTooltip is added for each important headline, see #Share_Tooltip
- The Headlines
- EnhanceHeadlines can be prevented in 2 ways
- by adding the HTML attribute "data-preventEnhanceHeadlines" to an arbitrary HTML element on the page, e. g.
<div data-pageMeta-preventEnhanceHeadlines=""></div>
- the content of the attribute is not relevant it can be empty like<div data-pageMeta-preventEnhanceHeadlines></div>
. This attribute is just used as a meta control mechanism. If present NO headline on the page will be enhanced - or by adding the template Template:PreventEnhanceHeadlines like so
{{PreventEnhanceHeadlines}}
which renders to<div data-pageMeta-preventEnhanceHeadlines></div>
as explained in variant 1
- by adding the HTML attribute "data-preventEnhanceHeadlines" to an arbitrary HTML element on the page, e. g.
- The relevant files are
Expand (mw-collapse) alternative labels (Technique)[edit]
- The mw-collapse class is a wiki internal class to create collapsible elements for Javascript users
- It is also used by our template Collapsible Template
- The design of the toggle button is determined by our skin (Boilerplate.css)
- But the text content of the toggle button can also be changed. This is a MediaWiki function, so not really a module, but a technique. But it's not very well documented by MediaWiki, so it's mentioned here
- Usage : There are 2 attributes which can be added to the element which has mw-collapsible
- Add
data-expandtext
to change the text in the "Expand" case - Add
data-collapsetext
to change the text in the "Collapse" case - See examples here: Dev/wikitest#Expand_Button_different_labels
- Add
- Relevant files
Expand Or Collapse All[edit]
- The Expand Or Collapse All Button is a conveniance feature to deal with page where there are multiple expand/ collapse buttons
- This only applies to html elements with the class ".mw-collapsible-text", usually divs, and our template Collapsible Template. Those already have a toggle (expand / collapse) button for each one individually
- If the Expand Or Collapse All Button is clicked then all ".mw-collapsible-text" elements will be opened
- If all ".mw-collapsible-text" are already opened then the "Expand All" button will show "Collapse All" and if clicked all ".mw-collapsible-text" elements will be collapsed
- Relevant files
- Usage:
{{Expand_or_Collapse_All}}
FlyInNotification Module[edit]
- It is a delayed notification to show a user special information after a period of time of staying on a Kicksecure page.
- The widget is dismissable and sets a cookie named
flyInBannerIdDismissed
which is documented in our Cookie_Policy#Preferences. - Shown for JavaScript enabled browsers: Yes. Shown for NoScript users: No
- Note : A dismissable Fly-In-Notification which is also functional for no-JS (NoScript) enabled browsers is too much effort to implement. It would require a MediaWiki extension / PHP.
- Relevant files
- The widget is at the moment wiki wide enabled using Template:Footer.
- If this changes in the future and the devs want to implement it on a page by page basis, it can be implemented by simply adding the template
{{FlyInNotification|...}}
- In the current implementation the fly-in-notification can be disabled using
{{#css:/src-copy/Hide_all_banners.min.css}}
or generally (and usually) by using Template:Hide_all_banners, i.e. by using the usual wiki syntax to include a wiki template:{{hide_all_banners}}
- It is already disabled on some pages such as Donation related pages and legal related pages.
- Dev note: If you want to change this behaviour in the future read Hide_all_banners.css to learn how CSS works in tandem with JavaScript to hide the notification
- If this changes in the future and the devs want to implement it on a page by page basis, it can be implemented by simply adding the template
- NOTE: There is a dedicated Testpage for FlyInNotification, see TestpageForFlyInNotification, there you can also play with some settings which will only affect the page itself
- USAGE: See Template:Footer for the current implementation as an example
- There are options general options, that er set in the Javascript file. And there are parameters being set in Template:Footer
- General options
currentCookieId
: The id which is stored in the cookie. ThecurrentCookieId
will be compared to the id in the cookie, if it matches widget will not be shown. Suggestion: increment the id in integer steps if you want to show the user the next new notificationwaitInSeconds
: The time to wait until the notification pops up (is shown to the user)content
: HTML content which is defined as a structured string in the JavaScript file
- Parameters
headline
: The headline of the notificationimgSrc
: The url of the source for the imageimgWidth
: The width setting for the imageimgHeight
: The height setting for the imageimgLink
: A link url where clicking on the image should refer to. This link will also automatically be added to the headlinehtml
: HTMl for the body of the notification- Example : {{FlyInNotification |imgSrc=/your-image |imgLink=/wiki/Your_page |imgWidth=300 |imgHeight=215 |headline=Your headline |html=Your <b>bold</b> HTML }}
Gallery (MediaWiki)[edit]
- The gallery is a feature provided by MediaWiki, but we augmented it and would like to document here to have all our tools' documentation in one place
- The Wikipedia documentation for the gallery tag is best https://en.wikipedia.org/wiki/Help:Gallery_tag, the MediaWiki documentation adds some details https://www.mediawiki.org/wiki/Help:Images/en#Gallery_syntax
- USAGE
- The basic usage is adding image files with the
[[File:...]]
syntax without square brackets, see example 1 - These attributes can be added : widths, heights, class, caption, perrow, showfilename, mode, showthumbnails and any html attribute allowed on a
<ul>
tag (e.g. id, title, class) - see Wikipedia documentation for more info - Special class
class="thumb-gallery-style"
: This CSS is our individual class which should be added to use our optimized, screen-size-responsive gallery styling. See example 1 - Special class
class="gallery-white"
: This CSS is our individual class which sets the background color for every image to white. For a normal gallery this only applies to the image background (.thumb), for galleries with alsothumb-gallery-style
this applies to the whole box (text and image) - Justify classes: Normally a gallery is centered or left bound (according to mode). But we offer the classes
justify-left
,justify-center
andjustify-right
to justify the gallery accordingly. See example 1
- The basic usage is adding image files with the
- Tests: Gallery (MediaWiki)
Example 1
<gallery widths=300 heights=200 class="thumb-gallery-style justify-center"> File:Example.jpg|Lorem ipsum File:Example.jpg|Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut </gallery>
GoogleOff Template[edit]
- This template offers the option to hide content from search engines either completely or it just prevents them from using it as a snippet
- Relevant files
- USAGE : Parameters
- content (mandatory, wikitext) : The content you want to hide from the search engines
- {{GoogleOff|content=Wiki text content you want to hide from search engines}}
- nosnippet (optional, boolean) : Set to true if you want the content to be found but NOT used as a snippet
- {{GoogleOff|nosnippet=true|content=Wiki text content you want to be found but not used as snippets}}
- span (optional, boolean) : Set to true if you want the wrapper to be span instead of div. Needed sometimes in specific cases in wikitext.
- {{GoogleOff|span=true|content=Wiki text content you want to wrap in a span instead of div}}
- NOTE: The data-nosnippet attribute that prevents search engines from generating a snippet from the GoogleOff area is active for the wrapper element in all cases. But when using the nosnippet=1 parameter this is the only preventive measure and the area can still be crawled, yet not be used as a snippet.
- content (mandatory, wikitext) : The content you want to hide from the search engines
Hash Controller[edit]
- The Hash of the URL (e. g. in kicksecure.com#anchor1 the "anchor1" part) can be a powerful tool to control parts of the page. In its usual use case and for nojs users it makes the browser window jump to the desired location. With Javascript the hash can be used as any data point
- The hash controller is for developers and centralizes the hash behavior as sub category in Dev/mediawiki#DevTools.
- USAGE : The following functions are available
- get() : Simply get the current hash as a string. NOTE for Devs : You get the decoded string, meaning special chars are transformed back from their escaped url form to their special char self. Also note that this might be confusing because many browsers show these special chars in their special char form. But as only ascii is allowed in urls their are in reality escaped.
- set( hash : string ) : Simply set the current hash with a string (without '#')
- register( id : string, callback : function, requestInitialTrigger : boolean ) : Register a function for a specific id/hash. Meaning: If the URL has/gets this hash then this function will be executed. Triggers EVERY TIME the hash changes. If requestInitialTrigger is set to true then at load time of the page all registered functions will be executed. This execution will only happen ONCE - even if multiple functions set requestInitialTrigger to true.
- registerInitialCallback( initialCallback : function ) : Register a function which is ONLY ONCE executed after the initial trigger has called all registered hash (and empty-hash) callbacks once
- NOTE: Once the initial trigger event has been executed, all other
initialCallback
functions that are registered withregisterInitialCallback
will be immediately executed.
- NOTE: Once the initial trigger event has been executed, all other
- trigger( isInitialTrigger : boolean ) : Triggers
triggerRegisteredCallbacks
, the execution function for all has registered callback functions. TheisInitialTrigger
parameter is only needed internally for MwCombineJsWrapper.js. This initial execution will only be triggered if either in theregister
functionrequestInitialTrigger
is set to true at least once OR if at least one function is registered withregisterInitialCallback
- Relevant files
Headline (Template)[edit]
- There is no way in MediaWiki to create dynamic headlines via a Template. This however is needed sometimes. Usually headlines are written using wikitext and the "=" notation. But sometimes the content of the headline might be given to a template via a parameter, separate from the level of the headline for programming and usability reasons. This is the case in a special case of Template:Tab, see #Tab_Template_.2F_Tab_Content_Controller → "Headlines excluded from TOC" for more information
- Features
- Headline will not be listed in TOC
- auto-generated or manual id
- adding classes to class attribute
- HTML Structure like regular MediaWiki headlines, h[1-6] > span.mw-headline#[headline-id]
- USAGE : Call the template (not the widget) with these parameters
- content (mandatory, html) : The HTML content of the headline, simple text or more complex (full) HTML (not only wikitext html)
- h (optional, [1-6], default: 1) : The level of the headline as known from html. Only the numbers 1-6 are allowed
- id (optional, default: autogen from content) : The id is rendered to the html attribute "id".
- auto-generate : If no id is given then id is auto-generated from content (all non-word-characters are rendered to dashes "-")
- none : Only if id is set to the special keyword "none" then no id attribute will be rendered
- addToClass (optional) : Additions to the (optinal) class attribute for the headline
- Example : Code
{{Headline|h=2|content=Test Headline}}
→ RenderTest Headline
- Relevant files
- Template:Headline (Title in tab without adding to table of contents (TOC))
- Widget:Headline
HtmlComment Widget[edit]
- In MediaWiki templates it is basically impossible to use Html comments and have them rendered on the final page. This is intentional by Mediawiki to reduce unnecessary output. Sometimes however comments are needed
- Because of that we created the widget HtmlComment. This allows HTML comments in Templates
- Relevant files
- USAGE
{{#widget:HtmlComment|content=Your HTML comment content}}
- This will create a real HTML comment (which of course is only seen in source code)
- NOTE: You cannot use wikitext as content
Icon (Template)[edit]
- Sometimes it is necessary to use FontAwesome icons with a nice background and a fitting foreground color as an icon. This template is for this use case
- NOTE: For much more convenient but much more limited way of using icons see IconSet (Template) which is based on this template but uses presets
- Parameters
- 1 | mandatory, string : This is the class for the font awesome icon, e. g.
fa-solid fa-info cs-red
. You can use not only FontAwesome classes but also other styling classes like our Color schemes - style | optional, string : These styles are available: (1)
square
(default) - making the outer shape a square, (2)circle
- making the outer shape a circle, (3)rounded
- making the outer shape a rounded square - border | optional, string : If set then the icon gets a border which has the text color. If set to
true
, then it's a thin border. If set tothick
then it gets a thicker border. - shadow | optional, boolean : If set to
true
then the icon gets a drop shadow - text | optional, string : If set then this text is displayed instead of the icon.
- NOTE: If you use parameter
text
be sure NOT to use FontAwesome icon class (like fa-info) for parameter1
. Only style classes like fa-solid (Font Awesome 6, bold) / fa-regular (FA6, normal) or modifiers like fa-2x, fa-rotate-90 etc - NOTE: You do NOT need to use fa-solid or fa-regular (which uses FontAwesome font family). But if you do it will display only uppercase letters, no small letters
- NOTE: If you use parameter
- 1 | mandatory, string : This is the class for the font awesome icon, e. g.
- Example: {{Icon|fa-solid fa-info cs-red}} which renders to
- Complex Example: {{Icon|text=F12|border=true|style=rounded|fa-solid fa-2x fa-rotate-180 cs-white}} which renders to F12
- NOTE: You can also use all FontAwesome modifiers, e. g. like
fa-2x
to enlarge your icons - Tests: Icon (Template)
- Relevant files
Icon Bullet List[edit]
- The Icon Bullet List is like a bullet list with Fontawesome icons instead of bullet points
- Relevant files
- Usage : call #widget:Icon_Bullet_List. Parameters:
- item (mandatory, string) : This parameter is separated into two parts, separated by a comma ",". The first part is the content of the
<i class="fas..."></i>
class parameter for the Fontawesome image. The second part is the text for the bullet points. HTML elements like <b></b> are permitted. NOTE: Only the first comma is a separator, all following commas will not be interpreted and therefore can be used as normal text structuring elements - addClass (optional, string) : This parameter is added the the class-attribute of the <ul></ul> parent element for the list. You can use the specific keywords "minimal" and "inverse"
- minimal = list is as short as its content
- inverse = darker list + white bullet point) or other classes of your liking
- fontSize (optional, string) : determines the font-size of the list as a CSS expression like "13px" or "3em". The whole list sizes with the font-size, so it's looks very good in every fontSize
- span (optional, boolean) : If true then the whole list will be a span element with other direct children span elements as list items. The same styles apply to the list should look the same. This is for special cases, like it's use in Dev/mediawiki#Anti-Spam_email_tooltip
- item (mandatory, string) : This parameter is separated into two parts, separated by a comma ",". The first part is the content of the
- Example
{{#widget:Icon_Bullet_List |item=fa-solid fa-check,Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points |item=fa-solid fa-minus,Negative Points }}
- Resulting in
- Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points
- Negative Points
- Example using all parameters
- NOTE: div with white background just for demonstration purposes. Do not use in production.
<div style="background: white; padding: 10px 20px;"> {{#widget:Icon_Bullet_List|addClass=inverse minimal|fontSize=20px |item=fa-solid fa-star,Standard |item=fa-solid fa-check cs-green,Plus Points |item=fa-solid fa-times cs-red,Negative Points |item=fa-solid fa-minus cs-yellow,Equal Points |item=fa-solid fa-check cs-blue,Chill Points }} </div>
- Resulting in
- Standard
- Plus Points
- Negative Points
- Equal Points
- Chill Points
- NOTE: The colors of the bullet icons is using our color schemes which you can read about here #Color_schemes
IconSet (Template)[edit]
- This template provides the ability to easily use colored icons for numbers and letters
- It is based on Icon (Template), but is a much more convenient and also much more limited way of using icons.
- Usage : {{IconSet|h1|1}}
- Parameters
- 1 | string, mandatory : This is the preset which will be applied to the given text. For a list of the currently possible values, see the "presets" bullet point
- 2 | string, mandatory : This is the text that the icon will show. Works with letters and numbers. Has no length limitation, but looks less like an icon, the longer the text is
- Presets
- Text below is always "i", which (like all letters here) renders to uppercase
- i Style
h1
- i Style
h2
- i Style
h3
- i Style
h4
- i Style
true
- i Style
false
- i Style
keyboard
- NOTE: The font size will always be appropriate to the font of the wikitext element this is contained in. In a headline this icon will have "headline font size". In a paragraph this will have "paragraph font size"
- Tests / Examples: IconSet (Template)
Info Tooltip[edit]
- Info tooltip is a small element to show a tooltip only by using CSS (nojs compatible)
- Usage
- give and element the class 'info-tooltip'
- hide an element inside which will only be shown when user hovers over info button
- example
<span class="info-tooltip"><span>Here's the hidden info</span></span>
- result Here's the hidden info
- Relevant files Utility.css
Intro paragraph and IntroLike[edit]
- intro is a template to write multiple paragraphs for the styled intro of a page
- These paragraphs will be styled as if they were a single box
- This paragraph is needed for the Extension:Popups, also know as Previews, formerly known as Hovercards https://www.mediawiki.org/wiki/Extension:Popups because this extension uses the https://www.mediawiki.org/wiki/Extension:TextExtracts which needs some free unstyled paragraphs at the beginning of a page to generate a content preview (related Extension:TextExtracts feature request: Explicit Definition for TextExtracts Content)
- This template uses a sophisticated CSS styling to accomplish the intro look while keeping the text as plain paragraphs. This styling works about 95% in all browsers. Only in Firefox there's 5% design flaw because Firefox does not yet support the CSS :has-selector which is needed
- NOTE: This Template should ONLY be used ONCE PER PAGE. If this specific style is needed somewhere else use Template:IntroLike
- Relevant files
- USAGE
- Normal usage where the text is shown {{intro|Your intro text with wikitext and newlines}}
- hidden=true: Hidden usage where the text is not know. NOTE: The named parameter can be used everywhere as named parameters in Mediawiki do not affect the referencing of unnamed parameters. {{intro|hidden=true|Your intro text with wikitext and newlines}}
- thumb=[wiki-image-name]: thumb is optinal and gets a name from an image file that is uploaded to the wiki. The thumb will always be hidden not matter if intro is hidden or not. This is because thumb (specifically the thumb for Extension:Popups) is never intended for the user to see. If the page needs a thumb that the user can also see, then the author can insert a regular thumb as these will also work with Extension:Popups. {{intro|hidden=true|thumb=Kicksecure-icon-logo.png|Your intro text with wikitext and newlines}}
- introLike is a template to use if the style of intro paragraph is desired but it's not actually the function of a page intro
- Relevant files
- USAGE
- Call IntroLike and set the required text / wikitext as the first anonymous character
- Example: {{introLike| Your intro like text with '''wikitext''' and newlines }}
- NOTE : Be sure to use a newline after the pipe symbol and a newline before the closing double braces
LeftRightImageText[edit]
- A Template to show an image left and right a text or the other way round for decorative purposes
- Recommended to be used as template, but also available as a widget because as a template there are too many limitations, especially for the style-attribute.
- It is responsive. And once the screen is smaller than 500px the 2 parts will go width 100% and be below each other with a margin under the image
- Below 500px the image will ALWAYS be ABOVE the text, to keep a consistent look
- If the text is longer than the image or the image is longer than the text, the smaller one will always be in the middle
- Relevant files
- USAGE : Template
{{LeftRightImageText|...}}
. Parametersimage
: The image with should be shown next to the text. NOTE: For this parameter there is a difference between template and widget. In template you simply use the file name for image like "Information-275708-640.png". In the widget you have to use real relative link like "w/images/thumb/7/70/Information-275708-640.png/300px-Information-275708-640.png"imagelink
: If you want the image to function as a link give |imagelink=your-link-to-image and the image will behave as a link with hover effect. NOTE: For this parameter there is a difference between template and widget if it's an wiki internal link. In template you simply use the page name like "About". In the widget you have to use real relative link like "/wiki/About"text
: The wikitext (template) or html (widget) which should be shown next to the imageimageright
: If you want to image to be right, use the parameter |imageright=true then the image will be on the right and the text on the leftimageAlt
: If you want add an alt attribute to the image, use the parameter |imageAlt=Image text when loading errer then the alt attribute will be added and show if browser was unable to load imageaddToClass
: If you want to add classes to the parent element, use the parameter |addToClass=your-classes- class promo-style: One specific class for the parent element is "promo-style" which will turn all h3 and p elements to bigger stylized text areas
- Example template
{{LeftRightImageText |image=Information-275708-640.png |imagelink=/wiki/About |imageright=true |imageAlt=Symbol information |text= This is an interesting product. You might want to hear more about it. This is an interesting product. You might want to hear more about it. This is an interesting product. You might want to hear more about it. This is an interesting product. You might want to hear more about it. This is an interesting product. You might want to hear more about it. This is an interesting product. You might want to hear more about it. }}
- Example widget
{{#widget:LeftRightImageText |image=/w/images/thumb/7/70/Information-275708-640.png/300px-Information-275708-640.png |imagelink=/wiki/About |imageright=1 |imageAlt=Symbol information |text= This is an interesting product. You might want to hear more about it. This is an interesting product. You might want to hear more about it. This is an interesting product. You might want to hear more about it. This is an interesting product. You might want to hear more about it. This is an interesting product. You might want to hear more about it. This is an interesting product. You might want to hear more about it. }}
- Result for both
Mini Modal[edit]
- MiniModal is a modal as a quick way to create lightweight modals
- Relevant files are
- Usage: implement the modal with this minimal structure <div class="mini-modal" id="your-id-recommended-to-use"></div>
- init : MiniModal are lazily initialized when they are shown or hidden (see "show" and "hide"). You can also actively initialize them with $('#your-id-recommended-to-use').miniModal('init'); . A sub div will be created with the underlay and a close button. And the direct content under the .mini-modal div will be moved to the sub-div .content
- show / hide : You can programmatically (JavaScript) open the modal with $('#your-id-recommended-to-use').miniModal('show');
and close it with $('#your-id-recommended-to-use').miniModal('hide');
- Whenever a modal is opened ("show") the URL will be changed. If not specified otherwise (see "data-url-hash") the url will get a hash-symbol # without any text. This enables the browser to use the back-button to close ("hide") the modal. Whenever the modal is closed the hash-symbol will disappear - including the hash-text if there is any
- checkForModalsCalledByHash and data-url-hash : This method can be called on any element, because it's global anyways $(window).miniModal('checkForModalsCalledByHash'); - This will check if any modal has the attribute "data-url-hash" and if this attribute matches the current url-hash. Then this modal is shown. This attribute also forces the url to be changed if the modal is called using the hash sign # plus hash-text. If the attribute is not present the url is changed as described above (see "show/hide")
- Events: You can listen to the self-explanatory events $('#your-modal').on('shown.miniModal', fn ); and $('#your-modal').on('hidden.miniModal', fn );
[edit]
- Mininav: Mini navigation: Mini navigation is used to have multiple buttons in a row linking to other pages. The outer element must be a <div class="mininav"> the inner element must be a list of elements, for example of links. This will automatically be transformed to the navigation
- CSS special classes
- mn-dark CSS class : When this class is added the navigation will become darker. This is useful for light and white backgrounds where the mininav would otherwise not be seen very well
- mn-[2-4]-lines : Normally the mininav takes 1 line and reserves this space to prevent content shift. The class mn-2-lines added to mininav makes mininav take 2 lines as standard. The other 2 classes take 3 lines and 4 lines respectively. This only concerns the minimal space taken. If the mininav takes more vertical space on smaller devices this has no effect.
- Link icon
- If the link starts with an image, then this image will be used as an icon for the link, see example below
- NOTE 1: The link icon image has to have the Mediawiki parameter link set to empty string
|link=
. This prevents the file from becoming a file link and renders it to an img tag - NOTE 2: The image should have a size of at least 25px, because 25px x 25px is the box in which the image is fitted. A width of 50px is probably optimal
- General Notes
- pseudo bold selected link: To prevent inconsistent lengths in the navigation, bold font weight is NOT used to indicated an active or selected or hovered link. Instead a pseudo-bold font technique is used making use of the text-shadow CSS property
- Relevant files: Mininav.css
Example 1 :
<div class="mininav"> * [[About]] * [[Download]] * [[FAQ]] </div>
renders to :
Example 2 : <div class="mininav mn-dark"> * [[About]] * [[File:Tux.png|50px|link=]][[Linux]] * [[FAQ]] </div>
renders to :
Non-Responsive Thumbnails classes[edit]
- See #Responsive_Thumbnails for an explanation of the standard behavior
- Sometimes other behaviors are favorable however. And these are reached by wrapping the thumbs in span or div elements with specific classes like so <div class="thumb-not-responsive">[[File:my-thumb-image.jpg|thumb|]]</div>
- Relevant Files:
- Also see (related): #hide-enlarge_and_thumb-hide-enlarge_class
PayViaPaypal module[edit]
- To offer users to donate via PayPal we offer a form to do so
- The form is a fully functional PayPal form which combines subscription payment and one time payment by switching input elements (as defined in PayPal's API) according to the user's selection
- This module is based on JavaScript because PayPal also seems at the moment only fully usable with JavaScript activated
- Relevant files
- Usage: To integrate the form into a page simply use
<div class="pay-via-paypal-module">[nojs text]</div>
and write the text or markup for NoJS users in the div- This text will be replaced by the form via JavaScript if JavaScript is activated
- You can also use "smooth" in the class attribute. This makes the form grow smoothly when it's fully loaded instead of popping into position
<div class="pay-via-paypal-module smooth">[nojs text]</div>
- On any page there can be multiple forms which are each independent of each other
- Dev Sandbox mode: To use this module in sandbox mode, add the query ?paypalmode=sandbox
to the url (e.g. https://www.kicksecure.com/wiki/Donate?paypalmode=sandbox).
- In live mode the form action URL is
https://www.paypal.com/cgi-bin/webscr
. In Sandbox mode the form action URL ishttps://sandbox.paypal.com/cgi-bin/webscr
. - There is also a sandbox indicator showing when PayPal sandbox is activated. It shows the text "P!" on blue ground and on hover there is a full info text shown, much like with Dev/mediawiki#StageServerNotice
- In live mode the form action URL is
Pre : <pre>, <div class="pre"> and <pre data-code>[edit]
<pre>
and<div class="pre">
are two ways to show preformatted code. Both look very similar. The difference is: In pre tags mediawiki does not parse newlines, variables etc, in div.pre it does. So according to usage scenario either pre or div.pre are preferrable<pre data-code>
(the attribute is data-code, so it's valid HTML) is useful in many situations where admin would have to write<code>...</code>
. Formally it's just a little shorter, but it's way easier to write. And pre also escapes every content like nowiki does.- NOTE : One drawback is that before a pre-tag other elements are most of the time enclosed in p tags, so it's not 100% of a replica of code
- Relevant files
Example pre:
test pre
Example div.pre
Example code test code
Example pre[data-code]
test pre[data-code]
Quotation (Template)[edit]
- For Quotes without any context normal blockquote can be used
- Example Code <blockquote>An important quote from a developer</blockquote>
- Example
An important quote from a developer
- But if the editor wants to add an image, the author or other context, they would need to use Template:Quotation which is also "prettier" and more accentuated
- USAGE
- Use template Quotation with the following parameters
- quote (wikitext, required) : the quote content
- image (optional) : The name of the file as it would be on the file page without file: or image: prefix
- context (wikitext, optional) : the author and other context, including links, right to the (optional) image
- Use template Quotation with the following parameters
- Relevant Files
Example Code {{Quotation |quote=An important quote from a developer |image=Deep-web-1106648640.jpg |context=Name, Position, Link }}
Example
An important quote from a developer Name, Position, Link
ScrollAutoWrapper[edit]
- Motivation
- Overwide elements: Tables and other elements like pre-tags have a flexible width auto-adjusting to their content - this means it can have over 100% of the given width of the content column of the page. We call elements with this condition "overwide elements"
- To give the user a smooth experience these overwide elements should not surpass 100% width
- To solve this we created an auto-wrapper for all overwide elements.
- This solution is currently only auto-applied for
pre
-elements andtable
elements with the "wikitable" class (which is our standard class for styled tables)
- Functionality
- This wrapper is applied via Javascript and therefore does not work for nojs users
- The wrapper is also only applied if the element is determined to have overwidth.
- To counter false-positives (for example it already happened in one case due to late-loaded fonts) we use the setting
enrichTolerance
, which should stay above.99
(99 percent). This settings says "As long as the inner size is (e. g.) 99 percent or less of the outer size, no scroll wrapper will be applied"
- To counter false-positives (for example it already happened in one case due to late-loaded fonts) we use the setting
- The wrapper always stays 100% width. And if the element is too wide there will be an overflow bar
- This is also a prerequisite for other elements which ScrollAutoWrapper is applied to. They need to have something similar to
display: block; width: 100%, overflow: auto;
, so a scrollbar would naturally appear in case of overwidth without any Javascript
- This is also a prerequisite for other elements which ScrollAutoWrapper is applied to. They need to have something similar to
- Custom overflow scrollbar : In case of overwidth (element width more than 100% of content column) there are scrollbars at the bottom and occasionally at the top (see next point below for clarification) of the overwide element for more accessibility to indicate an overwide element (which to user would overlook if the element is very long and the bottom scrollbar would not be visible when the element comes into view). The top scollbar and the bottom scrollbar are linked and therefore always scroll simultaneously. This works for mobile AND desktop because we are using a custom scrollbar library "tinyscrollbar" to not take any chances of a lowered accessiblity due to Firefox's auto-disappearing scrollbars or mobile auto-disappearing scrollbars
- Conditional top scrollbar : Not always a top scrollbar is needed. It might in fact be detrimental to the clarity of overwide element if it's very short in height and therefore the bottom scrollbar is immediately visible. Then the top scrollbar would be very confusing. We therefore have introduced a setting
fullScreenHeightFraction
in the ScrollAutoWrapper.js file. This value should be ideally and logically between.3
and1.5
and is to be interpreted "Once an element is a fraction of the browser viewport height that is equal or greater than the fullScreenHeightFraction then a top scrollbar will be introduced, otherwise not". The value is currently set to.5
, which admin can adjust once more empirical values have been tested. - Hidden elements : Sometimes overwide elements are first hidden (for example when wrapped in mw-collapsible) and therefore have no dimension and are not yet overwide. In this case the normal method does not work and would produce wrappers with a height of 0 and would result in a faulty layout
- To fix this we use IntersectionObserver to check if and when the element becomes visible. Only then will the usual Javascript be executed. And the IntersectionObserver will be disconnected to save computing power
- We also check if IntersectionObserver is available (it's not in old browser) and for those rare cases where it's not we do not apply the Javascript with the WikitableAutoWrapper at all to have at least a readable fallback
- Special margins : Sometimes a table has special margins. The wrapper has to have those margins because the table gets 0 on all margins to preserve "margin joining" with surrounding elements which otherwise would lead to content shift. Therefore the wrapper automatically gets the computed styles from the table while the tables gets 0 for all margins
- Tests / Examples : ScrollAutoWrapper
- Relevant files
- NOTES
- This solution replaces the previous solutions
WikitableAutoWrapper
,scroll-table
andscroll-overflow-indicator
/ScrollableIndicator
- Scrollbar problem on Firefox
- Since version 100 Firefox per Default hides scrollbars when the element is not scrolling, see https://connect.mozilla.org/t5/discussions/scrollbars-disappear-in-firefox-100/td-p/5433
- This goes against our accessibility efforts to help users understand where information might be hidden in an overwide element
- We tried implementing non-native Javascript scrollbars, namely Overlayscollbars, Simplebar, Slimbar, Minibar, Tinyscollbar and more. Our needs are a horizontal scrollbar feature, linked scrollbars feature, good documentation, (somewhat) active development (not abandoned), ease of use and a small footprint (below 10kb). Our choice felll on tinyscrollbar
- This solution replaces the previous solutions
SearchModal[edit]
- The search is generalized as a modal. Once the user clicks on the search button in the header the modal opens
- Relevant files
- Depedencies
- SearchModal.js is dependent on MiniModal.js
- Header.js is dependent on MediaWiki:SearchModal.js
[edit]
- A tooltip menu for copying and sharing a url to various social media
- You can insert the template and optionally reference an anchor. The hover menu will offer the user different sharing options
- Nojs: These sharing tooltips will not be visible for nojs users
- JS active: The span element will be used as a wrapper and filled with a complex menu with sharing options for twitter, facebook etc
- Relevant files
- dev note
- ShareTooltip is realized as a jQuery extension. This is availabe after ShareTooltip.js has been initialized (see build order in config-build-(shared and specific).json /tree/master/mediawiki-shared/build config-build-(shared and specific).json
- You can call $(selection).shareTooltip(action) - with action currently only allowed as 'init'. This will initialized all ShareSelect elements in the selection. Double initializations are prevented
- Usage
- the data-anchor parameter anchor is optional, without it the sharing link is the whole page
- NOTE: if you use an anchor this anchor (or an element with this id="my-anchor-id") should exist somewhere on this page
- If the data-anchor parameter is set (only then) you can also use the data-chapter parameter which will explicitly set the title of the chapter for various sharing options. If not the title will be fetched from the target element (e. g. if it's a headline, then the text) or if this also fails then the anchor id will be transformed by replacing "_" with space
- the data-anchor parameter anchor is optional, without it the sharing link is the whole page
<span class="share-tooltip" data-anchor="my-anchor-id" data-chapter="My chapter title"></span>
Result
SiteNotice Info and Donation Banners[edit]
- The sitenotice is used to communicated current infos to the user. It is used in a very versatile way
- Relevant elements
- Sitenotice is excluded from search engine indexing via #Exclusion_of_text_parts_from_search_engine_indexing
- NoJS: For NoJS users there is no option to close the siteNotice
- Update info
- In the past there were more rules for sitenotice, but this has change due to the new solution. All rules are given below. Also some more files were important back then, not anymore.
- In the past we used MediaWiki:Sitenotice_id. However updating this ID came in conflict with the https://www.mediawiki.org/wiki/Extension:FlaggedRevs that we're using. That's why it has been replaced with Template:Sitenotice_id which serves the same purpose
- History of solution stack
- Previously we used the Extension:DismissableSiteNotice, but this is no longer the case. We have our own solution which enables the sitenotice to be dismissable
- The solution needed to be dismissable. Therefore Javascript was involved
- But if dismissed banners are closed by Javascript this is too late if the page is loaded because the page will "jump" and have a bad lighthouse content shift score. Therefore the page is hidden by user cookie which is set to the server on request and rendered as a body class which then hides the cookie immediately. This is done by Dev/mediawiki#Extension_CookieToBodyClass Extension:CookieToBodyClass which our SiteNotice solution therefore is dependent on
- If the user dismisses a banner he gets a cookie which is active 1 month and then auto-deletes which shows the banner again
- We also needed a way to make banners active and non-active. So we introduced a Template. This template in turn uses the widget because widgets can do some things in mediawiki that templates can't
- Then we also needed a possibility to not show a banner if it's expired. That is also implemented
- And we needed a way to force new banners upon the user - for example if there is an emergency but the user has dismissed the old banner less than a month ago. Therefore we used Sitenotice_id. If this id is changed then the user cookie will not longer hide the banner and he sees the new one which he might dismiss again
- USAGE
- You usually only touch MediaWiki:Sitenotice, Template:Sitenotice_id and occasionally Sitenotice.css. Everything else is maintained by core developers of this wiki
- CREATE BANNER : Open MediaWiki:Sitenotice and create a new instance of Template:SitenoticeBanner with these parameters
- html (mandatory) : The content of the banner. You can omit it, but the banner in most cases makes no sense without HTML to fill it
- active (optional, default: unset) : This is NECESSARY if you want to activate (show) a banner. If this parameter is omitted or false then the banner will not even be rendered. Use "|active=true" (or True or TRUE) to show the banner. To explicitely state that the banner is inactive you can also write "|active=false"
- href (optional) : If it's given then the html is rendered inside of an a-element with href-attribute as href
- expires (optional) : This is a UNIX timestamp in seconds. If the banner needs to end on a specific date and the creator does not want to check all of the time this happens automatically and the banner will not even be rendered after this date
- id (optional) : Gives the banner an id-attribute for styling. It is recommended to add the individual styles of a banner to Sitenotice.css or LocalSkin.css /blob/master/mediawiki-shared/src/kicksecure/LocalSkin.css LocalSkin.css
- Banner visibility is global. If the user has dismissed your banner ALL of your banners will be invisible for one month. If you want to reset the banner visibility go to Template:Sitenotice_id and change the ID to a new string. Then whichever current banner (seen or not seen) will be visible again for ALL users
- Example code {{SitenoticeBanner |active=true |html=<img class="full-size" decoding="async" loading="lazy" src="/w/images/7/7d/Banner-dev-wanted-slim.jpg" width="960" height="140" alt="Developer wanted for Kicksecure ISO development"> |href=/wiki/Contribute |expires=16776808891 |id=my-banner-id }}
- Additional JS functionality: If you need special functionality for some banners put them in Sitenotice.js under "B : Custom Banners Functionality"
- Deactivate all banners: If you want to deactivate all banners (including the flyinnotification) just put this template somewhere on the page Template:Hide_all_banners
SiteNotice End Of Year Banner[edit]
- The SiteNotice End Of Year Banner is a complex banner for the donation drive at the end of the year
- The banner fulfills several requirements: (1) Responsive mobile / desktop (2) Predictable height to prevent content jumping (3) Content as a slideshow (4) Payment gadget always present or one click away (5) Dismissable (by cookie for 1 week) (6) Portable, so it can be loaded on other pages, in this case the forums (7) Customizable so there can be different content on different pages (i. e. Whonix and Kicksecure)
- Relevant files:
- The main Javascript file is Sitenotice_EndOfYear.js. There it provides a function initEndOfYearSitenotice( endOfYearDiv, contentForSlides, donatePageUrl = '/wiki/Donate', isLocalFileSystem = false ) that IS NOT directly executed.
- endOfYearDiv needs to be a jquery dom element or a valid CSS selector. It's the element where this whole banner gadget will be prepended (added to the front)
- contentForSlides needs to be an HTML-String which will then be added to the banner.
- Every slide (direct child) should be a div element to contain your slide content. This is individual content fitting the current wiki.
- Crypto: You will have to have an element in your string (e. g. div) which (1) has the attribute data-crypto-addresses (2) is a JSON string (3) and has the keys "payBitcoin", "payMonero" and "payEthereum" with the right addresses as string-values.
- Title: If you add an h1-element (also a child, use of HTML inside the h1 is allowed) then this will be used as the title of the end of year sitenotice being displayed at the top. If you don't use an h1-element here then there will be a generic title
- donatePageUrl, e. g. "https://www.whonix.org/wiki/Donate", is the URL where the donate button or "More payment options" button lead the user.
- isLocalFileSystem (boolean) indicated if this function is run locally for example on the Kicksecure local browser page. If true then localStorage will be used by Javascript to save when the user dismissed the donation banner
- In Sitenotice_EndOfYear.css the styles are defined.
- In Sitenotice_EndOfYear_LocalWiki.js (deprecated) /blob/master/mediawiki-shared/src/kicksecure/Sitenotice_EndOfYear_LocalWiki.js Sitenotice_EndOfYear_LocalWiki.js (deprecated) the function initEndOfYearSitenotice(...) is called. This must be done for each wiki individually. This is also usually where the content is stored.
- When clicking dismiss a data entry into "localStorage" is written with the current date plus 7 days. Before that time the banner will not be shown again. After that time, the banner will be shown again and the data entry will be deleted
- History: This functionality was originally using Ajax Calls to get the content. But this was too slow, so all content is stored in Sitenotice_EndOfYear_LocalWiki.js (deprecated) /blob/master/mediawiki-shared/src/kicksecure/Sitenotice_EndOfYear_LocalWiki.js Sitenotice_EndOfYear_LocalWiki.js (deprecated) now
- For more information how our banners work read #SiteNotice_Info_and_Donation_Banners. The end of year banner uses the expiration functionality and dismiss functionality from sitenotice.
- NOTE: If this banner is not in use please deactivate the three files Sitenotice_EndOfYear.js, Sitenotice_EndOfYear.css, Sitenotice_EndOfYear_LocalWiki.js (deprecated) /blob/master/mediawiki-shared/src/kicksecure/Sitenotice_EndOfYear_LocalWiki.js Sitenotice_EndOfYear_LocalWiki.js (deprecated) in config-build-(shared and specific).json /tree/master/mediawiki-shared/build config-build-(shared and specific).json by commenting them our using "//" as described in the Build file itself. Then run
mw-combine.php
. Deactivating these files saves bandwidth for the user.
feature slider - Splide homepage sliders[edit]
- We are using https://splidejs.com/ to create sliders on the homepages of our wikis
- This script seems very mature, we're using the standard theme
- It is implemented via Dev/mediawiki#Extension_HeadScript
- This script only works on the homepages, so pages with routes starting with
/wiki/Homepage
(or just /) or /w/index.php?title=Homepage
- Relevant files
- Our script only works on homepages because it checks whether the splide script is loaded
- USAGE
- The script checks all instances of
.mw-collapsible
which does also have the classslider-list-if-js
- All cards are cloned into the slides list, there they are styled and integrated in the slider automatically
- Structure : Be aware that this only works on the homepages and there's a specific structure needed
- All slide "templates" (the original cards) have to be an a-element with
href
attribute and they need to have the class.card-wrapper
- Exactly below card-wrapper there needs to be
.image-wrapper
with an img image inside - Also below card-wrapper there needs to be a
p
-element where the text content is stored - Also below there can be optionally a headline
h2,h3,h4,h5
which is where the headline text is extracted from
- All slide "templates" (the original cards) have to be an a-element with
- The script checks all instances of
feature slider - deprecated upstream[edit]
Deprecated upstream? Problem?
- https://github.com/Splidejs/splide last commit is from last year. Upstream dev does not reply to issues, ignores pull requests.
- https://github.com/Splidejs/splide/pull/1303 are wondering about deprecation. Upstream dev does not reply either.
- Therefore seems abandoned.
- However the last state of the library is well established, so it can be considered a "running system" that does not need further improvement for a long time
- Dev also checked the used Javascript core functions in the library and does not see any remote security critical functions. So updates from a security or privacy standpoint do not seem necessary
- Although not maintained at the moment Dev sees no problem in just keeping the library. It is stable, functional and does not seem to present any security or privacy risk
StageServerNotice[edit]
- If the wiki server is a stage server (all wikis have a stage server to test updates an upgrades before they go live)
- In order for admins to easily see it's a stage server, there in an indicator added automatically via a Javascript script
- This script checks whether a meta tag
<meta name="server-type-stage">
is present. If so the indicator is automatically added just left below the header - Relevant files
Subdomain_link[edit]
- This template creates a context based link to a subdomain of the wiki project. Works only for the official wiki clearnet and onion domains.
- Problem: normally it is optimal to use relative links. This is not possible for subdomains here. But to redirect with an absolute link to a subdomain poses the problem if there are multiple domains for the same website like with whonix where there is also an .onion domain
- This template solves the problem by automatically analysing the context (which domain the user is on) and creating the link automatically based on the context
- Relevant files
- Template:Subdomain_link - only this template should be used by editors
- Widget:Subdomain_link - this widget should only be edited by devs
- USAGE : Use template
{{Subdomain_link|...}}
with the following parameterstext | string, default: ""
: the text you want to display in your link. The effect of this parameter is influenced by the parameter result. If not|result=link
then this parameter text is obsoletesub | string, default: ""
: the subdomain without any special character. If you want forums.kicksecure.com, use "forums"append | string, default: ""
: an addition to the link after the domain. Always start with slash "/". Example: "/thread/12387" → "kicksecure.com/thread/12387"result | string, standard: "link"
: determines what the widget returns. Options (A) link - then an a-hyperlink will be created (B) url - then only the final url will be created (C) parts - then a string will be created. First part protocol "http", then comma, then "domain", example: "https,kicksecure.com"
Tab Template / Tab Content Controller[edit]
- A tab controller to conveniently show content as tabbed content areas
- Uses #Mini_Navigation as an auto-generated navbar
- Features
- For nojs visitors the content is plainly and fully shown without any navigation
- Url Hash Feature : For Js users all tabs are rendered as links, so if you right-click a tab it will give you the option to "copy link url". This URL has a hash and if this URL is called then this tab will be opened upon calling. This includes the tabs which are above it (if you have nested tab controllers). So for nojs users this link will jump straight to the headline
- Linked controllers : Link multiple controllers so they switch in unison
- Definitions
- Tab : A button in a same-page navigation where only a part of the page is changed
- Section : The content which is shown when a tab is clicked
- Controller : The controller functions as the container / parent / anchor point for the sections and also a parent for the navigation which is generated
- USAGE
- There are two template components which are needed: the controller and the section. Both are created by using the same multi-purpose template Template:Tab
- Parameters are different for controller and section
- Parameters for Controller and Section
- type (mandatory, for "controller") : This can be "controller", "section" or nothing. If controller is chosen a controller-component is created. Side note:
|type=controller
is rather long for a switch. But it was done this way so every new editor clearly sees if this is a controller. If section or nothing is chosen then a section-component is created. - addToClass (optional) : The content of this parameter will be added to the class attribute of the controller or the tab that is created
- lines (optional, 2-4) : This parameter accepts the numbers 2-4 and writes the respective classes mn-[2-4]-lines to the mininav. See Dev/mediawiki#Mini_Navigation
- type (mandatory, for "controller") : This can be "controller", "section" or nothing. If controller is chosen a controller-component is created. Side note:
- Parameters for Section
- title (mandatory) : This title needs to be gives as a wikitext headline. This headline should integrate in the normal flow and hierarchy of the whole page because for nojs users this is all that they will see.
- content (mandatory) : This parameter is where you put all the real wikitext content that is shown when tab is active but hidden when inactive. And always shown for nojs users
- link-tabs : This is an alternative to having content in a tab. If a single link is given as content (as external link, complex external link [https://mediawiki.org MediaWiki] or internal link [[Wikipage]]) then the nav point in the navbar will become an external / internal link instead of (standard:) a button to show the content. NOTE : For no-js users the content will be rendered as headline + the link as given.
- active (optional, only "true") : active can only be set to true. This means that the corresponding tab to the section with
|active=true
will be pre-selected. If this parameter is not set NO tab will be selected and NO content will be shown. This is required for some situations.- NOTE : Please avoid settings multiple sections to active, that would be a syntax error
- image (optional) : Here an image in wikitext form is given
[[File:my-image.png|alt=My image alt text|50px]]
to have an image which will be shown on the left of the tab before the tab title in the navbar.- NOTE : Be sure to use a small image of max. 60 x 60 pixel.
- NOTE : Always use alt-parameter, because image will be wrapped in a link element. This way your prevent Pagespeed / Lighthouse error "Image elements do not have [alt] attributes"
- Parameters for Controller
- content (mandatory) : For the controller content is different from section. The controller may ONLY have multiple sections - meaning instances of Template:Tab in the section variant - as children
- linkid (optional) : This is an internal id to link multiple controllers. This is needed if multiple controllers need to switch in unison. If two or more controllers have this parameter with the same content they will be linked, meaning: All tabs being clicked in one of the navigations will switch the tabs in the other navigations as well. This is synchronized by the number of the tab. Example: You click tab 1 in controller 1 then section 1 in controller 1 is shown AND then tab 1 in controller 2 is also shown as well as section 1 in controller 2.
- NOTE - different numbers: If there is not the same number of sections in both controllers they will only be synchronized as far as numbers are equal. If you click tab 6 and the other controller only has 3 tabs then the controller with 3 tabs remains unchanged
- NOTE - link-tabs: If a tab is a link tab then clicking it will not change the other controller
- Code Examples
- create the controller using Tab template with type controller and content {{Tab|type=controller|content=...}}
- Create a sections by using Tab template with title and content {{Tab|title= ==section1==|content=Section 1 content}}
- Further features
- .tcc-indent CSS class : Special CSS class that needs to be added to a controller via
"|addToClass=tcc-indent"
to take effect. Every tab content controller with this class will have a white border on the left to indent the content. This is especially useful if tab-content-controllers are nested inside each other and the user still needs to realise the different levels - .tcc-dark CSS class: Special CSS class that needs to be added to a controller via
"|addToClass=tcc-dark"
to take effect. The mininav sub element will automatically get the class "mn-dark" as described here: #Mini_Navigation. The mininav will also get gray borders instead of white ones when using the .tcc-indent class - Linked to URL hash
- Setting hash via controllers : Tab controllers are linked to url hash. As the tabs are basically generated from headlines, clicking on them changes the URL hash like navigating to a headline via TOC would do
- Setting controllers via hash : The other way around is also true. If you call a page with a URL hash that matches the controller tab ID then this tab will be opened when the page is loaded. Also the page will scroll to the correct position
- NOTE : nested controllers : This also works recursively with nested controllers. If a nested controller is chosen via hash then all parent controllers are opened too
- Controllable via TOC : Clicking on the TOC changes the URL and adds a hash. If this hash corresponds to a tab controller tab then this tab will be opened and scrolled to
- Headlines excluded from TOC : Compatible with #Headline_.28Widget.29 which means that those headlines can be used instead for the title parameter to create headlines excluded from TOC. Use
|title={{Headline...}}
. See Dev/wikitest#Nested_Tab_Test_:_No_TOC for examples
- .tcc-indent CSS class : Special CSS class that needs to be added to a controller via
- JavaScript functions
- init : This function is usually automatically called for all elements with the "tab-content-controller" class. But it can be individually called (maybe needed if a tab content controller is constructed later) with $('.my-controller-class').tabContentController('init');
- select : With this function an element with the classes tcc-tab or tcc-section can be referenced an then select will both select the section and the corresponding tab WITHOUT changing the hash of the page (which happens when you click a tab). Code $('.my-section-or-tab-class').tabContentController('select');
- Relevant files
- Full example
{{Tab|type=controller|content= {{Tab|title= ===section1===|content=Section 1 content}} {{Tab|title= ===section2===|content=Section 2 content}}
- Full Feature Example
{{Tab |type=controller |addToClass=tcc-indent tcc-dark |linkid=link1 |content= {{Tab |title= ==Section 1== |type=section |image=[[File:Logo-linux-500x500.png|25px]] |addToClass=info-box |active=true |content=Section 1 content }} {{Tab |title= ==Section 2== |content=Section 2 content }} }} <!-- end of tab controller 1 --> {{Tab |type=controller |linkid=link1 |content= {{Tab |title= ==Section 3== |active=true |content=Section 3 content }} {{Tab |title= ==Section 4== |content=Section 4 content }} {{Tab |title= ==Section 5 Link== |content=[[Donate]] }} }} <!-- end of tab controller 2 -->
ThumbGallery[edit]
- It is practical to use thumbnails with the
[[File:...|thumb]]
construction for a gallery - limited with and height, description etc - Sometimes also thumbs need to be shown as a gallery on mobile devices. This is the case if there are multiple thumbnails in a row that act as some kind of collective thumbnail for the page
- For both cases we use the streamlined ThumbGallery template
- PARAMETERS
- 1 (first unnamed) | wikitext, mandatory: The content of the gallery. Exclusively thumbnails with the
[[File:...|thumb]]
construction - justify | string, optional, default:center : Allows for
left
,center
orright
. Aligns whole gallery in this direction - mode | string, optional : Currently only
gallery
is available as mode. Turns the thumbnail collection into a gallery at ALL sizes. Normally only on smaller mobile devices it is rendered as a gallery
- 1 (first unnamed) | wikitext, mandatory: The content of the gallery. Exclusively thumbnails with the
- USAGE
- This can be easily achieved using the Template ThumbGallery. Simply wrap you thumbs into the template and below 540px display width these thumbnails will become a gallery
- Example {{ThumbGallery|justify=left|mode=gallery| [[File:Kicksecure-basic-logo.png|thumb|100px|[[Dev/Logo|Kicksecure logo]]]] [[File:Debian.png|thumb|100px|Debian logo]] [[File:Linuxkerneltux.png|thumb|100px|Linux logo]] }}
- Tests : ThumbGallery (Template)
- Relevant Files
TOC Level Switcher[edit]
Figure: Table of Contents Level Switcher
- There is a lot of content on this wiki and there are many headlines on one page. So the table of contents (toc) is sometimes very overwhelming. To improve this experience for the user we created a JavaScript augmentation for the TOC
- 3 Buttons are added right of the TOC where you can use the star and show all levels (standard) or click "2" to just show the top 2 levels or click "1" to just show the top level. You can open the levels by using the plus button. And you can see how many children one level has by the number in the brackets on the right. Levels with 0 children will have no plus button to open them
- The TOC is not shown at all if there is no level 2 headlines, because then the TOC could do nothing. If there is no level 3 headlines then the "Show level 2" button is not shown for the same reason
- TOC level switcher saves your choice to a cookie. But only if you make a choice that is not "all" (wiki default, asterisk symbol)
- So if you're someone who always likes to just get the top headlines this will help improve your experience across all pages.
- If you want to delete your choice and the whole data point completely from cookie just click the asterisk icon and the cookie will be wiped completely
- Relevant files
- NOTE: This feature is dependent on the #Extension_CookieToBodyClass
VideoLink (Template)[edit]
- To have a convenient way to show videos we introduced VideoLink
- Relevant files
- USAGE : Only use the template
{{VideoLink|...}}
- videoid: The videoid parameter is valid for all YouTube-link platforms. For each platform there is an icon generated as a link where the videoid is part of the url.
- text: This is the text that will be shown to the user. The text will be also rendered as a link with YouTube as its target
- style: For this parameter currently only the setting "subtle" is available which is another style variant. See Rendered examples
- Syntax Example : {{VideoLink|videoid=6nHufztdkUI|style=subtle|text=Test video}}
- Rendered examples : Wiki test VideoLink
- For Devs
- To introduce new platforms simply copy a link code line in Template:VideoLink and modify the image, the alt description and url
USAGE : CSS Design Documentation (Alphabetical order)[edit]
Col Container[edit]
- The class .col-container is a functional wrapper to have elements equal items in a horizontal list
- The class .cc-3 (only works in combination with .col-container) defines a horizontal list with 3 columns
- The used CSS technique is display:flex;
- Defined in Utility.css
Color schemes[edit]
- The following color schemes are available for usage in different contexts to your liking. The i-icon represents the font color, the border has the font color
cs-red |
cs-red-light |
cs-red-font
| |
cs-green |
cs-green-light |
cs-green-dark |
cs-green-font
|
cs-blue |
cs-blue-light |
cs-blue-dark |
cs-blue-font
|
cs-yellow |
cs-yellow-light |
cs-yellow-font
| |
cs-gray |
cs-gray-light |
cs-gray-dark |
cs-gray-font
|
cs-white
|
- Usage: Simply add one of these classes to a class-attribute in an html element of your choice
- They affect background-color and color
- They are defined in Boilerplate.css
Columns: use-2-columns, use-3-columns[edit]
- These classes can be used on any element, which has display:block or something similar. The content of the element will be automatically grouped in 2 or 3 columns, separated by lines between them.
- Note that under a certain page with the class will produce only 2 columns or 1 column to be responsive for mobile devices
- additional class "strict-list-columns" : If the parent element with the class "use-2-columns" or "use-3-columns" also gets the class "strict-list-columns" then lists ul/ol will be kept together in 1 column. This can be broken by inserting
<div></div>
into a list to break it cleanly into two and let those 2 lists be in different columns - sub class "keep-together" : This class can only be effectively used under the "use-2-columns" or "use-3-columns" class. Usually without "keep-together" the 3 columns will be automatically reorganized to occupy as little vertical space as possible. Thereby it will separate line which is sometimes not desirable. To keep lines together wrap them in a span with class "keep together". Example
<div class="use-3-columns"> <ul> <li>List element 1</li> <li><span class="keep-together">List element 2</span></li> </ul> </div>
Example 2 in a Template with "strict-list-columns"
<div class="use-3-columns strict-list-columns"> * List element 1 * List element 2 <div></div> * List element 3 * List element 4 </ul> </div>
Expand (mw-collapsible) paragraph as label[edit]
- For collapsible areas (div.mw-collapsible or our Collapsible Template) there is a section where the label is defined which is show next to the expand button
- This label often is an h4, h3 or other headline element
- To prevent headline disorder error for Lighthouse "Heading elements are not in sequentially - descending order" you can use a p-element instead
- The p-element will be styled the same as a headline but will cause no Lighthouse errors
- To prevent this p-element being styles as a headline add the class
mwc-headline-normal-text-size
. Here's a full example <div class="mw-collapsible mw-collapsed mwc-headline-normal-text-size"> Your headline / description looking like normal text <div class="mw-collapsible-content"> Your usual main content </div> </div>
- To prevent this p-element being styles as a headline add the class
- Relevant files
General utility style classes[edit]
Special classes are generic classes that are applicable to various html elements. Relevant file mostly Utility.css
- class "width-100" : an element gets the style width:100%
- class "text-align-center" : an element gets the style text-align:center
- class "vertical-align-middle" : an element gets the style vertical-align:middle
- class "margin-left-5" (margin-right/top/bottom-0/5/10/20) : adds margin 0, 5, 10 or 20 px in any direction to an element
- class "vspacer-10" (-0/1/2/3/4/5/10/20/30/50) : block element with no float and 100% width and the given height to make a vertical gap (vspacer = vertical spacer)
- class "pos-1px-up" (pos-1px/2px/3px-up/down) : positions the element relative and moves it up or down 1, 2 or 3 pixels
- class "fontsize19" (19/21) : Gives the element font-size: 19px
hide-enlarge and thumb-hide-enlarge class[edit]
- A thumb image will usually have an enlarge Button to show the images in full. This is sometimes not desirable. But thumb is sometimes the only useful image option (see #Images, Files and usage of thumb). Therefore thumb can be augmented with one of 2 classes hide-enlarge and thumb-hide-enlarge.
- thumb-hide-enlarge is the general purpose solution for all thumbnails. Simple wrap a division with the class "thumb-hide-enlarge" around the thumbnail
- example:
<div class="thumb-hide-enlarge">[[File:Swift 128.png|thumb|100px|link=|SWIFT]]</div>
- The enlarge button will be hidden. And the image description text will be centered
- example:
- The second option is a shortcut but only works on thumbnails without the link parameter. You can add the class parameter with the value hide-enlarge to the File-tag
- example:
[[File:Swift 128.png|thumb|100px|link=|class=hide-enlarge|SWIFT]]
- The effect is the same as with the wrapper
- example:
info-box class[edit]
- used for container elements to give them rounded borders, a white background and a shadow
- it is used in the Template Box, see: #Box_and_MBox
- There is a special class "ib-for-thumb". Read about it in #Box_and_MBox
intro-p Intro Paragraph class [DEPRECATED][edit]
- DEPRECATED FOR HTML USE.
- In the past it was used for an intro paragraph at the box of the page, but can also be used elsewhere to highlight text
- Allowed secondary usage in the past: <div class="intro-p">Here is your intro-text</div>
- Now you should always use the template #Intro_paragraph
NoJS classes[edit]
- The site is generally NoJS compatible. However for JavaScript (JS) users we offer some JS features to make the visit more comfortable.
- The JS enhanced elements work without JS, but with JS they have full functionality.
- IMPLEMENTATION: For no-JS users we have special styles which are only applied if the user has JS deactivated
- These styles make use of the Mediawiki classes "client-nojs" and "client-js" in the
<html>
top element. These classes are not added via Javascript but on the server-side which prevents content shift and makes it a very good solution - In Utility.css there are also some style for NoJS
- These styles make use of the Mediawiki classes "client-nojs" and "client-js" in the
- USAGE
- We introduced new classes to show content specifically for NoJS or JS users. These classes are
- .show-for-nojs-only: show content only if the user has no JS activated
- .show-for-js-only: show content only if the user has JS activated
- .hide-for-nojs-only: hide content only if the user has no JS activated
- .hide-for-js-only: hide content only if the user has JS activated
- Example:
<div class="show-for-nojs-only">Text is only show when JS is not active</div>
- On the CSS side you can use
html.client-nojs .your-element {...}
to style it for nojs users orhtml.client-js .your-element {...}
to style it for js users
- We introduced new classes to show content specifically for NoJS or JS users. These classes are
"NoScript" browser extension: Special style fixes[edit]
- Since Tor Browser relies on the NoScript Firefox extension to realize its "safest" mode this extension has to be considered
- On some pages there might be CSS fixes specifically for NoScript
- Currently in Page_Homepage.css /blob/master/mediawiki-shared/src/kicksecure/Page_Homepage.css Page_Homepage.css find "NoScript", there is a fix for a known "feature" of Noscript to elevate its warnings to the top by using a ludicrous z-index. See here https://forums.informaction.com/viewtopic.php?t=26288 and here https://github.com/mastodon/mastodon/issues/13444
- We fix this by forcing a z-index on the NoScript specific class .__ns__pop2top to make the page behave normally
USAGE : Server Scripts[edit]
Images Export Import[edit]
There are two different scripts on the server.
images-download-from-kicksecure
images-download-from-whonix
This was last tested in March 2022 and worked great.
Currently broken due to upstream bug: grabFiles.php broken in MediaWiki 1.38 due to MediaWiki API changes.
Images Export Implementation Details[edit]
Not important. Only for interested readers.
Implemented using mediawiki-tools-grabbers. The following commands would need to be adjusted and executed on the server.
sudo -u www-data php mediawiki-tools-grabbers/grabFiles.php --url https://www.kicksecure.com/w/api.php
sudo -u www-data php mediawiki-tools-grabbers/grabFiles.php --url https://www.whonix.org/w/api.php
TASK ARCHIVE : Done[edit]
Slow loading Javascript problem[edit]
DEV
- On pages where a lot of Javascript is used the page can slow down significantly
- A report was done for Dev/mediawiki by using DebugViaUrlModal. Total time about 6000ms
- enhanceHeadlines +2300ms / 38%
- 259 elements
- content: Sharetooltip is added to each one
- possibly time consuming: Sharetooltip creates Dom and adds event handler
- scrollAutoWrapper +1500ms / 25%
- 79 elements
- Custom scrollbar is being added
- possibly time consuming: (1) scrollbar library (2) ObserverEventHandler (needed if an element is hidden at the start)
- CodeSelect +1000ms / 17%
- 1420 elements
- possibly time consuming: (1) code Highlighting (as with CodeMirror) (2) scrollbar library (3) events for functionality
- header +300ms / 5%
- Not very important. Most scripts add 50 ms - 200 ms to loading
- enhanceHeadlines +2300ms / 38%
- Web workers were researched to use parallel processes - dead end, because web workers cannot access the main thread / Dom / events
- setTimeout method was explored + fixes were added
- setTimeout works, however the main problem is that the browser has no "time to breathe". Added setTimeout between the scripts helps, but for the main identified problem scripts, setTimeout might need to be applied to the individual "enrichment" of "time costly" elements
Patrick:
- use more setTimeout for the individual "enrichment"
- please document
DEV
- DONE
- Changes were done with great success. Report: On our Dev/website
- Dev tests before showed a blocked loading time of 6000ms to 6500ms
- Dev tests now show a semi-blocked loading time of 900ms to 1000ms
- Semi-blocking means that even in those 1000ms the user can interact with the page nicely because the browser "breathes" between the different scripts loads (work of yesterday) which was not the case before
- There are not many drawbacks. The page gradually enriches, but as we focussed on preventing content shift before the content does not shift but only changes slightly in appearance
- The only drawback is that currently the timing check is not very meaningful anymore, because it cannot account for the scripts anymore that are individually async
- Documentation here: Wiki Load Cascade : HTML, CSS, Javascript
- Todo Admin
- Check if everything is satisfactory
- Should something be done about the now inaccurate timing checks? - Dev could come up with something prob. in about 1-2 hours
- Patrick:
- yes, please.
DEV
- DONE
- Page loading was greatly improved
- page loading now outputs when the measuring starts and then outputs a detailled report when all expectedEvents are done
- For more details read updated documentation Performance Testing
Instant page download button bug (2024-10-08)[edit]
DEV
- Dev noticed when hovering download buttons that there's always an error in the console
- Dev realized it's due to instant page trying to load the "next page" when hovering, but not being allowed to fetch or refusing to fetch the data file
- See on wikitest Download_Button (Widget)
- Solved by using data-no-instant attribute in download button, see https://instant.page/blacklist
Pay as you go[edit]
examples:
design:
- no sneakiness
- still a simple download
- noJS users: download
- JS users: donation popup
- Not using: "No, thanks. Let's proceed with the download!"
- avoid confusion
- Confusing for users which might wonder:
- Do I get the same version if I choose 0?
- Seems like this cannot be downloaded for free.
- instead use a bigger, central: "Download Now (FREE!)" button
- Confusing for users which might wonder:
- don't add for simplicity: "Add me to the list of sponsors (from 20,- EUR/USD up)"
- feature: the user can use right click to download to skip the wait
- All the links in the modal open a new window except for the main download. They reference Donate page, but we don't want to divert donating users from their desired download page
- Documentation here Download Button
- A new test was introduced here: Download_Button (Widget)
- redirecturl feature was also ported to modal download button
CodeMirror Wiki Editor slowness bug[edit]
CodeMirror (our optional syntax highlighting extension) cannot handle wiki pages very well.
- https://www.mediawiki.org/w/index.php?title=Topic:Xy5wdyzedunlq944&topic_showPostId=xy6h0qknewsvivzr#flow-post-xy6h0qknewsvivzr
- TLDR: The extension has this problem, just like vanilla CodeMirror, just like many tools with syntax highlighting
- The problem is that basically the whole doc needs to be analysed and then a completely new document is created with a lot of HTML structure to "syntax highlight". This is processing intensive and takes time
- Replier also says that the module would basically have to be rewritten to eg just render parts of the page on demand.
- So basically this is not a bug and could just be feature request by us. But give that it would be a huge undertaking for them I see the chances very slim
fonts and scrollbar causes content shifting[edit]
https://www.kicksecure.com/wiki/VirtualBox/Troubleshooting
Please test on GTmetrix.
- enable Video
- network: 3G (slow)
Hopefully this example is still active: https://gtmetrix.com/reports/www.kicksecure.com/saJHEvIh/
has content shifting
DEV
- DONE: Investigation and headscript restructur
- Investigation found that the content shift is caused by the loaded special fonts. This is unavoidable
- Scrollbar cannot cause this issue from bottom up (and there is no scrollbar in the picture). Also scrollbar is optimized to have no content shift
- Dev optimized the mw-headscript according to HTML guidelines. Now fonts are first preloaded then the CSS is loaded. This causes a slightly more optimal loading waterfall for the font files
- All in all however the content shift remains because it is unavoidable
GoogleOff- exclude from google - whonix RAM wiki page[edit]
google search term:
site:whonix.org "Social Share Button"
(Nobody uses this exact search term. For demonstration purposes only. But it shows that something gets indexed which then shows up in other search results where it should not.)
The following is the Google search results:
See Also Social Share Button
TODO: please exclude "Social Share Button" from google
DEV
- Admin decision needed
- Dev checked all the instances in Google and checked all the pages for the mentioned Social share button
- In every case this is in the Share Tooltip Privacy Policy section. The text before "See Social share button" is from the Tooltip. The text after that phrase is from the content page
- So it could be the case that all these pages have been crawled before the html googleoff wrapper was added to Share Tooltip. Because the wrapper seems correctly used and should prevent google crawling this
- There could also be a Google bug. Or maybe the used GoogleOff incorrectly still.
- However if we move forward with this task we probably need to find a way to certainly say what the exact problem is
Patrick:
- archived and waiting if it goes away, can be re-opened later
CSS class="image"[edit]
CSS class image
is used on Whonix homepage.
class="image"
This is a MediaWiki class: https://www.mediawiki.org/wiki/Parsoid/Parser_Unification/Media_structure/FAQ#h-What_should_editors_look_out_for?
mediawiki code editor warnings[edit]
For example https://www.kicksecure.com/wiki/MediaWiki:Utility.css shows errors.
- Worth fixing?
- False-positives?
DEV
- Problem was researched
- Wiki editor for CSS and Javascript is based on Ace Editor
- Utility.css was tested with newest version of Ace Editor. No problems were found
- Dev has also seen warnings in other files, but always ignored them because the CSS works. And usually if there's a relevant problem in a CSS file then the whole file or at least everything after the error does not work
- Dev thinks that this problem is cause by the Extension either not using the newest Ace editor or not using the newest (not really so new) CSS specifications
Google Mobile-Friendly Test wants larger font sizes[edit]
Google Mobile friendly said that fonts are too small for mobile.
The problem with https://search.google.com/test/mobile-friendly is that it does not download all CSS due to crawler limits. Its judgement is based on incomplete CSS. Lighthouse does not find any issues.
archived ideas:
Use [[Special:ReplaceText]] to search for mentions of <code>font-size:</code>? Kicksecure and Whonix wiki. This is to fix google https://search.google.com/test/mobile-friendly "font too small" warning. Use https://www.kicksecure.com/test/ to reverse engineer this? * Create a few (mobile-only) HTML-only test pages with different font sizes to find out the smallest acceptable font size. * test with https://search.google.com/test/mobile-friendly For example https://search.google.com/test/mobile-friendly itself uses small fonts and passes the test for itself. How to see font size in browser console in chromium: * select text -> right click -> inspect -> <code>computed</code> -> scroll down to font size
Unlighthouse[edit]
Preliminary research. Please check if it does something other than automation which isn't needed yet.
DEV
- After Research Dev would actually recommend using Unlighthouse
- Cons
- Yes, it mainly uses Lighthouse and analyses all pages. But it offers a great overview
- It also does not seem very popular yet, has few reviews and is not listed on AlternativeTo. But the project is also very young (version 0.1.0 released in 2021-12)
- Pros
- It scans the whole website like a search engine using robots.txt and sitemaps
- It has a very intuitive interface, which can be tested here: https://inspect.unlighthouse.dev/
- It lays out the Lighthouse info more clearly, for example with SEO overviews for each page with a SEO score, link counts and ADDS own information like description preview, share image preview
- For best practices it counts inspector issues, image aspect ratios etc. All Lighthouse functionality but better presented in table form
Web Vitals Extension[edit]
https://web.dev/debug-cwvs-with-web-vitals-extension/
https://chrome.google.com/webstore/detail/web-vitals/ahfhijdlegdabablpippeagghigmibma
Preliminary research. Please check if it shows something useful we haven't addressed or discused yet.
DEV
- Research was done
- This plugin basically uses the same metrics as Lighthouse and Pagespeed - concentrating on Largest Contentful Paint, Cumulative Layout Shift and First Input Delay. It basically does the same thing, but presents it in a more practical sense
- Pros
- You have and "ambient bagde" - color indicator how a site is doing: red / yellow / green. And you can go through them easily by just clicking the badge
- It also offers an overlay (click to hide) with more information
- When using the Console logging then some more metrics are available than in Lighthouse
- BIG PRO: Whenever clicking an element you can see the FID. And after that every subsequent interaction. This is an "interactive metric" that Lighthouse does not offer
- Cons
- It eats some RAM, so only activate when needed
- Video: Overview by the creator: https://www.youtube.com/watch?v=2k1QbgLAFdI
- Video by fireship: https://www.youtube.com/watch?v=0fONene3OIA
Defer Upstream MediaWiki JavaScript[edit]
now:
<script defer src="/w/load.php?lang=en&modules=startup&only=scripts&raw=1&skin=vector"></script>
Patrick could server side easily rewrite that to:
<script defer src="/w/load.php?lang=en&modules=startup&only=scripts&raw=1&skin=vector"></script>
(Nobody uses script defer
but upstream said that is not a syntax error.)
please compare the speed and functionality on on kicksecure.com/test/ (already existing, caching disabled there)
DEV
- defer and async were introduced due to admin research
- Upon Dev research it seems that using defer and async together is redundant and not advised
- async fetches the scripts asynchronously and executes them as soon as they are ready
- defer does the same but waits for the whole HTML document to be ready and only then executes the script
- If both are present
- New browsers will prioritise async and ignore defer
- Older browser don't know async and will prioritize defer
- Two tests were written
- https://www.kicksecure.com/test/2023-05-06_kicksecure-hp_all-async.html and
- https://www.kicksecure.com/test/2023-05-06_kicksecure-hp_all-defer.html where all the scripts in headcontent and also the loaded mediawiki script are either called via defer or defer.
- Here are the results as averages after 3 tests each with pagespeed
metric | async | defer |
---|---|---|
FCP | 1.2s | 1.1s |
LCP | 3.5s | 3.4s |
Total Block T | 440ms | 443ms |
Speed Index | 2.1s | 1.9s |
- Dev also tested the functionality and in both cases the pages seemed to perform normal and fast enough for the users
- Dev recommends using only defer
- It seems to perform slightly better
- Most of our customs scripts are designed to perform only after the document is loaded anyways
- Async would only be sensible where there needs to be a fast loading page (so the document does not have to wait for the scripts), but where there are "non-document asap calculation steps" done in Javascript
Total Blocking Time[edit]
Total Blocking Time went up on google pagespeed for mobile. Ideas why? Anything changed? Related to uglifyjs?
DEV
- Research was conducted on possible issues
- Source maps could not be found in research to cause performance issues
- Really hard to find out, because it seems kind of a black box
- However: page map was not the problem. It was activated and deactivated without much difference
- 4 testing pages were compared and tested twice
- OLD: https://www.kicksecure.com/test/font-awesome-test-01-normal.html
- NEW: https://www.kicksecure.com/test/kicksecure-test_2023-03-28_homepage.html
- NEW_NoUserScripts: https://www.kicksecure.com/test/kicksecure-test_2023-03-28_homepage_without-scipts.html
- NEW_NoNewUserScripts: https://www.kicksecure.com/test/kicksecure-test_2023-03-28_homepage_without-new-scipts.html
Cat | OLD | NEW | NEW_NUS | NEW_NNUS |
---|---|---|---|---|
First Contentful Paint | 1.6s / 1.7s | 1.1s / 1.2s | 1.1s / 1.2s | 1.1s / 1.1s |
Total Blocking Time | 50ms / 70ms | 370ms / 580ms | 110ms / 220ms | 370ms / 210ms |
Speed Index | 1.8s / 1.9s | 1.9s / 1.9s | 1.6s / 1.4s | 1.7s / 1.5s |
Largest Contentful Paint | 3.3s / 3.4s | 3.0s / 3.6s | 3.4s / 3.7s | 3.4s / 3.0s |
- Analysis
- It seems the only metric truly affected IS total blocking time, the rest is pretty much the same
- It seems also obvious that the new scripts - prism and instant page - have a significant impact on TBT, but are NOT the only reason because without scripts (meaning also without combined.min.js) it's still not as fast as before
- Dev did a diff of OLD and NEW and saw some differences and found that in flyinnotification the image should be decoding="async" loading="lazy" which was already fixed too but didn't change much for pagespeed
- Dev also thinks it's possible that deferring Javascript leads to a worse TBT, because [Total blocking time] = [Time to interactive] minus [First contentful paint] → so the longer JS is deferred the longer it might take to reach time to interact. That is however just a speculation. This page here is a great overview over the topic https://www.fasterize.com/en/blog/understand-and-improve-the-time-to-interactive/ - not that this page states "It is important to specify that Time To Interactive is not a standardized indicator. It may therefore evolve. Note also that, although Google has included this metric in the calculation of the Lighthouse and PageSpeed Insights score, its weight has decreased during recent changes in the calculation of the score, to the point that it seems to be bound to disappear eventually."
- Here is some more explanation for total blocking time and suggestions to improve and possible reasons why it might have increased in our development https://calibreapp.com/blog/total-blocking-time
- How to proceed
- Dev suggests admin to define a course: Invest more time into improving this metric or waiting for this metric to phase out?
- Because - this was not mentioned before - there were also tests done with gtmetrics which gave very good results and slightly worse results when the "connection" was heavily throttled, indicating that maybe only server speed or dome size could be improved
- Analysis
Patrick:
- also happens with mediawiki therefore probably a pagespeed bug or less likely a mediawiki issue
- compare with a few other popular websites if they also have this issue now (which might be just a pagespeed bug)
- therefore not much time need to be used to analyze if we're causing the issue ourselves
- check with chromium 112 with built in lighthouse in chromium developer toolbar
- Lighthouse 10 will be available in Chrome 112, currently scheduled for release on March 29, 2023.
- Pagespeed performance dropped significantly due to total blocking time issue
Layout was forced console warning[edit]
On kicksecure.com with Firefox (new browser profile).
Layout was forced before the page was fully loaded. If stylesheets are not yet loaded this may cause a flash of unstyled content.
DEV
- Subject was researched. Found relevant sources
- It seems this might be a debugger / dev tool issue. Meaning the dev tools reload the content (sometimes) and therefore trigger this error message
- The worst thing that could happend however - even if this issue occurs in productions (not just for someone who opened dev tools) - is that the page looks strange because it's unstyled for some milliseconds
- Recommendation: ignore
- Alternative: We could try to improve load order. But if it's really just an issue with dev tools this won't fix it, because Dev tools may ignore even an improved load order
MediaWiki Logo HTTP2 Server Push Preload[edit]
MediaWiki by upstream default sends a response header which does a HTTP/2 Server Push. Example:
link: </w/images/2/2a/Kicksecure-logo-text.svg?b0edc>;rel=preload;as=image
Not on the main HTML document but for the CSS load.php. Example:
https://www.kicksecure.com/w/load.php?lang=en&modules=ext.DarkMode.styles%7Cext.dismissableSiteNotice.styles%7Cext.flaggedRevs.basic%2Cicons%7Cjquery.makeCollapsible.styles%7Cmediawiki.widgets.styles%7Coojs-ui-core.icons%2Cstyles%7Coojs-ui.styles.indicators%7Cskins.vector.styles.legacy&only=styles&skin=vector
MediaWiki by upstream default uses the $wgLogos
configuration variable to determine the link to the logo.
However, the hash ?b0edc
is auto generated by MediaWiki and after a cursory look at the source code it seems this cannot be disabled.
This causes the following warning with our custom skin:
The resource https://www.kicksecure.com/w/images/2/2a/Kicksecure-logo-text.svg?b0edc was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally.
This is because it does not know the hash ?b0edc
.
HTTP2 Server Push is being deprecated by upstream browsers: https://developer.chrome.com/blog/removing-push/
https://phabricator.wikimedia.org/T325960
Troubleshooting[edit]
session cache disable[edit]
In case there are login issues, the following could be attempted:
https://www.mediawiki.org/wiki/Manual:$wgSessionCacheType
CACHE_NONE
Notes by Patrick[edit]
- https://www.kicksecure.com/w/index.php?title=MediaWiki:Common.js&oldid=58177
- https://www.kicksecure.com/w/index.php?title=MediaWiki:Common.js&oldid=58384
- https://www.kicksecure.com/w/index.php?title=MediaWiki:Libraries.js&oldid=58825
- https://www.kicksecure.com/w/index.php?title=MediaWiki:CodeSelect.js&oldid=58367
Header:
- old: https://www.kicksecure.com/w/index.php?title=MediaWiki:Header.js&oldid=58824
- new: https://www.kicksecure.com/w/index.php?title=MediaWiki:Header.js&oldid=59272
- diff: https://www.kicksecure.com/w/index.php?title=MediaWiki%3AHeader.js&type=revision&diff=59272&oldid=58824
Entry point is always Mediawiki:Common.js?
Dev: Common.js has been transformed into a standalone library and is therefore now marked as Multiwiki. Common.js now imports ImportScripts.js which is NOT MultiWiki (see Dev/mediawiki#Multiwiki_definitions). This is done so Common.js is a true library and ImportScripts is now LocalWiki specific and there can be individual imports. Note: ImportScripts is loaded at the bottom of the file for call order reasons, therefore every loaded file will have the wikiJsLoader already available.
To disable all, remove all from Mediawiki:Common.js?
Dev: To disable all remove the following line at the bottom of Common.js
mw.loader.load( '/w/index.php?title=MediaWiki:ImportScripts.js&action=raw&ctype=text/javascript' );
What if in the future 1 script breaks? Do all scripts break?
Dev: The wikiJsLoader is totally independent and optional to use. You can call scripts the usual way as before. But now you also have the option to call scripts dependent on each other by using wikiJsLoader. If 1 script breaks this will only affect the script itself and all scripts which are made dependent on this script by using wikiJsLoader. But if those scripts are dependent on a broken script you will have to fix this script anyways to get those scripts running again.
Does a unloadable script show an error in the browser console?
Dev: No. This is because all scripts are loaded asynchronously and the loader is specifically built to load a script only when it is ready. However we could use a timer and show all unloaded scripts after 3 seconds, because it should never take this long to load all the scripts. Or we could write an internal log, which can be called to list all actions by the loader.
What is window.
?
Dev: Window is a JS Object representing the browser window. It is always available and represents the "global namespace" where all global objects are referenced.
How can I manually debug, execute MiniModal.js, Footer.js, CodeSelect.js?
Dev: You can manually load as usual
mw.loader.load( '/w/index.php?title=MediaWiki:MiniModal.js&action=raw&ctype=text/javascript' );
Dev: Or you can use the wikiJsLoader as follows. This is only needed recommended for scripts which are dependent on others.
window.wikiJsLoader.register( 'MiniModal', [], false, function() { ... }); window.wikiJsLoader.exec( ['MiniModal'] );
How to print a debug message with variable name and content to browser console?
Dev: A convenient way is to use console
var whateverYouWantVariable = "String or Object or Boolean or a system variable whatever"; console.info( "whateverYouWantVariable: ", whateverYouWantVariable );
pagespeed[edit]
No longer in use.
- https://www.kicksecure.com
- https://www.kicksecure.com?PageSpeedFilters=+debug
- https://www.kicksecure.com?PageSpeed=off
- https://www.kicksecure.com/wiki/Documentation?PageSpeed=off
- https://www.kicksecure.com/wiki/Hardened-kernel?PageSpeedFilters=-SupportNoScriptEnabled#Upstreaming
- https://github.com/apache/incubator-pagespeed-ngx/issues/1684 (fixed by setting
pagespeed SupportNoScriptEnabled false;
) - https://forums.whonix.org/t/speeding-up-whonix-org-through-caching/8733/3
load.php caching[edit]
- https://www.mediawiki.org/wiki/Topic:Vanoebois3bfqxd1
- https://www.mediawiki.org/wiki/Topic:Runnesgxgk2nc68f
- https://www.mediawiki.org/wiki/Talk:ResourceLoader
- https://serverfault.com/questions/677229/setting-expires-headers-for-things-retrieved-via-query-string
load.php debug mode[edit]
- https://www.kicksecure.com/w/index.php?title=Documentation
- https://www.kicksecure.com/w/index.php?title=Documentation&PageSpeed=off&debug=false
- https://www.kicksecure.com/w/index.php?title=Documentation&PageSpeed=off&debug=true
- https://www.kicksecure.com/wiki/Documentation?PageSpeed=off&debug=false
- https://www.kicksecure.com/wiki/Documentation?PageSpeed=off&debug=true
?pagespeed has no effect on CSS or JavaScript loads
https://github.com/jthingelstad/foreground/issues/370
- debug=true
49 JS 12 CSS
- debug=false
26 JS 1 CSS
instead of
load.php?[...]modulename.namespace.tool,tool2,tool3|differentmodule.tool,tool2
we have
- load.php?[...]modulename.namespace.tool
- load.php?[...]modulename.namespace.tool2
- load.php?[...]modulename.namespace.tool3
- load.php?[...]differentmodule.tool
Old CSS Checklist[edit]
These are actually done but written as if they are not done:
- On for example FAQ the long title
Frequently Asked Questions - Whonix ™ FAQ
breaks the layout on mobile. Because the title is too long, one has to scroll to the right side on mobile to read the title in full. Does the title miss some attribute such as "autowrap", "break line if too long"? - Images for example on Main_Page and About are not response rendered smaller on mobile.
- blockquotes don't really look like a quote. example:
Test
- info box overlaps with thumbnail illustrative image
- Example: VirtualBox/Recommended Version
- illustrative image box overwrites normal Template:Box, examples:
- Template:Box generates boxes which are longer than the text which they contain, example:
- On USB Installation there is much space between title
Installation of Whonix ™ on a USB
and the boxVM Live Mode Host Live Mode Whonix ™ on USB
? - tables prettification
- For example on Windows Hosts the tables look a bit weird. One has to scroll down a lot (specifically on mobile) before having a chance to see what category it is about. Also the colors aren’t great.
- missing table scroll buttons
- When viewing Comparison with Others on mobile it is not obvious that one can scroll the the right. Maybe a scroll button would help? Doesn’t need to be necessarily a scroll button. Also a different table style might be a better solution.
- beautify breadcrumbs (zB < dev on top of this page)
Wiki Js Loader[edit]
- As per now our research shows no option of the MediaWiki mw.loader API to load our own scripts and make them dependent on each other. So user script dependency does not seem to be supported
- Therefore we created our own resource loader under window.wikiJsLoader, see Mediawiki:Common.js. The challenge is to provide a mechanism to load modules which are yet unknown and which can only be known once they are loaded and registered due to the asynchronous loading by mw.loader.load
- Caution: Circular dependencies are not resolved and will be a roadblock for all batches containing these.
- The loader offers 4 methods
- register( name, dependencies, waitForCallback, fn ) - This method registers a function (fn,type:function) in the registry, including its module name (name,type:string), its dependencies (depedencies,type:array-of-strings, other user module names) and if the whole mechanism should wait for their callback (waitForCallback,type:boolean)
- The function fn will get the following parameters: fn(global, callback). global is the getter-setter described below.
- If waitForCallback is true then the registration will not be considered complete until the callback (calback,type:function) is called via callback()
- config( key, value ) - sets a wiki js loader configuration. Currently there is only debug (boolean), if true then all outputs will be shonw, not only warnings and errors
- global( key, value ) - getter-setter. If only key (type:string) is given then the value will be returned. If key and value are given, then key will be set with value
- exec( moduleNames ) - sets in motion the loading process. moduleNames (type:array-of-strings) are names of our dev scripts which shall be called and executed.
- First all depedencies will be checked, if they are not met then the script will not execute futher. But if another register process is completed then load will automatically be triggered again to check if NOW all dependencies are met and we can execute further
- This way scripts will be able to execute exactly when their dependencies are met, not earlier. This is especially necessary as the mw.loader seems to load our scripts asynchronously
- register( name, dependencies, waitForCallback, fn ) - This method registers a function (fn,type:function) in the registry, including its module name (name,type:string), its dependencies (depedencies,type:array-of-strings, other user module names) and if the whole mechanism should wait for their callback (waitForCallback,type:boolean)
- Relevant files
Wiki Js Loader Usage[edit]
1. All JS files which either have dependencies or are dependencies for others should be wrapped into window.wikiJsLoader.register( 'NameOfThisFileWithoutDotJs', ['ModuleDepedency1','ModuleDepedency1'], false, function() { ... });
2. All other files can be implemented as usual
3. All JS files (including with dependencies) can be called via mw.loader.load(...) as usual
4. To actually execute the managed scripts, use the following. This can be used to execute multiple batches of files or just one big batch window.wikiJsLoader.exec( [ 'NameOfThisFileWithoutDotJs1', 'NameOfThisFileWithoutDotJs2' ] );
Wiki Js Loader Debugging[edit]
- To debug a page where an error with wikiJsLoader was shown simple use the normal wiki url syntax "debug=true", e. g. like
https://www.kicksecure.com/wiki/Dev/mediawiki?debug=true
- wikiJsLoader will automatically go into debug mode as well and show you way more details
MediaWiki Gadgets Extension[edit]
It's been decided not to port to MediaWiki Gadgets. The wiki now now extended as per the mechanisms documented above.
Archived notes:
- Gadgets features:
- Supports ResourceLoader. Scripts getting combined and minified.
- ResourceLoader has a concept of dependencies.
- Gadgets supports loading some feature only when editing a wiki page.
- Gadgets supports loading scripts on specific wiki pages only
- https://www.mediawiki.org/wiki/MediaWiki:Gadget-site.js
- https://www.mediawiki.org/wiki/Gadget_kitchen
- https://www.mediawiki.org/wiki/MediaWiki:Gadgets-definition
- Gadgets version 2 development by MediaWiki stalled
TASK ARCHIVE : Rejected[edit]
mediawiki-extensions-Purge[edit]
What does https://github.com/AlPha5130/mediawiki-extensions-Purge/blob/master/resources/ext.purge.js (15 lines only) do?
Probably would have little effect for our wiki because of our custom skin? Does this functionality seem useful?
DEV
- The development of this extension seems pretty interesting
- The new extension (from pseudonym dev) is not much different from the original and seems to fix a faulty behavior of the original extension
- Both versions consist of 2 parts: ext.purge.js and Hooks.php
- In Hooks.php in every page (without our skin) there is a link added to call the purge page (which is not part of the extension but of mediawiki itself)
- This is just a convenience shortcut, but useful - even for us. Because if a dev is already on the edit page then our purge via super menu is not available. Removing this extension however would not be a terrible loss but a small convenience downgrade
- In ext.purge.js the convenience is even more improved for Javascript users only. Because then the link does not open the purge-page but is stopped and instead the purge action is instantly performed without going to the purge page
- Both versions are not perfect
- The original version fails to prevent the link to be augmented by Javascript. This might be due to it being loaded to early or other factors
- The newer version fixes this behavior but also prevents nojs users to use this button at all. It will be there but non-functional
- Suggestion (in order of preferability from Dev's perspective)
- However because it would be mainly for our convenience I suggest use the newer version
- If not then use the older version
- If not then write our own fork which would be the perfect solution
- Another option would be to just add our own purge button via a simple Javascript file on pages that don't have the skin. That would also be a ONLY-JS solution but it would be a bit quicker than the "perfect fork" solution
- If not then don't use at all, because we have instant access to purge via our skin
Patrick:
- Do we even need the purge button still?
- Only for template changes?
- Otherwise cache invalidation is stable nowadays?
- Weird anyhow that non-admins can clear cache.
- MediaWiki's solution prevents crawlers from accidentally pressing that button.
- noJS support not required.
- JS-only solution good enough.
- Could we make it login-only or admin only?
- Needs strong rationale. Using different cache busting methods nowadays.
bug: Custom Scrollbar on mobile not draggable (2024-08-22)[edit]
- The element itself is draggable, but the scrollbar cannot be touched on mobile.
- Please test and fix
DEV
- Analysis complete
- The option to have the scrollbar draggable is not implemented in tinyscrollbar. This would need us forking the original or making a separate augmentation via JS (not recommended by Dev)
- Easy improvement suggestion: Make scrollbars much smaller on mobile (half size?), so they are big enough to indicated "scrollability", but small enough so the mobile user is not motivated to try to touch the scollbar
- Patrick: Also confusing. Not worth it.
pagespeed[edit]
pagespeed - missing source maps[edit]
related to feautre slider SplideJS
Missing source maps for large first-party JavaScript
DEV
- Problem was checked
- We're dealing here with our own auto-generated source maps and wiki source maps and a splide source map
- Hard to say if the source maps are wrong or if pagespeed is wrong
- Fixing this could take a couple of hours because probably a lot of research is needed (AI could not give quick fix ideas either) into understand source maps in detail, understanding how mediawiki does it, how splide does it and how our autogen (uglify/minify) does it
- Very probably not feasible
pagespeed About Whonix and Kicksecure - touch targets spacing[edit]
https://www.whonix.org/wiki/About problem "Touch targets do not have sufficient size or spacing."
- 4 items are still criticized. Dev could try to fix those too, but it seems to be a tougher task because they could also be "false positives"
Tor Browser Maximum Security Slider Setting[edit]
Tor Browser Maximum Security Slider Setting - fix logo text version for[edit]
With Tor Browser security slider set to maximum, the logo text looks bad.
This is happening because the SVG cannot be load by Tor Browser - which is OK. But would be nice if the text version could look a bit better.
Whonix X Logo
Kicksec ure
TODO: please fix, if feasible
DEV
- Done
- Research was Done. Img not loaded alt text not really stylable except with some workaround (but hack not needed)
- Admin decided not worth it
- Dev did some styling so alt text looks decent enough to not be a great distraction
Tor Browser Maximum Security Slider Setting - homepage - SUID Disabler and Permission Hardener too large[edit]
Image for card SUID Disabler and Permission Hardener is too large.
DEV
- Cannot be reproduced
- Testing in general (with the other task) showed that browser cache busting seems very bad in Tor browser (safest settings). Even with version parameter Tor browser seems to ignore it. After 10 or so reloads it randomly got the new version
- And this was NOT ONLY on the onion but on the clearnet address as well
Tor Browser Maximum Security Slider Setting - registered sign[edit]
Looks bad.
- Kicksecure
- Whonix
TODO: please fix, if feasible
DEV
- Not feasable
- As Tor browser safest ignores our custom font the font that it loads depends on the user computer and installed fonts there. Any attempt to style will look good on one computer and bad on others
The following tasks have been considered for realization but have been rejected due to the contra arguments.
feature slider - pop out effect bug[edit]
When the slider card on the left pops out, it cuts the text on the left side.
Same for rightmost slider card.
DEV
- Discussed with admin
- rejected (because user can read fine in normal state)
donation appeal page[edit]
todo: discuss
- appeal
- https://www.thunderbird.net/en-US/thunderbird/115.0/appeal/
- https://web.archive.org/web/20230801072145/https://www.thunderbird.net/en-US/thunderbird/115.0/appeal/
- can be an HTML standalone page if that simplifies the development
- needs link to imprint
- where do we link to this page?
DEV
- In principle we already have a donation appeal page - that is Donate
- There the appeal is written on the left side with the image accompanying it
- Of course this can be more optimized and standalone or look like standalone
- The key question is: Does admin want this page as a new page or to replace Donate?
- If it's a new page what would be the exact use case? - Post this page in forums and social media as kind a of "donation landing page" to motivate the own fanbase? - Or motivate new customers? - But then the homepage would be better to first interest users, get them to use Whonix, and then motivate them to donate
- If it's a replacement, Dev suggests
- "scapping" everying that is not needed from the page including footer and work in progress notification.
- Keep the header so the user still knows they are on the Whonix wiki and they can navigate back
- Stylize the page using HTML via a widget and still using our assets that we build, for example the Paypal widget which could be opened via modal (like Thunderbird does it) or via expandable box
tab controller - closed by default[edit]
todo discuss
- A) close tab controller by default and only open if user clicks it?
- maybe bad for seo?
- B) first tab says "select your platform"?
- maybe also bad for seo?
Both can look weird. For example https://www.kicksecure.com/wiki/Linux the user would be greeted with very little content.
Maybe appropriate for https://www.kicksecure.com/wiki/Verify_the_images_using_Linux?
{{Tab |title= = Verification Method Selection = |addToClass=info-box |active=true |content= Select either OpenPGP or signify. }} <!-- close tab: verification method selection -->
DEV
- This could be indeed a useful feature for certain use cases
- Dev suggests the following solution
{{Tab |type=controller |closedInitText=Select either OpenPGP or signify }}
- It's solved with a single parameter that is very expressive "Closed initialization text", meaning it's initialized as closed, but you have to give a text so the user knows what's going on
- This tasks will prob take 2-3 hours also, because the open-by-hash function has to be adjusted for "closed controllers"
CodeSelect spacing bug[edit]
{{CodeSelect|code= - $tag:whonix-updatevm $default allow,target={{project_name_gateway_vm}} - $tag:whonix-updatevm $anyvm deny }}
- $tag:whonix-updatevm $default allow,target=kicksecure - $tag:whonix-updatevm $anyvm deny
DEV
- The problem was researched by DEV
- The problem seems to lie with mediawiki: MediaWiki "eats up" all the white spaces (incl. line breaks) after a parameter declaration "param=", so in the case above in the first line the white spaces are eaten up
- Dev could research a solution for this if admin wants. Time for a solution probably 30 min, time for a good solution 1h - 1,5h
Remove Edit from Search engine index no. 2[edit]
DEV
- Research was done. This was found
- https://www.mediawiki.org/wiki/Manual:Section_editing
Section editing is a default feature of MediaWiki but can be disabled in a number of ways [...] #disable section edit links for anonymous viewers : $wgDefaultUserOptions ['editsection'] = false; [...] The Magic word
__NOEDITSECTION__
can be used to hide all section edit links on a particular page. [...] In Vector and other skins, the section link has the following CSS class: .mw-editsection - https://www.freshegg.co.uk/seo/how-does-google-treat-hidden-content/#:~:text=In%20general%2C%20Google%20will%20not,command%20within%20a%20search%20snippet.
In general, Google will not display or highlight text that is hidden from initial view using the display
- https://www.mediawiki.org/wiki/Manual:Section_editing
- Dev suggests
- A) Disable it altogether for anons (easy solution, but maybe not wanted)
- Patrick: Yes. Not a good solution because Kicksecure / Whonix got a lot useful anon contributions.
- B) NOEDITSECTION is probably not very useful
- Patrick: True. Same as A).
- C) CSS might help as you see with the Google quote, but that might be a more complex solution because we would have different solutions for NOJS and JS. And on NOJS it probably would have to be invisible anyways
update #2:
- question: Does this bug happen with MediaWiki upstream?
- If yes: todo: Please write a mediawiki bug report draft that EDIT buttons are indexed and this should be prevented by using something similar to our Template:GoogleOff (the div tags, not the template).
- If no: Is this caused by our EnhanceHeadlines?
DEV
- As discussed with admin in chat this is a bug that is reproducible in mediawiki also. Google search
site:mediawiki.org "Enabling and disabling section links"
. There you will find the superfluous "edit" too in the search results - bug report: Publicly visible section edit buttons are indexable by search engines
Eager image widget[edit]
DEV
- Dev and admin talked about a template or widget which would make it possible to load an image eagerly
- This does not seem possible without an extension. Widget does not take a rendered template, but only wikitext as plain text. Therefore widget cannot get the dimensions and other attributes of the image. But that would be needed so the widget could replace loading="lazy" with eager
- Dev thinks the only solution would be an Extension
check integrity of user downloaded files[edit]
does HTML a href support integrity= for user file downloads?
is there any Javascript that i can install on my website that causes on click a file to be downloaded to user's computer and integrity checked?
<a href="example-file.zip" download="example-file.zip" integrity="sha384-B2v2d...">Download Example File </a>
function downloadAndVerify(url, expectedHash) { const link = document.createElement('a'); link.href = url; link.download = url.split('/').pop(); link.integrity = expectedHash; document.body.appendChild(link); link.click(); document.body.removeChild(link); } // Example usage: const url = 'https://example.com/file.zip'; const expectedHash = 'sha384-B2v2d...'; downloadAndVerify(url, expectedHash);
https://stackoverflow.com/a/49478626
https://www.dunebook.com/javascript-file-downloader/
https://github.com/openpgpjs/openpgpjs
https://tails.boum.org/contribute/design/download_verification/
https://tails.boum.org/install/inc/js/download.js
DEV
- Unfortunately this does seem possible
- In this post https://stackoverflow.com/questions/9840923/get-browser-download-path-with-javascript there is stated
Pure browser-JavaScript is not be able to get information about the user's filesystem. The default download path might also contain sensible information, which is risky:
Imagine that one stores his downloads at C:\CompanyName\RealName\PhoneNumber\Adress\
- This is due to security risks being exploited in the early days of Javascript, so now Javascript is in a Sandbox
- In the case of Tails it is possible because the user explicitly selects a filepath in an input:file field and therefore tells the browser. But it's different from a download prompt which is not accessible via Javascript
- This post https://stackoverflow.com/questions/41334881/detect-when-user-accepts-to-download-a-file has an excellent summary of our problem
As i've found from years of maintaining download.js, there simply is no way to tell from JS (or likely in general, see below) what a user chooses to do with the download Open/Save dialog. It's a common feature request, and i've looked into it repeatedly over the years. I can say with confidence that it's impossible; I'll joyfully pay 10 times this bounty if someone an demo a mechanical way to determine the post-prompt user action on any file!
- There might be clever workarounds to seem when the download has started and ended however https://stackoverflow.com/questions/1106377/detect-when-a-browser-receives-a-file-download, because this is also not directly possible
- But it seems very much so that the complicated way tails is doing it is the only way at the moment.
Patrick:
- download.js feature request: check integrity of downloaded files #120
- https://github.com/jimmywarting/StreamSaver.js
- https://github.com/eligrey/FileSaver.js
- https://github.com/whatwg/fs
- https://github.com/rndme/download/
- https://github.com/jimmywarting/native-file-system-adapter
DEV
- Downloading via JavaScript can be done in various ways. But StreamSaver is probably the best or even the only option because the files are so large (e.g., 2.2GB for Whonix). If we download them with JavaScript, everything will be held in RAM and could potentially crash the browser. This becomes especially problematic when we also want to calculate the hash.
- StreamSaver, on the other hand, breaks the download into small chunks that are manageable for the browser and continually frees up memory.
- The problem is: How can we calculate the hash if we only ever get chunks and never the whole file?
- If it's possible, and I understand it correctly, then this developer here has described a process. Although I understand that he is loading the file in chunks from the disk. But we should also be able to apply this during the download: https://medium.com/@0xVaccaro/hashing-big-file-with-filereader-js-e0a5c898fc98
- Conclusion: I now believe 70-80% that we can achieve this. But: It can take a while. And I can't make a guaranteed statement up to the "crucial point".
- But if admin says that theoretically, the total hash can also be calculated on the chunks, then this article I linked might be correct. And then I think it could work with StreamSaver.js.
Patrick:
- StreamSaver.js feature request: check integrity of downloaded files #321
Sufficient Color Contrast[edit]
Warning about insufficient contest might be true. As per:
- Elements Must Have Sufficient Color Contrast
- https://github.com/GoogleChrome/lighthouse/issues/5559
- https://www.plothost.com/kb/lighthouse-report-contrast/
reload content shift[edit]
- Write a bug report for chrome content shift
DEV
- As a draft, so admin can decide if this should really be reported to MediaWiki team
- Chrome seems to reload pages from the bottom up
- So every time there is a vertical content shift ABOVE an element Chrome has "jumping" issues
Title
page reload in Chrome results in vertical content shift
Description
When using Chrome there is bug which occurs when a page is reloaded and there is vertical content shift happening.
As Chrome does seem to reposition the view of the browser window from the page bottom up when there is content shift on the page, Chrome isn't able to position the browser window on the exact same scroll height as before but often a couple of pixels off.
This affects MediaWiki and Wikipedia on longer articles where there is a good chance of at least a bit of content shift is happening.
A problem with this bug is that it seems not very predictable in nature. So to reproduce you have to load 3-5 long articles on MediaWiki / Wikipedia and jump to the middle or lower half and reload the page a couple of times. Scroll up or scroll down a little bit and reload again. Where e. g. in Firefox after reload you would be on the exact same position after reload with Chrome you can often see the page "wander around" moving up or down in increments of a couple of pixels each time.
Patrick:
We cannot really say it's a known chrome bug if no bug report can be found for chrome.
Is it really a chrome bug happening all over the internet?
mediawiki.org doesn't seem to have this bug. For demonstration:
1. go to a very long page in mediawiki.org such as for example https://www.mediawiki.org/wiki/Manual:Hooks#Documentation
2. reload the page either using F5 or pressing enter in the address bar
This bug only happens for example on https://www.kicksecure.com/wiki/Dev/mediawiki#WikitableAutoWrapper_and_ScrollableIndicator when reloading the page.
The bug also doesn't happen on one of the longest pages in the Kicksecure wiki https://www.kicksecure.com/wiki/Mobile_Phone_Security#Registration_Locks
The bug only seems to happen on Dev/mediawiki.
We could say it's not important enough to investigate this bug because it happens only on one page that isn't focused on users? Otherwise finding out what part results in the content shift would require copying the full content of Dev/mediawiki to a testpage and then keeping removing (bigger) chapters until the bug can no longer be reproduced to find out which part of the wiki markup is causing it.
DEV
- Dev sent a video yesterday showing that in all Chromium Browser this content shift problem persists - under specific, but reproducable circumstances
- Dev can reproduce on https://www.mediawiki.org/wiki/Manual:Hooks#Documentation
- Dev can also reproduce here, but only on specific position, but there regularely: https://www.kicksecure.com/wiki/Mobile_Phone_Security#Registration_Locks
- Dev can also reproduce on https://de.wikipedia.org/wiki/Abraham_Lincoln but also only on specific positions
- So how should be proceed?
Minify HTML for wiki.min.js (2023-02-13)[edit]
TODO: discuss
- see https://www.kicksecure.com/mw-autogen/mw-combined-wikijs.min.js
- As you can see where there is HTML the file is not minified. This means some bloated file size
- This happens, because strings cannot be minified, because they would change
- Suggestion: Find or write a function for minifying HTML using Regexp
Patrick:
- Even the main wiki document (kicksecure.com, Main_Page, About, FAQ, all pages) has non-minified HTML.
- Improvement is possible in theory (nginx module pagespeed but currently doesn't seem under active maintenance).
- JS loads slow, with fetchpriority=low anyhow and is deferred. Therefore file sizes and CPU speed should be neglible.
- Speed test websites do not suggest to minify HTML.
- MediaWiki performance team doesn't think it helps: https://phabricator.wikimedia.org/T110612
MediaWiki Special Pages CSS Enhancements[edit]
- There was an issue that the text logo (vertically long) broke MediaWiki special pages because the logo was too long.
- There is a solution to create a localWiki CSS file where these types of corrections for wikis are made but not globally (MulitWiki) but locally. This file would have to be referenced in mw-combine.
- Admin rejected this idea due to complexity and uploads another image instead
MediaWiki Clean vs Unclean Links[edit]
- It's about this: Clean MediaWiki Links
- After editing a wiki page, now unclean links are back (
index.php
version). - This is caused by the MediaWiki FlaggedRevisions extension.
- An alternative might be the MediaWiki ApprovedRevs extension. https://www.mediawiki.org/wiki/Extension:Approved_Revs
Magic Variables Clearnet/Onion[edit]
- introduce our own magic variables, especially one to differentiate in templates and widgets between clearnet-request and onion-request
- This is especially useful in cases where a different link needs to be shown depending if it's onion or clearnet. And if that link is not relative
- Then give task to dev, so he can fix VirtualBox and remove onion extra link
- Cumbersome to implement and not that important because there are separate onion download links.
Expand Button new[edit]
- usually expand areas are created with .mw-collapsible and .mw-collapsible-content
- But this is a JavaScript solution and does not work for nojs users. For them the area is automatically expanded
- A new solution would be to create a widget which creates and expand container and button and content area
- This solution uses checkboxes for nojs users and a js solution for JavaScript users
- A second widget might me "Expand All / Collapse all button, like on page Documentation
- For nojs users this might also be a checkbox which works in tandem with the other new widget for Expand buttons
- A challenge might be that the Expand all checkbox always has to be on the same level as all parent elements of the lower level expand buttons
- For nojs users this might also be a checkbox which works in tandem with the other new widget for Expand buttons
- An alternative variant to the Expand all button might be to introduce a parameter to the expand button widget like "nojsexpanded" where the behavior is like with the current mw-collapsible solution and all areas are expanded if JavaScript is not active
Sitenotice no-JS Version[edit]
- The Sitenotice usually is not dismissable by the user
- We use Extension:DismissableSiteNotice so the user can click away the Sitenotce
- But the extension has a big flaw. On line 55 to 75 (see git of the extension) you can see the dev delivers the sitenotice via JavaScript
- This means the sitenotice is not even visible if the user has JavaScript deactivated.
- This is not desired behaviour. We want every user to see the notice. And JS users just have the additional luxury of being able to dismiss the sitenotice
- Solution suggestion
- We deactivate Extension:DismissableSiteNotice, because the JavaScript way was a deliberate choice of the dev, so even if we can fix the extension the dev very likely won't accept our solution upstream
- Without the extension the Sitenotice will be there for every user.
- We write a JavaScript file to make Sitenotice dismissable which saves this info into a cookie similar to Extension:DismissableSiteNotice, so only JS users have the comfort to dismiss a Sitenotice
Patrick said:
- priority: low
- Let's see what upstream is saying.
- https://phabricator.wikimedia.org/T11209
- https://phabricator.wikimedia.org/T225318#7686484
- Inquiries from 2022-02-06
CodeSelect Show Copy Contents Feature[edit]
- pro
- Would it be possible, and make sense to shop a popup what exactly has been copied to clipboard?
- Maybe useful for the new donation widget?
- Maybe useful generally, globally?
- contra
- In probably 99.9% of cases the user will immediately insert the contents they just copied into another form or programm. Therefore he will see the full copied content immediately afterwards anyways. So this might be superfluous
External Redirections Enhancements[edit]
status: wait
Waiting for new magic words mediawiki extension.
https://github.com/DavisNT/ExternalRedirect/ improvements
example external redirect:
- live:
- wiki source:
- solution?
- Can we change
{{#externalredirect: https://www.kicksecure.com/wiki/OpenPGP}}
- to
{{#externalredirect: {{kicksecure_clearnet_or_onion}}/wiki/OpenPGP}}
- ?
- goals:
- protocol handler respecting redirect.
- redirect Whonix® https visitors to Kicksecure https
- redirect Whonix® onion visitors to Kicksecure onion
- protocol handler respecting redirect.
- notices:
- title:
Redirection
- "You are being redirected. Will redirect in 5 seconds to Kicksecure website."
- "Whonix® is based on Kicksecure"
- title:
[edit]
- pro
- The style for example on A) USB_Installation "table abuse" looks a bit nicer than mininav for example B) Dev/website.
- "table abuse" is shows all navigation options in the same line on mobile which is great.
- "table abuse" has a nicer border?
- "table abuse" has a nicer background color?
- mininav splits it into multiple lines below each other which is non-ideal.
- contra
- mininav is designed with modern standards and especially mobile devices in mind
- the bottom border indicated like with tabs where the user is at
- the tabs can be on one line or multiple lines and are therefore responsive
- the design is subtle and nice and integrates with the rest of the visual language (gray background for code, but white for functional elements of the website)
homepage html optimizations[edit]
For Kicksecure and Whonix homepage. To reduce DOM size.
Something doable, useful here?
Instead of using this code;
<div id = ”navigation-main”> <ul> etc .. </ul> </div>
It would be better to use this other one;
<ul id = ”navigation-main”> etc .. </ul>
DEV
- That would be a small optimization, but nothing substantial for the DOM
- And it would require a lot of work because styles have to be rewritten, sometimes even JS scripts (at least the references)
- I advice against it
critical css test[edit]
info:
goals:
- A simplified test if critical CSS inclusion into the head results in faster website speed at all.
non-goals:
- Making mediawiki use critical CSS. How to integrate this with mediawiki will be considered at a later time in a separate task.
tools:
- https://www.sitelocity.com/critical-path-css-generator
- https://jonassebastianohlsson.com/criticalpathcssgenerator/
- https://www.corewebvitals.io/tools/critical-css-generator
- https://web.dev/codelab-extract-and-inline-critical-css/
todo:
- 1) Use a browser where you are logged out and have no cookies. This is because cookies and being logged in has an influence on the HTML provided by mediawiki.
- 2) on /test/ add Kicksecure homepage with the normal HTML document that we have now:
kicksecure-hp-normal-not-critical-css.html
. This will be needed for speed comparison. - 3) create a copy
kicksecure-hp-critical-css.html
- 4) use some tool to extract the critical css. add the critical css to the head. (https://web-dev.imgix.net/image/admin/RVU3OphqtjlkrlAtKLEn.png)
- 5) out-comment all other CSS for a simple test. Search the HTML document for
stylesheet
. (CSS load withmedia="print" onload="this.media='all'"
can and probably should be ignored and left enabled as it already loads async.) - 6) load all other CSS async
- 7) compare speed of the two different HTML documents
DEV
- Tests were created https://www.kicksecure.com/test/2023-05-06_kicksecure-hp_css-normal.html and https://www.kicksecure.com/test/2023-05-06_kicksecure-hp_css-critical-sitelocity.html and https://www.kicksecure.com/test/2023-05-06_kicksecure-hp_css-critical-corewebvitals.html - the other tools were not very well suited or suited at all for the task
- Results (un-comment wikitext below to see results)
- Conclusion: It seems that
- Critical CSS works. But it's not speeding up the page
- This might be because critical CSS is already very large in both versions
- sitelocity seems to be better with LCP, but has a content layout shift which is not good
- Dev cannot clearly say what happened here. Instructions were followed as described on the pages
TASK ARCHIVE : Backlog (Maybe Future)[edit]
Wiki_Enhancements twitter image broken[edit]
https://www.kicksecure.com/wiki/Wiki_Enhancements
Twitter preview image is broken. Probably because it is not 2:1?
TODO: please fix, try with a twitter image debugger (check they're functional on other pages first to see if these are generally functional)
DEV
- ADMIN ACTION NEEDED
- Problem could not be fixed yet
- Research journey
- Dev assumed it was an image issues.
- Dev used one of his own private servers (not known) and uploaded a copy of the Wiki_Enhancements source code to this and also the preview image
- This did also not work
- Dev tried different image sizes which did also not work.
- Dev tried the same experiment and downloaded the apple.com page and the preview image. This worked
- Dev tried to change the apple image with a recropped version of our image. This worked
- Dev tried again the Wiki_Enhancements source code on his private server with the recropped image. This worked.
- Different websites were tested
- https://www.wikipedia.org/ works, it is a png, 1:1
- https://www.mediawiki.org/wiki/Wikimedia_Hackathon_2024 works, it is a jpg, 16:9 or 1.78:1
- https://www.mediawiki.org does not work, it is a jpg, 1:1 - it works on the tester pages though
- https://www.apple.com/ works, it is a png, 1.905:1
- https://tails.net/ does not work, because it is prevented by robots.txt
- https://www.torproject.org/ works. It is a png with 2:1
- https://www.qubes-os.org/ works. It is a png with 1.905:1
- Also many Kicksecure pages were tested. Homepage, Download, About, Donate worked on Twitter, but did NOT work with the testers. Dev thinks that these pages are also "broken" but twitter does not reload them so the old preview is used and is therefore save. But that's just an assumption
- Dev concludes
- About the image I'm not sure completely, but the following is highly likely
- Images are accepted in multiple file types: jpg, png, also webp (not links about but other tests)
- Images can have a range of sizes. Common are 1:1 to 2:1 which all do work
- The pages do not use twitter:image but mostly og:image meta tag which seems to be accepted by twitter
- Use absolute links: Twitter seems to need absolute urls. This was tested on the private server. Relative adresses like
/w/images/...
do not work. Also absolute image starting with the domain likehttps://www.kicksecure.com/w/images/2/2c/Wiki-upgrade-social-preview.png?version=26ed5bd8ec8fbabdfec28f40d8463039
. This is automatically handled by our SEO extension, but it's worth mentioning in case we ever change it - The https://www.mediawiki.org not working is strange. Maybe also a legacy issue. But also the MediaWiki page (but NOT Wikipedia) have a weird meta tag policy where they have the og:image meta tag 3 times in then og:image:height and og:image:width each time again - the exact same meta tag. This seems supposed to be for the crawler for different sizes to choose, but as it is the same tag the crawler probably just takes the last instance of each tag. And maybe the 640x360 image is accepted from Hackathon 2024, but not the 640x640 image from the main page. So it can be assumed that wide images have different rules than square images. Wikipedia with its square image in contrast has a very large square png (>2000x2000)
- It also seems Twitter updates at the earliest every 10 minutes
- For later documentation, Dev suggests for Twitter image testing
- Test every new url that should go on twitter with these two pages. They sometimes have a refresh delay of max 1 minute each after you change something on the url. https://threadcreator.com/tools/twitter-card-validator and https://renderform.io/tools/twitter-card-preview-tool/#
- Test also on this page. Although it's deprecated (only for SEEING previews) by twitter it's still valuable for the log and maybe to trigger twitter to url (seems to sometimes work) https://cards-dev.x.com/validator
- The most reliable but also slowest test is on https://x.com/compose/post There you just post the URL and wait a couple of seconds for the preview to show up. If it takes to long reload the page and try again. If it still does not work the check cards-dev validator above again. Maybe there's an important info like
ERROR: Fetching the page failed because it's denied by robots.txt.
which it was for tails.net
- Now to our page: The last idea Dev has is that our CORS headers and other headers are the problem
- cross-origin-resource-policy: same-site restricts the resource to be used only by the same site. Twitter's crawler might not be considered part of the "same site". Alternative: cross-origin-resource-policy: cross-origin
- The header cross-origin-opener-policy: same-origin could potentially restrict cross-origin data sharing. Alternative cross-origin-opener-policy: unsafe-none
- The header x-frame-options: SAMEORIGIN prevents the image from being embedded in frames from other origins
- Also there's a content-type mismatch: The header content-type: image/webp indicates that the image is being served as a WebP file, but the file extension in the URL suggests it might be a JPEG (.jpg).
- TODO Admin
- Please try experimenting / fixing these 3 policies
- After that Dev would like to get this task back up to document the whole process in our Dev documentation
- About the image I'm not sure completely, but the following is highly likely
- Dev assumed it was an image issues.
Patrick:
- CORS is unlikely the issue because: Works on different wiki pages but all wiki pages have the same CORS headers. CORS is a a recommendation set by the server. The design idea is to protect a user's browser from a compromised server. The client software (browser or bot) needs to adhere to CORS. See also Content Security Policy (CSP).
- Test tools are not reliable. Twitter draft tool uses caching. Impossible to debug.
- Can be file format issue. SVG unsupported. WEBP unsupported.
Newsletter Widget[edit]
- Widget here means "widget" generally as in a box with a special feature.
- Not necessarily a MediaWiki widget.
- Is there a better terminology than widget to avoid confusion?
- features:
- subscribe
- unsubscribe
- add the newsletter subscribe/unsubscribe to homepage
- the widget should be re-usable in other places in the wiki
- Ideally noJS compatible.
- Just two (subscribe/unsubscribe) POST submit boxes.
- The backend on the server could be a simple PHP script that just appends the e-mail address to a file subscribe.txt / unsubscribe.txt.
- The PHP script should reject invalid e-mail address formats (such as with spaces in the middle or missing @ sign)
- The PHP script would return "Success. Thanks for signing up!" or "Failure to sign-up. Please report this bug in the forums."
- non-features:
- double opt-in (this will be done manually at a later stage before sending any e-mails)
- TODO: discuss
DEV
- Topic was discussed. Script should be simple and at best not using a database
- Dev did newsletter research. Conclusions
- Most scripts are paid and proprietary, e. g. https://www.formget.com/newsletter-php-script/
- Most scripts are rather complex
- Most scripts use MySQL
- Options
- We could write a completely new scripts
- We could base a widget on the research by admin: https://github.com/rodhilton/maillister (an old script)
- We could by a modern script and set it up with mysql
- Admin said he will do script research again
SVG to PNG conversion error probably by ImageMagick[edit]
DEV
- While creating a donor image for FUTO, the FUTO svg was used
- This created a problem, see here https://www.whonix.org/wiki/File:Futo-logo.svg
- Superficial research by Dev suggests that this could be a MediaWiki ImageMagick bug
- The SVG image by FUTO itself seems very simple and was even further simplified by Dev to an "optimized" SVG. Both versions failed in MediaWiki
- Admin probably should have a look if there's an internal problem
- For now PNG image was used for page Donors instead. If issue is resolved then svg image should be used
- Patrick: Probably MediaWiki bug.
Top Headline missing edit button[edit]
- One page Dev/mediawiki a headline was shown as headline level 1 but had no edit button
DEV
- Semi fix.
- Bug was thoroughly examined.
- No Javascript, CSS or HTML bug
- Previous and following chapter were analyzed
- Also the previous, this and the following chapter were copied to a testpage were everything worked fine
- It seemed the previous chapter also loads the chapter with the missing editsection button. So it was assumed the problem lies in the previous chapter, so sections of the were strategically deleted to find the problematic subsection.
- The problem was a wikitable in the direct previous chapter, a level 2 headline. Removing the wikitable solved the problem. But this is not a solution, so wikitable was just html-commented out (and notice was given)
- Dev would normally suggest a bug report to MediaWiki. However the bug is not reproducible in a smaller test page, see Testpage. It seems this is a "complexity bug", which is cause by multiple not obviously connected causes. Dev also performed a full page wikitext analysis and found no syntax errors (just very few of spelling errors which were corrected)
- So Dev suggests just archiving these finds and for now work with html-commenting out the problematic tables if necessary. If the bug becomes a practical one (and not a theoretical one like now) this should be re-investigated
MediaWiki:Page_Homepage.css Question[edit]
Only a question.
Could Page_Homepage.css /blob/master/mediawiki-shared/src/kicksecure/Page_Homepage.css Page_Homepage.css be embedded inline into widget:Page_Homepage? Good idea?
Reason: Potential website speed improvement?
Would get rid of https://www.whonix.org/w/index.php?title=MediaWiki:Page_Homepage.css&action=raw&ctype=text/css&css-extension=1 (the only call to index.php), would get rid of 1 additional file to download.
Might not be needed if nginx server side PHP caching speeds this up.
DEV
- Yes, Page_Homepage.css could be embedded
- Pro: That would improve parallel loading (because the CSS is there earlier). Speed COULD therefore improve a little bit
- Con: But that would inflate the page even more (which would also negatively impact the PageSpeed "Dom is too large" warning
- Alternative idea: Load the script directly from /mw-autogen/src-copy folder. This needs some small tweaks, probably in config-build-(shared and specific).json /tree/master/mediawiki-shared/build config-build-(shared and specific).json and/or mw-combine, but might be reasonably quick
Whonix Homepage Video[edit]
simplify noJS version[edit]
For the more beautiful, feature-rich implementation related to all of these video tasks, would it help if the noJS version would be further simplified?
Potentially acceptable for the homepage noJS version:
- just show the illustrative image
- direct link to the video
- video download link
- could offer many different quality / size versions
- YouTube link
- yewtu.be
- no need to play inside the homepage
Separate JS version[edit]
Should we add a more pretty video player if JS is available?
The HTML5 player is nice for noJS but has some probably unfixable issues. When playing the video over a slow connection (slow internet; Tor; onion) it starts, is then stuck, loads, play again. That is not very useful. This leads missing the hear the first few seconds of the video and no bearable video experience. Hence above chapter "simplify noJS version".
If we decide to use a JS based video player... Is there a video player for slow connections that
- can buffer the first 10-20 seconds or so?
- lower the video quality?
Streaming Protocols - RTSP RTSPS HLS[edit]
What we want is "VOA" - "video on demand". Only playing simple videos. No live streaming.
For adaptive bitrate streaming (lowering the video resolution and quality over slow connections), the whonix.org server would need to support RTSP (actually RTSPS for better security) and HLS? Patrick did preliminary research and thinks its doable.
research video players[edit]
requirements:
- must be Open Source
- installed to whonix.org/libs or so (not fetching from third parties such as jsDelivr)
- can be JS based
- with HTML5 only (noJS) features are probably limited and no players available?
- avoid NPM (seems very pretty much doable, players that Patrick has seen are deployed as a single JS file. Trivial to install on the server.)
feature wish list:
- remember video playback position after reload
- see also requested features above
review todo:
- https://videojs.com/ smoothQualityChange: true, http://rsmck.co.uk/blog/adaptive-hls-streaming-with-nginx/
- flow player
- etc
lazy load player[edit]
If we use a JS based video player, should it be lazy loaded to avoid increasing load times for normal visits?
CSS restyle html5 video controls[edit]
- Controls always visible because otherwise just a big black area that looks broken over slow connections
- add additional buttons
- direct link (https://www.whonix.org/videos/whonix-explainer.mp4)
- download link
- youtube link
- yewtu.be link
- video supermenu
- picture in picture restyle
- always show a progress bar spinner (even if a fake one) (Requires JS? If so, OK.)
resources:
- https://developer.mozilla.org/en-US/docs/Web/Guide/Audio_and_video_delivery/Video_player_styling_basics
remember video playback position after reload[edit]
video gallery[edit]
Would it make sense to add a video gallery / switcher using arrows so users can watch the other two Whonix explainer videos too?
FEATURE ARCHIVE[edit]
The following features are RETIRED
ContentImage (Template) - image wrapper for overlenght images[edit]
- This feature is retired and replaced by a global setting for all content images
- Content images is a term for images used in the content produced. These images usually occur between text, paragraphs, headlines. Sometimes these images can become too large for small display sizes
- For images which are expected to be too large for some displays, this wrapper template is ideal. Images inside this wrapper will have max-width:100% and height:auto;
- NOTE : Thumbnails DO NOT need to be wrapped in ContentImage, because they already have a max-width of 100%, read more here: Dev/mediawiki#Responsive_Thumbnails
- USAGE
- Simply wrap any image that you suspect could be oversize in this wrapper
- Parameter
- addToClass (optional, string) : This parameter's text will be added to the class attribute of the content image wrapper container
- w100 (optional, boolean) : Makes an image always width 100%. This parameter if true will add the class ciw-w100 to the content iamge wrapper container. This will make the container and all its children
width: 100%; display: inline-block;
. This parameter was introduced as a helper due to a changed in the way images are handled in MediaWiki since version 1.40.
- Example with wrapper Code {{ContentImage|[[File:Image-too-wide-demonstration.jpg]]}}
- Example without wrapper
[[File:Image-too-wide-demonstration.jpg]]
- Example with wrapper
- Relevant files
sd-start (currently retired)[edit]
- https://www.kicksecure.com/wiki/Widget:Sd-start-short
- https://www.kicksecure.com/wiki/Widget:Sd-end-short-start-detailed
- https://www.kicksecure.com/wiki/Widget:Sd-end-detailed
- https://www.kicksecure.com/wiki/Template:Sd-start-short
- https://www.kicksecure.com/wiki/Template:Sd-end-short-start-detailed
- https://www.kicksecure.com/wiki/Template:Sd-end-detailed
Footnotes[edit]
- ↑ https://github.com/jthingelstad/foreground/issues/392
- ↑
Kicksecure:
- system-wide (requires administrative ("root") rights) (compatible with noexec): flatpak install flathub {{{package}}}
- per-user (no administrative rights required) (probably not compatible with noexec): flatpak --user install flathub {{{package}}}
- <>usability:</> Flathub is enabled by default system-wide but not per-user.
- multi-user: On a multi-user system (probably if multiple human users use the same computer, which is rare nowadays), system-wide might be preferable as this saves disk space.
- At preset: Does not make any difference.
- Future-proof: Per-user might be more future-proof. It would be compatible with future Kicksecure security improvements Dev/boot_modes (strong user account isolation). However, noexec for the home folder is to be considered later, at which point this documentation needs to be updated once that has been implemented.
- ↑
Kicksecure-Qubes Template:
flatpak
cannot be used with the--user
option. This is because in case of using a Qubes Template, the flatpak needs to be installed system-wide into the/var/lib/flatpak
folder. This is due to Qubes Persistence. If the--user
option was used, the flatpak would only be available in the Template's home folder but not in any App Qube based on that Template, because App Qubes have their own independent home folder. - ↑
Kicksecure-Qubes App Qube:
flatpak
should be used with the--user
option. This is because in case of using an App Qube, the flatpak needs to be installed per-user only into the~/.local/share/flatpak
folder and not system-wide. This is due to Qubes Persistence. If the--user
option was not used, the flatpak would only be available in the App Qube's non-persistent/var/lib/flatpak
folder located in the root image.
We believe security software like Kicksecure needs to remain Open Source and independent. Would you help sustain and grow the project? Learn more about our 12 year success story and maybe DONATE!