<commit_before>/*==================================================
 *
 *              Timeline API
 *              ------------
 *
 * This file will load all the Javascript files
 * necessary to make the standard timeline work.
 * It also detects the default locale.
 *
 * To run Timeline directly from the www.simile-widgets.org server
 * include this fragment in your HTML file as follows:
 *
 *   <script src="http://api.simile-widgets.org/timeline/2.3.1/timeline-api.js"
 *    type="text/javascript"></script>
 *
 *
 * To host the Timeline files on your own server:
 *
 * 1) Install the Timeline files onto your webserver using
 *    the minimal distribution "timeline_<version>_minimal.(zip|tar.gz)" found at
 *
 *        http://code.google.com/p/simile-widgets/downloads/list
 *
 * 2) Set the following global js variable used to send parameters to this script:
 *     var Timeline_ajax_url  -- URL for simile-ajax-api.js
 *     var Timeline_urlPrefix -- URL for the *directory* that contains timeline-api.js
 *                               on your web site (including the trailing slash!)
 *
 * eg your HTML page would include
 *
 *   <script>
 *     var Timeline_ajax_url="http://YOUR_SERVER/apis/timeline/ajax/simile-ajax-api.js";
 *     var Timeline_urlPrefix='http://YOUR_SERVER/apis/timeline/';
 *   </script>
 *   <script src="http://YOUR_SERVER/javascripts/timeline/timeline-api.js"
 *     type="text/javascript">
 *   </script>
 *
 * SCRIPT PARAMETERS
 *
 * This script auto-magically figures out locale and has defaults for other parameters
 * To set parameters explicity, set js global variable Timeline_parameters or include as
 * parameters on the url using GET style. Eg the two next lines pass the same parameters:
 *     Timeline_parameters='bundle=true';                    // pass parameter via js variable
 *     <script src="http://....timeline-api.js?bundle=true"  // pass parameter via url
 *
 * Parameters
 *   timeline-use-local-resources --
 *   bundle -- true: use the single js bundle file; false: load individual files (for debugging)
 *   locales --
 *   defaultLocale --
 *   forceLocale -- force locale to be a particular value--used for debugging. Normally locale is determined
 *                  by browser's and server's locale settings.
 *
 * DEBUGGING
 *
 * If you have a problem with Timeline, the first step is to use the unbundled Javascript files. To do so:
 * To use the unbundled Timeline and Ajax libraries
 * Change
 *   <script src="http://api.simile-widgets.org/timeline/2.3.1/api/timeline-api.js?bundle=true" type="text/javascript"></script>
 * To
 *   <script>var Timeline_ajax_url = "http://api.simile-widgets.org/ajax/2.2.1/simile-ajax-api.js?bundle=false"</script>
 *   <script src="http://api.simile-widgets.org/timeline/2.3.1/api/timeline-api.js?bundle=false" type="text/javascript"></script>
 *
 * Note that the Ajax version is usually NOT the same as the Timeline version.
 * See variable simile_ajax_ver below for the current version
 *
 *==================================================
 */

(function() {

    var simile_ajax_ver = "2.2.1"; // ===========>>>  current Simile-Ajax version

    var isCompiled = ("Timeline_isCompiled" in window) && window.Timeline_isCompiled;

    var useLocalResources = false;
    if (document.location.search.length > 0) {
        var params = document.location.search.substr(1).split("&");
        for (var i = 0; i < params.length; i++) {
            if (params[i] == "timeline-use-local-resources") {
                useLocalResources = true;
            }
        }
    };

    var loadMe = function() {
        if ("Timeline" in window) {
            return;
        }

        window.Timeline = new Object();
        window.Timeline.DateTime = window.SimileAjax.DateTime; // for backward compatibility

        var bundle = false;
        var javascriptFiles = [
            "timeline.js",
            "band.js",
            "themes.js",
            "ethers.js",
            "ether-painters.js",
            "event-utils.js",
            "labellers.js",
            "sources.js",
            "original-painter.js",
            "detailed-painter.js",
            "overview-painter.js",
            "compact-painter.js",
            "decorators.js"
        ];
        var cssFiles = [
            "timeline.css",
            "ethers.css",
            "events.css"
        ];

        var localizedJavascriptFiles = [
            "timeline.js",
            "labellers.js"
        ];
        var localizedCssFiles = [
        ];

        // ISO-639 language codes, ISO-3166 country codes (2 characters)
        var supportedLocales = [
            "cs",       // Czech
            "de",       // German
            "en",       // English
            "es",       // Spanish
            "fr",       // French
            "it",       // Italian
            "nl",       // Dutch (The Netherlands)
            "ru",       // Russian
            "se",       // Swedish
            "tr",       // Turkish
            "vi",       // Vietnamese
            "zh"        // Chinese
        ];

        try {
            var desiredLocales = [ "en" ],
                defaultServerLocale = "en",
                forceLocale = null;

            var parseURLParameters = function(parameters) {
                var params = parameters.split("&");
                for (var p = 0; p < params.length; p++) {
                    var pair = params[p].split("=");
                    if (pair[0] == "locales") {
                        desiredLocales = desiredLocales.concat(pair[1].split(","));
                    } else if (pair[0] == "defaultLocale") {
                        defaultServerLocale = pair[1];
                    } else if (pair[0] == "forceLocale") {
                        forceLocale = pair[1];
                        desiredLocales = desiredLocales.concat(pair[1].split(","));
                    } else if (pair[0] == "bundle") {
                        bundle = pair[1] != "false";
                    }
                }
            };

            (function() {
                if (typeof Timeline_urlPrefix == "string") {
                    Timeline.urlPrefix = Timeline_urlPrefix;
                    if (typeof Timeline_parameters == "string") {
                        parseURLParameters(Timeline_parameters);
                    }
                } else {
                    var heads = document.documentElement.getElementsByTagName("head");
                    for (var h = 0; h < heads.length; h++) {
                        var scripts = heads[h].getElementsByTagName("script");
                        for (var s = 0; s < scripts.length; s++) {
                            var url = scripts[s].src;
                            var i = url.indexOf("timeline-api.js");
                            if (i >= 0) {
                                Timeline.urlPrefix = url.substr(0, i);
                                var q = url.indexOf("?");
                                if (q > 0) {
                                    parseURLParameters(url.substr(q + 1));
                                }
                                return;
                            }
                        }
                    }
                    throw new Error("Failed to derive URL prefix for Timeline API code files");
                }
            })();

            var includeJavascriptFiles = function(urlPrefix, filenames) {
                SimileAjax.includeJavascriptFiles(document, urlPrefix, filenames);
            }
            var includeCssFiles = function(urlPrefix, filenames) {
                SimileAjax.includeCssFiles(document, urlPrefix, filenames);
            }

            /*
             *  Include non-localized files
             */
            if (!isCompiled) {
                if (bundle) {
                    includeJavascriptFiles(Timeline.urlPrefix, [ "timeline-bundle.js" ]);
                    includeCssFiles(Timeline.urlPrefix, [ "timeline-bundle.css" ]);
                } else {
                    includeJavascriptFiles(Timeline.urlPrefix + "scripts/", javascriptFiles);
                    includeCssFiles(Timeline.urlPrefix + "styles/", cssFiles);
                }
            }

            /*
             *  Include localized files
             */
            var loadLocale = [];
            loadLocale[defaultServerLocale] = true;

            var tryExactLocale = function(locale) {
                for (var l = 0; l < supportedLocales.length; l++) {
                    if (locale == supportedLocales[l]) {
                        loadLocale[locale] = true;
                        return true;
                    }
                }
                return false;
            }
            var tryLocale = function(locale) {
                if (tryExactLocale(locale)) {
                    return locale;
                }

                var dash = locale.indexOf("-");
                if (dash > 0 && tryExactLocale(locale.substr(0, dash))) {
                    return locale.substr(0, dash);
                }

                return null;
            }

            for (var l = 0; l < desiredLocales.length; l++) {
                tryLocale(desiredLocales[l]);
            }

            var defaultClientLocale = defaultServerLocale;
            var defaultClientLocales = ("language" in navigator ? navigator.language : navigator.browserLanguage).split(";");
            for (var l = 0; l < defaultClientLocales.length; l++) {
                var locale = tryLocale(defaultClientLocales[l]);
                if (locale != null) {
                    defaultClientLocale = locale;
                    break;
                }
            }

            if (!isCompiled) {
                for (var l = 0; l < supportedLocales.length; l++) {
                    var locale = supportedLocales[l];
                    if (loadLocale[locale]) {
                        includeJavascriptFiles(Timeline.urlPrefix + "scripts/l10n/" + locale + "/", localizedJavascriptFiles);
                        includeCssFiles(Timeline.urlPrefix + "styles/l10n/" + locale + "/", localizedCssFiles);
                    }
                }
            }

            if (forceLocale == null) {
              Timeline.serverLocale = defaultServerLocale;
              Timeline.clientLocale = defaultClientLocale;
            } else {
              Timeline.serverLocale = forceLocale;
              Timeline.clientLocale = forceLocale;
            }
        } catch (e) {
            alert(e);
        }
    };

    /*
     *  Load SimileAjax if it's not already loaded
     */
    if (typeof SimileAjax == "undefined" && !isCompiled) {
        window.SimileAjax_onLoad = loadMe;

        var url = useLocalResources ?
            "http://127.0.0.1:9999/ajax/api/simile-ajax-api.js?bundle=false" :
            "http://api.simile-widgets.org/ajax/" + simile_ajax_ver + "/simile-ajax-api.js";
        if (typeof Timeline_ajax_url == "string") {
           url = Timeline_ajax_url;
        }
        var createScriptElement = function() {
            var script = document.createElement("script");
            script.type = "text/javascript";
            script.language = "JavaScript";
            script.src = url;
            document.getElementsByTagName("head")[0].appendChild(script);
        }
        if (document.body == null) {
            try {
                document.write("<script src='" + url + "' type='text/javascript'></script>");
            } catch (e) {
                createScriptElement();
            }
        } else {
            createScriptElement();
        }
    } else {
        loadMe();
    }
})();
<commit_msg>adding polish support to api file<commit_after>/*==================================================
 *
 *              Timeline API
 *              ------------
 *
 * This file will load all the Javascript files
 * necessary to make the standard timeline work.
 * It also detects the default locale.
 *
 * To run Timeline directly from the www.simile-widgets.org server
 * include this fragment in your HTML file as follows:
 *
 *   <script src="http://api.simile-widgets.org/timeline/2.3.1/timeline-api.js"
 *    type="text/javascript"></script>
 *
 *
 * To host the Timeline files on your own server:
 *
 * 1) Install the Timeline files onto your webserver using
 *    the minimal distribution "timeline_<version>_minimal.(zip|tar.gz)" found at
 *
 *        http://code.google.com/p/simile-widgets/downloads/list
 *
 * 2) Set the following global js variable used to send parameters to this script:
 *     var Timeline_ajax_url  -- URL for simile-ajax-api.js
 *     var Timeline_urlPrefix -- URL for the *directory* that contains timeline-api.js
 *                               on your web site (including the trailing slash!)
 *
 * eg your HTML page would include
 *
 *   <script>
 *     var Timeline_ajax_url="http://YOUR_SERVER/apis/timeline/ajax/simile-ajax-api.js";
 *     var Timeline_urlPrefix='http://YOUR_SERVER/apis/timeline/';
 *   </script>
 *   <script src="http://YOUR_SERVER/javascripts/timeline/timeline-api.js"
 *     type="text/javascript">
 *   </script>
 *
 * SCRIPT PARAMETERS
 *
 * This script auto-magically figures out locale and has defaults for other parameters
 * To set parameters explicity, set js global variable Timeline_parameters or include as
 * parameters on the url using GET style. Eg the two next lines pass the same parameters:
 *     Timeline_parameters='bundle=true';                    // pass parameter via js variable
 *     <script src="http://....timeline-api.js?bundle=true"  // pass parameter via url
 *
 * Parameters
 *   timeline-use-local-resources --
 *   bundle -- true: use the single js bundle file; false: load individual files (for debugging)
 *   locales --
 *   defaultLocale --
 *   forceLocale -- force locale to be a particular value--used for debugging. Normally locale is determined
 *                  by browser's and server's locale settings.
 *
 * DEBUGGING
 *
 * If you have a problem with Timeline, the first step is to use the unbundled Javascript files. To do so:
 * To use the unbundled Timeline and Ajax libraries
 * Change
 *   <script src="http://api.simile-widgets.org/timeline/2.3.1/api/timeline-api.js?bundle=true" type="text/javascript"></script>
 * To
 *   <script>var Timeline_ajax_url = "http://api.simile-widgets.org/ajax/2.2.1/simile-ajax-api.js?bundle=false"</script>
 *   <script src="http://api.simile-widgets.org/timeline/2.3.1/api/timeline-api.js?bundle=false" type="text/javascript"></script>
 *
 * Note that the Ajax version is usually NOT the same as the Timeline version.
 * See variable simile_ajax_ver below for the current version
 *
 *==================================================
 */

