<commit_before>'use strict'

import BrowserSurfaceView from './BrowserSurfaceView'
import BrowserCallback from './BrowserCallback'

export default class BrowserSurface {
  /**
   *
   * @param {GrSurface} grSurfaceResource
   * @param {BrowserCompositor} browserCompositor
   * @returns {BrowserSurface}
   */
  static create (grSurfaceResource, browserCompositor) {
    const browserSurface = new BrowserSurface(grSurfaceResource, browserCompositor)
    grSurfaceResource.implementation = browserSurface

    const browserSurfaceView = BrowserSurfaceView.create(0, 0, browserSurface)
    browserSurface.browserSurfaceViews.push(browserSurfaceView)

    return browserSurface
  }

  /**
   * Use BrowserSurface.create(grSurfaceResource) instead.
   * @private
   * @param {GrSurface} grSurfaceResource
   * @param {BrowserCompositor} browserCompositor
   */
  constructor (grSurfaceResource, browserCompositor) {
    this.resource = grSurfaceResource
    this.browserCompositor = browserCompositor

    this.pendingBrowserBuffer = null
    this.pendingBrowserBufferDestroyListener = (grBufferResource) => {
      this.pendingBrowserBuffer = null
    }
    this.browserBuffer = null

    this.browserSurfaceViews = []
  }

  /**
   *
   * Deletes the surface and invalidates its object ID.
   *
   *
   * @param {GrSurface} resource
   *
   * @since 1
   *
   */
  destroy (resource) {
    resource.destroy()
  }

  /**
   *
   *                Set a buffer as the content of this surface.
   *
   *                The new size of the surface is calculated based on the buffer
   *                size transformed by the inverse bufferTransform and the
   *                inverse bufferScale. This means that the supplied buffer
   *                must be an integer multiple of the bufferScale.
   *
   *                The x and y arguments specify the location of the new pending
   *                buffer's upper left corner, relative to the current buffer's upper
   *                left corner, in surface local coordinates. In other words, the
   *                x and y, combined with the new surface size define in which
   *                directions the surface's size changes.
   *
   *                Surface contents are double-buffered state, see GrSurface.commit.
   *
   *                The initial surface contents are void; there is no content.
   *                GrSurface.attach assigns the given GrBuffer as the pending
   *                GrBuffer. GrSurface.commit makes the pending GrBuffer the new
   *                surface contents, and the size of the surface becomes the size
   *                calculated from the GrBuffer, as described above. After commit,
   *                there is no pending buffer until the next attach.
   *
   *                Committing a pending GrBuffer allows the compositor to read the
   *                pixels in the GrBuffer. The compositor may access the pixels at
   *                any time after the GrSurface.commit request. It may take some
   *                time for the contents to arrive at the compositor if they have
   *                not been transferred already. The compositor will continue using
   *                old surface content and state until the new content has arrived.
   *                See also GrBuffer.complete.
   *
   *                If it is possible to re-use a GrBuffer or update its
   *                contents, the respective buffer factory shall define how that
   *                works.
   *
   *                Destroying the GrBuffer after GrBuffer.complete does not change
   *                the surface contents. However, if the client destroys the
   *                GrBuffer before receiving the GrBuffer.complete event, the surface
   *                contents become undefined immediately.
   *
   *                If GrSurface.attach is sent with a NULL GrBuffer, the
   *                following GrSurface.commit will remove the surface content.
   *
   *
   * @param {GrSurface} resource
   * @param {?*} buffer undefined
   * @param {Number} x undefined
   * @param {Number} y undefined
   *
   * @since 1
   *
   */
  attach (resource, buffer, x, y) {
    if (this.pendingBrowserBuffer) {
      this.pendingBrowserBuffer.removeDestroyListener(this.pendingBrowserBufferDestroyListener)
    }

    this.pendingBrowserBuffer = buffer
    this.pendingBrowserBuffer.addDestroyListener(this.pendingBrowserBufferDestroyListener)

    this.browserSurfaceViews.forEach((browserSurfaceView) => {
      const newGlobalX = browserSurfaceView.position.x + x
      const newGlobalY = browserSurfaceView.position.y + y
      browserSurfaceView.setPosition({x: newGlobalX, y: newGlobalY})
    })
  }

  /**
   *
   *                This request is used to describe the regions where the pending
   *                buffer is different from the current surface contents, and where
   *                the surface therefore needs to be repainted. The compositor
   *                ignores the parts of the damage that fall outside of the surface.
   *
   *                Damage is double-buffered state, see GrSurface.commit.
   *
   *                The damage rectangle is specified in surface local coordinates.
   *
   *                The initial value for pending damage is empty: no damage.
   *                GrSurface.damage adds pending damage: the new pending damage
   *                is the union of old pending damage and the given rectangle.
   *
   *                GrSurface.commit assigns pending damage as the current damage,
   *                and clears pending damage. The server will clear the current
   *                damage as it repaints the surface.
   *
   *                Alternatively, damage can be posted with GrSurface.damageBuffer
   *                which uses buffer co-ordinates instead of surface co-ordinates,
   *                and is probably the preferred and intuitive way of doing this.
   *
   *                The factory behind the the GrBuffer might imply full surface
   *                damage, overriding this request. This is common when the factory
   *                uses a video encoder, where regions outside the original changes
   *                may improve in quality.
   *
   *
   * @param {GrSurface} resource
   * @param {Number} x undefined
   * @param {Number} y undefined
   * @param {Number} width undefined
   * @param {Number} height undefined
   *
   * @since 1
   *
   */
  damage (resource, x, y, width, height) {

  }

  /**
   *
   *                Request a notification when it is a good time start drawing a new
   *                frame, by creating a frame callback. This is useful for throttling
   *                redrawing operations, and driving animations.
   *
   *                When a client is animating on a GrSurface, it can use the 'frame'
   *                request to get notified when it is a good time to draw and commit the
   *                next frame of animation. If the client commits an update earlier than
   *                that, it is likely that some updates will not make it to the display,
   *                and the client is wasting resources by drawing too often.
   *
   *                The frame request will take effect on the next GrSurface.commit.
   *                The notification will only be posted for one frame unless
   *                requested again. For a GrSurface, the notifications are posted in
   *                the order the frame requests were committed.
   *
   *                The server must send the notifications so that a client
   *                will not send excessive updates, while still allowing
   *                the highest possible update rate for clients that wait for the reply
   *                before drawing again. The server should give some time for the client
   *                to draw and commit after sending the frame callback events to let them
   *                hit the next output refresh.
   *
   *                A server should avoid signalling the frame callbacks if the
   *                surface is not visible in any way, e.g. the surface is off-screen,
   *                or completely obscured by other opaque surfaces.
   *
   *                The object returned by this request will be destroyed by the
   *                compositor after the callback is fired and as such the client must not
   *                attempt to use it after that point.
   *
   *                The callbackData passed in the callback is the current time, in
   *                milliseconds, with an undefined base.
   *
   *
   * @param {GrSurface} resource
   * @param {*} callback undefined
   *
   * @since 1
   *
   */
  frame (resource, callback) {
    if (this.frameCallback) {
      this.frameCallback.resource.destroy()
    }
    this.frameCallback = BrowserCallback.create(callback)
  }

  /**
   *
   *                This request sets the region of the surface that contains
   *                opaque content.
   *
   *                The opaque region is an optimization hint for the compositor
   *                that lets it optimize out redrawing of content behind opaque
   *                regions.  Setting an opaque region is not required for correct
   *                behaviour, but marking transparent content as opaque will result
   *                in repaint artifacts.
   *
   *                The opaque region is specified in surface local coordinates.
   *
   *                The compositor ignores the parts of the opaque region that fall
   *                outside of the surface.
   *
   *                Opaque region is double-buffered state, see GrSurface.commit.
   *
   *                GrSurface.setOpaqueRegion changes the pending opaque region.
   *                GrSurface.commit copies the pending region to the current region.
   *                Otherwise, the pending and current regions are never changed.
   *
   *                The initial value for opaque region is empty. Setting the pending
   *                opaque region has copy semantics, and the GrRegion object can be
   *                destroyed immediately. A NULL GrRegion causes the pending opaque
   *                region to be set to empty.
   *
   *
   * @param {GrSurface} resource
   * @param {?*} region undefined
   *
   * @since 1
   *
   */
  setOpaqueRegion (resource, region) {

  }

  /**
   *
   *                This request sets the region of the surface that can receive
   *                pointer and touch events.
   *
   *                Input events happening outside of this region will try the next
   *                surface in the server surface stack. The compositor ignores the
   *                parts of the input region that fall outside of the surface.
   *
   *                The input region is specified in surface local coordinates.
   *
   *                Input region is double-buffered state, see GrSurface.commit.
   *
   *                GrSurface.setInputRegion changes the pending input region.
   *                GrSurface.commit copies the pending region to the current region.
   *                Otherwise the pending and current regions are never changed,
   *                except cursor and icon surfaces are special cases, see
   *                GrPointer.setCursor and GrDataDevice.startDrag.
   *
   *                The initial value for input region is infinite. That means the
   *                whole surface will accept input. Setting the pending input region
   *                has copy semantics, and the GrRegion object can be destroyed
   *                immediately. A NULL GrRegion causes the input region to be set
   *                to infinite.
   *
   *
   * @param {GrSurface} resource
   * @param {?*} region undefined
   *
   * @since 1
   *
   */
  setInputRegion (resource, region) {

  }

  /**
   *
   *                Surface state (input, opaque, and damage regions, attached buffers,
   *                etc.) is double-buffered. Protocol requests modify the pending
   *                state, as opposed to current state in use by the compositor. Commit
   *                request atomically applies all pending state, replacing the current
   *                state. After commit, the new pending state is as documented for each
   *                related request.
   *
   *                On commit, a pending GrBuffer is applied first, all other state
   *                second. This means that all coordinates in double-buffered state are
   *                relative to the new GrBuffer coming into use, except for
   *                GrSurface.attach itself. If there is no pending GrBuffer, the
   *                coordinates are relative to the current surface contents.
   *
   *                All requests that need a commit to become effective are documented
   *                to affect double-buffered state.
   *
   *                Other interfaces may add further double-buffered surface state.
   *
   *
   * @param {GrSurface} resource
   *
   * @since 1
   *
   */
  commit (resource) {
    if (this.pendingBrowserBuffer) {
      this.pendingBrowserBuffer.removeDestroyListener(this.pendingBrowserBufferDestroyListener)
    }
    this.browserBuffer = this.pendingBrowserBuffer
    this.pendingBrowserBuffer = null
    this.browserCompositor.requestRender()
  }

