<commit_before>"use strict";

function getParameterByName(name) {  // http://stackoverflow.com/a/5158301/3694
    const match = new RegExp('[?&]' + name + '=([^&/]*)').exec(window.location.search);
    return match && decodeURIComponent(match[1].replace(/\+/g, ' '));
}

function redrawOptions() {
    const rs = allHelp.AllRepos.sort();
    const sel = document.getElementById("repo");
    while (sel.length > 1) {
        sel.removeChild(sel.lastChild);
    }
    const param = getParameterByName("repo");
    rs.forEach((opt) => {
        const o = document.createElement("option");
        o.text = opt;
        o.selected = (param && opt === param);
        sel.appendChild(o);
    });
}

window.onload = function () {
    // set dropdown based on options from query string
    const hash = window.location.hash;
    redrawOptions();
    redraw();

    // Register dialog
    const dialog = document.querySelector('dialog');
    dialogPolyfill.registerDialog(dialog);
    dialog.querySelector('.close').addEventListener('click', () => {
        dialog.close();
    });

    if (hash !== "") {
        const el = document.body.querySelector(hash);
        const mainContainer = document.body.querySelector(".mdl-layout__content");
        if (el && mainContainer) {
            setTimeout(() => {
                mainContainer.scrollTop = el.getBoundingClientRect().top;
                window.location.hash = hash;
            }, 32);
        }
    }
};

document.addEventListener("DOMContentLoaded", () => {
    configure();
});

function configure() {
    if (!branding) {
        return;
    }
    if (branding.logo) {
        document.getElementById('img').src = branding.logo;
    }
    if (branding.favicon) {
        document.getElementById('favicon').href = branding.favicon;
    }
    if (branding.background_color) {
        document.body.style.background = branding.background_color;
    }
    if (branding.header_color) {
        document.getElementsByTagName('header')[0].style.backgroundColor = branding.header_color;
    }
}

function selectionText(sel) {
    return sel.selectedIndex === 0 ? "" : sel.options[sel.selectedIndex].text;
}

/**
 * Takes an org/repo string and a repo to plugin map and returns the plugins
 * that apply to the repo.
 * @param {string} repoSel repo name
 * @param {Map<string, PluginHelp>} repoPlugins maps plugin name to plugin
 * @return {Array<string>}
 */
function applicablePlugins(repoSel, repoPlugins) {
    if (repoSel === "") {
        const all = repoPlugins[""];
        if (all) {
            return all.sort();
        }
        return [];
    }
    const parts = repoSel.split("/");
    const byOrg = repoPlugins[parts[0]];
    let plugins = [];
    if (byOrg && byOrg !== []) {
        plugins = plugins.concat(byOrg);
    }
    const pluginNames = repoPlugins[repoSel];
    if (pluginNames) {
        pluginNames.forEach((pluginName) => {
            if (!plugins.includes(pluginName)) {
                plugins.push(pluginName);
            }
        });
    }
    return plugins.sort();
}

/**
 * Returns a normal cell for the command row.
 * @param {Array<string>|string} data content of the cell
 * @param {Array<string>} styles a list of styles applied to the cell.
 * @param {boolean} noWrap true if the content of the cell should be wrap.
 * @return {Element}
 */
function createCommandCell(data, styles = [], noWrap = false) {
    const cell = document.createElement("TD");
    cell.classList.add("mdl-data-table__cell--non-numeric");
    if (!noWrap) {
        cell.classList.add("table-cell");
    }
    let content;
    if (Array.isArray((data))) {
        content = document.createElement("UL");
        content.classList = "command-example-list";

        data.forEach((item) => {
            const itemContainer = document.createElement("LI");
            const span = document.createElement("SPAN");
            span.innerHTML = item;
            span.classList.add(...styles);
            itemContainer.appendChild(span);
            content.appendChild(itemContainer);
        });
    } else {
        content = document.createElement("DIV");
        content.classList.add(...styles);
        content.innerHTML = data;
    }

    cell.appendChild(content);

    return cell;
}

/**
 * Returns an icon element.
 * @param {number} no no. command
 * @param {string} iconString icon name
 * @param {?Array<string>} styles list of styles of the icon
 * @param {string} tooltip tooltip string
 * @param {boolean} isButton true if icon is a button
 * @return {Element}
 */
function createIcon(no, iconString, styles = [], tooltip = "", isButton = false) {
    const icon = document.createElement("I");
    icon.id = "icon-" + iconString + "-" + no;
    icon.classList.add("material-icons");
    icon.classList.add(...styles);
    icon.innerHTML = iconString;

    const container = isButton ? document.createElement("BUTTON") : document.createElement("DIV");
    container.appendChild(icon);
    if (isButton) {
        container.classList.add(...["mdl-button", "mdl-js-button", "mdl-button--icon"]);
    }

    if (tooltip === "") {
        return container;
    }

    const tooltipEl = document.createElement("DIV");
    tooltipEl.setAttribute("for", icon.id);
    tooltipEl.classList.add("mdl-tooltip");
    tooltipEl.innerHTML = tooltip;
    container.appendChild(tooltipEl);

    return container;
}

/**
 * Returns the feature cell for the command row.
 * @param {boolean} isFeatured true if the command is featured.
 * @param {boolean} isExternal true if the command is external.
 * @param {number} no no. command.
 * @return {Element}
 */
function commandStatus(isFeatured, isExternal, no) {
    const status = document.createElement("TD");
    status.classList.add("mdl-data-table__cell--non-numeric");
    if (isFeatured) {
        status.appendChild(
            createIcon(no, "stars", ["featured-icon"], "Featured command"));
    }
    if (isExternal) {
        status.appendChild(
            createIcon(no, "open_in_new", ["external-icon"], "External plugin"));
    }
    return status;
}

/**
 * Returns a section to the content of the dialog
 * @param title title of the section
 * @param body body of the section
 * @return {Element}
 */
function addDialogSection(title, body) {
    const container = document.createElement("DIV");
    const sectionTitle = document.createElement("h5");
    const sectionBody = document.createElement("p");

    sectionBody.classList.add("dialog-section-body");
    sectionBody.innerHTML = body;

    sectionTitle.classList.add("dialog-section-title");
    sectionTitle.innerHTML = title;

    container.classList.add("dialog-section");
    container.appendChild(sectionTitle);
    container.appendChild(sectionBody);

    return container;
}

/**
 * Returns a cell for the Plugin column.
 * @param {string}repo repo name
 * @param {string} pluginName plugin name.
 * @param {PluginHelp} plugin the plugin to which the command belong to
 * @return {Element}
 */
function createPluginCell(repo, pluginName, plugin) {
    const pluginCell = document.createElement("TD");
    const button = document.createElement("button");
    pluginCell.classList.add("mdl-data-table__cell--non-numeric");
    button.classList.add("mdl-button", "mdl-button--js", "mdl-button--primary");
    button.innerHTML = pluginName;

    // Attach Event Hanlders.
    const dialog = document.querySelector('dialog');
    button.addEventListener('click', (event) => {
        const title = dialog.querySelector(".mdl-dialog__title");
        const content = dialog.querySelector(".mdl-dialog__content");

        while (content.firstChild) {
            content.removeChild(content.firstChild);
        }

        title.innerHTML = pluginName;
        if (plugin.Description) {
            content.appendChild(addDialogSection("Description", plugin.Description));
        }
        if (plugin.Events) {
            const sectionContent = "[" + plugin.Events.sort().join(", ") + "]";
            content.appendChild(addDialogSection("Events handled", sectionContent));
        }
        if (plugin.Config) {
            let sectionContent = plugin.Config ? plugin.Config[repo] : "";
            let sectionTitle =
                repo === "" ? "Configuration(global)" : "Configuration(" + repo + ")";
            if (sectionContent && sectionContent !== "") {
                content.appendChild(addDialogSection(sectionTitle, sectionContent));
            }
        }
        dialog.showModal();
    });

    pluginCell.appendChild(button);
    return pluginCell;
}

/**
 * Creates a link that links to the command.
 * @param name
 * @param no
 * @return {Element}
 */
function createCommandLink(name, no) {
    const link = document.createElement("TD");
    const iconButton = createIcon(no, "link", ["link-icon"], "", true);

    iconButton.addEventListener("click", () => {
        const tempInput = document.createElement("INPUT");
        let url = window.location.href;
        const hashIndex = url.indexOf("#");
        if (hashIndex !== -1) {
            url = url.slice(0, hashIndex);
        }

        url += "#" + name;
        tempInput.style.zIndex = "-99999";
        tempInput.style.background = "transparent";
        tempInput.value = url;

        document.body.appendChild(tempInput);
        tempInput.select();
        document.execCommand("copy");
        document.body.removeChild(tempInput);

        const toast = document.body.querySelector("#toast");
        toast.MaterialSnackbar.showSnackbar({message: "Copied to clipboard"});
    });

    link.appendChild(iconButton);
    link.classList.add("mdl-data-table__cell--non-numeric");

    return link;
}

/**
 * Creates a row for the Command table.
 * @param {string} repo repo name.
 * @param {string} pluginName plugin name.
 * @param {PluginHelp} plugin the plugin to which the command belongs.
 * @param {Command} command the command.
 * @param {boolean} isExternal true if the command belongs to an external
 * @param {number} no no. command
 * @return {Element}
 */
function createCommandRow(repo, pluginName, plugin, command, isExternal, no) {
    const row = document.createElement("TR");
    const name = extractCommandName(command.Examples[0]);
    row.id = name;

    row.appendChild(commandStatus(command.Featured, isExternal, no));
    row.appendChild(createCommandCell(command.Usage, ["command-usage"]));
    row.appendChild(
        createCommandCell(command.Examples, ["command-examples"], true));
    row.appendChild(
        createCommandCell(command.Description, ["command-desc-text"]));
    row.appendChild(createCommandCell(command.WhoCanUse, ["command-desc-text"]));
    row.appendChild(createPluginCell(repo, pluginName, plugin));
    row.appendChild(createCommandLink(name, no));

    return row;
}

/**
 * Redraw a plugin table.
 * @param {string} repo repo name.
 * @param {Map<string, Object>} helpMap maps a plugin name to a plugin.
 */
function redrawHelpTable(repo, helpMap) {
    const table = document.getElementById("command-table");
    const tableBody = document.querySelector("TBODY");
    if (helpMap.size === 0) {
        table.style.display = "none";
        return;
    }
    table.style.display = "table";
    while (tableBody.childElementCount !== 0) {
        tableBody.removeChild(tableBody.firstChild);
    }
    const names = helpMap.keys();
    const commandsWithPluginName = [];
    for (let name of names) {
        helpMap.get(name).plugin.Commands.forEach((command) => {
            commandsWithPluginName.push({
                pluginName: name,
                command: command
            });
        });
    }
    commandsWithPluginName
        .sort((command1, command2) => {
            return command1.command.Featured ? -1 : command2.command.Featured ? 1 : 0;
        })
        .forEach((command, index) => {
            const pluginName = command.pluginName;
            const {isExternal, plugin} = helpMap.get(pluginName);
            const commandRow = createCommandRow(
                repo,
                pluginName,
                plugin,
                command.command,
                isExternal,
                index);
            tableBody.appendChild(commandRow);
        });
}