(function() {

    var simile_ajax_ver = "2.2.1"; // ===========>>>  current Simile-Ajax version

    var isCompiled = ("Timeline_isCompiled" in window) && window.Timeline_isCompiled;

    var useLocalResources = false;
    if (document.location.search.length > 0) {
        var params = document.location.search.substr(1).split("&");
        for (var i = 0; i < params.length; i++) {
            if (params[i] == "timeline-use-local-resources") {
                useLocalResources = true;
            }
        }
    };

    var loadMe = function() {
        if ("Timeline" in window) {
            return;
        }

        window.Timeline = new Object();
        window.Timeline.DateTime = window.SimileAjax.DateTime; // for backward compatibility

        var bundle = false;
        var javascriptFiles = [
            "timeline.js",
            "band.js",
            "themes.js",
            "ethers.js",
            "ether-painters.js",
            "event-utils.js",
            "labellers.js",
            "sources.js",
            "original-painter.js",
            "detailed-painter.js",
            "overview-painter.js",
            "compact-painter.js",
            "decorators.js"
        ];
        var cssFiles = [
            "timeline.css",
            "ethers.css",
            "events.css"
        ];

        var localizedJavascriptFiles = [
            "timeline.js",
            "labellers.js"
        ];
        var localizedCssFiles = [
        ];

        // ISO-639 language codes, ISO-3166 country codes (2 characters)
        var supportedLocales = [
            "cs",       // Czech
            "de",       // German
            "en",       // English
            "es",       // Spanish
            "fr",       // French
            "it",       // Italian
            "nl",       // Dutch (The Netherlands)
            "pl",       // Polish
            "ru",       // Russian
            "se",       // Swedish
            "tr",       // Turkish
            "vi",       // Vietnamese
            "zh"        // Chinese
        ];

        try {
            var desiredLocales = [ "en" ],
                defaultServerLocale = "en",
                forceLocale = null;

            var parseURLParameters = function(parameters) {
                var params = parameters.split("&");
                for (var p = 0; p < params.length; p++) {
                    var pair = params[p].split("=");
                    if (pair[0] == "locales") {
                        desiredLocales = desiredLocales.concat(pair[1].split(","));
                    } else if (pair[0] == "defaultLocale") {
                        defaultServerLocale = pair[1];
                    } else if (pair[0] == "forceLocale") {
                        forceLocale = pair[1];
                        desiredLocales = desiredLocales.concat(pair[1].split(","));
                    } else if (pair[0] == "bundle") {
                        bundle = pair[1] != "false";
                    }
                }
            };

            (function() {
                if (typeof Timeline_urlPrefix == "string") {
                    Timeline.urlPrefix = Timeline_urlPrefix;
                    if (typeof Timeline_parameters == "string") {
                        parseURLParameters(Timeline_parameters);
                    }
                } else {
                    var heads = document.documentElement.getElementsByTagName("head");
                    for (var h = 0; h < heads.length; h++) {
                        var scripts = heads[h].getElementsByTagName("script");
                        for (var s = 0; s < scripts.length; s++) {
                            var url = scripts[s].src;
                            var i = url.indexOf("timeline-api.js");
                            if (i >= 0) {
                                Timeline.urlPrefix = url.substr(0, i);
                                var q = url.indexOf("?");
                                if (q > 0) {
                                    parseURLParameters(url.substr(q + 1));
                                }
                                return;
                            }
                        }
                    }
                    throw new Error("Failed to derive URL prefix for Timeline API code files");
                }
            })();

            var includeJavascriptFiles = function(urlPrefix, filenames) {
                SimileAjax.includeJavascriptFiles(document, urlPrefix, filenames);
            }
            var includeCssFiles = function(urlPrefix, filenames) {
                SimileAjax.includeCssFiles(document, urlPrefix, filenames);
            }

            /*
             *  Include non-localized files
             */
            if (!isCompiled) {
                if (bundle) {
                    includeJavascriptFiles(Timeline.urlPrefix, [ "timeline-bundle.js" ]);
                    includeCssFiles(Timeline.urlPrefix, [ "timeline-bundle.css" ]);
                } else {
                    includeJavascriptFiles(Timeline.urlPrefix + "scripts/", javascriptFiles);
                    includeCssFiles(Timeline.urlPrefix + "styles/", cssFiles);
                }
            }

            /*
             *  Include localized files
             */
            var loadLocale = [];
            loadLocale[defaultServerLocale] = true;

            var tryExactLocale = function(locale) {
                for (var l = 0; l < supportedLocales.length; l++) {
                    if (locale == supportedLocales[l]) {
                        loadLocale[locale] = true;
                        return true;
                    }
                }
                return false;
            }
            var tryLocale = function(locale) {
                if (tryExactLocale(locale)) {
                    return locale;
                }

                var dash = locale.indexOf("-");
                if (dash > 0 && tryExactLocale(locale.substr(0, dash))) {
                    return locale.substr(0, dash);
                }

                return null;
            }

            for (var l = 0; l < desiredLocales.length; l++) {
                tryLocale(desiredLocales[l]);
            }

            var defaultClientLocale = defaultServerLocale;
            var defaultClientLocales = ("language" in navigator ? navigator.language : navigator.browserLanguage).split(";");
            for (var l = 0; l < defaultClientLocales.length; l++) {
                var locale = tryLocale(defaultClientLocales[l]);
                if (locale != null) {
                    defaultClientLocale = locale;
                    break;
                }
            }

            if (!isCompiled) {
                for (var l = 0; l < supportedLocales.length; l++) {
                    var locale = supportedLocales[l];
                    if (loadLocale[locale]) {
                        includeJavascriptFiles(Timeline.urlPrefix + "scripts/l10n/" + locale + "/", localizedJavascriptFiles);
                        includeCssFiles(Timeline.urlPrefix + "styles/l10n/" + locale + "/", localizedCssFiles);
                    }
                }
            }

            if (forceLocale == null) {
              Timeline.serverLocale = defaultServerLocale;
              Timeline.clientLocale = defaultClientLocale;
            } else {
              Timeline.serverLocale = forceLocale;
              Timeline.clientLocale = forceLocale;
            }
        } catch (e) {
            alert(e);
        }
    };

    /*
     *  Load SimileAjax if it's not already loaded
     */
    if (typeof SimileAjax == "undefined" && !isCompiled) {
        window.SimileAjax_onLoad = loadMe;

        var url = useLocalResources ?
            "http://127.0.0.1:9999/ajax/api/simile-ajax-api.js?bundle=false" :
            "http://api.simile-widgets.org/ajax/" + simile_ajax_ver + "/simile-ajax-api.js";
        if (typeof Timeline_ajax_url == "string") {
           url = Timeline_ajax_url;
        }
        var createScriptElement = function() {
            var script = document.createElement("script");
            script.type = "text/javascript";
            script.language = "JavaScript";
            script.src = url;
            document.getElementsByTagName("head")[0].appendChild(script);
        }
        if (document.body == null) {
            try {
                document.write("<script src='" + url + "' type='text/javascript'></script>");
            } catch (e) {
                createScriptElement();
            }
        } else {
            createScriptElement();
        }
    } else {
        loadMe();
    }
})();
<|endoftext|>


