diff options
| -rw-r--r-- | CHANGELOG.md | 3 | ||||
| -rw-r--r-- | docs/angular.element.ngdoc | 13 | ||||
| -rw-r--r-- | src/Angular.js | 9 | ||||
| -rw-r--r-- | src/Compiler.js | 12 | ||||
| -rw-r--r-- | src/jqLite.js | 9 | ||||
| -rw-r--r-- | src/widgets.js | 2 | ||||
| -rw-r--r-- | test/CompilerSpec.js | 20 | ||||
| -rw-r--r-- | test/jqLiteSpec.js | 31 |
8 files changed, 61 insertions, 38 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 46323915..de7b3f4f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,9 @@ - setting the parent scope for scopes created by the service via `#parent()` - reloading the current route via `#reload()` +### API +- added `angular.element(...).scope()` method to retrieve scope for a given element. + ### Bug Fixes - <option> value attribute gets clobbered when the element contains new line character(s). - <ng:view> widget now works when nested inside an <ng:include> widget diff --git a/docs/angular.element.ngdoc b/docs/angular.element.ngdoc index a636cc25..90025799 100644 --- a/docs/angular.element.ngdoc +++ b/docs/angular.element.ngdoc @@ -9,16 +9,17 @@ Wraps a raw DOM element or HTML string as [jQuery](http://jquery.com) element. jQuery is loaded or a function that wraps the element or string in angular's jQuery lite implementation. -Real jQuery always takes precedence if it was loaded before angular. +Real jQuery always takes precedence (as long as it was loaded before `DOMContentEvent`) Angular's jQuery lite implementation is a tiny API-compatible subset of jQuery which allows -angular to manipulate DOM. The functions implemented are usually just the basic versions of -them and might not support arguments and invocation styles. +angular to manipulate DOM. The jQuery lite implements only a subset of jQuery api, with the +focus on the most commonly needed functionality and minimal footprint. For this reason only a +limited number of jQuery methods, arguments and invocation styles are supported. NOTE: All element references in angular are always wrapped with jQuery (lite) and are never raw DOM references. -Angular's jQuery lite implements these functions: +## Angular's jQuery lite implements these functions: - [addClass()](http://api.jquery.com/addClass/) - [after()](http://api.jquery.com/after/) @@ -39,5 +40,9 @@ Angular's jQuery lite implements these functions: - [text()](http://api.jquery.com/text/) - [trigger()](http://api.jquery.com/trigger/) +## Additionally these methods are available in both jQuery and jQuery lite version. + +- `scope()` - retrieves the current angular scope of the element. + @param {string|DOMElement} element HTML string or DOMElement to be wrapped into jQuery. @returns {Object} jQuery object. diff --git a/src/Angular.js b/src/Angular.js index b856aa24..9a1ab4a2 100644 --- a/src/Angular.js +++ b/src/Angular.js @@ -1032,5 +1032,12 @@ function angularJsConfig(document, config) { function bindJQuery(){ // bind to jQuery if present; jQuery = window.jQuery; - angular.element = jqLite = jQuery || jqLiteWrap; + // reset to jQuery or default to us. + if (window.jQuery) { + jqLite = window.jQuery; + jqLite.fn.scope = JQLite.prototype.scope; + } else { + jqLite = jqLiteWrap; + } + angular.element = jqLite; } diff --git a/src/Compiler.js b/src/Compiler.js index 472ec625..d1505404 100644 --- a/src/Compiler.js +++ b/src/Compiler.js @@ -69,18 +69,6 @@ Template.prototype = { } }; -/* - * Function walks up the element chain looking for the scope associated with the give element. - */ -function retrieveScope(element) { - var scope; - element = jqLite(element); - while (element && element.length && !(scope = element.data($$scope))) { - element = element.parent(); - } - return scope; -} - /////////////////////////////////// //Compiler ////////////////////////////////// diff --git a/src/jqLite.js b/src/jqLite.js index ad7734c9..206c1d70 100644 --- a/src/jqLite.js +++ b/src/jqLite.js @@ -87,6 +87,15 @@ JQLite.prototype = { })(this[0]); }, + scope: function() { + var scope, element = this; + while (element && element.length && !(scope = element.data($$scope))) { + element = element.parent(); + } + return scope; + }, + + ready: function(fn) { var fired = false; diff --git a/src/widgets.js b/src/widgets.js index 461684ac..f8efae60 100644 --- a/src/widgets.js +++ b/src/widgets.js @@ -561,7 +561,7 @@ angularWidget('option', function(){ return function(option) { var select = option.parent(); var isMultiple = select[0].type == 'select-multiple'; - var scope = retrieveScope(select); + var scope = select.scope(); var model = modelAccessor(scope, select); //if parent select doesn't have a name, don't bother doing anything any more diff --git a/test/CompilerSpec.js b/test/CompilerSpec.js index 498ee060..291a5011 100644 --- a/test/CompilerSpec.js +++ b/test/CompilerSpec.js @@ -166,24 +166,4 @@ describe('compiler', function(){ scope = compile('A---B---C===D'); expect(sortedHtml(scope.$element)).toEqual('<div>A<hr></hr>B<hr></hr>C<p></p>D</div>'); }); - - - describe('retrieveScope', function() { - it('should retrieve scope attached to the current element', function() { - scope = compile('<i>foo</i>'); - expect(retrieveScope(scope.$element)).toBe(scope); - }); - - it('should walk up the dom to find scope', function() { - scope = compile('<ul><li><p><b>deep deep</b><p></li></ul>'); - var deepChild = scope.$element[0].getElementsByTagName('b')[0]; - expect(retrieveScope(deepChild)).toBe(scope); - }); - - it('should return undefined when no scope was found', function() { - var html = jqLite('<ul><li><p><b>deep deep</b><p></li></ul>'), - deepChild = html[0].getElementsByTagName('b')[0]; - expect(retrieveScope(deepChild)).toBeNull(); - }); - }); }); diff --git a/test/jqLiteSpec.js b/test/jqLiteSpec.js new file mode 100644 index 00000000..da8ab206 --- /dev/null +++ b/test/jqLiteSpec.js @@ -0,0 +1,31 @@ +describe('jqLite', function(){ + var scope; + + beforeEach(function(){ + scope = angular.scope(); + }); + + describe('scope', function() { + it('should retrieve scope attached to the current element', function() { + var element = jqLite('<i>foo</i>'); + element.data('$scope', scope); + expect(element.scope()).toBe(scope); + dealoc(element); + }); + + it('should walk up the dom to find scope', function() { + var element = jqLite('<ul><li><p><b>deep deep</b><p></li></ul>'); + var deepChild = jqLite(element[0].getElementsByTagName('b')[0]); + element.data('$scope', scope); + expect(deepChild.scope()).toBe(scope); + dealoc(element); + }); + + it('should return undefined when no scope was found', function() { + var element = jqLite('<ul><li><p><b>deep deep</b><p></li></ul>'); + var deepChild = jqLite(element[0].getElementsByTagName('b')[0]); + expect(deepChild.scope()).toBeNull(); + dealoc(element); + }); + }); +}); |
