<commit_before>import abagnale from 'abagnale/lib/abagnale';
import cloneDeep from 'lodash/cloneDeep';
import eidolon from 'eidolon';
import { EventEmitter } from 'fbemitter';
import isUndefined from 'lodash/isUndefined';
import isArray from 'lodash/isArray';
import isObject from 'lodash/isObject';
import map from 'lodash/map';
import merge from 'lodash/merge';
import React from 'react';
import reduce from 'lodash/reduce';

import Attribute from '../Attribute/Attribute';
import Title from '../Title/Title';

import { preprocess } from '../../Modules/Preprocessor/Preprocessor';
import { preprocessSamples } from '../../Modules/SamplesPreprocessor/SamplesPreprocessor';

import defaultTheme from '../../Resources/theme';

class Attributes extends React.Component {
  static propTypes = {
    namedTypes: React.PropTypes.bool,
    collapseByDefault: React.PropTypes.bool,
    dataStructures: React.PropTypes.array,
    element: React.PropTypes.object,
    includedProperties: React.PropTypes.oneOfType([
      React.PropTypes.bool,
      React.PropTypes.string,
    ]),
    inheritedProperties: React.PropTypes.oneOfType([
      React.PropTypes.bool,
      React.PropTypes.string,
    ]),
    maxInheritanceDepth: React.PropTypes.any,
    onElementLinkClick: React.PropTypes.func,
    title: React.PropTypes.oneOfType([
      React.PropTypes.bool,
      React.PropTypes.string,
    ]),
    theme: React.PropTypes.object,
  };

  static childContextTypes = {
    dereferencedDataStructures: React.PropTypes.array,
    theme: React.PropTypes.object,
    element: React.PropTypes.object,
    namedTypes: React.PropTypes.bool,
    eventEmitter: React.PropTypes.object,
    onElementLinkClick: React.PropTypes.func,
    includedProperties: React.PropTypes.oneOfType([
      React.PropTypes.bool,
      React.PropTypes.string,
    ]),
    inheritedProperties: React.PropTypes.oneOfType([
      React.PropTypes.bool,
      React.PropTypes.string,
    ]),
  };

  constructor(props) {
    super(props);
    this.state = this.transformPropsIntoState(this.props);
    this.eventEmitter = new EventEmitter();
  };

  getChildContext() {
    return {
      dereferencedDataStructures: this.state.dereferencedDataStructures,
      eventEmitter: this.eventEmitter,
      includedProperties: this.state.includedProperties,
      inheritedProperties: this.state.inheritedProperties,
      onElementLinkClick: this.state.onElementLinkClick,
      theme: this.state.theme,
      namedTypes: this.state.namedTypes,
      element: this.state.element,
    };
  };

  componentWillReceiveProps(nextProps) {
    this.setState(
      this.transformPropsIntoState(nextProps)
    );
  };

  alignKeys = () => {
    this.eventEmitter.emit('alignKeys');
  };

  transformPropsIntoState(props) {
    let theme;

    // Make a deep clone of the default theme object
    // to prevent future mutations; then we'll merge in custom theme.
    theme = cloneDeep(defaultTheme);
    theme = merge(theme, props.theme || {});

    // `dataStructures` prop is optional and is used to
    // resolve inheritance, references and includes/mixins, plus to
    // render the inheritance tree.
    const dataStructures = props.dataStructures || [];

    // We have to resolve all references, otherwise we wouldn't be able to
    // render the element. Dereferencing turns `{ element: 'MyObject', ... }`
    // into `{ element: 'object', ... }`, which is something Attributes Kit
    // understands.
    //
    // First, let's build index of the data structure elements in the following
    // format—`[dataStructure.meta.id]: dataStructureElement`, where
    // `dataStructure.meta.id` is name of the data structure.
    const dataStructuresIndex = props.dataStructuresIndex || (
      reduce(dataStructures, (result, dataStructure) => {
        if (typeof dataStructure.meta.id === 'object') {
          result[dataStructure.meta.id.content] = dataStructure;
        } else {
          result[dataStructure.meta.id] = dataStructure;
        }
        return result;
      }, {})
    );

    const dereferencedDataStructures = props.dereferencedDataStructures || (
      map(dataStructures, (dataStructure) =>
        eidolon.dereference(
          cloneDeep(dataStructure), dataStructuresIndex
        )
      )
    );

    // Set default value of `inheritedProperties` and `includedProperties` options.
    // If a user hasn't provided the values, we default to true (= we'll render
    // the whole data structure including inherited and included properties).
    //
    // Options `showInherited` and `showIncluded` have been deprecated and
    // will be removed in the 1.0 release.
    let inheritedProperties = props.inheritedProperties || props.showInherited;
    let includedProperties = props.includedProperties || props.showIncluded;

    if (isUndefined(inheritedProperties)) {
      inheritedProperties = true;
    }

    if (isUndefined(includedProperties)) {
      includedProperties = true;
    }

    let title;

    if (props.title === 'show') {
      title = true;
    } else if (props.title === 'hide') {
      title = false;
    } else {
      title = true;
    }

    const maxInheritanceDepth = props.maxInheritanceDepth || undefined;

    // Set default value of `collapseByDefault` option. If a user hasn't
    // provided the value, we default to false (= render
    // the whole data structure expanded).
    let collapseByDefault = props.collapseByDefault;

    if (isUndefined(collapseByDefault)) {
      collapseByDefault = false;
    }

    let namedTypes = props.namedTypes;

    if (isUndefined(namedTypes)) {
      namedTypes = false;
    }

    // Set up a dummy handler for element link clicks.
    let onElementLinkClick = props.onElementLinkClick;

    if (isUndefined(onElementLinkClick)) {
      onElementLinkClick = function defaultOnElementLinkClickHandler() {};
    }

    const originElement = this.addNestedLevels(
      cloneDeep(props.element)
    );

    // Dereference the element. This overwrites the original
    // value with the normalized result. Reference information
    // is still available in the `meta.ref` properties.
    const dereferencedElement = eidolon.dereference(
      originElement,
      dataStructuresIndex
    );

    const element = abagnale.forge([dereferencedElement], { separator: '.' })[0];

    preprocessSamples(element);
    preprocess(element);

    return {
      collapseByDefault,
      dereferencedDataStructures,
      element,
      includedProperties,
      inheritedProperties,
      maxInheritanceDepth,
      namedTypes,
      onElementLinkClick,
      theme,
      title,
    };
  };

  addNestedLevels(element, nestedLevel = -1) {
    if (!element) {
      return element;
    }

    if (!element.meta) {
      element.meta = {};
    }

    if (element.content && element.content.value) {
      nestedLevel = nestedLevel + 1;
    }

    element.meta._nestedLevel = nestedLevel;

    if (element.content && isArray(element.content)) {
      element.content = map(element.content, (nestedElement) =>
        this.addNestedLevels(nestedElement, nestedLevel)
      );
    } else if (element.content && isObject(element.content)) {
      element.content.value = this.addNestedLevels(
        element.content.value,
        nestedLevel
      );
    }

    return element;
  };

  render() {
    if (!this.props.element) {
      console.error(
        new Error(`
          Please provide the ‘element’ prop (‘<Attributes element="" />’)
          to the Attributes Kit.
        `)
      );

      return null;
    }

    return (

        {
          this.state.title &&
            <Title element={this.state.element} />
        }

        <Attribute
          element={this.state.element}
          theme={this.state.theme}
          collapseByDefault={this.state.collapseByDefault}
        />

    );
  };
}

export default Attributes;
<commit_msg>fix(Attributes): set default properties<commit_after>import abagnale from 'abagnale/lib/abagnale';
import cloneDeep from 'lodash/cloneDeep';
import eidolon from 'eidolon';
import { EventEmitter } from 'fbemitter';
import isUndefined from 'lodash/isUndefined';
import isArray from 'lodash/isArray';
import isObject from 'lodash/isObject';
import map from 'lodash/map';
import merge from 'lodash/merge';
import React from 'react';
import reduce from 'lodash/reduce';

import Attribute from '../Attribute/Attribute';
import Title from '../Title/Title';

import { preprocess } from '../../Modules/Preprocessor/Preprocessor';
import { preprocessSamples } from '../../Modules/SamplesPreprocessor/SamplesPreprocessor';

import defaultTheme from '../../Resources/theme';

class Attributes extends React.Component {
  static propTypes = {
    namedTypes: React.PropTypes.bool,
    collapseByDefault: React.PropTypes.bool,
    dataStructures: React.PropTypes.array,
    element: React.PropTypes.object,
    includedProperties: React.PropTypes.oneOfType([
      React.PropTypes.bool,
      React.PropTypes.string,
    ]),
    inheritedProperties: React.PropTypes.oneOfType([
      React.PropTypes.bool,
      React.PropTypes.string,
    ]),
    maxInheritanceDepth: React.PropTypes.any,
    onElementLinkClick: React.PropTypes.func,
    title: React.PropTypes.oneOfType([
      React.PropTypes.bool,
      React.PropTypes.string,
    ]),
    theme: React.PropTypes.object,
  };

  static defaultProps = {
    includedProperties: 'show',
    inheritedProperties: 'show',
  };

  static childContextTypes = {
    dereferencedDataStructures: React.PropTypes.array,
    theme: React.PropTypes.object,
    element: React.PropTypes.object,
    namedTypes: React.PropTypes.bool,
    eventEmitter: React.PropTypes.object,
    onElementLinkClick: React.PropTypes.func,
    includedProperties: React.PropTypes.oneOfType([
      React.PropTypes.bool,
      React.PropTypes.string,
    ]),
    inheritedProperties: React.PropTypes.oneOfType([
      React.PropTypes.bool,
      React.PropTypes.string,
    ]),
  };

  constructor(props) {
    super(props);
    this.state = this.transformPropsIntoState(this.props);
    this.eventEmitter = new EventEmitter();
  };

  getChildContext() {
    return {
      dereferencedDataStructures: this.state.dereferencedDataStructures,
      eventEmitter: this.eventEmitter,
      includedProperties: this.state.includedProperties,
      inheritedProperties: this.state.inheritedProperties,
      onElementLinkClick: this.state.onElementLinkClick,
      theme: this.state.theme,
      namedTypes: this.state.namedTypes,
      element: this.state.element,
    };
  };

  componentWillReceiveProps(nextProps) {
    this.setState(
      this.transformPropsIntoState(nextProps)
    );
  };

  alignKeys = () => {
    this.eventEmitter.emit('alignKeys');
  };