<commit_before>const EXPORT = ["IconEmbedder"];

const HB_NS = "http://b.hatena.ne.jp/";

function IconEmbedder(doc) {
    this.doc = doc;
    this.site = SiteInfoSet.Paragraphs.get(doc);
    if (this.site)
        this.ready();
}

extend(IconEmbedder.prototype, {
    strings: new Strings("chrome://hatenabookmark/locale/browser.properties"),

    ready: function IE_ready() {
        this.embed();
        this.doc.addEventListener("HB.PageInserted", this, false);
        this.doc.defaultView.addEventListener("GM_AutoPagerizeLoaded", this, false, true);
    },

    embed: function IE_embed() {
        this.site.queryAll("paragraph").forEach(function (paragraph) {
            if (paragraph.hasAttributeNS(HB_NS, "counter")) return;
            paragraph.setAttributeNS(HB_NS, "hb:counter", "true");

            let link = this.site.query("link", paragraph) || paragraph;
            if (!link.href) return;
            let annotation = this.site.query("annotation", paragraph) || link;
            let container = annotation.parentNode;
            let anchor = annotation.nextSibling;
            switch (this.site.annotationPosition) {
            case "before":
                anchor = annotation;
                break;

            case "first":
                container = annotation;
                anchor = annotation.firstChild;
                break;

            case "last":
                container = annotation;
                anchor = null;
                break;

            case "after":
            default:
                break;
            }
            let icons = this.createIcons(link, paragraph);
            container.insertBefore(icons, anchor);
        }, this);
    },

    createIcons: function IE_createIcons(link, paragraph) {
        let icons = this.doc.createDocumentFragment();
        let space = this.doc.createTextNode(" ");
        if (Prefs.bookmark.get("embed.counter")) {
            let counter = xml2dom(

            );
            icons.appendChild(counter);
        }
        if (Prefs.bookmark.get("embed.addButton")) {
            if (icons.lastChild)
                icons.appendChild(space.cloneNode(false));
            let addButton = xml2dom(

            );
            icons.appendChild(addButton)
        }
        if (icons.firstChild) {
            icons.insertBefore(space.cloneNode(false), icons.firstChild);
            icons.appendChild(space.cloneNode(false));
        }
        return icons;
    },

    handleEvent: function IE_handleEvent(event) {
        switch (event.type) {
        case "DOMNodeInserted":
            if ("isPage" in this.site.data &&
                !this.site.query("isPage", event.target, Boolean))
                break;
            // fall through
        case "HB.PageInserted":
            this.embed();
            break;

        case "GM_AutoPagerizeLoaded":
            this.doc.addEventListener("DOMNodeInserted", this, false);
            break;
        }
    }
});

function tryToEmbedIcons(event) {
    if (Prefs.bookmark.get("embed.enabled") &&
        event.target instanceof HTMLDocument)
        new IconEmbedder(event.target);
}

window.addEventListener("load", function IconEmbedder_BEGIN() {
    gBrowser.addEventListener("DOMContentLoaded", tryToEmbedIcons, false);
}, false);
<commit_msg>検索結果でのアイコン表示: スタイルの追加。<commit_after>const EXPORT = ["IconEmbedder"];

const HB_NS = "http://b.hatena.ne.jp/";

function IconEmbedder(doc) {
    this.doc = doc;
    this.site = SiteInfoSet.Paragraphs.get(doc);
    if (this.site)
        this.ready();
}

IconEmbedder.STYLE = <![CDATA[
    .hBookmark-embedded-counter img,
    .hBookmark-embedded-add-button img {
        border: none;
        vertical-align: text-bottom;
    }
]]>.toString().replace(/\s+/g, " ");

extend(IconEmbedder.prototype, {
    strings: new Strings("chrome://hatenabookmark/locale/browser.properties"),

    ready: function IE_ready() {
        this.embedStyles();
        this.embed();
        this.doc.addEventListener("HB.PageInserted", this, false);
        this.doc.defaultView.addEventListener("GM_AutoPagerizeLoaded", this, false, true);
    },

    embedStyles: function IE_embedStyles() {
        let style = this.doc.createElementNS(XHTML_NS, "style");
        style.setAttribute("type", "text/css");
        style.textContent = IconEmbedder.STYLE;
        let head = this.doc.getElementsByTagName("head")[0];
        if (!head) return;
        head.appendChild(style);
    },

    embed: function IE_embed() {
        this.site.queryAll("paragraph").forEach(function (paragraph) {
            if (paragraph.hasAttributeNS(HB_NS, "counter")) return;
            paragraph.setAttributeNS(HB_NS, "hb:counter", "true");

            let link = this.site.query("link", paragraph) || paragraph;
            if (!link.href) return;
            let annotation = this.site.query("annotation", paragraph) || link;
            let container = annotation.parentNode;
            let anchor = annotation.nextSibling;
            switch (this.site.annotationPosition) {
            case "before":
                anchor = annotation;
                break;

            case "first":
                container = annotation;
                anchor = annotation.firstChild;
                break;

            case "last":
                container = annotation;
                anchor = null;
                break;

            case "after":
            default:
                break;
            }
            let icons = this.createIcons(link, paragraph);
            container.insertBefore(icons, anchor);
        }, this);
    },

    createIcons: function IE_createIcons(link, paragraph) {
        let icons = this.doc.createDocumentFragment();
        let space = this.doc.createTextNode(" ");
        if (Prefs.bookmark.get("embed.counter")) {
            let counter = xml2dom(

            );
            icons.appendChild(counter);
        }
        if (Prefs.bookmark.get("embed.addButton")) {
            if (icons.lastChild)
                icons.appendChild(space.cloneNode(false));
            let addButton = xml2dom(

            );
            icons.appendChild(addButton)
        }
        if (icons.firstChild) {
            icons.insertBefore(space.cloneNode(false), icons.firstChild);
            icons.appendChild(space.cloneNode(false));
        }
        return icons;
    },

    handleEvent: function IE_handleEvent(event) {
        switch (event.type) {
        case "DOMNodeInserted":
            if ("isPage" in this.site.data &&
                !this.site.query("isPage", event.target, Boolean))
                break;
            // fall through
        case "HB.PageInserted":
            this.embed();
            break;

        case "GM_AutoPagerizeLoaded":
            this.doc.addEventListener("DOMNodeInserted", this, false);
            break;
        }
    }
});

function tryToEmbedIcons(event) {
    if (Prefs.bookmark.get("embed.enabled") &&
        event.target instanceof HTMLDocument)
        new IconEmbedder(event.target);
}

window.addEventListener("load", function IconEmbedder_BEGIN() {
    gBrowser.addEventListener("DOMContentLoaded", tryToEmbedIcons, false);
}, false);
<|endoftext|>


