/*
DiagnostiCSS
==========================================================

Diagnostic CSS stylesheet that helps visually detect any
potentially invalid, inaccessible or erroneous HTML markup.

DiagnostiCSS highlights the following problems:

* [inline styles](#inline-styles) and [event attributes](#inline-event-attributes)
* [invalid links](#invalid-links)
* [empty](#empty-elements) or [deprecated](#deprecated-elements) elements
* [elements missing required attributes](#images)

Sponsored by [Flatstack](http://flatstack.com/).

*/

@import "modules.css.scss";

/*
Inline Styles
==========================================================

The whole point of CSS is to separate content from its presentation.
Inline styles is a mix of content and presentation.

Writing inline styles is almost the same as writing something like this:

`<font><big><marquee>BOOOOOOOOYA</marquee></big></font>`

However, inline styles are shown as a 'warning' because in real world
applications many JavaScript libraries/components/plugins use inline styles
to accomplish their functionality.

    <p style="font-family: Comic Sans MS, serif">
      Go ahead and do it. Dead or alive, you're coming with me.
    </p>
*/

[style]:not([style=""]) {
  @include warning('Avoid inline styles where possible');
}

/*
Inline Event Attributes
==========================================================

Same here: inline event handlers is a mix of content and behaviour.

You also get much less control over your events:

* you can bind only one event of each kind with inline event attributes,
  so you can't have two `click` event handlers.
* if event handler is specified inline, the JS is specified as a string
  and evaluated when event fires. Evaluation is dangerous.

In short, avoid inline event attributes and handle events via
`addEventListener` API, jQuery, ZeptoJS or something.

    <p onclick="alert('I CAN HAZ INLINE JS')">
      Serve the public trust. Protect the innocent. Uphold the law.
    </p>
*/

[onafterprint], [onbeforeprint], [onbeforeunload],
[onerror], [onhaschange], [onload], [onmessage],
[onoffline], [ononline], [onpagehide], [onpageshow],
[onpopstate], [onredo], [onresize], [onstorage],
[onundo], [onunload],
[onblur], [onchage], [oncontextmenu], [onfocus],
[onformchange], [onforminput], [oninput], [oninvalid],
[onreset], [onselect], [onsubmit],
[onkeydown], [onkeypress], [onkeyup],
[onclick], [ondblclick], [ondrag], [ondragend],
[ondragenter], [ondragleave], [ondragover],
[ondragstart], [ondrop], [onmousedown], [onmousemove],
[onmouseout], [onmouseover], [onmouseup], [onmousewheel],
[onscroll],
[onabort], [oncanplay], [oncanplaythrough],
[ondurationchange], [onemptied], [onended], [onerror],
[onloadeddata], [onloadedmetadata], [onloadstart],
[onpause], [onplay], [onplaying], [onprogress],
[onratechange], [onreadystatechange], [onseeked],
[onseeking], [onstalled], [onsuspend], [ontimeupdate],
[onvolumechange], [onwaiting] {
  @include error('Inline event attributes are definitely a bad idea')
}

/*
Invalid Links
==========================================================

#### Links without (or empty) href attribute

    <a>The Old Man</a>
    <a href="">Bob Morton</a>
*/

a:not([href]), a[href=""] {
  @include error('Link without (or empty) href attribute');
}

/*
#### Links with questionable `href` attribute (`#`, `javascript:;`)

`href` attribute specifies the URL of the page the link goes to.
However, `#` and `javascript` URLs will take you nowhere.

Please use more appropriate elements instead: `<button>` for actions,
something like `<span class="more-examples">` for pseudo-links.

    <a href="#">Dick Jones</a>
    <a href="javascript:;">Sergeant Warren Reed</a>
*/

a[href="#"], a[href^="javascript"] {
  @include warning("Link with questionable href attribute (" attr(href) ")");
}

/*
#### Links with `target` attribute

Does your website really should make the choice for visitor about
where and how to open the link?

However, such links are shown as a 'warning' because there are
some practical uses for this attribute: links to PDFs, help files
of additional information.

    <a href="http://www.omnicorp.com/" target="_blank">ED-209</a>
*/

a[target] {
  @include warning("Link with target attribute (" attr(target) ")");
}

/*
Empty Elements
==========================================================

Why do you need an empty `<li>` or `<p>`?


    <ul>
      <li></li>
    </ul>

    <p></p>

Instead of empty `<td>` or `<th>` you should use `colspan` attribute.

    <table>
      <tr>
        <th>Foo</th>
        <th>Bar</th> <!-- use colspan="2" instead -->
        <th></th>
      </tr>
      <tr>
        <td></td>
        <td>Baz</td>
        <td>Boo</td>
      </tr>
    </table>
*/

li:empty, p:empty, td:empty, th:empty {
  @include warning("Empty element");
}

/*
Images
==========================================================

Images with no `alt` attribute are bad for accessability,
your karma, and teeth.

    <img src="http://placekitten.com/400/200" width="400" height="200" />
*/

img:not([alt]) {
  outline: $error!important;
}

/*
Browsers give image elements a default size if they do not
have explicit width and height attributes. Once these images
have loaded, they expand or contract to their full size,
causing all other elements on the page to reflow in response.

    <img src="http://placekitten.com/400/200" alt="nice kitten" />
*/

img:not([width]):not([height]) {
  @extend %warning;
}

/*
Forms & Inputs
==========================================================

Always set `type` and `name` attributes for `input`,
`rows` and `cols` attributes for `textarea`. Also
don't forget about specifing correct `for` attribute
for `label`.


    <div>
      <input value="Input with no type">
    </div>
    <div>
      <textarea>Textarea without rows and cols</textarea>
    </div>
    <div>
      <input type="text" value="Input with no name">
    </div>
    <div>
      <input type="text" name="" value="Input with empty name">
    </div>
    <div>
      <input type="submit"> <!-- submit with no value -->
    </div>
    <div>
      <label>Label with no for</label>
    </div>
    <div>
      <label for="">Label with empty for</label>
    </div>
*/

input:not([type]) {
  @extend %error;
}

textarea:not([rows]):not([cols]) {
  @extend %error;
}

input:not([name]), input[name=""],
select:not([name]), select[name=""],
textarea:not([name]), textarea[name=""] {
  @extend %error;
}

input[type="submit"]:not([name]) {
  outline: none;
}

input[type="submit"]:not([value]),
input[type="submit"]:not([name]):not([value]) {
  @extend %error;
}

label:not([for]), label[for=""] {
  @include warning("Missing for attribute");
}

/*
Deprecated Elements
==========================================================

Older HTML tags that have been superseded by other more functional
or flexible alternatives (whether as HTML or as CSS ) are declared as deprecated.
Browsers should continue to support deprecated tags and attributes,
but eventually these tags are likely to become obsolete and
so future support cannot be guaranteed.

    <blink>Thank you for your cooperation. Good night.</blink>
*/
acronym, applet, basefont, bgsound, big, center, dir, font,
frame, frameset, isindex, listing, multicol, nextid, nobr,
noembed, noframes, plaintext, rb, spacer, strike, tt, xmp,
marquee, blink {
  @include error("Deprecated element");
}

/*
Print Stylesheets
==========================================================

It's always a good idea to hide all `<form>`s in printing
stylesheet.

*/
@media print {
  form {
    outline: $error;
  }
}
