chore(demos): start ionic-demo page

This commit is contained in:
Andrew Joslin
2014-05-16 13:29:52 -06:00
parent f19c6d0edc
commit 55e910d2e9
17 changed files with 414 additions and 67 deletions

View File

@@ -25,11 +25,16 @@ module.exports = function(config) {
config.set('versionData', versionData);
config.set('rendering.contentsFolder', path.join('docs', versionData.current.folder));
config.set('demos.outputFolder', path.join(__dirname, '../tmp/ionic-demo'));
config.set('processing.api-docs', {
outputPath: 'api/${docType}/${name}/index.md',
path: 'api/${docType}/${name}/',
moduleOutputPath: 'api/module/${name}/index.md',
modulePath: 'api/module/${name}/'
modulePath: 'api/module/${name}/',
mergeableTypes: {
demo: 'demos'
}
});
config.append('rendering.filters', [
@@ -59,10 +64,10 @@ module.exports = function(config) {
config.append('processing.processors', [
require('./processors/latest-version'),
require('./processors/keywords'),
require('./processors/pages-data'),
require('./processors/index-page'),
require('./processors/version-data'),
require('./processors/jekyll')
require('./processors/jekyll'),
require('./processors/demos')
]);
return config;

119
docs/processors/demos.js Normal file
View File

@@ -0,0 +1,119 @@
var path = require('canonical-path');
var log = require('winston');
var _ = require('lodash');
var currentVersion;
var contentsFolder;
module.exports = {
name: 'demos',
runAfter: ['api-docs'],
runBefore: ['index-page'],
description: 'Create demos',
init: function(config) {
currentVersion = config.get('currentVersion');
contentsFolder = config.get('rendering.contentsFolder');
},
process: function(docs, config, extraData) {
var demoTags = [
'javascript',
'html',
'css',
'spec',
'scenario'
];
var extensions = {
javascript: 'js',
html: 'html',
css: 'css',
spec: 'js',
scenario: 'js'
};
var demoFolder = path.join(config.get('versionData.current.folder'),
'${docType}/${name}');
var demoPath = '${name}/${filename}.${extension}';
var templatePath = 'demo/${filename}.template.${extension}';
var allDemos = [];
_(docs)
.filter(function(doc) { return doc.demos; })
.forEach(function(doc) {
var outputFolder = _.template(demoFolder,doc);
doc.demos.forEach(function(demo) {
var demoData = {};
allDemos.push(demoData);
var outputFolder = _.template(demoFolder, doc);
demoData.module = demo.module;
demoData.name = demo.name;
demoData.docName = doc.name;
demoData.href = '/' + outputFolder + '/' + demo.name;
demoTags.forEach(function(tagName) {
var data = demo.tags.tagsByName[tagName];
if (data && data.length) {
var content = data.map(function(d) {
return d.description;
}).join('\n');
var filename = tagName;
var ext = extensions[tagName];
var outputPath = outputFolder + '/' + _.template(demoPath, {
name: demo.name,
filename: filename,
extension: ext
});
var template = _.template(templatePath, {
filename: filename,
extension: ext
});
demoData[tagName] = {
path: outputPath,
content: content
};
//Write all the files for this demo (html, css, js)
docs.push({
docType: 'demo',
id: doc.name + '/' + demo.name,
outputPath: config.get('demos.outputFolder') + '/' + outputPath,
template: template,
contents: content
});
}
});
var outputPath = outputFolder + '/' + _.template(demoPath, {
name: demo.name,
filename: 'index',
extension: 'html'
});
//Write this specific demo's index page
docs.push({
docType: 'demo',
outputPath: path.join(config.get('demos.outputFolder'), outputPath),
template: 'demo_index.template.html',
demoData: demoData,
name: doc.name
});
});
})
.value();
//Write the demo page for this whole version (eg at /nightly)
docs.push({
docType: 'demo',
template: 'demo_index.template.html',
outputPath: path.join(
config.get('demos.outputFolder'),
config.get('versionData.current.folder'),
'index.html'
)
});
extraData.demos = allDemos;
}
};

View File

@@ -1,56 +0,0 @@
var _ = require('lodash');
var fs = require('fs');
var path = require('canonical-path');
var log = require('winston');
var outputFolder;
var processorConfig;
var currentVersion;
module.exports = {
name: 'pages-data',
description: 'This plugin will create a new doc that will be rendered as an angularjs module ' +
'which will contain meta information about the pages and navigation',
runAfter: ['adding-extra-docs', 'component-groups-generate'],
runBefore: ['extra-docs-added'],
init: function(config) {
outputFolder = config.rendering.outputFolder;
processorConfig = config.get('processing.pages-data', {});
currentVersion = config.get('currentVersion');
},
process: function(docs, config) {
// Generate an object collection of pages that is grouped by section e.g.
// - section "directive"
// - group "Tab Bar"
// - ion-tabs
// - ion-tab
// - group ""
// - ion-toggle
// - ion-checkbox
// - ...
//
var sections = _(docs)
.filter(function(doc) { return doc.area === 'api'; })
.filter(function(doc) { return doc.module === 'ionic'; })
.filter(function(doc) { return doc.docType !== 'componentGroup'; })
.groupBy('docType')
.map(function(pages, docType) {
return {
name: docType,
components: pages.map(function(page) {
return {
href: page.path,
name: page.name,
docType: page.docType,
type: page.docType
};
})
};
})
.sortBy(function(section) {
//Directives always first
return section.name != 'directive';
})
.value();
}
};

View File

@@ -16,10 +16,11 @@ module.exports = [
});
}
},
{
name: 'codepen'
},
{
name: 'alias'
}
{ name: 'codepen' },
{ name: 'alias' },
{ name: 'demo' },
{ name: 'javascript' },
{ name: 'css' },
{ name: 'html' },
{ name: 'ngModule' }
];

