diff --git a/docs/.nojekyll b/docs/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..96f1b29 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,26 @@ + +# BUI 入门教程 + + + +| **描述** | **修订日期** | **修订人** | +|:--------------------|---------------:|---------------:| +| BUI 1.4.3 重新整理文档 |2018-04-25 | 王伟深 | + + +欢迎加入我们的QQ技术交流群: + +BUI 移动开发交流群1: `691560280` + + +## 面向的开发者 + +?> 需要掌握一点前端基础知识, `html`,`css`,`javascript`或`jQuery` + +- 后端开发者 +- 美工 +- 前端开发者 + + + +[查看更多介绍](chapter1/about) \ No newline at end of file diff --git a/docs/_navbar.md b/docs/_navbar.md new file mode 100644 index 0000000..fa446e9 --- /dev/null +++ b/docs/_navbar.md @@ -0,0 +1,7 @@ +- [Demo](http://www.easybui.com/demo/) +- [API](http://www.easybui.com/demo/api/) +- FAQ + - [常见问题](faq.md) + - [我要提问](https://github.com/imouou/BUI-Guide/issues/new) +- 原生API + - [Link API](http://dev.bingocc.com/btapi/) diff --git a/docs/_sidebar.md b/docs/_sidebar.md new file mode 100644 index 0000000..55f7663 --- /dev/null +++ b/docs/_sidebar.md @@ -0,0 +1,35 @@ +* 入门 + + * [为什么用BUI?](chapter1/why.md) + * [介绍](chapter1/about.md) + * [安装](chapter1/installation.md) + * [快速开始](chapter1/quickstart.md) + * [多页路由](chapter1/multipage.md) + * [数据交互](chapter1/request.md) + * [布局](chapter1/layout.md) + * [调试](chapter1/debug.md) + + +* 进阶 + * [单页路由](chapter2/router.md) + * [模块化](chapter2/loader.md) + * [动画交互](chapter2/animate.md) + * [常用方法](chapter2/method.md) + * [控件用法](chapter2/controls.md) + * [打包独立应用](chapter2/package.md) + +* 效率 + * [BUI-Fast](tools/buifast.md) + * [buijs-cli](tools/buijs.md) + * [bui-template](tools/bui-template.md) + +* 规范 + * [切图规范](ui/cutimage.md) + * [开发规范](ui/standard.md) + * [样式规范](ui/style.md) + + +* 控件 + + +* [更新日志](changelog.md) diff --git a/docs/changelog.md b/docs/changelog.md new file mode 100644 index 0000000..b0c054f --- /dev/null +++ b/docs/changelog.md @@ -0,0 +1,1025 @@ +# BUI 版本更新日志 + + +## 目录 +[TOC] + + +## 1.4.4 20180501 + +### 升级指南 + +** 一, 资源替换: ** + +执行命令, 选择你使用的平台 +``` +# 更新 webapp 平台 bui.css, bui.js +$ buijs update + +# 更新 dcloud 平台 bui.css, bui.js +$ buijs update -p dcloud + +# 更新 apicloud 平台 bui.css, bui.js +$ buijs update -p apicloud + +# 更新 appcan 平台 bui.css, bui.js +$ buijs update -p appcan +``` + +会自动更新最新的 bui.css bui.js 文件 + + +### 重要修改 + +### 优化-修复-维护 + +#### bui.upload +1. 修复 上传文件的 data 不能附带参数问题 + +#### bui.list, bui.pullrefresh, bui.slide, bui.scroll, bui.dialog +1. 修复高度自动计算时,受键盘影响问题 + +#### bui.accordion +1. 修复配合全局初始化,在单页使用时导致部分失效的问题 + + +## 1.4.3 20180427 + +### 升级指南 + +** 一, 资源替换: ** + +执行命令, 选择你使用的平台 +``` +# 更新 webapp 平台 bui.css, bui.js +$ buijs update + +# 更新 dcloud 平台 bui.css, bui.js +$ buijs update -p dcloud + +# 更新 apicloud 平台 bui.css, bui.js +$ buijs update -p apicloud + +# 更新 appcan 平台 bui.css, bui.js +$ buijs update -p appcan +``` + +会自动更新最新的 bui.css bui.js 文件 + + +### 重要修改 + +修复 bui.ajax 不进入 fail 状态. + +修复字体图标冲突, 当你加入新的字体图标时, 会出现图标冲突的情况, 需要替换新的 bui.css 文件, 另外新的图标命名, 不要使用 icon- 开头, 可以是 icons- 啥的. + +### 优化-修复-维护 + +#### bui.select +1. 修复bui.select的onChange事件, 只有值改变的时候才触发 +2. 新增 appendTo 参数, 便于跟单页绑定 + +#### bui.router +1. 新增 "preloadend" 预加载结束事件 +2. 修复路由在bui.ready无法初始化问题 +3. 新增indexModule 参数,用于修改首页的指向 +4. 新增initScroll 方法,用于手动修改footer显示隐藏,main的高度不准确问题 +5. 修复 有键盘时,跳转的时候, 页面高度不准确问题 +6. 支持链接是 tel: 开头,会调用拨打电话功能, sms: 发短信 , mailto: 写邮件 + + +#### bui.loader +1. 修复return, exports 导出模块以后,重复加载模块, 如果有控件抛出,控件的引用是第一次的控件. +2. 修复多页开发使用bui.loader 定义的依赖模块,baseUrl的相对路径问题 not done. +3. 修复定义的第三方依赖的模块 + +#### bui.dialog +1. 新增 appendTo 参数, 便于跟单页绑定 + +#### bui.actionsheet +1. 新增 appendTo 参数, 便于跟单页绑定 + +#### bui.pickerdate +1. 新增 appendTo 参数, 便于跟单页绑定 + +#### bui.scroll +1. 新增 scrollTop 方法, 用于单页A标签无法处理的锚点跳转 + + +#### bui.checkVersion +1. 修复不支持打开https +2. 简化ios下载 + + +#### bui.load +1. 支持链接是 tel: 开头,会调用拨打电话功能, sms: 发短信 , mailto: 写邮件 + +#### bui.btn +1. 支持链接是 tel: 开头,会调用拨打电话功能, sms: 发短信 , mailto: 写邮件 + + +#### bui.slide +1. tab模式下,新增按钮的disabled 属性或样式, 阻止点击跳转, 这样便于使用其它跳转方式 +2. 在纵向滚动下, rem 的高度缩放存在问题 +3. 修复to事件监听,在动态加载tab时,webapp存在延迟会导致js先执行,再渲染模板 +3. 新增autoheight 参数, 便于在一些特殊情况使用, 比方tab 是在中间部分,由内容决定高度 + + +#### bui.listview +1. 修复默认宽度只能是屏幕宽度问题 +2. 删除 height 参数 +2. 新增menuWidth,menuHeight 等参数 + +#### bui.swipe +1. 修复默认宽度只能是屏幕宽度问题 + +#### bui.number +1. 新增onInput参数 + + + +## 1.4.2 20180329 + +### 升级指南 +** 一, 资源替换: ** + +执行命令, 选择你使用的平台 +``` +# 更新 webapp 平台 bui.css, bui.js +$ buijs update + +# 更新 dcloud 平台 bui.css, bui.js +$ buijs update -p dcloud + +# 更新 apicloud 平台 bui.css, bui.js +$ buijs update -p apicloud + +# 更新 appcan 平台 bui.css, bui.js +$ buijs update -p appcan +``` + +会自动更新最新的 bui.css bui.js 文件 + +### 重要修改 + +#### buijs cli 升级, 已经安装过的朋友,需要重新安装, +windows: +``` +npm install -g buijs +``` +mac: +``` +sudo npm install -g buijs +``` + +1. 修复创建工程时,没有网络不进行处理; +2. 修改了目录工程规范, 新建项目全部在 src 目录下, 对旧项目没有影响; +3. 支持自动编译,开启服务器,允许接口跨域等问题, 减少对工具的依赖; 使用方法请查看 buijs的readme.md + +#### 新增 BUI-fast ATOM编辑器插件 + + +### 新增 + +#### bui.array +1. 新增, 把常用的数组比对放在这个对象里, 不再有 bui.inArray, bui.compareArray 等这些都在 bui.array 里面查找 + +所有控件,新增控件的 destroy 方法, 用于销毁事件,内容,释放内存, 一般用在单页路由的后退上. + + +### 优化-修复-维护 + +#### bui.router +1. 新增preload方法,预加载错误页面 +2. 新增 currentPage 方法,可以获得当前的对象, 可以解决重复加载的页面模块,以及重复加载的控件 +3. 修复页面切换进度条问题 +4. 修复loadpart局部加载的重复加载问题 +5. 修复替换页面,替换的页面为已经加载过的页面,会导致无法后退问题 +6. 修复无法重复替换页面问题 +7. 修复替换页面以后,如果替换的页面是已经存在历史记录的,再点击跳多一层, 这时后退的应该是最靠近最后一层的数据. 之前是取最前面的历史记录 +8. 刷新也会加载iframe地址, 模块名不能以 http:// 或者 https:// 开头 +9. 修复后退问题 +10. 路由加载同一个页面的id重复问题 +11. 通过网址修改地址,会导致页面后退问题 +12. 修复刷新问题 +13. 单页应用跟单页应用的交互 +14. 修复先require一个模块,路由跳转的时候,就不再触发的问题 +15. 优化页面切换速度,更快 +16. 修复连续跳转时, 不能后退问题 +17. 修复无网络时,点击页面,再恢复网络时,触发不了事件 +18. 修复先map配置首页后, 使用replace方法还会有历史记录 + +19. 支持iframe跳转 +20. 控件事件监听里面 currentTarget 统一改为 target; +21. 修复bui.getPageParams 刷新传参失效; +22. 修复bui.getPartParams 局部加载接收不到 + +#### bui.loader +1. 修复checkLoad方法,不能单独检测一个模块 +2. 修复module.exports 的导出不被认可 +3. 修复loader.require 不能引入对应的模块 + +#### bui.pickerdate +1. 修复 cols 修改以后,显示时,布局凌乱 + +#### bui.pullrefresh +1. 修复 底部菜单是原生框时, 下拉刷新滑动距离过长,会导致不会触发. +2. 新增 stopHandle 参数, 禁止操作的样式名 + +#### bui.scroll +1. 新增 stopHandle 参数, 禁止操作的样式名 + + +#### bui.slide +1. to 方法,增加路径名跳转,自动查找对应的索引 +2. 新增 stopHandle 参数, 禁止操作的样式名 + + +#### bui.load +1. 新增iframe参数,用于单页加载外部网址 +1. 新增reload参数,用于单页应用跳转到另外一个单页应用 + + +#### bui.list +1. 修复callback 的事件绑定,会导致子集的冒泡无法阻止 +2. 新增 stopHandle 参数, 禁止操作的样式名 +3. 修复与vue一起协作时,高度过高但只请求一页,接下来不再触发的问题 + +#### bui.swipe +1. 新增 stopHandle 参数, 禁止操作的样式名 + +#### bui.number +1. 去除最大最小值的默认提醒,由用户自行定义 +2. 修复输入超出最大值,改为最小值,却不能点击问题 +3. 修复change事件,触发条件为值改变就触发 + + +#### bui.dialog +1. 修复宽度高度在定位为left,rigiht,top,bottom 时无效. + + + + + +## 1.4.1 20180131 + +### 升级指南 +** 一, 资源替换: ** + +1. (必须) 替换bui.js +2. (必须) 替换bui.css + + +### 新增 + + +### 优化-修复-维护 + +#### bui.isWebapp 设置 +用于替换 bui.debug. 同时也兼容旧的方式, 所以对熟悉的你没有影响. + +bui.isWebapp = true; 则使用web方法, +bui.isWebapp = false; 代表打包,使用原生方法 + +#### bui.router +1. 修复 loader.define 单独定义个对象问题 +2. 优化页面切换速度,更快 +3. 修复连跳2层后退以后的层级问题 +4. bui.back || router.back 支持 name 属性,指定后退到某一个层级 +5. 支持动态加载第三方网址 not ok + +重要: +6. 修复物理按键快速点击导致无法后退问题 ok. +7. 修复动态加载外部页面无法回退问题,部署的时候需要设置reloadCache,如果默认为true不利于调试 ok. + +#### bui.loader +1. 修复在中兴z802t 安卓4.3系统加载不了模块问题 + +#### bui.accordion +1. 修复showFirst方法有href的时候跟bui.load 冲突 + +#### bui.storage +1. 修复默认数字1问题 +2. 修复对多维对象存储及获取不够完整 +3. 修复覆盖新版本以后,旧版报错 + +#### bui.slide +1. 修复配合单页以后的高度计算问题 + +#### bui.sidebar +1. 修复配合单页以后双侧滑遮罩及错位问题 +2. 修复sidebar在oppo手机侧滑滚动触发关闭问题 + +#### bui.select +1. 修复配合单页以后弹出的遮罩问题,需要手动关闭遮罩 + +#### bui.list +1. 修复配合单页以后高度计算问题 + +#### bui.scroll +1. 修复配合单页以后高度计算问题 + +#### bui.pullrefresh +1. 修复配合单页以后高度计算问题 + +#### bui.dropdown +1. 修复相对定位覆盖绝对定位 + + +#### bui.mask +1. 修复公用遮罩的回调只有第一个可以点击的情况 + + + + +## 1.4.0-beta 20171224 + +### 升级指南 +** 一, 资源替换: ** + +1. (必须) 替换bui.js +2. (必须) 替换bui.css + + +### 新增 + +#### 1. bui.router 单页路由 +#### 2. bui.loader 模块化,配合单页一起使用 +#### 3. bui.prompt 输入对话框 +#### 4. bui.copyArray 数组复制方法 + +### 优化-修复-维护 +修复控件的 option 方法不能获取id 的值. +完善报错机制, 可以通过 bui.trace = true 拿到报错的调用栈 +统一了控件的事件监听, 点击事件,this=dom本身, 其它事件, this=ui 控件本身 + + +#### bui.upload +1. 修复web 上传可以看到上传控件,并且滚动的问题 +2. 支持web,ios,安卓上传 +3. 修复原生上传的this问题 + +#### bui.loading +1. 修复多次start, 在stop的时候,只是移除遮罩,loading还存在的问题 + +#### bui.toggle +1. 新增按顺序显示隐藏参数 +2. 新增几种页面动画 + +#### bui.slide +1. 新增autoload 参数,可以动态加载html到对应的内容 +2. 新增load 事件,配合动态加载以后的事件处理 +3. 新增load 方法,动态增加页面 +4. 修复微信里面使用lock 导致在往下滑动操作会返回第一页 +5. 模拟路由,配合多页开发使用,解决后退无法刷新问题 + +#### bui.accordion +1. 支持嵌套 + + +#### bui.dialog +1. 可以自由配置动画效果 + +#### bui.pickerdate +1. 修复弹窗模式IOS下打开缓慢问题. + +#### bui.removeArray +1. 修复无法删除普通数组问题,受影响的有 bui.storage + +#### bui.pickerdate, bui.select , bui.actionsheet, bui.accordion, bui.dropdown, 都加了disabled方法跟 enabled 方便控制是否触发弹窗 + +## 1.3.5 20170710 + +### 升级指南 +** 一, 资源替换: ** + +1. (必须) 替换bui.js +2. (必须) 替换bui.css + +### 优化viewport + +### 支持requirejs + +### 优化-修复-维护 +修复控件的 option 方法不能获取id 的值. + + + +## 1.3.4 20170628 + +### 升级指南 +** 一, 资源替换: ** + +1. (必须) 替换bui.js +2. (必须) 替换bui.css + +### 样式 +1. 新增流式等列布局, 具体查看 ui/layout.html 的底部,可以解决流式布局遇到5等分,7等分等情况. (替换 bui.css ) + + +### 优化-修复-维护 +#### bui.init +1. 支持自定义选择器计算main 的值 + +#### bui.dialog +1. 修复静态绑定对事件的处理. + +#### bui.slide +1. tab菜单滑动多个的时候,iphone会有滚动条,现在统一去掉. +2. 新增 direction:"y" 时,有滚动优先处理滚动再做滑动处理. +3. 新增 全屏效果示例. +4. 新增 alignClassName 参数,可以控制滑动内容的对齐方式,主要在全屏下的对齐; +5. autopage true 参数导致没有点击事件. +6. 修复 menu 为id 时, 无法点击事件. +7. 修复tab嵌套slide循环嵌套时外层无法滑动 + +#### bui.dropdown +1. 修复监听 change事件的时候,会触发2次问题 +1. 修复监听 change事件的时候,value方法获取不到值 +3. 新增 三级联调菜单效果,基于vue的例子 +4. 修复显示三角不显示问题. + +#### bui.select +1. 修复 value("11,22") 设置多个值的时候,会导致值永远是设置的值. +2. 修复在无值或者值的格式不对是,会导致报错无法继续. +3. 新增 三级联调菜单效果demo +4. 新增 静态自定义选择列表的demo ui_controls/bui.select.html + +#### bui.listview +1. 动态渲染的内容高度自适应问题(之前是统一高度) +2. 新增bui.listview 删除整行效果 +2. 新增bui.listview 配合dialog效果 + +#### bui.swipe +1. 新增alwaysTrigger 参数,控制滑动的距离不管达不达标都会触发一次open或者close事件, 默认为false 不触发, 用于频繁判断操作. +2. 新增isActive 方法,判断状态打开还是关闭 + +#### ui/form_edit.html +1. 整理编辑表单的单选多选列表结构示例(支持整行点击触发) + + +#### 解决在mx6浏览器整个页面上移不会还原的bug +1. 部分手机当页面有输入框聚焦, 会出现页面上移,但取消焦点,页面不会返回原来样子, 替换 bui.css + +### 优化文档的展示 + + +## 1.3.3 20170426 + +### 升级指南 +** 一, 资源替换: ** + +1. (必须) 替换bui.js +2. (必须) 替换bui.css +3. (必须) 替换bingotouch.js + +### 优化-修复-维护 + +#### bui.list +1. 修复多次调用init不请求的问题 (严重,在跟searchabr合作使用问题明显) + +#### bui.scroll +1. html结构下面的list, 右边没有箭头时无法点击, 替换 bui.css 文件 + +#### bui.swipe +1. 在打开的时候,滑动条件无法达到关闭时,会导致页面无法关闭, (listview,sidebar)都会受到影响. +2. 新增模拟日历复杂交互场景( bui.swipe_date.html ) +3. 打开状态下,双手指操作,导致移动错位(严重). + +#### bui.pickerdate +1. 修复在IOS下,只显示年月会导致ios下无法滚动(严重). + +#### bui.slide +1. 修复slide嵌套swipe,listview一起使用时, swipe参数为false,切换tab会导致swipe,listview无法滑动(手机才有). + + +#### bui.upload +1. 修复华为手机无法预览图片跟上传图片( web 模式). + +#### bui.pickerdate +1. 方法更改支持链式调用. + + +#### 新增入门文档 +1. 嵌入离线文档并进行手机适配. +2. 嵌入快速入门文档. + + +## 1.3.2 20170331 + +### 升级指南 +** 一, 资源替换: ** + +1. (必须) 替换bui.js +2. (必须) 替换bui.css + +### 重要修改 +1. 支持 jQuery (2.0以上) 跟 Zeptojs 库, 如果需要用到jquery库,则不引用zepto.js (正常Zeptojs 也能满足需求). 如果更改为 jquery 库, 需要替换 bingotouch.js 的精简版 ( 49k ) . + +2. bui.pullrefresh (bui.list bui.scroll也会受影响) 跟 bui.slide 的事件冲突问题 + +### 优化-修复-维护 + +#### bui.slide +1. 修复顶部导航的滑动菜单未完全展示 +2. 修复全屏时高度计算不准确 +3. 修复滑动过程会触发click事件(安卓4.3) + +#### bui.pullrefresh +1. 修复 fail 方法, 数据调用失败时不显示提醒 +2. 修复 失败时无法请求数据 +3. 修复 滑动过程中出现第2个手指会中断原本的操作 + +#### bui.viewport +1. 优化 meta 重复创建问题 + +#### bui.list +1. 新增 modify 方法,便于修改多个参数 跟 option 的区别在于, option 修改了多个参数会执行初始化. . +2. init 多次执行会导致列表请求的时候多次请求, 这个单独使用没问题, 跟 bui.searchbar 配合才出现的问题. + +#### bui.swipe +1. 上下滑动,只能滑出来,不能滑动回去 +2. 新增 targetMove 参数, 可以控制目标不跟着移动. +3. 新增 bui.swipe_down.html 的示例, 可以只滑一半. +4. 上下滑动跟滚动条的交互问题 +5. 新增 initDistance 参数初始化handle的距离, 具体使用场景: bui.swipe_down.html + +#### bui.select +1. 初始化 init 多次会创建多个select + + +#### 微信版样式 +1. 样式美化 + + + +## 1.3.1 20170317 + +### 升级指南 +** 一, 资源替换: ** + +1. (必须) 替换bui.js +2. (必须) 替换bui.css + +** 二, 重要修改: ** + +1. bui.searchbar 跟 bui.list 的操作变了, 原本 list 的option 修改参数以后,会执行初始化请求, 现在 bui.list 的 option 只做参数修改, 初始化需要调用 init 方法. + +### 优化-修复-完善 +#### CSS bui-navbar +1. 结合 bui-nav 变成按钮自适应横向滚动, li标签在书写时,之间不要有空白. +2. 增加demo ui/nav.html + +#### bui.ready +1. 增加$.Deferred的扩展,支持类似 ajax 一样的操作 +2. 如果需要在多处地方调用ready 可以监听pageready事件 + +#### bui.getPageParams +1. 增加$.Deferred的扩展,支持ajax 一样的操作, 这样就不用所有业务都写在回调里面, 原来的方式不受影响 +2. 增加示例演示 示例: ui_method/bui.getPageParams.html + +#### bui.mask +1. 遮罩改为共用遮罩,一次只能触发一个遮罩,这样可以节省部分dom操作 +2. 修复部分控件使用下 + +#### bui.loading +1. 进度在body下改为共用,一次只能触发一个进度条,这样可以节省部分dom操作 + +#### bui.dialog +1. 弹窗打开的时候,如果是autoClose: true, 快速点击遮罩会导致弹窗无法 + +#### bui.pickerdate +1. 简化formatValue 参数跟方法,通过formatValue: "yyyy-MM-dd hh:mm" 控制显示的字段; +2. 新增on 事件监听 +3. 新增 pickerdate 更多使用场景demo 示例: ui_controls/bui.pickerdate.html +4. 修复 pickerdate api 文档里的参数错误 +5. 修复 pickerdate 在iphone可能会打开的时候扭成一团 + +#### bui.animate +1. 完善animate的动画demo 示例: ui_method/bui.animate.html + +#### bui.toggle +1. 完善toggle的动画demo 示例: ui_method/bui.toggle.html +2. 修复快速点击可能导致的显示错误情况 + +#### bui.slide +1. 修复 on("to") 只能监听到调用 to 方法而不是每次都会触发的问题 +2. 完善 bui.slide 跟顶部导航出现横向滚动的情况的示例 示例: ui_controls/bui.slide_tab.html + +#### bui.btn +1. 修复在开启遮罩进行原生跳转的时候,点击返回需要手动关闭遮罩的问题 + +#### bui.searchbar +bui.searchbar 支持显示中文搜索按钮 + +## 1.3.0 20170313 + +### 升级指南 +#### 一, 资源替换: + +1. (必须) 替换bui.js +2. (必须) 替换bui.css +3. (可选) zeptojs 报trigger错问题,去掉了默认的swipe longtap 事件 +4. (可选) bingotouch 纯api版本 + +#### 二, 重要修改,可能会对已有的项目造成影响的地方: + +**js 方面** + +1. bui.sidebar 的初始化在 bui-page 的父级id , 需要在原本的 bui-sidebar 加上 swiperight 滑动方向. + +2. bui.slide 修改了参数 zoom: false; 不再默认缩放slide的整体比例. 之前如果有用到焦点图的地方,需要修改为 zoom: true; 也可以在配置文件修改. +``` +bui.config.slide.zoom = true; +``` + +3. 使用bui.swipe重写 bui.sidebar,bui.listview 等插件, 如果有用到 bui.sidebar 或者 bui.listview 则需要在想要滑动的方向加上 swipeleft swiperight ;如果用到的这类控件的地方比较多,可以修改配置文件批量修改 +``` +往左边滑动: bui.config.sidebar.swipeleft = ".bui-sidebar"; +往右边滑动: bui.config.sidebar.swiperight = ".bui-sidebar"; +往左边滑动: bui.config.listview.swipeleft = ".bui-listview-menu"; +往右边滑动: bui.config.listview.swiperight = ".bui-listview-menu"; +``` +4. 增加页面及控件的事件监听,具体查看, 控件初始化以后会有 on 方法用来监听事件. +[BUI 事件演示](http://www.easybui.com/demo/index.html#pages/ui_event/index.html) + +5. 比较重要的方法放在 bui, 不常用方法放在第三级, 例如 bui.platform.isWindow bui.unit.pxToRem 之类的 +bui.platform 统一了这类判断控件的调用方式 bui.platform.isWinow() ( 以前是bui.platform().isWindow() ) + +6. bui.getPagaparams 1.2.3版本 原生获取不到传参问题 + +7. bui.list 跟 bui.listview 的结合,不再需要在 bui.list 的回调里面多次执行 bui.listview ,一个控件只需要初始化一次. + + +** CSS方面 ** +1. bui-btn 统一了最小高度 .6rem的高度,并且line-height更改为 1 + +2. bui-list 列表的样式,单行改为固定高度垂直居中, +bui-list 下面的 bui-btn 会变成box 布局, 要注意有没有对自己的列表样式造成影响, 如果有影响,自定义对应的列表名称,把按钮改为 block; +``` +//自定义列表的样式,不要使用 .bui-list .bui-btn {} 会影响到其它控件 +.customList .bui-btn { display:block; } +``` +3. dialog 的头部底部,采用固定最小高度的方式,单行.6rem, 如果对你的造成影响,可以这样修改. +``` +// 自定义对话框的样式, 不要 .bui-dialog .bui-dialog-head +.custom-dialog .bui-dialog-head { line-height:inherit; min-height:inherit; } +``` +4. bui.checkVersion 检测版本更新的方法做过修改,需要传当前版本号进行比对 + +### 优化-修复-完善 + +** 3.1 原生相关** + +bui原生方法结构重整,方便扩展第三方平台 + +##### bui.download +bui.download 如果文件地址没有文件名,会存在文件被替换的情况, 新增 fileName 参数,可以自定义下载文件的名字 + +##### bui.ajax +bui.ajax 新增全局配置 + + +** 3.2 滑动交互类** +##### bui.swipe 新增 +bui.swipe 控件,支持更复杂的滑动交互,支持上下左右滑动,支持自定义滑动距离 + +##### bui.slide +bui.slide 在魅族浏览器滑动一次以后不灵敏的问题 +bui.slide zoom 参数的缩放问题 + +##### bui.listview +bui.listview 自定义渲染打开再关闭会有条蓝边 +bui.listview 只有最后一个有遮罩的问题. +bui.listview 的滑动重构,支持左右两边都有侧滑栏 +bui.listview 新增 open close active 等方法,支持自定义滑动距离 + +##### bui.sidebar的滑动重构 +bui.sidebar 只能滑动打开,不能滑动关闭的问题 +bui.sidebar 的滑动重构,支持左右两边都有侧滑栏,支持自定义滑动距离 + +** 3.3 数据交互类** +##### bui.btn +bui.btn 一个页面只需要初始化一个 bui.btn 的绑定操作就可以了. +bui.btn 新增disabled属性跟disabled样式的判断 +bui.btn 新增 replace 替换当前窗口参数,解决 登录提交->成功->后退 又回到登录页面问题 +bui.btn 新增 timeout 参数,定时关闭, 默认3000秒,主要因为在原生下一个页面,会导致页面返回还看到进度条 + + +##### bui.load +bui.load 新增 replace 替换当前窗口参数,解决 登录提交->成功->后退 又回到登录页面问题 + +##### bui.list 页面跳转 +bui.list 修改 onRefresh, onLoad 参数回调的第2个参数为 请求得到的对象(之前是数组) +bui.list 支持 vuejs, artTemplate, baiduTemplate 等第三方模板操作并提供示例. +bui.list 支持自定义参数 刷新是增加数据,还是覆盖数据 +bui.list 下拉刷新高度不足以后不会自动请求下一页 +bui.list 支持手动初始化 +bui.list 修改跟 bui.scroll children handle 保持一致的调用 +bui.list bui.scroll 小于最小高度又没有数据的情况下会一直请求. +bui.list 跟 bui.listview 配合使用导致页面宽度计算不准确问题. +bui.list bui.listview bui.sidebar bui.btn 等几个控件一起使用的复杂场景问题 +bui.list 的刷新方法数据为空的时候,不执行 + +##### bui.scroll +bui.scroll 新增 isRefresh 方法, 获取当前执行的是刷新操作还是加载操作. +bui.list bui.scroll 小于最小高度又没有数据的情况下会一直请求. +bui.pullrefresh,bui.list,bui.scroll 的下拉刷新优化 + +##### bui.searchbar +bui.searchbar 的示例页面拿不到数据 +bui.searchbar 修复 search 方法不能触发 + +##### bui.accordion +bui.accordion 扩展性更强,详情可以参考 bui.accordion_article.html 示例 + +** 3.4 弹出交互类** + +##### bui.pickerdate +bui.pickerdate 简化参数, 可以不传 value min max +bui.pickerdate 支持按钮取消及确定再进行设置 +bui.pickerdate 的格式导致ios报错问题 +bui.pickerdate 日期统一从0开始 + +##### bui.mask +bui.mask 增加了zIndex 参数设置, 默认 100, 跟 dropdown结合的时候,有可能需要设置层级 低于10. +bui.mask 修复2个弹窗以后,关闭弹窗会导致有一个没有遮罩 + +##### bui.loading +bui.loading 新增 pause 暂停滚动方法 +bui.loading 新增 timeout 参数,定时关闭,这种一般在 页面跳转时使用 + +##### bui.dialog +bui.dialog 底部按钮样式问题及自定义的dialog高度问题 + +##### bui.confirm +bui.confirm 新增几种弹出成功失败提醒示例 +bui.confirm 默认确定按钮高亮 + +##### bui.hint +bui.hint 去掉close参数,使用autoClose替代 +bui.hint 统一了提醒样式 +bui.hint interval 参数改为 timeout + +##### bui.select +bui.select 新增 active 方法,可以激活选中的第几个数据 +bui.select 弹出窗口的情况下会导致页面跳到底部,不采用label绑定input的方式 +bui.select 数据一多导致超出页面高度,滚动问题. + +##### bui.dropdown +bui.dropdown 新增 active 方法,可以激活指定二级菜单 +bui.dropdown 在第2个TAB会导致二级菜单不显示 +bui.dropdown 激活高亮显示 +bui.dropdown 跟 bui-bar 的各种不同位置使用场景 ui_controls/bui.dropdown_scenes.html + +##### bui.actionsheet +bui.actionsheet 美化 + + + +## 1.2.3 20161229 + +### 重要修复 +bui.list , bui.scroll, bui.pullrefresh 在滚动过程导致拖拽失效问题. +bui.load 不支持 http:// 地址问题 + + +### 新增 +bui.excessArray 去除多余重复元素方法 + +### 修复 +bui.listview 拖出来以后,回去会导致右边有条线问题 + +### 优化 +bui.inArray +bui.compareArray +bui.filterArray +bui.indexArray +bui.removeArray + + +## 1.2.2 20161226 +###重要修改: +1. bui.ready 手机的API调试加载增加了 window.onload ,如果替换新版,原先写在 bui.ready 外面的 window.onload 就可以取消了. 原因: 部分手机需要在onload 里面才能监听到设备接口准备完毕. + +2. 替换 bui.css 可以解决跟require等第三方插件配合使用导致的页面闪跳问题. + +3. bui.viewport.init() 方法如果项目中有独立使用到的,需要更改为 bui.init(); +4. bui.list 的field.data 参数 默认更改为""; + 修改说明: 如果旧项目数据返回默认是{data:[]}, 则需要全局配置修改一下,对已经配置过field的列表没有影响. + ``` + bui.config.list.field = {data:"data"}; + ``` + +5. 统一了 bui.storage 的get set remove 方法,可以获取某条数据,删除某条数据,增加某条数据, 更多请参考api例子. 跟localstorage的不同之处在于, bui.storage 存储的值可以是字符串,对象字面量,数组,返回的值统一是数组,也就是storage可以存储多条数据,常用于历史记录. +例如: +``` +var storage = bui.storage(); +// 存储字符串: + storage.set("username","wangws") +// 存储JSON: + storage.set("username",{"id","123","name":"wangws"}) +// 获取数组 + storage.get("username"); + // 输出数组 [{"id","123","name":"wangws"}] + +// 以前获取某个值 + storage.get("username")[0]; + // 输出 {"id","123","name":"wangws"} +// 输出某个字段 不存在时会报错 + storage.get("username")[0]["name"]; + +// 现在获取某个值 + storage.get("username",0); + // 输出 {"id","123","name":"wangws"} +// 还可以输出某个字段 不存在不会报错 + storage.get("username",0,"name"); + // wangws +``` + + +### 新增 +* 新增 bui.config.viewport.zoom 属性, 控制是否自动viewport, 默认是,一般无需修改 +* 新增 bui.toggle effect:"showIn" 简单的隐藏显示效果, dialog等其它控件也会支持效果. +* 新增 input标签type="radio" checkbox 等的title属性,便于这类选项框直接定义右边文本,需要修改时利用伪类 &:after {} 修改 + +### 修改 +* 修改 bui.css 控件库的样式,减少层级嵌套. +* 修改 bui.loading bui.mask appendTo 属性允许class名,只取第一个 +* 修改 bui.list 在数据还没加载出来不可以下拉刷新 +* 修改 bui.btn 的进度条开启方式,增加多一个 progress 属性,以及在html增加progress 对单个开启的控制. + +### 修复 +* 修复 bui.list 的 field data参数层级嵌套一样. +* 修复 bui.listview 跟 bui.mask relative 冲突问题 未解决 +* 修复 bui的viewport 会导致页面闪跳的问题, (需要替换bui.css文件) +* 修复 bui.slide 的手动设置高度导致无法滚动的问题 +* 修复 bui.slide autopage 参数可能导致的不可点击操作. +* 修复 bui.dropdown value text 为空字符串时,获取到的值是上一个设置值. +* 修复 bui.loading 点击遮罩有时删除,有时删除不了的问题 + +### 优化 +* 优化 bui.searchbar onInput +* 优化 bui.pullrefresh +* 优化 bui.scroll +* 优化 bui.list +* 优化 bui.slide +* 优化 bui.sidebar +* 优化 bui.listview + + +## 1.2 20161104 + +###重要修改, 升级需要注意: +* 优化 bui.confirm 的默认按钮, 统一主按钮更改在右边( 更新请注意,如果你点也使用默认确认框的操作, 按钮通过index去判断,这个会导致你的确认框的逻辑变更 ) +* 优化 bui.mask 的自动生成,改为默认不生成, 优化 add,remove,show,hide 方法 +* 优化 bui.loading 的自动生成,改为默认不生成, 优化 add,remove,show,hide 方法 +旧项目要升级,则需要全局更改为原来的方式 bui.config.mask.autoTrigger = true ; bui.config.loading.autoTrigger = true ; 或者更改为新的方式 + + +#### 新增控件 +* 新增 bui.upload 上传控件 +* 新增 bui.download 下载控件 +* 新增 bui.file 文件管理控件 +* 新增 bui.fileselect 文件选择控件 + +#### 新增控件参数及方法 +* 新增 常用控件的全局参数配置 ui.config.alert = {} 之类的统一配置以后,所有用到alert的公共参数都会改变. +* 新增 bui.list refresh 参数, false 可以选择不要刷新. +* 新增 bui.list headers 参数, 部分ajax需要这样的头部. +* 新增 bui.scroll refresh 参数, false 可以选择不要刷新. +* 新增 bui.hint isShow 方法. +* 新增 bui.dialog isOpen 方法, 并且修复快速点击窗口关闭及打开导致关闭混乱. +* 新增 bui.mask hide, show 方法 +* 新增 原生的方法多了个 native 参数, 对原生的方法是否单独使用web的方式, 比方 bui.ajax({native:false}).done(function(){}) 及时 bui.debug = false ;依然使用的是web的请求方式. +* 新增 bui.rating show 方法, 用于展示只读的分数, 比方 3.8, 最后一颗星星可以展示百分比. +* 新增 bui.btn().load() 对弹出键盘的处理方式,页面跳转比较快,键盘还没有完全关闭,会导致页面计算错误. +* 新增 sidebar dialog 控件的事件监听 $().on("open",function(e,status){}) +* 新增 bui.storage(size,bool) 的存储方式, 第2个参数为 false 则采用 sessionStorage true 这使用localStorage . + + +#### 修复 +* 修复 bui.ajax 不支持 headers 参数 +* 修复 bui.ajax 不支持数据是文本的方式 +* 修复 bui.ajax 增加 native 参数, debug=false 的情况下,还可以设置 native = false, 这样请求还是使用web请求. +* 修复 bui.ready 获取元素高度不准确 +* 修复 bui.list option 修改 data 参数,无需重新初始化. +* 修复 bui.list 跟 bui.searchbar 之间相互配合问题 +* 修复 bui.list option 分页值不会动态更改问题 +* 修复 bui.dropdown 的下拉菜单点击不能默认跳转( 跟btn 控件冲突). +* 修复 bui.dropdown 三星s3无法弹出二级菜单问题 +* 修复 bui.listview 默认自动隐藏按钮(跟scroll,list,pullrefresh冲突). +* 修复 bui.listview 跟 dialog 控件的mask冲突,无法触发 onMask 方法. +* 修复 bui.checkVersion 检测版本更新样式及不能下载问题. +* 修复 bui.pickerdate 的日期准确及字体大小问题. +* 修复 bui.btn().submit(callback,{}) 抛出进度条的参数修改,可以在后面的对象修改. +* 修复 bui.actionsheet 快速点击多次以后出现显示错乱问题. +* 修复 bui.sidebar 导致iphone6 闪白问题 +* 修复 bui.select 三星s3 取不到name值问题 +* 修复 bui.select ios下快速点击导致无法显示问题 +* 修改 控件的方法回调的指向. dom this指向dom本身, 非dom this 指向实例本身 + + +## 1.1.0 20160830 + +**修复控件的重要问题,建议更新到此版本.** + + +**js** + +* 兼容BT4.0 处理 ; + +* 新增 bui.select 的宽高参数; +* 新增 bui.init 方法,默认初始化,这样方便跟其它框架之间配合; +* 新增 bui.unit 对象, 后面存放一些小方法, 目前有 px 跟 rem 的等值换算,有小小误差,无伤大雅. + +* 修复 bui.dialog bui.alert bui.confirm 的宽高参数的缩放问题,及内容居中; +* 修复 bui.select 快速点击的动画无法打开问题; +* 修复 bui.slide 重新初始化问题; +* 修复 bui.listview 全部静态初始化的问题; +* 修复 bui.ajax 自定义配置字段以及数据为空的情况; +* 修复 bui.ajax 原生请求到的数据有问题; + +* 删除 bui.ready 的回调参数 viewport; + + + +## 1.0.6 20160729 + +**html** + +* 修改 bui-input 图标的大小 +* 修改 bui.dropdown 控件增加下拉箭头属性, 默认箭头居右及居上, 如果需要居中,需要手动增加 bui-arrow-center 样式在父层 + +**js** + +* 修复 bui.btn 跟 label 的冲突 +* 修复 bui.list 使用option导致原生在请求过程中数据不断重复问题; +* 修复 bui.searchbar onRemove 的可以word获取不到问题; +* 修复 bui.slide + bui.list 之间的切换,导致里面的元素要点2次才能点击 +* 修复 bui.ajax 原生不支持POST; + +* 修改 bui.list 新增 onRefresh 参数,在刷新后执行 +* 修改 bui.scroll 的filter 拿不到数据问题 +* 修改 bui.select 的selectNone 不支持radio的问题 +* 修改 bui.searchbar.html 示例, 每次回调的list 高度问题; +* 修改 bui.searchbar 新增 handleRemove 参数及 search方法; +* 修改 bui.ajax 支持contentType 的传参; + + + + +## 1.0.5 20160701 稳定版 + +* 新增 bui.actionsheet 插件 +* 新增 微信版皮肤风格及示例 +* 新增 bui.pickerdate 日期控件 + +* 修改 bui.pullRefresh 改为小写 bui.pullrefresh , 确保所有控件名都是小写,参数名区分大小写,这样使用才不会混乱 +* 修改 控件 buttons 参数的传参,支持2种格式 ["确定","取消"] [{name:"确定",className:"primary"},{name:"取消",className:"danger"}] +* 修改 bui.list 自定义事件,及手动刷新导致无法继续拖拽刷新 +* 修改 支持 Zepto或者jQuery2.2 两个库,自行选用, api 方面暂时只支持 Zepto. +* 修改 bui.select 的回调改为手动触发,用户可以自由操作.增加 bui-btn-line 样式可以扩大点击的区域在整行 +* 修改 bui.dropdown direction属性为 positon 值为 top bottom left right 统一了控件的位置属性, 支持宽度自定义, 新增 箭头显示控制, 激活状态控制 + +* 删除 js/plugins/picker 及 pickerdate 目录, 该插件已经整合在 bui.pickerdate + + + +## 1.0.4 20160624 + +### 建议更新到此版本! +**重要更新 :** + +* slide 重构 ok +* slide 高度计算不准确 ok +* slide 的滚动跟 scroll的滚动冲突 ok +* scroll list pullrefresh 控件在中兴z802t 只能滚动刷新一次,接下来滚动不了, ok +* alert 及 confirm 无法滚动 ok +* 版本检测更新的dialog无法滚动 ok +* 完善了bui.list 控件,更快速的组装开发 ok + +其它更新: +* bui.btn 增加 disabled 阻止事件跳转 ok +* bui.select 增加 自定义className 参数 ok +* bui.dialog 增加 自定义宽度高度参数 兼容PC ok +* bui.animate 修改了 trans3d方法 为 open3D ok + + +## 1.0.3 20160617 版本更新 + +* listView 如果每次只打开一个,会导致listview无法绑定点击事件 ok +* sidebar listview 有链接时跳转会导致页面跳转 ( 崔浩反馈 ) ok +* listview ios 在微信滑动问题有闪动 ( 崔浩反馈 ) ok +* dialog 的滚动跟父层 跟buiscroll 的滚动问题,在ios8 问题严重弹出层不能滚动, 是因为 -webkit-animation-fill-mode: both; 导致的 ok +* dialog 无法打开动态创建窗口 ok +* overflow-scrolling: touch 在ios8 无法滚动问题, 因为跟animate动画一起导致的scrolling无法滚动,另外这个在ios下面会有穿透问题. + 解决: 去掉了accordion dialog 的弹性滚动 scrolling:touch; 或者去掉动画效果, 因为 -webkit-animation-fill-mode: both; 导致的 ok +* dropdown点击同一个按钮,需要触发打开或者关闭, 并且修改为一次初始化一个id的下拉菜单 ok +* bui.viewport 可以不需要ready 使用 ok +* 规范化参数的传参 ok +* 修复了sidebar ios 不能关闭问题 ok +* 给每个控件增加了动态获取设置参数方法 ok +* 把回调统一传控件自身 ok +* select 全选以后获取不到值 ok + diff --git a/docs/chapter1/about.md b/docs/chapter1/about.md new file mode 100644 index 0000000..7a1198f --- /dev/null +++ b/docs/chapter1/about.md @@ -0,0 +1,89 @@ +# 介绍 + + +## BUI 是什么? + +?> BUI 是用来`快速构建界面交互`的UI框架, 专注webapp开发, 开发者只需关注业务的开发, 界面的布局及交互交给BUI, 开发出来的应用, `可以嵌入平台` ( 微信, 钉钉, 淘宝, 支付宝等 ), 亦可以跟其它第三方平台`打包成独立应用`( Bingotouch , Cordova , Dcloud , APICloud , Appcan , 前海圆舟 等), 最终可以`全跨平台展示`. + +?> 结合BUI提供的[BUI-Fast编辑插件](buifast), [NPM工具](chapter1/installation), BUI更是一个移动快速开发的解决方案. 可以解决以下常见问题. + +- 移动端的适配兼容问题 (`ui`) +- 交互体验不统一问题 (`ui`) +- 复杂交互的控件冲突问题 (`ui`) +- 多人协作问题 (`模块化`) +- 微信开发的缓存问题 (`模块化`) +- 后退刷新问题 (`单页路由`) +- 后退多层问题 (`单页路由`) +- 调试数据跨域问题 (`npm`) +- 本地服务器架设问题 (`npm`) +- 脚本编译问题 (`npm`) +- 打包安全问题 (`npm`) +- 同步刷新问题 (`npm`) +- 开发效率问题 (`bui-fast`) +- 使用规范问题 (`bui-fast`) + + +?> 欢迎加入我们的QQ技术交流群: `691560280` + + +## 起步 + +?> BUI 支持两种开发方式, 多页开发跟单页开发基本保持一致, 多页开发简单容易理解, 单页开发不受平台限制,保持一致交互体验. 选择一种即可. NPM工具跟编辑插件 + +- [多页开发](/chapter1/quickstart) `简单` `性能好` +- [单页开发](/chapter2/router) `推荐` `体验佳` + + +## 特色和优势 + +* 独创的设计稿移动端适配机制,跟原生DPI缩放保持一致; +* 快速上手,学习几乎零成本; +* 快速融入各种平台,保持原平台的交互操作; +* 简单的路由,丰富的切换效果; +* 模块化开发,按需加载; +* 开发一次,多平台适用; +* 轻松定制UI; +* 兼容requirejs,seajs模块; + + +## 适用场景 + +* 适合中小型应用开发; +* 适合Link,微信,QQ,淘宝,支付宝等平台的webapp开发; +* 适合基于Bingotouch,Cordova,Dcloud,APICloud,APPCan等的混合型应用; +* 适合不同风格高定制需求; +* 适合原生开发以后移植微信等其它平台; +* 适合快速开发demo原型投标; + + +## 支持第三方平台打包 +- Cordova +- DCloud +- APICloud +- AppCan +- 前海圆舟 + + +## 浏览器支持 +- 系统自带webkit浏览器 +- 魅族浏览器 +- 微信 +- QQ +- 淘宝 +- 支付宝 +- 钉钉 +- UC浏览器 + +> 部分浏览器如果默认开启了手势,会影响操作体验, UC已屏蔽 + +## 系统要求 +- iOS +- Android 4.3+ + + +## 谁在使用 +品高内部上百个移动终端项目,客户有移动,电信,地铁,政府等行业. + +?> 可以下载BUI安卓体验包, 用不同平台打包以后的效果. 进入下载中心 + + diff --git a/docs/chapter1/debug.md b/docs/chapter1/debug.md new file mode 100644 index 0000000..204188a --- /dev/null +++ b/docs/chapter1/debug.md @@ -0,0 +1,107 @@ +# 调试 + +?> 关于数据的调试,只需要打开跨域的Chrome就可以直接预览效果了,但在手机调试就需要部署工程,并且还要解决跨域问题, 这些通过`自动化部署工程`,简单配置一下就可以了. + +## 自动化部署工程 + +?> 使用[buijs](tools/buijs.md)创建的工程,安装好依赖以后,执行`npm run dev`,就会起一个服务器了. + +```bash +# 安装依赖 +$ npm install +# 部署环境并打开浏览器 +$ npm run dev +``` + +## 接口如何跨域 + +?> 配合自动化构建工程, 打开根目录下的 `app.json` ,里面有个键值 `proxy` 的对象. + +假设请求的接口地址为: http://www.easybui.com/api/getDetail/id/123 +*需要这样配置 proxy :* + +``` +{ +... +"proxy": { + "/api": { + "target": "http://www.easybui.com", + "changeOrigin":true, + "ssl": false + } + } +... +} +``` + +js: 脚本请求使用`相对路径`, 为了后面更改为正式地址, 建议可以把url部分作为配置项. + +``` +var apiUrl = ""; + +bui.ajax({ + url: apiUrl+ "api/getDetail/id/123" +}).then(function(res){ + +}) +``` +> 关于代理的更多配置,可以查看 [http-proxy-middleware](https://www.npmjs.com/package/http-proxy-middleware) 的使用说明. + +## Chrome跨域调试 + +?> 打开chrome 开发者工具, 开启模拟手机效果, 这样才能模拟手机的滑动拖拽事件. + +![chrome 预览图](http://www.easybui.com/docs/images/chrome.png) + +!> 在PC调试数据,界面等内容,需要打开跨域的chrome + +* **Chrome 49以下版本解决跨域问题** + + **mac** 在终端上输入以下命令: + ```bash + $ open -a Google\ Chrome --args --disable-web-security + ``` + **windows** 新建个快捷方式,右键->属性, 目标路径后面增加 `--args --disable-web-security`  + ``` + "C:\Program Files\Google\Chrome\Application\chrome.exe" --args --disable-web-security  + ``` + +* **Chrome 49以上版本解决跨域问题** + + **mac** 在终端上输入以下命令: + ```bash + $ open -a Google\ Chrome --args --disable-web-security  --user-data-dir + ``` + **windows** 新建个快捷方式,右键->属性, 目标路径后面增加 `--args --disable-web-security  --user-data-dir` + ``` + "C:\Program Files\Google\Chrome\Application\chrome.exe" --args --disable-web-security  --user-data-dir + ``` + +如果以上方式不能解决你的跨域问题,请自行网上搜索 chrome对应的版本的跨域. + + +## Debugtool调试 + +?> DebugTool是手机上的一个应用,可以在手机模拟打包后的调试效果,基于`Bingotouch`,`Link`开发的应用, 多页开发全局配置 `bui.isWebapp = false;` 可以切换成原生跳转,原生请求. + +* [安卓版下载](http://www.easybui.com/downloads/source/debugtool/DebugTool-v3.4.0.apk) +* [IOS版下载](http://www.easybui.com/downloads/source/debugtool/DebugTool-v1.0.ipa) + + +手机安装应用以后,工程需要服务器部署起来,然后才能在手机预览. 手机端预览,请更改成您的 `http://IP+端口号`. + +## 微信调试 + +?> 微信调试需要注意的是,微信里面的缓存很严重,每次修改,需要给修改的js引用,后面增加`?t=时间戳`之类的方式,来确保脚本的更新. + +*例如:* +```html + +``` + +?> 如果你使用的是`bui.loader`模块化开发, 可以在公共配置的地方, 设置 `bui.config.loader.cache = false;`, 加载的模块便会采用时间戳的方式加载. + +```js +bui.config.loader.cache = false; +``` + diff --git a/docs/chapter1/installation.md b/docs/chapter1/installation.md new file mode 100644 index 0000000..38bec0e --- /dev/null +++ b/docs/chapter1/installation.md @@ -0,0 +1,25 @@ +# 安装 + +## 开发环境 +?> 你可能只需要一个系统自带的notepad程序,就可以使用BUI开发应用, 但通过以下软件相互配合,对开发效率会有一定的帮助. + +1. 编辑器 ( 推荐: `Atom`[点击下载](https://atom.io/) 或 `Sublimetext3`[点击下载](https://www.sublimetext.com/) ); +2. `bui-fast` [点击下载](https://github.com/imouou/BUI-Fast-Snippets/releases) (配合编辑器快速书写插件, 支持 LinkIDE , Atom , Sublimetext , Webstorm , APICloudIDE ) [查看安装说明](tools/buifast.md); + +## 下载开发包 + +!> 我们推荐您学习使用[buijs](tools/buijs.md)`自动化构建`, 自动化构建默认是最新的`bui`版本. 手动下载的开发包不一定是最新的. + +### 单页开发包 + +?> 通过开发包的方式,我们已经帮您把目录结构规范好了,下载直接按照类似的方式就可以使用. 下载解压以后,删除`templates`,`platforms`,`dev`目录. + +[手动下载BUI单页开发包](https://github.com/imouou/BUI-Template/releases) + + +### 多页开发包 + + +[手动下载BUI多页开发包](http://www.easybui.com/downloads/source/bui/bui_simple_latest.zip) + + diff --git a/docs/chapter1/layout.md b/docs/chapter1/layout.md new file mode 100644 index 0000000..384cc6b --- /dev/null +++ b/docs/chapter1/layout.md @@ -0,0 +1,246 @@ +# 布局 +?> BUI 内置了3种布局,简单强大. 可以把以下代码,复制到 [在线尝试布局](http://jsbin.com/qoxexug/edit?html,output) 预览效果. + + + +!> 以下示例为了能够一眼看到结果,会增加背景色,高度等,实际开发`不推荐把样式写在标签上` + +## 流式12列布局 + +?> 流式布局把一行分为12列,后面的数字加起来等于12则一行,大于12则另起一行. + +```html +
+ +
2/12
+
4/12
+
4/12
+
2/12
+ +
4/12
+
4/12
+
4/12
+
+``` + +## 流式等列布局 + +?> 流式等列布局认为子元素全部是等分的,由父层数字决定子集占比,最多12列. + +```html + +``` + +## 弹性布局 + +?> 弹性布局这里也叫行布局,不管子集有多少元素,都会挤在一行. + +### 弹性布局-等比 `bui-box` + +*例子: 把整行划分成 3份, 子集可以是 span1-span12 * +```html +
+
+ 1/3大小 +
+
+ 2/3大小 +
+
+ +``` + +### 弹性布局-自适应 `bui-box` + +?> bui的部分元素默认也是采用这种布局, 比方 样式为 `bui-bar` 的自适应是 bui-bar-main, `bui-input` 自适应是 input标签 + +*例子: span1的宽度 = 整行宽度 - 100px, `span1`称之自适应 * +```html +
+
宽度100px
+
+ // 自适应内容 +
+
+``` + +### 弹性布局-垂直 `bui-box-vertical` + +*例子: span1的高度 = 整行高度 - 30px * +```html +
+
高度30px
+
+ // 自适应内容 +
+
+``` + +### 弹性布局-反序 `bui-box-reverse` +*例子: * +```html +
+
宽度100px
+
+ // 自适应内容 +
+
+``` +## 弹性布局-对齐 + +#### 弹性布局-绝对居中 `bui-box-center` +*例子: * +```html +
+
宽度100px,
高度50px
+
+``` +#### 弹性布局-水平居中 `bui-box-align-center` +*例子: * +```html +
+
宽度100px,
高度50px
+
+``` +#### 弹性布局-水平居左 `bui-box-align-left` +*例子: * +```html +
+
宽度100px,
高度50px
+
+``` +#### 弹性布局-水平居右 `bui-box-align-right` +*例子: * +```html +
+
宽度100px,
高度50px
+
+``` +#### 弹性布局-垂直居中 `bui-box-align-middle` +*例子: * +```html +
+
宽度100px,
高度50px
+
+``` +#### 弹性布局-顶部对齐 `bui-box-align-top` +*例子: * +```html +
+
宽度100px,
高度50px
+
+``` +#### 弹性布局-底部对齐 `bui-box-align-bottom` +*例子: * +```html +
+
宽度100px,
高度50px
+
+``` +#### 弹性布局-两端对齐 `bui-box-align-justify` +*例子: * +```html +
+
宽度100px
+
宽度100px
+
+``` +#### 弹性布局-子集等高 `bui-box-align-stretch` +*例子: * +```html +
+
高度50px
+
高度50px
+
+``` + + +## 间隙布局 + +?> 每种布局都有一种带间隔的布局, 只需在后面加上`-space` + +### 流式间隙 `bui-fluid-space` +*例子: * + +```html +
+
+ 1/2大小 +
+
+ 1/2大小 +
+
+``` +### 流式等比间隙 `bui-fluid-2-space` +*例子: * +```html +
+
+ 1/2大小 +
+
+ 1/2大小 +
+
+``` + +### 弹性间隙 `bui-box-space` +*例子: * +```html +
+
+ 1/2大小 +
+
+ 1/2大小 +
+
+``` + + +## 嵌套布局 + +?> 几种布局之间可以嵌套自身,也可以相互嵌套,实现更复杂的布局. + +*例子: 流式等列布局,嵌套弹性布局及流式布局* +```html + +``` +*例子: 弹性布局,嵌套流式等列布局及流式布局* +```html +
+
+ +
+
+
+
1/4
+
1/4
+
+
+
+``` \ No newline at end of file diff --git a/docs/chapter1/multipage.md b/docs/chapter1/multipage.md new file mode 100644 index 0000000..765e56d --- /dev/null +++ b/docs/chapter1/multipage.md @@ -0,0 +1,149 @@ +# 多页路由 + +?> [上一节](chapter1/quickstart) 我们用最简单的方式,创建了一个`index.html`, 当我们创建了多个页面以后, 就需要页面跳转了. + +!> 多页开发只需直接引入对应的脚本就可以开发. + +```html + + + + +``` + +## 页面跳转 + +?> 页面跳转有2种: `bui.btn` 跟 `bui.load` +- `静态绑定跳转`,含有属性 `href` 则会调用跳转页面操作; +- `动态跳转`, 需要自己绑定按钮跳转操作; + +### 1. bui.btn(option) `静态绑定` + +*参数: option是一个对象 * + +#### option.id +- Type: `string` +- Detail: `父层选择器` + +#### option.handle +- Type: `string` +- Detail: `要点击的目标` + +?> 绑定`.bui-page` 结构中 `.bui-btn`, `a`, 如果含有 `href` 属性则会跳转. `一个页面也只需要绑定一次`. bui.btn API + +*示例:* + +```html +
+ +``` +```js +bui.btn({id:".bui-page",handle:".bui-btn,a"}).load(); + +``` + +### 2. bui.load(option) `动态跳转` +?> 传参的时候比较方便 bui.load API + +*参数: option是一个对象 * + +#### option.url +- Type: `string` +- Detail: `相对路径` + +#### option.param +- Type: `object` +- Detail: `传给目标页面的参数` + +#### option.replace +- Type: `boolean` +- Detail: `替换页面,默认:false` + +*page1.html 示例:* + +```js +bui.load({ url: "pages/page2.html", param: { id: "page1"} }); +``` + +## 接收参数 + +### bui.getPageParams() + +?> 页面接收参数, 这里参数的值是在回调里面, 部分原生参数的接收是异步的, 这是为了保持接收参数的方式统一 bui.getPageParams API + +*page2.html 示例:* + +```js +var getParams = bui.getPageParams(); + getParams.done(function(result){ + console.log(result); + // {id:"page2"} + }) +``` +## 页面后退 + +### bui.back(option) + +?> 后退页面 bui.back API + +*参数: option是一个对象 * + +#### option.callback +- Type: `function` +- Detail: `后退以后执行回调` + +*示例:* + +```js +bui.back(); +``` + +!> webapp版的多页开发不支持后退刷新等操作. 如果需要更复杂的路由定制, 就需要以[单页开发](chapter2/router), 自由度会更高. + + +## 页面刷新 +### bui.refresh() + +?> 后退页面 bui.refresh API + +*示例:* + +```js +bui.refresh(); +``` + +## 页面替换 +### bui.load(option) + +?> 页面替换不会有历史记录 bui.load API + +*示例:* + +```js +bui.load({ url: "pages/page2.html", replace:true }); +``` + + +## bui.ready +?> 设备准备完毕, 一个页面只需要一个 `bui.ready`, 里面可以执行`$`的方法. +``` + bui.ready(function(){ + // 执行 + }) +``` +!> 注意, 以上的使用方式都需要在`bui.ready`的回调里面, `$` 选择器指 `Zepto`跟`jQuery`通用的方法. + +## 使用原生方法 +在页面引入的公共脚本里面, 加入一个`bui.isWebapp = false;` 的配置项, 运行在 `bui.ready` 里面的综合方法, `bui.load`,`bui.back`,`bui.ajax` 等等, 都会采用原生的处理. Yes, 就是这么简单! + +```js +bui.isWebapp = false; + +``` + +!> 启用原生以后,Chrome无法调试, 需要在`Bingotouch`或者对应的平台容器上才能调试. + + +?> 接下来可以继续学习 + +- [数据交互](chapter1/request) \ No newline at end of file diff --git a/docs/chapter1/quickstart.md b/docs/chapter1/quickstart.md new file mode 100644 index 0000000..7fcca08 --- /dev/null +++ b/docs/chapter1/quickstart.md @@ -0,0 +1,233 @@ +# 快速开始 + +?> 通过简单例子可以了解到bui的页面标准,及控件的基本使用, 后面还有一些工具的简单介绍. + +## 简单示例 + +?> 这是BUI最简单的使用方式,引入相应的库即可使用. 马上试试 + +```html + + + + +``` + +*index.html* + +```html + + + + + BUI 多页开发标准页面 + + + + + + + + + +``` + +?> 你还需要一个BUI的标准结构, 放在body中间. + +```html +
+ +
+
+ +
+
BUI标准页面
+
+
+
+ +
+ +
+``` + +!> 一个页面对应一个 bui-page. BUI 页面标准模板,包含 header(非必须) main(内容滚动区) footer(非必须), 无需使用 fixed 样式,footer也会固定在底部. + +## 效果预览 +?> 效果有点像这样: 可以直接在chrome浏览器打开html文件. + +![BUI标准页预览](https://raw.githubusercontent.com/imouou/BUI-Template/master/preview.png) + +## 控件基本使用 + +?> 接下来我们给页面加一个焦点图控件, 一个BUI的控件包含结构跟脚本初始化. 结构放main标签里面. + +*焦点图结构* + +```html +
+
+ +
+ +
+ +
+
+``` + +!> 脚本初始化必须在 `bui.ready` 里面执行, 多页开发`一个页面对应一个` bui.ready 其它自由编写, 便于自己维护就好. + +*焦点图初始化* + +```js + // 焦点图控件初始化 + var uiSlide = bui.slide({ + id:"#uiSlide", + height:200, + zoom: true + }) +``` +?> 给实例增加事件监听. + +```js + // 监听跳转以后触发 + uiSlide.on("to",function(index){ + console.log(index) + }) + +``` +?> 执行实例对应的方法, 具体请查看对应的 [API](http://www.easybui.com/demo/api/index.html). + +```js + // 跳转到第2个,索引值从0开始 + uiSlide.to(1); + +``` + +!> `注意:` 事件监听必须在方法执行之前. slide默认支持滑动,点击等事件, 但必须在手机或者开启Chrome设备预览才能操作, + +## 在线预览 + +?> 最终组合以后的代码, 你可以点击这里 在线编辑预览 + +*index.html* + +```html + + + + + BUI 多页开发标准页面 + + + + + +
+ +
+
+ +
+
BUI标准页面
+
+
+
+ +
+
+
    +
  • + + +
    图片标题
    +
  • +
  • + + +
    图片标题
    +
  • +
+
+
+
    +
  • 1
  • +
  • 2
  • +
+
+
+
+ +
+ + + + + +``` + + +## BUI-Fast 让编写更简单 + +?> 这是BUI的多页开发方式, 是不是很简单? BUI不止简单,还快. 上面的代码如果使用 `BUI-Fast` 插件来使用的话, 只需这几行代码就可以了. [如何安装BUI-Fast插件](tools/buifast) + +*方案1:* +- ui-html Tab 生成bui页面引用 +![BUI-Fast焦点图预览](http://www.easybui.com/docs/images/ui-html.gif) + +- ui-page Tab 生成bui标准页面结构 +![BUI-Fast焦点图预览](http://www.easybui.com/docs/images/ui-page.gif) + +- bui-slide-demo Tab 生成焦点图控件初始化代码及结构 +![BUI-Fast焦点图预览](http://www.easybui.com/docs/images/bui-slide-demo.gif) + +*方案2: * +- ui-html Tab 生成bui页面引用 +- ui-page Tab 生成bui标准页面结构 +- ui-slide Tab 生成焦点图控件结构 +- bui-slide Tab 生成焦点图控件初始化代码 + + + +## buijs 自动化工程 +?> 使用`buijs` NPM工具, 每次会获取最新工程包, 主要配合[单页开发](chapter2/router)使用, 例如,服务器部署,es6编译,sass编译,接口跨域,打包安全等,可以减少你对其它工具的依赖, 但这个需要你对NPM有一定的了解, 新手可以略过. 非新手猛击这里[如何安装使用buijs](tools/buijs) + + +## 准备好了吗? + +?> `bui-fast` 跟 `buijs` 这里给大家做个简单的介绍, 接下来你可以继续学习 + +- [多页路由](chapter1/multipage) + diff --git a/docs/chapter1/request.md b/docs/chapter1/request.md new file mode 100644 index 0000000..94c41fb --- /dev/null +++ b/docs/chapter1/request.md @@ -0,0 +1,180 @@ +# 数据交互 + +?> BUI里面有3种数据交互. + +* [页面跳转及传参](chapter1/multipage.md) +* [数据请求](chapter1/request?id=数据请求) +* [数据存储](chapter1/request?id=数据存储) + +## 数据请求 + +### bui.ajax(option) + +?> 数据请求 bui.ajax API + +*参数: option 是一个对象* + +#### option.url +- Type: `string` +- Detail: `url地址` + +#### option.data +- Type: `object` +- Detail: `请求的参数,默认:{}` + +#### option.method +- Type: `string` +- Detail: `默认: GET` + +*示例:* + +```js +bui.ajax({ + url: "", + data: {} +}).then(function(res){ + // 成功回调 + console.log(res) +},function(res,status){ + // 失败回调 + console.log(status); +}) +``` +?> 还有依赖请求,顺序请求等, [查看更多ajax技巧](http://www.easybui.com/demo/#pages/ui_method/bui.ajax) + +## 模板渲染 + +?> 这里你熟悉`$`的操作都可以直接在`bui.ready`里面使用, 模板渲染可以使用`$.html + 字符串`拼接, 也可以支持`ES6 的模板`, 你还可以引入第三方模板, [artTemplate](https://aui.github.io/art-template/zh-cn/docs/index.html), `BUI+Vuejs` 也是不错的选择. + +### 使用 `$` 渲染示例: + +?> 这些属于`jQuery`的基础操作, 更多知识请自行学习. + +*渲染一个列表:* + +*list.js* +```js +// 示例数据,正常由请求返回 +var data = [{ + name: "hello" + },{ + name: "bui" + }]; + +// 声明列表模板 +var templateList = function (data) { + var html = ''; + + data.forEach(function(el,index){ + html += '
  • '+el.name+'
  • '; + }) + + return html; +} + +var listTpl = templateList(data); + +// $渲染 +$("#list").html(listTpl); + +``` + +*list.html* +```html + +``` +### 使用 `artTemplate` 渲染示例: + +*list.js* +``` +// 渲染 + + +``` + +*list.html* +```html +// 引入artTemplate + + + + +// 模板放html里 + +``` + + +## 数据存储 + +### bui.storage(option) + +?> `bui.storage` 是基于 `localStorage` 及 `sessionStorage` 封装的, 主要解决两者之间的API统一问题, 并且支持JSON存储, 以及支持限制多少条数据等问题, 常用来做历史记录. + +*参数: option 是一个对象* + +#### option.local +- Type: `boolean` +- Detail: `设置是否为本地存储,默认:true` + +#### option.size +- Type: `number` +- Detail: `限制存储多少条数据,默认:1` + + +*示例1: 字符存储* + +```js +// 存储1条数据 +var storage = bui.storage(); + storage.set("name","hello"); + // 第2个会覆盖第1个 + storage.set("name","bui"); + +``` + +*示例2: 对象存储* + +```js +// 存储2条json数据 +var storage2 = bui.storage({size:2}); + // 通过id字段判断数据是否重复,如果有重复的ID,则会替换掉之前的数据 + storage2.set("user",{id:"u1",name:"hello"},"id"); + storage2.set("user",{id:"u2",name:"bui"},"id"); + + +``` + +*示例3: 结合示例1,示例2 获取数据* + +```js +// 获取字符串 +var names = storage.get("name"); + // names 为数组, 可以通过 names[0] 获取到内容. + console.log(names) // ["bui"] + +// 获取对象 +var users = storage2.get("user"); + // 最后存储的数据在前面 + console.log(users) // [{id:"u2",name:"bui"},{id:"u1",name:"hello"}] + +``` + +!> 注意: bui.storage 不管存什么数据,获取到的内容都在一个数组里面. + + diff --git a/docs/chapter1/why.md b/docs/chapter1/why.md new file mode 100644 index 0000000..ff8e1f0 --- /dev/null +++ b/docs/chapter1/why.md @@ -0,0 +1,34 @@ +# 为什么用BUI? + +?> 为什么要用,相信很多人有这样的疑问, 我以几个实际项目遇到的场景来说明下使用BUI的应用及好处吧. + + +*场景1: webapp使用第三方平台打包?* + +!> 开发好的webapp应用在浏览器跑的好好的,但在第三方平台打包以后,数据出不来! + +?> 这是因为有些平台本地打包的时候,禁止了跨域, 导致你原本的`$.ajax` 之类的web请求被禁止了, 因为这个请求,你要改的地方可能是N多个地方, 而使用BUI, 你用`bui.ajax`去请求你的数据,面对这种多变的情况, 你只需要改一个配置, `bui.isWebapp = false;` 这样页面的请求就会采用 原生平台的请求, 就没有跨域问题了. 这个也是BUI最早的设计初衷. 但BUI不仅限于这个跨域问题, 还有页面的切换等等, 你都可以一键切换为原生容器. + + +?> 感兴趣的朋友还可以看看这篇文章,对BUI的设计以及使用方式都做了一定的说明,有助于理解. +2018开发最快的webapp框架--BUI设计思路解析 + +*场景2: 开发好的打包应用,客户说要支持微信及浏览器?* + +!> 我们用第三方的平台开发并打包了一个应用, 刚开始的需求是说, 只要安卓跟IOS版就好, 等做完以后, 客户觉得想要开发一个跨平台的版本,微信浏览器都能拥有基本功能! + +?> 这个时候,你的很多业务都是可以复用的, 但是由于用了平台结合的UI, 在跨平台上面表现不佳, 无法适配? 一切都得从头开始. 而使用BUI开发,一开始就是跨平台的, 所以并不存在效果不一致这个问题, 你需要的是, 把业务用到原生的部分去掉. + +*场景3: 第三方平台的迁移* + +!> 假设你公司有一个自己的打包平台,有自己的UI, 有自己的原生API, 一切都近乎完美, 突然有一天, 客户说,我们想使用第三方平台开发打包, 一个客户说要用Dcloud,一个说要用APICloud,也可能是APPCan. 这时候, 一个混合框架包含原生API跟UI, 你的团队需要学习, `DCloud+UI`, `APICloud+UI`, `APPcan+UI` ... 每个UI都跟自己的框架结合紧密, 但最终团队的学习成本相当的高昂! + +?> 其实分析以后你会发现,一个应用的开发,很多效果,交互都应该是通用的, 只有少部分原生需要用第三方平台来开发, 这个时候你只需要使用 `BUI+APICloud`, `BUI+DCloud`, `BUI+APPCan` 等等, 你只需要用到原生api的时候,查一下, 开发方式还是按BUI的来, 最终可以在常用的平台都保持一致的交互效果, 学一个就够了. + +![](http://www.easybui.com/docs/images/bui-silu.png) + + +?>以上都是我们开发中遇到的真实客户需求, 用 BUI `以不变应万变`, 学习上手都很简单. + +- [了解更多特点](/chapter1/about) +- [快速开始学习](/chapter1/quickstart) diff --git a/docs/chapter2/animate.md b/docs/chapter2/animate.md new file mode 100644 index 0000000..f3254aa --- /dev/null +++ b/docs/chapter2/animate.md @@ -0,0 +1,3 @@ +# 动画交互 + +正在编写中 \ No newline at end of file diff --git a/docs/chapter2/controls.md b/docs/chapter2/controls.md new file mode 100644 index 0000000..5318fd1 --- /dev/null +++ b/docs/chapter2/controls.md @@ -0,0 +1,3 @@ +# 控件用法 + +正在编写中 \ No newline at end of file diff --git a/docs/chapter2/loader.md b/docs/chapter2/loader.md new file mode 100644 index 0000000..d7c28d6 --- /dev/null +++ b/docs/chapter2/loader.md @@ -0,0 +1,142 @@ +# 模块化 + +## 介绍 + +?> 随着应用的功能逐渐丰富,逻辑的复杂度不断的增加,多人协作等问题, BUI有了自己的模块化方案, 类似`requirejs`的AMD. 熟悉`requirejs`,`seajs`都可以很好的适应过来. + +!> `window.loader` 默认注册给了 `bui.loader`. 关于loader的用法,可以查看 bui.loader API. + +## 模块化解决什么问题? + +?> 在多页开发的时候,我们习惯一个页面对应一个脚本,把公共的脚本提取出来, 然后 + +## 定义模块 +### loader.define + +*loader.define 定义一个匿名模块. * + +```js +loader.define(function(require,exports,module){ + + // 以下几个参数非必须,如果前面加载了依赖,则这三个参数后移; + // require : 相当于 loader.require, 获取依赖的模块 + // exports : 如果没有return 可以采用这种方式输出模块 + // module : 拿到当前模块信息 + + // 模块如果需要给其它模块加载,通过 return 的方式抛出来,或者module.exports的方式 + return {}; +}) +``` +> * **定义模块需要遵循什么?** +1. 一个js 文件里面只能有一个 loader.define 的匿名模块; +2. 业务逻辑需要在 loader.define 里面,防止加载其它模块的时候冲突; +3. 避免循环依赖 A ->依赖 B 模块, 而 B模块 -> A模块, 这就造成循环依赖,一般需要避免这种设计,如果一定要用, 不使用依赖前置的方式; +4. 避免循环嵌套, 在loader.define 里面 又 require 加载当前模块, 这个时候还没实例化,就会造成死循环; +5. 每个页面的ID不能相同; + +关于模块定义的更多疑问,可以点击左边的疑难解答 + +## 加载模块 +### bui.require + +>假设我们定义了一个匿名模块, 是在pages/page2/目录下, 目录下有 page2.html ,page2.js 两个文件. 则默认匿名模块的 模块名是 pages/page2/page2 会根据.html 文件提取前面路径作为模块名. + +page2.js +``` +loader.define(function(require,exports,module){ + + return { + pageName: "page2" + } +}) +``` +>现在我们想在刚刚的main.js里面加载这个模块,调用pages/page2/page2 的名称. + +main.js +``` +loader.define(function(require,exports,module){ + + // 加载pages/page2/page2模块 + require("pages/page2/page2",function(page2){ + + // 访问page2模块的名称 + console.log( page2.pageName ) + }) + + return { + pageName: "main" + } +}) +``` +这样打开首页的时候,就会加载main.js, main.js 会去加载pages/page2/page2模块,成功以后输出名称. + + +模块的定义及加载更多用法,请大家自行查阅 bui.loader API + + +## 加载资源 +### loader.import + +## 获取配置模块 +### loader.map + + +## 疑难解答 + +#### 模块定义的常见问题 + +> * **如何抛出当前模块的方法共享** +1. 推荐 使用return 的方式 ; +2. 使用module.exports 的方式; +3. exports 的方式; +使用任意一种就可以. + +> * **熟悉requirejs或者seajs 模块化开发的开发者是不是有种似曾相识的感觉? ** +bui.loader跟requirejs都属于AMD异步模块定义的方式, 按照requirejs的接口设计, 目的就是为了让开发者快速上手. 如果你之前写过一些模块是基于以上两种方式,只要进行一些简单的修改,就能拿过来用的. + +> * **为什么不直接采用requirejs或者seajs呢?** +这两种方式都有在项目中使用,这样模块的复用及开发方式就无法统一,A项目开发完的部分模块,可能B项目也能用,但两者各自用的模块化方式不同, 这就需要熟悉的人去做一定的修改. 采用我们自己的模块化方式,可以跟bui.router路由更好的配合, 后面模块化的公共插件也会越来越多, 这是我们以后希望看到的. + +> * **如何定义模块的依赖呢?** +main.js +``` +// 依赖前置, 这种会优先加载完 page2,page3模块以后再执行main的回调. +loader.define(["pages/page2/page2","pages/page3/page3"],function(page2,page3){ + // 如果需要用到当前模块信息的话, page3后面依次还有 require,exports,module + +}) +``` + +> * **如何定义一个自定义名字的模块呢?** +>有时候,我们觉得通过路径加载名称比较长,想变短一点,那就需要自定义模块名称了,像main模块一样, 自定义名称需要有两步. +* 第1步: 映射脚本路径 +index.js +``` +// 映射脚本路径 +loader.map({ + moduleName: "page2", + script: "pages/page2/page2.js" +}) + +// 把路由实例化给 window.router +window.router = bui.router(); + +bui.on("pageinit",function(){ + + // 加载页面到div容器里面, 更多参数请查阅API + router.init({ + id: "#bui-router" + }) +}) +``` +* 第2步: 声明自定义模块, 名称需要跟映射的模块名一致 +pages/page2/page2.js +``` +loader.define("page2",function(require,exports,module){ + // 这里是page2的业务逻辑 +}) + +``` + +模块的定义及加载更多用法,请大家自行查阅 bui.loader API + diff --git a/docs/chapter2/method.md b/docs/chapter2/method.md new file mode 100644 index 0000000..987981f --- /dev/null +++ b/docs/chapter2/method.md @@ -0,0 +1,3 @@ +# 常用方法 + +正在编写中 \ No newline at end of file diff --git a/docs/chapter2/package.md b/docs/chapter2/package.md new file mode 100644 index 0000000..aa3dffa --- /dev/null +++ b/docs/chapter2/package.md @@ -0,0 +1,3 @@ +# 打包独立应用 + +正在编写中 \ No newline at end of file diff --git a/docs/chapter2/router.md b/docs/chapter2/router.md new file mode 100644 index 0000000..ba514a2 --- /dev/null +++ b/docs/chapter2/router.md @@ -0,0 +1,533 @@ +# 单页路由 + + +## 介绍 + +?> 单页路由可以实现对路由的复杂操作, 弥补多页开发的不足, 在体验上, 效果也会更佳. 从多页转单页开发, 保持了接口的一致性, 上手非常简单, 但需要你对模块化也有一定的了解. + +### 效果预览 + +![单页示例预览](http://www.easybui.com/static/images/controls/bui-router_low.gif) + +[点击这里体验](http://www.easybui.com/case/preview.html?url=http://www.easybui.com/case/source/router/demo/index.html) + +### 路由功能 + +* 页面跳转,支持html跳转或者模块跳转; +* 支持选择不同动画,融入不同平台的切换效果; +* 支持预加载; +* 支持页面刷新; +* 支持当前页面替换; +* 支持页面的局部加载; +* 支持页面传参,获取参数; +* 支持指定跳入某个页面; +* 支持缓存,默认已经配置; +* 支持展示进度条,需要配置; +* 支持后退刷新; +* 支持后退多层; +* 支持后退到指定模块; +* 支持物理后退按键; + + +## 创建单页工程 + +?> 使用`buijs`命令行构建. 如何使用buijs命令行工具? + +![buijs 创建工程预览](http://www.easybui.com/docs/images/router/buijs-create-demo_low.gif) + +### 创建demo工程 +```bash +# 创建目录 +$ mkdir demo + +# 进入demo目录 +$ cd demo + +# 创建单页工程 +$ buijs create +``` + +### 安装依赖及预览 +```bash +# 安装工程依赖 +$ npm install +# 运行服务并预览 +$ npm run dev +``` + +### 目录规范 + +![BUI 单页示例目录说明](http://www.easybui.com/docs/images/router/catalog.png) + +**目录说明:** + +| **目录名** | **描述** | **是否必须** | +|:------------- |:--------------------------------|--------------:| +| /app.json | 插件及跨域的配置 | 否 | +| /gulpfile.js | gulp编译配置 | 否 | +| /package.json | 工程依赖配置 | 否 | +| /src/index.html | 应用首页入口文件 | 是 | +| /src/index.js | 路由的初始化脚本及全局事件 | 是 | +| /src/css/ | 应用样式及bui.css样式 | 是 | +| /src/font/ | bui.css用到的字体图标 | 是 | +| /src/images/ | 应用图片目录 | 否 | +| /src/js/ | 应用脚本 | 是 | +| /src/js/zepto.js | bui.js默认依赖于zepto.js 或 jquery | 是 | +| /src/js/bui.js | BUI交互控件库 | 是 | +| /src/pages/ | 应用的模块 | 是 | +| /src/pages/main/ | 默认路由初始化以后会先载入这个main模块 | 是 | +| /src/pages/main/main.html | main模块的模板 | 是 | +| /src/pages/main/main.js | main模块的业务脚本 | 是 | + +---- + +## 路由初始化 + +*打开编辑 `src/index.html` , body 下只有一个div,这个便是路由最外层结构.* + +*src/index.html* + +```html + + + + + BUI单页工程 + + + + + + + +
    + + + + + + + +``` + +*src/index.js * + +```js +// 把路由实例化给 window.router +window.router = bui.router(); + +bui.ready(function(){ + + // 加载页面到div容器里面, 更多参数请查阅API + router.init({ + id: "#bui-router" + }) +}) +``` + +?> 当路由初始化以后,会自动查找首页`main`模块, 这个模块是内部定义好的, 默认指向路径 `pages/main/main.html` 并自动加载相同名字的js文件. 除了`main`, 正常我们都是创建匿名模块,这样只要通过路径跳转,就会自动加载同名的脚本. + +### main模块 +*src/pages/main/main.html* + +```html +
    +
    +
    +
    +
    main
    +
    +
    +
    +
    +
    跳转page2.html
    +
    + +
    +``` +*src/pages/main/main.js* + +```js +loader.define(function(require,exports,module){ + // 绑定按钮跳转 + $("#btn").on("click",function(){ + router.load({ url: "pages/page2/page2.html", param: {} }); + }) +}) + +``` + +### pages/page2/page2模块 + +?> 我们再创建一个 `src/pages/page2/page2.html`,及 `src/pages/page2/page2.js` ,那通过下面的方式跳转,则创建了一个 `src/pages/page2/page2` 的模块. + +*src/pages/page2/page2.html* + +```html +
    +
    +
    +
    +
    page2
    +
    +
    +
    +
    + +
    +``` + +*src/pages/page2/page2.js* + +```js +loader.define(function(require,exports,module){ + // 脚本都需要在这里执行 + +}) + +``` +---- + + +## 路由原理 + +?> 这就是一个简单的路由跳转过程. + +![BUI 路由模块加载流程图](http://www.easybui.com/docs/images/router/router_flow.png) + + +## 页面跳转 +### router.load(option) + +?> 页面跳转,保持js跟html一致的命名,才能自动加载触发. 同样支持 `bui.btn` 静态跳转 + +*参数: option是一个对象 * + +#### option.url +- Type: `string` +- Detail: `相对路径` + +#### option.param +- Type: `object` +- Detail: `传给目标页面的参数` + +*例子:* + +```js +router.load({ url: "pages/page2/page2.html", param: {} }); +``` + +!> 注意: 仔细查看下跟多页路由接口都是保持的一致,甚至你可以直接使用 `bui.load` 来代替 `router.load` , 这个也是最早我们推荐的方式, 所以你会看到部分例子还是保持这样的写法. 现在我们更推荐您使用 `router.load` 等统一单页路由的接口. + + +## 接收参数 +### router.getPageParams + +?> 接收到的参数为一个对象, 无需在回调里面拿. + +*例子:* + +```js +var params = router.getPageParams(); +``` + +## 页面后退 +### router.back(option) + +?> 支持后退以后执行回调,具体查看bui.back API + +*参数: option是一个对象 * + +#### option.index +- Type: `number` +- Detail: `后退几层,默认:-1` + +#### option.name +- Type: `string` +- Detail: `后退到指定的模块名, name跟index,只能有一个` + +#### option.callback +- Type: `function` +- Detail: `后退以后执行回调` + +*例子:* +```js +// 普通后退 +router.back(); + +// 后退2层刷新 +router.back({ + index: -2, + callback: function(){ + router.refresh() + } +}); + +// 后退局部刷新 +router.back({ + callback: function(module){ + // 后退的页面有抛出一个init方法 + module.init(); + } +}); + +// 不管在哪层,都可以后退到首页 +router.back({ + name: "main" +}); +``` + +## 页面刷新 +### router.refresh + +?> 页面刷新有可能造成事件重复绑定, 所以一般不建议这样使用. 可以结合 `loader.require` 调用模块抛出的方法, 实现局部刷新功能. + +*例子:* + +```js +router.refresh(); +``` + +## 页面替换 +### router.replace(option) + +?> 页面替换不会增加历史记录 + +*参数: option是一个对象 * + +#### option.url +- Type: `string` +- Detail: `相对路径` + +#### option.param +- Type: `object` +- Detail: `传给目标页面的参数` + +*例子:* + +```js +router.replace({ url: "pages/page3/page3.html" }); +``` + +## 局部加载模块 +### router.loadPart + +*参数: option是一个对象 * + +#### option.id +- Type: `string|object` +- Detail: `局部的id或者对象` + +#### option.url +- Type: `string` +- Detail: `相对路径` + +#### option.param +- Type: `object` +- Detail: `传给目标页面的参数` + +*例子:* + +```js +router.loadPart({ id:"#part", url: "pages/page2/page2.html", param: {} }); + +``` + +## 局部接收参数 +### router.getPartParams(moduleName) + +*参数: * + +#### moduleName +- Type: `string` +- Detail: `模块的名称` + +*例子:* + +```js +loader.define(function(require,exports,module) { + // module 为当前的模块信息 + var pid = module.moduleName, + params = router.getPartParams(pid); + + }) + +``` + +## 预加载 +### router.preload(option) + +?> 如果你的应用是webapp,那这个功能就比较好用了,先在首页预加载想要触发的页面, 当点击触发相同页面的时候, 你会发现跳转速度快多了, 本地应用则无需使用到预加载. + +*参数: option是一个对象 * + +#### option.url +- Type: `string` +- Detail: `缓存模板` + +#### option.script +- Type: `string` +- Detail: `缓存脚本` + +```js +// 预加载一个页面 +router.preload({ url: "pages/page2/page2.html" }); + +// 预加载多个页面 +router.preload([{ + url: "pages/page2/page2.html" +},{ + url: "pages/page3/page3.html" +}]); + +``` + +## 页面重复加载 + +### router.getCurrentPage() + +?> 有一种情况,页面需要被重复加载, 比方列表页,跳转到详情页,详情页又有推荐的列表,点击又会跳转到详情, 这种情况,就需要通过获取当前页面对象,来查找元素,而不能使用ID了, 包括控件的初始化. + +*控件初始化示例: * +```js +// 获取当前页面唯一ID +var currentPage = router.getCurrentPage(); + +// 页面唯一的样式名 +var accordionID = $(".bui-accordion",currentPage); + +// 控件初始化 +var uiAccordion = bui.accordion({ + id: accordionID +}) +``` + +*事件绑定示例: * +```js +// 获取当前页面唯一ID +var currentPage = router.getCurrentPage(); + +// 绑定当前页面下样式为 btn 的事件 +$(currentPage).on("click",".btn",function(e){ + +}) +``` + +!> 另外,建议一个单页应用的层级建议控制在 5级左右. 已经加载过的页面,使用后退刷新处理. 例如: + +``` +// 推荐: 这也是微信小程序里面推荐的层级数 +A->B->C->D->E + +// 不要这样, 这种做法本身会让用户陷入混乱 +A->B->C->B->C +``` + +## 获取历史记录 + +### router.history.get() + +?> 获取当前路由的历史记录 + +```js + var routerHistory = router.history.get(); +``` + +### router.history.getLast() +?> 获取路由的最后一条记录 + +```js + var routerLastHistory = router.history.getLast(); +``` + +---- + + +## 路由全局事件 + +### load 事件 +?> 页面加载,在模板加载完成就会触发,有缓存的时候只触发一次 + +```js +router.on("load",function(e){ + // 获取当前页的模块 + console.log(e.currentTarget); + // 获取上一页的模块 + console.log(e.prevTarget); +}) +``` + +### complete 事件 +?> 页面完成,每次加载完模板都会触发 + +```js +router.on("complete",function(e){ + // 获取当前页的模块 + console.log(e.currentTarget); + // 获取上一页的模块 + console.log(e.prevTarget); +}) +``` + +### back 事件 + +```js +router.on("back",function(e){ + // 获取当前页的模块 + console.log(e.currentTarget); + // 获取上一页的模块 + console.log(e.prevTarget); +}) +``` + +### refresh 事件 + +``` +router.on("refresh",function(e){ + // 获取当前页的模块 + console.log(e.currentTarget); + // 获取上一页的模块 + console.log(e.prevTarget); +}) +``` +### loadpart 事件 + +?> 页面局部加载后触发 + +``` +router.on("loadpart",function(e){ + // 获取当前页子模块 + console.log(e.currentTarget); + // 获取当前页父模块 + console.log(e.prevTarget); +}) +``` + + +*index.js * + +```js +bui.ready(function(){ + // 执行事件绑定 + bind(); +}) + +function bind(){ + // 静态绑定 bui-router 容器下所有带有 href 属性的按钮, 点击就会自动跳转, 一个单页应用只需要初始化一次. + bui.btn({id:"#bui-router",handle:".bui-btn"}).load(); + + // 监听页面所有后退事件 + router.on("back",function(e){ + console.log(e); + }) +} + +``` + +!> 注意: 建议全局事件都在 index.js 加载. 事件名全部为小写. + + + +?> 接下来你可以继续学习 + +- [模块化](chapter2/loader) diff --git a/docs/css/vue.css b/docs/css/vue.css new file mode 100644 index 0000000..2ec9312 --- /dev/null +++ b/docs/css/vue.css @@ -0,0 +1 @@ +@import url("https://fonts.googleapis.com/css?family=Roboto+Mono|Source+Sans+Pro:300,400,600");*{-webkit-font-smoothing:antialiased;-webkit-overflow-scrolling:touch;-webkit-tap-highlight-color:rgba(0,0,0,0);-webkit-text-size-adjust:none;-webkit-touch-callout:none;box-sizing:border-box}body:not(.ready){overflow:hidden}body:not(.ready) .app-nav,body:not(.ready)>nav,body:not(.ready) [data-cloak]{display:none}div#app{font-size:30px;font-weight:lighter;margin:40vh auto;text-align:center}div#app:empty:before{content:"Loading..."}.emoji{height:1.2rem;vertical-align:middle}.progress{background-color:var(--theme-color,#42b983);height:2px;left:0;position:fixed;right:0;top:0;transition:width .2s,opacity .4s;width:0;z-index:5}.search .search-keyword,.search a:hover{color:var(--theme-color,#42b983)}.search .search-keyword{font-style:normal;font-weight:700}body,html{height:100%}body{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;color:#34495e;font-family:Source Sans Pro,Helvetica Neue,Arial,sans-serif;font-size:15px;letter-spacing:0;margin:0;overflow-x:hidden}img{max-width:100%}a[disabled]{cursor:not-allowed;opacity:.6}kbd{border:1px solid #ccc;border-radius:3px;display:inline-block;font-size:12px!important;line-height:12px;margin-bottom:3px;padding:3px 5px;vertical-align:middle}.task-list-item{list-style-type:none}li input[type=checkbox]{margin:0 .2em .25em -1.6em;vertical-align:middle}.app-nav{margin:25px 60px 0 0;position:absolute;right:0;text-align:right;z-index:2}.app-nav.no-badge{margin-right:25px}.app-nav p{margin:0}.app-nav>a{margin:0 1rem;padding:5px 0}.app-nav li,.app-nav ul{display:inline-block;list-style:none;margin:0}.app-nav a{color:inherit;font-size:16px;text-decoration:none;transition:color .3s}.app-nav a.active,.app-nav a:hover{color:var(--theme-color,#42b983)}.app-nav a.active{border-bottom:2px solid var(--theme-color,#42b983)}.app-nav li{display:inline-block;margin:0 1rem;padding:5px 0;position:relative}.app-nav li ul{background-color:#fff;border:1px solid #ddd;border-bottom-color:#ccc;border-radius:4px;box-sizing:border-box;display:none;max-height:calc(100vh - 61px);overflow-y:auto;padding:10px 0;position:absolute;right:-15px;text-align:left;top:100%;white-space:nowrap}.app-nav li ul li{display:block;font-size:14px;line-height:1rem;margin:0;margin:8px 14px;white-space:nowrap}.app-nav li ul a{display:block;font-size:inherit;margin:0;padding:0}.app-nav li ul a.active{border-bottom:0}.app-nav li:hover ul{display:block}.github-corner{border-bottom:0;position:fixed;right:0;text-decoration:none;top:0;z-index:1}.github-corner:hover .octo-arm{animation:a .56s ease-in-out}.github-corner svg{color:#fff;fill:var(--theme-color,#42b983);height:80px;width:80px}main{display:block;position:relative;width:100vw;height:100%;z-index:0}main.hidden{display:none}.anchor{display:inline-block;text-decoration:none;transition:all .3s}.anchor span{color:#34495e}.anchor:hover{text-decoration:underline}.sidebar{border-right:1px solid rgba(0,0,0,.07);overflow-y:auto;padding:40px 0 0;position:absolute;top:0;bottom:0;left:0;transition:transform .25s ease-out;width:300px;z-index:3}.sidebar>h1{margin:0 auto 1rem;font-size:1.5rem;font-weight:300;text-align:center}.sidebar>h1 a{color:inherit;text-decoration:none}.sidebar>h1 .app-nav{display:block;position:static}.sidebar .sidebar-nav{line-height:2em;padding-bottom:40px}.sidebar li.collapse .app-sub-sidebar{display:none}.sidebar ul{margin:0;padding:0}.sidebar li>p{font-weight:700;margin:0}.sidebar ul,.sidebar ul li{list-style:none}.sidebar ul li a{border-bottom:none;display:block}.sidebar ul li ul{padding-left:20px}.sidebar::-webkit-scrollbar{width:4px}.sidebar::-webkit-scrollbar-thumb{background:transparent;border-radius:4px}.sidebar:hover::-webkit-scrollbar-thumb{background:hsla(0,0%,53%,.4)}.sidebar:hover::-webkit-scrollbar-track{background:hsla(0,0%,53%,.1)}.sidebar-toggle{background-color:transparent;background-color:hsla(0,0%,100%,.8);border:0;outline:none;padding:10px;position:absolute;bottom:0;left:0;text-align:center;transition:opacity .3s;width:284px;z-index:4}.sidebar-toggle .sidebar-toggle-button:hover{opacity:.4}.sidebar-toggle span{background-color:var(--theme-color,#42b983);display:block;margin-bottom:4px;width:16px;height:2px}body.sticky .sidebar,body.sticky .sidebar-toggle{position:fixed}.content{padding-top:60px;position:absolute;top:0;right:0;bottom:0;left:300px;transition:left .25s ease}.markdown-section{margin:0 auto;max-width:800px;padding:30px 15px 40px;position:relative}.markdown-section>*{box-sizing:border-box;font-size:inherit}.markdown-section>:first-child{margin-top:0!important}.markdown-section hr{border:none;border-bottom:1px solid #eee;margin:2em 0}.markdown-section iframe{border:1px solid #eee}.markdown-section table{border-collapse:collapse;border-spacing:0;display:block;margin-bottom:1rem;overflow:auto;width:100%}.markdown-section th{font-weight:700}.markdown-section td,.markdown-section th{border:1px solid #ddd;padding:6px 13px}.markdown-section tr{border-top:1px solid #ccc}.markdown-section p.tip,.markdown-section tr:nth-child(2n){background-color:#f8f8f8}.markdown-section p.tip{border-bottom-right-radius:2px;border-left:4px solid #f66;border-top-right-radius:2px;margin:2em 0;padding:12px 24px 12px 30px;position:relative}.markdown-section p.tip:before{background-color:#f66;border-radius:100%;color:#fff;content:"!";font-family:Dosis,Source Sans Pro,Helvetica Neue,Arial,sans-serif;font-size:14px;font-weight:700;left:-12px;line-height:20px;position:absolute;height:20px;width:20px;text-align:center;top:14px}.markdown-section p.tip code{background-color:#efefef}.markdown-section p.tip em{color:#34495e}.markdown-section p.warn{background:rgba(66,185,131,.1);border-radius:2px;padding:1rem}body.close .sidebar{transform:translateX(-300px)}body.close .sidebar-toggle{width:auto}body.close .content{left:0}@media print{.app-nav,.github-corner,.sidebar,.sidebar-toggle{display:none}}@media screen and (max-width:768px){.github-corner,.sidebar,.sidebar-toggle{position:fixed}.app-nav{margin-top:16px}.app-nav li ul{top:30px}main{height:auto;overflow-x:hidden}.sidebar{left:-300px;transition:transform .25s ease-out}.content{left:0;max-width:100vw;position:static;padding-top:20px;transition:transform .25s ease}.app-nav,.github-corner{transition:transform .25s ease-out}.sidebar-toggle{background-color:transparent;width:auto;padding:30px 30px 10px 10px}body.close .sidebar{transform:translateX(300px)}body.close .sidebar-toggle{background-color:hsla(0,0%,100%,.8);transition:background-color 1s;width:284px;padding:10px}body.close .content{transform:translateX(300px)}body.close .app-nav,body.close .github-corner{display:none}.github-corner:hover .octo-arm{animation:none}.github-corner .octo-arm{animation:a .56s ease-in-out}}@keyframes a{0%,to{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}section.cover{-ms-flex-align:center;align-items:center;background-position:50%;background-repeat:no-repeat;background-size:cover;height:100vh;display:none}section.cover.show{display:-ms-flexbox;display:flex}section.cover.has-mask .mask{background-color:#fff;opacity:.8;position:absolute;top:0;height:100%;width:100%}section.cover .cover-main{-ms-flex:1;flex:1;margin:-20px 16px 0;text-align:center;z-index:1}section.cover a{color:inherit}section.cover a,section.cover a:hover{text-decoration:none}section.cover p{line-height:1.5rem;margin:1em 0}section.cover h1{color:inherit;font-size:2.5rem;font-weight:300;margin:.625rem 0 2.5rem;position:relative;text-align:center}section.cover h1 a{display:block}section.cover h1 small{bottom:-.4375rem;font-size:1rem;position:absolute}section.cover blockquote{font-size:1.5rem;text-align:center}section.cover ul{line-height:1.8;list-style-type:none;margin:1em auto;max-width:500px;padding:0}section.cover .cover-main>p:last-child a{border:1px solid var(--theme-color,#42b983);border-radius:2rem;box-sizing:border-box;color:var(--theme-color,#42b983);display:inline-block;font-size:1.05rem;letter-spacing:.1rem;margin:.5rem 1rem;padding:.75em 2rem;text-decoration:none;transition:all .15s ease}section.cover .cover-main>p:last-child a:last-child{background-color:var(--theme-color,#42b983);color:#fff}section.cover .cover-main>p:last-child a:last-child:hover{color:inherit;opacity:.8}section.cover .cover-main>p:last-child a:hover{color:inherit}section.cover blockquote>p>a{border-bottom:2px solid var(--theme-color,#42b983);transition:color .3s}section.cover blockquote>p>a:hover{color:var(--theme-color,#42b983)}.sidebar,body{background-color:#fff}.sidebar{color:#364149}.sidebar li{margin:6px 0 6px 15px}.sidebar ul li a{color:#505d6b;font-size:14px;font-weight:400;overflow:hidden;text-decoration:none;text-overflow:ellipsis;white-space:nowrap}.sidebar ul li a:hover{text-decoration:underline}.sidebar ul li ul{padding:0}.sidebar ul li.active>a{border-right:2px solid;color:var(--theme-color,#42b983);font-weight:600}.app-sub-sidebar li:before{content:"-";padding-right:4px;float:left}.markdown-section h1,.markdown-section h2,.markdown-section h3,.markdown-section h4,.markdown-section strong{color:#2c3e50;font-weight:600}.markdown-section a{color:var(--theme-color,#42b983);font-weight:600}.markdown-section h1{font-size:2rem;margin:0 0 1rem}.markdown-section h2{font-size:1.75rem;margin:45px 0 .8rem}.markdown-section h3{font-size:1.5rem;margin:40px 0 .6rem}.markdown-section h4{font-size:1.25rem}.markdown-section h5{font-size:1rem}.markdown-section h6{color:#777;font-size:1rem}.markdown-section figure,.markdown-section p{margin:1.2em 0}.markdown-section ol,.markdown-section p,.markdown-section ul{line-height:1.6rem;word-spacing:.05rem}.markdown-section ol,.markdown-section ul{padding-left:1.5rem}.markdown-section blockquote{border-left:4px solid var(--theme-color,#42b983);color:#858585;margin:2em 0;padding-left:20px}.markdown-section blockquote p{font-weight:600;margin-left:0}.markdown-section iframe{margin:1em 0}.markdown-section em{color:#7f8c8d}.markdown-section code{border-radius:2px;color:#e96900;font-size:.8rem;margin:0 2px;padding:3px 5px;white-space:pre-wrap}.markdown-section code,.markdown-section pre{background-color:#f8f8f8;font-family:Roboto Mono,Monaco,courier,monospace}.markdown-section pre{-moz-osx-font-smoothing:initial;-webkit-font-smoothing:initial;line-height:1.5rem;margin:1.2em 0;overflow:auto;padding:0 1.4rem;position:relative;word-wrap:normal}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#8e908c}.token.namespace{opacity:.7}.token.boolean,.token.number{color:#c76b29}.token.punctuation{color:#525252}.token.property{color:#c08b30}.token.tag{color:#2973b7}.token.string{color:var(--theme-color,#42b983)}.token.selector{color:#6679cc}.token.attr-name{color:#2973b7}.language-css .token.string,.style .token.string,.token.entity,.token.url{color:#22a2c9}.token.attr-value,.token.control,.token.directive,.token.unit{color:var(--theme-color,#42b983)}.token.keyword{color:#e96900}.token.atrule,.token.regex,.token.statement{color:#22a2c9}.token.placeholder,.token.variable{color:#3d8fd1}.token.deleted{text-decoration:line-through}.token.inserted{border-bottom:1px dotted #202746;text-decoration:none}.token.italic{font-style:italic}.token.bold,.token.important{font-weight:700}.token.important{color:#c94922}.token.entity{cursor:help}.markdown-section pre>code{-moz-osx-font-smoothing:initial;-webkit-font-smoothing:initial;background-color:#f8f8f8;border-radius:2px;color:#525252;display:block;font-family:Roboto Mono,Monaco,courier,monospace;font-size:.8rem;line-height:inherit;margin:0 2px;max-width:inherit;overflow:inherit;padding:2.2em 5px;white-space:inherit}.markdown-section code:after,.markdown-section code:before{letter-spacing:.05rem}code .token{-moz-osx-font-smoothing:initial;-webkit-font-smoothing:initial;min-height:1.5rem}pre:after{color:#ccc;content:attr(data-lang);font-size:.6rem;font-weight:600;height:15px;line-height:15px;padding:5px 10px 0;position:absolute;right:0;text-align:right;top:0} \ No newline at end of file diff --git a/docs/docExample/cdn.md b/docs/docExample/cdn.md new file mode 100644 index 0000000..5b98d68 --- /dev/null +++ b/docs/docExample/cdn.md @@ -0,0 +1,49 @@ +# CDN + +推荐使用 [unpkg](//unpkg.com) —— 能及时获取到最新版。 + +## 获取最新版本 + +根据 UNPKG 的规则,不指定特定版本号时将引入最新版。 + +```html + + + + + +``` + +## 获取指定版本 + +如果担心频繁地版本更新又可能引入未知 Bug,我们也可以使用具体的版本。规则是 `//unpkg.com/docsify@VERSION/` + +```html + + + + + +``` + +!> 指定 *VERSION* 为 `latest` 可以强制每次都请求最新版本。 + +## 压缩版 + +CSS 的压缩文件位于 `/lib/themes/` 目录下 + +```html + +``` + +JS 的压缩文件是原有文件路径的基础上加 `.min`后缀 + +```html + +``` + +## 其他 CDN + +- http://www.bootcdn.cn/docsify (支持国内) +- https://cdn.jsdelivr.net/npm/docsify/ (国内外都支持) +- https://cdnjs.com/libraries/docsify diff --git a/docs/docExample/configuration.md b/docs/docExample/configuration.md new file mode 100644 index 0000000..c726840 --- /dev/null +++ b/docs/docExample/configuration.md @@ -0,0 +1,451 @@ +# 配置项 + +你可以配置在 `window.$docsify` 里。 + +```html + +``` + +## el + +* 类型:`String` +* 默认值:`#app` + +docsify 初始化的挂载元素,可以是一个 CSS 选择器,默认为 `#app` 如果不存在就直接绑定在 `body` 上。 + +```js +window.$docsify = { + el: '#app' +}; +``` + +## repo + +* 类型:`String` +* 默认值: `null` + +配置仓库地址或者 `username/repo` 的字符串,会在页面右上角渲染一个 [GitHub Corner](http://tholman.com/github-corners/) 挂件。 + +```js +window.$docsify = { + repo: 'QingWei-Li/docsify', + // or + repo: 'https://github.com/QingWei-Li/docsify/' +}; +``` + +## maxLevel + +* 类型:`Number` +* 默认值: `6` + +默认情况下会抓取文档中所有标题渲染成目录,可配置最大支持渲染的标题层级。 + +```js +window.$docsify = { + maxLevel: 4 +}; +``` + +## loadNavbar + +* 类型:`Boolean|String` +* 默认值: `false` + +加载自定义导航栏,参考[定制导航栏](zh-cn/custom-navbar.md) 了解用法。设置为 `true` 后会加载 `_navbar.md` 文件,也可以自定义加载的文件名。 + +```js +window.$docsify = { + // 加载 _navbar.md + loadNavbar: true, + + // 加载 nav.md + loadNavbar: 'nav.md' +}; +``` + +## loadSidebar + +* 类型:`Boolean|String` +* 默认值: `false` + +加载自定义侧边栏,参考[多页文档](zh-cn/more-pages.md)。设置为 `true` 后会加载 `_sidebar.md` 文件,也可以自定义加载的文件名。 + +```js +window.$docsify = { + // 加载 _sidebar.md + loadSidebar: true, + + // 加载 summary.md + loadSidebar: 'summary.md' +}; +``` + +## subMaxLevel + +* 类型:`Number` +* 默认值: `0` + +自定义侧边栏后默认不会再生成目录,你也可以通过设置生成目录的最大层级开启这个功能。 + +```js +window.$docsify = { + subMaxLevel: 2 +}; +``` + +## auto2top + +* 类型:`Boolean` +* 默认值: `false` + +切换页面后是否自动跳转到页面顶部。 + +```js +window.$docsify = { + auto2top: true +}; +``` + +## homepage + +* 类型:`String` +* 默认值: `README.md` + +设置首页文件加载路径。适合不想将 `README.md` 作为入口文件渲染,或者是文档存放在其他位置的情况使用。 + +```js +window.$docsify = { + // 入口文件改为 /home.md + homepage: 'home.md', + + // 文档和仓库根目录下的 README.md 内容一致 + homepage: + 'https://raw.githubusercontent.com/QingWei-Li/docsify/master/README.md' +}; +``` + +## basePath + +* 类型:`String` + +文档加载的根路径,可以是二级路径或者是其他域名的路径。 + +```js +window.$docsify = { + basePath: '/path/', + + // 直接渲染其他域名的文档 + basePath: 'https://docsify.js.org/', + + // 甚至直接渲染其他仓库 readme + basePath: + 'https://raw.githubusercontent.com/ryanmcdermott/clean-code-javascript/master/' +}; +``` + +## coverpage + +* 类型:`Boolean|String` +* 默认值: `false` + +启用[封面页](zh-cn/cover.md)。开启后是加载 `_coverpage.md` 文件,也可以自定义文件名。 + +```js +window.$docsify = { + coverpage: true, + + // 自定义文件名 + coverpage: 'cover.md', + + // mutiple covers + coverpage: ['/', '/zh-cn/'], + + // mutiple covers and custom file name + coverpage: { + '/': 'cover.md', + '/zh-cn/': 'cover.md' + } +}; +``` + +## name + +* 类型:`String` + +文档标题,会显示在侧边栏顶部。 + +```js +window.$docsify = { + name: 'docsify' +}; +``` + +## nameLink + +* 类型:`String` +* 默认值:`window.location.pathname` + +点击文档标题后跳转的链接地址。 + +```js +window.$docsify = { + nameLink: '/', + + // 按照路由切换 + nameLink: { + '/zh-cn/': '/zh-cn/', + '/': '/' + } +}; +``` + +## markdown + +* 类型: `Object|Function` + +参考 [Markdown 配置](zh-cn/markdown.md)。 + +```js +window.$docsify = { + // object + markdown: { + smartypants: true, + renderer: { + link: function() { + // ... + } + } + }, + + // function + markdown: function(marked, renderer) { + // ... + return marked; + } +}; +``` + +## themeColor + +* 类型:`String` + +替换主题色。利用 [CSS3 支持变量](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_variables)的特性,对于老的浏览器有 polyfill 处理。 + +```js +window.$docsify = { + themeColor: '#3F51B5' +}; +``` + +## alias + +* 类型:`Object` + +定义路由别名,可以更自由的定义路由规则。 支持正则。 + +```js +window.$docsify = { + alias: { + '/foo/(+*)': '/bar/$1', // supports regexp + '/zh-cn/changelog': '/changelog', + '/changelog': + 'https://raw.githubusercontent.com/QingWei-Li/docsify/master/CHANGELOG', + '/.*/_sidebar.md': '/_sidebar.md' // See #301 + } +}; +``` + +## autoHeader + +* 类型:`Boolean` + +同时设置 `loadSidebar` 和 `autoHeader` 后,可以根据 `_sidebar.md` 的内容自动为每个页面增加标题。[#78](https://github.com/QingWei-Li/docsify/issues/78) + +```js +window.$docsify = { + loadSidebar: true, + autoHeader: true +}; +``` + +## executeScript + +* 类型:`Boolean` + +执行文档里的 script 标签里的脚本,只执行第一个 script ([demo](zh-cn/themes.md))。 如果 Vue 存在,则自动开启。 + +```js +window.$docsify = { + executeScript: true +}; +``` + +```markdown +## This is test + + +``` + +注意如果执行的是一个外链脚本,比如 jsfiddle 的内嵌 demo,请确保引入 [external-script](plugins.md?id=外链脚本-external-script) 插件。 + +## noEmoji + +* type: `Boolean` + +禁用 emoji 解析。 + +```js +window.$docsify = { + noEmoji: true +}; +``` + +## mergeNavbar + +* type: `Boolean` + +小屏设备下合并导航栏到侧边栏。 + +```js +window.$docsify = { + mergeNavbar: true +}; +``` + +## formatUpdated + +* type: `String|Function` + +我们可以显示文档更新日期通过 **{docsify-updated}** 变量. 并且格式化日期通过 `formatUpdated`。参考 https://github.com/lukeed/tinydate#patterns + +```js +window.$docsify = { + formatUpdated: '{MM}/{DD} {HH}:{mm}', + + formatUpdated: function(time) { + // ... + + return time; + } +}; +``` + +## externalLinkTarget + +* type: `String` +* default: `_blank` + +当前默认为 \_blank, 配置一下就可以: + +```js +window.$docsify = { + externalLinkTarget: '_self' // default: '_blank' +}; +``` + +## routerMode + +* type: `String` +* default: `history` + +```js +window.$docsify = { + routerMode: 'history' // default: 'hash' +}; +``` + +## noCompileLinks + +* 类型: `Array` + +有时我们不希望 docsify 处理我们的链接。 参考 [#203](https://github.com/QingWei-Li/docsify/issues/203) + +```js +window.$docsify = { + noCompileLinks: ['/foo', '/bar/.*'] +}; +``` + +## requestHeaders + +* type: `Object` + +设置请求资源的请求头。 + +```js +window.$docsify = { + requestHeaders: { + 'x-token': 'xxx' + } +}; +``` + +## ext + +* type: `String` + +资源的文件扩展名。 + +```js +window.$docsify = { + ext: '.md' +}; +``` + +## fallbackLanguages + +* type: `Array` + +List of languages that will fallback to the default language when a page is request and didn't exists for the given local. + +Example: + +* try to fetch the page of `/de/overview`. If this page exists, it'll be displayed +* then try to fetch the default page `/overview` (depending on the default language). If this page exists, it'll be displayed +* then display 404 page. + +```js +window.$docsify = { + fallbackLanguages: ['fr', 'de'] +}; +``` + +## notFoundPage + +* type: `Boolean` | `String` | `Object` + +Load the `_404.md` file: +```js +window.$docsify = { + notFoundPage: true +}; +``` + +Load the customised path of the 404 page: +```js +window.$docsify = { + notFoundPage: 'my404.md' +}; +``` + +Load the right 404 page according to the localisation: +```js +window.$docsify = { + notFoundPage: { + '/': '_404.md', + '/de': 'de/_404.md', + } +}; +``` +> Note: The options with fallbackLanguages didn't work with the `notFoundPage` options. + + diff --git a/docs/docExample/cover.md b/docs/docExample/cover.md new file mode 100644 index 0000000..25026d2 --- /dev/null +++ b/docs/docExample/cover.md @@ -0,0 +1,99 @@ +# 封面 + +通过设置 `coverpage` 参数,可以开启渲染封面的功能。具体用法见[配置项#coverpage](configuration.md#coverpage)。 + +## 基本用法 + +封面的生成同样是从 markdown 文件渲染来的。开启渲染封面功能后在文档根目录创建 `_coverpage.md` 文件。渲染效果如本文档。 + +_index.html_ + +```html + + +``` + +_\_coverpage.md_ + +```markdown +![logo](_media/icon.svg) + +# docsify + +> A magical documentation site generator. + +* Simple and lightweight (~12kb gzipped) +* Multiple themes +* Not build static html files + +[GitHub](https://github.com/QingWei-Li/docsify/) +[Get Started](#quick-start) +``` + +!> 一份文档只会在根目录下加载封面,其他页面或者二级目录下都不会加载。 + +## 自定义背景 + +目前的背景是随机生成的渐变色,我们自定义背景色或者背景图。在文档末尾用添加图片的 Markdown 语法设置背景。 + +_\_coverpage.md_ + +```markdown +# docsify + +[GitHub](https://github.com/QingWei-Li/docsify/) +[Get Started](#quick-start) + + + +![](_media/bg.png) + + + +![color](#f0f0f0) +``` + +## 封面作为首页 + +通常封面和首页是同时出现的,当然你也是当封面独立出来通过设置[onlyCover 选项](zh-cn/configuration.md#onlycover)。 + +## 多个封面 + +如果你的文档网站是多语言的,或许你需要设置多个封面。 + +例如你的文档目录结构如下 + +```text +. +└── docs + ├── README.md + ├── guide.md + ├── _coverpage.md + └── zh-cn + ├── README.md + └── guide.md + └── _coverpage.md +``` + +那么你可以这么配置 + +```js +window.$docsify = { + coverpage: ['/', '/zh-cn/'] +}; +``` + +或者具体指名文件名 + +```js +window.$docsify = { + coverpage: { + '/': 'cover.md', + '/zh-cn/': 'cover.md' + } +}; +``` diff --git a/docs/docExample/custom-navbar.md b/docs/docExample/custom-navbar.md new file mode 100644 index 0000000..aac3e31 --- /dev/null +++ b/docs/docExample/custom-navbar.md @@ -0,0 +1,64 @@ +# 自定义导航栏 + +我们可以直接在 HTML 里定义导航栏,要注意链接要以 `#/` 开头。 + +_index.html_ + +```html + + +
    + +``` + +## 配置文件 + +那我们可以通过 Markdown 文件来配置导航。首先配置 `loadNavbar`,默认加载的文件为 `_navbar.md`。具体配置规则见[配置项#loadNavbar](configuration.md#loadnavbar)。 + +_index.html_ + +```html + + +``` + +_\_navbar.md_ + +```markdown +* [En](/) +* [中文](/zh-cn/) +``` + +`_navbar.md` 加载逻辑和 `sidebar` 文件一致,从每层目录下获取。例如当前路由为 `/zh-cn/custom-navbar` 那么是从 `/zh-cn/_navbar.md` 获取导航栏。 + +## 嵌套 + +如果导航内容过多,可以写成嵌套的列表,会被渲染成下拉列表的形式。 + +_\_navbar.md_ + +```markdown +* 基础 + * [快速开始](zh-cn/quickstart.md) + * [多页文档](zh-cn/more-pages.md) + * [定制导航栏](zh-cn/custom-navbar.md) + * [封面](zh-cn/cover.md) + +* 配置 + * [配置项](zh-cn/configuration.md) + * [主题](zh-cn/themes.md) + * [使用插件](zh-cn/plugins.md) + * [Markdown 配置](zh-cn/markdown.md) + * [代码高亮](zh-cn/language-highlight.md) +``` + +效果图 + +![嵌套导航栏](../_images/zh-cn/nested-navbar.png '嵌套导航栏') diff --git a/docs/docExample/deploy.md b/docs/docExample/deploy.md new file mode 100644 index 0000000..ab55a61 --- /dev/null +++ b/docs/docExample/deploy.md @@ -0,0 +1,58 @@ +# 部署 + +和 GitBook 生成的文档一样,我们可以直接把文档网站部署到 GitHub Pages 或者 VPS 上。 + +## GitHub Pages + +GitHub Pages 支持从三个地方读取文件 +- `docs/` 目录 +- master 分支 +- gh-pages 分支 + +我们推荐直接将文档放在 `docs/` 目录下,在设置页面开启 **GitHub Pages** 功能并选择 `master branch /docs folder` 选项。 + +![github pages](../_images/deploy-github-pages.png) + +!> 可以将文档放在根目录下,然后选择 **master 分支** 作为文档目录。 + + +## GitLab Pages + +如果你正在部署你的主分支, 在 `.gitlab-ci.yml` 中包含以下脚本: + +?> `.public` 的解决方法是这样的,`cp` 不会无限循环的将 `public/` 复制到自身。 + +``` YAML +pages: + stage: deploy + script: + - mkdir .public + - cp -r * .public + - mv .public public + artifacts: + paths: + - public + only: + - master +``` + +!> 你可以用 `- cp -r docs/. public` 替换脚本, 如果 `./docs` 是你的 docsify 子文件夹。 + + +## VPS + +和部署所有静态网站一样,只需将服务器的访问根目录设定为 `index.html` 文件。 + +例如 nginx 的配置 + +```nginx +server { + listen 80; + server_name your.domain.com; + + location / { + alias /path/to/dir/of/docs; + index index.html; + } +} +``` diff --git a/docs/docExample/embed-files.md b/docs/docExample/embed-files.md new file mode 100644 index 0000000..429cc8e --- /dev/null +++ b/docs/docExample/embed-files.md @@ -0,0 +1,63 @@ +# 文件嵌入 + +docsify 4.6 开始支持嵌入任何类型的文件到文档里。你可以将文件当成 `iframe`、`video`、`audio` 或者 `code block`,如果是 Markdown 文件,甚至可以直接插入到当前文档里。 + +这是一个嵌入 Markdown 文件的例子。 + +```markdown +[filename](../_media/example.md ':include') +``` + +`example.md` 文件的内容将会直接显示在这里 + +[filename](../_media/example.md ':include') + +你可以查看 [example.md](../_media/example.md ':ignore') 原始内容对比效果。 + +通常情况下,这样的语法将会被当作链接处理。但是在 docsify 里,如果你添加一个 `:include` 选项,它就会被当作文件嵌入。 + +## 嵌入的类型 + +当前,嵌入的类型是通过文件后缀自动识别的,这是目前支持的类型: + +* **iframe** `.html`, `.htm` +* **markdown** `.markdown`, `.md` +* **audio** `.mp3` +* **video** `.mp4`, `.ogg` +* **code** other file extension + +当然,你也可以强制设置嵌入类型。例如你想将 Markdown 文件当作一个 `code block` 嵌入。 + +```markdown +[filename](../_media/example.md ':include :type=code') +``` + +你将得到 + +[filename](../_media/example.md ':include :type=code') + +## 标签属性 + +如果你嵌入文件是一个 `iframe`、`audio` 或者 `video`,你可以给这些标签设置属性。 + +```markdown +[cinwell website](https://cinwell.com ':include :type=iframe width=100% height=400px') +``` + +[cinwell website](https://cinwell.com ':include :type=iframe width=100% height=400px') + +看见没?你只需要直接写属性就好了,每个标签有哪些属性建议你查看 [MDN 文档](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe)。 + +## 代码块高亮 + +如果是嵌入一个代码块,你可以设置高亮的语言,或者让它自动识别。这里是手动设置高亮语言 + +```markdown +[](../_media/example.html ':include :type=code text') +``` + +⬇️ + +[](../_media/example.html ':include :type=code text') + +?> 如何高亮代码?你可以查看[这份文档](language-highlight.md). diff --git a/docs/docExample/helpers.md b/docs/docExample/helpers.md new file mode 100644 index 0000000..f29f0fc --- /dev/null +++ b/docs/docExample/helpers.md @@ -0,0 +1,72 @@ +# 文档助手 + +docsify 扩展了一些 Markdown 语法,可以让文档更易读。 + +## 强调内容 + +适合显示重要的提示信息,语法为 `!> 内容`。 + +```markdown +!> 一段重要的内容,可以和其他 **Markdown** 语法混用。 +``` + +!> 一段重要的内容,可以和其他 **Markdown** 语法混用。 + +## 普通提示 + +普通的提示信息,比如写 TODO 或者参考内容等。 + +```markdown +?> _TODO_ 完善示例 +``` + +?> _TODO_ 完善示例 + +## 忽略编译链接 + +有时候我们会把其他一些相对路径放到链接上,你必须告诉 docsify 你不需要编译这个链接。 例如: + +```md +[link](/demo/) +``` + +它将被编译为 `link` 并将加载 `/demo/README.md`. 可能你想跳转到 `/demo/index.html`。 + +现在你可以做到这一点 + +```md +[link](/demo/ ':ignore') +``` + +即将会得到 `link` html 代码。不要担心,你仍然可以为链接设置标题。 + +```md +[link](/demo/ ':ignore title') + +link +``` + +## 设置链接的 target 属性 + +```md +[link](/demo ':target=_blank') +[link](/demo2 ':target=_self') +``` + +## Github 任务列表 + +```md +* [ ] foo +* bar +* [x] baz +* [] bam <~ not working + * [ ] bim + * [ ] lim +``` + +* [ ] foo +* bar +* [x] baz +* [] bam <~ not working + * [ ] bim + * [ ] lim diff --git a/docs/docExample/language-highlight.md b/docs/docExample/language-highlight.md new file mode 100644 index 0000000..20e9f22 --- /dev/null +++ b/docs/docExample/language-highlight.md @@ -0,0 +1,11 @@ +# 代码高亮 + +内置的代码高亮工具是 [Prism](https://github.com/PrismJS/prism),默认支持 CSS、JavaScript 和 HTML。如果需要高亮其语言——例如 PHP——可以手动引入代码高亮插件。 + +```html + + + +``` + +?> 其他的语言高亮插件可以查看[Prims 仓库](https://github.com/PrismJS/prism/tree/gh-pages/components)。 diff --git a/docs/docExample/markdown.md b/docs/docExample/markdown.md new file mode 100644 index 0000000..694698f --- /dev/null +++ b/docs/docExample/markdown.md @@ -0,0 +1,56 @@ +# Markdown 配置 + +内置的 Markdown 解析器是 [marked](https://github.com/markedjs/marked),可以修改它的配置。同时可以直接配置 `renderer`。 + +```js +window.$docsify = { + markdown: { + smartypants: true, + renderer: { + link: function() { + // ... + } + } + } +} +``` + +?> 完整配置参数参考 [marked 文档](https://github.com/markedjs/marked#options-1) + +当然也可以完全定制 Markdown 解析规则。 + +```js +window.$docsify = { + markdown: function(marked, renderer) { + // ... + + return marked + } +} +``` + + +## 支持 mermaid + +```js +// Import mermaid +// +// + +mermaid.initialize({ startOnLoad: false }); + +window.$docsify = { + markdown: { + renderer: { + code: function(code, lang) { + if (lang === "mermaid") { + return ( + '
    ' + mermaid.render(lang, code) + "
    " + ); + } + return this.origin.code.apply(this, arguments); + } + } + } +} +``` diff --git a/docs/docExample/more-pages.md b/docs/docExample/more-pages.md new file mode 100644 index 0000000..910273b --- /dev/null +++ b/docs/docExample/more-pages.md @@ -0,0 +1,100 @@ +# 多页文档 + +如果需要创建多个页面,或者需要多级路由的网站,在 docsify 里也能很容易的实现。例如创建一个 `guide.md` 文件,那么对应的路由就是 `/#/guide`。 + +假设你的目录结构如下: + +```text +-| docs/ + -| README.md + -| guide.md + -| zh-cn/ + -| README.md + -| guide.md +``` + +那么对应的访问页面将是 + +```text +docs/README.md => http://domain.com +docs/guide.md => http://domain.com/guide +docs/zh-cn/README.md => http://domain.com/zh-cn/ +docs/zh-cn/guide.md => http://domain.com/zh-cn/guide +``` + +## 定制侧边栏 + +默认情况下,侧边栏会根据当前文档的标题生成目录。也可以设置文档链接,通过 Markdown 文件生成,效果如当前的文档的侧边栏。 + +首先配置 `loadSidebar` 选项,具体配置规则见[配置项#loadSidebar](configuration.md#loadsidebar)。 + +```html + + +``` + +接着创建 `_sidebar.md` 文件,内容如下 + +```markdown +* [首页](zh-cn/) +* [指南](zh-cn/guide) +``` + +!> 需要在文档根目录创建 `.nojekyll` 命名的空文件,阻止 GitHub Pages 忽略命名是下划线开头的文件。 + +`_sidebar.md` 的加载逻辑是从每层目录下获取文件,如果当前目录不存在该文件则回退到上一级目录。例如当前路径为 `/zh-cn/more-pages` 则从 `/zh-cn/_sidebar.md` 获取文件,如果不存在则从 `/_sidebar.md` 获取。 + +当然你也可以配置 `alias` 避免不必要的回退过程。 + +```html + +``` + +## 显示目录 + +自定义侧边栏同时也可以开启目录功能。设置 `subMaxLevel` 配置项,具体介绍见 [配置项#sub-max-level](zh-cn/configuration#sub-max-level)。 + +```html + + +``` + +## 忽略副标题 + +当设置了 `subMaxLevel` 时,默认情况下每个标题都会自动添加到目录中。如果你想忽略特定的标题,可以给它添加  `{docsify-ignore}` 。 + +```markdown +# Getting Started + +## Header {docsify-ignore} + +该标题不会出现在侧边栏的目录中。 +``` + +要忽略特定页面上的所有标题,你可以在页面的第一个标题上使用 `{docsify-ignore-all}` 。 + +```markdown +# Getting Started {docsify-ignore-all} + +## Header + +该标题不会出现在侧边栏的目录中。 +``` + +在使用时, `{docsify-ignore}` 和 `{docsify-ignore-all}` 都不会在页面上呈现。 diff --git a/docs/docExample/plugins.md b/docs/docExample/plugins.md new file mode 100644 index 0000000..b65cec4 --- /dev/null +++ b/docs/docExample/plugins.md @@ -0,0 +1,181 @@ +# 插件列表 + +## 全文搜索 - Search + +全文搜索插件会根据当前页面上的超链接获取文档内容,在 `localStorage` 内建立文档索引。默认过期时间为一天,当然我们可以自己指定需要缓存的文件列表或者配置过期时间。 + + +```html + + + +``` + +## 谷歌统计 - Google Analytics + +需要配置 track id 才能使用。 + +```html + + + +``` + +也可以通过 `data-ga` 配置 id。 + +```html + + +``` + +## emoji + +默认是提供 emoji 解析的,能将类似 `:100:` 解析成 :100:。但是它不是精准的,因为没有处理非 emoji 的字符串。如果你需要正确解析 emoji 字符串,你可以引入这个插件。 + +```html + +``` + +## 外链脚本 - External Script + +如果文档里的 script 是内联脚本,可以直接执行;而如果是外链脚本(即 js 文件内容由 `src` 属性引入),则需要使用此插件。 + +```html + +``` + +## Demo code with instant preview and jsfiddle integration + +With this plugin, sample code can be rendered on the page instantly, so that the readers can see the preview immediately. +When readers expand the demo box, the source code and description are shown there. if they click the button `Try in Jsfiddle`, +`jsfiddle.net` will be open with the code of this sample, which allow readers to revise the code and try on their own. + +[Vue](https://njleonzhang.github.io/docsify-demo-box-vue/) and [React](https://njleonzhang.github.io/docsify-demo-box-react/) are both supported. + + +## 图片缩放 - Zoom image + +Medium's 风格的图片缩放插件. 基于 [medium-zoom](https://github.com/francoischalifour/medium-zoom)。 + +```html + +``` + + +忽略某张图片 + +```markdown +![](image.png ':no-zoom') +``` + + + +## 在 Github 上编辑 + +在每一页上添加 `Edit on github` 按钮. 由第三方库提供, 查看 [document](https://github.com/njleonzhang/docsify-edit-on-github) + + +## Copy to Clipboard + +Add a simple `Click to copy` button to all preformatted code blocks to effortlessly allow users to copy example code from your docs. Provided by [@jperasmus](https://github.com/jperasmus) + +```html + + +``` + +```javascript +window.$docsify = { + plugins: [ + window.DocsifyCopyCodePlugin.init() + ] +} +``` + +See [here](https://github.com/jperasmus/docsify-copy-code/blob/master/README.md) for more details. + + + +## Disqus + +Disqus comments. https://disqus.com/ + +```html + + +``` + + +## Gitalk + +[Gitalk](https://github.com/gitalk/gitalk) is a modern comment component based on Github Issue and Preact. + +```html + + + + + +``` + +## Navigation + +Pagination for docsify. By [@imyelo](https://github.com/imyelo) + +```html + + +``` diff --git a/docs/docExample/pwa.md b/docs/docExample/pwa.md new file mode 100644 index 0000000..2337e9f --- /dev/null +++ b/docs/docExample/pwa.md @@ -0,0 +1,113 @@ +# 离线模式 + +[Progressive Web Apps](https://developers.google.com/web/progressive-web-apps/)(PWA) 是一项融合 Web 和 Native 应用各项优点的解决方案。我们可以利用其支持离线功能的特点,让我们的网站可以在信号差或者离线状态下正常运行。 +要使用它也非常容易。 + +## 创建 serviceWorker +这里已经整理好了一份代码,你只需要在网站根目录下创建一个 `sw.js` 文件,并粘贴下面的代码。 + +*sw.js* + +```js +/* =========================================================== + * docsify sw.js + * =========================================================== + * Copyright 2016 @huxpro + * Licensed under Apache 2.0 + * Register service worker. + * ========================================================== */ + +const RUNTIME = 'docsify' +const HOSTNAME_WHITELIST = [ + self.location.hostname, + 'fonts.gstatic.com', + 'fonts.googleapis.com', + 'unpkg.com' +] + +// The Util Function to hack URLs of intercepted requests +const getFixedUrl = (req) => { + var now = Date.now() + var url = new URL(req.url) + + // 1. fixed http URL + // Just keep syncing with location.protocol + // fetch(httpURL) belongs to active mixed content. + // And fetch(httpRequest) is not supported yet. + url.protocol = self.location.protocol + + // 2. add query for caching-busting. + // Github Pages served with Cache-Control: max-age=600 + // max-age on mutable content is error-prone, with SW life of bugs can even extend. + // Until cache mode of Fetch API landed, we have to workaround cache-busting with query string. + // Cache-Control-Bug: https://bugs.chromium.org/p/chromium/issues/detail?id=453190 + if (url.hostname === self.location.hostname) { + url.search += (url.search ? '&' : '?') + 'cache-bust=' + now + } + return url.href +} + +/** + * @Lifecycle Activate + * New one activated when old isnt being used. + * + * waitUntil(): activating ====> activated + */ +self.addEventListener('activate', event => { + event.waitUntil(self.clients.claim()) +}) + +/** + * @Functional Fetch + * All network requests are being intercepted here. + * + * void respondWith(Promise r) + */ +self.addEventListener('fetch', event => { + // Skip some of cross-origin requests, like those for Google Analytics. + if (HOSTNAME_WHITELIST.indexOf(new URL(event.request.url).hostname) > -1) { + // Stale-while-revalidate + // similar to HTTP's stale-while-revalidate: https://www.mnot.net/blog/2007/12/12/stale + // Upgrade from Jake's to Surma's: https://gist.github.com/surma/eb441223daaedf880801ad80006389f1 + const cached = caches.match(event.request) + const fixedUrl = getFixedUrl(event.request) + const fetched = fetch(fixedUrl, { cache: 'no-store' }) + const fetchedCopy = fetched.then(resp => resp.clone()) + + // Call respondWith() with whatever we get first. + // If the fetch fails (e.g disconnected), wait for the cache. + // If there’s nothing in cache, wait for the fetch. + // If neither yields a response, return offline pages. + event.respondWith( + Promise.race([fetched.catch(_ => cached), cached]) + .then(resp => resp || fetched) + .catch(_ => { /* eat any errors */ }) + ) + + // Update the cache with the version we fetched (only for ok status) + event.waitUntil( + Promise.all([fetchedCopy, caches.open(RUNTIME)]) + .then(([response, cache]) => response.ok && cache.put(event.request, response)) + .catch(_ => { /* eat any errors */ }) + ) + } +}) +``` + +## 注册 + +现在,到 `index.html` 里注册它。这个功能只能工作在一些现代浏览器上,所以我们需要加个判断。 + +*index.html* + +```html + +``` + +## 体验一下 + +发布你的网站,并开始享受离线模式的魔力吧!:ghost: 当然你现在看到的 docsify 的文档网站已经支持离线模式了,你可以关掉 Wi-Fi 体验一下。 diff --git a/docs/docExample/quickstart.md b/docs/docExample/quickstart.md new file mode 100644 index 0000000..cd331b3 --- /dev/null +++ b/docs/docExample/quickstart.md @@ -0,0 +1,90 @@ +# 快速开始 + +推荐安装 `docsify-cli` 工具,可以方便创建及本地预览文档网站。 + +```bash +npm i docsify-cli -g +``` + +## 初始化项目 + +如果想在项目的 `./docs` 目录里写文档,直接通过 `init` 初始化项目。 + +```bash +docsify init ./docs +``` + +## 开始写文档 + +初始化成功后,可以看到 `./docs` 目录下创建的几个文件 + +- `index.html` 入口文件 +- `README.md` 会做为主页内容渲染 +- `.nojekyll` 用于阻止 GitHub Pages 会忽略掉下划线开头的文件 + +直接编辑 `docs/README.md` 就能更新网站内容,当然也可以[写多个页面](zh-cn/more-pages.md)。 + +## 本地预览网站 + +运行一个本地服务器通过 `docsify serve` 可以方便的预览效果,而且提供 LiveReload 功能,可以让实时的预览。默认访问 http://localhost:3000 。 + +```bash +docsify serve docs +``` + +?> 更多命令行工具用法,参考 [docsify-cli 文档](https://github.com/QingWei-Li/docsify-cli)。 + +## 手动初始化 + +如果不喜欢 npm 或者觉得安装工具太麻烦,我们其实只需要直接创建一个 `index.html` 文件。 + +*index.html* + +```html + + + + + + + + + +
    + + + + +``` + +如果系统里安装 Python 的话,也可以很轻易的启动一个静态服务器。 + +```bash +cd docs && python -m SimpleHTTPServer 3000 +``` + +## Loading 提示 + +初始化时会显示 `Loading...` 内容,你可以自定义提示信息。 + +*index.html* +```html +
    加载中
    +``` + +如果更改了 `el` 的配置,需要将该元素加上 `data-app` 属性。 + +*index.html* +```html +
    加载中
    + + +``` diff --git a/docs/docExample/ssr.md b/docs/docExample/ssr.md new file mode 100644 index 0000000..20ed35a --- /dev/null +++ b/docs/docExample/ssr.md @@ -0,0 +1,118 @@ +# 服务端渲染(SSR) + +先看例子 https://docsify.now.sh + +项目地址在 https://github.com/QingWei-Li/docsify-ssr-demo + +![](https://dn-mhke0kuv.qbox.me/2bfef08c592706108055.png) + +文档依旧是部署在 GitHub Pages 上,Node 服务部署在 now.sh 里,渲染的内容是从 GitHub Pages 上同步过来的。所以静态部署文档的服务器和服务端渲染的 Node 服务器是分开的,也就是说你还是可以用之前的方式更新文档,并不需要每次都部署。 + + + +## 快速开始 + +如果你熟悉 `now` 的使用,接下来的介绍就很简单了。先创建一个新项目,并安装 `now` 和 `docsify-cli`。 + +```bash +mkdir my-ssr-demo && cd my-ssr-demo +npm init -y +npm i now docsify-cli -D +``` + +配置 `package.json` + +```json +{ + "scripts": { + "start": "docsify start .", + "deploy": "now -p" + }, + "docsify": { + "config": { + "basePath": "https://docsify.js.org/", + "loadSidebar": true, + "loadNavbar": true + } + } +} +``` + +如果你还没有创建文档,可以参考[之前的文章](https://zhuanlan.zhihu.com/p/24540753)。其中 `basePath` 为文档所在的路径,可以填你的 docsify 文档网站。 + +配置可以单独写在配置文件内,然后通过 `--config config.js` 加载。 + +渲染的基础模版也可以自定义,配置在 `template` 属性上,例如 + +```js +"docsify": { + "template": "./ssr.html", + "config": { + "basePath": "https://docsify.js.org/", + "loadSidebar": true, + "loadNavbar": true + } + } +``` + +*ssr.html* + +```html + + + + + docsify + + + + + + + + + + + + + + +``` + +其中 `` 和 `` 为占位符,会自动将渲染后的 html 和配置内容注入到页面上。 + +现在,你可以运行 `npm start` 预览效果,如果没有问题就通过 `npm run deploy` 部署服务。 + +```bash +npm start +# open http://localhost:4000 + +npm run deploy +# now ... +``` + + + +## 更多玩法 + +`docsify start` 其实是依赖了 [`docsify-server-renderer`](https://npmarket.surge.sh/?name=docsify-server-renderer) 模块,如果你感兴趣,你完全可以用它自己实现一个 server,可以加入缓存等功能。 + +```js +var Renderer = require('docsify-server-renderer') +var readFileSync = require('fs').readFileSync + +// init +var renderer = new Renderer({ + template: readFileSync('./docs/index.template.html', 'utf-8')., + config: { + name: 'docsify', + repo: 'qingwei-li/docsify' + } +}) + +renderer.renderToString(url) + .then(html => {}) + .catch(err => {}) +``` + +当然文档文件和 server 也是可以部署在一起的,`basePath` 不是一个 URL 的话就会当做文件路径处理,也就是从服务器上加载资源。 diff --git a/docs/docExample/themes.md b/docs/docExample/themes.md new file mode 100644 index 0000000..ef51bd3 --- /dev/null +++ b/docs/docExample/themes.md @@ -0,0 +1,56 @@ +# 主题 + +目前提供三套主题可供选择,模仿 [Vue](//vuejs.org) 和 [buble](//buble.surge.sh) 官网订制的主题样式。还有 [@liril-net](https://github.com/liril-net) 贡献的黑色风格的主题。 + +```html + + + + +``` + +!> CSS 的压缩文件位于 `/lib/themes/` + +```html + + + + +``` + +如果你有其他想法或者想开发别的主题,欢迎提 [PR](https://github.com/QingWei-Li/docsify/pulls)。 + +#### 点击切换主题 + + + + + + + + diff --git a/docs/docExample/vue.md b/docs/docExample/vue.md new file mode 100644 index 0000000..e0ecc59 --- /dev/null +++ b/docs/docExample/vue.md @@ -0,0 +1,112 @@ +# 兼容 Vue + +你可以直接在 Markdown 文件里写 Vue 代码,它将被执行。我们可以用它写一些 Vue 的 Demo 或者示例代码。 + + +## 基础用法 + +在 `index.html` 里引入 Vue。 + +```html + + +``` + +接着就可以愉快地在 Markdown 里写 Vue 了。默认会执行 `new Vue({ el: '#main' })` 创建示例。 + +*README.md* + +```markdown +# Vue 介绍 + +`v-for` 的用法 + +```html + +`` + + +``` + +当然你也可以手动初始化 Vue,这样你可以自定义一些配置。 + +*README.md* + +```markdown +# Vue 的基本用法 + +
    hello {{ msg }}
    + + +``` + +!> 一个 Markdown 文件里只有第一个 `script` 标签内的内容会被执行。 + +## 搭配 Vuep 写 Playground + +[Vuep](https://github.com/QingWei-Li/vuep) 是一个提供在线编辑和预览效果的 Vue 组件,搭配 docsify 可以直接在文档里写 Vue 的示例代码,支持 Vue component spec 和 JSX。 + +*index.html* + +```html + + + + + + + + + + + + +``` + +*README.md* +```markdown +# Vuep 使用 + + + + + +``` + + + + + + +?> 具体效果参考 [Vuep 文档](https://qingwei-li.github.io/vuep/)。 diff --git a/docs/docExample/write-a-plugin.md b/docs/docExample/write-a-plugin.md new file mode 100644 index 0000000..25aa1d1 --- /dev/null +++ b/docs/docExample/write-a-plugin.md @@ -0,0 +1,94 @@ +# 自定义插件 + +docsify 提供了一套插件机制,其中提供的钩子(hook)支持处理异步逻辑,可以很方便的扩展功能。 + +## 完整功能 + +```js +window.$docsify = { + plugins: [ + function (hook, vm) { + hook.init(function() { + // 初始化时调用,只调用一次,没有参数。 + }) + + hook.beforeEach(function(content) { + // 每次开始解析 Markdown 内容时调用 + // ... + return content + }) + + hook.afterEach(function(html, next) { + // 解析成 html 后调用。beforeEach 和 afterEach 支持处理异步逻辑 + // ... + // 异步处理完成后调用 next(html) 返回结果 + next(html) + }) + + hook.doneEach(function() { + // 每次路由切换时数据全部加载完成后调用,没有参数。 + // ... + }) + + hook.mounted(function() { + // 初始化完成后调用 ,只调用一次,没有参数。 + }) + + hook.ready(function() { + // 初始化并第一次加完成数据后调用,没有参数。 + }) + } + ] +} +``` + +!> 如果需要用 docsify 的内部方法,可以通过 `window.Docsify` 获取,通过 `vm` 获取当前实例。 + +## 例子 + + +### footer + +给每个页面的末尾加上 `footer` + +```js +window.$docsify = { + plugins: [ + function (hook) { + var footer = [ + '
    ', + '' + ].join('') + + hook.afterEach(function (html) { + return html + footer + }) + } + ] +} +``` + + +### Edit Button + +```js +window.$docsify = { + plugins: [ + function(hook, vm) { + hook.beforeEach(function (html) { + var url = 'https://github.com/QingWei-Li/docsify/blob/master/docs' + vm.route.file + var editHtml = '[📝 EDIT DOCUMENT](' + url + ')\n' + + return editHtml + + html + + '\n----\n' + + 'Last modified {docsify-updated} ' + + editHtml + }) + } + ] +} +``` \ No newline at end of file diff --git a/docs/en/README.md b/docs/en/README.md new file mode 100644 index 0000000..da2056b --- /dev/null +++ b/docs/en/README.md @@ -0,0 +1,3 @@ +# Headline + +> An awesome project. diff --git a/docs/en/_sidebar.md b/docs/en/_sidebar.md new file mode 100644 index 0000000..b08baec --- /dev/null +++ b/docs/en/_sidebar.md @@ -0,0 +1,28 @@ +* 入门 + + * [快速开始](quickstart.md) + * [多页文档](more-pages.md) + * [定制导航栏](custom-navbar.md) + * [封面](cover.md) + +* 定制化 + + * [配置项](configuration.md) + * [主题](themes.md) + * [插件列表](plugins.md) + * [开发插件](write-a-plugin.md) + * [Markdown 配置](markdown.md) + * [代码高亮](language-highlight.md) + +* 指南 + + * [部署](deploy.md) + * [文档助手](helpers.md) + * [兼容 Vue](vue.md) + * [CDN](cdn.md) + * [离线模式(PWA)](pwa.md) + * [服务端渲染 (SSR)](ssr.md) + * [文件嵌入(new)](embed-files.md) + +* [Awesome docsify](awesome.md) +* [Changelog](changelog.md) diff --git a/docs/faq.md b/docs/faq.md new file mode 100644 index 0000000..897f6e7 --- /dev/null +++ b/docs/faq.md @@ -0,0 +1,29 @@ +# FAQ 常见问题 + + +## 请求跨域 + +打开可以跨域的谷歌; + +* **49以下版本解决跨域问题** + **mac** + ``` + $ open -a Google\ Chrome --args --disable-web-security + ``` + **windows** + ``` + "C:\Program Files\Google\Chrome\Application\chrome.exe" --args --disable-web-security  + ``` + +* **49以上版本解决跨域问题** + **mac** + ``` + $ open -a Google\ Chrome --args --disable-web-security  --user-data-dir + ``` + **windows** + ``` + "C:\Program Files\Google\Chrome\Application\chrome.exe" --args --disable-web-security  --user-data-dir + ``` + +如果以上方式不能解决你的跨域问题,请自行网上搜索 chrome对应的版本的跨域. + diff --git a/docs/images/ad1.png b/docs/images/ad1.png new file mode 100644 index 0000000..645d74a Binary files /dev/null and b/docs/images/ad1.png differ diff --git a/docs/images/ad2.png b/docs/images/ad2.png new file mode 100644 index 0000000..ab8f18e Binary files /dev/null and b/docs/images/ad2.png differ diff --git a/docs/images/ad3.png b/docs/images/ad3.png new file mode 100644 index 0000000..f611499 Binary files /dev/null and b/docs/images/ad3.png differ diff --git a/docs/images/ad4.png b/docs/images/ad4.png new file mode 100644 index 0000000..f50f5e6 Binary files /dev/null and b/docs/images/ad4.png differ diff --git a/docs/images/applogo.png b/docs/images/applogo.png new file mode 100644 index 0000000..4fab6c8 Binary files /dev/null and b/docs/images/applogo.png differ diff --git a/docs/images/bui-silu.png b/docs/images/bui-silu.png new file mode 100644 index 0000000..4a14331 Binary files /dev/null and b/docs/images/bui-silu.png differ diff --git a/docs/images/bui-silu2.png b/docs/images/bui-silu2.png new file mode 100644 index 0000000..72093c7 Binary files /dev/null and b/docs/images/bui-silu2.png differ diff --git a/docs/images/bui-slide-demo.gif b/docs/images/bui-slide-demo.gif new file mode 100644 index 0000000..fbd6cb5 Binary files /dev/null and b/docs/images/bui-slide-demo.gif differ diff --git a/docs/images/bui_dev_floder.png b/docs/images/bui_dev_floder.png new file mode 100644 index 0000000..48ed015 Binary files /dev/null and b/docs/images/bui_dev_floder.png differ diff --git a/docs/images/catalog.png b/docs/images/catalog.png new file mode 100644 index 0000000..ea41c5b Binary files /dev/null and b/docs/images/catalog.png differ diff --git a/docs/images/chrome.png b/docs/images/chrome.png new file mode 100644 index 0000000..be0864d Binary files /dev/null and b/docs/images/chrome.png differ diff --git a/docs/images/cutimage_low.gif b/docs/images/cutimage_low.gif new file mode 100644 index 0000000..0751ab4 Binary files /dev/null and b/docs/images/cutimage_low.gif differ diff --git a/docs/images/cutimage_low.jpg b/docs/images/cutimage_low.jpg new file mode 100644 index 0000000..06389bc Binary files /dev/null and b/docs/images/cutimage_low.jpg differ diff --git a/docs/images/ecode.png b/docs/images/ecode.png new file mode 100644 index 0000000..9803995 Binary files /dev/null and b/docs/images/ecode.png differ diff --git a/docs/images/getSlideHeight.png b/docs/images/getSlideHeight.png new file mode 100644 index 0000000..c74cc61 Binary files /dev/null and b/docs/images/getSlideHeight.png differ diff --git a/docs/images/modify540.png b/docs/images/modify540.png new file mode 100644 index 0000000..cdc9e2e Binary files /dev/null and b/docs/images/modify540.png differ diff --git a/docs/images/prepros.png b/docs/images/prepros.png new file mode 100644 index 0000000..231828d Binary files /dev/null and b/docs/images/prepros.png differ diff --git a/docs/images/qq_low.gif b/docs/images/qq_low.gif new file mode 100644 index 0000000..3fd4bb1 Binary files /dev/null and b/docs/images/qq_low.gif differ diff --git a/docs/images/readme.md b/docs/images/readme.md new file mode 100644 index 0000000..1a3ece2 --- /dev/null +++ b/docs/images/readme.md @@ -0,0 +1 @@ +这里存放的是 bui 文档用到的图片,远程地址调用 \ No newline at end of file diff --git a/docs/images/router/buijs-create-demo_low.gif b/docs/images/router/buijs-create-demo_low.gif new file mode 100644 index 0000000..8dcdb8e Binary files /dev/null and b/docs/images/router/buijs-create-demo_low.gif differ diff --git a/docs/images/router/catalog.png b/docs/images/router/catalog.png new file mode 100644 index 0000000..8f6f4e6 Binary files /dev/null and b/docs/images/router/catalog.png differ diff --git a/docs/images/router/preview.png b/docs/images/router/preview.png new file mode 100644 index 0000000..c169112 Binary files /dev/null and b/docs/images/router/preview.png differ diff --git a/docs/images/router/router_flow.png b/docs/images/router/router_flow.png new file mode 100644 index 0000000..9cbb240 Binary files /dev/null and b/docs/images/router/router_flow.png differ diff --git a/docs/images/ui-html.gif b/docs/images/ui-html.gif new file mode 100644 index 0000000..b6057f2 Binary files /dev/null and b/docs/images/ui-html.gif differ diff --git a/docs/images/ui-page.gif b/docs/images/ui-page.gif new file mode 100644 index 0000000..dacd0e7 Binary files /dev/null and b/docs/images/ui-page.gif differ diff --git a/docs/images/ui-router.gif b/docs/images/ui-router.gif new file mode 100644 index 0000000..ff46f90 Binary files /dev/null and b/docs/images/ui-router.gif differ diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 0000000..d04740c --- /dev/null +++ b/docs/index.html @@ -0,0 +1,87 @@ + + + + + + BUI 教程 + + + + + + + + + + + +
    Loading ...
    + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/js/docsify.min.js b/docs/js/docsify.min.js new file mode 100644 index 0000000..f040300 --- /dev/null +++ b/docs/js/docsify.min.js @@ -0,0 +1 @@ +!function(){function e(e){var t=Object.create(null);return function(n){var r=i(n)?n:JSON.stringify(n);return t[r]||(t[r]=e(n))}}var t=e(function(e){return e.replace(/([A-Z])/g,function(e){return"-"+e.toLowerCase()})}),n=Object.prototype.hasOwnProperty,r=Object.assign||function(e){for(var t=arguments,r=1;r=i.length)r(n);else if("function"==typeof t)if(2===t.length)t(n,function(t){n=t,o(e+1)});else{var a=t(n);n=void 0===a?n:a,o(e+1)}else o(e+1)};o(0)}var l=!0,c=l&&document.body.clientWidth<=600,u=l&&window.history&&window.history.pushState&&window.history.replaceState&&!navigator.userAgent.match(/((iPod|iPhone|iPad).+\bOS\s+[1-4]\D|WebApps\/.+CFNetwork)/),h={};function p(e,t){if(void 0===t&&(t=!1),"string"==typeof e){if(void 0!==window.Vue)return m(e);e=t?m(e):h[e]||(h[e]=m(e))}return e}var d=l&&document,g=l&&d.body,f=l&&d.head;function m(e,t){return t?e.querySelector(t):d.querySelector(e)}function v(e,t){return[].slice.call(t?e.querySelectorAll(t):d.querySelectorAll(e))}function b(e,t){return e=d.createElement(e),t&&(e.innerHTML=t),e}function y(e,t){return e.appendChild(t)}function k(e,t){return e.insertBefore(t,e.children[0])}function w(e,t,n){o(t)?window.addEventListener(e,t):e.addEventListener(t,n)}function x(e,t,n){o(t)?window.removeEventListener(e,t):e.removeEventListener(t,n)}function _(e,t,n){e&&e.classList[n?t:"toggle"](n||t)}var S=Object.freeze({getNode:p,$:d,body:g,head:f,find:m,findAll:v,create:b,appendTo:y,before:k,on:w,off:x,toggleClass:_,style:function(e){y(f,b("style",e))}});function C(e,t){return void 0===t&&(t=""),e&&e.length?(e.forEach(function(e){t+='
  • '+e.title+"
  • ",e.children&&(t+='
    • '+C(e.children)+"
    ")}),t):""}function L(e,t){return'

    '+t.slice(5).trim()+"

    "}var E,A;function $(e){var t,n=e.loaded,r=e.total,i=e.step;!E&&function(){var e=b("div");e.classList.add("progress"),y(g,e),E=e}(),t=i?(t=parseInt(E.style.width||0,10)+i)>80?80:t:Math.floor(n/r*100),E.style.opacity=1,E.style.width=t>=95?"100%":t+"%",t>=95&&(clearTimeout(A),A=setTimeout(function(e){E.style.opacity=0,E.style.width="0%"},200))}var T={};function P(e,t,r){void 0===t&&(t=!1),void 0===r&&(r={});var i=new XMLHttpRequest,o=function(){i.addEventListener.apply(i,arguments)},s=T[e];if(s)return{then:function(e){return e(s.content,s.opt)},abort:a};i.open("GET",e);for(var l in r)n.call(r,l)&&i.setRequestHeader(l,r[l]);return i.send(),{then:function(n,r){if(void 0===r&&(r=a),t){var s=setInterval(function(e){return $({step:Math.floor(5*Math.random()+1)})},500);o("progress",$),o("loadend",function(e){$(e),clearInterval(s)})}o("error",r),o("load",function(t){var a=t.target;if(a.status>=400)r(a);else{var o=T[e]={content:a.response,opt:{updatedAt:i.getResponseHeader("last-modified")}};n(o.content,o.opt)}})},abort:function(e){return 4!==i.readyState&&i.abort()}}}function F(e,t){e.innerHTML=e.innerHTML.replace(/var\(\s*--theme-color.*?\)/g,t)}var O=/([^{]*?)\w(?=\})/g,M={YYYY:"getFullYear",YY:"getYear",MM:function(e){return e.getMonth()+1},DD:"getDate",HH:"getHours",mm:"getMinutes",ss:"getSeconds"};var N="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function j(e,t){return e(t={exports:{}},t.exports),t.exports}var q=j(function(e,t){(function(){var t={newline:/^\n+/,code:/^( {4}[^\n]+\n*)+/,fences:p,hr:/^( *[-*_]){3,} *(?:\n+|$)/,heading:/^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)/,nptable:p,lheading:/^([^\n]+)\n *(=|-){2,} *(?:\n+|$)/,blockquote:/^( *>[^\n]+(\n(?!def)[^\n]+)*\n*)+/,list:/^( *)(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,html:/^ *(?:comment *(?:\n|\s*$)|closed *(?:\n{2,}|\s*$)|closing *(?:\n{2,}|\s*$))/,def:/^ *\[([^\]]+)\]: *]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/,table:p,paragraph:/^((?:[^\n]+\n?(?!hr|heading|lheading|blockquote|tag|def))+)\n*/,text:/^[^\n]+/};t.bullet=/(?:[*+-]|\d+\.)/,t.item=/^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/,t.item=l(t.item,"gm")(/bull/g,t.bullet)(),t.list=l(t.list)(/bull/g,t.bullet)("hr","\\n+(?=\\1?(?:[-*_] *){3,}(?:\\n+|$))")("def","\\n+(?="+t.def.source+")")(),t.blockquote=l(t.blockquote)("def",t.def)(),t._tag="(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:/|[^\\w\\s@]*@)\\b",t.html=l(t.html)("comment",//)("closed",/<(tag)[\s\S]+?<\/\1>/)("closing",/])*?>/)(/tag/g,t._tag)(),t.paragraph=l(t.paragraph)("hr",t.hr)("heading",t.heading)("lheading",t.lheading)("blockquote",t.blockquote)("tag","<"+t._tag)("def",t.def)(),t.normal=d({},t),t.gfm=d({},t.normal,{fences:/^ *(`{3,}|~{3,})[ \.]*(\S+)? *\n([\s\S]*?)\s*\1 *(?:\n+|$)/,paragraph:/^/,heading:/^ *(#{1,6}) +([^\n]+?) *#* *(?:\n+|$)/}),t.gfm.paragraph=l(t.paragraph)("(?!","(?!"+t.gfm.fences.source.replace("\\1","\\2")+"|"+t.list.source.replace("\\1","\\3")+"|")(),t.tables=d({},t.gfm,{nptable:/^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*/,table:/^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*/});function n(e){this.tokens=[],this.tokens.links={},this.options=e||g.defaults,this.rules=t.normal,this.options.gfm&&(this.options.tables?this.rules=t.tables:this.rules=t.gfm)}n.rules=t,n.lex=function(e,t){return new n(t).lex(e)},n.prototype.lex=function(e){return e=e.replace(/\r\n|\r/g,"\n").replace(/\t/g," ").replace(/\u00a0/g," ").replace(/\u2424/g,"\n"),this.token(e,!0)},n.prototype.token=function(e,n,r){var i,a,o,s,l,c,u,h,p;for(e=e.replace(/^ +$/gm,"");e;)if((o=this.rules.newline.exec(e))&&(e=e.substring(o[0].length),o[0].length>1&&this.tokens.push({type:"space"})),o=this.rules.code.exec(e))e=e.substring(o[0].length),o=o[0].replace(/^ {4}/gm,""),this.tokens.push({type:"code",text:this.options.pedantic?o:o.replace(/\n+$/,"")});else if(o=this.rules.fences.exec(e))e=e.substring(o[0].length),this.tokens.push({type:"code",lang:o[2],text:o[3]||""});else if(o=this.rules.heading.exec(e))e=e.substring(o[0].length),this.tokens.push({type:"heading",depth:o[1].length,text:o[2]});else if(n&&(o=this.rules.nptable.exec(e))){for(e=e.substring(o[0].length),c={type:"table",header:o[1].replace(/^ *| *\| *$/g,"").split(/ *\| */),align:o[2].replace(/^ *|\| *$/g,"").split(/ *\| */),cells:o[3].replace(/\n$/,"").split("\n")},h=0;h ?/gm,""),this.token(o,n,!0),this.tokens.push({type:"blockquote_end"});else if(o=this.rules.list.exec(e)){for(e=e.substring(o[0].length),s=o[2],this.tokens.push({type:"list_start",ordered:s.length>1}),i=!1,p=(o=o[0].match(this.rules.item)).length,h=0;h1&&l.length>1||(e=o.slice(h+1).join("\n")+e,h=p-1)),a=i||/\n\n(?!\s*$)/.test(c),h!==p-1&&(i="\n"===c.charAt(c.length-1),a||(a=i)),this.tokens.push({type:a?"loose_item_start":"list_item_start"}),this.token(c,!1,r),this.tokens.push({type:"list_item_end"});this.tokens.push({type:"list_end"})}else if(o=this.rules.html.exec(e))e=e.substring(o[0].length),this.tokens.push({type:this.options.sanitize?"paragraph":"html",pre:!this.options.sanitizer&&("pre"===o[1]||"script"===o[1]||"style"===o[1]),text:o[0]});else if(!r&&n&&(o=this.rules.def.exec(e)))e=e.substring(o[0].length),this.tokens.links[o[1].toLowerCase()]={href:o[2],title:o[3]};else if(n&&(o=this.rules.table.exec(e))){for(e=e.substring(o[0].length),c={type:"table",header:o[1].replace(/^ *| *\| *$/g,"").split(/ *\| */),align:o[2].replace(/^ *|\| *$/g,"").split(/ *\| */),cells:o[3].replace(/(?: *\| *)?\n$/,"").split("\n")},h=0;h])/,autolink:/^<([^ <>]+(@|:\/)[^ <>]+)>/,url:p,tag:/^|^<\/?\w+(?:"[^"]*"|'[^']*'|[^<'">])*?>/,link:/^!?\[(inside)\]\(href\)/,reflink:/^!?\[(inside)\]\s*\[([^\]]*)\]/,nolink:/^!?\[((?:\[[^\]]*\]|[^\[\]])*)\]/,strong:/^__([\s\S]+?)__(?!_)|^\*\*([\s\S]+?)\*\*(?!\*)/,em:/^\b_((?:[^_]|__)+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,code:/^(`+)([\s\S]*?[^`])\1(?!`)/,br:/^ {2,}\n(?!\s*$)/,del:p,text:/^[\s\S]+?(?=[\\?(?:\s+['"]([\s\S]*?)['"])?\s*/,r.link=l(r.link)("inside",r._inside)("href",r._href)(),r.reflink=l(r.reflink)("inside",r._inside)(),r.normal=d({},r),r.pedantic=d({},r.normal,{strong:/^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,em:/^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/}),r.gfm=d({},r.normal,{escape:l(r.escape)("])","~|])")(),url:/^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/,del:/^~~(?=\S)([\s\S]*?\S)~~/,text:l(r.text)("]|","~]|")("|","|https?://|")()}),r.breaks=d({},r.gfm,{br:l(r.br)("{2,}","*")(),text:l(r.gfm.text)("{2,}","*")()});function i(e,t){if(this.options=t||g.defaults,this.links=e,this.rules=r.normal,this.renderer=this.options.renderer||new a,this.renderer.options=this.options,!this.links)throw new Error("Tokens array requires a `links` property.");this.options.gfm?this.options.breaks?this.rules=r.breaks:this.rules=r.gfm:this.options.pedantic&&(this.rules=r.pedantic)}i.rules=r,i.output=function(e,t,n){return new i(t,n).output(e)},i.prototype.output=function(e){for(var t,n,r,i,a="";e;)if(i=this.rules.escape.exec(e))e=e.substring(i[0].length),a+=i[1];else if(i=this.rules.autolink.exec(e))e=e.substring(i[0].length),"@"===i[2]?(n=s(":"===i[1].charAt(6)?this.mangle(i[1].substring(7)):this.mangle(i[1])),r=this.mangle("mailto:")+n):r=n=s(i[1]),a+=this.renderer.link(r,null,n);else if(this.inLink||!(i=this.rules.url.exec(e))){if(i=this.rules.tag.exec(e))!this.inLink&&/^/i.test(i[0])&&(this.inLink=!1),e=e.substring(i[0].length),a+=this.options.sanitize?this.options.sanitizer?this.options.sanitizer(i[0]):s(i[0]):i[0];else if(i=this.rules.link.exec(e))e=e.substring(i[0].length),this.inLink=!0,a+=this.outputLink(i,{href:i[2],title:i[3]}),this.inLink=!1;else if((i=this.rules.reflink.exec(e))||(i=this.rules.nolink.exec(e))){if(e=e.substring(i[0].length),t=(i[2]||i[1]).replace(/\s+/g," "),!(t=this.links[t.toLowerCase()])||!t.href){a+=i[0].charAt(0),e=i[0].substring(1)+e;continue}this.inLink=!0,a+=this.outputLink(i,t),this.inLink=!1}else if(i=this.rules.strong.exec(e))e=e.substring(i[0].length),a+=this.renderer.strong(this.output(i[2]||i[1]));else if(i=this.rules.em.exec(e))e=e.substring(i[0].length),a+=this.renderer.em(this.output(i[2]||i[1]));else if(i=this.rules.code.exec(e))e=e.substring(i[0].length),a+=this.renderer.codespan(s(i[2].trim(),!0));else if(i=this.rules.br.exec(e))e=e.substring(i[0].length),a+=this.renderer.br();else if(i=this.rules.del.exec(e))e=e.substring(i[0].length),a+=this.renderer.del(this.output(i[1]));else if(i=this.rules.text.exec(e))e=e.substring(i[0].length),a+=this.renderer.text(s(this.smartypants(i[0])));else if(e)throw new Error("Infinite loop on byte: "+e.charCodeAt(0))}else e=e.substring(i[0].length),r=n=s(i[1]),a+=this.renderer.link(r,null,n);return a},i.prototype.outputLink=function(e,t){var n=s(t.href),r=t.title?s(t.title):null;return"!"!==e[0].charAt(0)?this.renderer.link(n,r,this.output(e[1])):this.renderer.image(n,r,s(e[1]))},i.prototype.smartypants=function(e){return this.options.smartypants?e.replace(/---/g,"—").replace(/--/g,"–").replace(/(^|[-\u2014/(\[{"\s])'/g,"$1‘").replace(/'/g,"’").replace(/(^|[-\u2014/(\[{\u2018\s])"/g,"$1“").replace(/"/g,"”").replace(/\.{3}/g,"…"):e},i.prototype.mangle=function(e){if(!this.options.mangle)return e;for(var t,n="",r=e.length,i=0;i.5&&(t="x"+t.toString(16)),n+="&#"+t+";";return n};function a(e){this.options=e||{}}a.prototype.code=function(e,t,n){if(this.options.highlight){var r=this.options.highlight(e,t);null!=r&&r!==e&&(n=!0,e=r)}return t?'
    '+(n?e:s(e,!0))+"\n
    \n":"
    "+(n?e:s(e,!0))+"\n
    "},a.prototype.blockquote=function(e){return"
    \n"+e+"
    \n"},a.prototype.html=function(e){return e},a.prototype.heading=function(e,t,n){return"'+e+"\n"},a.prototype.hr=function(){return this.options.xhtml?"
    \n":"
    \n"},a.prototype.list=function(e,t){var n=t?"ol":"ul";return"<"+n+">\n"+e+"\n"},a.prototype.listitem=function(e){return"
  • "+e+"
  • \n"},a.prototype.paragraph=function(e){return"

    "+e+"

    \n"},a.prototype.table=function(e,t){return"\n\n"+e+"\n\n"+t+"\n
    \n"},a.prototype.tablerow=function(e){return"\n"+e+"\n"},a.prototype.tablecell=function(e,t){var n=t.header?"th":"td";return(t.align?"<"+n+' style="text-align:'+t.align+'">':"<"+n+">")+e+"\n"},a.prototype.strong=function(e){return""+e+""},a.prototype.em=function(e){return""+e+""},a.prototype.codespan=function(e){return""+e+""},a.prototype.br=function(){return this.options.xhtml?"
    ":"
    "},a.prototype.del=function(e){return""+e+""},a.prototype.link=function(e,t,n){if(this.options.sanitize){try{var r=decodeURIComponent((i=e,i.replace(/&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/gi,function(e,t){return"colon"===(t=t.toLowerCase())?":":"#"===t.charAt(0)?"x"===t.charAt(1)?String.fromCharCode(parseInt(t.substring(2),16)):String.fromCharCode(+t.substring(1)):""}))).replace(/[^\w:]/g,"").toLowerCase()}catch(e){return n}if(0===r.indexOf("javascript:")||0===r.indexOf("vbscript:")||0===r.indexOf("data:"))return n}var i;this.options.baseUrl&&!h.test(e)&&(e=c(this.options.baseUrl,e));var a='
    "},a.prototype.image=function(e,t,n){this.options.baseUrl&&!h.test(e)&&(e=c(this.options.baseUrl,e));var r=''+n+'":">"},a.prototype.text=function(e){return e};function o(e){this.tokens=[],this.token=null,this.options=e||g.defaults,this.options.renderer=this.options.renderer||new a,this.renderer=this.options.renderer,this.renderer.options=this.options}o.parse=function(e,t,n){return new o(t,n).parse(e)},o.prototype.parse=function(e){this.inline=new i(e.links,this.options,this.renderer),this.tokens=e.reverse();for(var t="";this.next();)t+=this.tok();return t},o.prototype.next=function(){return this.token=this.tokens.pop()},o.prototype.peek=function(){return this.tokens[this.tokens.length-1]||0},o.prototype.parseText=function(){for(var e=this.token.text;"text"===this.peek().type;)e+="\n"+this.next().text;return this.inline.output(e)},o.prototype.tok=function(){switch(this.token.type){case"space":return"";case"hr":return this.renderer.hr();case"heading":return this.renderer.heading(this.inline.output(this.token.text),this.token.depth,this.token.text);case"code":return this.renderer.code(this.token.text,this.token.lang,this.token.escaped);case"table":var e,t,n,r,i="",a="";for(n="",e=0;e/g,">").replace(/"/g,""").replace(/'/g,"'")}function l(e,t){return e=e.source,t=t||"",function n(r,i){return r?(i=(i=i.source||i).replace(/(^|[^\[])\^/g,"$1"),e=e.replace(r,i),n):new RegExp(e,t)}}function c(e,t){return u[" "+e]||(/^[^:]+:\/*[^/]*$/.test(e)?u[" "+e]=e+"/":u[" "+e]=e.replace(/[^/]*$/,"")),e=u[" "+e],"//"===t.slice(0,2)?e.replace(/:[\s\S]*/,":")+t:"/"===t.charAt(0)?e.replace(/(:\/*[^/]*)[\s\S]*/,"$1")+t:e+t}var u={},h=/^$|^[a-z][a-z0-9+.-]*:|^[?#]/i;function p(){}p.exec=p;function d(e){for(var t,n,r=arguments,i=1;iAn error occurred:

    "+s(e.message+"",!0)+"
    ";throw e}}g.options=g.setOptions=function(e){return d(g.defaults,e),g},g.defaults={gfm:!0,tables:!0,breaks:!1,pedantic:!1,sanitize:!1,sanitizer:null,mangle:!0,smartLists:!1,silent:!1,highlight:null,langPrefix:"lang-",smartypants:!1,headerPrefix:"",renderer:new a,xhtml:!1,baseUrl:null},g.Parser=o,g.parser=o.parse,g.Renderer=a,g.Lexer=n,g.lexer=n.lex,g.InlineLexer=i,g.inlineLexer=i.output,g.parse=g,e.exports=g}).call(function(){return this||("undefined"!=typeof window?window:N)}())}),R=j(function(e){var t="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},n=function(){var e=/\blang(?:uage)?-(\w+)\b/i,n=0,r=t.Prism={manual:t.Prism&&t.Prism.manual,disableWorkerMessageHandler:t.Prism&&t.Prism.disableWorkerMessageHandler,util:{encode:function(e){return e instanceof i?new i(e.type,r.util.encode(e.content),e.alias):"Array"===r.util.type(e)?e.map(r.util.encode):e.replace(/&/g,"&").replace(/e.length)return;if(!(w instanceof l)){p.lastIndex=0;var x=1;if(!(A=p.exec(w))&&f&&y!=t.length-1){if(p.lastIndex=k,!(A=p.exec(e)))break;for(var _=A.index+(g?A[1].length:0),S=A.index+A[0].length,C=y,L=k,E=t.length;C=(L+=t[C].length)&&(++y,k=L);if(t[y]instanceof l||t[C-1].greedy)continue;x=C-y,w=e.slice(k,L),A.index-=k}if(A){g&&(m=A[1].length);S=(_=A.index+m)+(A=A[0].slice(m)).length;var A,$=w.slice(0,_),T=w.slice(S),P=[y,x];$&&(++y,k+=$.length,P.push($));var F=new l(c,d?r.tokenize(A,d):A,v,A,f);if(P.push(F),T&&P.push(T),Array.prototype.splice.apply(t,P),1!=x&&r.matchGrammar(e,t,n,y,k,!0,c),o)break}else if(o)break}}}}},tokenize:function(e,t,n){var i=[e],a=t.rest;if(a){for(var o in a)t[o]=a[o];delete t.rest}return r.matchGrammar(e,i,t,0,0,!1),i},hooks:{all:{},add:function(e,t){var n=r.hooks.all;n[e]=n[e]||[],n[e].push(t)},run:function(e,t){var n=r.hooks.all[e];if(n&&n.length)for(var i,a=0;i=n[a++];)i(t)}}},i=r.Token=function(e,t,n,r,i){this.type=e,this.content=t,this.alias=n,this.length=0|(r||"").length,this.greedy=!!i};if(i.stringify=function(e,t,n){if("string"==typeof e)return e;if("Array"===r.util.type(e))return e.map(function(n){return i.stringify(n,t,e)}).join("");var a={type:e.type,content:i.stringify(e.content,t,n),tag:"span",classes:["token",e.type],attributes:{},language:t,parent:n};if(e.alias){var o="Array"===r.util.type(e.alias)?e.alias:[e.alias];Array.prototype.push.apply(a.classes,o)}r.hooks.run("wrap",a);var s=Object.keys(a.attributes).map(function(e){return e+'="'+(a.attributes[e]||"").replace(/"/g,""")+'"'}).join(" ");return"<"+a.tag+' class="'+a.classes.join(" ")+'"'+(s?" "+s:"")+">"+a.content+""},!t.document)return t.addEventListener?(r.disableWorkerMessageHandler||t.addEventListener("message",function(e){var n=JSON.parse(e.data),i=n.language,a=n.code,o=n.immediateClose;t.postMessage(r.highlight(a,r.languages[i],i)),o&&t.close()},!1),t.Prism):t.Prism;var a=document.currentScript||[].slice.call(document.getElementsByTagName("script")).pop();return a&&(r.filename=a.src,r.manual||a.hasAttribute("data-manual")||("loading"!==document.readyState?window.requestAnimationFrame?window.requestAnimationFrame(r.highlightAll):window.setTimeout(r.highlightAll,16):document.addEventListener("DOMContentLoaded",r.highlightAll))),t.Prism}();e.exports&&(e.exports=n),void 0!==N&&(N.Prism=n),n.languages.markup={comment://,prolog:/<\?[\s\S]+?\?>/,doctype://i,cdata://i,tag:{pattern:/<\/?(?!\d)[^\s>\/=$<]+(?:\s+[^\s>\/=]+(?:=(?:("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|[^\s'">=]+))?)*\s*\/?>/i,inside:{tag:{pattern:/^<\/?[^\s>\/]+/i,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"attr-value":{pattern:/=(?:("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|[^\s'">=]+)/i,inside:{punctuation:[/^=/,{pattern:/(^|[^\\])["']/,lookbehind:!0}]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:/&#?[\da-z]{1,8};/i},n.languages.markup.tag.inside["attr-value"].inside.entity=n.languages.markup.entity,n.hooks.add("wrap",function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&/,"&"))}),n.languages.xml=n.languages.markup,n.languages.html=n.languages.markup,n.languages.mathml=n.languages.markup,n.languages.svg=n.languages.markup,n.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-]+?.*?(?:;|(?=\s*\{))/i,inside:{rule:/@[\w-]+/}},url:/url\((?:(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1|.*?)\)/i,selector:/[^{}\s][^{};]*?(?=\s*\{)/,string:{pattern:/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},property:/[-_a-z\xA0-\uFFFF][-\w\xA0-\uFFFF]*(?=\s*:)/i,important:/\B!important\b/i,function:/[-a-z0-9]+(?=\()/i,punctuation:/[(){};:]/},n.languages.css.atrule.inside.rest=n.util.clone(n.languages.css),n.languages.markup&&(n.languages.insertBefore("markup","tag",{style:{pattern:/()[\s\S]*?(?=<\/style>)/i,lookbehind:!0,inside:n.languages.css,alias:"language-css",greedy:!0}}),n.languages.insertBefore("inside","attr-value",{"style-attr":{pattern:/\s*style=("|')(?:\\[\s\S]|(?!\1)[^\\])*\1/i,inside:{"attr-name":{pattern:/^\s*style/i,inside:n.languages.markup.tag.inside},punctuation:/^\s*=\s*['"]|['"]\s*$/,"attr-value":{pattern:/.+/i,inside:n.languages.css}},alias:"language-css"}},n.languages.markup.tag)),n.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/((?:\b(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,boolean:/\b(?:true|false)\b/,function:/[a-z0-9_]+(?=\()/i,number:/\b-?(?:0x[\da-f]+|\d*\.?\d+(?:e[+-]?\d+)?)\b/i,operator:/--?|\+\+?|!=?=?|<=?|>=?|==?=?|&&?|\|\|?|\?|\*|\/|~|\^|%/,punctuation:/[{}[\];(),.:]/},n.languages.javascript=n.languages.extend("clike",{keyword:/\b(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|var|void|while|with|yield)\b/,number:/\b-?(?:0[xX][\dA-Fa-f]+|0[bB][01]+|0[oO][0-7]+|\d*\.?\d+(?:[Ee][+-]?\d+)?|NaN|Infinity)\b/,function:/[_$a-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*\()/i,operator:/-[-=]?|\+[+=]?|!=?=?|<>?>?=?|=(?:==?|>)?|&[&=]?|\|[|=]?|\*\*?=?|\/=?|~|\^=?|%=?|\?|\.{3}/}),n.languages.insertBefore("javascript","keyword",{regex:{pattern:/(^|[^/])\/(?!\/)(\[[^\]\r\n]+]|\\.|[^/\\\[\r\n])+\/[gimyu]{0,5}(?=\s*($|[\r\n,.;})]))/,lookbehind:!0,greedy:!0},"function-variable":{pattern:/[_$a-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*=\s*(?:function\b|(?:\([^()]*\)|[_$a-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*)\s*=>))/i,alias:"function"}}),n.languages.insertBefore("javascript","string",{"template-string":{pattern:/`(?:\\[\s\S]|[^\\`])*`/,greedy:!0,inside:{interpolation:{pattern:/\$\{[^}]+\}/,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:n.languages.javascript}},string:/[\s\S]+/}}}),n.languages.markup&&n.languages.insertBefore("markup","tag",{script:{pattern:/()[\s\S]*?(?=<\/script>)/i,lookbehind:!0,inside:n.languages.javascript,alias:"language-javascript",greedy:!0}}),n.languages.js=n.languages.javascript,"undefined"!=typeof self&&self.Prism&&self.document&&document.querySelector&&(self.Prism.fileHighlight=function(){var e={js:"javascript",py:"python",rb:"ruby",ps1:"powershell",psm1:"powershell",sh:"bash",bat:"batch",h:"c",tex:"latex"};Array.prototype.slice.call(document.querySelectorAll("pre[data-src]")).forEach(function(t){for(var r,i=t.getAttribute("data-src"),a=t,o=/\blang(?:uage)?-(?!\*)(\w+)\b/i;a&&!o.test(a.className);)a=a.parentNode;if(a&&(r=(t.className.match(o)||[,""])[1]),!r){var s=(i.match(/\.(\w+)$/)||[,""])[1];r=e[s]||s}var l=document.createElement("code");l.className="language-"+r,t.textContent="",l.textContent="Loading…",t.appendChild(l);var c=new XMLHttpRequest;c.open("GET",i,!0),c.onreadystatechange=function(){4==c.readyState&&(c.status<400&&c.responseText?(l.textContent=c.responseText,n.highlightElement(l)):c.status>=400?l.textContent="✖ Error "+c.status+" while fetching file: "+c.statusText:l.textContent="✖ Error: File does not exist or is empty")},c.send(null)})},document.addEventListener("DOMContentLoaded",self.Prism.fileHighlight))});function H(e,t){var n=[],r={};return e.forEach(function(e){var i=e.level||1,a=i-1;i>t||(r[a]?r[a].children=(r[a].children||[]).concat(e):n.push(e),r[i]=e)}),n}var z={},I=/[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,./:;<=>?@[\]^`{|}~]/g;function B(e){return e.toLowerCase()}function U(e){if("string"!=typeof e)return"";var t=e.trim().replace(/[A-Z]+/g,B).replace(/<[^>\d]+>/g,"").replace(I,"").replace(/\s/g,"-").replace(/-+/g,"-").replace(/^(\d)/,"_$1"),r=z[t];return r=n.call(z,t)?r+1:0,z[t]=r,r&&(t=t+"-"+r),t}U.clear=function(){z={}};function D(e,t){return''+t+''}var Y=decodeURIComponent,W=encodeURIComponent;function G(e){var t={};return(e=e.trim().replace(/^(\?|#|&)/,""))?(e.split("&").forEach(function(e){var n=e.replace(/\+/g," ").split("=");t[n[0]]=n[1]&&Y(n[1])}),t):t}function X(e,t){void 0===t&&(t=[]);var n=[];for(var r in e)t.indexOf(r)>-1||n.push(e[r]?(W(r)+"="+W(e[r])).toLowerCase():W(r));return n.length?"?"+n.join("&"):""}var Q=e(function(e){return/(:|(\/{2}))/g.test(e)}),V=e(function(e){return/\/$/g.test(e)?e:(e=e.match(/(\S*\/)[^/]+$/))?e[1]:""}),Z=e(function(e){return e.replace(/^\/+/,"/").replace(/([^:])\/{2,}/g,"$1/")});function J(){for(var e=[],t=arguments.length;t--;)e[t]=arguments[t];return Z(e.join("/"))}var K=e(function(e){return e.replace("#","?id=")}),ee={};function te(e){void 0===e&&(e="");var t={};return e&&(e=e.replace(/:([\w-]+)=?([\w-]+)?/g,function(e,n,r){return t[n]=r&&r.replace(/"/g,"")||!0,""}).trim()),{str:e,config:t}}var ne={markdown:function(e){return{url:e}},iframe:function(e,t){return{code:'"}},video:function(e,t){return{code:'"}},audio:function(e,t){return{code:'"}},code:function(e,t){var n=e.match(/\.(\w+)$/);return"md"===(n=t||n&&n[1])&&(n="markdown"),{url:e,lang:n}}},re=function(t,n){this.config=t,this.router=n,this.cacheTree={},this.toc=[],this.linkTarget=t.externalLinkTarget||"_blank",this.contentBase=n.getBasePath();var a,s=this._initRenderer(),c=t.markdown||{};o(c)?a=c(q,s):(q.setOptions(r(c,{renderer:r(s,c.renderer)})),a=q),this._marked=a,this.compile=e(function(e){var n="";if(!e)return e;n=i(e)?a(e):a.parser(e),n=t.noEmoji?n:(r=n,r.replace(/<(pre|template|code)[^>]*?>[\s\S]+?<\/(pre|template|code)>/g,function(e){return e.replace(/:/g,"__colon__")}).replace(/:(\w+?):/gi,l&&window.emojify||D).replace(/__colon__/g,":"));var r;return U.clear(),n})};re.prototype.compileEmbed=function(e,t){var n,r=te(t),i=r.str,a=r.config;if(t=i,a.include){Q(e)||(e=J(this.contentBase,V(this.router.getCurrentPath()),e));var o;if(a.type&&(o=ne[a.type]))(n=o.call(this,e,t)).type=a.type;else{var s="code";/\.(md|markdown)/.test(e)?s="markdown":/\.html?/.test(e)?s="iframe":/\.(mp4|ogg)/.test(e)?s="video":/\.mp3/.test(e)&&(s="audio"),(n=ne[s].call(this,e,t)).type=s}return n}},re.prototype._matchNotCompileLink=function(e){for(var t=this.config.noCompileLinks||[],n=0;n
    '+e+""},a.code=e.code=function(e,t){void 0===t&&(t=""),e=e.replace(/@DOCSIFY_QM@/g,"`");return'
    '+R.highlight(e,R.languages[t]||R.languages.markup)+"
    "},a.link=e.link=function(e,r,a){void 0===r&&(r="");var o="",s=te(r),l=s.str,c=s.config;return r=l,/:|(\/{2})/.test(e)||i._matchNotCompileLink(e)||c.ignore?o+=' target="'+t+'"':(e===i.config.homepage&&(e="README"),e=n.toURL(e,null,n.getCurrentPath())),c.target&&(o+=" target="+c.target),c.disabled&&(o+=" disabled",e="javascript:void(0)"),r&&(o+=' title="'+r+'"'),'"+a+""},a.paragraph=e.paragraph=function(e){return/^!>/.test(e)?L("tip",e):/^\?>/.test(e)?L("warn",e):"

    "+e+"

    "},a.image=e.image=function(e,t,i){var a=e,o="",s=te(t);return t=s.str,s.config["no-zoom"]&&(o+=" data-no-zoom"),t&&(o+=' title="'+t+'"'),Q(e)||(a=J(r,V(n.getCurrentPath()),e)),''+i+'"};var o=/^\[([ x])\] +/;return a.listitem=e.listitem=function(e){var t=o.exec(e);return t&&(e=e.replace(o,'")),""+e+"\n"},e.origin=a,e},re.prototype.sidebar=function(e,t){var n=this.router.getCurrentPath(),r="";if(e)r=(r=this.compile(e))&&r.match(/]*>([\s\S]+)<\/ul>/g)[0];else{var i=this.cacheTree[n]||H(this.toc,t);r=C(i,"
      "),this.cacheTree[n]=i}return r},re.prototype.subSidebar=function(e){if(e){var t=this.router.getCurrentPath(),n=this.cacheTree,r=this.toc;r[0]&&r[0].ignoreAllSubs&&r.splice(0),r[0]&&1===r[0].level&&r.shift();for(var i=0;i')}this.toc=[]},re.prototype.article=function(e){return this.compile(e)},re.prototype.cover=function(e){var t=this.toc.slice(),n=this.compile(e);return this.toc=t.slice(),n};var ie=d.title;function ae(){var e=p("section.cover");if(e){var t=e.getBoundingClientRect().height;window.pageYOffset>=t||e.classList.contains("hidden")?_(g,"add","sticky"):_(g,"remove","sticky")}}function oe(e,t,n,r){var i,a=v(t=p(t),"a"),o=decodeURI(e.toURL(e.getCurrentPath()));return a.sort(function(e,t){return t.href.length-e.href.length}).forEach(function(e){var t=e.getAttribute("href"),r=n?e.parentNode:e;0!==o.indexOf(t)||i?_(r,"remove","active"):(i=e,_(r,"add","active"))}),r&&(d.title=i?i.innerText+" - "+ie:ie),i}var se=function(){function e(e,t){for(var n=0;n0&&void 0!==arguments[0]?arguments[0]:{};!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.duration=t.duration||1e3,this.ease=t.easing||this._defaultEase,this.start=t.start,this.end=t.end,this.frame=null,this.next=null,this.isRunning=!1,this.events={},this.direction=this.startthis.end&&e>=this.next}[this.direction]}},{key:"_defaultEase",value:function(e,t,n,r){return(e/=r/2)<1?n/2*e*e+t:-n/2*(--e*(e-2)-1)+t}}]),e}(),ce={},ue=!1,he=null,pe=!0,de=0;function ge(e){if(pe){for(var t,n=p(".sidebar"),r=v(".anchor"),i=m(n,".sidebar-nav"),a=m(n,"li.active"),o=document.documentElement,s=(o&&o.scrollTop||document.body.scrollTop)-de,l=0,c=r.length;ls){t||(t=u);break}t=u}if(t){var h=ce[fe(e,t.getAttribute("data-id"))];if(h&&h!==a&&(a&&a.classList.remove("active"),h.classList.add("active"),a=h,!ue&&g.classList.contains("sticky"))){var d=n.clientHeight,f=a.offsetTop+a.clientHeight+40,b=f-0=i.scrollTop&&f<=i.scrollTop+d?i.scrollTop:b?0:f-d;n.scrollTop=y}}}}function fe(e,t){return e+"?id="+t}function me(e,t){if(t){var n=m("#"+t);n&&(r=n,he&&he.stop(),pe=!1,he=new le({start:window.pageYOffset,end:r.getBoundingClientRect().top+window.pageYOffset,duration:500}).on("tick",function(e){return window.scrollTo(0,e)}).on("done",function(){pe=!0,he=null}).begin());var r,i=ce[fe(e,t)],a=m(p(".sidebar"),"li.active");a&&a.classList.remove("active"),i&&i.classList.add("active")}}var ve=d.scrollingElement||d.documentElement;var be={};function ye(e,t){var n=e.compiler,i=e.raw;void 0===i&&(i="");var a,o=e.fetch;if(a=be[i])return t(a);var s=n._marked,l=s.lexer(i),c=[],u=s.InlineLexer.rules.link,h=l.links;l.forEach(function(e,t){"paragraph"===e.type&&(e.text=e.text.replace(new RegExp(u.source,"g"),function(e,r,i,a){var o=n.compileEmbed(i,a);return o?("markdown"!==o.type&&"code"!==o.type||c.push({index:t,embed:o}),o.code):e}))});var p=0;!function e(t,n){var r=t.step;void 0===r&&(r=0);var i=t.embedTokens,a=t.compile,o=t.fetch,s=i[r];if(!s)return n({});P(s.embed.url).then(function(t){var l;t&&("markdown"===s.embed.type?l=a.lexer(t):"code"===s.embed.type&&(l=a.lexer("```"+s.embed.lang+"\n"+t.replace(/`/g,"@DOCSIFY_QM@")+"\n```\n"))),n({token:s,embedToken:l}),e({step:++r,compile:a,embedTokens:i,fetch:o},n)})}({compile:s,embedTokens:c,fetch:o},function(e){var n=e.embedToken,a=e.token;if(a){var o=a.index+p;r(h,n.links),l=l.slice(0,o).concat(n,l.slice(o+1)),p+=n.length-1}else be[i]=l.concat(),l.links=be[i].links=h,t(l)})}function ke(){var e=v(".markdown-section>script").filter(function(e){return!/template/.test(e.type)})[0];if(!e)return!1;var t=e.innerText.trim();if(!t)return!1;setTimeout(function(e){window.__EXECUTE_RESULT__=new Function(t)()},0)}function we(e,t,n){return t="function"==typeof n?n(t):"string"==typeof n?function(e){var t=[],n=0;return e.replace(O,function(r,i,a){t.push(e.substring(n,a-1)),n=a+=r.length+1,t.push(function(e){return("00"+("string"==typeof M[r]?e[M[r]]():M[r](e))).slice(-r.length)})}),n!==e.length&&t.push(e.substring(n)),function(e){for(var n="",r=0,i=e||new Date;r'):"")),t.coverpage&&(a+='
      \x3c!--cover--\x3e
      '),a+=function(e){var t='';return(c?t+"
      ":"
      "+t)+'
      \x3c!--main--\x3e
      '}(t),e._renderTo(i,a,!0)):e.rendered=!0;var s;t.mergeNavbar&&c?o=m(".sidebar"):(r.classList.add("app-nav"),t.repo||r.classList.add("no-badge")),t.loadNavbar&&k(o,r),t.themeColor&&(d.head.appendChild(b("div",(u=t.themeColor,"")).firstElementChild),function(e){if(!(window.CSS&&window.CSS.supports&&window.CSS.supports("(--v:red)"))){var t=v("style:not(.inserted),link");[].forEach.call(t,function(t){if("STYLE"===t.nodeName)F(t,e);else if("LINK"===t.nodeName){var n=t.getAttribute("href");if(!/\.css$/.test(n))return;P(n).then(function(t){var n=b("style",t);f.appendChild(n),F(n,e)})}})}}(t.themeColor));var u;e._updateRender(),_(g,"ready")}var Se={};var Ce=function(e){this.config=e};Ce.prototype.getBasePath=function(){return this.config.basePath},Ce.prototype.getFile=function(e,t){void 0===e&&(e=this.getCurrentPath());var n=this.config,r=this.getBasePath(),i="string"==typeof n.ext?n.ext:".md";e=n.alias?function e(t,n,r){var i=Object.keys(n).filter(function(e){return(Se[e]||(Se[e]=new RegExp("^"+e+"$"))).test(t)&&t!==r})[0];return i?e(t.replace(Se[i],n[i]),n,t):t}(e,n.alias):e,a=e,o=i;var a,o;return e=(e=new RegExp("\\.("+o.replace(/^\./,"")+"|html)$","g").test(a)?a:/\/$/g.test(a)?a+"README"+o:""+a+o)==="/README"+i?n.homepage||e:e,e=Q(e)?e:J(r,e),t&&(e=e.replace(new RegExp("^"+r),"")),e},Ce.prototype.onchange=function(e){void 0===e&&(e=a),e()},Ce.prototype.getCurrentPath=function(){},Ce.prototype.normalize=function(){},Ce.prototype.parse=function(){},Ce.prototype.toURL=function(e,t,n){var i=n&&"#"===e[0],a=this.parse(K(e));if(a.query=r({},a.query,t),e=(e=a.path+X(a.query)).replace(/\.md(\?)|\.md$/,"$1"),i){var o=n.indexOf("?");e=(o>0?n.substr(0,o):n)+e}return Z("/"+e)};function Le(e){var t=location.href.indexOf("#");location.replace(location.href.slice(0,t>=0?t:0)+"#"+e)}var Ee=function(e){function t(t){e.call(this,t),this.mode="hash"}return e&&(t.__proto__=e),t.prototype=Object.create(e&&e.prototype),t.prototype.constructor=t,t.prototype.getBasePath=function(){var e=window.location.pathname||"",t=this.config.basePath;return/^(\/|https?:)/g.test(t)?t:Z(e+"/"+t)},t.prototype.getCurrentPath=function(){var e=location.href,t=e.indexOf("#");return-1===t?"":e.slice(t+1)},t.prototype.onchange=function(e){void 0===e&&(e=a),w("hashchange",e)},t.prototype.normalize=function(){var e=this.getCurrentPath();if("/"===(e=K(e)).charAt(0))return Le(e);Le("/"+e)},t.prototype.parse=function(e){void 0===e&&(e=location.href);var t="",n=e.indexOf("#");n>=0&&(e=e.slice(n+1));var r=e.indexOf("?");return r>=0&&(t=e.slice(r+1),e=e.slice(0,r)),{path:e,file:this.getFile(e,!0),query:G(t)}},t.prototype.toURL=function(t,n,r){return"#"+e.prototype.toURL.call(this,t,n,r)},t}(Ce),Ae=function(e){function t(t){e.call(this,t),this.mode="history"}return e&&(t.__proto__=e),t.prototype=Object.create(e&&e.prototype),t.prototype.constructor=t,t.prototype.getCurrentPath=function(){var e=this.getBasePath(),t=window.location.pathname;return e&&0===t.indexOf(e)&&(t=t.slice(e.length)),(t||"/")+window.location.search+window.location.hash},t.prototype.onchange=function(e){void 0===e&&(e=a),w("click",function(t){var n="A"===t.target.tagName?t.target:t.target.parentNode;if("A"===n.tagName&&!/_blank/.test(n.target)){t.preventDefault();var r=n.href;window.history.pushState({key:r},"",r),e()}}),w("popstate",e)},t.prototype.parse=function(e){void 0===e&&(e=location.href);var t="",n=e.indexOf("?");n>=0&&(t=e.slice(n+1),e=e.slice(0,n));var r=J(location.origin),i=e.indexOf(r);return i>-1&&(e=e.slice(i+r.length)),{path:e,file:this.getFile(e),query:G(t)}},t}(Ce);var $e={};function Te(e){e.router.normalize(),e.route=e.router.parse(),g.setAttribute("data-page",e.route.file)}function Pe(e){!function(e){var t=function(e){return g.classList.toggle("close")};w(e=p(e),"click",function(e){e.stopPropagation(),t()}),c&&w(g,"click",function(e){return g.classList.contains("close")&&t()})}("button.sidebar-toggle",e.router),t=".sidebar",e.router,w(t=p(t),"click",function(e){var t=e.target;"A"===t.nodeName&&t.nextSibling&&t.nextSibling.classList.contains("app-sub-sidebar")&&_(t.parentNode,"collapse")});var t;e.config.coverpage?!c&&w("scroll",ae):g.classList.add("sticky")}function Fe(e,t,n,r,i,a){e=a?e:e.replace(/\/$/,""),(e=V(e))&&P(i.router.getFile(e+n)+t,!1,i.config.requestHeaders).then(r,function(a){return Fe(e,t,n,r,i)})}var Oe=Object.freeze({cached:e,hyphenate:t,hasOwn:n,merge:r,isPrimitive:i,noop:a,isFn:o,inBrowser:l,isMobile:c,supportsPushState:u,parseQuery:G,stringifyQuery:X,isAbsolutePath:Q,getParentPath:V,cleanPath:Z,getPath:J,replaceSlug:K});function Me(){this._init()}var Ne=Me.prototype;Ne._init=function(){this.config=function(){var e=r({el:"#app",repo:"",maxLevel:6,subMaxLevel:0,loadSidebar:null,loadNavbar:null,homepage:"README.md",coverpage:"",basePath:"",auto2top:!1,name:"",themeColor:"",nameLink:window.location.pathname,autoHeader:!1,executeScript:null,noEmoji:!1,ga:"",ext:".md",mergeNavbar:!1,formatUpdated:"",externalLinkTarget:"_blank",routerMode:"hash",noCompileLinks:[]},window.$docsify),a=document.currentScript||[].slice.call(document.getElementsByTagName("script")).filter(function(e){return/docsify\./.test(e.src)})[0];if(a){for(var o in e)if(n.call(e,o)){var s=a.getAttribute("data-"+t(o));i(s)&&(e[o]=""===s||s)}!0===e.loadSidebar&&(e.loadSidebar="_sidebar"+e.ext),!0===e.loadNavbar&&(e.loadNavbar="_navbar"+e.ext),!0===e.coverpage&&(e.coverpage="_coverpage"+e.ext),!0===e.repo&&(e.repo=""),!0===e.name&&(e.name="")}return window.$docsify=e,e}(),(e=this)._hooks={},e._lifecycle={},["init","mounted","beforeEach","afterEach","doneEach","ready"].forEach(function(t){var n=e._hooks[t]=[];e._lifecycle[t]=function(e){return n.push(e)}});var e;[].concat((a=this).config.plugins).forEach(function(e){return o(e)&&e(a._lifecycle,a)});var a;s(this,"init"),function(e){var t,n=e.config;t="history"===(n.routerMode||"hash")&&u?new Ae(n):new Ee(n),e.router=t,Te(e),$e=e.route,t.onchange(function(t){Te(e),e._updateRender(),$e.path!==e.route.path?(e.$fetch(),$e=e.route):e.$resetEvents()})}(this),_e(this),Pe(this),function(e){var t=e.config.loadSidebar;if(e.rendered){var n=oe(e.router,".sidebar-nav",!0,!0);t&&n&&(n.parentNode.innerHTML+=window.__SUB_SIDEBAR__),e._bindEventOnRendered(n),e.$resetEvents(),s(e,"doneEach"),s(e,"ready")}else e.$fetch(function(t){return s(e,"ready")})}(this),s(this,"mounted")};Ne.route={};(je=Ne)._renderTo=function(e,t,n){var r=p(e);r&&(r[n?"outerHTML":"innerHTML"]=t)},je._renderSidebar=function(e){var t=this.config,n=t.maxLevel,r=t.subMaxLevel,i=t.loadSidebar;this._renderTo(".sidebar-nav",this.compiler.sidebar(e,n));var a=oe(this.router,".sidebar-nav",!0,!0);i&&a?a.parentNode.innerHTML+=this.compiler.subSidebar(r)||"":this.compiler.subSidebar(),this._bindEventOnRendered(a)},je._bindEventOnRendered=function(e){var t=this.config,n=t.autoHeader,r=t.auto2top;if(function(e){var t=m(".cover.show");de=t?t.offsetHeight:0;for(var n=p(".sidebar"),r=v(n,"li"),i=0,a=r.length;i([^<]*?)

      $');if(i){if("color"===i[2])n.style.background=i[1]+(i[3]||"");else{var a=i[1];_(n,"add","has-mask"),Q(i[1])||(a=J(this.router.getBasePath(),i[1])),n.style.backgroundImage="url("+a+")",n.style.backgroundSize="cover",n.style.backgroundPosition="center center"}r=r.replace(i[0],"")}this._renderTo(".cover-main",r),ae()}else _(n,"remove","show")},je._updateRender=function(){!function(e){var t=p(".app-name-link"),n=e.config.nameLink,r=e.route.path;if(t)if(i(e.config.nameLink))t.setAttribute("href",n);else if("object"==typeof n){var a=Object.keys(n).filter(function(e){return r.indexOf(e)>-1})[0];t.setAttribute("href",n[a])}}(this)};var je;!function(e){var t,n=function(e,n,r){return t&&t.abort&&t.abort(),t=P(e,!0,r)};e._loadSideAndNav=function(e,t,n,r){var i=this;return function(){if(!n)return r();Fe(e,t,n,function(e){i._renderSidebar(e),r()},i,!0)}},e._fetch=function(e){var t=this;void 0===e&&(e=a);var r=this.route,i=r.path,o=X(r.query,["id"]),s=this.config,l=s.loadNavbar,c=s.requestHeaders,u=s.loadSidebar,h=this.router.getFile(i),p=n(h+o,0,c);this.isHTML=/\.html$/g.test(h),p.then(function(n,r){return t._renderMain(n,r,t._loadSideAndNav(i,o,u,e))},function(n){t._fetchFallbackPage(h,o,e)||t._fetch404(h,o,e)}),l&&Fe(i,o,l,function(e){return t._renderNav(e)},this,!0)},e._fetchCover=function(){var e=this,t=this.config,n=t.coverpage,r=t.requestHeaders,i=this.route.query,a=V(this.route.path);if(n){var o=null,s=this.route.path;if("string"==typeof n)"/"===s&&(o=n);else if(Array.isArray(n))o=n.indexOf(s)>-1&&"_coverpage";else{var l=n[s];o=!0===l?"_coverpage":l}var c=Boolean(o)&&this.config.onlyCover;return o?(o=this.router.getFile(a+o),this.coverIsHTML=/\.html$/g.test(o),P(o+X(i,["id"]),!1,r).then(function(t){return e._renderCover(t,c)})):this._renderCover(null,c),c}},e.$fetch=function(e){var t=this;void 0===e&&(e=a);var n=function(){s(t,"doneEach"),e()};this._fetchCover()?n():this._fetch(function(){t.$resetEvents(),n()})},e._fetchFallbackPage=function(e,t,r){var i=this;void 0===r&&(r=a);var o=this.config,s=o.requestHeaders,l=o.fallbackLanguages,c=o.loadSidebar;if(!l)return!1;var u=e.split("/")[1];if(-1===l.indexOf(u))return!1;var h=e.replace(new RegExp("^/"+u),"");return n(h+t,0,s).then(function(n,a){return i._renderMain(n,a,i._loadSideAndNav(e,t,c,r))},function(){return i._fetch404(e,t,r)}),!0},e._fetch404=function(e,t,r){var i=this;void 0===r&&(r=a);var o=this.config,s=o.loadSidebar,l=o.requestHeaders,c=o.notFoundPage,u=this._loadSideAndNav(e,t,s,r);if(c){var h=function(e,t){var n,r,i=t.notFoundPage,a="_404"+(t.ext||".md");switch(typeof i){case"boolean":r=a;break;case"string":r=i;break;case"object":r=(n=Object.keys(i).sort(function(e,t){return t.length-e.length}).find(function(t){return e.match(new RegExp("^"+t))}))&&i[n]||a}return r}(e,this.config);return n(this.router.getFile(h),0,l).then(function(e,t){return i._renderMain(e,t,u)},function(){return i._renderMain(null,{},u)}),!0}return this._renderMain(null,{},u),!1}}(Ne),Ne.$resetEvents=function(){me(this.route.path,this.route.query.id),this.config.loadNavbar&&oe(this.router,"nav")};window.Docsify={util:Oe,dom:S,get:P,slugify:U},window.DocsifyCompiler=re,window.marked=q,window.Prism=R,Me.version="4.6.10",function(e){var t=document.readyState;if("complete"===t||"interactive"===t)return setTimeout(e,0);document.addEventListener("DOMContentLoaded",e)}(function(e){return new Me})}(); diff --git a/docs/js/plugins/ga.min.js b/docs/js/plugins/ga.min.js new file mode 100644 index 0000000..500ea93 --- /dev/null +++ b/docs/js/plugins/ga.min.js @@ -0,0 +1 @@ +!function(){function n(n){!function(){var n=document.createElement("script");n.async=!0,n.src="https://www.google-analytics.com/analytics.js",document.body.appendChild(n)}(),window.ga=window.ga||function(){(window.ga.q=window.ga.q||[]).push(arguments)},window.ga.l=Number(new Date),window.ga("create",n,"auto")}function o(){window.ga||n($docsify.ga),window.ga("set","page",location.hash),window.ga("send","pageview")}$docsify.plugins=[].concat(function(n){$docsify.ga?n.beforeEach(o):console.error("[Docsify] ga is required.")},$docsify.plugins)}(); diff --git a/docs/js/plugins/search.min.js b/docs/js/plugins/search.min.js new file mode 100644 index 0000000..e4d4064 --- /dev/null +++ b/docs/js/plugins/search.min.js @@ -0,0 +1 @@ +!function(){var n,e={};function t(n){var e={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"};return String(n).replace(/[&<>"'/]/g,function(n){return e[n]})}function o(t,o){n=Docsify;var a="auto"===t.paths,i=localStorage.getItem("docsify.search.expires")l.length&&(d=l.length);var h="..."+t(l).substring(i,d).replace(e,''+n+"")+"...";s+=h}}),r)){var h={title:t(c),content:s,url:d};o.push(h)}},s=0;s\n

      '+n.title+"

      \n

      "+n.content+"

      \n\n"}),i.classList.add("show"),r.classList.add("show"),i.innerHTML=s||'

      '+a+"

      "}function r(n,e){var t=e.router.parse().query.s;Docsify.dom.style("\n.sidebar {\n padding-top: 0;\n}\n\n.search {\n margin-bottom: 20px;\n padding: 6px;\n border-bottom: 1px solid #eee;\n}\n\n.search .input-wrap {\n display: flex;\n align-items: center;\n}\n\n.search .results-panel {\n display: none;\n}\n\n.search .results-panel.show {\n display: block;\n}\n\n.search input {\n outline: none;\n border: none;\n width: 100%;\n padding: 0 7px;\n line-height: 36px;\n font-size: 14px;\n}\n\n.search input::-webkit-search-decoration,\n.search input::-webkit-search-cancel-button,\n.search input {\n -webkit-appearance: none;\n -moz-appearance: none;\n appearance: none;\n}\n.search .clear-button {\n width: 36px;\n text-align: right;\n display: none;\n}\n\n.search .clear-button.show {\n display: block;\n}\n\n.search .clear-button svg {\n transform: scale(.5);\n}\n\n.search h2 {\n font-size: 17px;\n margin: 10px 0;\n}\n\n.search a {\n text-decoration: none;\n color: inherit;\n}\n\n.search .matching-post {\n border-bottom: 1px solid #eee;\n}\n\n.search .matching-post:last-child {\n border-bottom: 0;\n}\n\n.search p {\n font-size: 14px;\n overflow: hidden;\n text-overflow: ellipsis;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n}\n\n.search p.empty {\n text-align: center;\n}"),function(n,e){void 0===e&&(e="");var t='
      \n \n
      \n \n \n \n \n \n
      \n
      \n
      \n ',o=Docsify.dom.create("div",t),a=Docsify.dom.find("aside");Docsify.dom.toggleClass(o,"search"),Docsify.dom.before(a,o)}(0,t),function(){var n,e=Docsify.dom.find("div.search"),t=Docsify.dom.find(e,"input"),o=Docsify.dom.find(e,".input-wrap");Docsify.dom.on(e,"click",function(n){return"A"!==n.target.tagName&&n.stopPropagation()}),Docsify.dom.on(t,"input",function(e){clearTimeout(n),n=setTimeout(function(n){return i(e.target.value.trim())},100)}),Docsify.dom.on(o,"click",function(n){"INPUT"!==n.target.tagName&&(t.value="",i())})}(),t&&setTimeout(function(n){return i(t)},500)}function s(n,e){!function(n,e){var t=Docsify.dom.getNode('.search input[type="search"]');if(t)if("string"==typeof n)t.placeholder=n;else{var o=Object.keys(n).filter(function(n){return e.indexOf(n)>-1})[0];t.placeholder=n[o]}}(n.placeholder,e.route.path),function(n,e){if("string"==typeof n)a=n;else{var t=Object.keys(n).filter(function(n){return e.indexOf(n)>-1})[0];a=n[t]}}(n.noData,e.route.path)}var c={placeholder:"Type to search",noData:"No Results!",paths:"auto",depth:2,maxAge:864e5};$docsify.plugins=[].concat(function(n,e){var t=Docsify.util,a=e.config.search||c;Array.isArray(a)?c.paths=a:"object"==typeof a&&(c.paths=Array.isArray(a.paths)?a.paths:"auto",c.maxAge=t.isPrimitive(a.maxAge)?a.maxAge:c.maxAge,c.placeholder=a.placeholder||c.placeholder,c.noData=a.noData||c.noData,c.depth=a.depth||c.depth);var i="auto"===c.paths;n.mounted(function(n){r(0,e),!i&&o(c,e)}),n.doneEach(function(n){s(c,e),i&&o(c,e)})},$docsify.plugins)}(); diff --git a/docs/js/plugins/template-web.js b/docs/js/plugins/template-web.js new file mode 100644 index 0000000..0e36682 --- /dev/null +++ b/docs/js/plugins/template-web.js @@ -0,0 +1,3 @@ +/*! art-template@4.12.2 for browser | https://github.com/aui/art-template */ +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.template=t():e.template=t()}(this,function(){return function(e){function t(r){if(n[r])return n[r].exports;var i=n[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,t),i.l=!0,i.exports}var n={};return t.m=e,t.c=n,t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},t.n=function(e){var n=e&&e.__esModule?function(){return e["default"]}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=6)}([function(e,t,n){(function(t){e.exports=!1;try{e.exports="[object process]"===Object.prototype.toString.call(t.process)}catch(n){}}).call(t,n(4))},function(e,t,n){"use strict";var r=n(8),i=n(3),o=n(23),s=function(e,t){t.onerror(e,t);var n=function(){return"{Template Error}"};return n.mappings=[],n.sourcesContent=[],n},a=function c(e){var t=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};"string"!=typeof e?t=e:t.source=e,t=i.$extend(t),e=t.source,!0===t.debug&&(t.cache=!1,t.minimize=!1,t.compileDebug=!0),t.compileDebug&&(t.minimize=!1),t.filename&&(t.filename=t.resolveFilename(t.filename,t));var n=t.filename,a=t.cache,u=t.caches;if(a&&n){var p=u.get(n);if(p)return p}if(!e)try{e=t.loader(n,t),t.source=e}catch(d){var l=new o({name:"CompileError",path:n,message:"template not found: "+d.message,stack:d.stack});if(t.bail)throw l;return s(l,t)}var f=void 0,h=new r(t);try{f=h.build()}catch(l){if(l=new o(l),t.bail)throw l;return s(l,t)}var m=function(e,n){try{return f(e,n)}catch(l){if(!t.compileDebug)return t.cache=!1,t.compileDebug=!0,c(t)(e,n);if(l=new o(l),t.bail)throw l;return s(l,t)()}};return m.mappings=f.mappings,m.sourcesContent=f.sourcesContent,m.toString=function(){return f.toString()},a&&n&&u.set(n,m),m};a.Compiler=r,e.exports=a},function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t["default"]=/((['"])(?:(?!\2|\\).|\\(?:\r\n|[\s\S]))*(\2)?|`(?:[^`\\$]|\\[\s\S]|\$(?!\{)|\$\{(?:[^{}]|\{[^}]*\}?)*\}?)*(`)?)|(\/\/.*)|(\/\*(?:[^*]|\*(?!\/))*(\*\/)?)|(\/(?!\*)(?:\[(?:(?![\]\\]).|\\.)*\]|(?![\/\]\\]).|\\.)+\/(?:(?!\s*(?:\b|[\u0080-\uFFFF$\\'"~({]|[+\-!](?!=)|\.?\d))|[gmiyu]{1,5}\b(?![\u0080-\uFFFF$\\]|\s*(?:[+\-*%&|^<>!=?({]|\/(?![\/*])))))|(0[xX][\da-fA-F]+|0[oO][0-7]+|0[bB][01]+|(?:\d*\.\d+|\d+\.?)(?:[eE][+-]?\d+)?)|((?!\d)(?:(?!\s)[$\w\u0080-\uFFFF]|\\u[\da-fA-F]{4}|\\u\{[\da-fA-F]+\})+)|(--|\+\+|&&|\|\||=>|\.{3}|(?:[+\-\/%&|^]|\*{1,2}|<{1,2}|>{1,3}|!=?|={1,2})=?|[?~.,:;[\](){}])|(\s+)|(^$|[\s\S])/g,t.matchToToken=function(e){var t={type:"invalid",value:e[0]};return e[1]?(t.type="string",t.closed=!(!e[3]&&!e[4])):e[5]?t.type="comment":e[6]?(t.type="comment",t.closed=!!e[7]):e[8]?t.type="regex":e[9]?t.type="number":e[10]?t.type="name":e[11]?t.type="punctuator":e[12]&&(t.type="whitespace"),t}},function(e,t,n){"use strict";function r(){this.$extend=function(e){return e=e||{},s(e,e instanceof r?e:this)}}var i=n(0),o=n(12),s=n(13),a=n(14),c=n(15),u=n(16),p=n(17),l=n(18),f=n(19),h=n(20),m=n(22),d={source:null,filename:null,rules:[f,l],escape:!0,debug:!!i&&"production"!==process.env.NODE_ENV,bail:!0,cache:!0,minimize:!0,compileDebug:!1,resolveFilename:m,include:a,htmlMinifier:h,htmlMinifierOptions:{collapseWhitespace:!0,minifyCSS:!0,minifyJS:!0,ignoreCustomFragments:[]},onerror:c,loader:p,caches:u,root:"/",extname:".art",ignore:[],imports:o};r.prototype=d,e.exports=new r},function(e,t){var n;n=function(){return this}();try{n=n||Function("return this")()||(0,eval)("this")}catch(r){"object"==typeof window&&(n=window)}e.exports=n},function(e,t){},function(e,t,n){"use strict";var r=n(7),i=n(1),o=n(24),s=function(e,t){return t instanceof Object?r({filename:e},t):i({filename:e,source:t})};s.render=r,s.compile=i,s.defaults=o,e.exports=s},function(e,t,n){"use strict";var r=n(1),i=function(e,t,n){return r(e,n)(t)};e.exports=i},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var i=n(9),o=n(11),s="$data",a="$imports",c="print",u="include",p="extend",l="block",f="$$out",h="$$line",m="$$blocks",d="$$slice",v="$$from",g="$$options",y=function(e,t){return Object.hasOwnProperty.call(e,t)},b=JSON.stringify,x=function(){function e(t){var n,i,y=this;r(this,e);var b=t.source,x=t.minimize,w=t.htmlMinifier;if(this.options=t,this.stacks=[],this.context=[],this.scripts=[],this.CONTEXT_MAP={},this.ignore=[s,a,g].concat(t.ignore),this.internal=(n={},n[f]="''",n[h]="[0,0]",n[m]="arguments[1]||{}",n[v]="null",n[c]="function(){var s=''.concat.apply('',arguments);"+f+"+=s;return s}",n[u]="function(src,data){var s="+g+".include(src,data||"+s+",arguments[2]||"+m+","+g+");"+f+"+=s;return s}",n[p]="function(from){"+v+"=from}",n[d]="function(c,p,s){p="+f+";"+f+"='';c();s="+f+";"+f+"=p+s;return s}",n[l]="function(){var a=arguments,s;if(typeof a[0]==='function'){return "+d+"(a[0])}else if("+v+"){if(!"+m+"[a[0]]){"+m+"[a[0]]="+d+"(a[1])}else{"+f+"+="+m+"[a[0]]}}else{s="+m+"[a[0]];if(typeof s==='string'){"+f+"+=s}else{s="+d+"(a[1])}return s}}",n),this.dependencies=(i={},i[c]=[f],i[u]=[f,g,s,m],i[p]=[v,u],i[l]=[d,v,f,m],i),this.importContext(f),t.compileDebug&&this.importContext(h),x)try{b=w(b,t)}catch(E){}this.source=b,this.getTplTokens(b,t.rules,this).forEach(function(e){e.type===o.TYPE_STRING?y.parseString(e):y.parseExpression(e)})}return e.prototype.getTplTokens=function(){return o.apply(undefined,arguments)},e.prototype.getEsTokens=function(e){return i(e)},e.prototype.getVariables=function(e){var t=!1;return e.filter(function(e){return"whitespace"!==e.type&&"comment"!==e.type}).filter(function(e){return"name"===e.type&&!t||(t="punctuator"===e.type&&"."===e.value,!1)}).map(function(e){return e.value})},e.prototype.importContext=function(e){var t=this,n="",r=this.internal,i=this.dependencies,o=this.ignore,c=this.context,u=this.options,p=u.imports,l=this.CONTEXT_MAP;y(l,e)||-1!==o.indexOf(e)||(y(r,e)?(n=r[e],y(i,e)&&i[e].forEach(function(e){return t.importContext(e)})):n="$escape"===e||"$each"===e||y(p,e)?a+"."+e:s+"."+e,l[e]=n,c.push({name:e,value:n}))},e.prototype.parseString=function(e){var t=e.value;if(t){var n=f+"+="+b(t);this.scripts.push({source:t,tplToken:e,code:n})}},e.prototype.parseExpression=function(e){var t=this,n=e.value,r=e.script,i=r.output,s=this.options.escape,a=r.code;i&&(a=!1===s||i===o.TYPE_RAW?f+"+="+r.code:f+"+=$escape("+r.code+")");var c=this.getEsTokens(a);this.getVariables(c).forEach(function(e){return t.importContext(e)}),this.scripts.push({source:n,tplToken:e,code:a})},e.prototype.checkExpression=function(e){for(var t=[[/^\s*}[\w\W]*?{?[\s;]*$/,""],[/(^[\w\W]*?\([\w\W]*?(?:=>|\([\w\W]*?\))\s*{[\s;]*$)/,"$1})"],[/(^[\w\W]*?\([\w\W]*?\)\s*{[\s;]*$)/,"$1}"]],n=0;n2&&arguments[2]!==undefined?arguments[2]:{},i=[{type:"string",value:e,line:0,start:0,end:e.length}],o=0;o]/;s.$escape=function(e){return i(r(e))},s.$each=function(e,t){if(Array.isArray(e))for(var n=0,r=e.length;n {{"+n+"}}")};switch("#"===t&&h("#value","@value"),f){case"set":i="var "+c.join("").trim();break;case"if":i="if("+c.join("").trim()+"){";break;case"else":var m=c.indexOf("if");~m?(c.splice(0,m+1),i="}else if("+c.join("").trim()+"){"):i="}else{";break;case"/if":i="}";break;case"each":p=r._split(a),p.shift(),"as"===p[1]&&(h("each object as value index","each object value index"),p.splice(1,1));i="$each("+(p[0]||"$data")+",function("+(p[1]||"$value")+","+(p[2]||"$index")+"){";break;case"/each":i="})";break;case"block":p=r._split(a),p.shift(),i="block("+p.join(",").trim()+",function(){";break;case"/block":i="})";break;case"echo":f="print",h("echo value","value");case"print":case"include":case"extend":if(0!==c.join("").trim().indexOf("(")){p=r._split(a),p.shift(),i=f+"("+p.join(",")+")";break}default:if(~c.indexOf("|")){var d=a.reduce(function(e,t){var n=t.value,r=t.type;return"|"===n?e.push([]):"whitespace"!==r&&"comment"!==r&&(e.length||e.push([]),":"===n&&1===e[e.length-1].length?h("value | filter: argv","value | filter argv"):e[e.length-1].push(t)),e},[]).map(function(e){return r._split(e)});i=d.reduce(function(e,t){var n=t.shift();return t.unshift(e),"$imports."+n+"("+t.join(",")+")"},d.shift().join(" ").trim())}l=l||"escape"}return u.code=i,u.output=l,u},_split:function(e){e=e.filter(function(e){var t=e.type;return"whitespace"!==t&&"comment"!==t});for(var t=0,n=e.shift(),r=/\]|\)/,i=[[n]];t/,use:function(e,t,n,r){return n={"-":"raw","=":"escape","":!1,"==":"raw","=#":"raw"}[n],t&&(r="/*"+r+"*/",n=!1),{code:r,output:n}}};e.exports=r},function(e,t,n){"use strict";var r=n(0),i=function(e,t){if(r){var i,o=n(21).minify,s=t.htmlMinifierOptions,a=t.rules.map(function(e){return e.test});(i=s.ignoreCustomFragments).push.apply(i,a),e=o(e,s)}return e};e.exports=i},function(e,t){!function(e){e.noop=function(){}}("object"==typeof e&&"object"==typeof e.exports?e.exports:window)},function(e,t,n){"use strict";var r=n(0),i=/^\.+\//,o=function(e,t){if(r){var o=n(5),s=t.root,a=t.extname;if(i.test(e)){var c=t.filename,u=!c||e===c,p=u?s:o.dirname(c);e=o.resolve(p,e)}else e=o.resolve(s,e);o.extname(e)||(e+=a)}return e};e.exports=o},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function i(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function o(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}function s(e){var t=e.name,n=e.source,r=e.path,i=e.line,o=e.column,s=e.generated,a=e.message;if(!n)return a;var c=n.split(/\n/),u=Math.max(i-3,0),p=Math.min(c.length,i+3),l=c.slice(u,p).map(function(e,t){var n=t+u+1;return(n===i?" >> ":" ")+n+"| "+e}).join("\n");return(r||"anonymous")+":"+i+":"+o+"\n"+l+"\n\n"+t+": "+a+(s?"\n generated: "+s:"")}var a=function(e){function t(n){r(this,t);var o=i(this,e.call(this,n.message));return o.name="TemplateError",o.message=s(n),Error.captureStackTrace&&Error.captureStackTrace(o,o.constructor),o}return o(t,e),t}(Error);e.exports=a},function(e,t,n){"use strict";e.exports=n(3)}])}); \ No newline at end of file diff --git a/docs/js/prism/prism-bash.min.js b/docs/js/prism/prism-bash.min.js new file mode 100644 index 0000000..46332cb --- /dev/null +++ b/docs/js/prism/prism-bash.min.js @@ -0,0 +1 @@ +!function(e){var t={variable:[{pattern:/\$?\(\([\s\S]+?\)\)/,inside:{variable:[{pattern:/(^\$\(\([\s\S]+)\)\)/,lookbehind:!0},/^\$\(\(/],number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+\.?\d*|\B\.\d+)(?:[Ee]-?\d+)?/,operator:/--?|-=|\+\+?|\+=|!=?|~|\*\*?|\*=|\/=?|%=?|<<=?|>>=?|<=?|>=?|==?|&&?|&=|\^=?|\|\|?|\|=|\?|:/,punctuation:/\(\(?|\)\)?|,|;/}},{pattern:/\$\([^)]+\)|`[^`]+`/,greedy:!0,inside:{variable:/^\$\(|^`|\)$|`$/}},/\$(?:[\w#?*!@]+|\{[^}]+\})/i]};e.languages.bash={shebang:{pattern:/^#!\s*\/bin\/bash|^#!\s*\/bin\/sh/,alias:"important"},comment:{pattern:/(^|[^"{\\])#.*/,lookbehind:!0},string:[{pattern:/((?:^|[^<])<<\s*)["']?(\w+?)["']?\s*\r?\n(?:[\s\S])*?\r?\n\2/,lookbehind:!0,greedy:!0,inside:t},{pattern:/(["'])(?:\\[\s\S]|\$\([^)]+\)|`[^`]+`|(?!\1)[^\\])*\1/,greedy:!0,inside:t}],variable:t.variable,"function":{pattern:/(^|[\s;|&])(?:alias|apropos|apt-get|aptitude|aspell|awk|basename|bash|bc|bg|builtin|bzip2|cal|cat|cd|cfdisk|chgrp|chmod|chown|chroot|chkconfig|cksum|clear|cmp|comm|command|cp|cron|crontab|csplit|curl|cut|date|dc|dd|ddrescue|df|diff|diff3|dig|dir|dircolors|dirname|dirs|dmesg|du|egrep|eject|enable|env|ethtool|eval|exec|expand|expect|export|expr|fdformat|fdisk|fg|fgrep|file|find|fmt|fold|format|free|fsck|ftp|fuser|gawk|getopts|git|grep|groupadd|groupdel|groupmod|groups|gzip|hash|head|help|hg|history|hostname|htop|iconv|id|ifconfig|ifdown|ifup|import|install|jobs|join|kill|killall|less|link|ln|locate|logname|logout|look|lpc|lpr|lprint|lprintd|lprintq|lprm|ls|lsof|make|man|mkdir|mkfifo|mkisofs|mknod|more|most|mount|mtools|mtr|mv|mmv|nano|netstat|nice|nl|nohup|notify-send|npm|nslookup|open|op|passwd|paste|pathchk|ping|pkill|popd|pr|printcap|printenv|printf|ps|pushd|pv|pwd|quota|quotacheck|quotactl|ram|rar|rcp|read|readarray|readonly|reboot|rename|renice|remsync|rev|rm|rmdir|rsync|screen|scp|sdiff|sed|seq|service|sftp|shift|shopt|shutdown|sleep|slocate|sort|source|split|ssh|stat|strace|su|sudo|sum|suspend|sync|tail|tar|tee|test|time|timeout|times|touch|top|traceroute|trap|tr|tsort|tty|type|ulimit|umask|umount|unalias|uname|unexpand|uniq|units|unrar|unshar|uptime|useradd|userdel|usermod|users|uuencode|uudecode|v|vdir|vi|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yes|zip)(?=$|[\s;|&])/,lookbehind:!0},keyword:{pattern:/(^|[\s;|&])(?:let|:|\.|if|then|else|elif|fi|for|break|continue|while|in|case|function|select|do|done|until|echo|exit|return|set|declare)(?=$|[\s;|&])/,lookbehind:!0},"boolean":{pattern:/(^|[\s;|&])(?:true|false)(?=$|[\s;|&])/,lookbehind:!0},operator:/&&?|\|\|?|==?|!=?|<<>|<=?|>=?|=~/,punctuation:/\$?\(\(?|\)\)?|\.\.|[{}[\];]/};var a=t.variable[1].inside;a.string=e.languages.bash.string,a["function"]=e.languages.bash["function"],a.keyword=e.languages.bash.keyword,a.boolean=e.languages.bash.boolean,a.operator=e.languages.bash.operator,a.punctuation=e.languages.bash.punctuation,e.languages.shell=e.languages.bash}(Prism); \ No newline at end of file diff --git a/docs/js/prism/prism-markdown.min.js b/docs/js/prism/prism-markdown.min.js new file mode 100644 index 0000000..012565b --- /dev/null +++ b/docs/js/prism/prism-markdown.min.js @@ -0,0 +1 @@ +Prism.languages.markdown=Prism.languages.extend("markup",{}),Prism.languages.insertBefore("markdown","prolog",{blockquote:{pattern:/^>(?:[\t ]*>)*/m,alias:"punctuation"},code:[{pattern:/^(?: {4}|\t).+/m,alias:"keyword"},{pattern:/``.+?``|`[^`\n]+`/,alias:"keyword"}],title:[{pattern:/\w+.*(?:\r?\n|\r)(?:==+|--+)/,alias:"important",inside:{punctuation:/==+$|--+$/}},{pattern:/(^\s*)#+.+/m,lookbehind:!0,alias:"important",inside:{punctuation:/^#+|#+$/}}],hr:{pattern:/(^\s*)([*-])(?:[\t ]*\2){2,}(?=\s*$)/m,lookbehind:!0,alias:"punctuation"},list:{pattern:/(^\s*)(?:[*+-]|\d+\.)(?=[\t ].)/m,lookbehind:!0,alias:"punctuation"},"url-reference":{pattern:/!?\[[^\]]+\]:[\t ]+(?:\S+|<(?:\\.|[^>\\])+>)(?:[\t ]+(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\)))?/,inside:{variable:{pattern:/^(!?\[)[^\]]+/,lookbehind:!0},string:/(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\))$/,punctuation:/^[\[\]!:]|[<>]/},alias:"url"},bold:{pattern:/(^|[^\\])(\*\*|__)(?:(?:\r?\n|\r)(?!\r?\n|\r)|.)+?\2/,lookbehind:!0,inside:{punctuation:/^\*\*|^__|\*\*$|__$/}},italic:{pattern:/(^|[^\\])([*_])(?:(?:\r?\n|\r)(?!\r?\n|\r)|.)+?\2/,lookbehind:!0,inside:{punctuation:/^[*_]|[*_]$/}},url:{pattern:/!?\[[^\]]+\](?:\([^\s)]+(?:[\t ]+"(?:\\.|[^"\\])*")?\)| ?\[[^\]\n]*\])/,inside:{variable:{pattern:/(!?\[)[^\]]+(?=\]$)/,lookbehind:!0},string:{pattern:/"(?:\\.|[^"\\])*"(?=\)$)/}}}}),Prism.languages.markdown.bold.inside.url=Prism.languages.markdown.url,Prism.languages.markdown.italic.inside.url=Prism.languages.markdown.url,Prism.languages.markdown.bold.inside.italic=Prism.languages.markdown.italic,Prism.languages.markdown.italic.inside.bold=Prism.languages.markdown.bold; \ No newline at end of file diff --git a/docs/js/prism/prism-nginx.min.js b/docs/js/prism/prism-nginx.min.js new file mode 100644 index 0000000..134bfbd --- /dev/null +++ b/docs/js/prism/prism-nginx.min.js @@ -0,0 +1 @@ +Prism.languages.nginx=Prism.languages.extend("clike",{comment:{pattern:/(^|[^"{\\])#.*/,lookbehind:!0},keyword:/\b(?:CONTENT_|DOCUMENT_|GATEWAY_|HTTP_|HTTPS|if_not_empty|PATH_|QUERY_|REDIRECT_|REMOTE_|REQUEST_|SCGI|SCRIPT_|SERVER_|http|events|accept_mutex|accept_mutex_delay|access_log|add_after_body|add_before_body|add_header|addition_types|aio|alias|allow|ancient_browser|ancient_browser_value|auth|auth_basic|auth_basic_user_file|auth_http|auth_http_header|auth_http_timeout|autoindex|autoindex_exact_size|autoindex_localtime|break|charset|charset_map|charset_types|chunked_transfer_encoding|client_body_buffer_size|client_body_in_file_only|client_body_in_single_buffer|client_body_temp_path|client_body_timeout|client_header_buffer_size|client_header_timeout|client_max_body_size|connection_pool_size|create_full_put_path|daemon|dav_access|dav_methods|debug_connection|debug_points|default_type|deny|devpoll_changes|devpoll_events|directio|directio_alignment|disable_symlinks|empty_gif|env|epoll_events|error_log|error_page|expires|fastcgi_buffer_size|fastcgi_buffers|fastcgi_busy_buffers_size|fastcgi_cache|fastcgi_cache_bypass|fastcgi_cache_key|fastcgi_cache_lock|fastcgi_cache_lock_timeout|fastcgi_cache_methods|fastcgi_cache_min_uses|fastcgi_cache_path|fastcgi_cache_purge|fastcgi_cache_use_stale|fastcgi_cache_valid|fastcgi_connect_timeout|fastcgi_hide_header|fastcgi_ignore_client_abort|fastcgi_ignore_headers|fastcgi_index|fastcgi_intercept_errors|fastcgi_keep_conn|fastcgi_max_temp_file_size|fastcgi_next_upstream|fastcgi_no_cache|fastcgi_param|fastcgi_pass|fastcgi_pass_header|fastcgi_read_timeout|fastcgi_redirect_errors|fastcgi_send_timeout|fastcgi_split_path_info|fastcgi_store|fastcgi_store_access|fastcgi_temp_file_write_size|fastcgi_temp_path|flv|geo|geoip_city|geoip_country|google_perftools_profiles|gzip|gzip_buffers|gzip_comp_level|gzip_disable|gzip_http_version|gzip_min_length|gzip_proxied|gzip_static|gzip_types|gzip_vary|if|if_modified_since|ignore_invalid_headers|image_filter|image_filter_buffer|image_filter_jpeg_quality|image_filter_sharpen|image_filter_transparency|imap_capabilities|imap_client_buffer|include|index|internal|ip_hash|keepalive|keepalive_disable|keepalive_requests|keepalive_timeout|kqueue_changes|kqueue_events|large_client_header_buffers|limit_conn|limit_conn_log_level|limit_conn_zone|limit_except|limit_rate|limit_rate_after|limit_req|limit_req_log_level|limit_req_zone|limit_zone|lingering_close|lingering_time|lingering_timeout|listen|location|lock_file|log_format|log_format_combined|log_not_found|log_subrequest|map|map_hash_bucket_size|map_hash_max_size|master_process|max_ranges|memcached_buffer_size|memcached_connect_timeout|memcached_next_upstream|memcached_pass|memcached_read_timeout|memcached_send_timeout|merge_slashes|min_delete_depth|modern_browser|modern_browser_value|mp4|mp4_buffer_size|mp4_max_buffer_size|msie_padding|msie_refresh|multi_accept|open_file_cache|open_file_cache_errors|open_file_cache_min_uses|open_file_cache_valid|open_log_file_cache|optimize_server_names|override_charset|pcre_jit|perl|perl_modules|perl_require|perl_set|pid|pop3_auth|pop3_capabilities|port_in_redirect|post_action|postpone_output|protocol|proxy|proxy_buffer|proxy_buffer_size|proxy_buffering|proxy_buffers|proxy_busy_buffers_size|proxy_cache|proxy_cache_bypass|proxy_cache_key|proxy_cache_lock|proxy_cache_lock_timeout|proxy_cache_methods|proxy_cache_min_uses|proxy_cache_path|proxy_cache_use_stale|proxy_cache_valid|proxy_connect_timeout|proxy_cookie_domain|proxy_cookie_path|proxy_headers_hash_bucket_size|proxy_headers_hash_max_size|proxy_hide_header|proxy_http_version|proxy_ignore_client_abort|proxy_ignore_headers|proxy_intercept_errors|proxy_max_temp_file_size|proxy_method|proxy_next_upstream|proxy_no_cache|proxy_pass|proxy_pass_error_message|proxy_pass_header|proxy_pass_request_body|proxy_pass_request_headers|proxy_read_timeout|proxy_redirect|proxy_redirect_errors|proxy_send_lowat|proxy_send_timeout|proxy_set_body|proxy_set_header|proxy_ssl_session_reuse|proxy_store|proxy_store_access|proxy_temp_file_write_size|proxy_temp_path|proxy_timeout|proxy_upstream_fail_timeout|proxy_upstream_max_fails|random_index|read_ahead|real_ip_header|recursive_error_pages|request_pool_size|reset_timedout_connection|resolver|resolver_timeout|return|rewrite|root|rtsig_overflow_events|rtsig_overflow_test|rtsig_overflow_threshold|rtsig_signo|satisfy|satisfy_any|secure_link_secret|send_lowat|send_timeout|sendfile|sendfile_max_chunk|server|server_name|server_name_in_redirect|server_names_hash_bucket_size|server_names_hash_max_size|server_tokens|set|set_real_ip_from|smtp_auth|smtp_capabilities|so_keepalive|source_charset|split_clients|ssi|ssi_silent_errors|ssi_types|ssi_value_length|ssl|ssl_certificate|ssl_certificate_key|ssl_ciphers|ssl_client_certificate|ssl_crl|ssl_dhparam|ssl_engine|ssl_prefer_server_ciphers|ssl_protocols|ssl_session_cache|ssl_session_timeout|ssl_verify_client|ssl_verify_depth|starttls|stub_status|sub_filter|sub_filter_once|sub_filter_types|tcp_nodelay|tcp_nopush|timeout|timer_resolution|try_files|types|types_hash_bucket_size|types_hash_max_size|underscores_in_headers|uninitialized_variable_warn|upstream|use|user|userid|userid_domain|userid_expires|userid_name|userid_p3p|userid_path|userid_service|valid_referers|variables_hash_bucket_size|variables_hash_max_size|worker_connections|worker_cpu_affinity|worker_priority|worker_processes|worker_rlimit_core|worker_rlimit_nofile|worker_rlimit_sigpending|working_directory|xclient|xml_entities|xslt_entities|xslt_stylesheet|xslt_types)\b/i}),Prism.languages.insertBefore("nginx","keyword",{variable:/\$[a-z_]+/i}); \ No newline at end of file diff --git a/docs/norm/css.md b/docs/norm/css.md new file mode 100644 index 0000000..9236ce9 --- /dev/null +++ b/docs/norm/css.md @@ -0,0 +1,116 @@ +# 切图规范 + +> 开发者可以跳过 切图制作流程. + +BUI有独特的自适应规范,这个规范跟正常的web切图流程一致, 唯一需要注意的就是单位的转换, BUI的制作是基于rem缩放, 无需关注viewport或scale, 在bui里面, 基于540px设计稿量取大小, 1rem = 100px; 这样做出来的应用,能保持在各种系统,各种浏览器,保持跟设计稿一致的效果. + +## 按源稿大小切图 +1. 打开PSD源稿 +2. 选中图片,导出为PNG格式, ( 这里用到一个 cutterman PS插件; +2. 把图片放到BUI开发包的 `images` 目录下; +>images目录里面可以自行规划,例如:icons,banner等; + +**演示:** +![切图](http://www.easybui.com/docs/images/cutimage_low.gif) + +## 转换设计稿大小 +> BUI独创的基于REM适配手机,保持跟原生DPI一致的缩放效果, 需要把设计稿转换为540的设计稿,这样量取到的值,直接除以100,便是rem值. + + +5.2.1. 把设计稿更改为`540px`宽度,高度等比缩放的设计稿 + +![修改设计稿为540宽度](http://www.easybui.com/docs/images/modify540.png) + +5.2.2. 量取设计稿内容的大小/100, 转成rem单位 +![转换尺寸为rem单位](http://www.easybui.com/docs/images/getSlideHeight.png) + +>**说明:** +如果希望slide的高度随着移动设备的不同比例缩放,需要转换成rem单位, 比方,你量取到的宽度是`540px`,高度是`270px`的焦点图, 那么写成 `2.7rem = 270px/100` ; 这样页面的slide,就会根据手机的分辨率不同,自动更改为等比的焦点图. +``` +.slide { width:100%;height:2.7rem; } +``` +---- +**如果写成`270px` 会有什么问题呢? ** +答: 如果是写成`270px` 那么页面的高度就剩下不多(iphone4 高度`480px`,iphone5 高度`568px`),最终做出来的页面,跟设计稿会有比较大的误差.而设置成`2.7rem`以后,就会随着不同DPI而转换成等比的高度; 换句话说,设计搞放到手机上是什么样子,做出来就是什么样子, 精确还原. + +---- +**那么是不是所有的 px 都需要这样转换呢? ** +答: `1px` 不需要转换,直接就写`1px`; + +## 编写结构 + +**BUI 标准的页面结构** +``` +
      +
      + +
      +
      + +
      +
      + +
      +
      +``` +> **标准结构说明:** BUI的页面分为上中下结构,中间main是主要内容的容器(唯一).BUI会去计算main的容器高度,除去header,footer以后的高度,所以如果你有内容要放底部,就放footer里面. + +## 布局 +BUI的布局简单强大,学会则没有布不了的局. + +弹性布局 (点击看更多示例) + +``` +// 弹性等分布局: span1容器放内容或控件,如果还有span1 则是1/3 大小... +
      +
      + 1/2大小 +
      +
      + 1/2大小 +
      +
      + +// 弹性自适应布局: span1容器的宽度 = 页面宽度 - 100 +
      +
      +
      + // 自适应内容 +
      +
      +``` + +流式布局 (点击看更多示例) + +``` +// 流式等分布局: 6+6 = 12 = 一行, 最大也就span12 +
      +
      + 1/2大小 +
      +
      + 1/2大小 +
      +
      +// 自由比例: 3+3+4+2 = 12 = 一行, 最大也就span12 +
      +
      +
      +
      +
      +
      +``` + +流式等列布局 (点击看更多示例) + +``` +// 流式等列布局: +
        +
      • + 1/2大小 +
      • +
      • + 1/2大小 +
      • +
      +``` \ No newline at end of file diff --git a/docs/norm/cutimage.md b/docs/norm/cutimage.md new file mode 100644 index 0000000..9236ce9 --- /dev/null +++ b/docs/norm/cutimage.md @@ -0,0 +1,116 @@ +# 切图规范 + +> 开发者可以跳过 切图制作流程. + +BUI有独特的自适应规范,这个规范跟正常的web切图流程一致, 唯一需要注意的就是单位的转换, BUI的制作是基于rem缩放, 无需关注viewport或scale, 在bui里面, 基于540px设计稿量取大小, 1rem = 100px; 这样做出来的应用,能保持在各种系统,各种浏览器,保持跟设计稿一致的效果. + +## 按源稿大小切图 +1. 打开PSD源稿 +2. 选中图片,导出为PNG格式, ( 这里用到一个 cutterman PS插件; +2. 把图片放到BUI开发包的 `images` 目录下; +>images目录里面可以自行规划,例如:icons,banner等; + +**演示:** +![切图](http://www.easybui.com/docs/images/cutimage_low.gif) + +## 转换设计稿大小 +> BUI独创的基于REM适配手机,保持跟原生DPI一致的缩放效果, 需要把设计稿转换为540的设计稿,这样量取到的值,直接除以100,便是rem值. + + +5.2.1. 把设计稿更改为`540px`宽度,高度等比缩放的设计稿 + +![修改设计稿为540宽度](http://www.easybui.com/docs/images/modify540.png) + +5.2.2. 量取设计稿内容的大小/100, 转成rem单位 +![转换尺寸为rem单位](http://www.easybui.com/docs/images/getSlideHeight.png) + +>**说明:** +如果希望slide的高度随着移动设备的不同比例缩放,需要转换成rem单位, 比方,你量取到的宽度是`540px`,高度是`270px`的焦点图, 那么写成 `2.7rem = 270px/100` ; 这样页面的slide,就会根据手机的分辨率不同,自动更改为等比的焦点图. +``` +.slide { width:100%;height:2.7rem; } +``` +---- +**如果写成`270px` 会有什么问题呢? ** +答: 如果是写成`270px` 那么页面的高度就剩下不多(iphone4 高度`480px`,iphone5 高度`568px`),最终做出来的页面,跟设计稿会有比较大的误差.而设置成`2.7rem`以后,就会随着不同DPI而转换成等比的高度; 换句话说,设计搞放到手机上是什么样子,做出来就是什么样子, 精确还原. + +---- +**那么是不是所有的 px 都需要这样转换呢? ** +答: `1px` 不需要转换,直接就写`1px`; + +## 编写结构 + +**BUI 标准的页面结构** +``` +
      +
      + +
      +
      + +
      +
      + +
      +
      +``` +> **标准结构说明:** BUI的页面分为上中下结构,中间main是主要内容的容器(唯一).BUI会去计算main的容器高度,除去header,footer以后的高度,所以如果你有内容要放底部,就放footer里面. + +## 布局 +BUI的布局简单强大,学会则没有布不了的局. + +弹性布局 (点击看更多示例) + +``` +// 弹性等分布局: span1容器放内容或控件,如果还有span1 则是1/3 大小... +
      +
      + 1/2大小 +
      +
      + 1/2大小 +
      +
      + +// 弹性自适应布局: span1容器的宽度 = 页面宽度 - 100 +
      +
      +
      + // 自适应内容 +
      +
      +``` + +流式布局 (点击看更多示例) + +``` +// 流式等分布局: 6+6 = 12 = 一行, 最大也就span12 +
      +
      + 1/2大小 +
      +
      + 1/2大小 +
      +
      +// 自由比例: 3+3+4+2 = 12 = 一行, 最大也就span12 +
      +
      +
      +
      +
      +
      +``` + +流式等列布局 (点击看更多示例) + +``` +// 流式等列布局: +
        +
      • + 1/2大小 +
      • +
      • + 1/2大小 +
      • +
      +``` \ No newline at end of file diff --git a/docs/ui/cutimage.md b/docs/ui/cutimage.md new file mode 100644 index 0000000..d492d78 --- /dev/null +++ b/docs/ui/cutimage.md @@ -0,0 +1,42 @@ +# 切图规范 + +## 切图制作流程 + +?> BUI有独特的自适应规范,这个规范跟正常的web切图流程一致, 唯一需要注意的就是单位的转换, BUI的制作是基于rem缩放, 无需关注viewport或scale, 在bui里面, 基于540px设计稿量取大小, 1rem = 100px; 这样做出来的应用,能保持在各种系统,各种浏览器,保持跟设计稿一致的效果. + +## 按源稿大小切图 +1. 打开PSD源稿 +2. 选中图片,导出为PNG格式, ( 这里用到一个 cutterman PS插件; +2. 把图片放到BUI开发包的 `images` 目录下; +?>images目录里面可以自行规划,例如:icons,banner等; + +**演示:** +![切图](http://www.easybui.com/docs/images/cutimage_low.gif) + +## 转换设计稿大小 +> BUI独创的基于REM适配手机,保持跟原生DPI一致的缩放效果, 需要把设计稿转换为540的设计稿,这样量取到的值,直接除以100,便是rem值. + + +### 把设计稿更改为`540px`宽度,高度等比缩放的设计稿 + +![修改设计稿为540宽度](http://www.easybui.com/docs/images/modify540.png) + +### 量取设计稿内容的大小/100, 转成rem单位 +![转换尺寸为rem单位](http://www.easybui.com/docs/images/getSlideHeight.png) + +*说明:* + +?>如果希望slide的高度随着移动设备的不同比例缩放,需要转换成rem单位, 比方,你量取到的宽度是`540px`,高度是`270px`的焦点图, 那么写成 `2.7rem = 270px/100` ; 这样页面的slide,就会根据手机的分辨率不同,自动更改为等比的焦点图. +```css +.slide { width:100%;height:2.7rem; } +``` +---- + +?> **如果写成`270px` 会有什么问题呢? ** + +答: 如果是写成`270px` 那么页面的高度就剩下不多(iphone4 高度`480px`,iphone5 高度`568px`),最终做出来的页面,跟设计稿会有比较大的误差.而设置成`2.7rem`以后,就会随着不同DPI而转换成等比的高度; 换句话说,设计搞放到手机上是什么样子,做出来就是什么样子, 精确还原. + +---- +?>**那么是不是所有的 px 都需要这样转换呢? ** + +答: `1px` 不需要转换,直接就写`1px`; \ No newline at end of file diff --git a/docs/ui/standard.md b/docs/ui/standard.md new file mode 100644 index 0000000..f8cb254 --- /dev/null +++ b/docs/ui/standard.md @@ -0,0 +1,183 @@ +# 开发规范 + + +## 目录规范 + +![BUI 单页示例目录说明](http://www.easybui.com/docs/images/router/catalog.png) + +!> `src`目录及外层 `app.json`,`gulpfile.js`,`package.json`, 不使用npm时,非必须. + +**目录说明:** + +| **目录名** | **描述** | **是否必须** | +|:------------- |:--------------------------------|--------------:| +| /app.json | 插件及跨域的配置 | 否 | +| /gulpfile.js | gulp编译配置 | 否 | +| /package.json | 工程依赖配置 | 否 | +| /src/index.html | 应用首页入口文件 | 是 | +| /src/index.js | 路由的初始化脚本及全局事件 | 是 | +| /src/css/ | 应用样式及bui.css样式 | 是 | +| /src/font/ | bui.css用到的字体图标 | 是 | +| /src/images/ | 应用图片目录 | 否 | +| /src/js/ | 应用脚本 | 是 | +| /src/js/zepto.js | bui.js默认依赖于zepto.js 或 jquery | 是 | +| /src/js/bui.js | BUI交互控件库 | 是 | +| /src/pages/ | 应用的模块 | 是 | +| /src/pages/main/ | 默认路由初始化以后会先载入这个main模块 | 是 | +| /src/pages/main/main.html | main模块的模板 | 是 | +| /src/pages/main/main.js | main模块的业务脚本 | 是 | + + +## 页面结构规范 +?> 一个标准的结构包含, .bui-page 子集分别是 `header`, `main`, `footer` 等标签, `main` 标签必须有, 因为页面初始化的时候会自动撑开main的高度. 快速书写 `ui-page` Tab + +```html +
      +
      +
      + +
      +
      +
      BUI开发工程模板
      +
      + +
      +
      +
      +
      + +
      +
      + +
      +
      +``` + +## 结构及命名规范 + +*注意:* +* `bui-box, bui-fluid, bui-btn, span1 - span12, icon-`, 是全局定义的关键字,不要使用上面的名称开头,可能导致你的样式多了很多东西 +* 业务中新增的样式无需以bui开头命名 +* 结构使用 控件名+中横杆+位置 命名 head main foot left right cell wrap + + **上下结构 示例** : 滑动控件 + 快速书写: `ui-slide` Tab + + ```html +
      +
      +
      +
      +
      +
      + ``` + **上中下结构 示例** : 滚动加载控件 + 快速书写: `ui-scroll` Tab + + ```html +
      +
      +
      +
      +
      + ``` + **左中右结构 示例** : bar + 快速书写: `ui-bar` Tab + + ```html +
      +
      +
      +
      +
      +
      +
      + ``` + **控件的重复子元素使用 -cell 示例** : 步骤条 + 快速书写: `ui-rating` Tab + + ```html +
      +
      +
      + ``` + **控件名父层在控件名后面加上 -wrap 示例** : 侧边栏 + 快速书写: `ui-sidebar` Tab + + ```html +
      + +
      + 页面正文 +
      +
      + ``` + + + +## 模块化规范 + +1. 一个js 文件里面只能有一个 `loader.define` 的匿名模块; +2. 业务逻辑需要在 `loader.define` 里面,防止加载其它模块的时候冲突; +3. 避免循环依赖 A ->依赖 B 模块, 而 B模块 -> A模块, 这就造成循环依赖,一般需要避免这种设计,如果一定要用, 不使用依赖前置的方式; +4. 避免循环嵌套, 在`loader.define` 里面 又 `require` 加载当前模块, 这个时候还没实例化,就会造成死循环; +5. 每个页面的ID不能相同; +6. 模块的路径以及资源等,都使用相对路径; + +## 事件规范 + +?>事件分为全局事件,及控件事件, + +- **全局事件**: 指页面加载的时候,就会触发的事件; + +- **控件事件**: 在控件初始化以后才会存在; + + +### 全局事件 + +页面初始化加载事件 + +- pagebefore (dom 初始化完毕, BUI 及 原生方法未初始化) +- pageinit (dom 及 BUI 初始化完毕, 原生方法未初始化 ) +- pageready (dom 及 BUI 及原生方法 初始化完毕 ) +- onload (dom 及 BUI 及原生方法 及 图片js资源 都初始化完毕 ) + +?> UI控件初始化可以在下面执行: + +``` +// dom及bui控件初始化完毕 +bui.on("pageinit",function(){ + // dom ready , bui ready +}) +``` + +?> 多页开发控件及原生方法都必须在`bui.ready` 里面 + +``` +// dom及bui及原生方法都初始化完毕 +bui.ready(function(){ + // dom ready , bui ready, native ready +}) +``` + +?> 在PC的加载顺序是 `pagebefore -> pageinit -> pageready -> onload` , 在手机的加载顺序是 `pagebefore -> pageinit -> onload -> pageready` 所以为了方法及dom能正确初始化, 我们的事件监听一般在 `bui.ready` . + +### 控件事件 + +?>已安装BUI Fast 插件的SublimeText用户, 输入 `bui- + 控件名 + -on`,按Tab键可以生成以下结构. + +BUI Fast 书写示例: `bui-accordion-on` + +```js +// 监听事件 +uiAccordion.on("show",function(){ + // 显示的时候做什么事情 +}) + +``` +控件的更多事件,请查看[API文档](http://www.easybui.com/demo/api/) + +!> 注意: 控件的事件监听要在控件初始化之后. + diff --git a/docs/ui/style.md b/docs/ui/style.md new file mode 100644 index 0000000..f0cf740 --- /dev/null +++ b/docs/ui/style.md @@ -0,0 +1,110 @@ +# 样式规范 + + +## 字体图标 + +[图标内置样式](http://www.easybui.com/demo/#pages/ui/icon) + +[更多图标预览](http://www.easybui.com/demo/font/demo.html) + +?> 样式名 `icon` 及 `icon-` 开头默认自带了字体图标的样式, 如果需要自定义图标或引入第三方图标,建议更改样式名为 `icons-` 或其它命名. + +## 布局样式 + +| **布局** | **子元素** | **描述** | +|:------------- |:-------------------|:-------------------| +| bui-box | span1 - span12 | 弹性布局 | +| bui-box-space | span1 - span12 | 留白弹性布局 | +| bui-box-vertical | span1 - span12 | 垂直方向 | +| bui-box-reverse | span1 - span12 | 反序排列 | +| bui-fluid | span1 - span12 | 流式布局 | +| bui-fluid-space | span1 - span12 | 留白流式布局 | +| bui-fluid-5 | span1 | 流式5列等比布局, 数字支持1-12 | +| bui-fluid-space-5 | span1 | 流式5列等比留白布局, 数字支持1-12 | +| bui-left | | 左浮动 | +| bui-right | | 右浮动 | +| bui-clear | | 清除浮动 | + +## 布局对齐 + +| **布局** | **子元素** | **描述** | +|:------------- |:-------------------|:-------------------| +| bui-box-center | div | 块元素水平垂直居中 | +| bui-box-align-center | div | 水平居中 | +| bui-box-align-left | div | 居左对齐 | +| bui-box-align-right | div | 居右对齐 | +| bui-box-align-middle | div | 垂直居中对齐 | +| bui-box-align-top | div | 顶部对齐 | +| bui-box-align-bottom | div | 底部对齐 | +| bui-box-align-justify | div | 两端对齐 | +| bui-box-align-stretch | div | 子集高度拉伸等高 | + +## 全局样式-常用类 + +| **样式名** | **描述** | +|:------------- |:-------------------| +| bui-btn- | 自定义按钮,后面跟名字,自带bui-btn样式 | +| container-x | 左右间隙 | +| container-y | 上下间隙 | +| container-xy | 上下左右间隙 | +| active | 按钮高亮颜色 | +| clearactive | 清除按钮高亮,常用于表单 | +| inline | 内联元素 | +| round | 圆角 | +| noround | 没有圆角 | +| ring | 圆 | +| large | 加大高度 | +| xlarge | 超大高度 | +| bui-reset | 按钮样式重置 | +| bui-show | 显示块元素 | +| bui-hide | 隐藏块元素 | + +## 全局样式-颜色类 + +| **样式名** | **描述** | +|:------------- |:-------------------| +| default | 默认颜色 | +| primary | 页面主颜色 | +| success | 一般是绿色 | +| warning | 一般是橘红色 | +| danger | 列表的分组标题 | + +## 全局样式-标题类 + +| **样式名** | **描述** | +|:------------- |:-------------------| +| page-title | 页面标题 | +| title | 文章标题 | +| subtitle | 文章子标题 | +| section-title | 章节标题,常用于页面的模块划分 | +| bui-btn-title | 列表的分组标题 | +| item-title | 列表的多行标题 | +| item-text | 列表的多行内容 | + +## 全局样式-文本类 + +| **样式名** | **描述** | +|:------------- |:-------------------| +| bui-align-left | 文本左对齐 | +| bui-align-right | 文本右对齐 | +| bui-align-center | 文本居中对齐 | +| bui-text-show | 文本显示 | +| bui-text-hide | 文本超出点点点 | +| bui-box-text-hide | 文本2行超出点点点 | +| bui-text-clip | 文本超出截断 | + +## 全局样式-箭头类 + +| **样式名** | **描述** | +|:------------- |:-------------------| +| bui-arrow-left | 左边箭头,需要父级增加 positon:relative; | +| bui-arrow-right | 右边箭头,需要父级增加 positon:relative; | +| bui-arrow-up | 顶部箭头,需要父级增加 positon:relative; | +| bui-arrow-down | 底部箭头,需要父级增加 positon:relative; | + + +## 注意事项 +* `active` 是控件的公共样式,请通过父层的方式定义 `.bui-nav .active{}` ,不要直接 `.active {}` ; +* BUI的样式单位都需要以 rem 为单位, 也就是量到的px除以100 就能转换成rem, 除了`1px` 不做转换; +注意: `.bui-nav .active{}` 也会修改到使用bui-nav的其它控件, 所以如果跟业务相关,请直接加上自己的业务样式进行修改; +