  transformPropsIntoState(props) {
    let theme;

    // Make a deep clone of the default theme object
    // to prevent future mutations; then we'll merge in custom theme.
    theme = cloneDeep(defaultTheme);
    theme = merge(theme, props.theme || {});

    // `dataStructures` prop is optional and is used to
    // resolve inheritance, references and includes/mixins, plus to
    // render the inheritance tree.
    const dataStructures = props.dataStructures || [];

    // We have to resolve all references, otherwise we wouldn't be able to
    // render the element. Dereferencing turns `{ element: 'MyObject', ... }`
    // into `{ element: 'object', ... }`, which is something Attributes Kit
    // understands.
    //
    // First, let's build index of the data structure elements in the following
    // format—`[dataStructure.meta.id]: dataStructureElement`, where
    // `dataStructure.meta.id` is name of the data structure.
    const dataStructuresIndex = props.dataStructuresIndex || (
      reduce(dataStructures, (result, dataStructure) => {
        if (typeof dataStructure.meta.id === 'object') {
          result[dataStructure.meta.id.content] = dataStructure;
        } else {
          result[dataStructure.meta.id] = dataStructure;
        }
        return result;
      }, {})
    );

    const dereferencedDataStructures = props.dereferencedDataStructures || (
      map(dataStructures, (dataStructure) =>
        eidolon.dereference(
          cloneDeep(dataStructure), dataStructuresIndex
        )
      )
    );

    // Set default value of `inheritedProperties` and `includedProperties` options.
    // If a user hasn't provided the values, we default to true (= we'll render
    // the whole data structure including inherited and included properties).
    //
    // Options `showInherited` and `showIncluded` have been deprecated and
    // will be removed in the 1.0 release.
    let inheritedProperties = props.inheritedProperties || props.showInherited;
    let includedProperties = props.includedProperties || props.showIncluded;

    if (isUndefined(inheritedProperties)) {
      inheritedProperties = true;
    }

    if (isUndefined(includedProperties)) {
      includedProperties = true;
    }

    let title;

    if (props.title === 'show') {
      title = true;
    } else if (props.title === 'hide') {
      title = false;
    } else {
      title = true;
    }

    const maxInheritanceDepth = props.maxInheritanceDepth || undefined;

    // Set default value of `collapseByDefault` option. If a user hasn't
    // provided the value, we default to false (= render
    // the whole data structure expanded).
    let collapseByDefault = props.collapseByDefault;

    if (isUndefined(collapseByDefault)) {
      collapseByDefault = false;
    }

    let namedTypes = props.namedTypes;

    if (isUndefined(namedTypes)) {
      namedTypes = false;
    }

    // Set up a dummy handler for element link clicks.
    let onElementLinkClick = props.onElementLinkClick;

    if (isUndefined(onElementLinkClick)) {
      onElementLinkClick = function defaultOnElementLinkClickHandler() {};
    }

    const originElement = this.addNestedLevels(
      cloneDeep(props.element)
    );

    // Dereference the element. This overwrites the original
    // value with the normalized result. Reference information
    // is still available in the `meta.ref` properties.
    const dereferencedElement = eidolon.dereference(
      originElement,
      dataStructuresIndex
    );

    const element = abagnale.forge([dereferencedElement], { separator: '.' })[0];

    preprocessSamples(element);
    preprocess(element);

    return {
      collapseByDefault,
      dereferencedDataStructures,
      element,
      includedProperties,
      inheritedProperties,
      maxInheritanceDepth,
      namedTypes,
      onElementLinkClick,
      theme,
      title,
    };
  };

  addNestedLevels(element, nestedLevel = -1) {
    if (!element) {
      return element;
    }

    if (!element.meta) {
      element.meta = {};
    }

    if (element.content && element.content.value) {
      nestedLevel = nestedLevel + 1;
    }

    element.meta._nestedLevel = nestedLevel;

    if (element.content && isArray(element.content)) {
      element.content = map(element.content, (nestedElement) =>
        this.addNestedLevels(nestedElement, nestedLevel)
      );
    } else if (element.content && isObject(element.content)) {
      element.content.value = this.addNestedLevels(
        element.content.value,
        nestedLevel
      );
    }

    return element;
  };

  render() {
    if (!this.props.element) {
      console.error(
        new Error(`
          Please provide the ‘element’ prop (‘<Attributes element="" />’)
          to the Attributes Kit.
        `)
      );

      return null;
    }

    return (

        {
          this.state.title &&
            <Title element={this.state.element} />
        }

        <Attribute
          element={this.state.element}
          theme={this.state.theme}
          collapseByDefault={this.state.collapseByDefault}
        />

    );
  };
}

export default Attributes;
<|endoftext|>


<commit_before>import React from "react"
import { renderToString } from "react-dom/server"
import { ServerRouter, createServerRenderContext } from "react-router"
import { CodeSplitProvider, createRenderContext } from "code-split-component"
import Helmet from "react-helmet"
import { ApolloProvider, getDataFromTree } from "react-apollo"

import renderPage from "./renderPage"
import { createApolloClient, createReduxStore } from "../common/Data"

/**
 * Using Apollo logic to recursively resolve all queries needed for
 * initial rendering. The convention is to use the full JSX tree,
 * traverse it and look for all occurrences of a static `fetchData() => Promise`
 * method which is being executed and waited for.
 *
 * See also:
 * https://www.npmjs.com/package/react-redux-universal-hot-example#server-side-data-fetching
 */
function renderToStringWithData(component) {
  var startLoading = process.hrtime()
  var nanoToMilli = 1000000
  return getDataFromTree(component).then(() => {
    var loadingRuntime = Math.round(process.hrtime(startLoading)[1] / nanoToMilli)

    var startRendering = process.hrtime()
    var result = renderToString(component)
    var renderingRuntime = Math.round(process.hrtime(startRendering)[1] / nanoToMilli)

    console.log(`Server: Loading: ${loadingRuntime}ms Rendering: ${renderingRuntime}ms`)
    return result
  })
}

// SSR is disabled so we will just return an empty html page and will
// rely on the client to populate the initial react application state.
function renderLight({ request, response, nonce, initialState }) {
  /* eslint-disable no-magic-numbers */
  try {
    const html = renderPage({
      // Provide the redux store state, this will be bound to the window.APP_STATE
      // so that we can rehydrate the state on the client.
      initialState,

      // Nonce which allows us to safely declare inline scripts.
      nonce
    })
    response.status(200).send(html)
  } catch (error) {
    response.status(500).send(`Error during rendering: ${error}!: ${error.stack}`)
  }
}

function renderFull({ request, response, nonce, AppContainer, apolloClient, reduxStore }) {
  // First create a context for <ServerRouter>, which will allow us to
  // query for the results of the render.
  const routingContext = createServerRenderContext()

  // We also create a context for our <CodeSplitProvider> which will allow us
  // to query which chunks/modules were used during the render process.
  const codeSplitContext = createRenderContext()

  console.log("Server: Rendering app with data...")

  // Create the application react element.
  renderToStringWithData(
    <CodeSplitProvider context={codeSplitContext}>
      <ServerRouter location={request.url} context={routingContext}>
        <ApolloProvider client={apolloClient} store={reduxStore}>
          <AppContainer/>
        </ApolloProvider>
      </ServerRouter>
    </CodeSplitProvider>
  ).then((renderedApp) => {
    const reduxState = reduxStore.getState()
    console.log("Server: Rendered state:", reduxState)

    // Render the app to a string.
    const html = renderPage({
      // Provide the full rendered App react element.
      renderedApp,

      // Provide the redux store state, this will be bound to the window.APP_STATE
      // so that we can rehydrate the state on the client.
      initialState: reduxState,

      // Nonce which allows us to safely declare inline scripts.
      nonce,

      // Running this gets all the helmet properties (e.g. headers/scripts/title etc)
      // that need to be included within our html. It's based on the rendered app.
      // @see https://github.com/nfl/react-helmet
      helmet: Helmet.rewind(),

      // We provide our code split state so that it can be included within the
      // html, and then the client bundle can use this data to know which chunks/
      // modules need to be rehydrated prior to the application being rendered.
      codeSplitState: codeSplitContext.getState()
    })

    // Get the render result from the server render context.
    const renderedResult = routingContext.getResult()

    console.log("Server: Sending page...")

    /* eslint-disable no-magic-numbers */

    // Check if the render result contains a redirect, if so we need to set
    // the specific status and redirect header and end the response.
    if (renderedResult.redirect) {
      response.status(301).setHeader("Location", renderedResult.redirect.pathname)
      response.end()
      return
    }

    // If the renderedResult contains a "missed" match then we set a 404 code.
    // Our App component will handle the rendering of an Error404 view.
    // Otherwise everything is all good and we send a 200 OK status.
    response.status(renderedResult.missed ? 404 : 200).send(html)
  }).catch((error) => {
    console.error("Error during producing response:", error)
  })
}

/**
 * An express middleware that is capable of doing React server side rendering.
 */
export default function createUniversalMiddleware({ AppContainer, ssrData, batchRequests = false, trustNetwork = true })
{
  return function middleware(request, response)
  {
    if (typeof response.locals.nonce !== "string") {
      throw new Error(`A "nonce" value has not been attached to the response`)
    }
    const nonce = response.locals.nonce

    // Pass object with all Server Side Rendering (SSR) related data to the client
    const initialState = {
      ssr: ssrData
    }

    if (process.env.DISABLE_SSR)
    {
      renderLight({ request, response, nonce, initialState })
    }
    else
    {
      const apolloClient = createApolloClient({
        headers: request.headers,
        initialState,
        batchRequests,
        trustNetwork
      })

      const reduxStore = createReduxStore({
        apolloClient,
        initialState,
        reducers: AppContainer.getReducers(),
        enhancers: AppContainer.getEnhancers(),
        middlewares: AppContainer.getMiddlewares()
      })

      renderFull({ request, response, nonce, AppContainer, apolloClient, reduxStore })
    }
  }
}
<commit_msg>Made less verbose<commit_after>import React from "react"
import { renderToString } from "react-dom/server"
import { ServerRouter, createServerRenderContext } from "react-router"
import { CodeSplitProvider, createRenderContext } from "code-split-component"
import Helmet from "react-helmet"
import { ApolloProvider, getDataFromTree } from "react-apollo"

import renderPage from "./renderPage"
import { createApolloClient, createReduxStore } from "../common/Data"

/**
 * Using Apollo logic to recursively resolve all queries needed for
 * initial rendering. The convention is to use the full JSX tree,
 * traverse it and look for all occurrences of a static `fetchData() => Promise`
 * method which is being executed and waited for.
 *
 * See also:
 * https://www.npmjs.com/package/react-redux-universal-hot-example#server-side-data-fetching
 */
function renderToStringWithData(component) {
  var startLoading = process.hrtime()
  var nanoToMilli = 1000000
  return getDataFromTree(component).then(() => {
    var loadingRuntime = Math.round(process.hrtime(startLoading)[1] / nanoToMilli)

    var startRendering = process.hrtime()
    var result = renderToString(component)
    var renderingRuntime = Math.round(process.hrtime(startRendering)[1] / nanoToMilli)

    console.log(`Server: Loading: ${loadingRuntime}ms Rendering: ${renderingRuntime}ms`)
    return result
  })
}

// SSR is disabled so we will just return an empty html page and will
// rely on the client to populate the initial react application state.
function renderLight({ request, response, nonce, initialState }) {
  /* eslint-disable no-magic-numbers */
  try {
    const html = renderPage({
      // Provide the redux store state, this will be bound to the window.APP_STATE
      // so that we can rehydrate the state on the client.
      initialState,

      // Nonce which allows us to safely declare inline scripts.
      nonce
    })
    response.status(200).send(html)
  } catch (error) {
    response.status(500).send(`Error during rendering: ${error}!: ${error.stack}`)
  }
}

