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

/**
 * External dependencies
 */
import styled from 'styled-components';
/**
 * Internal dependencies
 */
import { Text } from '../../';
import * as Icons from '../';
import * as ActionIcons from '../action';
import * as AlertIcons from '../alert';
import * as AvIcons from '../av';
import * as ContentIcons from '../content';
import * as DashboardIcons from '../dashboard';
import * as EditorIcons from '../editor';
import * as FileIcons from '../file';
import * as NavigationIcons from '../navigation';
import * as SocialIcons from '../social';

export default {
  title: 'DesignSystem/Icons',
};

const IconsList = styled.ul`
  color: ${({ theme }) => theme.colors.fg.primary};
  list-style-type: none;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 20px 10px;

  li {
    display: flex;
    flex-direction: column;
    justify-items: flex-start;
    align-items: center;
  }
  svg {
    height: 40px;
    width: 40px;
    margin-bottom: 10px;
  }
`;

export const AllIcons = () => {
  return (
    <>
      <Text>{`Total Icons: ${Object.values(Icons).length}`}</Text>

      <IconsList>
        {Object.keys(Icons).map((iconName) => {
          // eslint-disable-next-line import/namespace
          const Icon = Icons[iconName];
          return (

              <Icon />
              <Text as="span" isBold>
                {iconName}
              </Text>

          );
        })}
      </IconsList>
    </>
  );
};

export const Action = () => {
  return (
    <IconsList>
      {Object.keys(ActionIcons).map((iconName) => {
        // eslint-disable-next-line import/namespace
        const Icon = ActionIcons[iconName];
        return (

            <Icon />
            <Text as="span" isBold>
              {iconName}
            </Text>

        );
      })}
    </IconsList>
  );
};

export const Alert = () => {
  return (
    <IconsList>
      {Object.keys(AlertIcons).map((iconName) => {
        // eslint-disable-next-line import/namespace
        const Icon = AlertIcons[iconName];
        return (

            <Icon />
            <Text as="span" isBold>
              {iconName}
            </Text>

        );
      })}
    </IconsList>
  );
};

export const Av = () => {
  return (
    <IconsList>
      {Object.keys(AvIcons).map((iconName) => {
        // eslint-disable-next-line import/namespace
        const Icon = AvIcons[iconName];
        return (

            <Icon />
            <Text as="span" isBold>
              {iconName}
            </Text>

        );
      })}
    </IconsList>
  );
};

export const Content = () => {
  return (
    <IconsList>
      {Object.keys(ContentIcons).map((iconName) => {
        // eslint-disable-next-line import/namespace
        const Icon = ContentIcons[iconName];
        return (

            <Icon />
            <Text as="span" isBold>
              {iconName}
            </Text>

        );
      })}
    </IconsList>
  );
};

export const Dashboard = () => {
  return (
    <IconsList>
      {Object.keys(DashboardIcons).map((iconName) => {
        // eslint-disable-next-line import/namespace
        const Icon = DashboardIcons[iconName];
        return (

            <Icon />
            <Text as="span" isBold>
              {iconName}
            </Text>

        );
      })}
    </IconsList>
  );
};

export const Editor = () => {
  return (
    <IconsList>
      {Object.keys(EditorIcons).map((iconName) => {
        // eslint-disable-next-line import/namespace
        const Icon = EditorIcons[iconName];
        return (

            <Icon />
            <Text as="span" isBold>
              {iconName}
            </Text>

        );
      })}
    </IconsList>
  );
};

export const File = () => {
  return (
    <IconsList>
      {Object.keys(FileIcons).map((iconName) => {
        // eslint-disable-next-line import/namespace
        const Icon = FileIcons[iconName];
        return (

            <Icon />
            <Text as="span" isBold>
              {iconName}
            </Text>

        );
      })}
    </IconsList>
  );
};

export const Navigation = () => {
  return (
    <IconsList>
      {Object.keys(NavigationIcons).map((iconName) => {
        // eslint-disable-next-line import/namespace
        const Icon = NavigationIcons[iconName];
        return (

            <Icon />
            <Text as="span" isBold>
              {iconName}
            </Text>

        );
      })}
    </IconsList>
  );
};

export const Social = () => {
  return (
    <IconsList>
      {Object.keys(SocialIcons).map((iconName) => {
        // eslint-disable-next-line import/namespace
        const Icon = SocialIcons[iconName];
        return (

            <Icon />
            <Text as="span" isBold>
              {iconName}
            </Text>

        );
      })}
    </IconsList>
  );
};

export const Action = () => {
  return (
    <IconsList>
      {Object.keys(ActionIcons).map((iconName) => {
        // eslint-disable-next-line import/namespace
        const Icon = ActionIcons[iconName];
        return (

            <Icon />
            <Text as="span" isBold>
              {iconName}
            </Text>

        );
      })}
    </IconsList>
  );
};

export const Alert = () => {
  return (
    <IconsList>
      {Object.keys(AlertIcons).map((iconName) => {
        // eslint-disable-next-line import/namespace
        const Icon = AlertIcons[iconName];
        return (

            <Icon />
            <Text as="span" isBold>
              {iconName}
            </Text>

        );
      })}
    </IconsList>
  );
};

export const Av = () => {
  return (
    <IconsList>
      {Object.keys(AvIcons).map((iconName) => {
        // eslint-disable-next-line import/namespace
        const Icon = AvIcons[iconName];
        return (

            <Icon />
            <Text as="span" isBold>
              {iconName}
            </Text>

        );
      })}
    </IconsList>
  );
};

export const Content = () => {
  return (
    <IconsList>
      {Object.keys(ContentIcons).map((iconName) => {
        // eslint-disable-next-line import/namespace
        const Icon = ContentIcons[iconName];
        return (

            <Icon />
            <Text as="span" isBold>
              {iconName}
            </Text>

        );
      })}
    </IconsList>
  );
};

export const Editor = () => {
  return (
    <IconsList>
      {Object.keys(EditorIcons).map((iconName) => {
        // eslint-disable-next-line import/namespace
        const Icon = EditorIcons[iconName];
        return (

            <Icon />
            <Text as="span" isBold>
              {iconName}
            </Text>

        );
      })}
    </IconsList>
  );
};

export const Dashboard = () => {
  return (
    <IconsList>
      {Object.keys(DashboardIcons).map((iconName) => {
        // eslint-disable-next-line import/namespace
        const Icon = DashboardIcons[iconName];
        return (

            <Icon />
            <Text as="span" isBold>
              {iconName}
            </Text>

        );
      })}
    </IconsList>
  );
};

export const File = () => {
  return (
    <IconsList>
      {Object.keys(FileIcons).map((iconName) => {
        // eslint-disable-next-line import/namespace
        const Icon = FileIcons[iconName];
        return (

            <Icon />
            <Text as="span" isBold>
              {iconName}
            </Text>

        );
      })}
    </IconsList>
  );
};

export const Navigation = () => {
  return (
    <IconsList>
      {Object.keys(NavigationIcons).map((iconName) => {
        // eslint-disable-next-line import/namespace
        const Icon = NavigationIcons[iconName];
        return (

            <Icon />
            <Text as="span" isBold>
              {iconName}
            </Text>

        );
      })}
    </IconsList>
  );
};

