Tags: web

RSS - Atom - Subscribe via email

Beginner web dev tip: Use Inspect Element to learn more about HTML and CSS on a page

Posted: - Modified: | geek

One of the neat things about learning web development is that the Web is full of examples you can learn from. You can use your browser's View Page Source or View Source command (available from the right-click menu in Google Chrome, Mozilla Firefox, or Internet Explorer). An even better way to explore, though, is to use the Inspect Element action from the right-click menu in those browsers. If you right-click on the item you want to learn more about, you'll be able to see the HTML and the current CSS applied to the page.

I use Google Chrome most of the time, so I'll show you Inspect Element screen in that browser. Here we're looking at the button on CSS-Tricks.com:

2014-11-10 15_37_06-CSS-Tricks.png

You'll see the HTML on the left side and the CSS on the right. You can check or uncheck different CSS rules, and you can double-click on things to edit them. Check out the right-click menus for even more options.

Sometimes you may need to click on a different element in order to see the CSS rules that are relevant to what you're curious about. As you hover over different elements, you'll see them highlighted on the page.

If you click on the Console tab, you can experiment with Javascript too. If you want to view both the inspect element information and the Javascript console at the same time, click on the icon that looks like a > on the right side. This is particularly handy if you have a large screen.

Hope that helps!

First steps towards Javascript testing

Posted: - Modified: | development, geek

I know, I know, it's about time I got the hang of this. Better late than never, right? =) Anyway, I spent some time going through tutorials for QUnit and Jasmine. For QUnit, I followed this Smashing Magazine tutorial on Javascript unit testing. I modified the code a little bit to add the Z timezone to the test data, since my tests initially didn't pass.

test.html

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <title>Refactored date examples</title>
    <link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-1.15.0.css" />
    <script src="http://code.jquery.com/qunit/qunit-1.15.0.js"></script>
    <script src="prettydate.js"></script>
    <script>
     test("prettydate.format", function() {
       function date(then, expected) {
         equal(prettyDate.format('2008/01/28 22:25:00Z', then), expected);
       }
       date("2008/01/28 22:24:30Z", "just now");
       date("2008/01/28 22:23:30Z", "1 minute ago");
       date("2008/01/28 21:23:30Z", "1 hour ago");
       date("2008/01/27 22:23:30Z", "Yesterday");
       date("2008/01/26 22:23:30Z", "2 days ago");
       date("2007/01/26 22:23:30Z", undefined);
     });
     function domtest(name, now, first, second) {
       test(name, function() {
         var links = document.getElementById('qunit-fixture').getElementsByTagName('a');
         equal(links[0].innerHTML, 'January 28th, 2008');
         equal(links[2].innerHTML, 'January 27th, 2008');
         prettyDate.update(now);
         equal(links[0].innerHTML, first);
         equal(links[2].innerHTML, second);
       });
     }

     domtest("prettyDate.update", '2008-01-28T22:25:00Z', '2 hours ago', 'Yesterday');
     domtest("prettyDate.update, one day later", '2008-01-29T22:25:00Z', 'Yesterday', '2 days ago');
    </script>
</head>
<body>
  <div id="qunit"></div>
  <div id="qunit-fixture">
    <ul>
      <li class="entry" id="post57">
        <p>blah blah blah…</p>
        <small class="extra">
          Posted <span class="time"><a href="/2008/01/blah/57/" title="2008-01-28T20:24:17Z">January 28th, 2008</a></span>
          by <span class="author"><a href="/john/">John Resig</a></span>
        </small>
      </li>
      <li class="entry" id="post57">
        <p>blah blah blah…</p>
        <small class="extra">
          Posted <span class="time"><a href="/2008/01/blah/57/" title="2008-01-27T22:24:17Z">January 27th, 2008</a></span>
          by <span class="author"><a href="/john/">John Resig</a></span>
        </small>
      </li>
    </ul>
  </div>
</body>
</html>

For practice, I converted the QUnit tests to Jasmine. The first part of the test was easy, but I wanted a clean way to do the HTML fixture-based tests for prettydate.update too. Jasmine-JQuery gives you a handy way to have HTML fixtures. Here's what my code ended up as:

spec/DateSpec.js

describe("PrettyDate.format", function() {
    function checkDate(name, then, expected) {
        it(name, function() {
            expect(prettyDate.format('2008/01/28 22:25:00Z', then)).toEqual(expected);
        });
    }
    checkDate("should display recent times", '2008/01/28 22:24:30Z', 'just now');
    checkDate("should display times within a minute", '2008/01/28 22:23:30Z', '1 minute ago');
    checkDate("should display times within an hour", '2008/01/28 21:23:30Z', '1 hour ago');
    checkDate("should display times within a day", '2008/01/27 22:23:30Z', 'Yesterday');
    checkDate("should display times within two days", '2008/01/26 22:23:30Z', '2 days ago');
});
describe("PrettyDate.update", function() {
    function domtest(name, now, first, second) {
       it(name, function() {
           loadFixtures('test_fixture.html');
           var links = document.getElementById('qunit-fixture').getElementsByTagName('a');
           expect(links[0].innerHTML).toEqual('January 28th, 2008');
           expect(links[2].innerHTML).toEqual('January 27th, 2008');
           prettyDate.update(now);
           expect(links[0].innerHTML).toEqual(first);
           expect(links[2].innerHTML).toEqual(second);
       });
    }
    domtest("prettyDate.update", '2008-01-28T22:25:00Z', '2 hours ago', 'Yesterday');
    domtest("prettyDate.update, one day later", '2008-01-29T22:25:00Z', 'Yesterday', '2 days ago');
});