function renderFull({ request, response, nonce, AppContainer, apolloClient, reduxStore }) {
  // First create a context for <ServerRouter>, which will allow us to
  // query for the results of the render.
  const routingContext = createServerRenderContext()

  // We also create a context for our <CodeSplitProvider> which will allow us
  // to query which chunks/modules were used during the render process.
  const codeSplitContext = createRenderContext()

  console.log("Server: Rendering app with data...")

  // Create the application react element.
  renderToStringWithData(
    <CodeSplitProvider context={codeSplitContext}>
      <ServerRouter location={request.url} context={routingContext}>
        <ApolloProvider client={apolloClient} store={reduxStore}>
          <AppContainer/>
        </ApolloProvider>
      </ServerRouter>
    </CodeSplitProvider>
  ).then((renderedApp) => {
    const reduxState = reduxStore.getState()
    // console.log("Server: Rendered state:", reduxState)

    // Render the app to a string.
    const html = renderPage({
      // Provide the full rendered App react element.
      renderedApp,

      // Provide the redux store state, this will be bound to the window.APP_STATE
      // so that we can rehydrate the state on the client.
      initialState: reduxState,

      // Nonce which allows us to safely declare inline scripts.
      nonce,

      // Running this gets all the helmet properties (e.g. headers/scripts/title etc)
      // that need to be included within our html. It's based on the rendered app.
      // @see https://github.com/nfl/react-helmet
      helmet: Helmet.rewind(),

      // We provide our code split state so that it can be included within the
      // html, and then the client bundle can use this data to know which chunks/
      // modules need to be rehydrated prior to the application being rendered.
      codeSplitState: codeSplitContext.getState()
    })

    // Get the render result from the server render context.
    const renderedResult = routingContext.getResult()

    console.log("Server: Sending page...")

    /* eslint-disable no-magic-numbers */

    // Check if the render result contains a redirect, if so we need to set
    // the specific status and redirect header and end the response.
    if (renderedResult.redirect) {
      response.status(301).setHeader("Location", renderedResult.redirect.pathname)
      response.end()
      return
    }

    // If the renderedResult contains a "missed" match then we set a 404 code.
    // Our App component will handle the rendering of an Error404 view.
    // Otherwise everything is all good and we send a 200 OK status.
    response.status(renderedResult.missed ? 404 : 200).send(html)
  }).catch((error) => {
    console.error("Error during producing response:", error)
  })
}

/**
 * An express middleware that is capable of doing React server side rendering.
 */
export default function createUniversalMiddleware({ AppContainer, ssrData, batchRequests = false, trustNetwork = true })
{
  return function middleware(request, response)
  {
    if (typeof response.locals.nonce !== "string") {
      throw new Error(`A "nonce" value has not been attached to the response`)
    }
    const nonce = response.locals.nonce

    // Pass object with all Server Side Rendering (SSR) related data to the client
    const initialState = {
      ssr: ssrData
    }

    if (process.env.DISABLE_SSR)
    {
      renderLight({ request, response, nonce, initialState })
    }
    else
    {
      const apolloClient = createApolloClient({
        headers: request.headers,
        initialState,
        batchRequests,
        trustNetwork
      })

      const reduxStore = createReduxStore({
        apolloClient,
        initialState,
        reducers: AppContainer.getReducers(),
        enhancers: AppContainer.getEnhancers(),
        middlewares: AppContainer.getMiddlewares()
      })

      renderFull({ request, response, nonce, AppContainer, apolloClient, reduxStore })
    }
  }
}
<|endoftext|>


<commit_before>/*
 * Screens.js - v0.9b
 * Copyright (C) 2013-2014 Andreu Santaren Llop
 */

// Init Screens.js library
{
    Array.prototype.last = function()
    {
        return this[this.length - 1];
    };

    Array.prototype.remove = function(index)
    {
        this.splice(index, 1);
    };

    window.BROADCAST_REGISTER_ARRAY = new Array();
    window.SCREEN_STACK = new Array();
}

// Create a class
function __CONTEXT_CLASS__(context, name, obj1, obj2)
{
    if (obj2 !== undefined)            // New class by heritance
    {
        if (typeof(obj1) !== "object")
        {
            throw "Extending from a non object";
        }

        // Clone the object
        var _asc_ = __CLONE__(obj1);

        // Get all element of obj and push it in _asc_
        for (var index in obj2)
        {
            var attr = obj2[index];
            _asc_[index] = attr;
        }

        // Init base properties
        _asc_.CLASS_TYPE.push(_asc_.CLASS_NAME);
        _asc_.CLASS_NAME = name;

        // Create the variable for the class
        context[name] = _asc_;
        return _asc_;
    }
    else                        // New base class
    {
        // Init base methods
        obj1.New = function()
        {
            var newObj = __CLONE__(this);

            delete newObj.New;

            newObj.OBJECT_UNIQUE_KEY = Math.floor(Math.random() * 10000000000000000).toString();

            // Call constructor
            newObj['Init'].apply(newObj, arguments);

            return newObj;
        };

        obj1.Super = function(elementName)
        {
            var superClass = this.CLASS_TYPE.last();

            if (superClass === "__CLASS__")
            {
                return null;
            }
            else
            {
                var object = __CLONE__(eval(superClass));

                if (elementName == null)
                {
                    return object;
                }

                for (var attr in object)
                {
                    if (attr === elementName)
                    {
                        if (typeof(object[attr]) === 'function')
                        {
                            return $.proxy(object[attr], this);
                        }
                        else
                        {
                            return null;
                        }
                    }
                }

                return null;
            }
        };

        if (!('Init' in obj1))
        {
            obj1.Init = function() {};
        }

        // Init base properties
        obj1.CLASS_TYPE = new Array("__CLASS__");
        obj1.CLASS_NAME = name;

        // Create the variable for the class
        context[name] = obj1;
        return obj1;
    }
}

// Create a class in the global context
function __CLASS__(name, obj1, obj2)
{
    return __CONTEXT_CLASS__(window, name, obj1, obj2);
}

// Base class
__CLASS__('Obj',
{
    Clone: function(obj)
    {
        return __CLONE__(obj);
    },

	Serialize: function(obj)
	{
		return __SERIALIZE__(obj);
	},

	Deserialize: function(obj)
	{
		return __DESERIALIZE__(obj);
	},

	Merge: function(org, dest)
	{
    	__MERGE__(org, dest);
	},

    Copy: function(org, dest)
	{
    	__COPY__(org, dest);
	},

    LoadClass: function(name, baseurl, readyCallBack)
    {
        return __LOAD_CLASS__(name, baseurl, this, readyCallBack);
    },

    UnloadClass: function(classname)
    {
        return __UNLOAD_CLASS__(classname);
    },

	RegisterReceiver: function(delegate, filter)
    {
        return __REGISTER_RECEIVER__(this, delegate, filter);
    },

    UnregisterReceiver: function(receiver)
    {
        __UNREGISTER_RECEIVER__(receiver);
    },

    SendOrderedBroadcast: function(filter, message)
    {
        __SEND_BROADCAST__(filter, message, false);
    },

    SendBroadcast: function(filter, message)
    {
        __SEND_BROADCAST__(filter, message, true);
    },

    SendMessage: function(filter, message)
    {
        return __SEND_MESSAGE__(filter, message);
    },

    FindReceiver: function(receiver)
    {
        return __FIND_RECEIVER__(receiver);
    }
});

// Base class for screens
__CLASS__('Screen', Obj,
{
    Selector: null,

    OnLoad: function()
    {},

    OnClose: function()
    {},

    OnReturn: function(retdata)
    {},

    CloseScreen: function(screen)
    {
        screen.OnClose();
    },

    PushScreen: function(selector, screen, sentdata, loader, args)
    {
        __PUSH_SCREEN__(selector, screen, sentdata, loader, args);
    },

    PopScreen: function(retdata, args)
    {
        __POP_SCREEN__(retdata, args);
    },

    SetScreen: function(selector, screen, sentdata)
    {
        return __SET_SCREEN__(selector, screen, sentdata);
    },

    UnsetScreen: function(selector, screenObj)
    {
        __UNSET_SCREEN__(selector, screenObj);
    },

    SetHtml: function(selector, html)
    {
	    __SET_HTML__(this, selector, html);
    },

    Brand: function(selector)
    {
	    __BRAND__(seletor, this);
    },

    Unbrand: function(selector)
    {
	    __UNBRAND__(selector);
    },

    Callback: function(callback)
    {
        return __CALLBACK__(this, callback);
    },

    Ref: function(selector)
    {
        return __REF__(this, selector);
    },

    Click: function(delegate, selector)
    {
        __CLICK__(this, delegate, selector);
    },

    DoubleClick: function(delegate, selector)
    {
        __DOUBLE_CLICK__(this, delegate, selector);
    },

    ListClick: function(delegate, selector)
    {
        __LIST_CLICK__(this, delegate, selector);
    },

    Change: function(delegate, selector)
    {
        __CHANGE__(this, delegate, selector);
    },

    CheckboxClick: function(delegate, selector)
    {
        __CHECKER_CLICK__(this, delegate, selector, 'checkbox');
    },

    RadioClick: function(delegate, selector)
    {
        __CHECKER_CLICK__(this, delegate, selector, 'radio');
    }
});

// Clone an object
function __CLONE__(obj)
{
   return __DESERIALIZE__(__SERIALIZE__(obj));
}

// Convert a class object to string
function __SERIALIZE__(obj)
{
    var fooArray = new Array();
    var attrArray = new Array();

    // Find all functions and convert to string
    for (var attr in obj)
    {
        if (typeof(obj[attr]) === 'function')
        {
            fooArray.push(obj[attr].toString());
            attrArray.push(attr);
        }
    }

    // Obtain a copy of the object (ignoring functions)
    var json = JSON.stringify(obj);
    var copy = JSON.parse(json);

    // Replace the original functions by the strings
    for (var i = 0 ; i < fooArray.length ; i++)
    {
        copy[attrArray[i]] = '(' + fooArray[i] + ')';
    }

    // Add an array for function names
    copy.OBJ_FOO_NAMES = attrArray;

    var serialized = JSON.stringify(copy);

    return serialized;
}

// Convert a string to a class object
function __DESERIALIZE__(obj)
{
    var copy = JSON.parse(obj);

    if (typeof(copy.OBJ_FOO_NAMES) !== 'object')
    {
        throw 'Not a valid serialized object';
    }

    // Take function string and evaluate to obtain the originals
    for (var i = 0 ; i < copy.OBJ_FOO_NAMES.length ; i++)
    {
        var fooStr = copy[copy.OBJ_FOO_NAMES[i]];
        copy[copy.OBJ_FOO_NAMES[i]] = eval('(' + fooStr + ')');
    }

    delete copy.OBJ_FOO_NAMES;

    return copy;
}

// Merge propierties of org object to dest object
function __MERGE__(org, dest)
{
    for (var attr in org)
    {
        if (attr != 'CLASS_NAME' && attr != 'CLASS_TYPE' && attr != '__proto__')
        {
            dest[attr] = org[attr];
        }
    }
}

// Copy propierties of org object to dest object
function __COPY__(org, dest)
{
    for (var attr in org)
    {
        if (attr != 'CLASS_NAME' && attr != 'CLASS_TYPE' && attr != '__proto__')
        {
            if (dest[attr] !== undefined)
            {
                dest[attr] = org[attr];
            }
        }
    }
}

function __PUSH_SCREEN__(selector, screen, sentdata, loader, args)
{
    var name = screen.CLASS_NAME;

    // Create an instance of screen class and save it in the stack
    var callname = name + '.New()';
    var screenObj = eval(callname);

    __BRAND__(selector, screenObj);

    if (loader != null)
    {
        loader(selector, args);     // execute loader callback
    }

    screenObj.Selector = selector;
    screenObj.OnLoad(sentdata);     // Screen OnLoad methode

    // Add screen to stack
    window.SCREEN_STACK.push({screen: screenObj, selector: selector, loader: loader});
}

function __POP_SCREEN__(retdata, args)
{
    // It is the main screen, no one in the back
    if (window.SCREEN_STACK.length <= 1)
    {
        return;
    }

    // Close the current screen
    var lastScreen = window.SCREEN_STACK.pop();
    lastScreen.screen.OnClose();

    // Get de previus screen object
    var stackObj = window.SCREEN_STACK.last();

    var pageSelector = stackObj.selector;
    var lastPageSelector = lastScreen.selector;

    // Disable all events
    $(lastPageSelector).add("*").off();

    __UNBRAND__(lastScreen.selector);

    if (stackObj.loader != null)
    {
        stackObj.loader(pageSelector, args);
    }

    stackObj.screen.OnLoad();      // Screen OnLoad methode

    // Call the return function
    if (retdata !== null)
    {
        stackObj.screen.OnReturn(retdata);
    }
}

