|
212 | 212 | * * (no prefix) - Locate the required controller on the current element. Throw an error if not found.
|
213 | 213 | * * `?` - Attempt to locate the required controller or pass `null` to the `link` fn if not found.
|
214 | 214 | * * `^` - Locate the required controller by searching the element and its parents. Throw an error if not found.
|
| 215 | + * * `^^` - Locate the required controller by searching the element's parents. Throw an error if not found. |
215 | 216 | * * `?^` - Attempt to locate the required controller by searching the element and its parents or pass
|
216 | 217 | * `null` to the `link` fn if not found.
|
| 218 | + * * `?^^` - Attempt to locate the required controller by searching the element's parents, or pass |
| 219 | + * `null` to the `link` fn if not found. |
217 | 220 | *
|
218 | 221 | *
|
219 | 222 | * #### `controllerAs`
|
@@ -567,7 +570,8 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
567 | 570 | Suffix = 'Directive',
|
568 | 571 | COMMENT_DIRECTIVE_REGEXP = /^\s*directive\:\s*([\d\w_\-]+)\s+(.*)$/,
|
569 | 572 | CLASS_DIRECTIVE_REGEXP = /(([\d\w_\-]+)(?:\:([^;]+))?;?)/,
|
570 |
| - ALL_OR_NOTHING_ATTRS = makeMap('ngSrc,ngSrcset,src,srcset'); |
| 573 | + ALL_OR_NOTHING_ATTRS = makeMap('ngSrc,ngSrcset,src,srcset'), |
| 574 | + REQUIRE_PREFIX_REGEXP = /^(?:(\^\^?)?(\?)?(\^\^?)?)?/; |
571 | 575 |
|
572 | 576 | // Ref: http://developers.whatwg.org/webappapis.html#event-handler-idl-attributes
|
573 | 577 | // The assumption is that future DOM event attribute names will begin with
|
@@ -1589,22 +1593,34 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
1589 | 1593 |
|
1590 | 1594 | function getControllers(directiveName, require, $element, elementControllers) {
|
1591 | 1595 | var value, retrievalMethod = 'data', optional = false;
|
| 1596 | + var $searchElement = $element; |
| 1597 | + var match; |
1592 | 1598 | if (isString(require)) {
|
1593 |
| - while((value = require.charAt(0)) == '^' || value == '?') { |
1594 |
| - require = require.substr(1); |
1595 |
| - if (value == '^') { |
1596 |
| - retrievalMethod = 'inheritedData'; |
1597 |
| - } |
1598 |
| - optional = optional || value == '?'; |
| 1599 | + match = require.match(REQUIRE_PREFIX_REGEXP); |
| 1600 | + require = require.substring(match[0].length); |
| 1601 | + |
| 1602 | + if (match[3]) { |
| 1603 | + if (match[1]) match[3] = null; |
| 1604 | + else match[1] = match[3]; |
1599 | 1605 | }
|
| 1606 | + if (match[1] === '^') { |
| 1607 | + retrievalMethod = 'inheritedData'; |
| 1608 | + } else if (match[1] === '^^') { |
| 1609 | + retrievalMethod = 'inheritedData'; |
| 1610 | + $searchElement = $element.parent(); |
| 1611 | + } |
| 1612 | + if (match[2] === '?') { |
| 1613 | + optional = true; |
| 1614 | + } |
| 1615 | + |
1600 | 1616 | value = null;
|
1601 | 1617 |
|
1602 | 1618 | if (elementControllers && retrievalMethod === 'data') {
|
1603 | 1619 | if (value = elementControllers[require]) {
|
1604 | 1620 | value = value.instance;
|
1605 | 1621 | }
|
1606 | 1622 | }
|
1607 |
| - value = value || $element[retrievalMethod]('$' + require + 'Controller'); |
| 1623 | + value = value || $searchElement[retrievalMethod]('$' + require + 'Controller'); |
1608 | 1624 |
|
1609 | 1625 | if (!value && !optional) {
|
1610 | 1626 | throw $compileMinErr('ctreq',
|
|
0 commit comments