forked from mirrors/gecko-dev
		
	 d2ebbb38df
			
		
	
	
		d2ebbb38df
		
	
	
	
	
		
			
			This removes the sync reflow from almost all cases. The only case where we keep it is when a keypress caught in content triggers a sync message to the parent process. We should clean this up in bug 1371523. I've tried to fix the tests, but a lot of them seem to be disabled anyway... MozReview-Commit-ID: 9k36p7q8MKy --HG-- extra : rebase_source : 311ee41ba9456a5c5d58b81a0cfa999bcef0027e
		
			
				
	
	
		
			198 lines
		
	
	
	
		
			7.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			198 lines
		
	
	
	
		
			7.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| "use strict";
 | |
| 
 | |
| ChromeUtils.defineModuleGetter(this, "setTimeout", "resource://gre/modules/Timer.jsm");
 | |
| 
 | |
| const kFixtureBaseURL = "https://example.com/browser/toolkit/modules/tests/browser/";
 | |
| 
 | |
| function removeDupes(list) {
 | |
|   let j = 0;
 | |
|   for (let i = 1; i < list.length; i++) {
 | |
|     if (list[i] != list[j]) {
 | |
|       j++;
 | |
|       if (i != j) {
 | |
|         list[j] = list[i];
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   list.length = j + 1;
 | |
| }
 | |
| 
 | |
| function compareLists(list1, list2, kind) {
 | |
|   list1.sort();
 | |
|   removeDupes(list1);
 | |
|   list2.sort();
 | |
|   removeDupes(list2);
 | |
|   is(String(list1), String(list2), `${kind} URLs correct`);
 | |
| }
 | |
| 
 | |
| async function promiseOpenFindbar(findbar) {
 | |
|   await gBrowser.getFindBar();
 | |
|   findbar.onFindCommand();
 | |
|   return gFindBar._startFindDeferred && gFindBar._startFindDeferred.promise;
 | |
| }
 | |
| 
 | |
| function promiseFindResult(findbar, str = null) {
 | |
|   let highlightFinished = false;
 | |
|   let findFinished = false;
 | |
|   return new Promise(resolve => {
 | |
|     let listener = {
 | |
|       onFindResult({ searchString }) {
 | |
|         if (str !== null && str != searchString) {
 | |
|           return;
 | |
|         }
 | |
|         findFinished = true;
 | |
|         if (highlightFinished) {
 | |
|           findbar.browser.finder.removeResultListener(listener);
 | |
|           resolve();
 | |
|         }
 | |
|       },
 | |
|       onHighlightFinished() {
 | |
|         highlightFinished = true;
 | |
|         if (findFinished) {
 | |
|           findbar.browser.finder.removeResultListener(listener);
 | |
|           resolve();
 | |
|         }
 | |
|       },
 | |
|       onMatchesCountResult: () => {}
 | |
|     };
 | |
|     findbar.browser.finder.addResultListener(listener);
 | |
|   });
 | |
| }
 | |
| 
 | |
| function promiseEnterStringIntoFindField(findbar, str) {
 | |
|   let promise = promiseFindResult(findbar, str);
 | |
|   for (let i = 0; i < str.length; i++) {
 | |
|     let event = document.createEvent("KeyboardEvent");
 | |
|     event.initKeyEvent("keypress", true, true, null, false, false,
 | |
|                        false, false, 0, str.charCodeAt(i));
 | |
|     findbar._findField.inputField.dispatchEvent(event);
 | |
|   }
 | |
|   return promise;
 | |
| }
 | |
| 
 | |
| function promiseTestHighlighterOutput(browser, word, expectedResult, extraTest = () => {}) {
 | |
|   return ContentTask.spawn(browser, { word, expectedResult, extraTest: extraTest.toSource() },
 | |
|     async function({ word, expectedResult, extraTest }) {
 | |
|     return new Promise((resolve, reject) => {
 | |
|       let stubbed = {};
 | |
|       let callCounts = {
 | |
|         insertCalls: [],
 | |
|         removeCalls: [],
 | |
|         animationCalls: []
 | |
|       };
 | |
|       let lastMaskNode, lastOutlineNode;
 | |
|       let rects = [];
 | |
| 
 | |
|       // Amount of milliseconds to wait after the last time one of our stubs
 | |
|       // was called.
 | |
|       const kTimeoutMs = 1000;
 | |
|       // The initial timeout may wait for a while for results to come in.
 | |
|       let timeout = setTimeout(() => finish(false, "Timeout"), kTimeoutMs * 5);
 | |
| 
 | |
|       function finish(ok = true, message = "finished with error") {
 | |
|         // Restore the functions we stubbed out.
 | |
|         try {
 | |
|           content.document.insertAnonymousContent = stubbed.insert;
 | |
|           content.document.removeAnonymousContent = stubbed.remove;
 | |
|         } catch (ex) {}
 | |
|         stubbed = {};
 | |
|         clearTimeout(timeout);
 | |
| 
 | |
|         if (expectedResult.rectCount !== 0)
 | |
|           Assert.ok(ok, message);
 | |
| 
 | |
|         Assert.greaterOrEqual(callCounts.insertCalls.length, expectedResult.insertCalls[0],
 | |
|           `Min. insert calls should match for '${word}'.`);
 | |
|         Assert.lessOrEqual(callCounts.insertCalls.length, expectedResult.insertCalls[1],
 | |
|           `Max. insert calls should match for '${word}'.`);
 | |
|         Assert.greaterOrEqual(callCounts.removeCalls.length, expectedResult.removeCalls[0],
 | |
|           `Min. remove calls should match for '${word}'.`);
 | |
|         Assert.lessOrEqual(callCounts.removeCalls.length, expectedResult.removeCalls[1],
 | |
|           `Max. remove calls should match for '${word}'.`);
 | |
| 
 | |
|         // We reached the amount of calls we expected, so now we can check
 | |
|         // the amount of rects.
 | |
|         if (!lastMaskNode && expectedResult.rectCount !== 0) {
 | |
|           Assert.ok(false, `No mask node found, but expected ${expectedResult.rectCount} rects.`);
 | |
|         }
 | |
| 
 | |
|         Assert.equal(rects.length, expectedResult.rectCount,
 | |
|           `Amount of inserted rects should match for '${word}'.`);
 | |
| 
 | |
|         if ("animationCalls" in expectedResult) {
 | |
|           Assert.greaterOrEqual(callCounts.animationCalls.length,
 | |
|             expectedResult.animationCalls[0], `Min. animation calls should match for '${word}'.`);
 | |
|           Assert.lessOrEqual(callCounts.animationCalls.length,
 | |
|             expectedResult.animationCalls[1], `Max. animation calls should match for '${word}'.`);
 | |
|         }
 | |
| 
 | |
|         // Allow more specific assertions to be tested in `extraTest`.
 | |
|         // eslint-disable-next-line no-eval
 | |
|         extraTest = eval(extraTest);
 | |
|         extraTest(lastMaskNode, lastOutlineNode, rects);
 | |
| 
 | |
|         resolve();
 | |
|       }
 | |
| 
 | |
|       function stubAnonymousContentNode(domNode, anonNode) {
 | |
|         let originals = [anonNode.setTextContentForElement,
 | |
|           anonNode.setAttributeForElement, anonNode.removeAttributeForElement,
 | |
|           anonNode.setCutoutRectsForElement, anonNode.setAnimationForElement];
 | |
|         anonNode.setTextContentForElement = (id, text) => {
 | |
|           try {
 | |
|             (domNode.querySelector("#" + id) || domNode).textContent = text;
 | |
|           } catch (ex) {}
 | |
|           return originals[0].call(anonNode, id, text);
 | |
|         };
 | |
|         anonNode.setAttributeForElement = (id, attrName, attrValue) => {
 | |
|           try {
 | |
|             (domNode.querySelector("#" + id) || domNode).setAttribute(attrName, attrValue);
 | |
|           } catch (ex) {}
 | |
|           return originals[1].call(anonNode, id, attrName, attrValue);
 | |
|         };
 | |
|         anonNode.removeAttributeForElement = (id, attrName) => {
 | |
|           try {
 | |
|             let node = domNode.querySelector("#" + id) || domNode;
 | |
|             if (node.hasAttribute(attrName))
 | |
|               node.removeAttribute(attrName);
 | |
|           } catch (ex) {}
 | |
|           return originals[2].call(anonNode, id, attrName);
 | |
|         };
 | |
|         anonNode.setCutoutRectsForElement = (id, cutoutRects) => {
 | |
|           rects = cutoutRects;
 | |
|           return originals[3].call(anonNode, id, cutoutRects);
 | |
|         };
 | |
|         anonNode.setAnimationForElement = (id, keyframes, options) => {
 | |
|           callCounts.animationCalls.push([keyframes, options]);
 | |
|           return originals[4].call(anonNode, id, keyframes, options);
 | |
|         };
 | |
|       }
 | |
| 
 | |
|       // Create a function that will stub the original version and collects
 | |
|       // the arguments so we can check the results later.
 | |
|       function stub(which) {
 | |
|         stubbed[which] = content.document[which + "AnonymousContent"];
 | |
|         let prop = which + "Calls";
 | |
|         return function(node) {
 | |
|           callCounts[prop].push(node);
 | |
|           if (which == "insert") {
 | |
|             if (node.outerHTML.indexOf("outlineMask") > -1)
 | |
|               lastMaskNode = node;
 | |
|             else
 | |
|               lastOutlineNode = node;
 | |
|           }
 | |
|           clearTimeout(timeout);
 | |
|           timeout = setTimeout(() => {
 | |
|             finish();
 | |
|           }, kTimeoutMs);
 | |
|           let res = stubbed[which].call(content.document, node);
 | |
|           if (which == "insert")
 | |
|             stubAnonymousContentNode(node, res);
 | |
|           return res;
 | |
|         };
 | |
|       }
 | |
|       content.document.insertAnonymousContent = stub("insert");
 | |
|       content.document.removeAnonymousContent = stub("remove");
 | |
|     });
 | |
|   });
 | |
| }
 |