ArraySearch with Chained Functions

After working with some large data sets and developing code to processes them, I created a utility implementing a pattern referred to as “chained functions”.

The Problem

I recently discovered the array.prototype.some and array.prototype.every methods, and saw their utility for searching arrays. I became determined there was a way to streamline their functionality after an initial usage in a case similar to this (although in a far more complex situation):

This block of code finds a single person object with an age of “17” in the people array, and throws an error if one is not found.

However, this takes up a lot of room, and I enjoy the challenge of condensing things, so ended up with this (roughly) equivalent block:

Now I can certainly imagine at least a few programmers would cringe at what could could be considered a confusing and abusive usage of some, among other offenses. And I admit a first time viewer would probably need a few seconds to decipher what’s going on here. However, the alternative is verbose and unwieldy, adding it’s own layer of complexity, So I took some time to write an (rather robust) alternative.

The Solution

Based on my experience, the situation of needing to find a particular object in a array with a particular property (or properties) is pretty common. The ArraySearch utility aims to provide an elegant solution. You can skip to the end and see the result, but here’s a bit of explanation behind the solution.

Recently, I’ve discovered the concept of what I like to call “natural language functions”. These are functions that chain arguments into successive calls, rather than a single call accepting a large group of arguments or breaking functionality into multiple distinct functions. This proves to be extremely effective at reducing both complexity and development time, and vastly increasing readability. My initial exposure to this was through the Chai assertion library, which uses the following syntax:

This style of abstraction/structure allows code to be quickly deciphered and written. Wherever possible, I’ve tried to implement it in my coding. Here’s an example based around ArraySearch:

Traditional function calls with multiple arguments are inherently confusing and ambiguous. Natural language removes the question of what goes where and awkward Boolean values or flags; the function call reads like a sentence and takes advantage of intellisense/auto-complete functionality.

Natural language functions are definitely trickier to write than traditional functions, and use some relatively advanced JavaScript constructs, but they provide immense implementation benefits.

How do they work?

Natural language functions take advantage of “chaining” through custom getter functions. Here’s an example of a couple pieces of ArrayFinder:

This packages the return type implementation into two clear values “one” or “all”. Next the arraySetter accepts a value for the array and stores it, returning another object that contains the actual executing functions:

findBy is a search function internal to ArraySearch that would normally have to be called with multiple explicit arguments, but that is instead provided with the proper context. setSearchPath continues the chain for more complex functionality.

ArraySearch

The final result:

What’s going on here takes no deciphering abilities (and doesn’t need any comments), is extremely quick to write, and takes up very little space. The ArraySearch utility includes the ability to search by any number of properties and at any depth, and to search arrays within an object, and is available on my GitHub.

A few more examples:

The with function accepts an predicate to search for within an array inside of the object, defined by the object path (admittedly this could take the whole natural language thing a little farther, but coming soon).

Please comment with any feedback or bugs/issues you find in my code!

 

Stopping Spam: CAPTCHA Techniques

An ongoing struggle in web application development is preventing apps from being vulnerable to exploitation by bots while keeping them friendly for the average user. It used to be standard to slap a string of garbled text on the screen and ask users to interpret it. However, as bots grow more sophisticated, images have become increasingly difficult for legitimate users to decipher, while proving increasingly ineffective at preventing malicious responses. While this approach has been abandoned even by the popular reCAPTCHA service, a number of new, more effective and more user-friendly techniques have emerged.

Math Problem

mathCaptchaExample

At first glance this may seem overly simple to prevent any sort of attack. However, there a few key elements that can make this kind of CAPTCHA effective.

The first is to disguise the markup used for the label and input elements:

Marking up the field as a “url” field will cause many spam bots to simply attempt to enter their URL into the field. You’ll next notice there are no actual numbers in the math problem. The numbers are inserted through CSS psuedo elements:

Even if a bot parsed the text on the page to determine the input was a CAPTCHA looking for a number, it wouldn’t be able to determine the numbers to solve the problem. Without parsing the CSS associated with the page, the numbers are completely invisible to any script parsing the HTML (psuedo-elements cannot be directly accessed or modified through JavaScript).

This certainly wouldn’t protect against any targeted attack, but for any small cite trying to deter blanket spam attack, this a method is simple for users to solve and difficult for bots to bypass. In addition, further security could be added by dynamically inserting numbers into the CSS.

The same effect can also be accomplished by asking the user other trivial questions.

Checkbox

This CAPTCHA solution involves simply asking the user to check a certain check box input indicating they are human. While this again might seem like an ineffectively simple solution, it would be difficult for a box to interpret text asking them if they are human or not. In fact, this is the basic method employed by Google’s new reCAPTCHA service.

A variation on this would could involve asking the user to un-check a checkbox that is checked by default.

Slider

Even more difficult for the majority of bots to bypass is a simple slider widget. While such a widget is trivially simple for humans using a touch screen or mouse, it is no simple task for a bot to emulate the same behavior. A slider can be implemented through the QapTcha jQuery plugin.

reCAPTCHA (and other services)no-captcha

In addition to reCAPTCHA, there are a number of services that provide more advance security. Combining one of the above techniques or more involved tests (at least from a technical perspective), these services provide enhance protection from even targeted attacks. This is useful in situations where your site or application may be specifically targeted and the above techniques are easily identify and accounted for by the attacker.

Ineffective and Obsolete Methods

