Permalink
Browse files

Update jQuery Entwine to latest to pull memory leak fix

  • Loading branch information...
1 parent de3b1b2 commit 13377ee4bd6de649a228c47b48f1be17581b6a59 Hamish Friedlander committed Aug 20, 2013
@@ -3,6 +3,6 @@ repository_url: https://github.com/hafriedlander/jquery.entwine.git
format: 1
handler:
branch: master
- commit: 21af92dbad424148af6dd7ea310ab7344fcf7015
-repository_class: Piston::Git::Repository
+ commit: 0e475ced9ef10e1f854bcd70ac157a489236105d
lock: false
+repository_class: Piston::Git::Repository
@@ -2,9 +2,20 @@ h1. Entwine - Support for Concrete UI style programming in jQuery
By Hamish Friedlander, with thanks to "SilverStripe":http://www.silverstripe.com/
-Entwine tries to provide a new model of code organisation - a replacement for Object Oriented programming that is focused on adding functions to groups of DOM elements based on the structure and contents of those DOM elements. It's a merging of the model and view layer that initially seems weird, but can give very powerful results.
+Entwine tries to provide a new model of code organisation - a replacement for Object Oriented programming that is
+focused on adding functions to groups of DOM elements based on the structure and contents of those DOM elements. It's a
+merging of the model and view layer that initially seems weird, but can give very powerful results.
-We're standing on the shoulders of giants here - combining ideas from Prototype's behaviour & lowpro and jQuery's effen & livequery (who themselves stole ideals from Self's Morphic UI and others), but extending & combining the concepts presented in those tools to provide a complete alternative to traditional OO concepts - self-aware methods, inheritance, polymorphisim and namespacing without a single class definition.
+We're standing on the shoulders of giants here - combining ideas from Prototype's behaviour & lowpro and jQuery's effen
+& livequery (who themselves stole ideals from Self's Morphic UI and others), but extending & combining the concepts
+presented in those tools to provide a complete alternative to traditional OO concepts - self-aware methods, inheritance,
+polymorphisim and namespacing without a single class definition.
+
+h2. Requirements
+
+Currently Entwine layers itself on top of jQuery. Any patch level of jQuery from 1.7 through 1.10 or 2.0 should work.
+Because we patch some internal jQuery APIs there can be a delay between a new version of jQuery being released
+and Entwine providing support.
h2. Getting Started
@@ -753,8 +753,11 @@ Sizzle is good for finding elements for a selector, but not so good for telling
* Add focusin and focusout support to bind and live for browers other than IE. Designed to be usable in a delegated fashion (like $.live)
* Copyright (c) 2007 Jörn Zaefferer
*/
- $.support.focusInOut = !!($.browser.msie);
- if (!$.support.focusInOut) {
+ if ($.support.focusinBubbles === undefined) {
+ $.support.focusinBubbles = !!($.browser.msie);
+ }
+
+ if (!$.support.focusinBubbles && !$.event.special.focusin) {
// Emulate focusin and focusout by binding focus and blur in capturing mode
$.each({focus: 'focusin', blur: 'focusout'}, function(original, fix){
$.event.special[fix] = {
@@ -807,8 +810,30 @@ catch (e) {
window.console = undefined;
}
-(function($) {
-
+(function($) {
+
+ /* Create a subclass of the jQuery object. This was introduced in jQuery 1.5, but removed again in 1.9 */
+ var sub = function() {
+ function jQuerySub( selector, context ) {
+ return new jQuerySub.fn.init( selector, context );
+ }
+
+ jQuery.extend( true, jQuerySub, $ );
+ jQuerySub.superclass = $;
+ jQuerySub.fn = jQuerySub.prototype = $();
+ jQuerySub.fn.constructor = jQuerySub;
+ jQuerySub.fn.init = function init( selector, context ) {
+ if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) {
+ context = jQuerySub( context );
+ }
+
+ return jQuery.fn.init.call( this, selector, context, rootjQuerySub );
+ };
+ jQuerySub.fn.init.prototype = jQuerySub.fn;
+ var rootjQuerySub = jQuerySub(document);
+ return jQuerySub;
+ };
+
var namespaces = {};
$.entwine = function() {
@@ -928,49 +953,12 @@ catch (e) {
}
else {
// We're in a namespace, so we build a Class that subclasses the jQuery Object Class to inject namespace functions into
-
- // jQuery 1.5 already provides a nice way to subclass, so use it
- if ($.sub) {
- this.$ = $.sub();
- this.injectee = this.$.prototype;
- }
- // For jQuery < 1.5 we have to do it ourselves
- else {
- var subfn = function(){};
- this.injectee = subfn.prototype = new $;
-
- // And then we provide an overriding $ that returns objects of our new Class, and an overriding pushStack to catch further selection building
- var bound$ = this.$ = function(a) {
- // Try the simple way first
- var jq = $.fn.init.apply(new subfn(), arguments);
- if (jq instanceof subfn) return jq;
-
- // That didn't return a bound object, so now we need to copy it
- var rv = new subfn();
- rv.selector = jq.selector; rv.context = jq.context; var i = rv.length = jq.length;
- while (i--) rv[i] = jq[i];
- return rv;
- };
-
- this.injectee.pushStack = function(elems, name, selector){
- var ret = bound$(elems);
+ this.$ = $.sub ? $.sub() : sub();
+ // Work around bug in sub() - subclass must share cache with root or data won't get cleared by cleanData
+ this.$.cache = $.cache;
+
+ this.injectee = this.$.prototype;
- // Add the old object onto the stack (as a reference)
- ret.prevObject = this;
- ret.context = this.context;
-
- if ( name === "find" ) ret.selector = this.selector + (this.selector ? " " : "") + selector;
- else if ( name ) ret.selector = this.selector + "." + name + "(" + selector + ")";
-
- // Return the newly-formed element set
- return ret;
- };
-
- // Copy static functions through from $ to this.$ so e.g. $.ajax still works
- // @bug, @cantfix: Any class functions added to $ after this call won't get mirrored through
- $.extend(this.$, $);
- }
-
// We override entwine to inject the name of this namespace when defining blocks inside this namespace
var entwine_wrapper = this.injectee.entwine = function(spacename) {
var args = arguments;
@@ -1205,32 +1193,37 @@ catch (e) {
var dontTrigger = false;
- // Monkey patch $.fn.domManip to catch all regular jQuery add element calls
- var _domManip = $.prototype.domManip;
- $.prototype.domManip = function(args, table, callback) {
- if (!callback.patched) {
- var original = callback;
- arguments[2] = function(elem){
- var added = [];
-
- if (!dontTrigger) {
- if (elem.nodeType == 1) added[added.length] = elem;
- getElements(added, elem);
- }
+ var patchDomManipCallback = function(original) {
+ var patched = function(elem){
+ var added = [];
- var rv = original.apply(this, arguments);
+ if (!dontTrigger) {
+ if (elem.nodeType == 1) added[added.length] = elem;
+ getElements(added, elem);
+ }
- if (!dontTrigger && added.length) {
- var event = $.Event('EntwineElementsAdded');
- event.targets = added;
- $(document).triggerHandler(event);
- }
+ var rv = original.apply(this, arguments);
- return rv;
+ if (!dontTrigger && added.length) {
+ var event = $.Event('EntwineElementsAdded');
+ event.targets = added;
+ $(document).triggerHandler(event);
}
- arguments[2].patched = true;
+
+ return rv;
}
+ patched.patched = true;
+
+ return patched;
+ }
+ var version = $.prototype.jquery.split('.');
+ var callbackIdx = (version[0] > 1 || version[1] >= 10 ? 1 : 2);
+
+ // Monkey patch $.fn.domManip to catch all regular jQuery add element calls
+ var _domManip = $.prototype.domManip;
+ $.prototype.domManip = function() {
+ if (!arguments[callbackIdx].patched) arguments[callbackIdx] = patchDomManipCallback(arguments[callbackIdx]);
return _domManip.apply(this, arguments);
}
@@ -1772,6 +1765,12 @@ catch (e) {
}
};
+ var document_proxy = function(selector, handler, includechildren) {
+ return function(e){
+ if (e.target === document) return handler.apply(this, arguments);
+ }
+ };
+
var window_proxy = function(selector, handler, includechildren) {
return function(e){
if (e.target === window) return handler.apply(this, arguments);
@@ -1805,6 +1804,7 @@ catch (e) {
if (from.match(/[^\w]/)) proxyGen = selector_proxy;
else if (from == 'Window' || from == 'window') proxyGen = window_proxy;
+ else if (from == 'Document' || from == 'document') proxyGen = document_proxy;
else proxyGen = property_proxy;
for (var onevent in v) {
@@ -753,8 +753,11 @@ Sizzle is good for finding elements for a selector, but not so good for telling
* Add focusin and focusout support to bind and live for browers other than IE. Designed to be usable in a delegated fashion (like $.live)
* Copyright (c) 2007 Jörn Zaefferer
*/
- $.support.focusInOut = !!($.browser.msie);
- if (!$.support.focusInOut) {
+ if ($.support.focusinBubbles === undefined) {
+ $.support.focusinBubbles = !!($.browser.msie);
+ }
+
+ if (!$.support.focusinBubbles && !$.event.special.focusin) {
// Emulate focusin and focusout by binding focus and blur in capturing mode
$.each({focus: 'focusin', blur: 'focusout'}, function(original, fix){
$.event.special[fix] = {
@@ -807,8 +810,30 @@ catch (e) {
window.console = undefined;
}
-(function($) {
-
+(function($) {
+
+ /* Create a subclass of the jQuery object. This was introduced in jQuery 1.5, but removed again in 1.9 */
+ var sub = function() {
+ function jQuerySub( selector, context ) {
+ return new jQuerySub.fn.init( selector, context );
+ }
+
+ jQuery.extend( true, jQuerySub, $ );
+ jQuerySub.superclass = $;
+ jQuerySub.fn = jQuerySub.prototype = $();
+ jQuerySub.fn.constructor = jQuerySub;
+ jQuerySub.fn.init = function init( selector, context ) {
+ if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) {
+ context = jQuerySub( context );
+ }
+
+ return jQuery.fn.init.call( this, selector, context, rootjQuerySub );
+ };
+ jQuerySub.fn.init.prototype = jQuerySub.fn;
+ var rootjQuerySub = jQuerySub(document);
+ return jQuerySub;
+ };
+
var namespaces = {};
$.entwine = function() {
@@ -928,49 +953,12 @@ catch (e) {
}
else {
// We're in a namespace, so we build a Class that subclasses the jQuery Object Class to inject namespace functions into
-
- // jQuery 1.5 already provides a nice way to subclass, so use it
- if ($.sub) {
- this.$ = $.sub();
- this.injectee = this.$.prototype;
- }
- // For jQuery < 1.5 we have to do it ourselves
- else {
- var subfn = function(){};
- this.injectee = subfn.prototype = new $;
-
- // And then we provide an overriding $ that returns objects of our new Class, and an overriding pushStack to catch further selection building
- var bound$ = this.$ = function(a) {
- // Try the simple way first
- var jq = $.fn.init.apply(new subfn(), arguments);
- if (jq instanceof subfn) return jq;
-
- // That didn't return a bound object, so now we need to copy it
- var rv = new subfn();
- rv.selector = jq.selector; rv.context = jq.context; var i = rv.length = jq.length;
- while (i--) rv[i] = jq[i];
- return rv;
- };
-
- this.injectee.pushStack = function(elems, name, selector){
- var ret = bound$(elems);
+ this.$ = $.sub ? $.sub() : sub();
+ // Work around bug in sub() - subclass must share cache with root or data won't get cleared by cleanData
+ this.$.cache = $.cache;
+
+ this.injectee = this.$.prototype;
- // Add the old object onto the stack (as a reference)
- ret.prevObject = this;
- ret.context = this.context;
-
- if ( name === "find" ) ret.selector = this.selector + (this.selector ? " " : "") + selector;
- else if ( name ) ret.selector = this.selector + "." + name + "(" + selector + ")";
-
- // Return the newly-formed element set
- return ret;
- };
-
- // Copy static functions through from $ to this.$ so e.g. $.ajax still works
- // @bug, @cantfix: Any class functions added to $ after this call won't get mirrored through
- $.extend(this.$, $);
- }
-
// We override entwine to inject the name of this namespace when defining blocks inside this namespace
var entwine_wrapper = this.injectee.entwine = function(spacename) {
var args = arguments;
@@ -1205,32 +1193,37 @@ catch (e) {
var dontTrigger = false;
- // Monkey patch $.fn.domManip to catch all regular jQuery add element calls
- var _domManip = $.prototype.domManip;
- $.prototype.domManip = function(args, table, callback) {
- if (!callback.patched) {
- var original = callback;
- arguments[2] = function(elem){
- var added = [];
-
- if (!dontTrigger) {
- if (elem.nodeType == 1) added[added.length] = elem;
- getElements(added, elem);
- }
+ var patchDomManipCallback = function(original) {
+ var patched = function(elem){
+ var added = [];
- var rv = original.apply(this, arguments);
+ if (!dontTrigger) {
+ if (elem.nodeType == 1) added[added.length] = elem;
+ getElements(added, elem);
+ }
- if (!dontTrigger && added.length) {
- var event = $.Event('EntwineElementsAdded');
- event.targets = added;
- $(document).triggerHandler(event);
- }
+ var rv = original.apply(this, arguments);
- return rv;
+ if (!dontTrigger && added.length) {
+ var event = $.Event('EntwineElementsAdded');
+ event.targets = added;
+ $(document).triggerHandler(event);
}
- arguments[2].patched = true;
+
+ return rv;
}
+ patched.patched = true;
+
+ return patched;
+ }
+ var version = $.prototype.jquery.split('.');
+ var callbackIdx = (version[0] > 1 || version[1] >= 10 ? 1 : 2);
+
+ // Monkey patch $.fn.domManip to catch all regular jQuery add element calls
+ var _domManip = $.prototype.domManip;
+ $.prototype.domManip = function() {
+ if (!arguments[callbackIdx].patched) arguments[callbackIdx] = patchDomManipCallback(arguments[callbackIdx]);
return _domManip.apply(this, arguments);
}
@@ -1772,6 +1765,12 @@ catch (e) {
}
};
+ var document_proxy = function(selector, handler, includechildren) {
+ return function(e){
+ if (e.target === document) return handler.apply(this, arguments);
+ }
+ };
+
var window_proxy = function(selector, handler, includechildren) {
return function(e){
if (e.target === window) return handler.apply(this, arguments);
@@ -1805,6 +1804,7 @@ catch (e) {
if (from.match(/[^\w]/)) proxyGen = selector_proxy;
else if (from == 'Window' || from == 'window') proxyGen = window_proxy;
+ else if (from == 'Document' || from == 'document') proxyGen = document_proxy;
else proxyGen = property_proxy;
for (var onevent in v) {
Oops, something went wrong.

0 comments on commit 13377ee

Please sign in to comment.