<commit_before>(function (bender) {
  "use strict";

  var K = 0;  // counter for placeholders (debug)

  var A = Array.prototype;

  // The Bender namespace, also adding the "bender" namespace prefix for
  // flexo.create_element
  bender.ns = flexo.ns.bender = "http://bender.igel.co.jp";

  // Create a rendering contest given a target element in a host document (using
  // the document element as a default.)
  bender.create_context = function (target) {
    target = target || document.documentElement;
    var host_doc = target.ownerDocument;
    var context = host_doc.implementation.createDocument(bender.ns, "context",
      null);
    context._uri = host_doc.baseURI;

    // Wrap all new elements created in this context
    context.createElement = function (name) {
      return wrap_element(Object.getPrototypeOf(this).createElementNS.call(this,
            bender.NS, name));
    };
    context.createElementNS = function (ns, qname) {
      return wrap_element(Object.getPrototypeOf(this).createElementNS.call(this,
            ns, qname));
    };

    // Read-only target property
    Object.defineProperty(context, "_target", {
      enumerable: true,
      get: function () {
        return target;
      }
    });

    // Add an instance to the context; it now becomes live. Return the added
    // instance.
    context._add_instance = function (instance) {
      return this.documentElement.appendChild(instance);
    };

    // Loaded files by URI. When a file is being loaded, store all instances
    // that are requesting it; once it's loaded, store the loaded component
    var loaded = {};
    loaded[flexo.normalize_uri(context._uri, "")] = context.documentElement;

    // Load the component at the given URI for the instance
    context._load_component = function (uri, instance) {
      var split = uri.split("#");
      var locator = flexo.normalize_uri(instance._uri, split[0]);
      // var id = split[1];
      if (loaded[locator] instanceof window.Node) {
        flexo.notify(instance, "@loaded", { uri: locator,
          component: loaded[locator] });
      } else if (Array.isArray(loaded[locator])) {
        loaded[locator].push(instance);
      } else {
        loaded[locator] = [instance];
        flexo.ez_xhr(locator, { responseType: "document" }, function (req) {
          var ev = { uri: locator, req: req };
          if (req.status !== 0 && req.status !== 200) {
            ev.message = "HTTP error {0}".fmt(req.status);
            flexo.notify(instance, "@error", ev);
          } else if (!req.response) {
            ev.message = "could not parse response as XML";
            flexo.notify(instance, "@error", ev);
          } else {
            var c = context._import_node(req.response.documentElement, locator);
            if (is_bender_element(c, "component")) {
              ev.component = c;
              loaded[locator].forEach(function (i) {
                flexo.notify(i, "@loaded", ev);
              });
              loaded[locator] = c;
            } else {
              ev.message = "not a Bender component";
              flexo.notify(instance, "@error", ev);
            }
          }
        });
      }
    };

    // Import a node in the context (for loaded components)
    context._import_node = function (node, uri) {
      if (node.nodeType === window.Node.ELEMENT_NODE) {
        var n = this.createElementNS(node.namespaceURI, node.localName);
        if (is_bender_element(n, "component")) {
          n._uri = uri;
        }
        A.forEach.call(node.attributes, function (attr) {
          if (attr.namespaceURI) {
            if (attr.namespaceURI === flexo.ns.xmlns &&
                attr.localName !== "xmlns") {
              n.setAttribute("xmlns:" + attr.localName, attr.nodeValue);
            } else {
              n.setAttributeNS(attr.namespaceURI, attr.localName,
                attr.nodeValue);
            }
          } else {
            n.setAttribute(attr.localName, attr.nodeValue);
          }
        });
        A.forEach.call(node.childNodes, function (ch) {
          var ch_ = this._import_node(ch, uri);
          if (ch_) {
            n.appendChild(ch_);
          }
        }, this);
        return n;
      }
      if (node.nodeType === window.Node.TEXT_NODE ||
          node.nodeType === window.Node.CDATA_SECTION_NODE) {
        return this.createTextNode(node.textContent)
      }
    };

    context.$ = flexo.create_element.bind(context);
    var view = wrap_element(context.documentElement);
    view._target = target;
    return context;
  };

  // Bender elements overload some DOM methods in order to track changes to the
  // tree.

  var prototypes = {
    // Default overloaded DOM methods for Bender elements
    "": {
      // Make sure that an overloaded insertBefore() is called for appendChild()
      appendChild: function (ch) {
        return this.insertBefore(ch, null);
      },
    }
  };

  ["component", "context", "instance", "view"].forEach(function (p) {
    prototypes[p] = {};
  });

  // Component methods

  prototypes.component._init = function () {
    this._properties = [];  // all the property elements for this component
    this._watches = [];     // all the watch elements fro this component
    this._instances = [];   // live instances of this componet
  };

  // Convenience method to create a new instance of that component
  prototypes.component._create_instance = function () {
    var instance = this.ownerDocument.$("instance");
    instance._component = this;
    return instance;
  };

  prototypes.component.insertBefore = function (ch, ref) {
    Object.getPrototypeOf(this).insertBefore.call(this, ch, ref);
    if (ch.namespaceURI === bender.ns) {
      if (ch.localName === "view") {
        if (this._view) {
          console.error("Multiple views for component", this);
        } else {
          this._view = ch;
          this._view._set_uri_for_instances(this._uri);
        }
      } else if (ch.localName === "property") {
        this._properties.push(ch);
      } else if (ch.localName === "watch") {
        this._watches.push(ch);
      }
    }
    return ch;
  };

  prototypes.component.removeChild = function (ch) {
    if (ch.namespaceURI === bender.ns) {
      if (ch.localName === "view") {
        if (this._view === ch) {
          delete this._view;
          this._instances.forEach(function (instance) {
            // TODO unrender?
          });
        }
      } else if (ch.localName === "property") {
        flexo.remove_from_array(this._properties, ch);
      } else if (ch.localName === "watch") {
        flexo.remove_from_array(this._watches, ch);
      }
    }
    Object.getPrototypeOf(this).removeChild.call(this, ch);
    return ch;
  };

  // Context methods

  // Add instances to the context and render them in the context target
  prototypes.context.insertBefore = function (ch, ref) {
    if (is_bender_element(ch, "instance")) {
      Object.getPrototypeOf(this).insertBefore.call(this, ch, ref);
      ch._uri = this.ownerDocument._uri;
      var placeholder = ch._render(this._target);
      this._target.insertBefore(placeholder, ref && ref._placeholder);
      return ch;
    } else {
      console.warn("Unexpected element in context:", ch);
    }
  };

  prototypes.context.removeChild = function (ch) {
    if (is_bender_element(ch, "instance")) {
      // TODO unrender
    }
    Object.getPrototypeOf(this).removeChild.call(this, ch);
    return ch;
  };

  // Instance methods
  // Status of an instance:
  //   ._uri: base URI; if not set, then it is not in the tree
  //   ._href: has a reference to a component
  //   ._component: if set, then loaded; otherwise, not ready
  //   ._target: has a target to render into

  prototypes.instance._init = function (component) {
    this._children = [];
    // Set the component: instantiate and render it (it is already loaded)
    Object.defineProperty(this, "_component", { enumerable: true,
      get: function () { return component; },
      set: function (c) {
        if (component !== c) {
          component = c;
        }
      }
    });
  };

  // Render this instance in a fresh placeholder, and return the placeholder.
  // Actual rendering may be delayed if the component is not loaded yet but the
  // placeholder can be inserted in its place immediately. Send a notification
  // that rendering has started (@rendering); a notification that rendering has
  // ended will be sent as well (@rendered)
  prototypes.instance._render = function (target) {
    this._placeholder = target.ownerDocument.createElementNS(bender.ns,
        "placeholder");
    this._placeholder.setAttribute("no", K++);
    this._placeholder._instance = this;
    // Keep track of pending instances (see _finished_rendering below),
    // including self
    this.__pending = [this];
    flexo.notify(this, "@rendering");
    var render = function () {
      if (this._component._view) {
        render_children(this._component._view, this._placeholder);
      }
      this._finished_rendering(this);
    };
    if (this._component) {
      render.call(this);
    } else {
      this._load_component(render);
    }
    return this._placeholder;
  };

  // instance has finished rendering, so it can be removed from the current list
  // of pending instances. When the list is empty, the instance is completely
  // rendered so we can send the @rendered event, and tell the parent instance,
  // if any, to take it of its pending list.
  prototypes.instance._finished_rendering = function(instance) {
    var removed = flexo.remove_from_array(this.__pending, instance);
    if (this.__pending.length === 0) {
      delete this.__pending;
      flexo.notify(this, "@rendered");
      if (this._parent) {
        this._parent._finished_rendering(this);
      }
    }
  };

  prototypes.instance._load_component = function (k) {
    if (this._uri && this._href && !this._component) {
      flexo.listen_once(this, "@loaded", function (e) {
        e.source._component = e.component;
        k.call(e.source);
      });
      flexo.listen_once(this.ownerDocument, "@error", function (e) {
        console.error("Error loading component at {0}: {1}"
          .fmt(e.uri, e.message), e.source);
      });
      this.ownerDocument._load_component(this._href, this);
    }
  };

  prototypes.instance._add_child_instance = function(template) {
    var instance = this.ownerDocument.$("instance");
    instance._template = template;
    instance._parent = this;
    this._children.push(instance);
    instance._uri = template._uri;
    instance._href = template._href;
    instance._component = template._component;
    return instance;
  };

  prototypes.instance.setAttribute = function (name, value) {
    Object.getPrototypeOf(this).setAttribute.call(this, name, value);
    if (name === "href") {
      this._href = value;
    }
  };

  prototypes.instance.insertBefore = prototypes.component.insertBefore;

  function render_children(view, target) {
    A.forEach.call(view.childNodes, function (ch) {
      if (ch.nodeType === window.Node.ELEMENT_NODE) {
        if (ch.namespaceURI === bender.ns) {
          if (ch.localName === "instance") {
            var instance = instance_of(target);
            var child_instance = instance._add_child_instance(ch);
            instance.__pending.push(child_instance);
            target.appendChild(child_instance._render(target));
          } else if (ch.localName === "content") {
            var instance = instance_of(target);
            if (instance._template) {
              instance = instance._template;
            }
            if (instance.childNodes.length > 0) {
              render_children(instance, target);
            } else {
              render_children(ch, target);
            }
          } else {
            console.warn("Unexpected Bender element {0} in view; skipped."
              .fmt(ch.localName));
          }
        } else {
          var t = target.appendChild(
            target.ownerDocument.createElementNS(ch.namespaceURI,
              ch.localName));
          A.forEach.call(ch.attributes, function (attr) {
            t.setAttributeNS(attr.namespaceURI, attr.localName, attr.value);
          });
          render_children(ch, t);
        }
      } else if (ch.nodeType === window.Node.TEXT_NODE ||
        ch.nodeType === window.Node.CDATA_SECTION_NODE) {
        var t = target.appendChild(
          target.ownerDocument.createTextNode(ch.textContent));
      }
    });
  }

  // View methods

  prototypes.view.insertBefore = function (ch, ref) {
    Object.getPrototypeOf(this).insertBefore.call(this, ch, ref);
    if (!is_bender_element(ch)) {
      return wrap_element(ch, prototypes.view);
    }
  };

  prototypes.view._set_uri_for_instances = function (uri) {
    A.forEach.call(this.childNodes, function (ch) {
      if (is_bender_element(ch, "instance")) {
        ch._uri = uri;
      } else if (typeof ch._set_uri_for_instances === "function") {
        ch._set_uri_for_instances(uri);
      }
    });
  };

  // Utility functions

  // Find the nearest instance ancestor for this element (may be undefined, for
  // instance if the element is not rooted)
  function instance_of(elem) {
    if (is_bender_element(elem, "instance")) {
      return elem;
    } else if (is_bender_element(elem, "placeholder")) {
      return elem._instance;
    } else if (elem) {
      return instance_of(elem.parentNode);
    }
  }

  // Test whether the given node is an element in the Bender namespace with the
  // given name
  function is_bender_element(node, name) {
    return node instanceof window.Node &&
      node.nodeType === window.Node.ELEMENT_NODE &&
      node.namespaceURI === bender.ns &&
      (name === undefined || node.localName === name);
  }

  // Extend an element with Bender methods, calls its _init() method, and return
  // the wrapped element.
  function wrap_element(e, proto) {
    if (typeof proto !== "object") {
      proto = prototypes[e.localName];
    }
    if (proto) {
      for (var p in proto) {
        if (proto.hasOwnProperty(p)) {
          e[p] = proto[p];
        }
      }
    }
    for (p in prototypes[""]) {
      if (prototypes[""].hasOwnProperty(p) && !e.hasOwnProperty(p)) {
        e[p] = prototypes[""][p];
      }
    }
    if (typeof e._init === "function") {
      e._init();
    }
    return e;
  }

}(window.bender = {}))
<commit_msg>Target<commit_after>(function (bender) {
  "use strict";

  var K = 0;  // counter for placeholders (debug)

  var A = Array.prototype;

  // The Bender namespace, also adding the "bender" namespace prefix for
  // flexo.create_element
  bender.ns = flexo.ns.bender = "http://bender.igel.co.jp";

  // Create a rendering contest given a target element in a host document (using
  // the document element as a default.)
  bender.create_context = function (target) {
    target = target || document.documentElement;
    var host_doc = target.ownerDocument;
    var context = host_doc.implementation.createDocument(bender.ns, "context",
      null);
    context._uri = host_doc.baseURI;

    // Wrap all new elements created in this context
    context.createElement = function (name) {
      return wrap_element(Object.getPrototypeOf(this).createElementNS.call(this,
            bender.NS, name));
    };
    context.createElementNS = function (ns, qname) {
      return wrap_element(Object.getPrototypeOf(this).createElementNS.call(this,
            ns, qname));
    };

    // Read-only target property
    Object.defineProperty(context, "_target", {
      enumerable: true,
      get: function () {
        return target;
      }
    });

    // Add an instance to the context; it now becomes live. Return the added
    // instance.
    context._add_instance = function (instance) {
      return this.documentElement.appendChild(instance);
    };

    // Loaded files by URI. When a file is being loaded, store all instances
    // that are requesting it; once it's loaded, store the loaded component
    var loaded = {};
    loaded[flexo.normalize_uri(context._uri, "")] = context.documentElement;

    // Load the component at the given URI for the instance
    context._load_component = function (uri, instance) {
      var split = uri.split("#");
      var locator = flexo.normalize_uri(instance._uri, split[0]);
      // var id = split[1];
      if (loaded[locator] instanceof window.Node) {
        flexo.notify(instance, "@loaded", { uri: locator,
          component: loaded[locator] });
      } else if (Array.isArray(loaded[locator])) {
        loaded[locator].push(instance);
      } else {
        loaded[locator] = [instance];
        flexo.ez_xhr(locator, { responseType: "document" }, function (req) {
          var ev = { uri: locator, req: req };
          if (req.status !== 0 && req.status !== 200) {
            ev.message = "HTTP error {0}".fmt(req.status);
            flexo.notify(instance, "@error", ev);
          } else if (!req.response) {
            ev.message = "could not parse response as XML";
            flexo.notify(instance, "@error", ev);
          } else {
            var c = context._import_node(req.response.documentElement, locator);
            if (is_bender_element(c, "component")) {
              ev.component = c;
              loaded[locator].forEach(function (i) {
                flexo.notify(i, "@loaded", ev);
              });
              loaded[locator] = c;
            } else {
              ev.message = "not a Bender component";
              flexo.notify(instance, "@error", ev);
            }
          }
        });
      }
    };

    // Import a node in the context (for loaded components)
    context._import_node = function (node, uri) {
      if (node.nodeType === window.Node.ELEMENT_NODE) {
        var n = this.createElementNS(node.namespaceURI, node.localName);
        if (is_bender_element(n, "component")) {
          n._uri = uri;
        }
        A.forEach.call(node.attributes, function (attr) {
          if (attr.namespaceURI) {
            if (attr.namespaceURI === flexo.ns.xmlns &&
                attr.localName !== "xmlns") {
              n.setAttribute("xmlns:" + attr.localName, attr.nodeValue);
            } else {
              n.setAttributeNS(attr.namespaceURI, attr.localName,
                attr.nodeValue);
            }
          } else {
            n.setAttribute(attr.localName, attr.nodeValue);
          }
        });
        A.forEach.call(node.childNodes, function (ch) {
          var ch_ = this._import_node(ch, uri);
          if (ch_) {
            n.appendChild(ch_);
          }
        }, this);
        return n;
      }
      if (node.nodeType === window.Node.TEXT_NODE ||
          node.nodeType === window.Node.CDATA_SECTION_NODE) {
        return this.createTextNode(node.textContent)
      }
    };

    context.$ = flexo.create_element.bind(context);
    var view = wrap_element(context.documentElement);
    view._target = target;
    return context;
  };

  // Bender elements overload some DOM methods in order to track changes to the
  // tree.

  var prototypes = {
    // Default overloaded DOM methods for Bender elements
    "": {
      // Make sure that an overloaded insertBefore() is called for appendChild()
      appendChild: function (ch) {
        return this.insertBefore(ch, null);
      },
    }
  };

  ["component", "context", "instance", "target", "view"].forEach(function (p) {
    prototypes[p] = {};
  });

  // Component methods

  prototypes.component._init = function () {
    this._properties = [];  // all the property elements for this component
    this._watches = [];     // all the watch elements fro this component
    this._instances = [];   // live instances of this componet
  };

  // Convenience method to create a new instance of that component
  prototypes.component._create_instance = function () {
    var instance = this.ownerDocument.$("instance");
    instance._component = this;
    return instance;
  };

  prototypes.component.insertBefore = function (ch, ref) {
    Object.getPrototypeOf(this).insertBefore.call(this, ch, ref);
    if (ch.namespaceURI === bender.ns) {
      if (ch.localName === "view") {
        if (this._view) {
          console.error("Multiple views for component", this);
        } else {
          this._view = ch;
          this._view._set_uri_for_instances(this._uri);
        }
      } else if (ch.localName === "property") {
        this._properties.push(ch);
      } else if (ch.localName === "watch") {
        this._watches.push(ch);
      }
    }
    return ch;
  };

  prototypes.component.removeChild = function (ch) {
    if (ch.namespaceURI === bender.ns) {
      if (ch.localName === "view") {
        if (this._view === ch) {
          delete this._view;
          this._instances.forEach(function (instance) {
            // TODO unrender?
          });
        }
      } else if (ch.localName === "property") {
        flexo.remove_from_array(this._properties, ch);
      } else if (ch.localName === "watch") {
        flexo.remove_from_array(this._watches, ch);
      }
    }
    Object.getPrototypeOf(this).removeChild.call(this, ch);
    return ch;
  };

  // Context methods

  // Add instances to the context and render them in the context target
  prototypes.context.insertBefore = function (ch, ref) {
    if (is_bender_element(ch, "instance")) {
      Object.getPrototypeOf(this).insertBefore.call(this, ch, ref);
      ch._uri = this.ownerDocument._uri;
      var placeholder = ch._render(this._target);
      this._target.insertBefore(placeholder, ref && ref._placeholder);
      return ch;
    } else {
      console.warn("Unexpected element in context:", ch);
    }
  };

  prototypes.context.removeChild = function (ch) {
    if (is_bender_element(ch, "instance")) {
      // TODO unrender
    }
    Object.getPrototypeOf(this).removeChild.call(this, ch);
    return ch;
  };

  // Instance methods
  // Status of an instance:
  //   ._uri: base URI; if not set, then it is not in the tree
  //   ._href: has a reference to a component
  //   ._component: if set, then loaded; otherwise, not ready
  //   ._target: has a target to render into

  prototypes.instance._init = function (component) {
    this._children = [];
    // Set the component: instantiate and render it (it is already loaded)
    Object.defineProperty(this, "_component", { enumerable: true,
      get: function () { return component; },
      set: function (c) {
        if (component !== c) {
          component = c;
        }
      }
    });
  };

  // Render this instance in a fresh placeholder, and return the placeholder.
  // Actual rendering may be delayed if the component is not loaded yet but the
  // placeholder can be inserted in its place immediately. Send a notification
  // that rendering has started (@rendering); a notification that rendering has
  // ended will be sent as well (@rendered)
  prototypes.instance._render = function (target) {
    this._placeholder = target.ownerDocument.createElementNS(bender.ns,
        "placeholder");
    this._placeholder.setAttribute("no", K++);
    this._placeholder._instance = this;
    // Keep track of pending instances (see _finished_rendering below),
    // including self
    this.__pending = [this];
    flexo.notify(this, "@rendering");
    var render = function () {
      if (this._component._view) {
        render_children(this._component._view, this._placeholder);
      }
      this._finished_rendering(this);
    };
    if (this._component) {
      render.call(this);
    } else {
      this._load_component(render);
    }
    return this._placeholder;
  };

  // instance has finished rendering, so it can be removed from the current list
  // of pending instances. When the list is empty, the instance is completely
  // rendered so we can send the @rendered event, and tell the parent instance,
  // if any, to take it of its pending list.
  prototypes.instance._finished_rendering = function(instance) {
    var removed = flexo.remove_from_array(this.__pending, instance);
    if (this.__pending.length === 0) {
      delete this.__pending;
      flexo.notify(this, "@rendered");
      if (this._parent) {
        this._parent._finished_rendering(this);
      }
    }
  };

  prototypes.instance._load_component = function (k) {
    if (this._uri && this._href && !this._component) {
      flexo.listen_once(this, "@loaded", function (e) {
        e.source._component = e.component;
        k.call(e.source);
      });
      flexo.listen_once(this.ownerDocument, "@error", function (e) {
        console.error("Error loading component at {0}: {1}"
          .fmt(e.uri, e.message), e.source);
      });
      this.ownerDocument._load_component(this._href, this);
    }
  };

  prototypes.instance._add_child_instance = function(template) {
    var instance = this.ownerDocument.$("instance");
    instance._template = template;
    instance._parent = this;
    this._children.push(instance);
    instance._uri = template._uri;
    instance._href = template._href;
    instance._component = template._component;
    return instance;
  };

  prototypes.instance.setAttribute = function (name, value) {
    Object.getPrototypeOf(this).setAttribute.call(this, name, value);
    if (name === "href") {
      this._href = value;
    }
  };

  prototypes.instance.insertBefore = prototypes.component.insertBefore;

  function render_children(view, target, unique) {
    A.forEach.call(view.childNodes, function (ch) {
      if (ch.nodeType === window.Node.ELEMENT_NODE) {
        if (ch.namespaceURI === bender.ns) {
          if (ch.localName === "instance") {
            var instance = instance_of(target);
            var child_instance = instance._add_child_instance(ch);
            instance.__pending.push(child_instance);
            target.appendChild(child_instance._render(target));
          } else if (ch.localName === "content") {
            var instance = instance_of(target);
            if (instance._template) {
              instance = instance._template;
            }
            if (instance.childNodes.length > 0) {
              render_children(instance, target, unique);
            } else {
              render_children(ch, target, unique);
            }
          } else if (ch.localName === "target") {
            // TODO mixing target and content
            var t = ch._find_target(target);
            if (!t) {
              console.error("No target for", ch);
              return;
            }
            if (ch._unique) {
              if (!ch._rendered) {
                render_children(ch, t, true);
                ch._rendered = true;
              }
            } else {
              render_children(ch, t, unique);
            }
          } else {
            console.warn("Unexpected Bender element {0} in view; skipped."
              .fmt(ch.localName));
          }
        } else {
          var t = target.appendChild(
            target.ownerDocument.createElementNS(ch.namespaceURI,
              ch.localName));
          A.forEach.call(ch.attributes, function (attr) {
            t.setAttributeNS(attr.namespaceURI, attr.localName, attr.value);
          });
          render_children(ch, t, unique);
        }
      } else if (ch.nodeType === window.Node.TEXT_NODE ||
        ch.nodeType === window.Node.CDATA_SECTION_NODE) {
        var t = target.appendChild(
          target.ownerDocument.createTextNode(ch.textContent));
      }
    });
  }

  // Target methods

  prototypes.target.setAttribute = function (name, value) {
    Object.getPrototypeOf(this).setAttribute.call(this, name, value);
    if (name === "q") {
      this._q = value.trim();
    } else if (name === "unique") {
      this._unique = flexo.is_true(value);
    }
  };

  // Find the target element given the `q` attribute using querySelector on the
  // destination element. If no `q` is set, just return the dest. Be careful
  // that the target may not be found
  prototypes.target._find_target = function (dest) {
    if (this._q) {
      return dest.ownerDocument.querySelector(this._q);
    }
    return dest;
  };

  // View methods

  prototypes.view.insertBefore = function (ch, ref) {
    Object.getPrototypeOf(this).insertBefore.call(this, ch, ref);
    if (!is_bender_element(ch)) {
      return wrap_element(ch, prototypes.view);
    }
  };

  prototypes.view._set_uri_for_instances = function (uri) {
    A.forEach.call(this.childNodes, function (ch) {
      if (is_bender_element(ch, "instance")) {
        ch._uri = uri;
      } else if (typeof ch._set_uri_for_instances === "function") {
        ch._set_uri_for_instances(uri);
      }
    });
  };

  // Utility functions

  // Find the nearest instance ancestor for this element (may be undefined, for
  // instance if the element is not rooted)
  function instance_of(elem) {
    if (is_bender_element(elem, "instance")) {
      return elem;
    } else if (is_bender_element(elem, "placeholder")) {
      return elem._instance;
    } else if (elem) {
      return instance_of(elem.parentNode);
    }
  }

  // Test whether the given node is an element in the Bender namespace with the
  // given name
  function is_bender_element(node, name) {
    return node instanceof window.Node &&
      node.nodeType === window.Node.ELEMENT_NODE &&
      node.namespaceURI === bender.ns &&
      (name === undefined || node.localName === name);
  }

  // Extend an element with Bender methods, calls its _init() method, and return
  // the wrapped element.
  function wrap_element(e, proto) {
    if (typeof proto !== "object") {
      proto = prototypes[e.localName];
    }
    if (proto) {
      for (var p in proto) {
        if (proto.hasOwnProperty(p)) {
          e[p] = proto[p];
        }
      }
    }
    for (p in prototypes[""]) {
      if (prototypes[""].hasOwnProperty(p) && !e.hasOwnProperty(p)) {
        e[p] = prototypes[""][p];
      }
    }
    if (typeof e._init === "function") {
      e._init();
    }
    return e;
  }

}(window.bender = {}))
<|endoftext|>


