<commit_before>describe("Reformed Churches Locator", function() {

    afterEach(function() {
        // Remove the docs we just created
        // TODO: Figure out how to refactor this into a general function that can be used in all tests
        // dir.destroy()
        // TODO: Improve this to only remove the docs created by this test, rather
        //  than all docs.
        // $('#delete_all_docs').click()
        // Returns the page to display the home page as it should
        app.navigate(config.test_home_address, {trigger:true})
    });

    describe("'Find a church' page", function() {
        it("should not display an error", function() {
            app.navigate('find_a_church', { trigger: true })
            var content = $('#content').html()
            expect(content).toMatch('Find a church')
        });
    });

    describe("'Import a directory' page", function() {
        it("should not display an error", function() {
            app.navigate('import_directory', { trigger: true })
            var content = $('#content').html()
            expect(content).toMatch('downloading')
        });
        function trigger_url_field(){
            $('#url').val('http://opc.org/locator.html')
            $('#url').focus().keyup()
        }
        function directory_type_is_visible(){
            // The test should wait until the AJAX call completes
            // Check to see if the AJAX call returned here
            return $('#directory_type').is(':visible')
        }
        function click_state_radio_button(){
            $("#one_state_per_page").prop("checked",true)
            $("#one_state_per_page").click()
        }
        function state_page_is_visible(){
            return $('#state_page').is(':visible') || ($('#state_page').css('display') != 'none')
        }
        describe('url field', function(){
            it('should display step 2 when a valid URL is entered', function(){
                // TODO: Because this test writes to the database, decide whether
                //  the tests should run in a test copy of the database.
                runs(trigger_url_field)
                waitsFor(directory_type_is_visible, "AJAX call to get URL HTML", 60000)
                runs(function(){
                    expect($('#directory_type').is(':visible')).toBe(true)
                })
            })
        })

        describe('state section', function(){
            it('should display when radio button is clicked', function(){
                runs(trigger_url_field)
                waitsFor(directory_type_is_visible, "AJAX call to get URL HTML")
                runs(click_state_radio_button)
                waitsFor(state_page_is_visible, 'state page to display', 20000)
                runs(function(){
                    expect($('#state_page').is(':visible')).toBe(true)
                })
            })
        })
        describe('cong details', function(){
            it('should display when select box is clicked', function(){
                runs(trigger_url_field)
                waitsFor(directory_type_is_visible, "AJAX call to get URL HTML")
                runs(click_state_radio_button)
                waitsFor(state_page_is_visible, 'state page to display', 20000)
                runs(function(){
                    $('#state_drop_down_selector select[name=state]').click()
                })
                waitsFor(function(){
                    return $('#cong_details_url_selector').is(':visible')
                },'cong_details_url_selector to be visible', 20000)
                runs(function(){
                    expect($('#cong_details_url_selector').is(':visible')).toBe(true)
                })
            })
        })
        describe('get congregation id', function(){
            it('should display when link is clicked', function(){
                runs(trigger_url_field)
                waitsFor(directory_type_is_visible, "AJAX call to get URL HTML")
                runs(click_state_radio_button)
                waitsFor(state_page_is_visible, 'state page to display', 20000)
                runs(function(){
                    $('#state_drop_down_selector select[name=state]').click()
                })
                waitsFor(function(){
                    return $('#cong_details_url_selector').is(':visible') &&
                        $('#cong_details_url_selector').html().indexOf('Directory of Congregations') != -1
                },'cong_details_url_selector to be visible', 5000)
                runs(function(){
                    // TODO: Write test to click on the element with this XPATH:
                    //  //*[@id="churchListTable"]/tbody/tr[2]/td[1]/a
                    // console.log($.xpath('//*[@id="churchListTable"]/tbody/tr[2]/td[1]/a'))
                    // $.xpath('//*[@id="churchListTable"]/tbody/tr[2]/td[1]/a').click()
                    console.log($('a[class=lista]')[0])
                    $('a[class=lista]')[0].click()
                })
                waitsFor(function(){
                    return $('#cong_details_url_selector').html().indexOf('Step 4.5') != -1
                },'cong_details_url_selector to display step 4.5', 4000)
                runs(function(){
                    expect($('#cong_details_url_selector').html()).toMatch('Step 4.5')
                })
            })
        })
    });
});

