<commit_before>function ListWidget(offers_selector, current_tags_selector) {

    var offers;
    var tags;
    var offers_render_fn;
    var current_tags;
    var offers_uri;
    var _offers_updated=new Array();
    var map;

    var offers_directives = {
        'div.offer': {
            'offer <- Messages': {
                'a.username@href': 'offer.created_by.profile_url',
                'a.avatar@href': 'offer.created_by.profile_url',
                'a.username': 'offer.created_by.provider_user_name',
                '.avatar img@src': 'offer.created_by.profile_pic_url',
                '.msg .text': 'offer.offer_text',

                'span.tags': {
                    'tag <- offer.tags': {
                        'a': 'tag.tag'/*,
                        '+a@class': 'tag.type'*/
                    }
                },
                '.when': 'offer.timestamp'

            }
        }
    };

    var init = function() {

        offers_uri = container.offers_uri;
        //compile to a function as soon as possible (ie in 'constructor')
        offers_render_fn = $(offers_selector + ' .template').compile(offers_directives);
        current_tags = new TagsWidget(current_tags_selector);
        current_tags.on_tag_click(function(tag_text, tag_type) {
            remove_filter(tag_text);
            return false;
        });
    }

    var on_offers_updated = function(functionRef) {
        _offers_updated.push(functionRef);
    }

    var update_offers = function() {
        var json_url = current_tags.decorate_url(offers_uri);
        if (arguments.length > 0) json_url += "&username=" + arguments[1] + "&namespace=ooooby";
        $.getJSON(json_url, function(data) {
            $.each(data.Messages, function() {
                var overall = this.timestamp.split("T");
                var dates = overall[0].split("-");
                var times = overall[1].split(":");
                var time = times[0] + ":" + times[1];
                var date = dates[2] + "-" + dates[1] + "-" + dates[0];
                this.timestamp = time + " " + date;
                //this.timestamp = Date.parse(this.timestamp);
            }
            );
            $(offers_selector + ' .template').render(data, offers_render_fn);
            $(offers_selector + ' .tags a').click(function() {
                //add a filter when tags under a message are clicked
                add_filter($(this).text(), $(this).css());
            });
            offers = data.Messages;
            tags = data.Tags;
            if (!!_offers_updated) {
                $.each(_offers_updated, function() {
                    this(offers);
                });
            }
            $(offers_selector + " .template").quickPager({ pageSize: 4 }, "#pager");
        });
    };

    var add_filter = function(tag_text, tag_type) {
        current_tags.add_tag(tag_text, tag_type);
        current_tags.update_view();
        update_offers();
    };
    var filter_by_user = function(username) {
        update_offers(username);
    };
    var toggle_filter = function(tag_text, tag_type) {
        current_tags.toggle_filter(tag_text, tag_type);
        current_tags.update_view();
        update_offers();
    };

    var remove_filter = function(tag_text) {
        current_tags.remove_tag(tag_text);
        current_tags.update_view();
        update_offers();
    };

    var add_fixed_filter = function(tag_text, tag_type) {
        current_tags.add_fixed_tag(tag_text, tag_type, false);
        current_tags.update_view();
        update_offers();
    };

    init();

    /* 'public' methods */
    this.toggle_filter = toggle_filter;
    this.update_offers = update_offers;
    this.on_offers_updated = on_offers_updated;
    this.add_filter = add_filter;
    this.remove_filter = remove_filter;
    this.add_fixed_filter = add_fixed_filter;
    this.get_offers = function() {
        return offers;
    }
    this.get_tags = function() {
        return tags;
    }
    this.current_tags = function() {
        return current_tags;
    }
}

<commit_msg>attempt to add filter by user name 3<commit_after>function ListWidget(offers_selector, current_tags_selector) {

    var offers;
    var tags;
    var offers_render_fn;
    var current_tags;
    var offers_uri;
    var _offers_updated=new Array();
    var map;

    var offers_directives = {
        'div.offer': {
            'offer <- Messages': {
                'a.username@href': 'offer.created_by.profile_url',
                'a.avatar@href': 'offer.created_by.profile_url',
                'a.username': 'offer.created_by.provider_user_name',
                '.avatar img@src': 'offer.created_by.profile_pic_url',
                '.msg .text': 'offer.offer_text',

                'span.tags': {
                    'tag <- offer.tags': {
                        'a': 'tag.tag'/*,
                        '+a@class': 'tag.type'*/
                    }
                },
                '.when': 'offer.timestamp'

            }
        }
    };

    var init = function() {

        offers_uri = container.offers_uri;
        //compile to a function as soon as possible (ie in 'constructor')
        offers_render_fn = $(offers_selector + ' .template').compile(offers_directives);
        current_tags = new TagsWidget(current_tags_selector);
        current_tags.on_tag_click(function(tag_text, tag_type) {
            remove_filter(tag_text);
            return false;
        });
    }

    var on_offers_updated = function(functionRef) {
        _offers_updated.push(functionRef);
    }

    var update_offers = function() {
        var json_url = current_tags.decorate_url(offers_uri);
        if (arguments.length > 0) json_url += "&username=" + arguments[1] + "&namespace=ooooby";
        $.getJSON(json_url, function(data) {
            $.each(data.Messages, function() {
                var overall = this.timestamp.split("T");
                var dates = overall[0].split("-");
                var times = overall[1].split(":");
                var time = times[0] + ":" + times[1];
                var date = dates[2] + "-" + dates[1] + "-" + dates[0];
                this.timestamp = time + " " + date;
                //this.timestamp = Date.parse(this.timestamp);
            }
            );
            $(offers_selector + ' .template').render(data, offers_render_fn);
            $(offers_selector + ' .tags a').click(function() {
                //add a filter when tags under a message are clicked
                add_filter($(this).text(), $(this).css());
            });
            offers = data.Messages;
            tags = data.Tags;
            if (!!_offers_updated) {
                $.each(_offers_updated, function() {
                    this(offers);
                });
            }
            $(offers_selector + " .template").quickPager({ pageSize: 4 }, "#pager");
        });
    };

    var add_filter = function(tag_text, tag_type) {
        current_tags.add_tag(tag_text, tag_type);
        current_tags.update_view();
        update_offers();
    };
    var filter_by_user = function(username) {
        update_offers(username);
    };
    var toggle_filter = function(tag_text, tag_type) {
        current_tags.toggle_filter(tag_text, tag_type);
        current_tags.update_view();
        update_offers();
    };

    var remove_filter = function(tag_text) {
        current_tags.remove_tag(tag_text);
        current_tags.update_view();
        update_offers();
    };

    var add_fixed_filter = function(tag_text, tag_type) {
        current_tags.add_fixed_tag(tag_text, tag_type, false);
        current_tags.update_view();
        update_offers();
    };

    init();

    /* 'public' methods */
    this.filter_by_user = filter_by_user;
    this.toggle_filter = toggle_filter;
    this.update_offers = update_offers;
    this.on_offers_updated = on_offers_updated;
    this.add_filter = add_filter;
    this.remove_filter = remove_filter;
    this.add_fixed_filter = add_fixed_filter;
    this.get_offers = function() {
        return offers;
    }
    this.get_tags = function() {
        return tags;
    }
    this.current_tags = function() {
        return current_tags;
    }
}

<|endoftext|>


<commit_before>import Ember from 'ember';

export function mergedHash( params, hash ) {
  // Assumes all params are objects
  if ( params.length > 0 ) {
    let merged = {};

    // Use Ember.assign() if available (added in ember v2.5)
    if ( Ember.assign ) {
      merged = Ember.assign( merged, ...params, hash );

    // Fall back to Ember.merge() (depreciated as of ember v2.5)
    } else {
      params.forEach( param => {
        merged = Ember.merge( merged, param );
      });
      merged = Ember.merge( merged, hash );
    }

    return merged;
  } else {
    return hash;
  }
} // mergedHash()

export default Ember.Helper.helper(mergedHash);
<commit_msg>Have the `{{merged-hash}}` helper use the `assign` polyfill<commit_after>import Ember from 'ember';
import assign from 'ember-assign-polyfill';

export function mergedHash( params, hash ) {
  // Assumes all params are objects
  if ( params.length > 0 ) {
    return assign( {}, ...params, hash );
  } else {
    return hash;
  }
} // mergedHash()

export default Ember.Helper.helper(mergedHash);
<|endoftext|>


<commit_before>/**
 * Client to connect to a darkwallet gateway.
 *
 * @param {String}   connect_uri Gateway websocket URI
 * @param {Function} handle_connect Callback to run when connected
 */
function GatewayClient(connect_uri, handle_connect) {
    var self = this;
    this.handler_map = {};
    this.websocket = new WebSocket(connect_uri);
    this.websocket.onopen = function(evt) {
        handle_connect();
    };
    this.websocket.onclose = function(evt) {
        self.on_close(evt);
    };
    this.websocket.onerror = function(evt) {
        self.on_error(evt);
    };
    this.websocket.onmessage = function(evt) {
        self._on_message(evt);
    };
}

/**
 * Get last height
 *
 * @param {Function} handle_fetch Callback to handle the returned height
 */
GatewayClient.prototype.fetch_last_height = function(handle_fetch) {
    GatewayClient._check_function(handle_fetch);

    this.make_request("fetch_last_height", [], function(response) {
        handle_fetch(response["error"], response["result"][0]);
    });
};

/**
 * Fetch transaction
 *
 * @param {String}   tx_hash Transaction identifier hash
 * @param {Function} handle_fetch Callback to handle the JSON object
 * representing the transaction
 */
GatewayClient.prototype.fetch_transaction = function(tx_hash, handle_fetch) {
    GatewayClient._check_function(handle_fetch);

    this.make_request("fetch_transaction", [tx_hash], function(response) {
        handle_fetch(response["error"], response["result"][0]);
    });
};