<commit_before>
import gulp   from 'gulp'
import deploy from 'gulp-gh-pages'
import path   from 'path'

gulp.task('deploy', function () {
  return gulp.src('dist/**/*')
    .pipe(deploy({
      cacheDir: path.resolve(__dirname, '../../www'),
      branch: 'master',
    }))
})
<commit_msg>fix(tasks/deploy): fix deployment to wrong remote<commit_after>
import gulp   from 'gulp'
import deploy from 'gulp-gh-pages'
import path   from 'path'

gulp.task('deploy', function () {
  return gulp.src('dist/**/*')
    .pipe(deploy({
      cacheDir: path.resolve(__dirname, '../../www'),
      remote: 'www',
      branch: 'master',
    }))
})
<|endoftext|>


<commit_before>var rewire = require('rewire');
var proxyquire = require('proxyquire');
var react = require('react-tools')

var jshintcli = rewire('jshint/src/cli');

var origLint = jshintcli.__get__("lint");

jshintcli.__set__("lint", function myLint(code, results, config, data, file) {
console.log("Linting file:",file);
origLint(react.transform(code);, results, config, data, file);
});

var libJsHint = proxyquire('grunt-contrib-jshint/lib/jshint',{
'jshint/src/cli': jshintcli
});

var gruntContribJshint = proxyquire('grunt-contrib-jshint',{
'./lib/jshint': libJsHint
});

