| 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
 | @ngdoc overview
@name Developer Guide: Angular HTML Compiler: Extending the Angular Compiler
@description
Let's say that we want to create a new DOM element called `<my:greeter/>` that displays a greeting.
We want this HTML source:
<pre>
   <div ng:init="s='Hello'; n='World'">
      <my:greeter salutation="s" name="n"></my:greeter>
  </div>
</pre>
to produce this DOM:
<pre>
<div ng:init="s='Hello'; n='World'">
<my:greeter salutation="s" name="n"/>
  <span class="salutation">Hello</span>
  <span class="name">World</span>!
</my:greeter>
</div>
</pre>
That is, the new `<my:greeter></my:greeter>` tag's `salutation` and `name` attributes should be
transformed by the compiler such that two `<span>` tags display the values of the attributes, with
CSS classes applied to the output.
The following code snippet shows how to write a following widget definition that will be processed
by the compiler. Note that you have to declare the {@link dev_guide.bootstrap namespace} `my` in
the page:
<pre>
angular.widget('my:greeter', function(compileElement){
  var compiler = this;
  compileElement.css('display', 'block');
  var salutationExp = compileElement.attr('salutation');
  var nameExp = compileElement.attr('name');
  return function(linkElement){
    var salutationSpan = angular.element('<span class="salutation"></span');
    var nameSpan = angular.element('<span class="name"></span>');
    linkElement.append(salutationSpan);
    linkElement.append(' ');
    linkElement.append(nameSpan);
    linkElement.append('!');
    this.$watch(salutationExp, function(value){
      salutationSpan.text(value);
     });
    this.$watch(nameExp, function(value){
    nameSpan.text(value);
    });
  };
});
</pre>
Note: For more about widgets, see {@link dev_guide.compiler.widgets Understanding Angular Widgets}
and the {@link api/angular.widget widget API reference page}.
# Compilation process for `<my:greeter>`
Here are the steps that the compiler takes in processing the page that contains the widget
definition above:
## Compile Phase
1. Recursively traverse the DOM depth-first.
2. Find the angular.widget definition.
3. Find and execute the widget's compileElement function, which includes the following steps:
   1. Add a style element with attribute display: block; to the template DOM so that the browser
knows to treat the element as block element for rendering. (Note: because this style element was
added on the template compileElement, this style is automatically applied to any clones of the
template (i.e. any repeating elements)).
   2. Extract the salutation and name HTML attributes as angular expressions.
4. Return the aggregate link function, which includes just one link function in this example.
## Link Phase
1. Execute the aggregate link function, which includes the following steps:
   1. Create a <span> element set to the salutation class
   2. Create a <span> element set to the name class.
2. Add the span elements to the linkElement. (Note: be careful not to add them to the
compileElement, because that's the template.)
3. Set up watches on the expressions. When an expression changes, copy the data to the
corresponding spans.
## Related Topics
* {@link dev_guide.compiler Angular HTML Compiler}
* {@link dev_guide.compiler.understanding_compiler Understanding How the Compiler Works}
* {@link dev_guide.compiler.testing_dom_element Testing a New DOM Element}
## Related API
* {@link api/angular.module.NG.$compile $compile()}
 |