  /**
   *
   *                This request sets an optional transformation on how the compositor
   *                interprets the contents of the buffer attached to the surface. The
   *                accepted values for the transform parameter are the values for
   *                GrOutput.transform.
   *
   *                Buffer transform is double-buffered state, see GrSurface.commit.
   *
   *                A newly created surface has its buffer transformation set to normal.
   *
   *                GrSurface.setBufferTransform changes the pending buffer
   *                transformation. GrSurface.commit copies the pending buffer
   *                transformation to the current one. Otherwise, the pending and current
   *                values are never changed.
   *
   *                The purpose of this request is to allow clients to render content
   *                according to the output transform, thus permiting the compositor to
   *                use certain optimizations even if the display is rotated. Using
   *                hardware overlays and scanning out a client buffer for fullscreen
   *                surfaces are examples of such optimizations. Those optimizations are
   *                highly dependent on the compositor implementation, so the use of this
   *                request should be considered on a case-by-case basis.
   *
   *                Note that if the transform value includes 90 or 270 degree rotation,
   *                the width of the buffer will become the surface height and the height
   *                of the buffer will become the surface width.
   *
   *                If transform is not one of the values from the
   *                GrOutput.transform enum the invalidTransform protocol error
   *                is raised.
   *
   *
   * @param {GrSurface} resource
   * @param {Number} transform undefined
   *
   * @since 2
   *
   */
  setBufferTransform (resource, transform) {

  }

  /**
   *
   *                This request sets an optional scaling factor on how the compositor
   *                interprets the contents of the buffer attached to the window.
   *
   *                Buffer scale is double-buffered state, see GrSurface.commit.
   *
   *                A newly created surface has its buffer scale set to 1.
   *
   *                GrSurface.setBufferScale changes the pending buffer scale.
   *                GrSurface.commit copies the pending buffer scale to the current one.
   *                Otherwise, the pending and current values are never changed.
   *
   *                The purpose of this request is to allow clients to supply higher
   *                resolution buffer data for use on high resolution outputs. Its
   *                intended that you pick the same  buffer scale as the scale of the
   *                output that the surface is displayed on.This means the compositor
   *                can avoid scaling when rendering the surface on that output.
   *
   *                Note that if the scale is larger than 1, then you have to attach
   *                a buffer that is larger (by a factor of scale in each dimension)
   *                than the desired surface size.
   *
   *                If scale is not positive the invalidScale protocol error is
   *                raised.
   *
   *
   * @param {GrSurface} resource
   * @param {Number} scale undefined
   *
   * @since 3
   *
   */
  setBufferScale (resource, scale) {

  }

  /**
   *
   *                This request is used to describe the regions where the pending
   *                buffer is different from the current surface contents, and where
   *                the surface therefore needs to be repainted. The compositor
   *                ignores the parts of the damage that fall outside of the surface.
   *
   *                Damage is double-buffered state, see GrSurface.commit.
   *
   *                The damage rectangle is specified in buffer coordinates.
   *
   *                The initial value for pending damage is empty: no damage.
   *                GrSurface.damageBuffer adds pending damage: the new pending
   *                damage is the union of old pending damage and the given rectangle.
   *
   *                GrSurface.commit assigns pending damage as the current damage,
   *                and clears pending damage. The server will clear the current
   *                damage as it repaints the surface.
   *
   *                This request differs from GrSurface.damage in only one way - it
   *                takes damage in buffer co-ordinates instead of surface local
   *                co-ordinates. While this generally is more intuitive than surface
   *                co-ordinates, it is especially desirable when using wpViewport
   *                or when a drawing library (like EGL) is unaware of buffer scale
   *                and buffer transform.
   *
   *                Note: Because buffer transformation changes and damage requests may
   *                be interleaved in the protocol stream, It is impossible to determine
   *                the actual mapping between surface and buffer damage until
   *                GrSurface.commit time. Therefore, compositors wishing to take both
   *                kinds of damage into account will have to accumulate damage from the
   *                two requests separately and only transform from one to the other
   *                after receiving the GrSurface.commit.
   *
   *
   * @param {GrSurface} resource
   * @param {Number} x undefined
   * @param {Number} y undefined
   * @param {Number} width undefined
   * @param {Number} height undefined
   *
   * @since 4
   *
   */
  damageBuffer (resource, x, y, width, height) {

  }
}
<commit_msg>properly create callback frame resource<commit_after>'use strict'

import greenfield from './protocol/greenfield-browser-protocol'
import BrowserSurfaceView from './BrowserSurfaceView'
import BrowserCallback from './BrowserCallback'

export default class BrowserSurface {
  /**
   *
   * @param {GrSurface} grSurfaceResource
   * @param {BrowserCompositor} browserCompositor
   * @returns {BrowserSurface}
   */
  static create (grSurfaceResource, browserCompositor) {
    const browserSurface = new BrowserSurface(grSurfaceResource, browserCompositor)
    grSurfaceResource.implementation = browserSurface

    const browserSurfaceView = BrowserSurfaceView.create(0, 0, browserSurface)
    browserSurface.browserSurfaceViews.push(browserSurfaceView)

    return browserSurface
  }

  /**
   * Use BrowserSurface.create(grSurfaceResource) instead.
   * @private
   * @param {GrSurface} grSurfaceResource
   * @param {BrowserCompositor} browserCompositor
   */
  constructor (grSurfaceResource, browserCompositor) {
    this.resource = grSurfaceResource
    this.browserCompositor = browserCompositor

    this.pendingBrowserBuffer = null
    this.pendingBrowserBufferDestroyListener = (grBufferResource) => {
      this.pendingBrowserBuffer = null
    }
    this.browserBuffer = null

    this.browserSurfaceViews = []
  }

  /**
   *
   * Deletes the surface and invalidates its object ID.
   *
   *
   * @param {GrSurface} resource
   *
   * @since 1
   *
   */
  destroy (resource) {
    resource.destroy()
  }

  /**
   *
   *                Set a buffer as the content of this surface.
   *
   *                The new size of the surface is calculated based on the buffer
   *                size transformed by the inverse bufferTransform and the
   *                inverse bufferScale. This means that the supplied buffer
   *                must be an integer multiple of the bufferScale.
   *
   *                The x and y arguments specify the location of the new pending
   *                buffer's upper left corner, relative to the current buffer's upper
   *                left corner, in surface local coordinates. In other words, the
   *                x and y, combined with the new surface size define in which
   *                directions the surface's size changes.
   *
   *                Surface contents are double-buffered state, see GrSurface.commit.
   *
   *                The initial surface contents are void; there is no content.
   *                GrSurface.attach assigns the given GrBuffer as the pending
   *                GrBuffer. GrSurface.commit makes the pending GrBuffer the new
   *                surface contents, and the size of the surface becomes the size
   *                calculated from the GrBuffer, as described above. After commit,
   *                there is no pending buffer until the next attach.
   *
   *                Committing a pending GrBuffer allows the compositor to read the
   *                pixels in the GrBuffer. The compositor may access the pixels at
   *                any time after the GrSurface.commit request. It may take some
   *                time for the contents to arrive at the compositor if they have
   *                not been transferred already. The compositor will continue using
   *                old surface content and state until the new content has arrived.
   *                See also GrBuffer.complete.
   *
   *                If it is possible to re-use a GrBuffer or update its
   *                contents, the respective buffer factory shall define how that
   *                works.
   *
   *                Destroying the GrBuffer after GrBuffer.complete does not change
   *                the surface contents. However, if the client destroys the
   *                GrBuffer before receiving the GrBuffer.complete event, the surface
   *                contents become undefined immediately.
   *
   *                If GrSurface.attach is sent with a NULL GrBuffer, the
   *                following GrSurface.commit will remove the surface content.
   *
   *
   * @param {GrSurface} resource
   * @param {?*} buffer undefined
   * @param {Number} x undefined
   * @param {Number} y undefined
   *
   * @since 1
   *
   */
  attach (resource, buffer, x, y) {
    if (this.pendingBrowserBuffer) {
      this.pendingBrowserBuffer.removeDestroyListener(this.pendingBrowserBufferDestroyListener)
    }

    this.pendingBrowserBuffer = buffer
    this.pendingBrowserBuffer.addDestroyListener(this.pendingBrowserBufferDestroyListener)

    this.browserSurfaceViews.forEach((browserSurfaceView) => {
      const newGlobalX = browserSurfaceView.position.x + x
      const newGlobalY = browserSurfaceView.position.y + y
      browserSurfaceView.setPosition({x: newGlobalX, y: newGlobalY})
    })
  }

  /**
   *
   *                This request is used to describe the regions where the pending
   *                buffer is different from the current surface contents, and where
   *                the surface therefore needs to be repainted. The compositor
   *                ignores the parts of the damage that fall outside of the surface.
   *
   *                Damage is double-buffered state, see GrSurface.commit.
   *
   *                The damage rectangle is specified in surface local coordinates.
   *
   *                The initial value for pending damage is empty: no damage.
   *                GrSurface.damage adds pending damage: the new pending damage
   *                is the union of old pending damage and the given rectangle.
   *
   *                GrSurface.commit assigns pending damage as the current damage,
   *                and clears pending damage. The server will clear the current
   *                damage as it repaints the surface.
   *
   *                Alternatively, damage can be posted with GrSurface.damageBuffer
   *                which uses buffer co-ordinates instead of surface co-ordinates,
   *                and is probably the preferred and intuitive way of doing this.
   *
   *                The factory behind the the GrBuffer might imply full surface
   *                damage, overriding this request. This is common when the factory
   *                uses a video encoder, where regions outside the original changes
   *                may improve in quality.
   *
   *
   * @param {GrSurface} resource
   * @param {Number} x undefined
   * @param {Number} y undefined
   * @param {Number} width undefined
   * @param {Number} height undefined
   *
   * @since 1
   *
   */
  damage (resource, x, y, width, height) {

  }

  /**
   *
   *                Request a notification when it is a good time start drawing a new
   *                frame, by creating a frame callback. This is useful for throttling
   *                redrawing operations, and driving animations.
   *
   *                When a client is animating on a GrSurface, it can use the 'frame'
   *                request to get notified when it is a good time to draw and commit the
   *                next frame of animation. If the client commits an update earlier than
   *                that, it is likely that some updates will not make it to the display,
   *                and the client is wasting resources by drawing too often.
   *
   *                The frame request will take effect on the next GrSurface.commit.
   *                The notification will only be posted for one frame unless
   *                requested again. For a GrSurface, the notifications are posted in
   *                the order the frame requests were committed.
   *
   *                The server must send the notifications so that a client
   *                will not send excessive updates, while still allowing
   *                the highest possible update rate for clients that wait for the reply
   *                before drawing again. The server should give some time for the client
   *                to draw and commit after sending the frame callback events to let them
   *                hit the next output refresh.
   *
   *                A server should avoid signalling the frame callbacks if the
   *                surface is not visible in any way, e.g. the surface is off-screen,
   *                or completely obscured by other opaque surfaces.
   *
   *                The object returned by this request will be destroyed by the
   *                compositor after the callback is fired and as such the client must not
   *                attempt to use it after that point.
   *
   *                The callbackData passed in the callback is the current time, in
   *                milliseconds, with an undefined base.
   *
   *
   * @param {GrSurface} resource
   * @param {*} callback undefined
   *
   * @since 1
   *
   */
  frame (resource, callback) {
    if (this.frameCallback) {
      this.frameCallback.resource.destroy()
      this.frameCallback = null
    }
    this.frameCallback = BrowserCallback.create(new greenfield.GrCallback(resource.client, callback, 1))
  }

