var docsApp = { controller: {}, directive: {}, serviceFactory: {} }; docsApp.directive.focused = function($timeout) { return function(scope, element, attrs) { element[0].focus(); element.bind('focus', function() { scope.$apply(attrs.focused + '=true'); }); element.bind('blur', function() { // have to use $timeout, so that we close the drop-down after the user clicks, // otherwise when the user clicks we process the closing before we process the click. $timeout(function() { scope.$eval(attrs.focused + '=false'); }); }); scope.$eval(attrs.focused + '=true') } }; docsApp.directive.code = function() { return { restrict:'E', terminal: true }; }; docsApp.directive.sourceEdit = function(getEmbeddedTemplate) { return { template: '\n', scope: true, controller: function($scope, $attrs, openJsFiddle) { var sources = { module: $attrs.sourceEdit, deps: read($attrs.sourceEditDeps), html: read($attrs.sourceEditHtml), css: read($attrs.sourceEditCss), js: read($attrs.sourceEditJs), unit: read($attrs.sourceEditUnit), scenario: read($attrs.sourceEditScenario) }; $scope.fiddle = function(e) { e.stopPropagation(); openJsFiddle(sources); } } } function read(text) { var files = []; angular.forEach(text ? text.split(' ') : [], function(refId) { files.push({name: refId.split('-')[0], content: getEmbeddedTemplate(refId)}); }); return files; } }; docsApp.directive.docTutorialNav = function(templateMerge) { var pages = [ '', 'step_00', 'step_01', 'step_02', 'step_03', 'step_04', 'step_05', 'step_06', 'step_07', 'step_08', 'step_09', 'step_10', 'step_11', 'the_end' ]; return { compile: function(element, attrs) { var seq = 1 * attrs.docTutorialNav, props = { seq: seq, prev: pages[seq], next: pages[2 + seq], diffLo: seq ? (seq - 1): '0~1', diffHi: seq }; element.addClass('btn-group'); element.addClass('tutorial-nav'); element.append(templateMerge( '
  • Previous
  • \n' + '
  • Live Demo
  • \n' + '
  • Code Diff
  • \n' + '
  • Next
  • ', props)); } }; }; docsApp.directive.docTutorialReset = function() { function tab(name, command, id, step) { return '' + '
    \n' + '
      \n' + '
    1. Reset the workspace to step ' + step + '.

      ' + '
      ' + command + '
    2. \n' + '
    3. Refresh your browser or check the app out on angular\'s server.

    4. \n' + '
    \n' + '
    \n'; } return { compile: function(element, attrs) { var step = attrs.docTutorialReset; element.html( '
    ' + '

    Workspace Reset Instructions āž¤

    ' + '
    \n' + '
    \n' + tab('Git on Mac/Linux', 'git checkout -f step-' + step, 'gitUnix', step) + tab('Git on Windows', 'git checkout -f step-' + step, 'gitWin', step) + tab('Snapshots on Mac/Linux', './goto_step.sh ' + step, 'snapshotUnix', step) + tab('Snapshots on on Windows', './goto_step.bat ' + step, 'snapshotWin', step) + '
    \n'); } }; } docsApp.serviceFactory.angularUrls = function($document) { var urls = {}; angular.forEach($document.find('script'), function(script) { var match = script.src.match(/^.*\/(angular[^\/]*\.js)$/); if (match) { urls[match[1].replace(/(\-\d.*)?(\.min)?\.js$/, '.js')] = match[0]; } }); return urls; } docsApp.serviceFactory.formPostData = function($document) { return function(url, fields) { var form = angular.element('
    '); angular.forEach(fields, function(value, name) { var input = angular.element(''); input.attr('value', value); form.append(input); }); $document.find('body').append(form); form[0].submit(); form.remove(); }; }; docsApp.serviceFactory.openJsFiddle = function(templateMerge, getEmbeddedTemplate, formPostData, angularUrls) { var HTML = '
    \n{{html:2}}
    ', CSS = ' \n' + '{{head:0}}