Merge pull request #4131 from karlden/findUnboundedRecursionBug960409

Fixes find functionality recursion (bugzilla FF bug 960409)
This commit is contained in:
Yury Delendik 2014-01-28 06:44:42 -08:00
commit 187c9007ef

View File

@ -52,8 +52,6 @@ var PDFFindController = {
resumePageIdx: null, resumePageIdx: null,
resumeCallback: null,
state: null, state: null,
dirtyMatch: false, dirtyMatch: false,
@ -66,7 +64,7 @@ var PDFFindController = {
initialize: function(options) { initialize: function(options) {
if(typeof PDFFindBar === 'undefined' || PDFFindBar === null) { if(typeof PDFFindBar === 'undefined' || PDFFindBar === null) {
throw 'PDFFindController cannot be initialized ' + throw 'PDFFindController cannot be initialized ' +
'without a PDFFindController instance'; 'without a PDFFindController instance';
} }
@ -126,10 +124,8 @@ var PDFFindController = {
this.pageMatches[pageIndex] = matches; this.pageMatches[pageIndex] = matches;
this.updatePage(pageIndex); this.updatePage(pageIndex);
if (this.resumePageIdx === pageIndex) { if (this.resumePageIdx === pageIndex) {
var callback = this.resumeCallback;
this.resumePageIdx = null; this.resumePageIdx = null;
this.resumeCallback = null; this.nextPageMatch();
callback();
} }
}, },
@ -218,7 +214,6 @@ var PDFFindController = {
this.offset.pageIdx = currentPageIndex; this.offset.pageIdx = currentPageIndex;
this.offset.matchIdx = null; this.offset.matchIdx = null;
this.hadMatch = false; this.hadMatch = false;
this.resumeCallback = null;
this.resumePageIdx = null; this.resumePageIdx = null;
this.pageMatches = []; this.pageMatches = [];
var self = this; var self = this;
@ -245,7 +240,7 @@ var PDFFindController = {
} }
// If we're waiting on a page, we return since we can't do anything else. // If we're waiting on a page, we return since we can't do anything else.
if (this.resumeCallback) { if (this.resumePageIdx) {
return; return;
} }
@ -271,48 +266,51 @@ var PDFFindController = {
this.nextPageMatch(); this.nextPageMatch();
}, },
matchesReady: function(matches) {
var offset = this.offset;
var numMatches = matches.length;
var previous = this.state.findPrevious;
if (numMatches) {
// There were matches for the page, so initialize the matchIdx.
this.hadMatch = true;
offset.matchIdx = previous ? numMatches - 1 : 0;
this.updateMatch(true);
// matches were found
return true;
} else {
// No matches attempt to search the next page.
this.advanceOffsetPage(previous);
if (offset.wrapped) {
offset.matchIdx = null;
if (!this.hadMatch) {
// No point in wrapping there were no matches.
this.updateMatch(false);
// while matches were not found, searching for a page
// with matches should nevertheless halt.
return true;
}
}
// matches were not found (and searching is not done)
return false;
}
},
nextPageMatch: function() { nextPageMatch: function() {
if (this.resumePageIdx !== null) if (this.resumePageIdx !== null)
console.error('There can only be one pending page.'); console.error('There can only be one pending page.');
// done boolean to remove do-while construct per review of PR 4131
var matchesReady = function(matches) { var done = false;
var offset = this.offset; while (!done) {
var numMatches = matches.length; var pageIdx = this.offset.pageIdx;
var previous = this.state.findPrevious; var matches = this.pageMatches[pageIdx];
if (numMatches) { if (!matches) {
// There were matches for the page, so initialize the matchIdx. // The matches don't exist yet for processing by "matchesReady",
this.hadMatch = true; // so set a resume point for when they do exist.
offset.matchIdx = previous ? numMatches - 1 : 0; this.resumePageIdx = pageIdx;
this.updateMatch(true); break;
} else {
// No matches attempt to search the next page.
this.advanceOffsetPage(previous);
if (offset.wrapped) {
offset.matchIdx = null;
if (!this.hadMatch) {
// No point in wrapping there were no matches.
this.updateMatch(false);
return;
}
}
// Search the next page.
this.nextPageMatch();
} }
}.bind(this); done = this.matchesReady(matches);
var pageIdx = this.offset.pageIdx;
var pageMatches = this.pageMatches;
if (!pageMatches[pageIdx]) {
// The matches aren't ready setup a callback so we can be notified,
// when they are ready.
this.resumeCallback = function() {
matchesReady(pageMatches[pageIdx]);
};
this.resumePageIdx = pageIdx;
return;
} }
// The matches are finished already.
matchesReady(pageMatches[pageIdx]);
}, },
advanceOffsetPage: function(previous) { advanceOffsetPage: function(previous) {