<commit_before>/*
 * Rapid Interface Builder (RIB) - A simple WYSIWYG HTML5 app creator
 * Copyright (c) 2011-2012, Intel Corporation.
 *
 * This program is licensed under the terms and conditions of the
 * Apache License, version 2.0.  The full text of the Apache License is at
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 */
"use strict";
// Property view widget

(function($, undefined) {

    $.widget('rib.propertyView', {

        options: {
            model: null,
        },

        _create: function() {
            var o = this.options,
                e = this.element;

            o.designReset = this._designResetHandler;
            o.selectionChanged = this._selectionChangedHandler;
            o.activePageChanged = this._activePageChangedHandler;
            o.modelUpdated = this._modelUpdatedHandler;

            // FIXME: This should work, but $.extend of options seems to be
            //        creating a copy of the ADM, which will not containt the
            //        same nodes and events as the master
            //o.model = o.model || ADM || undefined;
            if (o.model) {
                this._bindADMEvents(o.model);
            }

            this.element
                .addClass(this.widgetName)
                .append('
')
                .children(':last')
                .addClass('property_content');

            this.options.primaryTools = this._createPrimaryTools();
            this.options.secondaryTools = this._createSecondaryTools();
            $(window).resize(this, function(event) {
                var el = event.data.element;
                if (el.parent().height() == 0)
                    return;

                var newHeight = Math.round((el.parent().height()
                                - el.parent().find('.pageView').height()
                                - el.parent().find('.property_title')
                                      .height()
                                - 20) // height of ui-state-default + borders
                                * 0.4);
                el.height(newHeight);
            });

            this.refresh(null, this);

            return this;
        },

        _setOption: function(key, value) {
            switch (key) {
                // Should this REALLY be done here, or plugin registration in
                // the "host"... using the functions mapped in widget options?
                case 'model':
                    this._unbindADMEvents();
                    this._bindADMEvents(value);
                    this.refresh(null, this);
                    break;
                default:
                    break;
            }
        },

        destroy: function() {
            // TODO: unbind any ADM event handlers
            $(this.element).find('.'+this.widgetName).remove();
            this.options.primaryTools.remove();
            this.options.secondaryTools.remove();
        },

        refresh: function(event, widget) {
            widget = widget || this;
            if (event) {
                if (event.node && !(event.name === "modelUpdated" &&
                    event.type === "nodeRemoved")) {
                    widget._showProperties(event);
                } else {
                    event.node = ADM.getActivePage();
                    widget._showProperties(event);
                }
            }
        },

        // Private functions
        _createPrimaryTools: function() {
            return $(null);
        },

        _createSecondaryTools: function() {
            return $(null);
        },

        _bindADMEvents: function(a) {
            var o = this.options,
                d = this.designRoot;

            if (a) {
                o.model = a;

                if (o.designReset) {
                    a.bind("designReset", o.designReset, this);
                }
                if (o.selectionChanged) {
                    a.bind("selectionChanged", o.selectionChanged, this);
                }
                if (o.activePageChanged) {
                    a.bind("activePageChanged", o.activePageChanged, this);
                }

                // Since model changed, need to call our designReset hander
                // to sync up the ADMDesign modelUpdated event handler
                if (o.designReset) {
                    o.designReset({design: a.getDesignRoot()}, this);
                }
            }
        },

        _unbindADMEvents: function() {
            var o = this.options,
                a = this.options.model,
                d = this.designRoot;

            // First unbind our ADMDesign modelUpdated handler, if any...
            if (d && o.modelUpdated) {
                d.designRoot.unbind("modelUpdated", o.modelUpdated, this);
            }

            // Now unbind all ADM model event handlers, if any...
            if (a) {
                if (o.designReset) {
                    a.unbind("designReset", o.designReset, this);
                }
                if (o.selectionChanged) {
                    a.unbind("selectionChanged", o.selectionChanged, this);
                }
                if (o.activePageChanged) {
                    a.unbind("activePageChanged", o.activePageChanged, this);
                }
            }
        },

        _designResetHandler: function(event, widget) {
            var d = event && event.design, o;

            widget = widget || this;
            o = widget.options;
            d = d || o.model.getDesignRoot();

            // Do nothing if the new ADMDesign equals our currently cached one
            if (d === widget.designRoot) {
                return;
            }

            // First, unbind existing modelUpdated hander, if any...
            if (widget.designRoot && o.modelUpdated) {
                widget.designRoot.unbind("modelUpdated", o.modelUpdated,widget);
            }

            // Next, bind to modelUpdated events from new ADMDesign, if any...
            if (d && o.modelUpdated) {
                d.bind("modelUpdated", o.modelUpdated, widget);
            }

            // Then, cache the new ADMDesign reference with this instance
            widget.designRoot = d;

            // Finally, redraw our view since the ADMDesign root has changed
            widget.refresh(event, widget);
        },

        _selectionChangedHandler: function(event, widget) {
            widget = widget || this;
            //in case current focus input item change event not triggered
            //we trigger it firstly
            $("input:focus").trigger('change');
            widget.refresh(event,widget);
        },

        _activePageChangedHandler: function(event, widget) {
            widget = widget || this;
            widget.refresh(event,widget);
        },

        _modelUpdatedHandler: function(event, widget) {
            widget = widget || this;
            widget.refresh(event,widget);
        },

        _showProperties: function(event) {
            var node = event.node,
                labelId, labelVal, valueId, valueVal, count,
                widget = this, type,  i, child, index, propType,
                p, props, options, code, o, propertyItems, label, value,
                title = this.element.parent().find('.property_title'),
                content = this.element.find('.property_content');

            // Clear the properties pane when nothing is selected
            if (node === null || node === undefined) {
                node = ADM.getActivePage();
                if (node === null || node === undefined) {
                    $('#property_content').empty()
                        .append('Nothing Selected');
                    return;
                }
            }

            type = node.getType();
            title.empty()
                .append('')
                .children(':first')
                    .addClass('title')
                    .text(BWidget.getDisplayLabel(type)+' Properties');
            content.empty()
                .append('

');
            propertyItems = content.find('div')
                .addClass("propertyItems");
            props = node.getProperties();
            options = node.getPropertyOptions();
            // iterate property of node
            for (p in props) {
                labelVal = p.replace(/_/g,'-');
                valueId = p+'-value';
                valueVal = props[p];
                propType = BWidget.getPropertyType(type, p);
                code = $('
')
                    .appendTo(propertyItems);
                label = $('').appendTo(code)
                    .attr('for', valueId)
                    .text(labelVal)
                    .addClass('title');
                value = $('
').appendTo(code);
                // display property of widget
                switch (propType) {
                    case "boolean":
                        $('<input type="checkbox"/>')
                            .attr('id', valueId)
                            .appendTo(value);

                        // initial value of checkbox
                        if ((node.getProperty (p) === true) ||
                            (node.getProperty (p) === "true")) {
                            $("#" + valueId).attr("checked", true);
                        }
                        break;
                    case "record-array":
                        $('
')
                            .attr('id', 'selectOption')
                            .attr('cellspacing', '5')
                            .appendTo(value);
                        var selectOption = value.find('#selectOption');
                        $('
')
                            .append('	')
                            .append(' Text 	')
                                .children().eq(1)
                                .addClass('title')
                                .end().end()
                            .append(' Value 	')
                                .children().eq(2)
                                .addClass('title')
                                .end().end()
                            .append('	')
                            .appendTo(selectOption);
                        for (i = 0; i< props[p].children.length; i ++){
                            child = props[p].children[i];
                            $('
').data('index', i)
                                .addClass("options")
                                .append('')
                                    .children().eq(0)
                                    .append('')
                                    .children(':first')
                                    .attr('src', "src/css/images/propertiesDragIconSmall.png")
                                    .end()
                                    .end().end()
                                .append('')
                                    .children().eq(1)
                                    .append('<input type="text"/>')
                                        .children().eq(0)
                                        .val(child.text)
                                        .addClass('title optionInput')
                                        .change(node, function (event) {
                                            index = $(this).parent().parent().data('index');
                                            props[p].children[index].text = $(this).val();
                                            node.fireEvent("modelUpdated",
                                                {type: "propertyChanged",
                                                 node: node,
                                                 property: p});
                                        })
                                        .end().end()
                                    .end().end()
                                .append('')
                                    .children().eq(2)
                                    .append('<input type="text"/>')
                                        .children().eq(0)
                                        .val(child.value)
                                        .addClass('title optionInput')
                                        .change(node, function (event) {
                                            index = $(this).parent().parent().data('index');
                                            props[p].children[index].value = $(this).val();
                                            node.fireEvent("modelUpdated",
                                                {type: "propertyChanged",
                                                 node: node,
                                                 property: p});
                                        })
                                        .end().end()
                                    .end().end()
                                .append('')
                                    .children().eq(3)
                                    .append('')
                                        .children(':first')
                                        .attr('src', "src/css/images/deleteButton_up.png")
                                        // add delete option handler
                                        .click(function(e) {
                                            try {
                                                index = $(this).parent().parent().data('index');
                                                props[p].children.splice(index, 1);
                                                node.fireEvent("modelUpdated",
                                                    {type: "propertyChanged",
                                                        node: node,
                                                    property: p});
                                            }
                                            catch (err) {
                                                console.error(err.message);
                                            }
                                            e.stopPropagation();
                                            return false;
                                        })
                                        .end()
                                    .end().end()
                               .appendTo(selectOption);
                        }

                        // add add items handler
                        $('+ add item')
                            .children(':first')
                            .addClass('rightLabel title')
                            .attr('id', 'addOptionItem')
                            .end()
                            .appendTo(value);
                        value.find('#addOptionItem')
                            .click(function(e) {
                                try {
                                    var optionItem = {};
                                    optionItem.text = "Option";
                                    optionItem.value = "Value";
                                    props[p].children.push(optionItem);
                                    node.fireEvent("modelUpdated",
                                                  {type: "propertyChanged",
                                                   node: node,
                                                   property: p});
                                }
                                catch (err) {
                                    console.error(err.message);
                                }
                                e.stopPropagation();
                                return false;
                            });

                        // make option sortable
                        value.find('#selectOption tbody').sortable({
                            axis: 'y',
                            items: '.options',
                            containment: value.find('#selectOption tbody'),
                            start: function(event, ui) {
                                widget.origRowIndex = ui.item.index() - 1;
                            },
                            stop: function(event, ui) {
                                var optionItem, curIndex = ui.item.index() - 1,
                                    origIndex = widget.origRowIndex;
                                    optionItem = props[p].children.splice(origIndex,1)[0];

                                props[p].children.splice(curIndex, 0, optionItem);
                                node.fireEvent("modelUpdated",
                                              {type: "propertyChanged",
                                               node: node,
                                               property: p});
                            },
                        });
                        break;
                    default:
                        // handle property has options
                        if (options[p]) {
                            $('<select size="1">')
                                .attr('id', valueId)
                                .addClass('title')
                                .appendTo(value);
                            //add options to select list
                            for (o in options[p]) {
                                //TODO make it simple
                                $('<option value="' + options[p][o] +
                                  '">' +options[p][o] + '</option>')
                                    .appendTo(value.find("#" + valueId));
                                value.find('#'+ valueId).val(valueVal);
                            }
                        } else {
                            $('<input type ="text" value="">')
                                .attr('id', valueId)
                                .addClass('title labelInput')
                                .appendTo(value);
                            //set default value
                            value.find('#' + valueId).val(valueVal);
                        }
                        break;
                }

                content.find('#' + valueId)
                    .change(node, function (event) {
                        var updated, node, element, type, value, ret;
                        updated = event.target.id.replace(/-value/,''),
                        node = event.data;

                        if (node === null || node === undefined) {
                            throw new Error("Missing node, prop change failed!");
                            return;
                        }
                        value = validValue($(this),
                            BWidget.getPropertyType(node.getType(), updated));
                        ret = ADM.setProperty(node, updated, value);
                        if(ret.result === false) {
                            $(this).val(node.getProperty(updated));
                        }
                        event.stopPropagation();
                        return false;
                    });
            }

            // add delete element button
            $('
<button> Delete Element </button>
')
                .addClass('property_footer')
                .children('button')
                .addClass('buttonStyle')
                .attr('id', "deleteElement")
                .end()
                .appendTo(content);
            content.find('#deleteElement')
                .one('click', function (e) {
                    var parent, zone, index;
                    try {
                        index = node.getZoneIndex();
                        parent = node.getParent();
                        zone = parent.getZoneArray(node.getZone());
                        if (type === "Page") {
                            $.rib.pageUtils.deletePage(node.getUid(), false);
                        } else {
                            ADM.removeChild(node.getUid(), false);
                        }
                        // Select sibling of removed node, or parent node
                        // if removed node is the last node of parent.  The
                        // order is next sibling, prev sibling and parent
                        if (zone.length === 0) {
                            //find the first selectable ancestor
                            while (!parent.isSelectable()) {
                                parent = parent.getParent();
                            }
                            ADM.setSelected(parent);
                        } else if (index < zone.length) {
                            ADM.setSelected(zone[index])
                        } else {
                            ADM.setSelected(zone[zone.length - 1]);
                        }
                    }
                    catch (err) {
                        console.error(err.message);
                    }
                    e.stopPropagation();
                    return false;
                });

            function validValue(element, type) {
                var ret = null, value = element.val();
                switch (type) {
                    case 'boolean':
                        ret = element.is(':checked');;
                        break;
                    case 'float':
                        ret = parseFloat(value);
                        break;
                    case 'integer':
                        ret = parseInt(value, 10);
                        break;
                    case 'number':
                        ret = Number(value);
                        break;
                    case 'object':
                        ret = Object(value);
                        break;
                    case 'string':
                        ret = String(value);
                        break;
                    default:
                        ret = value;
                        break;
                }
                return ret;
            };
        },
    });
})(jQuery);
<commit_msg>[Property View] Use proper context for jQuery selectors<commit_after>/*
 * Rapid Interface Builder (RIB) - A simple WYSIWYG HTML5 app creator
 * Copyright (c) 2011-2012, Intel Corporation.
 *
 * This program is licensed under the terms and conditions of the
 * Apache License, version 2.0.  The full text of the Apache License is at
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 */
"use strict";
// Property view widget

(function($, undefined) {

    $.widget('rib.propertyView', {

        options: {
            model: null,
        },

        _create: function() {
            var o = this.options,
                e = this.element;

            o.designReset = this._designResetHandler;
            o.selectionChanged = this._selectionChangedHandler;
            o.activePageChanged = this._activePageChangedHandler;
            o.modelUpdated = this._modelUpdatedHandler;

            // FIXME: This should work, but $.extend of options seems to be
            //        creating a copy of the ADM, which will not containt the
            //        same nodes and events as the master
            //o.model = o.model || ADM || undefined;
            if (o.model) {
                this._bindADMEvents(o.model);
            }

            this.element
                .addClass(this.widgetName)
                .append('
')
                .children(':last')
                .addClass('property_content');

            this.options.primaryTools = this._createPrimaryTools();
            this.options.secondaryTools = this._createSecondaryTools();
            $(window).resize(this, function(event) {
                var el = event.data.element;
                if (el.parent().height() == 0)
                    return;

                var newHeight = Math.round((el.parent().height()
                                - el.parent().find('.pageView').height()
                                - el.parent().find('.property_title')
                                      .height()
                                - 20) // height of ui-state-default + borders
                                * 0.4);
                el.height(newHeight);
            });

            this.refresh(null, this);

            return this;
        },

        _setOption: function(key, value) {
            switch (key) {
                // Should this REALLY be done here, or plugin registration in
                // the "host"... using the functions mapped in widget options?
                case 'model':
                    this._unbindADMEvents();
                    this._bindADMEvents(value);
                    this.refresh(null, this);
                    break;
                default:
                    break;
            }
        },

        destroy: function() {
            // TODO: unbind any ADM event handlers
            $(this.element).find('.'+this.widgetName).remove();
            this.options.primaryTools.remove();
            this.options.secondaryTools.remove();
        },

        refresh: function(event, widget) {
            widget = widget || this;
            if (event) {
                if (event.node && !(event.name === "modelUpdated" &&
                    event.type === "nodeRemoved")) {
                    widget._showProperties(event);
                } else {
                    event.node = ADM.getActivePage();
                    widget._showProperties(event);
                }
            }
        },

        // Private functions
        _createPrimaryTools: function() {
            return $(null);
        },

        _createSecondaryTools: function() {
            return $(null);
        },

        _bindADMEvents: function(a) {
            var o = this.options,
                d = this.designRoot;

            if (a) {
                o.model = a;

                if (o.designReset) {
                    a.bind("designReset", o.designReset, this);
                }
                if (o.selectionChanged) {
                    a.bind("selectionChanged", o.selectionChanged, this);
                }
                if (o.activePageChanged) {
                    a.bind("activePageChanged", o.activePageChanged, this);
                }

                // Since model changed, need to call our designReset hander
                // to sync up the ADMDesign modelUpdated event handler
                if (o.designReset) {
                    o.designReset({design: a.getDesignRoot()}, this);
                }
            }
        },

        _unbindADMEvents: function() {
            var o = this.options,
                a = this.options.model,
                d = this.designRoot;

            // First unbind our ADMDesign modelUpdated handler, if any...
            if (d && o.modelUpdated) {
                d.designRoot.unbind("modelUpdated", o.modelUpdated, this);
            }

            // Now unbind all ADM model event handlers, if any...
            if (a) {
                if (o.designReset) {
                    a.unbind("designReset", o.designReset, this);
                }
                if (o.selectionChanged) {
                    a.unbind("selectionChanged", o.selectionChanged, this);
                }
                if (o.activePageChanged) {
                    a.unbind("activePageChanged", o.activePageChanged, this);
                }
            }
        },

        _designResetHandler: function(event, widget) {
            var d = event && event.design, o;

            widget = widget || this;
            o = widget.options;
            d = d || o.model.getDesignRoot();

            // Do nothing if the new ADMDesign equals our currently cached one
            if (d === widget.designRoot) {
                return;
            }

            // First, unbind existing modelUpdated hander, if any...
            if (widget.designRoot && o.modelUpdated) {
                widget.designRoot.unbind("modelUpdated", o.modelUpdated,widget);
            }

            // Next, bind to modelUpdated events from new ADMDesign, if any...
            if (d && o.modelUpdated) {
                d.bind("modelUpdated", o.modelUpdated, widget);
            }

            // Then, cache the new ADMDesign reference with this instance
            widget.designRoot = d;

            // Finally, redraw our view since the ADMDesign root has changed
            widget.refresh(event, widget);
        },

        _selectionChangedHandler: function(event, widget) {
            widget = widget || this;
            //in case current focus input item change event not triggered
            //we trigger it firstly
            $("input:focus").trigger('change');
            widget.refresh(event,widget);
        },

        _activePageChangedHandler: function(event, widget) {
            widget = widget || this;
            widget.refresh(event,widget);
        },

        _modelUpdatedHandler: function(event, widget) {
            widget = widget || this;
            widget.refresh(event,widget);
        },

        _showProperties: function(event) {
            var node = event.node,
                labelId, labelVal, valueId, valueVal, count,
                widget = this, type,  i, child, index, propType,
                p, props, options, code, o, propertyItems, label, value,
                title = this.element.parent().find('.property_title'),
                content = this.element.find('.property_content');

            // Clear the properties pane when nothing is selected
            if (node === null || node === undefined) {
                node = ADM.getActivePage();
                if (node === null || node === undefined) {
                    content.empty()
                        .append('Nothing Selected');
                    return;
                }
            }

            type = node.getType();
            title.empty()
                .append('')
                .children(':first')
                    .addClass('title')
                    .text(BWidget.getDisplayLabel(type)+' Properties');
            content.empty();
            propertyItems = $('
').addClass("propertyItems")
                                    .appendTo(content);
            props = node.getProperties();
            options = node.getPropertyOptions();
            // iterate property of node
            for (p in props) {
                labelVal = p.replace(/_/g,'-');
                valueId = p+'-value';
                valueVal = props[p];
                propType = BWidget.getPropertyType(type, p);
                code = $('
')
                    .appendTo(propertyItems);
                label = $('').appendTo(code)
                    .attr('for', valueId)
                    .text(labelVal)
                    .addClass('title');
                value = $('
').appendTo(code);
                // display property of widget
                switch (propType) {
                    case "boolean":
                        $('<input type="checkbox"/>')
                            .attr('id', valueId)
                            .appendTo(value);

                        // initial value of checkbox
                        if ((node.getProperty (p) === true) ||
                            (node.getProperty (p) === "true")) {
                            value.find("#" + valueId).attr("checked", true);
                        }
                        break;
                    case "record-array":
                        $('
')
                            .attr('id', 'selectOption')
                            .attr('cellspacing', '5')
                            .appendTo(value);
                        var selectOption = value.find('#selectOption');
                        $('
')
                            .append('	')
                            .append(' Text 	')
                                .children().eq(1)
                                .addClass('title')
                                .end().end()
                            .append(' Value 	')
                                .children().eq(2)
                                .addClass('title')
                                .end().end()
                            .append('	')
                            .appendTo(selectOption);
                        for (i = 0; i< props[p].children.length; i ++){
                            child = props[p].children[i];
                            $('
').data('index', i)
                                .addClass("options")
                                .append('')
                                    .children().eq(0)
                                    .append('')
                                    .children(':first')
                                    .attr('src', "src/css/images/propertiesDragIconSmall.png")
                                    .end()
                                    .end().end()
                                .append('')
                                    .children().eq(1)
                                    .append('<input type="text"/>')
                                        .children().eq(0)
                                        .val(child.text)
                                        .addClass('title optionInput')
                                        .change(node, function (event) {
                                            index = $(this).parent().parent().data('index');
                                            props[p].children[index].text = $(this).val();
                                            node.fireEvent("modelUpdated",
                                                {type: "propertyChanged",
                                                 node: node,
                                                 property: p});
                                        })
                                        .end().end()
                                    .end().end()
                                .append('')
                                    .children().eq(2)
                                    .append('<input type="text"/>')
                                        .children().eq(0)
                                        .val(child.value)
                                        .addClass('title optionInput')
                                        .change(node, function (event) {
                                            index = $(this).parent().parent().data('index');
                                            props[p].children[index].value = $(this).val();
                                            node.fireEvent("modelUpdated",
                                                {type: "propertyChanged",
                                                 node: node,
                                                 property: p});
                                        })
                                        .end().end()
                                    .end().end()
                                .append('')
                                    .children().eq(3)
                                    .append('')
                                        .children(':first')
                                        .attr('src', "src/css/images/deleteButton_up.png")
                                        // add delete option handler
                                        .click(function(e) {
                                            try {
                                                index = $(this).parent().parent().data('index');
                                                props[p].children.splice(index, 1);
                                                node.fireEvent("modelUpdated",
                                                    {type: "propertyChanged",
                                                        node: node,
                                                    property: p});
                                            }
                                            catch (err) {
                                                console.error(err.message);
                                            }
                                            e.stopPropagation();
                                            return false;
                                        })
                                        .end()
                                    .end().end()
                               .appendTo(selectOption);
                        }

                        // add add items handler
                        $('+ add item')
                            .children(':first')
                            .addClass('rightLabel title')
                            .attr('id', 'addOptionItem')
                            .end()
                            .appendTo(value);
                        value.find('#addOptionItem')
                            .click(function(e) {
                                try {
                                    var optionItem = {};
                                    optionItem.text = "Option";
                                    optionItem.value = "Value";
                                    props[p].children.push(optionItem);
                                    node.fireEvent("modelUpdated",
                                                  {type: "propertyChanged",
                                                   node: node,
                                                   property: p});
                                }
                                catch (err) {
                                    console.error(err.message);
                                }
                                e.stopPropagation();
                                return false;
                            });

                        // make option sortable
                        value.find('#selectOption tbody').sortable({
                            axis: 'y',
                            items: '.options',
                            containment: value.find('#selectOption tbody'),
                            start: function(event, ui) {
                                widget.origRowIndex = ui.item.index() - 1;
                            },
                            stop: function(event, ui) {
                                var optionItem, curIndex = ui.item.index() - 1,
                                    origIndex = widget.origRowIndex;
                                    optionItem = props[p].children.splice(origIndex,1)[0];

                                props[p].children.splice(curIndex, 0, optionItem);
                                node.fireEvent("modelUpdated",
                                              {type: "propertyChanged",
                                               node: node,
                                               property: p});
                            },
                        });
                        break;
                    default:
                        // handle property has options
                        if (options[p]) {
                            $('<select size="1">')
                                .attr('id', valueId)
                                .addClass('title')
                                .appendTo(value);
                            //add options to select list
                            for (o in options[p]) {
                                //TODO make it simple
                                $('<option value="' + options[p][o] +
                                  '">' +options[p][o] + '</option>')
                                    .appendTo(value.find("#" + valueId));
                                value.find('#'+ valueId).val(valueVal);
                            }
                        } else {
                            $('<input type ="text" value="">')
                                .attr('id', valueId)
                                .addClass('title labelInput')
                                .appendTo(value);
                            //set default value
                            value.find('#' + valueId).val(valueVal);
                        }
                        break;
                }

                content.find('#' + valueId)
                    .change(node, function (event) {
                        var updated, node, element, type, value, ret;
                        updated = event.target.id.replace(/-value/,''),
                        node = event.data;

                        if (node === null || node === undefined) {
                            throw new Error("Missing node, prop change failed!");
                            return;
                        }
                        value = validValue($(this),
                            BWidget.getPropertyType(node.getType(), updated));
                        ret = ADM.setProperty(node, updated, value);
                        if(ret.result === false) {
                            $(this).val(node.getProperty(updated));
                        }
                        event.stopPropagation();
                        return false;
                    });
            }

            // add delete element button
            $('
<button> Delete Element </button>
')
                .addClass('property_footer')
                .children('button')
                .addClass('buttonStyle')
                .attr('id', "deleteElement")
                .end()
                .appendTo(content);
            content.find('#deleteElement')
                .one('click', function (e) {
                    var parent, zone, index;
                    try {
                        index = node.getZoneIndex();
                        parent = node.getParent();
                        zone = parent.getZoneArray(node.getZone());
                        if (type === "Page") {
                            $.rib.pageUtils.deletePage(node.getUid(), false);
                        } else {
                            ADM.removeChild(node.getUid(), false);
                        }
                        // Select sibling of removed node, or parent node
                        // if removed node is the last node of parent.  The
                        // order is next sibling, prev sibling and parent
                        if (zone.length === 0) {
                            //find the first selectable ancestor
                            while (!parent.isSelectable()) {
                                parent = parent.getParent();
                            }
                            ADM.setSelected(parent);
                        } else if (index < zone.length) {
                            ADM.setSelected(zone[index])
                        } else {
                            ADM.setSelected(zone[zone.length - 1]);
                        }
                    }
                    catch (err) {
                        console.error(err.message);
                    }
                    e.stopPropagation();
                    return false;
                });

            function validValue(element, type) {
                var ret = null, value = element.val();
                switch (type) {
                    case 'boolean':
                        ret = element.is(':checked');;
                        break;
                    case 'float':
                        ret = parseFloat(value);
                        break;
                    case 'integer':
                        ret = parseInt(value, 10);
                        break;
                    case 'number':
                        ret = Number(value);
                        break;
                    case 'object':
                        ret = Object(value);
                        break;
                    case 'string':
                        ret = String(value);
                        break;
                    default:
                        ret = value;
                        break;
                }
                return ret;
            };
        },
    });
})(jQuery);
<|endoftext|>


<commit_before>// @flow
import React, { Component } from 'react';
import type { Node } from 'react';
import { observable, runInAction } from 'mobx';
import { storiesOf } from '@storybook/react';
import { action } from '@storybook/addon-actions';
import BigNumber from 'bignumber.js';
import moment from 'moment';

// Assets and helpers
import StoryDecorator from './support/StoryDecorator';
import walletsIcon from '../../source/renderer/app/assets/images/sidebar/wallet-ic.inline.svg';
import settingsIcon from '../../source/renderer/app/assets/images/sidebar/settings-ic.inline.svg';
import adaIcon from '../../source/renderer/app/assets/images/sidebar/ada-redemption-ic.inline.svg';
import paperCertificateIcon from '../../source/renderer/app/assets/images/sidebar/paper-certificate-ic.inline.svg';
import { formattedWalletAmount } from '../../source/renderer/app/utils/ada/formatters';
import NodeSyncStatusIcon from '../../source/renderer/app/components/widgets/NodeSyncStatusIcon';
import WalletAddress from '../../source/renderer/app/domains/WalletAddress';
import { generateTransaction } from './WalletTransactionsList.stories.js';
import { transactionTypes } from '../../source/renderer/app/domains/WalletTransaction';

// Empty screen elements
import TopBar from '../../source/renderer/app/components/layout/TopBar';
import Sidebar from '../../source/renderer/app/components/sidebar/Sidebar';
import SidebarLayout from '../../source/renderer/app/components/layout/SidebarLayout';
import SidebarWalletsMenu from '../../source/renderer/app/components/sidebar/wallets/SidebarWalletsMenu';
import WalletWithNavigation from '../../source/renderer/app/components/wallet/layouts/WalletWithNavigation';

// Screens
import WalletSummary from '../../source/renderer/app/components/wallet/summary/WalletSummary';
import WalletSendForm from '../../source/renderer/app/components/wallet/WalletSendForm';
import WalletReceive from '../../source/renderer/app/components/wallet/WalletReceive';
import WalletTransactionsList from '../../source/renderer/app/components/wallet/transactions/WalletTransactionsList';
// import WalletSettings from '../../source/renderer/app/components/wallet/WalletSettings';

type Props = {
  activeNavItem?: string,
  children?: any | Node
};

const sidebarCategories = [
  {
    name: 'WALLETS',
    route: '/wallets',
    icon: walletsIcon,
  },
  {
    name: 'SETTINGS',
    route: '/settings',
    icon: settingsIcon,
  },
  {
    name: 'ADA_REDEMPTION',
    route: '/ada-redemption',
    icon: adaIcon,
  },
  {
    name: 'PAPER_WALLET',
    route: '/paper-wallet-create-certificate',
    icon: paperCertificateIcon,
  }
];

const sidebarMenus = observable({
  wallets: {
    items: [
      { id: '1', title: 'Mining', info: '0.000000 ADA', isConnected: true },
      { id: '2', title: 'Shopping', info: '66.998.623133 ADA', isConnected: true },
    ],
    activeWalletId: '2',
    actions: {
      onAddWallet: action('toggleAddWallet'),
      onWalletItemClick: (walletId: string) => {
        runInAction(() => sidebarMenus.wallets.activeWalletId = walletId);
      }
    }
  }
});

class WalletScreen extends Component<Props> {

  render() {

    const { children, activeNavItem } = this.props;

    return (

        <SidebarLayout
          sidebar={this.sidebar(!!children)}
          topbar={this.topbar}
        >
          {
            children &&
              (
                <WalletWithNavigation
                  isActiveScreen={item => item === activeNavItem}
                  onWalletNavItemClick={action('onWalletNavItemClick')}
                >
                  {children}
                </WalletWithNavigation>
              )
          }
        </SidebarLayout>

    );
  }

  sidebar = isShowingSubMenus => (
    <Sidebar
      categories={sidebarCategories}
      activeSidebarCategory={sidebarCategories[0].route}
      menus={sidebarMenus}
      isShowingSubMenus={isShowingSubMenus}
      onCategoryClicked={action('onCategoryClicked')}
      isDialogOpen={() => false}
      onAddWallet={action('onAddWallet')}
      openDialogAction={action('openDialog')}
      onSubmitSupportRequest={()=>{}}
    />
  )

  // TODO: Find out how to activave the `topBarTitle` on TopBar
  get topbar() {
    return (
      <TopBar
        formattedWalletAmount={formattedWalletAmount}
        currentRoute="summary"
        showSubMenuToggle
        showSubMenus
      >
        <NodeSyncStatusIcon
          networkStatus={{
            isSynced: true,
            syncPercentage: 100,
          }}
          isProduction
        />
      </TopBar>
    );
  }
}

storiesOf('WalletScreens', module)

  .addDecorator((story) => (
    <StoryDecorator>
      {story()}
    </StoryDecorator>
  ))

  // ====== Stories ======

  .add('empty', () => (
    <WalletScreen/>
  ))

  .add('Summary', () => (
    <WalletScreen
      activeNavItem="summary"
    >
      <WalletSummary
        walletName="Shopping wallet"
        amount="45119903750165.23"
        pendingAmount={{
          incoming: new BigNumber(1),
          outgoing: new BigNumber(2),
          total: new BigNumber(3)
        }}
        numberOfTransactions={20303585}
        isLoadingTransactions={false}
      />
    </WalletScreen>
  ))

  .add('Send', () => (
    <WalletScreen
      activeNavItem="send"
    >
      <WalletSendForm
        currencyUnit="Ada"
        currencyMaxFractionalDigits={ 6}
        currencyMaxIntegerDigits={11}
        validateAmount={() => true}
        calculateTransactionFee={()=>{}}
        addressValidator={()=>{}}
        openDialogAction={()=>{}}
        isDialogOpen={()=>{}}
        isRestoreActive={false}
      />
    </WalletScreen>
  ))

  .add('Receive', () => (
    <WalletScreen
      activeNavItem="receive"
    >
      <WalletReceive
        walletAddress="5628aab8ac98c963e4a2e8cfce5aa1cbd4384fe2f9a0f3c5f791bfb83a5e02ds"
        isWalletAddressUsed={false}
        walletAddresses={[
          {
            id: '5628aab8ac98c963e4a2e8cfce5aa1cbd4384fe2f9a0f3c5f791bfb83a5e02ds',
            amount: new BigNumber(1),
            isUsed:false,
          },
          {
            id: 'f465aca571de909091967349e1dc39fc9ce9755ff8ffdb7cc3771b503904e49a',
            amount: new BigNumber(1),
            isUsed:false,
          },
          {
            id: '5628aab8ac98c963e4a2e8cfce5aa1cbd4384fe2f9a0f3c5f791bfb83a5e02ds',
            amount: new BigNumber(1),
            isUsed:false,
          },
          {
            id: 'f465aca571de909091967349e1dc39fc9ce9755ff8ffdb7cc3771b503904e49a',
            amount: new BigNumber(1),
            isUsed:false,
          },
          {
            id: '5628aab8ac98c963e4a2e8cfce5aa1cbd4384fe2f9a0f3c5f791bfb83a5e02ds',
            amount: new BigNumber(1),
            isUsed:false,
          },
          {
            id: 'f465aca571de909091967349e1dc39fc9ce9755ff8ffdb7cc3771b503904e49a',
            amount: new BigNumber(1),
            isUsed:false,
          },
          {
            id: '68a1107193a8183bcd7758c9b3d9f3e8b0437206cc432b4e01a49d948157f51e',
            amount: new BigNumber(1),
            isUsed:true,
          },
          {
            id: '68a1107193a8183bcd7758c9b3d9f3e8b0437206cc432b4e01a49d948157f51e',
            amount: new BigNumber(1),
            isUsed:true,
          },
          {
            id: '68a1107193a8183bcd7758c9b3d9f3e8b0437206cc432b4e01a49d948157f51e',
            amount: new BigNumber(1),
            isUsed:true,
          },
          {
            id: '68a1107193a8183bcd7758c9b3d9f3e8b0437206cc432b4e01a49d948157f51e',
            amount: new BigNumber(1),
            isUsed:true,
          },
          {
            id: '68a1107193a8183bcd7758c9b3d9f3e8b0437206cc432b4e01a49d948157f51e',
            amount: new BigNumber(1),
            isUsed:true,
          },
          {
            id: '68a1107193a8183bcd7758c9b3d9f3e8b0437206cc432b4e01a49d948157f51e',
            amount: new BigNumber(1),
            isUsed:true,
          },

        ]}
        onGenerateAddress={()=>{}}
        onCopyAddress={()=>{}}
        isSidebarExpanded
        walletHasPassword={false}
        isSubmitting={false}
      />

    </WalletScreen>
  ))

  .add('Transactions', () => (
    <WalletScreen
      activeNavItem="transactions"
    >
      <WalletTransactionsList
        transactions={[
          generateTransaction(transactionTypes.INCOME, new Date(), new BigNumber(1)),
          generateTransaction(transactionTypes.INCOME, moment().subtract(1, 'days').toDate(), new BigNumber(1)),
          generateTransaction(transactionTypes.INCOME, new Date(), new BigNumber(1)),
          generateTransaction(transactionTypes.INCOME, moment().subtract(2, 'days').toDate(), new BigNumber(1)),
          generateTransaction(transactionTypes.INCOME, moment().subtract(1, 'days').toDate(), new BigNumber(1)),
        ]}
        isLoadingTransactions={false}
        hasMoreToLoad={false}
        assuranceMode={{ low: 1, medium: 2 }}
        walletId="test-wallet"
        formattedWalletAmount={formattedWalletAmount}
      />
    </WalletScreen>
  ))

  .add('Settings', () => (
    <WalletScreen
      activeNavItem="settings"
    >
      Settings screen
    </WalletScreen>
  ));

<commit_msg>[DDW-280] Transactions screen content<commit_after>// @flow
import React, { Component } from 'react';
import type { Node } from 'react';
import { observable, runInAction } from 'mobx';
import { storiesOf } from '@storybook/react';
import { action } from '@storybook/addon-actions';
import BigNumber from 'bignumber.js';
import moment from 'moment';

// Assets and helpers
import StoryDecorator from './support/StoryDecorator';
import walletsIcon from '../../source/renderer/app/assets/images/sidebar/wallet-ic.inline.svg';
import settingsIcon from '../../source/renderer/app/assets/images/sidebar/settings-ic.inline.svg';
import adaIcon from '../../source/renderer/app/assets/images/sidebar/ada-redemption-ic.inline.svg';
import paperCertificateIcon from '../../source/renderer/app/assets/images/sidebar/paper-certificate-ic.inline.svg';
import { formattedWalletAmount } from '../../source/renderer/app/utils/ada/formatters';
import NodeSyncStatusIcon from '../../source/renderer/app/components/widgets/NodeSyncStatusIcon';
import WalletAddress from '../../source/renderer/app/domains/WalletAddress';
import { generateTransaction } from './WalletTransactionsList.stories.js';
import { transactionStates, transactionTypes } from '../../source/renderer/app/domains/WalletTransaction';

// Empty screen elements
import TopBar from '../../source/renderer/app/components/layout/TopBar';
import Sidebar from '../../source/renderer/app/components/sidebar/Sidebar';
import SidebarLayout from '../../source/renderer/app/components/layout/SidebarLayout';
import SidebarWalletsMenu from '../../source/renderer/app/components/sidebar/wallets/SidebarWalletsMenu';
import WalletWithNavigation from '../../source/renderer/app/components/wallet/layouts/WalletWithNavigation';

// Screens
import WalletSummary from '../../source/renderer/app/components/wallet/summary/WalletSummary';
import WalletSendForm from '../../source/renderer/app/components/wallet/WalletSendForm';
import WalletReceive from '../../source/renderer/app/components/wallet/WalletReceive';
import WalletTransactionsList from '../../source/renderer/app/components/wallet/transactions/WalletTransactionsList';
// import WalletSettings from '../../source/renderer/app/components/wallet/WalletSettings';

type Props = {
  activeNavItem?: string,
  children?: any | Node
};

const sidebarCategories = [
  {
    name: 'WALLETS',
    route: '/wallets',
    icon: walletsIcon,
  },
  {
    name: 'SETTINGS',
    route: '/settings',
    icon: settingsIcon,
  },
  {
    name: 'ADA_REDEMPTION',
    route: '/ada-redemption',
    icon: adaIcon,
  },
  {
    name: 'PAPER_WALLET',
    route: '/paper-wallet-create-certificate',
    icon: paperCertificateIcon,
  }
];

const sidebarMenus = observable({
  wallets: {
    items: [
      { id: '1', title: 'Mining', info: '0.000000 ADA', isConnected: true },
      { id: '2', title: 'Shopping', info: '66.998.623133 ADA', isConnected: true },
    ],
    activeWalletId: '2',
    actions: {
      onAddWallet: action('toggleAddWallet'),
      onWalletItemClick: (walletId: string) => {
        runInAction(() => sidebarMenus.wallets.activeWalletId = walletId);
      }
    }
  }
});

class WalletScreen extends Component<Props> {

  render() {

    const { children, activeNavItem } = this.props;

    return (

        <SidebarLayout
          sidebar={this.sidebar(!!children)}
          topbar={this.topbar}
        >
          {
            children &&
              (
                <WalletWithNavigation
                  isActiveScreen={item => item === activeNavItem}
                  onWalletNavItemClick={action('onWalletNavItemClick')}
                >
                  {children}
                </WalletWithNavigation>
              )
          }
        </SidebarLayout>

    );
  }

  sidebar = isShowingSubMenus => (
    <Sidebar
      categories={sidebarCategories}
      activeSidebarCategory={sidebarCategories[0].route}
      menus={sidebarMenus}
      isShowingSubMenus={isShowingSubMenus}
      onCategoryClicked={action('onCategoryClicked')}
      isDialogOpen={() => false}
      onAddWallet={action('onAddWallet')}
      openDialogAction={action('openDialog')}
      onSubmitSupportRequest={()=>{}}
    />
  )

  // TODO: Find out how to activave the `topBarTitle` on TopBar
  get topbar() {
    return (
      <TopBar
        formattedWalletAmount={formattedWalletAmount}
        currentRoute="summary"
        showSubMenuToggle
        showSubMenus
      >
        <NodeSyncStatusIcon
          networkStatus={{
            isSynced: true,
            syncPercentage: 100,
          }}
          isProduction
        />
      </TopBar>
    );
  }
}

storiesOf('WalletScreens', module)

  .addDecorator((story) => (
    <StoryDecorator>
      {story()}
    </StoryDecorator>
  ))

  // ====== Stories ======

  .add('empty', () => (
    <WalletScreen/>
  ))

  .add('Summary', () => (
    <WalletScreen
      activeNavItem="summary"
    >
      <WalletSummary
        walletName="Shopping wallet"
        amount="45119903750165.23"
        pendingAmount={{
          incoming: new BigNumber(1),
          outgoing: new BigNumber(2),
          total: new BigNumber(3)
        }}
        numberOfTransactions={20303585}
        isLoadingTransactions={false}
      />
    </WalletScreen>
  ))

  .add('Send', () => (
    <WalletScreen
      activeNavItem="send"
    >
      <WalletSendForm
        currencyUnit="Ada"
        currencyMaxFractionalDigits={ 6}
        currencyMaxIntegerDigits={11}
        validateAmount={() => true}
        calculateTransactionFee={()=>{}}
        addressValidator={()=>{}}
        openDialogAction={()=>{}}
        isDialogOpen={()=>{}}
        isRestoreActive={false}
      />
    </WalletScreen>
  ))

  .add('Receive', () => (
    <WalletScreen
      activeNavItem="receive"
    >
      <WalletReceive
        walletAddress="5628aab8ac98c963e4a2e8cfce5aa1cbd4384fe2f9a0f3c5f791bfb83a5e02ds"
        isWalletAddressUsed={false}
        walletAddresses={[
          {
            id: '5628aab8ac98c963e4a2e8cfce5aa1cbd4384fe2f9a0f3c5f791bfb83a5e02ds',
            amount: new BigNumber(1),
            isUsed:false,
          },
          {
            id: 'f465aca571de909091967349e1dc39fc9ce9755ff8ffdb7cc3771b503904e49a',
            amount: new BigNumber(1),
            isUsed:false,
          },
          {
            id: '5628aab8ac98c963e4a2e8cfce5aa1cbd4384fe2f9a0f3c5f791bfb83a5e02ds',
            amount: new BigNumber(1),
            isUsed:false,
          },
          {
            id: 'f465aca571de909091967349e1dc39fc9ce9755ff8ffdb7cc3771b503904e49a',
            amount: new BigNumber(1),
            isUsed:false,
          },
          {
            id: '5628aab8ac98c963e4a2e8cfce5aa1cbd4384fe2f9a0f3c5f791bfb83a5e02ds',
            amount: new BigNumber(1),
            isUsed:false,
          },
          {
            id: 'f465aca571de909091967349e1dc39fc9ce9755ff8ffdb7cc3771b503904e49a',
            amount: new BigNumber(1),
            isUsed:false,
          },
          {
            id: '68a1107193a8183bcd7758c9b3d9f3e8b0437206cc432b4e01a49d948157f51e',
            amount: new BigNumber(1),
            isUsed:true,
          },
          {
            id: '68a1107193a8183bcd7758c9b3d9f3e8b0437206cc432b4e01a49d948157f51e',
            amount: new BigNumber(1),
            isUsed:true,
          },
          {
            id: '68a1107193a8183bcd7758c9b3d9f3e8b0437206cc432b4e01a49d948157f51e',
            amount: new BigNumber(1),
            isUsed:true,
          },
          {
            id: '68a1107193a8183bcd7758c9b3d9f3e8b0437206cc432b4e01a49d948157f51e',
            amount: new BigNumber(1),
            isUsed:true,
          },
          {
            id: '68a1107193a8183bcd7758c9b3d9f3e8b0437206cc432b4e01a49d948157f51e',
            amount: new BigNumber(1),
            isUsed:true,
          },
          {
            id: '68a1107193a8183bcd7758c9b3d9f3e8b0437206cc432b4e01a49d948157f51e',
            amount: new BigNumber(1),
            isUsed:true,
          },

        ]}
        onGenerateAddress={()=>{}}
        onCopyAddress={()=>{}}
        isSidebarExpanded
        walletHasPassword={false}
        isSubmitting={false}
      />

    </WalletScreen>
  ))

  .add('Transactions', () => (
    <WalletScreen
      activeNavItem="transactions"
    >
      <WalletTransactionsList
        transactions={[
          generateTransaction(transactionTypes.INCOME, new Date(), new BigNumber(1), 1),
          generateTransaction(transactionTypes.EXCHANGE, new Date(), new BigNumber(1)),
          generateTransaction(transactionTypes.EXPEND, moment().subtract(1, 'days').toDate(), new BigNumber(2), 0, transactionStates.PENDING),
          generateTransaction(transactionTypes.INCOME, moment().subtract(1, 'days').toDate(), new BigNumber(1), 0, transactionStates.FAILED),
          generateTransaction(transactionTypes.EXPEND, moment().subtract(2, 'days').toDate(), new BigNumber(3)),
          generateTransaction(transactionTypes.EXPEND, moment().subtract(3, 'days').toDate(), new BigNumber(5)),
          generateTransaction(transactionTypes.INCOME, moment().subtract(4, 'days').toDate(), new BigNumber(6)),
        ]}
        isLoadingTransactions={false}
        hasMoreToLoad={false}
        assuranceMode={{ low: 1, medium: 2 }}
        walletId="test-wallet"
        formattedWalletAmount={formattedWalletAmount}
      />
    </WalletScreen>
  ))

  .add('Settings', () => (
    <WalletScreen
      activeNavItem="settings"
    >
      Settings screen
    </WalletScreen>
  ));

<|endoftext|>


<commit_before>var histogram1d = function() {

  var hist = chart();

  function ready(){
    refresh = histogram1d_refresh;
    module_ready();
  }

  function histogram1d_refresh() {
    module_get(update, error);
  }

  function update(data) {
    module_update(data);

    hist = hist.histogram(process_histogram(data.histogram));
    hist(d3.select("#histogram1d"));
  }

  function error(err) {
    console.log(err);
  }

  function process_histogram(prohist){
    return prohist.values.reduce(function(acc, val, idx, arr){
      // x: lower bound
      // dx: bin width
      // y: bin count
      acc.push({x: prohist.edges[idx],
                dx: prohist.edges[idx+1] - prohist.edges[idx],
                y: val});
      return acc;
    }, []);
  }

  /**
   * Histogram; this is the encapsulated component.
   */
  function chart(){
    var histogram = [];
    var margin = { top: 10, bottom: 25, left: 45, right: 15};
    var width = 400 - margin.left - margin.right;
    var height = 100 - margin.top - margin.bottom;
    var xScale = d3.scale.linear();
    var yScale = d3.scale.linear();

    function my(selection){
      selection.each(function() {
        //set up scales and svg element
        xScale.domain([histogram[0].x, histogram[histogram.length-1].x + histogram[histogram.length-1].dx]).range([0,width]);
        yScale.domain([0, d3.max(histogram, function(d){ return d.y; })]).range([height,0]);
        var xAxis = d3.svg.axis().scale(xScale).orient("bottom");
        var yAxis = d3.svg.axis().ticks(5).scale(yScale).orient("left");

        var svg = d3.select(this).selectAll("svg").data([histogram]);
        var gEnter = svg.enter().append("svg")
          .attr("width", width + margin.left + margin.right)
          .attr("height", height + margin.top + margin.bottom)
          .append("g")
            .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
        //draw bars
        var bar = gEnter.selectAll(".bar").data(histogram);
        bar.enter().append("g")
          .attr("class", "bar")
          .attr("transform", function(d) { return "translate(" + xScale(d.x) + "," + 0 + ")"; });

        bar.append("rect")
           .attr("x", 1)
           .attr("y", function(d){ return yScale(d.y); })

        var rects = selection.selectAll("rect").data(histogram)
          .attr("y", function(d){ return yScale(d.y); })
          .attr("width", function(d){ return xScale(d.x + d.dx) - xScale(d.x) - 1; })
          .attr("height", function(d) { return height - yScale(d.y); });

        //draw axes
        var x = svg.selectAll(".x").data([histogram]);
        x.enter()
           .append("g")
           .attr("class", "x axis")
           .attr("transform", "translate(" + margin.left + "," + (height + margin.top) + ")");

        x.call(xAxis);

        var y = svg.selectAll(".y").data([histogram]);
        y.enter()
           .append("g")
           .attr("class", "y axis")
           .attr("transform", "translate(" + (margin.left) + ", " + margin.top + ")");

        y.call(yAxis);
      });
    }

    my.width = function(value){
      if(!arguments.length){
        return width;
      }
      width = +value;
      return my;
    }

    my.height = function(value){
      if(!arguments.length){
        return height;
      }
      height = +value;
      return my;
    }

    my.histogram = function(value){
      if(!arguments.length){
        return histogram;
      }
      histogram = value;
      return my;
    }

    return my;
  }

  return {
    ready: ready,
    chart: chart,
    process_histogram: process_histogram
  };
}();
<commit_msg>better dimensions API (width and height represent total widget dimensions)<commit_after>var histogram1d = function() {

  var hist = chart();

  function ready(){
    refresh = histogram1d_refresh;
    module_ready();
  }

  function histogram1d_refresh() {
    module_get(update, error);
  }

  function update(data) {
    module_update(data);

    hist = hist.histogram(process_histogram(data.histogram));
    hist.width(600).height(400);
    hist(d3.select("#histogram1d"));
  }

  function error(err) {
    console.log(err);
  }

  function process_histogram(prohist){
    return prohist.values.reduce(function(acc, val, idx, arr){
      // x: lower bound
      // dx: bin width
      // y: bin count
      acc.push({x: prohist.edges[idx],
                dx: prohist.edges[idx+1] - prohist.edges[idx],
                y: val});
      return acc;
    }, []);
  }

  /**
   * Histogram; this is the encapsulated component.
   */
  function chart(){
    var histogram = [];
    var margin = { top: 10, bottom: 25, left: 45, right: 15};
    var width = 400;
    var innerWidth = width - margin.left - margin.right;
    var height = 100;
    var innerHeight = height - margin.top - margin.bottom;
    var xScale = d3.scale.linear();
    var yScale = d3.scale.linear();

    function my(selection){
      selection.each(function() {
        //set up scales and svg element
        xScale.domain([histogram[0].x, histogram[histogram.length-1].x + histogram[histogram.length-1].dx]).range([0,innerWidth]);
        yScale.domain([0, d3.max(histogram, function(d){ return d.y; })]).range([innerHeight,0]);
        var xAxis = d3.svg.axis().scale(xScale).orient("bottom");
        var yAxis = d3.svg.axis().ticks(5).scale(yScale).orient("left");

        var svg = d3.select(this).selectAll("svg").data([histogram]);
        var gEnter = svg.enter().append("svg")
          .attr("width", width)
          .attr("height", height)
          .append("g")
            .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
        //draw bars
        var bar = gEnter.selectAll(".bar").data(histogram);
        bar.enter().append("g")
          .attr("class", "bar")
          .attr("transform", function(d) { return "translate(" + xScale(d.x) + "," + 0 + ")"; });

        bar.append("rect")
           .attr("x", 1)
           .attr("y", function(d){ return yScale(d.y); })

        var rects = selection.selectAll("rect").data(histogram)
          .attr("y", function(d){ return yScale(d.y); })
          .attr("width", function(d){ return xScale(d.x + d.dx) - xScale(d.x) - 1; })
          .attr("height", function(d) { return innerHeight - yScale(d.y); });

        //draw axes
        var x = svg.selectAll(".x").data([histogram]);
        x.enter()
           .append("g")
           .attr("class", "x axis")
           .attr("transform", "translate(" + margin.left + "," + (innerHeight + margin.top) + ")");

        x.call(xAxis);

        var y = svg.selectAll(".y").data([histogram]);
        y.enter()
           .append("g")
           .attr("class", "y axis")
           .attr("transform", "translate(" + margin.left + ", " + margin.top + ")");

        y.call(yAxis);
      });
    }

    my.width = function(value){
      if(!arguments.length){
        return width;
      }
      width = +value;
      innerWidth = width - margin.left - margin.right;
      return my;
    }

    my.height = function(value){
      if(!arguments.length){
        return height;
      }
      height = +value;
      innerHeight = height - margin.top - margin.bottom;
      return my;
    }

    my.histogram = function(value){
      if(!arguments.length){
        return histogram;
      }
      histogram = value;
      return my;
    }

    return my;
  }

  return {
    ready: ready,
    chart: chart,
    process_histogram: process_histogram
  };
}();
<|endoftext|>


<commit_before>import { api } from '/api';
import { store } from '/store';

import urbitOb from 'urbit-ob';

export class Subscription {

  constructor() {
    this.firstRoundSubscriptionComplete = false;
  }

  start() {
    if (api.authTokens) {
      this.firstRoundSubscription();
    } else {
      console.error("~~~ ERROR: Must set api.authTokens before operation ~~~");
    }
  }

  subscribe(path, app) {
    api.bind(path, 'PUT', api.authTokens.ship, app,
      this.handleEvent.bind(this),
      this.handleError.bind(this),
      () => {
        this.subscribe(path, app);
      });
  }

  firstRoundSubscription() {
    this.subscribe('/primary', 'chat-view');
  }

  secondRoundSubscriptions() {
    this.subscribe('/synced', 'chat-hook');
    this.subscribe('/primary', 'invite-view');
    this.subscribe('/all', 'permission-store');
    this.subscribe('/primary', 'contact-view');
    this.subscribe('/app-name/chat', 'metadata-store');
    this.subscribe('/app-name/contacts', 'metadata-store');
  }

  handleEvent(diff) {
    if (!this.firstRoundSubscriptionComplete) {
      this.firstRoundSubscriptionComplete = true;
      this.secondRoundSubscriptions();
    }
    store.handleEvent(diff);
  }

  handleError(err) {
    console.error(err);
  }

  fetchMessages(start, end, path) {
    console.log(start, end, path);
    fetch(`/~chat/paginate/${start}/${end}${path}`)
      .then((response) => response.json())
      .then((json) => {
        store.handleEvent({
          data: json
        });
      });
  }

}

export let subscription = new Subscription();
<commit_msg>chat-js: resubscribe on error, not just on quit<commit_after>import { api } from '/api';
import { store } from '/store';

import urbitOb from 'urbit-ob';

export class Subscription {

  constructor() {
    this.firstRoundSubscriptionComplete = false;
  }

  start() {
    if (api.authTokens) {
      this.firstRoundSubscription();
    } else {
      console.error("~~~ ERROR: Must set api.authTokens before operation ~~~");
    }
  }

  subscribe(path, app) {
    api.bind(path, 'PUT', api.authTokens.ship, app,
      this.handleEvent.bind(this),
      (err) => {
        console.log(err);
        this.subscribe(path, app);
      },
      () => {
        this.subscribe(path, app);
      });
  }

  firstRoundSubscription() {
    this.subscribe('/primary', 'chat-view');
  }

  secondRoundSubscriptions() {
    this.subscribe('/synced', 'chat-hook');
    this.subscribe('/primary', 'invite-view');
    this.subscribe('/all', 'permission-store');
    this.subscribe('/primary', 'contact-view');
    this.subscribe('/app-name/chat', 'metadata-store');
    this.subscribe('/app-name/contacts', 'metadata-store');
  }

  handleEvent(diff) {
    if (!this.firstRoundSubscriptionComplete) {
      this.firstRoundSubscriptionComplete = true;
      this.secondRoundSubscriptions();
    }
    store.handleEvent(diff);
  }

  fetchMessages(start, end, path) {
    console.log(start, end, path);
    fetch(`/~chat/paginate/${start}/${end}${path}`)
      .then((response) => response.json())
      .then((json) => {
        store.handleEvent({
          data: json
        });
      });
  }

}

export let subscription = new Subscription();
<|endoftext|>


<commit_before>// TODO RELEASEBLOCKER nur width oder height setzen, wenn w bzw h relativ zu elternelement ist

(function($) {
  $.fn.sticky_enable = function(opts) {
    var parent_selector, sticky_class, z_index, stick_directions, scrollarea_offset;
    var _fn;
    if (opts == null) {
      opts = {};
    }
    sticky_class = opts.sticky_class, parent_selector = opts.parent, z_index = opts.z_index, stick_directions = opts.stick_directions, scrollarea_offset=opts.scrollarea_offset;

    if (parent_selector == null) {
      parent_selector = void 0;
    }
    if (sticky_class == null) {
      sticky_class = "sticked";
    }
    if (stick_directions == null) {
      stick_directions = "t";
    }
    if (scrollarea_offset == null) {
      scrollarea_offset = "";
    }
    if (z_index == null) {
        z_index=1;
    }

    _fn = function(elm) {
        var parent,spacer;
        var STATE={OFF: 0, VIEWPORT_TOP:1, VIEWPORT_BOTTOM: 2, PARENT_TOP: 3, PARENT_BOTTOM: 4};
        var state=STATE.OFF;
        var spacerEnabled=false;
        var element_top,element_height,parent_top,parent_height,viewport_height;
        var createSpacer,destroySpacer,setElementState,tick,recalc;

        // mark as enabled
        if (elm.data("sticky_enabled")) return;
        elm.data("sticky_enabled", true);

        // determine parent
        parent = elm.parent();
        if (parent_selector !== null) parent = parent.closest(parent_selector);
        if (!parent.length) throw "failed to find sticky_parent";

        // check conditions
        if (elm.outerHeight(true) === parent.height()) {
            return;
        }

        // init spacer
        spacer = $("<div />");

        createSpacer = function() {
            if (spacerEnabled) return;
            spacerEnabled=true;

            spacer.css({
              width: elm.outerWidth(true),
              height: elm.outerHeight(true),
              display: elm.css("display"),
              "vertical-align": elm.css("vertical-align"),
              "float": elm.css("float"),
              'position': elm.css('position'),
              visibility:'hidden'
            });

            elm.after(spacer);
        };

        destroySpacer = function() {
            if (!spacerEnabled) return;
            spacerEnabled = false;

            spacer.detach();
        };

        setElementState = function(s) {
            if (s===state) return;
            var oldstate=state;
            state=s;

            if (s==STATE.OFF) {
                elm.css({
                    position: "",
                    top: "",
                    width: "",
                    height: "",
                    bottom: "",
                    "z-index": ""
                });
                parent.css("position", "");

                if (oldstate==STATE.VIEWPORT_TOP) {
                    if (scrollarea_offset.indexOf("t")!==-1) {
                        blueleaf.scrollarea.changeOffset({top:-elm.outerHeight(true)});
                    }                }
                else if (oldstate==STATE.VIEWPORT_BOTTOM) {
                    if (scrollarea_offset.indexOf("b")!==-1) {
                        blueleaf.scrollarea.changeOffset({bottom:-elm.outerHeight(true)});
                    }
                }

                elm.removeClass(sticky_class);
            }
            else {
                elm.addClass(sticky_class);

                if (s==STATE.VIEWPORT_TOP) {
                    if (scrollarea_offset.indexOf("t")!==-1) {
                        blueleaf.scrollarea.changeOffset({top:elm.outerHeight(true)});
                    }

                    elm.css ({
                        position: "fixed",
                        "z-index": z_index,
                        top: 0,
                        bottom: "",
                        width: elm.css("box-sizing") === "border-box" ? elm.outerWidth() + "px" : elm.width() + "px",
                        height: elm.css("box-sizing") === "border-box" ? elm.outerHeight() + "px" : elm.height() + "px"
                    });
                }
                else if (s==STATE.VIEWPORT_BOTTOM) {
                    if (scrollarea_offset.indexOf("b")!==-1) {
                        blueleaf.scrollarea.changeOffset({bottom:elm.outerHeight(true)});
                    }

                    elm.css ({
                        position: "fixed",
                        "z-index": z_index,
                        top: "",
                        bottom: 0,
                        width: elm.css("box-sizing") === "border-box" ? elm.outerWidth() + "px" : elm.width() + "px",
                        height: elm.css("box-sizing") === "border-box" ? elm.outerHeight() + "px" : elm.height() + "px"
                    });
                }
                else if (s==STATE.PARENT_TOP) {
                    elm.css ({
                        position: "absolute",
                        "z-index": z_index,
                        top: parent.css("padding-top"),
                        bottom:"",
                        width: elm.css("box-sizing") === "border-box" ? elm.outerWidth() + "px" : elm.width() + "px",
                        height: elm.css("box-sizing") === "border-box" ? elm.outerHeight() + "px" : elm.height() + "px"
                    });
                }
                else if (s==STATE.PARENT_BOTTOM) {
                    elm.css ({
                        position: "absolute",
                        "z-index": z_index,
                        top: "",
                        bottom: parent.css("padding-bottom"),
                        width: elm.css("box-sizing") === "border-box" ? elm.outerWidth() + "px" : elm.width() + "px",
                        height: elm.css("box-sizing") === "border-box" ? elm.outerHeight() + "px" : elm.height() + "px"
                    });
                }

                if (parent.css("position") === "static") parent.css("position", "relative");
            }
        };

        recalc = function() {
            if (!elm.data("sticky_enabled")) return;

            destroySpacer();
            setElementState(STATE.OFF);

            element_top = elm.offset().top;
            element_height = elm.outerHeight(true);
            parent_top = parent.offset().top + parseInt(parent.css("border-top-width")) + parseInt(parent.css("padding-top"));
            parent_height = parent.height();
            viewport_height = $(window).height();

            elm.addClass(sticky_class);
            element_top-=parseInt(elm.css("margin-top"));
            element_height+=parseInt(elm.css("margin-top"))+parseInt(elm.css("margin-bottom"));
            elm.removeClass(sticky_class);

            tick();
        };

        tick = function() {
            if (!elm.data("sticky_enabled")) return;

            var scroll = $(window).scrollTop();

            if (scroll>element_top && stick_directions.indexOf("t")!==-1) {
                if (scroll+element_height>parent_top+parent_height) {
                    createSpacer();
                    setElementState(STATE.PARENT_BOTTOM);
                }
                else {
                    createSpacer();
                    setElementState(STATE.VIEWPORT_TOP);
                }
            }
            else if (scroll+viewport_height<element_top+element_height && stick_directions.indexOf("b")!==-1) {
                if (scroll+viewport_height<parent_top+element_height) {
                    createSpacer();
                    setElementState(STATE.PARENT_TOP);
                }
                else {
                    createSpacer();
                    setElementState(STATE.VIEWPORT_BOTTOM);
                }
            }
            else {
                destroySpacer();
                setElementState(STATE.OFF);
            }
        };

        detach = function() {
            if (!elm.data("sticky_enabled")) return;
            elm.removeData("sticky_enabled");

            $(window).off("scroll", tick);
            $(window).off("touchmove", tick);
            $(window).off("resize", recalc);
            elm.off("sticky_detach", detach);

            setElementState(STATE.OFF);
            destroySpacer();
            spacer.remove();
        };

        recalc();

        $(window).on("touchmove", tick);
        $(window).on("scroll", tick);
        $(window).on("resize", recalc);
        elm.on("sticky_detach", detach);
    };
    for (var _i = 0, _len = this.length; _i < _len; _i++) {
        var elm = this[_i];
        _fn($(elm));
    }
    return this;
  };

  $.fn.sticky_disable = function() {
    _fn = function(elm) {
        elm.trigger("sticky_detach");
    };
    for (var _i = 0, _len = this.length; _i < _len; _i++) {
        var elm = this[_i];
        _fn($(elm));
    }
    return this;
  };

})(jQuery);<commit_msg>Sticky: recalculate variables when a DOM mutation happens<commit_after>(function($) {
  $.fn.sticky_enable = function(opts) {
    var parent_selector, sticky_class, z_index, stick_directions, scrollarea_offset;
    var _fn;
    if (opts == null) {
      opts = {};
    }
    sticky_class = opts.sticky_class, parent_selector = opts.parent, z_index = opts.z_index, stick_directions = opts.stick_directions, scrollarea_offset=opts.scrollarea_offset;

    if (parent_selector == null) {
      parent_selector = void 0;
    }
    if (sticky_class == null) {
      sticky_class = "sticked";
    }
    if (stick_directions == null) {
      stick_directions = "t";
    }
    if (scrollarea_offset == null) {
      scrollarea_offset = "";
    }
    if (z_index == null) {
        z_index=1;
    }

    _fn = function(elm) {
        var parent,spacer;
        var STATE={OFF: 0, VIEWPORT_TOP:1, VIEWPORT_BOTTOM: 2, PARENT_TOP: 3, PARENT_BOTTOM: 4};
        var state=STATE.OFF;
        var spacerEnabled=false;
        var element_top,element_height,parent_top,parent_height,viewport_height;
        var createSpacer,destroySpacer,setElementState,tick,recalc;
        var observer;

        // mark as enabled
        if (elm.data("sticky_enabled")) return;
        elm.data("sticky_enabled", true);

        // determine parent
        parent = elm.parent();
        if (parent_selector !== null) parent = parent.closest(parent_selector);
        if (!parent.length) throw "failed to find sticky_parent";

        // check conditions
        if (elm.outerHeight(true) === parent.height()) {
            return;
        }

        // init spacer
        spacer = $("<div />");

        createSpacer = function() {
            if (spacerEnabled) return;
            spacerEnabled=true;

            spacer.css({
              width: elm.outerWidth(true),
              height: elm.outerHeight(true),
              display: elm.css("display"),
              "vertical-align": elm.css("vertical-align"),
              "float": elm.css("float"),
              'position': elm.css('position'),
              visibility:'hidden'
            });

            elm.after(spacer);
        };

        destroySpacer = function() {
            if (!spacerEnabled) return;
            spacerEnabled = false;

            spacer.detach();
        };

        setElementState = function(s) {
            if (s===state) return;
            var oldstate=state;
            state=s;

            if (s==STATE.OFF) {
                elm.css({
                    position: "",
                    top: "",
                    width: "",
                    height: "",
                    bottom: "",
                    "z-index": ""
                });
                parent.css("position", "");

                if (oldstate==STATE.VIEWPORT_TOP) {
                    if (scrollarea_offset.indexOf("t")!==-1) {
                        blueleaf.scrollarea.changeOffset({top:-elm.outerHeight(true)});
                    }                }
                else if (oldstate==STATE.VIEWPORT_BOTTOM) {
                    if (scrollarea_offset.indexOf("b")!==-1) {
                        blueleaf.scrollarea.changeOffset({bottom:-elm.outerHeight(true)});
                    }
                }

                elm.removeClass(sticky_class);
            }
            else {
                elm.addClass(sticky_class);

                if (s==STATE.VIEWPORT_TOP) {
                    if (scrollarea_offset.indexOf("t")!==-1) {
                        blueleaf.scrollarea.changeOffset({top:elm.outerHeight(true)});
                    }

                    elm.css ({
                        position: "fixed",
                        "z-index": z_index,
                        top: 0,
                        bottom: "",
                        width: elm.css("box-sizing") === "border-box" ? elm.outerWidth() + "px" : elm.width() + "px",
                        height: elm.css("box-sizing") === "border-box" ? elm.outerHeight() + "px" : elm.height() + "px"
                    });
                }
                else if (s==STATE.VIEWPORT_BOTTOM) {
                    if (scrollarea_offset.indexOf("b")!==-1) {
                        blueleaf.scrollarea.changeOffset({bottom:elm.outerHeight(true)});
                    }

                    elm.css ({
                        position: "fixed",
                        "z-index": z_index,
                        top: "",
                        bottom: 0,
                        width: elm.css("box-sizing") === "border-box" ? elm.outerWidth() + "px" : elm.width() + "px",
                        height: elm.css("box-sizing") === "border-box" ? elm.outerHeight() + "px" : elm.height() + "px"
                    });
                }
                else if (s==STATE.PARENT_TOP) {
                    elm.css ({
                        position: "absolute",
                        "z-index": z_index,
                        top: parent.css("padding-top"),
                        bottom:"",
                        width: elm.css("box-sizing") === "border-box" ? elm.outerWidth() + "px" : elm.width() + "px",
                        height: elm.css("box-sizing") === "border-box" ? elm.outerHeight() + "px" : elm.height() + "px"
                    });
                }
                else if (s==STATE.PARENT_BOTTOM) {
                    elm.css ({
                        position: "absolute",
                        "z-index": z_index,
                        top: "",
                        bottom: parent.css("padding-bottom"),
                        width: elm.css("box-sizing") === "border-box" ? elm.outerWidth() + "px" : elm.width() + "px",
                        height: elm.css("box-sizing") === "border-box" ? elm.outerHeight() + "px" : elm.height() + "px"
                    });
                }

                if (parent.css("position") === "static") parent.css("position", "relative");
            }
        };

        recalc = function() {
            if (!elm.data("sticky_enabled")) return;

            destroySpacer();
            setElementState(STATE.OFF);

            element_top = elm.offset().top;
            element_height = elm.outerHeight(true);
            parent_top = parent.offset().top + parseInt(parent.css("border-top-width")) + parseInt(parent.css("padding-top"));
            parent_height = parent.height();
            viewport_height = $(window).height();

            elm.addClass(sticky_class);
            element_top-=parseInt(elm.css("margin-top"));
            element_height+=parseInt(elm.css("margin-top"))+parseInt(elm.css("margin-bottom"));
            elm.removeClass(sticky_class);

            tick();
        };

        tick = function() {
            if (!elm.data("sticky_enabled")) return;

            var scroll = $(window).scrollTop();

            if (scroll>element_top && stick_directions.indexOf("t")!==-1) {
                if (scroll+element_height>parent_top+parent_height) {
                    createSpacer();
                    setElementState(STATE.PARENT_BOTTOM);
                }
                else {
                    createSpacer();
                    setElementState(STATE.VIEWPORT_TOP);
                }
            }
            else if (scroll+viewport_height<element_top+element_height && stick_directions.indexOf("b")!==-1) {
                if (scroll+viewport_height<parent_top+element_height) {
                    createSpacer();
                    setElementState(STATE.PARENT_TOP);
                }
                else {
                    createSpacer();
                    setElementState(STATE.VIEWPORT_BOTTOM);
                }
            }
            else {
                destroySpacer();
                setElementState(STATE.OFF);
            }
        };

        detach = function() {
            if (!elm.data("sticky_enabled")) return;
            elm.removeData("sticky_enabled");

            $(window).off("scroll", tick);
            $(window).off("touchmove", tick);
            $(window).off("resize", recalc);
            elm.off("sticky_detach", detach);

            observer.disconnect();

            setElementState(STATE.OFF);
            destroySpacer();
            spacer.remove();
        };

        recalc();

        $(window).on("touchmove", tick);
        $(window).on("scroll", tick);
        $(window).on("resize", recalc);
        elm.on("sticky_detach", detach);

        observer = new MutationObserver(function(mutations) {
            recalc();
        });

        elm.uniqueId();
        observer.observe(document.getElementById(elm.attr('id')), { attributes:false,childList:true,characterData:true,subtree:true });
    };
    for (var _i = 0, _len = this.length; _i < _len; _i++) {
        var elm = this[_i];
        _fn($(elm));
    }
    return this;
  };

  $.fn.sticky_disable = function() {
    _fn = function(elm) {
        elm.trigger("sticky_detach");
    };
    for (var _i = 0, _len = this.length; _i < _len; _i++) {
        var elm = this[_i];
        _fn($(elm));
    }
    return this;
  };

})(jQuery);<|endoftext|>


<commit_before>'use strict';

window.addEventListener('message', msg => {
    if (msg.data && msg.data.installGiphy) {
        injectCSSFile('extension.css');
        injectJSFile('bundle.js');
    };

    if (msg.data && msg.data.giphySearch) {
        chrome.runtime.sendMessage({
            giphySearch: true,
            query: msg.data.query
        }, res => {
            window.postMessage({
                giphyResponse: true,
                res: res
            }, '*');
        });
    }
});

function messageIfFound(window) {
    'use strict';

    try {
        // Determine if the page is truly a GitHub page. Use their
        // feature detection to detect them :)
        require('github/feature-detection');
        window.postMessage({ installGiphy: true }, '*');
    } catch(err) {}
}

function runFnInPage(fn) {
    const script = document.createElement('script');
    script.textContent = `;(${fn.toString()}(window))`;
    document.documentElement.appendChild(script);
    script.parentNode.removeChild(script);
}

function injectCSSFile(path) {
    const link = document.createElement('link');
    link.type = 'text/css';
    link.rel = 'stylesheet';
    link.href = chrome.extension.getURL(path);
    document.body.appendChild(link);
}

function injectJSFile(path) {
    const inspectorScript = document.createElement('script');
    inspectorScript.src = chrome.extension.getURL(path);
    document.documentElement.appendChild(inspectorScript);
}

runFnInPage(messageIfFound);
<commit_msg>Dont break gitlab<commit_after>'use strict';

window.addEventListener('message', msg => {
    if (msg.data && msg.data.installGiphy) {
        injectCSSFile('extension.css');
        injectJSFile('bundle.js');
    };

    if (msg.data && msg.data.giphySearch) {
        chrome.runtime.sendMessage({
            giphySearch: true,
            query: msg.data.query
        }, res => {
            window.postMessage({
                giphyResponse: true,
                res: res
            }, '*');
        });
    }
});

function messageIfFound(window) {
    'use strict';

    try {
        // Determine if the page is truly a GitHub page. Use their
        // feature detection to detect them :)
        const isGitHub = !!require('github/feature-detection');
        if (isGitHub) window.postMessage({ installGiphy: true }, '*');
    } catch(err) {}
}

function runFnInPage(fn) {
    const script = document.createElement('script');
    script.textContent = `;(${fn.toString()}(window))`;
    document.documentElement.appendChild(script);
    script.parentNode.removeChild(script);
}

function injectCSSFile(path) {
    const link = document.createElement('link');
    link.type = 'text/css';
    link.rel = 'stylesheet';
    link.href = chrome.extension.getURL(path);
    document.body.appendChild(link);
}

function injectJSFile(path) {
    const inspectorScript = document.createElement('script');
    inspectorScript.src = chrome.extension.getURL(path);
    document.documentElement.appendChild(inspectorScript);
}

runFnInPage(messageIfFound);
<|endoftext|>


<commit_before>var five = require('johnny-five');

var board = new five.Board({ port: '/dev/ttyAMA0'});
board.on('ready', function () {
  console.log('Board is ready');
});

var controllers = {};

var addController = function (path) {
  // 1. Require the controller
  var controller = require(path)(five);
  console.log('new controller added');
  console.log(controller);

  // 2. Add the controller to controller list
  controllers[controller.id] = controller;
};

var execute = function(controllerID, functionName) {
  console.log(controllerID, functionName);

  controllers[controllerID][functionName]();
};

// var listControllers = function () {

// };

module.exports = {
  addController: addController,
  execute: execute,
  board: board,
};<commit_msg>refactor all the way<commit_after>var five = require('johnny-five');

var board = new five.Board({ port: '/dev/ttyAMA0'});
board.on('ready', function () {
  console.log('Board is ready');
});

var controllers = {};

var addController = function (path) {
  // 1. Require the controller
  var controller = require(path)(five);
  console.log('new controller added');
  console.log(controller);

  // 2. Add the controller to controller list
  controllers[controller.id] = controller;
};

var execute = function(controllerID, functionName) {
  console.log(controllerID, functionName);

  console.log(controllers[controllerID]);
  console.log(controllers[controllerID][functionName]);

  controllers[controllerID][functionName]();
};

// var listControllers = function () {

// };

module.exports = {
  addController: addController,
  execute: execute,
  board: board,
};<|endoftext|>