Skip to content
This repository has been archived by the owner on Aug 29, 2023. It is now read-only.

Commit

Permalink
fix(tabs): properly detect text changes
Browse files Browse the repository at this point in the history
* Currently the MutationObserver is watching for attribute changes and subtree modifications.
  It also watches for text content changes, but that's not working properly for span elements with `<md-tab-label>` elements.
  See https://bugzilla.mozilla.org/show_bug.cgi?id=1138368

The MutationObserver should watch for `characterData` to properly detect text changes.

Fixes #8667.

Closes #8803
  • Loading branch information
devversion authored and ThomasBurleson committed Jun 20, 2016
1 parent bb04bfa commit 121a39d
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 14 deletions.
10 changes: 9 additions & 1 deletion src/components/tabs/js/tabsDummyWrapperDirective.js
Expand Up @@ -21,7 +21,15 @@ function MdTabsDummyWrapper ($mdUtil) {
ctrl.updatePagination();
ctrl.updateInkBarStyles();
});
var config = { childList: true, subtree: true };

var config = {
childList: true,
subtree: true,
// Per https://bugzilla.mozilla.org/show_bug.cgi?id=1138368, browsers will not fire
// the childList mutation, once a <span> element's innerText changes.
// The characterData of the <span> element will change.
characterData: true
};

observer.observe(element[0], config);

Expand Down
77 changes: 64 additions & 13 deletions src/components/tabs/tabs.spec.js
Expand Up @@ -233,7 +233,7 @@ describe('<md-tabs>', function () {
});

it('updates pagination and ink styles when string labels change', function(done) {
inject(function($rootScope) {
inject(function($rootScope, $timeout) {
// Setup our initial label
$rootScope.$apply('label = "Some Label"');

Expand All @@ -242,21 +242,72 @@ describe('<md-tabs>', function () {
var tabs = setup(template);
var ctrl = tabs.controller('mdTabs');

// Setup spies
spyOn(ctrl, 'updatePagination');
spyOn(ctrl, 'updateInkBarStyles');

// Change the label
$rootScope.$apply('label="Another Label"');
// Flush the tabs controller timeout for initialization.
$timeout.flush();

// Use window.setTimeout to add our expectations to the end of the call stack, after the
// After the first timeout the mutation observer should have been fired once, because
// the initialization of the dummy tabs, already causes some mutations.
// Use setTimeout to add our expectations to the end of the call stack, after the
// MutationObservers have already fired
window.setTimeout(function() {
// Fire expectations
expect(ctrl.updatePagination.calls.count()).toBe(1);
expect(ctrl.updateInkBarStyles.calls.count()).toBe(1);
setTimeout(function() {
// Setup spies
spyOn(ctrl, 'updatePagination');
spyOn(ctrl, 'updateInkBarStyles');

// Update the label to trigger a new update of the pagination and InkBar styles.
$rootScope.$apply('label = "Another Label"');

// Use setTimeout to add our expectations to the end of the call stack, after the
// MutationObservers have already fired
setTimeout(function() {
expect(ctrl.updatePagination).toHaveBeenCalledTimes(1);
expect(ctrl.updateInkBarStyles).toHaveBeenCalledTimes(1);

done();
});
});
})
});

done();
it('updates pagination and ink styles when content label changes', function(done) {
inject(function($rootScope, $timeout) {
// Setup our initial label
$rootScope.$apply('label = "Default Label"');

// Init our variables
var template = '' +
'<md-tabs>' +
'<md-tab>' +
'<md-tab-label>{{ label }}</md-tab-label>' +
'</md-tab>' +
'</md-tabs>';

var tabs = setup(template);
var ctrl = tabs.controller('mdTabs');

// Flush the tabs controller timeout for initialization.
$timeout.flush();

// After the first timeout the mutation observer should have been fired once, because
// the initialization of the dummy tabs, already causes some mutations.
// Use setTimeout to add our expectations to the end of the call stack, after the
// MutationObservers have already fired
setTimeout(function() {
// Setup spies
spyOn(ctrl, 'updatePagination');
spyOn(ctrl, 'updateInkBarStyles');

// Update the label to trigger a new update of the pagination and InkBar styles.
$rootScope.$apply('label = "New Label"');

// Use setTimeout to add our expectations to the end of the call stack, after the
// MutationObservers have already fired
setTimeout(function() {
expect(ctrl.updatePagination).toHaveBeenCalledTimes(1);
expect(ctrl.updateInkBarStyles).toHaveBeenCalledTimes(1);

done();
});
});
})
});
Expand Down

0 comments on commit 121a39d

Please sign in to comment.