Monday, September 28, 2015

Installing memcached on OS X

The first step is to install the latest and greatest Xcode.
Install the Xcode developer tools. Apple seems to have removed this option from the preferences so you'll need to handle this from the command line.
$ xcode-select --install
Next we will install the required dependencies. If you are not already using Homebrew you should be.
$ brew install wget autoconf pkg-config libmemcached
You will also want to make sure you have PEAR installed; instructions can be found here but can be summarized as follows:
$ wget http://pear.php.net/go-pear.phar
$ php go-pear.phar
Then in the /tmp directory we will create a folder we can work in.
$ cd /tmp
$ mkdir memcached-work
$ cd memcached-work
Then we will use pecl, part of pear, to fetch the current version of the extension. The version of the memcached extension will vary so you may need to update your paths accordingly.
$ pecl download memcached
$ open memcached-{{version}}.tgz
$ cd memcached-{{version}}/memcached-{{version}}
$ phpize
$ ./configure
$ make
$ sudo make install
Finally you will need to add the following line to your php.ini
extension = memcached.so
You can verify your installation with the following:
$ php --info | grep memcached\\.
Depending on your setup now you may want to restart apache.
$ sudo apachectl restart
You should be all set to go!

BB Code to HTML

PHP
To convert the parser to HTML to BB Code, change this line:

$newtext = str_replace($bbcode, $htmlcode, $text);

to

$newtext = str_replace($htmlcode, $bbcode, $text);
function bb2html($text)
{
  $bbcode = array("<", ">",
                "[list]", "[*]", "[/list]", 
                "[img]", "[/img]", 
                "[b]", "[/b]", 
                "[u]", "[/u]", 
                "[i]", "[/i]",
                '[color="', "[/color]",
                "[size="", "[/size]",
                '[url="', "[/url]",
                "[mail="", "[/mail]",
                "[code]", "[/code]",
                "[quote]", "[/quote]",
                '"]');
  $htmlcode = array("&lt;", "&gt;",
                "<ul>", "<li>", "</ul>", 
                "<img src="", "">", 
                "<b>", "</b>", 
                "<u>", "</u>", 
                "<i>", "</i>",
                "<span style="color:", "</span>",
                "<span style="font-size:", "</span>",
                '<a href="', "</a>",
                "<a href="mailto:", "</a>",
                "<code>", "</code>",
                "<table width=100% bgcolor=lightgray><tr><td bgcolor=white>", "</td></tr></table>",
                '">');
  $newtext = str_replace($bbcode, $htmlcode, $text);
  $newtext = nl2br($newtext);//second pass
  return $newtext;
}

[iFrame] - Only allow on one domain

The best thing you can do is the following:
if (window.top.location.host != "hostname") {
    document.body.innerHTML = "Access Denied";
}
Add the above to your JavaScript and then use a JavaSript obfuscator

[CSS] text-overflow

.ellipsis {
  text-overflow: ellipsis;

  /* Required for text-overflow to do anything */
  white-space: nowrap;
  overflow: hidden;
}
Note that text-overflow only occurs when the container's overflow property has the value hiddenscroll or auto and white-space: nowrap;.
Text overflow can only happen on block or inline-block level elements, because the element needs to have a width in order to be overflow-ed. The overflow happens in the direction as determined by the direction property or related attributes.
The following demo displays the behavior of the text-overflow property including all the possible values. Browser support varies!
Setting overflow to scroll or auto will display scrollbars to reveal the additional text, while hidden will not. The hidden text can be selected by selecting the ellipses.

Create dropdowns not suck

Custom dropdown preview

The markup

To get started, below is the markup needed for a custom HTML dropdown.
<span class="custom-dropdown custom-dropdown--white">
    <select class="custom-dropdown__select custom-dropdown__select--white">
        <option>The Shawshank Redemption</option>
        <option>The Godfather</option>
        <option>Pulp Fiction</option>
        <option>The Good, the Bad and the Ugly</option>
        <option>12 Angry Men</option>
    </select>
