<commit_before>(function () {
    /* (c) 2015 Oleg Grenrus MIT-Licensed. */
    'use strict';

    var h = Cycle.h;
    var Rx = Cycle.Rx;
    var svg = Cycle.svg;

    var MINGRADE = 0;
    var MAXGRADE = 3;
    var MINRADIUS = 30;
    var SVGRADIUS = 250;
    var GRAPHRADIUS = 200;

    var MINCOLS = 3;
    var MAXCOLS = 9;

    var MINROWS = 1;
    var MAXVISIBLEROWS = 6;
    var MAXROWS = 30;

    function button(title, disabled, ev) {
        var attributes = {
            'data-click': JSON.stringify(ev || null),
        };
        if (disabled) {
            attributes.disabled = 'disabled';
        }
        return h('button', { attributes: attributes }, title);
    }

    function dataCell(value, colIdx, rowIdx) {
        return h('td', [
            button('-', value <= MINGRADE, { type: 'minus', colIdx: colIdx, rowIdx: rowIdx }),
            ' ' + value + ' ',
            button('+', value >= MAXGRADE, { type: 'plus', colIdx: colIdx, rowIdx: rowIdx }),
        ]);
    }

    var STYLES = [
        'rgba( 51, 102, 153, 0.5)',
        'rgba(153,  51, 102, 0.5)',
        'rgba(102, 153,  51, 0.5)',
        'rgba( 51, 153, 102, 0.5)',
        'rgba(102,  51, 153, 0.5)',
        'rgba(153, 102,  51, 0.5)',
    ];

    var initialState = {
        fields: [
            'FP',
            'OO',
            'Type-safety',
            'Performance',
            'Obscurity',
        ],
        items: [
            { title: 'Haskell', data: [3, 1, 3, 2, 0], visible: true },
            { title: 'JavaScript', data: [2, 2, 0, 1, 2], visible: false },
            { title: 'C', data: [1, 1, 1, 3, 2], visible: true },
        ],
    };

    var initialSystem = {
        state: initialState,
        past: [],
        future: [],
    };

    function isVisible(item) {
        return item.visible;
    }

    function addColumn(newState) {
        var colCount = newState.fields.length;
        newState.fields[colCount] = 'Column ' + (colCount + 1);
        newState.items.forEach(function (item) {
            item.data[colCount] = MINGRADE;
        });
    }

    function removeColumn(newState, colIdx) {
        newState.fields.splice(colIdx, 1);
        newState.items.forEach(function (item) {
            item.data.splice(colIdx, 1);
        });
    }

    function addRow(newState, visibleCount) {
        newState.items.push({
            title: 'Row ' + (newState.items.length + 1),
            data: _.range(newState.fields.length).map(function () { return Math.floor(Math.random() * (MAXGRADE + 1)); }),
            visible: visibleCount < MAXVISIBLEROWS
        });
    }

    function removeRow(newState, rowIdx) {
        newState.items.splice(rowIdx, 1);
    }

    function moveRight(newState, colIdx) {
        var colCount = newState.fields.length;
        var f = _.identity;
        if (colIdx >= colCount - 1) {
            f = function (arr) {
                // add last to beginning
                arr.splice(0, 0, arr.splice(colIdx, 1));
            };
        } else {
            f = function (arr) {
                var tmp = arr[colIdx];
                arr[colIdx] = arr[colIdx + 1];
                arr[colIdx + 1] = tmp;
            };
        }
        f(newState.fields);
        newState.items.forEach(function (item) {
            f(item.data);
        });
    }

    function moveLeft(newState, colIdx) {
        var colCount = newState.fields.length;
        var f = _.identity;
        if (colIdx <= 0) {
            f = function (arr) {
                arr.splice(colCount - 1, 0, arr.splice(0, 1));
            };
        } else {
            f = function (arr) {
                var tmp = arr[colIdx];
                arr[colIdx] = arr[colIdx - 1];
                arr[colIdx - 1] = tmp;
            };
        }
        f(newState.fields);
        newState.items.forEach(function (item) {
            f(item.data);
        });
    }

    function applyEvent(system, ev) {
        var state = system.state;
        var newState = _.cloneDeep(state);
        var visibleItems = state.items.filter(isVisible);
        var visibleCount = visibleItems.length;

        switch (ev.type) {
            case 'undo': return {
                state: system.past[0],
                past: system.past.slice(1),
                future: [state].concat(system.future)
            };
            case 'redo': return {
                state: system.future[0],
                past: [state].concat(system.past),
                future: system.future.slice(1)
            };
            case 'plus': newState.items[ev.rowIdx].data[ev.colIdx] += 1; break;
            case 'minus': newState.items[ev.rowIdx].data[ev.colIdx] -= 1; break;
            case 'add-col': addColumn(newState); break;
            case 'remove-col': removeColumn(newState, ev.colIdx); break;
            case 'add-row': addRow(newState, visibleCount); break;
            case 'remove-row': removeRow(newState, ev.rowIdx); break;
            case 'move-right': moveRight(newState, ev.colIdx); break;
            case 'move-left': moveLeft(newState, ev.colIdx); break;
            case 'column-header': newState.fields[ev.colIdx] = ev.value; break;
            case 'row-header': newState.items[ev.rowIdx].title = ev.value; break;
            case 'show-hide': newState.items[ev.rowIdx].visible = ev.value; break;
            default:
                /* eslint-disable no-console */
                console.warn('UNKNOWN EVENT', ev);
                /* eslint-enable no-console */
                break;
        }

        return {
            state: newState,
            future: [],
            past: [state].concat(system.past)
        };
    }

    function render(system) {
        var state = system.state;
        var hasPast = system.past.length > 0;
        var hasFuture = system.future.length > 0;

        var rowCount = state.items.length;
        var colCount = state.fields.length;
        var visibleItems = state.items.filter(isVisible);
        var visibleCount = visibleItems.length;

        function calcR(grade) {
            return MINRADIUS + grade / MAXGRADE * (GRAPHRADIUS - MINRADIUS);
        }

        function calcTheta(colIdx) {
            return colIdx / colCount * Math.PI * 2;
        }

        function calcX(r, theta) {
            return Math.floor(r * Math.sin(theta) + SVGRADIUS);
        }

        function calcY(r, theta) {
            return Math.floor(-r * Math.cos(theta) + SVGRADIUS);
        }

        function calcPoint(r, theta) {
            return calcX(r, theta) + ',' + calcY(r, theta);
        }

        var grid1 = _.range(MAXGRADE + 1).map(function (grade) {
            var r = calcR(grade);

            var points = _.range(colCount).map(function (colIdx) {
                var theta = calcTheta(colIdx);
                return calcPoint(r, theta);
            }).join(' ');

            return svg('polygon', {
                attributes: {
                    points: points,
                },
                style: {
                    fill: 'rgba(0,0,0,0)',
                    stroke: 'white',
                    strokeWidth: 1,
                },
            });
        });

        var grid2 = _.range(colCount).map(function (colIdx) {
            var theta = calcTheta(colIdx);

            var r1 = MINRADIUS;
            var r2 = GRAPHRADIUS;

            return svg('line', {
                attributes: {
                    x1: calcX(r1, theta),
                    y1: calcY(r1, theta),
                    x2: calcX(r2, theta),
                    y2: calcY(r2, theta),
                },
                style: {
                    stroke: 'white',
                    strokeWidth: 1
                }
            });
        });

        var titles = state.fields.map(function (field, colIdx) {
            var theta = calcTheta(colIdx);
            var x = calcX(GRAPHRADIUS + 15, theta);
            var y = calcY(GRAPHRADIUS + 15, theta);
            var textTheta = theta > Math.PI / 2 && theta < 3 * Math.PI / 2 ? theta + Math.PI : theta;
            return svg('text', {
                attributes: {
                    x: x,
                    y: y,
                    fill: '#339966',
                    'text-anchor': 'middle',
                    transform: 'rotate(' + (textTheta / Math.PI * 180 + ' ' + x + ',' + y) + ')',
                }
            }, field);
        });

        var otherTitles = visibleItems.map(function (item, rowIdx) {
            return svg('text', {
                attributes: {
                    x: 10,
                    y: rowIdx * 18 + 15,
                    fill: STYLES[rowIdx % STYLES.length],
                    'text-anchor': 'start',
                }
            }, item.title);
        });

        var polygons = visibleItems.map(function (item, itemIdx) {
            var points = item.data.map(function (grade, colIdx) {
                var r = calcR(grade);
                var theta = calcTheta(colIdx);
                return calcPoint(r, theta);
            }).join(' ');

            return svg('polygon', {
                style: { fill: STYLES[itemIdx % STYLES.length] },
                attributes: { points: points }
            });
        });

        var svgElement = svg('svg', {
            style: {
                background: '#c6ece5'
            },
            attributes: {
                height: SVGRADIUS * 2,
                width: SVGRADIUS * 2,
            },
        }, _.flatten([grid1, grid2, titles, otherTitles, polygons]));

        var headerCells = state.fields.map(function (field, colIdx) {
            return h('th', [
                h('input', {
                    value: field,
                    attributes: {
                        'data-input': JSON.stringify({ type: 'column-header', colIdx: colIdx }),
                    }
                }),
                h('br'),
                button('←', false, { type: 'move-left', colIdx: colIdx }),
                button('→', false, { type: 'move-right', colIdx: colIdx }),
            ]);
        });

        var headerRow = h('tr', _.flatten([
            [h('th'), h('th', [
                button('undo', !hasPast, { type: 'undo' }),
                button('redo', !hasFuture, { type: 'redo' }),
            ])],
            headerCells,
            [h('th', button('add column', colCount >= MAXCOLS, { type: 'add-col' }))],
        ]));

        var footerRow = h('tr', _.flatten([
            [h('td'), h('td', button('add row', rowCount >= MAXROWS, { type: 'add-row' }))],
            _.range(colCount).map(function (colIdx) {
                return h('td', button('remove column', colCount <= MINCOLS, { type: 'remove-col', colIdx: colIdx }));
            }),
            [h('td')],
        ]));

        var dataRows = state.items.map(function (item, rowIdx) {
            var colorIdx = visibleItems.indexOf(item);
            var background = colorIdx === -1 ? 'white' : STYLES[colorIdx % STYLES.length];
            return h('tr', {
                style: {
                    background: background,
                }
            }, _.flatten([
                [
                    h('td', h('input', {
                        checked: item.visible,
                        disabled: !(item.visible ? visibleCount > 1 : visibleCount < MAXVISIBLEROWS),
                        type: 'checkbox',
                        attributes: {
                            'data-checkbox': JSON.stringify({ type: 'show-hide', rowIdx: rowIdx })
                        }
                    })),
                    h('td', h('input', {
                        value: item.title,
                        attributes: {
                            'data-input': JSON.stringify({ type: 'row-header', rowIdx: rowIdx }),
                        }
                    }))
                ],
                item.data.map(function (value, colIdx) {
                    return dataCell(value, colIdx, rowIdx);
                }),
                [h('td', button('remove row', item.visible ? visibleCount <= MINROWS : rowCount <= MINROWS, { type: 'remove-row', rowIdx: rowIdx }))],
            ]));
        });

        var table = h('table', _.flatten([
            [headerRow],
            dataRows,
            [footerRow],
        ]));

        var html = h('div', [
            svgElement,
            table
        ]);

        return html;
    }

    function computer(interactions) {
        var buttonClicks$ = interactions.get('button', 'click')
            .map(function (ev) {
                return JSON.parse(ev.target.getAttribute('data-click'));
            })
            .filter(_.negate(_.isEmpty));

        var inputs$ = interactions.get('input', 'input')
            .map(function (ev) {
                var el = ev.target;
                var data = JSON.parse(el.getAttribute('data-input'));
                data.value = el.value;
                return data;
            });

        var checkboxes$ = interactions.get('input[type=checkbox]', 'change')
            .map(function (ev) {
                var el = ev.target;
                var data = JSON.parse(el.getAttribute('data-checkbox'));
                data.value = el.checked;
                return data;
            });

        return Rx.Observable.merge(buttonClicks$, inputs$, checkboxes$)
            .scan(initialSystem, applyEvent)
            .startWith(initialSystem)
            .map(render);
    }

    Cycle.applyToDOM('#container', computer);
})();
<commit_msg>Limit undo<commit_after>(function () {
    /* (c) 2015 Oleg Grenrus MIT-Licensed. */
    'use strict';

    var h = Cycle.h;
    var Rx = Cycle.Rx;
    var svg = Cycle.svg;

    var MINGRADE = 0;
    var MAXGRADE = 3;
    var MINRADIUS = 30;
    var SVGRADIUS = 250;
    var GRAPHRADIUS = 200;

    var MINCOLS = 3;
    var MAXCOLS = 9;

    var MINROWS = 1;
    var MAXVISIBLEROWS = 6;
    var MAXROWS = 30;

    var MAXUNDO = 1000;

    function button(title, disabled, ev) {
        var attributes = {
            'data-click': JSON.stringify(ev || null),
        };
        if (disabled) {
            attributes.disabled = 'disabled';
        }
        return h('button', { attributes: attributes }, title);
    }

    function dataCell(value, colIdx, rowIdx) {
        return h('td', [
            button('-', value <= MINGRADE, { type: 'minus', colIdx: colIdx, rowIdx: rowIdx }),
            ' ' + value + ' ',
            button('+', value >= MAXGRADE, { type: 'plus', colIdx: colIdx, rowIdx: rowIdx }),
        ]);
    }

    var STYLES = [
        'rgba( 51, 102, 153, 0.5)',
        'rgba(153,  51, 102, 0.5)',
        'rgba(102, 153,  51, 0.5)',
        'rgba( 51, 153, 102, 0.5)',
        'rgba(102,  51, 153, 0.5)',
        'rgba(153, 102,  51, 0.5)',
    ];

    var initialState = {
        fields: [
            'FP',
            'OO',
            'Type-safety',
            'Performance',
            'Obscurity',
        ],
        items: [
            { title: 'Haskell', data: [3, 1, 3, 2, 0], visible: true },
            { title: 'JavaScript', data: [2, 2, 0, 1, 2], visible: false },
            { title: 'C', data: [1, 1, 1, 3, 2], visible: true },
        ],
    };

    var initialSystem = {
        state: initialState,
        past: [],
        future: [],
    };

    function isVisible(item) {
        return item.visible;
    }

    function addColumn(newState) {
        var colCount = newState.fields.length;
        newState.fields[colCount] = 'Column ' + (colCount + 1);
        newState.items.forEach(function (item) {
            item.data[colCount] = MINGRADE;
        });
    }

    function removeColumn(newState, colIdx) {
        newState.fields.splice(colIdx, 1);
        newState.items.forEach(function (item) {
            item.data.splice(colIdx, 1);
        });
    }

    function addRow(newState, visibleCount) {
        newState.items.push({
            title: 'Row ' + (newState.items.length + 1),
            data: _.range(newState.fields.length).map(function () { return Math.floor(Math.random() * (MAXGRADE + 1)); }),
            visible: visibleCount < MAXVISIBLEROWS
        });
    }

    function removeRow(newState, rowIdx) {
        newState.items.splice(rowIdx, 1);
    }

    function moveRight(newState, colIdx) {
        var colCount = newState.fields.length;
        var f = _.identity;
        if (colIdx >= colCount - 1) {
            f = function (arr) {
                // add last to beginning
                arr.splice(0, 0, arr.splice(colIdx, 1));
            };
        } else {
            f = function (arr) {
                var tmp = arr[colIdx];
                arr[colIdx] = arr[colIdx + 1];
                arr[colIdx + 1] = tmp;
            };
        }
        f(newState.fields);
        newState.items.forEach(function (item) {
            f(item.data);
        });
    }

    function moveLeft(newState, colIdx) {
        var colCount = newState.fields.length;
        var f = _.identity;
        if (colIdx <= 0) {
            f = function (arr) {
                arr.splice(colCount - 1, 0, arr.splice(0, 1));
            };
        } else {
            f = function (arr) {
                var tmp = arr[colIdx];
                arr[colIdx] = arr[colIdx - 1];
                arr[colIdx - 1] = tmp;
            };
        }
        f(newState.fields);
        newState.items.forEach(function (item) {
            f(item.data);
        });
    }

    function applyEvent(system, ev) {
        var state = system.state;
        var newState = _.cloneDeep(state);
        var visibleItems = state.items.filter(isVisible);
        var visibleCount = visibleItems.length;

        switch (ev.type) {
            case 'undo': return {
                state: system.past[0],
                past: system.past.slice(1),
                future: [state].concat(system.future)
            };
            case 'redo': return {
                state: system.future[0],
                past: [state].concat(system.past),
                future: system.future.slice(1)
            };
            case 'plus': newState.items[ev.rowIdx].data[ev.colIdx] += 1; break;
            case 'minus': newState.items[ev.rowIdx].data[ev.colIdx] -= 1; break;
            case 'add-col': addColumn(newState); break;
            case 'remove-col': removeColumn(newState, ev.colIdx); break;
            case 'add-row': addRow(newState, visibleCount); break;
            case 'remove-row': removeRow(newState, ev.rowIdx); break;
            case 'move-right': moveRight(newState, ev.colIdx); break;
            case 'move-left': moveLeft(newState, ev.colIdx); break;
            case 'column-header': newState.fields[ev.colIdx] = ev.value; break;
            case 'row-header': newState.items[ev.rowIdx].title = ev.value; break;
            case 'show-hide': newState.items[ev.rowIdx].visible = ev.value; break;
            default:
                /* eslint-disable no-console */
                console.warn('UNKNOWN EVENT', ev);
                /* eslint-enable no-console */
                break;
        }

        return {
            state: newState,
            future: [],
            past: _.take([state].concat(system.past), MAXUNDO) // no unlimited undo
        };
    }

    function render(system) {
        var state = system.state;
        var hasPast = system.past.length > 0;
        var hasFuture = system.future.length > 0;

        var rowCount = state.items.length;
        var colCount = state.fields.length;
        var visibleItems = state.items.filter(isVisible);
        var visibleCount = visibleItems.length;

        function calcR(grade) {
            return MINRADIUS + grade / MAXGRADE * (GRAPHRADIUS - MINRADIUS);
        }

        function calcTheta(colIdx) {
            return colIdx / colCount * Math.PI * 2;
        }

        function calcX(r, theta) {
            return Math.floor(r * Math.sin(theta) + SVGRADIUS);
        }

        function calcY(r, theta) {
            return Math.floor(-r * Math.cos(theta) + SVGRADIUS);
        }

        function calcPoint(r, theta) {
            return calcX(r, theta) + ',' + calcY(r, theta);
        }

        var grid1 = _.range(MAXGRADE + 1).map(function (grade) {
            var r = calcR(grade);

            var points = _.range(colCount).map(function (colIdx) {
                var theta = calcTheta(colIdx);
                return calcPoint(r, theta);
            }).join(' ');

            return svg('polygon', {
                attributes: {
                    points: points,
                },
                style: {
                    fill: 'rgba(0,0,0,0)',
                    stroke: 'white',
                    strokeWidth: 1,
                },
            });
        });

        var grid2 = _.range(colCount).map(function (colIdx) {
            var theta = calcTheta(colIdx);

            var r1 = MINRADIUS;
            var r2 = GRAPHRADIUS;

            return svg('line', {
                attributes: {
                    x1: calcX(r1, theta),
                    y1: calcY(r1, theta),
                    x2: calcX(r2, theta),
                    y2: calcY(r2, theta),
                },
                style: {
                    stroke: 'white',
                    strokeWidth: 1
                }
            });
        });

        var titles = state.fields.map(function (field, colIdx) {
            var theta = calcTheta(colIdx);
            var x = calcX(GRAPHRADIUS + 15, theta);
            var y = calcY(GRAPHRADIUS + 15, theta);
            var textTheta = theta > Math.PI / 2 && theta < 3 * Math.PI / 2 ? theta + Math.PI : theta;
            return svg('text', {
                attributes: {
                    x: x,
                    y: y,
                    fill: '#339966',
                    'text-anchor': 'middle',
                    transform: 'rotate(' + (textTheta / Math.PI * 180 + ' ' + x + ',' + y) + ')',
                }
            }, field);
        });

        var otherTitles = visibleItems.map(function (item, rowIdx) {
            return svg('text', {
                attributes: {
                    x: 10,
                    y: rowIdx * 18 + 15,
                    fill: STYLES[rowIdx % STYLES.length],
                    'text-anchor': 'start',
                }
            }, item.title);
        });

        var polygons = visibleItems.map(function (item, itemIdx) {
            var points = item.data.map(function (grade, colIdx) {
                var r = calcR(grade);
                var theta = calcTheta(colIdx);
                return calcPoint(r, theta);
            }).join(' ');

            return svg('polygon', {
                style: { fill: STYLES[itemIdx % STYLES.length] },
                attributes: { points: points }
            });
        });

        var svgElement = svg('svg', {
            style: {
                background: '#c6ece5'
            },
            attributes: {
                height: SVGRADIUS * 2,
                width: SVGRADIUS * 2,
            },
        }, _.flatten([grid1, grid2, titles, otherTitles, polygons]));

        var headerCells = state.fields.map(function (field, colIdx) {
            return h('th', [
                h('input', {
                    value: field,
                    attributes: {
                        'data-input': JSON.stringify({ type: 'column-header', colIdx: colIdx }),
                    }
                }),
                h('br'),
                button('←', false, { type: 'move-left', colIdx: colIdx }),
                button('→', false, { type: 'move-right', colIdx: colIdx }),
            ]);
        });

        var headerRow = h('tr', _.flatten([
            [h('th'), h('th', [
                button('undo', !hasPast, { type: 'undo' }),
                button('redo', !hasFuture, { type: 'redo' }),
            ])],
            headerCells,
            [h('th', button('add column', colCount >= MAXCOLS, { type: 'add-col' }))],
        ]));

        var footerRow = h('tr', _.flatten([
            [h('td'), h('td', button('add row', rowCount >= MAXROWS, { type: 'add-row' }))],
            _.range(colCount).map(function (colIdx) {
                return h('td', button('remove column', colCount <= MINCOLS, { type: 'remove-col', colIdx: colIdx }));
            }),
            [h('td')],
        ]));

        var dataRows = state.items.map(function (item, rowIdx) {
            var colorIdx = visibleItems.indexOf(item);
            var background = colorIdx === -1 ? 'white' : STYLES[colorIdx % STYLES.length];
            return h('tr', {
                style: {
                    background: background,
                }
            }, _.flatten([
                [
                    h('td', h('input', {
                        checked: item.visible,
                        disabled: !(item.visible ? visibleCount > 1 : visibleCount < MAXVISIBLEROWS),
                        type: 'checkbox',
                        attributes: {
                            'data-checkbox': JSON.stringify({ type: 'show-hide', rowIdx: rowIdx })
                        }
                    })),
                    h('td', h('input', {
                        value: item.title,
                        attributes: {
                            'data-input': JSON.stringify({ type: 'row-header', rowIdx: rowIdx }),
                        }
                    }))
                ],
                item.data.map(function (value, colIdx) {
                    return dataCell(value, colIdx, rowIdx);
                }),
                [h('td', button('remove row', item.visible ? visibleCount <= MINROWS : rowCount <= MINROWS, { type: 'remove-row', rowIdx: rowIdx }))],
            ]));
        });

        var table = h('table', _.flatten([
            [headerRow],
            dataRows,
            [footerRow],
        ]));

        var html = h('div', [
            svgElement,
            table
        ]);

        return html;
    }

    function computer(interactions) {
        var buttonClicks$ = interactions.get('button', 'click')
            .map(function (ev) {
                return JSON.parse(ev.target.getAttribute('data-click'));
            })
            .filter(_.negate(_.isEmpty));

        var inputs$ = interactions.get('input', 'input')
            .map(function (ev) {
                var el = ev.target;
                var data = JSON.parse(el.getAttribute('data-input'));
                data.value = el.value;
                return data;
            });

        var checkboxes$ = interactions.get('input[type=checkbox]', 'change')
            .map(function (ev) {
                var el = ev.target;
                var data = JSON.parse(el.getAttribute('data-checkbox'));
                data.value = el.checked;
                return data;
            });

        return Rx.Observable.merge(buttonClicks$, inputs$, checkboxes$)
            .scan(initialSystem, applyEvent)
            .startWith(initialSystem)
            .map(render);
    }

    Cycle.applyToDOM('#container', computer);
})();
<|endoftext|>


