Bug 781973 - Use filepicker's open() instead of the obsolete show() in /browser. r=bbondy
This commit is contained in:
@@ -2076,21 +2076,28 @@ function BrowserOpenFileWindow()
|
|||||||
{
|
{
|
||||||
// Get filepicker component.
|
// Get filepicker component.
|
||||||
try {
|
try {
|
||||||
const nsIFilePicker = Components.interfaces.nsIFilePicker;
|
const nsIFilePicker = Ci.nsIFilePicker;
|
||||||
var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
|
let fp = Cc["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
|
||||||
fp.init(window, gNavigatorBundle.getString("openFile"), nsIFilePicker.modeOpen);
|
let fpCallback = function fpCallback_done(aResult) {
|
||||||
fp.appendFilters(nsIFilePicker.filterAll | nsIFilePicker.filterText | nsIFilePicker.filterImages |
|
if (aResult == nsIFilePicker.returnOK) {
|
||||||
nsIFilePicker.filterXML | nsIFilePicker.filterHTML);
|
try {
|
||||||
fp.displayDirectory = gLastOpenDirectory.path;
|
if (fp.file) {
|
||||||
|
gLastOpenDirectory.path =
|
||||||
if (fp.show() == nsIFilePicker.returnOK) {
|
fp.file.parent.QueryInterface(Ci.nsILocalFile);
|
||||||
try {
|
}
|
||||||
if (fp.file)
|
} catch (ex) {
|
||||||
gLastOpenDirectory.path = fp.file.parent.QueryInterface(Ci.nsILocalFile);
|
}
|
||||||
} catch(e) {
|
openUILinkIn(fp.fileURL.spec, "current");
|
||||||
}
|
}
|
||||||
openUILinkIn(fp.fileURL.spec, "current");
|
};
|
||||||
}
|
|
||||||
|
fp.init(window, gNavigatorBundle.getString("openFile"),
|
||||||
|
nsIFilePicker.modeOpen);
|
||||||
|
fp.appendFilters(nsIFilePicker.filterAll | nsIFilePicker.filterText |
|
||||||
|
nsIFilePicker.filterImages | nsIFilePicker.filterXML |
|
||||||
|
nsIFilePicker.filterHTML);
|
||||||
|
fp.displayDirectory = gLastOpenDirectory.path;
|
||||||
|
fp.open(fpCallback);
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -112,15 +112,22 @@ const nsIFilePicker = Components.interfaces.nsIFilePicker;
|
|||||||
function onChooseFile()
|
function onChooseFile()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
|
let fp = Components.classes["@mozilla.org/filepicker;1"].
|
||||||
fp.init(window, dialog.bundle.getString("chooseFileDialogTitle"), nsIFilePicker.modeOpen);
|
createInstance(nsIFilePicker);
|
||||||
fp.appendFilters(nsIFilePicker.filterHTML | nsIFilePicker.filterText |
|
let fpCallback = function fpCallback_done(aResult) {
|
||||||
nsIFilePicker.filterAll | nsIFilePicker.filterImages | nsIFilePicker.filterXML);
|
if (aResult == nsIFilePicker.returnOK && fp.fileURL.spec &&
|
||||||
|
fp.fileURL.spec.length > 0) {
|
||||||
|
dialog.input.value = fp.fileURL.spec;
|
||||||
|
}
|
||||||
|
doEnabling();
|
||||||
|
};
|
||||||
|
|
||||||
if (fp.show() == nsIFilePicker.returnOK && fp.fileURL.spec && fp.fileURL.spec.length > 0)
|
fp.init(window, dialog.bundle.getString("chooseFileDialogTitle"),
|
||||||
dialog.input.value = fp.fileURL.spec;
|
nsIFilePicker.modeOpen);
|
||||||
|
fp.appendFilters(nsIFilePicker.filterAll | nsIFilePicker.filterText |
|
||||||
|
nsIFilePicker.filterImages | nsIFilePicker.filterXML |
|
||||||
|
nsIFilePicker.filterHTML);
|
||||||
|
fp.open(fpCallback);
|
||||||
|
} catch (ex) {
|
||||||
}
|
}
|
||||||
catch(ex) {
|
|
||||||
}
|
|
||||||
doEnabling();
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -761,31 +761,33 @@ function getSelectedRow(tree)
|
|||||||
return (rows.length == 1) ? rows[0] : -1;
|
return (rows.length == 1) ? rows[0] : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectSaveFolder()
|
function selectSaveFolder(aCallback)
|
||||||
{
|
{
|
||||||
const nsILocalFile = Components.interfaces.nsILocalFile;
|
const nsILocalFile = Components.interfaces.nsILocalFile;
|
||||||
const nsIFilePicker = Components.interfaces.nsIFilePicker;
|
const nsIFilePicker = Components.interfaces.nsIFilePicker;
|
||||||
var fp = Components.classes["@mozilla.org/filepicker;1"]
|
let titleText = gBundle.getString("mediaSelectFolder");
|
||||||
.createInstance(nsIFilePicker);
|
let fp = Components.classes["@mozilla.org/filepicker;1"].
|
||||||
|
createInstance(nsIFilePicker);
|
||||||
|
let fpCallback = function fpCallback_done(aResult) {
|
||||||
|
if (aResult == nsIFilePicker.returnOK) {
|
||||||
|
aCallback(fp.file.QueryInterface(nsILocalFile));
|
||||||
|
} else {
|
||||||
|
aCallback(null);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
var titleText = gBundle.getString("mediaSelectFolder");
|
|
||||||
fp.init(window, titleText, nsIFilePicker.modeGetFolder);
|
fp.init(window, titleText, nsIFilePicker.modeGetFolder);
|
||||||
try {
|
|
||||||
var prefs = Components.classes[PREFERENCES_CONTRACTID]
|
|
||||||
.getService(Components.interfaces.nsIPrefBranch);
|
|
||||||
|
|
||||||
var initialDir = prefs.getComplexValue("browser.download.dir", nsILocalFile);
|
|
||||||
if (initialDir)
|
|
||||||
fp.displayDirectory = initialDir;
|
|
||||||
}
|
|
||||||
catch (ex) { }
|
|
||||||
|
|
||||||
fp.appendFilters(nsIFilePicker.filterAll);
|
fp.appendFilters(nsIFilePicker.filterAll);
|
||||||
var ret = fp.show();
|
try {
|
||||||
|
let prefs = Components.classes[PREFERENCES_CONTRACTID].
|
||||||
if (ret == nsIFilePicker.returnOK)
|
getService(Components.interfaces.nsIPrefBranch);
|
||||||
return fp.file.QueryInterface(nsILocalFile);
|
let initialDir = prefs.getComplexValue("browser.download.dir", nsILocalFile);
|
||||||
return null;
|
if (initialDir) {
|
||||||
|
fp.displayDirectory = initialDir;
|
||||||
|
}
|
||||||
|
} catch (ex) {
|
||||||
|
}
|
||||||
|
fp.open(fpCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
function saveMedia()
|
function saveMedia()
|
||||||
@@ -807,37 +809,39 @@ function saveMedia()
|
|||||||
|
|
||||||
saveURL(url, null, titleKey, false, false, makeURI(item.baseURI));
|
saveURL(url, null, titleKey, false, false, makeURI(item.baseURI));
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
selectSaveFolder(function(aDirectory) {
|
||||||
var odir = selectSaveFolder();
|
if (aDirectory) {
|
||||||
|
var saveAnImage = function(aURIString, aChosenData, aBaseURI) {
|
||||||
var saveAnImage = function(aURIString, aChosenData, aBaseURI) {
|
internalSave(aURIString, null, null, null, null, false, "SaveImageTitle",
|
||||||
internalSave(aURIString, null, null, null, null, false, "SaveImageTitle",
|
aChosenData, aBaseURI);
|
||||||
aChosenData, aBaseURI);
|
};
|
||||||
}
|
|
||||||
|
for (var i = 0; i < rowArray.length; i++) {
|
||||||
for (var i = 0; i < rowArray.length; i++) {
|
var v = rowArray[i];
|
||||||
var v = rowArray[i];
|
var dir = aDirectory.clone();
|
||||||
var dir = odir.clone();
|
var item = gImageView.data[v][COL_IMAGE_NODE];
|
||||||
var item = gImageView.data[v][COL_IMAGE_NODE];
|
var uriString = gImageView.data[v][COL_IMAGE_ADDRESS];
|
||||||
var uriString = gImageView.data[v][COL_IMAGE_ADDRESS];
|
var uri = makeURI(uriString);
|
||||||
var uri = makeURI(uriString);
|
|
||||||
|
try {
|
||||||
try {
|
uri.QueryInterface(Components.interfaces.nsIURL);
|
||||||
uri.QueryInterface(Components.interfaces.nsIURL);
|
dir.append(decodeURIComponent(uri.fileName));
|
||||||
dir.append(decodeURIComponent(uri.fileName));
|
} catch(ex) {
|
||||||
|
/* data: uris */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == 0) {
|
||||||
|
saveAnImage(uriString, new AutoChosen(dir, uri), makeURI(item.baseURI));
|
||||||
|
} else {
|
||||||
|
// This delay is a hack which prevents the download manager
|
||||||
|
// from opening many times. See bug 377339.
|
||||||
|
setTimeout(saveAnImage, 200, uriString, new AutoChosen(dir, uri),
|
||||||
|
makeURI(item.baseURI));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch(ex) { /* data: uris */ }
|
});
|
||||||
|
|
||||||
if (i == 0)
|
|
||||||
saveAnImage(uriString, new AutoChosen(dir, uri), makeURI(item.baseURI));
|
|
||||||
else {
|
|
||||||
// This delay is a hack which prevents the download manager
|
|
||||||
// from opening many times. See bug 377339.
|
|
||||||
setTimeout(saveAnImage, 200, uriString, new AutoChosen(dir, uri),
|
|
||||||
makeURI(item.baseURI));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -151,26 +151,28 @@ let gSyncUtils = {
|
|||||||
let dialogTitle = this.bundle.GetStringFromName("save.recoverykey.title");
|
let dialogTitle = this.bundle.GetStringFromName("save.recoverykey.title");
|
||||||
let defaultSaveName = this.bundle.GetStringFromName("save.recoverykey.defaultfilename");
|
let defaultSaveName = this.bundle.GetStringFromName("save.recoverykey.defaultfilename");
|
||||||
this._preparePPiframe(elid, function(iframe) {
|
this._preparePPiframe(elid, function(iframe) {
|
||||||
let filepicker = Cc["@mozilla.org/filepicker;1"]
|
let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
|
||||||
.createInstance(Ci.nsIFilePicker);
|
let fpCallback = function fpCallback_done(aResult) {
|
||||||
filepicker.init(window, dialogTitle, Ci.nsIFilePicker.modeSave);
|
if (aResult == Ci.nsIFilePicker.returnOK ||
|
||||||
filepicker.appendFilters(Ci.nsIFilePicker.filterHTML);
|
aResult == Ci.nsIFilePicker.returnReplace) {
|
||||||
filepicker.defaultString = defaultSaveName;
|
let stream = Cc["@mozilla.org/network/file-output-stream;1"].
|
||||||
let rv = filepicker.show();
|
createInstance(Ci.nsIFileOutputStream);
|
||||||
if (rv == Ci.nsIFilePicker.returnOK
|
stream.init(fp.file, -1, 0600, 0);
|
||||||
|| rv == Ci.nsIFilePicker.returnReplace) {
|
|
||||||
let stream = Cc["@mozilla.org/network/file-output-stream;1"]
|
|
||||||
.createInstance(Ci.nsIFileOutputStream);
|
|
||||||
stream.init(filepicker.file, -1, 0600, 0);
|
|
||||||
|
|
||||||
let serializer = new XMLSerializer();
|
let serializer = new XMLSerializer();
|
||||||
let output = serializer.serializeToString(iframe.contentDocument);
|
let output = serializer.serializeToString(iframe.contentDocument);
|
||||||
output = output.replace(/<!DOCTYPE (.|\n)*?]>/,
|
output = output.replace(/<!DOCTYPE (.|\n)*?]>/,
|
||||||
'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" ' +
|
'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" ' +
|
||||||
'"DTD/xhtml1-strict.dtd">');
|
'"DTD/xhtml1-strict.dtd">');
|
||||||
output = Weave.Utils.encodeUTF8(output);
|
output = Weave.Utils.encodeUTF8(output);
|
||||||
stream.write(output, output.length);
|
stream.write(output, output.length);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fp.init(window, dialogTitle, Ci.nsIFilePicker.modeSave);
|
||||||
|
fp.appendFilters(Ci.nsIFilePicker.filterHTML);
|
||||||
|
fp.defaultString = defaultSaveName;
|
||||||
|
fp.open(fpCallback);
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -708,46 +708,53 @@ FeedWriter.prototype = {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Displays a prompt from which the user may choose a (client) feed reader.
|
* Displays a prompt from which the user may choose a (client) feed reader.
|
||||||
* @return - true if a feed reader was selected, false otherwise.
|
* @param aCallback the callback method, passes in true if a feed reader was
|
||||||
|
* selected, false otherwise.
|
||||||
*/
|
*/
|
||||||
_chooseClientApp: function FW__chooseClientApp() {
|
_chooseClientApp: function FW__chooseClientApp(aCallback) {
|
||||||
try {
|
try {
|
||||||
var fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
|
let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
|
||||||
fp.init(this._window,
|
let fpCallback = function fpCallback_done(aResult) {
|
||||||
this._getString("chooseApplicationDialogTitle"),
|
if (aResult == Ci.nsIFilePicker.returnOK) {
|
||||||
Ci.nsIFilePicker.modeOpen);
|
this._selectedApp = fp.file;
|
||||||
fp.appendFilters(Ci.nsIFilePicker.filterApps);
|
if (this._selectedApp) {
|
||||||
|
// XXXben - we need to compare this with the running instance
|
||||||
if (fp.show() == Ci.nsIFilePicker.returnOK) {
|
// executable just don't know how to do that via script
|
||||||
this._selectedApp = fp.file;
|
// XXXmano TBD: can probably add this to nsIShellService
|
||||||
if (this._selectedApp) {
|
|
||||||
// XXXben - we need to compare this with the running instance executable
|
|
||||||
// just don't know how to do that via script...
|
|
||||||
// XXXmano TBD: can probably add this to nsIShellService
|
|
||||||
#ifdef XP_WIN
|
#ifdef XP_WIN
|
||||||
#expand if (fp.file.leafName != "__MOZ_APP_NAME__.exe") {
|
#expand if (fp.file.leafName != "__MOZ_APP_NAME__.exe") {
|
||||||
#else
|
#else
|
||||||
#ifdef XP_MACOSX
|
#ifdef XP_MACOSX
|
||||||
#expand if (fp.file.leafName != "__MOZ_MACBUNDLE_NAME__") {
|
#expand if (fp.file.leafName != "__MOZ_MACBUNDLE_NAME__") {
|
||||||
#else
|
#else
|
||||||
#expand if (fp.file.leafName != "__MOZ_APP_NAME__-bin") {
|
#expand if (fp.file.leafName != "__MOZ_APP_NAME__-bin") {
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
this._initMenuItemWithFile(this._contentSandbox.selectedAppMenuItem,
|
this._initMenuItemWithFile(this._contentSandbox.selectedAppMenuItem,
|
||||||
this._selectedApp);
|
this._selectedApp);
|
||||||
|
|
||||||
// Show and select the selected application menuitem
|
// Show and select the selected application menuitem
|
||||||
var codeStr = "selectedAppMenuItem.hidden = false;" +
|
let codeStr = "selectedAppMenuItem.hidden = false;" +
|
||||||
"selectedAppMenuItem.doCommand();"
|
"selectedAppMenuItem.doCommand();"
|
||||||
Cu.evalInSandbox(codeStr, this._contentSandbox);
|
Cu.evalInSandbox(codeStr, this._contentSandbox);
|
||||||
return true;
|
if (aCallback) {
|
||||||
|
aCallback(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
if (aCallback) {
|
||||||
}
|
aCallback(false);
|
||||||
catch(ex) { }
|
}
|
||||||
|
}.bind(this);
|
||||||
|
|
||||||
return false;
|
fp.init(this._window, this._getString("chooseApplicationDialogTitle"),
|
||||||
|
Ci.nsIFilePicker.modeOpen);
|
||||||
|
fp.appendFilters(Ci.nsIFilePicker.filterApps);
|
||||||
|
fp.open(fpCallback);
|
||||||
|
} catch(ex) {
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_setAlwaysUseCheckedState: function FW__setAlwaysUseCheckedState(feedType) {
|
_setAlwaysUseCheckedState: function FW__setAlwaysUseCheckedState(feedType) {
|
||||||
@@ -833,10 +840,14 @@ FeedWriter.prototype = {
|
|||||||
*/
|
*/
|
||||||
var popupbox = this._handlersMenuList.firstChild.boxObject;
|
var popupbox = this._handlersMenuList.firstChild.boxObject;
|
||||||
popupbox.QueryInterface(Components.interfaces.nsIPopupBoxObject);
|
popupbox.QueryInterface(Components.interfaces.nsIPopupBoxObject);
|
||||||
if (popupbox.popupState == "hiding" && !this._chooseClientApp()) {
|
if (popupbox.popupState == "hiding") {
|
||||||
// Select the (per-prefs) selected handler if no application was
|
this._chooseClientApp(function(aResult) {
|
||||||
// selected
|
if (!aResult) {
|
||||||
this._setSelectedHandler(this._getFeedType());
|
// Select the (per-prefs) selected handler if no application
|
||||||
|
// was selected
|
||||||
|
this._setSelectedHandler(this._getFeedType());
|
||||||
|
}
|
||||||
|
}.bind(this));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -1210,70 +1221,77 @@ FeedWriter.prototype = {
|
|||||||
var useAsDefault = this._getUIElement("alwaysUse").getAttribute("checked");
|
var useAsDefault = this._getUIElement("alwaysUse").getAttribute("checked");
|
||||||
|
|
||||||
var selectedItem = this._getSelectedItemFromMenulist(this._handlersMenuList);
|
var selectedItem = this._getSelectedItemFromMenulist(this._handlersMenuList);
|
||||||
|
let subscribeCallback = function() {
|
||||||
|
if (selectedItem.hasAttribute("webhandlerurl")) {
|
||||||
|
var webURI = selectedItem.getAttribute("webhandlerurl");
|
||||||
|
prefs.setCharPref(getPrefReaderForType(feedType), "web");
|
||||||
|
|
||||||
|
var supportsString = Cc["@mozilla.org/supports-string;1"].
|
||||||
|
createInstance(Ci.nsISupportsString);
|
||||||
|
supportsString.data = webURI;
|
||||||
|
prefs.setComplexValue(getPrefWebForType(feedType), Ci.nsISupportsString,
|
||||||
|
supportsString);
|
||||||
|
|
||||||
|
var wccr = Cc["@mozilla.org/embeddor.implemented/web-content-handler-registrar;1"].
|
||||||
|
getService(Ci.nsIWebContentConverterService);
|
||||||
|
var handler = wccr.getWebContentHandlerByURI(this._getMimeTypeForFeedType(feedType), webURI);
|
||||||
|
if (handler) {
|
||||||
|
if (useAsDefault) {
|
||||||
|
wccr.setAutoHandler(this._getMimeTypeForFeedType(feedType), handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._window.location.href = handler.getHandlerURI(this._window.location.href);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch (selectedItem.getAttribute("anonid")) {
|
||||||
|
case "selectedAppMenuItem":
|
||||||
|
prefs.setComplexValue(getPrefAppForType(feedType), Ci.nsILocalFile,
|
||||||
|
this._selectedApp);
|
||||||
|
prefs.setCharPref(getPrefReaderForType(feedType), "client");
|
||||||
|
break;
|
||||||
|
case "defaultHandlerMenuItem":
|
||||||
|
prefs.setComplexValue(getPrefAppForType(feedType), Ci.nsILocalFile,
|
||||||
|
this._defaultSystemReader);
|
||||||
|
prefs.setCharPref(getPrefReaderForType(feedType), "client");
|
||||||
|
break;
|
||||||
|
case "liveBookmarksMenuItem":
|
||||||
|
defaultHandler = "bookmarks";
|
||||||
|
prefs.setCharPref(getPrefReaderForType(feedType), "bookmarks");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
var feedService = Cc["@mozilla.org/browser/feeds/result-service;1"].
|
||||||
|
getService(Ci.nsIFeedResultService);
|
||||||
|
|
||||||
|
// Pull the title and subtitle out of the document
|
||||||
|
var feedTitle = this._document.getElementById(TITLE_ID).textContent;
|
||||||
|
var feedSubtitle = this._document.getElementById(SUBTITLE_ID).textContent;
|
||||||
|
feedService.addToClientReader(this._window.location.href, feedTitle, feedSubtitle, feedType);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If "Always use..." is checked, we should set PREF_*SELECTED_ACTION
|
||||||
|
// to either "reader" (If a web reader or if an application is selected),
|
||||||
|
// or to "bookmarks" (if the live bookmarks option is selected).
|
||||||
|
// Otherwise, we should set it to "ask"
|
||||||
|
if (useAsDefault) {
|
||||||
|
prefs.setCharPref(getPrefActionForType(feedType), defaultHandler);
|
||||||
|
} else {
|
||||||
|
prefs.setCharPref(getPrefActionForType(feedType), "ask");
|
||||||
|
}
|
||||||
|
}.bind(this);
|
||||||
|
|
||||||
// Show the file picker before subscribing if the
|
// Show the file picker before subscribing if the
|
||||||
// choose application menuitem was chosen using the keyboard
|
// choose application menuitem was chosen using the keyboard
|
||||||
if (selectedItem.getAttribute("anonid") == "chooseApplicationMenuItem") {
|
if (selectedItem.getAttribute("anonid") == "chooseApplicationMenuItem") {
|
||||||
if (!this._chooseClientApp())
|
this._chooseClientApp(function(aResult) {
|
||||||
return;
|
if (aResult) {
|
||||||
|
selectedItem =
|
||||||
selectedItem = this._getSelectedItemFromMenulist(this._handlersMenuList);
|
this._getSelectedItemFromMenulist(this._handlersMenuList);
|
||||||
|
subscribeCallback();
|
||||||
|
}
|
||||||
|
}.bind(this));
|
||||||
|
} else {
|
||||||
|
subscribeCallback();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selectedItem.hasAttribute("webhandlerurl")) {
|
|
||||||
var webURI = selectedItem.getAttribute("webhandlerurl");
|
|
||||||
prefs.setCharPref(getPrefReaderForType(feedType), "web");
|
|
||||||
|
|
||||||
var supportsString = Cc["@mozilla.org/supports-string;1"].
|
|
||||||
createInstance(Ci.nsISupportsString);
|
|
||||||
supportsString.data = webURI;
|
|
||||||
prefs.setComplexValue(getPrefWebForType(feedType), Ci.nsISupportsString,
|
|
||||||
supportsString);
|
|
||||||
|
|
||||||
var wccr = Cc["@mozilla.org/embeddor.implemented/web-content-handler-registrar;1"].
|
|
||||||
getService(Ci.nsIWebContentConverterService);
|
|
||||||
var handler = wccr.getWebContentHandlerByURI(this._getMimeTypeForFeedType(feedType), webURI);
|
|
||||||
if (handler) {
|
|
||||||
if (useAsDefault)
|
|
||||||
wccr.setAutoHandler(this._getMimeTypeForFeedType(feedType), handler);
|
|
||||||
|
|
||||||
this._window.location.href = handler.getHandlerURI(this._window.location.href);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
switch (selectedItem.getAttribute("anonid")) {
|
|
||||||
case "selectedAppMenuItem":
|
|
||||||
prefs.setComplexValue(getPrefAppForType(feedType), Ci.nsILocalFile,
|
|
||||||
this._selectedApp);
|
|
||||||
prefs.setCharPref(getPrefReaderForType(feedType), "client");
|
|
||||||
break;
|
|
||||||
case "defaultHandlerMenuItem":
|
|
||||||
prefs.setComplexValue(getPrefAppForType(feedType), Ci.nsILocalFile,
|
|
||||||
this._defaultSystemReader);
|
|
||||||
prefs.setCharPref(getPrefReaderForType(feedType), "client");
|
|
||||||
break;
|
|
||||||
case "liveBookmarksMenuItem":
|
|
||||||
defaultHandler = "bookmarks";
|
|
||||||
prefs.setCharPref(getPrefReaderForType(feedType), "bookmarks");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
var feedService = Cc["@mozilla.org/browser/feeds/result-service;1"].
|
|
||||||
getService(Ci.nsIFeedResultService);
|
|
||||||
|
|
||||||
// Pull the title and subtitle out of the document
|
|
||||||
var feedTitle = this._document.getElementById(TITLE_ID).textContent;
|
|
||||||
var feedSubtitle = this._document.getElementById(SUBTITLE_ID).textContent;
|
|
||||||
feedService.addToClientReader(this._window.location.href, feedTitle, feedSubtitle, feedType);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If "Always use..." is checked, we should set PREF_*SELECTED_ACTION
|
|
||||||
// to either "reader" (If a web reader or if an application is selected),
|
|
||||||
// or to "bookmarks" (if the live bookmarks option is selected).
|
|
||||||
// Otherwise, we should set it to "ask"
|
|
||||||
if (useAsDefault)
|
|
||||||
prefs.setCharPref(getPrefActionForType(feedType), defaultHandler);
|
|
||||||
else
|
|
||||||
prefs.setCharPref(getPrefActionForType(feedType), "ask");
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// nsIObserver
|
// nsIObserver
|
||||||
|
|||||||
@@ -354,34 +354,39 @@ var PlacesOrganizer = {
|
|||||||
* Open a file-picker and import the selected file into the bookmarks store
|
* Open a file-picker and import the selected file into the bookmarks store
|
||||||
*/
|
*/
|
||||||
importFromFile: function PO_importFromFile() {
|
importFromFile: function PO_importFromFile() {
|
||||||
var fp = Cc["@mozilla.org/filepicker;1"].
|
let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
|
||||||
createInstance(Ci.nsIFilePicker);
|
let fpCallback = function fpCallback_done(aResult) {
|
||||||
fp.init(window, PlacesUIUtils.getString("SelectImport"),
|
if (aResult != Ci.nsIFilePicker.returnCancel && fp.fileURL) {
|
||||||
Ci.nsIFilePicker.modeOpen);
|
|
||||||
fp.appendFilters(Ci.nsIFilePicker.filterHTML);
|
|
||||||
if (fp.show() != Ci.nsIFilePicker.returnCancel) {
|
|
||||||
if (fp.fileURL) {
|
|
||||||
Components.utils.import("resource://gre/modules/BookmarkHTMLUtils.jsm");
|
Components.utils.import("resource://gre/modules/BookmarkHTMLUtils.jsm");
|
||||||
BookmarkHTMLUtils.importFromURL(fp.fileURL.spec, false);
|
BookmarkHTMLUtils.importFromURL(fp.fileURL.spec, false);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
|
fp.init(window, PlacesUIUtils.getString("SelectImport"),
|
||||||
|
Ci.nsIFilePicker.modeOpen);
|
||||||
|
fp.appendFilters(Ci.nsIFilePicker.filterHTML);
|
||||||
|
fp.open(fpCallback);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allows simple exporting of bookmarks.
|
* Allows simple exporting of bookmarks.
|
||||||
*/
|
*/
|
||||||
exportBookmarks: function PO_exportBookmarks() {
|
exportBookmarks: function PO_exportBookmarks() {
|
||||||
var fp = Cc["@mozilla.org/filepicker;1"].
|
let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
|
||||||
createInstance(Ci.nsIFilePicker);
|
let fpCallback = function fpCallback_done(aResult) {
|
||||||
|
if (aResult != Ci.nsIFilePicker.returnCancel) {
|
||||||
|
let exporter =
|
||||||
|
Cc["@mozilla.org/browser/places/import-export-service;1"].
|
||||||
|
getService(Ci.nsIPlacesImportExportService);
|
||||||
|
exporter.exportHTMLToFile(fp.file);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
fp.init(window, PlacesUIUtils.getString("EnterExport"),
|
fp.init(window, PlacesUIUtils.getString("EnterExport"),
|
||||||
Ci.nsIFilePicker.modeSave);
|
Ci.nsIFilePicker.modeSave);
|
||||||
fp.appendFilters(Ci.nsIFilePicker.filterHTML);
|
fp.appendFilters(Ci.nsIFilePicker.filterHTML);
|
||||||
fp.defaultString = "bookmarks.html";
|
fp.defaultString = "bookmarks.html";
|
||||||
if (fp.show() != Ci.nsIFilePicker.returnCancel) {
|
fp.open(fpCallback);
|
||||||
var exporter = Cc["@mozilla.org/browser/places/import-export-service;1"].
|
|
||||||
getService(Ci.nsIPlacesImportExportService);
|
|
||||||
exporter.exportHTMLToFile(fp.file);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -441,20 +446,23 @@ var PlacesOrganizer = {
|
|||||||
* Prompts for a file and restores bookmarks to those in the file.
|
* Prompts for a file and restores bookmarks to those in the file.
|
||||||
*/
|
*/
|
||||||
onRestoreBookmarksFromFile: function PO_onRestoreBookmarksFromFile() {
|
onRestoreBookmarksFromFile: function PO_onRestoreBookmarksFromFile() {
|
||||||
var fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
|
let dirSvc = Cc["@mozilla.org/file/directory_service;1"].
|
||||||
|
getService(Ci.nsIProperties);
|
||||||
|
let backupsDir = dirSvc.get("Desk", Ci.nsILocalFile);
|
||||||
|
let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
|
||||||
|
let fpCallback = function fpCallback_done(aResult) {
|
||||||
|
if (aResult != Ci.nsIFilePicker.returnCancel) {
|
||||||
|
this.restoreBookmarksFromFile(fp.file);
|
||||||
|
}
|
||||||
|
}.bind(this);
|
||||||
|
|
||||||
fp.init(window, PlacesUIUtils.getString("bookmarksRestoreTitle"),
|
fp.init(window, PlacesUIUtils.getString("bookmarksRestoreTitle"),
|
||||||
Ci.nsIFilePicker.modeOpen);
|
Ci.nsIFilePicker.modeOpen);
|
||||||
fp.appendFilter(PlacesUIUtils.getString("bookmarksRestoreFilterName"),
|
fp.appendFilter(PlacesUIUtils.getString("bookmarksRestoreFilterName"),
|
||||||
PlacesUIUtils.getString("bookmarksRestoreFilterExtension"));
|
PlacesUIUtils.getString("bookmarksRestoreFilterExtension"));
|
||||||
fp.appendFilters(Ci.nsIFilePicker.filterAll);
|
fp.appendFilters(Ci.nsIFilePicker.filterAll);
|
||||||
|
|
||||||
var dirSvc = Cc["@mozilla.org/file/directory_service;1"].
|
|
||||||
getService(Ci.nsIProperties);
|
|
||||||
var backupsDir = dirSvc.get("Desk", Ci.nsILocalFile);
|
|
||||||
fp.displayDirectory = backupsDir;
|
fp.displayDirectory = backupsDir;
|
||||||
|
fp.open(fpCallback);
|
||||||
if (fp.show() != Ci.nsIFilePicker.returnCancel)
|
|
||||||
this.restoreBookmarksFromFile(fp.file);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -498,21 +506,23 @@ var PlacesOrganizer = {
|
|||||||
* of those items.
|
* of those items.
|
||||||
*/
|
*/
|
||||||
backupBookmarks: function PO_backupBookmarks() {
|
backupBookmarks: function PO_backupBookmarks() {
|
||||||
var fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
|
let dirSvc = Cc["@mozilla.org/file/directory_service;1"].
|
||||||
|
getService(Ci.nsIProperties);
|
||||||
|
let backupsDir = dirSvc.get("Desk", Ci.nsILocalFile);
|
||||||
|
let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
|
||||||
|
let fpCallback = function fpCallback_done(aResult) {
|
||||||
|
if (aResult != Ci.nsIFilePicker.returnCancel) {
|
||||||
|
PlacesUtils.backups.saveBookmarksToJSONFile(fp.file);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
fp.init(window, PlacesUIUtils.getString("bookmarksBackupTitle"),
|
fp.init(window, PlacesUIUtils.getString("bookmarksBackupTitle"),
|
||||||
Ci.nsIFilePicker.modeSave);
|
Ci.nsIFilePicker.modeSave);
|
||||||
fp.appendFilter(PlacesUIUtils.getString("bookmarksRestoreFilterName"),
|
fp.appendFilter(PlacesUIUtils.getString("bookmarksRestoreFilterName"),
|
||||||
PlacesUIUtils.getString("bookmarksRestoreFilterExtension"));
|
PlacesUIUtils.getString("bookmarksRestoreFilterExtension"));
|
||||||
|
|
||||||
var dirSvc = Cc["@mozilla.org/file/directory_service;1"].
|
|
||||||
getService(Ci.nsIProperties);
|
|
||||||
var backupsDir = dirSvc.get("Desk", Ci.nsILocalFile);
|
|
||||||
fp.displayDirectory = backupsDir;
|
|
||||||
|
|
||||||
fp.defaultString = PlacesUtils.backups.getFilenameForDate();
|
fp.defaultString = PlacesUtils.backups.getFilenameForDate();
|
||||||
|
fp.displayDirectory = backupsDir;
|
||||||
if (fp.show() != Ci.nsIFilePicker.returnCancel)
|
fp.open(fpCallback);
|
||||||
PlacesUtils.backups.saveBookmarksToJSONFile(fp.file);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_paneDisabled: false,
|
_paneDisabled: false,
|
||||||
|
|||||||
@@ -1715,6 +1715,28 @@ var gApplicationsPane = {
|
|||||||
aEvent.stopPropagation();
|
aEvent.stopPropagation();
|
||||||
|
|
||||||
var handlerApp;
|
var handlerApp;
|
||||||
|
let chooseAppCallback = function(aHandlerApp) {
|
||||||
|
// Rebuild the actions menu whether the user picked an app or canceled.
|
||||||
|
// If they picked an app, we want to add the app to the menu and select it.
|
||||||
|
// If they canceled, we want to go back to their previous selection.
|
||||||
|
this.rebuildActionsMenu();
|
||||||
|
|
||||||
|
// If the user picked a new app from the menu, select it.
|
||||||
|
if (aHandlerApp) {
|
||||||
|
let typeItem = this._list.selectedItem;
|
||||||
|
let actionsMenu =
|
||||||
|
document.getAnonymousElementByAttribute(typeItem, "class", "actionsMenu");
|
||||||
|
let menuItems = actionsMenu.menupopup.childNodes;
|
||||||
|
for (let i = 0; i < menuItems.length; i++) {
|
||||||
|
let menuItem = menuItems[i];
|
||||||
|
if (menuItem.handlerApp && menuItem.handlerApp.equals(aHandlerApp)) {
|
||||||
|
actionsMenu.selectedIndex = i;
|
||||||
|
this.onSelectAction(menuItem);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.bind(this);
|
||||||
|
|
||||||
#ifdef XP_WIN
|
#ifdef XP_WIN
|
||||||
var params = {};
|
var params = {};
|
||||||
@@ -1743,47 +1765,33 @@ var gApplicationsPane = {
|
|||||||
// Add the app to the type's list of possible handlers.
|
// Add the app to the type's list of possible handlers.
|
||||||
handlerInfo.addPossibleApplicationHandler(handlerApp);
|
handlerInfo.addPossibleApplicationHandler(handlerApp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
chooseAppCallback(handlerApp);
|
||||||
#else
|
#else
|
||||||
var fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
|
let winTitle = this._prefsBundle.getString("fpTitleChooseApp");
|
||||||
var winTitle = this._prefsBundle.getString("fpTitleChooseApp");
|
let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
|
||||||
fp.init(window, winTitle, Ci.nsIFilePicker.modeOpen);
|
let fpCallback = function fpCallback_done(aResult) {
|
||||||
fp.appendFilters(Ci.nsIFilePicker.filterApps);
|
if (aResult == Ci.nsIFilePicker.returnOK && fp.file &&
|
||||||
|
this._isValidHandlerExecutable(fp.file)) {
|
||||||
|
handlerApp = Cc["@mozilla.org/uriloader/local-handler-app;1"].
|
||||||
|
createInstance(Ci.nsILocalHandlerApp);
|
||||||
|
handlerApp.name = getFileDisplayName(fp.file);
|
||||||
|
handlerApp.executable = fp.file;
|
||||||
|
|
||||||
|
// Add the app to the type's list of possible handlers.
|
||||||
|
let handlerInfo = this._handledTypes[this._list.selectedItem.type];
|
||||||
|
handlerInfo.addPossibleApplicationHandler(handlerApp);
|
||||||
|
|
||||||
|
chooseAppCallback(handlerApp);
|
||||||
|
}
|
||||||
|
}.bind(this);
|
||||||
|
|
||||||
// Prompt the user to pick an app. If they pick one, and it's a valid
|
// Prompt the user to pick an app. If they pick one, and it's a valid
|
||||||
// selection, then add it to the list of possible handlers.
|
// selection, then add it to the list of possible handlers.
|
||||||
if (fp.show() == Ci.nsIFilePicker.returnOK && fp.file &&
|
fp.init(window, winTitle, Ci.nsIFilePicker.modeOpen);
|
||||||
this._isValidHandlerExecutable(fp.file)) {
|
fp.appendFilters(Ci.nsIFilePicker.filterApps);
|
||||||
handlerApp = Cc["@mozilla.org/uriloader/local-handler-app;1"].
|
fp.open(fpCallback);
|
||||||
createInstance(Ci.nsILocalHandlerApp);
|
|
||||||
handlerApp.name = getFileDisplayName(fp.file);
|
|
||||||
handlerApp.executable = fp.file;
|
|
||||||
|
|
||||||
// Add the app to the type's list of possible handlers.
|
|
||||||
let handlerInfo = this._handledTypes[this._list.selectedItem.type];
|
|
||||||
handlerInfo.addPossibleApplicationHandler(handlerApp);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Rebuild the actions menu whether the user picked an app or canceled.
|
|
||||||
// If they picked an app, we want to add the app to the menu and select it.
|
|
||||||
// If they canceled, we want to go back to their previous selection.
|
|
||||||
this.rebuildActionsMenu();
|
|
||||||
|
|
||||||
// If the user picked a new app from the menu, select it.
|
|
||||||
if (handlerApp) {
|
|
||||||
let typeItem = this._list.selectedItem;
|
|
||||||
let actionsMenu =
|
|
||||||
document.getAnonymousElementByAttribute(typeItem, "class", "actionsMenu");
|
|
||||||
let menuItems = actionsMenu.menupopup.childNodes;
|
|
||||||
for (let i = 0; i < menuItems.length; i++) {
|
|
||||||
let menuItem = menuItems[i];
|
|
||||||
if (menuItem.handlerApp && menuItem.handlerApp.equals(handlerApp)) {
|
|
||||||
actionsMenu.selectedIndex = i;
|
|
||||||
this.onSelectAction(menuItem);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// Mark which item in the list was last selected so we can reselect it
|
// Mark which item in the list was last selected so we can reselect it
|
||||||
|
|||||||
@@ -1702,6 +1702,28 @@ var gApplicationsPane = {
|
|||||||
aEvent.stopPropagation();
|
aEvent.stopPropagation();
|
||||||
|
|
||||||
var handlerApp;
|
var handlerApp;
|
||||||
|
let chooseAppCallback = function(aHandlerApp) {
|
||||||
|
// Rebuild the actions menu whether the user picked an app or canceled.
|
||||||
|
// If they picked an app, we want to add the app to the menu and select it.
|
||||||
|
// If they canceled, we want to go back to their previous selection.
|
||||||
|
this.rebuildActionsMenu();
|
||||||
|
|
||||||
|
// If the user picked a new app from the menu, select it.
|
||||||
|
if (aHandlerApp) {
|
||||||
|
let typeItem = this._list.selectedItem;
|
||||||
|
let actionsMenu =
|
||||||
|
document.getAnonymousElementByAttribute(typeItem, "class", "actionsMenu");
|
||||||
|
let menuItems = actionsMenu.menupopup.childNodes;
|
||||||
|
for (let i = 0; i < menuItems.length; i++) {
|
||||||
|
let menuItem = menuItems[i];
|
||||||
|
if (menuItem.handlerApp && menuItem.handlerApp.equals(aHandlerApp)) {
|
||||||
|
actionsMenu.selectedIndex = i;
|
||||||
|
this.onSelectAction(menuItem);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.bind(this);
|
||||||
|
|
||||||
#ifdef XP_WIN
|
#ifdef XP_WIN
|
||||||
var params = {};
|
var params = {};
|
||||||
@@ -1730,47 +1752,33 @@ var gApplicationsPane = {
|
|||||||
// Add the app to the type's list of possible handlers.
|
// Add the app to the type's list of possible handlers.
|
||||||
handlerInfo.addPossibleApplicationHandler(handlerApp);
|
handlerInfo.addPossibleApplicationHandler(handlerApp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
chooseAppCallback(handlerApp);
|
||||||
#else
|
#else
|
||||||
var fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
|
let winTitle = this._prefsBundle.getString("fpTitleChooseApp");
|
||||||
var winTitle = this._prefsBundle.getString("fpTitleChooseApp");
|
let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
|
||||||
fp.init(window, winTitle, Ci.nsIFilePicker.modeOpen);
|
let fpCallback = function fpCallback_done(aResult) {
|
||||||
fp.appendFilters(Ci.nsIFilePicker.filterApps);
|
if (aResult == Ci.nsIFilePicker.returnOK && fp.file &&
|
||||||
|
this._isValidHandlerExecutable(fp.file)) {
|
||||||
|
handlerApp = Cc["@mozilla.org/uriloader/local-handler-app;1"].
|
||||||
|
createInstance(Ci.nsILocalHandlerApp);
|
||||||
|
handlerApp.name = getFileDisplayName(fp.file);
|
||||||
|
handlerApp.executable = fp.file;
|
||||||
|
|
||||||
|
// Add the app to the type's list of possible handlers.
|
||||||
|
let handlerInfo = this._handledTypes[this._list.selectedItem.type];
|
||||||
|
handlerInfo.addPossibleApplicationHandler(handlerApp);
|
||||||
|
|
||||||
|
chooseAppCallback(handlerApp);
|
||||||
|
}
|
||||||
|
}.bind(this);
|
||||||
|
|
||||||
// Prompt the user to pick an app. If they pick one, and it's a valid
|
// Prompt the user to pick an app. If they pick one, and it's a valid
|
||||||
// selection, then add it to the list of possible handlers.
|
// selection, then add it to the list of possible handlers.
|
||||||
if (fp.show() == Ci.nsIFilePicker.returnOK && fp.file &&
|
fp.init(window, winTitle, Ci.nsIFilePicker.modeOpen);
|
||||||
this._isValidHandlerExecutable(fp.file)) {
|
fp.appendFilters(Ci.nsIFilePicker.filterApps);
|
||||||
handlerApp = Cc["@mozilla.org/uriloader/local-handler-app;1"].
|
fp.open(fpCallback);
|
||||||
createInstance(Ci.nsILocalHandlerApp);
|
|
||||||
handlerApp.name = getFileDisplayName(fp.file);
|
|
||||||
handlerApp.executable = fp.file;
|
|
||||||
|
|
||||||
// Add the app to the type's list of possible handlers.
|
|
||||||
let handlerInfo = this._handledTypes[this._list.selectedItem.type];
|
|
||||||
handlerInfo.addPossibleApplicationHandler(handlerApp);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Rebuild the actions menu whether the user picked an app or canceled.
|
|
||||||
// If they picked an app, we want to add the app to the menu and select it.
|
|
||||||
// If they canceled, we want to go back to their previous selection.
|
|
||||||
this.rebuildActionsMenu();
|
|
||||||
|
|
||||||
// If the user picked a new app from the menu, select it.
|
|
||||||
if (handlerApp) {
|
|
||||||
let typeItem = this._list.selectedItem;
|
|
||||||
let actionsMenu =
|
|
||||||
document.getAnonymousElementByAttribute(typeItem, "class", "actionsMenu");
|
|
||||||
let menuItems = actionsMenu.menupopup.childNodes;
|
|
||||||
for (let i = 0; i < menuItems.length; i++) {
|
|
||||||
let menuItem = menuItems[i];
|
|
||||||
if (menuItem.handlerApp && menuItem.handlerApp.equals(handlerApp)) {
|
|
||||||
actionsMenu.selectedIndex = i;
|
|
||||||
this.onSelectAction(menuItem);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// Mark which item in the list was last selected so we can reselect it
|
// Mark which item in the list was last selected so we can reselect it
|
||||||
|
|||||||
@@ -258,17 +258,29 @@ var gMainPane = {
|
|||||||
const nsIFilePicker = Components.interfaces.nsIFilePicker;
|
const nsIFilePicker = Components.interfaces.nsIFilePicker;
|
||||||
const nsILocalFile = Components.interfaces.nsILocalFile;
|
const nsILocalFile = Components.interfaces.nsILocalFile;
|
||||||
|
|
||||||
var fp = Components.classes["@mozilla.org/filepicker;1"]
|
let bundlePreferences = document.getElementById("bundlePreferences");
|
||||||
.createInstance(nsIFilePicker);
|
let title = bundlePreferences.getString("chooseDownloadFolderTitle");
|
||||||
var bundlePreferences = document.getElementById("bundlePreferences");
|
let folderListPref = document.getElementById("browser.download.folderList");
|
||||||
var title = bundlePreferences.getString("chooseDownloadFolderTitle");
|
let currentDirPref = this._indexToFolder(folderListPref.value); // file
|
||||||
|
let defDownloads = this._indexToFolder(1); // file
|
||||||
|
let fp = Components.classes["@mozilla.org/filepicker;1"].
|
||||||
|
createInstance(nsIFilePicker);
|
||||||
|
let fpCallback = function fpCallback_done(aResult) {
|
||||||
|
if (aResult == nsIFilePicker.returnOK) {
|
||||||
|
let file = fp.file.QueryInterface(nsILocalFile);
|
||||||
|
let downloadDirPref = document.getElementById("browser.download.dir");
|
||||||
|
|
||||||
|
downloadDirPref.value = file;
|
||||||
|
folderListPref.value = this._folderToIndex(file);
|
||||||
|
// Note, the real prefs will not be updated yet, so dnld manager's
|
||||||
|
// userDownloadsDirectory may not return the right folder after
|
||||||
|
// this code executes. displayDownloadDirPref will be called on
|
||||||
|
// the assignment above to update the UI.
|
||||||
|
}
|
||||||
|
}.bind(this);
|
||||||
|
|
||||||
fp.init(window, title, nsIFilePicker.modeGetFolder);
|
fp.init(window, title, nsIFilePicker.modeGetFolder);
|
||||||
fp.appendFilters(nsIFilePicker.filterAll);
|
fp.appendFilters(nsIFilePicker.filterAll);
|
||||||
|
|
||||||
var folderListPref = document.getElementById("browser.download.folderList");
|
|
||||||
var currentDirPref = this._indexToFolder(folderListPref.value); // file
|
|
||||||
var defDownloads = this._indexToFolder(1); // file
|
|
||||||
|
|
||||||
// First try to open what's currently configured
|
// First try to open what's currently configured
|
||||||
if (currentDirPref && currentDirPref.exists()) {
|
if (currentDirPref && currentDirPref.exists()) {
|
||||||
fp.displayDirectory = currentDirPref;
|
fp.displayDirectory = currentDirPref;
|
||||||
@@ -279,18 +291,7 @@ var gMainPane = {
|
|||||||
else {
|
else {
|
||||||
fp.displayDirectory = this._indexToFolder(0);
|
fp.displayDirectory = this._indexToFolder(0);
|
||||||
}
|
}
|
||||||
|
fp.open(fpCallback);
|
||||||
if (fp.show() == nsIFilePicker.returnOK) {
|
|
||||||
var file = fp.file.QueryInterface(nsILocalFile);
|
|
||||||
var currentDirPref = document.getElementById("browser.download.dir");
|
|
||||||
currentDirPref.value = file;
|
|
||||||
var folderListPref = document.getElementById("browser.download.folderList");
|
|
||||||
folderListPref.value = this._folderToIndex(file);
|
|
||||||
// Note, the real prefs will not be updated yet, so dnld manager's
|
|
||||||
// userDownloadsDirectory may not return the right folder after
|
|
||||||
// this code executes. displayDownloadDirPref will be called on
|
|
||||||
// the assignment above to update the UI.
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -255,17 +255,29 @@ var gMainPane = {
|
|||||||
const nsIFilePicker = Components.interfaces.nsIFilePicker;
|
const nsIFilePicker = Components.interfaces.nsIFilePicker;
|
||||||
const nsILocalFile = Components.interfaces.nsILocalFile;
|
const nsILocalFile = Components.interfaces.nsILocalFile;
|
||||||
|
|
||||||
var fp = Components.classes["@mozilla.org/filepicker;1"]
|
let bundlePreferences = document.getElementById("bundlePreferences");
|
||||||
.createInstance(nsIFilePicker);
|
let title = bundlePreferences.getString("chooseDownloadFolderTitle");
|
||||||
var bundlePreferences = document.getElementById("bundlePreferences");
|
let folderListPref = document.getElementById("browser.download.folderList");
|
||||||
var title = bundlePreferences.getString("chooseDownloadFolderTitle");
|
let currentDirPref = this._indexToFolder(folderListPref.value); // file
|
||||||
|
let defDownloads = this._indexToFolder(1); // file
|
||||||
|
let fp = Components.classes["@mozilla.org/filepicker;1"].
|
||||||
|
createInstance(nsIFilePicker);
|
||||||
|
let fpCallback = function fpCallback_done(aResult) {
|
||||||
|
if (aResult == nsIFilePicker.returnOK) {
|
||||||
|
let file = fp.file.QueryInterface(nsILocalFile);
|
||||||
|
let downloadDirPref = document.getElementById("browser.download.dir");
|
||||||
|
|
||||||
|
downloadDirPref.value = file;
|
||||||
|
folderListPref.value = this._folderToIndex(file);
|
||||||
|
// Note, the real prefs will not be updated yet, so dnld manager's
|
||||||
|
// userDownloadsDirectory may not return the right folder after
|
||||||
|
// this code executes. displayDownloadDirPref will be called on
|
||||||
|
// the assignment above to update the UI.
|
||||||
|
}
|
||||||
|
}.bind(this);
|
||||||
|
|
||||||
fp.init(window, title, nsIFilePicker.modeGetFolder);
|
fp.init(window, title, nsIFilePicker.modeGetFolder);
|
||||||
fp.appendFilters(nsIFilePicker.filterAll);
|
fp.appendFilters(nsIFilePicker.filterAll);
|
||||||
|
|
||||||
var folderListPref = document.getElementById("browser.download.folderList");
|
|
||||||
var currentDirPref = this._indexToFolder(folderListPref.value); // file
|
|
||||||
var defDownloads = this._indexToFolder(1); // file
|
|
||||||
|
|
||||||
// First try to open what's currently configured
|
// First try to open what's currently configured
|
||||||
if (currentDirPref && currentDirPref.exists()) {
|
if (currentDirPref && currentDirPref.exists()) {
|
||||||
fp.displayDirectory = currentDirPref;
|
fp.displayDirectory = currentDirPref;
|
||||||
@@ -276,18 +288,7 @@ var gMainPane = {
|
|||||||
else {
|
else {
|
||||||
fp.displayDirectory = this._indexToFolder(0);
|
fp.displayDirectory = this._indexToFolder(0);
|
||||||
}
|
}
|
||||||
|
fp.open(fpCallback);
|
||||||
if (fp.show() == nsIFilePicker.returnOK) {
|
|
||||||
var file = fp.file.QueryInterface(nsILocalFile);
|
|
||||||
var currentDirPref = document.getElementById("browser.download.dir");
|
|
||||||
currentDirPref.value = file;
|
|
||||||
var folderListPref = document.getElementById("browser.download.folderList");
|
|
||||||
folderListPref.value = this._folderToIndex(file);
|
|
||||||
// Note, the real prefs will not be updated yet, so dnld manager's
|
|
||||||
// userDownloadsDirectory may not return the right folder after
|
|
||||||
// this code executes. displayDownloadDirPref will be called on
|
|
||||||
// the assignment above to update the UI.
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -668,15 +668,7 @@ var Scratchpad = {
|
|||||||
*/
|
*/
|
||||||
openFile: function SP_openFile(aIndex)
|
openFile: function SP_openFile(aIndex)
|
||||||
{
|
{
|
||||||
let fp;
|
let promptCallback = function(aFile) {
|
||||||
if (!aIndex && aIndex !== 0) {
|
|
||||||
fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
|
|
||||||
fp.init(window, this.strings.GetStringFromName("openFile.title"),
|
|
||||||
Ci.nsIFilePicker.modeOpen);
|
|
||||||
fp.defaultString = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aIndex > -1 || fp.show() != Ci.nsIFilePicker.returnCancel) {
|
|
||||||
this.promptSave(function(aCloseFile, aSaved, aStatus) {
|
this.promptSave(function(aCloseFile, aSaved, aStatus) {
|
||||||
let shouldOpen = aCloseFile;
|
let shouldOpen = aCloseFile;
|
||||||
if (aSaved && !Components.isSuccessCode(aStatus)) {
|
if (aSaved && !Components.isSuccessCode(aStatus)) {
|
||||||
@@ -687,8 +679,8 @@ var Scratchpad = {
|
|||||||
this._skipClosePrompt = true;
|
this._skipClosePrompt = true;
|
||||||
|
|
||||||
let file;
|
let file;
|
||||||
if (fp) {
|
if (aFile) {
|
||||||
file = fp.file;
|
file = aFile;
|
||||||
} else {
|
} else {
|
||||||
file = Components.classes["@mozilla.org/file/local;1"].
|
file = Components.classes["@mozilla.org/file/local;1"].
|
||||||
createInstance(Components.interfaces.nsILocalFile);
|
createInstance(Components.interfaces.nsILocalFile);
|
||||||
@@ -701,6 +693,22 @@ var Scratchpad = {
|
|||||||
this.setRecentFile(file);
|
this.setRecentFile(file);
|
||||||
}
|
}
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
|
}.bind(this);
|
||||||
|
|
||||||
|
if (aIndex > -1) {
|
||||||
|
promptCallback();
|
||||||
|
} else {
|
||||||
|
let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
|
||||||
|
let fpCallback = function fpCallback_done(aResult) {
|
||||||
|
if (aResult != Ci.nsIFilePicker.returnCancel) {
|
||||||
|
promptCallback(fp.file);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fp.init(window, this.strings.GetStringFromName("openFile.title"),
|
||||||
|
Ci.nsIFilePicker.modeOpen);
|
||||||
|
fp.defaultString = "";
|
||||||
|
fp.open(fpCallback);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -894,22 +902,25 @@ var Scratchpad = {
|
|||||||
saveFileAs: function SP_saveFileAs(aCallback)
|
saveFileAs: function SP_saveFileAs(aCallback)
|
||||||
{
|
{
|
||||||
let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
|
let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
|
||||||
|
let fpCallback = function fpCallback_done(aResult) {
|
||||||
|
if (aResult != Ci.nsIFilePicker.returnCancel) {
|
||||||
|
this.setFilename(fp.file.path);
|
||||||
|
this.exportToFile(fp.file, true, false, function(aStatus) {
|
||||||
|
if (Components.isSuccessCode(aStatus)) {
|
||||||
|
this.editor.dirty = false;
|
||||||
|
this.setRecentFile(fp.file);
|
||||||
|
}
|
||||||
|
if (aCallback) {
|
||||||
|
aCallback(aStatus);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}.bind(this);
|
||||||
|
|
||||||
fp.init(window, this.strings.GetStringFromName("saveFileAs"),
|
fp.init(window, this.strings.GetStringFromName("saveFileAs"),
|
||||||
Ci.nsIFilePicker.modeSave);
|
Ci.nsIFilePicker.modeSave);
|
||||||
fp.defaultString = "scratchpad.js";
|
fp.defaultString = "scratchpad.js";
|
||||||
if (fp.show() != Ci.nsIFilePicker.returnCancel) {
|
fp.open(fpCallback);
|
||||||
this.setFilename(fp.file.path);
|
|
||||||
|
|
||||||
this.exportToFile(fp.file, true, false, function(aStatus) {
|
|
||||||
if (Components.isSuccessCode(aStatus)) {
|
|
||||||
this.editor.dirty = false;
|
|
||||||
this.setRecentFile(fp.file);
|
|
||||||
}
|
|
||||||
if (aCallback) {
|
|
||||||
aCallback(aStatus);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -288,22 +288,24 @@ StyleEditor.prototype = {
|
|||||||
*/
|
*/
|
||||||
importFromFile: function SE_importFromFile(aFile, aParentWindow)
|
importFromFile: function SE_importFromFile(aFile, aParentWindow)
|
||||||
{
|
{
|
||||||
aFile = this._showFilePicker(aFile, false, aParentWindow);
|
let callback = function(aFile) {
|
||||||
if (!aFile) {
|
if (aFile) {
|
||||||
return;
|
this._savedFile = aFile; // remember filename for next save if any
|
||||||
}
|
|
||||||
this._savedFile = aFile; // remember filename for next save if any
|
|
||||||
|
|
||||||
NetUtil.asyncFetch(aFile, function onAsyncFetch(aStream, aStatus) {
|
NetUtil.asyncFetch(aFile, function onAsyncFetch(aStream, aStatus) {
|
||||||
if (!Components.isSuccessCode(aStatus)) {
|
if (!Components.isSuccessCode(aStatus)) {
|
||||||
return this._signalError(LOAD_ERROR);
|
return this._signalError(LOAD_ERROR);
|
||||||
|
}
|
||||||
|
let source = NetUtil.readInputStreamToString(aStream, aStream.available());
|
||||||
|
aStream.close();
|
||||||
|
|
||||||
|
this._appendNewStyleSheet(source);
|
||||||
|
this.clearFlag(StyleEditorFlags.ERROR);
|
||||||
|
}.bind(this));
|
||||||
}
|
}
|
||||||
let source = NetUtil.readInputStreamToString(aStream, aStream.available());
|
}.bind(this);
|
||||||
aStream.close();
|
|
||||||
|
|
||||||
this._appendNewStyleSheet(source);
|
this._showFilePicker(aFile, false, aParentWindow, callback);
|
||||||
this.clearFlag(StyleEditorFlags.ERROR);
|
|
||||||
}.bind(this));
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -553,46 +555,48 @@ StyleEditor.prototype = {
|
|||||||
*/
|
*/
|
||||||
saveToFile: function SE_saveToFile(aFile, aCallback)
|
saveToFile: function SE_saveToFile(aFile, aCallback)
|
||||||
{
|
{
|
||||||
aFile = this._showFilePicker(aFile || this._styleSheetFilePath, true);
|
let callback = function(aReturnFile) {
|
||||||
|
if (!aReturnFile) {
|
||||||
if (!aFile) {
|
|
||||||
if (aCallback) {
|
|
||||||
aCallback(null);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this._sourceEditor) {
|
|
||||||
this._state.text = this._sourceEditor.getText();
|
|
||||||
}
|
|
||||||
|
|
||||||
let ostream = FileUtils.openSafeFileOutputStream(aFile);
|
|
||||||
let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"]
|
|
||||||
.createInstance(Ci.nsIScriptableUnicodeConverter);
|
|
||||||
converter.charset = "UTF-8";
|
|
||||||
let istream = converter.convertToInputStream(this._state.text);
|
|
||||||
|
|
||||||
NetUtil.asyncCopy(istream, ostream, function SE_onStreamCopied(status) {
|
|
||||||
if (!Components.isSuccessCode(status)) {
|
|
||||||
if (aCallback) {
|
if (aCallback) {
|
||||||
aCallback(null);
|
aCallback(null);
|
||||||
}
|
}
|
||||||
this._signalError(SAVE_ERROR);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
FileUtils.closeSafeFileOutputStream(ostream);
|
|
||||||
|
|
||||||
// remember filename for next save if any
|
if (this._sourceEditor) {
|
||||||
this._friendlyName = null;
|
this._state.text = this._sourceEditor.getText();
|
||||||
this._savedFile = aFile;
|
|
||||||
this._persistExpando();
|
|
||||||
|
|
||||||
if (aCallback) {
|
|
||||||
aCallback(aFile);
|
|
||||||
}
|
}
|
||||||
this.clearFlag(StyleEditorFlags.UNSAVED);
|
|
||||||
this.clearFlag(StyleEditorFlags.ERROR);
|
let ostream = FileUtils.openSafeFileOutputStream(aReturnFile);
|
||||||
}.bind(this));
|
let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"]
|
||||||
|
.createInstance(Ci.nsIScriptableUnicodeConverter);
|
||||||
|
converter.charset = "UTF-8";
|
||||||
|
let istream = converter.convertToInputStream(this._state.text);
|
||||||
|
|
||||||
|
NetUtil.asyncCopy(istream, ostream, function SE_onStreamCopied(status) {
|
||||||
|
if (!Components.isSuccessCode(status)) {
|
||||||
|
if (aCallback) {
|
||||||
|
aCallback(null);
|
||||||
|
}
|
||||||
|
this._signalError(SAVE_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
FileUtils.closeSafeFileOutputStream(ostream);
|
||||||
|
|
||||||
|
// remember filename for next save if any
|
||||||
|
this._friendlyName = null;
|
||||||
|
this._savedFile = aReturnFile;
|
||||||
|
this._persistExpando();
|
||||||
|
|
||||||
|
if (aCallback) {
|
||||||
|
aCallback(aReturnFile);
|
||||||
|
}
|
||||||
|
this.clearFlag(StyleEditorFlags.UNSAVED);
|
||||||
|
this.clearFlag(StyleEditorFlags.ERROR);
|
||||||
|
}.bind(this));
|
||||||
|
}.bind(this);
|
||||||
|
|
||||||
|
this._showFilePicker(aFile || this._styleSheetFilePath, true, null, callback);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -690,31 +694,36 @@ StyleEditor.prototype = {
|
|||||||
* @param nsIWindow aParentWindow
|
* @param nsIWindow aParentWindow
|
||||||
* Optional parent window. If null the parent window of the file picker
|
* Optional parent window. If null the parent window of the file picker
|
||||||
* will be the window of the attached input element.
|
* will be the window of the attached input element.
|
||||||
* @return nsIFile
|
* @param aCallback
|
||||||
* The selected file or null if the user did not pick one.
|
* The callback method, which will be called passing in the selected
|
||||||
|
* file or null if the user did not pick one.
|
||||||
*/
|
*/
|
||||||
_showFilePicker: function SE__showFilePicker(aFile, aSave, aParentWindow)
|
_showFilePicker: function SE__showFilePicker(aFile, aSave, aParentWindow, aCallback)
|
||||||
{
|
{
|
||||||
if (typeof(aFile) == "string") {
|
if (typeof(aFile) == "string") {
|
||||||
try {
|
try {
|
||||||
if (Services.io.extractScheme(aFile) == "file") {
|
if (Services.io.extractScheme(aFile) == "file") {
|
||||||
let uri = Services.io.newURI(aFile, null, null);
|
let uri = Services.io.newURI(aFile, null, null);
|
||||||
let file = uri.QueryInterface(Ci.nsIFileURL).file;
|
let file = uri.QueryInterface(Ci.nsIFileURL).file;
|
||||||
return file;
|
aCallback(file);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
|
let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
|
||||||
file.initWithPath(aFile);
|
file.initWithPath(aFile);
|
||||||
return file;
|
aCallback(file);
|
||||||
|
return;
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
this._signalError(aSave ? SAVE_ERROR : LOAD_ERROR);
|
this._signalError(aSave ? SAVE_ERROR : LOAD_ERROR);
|
||||||
return null;
|
aCallback(null);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (aFile) {
|
if (aFile) {
|
||||||
return aFile;
|
aCallback(aFile);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let window = aParentWindow
|
let window = aParentWindow
|
||||||
@@ -723,13 +732,19 @@ StyleEditor.prototype = {
|
|||||||
let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
|
let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
|
||||||
let mode = aSave ? fp.modeSave : fp.modeOpen;
|
let mode = aSave ? fp.modeSave : fp.modeOpen;
|
||||||
let key = aSave ? "saveStyleSheet" : "importStyleSheet";
|
let key = aSave ? "saveStyleSheet" : "importStyleSheet";
|
||||||
|
let fpCallback = function fpCallback_done(aResult) {
|
||||||
|
if (aResult == Ci.nsIFilePicker.returnCancel) {
|
||||||
|
aCallback(null);
|
||||||
|
} else {
|
||||||
|
aCallback(fp.file);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
fp.init(window, _(key + ".title"), mode);
|
fp.init(window, _(key + ".title"), mode);
|
||||||
fp.appendFilters(_(key + ".filter"), "*.css");
|
fp.appendFilters(_(key + ".filter"), "*.css");
|
||||||
fp.appendFilters(fp.filterAll);
|
fp.appendFilters(fp.filterAll);
|
||||||
|
fp.open(fpCallback);
|
||||||
let rv = fp.show();
|
return;
|
||||||
return (rv == fp.returnCancel) ? null : fp.file;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ interface nsIURI;
|
|||||||
interface nsIDOMWindow;
|
interface nsIDOMWindow;
|
||||||
interface nsISimpleEnumerator;
|
interface nsISimpleEnumerator;
|
||||||
|
|
||||||
[scriptable, uuid(0d79adad-b244-49A5-9997-2a8cad93fc44)]
|
[scriptable, function, uuid(0d79adad-b244-49A5-9997-2a8cad93fc44)]
|
||||||
interface nsIFilePickerShownCallback : nsISupports
|
interface nsIFilePickerShownCallback : nsISupports
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user