Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-docs.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAchilleas Pipinellis <axil@gitlab.com>2018-02-07 15:30:26 +0300
committerAchilleas Pipinellis <axil@gitlab.com>2018-02-07 15:30:26 +0300
commit29a8cf3c2a6355955fbc17be8c2c84d9fd17dc25 (patch)
tree29a14f0af67f8f0c414fb4800b675c63b0baaeff /content
parent1c38d9811df4ba39ffb572a45ed7c3fa87e1b395 (diff)
parent89883d5e65e0f17c27f8dae41c32848324d7b419 (diff)
Merge branch 'article-layout-1' into 'master'
Article layout Closes #157 See merge request gitlab-com/gitlab-docs!182
Diffstat (limited to 'content')
-rw-r--r--content/assets/javascripts/classlist-polyfill.js240
-rw-r--r--content/assets/javascripts/docs.js38
-rw-r--r--content/assets/stylesheets/_variables.scss2
-rw-r--r--content/assets/stylesheets/stylesheet.scss38
-rw-r--r--content/assets/stylesheets/toc.scss101
-rw-r--r--content/index.erb2
6 files changed, 326 insertions, 95 deletions
diff --git a/content/assets/javascripts/classlist-polyfill.js b/content/assets/javascripts/classlist-polyfill.js
new file mode 100644
index 00000000..09b2e8b0
--- /dev/null
+++ b/content/assets/javascripts/classlist-polyfill.js
@@ -0,0 +1,240 @@
+/*
+ * classList.js: Cross-browser full element.classList implementation.
+ * 1.1.20170427
+ *
+ * By Eli Grey, http://eligrey.com
+ * License: Dedicated to the public domain.
+ * See https://github.com/eligrey/classList.js/blob/master/LICENSE.md
+ */
+
+/*global self, document, DOMException */
+
+/*! @source http://purl.eligrey.com/github/classList.js/blob/master/classList.js */
+
+if ("document" in window.self) {
+
+// Full polyfill for browsers with no classList support
+// Including IE < Edge missing SVGElement.classList
+if (!("classList" in document.createElement("_"))
+ || document.createElementNS && !("classList" in document.createElementNS("http://www.w3.org/2000/svg","g"))) {
+
+(function (view) {
+
+"use strict";
+
+if (!('Element' in view)) return;
+
+var
+ classListProp = "classList"
+ , protoProp = "prototype"
+ , elemCtrProto = view.Element[protoProp]
+ , objCtr = Object
+ , strTrim = String[protoProp].trim || function () {
+ return this.replace(/^\s+|\s+$/g, "");
+ }
+ , arrIndexOf = Array[protoProp].indexOf || function (item) {
+ var
+ i = 0
+ , len = this.length
+ ;
+ for (; i < len; i++) {
+ if (i in this && this[i] === item) {
+ return i;
+ }
+ }
+ return -1;
+ }
+ // Vendors: please allow content code to instantiate DOMExceptions
+ , DOMEx = function (type, message) {
+ this.name = type;
+ this.code = DOMException[type];
+ this.message = message;
+ }
+ , checkTokenAndGetIndex = function (classList, token) {
+ if (token === "") {
+ throw new DOMEx(
+ "SYNTAX_ERR"
+ , "An invalid or illegal string was specified"
+ );
+ }
+ if (/\s/.test(token)) {
+ throw new DOMEx(
+ "INVALID_CHARACTER_ERR"
+ , "String contains an invalid character"
+ );
+ }
+ return arrIndexOf.call(classList, token);
+ }
+ , ClassList = function (elem) {
+ var
+ trimmedClasses = strTrim.call(elem.getAttribute("class") || "")
+ , classes = trimmedClasses ? trimmedClasses.split(/\s+/) : []
+ , i = 0
+ , len = classes.length
+ ;
+ for (; i < len; i++) {
+ this.push(classes[i]);
+ }
+ this._updateClassName = function () {
+ elem.setAttribute("class", this.toString());
+ };
+ }
+ , classListProto = ClassList[protoProp] = []
+ , classListGetter = function () {
+ return new ClassList(this);
+ }
+;
+// Most DOMException implementations don't allow calling DOMException's toString()
+// on non-DOMExceptions. Error's toString() is sufficient here.
+DOMEx[protoProp] = Error[protoProp];
+classListProto.item = function (i) {
+ return this[i] || null;
+};
+classListProto.contains = function (token) {
+ token += "";
+ return checkTokenAndGetIndex(this, token) !== -1;
+};
+classListProto.add = function () {
+ var
+ tokens = arguments
+ , i = 0
+ , l = tokens.length
+ , token
+ , updated = false
+ ;
+ do {
+ token = tokens[i] + "";
+ if (checkTokenAndGetIndex(this, token) === -1) {
+ this.push(token);
+ updated = true;
+ }
+ }
+ while (++i < l);
+
+ if (updated) {
+ this._updateClassName();
+ }
+};
+classListProto.remove = function () {
+ var
+ tokens = arguments
+ , i = 0
+ , l = tokens.length
+ , token
+ , updated = false
+ , index
+ ;
+ do {
+ token = tokens[i] + "";
+ index = checkTokenAndGetIndex(this, token);
+ while (index !== -1) {
+ this.splice(index, 1);
+ updated = true;
+ index = checkTokenAndGetIndex(this, token);
+ }
+ }
+ while (++i < l);
+
+ if (updated) {
+ this._updateClassName();
+ }
+};
+classListProto.toggle = function (token, force) {
+ token += "";
+
+ var
+ result = this.contains(token)
+ , method = result ?
+ force !== true && "remove"
+ :
+ force !== false && "add"
+ ;
+
+ if (method) {
+ this[method](token);
+ }
+
+ if (force === true || force === false) {
+ return force;
+ } else {
+ return !result;
+ }
+};
+classListProto.toString = function () {
+ return this.join(" ");
+};
+
+if (objCtr.defineProperty) {
+ var classListPropDesc = {
+ get: classListGetter
+ , enumerable: true
+ , configurable: true
+ };
+ try {
+ objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);
+ } catch (ex) { // IE 8 doesn't support enumerable:true
+ // adding undefined to fight this issue https://github.com/eligrey/classList.js/issues/36
+ // modernie IE8-MSW7 machine has IE8 8.0.6001.18702 and is affected
+ if (ex.number === undefined || ex.number === -0x7FF5EC54) {
+ classListPropDesc.enumerable = false;
+ objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);
+ }
+ }
+} else if (objCtr[protoProp].__defineGetter__) {
+ elemCtrProto.__defineGetter__(classListProp, classListGetter);
+}
+
+}(window.self));
+
+}
+
+// There is full or partial native classList support, so just check if we need
+// to normalize the add/remove and toggle APIs.
+
+(function () {
+ "use strict";
+
+ var testElement = document.createElement("_");
+
+ testElement.classList.add("c1", "c2");
+
+ // Polyfill for IE 10/11 and Firefox <26, where classList.add and
+ // classList.remove exist but support only one argument at a time.
+ if (!testElement.classList.contains("c2")) {
+ var createMethod = function(method) {
+ var original = DOMTokenList.prototype[method];
+
+ DOMTokenList.prototype[method] = function(token) {
+ var i, len = arguments.length;
+
+ for (i = 0; i < len; i++) {
+ token = arguments[i];
+ original.call(this, token);
+ }
+ };
+ };
+ createMethod('add');
+ createMethod('remove');
+ }
+
+ testElement.classList.toggle("c3", false);
+
+ // Polyfill for IE 10 and Firefox <24, where classList.toggle does not
+ // support the second argument.
+ if (testElement.classList.contains("c3")) {
+ var _toggle = DOMTokenList.prototype.toggle;
+
+ DOMTokenList.prototype.toggle = function(token, force) {
+ if (1 in arguments && !this.contains(token) === !force) {
+ return force;
+ } else {
+ return _toggle.call(this, token);
+ }
+ };
+
+ }
+
+ testElement = null;
+}());
+
+}
diff --git a/content/assets/javascripts/docs.js b/content/assets/javascripts/docs.js
index ae70aad0..05e8ab35 100644
--- a/content/assets/javascripts/docs.js
+++ b/content/assets/javascripts/docs.js
@@ -1,3 +1,5 @@
+var NAV_INLINE_BREAKPOINT = 1100;
+
var navtoggle = document.getElementById("docs-nav-toggle");
if (navtoggle) {
navtoggle.addEventListener("click", toggleNavigation);
@@ -10,22 +12,22 @@ function toggleNavigation() {
// move document nav to sidebar
(function() {
- var nav = document.querySelectorAll('.breadcrumbs +ul');
- var main = document.querySelectorAll('.main.class');
+ var tocList = document.querySelector('.js-article-content > ul:first-child');
+ var main = document.querySelector('.js-main-wrapper');
// if the document has a top level nav
- if(nav[0]) {
+ if(tocList) {
// append to the sidebar
var sidebar = document.getElementById('doc-nav');
if(sidebar) {
// if there is one h1 in the documentation
- if(nav[0].children.length == 1) {
+ if(tocList.children.length == 1) {
// if there is a nested ul after the first anchor
- if(nav[0].children[0].children.length > 1) {
- var menu = nav[0].children[0].children[1];
+ if(tocList.children[0].children.length > 1) {
+ var menu = tocList.children[0].children[1];
var footnotes = menu.querySelector('.footnotes');
if (footnotes) {
@@ -43,33 +45,37 @@ function toggleNavigation() {
var sidebarHeight = sidebar.querySelector('ul').getBoundingClientRect().height + 55;
+ // When we scroll down to the bottom, we don't want the footer covering
+ // the TOC list (sticky behavior)
document.addEventListener('scroll', function() {
- if (window.innerWidth < 1099) return;
+ var isTouchingBottom = false;
+ if (window.innerWidth >= NAV_INLINE_BREAKPOINT) {
+ isTouchingBottom = window.scrollY + sidebarHeight >= main.offsetHeight;
+ }
- if (window.scrollY + sidebarHeight >= main[0].offsetHeight) {
- sidebar.style.position = 'absolute';
- sidebar.style.top = (main[0].offsetHeight - sidebarHeight) + 'px';
+ sidebar.classList.toggle('doc-nav-bottom-touching', isTouchingBottom)
+ if (isTouchingBottom) {
+ sidebar.style.top = (main.offsetHeight - sidebarHeight) + 'px';
} else {
- sidebar.style.position = '';
sidebar.style.top = '';
}
}, { passive : true });
}
// remove what is left of the old navigation
- nav[0].remove()
+ tocList.remove()
}
else {
- nav[0].remove()
+ tocList.remove()
}
}
// main content has-toc
- if (main[0] && main[0].classList) {
- main[0].classList.add('has-toc');
+ if (main && main.classList) {
+ main.classList.add('has-toc');
}
else {
- main[0].className += ' has-toc';
+ main.className += ' has-toc';
}
}
})();
diff --git a/content/assets/stylesheets/_variables.scss b/content/assets/stylesheets/_variables.scss
index 978bf2ce..d3351399 100644
--- a/content/assets/stylesheets/_variables.scss
+++ b/content/assets/stylesheets/_variables.scss
@@ -229,3 +229,5 @@ $facebook-bg: #3b5998;
$twitter-bg: #55acee;
$google-bg: #dd4b39;
$linkedin-bg: #007bb5;
+
+$article-metadata: rgb(110, 110, 110);
diff --git a/content/assets/stylesheets/stylesheet.scss b/content/assets/stylesheets/stylesheet.scss
index b8635318..cf0e206f 100644
--- a/content/assets/stylesheets/stylesheet.scss
+++ b/content/assets/stylesheets/stylesheet.scss
@@ -178,7 +178,9 @@ h6 {
.edit-on {
text-align: center;
-
+ border-top: 1px solid $hr-border-color;
+ padding-top: 20px;
+ margin-top: 15px;
a {
color: $h1-border-bottom;
&::before {
@@ -221,7 +223,7 @@ h6 {
}
p {
- margin: 20px 0;
+ margin: 7px 0;
line-height: 22px;
}
@@ -254,11 +256,7 @@ h6 {
}
.breadcrumbs {
- margin: 0;
-
- li {
- margin-top: 20px;
- }
+ font-style: italic;
.last-updated {
color: $color-light-gray;
@@ -268,6 +266,7 @@ h6 {
}
.header {
+ z-index: 1;
background: $main-background-color;
position: relative;
width: 100%;
@@ -414,6 +413,26 @@ h6 {
}
}
+// Articles layout
+.article-metadata {
+ color: $article-metadata;
+ display: block;
+ order: -1;
+ font-style: italic;
+ margin-bottom: 15px;
+}
+
+.article-content {
+ > h1:first-of-type {
+ display: none;
+ }
+}
+
+// Override bootstrap's alert color
+.alert {
+ color: inherit;
+}
+
// Home page //
.landing {
@@ -559,11 +578,6 @@ h6 {
visibility: hidden;
}
-// Override bootstrap's alert color
-.alert {
- color: inherit;
-}
-
//
// Algolia search for mobile
// https://github.com/algolia/docsearch/issues/181#issuecomment-301730219
diff --git a/content/assets/stylesheets/toc.scss b/content/assets/stylesheets/toc.scss
index 040f6a48..852e3522 100644
--- a/content/assets/stylesheets/toc.scss
+++ b/content/assets/stylesheets/toc.scss
@@ -4,8 +4,22 @@ version: 2
@import "variables";
+.clear {
+ clear: both;
+}
+
+.doc-nav {
+ h4 {
+ padding-bottom: 5px;
+ }
+
+ li > a {
+ font-size: 14px;
+ }
+}
+
// ToC styles
-.breadcrumbs + ul, .doc-nav > ul, .quick-nav ul {
+.doc-nav > ul {
background: $body-background-color;
padding: 20px;
margin-top: 60px;
@@ -20,30 +34,8 @@ version: 2
}
}
-.doc-nav, .quick-nav {
- h4 {
- padding-bottom: 5px;
- }
-
- li > a {
- font-size: 14px;
- }
-}
-
-.clear {
- clear: both;
-}
-
// not wide enough to show quick nav and toc
@media(max-width:1099px) {
- .doc-nav {
- margin: 0 auto;
- padding: 40px 40px 0;
- background: $white;
- width: inherit;
- max-width: 900px;
- }
-
.doc-nav > ul {
margin: 0;
}
@@ -54,10 +46,6 @@ version: 2
margin: 0 auto;
max-width: 900px;
}
-
- .quick-nav {
- display: none;
- }
}
// wide enough to show toc but not quick nav
@@ -79,65 +67,46 @@ version: 2
right: 0;
padding-top: 55px;
overflow-y: scroll;
- height: 100%;
- }
-
- .doc-nav ul ul {
- padding-left: 25px;
+ height: 100vh;
}
- .doc-nav > ul .quick-nav ul {
- margin: 0;
+ .doc-nav-bottom-touching {
+ position: absolute;
}
- .doc-nav, .quick-nav {
- width: 25%;
+ .doc-nav ul ul {
+ padding-left: 25px;
}
}
@media(min-width:1100px) and (max-width:1600px) {
- .quick-nav {
- display: none;
+ .main.class.has-toc {
+ width: 70vw;
+ max-width: 70vw;
+ float: left;
}
.doc-nav {
- width: 30%;
- max-width: 30%;
+ width: 30vw;
+ max-width: 30vw;
}
-
- .main.class.has-toc {
- width: 70%;
- max-width: 70%;
- float: left;
+ .doc-nav-bottom-touching {
+ right: -30vw;
}
}
// wide enough to show quick nav and toc
@media(min-width:1601px) {
.main.class.has-toc {
- width: 50%;
- margin-left: 25%;
- max-width: 50%;
- }
-
- .quick-nav {
- position: fixed;
- top: 0;
- padding-top: 55px;
- left: 0;
- overflow-y: scroll;
- height: 100%;
+ width: 50vw;
+ max-width: 50vw;
+ margin-left: 25vw;
}
- .quick-nav ul ul {
- padding-bottom: 0;
- }
-
- .quick-nav h4 {
- margin-top: 25px;
+ .doc-nav {
+ width: 25vw;
}
-
- .quick-nav h4:first-child {
- margin-top: 10px;
+ .doc-nav-bottom-touching {
+ right: -25vw;
}
}
diff --git a/content/index.erb b/content/index.erb
index 527f62fc..b63b494c 100644
--- a/content/index.erb
+++ b/content/index.erb
@@ -4,7 +4,7 @@ title: GitLab Documentation
<ul class="topics" itemscope itemtype="http://www.schema.org/SiteNavigationElement">
<% @config[:products].each do |name, product| %>
- <% if product[:expose] == true %>
+ <% if product[:expose] == true && @items["/#{product[:slug]}/#{product[:index_file]}"] %>
<li class="topic-<%= product[:slug] %>">
<a href="<%= @items["/#{product[:slug]}/#{product[:index_file]}"].path %>" itemprop="url">
<div class="wrapper">