@james-zhang/elpis 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/.eslintignore +3 -0
  2. package/.eslintrc +55 -0
  3. package/.tmp-check.js +47 -0
  4. package/README.md +287 -0
  5. package/app/controller/base.js +37 -0
  6. package/app/controller/project.js +76 -0
  7. package/app/controller/view.js +17 -0
  8. package/app/extend/logger.js +36 -0
  9. package/app/middleware/api-params-verify.js +78 -0
  10. package/app/middleware/api-sign-verify.js +31 -0
  11. package/app/middleware/error-handler.js +36 -0
  12. package/app/middleware/project-handler.js +26 -0
  13. package/app/middleware.js +69 -0
  14. package/app/pages/asserts/custom.css +10 -0
  15. package/app/pages/boot.js +44 -0
  16. package/app/pages/common/curl.js +76 -0
  17. package/app/pages/common/utils.js +2 -0
  18. package/app/pages/dashboard/complex-view/header-view/complex-view/sub-menu/sub-menu.vue +19 -0
  19. package/app/pages/dashboard/complex-view/header-view/header-view.vue +131 -0
  20. package/app/pages/dashboard/complex-view/iframe-view/iframe-view.vue +29 -0
  21. package/app/pages/dashboard/complex-view/schema-view/complex-view/search-pannel/search-pannel.vue +36 -0
  22. package/app/pages/dashboard/complex-view/schema-view/complex-view/table-pannel/table-pannel.vue +125 -0
  23. package/app/pages/dashboard/complex-view/schema-view/components/component-config.js +19 -0
  24. package/app/pages/dashboard/complex-view/schema-view/components/create-form/create-form.vue +119 -0
  25. package/app/pages/dashboard/complex-view/schema-view/components/detail-panel/detail-panel.vue +131 -0
  26. package/app/pages/dashboard/complex-view/schema-view/components/edit-form/edit-form.vue +149 -0
  27. package/app/pages/dashboard/complex-view/schema-view/hook/schema.js +126 -0
  28. package/app/pages/dashboard/complex-view/schema-view/schema-view.vue +111 -0
  29. package/app/pages/dashboard/complex-view/sider-view/complex-view/sub-menu/sub-menu.vue +28 -0
  30. package/app/pages/dashboard/complex-view/sider-view/sider-view.vue +138 -0
  31. package/app/pages/dashboard/dashboard.vue +121 -0
  32. package/app/pages/dashboard/entry.dashboard.js +52 -0
  33. package/app/pages/dashboard/router.js +3 -0
  34. package/app/pages/dashboard/todo/todo.vue +10 -0
  35. package/app/pages/store/index.js +3 -0
  36. package/app/pages/store/menu.js +71 -0
  37. package/app/pages/store/project.js +15 -0
  38. package/app/pages/widgets/header-container/asserts/avatar.png +0 -0
  39. package/app/pages/widgets/header-container/asserts/logo.png +0 -0
  40. package/app/pages/widgets/header-container/header-container.vue +118 -0
  41. package/app/pages/widgets/schema-form/complex-view/input/input.vue +165 -0
  42. package/app/pages/widgets/schema-form/complex-view/input-number/input-number.vue +164 -0
  43. package/app/pages/widgets/schema-form/complex-view/select/select.vue +138 -0
  44. package/app/pages/widgets/schema-form/form-item-config.js +20 -0
  45. package/app/pages/widgets/schema-form/schema-form.vue +154 -0
  46. package/app/pages/widgets/schema-search-bar/complex-view/date-range/date-range.vue +49 -0
  47. package/app/pages/widgets/schema-search-bar/complex-view/dynamic-select/dynamic-select.vue +65 -0
  48. package/app/pages/widgets/schema-search-bar/complex-view/input/input.vue +44 -0
  49. package/app/pages/widgets/schema-search-bar/complex-view/select/select.vue +50 -0
  50. package/app/pages/widgets/schema-search-bar/schema-search-bar.vue +134 -0
  51. package/app/pages/widgets/schema-search-bar/search-item-config.js +27 -0
  52. package/app/pages/widgets/schema-table/schema-table.vue +277 -0
  53. package/app/pages/widgets/sider-container/sider-container.vue +42 -0
  54. package/app/public/static/logo.png +0 -0
  55. package/app/public/static/normalize.css +239 -0
  56. package/app/router/project.js +7 -0
  57. package/app/router/view.js +7 -0
  58. package/app/router-schema/project.js +34 -0
  59. package/app/service/base.js +10 -0
  60. package/app/service/project.js +43 -0
  61. package/app/view/entry.tpl +31 -0
  62. package/app/webpack/config/webpack.base.js +224 -0
  63. package/app/webpack/config/webpack.dev.js +53 -0
  64. package/app/webpack/config/webpack.prod.js +104 -0
  65. package/app/webpack/dev.js +54 -0
  66. package/app/webpack/libs/blank.js +1 -0
  67. package/app/webpack/prod.js +17 -0
  68. package/config/config.default.js +3 -0
  69. package/docs/dashboard-model.js +150 -0
  70. package/elpis-core/env.js +21 -0
  71. package/elpis-core/index.js +82 -0
  72. package/elpis-core/loader/config.js +58 -0
  73. package/elpis-core/loader/controller.js +55 -0
  74. package/elpis-core/loader/extend.js +42 -0
  75. package/elpis-core/loader/middleware.js +50 -0
  76. package/elpis-core/loader/router-schema.js +28 -0
  77. package/elpis-core/loader/router.js +42 -0
  78. package/elpis-core/loader/service.js +51 -0
  79. package/index.js +37 -0
  80. package/logs/application.log +50 -0
  81. package/logs/application.log.2026-06-13 +159 -0
  82. package/model/index.js +119 -0
  83. package/package.json +88 -0
  84. package/scripts/generate-cover.py +93 -0
  85. package/scripts/generate-diagrams.js +80 -0
  86. package/test/controller/project.test.js +218 -0