<commit_before>
  var loadingMessages = [];
    loadingMessages["normal_table"] = "table loaded";
    loadingMessages["query_table"] = "query results";
    loadingMessages["filter_table"] = "filter results";
    loadingMessages["tags"] = "table tags updated";
    loadingMessages["name"] = "table name updated";
    loadingMessages["privacy"] = "table privacy updated";
    loadingMessages["update_cell"] = "cell value changed";
    loadingMessages["rename_column"] = "column renamed";
    loadingMessages["update_geometry"] = "geometry updated";
    loadingMessages["column_type"] = "column type changed";
    loadingMessages["new_column"] = "column added";
    loadingMessages["georeference_address"] = "address column geocoded";
    loadingMessages["delete_column"] = "column deleted";
    loadingMessages["delete_row"] = "row deleted";
    loadingMessages["add_row"] = "row added";
    loadingMessages["change_latlng"] = "position updated";
    loadingMessages["adding"] = "row added";
    loadingMessages["remove_point"] = "point removed";
    loadingMessages["remove_points"] = "points removed";
<commit_msg>new loading messages for the table<commit_after>
  var loadingMessages = [];
    loadingMessages["normal_table"] = "records loaded";
    loadingMessages["query_table"] = "query results";
    loadingMessages["filter_table"] = "records filtered";
    loadingMessages["tags"] = "table tags updated";
    loadingMessages["name"] = "table name updated";
    loadingMessages["privacy"] = "table privacy updated";
    loadingMessages["update_cell"] = "cell value changed";
    loadingMessages["rename_column"] = "column renamed";
    loadingMessages["update_geometry"] = "geometry updated";
    loadingMessages["column_type"] = "column type changed";
    loadingMessages["new_column"] = "column added";
    loadingMessages["georeference_address"] = "address column geocoded";
    loadingMessages["delete_column"] = "column deleted";
    loadingMessages["delete_row"] = "row deleted";
    loadingMessages["add_row"] = "row added";
    loadingMessages["change_latlng"] = "position updated";
    loadingMessages["adding"] = "row added";
    loadingMessages["remove_point"] = "point removed";
    loadingMessages["remove_points"] = "points removed";
<|endoftext|>


<commit_before>import React from 'react';
import Reflux from 'reflux';
import _ from 'lodash';

import { DialogMixin, FormMixin } from '../../mixins';

import HostingDialogStore from './HostingDialogStore';
import HostingStore from './HostingStore';
import HostingActions from './HostingActions';
import SessionStore from '../Session/SessionStore';

import { TextField, Toggle } from 'material-ui';
import { Dialog, Show, Notification } from '../../common';

const CreateHostingDialog = React.createClass({
  mixins: [
    Reflux.connect(HostingDialogStore),
    DialogMixin,
    FormMixin
  ],

  validatorConstraints: {
    name: {
      presence: true
    },
    description: {
      length: {
        maximum: 256
      }
    }
  },

  getHostingParams() {
    const { description, domains = [], id, is_default, name } = this.state;

    return { name, description, id, is_default, domains };
  },

  getStyles() {
    return {
      contentSection: {
        margin: '0 0 20px'
      },
      toggle: {
        maxWidth: 400,
        margin: '10px 0'
      },
      nameStyle: {
        lineHeight: 1.4,
        color: 'rgba(68, 68, 68, .8)'
      },
      defaultExplanation: {
        margin: '30px 0 10px'
      }
    };
  },

  handleAddSubmit() {
    const { description, domains = [], is_default, name, cname } = this.state;
    const hostingCount = HostingStore.data.items.length;
    const params = { description, domains, is_default, name };

    cname && params.domains.push(cname);

    if (!hostingCount) {
      params.is_default = true;
    }

    HostingActions.createHosting(params);
  },

  handleEditSubmit() {
    const params = this.getHostingParams();
    const { cnameIndex, cname = params.domains[cnameIndex] } = this.state;
    const pristineCname = cname && cnameIndex < 0;
    const updateCname = cname && cnameIndex > -1;
    const removeCname = !cname && cnameIndex > -1;

    if (pristineCname) {
      params.domains.push(cname);
    }

    if (updateCname) {
      params.domains[cnameIndex] = cname;
    }

    if (removeCname) {
      _.remove(params.domains, (value, index) => index === cnameIndex);
    }

    HostingActions.updateHosting(params.id, params);
  },

  handleChangeName(event, value) {
    this.setState({ name: value });
  },

  handleCNAMEChange(event, value) {
    this.setState({ cname: value });
  },

  handleChangeDescription(event, value) {
    this.setState({ description: value });
  },

  handleDefaultDomain() {
    const { is_default } = this.state;

    this.setState({ is_default: !is_default });
  },

  render() {
    const { is_default, isLoading, open, name, description, canSubmit, domains = [], cnameIndex, cname } = this.state;
    const title = this.hasEditMode() ? 'Edit Hosting' : 'Add Hosting';
    const currentInstance = SessionStore.getInstance();
    const currentInstanceName = currentInstance && currentInstance.name;
    const defaultLink = `https://${currentInstanceName}.syncano.site`;
    const nameLink = `https://${name}--${currentInstanceName}.syncano.site`;
    const styles = this.getStyles();

    return (
      <Dialog.FullPage
        key="dialog"
        ref="dialog"
        title={title}
        onRequestClose={this.handleCancel}
        open={open}
        isLoading={isLoading}
        actions={
          <Dialog.StandardButtons
            disabled={!canSubmit}
            handleCancel={this.handleCancel}
            handleConfirm={this.handleFormValidation}
            data-e2e-submit="hosting-dialog-submit-button"
          />
        }
        sidebar={
          <Dialog.SidebarBox>
            <Dialog.SidebarSection>
              Hosting allows you to manage, deploy and publish websites using Syncano Platform.
            </Dialog.SidebarSection>
            <Dialog.SidebarSection title="Hosting name">
              {"Hosting's name in Syncano Dashboard. It is also used as a domain in your hosting."}
            </Dialog.SidebarSection>
            <Dialog.SidebarSection title="CNAME">
              Thanks to CNAME you can add an additional alias to your hosting. CNAME makes it available to publish
              your website to several domains
              The domains will be linked to your hosting at
              https://CNAME--{currentInstanceName}.syncano.site
            </Dialog.SidebarSection>
            <Show if={this.hasEditMode()}>
              <Dialog.SidebarSection title="Default hosting">
                You can also toogle on Default hosting  then it will be connected directly to your current
                Instance and avaliable at {defaultLink}
              </Dialog.SidebarSection>
            </Show>
            <Dialog.SidebarSection last={true}>
              <Dialog.SidebarLink to="http://docs.syncano.io/v1.1/docs/hosting/">
                Learn more
              </Dialog.SidebarLink>
            </Dialog.SidebarSection>
          </Dialog.SidebarBox>
        }
      >

          <TextField
            autoFocus={true}
            fullWidth={true}
            value={name}
            name="name"
            onChange={this.handleChangeName}
            errorText={this.getValidationMessages('name').join(' ')}
            hintText="Hosting's name"
            floatingLabelText="Name"
            disabled={this.hasEditMode()}
            data-e2e="hosting-dialog-name-input"
          />
          <TextField
            fullWidth={true}
            value={description}
            name="description"
            onChange={this.handleChangeDescription}
            errorText={this.getValidationMessages('description').join(' ')}
            hintText="Hosting's description"
            floatingLabelText="Description"
            data-e2e="hosting-dialog-description-input"
            style={styles.contentSection}
          />
          <Show if={this.hasEditMode()}>
            <Dialog.ContentSection
              title="Default Hosting"
              style={styles.contentSection}
            >

                <Notification hasCloseButtonVisible={false}>
                  {'Default hosting is available at '}

                    {`${defaultLink}.`}

                  {'Each instance can have one default hosting. '}
                  {'Setting this as a default will not affect '}

                    {`${nameLink}.`}

                </Notification>

              <Toggle
                label="Set as default hosting"
                style={styles.toggle}
                toggled={is_default}
                onToggle={this.handleDefaultDomain}
              />
            </Dialog.ContentSection>
          </Show>
          <TextField
            fullWidth={true}
            defaultValue={domains[cnameIndex]}
            value={cname}
            name="CNAME"
            onChange={this.handleCNAMEChange}
            hintText="Hosting's CNAME"
            floatingLabelText="CNAME"
            data-e2e="hosting-dialog-cname-input"
          />

          {this.renderFormNotifications()}
          <Show if={this.getValidationMessages('domains').length}>
            <Notification type="error">
              {this.getValidationMessages('domains').join(' ')}
            </Notification>
          </Show>
          <Show if={this.getValidationMessages('detail').length}>
            <Notification type="error">
              {this.getValidationMessages('detail').join(' ')}
            </Notification>
          </Show>

      </Dialog.FullPage>
    );
  }
});

export default CreateHostingDialog;
<commit_msg>[DASH-2382] Improvements in the hosting dialog sidebar text<commit_after>import React from 'react';
import Reflux from 'reflux';
import _ from 'lodash';

import { DialogMixin, FormMixin } from '../../mixins';

import HostingDialogStore from './HostingDialogStore';
import HostingStore from './HostingStore';
import HostingActions from './HostingActions';
import SessionStore from '../Session/SessionStore';

