<commit_before>/**
 * StopFlash
 *
 * https://github.com/JWhile/StopFlash
 *
 * content_script.js
 */

// function isFlash(HTMLElement element):boolean
var isFlash = function(element)
{
    return (element.nodeName === 'OBJECT' || element.nodeName === 'EMBED');
};

// class FlashCollection
function FlashCollection(doc)
{
    this.flashElements = []; // :Array<FlashElement>

    this.port = chrome.runtime.connect({'name': 'stopflashContentScript'}); // :chrome.runtime.Port

    this.elementId = 0; // :int

    this.whitelist = []; // :Array<String>

    this.id = 0; // :int

    var self = this;

    this.port.onMessage.addListener(function(req)
    {
        if(req['stopflashWhitelist'])
        {
            self.whitelist = req['stopflashWhitelist'];
            self.id = req['stopflashCollectionId'];

            // init
            self.add(doc.getElementsByTagName('OBJECT'));
            self.add(doc.getElementsByTagName('EMBED'));

            self.sendData();
        }

        if(req['stopflashBlock'])
        {
            var e = self.getById(req['stopflashBlock'].id);

            if(e != null)
            {
                e.block();

                self.sendData();
            }
        }

        if(req['stopflashUnblock'])
        {
            var e = self.getById(req['stopflashUnblock'].id);

            if(e != null)
            {
                e.unblock();

                self.sendData();
            }
        }
    });

    this.port.postMessage({'stopflashInit': true, 'stopflashIsMainFrame': (window == window.top)});

    var observer = new MutationObserver(function(changes)
    {
        var changed = false;

        for(var i = 0, c; i < changes.length; ++i)
        {
            c = changes[i];

            if(c.addedNodes != null)
            {
                changed = (self.add(c.addedNodes) || false);
            }

            if(c.removedNodes != null)
            {
                changed = (self.remove(c.removedNodes) || false);
            }
        }

        if(changed)
        {
            self.sendData();
        }
    });

    observer.observe(doc, {childList: true, subtree: true});

    this.sendData();
}
// function sendData():void
FlashCollection.prototype.sendData = function()
{
    var data = [];

    for(var i = 0; i < this.flashElements.length; ++i)
    {
        data.push(this.flashElements[i].getData());
    }

    this.port.postMessage({'stopflashDataUpdate': true, 'stopflashData': data, 'stopflashCollectionId': this.id});
};
// function add(NodeList elements):boolean
FlashCollection.prototype.add = function(elements)
{
    var changed = false;

    for(var i = 0, e; i < elements.length; ++i)
    {
        e = elements[i];

        if(isFlash(e))
        {
            var parent = e;

            while(parent = parent.parentNode)
            {
                if(isFlash(parent))
                {
                    e = parent;
                }
            }

            var f = this.get(e);

            if(f == null)
            {
                f = new FlashElement(this, ++this.elementId, e);

                if(f.isValid())
                {
                    this.flashElements.push(f);

                    if(!f.isWhitelist())
                    {
                        f.block();
                    }

                    changed = true;
                }
            }
            else
            {
                f.update();

                if(f.blocked)
                {
                    f.block();
                }
            }
        }
    }

    return changed;
};
// function remove(NodeList elements):boolean
FlashCollection.prototype.remove = function(elements)
{
    var changed = false;

    for(var i = 0, f; i < elements.length; ++i)
    {
        f = this.get(elements[i]);

        if(f != null && !f.blocked)
        {
            f.remove();

            changed = true;
        }
    }

    return changed;
};
// function get(HTMLElement element)
FlashCollection.prototype.get = function(element)
{
    for(var i = 0; i < this.flashElements.length; ++i)
    {
        if(element == this.flashElements[i].element)
        {
            return this.flashElements[i];
        }
    }

    return null;
};
// function getById(int id)
FlashCollection.prototype.getById = function(id)
{
    for(var i = 0; i < this.flashElements.length; ++i)
    {
        if(id === this.flashElements[i].id)
        {
            return this.flashElements[i];
        }
    }

    return null;
};

var styles = [
    'float', 'clear',
    'position', 'top', 'left',
    'margin-top', 'margin-right', 'margin-bottom', 'margin-left',
    'padding-top', 'padding-right', 'padding-bottom', 'padding-left',
    'border-top', 'border-right', 'border-bottom', 'border-left'
]; // :Array<String>

var iconSizes = [128, 64, 48]; // :Array<int>

// class FlashElement
function FlashElement(collection, id, element)
{
    this.collection = collection; // :FlashCollection

    this.id = id; // :int

    this.parent = element.parentNode; // :HTMLElement
    this.element = element; // :HTMLElement
    this.nextSibling = element.nextSibling; // :HTMLElement

    this.blocked = false; // :boolean

    var self = this;

    var width = parseInt(Builder.getStyle(element, 'width'));
    var height = parseInt(Builder.getStyle(element, 'height'));

    var size = 32;

    for(var i = 0, s; i < iconSizes.length; ++i)
    {
        s = iconSizes[i];

        if(s < width && s < height)
        {
            size = s;
            break;
        }
    }

    var replacement = new Builder('div')
        .css('display', 'block')
        .css('width', width +'px')
        .css('height', height +'px')
        .css('cursor', 'pointer')
        .css('min-width', '34px')
        .css('min-height', '34px')
        .css('background', '#333 url("'+ chrome.extension.getURL('icons/stopflash_'+ size +'.png') +'") center center no-repeat')
        .event('click', function()
        {
            self.unblock();

            self.collection.sendData();
        });

    for(var i = 0; i < styles.length; ++i)
    {
        replacement.css(styles[i], Builder.getStyle(element, styles[i]));
    }

    this.replacement = replacement.node; // :HTMLElement
}
// function isValid():boolean
FlashElement.prototype.isValid = function()
{
    return (this.parent != null && this.getUrl() != null);
};
// function getData():Object
FlashElement.prototype.getData = function()
{
    return {
        'collection': this.collection.id,
        'id': this.id,
        'type': this.element.nodeName,
        'url': this.getUrl(),
        'blocked': this.blocked,
        'whitelist': this.isWhitelist()
    };
};
// function isWhitelist():boolean
FlashElement.prototype.isWhitelist = function()
{
    var url = this.getUrl();

    for(var i = 0; i < this.collection.whitelist.length; ++i)
    {
        if(url.indexOf(this.collection.whitelist[i]) >= 0)
        {
            return true;
        }
    }

    return false;
};
// function getUrl():String
FlashElement.prototype.getUrl = function()
{
    if(this.element.nodeName === 'EMBED')
    {
        return this.element.src;
    }
    else if(this.element.nodeName === 'OBJECT')
    {
        if(this.element.data)
        {
            return this.element.data;
        }
        else
        {
            var child = this.element.firstChild;

            while(child != null)
            {
                if(child.nodeName === 'PARAM' && (child.name === 'src' || child.name === 'movie'))
                {
                    return child.value;
                }

                child = child.nextSibling;
            }
        }
    }

    return null;
};
// function update():void
FlashElement.prototype.update = function()
{
    if(this.element.parentNode)
    {
        this.parent = this.element.parentNode;
        this.nextSibling = this.element.nextSibling;
    }
    else if(this.replacement.parentNode)
    {
        this.parent = this.replacement.parentNode;
        this.nextSibling = this.replacement.nextSibling;
    }
};
// function block():void
FlashElement.prototype.block = function()
{
    this.blocked = true;

    this.parent.insertBefore(this.replacement, this.nextSibling);

    this.parent.removeChild(this.element);
};
// function unblock():void
FlashElement.prototype.unblock = function()
{
    this.blocked = false;

    this.parent.insertBefore(this.element, this.nextSibling);

    this.parent.removeChild(this.replacement);
};
// function remove():void
FlashElement.prototype.remove = function()
{
    if(this.replacement.parentNode)
    {
        this.replacement.parentNode.removeChild(this.replacement);
    }

    if(this.element.parentNode)
    {
        this.element.parentNode.removeChild(this.element);
    }
};

// main
var collection = null;

var main = function()
{
    collection = new FlashCollection(document);
};

document.addEventListener('DOMContentLoaded', main, false);
<commit_msg>Handle stopflashIsWhitelist data & not block on whitelisted tab<commit_after>/**
 * StopFlash
 *
 * https://github.com/JWhile/StopFlash
 *
 * content_script.js
 */

// function isFlash(HTMLElement element):boolean
var isFlash = function(element)
{
    return (element.nodeName === 'OBJECT' || element.nodeName === 'EMBED');
};

// class FlashCollection
function FlashCollection(doc)
{
    this.flashElements = []; // :Array<FlashElement>

    this.port = chrome.runtime.connect({'name': 'stopflashContentScript'}); // :chrome.runtime.Port

    this.elementId = 0; // :int

    this.whitelist = []; // :Array<String>
    this.isWhitelist = false; // :boolean

    this.id = 0; // :int

    var self = this;

    this.port.onMessage.addListener(function(req)
    {
        if(req['stopflashWhitelist'])
        {
            self.whitelist = req['stopflashWhitelist'];
            self.isWhitelist = req['stopflashIsWhitelist'];
            self.id = req['stopflashCollectionId'];

            // init
            self.add(doc.getElementsByTagName('OBJECT'));
            self.add(doc.getElementsByTagName('EMBED'));

            self.sendData();
        }

        if(req['stopflashBlock'])
        {
            var e = self.getById(req['stopflashBlock'].id);

            if(e != null)
            {
                e.block();

                self.sendData();
            }
        }

        if(req['stopflashUnblock'])
        {
            var e = self.getById(req['stopflashUnblock'].id);

            if(e != null)
            {
                e.unblock();

                self.sendData();
            }
        }
    });

    this.port.postMessage({'stopflashInit': true, 'stopflashIsMainFrame': (window == window.top)});

    var observer = new MutationObserver(function(changes)
    {
        var changed = false;

        for(var i = 0, c; i < changes.length; ++i)
        {
            c = changes[i];

            if(c.addedNodes != null)
            {
                changed = (self.add(c.addedNodes) || false);
            }

            if(c.removedNodes != null)
            {
                changed = (self.remove(c.removedNodes) || false);
            }
        }

        if(changed)
        {
            self.sendData();
        }
    });

    observer.observe(doc, {childList: true, subtree: true});

    this.sendData();
}
// function sendData():void
FlashCollection.prototype.sendData = function()
{
    var data = [];

    for(var i = 0; i < this.flashElements.length; ++i)
    {
        data.push(this.flashElements[i].getData());
    }

    this.port.postMessage({'stopflashDataUpdate': true, 'stopflashData': data, 'stopflashCollectionId': this.id});
};
// function add(NodeList elements):boolean
FlashCollection.prototype.add = function(elements)
{
    var changed = false;

    for(var i = 0, e; i < elements.length; ++i)
    {
        e = elements[i];

        if(isFlash(e))
        {
            var parent = e;

            while(parent = parent.parentNode)
            {
                if(isFlash(parent))
                {
                    e = parent;
                }
            }

            var f = this.get(e);

            if(f == null)
            {
                f = new FlashElement(this, ++this.elementId, e);

                if(f.isValid())
                {
                    this.flashElements.push(f);

                    if(!f.isWhitelist() && !this.isWhitelist)
                    {
                        f.block();
                    }

                    changed = true;
                }
            }
            else
            {
                f.update();

                if(f.blocked)
                {
                    f.block();
                }
            }
        }
    }

    return changed;
};
// function remove(NodeList elements):boolean
FlashCollection.prototype.remove = function(elements)
{
    var changed = false;

    for(var i = 0, f; i < elements.length; ++i)
    {
        f = this.get(elements[i]);

        if(f != null && !f.blocked)
        {
            f.remove();

            changed = true;
        }
    }

    return changed;
};
// function get(HTMLElement element)
FlashCollection.prototype.get = function(element)
{
    for(var i = 0; i < this.flashElements.length; ++i)
    {
        if(element == this.flashElements[i].element)
        {
            return this.flashElements[i];
        }
    }

    return null;
};
// function getById(int id)
FlashCollection.prototype.getById = function(id)
{
    for(var i = 0; i < this.flashElements.length; ++i)
    {
        if(id === this.flashElements[i].id)
        {
            return this.flashElements[i];
        }
    }

    return null;
};