  /**
   *
   *                This request sets the region of the surface that contains
   *                opaque content.
   *
   *                The opaque region is an optimization hint for the compositor
   *                that lets it optimize out redrawing of content behind opaque
   *                regions.  Setting an opaque region is not required for correct
   *                behaviour, but marking transparent content as opaque will result
   *                in repaint artifacts.
   *
   *                The opaque region is specified in surface local coordinates.
   *
   *                The compositor ignores the parts of the opaque region that fall
   *                outside of the surface.
   *
   *                Opaque region is double-buffered state, see GrSurface.commit.
   *
   *                GrSurface.setOpaqueRegion changes the pending opaque region.
   *                GrSurface.commit copies the pending region to the current region.
   *                Otherwise, the pending and current regions are never changed.
   *
   *                The initial value for opaque region is empty. Setting the pending
   *                opaque region has copy semantics, and the GrRegion object can be
   *                destroyed immediately. A NULL GrRegion causes the pending opaque
   *                region to be set to empty.
   *
   *
   * @param {GrSurface} resource
   * @param {?*} region undefined
   *
   * @since 1
   *
   */
  setOpaqueRegion (resource, region) {

  }

  /**
   *
   *                This request sets the region of the surface that can receive
   *                pointer and touch events.
   *
   *                Input events happening outside of this region will try the next
   *                surface in the server surface stack. The compositor ignores the
   *                parts of the input region that fall outside of the surface.
   *
   *                The input region is specified in surface local coordinates.
   *
   *                Input region is double-buffered state, see GrSurface.commit.
   *
   *                GrSurface.setInputRegion changes the pending input region.
   *                GrSurface.commit copies the pending region to the current region.
   *                Otherwise the pending and current regions are never changed,
   *                except cursor and icon surfaces are special cases, see
   *                GrPointer.setCursor and GrDataDevice.startDrag.
   *
   *                The initial value for input region is infinite. That means the
   *                whole surface will accept input. Setting the pending input region
   *                has copy semantics, and the GrRegion object can be destroyed
   *                immediately. A NULL GrRegion causes the input region to be set
   *                to infinite.
   *
   *
   * @param {GrSurface} resource
   * @param {?*} region undefined
   *
   * @since 1
   *
   */
  setInputRegion (resource, region) {

  }

  /**
   *
   *                Surface state (input, opaque, and damage regions, attached buffers,
   *                etc.) is double-buffered. Protocol requests modify the pending
   *                state, as opposed to current state in use by the compositor. Commit
   *                request atomically applies all pending state, replacing the current
   *                state. After commit, the new pending state is as documented for each
   *                related request.
   *
   *                On commit, a pending GrBuffer is applied first, all other state
   *                second. This means that all coordinates in double-buffered state are
   *                relative to the new GrBuffer coming into use, except for
   *                GrSurface.attach itself. If there is no pending GrBuffer, the
   *                coordinates are relative to the current surface contents.
   *
   *                All requests that need a commit to become effective are documented
   *                to affect double-buffered state.
   *
   *                Other interfaces may add further double-buffered surface state.
   *
   *
   * @param {GrSurface} resource
   *
   * @since 1
   *
   */
  commit (resource) {
    if (this.pendingBrowserBuffer) {
      this.pendingBrowserBuffer.removeDestroyListener(this.pendingBrowserBufferDestroyListener)
    }
    this.browserBuffer = this.pendingBrowserBuffer
    this.pendingBrowserBuffer = null
    this.browserCompositor.requestRender()
  }

  /**
   *
   *                This request sets an optional transformation on how the compositor
   *                interprets the contents of the buffer attached to the surface. The
   *                accepted values for the transform parameter are the values for
   *                GrOutput.transform.
   *
   *                Buffer transform is double-buffered state, see GrSurface.commit.
   *
   *                A newly created surface has its buffer transformation set to normal.
   *
   *                GrSurface.setBufferTransform changes the pending buffer
   *                transformation. GrSurface.commit copies the pending buffer
   *                transformation to the current one. Otherwise, the pending and current
   *                values are never changed.
   *
   *                The purpose of this request is to allow clients to render content
   *                according to the output transform, thus permiting the compositor to
   *                use certain optimizations even if the display is rotated. Using
   *                hardware overlays and scanning out a client buffer for fullscreen
   *                surfaces are examples of such optimizations. Those optimizations are
   *                highly dependent on the compositor implementation, so the use of this
   *                request should be considered on a case-by-case basis.
   *
   *                Note that if the transform value includes 90 or 270 degree rotation,
   *                the width of the buffer will become the surface height and the height
   *                of the buffer will become the surface width.
   *
   *                If transform is not one of the values from the
   *                GrOutput.transform enum the invalidTransform protocol error
   *                is raised.
   *
   *
   * @param {GrSurface} resource
   * @param {Number} transform undefined
   *
   * @since 2
   *
   */
  setBufferTransform (resource, transform) {

  }

  /**
   *
   *                This request sets an optional scaling factor on how the compositor
   *                interprets the contents of the buffer attached to the window.
   *
   *                Buffer scale is double-buffered state, see GrSurface.commit.
   *
   *                A newly created surface has its buffer scale set to 1.
   *
   *                GrSurface.setBufferScale changes the pending buffer scale.
   *                GrSurface.commit copies the pending buffer scale to the current one.
   *                Otherwise, the pending and current values are never changed.
   *
   *                The purpose of this request is to allow clients to supply higher
   *                resolution buffer data for use on high resolution outputs. Its
   *                intended that you pick the same  buffer scale as the scale of the
   *                output that the surface is displayed on.This means the compositor
   *                can avoid scaling when rendering the surface on that output.
   *
   *                Note that if the scale is larger than 1, then you have to attach
   *                a buffer that is larger (by a factor of scale in each dimension)
   *                than the desired surface size.
   *
   *                If scale is not positive the invalidScale protocol error is
   *                raised.
   *
   *
   * @param {GrSurface} resource
   * @param {Number} scale undefined
   *
   * @since 3
   *
   */
  setBufferScale (resource, scale) {

  }

  /**
   *
   *                This request is used to describe the regions where the pending
   *                buffer is different from the current surface contents, and where
   *                the surface therefore needs to be repainted. The compositor
   *                ignores the parts of the damage that fall outside of the surface.
   *
   *                Damage is double-buffered state, see GrSurface.commit.
   *
   *                The damage rectangle is specified in buffer coordinates.
   *
   *                The initial value for pending damage is empty: no damage.
   *                GrSurface.damageBuffer adds pending damage: the new pending
   *                damage is the union of old pending damage and the given rectangle.
   *
   *                GrSurface.commit assigns pending damage as the current damage,
   *                and clears pending damage. The server will clear the current
   *                damage as it repaints the surface.
   *
   *                This request differs from GrSurface.damage in only one way - it
   *                takes damage in buffer co-ordinates instead of surface local
   *                co-ordinates. While this generally is more intuitive than surface
   *                co-ordinates, it is especially desirable when using wpViewport
   *                or when a drawing library (like EGL) is unaware of buffer scale
   *                and buffer transform.
   *
   *                Note: Because buffer transformation changes and damage requests may
   *                be interleaved in the protocol stream, It is impossible to determine
   *                the actual mapping between surface and buffer damage until
   *                GrSurface.commit time. Therefore, compositors wishing to take both
   *                kinds of damage into account will have to accumulate damage from the
   *                two requests separately and only transform from one to the other
   *                after receiving the GrSurface.commit.
   *
   *
   * @param {GrSurface} resource
   * @param {Number} x undefined
   * @param {Number} y undefined
   * @param {Number} width undefined
   * @param {Number} height undefined
   *
   * @since 4
   *
   */
  damageBuffer (resource, x, y, width, height) {

  }
}
<|endoftext|>


<commit_before>/*---------------------------/
| Users Ressource
|----------------------------*/

let users = {

  // Name of the ressource
  name: "users",

  // Default ressource Configuration
  config: {

    // Enabled CRUD
    CRUD: false,

    // GET method routes
    GET: [
      {
        path: "/",
        action: (req, res, next) => {
          res.send("ok");
        },
        middleware: ["auth.generateAuthToken"],
        need: false
      },
    ],

    // POST method routes
    POST: [
      {
        path: "/signup",
        uses: "users@signup",
      },

      {
        path: "/login",
        uses: "users@login",
        middleware: ["auth.generateAuthToken"],
      }
    ],

    // PUT methods routes
    PUT: [],

    // DELETE methods routes
    DELETE: []
  }
};

export {users};
<commit_msg>clear user routes<commit_after>/*---------------------------/
| Users Ressource
|----------------------------*/

let users = {

  // Name of the ressource
  name: "users",

  // Default ressource Configuration
  config: {

    // Enabled CRUD
    CRUD: [
      { action: "all" },
      { action: "read" }
    ],

    // GET method routes
    GET: [
    ],

    // POST method routes
    POST: [
      {
        path: "/signup",
        uses: "users@signup",
      },

      {
        path: "/login",
        uses: "users@login",
        middleware: ["auth.generateAuthToken"],
      }
    ],

    // PUT methods routes
    PUT: [],

    // DELETE methods routes
    DELETE: []
  }
};

export {users};
<|endoftext|>


<commit_before>//
//   Copyright 2009-2014 Ilkka Oksanen <iao@iki.fi>
//
//   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.
//

'use strict';

import Ember from 'ember';

export default Ember.Component.extend({
    sortProperties: [ 'online', 'last', 'name' ],
    sortAscending: false,

    sortedFriends: Ember.computed.sort('friends', 'sortProperties')
});
<commit_msg>Fix friends list sorting<commit_after>//
//   Copyright 2009-2014 Ilkka Oksanen <iao@iki.fi>
//
//   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.
//

'use strict';

import Ember from 'ember';

export default Ember.Component.extend({
    sortProperties: [ 'online:desc', 'last:desc', 'name' ],
    sortAscending: false,

    sortedFriends: Ember.computed.sort('friends', 'sortProperties')
});
<|endoftext|>


<commit_before>var geom = require('pex-geom');
var Vec2 = geom.Vec2;
var Vec3 = geom.Vec3;
var Vec4 = geom.Vec4;
var Mat4 = geom.Mat4;
var Ray = geom.Ray;

function PerspectiveCamera(fov, aspectRatio, near, far, position, target, up) {
  this.fov = fov || 60;
  this.aspectRatio = aspectRatio || 4 / 3;
  this.near = near || 0.1;
  this.far = far || 100;
  this.position = position || Vec3.create(0, 0, 5);
  this.target = target || Vec3.create(0, 0, 0);
  this.up = up || Vec3.create(0, 1, 0);
  this.projectionMatrix = Mat4.create();
  this.viewMatrix = Mat4.create();
  this.tmpProjected = new Vec4();
  this.updateMatrices();
}

PerspectiveCamera.prototype.getFov = function() {
  return this.fov;
};

PerspectiveCamera.prototype.getAspectRatio = function() {
  return this.aspectRatio;
};

PerspectiveCamera.prototype.getNear = function() {
  return this.near;
};

PerspectiveCamera.prototype.getFar = function() {
  return this.far;
};

