This commit is contained in:
dntzhang 2018-02-25 16:06:09 +08:00
parent c45f8c81a6
commit c637586cff
484 changed files with 38748 additions and 170136 deletions

View File

@ -1,7 +1,15 @@
asset
dist
node_modules
src/art-template.js
src/soda.js
src/html2json.js
example/hyperscript/bundler.js
example/life-cycle/bundler.js
example/nest/bundler.js
example/pagination/bundler.js
example/perfs
example/plugin/bundler.js
example/ref/bundler.js
example/simple/bundler.js
example/slot/bundler.js
example/todo/bundler.js
example/tree/bundler.js

View File

@ -1,10 +1,11 @@
{
"extends": "standard",
"rules": {
// special alloyteam code style
// special alloyteam code style
// @see: http://alloyteam.github.io/CodeGuide/#js-indentation
"indent": ["error", 4],
// @see: http://alloyteam.github.io/CodeGuide/#js-space
"space-before-function-paren": ["error", "never"]
"space-before-function-paren": ["error", "never"],
"one-var": 0
}
}
}

13
.gitignore vendored
View File

@ -1,8 +1,5 @@
.DS_Store
node_modules
/.idea
/md2site/template/app/rev
/omi-canvas
/example/server-rendering
/node_modules
/plugins/omi-finger/node_modules
/plugins/omi-router/node_modules
/plugins/omi-touch/node_modules
/plugins/omi-transform/node_modules

209
README.md
View File

@ -1,109 +1,160 @@

