<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

"use strict";

var EXPORTED_SYMBOLS = [ "SearchEngines" ];


const { classes: Cc, interfaces: Ci, utils: Cu } = Components;

Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");

XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
    "resource://gre/modules/FileUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "OS",
    "resource://gre/modules/osfile.jsm");


const OPENSEARCH_NS = "http://a9.com/-/spec/opensearch/1.1/";
const OPENSEARCH_LOCALNAME = "OpenSearchDescription";

const MOZSEARCH_NS = "http://www.mozilla.org/2006/browser/search/";
const MOZSEARCH_LOCALNAME = "SearchPlugin";

/*
 * The different available alternatives for the empty base document used to
 * serialize an engine.
 */
const OPENSEARCH_EMPTY_ENGINE_DOC = `<?xml version="1.0"?>
<${OPENSEARCH_LOCALNAME} xmlns="${OPENSEARCH_NS}" xmlns:moz="${MOZSEARCH_NS}"/>
`;
const MOZSEARCH_EMPTY_ENGINE_DOC = `<?xml version="1.0"?>
<${MOZSEARCH_LOCALNAME} xmlns="${MOZSEARCH_NS}" xmlns:os="${OPENSEARCH_NS}"/>
`;
Object.defineProperty(this, "emptyEngineDoc", {
    get: function() {
        let useMozNs = Services.prefs.getBoolPref(
                        "extensions.xseei.exporter.useMozNamespaceAsDefault");
        return useMozNs ? MOZSEARCH_EMPTY_ENGINE_DOC
                        : OPENSEARCH_EMPTY_ENGINE_DOC;
    },
    enumerable: true
});

const MAX_ENGINE_FILENAME_LENGTH = 60;

const ABOUT_MOZPARAMS_EXPORT_MSG =
    "The original definition of this search engine included too some " +
    "non-standard 'MozParam' parameters. As they are recognized by " +
    "Firefox only if they are found in an engine included by default in " +
    "the application, they were omitted here.";


function appendTextNode(document, namespace, localName, value) {
    if (!value)
        return null;

    let node = document.createElementNS(namespace, localName);
    node.appendChild(document.createTextNode(value));
    document.documentElement.appendChild(node);
    document.documentElement.appendChild(document.createTextNode("\n"));
    return node;
}


/*
 * A object encapsulating a set of utilities to deal with search engines.
 *
 * Many of these has been recovered from upstream as they were removed by bug
 * 1203167, which replaces the storage of the user-installed search engines
 * in individual xml files with the new compressed 'search.json.mozlz4' file:
 *
 *   https://bugzilla.mozilla.org/show_bug.cgi?id=1203167
 */