PerspectiveCamera.prototype.getPosition = function() {
  return this.position;
};

PerspectiveCamera.prototype.getTarget = function() {
  return this.target;
};

PerspectiveCamera.prototype.getUp = function() {
  return this.up;
};

PerspectiveCamera.prototype.getViewMatrix = function() {
  return this.viewMatrix;
};

PerspectiveCamera.prototype.getProjectionMatrix = function() {
  return this.projectionMatrix;
};

PerspectiveCamera.prototype.setFov = function(fov) {
  this.fov = fov;
  this.updateMatrices();
};

PerspectiveCamera.prototype.setAspectRatio = function(ratio) {
  this.aspectRatio = ratio;
  this.updateMatrices();
};

PerspectiveCamera.prototype.setFar = function(far) {
  this.far = far;
  this.updateMatrices();
};

PerspectiveCamera.prototype.setNear = function(near) {
  this.near = near;
  this.updateMatrices();
};

PerspectiveCamera.prototype.setPosition = function(position) {
  this.position = position;
  this.updateMatrices();
};

PerspectiveCamera.prototype.setTarget = function(target) {
  this.target = target;
  this.updateMatrices();
};

PerspectiveCamera.prototype.setUp = function(up) {
  this.up = up;
  this.updateMatrices();
};

PerspectiveCamera.prototype.lookAt = function(target, eyePosition, up) {
  if (target) {
    this.target = target;
  }
  if (eyePosition) {
    this.position = eyePosition;
  }
  if (up) {
    this.up = up;
  }
  this.updateMatrices();
};

PerspectiveCamera.prototype.updateMatrices = function() {
  this.projectionMatrix.identity().perspective(this.fov, this.aspectRatio, this.near, this.far);
  this.viewMatrix.identity().lookAt(this.position, this.target, this.up);
};

PerspectiveCamera.prototype.getScreenPos = function(point, windowWidth, windowHeight) {
  this.tmpProjected.set(point.x, point.y, point.z, 1.0);
  this.tmpProjected.transformMat4(this.viewMatrix);
  this.tmpProjected.transformMat4(this.projectionMatrix);
  var out = Vec2.create().set(this.tmpProjected.x, this.tmpProjected.y);
  out.x /= this.tmpProjected.w;
  out.y /= this.tmpProjected.w;
  out.x = out.x * 0.5 + 0.5;
  out.y = 1.0 - (out.y * 0.5 + 0.5);
  out.x *= windowWidth;
  out.y *= windowHeight;
  return out;
};

PerspectiveCamera.prototype.getViewRay = function(x, y, windowWidth, windowHeight) {
  var px = (x - windowWidth / 2) / (windowWidth / 2);
  var py = -(y - windowHeight / 2) / (windowHeight / 2);
  var hNear = 2 * Math.tan(this.getFov() / 180 * Math.PI / 2) * this.getNear();
  var wNear = hNear * this.getAspectRatio();
  px *= wNear / 2;
  py *= hNear / 2;
  var vOrigin = new Vec3(0, 0, 0);
  var vTarget = new Vec3(px, py, -this.getNear());
  var vDirection = vTarget.dup().sub(vOrigin).normalize();
  return new Ray(vOrigin, vDirection);
};

PerspectiveCamera.prototype.getWorldRay = function(x, y, windowWidth, windowHeight) {
  x = (x - windowWidth / 2) / (windowWidth / 2);
  y = -(y - windowHeight / 2) / (windowHeight / 2);
  var hNear = 2 * Math.tan(this.getFov() / 180 * Math.PI / 2) * this.getNear();
  var wNear = hNear * this.getAspectRatio();
  x *= wNear / 2;
  y *= hNear / 2;
  var vOrigin = new Vec3(0, 0, 0);
  var vTarget = new Vec3(x, y, -this.getNear());
  var invViewMatrix = this.getViewMatrix().dup().invert();
  var wOrigin = vOrigin.dup().transformMat4(invViewMatrix);
  var wTarget = vTarget.dup().transformMat4(invViewMatrix);
  var wDirection = wTarget.dup().sub(wOrigin).normalize();
  return new Ray(wOrigin, wDirection);
};

module.exports = PerspectiveCamera;
<commit_msg>Added PerspectiveCamera frustum calculation<commit_after>var geom = require('pex-geom');
var Vec2 = geom.Vec2;
var Vec3 = geom.Vec3;
var Vec4 = geom.Vec4;
var Mat4 = geom.Mat4;
var Ray = geom.Ray;
var Frustum = geom.Frustum;
var Plane = geom.Plane;

function PerspectiveCamera(fov, aspectRatio, near, far, position, target, up) {
  this.fov = fov || 60;
  this.aspectRatio = aspectRatio || 4 / 3;
  this.near = near || 0.1;
  this.far = far || 100;
  this.position = position || Vec3.create(0, 0, 5);
  this.target = target || Vec3.create(0, 0, 0);
  this.up = up || Vec3.create(0, 1, 0);
  this.projectionMatrix = Mat4.create();
  this.viewMatrix = Mat4.create();
  this.tmpProjected = new Vec4();
  this.updateMatrices();
}

PerspectiveCamera.prototype.getFov = function() {
  return this.fov;
};

PerspectiveCamera.prototype.getAspectRatio = function() {
  return this.aspectRatio;
};

PerspectiveCamera.prototype.getNear = function() {
  return this.near;
};

PerspectiveCamera.prototype.getFar = function() {
  return this.far;
};

PerspectiveCamera.prototype.getPosition = function() {
  return this.position;
};

PerspectiveCamera.prototype.getTarget = function() {
  return this.target;
};

PerspectiveCamera.prototype.getUp = function() {
  return this.up;
};

PerspectiveCamera.prototype.getViewMatrix = function() {
  return this.viewMatrix;
};

PerspectiveCamera.prototype.getProjectionMatrix = function() {
  return this.projectionMatrix;
};

PerspectiveCamera.prototype.setFov = function(fov) {
  this.fov = fov;
  this.updateMatrices();
};

PerspectiveCamera.prototype.setAspectRatio = function(ratio) {
  this.aspectRatio = ratio;
  this.updateMatrices();
};

PerspectiveCamera.prototype.setFar = function(far) {
  this.far = far;
  this.updateMatrices();
};

PerspectiveCamera.prototype.setNear = function(near) {
  this.near = near;
  this.updateMatrices();
};

PerspectiveCamera.prototype.setPosition = function(position) {
  this.position = position;
  this.updateMatrices();
};

PerspectiveCamera.prototype.setTarget = function(target) {
  this.target = target;
  this.updateMatrices();
};

PerspectiveCamera.prototype.setUp = function(up) {
  this.up = up;
  this.updateMatrices();
};

PerspectiveCamera.prototype.lookAt = function(target, eyePosition, up) {
  if (target) {
    this.target = target;
  }
  if (eyePosition) {
    this.position = eyePosition;
  }
  if (up) {
    this.up = up;
  }
  this.updateMatrices();
};

PerspectiveCamera.prototype.updateMatrices = function() {
  this.projectionMatrix.identity().perspective(this.fov, this.aspectRatio, this.near, this.far);
  this.viewMatrix.identity().lookAt(this.position, this.target, this.up);
};

PerspectiveCamera.prototype.getScreenPos = function(point, windowWidth, windowHeight) {
  this.tmpProjected.set(point.x, point.y, point.z, 1.0);
  this.tmpProjected.transformMat4(this.viewMatrix);
  this.tmpProjected.transformMat4(this.projectionMatrix);
  var out = Vec2.create().set(this.tmpProjected.x, this.tmpProjected.y);
  out.x /= this.tmpProjected.w;
  out.y /= this.tmpProjected.w;
  out.x = out.x * 0.5 + 0.5;
  out.y = 1.0 - (out.y * 0.5 + 0.5);
  out.x *= windowWidth;
  out.y *= windowHeight;
  return out;
};

PerspectiveCamera.prototype.getViewRay = function(x, y, windowWidth, windowHeight) {
  var px = (x - windowWidth / 2) / (windowWidth / 2);
  var py = -(y - windowHeight / 2) / (windowHeight / 2);
  var hNear = 2 * Math.tan(this.getFov() / 180 * Math.PI / 2) * this.getNear();
  var wNear = hNear * this.getAspectRatio();
  px *= wNear / 2;
  py *= hNear / 2;
  var vOrigin = new Vec3(0, 0, 0);
  var vTarget = new Vec3(px, py, -this.getNear());
  var vDirection = vTarget.dup().sub(vOrigin).normalize();
  return new Ray(vOrigin, vDirection);
};

PerspectiveCamera.prototype.getWorldRay = function(x, y, windowWidth, windowHeight) {
  x = (x - windowWidth / 2) / (windowWidth / 2);
  y = -(y - windowHeight / 2) / (windowHeight / 2);
  var hNear = 2 * Math.tan(this.getFov() / 180 * Math.PI / 2) * this.getNear();
  var wNear = hNear * this.getAspectRatio();
  x *= wNear / 2;
  y *= hNear / 2;
  var vOrigin = new Vec3(0, 0, 0);
  var vTarget = new Vec3(x, y, -this.getNear());
  var invViewMatrix = this.getViewMatrix().dup().invert();
  var wOrigin = vOrigin.dup().transformMat4(invViewMatrix);
  var wTarget = vTarget.dup().transformMat4(invViewMatrix);
  var wDirection = wTarget.dup().sub(wOrigin).normalize();
  return new Ray(wOrigin, wDirection);
};

PerspectiveCamera.prototype.getFrustumClippingPlanes = function() {
  var frustumNear = this.getNear();
  var frustumFar = this.getFar();
  var frustumTop = Math.tan(this.getFov() / 180 * Math.PI / 2) * frustumNear;
  var frustumRight = frustumTop * this.getAspectRatio();
  var frustumLeft = -frustumTop;
  var frustumBottom = -frustumLeft;

  var front = Vec3.create().asSub(this.getTarget(), this.getPosition()).normalize();
  var up = this.getUp().clone();
  var right = Vec3.create().asCross(front, up).normalize();

  var ntl = right.dup().scale(-frustumRight).add(up.dup().scale( frustumTop)).add(front.dup().scale(frustumNear));
  var ntr = right.dup().scale( frustumRight).add(up.dup().scale( frustumTop)).add(front.dup().scale(frustumNear));
  var nbr = right.dup().scale( frustumRight).add(up.dup().scale(-frustumTop)).add(front.dup().scale(frustumNear));
  var nbl = right.dup().scale(-frustumRight).add(up.dup().scale(-frustumTop)).add(front.dup().scale(frustumNear));

  var farNearRatio = frustumFar / frustumNear;

  var ftl = ntl.dup().scale(farNearRatio);
  var ftr = ntr.dup().scale(farNearRatio);
  var fbr = nbr.dup().scale(farNearRatio);
  var fbl = nbl.dup().scale(farNearRatio);

  ntl.add(this.position);
  ntr.add(this.position);
  nbr.add(this.position);
  nbl.add(this.position);

  ftl.add(this.position);
  ftr.add(this.position);
  fbr.add(this.position);
  fbl.add(this.position);

  var clippingPlanes = [
    Plane.fromPoints(ntr, ntl, ftl),
    Plane.fromPoints(nbl, nbr, fbr),
    Plane.fromPoints(ntl, nbl, fbl),
    Plane.fromPoints(ftr, fbr, nbr),
    Plane.fromPoints(ntl, ntr, nbr),
    Plane.fromPoints(ftr, ftl, fbl)
  ];

  return clippingPlanes;
}