module.exports = gruntContribJshint;
<commit_msg>Removed wrong semicolon<commit_after>var rewire = require('rewire');
var proxyquire = require('proxyquire');
var react = require('react-tools')

var jshintcli = rewire('jshint/src/cli');

var origLint = jshintcli.__get__("lint");

jshintcli.__set__("lint", function myLint(code, results, config, data, file) {
  console.log("Linting file:",file);
  origLint(react.transform(code), results, config, data, file);
});

var libJsHint = proxyquire('grunt-contrib-jshint/lib/jshint',{
  'jshint/src/cli': jshintcli
});

var gruntContribJshint = proxyquire('grunt-contrib-jshint',{
  './lib/jshint': libJsHint
});

module.exports = gruntContribJshint;
<|endoftext|>


<commit_before>import { Store } from 'express-session';
import AWS from 'aws-sdk';
import {
  DEFAULT_TABLE_NAME,
  DEFAULT_RCU,
  DEFAULT_WCU,
  DEFAULT_CALLBACK,
  DEFAULT_HASH_KEY,
  DEFAULT_HASH_PREFIX,
  DEFAULT_TTL,
  DEFAULT_TOUCH_INTERVAL,
  DEFAULT_KEEP_EXPIRED_POLICY,
  API_VERSION,
} from './constants';
import { toSecondsEpoch, debug } from './util';

/**
 * Express.js session store fro DynamoDB.
 */
export default class DynamoDBStore extends Store {
  /**
   * Constructor.
   * @param  {Object} options                Store
   * @param  {Function} callback Optional callback for table creation.
   */
  constructor(options = {}, callback = DEFAULT_CALLBACK) {
    super();
    debug('Initializing store', options);

    const {
      table = {},
      touchInterval = DEFAULT_TOUCH_INTERVAL,
      ttl = DEFAULT_TTL,
      keepExpired = DEFAULT_KEEP_EXPIRED_POLICY,
      dynamoConfig = {},
    } = options;

    const {
      name = DEFAULT_TABLE_NAME,
      hashPrefix = DEFAULT_HASH_PREFIX,
      hashKey = DEFAULT_HASH_KEY,
      readCapacityUnits = DEFAULT_RCU,
      writeCapacityUnits = DEFAULT_WCU,
    } = table;

    this.tableName = name;
    this.hashPrefix = hashPrefix;
    this.hashKey = hashKey;
    this.readCapacityUnits = Number(readCapacityUnits);
    this.writeCapacityUnits = Number(writeCapacityUnits);

    this.touchInterval = touchInterval;
    this.ttl = ttl;
    this.keepExpired = keepExpired;

    // dynamodb client configuration
    this.dynamoService = new AWS.DynamoDB({
      ...dynamoConfig,
      apiVersion: API_VERSION,
    });
    this.documentClient = new AWS.DynamoDB.DocumentClient({
      service: this.dynamoService,
    });

    // creates the table if necessary
    (async () => {
      try {
        await this.dynamoService
          .describeTable({
            TableName: this.tableName,
          })
          .promise();
        debug(`Table ${this.tableName} already exists.`, options);
        callback();
      } catch (err) {
        this.createTable(callback);
      }
    })();
  }

  /**
   * Creates the session table.
   * @param  {Function} callback Callback to be invoked at the wnd of the execution.
   */
  async createTable(callback) {
    try {
      const params = {
        TableName: this.tableName,
        KeySchema: [{ AttributeName: this.hashKey, KeyType: 'HASH' }],
        AttributeDefinitions: [{ AttributeName: this.hashKey, AttributeType: 'S' }],
        ProvisionedThroughput: {
          ReadCapacityUnits: this.readCapacityUnits,
          WriteCapacityUnits: this.writeCapacityUnits,
        },
      };
      await this.dynamoService.createTable(params).promise();
      debug(`Table ${this.tableName} created`, params);
      callback();
    } catch (err) {
      debug(`Error creating table ${this.tableName}`, err);
      callback(err);
    }
  }

  /**
   * Stores a session.
   * @param  {String}   sid      Session ID.
   * @param  {Object}   sess     The session object.
   * @param  {Function} callback Callback to be invoked at the wnd of the execution.
   */
  async set(sid, sess, callback) {
    try {
      const sessionId = this.getSessionId(sid);
      const expires = this.getExpirationDate(sess);
      const params = {
        TableName: this.tableName,
        Item: {
          [this.hashKey]: sessionId,
          expires: toSecondsEpoch(expires),
          sess: {
            ...sess,
            updated: Date.now(),
          },
        },
      };
      debug(`Saving session '${sid}'`, sess);
      this.documentClient.put(params, callback);
    } catch (err) {
      debug('Error saving session', {
        sid,
        sess,
        err,
      });
      callback(err);
    }
  }