var SearchEngines = {

    addEngineFromXmlFile(file) {
        return new Promise((resolve, reject) => {
            let uri = OS.Path.toFileURI(file.path);

            let searchInstallCallback = {
                onSuccess: engine => {
                    resolve(engine);
                },
                onError: errorCode => {
                    switch (errorCode) {
                        case Ci.nsISearchInstallCallback.ERROR_DUPLICATE_ENGINE:
                            reject(Error("a search engine with the included " +
                                         "name already exists"));
                            break;

                        case Ci.nsISearchInstallCallback.ERROR_UNKNOWN_FAILURE:
                        default:
                            reject(Error("unknown error"));
                            break;
                    }
                }
            };

            Services.search.addEngine(uri,
                                      Ci.nsISearchEngine.DATA_XML,
                                      "",       // iconURL
                                      false,    // confirm
                                      searchInstallCallback);
        });
    },


    saveEnginesToZipFile(engines, file) {
        return Promise.resolve().then(() => {
            let zw = Cc["@mozilla.org/zipwriter;1"]
                        .createInstance(Ci.nsIZipWriter);
            zw.open(file,
                    FileUtils.MODE_WRONLY | FileUtils.MODE_CREATE
                                          | FileUtils.MODE_TRUNCATE);

            let serializer = Cc["@mozilla.org/xmlextras/xmlserializer;1"]
                                .createInstance(Ci.nsIDOMSerializer);

            engines.forEach(engine => {
                let doc = this.serializeEngineToDocument(engine);

                let istream = Cc["@mozilla.org/io/string-input-stream;1"]
                                .createInstance(Ci.nsIStringInputStream);
                istream.data = serializer.serializeToString(doc);

                zw.addEntryStream(this.sanitizeEngineName(engine.name) + ".xml",
                                  Date.now() * 1000,
                                  Ci.nsIZipWriter.COMPRESSION_DEFAULT,
                                  istream,
                                  false);
            });
            zw.close();
        });
    },


    saveEngineToXmlFile(engine, file) {
        let serializer = Cc["@mozilla.org/xmlextras/xmlserializer;1"]
                                .createInstance(Ci.nsIDOMSerializer);

        let doc = this.serializeEngineToDocument(engine);
        let data = serializer.serializeToString(doc);

        let useTmpFile = Services.prefs.getBoolPref(
                            "extensions.xseei.exporter.useTemporaryFile");<commit_msg>Fix files with wrong encoding in export-all zip file<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

"use strict";

var EXPORTED_SYMBOLS = [ "SearchEngines" ];


const { classes: Cc, interfaces: Ci, utils: Cu } = Components;

Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");

XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
    "resource://gre/modules/FileUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "OS",
    "resource://gre/modules/osfile.jsm");


const OPENSEARCH_NS = "http://a9.com/-/spec/opensearch/1.1/";
const OPENSEARCH_LOCALNAME = "OpenSearchDescription";

const MOZSEARCH_NS = "http://www.mozilla.org/2006/browser/search/";
const MOZSEARCH_LOCALNAME = "SearchPlugin";

/*
 * The different available alternatives for the empty base document used to
 * serialize an engine.
 */
const OPENSEARCH_EMPTY_ENGINE_DOC = `<?xml version="1.0"?>
<${OPENSEARCH_LOCALNAME} xmlns="${OPENSEARCH_NS}" xmlns:moz="${MOZSEARCH_NS}"/>
`;
const MOZSEARCH_EMPTY_ENGINE_DOC = `<?xml version="1.0"?>
<${MOZSEARCH_LOCALNAME} xmlns="${MOZSEARCH_NS}" xmlns:os="${OPENSEARCH_NS}"/>
`;
Object.defineProperty(this, "emptyEngineDoc", {
    get: function() {
        let useMozNs = Services.prefs.getBoolPref(
                        "extensions.xseei.exporter.useMozNamespaceAsDefault");
        return useMozNs ? MOZSEARCH_EMPTY_ENGINE_DOC
                        : OPENSEARCH_EMPTY_ENGINE_DOC;
    },
    enumerable: true
});

const MAX_ENGINE_FILENAME_LENGTH = 60;

const ABOUT_MOZPARAMS_EXPORT_MSG =
    "The original definition of this search engine included too some " +
    "non-standard 'MozParam' parameters. As they are recognized by " +
    "Firefox only if they are found in an engine included by default in " +
    "the application, they were omitted here.";


function appendTextNode(document, namespace, localName, value) {
    if (!value)
        return null;

    let node = document.createElementNS(namespace, localName);
    node.appendChild(document.createTextNode(value));
    document.documentElement.appendChild(node);
    document.documentElement.appendChild(document.createTextNode("\n"));
    return node;
}


/*
 * A object encapsulating a set of utilities to deal with search engines.
 *
 * Many of these has been recovered from upstream as they were removed by bug
 * 1203167, which replaces the storage of the user-installed search engines
 * in individual xml files with the new compressed 'search.json.mozlz4' file:
 *
 *   https://bugzilla.mozilla.org/show_bug.cgi?id=1203167
 */
var SearchEngines = {

    addEngineFromXmlFile(file) {
        return new Promise((resolve, reject) => {
            let uri = OS.Path.toFileURI(file.path);

            let searchInstallCallback = {
                onSuccess: engine => {
                    resolve(engine);
                },
                onError: errorCode => {
                    switch (errorCode) {
                        case Ci.nsISearchInstallCallback.ERROR_DUPLICATE_ENGINE:
                            reject(Error("a search engine with the included " +
                                         "name already exists"));
                            break;

                        case Ci.nsISearchInstallCallback.ERROR_UNKNOWN_FAILURE:
                        default:
                            reject(Error("unknown error"));
                            break;
                    }
                }
            };

            Services.search.addEngine(uri,
                                      Ci.nsISearchEngine.DATA_XML,
                                      "",       // iconURL
                                      false,    // confirm
                                      searchInstallCallback);
        });
    },


    saveEnginesToZipFile(engines, file) {
        return Promise.resolve().then(() => {
            let zw = Cc["@mozilla.org/zipwriter;1"]
                        .createInstance(Ci.nsIZipWriter);
            zw.open(file,
                    FileUtils.MODE_WRONLY | FileUtils.MODE_CREATE
                                          | FileUtils.MODE_TRUNCATE);

            let serializer = Cc["@mozilla.org/xmlextras/xmlserializer;1"]
                                .createInstance(Ci.nsIDOMSerializer);
            let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"]
                            .createInstance(Ci.nsIScriptableUnicodeConverter);
            converter.charset = "UTF-8";

            engines.forEach(engine => {
                let doc = this.serializeEngineToDocument(engine);
                let str = serializer.serializeToString(doc);
                let istream = converter.convertToInputStream(str);

                zw.addEntryStream(this.sanitizeEngineName(engine.name) + ".xml",
                                  Date.now() * 1000,
                                  Ci.nsIZipWriter.COMPRESSION_DEFAULT,
                                  istream,
                                  false);
            });
            zw.close();
        });
    },


    saveEngineToXmlFile(engine, file) {
        let serializer = Cc["@mozilla.org/xmlextras/xmlserializer;1"]
                                .createInstance(Ci.nsIDOMSerializer);

        let doc = this.serializeEngineToDocument(engine);
        let data = serializer.serializeToString(doc);

        let useTmpFile = Services.prefs.getBoolPref(
                            "extensions.xseei.exporter.useTemporaryFile");
{'fraction_non_alphanumeric': 0.10317957904164801, 'fraction_numerical': 0.007165248544558889, 'mean_word_length': 1.9752198241406875, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 4, '>': 21, 'https://': 2, 'lorem ipsum': 0, 'www.': 2, 'xml': 24}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 26, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '918858', 'n_tokens_mistral': 3171, 'n_tokens_neox': 2967, 'n_words': 633}