/**
 * Redraws the content of the page.
 */
function redraw() {
    const repoSel = selectionText(document.getElementById("repo"));
    if (window.history && window.history.replaceState !== undefined) {
        if (repoSel !== "") {
            history.replaceState(null, "", "/command-help?repo="
                + encodeURIComponent(repoSel));
        } else {
            history.replaceState(null, "", "/command-help")
        }
    }
    redrawOptions();

    const pluginsWithCommands = new Map();
    applicablePlugins(repoSel, allHelp.RepoPlugins)
        .forEach((name) => {
            if (allHelp.PluginHelp[name] && allHelp.PluginHelp[name].Commands) {
                pluginsWithCommands.set(
                    name,
                    {
                        isExternal: false,
                        plugin: allHelp.PluginHelp[name]
                    });
            }
        });
    applicablePlugins(repoSel, allHelp.RepoExternalPlugins)
        .forEach((name) => {
            if (allHelp.ExternalPluginHelp[name]
                && allHelp.ExternalPluginHelp[name].Commands) {
                pluginsWithCommands.set(
                    name,
                    {
                        isExternal: true,
                        plugin: allHelp.ExternalPluginHelp[name]
                    });
            }
        });
    redrawHelpTable(repoSel, pluginsWithCommands);
}

/**
 * Extracts a command name from a command example. It takes the first example,
 * with out the slash, as the name for the command. Also, any '-' character is
 * replaced by '_' to make the name valid in the address.
 * @param {string} commandExample
 * @return {string}
 */
function extractCommandName(commandExample) {
    const command = commandExample.split(" ");
    if (!command || command.length === 0) {
        throw new Error("Cannot extract command name.");
    }
    return command[0].slice(1).split("-").join("_");
}<commit_msg>Display dialog when page is loaded with #plugin<commit_after>"use strict";

function getParameterByName(name) {  // http://stackoverflow.com/a/5158301/3694
    const match = new RegExp('[?&]' + name + '=([^&/]*)').exec(window.location.search);
    return match && decodeURIComponent(match[1].replace(/\+/g, ' '));
}

function redrawOptions() {
    const rs = allHelp.AllRepos.sort();
    const sel = document.getElementById("repo");
    while (sel.length > 1) {
        sel.removeChild(sel.lastChild);
    }
    const param = getParameterByName("repo");
    rs.forEach((opt) => {
        const o = document.createElement("option");
        o.text = opt;
        o.selected = (param && opt === param);
        sel.appendChild(o);
    });
}

window.onload = function () {
    // set dropdown based on options from query string
    const hash = window.location.hash;
    redrawOptions();
    redraw();

    // Register dialog
    const dialog = document.querySelector('dialog');
    dialogPolyfill.registerDialog(dialog);
    dialog.querySelector('.close').addEventListener('click', () => {
        dialog.close();
    });

    if (hash !== "") {
        const el = document.body.querySelector(hash);
        const mainContainer = document.body.querySelector(".mdl-layout__content");
        if (el && mainContainer) {
            setTimeout(() => {
                mainContainer.scrollTop = el.getBoundingClientRect().top;
                window.location.hash = hash;
            }, 32);
            el.querySelector(".mdl-button--primary").click();
        }
    }
};

document.addEventListener("DOMContentLoaded", () => {
    configure();
});

function configure() {
    if (!branding) {
        return;
    }
    if (branding.logo) {
        document.getElementById('img').src = branding.logo;
    }
    if (branding.favicon) {
        document.getElementById('favicon').href = branding.favicon;
    }
    if (branding.background_color) {
        document.body.style.background = branding.background_color;
    }
    if (branding.header_color) {
        document.getElementsByTagName('header')[0].style.backgroundColor = branding.header_color;
    }
}

function selectionText(sel) {
    return sel.selectedIndex === 0 ? "" : sel.options[sel.selectedIndex].text;
}

/**
 * Takes an org/repo string and a repo to plugin map and returns the plugins
 * that apply to the repo.
 * @param {string} repoSel repo name
 * @param {Map<string, PluginHelp>} repoPlugins maps plugin name to plugin
 * @return {Array<string>}
 */
function applicablePlugins(repoSel, repoPlugins) {
    if (repoSel === "") {
        const all = repoPlugins[""];
        if (all) {
            return all.sort();
        }
        return [];
    }
    const parts = repoSel.split("/");
    const byOrg = repoPlugins[parts[0]];
    let plugins = [];
    if (byOrg && byOrg !== []) {
        plugins = plugins.concat(byOrg);
    }
    const pluginNames = repoPlugins[repoSel];
    if (pluginNames) {
        pluginNames.forEach((pluginName) => {
            if (!plugins.includes(pluginName)) {
                plugins.push(pluginName);
            }
        });
    }
    return plugins.sort();
}

/**
 * Returns a normal cell for the command row.
 * @param {Array<string>|string} data content of the cell
 * @param {Array<string>} styles a list of styles applied to the cell.
 * @param {boolean} noWrap true if the content of the cell should be wrap.
 * @return {Element}
 */
function createCommandCell(data, styles = [], noWrap = false) {
    const cell = document.createElement("TD");
    cell.classList.add("mdl-data-table__cell--non-numeric");
    if (!noWrap) {
        cell.classList.add("table-cell");
    }
    let content;
    if (Array.isArray((data))) {
        content = document.createElement("UL");
        content.classList = "command-example-list";

        data.forEach((item) => {
            const itemContainer = document.createElement("LI");
            const span = document.createElement("SPAN");
            span.innerHTML = item;
            span.classList.add(...styles);
            itemContainer.appendChild(span);
            content.appendChild(itemContainer);
        });
    } else {
        content = document.createElement("DIV");
        content.classList.add(...styles);
        content.innerHTML = data;
    }

    cell.appendChild(content);

    return cell;
}

/**
 * Returns an icon element.
 * @param {number} no no. command
 * @param {string} iconString icon name
 * @param {?Array<string>} styles list of styles of the icon
 * @param {string} tooltip tooltip string
 * @param {boolean} isButton true if icon is a button
 * @return {Element}
 */
function createIcon(no, iconString, styles = [], tooltip = "", isButton = false) {
    const icon = document.createElement("I");
    icon.id = "icon-" + iconString + "-" + no;
    icon.classList.add("material-icons");
    icon.classList.add(...styles);
    icon.innerHTML = iconString;

    const container = isButton ? document.createElement("BUTTON") : document.createElement("DIV");
    container.appendChild(icon);
    if (isButton) {
        container.classList.add(...["mdl-button", "mdl-js-button", "mdl-button--icon"]);
    }

    if (tooltip === "") {
        return container;
    }

    const tooltipEl = document.createElement("DIV");
    tooltipEl.setAttribute("for", icon.id);
    tooltipEl.classList.add("mdl-tooltip");
    tooltipEl.innerHTML = tooltip;
    container.appendChild(tooltipEl);

    return container;
}

/**
 * Returns the feature cell for the command row.
 * @param {boolean} isFeatured true if the command is featured.
 * @param {boolean} isExternal true if the command is external.
 * @param {number} no no. command.
 * @return {Element}
 */
function commandStatus(isFeatured, isExternal, no) {
    const status = document.createElement("TD");
    status.classList.add("mdl-data-table__cell--non-numeric");
    if (isFeatured) {
        status.appendChild(
            createIcon(no, "stars", ["featured-icon"], "Featured command"));
    }
    if (isExternal) {
        status.appendChild(
            createIcon(no, "open_in_new", ["external-icon"], "External plugin"));
    }
    return status;
}

/**
 * Returns a section to the content of the dialog
 * @param title title of the section
 * @param body body of the section
 * @return {Element}
 */
function addDialogSection(title, body) {
    const container = document.createElement("DIV");
    const sectionTitle = document.createElement("h5");
    const sectionBody = document.createElement("p");

    sectionBody.classList.add("dialog-section-body");
    sectionBody.innerHTML = body;

    sectionTitle.classList.add("dialog-section-title");
    sectionTitle.innerHTML = title;

    container.classList.add("dialog-section");
    container.appendChild(sectionTitle);
    container.appendChild(sectionBody);

    return container;
}

/**
 * Returns a cell for the Plugin column.
 * @param {string}repo repo name
 * @param {string} pluginName plugin name.
 * @param {PluginHelp} plugin the plugin to which the command belong to
 * @return {Element}
 */
function createPluginCell(repo, pluginName, plugin) {
    const pluginCell = document.createElement("TD");
    const button = document.createElement("button");
    pluginCell.classList.add("mdl-data-table__cell--non-numeric");
    button.classList.add("mdl-button", "mdl-button--js", "mdl-button--primary");
    button.innerHTML = pluginName;

    // Attach Event Handlers.
    const dialog = document.querySelector('dialog');
    button.addEventListener('click', (event) => {
        const title = dialog.querySelector(".mdl-dialog__title");
        const content = dialog.querySelector(".mdl-dialog__content");

        while (content.firstChild) {
            content.removeChild(content.firstChild);
        }

        title.innerHTML = pluginName;
        if (plugin.Description) {
            content.appendChild(addDialogSection("Description", plugin.Description));
        }
        if (plugin.Events) {
            const sectionContent = "[" + plugin.Events.sort().join(", ") + "]";
            content.appendChild(addDialogSection("Events handled", sectionContent));
        }
        if (plugin.Config) {
            let sectionContent = plugin.Config ? plugin.Config[repo] : "";
            let sectionTitle =
                repo === "" ? "Configuration(global)" : "Configuration(" + repo + ")";
            if (sectionContent && sectionContent !== "") {
                content.appendChild(addDialogSection(sectionTitle, sectionContent));
            }
        }
        dialog.showModal();
    });

    pluginCell.appendChild(button);
    return pluginCell;
}

/**
 * Creates a link that links to the command.
 * @param name
 * @param no
 * @return {Element}
 */
function createCommandLink(name, no) {
    const link = document.createElement("TD");
    const iconButton = createIcon(no, "link", ["link-icon"], "", true);

    iconButton.addEventListener("click", () => {
        const tempInput = document.createElement("INPUT");
        let url = window.location.href;
        const hashIndex = url.indexOf("#");
        if (hashIndex !== -1) {
            url = url.slice(0, hashIndex);
        }

        url += "#" + name;
        tempInput.style.zIndex = "-99999";
        tempInput.style.background = "transparent";
        tempInput.value = url;

        document.body.appendChild(tempInput);
        tempInput.select();
        document.execCommand("copy");
        document.body.removeChild(tempInput);

        const toast = document.body.querySelector("#toast");
        toast.MaterialSnackbar.showSnackbar({message: "Copied to clipboard"});
    });

    link.appendChild(iconButton);
    link.classList.add("mdl-data-table__cell--non-numeric");

    return link;
}