jasmine.html

<!DOCTYPE HTML>
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  <title>Jasmine Spec Runner v2.0.2</title>

  <link rel="shortcut icon" type="image/png" href="lib/jasmine-2.0.2/jasmine_favicon.png">
  <link rel="stylesheet" type="text/css" href="lib/jasmine-2.0.2/jasmine.css">

  <script type="text/javascript" src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
  <script type="text/javascript" src="lib/jasmine-2.0.2/jasmine.js"></script>
  <script type="text/javascript" src="lib/jasmine-2.0.2/jasmine-html.js"></script>
  <script type="text/javascript" src="lib/jasmine-2.0.2/boot.js"></script>
  <script type="text/javascript" src="jasmine-jquery.js"></script>

  <!-- include source files here... -->
  <script type="text/javascript" src="prettydate.js"></script>

  <!-- include spec files here... -->
  <script type="text/javascript" src="spec/DateSpec.js"></script>

</head>

<body>
</body>
</html>

I'm looking forward to learning how to use Jasmine to test Angular applications, since behaviour-driven testing seems to be common practice there. Little steps! =)

Emacs: Evaluating Javascript and CSS in Chrome using Skewer Mode

Posted: - Modified: | emacs, geek

I build a lot of quick prototypes, using Javascript and CSS to build little tools on top of the Jive social business platform. Since Javascript syntax errors could prevent the proper loading of the overview page customization screen and require me to reset the overview page through the admin console, my previous Javascript workflow involved copying and pasting code into Google Chrome's developer console. Most of the time, I used narrow-to-region to focus on just the specific script block or set of functions I was working on, and I used js2-mode to handle syntax highlighting and indentation. Once the Javascript was sorted out, I'd widen to get back to the full HTML, JS, and CSS file, using web-mode for indentation.

Copying code between Javascript buffers and the developer console was a bit of a hassle. I'd use C-x h (mark-whole-buffer) to select the buffer, then C-w to copy it, change over to the Chrome window (possibly wading through a number of tabs and windows to find the right one), find the developer console, click in it, paste the code, and run it. My first step was to define a custom function that copied the whole buffer:

(defun sacha/copy-buffer ()
  "Copy buffer contents to kill ring."
  (interactive)
  (kill-new (buffer-substring-no-properties (point-min) (point-max))))