PerspectiveCamera.prototype.getFrustum = function() {
  return new Frustum(this.getFrustumClippingPlanes());
}

module.exports = PerspectiveCamera;
<|endoftext|>


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

    var myAppModule = angular.module(
        'myApp',
        [
            'ngRoute',
            'ui.bootstrap'
        ]);

    myAppModule.config([
        '$routeProvider', function ($routeProvider) {
            $routeProvider.when('/', { templateUrl: 'scripts/app/views/default.html' });
            $routeProvider.when('/bicycles', { templateUrl: 'scripts/app/views/bicyclesIndex.html' });
            $routeProvider.when('/customers', { templateUrl: 'scripts/app/views/customersIndex.html' });
            $routeProvider.when('/rentals', { templateUrl: 'scripts/app/views/rentalsIndex.html' });
        }
    ]);

})();<commit_msg>changed routing to fluent API<commit_after>(function () {
    "use strict";

    var myAppModule = angular.module(
        'myApp',
        [
            'ngRoute',
            'ui.bootstrap'
        ]);

    myAppModule.config([
        '$routeProvider', function ($routeProvider) {
            $routeProvider
                .when('/', { templateUrl: 'scripts/app/views/default.html' })
                .when('/bicycles', { templateUrl: 'scripts/app/views/bicyclesIndex.html' })
                .when('/customers', { templateUrl: 'scripts/app/views/customersIndex.html' })
                .when('/rentals', { templateUrl: 'scripts/app/views/rentalsIndex.html' });
        }
    ]);

})();<|endoftext|>


<commit_before>import React, {Component} from 'react';
import classNames from 'classnames';

import {Form, TextInput, RadioButton, Checkbox, Button, Select} from 'react-chloroform';
import styles from './app.module.css';

class App extends Component {
  handleSubmit = model => {
    console.log(model);
  };

  render() {
    const initalState = {
      email: 'bla@bla.is',
      name: 'darri',
    };

    const options = [
      {
        name: 'Darri',
        value: 'darri',
      },
      {
        name: 'Steinn',
        value: 'steinn',
      },
      {
        name: 'Konn',
        value: 'konn',
      },
      {
        name: 'Konradsson',
        value: 'konradsson',
      },
    ];

    return (

React Chloroform

          <Form initialState={initalState} onSubmit={this.handleSubmit}>
            Email:
            <TextInput name="email" id="email" label="email" />

              Name:
              <TextInput name="name" id="name" placeholder="name" />

            Age
            <Checkbox name="age" id="age" />

              Yes
              <RadioButton name="darrmundur" id="darrmundur1" value="true" />

              No
              <RadioButton name="darrmundur" id="darrmundur2" value="false" />

              <Select
                name="wabbalabbadubdub"
                options={options}
                placeholder="Choose your option"
              />

              <Select
                name="rickandmorty"
                options={options}
                initialValue="darri"
              />

            <Button type="submit" text="Submit" className={classNames(styles.root, styles.button)} />
          </Form>

    );
  }
}

export default App;
<commit_msg>Use validator api in example<commit_after>import React, {Component} from 'react';
import classNames from 'classnames';

import {Form, TextInput, RadioButton, Checkbox, Button, Select} from 'react-chloroform';
import styles from './app.module.css';

class App extends Component {
  handleSubmit = model => {
    console.log(model);
  };

  render() {
    const initalState = {
      email: 'bla@bla.is',
      name: 'darri',
    };

    const options = [
      {
        name: 'Darri',
        value: 'darri',
      },
      {
        name: 'Steinn',
        value: 'steinn',
      },
      {
        name: 'Konn',
        value: 'konn',
      },
      {
        name: 'Konradsson',
        value: 'konradsson',
      },
    ];

    return (

React Chloroform

          <Form initialState={initalState} onSubmit={this.handleSubmit}>
            Email:
            <TextInput
              name="email"
              id="email"
              label="email"
              validator={[
                val => val === 'darri' && `Do not prump me with "${val}"`,
                val => val.length === 5 && 'shit not me',
              ]}
            />

              Name:
              <TextInput
                name="name"
                id="name"
                placeholder="name"
                validator={[
                  val => val === 'darri' && `Do not rump me with "${val}"`,
                  val => val.length === 5 && 'shit not me',
                ]}
              />

            Age
            <Checkbox name="age" id="age" />

              Yes
              <RadioButton name="darrmundur" id="darrmundur1" value="true" />

              No
              <RadioButton name="darrmundur" id="darrmundur2" value="false" />

              <Select
                name="wabbalabbadubdub"
                options={options}
                placeholder="Choose your option"
              />

              <Select
                name="rickandmorty"
                options={options}
                initialValue="darri"
              />

            <Button type="submit" text="Submit" className={classNames(styles.root, styles.button)} />
          </Form>

    );
  }
}

export default App;
<|endoftext|>


<commit_before>//= require_self
//= require_tree ../spree/helpers
//= require_tree ../spree/models
//= require_tree ../spree/apps/store
//= require_tree ../spree/apps/cart
//= require_tree ../spree/apps/checkout
//= require_tree ../spree/apps/orders
//= require_tree ../spree/apps/taxonomies/list
//= require_tree ../spree/apps/taxonomies/show
//= require_tree ../spree/apps/products/list
//= require_tree ../spree/apps/products/show
Spree = {}
SpreeStore = new Backbone.Marionette.Application()
SpreeStore.currentOrderId = window.localStorage['currentOrderId']
SpreeStore.currentOrderToken = window.localStorage['currentOrderToken']

SpreeStore.MainRegion = Backbone.Marionette.Region.extend({
  el: '.fast-freddy'
});

SpreeStore.Sidebar = Backbone.Marionette.Region.extend({
  el: '#sidebar'
});

SpreeStore.addRegions({
    mainRegion: SpreeStore.MainRegion,
    cartInfo: '#link-to-cart',
    sidebar: SpreeStore.Sidebar,
    cart: "#cart"
});

SpreeStore.noSidebar = function() {
  SpreeStore.sidebar.close();
  $('#content').attr('class', 'columns sixteen');
}

SpreeStore.navigate = function(route, options) {
  options || (options = {});
  Backbone.history.navigate(route, options)
}

SpreeStore.getCurrentRoute = function() {
  return Backbone.history.fragment;
}

SpreeStore.on("initialize:before", function(){
  $.get('/store/api/config/money', function(data) {
    Spree.Money.Settings = data
  })

  $.get('/store/api/config', function(data) {
    Spree.Settings = data
  })
})

SpreeStore.on("initialize:after", function(){
  if (Backbone.history) {
    Backbone.history.start();
  }
  if (this.getCurrentRoute() === "") {
    SpreeStore.trigger("products:list")
  }
});
<commit_msg>Run config AJAX requests non-asynchronously to ensure data is loaded when necessary<commit_after>//= require_self
//= require_tree ../spree/helpers
//= require_tree ../spree/models
//= require_tree ../spree/apps/store
//= require_tree ../spree/apps/cart
//= require_tree ../spree/apps/checkout
//= require_tree ../spree/apps/orders
//= require_tree ../spree/apps/taxonomies/list
//= require_tree ../spree/apps/taxonomies/show
//= require_tree ../spree/apps/products/list
//= require_tree ../spree/apps/products/show
Spree = {}
SpreeStore = new Backbone.Marionette.Application()
SpreeStore.currentOrderId = window.localStorage['currentOrderId']
SpreeStore.currentOrderToken = window.localStorage['currentOrderToken']

SpreeStore.MainRegion = Backbone.Marionette.Region.extend({
  el: '.fast-freddy'
});

SpreeStore.Sidebar = Backbone.Marionette.Region.extend({
  el: '#sidebar'
});

SpreeStore.addRegions({
    mainRegion: SpreeStore.MainRegion,
    cartInfo: '#link-to-cart',
    sidebar: SpreeStore.Sidebar,
    cart: "#cart"
});

SpreeStore.noSidebar = function() {
  SpreeStore.sidebar.close();
  $('#content').attr('class', 'columns sixteen');
}

SpreeStore.navigate = function(route, options) {
  options || (options = {});
  Backbone.history.navigate(route, options)
}

SpreeStore.getCurrentRoute = function() {
  return Backbone.history.fragment;
}

SpreeStore.on("initialize:before", function(){
  $.ajax({
    async: false,
    url: '/store/api/config/money',
    success: function(data) {
      Spree.Money.Settings = data
    }
  })

  $.ajax({
    async: false,
    url: '/store/api/config/',
    success: function(data) {
      Spree.Settings = data
    }
  })
})

SpreeStore.on("initialize:after", function(){
  if (Backbone.history) {
    Backbone.history.start();
  }
  if (this.getCurrentRoute() === "") {
    SpreeStore.trigger("products:list")
  }
});
<|endoftext|>