var styles = [
    'float', 'clear',
    'position', 'top', 'left',
    'margin-top', 'margin-right', 'margin-bottom', 'margin-left',
    'padding-top', 'padding-right', 'padding-bottom', 'padding-left',
    'border-top', 'border-right', 'border-bottom', 'border-left'
]; // :Array<String>

var iconSizes = [128, 64, 48]; // :Array<int>

// class FlashElement
function FlashElement(collection, id, element)
{
    this.collection = collection; // :FlashCollection

    this.id = id; // :int

    this.parent = element.parentNode; // :HTMLElement
    this.element = element; // :HTMLElement
    this.nextSibling = element.nextSibling; // :HTMLElement

    this.blocked = false; // :boolean

    var self = this;

    var width = parseInt(Builder.getStyle(element, 'width'));
    var height = parseInt(Builder.getStyle(element, 'height'));

    var size = 32;

    for(var i = 0, s; i < iconSizes.length; ++i)
    {
        s = iconSizes[i];

        if(s < width && s < height)
        {
            size = s;
            break;
        }
    }

    var replacement = new Builder('div')
        .css('display', 'block')
        .css('width', width +'px')
        .css('height', height +'px')
        .css('cursor', 'pointer')
        .css('min-width', '34px')
        .css('min-height', '34px')
        .css('background', '#333 url("'+ chrome.extension.getURL('icons/stopflash_'+ size +'.png') +'") center center no-repeat')
        .event('click', function()
        {
            self.unblock();

            self.collection.sendData();
        });

    for(var i = 0; i < styles.length; ++i)
    {
        replacement.css(styles[i], Builder.getStyle(element, styles[i]));
    }

    this.replacement = replacement.node; // :HTMLElement
}
// function isValid():boolean
FlashElement.prototype.isValid = function()
{
    return (this.parent != null && this.getUrl() != null);
};
// function getData():Object
FlashElement.prototype.getData = function()
{
    return {
        'collection': this.collection.id,
        'id': this.id,
        'type': this.element.nodeName,
        'url': this.getUrl(),
        'blocked': this.blocked,
        'whitelist': this.isWhitelist()
    };
};
// function isWhitelist():boolean
FlashElement.prototype.isWhitelist = function()
{
    var url = this.getUrl();

    for(var i = 0; i < this.collection.whitelist.length; ++i)
    {
        if(url.indexOf(this.collection.whitelist[i]) >= 0)
        {
            return true;
        }
    }

    return false;
};
// function getUrl():String
FlashElement.prototype.getUrl = function()
{
    if(this.element.nodeName === 'EMBED')
    {
        return this.element.src;
    }
    else if(this.element.nodeName === 'OBJECT')
    {
        if(this.element.data)
        {
            return this.element.data;
        }
        else
        {
            var child = this.element.firstChild;

            while(child != null)
            {
                if(child.nodeName === 'PARAM' && (child.name === 'src' || child.name === 'movie'))
                {
                    return child.value;
                }

                child = child.nextSibling;
            }
        }
    }

    return null;
};
// function update():void
FlashElement.prototype.update = function()
{
    if(this.element.parentNode)
    {
        this.parent = this.element.parentNode;
        this.nextSibling = this.element.nextSibling;
    }
    else if(this.replacement.parentNode)
    {
        this.parent = this.replacement.parentNode;
        this.nextSibling = this.replacement.nextSibling;
    }
};
// function block():void
FlashElement.prototype.block = function()
{
    this.blocked = true;

    this.parent.insertBefore(this.replacement, this.nextSibling);

    this.parent.removeChild(this.element);
};
// function unblock():void
FlashElement.prototype.unblock = function()
{
    this.blocked = false;

    this.parent.insertBefore(this.element, this.nextSibling);

    this.parent.removeChild(this.replacement);
};
// function remove():void
FlashElement.prototype.remove = function()
{
    if(this.replacement.parentNode)
    {
        this.replacement.parentNode.removeChild(this.replacement);
    }

    if(this.element.parentNode)
    {
        this.element.parentNode.removeChild(this.element);
    }
};

// main
var collection = null;

var main = function()
{
    collection = new FlashCollection(document);
};

document.addEventListener('DOMContentLoaded', main, false);
<|endoftext|>


<commit_before>define([
  "lodash",
  "vue",
  "frontend/util/ajax",
  "frontend/helpers/watch-hash",
  "frontend/views/route-config/v-route-config",
  "./v-control-panel.tmpl",
  "./v-control-panel.styl"
], function (_, Vue, ajax, watchHash, RouteConfig, tmpl) {

  return Vue.extend({
    template: tmpl,

    components: {
      "route-config": RouteConfig
    },

    mixins: [
      watchHash
    ],

    watch: {
      "delay": _.debounce(function (newValue) {
        ajax.put("/surrogate/api/delay", {
          data: { delay: newValue }
        });
      }, 300)
    },

    computed: {
      // range 0 - 10
      delayWidgetPosition: {
        get: function () {
          var number;
          if (this.delay === 0) {
            return 0;
          } else if (this.delay === null  ) {
            return 10;
          }
          number = Math.log(this.delay / 10) / Math.log(2);
          return parseFloat(number.toPrecision(2));
        },
        set: function (newValue) {
          newValue = parseFloat(newValue);
          if (newValue === 0) {
            this.delay = 0;
          } else if (newValue === 10) {
            this.delay = null;
          } else {
            this.delay = Math.pow(2, newValue) * 10;
          }
        }
      },

      delayDisplay: function () {
        return this.delay === "forever" ?
          "HANG" :
          this.delay.toString() + " ms";
      }
    },

    methods: {
      resetSurrogate: function () {
        var self = this;
        return ajax.post("/surrogate/api/reset").then(function () {
          self._getDocument().location.reload();
        });
      },

      toggleRouteConfig: function (route) {
        var alreadyExpanded = route.expanded;
        _.each(this.routes, function (route) {
          route.expanded = false;
        });
        route.expanded = !alreadyExpanded;
      },

      _getDocument: function () {
        return document;
      }
    }
  });

});
<commit_msg>v-control-panel.js --> CJS<commit_after>var
  ajax = require("frontend/util/ajax"),
  RouteConfig = require("frontend/views/route-config/v-route-config"),
  watchHash = require("frontend/helpers/watch-hash"),
  tmpl = require("./v-control-panel.tmpl"),
  _ = require("lodash"),
  Vue = require("vue");

require("./v-control-panel.styl");

module.exports = Vue.extend({
  template: tmpl,

  components: {
    "route-config": RouteConfig
  },

  mixins: [
    watchHash
  ],

  watch: {
    "delay": _.debounce(function (newValue) {
      ajax.put("/surrogate/api/delay", {
        data: { delay: newValue }
      });
    }, 300)
  },

  computed: {
    // range 0 - 10
    delayWidgetPosition: {
      get: function () {
        var number;
        if (this.delay === 0) {
          return 0;
        } else if (this.delay === null  ) {
          return 10;
        }
        number = Math.log(this.delay / 10) / Math.log(2);
        return parseFloat(number.toPrecision(2));
      },
      set: function (newValue) {
        newValue = parseFloat(newValue);
        if (newValue === 0) {
          this.delay = 0;
        } else if (newValue === 10) {
          this.delay = null;
        } else {
          this.delay = Math.pow(2, newValue) * 10;
        }
      }
    },

    delayDisplay: function () {
      return this.delay === "forever" ?
        "HANG" :
        this.delay.toString() + " ms";
    }
  },

  methods: {
    resetSurrogate: function () {
      var self = this;
      return ajax.post("/surrogate/api/reset").then(function () {
        self._getDocument().location.reload();
      });
    },

    toggleRouteConfig: function (route) {
      var alreadyExpanded = route.expanded;
      _.each(this.routes, function (route) {
        route.expanded = false;
      });
      route.expanded = !alreadyExpanded;
    },

    _getDocument: function () {
      return document;
    }
  }
});
<|endoftext|>


<commit_before>import React, { useState } from 'react';
import PropTypes from 'prop-types';
import { Editor } from 'react-draft-wysiwyg';
import cx from 'classnames';
import {
  IconTextBoldMediumOutline,
  IconTextItalicMediumOutline,
  IconListNumeredMediumOutline,
  IconListMediumOutline,
  IconLinkMediumOutline,
} from '@teamleader/ui-icons';

import Box, { pickBoxProps } from '../box';
import ValidationText from '../validationText';

import InlineStylingOptions from './InlineStylingOptions';
import ListStylingOptions from './ListStylingOptions';
import LinkOptions from './LinkOptions';
import { linkDecorator } from './decorators';
import theme from './theme.css';
import translations from './translations';

