Responsive Image Maps - Generator and jQuery Plugin

Bottom line, I need to do an image map in a responsive website.

First, I found this lovely image map generator. It is simple and works very well. It's good enough that I actually gave him a few bucks.

http://www.image-maps.com

The resulting <map> worked right away.

Then I started working on the real website. The image loads in a size relative to the browser window's size. The image map was out of alignment. I quickly realized the problem and googled Responsive Image Maps.

I found this:

https://github.com/stowball/jQuery-rwdImageMaps

I groaned. I hate adding dependencies and even more, I hate figuring out how to work new stuff that I'm probably not going to use again (this is the first image map I've used in years and once this project ends, probably the last for a long time). But, I did it.

The learning curve was ZERO.

I added the plugin. Copied his sample initialization and it worked perfectly the first time.

Win!!

Tape Suppresses console.log() and Makes Debugging Difficult

I was seduced, eg [1], by the fact that the Tape (the "tap-producing test harness for node and browsers") unit testing tool does less. Not only does it not litter your Javascript universe with globals, it does a lot less magic stuff.

I am in the early stages of a new project and decided to do the right thing and test everything from the first moment. Having been irritated by the amount of arcane stuff in Mocha, I drank the koolaid and rewrote my starter testing for Tape.

Bad move.

Tape is simple to use but, when I started doing real development and a new test didn't run, I needed to debug and couldn't.

Turns out that Tape suppresses console.log(), process.exit(), etc. Of course, there are other ways to debug Javascript, but I am a fan of print-trace, ie, console.log() and you cannot use console.log() with Tape.

Searching the web, I found that this is not something that is not something that is noted very often. I don't know why. If I had known this, I would not use Tape. In fact, I am going to revert to using Mocha. The elimination of testing globals is not sufficiently compelling to make it worth changing my approach to debugging.


[1] Why I use Tape Instead of Mocha & So Should You - http://tqwhite.org?F7A285

Remote Volume Sharing with Ubuntu and fstab

I have two applications that run on my Ubuntu server. They both deposit their output onto the different  directories on the same remote volume. To avoid confusing my tiny brain, I like to isolate separate applications into separate users on my server. (It allows me to login and have the environment initialized with appropriate, different, management tools.)

So, I set about making it so that the volume mounted all the time. (That they are Windows volumes has, I believe, no bearing on this subject.) That is, the /ets/fstabs file contains a couple of lines like this:

//00.00.00.00/c$ /home/appUserA/volumeName cifs uid=appUseruserA,rw,user,username=remoteName,password=******* 0 0

//00.00.00.00/c$ /home/appUseruserA/volumeName cifs uid=appUseruserB,rw,user,username=remoteName,password=******* 0 0

The important point is that the IP addresses (here shown with zeroes) are the same and volumes (c$) match. 

The mounting worked. I could see the volume in both user directories. I got the application for appUserA to work. Life is good. But, when I got to the other application for appUserB, I could not write to its destination directory. 

After screwing around a long time, I realized that Ubuntu locks the mounted directory for the user that touches it first. This, before I figured it out, made for confusing results. Sometimes A could write. Other times B. In any case, I could always write with sudo.

I will have to do a different way of making these directories accessible (probably a common mount point with aliases into the appropriate directories).

So will you.


AMD for CSS

