summaryrefslogtreecommitdiffstats
path: root/dom/base/test/browser_object_attachment.js
blob: b4432862f0a29a09c79f3ce49f2f0668c543d31b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
ChromeUtils.defineESModuleGetters(this, {
  Downloads: "resource://gre/modules/Downloads.sys.mjs",
});

const httpsTestRoot = getRootDirectory(gTestPath).replace(
  "chrome://mochitests/content",
  "https://example.com"
);

add_task(async function test_pdf_object_attachment() {
  await SpecialPowers.pushPrefEnv({
    set: [["dom.navigation.object_embed.allow_retargeting", false]],
  });

  await BrowserTestUtils.withNewTab(
    `${httpsTestRoot}/file_pdf_object_attachment.html`,
    async browser => {
      is(
        browser.browsingContext.children.length,
        1,
        "Should have a child frame"
      );
      await SpecialPowers.spawn(browser, [], async () => {
        let obj = content.document.querySelector("object");
        is(
          obj.displayedType,
          Ci.nsIObjectLoadingContent.TYPE_DOCUMENT,
          "should be displaying TYPE_DOCUMENT"
        );
      });
    }
  );
});

add_task(async function test_img_object_attachment() {
  await SpecialPowers.pushPrefEnv({
    set: [["dom.navigation.object_embed.allow_retargeting", false]],
  });

  await BrowserTestUtils.withNewTab(
    `${httpsTestRoot}/file_img_object_attachment.html`,
    async browser => {
      is(
        browser.browsingContext.children.length,
        1,
        "Should have a child frame"
      );
      await SpecialPowers.spawn(browser, [], async () => {
        let obj = content.document.querySelector("object");
        is(
          obj.displayedType,
          Ci.nsIObjectLoadingContent.TYPE_DOCUMENT,
          "should be displaying TYPE_DOCUMENT"
        );
      });
    }
  );
});

async function waitForDownload() {
  // Get the downloads list and add a view to listen for a download to be added.
  let downloadList = await Downloads.getList(Downloads.ALL);

  // Wait for a single download
  let downloadView;
  let finishedAllDownloads = new Promise(resolve => {
    downloadView = {
      onDownloadAdded(aDownload) {
        info("download added");
        resolve(aDownload);
      },
    };
  });
  await downloadList.addView(downloadView);
  let download = await finishedAllDownloads;
  await downloadList.removeView(downloadView);

  // Clean up the download from the list.
  await downloadList.remove(download);
  await download.finalize(true);

  // Return the download
  return download;
}

add_task(async function test_pdf_object_attachment_download() {
  await SpecialPowers.pushPrefEnv({
    set: [["dom.navigation.object_embed.allow_retargeting", true]],
  });

  // Set the behaviour to save pdfs to disk and not handle internally, so we
  // don't end up with extra tabs after the test.
  var gMimeSvc = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService);
  var gHandlerSvc = Cc["@mozilla.org/uriloader/handler-service;1"].getService(
    Ci.nsIHandlerService
  );
  const mimeInfo = gMimeSvc.getFromTypeAndExtension("application/pdf", "pdf");
  let previousAction = mimeInfo.preferredAction;
  mimeInfo.preferredAction = Ci.nsIHandlerInfo.saveToDisk;
  gHandlerSvc.store(mimeInfo);
  registerCleanupFunction(() => {
    mimeInfo.preferredAction = previousAction;
    gHandlerSvc.store(mimeInfo);
  });

  // Start listening for the download before opening the new tab.
  let downloadPromise = waitForDownload();
  await BrowserTestUtils.withNewTab(
    `${httpsTestRoot}/file_pdf_object_attachment.html`,
    async browser => {
      let download = await downloadPromise;
      is(
        download.source.url,
        `${httpsTestRoot}/file_pdf_attachment.pdf`,
        "download should be the pdf"
      );

      await SpecialPowers.spawn(browser, [], async () => {
        let obj = content.document.querySelector("object");
        is(
          obj.displayedType,
          Ci.nsIObjectLoadingContent.TYPE_FALLBACK,
          "should be displaying TYPE_FALLBACK"
        );
      });
    }
  );
});

add_task(async function test_img_object_attachment_download() {
  // NOTE: This is testing our current behaviour here as of bug 1868001 (which
  // is to download an image with `Content-Disposition: attachment` embedded
  // within an object or embed element).
  //
  // Other browsers ignore the `Content-Disposition: attachment` header when
  // loading images within object or embed element as-of december 2023, as
  // we did prior to the changes in bug 1595491.
  //
  // If this turns out to be a web-compat issue, we may want to introduce
  // special handling to ignore content-disposition when loading images within
  // an object or embed element.
  await SpecialPowers.pushPrefEnv({
    set: [["dom.navigation.object_embed.allow_retargeting", true]],
  });

  // Start listening for the download before opening the new tab.
  let downloadPromise = waitForDownload();
  await BrowserTestUtils.withNewTab(
    `${httpsTestRoot}/file_img_object_attachment.html`,
    async browser => {
      let download = await downloadPromise;
      is(
        download.source.url,
        `${httpsTestRoot}/file_img_attachment.jpg`,
        "download should be the jpg"
      );

      await SpecialPowers.spawn(browser, [], async () => {
        let obj = content.document.querySelector("object");
        is(
          obj.displayedType,
          Ci.nsIObjectLoadingContent.TYPE_FALLBACK,
          "should be displaying TYPE_FALLBACK"
        );
      });
    }
  );
});