<commit_before>//-----------------------------------------------
app.controller('passengerRegisterCtrl', function($scope, $http){
  $scope.newPassenger = function(registrationData){
    $http.post('http://localhost:3000/passengers/create', registrationData)
      .success(function(data){
        console.log("the ajax call worked!!!!!!!!")
        console.log(data)
        // do something good
    })
      .error(function(){
        console.log("something needs to change!!!!!!!!!")
        console.log(data)
          //do something bad
    });
  };
})

//-----------------------------------------------
app.controller('passengerDashCtrl', function($scope, $ionicLoading) {

  // $scope.getMyLocation = function(){
  //   navigator.geolocation.getCurrentPosition(function (position) {
  //     return position;
  //   });
  // }

  $scope.mapCreated = function(map) {
    $scope.map = map;
  };

  $scope.centerOnMe = function () {
    console.log("Centering");
    if (!$scope.map) {
      return;
    }

    $scope.loading = $ionicLoading.show({
      content: 'Getting current location...',
      showBackdrop: false
    });

    navigator.geolocation.getCurrentPosition(function (pos) {
      console.log('Got your location');
      $scope.map.setCenter(new google.maps.LatLng(pos.coords.latitude, pos.coords.longitude));
      $ionicLoading.hide();
    }, function (error) {
      alert('Unable to get location: ' + error.message);
    });
  };
});