I am using a lot of Javascript plugins these days and managing them has become a fairly big deal. Recently, I have adopted Asynchronous Module Definition. I am using Require JS (http://requirejs.org) and like it a lot.

The problem is, Require JS does not work with CSS and it turns out that loading CSS is as much of a hassle as loading Javascript.

I think that the basic solution is to put a link to the CSS file into their page. But, I work with a framework and I do not want to pollute it with content-specific code. Some of the pages/sites that use the framework do not need plugin X and should not be having the CSS for it any more than they should have the JS.

Require JS says that they don't support CSS files because there isn't any good way to know when they arrive. It offers a tidbit of code for those, they say, who don't care about the timing of the arrival of the file.

This is nonsense. Following is code that does exactly that. Unfortunately, since it's not built into Require JS, I have to wrap stuff up for callback, but, c'est la vie.


var loadCssFile = function(filePath, callback){

  var link = document.createElement("link");
  link.type = "text/css";
  link.rel = "stylesheet";
  link.href = filePath;
  document.getElementsByTagName("head")[0].appendChild(link);

  var count=0,
  tryAgain=function(){
    for (var i=0, len=document.styleSheets.length; i<len; i++){
      var element=document.styleSheets[i];
      if (element.href && element.href.match(filePath)){
        callback();
        return;
      }
    }
        if (count<10){
          count++;
          setTimeout(tryAgain, 100);
        }
        else{
          throw "loadCssFile() failed on to find "+filePath;
        }
  }

  setTimeout(tryAgain, 100);

}

PHP Pretty Print with bbedit

PHP is old and ubiquitous. It is completely bizarre that there are almost no options to format your PHP. Javascript has eighteen formatters and evaluaters and lint-ers. PHP is really lame by comparison.

In fact, other than online versions, I only found one. (Your comments will be appreciated!)

http://www.phpformatter.com/ is the only one I could find that I can run on my own computer. It is a pear component. I hate pear. It has all the worst aspects of php - inconsistent calls, structures and everything else.

But, I'm desperate. After a year of primarily NodeJS, I'm returning to PHP having developed a strong reliance on being able to clean up my code at the press of a button. Further, the project I'm returning to did not benefit from that technology so it's got a million lines of code that is only as pretty as I had energy that particular day. Since I'm also trying to read an old project, this is an urgent need.

Since I have hated pear for much longer than I've had my current computer, I had to install it. That was infinitely more hassle than it should have been (I know there are people who dislike NPM but it works infinitely better than anything PHP, including composer). But, done.

After that, installing php_formatter was no big deal. It works, too. Except...

1) Php_formatter actually sets the PHP error_level explictly. The PHP authors, in another example of what's bad about PHP, has changed the meaning of E_ALL. Now it includes E_STRICT. This is really stupid.

2) Php_formatter strips all empty lines from the code. I use empty lines. A lot.

So, here's the thing. I had to edit the php_formatter files to comment out their error specification. Amateurs. It was two files. I don't remember which so do a multi-file search.

I use bbedit by Bare Bones Software (a great program). I want this to operate as a Text Filter. That's not so hard. bbedit passes the contents of the window (or selection) to the program and, bingo!, you are in business. In fact, php_formatter worked correctly once I got it working at all.

The problem is the stripping of blank lines. Turns out that php_formatter supposedly has a filter that preserves them but I could not make that work.

I made a NodeJS program that turns blank lines into comments. Then I beautify. Then I remove the comment characters. Voila! Blank lines are retained.

For the record, here's the Text Filter:

#!/bin/bash

~/Scripts/bin/js/commentUnComment.js -c | php  /Users/tqwhite/Documents/webdev/pear/bin/php_beautifier -t | ~/Scripts/bin/js/commentUnComment.js -u


And here's commentUncomment.js:

[NOTE: This is updated as of 5/29/15. The second regex failed in some circumstances.]

//=========================================================
#!/usr/local/bin/node

var inString='';

var cmdLineParameters={};
for (var i = 0, len = process.argv.length; i < len; i++) {
            var element = process.argv[i];
            if (element=='-c'){
                cmdLineParameters.c=true;
            }
            if (element=='-u'){
                cmdLineParameters.u=true;
            }
        }
       
var writeStuff = function() {
        var outString='';
       
        if (cmdLineParameters.c){
        outString=inString.replace(/\n\s*\n/gm, '\r//\r');
        }
        if (cmdLineParameters.u){
        outString=inString.replace(/^\s*\/\/\s*$/gi, '');
        outString=inString.replace(/^\t*\/\/\s*$/gmi, '');
        }
       
       
        process.stdout.write(outString);
       

    };

//the rest ========================================================

process.stdin.resume();
process.stdin.setEncoding('utf8');
process.stdin.on('data', function(data){
        inString+=data;
    });
process.stdin.on('end', writeStuff);