// Set a Screen class to control a part of an existing page
function __SET_SCREEN__(selector, screen, sentdata)
{
    // Disable all events
    $(selector).find("*").off();

    // Create an instance of screen class and save it in the stack
    var screenObj = eval(screen.CLASS_NAME + '.New()');

    __BRAND__(selector, screenObj);

    screenObj.Selector = selector;
    screenObj.OnLoad(sentdata);     // Screen OnLoad methode

    return screenObj;
}

function __UNSET_SCREEN__(selector, screenObj)
{
    // Disable all events
    $(selector).add("*").off();

    __UNBRAND__(selector);

    screenObj.OnClose();
}

// Insert HTML in the DOM and update screen classes
function __SET_HTML__(screen, selector, html)
{
	__REF__(screen, selector).html(html);
    __BRAND__(selector, screen);
}

// Set the Screens brand for a piece of DOM
function __BRAND__(selector, screen)
{
	$(selector).attr('screensclass', screen.CLASS_NAME);
    $(selector).attr('screensid', screen.OBJECT_UNIQUE_KEY);
	$(selector).find('*').attr('screensclass', screen.CLASS_NAME);
    $(selector).find('*').attr('screensid', screen.OBJECT_UNIQUE_KEY);
}

// Remove the Screens brand
function __UNBRAND__(selector)
{
	$(selector).removeAttr('screensclass');
    $(selector).removeAttr('screensid');
	$(selector).find('*').removeAttr('screensclass');
    $(selector).find('*').removeAttr('screensid');
}

// Load a class
function __LOAD_CLASS__(name, baseurl, obj, readyCallBack)
{
    var jsurl = baseurl + "/" + name + ".js";

    if (typeof(window[name]) === 'undefined')
    {
        if (readyCallBack == null)
        {
            jQuery.ajaxSetup({async:false});

            // Load JavaScript class
            $.getScript(jsurl);

            jQuery.ajaxSetup({async:true});

            return true;
        }
        else
        {
            // Load JavaScript class
            $.getScript(jsurl, $.proxy(readyCallBack, obj));

            return true;
        }
    }
    else
    {
        // Class already loaded
        return false;
    }
}

function __UNLOAD_CLASS__(classname)
{
    if (typeof(classname) === 'string')
    {
        return delete window[classname];
    }
    else
    {
        return false;
    }
}

// Callback in the obj context setting the original 'this' as argument
function __CALLBACK__(obj, callback)
{
    return function(args)
    {
        return $.proxy(callback, obj)(this, args);
    };
}

// Get an element of a screen by a selector
function __REF__(obj, selector)
{
    return $(
    			"[screensclass='" + obj.CLASS_NAME + "']" +
    			"[screensid='" + obj.OBJECT_UNIQUE_KEY + "']" +
    			selector
    		);
}

// Set click event delegate
function __CLICK__(obj, delegate, selector)
{
    __REF__(obj, selector).click(__CALLBACK__(obj, delegate));
}

// Set double click event delegate
function __DOUBLE_CLICK__(obj, delegate, selector)
{
    __REF__(obj, selector).dblclick(__CALLBACK__(obj, delegate));
}

// Set list click event delegate
function __LIST_CLICK__(obj, delegate, selector)
{
    __REF__(obj, selector).on('click', 'li', __CALLBACK__(obj, delegate));
}

// Element changed delegate
function __CHANGE__(obj, delegate, selector)
{
    __REF__(obj, selector).on('change', __CALLBACK__(obj, delegate));
}

// Set checkbox/radio click event delegate
function __CHECKER_CLICK__(obj, delegate, selector, type)
{
	__REF__(obj, selector).find('input[type=' + type + ']').on('click', __CALLBACK__(obj, delegate));
}

// Register a broadcast receiver
function __REGISTER_RECEIVER__(obj, delegate, filter)
{
    var broadcastObj = {callback: $.proxy(delegate, obj), filter: filter, id: Math.random()};
    window.BROADCAST_REGISTER_ARRAY.push(broadcastObj);

    return broadcastObj.id;
}

// Unregister a broadcast receiver
function __UNREGISTER_RECEIVER__(receiver)
{
    for (var i = 0 ; i < window.BROADCAST_REGISTER_ARRAY.length ; i++)
    {
        if (window.BROADCAST_REGISTER_ARRAY[i].id === receiver)
        {
            window.BROADCAST_REGISTER_ARRAY.remove(i);
            return;
        }
    }
}

// Send broadcast message
function __SEND_BROADCAST__(filter, message, massive)
{
    // Make a copy of the array to avoid problems when others change it
    var arrCopy = window.BROADCAST_REGISTER_ARRAY.slice();

    for (var i = 0 ; i < arrCopy.length ; i++)
    {
        if (arrCopy[i].filter === filter)
        {
            if (massive)
            {
                arrCopy[i].callback(message);
            }
            else
            {
                // If ordered broadcast and callback returns true, halt broadcast
                if (arrCopy[i].callback(message)) return;
            }
        }
    }
}

// Send message and return result
function __SEND_MESSAGE__(filter, message)
{
    // Make a copy of the array to avoid problems when others change it
    var arrCopy = window.BROADCAST_REGISTER_ARRAY.slice();

    for (var i = 0 ; i < arrCopy.length ; i++)
    {
        if (arrCopy[i].filter === filter)
        {
            // Execute the first ocurrence of 'filter' and return the result
            return arrCopy[i].callback(message);
        }
    }

    return null;
}

// Return the receiver object for a certain receiver id
function __FIND_RECEIVER__(receiver)
{
    for (var i = 0 ; i < window.BROADCAST_REGISTER_ARRAY.length ; i++)
    {
        if (window.BROADCAST_REGISTER_ARRAY[i].id === receiver)
        {
            return window.BROADCAST_REGISTER_ARRAY[i];
        }
    }
}
<commit_msg>Version 1.0 stable.<commit_after>/*
 * Screens.js - v1.0
 * Copyright (C) 2013-2014 Andreu Santaren Llop
 */

// Init Screens.js library
{
    Array.prototype.last = function()
    {
        return this[this.length - 1];
    };

    Array.prototype.remove = function(index)
    {
        this.splice(index, 1);
    };

    window.BROADCAST_REGISTER_ARRAY = new Array();
    window.SCREEN_STACK = new Array();
}

// Create a class
function __CONTEXT_CLASS__(context, name, obj1, obj2)
{
    if (obj2 !== undefined)            // New class by heritance
    {
        if (typeof(obj1) !== "object")
        {
            throw "Extending from a non object";
        }

        // Clone the object
        var _asc_ = __CLONE__(obj1);

        // Get all element of obj and push it in _asc_
        for (var index in obj2)
        {
            var attr = obj2[index];
            _asc_[index] = attr;
        }

        // Init base properties
        _asc_.CLASS_TYPE.push(_asc_.CLASS_NAME);
        _asc_.CLASS_NAME = name;

        // Create the variable for the class
        context[name] = _asc_;
        return _asc_;
    }
    else                        // New base class
    {
        // Init base methods
        obj1.New = function()
        {
            var newObj = __CLONE__(this);

            delete newObj.New;

            newObj.OBJECT_UNIQUE_KEY = Math.floor(Math.random() * 10000000000000000).toString();

            // Call constructor
            newObj['Init'].apply(newObj, arguments);

            return newObj;
        };

        obj1.Super = function(elementName)
        {
            var superClass = this.CLASS_TYPE.last();

            if (superClass === "__CLASS__")
            {
                return null;
            }
            else
            {
                var object = __CLONE__(eval(superClass));

                if (elementName == null)
                {
                    return object;
                }

                for (var attr in object)
                {
                    if (attr === elementName)
                    {
                        if (typeof(object[attr]) === 'function')
                        {
                            return $.proxy(object[attr], this);
                        }
                        else
                        {
                            return null;
                        }
                    }
                }

                return null;
            }
        };

        if (!('Init' in obj1))
        {
            obj1.Init = function() {};
        }

        // Init base properties
        obj1.CLASS_TYPE = new Array("__CLASS__");
        obj1.CLASS_NAME = name;

        // Create the variable for the class
        context[name] = obj1;
        return obj1;
    }
}

// Create a class in the global context
function __CLASS__(name, obj1, obj2)
{
    return __CONTEXT_CLASS__(window, name, obj1, obj2);
}

// Base class
__CLASS__('Obj',
{
    Clone: function(obj)
    {
        return __CLONE__(obj);
    },

	Serialize: function(obj)
	{
		return __SERIALIZE__(obj);
	},

	Deserialize: function(obj)
	{
		return __DESERIALIZE__(obj);
	},

	Merge: function(org, dest)
	{
    	__MERGE__(org, dest);
	},

    Copy: function(org, dest)
	{
    	__COPY__(org, dest);
	},

    LoadClass: function(name, baseurl, readyCallBack)
    {
        return __LOAD_CLASS__(name, baseurl, this, readyCallBack);
    },

    UnloadClass: function(classname)
    {
        return __UNLOAD_CLASS__(classname);
    },

	RegisterReceiver: function(delegate, filter)
    {
        return __REGISTER_RECEIVER__(this, delegate, filter);
    },

    UnregisterReceiver: function(receiver)
    {
        __UNREGISTER_RECEIVER__(receiver);
    },

    SendOrderedBroadcast: function(filter, message)
    {
        __SEND_BROADCAST__(filter, message, false);
    },

    SendBroadcast: function(filter, message)
    {
        __SEND_BROADCAST__(filter, message, true);
    },

    SendMessage: function(filter, message)
    {
        return __SEND_MESSAGE__(filter, message);
    },

    FindReceiver: function(receiver)
    {
        return __FIND_RECEIVER__(receiver);
    }
});

// Base class for screens
__CLASS__('Screen', Obj,
{
    Selector: null,

    OnLoad: function()
    {},

    OnClose: function()
    {},

    OnReturn: function(retdata)
    {},

    CloseScreen: function(screen)
    {
        screen.OnClose();
    },

    PushScreen: function(selector, screen, sentdata, loader, args)
    {
        __PUSH_SCREEN__(selector, screen, sentdata, loader, args);
    },

    PopScreen: function(retdata, args)
    {
        __POP_SCREEN__(retdata, args);
    },

    SetScreen: function(selector, screen, sentdata)
    {
        return __SET_SCREEN__(selector, screen, sentdata);
    },

    UnsetScreen: function(selector, screenObj)
    {
        __UNSET_SCREEN__(selector, screenObj);
    },

    SetHtml: function(selector, html)
    {
	    __SET_HTML__(this, selector, html);
    },

    Brand: function(selector)
    {
	    __BRAND__(seletor, this);
    },

    Unbrand: function(selector)
    {
	    __UNBRAND__(selector);
    },

    Callback: function(callback)
    {
        return __CALLBACK__(this, callback);
    },

    Ref: function(selector)
    {
        return __REF__(this, selector);
    },

    Click: function(delegate, selector)
    {
        __CLICK__(this, delegate, selector);
    },

    DoubleClick: function(delegate, selector)
    {
        __DOUBLE_CLICK__(this, delegate, selector);
    },

    ListClick: function(delegate, selector)
    {
        __LIST_CLICK__(this, delegate, selector);
    },

    Change: function(delegate, selector)
    {
        __CHANGE__(this, delegate, selector);
    },

    CheckboxClick: function(delegate, selector)
    {
        __CHECKER_CLICK__(this, delegate, selector, 'checkbox');
    },

    RadioClick: function(delegate, selector)
    {
        __CHECKER_CLICK__(this, delegate, selector, 'radio');
    }
});