/**
 * Fetch history
 *
 * @param {String}   address
 * @param {Function} handle_fetch Callback to handle the JSON object
 * representing the history of the address
 */
GatewayClient.prototype.fetch_history = function(address, handle_fetch) {
    GatewayClient._check_function(handle_fetch);

    this.make_request("fetch_history", [address], function(response) {
        handle_fetch(response["error"], response["result"][0]);
    });
};

GatewayClient.prototype.fetch_stealth = function(
    prefix, handle_fetch, from_height)
{
    GatewayClient._check_function(handle_fetch);

    this.make_request("fetch_stealth", [prefix, from_height],
        function(response) {
            handle_fetch(response["error"], response["result"][0]);
        });
};

/**
 * Subscribe
 *
 * @param {String}   address
 * @param {Function} handle_fetch Callback to handle subscription result
 * @param {Function} handle_update Callback to handle the JSON object
 * representing for updates
 */
GatewayClient.prototype.subscribe = function(
    address, handle_fetch, handle_update)
{
    var self = this;
    this.make_request("subscribe_address", [address], function(response) {
        handle_fetch(response["error"], response["result"][0]);
        if (handle_update) {
            self.handler_map["update." + address] = handle_update;
        }
    });
}

GatewayClient.prototype.fetch_block_header = function(index, handle_fetch) {
    GatewayClient._check_function(handle_fetch);

    this.make_request("fetch_block_header", [index], function(response) {
        handle_fetch(response["error"], response["result"][0]);
    });
};

GatewayClient.prototype.fetch_block_transaction_hashes = function(
    index, handle_fetch)
{
    GatewayClient._check_function(handle_fetch);

    this.make_request("fetch_block_transaction_hashes", [index],
        function(response) {
            handle_fetch(response["error"], response["result"][0]);
        });
};

GatewayClient.prototype.fetch_spend = function(outpoint, handle_fetch) {
    GatewayClient._check_function(handle_fetch);

    this.make_request("fetch_spend", [outpoint], function(response) {
        handle_fetch(response["error"], response["result"][0]);
    });
};

GatewayClient.prototype.fetch_transaction_index = function(
    tx_hash, handle_fetch)
{
    GatewayClient._check_function(handle_fetch);

    this.make_request("fetch_transaction_index", [tx_hash],
        function(response) {
            result = response["result"];
            handle_fetch(response["error"], result[0], result[1]);
        });
};

GatewayClient.prototype.fetch_block_height = function(blk_hash, handle_fetch)
{
    GatewayClient._check_function(handle_fetch);

    this.make_request("fetch_block_height", [blk_hash], function(response) {
        handle_fetch(response["error"], response["result"][0]);
    });
};

GatewayClient.prototype.broadcast_transaction = function(
    raw_tx, handle_fetch)
{
    GatewayClient._check_function(handle_fetch);

    this.make_request("broadcast_transaction", [raw_tx], function(response) {
        handle_fetch(response["error"], response["result"][0]);
    });
};

/**
 * Renew
 *
 * @param {String}   address
 * @param {Function} handle_fetch Callback to handle subscription result
 * @param {Function} handle_update Callback to handle the JSON object
 * representing for updates
 */
GatewayClient.prototype.renew = function(address, handle_fetch, handle_update)
{
    var self = this;
    this.make_request("renew_address", [address], function(response) {
        handle_fetch(response["error"], response["result"][0]);
        if (handle_update) {
            self.handler_map["update."+address] = handle_update;
        }
    });
}

/**
 * Chan functionality
 */
GatewayClient.prototype.chan_post = function(section_name, thread_id, data, handle_fetch) {
    GatewayClient._check_function(handle_fetch);

    this.make_request("chan_post", [section_name, thread_id, data], function(response) {
        if (handle_fetch)
            console.log("raw chan post", response["result"]);
            handle_fetch(response["error"], response["result"]);
    });
};

GatewayClient.prototype.chan_list = function(section_name, handle_fetch) {
    GatewayClient._check_function(handle_fetch);

    this.make_request("chan_list", [section_name], function(response) {
        if (handle_fetch)
            handle_fetch(response["error"], response["result"]);
    });
};

GatewayClient.prototype.chan_get = function(section_name, thread_id, handle_fetch) {
    GatewayClient._check_function(handle_fetch);

    this.make_request("chan_get", [section_name, thread_id], function(response) {
        if (handle_fetch)
            handle_fetch(response["error"], response["result"]);
    });
};

/**
 * Make requests to the server
 *
 * @param {String} command
 * @param {Array} params
 * @param {Function} handler
 */
GatewayClient.prototype.make_request = function(command, params, handler) {
    GatewayClient._check_function(handler);

    var id = GatewayClient._random_integer();
    var request = {
        "id": id,
        "command": command,
        "params": params
    };
    var message = JSON.stringify(request);
    this.websocket.send(message);
    this.handler_map[id] = handler;
};

/**
 * Close event handler
 *
 * @param {Object} evt event
 */
GatewayClient.prototype.on_close = function(evt) {
};

/**
 * Error event handler
 *
 * @param {Object} evt event
 *
 * @throws {Object}
 */
GatewayClient.prototype.on_error = function(evt) {
    throw evt;
};

/**
 * After triggering message event, calls to the handler of the petition
 *
 * @param {Object} evt event
 * @private
 */
GatewayClient.prototype._on_message = function(evt) {
    this.on_message(evt)
    response = JSON.parse(evt.data);
    id = response.id;
    // Should be a separate map entirely. This is a hack.
    if (response.name == "update")
        id = "update." + response.address;
    // Prefer flat code over nested.
    if (!this.handler_map[id]) {
        console.log("Handler not found");
        return;
    }
    handler = this.handler_map[id];
    handler(response);
};

/**
 * Message event handler
 *
 * @param {Object} evt event
 */
GatewayClient.prototype.on_message = function(evt) {
}

/**
 * (Pseudo-)Random integer generator
 *
 * @return {Number} Random integer
 * @private
 */
GatewayClient._random_integer = function() {
    return Math.floor((Math.random() * 4294967296));
};

/**
 * Checks if param can be executed
 *
 * @param {Function} Function to be checked
 *
 * @throws {String} Parameter is not a function
 * @protected
 */
GatewayClient._check_function = function(func) {
    if (typeof func !== 'function') {
        throw "Parameter is not a function";
    }
};

<commit_msg>update gateway.js to latest upstream version<commit_after>/**
 * Client to connect to a darkwallet gateway.
 *
 * @param {String}   connect_uri Gateway websocket URI
 * @param {Function} handle_connect Callback to run when connected
 */
function GatewayClient(connect_uri, handle_connect) {
    var self = this;
    this.handler_map = {};
    this.websocket = new WebSocket(connect_uri);
    this.websocket.onopen = function(evt) {
        handle_connect();
    };
    this.websocket.onclose = function(evt) {
        self.on_close(evt);
    };
    this.websocket.onerror = function(evt) {
        self.on_error(evt);
    };
    this.websocket.onmessage = function(evt) {
        self._on_message(evt);
    };
}

/**
 * Get last height
 *
 * @param {Function} handle_fetch Callback to handle the returned height
 */
GatewayClient.prototype.fetch_last_height = function(handle_fetch) {
    GatewayClient._check_function(handle_fetch);

    this.make_request("fetch_last_height", [], function(response) {
        handle_fetch(response["error"], response["result"][0]);
    });
};

/**
 * Fetch transaction
 *
 * @param {String}   tx_hash Transaction identifier hash
 * @param {Function} handle_fetch Callback to handle the JSON object
 * representing the transaction
 */
GatewayClient.prototype.fetch_transaction = function(tx_hash, handle_fetch) {
    GatewayClient._check_function(handle_fetch);

    this.make_request("fetch_transaction", [tx_hash], function(response) {
        handle_fetch(response["error"], response["result"][0]);
    });
};

/**
 * Fetch history
 *
 * @param {String}   address
 * @param {Function} handle_fetch Callback to handle the JSON object
 * representing the history of the address
 */
GatewayClient.prototype.fetch_history = function(address, handle_fetch) {
    GatewayClient._check_function(handle_fetch);

    this.make_request("fetch_history", [address], function(response) {
        handle_fetch(response["error"], response["result"][0]);
    });
};

GatewayClient.prototype.fetch_stealth = function(
    prefix, handle_fetch, from_height)
{
    GatewayClient._check_function(handle_fetch);

    this.make_request("fetch_stealth", [prefix, from_height],
        function(response) {
            handle_fetch(response["error"], response["result"][0]);
        });
};

/**
 * Subscribe
 *
 * @param {String}   address
 * @param {Function} handle_fetch Callback to handle subscription result
 * @param {Function} handle_update Callback to handle the JSON object
 * representing for updates
 */
GatewayClient.prototype.subscribe = function(
    address, handle_fetch, handle_update)
{
    var self = this;
    this.make_request("subscribe_address", [address], function(response) {
        handle_fetch(response["error"], response["result"][0]);
        if (handle_update) {
            self.handler_map["update." + address] = handle_update;
        }
    });
}

GatewayClient.prototype.fetch_block_header = function(index, handle_fetch) {
    GatewayClient._check_function(handle_fetch);

    this.make_request("fetch_block_header", [index], function(response) {
        handle_fetch(response["error"], response["result"][0]);
    });
};

GatewayClient.prototype.fetch_block_transaction_hashes = function(
    index, handle_fetch)
{
    GatewayClient._check_function(handle_fetch);

    this.make_request("fetch_block_transaction_hashes", [index],
        function(response) {
            handle_fetch(response["error"], response["result"][0]);
        });
};

GatewayClient.prototype.fetch_spend = function(outpoint, handle_fetch) {
    GatewayClient._check_function(handle_fetch);

    this.make_request("fetch_spend", [outpoint], function(response) {
        handle_fetch(response["error"], response["result"][0]);
    });
};