View File

@@ -4,6 +4,7 @@
<@ block additional @>
<@ block usage @>
<pre><$ doc | json $></pre>
<h2 id="usage">Usage</h2>
<@ if doc.usage @>
<$ doc.usage $>

1
docs/templates/demo/css.template.css vendored Normal file
View File

@@ -0,0 +1 @@
<$ doc.contents $>

View File

@@ -0,0 +1 @@
<$ doc.contents $>

View File

@@ -0,0 +1 @@
<$ doc.contents $>

View File

@@ -0,0 +1 @@
<$ doc.contents $>

1
docs/templates/demo/spec.template.js vendored Normal file
View File

@@ -0,0 +1 @@
<$ doc.contents $>

168
docs/templates/demo_index.template.html vendored Normal file
View File

@@ -0,0 +1,168 @@
<!doctype html>
<html ng-app="<@ if doc.demoData @><$ doc.demoData.module $><@ else @>demoApp<@ endif @>" ng-controller="IonicDemoCtrl">
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<link rel="stylesheet" href="http://code.ionicframework.com/<$ version.current.name $>/css/ionic.min.css">
<@ if doc.demoData and doc.demoData.css @>
<link rel="stylesheet" href="/<$ doc.demoData.css.path $>">
<@ endif @>
<script src="http://code.ionicframework.com/<$ version.current.name $>/js/ionic.bundle.min.js"></script>
<@ if doc.demoData and doc.demoData.javascript @>
<script src="/<$ doc.demoData.javascript.path $>"></script>
<@ endif @>
</head>
<body>
<@ if doc.demoData @>
<div class="demo-content-pane">
<$ doc.demoData.html.content $>
</div>
<div class="bar bar-footer bar-light demo-footer" ng-click="$demoModal.show()">
<div class="demo-footer-icon" ng-hide="$demoModal.isShown()">
<i class="icon ion-chevron-up"></i>
</div>
<h1 class="title" style="right:auto;">
<$ doc.name $>: <$ doc.demoData.name | capital $>
</h1>
<div class="buttons right-buttons">
<a class="button" ng-click="demoScratch($demo); $event.stopPropagation()">
<i class="icon ion-code"></i>
View Source
</a>
</div>
<@ else @>
<div class="pane">
<div ng-include="'demo-list.html'">
</div>
</div>
<@ endif @>
<script type="text/ng-template" id="ionic-demo-modal.html">
<div class="modal">
<div ng-include="'demo-list.html'">
</div>
</div>
</script>
<script type="text/ng-template" id="demo-list.html">
<ion-header-bar class="bar-light">
<a class="button" ng-click="$demoModal.hide()" ng-if="$demo">
Cancel
</a>
<h1 class="title">All Demos</h1>
</ion-header-bar>
<ion-content>
<div class="list">
<div class="item item-input-inset">
<label class="item-input-wrapper">
<input type="text" placeholder="Filter Demos..." ng-model="demoFilter" autofocus>
</label>
<button class="button button-small" ng-click="demoFilter = ''">
Clear
</button>
</div>
<a class="item item-icon-right"
ng-class="{active: demo.module == $demo.module }"
ng-repeat="demo in $demos | filter:demoFilter"
ng-href="{{demo.href}}">
{{demo.docName}}: {{demo.name | capitalize}}
<i class="icon icon-accessory ion-chevron-right"></i>
</a>
</div>
</ion-content>
</script>
<script>
var DEMOS = <$ demos | json $>;
var DEMO;
<@ if doc.demoData @>
DEMO = <$ doc.demoData | json $>;
<@ endif @>
</script>
<script>
angular.module(<@ if doc.demoData @>'<$ doc.demoData.module $>'<@ else @>'demoApp', ['ionic']<@ endif @>)
.controller('IonicDemoCtrl', function($scope, $ionicModal, $http) {
$scope.$demos = DEMOS;
$scope.$demo = DEMO;
$ionicModal.fromTemplateUrl('ionic-demo-modal.html', {
scope: $scope
}).then(function(modal) {
$scope.$demoModal = modal;
});
if (DEMO) {
//don't try this at home
ionic.onGesture('dragup', function(e) {
if (e.gesture.distance > 35 && !$scope.$demoModal.isShown()) {
$scope.$apply(function(e) {
$scope.$demoModal.show();
});
}
}, document.querySelector('.demo-footer'));
}
$scope.demoScratch = function(demo) {
var data = new FormData();
data.append('html', demo.html && demo.html.content || '');
data.append('css', demo.css && demo.css.content || '');
data.append('js', demo.javascript && demo.javascript.content || '');
$http.post('http://scratch.ionicsdk.com/embed', data, {
transformRequest: angular.identity,
headers: {
'Content-Type': 'multipart/form-data'
}
});
};
})
.filter('capitalize', function() {
return function(input) {
return input.charAt(0).toLowerCase() + input.substring(1);
};
});
</script>
<style>
body {
margin-bottom: 44px;
}
.demo-content-pane {
position: absolute;
top: 0;
right: 0;
bottom: 44px;
left: 0;
width: 100%;
overflow: hidden;
}
.demo-footer-icon {
position: absolute;
left: 0;
right: 0;
top: -3px;
margin: auto;
text-align: center;
-webkit-transform: scaleX(1.3);
-moz-transform: scaleX(1.3);
transform: scaleX(1.3);
}
.demo-footer-icon .icon {
color: #CCC;
font-size: 18px;
}
</style>
</body>
</html>

