angular-cn/public/resources/js/directives/api-list.js

270 lines
9.6 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*eslint no-unused-vars: "angularIO" */
/*
* API List & Filter Directive
*
* A page displaying all of the angular API methods available
* including a filter that can hide/show methods bases on filter
* settings.
*/
angularIO.directive('apiList', function () {
var QUERY_KEY = 'query';
var TYPE_KEY = 'type';
var STATUS_KEY = 'status';
return {
restrict: 'E',
template:
'<div ng-cloak="ng-cloak" class="l-flex-wrap banner is-plain api-filter">' +
' <div class="form-select-menu">' +
' <button ng-repeat="type in $ctrl.types" ng-if="$ctrl.type === type.matches[0]" class="form-select-button has-symbol" ng-click="$ctrl.toggleMenu(\'type\')"><strong>Type:</strong><span class="symbol {{type.cssClass}}" ng-if="type.cssClass !== \'stable\'" ></span>{{type.title}}</button>'+
' <button class="form-select-button is-default" ng-if="$ctrl.type === null" ng-click="$ctrl.toggleMenu(\'type\')"><strong>Type: All</strong></button>'+
' <ul class="form-select-dropdown" ng-class="{ visible: $ctrl.showTypeMenu === true }">' +
' <li ng-class="{ active: !$ctrl.type }" ng-click="$ctrl.clear(\'type\')">All</li>' +
' <li ng-repeat="type in $ctrl.types" ng-class="{ active: $ctrl.type === type }" ng-click="$ctrl.set(type, \'type\')"><span class="symbol {{type.cssClass}}"></span>{{type.title}}</li>' +
' </ul>' +
' <div class="overlay" ng-class="{ visible: $ctrl.showTypeMenu === true }" ng-click="$ctrl.toggleMenu(\'type\')"></div>' +
' </div>' +
' ' +
' <div class="form-select-menu" ng-if="!$ctrl.isForDart">' +
' <button ng-repeat="status in $ctrl.statuses" ng-if="$ctrl.status === status.matches[0]" class="form-select-button" ng-click="$ctrl.toggleMenu(\'status\')"><strong>Status:</strong>{{status.title}}</button>'+
' <button class="form-select-button is-default" ng-if="$ctrl.status === null" ng-click="$ctrl.toggleMenu(\'status\')"><strong>Status: All</strong></button>'+
' <ul class="form-select-dropdown" ng-class="{ visible: $ctrl.showStatusMenu === true }">' +
' <li ng-class="{ active: !$ctrl.status }" ng-click="$ctrl.clear(\'status\')">All</li>' +
' <li ng-repeat="status in $ctrl.statuses" ng-class="{ active: $ctrl.status === status }" ng-click="$ctrl.set(status, \'status\')">{{status.title}}</li>' +
' </ul>' +
' <div class="overlay" ng-class="{ visible: $ctrl.showStatusMenu === true }" ng-click="$ctrl.toggleMenu(\'status\')"></div>' +
' </div>' +
' ' +
' <div class="form-search">' +
' <i class="material-icons">search</i>' +
' <input placeholder="Filter" ng-model="$ctrl.query" ng-model-options="{updateOn: \'default blur\', debounce: {\'default\': 350, \'blur\': 0}}">' +
' </div>' +
'</div>' +
' ' +
'<article class="l-content-small docs-content">' +
' <div ng-repeat="section in $ctrl.groupedSections" ng-if="$ctrl.filterSections(section)" ng-cloak="ng-cloak">' +
' <h2>{{ section.title }}</h2>' +
' <ul class="api-list">' +
' <li ng-repeat="item in section.items" ng-show="item.show" class="api-item">' +
' <a ng-href="{{ item.path }}"><span class="symbol {{ item.docType }}"></span>{{ item.title }}</a>' +
' </li>' +
' </ul>' +
' </div>' +
'</article>',
controllerAs: '$ctrl',
controller: function($scope, $attrs, $http, $location) {
// DEFAULT VALUES
var $ctrl = this;
$ctrl.showTypeMenu = false;
$ctrl.showStatusMenu = false;
$ctrl.status = null;
$ctrl.query = null;
$ctrl.type = null;
$ctrl.groupedSections = [];
// API TYPES
$ctrl.types = [
{ cssClass: 'directive', title: 'Directive', matches: ['directive'] },
{ cssClass: 'pipe', title: 'Pipe', matches: ['pipe'] },
{ cssClass: 'decorator', title: 'Decorator', matches: ['decorator'] },
{ cssClass: 'class', title: 'Class', matches: ['class'] },
{ cssClass: 'interface', title: 'Interface', matches: ['interface'] },
{ cssClass: 'function', title: 'Function', matches: ['function'] },
{ cssClass: 'enum', title: 'Enum', matches: ['enum'] },
{ cssClass: 'type-alias', title: 'Type Alias', matches: ['type-alias'] },
{ cssClass: 'const', title: 'Const', matches: ['const', 'var', 'let'] }
];
// STATUSES
$ctrl.statuses = [
{ cssClass: 'stable', title: 'Stable', matches: ['stable']},
{ cssClass: 'deprecated', title: 'Deprecated', matches: ['deprecated']},
{ cssClass: 'experimental', title: 'Experimental', matches: ['experimental']},
{ cssClass: 'security', title: 'Security Risk', matches: ['security']}
];
// SET FILTER VALUES
getFilterValues();
// GRAB DATA FOR SECTIONS
$http.get($attrs.src).then(function(response) {
$ctrl.sections =  response.data;
$ctrl.groupedSections = Object.keys($ctrl.sections).map(function(title) {
return { title: title, items: $ctrl.sections[title] };
});
});
// SET SELECTED VALUE FROM MENUS/FORM
$ctrl.set = function(item, kind) {
var value = (item && item.matches) ? item.matches[0] : null;
switch(kind) {
case 'type': $ctrl.type = value ; break;
case 'query': $ctrl.query = value ; break;
case 'status': $ctrl.status = value ; break;
}
$ctrl.toggleMenu(kind);
}
// CLEAR SELECTED VALUE FROM MENUS/FORM
$ctrl.clear = function (kind) {
switch(kind) {
case 'type': $ctrl.type = null ; break;
case 'query': $ctrl.query = null ; break;
case 'status': $ctrl.status = null ; break;
}
$ctrl.toggleMenu(kind);
};
// TOGGLE MENU
$ctrl.toggleMenu = function(kind) {
switch(kind) {
case 'type': $ctrl.showTypeMenu = !$ctrl.showTypeMenu; ; break;
case 'status': $ctrl.showStatusMenu = !$ctrl.showStatusMenu; ; break;
}
}
// UPDATE VALUES IF DART API
var isForDart = $attrs.lang === 'dart';
if (isForDart) {
$ctrl.isForDart = true;
$ctrl.statuses = [];
$ctrl.types = $ctrl.types.filter(function (t) {
return t.cssClass.match(/^(class|function|const)$/);
});
}
// SET URL WITH VALUES
$scope.$watchGroup(
[
function() { return $ctrl.query; },
function() { return $ctrl.type; },
function() { return $ctrl.status; },
function() { return $ctrl.sections; }
],
function() {
var queryURL = $ctrl.query ? $ctrl.query.toLowerCase() : null;
var typeURL = $ctrl.type || null;
var statusURL = $ctrl.status || null;
// SET URLS
$location.search(QUERY_KEY, queryURL);
$location.search(STATUS_KEY, statusURL);
$location.search(TYPE_KEY, typeURL);
}
);
// GET VALUES FROM URL
function getFilterValues() {
var urlParams = $location.search();
$ctrl.status = urlParams[STATUS_KEY] || null;
$ctrl.query = urlParams[QUERY_KEY] || null;;
$ctrl.type = urlParams[TYPE_KEY] || null;;
}
// CHECK IF IT'S A CONSTANT TYPE
function isConst(item) {
var isConst = false;
switch(item.docType) {
case 'let': isConst = true; break;
case 'var': isConst = true; break;
case 'const': isConst = true; break;
default: isConst = false;
}
return isConst;
}
// FILTER SECTION & ITEMS LOOP
$ctrl.filterSections = function(section) {
var showSection = false;
section.items.forEach(function(item) {
item.show = false;
// CHECK IF TYPE IS NULL & STATUS, QUERY
if (($ctrl.type === null) && statusSelected(item) && queryEntered(section, item)) {
item.show = true;
}
// CHECK IF TYPE IS SELECTED & STATUS, QUERY
if (($ctrl.type === item.docType) && statusSelected(item) && queryEntered(section, item)) {
item.show = true;
}
// CHECK IF TYPE IS CONST & STATUS, QUERY
if (($ctrl.type === 'const') && isConst(item) && statusSelected(item) && queryEntered(section, item)) {
item.show = true;
}
// SHOW SECTION IF ONE ITEM IS VISIBLE
if(!showSection && item.show) {
showSection = true;
}
});
return showSection;
}
// CHECK FOR QUERY
function queryEntered(section, item) {
var isVisible = false;
// CHECK IF QUERY MATCH SECTION OR ITEM
var query = ($ctrl.query || '').toLowerCase();
var matchesSection = $ctrl.query === '' || $ctrl.query === null || section.title.toLowerCase().indexOf($ctrl.query.toLowerCase()) !== -1;
var matchesTitle = !query || item.title.toLowerCase().indexOf(query) !== -1;
// FILTER BY QUERY
if(matchesTitle || matchesSection) {
isVisible = true;
}
return isVisible;
}
// CHECK IF AN API ITEM IS VISIBLE BY STATUS
function statusSelected(item) {
var status = item.stability;
var insecure = item.secure === 'false' ? false : true;
var isVisible = false;
if($ctrl.status === null) {
isVisible = true;
}
if(status === $ctrl.status) {
isVisible = true;
}
if(($ctrl.status === 'security') && insecure) {
isVisible = true;
}
return isVisible;
};
}
};
});