// app.controller('passengerSigninCtrl', function($scope, $stateParams, $http) {
//   $scope.data = {}
//   console.log($stateParams)
//   $scope.login = function(){
//     console.log($scope.data);
//     $http.post('http://bike-me.herokuapp.com', data).success(function(data){
//       $location.path("tab.passengerDash")
//       //add service to keep care of current user
//     });
//   }
// })

//-----------------------------------------------
app.controller('passengerChatsCtrl', function($scope, Chats) {
  $scope.chats = Chats.all();
})

//-----------------------------------------------
app.controller('passengerChatDetailCtrl', function($scope, $stateParams, Chats) {
  // console.log($stateParams)
  $scope.chat = Chats.get($stateParams.chatId);
  // console.log($scope.chat)
})

//-----------------------------------------------
app.controller('passengerAccountCtrl', function($scope) {
  $scope.settings = {
    enableFriends: false
  };
});
<commit_msg>add form for registration<commit_after>//-----------------------------------------------
app.controller('passengerRegisterCtrl', function($scope, $http){
  $scope.newPassenger = function(registrationData){
    console.log(registrationData)
    $http.post('http://localhost:3000/passengers', registrationData)
      .success(function(data){
        console.log("the ajax call worked!!!!!!!!")
        console.log(data)
        // do something good
    })
      .error(function(){
        console.log("something needs to change!!!!!!!!!")
        // console.log(data)
          //do something bad
    });
  };
})

//-----------------------------------------------
app.controller('passengerDashCtrl', function($scope, $ionicLoading) {

  // $scope.getMyLocation = function(){
  //   navigator.geolocation.getCurrentPosition(function (position) {
  //     return position;
  //   });
  // }

  $scope.mapCreated = function(map) {
    $scope.map = map;
  };

  $scope.centerOnMe = function () {
    console.log("Centering");
    if (!$scope.map) {
      return;
    }

    $scope.loading = $ionicLoading.show({
      content: 'Getting current location...',
      showBackdrop: false
    });

    navigator.geolocation.getCurrentPosition(function (pos) {
      console.log('Got your location');
      $scope.map.setCenter(new google.maps.LatLng(pos.coords.latitude, pos.coords.longitude));
      $ionicLoading.hide();
    }, function (error) {
      alert('Unable to get location: ' + error.message);
    });
  };
});

// app.controller('passengerSigninCtrl', function($scope, $stateParams, $http) {
//   $scope.data = {}
//   console.log($stateParams)
//   $scope.login = function(){
//     console.log($scope.data);
//     $http.post('http://bike-me.herokuapp.com', data).success(function(data){
//       $location.path("tab.passengerDash")
//       //add service to keep care of current user
//     });
//   }
// })

//-----------------------------------------------
app.controller('passengerChatsCtrl', function($scope, Chats) {
  $scope.chats = Chats.all();
})

//-----------------------------------------------
app.controller('passengerChatDetailCtrl', function($scope, $stateParams, Chats) {
  // console.log($stateParams)
  $scope.chat = Chats.get($stateParams.chatId);
  // console.log($scope.chat)
})

//-----------------------------------------------
app.controller('passengerAccountCtrl', function($scope) {
  $scope.settings = {
    enableFriends: false
  };
});
<|endoftext|>


<commit_before>var fs               = require('fs')
,   util             = require('util')
,   events           = require('events')
,   moment           = require('moment')
,   Playlist         = require('./api/Playlist')
,   Melted           = require('./api/Melted')
,   Media            = require('./api/Media')
,   ScheduledMedia   = require('./api/ScheduledMedia')
,   mvcp_server      = require('./drivers/mvcp/mvcp-driver')
,   playlists_driver = require('./drivers/playlists/playlists-driver')
,   status_driver    = require('./drivers/status/pubsub')
,   utils            = require('./utils')
,   config           = require('mbc-common').config.Mosto.General
,   _                = require('underscore')
,   hearbeats        = require('./heartbeats')
,   models           = require('./models/Mosto')
;

