Material Design Lite

CSS (+ some Javascript) framework, implementing Google's material design for static web pages.

Can be used for plain websites without requiring a full blown Javascript framework, unlike the (also excellent) Polymer paper elements, or Angular material.

Prelimiary impression:

I would recommend against using it at this stage, for a couple of reasons:

  • It is much less complete than you might expect from a CSS framewor...

How to disable auto-complete on login forms

Disabling auto-complete in login forms is probably a bad idea, since it encourages weak passwords.

If you are still forced to implement this (maybe due to legal or policy requirements), this is how:

Prevent browsers from saving the password in the first place. Disabling autocomplete does not improve security.

How to prevent password saving:

To prevent the browser from saving passwords (and usernames), you need to:

  • copy username and password to hidden form fields before submitting the login form
  • c...

SmartUnderline

SmartUnderline is an open-source JavaScript library which uses clever tricks to draw underlines in a more beautiful and readable way.

We've not yet put this into a project, but its effect is very pretty. Please update this card when you use it.

Copy & Paste & The Web | CSS-Tricks

Insanely detailled guide about controlling copy & paste behavior using web technology in 2015.

Note that you can now trigger a copy action through Javascript, no Flash required.

Testing regular expressions visually

Developing complex regular expressions quickly blows my mind. Here are some online regex editors that help you by highlighting matching text and capture groups:

Reverse-proxying web applications with Apache 2.4+

Note: Making a reverse proxy with nginx is much more straightforward.


A reverse proxy is a "man in the middle" server that tunnels requests to another server. You can use for things like:

  • Expose a local service that you cannot directly reach over the internet
  • "Change" the domain or path of a web application by rewriting them on the fly
  • Instantly change servers that respond to a name or ...

Manually trigger a delegated DOM event

When you register a delegated event using on (or the deprecated delegate / live), it is somewhat hard to manually trigger these events manually, e.g. for testing.

After trying jQuery's trigger to no avail, I had success by using native Javascript methods to create and dispatch an event. For instance, to trigger a mousedown event:

element = $('...').get(0);
event = new MouseEvent('mousedown', { view: window, cancelable: true, bubbles: true }...

sessionStorage: Per-window browser storage

All major browsers (IE8+, FF3.5+, Safari 4+, any Chrome) support sessionStorage, a JavaScript storage object that

  • survives page reloads and browser restores,
  • but is different per new tab/window (in contrast to localStorage which is shared across all tabs).

MDN says:

The sessionStorage object is most useful for hanging on to temporary data that should be saved and restored if the browser is accidentally refreshed

Demo

Example usage:

Customizable date (and time) picker: Rome

Datetime picker that offers:

  • simple UI without a specific framework
  • several of customization options
  • allows custom date/time validations

Localization happens via moment.js (which is a Dependency anyway).

However, you won't be happy trying to customize it too much:

  • It does not support full custom templates, you can only set classes of its elements. If you require extra containers, you are out of luck.
  • It offers only a few events, and you can not distinguish if users pick a date, switch to another month, or click outside of the p...

Clusterize.js

Small (1.5 KB) Javascript library that lets you render tables, lists, etc. with hundreds of thousands of items.

How it works is that you move your data set from the DOM into JS. Clusterize than makes sure only the rows in the viewport (and adjacent batches) are rendered.

I believe that AngularUI's data grid component uses a similar technique to reduce the number of bindings in large tables, but I can't seem to find documentation on that.

A solid and unobtrusive plugin for form field placeholders

jquery-placeholder is a simple jQuery plugin that enables form placeholders in browsers that do not support them natively, i.e. IE < 10.

Properties

  • Works in IE6.
  • Automatically checks whether the browser natively supports the HTML5 placeholder attribute for input and textarea elements. If this is the case, the plugin won’t do anything. If @placeholder is only supported for input elements, the plugin will leave those alone and apply to textareas exclusively. (This is the case for Safari 4, Opera 11.00, and possibly other browsers.)
    ...

Make "rake notes" learn about Haml, Sass, CoffeeScript, and other file types

Rails comes with a Rake task notes that shows code comments that start with "TODO", "FIXME", or "OPTIMIZE".

While it's generally not good practice to leave them in your code (your work is not done until it's done), in larger projects you will occasionally have to use them as other parts of the application that you depend upon are not yet available.
To keep track of them, run rake notes. Its output looks something like this:

$ rake notes
app/controllers/fron...

Capybara: Waiting for pending AJAX requests after a test

When ending a Selenium test Capybara resets the browser state by closing the tab, clearing cookies, localStorage, etc.

It may be a good idea to wait for all in-flight AJAX requests to finish before ending a scenario:

  • You may have client-side JavaScript that freaks out when the tab closure kills their pending requests. If that JavaScript opens an error alert or spams errors to the console, your test may fail after the last step.
  • With unlucky timing the server may receive an AJAX request as the browser tab closes, causing a connection ...

