<commit_before>module.exports = function(grunt) {

    var pkg = grunt.file.readJSON('package.json');

    grunt.initConfig({
        pkg : pkg,
        props : {
            out : 'target',
            src : 'src/main',
            test : 'src/test',
            name : '<%=pkg.name%>-<%=pkg.version%>'
        },
        clean : ['target'],
        jslint: {
            webapp: {
                src: [
                    '<%= props.src%>/**/*.js'
                ],
                directives: {
                    browser: true,
                    white : true,
                    vars : true,
                    plusplus : true,
                    continue : true,
                    sloppy : true,
                    nomen: true,
                    unparam : true
                },
                options: {
                    junit: '<%= props.out%>/jslint/jslint-src-webapp.xml'
                }
            }
        },
        handlebars : {
            compile : {
                options : {
                    namespace : 'Harpy.Templates',
                    partialsUseNamespace : true,
                    processName : function(path) {
                        path = path.replace(".handlebars","");
                        return path.substr(path.lastIndexOf("/")+1);
                    }
                },
                files : {
                    '<%= props.out%>/templates/templates.js' : ['<%= props.src%>/handlebars/*.handlebars'],
                    '<%= props.test%>/resources/handlebars/templates.js' : ['<%= props.src%>/handlebars/*.handlebars']
                }
            }
        },
        copy : { // copy everything - so can run in dev mode
            info: {
                files: [
                    {
                        src: ['LICENSE','README.md'],
                        filter : 'isFile',
                        dest: '<%= props.out%>/<%=props.name%>/'
                    }
                ]
            }
        },
        concat: { // build the webapp
            js: {
                src: [
                    '<%= props.src%>/js/**/*.js',
                    '<%= props.out%>/templates/templates.js'
                ],
                dest: '<%= props.out%>/<%=props.name%>/<%=props.name%>.js'
            },
            css: {
                src: [
                    '<%= props.src%>/css/**/*.css'
                ],
                dest: '<%= props.out%>/<%=props.name%>/<%=props.name%>.css'
            }
        },
        gcc: {
            js: {
                src: ['<%= props.out%>/<%=props.name%>/<%=props.name%>.js'],
                dest: '<%= props.out%>/<%=props.name%>/<%=props.name%>.min.js'
            }
        },
        cssmin: {
            minify: {
                src: ['<%= props.out%>/<%=props.name%>/<%=props.name%>.css'],
                dest: '<%= props.out%>/<%=props.name%>/<%=props.name%>.min.css'
            }
        },
        compress : {
            main: {
                options: {
                    mode : 'tgz',
                    archive: '<%= props.out%>/<%=props.name%>.tgz'
                },
                files: [
                    {
                        src: ['<%= props.out%>/<%=props.name%>/**'],
                        flatten : true,
                        expand : true
                    }
                ]
            }
        }
    });

    grunt.loadNpmTasks('grunt-install-dependencies');
    grunt.loadNpmTasks('grunt-contrib-handlebars');

    for(var i in pkg.devDependencies) {
        if(pkg.devDependencies.hasOwnProperty(i)) {
            grunt.loadNpmTasks(i);
        }
    }

    grunt.registerTask('compile', ['jslint','copy','handlebars','concat','gcc','cssmin']);
    grunt.registerTask('package', ['compress']);
    grunt.registerTask('default', ['clean','compile','package']);

};<commit_msg>build zip as well as tarball<commit_after>module.exports = function(grunt) {

    var pkg = grunt.file.readJSON('package.json');

    grunt.initConfig({
        pkg : pkg,
        props : {
            out : 'target',
            src : 'src/main',
            test : 'src/test',
            name : '<%=pkg.name%>-<%=pkg.version%>'
        },
        clean : ['target'],
        jslint: {
            webapp: {
                src: [
                    '<%= props.src%>/**/*.js'
                ],
                directives: {
                    browser: true,
                    white : true,
                    vars : true,
                    plusplus : true,
                    continue : true,
                    sloppy : true,
                    nomen: true,
                    unparam : true
                },
                options: {
                    junit: '<%= props.out%>/jslint/jslint-src-webapp.xml'
                }
            }
        },
        handlebars : {
            compile : {
                options : {
                    namespace : 'Harpy.Templates',
                    partialsUseNamespace : true,
                    processName : function(path) {
                        path = path.replace(".handlebars","");
                        return path.substr(path.lastIndexOf("/")+1);
                    }
                },
                files : {
                    '<%= props.out%>/templates/templates.js' : ['<%= props.src%>/handlebars/*.handlebars'],
                    '<%= props.test%>/resources/handlebars/templates.js' : ['<%= props.src%>/handlebars/*.handlebars']
                }
            }
        },
        copy : { // copy everything - so can run in dev mode
            info: {
                files: [
                    {
                        src: ['LICENSE','README.md'],
                        filter : 'isFile',
                        dest: '<%= props.out%>/<%=props.name%>/'
                    }
                ]
            }
        },
        concat: { // build the webapp
            js: {
                src: [
                    '<%= props.src%>/js/**/*.js',
                    '<%= props.out%>/templates/templates.js'
                ],
                dest: '<%= props.out%>/<%=props.name%>/<%=props.name%>.js'
            },
            css: {
                src: [
                    '<%= props.src%>/css/**/*.css'
                ],
                dest: '<%= props.out%>/<%=props.name%>/<%=props.name%>.css'
            }
        },
        gcc: {
            js: {
                src: ['<%= props.out%>/<%=props.name%>/<%=props.name%>.js'],
                dest: '<%= props.out%>/<%=props.name%>/<%=props.name%>.min.js'
            }
        },
        cssmin: {
            minify: {
                src: ['<%= props.out%>/<%=props.name%>/<%=props.name%>.css'],
                dest: '<%= props.out%>/<%=props.name%>/<%=props.name%>.min.css'
            }
        },
        compress : {
            tgz: {
                options: {
                    mode : 'tgz',
                    archive: '<%= props.out%>/<%=props.name%>.tgz'
                },
                files: [
                    {
                        src: ['<%= props.out%>/<%=props.name%>/**'],
                        flatten : true,
                        expand : true
                    }
                ]
            },
            zip: {
                options: {
                    mode : 'zip',
                    archive: '<%= props.out%>/<%=props.name%>.zip'
                },
                files: [
                    {
                        src: ['<%= props.out%>/<%=props.name%>/**'],
                        flatten : true,
                        expand : true
                    }
                ]
            }
        }
    });

    grunt.loadNpmTasks('grunt-install-dependencies');
    grunt.loadNpmTasks('grunt-contrib-handlebars');

    for(var i in pkg.devDependencies) {
        if(pkg.devDependencies.hasOwnProperty(i)) {
            grunt.loadNpmTasks(i);
        }
    }

    grunt.registerTask('compile', ['jslint','copy','handlebars','concat','gcc','cssmin']);
    grunt.registerTask('package', ['compress']);
    grunt.registerTask('default', ['clean','compile','package']);

};<|endoftext|>


<commit_before>document.addEventListener('DOMContentLoaded', function() {
  var socketio = io.connect("http://localhost:8080");

  socketio.on("overrun", function() {
    window.alert("これ以上回せません");
  });
  socketio.on("next", function(next) {
    var state = getState(next);
    var element = document.getElementById("showNext");

    element.innerHTML = state.str;
    element.style.color = state.color;
  });

  document.getElementById("next").addEventListener("click", function(ev) {
    socketio.emit("next");
  });

  document.getElementById("reset").addEventListener("click", function(ev) {
    socketio.emit("reset");
  });
});
<commit_msg>socketioをグローバルに置く<commit_after>var socketio;

document.addEventListener('DOMContentLoaded', function() {
  socketio = io.connect("http://localhost:8080");

  socketio.on("overrun", function() {
    window.alert("これ以上回せません");
  });
  socketio.on("next", function(next) {
    var state = getState(next);
    var element = document.getElementById("showNext");

    element.innerHTML = state.str;
    element.style.color = state.color;
  });

  document.getElementById("next").addEventListener("click", function(ev) {
    socketio.emit("next");
  });

  document.getElementById("reset").addEventListener("click", function(ev) {
    socketio.emit("reset");
  });
});
<|endoftext|>


<commit_before>import React, { memo, useState } from 'react';
import { getThemeName, setThemeName, modernThemes, PARAMS_EVENT } from '.';
import { classicTheme }  from '../../src/style/themes';
import { withTheme } from '@storybook/theming';
import { useChannel } from '@storybook/api';
import {
  IconButton,
  WithTooltip,
  TooltipLinkList,
  Icons
} from '@storybook/components';
import addons, { types } from '@storybook/addons';
import { FORCE_RE_RENDER, STORY_MISSING } from '@storybook/core-events';
import styled from 'styled-components';

addons.register('sage/first-page', api => {
  api.on(STORY_MISSING, () => {
    api.selectStory('Welcome', 'Welcome Page')
  })
})

addons.register('sage/theme-switcher', api => {
  addons.add('sage/theme-switcher', {
    title: 'theme-switcher',
    type: types.TOOL,
    match: ({ viewMode }) => ['story', 'docs'].includes(viewMode),
    render: () => <ThemeSwitcher api={api} />,
  });
});

const IconButtonWithLabel = styled(IconButton)`
  display: inline-flex;
  align-items: center;
  cursor: ${({disabled}) => disabled ? 'not-allowed' : 'pointer'} !important;
`;

const IconButtonLabel = withTheme(styled.div`
  font-size: ${({theme}) => theme.typography.size.s2 - 1}px;
  margin-left: 10px;
`);

const ThemeIcon = styled.span`
  height: 1rem;
  width: 1rem;
  display: block;
  background: ${({background}) => background};
`;

export const ThemeSwitcher = memo(withTheme(({ api }) => {
  const [activeTheme, setTheme] = useState(getThemeName());
  const [expanded, setExpanded] = useState(false);
  const [isClassic, setIsClassic] = useState();
  useChannel({
    [PARAMS_EVENT]: ({isClassic}) => {
      setIsClassic(isClassic);
    },
  });

  const themeList = Object.keys(modernThemes).map(themeName => ({
    id: themeName,
    title: themeName,
    onClick: () => {
      setTheme(themeName);
      setThemeName(themeName);
      addons.getChannel().emit(FORCE_RE_RENDER);
    },
    right: <ThemeIcon background={modernThemes[themeName].colors.base}/>
  }));

  const isDocsMode =  api.getUrlState().viewMode === 'docs';
  if(!isDocsMode && isClassic){
    return <IconButtonWithLabel disabled><Icons icon="paintbrush" /><IconButtonLabel>{classicTheme.name}</IconButtonLabel></IconButtonWithLabel>
  }

  return (
    <WithTooltip
      placement="top"
      trigger="click"
      tooltipShown={expanded}
      onVisibilityChange={s => setExpanded(s)}
      tooltip={<TooltipLinkList links={themeList} />}
      closeOnClick
    >
      <IconButtonWithLabel><Icons icon="paintbrush" /><IconButtonLabel>{activeTheme}</IconButtonLabel></IconButtonWithLabel>
    </WithTooltip>
  );
}));<commit_msg>chore(storybook): turn off bottom panel on welcome page<commit_after>import React, { memo, useState } from 'react';
import { getThemeName, setThemeName, modernThemes, PARAMS_EVENT } from '.';
import { classicTheme }  from '../../src/style/themes';
import { withTheme } from '@storybook/theming';
import { useChannel } from '@storybook/api';
import {
  IconButton,
  WithTooltip,
  TooltipLinkList,
  Icons
} from '@storybook/components';
import addons, { types } from '@storybook/addons';
import { FORCE_RE_RENDER, STORY_MISSING } from '@storybook/core-events';
import styled from 'styled-components';