  /**
   * Retrieves a session from dynamo.
   * @param  {String}   sid      Session ID.
   * @param  {Function} callback Callback to be invoked at the wnd of the execution.
   */
  async get(sid, callback) {
    try {
      const sessionId = this.getSessionId(sid);
      const params = {
        TableName: this.tableName,
        Key: {
          [this.hashKey]: sessionId,
        },
        ConsistentRead: true,
      };
      const result = await this.documentClient.get(params).promise();

      if (!result || !result.Item) {
        debug(`Session '${sid}' not found`);
        callback(null, null);
      } else if (!result.Item.expires || result.Item.expires <= toSecondsEpoch(new Date())) {
        debug(`Found session '${sid}' but it is expired`);
        if (this.keepExpired) {
          callback(null, null);
        } else {
          this.destroy(sid, callback);
        }
      } else {
        debug(`Session '${sid}' found`, result.Item.sess);
        callback(null, result.Item.sess);
      }
    } catch (err) {
      debug(`Error getting session '${sid}'`, err);
      callback(err);
    }
  }

  /**
   * Deletes a session from dynamo.
   * @param  {String}   sid      Session ID.
   * @param  {Function} callback Callback to be invoked at the wnd of the execution.
   */
  async destroy(sid, callback) {
    try {
      const sessionId = this.getSessionId(sid);
      const params = {
        TableName: this.tableName,
        Key: {
          [this.hashKey]: sessionId,
        },
      };
      await this.documentClient.delete(params).promise();
      debug(`Destroyed session '${sid}'`);
      callback(null, null);
    } catch (err) {
      debug(`Error destroying session '${sid}'`, err);
      callback(err);
    }
  }

  /**
   * Updates the expiration time of an existing session.
   * @param  {String}   sid      Session ID.
   * @param  {Object}   sess     The session object.
   * @param  {Function} callback Callback to be invoked at the wnd of the execution.
   */
  async touch(sid, sess, callback) {
    try {
      if (!sess.updated || Number(sess.updated) + this.touchInterval <= Date.now()) {
        const sessionId = this.getSessionId(sid);
        const expires = this.getExpirationDate(sess);
        const params = {
          TableName: this.tableName,
          Key: {
            [this.hashKey]: sessionId,
          },
          UpdateExpression: 'set expires = :e, sess.#up = :n',
          ExpressionAttributeNames: {
            '#up': 'updated',
          },
          ExpressionAttributeValues: {
            ':e': toSecondsEpoch(expires),
            ':n': Date.now(),
          },
          ReturnValues: 'UPDATED_NEW',
        };
        debug(`Touching session '${sid}'`);
        this.documentClient.update(params, callback);
      } else {
        debug(`Skipping touch of session '${sid}'`);
        callback(null);
      }
    } catch (err) {
      debug(`Error touching session '${sid}'`, err);
      callback(err);
    }
  }

  /**
   * Builds the session ID foe storage.
   * @param  {String} sid Original session id.
   * @return {String}     Prefix + original session id.
   */
  getSessionId(sid) {
    return `${this.hashPrefix}${sid}`;
  }

  /**
   * Calculates the session expiration date.
   * @param  {Object} sess The session object.
   * @return {Date}      the session expiration date.
   */
  getExpirationDate(sess) {
    let expirationDate = Date.now();
    if (sess.cookie && Number.isInteger(sess.cookie.maxAge)) {
      expirationDate += sess.cookie.maxAge;
    } else {
      expirationDate += this.ttl;
    }
    return new Date(expirationDate);
  }
}
<commit_msg>Update DynamoDBStore.js<commit_after>import { Store } from 'express-session';
import AWS from 'aws-sdk';
import {
  DEFAULT_TABLE_NAME,
  DEFAULT_RCU,
  DEFAULT_WCU,
  DEFAULT_CALLBACK,
  DEFAULT_HASH_KEY,
  DEFAULT_HASH_PREFIX,
  DEFAULT_TTL,
  DEFAULT_TOUCH_INTERVAL,
  DEFAULT_KEEP_EXPIRED_POLICY,
  API_VERSION,
} from './constants';
import { toSecondsEpoch, debug } from './util';

/**
 * Express.js session store for DynamoDB.
 */
export default class DynamoDBStore extends Store {
  /**
   * Constructor.
   * @param  {Object} options                Store
   * @param  {Function} callback Optional callback for table creation.
   */
  constructor(options = {}, callback = DEFAULT_CALLBACK) {
    super();
    debug('Initializing store', options);

    const {
      table = {},
      touchInterval = DEFAULT_TOUCH_INTERVAL,
      ttl = DEFAULT_TTL,
      keepExpired = DEFAULT_KEEP_EXPIRED_POLICY,
      dynamoConfig = {},
    } = options;

    const {
      name = DEFAULT_TABLE_NAME,
      hashPrefix = DEFAULT_HASH_PREFIX,
      hashKey = DEFAULT_HASH_KEY,
      readCapacityUnits = DEFAULT_RCU,
      writeCapacityUnits = DEFAULT_WCU,
    } = table;

    this.tableName = name;
    this.hashPrefix = hashPrefix;
    this.hashKey = hashKey;
    this.readCapacityUnits = Number(readCapacityUnits);
    this.writeCapacityUnits = Number(writeCapacityUnits);

    this.touchInterval = touchInterval;
    this.ttl = ttl;
    this.keepExpired = keepExpired;

    // dynamodb client configuration
    this.dynamoService = new AWS.DynamoDB({
      ...dynamoConfig,
      apiVersion: API_VERSION,
    });
    this.documentClient = new AWS.DynamoDB.DocumentClient({
      service: this.dynamoService,
    });

    // creates the table if necessary
    (async () => {
      try {
        await this.dynamoService
          .describeTable({
            TableName: this.tableName,
          })
          .promise();
        debug(`Table ${this.tableName} already exists.`, options);
        callback();
      } catch (err) {
        this.createTable(callback);
      }
    })();
  }

  /**
   * Creates the session table.
   * @param  {Function} callback Callback to be invoked at the wnd of the execution.
   */
  async createTable(callback) {
    try {
      const params = {
        TableName: this.tableName,
        KeySchema: [{ AttributeName: this.hashKey, KeyType: 'HASH' }],
        AttributeDefinitions: [{ AttributeName: this.hashKey, AttributeType: 'S' }],
        ProvisionedThroughput: {
          ReadCapacityUnits: this.readCapacityUnits,
          WriteCapacityUnits: this.writeCapacityUnits,
        },
      };
      await this.dynamoService.createTable(params).promise();
      debug(`Table ${this.tableName} created`, params);
      callback();
    } catch (err) {
      debug(`Error creating table ${this.tableName}`, err);
      callback(err);
    }
  }

  /**
   * Stores a session.
   * @param  {String}   sid      Session ID.
   * @param  {Object}   sess     The session object.
   * @param  {Function} callback Callback to be invoked at the wnd of the execution.
   */
  async set(sid, sess, callback) {
    try {
      const sessionId = this.getSessionId(sid);
      const expires = this.getExpirationDate(sess);
      const params = {
        TableName: this.tableName,
        Item: {
          [this.hashKey]: sessionId,
          expires: toSecondsEpoch(expires),
          sess: {
            ...sess,
            updated: Date.now(),
          },
        },
      };
      debug(`Saving session '${sid}'`, sess);
      this.documentClient.put(params, callback);
    } catch (err) {
      debug('Error saving session', {
        sid,
        sess,
        err,
      });
      callback(err);
    }
  }

  /**
   * Retrieves a session from dynamo.
   * @param  {String}   sid      Session ID.
   * @param  {Function} callback Callback to be invoked at the wnd of the execution.
   */
  async get(sid, callback) {
    try {
      const sessionId = this.getSessionId(sid);
      const params = {
        TableName: this.tableName,
        Key: {
          [this.hashKey]: sessionId,
        },
        ConsistentRead: true,
      };
      const result = await this.documentClient.get(params).promise();

      if (!result || !result.Item) {
        debug(`Session '${sid}' not found`);
        callback(null, null);
      } else if (!result.Item.expires || result.Item.expires <= toSecondsEpoch(new Date())) {
        debug(`Found session '${sid}' but it is expired`);
        if (this.keepExpired) {
          callback(null, null);
        } else {
          this.destroy(sid, callback);
        }
      } else {
        debug(`Session '${sid}' found`, result.Item.sess);
        callback(null, result.Item.sess);
      }
    } catch (err) {
      debug(`Error getting session '${sid}'`, err);
      callback(err);
    }
  }

  /**
   * Deletes a session from dynamo.
   * @param  {String}   sid      Session ID.
   * @param  {Function} callback Callback to be invoked at the wnd of the execution.
   */
  async destroy(sid, callback) {
    try {
      const sessionId = this.getSessionId(sid);
      const params = {
        TableName: this.tableName,
        Key: {
          [this.hashKey]: sessionId,
        },
      };
      await this.documentClient.delete(params).promise();
      debug(`Destroyed session '${sid}'`);
      callback(null, null);
    } catch (err) {
      debug(`Error destroying session '${sid}'`, err);
      callback(err);
    }
  }

  /**
   * Updates the expiration time of an existing session.
   * @param  {String}   sid      Session ID.
   * @param  {Object}   sess     The session object.
   * @param  {Function} callback Callback to be invoked at the wnd of the execution.
   */
  async touch(sid, sess, callback) {
    try {
      if (!sess.updated || Number(sess.updated) + this.touchInterval <= Date.now()) {
        const sessionId = this.getSessionId(sid);
        const expires = this.getExpirationDate(sess);
        const params = {
          TableName: this.tableName,
          Key: {
            [this.hashKey]: sessionId,
          },
          UpdateExpression: 'set expires = :e, sess.#up = :n',
          ExpressionAttributeNames: {
            '#up': 'updated',
          },
          ExpressionAttributeValues: {
            ':e': toSecondsEpoch(expires),
            ':n': Date.now(),
          },
          ReturnValues: 'UPDATED_NEW',
        };
        debug(`Touching session '${sid}'`);
        this.documentClient.update(params, callback);
      } else {
        debug(`Skipping touch of session '${sid}'`);
        callback(null);
      }
    } catch (err) {
      debug(`Error touching session '${sid}'`, err);
      callback(err);
    }
  }

  /**
   * Builds the session ID foe storage.
   * @param  {String} sid Original session id.
   * @return {String}     Prefix + original session id.
   */
  getSessionId(sid) {
    return `${this.hashPrefix}${sid}`;
  }

  /**
   * Calculates the session expiration date.
   * @param  {Object} sess The session object.
   * @return {Date}      the session expiration date.
   */
  getExpirationDate(sess) {
    let expirationDate = Date.now();
    if (sess.cookie && Number.isInteger(sess.cookie.maxAge)) {
      expirationDate += sess.cookie.maxAge;
    } else {
      expirationDate += this.ttl;
    }
    return new Date(expirationDate);
  }
}
<|endoftext|>


<commit_before>
/*
 * grunt-todo
 * https://github.com/Leny/grunt-todo
 *
 * Copyright (c) 2014 leny
 * Licensed under the MIT license.
 */
"use strict";
var Parker, chalk;

chalk = require("chalk");

Parker = require("parker");