GatewayClient.prototype.fetch_transaction_index = function(
    tx_hash, handle_fetch)
{
    GatewayClient._check_function(handle_fetch);

    this.make_request("fetch_transaction_index", [tx_hash],
        function(response) {
            result = response["result"];
            handle_fetch(response["error"], result[0], result[1]);
        });
};

GatewayClient.prototype.fetch_block_height = function(blk_hash, handle_fetch)
{
    GatewayClient._check_function(handle_fetch);

    this.make_request("fetch_block_height", [blk_hash], function(response) {
        handle_fetch(response["error"], response["result"][0]);
    });
};

GatewayClient.prototype.broadcast_transaction = function(
    raw_tx, handle_fetch)
{
    GatewayClient._check_function(handle_fetch);

    this.make_request("broadcast_transaction", [raw_tx], function(response) {
        handle_fetch(response["error"], response["result"][0]);
    });
};

/**
 * Renew
 *
 * @param {String}   address
 * @param {Function} handle_fetch Callback to handle subscription result
 * @param {Function} handle_update Callback to handle the JSON object
 * representing for updates
 */
GatewayClient.prototype.renew = function(address, handle_fetch, handle_update)
{
    var self = this;
    this.make_request("renew_address", [address], function(response) {
        handle_fetch(response["error"], response["result"][0]);
        if (handle_update) {
            self.handler_map["update."+address] = handle_update;
        }
    });
}

/**
 * Chan functionality
 */
GatewayClient.prototype.chan_post = function(section_name, thread_id, data, handle_fetch) {
    GatewayClient._check_function(handle_fetch);

    this.make_request("chan_post", [section_name, thread_id, data], function(response) {
        if (handle_fetch)
            console.log("raw chan post", response["result"]);
            handle_fetch(response["error"], response["result"]);
    });
};

GatewayClient.prototype.chan_list = function(section_name, handle_fetch) {
    GatewayClient._check_function(handle_fetch);

    this.make_request("chan_list", [section_name], function(response) {
        if (handle_fetch)
            handle_fetch(response["error"], response["result"]);
    });
};

GatewayClient.prototype.chan_get = function(section_name, thread_id, handle_fetch) {
    GatewayClient._check_function(handle_fetch);

    this.make_request("chan_get", [section_name, thread_id], function(response) {
        if (handle_fetch)
            handle_fetch(response["error"], response["result"]);
    });
};

GatewayClient.prototype.chan_subscribe = function(section_name, thread_id, handle_fetch, handle_update) {
    GatewayClient._check_function(handle_fetch);
    var self = this;
    this.make_request("chan_subscribe", [section_name, thread_id], function(response) {
        if (handle_fetch)
            handle_fetch(response["error"], response["result"]);
        if (handle_update) {
            self.handler_map["chan.update." + thread_id] = handle_update;
        }

    });
};

/**
 * Make requests to the server
 *
 * @param {String} command
 * @param {Array} params
 * @param {Function} handler
 */
GatewayClient.prototype.make_request = function(command, params, handler) {
    GatewayClient._check_function(handler);

    var id = GatewayClient._random_integer();
    var request = {
        "id": id,
        "command": command,
        "params": params
    };
    var message = JSON.stringify(request);
    this.websocket.send(message);
    this.handler_map[id] = handler;
};

/**
 * Close event handler
 *
 * @param {Object} evt event
 */
GatewayClient.prototype.on_close = function(evt) {
};

/**
 * Error event handler
 *
 * @param {Object} evt event
 *
 * @throws {Object}
 */
GatewayClient.prototype.on_error = function(evt) {
    throw evt;
};

/**
 * After triggering message event, calls to the handler of the petition
 *
 * @param {Object} evt event
 * @private
 */
GatewayClient.prototype._on_message = function(evt) {
    this.on_message(evt)
    response = JSON.parse(evt.data);
    id = response.id;
    // Should be a separate map entirely. This is a hack.
    if (response.type == "update")
        id = "update." + response.address;
    if (response.type == "chan_update")
        id = "chan.update." + response.thread;
    // Prefer flat code over nested.
    if (!this.handler_map[id]) {
        console.log("Handler not found", id);
        return;
    }
    handler = this.handler_map[id];
    handler(response);
};

/**
 * Message event handler
 *
 * @param {Object} evt event
 */
GatewayClient.prototype.on_message = function(evt) {
}

/**
 * (Pseudo-)Random integer generator
 *
 * @return {Number} Random integer
 * @private
 */
GatewayClient._random_integer = function() {
    return Math.floor((Math.random() * 4294967296));
};

/**
 * Checks if param can be executed
 *
 * @param {Function} Function to be checked
 *
 * @throws {String} Parameter is not a function
 * @protected
 */
GatewayClient._check_function = function(func) {
    if (typeof func !== 'function') {
        throw "Parameter is not a function";
    }
};

<|endoftext|>


<commit_before>/**
 * Form validation
 */
bolt.validation = (function () {

    /**
     * Basic legacy validation checking
     * Adapted from  http://www.sitepoint.com/html5-forms-javascript-constraint-validation-api/
     *
     * @param {Object} field - Field element
     * @returns {boolean}
     */
    function legacyValidation(field) {
        var
            valid = true,
            val = field.value,
            type = field.getAttribute('type'),
            chkbox = type === 'checkbox' || type === 'radio',
            required = field.getAttribute('required'),
            minlength = field.getAttribute('minlength'),
            maxlength = field.getAttribute('maxlength'),
            pattern = field.getAttribute('pattern');

        // Disabled fields should not be validated
        if (field.disabled) {
            return valid;
        }

        /* jshint -W126 */

        // value required?
        valid = valid && (!required ||
            (chkbox && field.checked) ||
            (!chkbox && val !== "")
        );

        // minlength or maxlength set?
        valid = valid && (chkbox || (
            (!minlength || val.length >= minlength) &&
            (!maxlength || val.length <= maxlength)
        ));

        /* jshint +W126 */

        // Test pattern
        if (valid && pattern) {
            pattern = new RegExp('^(?:' + pattern + ')$');
            valid = pattern.test(val);
        }

        return valid;
    }

    /**
     * Adds error classes to field
     *
     * @param {Object} field - Field element
     * @param {boolean} isCkeditor - Is a isCkeditor field
     */
    function addErrorClass(field, isCkeditor) {
        $(field).addClass('error');

        if (isCkeditor) {
            $('#cke_' + field.id).addClass('cke_error');
        }
    }

    /**
     * Removes error classes from field
     *
     * @param {Object} field - Field element
     * @param {boolean} isCkeditor - Is a isCkeditor field
     */
    function removeErrorClass(field, isCkeditor) {
        $(field).removeClass('error');

        if (isCkeditor) {
            $('#cke_' + field.id).removeClass('cke_error');
        }
    }

    /**
     * Show alertbox
     *
     * @param {string} id - Id of the alertbox
     * @param {string} msg - Message text
     */
    function showAlertbox(id, msg) {
        var alertbox = bolt.data.editcontent.error.alertbox.subst({
            '%NOTICE_ID%': id,
            '%MESSAGE%': msg
        });

        $(alertbox)
            .hide()
            .insertAfter('.page-header')
            .slideDown('fast');
    }

    /**
     * Checks if value is a float
     *
     * @param {string} value - Value of field
     * @returns {string}
     */
    function checkFloat(value) {
        if (value !== '' && !value.match(/^[-+]?[0-9]*[,.]?[0-9]+([eE][-+]?[0-9]+)?$/)) {
            return bolt.data.validation.float;
        } else {
            return '';
        }
    }

    /**
     * Validates a field
     *
     * @param {Object} field - Field element
     * @returns {boolean}
     */
    function validate(field) {
        var hasNativeValidation = typeof field.willValidate !== 'undefined',
            isCkeditor,
            task,
            param,
            value = field.value,
            error,
            label;

        var validates = $(field).data('validate');
        if (validates) {
            for (task in validates) {
                param = validates[task];

                switch (task) {
                    case 'float':
                        error = checkFloat(value);
                        break;

                    case 'required':
                        if (param === true && value === '') {
                            error = bolt.data.validation.required;
                        }
                        break;

                    case 'min':
                        if (value !== '' && Number(value.replace(',', '.')) < param) {
                            error = bolt.data.validation.min.subst({'%MINVAL%': param});
                        }
                        break;

                    case 'max':
                        if (value !== '' && Number(value.replace(',', '.')) > param) {
                            error = bolt.data.validation.max.subst({'%MAXVAL%': param});
                        }
                        break;

                    default:
                        console.log('UNKNOWN VALIDATION' + task + " -> " + param);
                }
                // Stop on first error
                if (error) {
                    // Insert label
                    label = $('label[for="' + field.id + '"]').contents().first().text().trim();
                    error = error.subst({'%FIELDNAME%': label ? label : field.name});

                    if (hasNativeValidation) {
                        field.setCustomValidity(error);
                    } else {
                        field.validity.valid = false;
                    }
                    break;
                } else {
                    if (hasNativeValidation) {
                        field.setCustomValidity('');
                    } else {
                        field.validity.valid = true;
                    }
                }
            }
        } else {
            // Is native browser validation available?
            if (hasNativeValidation) {
                // Native validation available
                if (field.nodeName === 'INPUT' && field.type !== field.getAttribute('type')) {
                    // Input type not supported! Use legacy JavaScript validation
                    field.setCustomValidity(legacyValidation(field) ? '' : 'error');
                }
                // Native browser check
                field.checkValidity();
            } else {
                // Native validation not available
                field.validity = field.validity || {};
                // Set to result of validation function
                field.validity.valid = legacyValidation(field);

                // If "invalid" events are required, trigger it here
            }

            // Special validation for CKEditor fields
            isCkeditor = field.nodeName === 'TEXTAREA' && $(field).hasClass('ckeditor');
            if (isCkeditor) {
                var editor = CKEDITOR.instances[field.id],
                    invalid;

                if (editor) {
                    invalid = editor._.required === true && editor.getData().trim() === '';
                    if (hasNativeValidation) {
                        field.setCustomValidity(invalid ? 'Required' : '');
                    } else {
                        field.validity.valid = !invalid;
                    }
                }
            }
        }

        var noticeID = 'notice--' + field.id;

        // First, remove any existing old notices
        $('#' + noticeID).remove();

        if (field.validity.valid) {
            removeErrorClass(field, isCkeditor);

            return true;
        } else {
            addErrorClass(field, isCkeditor);

            var msg = error || $(field).data('errortext');
            if (!msg) {
                msg = bolt.data.editcontent.error.msg.subst({'%FIELDNAME%': field.name});
            }
            showAlertbox(noticeID, msg);

            return false;
        }
    }

    return {
        /**
         * Validates all inputs of a form
         *
         * @param {Object} form - Form element
         * @returns {boolean}
         */
        run: function (form) {
            var formLength = form.elements.length,
                f,
                field,
                formvalid = true;

            // Loop all fields
            for (f = 0; f < formLength; f++) {
                field = form.elements[f];

                if (field.nodeName !== 'INPUT' && field.nodeName !== 'TEXTAREA' && field.nodeName !== 'SELECT') {
                    continue;
                }

                if (field.nodeName === 'INPUT') {
                    // Trim input values
                    field.value = field.value.trim();
                }

                if (validate(field) === false) {
                    formvalid = false;
                }
            }

            return formvalid;
        }
    };
} ());
<commit_msg>Move required check in own method<commit_after>/**
 * Form validation
 */
