function compile(templateElement, transcludeFn, maxPriority) {
      if (!(templateElement instanceof jqLite)) {
        // jquery always rewraps, where as we need to preserve the original selector so that we can modify it.
        templateElement = jqLite(templateElement);
      }
      // We can not compile top level text elements since text nodes can be merged and we will
      // not be able to attach scope data to them, so we will wrap them in <span>
      forEach(templateElement, function(node, index){
        if (node.nodeType == 3 /* text node */) {
          templateElement[index] = jqLite(node).wrap('<span>').parent()[0];
        }
      });
      var linkingFn = compileNodes(templateElement, transcludeFn, templateElement, maxPriority);
      return function(scope, cloneConnectFn){
        assertArg(scope, 'scope');
        // important!!: we must call our jqLite.clone() since the jQuery one is trying to be smart
        // and sometimes changes the structure of the DOM.
        var element = cloneConnectFn
          ? JQLitePrototype.clone.call(templateElement) // IMPORTANT!!!
          : templateElement;
        safeAddClass(element.data('$scope', scope), 'ng-scope');
        if (cloneConnectFn) cloneConnectFn(element, scope);
        if (linkingFn) linkingFn(scope, element, element);
        return element;
      };
    }
Observe an interpolated attribute.
The observer will never be called, if given attribute is not interpolated.

@param {string} key Normalized key. (ie ngAttribute) .
@param {function(*)} fn Function that will be called whenever the attribute value changes.