function mosto(customConfig) {

    /** CONFIGURATION */
    this.config = customConfig || config;
    this.server = undefined;
    this.server_started = false;
    this.pl_driver = undefined;
    this.status_driver = undefined;

    /* MODULES */
    this.heartbeats = undefined;
}

mosto.prototype.initDriver = function() {

    console.log("mbc-mosto: [INFO] Initializing playlists driver");

    self.driver.on ("create", function(playlist) {

        self.fetcher.addPlaylist( playlist, self.fetcher );
    } );
    self.driver.on ("update", function(playlist) {
        self.fetcher.updatePlaylist( playlist, self.fetcher);
    } );
    self.driver.on ("delete", function(playlist) {
        self.fetcher.removePlaylist( playlist, self.fetcher);
    } );

    self.driver.start();
};

mosto.prototype.stopDriver = function() {

    console.log("mbc-mosto: [INFO] Stopping playlists driver");

    self.driver.stop();

    self.driver.removeAllListeners("create");
    self.driver.removeAllListeners("update");
    self.driver.removeAllListeners("delete");
};

mosto.prototype.startMvcpServer = function(callback) {
    var result = self.server.initServer();
    result.then(function() {
        console.log("mbc-mosto: [INFO] MVCP server started");
        self.server_started = true;
        if (callback !== undefined) {
            callback();
        }
    }, function(err) {
        var e = new Error("mbc-mosto: [ERROR] Error starting MVCP server: " + err + ".\nRetrying in 2 seconds...");
        console.error(e);
        setTimeout(function() {
            self.startMvcpServer(callback);
        }, 2000);
    });
};

console.log("mbc-mosto: [INFO] Starting mbc-mosto... ") ;

mosto.prototype.init = function( melted, callback) {
    console.log("mbc-mosto: [INFO] Init mbc-mosto... ") ;
    var self = this;
    /*
     * inicializar los drivers
     * inicializar los modelos backbone
     * inicializar los heartbeats
     * linkear los eventos entre pl driver y backbone driver
     * linkear heartbeat con status driver
     */
    function startall() {
        self.server        = new mvcp_server(self.config.mvcp_server);
        self.pl_driver     = new playlists_driver(self.config.playlist_server);
        self.status_driver = new status_driver();
        self.playlists = models.Playlists;

        self.heartbeats.on('frameStatus', function(current_frame) {
            var now = moment();
            var current = self.playlists.get('melted_medias').find(function(media) {
                return media.get('start') <= now && media.get('end') >= now;
            });
            self.status_driver.setStatusClip(StatusClip(
                current.id,
                current.get('playlist_order'),
                current.playlist.id,
                current.get('fps'),
                current_frame,
                current.get('total_frames'),
            ));
        });
        self.heartbeats.on('clipStatus', function(media) {
            var melted_medias = self.playlists.get('melted_medias');
            var playlists = self.playlists.get('playlists');
            var status = {
                clip:{
                    previous: undefined,
                    current: undefined,
                    next: undefined,
                },
                show: {
                    previous: undefined,
                    current: undefined,
                    next: undefined,
                },
                position: 0,
                clips: melted_medias.toJSON(),
                status: none,
            };
            /* clips */
            var index = melted_medias.indexOf(media);
            status.clip.current = media.toJSON();
            if( index > 0 )
                status.clip.previous = melted_medias.at(index-1).toJSON();
            if( index < melted_medias.length )
                status.clip.next = melted_medias.at(index+1).toJSON();
            /* shows */
            var playlist = playlists.find(function(pl) {
                return pl.indexOf(media) >= 0;
            });
            index = playlists.indexOf(playlist);
            status.show.current = playlist.toJSON();
            if( index > 0 )
                status.show.previous = playlists.at(index-1).toJSON();
            if( index < playlists.length )
                status.show.next = playlists.at(index+1).toJSON();
            self.status_driver.setStatus(status);
        });

        self.pl_driver.on('create');
        self.pl_driver.on('update');
        self.pl_driver.on('delete');

        self.initDriver();
        self.heartbeats.init();

        self.startMvcpServer( function() {
            self.player.play( self.player );
            if (callback) callback();
        } );
    }

    function check_and_start() {
        Melted.is_running(function(running) {
            if (!running) {
                Melted.start(function(pid) {
                    Melted.setup( undefined, undefined, function(result) {
                        startall();
                    });
                });
            } else {
                startall();
            }
        });
    };

    if (melted!==undefined) {
        Melted = melted;
        check_and_start();
    }
    else
        Melted.take( check_and_start );

}

mosto.prototype.finish = function(callback) {
    console.log("mbc-mosto: [INFO] Finish mbc-mosto... ") ;
    self.stopDriver();
    self.player.stop();
    Melted.stop(function(pid) {
        setTimeout( function() {
            Melted.leave();
            if (callback) callback();
        }, 1000 );
    });
}

}

exports = module.exports = function(customConfig) {
    util.inherits(mosto, events.EventEmitter);
    var mosto_server = new mosto(customConfig);
    return mosto_server;
};
/*

  mosto tiene que:

  * inicializar melted
  * inicializar los drivers
  * inicializar los modelos backbone
  * inicializar los heartbeats
  * linkear los eventos entre pl driver y backbone driver
  * linkear heartbeat con status driver

  */
<commit_msg>Fixed the way events emitter was created<commit_after>var fs               = require('fs')
,   util             = require('util')
,   events           = require('events')
,   moment           = require('moment')
,   Playlist         = require('./api/Playlist')
,   Melted           = require('./api/Melted')
,   Media            = require('./api/Media')
,   ScheduledMedia   = require('./api/ScheduledMedia')
,   mvcp_server      = require('./drivers/mvcp/mvcp-driver')
,   playlists_driver = require('./drivers/playlists/playlists-driver')
,   status_driver    = require('./drivers/status/pubsub')
,   utils            = require('./utils')
,   config           = require('mbc-common').config.Mosto.General
,   _                = require('underscore')
,   hearbeats        = require('./heartbeats')
,   models           = require('./models/Mosto')
;

function mosto(customConfig) {

    /** CONFIGURATION */
    this.config = customConfig || config;
    this.server = undefined;
    this.server_started = false;
    this.pl_driver = undefined;
    this.status_driver = undefined;

    /* MODULES */
    this.heartbeats = undefined;

    events.EventEmitter.call(this);
}

util.inherits(mosto, events.EventEmitter);

mosto.prototype.initDriver = function() {

    console.log("mbc-mosto: [INFO] Initializing playlists driver");

    self.driver.on ("create", function(playlist) {

        self.fetcher.addPlaylist( playlist, self.fetcher );
    } );
    self.driver.on ("update", function(playlist) {
        self.fetcher.updatePlaylist( playlist, self.fetcher);
    } );
    self.driver.on ("delete", function(playlist) {
        self.fetcher.removePlaylist( playlist, self.fetcher);
    } );

    self.driver.start();
};

mosto.prototype.stopDriver = function() {

    console.log("mbc-mosto: [INFO] Stopping playlists driver");

    self.driver.stop();

    self.driver.removeAllListeners("create");
    self.driver.removeAllListeners("update");
    self.driver.removeAllListeners("delete");
};

mosto.prototype.startMvcpServer = function(callback) {
    var result = self.server.initServer();
    result.then(function() {
        console.log("mbc-mosto: [INFO] MVCP server started");
        self.server_started = true;
        if (callback !== undefined) {
            callback();
        }
    }, function(err) {
        var e = new Error("mbc-mosto: [ERROR] Error starting MVCP server: " + err + ".\nRetrying in 2 seconds...");
        console.error(e);
        setTimeout(function() {
            self.startMvcpServer(callback);
        }, 2000);
    });
};

console.log("mbc-mosto: [INFO] Starting mbc-mosto... ") ;

mosto.prototype.init = function( melted, callback) {
    console.log("mbc-mosto: [INFO] Init mbc-mosto... ") ;
    var self = this;
    /*
     * inicializar los drivers
     * inicializar los modelos backbone
     * inicializar los heartbeats
     * linkear los eventos entre pl driver y backbone driver
     * linkear heartbeat con status driver
     */
    function startall() {
        self.server        = new mvcp_server(self.config.mvcp_server);
        self.pl_driver     = new playlists_driver(self.config.playlist_server);
        self.status_driver = new status_driver();
        self.playlists = models.Playlists;

        self.heartbeats.on('frameStatus', function(current_frame) {
            var now = moment();
            var current = self.playlists.get('melted_medias').find(function(media) {
                return media.get('start') <= now && media.get('end') >= now;
            });
            self.status_driver.setStatusClip(StatusClip(
                current.id,
                current.get('playlist_order'),
                current.playlist.id,
                current.get('fps'),
                current_frame,
                current.get('total_frames'),
            ));
        });
        self.heartbeats.on('clipStatus', function(media) {
            var melted_medias = self.playlists.get('melted_medias');
            var playlists = self.playlists.get('playlists');
            var status = {
                clip:{
                    previous: undefined,
                    current: undefined,
                    next: undefined,
                },
                show: {
                    previous: undefined,
                    current: undefined,
                    next: undefined,
                },
                position: 0,
                clips: melted_medias.toJSON(),
                status: none,
            };
            /* clips */
            var index = melted_medias.indexOf(media);
            status.clip.current = media.toJSON();
            if( index > 0 )
                status.clip.previous = melted_medias.at(index-1).toJSON();
            if( index < melted_medias.length )
                status.clip.next = melted_medias.at(index+1).toJSON();
            /* shows */
            var playlist = playlists.find(function(pl) {
                return pl.indexOf(media) >= 0;
            });
            index = playlists.indexOf(playlist);
            status.show.current = playlist.toJSON();
            if( index > 0 )
                status.show.previous = playlists.at(index-1).toJSON();
            if( index < playlists.length )
                status.show.next = playlists.at(index+1).toJSON();
            self.status_driver.setStatus(status);
        });

        self.pl_driver.on('create');
        self.pl_driver.on('update');
        self.pl_driver.on('delete');

        self.initDriver();
        self.heartbeats.init();

        self.startMvcpServer( function() {
            self.player.play( self.player );
            if (callback) callback();
        } );
    }

    function check_and_start() {
        Melted.is_running(function(running) {
            if (!running) {
                Melted.start(function(pid) {
                    Melted.setup( undefined, undefined, function(result) {
                        startall();
                    });
                });
            } else {
                startall();
            }
        });
    };

    if (melted!==undefined) {
        Melted = melted;
        check_and_start();
    }
    else
        Melted.take( check_and_start );

}