bolt.validation = (function () {

    /**
     * Basic legacy validation checking
     * Adapted from  http://www.sitepoint.com/html5-forms-javascript-constraint-validation-api/
     *
     * @param {Object} field - Field element
     * @returns {boolean}
     */
    function legacyValidation(field) {
        var
            valid = true,
            val = field.value,
            type = field.getAttribute('type'),
            chkbox = type === 'checkbox' || type === 'radio',
            required = field.getAttribute('required'),
            minlength = field.getAttribute('minlength'),
            maxlength = field.getAttribute('maxlength'),
            pattern = field.getAttribute('pattern');

        // Disabled fields should not be validated
        if (field.disabled) {
            return valid;
        }

        /* jshint -W126 */

        // value required?
        valid = valid && (!required ||
            (chkbox && field.checked) ||
            (!chkbox && val !== "")
        );

        // minlength or maxlength set?
        valid = valid && (chkbox || (
            (!minlength || val.length >= minlength) &&
            (!maxlength || val.length <= maxlength)
        ));

        /* jshint +W126 */

        // Test pattern
        if (valid && pattern) {
            pattern = new RegExp('^(?:' + pattern + ')$');
            valid = pattern.test(val);
        }

        return valid;
    }

    /**
     * Adds error classes to field
     *
     * @param {Object} field - Field element
     * @param {boolean} isCkeditor - Is a isCkeditor field
     */
    function addErrorClass(field, isCkeditor) {
        $(field).addClass('error');

        if (isCkeditor) {
            $('#cke_' + field.id).addClass('cke_error');
        }
    }

    /**
     * Removes error classes from field
     *
     * @param {Object} field - Field element
     * @param {boolean} isCkeditor - Is a isCkeditor field
     */
    function removeErrorClass(field, isCkeditor) {
        $(field).removeClass('error');

        if (isCkeditor) {
            $('#cke_' + field.id).removeClass('cke_error');
        }
    }

    /**
     * Show alertbox
     *
     * @param {string} id - Id of the alertbox
     * @param {string} msg - Message text
     */
    function showAlertbox(id, msg) {
        var alertbox = bolt.data.editcontent.error.alertbox.subst({
            '%NOTICE_ID%': id,
            '%MESSAGE%': msg
        });

        $(alertbox)
            .hide()
            .insertAfter('.page-header')
            .slideDown('fast');
    }

    /**
     * Checks if value is a float
     *
     * @param {string} value - Value of field
     * @returns {string}
     */
    function checkFloat(value) {
        if (value !== '' && !value.match(/^[-+]?[0-9]*[,.]?[0-9]+([eE][-+]?[0-9]+)?$/)) {
            return bolt.data.validation.float;
        } else {
            return '';
        }
    }

    /**
     * Checks if a value is set
     *
     * @param {string} value - Value of field
     * @returns {string}
     */
    function checkRequired(value) {
        return value === '' ? bolt.data.validation.required : '';
    }

    /**
     * Validates a field
     *
     * @param {Object} field - Field element
     * @returns {boolean}
     */
    function validate(field) {
        var hasNativeValidation = typeof field.willValidate !== 'undefined',
            isCkeditor,
            task,
            param,
            value = field.value,
            error,
            label;

        var validates = $(field).data('validate');
        if (validates) {
            for (task in validates) {
                param = validates[task];

                switch (task) {
                    case 'float':
                        error = checkFloat(value);
                        break;

                    case 'required':
                        error = param === true ? checkRequired(value) : '';
                        break;

                    case 'min':
                        if (value !== '' && Number(value.replace(',', '.')) < param) {
                            error = bolt.data.validation.min.subst({'%MINVAL%': param});
                        }
                        break;

                    case 'max':
                        if (value !== '' && Number(value.replace(',', '.')) > param) {
                            error = bolt.data.validation.max.subst({'%MAXVAL%': param});
                        }
                        break;

                    default:
                        console.log('UNKNOWN VALIDATION' + task + " -> " + param);
                }
                // Stop on first error
                if (error) {
                    // Insert label
                    label = $('label[for="' + field.id + '"]').contents().first().text().trim();
                    error = error.subst({'%FIELDNAME%': label ? label : field.name});

                    if (hasNativeValidation) {
                        field.setCustomValidity(error);
                    } else {
                        field.validity.valid = false;
                    }
                    break;
                } else {
                    if (hasNativeValidation) {
                        field.setCustomValidity('');
                    } else {
                        field.validity.valid = true;
                    }
                }
            }
        } else {
            // Is native browser validation available?
            if (hasNativeValidation) {
                // Native validation available
                if (field.nodeName === 'INPUT' && field.type !== field.getAttribute('type')) {
                    // Input type not supported! Use legacy JavaScript validation
                    field.setCustomValidity(legacyValidation(field) ? '' : 'error');
                }
                // Native browser check
                field.checkValidity();
            } else {
                // Native validation not available
                field.validity = field.validity || {};
                // Set to result of validation function
                field.validity.valid = legacyValidation(field);

                // If "invalid" events are required, trigger it here
            }

            // Special validation for CKEditor fields
            isCkeditor = field.nodeName === 'TEXTAREA' && $(field).hasClass('ckeditor');
            if (isCkeditor) {
                var editor = CKEDITOR.instances[field.id],
                    invalid;

                if (editor) {
                    invalid = editor._.required === true && editor.getData().trim() === '';
                    if (hasNativeValidation) {
                        field.setCustomValidity(invalid ? 'Required' : '');
                    } else {
                        field.validity.valid = !invalid;
                    }
                }
            }
        }

        var noticeID = 'notice--' + field.id;

        // First, remove any existing old notices
        $('#' + noticeID).remove();

        if (field.validity.valid) {
            removeErrorClass(field, isCkeditor);

            return true;
        } else {
            addErrorClass(field, isCkeditor);

            var msg = error || $(field).data('errortext');
            if (!msg) {
                msg = bolt.data.editcontent.error.msg.subst({'%FIELDNAME%': field.name});
            }
            showAlertbox(noticeID, msg);

            return false;
        }
    }

    return {
        /**
         * Validates all inputs of a form
         *
         * @param {Object} form - Form element
         * @returns {boolean}
         */
        run: function (form) {
            var formLength = form.elements.length,
                f,
                field,
                formvalid = true;

            // Loop all fields
            for (f = 0; f < formLength; f++) {
                field = form.elements[f];

                if (field.nodeName !== 'INPUT' && field.nodeName !== 'TEXTAREA' && field.nodeName !== 'SELECT') {
                    continue;
                }

                if (field.nodeName === 'INPUT') {
                    // Trim input values
                    field.value = field.value.trim();
                }

                if (validate(field) === false) {
                    formvalid = false;
                }
            }

            return formvalid;
        }
    };
} ());
<|endoftext|>


