We were doing it this way because managers usually have the management
section open at all times. However, this might not always be the case,
and by opening links in a new tab, we're taking control away from them.
If managers would like to keep the management section open, they can
open the link in a new tab, and if they open it in the same tab, they
can go back to the management section by either clicking the browser's
back button or clicking on the navigation link to the management
section.
Note that, unlike what we did in the admin section we're opening links
to budget investments on the same tab. There are two reasons for it; the
first one is that, in this case, there are no filters in the moderation
section that are lost after editing an investment, and the second one is
that, in this context, administrators usually don't go to the investment
in order to edit it, so they can just check something and use the
browser's back button to go back.
In the admin section, when clicking on a link that leads to a page in
the public area, sometimes the page was opened in the same window and
sometimes it would open in a new window, with no clear criteria
regarding when either scenario would take place.
This was really confusing, so now we're more consistent and open
(almost) every link in the same window. The main reason behind it is
simple: if we add `target: _blank`, people who want to open those links
in the same window can no longer do so, so we're taking control away
from them. However, if we don't add this attribute, people can choose
whether to open the link on the same tab or to open it on a new one,
since all browsers implement a method to do so.
More reasons behind this decision can be found in "Opening Links in New
Browser Windows and Tabs" [1].
We're keeping some exceptions, though:
* Opening the link to edit an investment on the same tab would result in
losing all the investment filters already applied when searching for
investments, so until we implement a way to keep these filters, we're
also opening the link to edit an investment in a new tab
* For now, we're also opening links to download files in a new window;
we'll deal with this case in the future
[1] https://www.nngroup.com/articles/new-browser-windows-and-tabs/
We were opening these links in a new tab/window because we assume they
were external links.
But, on the one hand, we don't even know whether these links are
external, since they could also point to URLs from our site. And, on the
other hand, opening external links in new windows results in usability
issues as well [1, 2].
On top of that, old browsers have security issues when opening links in
new tabs unless we add `rel="noopener"` [3], and we aren't doing so.
[1] https://www.nngroup.com/articles/new-browser-windows-and-tabs
[2] https://css-tricks.com/use-target_blank
[3] https://mathiasbynens.github.io/rel-noopener/
Out of the usability issues I've experienced when using Consul
Democracy, the biggest one has arguably been the fact that the link to
edit a proposal opens in a new tab. I guess the reasoning behind it is
that the page to edit a proposal is not part of the proposals dashboard,
but what the hell! Imagine if every link to edit something opened in a
new tab...
So we're reducing the impact of this nonsense by opening most dashboard
links in the same window; for now, we're still opening in a new window
links to download files and links that might point to external websites.
We'll address those ones in the future.
Most screen readers don't notify when a link is about to open in a new
window [1], so we're indicating it, like we were already doing in most
places with similar links.
We could also add a visual indicator, but since links inside labels
already have accessibility issues, giving more attention to these links
might make matters worse.
[1] https://www.powermapper.com/tests/screen-readers/navigation/a-target-blank/
IMHO the best solution would be to completely remove this checkbox on
forms that require registration. Other than the fact that people have
already agreed with these terms when registering (although I guess these
terms might have changed since then) and that approximately 0% of the
population will read the conditions every time they agree with them,
there's the fact that these links are inside a label and people might
accidentally click on them while trying to click on the label in order
to check the checkbox.
I guess the idea is that these conditions might have changed since the
moment people registered. In a fair world, checking "I agree" would have
no legal meaning because it's unreasonable to expect that people will
read these conditions every time they fill in a form, so whatever we're
trying to do here would be pointless.
But, since I'm not sure about the legal implications of removing this
field in a world where you have to inform people that websites requiring
identification use cookies, for now the field will stay where it is.
In some places, we were using `blank` instead of `_blank`. Most browsers
treat `blank` like `_blank`, though, so most people didn't experience
any difference.
In another place, we were incorrectly passing the `target` option inside
an `options:` hash, resulting in invalid HTML.
Quoting usability experts Jakob Nielsen and Anna Kaley [1]:
> [Opening PDF files in new tabs] is problematic, because it assumes
> users will always do the exact same things with certain file formats,
> which isn’t always the case.
There are many examples of this situation. For example, some people
(myself included) configure their browser so it downloads PDF files
instead of opening them in the browser. In this situation, a new tab is
opened, a blank page is displayed, the file is downloaded, and then
either the tab is closed or the blank page needs to be manually closed.
The end result is really annoying.
Other situations include people who use a mobile phone browser, where
navigating through tabs is generally much harder than doing so on a
desktop browser.
But IMHO the most important point is: every browser already provides a
way to open "regular" links in a new tab, so people can choose what to
do, but if we decide to open the link in a new tab, we take control away
from them, and people who'd like to open the link in the same tab might
feel frustrated.
In these cases, the links either say "download" or include the word
"PDF", so people know in advance that they're going to download/open a
PDF file, and so we're giving them information and, by removing the
`target` attribute, we're giving them control over their browser so they
can choose what's convenient for them.
[1] https://www.nngroup.com/articles/new-browser-windows-and-tabs
We were displaying documents in five places, and in five different ways.
Sometimes with the metadata in parenthesis after the title, sometimes
with the metadata below the title, sometimes without metadata, sometimes
with an icon in front of the document, and sometimes with a separate
link to download the file.
So we're now displaying the same thing everywhere. Not sure whether this
is the best solution, but at least it's consistent.
We aren't unifying the way we display a list of documents, though, since
different sections look pretty different and I'm not sure whether the
same style would look well everywhere.
Note that we're renaming the `document` HTML class in the documents
table to `document-row` so the styles for the `document` class don't
apply here.
This way it'll be easier to change them.
Note that there were two `.document-link` elements which aren't part of
a `.documents` element. We're renaming the HTML class of the link in
investments because it didn't contain links to download documents and
are slightly duplicating the CSS in the poll answer documents in order
to keep the `word-wrap` property.
Using the `document` or `documents` classes meant styles defined for the
public list of documents conflict with these ones.
So now we're using HTML classes that match the name of the Ruby
component classes, as we usually do.
We were adding <div> tags with the `images` or `documents` HTML class
prettly much every time we rendered a NestedComponent. We're now
including the HTML class inside the component, as we usually do.
We're also rendering the nested components directly, since it's been a
while since the partials were changed to simply render the components.
We aren't using <hr> tags on any forms containing fields to add/edit
documents, so using this in the dashboard actions form and the
legislation process form was inconsistent.
We were using a "Download file" link in one place, while in another
place we had an additional column where the name of the document was a
link to download it.
There's a link next to it that does the exact same thing and includes
the word "download", which was confusing in some cases since people
might think that links with different texts lead to different pages.
Other packages depend on jQuery, so that's why these are the first one
we move from the Gemfile to the package.json file.
This way we can also test whether dependabot correctly opens pull
requests to update Node packages.
I've tried several configuration options for the asset pipeline in order
to be able to include images referenced in jQuery UI CSS files. So far,
adding the `node_modules/jquery-ui/themes/base` folder to the assets
paths is the only way I've found to make it work. Hopefully we can find
a better solution in the future so we don't have to study the internals
of every Node package in order to integrate it with the assets pipeline.
This way we make it easier to modify.
Note that, since the title of the page is "Administration" and it's in
the "Admin" section, we're adding an option to the `header` method in
order to avoid having a confusing title like "Administration - Admin".
Also note that, by removing the `title` HTML class, we avoid inheriting
styles from the `dashboard.scss` stylesheet, and now the heading is
displayed in the position it was meant to.
Finally, the concept of using a `main-class` for the current page comes
from a branch (currently in development) which will replace the <div>
tag with the `admin-content` class with a `main` tag.
We were displaying the alt text using the same color as the background
color, which made it impossible to read it when the logo didn't load
(for whatever reason).
Using the same color as the text, like done in the admin section, solves
the issue.
Not all the colors initialjs uses by default provide enough contrast
against a white text. The default initialjs colors are:
["#1abc9c", "#16a085", "#f1c40f", "#f39c12", "#2ecc71", "#27ae60",
"#e67e22", "#d35400", "#3498db", "#2980b9", "#e74c3c", "#c0392b",
"#9b59b6", "#8e44ad", "#bdc3c7", "#34495e", "#2c3e50", "#95a5a6",
"#7f8c8d", "#ec87bf", "#d870ad", "#f69785", "#9ba37e", "#b49255",
"#b49255", "#a94136"]
We're replacing them with colors containing less luminosity when
necessary in order to get a 4,5:1 contrast (it could be argued that a
3:1 contrast is enough when the icons are big, but that isn't always the
case and more contrast doesn't hurt):
["#16836d", "#12826c", "#896f06", "#a06608", "#1e8549", "#1e8549",
"#b35e14", "#c75000", "#207ab6", "#2779b0", "#de2f1b", "#c0392b",
"#9b59b6", "#8e44ad", "#6c767f", "#34495e", "#2c3e50", "#66797a",
"#697677", "#d82286", "#c93b8e", "#db310f", "#727755", "#8a6f3d",
"#8a6f3d", "#a94136"]
Since initialjs doesn't provide a way to change these colors using
JavaScript, we're changing them in Ruby, following the same algorithm
used by initialjs.
The color we were using didn't have enough contrast against a white
background, which made it harder to read texts like "Remove map marker"
or "Erase my account".
Since the new color is almost identical to the color we were using on
hover and for the border, we're changing the color on hover as well,
while IMHO it's no longer necessary to use a different color for the
border.
The Web Content Accessibility Guidelines version 2.1 added a success
criterion called Non-text Contrast [1], which mentions that the focus
indicator must contrast with the background, and version 2.2 introduced
a specific one regarding focus appearance [2]. According to that
criterion, the focus indicator:
* is at least as large as the area of a 2 CSS pixel thick perimeter of
the unfocused component or sub-component
* has a contrast ratio of at least 3:1 between the same pixels in the
focused and unfocused states.
Our current solution for highlighting elements on focus has a couple of
issues:
* It doesn't offer enough contrast against the default white background
(1.6:1)
* It offers even less contrast against other backgrounds, like the
homepage banner or the featured proposals/debates
Making the color of the outline darker would increase the contrast
against these backgrounds, but it would reduce the contrast against
other backgrounds like our default brand color.
For this reason, most modern browsers use a special double outline with
two different colors [3], and we're choosing to combine an outline and a
box shadow to emulate it, using the brand color as the second color.
However, this double-colored outline doesn't work so well when focusing
on dark buttons surrounded by a light background, so instead we're using
a triple outline, which works well on any color combination [4]. Since I
feel that making the third outline 2px wide makes the overall outline
too wide, I'm making the inner outline just 1px wide since that's enough
to prevent edge cases.
Note that Foundation adds a transition for the `box-shadow` property on
`select` controls, which gets in the way of the focus we use on the
language selector. So we're removing the transition.
Also note that the box-shadow style didn't work properly with the
box-shadow we added on the `:hover` status on cards, so we're changing
the code in order to cover this case.
Finally, note that the box-shadow isn't displayed properly on multiline
links (in Chrome, not even with `box-decoration-break: clone`), like the
ones in debates/proposals/polls/investments/processes titles, so we're
changing the style of these links to `inline-block`.
[1] https://www.w3.org/TR/WCAG21/#non-text-contrast
[2] https://www.w3.org/TR/WCAG22/#focus-appearance
[3] https://www.sarasoueidan.com/blog/focus-indicators/#examining-(current)-browser-focus-indicators-against-wcag-requirements
[4] https://www.erikkroes.nl/blog/the-universal-focus-state/
In some cases, like SDG icons and the proposals map, the image was
bigger than the link containing it, resulting in a funny-looking outline
on focus.
For reasons I don't understand, using `&:active,&:focus:active` didn't
compile to the CSS I was expecting, so I'm repeating the same code for
these two separate cases.
The outline was invisible when we had the link containing block
elements, and I didn't manage to fix it, so the easiest solution is to
use an inline link and style the card with CSS.
This way it's going to be easier to style the link on focus, since
styles like `box-shadow` weren't working properly when we had an inline
link with block elements inside, and adding the `display: inline-block`
element to the link didn't play well with the layout we were using for
the recommendations.
We're also fixing the focus outline on recommendations, which didn't
look properly because of the border added with:
```
.recommended-index {
// (...)
@include full-width-border(top, 1px solid #fafafa);
}
```
The border was on top of the outline, breaking it. Increasing the
`z-index` of the element containing the outline solves the issue.
In a similar way, we're making sure the button to hide recommendations
stays visible so it's easier to click it.
As far as possible I think the code is clearer if we use CRUD actions
rather than custom actions. This will make it easier to add the action
to remove votes in the next commit.
Note that we are adding this line as we need to validate it that a vote
can be created on a comment by the current user:
```authorize! :create, Vote.new(voter: current_user, votable: @comment)```
We have done it this way and not with the following code as you might
expect, as this way two votes are created instead of one.
```load_and_authorize_resource through: :comment, through_association: :votes_for```
This line tries to load the resource @comment and through the association
"votes_for" it tries to create a new vote associated to that debate.
Therefore a vote is created when trying to authorise the resource and
then another one in the create action, when calling @comment.vote.