</span>
You may wonder why I chose a span as a wrapper and not a label which might seem more appropiate. The reason is because we don't want to waste the label's functionality for this customization only. Also, this way you can still wrap everything inside a label to improve usability like so:
<label>
    IMDB Top Movies:
    <span class="custom-dropdown custom-dropdown--white">
        <select class="custom-dropdown__select custom-dropdown__select--white">
            <option>The Shawshank Redemption</option>
            <option>The Godfather</option>
            <option>Pulp Fiction</option>
            <option>The Good, the Bad and the Ugly</option>
            <option>12 Angry Men</option>
        </select>
    </span>
</label>

BEM naming convention

In case you noticed the namespacing, I'm using the BEM naming convention which I'm sure you've seen before. Needless to say, this rocks!
(Block) .custom-dropdown            = The main component
(Element) .custom-dropdown__select  = Descendant of .custom-dropdown
(Modifier) .custom-dropdown--*      = Different state of .custom-dropdown

The CSS

Custom dropdown deconstructed
Check the styles below to see how everything works. The @supports rule does all the the magic:
.custom-dropdown--large {
    font-size: 1.5em;
}

.custom-dropdown--small {
    font-size: .7em;
}

.custom-dropdown__select{
    font-size: inherit; /* inherit size from .custom-dropdown */
    padding: .5em; /* add some space*/
    margin: 0; /* remove default margins */
}

.custom-dropdown__select--white {
    background-color: #fff;
    color: #444;    
}

@supports (pointer-events: none) and
      ((-webkit-appearance: none) or
      (-moz-appearance: none) or
      (appearance: none)) {

    .custom-dropdown {
        position: relative;
        display: inline-block;
        vertical-align: middle;
    }

    .custom-dropdown__select {
        padding-right: 2.5em; /* accommodate with the pseudo elements for the dropdown arrow */
        border: 0;
        border-radius: 3px;
        -webkit-appearance: none;
        -moz-appearance: none;
        appearance: none;    
    }

    .custom-dropdown::before,
    .custom-dropdown::after {
        content: "";
        position: absolute;
        pointer-events: none;
    }

    .custom-dropdown::after { /*  Custom dropdown arrow */
        content: "\25BC";
        height: 1em;
        font-size: .625em;
        line-height: 1;
        right: 1.2em;
        top: 50%; margin-top: -.5em;
    }

    .custom-dropdown::before { /*  Custom dropdown arrow cover */
        width: 2em;
        right: 0; top: 0; bottom: 0;
        border-radius: 0 3px 3px 0;
    }

    .custom-dropdown__select[disabled] {
        color: rgba(0,0,0,.3);
    }

    .custom-dropdown.custom-dropdown--disabled::after {
        color: rgba(0,0,0,.1);
    }

    /* White dropdown style */
    .custom-dropdown--white::before {
        background-color: #fff;
        border-left: 1px solid rgba(0,0,0,.1);
    }

    .custom-dropdown--white::after {
        color: rgba(0,0,0,.9);
    }

    /* FF only temp fix */
    @-moz-document url-prefix() {
        .custom-dropdown__select             { padding-right: .9em }
        .custom-dropdown--large .custom-dropdown__select { padding-right: 1.3em }
        .custom-dropdown--small .custom-dropdown__select { padding-right: .5em }
    }
}

Summary

At first sight, the CSS might seem a bit too overwhelming, so let's deconstruct it.

appearance

The appearance: none declaration is used here to reset the default look for the native dropdown. The appearance property is very useful when you want to add a specific styling to an element that doesn't have it by default or to remove the specific styling entirely, as in this case.
You may have seen above this CSS rule: @-moz-document url-prefix(), well this is a hack to target Firefox only browsers. There is a pretty old bug on Firefox on how appearance: none works, it's about the fact that while appearance: none seem to work, the native dropdown arrow is still showing.
So, the temporary solution is to basically cover the native dropdown arrow for now:
@-moz-document url-prefix() {
  ...
}