import { TextField, Toggle } from 'material-ui';
import { Dialog, Show, Notification } from '../../common';

const CreateHostingDialog = React.createClass({
  mixins: [
    Reflux.connect(HostingDialogStore),
    DialogMixin,
    FormMixin
  ],

  validatorConstraints: {
    name: {
      presence: true
    },
    description: {
      length: {
        maximum: 256
      }
    }
  },

  getHostingParams() {
    const { description, domains = [], id, is_default, name } = this.state;

    return { name, description, id, is_default, domains };
  },

  getStyles() {
    return {
      contentSection: {
        margin: '0 0 20px'
      },
      toggle: {
        maxWidth: 400,
        margin: '10px 0'
      },
      nameStyle: {
        lineHeight: 1.4,
        color: 'rgba(68, 68, 68, .8)'
      },
      defaultExplanation: {
        margin: '30px 0 10px'
      }
    };
  },

  handleAddSubmit() {
    const { description, domains = [], is_default, name, cname } = this.state;
    const hostingCount = HostingStore.data.items.length;
    const params = { description, domains, is_default, name };

    cname && params.domains.push(cname);

    if (!hostingCount) {
      params.is_default = true;
    }

    HostingActions.createHosting(params);
  },

  handleEditSubmit() {
    const params = this.getHostingParams();
    const { cnameIndex, cname = params.domains[cnameIndex] } = this.state;
    const pristineCname = cname && cnameIndex < 0;
    const updateCname = cname && cnameIndex > -1;
    const removeCname = !cname && cnameIndex > -1;

    if (pristineCname) {
      params.domains.push(cname);
    }

    if (updateCname) {
      params.domains[cnameIndex] = cname;
    }

    if (removeCname) {
      _.remove(params.domains, (value, index) => index === cnameIndex);
    }

    HostingActions.updateHosting(params.id, params);
  },

  handleChangeName(event, value) {
    this.setState({ name: value });
  },

  handleCNAMEChange(event, value) {
    this.setState({ cname: value });
  },

  handleChangeDescription(event, value) {
    this.setState({ description: value });
  },

  handleDefaultDomain() {
    const { is_default } = this.state;

    this.setState({ is_default: !is_default });
  },

  render() {
    const { is_default, isLoading, open, name, description, canSubmit, domains = [], cnameIndex, cname } = this.state;
    const title = this.hasEditMode() ? 'Edit Hosting' : 'Add Hosting';
    const currentInstance = SessionStore.getInstance();
    const currentInstanceName = currentInstance && currentInstance.name;
    const defaultLink = `https://${currentInstanceName}.syncano.site`;
    const nameLink = `https://${name}--${currentInstanceName}.syncano.site`;
    const styles = this.getStyles();

    return (
      <Dialog.FullPage
        key="dialog"
        ref="dialog"
        title={title}
        onRequestClose={this.handleCancel}
        open={open}
        isLoading={isLoading}
        actions={
          <Dialog.StandardButtons
            disabled={!canSubmit}
            handleCancel={this.handleCancel}
            handleConfirm={this.handleFormValidation}
            data-e2e-submit="hosting-dialog-submit-button"
          />
        }
        sidebar={
          <Dialog.SidebarBox>
            <Dialog.SidebarSection>
              Hosting allows you to manage, deploy and publish websites using Syncano Platform.
            </Dialog.SidebarSection>
            <Dialog.SidebarSection title="Hosting name">
              {"Hosting's name in Syncano Dashboard. It is also used to construct your hosting domain url."}
            </Dialog.SidebarSection>
            <Show if={this.hasEditMode()}>
              <Dialog.SidebarSection title="Default hosting">
                Enabling the default hosting will set this hosting's domain url to be also available
                at {defaultLink}
              </Dialog.SidebarSection>
            </Show>
            <Dialog.SidebarSection title="CNAME">
              If your domain name is, for example, my-domain.com then type it in the CNAME field. Next,
              go to your domain name provider website and set the CNAME to point at {nameLink}
            </Dialog.SidebarSection>
            <Dialog.SidebarSection last={true}>
              <Dialog.SidebarLink to="http://docs.syncano.io/v1.1/docs/hosting/">
                Learn more
              </Dialog.SidebarLink>
            </Dialog.SidebarSection>
          </Dialog.SidebarBox>
        }
      >

          <TextField
            autoFocus={true}
            fullWidth={true}
            value={name}
            name="name"
            onChange={this.handleChangeName}
            errorText={this.getValidationMessages('name').join(' ')}
            hintText="Hosting's name"
            floatingLabelText="Name"
            disabled={this.hasEditMode()}
            data-e2e="hosting-dialog-name-input"
          />
          <TextField
            fullWidth={true}
            value={description}
            name="description"
            onChange={this.handleChangeDescription}
            errorText={this.getValidationMessages('description').join(' ')}
            hintText="Hosting's description"
            floatingLabelText="Description"
            data-e2e="hosting-dialog-description-input"
            style={styles.contentSection}
          />
          <Show if={this.hasEditMode()}>
            <Dialog.ContentSection
              title="Default Hosting"
              style={styles.contentSection}
            >

                <Notification hasCloseButtonVisible={false}>
                  {'Default hosting is available at '}

                    {`${defaultLink}.`}

                  {'Each instance can have one default hosting. '}
                  {'Setting this as a default will not affect '}

                    {`${nameLink}.`}

                </Notification>

              <Toggle
                label="Set as default hosting"
                style={styles.toggle}
                toggled={is_default}
                onToggle={this.handleDefaultDomain}
              />
            </Dialog.ContentSection>
          </Show>
          <TextField
            fullWidth={true}
            defaultValue={domains[cnameIndex]}
            value={cname}
            name="CNAME"
            onChange={this.handleCNAMEChange}
            hintText="Hosting's CNAME"
            floatingLabelText="CNAME"
            data-e2e="hosting-dialog-cname-input"
          />

          {this.renderFormNotifications()}
          <Show if={this.getValidationMessages('domains').length}>
            <Notification type="error">
              {this.getValidationMessages('domains').join(' ')}
            </Notification>
          </Show>
          <Show if={this.getValidationMessages('detail').length}>
            <Notification type="error">
              {this.getValidationMessages('detail').join(' ')}
            </Notification>
          </Show>

      </Dialog.FullPage>
    );
  }
});

export default CreateHostingDialog;
<|endoftext|>


<commit_before>// Workaround because mixpanel.cjs.js doesn't pass flow-checks
export Mixpanel from 'mixpanel-browser/build/mixpanel.cjs.js'
<commit_msg>Fix exporting of mixpanel module<commit_after>// Workaround because mixpanel.cjs.js doesn't pass flow-checks
import Mixpanel from 'mixpanel-browser/build/mixpanel.cjs.js'
export default Mixpanel
<|endoftext|>


