From a1a294049519ea9cba24c554ad0c0ab13731b3f1 Mon Sep 17 00:00:00 2001 From: Josh Barr Date: Mon, 15 Feb 2016 22:31:07 +1300 Subject: [PATCH] fixed font size rounding issue in firefox, added contrib notes --- .scss-lint.yml | 5 +- CHANGELOG.txt | 1 + CONTRIBUTORS.rst | 3 +- docs/topics/writing_templates.rst | 25 +- .../static_src/wagtailadmin/js/userbar.js | 43 ++- .../wagtailadmin/scss/_font-icons.scss | 19 + .../static_src/wagtailadmin/scss/_fonts.scss | 30 +- .../static_src/wagtailadmin/scss/_mixins.scss | 48 ++- .../wagtailadmin/scss/_variables-icons.scss | 86 +++++ .../wagtailadmin/scss/components/_icons.scss | 329 ++---------------- .../static_src/wagtailadmin/scss/core.scss | 8 + .../static_src/wagtailadmin/scss/userbar.scss | 312 ++++++++++++----- .../templates/wagtailadmin/userbar/base.html | 22 +- .../wagtailadmin/userbar/item_admin.html | 6 +- .../wagtailadmin/userbar/item_page_add.html | 6 +- .../userbar/item_page_approve.html | 2 +- .../wagtailadmin/userbar/item_page_edit.html | 2 +- .../userbar/item_page_explore.html | 2 +- .../userbar/item_page_reject.html | 2 +- .../templatetags/wagtailuserbar.py | 4 +- 20 files changed, 496 insertions(+), 459 deletions(-) create mode 100644 wagtail/wagtailadmin/static_src/wagtailadmin/scss/_font-icons.scss create mode 100644 wagtail/wagtailadmin/static_src/wagtailadmin/scss/_variables-icons.scss diff --git a/.scss-lint.yml b/.scss-lint.yml index 43019f6f4d..95fbe2c809 100644 --- a/.scss-lint.yml +++ b/.scss-lint.yml @@ -11,6 +11,7 @@ linters: Indentation: severity: warning width: 4 + # because https://github.com/brigade/scss-lint/issues/409 allow_non_nested_indentation: true character: space @@ -61,7 +62,7 @@ linters: enabled: true ImportantRule: - enabled: true + enabled: false exclude: - '**/_datetimepicker.scss' @@ -92,7 +93,7 @@ linters: # There are regretably quite a few exlusions here, made necessary by # a) the conversion of django field/widget names to underscored class names # b) the use of third party code such as Hallo.js which uses classes with snakeCaseClasses. - exclude: + exclude: - '**/rich-text.scss' - '**/_forms.scss' - '**/_streamfield.scss' diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 37e765c715..065f949259 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -20,6 +20,7 @@ Changelog * Page models now perform field validation, including testing slugs for uniqueness within a parent page, at the model level on saving * Page slugs are now auto-generated at the model level on page creation if one has not been specified explicitly * The `Page` model now has two new methods `get_site()` and `get_url_parts()` to aid with customising the page URL generation logic + * The `edit bird` on the frontend has been redesigned, and no longer depends on an iframe (Thomas Winter, Gareth Price). * New translations for Hungarian, Swedish (Sweden) and Turkish * Fix: Custom page managers no longer raise an error when used on an abstract model * Fix: Wagtail's migrations are now all reversible (benjaoming) diff --git a/CONTRIBUTORS.rst b/CONTRIBUTORS.rst index e8bcc1e444..d13f470f58 100644 --- a/CONTRIBUTORS.rst +++ b/CONTRIBUTORS.rst @@ -107,7 +107,8 @@ Contributors * Nigel Fletton * Kait Crawford * Adam Bolfik - +* Thomas Winter +* Gareth Price Translators =========== diff --git a/docs/topics/writing_templates.rst b/docs/topics/writing_templates.rst index c6b2c1cc94..8e16dc8209 100644 --- a/docs/topics/writing_templates.rst +++ b/docs/topics/writing_templates.rst @@ -4,10 +4,10 @@ Writing templates ================= -Wagtail uses Django's templating language. For developers new to Django, start with Django's own template documentation: +Wagtail uses Django's templating language. For developers new to Django, start with Django's own template documentation: https://docs.djangoproject.com/en/dev/topics/templates/ -Python programmers new to Django/Wagtail may prefer more technical documentation: +Python programmers new to Django/Wagtail may prefer more technical documentation: https://docs.djangoproject.com/en/dev/ref/templates/api/ You should be familiar with Django templating basics before continuing with this documentation. @@ -47,7 +47,7 @@ Static assets ============= Static files e.g CSS, JS and images are typically stored here:: - + name_of_project/ name_of_app/ static/ @@ -57,7 +57,7 @@ Static files e.g CSS, JS and images are typically stored here:: images/ models.py -(The names "css", "js" etc aren't important, only their position within the tree.) +(The names "css", "js" etc aren't important, only their position within the tree.) Any file within the static folder should be inserted into your HTML using the ``{% static %}`` tag. More about it: :ref:`static_tag`. @@ -204,12 +204,23 @@ This tag provides a contextual flyout menu on the top-right of a page for logged ... {% wagtailuserbar %} -By default the User Bar appears in the top right of the browser window, flush with the edge. If this conflicts with your design it can be moved with a css rule in your own CSS files e.g to move it down from the top: +By default the User Bar appears in the bottom right of the browser window, inset from the edge. If this conflicts with your design it can be moved by passing a parameter to the template tag. These examples show you how to position the userbar in each corner of the screen: + +.. code-block:: html+django + ... + {% wagtailuserbar 'top-left' %} + {% wagtailuserbar 'top-right' %} + {% wagtailuserbar 'bottom-left' %} + {% wagtailuserbar 'bottom-right' %} + ... + +The userbar can be positioned where it works best with your design. Alternatively, you can position it with a css rule in your own CSS files, for example: .. code-block:: css - #wagtail-userbar{ - top:200px + .wagtail-userbar { + top: 200px !important; + left: 10px !important; } diff --git a/wagtail/wagtailadmin/static_src/wagtailadmin/js/userbar.js b/wagtail/wagtailadmin/static_src/wagtailadmin/js/userbar.js index 2d6b258236..4722b515d5 100644 --- a/wagtail/wagtailadmin/static_src/wagtailadmin/js/userbar.js +++ b/wagtail/wagtailadmin/static_src/wagtailadmin/js/userbar.js @@ -1,33 +1,54 @@ 'use strict'; -document.addEventListener('DOMContentLoaded', function() { - var trigger = document.querySelector('[data-wagtail-userbar-trigger]'); +document.addEventListener('DOMContentLoaded', function userBar(e) { var userbar = document.querySelector('[data-wagtail-userbar]'); + var trigger = userbar.querySelector('[data-wagtail-userbar-trigger]'); + var list = userbar.querySelector('ul'); var className = 'is-active'; + var hasTouch = 'ontouchstart' in window; + var clickEvent = hasTouch ? 'touchstart' : 'click'; - if ('ontouchstart' in window) { + if (!'classList' in userbar) { + return; + } + + if (hasTouch) { userbar.classList.add('touch'); } else { userbar.classList.add('no-touch'); } - trigger.addEventListener('mouseenter', showUserbar, false); - userbar.addEventListener('mouseleave', hideUserbar, false); - - trigger.addEventListener('touchstart', toggleUserbar, false); + trigger.addEventListener(clickEvent, toggleUserbar, false); // make sure userbar is hidden when navigating back window.addEventListener('pageshow', hideUserbar, false); - function showUserbar() { + function showUserbar(e) { userbar.classList.add(className); + list.addEventListener(clickEvent, sandboxClick, false); + window.addEventListener(clickEvent, clickOutside, false); } - function hideUserbar() { + function hideUserbar(e) { userbar.classList.remove(className); + list.addEventListener(clickEvent, sandboxClick, false); + window.removeEventListener(clickEvent, clickOutside, false); } - function toggleUserbar() { - userbar.classList.toggle(className); + function toggleUserbar(e) { + e.stopPropagation(); + if (userbar.classList.contains(className)) { + hideUserbar(); + } else { + showUserbar(); + } + } + + function sandboxClick(e) { + e.stopPropagation(); + } + + function clickOutside(e) { + hideUserbar(); } }); diff --git a/wagtail/wagtailadmin/static_src/wagtailadmin/scss/_font-icons.scss b/wagtail/wagtailadmin/static_src/wagtailadmin/scss/_font-icons.scss new file mode 100644 index 0000000000..39230e026f --- /dev/null +++ b/wagtail/wagtailadmin/static_src/wagtailadmin/scss/_font-icons.scss @@ -0,0 +1,19 @@ +// The wagtail font isn't available in WOFF2, so a @font-face is set here without a mixin. +@font-face { + font-family: 'wagtail'; + src: url('#{$font-root}wagtail.eot'); + src: url('#{$font-root}wagtail.eot?#iefix') format('embedded-opentype'), + url('#{$font-root}wagtail.ttf') format('truetype'), + url('#{$font-root}wagtail.svg#wagtail') format('svg'), + url('#{$font-root}wagtail.woff') format('woff'); + font-weight: normal; + font-style: normal; +} + +// One exception to the limited font formats used above is the Wagtail icon font for Windows, where using the SVG version improves antialiasing +@media screen and (-webkit-min-device-pixel-ratio: 0) { + @font-face { + font-family: 'wagtail'; + src: url('#{$font-root}wagtail.svg#wagtail') format('svg'); + } +} diff --git a/wagtail/wagtailadmin/static_src/wagtailadmin/scss/_fonts.scss b/wagtail/wagtailadmin/static_src/wagtailadmin/scss/_fonts.scss index b9692ad921..76cf7391c8 100644 --- a/wagtail/wagtailadmin/static_src/wagtailadmin/scss/_fonts.scss +++ b/wagtail/wagtailadmin/static_src/wagtailadmin/scss/_fonts.scss @@ -14,16 +14,6 @@ // // See https://css-tricks.com/snippets/css/using-font-face/ for more information. -@mixin webfont($fontname, $filestub, $weight, $style:normal) { - @font-face { - font-family: '#{$fontname}'; - src: url('#{$font-root}#{$filestub}.woff2') format('woff2'), - url('#{$font-root}#{$filestub}.woff') format('woff'), - url('#{$font-root}#{$filestub}.ttf') format('truetype'); - font-weight: $weight; - font-style: $style; - } -} @include webfont(Open Sans, opensans-light, 300, normal); @include webfont(Open Sans, opensans-regular, 400, normal); @@ -32,22 +22,4 @@ @include webfont(Roboto Slab, robotoslab-regular, 400, normal); @include webfont(Roboto Slab, robotoslab-bold, 700, normal); -// The wagtail font isn't available in WOFF2, so a @font-face is set here without a mixin. -@font-face { - font-family: 'wagtail'; - src: url('#{$font-root}wagtail.eot'); - src: url('#{$font-root}wagtail.eot?#iefix') format('embedded-opentype'), - url('#{$font-root}wagtail.ttf') format('truetype'), - url('#{$font-root}wagtail.svg#wagtail') format('svg'), - url('#{$font-root}wagtail.woff') format('woff'); - font-weight: normal; - font-style: normal; -} - -// One exception to the limited font formats used above is the Wagtail icon font for Windows, where using the SVG version improves antialiasing -@media screen and (-webkit-min-device-pixel-ratio: 0) { - @font-face { - font-family: 'wagtail'; - src: url('#{$font-root}wagtail.svg#wagtail') format('svg'); - } -} +@import 'wagtailadmin/scss/font-icons'; diff --git a/wagtail/wagtailadmin/static_src/wagtailadmin/scss/_mixins.scss b/wagtail/wagtailadmin/static_src/wagtailadmin/scss/_mixins.scss index 3b6b77b080..fe2cc8cb5b 100644 --- a/wagtail/wagtailadmin/static_src/wagtailadmin/scss/_mixins.scss +++ b/wagtail/wagtailadmin/static_src/wagtailadmin/scss/_mixins.scss @@ -1,3 +1,10 @@ +// ============================================================================= +// Mixins +// ============================================================================= + +// Please note that the mixins partial shouldn't include any classes. This is so +// it can be included in any file without accidentally producing output + @mixin clearfix() { &:before, &:after { @@ -11,14 +18,14 @@ } @mixin unlist() { - &, - ul, + &, + ul, li { list-style-type: none; font-style: normal; } - &, + &, ul { margin-top: 0; margin-bottom: 0; @@ -42,7 +49,7 @@ position: absolute; width: 1px; - &:active, + &:active, &:focus { clip: auto; height: auto; @@ -53,9 +60,6 @@ } } -.visuallyhidden { - @include visuallyhidden; -} @mixin visuallyvisible { clip: none; @@ -66,6 +70,32 @@ position: initial; } -.visuallyvisible { - @include visuallyvisible; + +@mixin icon () { + font-family: 'wagtail'; + font-style: normal; + font-weight: normal; + font-variant: normal; + text-transform: none; + speak: none; + text-decoration: none; + width: 1.3em; + line-height: 1em; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + text-align: left; + vertical-align: middle; + margin-right: 0.2em; +} + + +@mixin webfont($fontname, $filestub, $weight, $style:normal) { + @font-face { + font-family: '#{$fontname}'; + src: url('#{$font-root}#{$filestub}.woff2') format('woff2'), + url('#{$font-root}#{$filestub}.woff') format('woff'), + url('#{$font-root}#{$filestub}.ttf') format('truetype'); + font-weight: $weight; + font-style: $style; + } } diff --git a/wagtail/wagtailadmin/static_src/wagtailadmin/scss/_variables-icons.scss b/wagtail/wagtailadmin/static_src/wagtailadmin/scss/_variables-icons.scss new file mode 100644 index 0000000000..afa898126d --- /dev/null +++ b/wagtail/wagtailadmin/static_src/wagtailadmin/scss/_variables-icons.scss @@ -0,0 +1,86 @@ +$icons: ( + 'cogs': 'a', + 'doc-empty-inverse': 'b', + 'doc-empty': 'c', + 'edit': 'd', + 'arrow-up': 'e', + 'arrow-down': 'q', + 'search': 'f', + 'cross': 'g', + 'folder-open-1': 'i', + 'folder-inverse': 'j', + 'mail': 'k', + 'arrows-up-down': 'l', + 'locked': 'm', + 'arrow-right': 'n', + 'doc-full': 'h', + 'file-text-alt': 'h', + 'image': 'o', + 'picture': 'o', + 'unlocked': 'p', + 'doc-full-inverse': 'r', + 'folder': 's', + 'plus': 't', + 'tag': 'u', + 'folder-open-inverse': 'v', + 'cog': 'w', + 'tick': 'x', + 'user': 'y', + 'arrow-left': 'z', + 'tick-inverse': 'A', + 'plus-inverse': 'B', + 'snippet': 'D', + 'wagtail': 'V', + 'wagtail-inverse': '0', + 'bold': 'C', + 'italic': 'E', + 'undo': 'H', + 'repeat': 'I', + 'list-ol': 'G', + 'list-ul': 'F', + 'link': 'J', + 'radio-full': 'K', + 'radio-empty': 'L', + 'arrow-up-big': 'M', + 'arrow-down-big': 'N', + 'group': 'O', + 'media': 'P', + 'password': 'Q', + 'download': 'S', + 'order': 'T', + 'grip': 'U', + 'home': 'W', + 'order-down': 'X', + 'order-up': 'Y', + 'bin': 'Z', + 'spinner': '1', + 'pick': '2', + 'redirect': '3', + 'view': '4', + 'no-view': '^', + 'collapse-down': '5', + 'collapse-up': '6', + 'date': '7', + 'time': '8', + 'success': '9', + 'help': '?', + 'warning': '!', + 'form': '$', + 'site': '@', + 'placeholder': ' {', + 'pilcrow': '\e600', + 'title': '\f034', + 'code': '\e601', + 'openquote': '“', + 'horizontalrule': '\2014' +); + +$icons-after: ( + 'arrow-up': 'e', + 'arrow-down-after': 'q', + 'arrow-right-after': 'n' +); + + + + diff --git a/wagtail/wagtailadmin/static_src/wagtailadmin/scss/components/_icons.scss b/wagtail/wagtailadmin/static_src/wagtailadmin/scss/components/_icons.scss index 26bab4a731..a1ed91cbff 100644 --- a/wagtail/wagtailadmin/static_src/wagtailadmin/scss/components/_icons.scss +++ b/wagtail/wagtailadmin/static_src/wagtailadmin/scss/components/_icons.scss @@ -1,3 +1,5 @@ +@import 'wagtailadmin/scss/variables-icons'; + .icon.teal { color: $color-teal; } @@ -11,20 +13,7 @@ .hallotoolbar [class^='icon-'], .hallotoolbar [class*=' icon-']:before, .hallotoolbar [class^='icon-']:before { - font-family: 'wagtail'; - font-style: normal; - font-weight: normal; - font-variant: normal; - text-transform: none; - speak: none; - text-decoration: none; - width: 1.3em; - line-height: 1em; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - text-align: left; - vertical-align: middle; - margin-right: 0.2em; + @include icon(); // from _mixins.scss } .icon:after, @@ -41,309 +30,51 @@ margin-right: 0; } -.icon-cogs:before { - content: 'a'; -} -.icon-doc-empty-inverse:before { - content: 'b'; -} +// ============================================================================= +// Icon factory methods +// ============================================================================= -.icon-doc-empty:before { - content: 'c'; -} - -.icon-edit:before { - content: 'd'; -} - -.icon-arrow-up:before, -.icon-arrow-up-after:after { - content: 'e'; -} - -.icon-arrow-down:before, -.icon-arrow-down-after:after { - content: 'q'; -} - -.icon-search:before { - content: 'f'; -} - -.icon-cross:before { - content: 'g'; -} - -.icon-folder-open-1:before { - content: 'i'; -} - -.icon-folder-inverse:before { - content: 'j'; -} - -.icon-mail:before { - content: 'k'; -} - -.icon-arrows-up-down:before { - content: 'l'; -} - -.icon-locked:before { - content: 'm'; -} - -.icon-arrow-right:before, -.icon-arrow-right-after:after { - content: 'n'; -} - -.icon-doc-full:before, -.icon-file-text-alt:before { - content: 'h'; -} - -.icon-image:before, -.icon-picture:before { - content: 'o'; -} - -.icon-unlocked:before { - content: 'p'; -} - -.icon-doc-full-inverse:before { - content: 'r'; -} - -.icon-folder:before { - content: 's'; -} - -.icon-plus:before { - content: 't'; -} - -.icon-tag:before { - content: 'u'; -} - -.icon-folder-open-inverse:before { - content: 'v'; -} - -.icon-cog:before { - content: 'w'; -} - -.icon-tick:before { - content: 'x'; -} - -.icon-user:before { - content: 'y'; -} - -.icon-arrow-left:before { - content: 'z'; -} - -.icon-tick-inverse:before { - content: 'A'; -} - -.icon-plus-inverse:before { - content: 'B'; -} - -.icon-snippet:before { - content: 'D'; -} - -.icon-wagtail:before { - content: 'V'; -} - -.icon-wagtail-inverse:before { - content: '0'; -} - -.icon-bold:before { - content: 'C'; -} - -.icon-italic:before { - content: 'E'; -} - -.icon-undo:before { - content: 'H'; -} - -.icon-repeat:before { - content: 'I'; -} - -.icon-list-ol:before { - content: 'G'; -} - -.icon-list-ul:before { - content: 'F'; -} - -.icon-link:before { - content: 'J'; -} - -.icon-radio-full:before { - content: 'K'; -} - -.icon-radio-empty:before { - content: 'L'; -} - -.icon-arrow-up-big:before { - content: 'M'; -} - -.icon-arrow-down-big:before { - content: 'N'; -} - -.icon-group:before { - content: 'O'; -} - -.icon-media:before { - content: 'P'; -} - -.icon-horizontalrule { - &:before { - font-family: Open Sans, Arial, sans-serif; - content: '\2014'; +@each $icon, $content in $icons { + .icon-#{$icon}:before { + content: quote(#{$content}); } } -.icon-password:before { - content: 'Q'; +@each $icon, $content in $icons-after { + .icon-#{$icon}:after { + content: #{$content}; + } } -.icon-download:before { - content: 'S'; // Credit: Icon made by Freepik from Flaticon.com -} -.icon-order:before { - content: 'T'; -} +// ============================================================================= +// Custom config for various icons +// ============================================================================= -.icon-grip:before { - content: 'U'; -} - -.icon-home:before { - content: 'W'; -} - -.icon-order-down:before { - content: 'X'; -} - -.icon-order-up:before { - content: 'Y'; -} - -.icon-bin:before { - content: 'Z'; -} - -.icon-spinner:after { - width: 1em; - animation: spin 0.5s infinite linear; - content: '1'; -} - -.icon-pick:before { - content: '2'; -} - -.icon-redirect:before { - content: '3'; +.icon-download { + // Credit: Icon made by Freepik from Flaticon.com } .icon-view:before, .icon-no-view:before { vertical-align: -3.5px; - font-size: 1.1rem; + font-size: 1.1rem; } -.icon-view:before { - content: '4'; + +.icon-spinner:after, +.icon-spinner:before { + width: 1em; + animation: spin 0.5s infinite linear; + display: inline-block; + // content: '1'; } -.icon-no-view:before { - content: '^'; +.icon-horizontalrule:before { + font-family: Open Sans, Arial, sans-serif; } -.icon-collapse-down:before { - content: '5'; -} - -.icon-collapse-up:before { - content: '6'; -} - -.icon-date:before { - content: '7'; -} - -.icon-time:before { - content: '8'; -} - -.icon-success:before { - content: '9'; -} - -.icon-help:before { - content: '?'; -} - -.icon-warning:before { - content: '!'; -} - -.icon-form:before { - content: '$'; -} - -.icon-site:before { - content: '@'; -} - -.icon-placeholder:before { - content: ' {'; -} - -.icon-pilcrow:before { - content: '\e600'; -} - -.icon-title:before { - content: '\f034'; -} - -.icon-code:before { - content: '\e601'; -} - -.icon-openquote:before { - content: '“'; -} .icon-larger:before { font-size: 1.5em; @@ -366,11 +97,11 @@ } @keyframes spin { - from { + 0% { transform: rotate(0deg); } - to { + 100% { transform: rotate(360deg); } } diff --git a/wagtail/wagtailadmin/static_src/wagtailadmin/scss/core.scss b/wagtail/wagtailadmin/static_src/wagtailadmin/scss/core.scss index 671c082fff..d4714402b0 100644 --- a/wagtail/wagtailadmin/static_src/wagtailadmin/scss/core.scss +++ b/wagtail/wagtailadmin/static_src/wagtailadmin/scss/core.scss @@ -44,6 +44,14 @@ body { } } +.visuallyvisible { + @include visuallyvisible; +} + +.visuallyhidden { + @include visuallyhidden; +} + .capabilitymessage { display: block; background-color: $color-red; diff --git a/wagtail/wagtailadmin/static_src/wagtailadmin/scss/userbar.scss b/wagtail/wagtailadmin/static_src/wagtailadmin/scss/userbar.scss index e18603bc21..40243c288c 100644 --- a/wagtail/wagtailadmin/static_src/wagtailadmin/scss/userbar.scss +++ b/wagtail/wagtailadmin/static_src/wagtailadmin/scss/userbar.scss @@ -1,124 +1,199 @@ @import 'wagtailadmin/scss/variables'; @import 'wagtailadmin/scss/mixins'; -@import 'wagtailadmin/scss/components/icons'; -@import 'wagtailadmin/scss/fonts'; +@import 'wagtailadmin/scss/font-icons'; +@import 'wagtailadmin/scss/variables-icons'; + + +// ============================================================================= +// Variables +// ============================================================================= $size-home-button: 3.5em; +$position: 2rem; +$width-arrow: .6em; +$box-shadow-props: 0 0 1px 0 rgba(107, 214, 230, 1); +$max-items: 12; +$userbar-radius: 6px; -.wagtail-userbar { - position: fixed; - z-index: 9999; - bottom: 2em; - right: 2em; + +// Classnames will start with this parameter, eg .wagtail- +$namespace: 'wagtail'; + +// Possible positions for the userbar to exist in. These are set through the +// {% wagtailuserbar 'bottom-left' %} template tag. +$positions: ( + 'top-left': ( + 'vertical': 'top', + 'horizontal': 'left', + 'arrow': 'bottom' + ), + 'top-right': ( + 'vertical': 'top', + 'horizontal': 'right', + 'arrow': 'bottom' + ), + 'bottom-left': ( + 'vertical': 'bottom', + 'horizontal': 'left', + 'arrow': 'top' + ), + 'bottom-right': ( + 'vertical': 'bottom', + 'horizontal': 'right', + 'arrow': 'top' + ) +); + + +// ============================================================================= +// Fonts +// ============================================================================= + +@include webfont(Open Sans, opensans-regular, 400, normal); + +// ============================================================================= +// Namespaced icon component +// ============================================================================= + +// TODO: refactor into a mixin +.#{$namespace}-icon:before { + @include icon(); } - .wagtail-userbar-trigger { + +// ============================================================================= +// Icons +// ============================================================================= + +@each $icon, $content in $icons { + .#{$namespace}-icon-#{$icon}:before { + content: quote(#{$content}); + } +} + +@each $icon, $content in $icons-after { + .#{$namespace}-icon-#{$icon}:after { + content: #{$content}; + } +} + + +// ============================================================================= +// Wagtail userbar proper +// ============================================================================= + +.#{$namespace}-userbar-reset { + all: initial; +} + +.#{$namespace}-userbar { + position: fixed; + z-index: 9999; + font-size: initial; + line-height: initial; + margin: 0; + padding: 0; + display: block; + border: 0; + width: auto; + height: auto; +} + + .#{$namespace}-userbar-trigger { width: $size-home-button; height: $size-home-button; overflow: hidden; - background-color: $color-white; border-radius: 50%; color: $color-black; padding: 0; - cursor: pointer; - - box-shadow: 0 0 1px 0 rgba(107, 214, 230, 1), 0 1px 10px 0 rgba(107, 214, 230, .7); + box-shadow: $box-shadow-props, 0 1px 10px 0 rgba(107, 214, 230, .7); transition: all 0.2s ease-in-out; - .wagtail-userbar.touch.is-active &, - .no-touch &:hover { - box-shadow: 0 0 1px 0 rgba(107, 214, 230, 1), 0 3px 15px 0 rgba(107, 214, 230, .95); + .#{$namespace}-userbar.touch.is-active &, + .#{$namespace}-userbar.no-touch &:hover { + box-shadow: $box-shadow-props, 0 3px 15px 0 rgba(107, 214, 230, .95); } - &.icon:before { - @include transition(color .2s ease); - font-size: 35px; - margin: .25em .15em .2em .175em; + &.#{$namespace}-icon:before { + transition: color .2s ease; + font-size: 32px; + margin: .4em .15em .4em .375em; display: block; } } - .wagtail-userbar-nav { - $width-arrow: .6em; + .#{$namespace}-userbar-items { + list-style: none; + position: absolute; + margin: 0; + min-width: 210px; + visibility: hidden; + font-family: 'Open Sans', sans-serif; + font-size: 14px; + box-sizing: border-box; + padding-left: 0; - ul { - list-style: none; - position: absolute; - bottom: 100%; - right: 0; - margin: 0; - padding-bottom: $width-arrow * 2; - min-width: 17em; - - visibility: hidden; - - .wagtail-userbar.is-active & { - visibility: visible; - } + .#{$namespace}-userbar.is-active & { + visibility: visible; } + } - // bottom array - ul:after { - content: ''; - position: absolute; - bottom: $width-arrow + .1em; - right: $size-home-button / 2 - $width-arrow / 2; - width: 0; - height: 0; - border-left: $width-arrow solid transparent; - border-right: $width-arrow solid transparent; - border-top: $width-arrow solid $color-grey-1; + // Arrow + .#{$namespace}-userbar-items:after { + content: ''; + position: absolute; + width: 0; + height: 0; + opacity: 0; + border: solid $width-arrow transparent; + transition-duration: .15s; + transition-timing-function: cubic-bezier(.55, 0, .1, 1); - opacity: 0; - transform: translateY(-$width-arrow); - transition-duration: .15s; - transition-timing-function: cubic-bezier(.55, 0, .1, 1); - - .wagtail-userbar.is-active & { - opacity: 1; - transform: translateY(0); - transition-delay: .3s; - } + .#{$namespace}-userbar.is-active & { + opacity: 1; + transform: translateY(0); + transition-delay: .3s; } + } + + + .#{$namespace}-userbar-nav { + background: transparent !important; + padding: 0; + margin: 0; li { background-color: $color-grey-1; - - transform: translateY(1em); opacity: 0; transition-duration: .125s; transition-timing-function: cubic-bezier(.55, 0, .1, 1); &:first-child { - border-top-left-radius: .5em; - border-top-right-radius: .5em; + border-top-left-radius: $userbar-radius; + border-top-right-radius: $userbar-radius; } &:last-child { - border-bottom-right-radius: .5em; - border-bottom-left-radius: .5em; + border-bottom-right-radius: $userbar-radius; + border-bottom-left-radius: $userbar-radius; } + li { border-top: 1px solid darken($color-grey-1, 3%); } - - .wagtail-userbar.is-active & { - transform: translateY(0); - opacity: 1; - - @for $i from 1 through 10 { - &:nth-last-child(#{$i}) { - transition-delay: .05s * $i; - } - } - } } + .#{$namespace}-action { + + background: transparent; + } + + + li a, - li .action { + li .#{$namespace}-action { color: #aaa; display: block; text-decoration: none; @@ -131,29 +206,106 @@ $size-home-button: 3.5em; } } - li .icon { + li .#{$namespace}-icon { position: relative; &:before { position: absolute; top: 50%; transform: translateY(-50%); - left: 1.5em; + left: 14px; } } li a, li input { - font-size: 0.95em; - font-weight: 300; + font-size: 14px; text-align: left; - padding: 0.8em 1.7em 0.8em 3.5em; + padding: 0.8rem 1.7rem 0.8rem 3.5rem; } li input { + // -webkit-appearance: none; + // appearance: none; + // margin: 0; border: 0; background: none; width: 100%; } - } + + +// ============================================================================= +// Userbar positional classes (tl, tr, bl, br) +// ============================================================================= + +@each $pos, $attrs in $positions { + $vertical: map-get($attrs, vertical); + $horizontal: map-get($attrs, horizontal); + $arrow: map-get($attrs, arrow); + + .#{$namespace}-userbar--#{$pos} { + #{$vertical}: $position; + #{$horizontal}: $position; + + .#{$namespace}-userbar-items { + #{$vertical}: 100%; + #{$horizontal}: 0; + padding-#{$vertical}: $width-arrow * 2; + } + + .#{$namespace}-userbar-nav li { + // Yes, we could use an @else, but there's a bug in scss-lint. + @if $vertical == 'bottom' { + transform: translateY(1rem); + } + + @if $vertical == 'top' { + transform: translateY(-1rem); + } + } + + .#{$namespace}-userbar-items:after { + #{$vertical}: 2px; + #{$horizontal}: $size-home-button / 2 - $width-arrow / 2; + border-#{$arrow}-color: $color-grey-1; + + @if $vertical == 'bottom' { + transform: translateY(-$width-arrow); + } + @if $vertical == 'top' { + transform: translateY($width-arrow); + } + } + + &.is-active li { + @for $i from 1 through $max-items { + + @if $vertical == 'bottom' { + $prop: 'nth-last-child'; + } + + @if $vertical == 'top' { + $prop: 'nth-child'; + } + + &:#{unquote($prop)}(#{$i}) { + transition-delay: .05s * $i; + } + } + } + } +} + + +// ============================================================================= +// States +// ============================================================================= + +// Active state for the list items comes last. + +.#{$namespace}-userbar.is-active li { + transform: translateY(0); + opacity: 1; +} + diff --git a/wagtail/wagtailadmin/templates/wagtailadmin/userbar/base.html b/wagtail/wagtailadmin/templates/wagtailadmin/userbar/base.html index a27f2d9228..aaf5df9854 100644 --- a/wagtail/wagtailadmin/templates/wagtailadmin/userbar/base.html +++ b/wagtail/wagtailadmin/templates/wagtailadmin/userbar/base.html @@ -1,15 +1,17 @@ {% load staticfiles i18n %} -
- -
-
{% trans 'Go to Wagtail admin interface' %}
-
    - {% for item in items %} - {{ item|safe }} - {% endfor %} -
