AngularJS Example

HTML

<div ng-app="MFSwatches" ng-cloak>
  <div data-ng-controller="SwatchesCtrl" class="swatches" data-color-name="{{currentColorName}}" data-size-availability="{{sizeAvailability}}">
    I have {{swatches.length}} colors. They are:
    <a ng-href="{{mainProductImageURL}}" class="lightbox" title="{{currentColorName + ' comes in ' + currentSwatchSizes}}" >
      <img 
        ng-src="{{mainProductImageURL}}" 
        alt="" 
        class="main-product-image"
      />
    </a>
    <div 
      class="swatch" 
      data-ng-repeat="swatch in swatches"
      data-set-up="" 
      data-ng-mouseenter="handleMouseEnter();"
      data-ng-mouseleave="handleMouseLeave();"
    >
      <a ng-href="{{swatch.imageURL}}" class="lightbox" title="{{swatch.name + currentColorName}}"></a>
    </div>
    <div>
      Color available in: 
      <span data-ng-repeat="size in currentSwatchSizes" class="sizes-in-color">{{size | uppercase}}</span>
    </div>
  </div>
  {{hex="ffffff";sizes=["s","m","l"];name="white";""}}
  {{hex="000000";sizes=["s","m","l"];name="black";""}}
  {{hex="ff0000";sizes=["s","l"];name="red";""}}
  <div data-add-to-cart=""></div>
</div>

CSS

</style> <!-- Ugly Hack due to jsFiddle issue: http://goo.gl/BUfGZ --> 
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.3/angular.js"></script>
<style>
strong {display:none;}
div:active strong {display:inline;}
.ng-invalid { border: 1px solid red; }
[data-white] {color:blue;}
.swatches { position:relative; }
.swatch { display:inline-block; margin:.2em; width:20px; height:20px; border:1px solid black; box-shadow:0 0 transparent; -moz-box-shadow:0 0 transparent; -webkit-box-shadow:0 0 transparent; -webkit-transform:rotate(0deg) scale(1); -webkit-transition:-webkit-transform 500ms cubic-bezier(0.230, 1.000, 0.320, 1.000) 0ms; -ms-transform:rotate(0deg) scale(1); -ms-transition:-ms-transform 500ms cubic-bezier(0.230, 1.000, 0.320, 1.000) 0ms; -o-transform:rotate(0deg) scale(1); -o-transition:-o-transform 500ms cubic-bezier(0.230, 1.000, 0.320, 1.000) 0ms; transform:rotate(0deg) scale(1); transition:transform 500ms cubic-bezier(0.230, 1.000, 0.320, 1.000) 0ms; }
.swatch:hover { box-shadow:0 0 10px rgba(0, 0, 0, .4); -moz-box-shadow:0 0 10px rgba(0, 0, 0, .4); -webkit-box-shadow:0 0 10px rgba(0, 0, 0, .4); -webkit-transform:rotate(45deg) scale(2); -webkit-transition:-webkit-transform 500ms cubic-bezier(0.230, 1.000, 0.320, 1.000) 0ms; -ms-transform:rotate(45deg) scale(2); -ms-transition:-ms-transform 500ms cubic-bezier(0.230, 1.000, 0.320, 1.000) 0ms; -o-transform:rotate(45deg) scale(2); -o-transition:-o-transform 500ms cubic-bezier(0.230, 1.000, 0.320, 1.000) 0ms; transform:rotate(45deg) scale(2); transition:transform 500ms cubic-bezier(0.230, 1.000, 0.320, 1.000) 0ms; position:relative; z-index:1; }
.main-product-image { float:right; height:298px; max-width:252px; }
.swatches:after { content:attr(data-color-name); position:absolute; top:0; right:0; font:400 2em/1.3 "Verdana"; background-image:-webkit-linear-gradient(245deg, rgba(0, 0, 0, 0.4), rgba(255, 255, 255, 0) 80%); background-image:-ms-linear-gradient(245deg, rgba(0, 0, 0, 0.4), rgba(255, 255,...

JavaScript

var PRODUCT = {
    SKU:"R3000",
    ID: "617020938",
    NAME: "R3000 - UltraClub Reusable Shopping Bag",
    VARIATIONS_LENGTH: "2",
    MOCK: [5,4,2,1]
};
if(typeof Object.freeze !== "undefined") {
    Object.freeze(PRODUCT);
}
var MFSwatches = angular.module("MFSwatches", [])
    .directive("addToCart", function ($rootScope, $compile) {
        debugger;
        var beefcake = $rootScope;
        var cmp = $compile;
        var directiveDefinitionObject = {
          template: '<span class="beef">{{num}}</span>',
          replace:true,
          restrict: 'ECAM',
          transclude:true,
          scope: {
            num:'@'
          },
          controller: 'SwatchesCtrl',
          compile: function compile(tElement, tAttrs, transclude) {
            debugger;
            tElement[0].dataset.variationsLength = PRODUCT.VARIATIONS_LENGTH;
            
                if(typeof tAttrs.ngRepeat === "undefined") {
                  tAttrs.$set("ngRepeat","num in [4,3,2]");
                }
            console.log(arguments, beefcake, cmp);
            return function(scope, iElement, iAttrs, controller) {
                debugger;
              cmp(iElement)(scope,function(arg,scope){
              debugger;
              });
                console.log(scope.swatches);
                console.log(arguments);
              };            
          }
        };
        return directiveDefinitionObject;
    })
    .directive("setUp", function () {
        return {
            link:function(scope, iElement, iAttrs) {
                    iElement.attr({
                      "title":"Get " + scope.swatch.name + " in " + scope.swatch.sizes.toString().toUpperCase(),
                      "data-color-name":scope.swatch.name,
                      "data-hex-code":scope.swatch.hex,
                      "style":"background-color:#"+scope.swatch.hex+";"
                    });
                }            
          };
    })
    .factory("swatchHover", function(){
...