Wednesday, December 10, 2014

unix/osx find

To find files in (and below) the current path, less than 14 days old:

find . -mtime -14 
Older would be +14. More variants here, including date ranges, minute-level stuff, etc.

Thursday, November 27, 2014

css spritesheets

CSS spritesheets, putting a bunch of images in one big image (so that http round trips are minimized) and then using CSS to just show the correct image subset of the full sheet, is a good trick to know about. (I suddenly started wondering if advances in the http protocol would make them less crucial, and allow multiple files to be downloaded in one gulp, so to speak.. googling to check that out brought me to a page saying you should embed images as encoded text in the CSS which seems to be taking it a bit too far!)

Anyway, I found it convenient to use good ol' ImageMagick. This page goes into some detail, but the net-net was doing:
convert img1.png img2.png img3.png -append spritesheet.png
was all I needed. That gave me a single .png with all the images in a vertical stack. I then made a quick perl script to generate the css, something like
.img {
    background-image: url('spritesheet.png');
       background-position: 0px 0px
       background-position: 0px -50px

(I had 25 of these to do). The important thing here is the offset, which is increasingly negative for each subsequent image.

The HTML was then something like
<div class="img thing1"></div>
<div class="img thing2"></div>
This raises best practices / style questions. W3Schools recommends using the img tag with a placeholder for the src (lest your html be invalid), ala:
<img class="thing1" src="img_trans.gif">
I see that it's kind of cool to keep things an image (even better would be list item tags or other semantically meaningful html tags) but going back to the old "transparent GIF" placeholder thing gives me the creeps!

Also you can run your generated file through an online image compressor... and there are even other online tools to smush the image together and give you the resulting CSS.


One of those things I grew up living with out (because it didn't exist in most browsers) and so don't always think of: localStorage is trivial to use in modern browsers, and provides decent support when you want to store some state across sessions, but don't want to make up a backend server to support it.

You have to be ok with not getting state back if the user is using a different device or browser, but then again, that's always true unless you've actually made some kind of server-side account system. (Which also has UX implications, in terms of a lot of people have "make an account to use this fatigue". And also "link to my FB account" fatigue.)

Anyway, window.localStorage; it's just sitting there, waiting for you, with old Old Skool messing with cookies.
and later
or you can even use array-like syntax:

The only caveat it is many or all browsers will coerce your data to a string, so most likely you want something like
localStorage.setItem("someKey", JSON.stringify(someThing));
someThing = JSON.parse(localStorage.getItem("someKey"));
(with an appropriate safety checks)

Sunday, November 16, 2014

yosemite fullscreen

Even though it was reviled as being inconsistent and unpredictable, I preferred the old OSX "zoom" button behavior, where it (kinda sorta) maximized the window within the context of the current set of windows over the new "take over the whole screen world" pattern it has in Yosemite. I often want a bit more real estate for a given window, and rarely am I thinking "boy I wish I was looking at this window AND NOTHING ELSE MATTERS IN MY COMPUTER'S WORLD".

Besides predictability (especially when resizing browsers; some people found it odd that it didn't always try to be as wide as possible) I suppose Apple is trying to catch an iOS-like sense of "focus on this one thing" monotasking, and so they hide the dock and title bar. Personally, I think this is a UX misthink; a flavor of multitasking (or at least quick task switching) is fundamental to many people's use of a laptop or desktop.

(I like how Windows 7 did it; the window still takes up the full screen, but then you can reposition it)

Anyway, you can hold "option" when you click the green circle, and then gets the old zoom behavior; I just wish there was a way to switch which one was the default.

Friday, November 14, 2014

friday 5:30 pm kinds of problems and shaking old habits

One problem with being in the industry a decade and a half or so is that old habits die hard.

FOR EXAMPLE, I suspect some possible future employers will be thinking I'm a cave-dwelling Netscape 4.7 barbarian unless I go refactor out the use <table> for layout purposes on those sites I wrote in 2005 or so.

(THAT SAID, CSS only recently is anywhere near caught up with tables in its ability to position multiple objects relative to each other- the fact that this page on fluid width equal height columns even suggests monstrosities such as
margin-bottom: -99999px; 
padding-bottom: 99999px;
points to some serious limitations! (That hopefully flexbox et al will be resolving...) But really, I think <table> is a shibboleth, since if you're using <div> for display, you're pretty far from the html5 dream of the Semantic web anyway..)

ANYWAY. Old habits. One was in my use of console.log(). Earlier versions of it weren't very smart, it would just cast everything to a string.  And so I developed habits of doing stuff like this:
console.log("the thing is "+JSON.stringify(thing));
but that of course meant I would miss out on chrome's ability to display the object in the console in clever, expandable way.
But console.log happily also takes multiple arguments now too! So you can do
console.log("the thing is ", thing);
which is the best of all worlds; getting rid of JSON.stringify() cruft, having an expandable view of thing, and still having a human readable caption.

FINALLY, before I realized/remembered about how flexible chrome's console.log() is, I learned the hard way that JSON.stringify() on a variable set to a function gets very weirdish results. Just don't do it. I thought I was going nuts with my ability to curry a function until I realized it was because I was throwing JSON.stringify() into the mix.

Thursday, November 13, 2014

getting closure

Just a reminder about Self Excuting Anonymous Functions.. they're a great way to avoid polluting a page's global name space if you are making a script to be included on someone else's page (like in the window.onload event, where you don't want to leave a remnant.)

Some code I did today had bits like this:

(function (){
var oldOnLoad = window.onload;
window.onload = function(e){
if(typeof oldOnLoad  == "function"){

That was a decent way to not overwrite any existing window.onload code, but oldOnLoad isn't in the global space, because of the use of the closure.