<commit_before>/*! skrollr-menu 0.1.0 (2013-05-18) | Alexander Prinzhorn - https://github.com/Prinzhorn/skrollr-menu | Free to use under terms of MIT license */
(function(t,e){"use strict";var n=500,r="sqrt",a="data-menu-top",i=e.skrollr,o=function(e){return"A"===e.tagName?e:e===t?!1:o(e.parentNode)},u=function(e){var n=o(e.target);if(n){var r=n.getAttribute("href");if(!/^#/.test(r)){var i;if(n.hasAttribute(a))i=+n.getAttribute(a);else{var u=t.getElementById(r.substr(1));if(!u)return;i=s.relativeToAbsolute(u,"top","top")}f?s.animateTo(i,{duration:c,easing:l}):s.setScrollTop(i),e.preventDefault()}}};i.menu={},i.menu.init=function(e,a){s=e,a=a||{},c=a.duration||n,l=a.easing||r,f=a.animate!==!1,i.addEvent(t,"click",u)};var s,l,c,f;e.setTimeout(function(){e.location.hash&&e.scrollTo(0,0)},1)})(document,window);<commit_msg>handle the case when the element has no href attribute<commit_after>/*! skrollr-menu 0.1.1 (2013-05-18) | Alexander Prinzhorn - https://github.com/Prinzhorn/skrollr-menu | Free to use under terms of MIT license */
(function(t,e){"use strict";var n=500,r="sqrt",a="data-menu-top",i=e.skrollr,o=function(e){return"A"===e.tagName?e:e===t?!1:o(e.parentNode)},u=function(e){var n=o(e.target);if(n){var r=n.getAttribute("href");if(!/^#/.test(r)){var i;if(n.hasAttribute(a))i=+n.getAttribute(a);else{var u=t.getElementById(r.substr(1));if(!u)return;i=s.relativeToAbsolute(u,"top","top")}f?s.animateTo(i,{duration:c,easing:l}):s.setScrollTop(i),e.preventDefault()}}};i.menu={},i.menu.init=function(e,a){s=e,a=a||{},c=a.duration||n,l=a.easing||r,f=a.animate!==!1,i.addEvent(t,"click",u)};var s,l,c,f;e.setTimeout(function(){e.location.hash&&e.scrollTo(0,0)},1)})(document,window);<|endoftext|>


<commit_before>
  command: 'curl -s "http://legacy.cafebonappetit.com/api/2/menus?cafe=261"',
  refreshFrequency: 6000000,

  render: function(output) {
    return [
        '

',
        '

',
        '

',
        '

',
    ].join('')
  },

  update: function(output, domEl) {

    function createOutputString(okItems){
        var str = "";
        for(var i = 0; i < okItems.length; i++){
            str+= okItems[i]+"

";
        }
        return str;
    }

    function parseDate(x){
        var m,d,y;
        y=x.substr(0,4);
        m=x.substr(5,2);
        d=x.substr(8,2);

        var rawToday = new Date(y+"-"+m+"-"+d);
        var offsetDate = Date(rawToday - rawToday.getTimezoneOffset());
        var todayDate = new Date(offsetDate).toString();
        var today = todayDate.substr(0,10);

        return today.toString();
    }

    function parseMenu(menu){
        // enum object to map diets to numbers
        var diets = {
            "FTF"   : 6, // farm to fork
            "GF"    : 9, // gluten free
            "VEG"   : 1, // vegetarian
            "VEGAN" : 4, // vegan
        };

        // your selected diets
        var preferredDiet = diets.GF;

        console.log ("menu: ")
        console.log(arguments);

        var okItems = [];
        var prevStation = "";

        for(var prop in menu){
            var item = "";
            // looping through the properties on an element
            if(menu.hasOwnProperty(prop)){
                // Icon (filtering dietary restrictions)
                if(menu[prop].cor_icon.hasOwnProperty(preferredDiet)){
                    // Station
                    if(menu[prop].station != prevStation){
                        // clean station string
                        item = cleanUpStationLabel(menu[prop].station + "
");
                        // push food label next to the station
                        item += "⚬ " + capitalizeStr(menu[prop].label, 0, 1);
                        // the previous station
                        prevStation = menu[prop].station;
                    }
                    // same station with more items
                    else {
                        // the served food item
                        item = "⚬ " + capitalizeStr(menu[prop].label, 0, 1);
                        // the previous station
                        prevStation = menu[prop].station;
                    }

                    // add it
                    okItems.push(item);
                }
            }
        }
        // Handle update on Mondays and 0 results
        if(okItems.length === 0) {
            // Body
            okItems.push("0 menu items found...");

            // Footer
            var theDay = new Date().getDay();
            if(theDay === 1) {
                var footer = document.getElementById("footer");
                footer.innerHTML = "*Note: the menu usually updates on Mondays";
            }
        }

        return okItems;
    }

    function cleanUpStationLabel(theStation) {
        // replace the @ symbol
        var cleanString = theStation.replace("@", "");
        // capitalize first letter
        var capitalizedStr = capitalizeStr(cleanString, 8, 9);
        // add back in the bold formatting
        capitalizedStr = "" + capitalizedStr + "";

        return capitalizedStr;
    }

    var dom,
     theDate,
     theMenu,
     title,
     jstringObj,
     outputString;

    dom = $(domEl);
    jstringObj = JSON.parse(output);
    theDate= parseDate(jstringObj.days[0].date);
    theMenu= jstringObj.items;
    var friendly= parseMenu(theMenu);
    outputString= createOutputString(friendly);

    title = "Stav Hall Menu";

    //Output
    dom.find(widgetTitle).html(title);
    dom.find(date).html(theDate);
    dom.find(food).html(outputString);
  },

  style: [
    "top: 20px",
    "left: 40px",
    "width:400px",
    "margin:0px",
    "padding:0px",
    "background:rgba(#FFF, 0.5)",
    "border:2px solid rgba(#000, 0.5)",
    "border-radius:10px",
    "overflow:hidden",

    "#date",
    "  margin:12pt",
    "  margin-bottom:12pt",
    "  font-family: Helvetica",
    "  font-size: 25pt",
    "  font-weight:bold",
    "  color: rgba(128,0,0,0.75)",

    "#title",
    "  margin-left:50pt",
    "  margin-right:12pt",
    "  font-family: American Typewriter",
    "  font-size: 20pt",
    "  font-weight:bold",

    "#description",
    "  margin-left:12pt",
    "  margin-right:12pt",
    "  font-family: American Typewriter",
    "  font-size: 12pt",
    "  line-height:18pt",
    "  max-height:10pt",
    "  overflow:hidden",
    "  hyphens: auto",

    "#food",
    "  height: 350px",

    "#footer",
    "  font-family: Helvetica",
    "  font-size: 9pt",
    "  margin:12pt",
    "  color: rgba(#000, 0.5)",

    "p",
    "  margin: 0 0 0 20px",

    ".e",
    "  margin-top: -40px",
    "  margin-left: 20px",
    "  height: 60pt",

    ".event",
    "  font-size: 17pt",
    "  font-weight: bold",
    ].join('\n')
<commit_msg>Change height to auto<commit_after>
  command: 'curl -s "http://legacy.cafebonappetit.com/api/2/menus?cafe=261"',
  refreshFrequency: 6000000,

  render: function(output) {
    return [
        '

',
        '

',
        '

',
        '

',
    ].join('')
  },

  update: function(output, domEl) {

    function createOutputString(okItems){
        var str = "";
        for(var i = 0; i < okItems.length; i++){
            str+= okItems[i]+"

";
        }
        return str;
    }

    function parseDate(x){
        var m,d,y;
        y=x.substr(0,4);
        m=x.substr(5,2);
        d=x.substr(8,2);

        var rawToday = new Date(y+"-"+m+"-"+d);
        var offsetDate = Date(rawToday - rawToday.getTimezoneOffset());
        var todayDate = new Date(offsetDate).toString();
        var today = todayDate.substr(0,10);

        return today.toString();
    }

    function parseMenu(menu){
        // enum object to map diets to numbers
        var diets = {
            "FTF"   : 6, // farm to fork
            "GF"    : 9, // gluten free
            "VEG"   : 1, // vegetarian
            "VEGAN" : 4, // vegan
        };

        // your selected diets
        var preferredDiet = diets.GF;

        console.log ("menu: ")
        console.log(arguments);

        var okItems = [];
        var prevStation = "";

        for(var prop in menu){
            var item = "";
            // looping through the properties on an element
            if(menu.hasOwnProperty(prop)){
                // Icon (filtering dietary restrictions)
                if(menu[prop].cor_icon.hasOwnProperty(preferredDiet)){
                    // Station
                    if(menu[prop].station != prevStation){
                        // clean station string
                        item = cleanUpStationLabel(menu[prop].station + "
");
                        // push food label next to the station
                        item += "⚬ " + capitalizeStr(menu[prop].label, 0, 1);
                        // the previous station
                        prevStation = menu[prop].station;
                    }
                    // same station with more items
                    else {
                        // the served food item
                        item = "⚬ " + capitalizeStr(menu[prop].label, 0, 1);
                        // the previous station
                        prevStation = menu[prop].station;
                    }

                    // add it
                    okItems.push(item);
                }
            }
        }
        // Handle update on Mondays and 0 results
        if(okItems.length === 0) {
            // Body
            okItems.push("0 menu items found...");

            // Footer
            var theDay = new Date().getDay();
            if(theDay === 1) {
                var footer = document.getElementById("footer");
                footer.innerHTML = "*Note: the menu usually updates on Mondays";
            }
        }

        return okItems;
    }

    function cleanUpStationLabel(theStation) {
        // replace the @ symbol
        var cleanString = theStation.replace("@", "");
        // capitalize first letter
        var capitalizedStr = capitalizeStr(cleanString, 8, 9);
        // add back in the bold formatting
        capitalizedStr = "" + capitalizedStr + "";

        return capitalizedStr;
    }

    var dom,
     theDate,
     theMenu,
     title,
     jstringObj,
     outputString;

    dom = $(domEl);
    jstringObj = JSON.parse(output);
    theDate= parseDate(jstringObj.days[0].date);
    theMenu= jstringObj.items;
    var friendly= parseMenu(theMenu);
    outputString= createOutputString(friendly);

    title = "Stav Hall Menu";

    //Output
    dom.find(widgetTitle).html(title);
    dom.find(date).html(theDate);
    dom.find(food).html(outputString);
  },

  style: [
    "top: 20px",
    "left: 40px",
    "width:400px",
    "margin:0px",
    "padding:0px",
    "background:rgba(#FFF, 0.5)",
    "border:2px solid rgba(#000, 0.5)",
    "border-radius:10px",
    "overflow:hidden",

    "#date",
    "  margin:12pt",
    "  margin-bottom:12pt",
    "  font-family: Helvetica",
    "  font-size: 25pt",
    "  font-weight:bold",
    "  color: rgba(128,0,0,0.75)",

    "#title",
    "  margin-left:50pt",
    "  margin-right:12pt",
    "  font-family: American Typewriter",
    "  font-size: 20pt",
    "  font-weight:bold",

    "#description",
    "  margin-left:12pt",
    "  margin-right:12pt",
    "  font-family: American Typewriter",
    "  font-size: 12pt",
    "  line-height:18pt",
    "  max-height:10pt",
    "  overflow:hidden",
    "  hyphens: auto",

    "#food",
    "  height: auto",

    "#footer",
    "  font-family: Helvetica",
    "  font-size: 9pt",
    "  margin:12pt",
    "  color: rgba(#000, 0.5)",

    "p",
    "  margin: 0 0 0 20px",

    ".e",
    "  margin-top: -40px",
    "  margin-left: 20px",
    "  height: 60pt",

    ".event",
    "  font-size: 17pt",
    "  font-weight: bold",
    ].join('\n')
<|endoftext|>


<commit_before>/* kate-script
* author: Gregor Petrin
* license: BSD
* revision: 1
* kate-version: 3.4
* type: commands
* functions: emmetExpand, emmetWrap, emmetSelectTagPairInwards, emmetSelectTagPairOutwards, emmetMatchingPair, emmetToggleComment ,emmetNext, emmetPrev, emmetSelectNext, emmetSelectPrev, emmetDelete, emmetSplitJoinTab, emmetEvaluateMathExpression, emmetDecrementNumberBy1, emmetDecrementNumberBy10, emmetDecrementNumberBy01, emmetIncrementNumberBy1, emmetIncrementNumberBy10, emmetIncrementNumberBy01
*
*/

function help(cmd)
{
	cmds = {
		"emmetExpand" : "Expands the abbreviation using Emmet expressions; see http://code.google.com/p/zen-coding/wiki/ZenHTMLSelectorsEn",
		"emmetWrap" : "Wraps the selected text in XML tags constructed from the provided Emmet expression (defaults to div).",
		"emmetMatchingPair" : "Moves the caret to the current tag's pair",
		"emmetSelectTagPairInwards" : "Select contents of HTML/XML tag, moving inward on continious invocations",
		"emmetSelectTagPairOutwards" : "Select contents of HTML/XML tag, moving outwards on continious invocations",
		"emmetNext" : "Move to the next edit point (tag or empty attribute).",
		"emmetPrev" : "Move to the previous edit point (tag or empty attribute).",
		"emmetSelectNext" : "Select next edit point (tag or empty attribute).",
		"emmetSelectPrev" : "Select previous edit point (tag or empty attribute).",
		"emmetToggleComment" : "Toggle comment of current tag or CSS selector",
		"emmetDelete" : "Deletes tag under cursor",
		"emmetSplitJoinTab" : "Splits or joins a tag",
		"emmetEvaluateMathExpression" : "Evaluates a simple math expression",
		"emmetDecrementNumberBy1" : "Decrement number under cursor by 1",
		"emmetDecrementNumberBy10" : "Decrement number under cursor by 10",
		"emmetDecrementNumberBy01" : "Decrement number under cursor by 0.1",
		"emmetIncrementNumberBy1" : "Increment number under cursor by 1",
		"emmetIncrementNumberBy10" : "Increment number under cursor by 10",
		"emmetIncrementNumberBy01" : "Increment number under cursor by 0.1"
	}
	return i18n(cmds[cmd]);
}

function action(cmd)
{
		var a = new Object();
		a.icon = "";
		a.category = "";
		a.shortcut = "";
			a.interactive = false;
		if (cmd == "emmetExpand") {
				a.text = i18n("Emmet: expand abbreviation");
		} else if (cmd == "emmetWrap") {
			a.text = i18n("Emmet: wrap with tag");
			a.interactive = true;
		} else if (cmd == "emmetMatchingPair") {
			a.text = i18n("Emmet: move cursor to matching tag");
		} else if (cmd == "emmetSelectTagPairInwards") {
			a.text = i18n("Emmet: select HTML/XML tag contents inwards");
		} else if (cmd == "emmetSelectTagPairOutwards") {
			a.text = i18n("Emmet: select HTML/XML tag contents outwards");
		} else if (cmd == "emmetToggleComment") {
			a.text = i18n("Emmet: toggle comment");
		} else if (cmd == "emmetNext") {
			a.text = i18n("Emmet: go to next edit point");
		} else if (cmd == "emmetPrev") {
			a.text = i18n("Emmet: go to previous edit point");
		} else if (cmd == "emmetSelectNext") {
			a.text = i18n("Emmet: select next edit point");
		} else if (cmd == "emmetSelectPrev") {
			a.text = i18n("Emmet: select previous edit point");
		} else if (cmd == "emmetDelete") {
			a.text = i18n("Emmet: delete tag under cursor");
		} else if (cmd == "emmetSplitJoinTab") {
			a.text = i18n("Emmet: split or join a tag");
		} else if (cmd == "emmetEvaluateMathExpression") {
			a.text = i18n("Emmet: evaluate a simple math expression");
		} else if (cmd == "emmetDecrementNumberBy1") {
			a.text = i18n("Emmet: decrement number by 1");
		} else if (cmd == "emmetDecrementNumberBy10") {
			a.text = i18n("Emmet: decrement number by 10");
		} else if (cmd == "emmetDecrementNumberBy01") {
			a.text = i18n("Emmet: decrement number by 0.1");
		} else if (cmd == "emmetIncrementNumberBy1") {
			a.text = i18n("Emmet: increment number by 1");
		} else if (cmd == "emmetIncrementNumberBy10") {
			a.text = i18n("Emmet: increment number by 10");
		} else if (cmd == "emmetIncrementNumberBy01") {
			a.text = i18n("Emmet: increment number by 0.1");
		}
		return a;
}

//Returns the kate editor interface
function getInterface() {
	var kateInterface = new zen_editor(document, view);
	return kateInterface;
}

function emmetExpand() {
	emmet.require('actions').run('expand_abbreviation', getInterface());
}

// Wraps the selection with a given tag (command line only, otherwise div is used as we can't prompt for input).
function emmetWrap(par) {
	emmet.require('actions').run('wrap_with_abbreviation', getInterface(), par || 'div');
}

function emmetMatchingPair() {
	emmet.require('actions').run('matching_pair', getInterface());
}

function emmetSelectTagPairInwards() {
	emmet.require('actions').run('match_pair', getInterface());
}

function emmetSelectTagPairOutwards() {
	emmet.require('actions').run('match_pair', getInterface());
}

function emmetNext() {
	emmet.require('actions').run('next_edit_point', getInterface());
}

function emmetPrev() {
	emmet.require('actions').run('prev_edit_point', getInterface());
}

function emmetSelectNext() {
	emmet.require('actions').run('select_next_item', getInterface());
}

function emmetSelectPrev() {
	emmet.require('actions').run('select_previous_item', getInterface());
}

function emmetToggleComment() {
	emmet.require('actions').run('toggle_comment', getInterface());
}

function emmetDelete() {
	emmet.require('actions').run('remove_tag', getInterface());
}

function emmetSplitJoinTab() {
	emmet.require('actions').run('split_join_tag', getInterface());
}

function emmetEvaluateMathExpression() {
	emmet.require('actions').run('evaluate_math_expression', getInterface());
}

function emmetIncrementNumberBy1() {
	emmet.require('actions').run('increment_number_by_1', getInterface());
}

function emmetIncrementNumberBy10() {
	emmet.require('actions').run('increment_number_by_10', getInterface());
}

function emmetIncrementNumberBy01() {
	emmet.require('actions').run('increment_number_by_01', getInterface());
}

function emmetDecrementNumberBy1() {
	emmet.require('actions').run('decrement_number_by_1', getInterface());
}

function emmetDecrementNumberBy10() {
	emmet.require('actions').run('decrement_number_by_10', getInterface());
}

function emmetDecrementNumberBy01() {
	emmet.require('actions').run('decrement_number_by_01', getInterface());
}

/*
select_next_item: [object Object]
select_previous_item: [object Object]
*/<commit_msg>Removed some commented out code and a superfluous comment<commit_after>/* kate-script
* author: Gregor Petrin
* license: BSD
* revision: 1
* kate-version: 3.4
* type: commands
* functions: emmetExpand, emmetWrap, emmetSelectTagPairInwards, emmetSelectTagPairOutwards, emmetMatchingPair, emmetToggleComment ,emmetNext, emmetPrev, emmetSelectNext, emmetSelectPrev, emmetDelete, emmetSplitJoinTab, emmetEvaluateMathExpression, emmetDecrementNumberBy1, emmetDecrementNumberBy10, emmetDecrementNumberBy01, emmetIncrementNumberBy1, emmetIncrementNumberBy10, emmetIncrementNumberBy01
*
*/

function help(cmd)
{
	cmds = {
		"emmetExpand" : "Expands the abbreviation using Emmet expressions; see http://code.google.com/p/zen-coding/wiki/ZenHTMLSelectorsEn",
		"emmetWrap" : "Wraps the selected text in XML tags constructed from the provided Emmet expression (defaults to div).",
		"emmetMatchingPair" : "Moves the caret to the current tag's pair",
		"emmetSelectTagPairInwards" : "Select contents of HTML/XML tag, moving inward on continious invocations",
		"emmetSelectTagPairOutwards" : "Select contents of HTML/XML tag, moving outwards on continious invocations",
		"emmetNext" : "Move to the next edit point (tag or empty attribute).",
		"emmetPrev" : "Move to the previous edit point (tag or empty attribute).",
		"emmetSelectNext" : "Select next edit point (tag or empty attribute).",
		"emmetSelectPrev" : "Select previous edit point (tag or empty attribute).",
		"emmetToggleComment" : "Toggle comment of current tag or CSS selector",
		"emmetDelete" : "Deletes tag under cursor",
		"emmetSplitJoinTab" : "Splits or joins a tag",
		"emmetEvaluateMathExpression" : "Evaluates a simple math expression",
		"emmetDecrementNumberBy1" : "Decrement number under cursor by 1",
		"emmetDecrementNumberBy10" : "Decrement number under cursor by 10",
		"emmetDecrementNumberBy01" : "Decrement number under cursor by 0.1",
		"emmetIncrementNumberBy1" : "Increment number under cursor by 1",
		"emmetIncrementNumberBy10" : "Increment number under cursor by 10",
		"emmetIncrementNumberBy01" : "Increment number under cursor by 0.1"
	}
	return i18n(cmds[cmd]);
}

function action(cmd)
{
		var a = new Object();
		a.icon = "";
		a.category = "";
		a.shortcut = "";
			a.interactive = false;
		if (cmd == "emmetExpand") {
				a.text = i18n("Emmet: expand abbreviation");
		} else if (cmd == "emmetWrap") {
			a.text = i18n("Emmet: wrap with tag");
			a.interactive = true;
		} else if (cmd == "emmetMatchingPair") {
			a.text = i18n("Emmet: move cursor to matching tag");
		} else if (cmd == "emmetSelectTagPairInwards") {
			a.text = i18n("Emmet: select HTML/XML tag contents inwards");
		} else if (cmd == "emmetSelectTagPairOutwards") {
			a.text = i18n("Emmet: select HTML/XML tag contents outwards");
		} else if (cmd == "emmetToggleComment") {
			a.text = i18n("Emmet: toggle comment");
		} else if (cmd == "emmetNext") {
			a.text = i18n("Emmet: go to next edit point");
		} else if (cmd == "emmetPrev") {
			a.text = i18n("Emmet: go to previous edit point");
		} else if (cmd == "emmetSelectNext") {
			a.text = i18n("Emmet: select next edit point");
		} else if (cmd == "emmetSelectPrev") {
			a.text = i18n("Emmet: select previous edit point");
		} else if (cmd == "emmetDelete") {
			a.text = i18n("Emmet: delete tag under cursor");
		} else if (cmd == "emmetSplitJoinTab") {
			a.text = i18n("Emmet: split or join a tag");
		} else if (cmd == "emmetEvaluateMathExpression") {
			a.text = i18n("Emmet: evaluate a simple math expression");
		} else if (cmd == "emmetDecrementNumberBy1") {
			a.text = i18n("Emmet: decrement number by 1");
		} else if (cmd == "emmetDecrementNumberBy10") {
			a.text = i18n("Emmet: decrement number by 10");
		} else if (cmd == "emmetDecrementNumberBy01") {
			a.text = i18n("Emmet: decrement number by 0.1");
		} else if (cmd == "emmetIncrementNumberBy1") {
			a.text = i18n("Emmet: increment number by 1");
		} else if (cmd == "emmetIncrementNumberBy10") {
			a.text = i18n("Emmet: increment number by 10");
		} else if (cmd == "emmetIncrementNumberBy01") {
			a.text = i18n("Emmet: increment number by 0.1");
		}
		return a;
}

//Returns the kate editor interface
function getInterface() {
	var kateInterface = new zen_editor(document, view);
	return kateInterface;
}

function emmetExpand() {
	emmet.require('actions').run('expand_abbreviation', getInterface());
}

function emmetWrap(par) {
	emmet.require('actions').run('wrap_with_abbreviation', getInterface(), par || 'div');
}

function emmetMatchingPair() {
	emmet.require('actions').run('matching_pair', getInterface());
}

function emmetSelectTagPairInwards() {
	emmet.require('actions').run('match_pair', getInterface());
}

function emmetSelectTagPairOutwards() {
	emmet.require('actions').run('match_pair', getInterface());
}

function emmetNext() {
	emmet.require('actions').run('next_edit_point', getInterface());
}

function emmetPrev() {
	emmet.require('actions').run('prev_edit_point', getInterface());
}

function emmetSelectNext() {
	emmet.require('actions').run('select_next_item', getInterface());
}

function emmetSelectPrev() {
	emmet.require('actions').run('select_previous_item', getInterface());
}

function emmetToggleComment() {
	emmet.require('actions').run('toggle_comment', getInterface());
}

function emmetDelete() {
	emmet.require('actions').run('remove_tag', getInterface());
}

function emmetSplitJoinTab() {
	emmet.require('actions').run('split_join_tag', getInterface());
}

function emmetEvaluateMathExpression() {
	emmet.require('actions').run('evaluate_math_expression', getInterface());
}

function emmetIncrementNumberBy1() {
	emmet.require('actions').run('increment_number_by_1', getInterface());
}

function emmetIncrementNumberBy10() {
	emmet.require('actions').run('increment_number_by_10', getInterface());
}

function emmetIncrementNumberBy01() {
	emmet.require('actions').run('increment_number_by_01', getInterface());
}

function emmetDecrementNumberBy1() {
	emmet.require('actions').run('decrement_number_by_1', getInterface());
}

function emmetDecrementNumberBy10() {
	emmet.require('actions').run('decrement_number_by_10', getInterface());
}

function emmetDecrementNumberBy01() {
	emmet.require('actions').run('decrement_number_by_01', getInterface());
}<|endoftext|>


<commit_before>import { Popover, PopoverInteractionKind, Position } from "@blueprintjs/core"
import { resetPagination, SEARCH_OBJECT_LABELS, setSearchQuery } from "actions"
import AdvancedSearch from "components/AdvancedSearch"
import { SearchDescription } from "components/SearchFilters"
import _isEqual from "lodash/isEqual"
import PropTypes from "prop-types"
import React, { useEffect, useRef, useState } from "react"
import { Button, Form, FormControl, InputGroup } from "react-bootstrap"
import { connect } from "react-redux"
import { useHistory } from "react-router-dom"
import SEARCH_ICON from "resources/search-alt.png"

import { Popover, Position, PopoverInteractionKind } from "@blueprintjs/core"

export class SearchPopover extends PureComponent {
  constructor(props) {
    super(props)
    this.state = {
      isOpen: false
    }
  }

  render() {
    const { isOpen } = this.state
    const { popoverContent, children } = this.props
    return (
      <Popover
        isOpen={isOpen}
        onInteraction={this._handleInteraction}
        boundary="window"
        captureDismiss
        content={popoverContent}
        interactionKind={PopoverInteractionKind.CLICK}
        position={Position.BOTTOM_LEFT}
        usePortal={false}
        modifiers={{
          preventOverflow: {
            enabled: false
          },
          flip: {
            enabled: false
          }
        }}
      >
        {children}
      </Popover>
    )
  }
  _handleInteraction = isOpen => this.setState({ isOpen })
}

SearchPopover.propTypes = {
  popoverContent: PropTypes.element.isRequired,
  children: PropTypes.any.isRequired
}

const SearchBar = props => {
  const {
    query,
    searchObjectTypes,
    resetPagination,
    setSearchQuery,
    onSearchGoToSearchPage
  } = props
  const history = useHistory()
  // (Re)set searchTerms if the query.text prop changes
  const latestQueryText = useRef(query.text)
  const queryTextUnchanged = _isEqual(latestQueryText.current, query.text)
  const [searchTerms, setSearchTerms] = useState(query.text)
  const [showAdvancedSearch, setShowAdvancedSearch] = useState(false)

  useEffect(() => {
    if (!queryTextUnchanged) {
      latestQueryText.current = query.text
      setSearchTerms(query.text)
    }
  }, [query, setSearchTerms, queryTextUnchanged])

  const placeholder = query.objectType
    ? "Filter " + SEARCH_OBJECT_LABELS[query.objectType]
    : "Search for " +
      searchObjectTypes.map(type => SEARCH_OBJECT_LABELS[type]).join(", ")

  const PopoverContent = (
    <AdvancedSearch
      onSearch={runAdvancedSearch}
      onCancel={setShowAdvancedSearch}
      text={searchTerms}
    />
  )
  return (

      <Form onSubmit={onSubmit} className="advanced-search-form">
        <InputGroup>
          <FormControl
            value={searchTerms}
            placeholder={placeholder}
            onChange={onChange}
            id="searchBarInput"
          />
          {!showAdvancedSearch && (
            <InputGroup.Button>
              <Button onClick={onSubmit} id="searchBarSubmit">

              </Button>
            </InputGroup.Button>
          )}
        </InputGroup>
      </Form>
      <SearchPopover popoverContent={PopoverContent}>
        <SearchDescription query={query} showPlaceholders />
      </SearchPopover>

  )

  function onChange(event) {
    setSearchTerms(event.target.value)
  }

  function onSubmit(event) {
    if (!showAdvancedSearch) {
      // We only update the Redux state on submit
      resetPagination()
      setSearchQuery({ text: searchTerms })
      if (onSearchGoToSearchPage) {
        history.push("/search")
      }
    }
    event.preventDefault()
    event.stopPropagation()
  }

  function runAdvancedSearch() {
    setShowAdvancedSearch(false)
  }
}

SearchBar.propTypes = {
  setSearchQuery: PropTypes.func.isRequired,
  onSearchGoToSearchPage: PropTypes.bool,
  query: PropTypes.shape({
    text: PropTypes.string,
    filters: PropTypes.any,
    objectType: PropTypes.string
  }),
  searchObjectTypes: PropTypes.array,
  resetPagination: PropTypes.func.isRequired
}

const mapStateToProps = (state, ownProps) => ({
  query: state.searchQuery,
  onSearchGoToSearchPage: state.searchProps.onSearchGoToSearchPage,
  searchObjectTypes: state.searchProps.searchObjectTypes
})

const mapDispatchToProps = (dispatch, ownProps) => ({
  setSearchQuery: searchTerms => dispatch(setSearchQuery(searchTerms)),
  resetPagination: () => dispatch(resetPagination())
})

export default connect(mapStateToProps, mapDispatchToProps)(SearchBar)
<commit_msg>NCI-Agency/anet#GH-1810: Refactor SearchPopover to functional component<commit_after>import { Popover, PopoverInteractionKind, Position } from "@blueprintjs/core"
import { resetPagination, SEARCH_OBJECT_LABELS, setSearchQuery } from "actions"
import AdvancedSearch from "components/AdvancedSearch"
import { SearchDescription } from "components/SearchFilters"
import _isEqual from "lodash/isEqual"
import PropTypes from "prop-types"
import React, { useEffect, useRef, useState } from "react"
import { Button, Form, FormControl, InputGroup } from "react-bootstrap"
import { connect } from "react-redux"
import { useHistory } from "react-router-dom"
import SEARCH_ICON from "resources/search-alt.png"

export const SearchPopover = ({ popoverContent, children }) => {
  const [isOpen, setIsOpen] = useState(false)
  const _handleInteraction = isOpen => setIsOpen(isOpen)
  return (
    <Popover
      isOpen={isOpen}
      onInteraction={_handleInteraction}
      boundary="window"
      captureDismiss
      content={popoverContent}
      interactionKind={PopoverInteractionKind.CLICK}
      position={Position.BOTTOM_LEFT}
      usePortal={false}
      modifiers={{
        preventOverflow: {
          enabled: false
        },
        flip: {
          enabled: false
        }
      }}
    >
      {children}
    </Popover>
  )
}

SearchPopover.propTypes = {
  popoverContent: PropTypes.element.isRequired,
  children: PropTypes.any.isRequired
}

const SearchBar = props => {
  const {
    query,
    searchObjectTypes,
    resetPagination,
    setSearchQuery,
    onSearchGoToSearchPage
  } = props
  const history = useHistory()
  // (Re)set searchTerms if the query.text prop changes
  const latestQueryText = useRef(query.text)
  const queryTextUnchanged = _isEqual(latestQueryText.current, query.text)
  const [searchTerms, setSearchTerms] = useState(query.text)
  const [showAdvancedSearch, setShowAdvancedSearch] = useState(false)

  useEffect(() => {
    if (!queryTextUnchanged) {
      latestQueryText.current = query.text
      setSearchTerms(query.text)
    }
  }, [query, setSearchTerms, queryTextUnchanged])

  const placeholder = query.objectType
    ? "Filter " + SEARCH_OBJECT_LABELS[query.objectType]
    : "Search for " +
      searchObjectTypes.map(type => SEARCH_OBJECT_LABELS[type]).join(", ")

  const PopoverContent = (
    <AdvancedSearch
      onSearch={runAdvancedSearch}
      onCancel={setShowAdvancedSearch}
      text={searchTerms}
    />
  )
  return (
    <>
      <Form onSubmit={onSubmit} className="advanced-search-form">
        <InputGroup>
          <FormControl
            value={searchTerms}
            placeholder={placeholder}
            onChange={onChange}
            id="searchBarInput"
          />
          {!showAdvancedSearch && (
            <InputGroup.Button>
              <Button onClick={onSubmit} id="searchBarSubmit">

              </Button>
            </InputGroup.Button>
          )}
        </InputGroup>
      </Form>
      <SearchPopover popoverContent={PopoverContent}>
        <SearchDescription query={query} showPlaceholders />
      </SearchPopover>
    </>
  )

  function onChange(event) {
    setSearchTerms(event.target.value)
  }

  function onSubmit(event) {
    if (!showAdvancedSearch) {
      // We only update the Redux state on submit
      resetPagination()
      setSearchQuery({ text: searchTerms })
      if (onSearchGoToSearchPage) {
        history.push("/search")
      }
    }
    event.preventDefault()
    event.stopPropagation()
  }

  function runAdvancedSearch() {
    setShowAdvancedSearch(false)
  }
}

SearchBar.propTypes = {
  setSearchQuery: PropTypes.func.isRequired,
  onSearchGoToSearchPage: PropTypes.bool,
  query: PropTypes.shape({
    text: PropTypes.string,
    filters: PropTypes.any,
    objectType: PropTypes.string
  }),
  searchObjectTypes: PropTypes.array,
  resetPagination: PropTypes.func.isRequired
}

const mapStateToProps = (state, ownProps) => ({
  query: state.searchQuery,
  onSearchGoToSearchPage: state.searchProps.onSearchGoToSearchPage,
  searchObjectTypes: state.searchProps.searchObjectTypes
})

const mapDispatchToProps = (dispatch, ownProps) => ({
  setSearchQuery: searchTerms => dispatch(setSearchQuery(searchTerms)),
  resetPagination: () => dispatch(resetPagination())
})

export default connect(mapStateToProps, mapDispatchToProps)(SearchBar)
<|endoftext|>