<commit_before>define([
  'angular',
  'lodash',
  './helperFunctions'
],
function (angular, _) {
  'use strict';

  var module = angular.module('grafana.controllers');
  var targetLetters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';

  module.controller('ZabbixAPIQueryCtrl', function($scope, $sce, templateSrv, zabbixHelperSrv) {

    $scope.init = function() {
      $scope.targetLetters = targetLetters;
      if ($scope.target.ITService) {
        $scope.slaPropertyList = [
          {name: "SLA", property: "sla"},
          {name: "OK time", property: "okTime"},
          {name: "Problem time", property: "problemTime"},
          {name: "Down time", property: "downtimeTime"}
        ];
        $scope.itserviceList = [{name: "test"}];
        $scope.updateITServiceList();
      } else {
        $scope.metric = {
          hostGroupList: [],
          hostList: [{name: '*', visible_name: 'All'}],
          applicationList: [{name: '*', visible_name: 'All'}],
          itemList: [{name: 'All'}]
        };

        // Update host group, host, application and item lists
        $scope.updateGroupList();
        $scope.updateHostList();
        $scope.updateAppList();
        $scope.updateItemList();

        setItemAlias();
      }

      $scope.target.errors = validateTarget($scope.target);
    };

    $scope.switchEditorMode = function() {
      $scope.target.ITService = !$scope.target.ITService;
      $scope.init();
    };

    /**
     * Take alias from item name by default
     */
    function setItemAlias() {
      if (!$scope.target.alias && $scope.target.item) {
        $scope.target.alias = $scope.target.item.name;
      }
    }

    $scope.targetBlur = function() {
      setItemAlias();
      $scope.target.errors = validateTarget($scope.target);
      if (!_.isEqual($scope.oldTarget, $scope.target) && _.isEmpty($scope.target.errors)) {
        $scope.oldTarget = angular.copy($scope.target);
        $scope.get_data();
      }
    };

    /**
     * Call when IT service is selected.
     */
    $scope.selectITService = function() {
      $scope.target.errors = validateTarget($scope.target);
      if (!_.isEqual($scope.oldTarget, $scope.target) && _.isEmpty($scope.target.errors)) {
        $scope.oldTarget = angular.copy($scope.target);
        $scope.get_data();
      }
    };

    /**
     * Call when host group selected
     */
    $scope.selectHostGroup = function() {
      $scope.updateHostList();
      $scope.updateAppList();
      $scope.updateItemList();

      $scope.target.errors = validateTarget($scope.target);
      if (!_.isEqual($scope.oldTarget, $scope.target) && _.isEmpty($scope.target.errors)) {
        $scope.oldTarget = angular.copy($scope.target);
        $scope.get_data();
      }
    };

    /**
     * Call when host selected
     */
    $scope.selectHost = function() {
      $scope.updateAppList();
      $scope.updateItemList();

      $scope.target.errors = validateTarget($scope.target);
      if (!_.isEqual($scope.oldTarget, $scope.target) && _.isEmpty($scope.target.errors)) {
        $scope.oldTarget = angular.copy($scope.target);
        $scope.get_data();
      }
    };

    /**
     * Call when application selected
     */
    $scope.selectApplication = function() {
      $scope.updateItemList();

      $scope.target.errors = validateTarget($scope.target);
      if (!_.isEqual($scope.oldTarget, $scope.target) && _.isEmpty($scope.target.errors)) {
        $scope.oldTarget = angular.copy($scope.target);
        $scope.get_data();
      }
    };

    /**
     * Call when item selected
     */
    $scope.selectItem = function() {
      setItemAlias();
      $scope.target.errors = validateTarget($scope.target);
      if (!_.isEqual($scope.oldTarget, $scope.target) && _.isEmpty($scope.target.errors)) {
        $scope.oldTarget = angular.copy($scope.target);
        $scope.get_data();
      }
    };

    $scope.duplicate = function() {
      var clone = angular.copy($scope.target);
      $scope.panel.targets.push(clone);
    };

    $scope.moveMetricQuery = function(fromIndex, toIndex) {
      _.move($scope.panel.targets, fromIndex, toIndex);
    };

    //////////////////////////////
    // SUGGESTION QUERIES
    //////////////////////////////

    /**
     * Update list of IT services
     */
    $scope.updateITServiceList = function() {
      $scope.datasource.zabbixAPI.getITService().then(function (iteservices) {
        $scope.itserviceList = [];
        $scope.itserviceList = $scope.itserviceList.concat(iteservices);
      });
    };

    /**
     * Update list of host groups
     */
    $scope.updateGroupList = function() {
      $scope.datasource.zabbixAPI.performHostGroupSuggestQuery().then(function (groups) {
        $scope.metric.groupList = [{name: '*', visible_name: 'All'}];
        addTemplatedVariables($scope.metric.groupList);
        $scope.metric.groupList = $scope.metric.groupList.concat(groups);
      });
    };

    /**
     * Update list of hosts
     */
    $scope.updateHostList = function() {
      var groups = $scope.target.group ? zabbixHelperSrv.splitMetrics(templateSrv.replace($scope.target.group.name)) : undefined;
      if (groups) {
        $scope.datasource.zabbixAPI.hostFindQuery(groups).then(function (hosts) {
          $scope.metric.hostList = [{name: '*', visible_name: 'All'}];
          addTemplatedVariables($scope.metric.hostList);
          $scope.metric.hostList = $scope.metric.hostList.concat(hosts);
        });
      }
    };

    /**
     * Update list of host applications
     */
    $scope.updateAppList = function() {
      var groups = $scope.target.group ? zabbixHelperSrv.splitMetrics(templateSrv.replace($scope.target.group.name)) : undefined;
      var hosts = $scope.target.host ? zabbixHelperSrv.splitMetrics(templateSrv.replace($scope.target.host.name)) : undefined;
      if (groups && hosts) {
        $scope.datasource.zabbixAPI.appFindQuery(hosts, groups).then(function (apps) {
          apps = _.map(_.uniq(_.map(apps, 'name')), function (appname) {
            return {name: appname};
          });
          $scope.metric.applicationList = [{name: '*', visible_name: 'All'}];
          addTemplatedVariables($scope.metric.applicationList);
          $scope.metric.applicationList = $scope.metric.applicationList.concat(apps);
        });
      }
    };

    /**
     * Update list of items
     */
    $scope.updateItemList = function() {
      var groups = $scope.target.group ? zabbixHelperSrv.splitMetrics(templateSrv.replace($scope.target.group.name)) : undefined;
      var hosts = $scope.target.host ? zabbixHelperSrv.splitMetrics(templateSrv.replace($scope.target.host.name)) : undefined;
      var apps = $scope.target.application ? zabbixHelperSrv.splitMetrics(templateSrv.replace($scope.target.application.name)) : undefined;
      if (groups && hosts && apps) {
        $scope.datasource.zabbixAPI.itemFindQuery(groups, hosts, apps).then(function (items) {
          // Show only unique item names
          var uniq_items = _.map(_.uniq(items, function (item) {
            return zabbixHelperSrv.expandItemName(item);
          }), function (item) {
            return {name: zabbixHelperSrv.expandItemName(item)};
          });
          $scope.metric.itemList = [{name: 'All'}];
          addTemplatedVariables($scope.metric.itemList);
          $scope.metric.itemList = $scope.metric.itemList.concat(uniq_items);
        });
      }
    };

    /**
     * Add templated variables to list of available metrics
     *
     * @param {Array} metricList List of metrics which variables add to
     */
    function addTemplatedVariables(metricList) {
      _.each(templateSrv.variables, function(variable) {
        metricList.push({
          name: '$' + variable.name,
          templated: true
        });
      });
    }

    //////////////////////////////
    // VALIDATION
    //////////////////////////////

    function validateTarget(target) {
      var errs = {};
      if (!target) {
        errs = 'Not defined';
      }
      return errs;
    }

  });

});
<commit_msg>Refactoring - reformat code.<commit_after>define([
    'angular',
    'lodash',
    './helperFunctions'
  ],
  function (angular, _) {
    'use strict';

    var module = angular.module('grafana.controllers');
    var targetLetters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';

    module.controller('ZabbixAPIQueryCtrl', function ($scope, $sce, templateSrv, zabbixHelperSrv) {

      $scope.init = function () {
        $scope.targetLetters = targetLetters;
        if ($scope.target.ITService) {
          $scope.slaPropertyList = [
            {name: "SLA", property: "sla"},
            {name: "OK time", property: "okTime"},
            {name: "Problem time", property: "problemTime"},
            {name: "Down time", property: "downtimeTime"}
          ];
          $scope.itserviceList = [{name: "test"}];
          $scope.updateITServiceList();
        } else {
          $scope.metric = {
            hostGroupList: [],
            hostList: [{name: '*', visible_name: 'All'}],
            applicationList: [{name: '*', visible_name: 'All'}],
            itemList: [{name: 'All'}]
          };

          // Update host group, host, application and item lists
          $scope.updateGroupList();
          $scope.updateHostList();
          $scope.updateAppList();
          $scope.updateItemList();

          setItemAlias();
        }

        $scope.target.errors = validateTarget($scope.target);
      };

      $scope.switchEditorMode = function () {
        $scope.target.ITService = !$scope.target.ITService;
        $scope.init();
      };

      /**
       * Take alias from item name by default
       */
      function setItemAlias() {
        if (!$scope.target.alias && $scope.target.item) {
          $scope.target.alias = $scope.target.item.name;
        }
      }

      $scope.targetBlur = function () {
        setItemAlias();
        $scope.target.errors = validateTarget($scope.target);
        if (!_.isEqual($scope.oldTarget, $scope.target) && _.isEmpty($scope.target.errors)) {
          $scope.oldTarget = angular.copy($scope.target);
          $scope.get_data();
        }
      };

      /**
       * Call when IT service is selected.
       */
      $scope.selectITService = function () {
        $scope.target.errors = validateTarget($scope.target);
        if (!_.isEqual($scope.oldTarget, $scope.target) && _.isEmpty($scope.target.errors)) {
          $scope.oldTarget = angular.copy($scope.target);
          $scope.get_data();
        }
      };

      /**
       * Call when host group selected
       */
      $scope.selectHostGroup = function () {
        $scope.updateHostList();
        $scope.updateAppList();
        $scope.updateItemList();

        $scope.target.errors = validateTarget($scope.target);
        if (!_.isEqual($scope.oldTarget, $scope.target) && _.isEmpty($scope.target.errors)) {
          $scope.oldTarget = angular.copy($scope.target);
          $scope.get_data();
        }
      };

      /**
       * Call when host selected
       */
      $scope.selectHost = function () {
        $scope.updateAppList();
        $scope.updateItemList();

        $scope.target.errors = validateTarget($scope.target);
        if (!_.isEqual($scope.oldTarget, $scope.target) && _.isEmpty($scope.target.errors)) {
          $scope.oldTarget = angular.copy($scope.target);
          $scope.get_data();
        }
      };

      /**
       * Call when application selected
       */
      $scope.selectApplication = function () {
        $scope.updateItemList();

        $scope.target.errors = validateTarget($scope.target);
        if (!_.isEqual($scope.oldTarget, $scope.target) && _.isEmpty($scope.target.errors)) {
          $scope.oldTarget = angular.copy($scope.target);
          $scope.get_data();
        }
      };

      /**
       * Call when item selected
       */
      $scope.selectItem = function () {
        setItemAlias();
        $scope.target.errors = validateTarget($scope.target);
        if (!_.isEqual($scope.oldTarget, $scope.target) && _.isEmpty($scope.target.errors)) {
          $scope.oldTarget = angular.copy($scope.target);
          $scope.get_data();
        }
      };

      $scope.duplicate = function () {
        var clone = angular.copy($scope.target);
        $scope.panel.targets.push(clone);
      };

      $scope.moveMetricQuery = function (fromIndex, toIndex) {
        _.move($scope.panel.targets, fromIndex, toIndex);
      };

      //////////////////////////////
      // SUGGESTION QUERIES
      //////////////////////////////

      /**
       * Update list of IT services
       */
      $scope.updateITServiceList = function () {
        $scope.datasource.zabbixAPI.getITService().then(function (iteservices) {
          $scope.itserviceList = [];
          $scope.itserviceList = $scope.itserviceList.concat(iteservices);
        });
      };

      /**
       * Update list of host groups
       */
      $scope.updateGroupList = function () {
        $scope.datasource.zabbixAPI.performHostGroupSuggestQuery().then(function (groups) {
          $scope.metric.groupList = [{name: '*', visible_name: 'All'}];
          addTemplatedVariables($scope.metric.groupList);
          $scope.metric.groupList = $scope.metric.groupList.concat(groups);
        });
      };

      /**
       * Update list of hosts
       */
      $scope.updateHostList = function () {
        var groups = $scope.target.group ? zabbixHelperSrv.splitMetrics(templateSrv.replace($scope.target.group.name)) : undefined;
        if (groups) {
          $scope.datasource.zabbixAPI.hostFindQuery(groups).then(function (hosts) {
            $scope.metric.hostList = [{name: '*', visible_name: 'All'}];
            addTemplatedVariables($scope.metric.hostList);
            $scope.metric.hostList = $scope.metric.hostList.concat(hosts);
          });
        }
      };

      /**
       * Update list of host applications
       */
      $scope.updateAppList = function () {
        var groups = $scope.target.group ? zabbixHelperSrv.splitMetrics(templateSrv.replace($scope.target.group.name)) : undefined;
        var hosts = $scope.target.host ? zabbixHelperSrv.splitMetrics(templateSrv.replace($scope.target.host.name)) : undefined;
        if (groups && hosts) {
          $scope.datasource.zabbixAPI.appFindQuery(hosts, groups).then(function (apps) {
            apps = _.map(_.uniq(_.map(apps, 'name')), function (appname) {
              return {name: appname};
            });
            $scope.metric.applicationList = [{name: '*', visible_name: 'All'}];
            addTemplatedVariables($scope.metric.applicationList);
            $scope.metric.applicationList = $scope.metric.applicationList.concat(apps);
          });
        }
      };

      /**
       * Update list of items
       */
      $scope.updateItemList = function () {
        var groups = $scope.target.group ? zabbixHelperSrv.splitMetrics(templateSrv.replace($scope.target.group.name)) : undefined;
        var hosts = $scope.target.host ? zabbixHelperSrv.splitMetrics(templateSrv.replace($scope.target.host.name)) : undefined;
        var apps = $scope.target.application ? zabbixHelperSrv.splitMetrics(templateSrv.replace($scope.target.application.name)) : undefined;
        if (groups && hosts && apps) {
          $scope.datasource.zabbixAPI.itemFindQuery(groups, hosts, apps).then(function (items) {
            // Show only unique item names
            var uniq_items = _.map(_.uniq(items, function (item) {
              return zabbixHelperSrv.expandItemName(item);
            }), function (item) {
              return {name: zabbixHelperSrv.expandItemName(item)};
            });
            $scope.metric.itemList = [{name: 'All'}];
            addTemplatedVariables($scope.metric.itemList);
            $scope.metric.itemList = $scope.metric.itemList.concat(uniq_items);
          });
        }
      };

      /**
       * Add templated variables to list of available metrics
       *
       * @param {Array} metricList List of metrics which variables add to
       */
      function addTemplatedVariables(metricList) {
        _.each(templateSrv.variables, function (variable) {
          metricList.push({
            name: '$' + variable.name,
            templated: true
          });
        });
      }

      //////////////////////////////
      // VALIDATION
      //////////////////////////////

      function validateTarget(target) {
        var errs = {};
        if (!target) {
          errs = 'Not defined';
        }
        return errs;
      }

    });

  });