addons.register('sage/first-page', api => {
  api.on(STORY_MISSING, () => {
    api.selectStory('Welcome', 'Welcome Page');
    api.togglePanel(false);
  })
})

addons.register('sage/theme-switcher', api => {
  addons.add('sage/theme-switcher', {
    title: 'theme-switcher',
    type: types.TOOL,
    match: ({ viewMode }) => ['story', 'docs'].includes(viewMode),
    render: () => <ThemeSwitcher api={api} />,
  });
});

const IconButtonWithLabel = styled(IconButton)`
  display: inline-flex;
  align-items: center;
  cursor: ${({disabled}) => disabled ? 'not-allowed' : 'pointer'} !important;
`;

const IconButtonLabel = withTheme(styled.div`
  font-size: ${({theme}) => theme.typography.size.s2 - 1}px;
  margin-left: 10px;
`);

const ThemeIcon = styled.span`
  height: 1rem;
  width: 1rem;
  display: block;
  background: ${({background}) => background};
`;

export const ThemeSwitcher = memo(withTheme(({ api }) => {
  const [activeTheme, setTheme] = useState(getThemeName());
  const [expanded, setExpanded] = useState(false);
  const [isClassic, setIsClassic] = useState();
  useChannel({
    [PARAMS_EVENT]: ({isClassic}) => {
      setIsClassic(isClassic);
    },
  });

  const themeList = Object.keys(modernThemes).map(themeName => ({
    id: themeName,
    title: themeName,
    onClick: () => {
      setTheme(themeName);
      setThemeName(themeName);
      addons.getChannel().emit(FORCE_RE_RENDER);
    },
    right: <ThemeIcon background={modernThemes[themeName].colors.base}/>
  }));

  const isDocsMode =  api.getUrlState().viewMode === 'docs';
  if(!isDocsMode && isClassic){
    return <IconButtonWithLabel disabled><Icons icon="paintbrush" /><IconButtonLabel>{classicTheme.name}</IconButtonLabel></IconButtonWithLabel>
  }

  return (
    <WithTooltip
      placement="top"
      trigger="click"
      tooltipShown={expanded}
      onVisibilityChange={s => setExpanded(s)}
      tooltip={<TooltipLinkList links={themeList} />}
      closeOnClick
    >
      <IconButtonWithLabel><Icons icon="paintbrush" /><IconButtonLabel>{activeTheme}</IconButtonLabel></IconButtonWithLabel>
    </WithTooltip>
  );
}));<|endoftext|>


<commit_before>// ==UserScript==
// @name           futaba ID+IP popup
// @namespace      https://github.com/himuro-majika
// @description    同じIDやIPのレスをポップアップしちゃう
// @author         himuro_majika
// @note           赤福の「続きを読む」機能で読み込んだレスには反応しません。
// @note           適宜ページ全体をリロードしてください。
// @include        http://*.2chan.net/*/res/*.htm
// @version        1.1
// @grant          GM_addStyle
// @license        MIT
// @icon         data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAAPUExURYv4i2PQYy2aLUe0R////zorx9oAAAAFdFJOU/////8A+7YOUwAAAElJREFUeNqUj1EOwDAIQoHn/c88bX+2fq0kRsAoUXVAfwzCttWsDWzw0kNVWd2tZ5K9gqmMZB8libt4pSg6YlO3RnTzyxePAAMAzqMDgTX8hYYAAAAASUVORK5CYII=
// ==/UserScript==
(function () {

	var Start = new Date().getTime();//count parsing time
	var saba = location.host.replace(".2chan.net","") +
		location.pathname.replace("futaba.htm","");
	var timer;

	setClassAndName();
	createCounter();
	setEvent();
	setStyle();

	// ID/IPにclass,nameを設定する
	function setClassAndName() {
		res();
		// レス
		function res() {
			var atd = document.getElementsByClassName("rtd");
			for (var i = 0; i < atd.length; i++) {
				var td = atd[i];
				td.innerHTML = td.innerHTML.replace(
					/(I[DP]:\S+)/,
					"$1"
				);
			}
		}
	}
	// 出現数の表示
	function createCounter() {
		var a = document.getElementsByClassName("GM_fip_name");
		var ids = {};
		for (var i = 0; i < a.length; i++) {
			var node = a[i];
			var id = node.name;
			if (ids[id]) {
				ids[id]++;
			} else {
				ids[id] = 1;
			}
			var name = document.querySelectorAll(".GM_fip_name[name='" + id + "']");
			var span = document.createElement("span");
			span.setAttribute("class", "GM_fip_counter");
			span.textContent = "[" + ids[id] + "/" + name.length + "]";
			// node.parentNode.insertBefore(span, node.nextSibling);
			node.appendChild(span);
		}
	}
	// イベントを設定
	function setEvent() {
		var aa = document.getElementsByClassName("GM_fip_name");
		for (var i = 0; i < aa.length; i++) {
			var a = aa[i];
			a.addEventListener("mouseover",show,true);
			a.addEventListener("mouseout",hide,true);
		}
	}
	// ポップアップを表示する
	function show(event) {
		delpop();
		var wX;	//ポップアップ表示位置X
		var wY;	//ポップアップ表示位置Y
		var tda = document.getElementsByName(this.name);
		var restable = [];
		for (var i = 0; i < tda.length; i++) {
			restable.push(tda[i].parentNode.parentNode.parentNode.innerHTML);
		}
		var table = document.createElement("table");
		table.id = "GM_fip_pop";
		table.innerHTML = restable.join(" ");
		table.addEventListener("mouseover",function(){
			clearTimeout(timer);
		},true);
		table.addEventListener("mouseout",hide,true);
		var body = document.getElementsByTagName("body");
		body[0].appendChild(table);
		wX = event.clientX;
		wY = window.scrollY + event.clientY - table.clientHeight;
		if ( wY < 0 ) {	//ポップアップが上に見きれる時は下に表示
			wY = window.scrollY + event.clientY;
		}
		table.setAttribute("style", "left:" + wX + "px; top:" + wY + "px;");
	}
	// ポップアップを消す
	function hide() {
		timer = setTimeout(delpop,250);
	}

	function delpop() {
		var doc_pop = document.getElementById("GM_fip_pop");
		if ( doc_pop ) {
			doc_pop.parentNode.removeChild(doc_pop);
		}
	}
	/*
	 * スタイル設定
	 */
	function setStyle() {
		var css = "#GM_fip_pop {" +
			"  position: absolute;" +
			"  z-index: 500;" +
			"  background-color: #eeaa88;"+
			"}" +
		"#GM_fip_pop > tbody > tr > td {" +
			"  color: #800000;" +
			"  font-size: 8pt !important;" +
			"}" +
		"#GM_fip_pop > tbody > tr > td > blockquote {" +
			"  margin-top: 0px !important;" +
			"  argin-bottom: 0px !important;" +
			"}" +
		".GM_fip_name {" +
			"  color: #F00;" +
			"}" +
		".GM_fip_counter {" +
		  "  margin: 0 0.3em" +
		"}";
		if (typeof GM_addStyle != "undefined") {
			GM_addStyle(css);
		} else if (typeof addStyle != "undefined") {
			addStyle(css);
		} else {
			var heads = document.getElementsByTagName("head");
			if (heads.length > 0) {
				var node = document.createElement("style");
				node.type = "text/css";
				node.appendChild(document.createTextNode(css));
				heads[0].appendChild(node);
			}
		}
	}

	console.log('Parsing '+saba+': '+((new Date()).getTime()-Start) +'msec');//log parsing time

})();
<commit_msg>Change showing popup method<commit_after>// ==UserScript==
// @name           futaba ID+IP popup
// @namespace      https://github.com/himuro-majika
// @description    同じIDやIPのレスをポップアップしちゃう
// @author         himuro_majika
// @note           赤福の「続きを読む」機能で読み込んだレスには反応しません。
// @note           適宜ページ全体をリロードしてください。
// @include        http://*.2chan.net/*/res/*.htm
// @version        1.1
// @grant          GM_addStyle
// @license        MIT
// @icon         data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAAPUExURYv4i2PQYy2aLUe0R////zorx9oAAAAFdFJOU/////8A+7YOUwAAAElJREFUeNqUj1EOwDAIQoHn/c88bX+2fq0kRsAoUXVAfwzCttWsDWzw0kNVWd2tZ5K9gqmMZB8libt4pSg6YlO3RnTzyxePAAMAzqMDgTX8hYYAAAAASUVORK5CYII=
// ==/UserScript==
(function () {

	var Start = new Date().getTime();//count parsing time
	var saba = location.host.replace(".2chan.net","") +
		location.pathname.replace("futaba.htm","");
	var timer_show, timer_hide;

	setClassAndName();
	createCounter();
	setEvent();
	setStyle();

	// ID/IPにclass,nameを設定する
	function setClassAndName() {
		res();
		// レス
		function res() {
			var atd = document.getElementsByClassName("rtd");
			for (var i = 0; i < atd.length; i++) {
				var td = atd[i];
				td.innerHTML = td.innerHTML.replace(
					/(I[DP]:\S+)/,
					"$1"
				);
			}
		}
	}
	// 出現数の表示
	function createCounter() {
		var a = document.getElementsByClassName("GM_fip_name");
		var ids = {};
		for (var i = 0; i < a.length; i++) {
			var node = a[i];
			var id = node.name;
			if (ids[id]) {
				ids[id]++;
			} else {
				ids[id] = 1;
			}
			var name = document.querySelectorAll(".GM_fip_name[name='" + id + "']");
			var span = document.createElement("span");
			span.setAttribute("class", "GM_fip_counter");
			span.textContent = "[" + ids[id] + "/" + name.length + "]";
			// node.parentNode.insertBefore(span, node.nextSibling);
			node.appendChild(span);
		}
	}
	// イベントを設定
	function setEvent() {
		var aa = document.getElementsByClassName("GM_fip_name");
		for (var i = 0; i < aa.length; i++) {
			var a = aa[i];
			a.addEventListener("mouseover", show, true);
			a.addEventListener("mouseout", hide, true);
		}
	}
	// ポップアップを表示する
	function show(event) {
		clearTimeout(timer_show);
		delpop();
		var name = this.name;
		timer_show = setTimeout(function() {
			var wX;	//ポップアップ表示位置X
			var wY;	//ポップアップ表示位置Y
			var popup = document.createElement("table");
			var tda = document.getElementsByName(name);
			for (var i = 0; i < tda.length; i++) {
				// restable.push(tda[i].parentNode.parentNode.parentNode.innerHTML);
				var table = tda[i].parentNode.parentNode.parentNode.cloneNode(true);
				popup.appendChild(table);
			}
			var restable = [];
			console.dir(restable);
			popup.id = "GM_fip_pop";
			// popup.innerHTML = restable.join(" ");
			popup.addEventListener("mouseover",function(){
				clearTimeout(timer_hide);
			},true);
			popup.addEventListener("mouseout",hide,true);
			var body = document.getElementsByTagName("body");
			body[0].appendChild(popup);
			wX = event.clientX + 10;
			wY = window.scrollY + event.clientY - popup.clientHeight - 10;
			if ( wY < 0 ) {	//ポップアップが上に見きれる時は下に表示
				wY = window.scrollY + event.clientY;
			}
			popup.setAttribute("style", "left:" + wX + "px; top:" + wY + "px;");
		}, 300);
	}
	// ポップアップを消す
	function hide() {
		clearTimeout(timer_show);
		timer_hide = setTimeout(delpop, 300);
	}

	function delpop() {
		var doc_pop = document.getElementById("GM_fip_pop");
		if ( doc_pop ) {
			doc_pop.parentNode.removeChild(doc_pop);
		}
	}
	/*
	 * スタイル設定
	 */
	function setStyle() {
		var css = "#GM_fip_pop {" +
			"  position: absolute;" +
			"  z-index: 350;" +
			"  background-color: #eeaa88;"+
			"}" +
		"#GM_fip_pop > tbody > tr > td {" +
			"  color: #800000;" +
			"  font-size: 8pt !important;" +
			"}" +
		"#GM_fip_pop > tbody > tr > td > blockquote {" +
			"  margin-top: 0px !important;" +
			"  argin-bottom: 0px !important;" +
			"}" +
		".GM_fip_name {" +
			"  color: #F00;" +
			"}" +
		".GM_fip_counter {" +
		  "  margin: 0 0.3em" +
		"}";
		if (typeof GM_addStyle != "undefined") {
			GM_addStyle(css);
		} else if (typeof addStyle != "undefined") {
			addStyle(css);
		} else {
			var heads = document.getElementsByTagName("head");
			if (heads.length > 0) {
				var node = document.createElement("style");
				node.type = "text/css";
				node.appendChild(document.createTextNode(css));
				heads[0].appendChild(node);
			}
		}
	}

	console.log('Parsing '+saba+': '+((new Date()).getTime()-Start) +'msec');//log parsing time

})();
<|endoftext|>