Angular: Fixing "Referencing DOM nodes in Angular expressions is disallowed"

Reason

If you are using Coffeescript, it is likely to be the culprit. Since Coffeescript always returns the value of the last expression, it may return DOM nodes:

# coffeescript
scope.focus = ->
  element.focus()

# javascript
scope.focus = function() {
  return element.focus(); // wheee
}

If you e.g. use this function like this, the error will be raised:

<span ng-click="focus()">...</span>

Solution

By adding an explicit return value (e.g. return false), you can Coffees...

Getting permanent links to files on Github or Gitlab

Please don't simply copy line number links from Github. The URL usually contains a branch name like master which will change over time:

https://github.com/makandra/upjs/blob/master/lib/assets/javascripts/up/link.js.coffee#L76

If someone now posts an insertion or deletion to that file into master your link points to the wrong line!

A better way is to press the Y key after clicking on a line number. This will transform the URL to another URL that points to the particular commit:

https://github.com/makandra/upjs/blob/b3b14...

Detecting when fonts are loaded via JavaScript

Webfonts are not always available when your JavaScript runs on first page load. Since fonts may affect element sizes, you may want to know when fonts have been loaded to trigger some kind of recalculation.

Vanilla JavaScript / Modern DOM API

In modern browsers (all but IE and legacy Edge) you can use document.fonts. Use load to request a font and receive a Promise that will be resolved once the font is available. Example:

document.fonts.load('1rem "Open S...

How to create memory leaks in jQuery

jQuery doesn't store information about event listeners and data values with the element itself. This information is instead stored in a global, internal jQuery cache object. Every time you add an event listener or data value to a jQuery object, the jQuery cache gains another entry.

The only way that a jQuery cache entry gets deleted is when you call remove() on the element that put it there!

Since cache entries also have a pointer back to the element that spawned them, it is easy to create DOM elements that can never be garbage-co...

How to create giant memory leaks in AngularJS (and other client-side JavaScript)

This guide shows how to create an AngularJS application that consumes more and more memory until, eventually, the browser process crashes on your users.

Although this guide has been written for Angular 1 originally, most of the advice is relevant for all client-side JavaScript code.

How to observe memory consumption

To inspect the amount of memory consumed by your Javascripts in Chrome:

  • Open an incognito window
  • Open the page you want to inspect
  • Press Shift + ESC to see a list of Chrome processes...

How to detect touch-capable browsers

The easiest way to detect touch-capable browsers is to check for the presence of touch events. It is no 100% solution, but has by far the best cost-benefit ratio. (Know that this does not detect touch devices, but browsers.)

Javascript

var isTouchDevice = 'ontouchstart' in window

Coffeescript

isTouchDevice = 'ontouchstart' of window

On the difference between the Javascript and the Coffeescript version, see [Beware: Coffeescript "in" is not the Javascript "in"](https://makandracards.com/makandra/31073-beware-c...

Beware: Coffeescript "in" is not the Javascript "in"

The Javascript in operator does what Hash#has_key? does in Ruby: Return whether an object has a property.
However, Coffeescript has its own in operator that checks for array inclusion. To check whether an object has a property, use of:

Javascript

'name' in {name: 'Horst'} # => true

Coffeescript

# wrong
'name' in {name: 'Horst'} # => false

# correct
'name' of {name: 'Horst'} # => true
1 in [1,2,3] # => true

True story.

Jasmine: Testing AJAX calls that manipulate the DOM

Here is a Javascript function reloadUsers() that fetches a HTML snippet from the server using AJAX and replaces the current .users container in the DOM:

window.reloadUsers = ->
  $.get('/users').then (html) ->
    $('.users').html(html)

Testing this simple function poses a number of challenges:

  • It only works if there is a <div class="users">...</div> container in the current DOM. Obviously the Jasmine spec runner has no such container.
  • The code requests /users and we want to prevent network interaction in our uni...

Jasmine: Reset the location when testing code that uses pushState / replaceState

When testing code that uses pushState / replaceState, your browser will appear to navigate away from http://localhost:3000/specs (or wherever you run your Jasmine tests). This is inconvenient, since reloading the document will no longer re-run the test suite.

To remedy this, copy the attached file to a place like spec/javascripts/helpers and #= require it from your tests. It will store the current location before every test and reset if afterwards (using location.replaceState).

velesin/jasmine-jquery

This jasmine plugin helps with testing DOM manipulation in two ways:

  1. It gives you DOM-related matchers like toBeVisible() or toHaveCss(css)
  2. It gives you a function to load HTML from fixture files. Without this you would have to manually add elements to <body> and clean up afterwards.

Cucumber: More patience for Selenium features

When running Selenium features with parallel_tests, some browser-server interaction might take longer than usual and the impatient Capybara will not wait enough to see results.

Put the attached file into features/support/ to make Capybara more patient in scenarios tagged @javascript.