// General test-runner code
(function() {
    var jasmineEnv = jasmine.getEnv();
    jasmineEnv.updateInterval = 1000;
    var htmlReporter = new jasmine.HtmlReporter();
    jasmineEnv.addReporter(htmlReporter);
    jasmineEnv.specFilter = function(spec) {
        return htmlReporter.specFilter(spec);
    };
    var currentWindowOnload = window.onload;
    window.onload = function() {
        if (currentWindowOnload) {
            currentWindowOnload();
        }
        execJasmine();
    };
    function execJasmine() {
        jasmineEnv.execute();
        // Move Jasmine's symbolSummary to top of page to make it easy to see if
        //    some tests are not passing
        $('body').prepend('

')
        $('.banner').first().prepend($('.symbolSummary'))
    }
})();<commit_msg>Extended the time outs<commit_after>describe("Reformed Churches Locator", function() {

    afterEach(function() {
        // Remove the docs we just created
        // TODO: Figure out how to refactor this into a general function that can be used in all tests
        // dir.destroy()
        // TODO: Improve this to only remove the docs created by this test, rather
        //  than all docs.
        // $('#delete_all_docs').click()
        // Returns the page to display the home page as it should
        app.navigate(config.test_home_address, {trigger:true})
    });

    describe("'Find a church' page", function() {
        it("should not display an error", function() {
            app.navigate('find_a_church', { trigger: true })
            var content = $('#content').html()
            expect(content).toMatch('Find a church')
        });
    });

    describe("'Import a directory' page", function() {
        it("should not display an error", function() {
            app.navigate('import_directory', { trigger: true })
            var content = $('#content').html()
            expect(content).toMatch('downloading')
        });
        function trigger_url_field(){
            $('#url').val('http://opc.org/locator.html')
            $('#url').focus().keyup()
        }
        function directory_type_is_visible(){
            // The test should wait until the AJAX call completes
            // Check to see if the AJAX call returned here
            return $('#directory_type').is(':visible')
        }
        function click_state_radio_button(){
            $("#one_state_per_page").prop("checked",true)
            $("#one_state_per_page").click()
        }
        function state_page_is_visible(){
            return $('#state_page').is(':visible') || ($('#state_page').css('display') != 'none')
        }
        describe('url field', function(){
            it('should display step 2 when a valid URL is entered', function(){
                // TODO: Because this test writes to the database, decide whether
                //  the tests should run in a test copy of the database.
                runs(trigger_url_field)
                waitsFor(directory_type_is_visible, "AJAX call to get URL HTML", 120000)
                runs(function(){
                    expect($('#directory_type').is(':visible')).toBe(true)
                })
            })
        })

        describe('state section', function(){
            it('should display when radio button is clicked', function(){
                runs(trigger_url_field)
                waitsFor(directory_type_is_visible, "AJAX call to get URL HTML")
                runs(click_state_radio_button)
                waitsFor(state_page_is_visible, 'state page to display', 20000)
                runs(function(){
                    expect($('#state_page').is(':visible')).toBe(true)
                })
            })
        })
        describe('cong details', function(){
            it('should display when select box is clicked', function(){
                runs(trigger_url_field)
                waitsFor(directory_type_is_visible, "AJAX call to get URL HTML")
                runs(click_state_radio_button)
                waitsFor(state_page_is_visible, 'state page to display', 20000)
                runs(function(){
                    $('#state_drop_down_selector select[name=state]').click()
                })
                waitsFor(function(){
                    return $('#cong_details_url_selector').is(':visible')
                },'cong_details_url_selector to be visible', 20000)
                runs(function(){
                    expect($('#cong_details_url_selector').is(':visible')).toBe(true)
                })
            })
        })
        describe('get congregation id', function(){
            it('should display when link is clicked', function(){
                runs(trigger_url_field)
                waitsFor(directory_type_is_visible, "AJAX call to get URL HTML")
                runs(click_state_radio_button)
                waitsFor(state_page_is_visible, 'state page to display', 20000)
                runs(function(){
                    $('#state_drop_down_selector select[name=state]').click()
                })
                waitsFor(function(){
                    return $('#cong_details_url_selector').is(':visible') &&
                        $('#cong_details_url_selector').html().indexOf('Directory of Congregations') != -1
                },'cong_details_url_selector to be visible', 20000)
                runs(function(){
                    // TODO: Write test to click on the element with this XPATH:
                    //  //*[@id="churchListTable"]/tbody/tr[2]/td[1]/a
                    // console.log($.xpath('//*[@id="churchListTable"]/tbody/tr[2]/td[1]/a'))
                    // $.xpath('//*[@id="churchListTable"]/tbody/tr[2]/td[1]/a').click()
                    console.log($('a[class=lista]')[0])
                    $('a[class=lista]')[0].click()
                })
                waitsFor(function(){
                    return $('#cong_details_url_selector').html().indexOf('Step 4.5') != -1
                },'cong_details_url_selector to display step 4.5', 4000)
                runs(function(){
                    expect($('#cong_details_url_selector').html()).toMatch('Step 4.5')
                })
            })
        })
    });
});

// General test-runner code
(function() {
    var jasmineEnv = jasmine.getEnv();
    jasmineEnv.updateInterval = 1000;
    var htmlReporter = new jasmine.HtmlReporter();
    jasmineEnv.addReporter(htmlReporter);
    jasmineEnv.specFilter = function(spec) {
        return htmlReporter.specFilter(spec);
    };
    var currentWindowOnload = window.onload;
    window.onload = function() {
        if (currentWindowOnload) {
            currentWindowOnload();
        }
        execJasmine();
    };
    function execJasmine() {
        jasmineEnv.execute();
        // Move Jasmine's symbolSummary to top of page to make it easy to see if
        //    some tests are not passing
        $('body').prepend('

')
        $('.banner').first().prepend($('.symbolSummary'))
    }
})();<|endoftext|>


<commit_before>/*global enyo, Ares, ComponentsRegistry */

enyo.kind({
	name: "DocumentToolbar",
	kind:"FittableRows",
	events: {
		onToggleOpen: "",
		onSwitchDoc: "",
		onCloseDocRequest: "",
		onRegisterMe: "",
		onGrabberClick: "",
		onAceFocus: ""
	},
	components: [
		{
			name: "tabs",
			kind: "onyx.TabBar",
			classes: "ares-small-toolbar title-gradient",
			showing: false,
			checkBeforeClosing: true,
			onTabChanged: 'switchDoc',
			onTabRemoveRequested: 'requestCloseDoc',
			onHide: "doAceFocus"
		}
	],

	create: function() {
		this.inherited(arguments);
		this.doRegisterMe({name:"documentToolbar", reference:this});
	},
	createDocTab: function(name, id, path) {
		this.$.tabs.show();
		this.$.tabs.render();
		this.$.tabs.addTab({
			caption: name,
			// id like home-123f3c8a766751826...
			// id encodes project name and file path
			userId: id,
			tooltipMsg: path
		});
	},

	switchDoc: function(inSender, inEvent) {
		var newDoc = Ares.Workspace.files.get(inEvent.id);
		this.trace(inEvent.id, newDoc);
		ComponentsRegistry.getComponent("enyoEditor").switchToDocument(newDoc);
		return true;
	},

	activateDocWithId: function(id) {
		this.$.tabs.activate({ userId: id });
	},

	requestCloseDoc: function(inSender, inEvent) {
		// inEvent.next callback is ditched. Ares will call removeTab
		// when file is closed by Ace
		this.doCloseDocRequest({id: inEvent.userId});
		return true;
	},
	removeTab: function(id) {
		this.$.tabs.removeTab({ userId: id }) ;
		if (this.$.tabs.isEmpty() ) {
			this.$.tabs.hide();
		}
	}
});
<commit_msg>ENYO-3082: fix missing trace method<commit_after>/*global enyo, Ares, ComponentsRegistry, ares */

enyo.kind({
	name: "DocumentToolbar",
	kind:"FittableRows",
	events: {
		onToggleOpen: "",
		onSwitchDoc: "",
		onCloseDocRequest: "",
		onRegisterMe: "",
		onGrabberClick: "",
		onAceFocus: ""
	},
	components: [
		{
			name: "tabs",
			kind: "onyx.TabBar",
			classes: "ares-small-toolbar title-gradient",
			showing: false,
			checkBeforeClosing: true,
			onTabChanged: 'switchDoc',
			onTabRemoveRequested: 'requestCloseDoc',
			onHide: "doAceFocus"
		}
	],

	create: function() {
		this.inherited(arguments);
		ares.setupTraceLogger(this);
		this.doRegisterMe({name:"documentToolbar", reference:this});
	},
	createDocTab: function(name, id, path) {
		this.$.tabs.show();
		this.$.tabs.render();
		this.$.tabs.addTab({
			caption: name,
			// id like home-123f3c8a766751826...
			// id encodes project name and file path
			userId: id,
			tooltipMsg: path
		});
	},

	switchDoc: function(inSender, inEvent) {
		var newDoc = Ares.Workspace.files.get(inEvent.id);
		this.trace(inEvent.id, newDoc);
		ComponentsRegistry.getComponent("enyoEditor").switchToDocument(newDoc);
		return true;
	},

	activateDocWithId: function(id) {
		this.$.tabs.activate({ userId: id });
	},

	requestCloseDoc: function(inSender, inEvent) {
		// inEvent.next callback is ditched. Ares will call removeTab
		// when file is closed by Ace
		this.doCloseDocRequest({id: inEvent.userId});
		return true;
	},
	removeTab: function(id) {
		this.$.tabs.removeTab({ userId: id }) ;
		if (this.$.tabs.isEmpty() ) {
			this.$.tabs.hide();
		}
	}
});
<|endoftext|>


<commit_before>import React from 'react'
import { graphql, Link } from 'gatsby'
import styled from 'styled-components'
import ScrollableAnchor, { configureAnchors } from 'react-scrollable-anchor'
import SEO from './../components/general/SEO'
import Arrow from './../components/general/Arrow'
import Hero from './../components/general/Hero'

configureAnchors({
  offset: -32,
  scrollDuration: 1000,
})

const Wrapper = styled.div`
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: 1fr;
  grid-template-areas: 'Content';
  max-width: 100%;
`
const Content = styled.div`
  grid-area: Content;
  display: flex;
  height: calc(100vh - 9rem);
  flex-direction: column;
  align-items: center;
  justify-content: center;
  margin: 2rem;
  @media screen and (min-width: 52em) {
    height: calc(100vh - 7rem);
    margin: 1rem;
    section {
      width: 76.4%;
    }
  }
  @media screen and (min-width: 64em) {
    height: calc(100vh);
    margin: 0;
    section {
      width: 61.8%;
    }
  }
`
const BlogContent = styled.div`
  display: flex;
  min-height: 100vh;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  margin: 2rem;

  section {
    width: 100%;
    article {
      margin: 2rem 0;
    }
  }
  @media screen and (min-width: 52em) {
    margin: 1rem;
    section {
      width: 61.8%;
    }
  }
  @media screen and (min-width: 64em) {
    margin: 0;
    section {
      width: 61.8%;
    }
  }
`

const Buttons = styled.div`
  grid-column: 3;
  margin-bottom: 5rem;
  @media screen and (min-width: 52em) {
    margin-bottom: 2rem;
  }
`

const BlogPost = ({ data, pageContext }) => {
  const post = data.contentfulPost
  const comments = `https://mobile.twitter.com/search?q=${encodeURIComponent(
    `https://iammatthias.com/blog/${post.slug}/`
  )}`
  const previous = pageContext.prev
  const next = pageContext.next
  return (
    <>
      <SEO
        title={post.title}
        image={post.heroImage}
        description={post.body.childMarkdownRemark.metaExcerpt}
      />
      <Wrapper>
        <Content>
          <ScrollableAnchor id="content">

{post.title}

                Published: {post.publishDate} {'// '}
                Est. {post.body.childMarkdownRemark.timeToRead} minutes to read

          </ScrollableAnchor>
          <Arrow anchor="#post" />
        </Content>
        <BlogContent>
          <ScrollableAnchor id="post">
            <>

                <Hero image={post.heroImage} />

              <Buttons>
                {previous && (
                  <Link className="button" to={`/blog/${previous.slug}/`}>
                    ← Prev Post
                  </Link>
                )}
                {next && (
                  <Link className="button" to={`/blog/${next.slug}/`}>
                    Next Post →
                  </Link>
                )}

                  Discuss on Twitter

              </Buttons>
            </>
          </ScrollableAnchor>
        </BlogContent>
      </Wrapper>
    </>
  )
}

export const query = graphql`
  query($slug: String!) {
    contentfulPost(slug: { eq: $slug }) {
      title
      id
      slug
      metaDescription {
        internal {
          content
        }
      }
      publishDate(formatString: "DD MMM YYYY")
      publishDateISO: publishDate(formatString: "YYYY-MM-DD")
      tags {
        title
        id
        slug
      }
      heroImage {
        title
        fluid(maxWidth: 1600, quality: 50) {
          ...GatsbyContentfulFluid_withWebp
          src
        }
        ogimg: fluid(maxWidth: 900, quality: 50) {
          ...GatsbyContentfulFluid_withWebp
          src
        }
      }
      body {
        childMarkdownRemark {
          html
          excerpt(pruneLength: 320)
          metaExcerpt: excerpt(pruneLength: 120)
          timeToRead
        }
      }
    }
  }
`

export default BlogPost
<commit_msg>Update post.js<commit_after>import React from 'react'
import { graphql, Link } from 'gatsby'
import styled from 'styled-components'
import ScrollableAnchor, { configureAnchors } from 'react-scrollable-anchor'
import SEO from './../components/general/SEO'
import Arrow from './../components/general/Arrow'
import Hero from './../components/general/Hero'

configureAnchors({
  offset: -32,
  scrollDuration: 1000,
})

const Wrapper = styled.div`
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: 1fr;
  grid-template-areas: 'Content';
  max-width: 100%;
`
const Content = styled.div`
  grid-area: Content;
  display: flex;
  height: calc(100vh - 9rem);
  flex-direction: column;
  align-items: center;
  justify-content: center;
  margin: 2rem;
  @media screen and (min-width: 52em) {
    height: calc(100vh - 7rem);
    margin: 1rem;
    section {
      width: 76.4%;
    }
  }
  @media screen and (min-width: 64em) {
    height: calc(100vh);
    margin: 0;
    section {
      width: 61.8%;
    }
  }
`
const BlogContent = styled.div`
  display: flex;
  min-height: 100vh;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  margin: 2rem;
  width: 100%;
  section {
    article {
      margin: 2rem 0;
    }
  }
  @media screen and (min-width: 52em) {
    margin: 1rem;
    section {
      width: 61.8%;
    }
  }
  @media screen and (min-width: 64em) {
    margin: 0;
    section {
      width: 61.8%;
    }
  }
`

const Buttons = styled.div`
  grid-column: 3;
  margin-bottom: 5rem;
  @media screen and (min-width: 52em) {
    margin-bottom: 2rem;
  }
`

const BlogPost = ({ data, pageContext }) => {
  const post = data.contentfulPost
  const comments = `https://mobile.twitter.com/search?q=${encodeURIComponent(
    `https://iammatthias.com/blog/${post.slug}/`
  )}`
  const previous = pageContext.prev
  const next = pageContext.next
  return (
    <>
      <SEO
        title={post.title}
        image={post.heroImage}
        description={post.body.childMarkdownRemark.metaExcerpt}
      />
      <Wrapper>
        <Content>
          <ScrollableAnchor id="content">

{post.title}

                Published: {post.publishDate} {'// '}
                Est. {post.body.childMarkdownRemark.timeToRead} minutes to read

          </ScrollableAnchor>
          <Arrow anchor="#post" />
        </Content>
        <BlogContent>
          <ScrollableAnchor id="post">
            <>

                <Hero image={post.heroImage} />

              <Buttons>
                {previous && (
                  <Link className="button" to={`/blog/${previous.slug}/`}>
                    ← Prev Post
                  </Link>
                )}
                {next && (
                  <Link className="button" to={`/blog/${next.slug}/`}>
                    Next Post →
                  </Link>
                )}

                  Discuss on Twitter

              </Buttons>
            </>
          </ScrollableAnchor>
        </BlogContent>
      </Wrapper>
    </>
  )
}

export const query = graphql`
  query($slug: String!) {
    contentfulPost(slug: { eq: $slug }) {
      title
      id
      slug
      metaDescription {
        internal {
          content
        }
      }
      publishDate(formatString: "DD MMM YYYY")
      publishDateISO: publishDate(formatString: "YYYY-MM-DD")
      tags {
        title
        id
        slug
      }
      heroImage {
        title
        fluid(maxWidth: 1600, quality: 50) {
          ...GatsbyContentfulFluid_withWebp
          src
        }
        ogimg: fluid(maxWidth: 900, quality: 50) {
          ...GatsbyContentfulFluid_withWebp
          src
        }
      }
      body {
        childMarkdownRemark {
          html
          excerpt(pruneLength: 320)
          metaExcerpt: excerpt(pruneLength: 120)
          timeToRead
        }
      }
    }
  }