<commit_before>enyo.kind({
    name: "moon.sample.photos.PhotoDetailWideSample",
    kind : "moon.Panel",
    classes: "moon enyo-unselectable photo-detail",
    fit: true,
    title : "PHOTO NAME",
    titleAbove : "03",
    titleBelow : "2013-04-08",
    headerComponents : [
        { kind : "moon.IconButton", classes : "header-icon", src : "assets/icon-favorite.png" },
        { kind : "moon.IconButton", classes : "header-icon", src : "assets/icon-download.png"},
        { kind : "moon.IconButton", classes : "header-icon", src : "assets/icon-next.png"},
    ],
    components: [
        {
            kind : "FittableColumns",
            components : [
                {
                    style : "width : 50%;",
                    components : [
                        {
                            kind : "enyo.Image",
                            classes : "main-photo",
                            src : "assets/default-movie.png",
                        }
                    ]
                },
                {
                    style : "width : 3%;"
                },
                {
                    style : "width : 47%;",
                    kind : "FittableRows",
                    components : [
                        {
                            kind: "moon.RadioButtonGroup",
                            onActivate: "buttonActivated",
                            components: [
                                {name : "button-desc", classes : "radio-button", content: "DESCRIPTION"},
                                {name : "button-comments", classes : "radio-button", content: "COMMENTS(98)"},
                                {name : "button-likes", classes : "radio-button", content: "LIKES(387)"},
                                {name : "button-albums", classes : "radio-button", content: "ALBUMS(5)"},
                            ]
                        },
                        { kind : "moon.Divider", classes : "divider" },
                        {
                            name : "mainContent",
                            components : [
                                {
                                    name : "panels",
                                    kind: "Panels",
                                    arrangerKind: "CardSlideInArranger",
                                    classes: "photo-panels",
                                    index:0,
                                    fit:true,
                                    realtimeFit: true,
                                    components: [
                                        {kind: "moon.Scroller", components:[
                                            {
                                                style: "text-transform:none;white-space:normal;font-align:left; font-size:32px; line-height:36px; padding : 0px 10px 0px 10px;",
                                                bindFrom: "content"
                                            }
                                        ]}
                                    ]
                                }
                            ]
                        }
                    ]
                }
            ]
        }
    ],

    bindings: [
        {from: ".controller.details", to: "$.panels.controller"}
    ],

    buttonActivated: function(inSender, inEvent) {
        if ((inEvent.originator.getActive()) && (inEvent.originator.kind === "moon.RadioButton")) {
            var tName = inEvent.originator.name;

            if(tName == "button-desc"){
                this.$.panels.setIndex(0);
            } else if(tName=="button-comments"){
                this.$.panels.setIndex(1);
            } else if(tName=="button-likes"){
                this.$.panels.setIndex(2);
            } else if(tName=="button-albums"){
                this.$.panels.setIndex(3);
            }
        }
    }
});

// Sample model

enyo.ready(function(){
    var sampleModel = new enyo.Model({
        details: new enyo.Collection([
            {
                content: "Pixar genius reigns in this funny romantic comedy, which stars a robot who says absolutely nothing for a full 25 minutes yet somehow completely transfixes and endears himself to the audience within the first few minutes of the film. As the last robot left on earth, Wall-E (voiced by Ben Burtt) is one small robot--with a big, big heart--who holds the future of earth and mankind squarely in the palm of his metal hand. He's outlasted all the \"Waste Allocation Load Lifter Earth-Class\" robots that were assigned some 700 years ago to clean up the environmental mess that man made of earth while man vacationed aboard the luxury spaceship Axiom.",
            },
            {
                content: "Pixar genius reigns in this funny romantic comedy, which stars a robot who says absolutely nothing for a full 25 minutes yet somehow completely transfixes and endears himself to the audience within the first few minutes of the film. As the last robot left on earth, Wall-E (voiced by Ben Burtt) is one small robot--with a big, big heart--who holds the future of earth and mankind squarely in the palm of his metal hand. He's outlasted all the \"Waste Allocation Load Lifter Earth-Class\" robots that were assigned some 700 years ago to clean up the environmental mess that man made of earth while man vacationed aboard the luxury spaceship Axiom.",
            },
            {
                content: "Pixar genius reigns in this funny romantic comedy, which stars a robot who says absolutely nothing for a full 25 minutes yet somehow completely transfixes and endears himself to the audience within the first few minutes of the film. As the last robot left on earth, Wall-E (voiced by Ben Burtt) is one small robot--with a big, big heart--who holds the future of earth and mankind squarely in the palm of his metal hand. He's outlasted all the \"Waste Allocation Load Lifter Earth-Class\" robots that were assigned some 700 years ago to clean up the environmental mess that man made of earth while man vacationed aboard the luxury spaceship Axiom.",
            },
            {
                content: "Pixar genius reigns in this funny romantic comedy, which stars a robot who says absolutely nothing for a full 25 minutes yet somehow completely transfixes and endears himself to the audience within the first few minutes of the film. As the last robot left on earth, Wall-E (voiced by Ben Burtt) is one small robot--with a big, big heart--who holds the future of earth and mankind squarely in the palm of his metal hand. He's outlasted all the \"Waste Allocation Load Lifter Earth-Class\" robots that were assigned some 700 years ago to clean up the environmental mess that man made of earth while man vacationed aboard the luxury spaceship Axiom.",
            }
        ])
    });

//  Application to render sample

    new enyo.Application({
        view: {
            classes: "enyo-unselectable moon",
            components: [
                {kind: "enyo.Spotlight"},
                {
                    kind: "moon.sample.photos.PhotoDetailWideSample",
                    controller: ".app.controllers.photoController",
                    classes: "enyo-fit"
                }
            ]
        },
        controllers: [
            {
                name: "photoController",
                kind: "enyo.ModelController",
                model: sampleModel,
                changImage: function(inSender, inEvent) {

                }
            }
        ]
    });
});<commit_msg>GF-4661: Apply MVC without Panels<commit_after>enyo.kind({
    name: "moon.sample.photos.PhotoDetailWideSample",
    kind: "moon.Panel",
    classes: "moon enyo-unselectable photo-detail",
    fit: true,
    title: "PHOTO NAME",
    titleAbove: "03",
    titleBelow:  "2013-04-08",
    headerComponents: [
        {kind: "moon.IconButton", classes: "header-icon", src: "assets/icon-favorite.png"},
        {kind: "moon.IconButton", classes: "header-icon", src: "assets/icon-download.png"},
        {kind: "moon.IconButton", classes: "header-icon", src: "assets/icon-next.png"},
    ],
    components: [
        {
            kind: "FittableColumns",
            components: [
                {
                    style: "width: 50%;",
                    components: [
                        {
                            kind: "enyo.Image",
                            classes: "main-photo",
                            src: "assets/default-movie.png",
                        }
                    ]
                },
                {
                    style: "width : 3%;"
                },
                {
                    style: "width : 47%;",
                    kind: "FittableRows",
                    components: [
                        {
                            kind: "moon.RadioButtonGroup",
                            onActivate: "buttonActivated",
                            components: [
                                {name: "button-desc", classes: "radio-button", content: "DESCRIPTION"},
                                {name: "button-comments", classes: "radio-button", content: "COMMENTS(98)"},
                                {name: "button-likes", classes: "radio-button", content: "LIKES(387)"},
                                {name: "button-albums", classes: "radio-button", content: "ALBUMS(5)"},
                            ]
                        },
                        {kind: "moon.Divider", classes: "divider" },
                        {
                            name: "mainContent",
                            components: [
                                {
                                    name: "panels",
                                    kind: "DataList",
                                    /** TODO: Make more smater Panel to deal with data input
                                    /*kind: "moon.Panels",
                                    arrangerKind: "CardSlideInArranger",        */
                                    classes: "photo-panels",
                                    index:0,
                                    fit:true,
                                    realtimeFit: true,
                                    components: [
                                        {kind: "moon.Scroller", components:[
                                            {
                                                style: "text-transform:none;white-space:normal;font-align:left; font-size:32px; line-height:36px; padding: 0px 10px 0px 10px;",
                                                bindFrom: "content"
                                            }
                                        ]}
                                    ]
                                }
                            ]
                        }
                    ]
                }
            ]
        }
    ],

    bindings: [
        {from: ".controller.details", to: "$.panels.controller"}
    ],

/*    buttonActivated: function(inSender, inEvent) {
        if ((inEvent.originator.getActive()) && (inEvent.originator.kind === "moon.RadioButton")) {
            var tName = inEvent.originator.name;

            if(tName == "button-desc"){
                this.$.panels.setIndex(0);
            } else if(tName=="button-comments"){
                this.$.panels.setIndex(1);
            } else if(tName=="button-likes"){
                this.$.panels.setIndex(2);
            } else if(tName=="button-albums"){
                this.$.panels.setIndex(3);
            }
        }
    }*/
});