<commit_before>/*global module*/
module.exports = function (grunt) {
    'use strict';

    // standardize EOL
    grunt.util.linefeed = '\n';

    grunt.initConfig({

        pkg: grunt.file.readJSON('package.json'),

        meta: {
            banner: '/*!\n * <%= pkg.title || pkg.name %>' +
                    ' v<%= pkg.version %>\n' +
                    ' * commit <%= commitish %> -' +
                    ' <%= grunt.template.today("yyyy-mm-dd") %>\n' +
                    ' <%= pkg.homepage ? "* " + pkg.homepage + "\\n" : "" %>' +
                    ' * Copyright (c) <%= grunt.template.today("yyyy") %>\n' +
                    ' * License <%= pkg.license %>\n */\n'
        },

        concat: {
            dist: {
                files: {
                    'symphony/assets/css/symphony.min.css': [
                        'symphony/assets/css/src/symphony.css',
                        'symphony/assets/css/src/symphony.affix.css',
                        'symphony/assets/css/src/symphony.grids.css',
                        'symphony/assets/css/src/symphony.forms.css',
                        'symphony/assets/css/src/symphony.tables.css',
                        'symphony/assets/css/src/symphony.frames.css',
                        'symphony/assets/css/src/symphony.tabs.css',
                        'symphony/assets/css/src/symphony.drawers.css',
                        'symphony/assets/css/src/symphony.associations.css',
                        'symphony/assets/css/src/symphony.notices.css',
                        'symphony/assets/css/src/symphony.suggestions.css',
                        'symphony/assets/css/src/symphony.calendar.css',
                        'symphony/assets/css/src/symphony.filtering.css',
                        'symphony/assets/css/src/admin.css'
                    ],
                    'symphony/assets/css/installer.min.css': [
                        'symphony/assets/css/src/symphony.css',
                        'symphony/assets/css/src/symphony.grids.css',
                        'symphony/assets/css/src/symphony.forms.css',
                        'symphony/assets/css/src/symphony.frames.css',
                        'symphony/assets/css/src/installer.css'
                    ],
                },
            },
        },

        autoprefixer: {
            styles: {
                files: {
                    'symphony/assets/css/symphony.min.css': [
                        'symphony/assets/css/symphony.min.css'
                    ],
                    'symphony/assets/css/installer.min.css': [
                        'symphony/assets/css/installer.min.css'
                    ],
                    'symphony/assets/css/devkit.min.css': [
                        'symphony/assets/css/src/devkit.css'
                    ]
                }
            }
        },

        csso: {
            styles: {
                options: {
                    banner: '<%= meta.banner %>'
                },
                files: {
                    'symphony/assets/css/symphony.min.css': [
                        'symphony/assets/css/symphony.min.css'
                    ],
                    'symphony/assets/css/installer.min.css': [
                        'symphony/assets/css/installer.min.css'
                    ],
                    'symphony/assets/css/devkit.min.css': [
                        'symphony/assets/css/devkit.min.css'
                    ]
                }
            }
        },

        /*
        jshint: {
            scripts: [
                'symphony/assets/js/src/symphony.js',
                'symphony/assets/js/src/symphony.collapsible.js',
                'symphony/assets/js/src/symphony.orderable.js',
                'symphony/assets/js/src/symphony.selectable.js',
                'symphony/assets/js/src/symphony.duplicator.js',
                'symphony/assets/js/src/symphony.tags.js',
                'symphony/assets/js/src/symphony.suggestions.js',
                'symphony/assets/js/src/symphony.pickable.js',
                'symphony/assets/js/src/symphony.timeago.js',
                'symphony/assets/js/src/symphony.notify.js',
                'symphony/assets/js/src/symphony.drawer.js',
                'symphony/assets/js/src/admin.js'
            ]
        },
        */

        uglify: {
            scripts: {
                options: {
                    banner: '<%= meta.banner %>',
                    preserveComments: 'some'
                },
                files: {
                    'symphony/assets/js/symphony.min.js': [
                        'symphony/assets/js/lib/jquery.js',
                        'symphony/assets/js/lib/signals.js',
                        'symphony/assets/js/lib/crossroads.js',
                        'symphony/assets/js/lib/selectize.js',
                        'symphony/assets/js/lib/moment.min.js',
                        'symphony/assets/js/lib/clndr.min.js',
                        'symphony/assets/js/src/symphony.js',
                        'symphony/assets/js/src/symphony.affix.js',
                        'symphony/assets/js/src/symphony.collapsible.js',
                        'symphony/assets/js/src/symphony.defaultvalue.js',
                        'symphony/assets/js/src/symphony.orderable.js',
                        'symphony/assets/js/src/symphony.selectable.js',
                        'symphony/assets/js/src/symphony.duplicator.js',
                        'symphony/assets/js/src/symphony.tags.js',
                        'symphony/assets/js/src/symphony.pickable.js',
                        'symphony/assets/js/src/symphony.timeago.js',
                        'symphony/assets/js/src/symphony.notify.js',
                        'symphony/assets/js/src/symphony.drawer.js',
                        'symphony/assets/js/src/symphony.calendar.js',
                        'symphony/assets/js/src/symphony.filtering.js',
                        'symphony/assets/js/src/symphony.suggestions.js',
                        'symphony/assets/js/src/backend.js',
                        'symphony/assets/js/src/backend.views.js',
                    ]
                }
            }
        },

        watch: {
            styles: {
                files: 'symphony/assets/css/src/*.css',
                tasks: ['css']
            },
            scripts: {
                files: 'symphony/assets/js/src/*.js',
                tasks: ['js']
            },
            php: {
                files: ['symphony/**/*.php', 'install/**/*.php'],
                tasks: ['php']
            }
        },

        phpcs: {
            application: {
                src: ['symphony/**/*.php', 'install/**/*.php', 'index.php']
            },
            options: {
                bin: 'vendor/bin/phpcs',
                standard: 'PSR1',
                showSniffCodes: true,
                tabWidth: 4,
                errorSeverity: 10
            }
        },

        commitish: '',
        'git-rev-parse': {
            options: {
                prop: 'commitish',
                silent: true,
                number: 7
            },
            dist: {}
        }
    });

    grunt.loadNpmTasks('grunt-contrib-concat');
    grunt.loadNpmTasks('grunt-autoprefixer');
    grunt.loadNpmTasks('grunt-csso');
    //grunt.loadNpmTasks('grunt-contrib-jshint');
    grunt.loadNpmTasks('grunt-contrib-uglify');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-phpcs');
    grunt.loadNpmTasks('grunt-git-rev-parse');

    grunt.registerTask('default', ['css', 'js']);
    grunt.registerTask('css', ['git-rev-parse', 'concat', 'autoprefixer', 'csso']);
    grunt.registerTask('php', ['phpcs']);
    grunt.registerTask('js', ['git-rev-parse', 'uglify']);
};<commit_msg>Try to compress js files a little more<commit_after>/*global module*/
module.exports = function (grunt) {
    'use strict';

    // standardize EOL
    grunt.util.linefeed = '\n';

    grunt.initConfig({

        pkg: grunt.file.readJSON('package.json'),

        meta: {
            banner: '/*!\n * <%= pkg.title || pkg.name %>' +
                    ' v<%= pkg.version %>\n' +
                    ' * commit <%= commitish %> -' +
                    ' <%= grunt.template.today("yyyy-mm-dd") %>\n' +
                    ' <%= pkg.homepage ? "* " + pkg.homepage + "\\n" : "" %>' +
                    ' * Copyright (c) <%= grunt.template.today("yyyy") %>\n' +
                    ' * License <%= pkg.license %>\n */\n'
        },

        concat: {
            dist: {
                files: {
                    'symphony/assets/css/symphony.min.css': [
                        'symphony/assets/css/src/symphony.css',
                        'symphony/assets/css/src/symphony.affix.css',
                        'symphony/assets/css/src/symphony.grids.css',
                        'symphony/assets/css/src/symphony.forms.css',
                        'symphony/assets/css/src/symphony.tables.css',
                        'symphony/assets/css/src/symphony.frames.css',
                        'symphony/assets/css/src/symphony.tabs.css',
                        'symphony/assets/css/src/symphony.drawers.css',
                        'symphony/assets/css/src/symphony.associations.css',
                        'symphony/assets/css/src/symphony.notices.css',
                        'symphony/assets/css/src/symphony.suggestions.css',
                        'symphony/assets/css/src/symphony.calendar.css',
                        'symphony/assets/css/src/symphony.filtering.css',
                        'symphony/assets/css/src/admin.css'
                    ],
                    'symphony/assets/css/installer.min.css': [
                        'symphony/assets/css/src/symphony.css',
                        'symphony/assets/css/src/symphony.grids.css',
                        'symphony/assets/css/src/symphony.forms.css',
                        'symphony/assets/css/src/symphony.frames.css',
                        'symphony/assets/css/src/installer.css'
                    ],
                },
            },
        },

        autoprefixer: {
            styles: {
                files: {
                    'symphony/assets/css/symphony.min.css': [
                        'symphony/assets/css/symphony.min.css'
                    ],
                    'symphony/assets/css/installer.min.css': [
                        'symphony/assets/css/installer.min.css'
                    ],
                    'symphony/assets/css/devkit.min.css': [
                        'symphony/assets/css/src/devkit.css'
                    ]
                }
            }
        },

        csso: {
            styles: {
                options: {
                    banner: '<%= meta.banner %>'
                },
                files: {
                    'symphony/assets/css/symphony.min.css': [
                        'symphony/assets/css/symphony.min.css'
                    ],
                    'symphony/assets/css/installer.min.css': [
                        'symphony/assets/css/installer.min.css'
                    ],
                    'symphony/assets/css/devkit.min.css': [
                        'symphony/assets/css/devkit.min.css'
                    ]
                }
            }
        },

        /*
        jshint: {
            scripts: [
                'symphony/assets/js/src/symphony.js',
                'symphony/assets/js/src/symphony.collapsible.js',
                'symphony/assets/js/src/symphony.orderable.js',
                'symphony/assets/js/src/symphony.selectable.js',
                'symphony/assets/js/src/symphony.duplicator.js',
                'symphony/assets/js/src/symphony.tags.js',
                'symphony/assets/js/src/symphony.suggestions.js',
                'symphony/assets/js/src/symphony.pickable.js',
                'symphony/assets/js/src/symphony.timeago.js',
                'symphony/assets/js/src/symphony.notify.js',
                'symphony/assets/js/src/symphony.drawer.js',
                'symphony/assets/js/src/admin.js'
            ]
        },
        */

        uglify: {
            scripts: {
                options: {
                    banner: '<%= meta.banner %>',
                    preserveComments: 'some',
                    screwIE8: true,
                    quoteStyle: 3,
                    compress: {
                        drop_console: true,
                        dead_code: true,
                        unused: true,
                        warnings: grunt.option('verbose')
                    }
                },
                files: {
                    'symphony/assets/js/symphony.min.js': [
                        'symphony/assets/js/lib/jquery.js',
                        'symphony/assets/js/lib/signals.js',
                        'symphony/assets/js/lib/crossroads.js',
                        'symphony/assets/js/lib/selectize.js',
                        'symphony/assets/js/lib/moment.min.js',
                        'symphony/assets/js/lib/clndr.min.js',
                        'symphony/assets/js/src/symphony.js',
                        'symphony/assets/js/src/symphony.affix.js',
                        'symphony/assets/js/src/symphony.collapsible.js',
                        'symphony/assets/js/src/symphony.defaultvalue.js',
                        'symphony/assets/js/src/symphony.orderable.js',
                        'symphony/assets/js/src/symphony.selectable.js',
                        'symphony/assets/js/src/symphony.duplicator.js',
                        'symphony/assets/js/src/symphony.tags.js',
                        'symphony/assets/js/src/symphony.pickable.js',
                        'symphony/assets/js/src/symphony.timeago.js',
                        'symphony/assets/js/src/symphony.notify.js',
                        'symphony/assets/js/src/symphony.drawer.js',
                        'symphony/assets/js/src/symphony.calendar.js',
                        'symphony/assets/js/src/symphony.filtering.js',
                        'symphony/assets/js/src/symphony.suggestions.js',
                        'symphony/assets/js/src/backend.js',
                        'symphony/assets/js/src/backend.views.js'
                    ]
                }
            }
        },

        watch: {
            styles: {
                files: 'symphony/assets/css/src/*.css',
                tasks: ['css']
            },
            scripts: {
                files: 'symphony/assets/js/src/*.js',
                tasks: ['js']
            },
            php: {
                files: ['symphony/**/*.php', 'install/**/*.php'],
                tasks: ['php']
            }
        },

        phpcs: {
            application: {
                src: ['symphony/**/*.php', 'install/**/*.php', 'index.php']
            },
            options: {
                bin: 'vendor/bin/phpcs',
                standard: 'PSR1',
                showSniffCodes: true,
                tabWidth: 4,
                errorSeverity: 10
            }
        },

        commitish: '',
        'git-rev-parse': {
            options: {
                prop: 'commitish',
                silent: true,
                number: 7
            },
            dist: {}
        }
    });

    grunt.loadNpmTasks('grunt-contrib-concat');
    grunt.loadNpmTasks('grunt-autoprefixer');
    grunt.loadNpmTasks('grunt-csso');
    //grunt.loadNpmTasks('grunt-contrib-jshint');
    grunt.loadNpmTasks('grunt-contrib-uglify');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-phpcs');
    grunt.loadNpmTasks('grunt-git-rev-parse');

    grunt.registerTask('default', ['css', 'js']);
    grunt.registerTask('css', ['git-rev-parse', 'concat', 'autoprefixer', 'csso']);
    grunt.registerTask('php', ['phpcs']);
    grunt.registerTask('js', ['git-rev-parse', 'uglify']);
};<|endoftext|>