/**
 * Creates a row for the Command table.
 * @param {string} repo repo name.
 * @param {string} pluginName plugin name.
 * @param {PluginHelp} plugin the plugin to which the command belongs.
 * @param {Command} command the command.
 * @param {boolean} isExternal true if the command belongs to an external
 * @param {number} no no. command
 * @return {Element}
 */
function createCommandRow(repo, pluginName, plugin, command, isExternal, no) {
    const row = document.createElement("TR");
    const name = extractCommandName(command.Examples[0]);
    row.id = name;

    row.appendChild(commandStatus(command.Featured, isExternal, no));
    row.appendChild(createCommandCell(command.Usage, ["command-usage"]));
    row.appendChild(
        createCommandCell(command.Examples, ["command-examples"], true));
    row.appendChild(
        createCommandCell(command.Description, ["command-desc-text"]));
    row.appendChild(createCommandCell(command.WhoCanUse, ["command-desc-text"]));
    row.appendChild(createPluginCell(repo, pluginName, plugin));
    row.appendChild(createCommandLink(name, no));

    return row;
}

/**
 * Redraw a plugin table.
 * @param {string} repo repo name.
 * @param {Map<string, Object>} helpMap maps a plugin name to a plugin.
 */
function redrawHelpTable(repo, helpMap) {
    const table = document.getElementById("command-table");
    const tableBody = document.querySelector("TBODY");
    if (helpMap.size === 0) {
        table.style.display = "none";
        return;
    }
    table.style.display = "table";
    while (tableBody.childElementCount !== 0) {
        tableBody.removeChild(tableBody.firstChild);
    }
    const names = helpMap.keys();
    const commandsWithPluginName = [];
    for (let name of names) {
        helpMap.get(name).plugin.Commands.forEach((command) => {
            commandsWithPluginName.push({
                pluginName: name,
                command: command
            });
        });
    }
    commandsWithPluginName
        .sort((command1, command2) => {
            return command1.command.Featured ? -1 : command2.command.Featured ? 1 : 0;
        })
        .forEach((command, index) => {
            const pluginName = command.pluginName;
            const {isExternal, plugin} = helpMap.get(pluginName);
            const commandRow = createCommandRow(
                repo,
                pluginName,
                plugin,
                command.command,
                isExternal,
                index);
            tableBody.appendChild(commandRow);
        });
}

/**
 * Redraws the content of the page.
 */
function redraw() {
    const repoSel = selectionText(document.getElementById("repo"));
    if (window.history && window.history.replaceState !== undefined) {
        if (repoSel !== "") {
            history.replaceState(null, "", "/command-help?repo="
                + encodeURIComponent(repoSel));
        } else {
            history.replaceState(null, "", "/command-help")
        }
    }
    redrawOptions();

    const pluginsWithCommands = new Map();
    applicablePlugins(repoSel, allHelp.RepoPlugins)
        .forEach((name) => {
            if (allHelp.PluginHelp[name] && allHelp.PluginHelp[name].Commands) {
                pluginsWithCommands.set(
                    name,
                    {
                        isExternal: false,
                        plugin: allHelp.PluginHelp[name]
                    });
            }
        });
    applicablePlugins(repoSel, allHelp.RepoExternalPlugins)
        .forEach((name) => {
            if (allHelp.ExternalPluginHelp[name]
                && allHelp.ExternalPluginHelp[name].Commands) {
                pluginsWithCommands.set(
                    name,
                    {
                        isExternal: true,
                        plugin: allHelp.ExternalPluginHelp[name]
                    });
            }
        });
    redrawHelpTable(repoSel, pluginsWithCommands);
}

/**
 * Extracts a command name from a command example. It takes the first example,
 * with out the slash, as the name for the command. Also, any '-' character is
 * replaced by '_' to make the name valid in the address.
 * @param {string} commandExample
 * @return {string}
 */
function extractCommandName(commandExample) {
    const command = commandExample.split(" ");
    if (!command || command.length === 0) {
        throw new Error("Cannot extract command name.");
    }
    return command[0].slice(1).split("-").join("_");
}
<|endoftext|>