// Sample model

enyo.ready(function(){
    var sampleModel = new enyo.Model({
        details: new enyo.Collection([
            {
                content: "Pixar genius reigns in this funny romantic comedy, which stars a robot who says absolutely nothing for a full 25 minutes yet somehow completely transfixes and endears himself to the audience within the first few minutes of the film. As the last robot left on earth, Wall-E (voiced by Ben Burtt) is one small robot--with a big, big heart--who holds the future of earth and mankind squarely in the palm of his metal hand. He's outlasted all the \"Waste Allocation Load Lifter Earth-Class\" robots that were assigned some 700 years ago to clean up the environmental mess that man made of earth while man vacationed aboard the luxury spaceship Axiom.",
            },
        ])
    });

//  Application to render sample

    new enyo.Application({
        view: {
            classes: "enyo-unselectable moon",
            components: [
                {kind: "enyo.Spotlight"},
                {
                    kind: "moon.sample.photos.PhotoDetailWideSample",
                    controller: ".app.controllers.photoController",
                    classes: "enyo-fit"
                }
            ]
        },
        controllers: [
            {
                name: "photoController",
                kind: "enyo.ModelController",
                model: sampleModel,
                changImage: function(inSender, inEvent) {

                }
            }
        ]
    });
});<|endoftext|>


<commit_before>define('spec/surfnperfRT_spec', [
  'surfnperf/resource-timing'
], function(
  SurfNPerfRT
) {
  describe('SurfNPerfRT', function() {
    var NOW_TS = 1388595600000, // Wed Jan 01 2014 12:00:00 GMT-0500 (EST)
      NOW_HIGH_RES = 3.1415926;

    beforeEach(function() {
      var name = "a";
      if(!window.performance) {
        window.performance = {
          now: function() {
            return NOW_HIGH_RES;
          },
          getEntriesByName: function(name) {},
          timing: {}
        };
      }
    });

    describe('Singleton Behavior', function() {
      it('is only instantiated once, even if the library is attempted to be instantiated more than once (as good singletons do)', function() {
        var a = SurfNPerfRT,
          b = SurfNPerfRT;
        expect(a).toBe(b);
      });
    });

    describe('#initialize', function() {

      beforeEach(function() {
        SurfNPerfRT.initialize();
      });

      it('sets the Resource Timing API properties appropriately', function() {
        expect(SurfNPerfRT._resourceTiming).not.toBeNull();
      });

    });

    describe('#_inList', function() {
      // Minsu
      describe('whitelist as a key', function() {
        var options = {
          "whitelist": ["A", "B", "C"]
        }
        it('returns true if the given origin is listed in whitelist', function() {
          expect(SurfNPerfRT._inList("A", options)).toEqual(true);
        });
        it('returns false if the given origin is not listed in whitelist', function() {
          expect(SurfNPerfRT._inList("D", options)).toEqual(false);
        });
      });
      describe('blackList as a key', function() {
        var options = {
          "blacklist": ["A", "B", "C"]
        }
        it('returns true if the given origin is not listed in blacklist', function() {
          expect(SurfNPerfRT._inList("D", options)).toEqual(true);
        });
        it('returns false if the given origin is listed in blacklist', function() {
          expect(SurfNPerfRT._inList("A", options)).toEqual(false);
        });
      });
      describe('none specific key', function() {
        options = {}
        it('returns true no matter what if options does not have any key', function() {
          expect(SurfNPerfRT._inList("A", options)).toBe(true);
        });
      });

    });

    describe('#_getURLOrigin', function() {
      describe('when the provided URL has no port', function() {
        it('returns the origin', function() {
          expect(SurfNPerfRT._getURLOrigin("http://johnriv.github.io/Surf-N-Perf/")).toEqual("http://johnriv.github.io");
        });
      });
      describe('when the provided URL has a port', function() {
        it('returns the origin', function() {
          expect(SurfNPerfRT._getURLOrigin("http://johnriv.github.io:3000/Surf-N-Perf/")).toEqual("http://johnriv.github.io:3000");
        });
      });
    });

    describe('#getOrigins', function() {
      // Minsu

    });

    describe('#getResourcesFromOrigin', function() {
      describe('when the browser does not support resource timings', function() {
        it('returns null', function() {
          SurfNPerfRT._resourceTiming = false;
          expect(SurfNPerfRT.getResourcesFromOrigin("http://johnriv.github.io:3000")).toEqual(null);
        });
      });
      describe('when the browser supports resource timings', function() {

      });
    });

    describe('#_name', function() {
      // Minsu
    });

    describe('#getResource', function() {
      // Ros
      describe('when the browser does not support resource timings', function() {
        it('returns null', function() {
          SurfNPerfRT._resourceTiming = false;
          expect(SurfNPerfRT.getResource(name)).toEqual(null);
        });
      });
      describe('when the browser supports resource timings', function() {

      });
    });

    describe('#duration', function() {
      // Minsu
      describe('when the browser does not support resource timings', function() {
        it('returns null', function() {
          SurfNPerfRT._resourceTiming = false;
          expect(SurfNPerfRT.duration(name, "A", "B", {})).toEqual(null);
        });
      });
      describe('when the browser supports resource timings', function() {
        // it('returns the diff between 2 resource timing marks, not rounded if optional 4th param not included', function() {
        //   SurfNPerfRT._resourceTiming = true;
        //   spyOn(window.performance, 'getEntriesByName').andReturn([{
        //     eventA: 480.04,
        //     eventB: 490.05
        //   }]);
        //   expect(SurfNPerfRT.duration(name, "eventA", "eventB")).toEqual(10.01);
        // });
        it('returns false if either eventA or eventB is 0', function() {
          SurfNPerfRT._resourceTiming = true;
          spyOn(window.performance, 'getEntriesByName').andReturn([{
            eventA: 0,
            eventB: 0,
            eventC: 10
          }]);
          expect(SurfNPerfRT.duration(name, "eventA", "eventC")).toEqual(false);
          expect(SurfNPerfRT.duration(name, "eventC", "eventB")).toEqual(false);
        });
        // it('returns the diff between 2 resource timing marks, rounded when optional 4th param decimalPlaces included', function() {
        //   SurfNPerfRT._resourceTiming = true;
        //   spyOn(window.performance, 'getEntriesByName').andReturn([{
        //     eventA: 480.04,
        //     eventB: 490.05
        //   }]);
        //   expect(SurfNPerfRT.duration(name, "eventA", "eventB", {
        //     "decimalPlaces": 1
        //   })).toEqual(10.0);
        //   expect(SurfNPerfRT.duration(name, "eventA", "eventB", {
        //     "decimalPlaces": 2
        //   })).toEqual(10.01);
        // });
      });
    });

    describe('#start', function() {
      // Ros
      describe('when the browser does not support resource timings', function() {
        it('returns null', function() {
          SurfNPerfRT._resourceTiming = false;
          expect(SurfNPerfRT.start(name)).toEqual(null);
        });
      });
      describe('when the browser supports resource timings', function() {
        it("returns the start time of the resource", function() {
          SurfNPerfRT._resourceTiming = true;
          spyOn(window.performance, 'getEntriesByName').andReturn([{
            startTime: 487.05
          }]);
<<<<<<< HEAD
          expect(SurfNPerfRT.start(name)).toEqual(487.05);
=======
          expect(SurfNPerfRT._resourceTiming).toEqual(true)
          expect(SurfNPerfRT.start(name, {
            decimalPlaces: 2
          })).toEqual(487.05);
>>>>>>> b01d5ee73ebb7a83b4084e1e6b87c6127ac456dc
        });
      });
    });

    describe('#end', function() {
      // Minsu
      describe('when the browser does not support resource timings', function() {
        it('returns null', function() {
          SurfNPerfRT._resourceTiming = false;
          expect(SurfNPerfRT.end("http://johnriv.github.io:3000")).toEqual(null);
        });
      });
      describe('when the browser supports resource timings', function() {
        it("returns the end time of the resource response", function() {
          SurfNPerfRT._resourceTiming = true;
          spyOn(window.performance, 'getEntriesByName').andReturn([{
            responseEnd: 487.05
          }]);
<<<<<<< HEAD
          expect(SurfNPerfRT.end(name)).toEqual(487.05);
=======
          expect(SurfNPerfRT.end(name, {
            decimalPlaces: 2
          })).toEqual(487.05);
>>>>>>> b01d5ee73ebb7a83b4084e1e6b87c6127ac456dc
        });
      });
    });

    describe('#getFullRequestLoadTime', function() {
      // Ros
      describe('when the browser does not support resource timings', function() {
        it('returns null', function() {
          SurfNPerfRT._resourceTiming = false;
          expect(SurfNPerfRT.getFullRequestLoadTime(name)).toEqual(null);
        });
      });
      describe('when the browser supports resource timings', function() {
        it("returns the duration of the resource load time", function() {
          SurfNPerfRT._resourceTiming = true;
          spyOn(window.performance, 'getEntriesByName').andReturn([{
            duration: 487.05
          }]);
<<<<<<< HEAD
          expect(SurfNPerfRT.getFullRequestLoadTime(name)).toEqual(487.05);
=======
          expect(SurfNPerfRT.getFullRequestLoadTime(name, {
            decimalPlaces: 2
          })).toEqual(487.05);
>>>>>>> b01d5ee73ebb7a83b4084e1e6b87c6127ac456dc
        });

      });
    });

    describe('#getNetworkTime', function() {
      // Minsu
      describe('when the browser does not support resource timings', function() {
        it('returns null', function() {
          SurfNPerfRT._resourceTiming = false;
          expect(SurfNPerfRT.getNetworkTime("http://johnriv.github.io:3000", {})).toEqual(null);
        });
      });
      describe('when the browser supports resource timings', function() {
        it("returns the network time while loading the resource", function() {
          SurfNPerfRT._resourceTiming = true;
          spyOn(window.performance, 'getEntriesByName').andReturn([{
            fetchStart: 480.05,
            connectEnd: 490.05
          }]);
          expect(SurfNPerfRT.getNetworkTime(name)).toEqual(10.0);
        });
      });
    });

    describe('#getServerTime', function() {
      // Ros
      describe('when the browser does not support resource timings', function() {
        it('returns null', function() {
          SurfNPerfRT._resourceTiming = false;
          expect(SurfNPerfRT.getServerTime(name)).toEqual(null);
        });
      });
      describe('when the browser supports resource timings', function() {
        it("returns the server time while loading the resource", function() {
          SurfNPerfRT._resourceTiming = true;
          spyOn(window.performance, 'getEntriesByName').andReturn([{
            requestStart: 480.05,
            responseEnd: 490.05
          }]);
          expect(SurfNPerfRT.getServerTime(name)).toEqual(10.0);
        });
      });
    });

    describe('#getBlockingTime', function() {
      // Minsu
      describe('when the browser does not support resource timings', function() {
        it('returns null', function() {
          SurfNPerfRT._resourceTiming = false;
          expect(SurfNPerfRT.getBlockingTime("http://johnriv.github.io:3000", {})).toEqual(null);
        });
      });
      describe('when the browser supports resource timings', function() {
        SurfNPerfRT._resourceTiming = true;
      });
    });

  });
});
<commit_msg>conflict resolved<commit_after>define('spec/surfnperfRT_spec', [
  'surfnperf/resource-timing'
], function(
  SurfNPerfRT
) {
  describe('SurfNPerfRT', function() {
    var NOW_TS = 1388595600000, // Wed Jan 01 2014 12:00:00 GMT-0500 (EST)
      NOW_HIGH_RES = 3.1415926;

    beforeEach(function() {
      var name = "a";
      if(!window.performance) {
        window.performance = {
          now: function() {
            return NOW_HIGH_RES;
          },
          getEntriesByName: function(name) {},
          timing: {}
        };
      }
    });

    describe('Singleton Behavior', function() {
      it('is only instantiated once, even if the library is attempted to be instantiated more than once (as good singletons do)', function() {
        var a = SurfNPerfRT,
          b = SurfNPerfRT;
        expect(a).toBe(b);
      });
    });

    describe('#initialize', function() {

      beforeEach(function() {
        SurfNPerfRT.initialize();
      });

      it('sets the Resource Timing API properties appropriately', function() {
        expect(SurfNPerfRT._resourceTiming).not.toBeNull();
      });

    });

    describe('#_inList', function() {
      // Minsu
      describe('whitelist as a key', function() {
        var options = {
          "whitelist": ["A", "B", "C"]
        }
        it('returns true if the given origin is listed in whitelist', function() {
          expect(SurfNPerfRT._inList("A", options)).toEqual(true);
        });
        it('returns false if the given origin is not listed in whitelist', function() {
          expect(SurfNPerfRT._inList("D", options)).toEqual(false);
        });
      });
      describe('blackList as a key', function() {
        var options = {
          "blacklist": ["A", "B", "C"]
        }
        it('returns true if the given origin is not listed in blacklist', function() {
          expect(SurfNPerfRT._inList("D", options)).toEqual(true);
        });
        it('returns false if the given origin is listed in blacklist', function() {
          expect(SurfNPerfRT._inList("A", options)).toEqual(false);
        });
      });
      describe('none specific key', function() {
        options = {}
        it('returns true no matter what if options does not have any key', function() {
          expect(SurfNPerfRT._inList("A", options)).toBe(true);
        });
      });

    });

    describe('#_getURLOrigin', function() {
      describe('when the provided URL has no port', function() {
        it('returns the origin', function() {
          expect(SurfNPerfRT._getURLOrigin("http://johnriv.github.io/Surf-N-Perf/")).toEqual("http://johnriv.github.io");
        });
      });
      describe('when the provided URL has a port', function() {
        it('returns the origin', function() {
          expect(SurfNPerfRT._getURLOrigin("http://johnriv.github.io:3000/Surf-N-Perf/")).toEqual("http://johnriv.github.io:3000");
        });
      });
    });

    describe('#getOrigins', function() {
      // Minsu

    });

    describe('#getResourcesFromOrigin', function() {
      describe('when the browser does not support resource timings', function() {
        it('returns null', function() {
          SurfNPerfRT._resourceTiming = false;
          expect(SurfNPerfRT.getResourcesFromOrigin("http://johnriv.github.io:3000")).toEqual(null);
        });
      });
      describe('when the browser supports resource timings', function() {

      });
    });

    describe('#_name', function() {
      // Minsu
    });

    describe('#getResource', function() {
      // Ros
      describe('when the browser does not support resource timings', function() {
        it('returns null', function() {
          SurfNPerfRT._resourceTiming = false;
          expect(SurfNPerfRT.getResource(name)).toEqual(null);
        });
      });
      describe('when the browser supports resource timings', function() {

      });
    });

    describe('#duration', function() {
      // Minsu
      describe('when the browser does not support resource timings', function() {
        it('returns null', function() {
          SurfNPerfRT._resourceTiming = false;
          expect(SurfNPerfRT.duration(name, "A", "B", {})).toEqual(null);
        });
      });
      describe('when the browser supports resource timings', function() {
        // it('returns the diff between 2 resource timing marks, not rounded if optional 4th param not included', function() {
        //   SurfNPerfRT._resourceTiming = true;
        //   spyOn(window.performance, 'getEntriesByName').andReturn([{
        //     eventA: 480.04,
        //     eventB: 490.05
        //   }]);
        //   expect(SurfNPerfRT.duration(name, "eventA", "eventB")).toEqual(10.01);
        // });
        it('returns false if either eventA or eventB is 0', function() {
          SurfNPerfRT._resourceTiming = true;
          spyOn(window.performance, 'getEntriesByName').andReturn([{
            eventA: 0,
            eventB: 0,
            eventC: 10
          }]);
          expect(SurfNPerfRT.duration(name, "eventA", "eventC")).toEqual(false);
          expect(SurfNPerfRT.duration(name, "eventC", "eventB")).toEqual(false);
        });
        // it('returns the diff between 2 resource timing marks, rounded when optional 4th param decimalPlaces included', function() {
        //   SurfNPerfRT._resourceTiming = true;
        //   spyOn(window.performance, 'getEntriesByName').andReturn([{
        //     eventA: 480.04,
        //     eventB: 490.05
        //   }]);
        //   expect(SurfNPerfRT.duration(name, "eventA", "eventB", {
        //     "decimalPlaces": 1
        //   })).toEqual(10.0);
        //   expect(SurfNPerfRT.duration(name, "eventA", "eventB", {
        //     "decimalPlaces": 2
        //   })).toEqual(10.01);
        // });
      });
    });

    describe('#start', function() {
      // Ros
      describe('when the browser does not support resource timings', function() {
        it('returns null', function() {
          SurfNPerfRT._resourceTiming = false;
          expect(SurfNPerfRT.start(name)).toEqual(null);
        });
      });
      describe('when the browser supports resource timings', function() {
        it("returns the start time of the resource", function() {
          SurfNPerfRT._resourceTiming = true;
          spyOn(window.performance, 'getEntriesByName').andReturn([{
            startTime: 487.05
          }]);
          expect(SurfNPerfRT.start(name, {
            decimalPlaces: 2
          })).toEqual(487.05);
        });
      });
    });

    describe('#end', function() {
      // Minsu
      describe('when the browser does not support resource timings', function() {
        it('returns null', function() {
          SurfNPerfRT._resourceTiming = false;
          expect(SurfNPerfRT.end("http://johnriv.github.io:3000")).toEqual(null);
        });
      });
      describe('when the browser supports resource timings', function() {
        it("returns the end time of the resource response", function() {
          SurfNPerfRT._resourceTiming = true;
          spyOn(window.performance, 'getEntriesByName').andReturn([{
            responseEnd: 487.05
          }]);
          expect(SurfNPerfRT.end(name, {
            decimalPlaces: 2
          })).toEqual(487.05);
        });
      });
    });

    describe('#getFullRequestLoadTime', function() {
      // Ros
      describe('when the browser does not support resource timings', function() {
        it('returns null', function() {
          SurfNPerfRT._resourceTiming = false;
          expect(SurfNPerfRT.getFullRequestLoadTime(name)).toEqual(null);
        });
      });
      describe('when the browser supports resource timings', function() {
        it("returns the duration of the resource load time", function() {
          SurfNPerfRT._resourceTiming = true;
          spyOn(window.performance, 'getEntriesByName').andReturn([{
            duration: 487.05
          }]);
          expect(SurfNPerfRT.getFullRequestLoadTime(name, {
            decimalPlaces: 2
          })).toEqual(487.05);
        });

      });
    });

    describe('#getNetworkTime', function() {
      // Minsu
      describe('when the browser does not support resource timings', function() {
        it('returns null', function() {
          SurfNPerfRT._resourceTiming = false;
          expect(SurfNPerfRT.getNetworkTime("http://johnriv.github.io:3000", {})).toEqual(null);
        });
      });
      describe('when the browser supports resource timings', function() {
        it("returns the network time while loading the resource", function() {
          SurfNPerfRT._resourceTiming = true;
          spyOn(window.performance, 'getEntriesByName').andReturn([{
            fetchStart: 480.05,
            connectEnd: 490.05
          }]);
          expect(SurfNPerfRT.getNetworkTime(name)).toEqual(10.0);
        });
      });
    });

    describe('#getServerTime', function() {
      // Ros
      describe('when the browser does not support resource timings', function() {
        it('returns null', function() {
          SurfNPerfRT._resourceTiming = false;
          expect(SurfNPerfRT.getServerTime(name)).toEqual(null);
        });
      });
      describe('when the browser supports resource timings', function() {
        it("returns the server time while loading the resource", function() {
          SurfNPerfRT._resourceTiming = true;
          spyOn(window.performance, 'getEntriesByName').andReturn([{
            requestStart: 480.05,
            responseEnd: 490.05
          }]);
          expect(SurfNPerfRT.getServerTime(name)).toEqual(10.0);
        });
      });
    });

    describe('#getBlockingTime', function() {
      // Minsu
      describe('when the browser does not support resource timings', function() {
        it('returns null', function() {
          SurfNPerfRT._resourceTiming = false;
          expect(SurfNPerfRT.getBlockingTime("http://johnriv.github.io:3000", {})).toEqual(null);
        });
      });
      describe('when the browser supports resource timings', function() {
        SurfNPerfRT._resourceTiming = true;
      });
    });

  });
});
<|endoftext|>