// Clone an object
function __CLONE__(obj)
{
   return __DESERIALIZE__(__SERIALIZE__(obj));
}

// Convert a class object to string
function __SERIALIZE__(obj)
{
    var fooArray = new Array();
    var attrArray = new Array();

    // Find all functions and convert to string
    for (var attr in obj)
    {
        if (typeof(obj[attr]) === 'function')
        {
            fooArray.push(obj[attr].toString());
            attrArray.push(attr);
        }
    }

    // Obtain a copy of the object (ignoring functions)
    var json = JSON.stringify(obj);
    var copy = JSON.parse(json);

    // Replace the original functions by the strings
    for (var i = 0 ; i < fooArray.length ; i++)
    {
        copy[attrArray[i]] = '(' + fooArray[i] + ')';
    }

    // Add an array for function names
    copy.OBJ_FOO_NAMES = attrArray;

    var serialized = JSON.stringify(copy);

    return serialized;
}

// Convert a string to a class object
function __DESERIALIZE__(obj)
{
    var copy = JSON.parse(obj);

    if (typeof(copy.OBJ_FOO_NAMES) !== 'object')
    {
        throw 'Not a valid serialized object';
    }

    // Take function string and evaluate to obtain the originals
    for (var i = 0 ; i < copy.OBJ_FOO_NAMES.length ; i++)
    {
        var fooStr = copy[copy.OBJ_FOO_NAMES[i]];
        copy[copy.OBJ_FOO_NAMES[i]] = eval('(' + fooStr + ')');
    }

    delete copy.OBJ_FOO_NAMES;

    return copy;
}

// Merge propierties of org object to dest object
function __MERGE__(org, dest)
{
    for (var attr in org)
    {
        if (attr != 'CLASS_NAME' && attr != 'CLASS_TYPE' && attr != '__proto__')
        {
            dest[attr] = org[attr];
        }
    }
}

// Copy propierties of org object to dest object
function __COPY__(org, dest)
{
    for (var attr in org)
    {
        if (attr != 'CLASS_NAME' && attr != 'CLASS_TYPE' && attr != '__proto__')
        {
            if (dest[attr] !== undefined)
            {
                dest[attr] = org[attr];
            }
        }
    }
}

function __PUSH_SCREEN__(selector, screen, sentdata, loader, args)
{
    var name = screen.CLASS_NAME;

    // Create an instance of screen class and save it in the stack
    var callname = name + '.New()';
    var screenObj = eval(callname);

    __BRAND__(selector, screenObj);

    if (loader != null)
    {
        loader(selector, args);     // execute loader callback
    }

    screenObj.Selector = selector;
    screenObj.OnLoad(sentdata);     // Screen OnLoad methode

    // Add screen to stack
    window.SCREEN_STACK.push({screen: screenObj, selector: selector, loader: loader});
}

function __POP_SCREEN__(retdata, args)
{
    // It is the main screen, no one in the back
    if (window.SCREEN_STACK.length <= 1)
    {
        return;
    }

    // Close the current screen
    var lastScreen = window.SCREEN_STACK.pop();
    lastScreen.screen.OnClose();

    // Get de previus screen object
    var stackObj = window.SCREEN_STACK.last();

    var pageSelector = stackObj.selector;
    var lastPageSelector = lastScreen.selector;

    // Disable all events
    $(lastPageSelector).add("*").off();

    __UNBRAND__(lastScreen.selector);

    if (stackObj.loader != null)
    {
        stackObj.loader(pageSelector, args);
    }

    stackObj.screen.OnLoad();      // Screen OnLoad methode

    // Call the return function
    if (retdata !== null)
    {
        stackObj.screen.OnReturn(retdata);
    }
}

// Set a Screen class to control a part of an existing page
function __SET_SCREEN__(selector, screen, sentdata)
{
    // Disable all events
    $(selector).find("*").off();

    // Create an instance of screen class and save it in the stack
    var screenObj = eval(screen.CLASS_NAME + '.New()');

    __BRAND__(selector, screenObj);

    screenObj.Selector = selector;
    screenObj.OnLoad(sentdata);     // Screen OnLoad methode

    return screenObj;
}

function __UNSET_SCREEN__(selector, screenObj)
{
    // Disable all events
    $(selector).add("*").off();

    __UNBRAND__(selector);

    screenObj.OnClose();
}

// Insert HTML in the DOM and update screen classes
function __SET_HTML__(screen, selector, html)
{
	__REF__(screen, selector).html(html);
    __BRAND__(selector, screen);
}

// Set the Screens brand for a piece of DOM
function __BRAND__(selector, screen)
{
	$(selector).attr('screensclass', screen.CLASS_NAME);
    $(selector).attr('screensid', screen.OBJECT_UNIQUE_KEY);
	$(selector).find('*').attr('screensclass', screen.CLASS_NAME);
    $(selector).find('*').attr('screensid', screen.OBJECT_UNIQUE_KEY);
}

// Remove the Screens brand
function __UNBRAND__(selector)
{
	$(selector).removeAttr('screensclass');
    $(selector).removeAttr('screensid');
	$(selector).find('*').removeAttr('screensclass');
    $(selector).find('*').removeAttr('screensid');
}

// Load a class
function __LOAD_CLASS__(name, baseurl, obj, readyCallBack)
{
    var jsurl = baseurl + "/" + name + ".js";

    if (typeof(window[name]) === 'undefined')
    {
        if (readyCallBack == null)
        {
            jQuery.ajaxSetup({async:false});

            // Load JavaScript class
            $.getScript(jsurl);

            jQuery.ajaxSetup({async:true});

            return true;
        }
        else
        {
            // Load JavaScript class
            $.getScript(jsurl, $.proxy(readyCallBack, obj));

            return true;
        }
    }
    else
    {
        // Class already loaded
        return false;
    }
}

function __UNLOAD_CLASS__(classname)
{
    if (typeof(classname) === 'string')
    {
        return delete window[classname];
    }
    else
    {
        return false;
    }
}

// Callback in the obj context setting the original 'this' as argument
function __CALLBACK__(obj, callback)
{
    return function(args)
    {
        return $.proxy(callback, obj)(this, args);
    };
}

// Get an element of a screen by a selector
function __REF__(obj, selector)
{
    return $(
    			"[screensclass='" + obj.CLASS_NAME + "']" +
    			"[screensid='" + obj.OBJECT_UNIQUE_KEY + "']" +
    			selector
    		);
}

// Set click event delegate
function __CLICK__(obj, delegate, selector)
{
    __REF__(obj, selector).click(__CALLBACK__(obj, delegate));
}

// Set double click event delegate
function __DOUBLE_CLICK__(obj, delegate, selector)
{
    __REF__(obj, selector).dblclick(__CALLBACK__(obj, delegate));
}

// Set list click event delegate
function __LIST_CLICK__(obj, delegate, selector)
{
    __REF__(obj, selector).on('click', 'li', __CALLBACK__(obj, delegate));
}

// Element changed delegate
function __CHANGE__(obj, delegate, selector)
{
    __REF__(obj, selector).on('change', __CALLBACK__(obj, delegate));
}

// Set checkbox/radio click event delegate
function __CHECKER_CLICK__(obj, delegate, selector, type)
{
	__REF__(obj, selector).find('input[type=' + type + ']').on('click', __CALLBACK__(obj, delegate));
}

// Register a broadcast receiver
function __REGISTER_RECEIVER__(obj, delegate, filter)
{
    var broadcastObj = {callback: $.proxy(delegate, obj), filter: filter, id: Math.random()};
    window.BROADCAST_REGISTER_ARRAY.push(broadcastObj);

    return broadcastObj.id;
}

// Unregister a broadcast receiver
function __UNREGISTER_RECEIVER__(receiver)
{
    for (var i = 0 ; i < window.BROADCAST_REGISTER_ARRAY.length ; i++)
    {
        if (window.BROADCAST_REGISTER_ARRAY[i].id === receiver)
        {
            window.BROADCAST_REGISTER_ARRAY.remove(i);
            return;
        }
    }
}

// Send broadcast message
function __SEND_BROADCAST__(filter, message, massive)
{
    // Make a copy of the array to avoid problems when others change it
    var arrCopy = window.BROADCAST_REGISTER_ARRAY.slice();

    for (var i = 0 ; i < arrCopy.length ; i++)
    {
        if (arrCopy[i].filter === filter)
        {
            if (massive)
            {
                arrCopy[i].callback(message);
            }
            else
            {
                // If ordered broadcast and callback returns true, halt broadcast
                if (arrCopy[i].callback(message)) return;
            }
        }
    }
}

// Send message and return result
function __SEND_MESSAGE__(filter, message)
{
    // Make a copy of the array to avoid problems when others change it
    var arrCopy = window.BROADCAST_REGISTER_ARRAY.slice();

    for (var i = 0 ; i < arrCopy.length ; i++)
    {
        if (arrCopy[i].filter === filter)
        {
            // Execute the first ocurrence of 'filter' and return the result
            return arrCopy[i].callback(message);
        }
    }

    return null;
}

// Return the receiver object for a certain receiver id
function __FIND_RECEIVER__(receiver)
{
    for (var i = 0 ; i < window.BROADCAST_REGISTER_ARRAY.length ; i++)
    {
        if (window.BROADCAST_REGISTER_ARRAY[i].id === receiver)
        {
            return window.BROADCAST_REGISTER_ARRAY[i];
        }
    }
}
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import {default_order, default_order_diff} from "../demo_data";
import SortableReact from '../../SortableReact';
import Markdown from 'react-markdown';

const code = `
\`\`\`js
<SortableReact
  sortable_mode={sortable_mode}
  stiffness={95}
  damping={20}
  delta={30}
  scale_active={0.8}
  shadow_active={1.4}
  order=[
    {id: "1", w:2, h:2, col:1, row:1, con: "1",
    style:{background:"url(im1.jpg) no-repeat", backgroundSize:"cover", color: "white", fontSize:10}},
    ...]
/>
\`\`\`
`

const text = `
  # Item with image
  ${code}
`

class  StoreItemWithImage extends Component {
  constructor(props) {
    super(props)
    this.state = {mode: "left_right"};
    console.log("state::::", this.state)
    // let new_order = []
    // const default_order_diff2 = default_order_diff.clone()
    // default_order_diff2.forEach((item)=>{
    //   item.style = {background:"url(favicon.ico) no-repeat", backgroundSize:"100%", color: "white", fontSize:40}
    //   new_order.push(item)
    // })
    this.new_order = [
      {id: "1", w:2, h:2, col:1, row:1, con: "1", style:{background:"url(im1.jpg) no-repeat", backgroundSize:"cover", color: "white", fontSize:10}},
      {id: "2", w:1, h:1, col:3, row:1, con: "2", style:{background:"url(im2.jpg) no-repeat", backgroundSize:"cover", color: "white", fontSize:10}},
      // {id: "3", w:2, h:2, col:3, row:1, con: "3"},
      {id: "11", w:1, h:1, col:3, row:2, con: "11", style:{background:"url(im3.jpg) no-repeat", backgroundSize:"cover", color: "white", fontSize:10}},
      // {id: "12", w:1, h:1, col:2, row:2, con: "12"},
      {id: "21", w:1, h:1, col:1, row:3, con: "21", style:{background:"url(im4.jpg) no-repeat", backgroundSize:"cover", color: "white", fontSize:10}},
      {id: "22", w:1, h:1, col:2, row:3, con: "22", style:{background:"url(im5.jpg) no-repeat", backgroundSize:"cover", color: "white", fontSize:10}},
      {id: "23", w:1, h:1, col:3, row:3, con: "23", style:{background:"url(im6.jpg) no-repeat", backgroundSize:"cover", color: "white", fontSize:10}},
      // {id: "24", w:1, h:1, col:4, row:3, con: "24"},
    ]

  }

