@qtoggle/qui 0.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 (202) hide show
  1. package/.eslintignore +2 -0
  2. package/.eslintrc.json +492 -0
  3. package/.github/ISSUE_TEMPLATE/bug_report.md +33 -0
  4. package/.github/ISSUE_TEMPLATE/feature_request.md +23 -0
  5. package/.github/ISSUE_TEMPLATE/improvement_proposal.md +20 -0
  6. package/.github/workflows/main.yml +74 -0
  7. package/.pre-commit-config.yaml +8 -0
  8. package/LICENSE.txt +177 -0
  9. package/README.md +4 -0
  10. package/font/dejavusans-bold.woff +0 -0
  11. package/font/dejavusans-bolditalic.woff +0 -0
  12. package/font/dejavusans-italic.woff +0 -0
  13. package/font/dejavusans-regular.woff +0 -0
  14. package/img/qui-icons.svg +1937 -0
  15. package/js/base/base.js +47 -0
  16. package/js/base/condition-variable.js +92 -0
  17. package/js/base/errors.js +36 -0
  18. package/js/base/i18n.js +20 -0
  19. package/js/base/mixwith.js +135 -0
  20. package/js/base/require-js-compat.js +78 -0
  21. package/js/base/signal.js +91 -0
  22. package/js/base/singleton.js +66 -0
  23. package/js/base/timer.js +126 -0
  24. package/js/config.js +184 -0
  25. package/js/forms/common-fields/check-field.js +42 -0
  26. package/js/forms/common-fields/choice-buttons-field.js +30 -0
  27. package/js/forms/common-fields/color-combo-field.js +37 -0
  28. package/js/forms/common-fields/combo-field.js +108 -0
  29. package/js/forms/common-fields/common-fields.js +23 -0
  30. package/js/forms/common-fields/composite-field.js +132 -0
  31. package/js/forms/common-fields/custom-html-field.js +51 -0
  32. package/js/forms/common-fields/email-field.js +30 -0
  33. package/js/forms/common-fields/file-picker-field.js +46 -0
  34. package/js/forms/common-fields/jquery-ui-field.js +111 -0
  35. package/js/forms/common-fields/labels-field.js +69 -0
  36. package/js/forms/common-fields/numeric-field.js +39 -0
  37. package/js/forms/common-fields/password-field.js +28 -0
  38. package/js/forms/common-fields/phone-field.js +26 -0
  39. package/js/forms/common-fields/progress-disk-field.js +69 -0
  40. package/js/forms/common-fields/push-button-field.js +138 -0
  41. package/js/forms/common-fields/slider-field.js +51 -0
  42. package/js/forms/common-fields/text-area-field.js +34 -0
  43. package/js/forms/common-fields/text-field.js +89 -0
  44. package/js/forms/common-fields/up-down-field.js +85 -0
  45. package/js/forms/common-forms/common-forms.js +16 -0
  46. package/js/forms/common-forms/options-form.js +77 -0
  47. package/js/forms/common-forms/page-form.js +115 -0
  48. package/js/forms/form-button.js +202 -0
  49. package/js/forms/form-field.js +1183 -0
  50. package/js/forms/form.js +1181 -0
  51. package/js/forms/forms.js +68 -0
  52. package/js/global-glass.js +100 -0
  53. package/js/icons/default-stock.js +173 -0
  54. package/js/icons/icon.js +64 -0
  55. package/js/icons/icons.js +16 -0
  56. package/js/icons/multi-state-sprites-icon.js +362 -0
  57. package/js/icons/stock-icon.js +219 -0
  58. package/js/icons/stock.js +98 -0
  59. package/js/icons/stocks.js +57 -0
  60. package/js/index.js +232 -0
  61. package/js/lib/jquery.longpress.js +79 -0
  62. package/js/lib/jquery.module.js +4 -0
  63. package/js/lib/logger.module.js +4 -0
  64. package/js/lib/pep.module.js +4 -0
  65. package/js/lists/common-items/common-items.js +5 -0
  66. package/js/lists/common-items/icon-label-list-item.js +86 -0
  67. package/js/lists/common-lists/common-lists.js +5 -0
  68. package/js/lists/common-lists/page-list.js +53 -0
  69. package/js/lists/list-item.js +147 -0
  70. package/js/lists/list.js +636 -0
  71. package/js/lists/lists.js +26 -0
  72. package/js/main-ui/main-ui.js +64 -0
  73. package/js/main-ui/menu-bar.js +144 -0
  74. package/js/main-ui/options-bar.js +181 -0
  75. package/js/main-ui/status.js +185 -0
  76. package/js/main-ui/top-bar.js +59 -0
  77. package/js/messages/common-message-forms/common-message-forms.js +7 -0
  78. package/js/messages/common-message-forms/confirm-message-form.js +81 -0
  79. package/js/messages/common-message-forms/simple-message-form.js +67 -0
  80. package/js/messages/common-message-forms/sticky-simple-message-form.js +27 -0
  81. package/js/messages/message-form.js +107 -0
  82. package/js/messages/messages.js +21 -0
  83. package/js/messages/sticky-modal-page.js +98 -0
  84. package/js/messages/sticky-modal-progress-message.js +27 -0
  85. package/js/messages/toast.js +164 -0
  86. package/js/navigation.js +654 -0
  87. package/js/pages/breadcrumbs.js +124 -0
  88. package/js/pages/common-pages/common-pages.js +6 -0
  89. package/js/pages/common-pages/modal-progress-page.js +83 -0
  90. package/js/pages/common-pages/structured-page.js +46 -0
  91. package/js/pages/page.js +1018 -0
  92. package/js/pages/pages-context.js +154 -0
  93. package/js/pages/pages.js +252 -0
  94. package/js/pwa.js +337 -0
  95. package/js/sections/section.js +612 -0
  96. package/js/sections/sections.js +300 -0
  97. package/js/tables/common-cells/common-cells.js +7 -0
  98. package/js/tables/common-cells/icon-label-table-cell.js +68 -0
  99. package/js/tables/common-cells/push-button-table-cell.js +133 -0
  100. package/js/tables/common-cells/simple-table-cell.js +37 -0
  101. package/js/tables/common-tables/common-tables.js +5 -0
  102. package/js/tables/common-tables/page-table.js +55 -0
  103. package/js/tables/table-cell.js +198 -0
  104. package/js/tables/table-row.js +126 -0
  105. package/js/tables/table.js +492 -0
  106. package/js/tables/tables.js +36 -0
  107. package/js/theme.js +304 -0
  108. package/js/utils/ajax.js +126 -0
  109. package/js/utils/array.js +194 -0
  110. package/js/utils/colors.js +445 -0
  111. package/js/utils/cookies.js +65 -0
  112. package/js/utils/crypto.js +439 -0
  113. package/js/utils/css.js +234 -0
  114. package/js/utils/date.js +300 -0
  115. package/js/utils/files.js +27 -0
  116. package/js/utils/gestures.js +165 -0
  117. package/js/utils/html.js +76 -0
  118. package/js/utils/misc.js +81 -0
  119. package/js/utils/object.js +324 -0
  120. package/js/utils/promise.js +49 -0
  121. package/js/utils/string.js +192 -0
  122. package/js/utils/url.js +187 -0
  123. package/js/utils/utils.js +3 -0
  124. package/js/utils/visibility-manager.js +211 -0
  125. package/js/views/common-views/common-views.js +7 -0
  126. package/js/views/common-views/icon-label-view.js +210 -0
  127. package/js/views/common-views/progress-view.js +89 -0
  128. package/js/views/common-views/structured-view.js +368 -0
  129. package/js/views/view.js +467 -0
  130. package/js/views/views.js +3 -0
  131. package/js/widgets/base-widget.js +23 -0
  132. package/js/widgets/common-widgets/check-button.js +109 -0
  133. package/js/widgets/common-widgets/choice-buttons.js +322 -0
  134. package/js/widgets/common-widgets/color-combo.js +104 -0
  135. package/js/widgets/common-widgets/combo.js +645 -0
  136. package/js/widgets/common-widgets/common-widgets.js +17 -0
  137. package/js/widgets/common-widgets/email-input.js +7 -0
  138. package/js/widgets/common-widgets/file-picker.js +133 -0
  139. package/js/widgets/common-widgets/labels.js +132 -0
  140. package/js/widgets/common-widgets/numeric-input.js +49 -0
  141. package/js/widgets/common-widgets/password-input.js +91 -0
  142. package/js/widgets/common-widgets/phone-input.js +7 -0
  143. package/js/widgets/common-widgets/progress-disk.js +174 -0
  144. package/js/widgets/common-widgets/push-button.js +155 -0
  145. package/js/widgets/common-widgets/slider.js +455 -0
  146. package/js/widgets/common-widgets/text-area.js +52 -0
  147. package/js/widgets/common-widgets/text-input.js +174 -0
  148. package/js/widgets/common-widgets/up-down.js +351 -0
  149. package/js/widgets/widgets.js +57 -0
  150. package/js/window.js +557 -0
  151. package/jsdoc.conf.json +20 -0
  152. package/less/base.less +123 -0
  153. package/less/forms/common-fields.less +101 -0
  154. package/less/forms/common-forms.less +5 -0
  155. package/less/forms/form-button.less +21 -0
  156. package/less/forms/form-field.less +266 -0
  157. package/less/forms/form.less +131 -0
  158. package/less/global-glass.less +64 -0
  159. package/less/icon-label-view.less +82 -0
  160. package/less/icons.less +144 -0
  161. package/less/lists.less +105 -0
  162. package/less/main-ui.less +328 -0
  163. package/less/messages.less +189 -0
  164. package/less/no-effects.less +24 -0
  165. package/less/pages/breadcrumbs.less +98 -0
  166. package/less/pages/common-pages.less +36 -0
  167. package/less/pages/page.less +70 -0
  168. package/less/progress-view.less +51 -0
  169. package/less/stock-icons.less +43 -0
  170. package/less/structured-view.less +245 -0
  171. package/less/tables.less +84 -0
  172. package/less/theme-dark.less +133 -0
  173. package/less/theme-light.less +132 -0
  174. package/less/theme.less +419 -0
  175. package/less/visibility-manager.less +11 -0
  176. package/less/widgets/check-button.less +96 -0
  177. package/less/widgets/choice-buttons.less +160 -0
  178. package/less/widgets/color-combo.less +33 -0
  179. package/less/widgets/combo.less +230 -0
  180. package/less/widgets/common-buttons.less +120 -0
  181. package/less/widgets/common.less +24 -0
  182. package/less/widgets/input.less +258 -0
  183. package/less/widgets/labels.less +81 -0
  184. package/less/widgets/progress-disk.less +70 -0
  185. package/less/widgets/slider.less +199 -0
  186. package/less/widgets/updown.less +115 -0
  187. package/less/widgets/various.less +36 -0
  188. package/package.json +47 -0
  189. package/pyproject.toml +45 -0
  190. package/qui/__init__.py +110 -0
  191. package/qui/constants.py +1 -0
  192. package/qui/exceptions.py +2 -0
  193. package/qui/j2template.py +71 -0
  194. package/qui/settings.py +60 -0
  195. package/qui/templates/manifest.json +25 -0
  196. package/qui/templates/qui.html +126 -0
  197. package/qui/templates/service-worker.js +188 -0
  198. package/qui/web/__init__.py +0 -0
  199. package/qui/web/tornado.py +220 -0
  200. package/scripts/postinstall.sh +10 -0
  201. package/webpack/webpack-adjust-css-urls-loader.js +36 -0
  202. package/webpack/webpack-common.js +384 -0
