/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ // Drag and drop stuff from inside one shadow DOM to another shadow DOM. // Includes shadow DOMs in iframes. "use strict"; const kBaseUrl1 = "https://example.org/browser/dom/events/test/"; const kBaseUrl2 = "https://example.com/browser/dom/events/test/"; let testName; let mockCA = { isActive: true, mightBeActive: true, caShouldAllow: undefined, numAnalyzeContentRequestPrivateCalls: undefined, numGetURIForDropEvent: undefined, getURIForDropEvent(event) { info(`[${testName}]| Called getURIForDropEvent`); this.numGetURIForDropEvent += 1; return this.realCAService.getURIForDropEvent(event); }, analyzeContentRequestPrivate(aRequest, _aAutoAcknowledge, aCallback) { info(`[${testName}]| Called analyzeContentRequestPrivate`); this.numAnalyzeContentRequestPrivateCalls += 1; is( aRequest.analysisType, Ci.nsIContentAnalysisRequest.eBulkDataEntry, "request has correct analysisType" ); is( aRequest.reason, Ci.nsIContentAnalysisRequest.eDragAndDrop, "request has correct reason" ); is( aRequest.operationTypeForDisplay, Ci.nsIContentAnalysisRequest.eDroppedText, "request has correct operation type" ); is( aRequest.userActionRequestsCount, 1, "request has correct userActionRequestsCount" ); ok( aRequest.userActionId.length, "request userActionId should not be empty" ); aCallback.contentResult( this.realCAService.makeResponseForTest( this.caShouldAllow ? Ci.nsIContentAnalysisResponse.eAllow : Ci.nsIContentAnalysisResponse.eBlock, aRequest.requestToken, aRequest.userActionId ) ); }, analyzeContentRequests(aRequests, aAutoAcknowledge) { // This will call into our mock analyzeContentRequestPrivate return this.realCAService.analyzeContentRequests( aRequests, aAutoAcknowledge ); }, analyzeBatchContentRequest(aRequest, aAutoAcknowledge) { // This will call into our mock analyzeContentRequestPrivate return this.realCAService.analyzeBatchContentRequest( aRequest, aAutoAcknowledge ); }, analyzeContentRequestsCallback(aRequests, aAutoAcknowledge, aCallback) { // This will call into our mock analyzeContentRequestPrivate this.realCAService.analyzeContentRequestsCallback( aRequests, aAutoAcknowledge, aCallback ); }, showBlockedRequestDialog(aRequest) { info(`got showBlockedRequestDialog for request ${aRequest.requestToken}`); }, }; add_setup(async function () { mockCA = await mockContentAnalysisService(mockCA); await setup({ outerURL1: kBaseUrl1 + "browser_dragdrop_shadow_outer.html", outerURL2: kBaseUrl2 + "browser_dragdrop_shadow_outer.html", innerURL1: kBaseUrl1 + "browser_dragdrop_shadow_inner.html", innerURL2: kBaseUrl2 + "browser_dragdrop_shadow_inner.html", }); }); Services.scriptloader.loadSubScript( "chrome://mochitests/content/browser/dom/events/test/browser_dragdrop_impl.js", this ); const TEST_MODES = Object.freeze({ ALLOW: { caAllow: true, turnOffPref: false, shouldRunCA: true, }, BLOCK: { caAllow: false, turnOffPref: false, shouldRunCA: true, }, PREFOFF: { caAllow: true, turnOffPref: true, shouldRunCA: false, }, }); runTest = async function ( testRootName, sourceBrowsingCxt, targetBrowsingCxt, dndOptions = {} ) { mockCA.sourceBrowsingCxt = sourceBrowsingCxt; mockCA.targetBrowsingCxt = targetBrowsingCxt; for (let testMode of [ TEST_MODES.ALLOW, TEST_MODES.BLOCK, TEST_MODES.PREFOFF, ]) { mockCA.caShouldAllow = testMode.caAllow; mockCA.numAnalyzeContentRequestPrivateCalls = 0; mockCA.numGetURIForDropEvent = 0; let shouldRunCA; let description; if (testMode.shouldRunCA) { shouldRunCA = true; description = testMode.caAllow ? "allow_drop" : "deny_drop"; } else if (testMode.turnOffPref) { shouldRunCA = false; description = "no_run_ca_because_of_dnd_interception_point_pref"; } let name = `${testRootName}:${description}`; info(name); testName = name; if (testMode.turnOffPref) { await SpecialPowers.pushPrefEnv({ set: [ [ "browser.contentanalysis.interception_point.drag_and_drop.enabled", false, ], ], }); } let dropPromise = SpecialPowers.spawn( targetBrowsingCxt, [mockCA.caShouldAllow], async shouldAllow => { let resolver; let promise = new Promise(res => { resolver = res; }); let shadowRoots = content.window.document.getConnectedShadowRoots(); let targetElt; for (let shadowRoot of shadowRoots) { targetElt = shadowRoot.getElementById("dropTarget"); if (targetElt) { break; } } ok(targetElt, "found dropTarget in shadow"); targetElt.addEventListener( shouldAllow ? "drop" : "dragleave", _ => { resolver(); }, { once: true } ); await promise; info("dropPromise was alerted in content"); } ); await runDnd(name, sourceBrowsingCxt, targetBrowsingCxt, { dropPromise, expectDragLeave: !mockCA.caShouldAllow, ...dndOptions, }); is( mockCA.numAnalyzeContentRequestPrivateCalls, shouldRunCA ? 1 : 0, `[${testName}]| Called analyzeContentRequestPrivate correct number of times` ); is( mockCA.numGetURIForDropEvent, 1, `[${testName}]| GetURIForDropEvent was called correct number of times` ); if (testMode.turnOffPref) { await SpecialPowers.popPrefEnv(); } } };