<|endoftext|>


<commit_before>angular.module('app.frontend')
  .config(function ($stateProvider, $urlRouterProvider, $locationProvider) {

    $stateProvider
      .state('base', {
        abstract: true,
      })

      .state('home', {
        url: '/',
        parent: 'base',
        views: {
          'content@' : {
            templateUrl: 'frontend/home.html',
            controller: 'HomeCtrl'
          }
        }
      })

      // Default fall back route
      $urlRouterProvider.otherwise(function($injector, $location){
         var state = $injector.get('$state');
         state.go('home');
         return $location.path();
      });

      var runningInElectron = process.versions['electron'];
      if(!runningInElectron) {
        console.log("Enabling HTML5 Mode.")
        if (window.history && window.history.pushState) {
          $locationProvider.html5Mode({
            enabled: true,
            requireBase: false
          });
        }
      } else {
        $locationProvider.html5Mode(false);
        console.log("Disabling HTML5 Mode.")
      }

  });
<commit_msg>fix electron check<commit_after>angular.module('app.frontend')
  .config(function ($stateProvider, $urlRouterProvider, $locationProvider) {

    $stateProvider
      .state('base', {
        abstract: true,
      })

      .state('home', {
        url: '/',
        parent: 'base',
        views: {
          'content@' : {
            templateUrl: 'frontend/home.html',
            controller: 'HomeCtrl'
          }
        }
      })

      // Default fall back route
      $urlRouterProvider.otherwise(function($injector, $location){
         var state = $injector.get('$state');
         state.go('home');
         return $location.path();
      });

      var runningInElectron = window && window.process && window.process.type && window.process.versions["electron"];
      if(!runningInElectron) {
        console.log("Enabling HTML5 Mode.")
        if (window.history && window.history.pushState) {
          $locationProvider.html5Mode({
            enabled: true,
            requireBase: false
          });
        }
      } else {
        $locationProvider.html5Mode(false);
        console.log("Disabling HTML5 Mode.")
      }

  });
<|endoftext|>


<commit_before>/**
 * @fileOverview Default animation configuration for geoms
 * @author sima.zhang
 */
const Util = require('../util');
const Action = require('./action');

const defaultAnimationCfg = {
  appear: {
    duration: 450,
    easing: 'easeQuadOut'
  }, // 初始入场动画配置
  update: {
    duration: 450,
    easing: 'easeQuadInOut'
  }, // 更新时发生变更的动画配置
  enter: {
    duration: 400,
    easing: 'easeQuadInOut',
    delay: 100
  }, // 更新时新增元素的入场动画配置
  leave: {
    duration: 350,
    easing: 'easeQuadIn'
  } // 更新时销毁动画配置
};