View File

@@ -15,6 +15,60 @@
* <ion-checkbox ng-model="isChecked">Checkbox Label</ion-checkbox>
* ```
*/
/**
* @ngdoc demo
* @name ionCheckbox#simple
* @module checkboxSimple
* @javascript
* var app = angular.module('checkboxSimple', ['ionic']);
* app.controller('CheckboxSimpleCtrl', function($scope) {
* $scope.pizza = {
* pepperoni: true,
* sausage: false,
* anchovies: true,
* jalapenos: false
* };
*
* $scope.toppings = function() {
* var toppings = Object.keys($scope.pizza).filter(function(flavor) {
* return $scope.pizza[flavor];
* });
* if (toppings.length > 1) {
* toppings[toppings.length - 1] = 'and ' + toppings[toppings.length - 1];
* }
* if (toppings.length > 2) {
* return toppings.join(', ');
* } else if (toppings.length) {
* return toppings.join(' ');
* } else {
* return 'nothing';
* }
* };
* });
*
* @html
* <ion-header-bar class="bar-positive">
* <h1 class="title">
* Checkbox: Simple Usage
* </h1>
* </ion-header-bar>
* <ion-content ng-controller="CheckboxSimpleCtrl" class="padding">
* <h3>Your pizza has {{toppings()}}!</h3>
* <ion-checkbox ng-model="pizza.pepperoni">
* Pepperoni?
* </ion-checkbox>
* <ion-checkbox ng-model="pizza.sausage">
* Sausage?
* </ion-checkbox>
* <ion-checkbox ng-model="pizza.anchovies">
* Jalapeno?
* </ion-checkbox>
* <ion-checkbox ng-model="pizza.jalapenos">
* Anchovies?
* </ion-checkbox>
* </ion-content>
*/
IonicModule
.directive('ionCheckbox', function() {
return {

View File

@@ -9,7 +9,7 @@ var ITEM_TPL_OPTION_BUTTONS =
* @restrict E
* Creates an option button inside a list item, that is visible when the item is swiped
* to the left by the user. Swiped open option buttons can be hidden with
* {@link ionic.directive:$ionicListDelegate#closeOptionButtons $ionicListDelegate#closeOptionButtons}.
* {@link ionic.service:$ionicListDelegate#closeOptionButtons $ionicListDelegate#closeOptionButtons}.
*
* Can be assigned any button class.
*

View File

@@ -57,3 +57,4 @@ IonicModule
}
};
});

View File

@@ -50,6 +50,51 @@ IonicModule
* with {@link ionic.service:$ionicSideMenuDelegate}.
*
*/
/**
* @ngdoc demo
* @name ionSideMenus#simple
* @module sideMenusSimple
* @javascript
var app = angular.module('sideMenusSimple', ['ionic']);
app.controller('SideMenusSimpleCtrl', function($scope, $ionicSideMenuDelegate) {
$scope.toggleLeft = function() {
$ionicSideMenuDelegate.toggleLeft();
};
});
*
* @html
<ion-view title="Side Menus Simple" ng-controller="SideMenusSimpleCtrl">
<ion-side-menus>
<ion-side-menu-content>
<ion-header-bar class="bar-positive">
<div class="buttons">
<div class="button button-clear" ng-click="toggleLeft()">
<i class="icon ion-navicon"></i>
</div>
</div>
</ion-header-bar>
<ion-content class="padding">
<p>Slide the content or press the button on the header to open a side menu.</p>
</ion-content>
</ion-side-menu-content>
<ion-side-menu side="left">
<ion-header-bar class="bar-positive">
</ion-header-bar>
<ion-content>
<a class="item" ng-click="toggleLeft()">
Close Menu
</a>
</ion-content>
</ion-side-menu>
</ion-side-menus>
</ion-view>
*/
.directive('ionSideMenus', [function() {
return {
restrict: 'ECA',

View File

@@ -4,7 +4,7 @@
* @module ionic
* @description
* 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.
* 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`.
*
* @usage

View File

@@ -20,6 +20,10 @@ describe('viewState', function() {
expect(navButtons('right').getText()).toEqual('');
expect(navButtons('right').getAttribute('class')).toContain('ion-navicon');
browser.takeScreenshot().then(function(png) {
console.log(png);
});
element(by.id('sign-in-button')).click();