module.exports = function(grunt) {
  return grunt.registerMultiTask("parker", "Stylesheet analysis", function() {
    var aLogFileLines, aMetrics, i, len, oError, oMetric, oOptions, oParsedMetrics, oProjectPackage, parker, sDefaultTitle, sDescription, sHomePage, sMetric, sTitle, sVersion;
    oOptions = this.options({
      metrics: false,
      file: false,
      title: false,
      colophon: false,
      usePackage: false
    });
    aLogFileLines = [];
    sDefaultTitle = "Grunt Parker Report";
    if (grunt.util.kindOf(oOptions.metrics) === "array") {
      aMetrics = (function() {
        var i, len, ref, results;
        ref = oOptions.metrics;
        results = [];
        for (i = 0, len = ref.length; i < len; i++) {
          sMetric = ref[i];
          results.push(require("parker/metrics/" + sMetric + ".js"));
        }
        return results;
      })();
    } else {
      aMetrics = require("parker/metrics/All.js");
    }
    parker = new Parker(aMetrics);
    oParsedMetrics = {};
    for (i = 0, len = aMetrics.length; i < len; i++) {
      oMetric = aMetrics[i];
      oParsedMetrics[oMetric.id] = oMetric;
    }
    if (oOptions.usePackage) {
      try {
        oProjectPackage = grunt.file.readJSON((process.cwd()) + "/package.json");
      } catch (_error) {
        oError = _error;
        grunt.log.writeln("");
        grunt.log.writeln(chalk.yellow.bold("Oops:"), "No " + (chalk.cyan('package.json')) + " file found. Disabling " + (chalk.green('usePackage')) + " option.");
        oOptions.usePackage = false;
      }
    }
    if (oOptions.file) {
      if (sTitle = oOptions.title || (oOptions.usePackage && oProjectPackage.name ? oProjectPackage.name : false) || sDefaultTitle) {
        if (oOptions.usePackage) {
          if (sHomePage = oProjectPackage.homepage) {
            aLogFileLines.push("# [" + sTitle + "]( " + sHomePage + " )");
          } else {
            aLogFileLines.push("# " + sTitle);
          }
          aLogFileLines.push("");
          if (sVersion = oProjectPackage.version) {
            aLogFileLines.push("**Version:** `" + sVersion + "`");
            aLogFileLines.push("");
          }
          if (sDescription = oProjectPackage.description) {
            aLogFileLines.push("> " + sDescription);
            aLogFileLines.push("");
            aLogFileLines.push("* * *");
            aLogFileLines.push("");
          }
        } else {
          aLogFileLines.push("# " + sTitle);
          aLogFileLines.push("");
        }
        if (sTitle !== sDefaultTitle) {
          aLogFileLines.push("## Parker Report");
        }
      } else {
        aLogFileLines.push("# " + sDefaultTitle);
      }
      aLogFileLines.push("");
    }
    this.filesSrc.filter(function(sFilePath) {
      return grunt.file.exists(sFilePath) && grunt.file.isFile(sFilePath);
    }).forEach(function(sFilePath) {
      var aFileResults, aResult, aResults, j, len1, mValue, oParkerMetrics, sResult, sValue;
      aResults = [];
      aFileResults = [];
      oParkerMetrics = parker.run(grunt.file.read(sFilePath));
      if (oParkerMetrics) {
        for (sMetric in oParkerMetrics) {
          mValue = oParkerMetrics[sMetric];
          aResults.push([oParsedMetrics[sMetric].name, mValue]);
        }
        if (aResults.length) {
          grunt.log.writeln();
          grunt.log.writeln(chalk.underline(sFilePath));
          grunt.log.writeln();
          for (j = 0, len1 = aResults.length; j < len1; j++) {
            aResult = aResults[j];
            sValue = (function() {
              var k, l, len2, len3, ref, ref1, results;
              switch (grunt.util.kindOf(aResult[1])) {
                case "array":
                  grunt.log.writeln(chalk.cyan(aResult[0] + ":"));
                  ref = aResult[1];
                  for (k = 0, len2 = ref.length; k < len2; k++) {
                    sResult = ref[k];
                    grunt.log.writeln("\t" + sResult);
                  }
                  aFileResults.push("- **" + aResult[0] + ":**");
                  ref1 = aResult[1];
                  results = [];
                  for (l = 0, len3 = ref1.length; l < len3; l++) {
                    sResult = ref1[l];
                    if (sResult.substring(0, 1) === "#") {
                      sResult = "`" + sResult + "`";
                    }
                    results.push(aFileResults.push("\t- " + sResult));
                  }
                  return results;
                  break;
                case "number":
                  grunt.log.writeln(chalk.cyan(aResult[0] + ":"), chalk.yellow(aResult[1]));
                  return aFileResults.push("- **" + aResult[0] + ":** " + aResult[1]);
                default:
                  grunt.log.writeln(chalk.cyan(aResult[0] + ":"), aResult[1]);
                  return aFileResults.push("- **" + aResult[0] + ":** " + aResult[1]);
              }
            })();
          }
        }
      }
      if (oOptions.file && aFileResults.length) {
        aLogFileLines.push("### " + sFilePath);
        aLogFileLines.push("");
        aLogFileLines = aLogFileLines.concat(aFileResults);
        return aLogFileLines.push("");
      }
    });
    if (oOptions.file) {
      if (oOptions.colophon) {
        aLogFileLines.push("");
        aLogFileLines.push("* * *");
        aLogFileLines.push("");
        aLogFileLines.push("Last generated: " + (grunt.template.today()) + " by [grunt-parker](https://github.com/leny/grunt-parker).");
        aLogFileLines.push("");
      }
      grunt.file.write(oOptions.file, aLogFileLines.join("\n"));
      grunt.log.writeln();
      return grunt.log.writeln("Logged in " + (chalk.yellow(oOptions.file)));
    }
  });
};
<commit_msg>Silence output to grunt console with options.file<commit_after>
/*
 * grunt-todo
 * https://github.com/Leny/grunt-todo
 *
 * Copyright (c) 2014 leny
 * Licensed under the MIT license.
 */
"use strict";
var Parker, chalk;

chalk = require("chalk");

Parker = require("parker");

module.exports = function(grunt) {
  return grunt.registerMultiTask("parker", "Stylesheet analysis", function() {
    var aLogFileLines, aMetrics, i, len, oError, oMetric, oOptions, oParsedMetrics, oProjectPackage, parker, sDefaultTitle, sDescription, sHomePage, sMetric, sTitle, sVersion;
    oOptions = this.options({
      metrics: false,
      file: false,
      title: false,
      colophon: false,
      usePackage: false
    });
    aLogFileLines = [];
    sDefaultTitle = "Grunt Parker Report";
    if (grunt.util.kindOf(oOptions.metrics) === "array") {
      aMetrics = (function() {
        var i, len, ref, results;
        ref = oOptions.metrics;
        results = [];
        for (i = 0, len = ref.length; i < len; i++) {
          sMetric = ref[i];
          results.push(require("parker/metrics/" + sMetric + ".js"));
        }
        return results;
      })();
    } else {
      aMetrics = require("parker/metrics/All.js");
    }
    parker = new Parker(aMetrics);
    oParsedMetrics = {};
    for (i = 0, len = aMetrics.length; i < len; i++) {
      oMetric = aMetrics[i];
      oParsedMetrics[oMetric.id] = oMetric;
    }
    if (oOptions.usePackage) {
      try {
        oProjectPackage = grunt.file.readJSON((process.cwd()) + "/package.json");
      } catch (_error) {
        oError = _error;
        grunt.log.writeln("");
        grunt.log.writeln(chalk.yellow.bold("Oops:"), "No " + (chalk.cyan('package.json')) + " file found. Disabling " + (chalk.green('usePackage')) + " option.");
        oOptions.usePackage = false;
      }
    }
    if (oOptions.file) {
      if (sTitle = oOptions.title || (oOptions.usePackage && oProjectPackage.name ? oProjectPackage.name : false) || sDefaultTitle) {
        if (oOptions.usePackage) {
          if (sHomePage = oProjectPackage.homepage) {
            aLogFileLines.push("# [" + sTitle + "]( " + sHomePage + " )");
          } else {
            aLogFileLines.push("# " + sTitle);
          }
          aLogFileLines.push("");
          if (sVersion = oProjectPackage.version) {
            aLogFileLines.push("**Version:** `" + sVersion + "`");
            aLogFileLines.push("");
          }
          if (sDescription = oProjectPackage.description) {
            aLogFileLines.push("> " + sDescription);
            aLogFileLines.push("");
            aLogFileLines.push("* * *");
            aLogFileLines.push("");
          }
        } else {
          aLogFileLines.push("# " + sTitle);
          aLogFileLines.push("");
        }
        if (sTitle !== sDefaultTitle) {
          aLogFileLines.push("## Parker Report");
        }
      } else {
        aLogFileLines.push("# " + sDefaultTitle);
      }
      aLogFileLines.push("");
    }
    this.filesSrc.filter(function(sFilePath) {
      return grunt.file.exists(sFilePath) && grunt.file.isFile(sFilePath);
    }).forEach(function(sFilePath) {
      var aFileResults, aResult, aResults, j, len1, mValue, oParkerMetrics, sResult, sValue;
      aResults = [];
      aFileResults = [];
      oParkerMetrics = parker.run(grunt.file.read(sFilePath));
      if (oParkerMetrics) {
        for (sMetric in oParkerMetrics) {
          mValue = oParkerMetrics[sMetric];
          aResults.push([oParsedMetrics[sMetric].name, mValue]);
        }
        if (aResults.length) {
          if(!oOptions.file){
            grunt.log.writeln();
            grunt.log.writeln(chalk.underline(sFilePath));
            grunt.log.writeln();
          }
          for (j = 0, len1 = aResults.length; j < len1; j++) {
            aResult = aResults[j];
            sValue = (function() {
              var k, l, len2, len3, ref, ref1, results;
              switch (grunt.util.kindOf(aResult[1])) {
                case "array":
                  if(!oOptions.file){ grunt.log.writeln(chalk.cyan(aResult[0] + ":")); }
                  ref = aResult[1];
                  for (k = 0, len2 = ref.length; k < len2; k++) {
                    sResult = ref[k];
                    if(!oOptions.file){ grunt.log.writeln("\t" + sResult); }
                  }
                  aFileResults.push("- **" + aResult[0] + ":**");
                  ref1 = aResult[1];
                  results = [];
                  for (l = 0, len3 = ref1.length; l < len3; l++) {
                    sResult = ref1[l];
                    if (sResult.substring(0, 1) === "#") {
                      sResult = "`" + sResult + "`";
                    }
                    results.push(aFileResults.push("\t- " + sResult));
                  }
                  return results;
                  break;
                case "number":
                  if(!oOptions.file){ grunt.log.writeln(chalk.cyan(aResult[0] + ":"), chalk.yellow(aResult[1])); }
                  return aFileResults.push("- **" + aResult[0] + ":** " + aResult[1]);
                default:
                  if(!oOptions.file){ grunt.log.writeln(chalk.cyan(aResult[0] + ":"), aResult[1]); }
                  return aFileResults.push("- **" + aResult[0] + ":** " + aResult[1]);
              }
            })();
          }
        }
      }
      if (oOptions.file && aFileResults.length) {
        aLogFileLines.push("### " + sFilePath);
        aLogFileLines.push("");
        aLogFileLines = aLogFileLines.concat(aFileResults);
        return aLogFileLines.push("");
      }
    });
    if (oOptions.file) {
      if (oOptions.colophon) {
        aLogFileLines.push("");
        aLogFileLines.push("* * *");
        aLogFileLines.push("");
        aLogFileLines.push("Last generated: " + (grunt.template.today()) + " by [grunt-parker](https://github.com/leny/grunt-parker).");
        aLogFileLines.push("");
      }
      grunt.file.write(oOptions.file, aLogFileLines.join("\n"));
      grunt.log.writeln();
      return grunt.log.writeln("Logged in " + (chalk.yellow(oOptions.file)));
    }
  });
};
<|endoftext|>


