How to call overwritten methods of parent classes in Backbone.js
When you are working with Backbone models and inheritance, at some point you want to overwrite inherited methods but call the parent's implementation, too.
In JavaScript, there is no simple "super" method like in Ruby -- so here is how to do it with Backbone.
Example
BaseClass = Backbone.Model.extend({
initialize: function(options) {
console.log(options.baseInfo);
}
});
MyClass = BaseClass.extend({
initialize: function(options) {
console.log(options.myInfo);
}
});
ne...
Upgrade guide for moving a Rails app from Webpack 3 to Webpack 4
Webpacker is Rails' way of integrating Webpack, and version 4 has been released just a few days ago, allowing us to use Webpack 4.
I successfully upgraded an existing real-world Webpack 3 application. Below are notes on everything that I encountered.
Note that we prefer not using the Rails asset pipeline at all and serving all assets through Webpack for the sake of consistency.
Preparations
- Remove version locks in
Gemfileforwebpacker - Remove version locks in
package.jsonforwebpackandwebpack-dev-server - Install by ca...
Bootstrap 4 is coming
What's new
- Moved from Less to Sass. Bootstrap now compiles faster than ever thanks to Libsass, and we join an increasingly large community of Sass developers.
-
Improved grid system. We’ve added a new grid tier to better target mobile devices and completely overhauled our semantic mixins.
Opt-in flexbox support is here. The future is now—switch a boolean variable and recompile your CSS to take advantage of a flexbox-based grid system and components. - Dropped wells, thumbnails, and panels for cards. Cards are a brand new co...
Testing focus/blur events with Cucumber
This is a problem when using Selenium with Firefox. We recommend using ChromeDriver for your Selenium tests.
This setup allows to test focus/blur events in Cucumber tests (using Selenium). For background information, see How to solve Selenium focus issues.
Cucumber step definition:
# This step is needed because in Selenium tests, blur events are not triggered
# when the browser has no focus.
When /^I unfocus the "(.*?)" field to trigger ja...
Force absolute URLs in views throughout a response
This is more tricky than it should be because url_for, asset_path, etc. all rely on different mechanisms.
Anyway, you can use the attached trait like this:
class ExampleController < ApplicationController
does 'host_enforcement', :for => 'some_action'
end
Short explanation:
-
asset_hostis used for links to stylesheets and javascripts -
asset_hostbelongs toActionController::Base-- changes are persistent and will not be reset after a request -
rewrite_optionsis used by the..._pathmethods in the views
^...
Spreewald: Content-Disposition not set when testing a download's filename
Precondition
- You are not using javascript tests
- The file is served from a public folder (not via controller)
Problem description
If you deliver files from a public folder it might be that the Content-Disposition header is not set. That's why the following spreewald step might raise an error:
Then I should get a download with filename "..."
expected: /filename="some.pdf"$/
got: nil (using =~) (RSpec::Expectations::ExpectationNotMetError)
Solution
One solution...
Drag'n'drop in trees: I went to town
For my Gem Session project Holly I ran the Ironman of drag'n'drop implementations:
- Dragging in nested lists
- User-definable order of items
- Complicated item elements with super-custom CSS and other Javascript functionality
- Items that can be both leaves and containers of other items
- has_ancestry on the server side
Things I learned:
- Be ready to write a lot of CSS. You need to indicate what is being dragged, where it will be dropped, if it is dropped above, below o...
Test that an exception or error page is raised in Capybara
You can use these step definitions:
Then /^I should not see an error$/ do
(200 .. 399).should include(page.status_code)
end
Then /^I should see an error$/ do
(400 .. 599).should include(page.status_code)
end
Note that you need to tag the scenario with @allow-rescue to test that an error is shown like this
@allow-rescue
Scenario: Accessing the admin area requires a login
When I go to the admin area
Then I should see an error
These step definitions will not work for @javascript scena...
Rails 3: Make "link_to :remote => true" replace HTML elements with jQuery
In Rails 2, you could use link_to_remote ... :update => 'id' to automatically replace the content of $('#id').
To do the same in Rails 3, include usual rails-ujs JavaScript, and put this into your application.js:
$(function() {
$('[data-remote][data-replace]')
.data('type', 'html')
.live('ajax:success', function(event, data) {
var $this = $(this);
$($this.data('replace')).html(data);
$this.trigger('ajax:replaced');...
Clicking issues with chromedriver
ChromeDriver clicking works by simulating a mouse click in the middle of the element's first client rect (or bounding client rect if it doesn't have a first client rect). (Clicking issues)
So if you are trying to click on an element, chromedriver tries to click at the position where it first finds that element.
This can lead to some problems and unexpected behavior like:
-
Element is not clickable at point ...erros - Another element which is now located at...
Make jQuery.animate run smoother with almost no code changes
jQuery comes with .animate() that lets you transition some CSS selectors:
function floatIn($element) {
$element.css({ 'opacity': 0, 'margin-top': 200px });
$element.animate({ 'opacity': 1, 'margin-top': 0 }, { duration: 500 });
}
The animation is implemented using setInterval and Javascript. This works great, but it's not as smooth as a CSS transition.
Fortunately the animate API can be mapped almo...
Cucumber: Wait until CKEditor is loaded
I had to deal with JavaScript Undefined Error while accessing a specific CKEditor instance to fill in text.
Ensure everything is loaded with
patiently do
page.execute_script("return isCkeditorLoaded('#{selector}');").should be_true
end
Example
The fill in text snippet for Cucumber:
When /^I fill in the "([^\"]+)" WYSIWYG editor with:$/ do |selector, html|
patiently do
page.execute_script("return isCkeditorLoaded('#{selector}');").should be_true
end
html.gsub!(/\n+/, "") # otherwise: unterminated string lit...
How to open a new tab with Selenium
Until recently, you could open a new tab via window.open when using execute_script in Selenium tests. It no longer works in Chrome (will show a "popup blocked" notification).
This is because browsers usually block window.open unless the user interacted with an element for security reasons. I am not sure why it did work via Selenium before.
Here is an approach that will insert a link into the page, and have Selenium click it:
path = "/your/path/here"
id = "helper_#{SecureRandom.hex(8)}"
execute_script <<-JAVASCRIPT
...
Looping through iterators in Coffeescript
Some modern Javascript APIs return iterators instead of arrays.
In plain Javascript you can loop through an iterator using
for...of:
var iterator = ...;
for (var value of iterator) {
console.log(value);
}
While there is a for...of construct in Coffeescript, it iterates through property/value pairs and **...
How to make Webpacker compile once for parallel tests, and only if necessary
Webpack is the future. We're using it in our latest Rails applications.
For tests, we want to compile assets like for production.
For parallel tests, we want to avoid 8 workers compiling the same files at the same time.
When assets did not change, we do not want to spend time compiling them.
Here is our solution for all that.
Its concept should work for all test suites.
Copy the following to config/initializers/webpacker_compile_once.rb. It will patch Webpacker, but only for the test environment:
# Avoid hardcoded asset host...
IE7 not properly redrawing elements with position: relative
If you manipulate the DOM with JavaScript and your page contains nested elements with position: relative, chances are Internet Explorer 7 will not properly move to the right position.
I have not found a fool-proof workaround, but these are options that have worked for me:
- Try to lose some
position: relativeattributes, so they do not nest. This is often impossible, though. - Force the correct redrawing of the elements using JavaScript. Adding a bogus class (
$(element).addClass('touch')) seems to suffice. - Try to give the off...
Disable built-in dragging of text and images
Most browsers have built-in drag and drop support for different page elements like text and images. While this may be useful in most situations, it may become annoying in others. If you e.g. want to allow the user to scroll/move horizontally within a container by grabbing an item and moving the mouse, you will notice that nothing will move and you'll instead start dragging that element.
To disable this, add the following CSS to your content:
-webkit-user-drag: none
user-drag: none
-webkit-user-drag is only fully supported in ...
Unpoly 2: Don't try to download files through AJAX requests
Rails has the handy controller method send_file which lets us download files easily. We can decide whether the file should be downloaded (disposition: 'attachment') or shown in the browser (disposition: 'inline'). The default is disposition: 'attachment'.
Downloading files will not work when you are calling the controller action from an AJAX request. The browser will try to render the file and insert it in the DOM, which is never what you want.
Unpoly 2
Unpoly (sin...
AngularJS directive to format a text with paragraphs and new lines
If you are using Angular and want something like Rails' simple_format which HTML-formats a plain-text input into paragraphs and line breaks, this directive is for you.
Any HTML fragments inside that text will still be escaped properly.
Use it like this, where your text attribute specifies something available in your current scope:
<simple-format text="email.message"></simple-format>
This is the directive, in CoffeeScript syntax:
@app.directive 'simpleFor...
When does Webpacker compile?
Webpack builds can take a long time, so we only want to compile when needed.
This card shows what will cause Webpacker (the Rails/Webpack integration) to compile your assets.
When you run a dev server
While development it is recommended to boot a webpack dev server using bin/webpack-dev-server.
The dev server compiles once when booted. When you access your page on localhost before the initial compilation, the page may load without assets.
The ...
Skip Selenium scenarios in a Cucumber run
Cucumber scenarios that are tagged with @javascript so they run with Selenium are very slow. You might not want to run them every time.
In order to skip all Selenium scenarios, call Cucumber like this:
cucumber --tags ~@javascript
Note that you should still run all the scenarios, including the Selenium ones, before you push a change.
Flash-Free Clipboard for the Web
Unfortunately, Web APIs haven’t provided the functionality to copy text to the clipboard through JavaScript, which is why visiting GitHub with Flash disabled shows an ugly grey box where the button is supposed to be. Fortunately, we have a solution. The editor APIs provide document.execCommand as an entry point for executing editor commands. The "copy" and cut" commands have previously been disabled for web pages, but with Firefox 41, which is currently in Beta, and slated to move to release in mid-September, it is becoming available to Ja...
rails/turbolinks
Turbolinks makes following links in your web application faster. Instead of letting the browser recompile the JavaScript and CSS between each page change, it keeps the current page instance alive and replaces only the body and the title in the head.
This is similar to pjax, but instead of worrying about what element on the page to replace, and tailoring the server-side response to fit, we replace the entire body. This means that you get the bulk of the speed benefits from pjax (no recompiling of the JavaScript or CSS) without having to tail...
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.rc12.3.0.alpha23.0.0.beta34.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...