<commit_before>/* See license.txt for terms of usage */
FBL.ns(function() { with (FBL) {

// ************************************************************************************************
// Constants

const Cc = Components.classes;
const Ci = Components.interfaces;

const prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch2);

// ************************************************************************************************

// Register string bundle of this extension so, $STR method (implemented by Firebug)
// can be used. Also, perform the registration here so, localized strings used
// in template definitions can be resolved.
Firebug.registerStringBundle("chrome://selectbug/locale/selectbug.properties");

// ************************************************************************************************


/**
 * @panel Selector side panel displaying HTML elements for the current selector,
 * either from the CSS main panel or user entry
 */
function SelectorPanel() {}
SelectorPanel.prototype = extend(Firebug.Panel,
/** @lends SelectorPanel */
{
    name: 'selection',
    parentPanel: 'stylesheet',
    title: $STR("selectbug.Selection"),
    editable: true,

    initialize: function(context, doc)
    {
        Firebug.Panel.initialize.apply(this, arguments);
    },

    initializeNode: function(oldPanelNode)
    {
        Firebug.Panel.initializeNode.apply(this, arguments);

        appendStylesheet(this.panelNode.ownerDocument, "chrome://selectbug/skin/selectbug.css");
        appendStylesheet(this.mainPanel.panelNode.ownerDocument, "chrome://selectbug/skin/selectbug.css");

        this.setSelection = bind(this.setSelection, this);
        this.clearSelection = bind(this.clearSelection, this);
        this.lockSelection = bind(this.lockSelection, this);
        this.mainPanel.panelNode.addEventListener("mouseover", this.setSelection, false);
        this.mainPanel.panelNode.addEventListener("mouseout", this.clearSelection, false);
        this.mainPanel.panelNode.addEventListener("mousedown", this.lockSelection, false);
    },

    destroyNode: function()
    {
        this.mainPanel.panelNode.removeEventListener("mouseover", this.setSelection, false);
        this.mainPanel.panelNode.removeEventListener("mouseout", this.clearSelection, false);
        this.mainPanel.panelNode.removeEventListener("mousedown", this.lockSelection, false);
        Firebug.Panel.destroyNode.apply(this, arguments);
    },

    show: function(state)
    {
        Firebug.Panel.show.apply(this, arguments);
        this.refresh();
    },

    getCSSStyleRule: function(event)
    {
        var object = Firebug.getRepObject(event.target);
        if(object && (object instanceof CSSStyleRule))
            return object;
    },

    getCSSRuleElement: function(element)
    {
        while(element && !element.classList.contains("cssRule"))
            element = element.parentNode;

        return element;
    },

    setSelection: function(event)
    {
        var rule = this.getCSSStyleRule(event);
        if (rule) // then we have entered a rule element
        {
            var ruleElement = this.getCSSRuleElement(event.target);
            if (ruleElement && ruleElement !== this.lockedElement)
                ruleElement.classList.add("selectedSelectorRule");

            this.selection = rule;
            this.rebuild();
        }
    },

    clearSelection: function(event)
    {
        if (this.selection !== this.lockedSelection)
        {
            this.selection = this.lockedSelection;
            this.rebuild();
        }

        var rule = this.getCSSStyleRule(event);
        if (rule)  // then we are leaving a rule element that we may have highlighted.
        {
            var ruleElement = this.getCSSRuleElement(event.target);
            if (ruleElement)
                ruleElement.classList.remove("selectedSelectorRule");
        }
    },

    lockSelection: function(event)
    {
        var rule = this.getCSSStyleRule(event);
        if (rule)
        {
            if (this.lockedElement)
                this.lockedElement.classList.remove("lockedSelectorRule");

            this.lockedElement = this.getCSSRuleElement(event.target);

            if (this.lockedElement)
            {
                this.lockedElement.classList.add("lockedSelectorRule");
                this.lockedElement.classList.remove("selectedSelectorRule");
            }

            this.lockedSelection = rule;
        }
    },

    hide: function()
    {
        Firebug.Panel.hide.apply(this, arguments);
    },

    refresh: function()
    {
        var root = this.context.window.document.documentElement;
        this.selection = this.mainPanel.selection;
        this.rebuild(true);
    },

    /**
     * returns an array of Elements matched from selector
     */
    getSelectedElements: function(selectorText)
    {
        var selections = Firebug.currentContext.window.document.querySelectorAll(selectorText);
        if (selections instanceof NodeList)
            return selections;
        else
            throw new Error("Selection Failed: "+selections);
    },

    /**
     * Build content of the panel. The basic layout of the panel is generated by
     * {@link SelectorTemplate} template.
     */
    rebuild: function()
    {
        if (this.selection)
        {
            try
            {
                if (this.selection instanceof CSSStyleRule)
                    var selectorText = this.selection.selectorText;
                else
                    var selectorText = this.selection;

                var elements = this.getSelectedElements(selectorText);
                if (elements && elements.length)
                {
                    SelectorTemplate.tag.replace({object: elements}, this.panelNode);
                    this.showTrialSelector(this.trialSelector);
                    return;
                }
            }
            catch(e)
            {
                var table = SelectorTemplate.tag.replace({object: []}, this.panelNode);
                var tbody = table.lastChild;
                WarningTemplate.selectErrorTag.insertRows({object: e}, tbody.lastChild);
                WarningTemplate.selectErrorTextTag.insertRows({object: e}, tbody.lastChild);
                this.showTrialSelector(this.trialSelector);
                return;
            }
        }

        var table = SelectorTemplate.tag.replace({object: []}, this.panelNode);
        var tbody = table.lastChild;

        if (this.trialSelector)
            WarningTemplate.noSelectionResultsTag.insertRows({object: this.selection}, tbody.lastChild)
        else
            WarningTemplate.noSelectionTag.insertRows({object: this.selection}, tbody.lastChild);

        this.showTrialSelector(this.trialSelector);<commit_msg>Issue 5442 (Hovering a CSS rule fails to show a list of matched elements) http://code.google.com/p/fbug/issues/detail?id=5442<commit_after>/* See license.txt for terms of usage */
FBL.ns(function() { with (FBL) {

// ************************************************************************************************
// Constants

const Cc = Components.classes;
const Ci = Components.interfaces;

const prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch2);

// ************************************************************************************************

// Register string bundle of this extension so, $STR method (implemented by Firebug)
// can be used. Also, perform the registration here so, localized strings used
// in template definitions can be resolved.
Firebug.registerStringBundle("chrome://selectbug/locale/selectbug.properties");

// ************************************************************************************************


/**
 * @panel Selector side panel displaying HTML elements for the current selector,
 * either from the CSS main panel or user entry
 */
function SelectorPanel() {}
SelectorPanel.prototype = extend(Firebug.Panel,
/** @lends SelectorPanel */
{
    name: 'selection',
    parentPanel: 'stylesheet',
    title: $STR("selectbug.Selection"),
    editable: true,

    initialize: function(context, doc)
    {
        Firebug.Panel.initialize.apply(this, arguments);
    },

    initializeNode: function(oldPanelNode)
    {
        Firebug.Panel.initializeNode.apply(this, arguments);

        appendStylesheet(this.panelNode.ownerDocument, "chrome://selectbug/skin/selectbug.css");
        appendStylesheet(this.mainPanel.panelNode.ownerDocument, "chrome://selectbug/skin/selectbug.css");

        this.setSelection = bind(this.setSelection, this);
        this.clearSelection = bind(this.clearSelection, this);
        this.lockSelection = bind(this.lockSelection, this);
        this.mainPanel.panelNode.addEventListener("mouseover", this.setSelection, false);
        this.mainPanel.panelNode.addEventListener("mouseout", this.clearSelection, false);
        this.mainPanel.panelNode.addEventListener("mousedown", this.lockSelection, false);
    },

    destroyNode: function()
    {
        this.mainPanel.panelNode.removeEventListener("mouseover", this.setSelection, false);
        this.mainPanel.panelNode.removeEventListener("mouseout", this.clearSelection, false);
        this.mainPanel.panelNode.removeEventListener("mousedown", this.lockSelection, false);
        Firebug.Panel.destroyNode.apply(this, arguments);
    },

    show: function(state)
    {
        Firebug.Panel.show.apply(this, arguments);
        this.refresh();
    },

    getCSSStyleRule: function(event)
    {
        var object = Firebug.getRepObject(event.target);
        if(object && (object instanceof CSSStyleRule))
            return object;
    },

    getCSSRuleElement: function(element)
    {
        while(element && !element.classList.contains("cssRule"))
            element = element.parentNode;

        return element;
    },

    setSelection: function(event)
    {
        var rule = this.getCSSStyleRule(event);
        if (rule) // then we have entered a rule element
        {
            var ruleElement = this.getCSSRuleElement(event.target);
            if (ruleElement && ruleElement !== this.lockedElement)
                ruleElement.classList.add("selectedSelectorRule");

            this.selection = rule;
            this.rebuild();
        }
    },

    clearSelection: function(event)
    {
        if (this.selection !== this.lockedSelection)
        {
            this.selection = this.lockedSelection;
            this.rebuild();
        }

        var rule = this.getCSSStyleRule(event);
        if (rule)  // then we are leaving a rule element that we may have highlighted.
        {
            var ruleElement = this.getCSSRuleElement(event.target);
            if (ruleElement)
                ruleElement.classList.remove("selectedSelectorRule");
        }
    },

    lockSelection: function(event)
    {
        var rule = this.getCSSStyleRule(event);
        if (rule)
        {
            if (this.lockedElement)
                this.lockedElement.classList.remove("lockedSelectorRule");

            this.lockedElement = this.getCSSRuleElement(event.target);

            if (this.lockedElement)
            {
                this.lockedElement.classList.add("lockedSelectorRule");
                this.lockedElement.classList.remove("selectedSelectorRule");
            }

            this.lockedSelection = rule;
        }
    },

    hide: function()
    {
        Firebug.Panel.hide.apply(this, arguments);
    },

    refresh: function()
    {
        var root = this.context.window.document.documentElement;
        this.selection = this.mainPanel.selection;
        this.rebuild(true);
    },

    /**
     * returns an array of Elements matched from selector
     */
    getSelectedElements: function(selectorText)
    {
        var selections = Firebug.currentContext.window.document.querySelectorAll(selectorText);

        // For some reason the return value of querySelectorAll()
        // is not recognized as a NodeList anymore since Firefox 10.0.
        // See issue 5442.
        if (selections)
        {
            var elements = [];
            for (var i = 0; i < selections.length; ++i)
              elements.push(selections[i]);

            return elements;
        }
        else
        {
            throw new Error("Selection Failed: "+selections);
        }
    },

    /**
     * Build content of the panel. The basic layout of the panel is generated by
     * {@link SelectorTemplate} template.
     */
    rebuild: function()
    {
        if (this.selection)
        {
            try
            {
                if (this.selection instanceof CSSStyleRule)
                    var selectorText = this.selection.selectorText;
                else
                    var selectorText = this.selection;

                var elements = this.getSelectedElements(selectorText);
                if (elements && elements.length != 0)
                {
                    SelectorTemplate.tag.replace({object: elements}, this.panelNode);
                    this.showTrialSelector(this.trialSelector);
                    return;
                }
            }
            catch(e)
            {
                var table = SelectorTemplate.tag.replace({object: []}, this.panelNode);
                var tbody = table.lastChild;
                WarningTemplate.selectErrorTag.insertRows({object: e}, tbody.lastChild);
                WarningTemplate.selectErrorTextTag.insertRows({object: e}, tbody.lastChild);
                this.showTrialSelector(this.trialSelector);
                return;
            }
        }

        var table = SelectorTemplate.tag.replace({object: []}, this.panelNode);
        var tbody = table.lastChild;

        if (this.trialSelector)
            WarningTemplate.noSelectionResultsTag.insertRows({object: this.selection}, tbody.lastChild)
        else
            WarningTemplate.noSelectionTag.insertRows({object: this.selection}, tbody.lastChild);

        this.showTrialSelector(this.trialSelector);
{'fraction_non_alphanumeric': 0.1428875336831655, 'fraction_numerical': 0.0014891504751099135, 'mean_word_length': 2.424720738222438, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '768177', 'n_tokens_mistral': 3631, 'n_tokens_neox': 3472, 'n_words': 725}