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:
authorEric Eastwood <contact@ericeastwood.com>2018-02-07 02:16:57 +0300
committerEric Eastwood <contact@ericeastwood.com>2018-02-07 02:30:00 +0300
commita237f294e6dab85779ac20d5aabe891fcdb8ed39 (patch)
tree532fc73c723e2ba2232141f403088d2df8829c30 /content
parent5f3270104b1ab8ba9cc1f84a85182ca56007e5e8 (diff)
Clean up TOC styles and fix bugs
- Clean up unused TOC styles - Fix bug in sticky TOC where if you scrolled down to the bottom to make it sticky, then reduce your viewport width to mobile, the TOC would disappear. - Fix empty TOC covering header on a path without any TOC See https://gitlab.com/gitlab-com/gitlab-docs/merge_requests/182#note_57833460
Diffstat (limited to 'content')
-rw-r--r--content/assets/javascripts/classlist-polyfill.js240
-rw-r--r--content/assets/javascripts/docs.js14
-rw-r--r--content/assets/stylesheets/stylesheet.scss5
-rw-r--r--content/assets/stylesheets/toc.scss100
4 files changed, 286 insertions, 73 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 4d894590..100a0f9b 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);
@@ -43,14 +45,18 @@ 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[0].offsetHeight;
+ }
- if (window.scrollY + sidebarHeight >= main[0].offsetHeight) {
- sidebar.style.position = 'absolute';
+ sidebar.classList.toggle('doc-nav-bottom-touching', isTouchingBottom)
+ if (isTouchingBottom) {
sidebar.style.top = (main[0].offsetHeight - sidebarHeight) + 'px';
} else {
- sidebar.style.position = '';
sidebar.style.top = '';
}
}, { passive : true });
diff --git a/content/assets/stylesheets/stylesheet.scss b/content/assets/stylesheets/stylesheet.scss
index 30cf3519..cf0e206f 100644
--- a/content/assets/stylesheets/stylesheet.scss
+++ b/content/assets/stylesheets/stylesheet.scss
@@ -258,10 +258,6 @@ h6 {
.breadcrumbs {
font-style: italic;
- li {
- margin-top: 20px;
- }
-
.last-updated {
color: $color-light-gray;
font-size: 13px;
@@ -270,6 +266,7 @@ h6 {
}
.header {
+ z-index: 1;
background: $main-background-color;
position: relative;
width: 100%;
diff --git a/content/assets/stylesheets/toc.scss b/content/assets/stylesheets/toc.scss
index 4a1ad2fa..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,29 +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;
- background: $white;
- width: inherit;
- max-width: 900px;
- }
-
.doc-nav > ul {
margin: 0;
}
@@ -53,10 +46,6 @@ version: 2
margin: 0 auto;
max-width: 900px;
}
-
- .quick-nav {
- display: none;
- }
}
// wide enough to show toc but not quick nav
@@ -78,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;
}
}