<commit_before><commit_msg>cap 5<commit_after><|endoftext|>


<commit_before>'use strict';

module.exports = function( grunt ) {
    var JS_INCLUDE = [ '**/*.js', '!node_modules/**', '!test/**/*.spec.js', '!public/js/*-bundle.js', '!public/js/*-bundle.min.js' ];
    var pkg = grunt.file.readJSON( 'package.json' );
    var path = require( 'path' );
    var nodeSass = require( 'node-sass' );

    require( 'time-grunt' )( grunt );
    require( 'load-grunt-tasks' )( grunt );

    grunt.config.init( {
        concurrent: {
            develop: {
                tasks: [ 'nodemon', 'watch' ],
                options: {
                    logConcurrentOutput: true
                }
            }
        },
        nodemon: {
            dev: {
                script: 'app.js',
                options: {
                    watch: [ 'app', 'config' ],
                    //nodeArgs: [ '--debug' ],
                    env: {
                        NODE_ENV: 'development',
                        DEBUG: '*, -express:*, -send, -compression, -body-parser:*'
                    }
                }
            }
        },
        sass: {
            options: {
                functions: {
                    'base64-url($mimeType, $data)': function( mimeType, data ) {
                        var base64 = new Buffer( data.getValue() ).toString( 'base64' );
                        var urlString = 'url("data:' + mimeType.getValue() + ';base64,' + base64 + '")';
                        return nodeSass.types.String( urlString );
                    }
                }
            },
            compile: {
                cwd: 'app/views/styles',
                dest: 'public/css',
                expand: true,
                outputStyle: 'compressed',
                src: '**/*.scss',
                ext: '.css',
                flatten: true,
                extDot: 'last'
            }
        },
        watch: {
            config: {
                files: [ 'config/*.json' ],
                tasks: [ 'client-config-file:create' ]
            },
            sass: {
                files: [ 'app/views/styles/**/*.scss', 'widget/**/*.scss', '!app/views/styles/component/_system_variables.scss' ],
                tasks: [ 'sass' ],
                options: {
                    spawn: false,
                    livereload: true
                }
            },
            jade: {
                files: [ 'app/views/**/*.pug' ],
                options: {
                    spawn: false,
                    livereload: true
                }
            },
            language: {
                files: [ 'app/views/**/*.pug', 'app/controllers/**/*.js', 'app/models/**/*.js', 'public/js/src/**/*.js' ],
                tasks: [ /*'shell:translation', 'i18next'*/]
            },
            js: {
                files: [ 'public/js/src/**/*.js', 'widget/**/*.js' ],
                tasks: [ 'js-dev' ],
                options: {
                    spawn: false,
                    livereload: true
                }
            }
        },
        shell: {
            translation: {
                command: [
                    'cd locales',
                    'gulp',
                    'cd ..'
                ].join( '&&' )
            }
        },
        jsbeautifier: {
            test: {
                src: JS_INCLUDE,
                options: {
                    config: './.jsbeautifyrc',
                    mode: 'VERIFY_ONLY'
                }
            },
            fix: {
                src: JS_INCLUDE,
                options: {
                    config: './.jsbeautifyrc'
                }
            }
        },
        eslint: {
            all: JS_INCLUDE,
        },
        // test server JS
        mochaTest: {
            all: {
                options: {
                    reporter: 'dot'
                },
                src: [ 'test/server/**/*.spec.js' ]
            },
            account: {
                src: [ 'test/server/account-*.spec.js' ]
            }
        },
        // test client JS
        karma: {
            options: {
                singleRun: true,
                reporters: [ 'dots' ],
                configFile: 'test/client/config/karma.conf.js'
            },
            headless: {
                browsers: [ 'ChromeHeadless' ]
            },
            browsers: {
                browsers: [ 'Chrome', 'ChromeCanary', 'Firefox', 'Opera' /*,'Safari'*/ ],
            }
        },
        browserify: {
            development: {
                files: {
                    'public/js/enketo-webform-dev-bundle.js': [ 'public/js/src/main-webform.js' ],
                    'public/js/enketo-webform-edit-dev-bundle.js': [ 'public/js/src/main-webform-edit.js' ],
                    'public/js/enketo-webform-fs-dev-bundle.js': [ 'public/js/src/main-webform-fieldsubmission.js' ],
                    'public/js/enketo-webform-view-dev-bundle.js': [ 'public/js/src/main-webform-view.js' ],
                    'public/js/enketo-offline-fallback-dev-bundle.js': [ 'public/js/src/main-offline-fallback.js' ]
                },
                options: {
                    browserifyOptions: {
                        debug: true
                    }
                },
            },
            production: {
                files: {
                    'public/js/enketo-webform-bundle.js': [ 'public/js/src/main-webform.js' ],
                    'public/js/enketo-webform-edit-bundle.js': [ 'public/js/src/main-webform-edit.js' ],
                    'public/js/enketo-webform-fs-bundle.js': [ 'public/js/src/main-webform-fieldsubmission.js' ],
                    'public/js/enketo-webform-view-bundle.js': [ 'public/js/src/main-webform-view.js' ],
                    'public/js/enketo-offline-fallback-bundle.js': [ 'public/js/src/main-offline-fallback.js' ]
                },
            },
            options: {
                // ensure that enketo-config and widgets are overridden in **enketo-core**
                transform: [
                    [ 'aliasify', {
                        aliases: pkg.aliasify.aliases,
                        global: true
                    } ]
                ]
            },
        },
        uglify: {
            all: {
                files: {
                    'public/js/enketo-webform-bundle.min.js': [ 'public/js/enketo-webform-bundle.js' ],
                    'public/js/enketo-webform-edit-bundle.min.js': [ 'public/js/enketo-webform-edit-bundle.js' ],
                    'public/js/enketo-webform-fs-bundle.min.js': [ 'public/js/enketo-webform-fs-bundle.js' ],
                    'public/js/enketo-webform-view-bundle.min.js': [ 'public/js/enketo-webform-view-bundle.js' ],
                    'public/js/enketo-offline-fallback-bundle.min.js': [ 'public/js/enketo-offline-fallback-bundle.js' ],
                },
            },
        },
        env: {
            develop: {
                NODE_ENV: 'develop'
            },
            test: {
                NODE_ENV: 'test'
            },
            production: {
                NODE_ENV: 'production'
            }
        },
        i18next: {
            locales: {
                cwd: 'locales/',
                expand: true,
                src: [ '*/' ],
                include: [ '**/translation.json', '**/translation-additions.json' ],
                rename: function( dest, src ) {
                    return dest + src + 'translation-combined.json';
                },
                dest: 'locales/'
            }
        }
    } );

    grunt.registerTask( 'client-config-file', 'Temporary client-config file', function( task ) {
        var CLIENT_CONFIG_PATH = 'public/temp-client-config.json';
        if ( task === 'create' ) {
            var config = require( './app/models/config-model' );
            grunt.file.write( CLIENT_CONFIG_PATH, JSON.stringify( config.client ) );
            grunt.log.writeln( 'File ' + CLIENT_CONFIG_PATH + ' created' );
        } else if ( task === 'remove' ) {
            grunt.file.delete( CLIENT_CONFIG_PATH );
            grunt.log.writeln( 'File ' + CLIENT_CONFIG_PATH + ' removed' );
        }
    } );

    grunt.registerTask( 'system-sass-variables', 'Creating _system_variables.scss', function() {
        var SYSTEM_SASS_VARIABLES_PATH = 'app/views/styles/component/_system_variables.scss';
        var config = require( './app/models/config-model' );
        grunt.file.write( SYSTEM_SASS_VARIABLES_PATH, '$base-path: "' + config.server[ 'base path' ] + '";' );
        grunt.log.writeln( 'File ' + SYSTEM_SASS_VARIABLES_PATH + ' created' );
    } );

    grunt.registerTask( 'transforms', 'Creating forms.json', function() {
        var forms = {};
        var done = this.async();
        var jsonStringify = require( 'json-pretty' );
        var formsJsonPath = 'test/client/forms/forms.json';
        var xformsPaths = grunt.file.expand( {}, 'test/client/forms/*.xml' );
        var transformer = require( 'enketo-transformer' );

        xformsPaths.reduce( function( prevPromise, filePath ) {
                return prevPromise.then( function() {
                    var xformStr = grunt.file.read( filePath );
                    grunt.log.writeln( 'Transforming ' + filePath + '...' );
                    return transformer.transform( {
                            xform: xformStr,
                            includeRelevantMsg: true
                        } )
                        .then( function( result ) {
                            forms[ filePath.substring( filePath.lastIndexOf( '/' ) + 1 ) ] = {
                                html_form: result.form,
                                xml_model: result.model
                            };
                        } );
                } );

            }, Promise.resolve() )
            .then( function() {
                grunt.file.write( formsJsonPath, jsonStringify( forms ) );
                done();
            } );
    } );

    grunt.registerTask( 'widgets', 'generate widget reference files', function() {
        var content;
        var WIDGETS_JS_LOC = 'public/js/';
        var WIDGETS_JS = WIDGETS_JS_LOC + 'widgets.js';
        var WIDGETS_SASS_LOC = 'app/views/styles/component/';
        var WIDGETS_SASS = WIDGETS_SASS_LOC + '_widgets.scss';
        var PRE = '// This file is automatically generated with `grunt widgets`\n';
        var widgets = require( './app/models/config-model' ).server.widgets;
        var coreWidgets = require( './public/js/src/module/core-widgets' );
        var paths = Object.keys( widgets ).map( function( key ) {
            return coreWidgets[ widgets[ key ] ] || widgets[ key ];
        } );
        content = PRE + '\'use strict\';\n\nmodule.exports = [\n    ' +
            paths.map( function( p ) {
                return grunt.file.exists( WIDGETS_JS_LOC, p + '.js' ) ? 'require( \'' + p + '\' )' : '//' + p + ' not found';
            } ).join( ',\n    ' ) + '\n];\n';
        grunt.file.write( WIDGETS_JS, content );
        grunt.log.writeln( 'File ' + WIDGETS_JS + ' created' );
        content = PRE +
            paths.map( function( p ) {
                p = path.join( '../../', p );
                return grunt.file.exists( WIDGETS_SASS_LOC, p + '.scss' ) ? '@import "' + p + '"' : '//' + p + ' not found';
            } ).join( ';\n' ) + ';';
        grunt.file.write( WIDGETS_SASS, content );
        grunt.log.writeln( 'File ' + WIDGETS_SASS + ' created' );
    } );

    grunt.registerTask( 'default', [ 'i18next', 'widgets', 'css', 'js', 'uglify' ] );
    grunt.registerTask( 'js', [ 'client-config-file:create', 'widgets', 'browserify:production' ] );
    grunt.registerTask( 'js-dev', [ 'client-config-file:create', 'widgets', 'browserify:development' ] );
    grunt.registerTask( 'css', [ 'system-sass-variables:create', 'sass' ] );
    grunt.registerTask( 'test', [ 'env:test', 'js', 'css', 'mochaTest:all', 'karma:headless', 'jsbeautifier:test', 'eslint' ] );
    grunt.registerTask( 'test-browser', [ 'env:test', 'css', 'client-config-file:create', 'karma:browsers' ] );
    grunt.registerTask( 'develop', [ 'env:develop', 'i18next', 'js-dev', 'css', 'concurrent:develop' ] );
    grunt.registerTask( 'test-and-build', [ 'env:test', 'mochaTest:all', 'karma:headless', 'env:production', 'default' ] );
};
<commit_msg>fixed: tests<commit_after>'use strict';