<commit_before>import Ember from 'ember';
import {queryParamPropertyName, ajaxOptionsPropertyName} from '../property-names';

var evaluateFunctions = function (object, record) {
  if (Ember.isArray(object)) {
    object.forEach(function (element) {
      if (typeof element === 'object') {
        evaluateFunctions(element, record);
      }
    });
  } else {
    Object.keys(object).forEach(function (key) {
      if (!object.hasOwnProperty(key)) {
        return;
      }
      var value = object[key];
      if (typeof value === 'function') {
        object[key] = value.apply(record);
      } else if (typeof value === 'object') {
        evaluateFunctions(value, record);
      }
    });
  }
};

/**
 * Mixin for DS.RESTAdapter.
 */
export default Ember.Mixin.create({
  findHasMany: function (store, snapshot, url, relationship) {
    var id = snapshot.id;
    var type = snapshot.modelName;

    url = this.urlPrefix(url, this.buildURL(type, id, null, 'findHasMany'));
    var query = this.buildRelationshipQuery(snapshot, relationship);

    var options = {data: query};
    snapshot.record.set(ajaxOptionsPropertyName(relationship.key), options);
    return this.ajax(url, 'GET', options);
  },
  findBelongsTo: function (store, snapshot, url, relationship) {
    var id = snapshot.id;
    var type = snapshot.modelName;

    url = this.urlPrefix(url, this.buildURL(type, id, null, 'findBelongsTo'));
    var query = this.buildRelationshipQuery(snapshot, relationship);

    var options = {data: query};
    snapshot.record.set(ajaxOptionsPropertyName(relationship.key), options);
    return this.ajax(url, 'GET', options);
  },
  buildRelationshipQuery: function (snapshot, relationship) {
    var data = {};

    //add query parameters from the model mixin's query function
    var queryParams = snapshot.record.get(queryParamPropertyName(relationship.key));
    if (!Ember.isEmpty(queryParams)) {
      data = jQuery.extend(true, data, queryParams);
    }

    //add query parameters defined in the model itself by the 'parameters' option
    var relationshipParams = relationship.options.parameters;
    if (!Ember.isEmpty(relationshipParams)) {
      data = jQuery.extend(true, data, relationshipParams);
    }

    //replace any functions in the data with their return value
    evaluateFunctions(data, snapshot.record);
    return data;
  },
  ajaxOptions(url, type, options) {
    var ajaxOptions = this._super(...arguments);
    var defaultBeforeSend = ajaxOptions.beforeSend || function () {
      };
    ajaxOptions.beforeSend = function (jqXHR) {
      defaultBeforeSend(...arguments);
      //store the jqXHR in the options object, which in turn is stored in the model itself, so the model mixin can abort it
      ajaxOptions.jqXHR = jqXHR;
    };
    return ajaxOptions;
  }
});
<commit_msg>Fixed jshint error<commit_after>import Ember from 'ember';
import {queryParamPropertyName, ajaxOptionsPropertyName} from '../property-names';

var evaluateFunctions = function (object, record) {
  if (Ember.isArray(object)) {
    object.forEach(function (element) {
      if (typeof element === 'object') {
        evaluateFunctions(element, record);
      }
    });
  } else {
    Object.keys(object).forEach(function (key) {
      if (!object.hasOwnProperty(key)) {
        return;
      }
      var value = object[key];
      if (typeof value === 'function') {
        object[key] = value.apply(record);
      } else if (typeof value === 'object') {
        evaluateFunctions(value, record);
      }
    });
  }
};

/**
 * Mixin for DS.RESTAdapter.
 */
export default Ember.Mixin.create({
  findHasMany: function (store, snapshot, url, relationship) {
    var id = snapshot.id;
    var type = snapshot.modelName;

    url = this.urlPrefix(url, this.buildURL(type, id, null, 'findHasMany'));
    var query = this.buildRelationshipQuery(snapshot, relationship);

    var options = {data: query};
    snapshot.record.set(ajaxOptionsPropertyName(relationship.key), options);
    return this.ajax(url, 'GET', options);
  },
  findBelongsTo: function (store, snapshot, url, relationship) {
    var id = snapshot.id;
    var type = snapshot.modelName;

    url = this.urlPrefix(url, this.buildURL(type, id, null, 'findBelongsTo'));
    var query = this.buildRelationshipQuery(snapshot, relationship);

    var options = {data: query};
    snapshot.record.set(ajaxOptionsPropertyName(relationship.key), options);
    return this.ajax(url, 'GET', options);
  },
  buildRelationshipQuery: function (snapshot, relationship) {
    var data = {};

    //add query parameters from the model mixin's query function
    var queryParams = snapshot.record.get(queryParamPropertyName(relationship.key));
    if (!Ember.isEmpty(queryParams)) {
      data = jQuery.extend(true, data, queryParams);
    }

    //add query parameters defined in the model itself by the 'parameters' option
    var relationshipParams = relationship.options.parameters;
    if (!Ember.isEmpty(relationshipParams)) {
      data = jQuery.extend(true, data, relationshipParams);
    }

    //replace any functions in the data with their return value
    evaluateFunctions(data, snapshot.record);
    return data;
  },
  ajaxOptions: function () {
    var ajaxOptions = this._super(...arguments);
    var defaultBeforeSend = ajaxOptions.beforeSend || function () {
      };
    ajaxOptions.beforeSend = function (jqXHR) {
      defaultBeforeSend(...arguments);
      //store the jqXHR in the options object, which in turn is stored in the model itself, so the model mixin can abort it
      ajaxOptions.jqXHR = jqXHR;
    };
    return ajaxOptions;
  }
});
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2013 Yahoo! Inc. All rights reserved.
 */