`

export default BlogPost
<|endoftext|>


<commit_before>// @flow

import React, { PropTypes } from 'react';
import {
  Animated,
  BackAndroid,
  Easing,
  PixelRatio,
  Platform,
  StyleSheet,
  Text,
  Image,
  NativeModules,
  TouchableOpacity,
  TouchableNativeFeedback,
  TouchableWithoutFeedback,
  View,
} from 'react-native';

// Not everybody has this enabled yet
const useNativeDriver = !!NativeModules.NativeAnimatedModule;

type ActionSheetOptions = {
  options: Array<string>,
  icons: ?Array<number>,
  destructiveButtonIndex: ?number,
  cancelButtonIndex: ?number,
}

type ActionGroupProps = {
  options: Array<string>,
  icons: ?Array<number>,
  destructiveButtonIndex: ?number,
  onSelect: (i: number) => boolean,
  startIndex: number,
  length: number,
}

type ActionSheetState = {
  isVisible: boolean,
  isAnimating: boolean,
  options: ?ActionSheetOptions,
  onSelect: ?(i: number) => void,
  overlayOpacity: any,
  sheetOpacity: any,
}

type ActionSheetProps = {
  children: ?any,
}

const OPACITY_ANIMATION_TIME = 150;
const PIXEL = 1 / PixelRatio.get();

class ActionGroup extends React.Component {
  props: ActionGroupProps;

  static propTypes = {
    options: PropTypes.array.isRequired,
    icons: PropTypes.array,
    destructiveButtonIndex: PropTypes.number,
    onSelect: PropTypes.func.isRequired,
    startIndex: PropTypes.number.isRequired,
    length: PropTypes.number.isRequired,
  };

  render() {
    let {
      options,
      icons,
      destructiveButtonIndex,
      onSelect,
      startIndex,
      length,
    } = this.props;

    let optionViews = [];

    let nativeFeedbackBackground = TouchableNativeFeedbackSafe.Ripple(
      'rgba(180, 180, 180, 1)',
      false
    );

    for (let i = startIndex; i < startIndex + length; i++) {
      let color = '#444444';
      if (i === destructiveButtonIndex) {
        color = '#ff3b30';
      }

      let iconElement = undefined

      if (icons && icons[i]) {
        iconElement = (
          <Image
            source={icons[i]}
            style={styles.icon}
          />
          )
      }

      optionViews.push(
        <TouchableNativeFeedbackSafe
          key={i}
          pressInDelay={0}
          background={nativeFeedbackBackground}
          onPress={() => onSelect(i)}
          style={styles.button}>
          {iconElement}
          <Text style={[styles.text, {color}]}>
            {options[i]}
          </Text>
        </TouchableNativeFeedbackSafe>
      );

      if (i < startIndex + length - 1) {
        optionViews.push(
          <View key={`separator-${i}`} style={styles.rowSeparator} />
        );
      }
    }

    return (
      <View style={styles.groupContainer}>
        {optionViews}
      </View>
    );
  }
}

// Has same API as https://facebook.github.io/react-native/docs/actionsheetios.html
export default class ActionSheet extends React.Component {
  props: ActionSheetProps;
  _animateOutCallback: ?() => void = null;

  state: ActionSheetState = {
    isVisible: false,
    isAnimating: false,
    options: null,
    onSelect: null,
    overlayOpacity: new Animated.Value(0),
    sheetOpacity: new Animated.Value(0),
  };

  render() {
    let { isVisible } = this.state;
    let overlay = isVisible ? (
      <Animated.View style={[styles.overlay, {
        opacity: this.state.overlayOpacity,
      }]} />
    ) : null;

    let sheet = isVisible ? this._renderSheet() : null;

    return (
      <View style={{flex: 1}}>
        {React.Children.only(this.props.children)}
        {overlay}
        {sheet}
      </View>
    );
  }

  _renderSheet() {
    if (!this.state.options) {
      return;
    }

    let numOptions = this.state.options.options.length;

    return (
      <TouchableWithoutFeedback onPress={this._selectCancelButton}>
        <Animated.View
          needsOffscreenAlphaCompositing={this.state.isAnimating}
          style={[styles.sheetContainer, {
            opacity: this.state.sheetOpacity,
            transform: [{scale: this.state.sheetOpacity.interpolate({inputRange: [0, 0.5, 1], outputRange: [0.6, 1, 1]})}],
          }]}>
          <View style={styles.sheet}>
            <ActionGroup
              options={this.state.options.options}
              icons={this.state.options.icons}
              destructiveButtonIndex={this.state.options.destructiveButtonIndex}
              onSelect={this._onSelect}
              startIndex={0}
              length={numOptions}
            />
          </View>
        </Animated.View>
      </TouchableWithoutFeedback>
    );
  }

  showActionSheetWithOptions(
    options: ActionSheetOptions,
    onSelect: (i: number) => void,
    onAnimateOut: () => void
  ) {
    if (this.state.isVisible) {
      return;
    }

    this.setState({
      options,
      onSelect,
      isVisible: true,
      isAnimating: true,
    });

    this.state.overlayOpacity.setValue(0);
    this.state.sheetOpacity.setValue(0);

    Animated.parallel([
      Animated.timing(this.state.overlayOpacity, {
        toValue: 0.5,
        easing: Easing.in(Easing.linear),
        duration: OPACITY_ANIMATION_TIME,
        useNativeDriver,
      }),
      Animated.timing(this.state.sheetOpacity, {
        toValue: 1,
        easing: Easing.in(Easing.linear),
        duration: OPACITY_ANIMATION_TIME,
        useNativeDriver,
      }),
    ]).start(result => {
      if (result.finished) {
        this.setState({
          isAnimating: false,
        });
      }
    });

    this._animateOutCallback = onAnimateOut;

    BackAndroid.addEventListener('actionSheetHardwareBackPress', this._selectCancelButton);
  }

  _selectCancelButton = () => {
    if (!this.state.options) {
      return false;
    }

    if (typeof this.state.options.cancelButtonIndex === 'number') {
      return this._onSelect(this.state.options.cancelButtonIndex);
    } else {
      return this._animateOut();
    }
  }

  _onSelect = (index: number): boolean => {
    if (this.state.isAnimating) {
      return false;
    }

    this.state.onSelect && this.state.onSelect(index);
    return this._animateOut();
  }

  _animateOut = (): boolean => {
    if (this.state.isAnimating) {
      return false;
    }

    BackAndroid.removeEventListener('actionSheetHardwareBackPress', this._selectCancelButton);

    this.setState({
      isAnimating: true,
    });

    Animated.parallel([
      Animated.timing(this.state.overlayOpacity, {
        toValue: 0,
        easing: Easing.in(Easing.linear),
        duration: OPACITY_ANIMATION_TIME,
        useNativeDriver,
      }),
      Animated.timing(this.state.sheetOpacity, {
        toValue: 0,
        easing: Easing.in(Easing.linear),
        duration: OPACITY_ANIMATION_TIME,
        useNativeDriver,
      }),
    ]).start(result => {
      if (result.finished) {
        this.setState({
          isVisible: false,
          isAnimating: false,
        });
        if (typeof this._animateOutCallback === 'function') {
          this._animateOutCallback();
          this._animateOutCallback = null;
        }
      }
    });

    return true;
  }
}

let TouchableComponent;

TouchableComponent = Platform.Version <= 20 ? TouchableOpacity : TouchableNativeFeedback;

if (TouchableComponent !== TouchableNativeFeedback) {
  TouchableComponent.SelectableBackground = () => ({});
  TouchableComponent.SelectableBackgroundBorderless = () => ({});
  TouchableComponent.Ripple = (color, borderless) => ({});
}

class TouchableNativeFeedbackSafe extends React.Component {

  static SelectableBackground = TouchableComponent.SelectableBackground;
  static SelectableBackgroundBorderless = TouchableComponent.SelectableBackgroundBorderless;
  static Ripple = TouchableComponent.Ripple;

  render() {
    if (TouchableComponent === TouchableNativeFeedback) {
      return (
        <TouchableComponent {...this.props} style={{}}>
          <View style={this.props.style}>
            {this.props.children}
          </View>
        </TouchableComponent>
      );
    } else {
      return (
        <TouchableComponent {...this.props}>
          {this.props.children}
        </TouchableComponent>
      );
    }
  }
}

let styles = StyleSheet.create({
  groupContainer: {
    backgroundColor: '#fefefe',
    borderRadius: 4,
    borderColor: '#cbcbcb',
    borderWidth: PIXEL,
    overflow: 'hidden',
    marginHorizontal: 16,
    marginBottom: 8,
  },
  button: {
    justifyContent: 'flex-start',
    alignItems: 'center',
    flexDirection: 'row',
    height: 50,
    paddingHorizontal: 16,
  },
  icon: {
    marginRight: 15,
  },
  text: {
    fontSize: 17,
    fontWeight: '700',
  },
  rowSeparator: {
    backgroundColor: '#dddddd',
    height: 1,
    flex: 1,
  },
  overlay: {
    position: 'absolute',
    top: 0,
    right: 0,
    bottom: 0,
    left: 0,
    backgroundColor: 'black',
  },
  sheetContainer: {
    position: 'absolute',
    left: 0,
    right: 0,
    bottom: 0,
    top: 0,
    backgroundColor: 'transparent',
    alignItems: 'center',
    justifyContent: 'center',
    flexDirection: 'row',
  },
  sheet: {
    flex: 1,
    backgroundColor: 'transparent',
  },
});
<commit_msg>Feature(Android): ability to change text style<commit_after>// @flow

import React, { PropTypes } from 'react';
import {
  Animated,
  BackAndroid,
  Easing,
  PixelRatio,
  Platform,
  StyleSheet,
  Text,
  Image,
  NativeModules,
  TouchableOpacity,
  TouchableNativeFeedback,
  TouchableWithoutFeedback,
  View,
} from 'react-native';

// Not everybody has this enabled yet
const useNativeDriver = !!NativeModules.NativeAnimatedModule;

type ActionSheetOptions = {
  options: Array<string>,
  icons: ?Array<number>,
  destructiveButtonIndex: ?number,
  cancelButtonIndex: ?number,
  textStyle: ?any,
}

type ActionGroupProps = {
  options: Array<string>,
  icons: ?Array<number>,
  destructiveButtonIndex: ?number,
  onSelect: (i: number) => boolean,
  startIndex: number,
  length: number,
  textStyle: ?any,
}

type ActionSheetState = {
  isVisible: boolean,
  isAnimating: boolean,
  options: ?ActionSheetOptions,
  onSelect: ?(i: number) => void,
  overlayOpacity: any,
  sheetOpacity: any,
}

type ActionSheetProps = {
  children: ?any,
}

const OPACITY_ANIMATION_TIME = 150;
const PIXEL = 1 / PixelRatio.get();

class ActionGroup extends React.Component {
  props: ActionGroupProps;

  static propTypes = {
    options: PropTypes.array.isRequired,
    icons: PropTypes.array,
    destructiveButtonIndex: PropTypes.number,
    onSelect: PropTypes.func.isRequired,
    startIndex: PropTypes.number.isRequired,
    length: PropTypes.number.isRequired,
    textStyle: Text.propTypes.style,
  };

  render() {
    let {
      options,
      icons,
      destructiveButtonIndex,
      onSelect,
      startIndex,
      length,
      textStyle,
    } = this.props;

    let optionViews = [];

    let nativeFeedbackBackground = TouchableNativeFeedbackSafe.Ripple(
      'rgba(180, 180, 180, 1)',
      false
    );

    for (let i = startIndex; i < startIndex + length; i++) {
      let color = '#444444';
      if (i === destructiveButtonIndex) {
        color = '#ff3b30';
      }

      let iconElement = undefined

      if (icons && icons[i]) {
        iconElement = (
          <Image
            source={icons[i]}
            style={styles.icon}
          />
          )
      }

      optionViews.push(
        <TouchableNativeFeedbackSafe
          key={i}
          pressInDelay={0}
          background={nativeFeedbackBackground}
          onPress={() => onSelect(i)}
          style={styles.button}>
          {iconElement}
          <Text style={[styles.text, {color}, textStyle]}>
            {options[i]}
          </Text>
        </TouchableNativeFeedbackSafe>
      );

      if (i < startIndex + length - 1) {
        optionViews.push(
          <View key={`separator-${i}`} style={styles.rowSeparator} />
        );
      }
    }

    return (
      <View style={styles.groupContainer}>
        {optionViews}
      </View>
    );
  }
}

// Has same API as https://facebook.github.io/react-native/docs/actionsheetios.html
export default class ActionSheet extends React.Component {
  props: ActionSheetProps;
  _animateOutCallback: ?() => void = null;

  state: ActionSheetState = {
    isVisible: false,
    isAnimating: false,
    options: null,
    onSelect: null,
    overlayOpacity: new Animated.Value(0),
    sheetOpacity: new Animated.Value(0),
  };

  render() {
    let { isVisible } = this.state;
    let overlay = isVisible ? (
      <Animated.View style={[styles.overlay, {
        opacity: this.state.overlayOpacity,
      }]} />
    ) : null;

    let sheet = isVisible ? this._renderSheet() : null;

    return (
      <View style={{flex: 1}}>
        {React.Children.only(this.props.children)}
        {overlay}
        {sheet}
      </View>
    );
  }

  _renderSheet() {
    if (!this.state.options) {
      return;
    }

    let numOptions = this.state.options.options.length;

    return (
      <TouchableWithoutFeedback onPress={this._selectCancelButton}>
        <Animated.View
          needsOffscreenAlphaCompositing={this.state.isAnimating}
          style={[styles.sheetContainer, {
            opacity: this.state.sheetOpacity,
            transform: [{scale: this.state.sheetOpacity.interpolate({inputRange: [0, 0.5, 1], outputRange: [0.6, 1, 1]})}],
          }]}>
          <View style={styles.sheet}>
            <ActionGroup
              options={this.state.options.options}
              icons={this.state.options.icons}
              destructiveButtonIndex={this.state.options.destructiveButtonIndex}
              onSelect={this._onSelect}
              startIndex={0}
              length={numOptions}
              textStyle={this.state.options.textStyle}
            />
          </View>
        </Animated.View>
      </TouchableWithoutFeedback>
    );
  }

  showActionSheetWithOptions(
    options: ActionSheetOptions,
    onSelect: (i: number) => void,
    onAnimateOut: () => void
  ) {
    if (this.state.isVisible) {
      return;
    }

    this.setState({
      options,
      onSelect,
      isVisible: true,
      isAnimating: true,
    });

    this.state.overlayOpacity.setValue(0);
    this.state.sheetOpacity.setValue(0);

    Animated.parallel([
      Animated.timing(this.state.overlayOpacity, {
        toValue: 0.5,
        easing: Easing.in(Easing.linear),
        duration: OPACITY_ANIMATION_TIME,
        useNativeDriver,
      }),
      Animated.timing(this.state.sheetOpacity, {
        toValue: 1,
        easing: Easing.in(Easing.linear),
        duration: OPACITY_ANIMATION_TIME,
        useNativeDriver,
      }),
    ]).start(result => {
      if (result.finished) {
        this.setState({
          isAnimating: false,
        });
      }
    });

    this._animateOutCallback = onAnimateOut;

    BackAndroid.addEventListener('actionSheetHardwareBackPress', this._selectCancelButton);
  }

  _selectCancelButton = () => {
    if (!this.state.options) {
      return false;
    }

    if (typeof this.state.options.cancelButtonIndex === 'number') {
      return this._onSelect(this.state.options.cancelButtonIndex);
    } else {
      return this._animateOut();
    }
  }

  _onSelect = (index: number): boolean => {
    if (this.state.isAnimating) {
      return false;
    }

    this.state.onSelect && this.state.onSelect(index);
    return this._animateOut();
  }

  _animateOut = (): boolean => {
    if (this.state.isAnimating) {
      return false;
    }

    BackAndroid.removeEventListener('actionSheetHardwareBackPress', this._selectCancelButton);

    this.setState({
      isAnimating: true,
    });

    Animated.parallel([
      Animated.timing(this.state.overlayOpacity, {
        toValue: 0,
        easing: Easing.in(Easing.linear),
        duration: OPACITY_ANIMATION_TIME,
        useNativeDriver,
      }),
      Animated.timing(this.state.sheetOpacity, {
        toValue: 0,
        easing: Easing.in(Easing.linear),
        duration: OPACITY_ANIMATION_TIME,
        useNativeDriver,
      }),
    ]).start(result => {
      if (result.finished) {
        this.setState({
          isVisible: false,
          isAnimating: false,
        });
        if (typeof this._animateOutCallback === 'function') {
          this._animateOutCallback();
          this._animateOutCallback = null;
        }
      }
    });

    return true;
  }
}

let TouchableComponent;

TouchableComponent = Platform.Version <= 20 ? TouchableOpacity : TouchableNativeFeedback;

if (TouchableComponent !== TouchableNativeFeedback) {
  TouchableComponent.SelectableBackground = () => ({});
  TouchableComponent.SelectableBackgroundBorderless = () => ({});
  TouchableComponent.Ripple = (color, borderless) => ({});
}

class TouchableNativeFeedbackSafe extends React.Component {

  static SelectableBackground = TouchableComponent.SelectableBackground;
  static SelectableBackgroundBorderless = TouchableComponent.SelectableBackgroundBorderless;
  static Ripple = TouchableComponent.Ripple;

  render() {
    if (TouchableComponent === TouchableNativeFeedback) {
      return (
        <TouchableComponent {...this.props} style={{}}>
          <View style={this.props.style}>
            {this.props.children}
          </View>
        </TouchableComponent>
      );
    } else {
      return (
        <TouchableComponent {...this.props}>
          {this.props.children}
        </TouchableComponent>
      );
    }
  }
}

let styles = StyleSheet.create({
  groupContainer: {
    backgroundColor: '#fefefe',
    borderRadius: 4,
    borderColor: '#cbcbcb',
    borderWidth: PIXEL,
    overflow: 'hidden',
    marginHorizontal: 16,
    marginBottom: 8,
  },
  button: {
    justifyContent: 'flex-start',
    alignItems: 'center',
    flexDirection: 'row',
    height: 50,
    paddingHorizontal: 16,
  },
  icon: {
    marginRight: 15,
  },
  text: {
    fontSize: 17,
    fontWeight: '700',
    textAlignVertical: 'center',
  },
  rowSeparator: {
    backgroundColor: '#dddddd',
    height: 1,
    flex: 1,
  },
  overlay: {
    position: 'absolute',
    top: 0,
    right: 0,
    bottom: 0,
    left: 0,
    backgroundColor: 'black',
  },
  sheetContainer: {
    position: 'absolute',
    left: 0,
    right: 0,
    bottom: 0,
    top: 0,
    backgroundColor: 'transparent',
    alignItems: 'center',
    justifyContent: 'center',
    flexDirection: 'row',
  },
  sheet: {
    flex: 1,
    backgroundColor: 'transparent',
  },
});
<|endoftext|>


<commit_before>'use strict';

var runner  = require('urbit-runner')
var Urbit   = runner.Urbit;
var ERROR   = runner.ERROR;
var actions = runner.actions

var args  = ['-A', '../arvo', '-csgPSF', 'zod', 'zod'];
var urbit = new Urbit(args);

Promise.resolve(urbit)
.then(actions.safeBoot)
.then(actions.test)
.then(function(){
  return urbit.exit(0);
})
.catch(function(err){
  return urbit.waitSilent()
  .then(function(){
    urbit.warn("Arvo test aborted:", err);
    // we still exit 0, it's not our fault ...
    return urbit.exit(0);
  });
});
<commit_msg>[CI] sends ctrl-z to work around profiling output hang<commit_after>'use strict';

var runner  = require('urbit-runner')
var Urbit   = runner.Urbit;
var ERROR   = runner.ERROR;
var actions = runner.actions

var args  = ['-A', '../arvo', '-csgPSF', 'zod', 'zod'];
var urbit = new Urbit(args);

// vere hangs (always?) with run in travis-ci with -P
// so we send ^Z if we hang for ~s30
function exit() {
  setTimeout(function(){
    urbit.pty.write('\x1a');
    urbit.pty.on('exit', function(code, signal){
      process.exit(0);
    })
  }, 30 * 1000);

  return urbit.exit(0);
}

Promise.resolve(urbit)
.then(actions.safeBoot)
.then(actions.test)
.then(exit)
.catch(function(err){
  // we still exit 0, Arvo errors are not our fault ...
  return urbit.waitSilent()
  .then(function(){
    return urbit.warn("Arvo test aborted:", err);
  })
  .then(exit);
});
<|endoftext|>


<commit_before>var path = require("path");
var tl = require("vso-task-lib");
require("shelljs/global");

// Global variables.
var codePushCommandPrefix = "node " + path.join(__dirname, "node_modules", "code-push-cli", "script", "cli");

// Export for unit testing.
function log(message) {
  console.log(message);
}

// Helper functions.
function buildCommand(cmd, positionArgs, optionFlags) {
  var command = codePushCommandPrefix + " " + cmd;

  positionArgs && positionArgs.forEach(function(positionArg) {
    command = command + " " + positionArg;
  });

  for (var flag in optionFlags) {
    // If the value is falsey, the option flag doesn't have to be specified.
    if (optionFlags[flag]) {
      var flagValue = "" + optionFlags[flag];
      // If the value contains spaces, wrap in double quotes.
      if (flagValue.indexOf(" ") >= 0) {
        flagValue = "\"" + flagValue + "\"";
      }

      command = command + " --" + flag;
      // For boolean flags, the presence of the flag is enough to indicate its value.
      if (flagValue != "true" && flagValue != "false") {
        command = command + " " + flagValue;
      }
    }
  }

  return command;
}

function executeCommandAndHandleResult(cmd, positionArgs, optionFlags) {
  var command = buildCommand(cmd, positionArgs, optionFlags);

  var result = exec(command, { silent: true });

  if (result.code == 0) {
    module.exports.log(result.output);
  } else {
    tl.setResult(1, result.output);
    ensureLoggedOut();
    throw new Error(result.output);
  }

  return result;
}

function ensureLoggedOut() {
  exec(buildCommand("logout", /*positionArgs*/ null, { local: true }), { silent: true });
}

// The main function to be executed.
function performDeployTask(accessKey, appName, packagePath, appStoreVersion, deploymentName, description, isMandatory) {
  // If function arguments are provided (e.g. during test), use those, else, get user inputs provided by VSTS.
  var authType = tl.getInput("authType", false);
  if (authType === "AccessKey") {
      accessKey = tl.getInput("accessKey", true);
  } else if (authType === "ServiceEndpoint") {
      var serviceAccount = tl.getEndpointAuthorization(tl.getInput("serviceEndpoint", true));
      accessKey = serviceAccount.parameters.password;
  }

  accessKey       = accessKey;
  appName         = appName || tl.getInput("appName", true);
  packagePath     = packagePath || tl.getPathInput("packagePath", true);
  appStoreVersion = appStoreVersion || tl.getInput("appStoreVersion", true);
  deploymentName  = deploymentName || tl.getInput("deploymentName", false);
  description     = description || tl.getInput("description", false);
  isMandatory     = isMandatory || tl.getInput("isMandatory", false);

  if (!accessKey) {
      console.error("Access key required");
      tl.setResult(1, "Access key required");
  }

  // Ensure all other users are logged out.
  ensureLoggedOut();

  // Log in to the CodePush CLI.
  executeCommandAndHandleResult("login", /*positionArgs*/ null, { accessKey: accessKey });

  // Run release command.
  executeCommandAndHandleResult(
    "release",
    [appName, packagePath, appStoreVersion],
    {
      deploymentName: deploymentName,
      description: description,
      mandatory: isMandatory
    }
  );

  // Log out.
  ensureLoggedOut();
}

module.exports = {
  buildCommand: buildCommand,
  commandPrefix: codePushCommandPrefix,
  ensureLoggedOut: ensureLoggedOut,
  executeCommandAndHandleResult: executeCommandAndHandleResult,
  log: log,
  performDeployTask: performDeployTask
}

if (require.main === module) {
  // Only run the deploy task if the script is being run directly, and not imported as a module (eg. during test)
  performDeployTask();
}
<commit_msg>removing a noop assign<commit_after>var path = require("path");
var tl = require("vso-task-lib");
require("shelljs/global");

// Global variables.
var codePushCommandPrefix = "node " + path.join(__dirname, "node_modules", "code-push-cli", "script", "cli");

// Export for unit testing.
function log(message) {
  console.log(message);
}

// Helper functions.
function buildCommand(cmd, positionArgs, optionFlags) {
  var command = codePushCommandPrefix + " " + cmd;

  positionArgs && positionArgs.forEach(function(positionArg) {
    command = command + " " + positionArg;
  });

  for (var flag in optionFlags) {
    // If the value is falsey, the option flag doesn't have to be specified.
    if (optionFlags[flag]) {
      var flagValue = "" + optionFlags[flag];
      // If the value contains spaces, wrap in double quotes.
      if (flagValue.indexOf(" ") >= 0) {
        flagValue = "\"" + flagValue + "\"";
      }

      command = command + " --" + flag;
      // For boolean flags, the presence of the flag is enough to indicate its value.
      if (flagValue != "true" && flagValue != "false") {
        command = command + " " + flagValue;
      }
    }
  }

  return command;
}

function executeCommandAndHandleResult(cmd, positionArgs, optionFlags) {
  var command = buildCommand(cmd, positionArgs, optionFlags);

  var result = exec(command, { silent: true });

  if (result.code == 0) {
    module.exports.log(result.output);
  } else {
    tl.setResult(1, result.output);
    ensureLoggedOut();
    throw new Error(result.output);
  }

  return result;
}

function ensureLoggedOut() {
  exec(buildCommand("logout", /*positionArgs*/ null, { local: true }), { silent: true });
}

// The main function to be executed.
function performDeployTask(accessKey, appName, packagePath, appStoreVersion, deploymentName, description, isMandatory) {
  // If function arguments are provided (e.g. during test), use those, else, get user inputs provided by VSTS.
  var authType = tl.getInput("authType", false);
  if (authType === "AccessKey") {
      accessKey = tl.getInput("accessKey", true);
  } else if (authType === "ServiceEndpoint") {
      var serviceAccount = tl.getEndpointAuthorization(tl.getInput("serviceEndpoint", true));
      accessKey = serviceAccount.parameters.password;
  }

  appName         = appName || tl.getInput("appName", true);
  packagePath     = packagePath || tl.getPathInput("packagePath", true);
  appStoreVersion = appStoreVersion || tl.getInput("appStoreVersion", true);
  deploymentName  = deploymentName || tl.getInput("deploymentName", false);
  description     = description || tl.getInput("description", false);
  isMandatory     = isMandatory || tl.getInput("isMandatory", false);

  if (!accessKey) {
      console.error("Access key required");
      tl.setResult(1, "Access key required");
  }

  // Ensure all other users are logged out.
  ensureLoggedOut();

  // Log in to the CodePush CLI.
  executeCommandAndHandleResult("login", /*positionArgs*/ null, { accessKey: accessKey });

  // Run release command.
  executeCommandAndHandleResult(
    "release",
    [appName, packagePath, appStoreVersion],
    {
      deploymentName: deploymentName,
      description: description,
      mandatory: isMandatory
    }
  );

  // Log out.
  ensureLoggedOut();
}

module.exports = {
  buildCommand: buildCommand,
  commandPrefix: codePushCommandPrefix,
  ensureLoggedOut: ensureLoggedOut,
  executeCommandAndHandleResult: executeCommandAndHandleResult,
  log: log,
  performDeployTask: performDeployTask
}

if (require.main === module) {
  // Only run the deploy task if the script is being run directly, and not imported as a module (eg. during test)
  performDeployTask();
}
<|endoftext|>


<commit_before>angular.module('mean').directive('ngEnter', function() {
    return function(scope, elm, attrs) {
        elm.bind('keypress', function(e) {
            if (e.charCode === 13 && !e.ctrlKey) scope.$apply(attrs.ngEnter);
        });
    };
});

angular.module('mean').directive('ngEditable', function() {
    return {
        // can be in-lined or async loaded by xhr
        // or inlined as JS string (using template property)
        template: '' + '{{model}}' + '<input type="text" data-ng-model="value" data-ng-blur="edit = false; model = value" data-ng-show="edit" data-ng-enter="model=value;edit=false;"/>' + '',
        scope: {
            model: '=ngEditableModel',
            update: '&ngEditable'
        },
        replace: true,
        link: function(scope, element, attrs) {
            // scope.$watch('model', function() {
            //     console.log('hhhhh');
            // });
            scope.focus = function() {
                console.log(element.find("input"));
                element.find("input").focus();
            };

            scope.$watch('edit', function(isEditable) {
                if (isEditable === false) {
                    scope.update();
                } else {
                    // scope.focus();
                }
            });
        }
    };
});

angular.module('mean').directive('ngEditableParagraph', function() {
    return {
        // can be in-lined or async loaded by xhr
        // or inlined as JS string (using template property)
        template: '' + '{{model}}' + '<textarea data-ng-model="value" data-ng-blur="model=value ; edit=false" data-ng-show="edit" data-ng-enter="model=value;edit=false;" class="span8"></textarea>' + '',
        scope: {
            model: '=ngEditableModel',
            update: '&ngEditableParagraph'
        },
        replace: true,
        link: function(scope, element, attrs) {
            scope.focus = function() {
                element.find("input").focus();
            };
            scope.$watch('edit', function(isEditable) {
                if (isEditable === false) {
                    scope.update();
                } else {
                    scope.focus();
                }
            });
        }
    };
});

angular.module('mean').directive('ngEditableSelect', function() {
    return {
        template: '' + '{{m}};' + '<select data-ng-model="value" data-ng-show="edit" data-ng-multiple="true" multiple data-ng-options="option for option in options" data-ng-change="model=value;edit=false;">' + '<option value="">Choose Option</option>' + '</select>' + '',
        scope: {
            text: '&ngEditableSelectText',
            model: '=ngEditableSelectModel',
            options: '=ngEditableSelectOptions',
            update: '&ngEditableSelect'
        },
        transclude: true,
        replace: true,
        link: function(scope, element, attrs) {
            scope.$watch('edit', function(isEditable) {
                if (isEditable === false) {
                    scope.update();
                }
            });
        }
    };
});

angular.module('mean').directive('ezDatepicker', function() {
    return {
        restrict: 'A',
        link: function(scope, element, attrs) {
            element.datetimepicker({
             lang:'fr',
             i18n:{
              fr:{
               months:[
                'Janvier','Fevrier','Mars','Avril',
                'Mai','Juin','Juiller','Aout',
                'Septembre','Octobre','Novembre','Decembre',
               ],
               dayOfWeek:[
                "Dim.", "Lun", "Mar", "Mer",
                "Jeu", "Ven", "Sam",
               ]
              }
             },
             timepicker:false,
             format:'Y-m-d'
            });
        }
    };
});

<commit_msg>fix juiller to juillet<commit_after>angular.module('mean').directive('ngEnter', function() {
    return function(scope, elm, attrs) {
        elm.bind('keypress', function(e) {
            if (e.charCode === 13 && !e.ctrlKey) scope.$apply(attrs.ngEnter);
        });
    };
});

angular.module('mean').directive('ngEditable', function() {
    return {
        // can be in-lined or async loaded by xhr
        // or inlined as JS string (using template property)
        template: '' + '{{model}}' + '<input type="text" data-ng-model="value" data-ng-blur="edit = false; model = value" data-ng-show="edit" data-ng-enter="model=value;edit=false;"/>' + '',
        scope: {
            model: '=ngEditableModel',
            update: '&ngEditable'
        },
        replace: true,
        link: function(scope, element, attrs) {
            // scope.$watch('model', function() {
            //     console.log('hhhhh');
            // });
            scope.focus = function() {
                console.log(element.find("input"));
                element.find("input").focus();
            };

            scope.$watch('edit', function(isEditable) {
                if (isEditable === false) {
                    scope.update();
                } else {
                    // scope.focus();
                }
            });
        }
    };
});

angular.module('mean').directive('ngEditableParagraph', function() {
    return {
        // can be in-lined or async loaded by xhr
        // or inlined as JS string (using template property)
        template: '' + '{{model}}' + '<textarea data-ng-model="value" data-ng-blur="model=value ; edit=false" data-ng-show="edit" data-ng-enter="model=value;edit=false;" class="span8"></textarea>' + '',
        scope: {
            model: '=ngEditableModel',
            update: '&ngEditableParagraph'
        },
        replace: true,
        link: function(scope, element, attrs) {
            scope.focus = function() {
                element.find("input").focus();
            };
            scope.$watch('edit', function(isEditable) {
                if (isEditable === false) {
                    scope.update();
                } else {
                    scope.focus();
                }
            });
        }
    };
});

angular.module('mean').directive('ngEditableSelect', function() {
    return {
        template: '' + '{{m}};' + '<select data-ng-model="value" data-ng-show="edit" data-ng-multiple="true" multiple data-ng-options="option for option in options" data-ng-change="model=value;edit=false;">' + '<option value="">Choose Option</option>' + '</select>' + '',
        scope: {
            text: '&ngEditableSelectText',
            model: '=ngEditableSelectModel',
            options: '=ngEditableSelectOptions',
            update: '&ngEditableSelect'
        },
        transclude: true,
        replace: true,
        link: function(scope, element, attrs) {
            scope.$watch('edit', function(isEditable) {
                if (isEditable === false) {
                    scope.update();
                }
            });
        }
    };
});

angular.module('mean').directive('ezDatepicker', function() {
    return {
        restrict: 'A',
        link: function(scope, element, attrs) {
            element.datetimepicker({
             lang:'fr',
             i18n:{
              fr:{
               months:[
                'Janvier','Fevrier','Mars','Avril',
                'Mai','Juin','Juillet','Aout',
                'Septembre','Octobre','Novembre','Decembre',
               ],
               dayOfWeek:[
                "Dim.", "Lun", "Mar", "Mer",
                "Jeu", "Ven", "Sam",
               ]
              }
             },
             timepicker:false,
             format:'Y-m-d'
            });
        }
    };
});

<|endoftext|>


<commit_before>'use strict';

const audioUtil = require('../utils/audio');

const PhysicsSprite = require('./physics-sprite');

class Barrier extends PhysicsSprite {
  constructor(game, x, y) {
    super(game, x, y, 'barrier', 2, true);

    this.animations.add('up', [ 2, 1, 0 ], 10, false);
    this.animations.add('down', [ 0, 1, 2 ], 10, false);

    this.introSfx = audioUtil.addSfx(
      game, 'barrier', game.rnd.integerInRange(0, 2)
    );
  }

  playIntro() {
    this.animations.play('up');

    this.introSfx.play();
  }

  playOutro() {
    this.animations.play('down');
  }
}

module.exports = Barrier;
<commit_msg>Fix the call to addSfx broken by the signature change<commit_after>'use strict';

const audioUtil = require('../utils/audio');

const PhysicsSprite = require('./physics-sprite');

class Barrier extends PhysicsSprite {
  constructor(game, x, y) {
    super(game, x, y, 'barrier', 2, true);

    this.animations.add('up', [ 2, 1, 0 ], 10, false);
    this.animations.add('down', [ 0, 1, 2 ], 10, false);

    this.introSfx = audioUtil.addSfx('barrier', game.rnd.integerInRange(0, 2));
  }

  playIntro() {
    this.animations.play('up');

    this.introSfx.play();
  }

  playOutro() {
    this.animations.play('down');
  }
}

module.exports = Barrier;
<|endoftext|>


<commit_before>import { CellSelector } from '../cell/cell.selector';
import { Command } from '../command/command';
import { GRID_PREFIX } from '../definition';
import { findLeaves, findNode } from '../node/node.service';
import { SelectionService } from '../selection/selection.service';
import { Fastdom } from '../services/fastdom';
import * as sortService from '../sort/sort.service';
import { noop } from '../utility/kit';

export class HighlightLet {
	constructor(plugin) {
		const { model, table, observeReply, observe } = plugin;
		this.plugin = plugin;

		this.cellSelector = new CellSelector(model, table);
		this.selectionService = new SelectionService(model);

		let sortBlurs = [];
		let columnHoverBlurs = [];
		let columnFilterBlurs = [];
		let rowHoverBlurs = [];
		let selectionBlurs = [];
		let cellHoverBlurs = [];

		this.column = new Command({
			source: 'highlight.view',
			canExecute: () => !this.isRendering,
			execute: (column, state) => {
				const columns = Array.from(model.highlight().columns);
				const index = columns.indexOf(column.key);
				let hasChanges = false;
				if (state) {
					if (index < 0) {
						columns.push(column.key);
						hasChanges = true;
					}
				}
				else {
					if (index >= 0) {
						columns.splice(index, 1);
						hasChanges = true;
					}
				}

				if (hasChanges) {
					model.highlight({ columns }, {
						source: 'highlight.view',
					});
				}
			}
		});

		this.row = new Command({
			source: 'highlight.view',
			canExecute: () => !this.isRendering,
			execute: (row, state) => {
				const rows = Array.from(model.highlight().rows);
				const index = rows.indexOf(row);
				let hasChanges = false;
				if (state) {
					if (index < 0) {
						rows.push(row);
						hasChanges = true;
					}
				}
				else {
					if (index >= 0) {
						rows.splice(index, 1);
						hasChanges = true;
					}
				}

				if (hasChanges) {
					model.highlight({ rows }, {
						source: 'highlight.view'
					});
				}
			}
		});

		this.cell = new Command({
			source: 'highlight.view',
			canExecute: () => !this.isRendering,
			execute: (newCell, state) => {
				let { cell } = model.highlight();
				let hasChanges = true;
				if (newCell === cell) {
					hasChanges = false;
				}
				else if (newCell && cell) {
					hasChanges =
						newCell.rowIndex !== cell.rowIndex
						|| newCell.columnIndex !== cell.columnIndex;
				}

				if (hasChanges) {
					model.highlight({ cell: newCell }, {
						source: 'highlight.view'
					});
				}
			}
		});

		this.clear = new Command({
			execute: () => {
				const { rows, cell } = model.highlight();

				rows.forEach(rowIndex => this.row.execute(rowIndex, false));

				if (cell) {
					this.cell.execute(null, false);
				}
			}
		});

		observeReply(model.selectionChanged)
			.subscribe(e => {
				if (e.hasChanges('items')) {
					selectionBlurs = this.invalidateSelection(selectionBlurs);
				}
			});

		observeReply(model.sceneChanged)
			.subscribe(e => {
				if (e.hasChanges('status')) {
					if (e.state.status === 'stop') {
						columnHoverBlurs = this.invalidateColumnHover(columnHoverBlurs);
						rowHoverBlurs = this.invalidateRowHover(rowHoverBlurs);
						cellHoverBlurs = this.invalidateCellHover(cellHoverBlurs);
						sortBlurs = this.invalidateSortBy(sortBlurs);
						selectionBlurs = this.invalidateSelection(selectionBlurs);
					}
				}
			});

		observeReply(model.sortChanged)
			.subscribe(e => {
				if (!this.isRendering && e.hasChanges('by')) {
					sortBlurs = this.invalidateSortBy(sortBlurs);
				}
			});

		observeReply(model.filterChanged)
			.subscribe(e => {
				if (!this.isRendering && e.hasChanges('by')) {
					columnFilterBlurs = this.invalidateColumnFilterBy(columnFilterBlurs);
				}
			});

		observeReply(model.highlightChanged)
			.subscribe(e => {
				if (!this.isRendering) {
					if (e.hasChanges('cell')) {
						cellHoverBlurs = this.invalidateCellHover(cellHoverBlurs);
					}

					if (e.hasChanges('columns')) {
						columnHoverBlurs = this.invalidateColumnHover(columnHoverBlurs);
					}

					if (e.hasChanges('rows')) {
						rowHoverBlurs = this.invalidateRowHover(rowHoverBlurs);
					}
				}
			});

		observe(model.dragChanged)
			.subscribe(e => {
				if (e.hasChanges('isActive')) {
					if (e.state.isActive) {
						model.highlight({
							columns: [],
							rows: [],
							cell: null
						}, {
							source: 'highlight.view'
						});

						columnHoverBlurs = this.invalidateColumnHover(columnHoverBlurs);
						rowHoverBlurs = this.invalidateRowHover(rowHoverBlurs);
						cellHoverBlurs = this.invalidateCellHover(cellHoverBlurs);
					}
				}
			})
	}

	get isRendering() {
		const { model } = this.plugin;
		return model.scene().status !== 'stop' || model.drag().isActive;
	}

	invalidateColumnHover(dispose) {
		dispose.forEach(f => f());

		const { model } = this.plugin;
		const { columns } = model.highlight();

		return columns
			.map(columnKey => this.highlightColumn(columnKey, 'highlighted'));
	}

	invalidateColumnFilterBy(dispose) {
		dispose.forEach(f => f());

		const { model } = this.plugin;
		const { by } = model.filter();

		dispose = [];
		const keys = Object.keys(by);
		for (let key of keys) {
			dispose.push(this.highlightColumn(key, 'filtered'));
		}

		return dispose;
	}

	invalidateRowHover(dispose) {
		dispose.forEach(f => f());

		const { model } = this.plugin;
		const { rows } = model.highlight();

		return rows
			.map(row => this.highlightRow(row, 'highlighted'));
	}

	invalidateCellHover(dispose) {
		dispose.forEach(f => f());

		const { model, table } = this.plugin;
		const { cell } = model.highlight();

		dispose = [];
		if (cell) {
			const { body } = table;
			const { rowIndex, columnIndex } = cell;
			dispose.push(this.highlightCell(body.cell(rowIndex, columnIndex), 'highlighted'));
		}

		return dispose;
	}

	invalidateSortBy(dispose) {
		dispose.forEach(f => f());

		const { model } = this.plugin;
		const sortBy = model.sort().by;

		dispose = [];
		for (let entry of sortBy) {
			const key = sortService.getKey(entry);
			dispose.push(this.highlightColumn(key, 'sorted'));
		}

		return dispose;
	}

	invalidateSelection(dispose) {
		dispose.forEach(f => f());

		const { model } = this.plugin;
		const { items } = model.selection();

		const entries = this.selectionService.lookup(items);
		const cells = this.cellSelector.map(entries);

		return cells
			.map(cell => this.highlightCell(cell, 'selected'));
	}

	findColumnPosition(key) {
		const { model } = this.plugin;
		const { index } = model.columnList();

		const pos = findNode(index, node => node.key.model.key === key);
		if (pos) {
			return findLeaves(pos.node).map(leaf => leaf.key.columnIndex);
		}

		return [];
	}

	highlightColumn(key, cls) {
		const { table } = this.plugin;

		const position = this.findColumnPosition(key);
		if (!position.length) {
			return noop;
		}

		const { head, body, foot } = table;
		Fastdom.mutate(() => {
			const isLeaf = position.length === 1;
			for (let index of position) {
				if (isLeaf) {
					head.column(index).addClass(`${GRID_PREFIX}-${cls}`);
					head.column(index - 1).addClass(`${GRID_PREFIX}-${cls}-prev`);
					head.column(index + 1).addClass(`${GRID_PREFIX}-${cls}-next`);
				}

				const bodyColumn = body.column(index);
				const column = bodyColumn.model();
				if (column && column.canHighlight) {
					bodyColumn.addClass(`${GRID_PREFIX}-${cls}`);
					foot.column(index).addClass(`${GRID_PREFIX}-${cls}`);
				}
			}
		});

		return this.blurColumn(key, cls);
	}

	blurColumn(key, cls) {
		const { table } = this.plugin;

		const position = this.findColumnPosition(key);
		if (!position.length) {
			return noop;
		}

		const { head, body, foot } = table;
		return () => {
			Fastdom.mutate(() => {
				for (let index of position) {
					head.column(index).removeClass(`${GRID_PREFIX}-${cls}`);
					head.column(index - 1).removeClass(`${GRID_PREFIX}-${cls}-prev`);
					head.column(index + 1).removeClass(`${GRID_PREFIX}-${cls}-next`);
					body.column(index).removeClass(`${GRID_PREFIX}-${cls}`);
					foot.column(index).removeClass(`${GRID_PREFIX}-${cls}`);
				}
			});
		};
	}

	highlightRow(index, cls) {
		const { table } = this.plugin;

		if (index < 0) {
			return noop;
		}

		const { body } = table;
		Fastdom.mutate(() => body.row(index).addClass(`${GRID_PREFIX}-${cls}`));

		return this.blurRow(index, cls);
	}

	blurRow(index, cls) {
		const { table } = this.plugin;

		if (index < 0) {
			return noop;
		}

		const row = table.body.row(index);
		return () => Fastdom.mutate(() => row.removeClass(`${GRID_PREFIX}-${cls}`));
	}

	highlightCell(cell, cls) {
		Fastdom.mutate(() => {
			cell.addClass(`${GRID_PREFIX}-${cls}`);
		});

		return this.blurCell(cell, cls);
	}

	blurCell(cell, cls) {
		return () =>
			Fastdom.mutate(() => {
				cell.removeClass(`${GRID_PREFIX}-${cls}`);
			});
	}
}<commit_msg>fix: code-review<commit_after>import { CellSelector } from '../cell/cell.selector';
import { Command } from '../command/command';
import { GRID_PREFIX } from '../definition';
import { findLeaves, findNode } from '../node/node.service';
import { SelectionService } from '../selection/selection.service';
import { Fastdom } from '../services/fastdom';
import * as sortService from '../sort/sort.service';
import { noop } from '../utility/kit';

export class HighlightLet {
	constructor(plugin) {
		const { model, table, observeReply, observe } = plugin;
		this.plugin = plugin;

		this.cellSelector = new CellSelector(model, table);
		this.selectionService = new SelectionService(model);

		let sortBlurs = [];
		let columnHoverBlurs = [];
		let columnFilterBlurs = [];
		let rowHoverBlurs = [];
		let selectionBlurs = [];
		let cellHoverBlurs = [];

		this.column = new Command({
			source: 'highlight.view',
			canExecute: () => !this.isRendering,
			execute: (column, state) => {
				const columns = Array.from(model.highlight().columns);
				const index = columns.indexOf(column.key);
				let hasChanges = false;
				if (state) {
					if (index < 0) {
						columns.push(column.key);
						hasChanges = true;
					}
				}
				else {
					if (index >= 0) {
						columns.splice(index, 1);
						hasChanges = true;
					}
				}

				if (hasChanges) {
					model.highlight({ columns }, {
						source: 'highlight.view',
					});
				}
			}
		});

		this.row = new Command({
			source: 'highlight.view',
			canExecute: () => !this.isRendering,
			execute: (row, state) => {
				const rows = Array.from(model.highlight().rows);
				const index = rows.indexOf(row);
				let hasChanges = false;
				if (state) {
					if (index < 0) {
						rows.push(row);
						hasChanges = true;
					}
				}
				else {
					if (index >= 0) {
						rows.splice(index, 1);
						hasChanges = true;
					}
				}

				if (hasChanges) {
					model.highlight({ rows }, {
						source: 'highlight.view'
					});
				}
			}
		});

		this.cell = new Command({
			source: 'highlight.view',
			canExecute: () => !this.isRendering,
			execute: (newCell, state) => {
				let { cell } = model.highlight();
				let hasChanges = true;
				if (newCell === cell) {
					hasChanges = false;
				}
				else if (newCell && cell) {
					hasChanges =
						newCell.rowIndex !== cell.rowIndex
						|| newCell.columnIndex !== cell.columnIndex;
				}

				if (hasChanges) {
					model.highlight({ cell: newCell }, {
						source: 'highlight.view'
					});
				}
			}
		});

		this.clear = new Command({
			execute: () => {
				const { rows, cell } = model.highlight();

				rows.forEach(rowIndex => this.row.execute(rowIndex, false));

				if (cell) {
					this.cell.execute(null, false);
				}
			}
		});

		observeReply(model.selectionChanged)
			.subscribe(e => {
				if (e.hasChanges('items')) {
					selectionBlurs = this.invalidateSelection(selectionBlurs);
				}
			});

		observeReply(model.sceneChanged)
			.subscribe(e => {
				if (e.hasChanges('status')) {
					if (e.state.status === 'stop') {
						columnHoverBlurs = this.invalidateColumnHover(columnHoverBlurs);
						rowHoverBlurs = this.invalidateRowHover(rowHoverBlurs);
						cellHoverBlurs = this.invalidateCellHover(cellHoverBlurs);
						sortBlurs = this.invalidateSortBy(sortBlurs);
						selectionBlurs = this.invalidateSelection(selectionBlurs);
					}
				}
			});

		observeReply(model.sortChanged)
			.subscribe(e => {
				if (!this.isRendering && e.hasChanges('by')) {
					sortBlurs = this.invalidateSortBy(sortBlurs);
				}
			});

		observeReply(model.filterChanged)
			.subscribe(e => {
				if (!this.isRendering && e.hasChanges('by')) {
					columnFilterBlurs = this.invalidateColumnFilterBy(columnFilterBlurs);
				}
			});

		observeReply(model.highlightChanged)
			.subscribe(e => {
				if (!this.isRendering) {
					if (e.hasChanges('cell')) {
						cellHoverBlurs = this.invalidateCellHover(cellHoverBlurs);
					}

					if (e.hasChanges('columns')) {
						columnHoverBlurs = this.invalidateColumnHover(columnHoverBlurs);
					}

					if (e.hasChanges('rows')) {
						rowHoverBlurs = this.invalidateRowHover(rowHoverBlurs);
					}
				}
			});

		observe(model.dragChanged)
			.subscribe(e => {
				if (e.hasChanges('isActive')) {
					if (e.state.isActive) {
						model.highlight({
							columns: [],
							rows: [],
							cell: null
						}, {
							source: 'highlight.view'
						});

						columnHoverBlurs = this.invalidateColumnHover(columnHoverBlurs);
						rowHoverBlurs = this.invalidateRowHover(rowHoverBlurs);
						cellHoverBlurs = this.invalidateCellHover(cellHoverBlurs);
					}
				}
			})
	}

	get isRendering() {
		const { model } = this.plugin;
		return model.scene().status !== 'stop' || model.drag().isActive;
	}

	invalidateColumnHover(dispose) {
		dispose.forEach(f => f());

		const { model } = this.plugin;
		const { columns } = model.highlight();

		return columns
			.map(columnKey => this.highlightColumn(columnKey, 'highlighted'));
	}

	invalidateColumnFilterBy(dispose) {
		dispose.forEach(f => f());

		const { model } = this.plugin;
		const { by } = model.filter();

		dispose = [];
		const keys = Object.keys(by);
		for (let key of keys) {
      if (key === '$expression') {
        continue;
      }

			dispose.push(this.highlightColumn(key, 'filtered'));
		}

		return dispose;
	}

	invalidateRowHover(dispose) {
		dispose.forEach(f => f());

		const { model } = this.plugin;
		const { rows } = model.highlight();

		return rows
			.map(row => this.highlightRow(row, 'highlighted'));
	}

	invalidateCellHover(dispose) {
		dispose.forEach(f => f());

		const { model, table } = this.plugin;
		const { cell } = model.highlight();

		dispose = [];
		if (cell) {
			const { body } = table;
			const { rowIndex, columnIndex } = cell;
			dispose.push(this.highlightCell(body.cell(rowIndex, columnIndex), 'highlighted'));
		}

		return dispose;
	}

	invalidateSortBy(dispose) {
		dispose.forEach(f => f());

		const { model } = this.plugin;
		const sortBy = model.sort().by;

		dispose = [];
		for (let entry of sortBy) {
			const key = sortService.getKey(entry);
			dispose.push(this.highlightColumn(key, 'sorted'));
		}

		return dispose;
	}

	invalidateSelection(dispose) {
		dispose.forEach(f => f());

		const { model } = this.plugin;
		const { items } = model.selection();

		const entries = this.selectionService.lookup(items);
		const cells = this.cellSelector.map(entries);

		return cells
			.map(cell => this.highlightCell(cell, 'selected'));
	}

	findColumnPosition(key) {
		const { model } = this.plugin;
		const { index } = model.columnList();

		const pos = findNode(index, node => node.key.model.key === key);
		if (pos) {
			return findLeaves(pos.node).map(leaf => leaf.key.columnIndex);
		}

		return [];
	}

	highlightColumn(key, cls) {
		const { table } = this.plugin;

		const position = this.findColumnPosition(key);
		if (!position.length) {
			return noop;
		}

		const { head, body, foot } = table;
		Fastdom.mutate(() => {
			const isLeaf = position.length === 1;
			for (let index of position) {
				if (isLeaf) {
					head.column(index).addClass(`${GRID_PREFIX}-${cls}`);
					head.column(index - 1).addClass(`${GRID_PREFIX}-${cls}-prev`);
					head.column(index + 1).addClass(`${GRID_PREFIX}-${cls}-next`);
				}

				const bodyColumn = body.column(index);
				const column = bodyColumn.model();
				if (column && column.canHighlight) {
					bodyColumn.addClass(`${GRID_PREFIX}-${cls}`);
					foot.column(index).addClass(`${GRID_PREFIX}-${cls}`);
				}
			}
		});

		return this.blurColumn(key, cls);
	}

	blurColumn(key, cls) {
		const { table } = this.plugin;

		const position = this.findColumnPosition(key);
		if (!position.length) {
			return noop;
		}

		const { head, body, foot } = table;
		return () => {
			Fastdom.mutate(() => {
				for (let index of position) {
					head.column(index).removeClass(`${GRID_PREFIX}-${cls}`);
					head.column(index - 1).removeClass(`${GRID_PREFIX}-${cls}-prev`);
					head.column(index + 1).removeClass(`${GRID_PREFIX}-${cls}-next`);
					body.column(index).removeClass(`${GRID_PREFIX}-${cls}`);
					foot.column(index).removeClass(`${GRID_PREFIX}-${cls}`);
				}
			});
		};
	}

	highlightRow(index, cls) {
		const { table } = this.plugin;

		if (index < 0) {
			return noop;
		}

		const { body } = table;
		Fastdom.mutate(() => body.row(index).addClass(`${GRID_PREFIX}-${cls}`));

		return this.blurRow(index, cls);
	}

	blurRow(index, cls) {
		const { table } = this.plugin;

		if (index < 0) {
			return noop;
		}

		const row = table.body.row(index);
		return () => Fastdom.mutate(() => row.removeClass(`${GRID_PREFIX}-${cls}`));
	}

	highlightCell(cell, cls) {
		Fastdom.mutate(() => {
			cell.addClass(`${GRID_PREFIX}-${cls}`);
		});

		return this.blurCell(cell, cls);
	}

	blurCell(cell, cls) {
		return () =>
			Fastdom.mutate(() => {
				cell.removeClass(`${GRID_PREFIX}-${cls}`);
			});
	}
}<|endoftext|>


<commit_before>//{namespace name=backend/bepado/view/main}

//{block name="backend/bepado/view/changed_products/tabs"}
Ext.define('Shopware.apps.Bepado.view.changed_products.Tabs', {
    extend: 'Ext.tab.Panel',
    alias: 'widget.bepado-changed-products-tabs',

    height: 300,

    border: false,

    title: '{s name=changed_products/changeview}Changes{/s}',

    initComponent: function() {
        var me = this;

        me.createItems();

        me.callParent(arguments);
    },

    /**
     * Creates the actual tabs for the known fields
     */
    createItems: function() {
        var me = this;

        me.fields = { };
        Ext.each(['price', 'shortDescription', 'longDescription', 'name', 'image'], function(field) {
            me.fields[field] = me.createContainer(field);
        });
    },

    /**
     * Creates the tab for given field type. Each tab will have a field for the remote and for the local value
     * so the user can compare them
     *
     * @param name
     * @returns Object
     */
    createContainer: function(name) {
        var me = this,
            config, applyButton,
            local, remote;

        // Define the fields for the given type
        switch (name) {
            case 'price':
                config = {
                    xtype: 'numberfield',
                    precision: 2,
                    title: me.getTranslatedTitle('price')
                };
                break;
            case 'name':
                config = {
                    xtype: 'textfield',
                    title: me.getTranslatedTitle('name')
                };
                break;
            case 'shortDescription':
                config = {
                    xtype: 'textarea',
                    title: me.getTranslatedTitle('shortDescription'),
                    height: 150
                };
                break;
            case 'longDescription':
                config = {
                    xtype: 'textarea',
                    title: me.getTranslatedTitle('longDescription'),
                    height: 150
                };
                break;
            case 'image':
                config = {
                    xtype: 'shopware-images-field',
                    title: me.getTranslatedTitle('image'),
                    margin: 10
                };
        }

        // Define some default options for the local / remote field
        // The name is generated from the passed name and the prefix "local"/"remote"
        local = {
            fieldLabel: 'Current',
            name: name + '{s name=changed_products/local}Local{/s}',
            enabled: false
        };
        remote = {
            fieldLabel: '{s name=changed_products/remote}Remote{/s}',
            name: name + 'Remote',
            enabled: false
        };

        // Merge local/remote objects and the generated type-related object
        Ext.apply(local, config);
        Ext.apply(remote, config);

        applyButton = Ext.create('Ext.button.Button', {
            text: '{s name=changed_products/applyButton}Apply changes now{/s}'
        });

        // Create a form and put the local and remote field into
        return Ext.create('Ext.form.Panel', {
                autoScroll: true,
                title: config.title,
                border: false,
                layout: {
                    type: 'vbox',
                    align: 'stretch'
                },
                defaults: {
                    padding: 10,
                    border: false
                },
                applyButton: applyButton,
                items: [applyButton, local, remote]
            });
    },

    /**
     * Helper to translate titles like name, price…
     *
     * @param title
     * @returns string
     */
    getTranslatedTitle: function(title) {
        switch (title) {
            case 'name':
                return '{s name=changed_products/title/name}Name{/s}';
            case 'price':
                return '{s name=changed_products/title/price}Price{/s}';
            case 'image':
                return '{s name=changed_products/title/image}Image{/s}';
            case 'longDescription':
                return '{s name=changed_products/title/longDescription}longDescription{/s}';
            case 'shortDescription':
                return '{s name=changed_products/title/shortDescription}shortDescription{/s}';
            default:
                return '';
        }
    }

});
//{/block}<commit_msg>NTR - Changes default translation<commit_after>//{namespace name=backend/bepado/view/main}

//{block name="backend/bepado/view/changed_products/tabs"}
Ext.define('Shopware.apps.Bepado.view.changed_products.Tabs', {
    extend: 'Ext.tab.Panel',
    alias: 'widget.bepado-changed-products-tabs',

    height: 300,

    border: false,

    title: '{s name=changed_products/changeview}Changes{/s}',

    initComponent: function() {
        var me = this;

        me.createItems();

        me.callParent(arguments);
    },

    /**
     * Creates the actual tabs for the known fields
     */
    createItems: function() {
        var me = this;

        me.fields = { };
        Ext.each(['price', 'shortDescription', 'longDescription', 'name', 'image'], function(field) {
            me.fields[field] = me.createContainer(field);
        });
    },

    /**
     * Creates the tab for given field type. Each tab will have a field for the remote and for the local value
     * so the user can compare them
     *
     * @param name
     * @returns Object
     */
    createContainer: function(name) {
        var me = this,
            config, applyButton,
            local, remote;

        // Define the fields for the given type
        switch (name) {
            case 'price':
                config = {
                    xtype: 'numberfield',
                    precision: 2,
                    title: me.getTranslatedTitle('price')
                };
                break;
            case 'name':
                config = {
                    xtype: 'textfield',
                    title: me.getTranslatedTitle('name')
                };
                break;
            case 'shortDescription':
                config = {
                    xtype: 'textarea',
                    title: me.getTranslatedTitle('shortDescription'),
                    height: 150
                };
                break;
            case 'longDescription':
                config = {
                    xtype: 'textarea',
                    title: me.getTranslatedTitle('longDescription'),
                    height: 150
                };
                break;
            case 'image':
                config = {
                    xtype: 'shopware-images-field',
                    title: me.getTranslatedTitle('image'),
                    margin: 10
                };
        }

        // Define some default options for the local / remote field
        // The name is generated from the passed name and the prefix "local"/"remote"
        local = {
            fieldLabel: 'Current',
            name: name + '{s name=changed_products/local}Local{/s}',
            enabled: false
        };
        remote = {
            fieldLabel: '{s name=changed_products/remote}Remote{/s}',
            name: name + 'Remote',
            enabled: false
        };

        // Merge local/remote objects and the generated type-related object
        Ext.apply(local, config);
        Ext.apply(remote, config);

        applyButton = Ext.create('Ext.button.Button', {
            text: '{s name=changed_products/applyButton}Apply changes now{/s}'
        });

        // Create a form and put the local and remote field into
        return Ext.create('Ext.form.Panel', {
                autoScroll: true,
                title: config.title,
                border: false,
                layout: {
                    type: 'vbox',
                    align: 'stretch'
                },
                defaults: {
                    padding: 10,
                    border: false
                },
                applyButton: applyButton,
                items: [applyButton, local, remote]
            });
    },

    /**
     * Helper to translate titles like name, price…
     *
     * @param title
     * @returns string
     */
    getTranslatedTitle: function(title) {
        switch (title) {
            case 'name':
                return '{s name=changed_products/title/name}Name{/s}';
            case 'price':
                return '{s name=changed_products/title/price}Price{/s}';
            case 'image':
                return '{s name=changed_products/title/image}Image{/s}';
            case 'longDescription':
                return '{s name=changed_products/title/longDescription}longDescription{/s}';
            case 'shortDescription':
                return '{s name=changed_products/title/shortDescription}shortDescription{/s}';
            default:
                return title;
        }
    }

});
//{/block}<|endoftext|>