  onState(e){
    console.log("onState:", e.target.value)
    this.setState({"mode": e.target.value})
  }

  render(){
    // console.log("this.props.mode;;", this.props)
    const mode = this.state.mode
    return (

        <Markdown source={text}/>
        sortable_mode:
        <select style={{width:200, "marginLeft":20}} onChange={this.onState.bind(this)}>
          <option value="left_right">left_right</option>
          <option value="swap">swap</option>
        </select>
        <SortableReact
          sortable_mode={mode}
          stiffness={95}
          damping={20}
          delta={30}
          scale_active={0.8}
          shadow_active={1.4}
          order={this.new_order }
        />

    )
  }
}

export default StoreItemWithImage;
<commit_msg>add button on item with image demo<commit_after>import React, { Component } from 'react';
import {default_order, default_order_diff} from "../demo_data";
import SortableReact from '../../SortableReact';
import Markdown from 'react-markdown';

const code = `
\`\`\`js
<SortableReact
  sortable_mode={sortable_mode}
  stiffness={95}
  damping={20}
  delta={30}
  scale_active={0.8}
  shadow_active={1.4}
  order=[
    {
      id: "1", w:2, h:2, col:1, row:1,
      con: (
x
),
      style:{background:"url(im1.jpg) no-repeat", backgroundSize:"cover", color: "white", fontSize:10}
    },
    ...]
/>
\`\`\`
`

const text = `
  # Item with image
  ${code}
`

const style_item = { cursor:"pointer", lineHeight:1.5, "float": "right", paddingRight:10, color:"black"}

class  StoreItemWithImage extends Component {
  constructor(props) {
    super(props)
    this.state = {mode: "left_right"};
    console.log("state::::", this.state)
    // let new_order = []
    // const default_order_diff2 = default_order_diff.clone()
    // default_order_diff2.forEach((item)=>{
    //   item.style = {background:"url(favicon.ico) no-repeat", backgroundSize:"100%", color: "white", fontSize:40}
    //   new_order.push(item)
    // })
    this.new_order = [
      {id: "1", w:2, h:2, col:1, row:1, con: (
x
), style:{overflow:"hidden", background:"url(im1.jpg) no-repeat", backgroundSize:"cover", color: "white", fontSize:15}},
      {id: "2", w:1, h:1, col:3, row:1, con: (
x
), style:{background:"url(im2.jpg) no-repeat", backgroundSize:"cover", color: "white", fontSize:15}},
      // {id: "3", w:2, h:2, col:3, row:1, con: "3"},
      {id: "11", w:1, h:1, col:3, row:2, con: (
x
), style:{background:"url(im3.jpg) no-repeat", backgroundSize:"cover", color: "white", fontSize:15}},
      // {id: "12", w:1, h:1, col:2, row:2, con: "12"},
      {id: "21", w:1, h:1, col:1, row:3, con: (
x
), style:{background:"url(im4.jpg) no-repeat", backgroundSize:"cover", color: "white", fontSize:15}},
      {id: "22", w:1, h:1, col:2, row:3, con: (
x
), style:{background:"url(im5.jpg) no-repeat", backgroundSize:"cover", color: "white", fontSize:15}},
      {id: "23", w:1, h:1, col:3, row:3, con: (
x
), style:{background:"url(im6.jpg) no-repeat", backgroundSize:"cover", color: "white", fontSize:15}},
      // {id: "24", w:1, h:1, col:4, row:3, con: "24"},
    ]

  }

  onClick(e){
    console.log("e",String(e.target.id))
    alert("click: "+ String(e.target.id))
  }

  onState(e){
    console.log("onState:", e.target.value)
    this.setState({"mode": e.target.value})
  }

  render(){
    // console.log("this.props.mode;;", this.props)
    const mode = this.state.mode
    return (

        <Markdown source={text}/>
        sortable_mode:
        <select style={{width:200, "marginLeft":20}} onChange={this.onState.bind(this)}>
          <option value="left_right">left_right</option>
          <option value="swap">swap</option>
        </select>
        <SortableReact
          sortable_mode={mode}
          stiffness={95}
          damping={20}
          delta={30}
          scale_active={0.8}
          shadow_active={1.4}
          order={this.new_order }
        />

    )
  }
}

export default StoreItemWithImage;
<|endoftext|>


<commit_before>const gcm = require('node-gcm');

const method = 'gcm';

const sendChunk = (GCMSender, registrationTokens, message, retries) => new Promise((resolve) => {
    GCMSender.send(message, { registrationTokens }, retries, (err, response) => {
        // Response: see https://developers.google.com/cloud-messaging/http-server-ref#table5
        if (err) {
            resolve({
                method,
                success: 0,
                failure: registrationTokens.length,
                message: registrationTokens.map(value => ({
                    regId: value,
                    error: err,
                })),
            });
        } else if (response && response.results !== undefined) {
            var regIndex = 0;
            resolve({
                method,
                multicastId: response.multicast_id,
                success: response.success,
                failure: response.failure,
                message: response.results.map(value => {
                    var regToken = registrationTokens[regIndex];
                    regIndex++;
                    return {
                    messageId: value.message_id,
                    regId: value.registration_id || regToken,
                    error: value.error ? new Error(value.error) : null,
                    };
                }
                ),
            });
        } else {
            resolve({
                method,
                multicastId: response.multicast_id,
                success: response.success,
                failure: response.failure,
                message: registrationTokens.map(value => ({
                    regId: value,
                    error: new Error('unknown'),
                })),
            });
        }
    });
});

module.exports = (regIds, data, settings) => {
    const opts = Object.assign({}, settings.gcm);
    const id = opts.id;
    delete opts.id;
    const GCMSender = new gcm.Sender(id, opts);
    const promises = [];
    const notification = {
        title: data.title, // Android, iOS (Watch)
        body: data.body, // Android, iOS
        icon: data.icon, // Android
        sound: data.sound, // Android, iOS
        badge: data.badge, // iOS
        tag: data.tag, // Android
        color: data.color, // Android
        click_action: data.clickAction || data.category, // Android, iOS
        body_loc_key: data.locKey, // Android, iOS
        body_loc_args: data.locArgs, // Android, iOS
        title_loc_key: data.titleLocKey, // Android, iOS
        title_loc_args: data.titleLocArgs, // Android, iOS
    };

    let custom;
    if (typeof data.custom === 'string') {
        custom = {
            message: data.custom,
        };
    } else if (typeof data.custom === 'object') {
        custom = Object.assign({}, data.custom);
    } else {
        custom = {
            data: data.custom,
        };
    }

    custom.title = custom.title || data.title || '';
    custom.message = custom.message || data.body || '';
    custom.sound = custom.sound || data.sound || undefined;
    custom.icon = custom.icon || data.icon || undefined;
    custom.msgcnt = custom.msgcnt || data.badge || undefined;
    if (opts.phonegap === true && data.contentAvailable) {
        custom['content-available'] = 1;
    }

    const message = new gcm.Message({ // See https://developers.google.com/cloud-messaging/http-server-ref#table5
        collapseKey: data.collapseKey,
        priority: data.priority === 'normal' ? data.priority : 'high',
        contentAvailable: data.contentAvailable || false,
        delayWhileIdle: data.delayWhileIdle || false,
        timeToLive: data.expiry - Math.floor(Date.now() / 1000) || data.timeToLive || 28 * 86400,
        restrictedPackageName: data.restrictedPackageName,
        dryRun: data.dryRun || false,
        data: opts.phonegap === true ? Object.assign(custom, notification) : custom, // See https://github.com/phonegap/phonegap-plugin-push/blob/master/docs/PAYLOAD.md#android-behaviour
        notification: opts.phonegap === true ? undefined : notification,
    });
    let chunk = 0;

    // Split in 1.000 chunks, see https://developers.google.com/cloud-messaging/http-server-ref#table1
    do {
        const tokens = regIds.slice(chunk * 1000, (chunk + 1) * 1000);
        promises.push(sendChunk(GCMSender, tokens, message, data.retries || 0));
        chunk += 1;
    } while (1000 * chunk < regIds.length);

    return Promise.all(promises)
        .then((results) => {
            const resumed = {
                method,
                multicastId: [],
                success: 0,
                failure: 0,
                message: [],
            };
            for (const result of results) {
                if (result.multicastId) {
                    resumed.multicastId.push(result.multicastId);
                }
                resumed.success += result.success;
                resumed.failure += result.failure;
                resumed.message = [...resumed.message, ...result.message];
            }
            return resumed;
        });
};
<commit_msg>Follow Eslint<commit_after>const gcm = require('node-gcm');

const method = 'gcm';

const sendChunk = (GCMSender, registrationTokens, message, retries) => new Promise((resolve) => {
    GCMSender.send(message, { registrationTokens }, retries, (err, response) => {
        // Response: see https://developers.google.com/cloud-messaging/http-server-ref#table5
        if (err) {
            resolve({
                method,
                success: 0,
                failure: registrationTokens.length,
                message: registrationTokens.map(value => ({
                    regId: value,
                    error: err,
                })),
            });
        } else if (response && response.results !== undefined) {
            let regIndex = 0;
            resolve({
                method,
                multicastId: response.multicast_id,
                success: response.success,
                failure: response.failure,
                message: response.results.map((value) => {
                    const regToken = registrationTokens[regIndex];
                    regIndex += 1;
                    return {
                        messageId: value.message_id,
                        regId: value.registration_id || regToken,
                        error: value.error ? new Error(value.error) : null,
                    };
                }
                ),
            });
        } else {
            resolve({
                method,
                multicastId: response.multicast_id,
                success: response.success,
                failure: response.failure,
                message: registrationTokens.map(value => ({
                    regId: value,
                    error: new Error('unknown'),
                })),
            });
        }
    });
});

