forked from mirrors/gecko-dev
MozReview-Commit-ID: E5G0GmVhzLh --HG-- extra : rebase_source : 5c6624b9d2d06109a1b047ad48dcac7e9405ee59 extra : amend_source : fb23020f7d2772f56fabc61f2e32f7d9c4c2f52a
217 lines
8 KiB
JavaScript
217 lines
8 KiB
JavaScript
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
|
/* vim: set sts=2 sw=2 et tw=80: */
|
|
"use strict";
|
|
|
|
XPCOMUtils.defineLazyServiceGetter(this, "aboutNewTabService",
|
|
"@mozilla.org/browser/aboutnewtab-service;1",
|
|
"nsIAboutNewTabService");
|
|
XPCOMUtils.defineLazyModuleGetter(this, "AppConstants",
|
|
"resource://gre/modules/AppConstants.jsm");
|
|
XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils",
|
|
"resource://gre/modules/PrivateBrowsingUtils.jsm");
|
|
|
|
Cu.import("resource://gre/modules/ExtensionUtils.jsm");
|
|
var {
|
|
EventManager,
|
|
} = ExtensionUtils;
|
|
|
|
extensions.registerSchemaAPI("windows", (extension, context) => {
|
|
return {
|
|
windows: {
|
|
onCreated:
|
|
new WindowEventManager(context, "windows.onCreated", "domwindowopened", (fire, window) => {
|
|
fire(WindowManager.convert(extension, window));
|
|
}).api(),
|
|
|
|
onRemoved:
|
|
new WindowEventManager(context, "windows.onRemoved", "domwindowclosed", (fire, window) => {
|
|
fire(WindowManager.getId(window));
|
|
}).api(),
|
|
|
|
onFocusChanged: new EventManager(context, "windows.onFocusChanged", fire => {
|
|
// Keep track of the last windowId used to fire an onFocusChanged event
|
|
let lastOnFocusChangedWindowId;
|
|
|
|
let listener = event => {
|
|
let window = WindowManager.topWindow;
|
|
let windowId = window ? WindowManager.getId(window) : WindowManager.WINDOW_ID_NONE;
|
|
if (windowId !== lastOnFocusChangedWindowId) {
|
|
fire(windowId);
|
|
lastOnFocusChangedWindowId = windowId;
|
|
}
|
|
};
|
|
AllWindowEvents.addListener("focus", listener);
|
|
AllWindowEvents.addListener("blur", listener);
|
|
return () => {
|
|
AllWindowEvents.removeListener("focus", listener);
|
|
AllWindowEvents.removeListener("blur", listener);
|
|
};
|
|
}).api(),
|
|
|
|
get: function(windowId, getInfo) {
|
|
let window = WindowManager.getWindow(windowId, context);
|
|
return Promise.resolve(WindowManager.convert(extension, window, getInfo));
|
|
},
|
|
|
|
getCurrent: function(getInfo) {
|
|
let window = currentWindow(context);
|
|
return Promise.resolve(WindowManager.convert(extension, window, getInfo));
|
|
},
|
|
|
|
getLastFocused: function(getInfo) {
|
|
let window = WindowManager.topWindow;
|
|
return Promise.resolve(WindowManager.convert(extension, window, getInfo));
|
|
},
|
|
|
|
getAll: function(getInfo) {
|
|
let windows = Array.from(WindowListManager.browserWindows(),
|
|
window => WindowManager.convert(extension, window, getInfo));
|
|
return Promise.resolve(windows);
|
|
},
|
|
|
|
create: function(createData) {
|
|
let needResize = (createData.left !== null || createData.top !== null ||
|
|
createData.width !== null || createData.height !== null);
|
|
|
|
if (needResize) {
|
|
if (createData.state !== null && createData.state != "normal") {
|
|
return Promise.reject({message: `"state": "${createData.state}" may not be combined with "left", "top", "width", or "height"`});
|
|
}
|
|
createData.state = "normal";
|
|
}
|
|
|
|
function mkstr(s) {
|
|
let result = Cc["@mozilla.org/supports-string;1"].createInstance(Ci.nsISupportsString);
|
|
result.data = s;
|
|
return result;
|
|
}
|
|
|
|
let args = Cc["@mozilla.org/supports-array;1"].createInstance(Ci.nsISupportsArray);
|
|
|
|
if (createData.tabId !== null) {
|
|
if (createData.url !== null) {
|
|
return Promise.reject({message: "`tabId` may not be used in conjunction with `url`"});
|
|
}
|
|
|
|
let tab = TabManager.getTab(createData.tabId, context);
|
|
|
|
// Private browsing tabs can only be moved to private browsing
|
|
// windows.
|
|
let incognito = PrivateBrowsingUtils.isBrowserPrivate(tab.linkedBrowser);
|
|
if (createData.incognito !== null && createData.incognito != incognito) {
|
|
return Promise.reject({message: "`incognito` property must match the incognito state of tab"});
|
|
}
|
|
createData.incognito = incognito;
|
|
|
|
args.AppendElement(tab);
|
|
} else if (createData.url !== null) {
|
|
if (Array.isArray(createData.url)) {
|
|
let array = Cc["@mozilla.org/supports-array;1"].createInstance(Ci.nsISupportsArray);
|
|
for (let url of createData.url) {
|
|
array.AppendElement(mkstr(url));
|
|
}
|
|
args.AppendElement(array);
|
|
} else {
|
|
args.AppendElement(mkstr(createData.url));
|
|
}
|
|
} else {
|
|
args.AppendElement(mkstr(aboutNewTabService.newTabURL));
|
|
}
|
|
|
|
let features = ["chrome"];
|
|
|
|
if (createData.type === null || createData.type == "normal") {
|
|
features.push("dialog=no", "all");
|
|
} else {
|
|
// All other types create "popup"-type windows by default.
|
|
features.push("dialog", "resizable", "minimizable", "centerscreen", "titlebar", "close");
|
|
}
|
|
|
|
if (createData.incognito !== null) {
|
|
if (createData.incognito) {
|
|
features.push("private");
|
|
} else {
|
|
features.push("non-private");
|
|
}
|
|
}
|
|
|
|
let window = Services.ww.openWindow(null, "chrome://browser/content/browser.xul", "_blank",
|
|
features.join(","), args);
|
|
|
|
WindowManager.updateGeometry(window, createData);
|
|
|
|
// TODO: focused, type
|
|
|
|
return new Promise(resolve => {
|
|
window.addEventListener("load", function listener() {
|
|
window.removeEventListener("load", listener);
|
|
|
|
if (createData.state == "maximized" || createData.state == "normal" ||
|
|
(createData.state == "fullscreen" && AppConstants.platform != "macosx")) {
|
|
window.document.documentElement.setAttribute("sizemode", createData.state);
|
|
} else if (createData.state !== null) {
|
|
// window.minimize() has no useful effect until the window has
|
|
// been shown.
|
|
|
|
let obs = doc => {
|
|
if (doc === window.document) {
|
|
Services.obs.removeObserver(obs, "document-shown");
|
|
WindowManager.setState(window, createData.state);
|
|
resolve();
|
|
}
|
|
};
|
|
Services.obs.addObserver(obs, "document-shown", false);
|
|
return;
|
|
}
|
|
|
|
resolve();
|
|
});
|
|
}).then(() => {
|
|
return WindowManager.convert(extension, window);
|
|
});
|
|
},
|
|
|
|
update: function(windowId, updateInfo) {
|
|
if (updateInfo.state !== null && updateInfo.state != "normal") {
|
|
if (updateInfo.left !== null || updateInfo.top !== null ||
|
|
updateInfo.width !== null || updateInfo.height !== null) {
|
|
return Promise.reject({message: `"state": "${updateInfo.state}" may not be combined with "left", "top", "width", or "height"`});
|
|
}
|
|
}
|
|
|
|
let window = WindowManager.getWindow(windowId, context);
|
|
if (updateInfo.focused) {
|
|
Services.focus.activeWindow = window;
|
|
}
|
|
|
|
if (updateInfo.state !== null) {
|
|
WindowManager.setState(window, updateInfo.state);
|
|
}
|
|
|
|
if (updateInfo.drawAttention) {
|
|
// Bug 1257497 - Firefox can't cancel attention actions.
|
|
window.getAttention();
|
|
}
|
|
|
|
WindowManager.updateGeometry(window, updateInfo);
|
|
|
|
// TODO: All the other properties, focused=false...
|
|
|
|
return Promise.resolve(WindowManager.convert(extension, window));
|
|
},
|
|
|
|
remove: function(windowId) {
|
|
let window = WindowManager.getWindow(windowId, context);
|
|
window.close();
|
|
|
|
return new Promise(resolve => {
|
|
let listener = () => {
|
|
AllWindowEvents.removeListener("domwindowclosed", listener);
|
|
resolve();
|
|
};
|
|
AllWindowEvents.addListener("domwindowclosed", listener);
|
|
});
|
|
},
|
|
},
|
|
};
|
|
});
|