mosto.prototype.finish = function(callback) {
    console.log("mbc-mosto: [INFO] Finish mbc-mosto... ") ;
    self.stopDriver();
    self.player.stop();
    Melted.stop(function(pid) {
        setTimeout( function() {
            Melted.leave();
            if (callback) callback();
        }, 1000 );
    });
}

}

exports = module.exports = function(customConfig) {
    var mosto_server = new mosto(customConfig);
    return mosto_server;
};
/*

  mosto tiene que:

  * inicializar melted
  * inicializar los drivers
  * inicializar los modelos backbone
  * inicializar los heartbeats
  * linkear los eventos entre pl driver y backbone driver
  * linkear heartbeat con status driver

  */
<|endoftext|>


<commit_before>/**
 * @ngdoc service
 * @name $ionicModal
 * @module ionic
 * @description
 *
 * Related {@link ionic.controller:ionicModal ionicModal controller}.
 *
 * The Modal is a content pane that can go over the user's main view
 * temporarily.  Usually used for making a choice or editing an item.
 * Note that you need to put the content of the modal inside a div with the class `modal`.
 *
 * Hint: Be sure to call [remove()](#remove) when you are done with each modal
 * to clean it up and avoid memory leaks.
 *
 * Note: a modal will broadcast 'modal.shown', 'modal.hidden', and 'modal.removed' events from its originating
 * scope, passing in itself as an event argument. Note: both modal.removed and modal.hidden are
 * called when the modal is removed.
 *
 * @usage
 * ```html
 * <script id="my-modal.html" type="text/ng-template">
 *   <div class="modal">
 *     <ion-header-bar>
 *       <h1 class="title">My Modal title</h1>
 *     </ion-header-bar>
 *     <ion-content>
 *       Hello!
 *     </ion-content>
 *   </div>
 * </script>
 * ```
 * ```js
 * angular.module('testApp', ['ionic'])
 * .controller('MyController', function($scope, $ionicModal) {
 *   $ionicModal.fromTemplateUrl('my-modal.html', {
 *     scope: $scope,
 *     animation: 'slide-in-up'
 *   }).then(function(modal) {
 *     $scope.modal = modal;
 *   });
 *   $scope.openModal = function() {
 *     $scope.modal.show();
 *   };
 *   $scope.closeModal = function() {
 *     $scope.modal.hide();
 *   };
 *   //Cleanup the modal when we're done with it!
 *   $scope.$on('$destroy', function() {
 *     $scope.modal.remove();
 *   });
 *   // Execute action on hide modal
 *   $scope.$on('modal.hidden', function() {
 *     // Execute action
 *   });
 *   // Execute action on remove modal
 *   $scope.$on('modal.removed', function() {
 *     // Execute action
 *   });
 * });
 * ```
 */