const toolbar = {
  options: ['inline', 'list', 'link'],
  inline: {
    options: ['bold', 'italic'],
    bold: { icon: <IconTextBoldMediumOutline /> },
    italic: { icon: <IconTextItalicMediumOutline /> },
    component: InlineStylingOptions,
  },
  list: {
    component: ListStylingOptions,
    options: ['unordered', 'ordered'],
    unordered: { icon: <IconListMediumOutline /> },
    ordered: { icon: <IconListNumeredMediumOutline /> },
  },
  link: {
    component: LinkOptions,
    defaultTargetOption: '_self',
    showOpenOptionOnHover: true,
    options: ['link'],
    link: { icon: <IconLinkMediumOutline /> },
  },
};

const customStyleMap = {
  BOLD: {
    fontFamily: 'Inter-Bold',
  },
};

const availableLocales = ['en', 'es', 'it', 'nl', 'fr', 'de'];

const WysiwygEditor = ({
  className,
  error,
  onFocus,
  onBlur,
  success,
  warning,
  helpText,
  width,
  locale = 'en',
  ...others
}) => {
  const [isFocused, setIsFocused] = useState(false);
  const [isPlaceholderShown, setIsPlaceholderShown] = useState(true);

  const handleBlur = (event) => {
    setIsFocused(false);
    if (onBlur) {
      onBlur(event);
    }
  };

  const handleFocus = (event) => {
    setIsFocused(true);
    if (onFocus) {
      onFocus(event);
    }
  };

  const handleContentStateChange = ({ blocks: [{ type }] }) => {
    if (type === 'unstyled') {
      setIsPlaceholderShown(true);
      return;
    }
    setIsPlaceholderShown(false);
  };

  const wrapperClassNames = cx(
    theme['wrapper'],
    {
      [theme['has-focus']]: isFocused,
      [theme['has-error']]: error,
      [theme['has-success']]: success,
      [theme['has-warning']]: warning,
      [theme['has-placeholder']]: isPlaceholderShown,
    },
    className,
  );

  const boxProps = pickBoxProps(others);

  return (
    <Box style={{ width, flex: width && '0 0 auto' }} {...boxProps}>
      <Editor
        toolbar={toolbar}
        wrapperClassName={wrapperClassNames}
        editorClassName={theme['input']}
        toolbarClassName={theme['toolbar']}
        onFocus={handleFocus}
        onBlur={handleBlur}
        onContentStateChange={handleContentStateChange}
        customStyleMap={customStyleMap}
        customDecorators={[linkDecorator]}
        localization={
          availableLocales.includes(locale)
            ? {
                locale,
                translations: translations[locale],
              }
            : {
                locale: 'en',
                translations: translations['en'],
              }
        }
        {...others}
      />
      <ValidationText error={error} help={helpText} success={success} warning={warning} />
    </Box>
  );
};

WysiwygEditor.propTypes = {
  /** The text string/element to use as error message below the input. */
  error: PropTypes.oneOfType([PropTypes.bool, PropTypes.node]),
  /** The text string to use as help text below the input. */
  helpText: PropTypes.string,
  /** The text string/element to use as a prefix inside the input field */
  success: PropTypes.oneOfType([PropTypes.bool, PropTypes.node]),
  /** The text string/element to use as a suffix inside the input field */
  warning: PropTypes.oneOfType([PropTypes.bool, PropTypes.node]),
  /** A custom width for the editor field */
  width: PropTypes.string,
  /** Locale key for the language you want the editor to be displayed in. */
  locale: PropTypes.string,
};

export default WysiwygEditor;
<commit_msg>:sparkles: Add `inputClassname` prop on `WysiwygEditor`<commit_after>import React, { useState } from 'react';
import PropTypes from 'prop-types';
import { Editor } from 'react-draft-wysiwyg';
import cx from 'classnames';
import {
  IconTextBoldMediumOutline,
  IconTextItalicMediumOutline,
  IconListNumeredMediumOutline,
  IconListMediumOutline,
  IconLinkMediumOutline,
} from '@teamleader/ui-icons';

import Box, { pickBoxProps } from '../box';
import ValidationText from '../validationText';

import InlineStylingOptions from './InlineStylingOptions';
import ListStylingOptions from './ListStylingOptions';
import LinkOptions from './LinkOptions';
import { linkDecorator } from './decorators';
import theme from './theme.css';
import translations from './translations';

const toolbar = {
  options: ['inline', 'list', 'link'],
  inline: {
    options: ['bold', 'italic'],
    bold: { icon: <IconTextBoldMediumOutline /> },
    italic: { icon: <IconTextItalicMediumOutline /> },
    component: InlineStylingOptions,
  },
  list: {
    component: ListStylingOptions,
    options: ['unordered', 'ordered'],
    unordered: { icon: <IconListMediumOutline /> },
    ordered: { icon: <IconListNumeredMediumOutline /> },
  },
  link: {
    component: LinkOptions,
    defaultTargetOption: '_self',
    showOpenOptionOnHover: true,
    options: ['link'],
    link: { icon: <IconLinkMediumOutline /> },
  },
};

const customStyleMap = {
  BOLD: {
    fontFamily: 'Inter-Bold',
  },
};

const availableLocales = ['en', 'es', 'it', 'nl', 'fr', 'de'];

const WysiwygEditor = ({
  className,
  error,
  onFocus,
  onBlur,
  success,
  warning,
  helpText,
  width,
  locale = 'en',
  inputClassName,
  ...others
}) => {
  const [isFocused, setIsFocused] = useState(false);
  const [isPlaceholderShown, setIsPlaceholderShown] = useState(true);

  const handleBlur = (event) => {
    setIsFocused(false);
    if (onBlur) {
      onBlur(event);
    }
  };

  const handleFocus = (event) => {
    setIsFocused(true);
    if (onFocus) {
      onFocus(event);
    }
  };

  const handleContentStateChange = ({ blocks: [{ type }] }) => {
    if (type === 'unstyled') {
      setIsPlaceholderShown(true);
      return;
    }
    setIsPlaceholderShown(false);
  };

  const wrapperClassNames = cx(
    theme['wrapper'],
    {
      [theme['has-focus']]: isFocused,
      [theme['has-error']]: error,
      [theme['has-success']]: success,
      [theme['has-warning']]: warning,
      [theme['has-placeholder']]: isPlaceholderShown,
    },
    className,
  );

  const inputClassNames = cx(theme['input'], inputClassName);

  const boxProps = pickBoxProps(others);

  return (
    <Box style={{ width, flex: width && '0 0 auto' }} {...boxProps}>
      <Editor
        toolbar={toolbar}
        wrapperClassName={wrapperClassNames}
        editorClassName={inputClassNames}
        toolbarClassName={theme['toolbar']}
        onFocus={handleFocus}
        onBlur={handleBlur}
        onContentStateChange={handleContentStateChange}
        customStyleMap={customStyleMap}
        customDecorators={[linkDecorator]}
        localization={
          availableLocales.includes(locale)
            ? {
                locale,
                translations: translations[locale],
              }
            : {
                locale: 'en',
                translations: translations['en'],
              }
        }
        {...others}
      />
      <ValidationText error={error} help={helpText} success={success} warning={warning} />
    </Box>
  );
};

WysiwygEditor.propTypes = {
  /** The text string/element to use as error message below the input. */
  error: PropTypes.oneOfType([PropTypes.bool, PropTypes.node]),
  /** The text string to use as help text below the input. */
  helpText: PropTypes.string,
  /** The text string/element to use as a prefix inside the input field */
  success: PropTypes.oneOfType([PropTypes.bool, PropTypes.node]),
  /** The text string/element to use as a suffix inside the input field */
  warning: PropTypes.oneOfType([PropTypes.bool, PropTypes.node]),
  /** A custom width for the editor field */
  width: PropTypes.string,
  /** Locale key for the language you want the editor to be displayed in. */
  locale: PropTypes.string,
  /** Classname for the WysiwygEditor's input element */
  inputClassName: PropTypes.string,
};

export default WysiwygEditor;
<|endoftext|>


<commit_before>function updateGraph(market) {
    var options = {
        lines: { show: true },
        points: {show: true },
        xaxis: { mode: "time" }
    };
    var data = [];
    var placeholder = $("#placeholder");

    //$.plot(placeholder, data, options);

    function fetchData() {
        function onDataReceived(stocks) {
            // plot each stock
            // we get all the data in one go, if we only got partial data
            // we could merge it with what we already have
            data = [];

            $.each(stocks, function(index, stock) {
                // add to current data

                data.push(stock);

                // plot!
                $.plot(placeholder, data, options);
            });
        }

        $.ajax({
            url: '/orders/' + market + '/',
            method: 'GET',
            dataType: 'json',
            success: onDataReceived
        });
    }

    setTimeout(fetchData, 1000);
};
<commit_msg>removed unnecessary function and initial 1 second delay from updateGraph<commit_after>function updateGraph(market) {
    var options = {
        lines: { show: true },
        points: {show: true },
        xaxis: { mode: "time" }
    };
    var data = [];
    var placeholder = $("#placeholder");

    //$.plot(placeholder, data, options);

    function onDataReceived(stocks) {
        // plot each stock
        // we get all the data in one go, if we only got partial data
        // we could merge it with what we already have
        data = [];

        $.each(stocks, function(index, stock) {
            // add to current data

            data.push(stock);

            // plot!
            $.plot(placeholder, data, options);
        });
    }

    $.ajax({
        url: '/orders/' + market + '/',
        method: 'GET',
        dataType: 'json',
        success: onDataReceived
    });
};
<|endoftext|>


<commit_before>/* @flow */
import React, { PureComponent } from 'react';
import { StyleSheet, View, TextInput } from 'react-native';
import isEqual from 'lodash.isequal';

import type {
  Auth,
  Narrow,
  EditMessage,
  InputSelectionType,
  User,
  Actions,
  Dimensions,
} from '../types';
import patchMessage from '../api/updateMessage';
import { FloatingActionButton, Input, MultilineInput } from '../common';
import { showErrorAlert } from '../common/errorAlert';
import { IconDone, IconSend } from '../common/Icons';
import { isStreamNarrow, topicNarrow } from '../utils/narrow';
import ComposeMenuContainer from './ComposeMenuContainer';
import AutoCompleteView from '../autocomplete/AutoCompleteView';
import getComposeInputPlaceholder from './getComposeInputPlaceholder';
import { registerUserInputActivity } from '../utils/activity';
import { replaceEmoticonsWithEmoji } from '../emoji/emoticons';
import NotSubscribed from '../message/NotSubscribed';

const MIN_HEIGHT = 46;
const MAX_HEIGHT = 100;

const componentStyles = StyleSheet.create({
  bottom: {
    flexDirection: 'column',
    justifyContent: 'flex-end',
  },
  composeText: {
    flex: 1,
    flexDirection: 'column',
  },
  topic: {
    height: 30,
    backgroundColor: 'rgba(127, 127, 127, 0.25)',
  },
  button: {
    margin: 5,
  },
});