const Animate = {
  line: {
    appear() {
      return Action.appear.clipIn;
    },
    enter() {
      return Action.enter.clipIn;
    },
    leave() {
      return Action.leave.lineWidthOut;
    }
  },
  path: {
    appear() {
      return Action.appear.clipIn;
    },
    enter() {
      return Action.enter.clipIn;
    },
    leave() {
      return Action.leave.lineWidthOut;
    }
  },
  area: {
    appear() {
      return Action.appear.clipIn;
    },
    enter() {
      return Action.enter.fadeIn;
    },
    leave() {
      return Action.leave.fadeOut;
    },
    cfg: {
      appear: {
        duration: 500,
        easing: 'easeQuadInOut'
      },
      update: {
        duration: 450,
        easing: 'easeQuadInOut'
      },
      enter: {
        duration: 600,
        delay: 150,
        easing: 'easeQuadInOut'
      },
      leave: {
        easing: 'easeQuadOut',
        duration: 350
      }
    }
  },
  polygon: {
    appear() {
      return Action.appear.zoomIn;
    },
    enter() {
      return Action.enter.zoomIn;
    },
    leave() {
      return Action.leave.zoomOut;
    }
  },
  edge: {
    appear() {
      return Action.appear.pathIn;
    },
    enter() {
      return Action.enter.pathIn;
    },
    leave() {
      return Action.leave.pathOut;
    }
  },
  interval: {
    appear(coord) {
      let result;
      if (coord.isPolar) {
        result = Action.appear.zoomIn;
        if (coord.isTransposed || coord.type === 'theta') {
          result = Action.appear.fanIn;
        }
      } else if (coord.isRect) {
        result = coord.isTransposed ? Action.appear.scaleInX : Action.appear.scaleInY;
      } else {
        result = Action.appear.zoomIn;
      }
      return result;
    },
    enter(coord) {
      if (coord.isRect || coord.isTransposed || coord.type === 'theta') {
        return Action.enter.fadeIn;
      }
      return Action.enter.zoomIn;
    },
    leave() {
      return Action.leave.fadeOut;
    },
    update(coord) {
      if (coord.type === 'theta') {
        return Action.update.fanIn;
      }
    }
  },
  point: {
    appear() {
      return Action.appear.zoomIn;
    },
    enter() {
      return Action.enter.zoomIn;
    },
    leave() {
      return Action.leave.zoomOut;
    }
  },
  schema: {
    appear() {
      return Action.appear.clipIn;
    },
    enter() {
      return Action.enter.clipIn;
    },
    leave() {
      return Action.leave.lineWidthOut;
    }
  },
  contour: null,
  heatmap: null,
  label: {
    appear() {
      return Action.appear.fadeIn;
    },
    enter() {
      return Action.enter.fadeIn;
    },
    leave() {
      return Action.leave.fadeOut;
    },
    cfg: {
      appear: {
        duration: 900
      }
    }
  },
  'axis-label': {
    enter() {
      return Action.appear.fadeIn;
    },
    leave() {
      return Action.leave.fadeOut;
    },
    update(coord) {
      if (coord.isPolar) {
        return Action.appear.fadeIn;
      }
    }
  },
  'axis-ticks': {
    enter() {
      return Action.appear.fadeIn;
    },
    leave() {
      return Action.leave.fadeOut;
    },
    update(coord) {
      if (coord.isPolar) {
        return Action.appear.fadeIn;
      }
    }
  },
  'axis-grid': {
    enter() {
      return Action.appear.fadeIn;
    },
    leave() {
      return Action.leave.fadeOut;
    },
    update(coord) {
      if (coord.isPolar) {
        return Action.appear.fadeIn;
      }
    }
  },
  'axis-grid-rect': {
    enter() {
      return Action.appear.fadeIn;
    },
    leave() {
      return Action.leave.fadeOut;
    },
    update() {
      return Action.leave.fadeIn;
    }
  },
  labelLine: {
    appear() {
      return Action.appear.pathIn;
    },
    enter() {
      return Action.enter.pathIn;
    },
    leave() {
      return Action.leave.pathOut;
    }
  }
};

Animate.Action = Action;
Animate.defaultCfg = defaultAnimationCfg;

// 获取动画
Animate.getAnimation = function(geomType, coord, animationType) {
  const geomAnimateCfg = this[geomType];
  if (geomAnimateCfg) {
    const animation = geomAnimateCfg[animationType];
    if (Util.isFunction(animation)) {
      return animation(coord);
    }
  }
  return false;
};

// 获取动画配置
Animate.getAnimateCfg = function(geomType, animationType) {
  const defaultCfg = defaultAnimationCfg[animationType];
  if (this[geomType] && this[geomType].cfg && this[geomType].cfg[animationType]) {
    return Util.deepMix({}, defaultCfg, this[geomType].cfg[animationType]);
  }
  return defaultCfg;
};

// 注册动画
Animate.registerAnimation = function(animationType, animationName, animationFun) {
  if (!this.Action[animationType]) {
    this.Action[animationType] = {};
  }
  this.Action[animationType][animationName] = animationFun;
};

module.exports = Animate;
<commit_msg>fix: 统一 area 入场动画的缓动函数。<commit_after>/**
 * @fileOverview Default animation configuration for geoms
 * @author sima.zhang
 */
const Util = require('../util');
const Action = require('./action');

const defaultAnimationCfg = {
  appear: {
    duration: 450,
    easing: 'easeQuadOut'
  }, // 初始入场动画配置
  update: {
    duration: 450,
    easing: 'easeQuadInOut'
  }, // 更新时发生变更的动画配置
  enter: {
    duration: 400,
    easing: 'easeQuadInOut',
    delay: 100
  }, // 更新时新增元素的入场动画配置
  leave: {
    duration: 350,
    easing: 'easeQuadIn'
  } // 更新时销毁动画配置
};

const Animate = {
  line: {
    appear() {
      return Action.appear.clipIn;
    },
    enter() {
      return Action.enter.clipIn;
    },
    leave() {
      return Action.leave.lineWidthOut;
    }
  },
  path: {
    appear() {
      return Action.appear.clipIn;
    },
    enter() {
      return Action.enter.clipIn;
    },
    leave() {
      return Action.leave.lineWidthOut;
    }
  },
  area: {
    appear() {
      return Action.appear.clipIn;
    },
    enter() {
      return Action.enter.fadeIn;
    },
    leave() {
      return Action.leave.fadeOut;
    },
    cfg: {
      appear: {
        duration: 500,
        easing: 'easeQuadOut'
      },
      update: {
        duration: 450,
        easing: 'easeQuadInOut'
      },
      enter: {
        duration: 600,
        delay: 150,
        easing: 'easeQuadInOut'
      },
      leave: {
        easing: 'easeQuadOut',
        duration: 350
      }
    }
  },
  polygon: {
    appear() {
      return Action.appear.zoomIn;
    },
    enter() {
      return Action.enter.zoomIn;
    },
    leave() {
      return Action.leave.zoomOut;
    }
  },
  edge: {
    appear() {
      return Action.appear.pathIn;
    },
    enter() {
      return Action.enter.pathIn;
    },
    leave() {
      return Action.leave.pathOut;
    }
  },
  interval: {
    appear(coord) {
      let result;
      if (coord.isPolar) {
        result = Action.appear.zoomIn;
        if (coord.isTransposed || coord.type === 'theta') {
          result = Action.appear.fanIn;
        }
      } else if (coord.isRect) {
        result = coord.isTransposed ? Action.appear.scaleInX : Action.appear.scaleInY;
      } else {
        result = Action.appear.zoomIn;
      }
      return result;
    },
    enter(coord) {
      if (coord.isRect || coord.isTransposed || coord.type === 'theta') {
        return Action.enter.fadeIn;
      }
      return Action.enter.zoomIn;
    },
    leave() {
      return Action.leave.fadeOut;
    },
    update(coord) {
      if (coord.type === 'theta') {
        return Action.update.fanIn;
      }
    }
  },
  point: {
    appear() {
      return Action.appear.zoomIn;
    },
    enter() {
      return Action.enter.zoomIn;
    },
    leave() {
      return Action.leave.zoomOut;
    }
  },
  schema: {
    appear() {
      return Action.appear.clipIn;
    },
    enter() {
      return Action.enter.clipIn;
    },
    leave() {
      return Action.leave.lineWidthOut;
    }
  },
  contour: null,
  heatmap: null,
  label: {
    appear() {
      return Action.appear.fadeIn;
    },
    enter() {
      return Action.enter.fadeIn;
    },
    leave() {
      return Action.leave.fadeOut;
    },
    cfg: {
      appear: {
        duration: 900
      }
    }
  },
  'axis-label': {
    enter() {
      return Action.appear.fadeIn;
    },
    leave() {
      return Action.leave.fadeOut;
    },
    update(coord) {
      if (coord.isPolar) {
        return Action.appear.fadeIn;
      }
    }
  },
  'axis-ticks': {
    enter() {
      return Action.appear.fadeIn;
    },
    leave() {
      return Action.leave.fadeOut;
    },
    update(coord) {
      if (coord.isPolar) {
        return Action.appear.fadeIn;
      }
    }
  },
  'axis-grid': {
    enter() {
      return Action.appear.fadeIn;
    },
    leave() {
      return Action.leave.fadeOut;
    },
    update(coord) {
      if (coord.isPolar) {
        return Action.appear.fadeIn;
      }
    }
  },
  'axis-grid-rect': {
    enter() {
      return Action.appear.fadeIn;
    },
    leave() {
      return Action.leave.fadeOut;
    },
    update() {
      return Action.leave.fadeIn;
    }
  },
  labelLine: {
    appear() {
      return Action.appear.pathIn;
    },
    enter() {
      return Action.enter.pathIn;
    },
    leave() {
      return Action.leave.pathOut;
    }
  }
};

Animate.Action = Action;
Animate.defaultCfg = defaultAnimationCfg;

// 获取动画
Animate.getAnimation = function(geomType, coord, animationType) {
  const geomAnimateCfg = this[geomType];
  if (geomAnimateCfg) {
    const animation = geomAnimateCfg[animationType];
    if (Util.isFunction(animation)) {
      return animation(coord);
    }
  }
  return false;
};

// 获取动画配置
Animate.getAnimateCfg = function(geomType, animationType) {
  const defaultCfg = defaultAnimationCfg[animationType];
  if (this[geomType] && this[geomType].cfg && this[geomType].cfg[animationType]) {
    return Util.deepMix({}, defaultCfg, this[geomType].cfg[animationType]);
  }
  return defaultCfg;
};

// 注册动画
Animate.registerAnimation = function(animationType, animationName, animationFun) {
  if (!this.Action[animationType]) {
    this.Action[animationType] = {};
  }
  this.Action[animationType][animationName] = animationFun;
};

module.exports = Animate;
<|endoftext|>