<!DOCTYPE html>
<html>

<head>
  <link data-require="bootstrap-css@3.3.6" data-semver="3.3.6" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.css" />
  <link rel="stylesheet" href="style.css" />
</head>

<body ng-app="demoApp">
  <div class="container-fluid" ng-controller="mainCtrl as main">
    <h1>ngSnakeCamel live demo</h1>
    <p>Visit this project on <a href="https://github.com/Serrabits/ngSnakeCamel" _target="blank"><b>Git Hub</b></a> for more examples and to view the integration with <b>$http</b></p>
    <div class="row">
      <div class="col-sm-12">
        <div ng-model="main.input" ui-ace="{
            useWrapMode: true,
            showGutter: true,
            theme:'monokai',
            mode: 'json',
            useSoftTabs: true,
            tabSize: 2
          }">
        </div>
      </div>
    </div>
    <div class="row">
      <div class="col-sm-6">
        <h2>Snake filter</h2>
        <pre>{{main.input | snake}}</pre>
      </div>
      <div class="col-sm-6">
        <h2>Camel filter</h2>
        <pre>{{main.input | camel}}</pre>
      </div>
    </div>
  </div>
  <script data-require="angular.js@1.4.0" data-semver="1.4.0" src="https://code.angularjs.org/1.4.0/angular.js"></script>
  <script data-require="ace@*" data-semver="1.2.0" src="https://cdn.rawgit.com/ajaxorg/ace-builds/v1.2.0/src-min-noconflict/ace.js"></script>
  <script data-require="ui-ace@0.1.0" data-semver="0.1.0" src="https://angular-ui.github.io/ui-ace/dist/ui-ace.min.js"></script>
  <script src="ng-snake-camel.js"></script>
  <script src="script.js"></script>
</body>

</html>
(function() {
  
  function mainCtrl() {
    var main = this;
    var example = "{\n    \"glossary\": {\n        \"title\": \"example glossary\",\n        \"glossDiv\": {\n            \"title\": \"S\",\n            \"glossList\": {\n                \"glossEntry\": {\n                    \"id\": \"SGML\",\n                    \"sortAs\": \"SGML\",\n                    \"glossTerm\": \"Standard Generalized Markup Language\",\n                    \"acronym\": \"SGML\",\n                    \"abbrev\": \"ISO 8879:1986\",\n                    \"glossDef\": {\n                        \"para\": \"A meta-markup language, used to create markup languages such as DocBook.\",\n                        \"glossSeeAlso\": [\"GML\",\"XML\"]\n                    },\n                    \"glossSee\": \"markup\"\n                }\n            }\n        }\n    }\n}";
    main.input = example;
  }
  
  angular.module('demoApp', ['ngSnakeCamel','ui.ace'])
    .controller('mainCtrl', mainCtrl);
  
})();
/* Styles go here */

.ace_editor { height: 380px; }
'use strict';

/*global angular*/

(function() {
  var httpTransform = false;

  var JSON_START = /^\[|^\{(?!\{)/;
  var JSON_ENDS = {
    '[': /]$/,
    '{': /}$/
  };

  function isJsonLike(str, headers) {
    var type = headers('Content-Type');
    var jsonStart = str.match(JSON_START);
    return (type && type.indexOf('application/json') === 0) ||
      (jsonStart && JSON_ENDS[jsonStart[0]].test(str));
  }

  function camelJson(str) {
    return str.replace(/(_[a-zA-Z0-9])(?=\w*":)/g, function($1) {
      return $1[1].toUpperCase().replace('_', '');
    });
  }

  function snakeJson(str) {
    return str.replace(/([A-Z](?=[a-zA-Z0-9]*":))/g, function($1) {
      return '_' + $1.toLowerCase();
    });
  }

  function snakeHttp(data, headers) {
    var strData = angular.isObject(data) ? angular.toJson(data) : data;
    return strData && httpTransform && isJsonLike(strData, headers) ?
      snakeJson(strData) :
      data;
  }

  function camelHttp(data, headers) {
    var strData = angular.isObject(data) ? angular.toJson(data) : data;
    return strData && httpTransform && isJsonLike(strData, headers) ?
      camelJson(strData) :
      data;
  }

  function snakeFilter() {
    return function(data) {
      if (data) {
        var isObject = angular.isObject(data);
        var strData = isObject ? angular.toJson(data) : data;
        var jsonSnakelized = snakeJson(strData);
        data = isObject ? angular.fromJson(jsonSnakelized) : jsonSnakelized;
      }
      return data;
    };
  }

  function camelFilter() {
    return function(data) {
      if (data) {
        var isObject = angular.isObject(data);
        var strData = isObject ? angular.toJson(data) : data;
        var jsonCamelized = camelJson(strData);
        data = isObject ? angular.fromJson(jsonCamelized) : jsonCamelized;
      }
      return data;
    };
  }

  function snakeCamelConfig() {
    return {
      setHttpTransform: function(val) {
        httpTransform = !!val;
      },
      $get: function() {
        return {
          getHttpTransform: function() {
            return httpTransform;
          }
        };
      }
    };
  }

  function applyHttpTransform($http) {
    $http.defaults.transformResponse.unshift(camelHttp);
    $http.defaults.transformRequest.unshift(snakeHttp);
  }

  angular.module('ngSnakeCamel', [])
    .provider('snakeCamel', snakeCamelConfig)
    .filter('snake', snakeFilter)
    .filter('camel', camelFilter)
    .run(applyHttpTransform);
})();