<!DOCTYPE html>
<html ng-app="x">

  <head>
    <meta charset="utf-8" />
    <title>UI.Codemirror : demo </title>


    <!-- Le css -->
    <link rel="stylesheet" type="text/css" href="http://codemirror.net/lib/codemirror.css"/>

  </head>
  <body>


    <!-- Le content... -->
<section ng-controller="CodemirrorCtrl">

  <p>Non Repeating Version</p>
  <div ui-codemirror="piecesOfCode[0].options" ng-model="piecesOfCode[0].code"></div>
    
  <div ng-repeat="c in piecesOfCode">
    <p>Code should be: {{c.code}}</p>
    <div ui-codemirror="c.options" ng-model="c.code"></div>
  </div>

</section>



    <!-- Le vendor... -->
      <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular.min.js"></script>
      <script src="http://codemirror.net/lib/codemirror.js"></script>
      <script src="http://codemirror.net/mode/scheme/scheme.js"></script>
      <script src="http://codemirror.net/mode/javascript/javascript.js"></script>
      <script src="http://codemirror.net/mode/xml/xml.js"></script>
      <script src="ui-codemirror.js"></script>
    <script src="app.js"></script>
  </body>
</html>
var app = angular.module('x', ['ui.codemirror']);


app.controller('CodemirrorCtrl', ['$scope', function($scope) {

  $scope.piecesOfCode = [
    {
      code: ";; Scheme code in here.\n" +
            "(define (double x)\n\t(* x x))\n",
      options: {mode: "scheme", lineNumbers: true, indentWithTabs: true}
    },
    {
      code: '<!-- XML code in here. -->\n' +
            '<root>\n\t<foo>\n\t</foo>\n\t<bar/>\n</root>',
      options: {mode: "xml", lineNumbers: true, indentWithTabs: true}
    },
    {
      code: '// Javascript code in here.\n' +
            'function foo(msg) {\n\tvar r = Math.random();\n\treturn "" + r + " : " + msg;\n}',
      options: {mode: "javascript", lineNumbers: true, indentWithTabs: true}
    }
    ];

}]);
/**
 * Binds a CodeMirror widget to a <textarea> element.
 */
angular.module('ui.codemirror', [])
  .constant('uiCodemirrorConfig', {})
  .directive('uiCodemirror', ['uiCodemirrorConfig', function (uiCodemirrorConfig) {
    'use strict';

    return {
      restrict: 'EA',
      require: '?ngModel',
      compile: function compile(tElement, tAttrs, transclude) {

        // Require CodeMirror
        if (angular.isUndefined(window.CodeMirror)) {
          throw new Error('ui-codemirror need CodeMirror to work... (o rly?)');
        }

        var value = tElement.text();
        
        return function postLink(scope, iElement, iAttrs, ngModel) {
          
        // Create a codemirror instance with
        // - the function that will to place the editor into the document.
        // - the initial content of the editor.
        //   see http://codemirror.net/doc/manual.html#api_constructor
        var codeMirror = new CodeMirror(function (cm_el) {
          iElement.append(cm_el);
        }, {value: value});


          var options, opts, onChange;

          options = uiCodemirrorConfig.codemirror || {};
          opts = angular.extend({}, options, scope.$eval(iAttrs.uiCodemirror), scope.$eval(iAttrs.uiCodemirrorOpts));

          function updateOptions(newValues) {
            for (var key in newValues) {
              if (newValues.hasOwnProperty(key)) {
                codeMirror.setOption(key, newValues[key]);
              }
            }
          }

          updateOptions(opts);

          if (angular.isDefined(scope[iAttrs.uiCodemirror])) {
            scope.$watch(iAttrs.uiCodemirror, updateOptions, true);
          }
          // Specialize change event
          codeMirror.on("change", function (instance, changeObj) {
            var newValue = instance.getValue();
            if (ngModel && newValue !== ngModel.$viewValue) {
              ngModel.$setViewValue(newValue);
            }
            if (!scope.$$phase) {
              scope.$apply();
            }
          });


          if (ngModel) {
            // CodeMirror expects a string, so make sure it gets one.
            // This does not change the model.
            ngModel.$formatters.push(function (value) {
              if (angular.isUndefined(value) || value === null) {
                return '';
              }
              else if (angular.isObject(value) || angular.isArray(value)) {
                throw new Error('ui-codemirror cannot use an object or an array as a model');
              }
              return value;
            });


            // Override the ngModelController $render method, which is what gets called when the model is updated.
            // This takes care of the synchronizing the codeMirror element with the underlying model, in the case that it is changed by something else.
            ngModel.$render = function () {
              //Code mirror expects a string so make sure it gets one
              //Although the formatter have already done this, it can be possible that another formatter returns undefined (for example the required directive)
              var safeViewValue = ngModel.$viewValue || '';
              codeMirror.setValue(safeViewValue);
            };
          }


          // Watch ui-refresh and refresh the directive
          if (iAttrs.uiRefresh) {
            scope.$watch(iAttrs.uiRefresh, function (newVal, oldVal) {
              // Skip the initial watch firing
              if (newVal !== oldVal) {
                  codeMirror.refresh();
              }
            });
          }

          // onLoad callback
          if (angular.isFunction(opts.onLoad)) {
            opts.onLoad(codeMirror);
          }
        };
      }
    };
  }]);