::before & ::after

Having applied the above declaration which clears the default look, the dropdown triangle is made using pseudo elements. There isn't too much to say here, you know pseudos, they are everywhere. :)

pointer-events

If you aren't familiar with pointer-events, you should know that with pointer-events: none, which is the most encountered declaration, you can remove mouse events for current page navigation for example. In this case, we removed mouse events for the right triangle pseudo element to avoid accessibility issues.
As a side effect, if an element has pointer-events: none applied to, its hover state can't be styled anymore.

@supports

Last but not least, the latest @supports rule helps with CSS feature detection. Feature detection using JavaScript isn't something new and Modernizr is the best example here. So, if you already heard about Modernizr, then think about the @supports rule as its CSS equivalent.
To prevent browsers inconsistencies, the following rule allows you to target only browsers that have support for both pointer-events and appearance. The best examples here are the IE9 and IE10 browsers, both support a lot of CSS3 stuff from the above code but do not support (yet) cutting edge stuff like pointer-events or appearance which makes the technique inefficient.
@supports (pointer-events: none) and
    ((-webkit-appearance: none) or
     (-moz-appearance: none) or
     (appearance: none)) {
   ...
}

Some JavaScript

The truth is that you may use the CSS only keyword to name this styling solution. But, to cover also the case when a select is disabled, you'll need some JS to target the parent node for it and apply a HTML class like custom-dropdown--disabled.
<script>
(function(){
    /*1*/var customSelects = document.querySelectorAll(".custom-dropdown__select");
    /*2*/for(var i=0; i<customSelects.length; i++){
        if (customSelects[i].hasAttribute("disabled")){
            customSelects[i].parentNode.className += " custom-dropdown--disabled";
        }
    }    
})()
</script>
  1. Returns the list of the elements within the document that match .custom-dropdown__select.
  2. For each disabled select, go to its parent node and append the custom-dropdown--disabled HTML class. This way, we'll be able to use CSS in order to customize the arrow when a select is disabled.
Of course, none of the above will be necessary if the select element, which is a replaced element, would have allowed pseudo elements on it or if a CSS parent selector would have existed. But that's another story. :)

Create hexagons by CSS

Lets take a humble single element link<span>example</span>, which usually appears like so:
<span>example</span>
And let’s turn it into a hexagon:
example
Useful? Possibly. Fun? Let’s find out.
TL;DR? Final code at the bottom of the page.

This'll work by creating three rectangles – one from the main element, the other two from the ::before and ::after pseudo-elements. The two pseudo-element rectangles will be rotated, giving the appearance of a hexagon.
Diagram showing how we're going to construct the hexagon

For starters, we need to tell the span to act like a block element – otherwise none of the padding or margins will work.
a {
 display: block;
}

We now need to discover the dimensions of the rectangle.
Diagram showing what dimension we need to find out
We can work backwards from the final hexagon by first splitting it into six triangles. The six triangles are all equilateral – all angles and lengths are the same.
But this only tells us one of the lengths we need. We still need to find out the width from side to side, not point to point. We’re going to need to split these into two and end up with 12 right angle triangles.

Now we have two of the three measurements needed. These triangles can be used to find out the lengths that we need.

On this right angle triangle – since it's a right angle triangle that’s been created by splitting an equilateral triangle in two – the ratios are:
Diagram showing Pythagoras's theorem

Now we have the ratios of each side of the triangle and now can use this to make the rectangles that will make up the final hexagon. We don’t need to double the dimensions, as all we’re interested in at the moment are the ratios.

The final ratio of the rectangle: 1 to the square root of 3