There are few CAPTCHA methods that are no longer considered effective or that carry significant disadvantages.

Honeypot

A “honeypot” field is a field hidden with CSS and marked up to appear to bots a certain type of input, a company name for example, but that is validated to be empty to submit the form. While still effective, these fields can pose significant problems to screen readers, making the form inaccessible to who use them.

Traditional CAPTCHA

recaptcha-example

While once a staple of web forms, these services have been largely rendered obsolete as they become increasingly difficult for people to solve while increasingly easy for computers. Many sites still misguidedly employ these puzzles, but they should be avoided.

Optimizing Responsive Design For Mobile

The key area in optimizing page downloads on mobile is reducing download sizes, which are usually most heavily influenced by images. Using the following methods, I was able to reduce the desktop download size from 1.3 MB to as low as 475 KB on a site I am currently finishing up.

Trimming Content

The first line of defense against large mobile downloads and slow page renderings is tailoring the content to use cases on a mobile device, as opposed to how a user might be using the site on a desktop. While you never want frivolous content, the content present on mobile should honed with a razor focus. For example, elements that serve to enhance the presentation or aesthetic on wide-screen desktop displays should be stripped out of the mobile version. This includes things like large images or introduction paragraphs; they aren’t content mobile users will appreciate. How this trimming is handled though determines how effective it will be at enhancing the page load.

Media Queries

My design process usually involves hashing out the complex desktop first, then stripping out content and rearranging things as the screen gets narrower. However, when writing CSS media queries, the opposite approach must be used.

If media queries use the principle of graceful degradation:

Then the background image will still be loaded on mobile, even if it isn’t rendered. Rather, media queries should involving background images should be structured with wide format as the special case:

With this format, the image will only be requested if the page is wide enough to render it, instead of wasting bandwidth.

The <picture> Element

The <picture> element is a god-send for mobile optimization, allowing different images to be loaded based on size with little overhead. Although it is current only only supported in Chrome (desktop & mobile), Opera, and Firefox (by flag, although full support is coming soon), you can start using it now, because the syntax includes a fallback <img> tag. Using it is pretty simple:

As with CSS media queries, depending on which media condition is met, a specific source will be requested and rendered by the browser. If the browser does not support the <picture> element, it will render what ever default source is defined in the <img> tag.

In fact, the sources are applied to the <img> tag, so you can still style the image and completely forget about the <picture> tag altogether. It really is brilliant piece of web engineering and you can read more about how the <picture> element came to be on Ars Technica.

PHP Proxy Image Scripts

Although this technique will quickly be replaced by the <picture> element, for certain situations, it may be a valid solution. The basic idea is to insert a PHP script in front of the given image(s) that takes a GET argument for the width and re-sizes the image on the fly.  The PHP script can be seamlessly hidden with URL rewrite. Using a JavaScript, a width can be appended to the image request:

Obviously this technique has significant limitations/drawbacks:

  • You have to wait for the page to load before executing a JavaScript call to request the image.
  • Re-sizing the image takes time and server resources.

Probably the most valid situation for this is working with dynamic images, where you can’t manually re-size the images or store multiple copies.

A derivation of this could be to store different resolutions of an image, loading a default low resolution image. When the page loads, JavaScript could be used to request a higher resolution image, possibly mapped with a URL rewrites to request the appropriate higher resolution image.

Adventures with contenteditable

The contentenditable attribute offers powerful editing capabilities on nearly any HTML element, allowing far greater formatting options and more streamlined editing environment than a simple textarea. However, it has a few key short comings that require some work to overcome.

Depending on the situation, especially when a rich text editing toolbar is needed, the best solution may be a library like Medium.js, which includes a wide range of editing options and capabilities (although it does require a couple of dependencies). While this and other libraries will also make contenteditable beyond usable, I’ve tied up a couple of the loose ends currently present for a quick or lightweight implementation.

In it’s current incarnation, contenteditable handles empty elements rather poorly: an empty element is automatically deactivated and the cursor cannot be placed inside, even through JavaScript. The solution to this is to detect the backspace key on keyup and insert an empty span into the parent element when it is empty:

This function also prevents the backspace key from navigating the browser when the element is empty, as it normally would. To ensure that empty elements can be focused properly, another short function is required:

This creates an empty span and focuses the element, placing the cursor at the beginning. This code has been tested mainly in Chrome v41, although there shouldn’t be any significant issues with current version of Firefox or Internet Explorer (although IE 11 does exhibit some weird behavior with the cursor).

Hello world!

I think a good place to start is my motivations behind starting this blog and the kind of content I intend to post here. I’ve been a web developer for the past 6 years and, and over that time there’s been a number of interesting techniques and technologies I’ve come across and implemented. I’d like to be able to document my similar future experiences, in a public way, with my own contributions and insights. Secondly I spend a great deal of time keeping up with recent technological developments in general, and I’d like to post thoughts about those here.

So why a blog?

I think there’s a few reasons why a blog is the best medium for this content. The first is that a blog is an informal way to present content in an environment that I’m extremely familiar with. Depending on time constraints, I can exercise as much or little control over customization and polish as I desire, and I won’t feel limited by the platform. Given my skills, it’s a natural place to document my experiences and discoveries.

There are a few alternatives to posting this content through a blog, but I don’t think any of them meet my current needs or goals. For example, I could post these thoughts and experience on Facebook or another social media site, but these platforms are extremely limited in both their formatting options and content capacity.