/*jslint nomen: true, plusplus: true, forin: true */
YUI.add('mojito-pipeline-addon', function (Y, NAME) {
    'use strict';

    /**
     * The main task processor - takes care of the lifecycle
     * of the tasks
     * @param {Object} command the command from the action context
     * @param {Object} adapter the output adapter for flushing the rendered views
     * @param {ActionContext} ac the action context for the current request
     */

    function Pipeline(command, adapter, ac) {
        Pipeline.superclass.constructor.apply(this, {
            command: command,
            adapter: adapter,
            ac: ac
        });

        this.events = new Y.Pipeline.Events();
        this.Task.prototype.pipeline = this;

        this.unrenderedTasks = 0;
    }
    function Task() {
        Task.superclass.constructor.apply(this, arguments);
    }

    Y.extend(Pipeline, Y.Base, {
        namespace: 'pipeline',
        initializer: function (config) {
            this.sections     = config.sections;
            this._pushedTasks = {};
            this._flushQueue  = [];
            this._resolveRules();
            this.events = new Y.Pipeline.Events(this);
        }
    });

    Pipeline.prototype.render = function (task) {
        this.events.fire(task.id, 'beforeRender');
        // TODO: create action context
        // TODO: execute mojit
        // TODO: execute any actions subscribe to this task's render event
        // TODO: test flush condition, if true put in flush queue, else subscribe to events

    };

    Pipeline.prototype.flushQueue = function () {
        while (this._flushQueue.length) {
            this._flushQueue.shift().flush();
        }
    };

    Pipeline.prototype.getTask = function (id) {
        return this._pushedTasks[id];
    };

    Pipeline.prototype.push = function (task) {
        var pipeline = this,
            renderRuleTargets = {};
        task.pipeline = pipeline;

        // keep track to know when to flush the batch
        this.unrenderedTasks++;
        this._pushedTasks[task.id] = task;

        // for each section in the config
        Y.Object.each(task.sections, function (config, sectionId) {

            // push the default sections if they're not already there
            if (config['default'] && !this.getTask(sectionId)) {
                this.push(new Task({
                    id: sectionId,
                    config: config
                }));
            }
            // build the targets for the render rule of the task
            renderRuleTargets[sectionId] = ['render'];
        }, this);

        // subscribe to the events triggering the render action under some condition
        this.attachAction('render', renderRuleTargets, this._combineTests(this.renderTest, this._sectionsRenderTest), function () {

            // when the rendering is done, push the task in the queue
            pipeline._flushQueue.push(task);
            // check if this was the last task in the current batch (uninterrupted js event loop)
            pipeline.unrenderedTasks--;
            if (pipeline.unrenderedTasks === 0) {
                // if so, empty the queue
                pipeline.flushQueue();
            }
        });
    };

    Pipeline.prototype.close = function () {

    };

    Y.extend(Task, Y.Base, {
        initialize: function (options) {
            this.config        = options.config;
            this.id            = options.id;
            this.action        = options.action;
            this.sections      = this.config.sections;
            this._templateData = {};
            this._rendered     = undefined;
        }
    });

    Task.prototype.attachAction = function (action, targets, testFn, afterAction) {
        var subscription;
        afterAction = afterAction || function () {};

        if (testFn()) {
            this[action].call(this, afterAction);
        } else {
            subscription = this.pipeline.events.subscribe(targets, function (e, done) {
                if (testFn()) {
                    subscription.unsubscribe();
                    this[action].call(this, function () {
                        afterAction();
                        done();
                    });
                }
            });
        }
    };
    Task.prototype.render = function () {
        // this.pipeline.render(this);
    };
    Task.prototype.flush = function () {
        // this.prototype.flush();
    };
    Task.prototype._combineTests = function (test1, test2) {
        return function () {
            return test1() && test2();
        };
    };
    Task.prototype._sectionsRenderTest = function () {
        return !Y.Object.some(this.sections, function (sectionConfig, sectionId) {
            return !this.pipeline.getTask(sectionId).rendered;
        }, this);
    };
    Task.prototype.renderTest = Task.prototype.flushTest = function () {
        return true;
    };

    Pipeline.prototype.Task = Task;
    Pipeline.NAME = 'pipeline';
    Y.namespace('mojito.addons.ac').pipeline = Pipeline;
}, '0.0.1', {
    requires: [
        'base-base',
        'target-action-events'
    ]
});<commit_msg>combine tests fix<commit_after>/*
 * Copyright (c) 2013 Yahoo! Inc. All rights reserved.
 */

/*jslint nomen: true, plusplus: true, forin: true */
YUI.add('mojito-pipeline-addon', function (Y, NAME) {
    'use strict';

    /**
     * The main task processor - takes care of the lifecycle
     * of the tasks
     * @param {Object} command the command from the action context
     * @param {Object} adapter the output adapter for flushing the rendered views
     * @param {ActionContext} ac the action context for the current request
     */

    function Pipeline(command, adapter, ac) {
        Pipeline.superclass.constructor.apply(this, {
            command: command,
            adapter: adapter,
            ac: ac
        });

        this.events = new Y.Pipeline.Events();
        this.Task.prototype.pipeline = this;

        this.unrenderedTasks = 0;
    }
    function Task() {
        Task.superclass.constructor.apply(this, arguments);
    }

    Y.extend(Pipeline, Y.Base, {
        namespace: 'pipeline',
        initializer: function (config) {
            this.sections     = config.sections;
            this._pushedTasks = {};
            this._flushQueue  = [];
            this._resolveRules();
            this.events = new Y.Pipeline.Events(this);
        }
    });

    Pipeline.prototype.render = function (task) {
        this.events.fire(task.id, 'beforeRender');
        // TODO: create action context
        // TODO: execute mojit
        // TODO: execute any actions subscribe to this task's render event
        // TODO: test flush condition, if true put in flush queue, else subscribe to events

    };

    Pipeline.prototype.flushQueue = function () {
        while (this._flushQueue.length) {
            this._flushQueue.shift().flush();
        }
    };

    Pipeline.prototype.getTask = function (id) {
        return this._pushedTasks[id];
    };

    Pipeline.prototype.push = function (task) {
        var pipeline = this,
            renderRuleTargets = {},
            flushRuleTargets = {};
        task.pipeline = pipeline;

        // keep track to know when to flush the batch
        this.unrenderedTasks++;
        this._pushedTasks[task.id] = task;

        // for each section in the config
        Y.Object.each(task.sections, function (config, sectionId) {

            // push the default sections if they're not already there
            if (config['default'] && !this.getTask(sectionId)) {
                this.push(new Task({
                    id: sectionId,
                    config: config
                }));
            }
            // build the targets for the render rule of the task
            renderRuleTargets[sectionId] = ['render'];
        }, this);

        // TODO: parse the render rules and combine the tests with sectionsRenderTest
        task.renderTest = Task._combineTests(task.renderTest, task._sectionsRenderTest.bind(task));

        // subscribe to the events triggering the render action under some condition
        this.attachAction('render', renderRuleTargets, task.renderTest.bind(task), function () {

            // when the rendering is done, push the task in the queue
            pipeline._flushQueue.push(task);
            // check if this was the last task in the current batch (uninterrupted js event loop)
            pipeline.unrenderedTasks--;
            if (pipeline.unrenderedTasks === 0) {
                // if so, empty the queue
                pipeline.flushQueue();
            }
        });
    };

    Pipeline.prototype.close = function () {

    };

    Y.extend(Task, Y.Base, {
        initialize: function (options) {
            this.config        = options.config;
            this.id            = options.id;
            this.action        = options.action;
            this.sections      = this.config.sections;
            this._templateData = {};
            this._rendered     = undefined;
        }
    });

    Task.prototype.attachAction = function (action, targets, testFn, afterAction) {
        var subscription;
        afterAction = afterAction || function () {};

        if (testFn()) {
            this[action].call(this, afterAction);
        } else {
            subscription = this.pipeline.events.subscribe(targets, function (e, done) {
                if (testFn()) {
                    subscription.unsubscribe();
                    this[action].call(this, function () {
                        afterAction();
                        done();
                    });
                }
            });
        }
    };
    Task.prototype.render = function () {
        // this.pipeline.render(this);
    };
    Task.prototype.flush = function () {
        // this.prototype.flush();
    };
    Task._combineTests = function () {
        return function () {
            return !Y.Array.some(arguments, function (nextFn) {
                return !nextFn.call();
            });
        };
    };
    Task.prototype._sectionsRenderTest = function () {
        return !Y.Object.some(this.sections, function (sectionConfig, sectionId) {
            return !this.pipeline.getTask(sectionId).rendered;
        }, this);
    };
    Task.prototype.renderTest = Task.prototype.flushTest = function () {
        return true;
    };

    Pipeline.prototype.Task = Task;
    Pipeline.NAME = 'pipeline';
    Y.namespace('mojito.addons.ac').pipeline = Pipeline;
}, '0.0.1', {
    requires: [
        'base-base',
        'target-action-events'
    ]
});<|endoftext|>


<commit_before>module.exports = function(grunt) {
    var filesToMakeAppJS = ['public/ts/app.js', 'public/ts/*.js'];

    var filesToWatch = function(){
        return filesToMakeAppJS;
    };

    // Project configuration.
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        ts: {
            default: {
                src: ['public/**/*.ts'],
                tsconfig: true
            }
        },
        express: {
            options: {
                script: 'index.js',
                background: false
            }
        },
        concat: {
            app: {
                banner: '/* <%= grunt.template.today("yyyy-mm-dd") %> */\n',
                src: filesToMakeAppJS,
                dest: 'public/ts/bundle/app.js'
            }
        },
        less: {
		    default: {
				options: {
					// paths: ['Content/']
				},
				files: {
					'public/stylesheets/site.css': 'public/less/app.less'
				}
			}
		},
        uglify: {
            options: {
                banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n',
                sourceMap: true
            },
            build: {
                src: 'public/ts/bundle/app.js',
                dest: 'public/ts/bundle/app.min.js'
            },
            css: {
                src: 'public/stylesheets/site.css',
                dest: 'public/stylesheets/site.min.css'
            }
        },
        watch: {
            js: {
                files: ['public/**/*.ts'],
                tasks: ['ts', 'concat', 'uglify:build'],
                options: {
                    livereload: true
                }
            },
            less: {
                files: ['public/**/*.less'],
                tasks: ['less'],
                options: {
                    livereload: true
                }
            }
        }
    });

    // Load the plugin that provides the "uglify" task.
    grunt.loadNpmTasks('grunt-ts');
    grunt.loadNpmTasks('grunt-contrib-uglify');
    grunt.loadNpmTasks('grunt-contrib-concat');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-contrib-less');

    // Default task(s).
    grunt.registerTask('default', ['ts', 'less', 'concat', 'uglify']);

};<commit_msg>remove css minification<commit_after>module.exports = function(grunt) {
    var filesToMakeAppJS = ['public/ts/app.js', 'public/ts/*.js'];

    var filesToWatch = function(){
        return filesToMakeAppJS;
    };

    // Project configuration.
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        ts: {
            default: {
                src: ['public/**/*.ts'],
                tsconfig: true
            }
        },
        express: {
            options: {
                script: 'index.js',
                background: false
            }
        },
        concat: {
            app: {
                banner: '/* <%= grunt.template.today("yyyy-mm-dd") %> */\n',
                src: filesToMakeAppJS,
                dest: 'public/ts/bundle/app.js'
            }
        },
        less: {
		    default: {
				options: {
					// paths: ['Content/']
				},
				files: {
					'public/stylesheets/site.css': 'public/less/app.less'
				}
			}
		},
        uglify: {
            options: {
                banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n',
                sourceMap: true
            },
            build: {
                src: 'public/ts/bundle/app.js',
                dest: 'public/ts/bundle/app.min.js'
            }
        },
        watch: {
            js: {
                files: ['public/**/*.ts'],
                tasks: ['ts', 'concat', 'uglify:build'],
                options: {
                    livereload: true
                }
            },
            less: {
                files: ['public/**/*.less'],
                tasks: ['less'],
                options: {
                    livereload: true
                }
            }
        }
    });

    // Load the plugin that provides the "uglify" task.
    grunt.loadNpmTasks('grunt-ts');
    grunt.loadNpmTasks('grunt-contrib-uglify');
    grunt.loadNpmTasks('grunt-contrib-concat');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-contrib-less');

    // Default task(s).
    grunt.registerTask('default', ['ts', 'less', 'concat', 'uglify']);

};<|endoftext|>


