diff options
| author | Misko Hevery | 2012-03-09 15:12:48 -0800 | 
|---|---|---|
| committer | Misko Hevery | 2012-03-11 21:31:35 -0700 | 
| commit | 3e5377f4f3b1d0f06af50e21026835bee0556b4a (patch) | |
| tree | 156df16f60ddf501df847050946d9ed0765967d2 | |
| parent | 488a03631eb69794fd158f3f0df34d936084aec4 (diff) | |
| download | angular.js-3e5377f4f3b1d0f06af50e21026835bee0556b4a.tar.bz2 | |
doc(fixes): to better support ng-directive notation
| -rw-r--r-- | docs/content/guide/ie.ngdoc | 162 | ||||
| -rw-r--r-- | docs/src/dom.js | 3 | ||||
| -rw-r--r-- | docs/src/ngdoc.js | 45 | ||||
| -rw-r--r-- | src/Angular.js | 2 | ||||
| -rw-r--r-- | src/directive/booleanAttrDirs.js | 89 | ||||
| -rw-r--r-- | src/directive/form.js | 1 | ||||
| -rw-r--r-- | src/directive/input.js | 2 | ||||
| -rw-r--r-- | src/directive/ngBind.js | 1 | ||||
| -rw-r--r-- | src/directive/ngSwitch.js | 2 | ||||
| -rw-r--r-- | src/directive/script.js | 1 | ||||
| -rw-r--r-- | src/directive/select.js | 1 | ||||
| -rw-r--r-- | src/widgets.js | 0 | 
12 files changed, 249 insertions, 60 deletions
| diff --git a/docs/content/guide/ie.ngdoc b/docs/content/guide/ie.ngdoc new file mode 100644 index 00000000..3ba93d2d --- /dev/null +++ b/docs/content/guide/ie.ngdoc @@ -0,0 +1,162 @@ +@ngdoc overview +@name Developer Guide: Internet Explorer Compatibility +@description + +# Overview + +This document describes the Internet Explorer (IE) idiosyncrasies when dealing with custom HTML +attributes and tags. Read this document if you are planning on deploying your angular application +on IE v8.0 or earlier. + +# Short Version + +To make your angular application work on IE please make sure that: + +  1. you **do not** use custom element tags such as `<ng:view>` (use the attribute version `<div +  ng-view>` instead), or + +  2. if you **do use** custom element tags, then you must take these steps to make IE happy: + +<pre> +  <html xmlns:ng="http://angularjs.org"> +    <head> +      <!--[if lte IE 8]> +        <script> +          document.createElement('ng-include'); +          document.createElement('ng-pluralize'); +          document.createElement('ng-view'); +           +          // Optionally these for CSS +          document.createElement('ng:include'); +          document.createElement('ng:pluralize'); +          document.createElement('ng:view'); +        </script> +      <![endif]--> +    </head> +    <body> +      ... +    </body> +  </html> +</pre> + +The **important** parts are: + +  * `xmlns:ng` - *namespace* - you need one namespace for each custom tay you are planning on +    using. + +  * `document.createElement(yourTagName)` - *creation of custom tag names* - Since this is an +    issue only for older version of IE you need to load it conditionally. For each tag which does +    not have namespace and which is not defined in HTML you need to pre-declare it to make IE +    happy. + + +# Long Version + +IE has an issues with element tag names which are not standard HTML tag names. These fall into two +categories, and each category has its own fix. + +  * If the tag name starts with `my:` prefix than it is considered an XML namespace and must +    have corresponding namespace declaration on `<html xmlns:my="ignored">` + +  * If the tag has no `:` but it is not a standard HTML tag, then it must be pre-created using +    `document.createElement('my-tag')` + +  * If you have are planning on styling the custom tag with CSS selectors, then it must be +    pre-created using `document.createElement('my-tag')` regardless of XML namespace. + + +## The Good News + +The good news is that these restrictions only apply to element tag names, and not to element  +attribute names. So this requires no special handling in IE: `<div my-tag your:tag></div>`. + + +## What happens if I fail to do this? + +Suppose you have HTML with unknown tag `mytag` (this could also be `my:tag` or `my-tag` with same +result): + +<pre> +  <html> +    <body> +      <mytag>some text</mytag> +    </body> +  </html> +</pre> + +It should pares into the following DOM: + +<pre> +#document +  +- HTML +     +- BODY +        +- mytag +           +- #text: some text +</pre> + +The expected behavior is that the `BODY` element has a child element `mytag`, which in turn has +the text `some text`. + +But this is not what IE does (if the above fixes are not included): + +<pre> +#document +  +- HTML +     +- BODY +        +- mytag +        +- #text: some text +        +- /mytag +</pre> + +In IE, the behavior is that the `BODY` element has three children: + +  1. A self closing `mytag`. Example of self closing tag is `<br/>`. The trailing `/` is optional, +  but the `<br>` tag is not allowed to have any children, and browsers consider `<br>some +  text</br>` as three siblings not a `<br>` with `some text` as child. + +  2. A text node with `some text`. This should have been a child of `mytag` above, not a sibling. + +  3. A corrupt self closing `/mytag`. This is corrupt since element names are not allowed to have +  the `/` character. Furthermore this closing element should not be part of the DOM since it is +  only used to delimitate the structure of the DOM. + + +## CSS Styling of Custom Tag Names + +The to make CSS selector work with custom elements the custom element name must be shived with the +`document.createElement('my-tag')` regardless of XML namespace. + +<pre> +  <html xmlns:ng="needed for ng: namespace"> +    <head> +      <!--[if lte IE 8]> +        <script> +          // needed to make ng-include parse properly +          document.createElement('ng-include'); +           +          // needed to enable CSS reference +          document.createElement('ng:view'); +        </script> +      <![endif]--> +      <style> +        ng\\:view { +          display: block; +          border: 1px solid red; +        } + +        ng-include { +          display: block; +          border: 1px solid blue; +        } +      </style> +    </head> +    <body> +      <ng:view></ng:view> +      <ng-include></ng-include> +      ... +    </body> +  </html> +</pre> + + + diff --git a/docs/src/dom.js b/docs/src/dom.js index bda90373..e5320c5f 100644 --- a/docs/src/dom.js +++ b/docs/src/dom.js @@ -19,7 +19,8 @@ function DOM() {  var INLINE_TAGS = {      i: true, -    b: true +    b: true, +    a: true  };  DOM.prototype = { diff --git a/docs/src/ngdoc.js b/docs/src/ngdoc.js index 6cbf816c..1cbd968e 100644 --- a/docs/src/ngdoc.js +++ b/docs/src/ngdoc.js @@ -367,18 +367,14 @@ Doc.prototype = {      dom.h('Usage', function() {        var restrict = self.restrict || 'AC';        if (restrict.match(/E/)) { -        dom.text('as element'); +        dom.text('as element (see '); +        dom.tag('a', {href:'guide/ie'}, 'IE restrictions'); +        dom.text(')');          dom.code(function() {            dom.text('<');            dom.text(self.shortName); -          (self.param||[]).forEach(function(param){ -            dom.text('\n      '); -            dom.text(param.optional ? ' [' : ' '); -            dom.text(param.name); -            dom.text(BOOLEAN_ATTR[param.name] ? '' : '="..."'); -            dom.text(param.optional ? ']' : ''); -          }); -          dom.text('></'); +          renderParams('\n       ', '="', '"'); +          dom.text('>\n</');            dom.text(self.shortName);            dom.text('>');          }); @@ -389,9 +385,7 @@ Doc.prototype = {          dom.code(function() {            dom.text('<' + element + ' ');            dom.text(self.shortName); -          if (self.param.length) { -            dom.text('="' + self.param[0].name + '"'); -          } +          renderParams('\n     ', '="', '"', true);            dom.text('>\n   ...\n');            dom.text('</' + element + '>');          }); @@ -402,9 +396,7 @@ Doc.prototype = {          dom.code(function() {            dom.text('<' + element + ' class="');            dom.text(self.shortName); -          if (self.param.length) { -            dom.text(': ' + self.param[0].name + ';'); -          } +          renderParams(' ', ': ', ';', true);            dom.text('">\n   ...\n');            dom.text('</' + element + '>');          }); @@ -414,6 +406,27 @@ Doc.prototype = {      });      self.method_properties_events(dom); + +    function renderParams(prefix, infix, suffix, skipSelf) { +      (self.param||[]).forEach(function(param) { +        var skip = skipSelf && (param.name == self.shortName || param.name.indexOf(self.shortName + '|') == 0); +        if (!skip) { +          dom.text(prefix); +          dom.text(param.optional ? '[' : ''); +          var parts = param.name.split('|'); +          dom.text(parts[skipSelf ? 0 : 1] || parts[0]); +        } +        if (BOOLEAN_ATTR[param.name]) { +          dom.text(param.optional ? ']' : ''); +        } else { +          dom.text(BOOLEAN_ATTR[param.name] ? '' : infix ); +          dom.text(('{' + param.type + '}').replace(/^\{\'(.*)\'\}$/, '$1')); +          dom.text(param.optional ? ']' : ''); +          dom.text(suffix); +        } +      }); +    } +    },    html_usage_filter: function(dom){ @@ -455,7 +468,7 @@ Doc.prototype = {            dom.text('\n      ');            dom.text(param.optional ? ' [' : ' ');            dom.text(param.name); -          dom.text(BOOLEAN_ATTR[param.name] ? '' : '="..."'); +          dom.text(BOOLEAN_ATTR[param.name] ? '' : '="{' + param.type + '}"');            dom.text(param.optional ? ']' : '');          });          dom.text('>'); diff --git a/src/Angular.js b/src/Angular.js index 7ab0e7f6..cdffcf1d 100644 --- a/src/Angular.js +++ b/src/Angular.js @@ -818,7 +818,7 @@ function encodeUriQuery(val, pctEncodeSpaces) {   * @name angular.module.ng.$compileProvider.directive.ng-app   *   * @element ANY - * @param {angular.Module} module on optional application + * @param {angular.Module} ng-app on optional application   *   {@link angular.module module} name to load.   *   * @description diff --git a/src/directive/booleanAttrDirs.js b/src/directive/booleanAttrDirs.js index 0c1731a8..10c6eee8 100644 --- a/src/directive/booleanAttrDirs.js +++ b/src/directive/booleanAttrDirs.js @@ -3,6 +3,7 @@  /**   * @ngdoc directive   * @name angular.module.ng.$compileProvider.directive.ng-href + * @restrict A   *   * @description   * Using <angular/> markup like {{hash}} in an href attribute makes @@ -22,8 +23,8 @@   * <a ng-href="http://www.gravatar.com/avatar/{{hash}}"/>   * </pre>   * - * @element ANY - * @param {template} template any string which can contain `{{}}` markup. + * @element A + * @param {template} ng-href any string which can contain `{{}}` markup.   *   * @example   * This example uses `link` variable inside `href` attribute: @@ -83,6 +84,7 @@  /**   * @ngdoc directive   * @name angular.module.ng.$compileProvider.directive.ng-src + * @restrict A   *   * @description   * Using <angular/> markup like `{{hash}}` in a `src` attribute doesn't @@ -101,13 +103,14 @@   * <img ng-src="http://www.gravatar.com/avatar/{{hash}}"/>   * </pre>   * - * @element ANY - * @param {template} template any string which can contain `{{}}` markup. + * @element IMG + * @param {template} ng-src any string which can contain `{{}}` markup.   */  /**   * @ngdoc directive   * @name angular.module.ng.$compileProvider.directive.ng-disabled + * @restrict A   *   * @description   * @@ -138,14 +141,15 @@        </doc:scenario>      </doc:example>   * - * @element ANY - * @param {template} template any string which can contain '{{}}' markup. + * @element INPUT + * @param {template} ng-disabled any string which can contain '{{}}' markup.   */  /**   * @ngdoc directive   * @name angular.module.ng.$compileProvider.directive.ng-checked + * @restrict A   *   * @description   * The HTML specs do not require browsers to preserve the special attributes such as checked. @@ -167,14 +171,15 @@        </doc:scenario>      </doc:example>   * - * @element ANY - * @param {template} template any string which can contain '{{}}' markup. + * @element INPUT + * @param {template} ng-checked any string which can contain '{{}}' markup.   */  /**   * @ngdoc directive   * @name angular.module.ng.$compileProvider.directive.ng-multiple + * @restrict A   *   * @description   * The HTML specs do not require browsers to preserve the special attributes such as multiple. @@ -202,14 +207,15 @@         </doc:scenario>       </doc:example>   * - * @element ANY - * @param {template} template any string which can contain '{{}}' markup. + * @element SELECT + * @param {template} ng-multiple any string which can contain '{{}}' markup.   */  /**   * @ngdoc directive   * @name angular.module.ng.$compileProvider.directive.ng-readonly + * @restrict A   *   * @description   * The HTML specs do not require browsers to preserve the special attributes such as readonly. @@ -231,41 +237,42 @@        </doc:scenario>      </doc:example>   * - * @element ANY - * @param {template} template any string which can contain '{{}}' markup. + * @element INPUT + * @param {template} ng-readonly any string which can contain '{{}}' markup.   */  /** -* @ngdoc directive -* @name angular.module.ng.$compileProvider.directive.ng-selected -* -* @description -* The HTML specs do not require browsers to preserve the special attributes such as selected. -* (The presence of them means true and absence means false) -* This prevents the angular compiler from correctly retrieving the binding expression. -* To solve this problem, we introduce ng-selected. -* @example -   <doc:example> -     <doc:source> -       Check me to select: <input type="checkbox" ng-model="checked"><br/> -       <select> -         <option>Hello!</option> -         <option id="greet" ng-selected="{{checked}}">Greetings!</option> -       </select> -     </doc:source> -     <doc:scenario> -       it('should select Greetings!', function() { -         expect(element('.doc-example-live #greet').prop('selected')).toBeFalsy(); -         input('checked').check(); -         expect(element('.doc-example-live #greet').prop('selected')).toBeTruthy(); -       }); -     </doc:scenario> -   </doc:example> -* @element ANY -* @param {template} template any string which can contain '{{}}' markup. -*/ - + * @ngdoc directive + * @name angular.module.ng.$compileProvider.directive.ng-selected + * @restrict A + * + * @description + * The HTML specs do not require browsers to preserve the special attributes such as selected. + * (The presence of them means true and absence means false) + * This prevents the angular compiler from correctly retrieving the binding expression. + * To solve this problem, we introduce ng-selected. + * @example +    <doc:example> +      <doc:source> +        Check me to select: <input type="checkbox" ng-model="checked"><br/> +        <select> +          <option>Hello!</option> +          <option id="greet" ng-selected="{{checked}}">Greetings!</option> +        </select> +      </doc:source> +      <doc:scenario> +        it('should select Greetings!', function() { +          expect(element('.doc-example-live #greet').prop('selected')).toBeFalsy(); +          input('checked').check(); +          expect(element('.doc-example-live #greet').prop('selected')).toBeTruthy(); +        }); +      </doc:scenario> +    </doc:example> + * @element OPTION + * @param {template} ng-selected any string which can contain '{{}}' markup. + */ +   function ngAttributeAliasDirective(propName, attrName) {    ngAttributeAliasDirectives[directiveNormalize('ng-' + attrName)] = valueFn( diff --git a/src/directive/form.js b/src/directive/form.js index 84352902..96f7632b 100644 --- a/src/directive/form.js +++ b/src/directive/form.js @@ -105,6 +105,7 @@ function FormController($scope, name) {  /**   * @ngdoc directive   * @name angular.module.ng.$compileProvider.directive.form + * @restrict EA   *   * @scope   * @description diff --git a/src/directive/input.js b/src/directive/input.js index cccfb675..1a3acd01 100644 --- a/src/directive/input.js +++ b/src/directive/input.js @@ -616,6 +616,7 @@ function checkboxInputType(scope, element, attr, ctrl) {  /**   * @ngdoc directive   * @name angular.module.ng.$compileProvider.directive.input + * @restrict E   *   * @description   * HTML input element widget with angular data-binding. Input widget follows HTML5 input types @@ -916,6 +917,7 @@ var ngModelDirective = [function() {  /**   * @ngdoc directive   * @name angular.module.ng.$compileProvider.directive.ng-change + * @restrict E   *   * @description   * Evaluate given expression when user changes the input. diff --git a/src/directive/ngBind.js b/src/directive/ngBind.js index cf9b5688..cc80ac5a 100644 --- a/src/directive/ngBind.js +++ b/src/directive/ngBind.js @@ -158,6 +158,7 @@ var ngBindTemplateDirective = ['$interpolate', function($interpolate) {  /**   * @ngdoc directive   * @name angular.module.ng.$compileProvider.directive.ng-bind-attr + * @restrict A   *   * @description   * The `ng-bind-attr` attribute specifies that a diff --git a/src/directive/ngSwitch.js b/src/directive/ngSwitch.js index a4f5afad..59c7056e 100644 --- a/src/directive/ngSwitch.js +++ b/src/directive/ngSwitch.js @@ -15,7 +15,7 @@   *   <any ng-switch-default>...</any>   *   * @scope - * @param {*} on expression to match against <tt>ng-switch-when</tt>. + * @param {*} ng-switch|on expression to match against <tt>ng-switch-when</tt>.   * @paramDescription   * On child elments add:   * diff --git a/src/directive/script.js b/src/directive/script.js index 98e6394a..4090ae24 100644 --- a/src/directive/script.js +++ b/src/directive/script.js @@ -9,6 +9,7 @@   * template can be used by `ng-include`, `ng-view` or directive templates.   *   * @restrict E + * @param {'text/ng-template'} type must be set to `'text/ng-template'`   *   * @example    <doc:example> diff --git a/src/directive/select.js b/src/directive/select.js index 0ab35d1c..e5d619b9 100644 --- a/src/directive/select.js +++ b/src/directive/select.js @@ -3,6 +3,7 @@  /**   * @ngdoc directive   * @name angular.module.ng.$compileProvider.directive.select + * @restrict E   *   * @description   * HTML `SELECT` element with angular data-binding. diff --git a/src/widgets.js b/src/widgets.js deleted file mode 100644 index e69de29b..00000000 --- a/src/widgets.js +++ /dev/null | 
