Fixed infinite loops in onmatch() and onunmatch() when using $.entwine.synchronous_mode() with DOM manipulations in these methods. Allowing $.entwine.synchronous_mode() to be turned off again

This commit is contained in:
Ingo Schommer 2011-03-08 08:25:06 +13:00
parent a05de97706
commit 1fca5c5089
5 changed files with 55 additions and 5 deletions

View File

@ -1 +0,0 @@
jquery.entwine-dist.js

View File

@ -1459,12 +1459,20 @@ var console;
// Find the ones that are gone this time
rem = rule.cache.not(res);
// And call the destructor on them
if (rem.length) ctors.onunmatchproxy(rem, j, dtor);
if (rem.length && !rule.onunmatchRunning) {
rule.onunmatchRunning = true;
ctors.onunmatchproxy(rem, j, dtor);
rule.onunmatchRunning = false;
}
}
}
// Call the constructor on the newly matched ones
if (add.length && ctor) ctors.onmatchproxy(add, j, ctor);
if (add.length && ctor && !rule.onmatchRunning) {
rule.onmatchRunning = true;
ctors.onmatchproxy(add, j, ctor);
rule.onmatchRunning = false;
}
// Add these matched ones to the list tracking all elements matched so far
matched = matched.add(res);

View File

@ -29,6 +29,7 @@
<script type="text/javascript" src="spec.entwine.namespaces.js"></script>
<script type="text/javascript" src="spec.entwine.properties.js"></script>
<script type="text/javascript" src="spec.entwine.super.js"></script>
<script type="text/javascript" src="spec.entwine.synchronous.js"></script>
</head>
<body>

View File

@ -0,0 +1,34 @@
describe( 'Entwine', function() {
beforeEach(function() {
$.entwine.warningLevel = $.entwine.WARN_LEVEL_BESTPRACTISE;
$.entwine.synchronous_mode(true);
$('body').append('<div id="dom_test"></div>');
});
afterEach(function() {
$('#dom_test').remove();
$.entwine.synchronous_mode(false);
});
describe( 'Synchronous Mode', function() {
beforeEach(function() {
// $.entwine.clear_all_rules();
});
it( 'can modify the DOM in onmatch', function() {
$('#a').entwine({onmatch: function() {this.append('<div class="appended"></div>');}});
$('#dom_test').append('<div id="a" class="a b c" data-fieldtype="foo"></div><div id="b" class="c d e"></div>');
expect($('#a .appended').length).toEqual(1);
});
it( 'can modify the DOM in onunmatch', function() {
$('#a').entwine({onunmatch: function() {$('#dom_test').append('<div class="appended"></div>');}});
$('#dom_test').append('<div id="a" class="a b c" data-fieldtype="foo"></div><div id="b" class="c d e"></div>');
$('#dom_test').find('#a').remove();
expect($('#dom_test .appended').length).toEqual(1);
});
});
});

View File

@ -90,12 +90,20 @@
// Find the ones that are gone this time
rem = rule.cache.not(res);
// And call the destructor on them
if (rem.length) ctors.onunmatchproxy(rem, j, dtor);
if (rem.length && !rule.onunmatchRunning) {
rule.onunmatchRunning = true;
ctors.onunmatchproxy(rem, j, dtor);
rule.onunmatchRunning = false;
}
}
}
// Call the constructor on the newly matched ones
if (add.length && ctor) ctors.onmatchproxy(add, j, ctor);
if (add.length && ctor && !rule.onmatchRunning) {
rule.onmatchRunning = true;
ctors.onmatchproxy(add, j, ctor);
rule.onmatchRunning = false;
}
// Add these matched ones to the list tracking all elements matched so far
matched = matched.add(res);