mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 850213 - Update nsHTMLInputElement to nsIContentPrefService2. r=smaug
This commit is contained in:
parent
d03f3261e7
commit
04b26e63a2
@ -260,6 +260,48 @@ HTMLInputElement::nsFilePickerShownCallback::nsFilePickerShownCallback(
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(UploadLastDir::ContentPrefCallback, nsIContentPrefCallback2)
|
||||
|
||||
NS_IMETHODIMP
|
||||
UploadLastDir::ContentPrefCallback::HandleCompletion(uint16_t aReason)
|
||||
{
|
||||
nsCOMPtr<nsIFile> localFile = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID);
|
||||
NS_ENSURE_STATE(localFile);
|
||||
|
||||
if (aReason == nsIContentPrefCallback2::COMPLETE_ERROR ||
|
||||
!mResult) {
|
||||
// Default to "desktop" directory for each platform
|
||||
nsCOMPtr<nsIFile> homeDir;
|
||||
NS_GetSpecialDirectory(NS_OS_DESKTOP_DIR, getter_AddRefs(homeDir));
|
||||
localFile = do_QueryInterface(homeDir);
|
||||
} else {
|
||||
nsAutoString prefStr;
|
||||
nsCOMPtr<nsIVariant> pref;
|
||||
mResult->GetValue(getter_AddRefs(pref));
|
||||
pref->GetAsAString(prefStr);
|
||||
localFile->InitWithPath(prefStr);
|
||||
}
|
||||
|
||||
mFilePicker->SetDisplayDirectory(localFile);
|
||||
mFilePicker->Open(mFpCallback);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
UploadLastDir::ContentPrefCallback::HandleResult(nsIContentPref* pref)
|
||||
{
|
||||
mResult = pref;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
UploadLastDir::ContentPrefCallback::HandleError(nsresult error)
|
||||
{
|
||||
// HandleCompletion is always called (even with HandleError was called),
|
||||
// so we don't need to do anything special here.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
HTMLInputElement::nsFilePickerShownCallback::Done(int16_t aResult)
|
||||
{
|
||||
@ -389,6 +431,9 @@ HTMLInputElement::AsyncClickHandler::Run()
|
||||
|
||||
const nsCOMArray<nsIDOMFile>& oldFiles = mInput->GetFilesInternal();
|
||||
|
||||
nsCOMPtr<nsIFilePickerShownCallback> callback =
|
||||
new HTMLInputElement::nsFilePickerShownCallback(mInput, filePicker, multi);
|
||||
|
||||
if (oldFiles.Count()) {
|
||||
nsString path;
|
||||
|
||||
@ -415,23 +460,13 @@ HTMLInputElement::AsyncClickHandler::Run()
|
||||
filePicker->SetDefaultString(leafName);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Attempt to retrieve the last used directory from the content pref service
|
||||
nsCOMPtr<nsIFile> localFile;
|
||||
HTMLInputElement::gUploadLastDir->FetchLastUsedDirectory(doc,
|
||||
getter_AddRefs(localFile));
|
||||
if (!localFile) {
|
||||
// Default to "desktop" directory for each platform
|
||||
nsCOMPtr<nsIFile> homeDir;
|
||||
NS_GetSpecialDirectory(NS_OS_DESKTOP_DIR, getter_AddRefs(homeDir));
|
||||
localFile = do_QueryInterface(homeDir);
|
||||
}
|
||||
filePicker->SetDisplayDirectory(localFile);
|
||||
|
||||
return filePicker->Open(callback);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIFilePickerShownCallback> callback =
|
||||
new HTMLInputElement::nsFilePickerShownCallback(mInput, filePicker, multi);
|
||||
return filePicker->Open(callback);
|
||||
HTMLInputElement::gUploadLastDir->FetchDirectoryAndDisplayPicker(doc, filePicker, callback);
|
||||
return NS_OK;
|
||||
|
||||
}
|
||||
|
||||
#define CPS_PREF_NAME NS_LITERAL_STRING("browser.upload.lastDir")
|
||||
@ -456,10 +491,13 @@ HTMLInputElement::DestroyUploadLastDir() {
|
||||
}
|
||||
|
||||
nsresult
|
||||
UploadLastDir::FetchLastUsedDirectory(nsIDocument* aDoc, nsIFile** aFile)
|
||||
UploadLastDir::FetchDirectoryAndDisplayPicker(nsIDocument* aDoc,
|
||||
nsIFilePicker* aFilePicker,
|
||||
nsIFilePickerShownCallback* aFpCallback)
|
||||
{
|
||||
NS_PRECONDITION(aDoc, "aDoc is null");
|
||||
NS_PRECONDITION(aFile, "aFile is null");
|
||||
NS_PRECONDITION(aFilePicker, "aFilePicker is null");
|
||||
NS_PRECONDITION(aFpCallback, "aFpCallback is null");
|
||||
|
||||
nsIURI* docURI = aDoc->GetDocumentURI();
|
||||
NS_PRECONDITION(docURI, "docURI is null");
|
||||
@ -467,30 +505,22 @@ UploadLastDir::FetchLastUsedDirectory(nsIDocument* aDoc, nsIFile** aFile)
|
||||
nsCOMPtr<nsISupports> container = aDoc->GetContainer();
|
||||
nsCOMPtr<nsILoadContext> loadContext = do_QueryInterface(container);
|
||||
|
||||
// Attempt to get the CPS, if it's not present we'll just return
|
||||
nsCOMPtr<nsIContentPrefService> contentPrefService =
|
||||
nsCOMPtr<nsIContentPrefCallback2> prefCallback =
|
||||
new UploadLastDir::ContentPrefCallback(aFilePicker, aFpCallback);
|
||||
|
||||
// Attempt to get the CPS, if it's not present we'll fallback to use the Desktop folder
|
||||
nsCOMPtr<nsIContentPrefService2> contentPrefService =
|
||||
do_GetService(NS_CONTENT_PREF_SERVICE_CONTRACTID);
|
||||
if (!contentPrefService)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
nsCOMPtr<nsIWritableVariant> uri = do_CreateInstance(NS_VARIANT_CONTRACTID);
|
||||
if (!uri)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
uri->SetAsISupports(docURI);
|
||||
|
||||
// Get the last used directory, if it is stored
|
||||
bool hasPref;
|
||||
if (NS_SUCCEEDED(contentPrefService->HasPref(uri, CPS_PREF_NAME, loadContext, &hasPref)) && hasPref) {
|
||||
nsCOMPtr<nsIVariant> pref;
|
||||
contentPrefService->GetPref(uri, CPS_PREF_NAME, loadContext, nullptr, getter_AddRefs(pref));
|
||||
nsString prefStr;
|
||||
pref->GetAsAString(prefStr);
|
||||
|
||||
nsCOMPtr<nsIFile> localFile = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID);
|
||||
if (!localFile)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
localFile->InitWithPath(prefStr);
|
||||
localFile.forget(aFile);
|
||||
if (!contentPrefService) {
|
||||
prefCallback->HandleCompletion(nsIContentPrefCallback2::COMPLETE_ERROR);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsAutoCString cstrSpec;
|
||||
docURI->GetSpec(cstrSpec);
|
||||
NS_ConvertUTF8toUTF16 spec(cstrSpec);
|
||||
|
||||
contentPrefService->GetByDomainAndName(spec, CPS_PREF_NAME, loadContext, prefCallback);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -521,14 +551,14 @@ UploadLastDir::StoreLastUsedDirectory(nsIDocument* aDoc, nsIDOMFile* aDomFile)
|
||||
}
|
||||
|
||||
// Attempt to get the CPS, if it's not present we'll just return
|
||||
nsCOMPtr<nsIContentPrefService> contentPrefService =
|
||||
nsCOMPtr<nsIContentPrefService2> contentPrefService =
|
||||
do_GetService(NS_CONTENT_PREF_SERVICE_CONTRACTID);
|
||||
if (!contentPrefService)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
nsCOMPtr<nsIWritableVariant> uri = do_CreateInstance(NS_VARIANT_CONTRACTID);
|
||||
if (!uri)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
uri->SetAsISupports(docURI);
|
||||
|
||||
nsAutoCString cstrSpec;
|
||||
docURI->GetSpec(cstrSpec);
|
||||
NS_ConvertUTF8toUTF16 spec(cstrSpec);
|
||||
|
||||
// Find the parent of aFile, and store it
|
||||
nsString unicodePath;
|
||||
@ -542,17 +572,17 @@ UploadLastDir::StoreLastUsedDirectory(nsIDocument* aDoc, nsIDOMFile* aDomFile)
|
||||
|
||||
nsCOMPtr<nsISupports> container = aDoc->GetContainer();
|
||||
nsCOMPtr<nsILoadContext> loadContext = do_QueryInterface(container);
|
||||
return contentPrefService->SetPref(uri, CPS_PREF_NAME, prefValue, loadContext);
|
||||
return contentPrefService->Set(spec, CPS_PREF_NAME, prefValue, loadContext, nullptr);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
UploadLastDir::Observe(nsISupports* aSubject, char const* aTopic, PRUnichar const* aData)
|
||||
{
|
||||
if (strcmp(aTopic, "browser:purge-session-history") == 0) {
|
||||
nsCOMPtr<nsIContentPrefService> contentPrefService =
|
||||
nsCOMPtr<nsIContentPrefService2> contentPrefService =
|
||||
do_GetService(NS_CONTENT_PREF_SERVICE_CONTRACTID);
|
||||
if (contentPrefService)
|
||||
contentPrefService->RemovePrefsByName(CPS_PREF_NAME, nullptr);
|
||||
contentPrefService->RemoveByName(CPS_PREF_NAME, nullptr, nullptr);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "nsHTMLFormElement.h" // for ShouldShowInvalidUI()
|
||||
#include "nsIFile.h"
|
||||
#include "nsIFilePicker.h"
|
||||
#include "nsIContentPrefService2.h"
|
||||
|
||||
class nsDOMFileList;
|
||||
class nsIFilePicker;
|
||||
@ -36,12 +37,15 @@ public:
|
||||
|
||||
/**
|
||||
* Fetch the last used directory for this location from the content
|
||||
* pref service, if it is available.
|
||||
* pref service, and display the file picker opened in that directory.
|
||||
*
|
||||
* @param aDoc current document
|
||||
* @param aFile path to the last used directory
|
||||
* @param aDoc current document
|
||||
* @param aFilePicker the file picker to open
|
||||
* @param aFpCallback the callback object to be run when the file is shown.
|
||||
*/
|
||||
nsresult FetchLastUsedDirectory(nsIDocument* aDoc, nsIFile** aFile);
|
||||
nsresult FetchDirectoryAndDisplayPicker(nsIDocument* aDoc,
|
||||
nsIFilePicker* aFilePicker,
|
||||
nsIFilePickerShownCallback* aFpCallback);
|
||||
|
||||
/**
|
||||
* Store the last used directory for this location using the
|
||||
@ -51,6 +55,25 @@ public:
|
||||
* file will be stored
|
||||
*/
|
||||
nsresult StoreLastUsedDirectory(nsIDocument* aDoc, nsIDOMFile* aDomFile);
|
||||
|
||||
class ContentPrefCallback MOZ_FINAL : public nsIContentPrefCallback2
|
||||
{
|
||||
public:
|
||||
ContentPrefCallback(nsIFilePicker* aFilePicker, nsIFilePickerShownCallback* aFpCallback)
|
||||
: mFilePicker(aFilePicker)
|
||||
, mFpCallback(aFpCallback)
|
||||
{ }
|
||||
|
||||
virtual ~ContentPrefCallback()
|
||||
{ }
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSICONTENTPREFCALLBACK2
|
||||
|
||||
nsCOMPtr<nsIFilePicker> mFilePicker;
|
||||
nsCOMPtr<nsIFilePickerShownCallback> mFpCallback;
|
||||
nsCOMPtr<nsIContentPref> mResult;
|
||||
};
|
||||
};
|
||||
|
||||
class HTMLInputElement : public nsGenericHTMLFormElement,
|
||||
|
@ -19,10 +19,37 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=36619
|
||||
<button id='c' onmousedown="document.getElementById('a').click();">Show Filepicker</button>
|
||||
<button id='d' onmouseup="document.getElementById('a').click();">Show Filepicker</button>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
<script type="application/javascript;version=1.8">
|
||||
|
||||
/** Test for Bug 36619 **/
|
||||
|
||||
let gGen = doTest();
|
||||
function continueTest() {
|
||||
gGen.next();
|
||||
}
|
||||
|
||||
function waitForCondition(condition, errorMsg) {
|
||||
var tries = 0;
|
||||
var interval = setInterval(function() {
|
||||
if (tries >= 10) {
|
||||
ok(false, errorMsg);
|
||||
moveOn();
|
||||
}
|
||||
if (condition()) {
|
||||
moveOn();
|
||||
}
|
||||
tries++;
|
||||
}, 100);
|
||||
var moveOn = function() {
|
||||
clearInterval(interval);
|
||||
try {
|
||||
continueTest();
|
||||
} catch (e if e instanceof StopIteration) {
|
||||
SimpleTest.finish();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var MockFilePicker = SpecialPowers.MockFilePicker;
|
||||
@ -34,43 +61,45 @@ SpecialPowers.pushPrefEnv({'set': [
|
||||
["privacy.popups.showBrowserMessage", false]
|
||||
]}, function() {
|
||||
SimpleTest.waitForFocus(function() {
|
||||
|
||||
// Tests that a click on 'b' calls the show method.
|
||||
var b = document.getElementById('b');
|
||||
b.focus(); // Be sure the element is visible.
|
||||
synthesizeMouseAtCenter(b, {});
|
||||
SimpleTest.executeSoon(function() {
|
||||
ok(MockFilePicker.showing,
|
||||
"File picker showAsync method should have been called");
|
||||
MockFilePicker.reset();
|
||||
|
||||
// Tests that a click on 'a' doesn't call the show method, because it is hidden.
|
||||
document.getElementById("a").click();
|
||||
SimpleTest.executeSoon(function() {
|
||||
ok(!MockFilePicker.showing,
|
||||
"File picker showAsync method should not have been called");
|
||||
MockFilePicker.reset();
|
||||
|
||||
synthesizeMouseAtCenter(document.getElementById('c'), {});
|
||||
SimpleTest.executeSoon(function() {
|
||||
ok(!MockFilePicker.showing,
|
||||
"File picker showAsync method should have been called");
|
||||
MockFilePicker.reset();
|
||||
|
||||
synthesizeMouseAtCenter(document.getElementById('d'), {});
|
||||
SimpleTest.executeSoon(function() {
|
||||
ok(MockFilePicker.showing,
|
||||
"File picker showAsync method should have been called");
|
||||
|
||||
MockFilePicker.cleanup();
|
||||
SimpleTest.finish();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
continueTest();
|
||||
});
|
||||
});
|
||||
|
||||
let showing = function() MockFilePicker.showing;
|
||||
let notShowing = function() !MockFilePicker.showing;
|
||||
|
||||
function doTest() {
|
||||
ok(true, "Test start");
|
||||
var b = document.getElementById('b');
|
||||
b.focus(); // Be sure the element is visible.
|
||||
|
||||
synthesizeMouseAtCenter(b, {});
|
||||
yield waitForCondition(showing,
|
||||
"File picker showAsync method should have been called");
|
||||
|
||||
MockFilePicker.reset();
|
||||
|
||||
// Tests that a click on 'a' doesn't call the show method, because it is hidden.
|
||||
document.getElementById("a").click();
|
||||
yield waitForCondition(notShowing,
|
||||
"File picker showAsync method should not have been called");
|
||||
|
||||
MockFilePicker.reset();
|
||||
|
||||
synthesizeMouseAtCenter(document.getElementById('c'), {});
|
||||
yield waitForCondition(notShowing,
|
||||
"File picker showAsync method should not have been called");
|
||||
|
||||
MockFilePicker.reset();
|
||||
synthesizeMouseAtCenter(document.getElementById('d'), {});
|
||||
|
||||
yield waitForCondition(showing,
|
||||
"File picker showAsync method should have been called");
|
||||
|
||||
ok(true, "Test completed");
|
||||
MockFilePicker.cleanup();
|
||||
}
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
|
Loading…
Reference in New Issue
Block a user