module.exports = function( grunt ) {
    var JS_INCLUDE = [ '**/*.js', '!node_modules/**', '!test/**/*.spec.js', '!public/js/*-bundle.js', '!public/js/*-bundle.min.js' ];
    var pkg = grunt.file.readJSON( 'package.json' );
    var path = require( 'path' );
    var nodeSass = require( 'node-sass' );

    require( 'time-grunt' )( grunt );
    require( 'load-grunt-tasks' )( grunt );

    grunt.config.init( {
        concurrent: {
            develop: {
                tasks: [ 'nodemon', 'watch' ],
                options: {
                    logConcurrentOutput: true
                }
            }
        },
        nodemon: {
            dev: {
                script: 'app.js',
                options: {
                    watch: [ 'app', 'config' ],
                    //nodeArgs: [ '--debug' ],
                    env: {
                        NODE_ENV: 'development',
                        DEBUG: '*, -express:*, -send, -compression, -body-parser:*'
                    }
                }
            }
        },
        sass: {
            options: {
                functions: {
                    'base64-url($mimeType, $data)': function( mimeType, data ) {
                        var base64 = new Buffer( data.getValue() ).toString( 'base64' );
                        var urlString = 'url("data:' + mimeType.getValue() + ';base64,' + base64 + '")';
                        return nodeSass.types.String( urlString );
                    }
                }
            },
            compile: {
                cwd: 'app/views/styles',
                dest: 'public/css',
                expand: true,
                outputStyle: 'compressed',
                src: '**/*.scss',
                ext: '.css',
                flatten: true,
                extDot: 'last'
            }
        },
        watch: {
            config: {
                files: [ 'config/*.json' ],
                tasks: [ 'client-config-file:create' ]
            },
            sass: {
                files: [ 'app/views/styles/**/*.scss', 'widget/**/*.scss', '!app/views/styles/component/_system_variables.scss' ],
                tasks: [ 'sass' ],
                options: {
                    spawn: false,
                    livereload: true
                }
            },
            jade: {
                files: [ 'app/views/**/*.pug' ],
                options: {
                    spawn: false,
                    livereload: true
                }
            },
            language: {
                files: [ 'app/views/**/*.pug', 'app/controllers/**/*.js', 'app/models/**/*.js', 'public/js/src/**/*.js' ],
                tasks: [ /*'shell:translation', 'i18next'*/]
            },
            js: {
                files: [ 'public/js/src/**/*.js', 'widget/**/*.js' ],
                tasks: [ 'js-dev' ],
                options: {
                    spawn: false,
                    livereload: true
                }
            }
        },
        shell: {
            translation: {
                command: [
                    'cd locales',
                    'gulp',
                    'cd ..'
                ].join( '&&' )
            }
        },
        jsbeautifier: {
            test: {
                src: JS_INCLUDE,
                options: {
                    config: './.jsbeautifyrc',
                    mode: 'VERIFY_ONLY'
                }
            },
            fix: {
                src: JS_INCLUDE,
                options: {
                    config: './.jsbeautifyrc'
                }
            }
        },
        eslint: {
            all: JS_INCLUDE,
        },
        // test server JS
        mochaTest: {
            all: {
                options: {
                    reporter: 'dot'
                },
                src: [ 'test/server/**/*.spec.js' ]
            },
            account: {
                src: [ 'test/server/account-*.spec.js' ]
            }
        },
        // test client JS
        karma: {
            options: {
                singleRun: true,
                reporters: [ 'dots' ],
                configFile: 'test/client/config/karma.conf.js'
            },
            headless: {
                browsers: [ 'ChromeHeadless' ]
            },
            browsers: {
                browsers: [ 'Chrome', 'ChromeCanary', 'Firefox', 'Opera' /*,'Safari'*/ ],
            }
        },
        browserify: {
            development: {
                files: {
                    'public/js/enketo-webform-dev-bundle.js': [ 'public/js/src/main-webform.js' ],
                    'public/js/enketo-webform-edit-dev-bundle.js': [ 'public/js/src/main-webform-edit.js' ],
                    'public/js/enketo-webform-fs-dev-bundle.js': [ 'public/js/src/main-webform-fieldsubmission.js' ],
                    'public/js/enketo-webform-view-dev-bundle.js': [ 'public/js/src/main-webform-view.js' ],
                    'public/js/enketo-offline-fallback-dev-bundle.js': [ 'public/js/src/main-offline-fallback.js' ]
                },
                options: {
                    browserifyOptions: {
                        debug: true
                    }
                },
            },
            production: {
                files: {
                    'public/js/enketo-webform-bundle.js': [ 'public/js/src/main-webform.js' ],
                    'public/js/enketo-webform-edit-bundle.js': [ 'public/js/src/main-webform-edit.js' ],
                    'public/js/enketo-webform-fs-bundle.js': [ 'public/js/src/main-webform-fieldsubmission.js' ],
                    'public/js/enketo-webform-view-bundle.js': [ 'public/js/src/main-webform-view.js' ],
                    'public/js/enketo-offline-fallback-bundle.js': [ 'public/js/src/main-offline-fallback.js' ]
                },
            },
            options: {
                // ensure that enketo-config and widgets are overridden in **enketo-core**
                transform: [
                    [ 'aliasify', {
                        aliases: pkg.aliasify.aliases,
                        global: true
                    } ]
                ]
            },
        },
        uglify: {
            all: {
                files: {
                    'public/js/enketo-webform-bundle.min.js': [ 'public/js/enketo-webform-bundle.js' ],
                    'public/js/enketo-webform-edit-bundle.min.js': [ 'public/js/enketo-webform-edit-bundle.js' ],
                    'public/js/enketo-webform-fs-bundle.min.js': [ 'public/js/enketo-webform-fs-bundle.js' ],
                    'public/js/enketo-webform-view-bundle.min.js': [ 'public/js/enketo-webform-view-bundle.js' ],
                    'public/js/enketo-offline-fallback-bundle.min.js': [ 'public/js/enketo-offline-fallback-bundle.js' ],
                },
            },
        },
        env: {
            develop: {
                NODE_ENV: 'develop'
            },
            test: {
                NODE_ENV: 'test'
            },
            production: {
                NODE_ENV: 'production'
            }
        },
        i18next: {
            locales: {
                cwd: 'locales/',
                expand: true,
                src: [ '*/' ],
                include: [ '**/translation.json', '**/translation-additions.json' ],
                rename: function( dest, src ) {
                    return dest + src + 'translation-combined.json';
                },
                dest: 'locales/'
            }
        }
    } );

    grunt.registerTask( 'client-config-file', 'Temporary client-config file', function( task ) {
        var CLIENT_CONFIG_PATH = 'public/temp-client-config.json';
        if ( task === 'create' ) {
            var config = require( './app/models/config-model' );
            grunt.file.write( CLIENT_CONFIG_PATH, JSON.stringify( config.client ) );
            grunt.log.writeln( 'File ' + CLIENT_CONFIG_PATH + ' created' );
        } else if ( task === 'remove' ) {
            grunt.file.delete( CLIENT_CONFIG_PATH );
            grunt.log.writeln( 'File ' + CLIENT_CONFIG_PATH + ' removed' );
        }
    } );

    grunt.registerTask( 'system-sass-variables', 'Creating _system_variables.scss', function() {
        var SYSTEM_SASS_VARIABLES_PATH = 'app/views/styles/component/_system_variables.scss';
        var config = require( './app/models/config-model' );
        grunt.file.write( SYSTEM_SASS_VARIABLES_PATH, '$base-path: "' + config.server[ 'base path' ] + '";' );
        grunt.log.writeln( 'File ' + SYSTEM_SASS_VARIABLES_PATH + ' created' );
    } );

    grunt.registerTask( 'transforms', 'Creating forms.json', function() {
        var forms = {};
        var done = this.async();
        var jsonStringify = require( 'json-pretty' );
        var formsJsonPath = 'test/client/forms/forms.json';
        var xformsPaths = grunt.file.expand( {}, 'test/client/forms/*.xml' );
        var transformer = require( 'enketo-transformer' );

        xformsPaths.reduce( function( prevPromise, filePath ) {
                return prevPromise.then( function() {
                    var xformStr = grunt.file.read( filePath );
                    grunt.log.writeln( 'Transforming ' + filePath + '...' );
                    return transformer.transform( {
                            xform: xformStr,
                            includeRelevantMsg: true
                        } )
                        .then( function( result ) {
                            forms[ filePath.substring( filePath.lastIndexOf( '/' ) + 1 ) ] = {
                                html_form: result.form,
                                xml_model: result.model
                            };
                        } );
                } );

            }, Promise.resolve() )
            .then( function() {
                grunt.file.write( formsJsonPath, jsonStringify( forms ) );
                done();
            } );
    } );

    grunt.registerTask( 'widgets', 'generate widget reference files', function() {
        var content;
        var WIDGETS_JS_LOC = 'public/js/';
        var WIDGETS_JS = WIDGETS_JS_LOC + 'widgets.js';
        var WIDGETS_SASS_LOC = 'app/views/styles/component/';
        var WIDGETS_SASS = WIDGETS_SASS_LOC + '_widgets.scss';
        var PRE = '// This file is automatically generated with `grunt widgets`\n';
        var widgets = require( './app/models/config-model' ).server.widgets;
        var coreWidgets = require( './public/js/src/module/core-widgets' );
        var paths = Object.keys( widgets ).map( function( key ) {
            return coreWidgets[ widgets[ key ] ] || widgets[ key ];
        } );
        content = PRE + '\'use strict\';\n\nmodule.exports = [\n    ' +
            paths.map( function( p ) {
                return grunt.file.exists( WIDGETS_JS_LOC, p + '.js' ) ? 'require( \'' + p + '\' )' : '//' + p + ' not found';
            } ).join( ',\n    ' ) + '\n];\n';
        grunt.file.write( WIDGETS_JS, content );
        grunt.log.writeln( 'File ' + WIDGETS_JS + ' created' );
        content = PRE +
            paths.map( function( p ) {
                p = path.join( '../../', p );
                return grunt.file.exists( WIDGETS_SASS_LOC, p + '.scss' ) ? '@import "' + p + '"' : '//' + p + ' not found';
            } ).join( ';\n' ) + ';';
        grunt.file.write( WIDGETS_SASS, content );
        grunt.log.writeln( 'File ' + WIDGETS_SASS + ' created' );
    } );

    grunt.registerTask( 'default', [ 'i18next', 'widgets', 'css', 'js', 'uglify' ] );
    grunt.registerTask( 'js', [ 'client-config-file:create', 'widgets', 'browserify:production' ] );
    grunt.registerTask( 'js-dev', [ 'client-config-file:create', 'widgets', 'browserify:development' ] );
    grunt.registerTask( 'css', [ 'system-sass-variables:create', 'sass' ] );
    grunt.registerTask( 'test', [ 'env:test', 'transforms', 'js', 'css', 'mochaTest:all', 'karma:headless', 'jsbeautifier:test', 'eslint' ] );
    grunt.registerTask( 'test-browser', [ 'env:test', 'css', 'client-config-file:create', 'karma:browsers' ] );
    grunt.registerTask( 'develop', [ 'env:develop', 'i18next', 'js-dev', 'css', 'concurrent:develop' ] );
    grunt.registerTask( 'test-and-build', [ 'env:test', 'mochaTest:all', 'karma:headless', 'env:production', 'default' ] );
};
<|endoftext|>