<commit_before>/*jshint node:true, latedef:false */

'use strict';

var fs      = require('fs');
var path    = require('path');
var express = require('express');
var connect = require('connect');

var task = {
    id: 'server',
    name: 'Server',
    author: 'Indigo United',
    description: 'Run server',
    options: {
        env: {
            description: 'The environment that the server will run',
            'default': 'dev'
        },
        favicon: {
            description: 'The favicon path',
            'default': './favicon.ico'
        },
        index: {
            description: 'The index file to use (defaults to the index according to the environment)'
        },
        rewrite: {
            description: 'Enable or disable URL rewrite (in order to pushState to work)',
            'default': true
        },
        gzip: {
            description: 'Enable gzip compression (defaults to true if environment is not dev)'
        },
        port: {
            description: 'The port listen for requests',
            'default': 8000
        },
        host: {
            description: 'The host to listen for requests',
            'default': '127.0.0.1'
        }
    },
    filter: function (options, ctx, next) {
        if (!options.index) {
            options.index = options.env === 'dev' ? './index.html' : './index_' + options.env + '.html';
        }
        if (options.gzip == null) {
            options.gzip = options.env !== 'dev';
        }

        if (options.env === 'dev') {
            options.rootSymlink = true;
            options.rewrite = false;
            options.assetsDir = 'root';
        } else {
            options.assetsDir = options.env;
        }

        next();
    },
    tasks: [
        {
            task: function (options, ctx, next) {
                // Change cwd to the web folder
                process.chdir('web');
                var web = process.cwd(),
                    env = options.env,
                    root;

                // Check if the env is valid
                try {
                    fs.statSync(options.index);
                } catch (e) {
                    if (e.code === 'ENOENT') {
                        return next(new Error('Invalid environment: ' + env));
                    }
                }

                options.web = web;

                // Create root symlink
                if (options.rootSymlink) {
                    root = path.join(web, 'root');
                    try {
                        fs.unlink(root);
                    } catch (e) {}

                    fs.symlinkSync(path.resolve(web, '..'), root, 'dir');
                }

                try {
                    fs.statSync(options.assetsDir);
                } catch (e) {
                    if (e.code === 'ENOENT') {
                        return next(new Error('Assets dir not found, did you forgot to build?'));
                    }
                }

                next();
            },
            description: 'Prepare server'
        },
        {
            task: function (opts) {
                // Check if assets dir exists
                var site = express();

                // Enable compression?
                if (opts.gzip) {
                    express.use(connect.compress());
                }

                // Serve index
                site.get('/', function (req, res) {
                    return res.sendfile(opts.index);
                });

                // Serve favicon.ico
                site.use(express.favicon(opts.favicon));

                // Serve files & folders
                site.get('/*', function (req, res) {
                    // Get the requested file
                    // If there are query parameters, remove them
                    var file = path.join(opts.web, req.url.substr(1));
                    file = file.split('?')[0];

                    fs.stat(file, function (err, stat) {
                        // If file does not exists, serve 404 page
                        if (err && err.code === 'ENOENT') {
                            serve404(opts, res);
                        // If it exists and is a file, serve it
                        } else if (stat.isFile()) {
                            res.sendfile(file);
                        // Otherwise is a folder, so we deny the access
                        } else {
                            res.send(403);
                        }
                    });
                });

                // Effectively listen
                site.listen(opts.port, opts.host);
                this.log.infoln('Listening on http://' + (opts.host === '127.0.0.1' ? 'localhost' : opts.host) + ':' + opts.port + ' (' + opts.env + ' environment)');
            },
            description: 'Serve files'
        }
    ]
};

/**
 * Serve 404 page.
 *
 * @param {Object} The task options
 * @param {Object} The express response object
 */
function serve404(options, res) {
    // If the rewrite is disabled, we attempt to serve the 404.html page
    // Otherwise we rewrite to the front controller (index)
    if (!options.rewrite) {
        var file404 = path.join(options.web, '404.html');
        fs.stat(file404, function (err) {
            if (!err) {
                res.status(404);
                res.sendfile('404.html');
            } else {
                res.send(404);
            }
        });
    } else {
        res.sendfile(options.index);
    }
}

module.exports = task;
<commit_msg>Fix small issue in the server task.<commit_after>/*jshint node:true, latedef:false */

'use strict';

var fs      = require('fs');
var path    = require('path');
var express = require('express');
var connect = require('connect');

var task = {
    id: 'server',
    name: 'Server',
    author: 'Indigo United',
    description: 'Run server',
    options: {
        env: {
            description: 'The environment that the server will run',
            'default': 'dev'
        },
        favicon: {
            description: 'The favicon path',
            'default': './favicon.ico'
        },
        index: {
            description: 'The index file to use (defaults to the index according to the environment)'
        },
        rewrite: {
            description: 'Enable or disable URL rewrite (in order to pushState to work)',
            'default': true
        },
        gzip: {
            description: 'Enable gzip compression (defaults to true if environment is not dev)'
        },
        port: {
            description: 'The port listen for requests',
            'default': 8000
        },
        host: {
            description: 'The host to listen for requests',
            'default': '127.0.0.1'
        }
    },
    filter: function (options, ctx, next) {
        if (!options.index) {
            options.index = options.env === 'dev' ? './index.html' : './index_' + options.env + '.html';
        }
        if (options.gzip == null) {
            options.gzip = options.env !== 'dev';
        }

        if (options.env === 'dev') {
            options.rootSymlink = true;
            options.rewrite = false;
            options.assetsDir = 'root';
        } else {
            options.assetsDir = options.env;
        }

        next();
    },
    tasks: [
        {
            task: function (options, ctx, next) {
                // Change cwd to the web folder
                process.chdir('web');
                var web = process.cwd(),
                    env = options.env,
                    root;

                // Check if the env is valid
                try {
                    fs.statSync(options.index);
                } catch (e) {
                    if (e.code === 'ENOENT') {
                        return next(new Error('Invalid environment: ' + env));
                    }
                }

                options.web = web;

                // Create root symlink
                if (options.rootSymlink) {
                    root = path.join(web, 'root');
                    try {
                        fs.unlinkSync(root);
                    } catch (e) {}

                    fs.symlinkSync(path.resolve(web, '..'), root, 'dir');
                }

                try {
                    fs.statSync(options.assetsDir);
                } catch (e) {
                    if (e.code === 'ENOENT') {
                        return next(new Error('Assets dir not found, did you forgot to build?'));
                    }
                }

                next();
            },
            description: 'Prepare server'
        },
        {
            task: function (opts) {
                // Check if assets dir exists
                var site = express();

                // Enable compression?
                if (opts.gzip) {
                    site.use(connect.compress());
                }

                // Serve index
                site.get('/', function (req, res) {
                    return res.sendfile(opts.index);
                });

                // Serve favicon.ico
                site.use(express.favicon(opts.favicon));

                // Serve files & folders
                site.get('/*', function (req, res) {
                    // Get the requested file
                    // If there are query parameters, remove them
                    var file = path.join(opts.web, req.url.substr(1));
                    file = file.split('?')[0];

                    fs.stat(file, function (err, stat) {
                        // If file does not exists, serve 404 page
                        if (err && err.code === 'ENOENT') {
                            serve404(opts, res);
                        // If it exists and is a file, serve it
                        } else if (stat.isFile()) {
                            res.sendfile(file);
                        // Otherwise is a folder, so we deny the access
                        } else {
                            res.send(403);
                        }
                    });
                });

                // Effectively listen
                site.listen(opts.port, opts.host);
                this.log.infoln('Listening on http://' + (opts.host === '127.0.0.1' ? 'localhost' : opts.host) + ':' + opts.port + ' (' + opts.env + ' environment)');
            },
            description: 'Serve files'
        }
    ]
};

/**
 * Serve 404 page.
 *
 * @param {Object} The task options
 * @param {Object} The express response object
 */
function serve404(options, res) {
    // If the rewrite is disabled, we attempt to serve the 404.html page
    // Otherwise we rewrite to the front controller (index)
    if (!options.rewrite) {
        var file404 = path.join(options.web, '404.html');
        fs.stat(file404, function (err) {
            if (!err) {
                res.status(404);
                res.sendfile('404.html');
            } else {
                res.send(404);
            }
        });
    } else {
        res.sendfile(options.index);
    }
}

module.exports = task;
<|endoftext|>


<commit_before>import React from 'react';
import PropTypes from 'prop-types';
import {
  Dimensions,
  ListView,
  TouchableHighlight,
  View,
  StyleSheet,
} from 'react-native';

import Constants from './constants';
import { Photo } from './media';

// 1 margin and 1 border width
const ITEM_MARGIN = 2;

export default class GridContainer extends React.Component {

  static propTypes = {
    style: View.propTypes.style,
    square: PropTypes.bool,
    dataSource: PropTypes.instanceOf(ListView.DataSource).isRequired,
    displaySelectionButtons: PropTypes.bool,
    onPhotoTap: PropTypes.func,
    itemPerRow: PropTypes.number,

    /*
     * refresh the list to apply selection change
     */
    onMediaSelection: PropTypes.func,

    /**
     * offsets the width of the grid
     */
    offset: PropTypes.number,
  };

  static defaultProps = {
    displaySelectionButtons: false,
    onPhotoTap: () => {},
    itemPerRow: 3,
  };

  constructor(props, context) {
    super(props, context);

    this._renderRow = this._renderRow.bind(this);

    this.state = {};
  }

  _renderRow(media: Object, sectionID: number, rowID: number) {
    const {
      displaySelectionButtons,
      onPhotoTap,
      onMediaSelection,
      itemPerRow,
      square,
      offset,
      renderCustomState
    } = this.props;
    const screenWidth = Dimensions.get('window').width - offset;
    const photoWidth = (screenWidth / itemPerRow) - (ITEM_MARGIN * 2);

    return (
      <TouchableHighlight onPress={() => onPhotoTap(parseInt(rowID, 10))}>
        <View style={[styles.row, media.state === 'Deleted' ? {borderColor: 'red'} : {}, media.state === 'Unapproved' ? {borderColor: 'black'} : {}]}>
          <Photo
            item={media}
            width={photoWidth}
            height={square ? photoWidth : 100}
            resizeMode={'cover'}
            thumbnail
            progressImage={require('../Assets/hourglass.png')}
            displaySelectionButtons={displaySelectionButtons}
            uri={media.thumb || media.photo}
            selected={media.selected}
            onSelection={(isSelected) => {
              onMediaSelection(rowID, isSelected);
            }}
            renderCustomState={renderCustomState}
          />
        </View>
      </TouchableHighlight>
    );
  }