export const Social = () => {
  return (
    <IconsList>
      {Object.keys(SocialIcons).map((iconName) => {
        // eslint-disable-next-line import/namespace
        const Icon = SocialIcons[iconName];
        return (

            <Icon />
            <Text as="span" isBold>
              {iconName}
            </Text>

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

/**
 * External dependencies
 */
import styled from 'styled-components';
/**
 * Internal dependencies
 */
import { Text } from '../../';
import * as Icons from '../';
import * as ActionIcons from '../action';
import * as AlertIcons from '../alert';
import * as AvIcons from '../av';
import * as ContentIcons from '../content';
import * as DashboardIcons from '../dashboard';
import * as EditorIcons from '../editor';
import * as FileIcons from '../file';
import * as NavigationIcons from '../navigation';
import * as SocialIcons from '../social';

export default {
  title: 'DesignSystem/Icons',
};

const IconsList = styled.ul`
  color: ${({ theme }) => theme.colors.fg.primary};
  list-style-type: none;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 20px 10px;

  li {
    display: flex;
    flex-direction: column;
    justify-items: flex-start;
    align-items: center;
  }
  svg {
    height: 40px;
    width: 40px;
    margin-bottom: 10px;
  }
`;

export const AllIcons = () => {
  return (
    <>
      <Text>{`Total Icons: ${Object.values(Icons).length}`}</Text>

      <IconsList>
        {Object.keys(Icons).map((iconName) => {
          // eslint-disable-next-line import/namespace
          const Icon = Icons[iconName];
          return (

              <Icon />
              <Text as="span" isBold>
                {iconName}
              </Text>

          );
        })}
      </IconsList>
    </>
  );
};

export const Action = () => {
  return (
    <IconsList>
      {Object.keys(ActionIcons).map((iconName) => {
        // eslint-disable-next-line import/namespace
        const Icon = ActionIcons[iconName];
        return (

            <Icon />
            <Text as="span" isBold>
              {iconName}
            </Text>

        );
      })}
    </IconsList>
  );
};

export const Alert = () => {
  return (
    <IconsList>
      {Object.keys(AlertIcons).map((iconName) => {
        // eslint-disable-next-line import/namespace
        const Icon = AlertIcons[iconName];
        return (

            <Icon />
            <Text as="span" isBold>
              {iconName}
            </Text>

        );
      })}
    </IconsList>
  );
};

export const Av = () => {
  return (
    <IconsList>
      {Object.keys(AvIcons).map((iconName) => {
        // eslint-disable-next-line import/namespace
        const Icon = AvIcons[iconName];
        return (

            <Icon />
            <Text as="span" isBold>
              {iconName}
            </Text>

        );
      })}
    </IconsList>
  );
};

export const Content = () => {
  return (
    <IconsList>
      {Object.keys(ContentIcons).map((iconName) => {
        // eslint-disable-next-line import/namespace
        const Icon = ContentIcons[iconName];
        return (

            <Icon />
            <Text as="span" isBold>
              {iconName}
            </Text>

        );
      })}
    </IconsList>
  );
};

export const Dashboard = () => {
  return (
    <IconsList>
      {Object.keys(DashboardIcons).map((iconName) => {
        // eslint-disable-next-line import/namespace
        const Icon = DashboardIcons[iconName];
        return (

            <Icon />
            <Text as="span" isBold>
              {iconName}
            </Text>

        );
      })}
    </IconsList>
  );
};

export const Editor = () => {
  return (
    <IconsList>
      {Object.keys(EditorIcons).map((iconName) => {
        // eslint-disable-next-line import/namespace
        const Icon = EditorIcons[iconName];
        return (

            <Icon />
            <Text as="span" isBold>
              {iconName}
            </Text>

        );
      })}
    </IconsList>
  );
};

export const File = () => {
  return (
    <IconsList>
      {Object.keys(FileIcons).map((iconName) => {
        // eslint-disable-next-line import/namespace
        const Icon = FileIcons[iconName];
        return (

            <Icon />
            <Text as="span" isBold>
              {iconName}
            </Text>

        );
      })}
    </IconsList>
  );
};

export const Navigation = () => {
  return (
    <IconsList>
      {Object.keys(NavigationIcons).map((iconName) => {
        // eslint-disable-next-line import/namespace
        const Icon = NavigationIcons[iconName];
        return (

            <Icon />
            <Text as="span" isBold>
              {iconName}
            </Text>

        );
      })}
    </IconsList>
  );
};

export const Social = () => {
  return (
    <IconsList>
      {Object.keys(SocialIcons).map((iconName) => {
        // eslint-disable-next-line import/namespace
        const Icon = SocialIcons[iconName];
        return (

            <Icon />
            <Text as="span" isBold>
              {iconName}
            </Text>

        );
      })}
    </IconsList>
  );
};

export const Action = () => {
  return (
    <IconsList>
      {Object.keys(ActionIcons).map((iconName) => {
        // eslint-disable-next-line import/namespace
        const Icon = ActionIcons[iconName];
        return (

            <Icon />
            <Text as="span" isBold>
              {iconName}
            </Text>

        );
      })}
    </IconsList>
  );
};

export const Alert = () => {
  return (
    <IconsList>
      {Object.keys(AlertIcons).map((iconName) => {
        // eslint-disable-next-line import/namespace
        const Icon = AlertIcons[iconName];
        return (

            <Icon />
            <Text as="span" isBold>
              {iconName}
            </Text>

        );
      })}
    </IconsList>
  );
};

export const Av = () => {
  return (
    <IconsList>
      {Object.keys(AvIcons).map((iconName) => {
        // eslint-disable-next-line import/namespace
        const Icon = AvIcons[iconName];
        return (

            <Icon />
            <Text as="span" isBold>
              {iconName}
            </Text>

        );
      })}
    </IconsList>
  );
};

export const Content = () => {
  return (
    <IconsList>
      {Object.keys(ContentIcons).map((iconName) => {
        // eslint-disable-next-line import/namespace
        const Icon = ContentIcons[iconName];
        return (

            <Icon />
            <Text as="span" isBold>
              {iconName}
            </Text>

        );
      })}
    </IconsList>
  );
};

export const Editor = () => {
  return (
    <IconsList>
      {Object.keys(DashboardIcons).map((iconName) => {
        // eslint-disable-next-line import/namespace
        const Icon = DashboardIcons[iconName];
        return (

            <Icon />
            <Text as="span" isBold>
              {iconName}
            </Text>

        );
      })}
    </IconsList>
  );
};

export const Editor = () => {
  return (
    <IconsList>
      {Object.keys(EditorIcons).map((iconName) => {
        // eslint-disable-next-line import/namespace
        const Icon = EditorIcons[iconName];
        return (

            <Icon />
            <Text as="span" isBold>
              {iconName}
            </Text>

        );
      })}
    </IconsList>
  );
};

export const File = () => {
  return (
    <IconsList>
      {Object.keys(FileIcons).map((iconName) => {
        // eslint-disable-next-line import/namespace
        const Icon = FileIcons[iconName];
        return (

            <Icon />
            <Text as="span" isBold>
              {iconName}
            </Text>

        );
      })}
    </IconsList>
  );
};

export const Navigation = () => {
  return (
    <IconsList>
      {Object.keys(NavigationIcons).map((iconName) => {
        // eslint-disable-next-line import/namespace
        const Icon = NavigationIcons[iconName];
        return (

            <Icon />
            <Text as="span" isBold>
              {iconName}
            </Text>

        );
      })}
    </IconsList>
  );
};

export const Social = () => {
  return (
    <IconsList>
      {Object.keys(SocialIcons).map((iconName) => {
        // eslint-disable-next-line import/namespace
        const Icon = SocialIcons[iconName];
        return (

            <Icon />
            <Text as="span" isBold>
              {iconName}
            </Text>

        );
      })}
    </IconsList>
  );
};
<|endoftext|>


<commit_before>/**
 * ngTable: Table + Angular JS
 *
 * @author Vitalii Savchuk <esvit666@gmail.com>
 * @url https://github.com/esvit/ng-table/
 * @license New BSD License <http://creativecommons.org/licenses/BSD/>
 */

/**
 * @ngdoc directive
 * @name ngTable.directive:ngTable
 * @restrict A
 *
 * @description
 * Directive that instantiates {@link ngTable.directive:ngTable.ngTableController ngTableController}.
 */
app.directive('ngTable', ['$compile', '$q', '$parse',
    function ($compile, $q, $parse) {
        'use strict';

        return {
            restrict: 'A',
            priority: 1001,
            scope: true,
            controller: ngTableController,
            compile: function (element) {
                var columns = [], i = 0, row = null;

                // custom header
                var thead = element.find('thead');

                // IE 8 fix :not(.ng-table-group) selector
                angular.forEach(angular.element(element.find('tr')), function (tr) {
                    tr = angular.element(tr);
                    if (!tr.hasClass('ng-table-group') && !row) {
                        row = tr;
                    }
                });
                if (!row) {
                    return;
                }
                angular.forEach(row.find('td'), function (item) {
                    var el = angular.element(item);
                    if (el.attr('ignore-cell') && 'true' === el.attr('ignore-cell')) {
                        return;
                    }
                    var parsedAttribute = function (attr, defaultValue) {
                        return function (scope) {
                            return $parse(el.attr('x-data-' + attr) || el.attr('data-' + attr) || el.attr(attr))(scope, {
                                $columns: columns
                            }) || defaultValue;
                        };
                    };

                    var parsedTitle = parsedAttribute('title', ' '),
                        headerTemplateURL = parsedAttribute('header', false),
                        filter = parsedAttribute('filter', false)(),
                        filterTemplateURL = false,
                        filterName = false;

                    if (filter && filter.$$name) {
                        filterName = filter.$$name;
                        delete filter.$$name;
                    }
                    if (filter && filter.templateURL) {
                        filterTemplateURL = filter.templateURL;
                        delete filter.templateURL;
                    }

                    el.attr('data-title-text', parsedTitle()); // this used in responsive table
                    columns.push({
                        id: i++,
                        title: parsedTitle,
                        sortable: parsedAttribute('sortable', false),
                        'class': el.attr('x-data-header-class') || el.attr('data-header-class') || el.attr('header-class'),
                        filter: filter,
                        filterTemplateURL: filterTemplateURL,
                        filterName: filterName,
                        headerTemplateURL: headerTemplateURL,
                        filterData: (el.attr("filter-data") ? el.attr("filter-data") : null),
                        show: (el.attr("ng-show") ? function (scope) {
                            return $parse(el.attr("ng-show"))(scope);
                        } : function () {
                            return true;
                        })
                    });
                });
                return function (scope, element, attrs) {
                    scope.$loading = false;
                    scope.$columns = columns;

                    scope.$watch(attrs.ngTable, (function (params) {
                        if (angular.isUndefined(params)) {
                            return;
                        }
                        scope.paramsModel = $parse(attrs.ngTable);
                        scope.params = params;
                    }), true);
                    scope.parse = function (text) {
                        return angular.isDefined(text) ? text(scope) : '';
                    };
                    if (attrs.showFilter) {
                        scope.$parent.$watch(attrs.showFilter, function (value) {
                            scope.show_filter = value;
                        });
                    }
                    angular.forEach(columns, function (column) {
                        var def;
                        if (!column.filterData) {
                            return;
                        }
                        def = $parse(column.filterData)(scope, {
                            $column: column
                        });
                        if (!(angular.isObject(def) && angular.isObject(def.promise))) {
                            throw new Error('Function ' + column.filterData + ' must be instance of $q.defer()');
                        }
                        delete column.filterData;
                        return def.promise.then(function (data) {
                            if (!angular.isArray(data)) {
                                data = [];
                            }
                            data.unshift({
                                title: '-',
                                id: ''
                            });
                            column.data = data;
                        });
                    });
                    if (!element.hasClass('ng-table')) {
                        scope.templates = {
                            header: (attrs.templateHeader ? attrs.templateHeader : 'ng-table/header.html'),
                            pagination: (attrs.templatePagination ? attrs.templatePagination : 'ng-table/pager.html')
                        };
                        var headerTemplate = thead.length > 0 ? thead : angular.element(document.createElement('thead')).attr('ng-include', 'templates.header');
                        var paginationTemplate = angular.element(document.createElement('div')).attr({
                            'ng-table-pagination': 'params',
                            'template-url': 'templates.pagination'
                        });

                        element.find('thead').remove();

                        element.addClass('ng-table')
                            .prepend(headerTemplate)
                            .after(paginationTemplate);

                        $compile(headerTemplate)(scope);
                        $compile(paginationTemplate)(scope);
                    }
                };
            }
        }
    }
]);
<commit_msg>Compile thead only when it's necessary<commit_after>/**
 * ngTable: Table + Angular JS
 *
 * @author Vitalii Savchuk <esvit666@gmail.com>
 * @url https://github.com/esvit/ng-table/
 * @license New BSD License <http://creativecommons.org/licenses/BSD/>
 */

/**
 * @ngdoc directive
 * @name ngTable.directive:ngTable
 * @restrict A
 *
 * @description
 * Directive that instantiates {@link ngTable.directive:ngTable.ngTableController ngTableController}.
 */
app.directive('ngTable', ['$compile', '$q', '$parse',
    function ($compile, $q, $parse) {
        'use strict';

        return {
            restrict: 'A',
            priority: 1001,
            scope: true,
            controller: ngTableController,
            compile: function (element) {
                var columns = [], i = 0, row = null;

                // custom header
                var thead = element.find('thead');

                // IE 8 fix :not(.ng-table-group) selector
                angular.forEach(angular.element(element.find('tr')), function (tr) {
                    tr = angular.element(tr);
                    if (!tr.hasClass('ng-table-group') && !row) {
                        row = tr;
                    }
                });
                if (!row) {
                    return;
                }
                angular.forEach(row.find('td'), function (item) {
                    var el = angular.element(item);
                    if (el.attr('ignore-cell') && 'true' === el.attr('ignore-cell')) {
                        return;
                    }
                    var parsedAttribute = function (attr, defaultValue) {
                        return function (scope) {
                            return $parse(el.attr('x-data-' + attr) || el.attr('data-' + attr) || el.attr(attr))(scope, {
                                $columns: columns
                            }) || defaultValue;
                        };
                    };

                    var parsedTitle = parsedAttribute('title', ' '),
                        headerTemplateURL = parsedAttribute('header', false),
                        filter = parsedAttribute('filter', false)(),
                        filterTemplateURL = false,
                        filterName = false;

                    if (filter && filter.$$name) {
                        filterName = filter.$$name;
                        delete filter.$$name;
                    }
                    if (filter && filter.templateURL) {
                        filterTemplateURL = filter.templateURL;
                        delete filter.templateURL;
                    }

                    el.attr('data-title-text', parsedTitle()); // this used in responsive table
                    columns.push({
                        id: i++,
                        title: parsedTitle,
                        sortable: parsedAttribute('sortable', false),
                        'class': el.attr('x-data-header-class') || el.attr('data-header-class') || el.attr('header-class'),
                        filter: filter,
                        filterTemplateURL: filterTemplateURL,
                        filterName: filterName,
                        headerTemplateURL: headerTemplateURL,
                        filterData: (el.attr("filter-data") ? el.attr("filter-data") : null),
                        show: (el.attr("ng-show") ? function (scope) {
                            return $parse(el.attr("ng-show"))(scope);
                        } : function () {
                            return true;
                        })
                    });
                });
                return function (scope, element, attrs) {
                    scope.$loading = false;
                    scope.$columns = columns;

                    scope.$watch(attrs.ngTable, (function (params) {
                        if (angular.isUndefined(params)) {
                            return;
                        }
                        scope.paramsModel = $parse(attrs.ngTable);
                        scope.params = params;
                    }), true);
                    scope.parse = function (text) {
                        return angular.isDefined(text) ? text(scope) : '';
                    };
                    if (attrs.showFilter) {
                        scope.$parent.$watch(attrs.showFilter, function (value) {
                            scope.show_filter = value;
                        });
                    }
                    angular.forEach(columns, function (column) {
                        var def;
                        if (!column.filterData) {
                            return;
                        }
                        def = $parse(column.filterData)(scope, {
                            $column: column
                        });
                        if (!(angular.isObject(def) && angular.isObject(def.promise))) {
                            throw new Error('Function ' + column.filterData + ' must be instance of $q.defer()');
                        }
                        delete column.filterData;
                        return def.promise.then(function (data) {
                            if (!angular.isArray(data)) {
                                data = [];
                            }
                            data.unshift({
                                title: '-',
                                id: ''
                            });
                            column.data = data;
                        });
                    });
                    if (!element.hasClass('ng-table')) {
                        scope.templates = {
                            header: (attrs.templateHeader ? attrs.templateHeader : 'ng-table/header.html'),
                            pagination: (attrs.templatePagination ? attrs.templatePagination : 'ng-table/pager.html')
                        };

                        var headerTemplate = null;
                        var headerNeedComile = false;
                        if (thead.length > 0) {
                            headerTemplate = thead;
                        } else {
                            headerTemplate = angular.element(document.createElement('thead')).attr('ng-include', 'templates.header');
                            headerNeedComile = true;
                        }

                        var paginationTemplate = angular.element(document.createElement('div')).attr({
                            'ng-table-pagination': 'params',
                            'template-url': 'templates.pagination'
                        });

                        element.find('thead').remove();
                        element.addClass('ng-table')
                            .prepend(headerTemplate)
                            .after(paginationTemplate);

                        if (headerNeedComile) {
                            $compile(headerTemplate)(scope);
                        }
                        $compile(paginationTemplate)(scope);
                    }
                };
            }
        }
    }
]);
<|endoftext|>


<commit_before>import S3 from 'aws-sdk/clients/s3'
import * as React from 'react'
import * as reduxHook from 'redux-react-hook'

import * as Auth from 'containers/Auth'
import { useConfig } from 'utils/Config'
import * as RT from 'utils/reactTools'
import useMemoEq from 'utils/useMemoEq'

import * as Config from './Config'
import * as Credentials from './Credentials'

const DEFAULT_OPTS = {
  signatureVersion: 'v4',
}

const Ctx = React.createContext(DEFAULT_OPTS)

export const Provider = RT.composeComponent(
  'AWS.S3.Provider',
  ({ children, ...props }) => {
    const prev = React.useContext(Ctx)
    const value = { ...prev, ...props }
    return <Ctx.Provider value={value}>{children}</Ctx.Provider>
  },
)

export const useS3 = (extra) => {
  const config = Config.use()
  Credentials.use().suspend()
  const props = React.useContext(Ctx)
  // TODO: use cache?
  return useMemoEq({ ...config, ...props, ...extra }, (cfg) => new S3(cfg))
}

export const use = useS3

export const useRequest = (extra) => {
  const cfg = useConfig()
  const regularClient = useS3(extra)
  const proxyingClient = useS3({
    endpoint: cfg.s3Proxy,
    s3ForcePathStyle: true,
    ...extra,
  })
  const s3SelectClient = useS3({
    endpoint: `${cfg.apiGatewayEndpoint}/s3select/`,
    s3ForcePathStyle: true,
    ...extra,
  })
  const authenticated = reduxHook.useMappedState(Auth.selectors.authenticated)
  return React.useMemo(
    () => ({ bucket, operation, params }) => {
      let client
      if (!authenticated && operation === 'selectObjectContent') {
        client = s3SelectClient
      } else if (cfg.shouldProxy(bucket)) {
        client = proxyingClient
      } else {
        client = regularClient
      }
      const method =
        authenticated && cfg.shouldSign(bucket)
          ? 'makeRequest'
          : 'makeUnauthenticatedRequest'
      return client[method](operation, params).promise()
    },
    [regularClient, proxyingClient, authenticated, cfg],
  )
}

export const inject = (prop = 's3') =>
  RT.composeHOC('AWS.S3.inject', (Component) => (props) => {
    const s3 = use()
    return <Component {...{ [prop]: s3, ...props }} />
  })

export const injectRequest = (prop = 's3req') =>
  RT.composeHOC('AWS.S3.inject', (Component) => (props) => {
    const s3req = useRequest()
    return <Component {...{ [prop]: s3req, ...props }} />
  })

export const Inject = ({ children }) => children(use())

export const InjectRequest = ({ children }) => children(useRequest())
<commit_msg>Use the binary API gateway for S3 select (#1150)<commit_after>import S3 from 'aws-sdk/clients/s3'
import * as React from 'react'
import * as reduxHook from 'redux-react-hook'

import * as Auth from 'containers/Auth'
import { useConfig } from 'utils/Config'
import * as RT from 'utils/reactTools'
import useMemoEq from 'utils/useMemoEq'

import * as Config from './Config'
import * as Credentials from './Credentials'

const DEFAULT_OPTS = {
  signatureVersion: 'v4',
}

const Ctx = React.createContext(DEFAULT_OPTS)

export const Provider = RT.composeComponent(
  'AWS.S3.Provider',
  ({ children, ...props }) => {
    const prev = React.useContext(Ctx)
    const value = { ...prev, ...props }
    return <Ctx.Provider value={value}>{children}</Ctx.Provider>
  },
)

export const useS3 = (extra) => {
  const config = Config.use()
  Credentials.use().suspend()
  const props = React.useContext(Ctx)
  // TODO: use cache?
  return useMemoEq({ ...config, ...props, ...extra }, (cfg) => new S3(cfg))
}

export const use = useS3

export const useRequest = (extra) => {
  const cfg = useConfig()
  const regularClient = useS3(extra)
  const proxyingClient = useS3({
    endpoint: cfg.s3Proxy,
    s3ForcePathStyle: true,
    ...extra,
  })
  const s3SelectClient = useS3({
    endpoint: `${cfg.binaryApiGatewayEndpoint}/s3select/`,
    s3ForcePathStyle: true,
    ...extra,
  })
  const authenticated = reduxHook.useMappedState(Auth.selectors.authenticated)
  return React.useMemo(
    () => ({ bucket, operation, params }) => {
      let client
      if (!authenticated && operation === 'selectObjectContent') {
        client = s3SelectClient
      } else if (cfg.shouldProxy(bucket)) {
        client = proxyingClient
      } else {
        client = regularClient
      }
      const method =
        authenticated && cfg.shouldSign(bucket)
          ? 'makeRequest'
          : 'makeUnauthenticatedRequest'
      return client[method](operation, params).promise()
    },
    [regularClient, proxyingClient, authenticated, cfg],
  )
}

export const inject = (prop = 's3') =>
  RT.composeHOC('AWS.S3.inject', (Component) => (props) => {
    const s3 = use()
    return <Component {...{ [prop]: s3, ...props }} />
  })

export const injectRequest = (prop = 's3req') =>
  RT.composeHOC('AWS.S3.inject', (Component) => (props) => {
    const s3req = useRequest()
    return <Component {...{ [prop]: s3req, ...props }} />
  })

export const Inject = ({ children }) => children(use())

export const InjectRequest = ({ children }) => children(useRequest())
<|endoftext|>


<commit_before>/*
 * Copyright 2011 Adobe Systems Incorporated. All Rights Reserved.
 */

/*jslint vars: true, plusplus: true, devel: true, browser: true, nomen: true, indent: 4, maxerr: 50 */
/*global define, $ */

/*
* Displays an auto suggest popup list of files to allow the user to quickly navigate to a file and lines
* within a file.
* Uses FileIndexManger to supply the file list.
*
* TODO (issue 333) - currently jquery smart auto complete is used for the popup list. While it mostly works
* it has several issues, so it should be replace with an alternative. Issues:
* - only accepts an array of strings. A list of objects is preferred to avoid some work arounds to display
*   both the path and filename.
* - the popup position logic has flaws that require css work-arounds
* - the popup properties cannot be modified once the object is constructed
*/

define(function (require, exports, module) {
    'use strict';

    var FileIndexManager    = require("project/FileIndexManager"),
        JSLintUtils         = require("language/JSLintUtils"),
        DocumentManager     = require("document/DocumentManager"),
        EditorManager       = require("editor/EditorManager"),
        CommandManager      = require("command/CommandManager"),
        Commands            = require("command/Commands"),
        QuickOpenJSSymbol   = require("search/QuickOpenJavaScript"),
        QuickOpenCSS        = require("search/QuickOpenCSS"),
        QuickOpenHTML       = require("search/QuickOpenHTML"),
        ProjectManager      = require("project/ProjectManager");

    /** @type Array.<QuickOpenPlugin> */
    var plugins = [];

    /** @type {QuickOpenPlugin} */
    var currentPlugin = null;
    var fileList;

    /**
     * Rembers the current document that was displayed when showDialog() was called
     * The current document is restored if the user presses escape
     * @type {string} fullpath
     */
    var origDocPath;

    /**
     * Rembers the current cursor location that was present when showDialog() was called
     * The cursor position s restored if the user presses escape
     * @type ?{start:{line:number, ch:number}, end:{line:number, ch:number}}
     */
    var origSelection;

    var dialogOpen = false;

    /**
     * Defines API for new QuickOpen plguins
     * @param {string} plugin name
     * @param {Array.<string>} filetypes array. Example: ["js", "css", "txt"]
     * @param {Function} filter takes a query string and returns an array of strings that match the query
     * @param {?Functon} match takes a query string and returns true if this plugin wants to provide results for this query
     * @param {Functon} itemFocus performs an action when a result has focus
     * @param {Functon} itemSelect performs an action when a result is choosen
     * @param {?Functon} resultFormatter takes a query string and an item string and returns a
 item to insert into the displayed search resuklts
     */
    function QuickOpenPlugin(name, fileTypes, filter, match, itemFocus, itemSelect, resultsFormatter) {

        this.name = name;
        this.fileTypes = fileTypes; // empty array indicates all
        this.filter = filter;
        this.match = match;
        this.itemFocus = itemFocus;
        this.itemSelect = itemSelect;
        this.resultsFormatter = resultsFormatter;
    }

    /**
     * Registers new QuickOpenPlugin
     * @param {QuickOpenPlugin} plugin
     */
    function addQuickOpenPlugin(plugin) {
        plugins.push(new QuickOpenPlugin(
            plugin.name,
            plugin.fileTypes,
            plugin.filter,
            plugin.match,
            plugin.itemFocus,
            plugin.itemSelect,
            plugin.resultsFormatter
        ));
    }

    /**
    * QuickNavigateDialog class
    * @constructor
    */
    function QuickNavigateDialog() {
        this.searchField = undefined; // defined when showDialog() is called
    }

    /**
     * Creates a dialog div floating on top of the current code mirror editor
     */
    QuickNavigateDialog.prototype._createDialogDiv = function (template) {
        var wrap = $("#editorHolder")[0];
        this.dialog = wrap.insertBefore(document.createElement("div"), wrap.firstChild);
        this.dialog.className = "CodeMirror-dialog";
        this.dialog.innerHTML = '
' + template + '
';
    };

    function _filenameFromPath(path, includeExtension) {
        var end;
        if (includeExtension) {
            end = path.length;
        } else {
            end = path.lastIndexOf(".");
        }
        return path.slice(path.lastIndexOf("/") + 1, end);
    }

    function extractLineNumber(query) {
        var result;
        var regInfo = query.match(/(!?:)(\d+)/); // colon followed by a digit
        if (regInfo) {
            result = regInfo[2] - 1;
        }

        return result;
    }

    /**
     * Closes the search dialog and resolves the promise that showDialog returned
     */
    QuickNavigateDialog.prototype._handleItemSelect = function (selectedItem) {
        if (currentPlugin) {
            currentPlugin.itemSelect(selectedItem);
        } else {
            var query = this.searchField.val();
            var fullPath = $(selectedItem).attr("data-fullpath");

            // extract line number
            var cursor;
            var gotoLine = extractLineNumber(query);
            if (gotoLine) {
                cursor = {line: gotoLine, ch: 0};
            }

            // Do navigation
            if (fullPath) {
                CommandManager.execute(Commands.FILE_ADD_TO_WORKING_SET, {fullPath: fullPath})
                    .done(function () {
                        if (gotoLine) {
                            EditorManager.getCurrentFullEditor().setCursorPos(cursor);
                        }
                    });
            } else if (gotoLine) {
                EditorManager.getCurrentFullEditor().setCursorPos(cursor);
            }
        }

        this._close();
        EditorManager.focusEditor();
    };

    /**
     * Opens the file specified by selected item if there is no current plugin, otherwise defers handling
     * to the currentPlugin
     */
    QuickNavigateDialog.prototype._handleItemFocus = function (selectedItem) {
        if (currentPlugin) {
            currentPlugin.itemFocus(selectedItem);
        } else {
            var fullPath = $(selectedItem).attr("data-fullpath");
            if (fullPath) {
                fullPath = decodeURIComponent(fullPath);
                CommandManager.execute(Commands.FILE_OPEN, {fullPath: fullPath, focusEditor: false});
            }
        }
    };

    QuickNavigateDialog.prototype._handleKeyIn = function (e, query) {
        // extract line number
        var gotoLine = extractLineNumber(query);
        if (gotoLine) {
            var from = {line: gotoLine, ch: 0};
            var to = {line: gotoLine, ch: 99999};

            EditorManager.getCurrentFullEditor().setSelection(from, to);
        }

        // Remove current plugin if the query stops matching
        if (currentPlugin && !currentPlugin.match(query)) {
            currentPlugin = null;
        }

        if ($(".smart_autocomplete_highlight").length === 0) {
            this._handleItemFocus($(".smart_autocomplete_container > li:first-child"));
        }
    };

    /**
     * Close the dialog when the ENTER (13) or ESC (27) key is pressed
     */
    QuickNavigateDialog.prototype._handleKeyDown = function (e) {
        if (e.keyCode === 13 || e.keyCode === 27) {
            e.stopPropagation();
            e.preventDefault();

            // clear the query on ESC key and restore document and cursor poisition
            if (e.keyCode === 27) {

                // restore document and cursor position
                if (origDocPath) {
                    CommandManager.execute(Commands.FILE_OPEN, {fullPath: origDocPath})
                        .done(function () {
                            EditorManager.getCurrentFullEditor().setSelection(origSelection.start, origSelection.end);
                        });
                }
            } else if (e.keyCode === 13) {
                // Select current item on ENTER key
                this._handleItemSelect();
            }

            this._close();
        }
    };

    /**
    * Closes the search dialog and resolves the promise that showDialog returned
    */
    QuickNavigateDialog.prototype._close = function (value) {

        if (!dialogOpen) {
            return;
        }
        dialogOpen = false;

        JSLintUtils.setEnabled(true);

        // for some odd reason I need to remove the dialog like this through the parent
        // If I do it more directly listeners are not removed by the smart auto complete plugin
        this.dialog.parentNode.removeChild(this.dialog);
        $(".smart_autocomplete_container").remove();

        var editor = EditorManager.getCurrentFullEditor();
        editor.focus();
        editor.getCurrentFullEditor().setSelection(origSelection.start, origSelection.end);
    };

    function filterFileList(query) {
        var filteredList = $.map(fileList, function (itemInfo) {
            // match query against filename only (not the full path)
            var path = itemInfo.fullPath;
            var filename = _filenameFromPath(path, true);
            if (filename.toLowerCase().indexOf(query.toLowerCase()) !== -1) {
                return path;
            } else {
                return null;
            }
        }).sort(function (a, b) {
            a = a.toLowerCase();
            b = b.toLowerCase();
            //first,  sort by filename without extension
            var filenameA = _filenameFromPath(a, false);
            var filenameB = _filenameFromPath(b, false);
            if (filenameA < filenameB) {
                return -1;
            } else if (filenameA > filenameB) {
                return 1;
            } else {
                // filename is the same, compare including extension
                filenameA = _filenameFromPath(a, true);
                filenameB = _filenameFromPath(b, true);
                if (filenameA < filenameB) {
                    return -1;
                } else if (filenameA > filenameB) {
                    return 1;
                } else {
                    return 0;
                }
            }
        });

        return filteredList;
    }

    function _handleFilter(query) {
        var curDoc = DocumentManager.getCurrentDocument();
        if (curDoc) {
            var filename = _filenameFromPath(curDoc.file.fullPath, true);
            var extension = filename.slice(filename.lastIndexOf(".") + 1, filename.length);

            var i;
            for (i = 0; i < plugins.length; i++) {
                var plugin = plugins[i];
                var extensionMatch = plugin.fileTypes.indexOf(extension) !== -1 || plugin.fileTypes.length === 0;
                if (extensionMatch &&  plugin.match && plugin.match(query)) {
                    currentPlugin = plugin;
                    return plugin.filter(query);
                }
            }
        }

        currentPlugin = null;
        return filterFileList(query);
    }

    function defaultResultsFormatter(item, query) {
        query = query.slice(query.indexOf("@") + 1, query.length);
        var boldName = item.replace(new RegExp(query, "gi"), "$&");
        return "
" + boldName + "
";
    }

    function _handleResultsFormatter(item) {
        var query = $('input#quickFileOpenSearch').val();

        if (currentPlugin) {
            var formatter = currentPlugin.resultsFormatter || defaultResultsFormatter;
            return formatter(item, query);
        } else {
            // Format filename result
            var filename = _filenameFromPath(item, true);
            var rPath = ProjectManager.makeProjectRelativeIfPossible(item);
            var boldName = filename.replace(new RegExp(query, "gi"), "$&");
            return "
" + boldName +
                "
" + rPath + "
";
        }
    }

    function setCaretPosition(elem, caretPos) {
        if(elem != null) {
            if(elem.createTextRange) {
                var range = elem.createTextRange();
                range.move('character', caretPos);
                range.select();
            }
            else {
                if(elem.selectionStart) {
                    elem.focus();
                    elem.setSelectionRange(caretPos, caretPos);
                }
                else
                    elem.focus();
            }
        }
    }

    function setSearchFieldValue(initialValue) {
        initialValue = initialValue || "";
        var $field = $('input#quickFileOpenSearch');
        if ($field) {
            $field.val(initialValue);
            $field.focus();
            setCaretPosition($field.get(0), initialValue.length);
        }
    }

    /**
    * Shows the search dialog and initializes the auto suggestion list with filenames from the current project
    */
    QuickNavigateDialog.prototype.showDialog = function (initialValue) {
        var that = this;
        dialogOpen = true;

        // To improve performance during list selection disable JSLint until a document is choosen or dialog is closed
        JSLintUtils.setEnabled(false);

        var curDoc = DocumentManager.getCurrentDocument();
        origDocPath = curDoc ? curDoc.file.fullPath : null;
        if (curDoc) {
            origSelection = EditorManager.getCurrentFullEditor().getSelection();
        } else {
            origSelection = null;
        }

        // Move file list getting code so all this code isn't wrapped in it
        FileIndexManager.getFileInfoList("all")
            .done(function (files) {
                fileList = files;
                var dialogHTML = 'Quick Open: <input type="text" autocomplete="off" id="quickFileOpenSearch" style="width: 30em">';
                that._createDialogDiv(dialogHTML);
                that.searchField = $('input#quickFileOpenSearch');

                that.searchField.smartAutoComplete({
                    source: files,
                    maxResults: 20,
                    forceSelect: false,
                    typeAhead: false,   // won't work right now because smart auto complete
                                        // using internal raw results instead of filtered results for matching
                    filter: _handleFilter,
                    resultFormatter: _handleResultsFormatter
                });

                that.searchField.bind({
                    itemSelect: function (e, selectedItem) { that._handleItemSelect(selectedItem); },
                    /* Disabling open on rollover right now because it causes bugs
                    itemFocus: function (e, selectedItem) { that._handleItemFocus(selectedItem); },*/
                    keydown: function (e) { that._handleKeyDown(e); },
                    keyIn: function (e, query) { that._handleKeyIn(e, query); }
                });

                setSearchFieldValue(initialValue);
            });
    };

    function doSearch(prefix) {
        prefix = prefix || "";
        var currentEditor = EditorManager.getFocusedEditor();
        var initialString = currentEditor && currentEditor.getSelectedText() || "";
        initialString = prefix + initialString;

        if (dialogOpen) {
            setSearchFieldValue(initialString);
        } else {
            var dialog = new QuickNavigateDialog();
            dialog.showDialog(initialString);
        }
    }

    function doFileSearch() {
        doSearch();
    }

    function doGotoLine() {
        doSearch(":");
    }

    // TODO: should provide a way for QuickOpenJSSymbol to create this function as a plugin
    function doDefinitionSearch() {
        doSearch("@");
    }

    // TODO: in future we would dynamally discover quick open plugins and get their plugins
    var jsFuncPlugin = QuickOpenJSSymbol.getPlugin();
    addQuickOpenPlugin(jsFuncPlugin);

    var cssSelectorsPlugin = QuickOpenCSS.getPlugin();
    addQuickOpenPlugin(cssSelectorsPlugin);

    var htmlIDPlugin = QuickOpenHTML.getPlugin();
    addQuickOpenPlugin(htmlIDPlugin);

    // TODO: allow QuickOpenJS to register it's own commands and keybindings
    CommandManager.register(Commands.NAVIGATE_QUICK_OPEN, doFileSearch);
    CommandManager.register(Commands.NAVIGATE_GOTO_DEFINITION, doDefinitionSearch);
    CommandManager.register(Commands.NAVIGATE_GOTO_LINE, doGotoLine);

    exports.addQuickOpenPlugin = addQuickOpenPlugin;
});
<commit_msg>Remember original selection instead of cursor position<commit_after>/*
 * Copyright 2011 Adobe Systems Incorporated. All Rights Reserved.
 */

/*jslint vars: true, plusplus: true, devel: true, browser: true, nomen: true, indent: 4, maxerr: 50 */
/*global define, $ */

/*
* Displays an auto suggest popup list of files to allow the user to quickly navigate to a file and lines
* within a file.
* Uses FileIndexManger to supply the file list.
*
* TODO (issue 333) - currently jquery smart auto complete is used for the popup list. While it mostly works
* it has several issues, so it should be replace with an alternative. Issues:
* - only accepts an array of strings. A list of objects is preferred to avoid some work arounds to display
*   both the path and filename.
* - the popup position logic has flaws that require css work-arounds
* - the popup properties cannot be modified once the object is constructed
*/

define(function (require, exports, module) {
    'use strict';

    var FileIndexManager    = require("project/FileIndexManager"),
        JSLintUtils         = require("language/JSLintUtils"),
        DocumentManager     = require("document/DocumentManager"),
        EditorManager       = require("editor/EditorManager"),
        CommandManager      = require("command/CommandManager"),
        Commands            = require("command/Commands"),
        QuickOpenJSSymbol   = require("search/QuickOpenJavaScript"),
        QuickOpenCSS        = require("search/QuickOpenCSS"),
        QuickOpenHTML       = require("search/QuickOpenHTML"),
        ProjectManager      = require("project/ProjectManager");

    /** @type Array.<QuickOpenPlugin> */
    var plugins = [];

    /** @type {QuickOpenPlugin} */
    var currentPlugin = null;
    var fileList;

    /**
     * Rembers the current document that was displayed when showDialog() was called
     * The current document is restored if the user presses escape
     * @type {string} fullpath
     */
    var origDocPath;

    /**
     * Rembers the current cursor location that was present when showDialog() was called
     * The cursor position s restored if the user presses escape
     * @type ?{start:{line:number, ch:number}, end:{line:number, ch:number}}
     */
    var origSelection;

    var dialogOpen = false;

    /**
     * Defines API for new QuickOpen plguins
     * @param {string} plugin name
     * @param {Array.<string>} filetypes array. Example: ["js", "css", "txt"]
     * @param {Function} filter takes a query string and returns an array of strings that match the query
     * @param {?Functon} match takes a query string and returns true if this plugin wants to provide results for this query
     * @param {Functon} itemFocus performs an action when a result has focus
     * @param {Functon} itemSelect performs an action when a result is choosen
     * @param {?Functon} resultFormatter takes a query string and an item string and returns a
 item to insert into the displayed search resuklts
     */
    function QuickOpenPlugin(name, fileTypes, filter, match, itemFocus, itemSelect, resultsFormatter) {

        this.name = name;
        this.fileTypes = fileTypes; // empty array indicates all
        this.filter = filter;
        this.match = match;
        this.itemFocus = itemFocus;
        this.itemSelect = itemSelect;
        this.resultsFormatter = resultsFormatter;
    }

    /**
     * Registers new QuickOpenPlugin
     * @param {QuickOpenPlugin} plugin
     */
    function addQuickOpenPlugin(plugin) {
        plugins.push(new QuickOpenPlugin(
            plugin.name,
            plugin.fileTypes,
            plugin.filter,
            plugin.match,
            plugin.itemFocus,
            plugin.itemSelect,
            plugin.resultsFormatter
        ));
    }

    /**
    * QuickNavigateDialog class
    * @constructor
    */
    function QuickNavigateDialog() {
        this.searchField = undefined; // defined when showDialog() is called
    }

    /**
     * Creates a dialog div floating on top of the current code mirror editor
     */
    QuickNavigateDialog.prototype._createDialogDiv = function (template) {
        var wrap = $("#editorHolder")[0];
        this.dialog = wrap.insertBefore(document.createElement("div"), wrap.firstChild);
        this.dialog.className = "CodeMirror-dialog";
        this.dialog.innerHTML = '
' + template + '
';
    };

    function _filenameFromPath(path, includeExtension) {
        var end;
        if (includeExtension) {
            end = path.length;
        } else {
            end = path.lastIndexOf(".");
        }
        return path.slice(path.lastIndexOf("/") + 1, end);
    }

    function extractLineNumber(query) {
        var result;
        var regInfo = query.match(/(!?:)(\d+)/); // colon followed by a digit
        if (regInfo) {
            result = regInfo[2] - 1;
        }

        return result;
    }

    /**
     * Closes the search dialog and resolves the promise that showDialog returned
     */
    QuickNavigateDialog.prototype._handleItemSelect = function (selectedItem) {
        if (currentPlugin) {
            currentPlugin.itemSelect(selectedItem);
        } else {
            var query = this.searchField.val();
            var fullPath = $(selectedItem).attr("data-fullpath");

            // extract line number
            var cursor;
            var gotoLine = extractLineNumber(query);
            if (gotoLine) {
                cursor = {line: gotoLine, ch: 0};
            }

            // Do navigation
            if (fullPath) {
                CommandManager.execute(Commands.FILE_ADD_TO_WORKING_SET, {fullPath: fullPath})
                    .done(function () {
                        if (gotoLine) {
                            EditorManager.getCurrentFullEditor().setCursorPos(cursor);
                        }
                    });
            } else if (gotoLine) {
                EditorManager.getCurrentFullEditor().setCursorPos(cursor);
            }
        }

        this._close();
        EditorManager.focusEditor();
    };

    /**
     * Opens the file specified by selected item if there is no current plugin, otherwise defers handling
     * to the currentPlugin
     */
    QuickNavigateDialog.prototype._handleItemFocus = function (selectedItem) {
        if (currentPlugin) {
            currentPlugin.itemFocus(selectedItem);
        } else {
            var fullPath = $(selectedItem).attr("data-fullpath");
            if (fullPath) {
                fullPath = decodeURIComponent(fullPath);
                CommandManager.execute(Commands.FILE_OPEN, {fullPath: fullPath, focusEditor: false});
            }
        }
    };

    QuickNavigateDialog.prototype._handleKeyIn = function (e, query) {
        // extract line number
        var gotoLine = extractLineNumber(query);
        if (gotoLine) {
            var from = {line: gotoLine, ch: 0};
            var to = {line: gotoLine, ch: 99999};

            EditorManager.getCurrentFullEditor().setSelection(from, to);
        }

        // Remove current plugin if the query stops matching
        if (currentPlugin && !currentPlugin.match(query)) {
            currentPlugin = null;
        }

        if ($(".smart_autocomplete_highlight").length === 0) {
            this._handleItemFocus($(".smart_autocomplete_container > li:first-child"));
        }
    };

    /**
     * Close the dialog when the ENTER (13) or ESC (27) key is pressed
     */
    QuickNavigateDialog.prototype._handleKeyDown = function (e) {
        if (e.keyCode === 13 || e.keyCode === 27) {
            e.stopPropagation();
            e.preventDefault();

            // clear the query on ESC key and restore document and cursor poisition
            if (e.keyCode === 27) {

                // restore document and cursor position
                if (origDocPath) {
                    CommandManager.execute(Commands.FILE_OPEN, {fullPath: origDocPath})
                        .done(function () {
                            EditorManager.getCurrentFullEditor().setSelection(origSelection.start, origSelection.end);
                        });
                }
            } else if (e.keyCode === 13) {
                // Select current item on ENTER key
                this._handleItemSelect();
            }

            this._close();
        }
    };

    /**
    * Closes the search dialog and resolves the promise that showDialog returned
    */
    QuickNavigateDialog.prototype._close = function (value) {

        if (!dialogOpen) {
            return;
        }
        dialogOpen = false;

        JSLintUtils.setEnabled(true);

        // for some odd reason I need to remove the dialog like this through the parent
        // If I do it more directly listeners are not removed by the smart auto complete plugin
        this.dialog.parentNode.removeChild(this.dialog);
        $(".smart_autocomplete_container").remove();

        var editor = EditorManager.getCurrentFullEditor();
        editor.focus();
        editor.setSelection(origSelection.start, origSelection.end);
    };

    function filterFileList(query) {
        var filteredList = $.map(fileList, function (itemInfo) {
            // match query against filename only (not the full path)
            var path = itemInfo.fullPath;
            var filename = _filenameFromPath(path, true);
            if (filename.toLowerCase().indexOf(query.toLowerCase()) !== -1) {
                return path;
            } else {
                return null;
            }
        }).sort(function (a, b) {
            a = a.toLowerCase();
            b = b.toLowerCase();
            //first,  sort by filename without extension
            var filenameA = _filenameFromPath(a, false);
            var filenameB = _filenameFromPath(b, false);
            if (filenameA < filenameB) {
                return -1;
            } else if (filenameA > filenameB) {
                return 1;
            } else {
                // filename is the same, compare including extension
                filenameA = _filenameFromPath(a, true);
                filenameB = _filenameFromPath(b, true);
                if (filenameA < filenameB) {
                    return -1;
                } else if (filenameA > filenameB) {
                    return 1;
                } else {
                    return 0;
                }
            }
        });

        return filteredList;
    }

    function _handleFilter(query) {
        var curDoc = DocumentManager.getCurrentDocument();
        if (curDoc) {
            var filename = _filenameFromPath(curDoc.file.fullPath, true);
            var extension = filename.slice(filename.lastIndexOf(".") + 1, filename.length);

            var i;
            for (i = 0; i < plugins.length; i++) {
                var plugin = plugins[i];
                var extensionMatch = plugin.fileTypes.indexOf(extension) !== -1 || plugin.fileTypes.length === 0;
                if (extensionMatch &&  plugin.match && plugin.match(query)) {
                    currentPlugin = plugin;
                    return plugin.filter(query);
                }
            }
        }

        currentPlugin = null;
        return filterFileList(query);
    }

    function defaultResultsFormatter(item, query) {
        query = query.slice(query.indexOf("@") + 1, query.length);
        var boldName = item.replace(new RegExp(query, "gi"), "$&");
        return "
" + boldName + "
";
    }

    function _handleResultsFormatter(item) {
        var query = $('input#quickFileOpenSearch').val();

        if (currentPlugin) {
            var formatter = currentPlugin.resultsFormatter || defaultResultsFormatter;
            return formatter(item, query);
        } else {
            // Format filename result
            var filename = _filenameFromPath(item, true);
            var rPath = ProjectManager.makeProjectRelativeIfPossible(item);
            var boldName = filename.replace(new RegExp(query, "gi"), "$&");
            return "
" + boldName +
                "
" + rPath + "
";
        }
    }

    function setCaretPosition(elem, caretPos) {
        if(elem != null) {
            if(elem.createTextRange) {
                var range = elem.createTextRange();
                range.move('character', caretPos);
                range.select();
            }
            else {
                if(elem.selectionStart) {
                    elem.focus();
                    elem.setSelectionRange(caretPos, caretPos);
                }
                else
                    elem.focus();
            }
        }
    }

    function setSearchFieldValue(initialValue) {
        initialValue = initialValue || "";
        var $field = $('input#quickFileOpenSearch');
        if ($field) {
            $field.val(initialValue);
            $field.focus();
            setCaretPosition($field.get(0), initialValue.length);
        }
    }

    /**
    * Shows the search dialog and initializes the auto suggestion list with filenames from the current project
    */
    QuickNavigateDialog.prototype.showDialog = function (initialValue) {
        var that = this;
        dialogOpen = true;

        // To improve performance during list selection disable JSLint until a document is choosen or dialog is closed
        JSLintUtils.setEnabled(false);

        var curDoc = DocumentManager.getCurrentDocument();
        origDocPath = curDoc ? curDoc.file.fullPath : null;
        if (curDoc) {
            origSelection = EditorManager.getCurrentFullEditor().getSelection();
        } else {
            origSelection = null;
        }

        // Move file list getting code so all this code isn't wrapped in it
        FileIndexManager.getFileInfoList("all")
            .done(function (files) {
                fileList = files;
                var dialogHTML = 'Quick Open: <input type="text" autocomplete="off" id="quickFileOpenSearch" style="width: 30em">';
                that._createDialogDiv(dialogHTML);
                that.searchField = $('input#quickFileOpenSearch');

                that.searchField.smartAutoComplete({
                    source: files,
                    maxResults: 20,
                    forceSelect: false,
                    typeAhead: false,   // won't work right now because smart auto complete
                                        // using internal raw results instead of filtered results for matching
                    filter: _handleFilter,
                    resultFormatter: _handleResultsFormatter
                });

                that.searchField.bind({
                    itemSelect: function (e, selectedItem) { that._handleItemSelect(selectedItem); },
                    /* Disabling open on rollover right now because it causes bugs
                    itemFocus: function (e, selectedItem) { that._handleItemFocus(selectedItem); },*/
                    keydown: function (e) { that._handleKeyDown(e); },
                    keyIn: function (e, query) { that._handleKeyIn(e, query); }
                });

                setSearchFieldValue(initialValue);
            });
    };

    function doSearch(prefix) {
        prefix = prefix || "";
        var currentEditor = EditorManager.getFocusedEditor();
        var initialString = currentEditor && currentEditor.getSelectedText() || "";
        initialString = prefix + initialString;

        if (dialogOpen) {
            setSearchFieldValue(initialString);
        } else {
            var dialog = new QuickNavigateDialog();
            dialog.showDialog(initialString);
        }
    }

    function doFileSearch() {
        doSearch();
    }

    function doGotoLine() {
        doSearch(":");
    }

    // TODO: should provide a way for QuickOpenJSSymbol to create this function as a plugin
    function doDefinitionSearch() {
        doSearch("@");
    }

    // TODO: in future we would dynamally discover quick open plugins and get their plugins
    var jsFuncPlugin = QuickOpenJSSymbol.getPlugin();
    addQuickOpenPlugin(jsFuncPlugin);

    var cssSelectorsPlugin = QuickOpenCSS.getPlugin();
    addQuickOpenPlugin(cssSelectorsPlugin);

    var htmlIDPlugin = QuickOpenHTML.getPlugin();
    addQuickOpenPlugin(htmlIDPlugin);

    // TODO: allow QuickOpenJS to register it's own commands and keybindings
    CommandManager.register(Commands.NAVIGATE_QUICK_OPEN, doFileSearch);
    CommandManager.register(Commands.NAVIGATE_GOTO_DEFINITION, doDefinitionSearch);
    CommandManager.register(Commands.NAVIGATE_GOTO_LINE, doGotoLine);

    exports.addQuickOpenPlugin = addQuickOpenPlugin;
});
<|endoftext|>


<commit_before>import express from 'express';
import expressJwt from 'express-jwt';

import * as Member from 'server/controllers/member';

const router = express.Router();

router.get('/profile', Member.profile);

router.use(function (err, req, res, next) {
  if (err.name === 'UnauthorizedError') {
    res.status(401).send('invalid token...');
  }
});

export default router;<commit_msg>remove unused module<commit_after>import express from 'express';

import * as Member from 'server/controllers/member';

const router = express.Router();

router.get('/profile', Member.profile);

router.use(function (err, req, res, next) {
  if (err.name === 'UnauthorizedError') {
    res.status(401).send('invalid token...');
  }
});

export default router;<|endoftext|>


<commit_before>document.observe("dom:loaded", function() {
  var authToken = $$('meta[name=csrf-token]').first().readAttribute('content'),
    authParam = $$('meta[name=csrf-param]').first().readAttribute('content'),
    formTemplate = '<form method="#{method}" action="#{action}">\
      #{realmethod}<input name="#{param}" value="#{token}" type="hidden">\
      </form>',
    realmethodTemplate = '<input name="_method" value="#{method}" type="hidden">';

  function handleRemote(element) {
    var method, url, params;

    if (element.tagName.toLowerCase() == 'form') {
      method = element.readAttribute('method') || 'post';
      url    = element.readAttribute('action');
      params = element.serialize(true);
    } else {
      method = element.readAttribute('data-method') || 'get';
      url    = element.readAttribute('href');
      params = {};
    }

    var event = element.fire("ajax:before");
    if (event.stopped) return false;

    new Ajax.Request(url, {
      method: method,
      parameters: params,
      asynchronous: true,
      evalScripts: true,

      onLoading:     function(request) { element.fire("ajax:loading", {request: request}); },
      onLoaded:      function(request) { element.fire("ajax:loaded", {request: request}); },
      onInteractive: function(request) { element.fire("ajax:interactive", {request: request}); },
      onComplete:    function(request) { element.fire("ajax:complete", {request: request}); },
      onSuccess:     function(request) { element.fire("ajax:success", {request: request}); },
      onFailure:     function(request) { element.fire("ajax:failure", {request: request}); }
    });

    element.fire("ajax:after");
  }

  $(document.body).observe("click", function(event) {
    var message = event.element().readAttribute('data-confirm');
    if (message && !confirm(message)) {
      event.stop();
      return false;
    }

    var element = event.findElement("a[data-remote=true]");
    if (element) {
      handleRemote(element);
      event.stop();
    }

    var element = event.findElement("a[data-method]");
    if (element && element.readAttribute('data-remote') != 'true') {
      var method = element.readAttribute('data-method'),
        piggyback = method.toLowerCase() != 'post',
        formHTML = formTemplate.interpolate({
          method: 'POST',
          realmethod: piggyback ? realmethodTemplate.interpolate({ method: method }) : '',
          action: element.readAttribute('href'),
          token: authToken,
          param: authParam
        });

      var form = new Element('div').update(formHTML).down().hide();
      this.insert({ bottom: form });

      form.submit();
      event.stop();
    }
  });

  // TODO: I don't think submit bubbles in IE
  $(document.body).observe("submit", function(event) {
    var message = event.element().readAttribute('data-confirm');
    if (message && !confirm(message)) {
      event.stop();
      return false;
    }

    var inputs = event.element().select("input[type=submit][data-disable-with]");
    inputs.each(function(input) {
      input.disabled = true;
      input.writeAttribute('data-original-value', input.value);
      input.value = input.readAttribute('data-disable-with');
    });

    var element = event.findElement("form[data-remote=true]");
    if (element) {
      handleRemote(element);
      event.stop();
    }
  });

  $(document.body).observe("ajax:complete", function(event) {
    var element = event.element();

    if (element.tagName.toLowerCase() == 'form') {
      var inputs = element.select("input[type=submit][disabled=true][data-disable-with]");
      inputs.each(function(input) {
        input.value = input.readAttribute('data-original-value');
        input.writeAttribute('data-original-value', null);
        input.disabled = false;
      });
    }
  });
});
<commit_msg>Update rails.js to the latest one at http://github.com/rails/prototype-ujs<commit_after>document.observe("dom:loaded", function() {
  function handleRemote(element) {
    var method, url, params;

    if (element.tagName.toLowerCase() === 'form') {
      method = element.readAttribute('method') || 'post';
      url    = element.readAttribute('action');
      params = element.serialize(true);
    } else {
      method = element.readAttribute('data-method') || 'get';
      url    = element.readAttribute('href');
      params = {};
    }

    var event = element.fire("ajax:before");
    if (event.stopped) return false;

    new Ajax.Request(url, {
      method: method,
      parameters: params,
      asynchronous: true,
      evalScripts: true,

      onLoading:     function(request) { element.fire("ajax:loading", {request: request}); },
      onLoaded:      function(request) { element.fire("ajax:loaded", {request: request}); },
      onInteractive: function(request) { element.fire("ajax:interactive", {request: request}); },
      onComplete:    function(request) { element.fire("ajax:complete", {request: request}); },
      onSuccess:     function(request) { element.fire("ajax:success", {request: request}); },
      onFailure:     function(request) { element.fire("ajax:failure", {request: request}); }
    });

    element.fire("ajax:after");
  }

  function handleMethod(element) {
    var method, url, token_name, token;

    method     = element.readAttribute('data-method');
    url        = element.readAttribute('href');
    csrf_param = $$('meta[name=csrf-param]').first();
    csrf_token = $$('meta[name=csrf-token]').first();

    var form = new Element('form', { method: "POST", action: url, style: "display: none;" });
    element.parentNode.appendChild(form);

    if (method != 'post') {
      var field = new Element('input', { type: 'hidden', name: '_method', value: method });
      form.appendChild(field);
    }

    if (csrf_param) {
      var param = csrf_param.readAttribute('content');
      var token = csrf_token.readAttribute('content');
      var field = new Element('input', { type: 'hidden', name: param, value: token });
      form.appendChild(field);
    }

    form.submit();
  }

  $(document.body).observe("click", function(event) {
    var message = event.findElement().readAttribute('data-confirm');
    if (message && !confirm(message)) {
      event.stop();
      return false;
    }

    var element = event.findElement("a[data-remote]");
    if (element) {
      handleRemote(element);
      event.stop();
      return true;
    }

    var element = event.findElement("a[data-method]");
    if (element) {
      handleMethod(element);
      event.stop();
      return true;
    }
  });

  // TODO: I don't think submit bubbles in IE
  $(document.body).observe("submit", function(event) {
    var element = event.findElement(),
        message = element.readAttribute('data-confirm');
    if (message && !confirm(message)) {
      event.stop();
      return false;
    }

    var inputs = element.select("input[type=submit][data-disable-with]");
    inputs.each(function(input) {
      input.disabled = true;
      input.writeAttribute('data-original-value', input.value);
      input.value = input.readAttribute('data-disable-with');
    });

    var element = event.findElement("form[data-remote]");
    if (element) {
      handleRemote(element);
      event.stop();
    }
  });

  $(document.body).observe("ajax:after", function(event) {
    var element = event.findElement();

    if (element.tagName.toLowerCase() === 'form') {
      var inputs = element.select("input[type=submit][disabled=true][data-disable-with]");
      inputs.each(function(input) {
        input.value = input.readAttribute('data-original-value');
        input.writeAttribute('data-original-value', null);
        input.disabled = false;
      });
    }
  });
});<|endoftext|>