module.exports = (regIds, data, settings) => {
    const opts = Object.assign({}, settings.gcm);
    const id = opts.id;
    delete opts.id;
    const GCMSender = new gcm.Sender(id, opts);
    const promises = [];
    const notification = {
        title: data.title, // Android, iOS (Watch)
        body: data.body, // Android, iOS
        icon: data.icon, // Android
        sound: data.sound, // Android, iOS
        badge: data.badge, // iOS
        tag: data.tag, // Android
        color: data.color, // Android
        click_action: data.clickAction || data.category, // Android, iOS
        body_loc_key: data.locKey, // Android, iOS
        body_loc_args: data.locArgs, // Android, iOS
        title_loc_key: data.titleLocKey, // Android, iOS
        title_loc_args: data.titleLocArgs, // Android, iOS
    };

    let custom;
    if (typeof data.custom === 'string') {
        custom = {
            message: data.custom,
        };
    } else if (typeof data.custom === 'object') {
        custom = Object.assign({}, data.custom);
    } else {
        custom = {
            data: data.custom,
        };
    }

    custom.title = custom.title || data.title || '';
    custom.message = custom.message || data.body || '';
    custom.sound = custom.sound || data.sound || undefined;
    custom.icon = custom.icon || data.icon || undefined;
    custom.msgcnt = custom.msgcnt || data.badge || undefined;
    if (opts.phonegap === true && data.contentAvailable) {
        custom['content-available'] = 1;
    }

    const message = new gcm.Message({ // See https://developers.google.com/cloud-messaging/http-server-ref#table5
        collapseKey: data.collapseKey,
        priority: data.priority === 'normal' ? data.priority : 'high',
        contentAvailable: data.contentAvailable || false,
        delayWhileIdle: data.delayWhileIdle || false,
        timeToLive: data.expiry - Math.floor(Date.now() / 1000) || data.timeToLive || 28 * 86400,
        restrictedPackageName: data.restrictedPackageName,
        dryRun: data.dryRun || false,
        data: opts.phonegap === true ? Object.assign(custom, notification) : custom, // See https://github.com/phonegap/phonegap-plugin-push/blob/master/docs/PAYLOAD.md#android-behaviour
        notification: opts.phonegap === true ? undefined : notification,
    });
    let chunk = 0;

    // Split in 1.000 chunks, see https://developers.google.com/cloud-messaging/http-server-ref#table1
    do {
        const tokens = regIds.slice(chunk * 1000, (chunk + 1) * 1000);
        promises.push(sendChunk(GCMSender, tokens, message, data.retries || 0));
        chunk += 1;
    } while (1000 * chunk < regIds.length);

    return Promise.all(promises)
        .then((results) => {
            const resumed = {
                method,
                multicastId: [],
                success: 0,
                failure: 0,
                message: [],
            };
            for (const result of results) {
                if (result.multicastId) {
                    resumed.multicastId.push(result.multicastId);
                }
                resumed.success += result.success;
                resumed.failure += result.failure;
                resumed.message = [...resumed.message, ...result.message];
            }
            return resumed;
        });
};
<|endoftext|>


<commit_before>/* -------------------------------------------------------------------------- */
/* Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org)             */
/*                                                                            */
/* Licensed under the Apache License, Version 2.0 (the "License"); you may    */
/* not use this file except in compliance with the License. You may obtain    */
/* a copy of the License at                                                   */
/*                                                                            */
/* http://www.apache.org/licenses/LICENSE-2.0                                 */
/*                                                                            */
/* Unless required by applicable law or agreed to in writing, software        */
/* distributed under the License is distributed on an "AS IS" BASIS,          */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   */
/* See the License for the specific language governing permissions and        */
/* limitations under the License.                                             */
/* -------------------------------------------------------------------------- */

/* Some useful functions for Sunstone default plugins */
var INTERVAL=60000;

function someTime(){
    return Math.floor(Math.random()*30000);
}

//introduces 0s before a number until in reaches 'length'.
function pad(number,length) {
    var str = '' + number;
    while (str.length < length)
        str = '0' + str;
    return str;
}

//turns a Unix-formatted time into a human readable string
function pretty_time(time_seconds)
{
    var d = new Date();
    d.setTime(time_seconds*1000);

    var secs = pad(d.getSeconds(),2);
    var hour = pad(d.getHours(),2);
    var mins = pad(d.getMinutes(),2);
    var day = pad(d.getDate(),2);
    var month = pad(d.getMonth(),2);
    var year = d.getFullYear();

    return hour + ":" + mins +":" + secs + " " + month + "/" + day + "/" + year;
}

//returns a human readable size in Kilo, Mega, Giga or Tera bytes
function humanize_size(value) {
    if (typeof(value) === "undefined") {
        value = 0;
    }
    var binarySufix = ["K", "M", "G", "T" ];
    var i=0;
    while (value > 1024 && i < 3){
        value = value / 1024;
        i++;
    }
    value = Math.round(value * 10) / 10;

    if (value - Math.round(value) == 0) {
        value = Math.round(value);
    }

    var st = value + binarySufix[i];
    return st;
}

//Wrapper to add an element to a dataTable
function addElement(element,data_table){
	data_table.fnAddData(element);
}

//deletes an element with id 'tag' from a dataTable
function deleteElement(data_table,tag){
	var tr = $(tag).parents('tr')[0];
	data_table.fnDeleteRow(tr);
    $('input',data_table).trigger("change");
}

//Listens to the checkboxes of the datatable. This function is used
//by standard sunstone plugins to enable/disable certain action buttons
//according to the number of elements checked in the dataTables.
//It also checks the "check-all" box when all elements are checked
function tableCheckboxesListener(dataTable){

    //Initialization - disable all buttons
    var context = dataTable.parents('form');
    var last_action_b = $('.last_action_button',context);
    $('.top_button, .list_button',context).button("disable");
    if (last_action_b.length && last_action_b.val().length){
        last_action_b.button("disable");
    };
    $('.create_dialog_button',context).button("enable");

    //listen to changes
    $('input',dataTable).live("change",function(){
        var dataTable = $(this).parents('table').dataTable();
        var context = dataTable.parents('form');
        var last_action_b = $('.last_action_button',context);
        var nodes = dataTable.fnGetNodes();
        var total_length = nodes.length;
        var checked_length = $('input:checked',nodes).length;

        //if all elements are checked we check the check-all box
        if (total_length == checked_length && total_length != 0){
            $('.check_all',dataTable).attr("checked","checked");
        } else {
            $('.check_all',dataTable).removeAttr("checked");
        }

        //if some element is checked, we enable buttons, otherwise
        //we disable them.
        if (checked_length){
            $('.top_button, .list_button',context).button("enable");
            //check if the last_action_button should be enabled
            if (last_action_b.length && last_action_b.val().length){
                last_action_b.button("enable");
            };
        } else {
            $('.top_button, .list_button',context).button("disable");
            last_action_b.button("disable");
        }

        //any case the create dialog buttons should always be enabled.
        $('.create_dialog_button',context).button("enable");
    });

}

// Updates a data_table, with a 2D array containing the new values
// Does a partial redraw, so the filter and pagination are kept
function updateView(item_list,data_table){
	if (data_table!=null) {
		data_table.fnClearTable();
		data_table.fnAddData(item_list);
		data_table.fnDraw(false);
	};
}

//replaces an element with id 'tag' in a dataTable with a new one
function updateSingleElement(element,data_table,tag){
	var tr = $(tag).parents('tr')[0];
	var position = data_table.fnGetPosition(tr);
	data_table.fnUpdate(element,position,0);
    $('input',data_table).trigger("change");

}

// Returns an string in the form key=value key=value ...
// Does not explore objects in depth.
function stringJSON(json){
	var str = ""
	for (field in json) {
		str+= field + '=' + json[field] + ' ';
	}
	return str;
}

//Notifications
//Notification of submission of action
function notifySubmit(action, args, extra_param){
    var action_text = action.replace(/OpenNebula\./,'').replace(/\./,' ');

    var msg = "
Submitted
";
    if (typeof args == 'object'){
        msg += action_text;
    } else {
        msg += action_text + ": " + args;
    }
    if (extra_param != null)
        msg += " >> " + extra_param;

    $.jGrowl(msg, {theme: "jGrowl-notify-submit"});
}

//Notification on error
function notifyError(msg){
    msg = "
Error
" + msg;

    $.jGrowl(msg, {theme: "jGrowl-notify-error", sticky: true });
}

// Returns an HTML string with the json keys and values in the form
// key: value

// It recursively explores objects, and flattens their contents in
// the result.
function prettyPrintJSON(template_json){
	var str = ""
	for (field in template_json) {
		if (typeof template_json[field] == 'object'){
			str += prettyPrintJSON(template_json[field]) + '

';
		} else {
			str += '
'+field+'	'+template_json[field]+'
';
		};
	};
	return str;
}

//Add a listener to the check-all box of a datatable, enabling it to
//check and uncheck all the checkboxes of its elements.
function initCheckAllBoxes(datatable){
	//not showing nice in that position
	//$('.check_all').button({ icons: {primary : "ui-icon-check" },
	//							text : true});

    //small css hack
	$('.check_all',datatable).css({"border":"2px"});
	$('.check_all',datatable).click(function(){
		if ($(this).attr("checked")) {
			$('tbody input:checkbox',
				$(this).parents("table")).each(function(){
					$(this).attr("checked","checked");
			});

		} else {
			$('tbody input:checkbox',
				$(this).parents("table")).each(function(){
					$(this).removeAttr("checked");
			});			}
	});
}

//standard handling for the server errors on ajax requests.
//Pops up a message with the information.
function onError(request,error_json) {
    var method;
    var action;
    var object;
    var id;
    var reason;
    var m;
    var message = error_json.error.message;

    //redirect to login if unauthenticated
    if (error_json.error.http_status=="401") {
      window.location.href = "/login";
    };

    if (!message){
        notifyError("Cannot contact server: is Sunstone server running and reachable?");
        return false;
    }

    //Parse known errors:
    var action_error = /^\[(\w+)\] Error trying to (\w+) (\w+) \[(\w+)\].*Reason: (.*)\.$/;
    var action_error_noid = /^\[(\w+)\] Error trying to (\w+) (\w+) (.*)\.$/;
    var get_error = /^\[(\w+)\] Error getting (\w+) \[(\w+)\]\.$/;
    var auth_error = /^\[(\w+)\] User \[.\] not authorized to perform (\w+) on (\w+) \[?(\w+)\]?\.?$/;

    if (m = message.match(action_error)) {
        method  = m[1];
        action  = m[2];
        object  = m[3];
        id      = m[4];
        reason  = m[5];
    } else if (m = message.match(action_error_noid)) {
        method  = m[1];
        action  = m[2];
        object  = m[3];
        reason  = m[4];
    } else if (m = message.match(get_error)) {
        method  = m[1];
        action  = "SHOW";
        object  = m[2];
        id      = m[3];
    } else if (m = message.match(auth_error)) {
        method = m[1];
        action = m[2];
        object = m[3];
        id     = m[4];
    }

    if (m) {
        var rows;
        var i;
        var value;
        rows = ["method","action","object","id","reason"];
        message = "";
        for (i in rows){
            key = rows[i];
            value = eval(key);
            if (value)
                message += "
"+key+"	"+value+"
";
        }
        message = "
" + message + "
";
    }

    notifyError(message);
    return true;
}

//Replaces the checkboxes of a datatable with a ajax-loading spinner.
//Used when refreshing elements of a datatable.
function waitingNodes(dataTable){
    var nodes = dataTable.fnGetData();
    for (var i=0;i<nodes.length;i++){
       dataTable.fnUpdate(spinner,i,0);
    }
};

//given a user ID, returns an string with the user name.
//To do this it finds the user name in the user dataTable. If it is
//not defined then it returns "uid UID".
//TODO not very nice to hardcode a dataTable here...
function getUserName(uid){
    var user = "uid "+uid;
    if (typeof(dataTable_users) == "undefined") {
        return user;
        }
    var nodes = dataTable_users.fnGetData();

    $.each(nodes,function(){
       if (uid == this[1]) {
           user = this[2];
           return false;
       }
    });
    return user;

}