IonicModule
.factory('$ionicModal', [
  '$rootScope',
  '$document',
  '$compile',
  '$timeout',
  '$ionicPlatform',
  '$ionicTemplateLoader',
  '$q',
  '$log',
function($rootScope, $document, $compile, $timeout, $ionicPlatform, $ionicTemplateLoader, $q, $log) {

  /**
   * @ngdoc controller
   * @name ionicModal
   * @module ionic
   * @description
   * Instantiated by the {@link ionic.service:$ionicModal} service.
   *
   * Hint: Be sure to call [remove()](#remove) when you are done with each modal
   * to clean it up and avoid memory leaks.
   *
   * Note: a modal will broadcast 'modal.shown', 'modal.hidden', and 'modal.removed' events from its originating
   * scope, passing in itself as an event argument. Note: both modal.removed and modal.hidden are
   * called when the modal is removed.
   */
  var ModalView = ionic.views.Modal.inherit({
    /**
     * @ngdoc method
     * @name ionicModal#initialize
     * @description Creates a new modal controller instance.
     * @param {object} options An options object with the following properties:
     *  - `{object=}` `scope` The scope to be a child of.
     *    Default: creates a child of $rootScope.
     *  - `{string=}` `animation` The animation to show & hide with.
     *    Default: 'slide-in-up'
     *  - `{boolean=}` `focusFirstInput` Whether to autofocus the first input of
     *    the modal when shown.  Default: false.
     *  - `{boolean=}` `backdropClickToClose` Whether to close the modal on clicking the backdrop.
     *    Default: true.
     *  - `{boolean=}` `hardwareBackButtonClose` Whether the modal can be closed using the hardware
     *    back button on Android and similar devices.  Default: true.
     */
    initialize: function(opts) {
      ionic.views.Modal.prototype.initialize.call(this, opts);
      this.animation = opts.animation || 'slide-in-up';
    },

    /**
     * @ngdoc method
     * @name ionicModal#show
     * @description Show this modal instance.
     * @returns {promise} A promise which is resolved when the modal is finished animating in.
     */
    show: function() {
      var self = this;

      if(self.scope.$$destroyed) {
        $log.error('Cannot call modal.show() after remove(). Please create a new modal instance using $ionicModal.');
        return;
      }

      var modalEl = jqLite(self.modalEl);

      self.el.classList.remove('hide');
      $timeout(function(){
        $document[0].body.classList.add('modal-open');
      }, 400);

      if(!self.el.parentElement) {
        modalEl.addClass(self.animation);
        $document[0].body.appendChild(self.el);
      }

      modalEl.addClass('ng-enter active')
             .removeClass('ng-leave ng-leave-active');

      self._isShown = true;
      self._deregisterBackButton = $ionicPlatform.registerBackButtonAction(
        self.hardwareBackButtonClose ? angular.bind(self, self.hide) : angular.noop,
        PLATFORM_BACK_BUTTON_PRIORITY_MODAL
      );

      self._isOpenPromise = $q.defer();

      ionic.views.Modal.prototype.show.call(self);

      $timeout(function(){
        modalEl.addClass('ng-enter-active');
        self.scope.$parent && self.scope.$parent.$broadcast('modal.shown', self);
        self.el.classList.add('active');
      }, 20);

      return $timeout(function() {
        //After animating in, allow hide on backdrop click
        self.$el.on('click', function(e) {
          if (self.backdropClickToClose && e.target === self.el) {
            self.hide();
          }
        });
      }, 400);
    },

    /**
     * @ngdoc method
     * @name ionicModal#hide
     * @description Hide this modal instance.
     * @returns {promise} A promise which is resolved when the modal is finished animating out.
     */
    hide: function() {
      var self = this;
      var modalEl = jqLite(self.modalEl);

      self.el.classList.remove('active');
      modalEl.addClass('ng-leave');

      $timeout(function(){
        modalEl.addClass('ng-leave-active')
               .removeClass('ng-enter ng-enter-active active');
      }, 20);

      self.$el.off('click');
      self._isShown = false;
      self.scope.$parent && self.scope.$parent.$broadcast('modal.hidden', self);
      self._deregisterBackButton && self._deregisterBackButton();

      ionic.views.Modal.prototype.hide.call(self);

      return $timeout(function(){
        $document[0].body.classList.remove('modal-open');
        self.el.classList.add('hide');
      }, 500);
    },

    /**
     * @ngdoc method
     * @name ionicModal#remove
     * @description Remove this modal instance from the DOM and clean up.
     * @returns {promise} A promise which is resolved when the modal is finished animating out.
     */
    remove: function() {
      var self = this;
      self.scope.$parent && self.scope.$parent.$broadcast('modal.removed', self);

      return self.hide().then(function() {
        self.scope.$destroy();
        self.$el.remove();
      });
    },

    /**
     * @ngdoc method
     * @name ionicModal#isShown
     * @returns boolean Whether this modal is currently shown.
     */
    isShown: function() {
      return !!this._isShown;
    }
  });

  var createModal = function(templateString, options) {
    // Create a new scope for the modal
    var scope = options.scope && options.scope.$new() || $rootScope.$new(true);

    extend(scope, {
      $hasHeader: false,
      $hasSubheader: false,
      $hasFooter: false,
      $hasSubfooter: false,
      $hasTabs: false,
      $hasTabsTop: false
    });

    // Compile the template
    var element = $compile('<ion-modal>' + templateString + '</ion-modal>')(scope);

    options.$el = element;
    options.el = element[0];
    options.modalEl = options.el.querySelector('.modal');
    var modal = new ModalView(options);

    modal.scope = scope;

    // If this wasn't a defined scope, we can assign 'modal' to the isolated scope
    // we created
    if(!options.scope) {
      scope.modal = modal;
    }

    return modal;
  };

  return {
    /**
     * @ngdoc method
     * @name $ionicModal#fromTemplate
     * @param {string} templateString The template string to use as the modal's
     * content.
     * @param {object} options Options to be passed {@link ionic.controller:ionicModal#initialize ionicModal#initialize} method.
     * @returns {object} An instance of an {@link ionic.controller:ionicModal}
     * controller.
     */
    fromTemplate: function(templateString, options) {
      var modal = createModal(templateString, options || {});
      return modal;
    },
    /**
     * @ngdoc method
     * @name $ionicModal#fromTemplateUrl
     * @param {string} templateUrl The url to load the template from.
     * @param {object} options Options to be passed {@link ionic.controller:ionicModal#initialize ionicModal#initialize} method.
     * options object.
     * @returns {promise} A promise that will be resolved with an instance of
     * an {@link ionic.controller:ionicModal} controller.
     */
    fromTemplateUrl: function(url, options, _) {
      var cb;
      //Deprecated: allow a callback as second parameter. Now we return a promise.
      if (angular.isFunction(options)) {
        cb = options;
        options = _;
      }
      return $ionicTemplateLoader.load(url).then(function(templateString) {
        var modal = createModal(templateString, options || {});
        cb && cb(modal);
        return modal;
      });
    }
  };
}]);
<commit_msg>docs($ionicModal: add colon<commit_after>/**
 * @ngdoc service
 * @name $ionicModal
 * @module ionic
 * @description
 *
 * Related: {@link ionic.controller:ionicModal ionicModal controller}.
 *
 * The Modal is a content pane that can go over the user's main view
 * temporarily.  Usually used for making a choice or editing an item.
 * Note that you need to put the content of the modal inside a div with the class `modal`.
 *
 * Hint: Be sure to call [remove()](#remove) when you are done with each modal
 * to clean it up and avoid memory leaks.
 *
 * Note: a modal will broadcast 'modal.shown', 'modal.hidden', and 'modal.removed' events from its originating
 * scope, passing in itself as an event argument. Note: both modal.removed and modal.hidden are
 * called when the modal is removed.
 *
 * @usage
 * ```html
 * <script id="my-modal.html" type="text/ng-template">
 *   <div class="modal">
 *     <ion-header-bar>
 *       <h1 class="title">My Modal title</h1>
 *     </ion-header-bar>
 *     <ion-content>
 *       Hello!
 *     </ion-content>
 *   </div>
 * </script>
 * ```
 * ```js
 * angular.module('testApp', ['ionic'])
 * .controller('MyController', function($scope, $ionicModal) {
 *   $ionicModal.fromTemplateUrl('my-modal.html', {
 *     scope: $scope,
 *     animation: 'slide-in-up'
 *   }).then(function(modal) {
 *     $scope.modal = modal;
 *   });
 *   $scope.openModal = function() {
 *     $scope.modal.show();
 *   };
 *   $scope.closeModal = function() {
 *     $scope.modal.hide();
 *   };
 *   //Cleanup the modal when we're done with it!
 *   $scope.$on('$destroy', function() {
 *     $scope.modal.remove();
 *   });
 *   // Execute action on hide modal
 *   $scope.$on('modal.hidden', function() {
 *     // Execute action
 *   });
 *   // Execute action on remove modal
 *   $scope.$on('modal.removed', function() {
 *     // Execute action
 *   });
 * });
 * ```
 */
IonicModule
.factory('$ionicModal', [
  '$rootScope',
  '$document',
  '$compile',
  '$timeout',
  '$ionicPlatform',
  '$ionicTemplateLoader',
  '$q',
  '$log',
function($rootScope, $document, $compile, $timeout, $ionicPlatform, $ionicTemplateLoader, $q, $log) {

  /**
   * @ngdoc controller
   * @name ionicModal
   * @module ionic
   * @description
   * Instantiated by the {@link ionic.service:$ionicModal} service.
   *
   * Hint: Be sure to call [remove()](#remove) when you are done with each modal
   * to clean it up and avoid memory leaks.
   *
   * Note: a modal will broadcast 'modal.shown', 'modal.hidden', and 'modal.removed' events from its originating
   * scope, passing in itself as an event argument. Note: both modal.removed and modal.hidden are
   * called when the modal is removed.
   */
  var ModalView = ionic.views.Modal.inherit({
    /**
     * @ngdoc method
     * @name ionicModal#initialize
     * @description Creates a new modal controller instance.
     * @param {object} options An options object with the following properties:
     *  - `{object=}` `scope` The scope to be a child of.
     *    Default: creates a child of $rootScope.
     *  - `{string=}` `animation` The animation to show & hide with.
     *    Default: 'slide-in-up'
     *  - `{boolean=}` `focusFirstInput` Whether to autofocus the first input of
     *    the modal when shown.  Default: false.
     *  - `{boolean=}` `backdropClickToClose` Whether to close the modal on clicking the backdrop.
     *    Default: true.
     *  - `{boolean=}` `hardwareBackButtonClose` Whether the modal can be closed using the hardware
     *    back button on Android and similar devices.  Default: true.
     */
    initialize: function(opts) {
      ionic.views.Modal.prototype.initialize.call(this, opts);
      this.animation = opts.animation || 'slide-in-up';
    },

    /**
     * @ngdoc method
     * @name ionicModal#show
     * @description Show this modal instance.
     * @returns {promise} A promise which is resolved when the modal is finished animating in.
     */
    show: function() {
      var self = this;

      if(self.scope.$$destroyed) {
        $log.error('Cannot call modal.show() after remove(). Please create a new modal instance using $ionicModal.');
        return;
      }

      var modalEl = jqLite(self.modalEl);

      self.el.classList.remove('hide');
      $timeout(function(){
        $document[0].body.classList.add('modal-open');
      }, 400);

      if(!self.el.parentElement) {
        modalEl.addClass(self.animation);
        $document[0].body.appendChild(self.el);
      }

      modalEl.addClass('ng-enter active')
             .removeClass('ng-leave ng-leave-active');

      self._isShown = true;
      self._deregisterBackButton = $ionicPlatform.registerBackButtonAction(
        self.hardwareBackButtonClose ? angular.bind(self, self.hide) : angular.noop,
        PLATFORM_BACK_BUTTON_PRIORITY_MODAL
      );

      self._isOpenPromise = $q.defer();

      ionic.views.Modal.prototype.show.call(self);

      $timeout(function(){
        modalEl.addClass('ng-enter-active');
        self.scope.$parent && self.scope.$parent.$broadcast('modal.shown', self);
        self.el.classList.add('active');
      }, 20);

      return $timeout(function() {
        //After animating in, allow hide on backdrop click
        self.$el.on('click', function(e) {
          if (self.backdropClickToClose && e.target === self.el) {
            self.hide();
          }
        });
      }, 400);
    },

    /**
     * @ngdoc method
     * @name ionicModal#hide
     * @description Hide this modal instance.
     * @returns {promise} A promise which is resolved when the modal is finished animating out.
     */
    hide: function() {
      var self = this;
      var modalEl = jqLite(self.modalEl);

      self.el.classList.remove('active');
      modalEl.addClass('ng-leave');

      $timeout(function(){
        modalEl.addClass('ng-leave-active')
               .removeClass('ng-enter ng-enter-active active');
      }, 20);

      self.$el.off('click');
      self._isShown = false;
      self.scope.$parent && self.scope.$parent.$broadcast('modal.hidden', self);
      self._deregisterBackButton && self._deregisterBackButton();

      ionic.views.Modal.prototype.hide.call(self);

      return $timeout(function(){
        $document[0].body.classList.remove('modal-open');
        self.el.classList.add('hide');
      }, 500);
    },

    /**
     * @ngdoc method
     * @name ionicModal#remove
     * @description Remove this modal instance from the DOM and clean up.
     * @returns {promise} A promise which is resolved when the modal is finished animating out.
     */
    remove: function() {
      var self = this;
      self.scope.$parent && self.scope.$parent.$broadcast('modal.removed', self);

      return self.hide().then(function() {
        self.scope.$destroy();
        self.$el.remove();
      });
    },

    /**
     * @ngdoc method
     * @name ionicModal#isShown
     * @returns boolean Whether this modal is currently shown.
     */
    isShown: function() {
      return !!this._isShown;
    }
  });

  var createModal = function(templateString, options) {
    // Create a new scope for the modal
    var scope = options.scope && options.scope.$new() || $rootScope.$new(true);

    extend(scope, {
      $hasHeader: false,
      $hasSubheader: false,
      $hasFooter: false,
      $hasSubfooter: false,
      $hasTabs: false,
      $hasTabsTop: false
    });

    // Compile the template
    var element = $compile('<ion-modal>' + templateString + '</ion-modal>')(scope);

    options.$el = element;
    options.el = element[0];
    options.modalEl = options.el.querySelector('.modal');
    var modal = new ModalView(options);

    modal.scope = scope;

    // If this wasn't a defined scope, we can assign 'modal' to the isolated scope
    // we created
    if(!options.scope) {
      scope.modal = modal;
    }

    return modal;
  };

  return {
    /**
     * @ngdoc method
     * @name $ionicModal#fromTemplate
     * @param {string} templateString The template string to use as the modal's
     * content.
     * @param {object} options Options to be passed {@link ionic.controller:ionicModal#initialize ionicModal#initialize} method.
     * @returns {object} An instance of an {@link ionic.controller:ionicModal}
     * controller.
     */
    fromTemplate: function(templateString, options) {
      var modal = createModal(templateString, options || {});
      return modal;
    },
    /**
     * @ngdoc method
     * @name $ionicModal#fromTemplateUrl
     * @param {string} templateUrl The url to load the template from.
     * @param {object} options Options to be passed {@link ionic.controller:ionicModal#initialize ionicModal#initialize} method.
     * options object.
     * @returns {promise} A promise that will be resolved with an instance of
     * an {@link ionic.controller:ionicModal} controller.
     */
    fromTemplateUrl: function(url, options, _) {
      var cb;
      //Deprecated: allow a callback as second parameter. Now we return a promise.
      if (angular.isFunction(options)) {
        cb = options;
        options = _;
      }
      return $ionicTemplateLoader.load(url).then(function(templateString) {
        var modal = createModal(templateString, options || {});
        cb && cb(modal);
        return modal;
      });
    }
  };
}]);
<|endoftext|>


<commit_before>var utils = require('./test-utils');
var assert = require('chai').assert;

var Domain = require('../lib/database/domain').Domain;

var context;
var temporaryDatabase;

function commonSetup() {
  temporaryDatabase = utils.createTemporaryDatabase();
  context = temporaryDatabase.get();
}

function commonTeardown() {
  context = undefined;
  temporaryDatabase.clear();
  temporaryDatabase.teardown();
  temporaryDatabase = undefined;
}

suite('cs-create-domain', function() {
  setup(commonSetup);
  teardown(commonTeardown);

  test('create', function(done) {
    utils
      .run('cs-create-domain',
           '--domain-name', 'test',
           '--database-path', temporaryDatabase.path)
      .next(function(result) {
        assert.equal(result.code, 0);
        assert.include(result.output.stdout,
                       'Domain endpoints are currently being created.');

        context.reopen();
        var domain = new Domain('test', context);
        assert.isTrue(domain.exists());

        done();
      })
      .error(function(e) {
        done(e);
      });
  });

  test('create again', function(done) {
    utils
      .run('cs-create-domain',
           '--domain-name', 'test',
           '--database-path', temporaryDatabase.path)
      .run('cs-create-domain',
           '--domain-name', 'test',
           '--database-path', temporaryDatabase.path)
      .next(function(result) {
        assert.equal(result.code, 1);
        assert.include(result.output.stdout,
                       'The domain [test] already exists.');

        context.reopen();
        var domains = Domain.getAll(context).map(function(domain) {
              return domain.name;
            });
        assert.deepEqual(domains, ['test']);

        done();
      })
      .error(function(e) {
        done(e);
      });
  });

  test('missing domain name', function(done) {
    utils
      .run('cs-create-domain',
           '--database-path', temporaryDatabase.path)
      .next(function(result) {
        assert.equal(result.code, 1);
        assert.include(result.output.stdout,
                       'You must specify the domain name.');

        context.reopen();
        assert.deepEqual(Domain.getAll(context), []);

        done();
      })
      .error(function(e) {
        done(e);
      });
  });
});

suite('cs-describe-domain', function() {
  setup(commonSetup);
  teardown(commonTeardown);

  function report(domain, hostname) {
    return [
      'Domain Name               ' + domain.name,
      'Document Service Endpoint ' + domain.getDocumentsEndpoint(hostname),
      'Search Endpoint           ' + domain.getSearchEndpoint(hostname),
      'Searchable Documents      ' + domain.searchableDocumentsCount,
      'Index Fields              ' + domain.name,
      'SearchPartitionCount      ' + domain.searchPartitionCount,
      'SearchInstanceCount       ' + domain.searchInstanceCount,
      'SearchInstanceType        ' + domain.searchInstanceType
    ].join('\n');
  }

  test('describe one', function(done) {
    utils
      .run('cs-create-domain',
           '--domain-name', 'domain2',
           '--database-path', temporaryDatabase.path)
      .run('cs-create-domain',
           '--domain-name', 'domain1',
           '--database-path', temporaryDatabase.path)
      .run('cs-describe-domain',
           '--domain-name', 'domain1',
           '--database-path', temporaryDatabase.path)
      .next(function(result) {
        assert.equal(result.code, 0);
        assert.include(result.output.stdout,
                       report(new Domain('domain1', context), 'localhost'));

        done();
      })
      .error(function(e) {
        done(e);
      });
  });

  test('describe all', function(done) {
    utils
      .run('cs-create-domain',
           '--domain-name', 'domain2',
           '--database-path', temporaryDatabase.path)
      .run('cs-create-domain',
           '--domain-name', 'domain1',
           '--database-path', temporaryDatabase.path)
      .run('cs-describe-domain',
           '--show-all',
           '--database-path', temporaryDatabase.path)
      .next(function(result) {
        assert.equal(result.code, 0);
        assert.include(result.output.stdout,
                       report(new Domain('domain2', context), 'localhost'));
        assert.include(result.output.stdout,
                       report(new Domain('domain1', context), 'localhost'));

        done();
      })
      .error(function(e) {
        done(e);
      });
  });
});

suite('cs-configure-fields', function() {
  setup(commonSetup);
  teardown(commonTeardown);

  function testCreateField(done, name, type) {
    utils
      .run('cs-create-domain',
           '--domain-name', 'companies',
           '--database-path', temporaryDatabase.path)
      .run('cs-configure-fields',
           '--domain-name', 'companies',
           '--name', name,
           '--type', type,
           '--database-path', temporaryDatabase.path)
      .next(function(result) {
        assert.equal(result.code, 0);
        assert.equal(result.output.stdout,
                     'Updated 1 Index Field:\n' +
                     name + ' RequiresIndexDocuments ' + type + ' ()\n');

        context.reopen();
        var domain = new Domain('companies', context);
        var field = domain.getIndexField(name);
        assert.deepEqual({ type: field.type, exists: field.exists() },
                         { type: type, exists: true });

        done();
      })
      .error(function(e) {
        done(e);
      });
  }

  test('create text field', function(done) {
    testCreateField(done, 'name', 'text');
  });
  test('create uint field', function(done) {
    testCreateField(done, 'age', 'uint');
  });
  test('create literal field', function(done) {
    testCreateField(done, 'product', 'literal');
  });

  function testDeleteField(done, name, type) {
    utils
      .run('cs-create-domain',
           '--domain-name', 'companies',
           '--database-path', temporaryDatabase.path)
      .run('cs-configure-fields',
           '--domain-name', 'companies',
           '--name', name,
           '--type', type,
           '--database-path', temporaryDatabase.path)
      .run('cs-configure-fields',
           '--domain-name', 'companies',
           '--name', name,
           '--delete',
           '--database-path', temporaryDatabase.path)
      .next(function(result) {
        assert.equal(result.code, 0);
        assert.equal(result.output.stdout,
                     'Updated 1 Index Field:\n';

        context.reopen();
        var domain = new Domain('companies', context);
        var field = domain.getIndexField(name);
        assert.isFalse(field.exists());

        done();
      })
      .error(function(e) {
        done(e);
      });
  }

  test('delete text field', function(done) {
    testDeleteField(done, 'name', 'text');
  });
  test('delete uint field', function(done) {
    testDeleteField(done, 'age', 'uint');
  });
  test('delete literal field', function(done) {
    testDeleteField(done, 'product', 'literal');
  });
});
<commit_msg>Fix syntax error<commit_after>var utils = require('./test-utils');
var assert = require('chai').assert;

var Domain = require('../lib/database/domain').Domain;

var context;
var temporaryDatabase;

function commonSetup() {
  temporaryDatabase = utils.createTemporaryDatabase();
  context = temporaryDatabase.get();
}

function commonTeardown() {
  context = undefined;
  temporaryDatabase.clear();
  temporaryDatabase.teardown();
  temporaryDatabase = undefined;
}

suite('cs-create-domain', function() {
  setup(commonSetup);
  teardown(commonTeardown);

  test('create', function(done) {
    utils
      .run('cs-create-domain',
           '--domain-name', 'test',
           '--database-path', temporaryDatabase.path)
      .next(function(result) {
        assert.equal(result.code, 0);
        assert.include(result.output.stdout,
                       'Domain endpoints are currently being created.');

        context.reopen();
        var domain = new Domain('test', context);
        assert.isTrue(domain.exists());

        done();
      })
      .error(function(e) {
        done(e);
      });
  });

  test('create again', function(done) {
    utils
      .run('cs-create-domain',
           '--domain-name', 'test',
           '--database-path', temporaryDatabase.path)
      .run('cs-create-domain',
           '--domain-name', 'test',
           '--database-path', temporaryDatabase.path)
      .next(function(result) {
        assert.equal(result.code, 1);
        assert.include(result.output.stdout,
                       'The domain [test] already exists.');

        context.reopen();
        var domains = Domain.getAll(context).map(function(domain) {
              return domain.name;
            });
        assert.deepEqual(domains, ['test']);

        done();
      })
      .error(function(e) {
        done(e);
      });
  });

  test('missing domain name', function(done) {
    utils
      .run('cs-create-domain',
           '--database-path', temporaryDatabase.path)
      .next(function(result) {
        assert.equal(result.code, 1);
        assert.include(result.output.stdout,
                       'You must specify the domain name.');

        context.reopen();
        assert.deepEqual(Domain.getAll(context), []);

        done();
      })
      .error(function(e) {
        done(e);
      });
  });
});

suite('cs-describe-domain', function() {
  setup(commonSetup);
  teardown(commonTeardown);

  function report(domain, hostname) {
    return [
      'Domain Name               ' + domain.name,
      'Document Service Endpoint ' + domain.getDocumentsEndpoint(hostname),
      'Search Endpoint           ' + domain.getSearchEndpoint(hostname),
      'Searchable Documents      ' + domain.searchableDocumentsCount,
      'Index Fields              ' + domain.name,
      'SearchPartitionCount      ' + domain.searchPartitionCount,
      'SearchInstanceCount       ' + domain.searchInstanceCount,
      'SearchInstanceType        ' + domain.searchInstanceType
    ].join('\n');
  }

  test('describe one', function(done) {
    utils
      .run('cs-create-domain',
           '--domain-name', 'domain2',
           '--database-path', temporaryDatabase.path)
      .run('cs-create-domain',
           '--domain-name', 'domain1',
           '--database-path', temporaryDatabase.path)
      .run('cs-describe-domain',
           '--domain-name', 'domain1',
           '--database-path', temporaryDatabase.path)
      .next(function(result) {
        assert.equal(result.code, 0);
        assert.include(result.output.stdout,
                       report(new Domain('domain1', context), 'localhost'));

        done();
      })
      .error(function(e) {
        done(e);
      });
  });

  test('describe all', function(done) {
    utils
      .run('cs-create-domain',
           '--domain-name', 'domain2',
           '--database-path', temporaryDatabase.path)
      .run('cs-create-domain',
           '--domain-name', 'domain1',
           '--database-path', temporaryDatabase.path)
      .run('cs-describe-domain',
           '--show-all',
           '--database-path', temporaryDatabase.path)
      .next(function(result) {
        assert.equal(result.code, 0);
        assert.include(result.output.stdout,
                       report(new Domain('domain2', context), 'localhost'));
        assert.include(result.output.stdout,
                       report(new Domain('domain1', context), 'localhost'));

        done();
      })
      .error(function(e) {
        done(e);
      });
  });
});

suite('cs-configure-fields', function() {
  setup(commonSetup);
  teardown(commonTeardown);

  function testCreateField(done, name, type) {
    utils
      .run('cs-create-domain',
           '--domain-name', 'companies',
           '--database-path', temporaryDatabase.path)
      .run('cs-configure-fields',
           '--domain-name', 'companies',
           '--name', name,
           '--type', type,
           '--database-path', temporaryDatabase.path)
      .next(function(result) {
        assert.equal(result.code, 0);
        assert.equal(result.output.stdout,
                     'Updated 1 Index Field:\n' +
                     name + ' RequiresIndexDocuments ' + type + ' ()\n');

        context.reopen();
        var domain = new Domain('companies', context);
        var field = domain.getIndexField(name);
        assert.deepEqual({ type: field.type, exists: field.exists() },
                         { type: type, exists: true });

        done();
      })
      .error(function(e) {
        done(e);
      });
  }

  test('create text field', function(done) {
    testCreateField(done, 'name', 'text');
  });
  test('create uint field', function(done) {
    testCreateField(done, 'age', 'uint');
  });
  test('create literal field', function(done) {
    testCreateField(done, 'product', 'literal');
  });

  function testDeleteField(done, name, type) {
    utils
      .run('cs-create-domain',
           '--domain-name', 'companies',
           '--database-path', temporaryDatabase.path)
      .run('cs-configure-fields',
           '--domain-name', 'companies',
           '--name', name,
           '--type', type,
           '--database-path', temporaryDatabase.path)
      .run('cs-configure-fields',
           '--domain-name', 'companies',
           '--name', name,
           '--delete',
           '--database-path', temporaryDatabase.path)
      .next(function(result) {
        assert.equal(result.code, 0);
        assert.equal(result.output.stdout,
                     'Updated 1 Index Field:\n');

        context.reopen();
        var domain = new Domain('companies', context);
        var field = domain.getIndexField(name);
        assert.isFalse(field.exists());

        done();
      })
      .error(function(e) {
        done(e);
      });
  }

  test('delete text field', function(done) {
    testDeleteField(done, 'name', 'text');
  });
  test('delete uint field', function(done) {
    testDeleteField(done, 'age', 'uint');
  });
  test('delete literal field', function(done) {
    testDeleteField(done, 'product', 'literal');
  });
});
<|endoftext|>


<commit_before>
"use strict";

importScripts('../dom.js');

var addEventListener = function(type, cb, bubble) {
    document.addEventListener(type, cb, bubble);
};

var navigator = { userAgent: 'servo 0.1 webworker' }
var location = {href: "http://example.com/foo", search: ""}
var window = this;

function print() {
    var out = '';
    for (var i = 0; i < arguments.length; i++) {
        out += arguments[i] + ' ';
    }
    postMessage(out);
}

var console = {log: print}

var parser_num = 1;
var parsing = {}

onerror = function(err) {
    return false;
}

function handle_message(message) {
    try {
        var data = message.data;
        var reply = {}
        var parser = null;

        if (data.url) {
            parser = document.implementation.mozHTMLParser(data.url);
            var doc = parser.document();
            // work around for a proxy bug in ff
            Object.defineProperty(this, "document", { value: doc});

            doc.implementation.mozSetOutputMutationHandler(
                doc, function(msg) { postMessage(msg) }
            );
            parsing[parser_num] = parser;
            reply.parser = parser_num;
            parser_num++;
        } else {
            parser = parsing[data.parser];
            reply.parser = data.parser;
        }
        if (data.chunk) {
            parser.parse(data.chunk, data.finished);
        }
        if (data.finished) {
            reply.finished = true;
            parsing[reply.parser] = undefined;
            postMessage("Document loaded.");
            var event = document.createEvent('event');
            event.initEvent('load', false, true);
            document.dispatchEvent(event);
        }
        postMessage(reply);
    } catch (e) {
        postMessage("ERR " + e);
    }
}

onmessage = function(message) {
    var global = this;
    setTimeout(function() { handle_message.call(global, message) }, 0);
}
<commit_msg>add protocol to window.location<commit_after>
"use strict";

importScripts('../dom.js');

var addEventListener = function(type, cb, bubble) {
    document.addEventListener(type, cb, bubble);
};

var navigator = { userAgent: 'servo 0.1 webworker' }
var location = {href: "http://example.com/foo", search: "", protocol: "http"}
var window = this;

function print() {
    var out = '';
    for (var i = 0; i < arguments.length; i++) {
        out += arguments[i] + ' ';
    }
    postMessage(out);
}

var console = {log: print}

var parser_num = 1;
var parsing = {}

onerror = function(err) {
    return false;
}

function handle_message(message) {
    try {
        var data = message.data;
        var reply = {}
        var parser = null;

        if (data.url) {
            parser = document.implementation.mozHTMLParser(data.url);
            var doc = parser.document();
            // work around for a proxy bug in ff
            Object.defineProperty(this, "document", { value: doc});

            doc.implementation.mozSetOutputMutationHandler(
                doc, function(msg) { postMessage(msg) }
            );
            parsing[parser_num] = parser;
            reply.parser = parser_num;
            parser_num++;
        } else {
            parser = parsing[data.parser];
            reply.parser = data.parser;
        }
        if (data.chunk) {
            parser.parse(data.chunk, data.finished);
        }
        if (data.finished) {
            reply.finished = true;
            parsing[reply.parser] = undefined;
            postMessage("Document loaded.");
            var event = document.createEvent('event');
            event.initEvent('load', false, true);
            document.dispatchEvent(event);
        }
        postMessage(reply);
    } catch (e) {
        postMessage("ERR " + e);
    }
}

onmessage = function(message) {
    var global = this;
    setTimeout(function() { handle_message.call(global, message) }, 0);
}
<|endoftext|>


<commit_before>import Test from 'ember-test';
import run from 'ember-runloop';
import { assert } from 'ember-metal/utils';
import moment from 'moment';
import { find, click } from 'ember-native-dom-helpers';

function findCalendarElement(selector) {
  let target = find(selector);
  if (target) {
    if (target.classList.contains('ember-power-calendar')) {
      return target;
    } else {
      return find('.ember-power-calendar', target) || find('[data-power-calendar-id]', target);
    }
  }
}

function findCalendarGuid(selector) {
  let maybeCalendar = findCalendarElement(selector);
  if (!maybeCalendar) {
    return;
  }
  if (maybeCalendar.classList.contains('ember-power-calendar')) {
    return maybeCalendar.id;
  } else {
    return maybeCalendar.attributes['data-power-calendar-id'].value;
  }
}

function findComponentInstance(app, selector) {
  let calendarGuid = findCalendarGuid(selector);
  assert(`Could not find a calendar using selector: "${selector}"`, calendarGuid);
  let calendarService = app.__container__.lookup('service:power-calendar');
  return calendarService._calendars[calendarGuid];
}

export default function() {
  Test.registerAsyncHelper('calendarCenter', function(app, selector, newCenter) {
    assert('`calendarCenter` expect a Date or MomentJS object as second argument', newCenter);
    let calendarComponent = findComponentInstance(app, selector);
    let onCenterChange = calendarComponent.get('onCenterChange');
    assert('You cannot call `calendarCenter` on a component that doesn\'t has an `onCenterChange` action', !!onCenterChange);
    let newCenterMoment = moment(newCenter);
    return onCenterChange({ date: newCenterMoment._d, moment: newCenterMoment });
  });

  Test.registerAsyncHelper('calendarSelect', function(app, selector, selected) {
    assert('`calendarSelect` expect a Date or MomentJS object as second argument', selected);
    let selectedMoment = moment(selected);
    let calendarElement = findCalendarElement(selector);
    let daySelector = `${selector} [data-date="${selectedMoment.format('YYYY-MM-DD')}"]`;
    let dayElement = find(daySelector, calendarElement);
    if (!dayElement) {
      run(() => calendarCenter(selector, selected));
    }
    andThen(function() {
      click(daySelector);
    });
  });
}
<commit_msg>Acceptance helpers work with async/await<commit_after>import Test from 'ember-test';
import { assert } from 'ember-metal/utils';
import moment from 'moment';
import { find, click } from 'ember-native-dom-helpers';
import wait from 'ember-test-helpers/wait';

function findCalendarElement(selector) {
  let target = find(selector);
  if (target) {
    if (target.classList.contains('ember-power-calendar')) {
      return target;
    } else {
      return find('.ember-power-calendar', target) || find('[data-power-calendar-id]', target);
    }
  }
}

function findCalendarGuid(selector) {
  let maybeCalendar = findCalendarElement(selector);
  if (!maybeCalendar) {
    return;
  }
  if (maybeCalendar.classList.contains('ember-power-calendar')) {
    return maybeCalendar.id;
  } else {
    return maybeCalendar.attributes['data-power-calendar-id'].value;
  }
}

function findComponentInstance(app, selector) {
  let calendarGuid = findCalendarGuid(selector);
  assert(`Could not find a calendar using selector: "${selector}"`, calendarGuid);
  let calendarService = app.__container__.lookup('service:power-calendar');
  return calendarService._calendars[calendarGuid];
}

export default function() {
  Test.registerAsyncHelper('calendarCenter', async function(app, selector, newCenter) {
    assert('`calendarCenter` expect a Date or MomentJS object as second argument', newCenter);
    let calendarComponent = findComponentInstance(app, selector);
    let onCenterChange = calendarComponent.get('onCenterChange');
    assert('You cannot call `calendarCenter` on a component that doesn\'t has an `onCenterChange` action', !!onCenterChange);
    let publicAPI = calendarComponent.get('publicAPI');
    await publicAPI.actions.changeCenter(newCenter, publicAPI);
    return wait();
  });

  Test.registerAsyncHelper('calendarSelect', async function(app, selector, selected) {
    assert('`calendarSelect` expect a Date or MomentJS object as second argument', selected);
    let selectedMoment = moment(selected);
    let calendarElement = findCalendarElement(selector);
    let daySelector = `${selector} [data-date="${selectedMoment.format('YYYY-MM-DD')}"]`;
    let dayElement = find(daySelector, calendarElement);
    if (!dayElement) {
      await calendarCenter(selector, selected);
    }
    return click(daySelector);
  });
}
<|endoftext|>