<commit_before>/* jshint node: true */

module.exports = function(grunt) {
  "use strict";

  // Project configuration.
  grunt.initConfig({

    // Metadata.
    pkg: grunt.file.readJSON('package.json'),
    banner: '/**\n' +
              '* <%= pkg.name %>.js v<%= pkg.version %> by @fat and @mdo\n' +
              '* Copyright <%= grunt.template.today("yyyy") %> <%= pkg.author %>\n' +
              '* <%= _.pluck(pkg.licenses, "url").join(", ") %>\n' +
              '*/\n',
    jqueryCheck: 'if (!jQuery) { throw new Error(\"Bootstrap requires jQuery\") }\n\n',

    // Task configuration.
    clean: {
      dist: ['dist']
    },

    jshint: {
      options: {
        jshintrc: 'js/.jshintrc'
      },
      gruntfile: {
        src: 'Gruntfile.js'
      },
      src: {
        src: ['js/*.js']
      },
      test: {
        src: ['js/tests/unit/*.js']
      }
    },
    concat: {
      options: {
        banner: '<%= banner %><%= jqueryCheck %>',
        stripBanners: false
      },
      bootstrap: {
        src: [
          'js/transition.js',
          'js/alert.js',
          'js/button.js',
          'js/carousel.js',
          'js/collapse.js',
          'js/dropdown.js',
          'js/modal.js',
          'js/tooltip.js',
          'js/popover.js',
          'js/scrollspy.js',
          'js/tab.js',
          'js/affix.js'
        ],
        dest: 'dist/js/<%= pkg.name %>.js'
      }
    },
    uglify: {
      options: {
        banner: '<%= banner %>'
      },
      bootstrap: {
        src: ['<%= concat.bootstrap.dest %>'],
        dest: 'dist/js/<%= pkg.name %>.min.js'
      }
    },

    recess: {
      options: {
        compile: true
      },
      bootstrap: {
        src: ['less/bootstrap.less'],
        dest: 'dist/css/<%= pkg.name %>.css'
      },
      min: {
        options: {
          compress: true
        },
        src: ['less/bootstrap.less'],
        dest: 'dist/css/<%= pkg.name %>.min.css'
      }
    },

    qunit: {
      options: {
        inject: 'js/tests/unit/phantom.js'
      },
      files: ['js/tests/*.html']
    },
    connect: {
      server: {
        options: {
          port: 3000,
          base: '.'
        }
      }
    },

    watch: {
      src: {
        files: '<%= jshint.src.src %>',
        tasks: ['jshint:src', 'qunit']
      },
      test: {
        files: '<%= jshint.test.src %>',
        tasks: ['jshint:test', 'qunit']
      },
      recess: {
        files: 'less/*.less',
        tasks: ['recess']
      }
    }
  });

  // These plugins provide necessary tasks.
  grunt.loadNpmTasks('grunt-contrib-clean');
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-connect');
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-qunit');
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-recess');
  grunt.loadNpmTasks('browserstack-runner');

  // Test task.
  grunt.registerTask('test', ['jshint', 'qunit', 'browserstack_runner']);

  // JS distribution task.
  grunt.registerTask('dist-js', ['concat', 'uglify']);

  // CSS distribution task.
  grunt.registerTask('dist-css', ['recess']);

  // Full distribution task.
  grunt.registerTask('dist', ['clean', 'dist-css', 'dist-js']);

  // Default task.
  grunt.registerTask('default', ['test', 'dist']);
};
<commit_msg>only run browserstack tests in Travis<commit_after>/* jshint node: true */