type Props = {
  auth: Auth,
  canSend: boolean,
  narrow: Narrow,
  users: User[],
  draft: string,
  isSubscribed: boolean,
  editMessage: EditMessage,
  safeAreaInsets: Dimensions,
  actions: Actions,
  messageInputRef: (component: any) => void,
  onSend: () => void,
};

type State = {
  isMessageFocused: boolean,
  isTopicFocused: boolean,
  topic: string,
  message: string,
  height: number,
  selection: InputSelectionType,
};

export default class ComposeBox extends PureComponent<Props, State> {
  topicInput = null;
  messageInput = null;

  messageInput: TextInput;
  topicInput: TextInput;
  props: Props;

  static contextTypes = {
    styles: () => null,
  };

  state: State;

  state = {
    isMessageFocused: false,
    isTopicFocused: false,
    height: 46,
    topic: '',
    message: '',
    selection: { start: 0, end: 0 },
  };

  handleTopicChange = (topic: string) => {
    this.setState({ topic });
  };

  handleMessageChange = (message: string) => {
    this.setState({ message });
    const { auth } = this.props;
    registerUserInputActivity(auth);
  };

  handleMessageSelectionChange = (event: Object) => {
    const { selection } = event.nativeEvent;
    this.setState({ selection });
  };

  handleHeightChange = (height: number) => {
    this.setState({ height });
  };

  handleMessageFocus = () => {
    this.setState({ isMessageFocused: true });
  };

  handleMessageBlur = () => {
    setTimeout(() => {
      this.setState({ isMessageFocused: false });
    }, 200); // give a chance to the topic input to get the focus
  };

  handleTopicFocus = () => {
    this.setState({ isTopicFocused: true });
  };

  handleTopicBlur = () => {
    this.setState({ isTopicFocused: false });
  };

  clearMessageInput = () => {
    if (this.topicInput) {
      this.topicInput.clear();
    }
    if (this.messageInput) {
      this.messageInput.clear();
    }
    this.handleMessageChange('');
  };

  handleSend = () => {
    const { actions, narrow, onSend } = this.props;
    const { topic, message } = this.state;

    const topicToSend = replaceEmoticonsWithEmoji(topic);
    const messageToSend = replaceEmoticonsWithEmoji(message);
    const destinationNarrow = isStreamNarrow(narrow)
      ? topicNarrow(narrow[0].operand, topicToSend || '(no topic)')
      : narrow;

    actions.addToOutbox(destinationNarrow, messageToSend);

    this.clearMessageInput();
    onSend();
  };

  handleEdit = () => {
    const { auth, editMessage, actions } = this.props;
    const { message } = this.state;
    if (editMessage.content !== message) {
      patchMessage(auth, replaceEmoticonsWithEmoji(message), editMessage.id).catch(error =>
        showErrorAlert(error.message, 'Failed to edit message'),
      );
    }
    actions.cancelEditMessage();
  };

  handleAutoComplete = (input: string) => {
    this.setState({ message: input });
  };

  handleChangeText = (input: string) => {
    this.setState({ message: input });
  };

  tryUpdateDraft = () => {
    const { actions, draft, narrow } = this.props;
    const { message } = this.state;
    if (message !== '' && draft !== message) {
      actions.saveToDrafts(JSON.stringify(narrow), message);
    }
  };

  componentWillUnmount() {
    this.tryUpdateDraft();
  }

  componentWillMount() {
    const { draft } = this.props;
    if (draft) {
      this.setState({ message: draft });
    }
  }

  componentWillReceiveProps(nextProps: Props) {
    if (nextProps.editMessage !== this.props.editMessage) {
      this.setState({
        message: nextProps.editMessage ? nextProps.editMessage.content : '',
      });
      this.messageInput.focus();
    } else if (!isEqual(nextProps.narrow, this.props.narrow)) {
      this.tryUpdateDraft();

      if (nextProps.draft) {
        this.setState({ message: nextProps.draft });
      } else {
        this.clearMessageInput();
      }
    }
  }