Apple OSX Mail Program Changes the Port on Its Own

I use Mandrill for my outbound SMTP. For SSL, it operates through port 587.

I have had many occasions where my connection fails for no apparent reason. I'm just living my life and sending email and then, poof!, an email tells me it can't send with that server. I go through debugging and re-enter the credentials and it would work.

I started thinking "last time it happened, wasn't it the port number that was different then, too?" So, I changed the name of the server to "Mandrill, s/b port 587" so I would know.

It happened again today. I went to look at it the settings and there was a change to port 486. WTF?


I changed it back to 587 and it worked.

I have changed the setting "Automatically detect and maintain account settings" to be off. I'm going to be that stops the problem. If not, I'll update here. If it's been a long time since 5/15/15, you are safe in seeing that as a solution.

bbedit as commit message editor for Git

I had this

export EDITOR="bbedit -w"

and, as expected, Git opened bbedit.

But, it also said

Aborting commit due to empty commit message.

Screwy.

I found this:

git config --global core.editor "bbedit --wait --resume"

and put it here so it would be remembered.


Dave Winer Strikes a Blow for Freedom

I started my web career with this guy's software. He's an original blogger and podcaster whom I've been reading since the nineties. He's done a lot of interesting things but now he's doing something important.

He has put together a Javscript/Browser blog editing environment that is not tied to any predefined external service. He's making a big point of keeping all open source. One of his major ideas is creating ecosystems. I think this will establish an important niche.

The reason it's important is that it will allow us to establish a web presence without relying on some big company's software. For the most part, anyone who wants to blog or otherwise express him or herself on the web has to use Facebook, Twitter, Blogger, hosted Wordpress, Tumblr, etc. That is, you put yourself at the mercy of their terms and conditions. Worse, your information is stored on their servers where it is probably hard to retrieve for posterity, reuse or backup - if you can get it at all.

Dave's thing is intended to counter that. As I understand it, pre-release, he has defined a protocol for storing data from the browser that can be implemented on any server you want. He also has created a NodeJS component that implements the protocol. All open source.

With his other Javascript things (he calls them "snacks"), he has made configuring and using them an entirely browser-based experience. It sounds like this might require creating a storage location this time. We will see.

However, he has often expressed a philosophical viewpoint with which I agree heartily that being free requires that we be able to communicate on our own terms with technology that is sufficiently decentralized that we cannot be shut down. I'm looking forward to his release of his MyWord Editor Project.

http://tqwhite.org/?89E805

Dave provides additional explanation.

http://tqwhite.org?41A5AE

MSSQL Service Broker Does Not Work

It's time for a project I've not seen in awhile to get some love. It's .NET MVC running against SQL Server.

I fire it up. After some really annoying compiler reference issues (how does this happen on a project that has not been touched?), I get a dev version up and running.

I want to work on a copy of the database but I also want to leave the original up for reference as I move forward. So, I back up, make a new database and restore into it. I run my initialization script that, mainly, establishes a service broker. Edit the connection string to point at the new database, and, drum roll. . . . .

No love. The service broker is not configured properly.

This stuff worked just fine last time I used it and for years before that. I check a billion things. I recreate the database making sure I didn't screw anything up. I turn on the debugger and look at it from the program's viewpoint. Nothing does any good.

I am beat. After another round of dejected facebook or twitter or something, I am just staring at Management Studio. I, once again, look at the properties of the database. Goddam, Service Broker is turned on. I look at the original database again, Service Broker is turned on.

But I notice the GUID for the first time.

Bottom line, the Service Broker GUID was restored along with the rest of the database. For no particular reason (probably a guy who worked here years ago), I was setting ENABLE_BROKER.

A little google later and I learned about NEW_BROKER. Done. Works.

If you have a service broker that doesn't work, won't respond or otherwise gives you a big pain, check the database property/options and scroll down to service broker. If the GUID is the same as in another database, there's your problem.

OR, you could immediately try, ...

ALTER DATABASE [database name] SET NEW_BROKER WITH ROLLBACK IMMEDIATE;

And go to lunch.