Oreon-Lime-R2/mingw-wine-gecko/wine-gecko-2.47.4-src/wine-gecko-2.47.4/browser/components/extensions/ext-windows.js

216 lines
8.3 KiB
JavaScript
Raw Normal View History

/* -*- 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", null, (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 => {
// FIXME: This will send multiple messages for a single focus change.
let listener = event => {
let window = WindowManager.topWindow;
let windowId = window ? WindowManager.getId(window) : WindowManager.WINDOW_ID_NONE;
fire(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) {
if (createData.state !== null && createData.state != "normal") {
if (createData.left !== null || createData.top !== null ||
createData.width !== null || createData.height !== null) {
return Promise.reject({message: `"state": "${createData.state}" may not be combined with "left", "top", "width", or "height"`});
}
}
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);
if (tab == null) {
return Promise.reject({message: `Invalid tab ID: ${createData.tabId}`});
}
// 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);
if (createData.left !== null || createData.top !== null) {
let left = createData.left !== null ? createData.left : window.screenX;
let top = createData.top !== null ? createData.top : window.screenY;
window.moveTo(left, top);
}
if (createData.width !== null || createData.height !== null) {
let width = createData.width !== null ? createData.width : window.outerWidth;
let height = createData.height !== null ? createData.height : window.outerHeight;
window.resizeTo(width, height);
}
// 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) {
// TODO: When we support size/position updates:
// 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);
}
// 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);
});
},
},
};
});