summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2016-04-20 16:29:07 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2016-04-20 16:29:07 (GMT)
commit92892f13357188a5b4c81b5f2c35a3a740924d67 (patch)
tree26e5bb275c2171802f3bf477eb2a1aa0f20ec4df
First commit.
-rw-r--r--Toha.php10
-rw-r--r--Toha.skin.php395
-rw-r--r--i18n/en.json37
-rw-r--r--i18n/fr.json38
-rw-r--r--i18n/qqq.json7
-rw-r--r--resources/blog.pngbin0 -> 1183 bytes
-rw-r--r--resources/chat.pngbin0 -> 747 bytes
-rw-r--r--resources/contact.pngbin0 -> 2071 bytes
-rw-r--r--resources/contribs.pngbin0 -> 724 bytes
-rw-r--r--resources/delete.pngbin0 -> 860 bytes
-rw-r--r--resources/documentation.pngbin0 -> 1986 bytes
-rw-r--r--resources/download.pngbin0 -> 1206 bytes
-rw-r--r--resources/dynmenu.js91
-rw-r--r--resources/history.pngbin0 -> 920 bytes
-rw-r--r--resources/identity.pngbin0 -> 608 bytes
-rw-r--r--resources/logout.pngbin0 -> 770 bytes
-rw-r--r--resources/page.pngbin0 -> 773 bytes
-rw-r--r--resources/preferences.pngbin0 -> 758 bytes
-rw-r--r--resources/protect.pngbin0 -> 1027 bytes
-rw-r--r--resources/rename.pngbin0 -> 615 bytes
-rw-r--r--resources/screen.css824
-rw-r--r--resources/screenshots.pngbin0 -> 1550 bytes
-rw-r--r--resources/watchlist.pngbin0 -> 682 bytes
-rw-r--r--skin.json39
24 files changed, 1441 insertions, 0 deletions
diff --git a/Toha.php b/Toha.php
new file mode 100644
index 0000000..ac5508b
--- /dev/null
+++ b/Toha.php
@@ -0,0 +1,10 @@
+<?php
+/**
+ * This PHP entry point is deprecated. Please use wfLoadSkin() and the skin.json file
+ * instead. See https://www.mediawiki.org/wiki/Manual:Extension_registration for more details.
+ */
+if ( !function_exists( 'wfLoadSkin' ) ) {
+ die( 'The Example skin requires MediaWiki 1.25 or newer.' );
+}
+
+wfLoadSkin( 'Toha' );
diff --git a/Toha.skin.php b/Toha.skin.php
new file mode 100644
index 0000000..45ad911
--- /dev/null
+++ b/Toha.skin.php
@@ -0,0 +1,395 @@
+<?php
+/**
+ * Skin file for the Toha skin.
+ *
+ * @file
+ * @ingroup Skins
+ * @ref https://git.wikimedia.org/summary/mediawiki%2Fskins%2FExample.git
+ */
+
+/**
+ * SkinTemplate class for the Toha skin
+ *
+ * @ingroup Skins
+ */
+class SkinToha extends SkinTemplate {
+
+ public $skinname = 'Toha', $stylename = 'Toha',
+ $template = 'TohaTemplate', $useHeadElement = true;
+
+ /**
+ * initialize the page
+ */
+ public function initPage( OutputPage $out ) {
+ parent::initPage( $out );
+ $out->addModuleScripts( array(
+ 'skins.toha'
+ ) );
+ }
+
+ /**
+ * Add CSS via ResourceLoader
+ *
+ * @param $out OutputPage
+ */
+ function setupSkinUserCss( OutputPage $out ) {
+ parent::setupSkinUserCss( $out );
+ $out->addModuleStyles( array(
+ 'skins.toha'
+ ) );
+ }
+
+ /**
+ * initialize various variables and generate the template
+ *
+ * @since 1.23
+ * @return QuickTemplate The template to be executed by outputPage
+ */
+ function prepareQuickTemplate( ) {
+ global $wgSmallLogo;
+ $tpl = parent::prepareQuickTemplate( );
+ $tpl->setRef( 'smalllogopath', $wgSmallLogo );
+ return $tpl;
+
+ }
+
+}
+
+/**
+ * BaseTemplate class for the Toha skin
+ *
+ * @ingroup Skins
+ */
+class TohaTemplate extends BaseTemplate {
+
+ /**
+ * Outputs a single sidebar portlet of any kind.
+ */
+ private function outputPortlet( $box ) {
+ if ( !$box['content'] ) {
+ return;
+ }
+
+ ?>
+ <div
+ role="navigation"
+ class="mw-portlet"
+ id="<?php echo Sanitizer::escapeId( $box['id'] ) ?>"
+ <?php echo Linker::tooltip( $box['id'] ) ?>
+ >
+ <h3>
+ <?php
+ if ( isset( $box['headerMessage'] ) ) {
+ $this->msg( $box['headerMessage'] );
+ } else {
+ echo htmlspecialchars( $box['header'] );
+ }
+ ?>
+ </h3>
+
+ <?php
+ if ( is_array( $box['content'] ) ) {
+ echo '<ul>';
+
+ $wrapper = array( 'text-wrapper' => array(
+ array( 'tag' => 'div',
+ 'attributes' => array( 'class' => 'link_icon' ) ),
+ array( 'tag' => 'span' )
+ ) );
+
+ foreach ( $box['content'] as $key => $item ) {
+ echo $this->makeListItem( $key, $item, $wrapper );
+ }
+ echo '</ul>';
+ } else {
+ echo $box['content'];
+ }?>
+ </div>
+ <?php
+ }
+
+ /**
+ * Prepare links for submenus.
+ */
+ private function outputRawLinks( $name, $links ) {
+
+ echo 'var inner_' . $name . ' = \'';
+
+ if ( is_array( $links ) ) {
+
+ foreach ( $links as $key => $item )
+ echo $this->makeLink( $key, $item );
+
+ } else {
+
+ echo $links;
+
+ }
+
+ echo '\';' . "\n";
+
+ echo 'addMenuToID(\'n-' . $name . '-desc\', inner_' . $name . ');';
+
+ echo "\n\n";
+
+ }
+
+ /**
+ * Define menus on the left and on the right.
+ */
+ private function renderPortletAsSideButtons( $required, $boxes ) {
+
+ foreach ( $required as $req ) {
+
+ if ( ! array_key_exists( $req, $boxes ) )
+ continue;
+
+ $box = $boxes[$req];
+
+ if ( ! $box['content'] )
+ continue;
+
+ ?>
+ <ul id="<?php echo Sanitizer::escapeId( $box['id'] ) ?>">
+ <?php
+
+ if ( is_array( $box['content'] ) ) {
+
+ foreach ( $box['content'] as $key => $item )
+ echo $this->makeListItem( $key, $item,
+ array( 'text-wrapper' => array( 'tag' => 'span' ) ) );
+
+ } else {
+
+ echo $box['content'];
+
+ }
+
+ ?>
+ </ul>
+ <?php
+
+ }
+
+ }
+
+ /**
+ * Outputs the entire contents of the page.
+ */
+ public function execute() {
+
+ $this->html( 'headelement' ) ?>
+
+ <header>
+
+ <a
+ id="p-logo"
+ role="banner"
+ href="<?php echo htmlspecialchars( $this->data['nav_urls']['mainpage']['href'] ) ?>"
+ <?php echo Xml::expandAttributes( Linker::tooltipAndAccesskeyAttribs( 'p-logo' ) ) ?>
+ >
+ <img class="big"
+ src="<?php $this->text( 'logopath' ) ?>"
+ alt="<?php $this->text( 'sitename' ) ?>"
+ />
+ <img class="small"
+ src="<?php $this->text( 'smalllogopath' ) ?>"
+ alt="<?php $this->text( 'sitename' ) ?>"
+ />
+ </a>
+
+ <?php
+ $sideboxes = $this->getSidebar();
+ $this->outputPortlet( $sideboxes['navigation'] );
+ ?>
+
+ </header>
+
+ <div class="extender"></div>
+
+ <script>
+
+ function toggleExtender() {
+
+ header = document.getElementsByTagName("header")[0];
+
+ if (document.body.scrollTop > 105 || document.documentElement.scrollTop > 105)
+ header.className = "sticky";
+
+ else
+ header.className = "";
+
+ }
+
+ window.onscroll = toggleExtender;
+
+ </script>
+
+ <div id="mw-wrapper">
+
+ <script>
+
+ function buildDynMenus() {
+
+ <?php
+
+ foreach ( $sideboxes as $boxName => $box ) {
+
+ $parts = explode( '-', $boxName );
+
+ if ( count( $parts ) != 2 ) continue;
+
+ if ($parts[1] != 'submenu' ) break;
+
+ $this->outputRawLinks( $parts[0], $box['content'] );
+
+ }
+
+ ?>
+
+ }
+
+ document.body.onload = buildDynMenus;
+
+ </script>
+
+ <div class="mw-body" role="main">
+ <?php if ( $this->data['sitenotice'] ) { ?>
+ <div id="siteNotice"><?php $this->html( 'sitenotice' ) ?></div>
+ <?php } ?>
+
+ <?php if ( $this->data['newtalk'] ) { ?>
+ <div class="usermessage"><?php $this->html( 'newtalk' ) ?></div>
+ <?php } ?>
+
+ <?php
+ if (false/* && !$this->getSkin()->getTitle()->isMainPage()*/) {
+ ?>
+ <h1 class="firstHeading">
+ <?php $this->html( 'title' ) ?>
+ </h1>
+ <?php
+ }
+ ?>
+
+ <div class="mw-body-content">
+ <div id="contentSub">
+ <?php if ( $this->data['subtitle'] ) { ?>
+ <p><?php $this->html( 'subtitle' ) ?></p>
+ <?php } ?>
+ <?php if ( $this->data['undelete'] ) { ?>
+ <p><?php $this->html( 'undelete' ) ?></p>
+ <?php } ?>
+ </div>
+
+ <?php $this->html( 'bodytext' ) ?>
+
+ <?php $this->html( 'catlinks' ) ?>
+
+ <?php $this->html( 'dataAfterContent' ); ?>
+
+ </div>
+ </div>
+
+ <div id="mw-footer">
+
+ <ul id="poweredby">
+ <?php foreach ( $this->getFooterIcons( 'icononly' ) as $blockName => $footerIcons ) { ?>
+ <li>
+ <?php
+ foreach ( $footerIcons as $icon ) {
+ echo $this->getSkin()->makeFooterIcon( $icon );
+ }
+ ?>
+ </li>
+ <?php } ?>
+ </ul>
+
+ <ul id="lastmod">
+ <li><?php $this->html( 'lastmod' ) ?></li>
+ </ul>
+
+ <?php global $wgFooterImages; ?>
+
+ <ul id="links">
+ <?php foreach ( $wgFooterImages as $category => $params ) { ?>
+ <li>
+ <a href="<?= $params['url'] ?>">
+ <?php if ( isset( $params['src'] ) ) { ?>
+ <img alt="<?= $params['alt'] ?>" src="<?= $params['src'] ?>" onmouseover="this.src='<?= $params['hsrc'] ?>'" onmouseout="this.src='<?= $params['src'] ?>'">
+ <?php } else { ?>
+ <img alt="<?= $params['alt'] ?>" src="<?= $params['src'] ?>">
+ <?php } ?>
+ </a>
+ </li>
+ <?php } ?>
+ </ul>
+
+ <div style="clear: both;"></div>
+
+ </div>
+
+ <div id="mw-navigation" class="left-navigation">
+
+ <div>
+ <?php
+
+ $this->renderPortletAsSideButtons( array ( 'TOOLBOX', 'LANGUAGES' ), $sideboxes );
+
+ ?>
+ </div>
+
+ </div>
+
+ <div id="mw-navigation" class="right-navigation">
+
+ <div>
+ <?php
+
+ $navigations = $this->data['content_navigation'];
+
+ if ( array_key_exists('view', $navigations['views']) )
+ unset( $navigations['views']['view'] );
+
+ $rboxes = array(
+
+ 'personal' => array(
+
+ 'id' => 'p-personal',
+ 'content' => $this->getPersonalTools()
+
+ ),
+
+ 'views' => array(
+
+ 'id' => 'p-views',
+ 'content' => $navigations['views']
+
+ ),
+
+ 'actions' => array(
+
+ 'id' => 'p-actions',
+ 'content' => $navigations['actions']
+
+ )
+
+ );
+
+ $this->renderPortletAsSideButtons( array ( 'personal', 'views', 'actions' ), $rboxes );
+
+ ?>
+ </div>
+
+ </div>
+
+ </div>
+
+ <?php $this->printTrail() ?>
+
+ </body></html>
+
+ <?php
+ }
+
+}
diff --git a/i18n/en.json b/i18n/en.json
new file mode 100644
index 0000000..afeb503
--- /dev/null
+++ b/i18n/en.json
@@ -0,0 +1,37 @@
+{
+ "@metadata": {
+ "authors": [ "Cyrille Bagard" ]
+ },
+
+ "screenshots-url": "Screenshots",
+ "screenshots-desc": "SCREENSHOTS",
+ "documentation-url": "Documentation",
+ "documentation-desc": "DOCUMENTATION",
+ "download-url": "Download",
+ "download-desc": "DOWNLOAD",
+ "activity-url": "Blog:Articles",
+ "activity-desc": "EVOLUTIONS",
+ "contact-url": "Contacts",
+ "contact-desc": "CONTACTS",
+
+ "pythonapi-url" : "Pychrysalide_Python_Module",
+ "pythonapi-desc" : "Python documentation",
+ "howto-url" : "HowTo",
+ "howto-desc" : "HowTo",
+ "faq-url" : "FAQ",
+ "faq-desc" : "FAQ",
+
+ "blog-url" : "Blog:Articles",
+ "blog-desc" : "Blog",
+ "features-url" : "RoadMap",
+ "features-desc" : "Roadmap",
+ "comparison-url" : "Compare",
+ "comparison-desc" : "Comparisons",
+
+ "addresses-url" : "Contacts",
+ "addresses-desc" : "Contacts",
+ "references-url" : "References",
+ "references-desc" : "References",
+ "webresources-desc" : "Web Resources"
+
+}
diff --git a/i18n/fr.json b/i18n/fr.json
new file mode 100644
index 0000000..13bfa2b
--- /dev/null
+++ b/i18n/fr.json
@@ -0,0 +1,38 @@
+{
+ "@metadata": {
+ "authors": [ "Cyrille Bagard" ]
+ },
+
+ "screenshots-url": "Screenshots",
+ "screenshots-desc": "GALERIE PHOTOS",
+ "documentation-url": "Documentation",
+ "documentation-desc": "DOCUMENTATION",
+ "download-url": "Download",
+ "download-desc": "TELECHARGEMENT",
+ "activity-url": "Blog:Articles",
+ "activity-desc": "EVOLUTIONS",
+ "contact-url": "Contacts",
+ "contact-desc": "CONTACTS",
+
+ "pythonapi-url" : "Pychrysalide_Python_Module",
+ "pythonapi-desc" : "Documentation Python",
+ "howto-url" : "HowTo",
+ "howto-desc" : "HowTo",
+ "faq-url" : "FAQ",
+ "faq-desc" : "FAQ",
+
+ "blog-url" : "Blog:Articles",
+ "blog-desc" : "Blog",
+ "features-url" : "RoadMap",
+ "features-desc" : "Feuille de route",
+ "comparison-url" : "Compare",
+ "comparison-desc" : "Comparaisons",
+
+ "addresses-url" : "Contacts",
+ "addresses-desc" : "Contacts",
+ "references-url" : "References",
+ "references-desc" : "Références",
+ "webresources-url" : "WebResources",
+ "webresources-desc" : "Ressources Web"
+
+}
diff --git a/i18n/qqq.json b/i18n/qqq.json
new file mode 100644
index 0000000..87ddba7
--- /dev/null
+++ b/i18n/qqq.json
@@ -0,0 +1,7 @@
+{
+ "@metadata": {
+ "authors": [ "Cyrille Bagard" ]
+ },
+ "skinname-example": "{{optional}}",
+ "example-desc": "{{desc|what=skin|name=Example|url=https://www.mediawiki.org/wiki/Skin:Example}}"
+}
diff --git a/resources/blog.png b/resources/blog.png
new file mode 100644
index 0000000..9ad7e34
--- /dev/null
+++ b/resources/blog.png
Binary files differ
diff --git a/resources/chat.png b/resources/chat.png
new file mode 100644
index 0000000..1356422
--- /dev/null
+++ b/resources/chat.png
Binary files differ
diff --git a/resources/contact.png b/resources/contact.png
new file mode 100644
index 0000000..22c5354
--- /dev/null
+++ b/resources/contact.png
Binary files differ
diff --git a/resources/contribs.png b/resources/contribs.png
new file mode 100644
index 0000000..98e01d6
--- /dev/null
+++ b/resources/contribs.png
Binary files differ
diff --git a/resources/delete.png b/resources/delete.png
new file mode 100644
index 0000000..b994897
--- /dev/null
+++ b/resources/delete.png
Binary files differ
diff --git a/resources/documentation.png b/resources/documentation.png
new file mode 100644
index 0000000..617a119
--- /dev/null
+++ b/resources/documentation.png
Binary files differ
diff --git a/resources/download.png b/resources/download.png
new file mode 100644
index 0000000..b5f9fe2
--- /dev/null
+++ b/resources/download.png
Binary files differ
diff --git a/resources/dynmenu.js b/resources/dynmenu.js
new file mode 100644
index 0000000..a10296b
--- /dev/null
+++ b/resources/dynmenu.js
@@ -0,0 +1,91 @@
+
+var last_popped = null;
+var popped_in_use = false;
+
+var last_timeout = null;
+
+function prepareLastPopped(evt) {
+
+ last_popped.onmouseleave = removeLastPopped;
+
+ popped_in_use = true;
+
+}
+
+function removeLastPopped(evt) {
+
+ if (last_popped != null) {
+
+ last_popped.parentNode.removeChild(last_popped);
+ last_popped = null;
+
+ }
+
+}
+
+function forcePoppedHiding(evt) {
+
+ function cancelPopping() {
+
+ last_timeout = null;
+
+ if (!popped_in_use) {
+
+ removeLastPopped(null);
+
+ }
+
+ }
+
+ last_timeout = setTimeout(cancelPopping, 500);
+
+}
+
+function showMenu(target, inner) {
+
+ function waitForEvent(evt) {
+
+ if (last_timeout != null) {
+
+ clearTimeout(last_timeout);
+ last_timeout = null;
+
+ }
+
+ removeLastPopped(null);
+
+ if (inner == null)
+ return;
+
+ var menubar = document.createElement('div');
+
+ menubar.id = 'myMenu';
+ menubar.className = 'menu_arrow_box'
+ menubar.innerHTML = inner ;
+ document.body.insertBefore(menubar, document.body.childNodes[0]);
+
+ var rect = target.getBoundingClientRect();
+ var menu_rect = menubar.getBoundingClientRect();
+
+ menubar.style.left = (rect.left - (menu_rect.width - rect.width) / 2) + "px";
+ menubar.style.top = (rect.bottom + 20) + "px";
+
+ last_popped = menubar;
+ popped_in_use = false;
+
+ menubar.onmouseenter = prepareLastPopped;
+ target.onmouseleave = forcePoppedHiding;
+
+ }
+
+ return waitForEvent;
+
+}
+
+function addMenuToID(id, inner) {
+
+ var target = document.getElementById(id);
+
+ target.onmouseenter = showMenu(target, inner);
+
+}
diff --git a/resources/history.png b/resources/history.png
new file mode 100644
index 0000000..6fd4eb4
--- /dev/null
+++ b/resources/history.png
Binary files differ
diff --git a/resources/identity.png b/resources/identity.png
new file mode 100644
index 0000000..d3efc46
--- /dev/null
+++ b/resources/identity.png
Binary files differ
diff --git a/resources/logout.png b/resources/logout.png
new file mode 100644
index 0000000..230858b
--- /dev/null
+++ b/resources/logout.png
Binary files differ
diff --git a/resources/page.png b/resources/page.png
new file mode 100644
index 0000000..fc0015c
--- /dev/null
+++ b/resources/page.png
Binary files differ
diff --git a/resources/preferences.png b/resources/preferences.png
new file mode 100644
index 0000000..ef43654
--- /dev/null
+++ b/resources/preferences.png
Binary files differ
diff --git a/resources/protect.png b/resources/protect.png
new file mode 100644
index 0000000..fbe32e9
--- /dev/null
+++ b/resources/protect.png
Binary files differ
diff --git a/resources/rename.png b/resources/rename.png
new file mode 100644
index 0000000..7771959
--- /dev/null
+++ b/resources/rename.png
Binary files differ
diff --git a/resources/screen.css b/resources/screen.css
new file mode 100644
index 0000000..50166bf
--- /dev/null
+++ b/resources/screen.css
@@ -0,0 +1,824 @@
+
+/**
+ * http://paletton.com/#uid=13A0u0kmuvOcIMPi8DgrvtKtUnq
+ */
+
+
+/* ********************************************************************************** */
+/* DISPOSITION DE PARTIES PRINCIPALES */
+/* ********************************************************************************** */
+
+
+html, body {
+
+ font-family: sans-serif;
+ margin: 0;
+ padding: 0;
+
+}
+
+#mw-wrapper {
+
+ max-width: 70em;
+ margin: 0 auto;
+
+ position: relative;
+
+}
+
+
+/* ********************************************************************************** */
+/* BARRES DE NAVIGATION LATERALES */
+/* ********************************************************************************** */
+
+
+/* Positions respectives */
+
+.left-navigation {
+
+ position: absolute;
+ left: -300px;
+
+}
+
+.right-navigation {
+
+ position: absolute;
+ right: -150px;
+
+}
+
+/* Emplacement vertical fixe (cf. classe 'header') */
+
+#mw-navigation > div {
+
+ position: fixed;
+
+ top: 160px;
+
+}
+
+/* Affichage / retrait des listes */
+
+#mw-navigation ul {
+
+ text-align: left;
+ margin: 0;
+ margin-top: 50px;
+ border: 1px solid transparent;
+
+ padding-left: 4px;
+ padding-top: 8px;
+ padding-right: 4px;
+ padding-bottom: 8px;
+
+}
+
+#mw-navigation ul:hover {
+
+ background-color: #fff;
+ border-color: #ccc;
+ border-radius: 2px;
+ box-shadow: 2px 2px 2px #999;
+
+}
+
+#mw-navigation ul li {
+
+ padding: 0px;
+ padding-top: 2px;
+ padding-bottom: 2px;
+
+ margin: 0px;
+ list-style: none;
+ font-size: 0.875em;
+
+ opacity: 0.4;
+
+ /* Les images ne doivent pas être tronquées verticalement */
+ line-height: 32px;
+
+}
+
+#mw-navigation ul:hover li {
+
+ opacity: 0.8;
+
+}
+
+#mw-navigation ul li a {
+
+ display: block;
+
+ /* Fait de la place pour les images */
+ padding-left: 40px;
+
+ background-position: left center;
+ background-repeat: no-repeat;
+
+ white-space: nowrap;
+
+}
+
+#mw-navigation ul span {
+
+ visibility: hidden;
+
+}
+
+#mw-navigation ul:hover span {
+
+ visibility: visible;
+
+}
+
+/* Images associées par défaut */
+
+#pt-userpage a {
+
+ /**
+ * "User" par Philip Gwynne
+ * https://thenounproject.com/term/user/14219/
+ */
+ background-image: url('identity.png');
+
+}
+
+#pt-mytalk a {
+
+ /**
+ * "Chat" par Jaclyne Ooi
+ * https://thenounproject.com/term/chat/26692/
+ */
+ background-image: url('chat.png');
+
+}
+
+#pt-preferences a {
+
+ /**
+ * "Configure" par Gonzalo Bravo
+ * https://thenounproject.com/term/configure/63054/
+ */
+ background-image: url('preferences.png');
+
+}
+
+#pt-watchlist a {
+
+ /**
+ * "Eye" par Casper Jensen
+ * https://thenounproject.com/term/eye/104152/
+ */
+ background-image: url('watchlist.png');
+
+}
+
+#pt-mycontris a {
+
+ /**
+ * "Share" par P.J. Onori
+ * https://thenounproject.com/term/share/2886/
+ */
+ background-image: url('contribs.png');
+
+}
+
+#pt-logout a {
+
+ /**
+ * "Power" par Michela Tannoia
+ * https://thenounproject.com/term/power/25339/
+ */
+ background-image: url('logout.png');
+
+}
+
+#ca-edit a {
+
+ /**
+ * "Document" par Cody Lawson
+ * https://thenounproject.com/term/document/4502/
+ */
+ background-image: url('page.png');
+
+}
+
+#ca-history a {
+
+ /**
+ * "History" par Joe Mortell
+ * https://thenounproject.com/term/history/18126/
+ */
+ background-image: url('history.png');
+
+}
+
+
+#ca-delete a {
+
+ /**
+ * "Trash Can" par Dima Kolchan
+ * https://thenounproject.com/term/trash-can/8119/
+ */
+ background-image: url('delete.png');
+
+}
+
+#ca-move a {
+
+ /**
+ * "Rename" par Icons8
+ * https://thenounproject.com/term/rename/61456/
+ */
+ background-image: url('rename.png');
+
+}
+
+#ca-protect a {
+
+ /**
+ * "Shield" par Charlene Chen
+ * https://thenounproject.com/term/shield/7005/
+ */
+ background-image: url('protect.png');
+
+}
+
+
+/* ********************************************************************************** */
+/* BARRE SUPERIEURE DES PAGES */
+/* ********************************************************************************** */
+
+
+/* Barre supérieure rétractable */
+
+header {
+
+ background: rgb(58,110,165);
+
+ width: 100%;
+ height: 170px;
+
+ /**
+ * Pour une image de taille 200px, si on a header.height à 170px,
+ * il reste ~30px à compenser.
+ *
+ * On laisse beaucoup de marge pour que le texte du contenu de la
+ * ne colle pas l'image de trop près.
+ *
+ * La taille totale doit être reportée dans 'mw-wrapper'.
+ */
+
+ margin-bottom: 60px;
+
+}
+
+header.sticky {
+
+ position: fixed;
+ top: 0px;
+
+ height: 50px;
+
+ margin-bottom: 0px;
+
+ z-index: 8000;
+
+}
+
+
+header ~ div.extender {
+
+ display: none;
+
+}
+
+header.sticky ~ div.extender {
+
+ display: block;
+
+ /**
+ * On doit compenser les hauteurs ici.
+ *
+ * Par exemple : (170 + 60) = (50 + x)
+ * 180 = x
+ */
+
+ height: 180px;
+
+}
+
+header a, header a:hover, header a:focus {
+
+ text-deoration: none;
+ color: black;
+ opacity: 0.8;
+
+}
+
+
+/* ********************************************************************************** */
+/* LOGO EN HAUT DU SITE */
+/* ********************************************************************************** */
+
+
+#p-logo {
+
+ float: left;
+ text-align: right;
+
+ margin-left: 20px;
+
+ width: 620px;
+
+ position: relative;
+ top: 111px;
+ -webkit-transform: translateY(-50%);
+ -ms-transform: translateY(-50%);
+ transform: translateY(-50%);
+
+ opacity: 1.0;
+
+}
+
+header #p-logo {
+
+ top: 111px;
+
+}
+
+header #p-logo img.big {
+
+ display: initial;
+
+}
+
+header #p-logo img.small {
+
+ display: none;
+
+}
+
+header.sticky #p-logo {
+
+ top: 26px;
+
+}
+
+header.sticky #p-logo img.big {
+
+ display: none;
+
+}
+
+header.sticky #p-logo img.small {
+
+ display: initial;
+
+ height: 47px;
+
+}
+
+
+/* ********************************************************************************** */
+/* BARRE DE NAVIGATION SUPERIEURE */
+/* ********************************************************************************** */
+
+
+/* Barre supérieure de menu */
+#p-navigation {
+
+ display:inline-block;
+
+ position: relative;
+ top: 50%;
+ -webkit-transform: translateY(-50%);
+ -ms-transform: translateY(-50%);
+ transform: translateY(-50%);
+
+}
+
+#p-navigation ul {
+
+ list-style-type: none;
+ margin: 0;
+
+}
+
+#p-navigation ul li {
+
+ display: inline-block;
+ margin-left: 1em;
+ margin-right: 2em;
+
+ text-align: center;
+
+}
+
+#p-navigation a {
+
+ color: white;
+ opacity: 0.7;
+
+ font-weight: bold;
+
+ text-decoration: none;
+
+}
+
+#p-navigation a:hover, #p-navigation a:focus {
+
+ opacity: 1.0;
+
+}
+
+
+/* On cache certains en-têtes */
+#mw-navigation h2, #p-navigation h3, #p-search h3 {
+
+ display: none;
+
+}
+
+
+/* Conteneur final */
+
+.link_icon span {
+
+ white-space: nowrap;
+
+}
+
+header .link_icon {
+
+ visibility: visible;
+
+ padding-top: 70px;
+
+ background-position: center top;
+ background-repeat: no-repeat;
+
+}
+
+header.sticky .link_icon {
+
+ padding-top: 0px;
+
+ background-image: none;
+
+}
+
+
+/* Eléments du menu de navigation supérieur */
+
+header:not([class~=sticky]) #n-screenshots-desc .link_icon {
+
+ /**
+ * "Camera" par Haitham Almayman
+ * https://thenounproject.com/term/camera/76991/
+ */
+ background-image: url('screenshots.png');
+
+}
+
+header:not([class~=sticky]) #n-documentation-desc .link_icon {
+
+ /**
+ * "Books" par Les vieux garçons
+ * https://thenounproject.com/term/books/51607/
+ */
+ background-image: url('documentation.png');
+
+}
+
+header:not([class~=sticky]) #n-download-desc .link_icon {
+
+ /**
+ * "Download" par Alexander Bickov
+ * https://thenounproject.com/term/download/29328/
+ */
+ background-image: url('download.png');
+
+}
+
+header:not([class~=sticky]) #n-activity-desc .link_icon {
+
+ /**
+ * "Write" par Lemon Liu
+ * https://thenounproject.com/term/write/21211/
+ */
+ background-image: url('blog.png');
+
+}
+
+header:not([class~=sticky]) #n-contact-desc .link_icon {
+
+ /**
+ * "Contact" par Icons8
+ * https://thenounproject.com/term/contact/50339/
+ */
+ background-image: url('contact.png');
+
+}
+
+
+/* ********************************************************************************** */
+/* SOUS-MENUS DE LA PARTIE SUPERIEURE */
+/* ********************************************************************************** */
+
+
+#myMenu {
+
+ z-index: 100000;
+
+ position: fixed;
+
+ text-align: left;
+ padding: 8px;
+
+ padding-left: 20px;
+ padding-right: 20px;
+
+}
+
+#myMenu a {
+
+ display: block;
+
+ color: #205c9a;
+ opacity: 0.9;
+
+ font-weight: bold;
+
+ text-decoration: none;
+
+ line-height: 160%;
+
+}
+
+#myMenu a:hover {
+
+ color: white;
+ opacity: 1.0;
+
+}
+
+
+/* Cf. http://www.cssarrowplease.com/ */
+
+.menu_arrow_box {
+
+ background: #88afd8;
+ border: 1px solid #fff;
+
+ border-top-left-radius: 12px;
+ border-top-right-radius: 12px;
+ border-bottom-left-radius: 12px;
+ border-bottom-right-radius: 12px;
+
+}
+
+.menu_arrow_box:after, .menu_arrow_box:before {
+
+ bottom: 100%;
+ left: 50%;
+
+ border: solid transparent;
+
+ content: " ";
+
+ height: 0;
+ width: 0;
+
+ position: absolute;
+ pointer-events: none;
+
+}
+
+.menu_arrow_box:after {
+
+ border-color: rgba(0, 0, 0, 0);
+ border-bottom-color: #88afd8;
+
+ border-width: 13px;
+ margin-left: -13px;
+
+}
+
+.menu_arrow_box:before {
+
+ border-color: rgba(0, 0, 0, 0);
+ border-bottom-color: #fff;
+
+ border-width: 15px;
+ margin-left: -15px;
+
+}
+
+
+/* ********************************************************************************** */
+/* PIED DE PAGE */
+/* ********************************************************************************** */
+
+
+#mw-footer {
+
+ margin-top: 23px;
+ padding: 0.6em;
+ padding-bottom: 0.4em;
+
+ border: 1px solid rgb(32, 92, 154);
+ border-top-left-radius: 25px;
+ border-top-right-radius: 25px;
+
+ background-color: rgb(58,110,165);
+
+ display:table;
+ width: 100%;
+
+ position:absolute;
+ bottom:0;
+
+}
+
+#mw-footer ul {
+
+ list-style-type: none;
+ margin: 0;
+
+}
+
+#mw-footer ul li {
+
+ display: inline-block;
+ margin-right: 1em;
+
+}
+
+#mw-footer ul#poweredby {
+
+ display:table-cell;
+ vertical-align: middle;
+ text-align: left;
+
+}
+
+#mw-footer ul#lastmod {
+
+ display:table-cell;
+ vertical-align: middle;
+ text-align: center;
+
+ color: white;
+ opacity: 0.7;
+
+}
+
+#mw-footer ul#links {
+
+ display:table-cell;
+ vertical-align: middle;
+ text-align: right;
+
+}
+
+/* On colle le pied de page toujours en bas */
+
+html, body {
+
+ height: 100%;
+
+}
+
+#mw-wrapper {
+
+ /* 230px = header[.sticky].height + div.extender.height */
+ min-height: calc(100% - 230px);
+
+}
+
+#mw-footer {
+
+ position:absolute;
+ bottom:0;
+
+}
+
+.mw-body {
+
+ /**
+ * On reste un espace pour le pied de page, avec marge :
+ *
+ * 69px + 2em ~= #mw-footer.height + marge
+ */
+ padding-bottom: calc(69px + 2em);
+
+}
+
+
+/* ********************************************************************************** */
+/* PARTIES COMMUNES */
+/* ********************************************************************************** */
+
+
+/* Marge des images insérées dans du texte */
+
+a.image > img {
+
+ margin: 20px;
+
+}
+
+
+/* Sommaire */
+
+.toc {
+
+ /*background: #88afd8;*/
+ border: 2px solid #3a6ea5;
+ border: 2px solid #88afd8;
+ border-radius: 8px;
+
+ margin: 20px;
+
+ padding-left: 25px;
+ padding-right: 25px;
+ padding-bottom: 8px;
+
+ float: right;
+ display: table;
+
+}
+
+.toctoggle {
+
+ display: none;
+
+}
+
+.toclevel-1 {
+
+ margin-top: 10px;
+
+ list-style-type: square;
+
+}
+
+body:not(.page-Page_Main):not(.page-Accueil) *:not(#toctitle):not(.h2) > h2 {
+
+ position: relative;
+ left: -30px;
+
+ padding-left: 30px;
+ padding-right: 30px;
+
+ border-bottom: 2px solid rgb(58, 110, 165);
+
+ display: inline-block;
+ margin: 0px;
+ margin-top: 20px;
+
+ clear: both;
+
+}
+
+pre {
+
+ border: 2px dashed;
+ border-left: 8px solid;
+ border-color: rgb(58, 110, 165);
+
+ padding: 10px;
+ padding-right: 50px;
+
+ margin-left: 40px;
+
+ font-size: 120%;
+
+ display: table;
+ white-space: pre-wrap;
+
+}
+
+a {
+
+ text-decoration: none;
+
+}
+
+
+/**
+ * Par défaut, une image centrée reste à gauche...
+ * On force donc un comportement correct.
+ *
+ * Le code permettant de valider le résultat attendu est du genre :
+ *
+ * [[File:XXX.png|center]]
+ *
+ */
+div.center {
+
+ text-align: center;
+
+}
diff --git a/resources/screenshots.png b/resources/screenshots.png
new file mode 100644
index 0000000..59f6574
--- /dev/null
+++ b/resources/screenshots.png
Binary files differ
diff --git a/resources/watchlist.png b/resources/watchlist.png
new file mode 100644
index 0000000..cafa19e
--- /dev/null
+++ b/resources/watchlist.png
Binary files differ
diff --git a/skin.json b/skin.json
new file mode 100644
index 0000000..751f9f2
--- /dev/null
+++ b/skin.json
@@ -0,0 +1,39 @@
+{
+ "name": "Toha",
+ "version": "1.0",
+ "author": "Cyrille Bagard",
+ "url": "https://www.mediawiki.org/wiki/Skin:Toha",
+ "descriptionmsg": "toha-desc",
+ "namemsg": "skinname-toha",
+ "license-name": "CC0-1.0",
+ "type": "skin",
+ "ValidSkinNames": {
+ "toha": "Toha"
+ },
+ "MessagesDirs": {
+ "Toha": [
+ "i18n"
+ ]
+ },
+ "ResourceModules": {
+ "skins.toha": {
+ "styles": {
+ "resources/screen.css": {
+ "media": "screen"
+ }
+ },
+ "scripts": "resources/dynmenu.js",
+ "scripts2": [
+ "resources/dynmenu.js"
+ ]
+ }
+ },
+ "ResourceFileModulePaths": {
+ "localBasePath": "",
+ "remoteSkinPath": "Toha"
+ },
+ "AutoloadClasses": {
+ "SkinToha": "Toha.skin.php"
+ },
+ "manifest_version": 1
+}