  render() {
    const { dataSource } = this.props;

    return (
      <View style={styles.container}>
        <ListView
          contentContainerStyle={styles.list}
          dataSource={dataSource}
          initialListSize={21}
          pageSize={3}
          scrollRenderAheadDistance={500}
          renderRow={this._renderRow}
          removeClippedSubviews={false}
        />
      </View>
    );
  }

}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    paddingBottom: Constants.TOOLBAR_HEIGHT,
  },
  list: {
    justifyContent: 'flex-start',
    alignItems: 'flex-start',
    flexDirection: 'row',
    flexWrap: 'wrap',
  },
  row: {
    justifyContent: 'center',
    margin: 1,
    alignItems: 'center',
    borderColor: 'grey',
    borderWidth: 1,
    borderRadius: 1,
  },
});
<commit_msg>added sticky footer<commit_after>import React from 'react';
import PropTypes from 'prop-types';
import {
  Dimensions,
  ListView,
  TouchableHighlight,
  View,
  StyleSheet,
} from 'react-native';

import Constants from './constants';
import { Photo } from './media';

// 1 margin and 1 border width
const ITEM_MARGIN = 2;

export default class GridContainer extends React.Component {

  static propTypes = {
    style: View.propTypes.style,
    square: PropTypes.bool,
    dataSource: PropTypes.instanceOf(ListView.DataSource).isRequired,
    displaySelectionButtons: PropTypes.bool,
    onPhotoTap: PropTypes.func,
    itemPerRow: PropTypes.number,

    /*
     * refresh the list to apply selection change
     */
    onMediaSelection: PropTypes.func,

    /**
     * offsets the width of the grid
     */
    offset: PropTypes.number,
  };

  static defaultProps = {
    displaySelectionButtons: false,
    onPhotoTap: () => {},
    itemPerRow: 3,
  };

  constructor(props, context) {
    super(props, context);

    this._renderRow = this._renderRow.bind(this);

    this.state = {};
  }

  _renderRow(media: Object, sectionID: number, rowID: number) {
    const {
      displaySelectionButtons,
      onPhotoTap,
      onMediaSelection,
      itemPerRow,
      square,
      offset,
      renderCustomState
    } = this.props;
    const screenWidth = Dimensions.get('window').width - offset;
    const photoWidth = (screenWidth / itemPerRow) - (ITEM_MARGIN * 2);

    return (
      <TouchableHighlight onPress={() => onPhotoTap(parseInt(rowID, 10))}>
        <View style={[styles.row, media.state === 'Deleted' ? {borderColor: 'red'} : {}, media.state === 'Unapproved' ? {borderColor: 'black'} : {}]}>
          <Photo
            item={media}
            width={photoWidth}
            height={square ? photoWidth : 100}
            resizeMode={'cover'}
            thumbnail
            progressImage={require('../Assets/hourglass.png')}
            displaySelectionButtons={displaySelectionButtons}
            uri={media.thumb || media.photo}
            selected={media.selected}
            onSelection={(isSelected) => {
              onMediaSelection(rowID, isSelected);
            }}
            renderCustomState={renderCustomState}
          />
        </View>
      </TouchableHighlight>
    );
  }

  render() {
    const { dataSource, stickyFooter } = this.props;

    return (
      <View style={styles.container}>
        <ListView
          contentContainerStyle={styles.list}
          dataSource={dataSource}
          initialListSize={21}
          pageSize={3}
          scrollRenderAheadDistance={500}
          renderRow={this._renderRow}
          removeClippedSubviews={false}
			/>

		{stickyFooter && <View style={styles.filterContainer}></View>}
      </View>
    );
  }

}

const styles = StyleSheet.create({
  container: {
	flex: 1,
	flexDirection: 'column',
	paddingBottom: Constants.TOOLBAR_HEIGHT,
  },
  list: {
    justifyContent: 'flex-start',
    alignItems: 'flex-start',
    flexDirection: 'row',
	flexWrap: 'wrap',
  },
  row: {
    justifyContent: 'center',
    margin: 1,
    alignItems: 'center',
    borderColor: 'grey',
    borderWidth: 1,
    borderRadius: 1,
  },

  filterContainer: {
	backgroundColor: 'purple',
	bottom: 0,
	elevation: 5,
	flexDirection: 'row',
	height: Constants.TOOLBAR_HEIGHT,
	left: 0,
	position: 'absolute',
	right: 0,
	shadowColor: 'black',
	shadowOpacity: 0.2,
	shadowRadius: 1
},
});
<|endoftext|>


<commit_before>var gulp = require('gulp');
var s3 = require('s3');
var fs = require('fs');
var args = require('yargs').argv;
var exec = require('child_process').exec;

gulp.task('upload', ['release'], function(b) {
  var tag = args.tag || undefined;
  upload('./dist/', 'latest/', true);
  upload('./public/', '', false);
  if (tag) {
    exec('git tag ' + tag)
    exec('git push origin master --tags')
    upload(tag + '/');
  }
  return;
});

