Bookmarklet to generate a commit message with Pivotal Tracker story ID and title
For clarity and traceability, your commit messages should include the ID and title of the Pivotal Tracker story you're working on. For example:
[#12345] Add Google Maps to user profiles
Optional further commit messages in the body
Also see Howto: Write a proper git commit message
To quickly generate such commit messages, add a new link "Commit" to your bookmarks and use the following Javascript as the link URL:
javascript:(function() { ...
Bookmarklet to generate a Pivotal Tracker story from Zammad Ticket
This is a bookmarklet you can add to Chrome or Firefox which will allow you to create a story in Pivotal Tracker from a Zammad ticket. This might come in handy when creating stories for SWAT Teams.
But first you will have to set two variables in the script below:
-
pt_project_id
: the ID of the Pivotal Tracker Project you want to add stories to. This can be found as part of the URL of the project (https://www.pivotaltracker.com/n/projects/<pt_project_id>
) -
pt_token
: the Pivotal Tracker token used for authentication. Can be found in y...
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...
Webpack: Automatically generating an icon font from .svg files
Over the years we have tried several solution to have vector icons in our applications. There are many ways to achieve this, from SVGs inlined into the HTML, SVGs inlined in CSS, JavaScript-based solutions, to icon fonts.
Out of all these options, the tried and true icon font seems to have the most advantages, since
- icon fonts are supported everywhere
- they perform well and require no JavaScript at all
- their icons align nicely with text
- their icons automatically inherit color and size of the surrounding text
The big issue used to b...
Pre-releasing a Ruby gem
When a Ruby version gem has a letter in its version number, it is considered a pre-release:
1.0.0.rc1
2.3.0.alpha2
3.0.0.beta3
4.0.0.pre.rc2
Even if a pre-release gem has the highest version number, it is never installed unless the user explictily requested the version:
gem install foobar --version="=2.3.0.alpha2"
Also bundle update
will never update a stable version to a pre-release version unless the user explicitly requests it in the Gemfile
:
gem 'foobar', '=2.3.0.alpha2'
A note on Semanti...
makandra/capybara-lockstep
capybara-lockstep can help you with flaky end-to-end tests:
This Ruby gem synchronizes Capybara commands with client-side JavaScript and AJAX requests. This greatly improves the stability of a full-stack integration test suite, even if that suite has timing issues.
How to build a fully custom TinyMCE 5 dialog
TinyMCE is a WYSIWYG editor which is quite customizable.
- Add a custom button to the tinyMCE toolbar and tell tinyMCE to open a dialog with the route to your dialog's view.
tinymce.init({
// ...
toolbar: 'myCustomButton',
setup: function(editor) {
editor.ui.registry.addButton('myCustom Button', {
...
A few recent CSS properties
-
Feature Queries (Edge 12+): Similar to @media queries, @supports blocks can be scoped to browsers that support a given declaration. There is
CSS.supports()
to do the equivalent in Javascript. -
backdrop-filter
(Edge 17+, but not FF): Applying filters to what is visible through an element. -
[
touch-action
](https://d...
Defining "partials" in pure HTML without additional rendering helpers
A while ago I tweeted a thread about how a small JavaScript snippet, one that can fit in a single tweet in fact, can be used to allow defining custom elements purely in HTML. This post will expand on the idea, show how the snippet works, and argue for why you might want to actually use this.
A nice trick that lets you define "partials" in HTML without any additional rendering technology on the server or client.
DOM API for jQuery users
General hints on the DOM
- the root of the DOM is
document
- custom elements inherit from
HTMLElement
. They need a-
(dash) in their name, e.g.<notification-box>
. - event listeners don't have event delegation à la
.on('click', cssSelector, handler)
Comparison
Action | jQuery | DOM API equivalent |
---|---|---|
Find descendant(s) by CSS selector | .find(selector) |
one: `.querySelector(selecto... |
How to: Use Ace editor in a Webpack project
The Ace editor is a great enhancement when you want users to supply some kind of code (HTML, JavaScript, Ruby, etc).
It offers syntax highlighting and some neat features like auto-indenting.
For Webpack 3+
Integrate as described in the documentation. For example load ace Editor like this:
function loadAceEditor() {
return import(/* webpackChunkName: "ace" */ 'ace-builds/src-noconflict/ace').then(() => {
return import(/* webpackChunkName: "ace" */ 'ace-builds/webpack-r...
Haml: Generating a unique selector for an element
Having a unique selector for an element is useful to later select it from JavaScript or to update a fragment with an Unpoly.
Haml lets you use square brackets ([]
) to generate a unique class name and ID from a given Ruby object. Haml will infer a class
attribute from the given object's Ruby class. It will also infer an id
attribute from the given object's Ruby class and #id
method.
This is especially useful with ActiveRecord instances, which have a persisted #id
and will hence **generate the same selector o...
Font Awesome 5 migration guide
Font Awesome version 5 changed some icon names, and introduces new prefixes fab
, far
, and fas
.
There is a JavaScript shim that you can use as a "quick fix". It allows you to keep v4 icon names on v5.
The linked page includes details on using that, and a migration guide including a list of icon renames.
ClockPicker: Android-style time picker for Bootstrap
ClockPicker is a JavaScript and Bootstrap implementation of an Android-style time picker which looks and feels great.
Unfortunately, it is no longer maintained.
Middleman does not fingerprint asset paths by default
We're using Middleman for some static sites like our blog.
Despite being very similar to Rails, Middleman does not add a fingerprint hash to its asset paths by default. This means that when you write this:
<%= javascript_include_tag 'all.js' %>
... you always get the same path, regardless of the contents of all.js
:
<script src='/javascripts/all.js'>
Because browsers tend to cache assets for a while, this means that users might not get your changes until their cac...
object-fit polyfill by lazysizes
All new browsers support the new object-fit
CSS property. It allows to specify how an element behaves within its parent element and is intended for images and videos. The most useful values are contain
(fit-in) and cover
(crop).
Unfortunately, IE does not support this yet. However, if you're already using lazysizes, you can use its object-fit polyfill!
Usage
In your Javascript manifest, require them like this:
#= require plugins/object-fit/ls.obj...
Dynamically uploading files to Rails with jQuery File Upload
Say we want …
- to create a
Gallery
that has a name andhas_many :images
, which in turn have a caption - to offer the user a single form to create a gallery with any number of images
- immediate uploads with a progress bar per image
- a snappy UI
Enter jQuery File Upload. It's a mature library that can do the job frontend-wise. On the server, we'll use Carrierwave, because it's capable of caching images.
(FYI, [here's how to do the u...
Preloading images with CSS
Sometimes you want to preload images that you will be using later. E.g. if hovering over a an area changes its background image, the new image should be preloaded. If you only load it once the user starts hovering, there will be a delay until the background image flips.
The attached article explains how to preload images with only CSS. No Javascript required.
The gist is:
.element:after {
content: url(img01.jpg) url(img02.jpg) url(img03.jpg);
display: none;
}
thoughtbot/fake_stripe: A Stripe fake so that you can avoid hitting Stripe servers in tests.
fake_stripe spins up a local server that acts like Stripe’s and also serves a fake version of Stripe.js, Stripe’s JavaScript library that allows you to collect your customers’ payment information without ever having it touch your servers. It spins up when you run your feature specs, so that you can test your purchase flow without hitting Stripe’s servers or making any external HTTP requests.
We've also had tests actually hitting the testing sandbox of Stripe, which worked OK most of the time (can be flakey).
Manually uploading files via AJAX
To upload a file via AJAX (e.g. from an <input type='file'>
) you need to wrap your params in a FormData
object.
You can initialize a FormData
using the contents of a form:
var form = document.querySelector('form.my-form') // Find the <form> element
var formData = new FormData(form); // Wrap form contents
Or you can construct it manually, param by param:
var fileInput = document.querySelector('form input[type=file]');
var attachment = fileInput.files[0];
var f...
IIFEs in Coffeescript
In JavaScript we often use Immediately Invoked Function Expessions (or IIFEs) to prevent local variables from bleeding into an outside scope:
(function() {
var foo = "value"; // foo is scoped to this IIFE
})();
In Coffeescript an IIFE looks like this:
(->
foo = "value" # foo is scoped to this IIFE
)()
There is also a shorthand syntax with do
:
do ->
foo = "value" # foo is scoped to this IIFE
You can also use do
with arguments t...
Useful tricks for logging debugging information to the browser console
During debugging you might pepper your code with lines like these:
console.log('foo = ' + foo + ', bar = ' + bar)
I recommend to use variable interpolation instead:
console.log('foo = %o, bar = %o', foo, bar)
This has some advantages:
- It's easier to write
- Variables are colored in the console output
- You don't need to stringify arguments so the
+
operator doesn't explode - If the variable is a structured object like a D...
How to render an html_safe string escaped
Once Rails knows a given string is html_safe
, it will never escape it. However, there may be times when you still need to escape it. Examples are some safe HTML that you pipe through JSON, or the display of an otherwise safe embed snippet.
There is no semantically nice way to do this, as even raw
and h
do not escape html_safe
strings (the former just marks its argument as html_safe
). You need to turn your string into an unsafe string to get the escaping love from Rails:
embed = javascript_tag('var foo = 1337;') # This is an h...
Use jQuery's selector engine on vanilla DOM nodes
There are cases when you need to select DOM elements without jQuery, such as:
- when jQuery is not available
- when your code is is extremely performance-sensitive
- when you want to operate on an entire HTML document (which is hard to represent as a jQuery collection).
To select descendants of a vanilla DOM element (i.e. not a jQuery collection), one option is to use your browser's native querySelector
and [querySelectorAll
](https://developer.mozilla.org/de/docs/We...