+
+
+ +
+
{% trans 'Go to Wagtail admin interface' %}
+
    + {% for item in items %} + {{ item|safe }} + {% endfor %} +
+
+
-
diff --git a/wagtail/wagtailadmin/templates/wagtailadmin/userbar/item_admin.html b/wagtail/wagtailadmin/templates/wagtailadmin/userbar/item_admin.html index ba817755ac..1f67f5d04c 100644 --- a/wagtail/wagtailadmin/templates/wagtailadmin/userbar/item_admin.html +++ b/wagtail/wagtailadmin/templates/wagtailadmin/userbar/item_admin.html @@ -2,7 +2,7 @@ {% load i18n %} {% block item_content %} - + {% endblock %} diff --git a/wagtail/wagtailadmin/templates/wagtailadmin/userbar/item_page_add.html b/wagtail/wagtailadmin/templates/wagtailadmin/userbar/item_page_add.html index 545bdee2e7..f02673c2dc 100644 --- a/wagtail/wagtailadmin/templates/wagtailadmin/userbar/item_page_add.html +++ b/wagtail/wagtailadmin/templates/wagtailadmin/userbar/item_page_add.html @@ -2,7 +2,7 @@ {% load i18n %} {% block item_content %} - + {% endblock %} diff --git a/wagtail/wagtailadmin/templates/wagtailadmin/userbar/item_page_approve.html b/wagtail/wagtailadmin/templates/wagtailadmin/userbar/item_page_approve.html index 04564c7400..ccab7d4a77 100644 --- a/wagtail/wagtailadmin/templates/wagtailadmin/userbar/item_page_approve.html +++ b/wagtail/wagtailadmin/templates/wagtailadmin/userbar/item_page_approve.html @@ -4,7 +4,7 @@ {% block item_content %}
{% csrf_token %} -
+
diff --git a/wagtail/wagtailadmin/templates/wagtailadmin/userbar/item_page_edit.html b/wagtail/wagtailadmin/templates/wagtailadmin/userbar/item_page_edit.html index 492cd39bdb..cabe4e9c99 100644 --- a/wagtail/wagtailadmin/templates/wagtailadmin/userbar/item_page_edit.html +++ b/wagtail/wagtailadmin/templates/wagtailadmin/userbar/item_page_edit.html @@ -2,7 +2,7 @@ {% load i18n %} {% block item_content %} -
+ {% endblock %} \ No newline at end of file diff --git a/wagtail/wagtailadmin/templates/wagtailadmin/userbar/item_page_explore.html b/wagtail/wagtailadmin/templates/wagtailadmin/userbar/item_page_explore.html index 7386b2191c..0a5862eddb 100644 --- a/wagtail/wagtailadmin/templates/wagtailadmin/userbar/item_page_explore.html +++ b/wagtail/wagtailadmin/templates/wagtailadmin/userbar/item_page_explore.html @@ -2,7 +2,7 @@ {% load i18n %} {% block item_content %} -
+ {% endblock %} \ No newline at end of file diff --git a/wagtail/wagtailadmin/templates/wagtailadmin/userbar/item_page_reject.html b/wagtail/wagtailadmin/templates/wagtailadmin/userbar/item_page_reject.html index b8d844cc1c..ae649df659 100644 --- a/wagtail/wagtailadmin/templates/wagtailadmin/userbar/item_page_reject.html +++ b/wagtail/wagtailadmin/templates/wagtailadmin/userbar/item_page_reject.html @@ -4,7 +4,7 @@ {% block item_content %}
{% csrf_token %} -
+
diff --git a/wagtail/wagtailadmin/templatetags/wagtailuserbar.py b/wagtail/wagtailadmin/templatetags/wagtailuserbar.py index 21ed408967..b5b76ddb6e 100644 --- a/wagtail/wagtailadmin/templatetags/wagtailuserbar.py +++ b/wagtail/wagtailadmin/templatetags/wagtailuserbar.py @@ -26,10 +26,11 @@ def get_page_instance(context): @register.simple_tag(takes_context=True) -def wagtailuserbar(context): +def wagtailuserbar(context, position='bottom-right'): # Find request object request = context['request'] + # Don't render if user doesn't have permission to access the admin area if not request.user.has_perm('wagtailadmin.access_admin'): return '' @@ -78,6 +79,7 @@ def wagtailuserbar(context): return render_to_string('wagtailadmin/userbar/base.html', { 'request': request, 'items': rendered_items, + 'position': position, 'page': page, 'revision_id': revision_id })