@@ -0,0 +1,134 @@
1
+ <template>
2
+ <el-form
3
+ v-if="schema?.properties"
4
+ :inline="true"
5
+ class="schema-search-bar"
6
+ :model="searchForm"
7
+ >
8
+ <!-- 循环schema生成搜索项 -->
9
+ <el-form-item
10
+ v-for="(schemaItem, key) in schema.properties"
11
+ :key="key"
12
+ :label="schemaItem.label"
13
+ >
14
+ <!-- 根据字段类型渲染不同输入框(展示子组件) -->
15
+ <component
16
+ :ref="searchComList"
17
+ :is="SearchItemConfig[schemaItem.option?.comType]?.component"
18
+ :schemaKey="key"
19
+ :schema="schemaItem"
20
+ @load="handleChildLoader"
21
+ />
22
+ </el-form-item>
23
+
24
+ <!-- 操作区域 -->
25
+ <el-form-item>
26
+ <el-button
27
+ type="primary"
28
+ plain
29
+ class="search-btn"
30
+ @click="search"
31
+ >搜索</el-button>
32
+ <el-button
33
+ plain
34
+ class="reset-btn"
35
+ @click="reset"
36
+ >重置</el-button>
37
+ </el-form-item>
38
+ </el-form>
39
+ </template>
40
+
41
+
42
+ <script setup>
43
+ import {ref,computed,unref} from 'vue'
44
+ import SearchItemConfig from './search-item-config.js'
45
+ const props=defineProps({
46
+ /**
47
+ * schema配置结构如下:
48
+ * schema:{
49
+ //板块数据结构
50
+ type:'object',
51
+ properties:{
52
+ key:{
53
+ ...schema, //标准schema配置
54
+ type:'', //字段类型
55
+ label:'', //字段的中文名
56
+ //字段在search-bar中的相关配置
57
+ option:{
58
+ ...elComponentConfig,//标准el-component-column配置
59
+ comType:'',// 配置组件类型 input/select...
60
+ default:'', //默认值
61
+ }
62
+ }
63
+ }
64
+ },
65
+ */
66
+ schema:Object,
67
+ })
68
+ const schema=computed(()=>unref(props.schema))
69
+
70
+ const emit=defineEmits(['load','search','reset'])
71
+
72
+ const searchForm=ref({})
73
+ const searchComList=ref([])
74
+
75
+
76
+ const getValue=()=>{
77
+ let dtoObj={}
78
+ searchComList.value.forEach(component=>{
79
+ dtoObj={
80
+ ...dtoObj,
81
+ ...component?.getValue(),
82
+ }
83
+ })
84
+ return dtoObj
85
+ }
86
+
87
+ let childComLoadedCount=0
88
+ const handleChildLoader=(child)=>{
89
+ childComLoadedCount++
90
+ const schemaValue = unref(schema)
91
+ const properties = schemaValue?.properties || {}
92
+ if(childComLoadedCount>=Object.keys(properties).length){
93
+ emit('load',getValue())
94
+ }
95
+ }
96
+
97
+ const search=()=>{
98
+ emit('search',getValue())
99
+ }
100
+ const reset=()=>{
101
+ searchComList.value.forEach(component=>{
102
+ component?.reset()
103
+ })
104
+ emit('reset')
105
+ }
106
+
107
+ defineExpose({
108
+ getValue,
109
+ reset,
110
+ })
111
+ </script>
112
+
113
+ <style lang="less" scoped>
114
+ .schema-search-bar {
115
+ min-width: 500px;
116
+
117
+ .input{
118
+ width: 100px;
119
+ }
120
+ .select{
121
+ width: 100px;
122
+ }
123
+ .dynamic-select{
124
+ width: 100px;
125
+ }
126
+ .search-btn{
127
+ width: 100px;
128
+ }
129
+
130
+ .reset-btn{
131
+ width: 100px;
132
+ }
133
+ }
134
+ </style>
@@ -0,0 +1,27 @@
1
+ import input from './complex-view/input/input.vue'
2
+ import select from './complex-view/select/select.vue'
3
+ import dynamicSelect from './complex-view/dynamic-select/dynamic-select.vue'
4
+ import dateRange from './complex-view/date-range/date-range.vue'
5
+
6
+ //业务扩展 search-item 配置
7
+ import BusinessSchemaSearchItemConfig from '$businessSchemaSearchItemConfig'
8
+
9
+ const SearchItemConfig={
10
+ input:{
11
+ component:input,
12
+ },
13
+ select:{
14
+ component:select,
15
+ },
16
+ dynamicSelect:{
17
+ component:dynamicSelect,
18
+ },
19
+ dateRange:{
20
+ component:dateRange,
21
+ }
22
+ }
23
+
24
+ export default {
25
+ ...SearchItemConfig,
26
+ ...BusinessSchemaSearchItemConfig
27
+ }
@@ -0,0 +1,277 @@
1
+ <template>
2
+ <div class="schema-table">
3
+ <el-table
4
+ v-if="hasSchemaProperties || tableData.length > 0"
5
+ v-loading="loading"
6
+ :data="tableData"
7
+ class="table"
8
+ >
9
+ <!-- 循环schema配置渲染表格列 -->
10
+ <template v-if="hasSchemaProperties">
11
+ <el-table-column
12
+ v-for="(schemaItem, key) in schema.properties"
13
+ :key="key"
14
+ :prop="key"
15
+ :label="schemaItem.label"
16
+ v-bind="schemaItem.option"
17
+ ></el-table-column>
18
+ </template>
19
+
20
+ <!-- schema 为空时,根据返回数据自动生成列 -->
21
+ <template v-else>
22
+ <el-table-column
23
+ v-for="key in dataColumnKeys"
24
+ :key="key"
25
+ :prop="key"
26
+ :label="key"
27
+ ></el-table-column>
28
+ </template>
29
+
30
+ <!-- 操作列:动态渲染按钮 -->
31
+ <el-table-column
32
+ v-if="buttons?.length > 0"
33
+ label="操作"
34
+ fixed="right"
35
+ :width="operationWidth"
36
+ >
37
+ <template #default="scope">
38
+ <el-button v-for="item in buttons" link v-bind="item" :key="item.key" @click="operationHandler({btnConfig:item,rowData:scope.row})">
39
+ <!-- 按钮内容后续绑定item配置、点击事件 -->
40
+ {{ item.label }}
41
+ </el-button>
42
+ </template>
43
+ </el-table-column>
44
+
45
+ </el-table>
46
+ <el-row justify="end" class="pagination">
47
+ <el-pagination
48
+ :current-page="currentPage"
49
+ :page-size="pageSize"
50
+ :page-sizes="[10,20,50,100,200]"
51
+ :total="total"
52
+ layout="total,sizes, prev, pager, next, jumper"
53
+ @current-change="onCurrentPageChange"
54
+ @size-change="onPageSizeChange"
55
+ />
56
+ </el-row>
57
+ </div>
58
+ </template>
59
+
60
+ <script setup>
61
+ import { ref,onMounted,watch,nextTick,computed,unref } from 'vue'
62
+ import $curl from '$elpisCommon/curl.js'
63
+ // 接收父组件传入配置
64
+ const props = defineProps({
65
+ /**
66
+ * 表格Schema配置(列、字段、表单渲染规则)
67
+ * {
68
+ //板块数据结构
69
+ type:'',
70
+ properties:{
71
+ key:{
72
+ ...schema, //标准schema配置
73
+ type:'', //字段类型
74
+ label:'', //字段的中文名
75
+ option:{
76
+ ...elTableConfig,//标准table配置
77
+ visible:true, //是否在table中显示
78
+ }
79
+ }
80
+ }
81
+ }
82
+ */
83
+ schema: Object, // 表格Schema配置(列、字段、表单渲染规则)
84
+
85
+ /**
86
+ * 表格数据源 api
87
+ */
88
+ api: String, // 请求表格数据的接口地址
89
+
90
+ /**
91
+ * api请求参数,请求API时携带
92
+ */
93
+ apiParams:Object, // 请求表格数据的接口参数
94
+
95
+ /**
96
+ * buttons操作按钮相关配置,结构如下:
97
+ * {
98
+ label:'',//按钮中文名
99
+ eventKey:'',//按钮点击事件名
100
+ eventOption:{}, //按钮点击事件参数
101
+ ...elButtonConfig,//标准按钮配置
102
+ }
103
+ */
104
+ buttons: Array // 表格顶部操作按钮配置数组
105
+ })
106
+ const schema=computed(()=>unref(props.schema))
107
+ const api=computed(()=>unref(props.api))
108
+ const apiParams=computed(()=>{
109
+ const val = props.apiParams
110
+ if (val && typeof val === 'object' && 'value' in val) {
111
+ return val.value ?? {}
112
+ }
113
+ return val ?? {}
114
+ })
115
+ const buttons=computed(()=>unref(props.buttons))
116
+
117
+ const emit= defineEmits(['operate'])
118
+
119
+ const operationWidth=computed(()=>{
120
+ return buttons?.value?.length > 0 ? buttons.value.reduce((pre,cur)=>pre+cur.label.length*18,50)+'px' : '50px'
121
+ })
122
+
123
+ const hasSchemaProperties=computed(()=>{
124
+ return schema.value?.properties && Object.keys(schema.value.properties).length>0
125
+ })
126
+
127
+ const dataColumnKeys=computed(()=>{
128
+ if(!tableData.value || tableData.value.length===0){
129
+ return []
130
+ }
131
+ return Object.keys(tableData.value[0])
132
+ })
133
+
134
+ const loading=ref(false)
135
+ const tableData=ref([])
136
+ const currentPage=ref(1)
137
+ const pageSize=ref(10)
138
+ const total=ref(0)
139
+
140
+ onMounted(()=>{
141
+ initData()
142
+ })
143
+ watch([schema,api,apiParams],initData,{deep:true})
144
+
145
+
146
+ function initData(){
147
+ currentPage.value=1
148
+ pageSize.value=50
149
+ nextTick(async()=>{
150
+ await loadTableData()
151
+ })
152
+ }
153
+
154
+ //节流,避免频繁请求(onMounted/watch)
155
+ let timerId=null
156
+ const loadTableData=async()=>{
157
+ if(timerId){
158
+ clearTimeout(timerId)
159
+ }
160
+ timerId=setTimeout(async()=>{
161
+ await fetchTableData()
162
+ timerId=null //解除引用,释放内存
163
+ },100)
164
+ }
165
+
166
+ //请求table数据
167
+ const fetchTableData=async()=>{
168
+ if(!api.value){
169
+ return
170
+ }
171
+ showLoading()
172
+ const res=await $curl({
173
+ method:'get',
174
+ url:`${api.value}/list`,
175
+ query:{
176
+ page:currentPage.value,
177
+ size:pageSize.value,
178
+ ...(apiParams.value || {}),
179
+ }
180
+ })
181
+ hideLoading()
182
+
183
+ if(!res || !res.success){
184
+ tableData.value=[]
185
+ total.value=0
186
+ return
187
+ }
188
+
189
+ // 兼容两种返回结构:数组 或 { list, total }
190
+ const listData = Array.isArray(res.data) ? res.data : res.data?.list
191
+ if(!Array.isArray(listData)){
192
+ tableData.value=[]
193
+ total.value=0
194
+ return
195
+ }
196
+ tableData.value=buildTableData(listData)
197
+ total.value=res.data?.total ?? res.metaData?.total ?? 0
198
+ }
199
+ /**
200
+ * 对后端返回的数据进行渲染前的预处理
201
+ * @param {object} data 后端返回的原始数据
202
+ * @returns 处理后的数据
203
+ */
204
+
205
+ const buildTableData=(listData)=>{
206
+ if(!schema.value?.properties){
207
+ return listData
208
+ }
209
+ return listData.map(rowData=>{
210
+ for(const dKey in rowData){
211
+ const schemaItem=schema.value.properties[dKey]
212
+ // 处理toFixed配置
213
+ if(schemaItem?.option?.toFixed){
214
+ rowData[dKey]=rowData[dKey].toFixed && rowData[dKey].toFixed(schemaItem.option.toFixed)
215
+ }
216
+ }
217
+ return rowData
218
+ })
219
+ }
220
+
221
+ const showLoading=()=>{
222
+ loading.value=true
223
+ }
224
+ const hideLoading=()=>{
225
+ loading.value=false
226
+ }
227
+ /**
228
+ * 操作按钮点击事件处理
229
+ * @param {object} params 包含按钮配置和行数据的对象参数
230
+ */
231
+ const operationHandler=({btnConfig,rowData})=>{
232
+ emit('operate',{btnConfig,rowData})
233
+ }
234
+ /**
235
+ * 分页当前页改变事件处理
236
+ * @param {number} val 新的当前页码
237
+ */
238
+ const onCurrentPageChange=(val)=>{
239
+ currentPage.value=val
240
+ loadTableData()
241
+ }
242
+ /**
243
+ * 分页每页显示改变事件处理
244
+ * @param {number} val 新的每页显示数量
245
+ */
246
+ const onPageSizeChange=(val)=>{
247
+ pageSize.value=val
248
+ loadTableData()
249
+ }
250
+
251
+ defineExpose({
252
+ initData,
253
+ loadTableData,
254
+ showLoading,
255
+ hideLoading,
256
+ })
257
+
258
+
259
+ </script>
260
+
261
+ <style lang="less" scoped>
262
+ .schema-table {
263
+ flex: 1;
264
+ display: flex;
265
+ flex-direction: column;
266
+ overflow: auto;
267
+
268
+ .table {
269
+ flex: 1; /* 表格自适应占满剩余高度 */
270
+ }
271
+
272
+ .pagination {
273
+ margin: 10px 0;
274
+ text-align: right; /* 分页靠右对齐 */
275
+ }
276
+ }
277
+ </style>
@@ -0,0 +1,42 @@
1
+ <template>
2
+ <el-container class="sider-container">
3
+ <!-- 左侧侧边栏插槽 -->
4
+ <el-aside width="260px" class="aside">
5
+ <slot name="menu-content" />
6
+ </el-aside>
7
+ <!-- 右侧主内容区插槽 -->
8
+ <el-main class="main">
9
+ <slot name="main-content" />
10
+ </el-main>
11
+ </el-container>
12
+ </template>
13
+
14
+ <script setup>
15
+ // 纯布局组件,无业务逻辑
16
+ </script>
17
+
18
+ <style lang="less" scoped>
19
+ .sider-container {
20
+ flex: 1;
21
+ min-height: 0;
22
+ display: flex;
23
+ flex-direction: row;
24
+
25
+ .aside {
26
+ width: 260px;
27
+ min-width: 260px;
28
+ flex-shrink: 0;
29
+ border-right: 1px solid #E8E8E8;
30
+ overflow: auto;
31
+ }
32
+
33
+ .main {
34
+ overflow: auto;
35
+ }
36
+
37
+ // 深度修改内部el-menu样式,去掉右侧边框
38
+ :deep(.el-menu) {
39
+ border-right: 0;
40
+ }
41
+ }
42
+ </style>
Binary file
@@ -0,0 +1,239 @@
1
+ /*! normalize.css v3.0.2 | MIT License | git.io/normalize */
2
+
3
+ /**
4
+ * 1. Set default font family to sans-serif.
5
+ * 2. Prevent iOS text size adjust after orientation change, without disabling
6
+ * user zoom.
7
+ */
8
+ html,body,span,div,p,a,table,tbody,td,h1,h2,h3,img,form,font,strong,b,i,dl,dt,dd,ol,ul,li,dl,dd,dt,iframe,label,blockquote,input,button
9
+ {
10
+ padding: 0;
11
+ margin: 0;
12
+ list-style: none;
13
+ }
14
+
15
+ html {
16
+ font-family: "Open Sans","Helvetica Neue","Microsoft Yahei",sans-serif;/* 1 */
17
+ -ms-text-size-adjust: 100%; /* 2 */
18
+ -webkit-text-size-adjust: 100%; /* 2 */
19
+ }
20
+
21
+ /**
22
+ * Remove default margin.
23
+ */
24
+
25
+ body {
26
+ margin: 0;
27
+ }
28
+
29
+ /* Links
30
+ ========================================================================== */
31
+
32
+ /**
33
+ * Remove the gray background color from active links in IE 10.
34
+ */
35
+
36
+ a {
37
+ background-color: transparent;
38
+ text-decoration: none;
39
+ }
40
+
41
+ /**
42
+ * Improve readability when focused and also mouse hovered in all browsers.
43
+ */
44
+
45
+ a:active,
46
+ a:hover {
47
+ outline: 0;
48
+ }
49
+
50
+ /* Text-level semantics
51
+ ========================================================================== */
52
+
53
+ /**
54
+ * Address style set to `bolder` in Firefox 4+, Safari, and Chrome.
55
+ */
56
+
57
+ b,
58
+ strong {
59
+ font-weight: bold;
60
+ }
61
+
62
+ /* Embedded content
63
+ ========================================================================== */
64
+
65
+ /**
66
+ * Remove border when inside `a` element in IE 8/9/10.
67
+ */
68
+
69
+ img {
70
+ border: 0;
71
+ }
72
+
73
+
74
+ /* Grouping content
75
+ ========================================================================== */
76
+
77
+ /**
78
+ * Address margin not present in IE 8/9 and Safari.
79
+ */
80
+
81
+ figure {
82
+ margin: 1em 40px;
83
+ }
84
+
85
+
86
+ /* Forms
87
+ ========================================================================== */
88
+
89
+ /**
90
+ * Known limitation: by default, Chrome and Safari on OS X allow very limited
91
+ * styling of `select`, unless a `border` property is set.
92
+ */
93
+
94
+ /**
95
+ * 1. Correct color not being inherited.
96
+ * Known issue: affects color of disabled elements.
97
+ * 2. Correct font properties not being inherited.
98
+ * 3. Address margins set differently in Firefox 4+, Safari, and Chrome.
99
+ */
100
+
101
+ button,
102
+ input,
103
+ optgroup,
104
+ select,
105
+ textarea {
106
+ color: inherit; /* 1 */
107
+ font: inherit; /* 2 */
108
+ margin: 0; /* 3 */
109
+ }
110
+
111
+ /**
112
+ * Address `overflow` set to `hidden` in IE 8/9/10/11.
113
+ */
114
+
115
+ button {
116
+ overflow: visible;
117
+ }
118
+
119
+ /**
120
+ * Address inconsistent `text-transform` inheritance for `button` and `select`.
121
+ * All other form control elements do not inherit `text-transform` values.
122
+ * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.
123
+ * Correct `select` style inheritance in Firefox.
124
+ */
125
+
126
+ button,
127
+ select {
128
+ text-transform: none;
129
+ }
130
+
131
+ /**
132
+ * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
133
+ * and `video` controls.
134
+ * 2. Correct inability to style clickable `input` types in iOS.
135
+ * 3. Improve usability and consistency of cursor style between image-type
136
+ * `input` and others.
137
+ */
138
+
139
+ button,
140
+ html input[type="button"], /* 1 */
141
+ input[type="reset"],
142
+ input[type="submit"] {
143
+ -webkit-appearance: button; /* 2 */
144
+ cursor: pointer; /* 3 */
145
+ }
146
+
147
+ /**
148
+ * Re-set default cursor for disabled elements.
149
+ */
150
+
151
+ button[disabled],
152
+ html input[disabled] {
153
+ cursor: default;
154
+ }
155
+
156
+ /**
157
+ * Remove inner padding and border in Firefox 4+.
158
+ */
159
+
160
+ button::-moz-focus-inner,
161
+ input::-moz-focus-inner {
162
+ border: 0;
163
+ padding: 0;
164
+ }
165
+
166
+ /**
167
+ * Address Firefox 4+ setting `line-height` on `input` using `!important` in
168
+ * the UA stylesheet.
169
+ */
170
+
171
+ input {
172
+ line-height: normal;
173
+ }
174
+
175
+ /**
176
+ * It's recommended that you don't attempt to style these elements.
177
+ * Firefox's implementation doesn't respect box-sizing, padding, or width.
178
+ *
179
+ * 1. Address box sizing set to `content-box` in IE 8/9/10.
180
+ * 2. Remove excess padding in IE 8/9/10.
181
+ */
182
+
183
+ input[type="checkbox"],
184
+ input[type="radio"] {
185
+ box-sizing: border-box; /* 1 */
186
+ padding: 0; /* 2 */
187
+ }
188
+
189
+ /**
190
+ * Fix the cursor style for Chrome's increment/decrement buttons. For certain
191
+ * `font-size` values of the `input`, it causes the cursor style of the
192
+ * decrement button to change from `default` to `text`.
193
+ */
194
+
195
+ input[type="number"]::-webkit-inner-spin-button,
196
+ input[type="number"]::-webkit-outer-spin-button {
197
+ height: auto;
198
+ }
199
+
200
+ /**
201
+ * 1. Address `appearance` set to `searchfield` in Safari and Chrome.
202
+ * 2. Address `box-sizing` set to `border-box` in Safari and Chrome
203
+ * (include `-moz` to future-proof).
204
+ */
205
+
206
+ input[type="search"] {
207
+ -webkit-appearance: textfield; /* 1 */
208
+ -moz-box-sizing: content-box;
209
+ -webkit-box-sizing: content-box; /* 2 */
210
+ box-sizing: content-box;
211
+ }
212
+
213
+ /**
214
+ * Remove inner padding and search cancel button in Safari and Chrome on OS X.
215
+ * Safari (but not Chrome) clips the cancel button when the search input has
216
+ * padding (and `textfield` appearance).
217
+ */
218
+
219
+ input[type="search"]::-webkit-search-cancel-button,
220
+ input[type="search"]::-webkit-search-decoration {
221
+ -webkit-appearance: none;
222
+ }
223
+
224
+ /* Tables
225
+ ========================================================================== */
226
+
227
+ /**
228
+ * Remove most spacing between table cells.
229
+ */
230
+
231
+ table {
232
+ border-collapse: collapse;
233
+ border-spacing: 0;
234
+ }
235
+
236
+ td,
237
+ th {
238
+ padding: 0;
239
+ }