@@ -0,0 +1,384 @@
1
+
2
+ const crypto = require('crypto')
3
+ const glob = require('glob')
4
+ const path = require('path')
5
+ const webpack = require('webpack')
6
+
7
+ const TerserPlugin = require('terser-webpack-plugin')
8
+ const MiniCssExtractPlugin = require('mini-css-extract-plugin')
9
+ const FixStyleOnlyEntriesPlugin = require('webpack-fix-style-only-entries')
10
+ const InjectPlugin = require('webpack-inject-plugin').default
11
+ const WebpackShellPlugin = require('webpack-shell-plugin')
12
+ const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin')
13
+
14
+
15
+ const THEMES = ['dark', 'light']
16
+
17
+ const LAUNCHER_ICON_SIZES = [16, 32, 36, 48, 64, 72, 96, 144, 192, 256, 384, 512]
18
+ const LAUNCHER_ICON_SRC_NAME = 'launcher-icon.svg'
19
+ const LAUNCHER_ICON_NAME_TEMPLATE = 'launcher-icon-{size}.png'
20
+ const RSVG_CONVERT_CMD_TEMPLATE = 'rsvg-convert -w {size} -h {size} -f png -o {outfile} {infile}'
21
+
22
+ const JS_DIR = 'js'
23
+ const CSS_DIR = 'css'
24
+ const IMG_DIR = 'img'
25
+ const FONT_DIR = 'font'
26
+ const LESS_DIR = 'less'
27
+ const TMPL_DIR = 'templates'
28
+ const DIST_DIR = 'dist'
29
+
30
+ const LESS_REGEX = new RegExp(`${LESS_DIR}/.*\\.less$`)
31
+ const QUI_JS_REGEX = new RegExp(`qui/${JS_DIR}/.*\\.jsm?$`)
32
+ const QUI_LESS_REGEX = new RegExp(`qui/${LESS_DIR}/.*\\.less$`)
33
+ const IMG_REGEX = new RegExp(`${IMG_DIR}/.*\\.(svg|png|gif|jpg|jpe?g|ico)$`)
34
+ const FONT_REGEX = new RegExp(`${FONT_DIR}/.*\\.(woff)$`)
35
+ const TMPL_REGEX = new RegExp(`${TMPL_DIR}/.*\\.(html|json|js)$`)
36
+
37
+
38
+ function escapeForLess(s) {
39
+ return `~"${s}"`
40
+ }
41
+
42
+ function requireFromDir(regex, path, excludeRegex) {
43
+ let filePaths = glob.sync(path + '/**')
44
+
45
+ filePaths = filePaths.filter(p => p.match(regex))
46
+ if (excludeRegex) {
47
+ filePaths = filePaths.filter(p => !p.match(excludeRegex))
48
+ }
49
+
50
+ return filePaths
51
+ }
52
+
53
+ function makeLessRule({type, theme, isProduction, appName, appFullPath, quiFullPath, appVersion, buildHash}) {
54
+ let quiRelPath = isProduction ? '' : '../qui/'
55
+
56
+ let appLessPath = path.resolve(appFullPath, LESS_DIR)
57
+ let quiLessPath = path.resolve(quiFullPath, LESS_DIR)
58
+
59
+ let appImgPath = `../${IMG_DIR}`
60
+ let appFontPath = `../${FONT_DIR}`
61
+ let quiImgPath = `${quiRelPath}${IMG_DIR}`
62
+ let quiFontPath = `${quiRelPath}${FONT_DIR}`
63
+
64
+ let appLessRegex = new RegExp(appFullPath.split('/').slice(-1)[0] + `/${LESS_DIR}/.*\\.less$`)
65
+
66
+ const lessLoader = {
67
+ loader: 'less-loader',
68
+ options: {
69
+ lessOptions: {
70
+ globalVars: {
71
+ qui_theme: theme,
72
+ app_img_path: appImgPath,
73
+ app_font_path: appFontPath,
74
+ qui_img_path: escapeForLess(quiImgPath),
75
+ qui_font_path: escapeForLess(quiFontPath),
76
+ qui_less_path: escapeForLess(quiLessPath)
77
+ }
78
+ }
79
+ }
80
+ }
81
+
82
+ const cssLoader = {
83
+ loader: 'css-loader',
84
+ options: {
85
+ url: false
86
+ }
87
+ }
88
+
89
+ const adjustCSSUrlsLoader = {
90
+ loader: path.resolve(quiFullPath, 'webpack', 'webpack-adjust-css-urls-loader.js'),
91
+ options: {
92
+ appLessPath: appLessPath,
93
+ quiLessPath: quiLessPath,
94
+ additionalDirs: 1
95
+ }
96
+ }
97
+
98
+ const fileLoader = {
99
+ loader: 'file-loader',
100
+ options: {
101
+ name: `${CSS_DIR}/${theme}/[1].css`,
102
+ regExp: /less\/(.*)\.less$/
103
+ }
104
+ }
105
+
106
+ const hashURLLoader = {
107
+ loader: 'string-replace-loader',
108
+ options: {
109
+ multiple: [
110
+ { /* URLs with query arguments */
111
+ search: 'url\\(([\'"])?(?!http)(.+?\\?.+?)([\'"])?\\)',
112
+ replace: 'url($1$2&h=' + buildHash + '$3)',
113
+ flags: 'g'
114
+ },
115
+ { /* URLs without query arguments */
116
+ search: 'url\\(([\'"])?(?!http)([^\\?]+?)([\'"])?\\)',
117
+ replace: 'url($1$2?h=' + buildHash + '$3)',
118
+ flags: 'g'
119
+ }
120
+ ]
121
+ }
122
+ }
123
+
124
+ let loaders
125
+ if (isProduction) {
126
+ loaders = [
127
+ MiniCssExtractPlugin.loader,
128
+ cssLoader,
129
+ ]
130
+ }
131
+ else { /* Development mode */
132
+ loaders = [
133
+ fileLoader,
134
+ adjustCSSUrlsLoader
135
+ ]
136
+ }
137
+
138
+ loaders.push(hashURLLoader)
139
+ loaders.push(lessLoader)
140
+
141
+ return {
142
+ test: (type === 'qui') ? QUI_LESS_REGEX : appLessRegex,
143
+ use: loaders
144
+ }
145
+ }
146
+
147
+ function makeStaticCopyRule(regex, staticDir, searchReplace = []) {
148
+ let loaders = [
149
+ {
150
+ loader: 'file-loader',
151
+ options: {
152
+ name: `${staticDir}/[name].[ext]`
153
+ }
154
+ }
155
+ ]
156
+
157
+ searchReplace = searchReplace.map(sr => ({search: sr[0], replace: sr[1]}))
158
+
159
+ if (searchReplace.length) {
160
+ loaders.push({
161
+ loader: 'string-replace-loader',
162
+ options: {
163
+ multiple: searchReplace
164
+ }
165
+ })
166
+ }
167
+
168
+ return {
169
+ test: regex,
170
+ type: 'javascript/auto', /* Disables processing of JSON files */
171
+ use: loaders
172
+ }
173
+ }
174
+
175
+ function makeLauncherIconsCmd(appFullPath, distFullPath) {
176
+ let cmds = [
177
+ `test -f ${appFullPath}/${IMG_DIR}/${LAUNCHER_ICON_SRC_NAME} || exit 0`,
178
+ `mkdir -p ${path.resolve(distFullPath, IMG_DIR)}`
179
+ ]
180
+
181
+ let srcFullPath = path.resolve(appFullPath, IMG_DIR, LAUNCHER_ICON_SRC_NAME)
182
+
183
+ LAUNCHER_ICON_SIZES.forEach(function (size) {
184
+ let iconName = LAUNCHER_ICON_NAME_TEMPLATE.replace(new RegExp('{size}', 'g'), size.toString())
185
+ let iconNameFullPath = path.resolve(distFullPath, IMG_DIR, iconName)
186
+ let cmd = RSVG_CONVERT_CMD_TEMPLATE.replace(new RegExp('{size}', 'g'), size.toString())
187
+ .replace(new RegExp('{infile}', 'g'), srcFullPath)
188
+ .replace(new RegExp('{outfile}', 'g'), iconNameFullPath)
189
+
190
+ cmds.push(cmd)
191
+ })
192
+
193
+ return cmds.join(' && ')
194
+ }
195
+
196
+ function makeJSRule({type, appFullPath}) {
197
+ let appJSRegex = new RegExp(appFullPath.split('/').slice(-1)[0] + `/${JS_DIR}/.*\\.jsm?$`)
198
+
199
+ return {
200
+ test: (type === 'qui') ? QUI_JS_REGEX : appJSRegex,
201
+ use: [
202
+ {
203
+ loader: 'babel-loader',
204
+ options: {
205
+ presets: ['@babel/preset-env'],
206
+ plugins: ['@babel/plugin-proposal-class-properties']
207
+ }
208
+ }
209
+ ]
210
+ }
211
+ }
212
+
213
+ function makeConfig({theme, isProduction, appName, appFullPath, extraFiles, cssOnly}) {
214
+ /* QUI is assumed to live in `node_modules` */
215
+ let quiFullPath = path.resolve(__dirname, '..')
216
+
217
+ let quiLessPath = path.resolve(quiFullPath, LESS_DIR)
218
+ let appLessPath = path.resolve(appFullPath, LESS_DIR)
219
+ let quiJSPath = path.resolve(quiFullPath, JS_DIR)
220
+ let appJSPath = path.resolve(appFullPath, JS_DIR)
221
+ let nodeJSPath = path.resolve(appJSPath, '..', 'node_modules')
222
+ let quiImgPath = path.resolve(quiFullPath, IMG_DIR)
223
+ let appImgPath = path.resolve(appFullPath, IMG_DIR)
224
+ let quiFontPath = path.resolve(quiFullPath, FONT_DIR)
225
+ let appFontPath = path.resolve(appFullPath, FONT_DIR)
226
+ let quiTmplPath = path.resolve(quiFullPath, TMPL_DIR)
227
+ let appTmplPath = path.resolve(appFullPath, TMPL_DIR)
228
+
229
+ /* Use project root folder in development mode, since we're only building CSS
230
+ * and we rely on every other asset to be used directly from the project folder */
231
+ let distFullPath = isProduction ? path.resolve(appFullPath, DIST_DIR) : appFullPath
232
+
233
+ let excludeLessRegex = new RegExp('theme-(' + THEMES.join('|') + ')\\.less', 'i')
234
+ let cssRequirements = [
235
+ ...requireFromDir(LESS_REGEX, quiLessPath, excludeLessRegex),
236
+ ...requireFromDir(LESS_REGEX, appLessPath, excludeLessRegex)
237
+ ]
238
+
239
+ /* This is needed because FixStyleOnlyEntriesPlugin() needs resources for theme entries to be different */
240
+ cssRequirements.push(path.resolve(quiLessPath, `theme-${theme}.less`))
241
+
242
+ let mainRequirements = [
243
+ appJSPath,
244
+
245
+ /* Add image requirements */
246
+ ...requireFromDir(IMG_REGEX, quiImgPath),
247
+ ...requireFromDir(IMG_REGEX, appImgPath),
248
+
249
+ /* Add font requirements */
250
+ ...requireFromDir(FONT_REGEX, quiFontPath),
251
+ ...requireFromDir(FONT_REGEX, appFontPath),
252
+
253
+ /* Add template requirements */
254
+ ...requireFromDir(TMPL_REGEX, quiTmplPath),
255
+ ...requireFromDir(TMPL_REGEX, appTmplPath)
256
+ ]
257
+
258
+ // TODO add extraFiles to requirements
259
+
260
+ let mainEntryName = `${appName}-bundle`
261
+ let shellCommands = []
262
+ let entries = {}
263
+ entries[`${appName}-bundle-${theme}`] = cssRequirements
264
+ if (!cssOnly && isProduction) {
265
+ entries[mainEntryName] = mainRequirements
266
+ }
267
+
268
+ if (cssOnly) {
269
+ shellCommands.push(makeLauncherIconsCmd(appFullPath, distFullPath))
270
+ }
271
+
272
+ let packageJSON = require(path.resolve(appFullPath, 'package.json'))
273
+ let appVersion = packageJSON.version
274
+ let buildHash = crypto.createHash('sha256').update(appVersion).digest('hex').substring(0, 16)
275
+
276
+ return {
277
+ entry: entries,
278
+ resolve: {
279
+ alias: {
280
+ $qui: quiJSPath,
281
+ $app: appJSPath,
282
+ $node: nodeJSPath
283
+ }
284
+ },
285
+ output: {
286
+ path: distFullPath
287
+ },
288
+ devtool: isProduction ? 'source-map' : false,
289
+ module: {
290
+ rules: [
291
+ makeLessRule({
292
+ type: 'qui', theme: theme, isProduction: isProduction,
293
+ appName: appName, appFullPath: appFullPath, quiFullPath: quiFullPath,
294
+ appVersion: appVersion, buildHash: buildHash
295
+ }),
296
+ makeLessRule({
297
+ type: 'app', theme: theme, isProduction: isProduction,
298
+ appName: appName, appFullPath: appFullPath, quiFullPath: quiFullPath,
299
+ appVersion: appVersion, buildHash: buildHash
300
+ }),
301
+ makeStaticCopyRule(IMG_REGEX, IMG_DIR),
302
+ makeStaticCopyRule(FONT_REGEX, FONT_DIR),
303
+ makeStaticCopyRule(TMPL_REGEX, TMPL_DIR, [
304
+ ['__app_name_placeholder__', appName],
305
+ ['__app_version_placeholder__', appVersion]
306
+ ]),
307
+ makeJSRule({type: 'qui', appFullPath: appFullPath}),
308
+ makeJSRule({type: 'app', appFullPath: appFullPath})
309
+ ]
310
+ },
311
+ plugins: [
312
+ new MiniCssExtractPlugin(),
313
+ new InjectPlugin(
314
+ function () {
315
+ return `window.__quiAppVersion='${appVersion}';`
316
+ },
317
+ {
318
+ entryName: mainEntryName,
319
+ entryOrder: 1 /* First */
320
+ }
321
+ ),
322
+ new FixStyleOnlyEntriesPlugin(),
323
+ new WebpackShellPlugin({
324
+ onBuildEnd: shellCommands,
325
+ safe: true
326
+ }),
327
+ new webpack.ProgressPlugin({
328
+ entries: true,
329
+ modules: true,
330
+ profile: true
331
+ }),
332
+ new webpack.ProvidePlugin({
333
+ 'jQuery': path.resolve(path.join(__dirname, '../js/lib/jquery.js')),
334
+ 'window.jQuery': path.resolve(path.join(__dirname, '../js/lib/jquery.js')),
335
+ 'window.logger': path.resolve(path.join(__dirname, '../js/lib/logger.js')),
336
+ 'window.pep': path.resolve(path.join(__dirname, '../js/lib/pep.js'))
337
+ })
338
+ ],
339
+ performance: {
340
+ maxEntrypointSize: 1024 * 1024,
341
+ maxAssetSize: 1024 * 1024
342
+ },
343
+ optimization: {
344
+ minimizer: [
345
+ new TerserPlugin({
346
+ sourceMap: true
347
+ }),
348
+ new OptimizeCssAssetsPlugin({
349
+ assetNameRegExp: /-bundle-.*\.css$/g,
350
+ cssProcessorPluginOptions: {
351
+ preset: ['default', {
352
+ discardComments: { removeAll: true },
353
+ mergeRules: false
354
+ }]
355
+ }
356
+ })
357
+ ]
358
+ }
359
+ }
360
+ }
361
+
362
+ function makeConfigs({isProduction, appName, appFullPath, extraFiles}) {
363
+ /* Repeat the configuration for each theme, but only build JS once, the first time */
364
+
365
+ return THEMES.map((theme, i) => makeConfig({
366
+ theme: theme,
367
+ isProduction: isProduction,
368
+ appName: appName,
369
+ appFullPath: appFullPath,
370
+ extraFiles: extraFiles,
371
+ cssOnly: i > 0
372
+ }))
373
+ }
374
+
375
+
376
+ module.exports = {
377
+ THEMES: THEMES,
378
+
379
+ requireFromDir: requireFromDir,
380
+ makeLessRule: makeLessRule,
381
+ makeStaticCopyRule: makeStaticCopyRule,
382
+ makeConfig: makeConfig,
383
+ makeConfigs: makeConfigs
384
+ }