<commit_before>/*global $:false */
/*global jQuery:false */
/*global Backbone:false */
/*global jRespond:false */
/*global _:false */
var gc2table = (function () {
    "use strict";
    var host, js, isLoaded, object, init,
        scriptsLoaded = false,
        scriptSource = (function (scripts) {
            scripts = document.getElementsByTagName('script');
            var script = scripts[scripts.length - 1];
            if (script.getAttribute.length !== undefined) {
                return script.src;
            }
            return script.getAttribute('src', -1);
        }());

    // Try to set host from script if not set already
    if (typeof window.geocloud_host === "undefined") {
        host = (scriptSource.charAt(0) === "/") ? "" : scriptSource.split("/")[0] + "//" + scriptSource.split("/")[2];
    } else {
        host = window.geocloud_host;
    }

    if (typeof $ === "undefined") {
        js = document.createElement("script");
        js.type = "text/javascript";
        js.src = "https://ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js";
        document.getElementsByTagName("head")[0].appendChild(js);
    }
    (function pollForjQuery() {
        if (typeof jQuery !== "undefined") {
            if (typeof jQuery().typeahead === "undefined") {
                $.getScript(host + "/js/typeahead.js-0.10.5/dist/typeahead.bundle.js");
            }
            if (typeof jQuery().bootstrapTable === "undefined") {
                $.getScript(host + "/js/bootstrap-table/bootstrap-table.js");
            }
            if (typeof _ === 'undefined') {
                $.getScript(host + "/js/underscore/underscore-min.js");
            }
            if (typeof jRespond === "undefined") {
                $.getScript(host + "/js/div/jRespond.js");
            }
            (function pollForDependencies() {
                if (typeof jQuery().typeahead !== "undefined" &&
                    typeof jQuery().bootstrapTable !== "undefined" &&
                    typeof jQuery().bootstrapTable.locales !== "undefined" &&
                    typeof _ !== 'undefined' &&
                    typeof jRespond !== "undefined") {
                    if (typeof jQuery().bootstrapTable.locales['da-DK'] === "undefined") {
                        $.getScript(host + "/js/bootstrap-table/bootstrap-table-locale-all.js");
                    }
                    if (typeof jQuery().bootstrapTable.defaults.filterControl === "undefined") {
                        $.getScript(host + "/js/bootstrap-table/extensions/filter-control/bootstrap-table-filter-control.js");
                    }
                    if (typeof Backbone === "undefined") {
                        $.getScript("http://backbonejs.org/backbone.js");
                    }
                    (function pollForDependants() {
                        if (typeof jQuery().bootstrapTable.defaults.filterControl !== "undefined" &&
                            typeof jQuery().bootstrapTable.locales['da-DK'] !== "undefined" &&
                            typeof Backbone !== "undefined") {
                            scriptsLoaded = true;
                        } else {
                            setTimeout(pollForDependants, 10);
                        }
                    }());
                } else {
                    setTimeout(pollForDependencies, 10);
                }
            }());
            $('<link/>').attr({
                rel: 'stylesheet',
                type: 'text/css',
                href: host + '/js/bootstrap-table/bootstrap-table.min.css'
            }).appendTo('head');
        } else {
            setTimeout(pollForjQuery, 10);
        }
    }());

    isLoaded = function () {
        return scriptsLoaded;
    };
    object = {};
    init = function (conf) {
        var defaults = {
                el: "#table",
                autoUpdate: false,
                height: 300,
                setSelectedStyle: true,
                openPopUp: false,
                setViewOnSelect: true,
                responsive: true,
                autoPan: false,
                locale: 'en-US',
                styleSelected: {
                    weight: 5,
                    color: '#666',
                    dashArray: '',
                    fillOpacity: 0.7
                }
            }, prop,
            uid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
                var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
                return v.toString(16);
            });
        if (conf) {
            for (prop in conf) {
                defaults[prop] = conf[prop];
            }
        }
        var data,
            m = defaults.geocloud2,
            store = defaults.store,
            cm = defaults.cm,
            autoUpdate = defaults.autoUpdate,
            height = defaults.height,
            styleSelected = defaults.styleSelected,
            el = defaults.el, click, loadDataInTable,
            setSelectedStyle = defaults.setSelectedStyle,
            setViewOnSelect = defaults.setViewOnSelect,
            openPopUp = defaults.openPopUp,
            autoPan = defaults.autoPan,
            responsive = defaults.responsive,
            locale = defaults.locale;

        (function poll() {
            if (scriptsLoaded) {
                var originalLayers, filters;
                _.extend(object, Backbone.Events);
                object.on("selected" + "_" + uid, function (id) {
                    $(el + ' tr').removeClass("selected");
                    $.each(store.layer._layers, function (i, v) {
                        try {
                            store.layer.resetStyle(v);
                        } catch (e) {
                        }
                    });
                    var row = $('*[data-uniqueid="' + id + '"]');
                    row.addClass("selected");
                    if (setSelectedStyle) {
                        m.map._layers[id].setStyle(styleSelected);
                    }
                    if (openPopUp) {
                        var str = "
";
                        $.each(cm, function (i, v) {
                            str = str + "
" + v.header + "	" + m.map._layers[id].feature.properties[v.dataIndex] + "
";
                        });
                        str = str + "
";
                        m.map._layers[id].bindPopup(str, {
                            className: "custom-popup",
                            autoPan: autoPan,
                            closeButton: true
                        }).openPopup();
                    }

                });

                click = function (e) {
                    var row = $('*[data-uniqueid="' + e.target._leaflet_id + '"]');
                    $(el).bootstrapTable('scrollTo', row.index() * row.height());
                    object.trigger("selected" + "_" + uid, e.target._leaflet_id);
                };
                $.each(store.layer._layers, function (i, layer) {
                    layer.on({
                        click: click
                    });
                });

                $(el).append("

");
                $.each(cm, function (i, v) {
                    $(el + ' thead tr').append("" + v.header + "	");
                });

                var filterMap =
                    _.debounce(function () {
                        $.each(store.layer._layers, function (i, v) {
                            m.map.removeLayer(v);
                        });
                        $.each(originalLayers, function (i, v) {
                            m.map.addLayer(v);
                        });
                        filters = {};
                        $.each(cm, function (i, v) {
                            if (v.filterControl) {
                                filters[v.dataIndex] = $(".bootstrap-table-filter-control-" + v.dataIndex).val();
                            }
                        });
                        console.log(filters)
                        $.each(store.layer._layers, function (i, v) {
                            $.each(v.feature.properties, function (u, n) {
                                if (typeof filters[u] !== "undefined" && filters[u] !== null && (n.toLowerCase().indexOf(filters[u].toLowerCase()) === -1) && filters[u] !== "") {
                                    m.map.removeLayer(v);
                                }
                            });
                        });
                        bindEvent();
                    }, 350);

                var bindEvent = function (e) {
                    setTimeout(function () {
                        $(el + ' tr').on("click", function (e) {
                            object.trigger("selected" + "_" + uid, $(this).data('uniqueid'));
                            var layer = m.map._layers[$(this).data('uniqueid')];
                            setTimeout(function () {
                                if (setViewOnSelect) {
                                    m.map.fitBounds(layer.getBounds());
                                }
                            }, 100);
                        });
                    }, 100);
                };
                $(el).bootstrapTable({
                    uniqueId: "_id",
                    height: height,
                    locale: locale,
                    onToggle: bindEvent,
                    onSort: bindEvent,
                    onColumnSwitch: bindEvent,
                    onColumnSearch: filterMap
                });

                // Define a callback for when the SQL returns
                var customOnLoad = store.onLoad;
                store.onLoad = function () {
                    loadDataInTable();
                };
                loadDataInTable = function () {
                    data = [];
                    $.each(store.layer._layers, function (i, v) {
                        v.feature.properties._id = i;
                        $.each(v.feature.properties, function (n, m) {
                            $.each(cm, function (j, k) {
                                if (k.dataIndex === n && k.link === true) {
                                    v.feature.properties[n] = "" + "Link" + "";
                                }

                            });
                        });
                        data.push(v.feature.properties);
                        v.on({
                            click: click
                        });

                    });
                    originalLayers = jQuery.extend(true, {}, store.layer._layers);
                    $(el).bootstrapTable('load', data);
                    customOnLoad();
                };
                if (autoUpdate) {
                    m.on("moveend", _.debounce(function () {
                            store.reset();
                            store.load();
                        }, 200)
                    );
                }
                var jRes = jRespond([
                    {
                        label: 'handheld',
                        enter: 0,
                        exit: 400
                    },
                    {
                        label: 'desktop',
                        enter: 401,
                        exit: 100000
                    }
                ]);
                if (responsive) {
                    jRes.addFunc({
                        breakpoint: ['handheld'],
                        enter: function () {
                            $(el).bootstrapTable('toggleView');
                        },
                        exit: function () {
                            $(el).bootstrapTable('toggleView');
                        }
                    });
                    jRes.addFunc({
                        breakpoint: ['desktop'],
                        enter: function () {
                        },
                        exit: function () {
                        }
                    });
                }
            } else {
                setTimeout(poll, 20);
            }
        }());
        return {
            loadDataInTable: loadDataInTable,
            object: object,
            uid: uid
        };
    };
    return {
        init: init,
        isLoaded: isLoaded
    };
}());
<commit_msg>debouncing filters<commit_after>/*global $:false */
/*global jQuery:false */
/*global Backbone:false */
/*global jRespond:false */
/*global _:false */
var gc2table = (function () {
    "use strict";
    var host, js, isLoaded, object, init,
        scriptsLoaded = false,
        scriptSource = (function (scripts) {
            scripts = document.getElementsByTagName('script');
            var script = scripts[scripts.length - 1];
            if (script.getAttribute.length !== undefined) {
                return script.src;
            }
            return script.getAttribute('src', -1);
        }());

    // Try to set host from script if not set already
    if (typeof window.geocloud_host === "undefined") {
        host = (scriptSource.charAt(0) === "/") ? "" : scriptSource.split("/")[0] + "//" + scriptSource.split("/")[2];
    } else {
        host = window.geocloud_host;
    }

    if (typeof $ === "undefined") {
        js = document.createElement("script");
        js.type = "text/javascript";
        js.src = "https://ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js";
        document.getElementsByTagName("head")[0].appendChild(js);
    }
    (function pollForjQuery() {
        if (typeof jQuery !== "undefined") {
            if (typeof jQuery().typeahead === "undefined") {
                $.getScript(host + "/js/typeahead.js-0.10.5/dist/typeahead.bundle.js");
            }
            if (typeof jQuery().bootstrapTable === "undefined") {
                $.getScript(host + "/js/bootstrap-table/bootstrap-table.js");
            }
            if (typeof _ === 'undefined') {
                $.getScript(host + "/js/underscore/underscore-min.js");
            }
            if (typeof jRespond === "undefined") {
                $.getScript(host + "/js/div/jRespond.js");
            }
            (function pollForDependencies() {
                if (typeof jQuery().typeahead !== "undefined" &&
                    typeof jQuery().bootstrapTable !== "undefined" &&
                    typeof jQuery().bootstrapTable.locales !== "undefined" &&
                    typeof _ !== 'undefined' &&
                    typeof jRespond !== "undefined") {
                    if (typeof jQuery().bootstrapTable.locales['da-DK'] === "undefined") {
                        $.getScript(host + "/js/bootstrap-table/bootstrap-table-locale-all.js");
                    }
                    if (typeof jQuery().bootstrapTable.defaults.filterControl === "undefined") {
                        $.getScript(host + "/js/bootstrap-table/extensions/filter-control/bootstrap-table-filter-control.js");
                    }
                    if (typeof Backbone === "undefined") {
                        $.getScript("http://backbonejs.org/backbone.js");
                    }
                    (function pollForDependants() {
                        if (typeof jQuery().bootstrapTable.defaults.filterControl !== "undefined" &&
                            typeof jQuery().bootstrapTable.locales['da-DK'] !== "undefined" &&
                            typeof Backbone !== "undefined") {
                            scriptsLoaded = true;
                        } else {
                            setTimeout(pollForDependants, 10);
                        }
                    }());
                } else {
                    setTimeout(pollForDependencies, 10);
                }
            }());
            $('<link/>').attr({
                rel: 'stylesheet',
                type: 'text/css',
                href: host + '/js/bootstrap-table/bootstrap-table.min.css'
            }).appendTo('head');
        } else {
            setTimeout(pollForjQuery, 10);
        }
    }());

    isLoaded = function () {
        return scriptsLoaded;
    };
    object = {};
    init = function (conf) {
        var defaults = {
                el: "#table",
                autoUpdate: false,
                height: 300,
                setSelectedStyle: true,
                openPopUp: false,
                setViewOnSelect: true,
                responsive: true,
                autoPan: false,
                locale: 'en-US',
                styleSelected: {
                    weight: 5,
                    color: '#666',
                    dashArray: '',
                    fillOpacity: 0.7
                }
            }, prop,
            uid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
                var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
                return v.toString(16);
            });
        if (conf) {
            for (prop in conf) {
                defaults[prop] = conf[prop];
            }
        }
        var data,
            m = defaults.geocloud2,
            store = defaults.store,
            cm = defaults.cm,
            autoUpdate = defaults.autoUpdate,
            height = defaults.height,
            styleSelected = defaults.styleSelected,
            el = defaults.el, click, loadDataInTable,
            setSelectedStyle = defaults.setSelectedStyle,
            setViewOnSelect = defaults.setViewOnSelect,
            openPopUp = defaults.openPopUp,
            autoPan = defaults.autoPan,
            responsive = defaults.responsive,
            locale = defaults.locale;

        (function poll() {
            if (scriptsLoaded) {
                var originalLayers, filters;
                _.extend(object, Backbone.Events);
                object.on("selected" + "_" + uid, function (id) {
                    $(el + ' tr').removeClass("selected");
                    $.each(store.layer._layers, function (i, v) {
                        try {
                            store.layer.resetStyle(v);
                        } catch (e) {
                        }
                    });
                    var row = $('*[data-uniqueid="' + id + '"]');
                    row.addClass("selected");
                    if (setSelectedStyle) {
                        m.map._layers[id].setStyle(styleSelected);
                    }
                    if (openPopUp) {
                        var str = "
";
                        $.each(cm, function (i, v) {
                            str = str + "
" + v.header + "	" + m.map._layers[id].feature.properties[v.dataIndex] + "
";
                        });
                        str = str + "
";
                        m.map._layers[id].bindPopup(str, {
                            className: "custom-popup",
                            autoPan: autoPan,
                            closeButton: true
                        }).openPopup();
                    }

                });

                click = function (e) {
                    var row = $('*[data-uniqueid="' + e.target._leaflet_id + '"]');
                    $(el).bootstrapTable('scrollTo', row.index() * row.height());
                    object.trigger("selected" + "_" + uid, e.target._leaflet_id);
                };
                $.each(store.layer._layers, function (i, layer) {
                    layer.on({
                        click: click
                    });
                });

                $(el).append("

");
                $.each(cm, function (i, v) {
                    $(el + ' thead tr').append("" + v.header + "	");
                });

                var filterMap =
                    _.debounce(function () {
                        $.each(store.layer._layers, function (i, v) {
                            m.map.removeLayer(v);
                        });
                        $.each(originalLayers, function (i, v) {
                            m.map.addLayer(v);
                        });
                        filters = {};
                        $.each(cm, function (i, v) {
                            if (v.filterControl) {
                                filters[v.dataIndex] = $(".bootstrap-table-filter-control-" + v.dataIndex).val();
                            }
                        });
                        console.log(filters)
                        $.each(store.layer._layers, function (i, v) {
                            $.each(v.feature.properties, function (u, n) {
                                if (typeof filters[u] !== "undefined" && filters[u] !== null && (n.toLowerCase().indexOf(filters[u].toLowerCase()) === -1) && filters[u] !== "") {
                                    m.map.removeLayer(v);
                                }
                            });
                        });
                        bindEvent();
                    }, 500);

                var bindEvent = function (e) {
                    setTimeout(function () {
                        $(el + ' tr').on("click", function (e) {
                            object.trigger("selected" + "_" + uid, $(this).data('uniqueid'));
                            var layer = m.map._layers[$(this).data('uniqueid')];
                            setTimeout(function () {
                                if (setViewOnSelect) {
                                    m.map.fitBounds(layer.getBounds());
                                }
                            }, 100);
                        });
                    }, 100);
                };
                $(el).bootstrapTable({
                    uniqueId: "_id",
                    height: height,
                    locale: locale,
                    onToggle: bindEvent,
                    onSort: bindEvent,
                    onColumnSwitch: bindEvent,
                    onColumnSearch: filterMap
                });

                // Define a callback for when the SQL returns
                var customOnLoad = store.onLoad;
                store.onLoad = function () {
                    loadDataInTable();
                };
                loadDataInTable = function () {
                    data = [];
                    $.each(store.layer._layers, function (i, v) {
                        v.feature.properties._id = i;
                        $.each(v.feature.properties, function (n, m) {
                            $.each(cm, function (j, k) {
                                if (k.dataIndex === n && k.link === true) {
                                    v.feature.properties[n] = "" + "Link" + "";
                                }

                            });
                        });
                        data.push(v.feature.properties);
                        v.on({
                            click: click
                        });

                    });
                    originalLayers = jQuery.extend(true, {}, store.layer._layers);
                    $(el).bootstrapTable('load', data);
                    customOnLoad();
                };
                if (autoUpdate) {
                    m.on("moveend", _.debounce(function () {
                            store.reset();
                            store.load();
                        }, 200)
                    );
                }
                var jRes = jRespond([
                    {
                        label: 'handheld',
                        enter: 0,
                        exit: 400
                    },
                    {
                        label: 'desktop',
                        enter: 401,
                        exit: 100000
                    }
                ]);
                if (responsive) {
                    jRes.addFunc({
                        breakpoint: ['handheld'],
                        enter: function () {
                            $(el).bootstrapTable('toggleView');
                        },
                        exit: function () {
                            $(el).bootstrapTable('toggleView');
                        }
                    });
                    jRes.addFunc({
                        breakpoint: ['desktop'],
                        enter: function () {
                        },
                        exit: function () {
                        }
                    });
                }
            } else {
                setTimeout(poll, 20);
            }
        }());
        return {
            loadDataInTable: loadDataInTable,
            object: object,
            uid: uid
        };
    };
    return {
        init: init,
        isLoaded: isLoaded
    };
}());
<|endoftext|>