<commit_before>/*
 * Copyright 2013 The Polymer Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style
 * license that can be found in the LICENSE file.
 */
module.exports = function(grunt) {
  var banner = [grunt.file.read('LICENSE'), '// @version ' + grunt.file.readJSON('package.json').version, ''].join(grunt.util.linefeed);
  Platform = [
    '../platform/platform.min.js'
  ];

  PlatformNative = [
    '../platform/platform.native.min.js'
  ];

  PlatformSandbox = [
    '../platform/platform.sandbox.min.js'
  ];

  Polymer = [
    "polymer.js",
    "boot.js",
    "lib/lang.js",
    "lib/job.js",
    "lib/dom.js",
    "lib/super.js",
    "lib/deserialize.js",
    "api.js",
    "instance/utils.js",
    "instance/events.js",
    "instance/attributes.js",
    "instance/properties.js",
    "instance/mdv.js",
    "instance/base.js",
    "instance/styles.js",
    "declaration/path.js",
    "declaration/styles.js",
    "declaration/events.js",
    "declaration/properties.js",
    "declaration/attributes.js",
    "declaration/prototype.js",
    "declaration/polymer-element.js",
    "deprecated.js"
  ].map(function(n) {
    return "src/" + n;
  });

  // karma setup
  var browsers;
  (function() {
    try {
      var config = grunt.file.readJSON('local.json');
      if (config.browsers) {
        browsers = config.browsers;
      }
    } catch (e) {
      var os = require('os');
      browsers = ['Chrome', 'Firefox'];
      //browsers = ['Chrome'];
      if (os.type() === 'Darwin') {
        browsers.push('ChromeCanary');
      }
      if (os.type() === 'Windows_NT') {
        browsers.push('IE');
      }
    }
  })();

  grunt.initConfig({
    karma: {
      options: {
        configFile: 'conf/karma.conf.js',
        keepalive: true
      },
      buildbot: {
        browsers: browsers,
        reporters: ['crbot'],
        logLevel: 'OFF'
      },
      polymer: {
        browsers: browsers
      }
    },
    uglify: {
      options: {
        banner: banner,
        nonull: true
      },
      Polymer: {
        options: {
          sourceMap: 'polymer.min.js.map',
          //mangle: false, beautify: true, compress: false
        },
        files: {
          'polymer.min.js': [].concat(Platform, Polymer)
        }
      },
      PolymerNative: {
        options: {
          sourceMap: 'polymer.native.min.js.map'
        },
        files: {
          'polymer.native.min.js': [].concat(PlatformNative, Polymer)
        }
      },
      PolymerSandbox: {
        options: {
          sourceMap: 'polymer.sandbox.min.js.map',
          //mangle: false, beautify: true, compress: false
        },
        files: {
          'polymer.sandbox.min.js': [].concat(PlatformSandbox, Polymer)
        }
      }
    },
    yuidoc: {
      compile: {
        name: '<%= pkg.name %>',
        description: '<%= pkg.description %>',
        version: '<%= pkg.version %>',
        url: '<%= pkg.homepage %>',
        options: {
          exclude: 'third_party',
          extension: '.js,.html',
          paths: '.',
          outdir: 'docs',
          linkNatives: 'true',
          tabtospace: 2,
          themedir: '../docs/doc_themes/bootstrap'
        }
      }
    },
    audit: {
      polymer: {
        options: {
          repos: [
            '.',
            '../platform',
            '../ShadowDOM',
            '../HTMLImports',
            '../CustomElements',
            '../PointerEvents',
            '../PointerGestures',
            '../polymer-expressions',
            '../observe-js',
            '../NodeBind',
            '../TemplateInstances'
          ]
        },
        dest: 'build.log',
        src: [
          'polymer.min.js',
          'polymer.native.min.js',
          'polymer.sandbox.min.js'
        ]
      }
    },
    pkg: grunt.file.readJSON('package.json')
  });

  // plugins
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-yuidoc');
  grunt.loadNpmTasks('grunt-karma');
  grunt.loadNpmTasks('grunt-audit');

  // tasks
  grunt.registerTask('default', ['uglify', 'audit']);
  grunt.registerTask('minify', ['uglify']);
  grunt.registerTask('docs', ['yuidoc']);
  grunt.registerTask('test', ['karma:polymer']);
  grunt.registerTask('test-buildbot', ['karma:buildbot']);
};

<commit_msg>fix path for grunt audit<commit_after>/*
 * Copyright 2013 The Polymer Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style
 * license that can be found in the LICENSE file.
 */
module.exports = function(grunt) {
  var banner = [grunt.file.read('LICENSE'), '// @version ' + grunt.file.readJSON('package.json').version, ''].join(grunt.util.linefeed);
  Platform = [
    '../platform/platform.min.js'
  ];

  PlatformNative = [
    '../platform/platform.native.min.js'
  ];

  PlatformSandbox = [
    '../platform/platform.sandbox.min.js'
  ];

  Polymer = [
    "polymer.js",
    "boot.js",
    "lib/lang.js",
    "lib/job.js",
    "lib/dom.js",
    "lib/super.js",
    "lib/deserialize.js",
    "api.js",
    "instance/utils.js",
    "instance/events.js",
    "instance/attributes.js",
    "instance/properties.js",
    "instance/mdv.js",
    "instance/base.js",
    "instance/styles.js",
    "declaration/path.js",
    "declaration/styles.js",
    "declaration/events.js",
    "declaration/properties.js",
    "declaration/attributes.js",
    "declaration/prototype.js",
    "declaration/polymer-element.js",
    "deprecated.js"
  ].map(function(n) {
    return "src/" + n;
  });

  // karma setup
  var browsers;
  (function() {
    try {
      var config = grunt.file.readJSON('local.json');
      if (config.browsers) {
        browsers = config.browsers;
      }
    } catch (e) {
      var os = require('os');
      browsers = ['Chrome', 'Firefox'];
      //browsers = ['Chrome'];
      if (os.type() === 'Darwin') {
        browsers.push('ChromeCanary');
      }
      if (os.type() === 'Windows_NT') {
        browsers.push('IE');
      }
    }
  })();

  grunt.initConfig({
    karma: {
      options: {
        configFile: 'conf/karma.conf.js',
        keepalive: true
      },
      buildbot: {
        browsers: browsers,
        reporters: ['crbot'],
        logLevel: 'OFF'
      },
      polymer: {
        browsers: browsers
      }
    },
    uglify: {
      options: {
        banner: banner,
        nonull: true
      },
      Polymer: {
        options: {
          sourceMap: 'polymer.min.js.map',
          //mangle: false, beautify: true, compress: false
        },
        files: {
          'polymer.min.js': [].concat(Platform, Polymer)
        }
      },
      PolymerNative: {
        options: {
          sourceMap: 'polymer.native.min.js.map'
        },
        files: {
          'polymer.native.min.js': [].concat(PlatformNative, Polymer)
        }
      },
      PolymerSandbox: {
        options: {
          sourceMap: 'polymer.sandbox.min.js.map',
          //mangle: false, beautify: true, compress: false
        },
        files: {
          'polymer.sandbox.min.js': [].concat(PlatformSandbox, Polymer)
        }
      }
    },
    yuidoc: {
      compile: {
        name: '<%= pkg.name %>',
        description: '<%= pkg.description %>',
        version: '<%= pkg.version %>',
        url: '<%= pkg.homepage %>',
        options: {
          exclude: 'third_party',
          extension: '.js,.html',
          paths: '.',
          outdir: 'docs',
          linkNatives: 'true',
          tabtospace: 2,
          themedir: '../docs/doc_themes/bootstrap'
        }
      }
    },
    audit: {
      polymer: {
        options: {
          repos: [
            '.',
            '../platform',
            '../ShadowDOM',
            '../HTMLImports',
            '../CustomElements',
            '../PointerEvents',
            '../PointerGestures',
            '../polymer-expressions',
            '../observe-js',
            '../NodeBind',
            '../TemplateBinding'
          ]
        },
        dest: 'build.log',
        src: [
          'polymer.min.js',
          'polymer.native.min.js',
          'polymer.sandbox.min.js'
        ]
      }
    },
    pkg: grunt.file.readJSON('package.json')
  });

  // plugins
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-yuidoc');
  grunt.loadNpmTasks('grunt-karma');
  grunt.loadNpmTasks('grunt-audit');

  // tasks
  grunt.registerTask('default', ['uglify', 'audit']);
  grunt.registerTask('minify', ['uglify']);
  grunt.registerTask('docs', ['yuidoc']);
  grunt.registerTask('test', ['karma:polymer']);
  grunt.registerTask('test-buildbot', ['karma:buildbot']);
};

<|endoftext|>