<h1 align="center">
<a href="https://github.com/AlloyTeam/omix">→Use Omix if your like JSX←</a>
</h1>
<p align="center">
<a href="##Omix"><img src="http://images2017.cnblogs.com/blog/105416/201708/105416-20170807145434955-1872305404.png" alt="Omi"></a>
</p>
<p align="center">
Build UI with JSX - 使用 JSX 创建用户界面
</p>
<p align="center">
</p>
<p align="center">
<a href="##Omi"><img src="http://images2015.cnblogs.com/blog/105416/201701/105416-20170120114244046-622856943.png" alt="Omi"></a>
</p>
<p align="center">
Open and modern framework for building user interfaces.
</p>
<p align="center">
<a href="https://circleci.com/gh/AlloyTeam/omi/tree/master"><img src="https://img.shields.io/circleci/project/AlloyTeam/omi/master.svg" alt="Build Status"></a>
<a href="https://www.npmjs.com/package/omi"><img src="https://img.shields.io/npm/v/omi.svg" alt="Version"></a>
<a href="https://www.npmjs.com/package/omi"><img src="https://img.shields.io/npm/dm/omi.svg" alt="Download"></a>
<a href="https://circleci.com/gh/AlloyTeam/omix/tree/master"><img src="https://img.shields.io/circleci/project/AlloyTeam/omix/master.svg" alt="Build Status"></a>
<a href="https://www.npmjs.com/package/omix"><img src="https://img.shields.io/npm/v/omix.svg" alt="Version"></a>
<a href="https://www.npmjs.com/package/omix"><img src="https://img.shields.io/npm/dm/omix.svg" alt="Download"></a>
<a href="CONTRIBUTING.md"><img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg" alt="PRs"></a>
</p>
[中文README](README.zh-CN.md)
## Omi
* [中文文档](./docs/README.md)
* [Omi REPL](https://alloyteam.github.io/omix/repl/)
* [Change Log](https://github.com/AlloyTeam/omix/blob/master/change-log.md)
* [Omi Cli](https://github.com/AlloyTeam/omi-cli) and [Cli Usage](https://github.com/AlloyTeam/omi-cli#用户指南)
* [Omi Docs](https://github.com/AlloyTeam/omi/blob/master/tutorial/all.md)
* [Omi Playground](https://alloyteam.github.io/omi/example/playground/)
* [Omi Tutorial](https://github.com/AlloyTeam/omi/tree/master/tutorial)
* [New issue](https://github.com/AlloyTeam/omi/issues/new)
* If you want to be more convenient on the exchange of all Omi can join the QQ Omi exchange group (256426170)
## Features
* Super fast, [click here!!!!](https://alloyteam.github.io/omix/example/perfs)
* Super tiny size, 7 KB (gzip)
* Good compatibility, support IE8
* Support Scoped CSS, reusable components are composed of HTML, Scoped CSS and JS
* More free updates, each component has a update method, free to choose the right time to update
## Hello Omix
``` js
class Hello extends Omi.Component {
render() {
return <div> Hello {this.data.name}!</div>
}
}
class App extends Omi.Component {
install() {
this.name = 'Omi'
this.handleClick = this.handleClick.bind(this)
}
handleClick(e) {
this.name = 'Omix'
this.update()
}
style() {
return `h3{
color:red;
cursor: pointer;
}`
}
render() {
return <div>
<Hello name={this.name}></Hello>
<h3 onclick={this.handleClick}>Scoped css and event test! click me!</h3>
</div>
}
}
Omi.render(new App(), '#container')
```
## Using Store System
```js
class Store {
constructor(data, callbacks) {
this.name = data.name || ''
this.onRename = callbacks.onRename || function(){}
}
rename(name){
this.name = name
this.onRename()
}
}
class Hello extends Omi.Component {
render() {
return (
//you can also use this.$store.name here. but using data if this is a pure component.
<div> Hello <span>{this.data.name}</span>!</div>
)
}
}
class App extends Omi.Component {
install(){
this.rename = this.rename.bind(this)
}
rename(){
this.$store.rename('Omix')
}
render() {
return (
<div onclick={this.rename}>
<Hello name={this.$store.name}></Hello>
</div>
)
}
}
let app = new App()
let store = new Store({ name : 'Omi' } ,{
onRename :()=>{
app.update()
}
})
Omi.render(app, 'body',{
store
})
```
[→Try it online←](https://alloyteam.github.io/omix/repl/redirect.html)
## omi-cli
```bash
$ npm install omi-cli -g # install cli
$ omi init your_project_name # init project, you can also exec 'omi init' in an empty folder
$ cd your_project_name # please ignore this command if you executed 'omi init' in an empty folder
$ npm start                  # develop
$ npm run dist # release
$ npm install omi-cli -g # install cli
$ omi init-x your_project_name # init project, you can also exec 'omi init-x' in an empty folder
$ cd your_project_name # please ignore this command if you executed 'omi init' in an empty folder
$ npm start # develop
$ npm run dist # release
```
other cmd:
the latest cli support blow cmd to init omix project, not omi project:
```bash
$ npm run ie # debugging in ie8
```
## Features
* Super tiny size, 7 KB (gzip)
* Good compatibility, support IE8 (please import es5-shim or [es5-sham](//s.url.cn/qqun/xiaoqu/buluo/p/js/es5-sham-es5-sham.min.77c4325f.js) by yourself)
* Fully object-oriented component system
* Support Scoped CSS, reusable components are composed of HTML, Scoped CSS and JS
* More free updates, each component has a update method, free to choose the right time to update
* Template engines can be replaced, developers can override the Omi.template method to use any template engine
* Provides two development way ( ES6+ and ES5) for developers to choose freely
## Plugins
* [omi-router](https://github.com/AlloyTeam/omi/tree/master/plugins/omi-router): Router for Omi.
* [omi-finger](https://github.com/AlloyTeam/omi/tree/master/plugins/omi-finger): Omi /[AlloyFinger](https://github.com/AlloyTeam/AlloyFinger) integration.
* [omi-transform](https://github.com/AlloyTeam/omi/tree/master/plugins/omi-transform): Omi /[transformjs](https://alloyteam.github.io/AlloyTouch/transformjs/) integration.
* [omi-touch](https://github.com/AlloyTeam/omi/tree/master/plugins/omi-touch): Omi /[AlloyTouch](https://github.com/AlloyTeam/AlloyTouch) integration.
* [omi-jquery-date-picker](https://github.com/AlloyTeam/omi/tree/master/plugins/omi-jquery-date-picker): Omi / JQuery Date Picker integration.
omi init your_project_name
```
## Install
```bash
$ npm install omi
``` bash
npm install omix
```
## Hello World
or get it from CDN:
You can use [webpack](https://webpack.github.io/) + [babel](http://babeljs.io/), configure the [babel-loader](https://github.com/babel/babel-loader) in the module settings of webpack, then you can use ES6+ to write your web program.
* [https://unpkg.com/omix@1.2.9/dist/omix.min.js](https://unpkg.com/omix@1.2.9/dist/omix.min.js)
* [https://unpkg.com/omix@1.2.9/dist/omix.js](https://unpkg.com/omix@1.2.9/dist/omix.js)
* [[Hello World ES6+ ->Try it on Playground]](http://alloyteam.github.io/omi/website/redirect.html?type=hello_nest)
* [[Hello World ES5 ->Try it on Playground]](http://alloyteam.github.io/omi/website/redirect.html?type=hello_es5)
if using 'omi.lite.js' (without [mustache.js](https://github.com/janl/mustache.js)), you can [use the ${this.data.name} way](http://alloyteam.github.io/omi/website/redirect.html?type=without_tpl)
## Plugins
## CDN
* [https://unpkg.com/omi@1.7.5/dist/omi.min.js](https://unpkg.com/omi@1.7.5/dist/omi.min.js)
* [https://unpkg.com/omi@1.7.5/dist/omi.js](https://unpkg.com/omi@1.7.5/dist/omi.js)
* [https://unpkg.com/omi@1.7.5/dist/omi.art.min.js](https://unpkg.com/omi@1.7.5/dist/omi.art.min.js)
* [https://unpkg.com/omi@1.7.5/dist/omi.art.js](https://unpkg.com/omi@1.7.5/dist/omi.art.js)
* [https://unpkg.com/omi@1.7.5/dist/omi.lite.min.js](https://unpkg.com/omi@1.7.5/dist/omi.lite.min.js)
* [https://unpkg.com/omi@1.7.5/dist/omi.lite.js](https://unpkg.com/omi@1.7.5/dist/omi.lite.js)
* [https://unpkg.com/omi@1.7.5/dist/omi.mustache.min.js](https://unpkg.com/omi@1.7.5/dist/omi.mustache.min.js)
* [https://unpkg.com/omi@1.7.5/dist/omi.mustache.js](https://unpkg.com/omi@1.7.5/dist/omi.mustache.js)
## Thanks
* [morphdom](https://github.com/patrick-steele-idem/morphdom) - Fast and lightweight DOM diffing/patching (no virtual DOM needed)
* [art-template](https://github.com/aui/art-template) - JS template engine with excellent performance
* [sodajs](https://github.com/AlloyTeam/sodajs) - Light weight but powerful template engine for JavaScript
* [mustache.js](https://github.com/janl/mustache.js) - Minimal templating with {{mustaches}} in JavaScript
## Thanks to [omi contributors](https://github.com/AlloyTeam/omi/graphs/contributors)
* [omi-tap](https://github.com/AlloyTeam/omix/tree/master/plugins/omi-tap): Support tap event in your Omi project..
* [omi-router](https://github.com/AlloyTeam/omix/tree/master/plugins/omi-router): Router for Omi.
* [omi-finger](https://github.com/AlloyTeam/omix/tree/master/plugins/omi-finger): Omi /[AlloyFinger](https://github.com/AlloyTeam/AlloyFinger) integration.
* [omi-transform](https://github.com/AlloyTeam/omix/tree/master/plugins/omi-transform): Omi /[transformjs](https://alloyteam.github.io/AlloyTouch/transformjs/) integration.
* [omi-touch](https://github.com/AlloyTeam/omix/tree/master/plugins/omi-touch): Omi /[AlloyTouch](https://github.com/AlloyTeam/AlloyTouch) integration.
# License
This content is released under the [MIT](http://opensource.org/licenses/MIT) License.

View File

@ -1,116 +0,0 @@
<p align="center">
<a href ="##"><img alt="Omi" src="http://images2015.cnblogs.com/blog/105416/201701/105416-20170120114244046-622856943.png"></a>
</p>
<p align="center">
Open and modern framework for building user interfaces.
</p>
<p align="center">
<a href="https://travis-ci.org/AlloyTeam/omi"><img src="https://travis-ci.org/AlloyTeam/omi.svg"></a>
<a href="https://www.npmjs.com/package/omi"><img src="https://img.shields.io/npm/v/omi.svg" alt="Version"></a>
<a href="https://www.npmjs.com/package/omi"><img src="https://img.shields.io/npm/dm/omi.svg" alt="Download"></a>
<a href="CONTRIBUTING.md"><img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg" alt="PRs"></a>
</p>
[English README](README.md)
## 中文
* [Omi 官网](http://www.omijs.org)
* [Omi Cli](https://github.com/AlloyTeam/omi-cli) 和 [Cli 指南](https://github.com/AlloyTeam/omi-cli#用户指南)
* [Omi Playground](http://alloyteam.github.io/omi/example/playground/)
* [Omi 文档](https://github.com/AlloyTeam/omi/blob/master/tutorial/all.md)
* [Omi 教程](https://github.com/AlloyTeam/omi/tree/master/tutorial#omi-相关文章)
* [New issue](https://github.com/AlloyTeam/omi/issues/new)
* 如果想更加方便的交流关于Omi的一切可以加入QQ的Omi交流群(256426170)
## 命令行
```bash
$ npm install omi-cli -g # 安装cli
$ omi init your_project_name # 初始化项目,你也可以在一个空的文件夹下执行 omi init
$ cd your_project_name # 如果你是在空文件夹下执行的 omi init。请无视这条命令
$ npm start                  # 开发
$ npm run dist # 部署发布
```
当然omi-cli还有一个特殊命令:
```bash
$ npm run ie # 用于生成未压缩js的发布包用来定位ie8的问题
```
## 特性
* 超小的尺寸7 kb (gzip)
* 完全面向对象的组件体系
* 局部CSSHTML+ Scoped CSS + JS组成可复用的组件
* 更自由的更新每个组件都有update方法自由选择时机进行更新
* 模板引擎可替换开发者可以重写Omi.template方法来使用任意模板引擎
* 提供了ES6+和ES5的两种开发方案供开发者自由选择
* 良好的兼容性支持IE8
* omi.art.js和omi.lite.js以及omi.mustache.js兼容到IE8
* omi.js 兼容到IE9
* 兼容IE8请自行引用 es5-shim 或 [es5-sham](//s.url.cn/qqun/xiaoqu/buluo/p/js/es5-sham-es5-sham.min.77c4325f.js) 和 [console-polyfill](//s.url.cn/qqun/xiaoqu/buluo/p/js/console-polyfill.min.848060c4.js),比如:
```html
<!--[if lt IE 9]><script type="text/javascript" crossorigin="anonymous" src="//s.url.cn/qqun/xiaoqu/buluo/p/js/console-polyfill.min.848060c4.js"></script>
<script type="text/javascript" crossorigin="anonymous" src="//s.url.cn/qqun/xiaoqu/buluo/p/js/es5-sham-es5-sham.min.77c4325f.js"></script><![endif]-->
```
## 插件
* [omi-router](https://github.com/AlloyTeam/omi/tree/master/plugins/omi-router): Omi专属的官方Router插件.
* [omi-finger](https://github.com/AlloyTeam/omi/tree/master/plugins/omi-finger): Omi的[AlloyFinger](https://github.com/AlloyTeam/AlloyFinger)插件,支持各种触摸事件和手势
* [omi-transform](https://github.com/AlloyTeam/omi/tree/master/plugins/omi-transform): Omi的[transformjs](https://alloyteam.github.io/AlloyTouch/transformjs/)插件快速方便地设置DOM的CSS3 Transform属性
* [omi-touch](https://github.com/AlloyTeam/omi/tree/master/plugins/omi-touch): Omi的[AlloyTouch](https://github.com/AlloyTeam/AlloyTouch)插件Omi项目的触摸运动解决方案支持触摸滚动、旋转、翻页、选择等等
* [omi-jquery-date-picker](https://github.com/AlloyTeam/omi/tree/master/plugins/omi-jquery-date-picker): Omi的时间选择插件支持各种时间或者时间区域选择
## 通过npm安装
```bash
$ npm install omi
```
## Hello World
你可以使用 [webpack](https://webpack.github.io/) + [babel](http://babeljs.io/)在webpack配置的module设置[babel-loader](https://github.com/babel/babel-loader)立马就能使用ES6+来编写你的web程序。
* [[Hello World ES6+ ->在线试试]](http://alloyteam.github.io/omi/website/redirect.html?type=hello_nest)
* [[Hello World ES5 ->在线试试]](http://alloyteam.github.io/omi/website/redirect.html?type=hello_es5)
如果使用omi.lite.js版本(不包含[mustache.js](https://github.com/janl/mustache.js)模板引擎)的话,也可以[使用 ${this.data.name} 的方式](http://alloyteam.github.io/omi/website/redirect.html?type=without_tpl)。
## CDN
* [https://unpkg.com/omi@1.7.5/dist/omi.min.js](https://unpkg.com/omi@1.7.5/dist/omi.min.js)
* [https://unpkg.com/omi@1.7.5/dist/omi.js](https://unpkg.com/omi@1.7.5/dist/omi.js)
* [https://unpkg.com/omi@1.7.5/dist/omi.art.min.js](https://unpkg.com/omi@1.7.5/dist/omi.art.min.js)
* [https://unpkg.com/omi@1.7.5/dist/omi.art.js](https://unpkg.com/omi@1.7.5/dist/omi.art.js)
* [https://unpkg.com/omi@1.7.5/dist/omi.lite.min.js](https://unpkg.com/omi@1.7.5/dist/omi.lite.min.js)
* [https://unpkg.com/omi@1.7.5/dist/omi.lite.js](https://unpkg.com/omi@1.7.5/dist/omi.lite.js)
* [https://unpkg.com/omi@1.7.5/dist/omi.mustache.min.js](https://unpkg.com/omi@1.7.5/dist/omi.mustache.min.js)
* [https://unpkg.com/omi@1.7.5/dist/omi.mustache.js](https://unpkg.com/omi@1.7.5/dist/omi.mustache.js)
## 感谢
* [morphdom](https://github.com/patrick-steele-idem/morphdom) - Fast and lightweight DOM diffing/patching (no virtual DOM needed)
* [art-template](https://github.com/aui/art-template) - JS template engine with excellent performance
* [sodajs](https://github.com/AlloyTeam/sodajs) - Light weight but powerful template engine for JavaScript
* [mustache.js](https://github.com/janl/mustache.js) - Minimal templating with {{mustaches}} in JavaScript
## Contributors
|name |avatars |company |
|---|---|---|
| [CodeFalling](https://github.com/CodeFalling) | ![](https://avatars3.githubusercontent.com/u/5436704?v=3&s=60) | alibaba |
| [abell123456](https://github.com/abell123456) | ![](https://avatars1.githubusercontent.com/u/2232380?v=3&s=60) | alibaba |
| [Aresn](https://github.com/icarusion) | ![](https://avatars3.githubusercontent.com/u/5370542?v=3&s=60) | TalkingCoder |
| [pasturn](https://github.com/pasturn) | ![](https://avatars2.githubusercontent.com/u/6126885?v=3&s=60) | Mars Holding |
| [vorshen](https://github.com/vorshen) | ![](https://avatars2.githubusercontent.com/u/10334783?v=3&s=60) | Tencent |
| [xcatliu](https://github.com/xcatliu) | ![](https://avatars3.githubusercontent.com/u/5453359?v=3&s=60) | Microsoft |
| [dorsywang](https://github.com/dorsywang) | ![](https://avatars3.githubusercontent.com/u/7475208?v=3&s=60) | Tencent |
| [dntzhang](https://github.com/dntzhang) | ![](https://avatars2.githubusercontent.com/u/7917954?v=3&s=60) | Tencent |
# License
[MIT](http://opensource.org/licenses/MIT)

View File

@ -1,31 +0,0 @@
var fs = require("fs");
var data = fs.readFileSync("./dist/omi.js","utf-8");
var head = "\
/*!\r\n\
* Omi v0.1.0 By dntzhang\r\n\
* Github: https://github.com/AlloyTeam/omi\r\n\
* MIT Licensed.\r\n\
*/\r\n\
(function webpackUniversalModuleDefinition(root, factory) {\r\n\
if(typeof exports === 'object' && typeof module === 'object')\r\n\
module.exports = global.document ?\r\n\
factory( global, true ) :\r\n\
function( w ) {\r\n\
if ( !w.document ) {\r\n\
throw new Error( 'Omi requires a window with a document' );\r\n\
}\r\n\
return factory( w );\r\n\
};\r\n\
else if(typeof define === 'function' && define.amd)\r\n\
define('Omi', [], factory);\r\n\
else if(typeof exports === 'object')\r\n\
exports['Omi'] = factory();\r\n\
else\r\n\
root['Omi'] = factory();\r\n\
})(typeof window !== 'undefined' ? window : this, function( window, noGlobal ) {\r\n\
var document = window.document;\r\n\
";
fs.writeFileSync("./dist/omi.server.js",head+data.replace( data.split("return")[0],""));

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.7 KiB

View File

@ -1,99 +0,0 @@
/*
Original highlight.js style (c) Ivan Sagalaev <maniac@softwaremaniacs.org>
*/
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
background: #F0F0F0;
}
/* Base color: saturation 0; */
.hljs,
.hljs-subst {
color: #444;
}
.hljs-comment {
color: #888888;
}
.hljs-keyword,
.hljs-attribute,
.hljs-selector-tag,
.hljs-meta-keyword,
.hljs-doctag,
.hljs-name {
font-weight: bold;
}
/* User color: hue: 0 */
.hljs-type,
.hljs-string,
.hljs-number,
.hljs-selector-id,
.hljs-selector-class,
.hljs-quote,
.hljs-template-tag,
.hljs-deletion {
color: #880000;
}
.hljs-title,
.hljs-section {
color: #880000;
font-weight: bold;
}
.hljs-regexp,
.hljs-symbol,
.hljs-variable,
.hljs-template-variable,
.hljs-link,
.hljs-selector-attr,
.hljs-selector-pseudo {
color: #BC6060;
}
/* Language color: hue: 90; */
.hljs-literal {
color: #78A960;
}
.hljs-built_in,
.hljs-bullet,
.hljs-code,
.hljs-addition {
color: #397300;
}
/* Meta color: hue: 200 */
.hljs-meta {
color: #1f7199;
}
.hljs-meta-string {
color: #4d99bf;
}
/* Misc effects */
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}

File diff suppressed because one or more lines are too long

View File

@ -1,223 +0,0 @@
/*!
* reveal-code-focus 1.0.0
* Copyright 2015-2017 Benjamin Tan <https://demoneaux.github.io/>
* Available under MIT license <https://github.com/demoneaux/reveal-code-focus/blob/master/LICENSE>
*/
;(function(window, Reveal, hljs) {
if (typeof window.RevealCodeFocus == 'function') {
return;
}
var currentSlide, currentFragments, scrollToFocused = true, prevSlideData = null;
// Iterates through `array`, running `callback` for each `array` element.
function forEach(array, callback) {
var i = -1, length = array ? array.length : 0;
while (++i < length) {
callback(array[i]);
}
}
function indexOf(array, elem) {
var i = -1, length = array ? array.length : 0;
while (++i < length) {
if (array[i] === elem) {
return i;
}
}
}
function initialize(e) {
// Initialize code only once.
// TODO: figure out why `initialize` is being called twice.
if (initialize.ran) {
return;
}
initialize.ran = true;
// TODO: mark as parsed.
forEach(document.querySelectorAll('pre code'), function(element) {
// Trim whitespace if the `data-trim` attribute is present.
if (element.hasAttribute('data-trim') && typeof element.innerHTML.trim == 'function') {
element.innerHTML = element.innerHTML.trim();
}
// Highlight code using highlight.js.
hljs.highlightBlock(element);
// Split highlighted code into lines.
var openTags = [], reHtmlTag = /<(\/?)span(?:\s+(?:class=(['"])hljs-.*?\2)?\s*|\s*)>/g;
element.innerHTML = element.innerHTML.replace(/(.*?)\r?\n/g, function(_, string) {
if (!string) {
return '<span class=line>&nbsp;</span>';
}
var openTag, stringPrepend;
// Re-open all tags that were previously closed.
if (openTags.length) {
stringPrepend = openTags.join('');
}
// Match all HTML `<span>` tags.
reHtmlTag.lastIndex = 0;
while (openTag = reHtmlTag.exec(string)) {
// If it is a closing tag, remove the opening tag from the list.
if (openTag[1]) {
openTags.pop();
}
// Otherwise if it is an opening tag, push it to the list.
else {
openTags.push(openTag[0]);
}
}
// Close all opened tags, so that strings can be wrapped with `span.line`.
if (openTags.length) {
string += Array(openTags.length + 1).join('</span>');
}
if (stringPrepend) {
string = stringPrepend + string;
}
return '<span class=line>' + string + '</span>';
});
});
Reveal.addEventListener('slidechanged', updateCurrentSlide);
Reveal.addEventListener('fragmentshown', function(e) {
focusFragment(e.fragment);
});
// TODO: make this configurable.
// When a fragment is hidden, clear the current focused fragment,
// and focus on the previous fragment.
Reveal.addEventListener('fragmenthidden', function(e) {
var index = indexOf(currentFragments, e.fragment);
focusFragment(currentFragments[index - 1]);
});
updateCurrentSlide(e);
}
initialize.ran = false;
function updateCurrentSlide(e) {
currentSlide = e.currentSlide;
currentFragments = currentSlide.getElementsByClassName('fragment');
clearPreviousFocus();
// If moving back to a previous slide¡­
if (
currentFragments.length &&
prevSlideData &&
(
prevSlideData.indexh > e.indexh ||
(prevSlideData.indexh == e.indexh && prevSlideData.indexv > e.indexv)
)
) {
// ¡­return to the last fragment and highlight the code.
while (Reveal.nextFragment()) {}
var currentFragment = currentFragments[currentFragments.length - 1];
currentFragment.classList.add('current-fragment');
focusFragment(currentFragment);
}
// Update previous slide information.
prevSlideData = {
'indexh': e.indexh,
'indexv': e.indexv
};
}
// Removes any previously focused lines.
function clearPreviousFocus() {
forEach(currentSlide.querySelectorAll('pre code .line.focus'), function(line) {
line.classList.remove('focus');
});
}
function focusFragment(fragment) {
clearPreviousFocus();
if (!fragment) {
return;
}
var lines = fragment.getAttribute('data-code-focus');
if (!lines) {
return;
}
var codeBlock = parseInt(fragment.getAttribute('data-code-block'));
if (isNaN(codeBlock)) {
codeBlock = 1;
}
var code = currentSlide.querySelectorAll('pre:nth-of-type(' + codeBlock + ') code .line');
if (!code) {
return;
}
var topLineNumber, bottomLineNumber;
forEach(lines.split(','), function(line) {
lines = line.split('-');
if (lines.length == 1) {
focusLine(lines[0]);
} else {
var i = lines[0] - 1, j = lines[1];
while (++i <= j) {
focusLine(i);
}
}
});
function focusLine(lineNumber) {
// Convert from 1-based index to 0-based index.
lineNumber -= 1;
var line = code[lineNumber];
if (!line) {
return;
}
line.classList.add('focus');
if (scrollToFocused) {
if (topLineNumber == null) {
topLineNumber = bottomLineNumber = lineNumber;
} else {
if (lineNumber < topLineNumber) {
topLineNumber = lineNumber;
}
if (lineNumber > bottomLineNumber) {
bottomLineNumber = lineNumber;
}
}
}
}
if (scrollToFocused && topLineNumber != null) {
var topLine = code[topLineNumber];
var bottomLine = code[bottomLineNumber];
var codeParent = topLine.parentNode;
var scrollTop = topLine.offsetTop;
var scrollBottom = bottomLine.offsetTop + bottomLine.clientHeight;
codeParent.scrollTop = scrollTop - (codeParent.clientHeight - (scrollBottom - scrollTop)) / 2;
}
}
function RevealCodeFocus(options) {
options || (options = {
'scrollToFocused': true
});
if (options.scrollToFocused != null) {
scrollToFocused = options.scrollToFocused;
}
if (Reveal.isReady()) {
initialize({ 'currentSlide': Reveal.getCurrentSlide() });
} else {
Reveal.addEventListener('ready', initialize);
}
}
window.RevealCodeFocus = RevealCodeFocus;
}(this, this.Reveal, this.hljs));

View File

@ -1,83 +0,0 @@
/*
Monokai Sublime style. Derived from Monokai by noformnocontent http://nn.mit-license.org/
*/
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
background: #23241f;
}
.hljs,
.hljs-tag,
.hljs-subst {
color: #f8f8f2;
}
.hljs-strong,
.hljs-emphasis {
color: #a8a8a2;
}
.hljs-bullet,
.hljs-quote,
.hljs-number,
.hljs-regexp,
.hljs-literal,
.hljs-link {
color: #ae81ff;
}
.hljs-code,
.hljs-title,
.hljs-section,
.hljs-selector-class {
color: #a6e22e;
}
.hljs-strong {
font-weight: bold;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-name,
.hljs-attr {
color: #f92672;
}
.hljs-symbol,
.hljs-attribute {
color: #66d9ef;
}
.hljs-params,
.hljs-class .hljs-title {
color: #f8f8f2;
}
.hljs-string,
.hljs-type,
.hljs-built_in,
.hljs-builtin-name,
.hljs-selector-id,
.hljs-selector-attr,
.hljs-selector-pseudo,
.hljs-addition,
.hljs-variable,
.hljs-template-variable {
color: #e6db74;
}
.hljs-comment,
.hljs-deletion,
.hljs-meta {
color: #75715e;
}

View File

@ -1,119 +0,0 @@
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<link rel="stylesheet" href="monokai-sublime.css">
<style>
.line {
display: block;
}
</style>
</head>
<body>
<pre omi_scoped_2=""><code omi_scoped_2="" class="language-js hll-22_1-5">class Todo extends Omi.Component {
constructor(data) {
super(data);
}
add (evt) {
evt.preventDefault();
this.data.items.push(this.data.text);
this.data.text = '';
this.update();
}
style () {
return `
h3 { color:red; }
button{ color:green;}
`;
}
handleChange(target){
this.data.text = target.value;
}
Omi.render(new Todo({ items: [] ,text : '' }),"body");
</code></pre>
<script src="highlight.pack.js"></script>
<script>
// Iterates through `array`, running `callback` for each `array` element.
function forEach(array, callback) {
var i = -1, length = array ? array.length : 0;
while (++i < length) {
callback(array[i]);
}
}
function indexOf(array, elem) {
var i = -1, length = array ? array.length : 0;
while (++i < length) {
if (array[i] === elem) {
return i;
}
}
}
function initialize() {
// Initialize code only once.
// TODO: figure out why `initialize` is being called twice.
if (initialize.ran) {
return;
}
initialize.ran = true;
// TODO: mark as parsed.
forEach(document.querySelectorAll('pre code'), function(element) {
// Trim whitespace if the `data-trim` attribute is present.
if (element.hasAttribute('data-trim') && typeof element.innerHTML.trim == 'function') {
element.innerHTML = element.innerHTML.trim();
}
// Highlight code using highlight.js.
hljs.highlightBlock(element);
// Split highlighted code into lines.
var openTags = [], reHtmlTag = /<(\/?)span(?:\s+(?:class=(['"])hljs-.*?\2)?\s*|\s*)>/g;
element.innerHTML = element.innerHTML.replace(/(.*?)\r?\n/g, function(_, string) {
if (!string) {
return '<span class=line>&nbsp;</span>';
}
var openTag, stringPrepend;
// Re-open all tags that were previously closed.
if (openTags.length) {
stringPrepend = openTags.join('');
}
// Match all HTML `<span>` tags.
reHtmlTag.lastIndex = 0;
while (openTag = reHtmlTag.exec(string)) {
// If it is a closing tag, remove the opening tag from the list.
if (openTag[1]) {
openTags.pop();
}
// Otherwise if it is an opening tag, push it to the list.
else {
openTags.push(openTag[0]);
}
}
// Close all opened tags, so that strings can be wrapped with `span.line`.
if (openTags.length) {
string += Array(openTags.length + 1).join('</span>');
}
if (stringPrepend) {
string = stringPrepend + string;
}
return '<span class=line>' + string + '</span>';
});
});
}
initialize();
</script>
<script>
hljs.highlightBlock(document.querySelector('code'))
</script>
</body>
</html>

View File

@ -1,251 +0,0 @@
<script>
/*
* html2json for omi
* https://github.com/AlloyTeam/omi
*
* Original code by John Resig (ejohn.org)
* http://ejohn.org/blog/pure-javascript-html-parser/
* Original code by Erik Arvidsson, Mozilla Public License
* http://erik.eae.net/simplehtmlparser/simplehtmlparser.js
* Original code by Jxck
* https://github.com/Jxck/html2json
*/
(function(global) {
// Regular Expressions for parsing tags and attributes
var startTag = /^<([-A-Za-z0-9_]+)((?:\s+[a-zA-Z_:][-a-zA-Z0-9_:.]*(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>/,
endTag = /^<\/([-A-Za-z0-9_]+)[^>]*>/,
attr = /([a-zA-Z_:][-a-zA-Z0-9_:.]*)(?:\s*=\s*(?:(?:"((?:\\.|[^"])*)")|(?:'((?:\\.|[^'])*)')|([^>\s]+)))?/g;
var HTMLParser = function (html, handler) {
var index, chars, match, stack = [], last = html;
stack.last = function () {
return this[this.length - 1];
};
while (html) {
chars = true;
// Make sure we're not in a script or style element
if (!stack.last() ) {
if (html.indexOf("</") == 0) {
match = html.match(endTag);
if (match) {
html = html.substring(match[0].length);
match[0].replace(endTag, parseEndTag);
chars = false;
}
// start tag
} else if (html.indexOf("<") == 0) {
match = html.match(startTag);
if (match) {
html = html.substring(match[0].length);
match[0].replace(startTag, parseStartTag);
chars = false;
}
}
if (chars) {
index = html.indexOf("<");
var text = index < 0 ? html : html.substring(0, index);
html = index < 0 ? "" : html.substring(index);
if (handler.chars)
handler.chars(text);
}
} else {
html = html.replace(new RegExp("([\\s\\S]*?)<\/" + stack.last() + "[^>]*>"), function (all, text) {
if (handler.chars)
handler.chars(text);
return "";
});
parseEndTag("", stack.last());
}
if (html == last)
throw "Parse Error: " + html;
last = html;
}
// Clean up any remaining tags
parseEndTag();
function parseStartTag(tag, tagName, rest, unary) {
tagName = tagName.toLowerCase();
unary = !!unary;
if (!unary)
stack.push(tagName);
if (handler.start) {
var attrs = [];
rest.replace(attr, function (match, name) {
var value = arguments[2] ? arguments[2] :
arguments[3] ? arguments[3] :
arguments[4] ? arguments[4] :"";
attrs.push({
name: name,
value: value,
escaped: value.replace(/(^|[^\\])"/g, '$1\\\"') //"
});
});
if (handler.start)
handler.start(tagName, attrs, unary);
}
}
function parseEndTag(tag, tagName) {
// If no tag name is provided, clean shop
if (!tagName)
var pos = 0;
// Find the closest opened tag of the same type
else
for (var pos = stack.length - 1; pos >= 0; pos--)
if (stack[pos] == tagName)
break;
if (pos >= 0) {
// Close all the open elements, up the stack
for (var i = stack.length - 1; i >= pos; i--)
if (handler.end)
handler.end(stack[i]);
// Remove the open elements from the stack
stack.length = pos;
}
}
};
var DEBUG = false;
var debug = DEBUG ? console.log.bind(console) : function(){};
// Production steps of ECMA-262, Edition 5, 15.4.4.21
// Reference: http://es5.github.io/#x15.4.4.21
if (!Array.prototype.reduce) {
Array.prototype.reduce = function(callback /*, initialValue*/) {
'use strict';
if (this == null) {
throw new TypeError('Array.prototype.reduce called on null or undefined');
}
if (typeof callback !== 'function') {
throw new TypeError(callback + ' is not a function');
}
var t = Object(this), len = t.length >>> 0, k = 0, value;
if (arguments.length == 2) {
value = arguments[1];
} else {
while (k < len && !(k in t)) {
k++;
}
if (k >= len) {
throw new TypeError('Reduce of empty array with no initial value');
}
value = t[k++];
}
for (; k < len; k++) {
if (k in t) {
value = callback(value, t[k], k, t);
}
}
return value;
};
}
global.html2json = function html2json(html) {
var bufArray = [];
var results = {
node: 'root',
child: [],
};
HTMLParser(html, {
start: function(tag, attrs, unary) {
debug(tag, attrs, unary);
// node for this element
var node = {
node: 'element',
tag: tag,
};
if (attrs.length !== 0) {
node.attr = attrs.reduce(function(pre, attr) {
var name = attr.name;
var value = attr.value;
pre[name] = value;
return pre;
}, {});
}
if (unary) {
// if this tag dosen't have end tag
// like <img src="hoge.png"/>
// add to parents
var parent = bufArray[0] || results;
if (parent.child === undefined) {
parent.child = [];
}
parent.child.push(node);
} else {
bufArray.unshift(node);
}
},
end: function(tag) {
debug(tag);
// merge into parent tag
var node = bufArray.shift();
if (node.tag !== tag) console.error('invalid state: mismatch end tag');
if (bufArray.length === 0) {
results.child.push(node);
} else {
var parent = bufArray[0];
if (parent.child === undefined) {
parent.child = [];
}
parent.child.push(node);
}
},
chars: function(text) {
debug(text);
var node = {
node: 'text',
text: text,
};
if (bufArray.length === 0) {
results.child.push(node);
} else {
var parent = bufArray[0];
if (parent.child === undefined) {
parent.child = [];
}
parent.child.push(node);
}
}
});
return results;
};
})(this);
</script>
<script>
var json = html2json('<child tag="Hello2" data-ame="imSDFgsrc sfd" sfdsf data-amesd="22" >sd</child><c2 />')
alert(JSON.stringify( json)==='{"node":"root","child":[{"node":"element","tag":"child","attr":{"tag":"Hello2","data-ame":"imSDFgsrc sfd","sfdsf":"","data-amesd":"22"},"child":[{"node":"text","text":"sd"}]},{"node":"element","tag":"c2"}]}')
</script>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 193 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

View File

@ -1,13 +1,125 @@
## v1.7.5
# omix v1.2.8
* 再次修复 select 选中的问题, `option.setAttribute('selected', 'selected')` 改成 `option.selected = true`
* 优化了组件的复用
## v1.7.4
# omix v1.2.8
* 再次修复 组件 update 时候新加的组件 installed 方法不执行的问题
* fix Text 的 bug
## v1.7.3
# omix v1.2.7
* 支持 o-autofocus='{{xxx?"":""}}' 、o-checked='{{xxx?"":""}}' 等任意属性如果为null、空会自动移除该属性的特性
* 修复 组件 update 时候新加的组件 installed 方法不执行的问题
* 修复 scoped css 遇到 @-webkit-keyframe 替换的问题
* eslint fix
# omix v1.2.6
* fix 老的 IOS 9 和 10 下 style 为 readonly 的bug
# omix v1.2.5
* 代码精简
# omix v1.2.3
* 性能优化
# omix v1.2.2
* 解决 scoped style 相关问题
# omix v1.2.1
* 支持 store 系统,根节点注入 $store, 所有子节点都能共享。[例子](https://github.com/AlloyTeam/omix/tree/master/example/store)
# omix v1.2.0
* 使用 JSX 可以不用在写 Omi.tag(xx, xxx)
* 支持 在 JSX 中使用 JSON 格式的样式,或者数组。[例子](https://github.com/AlloyTeam/omix/blob/master/example/on/hello.js)
# omix v1.1.15
* 修复了事件 patch 之后没有移除的问题。
# omix v1.1.14
* 修复了 scoped attr 在组件更新之后没有移除的问题。
# omix v1.1.13
* 支持增量模式渲染
```
Omi.render(new App({ }, 'body', true))`
```
或者
```
Omi.render(new App({ }, 'body', {
increment : true
}))`
```
# omix v1.1.12
* 解决新加的组件 scoped attr 相互污染的问题
# omix v1.1.11
* 通过`closeScopedStyle`可以关闭局部CSS: 如:
```
Omi.render(new App({ closeScopedStyle : true }, '#ctn'))
```
或者
```
<your-tag closeScopedStyle></your-tag>
```
# omix v1.1.10
* 支持直出的数据前后端共享变更 - 以前使用input存数据改成直接暴露在`window.__omiSsrData`下
# omix v1.1.9
* node 环境不会执行 Omi.render
# omix v1.1.8
* 支持直出的数据前后端共享
* Omi.render 支持配置 ssr 代表二次渲染
```js
Omi.render(component, renderTo, { ssr : true })
```
# omix v1.1.7
* 美化 ssr css 输出格式
# omix v1.1.6
* fix node 环境 document 报错
* fix ssr 下,同类组件的 css 重复合成的问题
# omix v1.1.5
* fix node 环境 window 报错
# omix v1.1.4
* 新增 babel-preset-omi ,不再使用 virtual-dom-loader。 omi-cli 已经同步更新~~
* `Omi.renderToString` 支持服务器端渲染局部CSS
# omix v1.1.3
* 新增一种 hyperscript 方式
```js
$.tagName(selector, attrs, child, child, child ...)
```
# omix v1.1.2
* 新增了 `Omi.renderToString` 用于服务器端渲染

24
dist/README.md vendored
View File

@ -1,24 +0,0 @@
## 文件说明
### omi.js
UMD方式build你可以使用AMD、CommonJS或者Import导入使用。也可以在HTML里直接引用脚本使用
```js
<script src="omi.js"></script>
```
### omi.lite.js
不包含 mustache.js 模板引擎的 omi.js 。你可以重写 Omi.template 去使用任意模板引擎。
## Explanation of Build Files
### omi.js
The full UMD build.
### omi.lite.js
Same as omi.js but without mustache.js template engine.

3108
dist/omi.art.js vendored

File diff suppressed because it is too large Load Diff

8
dist/omi.art.min.js vendored

File diff suppressed because one or more lines are too long

3155
dist/omi.js vendored

File diff suppressed because it is too large Load Diff

2418
dist/omi.lite.js vendored

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

7
dist/omi.min.js vendored

File diff suppressed because one or more lines are too long

3040
dist/omi.mustache.js vendored

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

2574
dist/omi.server.js vendored

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +0,0 @@
/dist
/dev
/node_modules
/.idea
/rev

View File

@ -1,36 +0,0 @@
## [Docs All in One](https://github.com/AlloyTeam/omi/blob/master/tutorial/all.md)
### Usage
* [安装](./src/docs/cn/installation.md)
* [Hello World](./src/docs/cn/hello_world.md)
* [组件](./src/docs/cn/components.md)
* [组件通讯](./src/docs/cn/communication.md)
* [生命周期](./src/docs/cn/lifecycle.md)
* [Store体系](./src/docs/cn/store.md)
* [事件处理](./src/docs/cn/events.md)
* [条件判断](./src/docs/cn/condition.md)
* [循环遍历](./src/docs/cn/loop.md)
* [表单](./src/docs/cn/form.md)
* [继承](./src/docs/cn/inherit.md)
* [模板切换](./src/docs/cn/template.md)
* [获取DOM节点](./src/docs/cn/get_dom.md)
* [插件体系](./src/docs/cn/plugin.md)
* [Omi理念](./src/docs/cn/thinking_in_omi.md)
### Usage(en-us)
* [installation](./src/docs/en/installation.md)
* [Hello World](./src/docs/en/hello_world.md)
* [components](./src/docs/en/components.md)
* [communication](./src/docs/en/communication.md)
* [lifecycle](./src/docs/en/lifecycle.md)
* [events](./src/docs/en/events.md)
* [condition](./src/docs/en/condition.md)
* [loop](./src/docs/en/loop.md)
* [form](./src/docs/en/form.md)
* [inherit](./src/docs/en/inherit.md)
* [template](./src/docs/en/template.md)
* [get dom](./src/docs/en/get_dom.md)
* [plugin](./src/docs/en/plugin.md)
* [thinking_in_omi](./src/docs/en/thinking_in_omi.md)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

View File

@ -1,2 +0,0 @@
/*! @source http://purl.eligrey.com/github/classList.js/blob/master/classList.js */
"document"in self&&("classList"in document.createElement("_")&&(!document.createElementNS||"classList"in document.createElementNS("http://www.w3.org/2000/svg","g"))?!function(){"use strict";var t=document.createElement("_");if(t.classList.add("c1","c2"),!t.classList.contains("c2")){var e=function(t){var e=DOMTokenList.prototype[t];DOMTokenList.prototype[t]=function(t){var n,i=arguments.length;for(n=0;i>n;n++)t=arguments[n],e.call(this,t)}};e("add"),e("remove")}if(t.classList.toggle("c3",!1),t.classList.contains("c3")){var n=DOMTokenList.prototype.toggle;DOMTokenList.prototype.toggle=function(t,e){return 1 in arguments&&!this.contains(t)==!e?e:n.call(this,t)}}t=null}():!function(t){"use strict";if("Element"in t){var e="classList",n="prototype",i=t.Element[n],s=Object,r=String[n].trim||function(){return this.replace(/^\s+|\s+$/g,"")},o=Array[n].indexOf||function(t){for(var e=0,n=this.length;n>e;e++)if(e in this&&this[e]===t)return e;return-1},c=function(t,e){this.name=t,this.code=DOMException[t],this.message=e},a=function(t,e){if(""===e)throw new c("SYNTAX_ERR","An invalid or illegal string was specified");if(/\s/.test(e))throw new c("INVALID_CHARACTER_ERR","String contains an invalid character");return o.call(t,e)},l=function(t){for(var e=r.call(t.getAttribute("class")||""),n=e?e.split(/\s+/):[],i=0,s=n.length;s>i;i++)this.push(n[i]);this._updateClassName=function(){t.setAttribute("class",this.toString())}},u=l[n]=[],h=function(){return new l(this)};if(c[n]=Error[n],u.item=function(t){return this[t]||null},u.contains=function(t){return t+="",-1!==a(this,t)},u.add=function(){var t,e=arguments,n=0,i=e.length,s=!1;do t=e[n]+"",-1===a(this,t)&&(this.push(t),s=!0);while(++n<i);s&&this._updateClassName()},u.remove=function(){var t,e,n=arguments,i=0,s=n.length,r=!1;do for(t=n[i]+"",e=a(this,t);-1!==e;)this.splice(e,1),r=!0,e=a(this,t);while(++i<s);r&&this._updateClassName()},u.toggle=function(t,e){t+="";var n=this.contains(t),i=n?e!==!0&&"remove":e!==!1&&"add";return i&&this[i](t),e===!0||e===!1?e:!n},u.toString=function(){return this.join(" ")},s.defineProperty){var f={get:h,enumerable:!0,configurable:!0};try{s.defineProperty(i,e,f)}catch(d){void 0!==d.number&&-2146823252!==d.number||(f.enumerable=!1,s.defineProperty(i,e,f))}}else s[n].__defineGetter__&&i.__defineGetter__(e,h)}}(self));

File diff suppressed because one or more lines are too long

View File

@ -1 +0,0 @@
.hljs-comment,.hljs-quote{color:#8e908c}.hljs-deletion,.hljs-name,.hljs-regexp,.hljs-selector-class,.hljs-selector-id,.hljs-tag,.hljs-template-variable,.hljs-variable{color:#c82829}.hljs-built_in,.hljs-builtin-name,.hljs-link,.hljs-literal,.hljs-meta,.hljs-number,.hljs-params,.hljs-type{color:#f5871f}.hljs-attribute{color:#eab700}.hljs-addition,.hljs-bullet,.hljs-string,.hljs-symbol{color:#718c00}.hljs-section,.hljs-title{color:#4271ae}.hljs-keyword,.hljs-selector-tag{color:#8959a8}.hljs{display:block;overflow-x:auto;background:#fff;color:#4d4d4c}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}

View File

@ -1,72 +0,0 @@
/* http://jmblog.github.com/color-themes-for-google-code-highlightjs */
/* Tomorrow Comment */
.hljs-comment,
.hljs-quote {
color: #8e908c;
}
/* Tomorrow Red */
.hljs-variable,
.hljs-template-variable,
.hljs-tag,
.hljs-name,
.hljs-selector-id,
.hljs-selector-class,
.hljs-regexp,
.hljs-deletion {
color: #c82829;
}
/* Tomorrow Orange */
.hljs-number,
.hljs-built_in,
.hljs-builtin-name,
.hljs-literal,
.hljs-type,
.hljs-params,
.hljs-meta,
.hljs-link {
color: #f5871f;
}
/* Tomorrow Yellow */
.hljs-attribute {
color: #eab700;
}
/* Tomorrow Green */
.hljs-string,
.hljs-symbol,
.hljs-bullet,
.hljs-addition {
color: #718c00;
}
/* Tomorrow Blue */
.hljs-title,
.hljs-section {
color: #4271ae;
}
/* Tomorrow Purple */
.hljs-keyword,
.hljs-selector-tag {
color: #8959a8;
}
.hljs {
display: block;
overflow-x: auto;
background: white;
color: #4d4d4c;
/*padding: 0.5em;*/
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 193 B

View File

@ -1 +0,0 @@
body,html{background-color:#f9f9f9;font-family:proxima-nova,"Helvetica Neue",Helvetica,Roboto,PT Sans,DejaVu Sans,Arial,Segoe UI Light,Segoe UI,Microsoft Jhenghei,Mirco Yahei,'sans-serif';overflow-x:hidden}body,html,img,li,ul{margin:0;padding:0;border:0}li,ul{list-style:none}a{text-decoration:none}table{border-collapse:collapse}table,td,th{border:1px solid #ccc}@media only screen and (max-width:768px){.content img{width:100%}.content code[class*=language-],.content pre[class*=language-]{font-family:Consolas,"Liberation Mono",Courier,monospace;line-height:18px;font-size:12px;margin:0;width:100%;box-sizing:border-box}.content pre[class*=language-]{padding-left:10px}.content p{font-size:14px}.content h1,.content h2,.content h3,.content h4,.content h5,.content p{padding-left:10px;padding-right:10px}.line-highlight:before,.line-highlight[data-end]:after{top:0}}*{box-sizing:border-box}pre code.hljs{padding-left:14px;display:block;overflow-x:auto}.hljs{font-size:14px}code.hljs{display:inline-block;overflow-x:hidden;text-indent:0;position:relative;top:3px}.line.highlight{background-color:#f7ebc6;border-left:5px solid #f7d87c;display:block;margin-left:-14px;padding-left:9px}.line{display:block}

View File

@ -1,37 +0,0 @@
<!DOCTYPE html>
<html>
<head lang="zh">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0">
<title>Omi</title>
<link rel="shortcut icon" href="../asset/omi.ico">
<link rel="stylesheet" href="css/docs-d7bcd3f561.css">
<link rel="stylesheet" href="common/highlight/tomorrow-a2eb49c74d.css">
</head>
<body>
<!--[if lt IE 9]>
<script>
(function(){
document.body.innerHTML = "The docs website does not support IE8, IE7 and IE6...<br/>Please use modern browser!<br/>" +
"The website will redirect to GitHub after 3s."
setTimeout(function(){
window.location.href = 'https://github.com/AlloyTeam/omi';
},3000);
return;
})()
</script>
<![endif]-->
<!--[if IE 9]>
<script src="common/common/class_list.js"></script>
<![endif]-->
<script src="common/highlight/highlight.pack.js"></script>
<script src="common/remarkable.min.js"></script>
<script src="js/vendor.9506334d.js"></script>
<script src="js/omi.461a076c.js"></script>
<script src="js/docs-cn.c8b9fac0.js"></script>
</body>
</html>

View File

@ -1,38 +0,0 @@
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0">
<title>Omi</title>
<link rel="shortcut icon" href="../asset/omi.ico">
<link rel="stylesheet" href="css/docs-d7bcd3f561.css">
<link rel="stylesheet" href="common/highlight/tomorrow-a2eb49c74d.css">
</head>
<body>
<!--[if lt IE 9]>
<script>
(function(){
document.body.innerHTML = "The docs website does not support IE8, IE7 and IE6...<br/>Please use modern browser!<br/>" +
"The website will redirect to GitHub after 3s."
setTimeout(function(){
window.location.href = 'https://github.com/AlloyTeam/omi';
},3000);
return;
})()
</script>
<![endif]-->
<!--[if IE 9]>
<script src="common/common/class_list.js"></script>
<![endif]-->
<script src="common/highlight/highlight.pack.js"></script>
<script src="common/remarkable.min.js"></script>
<script src="js/vendor.9506334d.js"></script>
<script src="js/omi.461a076c.js"></script>
<script src="js/docs-en.efad4b02.js"></script>
</body>
</html>

View File

@ -1,13 +0,0 @@
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<script>
window.location.href='./docs-cn.html'
</script>
</head>
<body>
</body>
</html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -1,200 +0,0 @@
/******/ (function(modules) { // webpackBootstrap
/******/ // install a JSONP callback for chunk loading
/******/ var parentJsonpFunction = window["webpackJsonp"];
/******/ window["webpackJsonp"] = function webpackJsonpCallback(chunkIds, moreModules) {
/******/ // add "moreModules" to the modules object,
/******/ // then flag all "chunkIds" as loaded and fire callback
/******/ var moduleId, chunkId, i = 0, callbacks = [];
/******/ for(;i < chunkIds.length; i++) {
/******/ chunkId = chunkIds[i];
/******/ if(installedChunks[chunkId])
/******/ callbacks.push.apply(callbacks, installedChunks[chunkId]);
/******/ installedChunks[chunkId] = 0;
/******/ }
/******/ for(moduleId in moreModules) {
/******/ modules[moduleId] = moreModules[moduleId];
/******/ }
/******/ if(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules);
/******/ while(callbacks.length)
/******/ callbacks.shift().call(null, __webpack_require__);
/******/ if(moreModules[0]) {
/******/ installedModules[0] = 0;
/******/ return __webpack_require__(0);
/******/ }
/******/ };
/******/ // The module cache
/******/ var installedModules = {};
/******/ // object to store loaded and loading chunks
/******/ // "0" means "already loaded"
/******/ // Array means "loading", array contains callbacks
/******/ var installedChunks = {
/******/ 3:0
/******/ };
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId])
/******/ return installedModules[moduleId].exports;
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ exports: {},
/******/ id: moduleId,
/******/ loaded: false
/******/ };
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/ // Flag the module as loaded
/******/ module.loaded = true;
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/ // This file contains only the entry chunk.
/******/ // The chunk loading function for additional chunks
/******/ __webpack_require__.e = function requireEnsure(chunkId, callback) {
/******/ // "0" is the signal for "already loaded"
/******/ if(installedChunks[chunkId] === 0)
/******/ return callback.call(null, __webpack_require__);
/******/ // an array means "currently loading".
/******/ if(installedChunks[chunkId] !== undefined) {
/******/ installedChunks[chunkId].push(callback);
/******/ } else {
/******/ // start chunk loading
/******/ installedChunks[chunkId] = [callback];
/******/ var head = document.getElementsByTagName('head')[0];
/******/ var script = document.createElement('script');
/******/ script.type = 'text/javascript';
/******/ script.charset = 'utf-8';
/******/ script.async = true;
/******/ script.src = __webpack_require__.p + "" + chunkId + "." + ({"0":"docs-cn","1":"docs-en","2":"omi"}[chunkId]||chunkId) + "." + {"0":"c8b9fac0","1":"efad4b02","2":"461a076c"}[chunkId] + ".js";
/******/ head.appendChild(script);
/******/ }
/******/ };
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/ // Load entry module and return exports
/******/ return __webpack_require__(0);
/******/ })
/************************************************************************/
/******/ ({
/***/ 0:
/***/ function(module, exports, __webpack_require__) {
module.exports = __webpack_require__(51);
/***/ },
/***/ 51:
/***/ function(module, exports) {
"use strict";
/*! @source http://purl.eligrey.com/github/classList.js/blob/master/classList.js */
"document" in self && ("classList" in document.createElement("_") && (!document.createElementNS || "classList" in document.createElementNS("http://www.w3.org/2000/svg", "g")) ? !function () {
"use strict";
var t = document.createElement("_");if (t.classList.add("c1", "c2"), !t.classList.contains("c2")) {
var e = function e(t) {
var e = DOMTokenList.prototype[t];DOMTokenList.prototype[t] = function (t) {
var n,
i = arguments.length;for (n = 0; i > n; n++) {
t = arguments[n], e.call(this, t);
}
};
};e("add"), e("remove");
}if (t.classList.toggle("c3", !1), t.classList.contains("c3")) {
var n = DOMTokenList.prototype.toggle;DOMTokenList.prototype.toggle = function (t, e) {
return 1 in arguments && !this.contains(t) == !e ? e : n.call(this, t);
};
}t = null;
}() : !function (t) {
"use strict";
if ("Element" in t) {
var e = "classList",
n = "prototype",
i = t.Element[n],
s = Object,
r = String[n].trim || function () {
return this.replace(/^\s+|\s+$/g, "");
},
o = Array[n].indexOf || function (t) {
for (var e = 0, n = this.length; n > e; e++) {
if (e in this && this[e] === t) return e;
}return -1;
},
c = function c(t, e) {
this.name = t, this.code = DOMException[t], this.message = e;
},
a = function a(t, e) {
if ("" === e) throw new c("SYNTAX_ERR", "An invalid or illegal string was specified");if (/\s/.test(e)) throw new c("INVALID_CHARACTER_ERR", "String contains an invalid character");return o.call(t, e);
},
l = function l(t) {
for (var e = r.call(t.getAttribute("class") || ""), n = e ? e.split(/\s+/) : [], i = 0, s = n.length; s > i; i++) {
this.push(n[i]);
}this._updateClassName = function () {
t.setAttribute("class", this.toString());
};
},
u = l[n] = [],
h = function h() {
return new l(this);
};if (c[n] = Error[n], u.item = function (t) {
return this[t] || null;
}, u.contains = function (t) {
return t += "", -1 !== a(this, t);
}, u.add = function () {
var t,
e = arguments,
n = 0,
i = e.length,
s = !1;do {
t = e[n] + "", -1 === a(this, t) && (this.push(t), s = !0);
} while (++n < i);s && this._updateClassName();
}, u.remove = function () {
var t,
e,
n = arguments,
i = 0,
s = n.length,
r = !1;do {
for (t = n[i] + "", e = a(this, t); -1 !== e;) {
this.splice(e, 1), r = !0, e = a(this, t);
}
} while (++i < s);r && this._updateClassName();
}, u.toggle = function (t, e) {
t += "";var n = this.contains(t),
i = n ? e !== !0 && "remove" : e !== !1 && "add";return i && this[i](t), e === !0 || e === !1 ? e : !n;
}, u.toString = function () {
return this.join(" ");
}, s.defineProperty) {
var f = { get: h, enumerable: !0, configurable: !0 };try {
s.defineProperty(i, e, f);
} catch (d) {
void 0 !== d.number && -2146823252 !== d.number || (f.enumerable = !1, s.defineProperty(i, e, f));
}
} else s[n].__defineGetter__ && i.__defineGetter__(e, h);
}
}(self));
/***/ }
/******/ });

View File

@ -1,164 +0,0 @@
var del = require('del'),
gulp = require('gulp'),
csso = require('gulp-csso'),
webpack = require('webpack-stream'),
runSequence = require('run-sequence'),
htmlreplace = require('gulp-html-replace'),
rev = require('gulp-rev'),
revCollector = require('gulp-rev-collector'),
header = require('gulp-header'),
browserSync = require('browser-sync').create(),
config = require('./project.js'),
urlPrefix = require('gulp-html-url-prefix');
var assets = [],
cdn = config.cdn,
ENV = process.env.npm_lifecycle_event;
gulp.task('clean', function(callback) {
del.sync([ENV+'/**/**']);
callback();
});
var webpackConfig = require('./webpack.config.js');
var isDist = ENV ==='dist';
gulp.task('webpack', function() {
return gulp.src('src/js/index.js')
.pipe(webpack(webpackConfig, null, function(err, stats) {
/* Use stats to do more things if needed */
console.log(stats.toJson().assets);
assets = stats.toJson().assets;
//https://www.npmjs.com/package/gulp-html-replace
//require("fs").writeFileSync("stats.json",JSON.stringify(stats.toJson()));
})).pipe(gulp.dest(ENV+'/js/'));
});
gulp.task('copyCSS', function() {
if(isDist){
return gulp.src(['src/**/*.css','!src/component/**/*.css'])
.pipe(csso()).pipe(rev())
.pipe(gulp.dest(ENV))
.pipe(rev.manifest()) //- 生成一个rev-manifest.json
.pipe(gulp.dest('./rev'));
}else{
return gulp.src('src/**/*.css')
.pipe(gulp.dest(ENV))
}
});
gulp.task('rev', function() {
return gulp.src(['./rev/*.json', ENV+'/*.html']) //- 读取 rev-manifest.json 文件以及需要进行css名替换的文件
.pipe(revCollector()) //- 执行文件内css名的替换
.pipe(gulp.dest(ENV)); //- 替换后的文件输出的目录
});
gulp.task('copyHTML', function() {
return gulp.src('src/*.html').pipe(gulp.dest(ENV));
});
gulp.task('copyAsset', function() {
return gulp.src('src/asset/*.**').pipe(gulp.dest(ENV+'/asset'));
});
gulp.task('copyCommon', function() {
return gulp.src(['src/common/**']).pipe(gulp.dest(ENV+'/common'));
});
gulp.task('copyComponent', function() {
return gulp.src(['src/component/**','!src/component/**/*.js','!src/component/**/*.html','!src/component/**/*.css']).pipe(gulp.dest(ENV+'/component'));
});
gulp.task('fixEvn', function() {
return gulp.src(['src/component/**','!src/component/**/*.js']).pipe(gulp.dest(ENV+'/component'));
});
//https://segmentfault.com/q/1010000005760064/a-1020000005760268
gulp.task('replace', function() {
var vdName = assets[assets.length-1].name;
var omiName = '';
assets.forEach(function(item){
if(item.chunkNames[0]==='omi'){
omiName = item.name;
}
});
assets.forEach(function(item){
console.log(ENV+'/'+item.chunkNames[0]+ '.html')
gulp.src(ENV+'/'+item.chunkNames[0]+ '.html')
.pipe(htmlreplace({
'omijs':(isDist?(cdn+ 'js/'+ omiName):''),
'vjs': (isDist?(cdn+ 'js/'+ vdName):('js/'+ vdName)),
'js': (isDist?(cdn+ 'js/'+ item.name):('js/'+ item.name))
}))
.pipe(gulp.dest(ENV));
if(item.chunkNames[0]!=='omi'&&item.chunkNames[0]!=='vendor') {
gulp.src(ENV + '/js/' + item.name)
.pipe(header('window.Root ={}; Root.isDev = ' + (isDist ? 'false' : 'true') + ';'))
.pipe(gulp.dest(ENV + '/js'))
}
});
});
gulp.task('cdnReplace', function() {
return gulp.src('./dist/*.html')
.pipe(urlPrefix({
prefix: cdn
}))
.pipe(gulp.dest('./dist'));
});
gulp.task('browser-sync',function(){
browserSync.init({
server:{
baseDir:'./'+ENV+'/'
}
});
if(!isDist) {
gulp.watch(ENV + '/**').on('change', browserSync.reload);
gulp.watch(['src/docs/**/*.**','src/component/**/*.**','src/component/*.**', 'src/js/*.js', 'common/*.js'], function () {
runSequence(
'webpack',
'replace');
});
gulp.watch(['src/css/**'], function () {
runSequence(
'copyCSS');
});
}
});
if(isDist){
gulp.task('default', function(done) {
runSequence(
'clean',
'webpack',
'copyCSS',
'copyAsset',
'copyHTML',
'copyCommon',
'copyComponent',
'rev',
'cdnReplace',
'replace',
'browser-sync',
done);
});
}else{
gulp.task('default', function(done) {
runSequence(
'clean',
'webpack',
'copyCSS',
'copyAsset',
'copyHTML',
'copyCommon',
'copyComponent',
'replace',
'browser-sync',
done);
});
}

View File

@ -1,48 +0,0 @@
{
"name": "your-project-name",
"version": "0.0.0",
"description": "",
"scripts": {
"dev": "gulp",
"dist": "gulp"
},
"dependencies": {
"omi": "latest",
"omi-finger": "latest"
},
"devDependencies": {
"babel-core": "^6.22.1",
"babel-loader": "^6.2.10",
"babel-preset-es2015": "^6.22.0",
"babel-preset-stage-0": "^6.22.0",
"browser-sync": "^2.18.6",
"del": "^2.2.2",
"gulp": "^3.9.1",
"gulp-csso": "^2.0.0",
"gulp-header": "^1.8.8",
"gulp-html-replace": "^1.6.2",
"gulp-html-url-prefix": "^0.1.1",
"gulp-rev": "^7.1.2",
"gulp-rev-collector": "^1.1.1",
"html-webpack-plugin": "^2.26.0",
"md-text-loader": "^0.1.0",
"run-sequence": "^1.2.2",
"string-loader": "0.0.1",
"webpack": "^1.14.0",
"webpack-stream": "^3.2.0"
},
"repository": {
"type": "git",
"url": "git+https://github.com/AlloyTeam/omi.git"
},
"keywords": [
"md2site",
"omi"
],
"author": "dntzhang",
"license": "MIT",
"bugs": {
"url": "https://github.com/AlloyTeam/omi/issues/new"
},
"homepage": "http://alloyteam.github.io/omi"
}

View File

@ -1,7 +0,0 @@
module.exports = {
/*
your cdn address , such as:
cdn : '//s.url.cn/'
*/
cdn : ''
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

View File

@ -1,2 +0,0 @@
/*! @source http://purl.eligrey.com/github/classList.js/blob/master/classList.js */
"document"in self&&("classList"in document.createElement("_")&&(!document.createElementNS||"classList"in document.createElementNS("http://www.w3.org/2000/svg","g"))?!function(){"use strict";var t=document.createElement("_");if(t.classList.add("c1","c2"),!t.classList.contains("c2")){var e=function(t){var e=DOMTokenList.prototype[t];DOMTokenList.prototype[t]=function(t){var n,i=arguments.length;for(n=0;i>n;n++)t=arguments[n],e.call(this,t)}};e("add"),e("remove")}if(t.classList.toggle("c3",!1),t.classList.contains("c3")){var n=DOMTokenList.prototype.toggle;DOMTokenList.prototype.toggle=function(t,e){return 1 in arguments&&!this.contains(t)==!e?e:n.call(this,t)}}t=null}():!function(t){"use strict";if("Element"in t){var e="classList",n="prototype",i=t.Element[n],s=Object,r=String[n].trim||function(){return this.replace(/^\s+|\s+$/g,"")},o=Array[n].indexOf||function(t){for(var e=0,n=this.length;n>e;e++)if(e in this&&this[e]===t)return e;return-1},c=function(t,e){this.name=t,this.code=DOMException[t],this.message=e},a=function(t,e){if(""===e)throw new c("SYNTAX_ERR","An invalid or illegal string was specified");if(/\s/.test(e))throw new c("INVALID_CHARACTER_ERR","String contains an invalid character");return o.call(t,e)},l=function(t){for(var e=r.call(t.getAttribute("class")||""),n=e?e.split(/\s+/):[],i=0,s=n.length;s>i;i++)this.push(n[i]);this._updateClassName=function(){t.setAttribute("class",this.toString())}},u=l[n]=[],h=function(){return new l(this)};if(c[n]=Error[n],u.item=function(t){return this[t]||null},u.contains=function(t){return t+="",-1!==a(this,t)},u.add=function(){var t,e=arguments,n=0,i=e.length,s=!1;do t=e[n]+"",-1===a(this,t)&&(this.push(t),s=!0);while(++n<i);s&&this._updateClassName()},u.remove=function(){var t,e,n=arguments,i=0,s=n.length,r=!1;do for(t=n[i]+"",e=a(this,t);-1!==e;)this.splice(e,1),r=!0,e=a(this,t);while(++i<s);r&&this._updateClassName()},u.toggle=function(t,e){t+="";var n=this.contains(t),i=n?e!==!0&&"remove":e!==!1&&"add";return i&&this[i](t),e===!0||e===!1?e:!n},u.toString=function(){return this.join(" ")},s.defineProperty){var f={get:h,enumerable:!0,configurable:!0};try{s.defineProperty(i,e,f)}catch(d){void 0!==d.number&&-2146823252!==d.number||(f.enumerable=!1,s.defineProperty(i,e,f))}}else s[n].__defineGetter__&&i.__defineGetter__(e,h)}}(self));

File diff suppressed because one or more lines are too long

View File

@ -1,72 +0,0 @@
/* http://jmblog.github.com/color-themes-for-google-code-highlightjs */
/* Tomorrow Comment */
.hljs-comment,
.hljs-quote {
color: #8e908c;
}
/* Tomorrow Red */
.hljs-variable,
.hljs-template-variable,
.hljs-tag,
.hljs-name,
.hljs-selector-id,
.hljs-selector-class,
.hljs-regexp,
.hljs-deletion {
color: #c82829;
}
/* Tomorrow Orange */
.hljs-number,
.hljs-built_in,
.hljs-builtin-name,
.hljs-literal,
.hljs-type,
.hljs-params,
.hljs-meta,
.hljs-link {
color: #f5871f;
}
/* Tomorrow Yellow */
.hljs-attribute {
color: #eab700;
}
/* Tomorrow Green */
.hljs-string,
.hljs-symbol,
.hljs-bullet,
.hljs-addition {
color: #718c00;
}
/* Tomorrow Blue */
.hljs-title,
.hljs-section {
color: #4271ae;
}
/* Tomorrow Purple */
.hljs-keyword,
.hljs-selector-tag {
color: #8959a8;
}
.hljs {
display: block;
overflow-x: auto;
background: white;
color: #4d4d4c;
/*padding: 0.5em;*/
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}

File diff suppressed because one or more lines are too long

View File

@ -1,65 +0,0 @@
// Iterates through `array`, running `callback` for each `array` element.
function forEach(array, callback) {
var i = -1, length = array ? array.length : 0;
while (++i < length) {
callback(array[i]);
}
}
function indexOf(array, elem) {
var i = -1, length = array ? array.length : 0;
while (++i < length) {
if (array[i] === elem) {
return i;
}
}
}
function highlightLines() {
// TODO: mark as parsed.
forEach(document.querySelectorAll('pre code'), function(element) {
// Trim whitespace if the `data-trim` attribute is present.
if (element.hasAttribute('data-trim') && typeof element.innerHTML.trim == 'function') {
element.innerHTML = element.innerHTML.trim();
}
// Highlight code using highlight.js.
hljs.highlightBlock(element);
// Split highlighted code into lines.
var openTags = [], reHtmlTag = /<(\/?)span(?:\s+(?:class=(['"])hljs-.*?\2)?\s*|\s*)>/g;
element.innerHTML = element.innerHTML.replace(/(.*?)\r?\n/g, function(_, string) {
if (!string) {
return '<span class=line>&nbsp;</span>';
}
var openTag, stringPrepend;
// Re-open all tags that were previously closed.
if (openTags.length) {
stringPrepend = openTags.join('');
}
// Match all HTML `<span>` tags.
reHtmlTag.lastIndex = 0;
while (openTag = reHtmlTag.exec(string)) {
// If it is a closing tag, remove the opening tag from the list.
if (openTag[1]) {
openTags.pop();
}
// Otherwise if it is an opening tag, push it to the list.
else {
openTags.push(openTag[0]);
}
}
// Close all opened tags, so that strings can be wrapped with `span.line`.
if (openTags.length) {
string += Array(openTags.length + 1).join('</span>');
}
if (stringPrepend) {
string = stringPrepend + string;
}
return '<span class=line>' + string + '</span>';
});
});
}
export default highlightLines;

View File

@ -1,20 +0,0 @@
.content{
width: 80%;
}
h3{
color:#444444;
}
pre{
border: 1px solid #eee;
width: 100%;
}
li{
text-indent: 20px;
list-style:disc inside ;
}
@media only screen and (max-width: 768px) {
.content{
width: 100%;
}
}

View File

@ -1,3 +0,0 @@
<div class="content">
{{{html}}}
</div>

View File

@ -1,85 +0,0 @@
import Omi from 'omi';
import config from '../../docs/config.js';
import highlightLines from './highlight-lines.js';
const tpl = require('./index.html');
const css = require('./index.css');
class Content extends Omi.Component {
constructor(data) {
data = Object.assign({
lan:'cn',
name: 'installation'
},data);
super(data);
this.md = new Remarkable({html:true});
}
getMarkDown(name,lan) {
return require("md-text!../../docs/" + lan + "/" + name + ".md");
}
installed(){
this.initCodeStyle();
}
afterUpdate(){
this.initCodeStyle();
}
initCodeStyle() {
let codes = Omi.$$("code");
let codeHlNumArr = [];
codes.forEach(code => {
hljs.highlightBlock(code);
let arr = code.className.match(/{\S*}/);
let hllNums = null;
if (arr) {
let numArr = arr[0].replace(/[{|}]/g, '').split(',');
hllNums = this._arrToNumber(numArr);
}
codeHlNumArr.push(hllNums);
})
highlightLines();
codes.forEach((code, index) => {
this._hll(code, codeHlNumArr[index])
})
}
_arrToNumber (numArr){
let arr = [];
numArr.forEach(item=>{
if(item.indexOf('-')!==-1){
const tempArr = item.split('-');
const begin = Number(tempArr[0]);
const end = Number(tempArr[1]);
for(let i=begin;i<end+1;i++){
arr.push(i);
}
}else{
arr.push(Number(item));
}
})
return arr;
}
_hll(code, hllNums){
let spans = Omi.$$('.line',code);
hllNums&&hllNums.forEach(num =>{
spans[num]&&spans[num].classList.add('highlight');
})
}
render () {
this.data.html = this.md.render(this.getMarkDown(this.data.name, this.data.lan));
return tpl;
}
style () {
return css;
}
}
export default Content;

View File

@ -1,68 +0,0 @@
import Omi from 'omi';
import Content from './content/index.js';
import Sidebar from './sidebar/index.js';
import Head from './head/index.js';
import config from '../docs/config.js';
import Pager from './pager/index.js';
Omi.makeHTML('Content', Content);
Omi.makeHTML('Sidebar', Sidebar);
Omi.makeHTML('Head', Head);
Omi.makeHTML('Pager', Pager);
class Frame extends Omi.Component {
constructor(data) {
super(data);
}
install() {
this.setViewport();
window.onresize = ()=> {
if( window.innerWidth < 768) {
this.refs.main.style.width = '100%';
}else{
this.refs.main.style.width = (window.innerWidth - 220)+'px';
}
}
}
setViewport (){
if( window.innerWidth < 768) {
this.data.width = '100%';
}else{
this.data.width = (window.innerWidth - 220)+'px';
}
}
style() {
return `
<style>
.main{
position: absolute;
left:220px;
top:45px;
height:auto;
}
@media only screen and (max-width: 768px) {
.main{
left:0%;
}
}
</style>
`;
}
render() {
return `<div>
<Head data-lan="{{lan}}" />
<div class="main" ref="main" style="width:{{width}};">
<Content omi-id="content" data-lan="{{lan}}" />
<Pager omi-id="pager" data-lan="{{lan}}" />
</div>
<Sidebar omi-id="sidebar" data-lan="{{lan}}" />
</div>`;
}
}
export default Frame;

View File

@ -1,78 +0,0 @@
.head{
position:fixed;
height:45px;
line-height: 45px;
border-bottom: 1px solid #eee;
width:100%;
background-color:#303030;
z-index:100;
}
ul,li{
display: inline-block;
}
.logo_box{
width:100px;
display: inline-block;
text-align:center;
line-height: 60px;
}
.menu a,.logo_box a{
display: inline-block;
height:45px;
color:#ddd;
}
.menu{
position: absolute;
right:20px;
}
.menu li{
margin-left:15px;
}
.logo_box a{
font-size: 34px;
font-weight: bold;
color: #00bff3;
padding: 0px 15px;
line-height: 45px;
cursor: pointer;
}
.menu a:hover{
color: white;
}
.m_menu{
position:fixed;
display:none;
}
@media only screen and (max-width: 768px) {
.menu li{
display:none;
}
.menu .m_show{
display:block;
}
.logo_box{
display:inline-block;
}
.head{
text-align:center;
}
.m_menu{
top:0;
left:0;
display:block;
width:50px;
height:50px;
padding-top: 6px;
}
.m_menu img{
width:30px;
}
}

View File

@ -1,19 +0,0 @@
<div class="head bord-btm">
<div class="m_menu" omi-finger tap="toggleMenus" touchEnd="handleTouchEnd"> <img src="./component/head/menu.png" alt="" /></div>
<div class="logo_box">
<a href="https://github.com/AlloyTeam/omi">Omi</a>
</div>
<ul class="menu">
<li class="github_li"><a href="https://github.com/AlloyTeam/omi">Github</a>
<li><a href="http://alloyteam.github.io/omi/example/playground/">Playground</a></li>
<li><a href="https://github.com/AlloyTeam/omi/tree/master/docs">[Edit the Docs]</a></li>
{{#isEnLan}}
<li class="github_li m_show"><a href="docs-cn.html">中文</a>
{{/isEnLan}}
{{^isEnLan}}
<li class="github_li m_show"><a href="docs-en.html">English</a>
{{/isEnLan}}
</li>
</ul>
</div>

View File

@ -1,64 +0,0 @@
import Omi from 'omi';
import OmiFinger from 'omi-finger';
const tpl = require('./index.html');
const css = require('./index.css');
OmiFinger.init();
class Head extends Omi.Component {
constructor (data) {
super(data);
}
install(){
this.data.isEnLan = this.data.lan === 'en';
document.body.addEventListener('touchend',()=>{
setTimeout(()=>{
this.removeClass(Omi.get('sidebar').node,'show');
},300);
},false);
}
toggleMenus(evt){
this.toggleClass(Omi.get('sidebar').node,'show');
evt.stopPropagation();
}
handleTouchEnd(evt){
evt.stopPropagation();
}
toggleClass(element, className) {
if (!element || !className) {
return;
}
var classString = element.className, nameIndex = classString.indexOf(className);
if (nameIndex == -1) {
classString += ' ' + className;
}
else {
classString = classString.substr(0, nameIndex) + classString.substr(nameIndex + className.length);
}
element.className = classString;
}
removeClass(element, className) {
var classString = element.className, nameIndex = classString.indexOf(className);
if (nameIndex !== -1) {
classString = classString.substr(0, nameIndex) + classString.substr(nameIndex + className.length);
}
element.className = classString;
}
style () {
return css;
}
render () {
return tpl;
}
}
export default Head;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 193 B

View File

@ -1,26 +0,0 @@
li.title{
font-size: 16px;
font-weight: bold;
margin-bottom:10px;
margin-top:10px;
text-indent: 23px;
}
li{
margin-bottom:3px;
text-indent: 33px;
}
li a{
display:block;
font-size:14px;
height:20px;
line-height:20px;
color: #666;
}
li a.current{
background-color:#c3d4fc;
color:white;
}
li a:hover{
background-color:#b3d4fc;
color:white;
}

View File

@ -1,8 +0,0 @@
<ul>
<li class="title">{{title}}</li>
{{#list}}
<li>
<a href="#" onclick="goto('{{md}}',{{index}})" {{#isCurrent}}class="current"{{/isCurrent}}>{{name}}</a>
</li>
{{/list}}
</ul>

View File

@ -1,44 +0,0 @@
import Omi from 'omi';
const tpl = require('./index.html');
const css = require('./index.css');
class List extends Omi.Component {
constructor(data) {
super(data);
Omi.mixIndexToArray(this.data.list);
this.data.currentIndex = 0;
var self = this;
this.data.isCurrent = function () {
return (this.index === self.data.currentIndex) && self.data.active;
}
}
goto(name, index) {
Omi.get('content').data.name = name;
Omi.get('content').update();
this.data.currentIndex = index;
this.parent.children.forEach((child,index) => {
child.data.active = false;
if (child.id === this.id) {
Omi.get('pager').activeIndex = index;
child.data.active = true;
}
child.update();
});
Omi.get('pager').currentIndex = index;
Omi.get('pager').update();
document.body.scrollTop = 0;
}
render() {
return tpl;
}
style() {
return css;
}
}
export default List;

View File

@ -1,24 +0,0 @@
.pager {
width:85%;
height:80px;
line-height:80px;
position: relative;
font-size:16px;
}
@media only screen and (max-width: 768px) {
.pager {
width:100%;
}
}
.pre{
position: absolute;
left:10px;
top:10px;
}
.next{
position: absolute;
right:10px;
top:10px;
}

View File

@ -1,99 +0,0 @@
import Omi from 'omi';
import config from '../../docs/config.js';
import OmiFinger from 'omi-finger';
OmiFinger.init();
class Pager extends Omi.Component {
constructor (data) {
super(data);
this.activeIndex = 0;
this.currentIndex = 0;
}
updatePager() {
this.data.preMd = null;
this.data.preName = null;
this.data.nextMd = null;
this.data.nextName = null;
let item = config.menus[this.data.lan][this.activeIndex];
let pre = item.list[this.currentIndex - 1];
if (pre) {
this.data.preMd = pre.md;
this.data.preName = pre.name;
}
let next = item.list[this.currentIndex + 1];
if (next) {
this.data.nextMd = next.md;
this.data.nextName = next.name;
}
}
goto(name , dir){
let sidebar = Omi.get('sidebar');
if(dir ==='next'){
sidebar.children[this.activeIndex].goto(name,++this.currentIndex);
}else{
sidebar.children[this.activeIndex].goto(name,--this.currentIndex);
}
this.update();
}
handleTap(evt){
let dir = evt.target.getAttribute('data-dir');
let name= evt.target.getAttribute('data-name');
this.goto(name,dir);
}
isMobile(){
const browser={
versions:function(){
var u = navigator.userAgent, app = navigator.appVersion;
return {//移动终端浏览器版本信息
trident: u.indexOf('Trident') > -1, //IE内核
presto: u.indexOf('Presto') > -1, //opera内核
webKit: u.indexOf('AppleWebKit') > -1, //苹果、谷歌内核
gecko: u.indexOf('Gecko') > -1 && u.indexOf('KHTML') == -1, //火狐内核
mobile: !!u.match(/AppleWebKit.*Mobile.*/), //是否为移动终端
ios: !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/), //ios终端
android: u.indexOf('Android') > -1 || u.indexOf('Linux') > -1, //android终端或者uc浏览器
iPhone: u.indexOf('iPhone') > -1 , //是否为iPhone或者QQHD浏览器
iPad: u.indexOf('iPad') > -1, //是否iPad
webApp: u.indexOf('Safari') == -1 //是否web应该程序没有头部与底部
};
}(),
language:(navigator.browserLanguage || navigator.language).toLowerCase()
}
if(browser.versions.mobile || browser.versions.ios || browser.versions.android ||
browser.versions.iPhone || browser.versions.iPad){
return true;
}
return false;
}
render () {
this.updatePager();
if(this.isMobile()) {
return `
<div class="pager">
{{#preName}} <a class="pre" href="#" omi-finger tap="handleTap" data-dir="pre" data-name="{{preMd}}">{{preName}}</a>{{/preName}}
{{#nextName}}<a class="next" href="#" omi-finger tap="handleTap" data-dir="next" data-name="{{nextMd}}">{{nextName}}</a> {{/nextName}}
</div>`;
}else{
return`
<div class="pager">
{{#preName}} <a class="pre" href="#" onclick="goto('{{preMd}}','pre')">{{preName}}</a>{{/preName}}
{{#nextName}}<a class="next" href="#" onclick="goto('{{nextMd}}','next')">{{nextName}}</a> {{/nextName}}
</div>`;
}
}
style () {
return require('./index.css');
}
}
export default Pager;

View File

@ -1,32 +0,0 @@
@media only screen and (max-width: 768px) {
.list{
transform: translateX(-100%);
background-color:white;
-moz-transition: all .6s ease;
-o-transition: all .6s ease;
-webkit-transition: all .6s ease;
transition: all .6s ease;
}
.list.show {
-moz-transform: translateX(0%) translateZ(0);
-ms-transform: translateX(0%) translateZ(0);
-o-transform: translateX(0%) translateZ(0);
-webkit-transform: translateX(0%) translateZ(0);
transform: translateX(0%) translateZ(0);
}
}
.list{
width:200px;
text-indent: 20px;
border-right: 1px solid #eee;
overflow-x: hidden;
overflow-y: auto;
position:fixed;
top:45px;
}
.version{
height:20px;
}

View File

@ -1,4 +0,0 @@
<div class="list" style="height:{{height}}px;">
<div class="version"></div>
{{#items}}<List group-data="data.items" selfDataFirst /> {{/items}}
</div>

View File

@ -1,26 +0,0 @@
import Omi from 'omi';
import List from '../list/index.js';
import config from '../../docs/config.js';
Omi.makeHTML('List', List);
class Sidebar extends Omi.Component {
constructor(data) {
super(data);
}
install () {
this.data.items = config['menus'][this.data.lan] ;
this.data.height = window.innerHeight -45;
}
style () {
return require('./index.css');
}
render () {
return require('./index.html');
}
}
export default Sidebar;

View File

@ -1,96 +0,0 @@
html,body{
margin: 0;
padding: 0;
border: 0;
background-color: #f9f9f9;
font-family:proxima-nova,"Helvetica Neue",Helvetica,Roboto, PT Sans, DejaVu Sans, Arial,Segoe UI Light,Segoe UI,Microsoft Jhenghei,Mirco Yahei,'sans-serif';
overflow-x: hidden;
}
img,ul,li{
margin: 0;
padding: 0;
border: 0;
}
ul,li{
list-style: none;
}
a{
text-decoration: none;
}
table{
border-collapse: collapse;
}
table,td,th{
border: 1px solid #ccc;
}
@media only screen and (max-width: 768px) {
.content img{
width: 100%;
}
.content code[class*="language-"],
.content pre[class*="language-"] {
font-family: Consolas, "Liberation Mono", Courier, monospace;
line-height: 18px;
font-size: 12px;
margin: 0;
width: 100%;
box-sizing: border-box;
}
.content pre[class*="language-"] {
padding-left: 10px;
}
.content p{
font-size: 14px;
}
.content p,.content h1,.content h2,.content h3,.content h4,.content h5{
padding-left:10px;
padding-right:10px;
}
.line-highlight:before, .line-highlight[data-end]:after{
top: 0em;
}
}
*{
box-sizing: border-box;
}
pre code.hljs{
padding-left: 14px;
display: block;
overflow-x: auto;
}
.hljs{
font-size: 14px;
}
code.hljs{
display: inline-block;
overflow-x: hidden;
text-indent: 0;
position: relative;
top: 3px;
}
.line.highlight{
background-color: #f7ebc6;
border-left: 5px solid #f7d87c;
display: block;
margin-left: -14px;
padding-left: 9px;
}
.line {
display: block;
}

View File

@ -1,40 +0,0 @@
<!DOCTYPE html>
<html>
<head lang="zh">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0">
<title>Omi</title>
<link rel="shortcut icon" href="../asset/omi.ico">
<link rel="stylesheet" href="css/docs.css">
<link rel="stylesheet" href="common/highlight/tomorrow.css">
</head>
<body>
<!--[if lt IE 9]>
<script>
(function(){
document.body.innerHTML = "The docs website does not support IE8, IE7 and IE6...<br/>Please use modern browser!<br/>" +
"The website will redirect to GitHub after 3s."
setTimeout(function(){
window.location.href = 'https://github.com/AlloyTeam/omi';
},3000);
return;
})()
</script>
<![endif]-->
<!--[if IE 9]>
<script src="common/common/class_list.js"></script>
<![endif]-->
<script src="common/highlight/highlight.pack.js"></script>
<script src="common/remarkable.min.js"></script>
<!-- build:vjs -->
<script src="js/vendor.bundle.js"></script>
<!-- endbuild -->
<!-- build:omijs -->
<script src="js/omijs.bundle.js"></script>
<!-- endbuild -->
<!-- build:js -->
<script src="js/index.js"></script>
<!-- endbuild -->
</body>
</html>

View File

@ -1,41 +0,0 @@
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0">
<title>Omi</title>
<link rel="shortcut icon" href="../asset/omi.ico">
<link rel="stylesheet" href="css/docs.css">
<link rel="stylesheet" href="common/highlight/tomorrow.css">
</head>
<body>
<!--[if lt IE 9]>
<script>
(function(){
document.body.innerHTML = "The docs website does not support IE8, IE7 and IE6...<br/>Please use modern browser!<br/>" +
"The website will redirect to GitHub after 3s."
setTimeout(function(){
window.location.href = 'https://github.com/AlloyTeam/omi';
},3000);
return;
})()
</script>
<![endif]-->
<!--[if IE 9]>
<script src="common/common/class_list.js"></script>
<![endif]-->
<script src="common/highlight/highlight.pack.js"></script>
<script src="common/remarkable.min.js"></script>
<!-- build:vjs -->
<script src="js/vendor.bundle.js"></script>
<!-- endbuild -->
<!-- build:omijs -->
<script src="js/omijs.bundle.js"></script>
<!-- endbuild -->
<!-- build:js -->
<script src="js/index.js"></script>
<!-- endbuild -->
</body>
</html>

View File

@ -1,268 +0,0 @@
## 组件通讯
[Omi框架](https://github.com/AlloyTeam/omi)组建间的通讯非常便利灵活,因为有许多可选方案进行通讯:
* 通过在组件上声明 data-* 传递给子节点
* 通过在组件上声明 data 传递给子节点 (支持复杂数据类型的映射)
* 声明 group-data 传递(支持复杂数据类型的映射)
* 完全面向对象,可以非常容易地拿到对象的实例,之后可以设置实例属性和调用实例的方法
所以通讯变得畅通无阻,下面一一来举例说明。
### data-*通讯
```js {36}
class Hello extends Omi.Component {
constructor(data) {
super(data);
}
style () {
return `
h1{
cursor:pointer;
}
`;
}
handleClick(target, evt){
alert(target.innerHTML);
}
render() {
return `
<div>
<h1 onclick="handleClick(this, event)">Hello ,{{name}}!</h1>
</div>
`;
}
}
Omi.tag('hello', Hello);
class App extends Omi.Component {
constructor(data) {
super(data);
}
render() {
return `
<div>
<hello data-name="Omi" ></hello>
</div>
`;
}
}
Omi.render(new App(),"#container");
```
一般data-*用来传递值类型如string、number。值得注意的是通过data-*接收到的数据类型都是string需要自行转成number类型。
通常情况下data-*能满足我们的要求但是遇到复杂的数据类型是没有办法通过大量data-*去表达所以可以通过data通讯请往下看。
### data通讯
如上面代码所示,通过 data-name="Omi"可以把name传递给子组件。下面的代码也可以达到同样的效果。
```js {4,10}
...
class App extends Omi.Component {
constructor(data) {
super(data);
this.helloData = { name : 'Omi' };
}
render() {
return `
<div>
<hello data="helloData" ></hello>
</div>
`;
}
}
Omi.render(new App(),"#container");
```
使用data声明会去组件的instance也就是this下找对应的属性this下可以挂载任意复杂的对象。所以这也就突破了data-*的局限性。
如果instance下面的某个属性下面的某个属性下面的某个数组的第一个元素的某个属性要作为data传递Hello怎么办
没关系data声明是支持复杂类型的使用方式如下:
```js
...
class App extends Omi.Component {
constructor(data) {
super(data);
this.complexData ={
a:{
b:{
c:[
{
e:[{
name:'ComplexData Support1'
},{
name:'ComplexData Support2'
}]
},
{
name: 'ComplexData Support3'
}
]
}
}
};
}
render() {
return `
<div>
<hello data="complexData.a.b.c[1]" ></hello>
</div>
`;
}
}
...
```
<a href="http://alloyteam.github.io/omi/website/redirect.html?type=data_complex" target="_blank">点击这里→data映射复杂数据</a>
### group-data通讯
group-data专门是为了给一组组件批量传递data而设计。
```js
import Hello from './hello.js';
Omi.makeHTML('Hello', Hello);
class App extends Omi.Component {
constructor(data) {
super(data);
this.testData = [{name: 'Omi'}, {name: 'dntzhang'}, {name: 'AlloyTeam'}];
}
render() {
return `
<div>
<hello group-data="testData" ></hello>
<hello group-data="testData" ></hello>
<hello group-data="testData" ></hello>
</div>
`;
}
}
Omi.render(new App(),"#container");
```
只需要在声明的子组件上标记group-data就会去当前组件的instance也就是this下面找对应的属性然后根据当前的位置和对应数组的位置会一一对应起来。
运行结果如下:
![](http://images2015.cnblogs.com/blog/105416/201702/105416-20170216110701535-1698390390.png)
<a href="http://alloyteam.github.io/omi/website/redirect.html?type=group_data" target="_blank">点击这里→group-data</a>
同样group-data支持复杂数据类型的映射需要注意的是group-data映射的终点必须是一个数组:
```js
import Hello from './hello.js';
Omi.tag('hello', Hello);
class App extends Omi.Component {
constructor(data) {
super(data);
this.complexData ={
a:{
b:{
c:[
{
e:[{
name:'ComplexData Support1'
},{
name:'ComplexData Support2'
}]
},
{
name: 'ComplexData Support3'
}
]
}
}
};
}
render() {
return `
<div>
<hello group-data="complexData.a.b.c[0].e" ></hello>
<hello group-data="complexData.a.b.c[0].e" ></hello>
</div>
`;
}
}
Omi.render(new App(),"#container");
```
<a href="http://alloyteam.github.io/omi/website/redirect.html?type=group_data_complex" target="_blank">点击这里→group-data映射复杂数据</a>
### 通过对象实例
```js {7}
...
class App extends Omi.Component {
constructor(data) {
super(data);
}
installed(){
this.hello.data.name = "Omi";
this.update()
}
render() {
return `
<div>
<hello name="hello" ></hello>
</div>
`;
}
}
Omi.render(new App(),"#container");
```
### 通过omi-id
```js {7,14}
...
class App extends Omi.Component {
constructor(data) {
super(data);
}
installed(){
Omi.get("hello").data.name = "Omi";
this.update()
}
render() {
return `
<div>
<hello omi-id="hello" ></hello>
</div>
`;
}
}
Omi.render(new App(),"#container");
```
通过在组件上声明omi-id在程序任何地方拿到该对象的实例。这个可以算是跨任意组件通讯神器。

View File

@ -1,140 +0,0 @@
## 组件
[Omi框架](https://github.com/AlloyTeam/omi)完全基于组件体系设计我们希望开发者可以像搭积木一样制作Web程序一切皆是组件组件也可以嵌套子组件形成新的组件新的组件又可以当作子组件嵌套至任意组件形成新的组件...
![](http://images2015.cnblogs.com/blog/105416/201702/105416-20170210093427338-1536910080.png)
## 简单组件
这里使用Todo的例子来讲解Omi组件体系的使用。
```js
class Todo extends Omi.Component {
constructor(data) {
super(data);
}
add (evt) {
evt.preventDefault();
this.data.items.push(this.data.text);
this.data.text = '';
this.update();
}
style () {
return `
h3 { color:red; }
button{ color:green;}
`;
}
handleChange(target){
this.data.text = target.value;
}
render () {
return `<div>
<h3>TODO</h3>
<ul> {{#items}} <li>{{.}}</li> {{/items}}</ul>
<form onsubmit="add(event)" >
<input type="text" onchange="handleChange(this)" value="{{text}}" />
<button>Add #{{items.length}}</button>
</form>
</div>`;
}
}
Omi.render(new Todo({ items: [] ,text : '' }),"body");
```
组件生成的HTML最终会插入到body中。上面的例子展示了Omi的部分特性:
- data传递: new Todo(data,..)的data可以直接提供给render方法里的模板
- 局部CSS: h3只对render里的h3生效不会污染外面的h3button也是同样的
- 声明式事件绑定: onchange调用的就是组件内的handleChangethis可以拿到当然的DOM元素,还可以拿到当前的event
- 需要手动调用update方法才能更新组件
这里需要特别强调的是为了更加的自由和灵活度。Omi没有内置数据变更的自动更新需要开发者自己调用update方法。
<a href="http://alloyteam.github.io/omi/website/redirect.html?type=todo" target="_blank">点击这里→在线试试</a>
## 组件嵌套
如果页面超级简单的话可以没有组件嵌套。但是绝大部分Web网页或者Web应用需要嵌套定义的组件来完成所有的功能和展示。比如上面的Todo我们也是可以抽取出List。
这样让程序易维护、可扩展、方便复用。如我们抽取出List
```js
class List extends Omi.Component {
constructor(data) {
super(data);
}
render () {
return `<ul> {{#items}} <li>{{.}}</li> {{/items}}</ul>`;
}
}
```
怎么使用这个List我们需要使用Omi.makeHTML把List制作成可以声明式的标签在render方法中就能直接使用该标签。如下所示
```js
import List from './list.js';
Omi.tag('list', List);
class Todo extends Omi.Component {
constructor(data) {
super(data);
this.data.length = this.data.items.length;
this.listData = { items : this.data.items };
}
add (evt) {
evt.preventDefault();
this.list.data.items.push(this.data.text);
this.data.length = this.list.data.items.length;
this.data.text = '';
this.update();
}
style () {
return `
h3 { color:red; }
button{ color:green;}
`;
}
handleChange(target){
this.data.text = target.value;
}
render () {
return `<div>
<h3>TODO</h3>
<list name="list" data="listData" ></list>
<form onsubmit="add(event)" >
<input type="text" onchange="handleChange(this)" value="{{text}}" />
<button>Add #{{length}}</button>
</form>
</div>`;
}
}
```
* 第3行通过tag方法把组件制作成可以在render中使用的标签。当然Omi.tag('list', List);也可以写在List组件的代码下面。
* 第9行在父组件上定义listData属性用来传递给子组件。
* 第34行在render方法中使用List组件。其中name方法可以让你在代码里通过this快速方法到该组件的实例。data="listData"可以让你把this.listData传递给子组件。
需要注意的是父组件的this.listData会被通过Object.assign浅拷贝到子组件。你可以通过在组件上标记selfDataFirst或者sdf来表示组件自身的data的优先级更高还是父组件传递过来的data的优先级更好。Omi内部的源代码是这样子:
```js
if(this.selfDataFirst){
this.data = Object.assign({},this._getDataset(childStr),this.data)
}else{
this.data = Object.assign({},this.data, this._getDataset(childStr))
}
```
关于Omi组件通讯其实有4种方案这个后续教程会专门来讲。
<a href="http://alloyteam.github.io/omi/website/redirect.html?type=todo_nest" target="_blank">点击这里→在线试试</a>

View File

@ -1,108 +0,0 @@
## 条件判断
我们经常需要根据不同的状态呈现不同的界面比如有的用户是vip要显示vip的Logo。Omi有许多种方式满足你的要求。
### 方式零
```js
class ConditionTest extends Omi.Component {
constructor(data) {
super(data);
}
render () {
return `
<div o-if="isVip">you are VIP.</div>
<div o-if="!isVip">you are not VIP.</div>
`;
}
}
```
这是omi.js的条件判断方式。
### 方式一
```js
class ConditionTest extends Omi.Component {
constructor(data) {
super(data);
}
render () {
return `{{#isVip}}
<div>you are VIP.</div>
{{/isVip}}
{{^isVip}}
<div>you are not VIP.</div>
{{/isVip}}`;
}
}
```
上面是omi.mustache.js的条件判断方式。完全使用mustachejs的条件判断的语法。当然Omi不强制你使用mustachejs。你可以是omi.lite.js然后重写Omi.template方法去使用任意你喜爱的模板引擎。
### 方式二
```js
class ConditionTest extends Omi.Component {
constructor(data) {
super(data);
}
render () {
if(this.data.isVip){
return '<div>you are VIP.</div>';
}else{
return '<div>you are not VIP.</div>';
}
}
}
```
render就是提供了很好的可编程性里面可以写任意js逻辑代码。对了差点忘了style方法里面也可以写js逻辑的。
```js
class ConditionTest extends Omi.Component {
constructor(data) {
super(data);
}
style (){
if(this.data.isVip){
return 'div{ color : red; }';
}else{
return 'div{ color : green; }';
}
}
render () {
if(this.data.isVip){
return '<div>you are VIP.</div>';
}else{
return '<div>you are not VIP.</div>';
}
}
}
```
### 方式三
```js
class ConditionTest extends Omi.Component {
constructor(data) {
super(data);
}
render() {
return `
${this.data.isVip
?"<div>you are VIP.</div>"
:"<div>you are not VIP.</div>"
}
`;
}
}
```
当然可以使用${ }里面写javascript代码进行输出。

View File

@ -1,112 +0,0 @@
## 事件处理
Omi的事件分内置事件和自定义事件。在内置事件处理方面巧妙地利用了浏览器自身的管线机制可以通过event和this轻松拿到事件实例和触发该事件的元素。
### 内置事件
什么算内置事件?只要下面正则能匹配到就算内置事件。
```js
on(abort|blur|cancel|canplay|canplaythrough|change|click|close|contextmenu|cuechange|dblclick|drag|dragend|dragenter|dragleave|dragover|dragstart|drop|durationchange|emptied|ended|error|focus|input|invalid|keydown|keypress|keyup|load|loadeddata|loadedmetadata|loadstart|mousedown|mouseenter|mouseleave|mousemove|mouseout|mouseover|mouseup|mousewheel|pause|play|playing|progress|ratechange|reset|resize|scroll|seeked|seeking|select|show|stalled|submit|suspend|timeupdate|toggle|volumechange|waiting|autocomplete|autocompleteerror|beforecopy|beforecut|beforepaste|copy|cut|paste|search|selectstart|wheel|webkitfullscreenchange|webkitfullscreenerror|touchstart|touchmove|touchend|touchcancel|pointerdown|pointerup|pointercancel|pointermove|pointerover|pointerout|pointerenter|pointerleave)
```
内置事件怎么绑定?如下所示:
```js
class EventTest extends Omi.Component {
constructor(data) {
super(data);
}
handleClick(dom, evt){
alert(dom.innerHTML);
}
render () {
return `<div onclick="handleClick(this, event)">Hello, Omi!</div>`;
}
}
```
### 自定义事件
开发者自己定义的组件的事件称为自定义事件自定义事件必须以on开头即onXXXX的格式不然Omi识别不到。这里拿分页作为例子
```js
import Omi from '../../src/index.js';
import Pagination from './pagination.js';
import Content from './content.js';
Omi.tag('pagination', Pagination);
Omi.tag('content', Content);
class Main extends Omi.Component {
constructor(data) {
super(data);
}
installed(){
this.content.goto(this.pagination.data.currentPage+1);
}
handlePageChange(index){
this.content.goto(index+1);
}
render () {
return `<div>
<h1>Pagination Example</h1>
<content name="content" ></content>
<pagination
name="pagination"
data-total="100"
data-page-size="10"
data-num-edge="1"
data-num-display="4"     
onPageChange="handlePageChange" ></pagination>
</div>`;
}
}
Omi.render( new Main(),'body');
```
如上面的onPageChange就是自定义事件触发会执行handlePageChange。onPageChange方法是在Pagination中执行
```js
import Omi from '../../src/index.js';
class Pagination extends Omi.Component {
...
...
...
linkTo: "#",
prevText: "Prev",
nextText: "Next",
ellipseText: "...",
prevShow: true,
nextShow: true,
onPageChange: function () { return false; }
}, this.data);
this.pageNum = Math.ceil(this.data.total / this.data.pageSize);
}
goto (index,evt) {
evt.preventDefault();
this.data.currentPage=index;
this.update();
this.data.onPageChange(index);
}
...
...
...
}
```
这里取了Pagination组件的部分代码。高亮的就是执行onPageChange的地方。
### 相关地址
* [演示地址](http://alloyteam.github.io/omi/example/pagination/)
* [源码地址](https://github.com/AlloyTeam/omi/tree/master/example/pagination)

View File

@ -1,81 +0,0 @@
## 表单
Omi让一些表单操控起来更加方便特别是select
### select标签
以前,我们需要像如下的方式选中一个选项:
```html
<select>
<option value="grapefruit">Grapefruit</option>
<option value="lime">Lime</option>
<option selected value="coconut">Coconut</option>
<option value="mango">Mango</option>
</select>
```
第三个option由于加上了selected所有会被选中。这样带来的问题就是开发者写的程序可能要操遍历每个option。而使用Omi你只需要这样子
```html
<select value="coconut">
<option value="grapefruit">Grapefruit</option>
<option value="lime">Lime</option>
<option value="coconut">Coconut</option>
<option value="mango">Mango</option>
</select>
```
这样就能达到同样的效果。比如你想选择第一项:
```html
<select value="grapefruit">
<option value="grapefruit">Grapefruit</option>
<option value="lime">Lime</option>
<option value="coconut">Coconut</option>
<option value="mango">Mango</option>
</select>
```
是不是非常方便?
### 举个例子
```js
class FormTest extends Omi.Component {
constructor(data) {
super(data);
}
handleChange(target){
console.log(target.value)
this.data.value = target.value;
}
handleSubmit(evt) {
alert('Your favorite flavor is: ' + this.data.value);
evt.preventDefault();
}
render () {
return `
<form onsubmit="handleSubmit(event)">
<label>
Pick your favorite La Croix flavor:
<select value="{{value}}" onchange="handleChange(this)">
<option value="grapefruit">Grapefruit</option>
<option value="lime">Lime</option>
<option value="coconut">Coconut</option>
<option value="mango">Mango</option>
</select>
</label>
<input type="submit" value="Submit" />
</form>`;
}
}
Omi.render(new FormTest({ value: 'mango' }),'#container');
```
<a href="http://alloyteam.github.io/omi/website/redirect.html?type=form" target="_blank">点击这里→在线试试</a>

View File

@ -1,39 +0,0 @@
## 获取DOM节点
虽然绝大部分情况下开发者不需要去查找获取DOM但是还是有需要获取DOM的场景所以Omi提供了方便获取DOM节点的方式。
### ref和refs
```js
class Hello extends Omi.Component {
constructor(data) {
super(data);
}
style () {
return `
h1{
cursor:pointer;
}
`;
}
handleClick(){
alert(this.refs.abc.innerHTML);
}
render() {
return `
<div>
<h1 ref="abc" onclick="handleClick()">Hello ,{{name}}!</h1>
</div>
`;
}
}
Omi.render(new Hello({ name : "Omi" }),"#container");
```
可以看到通过在HTML中标记ref为abc那么就通过this.refs.abc访问到该DOM节点。
<a href="http://alloyteam.github.io/omi/website/redirect.html?type=ref" target="_blank">点击这里→在线试试</a>

View File

@ -1,130 +0,0 @@
## Hello World
你可以使用ES6+或者ES5的方式编写Omi程序来搭建你的Web程序。
### Hello World with ES6+
你可以使用 [webpack](https://webpack.github.io/) 打包工具webpack会把你的模块代码打成一个很小的包优化加载时间。使用[babel](http://babeljs.io/)让你立刻马上使用ES6+来编写你的web程序。你只需要在webpack配置的module设置好[babel-loader](https://github.com/babel/babel-loader)便可。
一个Omi的简短的例子如下所示:
```js
import Omi from './omi.js';
class Hello extends Omi.Component {
constructor(data) {
super(data);
}
style () {
//注意return中的<style></style>包裹是可选的。主要是为了识别为JSX文件可以有CSS高亮。
return `
<style>
h1{
cursor:pointer;
}
</style>
`;
}
handleClick(target, evt){
alert(target.innerHTML);
}
render() {
return `
<div>
<h1 onclick="handleClick(this, event)">Hello ,{{name}}!</h1>
</div>
`;
}
}
Omi.render(new Hello({ name : "Omi" }),"#container");
```
组件生成的HTML最终会插入到#container中。上面的例子展示了Omi的部分特性:
- data传递: new Hello(data,..)的data可以直接提供给render方法里的模板
- 局部CSS: h1只对render里的h1生效不会污染外面的h1
- 声明式事件绑定: onclick调用的就是组件内的handleClickthis可以拿到当前的DOM元素,还可以拿到当前的event
<a href="http://alloyteam.github.io/omi/website/redirect.html?type=hello" target="_blank">点击这里→在线试试</a>
你可以使用Omi.tag来生成组件标签用于嵌套。
```js
Omi.tag('hello', Hello);
```
那么你就在其他组件中使用,如
```js
...
render() {
return `
<div>
<div>Test</div>
<hello data-name="Omi" ></hello>
</div>
`;
}
...
```
<a href="http://alloyteam.github.io/omi/website/redirect.html?type=hello_nest" target="_blank">点击这里→在线试试</a>
### Hello World with ES5
当然Omi没有抛弃ES5的用户。你可以使用ES5的方式编写Omi。如在你的HTML中引用omi.js
```html
<script src="omi.js"></script>
```
然后:
```js
var Hello = Omi.create("hello", {
style: function () {
return "h1{ cursor:pointer }";
},
handleClick: function (dom) {
alert(dom.innerHTML)
},
render: function () {
return ' <div>\
<h1 onclick="handleClick(this, event)">\
Hello ,{{name}}!\
</h1>\
</div>'
}
});
var Test = Omi.create("Test", {
render: function () {
return '<div>\
<div>Test</div>\
<hello data-name="Omi" ><hello>\
</div>'
}
});
Omi.render(new Test(),'#container');
```
当然除了在HTML引入脚本你还可以使用AMD、CMD或者CommonJS的方式引入Omi这里就不再一一列举。
需要注意的是Omi.create的第一个参数Hello是用来生成Tag Name的。你可以在其他地方嵌入你的组件。如
```js
...
render:function() {
return '<div>\
<hello data-name="Omi1" ></hello>\
<div>Test XXXX</div>\
<hello data-name="Omi2" ></hello>\
</div>';
}
...
```
<a href="http://alloyteam.github.io/omi/website/redirect.html?type=hello_es5" target="_blank">点击这里→在线试试</a>

View File

@ -1,56 +0,0 @@
## 继承
通过继承机制,可以利用已有的数据类型来定义新的数据类型。所定义的新的数据类型不仅拥有新定义的成员,而且还同时拥有旧的成员。我们称已存在的用来派生新类的类为基类,又称为父类。由已存在的类派生出的新类称为派生类,又称为子类。
### 举个例子
```js
class Hello extends Omi.Component {
constructor(data) {
super(data);
}
style () {
return `
div{
cursor:pointer;
}
`;
}
handleClick(target, evt){
alert(target.innerHTML);
}
render() {
return ' <div onclick="handleClick(this,event)">Hello {{name}}!</div>'
}
}
class SubHello extends Hello {
constructor(data) {
super(data);
}
}
Omi.render(new SubHello({ name : 'Omi' }),'#container');
```
<a href="http://alloyteam.github.io/omi/website/redirect.html?type=inherit" target="_blank">点击这里→在线试试</a>
### ES5下的继承
```js
var Hello = Omi.create("hello",{
render:function(){
return ' <div>Hello {{name}}!</div>'
}
})
var SubHello = Omi.create("sub-hello",Hello,{ });
Omi.render(new SubHello({ name : 'Omi' }),'#container');
```
<a href="http://alloyteam.github.io/omi/website/redirect.html?type=inherit_es5" target="_blank">点击这里→在线试试</a>

View File

@ -1,25 +0,0 @@
## 安装
[Omi](https://github.com/AlloyTeam/omi)(读音 / [ˈomɪ] /, 汉字类似于 欧米) 是一款用于创建用户界面的组件化框架开放并且现代故得名Omi。
### 安装 Omi
我们推荐使用 [npm](https://www.npmjs.com/) 来管理你的前端依赖.
通过npm安装Omi你只需要执行下面的命令:
``` js
$ npm install omi
```
## omi-cli
你也可以通过omi-cli去初始化你的项目:
``` js
$ npm install omi-cli -g //安装cli
$ omi init your_project_name //初始化项目,你也可以在一个空的文件夹下执行 omi init
$ cd your_project_name //如果你是在空文件夹下执行的 omi init。请无视这条命令
$ npm run dev //开发
$ npm run dist //部署发布
```

View File

@ -1,55 +0,0 @@
## 生命周期
|name |avatars |company |
|---|---|---|
| constructor | 构造函数 | new的时候 |
| install | 初始化安装这可以拿到用户传进的data进行处理 | 实例化 |
| installed | 安装完成HTML已经插入页面之后执行 | 实例化 |
| uninstall | 卸载组件。执行remove方法会触发该事件 | 销毁时 |
| beforeUpdate | 更新前 | 存在期 |
| afterUpdate | 更新后 | 存在期 |
| beforeRender | render函数执行之前 | 存在期和实例化 |
## 示意图
![lc](http://images2015.cnblogs.com/blog/105416/201703/105416-20170322083548924-1871234168.jpg)
### 举个例子
```js
class Timer extends Omi.Component {
constructor(data) {
super(data);
}
install () {
this.data = {secondsElapsed: 0};
}
tick() {
this.data.secondsElapsed++;
this.update();
}
installed(){
this.interval = setInterval(() => this.tick(), 1000);
}
uninstall() {
clearInterval(this.interval);
}
style () {
return `
.num { color:red; }
`;
}
render () {
return `<div>Seconds Elapsed:<span class="num"> {{secondsElapsed}}</span></div>`;
}
}
```
<a href="http://alloyteam.github.io/omi/website/redirect.html?type=lifecycle" target="_blank">点击这里→在线试试</a>

View File

@ -1,117 +0,0 @@
## 循环遍历
下面介绍mustache.js的方式和javascript遍历的方式。
### 方式零
```js
class List extends Omi.Component {
constructor(data) {
super(data);
}
render(){
return `<div>
<div o-repeat="item in items" o-if="item.show">
{{$index}}- {{item.text}}
</div>
</div>`
}
}
Omi.render(new List({
items: [
{ text: 'Omi', show: true },
{ text: 'dntzhang', show: true },
{ text: 'AlloyTeam'}
]
}),"body",true);
```
### 方式一
```js
class List extends Omi.Component {
constructor(data) {
super(data);
}
render () {
return `<div>
<ul>
{{#items}}
<li id="{{id}}">{{text}}</li>
{{/items}}
</ul>
</div>`;
}
}
Omi.render(new List({
items: [
{id: 1, text: 'Omi'},
{id: 2, text: 'dntzhang'},
{id: 3, text: 'AlloyTeam'}
]
}),"body");
```
mustache.js更详细的循环遍历使用可看[https://github.com/janl/mustache.js#non-empty-lists](https://github.com/janl/mustache.js#non-empty-lists)。 比如还支持:
* 如果items的每一项是字符串可以直接**{{.}}**的方式来输出每一项
* 循环的时候调用定义好的函数
<a href="http://alloyteam.github.io/omi/website/redirect.html?type=list" target="_blank">点击这里→在线试试</a>
### 方式二
既然ES6+了,当然可以使用${ }以及Array的map方法:
```js
class List extends Omi.Component {
constructor(data) {
super(data);
}
render() {
return `<div>
<ul>
${this.data.items.map(item =>
`<li id="${item.id}">${item.text}</li>`
).join('')}
</ul>
</div>`;
}
}
Omi.render(new List({
items: [
{id: 1, text: 'Omi'},
{id: 2, text: 'dntzhang'},
{id: 3, text: 'AlloyTeam'}
]
}),"body");
```
你将在页面看到如下效果:
![pv](http://images2015.cnblogs.com/blog/105416/201701/105416-20170122095724129-2059595233.png)
<a href="http://alloyteam.github.io/omi/website/redirect.html?type=list2" target="_blank">点击这里→在线试试</a>
如果想在循环里加些判断呢比如需要把id为偶数的隐藏起来:
```js
render() {
return `<div>
<ul>
${this.data.items.map(item =>
`<li style="display:${item.id%2===0?'none':'block'};" id="${item.id}">${item.text}</li>`
).join('')}
</ul>
</div>`;
}
```
所以模板字符串还是非常方便随着ES继续发展下去模板引擎估计会慢慢消失。所以omi提供了 omi.lite.js 版本不包含任何模板引擎。

View File

@ -1,273 +0,0 @@
## 插件体系
[Omi](https://github.com/AlloyTeam/omi)是Web组件化框架怎么又来了个插件的概念
可以这么理解: Omi插件体系可以赋予dom元素一些能力并且可以和组件的实例产生关联。
### omi-drag
且看这个例子:
<a href="http://alloyteam.github.io/omi/website/redirect.html?type=plugin" target="_blank">点击这里→在线试试</a>
```js
import OmiDrag from './omi-drag.js';
OmiDrag.init();
class App extends Omi.Component {
constructor(data) {
super(data);
}
render() {
return `
<div>
<div omi-drag class="test">Drag Me</div>
</div>
`;
}
style(){
return `
.test{
width:100px;
height:100px;
color:white;
line-height:90px;
text-align:center;
background-color:#00BFF3;
}
`
}
}
Omi.render(new App(),"#container");
```
如上面的代码所示通过在div上标记omi-drag这个div就能够被用户使用鼠标拖拽。我们称omi-drag.js为omi插件。
是不是非常方便那么这个omi-drag是怎么实现的
## Omi.extendPlugin
核心方法: Omi.extendPlugin( pluginName, handler )
下面的代码就是展示了如何通过 Omi.extendPlugin 赋予dom拖拽的能力:
```js
;(function () {
var OmiDrag = {};
var Omi = typeof require === 'function'
? require('omi')
: window.Omi;
OmiDrag.init = function(){
Omi.extendPlugin('omi-drag',function(dom, instance){
dom.style.cursor='move';
var isMouseDown = false,
preX = null,
preY = null,
currentX = null,
currentY = null,
translateX = 0,
translateY = 0;
dom.addEventListener('mousedown',function(evt){
isMouseDown = true;
preX = evt.pageX;
preY = evt.pageY;
evt.stopPropagation();
},false);
window.addEventListener('mousemove',function(evt){
if(isMouseDown){
currentX = evt.pageX;
currentY = evt.pageY;
if(preX != null){
translateX += currentX - preX;
translateY += currentY - preY;
dom.style.transform = 'translateX('+translateX+'px) translateY('+translateY+'px)';
}
preX = currentX;
preY = currentY;
evt.preventDefault();
}
},false);
window.addEventListener('mouseup',function(){
isMouseDown = false;
preX = preY = currentX = currentY = null;
},false);
});
}
OmiDrag.destroy = function(){
delete Omi.plugins['omi-drag'];
};
if (typeof exports == "object") {
module.exports = OmiDrag;
} else if (typeof define == "function" && define.amd) {
define([], function(){ return OmiDrag });
} else {
window.OmiDrag = OmiDrag;
}
})();
```
方法: Omi.extendPlugin( pluginName, handler )
其中pluginName为插件的名称
其中handler为处理器。handler可以拿到标记了pluginName的dom以及dom所在的组件的实例即 dom 和 instance。
通过 Omi.extendPlugin可以赋予dom元素一些能力也可以和组件的实例(instance)产生关联。
但是上面的例子没有和instance产生关联我们接下来试试:
## 关联instance
我们想在组件里面能够监听到move并且执行回调。如下:
```js
...
...
moveHandler(){
console.log('moving');
}
render() {
return `
<div>
<div omi-drag class="test">Drag Me</div>
</div>
`;
}
...
```
主要被拖动过程中moveHandler就不断地被执行。插件代码需要修改:
```js
...
window.addEventListener('mousemove',function(evt){
if(isMouseDown){
currentX = evt.pageX;
currentY = evt.pageY;
if(preX != null){
translateX += currentX - preX;
translateY += currentY - preY;
dom.style.transform = 'translateX('+translateX+'px) translateY('+translateY+'px)';
}
preX = currentX;
preY = currentY;
evt.preventDefault();
instance.moveHandler(evt);
}
},false);
```
我们在里面增加了instance.moveHandler(evt);方法用来执行组件实例上的moveHandler方法。
这样的话:就是组件的实例(instance)产生关联。但是还是有问题如果标记了多个omi-drag 就会有问题!如:
```js
...
render() {
return `
<div>
<div omi-drag class="test">Drag Me</div>
<div omi-drag class="test">Drag Me</div>
</div>
`;
}
...
```
通常我们系统每个omi-drag都能对应一个回调函数
```js
...
...
moveHandlerA(){
console.log('moving');
}
moveHandlerB(){
console.log('moving');
}
render() {
return `
<div>
<div omi-drag class="test">Drag Me A</div>
<div omi-drag class="test">Drag Me B</div>
</div>
`;
}
...
```
怎么办怎么实现有办法通过dom传递数据给插件。
## 传递数据
先来看最后实现的效果:
```js
...
...
moveHandlerA(){
console.log('moving');
}
moveHandlerB(){
console.log('moving');
}
render() {
return `
<div>
<div omi-drag class="test" dragMove="moveHandlerA" >Drag Me A</div>
<div omi-drag class="test" dragMove="moveHandlerB" >Drag Me B</div>
</div>
`;
}
...
```
omi-drag修改的地方:
```js
...
var handlerName = dom.getAttribute('dragMove');
window.addEventListener('mousemove',function(evt){
if(isMouseDown){
currentX = evt.pageX;
currentY = evt.pageY;
if(preX != null){
translateX += currentX - preX;
translateY += currentY - preY;
dom.style.transform = 'translateX('+translateX+'px) translateY('+translateY+'px)';
}
preX = currentX;
preY = currentY;
evt.preventDefault();
instance[handlerName](evt);
}
},false);
...
```
* 通过 var handlerName = dom.getAttribute('dragMove') 拿到dom上声明的dragMove
* 通过 instance[handlerName](evt) 去执行对应的方法
<a href="http://alloyteam.github.io/omi/website/redirect.html?type=plugin" target="_blank">点击这里→在线试试</a>
## 更多插件
* [omi-finger](https://github.com/AlloyTeam/omi/tree/master/plugins/omi-finger) Omi的[AlloyFinger](https://github.com/AlloyTeam/AlloyFinger)插件,支持各种触摸事件和手势
* [omi-transform](https://github.com/AlloyTeam/omi/tree/master/plugins/omi-transform) Omi的[transformjs](http://alloyteam.github.io/AlloyTouch/transformjs/)插件快速方便地设置DOM的CSS3 Transform属性
* [omi-touch](https://github.com/AlloyTeam/omi/tree/master/plugins/omi-touch) Omi的[AlloyTouch](https://github.com/AlloyTeam/AlloyTouch)插件Omi项目的触摸运动解决方案支持触摸滚动、旋转、翻页、选择等等
* [omi-jquery-date-picker](https://github.com/AlloyTeam/omi/tree/master/plugins/omi-jquery-date-picker) Omi的时间选择插件支持各种时间或者时间区域选择

View File

@ -1,346 +0,0 @@
## Store 体系
先说说Store系统是干什么的为什么要造这样一个东西能够给系统架构带来什么
当我们组件之间拥有共享的数据的时候经常需要进行组件通讯。在Omi框架里父组件传递数据给子组件非常方便
* 通过在组件上声明 data-* 或者 :data-* 传递给子节点
* 通过在组件上声明 data 或者 :data 传递给子节点 (支持复杂数据类型的映射)
* 声明 group-data 把数组里的data传给一堆组件传递支持复杂数据类型的映射
注:上面带有冒号的是[传递javascript表达式](https://github.com/AlloyTeam/omi/blob/master/tutorial/js-expression.md)
通过声明onXxx="xxxx"可以让子组件内执行父组件的方法。具体的如下图所示:
![](http://images2015.cnblogs.com/blog/105416/201703/105416-20170323100946955-1938506287.jpg)
如果还不明白的话,那... 我就直接上代码了:
```js
class Main extends Omi.Component {
handlePageChange(index){
this.content.goto(index+1)
this.update()
}
render () {
return `<div>
<h1>Pagination Example</h1>
<Content name="content" />
<pagination
name="pagination"
:data-total="100"
:data-page-size="10"
:data-num-edge="1"
:data-num-display="4"     
onPageChange="handlePageChange" ></pagination>
</div>`;
}
}
```
上面的例子中,
* 父组件的render方法里通过 data-✽ 传递数据给子组件 Pagination
* 通过onPageChange="handlePageChange"实现子组件与父组件通讯
详细代码可以点击: [分页例子地址](https://github.com/AlloyTeam/omi/tree/master/example/pagination)
当然你也可以使用event emitter / pubsub库在组件之间通讯比如这个只有 200b 的超小库[mitt](https://github.com/developit/mitt) 。但是需要注意mitt兼容到IE9+Omi兼容IE8。但是使用event emitter / pubsub库会对组件代码进行入侵所以非常不建议在基础非业务组件使用这类代码库。
虽然组件通讯非常方便,但是在真实的业务场景中,不仅仅是父子、爷孙、爷爷和堂兄、嫂子和堂弟...
onXxx="xxxx"就显得无能为力,力不从心了,各种数据传递、组件实例互操作、 emitter/pubsub或者循环依赖让代码非常难看且难以维护。所以
Omi.Store是用来管理共享数据以及共享数据的逻辑 。
Omi Store使用足够简便对架构入侵性极极极小(3个极代表比极小还要小)。下面一步一步从todo的例子看下Store体系怎么使用。
### 定义 Omi.Store
Omi.Store是基类我们可以继承Omi.Store来定义自己的Store比如下面的TodoStore。
```js
import Omi from 'omi'
class TodoStore extends Omi.Store {
constructor(data , isReady) {
super(isReady)
this.data = Object.assign({
items:[],
length:0
},data)
this.data.length = this.data.items.length
}
add(value){
this.data.items.push(value)
this.data.length = this.data.items.length
this.update()
}
clear(){
this.data.items.length = 0
this.data.length = 0
this.update()
}
}
export default TodoStore
```
TodoStore定义了数据的基本格式和数据模型的逻辑。
比如 this.data 就是数据的基本格式:
```js
{
items:[],
length:0
}
```
add和clear就是共享数据相关的逻辑。
值得注意的是在add和clear方法里都有调用this.update();这个是用来更新组件的this.update并不会更新所有组件。但是他到底会更新哪些组件呢等讲到store的addView方法你就明白了。
### 创建 Omi.Store
通过 new 关键字来使用TodoStore对象的实例。
```js
let store = new TodoStore({ /* 初始化数据 */ /* 数据是否准备好 */ })
```
上面可以传入一些初始化配置信息store里面便包含了整个应用程序共享的状态数据以及贡献数据逻辑方法(add,clear)。
当然这些初始化配置信息可能是异步拉取的。所以有两种方法解决异步拉取store配置的问题
* 拉取数据然后new TodoStore()再Omi.render
* 先let store = new TodoStore(),再Omi.render,组件内部监听store.ready拉取数据更改store的data信息然后执行store.beReady()
### 根组件注入 store
为了让组件树能够使用到 store可以通过Omi.render的第三个参数给根组件注入 store:
```js
Omi.render(new Todo(),'body',{
store: store
});
```
当然ES2015已经允许你这样写了:
```js
Omi.render(new Todo(),'body',{
store
});
```
两份代码同样的效果。
通过Omi.render注入之后在组件树的**所有组件**都可以通过 this.$store 访问到 store。
### 利用 beforeRender
为什么要说beforeRender这个函数 因为通过beforeRender转换store的data到组件的data这样store的数据和组件的数据就解耦开了。
beforeRender是生命周期的一部分。且看下面这张图:
![beforeRender](http://images2015.cnblogs.com/blog/105416/201703/105416-20170322083548924-1871234168.jpg)
不管是实例化或者存在期间在render之前会去执行beforeRender方法。所以可以利用该方法写store的data到组件data的转换逻辑。比如
```js
import Omi from '../../src/index.js';
import List from './list.js';
Omi.tag('list', List);
class Todo extends Omi.Component {
constructor(data) {
super(data)
}
install(){
this.$store.addView(this)
}
beforeRender(){
this.data.length = this.$store.data.items.length
}
add (evt) {
evt.preventDefault()
let value = this.data.text
this.data.text = ''
this.$store.add(value)
}
style () {
return `
h3 { color:red; }
button{ color:green;}
`;
}
clear(){
this.data.text = ''
this.$store.clear()
}
handleChange(evt){
this.data.text = evt.target.value
}
render () {
return `<div>
<h3>TODO</h3>
<button onclick="clear">Clear</button>
<list name="list" data="$store.data" ></list>
<form onsubmit="add" >
<input type="text" onchange="handleChange" value="{{text}}" />
<button>Add #{{length}}</button>
</form>
</div>`;
}
}
export default Todo;
```
为什么要去写beforeRender方法因为render只会使用this.data去渲染页面而不会去使用this.$store.data所以需要把数据转移到组件的this.data下。这样组件既能使用自身的data也能使用全局放this.$store.data了不会耦合在一起。
注意看上面的:
```js
install(){
this.$store.addView(this)
}
```
通过 addView 可以让 store 和 view也就是组件的实例 关联起来以后store执行update方法的时候关联的view都会自动更新
再看上面的子组件声明:
```js
<List name="list" data="$store.data" />
```
这样相当于把this.$store.data传递给了List组件。所以在List内部就不再需要写beforeRender方法转换了。
```js
class List extends Omi.Component {
constructor(data) {
super(data)
}
render () {
return ` <ul> {{#items}} <li>{{.}}</li> {{/items}}</ul>`
}
}
```
这里需要特别强调不需要把所有的数据提取到store里只提取共享数据就好了组件自身的数据还是放在组件自己进行管理。
## 异步数据
通常在真实的业务需求中数据并不是马上能够拿到。所以这里模拟的异步拉取的todo数据
```js
let todoStore = new TodoStore()
setTimeout(()=>{
todoStore.data.items = ["omi","store"];
todoStore.data.length = todoStore.data.items.length
todoStore.beReady();
},2000)
```
上面的beReady就是代码已经准备就绪在组件内部可以监听ready方法
```js
class Todo extends Omi.Component {
constructor(data) {
super(data)
}
install(){
this.$store.addView(this)
}
installed(){
this.$store.ready(()=>this.$store.update())
}
add (evt) {
evt.preventDefault()
if(!this.$store.isReady){
return
}
let value = this.data.text
this.data.text = ''
this.$store.add(value)
}
```
可以看到上面的add方法可以通过this.$store.isReady获取组件store是否准备就绪。
## 补充20170323
在omi v1.1.0及以后的版本中已经支持Omi.createStore快捷创建store。如:
```js
export default Omi.createStore({
data: {
items: ["omi", "store"]
},
methods: {
add: function (value) {
this.data.items.push(value)
this.data.length = this.data.items.length
this.update()
},
clear: function () {
this.data.items.length = 0
this.data.length = 0
this.update()
}
}
})
```
## 补充20170324
在omi v1.1.1及以后的版本中也支持省略Omi.createStore的形式创建store。如:
```js
export default {
data: {
items: ["omi", "store"]
},
methods: {
add: function (value) {
this.data.items.push(value)
this.data.length = this.data.items.length
this.update()
},
clear: function () {
this.data.items.length = 0
this.data.length = 0
this.update()
}
}
}
```
## 源码地址
* 更为详细的代码可以[点击这里](https://github.com/AlloyTeam/omi/tree/master/example/todo-store)
* 异步拉取的代码可以[点击这里](https://github.com/AlloyTeam/omi/tree/master/example/todo-store-async)

View File

@ -1,53 +0,0 @@
## 模板切换
[Omi框架](https://github.com/AlloyTeam/omi)到目前为止有三种版本。
* omi.js 使用 [sodajs](https://github.com/AlloyTeam/sodajs) 为内置指令系统
* omi.lite.js 不包含任何模板引擎
* omi.mustache.js 使用 [mustache.js](https://github.com/janl/mustache.js)为内置模版引擎
[sodajs](https://github.com/AlloyTeam/sodajs)是我们团队高级工程师(dorsywang)的作品服务员QQ群、兴趣部落等多个产品线
以良好的兼容性、卓越的性能、简便的语法、超小的尺寸以及强大的功能而深受同事们的喜爱。下面先来看看sodajs怎么使用。
Omi不强制开发者使用soda指令或者mustache.js模版引擎你可以根据业务场景使用任意模板引擎或者不使用模板引擎。
那么怎么使用别的模板引擎?下面拿[artTemplate](https://github.com/aui/artTemplate)作为例子。
### 使用artTemplate
```js
Omi.template = function(tpl, data){
return artTemplate.compile(tpl)(data);
}
```
重写Omi.template方法tpl为传入的模板data为模板所需的数据返回值为HTML。
重写完毕后就能在render使用artTemplate的语法
```js
class List extends Omi.Component {
constructor(data) {
super(data);
}
style () {
return `
h1 { color:red; }
li{ color:green;}
`;
}
render () {
return `<h1>{{title}}</h1>
<ul>
{{each list as value i}}
<li>索引 {{i + 1}} {{value}}</li>
{{/each}}
</ul>`;
}
}
```
### 相关地址
* [演示地址](http://alloyteam.github.io/omi/example/artTemplate/)
* [源码地址](https://github.com/AlloyTeam/omi/tree/master/example/artTemplate)

View File

@ -1,40 +0,0 @@
## Omi的理念
Omi的理念是基于面向对象编程体系内建积木系统和Store体系支持局部dom diff和update(这也是为什么没有使用虚拟dom)。
对比函数式编程、命令式编程与面向对象编程,可以归纳总结出下面几条:
- 命令式编程干脆直接,利用循环条件等控制流程,强调执行过程
- 命令式编程对硬件执行友好,运行更容易,却阻碍了复杂程序的设计
- 函数式强调输入和输出,并非执行过程
- 函数式倡导多个简单执行单元组合成复杂运算程序
- 面向对象编程将对象作为程序的基本单元,更具有重用性、灵活性和扩展性
Javascript是哪种类型的语言现在ES6+已经有了class。那么他是面向对象语言
但是JS可以在任意地方定义函数并且当作把函数当作值来传递。那么他是函数式编程语言
所以没有精准的定义取决于你的用法和姿势。其次Web组件化架构层面编程模型和语言层面编程模型是非常自由的关系。意思就是你可以用Javascript构建函数式编程框架如React也可以基于面向对象体系搭建Omi。
### 函数式编程 VS 面向对象编程
在UI组件框架层面函数式编程的代表有ReactOmi属于面向对象编程体系。那么他们各有什么优缺点下面做了个对比其实也是函数式编程与面向对象编程的对比
| | React | Omi |
| ------------- |:-------------:|:-----:|
| 组件通信 | ★★★★☆| ★★★★★ |
| 稳定性 | ★★★★★ | ★★★★☆ |
| 灵活性 | ★★★★☆| ★★★★★ |
| 扩展性 | ★★★★☆ | ★★★★★ |
| 测试性 | ★★★★★ | ★★★★☆ |
| 文件大小 | ★★★☆☆ | ★★★★★ |
| 功能特性 | ★★★☆☆ | ★★★★☆ |
| DOM性能 | ★★★★★ | ★★★★☆ |
| 动画性能 | ★★★★☆ | ★★★★★ |
| 抽象复杂度 | ★★★★☆ | ★★★★★ |
| 异步编程 | ★★★★★ | ★★★★☆ |
总结来说更加推荐使用面向对象的方式去搭建UI组件化框架。
<hr/>
### 全文结束,感谢阅读。[开始Omi之旅吧!](https://github.com/AlloyTeam/omi)

View File

@ -1,53 +0,0 @@
let config = {
menus: {
cn: [
{
active: true,
title: '快速开始',
currentIndex: 0,
list: [
{'name': '安装', md: 'installation'},
{'name': 'Hello World', md: 'hello_world'},
{'name': '组件', md: 'components'},
{'name': '组件通讯', md: 'communication'},
{'name': '生命周期', md: 'lifecycle'},
{'name': '事件处理', md: 'events'},
{'name': '条件判断', md: 'condition'},
{'name': '循环遍历', md: 'loop'},
{'name': 'Store体系', md: 'store'},
{'name': '表单', md: 'form'},
{'name': '继承', md: 'inherit'},
{'name': '模板切换', md: 'template'},
{'name': '获取DOM节点', md: 'get_dom'},
{'name': '插件体系', md: 'plugin'},
{'name': 'Omi的理念', md: 'thinking_in_omi'}
]
}
],
en: [
{
title: 'QUICK START',
active: true,
currentIndex: 0,
list: [
{'name': 'Installation', md: 'installation'},
{'name': 'Hello World', md: 'hello_world'},
{'name': 'Components', md: 'components'},
{'name': 'Communication', md: 'communication'},
{'name': 'Lifecycle', md: 'lifecycle'},
{'name': 'Handling Events', md: 'events'},
{'name': 'Conditional Rendering', md: 'condition'},
{'name': 'Loop', md: 'loop'},
{'name': 'Forms', md: 'form'},
{'name': 'Inheritance', md: 'inherit'},
{'name': 'Templates', md: 'template'},
{'name': 'Get DOM', md: 'get_dom'},
{'name': 'Plugin', md: 'plugin'},
{'name': 'Thinking in Omi', md: 'thinking_in_omi'}
]
}
]
}
}
export default config;

View File

@ -1,269 +0,0 @@
## Component Communication
Communication between [Omi](https://github.com/AlloyTeam/omi) components is very flexible, there are many options:
- By declaring `data-*` on the component to pass data to child node
- By declaring `data` on the component to pass data to child node (support complex data types mapping)
- By declaring `group-data` (support complex data types mapping)
- It's completely object-oriented, you can easily get the object instance, then you can set the instance of the property or call the instance of the method
Let's see some examples.
### Communicate by `data-*`
```js
class Hello extends Omi.Component {
constructor(data) {
super(data);
}
style () {
return `
h1{
cursor:pointer;
}
`;
}
handleClick(target, evt){
alert(target.innerHTML);
}
render() {
return `
<div>
<h1 onclick="handleClick(this, event)">Hello ,{{name}}!</h1>
</div>
`;
}
}
Omi.makeHTML('Hello', Hello);
class App extends Omi.Component {
constructor(data) {
super(data);
}
render() {
return `
<div>
<Hello data-name="Omi" />
</div>
`;
}
}
Omi.render(new App(),"#container");
```
Generally `data-*` is used to pass value types such as string and number. It is worth noting that, through `data-*`, received data types are string. You need to manually transform it to the number type.
Normally, communicate by `data-*` is enough, but sometimes we may need to use complex data types, then we can use `data` to communicate.
### Communicate by `data`
As shown in the above code, name can be passed to the subcomponent by `data-name="Omi"`. The following code can also achieve the same effect.
```js
...
class App extends Omi.Component {
constructor(data) {
super(data);
this.helloData = { name : 'Omi' };
}
render() {
return `
<div>
<Hello data="helloData" />
</div>
`;
}
}
Omi.render(new App(),"#container");
```
Use the `data` tag, it will find the property from the component instance (that is, this), this can be mounted with any complex objects. This also broke the limitations of `data-*`.
Then how do we pass `data` that is in a deep depth of the instance to the Hello? No worries, `data` tag can be a complex statement:
```js
...
class App extends Omi.Component {
constructor(data) {
super(data);
this.complexData ={
a:{
b:{
c:[
{
e:[{
name:'ComplexData Support1'
},{
name:'ComplexData Support2'
}]
},
{
name: 'ComplexData Support3'
}
]
}
}
};
}
render() {
return `
<div>
<Hello data="complexData.a.b.c[1]" />
</div>
`;
}
}
...
```
<a href="http://alloyteam.github.io/omi/website/redirect.html?type=data_complex" target="_blank">Click me for the complex data mapping</a>
### Communicate by `group-data`
`group-data` can pass data to a group of components.
```js
import Hello from './hello.js';
Omi.makeHTML('Hello', Hello);
class App extends Omi.Component {
constructor(data) {
super(data);
this.testData = [{name: 'Omi'}, {name: 'dntzhang'}, {name: 'AlloyTeam'}];
}
render() {
return `
<div>
<Hello group-data="testData" />
<Hello group-data="testData" />
<Hello group-data="testData" />
</div>
`;
}
}
Omi.render(new App(),"#container");
```
By declaring a `group-data` tag in the sub-components, it will go to the current instance of the component (that is, `this`) to find the corresponding property. Then according to the current location, the data will pass to the positions one by one.
The results are as follows:
![group-data results](http://images2015.cnblogs.com/blog/105416/201702/105416-20170216110701535-1698390390.png)
<a href="http://alloyteam.github.io/omi/website/redirect.html?type=group_data" target="_blank">Click me for the group-data example</a>
Similarly, `group-data` supports the mapping of complex data types. It should be noted that the end of the group-data mapping must be an array:
```js
import Hello from './hello.js';
Omi.makeHTML('Hello', Hello);
class App extends Omi.Component {
constructor(data) {
super(data);
this.complexData ={
a:{
b:{
c:[
{
e:[{
name:'ComplexData Support1'
},{
name:'ComplexData Support2'
}]
},
{
name: 'ComplexData Support3'
}
]
}
}
};
}
render() {
return `
<div>
<Hello group-data="complexData.a.b.c[0].e" />
<Hello group-data="complexData.a.b.c[0].e" />
</div>
`;
}
}
Omi.render(new App(),"#container");
```
<a href="http://alloyteam.github.io/omi/website/redirect.html?type=group_data_complex" target="_blank">Click me for the complex group-data mapping</a>
### By object instance
```js
...
class App extends Omi.Component {
constructor(data) {
super(data);
}
installed(){
this.hello.data.name = "Omi";
this.update()
}
render() {
return `
<div>
<Hello name="hello" />
</div>
`;
}
}
Omi.render(new App(),"#container");
```
### By omi-id
```js
...
class App extends Omi.Component {
constructor(data) {
super(data);
}
installed(){
Omi.get("hello").data.name = "Omi";
this.update()
}
render() {
return `
<div>
<Hello omi-id="hello" />
</div>
`;
}
}
Omi.render(new App(),"#container");
```
By declaring `omi-id` on the component, we can get the instance of the object anywhere in the program. This can be regarded as any component communication artifacts.

View File

@ -1,135 +0,0 @@
## Components
[Omi](https://github.com/AlloyTeam/omi) is based entirely on component architecture, which allows developers to build web applications like building blocks. Everything is components, components can be nested to create new components.
![Omi Components System](http://images2015.cnblogs.com/blog/105416/201702/105416-20170210093427338-1536910080.png)
### Simple Components
Let's explore a simple Todo example to learn the components system in Omi.
```js
class Todo extends Omi.Component {
constructor(data) {
super(data);
}
add (evt) {
evt.preventDefault();
this.data.items.push(this.data.text);
this.data.text = '';
this.update();
}
style () {
return `
h3 { color:red; }
button{ color:green;}
`;
}
handleChange(target){
this.data.text = target.value;
}
render () {
return `<div>
<h3>TODO</h3>
<ul> {{#items}} <li>{{.}}</li> {{/items}}</ul>
<form onsubmit="add(event)" >
<input type="text" onchange="handleChange(this)" value="{{text}}" />
<button>Add #{{items.length}}</button>
</form>
</div>`;
}
}
Omi.render(new Todo({ items: [] ,text : '' }),"body");
```
The HTML generated by the component will eventually be inserted into the body. The above example shows some of the features of Omi:
- Data flow: `data` in `new Todo(data,..)` can be used directly in the template in render method.
- Partial CSS: `h3` in `style()` only effect inside of render. It'll never pollute `h3` outside of this component. The same rule applies to `button`.
- Declarative event binding: `onchange` will call `handleChange` that inside of the component. `this` refers to the current DOM element, `event` refers to the current DOM Event Object.
- You need to manually call the `this.update()` method to update the component
It is important to note that, for more freedom and flexibility, Omi does not automatically update DOM while data changes. Developers need to call the `update` method manually.
You can also use [oba] (https://github.com/dntzhang/oba) or mobx to implement automatic updates.
<a href="http://alloyteam.github.io/omi/website/redirect.html?type=todo" target="_blank">Click me for the live demo</a>
### Component Nesting
It's ok to not use nesting component if your page is super simple. However, for most of webpages and web applications, it is a necessary to define the nesting Components to implement complex features.
For instance, we can extract a `List` component form the Todo example. This brings maintainable, scalable and reuseable to our project:
```js
class List extends Omi.Component {
constructor(data) {
super(data);
}
render () {
return `<ul> {{#items}} <li>{{.}}</li> {{/items}}</ul>`;
}
}
```
Then how to use this `List`? We need to use `Omi.makeHTML` to make the `List` to a tag which can be used in render method:
```js
import List from './list.js';
Omi.makeHTML('List', List);
class Todo extends Omi.Component {
constructor(data) {
super(data);
this.data.length = this.data.items.length;
this.listData = { items : this.data.items };
}
add (evt) {
evt.preventDefault();
this.list.data.items.push(this.data.text);
this.data.length = this.list.data.items.length;
this.data.text = '';
this.update();
}
style () {
return `
h3 { color:red; }
button{ color:green;}
`;
}
handleChange(target){
this.data.text = target.value;
}
render () {
return `<div>
<h3>TODO</h3>
<List name="list" data="listData" />
<form onsubmit="add(event)" >
<input type="text" onchange="handleChange(this)" value="{{text}}" />
<button>Add #{{length}}</button>
</form>
</div>`;
}
}
```
- In line 3, we use `makeHTML` to make the component to a tag which can be used in render method. Of course, `Omi.makeHTML('List', List);` can also be written in the end of List component.
- In line 9, the parent component defines the 'listData' property
- In line 34, we use List component in the render method. `name` attribute allows us easily find the instance of the component by using `this`.`data="listData"` attribute allows us easily pass `this.listData` to the sub component from parent component.
It should be noted that the `data` passed from `data="listData"` is cloned to the subcomponents by Object.assign(shallow copy) , which means if we want to change the DOM, we recommend that first update the `data` of the instance of subcomponent(not the parent component's `listData` ) and secondly call the `update` method.
In fact there are 4 way to communicate between components, it'll be explained later.
<a href="http://alloyteam.github.io/omi/website/redirect.html?type=todo_nest" target="_blank">Click me for the live demo</a>

View File

@ -1,68 +0,0 @@
## Conditional Rendering
In most case, we need to show different layouts according to different states. For example, some users are vip and we need to show vip logo for them. Omi has many ways to meet this kind of requirements.
### First Option
```js
class ConditionTest extends Omi.Component {
constructor(data) {
super(data);
}
render () {
return `{{#isVip}}
<div>you are VIP.</div>
{{/isVip}}
{{^isVip}}
<div>you are not VIP.</div>
{{/isVip}}`;
}
}
```
In the above case, we use the condition in mustachejs for rendering. Of course Omi does not force you to use mustachejs. You can use omi.lite.js and then override the `Omi.template` method to use any of your favorite template engines.
### Second Option
```js
class ConditionTest extends Omi.Component {
constructor(data) {
super(data);
}
render () {
if(this.data.isVip){
return '<div>you are VIP.</div>';
}else{
return '<div>you are not VIP.</div>';
}
}
}
```
`render` provides a very good programmability, which can write any js code inside. Oh, don't forget that `style` method can also have js code inside it.
```js
class ConditionTest extends Omi.Component {
constructor(data) {
super(data);
}
style (){
if(this.data.isVip){
return 'div{ color : red; }';
}else{
return 'div{ color : green; }';
}
}
render () {
if(this.data.isVip){
return '<div>you are VIP.</div>';
}else{
return '<div>you are not VIP.</div>';
}
}
}
```

View File

@ -1,112 +0,0 @@
## Handling Events
There are two types of events in Omi, built-in events and custom events. Built-in events clever use of the browser's own pipeline mechanism, you can easily get events instance and the triggered event elements through `event` and `this`.
### Built-in events
What is the built-in event? As long as the it can match the following regular expression.
```js
on(abort|blur|cancel|canplay|canplaythrough|change|click|close|contextmenu|cuechange|dblclick|drag|dragend|dragenter|dragleave|dragover|dragstart|drop|durationchange|emptied|ended|error|focus|input|invalid|keydown|keypress|keyup|load|loadeddata|loadedmetadata|loadstart|mousedown|mouseenter|mouseleave|mousemove|mouseout|mouseover|mouseup|mousewheel|pause|play|playing|progress|ratechange|reset|resize|scroll|seeked|seeking|select|show|stalled|submit|suspend|timeupdate|toggle|volumechange|waiting|autocomplete|autocompleteerror|beforecopy|beforecut|beforepaste|copy|cut|paste|search|selectstart|wheel|webkitfullscreenchange|webkitfullscreenerror|touchstart|touchmove|touchend|touchcancel|pointerdown|pointerup|pointercancel|pointermove|pointerover|pointerout|pointerenter|pointerleave)
```
How to bind built-in events? As follows:
```js
class EventTest extends Omi.Component {
constructor(data) {
super(data);
}
handleClick(dom, evt){
alert(dom.innerHTML);
}
render () {
return `<div onclick="handleClick(this, event)">Hello, Omi!</div>`;
}
}
```
### Custom events
Events that defined by developers is the custom events. Here is the pagination example:
```js
import Omi from '../../src/index.js';
import Pagination from './pagination.js';
import Content from './content.js';
Omi.makeHTML('Pagination', Pagination);
Omi.makeHTML('Content', Content);
class Main extends Omi.Component {
constructor(data) {
super(data);
}
installed(){
this.content.goto(this.pagination.data.currentPage+1);
}
handlePageChange(index){
this.content.goto(index+1);
}
render () {
return `<div>
<h1>Pagination Example</h1>
<Content name="content" />
<Pagination
name="pagination"
data-total="100"
data-page-size="10"
data-num-edge="1"
data-num-display="4"     
onPageChange="handlePageChange" />
</div>`;
}
}
Omi.render( new Main(),'body');
```
As we can see, the `onPageChange` is a custom event, `handlePageChange` will being executed when `onPageChange` is triggered. The `onPageChange` method is executed in `Pagination`:
```js
import Omi from '../../src/index.js';
class Pagination extends Omi.Component {
...
...
...
linkTo: "#",
prevText: "Prev",
nextText: "Next",
ellipseText: "...",
prevShow: true,
nextShow: true,
onPageChange: function () { return false; }
}, this.data);
this.pageNum = Math.ceil(this.data.total / this.data.pageSize);
}
goto (index,evt) {
evt.preventDefault();
this.data.currentPage=index;
this.update();
this.data.onPageChange(index);
}
...
...
...
}
```
This is a part of `Pagination` code. Highlight is the place to execute `onPageChange`.
### Links
- [Demo](http://alloyteam.github.io/omi/example/pagination/)
- [Source](https://github.com/AlloyTeam/omi/tree/master/example/pagination)

View File

@ -1,81 +0,0 @@
## Forms
It's much more convenient to control forms in Omi, especially `<select>`!
### select element
In the past, we needed to select an option in the following way:
```html
<select>
<option value="grapefruit">Grapefruit</option>
<option value="lime">Lime</option>
<option selected value="coconut">Coconut</option>
<option value="mango">Mango</option>
</select>
```
The third option is selected because it is being set to `selected` attribute. The problem is that developers need to traversed each option. While using Omi, you can write code like this:
```html
<select value="coconut">
<option value="grapefruit">Grapefruit</option>
<option value="lime">Lime</option>
<option value="coconut">Coconut</option>
<option value="mango">Mango</option>
</select>
```
This will achieve the same effect. For example, you want to choose the first item:
```html
<select value="grapefruit">
<option value="grapefruit">Grapefruit</option>
<option value="lime">Lime</option>
<option value="coconut">Coconut</option>
<option value="mango">Mango</option>
</select>
```
Isn't it very convenient?
### For Example
```js
class FormTest extends Omi.Component {
constructor(data) {
super(data);
}
handleChange(target){
console.log(target.value)
this.data.value = target.value;
}
handleSubmit(evt) {
alert('Your favorite flavor is: ' + this.data.value);
evt.preventDefault();
}
render () {
return `
<form onsubmit="handleSubmit(event)">
<label>
Pick your favorite La Croix flavor:
<select value="{{value}}" onchange="handleChange(this)">
<option value="grapefruit">Grapefruit</option>
<option value="lime">Lime</option>
<option value="coconut">Coconut</option>
<option value="mango">Mango</option>
</select>
</label>
<input type="submit" value="Submit" />
</form>`;
}
}
Omi.render(new FormTest({ value: 'mango' }),'#container');
```
<a href="http://alloyteam.github.io/omi/website/redirect.html?type=form" target="_blank">Click me for a live demo</a>

View File

@ -1,41 +0,0 @@
## Get DOM
While most of the time, developers do not need to find the DOM, but sometimes is a need to get the DOM.
Omi provides a way to get the DOM node.
### ref and refs
```js
class Hello extends Omi.Component {
constructor(data) {
super(data);
}
style () {
return `
h1{
cursor:pointer;
}
`;
}
handleClick(){
alert(this.refs.abc.innerHTML);
}
render() {
return `
<div>
<h1 ref="abc" onclick="handleClick()">Hello ,{{name}}!</h1>
</div>
`;
}
}
Omi.render(new Hello({ name : "Omi" }),"#container");
```
As we can see, by referencing `ref` as `abc` in HTML, the DOM node can be accessed through `this.refs.abc`.
<a href="http://alloyteam.github.io/omi/website/redirect.html?type=ref" target="_blank">Click me for the live demo</a>

View File

@ -1,80 +0,0 @@
## Hello World
### Hello World with ES20XX
We recommend using a bundler like [webpack](https://webpack.github.io/) or [Browserify](http://browserify.org/) so you can write modular code and bundle it together into small packages to optimize load time.
The small Omi example looks like this:
```js
import Omi from './omi.js';
class Hello extends Omi.Component {
constructor(data) {
super(data);
}
style () {
return `
h1{
cursor:pointer;
}
`;
}
handleClick(target){
alert(target.innerHTML);
}
render() {
return `
<div>
<h1 onclick="handleClick(this)">Hello ,{{name}}!</h1>
</div>
`;
}
}
Omi.render(new Hello({ name : "Omi" }),"body");
```
This code renders into body element.
### Hello World with ES5
```html
<script src="omi.js"></script>
```
then:
```js
var Hello = Omi.create("Hello", {
style: function () {
return "h1{ cursor:pointer }";
},
handleClick: function (dom) {
alert(dom.innerHTML)
},
render: function () {
return ' <div>\
<h1 onclick="handleClick(this, event)">\
Hello ,{{name}}!\
</h1>\
</div>'
}
});
var Test = Omi.create("Test", {
render: function () {
return '<div>\
<div>Test</div>\
<Hello data-name="Omi" />\
</div>'
}
});
Omi.render(new Test(),'#container');
```

View File

@ -1,58 +0,0 @@
## Inheritance
Through the inheritance mechanism, we can define new classes base on old classes. The new classes not only have newly defined members, but also have old members at the same time.
We call the existing class the base class, also known as the parent class. And the new class derived from the existing class is called a derived class, also known as a subclass.
### For Example
```js
class Hello extends Omi.Component {
constructor(data) {
super(data);
}
style () {
return `
div{
cursor:pointer;
}
`;
}
handleClick(target, evt){
alert(target.innerHTML);
}
render() {
return ' <div onclick="handleClick(this,event)">Hello {{name}}!</div>'
}
}
class SubHello extends Hello {
constructor(data) {
super(data);
}
}
Omi.render(new SubHello({ name : 'Omi' }),'#container');
```
<a href="http://alloyteam.github.io/omi/website/redirect.html?type=inherit" target="_blank">Click me for the live demo</a>
### inherit in ES5
```js
var Hello = Omi.create("Hello",{
render:function(){
return ' <div>Hello {{name}}!</div>'
}
})
var SubHello = Omi.create("SubHello",Hello,{ });
Omi.render(new SubHello({ name : 'Omi' }),'#container');
```
<a href="http://alloyteam.github.io/omi/website/redirect.html?type=inherit_es5" target="_blank">Click me for the live demo</a>

View File

@ -1,22 +0,0 @@
## Installation
[Omi](https://github.com/AlloyTeam/omi) is open and modern framework for building user interfaces.
### Installing Omi
We recommend using [npm](https://www.npmjs.com/) for managing front-end dependencies. If you're new to package managers.
To install Omi with npm, run:
``` js
$ npm install omi
```
### omi-cli
``` js
$ npm install omi-cli -g
$ omi init your_project_name
$ cd your_project_name
$ npm run dev
$ npm run dist
```

View File

@ -1,56 +0,0 @@
## Lifecycle
| Name | Meaning | Occasion |
| :-------------: | :-------------: | :-----: |
| constructor | The constructor | When new a constructor |
| install | The installation. We can process the data that user pass | When instantiate |
| installed | Complete the installation. It'll trigger after HTML being inserted to the page. Please note that it'll trigger when component being removed and restored | **Instantiation and existence** |
| uninstall | Uninstall the component. It'll trigger when remove is executed | When destroy |
| beforeUpdate | Before update | When existence |
| afterUpdate | After update | When existence |
## Illustration
![lc](http://images2015.cnblogs.com/blog/105416/201703/105416-20170322084234049-1482108845.jpg)
It should be noted that the installed will be executed during the instantiation, which is not shown above. For example, it'll executed when a component is removed and restored, or when the new component is being added.
### Examples
```js
class Timer extends Omi.Component {
constructor(data) {
super(data);
}
install () {
this.data = {secondsElapsed: 0};
}
tick() {
this.data.secondsElapsed++;
this.update();
}
installed(){
this.interval = setInterval(() => this.tick(), 1000);
}
uninstall() {
clearInterval(this.interval);
}
style () {
return `
.num { color:red; }
`;
}
render () {
return `<div>Seconds Elapsed:<span class="num"> {{secondsElapsed}}</span></div>`;
}
}
```
<a href="http://alloyteam.github.io/omi/website/redirect.html?type=lifecycle" target="_blank">Click me for the live demo</a>

Some files were not shown because too many files have changed in this diff Show More