In an ideal world, this would just work:
span {
 display: block;
 height: 1em;
 width: 3em;
}
But it doesn’t. Ah well. So instead we’re going to use this:
span {
 display: block;
 height: 1em;
 width: 1.73205081em; /* equivalent to √3em */
}
We now have the first building block needed to make the first part of our hexagon. Now, onto the pseudo-elements!
The ::before and ::after pseudo-elements need to be the same dimensions as the parent rectangle. To keep things simple, we’re telling the pseudo-classes to inherit the same characteristics from their parent element – if the dimensions of a change, the dimensions of it’s pseudo-element children will also change.
span::before,
span::after {
 display: inherit;
 height: inherit;
 width: inherit;
}
But ::before and ::after just need a bit more work to get them to actually show up. Content.
span::before,
span::after {
 content: ' ';
}
And now we have a lovely… slightly larger rectangle that hides the main a element. So z-index needs to be used – and for z-index to be actually work, every element needs to be defined as position: relative orposition: absolute.
span {
 position: relative;
 z-index: 100;
}
In addition to the position and z-index, the ::before and ::after pseudo elements will need their left and top characteristics defined. Because the parent element is position: relative, the pseudo-elements are contained within.
span::before,
span::after {
 left: 0;
 position: absolute;
 top: 0;
 z-index: -100;
}
And here’s where it gets strange. Even though the z-index of the pseudo elements is lower than the main element, it still obscures it. But if we add a text into the a element, the text will appear above the pseudo-elements – but the background does not.
Although this appears to disobey the z-index, the z-index of the a works in relation to other elements outside of it – but not the pseudo-elements and the content within it. The pseudo-elements and the content obey each other’s z-index, but ignore that of the parent element. If we twisted the layout so we could see the z-axis, we’d see this:

The z-index of the element, from the element (bottom) to pseudo-elements (middle) to the contents (top)

Now for the rotation. This uses CSS3 transforms, so will currently work in every modern browser apart from Internet Explorer 8. (Can I Use has the latest info on this). Personally, I think this is okay – the fallback for browsers that don’t support rotations is that it will just appear as a rectangle.
The rotation is dead simple: transform: rotate(45deg) will twist the element by 45 degrees clockwise; anticlockwise rotation is done with a negative/minus angle. So, with the hexagon the ::before and ::afterelements need to be rotated by -60 degrees and 60 degrees.
span::before {
 transform: rotate(60deg);
}
span::after {
 transform: rotate(-60deg);
}
The eagle-eyed will have no doubt noticed that the CSS so far will only work in Firefox 16+ and Internet Explorer 10+; unfortunately the remedy is the malaise of CSS – the vendor prefix. The W3C version – the non vendor prefixed version – should to go last so it isn’t overridden.
span::before {
  -moz-transform: rotate(60deg);
  -ms-transform: rotate(60deg);
  -o-transform: rotate(60deg);
  -webkit-transform: rotate(60deg);
 transform: rotate(60deg);
}
span::after {
  -moz-transform: rotate(-60deg);
  -ms-transform: rotate(-60deg);
  -o-transform: rotate(-60deg);
  -webkit-transform: rotate(-60deg);
 transform: rotate(-60deg);
}
And now you have a lovely hexagon, where there once was only a span.
span {
 background: #ffde17;
 color: rgba(255, 255, 255, 0.5);
 display: block;
 font: 100 65px/2em sans-serif;
 height: 2em;
 position: relative;
 width: 3.46410162em;
 z-index: 100;
}
span:before,
span:after {
 background: inherit;
 content: ' ';
 display: inherit;
 height: inherit;
 left: 0;
 line-height: inherit;
 position: absolute;
 top: 0;
 width: inherit;
 z-index: -100;
}
span:before {
 -moz-transform: rotate(60deg);
 -ms-transform: rotate(60deg);
 -o-transform: rotate(60deg);
 -webkit-transform: rotate(60deg);
 transform: rotate(60deg);
}
span:after {
 -moz-transform: rotate(-60deg);
 -ms-transform: rotate(-60deg);
 -o-transform: rotate(-60deg);
 -webkit-transform: rotate(-60deg);
 transform: rotate(-60deg);
}