  render() {
    const { styles } = this.context;
    const { isMessageFocused, isTopicFocused, height, message, selection, topic } = this.state;
    const {
      auth,
      canSend,
      narrow,
      users,
      editMessage,
      safeAreaInsets,
      messageInputRef,
      isSubscribed,
    } = this.props;

    if (!canSend) {
      return null;
    }

    if (!isSubscribed) {
      return <NotSubscribed />;
    }

    const canSelectTopic = (isMessageFocused || isTopicFocused) && isStreamNarrow(narrow);
    const messageHeight = Math.min(Math.max(MIN_HEIGHT, height), MAX_HEIGHT);
    const totalHeight = canSelectTopic ? messageHeight + 30 : messageHeight;
    const placeholder = getComposeInputPlaceholder(narrow, auth.email, users);

    return (
      <View>
        <AutoCompleteView
          text={message}
          onAutocomplete={this.handleAutoComplete}
          selection={selection}
        />
        <View
          style={[styles.composeBox, { height: totalHeight, marginBottom: safeAreaInsets.bottom }]}
        >
          <View style={componentStyles.bottom}>
            <ComposeMenuContainer />
          </View>
          <View style={[componentStyles.composeText]}>
            {canSelectTopic && (
              <Input
                style={[styles.composeTextInput, componentStyles.topic]}
                underlineColorAndroid="transparent"
                placeholder="Topic"
                textInputRef={component => {
                  this.topicInput = component;
                }}
                onChangeText={this.handleTopicChange}
                onFocus={this.handleTopicFocus}
                onBlur={this.handleTopicBlur}
                value={topic}
              />
            )}
            <MultilineInput
              style={[styles.composeTextInput, { height: messageHeight }]}
              placeholder={placeholder}
              textInputRef={component => {
                this.messageInput = component;
                if (component) messageInputRef(component);
              }}
              onChange={this.handleMessageChange}
              onFocus={this.handleMessageFocus}
              onBlur={this.handleMessageBlur}
              onHeightChange={this.handleHeightChange}
              onSelectionChange={this.handleMessageSelectionChange}
              value={message}
            />
          </View>
          <View style={componentStyles.bottom}>
            <FloatingActionButton
              style={componentStyles.button}
              Icon={editMessage === null ? IconSend : IconDone}
              size={32}
              disabled={message.length === 0}
              onPress={editMessage === null ? this.handleSend : this.handleEdit}
            />
          </View>
        </View>
      </View>
    );
  }
}
<commit_msg>Automatically set compose box topic (#1305)<commit_after>/* @flow */
import React, { PureComponent } from 'react';
import { StyleSheet, View, TextInput } from 'react-native';
import isEqual from 'lodash.isequal';

import type {
  Auth,
  Narrow,
  EditMessage,
  InputSelectionType,
  User,
  Actions,
  Dimensions,
} from '../types';
import patchMessage from '../api/updateMessage';
import { FloatingActionButton, Input, MultilineInput } from '../common';
import { showErrorAlert } from '../common/errorAlert';
import { IconDone, IconSend } from '../common/Icons';
import { isStreamNarrow, topicNarrow } from '../utils/narrow';
import ComposeMenuContainer from './ComposeMenuContainer';
import AutoCompleteView from '../autocomplete/AutoCompleteView';
import getComposeInputPlaceholder from './getComposeInputPlaceholder';
import { registerUserInputActivity } from '../utils/activity';
import { replaceEmoticonsWithEmoji } from '../emoji/emoticons';
import NotSubscribed from '../message/NotSubscribed';

const MIN_HEIGHT = 46;
const MAX_HEIGHT = 100;

const componentStyles = StyleSheet.create({
  bottom: {
    flexDirection: 'column',
    justifyContent: 'flex-end',
  },
  composeText: {
    flex: 1,
    flexDirection: 'column',
  },
  topic: {
    height: 30,
    backgroundColor: 'rgba(127, 127, 127, 0.25)',
  },
  button: {
    margin: 5,
  },
});

type Props = {
  auth: Auth,
  canSend: boolean,
  narrow: Narrow,
  users: User[],
  draft: string,
  isSubscribed: boolean,
  editMessage: EditMessage,
  safeAreaInsets: Dimensions,
  actions: Actions,
  messageInputRef: (component: any) => void,
  onSend: () => void,
};

type State = {
  isMessageFocused: boolean,
  isTopicFocused: boolean,
  topic: string,
  message: string,
  height: number,
  selection: InputSelectionType,
};

export default class ComposeBox extends PureComponent<Props, State> {
  topicInput = null;
  messageInput = null;

  messageInput: TextInput;
  topicInput: TextInput;
  props: Props;

  static contextTypes = {
    styles: () => null,
  };

  state: State;

  state = {
    isMessageFocused: false,
    isTopicFocused: false,
    height: 46,
    topic: '',
    message: '',
    selection: { start: 0, end: 0 },
  };

  handleTopicChange = (topic: string) => {
    this.setState({ topic });
  };

  handleMessageChange = (message: string) => {
    this.setState({ message });
    const { auth } = this.props;
    registerUserInputActivity(auth);
  };

  handleMessageSelectionChange = (event: Object) => {
    const { selection } = event.nativeEvent;
    this.setState({ selection });
  };

  handleHeightChange = (height: number) => {
    this.setState({ height });
  };

  handleMessageFocus = () => {
    this.setState({ isMessageFocused: true });
  };

  handleMessageBlur = () => {
    setTimeout(() => {
      this.setState({ isMessageFocused: false });
    }, 200); // give a chance to the topic input to get the focus
  };

  handleTopicFocus = () => {
    this.setState({ isTopicFocused: true });
  };

  handleTopicBlur = () => {
    setTimeout(() => {
      this.setState({ isTopicFocused: false });
    }, 200); // give a chance to the mesage input to get the focus
  };

  clearMessageInput = () => {
    if (this.topicInput) {
      this.topicInput.clear();
    }
    if (this.messageInput) {
      this.messageInput.clear();
    }
    this.handleMessageChange('');
  };

  handleSend = () => {
    const { actions, narrow, onSend } = this.props;
    const { topic, message } = this.state;

    const topicToSend = replaceEmoticonsWithEmoji(topic);
    const messageToSend = replaceEmoticonsWithEmoji(message);
    const destinationNarrow = isStreamNarrow(narrow)
      ? topicNarrow(narrow[0].operand, topicToSend || '(no topic)')
      : narrow;

    actions.addToOutbox(destinationNarrow, messageToSend);

    this.clearMessageInput();
    onSend();
  };

  handleEdit = () => {
    const { auth, editMessage, actions } = this.props;
    const { message } = this.state;
    if (editMessage.content !== message) {
      patchMessage(auth, replaceEmoticonsWithEmoji(message), editMessage.id).catch(error =>
        showErrorAlert(error.message, 'Failed to edit message'),
      );
    }
    actions.cancelEditMessage();
  };

  handleAutoComplete = (input: string) => {
    this.setState({ message: input });
  };

  handleChangeText = (input: string) => {
    this.setState({ message: input });
  };

  tryUpdateDraft = () => {
    const { actions, draft, narrow } = this.props;
    const { message } = this.state;
    if (message !== '' && draft !== message) {
      actions.saveToDrafts(JSON.stringify(narrow), message);
    }
  };

  componentWillUnmount() {
    this.tryUpdateDraft();
  }

  componentWillMount() {
    const { draft } = this.props;
    if (draft) {
      this.setState({ message: draft });
    }
  }

  componentWillReceiveProps(nextProps: Props) {
    if (nextProps.editMessage !== this.props.editMessage) {
      this.setState({
        message: nextProps.editMessage ? nextProps.editMessage.content : '',
      });
      this.messageInput.focus();
    } else if (!isEqual(nextProps.narrow, this.props.narrow)) {
      this.tryUpdateDraft();

      if (nextProps.draft) {
        this.setState({ message: nextProps.draft });
      } else {
        this.clearMessageInput();
      }
    }
  }

  render() {
    const { styles } = this.context;
    const { isMessageFocused, isTopicFocused, height, message, selection, topic } = this.state;
    const {
      auth,
      canSend,
      lastTopic,
      narrow,
      users,
      editMessage,
      safeAreaInsets,
      messageInputRef,
      isSubscribed,
    } = this.props;

    if (!canSend) {
      return null;
    }

    if (!isSubscribed) {
      return <NotSubscribed />;
    }

    const canSelectTopic = (isMessageFocused || isTopicFocused) && isStreamNarrow(narrow);
    const messageHeight = Math.min(Math.max(MIN_HEIGHT, height), MAX_HEIGHT);
    const totalHeight = canSelectTopic ? messageHeight + 30 : messageHeight;
    const placeholder = getComposeInputPlaceholder(narrow, auth.email, users);

    return (
      <View>
        <AutoCompleteView
          text={message}
          onAutocomplete={this.handleAutoComplete}
          selection={selection}
        />
        <View
          style={[styles.composeBox, { height: totalHeight, marginBottom: safeAreaInsets.bottom }]}
        >
          <View style={componentStyles.bottom}>
            <ComposeMenuContainer />
          </View>
          <View style={[componentStyles.composeText]}>
            {canSelectTopic && (
              <Input
                style={[styles.composeTextInput, componentStyles.topic]}
                underlineColorAndroid="transparent"
                placeholder="Topic"
                textInputRef={component => {
                  this.topicInput = component;
                }}
                onChangeText={this.handleTopicChange}
                onFocus={this.handleTopicFocus}
                onBlur={this.handleTopicBlur}
                defaultValue={lastTopic}
              />
            )}
            <MultilineInput
              style={[styles.composeTextInput, { height: messageHeight }]}
              placeholder={placeholder}
              textInputRef={component => {
                this.messageInput = component;
                if (component) messageInputRef(component);
              }}
              onChange={this.handleMessageChange}
              onFocus={this.handleMessageFocus}
              onBlur={this.handleMessageBlur}
              onHeightChange={this.handleHeightChange}
              onSelectionChange={this.handleMessageSelectionChange}
              value={message}
            />
          </View>
          <View style={componentStyles.bottom}>
            <FloatingActionButton
              style={componentStyles.button}
              Icon={editMessage === null ? IconSend : IconDone}
              size={32}
              disabled={message.length === 0}
              onPress={editMessage === null ? this.handleSend : this.handleEdit}
            />
          </View>
        </View>
      </View>
    );
  }
}
<|endoftext|>


<commit_before>import {SwapStrategies} from './swap-strategies';
import {ViewLocator} from './view-locator';
import {ViewEngine} from './view-engine';
import {HtmlBehaviorResource} from './html-behavior';
import {BehaviorInstruction, ViewCompileInstruction} from './instructions';
import {CompositionTransaction} from './composition-transaction';
import {DOM} from 'aurelia-pal';
import {Container, inject} from 'aurelia-dependency-injection';
import {metadata} from 'aurelia-metadata';
/**
* Instructs the composition engine how to dynamically compose a component.
*/
interface CompositionContext {
  /**
  * The parent Container for the component creation.
  */
  container: Container;
  /**
  * The child Container for the component creation. One will be created from the parent if not provided.
  */
  childContainer?: Container;
  /**
  * The context in which the view model is executed in.
  */
  bindingContext: any;
  /**
  * A secondary binding context that can override the standard context.
  */
  overrideContext?: any;
  /**
  * The view model url or instance for the component.
  */
  viewModel?: any;
  /**
  * Data to be passed to the "activate" hook on the view model.
  */
  model?: any;
  /**
  * The HtmlBehaviorResource for the component.
  */
  viewModelResource?: HtmlBehaviorResource;
  /**
  * The view resources for the view in which the component should be created.
  */
  viewResources: ViewResources;
  /**
  * The view inside which this composition is happening.
  */
  owningView?: View;
  /**
  * The view url or view strategy to override the default view location convention.
  */
  view?: string | ViewStrategy;
  /**
  * The slot to push the dynamically composed component into.
  */
  viewSlot: ViewSlot;
  /**
  * Should the composition system skip calling the "activate" hook on the view model.
  */
  skipActivation?: boolean;
}

function tryActivateViewModel(context) {
  if (context.skipActivation || typeof context.viewModel.activate !== 'function') {
    return Promise.resolve();
  }

  return context.viewModel.activate(context.model) || Promise.resolve();
}

/**
* Used to dynamically compose components.
*/
@inject(ViewEngine, ViewLocator)
export class CompositionEngine {
  /**
  * Creates an instance of the CompositionEngine.
  * @param viewEngine The ViewEngine used during composition.
  */
  constructor(viewEngine: ViewEngine, viewLocator: ViewLocator) {
    this.viewEngine = viewEngine;
    this.viewLocator = viewLocator;
  }

  _createControllerAndSwap(context) {
    function swap(controller) {
      let swapStrategy = SwapStrategies[context.swapOrder] || SwapStrategies.after;
      let previousViews = context.viewSlot.children.slice();

      return swapStrategy(context.viewSlot, previousViews, () => {
        return Promise.resolve(context.viewSlot.add(controller.view)).then(() => {
          if (context.currentController) {
            context.currentController.unbind();
          }
        });
      }).then(() => {
        if (context.compositionTransactionNotifier) {
          context.compositionTransactionNotifier.done();
        }

        return controller;
      });
    }

    return this.createController(context).then(controller => {
      controller.automate(context.overrideContext, context.owningView);

      if (context.compositionTransactionOwnershipToken) {
        return context.compositionTransactionOwnershipToken.waitForCompositionComplete().then(() => swap(controller));
      }

      return swap(controller);
    });
  }

  /**
  * Creates a controller instance for the component described in the context.
  * @param context The CompositionContext that describes the component.
  * @return A Promise for the Controller.
  */
  createController(context: CompositionContext): Promise<Controller> {
    let childContainer;
    let viewModel;
    let viewModelResource;
    let m;

    return this.ensureViewModel(context).then(tryActivateViewModel).then(() => {
      childContainer = context.childContainer;
      viewModel = context.viewModel;
      viewModelResource = context.viewModelResource;
      m = viewModelResource.metadata;

      let viewStrategy = this.viewLocator.getViewStrategy(context.view || viewModel);

      if (context.viewResources) {
        viewStrategy.makeRelativeTo(context.viewResources.viewUrl);
      }

      return m.load(childContainer, viewModelResource.value, null, viewStrategy, true);
    }).then(viewFactory => m.create(childContainer, BehaviorInstruction.dynamic(context.host, viewModel, viewFactory)));
  }

  /**
  * Ensures that the view model and its resource are loaded for this context.
  * @param context The CompositionContext to load the view model and its resource for.
  * @return A Promise for the context.
  */
  ensureViewModel(context: CompositionContext): Promise<CompositionContext> {
    let childContainer = context.childContainer = (context.childContainer || context.container.createChild());

    if (typeof context.viewModel === 'string') {
      context.viewModel = context.viewResources
          ? context.viewResources.relativeToView(context.viewModel)
          : context.viewModel;

      return this.viewEngine.importViewModelResource(context.viewModel).then(viewModelResource => {
        childContainer.autoRegister(viewModelResource.value);

        if (context.host) {
          childContainer.registerInstance(DOM.Element, context.host);
        }

        context.viewModel = childContainer.viewModel = childContainer.get(viewModelResource.value);
        context.viewModelResource = viewModelResource;
        return context;
      });
    }

    let m = metadata.getOrCreateOwn(metadata.resource, HtmlBehaviorResource, context.viewModel.constructor);
    m.elementName = m.elementName || 'dynamic-element';
    m.initialize(context.container || childContainer, context.viewModel.constructor);
    context.viewModelResource = { metadata: m, value: context.viewModel.constructor };
    childContainer.viewModel = context.viewModel;
    return Promise.resolve(context);
  }

  /**
  * Dynamically composes a component.
  * @param context The CompositionContext providing information on how the composition should occur.
  * @return A Promise for the View or the Controller that results from the dynamic composition.
  */
  compose(context: CompositionContext): Promise<View | Controller> {
    context.childContainer = context.childContainer || context.container.createChild();
    context.view = this.viewLocator.getViewStrategy(context.view);

    let transaction = context.childContainer.get(CompositionTransaction);
    let compositionTransactionOwnershipToken = transaction.tryCapture();

    if (compositionTransactionOwnershipToken) {
      context.compositionTransactionOwnershipToken = compositionTransactionOwnershipToken;
    } else {
      context.compositionTransactionNotifier = transaction.enlist();
    }

    if (context.viewModel) {
      return this._createControllerAndSwap(context);
    } else if (context.view) {
      if (context.viewResources) {
        context.view.makeRelativeTo(context.viewResources.viewUrl);
      }

      return context.view.loadViewFactory(this.viewEngine, new ViewCompileInstruction()).then(viewFactory => {
        let result = viewFactory.create(context.childContainer);
        result.bind(context.bindingContext, context.overrideContext);

        let work = () => {
          let swapStrategy = SwapStrategies[context.swapOrder] || SwapStrategies.after;
          let previousViews = context.viewSlot.children.slice();

          return swapStrategy(context.viewSlot, previousViews, () => {
            return Promise.resolve(context.viewSlot.add(controller.result)).then(() => {
              if (context.currentController) {
                context.currentController.unbind();
              }
            });
          }).then(() => {
            if (context.compositionTransactionNotifier) {
              context.compositionTransactionNotifier.done();
            }

            return result;
          });
        };

        if (context.compositionTransactionOwnershipToken) {
          return context.compositionTransactionOwnershipToken.waitForCompositionComplete().then(work);
        }

        return work();
      });
    } else if (context.viewSlot) {
      context.viewSlot.removeAll();

      if (context.compositionTransactionNotifier) {
        context.compositionTransactionNotifier.done();
      }

      return Promise.resolve(null);
    }

    return Promise.resolve(null);
  }
}
<commit_msg>resolve merge conflicts<commit_after>import {SwapStrategies} from './swap-strategies';
import {ViewLocator} from './view-locator';
import {ViewEngine} from './view-engine';
import {HtmlBehaviorResource} from './html-behavior';
import {BehaviorInstruction, ViewCompileInstruction} from './instructions';
import {CompositionTransaction} from './composition-transaction';
import {DOM} from 'aurelia-pal';
import {Container, inject} from 'aurelia-dependency-injection';
import {metadata} from 'aurelia-metadata';
/**
* Instructs the composition engine how to dynamically compose a component.
*/
interface CompositionContext {
  /**
  * The parent Container for the component creation.
  */
  container: Container;
  /**
  * The child Container for the component creation. One will be created from the parent if not provided.
  */
  childContainer?: Container;
  /**
  * The context in which the view model is executed in.
  */
  bindingContext: any;
  /**
  * A secondary binding context that can override the standard context.
  */
  overrideContext?: any;
  /**
  * The view model url or instance for the component.
  */
  viewModel?: any;
  /**
  * Data to be passed to the "activate" hook on the view model.
  */
  model?: any;
  /**
  * The HtmlBehaviorResource for the component.
  */
  viewModelResource?: HtmlBehaviorResource;
  /**
  * The view resources for the view in which the component should be created.
  */
  viewResources: ViewResources;
  /**
  * The view inside which this composition is happening.
  */
  owningView?: View;
  /**
  * The view url or view strategy to override the default view location convention.
  */
  view?: string | ViewStrategy;
  /**
  * The slot to push the dynamically composed component into.
  */
  viewSlot: ViewSlot;
  /**
  * Should the composition system skip calling the "activate" hook on the view model.
  */
  skipActivation?: boolean;
}

function tryActivateViewModel(context) {
  if (context.skipActivation || typeof context.viewModel.activate !== 'function') {
    return Promise.resolve();
  }

  return context.viewModel.activate(context.model) || Promise.resolve();
}

class SwapStrategies {
  // animate the next view in before removing the current view;
  before(viewSlot, previousView, callback) {
    let promise = Promise.resolve(callback());

    if (previousView !== undefined) {
      return promise.then(() => viewSlot.remove(previousView, true));
    }

    return promise;
  }

  // animate the next view at the same time the current view is removed
  with(viewSlot, previousView, callback) {
    let promise = Promise.resolve(callback());

    if (previousView !== undefined) {
      return Promise.all([viewSlot.remove(previousView, true), promise]);
    }

    return promise;
  }

  // animate the next view in after the current view has been removed
  after(viewSlot, previousView, callback) {
    return Promise.resolve(viewSlot.removeAll(true)).then(callback);
  }
}

const swapStrategies = new SwapStrategies();

/**
* Used to dynamically compose components.
*/
@inject(ViewEngine, ViewLocator)
export class CompositionEngine {
  /**
  * Creates an instance of the CompositionEngine.
  * @param viewEngine The ViewEngine used during composition.
  */
  constructor(viewEngine: ViewEngine, viewLocator: ViewLocator) {
    this.viewEngine = viewEngine;
    this.viewLocator = viewLocator;
  }

  _createControllerAndSwap(context) {
    function swap(controller) {
      let swapStrategy = SwapStrategies[context.swapOrder] || SwapStrategies.after;
      let previousViews = context.viewSlot.children.slice();

      return swapStrategy(context.viewSlot, previousViews, () => {
        return Promise.resolve(context.viewSlot.add(controller.view)).then(() => {
          if (context.currentController) {
            context.currentController.unbind();
          }
        });
      }).then(() => {
        if (context.compositionTransactionNotifier) {
          context.compositionTransactionNotifier.done();
        }

        return controller;
      });
    }

    return this.createController(context).then(controller => {
      controller.automate(context.overrideContext, context.owningView);

      if (context.compositionTransactionOwnershipToken) {
        return context.compositionTransactionOwnershipToken.waitForCompositionComplete().then(() => swap(controller));
      }

      return swap(controller);
    });
  }

  /**
  * Creates a controller instance for the component described in the context.
  * @param context The CompositionContext that describes the component.
  * @return A Promise for the Controller.
  */
  createController(context: CompositionContext): Promise<Controller> {
    let childContainer;
    let viewModel;
    let viewModelResource;
    let m;

    return this.ensureViewModel(context).then(tryActivateViewModel).then(() => {
      childContainer = context.childContainer;
      viewModel = context.viewModel;
      viewModelResource = context.viewModelResource;
      m = viewModelResource.metadata;

      let viewStrategy = this.viewLocator.getViewStrategy(context.view || viewModel);

      if (context.viewResources) {
        viewStrategy.makeRelativeTo(context.viewResources.viewUrl);
      }

      return m.load(childContainer, viewModelResource.value, null, viewStrategy, true);
    }).then(viewFactory => m.create(childContainer, BehaviorInstruction.dynamic(context.host, viewModel, viewFactory)));
  }

  /**
  * Ensures that the view model and its resource are loaded for this context.
  * @param context The CompositionContext to load the view model and its resource for.
  * @return A Promise for the context.
  */
  ensureViewModel(context: CompositionContext): Promise<CompositionContext> {
    let childContainer = context.childContainer = (context.childContainer || context.container.createChild());

    if (typeof context.viewModel === 'string') {
      context.viewModel = context.viewResources
          ? context.viewResources.relativeToView(context.viewModel)
          : context.viewModel;

      return this.viewEngine.importViewModelResource(context.viewModel).then(viewModelResource => {
        childContainer.autoRegister(viewModelResource.value);

        if (context.host) {
          childContainer.registerInstance(DOM.Element, context.host);
        }

        context.viewModel = childContainer.viewModel = childContainer.get(viewModelResource.value);
        context.viewModelResource = viewModelResource;
        return context;
      });
    }

    let m = metadata.getOrCreateOwn(metadata.resource, HtmlBehaviorResource, context.viewModel.constructor);
    m.elementName = m.elementName || 'dynamic-element';
    m.initialize(context.container || childContainer, context.viewModel.constructor);
    context.viewModelResource = { metadata: m, value: context.viewModel.constructor };
    childContainer.viewModel = context.viewModel;
    return Promise.resolve(context);
  }

  /**
  * Dynamically composes a component.
  * @param context The CompositionContext providing information on how the composition should occur.
  * @return A Promise for the View or the Controller that results from the dynamic composition.
  */
  compose(context: CompositionContext): Promise<View | Controller> {
    context.childContainer = context.childContainer || context.container.createChild();
    context.view = this.viewLocator.getViewStrategy(context.view);

    let transaction = context.childContainer.get(CompositionTransaction);
    let compositionTransactionOwnershipToken = transaction.tryCapture();

    if (compositionTransactionOwnershipToken) {
      context.compositionTransactionOwnershipToken = compositionTransactionOwnershipToken;
    } else {
      context.compositionTransactionNotifier = transaction.enlist();
    }

    if (context.viewModel) {
      return this._createControllerAndSwap(context);
    } else if (context.view) {
      if (context.viewResources) {
        context.view.makeRelativeTo(context.viewResources.viewUrl);
      }

      return context.view.loadViewFactory(this.viewEngine, new ViewCompileInstruction()).then(viewFactory => {
        let result = viewFactory.create(context.childContainer);
        result.bind(context.bindingContext, context.overrideContext);

        let work = () => {
          let swapStrategy = SwapStrategies[context.swapOrder] || SwapStrategies.after;
          let previousViews = context.viewSlot.children.slice();

          return swapStrategy(context.viewSlot, previousViews, () => {
            return Promise.resolve(context.viewSlot.add(controller.result)).then(() => {
              if (context.currentController) {
                context.currentController.unbind();
              }
            });
          }).then(() => {
            if (context.compositionTransactionNotifier) {
              context.compositionTransactionNotifier.done();
            }

            return result;
          });
        };

        if (context.compositionTransactionOwnershipToken) {
          return context.compositionTransactionOwnershipToken.waitForCompositionComplete().then(work);
        }

        return work();
      });
    } else if (context.viewSlot) {
      context.viewSlot.removeAll();

      if (context.compositionTransactionNotifier) {
        context.compositionTransactionNotifier.done();
      }

      return Promise.resolve(null);
    }

    return Promise.resolve(null);
  }
}
<|endoftext|>


<commit_before>/*
 * Note: In order for S3 to work, the following environment variables
 * must be set: http://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/loading-node-credentials-environment.html
 * AWS_ACCESS_KEY_ID
 * AWS_SECRET_ACCESS_KEY
 */

/* TODO:
 * Custom collections have a username prefix, e.g.: vanwars_images
 * Create /endpoints/ listing w/list of all collections in DB.
 */
var helpers = require("../lib/helpers");
var mongodb = require("mongodb");
var im = require('imagemagick');
var ObjectID = mongodb.ObjectID;
var thumbnailer = require("../lib/thumbnailer");
var fileHandler = require("../lib/fileHandler");

// SEE: http://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/loading-node-credentials-environment.html
var S3_BUCKET = process.env.AWS_S3_BUCKET,
    fs = require('fs'),
    AWS = require('aws-sdk'),
    fs = require('fs'),
    flow = require('flow');

exports.list = function (req, res) {
    'use strict';
    var COLLECTION = req.params.collection,
        query = req.params;
    req.handleError(res, req.params, req.params);
    console.log(req.params);
        /*fields = ['username', 'description', 'genre'],
        i,
        field,
        val;
    for (i = 0; i < fields.length; i++) {
        field = fields[i];
        val = req.query[field];
        if (val) {
            query[field] = val;
        }
    }
    if (req.params.username) {
        query.username = req.params.username;
    }*/
    req.db.collection(COLLECTION).find(query).toArray(function (err, docs) {
        if (err) {
            req.handleError(res, err.message, "Failed to get images.");
        } else {
            res.status(200).json(docs);
        }
    });
};

exports.post = function (req, res) {
    'use strict';
    var COLLECTION = req.params.collection,
        requiredFields = ['username'],
        isValid,
        newImage = req.body;
    // ensure if someone accidentally posts an _id, that it doesn't
    // interfere w/MongoDB's indexing system. Delete _id from dictionary:
    delete req.body._id;
    req.body.username = req.body.username || req.params.username;

    isValid = helpers.validateCreateUpdate(requiredFields, req, res);
    if (!isValid) {
        return;
    }
    flow.exec(
        // generate thumbnails and transfer to S3:
        function () {
            if (req.files && req.files.image) {
                thumbnailer.generateThumbnails({
                    req: req,
                    res: res,
                    image: req.files.image,
                    index: 0
                }, this);
            } else {
                this();
            }
        },
        // append thumbnail data to JSON object:
        function (images) {
            if (images) {
                newImage.image = {
                    items: images,
                    original_file_name: req.files.image.name
                };
            }
            this();
        },
        // transfer audio to S3:
        function () {
            if (req.files && req.files.audio) {
                fileHandler.transferFile({
                    req: req,
                    res: res,
                    file: req.files.audio
                }, this);
            } else {
                this();
            }
        },
        // append audio data to JSON object:
        function (audioData) {
            if (audioData) {
                newImage.audio = audioData;
            }
            this();
        },
        // transfer file to S3:
        function () {
            if (req.files && req.files.file) {
                fileHandler.transferFile({
                    req: req,
                    res: res,
                    file: req.files.file
                }, this);
            } else {
                this();
            }
        },
        // append file data data to JSON object:
        function (fileData) {
            if (fileData) {
                newImage.file = fileData;
            }
            this();
        },
        // finally, save to database:
        function () {
            newImage.createDate = new Date();
            //finally, insert a new record:
            req.db.collection(COLLECTION).insertOne(newImage, function (err, doc) {
                if (err) {
                    req.handleError(res, err.message, "Failed to create new resource.");
                } else {
                    var d = doc.ops[0];
                    d.message = 'Resource successfully created';
                    console.log(doc.ops[0]);
                    res.status(201).json(d);
                }
            });
        }
    );
};

exports.get = function (req, res) {
    'use strict';
    var COLLECTION = req.params.collection;
    req.db.collection(COLLECTION).findOne({ _id: new ObjectID(req.params.id) }, function (err, doc) {
        if (err) {
            req.handleError(res, err.message, "Failed to find the requested resource");
        } else {
            console.log("Retrieved one:", doc);
            res.status(200).json(doc);
        }
    });
};

exports.put = function (req, res) {
    'use strict';
    var COLLECTION = req.params.collection,
        updateDoc = req.body,
        d;
    delete updateDoc._id;

    req.db.collection(COLLECTION).updateOne({_id: new ObjectID(req.params.id)}, updateDoc, function (err, doc) {
        if (err) {
            req.handleError(res, err.message, "Failed to update resource");
        } else {
            console.log("UPDATED DOC:", d);
            d = doc;
            res.status(204).json(d);
        }
    });
};

exports.delete = function (req, res) {
    'use strict';
    var COLLECTION = req.params.collection;
    console.log(req.params.id, req.params.collection);
    flow.exec(
        function () {
            // get image from database:
            req.db.collection(COLLECTION).findOne({ _id: new ObjectID(req.params.id) }, this);
            //req.db.collection(COLLECTION).findOne({"_id" : new ObjectID("583e4736afabfc00104b9ace")}, this);
        },
        function (err, record) {
            // store image in local variable or throw error:
            if (err) {
                req.handleError(res, err.message, "Failed to delete the requested resource");
            } else if (!record) {
                req.handleError(res, null, "Failed to locate the requested resource");
            } else {
                console.log(record);
                //image = record;
                this(record);
            }
        },
        function (record) {
            if (record.image) {
                //remove thumbnails from S3
                thumbnailer.deleteThumbnails({
                    req: req,
                    res: res,
                    record: record,
                    index: 0
                }, this);
            } else {
                this(record);
            }
        },
        function (record) {
            if (record.audio) {
                //remove audio file from S3
                fileHandler.deleteFile({
                    req: req,
                    res: res,
                    key: record.audio.key,
                    record: record
                }, this);
            } else {
                this(record);
            }
        },
        function (record) {
            if (record.file) {
                //remove audio file from S3
                fileHandler.deleteFile({
                    req: req,
                    res: res,
                    key: record.file.key,
                    record: record
                }, this);
            } else {
                this(record);
            }
        },
        function () {
            req.db.collection(COLLECTION).deleteOne({_id: new ObjectID(req.params.id)}, function (err, result) {
                if (err) {
                    req.handleError(res, err.message, "Failed to delete the requested resource");
                } else {
                    res.status(204).json(result).end();
                }
            });
        }
    );
};

exports.deleteAll = function (req, res) {
    'use strict';
    var COLLECTION = req.params.collection;
    req.db.collection(COLLECTION).deleteMany({}, function (err, result) {
        if (err) {
            req.handleError(res, err.message, "Failed to delete the requested resource");
        } else {
            res.status(204).json(result).end();
        }
    });
};<commit_msg>updated query<commit_after>/*
 * Note: In order for S3 to work, the following environment variables
 * must be set: http://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/loading-node-credentials-environment.html
 * AWS_ACCESS_KEY_ID
 * AWS_SECRET_ACCESS_KEY
 */

/* TODO:
 * Custom collections have a username prefix, e.g.: vanwars_images
 * Create /endpoints/ listing w/list of all collections in DB.
 */
var helpers = require("../lib/helpers");
var mongodb = require("mongodb");
var im = require('imagemagick');
var ObjectID = mongodb.ObjectID;
var thumbnailer = require("../lib/thumbnailer");
var fileHandler = require("../lib/fileHandler");

// SEE: http://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/loading-node-credentials-environment.html
var S3_BUCKET = process.env.AWS_S3_BUCKET,
    fs = require('fs'),
    AWS = require('aws-sdk'),
    fs = require('fs'),
    flow = require('flow');

exports.list = function (req, res) {
    'use strict';
    var COLLECTION = req.params.collection,
        query = req.params;
    delete query.username;
    delete query.collection;
    //req.handleError(res, req.params, req.params);
    //console.log(req.params);
        /*fields = ['username', 'description', 'genre'],
        i,
        field,
        val;
    for (i = 0; i < fields.length; i++) {
        field = fields[i];
        val = req.query[field];
        if (val) {
            query[field] = val;
        }
    }
    if (req.params.username) {
        query.username = req.params.username;
    }*/
    req.db.collection(COLLECTION).find(query).toArray(function (err, docs) {
        if (err) {
            req.handleError(res, err.message, "Failed to get images.");
        } else {
            res.status(200).json(docs);
        }
    });
};

exports.post = function (req, res) {
    'use strict';
    var COLLECTION = req.params.collection,
        requiredFields = ['username'],
        isValid,
        newImage = req.body;
    // ensure if someone accidentally posts an _id, that it doesn't
    // interfere w/MongoDB's indexing system. Delete _id from dictionary:
    delete req.body._id;
    req.body.username = req.body.username || req.params.username;

    isValid = helpers.validateCreateUpdate(requiredFields, req, res);
    if (!isValid) {
        return;
    }
    flow.exec(
        // generate thumbnails and transfer to S3:
        function () {
            if (req.files && req.files.image) {
                thumbnailer.generateThumbnails({
                    req: req,
                    res: res,
                    image: req.files.image,
                    index: 0
                }, this);
            } else {
                this();
            }
        },
        // append thumbnail data to JSON object:
        function (images) {
            if (images) {
                newImage.image = {
                    items: images,
                    original_file_name: req.files.image.name
                };
            }
            this();
        },
        // transfer audio to S3:
        function () {
            if (req.files && req.files.audio) {
                fileHandler.transferFile({
                    req: req,
                    res: res,
                    file: req.files.audio
                }, this);
            } else {
                this();
            }
        },
        // append audio data to JSON object:
        function (audioData) {
            if (audioData) {
                newImage.audio = audioData;
            }
            this();
        },
        // transfer file to S3:
        function () {
            if (req.files && req.files.file) {
                fileHandler.transferFile({
                    req: req,
                    res: res,
                    file: req.files.file
                }, this);
            } else {
                this();
            }
        },
        // append file data data to JSON object:
        function (fileData) {
            if (fileData) {
                newImage.file = fileData;
            }
            this();
        },
        // finally, save to database:
        function () {
            newImage.createDate = new Date();
            //finally, insert a new record:
            req.db.collection(COLLECTION).insertOne(newImage, function (err, doc) {
                if (err) {
                    req.handleError(res, err.message, "Failed to create new resource.");
                } else {
                    var d = doc.ops[0];
                    d.message = 'Resource successfully created';
                    console.log(doc.ops[0]);
                    res.status(201).json(d);
                }
            });
        }
    );
};

exports.get = function (req, res) {
    'use strict';
    var COLLECTION = req.params.collection;
    req.db.collection(COLLECTION).findOne({ _id: new ObjectID(req.params.id) }, function (err, doc) {
        if (err) {
            req.handleError(res, err.message, "Failed to find the requested resource");
        } else {
            console.log("Retrieved one:", doc);
            res.status(200).json(doc);
        }
    });
};

exports.put = function (req, res) {
    'use strict';
    var COLLECTION = req.params.collection,
        updateDoc = req.body,
        d;
    delete updateDoc._id;

    req.db.collection(COLLECTION).updateOne({_id: new ObjectID(req.params.id)}, updateDoc, function (err, doc) {
        if (err) {
            req.handleError(res, err.message, "Failed to update resource");
        } else {
            console.log("UPDATED DOC:", d);
            d = doc;
            res.status(204).json(d);
        }
    });
};

exports.delete = function (req, res) {
    'use strict';
    var COLLECTION = req.params.collection;
    console.log(req.params.id, req.params.collection);
    flow.exec(
        function () {
            // get image from database:
            req.db.collection(COLLECTION).findOne({ _id: new ObjectID(req.params.id) }, this);
            //req.db.collection(COLLECTION).findOne({"_id" : new ObjectID("583e4736afabfc00104b9ace")}, this);
        },
        function (err, record) {
            // store image in local variable or throw error:
            if (err) {
                req.handleError(res, err.message, "Failed to delete the requested resource");
            } else if (!record) {
                req.handleError(res, null, "Failed to locate the requested resource");
            } else {
                console.log(record);
                //image = record;
                this(record);
            }
        },
        function (record) {
            if (record.image) {
                //remove thumbnails from S3
                thumbnailer.deleteThumbnails({
                    req: req,
                    res: res,
                    record: record,
                    index: 0
                }, this);
            } else {
                this(record);
            }
        },
        function (record) {
            if (record.audio) {
                //remove audio file from S3
                fileHandler.deleteFile({
                    req: req,
                    res: res,
                    key: record.audio.key,
                    record: record
                }, this);
            } else {
                this(record);
            }
        },
        function (record) {
            if (record.file) {
                //remove audio file from S3
                fileHandler.deleteFile({
                    req: req,
                    res: res,
                    key: record.file.key,
                    record: record
                }, this);
            } else {
                this(record);
            }
        },
        function () {
            req.db.collection(COLLECTION).deleteOne({_id: new ObjectID(req.params.id)}, function (err, result) {
                if (err) {
                    req.handleError(res, err.message, "Failed to delete the requested resource");
                } else {
                    res.status(204).json(result).end();
                }
            });
        }
    );
};

exports.deleteAll = function (req, res) {
    'use strict';
    var COLLECTION = req.params.collection;
    req.db.collection(COLLECTION).deleteMany({}, function (err, result) {
        if (err) {
            req.handleError(res, err.message, "Failed to delete the requested resource");
        } else {
            res.status(204).json(result).end();
        }
    });
};<|endoftext|>


<commit_before>
var Web3 = require('web3');
var web3 = new Web3();
var rpc_url = process.env.rpc_url;
var address = process.env.contract_address;

web3.setProvider(new web3.providers.HttpProvider(rpc_url));

var kycbit = {};

if(web3.isConnected()){
        var abi = [{"constant":true,"inputs":[{"name":"_hash","type":"bytes32"}],"name":"IntIDQuery","outputs":[{"name":"_intID","type":"string"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"HashToBIK","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"HashToIntID","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_hash","type":"bytes32"}],"name":"AddressQuery","outputs":[{"name":"_address","type":"address"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_BIK","type":"string"},{"name":"_hash","type":"bytes32"},{"name":"_intID","type":"string"}],"name":"CustomerInsert","outputs":[{"name":"result","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"isins","outputs":[{"name":"","type":"uint8"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_hash","type":"bytes32"}],"name":"BIKQuery","outputs":[{"name":"BIK","type":"string"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"HashToAddress","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"inputs":[],"type":"constructor","payable":true},{"payable":false,"type":"fallback"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"}],"name":"Insert","type":"event"}];

        var coinbase = web3.eth.coinbase;

        kycbit = web3.eth.contract(abi).at(address);

        web3.eth.defaultAccount = web3.eth.accounts[0];
}

module.exports.test = function(){
    if(!!kycbit){

        var result = kycbit.address;

        console.log("%j", result);

        return result;

    } else {
        console.log("Error connection");
    }

    return null;
}

<commit_msg>Add contract + 6<commit_after>
var Web3 = require('web3');
var web3 = new Web3();
var rpc_url = process.env.rpc_url;
var address = process.env.contract_address;

web3.setProvider(new web3.providers.HttpProvider(rpc_url));

var kycbit = {};

if(web3.isConnected()){
        var abi = [{"constant":true,"inputs":[{"name":"_hash","type":"bytes32"}],"name":"IntIDQuery","outputs":[{"name":"_intID","type":"string"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"HashToBIK","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"HashToIntID","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_hash","type":"bytes32"}],"name":"AddressQuery","outputs":[{"name":"_address","type":"address"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_BIK","type":"string"},{"name":"_hash","type":"bytes32"},{"name":"_intID","type":"string"}],"name":"CustomerInsert","outputs":[{"name":"result","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"isins","outputs":[{"name":"","type":"uint8"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_hash","type":"bytes32"}],"name":"BIKQuery","outputs":[{"name":"BIK","type":"string"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"HashToAddress","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"inputs":[],"type":"constructor","payable":true},{"payable":false,"type":"fallback"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"}],"name":"Insert","type":"event"}];

        var coinbase = web3.eth.coinbase;

        kycbit = web3.eth.contract(abi).at(address);

        web3.eth.defaultAccount = web3.eth.accounts[0];
}

module.exports.test = function(){
    if(!!kycbit){

        var result = kycbit.address;

        console.log("%j", result);

        return result;

    } else {
        console.log("Error connection");
    }

    return "Error";
}

<|endoftext|>


<commit_before>// @flow
import React from "react"
import { Helmet } from "react-helmet"
import { withRouter } from "react-router-dom"
import gql from "graphql-tag"
import { Query } from "react-apollo"
import Grid from "@material-ui/core/Grid"
import { withStyles } from "@material-ui/core/styles"
import StrainDetailsList from "./StrainDetailsList"
import StockDetailsHeader from "components/Stocks/DetailsPageItems/StockDetailsHeader"
import ShoppingButtons from "components/Stocks/DetailsPageItems/ShoppingButtons"
import StockDetailsLoader from "components/Stocks/DetailsPageItems/StockDetailsLoader"
// import PhenotypeTable from "components/Stocks/Strains/Phenotypes/PhenotypeTable"
import GraphQLErrorPage from "components/Errors/GraphQLErrorPage"
import characterConverter from "components/Stocks/utils/characterConverter"
import styles from "./strainStyles"

export const GET_STRAIN = gql`
  query Strain($id: ID!) {
    strain(id: $id) {
      id
      label
      summary
      species
      parent {
        id
        label
      }
      depositor
      plasmid
      dbxrefs
      publications {
        id
      }
      genes
      in_stock
    }
  }
`

/**
 * query will still need these from annotations:
 *       names
      systematic_name
      characteristics
      genetic_modification
      genotypes
      mutagenesis_method
      phenotypes {
        phenotype
        note
        assay
        environment
        publication {
          authors {
            last_name
          }
          id
          pub_date
          title
          journal
          volume
          pages
        }
      }
 */

type Props = {
  classes: Object,
  title: string,
  match: Object,
}

/**
 * StrainDetailsContainer is the main component for an individual strain details page.
 * It is responsible for fetching the data and passing it down to more specific components.
 */

export const StrainDetailsContainer = (props: Props) => {
  const { classes, match } = props
  let title

  return (
    <Query query={GET_STRAIN} variables={{ id: match.params.id }}>
      {({ loading, error, data }) => {
        if (loading) return <StockDetailsLoader />
        if (error) return <GraphQLErrorPage error={error} />

        const label = characterConverter(data.strain.label)

        // if (data.strain.phenotypes.length > 0) {
        //   title = `Phenotype and Strain Details for ${data.strain.label}`
        // } else {
        title = `Strain Details for ${label}`
        // }

        return (
          <Grid container spacing={2} className={classes.layout}>
            <Helmet>
              <title>{title} - Dicty Stock Center</title>
              <meta
                name="description"
                content={`Dicty Stock Center strain details page for ${label}`}
              />
            </Helmet>
            <Grid item xs={12}>
              <StockDetailsHeader title={title} />
            </Grid>
            <Grid item xs={12}>
              {/* {data.strain.phenotypes.length > 0 && (
                <PhenotypeTable data={data.strain.phenotypes} />
              )} */}
              <StrainDetailsList data={data.strain} />
              <ShoppingButtons
                type="strain"
                id={data.strain.id}
                name={data.strain.label}
                inStock={data.strain.in_stock}
              />
            </Grid>
          </Grid>
        )
      }}
    </Query>
  )
}

export default withRouter(withStyles(styles)(StrainDetailsContainer))
<commit_msg>feat: add systematic name in the graphql query<commit_after>// @flow
import React from "react"
import { Helmet } from "react-helmet"
import { withRouter } from "react-router-dom"
import gql from "graphql-tag"
import { Query } from "react-apollo"
import Grid from "@material-ui/core/Grid"
import { withStyles } from "@material-ui/core/styles"
import StrainDetailsList from "./StrainDetailsList"
import StockDetailsHeader from "components/Stocks/DetailsPageItems/StockDetailsHeader"
import ShoppingButtons from "components/Stocks/DetailsPageItems/ShoppingButtons"
import StockDetailsLoader from "components/Stocks/DetailsPageItems/StockDetailsLoader"
// import PhenotypeTable from "components/Stocks/Strains/Phenotypes/PhenotypeTable"
import GraphQLErrorPage from "components/Errors/GraphQLErrorPage"
import characterConverter from "components/Stocks/utils/characterConverter"
import styles from "./strainStyles"

export const GET_STRAIN = gql`
  query Strain($id: ID!) {
    strain(id: $id) {
      id
      label
      summary
      species
      parent {
        id
        label
      }
      depositor
      plasmid
      dbxrefs
      publications {
        id
      }
      genes
      in_stock
      systematic_name
    }
  }
`

/**
 * query will still need these from annotations:
 *       names
      systematic_name
      characteristics
      genetic_modification
      genotypes
      mutagenesis_method
      phenotypes {
        phenotype
        note
        assay
        environment
        publication {
          authors {
            last_name
          }
          id
          pub_date
          title
          journal
          volume
          pages
        }
      }
 */

type Props = {
  classes: Object,
  title: string,
  match: Object,
}

/**
 * StrainDetailsContainer is the main component for an individual strain details page.
 * It is responsible for fetching the data and passing it down to more specific components.
 */

export const StrainDetailsContainer = (props: Props) => {
  const { classes, match } = props
  let title

  return (
    <Query query={GET_STRAIN} variables={{ id: match.params.id }}>
      {({ loading, error, data }) => {
        if (loading) return <StockDetailsLoader />
        if (error) return <GraphQLErrorPage error={error} />

        const label = characterConverter(data.strain.label)

        // if (data.strain.phenotypes.length > 0) {
        //   title = `Phenotype and Strain Details for ${data.strain.label}`
        // } else {
        title = `Strain Details for ${label}`
        // }

        return (
          <Grid container spacing={2} className={classes.layout}>
            <Helmet>
              <title>{title} - Dicty Stock Center</title>
              <meta
                name="description"
                content={`Dicty Stock Center strain details page for ${label}`}
              />
            </Helmet>
            <Grid item xs={12}>
              <StockDetailsHeader title={title} />
            </Grid>
            <Grid item xs={12}>
              {/* {data.strain.phenotypes.length > 0 && (
                <PhenotypeTable data={data.strain.phenotypes} />
              )} */}
              <StrainDetailsList data={data.strain} />
              <ShoppingButtons
                type="strain"
                id={data.strain.id}
                name={data.strain.label}
                inStock={data.strain.in_stock}
              />
            </Grid>
          </Grid>
        )
      }}
    </Query>
  )
}

export default withRouter(withStyles(styles)(StrainDetailsContainer))
<|endoftext|>