//Replaces all class"tip" divs with an information icon that
//displays the tip information on mouseover.
function setupTips(context){

        //For each tip in this context
		$('div.tip',context).each(function(){
                //store the text
				var tip = $(this).html();
                //replace the text with an icon and spans
				$(this).html('');
                $(this).append('');

                $(this).append('');

                //add the text to .tipspan
				$('span.tipspan',this).html(tip);
                //make sure it is not floating in the wrong place
                $(this).parent().append('

');
                //hide the text
				$('span.tipspan',this).hide();

                //When the mouse is hovering on the icon we fadein/out
                //the tip text
				$('span.info_icon',this).hover(function(e){
                    var top, left;
                    top = e.pageY - 15;// - $(this).parents('#create_vm_dialog').offset().top - 15;
                    left = e.pageX + 15;// - $(this).parents('#create_vm_dialog').offset().left;
                    $(this).next().css(
                        {"top":top+"px",
                        "left":left+"px"});
					$(this).next().fadeIn();
				},function(){
					$(this).next().fadeOut();
				});
		});
}

//returns an array of ids of selected elements in a dataTable
function getSelectedNodes(dataTable){
    var selected_nodes = [];
    if (dataTable != null){
            //Which rows of the datatable are checked?
            var nodes = $('input:checked',dataTable.fnGetNodes());
            $.each(nodes,function(){
                selected_nodes.push($(this).val());
            });
    }
    return selected_nodes;
}

//functions that used as true and false conditions for testing mainly
function True(){
    return true;
}
function False(){
    return false;
}
<commit_msg>Fixes feature #543: Improve check all handling.<commit_after>/* -------------------------------------------------------------------------- */
/* Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org)             */
/*                                                                            */
/* Licensed under the Apache License, Version 2.0 (the "License"); you may    */
/* not use this file except in compliance with the License. You may obtain    */
/* a copy of the License at                                                   */
/*                                                                            */
/* http://www.apache.org/licenses/LICENSE-2.0                                 */
/*                                                                            */
/* Unless required by applicable law or agreed to in writing, software        */
/* distributed under the License is distributed on an "AS IS" BASIS,          */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   */
/* See the License for the specific language governing permissions and        */
/* limitations under the License.                                             */
/* -------------------------------------------------------------------------- */

/* Some useful functions for Sunstone default plugins */
var INTERVAL=60000;

function someTime(){
    return Math.floor(Math.random()*30000);
}

//introduces 0s before a number until in reaches 'length'.
function pad(number,length) {
    var str = '' + number;
    while (str.length < length)
        str = '0' + str;
    return str;
}

//turns a Unix-formatted time into a human readable string
function pretty_time(time_seconds)
{
    var d = new Date();
    d.setTime(time_seconds*1000);

    var secs = pad(d.getSeconds(),2);
    var hour = pad(d.getHours(),2);
    var mins = pad(d.getMinutes(),2);
    var day = pad(d.getDate(),2);
    var month = pad(d.getMonth(),2);
    var year = d.getFullYear();

    return hour + ":" + mins +":" + secs + " " + month + "/" + day + "/" + year;
}

//returns a human readable size in Kilo, Mega, Giga or Tera bytes
function humanize_size(value) {
    if (typeof(value) === "undefined") {
        value = 0;
    }
    var binarySufix = ["K", "M", "G", "T" ];
    var i=0;
    while (value > 1024 && i < 3){
        value = value / 1024;
        i++;
    }
    value = Math.round(value * 10) / 10;

    if (value - Math.round(value) == 0) {
        value = Math.round(value);
    }

    var st = value + binarySufix[i];
    return st;
}

//Wrapper to add an element to a dataTable
function addElement(element,data_table){
	data_table.fnAddData(element);
}

//deletes an element with id 'tag' from a dataTable
function deleteElement(data_table,tag){
	var tr = $(tag).parents('tr')[0];
	data_table.fnDeleteRow(tr);
    $('input',data_table).trigger("change");
}

//Listens to the checkboxes of the datatable. This function is used
//by standard sunstone plugins to enable/disable certain action buttons
//according to the number of elements checked in the dataTables.
//It also checks the "check-all" box when all elements are checked
function tableCheckboxesListener(dataTable){

    //Initialization - disable all buttons
    var context = dataTable.parents('form');
    var last_action_b = $('.last_action_button',context);
    $('.top_button, .list_button',context).button("disable");
    if (last_action_b.length && last_action_b.val().length){
        last_action_b.button("disable");
    };
    $('.create_dialog_button',context).button("enable");

    //listen to changes in the visible inputs
    $('tbody input',dataTable).live("change",function(){
        var table = $(this).parents('tbody');
        var context = table.parents('form');
        var nodes = $('tr',table);
        var total_length = nodes.length;
        var checked_length = $('input:checked',nodes).length;

        var last_action_b = $('.last_action_button',context);

        //if all elements are checked we check the check-all box
        if (total_length == checked_length && total_length != 0){
            $('.check_all',dataTable).attr("checked","checked");
        } else {
            $('.check_all',dataTable).removeAttr("checked");
        }

        //if some element is checked, we enable buttons, otherwise
        //we disable them.
        if (checked_length){
            $('.top_button, .list_button',context).button("enable");
            //check if the last_action_button should be enabled
            if (last_action_b.length && last_action_b.val().length){
                last_action_b.button("enable");
            };
        } else {
            $('.top_button, .list_button',context).button("disable");
            last_action_b.button("disable");
        }

        //any case the create dialog buttons should always be enabled.
        $('.create_dialog_button',context).button("enable");
    });

}

// Updates a data_table, with a 2D array containing the new values
// Does a partial redraw, so the filter and pagination are kept
function updateView(item_list,data_table){
	if (data_table!=null) {
		data_table.fnClearTable();
		data_table.fnAddData(item_list);
		data_table.fnDraw(false);
	};
}

//replaces an element with id 'tag' in a dataTable with a new one
function updateSingleElement(element,data_table,tag){
	var tr = $(tag).parents('tr')[0];
	var position = data_table.fnGetPosition(tr);
	data_table.fnUpdate(element,position,0);
    $('input',data_table).trigger("change");

}

// Returns an string in the form key=value key=value ...
// Does not explore objects in depth.
function stringJSON(json){
	var str = ""
	for (field in json) {
		str+= field + '=' + json[field] + ' ';
	}
	return str;
}

//Notifications
//Notification of submission of action
function notifySubmit(action, args, extra_param){
    var action_text = action.replace(/OpenNebula\./,'').replace(/\./,' ');

    var msg = "
Submitted
";
    if (typeof args == 'object'){
        msg += action_text;
    } else {
        msg += action_text + ": " + args;
    }
    if (extra_param != null)
        msg += " >> " + extra_param;

    $.jGrowl(msg, {theme: "jGrowl-notify-submit"});
}

//Notification on error
function notifyError(msg){
    msg = "
Error
" + msg;

    $.jGrowl(msg, {theme: "jGrowl-notify-error", sticky: true });
}

// Returns an HTML string with the json keys and values in the form
// key: value

// It recursively explores objects, and flattens their contents in
// the result.
function prettyPrintJSON(template_json){
	var str = ""
	for (field in template_json) {
		if (typeof template_json[field] == 'object'){
			str += prettyPrintJSON(template_json[field]) + '

';
		} else {
			str += '
'+field+'	'+template_json[field]+'
';
		};
	};
	return str;
}

//Add a listener to the check-all box of a datatable, enabling it to
//check and uncheck all the checkboxes of its elements.
function initCheckAllBoxes(datatable){
	//not showing nice in that position
	//$('.check_all').button({ icons: {primary : "ui-icon-check" },
	//							text : true});

    //small css hack
	$('.check_all',datatable).css({"border":"2px"});
	$('.check_all',datatable).click(function(){
		if ($(this).attr("checked")) {
			$('tbody input:checkbox',
				$(this).parents("table")).each(function(){
					$(this).attr("checked","checked");
			});

		} else {
			$('tbody input:checkbox',
				$(this).parents("table")).each(function(){
					$(this).removeAttr("checked");
			});			}
	});
}

//standard handling for the server errors on ajax requests.
//Pops up a message with the information.
function onError(request,error_json) {
    var method;
    var action;
    var object;
    var id;
    var reason;
    var m;
    var message = error_json.error.message;

    //redirect to login if unauthenticated
    if (error_json.error.http_status=="401") {
      window.location.href = "/login";
    };

    if (!message){
        notifyError("Cannot contact server: is Sunstone server running and reachable?");
        return false;
    }

    //Parse known errors:
    var action_error = /^\[(\w+)\] Error trying to (\w+) (\w+) \[(\w+)\].*Reason: (.*)\.$/;
    var action_error_noid = /^\[(\w+)\] Error trying to (\w+) (\w+) (.*)\.$/;
    var get_error = /^\[(\w+)\] Error getting (\w+) \[(\w+)\]\.$/;
    var auth_error = /^\[(\w+)\] User \[.\] not authorized to perform (\w+) on (\w+) \[?(\w+)\]?\.?$/;

    if (m = message.match(action_error)) {
        method  = m[1];
        action  = m[2];
        object  = m[3];
        id      = m[4];
        reason  = m[5];
    } else if (m = message.match(action_error_noid)) {
        method  = m[1];
        action  = m[2];
        object  = m[3];
        reason  = m[4];
    } else if (m = message.match(get_error)) {
        method  = m[1];
        action  = "SHOW";
        object  = m[2];
        id      = m[3];
    } else if (m = message.match(auth_error)) {
        method = m[1];
        action = m[2];
        object = m[3];
        id     = m[4];
    }

    if (m) {
        var rows;
        var i;
        var value;
        rows = ["method","action","object","id","reason"];
        message = "";
        for (i in rows){
            key = rows[i];
            value = eval(key);
            if (value)
                message += "
"+key+"	"+value+"
";
        }
        message = "
" + message + "
";
    }

    notifyError(message);
    return true;
}

//Replaces the checkboxes of a datatable with a ajax-loading spinner.
//Used when refreshing elements of a datatable.
function waitingNodes(dataTable){
    var nodes = dataTable.fnGetData();
    for (var i=0;i<nodes.length;i++){
       dataTable.fnUpdate(spinner,i,0);
    }
};

//given a user ID, returns an string with the user name.
//To do this it finds the user name in the user dataTable. If it is
//not defined then it returns "uid UID".
//TODO not very nice to hardcode a dataTable here...
function getUserName(uid){
    var user = "uid "+uid;
    if (typeof(dataTable_users) == "undefined") {
        return user;
        }
    var nodes = dataTable_users.fnGetData();

    $.each(nodes,function(){
       if (uid == this[1]) {
           user = this[2];
           return false;
       }
    });
    return user;

}

//Replaces all class"tip" divs with an information icon that
//displays the tip information on mouseover.
function setupTips(context){

        //For each tip in this context
		$('div.tip',context).each(function(){
                //store the text
				var tip = $(this).html();
                //replace the text with an icon and spans
				$(this).html('');
                $(this).append('');

                $(this).append('');

                //add the text to .tipspan
				$('span.tipspan',this).html(tip);
                //make sure it is not floating in the wrong place
                $(this).parent().append('

');
                //hide the text
				$('span.tipspan',this).hide();

                //When the mouse is hovering on the icon we fadein/out
                //the tip text
				$('span.info_icon',this).hover(function(e){
                    var top, left;
                    top = e.pageY - 15;// - $(this).parents('#create_vm_dialog').offset().top - 15;
                    left = e.pageX + 15;// - $(this).parents('#create_vm_dialog').offset().left;
                    $(this).next().css(
                        {"top":top+"px",
                        "left":left+"px"});
					$(this).next().fadeIn();
				},function(){
					$(this).next().fadeOut();
				});
		});
}

//returns an array of ids of selected elements in a dataTable
function getSelectedNodes(dataTable){
    var selected_nodes = [];
    if (dataTable != null){
            //Which rows of the datatable are checked?
            var nodes = $('input:checked',$('tbody',dataTable));
            $.each(nodes,function(){
                selected_nodes.push($(this).val());
            });
    }
    return selected_nodes;
}

//functions that used as true and false conditions for testing mainly
function True(){
    return true;
}
function False(){
    return false;
}
<|endoftext|>