(global-set-key (kbd "C-c w") 'sacha/copy-buffer)

I still had to find the Chrome window and paste the code in, though.

My CSS workflow had its own challenges. I used Inspect Elements to look at CSS properties, and then I modified them on the fly. When I was happy with the rules I added or changed, I wrote the corresponding CSS code in my local file. Because I often ended up modifying several elements, it was hard to remember all the changes I needed to make, apply different sets of changes, or apply the changes after reloading the page. I used Stylish to make some of my changes persistent, but that still involved going back and forth between screens.

Since I'll continue to work on web development over the next year (at least!), I thought I'd invest some time into improving my workflow. I'd seen several demos of Skewer Mode for Emacs, and I'd even given it a try a few times before. I hadn't integrated it into my workflow yet, but it looked like it was definitely worth a try. Skewer allows you to interact with Google Chrome from Emacs. You can send HTML, CSS, and Javascript fragments to your browser.

If you use the included Greasemonkey-compatible script, you can even use this interactive capability on any website. I used the Tampermonkey extension for Google Chrome to run the script. When I tried it on the site I was working on, though, the https/http mismatch resulted in a content security error. It turns out that you need to run chrome --allow-running-insecure-content in order to let Chrome inject HTTPS sites with the scripts from the local HTTP server that Skewer Mode runs inside Emacs. If you had other Chrome sessions open, you'll want to close them before starting up Chrome with that option. Once I sorted that out, it was easy to run skewer-setup, open a JS file, and start sending code to my browser.

I quickly became a fan of how C-c C-k (skewer-load-buffer in JS, skewer-css-eval-buffer in CSS) let me send my buffer to my browser. I narrowed my buffer to the parts I was working on, wrote some tests using console.assert(...), and kept the console visible as I coded. I periodically loaded the buffer to check whether my tests passed. I also liked having a proper file identifier and correct line numbers for errors. (It's amazing how small things matter!)

Then to top it all off, I wanted a function that would prepare the source code for easy pasting into an HTML widget:

<script type="text/javascript">
// filename
</script>

Since Emacs is Emacs, you can do that. =)

(defvar sacha/javascript-test-regexp (concat (regexp-quote "/** Testing **/") "\\(.*\n\\)*")
  "Regular expression matching testing-related code to remove.
See `sacha/copy-javascript-region-or-buffer'.")

(defun sacha/copy-javascript-region-or-buffer (beg end)
  "Copy the active region or the buffer, wrapping it in script tags.
Add a comment with the current filename and skip test-related
code. See `sacha/javascript-test-regexp' to change the way
test-related code is detected."
  (interactive "r")
  (unless (region-active-p)
    (setq beg (point-min) end (point-max)))
  (kill-new
   (concat
    "<script type=\"text/javascript\">\n"
    (if (buffer-file-name) (concat "// " (file-name-nondirectory (buffer-file-name)) "\n") "")
    (replace-regexp-in-string
     sacha/javascript-test-regexp
     ""
     (buffer-substring (point-min) (point-max))
     nil)
    "\n</script>")))

(define-key js2-mode-map (kbd "C-c w") 'sacha/copy-javascript-region-or-buffer)

So now I can fiddle around with Javascript and CSS, send it to my browser with C-c C-k, and then use C-c w to wrap the Javascript in script tags and prepare it for copying.

Emacs!

Learning from things I like: Smashing Magazine's responsiveness

Posted: - Modified: | design

I'm teaching myself design by looking at things I like and trying to figure out why I like them. Smashing Magazine is not only a good blog for design inspiration, but it's also (naturally!) a great example of techniques.

One of the things I like about Smashing Magazine is how the site adapts to different screen sizes. For example, if you view it on a mobile device or in a small window, you'll see a simple header and the story.

2014-07-07 12_45_42-Smashing Magazine — For Professional Web Designers and Developers

The menu icon links to the footer menu, which is used only with narrow screens:

2014-07-07 13_08_53-Coding Archives _ Smashing Magazine

If you have a little more space, the header will include the top-leel site sections (books, e-books, workshops, job board) and the left sidebar will include categories. The search also moves from being hidden behind an icon to having its own space.

2014-07-07 12_45_26-Smashing Magazine — For Professional Web Designers and Developers

Even more space? The left sidebar gets collapsed into a small horizontal menu, and a right sidebar appears with an e-mail subscription form and some highlights from other sections. I wonder why the left sidebar is collapsed into the menu, but I guess it would be weird to have the category list jump from the left sidebar to the right sidebar and then back again, and they probably wanted the e-mail subscription form to be above the fold (so it wouldn't make sense to add it to the left sidebar). The search box is moved to the top of the right sidebar, too, so it looks more like a background element.

2014-07-07 12_45_09-Smashing Magazine — For Professional Web Designers and Developers

Incidentally, here's a little thing that happens when the window is just a little bit narrower – the WordPress menu item gets abbreviated to WP.

2014-07-07 13_05_24-Coding Archives _ Smashing Magazine

 

 

And here's what the site looks like when I maximize the window. There's the header, the left sidebar, and the right sidebar.

2014-07-07 12_44_45-

I also like Smashing Magazine's use of colours – the cool blue matches well with the warm red, for some reason that I can't quite explain at the moment. I also like how they use different grays to make things recede into the background.

When I redesigned my site, I wanted to do something like the responsiveness of Smashing Magazine, so I learned more about using media queries. Here's how my site behaves at different sizes. (Or at least, how it should!) On a small screen, the key links are just hand-drawn icons, and there's no sidebar:

2014-07-07 12_50_57-sacha chua __ living an awesome life - learn - share - scale

Slightly wider? I can add some text to the links, and I can add a couple of optional links like Random.

2014-07-07 12_51_17-sacha chua __ living an awesome life - learn - share - scale

On a normal-sized screen, I add a sidebar on the right side.

2014-07-07 12_51_32-

On a wide screen, I move the post meta information to the left margin.

2014-07-07 12_51_54-sacha chua __ living an awesome life - learn - share - scale

Automating bulk web stuff with iMacros

Posted: - Modified: | geek

I found myself needing to download a whole bunch of JSON data from a server that had a weird authentication thing that Chrome could deal with but wget/curl/Ruby couldn’t. Since my Firefox was on the fritz, I couldn’t use Selenium IDE or the Selenium Webdriver. iMacros to the rescue! (Chrome, Firefox)

2013-11-21 Geek notes - automating bulk web stuff with iMacros

That plus lots of keyboard macros and text manipulation in Emacs, plus a little parsing and regexp substitution in Ruby, plus more Emacs munging got me the data I wanted. Hooray for bubblegum and string scripting!

Library shortcuts

Posted: - Modified: | library

Matt Price e-mailed me about this wonderful piece of wizardry he added to YubNub (which is kinda like a command line for the Web). He set up the tpl command, which searches the Toronto Public Library. This prompted me to finally make YubNub the default handler for my Mozilla Firefox address bar, which you can also do by going to about:config and setting or creating the keyword.URL option to http://yubnub.org/parser/parse?command=

This is good stuff, and one of the many reasons why blogging saves me time and lets me hear about all sorts of interesting things. =) Matt, thanks for sharing!