<commit_before>
var Split = function (ids, options) {
    // Set defaults

    options = typeof options !== 'undefined' ?  options : {};

    if (!options.gutterWidth) options.gutterWidth = 10;
    if (!options.minWidth) options.minWidth = 100;

    // Event listeners for drag events, bound to a pair object.
    // Save the pair's left position and width when dragging starts.
    // Prevent selection on start and re-enable it when done.

    var startDragging = function () {
            this.dragging = true;

            this.width = this.left.clientWidth + this.right.clientWidth + options.gutterWidth;
            this.x = this.left.getBoundingClientRect().left;

            this.left.addEventListener('selectstart', preventSelection);
            this.left.addEventListener('dragstart', preventSelection);
            this.right.addEventListener('selectstart', preventSelection);
            this.right.addEventListener('dragstart', preventSelection);

            this.left.style.userSelect = 'none';
            this.left.style.webkitUserSelect = 'none';
            this.left.style.MozUserSelect = 'none';

            this.right.style.userSelect = 'none';
            this.right.style.webkitUserSelect = 'none';
            this.right.style.MozUserSelect = 'none';
        },

        stopDragging = function () {
            this.dragging = false;

            this.left.removeEventListener('selectstart', preventSelection);
            this.left.removeEventListener('dragstart', preventSelection);
            this.right.removeEventListener('selectstart', preventSelection);
            this.right.removeEventListener('dragstart', preventSelection);

            this.left.style.userSelect = '';
            this.left.style.webkitUserSelect = '';
            this.left.style.MozUserSelect = '';

            this.right.style.userSelect = '';
            this.right.style.webkitUserSelect = '';
            this.right.style.MozUserSelect = '';
        },

        drag = function (e) {
            if (!this.dragging) return;

            // Stop dragging if closer than minWidth to
            // the pair's left or right sides

            if (e.clientX <= this.x + options.minWidth ||
                e.clientX >= this.x + this.width - options.minWidth) {
                    return;
            }

            // Get the relative position of the event from the left side of the
            // pair for the left width. Right width is total width - left width.

            var offsetX = e.clientX - this.x;

            this.left.style.width = offsetX - (options.gutterWidth / 2) + 'px';
            this.right.style.width = this.width - offsetX - (options.gutterWidth / 2) + 'px';
        },

        preventSelection = function () { return false; },

        // Given a list of DOM element ids and a list of percentage widths,
        // assign each element a width allowing for a gutter between each
        // pair. The number of gutters is ids.length - 1, and the total gutter
        // width is gutterWidth * (ids.length - 1). Before calculating
        // each width, subtract the total gutter width for the parent width.

        parent = document.getElementById(ids[0]).parentNode,
        width = parent.clientWidth - (options.gutterWidth * (ids.length - 1));

    if (!options.widths) {
        var percent = 100 / ids.length;

        options.widths = [];

        for (var i = 0; i < ids.length; i++) {
            options.widths.push(percent);
        };
    }

    for (var i = 0; i < ids.length; i++) {
        var el = document.getElementById(ids[i]);

        if (i > 0) {
            var pair = {
                    left: document.getElementById(ids[i - 1]),
                    right: el,
                    dragging: false,
                    parent: parent
                },
                gutter = document.createElement('div');

            gutter.className = 'gutter';
            gutter.style.width = options.gutterWidth + 'px';
            gutter.style.float = 'left';

            gutter.addEventListener('mousedown', startDragging.bind(pair));

            parent.addEventListener('mouseup', stopDragging.bind(pair));
            parent.addEventListener('mousemove', drag.bind(pair));
            parent.addEventListener('mouseleave', stopDragging.bind(pair));

            parent.insertBefore(gutter, el);

            pair.gutter = gutter;
        }

        el.style.width = width * options.widths[i] / 100 + 'px';
    }
};
<commit_msg>add callbacks<commit_after>
var Split = function (ids, options) {
    // Set defaults

    options = typeof options !== 'undefined' ?  options : {};

    if (!options.gutterWidth) options.gutterWidth = 10;
    if (!options.minWidth) options.minWidth = 100;

    // Event listeners for drag events, bound to a pair object.
    // Save the pair's left position and width when dragging starts.
    // Prevent selection on start and re-enable it when done.

    var startDragging = function () {
            this.dragging = true;

            this.width = this.left.clientWidth + this.right.clientWidth + options.gutterWidth;
            this.x = this.left.getBoundingClientRect().left;

            this.left.addEventListener('selectstart', preventSelection);
            this.left.addEventListener('dragstart', preventSelection);
            this.right.addEventListener('selectstart', preventSelection);
            this.right.addEventListener('dragstart', preventSelection);

            this.left.style.userSelect = 'none';
            this.left.style.webkitUserSelect = 'none';
            this.left.style.MozUserSelect = 'none';

            this.right.style.userSelect = 'none';
            this.right.style.webkitUserSelect = 'none';
            this.right.style.MozUserSelect = 'none';

            if (options.onDrag) {
                options.onDragStart();
            }
        },

        stopDragging = function () {
            this.dragging = false;

            this.left.removeEventListener('selectstart', preventSelection);
            this.left.removeEventListener('dragstart', preventSelection);
            this.right.removeEventListener('selectstart', preventSelection);
            this.right.removeEventListener('dragstart', preventSelection);

            this.left.style.userSelect = '';
            this.left.style.webkitUserSelect = '';
            this.left.style.MozUserSelect = '';

            this.right.style.userSelect = '';
            this.right.style.webkitUserSelect = '';
            this.right.style.MozUserSelect = '';

            if (options.onDragEnd) {
                options.onDragEnd();
            }
        },

        drag = function (e) {
            if (!this.dragging) return;

            // Stop dragging if closer than minWidth to
            // the pair's left or right sides

            if (e.clientX <= this.x + options.minWidth ||
                e.clientX >= this.x + this.width - options.minWidth) {
                    return;
            }

            // Get the relative position of the event from the left side of the
            // pair for the left width. Right width is total width - left width.

            var offsetX = e.clientX - this.x;

            this.left.style.width = offsetX - (options.gutterWidth / 2) + 'px';
            this.right.style.width = this.width - offsetX - (options.gutterWidth / 2) + 'px';

            if (options.onDrag) {
                options.onDrag();
            }
        },

        preventSelection = function () { return false; },

        // Given a list of DOM element ids and a list of percentage widths,
        // assign each element a width allowing for a gutter between each
        // pair. The number of gutters is ids.length - 1, and the total gutter
        // width is gutterWidth * (ids.length - 1). Before calculating
        // each width, subtract the total gutter width for the parent width.

        parent = document.getElementById(ids[0]).parentNode,
        width = parent.clientWidth - (options.gutterWidth * (ids.length - 1));

    if (!options.widths) {
        var percent = 100 / ids.length;

        options.widths = [];

        for (var i = 0; i < ids.length; i++) {
            options.widths.push(percent);
        };
    }

    for (var i = 0; i < ids.length; i++) {
        var el = document.getElementById(ids[i]);

        if (i > 0) {
            var pair = {
                    left: document.getElementById(ids[i - 1]),
                    right: el,
                    dragging: false,
                    parent: parent
                },
                gutter = document.createElement('div');

            gutter.className = 'gutter';
            gutter.style.width = options.gutterWidth + 'px';
            gutter.style.float = 'left';

            gutter.addEventListener('mousedown', startDragging.bind(pair));

            parent.addEventListener('mouseup', stopDragging.bind(pair));
            parent.addEventListener('mousemove', drag.bind(pair));
            parent.addEventListener('mouseleave', stopDragging.bind(pair));

            parent.insertBefore(gutter, el);

            pair.gutter = gutter;
        }

        el.style.width = width * options.widths[i] / 100 + 'px';
    }
};
<|endoftext|>


<commit_before>'use strict';

