<commit_before>// Useful "constants"
var sqlDateTimeRe = /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/;
var isoDateTimeRe = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z$/;
var zoteroObjectKeyRe = /^[23456789ABCDEFGHIJKLMNPQRSTUVWXYZ]{8}$/; // based on Zotero.Utilities::generateObjectKey()

/**
 * Waits for a DOM event on the specified node. Returns a promise
 * resolved with the event.
 */
function waitForDOMEvent(target, event, capture) {
	var deferred = Zotero.Promise.defer();
	var func = function(ev) {
		target.removeEventListener(event, func, capture);
		deferred.resolve(ev);
	}
	target.addEventListener(event, func, capture);
	return deferred.promise;
}

/**
 * Open a chrome window and return a promise for the window
 *
 * @return {Promise<ChromeWindow>}
 */
function loadWindow(winurl, argument) {
	var win = window.openDialog(winurl, "_blank", "chrome", argument);
	return waitForDOMEvent(win, "load").then(function() {
		return win;
	});
}

/**
 * Open a browser window and return a promise for the window
 *
 * @return {Promise<ChromeWindow>}
 */
function loadBrowserWindow() {
	var win = window.openDialog("chrome://browser/content/browser.xul", "", "all,height=400,width=1000");
	return waitForDOMEvent(win, "load").then(function() {
		return win;
	});
}

/**
 * Opens the Zotero pane and selects My Library. Returns the containing window.
 *
 * @param {Window} [win] - Existing window to use; if not specified, a new window is opened
 */
var loadZoteroPane = Zotero.Promise.coroutine(function* (win) {
	if (!win) {
		var win = yield loadBrowserWindow();
	}
	Zotero.Prefs.clear('lastViewedFolder');
	win.ZoteroOverlay.toggleDisplay(true);
	
	yield waitForItemsLoad(win, 0);
	
	return win;
});

/**
 * Waits for a window with a specific URL to open. Returns a promise for the window, and
 * optionally passes the window to a callback immediately for use with modal dialogs,
 * which prevent async code from continuing
 */
function waitForWindow(uri, callback) {
	var deferred = Zotero.Promise.defer();
	Components.utils.import("resource://gre/modules/Services.jsm");
	var loadobserver = function(ev) {
		ev.originalTarget.removeEventListener("load", loadobserver, false);
		if(ev.target.location.href == uri) {
			Services.ww.unregisterNotification(winobserver);
			var win = ev.target.docShell
				.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
				.getInterface(Components.interfaces.nsIDOMWindow);
			// Give window code time to run on load
			win.setTimeout(function () {
				if (callback) {
					try {
						// If callback is a promise, wait for it
						let maybePromise = callback(win);
						if (maybePromise && maybePromise.then) {
							maybePromise.then(() => deferred.resolve(win)).catch(e => deferred.reject(e));
							return;
						}
					}
					catch (e) {
						Zotero.logError(e);
						win.close();
						deferred.reject(e);
						return;
					}
				}
				deferred.resolve(win);<commit_msg>Log opened windows in waitForWindow() test support function<commit_after>// Useful "constants"
var sqlDateTimeRe = /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/;
var isoDateTimeRe = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z$/;
var zoteroObjectKeyRe = /^[23456789ABCDEFGHIJKLMNPQRSTUVWXYZ]{8}$/; // based on Zotero.Utilities::generateObjectKey()

/**
 * Waits for a DOM event on the specified node. Returns a promise
 * resolved with the event.
 */
function waitForDOMEvent(target, event, capture) {
	var deferred = Zotero.Promise.defer();
	var func = function(ev) {
		target.removeEventListener(event, func, capture);
		deferred.resolve(ev);
	}
	target.addEventListener(event, func, capture);
	return deferred.promise;
}

/**
 * Open a chrome window and return a promise for the window
 *
 * @return {Promise<ChromeWindow>}
 */
function loadWindow(winurl, argument) {
	var win = window.openDialog(winurl, "_blank", "chrome", argument);
	return waitForDOMEvent(win, "load").then(function() {
		return win;
	});
}

/**
 * Open a browser window and return a promise for the window
 *
 * @return {Promise<ChromeWindow>}
 */
function loadBrowserWindow() {
	var win = window.openDialog("chrome://browser/content/browser.xul", "", "all,height=400,width=1000");
	return waitForDOMEvent(win, "load").then(function() {
		return win;
	});
}

/**
 * Opens the Zotero pane and selects My Library. Returns the containing window.
 *
 * @param {Window} [win] - Existing window to use; if not specified, a new window is opened
 */
var loadZoteroPane = Zotero.Promise.coroutine(function* (win) {
	if (!win) {
		var win = yield loadBrowserWindow();
	}
	Zotero.Prefs.clear('lastViewedFolder');
	win.ZoteroOverlay.toggleDisplay(true);
	
	yield waitForItemsLoad(win, 0);
	
	return win;
});

/**
 * Waits for a window with a specific URL to open. Returns a promise for the window, and
 * optionally passes the window to a callback immediately for use with modal dialogs,
 * which prevent async code from continuing
 */
function waitForWindow(uri, callback) {
	var deferred = Zotero.Promise.defer();
	Components.utils.import("resource://gre/modules/Services.jsm");
	var loadobserver = function(ev) {
		ev.originalTarget.removeEventListener("load", loadobserver, false);
		Zotero.debug("Window opened: " + ev.target.location.href);
		if(ev.target.location.href == uri) {
			Services.ww.unregisterNotification(winobserver);
			var win = ev.target.docShell
				.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
				.getInterface(Components.interfaces.nsIDOMWindow);
			// Give window code time to run on load
			win.setTimeout(function () {
				if (callback) {
					try {
						// If callback is a promise, wait for it
						let maybePromise = callback(win);
						if (maybePromise && maybePromise.then) {
							maybePromise.then(() => deferred.resolve(win)).catch(e => deferred.reject(e));
							return;
						}
					}
					catch (e) {
						Zotero.logError(e);
						win.close();
						deferred.reject(e);
						return;
					}
				}
				deferred.resolve(win);
{'fraction_non_alphanumeric': 0.14256994471435752, 'fraction_numerical': 0.009716870497570782, 'mean_word_length': 3.9625935162094765, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4405147', 'n_tokens_mistral': 2161, 'n_tokens_neox': 1901, 'n_words': 489}