module.exports = function(grunt) {
  "use strict";

  // Project configuration.
  grunt.initConfig({

    // Metadata.
    pkg: grunt.file.readJSON('package.json'),
    banner: '/**\n' +
              '* <%= pkg.name %>.js v<%= pkg.version %> by @fat and @mdo\n' +
              '* Copyright <%= grunt.template.today("yyyy") %> <%= pkg.author %>\n' +
              '* <%= _.pluck(pkg.licenses, "url").join(", ") %>\n' +
              '*/\n',
    jqueryCheck: 'if (!jQuery) { throw new Error(\"Bootstrap requires jQuery\") }\n\n',

    // Task configuration.
    clean: {
      dist: ['dist']
    },

    jshint: {
      options: {
        jshintrc: 'js/.jshintrc'
      },
      gruntfile: {
        src: 'Gruntfile.js'
      },
      src: {
        src: ['js/*.js']
      },
      test: {
        src: ['js/tests/unit/*.js']
      }
    },
    concat: {
      options: {
        banner: '<%= banner %><%= jqueryCheck %>',
        stripBanners: false
      },
      bootstrap: {
        src: [
          'js/transition.js',
          'js/alert.js',
          'js/button.js',
          'js/carousel.js',
          'js/collapse.js',
          'js/dropdown.js',
          'js/modal.js',
          'js/tooltip.js',
          'js/popover.js',
          'js/scrollspy.js',
          'js/tab.js',
          'js/affix.js'
        ],
        dest: 'dist/js/<%= pkg.name %>.js'
      }
    },
    uglify: {
      options: {
        banner: '<%= banner %>'
      },
      bootstrap: {
        src: ['<%= concat.bootstrap.dest %>'],
        dest: 'dist/js/<%= pkg.name %>.min.js'
      }
    },

    recess: {
      options: {
        compile: true
      },
      bootstrap: {
        src: ['less/bootstrap.less'],
        dest: 'dist/css/<%= pkg.name %>.css'
      },
      min: {
        options: {
          compress: true
        },
        src: ['less/bootstrap.less'],
        dest: 'dist/css/<%= pkg.name %>.min.css'
      }
    },

    qunit: {
      options: {
        inject: 'js/tests/unit/phantom.js'
      },
      files: ['js/tests/*.html']
    },
    connect: {
      server: {
        options: {
          port: 3000,
          base: '.'
        }
      }
    },

    watch: {
      src: {
        files: '<%= jshint.src.src %>',
        tasks: ['jshint:src', 'qunit']
      },
      test: {
        files: '<%= jshint.test.src %>',
        tasks: ['jshint:test', 'qunit']
      },
      recess: {
        files: 'less/*.less',
        tasks: ['recess']
      }
    }
  });

  // These plugins provide necessary tasks.
  grunt.loadNpmTasks('grunt-contrib-clean');
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-connect');
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-qunit');
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-recess');
  grunt.loadNpmTasks('browserstack-runner');

  // Test task.
  var testSubtasks = ['jshint', 'qunit'];
  if (process.env.TRAVIS) {
    testSubtasks.push('browserstack_runner');
  }
  grunt.registerTask('test', testSubtasks);

  // JS distribution task.
  grunt.registerTask('dist-js', ['concat', 'uglify']);

  // CSS distribution task.
  grunt.registerTask('dist-css', ['recess']);

  // Full distribution task.
  grunt.registerTask('dist', ['clean', 'dist-css', 'dist-js']);

  // Default task.
  grunt.registerTask('default', ['test', 'dist']);
};
<|endoftext|>


<commit_before>'use strict';

var controllersModule = require('./_index');

/**
 * @ngInject
 */
function ContactsCtrl($http, AppSettings, $log, $scope, $filter) {

  // ViewModel
  var vm = this;

  vm.contacts = [];
  vm.title = 'All contacts';

  $http.get(AppSettings.apiUrl + 'contacts').
    then(function(response) {
      vm.contacts = response.data.data;
    });

  $scope.deleteContact = function(contactId) {
    $http.delete(AppSettings.apiUrl + 'contacts/' + contactId).
      then(function(response) {
        vm.contacts = $filter('filter')(vm.contacts, { id: '!' + contactId });
      });
  };
}

function ContactDetailCtrl($http, AppSettings, $log, $stateParams) {

  // ViewModel
  var vm = this;
  var contactId = $stateParams.contactId;

  vm.title = 'Show contact';

  $http.get(AppSettings.apiUrl + 'contacts/' + contactId).
    then(function(response) {
      vm.contact = response.data.data;
    });
}

function ContactEditCtrl($scope, $http, AppSettings, $log, $stateParams, $state) {

  // ViewModel
  var vm = this;
  var contactId = $stateParams.contactId;

  vm.title = 'Edit contact';

  $http.get(AppSettings.apiUrl + 'contacts/' + contactId).
    then(function(response) {
      vm.contact = response.data.data;
    });

  $scope.updateContact = function() {
    var data = {
      contact: {
        name: vm.contact.name,
        phone: vm.contact.phone,
        email: vm.contact.email
      }
    };

    $http.put(AppSettings.apiUrl + 'contacts/' + contactId, data).
      then(function(response) {
        $state.go('Home');
      }, function(response) {
        vm.errorMessage = response.data.error.message;
      });
  };
}

function ContactNewCtrl($scope, $http, $log, AppSettings, $state) {

  // ViewModel
  var vm = this;
  vm.contact = {
    name: 'João Borges',
    email: 'jborges@medianeira.com',
    phone: '4599899930'
  }

  vm.title = 'New contact';
  $scope.addContact = function() {
    var data = { contact: vm.contact };

    $http.post(AppSettings.apiUrl + 'contacts', data).
      then(function(response) {
        $state.go('Home');
      }, function(response) {
        vm.errorMessage = response.data.error.message;
      });
  };
}

controllersModule.controller('ContactNewCtrl', ContactNewCtrl);
controllersModule.controller('ContactEditCtrl', ContactEditCtrl);
controllersModule.controller('ContactDetailCtrl', ContactDetailCtrl);
controllersModule.controller('ContactsCtrl', ContactsCtrl);
<commit_msg>Remove dummy data for Contact New initializer<commit_after>'use strict';

var controllersModule = require('./_index');

/**
 * @ngInject
 */
function ContactsCtrl($http, AppSettings, $log, $scope, $filter) {

  // ViewModel
  var vm = this;

  vm.contacts = [];
  vm.title = 'All contacts';

  $http.get(AppSettings.apiUrl + 'contacts').
    then(function(response) {
      vm.contacts = response.data.data;
    });

  $scope.deleteContact = function(contactId) {
    $http.delete(AppSettings.apiUrl + 'contacts/' + contactId).
      then(function(response) {
        vm.contacts = $filter('filter')(vm.contacts, { id: '!' + contactId });
      });
  };
}

function ContactDetailCtrl($http, AppSettings, $log, $stateParams) {

  // ViewModel
  var vm = this;
  var contactId = $stateParams.contactId;

  vm.title = 'Show contact';

  $http.get(AppSettings.apiUrl + 'contacts/' + contactId).
    then(function(response) {
      vm.contact = response.data.data;
    });
}

function ContactEditCtrl($scope, $http, AppSettings, $log, $stateParams, $state) {

  // ViewModel
  var vm = this;
  var contactId = $stateParams.contactId;

  vm.title = 'Edit contact';

  $http.get(AppSettings.apiUrl + 'contacts/' + contactId).
    then(function(response) {
      vm.contact = response.data.data;
    });

  $scope.updateContact = function() {
    var data = {
      contact: {
        name: vm.contact.name,
        phone: vm.contact.phone,
        email: vm.contact.email
      }
    };

    $http.put(AppSettings.apiUrl + 'contacts/' + contactId, data).
      then(function(response) {
        $state.go('Home');
      }, function(response) {
        vm.errorMessage = response.data.error.message;
      });
  };
}

function ContactNewCtrl($scope, $http, $log, AppSettings, $state) {

  // ViewModel
  var vm = this;
  vm.contact = {
    name: '',
    email: '',
    phone: ''
  }

  vm.title = 'New contact';
  $scope.addContact = function() {
    var data = { contact: vm.contact };

    $http.post(AppSettings.apiUrl + 'contacts', data).
      then(function(response) {
        $state.go('Home');
      }, function(response) {
        vm.errorMessage = response.data.error.message;
      });
  };
}

controllersModule.controller('ContactNewCtrl', ContactNewCtrl);
controllersModule.controller('ContactEditCtrl', ContactEditCtrl);
controllersModule.controller('ContactDetailCtrl', ContactDetailCtrl);
controllersModule.controller('ContactsCtrl', ContactsCtrl);
<|endoftext|>