define([
	'canjs',
	'core/appState',
	'app/simplePage/simplePageModel',
	'underscore',
	'core/helpers/preloader',
	'velocity',
	'social/vk/vk_sdk',
	'social/fb/fb_sdk',
	'css!app/simplePage/css/simplePage.css'
],
	function (can, appState, SimplePageModel, _) {

		return can.Control.extend({
			defaults: {
				viewpath: 'app/simplePage/',
				alternateViewpath: 'app/simplePage/alternateViews/',

				loadingInterval: 15,
				vkLoginPermission: '', //4 - photos
				facebookPermissions: 'email,user_birthday'
			}
		}, {
			init: function () {
				var self = this;

				var simplePage = self.getSimplePage();

				var viewfile =
					simplePage.alternate_view_path.length > 0 ?
					self.options.alternateViewpath + simplePage.alternate_view_path + '.stache' :
					self.options.viewpath + 'index.stache';

				self.element.html(
					can.view(viewfile, {
						simplePage: simplePage,
						appState: appState
					})
				);

				if (self.options.isReady) {
					self.options.isReady.resolve();
					$(window).scrollTop(0);
				}
			},

			getSimplePage: function () {
				var id = this.options.data.id;
				return _.find(appState.attr('simplePages'), function(element) {
					return element.url == id;
				});
			},

			'.socNets.fb click': function (el, ev) {
				var self = this;

				FB.login(can.proxy(self.fbLoginResponse, self), {
					scope: self.options.facebookPermissions
				});
			},

			fbLoginResponse: function (response) {
				var self = this;

				if (response.status === 'connected') {

					FB.api('/me', function(userResponse) {

						FB.api("/me/picture?width=180&height=180",  function(imageResponse) {
							self.saveUser(userResponse.first_name, userResponse.last_name, imageResponse.data.url, userResponse, null);
						});
					});

				} else if (response.status === 'not_authorized') {
					// The person is logged into Facebook, but not your app.
				} else {
					// The person is not logged into Facebook, so we're not sure if
					// they are logged into this app or not.
				}
			},

			'.socNets.vk click': function (el, ev) {
				var self = this;

				VK.Auth.login(can.proxy(self.vkLoginResponse, self), self.options.vkLoginPermission);
			},

			vkLoginResponse: function (response) {
				var self = this;

				if (response.session) {

					VK.api("getProfiles", {
						uids: response.session.mid,
						fields: 'bdate,city'
					}, function (profileData){

						if (profileData.response && profileData.response[0]){
							self.saveUser(profileData.response[0].first_name, profileData.response[0].last_name, profileData.response[0].photo_200, null, profileData.response[0]);
						}
					});

				} else {
					alert('not auth');
				}
			},

			'.socNets.od click': function (el, ev) {
				window.location = '/auth/odnoklassniki';
			},

			saveUser: function (name, surname, image, fbProfile, vkProfile) {
				appState.attr('user.facebook', fbProfile);
				appState.attr('user.vk', vkProfile);
				appState.attr('user.username', name);
				appState.attr('user.lastName', surname);
				appState.attr('user.image', image);

				if (appState.attr('user.odnoklassniki')) {
					var od_bd = appState.attr('user.odnoklassniki.birthday').split('-');
					var birthday = [od_bd[2],od_bd[1],od_bd[0]];
					appState.attr('user.birthday', birthday);
				} else if (appState.attr('user.vk')) {
					var vk_bd = appState.attr('user.vk.bdate').split('.');
					appState.attr('user.birthday', vk_bd);
				} else if (appState.attr('user.facebook')) {
					if (appState.attr('user.facebook.birthday')) {
						var fb_bd = appState.attr('user.facebook.birthday').split('/');
						appState.attr('user.birthday', [fb_bd[1],fb_bd[0],fb_bd[2]]);
					}
					if ( appState.attr('user.facebook.email') ) {
						appState.attr('user.email', appState.attr('user.facebook.email'));
					}
				}

				can.route.attr({
					module: 'simplePage',
					id: 'personal-form'
				}, true);
			},

			'.radioButton click': function (el, ev) {
				if (!el.hasClass('activeBtn')) {
					var $wrapper = el.parents('.radioWrapper');
					var $active = $wrapper.find('.activeBtn');
					var activeValue = $active.data('value');
					var $activeInput = $wrapper.find('input[value='+activeValue+']');

					$activeInput.attr('checked', false);
					$active.removeClass('activeBtn');

					var newActiveValue = el.data('value');
					var $newActiveInput = $wrapper.find('input[value='+newActiveValue+']');

					$newActiveInput.attr('checked', true);
					el.addClass('activeBtn');
				}
			},

			'.checkboxButton click': function (el, ev) {

				var $wrapper = el.parents('.checkboxWrapper');
				var buttonValue = el.data('value');
				var $checkboxInput = $wrapper.find('input[value='+buttonValue+']');

				if (el.hasClass('activeBtn')) {
					$checkboxInput.attr('checked', false);
					el.removeClass('activeBtn');
				} else {
					$checkboxInput.attr('checked', true);
					el.addClass('activeBtn');
				}
			},

			'.personalData submit': function (el, ev) {
				ev.preventDefault();

				var self = this;

				if ( el.find('.wrong').length == 0 ) {
					el.find('input[type=submit]').removeClass('validationFailure');
					var formData = can.deparam(el.serialize());

					if ( appState.attr('user._id') != null ) {
						formData._id = appState.attr('user._id');
					} else if ( appState.attr('user.facebook') != null ) {
						formData.facebook = appState.attr('user.facebook').attr();
					} else if ( appState.attr('user.vk') != null) {
						formData.vk = appState.attr('user.vk').attr();
					} else if ( appState.attr('user.odnoklassniki') != null) {
						formData.odnoklassniki = appState.attr('user.odnoklassniki').attr();
					}

					var simplePage = new SimplePageModel(formData);

					simplePage.save()
						.done(function() {
							can.route.attr({
								module: 'simplePage',
								id: 'questions-form'
							}, true);
						})
						.fail(function (data) {
							console.error(data);
						});
				} else {
					el.find('input[type=submit]').addClass('validationFailure');
				}
			},

			'.questionsForm submit': function (el, ev) {

				ev.preventDefault();

				var self = this;

				if ( el.find('.wrong').length == 0 ) {
					el.find('input[type=submit]').removeClass('validationFailure');
					var formData = can.deparam(el.serialize());

					if ( appState.attr('user._id') != null ) {
						formData._id = appState.attr('user._id');
					} else if ( appState.attr('user.facebook') != null ) {
						formData.facebook = appState.attr('user.facebook').attr();
					} else if ( appState.attr('user.vk') != null) {
						formData.vk = appState.attr('user.vk').attr();
					} else if ( appState.attr('user.odnoklassniki') != null) {
						formData.odnoklassniki = appState.attr('user.odnoklassniki').attr();
					}

					var simplePage = new SimplePageModel(formData);

					simplePage.save()
						.done(function() {
							can.route.attr({
								module: 'simplePage',
								id: 'gratitude'
							}, true);
						})
						.fail(function (data) {
							console.error(data);
						});
				} else {
					el.find('input[type=submit]').addClass('validationFailure');
				}
			},

			'.sendEmail submit': function (el, ev) {
				ev.preventDefault();

				if ( el.find('input[type=email]').val().length > 0 ) {
					var formData = can.deparam(el.serialize());

					if ( appState.attr('user._id') != null ) {
						formData._id = appState.attr('user._id');
					}

					var simplePage = new SimplePageModel(formData);

					simplePage.save()
						.done(function(data) {
							console.log(data);
							appState.attr('user._id', data._id);
							can.route.attr({
								module: 'simplePage',
								id: 'personal-form'
							}, true);
						})
						.fail(function (data) {
							console.error(data);
						});
				}
			},

			'.quesBtn click': function (el, ev) {
				var $parent = el.parents('.parentQuestion');

				if (el.hasClass('showChild')) {
					var $child = $parent.next();

					if ($child.hasClass('childQuestion')) {
						$child.velocity('slideDown');
					}
				} else if ($parent.find('.showChild').length > 0) {
					var $child = $parent.next();

					if ($child.hasClass('childQuestion')) {
						$child.velocity('slideUp');
					}
				}
			},

			'input.validate keyup': function (el, ev) {
				this.textValidate(el);
			},

			'textarea keyup': function (el, ev) {
				this.textValidate(el);
			},

			textValidate: function (el) {
				if (el.val().length > 0) {
					el.parents('.question').find('.valid').removeClass('wrong').addClass('correct');
				} else if ( el.val().length == 0 ) {
					el.parents('.question').find('.valid').removeClass('correct').addClass('wrong');
				}
			},

			'input.city keyup': function (el, ev) {
				var text = el.val();

				if (text.length > 2) {
					var matches = _.filter(appState.attr('cities').attr(), function (city) {
						return city.name.toLowerCase().indexOf(text.toLowerCase()) > -1;
					});

					if (matches.length > 0) {
						appState.attr('cityMatches', matches);
					} else {
						appState.attr('cityMatches', null);
					}
				} else {
					appState.attr('cityMatches', null);
				}
			},

			'input.radioValidate click': function (el, ev) {
				el.parents('.question').find('.valid').removeClass('wrong').addClass('correct');
			},

			'input.checkboxValidate click': function (el, ev) {
				var $parent = el.parents('.question');
				console.log($parent.find('input[checked=checked]').length);
				if ($parent.find('input[checked=checked]').length > 0) {
					$parent.find('.valid').removeClass('wrong').addClass('correct');
				} else {
					$parent.find('.valid').removeClass('correct').addClass('wrong');
				}
			},

			'.cityMatchItem click': function (el, ev) {
				var _id = el.data('_id');

				var $wrapper = el.parents('.question');

				$wrapper.find('input[name=city]').val(el.html());
				$wrapper.find('input[name=city_id]').val(_id);

				appState.attr('cityMatches', null);
			},

			'input.network keyup': function (el, ev) {
				var text = el.val();

				if (text.length > 2) {
					var matches = _.filter(appState.attr('networks').attr(), function (network) {
						return network.name.toLowerCase().indexOf(text.toLowerCase()) > -1;
					});

					if (matches.length > 0) {
						appState.attr('networkMatches', matches);
					} else {
						appState.attr('networkMatches', null);
					}
				} else {
					appState.attr('networkMatches', null);
				}
			},

			'.networkMatchItem click': function (el, ev) {
				var _id = el.data('_id');

				var $wrapper = el.parents('.question');

				$wrapper.find('input[name=network]').val(el.html());
				$wrapper.find('input[name=network_id]').val(_id);

				appState.attr('networkMatches', null);
			},

			'input.switcher click': function (el, ev) {
				var $parent = el.parents('.questionContainer');
				var $child = $parent.next();

				var $otherBlocks = $child.find('.questionWrap').not('[data-question_value='+el.data('value')+']');
				var $blockToShow = $child.find('[data-question_value='+el.data('value')+']');

				if ($blockToShow.css('display') == 'none') {
					$otherBlocks.velocity('slideUp', function(){
						$blockToShow.velocity('slideDown');
					});
				}
			},

			'input.validateChild click': function (el, ev) {
				var $parent = el.parents('.questionContainer');
				var $child = $parent.next();

				var $childBlock = $child.find('[data-question_value='+el.data('value')+']');
				var $otherBlocks = $child.find('.questionWrap').not('[data-question_value='+el.data('value')+']');

				$childBlock.find('.question.validate').append('

');
				$otherBlocks.find('.wrong').remove();
			}
		});

	}
);<commit_msg>bday fix2<commit_after>'use strict';

define([
	'canjs',
	'core/appState',
	'app/simplePage/simplePageModel',
	'underscore',
	'core/helpers/preloader',
	'velocity',
	'social/vk/vk_sdk',
	'social/fb/fb_sdk',
	'css!app/simplePage/css/simplePage.css'
],
	function (can, appState, SimplePageModel, _) {

		return can.Control.extend({
			defaults: {
				viewpath: 'app/simplePage/',
				alternateViewpath: 'app/simplePage/alternateViews/',

				loadingInterval: 15,
				vkLoginPermission: '', //4 - photos
				facebookPermissions: 'email,user_birthday'
			}
		}, {
			init: function () {
				var self = this;

				var simplePage = self.getSimplePage();

				var viewfile =
					simplePage.alternate_view_path.length > 0 ?
					self.options.alternateViewpath + simplePage.alternate_view_path + '.stache' :
					self.options.viewpath + 'index.stache';

				self.element.html(
					can.view(viewfile, {
						simplePage: simplePage,
						appState: appState
					})
				);

				if (self.options.isReady) {
					self.options.isReady.resolve();
					$(window).scrollTop(0);
				}
			},

			getSimplePage: function () {
				var id = this.options.data.id;
				return _.find(appState.attr('simplePages'), function(element) {
					return element.url == id;
				});
			},

			'.socNets.fb click': function (el, ev) {
				var self = this;

				FB.login(can.proxy(self.fbLoginResponse, self), {
					scope: self.options.facebookPermissions
				});
			},

			fbLoginResponse: function (response) {
				var self = this;

				if (response.status === 'connected') {

					FB.api('/me', function(userResponse) {

						FB.api("/me/picture?width=180&height=180",  function(imageResponse) {
							self.saveUser(userResponse.first_name, userResponse.last_name, imageResponse.data.url, userResponse, null);
						});
					});

				} else if (response.status === 'not_authorized') {
					// The person is logged into Facebook, but not your app.
				} else {
					// The person is not logged into Facebook, so we're not sure if
					// they are logged into this app or not.
				}
			},

			'.socNets.vk click': function (el, ev) {
				var self = this;

				VK.Auth.login(can.proxy(self.vkLoginResponse, self), self.options.vkLoginPermission);
			},

			vkLoginResponse: function (response) {
				var self = this;

				if (response.session) {

					VK.api("getProfiles", {
						uids: response.session.mid,
						fields: 'bdate,city'
					}, function (profileData){

						if (profileData.response && profileData.response[0]){
							self.saveUser(profileData.response[0].first_name, profileData.response[0].last_name, profileData.response[0].photo_200, null, profileData.response[0]);
						}
					});

				} else {
					alert('not auth');
				}
			},

			'.socNets.od click': function (el, ev) {
				window.location = '/auth/odnoklassniki';
			},

			saveUser: function (name, surname, image, fbProfile, vkProfile) {
				appState.attr('user.facebook', fbProfile);
				appState.attr('user.vk', vkProfile);
				appState.attr('user.username', name);
				appState.attr('user.lastName', surname);
				appState.attr('user.image', image);

				if (appState.attr('user.odnoklassniki')) {
					if ( appState.attr('user.odnoklassniki.birthday') ) {
						var od_bd = appState.attr('user.odnoklassniki.birthday').split('-');
						var birthday = [od_bd[2],od_bd[1],od_bd[0]];
						appState.attr('user.birthday', birthday);
					}
				} else if (appState.attr('user.vk')) {
					if ( appState.attr('user.vk.bdate') ) {
						var vk_bd = appState.attr('user.vk.bdate').split('.');
						appState.attr('user.birthday', vk_bd);
					}
				} else if (appState.attr('user.facebook')) {
					if (appState.attr('user.facebook.birthday')) {
						var fb_bd = appState.attr('user.facebook.birthday').split('/');
						appState.attr('user.birthday', [fb_bd[1],fb_bd[0],fb_bd[2]]);
					}
					if ( appState.attr('user.facebook.email') ) {
						appState.attr('user.email', appState.attr('user.facebook.email'));
					}
				}

				can.route.attr({
					module: 'simplePage',
					id: 'personal-form'
				}, true);
			},

			'.radioButton click': function (el, ev) {
				if (!el.hasClass('activeBtn')) {
					var $wrapper = el.parents('.radioWrapper');
					var $active = $wrapper.find('.activeBtn');
					var activeValue = $active.data('value');
					var $activeInput = $wrapper.find('input[value='+activeValue+']');

					$activeInput.attr('checked', false);
					$active.removeClass('activeBtn');

					var newActiveValue = el.data('value');
					var $newActiveInput = $wrapper.find('input[value='+newActiveValue+']');

					$newActiveInput.attr('checked', true);
					el.addClass('activeBtn');
				}
			},

			'.checkboxButton click': function (el, ev) {

				var $wrapper = el.parents('.checkboxWrapper');
				var buttonValue = el.data('value');
				var $checkboxInput = $wrapper.find('input[value='+buttonValue+']');

				if (el.hasClass('activeBtn')) {
					$checkboxInput.attr('checked', false);
					el.removeClass('activeBtn');
				} else {
					$checkboxInput.attr('checked', true);
					el.addClass('activeBtn');
				}
			},

			'.personalData submit': function (el, ev) {
				ev.preventDefault();

				var self = this;

				if ( el.find('.wrong').length == 0 ) {
					el.find('input[type=submit]').removeClass('validationFailure');
					var formData = can.deparam(el.serialize());

					if ( appState.attr('user._id') != null ) {
						formData._id = appState.attr('user._id');
					} else if ( appState.attr('user.facebook') != null ) {
						formData.facebook = appState.attr('user.facebook').attr();
					} else if ( appState.attr('user.vk') != null) {
						formData.vk = appState.attr('user.vk').attr();
					} else if ( appState.attr('user.odnoklassniki') != null) {
						formData.odnoklassniki = appState.attr('user.odnoklassniki').attr();
					}

					var simplePage = new SimplePageModel(formData);

					simplePage.save()
						.done(function() {
							can.route.attr({
								module: 'simplePage',
								id: 'questions-form'
							}, true);
						})
						.fail(function (data) {
							console.error(data);
						});
				} else {
					el.find('input[type=submit]').addClass('validationFailure');
				}
			},

			'.questionsForm submit': function (el, ev) {

				ev.preventDefault();

				var self = this;

				if ( el.find('.wrong').length == 0 ) {
					el.find('input[type=submit]').removeClass('validationFailure');
					var formData = can.deparam(el.serialize());

					if ( appState.attr('user._id') != null ) {
						formData._id = appState.attr('user._id');
					} else if ( appState.attr('user.facebook') != null ) {
						formData.facebook = appState.attr('user.facebook').attr();
					} else if ( appState.attr('user.vk') != null) {
						formData.vk = appState.attr('user.vk').attr();
					} else if ( appState.attr('user.odnoklassniki') != null) {
						formData.odnoklassniki = appState.attr('user.odnoklassniki').attr();
					}

					var simplePage = new SimplePageModel(formData);

					simplePage.save()
						.done(function() {
							can.route.attr({
								module: 'simplePage',
								id: 'gratitude'
							}, true);
						})
						.fail(function (data) {
							console.error(data);
						});
				} else {
					el.find('input[type=submit]').addClass('validationFailure');
				}
			},

			'.sendEmail submit': function (el, ev) {
				ev.preventDefault();

				if ( el.find('input[type=email]').val().length > 0 ) {
					var formData = can.deparam(el.serialize());

					if ( appState.attr('user._id') != null ) {
						formData._id = appState.attr('user._id');
					}

					var simplePage = new SimplePageModel(formData);

					simplePage.save()
						.done(function(data) {
							console.log(data);
							appState.attr('user._id', data._id);
							can.route.attr({
								module: 'simplePage',
								id: 'personal-form'
							}, true);
						})
						.fail(function (data) {
							console.error(data);
						});
				}
			},

			'.quesBtn click': function (el, ev) {
				var $parent = el.parents('.parentQuestion');

				if (el.hasClass('showChild')) {
					var $child = $parent.next();

					if ($child.hasClass('childQuestion')) {
						$child.velocity('slideDown');
					}
				} else if ($parent.find('.showChild').length > 0) {
					var $child = $parent.next();

					if ($child.hasClass('childQuestion')) {
						$child.velocity('slideUp');
					}
				}
			},

			'input.validate keyup': function (el, ev) {
				this.textValidate(el);
			},

			'textarea keyup': function (el, ev) {
				this.textValidate(el);
			},

			textValidate: function (el) {
				if (el.val().length > 0) {
					el.parents('.question').find('.valid').removeClass('wrong').addClass('correct');
				} else if ( el.val().length == 0 ) {
					el.parents('.question').find('.valid').removeClass('correct').addClass('wrong');
				}
			},

			'input.city keyup': function (el, ev) {
				var text = el.val();

				if (text.length > 2) {
					var matches = _.filter(appState.attr('cities').attr(), function (city) {
						return city.name.toLowerCase().indexOf(text.toLowerCase()) > -1;
					});

					if (matches.length > 0) {
						appState.attr('cityMatches', matches);
					} else {
						appState.attr('cityMatches', null);
					}
				} else {
					appState.attr('cityMatches', null);
				}
			},

			'input.radioValidate click': function (el, ev) {
				el.parents('.question').find('.valid').removeClass('wrong').addClass('correct');
			},

			'input.checkboxValidate click': function (el, ev) {
				var $parent = el.parents('.question');
				console.log($parent.find('input[checked=checked]').length);
				if ($parent.find('input[checked=checked]').length > 0) {
					$parent.find('.valid').removeClass('wrong').addClass('correct');
				} else {
					$parent.find('.valid').removeClass('correct').addClass('wrong');
				}
			},

			'.cityMatchItem click': function (el, ev) {
				var _id = el.data('_id');

				var $wrapper = el.parents('.question');

				$wrapper.find('input[name=city]').val(el.html());
				$wrapper.find('input[name=city_id]').val(_id);

				appState.attr('cityMatches', null);
			},

			'input.network keyup': function (el, ev) {
				var text = el.val();

				if (text.length > 2) {
					var matches = _.filter(appState.attr('networks').attr(), function (network) {
						return network.name.toLowerCase().indexOf(text.toLowerCase()) > -1;
					});

					if (matches.length > 0) {
						appState.attr('networkMatches', matches);
					} else {
						appState.attr('networkMatches', null);
					}
				} else {
					appState.attr('networkMatches', null);
				}
			},

			'.networkMatchItem click': function (el, ev) {
				var _id = el.data('_id');

				var $wrapper = el.parents('.question');

				$wrapper.find('input[name=network]').val(el.html());
				$wrapper.find('input[name=network_id]').val(_id);

				appState.attr('networkMatches', null);
			},

			'input.switcher click': function (el, ev) {
				var $parent = el.parents('.questionContainer');
				var $child = $parent.next();

				var $otherBlocks = $child.find('.questionWrap').not('[data-question_value='+el.data('value')+']');
				var $blockToShow = $child.find('[data-question_value='+el.data('value')+']');

				if ($blockToShow.css('display') == 'none') {
					$otherBlocks.velocity('slideUp', function(){
						$blockToShow.velocity('slideDown');
					});
				}
			},

			'input.validateChild click': function (el, ev) {
				var $parent = el.parents('.questionContainer');
				var $child = $parent.next();

				var $childBlock = $child.find('[data-question_value='+el.data('value')+']');
				var $otherBlocks = $child.find('.questionWrap').not('[data-question_value='+el.data('value')+']');

				$childBlock.find('.question.validate').append('

');
				$otherBlocks.find('.wrong').remove();
			}
		});

	}
);<|endoftext|>


<commit_before>/*
	Width management tool for responsive designs

	Author
		Aurélien Delogu (dev@dreamysource.fr)

	Some readings
		http://www.alistapart.com/articles/fontresizing/
		http://tripleodeon.com/2011/12/first-understand-your-screen/

	Notes
		Thanks to Lawrence Carvalho (carvalho@uk.yahoo-inc.com) for his useful TextResizeDetector script :)
*/

;(function(context,name,definition){
	if(typeof module!='undefined' && module.exports){
		module.exports=definition;
	}
	else if(typeof define=='function' && define.amd){
		define(definition);
	}
	else{
		context[name]=definition;
	}
}(this,'W',function(){

	// Prepare
	var win=window,
		doc=document,
		html=doc.documentElement,
		a,b,
		textElement,
		textHeight,
		listeners=[],
		trigger=false,
		unit,
		absolute_mode=false,
		refreshUnit=function(){
			a=doc.createElement('div');
			a.style.width='1em';
			html.appendChild(a);
			unit=a.offsetWidth;
			unit=unit?unit:16;
			html.removeChild(a);
		},
		getOrientation=function(){
			if('orientation' in window){
				return !window.orientation?'portrait':'landscape';
			}
			else{
				return html.clientWidth>html.clientHeight?'landscape':'portrait';
			}
		};
	refreshUnit();

	// Catch window resize event
	if(win.addEventListener){
		if('onorientationchange' in win){
			win.addEventListener('orientationchange',function(){
				trigger=true;
			},false);
		}
		else{
			win.addEventListener('resize',function(){
				trigger=true;
			},false);
		}
	}
	else{
		win.attachEvent('onresize',function(){
			trigger=true;
		});
	}

	// Initialize the text element to catch text resizes
	textElement=doc.createElement('b');
	textElement.style.position='absolute';
	textElement.style.top='-99em';
	textElement.innerHTML='W';
	html.appendChild(textElement);
	textHeight=textElement.offsetHeight;

	// Verify resizes every 250ms
	setInterval(function(){
		// Verify text element state
		a=textElement.offsetHeight;
		if(a!=textHeight){
			trigger=true;
		}
		textHeight=a;
		// Text has been resized
		if(trigger && html.clientWidth){
			refreshUnit();
			for(var i=0,j=listeners.length;i<j;++i){
				listeners[i]();
			}
			trigger=false;
		}
	},250);

	// Viewport resolution detection
	function detectViewport(){
		// Prepare
		var screen_width,
			screen_height,
			values=[
				{width:screen.availWidth,height:screen.availHeight},
				{width:window.outerWidth,height:window.outerHeight},
				{width:window.innerWidth,height:window.innerHeight}
			],
			notes=[],
			i,j;
		// Detect right screen resolution from orientation
		if(/(iPad|iPhone|iPod)/g.test(navigator.userAgent) && getOrientation()=='landscape'){
			screen_width=screen.height;
			screen_height=screen.width;
		}
		else{
			screen_width=screen.width;
			screen_height=screen.height;
		}
		// Absolute mode
		if(absolute_mode){
			return {
				width: screen_width,
				height: screen_height
			};
		}
		// Relative mode
		else{
			// Apply rules
			for(i=0,j=values.length;i<j;++i){
				if(values[i].width>screen_width || values[i].height>screen_height || !values[i].width || !values[i].height){
					values[i].note=0;
				}
				else if(values[i].width<screen_width || values[i].height<screen_height){
					values[i].note=2+(screen_width-values[i].width)+(screen_height-values[i].height);
				}
				else{
					values[i].note=1;
				}
			}
			// Sort notes
			values.sort(function(a,b){
				return b.note-a.note;
			});
			// Return the better value
			return {
				width: values[0].width,
				height: values[0].height
			};
		}
	}

	// Define W object
	return {
		px2em: function(px){
			return px/unit;
		},
		getViewportWidth: function(){
			return detectViewport().width;
		},
		getViewportHeight: function(){
			return detectViewport().height;
		},
		addListener: function(func){
			listeners.push(func);
			return func;
		},
		setAbsoluteMode: function(flag){
			absolute_mode=!!flag;
		},
		getOrientation: function(){
			return getOrientation();
		}
	};

}()));<commit_msg>Update header<commit_after>/* W 1.2.2 (https://github.com/pyrsmk/W) */

;(function(context,name,definition){
	if(typeof module!='undefined' && module.exports){
		module.exports=definition;
	}
	else if(typeof define=='function' && define.amd){
		define(definition);
	}
	else{
		context[name]=definition;
	}
}(this,'W',function(){

	// Prepare
	var win=window,
		doc=document,
		html=doc.documentElement,
		a,b,
		textElement,
		textHeight,
		listeners=[],
		trigger=false,
		unit,
		absolute_mode=false,
		refreshUnit=function(){
			a=doc.createElement('div');
			a.style.width='1em';
			html.appendChild(a);
			unit=a.offsetWidth;
			unit=unit?unit:16;
			html.removeChild(a);
		},
		getOrientation=function(){
			if('orientation' in window){
				return !window.orientation?'portrait':'landscape';
			}
			else{
				return html.clientWidth>html.clientHeight?'landscape':'portrait';
			}
		};
	refreshUnit();

	// Catch window resize event
	if(win.addEventListener){
		if('onorientationchange' in win){
			win.addEventListener('orientationchange',function(){
				trigger=true;
			},false);
		}
		else{
			win.addEventListener('resize',function(){
				trigger=true;
			},false);
		}
	}
	else{
		win.attachEvent('onresize',function(){
			trigger=true;
		});
	}

	// Initialize the text element to catch text resizes
	textElement=doc.createElement('b');
	textElement.style.position='absolute';
	textElement.style.top='-99em';
	textElement.innerHTML='W';
	html.appendChild(textElement);
	textHeight=textElement.offsetHeight;

	// Verify resizes every 250ms
	setInterval(function(){
		// Verify text element state
		a=textElement.offsetHeight;
		if(a!=textHeight){
			trigger=true;
		}
		textHeight=a;
		// Text has been resized
		if(trigger && html.clientWidth){
			refreshUnit();
			for(var i=0,j=listeners.length;i<j;++i){
				listeners[i]();
			}
			trigger=false;
		}
	},250);

	// Viewport resolution detection
	function detectViewport(){
		// Prepare
		var screen_width,
			screen_height,
			values=[
				{width:screen.availWidth,height:screen.availHeight},
				{width:window.outerWidth,height:window.outerHeight},
				{width:window.innerWidth,height:window.innerHeight}
			],
			notes=[],
			i,j;
		// Detect right screen resolution from orientation
		if(/(iPad|iPhone|iPod)/g.test(navigator.userAgent) && getOrientation()=='landscape'){
			screen_width=screen.height;
			screen_height=screen.width;
		}
		else{
			screen_width=screen.width;
			screen_height=screen.height;
		}
		// Absolute mode
		if(absolute_mode){
			return {
				width: screen_width,
				height: screen_height
			};
		}
		// Relative mode
		else{
			// Apply rules
			for(i=0,j=values.length;i<j;++i){
				if(values[i].width>screen_width || values[i].height>screen_height || !values[i].width || !values[i].height){
					values[i].note=0;
				}
				else if(values[i].width<screen_width || values[i].height<screen_height){
					values[i].note=2+(screen_width-values[i].width)+(screen_height-values[i].height);
				}
				else{
					values[i].note=1;
				}
			}
			// Sort notes
			values.sort(function(a,b){
				return b.note-a.note;
			});
			// Return the better value
			return {
				width: values[0].width,
				height: values[0].height
			};
		}
	}

	// Define W object
	return {
		px2em: function(px){
			return px/unit;
		},
		getViewportWidth: function(){
			return detectViewport().width;
		},
		getViewportHeight: function(){
			return detectViewport().height;
		},
		addListener: function(func){
			listeners.push(func);
			return func;
		},
		setAbsoluteMode: function(flag){
			absolute_mode=!!flag;
		},
		getOrientation: function(){
			return getOrientation();
		}
	};

}()));<|endoftext|>


<commit_before>/*
---
name: ART.Browser
description: A window with navigation controls.
requires: [ART.Window, ART.History]
provides: ART.Browser
...
*/

ART.Sheet.define('window.art.browser', {
	'header-height': 60,
	'header-overflow': 'visible'
});

ART.Sheet.define('window.art.browser history.art', {
	'padding': [0, 8, 0, 10]
});

ART.Sheet.define('window.art.browser:hidden history.art', {
	'padding': [0, 8, 0, 10],
	'display':'none'
}, 'css');

ART.Sheet.define('window.art.browser history.art', {
	'top':30,
	'position': 'absolute'
}, 'css');

ART.Sheet.define('window.art.browser history.art button.art', {
	'shadow-color': hsb(0, 0, 100, 0.4)
});

ART.Sheet.define('window.art.browser:dragging history.art', {
	'display': 'none'
}, 'css');

ART.Sheet.define('window.art.browser history.art', {
	'display': 'block'
}, 'css');

ART.Sheet.define('window.art.browser history.art divot', {
	'color': hsb(0, 0, 66)
});
ART.Sheet.define('window.art.browser:focused history.art divot', {
	'color': hsb(0, 0, 33)
});

ART.Browser = new Class({

	Extends: ART.Window,

	options: {
		className: 'art browser',
		historyOptions: {
			editable: false
		}
	},

	_build: function(){
		this.parent.apply(this, arguments);
		var styles = this.getSheet();
		this.history = new ART.History(
			$merge(this.options.historyOptions, {
				styles: {
					width: styles.width
				}
			})
		).inject(this, this.header);
		this.header.setStyles({
			'overflow': styles.headerOverflow
		});
		this.addEvents({
			shade: function() {
				this._dragging = true;
			},
			unshade: function(){
				this._dragging = false;
				this.history.resize(this.currentWidth);
			},
			focus: function(){
				this.history.enable();
			},
			blur: function(){
				this.history.disable();
			},
			minimize: function(){
				this.history.resize(this.currentWidth);
			},
			maximize: function(){
				this.history.resize(this.currentWidth);
			}
		});
	}

});

ART.WindowTools.implement({

	getHistory: function() {
		return this.getWindow().history;
	}

});<commit_msg>have to introduce a delay for resizing history while the window draws itself.<commit_after>/*
---
name: ART.Browser
description: A window with navigation controls.
requires: [ART.Window, ART.History]
provides: ART.Browser
...
*/

ART.Sheet.define('window.art.browser', {
	'header-height': 60,
	'header-overflow': 'visible'
});

ART.Sheet.define('window.art.browser history.art', {
	'padding': [0, 8, 0, 10]
});

ART.Sheet.define('window.art.browser:hidden history.art', {
	'padding': [0, 8, 0, 10],
	'display':'none'
}, 'css');

ART.Sheet.define('window.art.browser history.art', {
	'top':30,
	'position': 'absolute'
}, 'css');

ART.Sheet.define('window.art.browser history.art button.art', {
	'shadow-color': hsb(0, 0, 100, 0.4)
});

ART.Sheet.define('window.art.browser:dragging history.art', {
	'display': 'none'
}, 'css');

ART.Sheet.define('window.art.browser history.art', {
	'display': 'block'
}, 'css');

ART.Sheet.define('window.art.browser history.art divot', {
	'color': hsb(0, 0, 66)
});
ART.Sheet.define('window.art.browser:focused history.art divot', {
	'color': hsb(0, 0, 33)
});

ART.Browser = new Class({

	Extends: ART.Window,

	options: {
		className: 'art browser',
		historyOptions: {
			editable: false
		}
	},

	_build: function(){
		this.parent.apply(this, arguments);
		var styles = this.getSheet();
		this.history = new ART.History(
			$merge(this.options.historyOptions, {
				styles: {
					width: styles.width
				}
			})
		).inject(this, this.header);
		this.header.setStyles({
			'overflow': styles.headerOverflow
		});

		var sizerTimer;
		var sizer = function(){
			//have to delay here because this.currentWidth isn't defined
			//until after draw, which is also delayed
			$clear(sizerTimer);
			sizerTimer = (function(){
				this.history.resize(this.currentWidth);
			}).delay(1, this);
		}.bind(this);
		this.addEvents({
			shade: function() {
				this._dragging = true;
			},
			unshade: function(){
				this._dragging = false;
				sizer();
			},
			focus: function(){
				this.history.enable();
			},
			blur: function(){
				this.history.disable();
			},
			minimize: sizer,
			maximize: sizer,
			resize: sizer,
			show: sizer
		});
	}

});

ART.WindowTools.implement({

	getHistory: function() {
		return this.getWindow().history;
	}

});<|endoftext|>