var upload = function(localDir, prefix, deleteRemoved) {
  var awsOptions = JSON.parse(fs.readFileSync('./aws.json'));
  var client = s3.createClient({s3Options: awsOptions});
  var params = {localDir: localDir, deleteRemoved: !!deleteRemoved, s3Params: {Bucket: "cdn.clappr.io", Prefix: prefix}};
  var uploader = client.uploadDir(params);
  uploader.on('error', function(err) { console.error("unable to sync:", err.stack); });
  uploader.on('end', function() { console.log("done uploading for " + prefix); });
}
<commit_msg>tasks: fix tag upload (fixes #228)<commit_after>var gulp = require('gulp');
var s3 = require('s3');
var fs = require('fs');
var args = require('yargs').argv;
var exec = require('child_process').exec;

gulp.task('upload', ['release'], function(b) {
  var tag = args.tag || undefined;
//  upload('./dist/', 'latest/', true);
  if (tag) {
    upload('./dist/', tag + '/', true);
  }
  return;
});

var upload = function(localDir, prefix, deleteRemoved) {
  var awsOptions = JSON.parse(fs.readFileSync('./aws.json'));
  var client = s3.createClient({s3Options: awsOptions});
  var params = {localDir: localDir, deleteRemoved: !!deleteRemoved, s3Params: {Bucket: "cdn.clappr.io", Prefix: prefix}};
  var uploader = client.uploadDir(params);
  uploader.on('error', function(err) { console.error("unable to sync:", err.stack); });
  uploader.on('end', function() { console.log("done uploading for " + prefix); });
}
<|endoftext|>


<commit_before>import React from 'react';
import Const from './Const';

class TableRow extends React.Component{

  constructor(props) {
    super(props);
    this.clickNum = 0;
  }

  rowClick(e){
    if(e.target.tagName !== "INPUT" &&
        e.target.tagName !== "SELECT" &&
        e.target.tagName !== "TEXTAREA") {
      const rowIndex = e.currentTarget.rowIndex;
      if (this.props.selectRow) {
          if (this.props.selectRow.clickToSelect) {
            this.props.onSelectRow(rowIndex, !this.props.isSelected);
          } else if (this.props.selectRow.clickToSelectAndEditCell) {
            this.clickNum++;
            /** if clickToSelectAndEditCell is enabled,
             *  there should be a delay to prevent a selection changed when
             *  user dblick to edit cell on same row but different cell
            **/
            setTimeout(() => {
              if(this.clickNum === 1) {
                this.props.onSelectRow(rowIndex, !this.props.isSelected);
              }
              this.clickNum = 0;
            }, 200);
          }
      }
      if (this.props.onRowClick) this.props.onRowClick(rowIndex);
    }
  }

  rowMouseOut(e) {
    if (this.props.onRowMouseOut) {
      this.props.onRowMouseOut(e.currentTarget.rowIndex);
    }
  }

  rowMouseOver(e) {
    if (this.props.onRowMouseOver) {
      this.props.onRowMouseOver(e.currentTarget.rowIndex);
    }
  }

  render(){
    this.clickNum = 0;
    var trCss={
      style:{
        backgroundColor: this.props.isSelected?this.props.selectRow.bgColor:null
      },
      className:(this.props.isSelected && this.props.selectRow.className ? this.props.selectRow.className : '') + (this.props.className||'')
    };

    if(this.props.selectRow && (this.props.selectRow.clickToSelect ||
      this.props.selectRow.clickToSelectAndEditCell) || this.props.onRowClick){
      return(

{this.props.children}

      )
    }else{
      return(

{this.props.children}

      )
    }
  }
}
TableRow.propTypes = {
  isSelected: React.PropTypes.bool,
  enableCellEdit: React.PropTypes.bool,
  onRowClick: React.PropTypes.func,
  onSelectRow: React.PropTypes.func,
  onRowMouseOut: React.PropTypes.func,
  onRowMouseOver: React.PropTypes.func
};
TableRow.defaultProps = {
  onRowClick: undefined
}
export default TableRow;
<commit_msg>fix row selection index is shifted after rebase<commit_after>import React from 'react';
import Const from './Const';

class TableRow extends React.Component{

  constructor(props) {
    super(props);
    this.clickNum = 0;
  }

  rowClick(e){
    if(e.target.tagName !== "INPUT" &&
        e.target.tagName !== "SELECT" &&
        e.target.tagName !== "TEXTAREA") {
      const rowIndex = e.currentTarget.rowIndex + 1;
      if (this.props.selectRow) {
          if (this.props.selectRow.clickToSelect) {
            this.props.onSelectRow(rowIndex, !this.props.isSelected);
          } else if (this.props.selectRow.clickToSelectAndEditCell) {
            this.clickNum++;
            /** if clickToSelectAndEditCell is enabled,
             *  there should be a delay to prevent a selection changed when
             *  user dblick to edit cell on same row but different cell
            **/
            setTimeout(() => {
              if(this.clickNum === 1) {
                this.props.onSelectRow(rowIndex, !this.props.isSelected);
              }
              this.clickNum = 0;
            }, 200);
          }
      }
      if (this.props.onRowClick) this.props.onRowClick(rowIndex);
    }
  }

  rowMouseOut(e) {
    if (this.props.onRowMouseOut) {
      this.props.onRowMouseOut(e.currentTarget.rowIndex);
    }
  }

  rowMouseOver(e) {
    if (this.props.onRowMouseOver) {
      this.props.onRowMouseOver(e.currentTarget.rowIndex);
    }
  }

  render(){
    this.clickNum = 0;
    var trCss={
      style:{
        backgroundColor: this.props.isSelected?this.props.selectRow.bgColor:null
      },
      className:(this.props.isSelected && this.props.selectRow.className ? this.props.selectRow.className : '') + (this.props.className||'')
    };

    if(this.props.selectRow && (this.props.selectRow.clickToSelect ||
      this.props.selectRow.clickToSelectAndEditCell) || this.props.onRowClick){
      return(

{this.props.children}

      )
    }else{
      return(

{this.props.children}

      )
    }
  }
}
TableRow.propTypes = {
  isSelected: React.PropTypes.bool,
  enableCellEdit: React.PropTypes.bool,
  onRowClick: React.PropTypes.func,
  onSelectRow: React.PropTypes.func,
  onRowMouseOut: React.PropTypes.func,
  onRowMouseOver: React.PropTypes.func
};
TableRow.defaultProps = {
  onRowClick: undefined
}
export default TableRow;
<|endoftext|>


<commit_before>(function(W, U) {
	'use strict';

	W.fn.make('assets', {
		// Cache pre-existing CSS and JavaScript asset references
		_construct: function() {
			this.loaded = {};

			W.$each('link[rel="stylesheet"], script[src]', function(el) {
				this.loaded[el.href || el.src] = el;
			}, {
				scope: this
			});
		},
		// Get currently bound resource root or set root with specified value
		// Returns string
		root: function(value) {
			return value ? this.$set('.', value) : this.$get('.', '');
		},
		// Load specified assets with specified set of options
		load: function(options) {
			var conf = W.$extend({
					files: [],
					js: [],
					css: [],
					img: []
				}, options),
				files = W.$toArray(conf.files),
				js = W.$toArray(conf.js),
				css = W.$toArray(conf.css),
				img = W.$toArray(conf.img),
				root = conf.root !== U ? conf.root : this.root(),
				now = new Date().getTime(),
				i = 0,
				type;

			// Create group name if not specified
			if (! conf.group) {
				conf.group = 'load-' + now;
			}

			// Determine file type
			var assets = [];

			for (; i < files.length; i++) {
				var ext = files[i].split('.').pop().split(/\#|\?/)[0];
				type = (ext == 'js' || ext == 'css') ?
					ext : (/(gif|jpe?g|png|svg)$/i).test(ext) ?
						'img' : '';

				if (type) {
					assets[files[i]] = type;
				}
			}

			for (i = 0; i < js.length; i++) {
				assets[js[i]] = 'js';
			}

			for (i = 0; i < css.length; i++) {
				assets[css[i]] = 'css';
			}

			for (i = 0; i < img.length; i++) {
				assets[img[i]] = 'img';
			}

			// Set file array length to check against
			this.$set(conf.group, Object.keys(assets).length);
			this.$set(conf.group + 'fail', 0);
			this.$set(conf.group + 'conf', conf);

			// Request each specified file
			for (var file in assets) {
				type = assets[file];
				file = root + file;

				if (! this.loaded[file]) {
					if (conf.cache === false) {
						file += (file.indexOf('?') < 0 ? '?' : '&') + now;
					}

					this.$private('load', file, type, conf);
				}
			}
		},
		// Remove one or more files from the DOM
		remove: function(files, root) {
			files = W.$toArray(files);
			root = root || '';

			var keys = Object.keys(files),
				a = W._doc.createElement('a'),
				i = 0;

			for (; i < keys.length; i++) {
				var key = keys[i],
					src = root + files[key];
				a.href = src;
				src = a.href;

				var el = this.loaded[src];

				if (el !== U) {
					el.parentNode.removeChild(el);
					el = null;
					delete this.loaded[src];
				}
			}
		},
		// When specified references are ready execute callback
		ready: function(group, options, poll) {
			if (this.$get(group) === 0) {
				var conf = W.$extend(this.$get(group + 'conf'), options);
				options = {
					args: conf.args,
					scope: conf.scope
				};

				if (conf.failure && this.$get(group + 'fail') > 0) {
					W.$exec(conf.failure, options);
				} else if (conf.success) {
					W.$exec(conf.success, options);
				}
			} else if (poll) {
				setTimeout(function() {
					W.assets.ready(group, {}, true);
				}, 20);
			}
		}
	}, {
		// Request specific file
		load: function(path, type, conf) {
			var scope = this,
				pub = scope.$public,
				head = W._doc.getElementsByTagName('head')[0],
				group = conf.group,
				img = new Image();

			// Load file based on extension
			if (type == 'js') {
				var js = W._doc.createElement('script');

				js.src = path;
				js.async = conf.async === true;

				js.onload = js.onreadystatechange = function() {
					var rs = js.readyState;

					if (rs && rs != 'complete' && rs != 'loaded') {
						return;
					}

					pub.loaded[js.src] = js;
					scope.done(group);
				};

				js.onerror = function() {
					scope.fail(group);
				};

				head.appendChild(js);
			} else if (type == 'css') {
				var link = W._doc.createElement('link');

				link.rel = 'stylesheet';
				link.href = path;

				head.appendChild(link);

				img.onerror = function() {
					pub.loaded[link.href] = link;
					scope.done(group);
				};

				img.src = path;
			} else if (type == 'img') {
				img.onload = function() {
					scope.done(group);
				};

				img.onerror = function() {
					scope.fail(group);
				};

				img.src = path;
			}
		},
		// Decrement remaining count of assets to be loaded
		done: function(group) {
			this.$set(group, this.$get(group) - 1);
			this.$public.ready(group, {}, false);
		},
		// Track failed resources
		fail: function(group) {
			var key = group + 'fail';

			this.$set(key, this.$get(key) + 1);
			this.done(group);
		}
	});
})(Wee, undefined);<commit_msg>Replace CSS image src hack with a check against the document stylesheets<commit_after>(function(W, U) {
	'use strict';

	W.fn.make('assets', {
		// Cache pre-existing CSS and JavaScript asset references
		_construct: function() {
			var scope = this;
			this.loaded = {};

			W.$each('link[rel="stylesheet"], script[src]', function(el) {
				scope.loaded[el.href || el.src] = el;
			});
		},
		// Get currently bound resource root or set root with specified value
		// Returns string
		root: function(value) {
			return value ? this.$set('.', value) : this.$get('.', '');
		},
		// Load specified assets with specified set of options
		load: function(options) {
			var conf = W.$extend({
					files: [],
					js: [],
					css: [],
					img: []
				}, options),
				files = W.$toArray(conf.files),
				js = W.$toArray(conf.js),
				css = W.$toArray(conf.css),
				img = W.$toArray(conf.img),
				root = conf.root !== U ? conf.root : this.root(),
				now = new Date().getTime(),
				i = 0,
				assets = [],
				type;

			// Create group name if not specified
			if (! conf.group) {
				conf.group = 'load-' + now;
			}

			// Determine file type
			for (; i < files.length; i++) {
				var ext = files[i].split('.').pop().split(/\#|\?/)[0];
				type = (ext == 'js' || ext == 'css') ?
					ext : (/(gif|jpe?g|png|svg)$/i).test(ext) ?
						'img' : '';

				if (type) {
					assets[files[i]] = type;
				}
			}

			for (i = 0; i < js.length; i++) {
				assets[js[i]] = 'js';
			}

			for (i = 0; i < css.length; i++) {
				assets[css[i]] = 'css';
			}

			for (i = 0; i < img.length; i++) {
				assets[img[i]] = 'img';
			}

			// Set file array length to check against
			this.$set(conf.group, Object.keys(assets).length);
			this.$set(conf.group + 'fail', 0);
			this.$set(conf.group + 'conf', conf);

			// Request each specified file
			for (var file in assets) {
				type = assets[file];
				file = root + file;

				if (! this.loaded[file]) {
					if (conf.cache === false) {
						file += (file.indexOf('?') < 0 ? '?' : '&') + now;
					}

					this.$private('load', file, type, conf);
				}
			}
		},
		// Remove one or more files from the DOM
		remove: function(files, root) {
			files = W.$toArray(files);
			root = root || '';

			var keys = Object.keys(files),
				a = W._doc.createElement('a'),
				i = 0;

			for (; i < keys.length; i++) {
				var key = keys[i],
					src = root + files[key];
				a.href = src;
				src = a.href;

				var el = this.loaded[src];

				if (el !== U) {
					el.parentNode.removeChild(el);
					el = null;
					delete this.loaded[src];
				}
			}
		},
		// When specified references are ready execute callback
		ready: function(group, options, poll) {
			if (this.$get(group) === 0) {
				var conf = W.$extend(this.$get(group + 'conf'), options);
				options = {
					args: conf.args,
					scope: conf.scope
				};

				if (conf.failure && this.$get(group + 'fail') > 0) {
					W.$exec(conf.failure, options);
				} else if (conf.success) {
					W.$exec(conf.success, options);
				}
			} else if (poll) {
				setTimeout(function() {
					W.assets.ready(group, {}, true);
				}, 20);
			}
		}
	}, {
		// Request specific file
		load: function(path, type, conf) {
			var scope = this,
				pub = scope.$public,
				head = W._doc.getElementsByTagName('head')[0],
				group = conf.group;

			// Load file based on extension
			if (type == 'js') {
				var js = W._doc.createElement('script');

				head.appendChild(js);

				if (Wee._legacy) {
					js.onreadystatechange = function() {
						var rs = js.readyState;

						if (rs != 'complete' && rs != 'loaded') {
							return;
						}

						pub.loaded[js.src] = js;
						scope.done(group);
					};
				} else {
					js.async = conf.async === true;

					js.onload = function() {
						pub.loaded[js.src] = js;
						scope.done(group);
					};

					js.onerror = function() {
						scope.fail(group);
					};
				}

				js.src = path;
			} else if (type == 'css') {
				var link = W._doc.createElement('link');

				link.rel = 'stylesheet';
				link.href = path;

				if (Wee._legacy) {
					this.ind = this.ind ? this.ind + 1 : 1;
					var id = 'load-' + this.ind;
					link.id = id;

					link.attachEvent('onload', function() {
						var sheets = Wee._doc.styleSheets,
							i = sheets.length,
							text;

						try {
							while (i--) {
								var sheet = sheets[i];

								if (sheet.id == id) {
									text = sheet.cssText;
									scope.done(group);
									return;
								}
							}
						} catch (e) {}

						if (! text) {
							scope.fail(group);
						}
					});
				} else {
					link.addEventListener('load', function() {
						scope.done(group);
					}, false);

					link.addEventListener('error', function() {
						scope.fail(group);
					}, false);
				}

				head.appendChild(link);
			} else if (type == 'img') {
				var img = new Image();

				img.onload = function() {
					scope.done(group);
				};

				img.onerror = function() {
					scope.fail(group);
				};

				img.src = path;
			}
		},
		// Decrement remaining count of assets to be loaded
		done: function(group) {
			this.$set(group, this.$get(group) - 1);
			this.$public.ready(group, {}, false);
		},
		// Track failed resources
		fail: function(group) {
			var key = group + 'fail';

			this.$set(key, this.$get(key) + 1);
			this.done(group);
		}
	});
})(Wee, undefined);<|endoftext|>