├── example ├── 2.14jdf │ ├── source │ │ ├── test │ │ │ ├── js │ │ │ │ └── a.js │ │ │ ├── widget │ │ │ │ ├── css_hack │ │ │ │ │ ├── css_hack.js │ │ │ │ │ ├── css_hack.json │ │ │ │ │ ├── css_hack.vm │ │ │ │ │ ├── component.json │ │ │ │ │ └── css_hack.scss │ │ │ │ ├── js_smarty │ │ │ │ │ ├── js_smarty.js │ │ │ │ │ ├── js_smarty.scss │ │ │ │ │ ├── js_smarty.smarty │ │ │ │ │ ├── js_smarty.json │ │ │ │ │ └── component.json │ │ │ │ ├── js_seajs_use │ │ │ │ │ ├── js_seajs_use.vm │ │ │ │ │ ├── js_seajs_use.json │ │ │ │ │ ├── js_seajs_use.scss │ │ │ │ │ ├── component.json │ │ │ │ │ └── js_seajs_use.js │ │ │ │ ├── js_cmd_define │ │ │ │ │ ├── js_cmd_define.json │ │ │ │ │ ├── js_cmd_define.scss │ │ │ │ │ ├── js_cmd_define.vm │ │ │ │ │ ├── component.json │ │ │ │ │ └── js_cmd_define.js │ │ │ │ ├── sass_import_lib │ │ │ │ │ ├── sass_import_lib.js │ │ │ │ │ ├── sass_import_lib.json │ │ │ │ │ ├── sass_import_lib.vm │ │ │ │ │ ├── component.json │ │ │ │ │ ├── sass_import_lib.scss │ │ │ │ │ └── sass_lib.scss │ │ │ │ ├── css_background_url │ │ │ │ │ ├── css_background_url.js │ │ │ │ │ ├── css_background_url.json │ │ │ │ │ ├── css_background_url.vm │ │ │ │ │ ├── component.json │ │ │ │ │ └── css_background_url.scss │ │ │ │ └── css_background_sprite_base64 │ │ │ │ │ ├── css_background_sprite_base64.js │ │ │ │ │ ├── css_background_sprite_base64.json │ │ │ │ │ ├── css_background_sprite_base64.vm │ │ │ │ │ ├── component.json │ │ │ │ │ ├── i │ │ │ │ │ ├── icon1.png │ │ │ │ │ ├── icon2.png │ │ │ │ │ ├── icon3.png │ │ │ │ │ ├── icon4.png │ │ │ │ │ └── icon5.png │ │ │ │ │ └── css_background_sprite_base64.scss │ │ │ ├── result │ │ │ │ ├── js_seajs_use │ │ │ │ │ ├── js_seajs_use.vm │ │ │ │ │ ├── js_seajs_use.json │ │ │ │ │ ├── js_seajs_use.scss │ │ │ │ │ ├── component.json │ │ │ │ │ └── js_seajs_use.js │ │ │ │ ├── js_cmd_define │ │ │ │ │ ├── js_cmd_define.json │ │ │ │ │ ├── js_cmd_define.scss │ │ │ │ │ ├── js_cmd_define.vm │ │ │ │ │ ├── component.json │ │ │ │ │ └── js_cmd_define.js │ │ │ │ ├── sass_import_lib │ │ │ │ │ ├── sass_import_lib.js │ │ │ │ │ ├── sass_import_lib.json │ │ │ │ │ ├── sass_import_lib.vm │ │ │ │ │ ├── component.json │ │ │ │ │ ├── sass_import_lib.css │ │ │ │ │ └── sass_lib.scss │ │ │ │ ├── js_smarty │ │ │ │ │ └── js_smarty.html │ │ │ │ ├── css_hack │ │ │ │ │ └── css_hack.css │ │ │ │ ├── css_background_url │ │ │ │ │ └── css_background_url.css │ │ │ │ └── css_background_sprite_base64 │ │ │ │ │ └── css_background_sprite_base64.css │ │ │ ├── index.js │ │ │ ├── config.json │ │ │ ├── jdf_output_html.js │ │ │ ├── html │ │ │ │ └── index.html │ │ │ └── jdf_output.js │ │ ├── template │ │ │ ├── .eslintignore │ │ │ ├── .prettierrc │ │ │ ├── config.json │ │ │ └── .editorconfig │ │ ├── bin │ │ │ └── jdf │ │ ├── .npmignore │ │ ├── .gitignore │ │ ├── index.js │ │ ├── .travis.yml │ │ ├── lib │ │ │ ├── buildByAutoprefixer.js │ │ │ ├── findPort.js │ │ │ ├── fileWorker.js │ │ │ ├── wx.js │ │ │ ├── concat.js │ │ │ ├── base64.js │ │ │ ├── compressWorker.js │ │ │ ├── openurl.js │ │ │ ├── log.js │ │ │ ├── buildJs.js │ │ │ ├── fileFormat.js │ │ │ ├── csslint.js │ │ │ ├── vm.js │ │ │ ├── compressScheduler.js │ │ │ └── buildCss.js │ │ ├── doc │ │ │ ├── a_tool_livereload.md │ │ │ ├── core_tpl.md │ │ │ ├── a_tool_develop.md │ │ │ ├── a_tool_server.md │ │ │ ├── core_smarty.md │ │ │ ├── a_tool_weinre.md │ │ │ ├── a_tool_command.md │ │ │ ├── a_tool_format.md │ │ │ ├── core_dir_standard.md │ │ │ ├── core_widget.md │ │ │ ├── a_tool_lint.md │ │ │ ├── core_vm.md │ │ │ ├── core_css.md │ │ │ ├── a_tool_csssprite.md │ │ │ └── core_js.md │ │ ├── package.json │ │ └── README.md │ └── example │ │ ├── .eslintignore │ │ ├── .prettierrc │ │ ├── config.json │ │ └── .editorconfig ├── 3.8node_universal │ ├── README.md │ ├── .babelrc │ ├── cmrh.conf.js │ ├── public │ │ ├── favicon.ico │ │ └── style.css │ ├── src │ │ ├── constants.js │ │ ├── utils.js │ │ ├── components │ │ │ ├── Footer │ │ │ │ ├── Footer.css │ │ │ │ └── Footer.js │ │ │ └── Header │ │ │ │ ├── Header.css │ │ │ │ └── Header.js │ │ ├── routes.js │ │ ├── containers │ │ │ ├── Home.js │ │ │ └── App.js │ │ ├── store.js │ │ └── styles │ │ │ └── base.css │ ├── server.js │ ├── index.dev.html │ ├── client.js │ ├── server.dev.js │ ├── webpack.config.dev.js │ ├── webpack.config.prod.js │ ├── package.json │ └── server.prod.js ├── 2.2sqip │ ├── package.json │ ├── in.png │ ├── index.js │ └── index.html ├── 2.2lqip │ ├── in.png │ ├── package.json │ ├── index.js │ └── index.html ├── 2.5css │ ├── Snip.png │ └── index.html ├── 2.2gifsicle │ ├── in.gif │ └── out.gif ├── 2.2jpegtran │ ├── in.jpg │ └── out.jpg ├── 4.iOSWebView │ ├── Snip.png │ ├── iOSWebView │ │ ├── JSSDKViewControllerBase │ │ │ ├── WebViewJavascriptBridge_JS.h │ │ │ ├── WKWebViewJavascriptBridge.h │ │ │ ├── WebViewJavascriptBridgeBase.h │ │ │ └── WebViewJavascriptBridge.h │ │ ├── homeViewController.h │ │ ├── UIWebViewController.h │ │ ├── globalViewController.h │ │ ├── loginViewController.h │ │ ├── navBarController.h │ │ ├── navViewController.h │ │ ├── normalViewController.h │ │ ├── JSSDKSchemeViewController.h │ │ ├── JSSDKWebKitViewController.h │ │ ├── normalWebViewViewController.h │ │ ├── progressViewController.h │ │ ├── JSSDKScheme.html │ │ ├── main.m │ │ ├── JSSDKIframeViewController.h │ │ ├── AppDelegate.h │ │ ├── myProgressViewController.h │ │ ├── navViewController.m │ │ ├── normalViewController.m │ │ ├── UIWebViewController.m │ │ ├── Assets.xcassets │ │ │ └── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ ├── Info.plist │ │ ├── JSSDKWebKit.html │ │ ├── normalWebViewViewController.m │ │ ├── Base.lproj │ │ │ ├── Main.storyboard │ │ │ └── LaunchScreen.storyboard │ │ ├── globalWebViewBase │ │ │ ├── Source │ │ │ │ ├── WKWebView + HPKDelegateExtension.h │ │ │ │ ├── HPKCommonViewPool.h │ │ │ │ ├── WKWebView + HPKReusable.h │ │ │ │ ├── HPKWebViewPool.h │ │ │ │ ├── HPKDefaultWebViewControl.h │ │ │ │ ├── _HPKUtils.h │ │ │ │ ├── HPKWebViewExtensionDelegate.h │ │ │ │ ├── WKWebView + HPKExtension.h │ │ │ │ ├── HPKScrollProcessor.h │ │ │ │ ├── HPKPageManager.m │ │ │ │ └── _HPKAspects.h │ │ │ └── HPKViewProtocol.h │ │ ├── globalViewController.m │ │ ├── AppDelegate.m │ │ ├── login.html │ │ ├── JSSDKSchemeViewController.m │ │ ├── JSSDKIframe.html │ │ └── JSSDKIframeViewController.m │ └── iOSWebView.xcodeproj │ │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcshareddata │ │ └── xcschemes │ │ └── wkWebView.xcscheme ├── 3.3velocityjs │ ├── package.json │ └── index.js ├── 3.9pwa │ ├── public │ │ ├── favicon.png │ │ ├── style.css │ │ ├── manifest.json │ │ ├── index.html │ │ └── sw.js │ ├── package.json │ └── index.js ├── 2.2node-pngquant-native │ ├── package.json │ ├── in.png │ ├── out.png │ └── index.js ├── 3.7bigpipe │ ├── test2.js │ └── index.php ├── 3.6spa │ └── angular.html ├── 2.8js_moudules │ └── index.js ├── 5.nginx_config │ └── nginx.conf ├── 2.15webpack │ └── webpack.dev.dll.js └── 3.11lazyload │ └── lazyload.html ├── ppt ├── 第二章:静态资源优化.pdf ├── 第四章:原生App优化.pdf ├── 第五章:服务端和网络优化.pdf ├── 第六章:研发开发流程优化.pdf ├── 第七章:全链路质量监控体系建设.pdf └── 第三章:页面渲染架构设计与性能优化.pdf ├── README.md ├── .gitignore └── LICENSE /example/2.14jdf/source/test/js/a.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/2.14jdf/example/.eslintignore: -------------------------------------------------------------------------------- 1 | /build/ -------------------------------------------------------------------------------- /example/2.14jdf/source/template/.eslintignore: -------------------------------------------------------------------------------- 1 | /build/ -------------------------------------------------------------------------------- /example/3.8node_universal/README.md: -------------------------------------------------------------------------------- 1 | ## node_universal -------------------------------------------------------------------------------- /example/2.14jdf/source/test/widget/css_hack/css_hack.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/2.14jdf/source/test/widget/css_hack/css_hack.json: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/2.14jdf/source/test/widget/css_hack/css_hack.vm: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/2.14jdf/source/test/widget/js_smarty/js_smarty.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/2.14jdf/source/test/result/js_seajs_use/js_seajs_use.vm: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/2.14jdf/source/test/widget/js_seajs_use/js_seajs_use.vm: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/2.14jdf/source/test/widget/js_smarty/js_smarty.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/2.14jdf/source/test/result/js_cmd_define/js_cmd_define.json: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/2.14jdf/source/test/result/js_cmd_define/js_cmd_define.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/2.14jdf/source/test/result/js_cmd_define/js_cmd_define.vm: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/2.14jdf/source/test/result/js_seajs_use/js_seajs_use.json: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/2.14jdf/source/test/result/js_seajs_use/js_seajs_use.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/2.14jdf/source/test/widget/js_cmd_define/js_cmd_define.json: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/2.14jdf/source/test/widget/js_cmd_define/js_cmd_define.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/2.14jdf/source/test/widget/js_cmd_define/js_cmd_define.vm: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/2.14jdf/source/test/widget/js_seajs_use/js_seajs_use.json: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/2.14jdf/source/test/widget/js_seajs_use/js_seajs_use.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/2.14jdf/source/test/result/sass_import_lib/sass_import_lib.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/2.14jdf/source/test/result/sass_import_lib/sass_import_lib.json: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/2.14jdf/source/test/result/sass_import_lib/sass_import_lib.vm: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/2.14jdf/source/test/widget/sass_import_lib/sass_import_lib.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/2.14jdf/source/test/widget/sass_import_lib/sass_import_lib.json: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/2.14jdf/source/test/widget/sass_import_lib/sass_import_lib.vm: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/2.14jdf/source/test/result/js_smarty/js_smarty.html: -------------------------------------------------------------------------------- 1 | Hello js_smarty -------------------------------------------------------------------------------- /example/2.14jdf/source/test/widget/css_background_url/css_background_url.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/2.14jdf/source/test/widget/css_background_url/css_background_url.json: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/2.14jdf/source/test/widget/css_background_url/css_background_url.vm: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/2.14jdf/source/test/widget/js_smarty/js_smarty.smarty: -------------------------------------------------------------------------------- 1 | Hello {$name} -------------------------------------------------------------------------------- /example/2.14jdf/source/test/widget/js_smarty/js_smarty.json: -------------------------------------------------------------------------------- 1 | {"name": "js_smarty"} -------------------------------------------------------------------------------- /example/2.14jdf/example/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "semi": true 4 | } 5 | -------------------------------------------------------------------------------- /example/2.14jdf/source/bin/jdf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | require('../index.js').init(process.argv); -------------------------------------------------------------------------------- /example/2.14jdf/source/test/widget/css_background_sprite_base64/css_background_sprite_base64.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/2.14jdf/source/test/widget/css_background_sprite_base64/css_background_sprite_base64.json: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/2.14jdf/source/test/widget/css_background_sprite_base64/css_background_sprite_base64.vm: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/2.14jdf/source/.npmignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | npm-debug.log 3 | .svn 4 | .DS_Store 5 | test/build -------------------------------------------------------------------------------- /example/2.14jdf/source/template/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "semi": true 4 | } 5 | -------------------------------------------------------------------------------- /ppt/第二章:静态资源优化.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-fepo-course/HEAD/ppt/第二章:静态资源优化.pdf -------------------------------------------------------------------------------- /ppt/第四章:原生App优化.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-fepo-course/HEAD/ppt/第四章:原生App优化.pdf -------------------------------------------------------------------------------- /example/2.2sqip/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sqip", 3 | "dependencies": { 4 | "lqip": "0.3.3" 5 | } 6 | } -------------------------------------------------------------------------------- /ppt/第五章:服务端和网络优化.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-fepo-course/HEAD/ppt/第五章:服务端和网络优化.pdf -------------------------------------------------------------------------------- /ppt/第六章:研发开发流程优化.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-fepo-course/HEAD/ppt/第六章:研发开发流程优化.pdf -------------------------------------------------------------------------------- /example/2.2lqip/in.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-fepo-course/HEAD/example/2.2lqip/in.png -------------------------------------------------------------------------------- /example/2.2lqip/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lqip", 3 | "dependencies": { 4 | "lqip": "2.1.0" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /example/2.2sqip/in.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-fepo-course/HEAD/example/2.2sqip/in.png -------------------------------------------------------------------------------- /example/2.5css/Snip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-fepo-course/HEAD/example/2.5css/Snip.png -------------------------------------------------------------------------------- /ppt/第七章:全链路质量监控体系建设.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-fepo-course/HEAD/ppt/第七章:全链路质量监控体系建设.pdf -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # geek-fepo-course 2 | 3 | 极客时间《前端全链路性能优化实战》视频课程PPT和实例源码 4 | 5 | 注fepo:(Front-end performance optimization) 6 | -------------------------------------------------------------------------------- /example/2.2gifsicle/in.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-fepo-course/HEAD/example/2.2gifsicle/in.gif -------------------------------------------------------------------------------- /example/2.2jpegtran/in.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-fepo-course/HEAD/example/2.2jpegtran/in.jpg -------------------------------------------------------------------------------- /ppt/第三章:页面渲染架构设计与性能优化.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-fepo-course/HEAD/ppt/第三章:页面渲染架构设计与性能优化.pdf -------------------------------------------------------------------------------- /example/2.14jdf/source/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | npm-debug.log 3 | .svn 4 | .idea 5 | .DS_Store 6 | test/build 7 | temp -------------------------------------------------------------------------------- /example/2.2gifsicle/out.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-fepo-course/HEAD/example/2.2gifsicle/out.gif -------------------------------------------------------------------------------- /example/2.2jpegtran/out.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-fepo-course/HEAD/example/2.2jpegtran/out.jpg -------------------------------------------------------------------------------- /example/3.8node_universal/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "es2015", 4 | "react", 5 | "stage-1" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /example/3.8node_universal/cmrh.conf.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | generateScopedName: '[name]_[local]__[hash:base64:5]', 3 | }; -------------------------------------------------------------------------------- /example/4.iOSWebView/Snip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-fepo-course/HEAD/example/4.iOSWebView/Snip.png -------------------------------------------------------------------------------- /example/2.14jdf/example/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "host": "ftpServerIp", 3 | "user": "", 4 | "password": "", 5 | "projectPath": "" 6 | } -------------------------------------------------------------------------------- /example/2.14jdf/source/test/index.js: -------------------------------------------------------------------------------- 1 | // require('./jdf_output'); 2 | // require('./jdf_output_html'); 3 | console.log('jdf test'); -------------------------------------------------------------------------------- /example/3.3velocityjs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "velocityjs", 3 | "dependencies": { 4 | "velocityjs": "2.0.0" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /example/3.9pwa/public/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-fepo-course/HEAD/example/3.9pwa/public/favicon.png -------------------------------------------------------------------------------- /example/2.14jdf/source/template/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "host": "ftpServerIp", 3 | "user": "", 4 | "password": "", 5 | "projectPath": "" 6 | } -------------------------------------------------------------------------------- /example/2.14jdf/source/test/widget/css_hack/component.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "css_hack", 3 | "version": "1.0.0", 4 | "dependencies": {} 5 | } -------------------------------------------------------------------------------- /example/2.14jdf/source/test/widget/js_smarty/component.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "js_smarty", 3 | "version": "1.0.0", 4 | "dependencies": {} 5 | } -------------------------------------------------------------------------------- /example/2.2node-pngquant-native/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pngquant", 3 | "dependencies": { 4 | "jdf-png-native": "1.1.0" 5 | } 6 | } -------------------------------------------------------------------------------- /example/2.14jdf/source/test/result/js_seajs_use/component.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "js_seajs_use", 3 | "version": "1.0.0", 4 | "dependencies": {} 5 | } -------------------------------------------------------------------------------- /example/2.14jdf/source/test/widget/js_seajs_use/component.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "js_seajs_use", 3 | "version": "1.0.0", 4 | "dependencies": {} 5 | } -------------------------------------------------------------------------------- /example/2.2node-pngquant-native/in.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-fepo-course/HEAD/example/2.2node-pngquant-native/in.png -------------------------------------------------------------------------------- /example/2.2node-pngquant-native/out.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-fepo-course/HEAD/example/2.2node-pngquant-native/out.png -------------------------------------------------------------------------------- /example/2.14jdf/source/test/result/js_cmd_define/component.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "js_cmd_define", 3 | "version": "1.0.0", 4 | "dependencies": {} 5 | } -------------------------------------------------------------------------------- /example/2.14jdf/source/test/result/sass_import_lib/component.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "scss_import_lib", 3 | "version": "1.0.0", 4 | "dependencies": {} 5 | } -------------------------------------------------------------------------------- /example/2.14jdf/source/test/widget/js_cmd_define/component.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "js_cmd_define", 3 | "version": "1.0.0", 4 | "dependencies": {} 5 | } -------------------------------------------------------------------------------- /example/2.14jdf/source/test/widget/sass_import_lib/component.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "scss_import_lib", 3 | "version": "1.0.0", 4 | "dependencies": {} 5 | } -------------------------------------------------------------------------------- /example/2.14jdf/source/index.js: -------------------------------------------------------------------------------- 1 | var jdf = require('./lib/jdf.js'); 2 | 3 | module.exports = { 4 | init: function(argv) { 5 | jdf.init(argv); 6 | } 7 | }; -------------------------------------------------------------------------------- /example/3.8node_universal/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-fepo-course/HEAD/example/3.8node_universal/public/favicon.ico -------------------------------------------------------------------------------- /example/2.14jdf/source/test/widget/css_background_url/component.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "css_background_url", 3 | "version": "1.0.0", 4 | "dependencies": {} 5 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | npm-debug.log 3 | package-lock.json 4 | .idea 5 | .DS_Store 6 | 7 | .gitmodules 8 | xcuserdata 9 | *.xcuserdatad 10 | *.xcuserstate -------------------------------------------------------------------------------- /example/2.14jdf/source/.travis.yml: -------------------------------------------------------------------------------- 1 | os: 2 | - linux 3 | - osx 4 | language: node_js 5 | node_js: 6 | - "4.2.6" 7 | - "5" 8 | - "6" 9 | - "6.9.4" 10 | -------------------------------------------------------------------------------- /example/3.7bigpipe/test2.js: -------------------------------------------------------------------------------- 1 | function test2(id, message) { 2 | $(id).innerHTML = message; 3 | } 4 | 5 | if (BigPipe != undefined) { BigPipe.fileLoaded("test2.js"); } 6 | -------------------------------------------------------------------------------- /example/3.8node_universal/src/constants.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | RECEIVE_WEATHERITEMINFO: 'RECEIVE_WEATHERITEMINFO', 3 | RECEIVE_WEATHERCITY: 'RECEIVE_WEATHERCITY' 4 | } 5 | -------------------------------------------------------------------------------- /example/4.iOSWebView/iOSWebView/JSSDKViewControllerBase/WebViewJavascriptBridge_JS.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | NSString * WebViewJavascriptBridge_js(void); 4 | -------------------------------------------------------------------------------- /example/2.14jdf/source/test/widget/css_background_sprite_base64/component.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "css_background_sprite_base64", 3 | "version": "1.0.0", 4 | "dependencies": {} 5 | } -------------------------------------------------------------------------------- /example/2.14jdf/source/test/widget/sass_import_lib/sass_import_lib.scss: -------------------------------------------------------------------------------- 1 | @import "sass_lib"; 2 | 3 | .test1{ 4 | width: 100px; 5 | height: 100px; 6 | @include border-radius(10px); 7 | } -------------------------------------------------------------------------------- /example/3.8node_universal/src/utils.js: -------------------------------------------------------------------------------- 1 | function isEmpty (data) { 2 | if(data === undefined || !Object.keys(data).length ){ 3 | return true 4 | } 5 | return false 6 | } 7 | 8 | module.exports = { isEmpty } -------------------------------------------------------------------------------- /example/2.14jdf/source/test/result/sass_import_lib/sass_import_lib.css: -------------------------------------------------------------------------------- 1 | .test1{width:100px;height:100px;-webkit-border-radius:10px;-moz-border-radius:10px;-ms-border-radius:10px;-o-border-radius:10px;border-radius:10px} -------------------------------------------------------------------------------- /example/2.2sqip/index.js: -------------------------------------------------------------------------------- 1 | const sqip = require('sqip'); 2 | 3 | const result = sqip({ 4 | filename: './in.png', 5 | numberOfPrimitives: 10 6 | }); 7 | 8 | console.log(result.final_svg); 9 | 10 | -------------------------------------------------------------------------------- /example/2.14jdf/source/test/widget/css_background_sprite_base64/i/icon1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-fepo-course/HEAD/example/2.14jdf/source/test/widget/css_background_sprite_base64/i/icon1.png -------------------------------------------------------------------------------- /example/2.14jdf/source/test/widget/css_background_sprite_base64/i/icon2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-fepo-course/HEAD/example/2.14jdf/source/test/widget/css_background_sprite_base64/i/icon2.png -------------------------------------------------------------------------------- /example/2.14jdf/source/test/widget/css_background_sprite_base64/i/icon3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-fepo-course/HEAD/example/2.14jdf/source/test/widget/css_background_sprite_base64/i/icon3.png -------------------------------------------------------------------------------- /example/2.14jdf/source/test/widget/css_background_sprite_base64/i/icon4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-fepo-course/HEAD/example/2.14jdf/source/test/widget/css_background_sprite_base64/i/icon4.png -------------------------------------------------------------------------------- /example/2.14jdf/source/test/widget/css_background_sprite_base64/i/icon5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geek-fepo-course/HEAD/example/2.14jdf/source/test/widget/css_background_sprite_base64/i/icon5.png -------------------------------------------------------------------------------- /example/2.14jdf/source/test/widget/js_seajs_use/js_seajs_use.js: -------------------------------------------------------------------------------- 1 | 2 | seajs.use(["test1.js", "/test2.js",], function(a, b){ 3 | 4 | }); 5 | 6 | seajs.use(["jdf/1.0.0/unit/globalInit/2.0.0/globalInit.js"], function(globalInit){ 7 | 8 | }); -------------------------------------------------------------------------------- /example/3.9pwa/public/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin-left: 5%; 3 | margin-right: 5%; 4 | } 5 | 6 | #sw-status { 7 | background-color: #54fb0f; 8 | position: fixed; 9 | top: 0; 10 | left: 0; 11 | right: 0; 12 | text-align: center; 13 | } -------------------------------------------------------------------------------- /example/2.14jdf/source/test/result/js_seajs_use/js_seajs_use.js: -------------------------------------------------------------------------------- 1 | seajs.use(["http://misc.360buyimg.com/test1.js","http://misc.360buyimg.com/jdf-test/test2.js"],function(){}),seajs.use(["http://misc.360buyimg.com/jdf/1.0.0/unit/globalInit/2.0.0/globalInit.js"],function(){}); -------------------------------------------------------------------------------- /example/2.2lqip/index.js: -------------------------------------------------------------------------------- 1 | const lqip = require('lqip'); 2 | 3 | const file = './in.png'; 4 | 5 | //image 6 | lqip.base64(file).then(res => { 7 | console.log(res); 8 | }); 9 | 10 | //color 11 | lqip.palette(file).then(res => { 12 | console.log(res); 13 | }); 14 | -------------------------------------------------------------------------------- /example/3.8node_universal/src/components/Footer/Footer.css: -------------------------------------------------------------------------------- 1 | .footer { 2 | /*position: fixed; 3 | bottom: 0px;*/ 4 | width: 100%; 5 | padding: 0.5em 0; 6 | background-color: #eee; 7 | text-align: center; 8 | } 9 | 10 | .footer span { 11 | color: #000; 12 | } -------------------------------------------------------------------------------- /example/2.14jdf/source/test/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "host": "page.jd.com", 3 | "user": "arch", 4 | "password": "arch", 5 | "projectPath": "jdf-test", 6 | "output": { 7 | "hasBanner":0, 8 | "jsUrlReplace": true, 9 | "combineWidgetCss": false, 10 | "base64": true 11 | } 12 | } -------------------------------------------------------------------------------- /example/2.14jdf/source/test/result/sass_import_lib/sass_lib.scss: -------------------------------------------------------------------------------- 1 | @mixin border-radius($radius) { 2 | -webkit-border-radius: $radius; 3 | -moz-border-radius: $radius; 4 | -ms-border-radius: $radius; 5 | -o-border-radius: $radius; 6 | border-radius: $radius; 7 | } -------------------------------------------------------------------------------- /example/2.14jdf/source/test/widget/sass_import_lib/sass_lib.scss: -------------------------------------------------------------------------------- 1 | @mixin border-radius($radius) { 2 | -webkit-border-radius: $radius; 3 | -moz-border-radius: $radius; 4 | -ms-border-radius: $radius; 5 | -o-border-radius: $radius; 6 | border-radius: $radius; 7 | } -------------------------------------------------------------------------------- /example/4.iOSWebView/iOSWebView/homeViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // homeViewController.h 3 | // iOSWebView 4 | // 5 | // Copyright © 2019 putaoshu. Licensed under the MIT license. 6 | // 7 | 8 | #import 9 | 10 | @interface homeViewController : UIViewController 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /example/3.8node_universal/server.js: -------------------------------------------------------------------------------- 1 | require('babel-core/register'); 2 | require('css-modules-require-hook/preset'); 3 | 4 | var env = process.env.NODE_ENV || 'prod' 5 | 6 | if(env === 'prod'){ 7 | var app = require("./server.prod.js"); 8 | } else { 9 | var app = require("./server.dev.js"); 10 | } -------------------------------------------------------------------------------- /example/4.iOSWebView/iOSWebView.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/4.iOSWebView/iOSWebView/UIWebViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIWebViewController.h 3 | // iOSWebView 4 | // 5 | // Copyright © 2019 putaoshu. Licensed under the MIT license. 6 | // 7 | #import 8 | 9 | @interface UIWebViewController : UIViewController 10 | 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /example/4.iOSWebView/iOSWebView/globalViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // globalViewController.h 3 | // iOSWebView 4 | // 5 | // Copyright © 2019 putaoshu. Licensed under the MIT license. 6 | // 7 | 8 | #import 9 | 10 | @interface globalViewController : UIViewController 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /example/4.iOSWebView/iOSWebView/loginViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // loginViewController.h 3 | // iOSWebView 4 | // 5 | // Copyright © 2019 putaoshu. Licensed under the MIT license. 6 | // 7 | 8 | #import 9 | 10 | @interface loginViewController : UIViewController 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /example/4.iOSWebView/iOSWebView/navBarController.h: -------------------------------------------------------------------------------- 1 | // 2 | // navBarController.h 3 | // iOSWebView 4 | // 5 | // Copyright © 2019 putaoshu. Licensed under the MIT license. 6 | // 7 | 8 | #import 9 | 10 | @interface navBarController : UIViewController 11 | 12 | 13 | @end 14 | 15 | -------------------------------------------------------------------------------- /example/4.iOSWebView/iOSWebView/navViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // navViewController.h 3 | // iOSWebView 4 | // 5 | // Copyright © 2019 putaoshu. Licensed under the MIT license. 6 | // 7 | 8 | #import 9 | 10 | @interface navViewController : UINavigationController 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /example/4.iOSWebView/iOSWebView/normalViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // normalViewController.h 3 | // iOSWebView 4 | // 5 | // Copyright © 2019 putaoshu. Licensed under the MIT license. 6 | // 7 | 8 | #import 9 | 10 | @interface normalViewController : UIViewController 11 | 12 | @end 13 | 14 | -------------------------------------------------------------------------------- /example/4.iOSWebView/iOSWebView/JSSDKSchemeViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // JSSDKSchemeViewController.h 3 | // iOSWebView 4 | // 5 | // Copyright © 2019 putaoshu. Licensed under the MIT license. 6 | // 7 | 8 | #import 9 | 10 | @interface JSSDKSchemeViewController : UIViewController 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /example/4.iOSWebView/iOSWebView/JSSDKWebKitViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // JSSDKWebKitViewController.h 3 | // iOSWebView 4 | // 5 | // Copyright © 2019 putaoshu. Licensed under the MIT license. 6 | // 7 | 8 | #import 9 | 10 | @interface JSSDKWebKitViewController : UIViewController 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /example/4.iOSWebView/iOSWebView/normalWebViewViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // normalWebViewViewController.h 3 | // iOSWebView 4 | // 5 | // Copyright © 2019 putaoshu. Licensed under the MIT license. 6 | // 7 | 8 | #import 9 | 10 | @interface normalWebViewViewController : UIViewController 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /example/3.8node_universal/src/components/Header/Header.css: -------------------------------------------------------------------------------- 1 | .header { 2 | /*position: fixed; 3 | top: 0px;*/ 4 | width: 100%; 5 | background-color: #F0F8FF; 6 | text-align: center; 7 | padding: 1em 0; 8 | } 9 | 10 | .header a{ 11 | color: #61dafb; 12 | } 13 | 14 | .header .todo{ 15 | color: #999; 16 | } 17 | -------------------------------------------------------------------------------- /example/4.iOSWebView/iOSWebView/progressViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // progressViewController.h 3 | // iOSWebView 4 | // 5 | // Copyright © 2019 putaoshu. Licensed under the MIT license. 6 | // 7 | 8 | #import 9 | 10 | @interface progressViewController : UIViewController 11 | 12 | 13 | @end 14 | 15 | 16 | -------------------------------------------------------------------------------- /example/3.8node_universal/src/components/Header/Header.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Link } from 'react-router' 3 | import styles from './Header.css' 4 | 5 | function Header() { 6 | return ( 7 |
8 | Weather 9 |
10 | ) 11 | } 12 | 13 | export default Header -------------------------------------------------------------------------------- /example/4.iOSWebView/iOSWebView/JSSDKScheme.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | myjssdk - login 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /example/4.iOSWebView/iOSWebView/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // wkWebView 4 | // 5 | // 6 | 7 | #import 8 | #import "AppDelegate.h" 9 | 10 | int main(int argc, char * argv[]) { 11 | @autoreleasepool { 12 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /example/4.iOSWebView/iOSWebView/JSSDKIframeViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // JSSDKIframeViewController.h 3 | // iOSWebView 4 | // 5 | // Copyright © 2019 putaoshu. Licensed under the MIT license. 6 | // 7 | 8 | #import 9 | #import 10 | 11 | @interface JSSDKIframeViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /example/4.iOSWebView/iOSWebView.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/4.iOSWebView/iOSWebView/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // iOSWebView 4 | // 5 | // Copyright © 2019 putaoshu. Licensed under the MIT license. 6 | // 7 | 8 | #import 9 | 10 | @interface AppDelegate : UIResponder 11 | 12 | @property (strong, nonatomic) UIWindow *window; 13 | 14 | 15 | @end 16 | 17 | -------------------------------------------------------------------------------- /example/3.8node_universal/src/routes.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Route, IndexRoute, Link } from 'react-router' 3 | 4 | import App from './containers/App' 5 | import Home from './containers/Home' 6 | 7 | const routes = ( 8 | 9 | 10 | 11 | ) 12 | 13 | export default routes 14 | -------------------------------------------------------------------------------- /example/2.14jdf/source/test/result/css_hack/css_hack.css: -------------------------------------------------------------------------------- 1 | .test1{background:none\9\0} 2 | .test2{background:none\9} 3 | .test3{background:none\0} 4 | .test4{*width:100px} 5 | .test5{_width:100px} 6 | .test6{width:100px} 7 | .test7{-webkit-border-radius:10px} 8 | .test8{-moz-border-radius:10px} 9 | .test9{width:expression(eval(document.documentElement.scrollTop))} 10 | .test10 * div{width:100px} -------------------------------------------------------------------------------- /example/4.iOSWebView/iOSWebView/myProgressViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // myProgressViewController.h 3 | // iOSWebView 4 | // 5 | // Copyright © 2019 putaoshu. Licensed under the MIT license. 6 | // 7 | 8 | #import 9 | 10 | @interface myProgressViewController : UIViewController 11 | 12 | //- (void)startAnimate; 13 | //- (void)interruptCurrentAnimationAndFinished; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /example/3.9pwa/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pwa-demo", 3 | "version": "1.0.0", 4 | "description": "pwa demo", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "node index.js" 8 | }, 9 | "dependencies": { 10 | "chokidar": "^1.6.1", 11 | "express": "^4.15.2", 12 | "sw-precache": "^5.0.0", 13 | "compression": "^1.6.2" 14 | }, 15 | "engines": { 16 | "node": "6.9.x" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /example/2.2node-pngquant-native/index.js: -------------------------------------------------------------------------------- 1 | // var pngquant = require('node-pngquant-native'); 2 | var pngquant = require('jdf-png-native'); 3 | var fs = require('fs'); 4 | 5 | fs.readFile('./in.png', function(err, buffer) { 6 | if (err) throw err; 7 | 8 | var resBuffer = pngquant.option({}).compress(buffer); 9 | 10 | fs.writeFile('./out.png', resBuffer, { 11 | flags: 'wb' 12 | }, function(err) {}); 13 | }); -------------------------------------------------------------------------------- /example/4.iOSWebView/iOSWebView/navViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // navViewController.m 3 | // iOSWebView 4 | // 5 | // Copyright © 2019 putaoshu. Licensed under the MIT license. 6 | // 7 | 8 | #import "navViewController.h" 9 | 10 | @interface navViewController () 11 | 12 | @end 13 | 14 | @implementation navViewController 15 | 16 | - (void)viewDidLoad { 17 | [super viewDidLoad]; 18 | 19 | } 20 | 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /example/3.9pwa/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "PWA Demo", 3 | "icons": [{ 4 | "src": "https://cdn0.iconfinder.com/data/icons/green-world-colored/80/battery-energy-charger-charging-electric-station-tesla-256.png", 5 | "sizes": "192x192", 6 | "type": "image/png" 7 | }], 8 | "start_url": "/index.html", 9 | "display": "standalone", 10 | "theme_color": "#ffffff", 11 | "background_color": "#ffffff" 12 | } -------------------------------------------------------------------------------- /example/2.14jdf/source/lib/buildByAutoprefixer.js: -------------------------------------------------------------------------------- 1 | var autoprefixer = require('autoprefixer'); 2 | var postcss = require('postcss'); 3 | var cssnext = require('cssnext'); 4 | var f = require('./file'); 5 | 6 | var doAutoprefixer = module.exports = {}; 7 | doAutoprefixer.init = function(file, options){ 8 | var contents = postcss([autoprefixer(options), cssnext]).process(file.contents).css; 9 | f.write(file.path, contents); 10 | } 11 | 12 | -------------------------------------------------------------------------------- /example/3.8node_universal/src/components/Footer/Footer.js: -------------------------------------------------------------------------------- 1 | import React, { Component, PropTypes } from 'react' 2 | import styles from './Footer.css' 3 | 4 | export default class Footer extends Component { 5 | 6 | constructor (props) { 7 | super(props) 8 | } 9 | 10 | render () { 11 | return ( 12 |
13 | Copyright © Weather.com 14 |
15 | ) 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /example/2.14jdf/source/test/widget/css_background_sprite_base64/css_background_sprite_base64.scss: -------------------------------------------------------------------------------- 1 | //sprite 2 | .test1{ 3 | background: url(i/icon1.png?__sprite); 4 | } 5 | 6 | .test2{ 7 | background: url(i/icon2.png?__sprite); 8 | } 9 | 10 | .test3{ 11 | background: url(i/icon3.png?__sprite); 12 | } 13 | 14 | .test4{ 15 | background: url(i/icon4.png?__sprite); 16 | } 17 | 18 | //base64 19 | .test5{ 20 | background: url(i/icon5.png?__base64); 21 | } -------------------------------------------------------------------------------- /example/2.14jdf/source/test/widget/js_cmd_define/js_cmd_define.js: -------------------------------------------------------------------------------- 1 | define(function(require, exports, module){ 2 | var a = require('a.js'); 3 | 4 | var b = require('./b.js'); 5 | 6 | var c = require('../c.js'); 7 | 8 | var d = require('js/d.js'); 9 | 10 | var e = require('/js/e.js'); 11 | 12 | var globalInit = require('jdf/1.0.0/unit/globalInit/2.0.0/globalInit.js'); 13 | 14 | }); 15 | 16 | 17 | define('js_cmd_define.js', ['a.js', '/b.js'], function(require, exports, module){ 18 | 19 | }) -------------------------------------------------------------------------------- /example/2.14jdf/source/lib/findPort.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @find Port 3 | */ 4 | var net = require('net'); 5 | module.exports = function (port, callback) { 6 | var server = net.createServer().listen(port); 7 | server.on('listening',function() { 8 | if (server) server.close(); 9 | callback(true, port); 10 | }); 11 | 12 | server.on('error',function(err) { 13 | var result = true; 14 | if (err.code === 'EADDRINUSE' || err.code === 'EACCES') result = false; 15 | callback(result, port); 16 | }); 17 | } 18 | -------------------------------------------------------------------------------- /example/3.8node_universal/index.dev.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | weather 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /example/2.14jdf/example/.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # editorconfig.org 4 | 5 | root = true 6 | 7 | 8 | [*] 9 | 10 | # Change these settings to your own preference 11 | indent_style = space 12 | indent_size = 2 13 | 14 | # We recommend you to keep these unchanged 15 | end_of_line = lf 16 | charset = utf-8 17 | trim_trailing_whitespace = true 18 | insert_final_newline = true 19 | 20 | [*.md] 21 | trim_trailing_whitespace = false 22 | -------------------------------------------------------------------------------- /example/2.14jdf/source/template/.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # editorconfig.org 4 | 5 | root = true 6 | 7 | 8 | [*] 9 | 10 | # Change these settings to your own preference 11 | indent_style = space 12 | indent_size = 2 13 | 14 | # We recommend you to keep these unchanged 15 | end_of_line = lf 16 | charset = utf-8 17 | trim_trailing_whitespace = true 18 | insert_final_newline = true 19 | 20 | [*.md] 21 | trim_trailing_whitespace = false 22 | -------------------------------------------------------------------------------- /example/2.14jdf/source/test/widget/css_background_url/css_background_url.scss: -------------------------------------------------------------------------------- 1 | .test1{ 2 | background: url(i/test.png); 3 | } 4 | 5 | .test2{ 6 | background: url(./i/test.png); 7 | } 8 | 9 | .test3{ 10 | background: url(../i/test.png); 11 | } 12 | 13 | .test4{ 14 | background: url(css/i/test4.png); 15 | } 16 | 17 | .test5{ 18 | background: url(/css/i/test5.png); 19 | } 20 | 21 | .test6{ 22 | background: url(http://misc.360buyimg.com/jdf-test/css/i/test.png); 23 | } 24 | 25 | .test7{ 26 | background: url(//misc.360buyimg.com/jdf-test/css/i/test.png); 27 | } 28 | -------------------------------------------------------------------------------- /example/2.14jdf/source/test/widget/css_hack/css_hack.scss: -------------------------------------------------------------------------------- 1 | .test1{ 2 | background:none\9\0; 3 | } 4 | 5 | .test2{ 6 | background:none\9; 7 | } 8 | 9 | .test3{ 10 | background:none\0; 11 | } 12 | 13 | .test4{ 14 | *width:100px; 15 | } 16 | 17 | .test5{ 18 | _width:100px; 19 | } 20 | 21 | .test6{ 22 | width: 100px; 23 | } 24 | 25 | .test7{ 26 | -webkit-border-radius: 10px; 27 | } 28 | 29 | .test8{ 30 | -moz-border-radius: 10px; 31 | } 32 | 33 | .test9{ 34 | width: expression(eval(document.documentElement.scrollTop)) 35 | } 36 | 37 | .test10{ 38 | * div{width: 100px;} 39 | } -------------------------------------------------------------------------------- /example/3.3velocityjs/index.js: -------------------------------------------------------------------------------- 1 | var Velocity = require('velocityjs'); 2 | 3 | var VelocityRender = Velocity.render( 4 | '

This is $name !~

'+ 5 | '#foreach( $product in $allProducts )'+ 6 | '
  • $velocityCount $product.title $product.content
  • '+ 7 | '#end', 8 | 9 | { 10 | "name": "h2", 11 | "allProducts": [ 12 | { 13 | "title": "title1", 14 | "content": "content1" 15 | }, 16 | { 17 | "title": "title2", 18 | "content": "content2" 19 | } 20 | ] 21 | } 22 | ) 23 | 24 | console.log(VelocityRender); -------------------------------------------------------------------------------- /example/3.8node_universal/src/containers/Home.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import { Link } from 'react-router' 3 | 4 | class Home extends Component { 5 | constructor (props) { 6 | super(props) 7 | } 8 | 9 | render () { 10 | return ( 11 |

    12 | 北京 | 上海 | 广州 | 深圳 13 |

    14 | ) 15 | } 16 | } 17 | 18 | export default Home -------------------------------------------------------------------------------- /example/3.8node_universal/client.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { render } from 'react-dom' 3 | import { Provider } from 'react-redux' 4 | import { Router, browserHistory, hashHistory, useRouterHistory } from 'react-router' 5 | import { configureStore } from './src/store' 6 | import routes from './src/routes' 7 | let state = window.__initialState__ || undefined 8 | 9 | const store = configureStore(hashHistory, state) 10 | const history = hashHistory 11 | 12 | render( 13 | 14 | 15 | , 16 | document.getElementById('mount') 17 | ) 18 | -------------------------------------------------------------------------------- /example/2.14jdf/source/doc/a_tool_livereload.md: -------------------------------------------------------------------------------- 1 | # LiveReload自动刷新浏览器 2 | 3 | ## 使用说明 4 | 5 | * 1.现在仅支持chrome浏览器下的自动刷新,所以首先我们要安装 [LiveReload chrome 插件](https://chrome.google.com/webstore/detail/livereload/jnihajbhpnppcggbcgedagnkighmdlei) 6 | * 2.然后打开当前工程目录,CMD下执行 jdf build -open 7 | * 3.点击LiveReload chrome 插件,使当前页面 "Enable LiveReload" 8 | * 4.jdf如果提示"Browser connected LiveReload",则说明浏览器和LiveReload连接成功 9 | * 5.最后在编辑器里修改工程文件保存后,页面即会自动刷新 10 | 11 | ## 特别说明 12 | 13 | 如果有两个进程那么第二个进程的livereload功能被关闭 14 | 15 | ## 参考资料 16 | 17 | * [LiveReload官网](http://livereload.com/) 18 | * [LiveReload protocol](http://feedback.livereload.com/knowledgebase/articles/86174-livereload-protocol) 19 | -------------------------------------------------------------------------------- /example/3.8node_universal/src/store.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | import { createStore, combineReducers, compose, applyMiddleware } from 'redux' 4 | import { routerReducer, routerMiddleware } from 'react-router-redux' 5 | import thunkMiddleware from 'redux-thunk' 6 | 7 | export function configureStore(history, initialState) { 8 | 9 | const reducer = combineReducers({ 10 | routing: routerReducer 11 | }) 12 | 13 | const store = createStore( 14 | reducer, 15 | initialState, 16 | compose( 17 | applyMiddleware( 18 | thunkMiddleware, 19 | routerMiddleware(history) 20 | ) 21 | ) 22 | ) 23 | 24 | return store 25 | } 26 | -------------------------------------------------------------------------------- /example/2.14jdf/source/test/result/css_background_url/css_background_url.css: -------------------------------------------------------------------------------- 1 | .test1{background:url(http://misc.360buyimg.com/jdf-test/widget/css_background_url/i/test.png)} 2 | .test2{background:url(http://misc.360buyimg.com/jdf-test/widget/css_background_url/i/test.png)} 3 | .test3{background:url(http://misc.360buyimg.com/jdf-test/widget/css_background_url/i/test.png)} 4 | .test4{background:url(http://misc.360buyimg.com/jdf-test/widget/css_background_url/css/i/test4.png)} 5 | .test5{background:url(http://misc.360buyimg.com/jdf-test/css/i/test5.png)} 6 | .test6{background:url(http://misc.360buyimg.com/jdf-test/css/i/test.png)} 7 | .test7{background:url(//misc.360buyimg.com/jdf-test/css/i/test.png)} -------------------------------------------------------------------------------- /example/3.8node_universal/src/containers/App.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Link } from 'react-router' 3 | import { connect } from 'react-redux' 4 | 5 | /* generic styles */ 6 | import normalize from '../styles/normalize.css' 7 | import base from '../styles/base.css' 8 | // Object.assign(normalize, base) 9 | 10 | import Header from '../components/Header/Header' 11 | import Footer from '../components/Footer/Footer' 12 | 13 | function App({ pushPath, children }) { 14 | return ( 15 |
    16 |
    17 |
    18 | {children} 19 |
    20 |
    21 |
    22 | 23 | ); 24 | }; 25 | 26 | module.exports = connect( 27 | null 28 | )(App) -------------------------------------------------------------------------------- /example/2.2lqip/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | lqip 7 | 10 | 11 | 12 | 13 | 14 |
    15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /example/2.14jdf/source/doc/core_tpl.md: -------------------------------------------------------------------------------- 1 | # js前端模板 2 | 3 | ## 变量 4 | 5 | var data = {name: 'lilei'}; 6 | var str = "

    <%=name%>

    "; 7 | console.log($.tpl(str, data)); // =>

    lilei

    8 | 9 | ## 循环 10 | 11 | var data2 = { 12 | title:'listArray', 13 | list:[ 14 | { username:'tom',sex:1}, 15 | { username:'lili',sex:0} 16 | ] 17 | }; 18 | 19 | var str2 = '
    ' 20 | +'

    <%=title%>

    ' 21 | +'
      ' 22 | +' <%for(var i = 0;i' 23 | +'
    • ' 24 | +' <%=list[i].username%>' 25 | +' 性别:<%if (list[i].sex){%>男<%}else{%>女<%}%>' 26 | +'
    • ' 27 | +' <%}%>' 28 | +'
    ' 29 | +'
    '; 30 | 31 | console.log($.tpl(str2, data2)); 32 | -------------------------------------------------------------------------------- /example/2.14jdf/source/lib/fileWorker.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by wangshaoxing on 2014/12/15. 3 | */ 4 | var path = require('path'); 5 | var fs = require('fs'); 6 | 7 | //lib自身组件 8 | var $ = require('./base.js'); 9 | var f = require('./file.js'); 10 | 11 | process.on('message', function(data) { 12 | switch (data.route){ 13 | case "copy":move(data);break; 14 | case "del":del(data);break; 15 | default :break; 16 | 17 | } 18 | process.send({tag:1,job:1}); 19 | }); 20 | 21 | /** 22 | * @在辅助进程里 移动文件夹 23 | */ 24 | var move=function(data){ 25 | f.copy(data.source,data.target); 26 | f.del(data.source); 27 | } 28 | 29 | /** 30 | * @在辅助进程里 删除文件夹 31 | */ 32 | var del=function(data){ 33 | f.del(data.target); 34 | } -------------------------------------------------------------------------------- /example/2.14jdf/source/test/result/js_cmd_define/js_cmd_define.js: -------------------------------------------------------------------------------- 1 | define("http://misc.360buyimg.com/jdf-test/widget/js_cmd_define/js_cmd_define.js",["http://misc.360buyimg.com/a.js","http://misc.360buyimg.com/./b.js","http://misc.360buyimg.com/../c.js","http://misc.360buyimg.com/js/d.js","http://misc.360buyimg.com/jdf-test/js/e.js","http://misc.360buyimg.com/jdf/1.0.0/unit/globalInit/2.0.0/globalInit.js"],function(require){require("http://misc.360buyimg.com/a.js");require("http://misc.360buyimg.com/./b.js");require("http://misc.360buyimg.com/../c.js");require("http://misc.360buyimg.com/js/d.js");require("http://misc.360buyimg.com/jdf-test/js/e.js");require("http://misc.360buyimg.com/jdf/1.0.0/unit/globalInit/2.0.0/globalInit.js")}),define("js_cmd_define.js",["a.js","/b.js"],function(){}); -------------------------------------------------------------------------------- /example/3.6spa/angular.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Angular 7 | 8 | 9 | 10 |
    11 |
      12 |
    • 13 | {{ x.Name + ', ' + x.Country }} 14 |
    • 15 |
    16 |
    17 | 18 | 19 | 20 | 27 | -------------------------------------------------------------------------------- /example/2.14jdf/source/doc/a_tool_develop.md: -------------------------------------------------------------------------------- 1 | # 快速入门 2 | 3 | ## 初始化项目 4 | 在命令行执行如下命令,生成标准化的项目文件夹 5 | 6 | jdf install init 7 | 8 | jdf_init文件中里包括css、html、js、widget、config.json,其中config.json为配置文件,所有配置都需要修改此文件 9 | 10 | 注:config.json文件不允许有注释,单双引号使用时也需要统一 11 | 12 | ## 项目开发 13 | * 在html,js,css等文件夹中新建相应文件 14 | * 比如在html文件夹里新建一个页面index.html 15 | * 在widget文件夹新建抽离规划好的widget模块,即通过`jdf w -c mywidget`命令新建一个widget,包含js/scss/vm/json 16 | * index.html中任意位置插入`{%widget name="mywidget"%}` 17 | 18 | ## 项目调试 19 | * 可以通过`jdf build -o` 在浏览器中查看构建后的当前工程 20 | * mac下用80端口调试页面要先执行`sudo -s`之后再执行`jdf build -o`,因为mac访问访问1024以下端口需要root权限 21 | 22 | ## 项目输出 23 | `jdf output`输出项目文件夹,包括压缩合并css,js,images,静态资源加cdn前缀,同时压缩所有png图片 24 | `jdf output js/test.js,css` 自定义输出自己需要的文件或文件夹 25 | 26 | ## 项目联调和发布 27 | `jdf upload` 发布css/js/widget/html至远端机器,可联调与查看 -------------------------------------------------------------------------------- /example/2.14jdf/source/test/jdf_output_html.js: -------------------------------------------------------------------------------- 1 | var f = require('../lib/file.js'); 2 | var $ = require('../lib/base.js'); 3 | var child = require("child_process"); 4 | var path = require('path'); 5 | var expect = require('expect.js'); 6 | 7 | describe('jdf output -html...', function(){ 8 | this.timeout(10000); 9 | 10 | var js_smarty = f.read('result/js_smarty/js_smarty.html').split('\r\n'); 11 | 12 | before(function(done){ 13 | child.exec('jdf o -html', function(error, stdout, stderr){ 14 | if(!error){ 15 | js_smarty_build = f.read('build/jdf-test/html/index.html'); 16 | 17 | done(); 18 | } 19 | }); 20 | }); 21 | 22 | describe('#js_smarty tpl', function(){ 23 | it('it should console "Hello js_smarty"', function(){ 24 | expect(js_smarty_build).to.contain(js_smarty); 25 | }) 26 | }) 27 | }) -------------------------------------------------------------------------------- /example/3.9pwa/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | PWA demo 8 | 9 | 10 | 11 | 12 | 13 |

    PWA demo

    14 | 15 | 16 | 17 |
    18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /example/2.8js_moudules/index.js: -------------------------------------------------------------------------------- 1 | /*CommonJS*/ 2 | 3 | // 引入依赖 4 | var store = require('store'); 5 | // exports 6 | exports = function(){ 7 | return store.get('customers'); 8 | } 9 | 10 | /*NodeJS module */ 11 | // 引入依赖 12 | var store = require('store'); 13 | function customerStore(){ 14 | return store.get('customers'); 15 | } 16 | // exports 17 | modules.exports = customersFn; 18 | 19 | 20 | /*RequireJS*/ 21 | // 22 | 23 | /*SeaJS*/ 24 | //方式一 25 | define(function(require, exports, module) { 26 | // 模块代码 27 | }); 28 | //方式二 29 | define('module', ['module1', 'module2'], function(require, exports, module){ 30 | // 模块代码 31 | } ); 32 | 33 | /*ES6 import */ 34 | //square.js 35 | export function square(x) { 36 | return x * x; 37 | } 38 | 39 | //main.js 40 | import { square } from 'square'; 41 | console.log(square(10)); // 100 42 | -------------------------------------------------------------------------------- /example/2.14jdf/source/test/html/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | jdf-test 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | {%widget name="css_background_url"%} 16 | 17 | {%widget name="css_background_sprite_base64"%} 18 | 19 | {%widget name="css_hack"%} 20 | 21 | {%widget name="sass_import_lib"%} 22 | 23 | {%widget name="js_cmd_define"%} 24 | 25 | {%widget name="js_seajs_use"%} 26 | 27 | {%widget name="js_smarty"%} 28 | 29 | 30 | -------------------------------------------------------------------------------- /example/4.iOSWebView/iOSWebView/normalViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // normalViewController.m 3 | // iOSWebView 4 | // 5 | // Copyright © 2019 putaoshu. Licensed under the MIT license. 6 | // 7 | 8 | #import "normalViewController.h" 9 | #import 10 | 11 | @interface normalViewController () 12 | 13 | @end 14 | 15 | @implementation normalViewController 16 | 17 | - (void)viewDidLoad { 18 | [super viewDidLoad]; 19 | self.view.backgroundColor = [UIColor whiteColor]; 20 | 21 | UIButton *btn1 = [UIButton buttonWithType:UIButtonTypeCustom]; 22 | [btn1 setTitle:@"这是 普通原生页面" forState:UIControlStateNormal]; 23 | [btn1 setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; 24 | btn1.frame = CGRectMake(50, 200, 250, 30); 25 | [self.view addSubview:btn1]; 26 | 27 | self.navigationController.interactivePopGestureRecognizer.delegate = self; 28 | } 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /example/2.14jdf/source/doc/a_tool_server.md: -------------------------------------------------------------------------------- 1 | # 本地server 2 | 3 | ## 简介 4 | * 前端开发有时候我们需要引入线上静态资源,而本地并不关注这些资源,比如公共脚本jQuery,公共头尾样式图片等。 5 | * 利用server,我们可以把线上资源指定在本地目录,如果本地有和线上相同路径的资源,如果没有则直接取线上。 6 | * 完全可取代Fiddler,真正实现本地半离线开发,无需修改一次提交一次代码到测试服务器。 7 | 8 | ## 使用方法 9 | 10 | * 安装[chrome插件host文件管理工具](https://chrome.google.com/webstore/detail/hostadmin/oklkidkfohahankieehkeenbillligdn) , 此工具支持即时切换hosts,无须浏览多次刷新页面,同时不修改系统的默认hosts,我们的server即基于此规则来取,如果本地没有资源直接用线上来取。 11 | 12 | * 在任意项目文件夹执行 13 | 14 | jdf build -combo 15 | 16 | * 或者磁盘任意文件下执行 17 | 18 | jdf server 19 | 20 | 这样本地server就跑出来了,默认端口号为80端口 21 | 22 | * 用hosts切换工具把静态资源cdn路径配置本地hosts,如 23 | 24 | cdn.com 127.0.0.1 25 | 26 | * 项目联调阶段:本地修改项目文件夹下的静态文件,刷新浏览器下,我们会发现,cdn域名下的静态文件即指定我们修改后的文件 27 | * 线上调试BUG阶段:下载某一线上对应svn下的静态文件,修改,刷新浏览器即可进行调试,因为本地没有静态资源我们的server会从线上直接抓取 28 | 29 | ## todo 30 | 31 | * url映射本地指定目录配置 32 | * ip访问 33 | * combo合并的文件也从本地来取 34 | * 可配置指定文件类型转发 35 | * css合并后的文件如何本地开发? 36 | -------------------------------------------------------------------------------- /example/2.5css/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | CSS 7 | 10 | 11 | 12 |

    I'm h1

    13 | 34 | 35 | -------------------------------------------------------------------------------- /example/4.iOSWebView/iOSWebView/UIWebViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIWebViewController.m 3 | // iOSWebView 4 | // 5 | // Copyright © 2019 putaoshu. Licensed under the MIT license. 6 | // 7 | 8 | #import "UIWebViewController.h" 9 | 10 | @interface UIWebViewController () 11 | @property (nonatomic, strong, readwrite) UIWebView *webView; 12 | 13 | @end 14 | 15 | @implementation UIWebViewController 16 | 17 | - (void)viewDidLoad { 18 | [super viewDidLoad]; 19 | 20 | self.webView = [[UIWebView alloc] init]; 21 | self.webView.frame = self.view.frame; 22 | [self.view addSubview:self.webView]; 23 | self.webView.delegate = self; 24 | 25 | [self.webView loadRequest: [[NSURLRequest alloc] initWithURL: [NSURL URLWithString: @"https://m.baidu.com"]]]; 26 | } 27 | 28 | - (void)webViewDidStartLoad:(UIWebView *)webView{ 29 | NSLog(@"webViewDidStartLoad"); 30 | } 31 | 32 | - (void)webViewDidFinishLoad:(UIWebView *)webView{ 33 | NSLog(@"webViewDidFinishLoad"); 34 | } 35 | 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /example/2.14jdf/source/lib/wx.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var gitclone = require('git-clone'); 4 | var jdf = require('./jdf.js'); 5 | var f = require('./file.js'); 6 | 7 | var wx = module.exports = {}; 8 | 9 | var template = jdf.config.wxTemplate; 10 | 11 | wx.init = function(dir) { 12 | console.log('git clone mini template:' + template); 13 | 14 | if (f.exists(dir)) { 15 | console.log('jdf warnning : dir [' + dir + '] is exists'); 16 | return; 17 | } 18 | 19 | gitclone(template, dir, function(err) { 20 | if (err === undefined) { 21 | f.del(dir + '/.git'); 22 | console.log('git clone success...'); 23 | } else { 24 | console.log(err); 25 | } 26 | }) 27 | } 28 | 29 | wx.page = function(name) { 30 | var pageDir = 'pages/' + name; 31 | var pageArr = [name + '.js', name + '.json', name + '.wxml', name + '.wxss']; 32 | 33 | if (f.exists(pageDir)) { 34 | console.log('jdf warnning : page [' + name + '] is exists'); 35 | return; 36 | } 37 | 38 | f.mkdir(pageDir); 39 | 40 | pageArr.forEach(function(item) { 41 | f.write(pageDir + '/' + item, ''); 42 | }); 43 | } -------------------------------------------------------------------------------- /example/2.14jdf/source/lib/concat.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @files concat 3 | * @ctime 2014-9-24 4 | */ 5 | 6 | var path = require('path'); 7 | var fs = require('fs'); 8 | 9 | //lib自身组件 10 | var $ = require('./base.js'); 11 | var f = require('./file.js'); 12 | var jdf = require('./jdf.js'); 13 | 14 | //exports 15 | var concat = module.exports = {}; 16 | 17 | concat.init = function(rSource){ 18 | var concatFiles = jdf.config.output.concat; 19 | 20 | Object.size = function(obj) { 21 | var size = 0, key; 22 | for (key in obj) { 23 | if (obj.hasOwnProperty(key)) size++; 24 | } 25 | return size; 26 | }; 27 | var source = f.realpath(rSource)+'/'+jdf.getProjectPath(); 28 | 29 | if ( Object.size(concatFiles)) { 30 | for (var i in concatFiles ){ 31 | var res = ''; 32 | concatFiles[i].forEach(function(j){ 33 | var m = $.getCssExtname(source+'/'+j); 34 | if (f.exists(m)) { 35 | res += f.read(m); 36 | //f.del(source+'/'+j); 37 | }else { 38 | console.log('jdf warnning "'+j+'" is not exists'); 39 | } 40 | }); 41 | if (res != '') { 42 | f.write(source+'/'+i, res); 43 | } 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /example/2.14jdf/source/test/result/css_background_sprite_base64/css_background_sprite_base64.css: -------------------------------------------------------------------------------- 1 | .test1{background:url(http://misc.360buyimg.com/jdf-test/widget/css_background_sprite_base64/i/css_background_sprite_base64.png?__sprite);background-position:0 0} 2 | .test2{background:url(http://misc.360buyimg.com/jdf-test/widget/css_background_sprite_base64/i/css_background_sprite_base64.png?__sprite);background-position:0 -46px} 3 | .test3{background:url(http://misc.360buyimg.com/jdf-test/widget/css_background_sprite_base64/i/css_background_sprite_base64.png?__sprite);background-position:0 -92px} 4 | .test4{background:url(http://misc.360buyimg.com/jdf-test/widget/css_background_sprite_base64/i/css_background_sprite_base64.png?__sprite);background-position:0 -138px} 5 | .test5{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAUCAMAAABlGZcgAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAEhQTFRF////yBYj/PHyyyQwzSw4+unq++/vzCYz5I+V5IyS887Q/PT11lBZ2Fhh2V1m1EdS+ebo00VP7ri877q+2Ftkzi868cXJ773BjJeJ4QAAAFJJREFUeNpiYCAIxPgZIUBQGMxn4eEC01wi7GCakRWqkI2RCcyH62SmDV8AzT5eiANY+aB8BIDzORk4UPjcDNxwvihcHuIfcRaobhYhwoEDEGAAD1wBuVXYWesAAAAASUVORK5CYII=)} -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 putaoshu 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /example/4.iOSWebView/iOSWebView/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ios-marketing", 45 | "size" : "1024x1024", 46 | "scale" : "1x" 47 | } 48 | ], 49 | "info" : { 50 | "version" : 1, 51 | "author" : "xcode" 52 | } 53 | } -------------------------------------------------------------------------------- /example/3.8node_universal/server.dev.js: -------------------------------------------------------------------------------- 1 | import path from 'path' 2 | import express from 'express' 3 | import webpack from 'webpack' 4 | import webpackDevMiddleware from 'webpack-dev-middleware' 5 | import webpackHotMiddleware from 'webpack-hot-middleware' 6 | import webpackConfig from './webpack.config.dev' 7 | 8 | const app = express(); 9 | 10 | var compiler = webpack(webpackConfig); 11 | 12 | app.use(webpackDevMiddleware(compiler, { 13 | publicPath: webpackConfig.output.publicPath, 14 | stats: { colors: true }, 15 | hot: true, 16 | noInfo: true,//no deploy info 17 | historyApiFallback: true 18 | })); 19 | 20 | //hmr 21 | app.use(webpackHotMiddleware(compiler, { 22 | log: console.log, 23 | path: '/__webpack_hmr', 24 | heartbeat: 10 * 1000 25 | })); 26 | 27 | app.use('/public', express.static(__dirname + '/public')) 28 | 29 | //entry files --> index.dev.html 30 | app.get('*', function(req, res) { 31 | res.sendFile(path.join(__dirname, 'index.dev.html')); 32 | }); 33 | 34 | app.listen(3002, 'localhost', function (err) { 35 | if (err) { 36 | console.log(err); 37 | return; 38 | } 39 | 40 | console.log('==> 🌎 listening on http://localhost:3002') 41 | }) -------------------------------------------------------------------------------- /example/5.nginx_config/nginx.conf: -------------------------------------------------------------------------------- 1 | server{ 2 | listen 8087; 3 | listen 443 ssl http2; 4 | ssl_certificate /Users/liuwei/Downloads/code/nginx/cert/222.com.pem; 5 | ssl_certificate_key /Users/liuwei/Downloads/code/nginx/cert/222.com-key.pem; 6 | keepalive_timeout 70; 7 | server_name 222.com; 8 | server_tokens off; 9 | 10 | gzip on; 11 | # gzip_min_length 1k; 12 | gzip_comp_level 2; 13 | gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png; 14 | 15 | 16 | location / { 17 | root /Users/liuwei/Downloads/code/nginx/http2; 18 | autoindex on; 19 | autoindex_exact_size off; 20 | autoindex_localtime on; 21 | charset utf-8; 22 | index index.html index.php; 23 | 24 | location ~ .*\.(js|css|png|jpg|jpeg|gif|svg|ico)$ { 25 | expires 10m; 26 | #add_header Cache-Control max-age=6; 27 | #add_header Cache-Control no-cache; 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /example/2.14jdf/source/lib/base64.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @css base64 3 | * @ctime 2015-8-18 4 | */ 5 | var $ = require('./base.js'); 6 | var f = require('./file.js'); 7 | var jdf = require('./jdf.js'); 8 | 9 | var path = require('path'); 10 | var base64 = module.exports = {}; 11 | 12 | base64.init = function(source){ 13 | if(jdf.config.build.hasCmdLog) console.log('compress.base64---'+source); 14 | var reg_background = /background(?:-image)?:([\s\S]*?)(?:;|$)/gi; 15 | var reg_img_url = /url\s*\(\s*("(?:[^\\"\r\n\f]|\\[\s\S])*"|'(?:[^\\'\n\r\f]|\\[\s\S])*'|[^)}]+)\s*\)/i; 16 | var reg_is_base64 = /[?&]__base64/i; 17 | 18 | var content = f.read(source); 19 | var background = content.match(reg_background); 20 | 21 | if(background){ 22 | content = escape(content); 23 | background.forEach(function(item, index){ 24 | var img_url = item.match(reg_img_url); 25 | 26 | if(img_url && img_url[0].match(reg_is_base64)){ 27 | var base64Encode = f.base64Encode(path.join(path.dirname(source), img_url[1].replace('?__base64', ''))); 28 | content = content.replace(new RegExp(escape(img_url[1]), 'gi'), ('data:image/png;base64,'+base64Encode)); 29 | } 30 | }); 31 | } 32 | 33 | return unescape(content); 34 | } -------------------------------------------------------------------------------- /example/2.14jdf/source/doc/core_smarty.md: -------------------------------------------------------------------------------- 1 | # smarty模版 2 | 3 | ## 设计原则 4 | 让前端来写后端的smarty模板,并且前端不需要搭建各种繁杂的后端环境,另外模板的数据源可以在项目开始前前后端约定之后生成JSON文件,从而使两个角色并行开发。 5 | 6 | ## 使用方法: 7 |
    1、将widget中的模版扩展名改为`.smarty`
    8 |
    2、将模版需要渲染的数据,放在当前widget下的`.json`文件或者widget标签的data属性中
    9 |
    3、引用方式:`{%widget name="test"%}`
    10 |
    4、单独引用模版:`{%widget name="test" tydive="smarty"%}`
    11 | 12 | ## smarty基本语法 13 | * 变量 14 | Smarty有几种不同类型的变量,变量的类型取决于它的前缀是什么符号(或者被什么符号包围) 15 | Smarty的变量可以直接被输出或者作为函数属性和修饰符(modifiers)的参数,或者用于内部的条件表达式等等。 16 | 如果要输出一个变量,只要用定界符将它括起来就可以,例如: 17 | ```text 18 | {$Name} 19 | {$Contacts[row].Phone} 20 | ``` 21 | 22 | * if,else判断 23 | ```text 24 | {if $name eq "Fred"} 25 | Welcome Sir. 26 | {elseif $name eq "Wilma"} 27 | Welcome Ma'am. 28 | {else} 29 | Welcome, whatever you are. 30 | {/if} 31 | ``` 32 | 33 | * selection循环遍历 34 | 模板的section用于遍历数组中的数据。section标签必须成对出现,必须设置name和 loop属性。名称可以是包含字母、数字和下划线的任意组合,可以嵌套但必须保证嵌套的 name唯一。 35 | 变量loop(通常是数组)决定循环执行的次数。当需要在section循环内输出变量时,必须在变量后加上中括号包含着的name变量。 36 | ```text 37 | {section name=customer loop=$custid} 38 | id: {$custid[customer]}
    39 | {/section} 40 | 41 | OUTPUT: 42 | 43 | id: 1000
    44 | id: 1001
    45 | id: 1002
    46 | ``` 47 | -------------------------------------------------------------------------------- /example/2.15webpack/webpack.dev.dll.js: -------------------------------------------------------------------------------- 1 | import path from 'path'; 2 | import webpack from 'webpack'; 3 | 4 | const appRoot = path.join(__dirname, '../'); 5 | 6 | export default { 7 | mode: 'development', 8 | entry: { 9 | vendor: [ 10 | 'react', 11 | 'react-dom', 12 | 'react-redux', 13 | 'react-router-dom', 14 | 'react-transition-group', 15 | 'redux', 16 | 'redux-logger', 17 | 'redux-saga', 18 | 'history', 19 | 'immutable' 20 | ], 21 | }, 22 | 23 | output: { 24 | path: path.join(appRoot, 'public', 'dll'), 25 | filename: '[name].dll.js', 26 | /** 27 | * output.library 28 | * 将会定义为 window.${output.library} 29 | * 在这次的例子中,将会定义为 `window.vendorLibrary` 30 | */ 31 | library: '[name]Library', 32 | }, 33 | plugins: [ 34 | new webpack.DllPlugin({ 35 | /** 36 | * path 37 | * 定义 manifest 文件生成的位置 38 | * [name] 的部分由 entry 的名字替换 39 | */ 40 | path: path.join(appRoot, 'public', 'dll', '[name]-manifest.json'), 41 | /** 42 | * name 43 | * dll bundle 输出到那个全局变量上 44 | * 和 output.library 一样即可。 45 | */ 46 | name: '[name]Library', 47 | }), 48 | ], 49 | }; 50 | -------------------------------------------------------------------------------- /example/4.iOSWebView/iOSWebView/JSSDKViewControllerBase/WKWebViewJavascriptBridge.h: -------------------------------------------------------------------------------- 1 | // 2 | // WKWebViewJavascriptBridge.h 3 | // 4 | // Created by @LokiMeyburg on 10/15/14. 5 | // Copyright (c) 2014 @LokiMeyburg. All rights reserved. 6 | // 7 | 8 | #if (__MAC_OS_X_VERSION_MAX_ALLOWED > __MAC_10_9 || __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_7_1) 9 | #define supportsWKWebView 10 | #endif 11 | 12 | #if defined supportsWKWebView 13 | 14 | #import 15 | #import "WebViewJavascriptBridgeBase.h" 16 | #import 17 | 18 | @interface WKWebViewJavascriptBridge : NSObject 19 | 20 | + (instancetype)bridgeForWebView:(WKWebView*)webView; 21 | + (void)enableLogging; 22 | 23 | - (void)registerHandler:(NSString*)handlerName handler:(WVJBHandler)handler; 24 | - (void)removeHandler:(NSString*)handlerName; 25 | - (void)callHandler:(NSString*)handlerName; 26 | - (void)callHandler:(NSString*)handlerName data:(id)data; 27 | - (void)callHandler:(NSString*)handlerName data:(id)data responseCallback:(WVJBResponseCallback)responseCallback; 28 | - (void)reset; 29 | - (void)setWebViewDelegate:(id)webViewDelegate; 30 | - (void)disableJavscriptAlertBoxSafetyTimeout; 31 | 32 | @end 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /example/2.14jdf/source/lib/compressWorker.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by wangshaoxing on 2014/12/12. 3 | */ 4 | 5 | var path = require('path'); 6 | var fs = require('fs'); 7 | 8 | //lib自身组件 9 | var $ = require('./base.js'); 10 | var f = require('./file.js'); 11 | var compress = require('./compress.js'); 12 | var jdf = require('./jdf.js'); 13 | 14 | 15 | process.on('message', function(data) { 16 | 17 | compress.init( 18 | data.task, 19 | data.isdebug, 20 | data.config, 21 | data.getProject, 22 | function() { 23 | process.send({ tag: 1, job: data.task }); 24 | } 25 | ); 26 | 27 | 28 | // if (jdf.config.output.webp) { 29 | // compress.init( 30 | // data.task, 31 | // data.isdebug, 32 | // data.config, 33 | // data.getProject, 34 | // function(){ 35 | // process.send({ tag: 1, job: data.task }); 36 | // } 37 | // ); 38 | // } else { 39 | // compress.init( 40 | // data.task, 41 | // data.isdebug, 42 | // data.config, 43 | // data.getProject 44 | // ); 45 | // process.send({ tag: 1, job: data.task }); 46 | // } 47 | 48 | }); 49 | 50 | process.send({ tag: 1, job: "" }); 51 | -------------------------------------------------------------------------------- /example/3.8node_universal/webpack.config.dev.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const webpack = require('webpack'); 3 | const ExtractTextPlugin = require('extract-text-webpack-plugin'); 4 | const autoprefixer = require('autoprefixer'); 5 | 6 | module.exports = { 7 | devtool: 'inline-source-map', 8 | entry: [ 9 | //Hot Module Replacement(HMR) 10 | 'webpack-hot-middleware/client?path=/__webpack_hmr&timeout=10000&reload=true', 11 | './client' 12 | ], 13 | output: { 14 | filename: 'bundle.js', 15 | path: path.join(__dirname, 'public'), 16 | publicPath: '/public/' 17 | }, 18 | module: { 19 | loaders: [ 20 | { 21 | test: /\.js?$/, 22 | exclude: /node_modules/, 23 | loaders: ['react-hot', 'babel-loader'] 24 | //,query: {presets: ['es2015', 'react', 'stage-1']} //replace ".babelrc" file 25 | }, 26 | { 27 | test: /\.css$/i, 28 | loader: ExtractTextPlugin.extract('style', 29 | `css?modules&localIdentName=[name]_[local]__[hash:base64:5]!postcss`), 30 | } 31 | ] 32 | }, 33 | postcss: [ 34 | autoprefixer({ browsers: ['last 2 versions'] }) 35 | ], 36 | plugins: [ 37 | new ExtractTextPlugin('style.css', { allChunks: true }), 38 | //optimize files 39 | new webpack.optimize.OccurenceOrderPlugin(), 40 | new webpack.HotModuleReplacementPlugin(), 41 | //has error no exit 42 | new webpack.NoErrorsPlugin() 43 | ] 44 | }; -------------------------------------------------------------------------------- /example/3.9pwa/public/sw.js: -------------------------------------------------------------------------------- 1 | function displayMessage(message) { 2 | document.querySelector('#sw-status').innerText = message; 3 | } 4 | 5 | if ('serviceWorker' in navigator) { 6 | // See https://developers.google.com/web/fundamentals/instant-and-offline/service-worker/registration 7 | window.addEventListener('load', () => { 8 | navigator.serviceWorker.register('/service-worker.js').then(function(registration) { 9 | registration.onupdatefound = function() { 10 | var installingWorker = registration.installing; 11 | 12 | installingWorker.onstatechange = function() { 13 | switch (installingWorker.state) { 14 | case 'installed': 15 | if (navigator.serviceWorker.controller) { 16 | displayMessage('Please refresh for updates to this site.'); 17 | } else { 18 | displayMessage('This site is available offline!'); 19 | } 20 | break; 21 | case 'fetch': 22 | displayMessage('Service worker fetch'); 23 | break; 24 | case 'activate': 25 | displayMessage('Service worker activate'); 26 | break; 27 | case 'redundant': 28 | displayMessage('Service worker installation failed.'); 29 | break; 30 | } 31 | }; 32 | }; 33 | }).catch(function(e) { 34 | displayMessage('Error during service worker registration:' + e); 35 | }); 36 | }); 37 | } -------------------------------------------------------------------------------- /example/2.14jdf/source/doc/a_tool_weinre.md: -------------------------------------------------------------------------------- 1 | # 利用jdf调试移动设备的页面 2 | 3 | 一直以来,在移动设备上都缺少类似Firebug、Chrome dev的开发工具,导致在这些移动设备上调试页面是一件非常头疼的事情。 4 | 今天利用jdf,你可以通过三步轻松的搞定这件事情。 5 | 6 | #### 一、需要在本地进行一些简单的设置 7 | 1、在当前项目的`config.json`中打开调试开关(切记:在调试完页面之后,一定要关闭此开关,然后重新输出项目) 8 | ```javascript 9 | "build":{ 10 | "weinre": true //true为打开,false为关闭 11 | } 12 | ``` 13 | 2、打开fiddler,确认其设置的端口号,一般默认为8888 14 | 3、手机连接电脑热点wifi,将手机的wifi设置中的`HTTP代理`设置为手动。 15 | 其中的“服务器”设置为连接的电脑ip地址,端口号要与fiddler一致。如下图所示: 16 | 17 | 18 | #### 二、上传项目到测试服务器 19 | 20 | ```javascript 21 | jdf upload -nc 22 | jdf upload -nh 23 | ``` 24 | 25 | 分别执行以上两条命令,上传html、css、js、图片等文件到测试服务器,然后在电脑上打开项目的测试地址,例如: 26 | ```javascript 27 | http://page.jd.com/test/html 28 | ``` 29 | 30 | 你会看到当前项目的文件列表中多了一个`_debug.html` 31 | ```html 32 | _debug.html 14-Aug-2015 02:20 390 33 | index.html 14-Aug-2015 02:20 5831 34 | test.html 14-Aug-2015 02:20 688 35 | ``` 36 | 点击它,会看到项目中所有的html页面链接,点击你要调试的页面,就会打开一个类似于`Chrome dev`的调试工具。 37 | 38 | 39 | #### 三、在移动设备上打开测试服务器上需要调试的页面,例如: 40 | ```html 41 | http://page.jd.com/test/index.html 42 | ``` 43 | 44 | #### 四、没有第四了,接下来你可以在pc上尽情的调试移动设备上的页面了。 45 | 46 | 注意:项目开发完毕以后,一定要将第一步中的开关置为关闭状态,然后再重新输出上线文件。 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /example/2.14jdf/source/lib/openurl.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @openurl 3 | * @from https://github.com/rauschma/openurl/blob/master/openurl.js 4 | * @example require("./openurl").open(url); 5 | */ 6 | 7 | var spawn = require('child_process').spawn; 8 | var command; 9 | 10 | switch(process.platform) { 11 | case 'darwin': 12 | command = 'open'; 13 | break; 14 | case 'win32': 15 | command = 'explorer.exe'; 16 | break; 17 | case 'linux': 18 | command = 'xdg-open'; 19 | break; 20 | default: 21 | throw new Error('Unsupported platform: ' + process.platform); 22 | } 23 | 24 | /** 25 | * Error handling is deliberately minimal, as this function is to be easy to use for shell scripting 26 | * 27 | * @param url The URL to open 28 | * @param callback A function with a single error argument. Optional. 29 | */ 30 | 31 | function open(url, callback) { 32 | var child = spawn(command, [url]); 33 | var errorText = ""; 34 | child.stderr.setEncoding('utf8'); 35 | child.stderr.on('data', function (data) { 36 | errorText += data; 37 | }); 38 | child.stderr.on('end', function () { 39 | if (errorText.length > 0) { 40 | var error = new Error(errorText); 41 | if (callback) { 42 | callback(error); 43 | } else { 44 | throw error; 45 | } 46 | } else if (callback) { 47 | callback(error); 48 | } 49 | }); 50 | } 51 | 52 | exports.open = open; 53 | -------------------------------------------------------------------------------- /example/2.14jdf/source/lib/log.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @Logs 3 | */ 4 | var $ = require('./base.js'); 5 | var jdf = require('./jdf.js'); 6 | 7 | var log = module.exports; 8 | var os = require('os'); 9 | var SERVERURL = ''; 10 | 11 | var getIp = function(){ 12 | var net = os.networkInterfaces(); 13 | for(var key in net){ 14 | if(net.hasOwnProperty(key)){ 15 | var items = net[key]; 16 | if(items && items.length){ 17 | for(var i = 0; i < items.length; i++){ 18 | var ip = String(items[i].address).trim(); 19 | if(ip && /^\d+(?:\.\d+){3}$/.test(ip) && ip !== '127.0.0.1'){ 20 | return ip; 21 | } 22 | } 23 | } 24 | } 25 | } 26 | return '127.0.0.1'; 27 | }; 28 | 29 | log.get = function (){ 30 | var ip = getIp(); 31 | var version = require('../package.json').version; 32 | 33 | return { 34 | ip:ip, 35 | port:jdf.config.localServerPort, 36 | platform:os.platform(), 37 | hostname:os.hostname(), 38 | version:version, 39 | //other 40 | projectname:jdf.getProjectPath() 41 | } 42 | } 43 | 44 | /** 45 | * @log send 46 | */ 47 | log.send = function (str){ 48 | if ( str && jdf.config.haslog == true){ 49 | var param = log.get(); 50 | param.cmd = str; 51 | var str = ''; 52 | for (var i in param){ 53 | str += i +'=' +param[i]+'&'; 54 | } 55 | str = encodeURI(str); 56 | //console.log(str); 57 | // $.httpget('http://jdfe.sinaapp.com/log/log.php?'+str); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /example/3.9pwa/index.js: -------------------------------------------------------------------------------- 1 | const chokidar = require('chokidar'); 2 | const compression = require('compression'); 3 | const swPrecache = require('sw-precache'); 4 | const express = require('express'); 5 | 6 | const app = express(); 7 | app.use(compression()); 8 | 9 | const STATIC_ROOT = 'public'; 10 | 11 | const generateServiceWorker = () => { 12 | console.log('Generating a new service worker...'); 13 | return swPrecache.generate({ 14 | staticFileGlobs: [`${STATIC_ROOT}/**/!(*manifest.json*)`], 15 | stripPrefix: STATIC_ROOT, 16 | runtimeCaching: [{ 17 | ///https://cdn0.iconfinder.com/data/icons/green-world-colored/80/battery-energy-charger-charging-electric-station-tesla-256.png 18 | urlPattern: new RegExp('^https://cdn0.iconfinder.com/'), 19 | handler: 'cacheFirst', 20 | }], 21 | }); 22 | }; 23 | 24 | let swPromise = generateServiceWorker(); 25 | const watcher = chokidar.watch(STATIC_ROOT); 26 | watcher.on('ready', () => { 27 | watcher.on('all', () => { 28 | swPromise = generateServiceWorker(); 29 | }); 30 | }); 31 | 32 | app.use(express.static(STATIC_ROOT)); 33 | 34 | app.get('/service-worker.js', (request, response) => { 35 | swPromise.then((swContents) => { 36 | response.setHeader('Content-Type', 'application/javascript'); 37 | response.setHeader('Cache-Control', 'no-cache'); 38 | response.send(swContents); 39 | }); 40 | }); 41 | 42 | // process.env.PORT 43 | const listener = app.listen(3009, () => { 44 | console.log(`==> 🌎 listening on http://localhost:${listener.address().port}`); 45 | }); 46 | -------------------------------------------------------------------------------- /example/2.14jdf/source/doc/a_tool_command.md: -------------------------------------------------------------------------------- 1 | # 命令手册 2 | 3 | ## jdf build (jdf b) 4 | 执行此命令jdf会开启一个[本地服务](a_tool_server.md)用来构建项目,默认端口为`3000`。 5 | 6 | * `-open`或者`-o`,在开启本地服务的同时,自动打开`html/index.html` 7 | 8 | ## jdf output (jdf o) 9 | 10 | * `dirname`,输出到自定义的文件夹中,比如`jdf o js`即只输出js文件夹 11 | * `-debug`,输出未压缩的css、js、图片文件 12 | 13 | 输出当前项目到`build`文件夹,所谓的“输出”,指的是jdf会自动做以下几件事情: 14 | 15 | * 替换文件中的[widget](core_widget.md)引用标签为实际内容 16 | * 把less/sass文件编译为css 17 | * 合并压缩css、js、png文件,使用[cssSprite](a_tool_csssprite.md)技术将小图片合并为一张大图 18 | * 给css文件中引用的背景图片添加cdn 19 | 20 | ## jdf upload (jdf u) 21 | 22 | 把当前项目上传到测试服务器。直接执行`jdf upload`时,只上传js、css、图片文件到测试服务器。 23 | 24 | * `dirname`,只上传指定的文件夹/文件到测试服务器 25 | * `-debug`,上传时不压缩js、css、图片文件,以方便测试 26 | * `-preview`,只上传html文件到测试服务器 27 | * `-customw`,自定义上传`jdf u -c ./localDirxxx /serverDirxxx serverIp`即把本地的localDirxxx所有文件夹上传到serverIp的serverDirxxx文件夹中 28 | 29 | ## jdf widget (jdf w) 30 | 31 | * `-create xxx`,创建一个widget 32 | * `-all`,预览当前项目中的所有widget 33 | * `-preview xxx`,预览指定的widget 34 | * `-list`,获取服务器上所有的widget列表 35 | * `-install xxx`,下载安装widget到本地项目中 36 | * `-publish xxx`,发布widgt到服务器上 37 | 38 | ## jdf server (jdf s) 39 | 40 | 开启一个[本地服务](a_tool_server.md)用来调试代码,默认端口为`3000` 41 | 42 | ## jdf lint 43 | 44 | html、css、js文件代码质量检查工具,详细用法可点击[这里](a_tool_lint.md) 45 | 46 | ## jdf format 47 | 48 | html、css、js文件格式化工具,详细用法可点击[这里](a_tool_format.md) 49 | 50 | ## jdf compress 51 | 52 | html、css、js文件压缩工具 53 | 54 | ## jdf clean 55 | 56 | 清理jdf缓存文件,遇到比较反常的现象时,可尝试执行一下此命令 57 | 58 | ## jdf -h 59 | 60 | 获取jdf的帮助信息 61 | 62 | ## jdf -v 63 | 64 | 获取jdf的当前版本号 65 | 66 | 67 | -------------------------------------------------------------------------------- /example/2.2sqip/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | sqip 7 | 10 | 11 | 12 | 13 | 14 |
    15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /example/3.8node_universal/webpack.config.prod.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const webpack = require('webpack'); 3 | const ExtractTextPlugin = require('extract-text-webpack-plugin'); 4 | const autoprefixer = require('autoprefixer'); 5 | 6 | module.exports = { 7 | entry: { 8 | app: './client', 9 | vendor: [ 10 | 'isomorphic-fetch', 11 | 'react', 12 | 'react-dom', 13 | 'react-redux', 14 | 'react-router', 15 | 'react-router-redux', 16 | 'redux', 17 | 'redux-thunk' 18 | ] 19 | }, 20 | output: { 21 | path: path.join(__dirname, 'public'), 22 | filename: 'bundle.js', 23 | publicPath: '/public/' 24 | }, 25 | module: { 26 | loaders: [ 27 | { 28 | test: /\.js$/, 29 | loader: 'babel-loader', 30 | exclude: /node_modules/ 31 | }, 32 | { 33 | test: /\.css$/i, 34 | loader: ExtractTextPlugin.extract('style', 35 | `css?modules&localIdentName=[name]_[local]__[hash:base64:5]!postcss`), 36 | } 37 | ] 38 | }, 39 | postcss: [ 40 | autoprefixer({ browsers: ['last 2 versions'] }) 41 | ], 42 | plugins: [ 43 | new ExtractTextPlugin('style.css', { allChunks: true }), 44 | //NODE_ENV === 'production' 45 | new webpack.DefinePlugin({ 'process.env.NODE_ENV': '"production"' }), 46 | //Dedupe 47 | new webpack.optimize.DedupePlugin(), 48 | //UglifyJs 49 | new webpack.optimize.UglifyJsPlugin({minimize: true, compress: {warnings: false}}), 50 | //new webpack.optimize.OccurenceOrderPlugin(), 51 | new webpack.optimize.CommonsChunkPlugin('vendor', 'vendor.js') 52 | ] 53 | } 54 | -------------------------------------------------------------------------------- /example/2.14jdf/source/lib/buildJs.js: -------------------------------------------------------------------------------- 1 | var f = require("./file.js"); 2 | var jdf = require("./jdf.js"); 3 | var babelCore = require('babel-core'); 4 | 5 | var path = require('path'); 6 | var $ = require('./base.js'); 7 | 8 | /** 9 | * @build js 10 | * @time 2016-11-7 11 | * @param src 输入文件/文件夹相对路径 12 | * @param dist 输出文件/文件夹相对路径 13 | * @doc http://babeljs.io/docs/usage/api/ 14 | */ 15 | 16 | exports.init = function(src, dist){ 17 | if(f.isDir(src)){ 18 | var filelist = f.getdirlist(src,'(js)$',jdf.config.build.isEs6Exclude); 19 | filelist.forEach(function(item){ 20 | babel(item, dist); 21 | }) 22 | }else if(f.isFile(src)){ 23 | babel(src, dist); 24 | }else{ 25 | console.log('jdf buildJs "' + src + '"" is not exists'); 26 | } 27 | } 28 | 29 | var babel = function(src, dist){ 30 | 31 | //http://babeljs.io/docs/usage/api/#options 32 | //https://github.com/babel/babel/tree/master/packages/babel-preset-es2015 33 | 34 | var options = { 35 | presets: [ 36 | require('babel-preset-es2015') 37 | // require('babel-preset-es2015-without-strict') 38 | ,require('babel-preset-stage-1') 39 | ] 40 | } 41 | 42 | try { 43 | var dist = path.normalize(dist +'/'+ src); 44 | var src = path.normalize(jdf.currentDir +'/'+ src); 45 | 46 | if(jdf.config.build.hasCmdLog) console.log('buildES6js---'+ src); 47 | 48 | var result = babelCore.transformFileSync(src, options); 49 | f.write(dist, result.code); 50 | 51 | } catch (e) { 52 | console.log('jdf error [jdf.buildJS.ES6] - ' + src); 53 | console.log(e); 54 | } 55 | } -------------------------------------------------------------------------------- /example/4.iOSWebView/iOSWebView/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | NSAppTransportSecurity 24 | 25 | NSAllowsArbitraryLoads 26 | 27 | 28 | NSPhotoLibraryAddUsageDescription 29 | Our application needs permission to write photos 30 | UILaunchStoryboardName 31 | LaunchScreen 32 | UIMainStoryboardFile 33 | Main 34 | UIRequiredDeviceCapabilities 35 | 36 | armv7 37 | 38 | UISupportedInterfaceOrientations 39 | 40 | UIInterfaceOrientationPortrait 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | UIViewControllerBasedStatusBarAppearance 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /example/4.iOSWebView/iOSWebView/JSSDKWebKit.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 11 | 12 | 13 | 41 | 42 | 43 |
    回调显示
    44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /example/4.iOSWebView/iOSWebView/normalWebViewViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // normalWebViewViewController.m 3 | // iOSWebView 4 | // 5 | // Copyright © 2019 putaoshu. Licensed under the MIT license. 6 | // 7 | 8 | #import "normalWebViewViewController.h" 9 | #import 10 | 11 | @interface normalWebViewViewController () 12 | @end 13 | 14 | @implementation normalWebViewViewController 15 | 16 | - (void)viewDidLoad { 17 | [super viewDidLoad]; 18 | [self webViewInit]; 19 | 20 | self.navigationController.delegate = self; 21 | } 22 | 23 | - (void)webViewInit { 24 | WKWebView *webView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 50, self.view.bounds.size.width, self.view.bounds.size.height)]; 25 | webView.navigationDelegate = self; 26 | [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"https://m.baidu.com"]]]; 27 | [self.view addSubview:webView]; 28 | webView.scrollView.scrollEnabled = NO; 29 | } 30 | 31 | #pragma mark - 加载状态的回调 32 | // 页面开始加载时调用 33 | - (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation { 34 | NSLog(@"页面开始加载"); 35 | } 36 | // 当内容开始返回时调用 37 | - (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation { 38 | NSLog(@"数据开始返回"); 39 | } 40 | 41 | // 页面加载完成之后调用 42 | - (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation { 43 | NSLog(@"页面已经加载完成"); 44 | } 45 | // 页面加载失败时调用 46 | - (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation { 47 | NSLog(@"页面加载失败"); 48 | } 49 | 50 | @end 51 | -------------------------------------------------------------------------------- /example/3.8node_universal/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "node_universal", 3 | "description": "", 4 | "version": "1.0.0", 5 | "author": "putaoshu", 6 | "license": "MIT", 7 | "dependencies": { 8 | "react": "15.1.0", 9 | "react-dom": "15.1.0", 10 | "react-redux": "4.4.5", 11 | "react-router": "2.4.1", 12 | "react-router-redux": "4.0.5", 13 | "redux": "3.5.2", 14 | "redux-thunk": "2.1.0" 15 | }, 16 | "devDependencies": { 17 | 18 | "autoprefixer": "6.3.6", 19 | "babel-cli": "6.10.1", 20 | "babel-core": "6.9.1", 21 | "babel-loader": "6.2.4", 22 | "babel-preset-es2015": "6.9.0", 23 | "babel-preset-react": "6.5.0", 24 | "babel-preset-stage-1": "6.5.0", 25 | "babel-register": "6.9.0", 26 | "css-loader": "0.23.1", 27 | "css-modules-require-hook": "4.0.1", 28 | "express": "4.14.0", 29 | 30 | "extract-text-webpack-plugin": "1.0.1", 31 | "isomorphic-fetch": "2.2.1", 32 | "marked": "0.3.5", 33 | 34 | "request": "2.72.0", 35 | "scroll-behavior": "0.4.0", 36 | "serialize-javascript": "1.3.0", 37 | 38 | "postcss-loader": "0.8.2", 39 | "style-loader": "0.13.1", 40 | "webpack": "1.13.0", 41 | "webpack-dev-middleware": "1.6.1", 42 | 43 | "webpack-dev-server": "1.6.4", 44 | "webpack-hot-middleware": "2.10.0", 45 | "react-hot-loader": "1.3.0", 46 | 47 | "cross-env": "1.0.7" 48 | }, 49 | "scripts": { 50 | "clean": "rm public/bundle.js && rm public/style.css && rm public/vendor.js || true", 51 | "build": "webpack --config webpack.config.prod.js", 52 | "dev": "cross-env NODE_ENV=dev node server.js", 53 | "prod": "cross-env NODE_ENV=prod node server.js" 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /example/2.14jdf/source/lib/fileFormat.js: -------------------------------------------------------------------------------- 1 | var beautify = require('js-beautify'); 2 | var f = require('./file.js'); 3 | var $ = require('./base.js'); 4 | 5 | 6 | /** 7 | * @init 8 | * @param {String} filename 文件名称 9 | */ 10 | exports.init = function(filename){ 11 | if(!typeof(filename) !== 'undefined'){ 12 | if(f.isDir(filename)){ 13 | var filelist = f.getdirlist(filename, '(html|vm|tpl|css|scss|less|js)$'); 14 | 15 | filelist.forEach(function(file){ 16 | route(file); 17 | }); 18 | 19 | }else{ 20 | route(filename); 21 | } 22 | } 23 | 24 | function route(file){ 25 | var exists = f.exists(file); 26 | 27 | if(exists){ 28 | if($.is.html(file) || $.is.vm(file) || $.is.tpl(file)){ 29 | htmlFormat(file); 30 | 31 | }else if($.is.css(file) || $.is.less(file) || $.is.sass(file)){ 32 | cssFormat(file); 33 | 34 | }else if($.is.js(file)){ 35 | jsFormat(file); 36 | 37 | }else{ 38 | console.log('jdf warning: can not format the [' + file + '].\n'); 39 | } 40 | }else{ 41 | console.log('jdf error: the [' + file + '] may be not exist.'); 42 | } 43 | } 44 | } 45 | 46 | function htmlFormat(filename){ 47 | var content = f.read(filename); 48 | 49 | f.write(filename, beautify.html_beautify(content)); 50 | console.log('jdf format ['+filename+'] success'); 51 | } 52 | 53 | function cssFormat(filename){ 54 | var content = f.read(filename); 55 | 56 | f.write(filename, beautify.css_beautify(content)); 57 | console.log('jdf format ['+filename+'] success'); 58 | } 59 | 60 | function jsFormat(filename){ 61 | var content = f.read(filename); 62 | 63 | f.write(filename, beautify.js_beautify(content)); 64 | console.log('jdf format ['+filename+'] success'); 65 | } 66 | -------------------------------------------------------------------------------- /example/3.11lazyload/lazyload.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | lazyload 7 | 8 | 9 |

    请往下翻

    10 | 11 |
      12 | 13 | 14 | 15 | 16 | 17 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /example/4.iOSWebView/iOSWebView/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /example/2.14jdf/source/doc/a_tool_format.md: -------------------------------------------------------------------------------- 1 | # html/js/css文件格式化 2 | 3 | ## 使用说明 4 | 5 | * 方法1:在当前目录中,使用 `jdf format` 或者 `jdf format ./test` 可直接格式化当前目录或者指定目录下的所有文件。 6 | * 方法2:在当前目录中,使用 `jdf format test.html` 可直接格式化指定的文件。 7 | 8 | ## 使用示例 9 | 10 | `jdf format` 可快速格式化文件中的代码格式,比如 `test.html` 的内容如下: 11 | 12 | 13 | 14 | 15 | 16 | Document 17 | 18 | 19 |
      20 |

      jdf format

      21 |
      22 | 25 | 28 | 29 | 30 | 31 | 执行 `jdf format test.html` 或者 `jdf f test.html` 命令之后,此文件的代码会被格式化成: 32 | 33 | 34 | 35 | 36 | 37 | Document 38 | 39 | 40 |
      41 |

      jdf format 42 |

      43 |
      44 | 51 | 57 | 58 | 59 | 60 | ## 注意事项 61 | 62 | * 此工具会自动**递归格式化**指定目录中所有的html、vm、tpl、css、sass、less、js文件,其它文件会自动忽略,请谨慎指定目录。 63 | * 此工具会同时格式化html文档中包含的所有html、css、js代码。 64 | * 格式化后的代码会被覆盖保存到原文件中。 -------------------------------------------------------------------------------- /example/4.iOSWebView/iOSWebView/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /example/4.iOSWebView/iOSWebView/JSSDKViewControllerBase/WebViewJavascriptBridgeBase.h: -------------------------------------------------------------------------------- 1 | // 2 | // WebViewJavascriptBridgeBase.h 3 | // 4 | // Created by @LokiMeyburg on 10/15/14. 5 | // Copyright (c) 2014 @LokiMeyburg. All rights reserved. 6 | // 7 | 8 | #import 9 | 10 | #define kOldProtocolScheme @"wvjbscheme" 11 | #define kNewProtocolScheme @"https" 12 | #define kQueueHasMessage @"__wvjb_queue_message__" 13 | #define kBridgeLoaded @"__bridge_loaded__" 14 | 15 | typedef void (^WVJBResponseCallback)(id responseData); 16 | typedef void (^WVJBHandler)(id data, WVJBResponseCallback responseCallback); 17 | typedef NSDictionary WVJBMessage; 18 | 19 | @protocol WebViewJavascriptBridgeBaseDelegate 20 | - (NSString*) _evaluateJavascript:(NSString*)javascriptCommand; 21 | @end 22 | 23 | @interface WebViewJavascriptBridgeBase : NSObject 24 | 25 | 26 | @property (weak, nonatomic) id delegate; 27 | @property (strong, nonatomic) NSMutableArray* startupMessageQueue; 28 | @property (strong, nonatomic) NSMutableDictionary* responseCallbacks; 29 | @property (strong, nonatomic) NSMutableDictionary* messageHandlers; 30 | @property (strong, nonatomic) WVJBHandler messageHandler; 31 | 32 | + (void)enableLogging; 33 | + (void)setLogMaxLength:(int)length; 34 | - (void)reset; 35 | - (void)sendData:(id)data responseCallback:(WVJBResponseCallback)responseCallback handlerName:(NSString*)handlerName; 36 | - (void)flushMessageQueue:(NSString *)messageQueueString; 37 | - (void)injectJavascriptFile; 38 | - (BOOL)isWebViewJavascriptBridgeURL:(NSURL*)url; 39 | - (BOOL)isQueueMessageURL:(NSURL*)urll; 40 | - (BOOL)isBridgeLoadedURL:(NSURL*)urll; 41 | - (void)logUnkownMessage:(NSURL*)url; 42 | - (NSString *)webViewJavascriptCheckCommand; 43 | - (NSString *)webViewJavascriptFetchQueyCommand; 44 | - (void)disableJavscriptAlertBoxSafetyTimeout; 45 | 46 | @end 47 | -------------------------------------------------------------------------------- /example/4.iOSWebView/iOSWebView/globalWebViewBase/Source/WKWebView + HPKDelegateExtension.h: -------------------------------------------------------------------------------- 1 | // 2 | // WKWebView + HPKDelegateExtension.h 3 | // 4 | // Copyright (c) 2019 dequanzhu 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | // 24 | 25 | 26 | #import 27 | 28 | @interface WKWebView (HPKDelegateExtension) 29 | 30 | - (void)_useExternalNavigationDelegateAndWithDefaultUIDelegate:(BOOL)useDefaultUIDelegate; 31 | - (void)_setNavigationDelegate:(id)delegate __attribute__((unavailable)); 32 | - (void)_setMainNavigationDelegate:(NSObject *)mainDelegate; 33 | - (void)_addSecondaryNavigationDelegate:(NSObject *)delegate; 34 | - (void)_removeSecondaryNavigationDelegate:(NSObject *)delegate; 35 | - (void)_removeAllSecondaryNavigationDelegates; 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /example/2.14jdf/source/doc/core_dir_standard.md: -------------------------------------------------------------------------------- 1 | # 目录规范 2 | 3 | ## 名词解释 4 | 5 | * widget 为可共用的实际项目中组件 6 | * 项目目录 为当前要开发的项目目录 7 | * 输出目录 为联调测试时用的目录 8 | * 上线目录 为实际上线后的目录 9 | 10 | ## 项目目录规范 11 | 12 | * 项目目录 13 | 14 | ├─────jdf_init //项目根目录 15 | | ├── css //css文件夹 16 | | | └── i //图片文件夹 17 | | ├── js //js文件夹 18 | | ├── html //预览页面html 19 | | ├── html/images //预览页面的素材图片文件夹 20 | | ├── doc //项目文档,项目介绍 21 | | ├── widget //组件目录,包括模板组件,js组件,css组件 22 | | | └── header 23 | | | ├── header.vm //模板文件 24 | | | ├── header.json //vm的数据源文件 25 | | | ├── header.css //css文件 26 | | | ├── header.js //js文件 27 | | | ├── i/ //等待上线的图片文件夹 28 | | | ├── images/ //素材图片文件夹 29 | | | └── header.js //js文件 30 | | └── config.json //配置文件 31 | 32 | 33 | * 输出目录 34 | 35 | ├──jdf_demo //变更名称可修改config.json中的"projectPath" 36 | | ├── css //css文件目录 37 | | ├── html //预览页面html,仅供测试用 38 | | └── js //js文件目录 39 | 40 | * 上线目录 41 | 42 | ├──jdf_demo 43 | | ├── css //css文件目录 44 | | ├── css/i //图片文件目录 45 | | └── js //js文件目录 46 | 47 | ## widget目录规范 48 | 49 | * widget目录 50 | 51 | ├── widget //模块化目录,包括模板组件,js组件,css组件 52 | | └── header 53 | | ├── header.vm //模板文件 54 | | ├── header.source //vm的数据源文件 55 | | ├── header.css //css文件 56 | | ├── header.js //js文件 57 | | └── header.png //图片文件 58 | 59 | * 目录说明 60 | * header.source为当前tpl数据源文件 61 | 62 | * widget目录细化 63 | * 模板组件: 包括tpl模板,css,js 64 | * css组件: 仅提供必要的css支持,一般会和tpl一起使用 65 | * js组件: 仅提供必要的js支持, 一般也会和tpl一起使用 66 | 67 | ## 图片目录规范 68 | 69 | * 如下 70 | 71 | ├─────jdf_demo 72 | | ├── css //css文件夹 73 | | | └── i //图片文件夹 74 | | ├── widget //组件目录,包括模板组件,js组件,css组件 75 | | | └── header 76 | | | ├── header.css //css文件 77 | | | ├── i/ //等待上线的图片文件夹 78 | | | ├── images/ //素材图片文件夹 79 | | | └── header.js //图片文件 80 | 81 | * 说明 82 | * widget中: 要上线的的图片放在当前widget的i文件夹下, 素材图片放在images文件夹下 83 | * /css/中: 图片放在当css/的i文件夹下 84 | * 上线时widget中的图片会全部复制至/css/i下 85 | -------------------------------------------------------------------------------- /example/4.iOSWebView/iOSWebView/JSSDKViewControllerBase/WebViewJavascriptBridge.h: -------------------------------------------------------------------------------- 1 | // 2 | // WebViewJavascriptBridge.h 3 | // ExampleApp-iOS 4 | // 5 | // Created by Marcus Westin on 6/14/13. 6 | // Copyright (c) 2013 Marcus Westin. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "WebViewJavascriptBridgeBase.h" 11 | 12 | #if (__MAC_OS_X_VERSION_MAX_ALLOWED > __MAC_10_9 || __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_7_1) 13 | #define supportsWKWebView 14 | #endif 15 | 16 | #if defined supportsWKWebView 17 | #import 18 | #endif 19 | 20 | #if defined __MAC_OS_X_VERSION_MAX_ALLOWED 21 | #define WVJB_PLATFORM_OSX 22 | #define WVJB_WEBVIEW_TYPE WebView 23 | #define WVJB_WEBVIEW_DELEGATE_TYPE NSObject 24 | #define WVJB_WEBVIEW_DELEGATE_INTERFACE NSObject 25 | #elif defined __IPHONE_OS_VERSION_MAX_ALLOWED 26 | #import 27 | #define WVJB_PLATFORM_IOS 28 | #define WVJB_WEBVIEW_TYPE UIWebView 29 | #define WVJB_WEBVIEW_DELEGATE_TYPE NSObject 30 | #define WVJB_WEBVIEW_DELEGATE_INTERFACE NSObject 31 | #endif 32 | 33 | @interface WebViewJavascriptBridge : WVJB_WEBVIEW_DELEGATE_INTERFACE 34 | 35 | 36 | + (instancetype)bridgeForWebView:(id)webView; 37 | + (instancetype)bridge:(id)webView; 38 | 39 | + (void)enableLogging; 40 | + (void)setLogMaxLength:(int)length; 41 | 42 | - (void)registerHandler:(NSString*)handlerName handler:(WVJBHandler)handler; 43 | - (void)removeHandler:(NSString*)handlerName; 44 | - (void)callHandler:(NSString*)handlerName; 45 | - (void)callHandler:(NSString*)handlerName data:(id)data; 46 | - (void)callHandler:(NSString*)handlerName data:(id)data responseCallback:(WVJBResponseCallback)responseCallback; 47 | - (void)setWebViewDelegate:(id)webViewDelegate; 48 | - (void)disableJavscriptAlertBoxSafetyTimeout; 49 | 50 | @end 51 | -------------------------------------------------------------------------------- /example/4.iOSWebView/iOSWebView/globalWebViewBase/Source/HPKCommonViewPool.h: -------------------------------------------------------------------------------- 1 | // 2 | // HPKCommonViewPool.h 3 | // 4 | // Copyright (c) 2019 dequanzhu 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | // 24 | 25 | 26 | #import "HPKViewProtocol.h" 27 | /** 28 | * 底层页Components复用回收池 29 | */ 30 | @interface HPKCommonViewPool : NSObject 31 | 32 | + (HPKCommonViewPool *)sharedInstance; 33 | 34 | /** 35 | 从回收池中根据class取View 36 | */ 37 | - (HPKView *)dequeueComponentViewWithClass:(Class)viewClass; 38 | 39 | /** 40 | 回收相应view 41 | */ 42 | - (void)enqueueComponentView:(HPKView *)componentView; 43 | 44 | /** 45 | 回收某个view上的全部components View 46 | */ 47 | - (void)enqueueAllComponentViewsOfSuperView:(__kindof UIView *)superView; 48 | 49 | /** 50 | 重置View状态 51 | */ 52 | - (void)resetVisibleComponentViewState:(HPKView *)componentView; 53 | 54 | /** 55 | 清理全部复用View 56 | */ 57 | - (void)clearAllReusableComponentViews; 58 | @end 59 | -------------------------------------------------------------------------------- /example/4.iOSWebView/iOSWebView/globalViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // globalViewController.m 3 | // iOSWebView 4 | // 5 | // Copyright © 2019 putaoshu. Licensed under the MIT license. 6 | // 7 | 8 | #import "globalWebViewBase/HPKPageManager.h" 9 | #import "globalWebViewBase/HPKWebView.h" 10 | 11 | #import "globalViewController.h" 12 | #import 13 | 14 | @interface SingleWebView : HPKWebView 15 | @end 16 | @implementation SingleWebView 17 | @end 18 | 19 | @interface globalViewController () 20 | @property (nonatomic, strong, readwrite) SingleWebView *webView; 21 | @end 22 | 23 | @implementation globalViewController 24 | 25 | - (void)dealloc { 26 | [[HPKPageManager sharedInstance] enqueueWebView:self.webView]; 27 | } 28 | 29 | - (void)viewDidLoad { 30 | [super viewDidLoad]; 31 | NSLog(@"viewDidLoad"); 32 | 33 | [self.view addSubview:({ 34 | _webView = [[HPKPageManager sharedInstance] dequeueWebViewWithClass:[SingleWebView class] webViewHolder:self]; 35 | 36 | _webView.navigationDelegate = self; 37 | 38 | _webView.frame = CGRectMake(0, 50, self.view.frame.size.width, self.view.frame.size.height - CGRectGetMaxY(self.navigationController.navigationBar.frame));; 39 | 40 | [_webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"https://m.baidu.com"]]]; 41 | _webView; 42 | })]; 43 | } 44 | 45 | #pragma mark - 加载状态的回调 46 | // 页面开始加载时调用 47 | - (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation { 48 | NSLog(@"页面开始加载"); 49 | } 50 | // 当内容开始返回时调用 51 | - (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation { 52 | NSLog(@"数据开始返回"); 53 | } 54 | 55 | // 页面加载完成之后调用 56 | - (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation { 57 | NSLog(@"页面已经加载完成"); 58 | } 59 | // 页面加载失败时调用 60 | - (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation { 61 | NSLog(@"页面加载失败"); 62 | } 63 | 64 | @end 65 | -------------------------------------------------------------------------------- /example/4.iOSWebView/iOSWebView/globalWebViewBase/Source/WKWebView + HPKReusable.h: -------------------------------------------------------------------------------- 1 | // 2 | // WKWebView + HPKReusable.h 3 | // 4 | // Copyright (c) 2019 dequanzhu 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | // 24 | 25 | 26 | #import 27 | 28 | @protocol HPKReusableWebViewProtocol 29 | @optional 30 | - (void)componentViewWillLeavePool; //即将离开回收池 31 | - (void)componentViewWillEnterPool; //即将进入回收池 32 | @end 33 | 34 | @interface WKWebView (HPKReusable) 35 | 36 | @property (nonatomic, weak, readwrite) NSObject *holderObject; 37 | @property (nonatomic, assign, readwrite) NSInteger reusedTimes; 38 | @property (nonatomic, assign, readwrite) BOOL invalid; 39 | 40 | - (void)componentViewWillLeavePool __attribute__((objc_requires_super)); //即将离开回收池 41 | - (void)componentViewWillEnterPool __attribute__((objc_requires_super)); //即将进入回收池 42 | 43 | #pragma mark - clear backForwardList 44 | 45 | - (void)_clearBackForwardList; 46 | 47 | @end 48 | -------------------------------------------------------------------------------- /example/2.14jdf/source/doc/core_widget.md: -------------------------------------------------------------------------------- 1 | # widget模块 2 | 3 | ## widget定义 4 | * widget模块是可复用并且能独立提供功能的页面片段,可以在单个项目里面使用,也可以发布贡献出来供其它项目使用 5 | 6 | ## 引用和配置方法 7 | * 在页面中统一引入 8 | 9 | {%widget name="test"%} 10 | 11 | 此时当前widget文件夹下的vm编译到页面上,js和css也加载至页面上,同时json数据会打到vm里 12 | 13 | * 在页面中统一引入时,带相关数据 14 | 15 | {%widget name="test" data='{"name":"my"}'%} 16 | 17 | 此时在test.vm里就可以通过引用`$name`来取name的值了 18 | 19 | * 引入外部链接数据 20 | 21 | {%widget name="test" data='http://xxx.com/xxx.json'%} 22 | 23 | * 在页面中单独引入widget的vm文件 24 | 25 | {%widget name="test" type="vm"%} 26 | 27 | * 在页面中单独引入widget的vm文件 28 | 29 | {%widget name="test" type="vm"%} 30 | 31 | * 在页面中单独引入widget的js文件 32 | 33 | {%widget name="test" type="js"%} 34 | 35 | * 在页面中单独引入widget的css文件 36 | 37 | {%widget name="test" type="css"%} 38 | 39 | * widget引入时注释配置 40 | * 在页面中引入,不带文件路径注释 41 | 42 | {%widget name="test" comment="false"%} 43 | 44 | * 或在config.json里面配置统一的配置项 45 | 46 | build: { 47 | widgetIncludeComment:true //默认为true,不带可以设置成false 48 | } 49 | 50 | ## 页面编译输出 51 | 52 | 执行`jdf build` 53 | 54 | 55 | 56 | 57 | 58 | 59 |
      this is test
      60 | 61 | ## 页面交付输出 62 | 63 | 执行`jdf output` 64 | 65 | * 所有widget模块中css文件combo如下 66 | 67 | 68 | 69 | * 所有widget模块中js文件combo如下 70 | 71 | 72 | 73 | ## 相关命令 74 | 75 | * `widget -all` preview all widget //预览所有项目中所有widget 76 | * `widget -preview xxx` preview a widget //预览一个widget模块 77 | * `widget -install xxx` install a widget to local //安装一个widget模块到当前工程 78 | * `widget -publish xxx` publish a widget to server //发布一个widget模块到服务端 79 | * `widget -create xxx` create a widget to local //在本地项目新建一个widget,会生成widget文件夹和vm,css,js,json文件 80 | * `widget -list` get widget list from server //取得服务端所有widget列表 81 | 82 | -------------------------------------------------------------------------------- /example/2.14jdf/source/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jdf", 3 | "description": "Jingdong front-end integrated solution", 4 | "version": "2.1.52", 5 | "author": { 6 | "name": "jdf", 7 | "email": "putaoshu@126.com" 8 | }, 9 | "homepage": "https://github.com/putaoshu/jdf", 10 | "keywords": [ 11 | "jdf" 12 | ], 13 | "license": "MIT", 14 | "bin": { 15 | "jdf": "bin/jdf" 16 | }, 17 | "engines": { 18 | "node": ">= 4.2.6" 19 | }, 20 | "main": "index.js", 21 | "scripts": { 22 | "test": "mocha test/index.js" 23 | }, 24 | "repository": { 25 | "type": "git", 26 | "url": "https://github.com/putaoshu/jdf.git" 27 | }, 28 | "bugs": { 29 | "url": "http://github.com/putaoshu/jdf/issues" 30 | }, 31 | "preferGlobal": true, 32 | "readmeFilename": "README.md", 33 | "dependencies": { 34 | "atropa-jslint": "0.1.2", 35 | "clean-css": "2.1.8", 36 | "colors": "1.0.2", 37 | "csslint": "0.10.0", 38 | "expect.js": "0.3.1", 39 | "ftp": "0.3.6", 40 | 41 | "html-minifier": "0.6.9", 42 | "htmllint": "0.0.7", 43 | "iconv-lite": "0.4.13", 44 | 45 | "images": "^3.0.2", 46 | "jdf-png-native": "1.1.0", 47 | "jdf-ws": "1.0.3", 48 | 49 | "js-beautify": "1.5.4", 50 | "jsmart": "2.14.0", 51 | "less": "2.7.1", 52 | "node-watch": "0.4.1", 53 | "q": "1.0.1", 54 | "requirejs": "2.3.2", 55 | "simple-prompt": "0.2.1", 56 | "tar": "0.1.19", 57 | 58 | "velocityjs": "0.4.3", 59 | "webp-converter": "2.1.4", 60 | 61 | "babel-core": "6.18.2", 62 | "babel-preset-es2015": "6.18.0", 63 | "babel-preset-stage-1": "6.16.0", 64 | 65 | "async":"2.1.4", 66 | 67 | "autoprefixer":"6.5.3", 68 | "postcss":"5.2.6", 69 | "cssnext":"1.8.4", 70 | 71 | "commander": "2.9.0", 72 | 73 | "browser-sync":"2.18.2", 74 | 75 | "qrcode-terminal":"0.11.0", 76 | "node-sass": "^4.9.0", 77 | "uglify-js": "2.7.5", 78 | "sync-request": "4.0.1", 79 | 80 | "update-notifier": "2.1.0", 81 | 82 | "archiver": "2.0.0", 83 | "request": "2.83.0", 84 | 85 | "git-clone": "^0.1.0" 86 | }, 87 | "devDependencies": { 88 | "expect.js": "^0.3.1", 89 | "mocha": "3.2.0" 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /example/2.14jdf/source/lib/csslint.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @csslint 3 | * @ctime 2014-7-11 4 | * @wiki https://github.com/CSSLint/csslint/wiki/Command-line-interface 5 | */ 6 | 7 | var csslint = require('csslint').CSSLint; 8 | 9 | var f = require('./file.js'); 10 | var $ = require('./base.js'); 11 | var colors = require('colors'); 12 | var os = require('os'); 13 | 14 | function csslintInit(filename, fileContent){ 15 | var content = ''; 16 | if(typeof(fileContent) == 'undefined'){ 17 | content = f.read(filename); 18 | }else{ 19 | content = fileContent; 20 | } 21 | 22 | var result = csslint.verify(content); 23 | 24 | if(result && result.messages.length){ 25 | var n = 0; 26 | var messagesType = function (type){ 27 | return type == 'error' || type == 'warning'; 28 | } 29 | result.messages.forEach(function (message, i){ 30 | var type = message.type; 31 | if(messagesType(type)){ 32 | n += 1; 33 | } 34 | }); 35 | 36 | console.log(os.EOL + 'jdf csslint: ' + filename); 37 | 38 | result.messages.forEach(function (message, index){ 39 | var type = message.type; 40 | 41 | if(messagesType(type)){ 42 | console.log('#'+(index+1)); 43 | console.log(colors.red('> '), 'line: ' + message.line + ', column: ' + message.col); 44 | console.log(colors.red('> '), 'msg: ' + message.message); 45 | console.log(colors.red('> '), 'at: ' + message.evidence); 46 | } 47 | }); 48 | 49 | }else{ 50 | console.log('jdf csslint: ' + filename + ' is ok' ); 51 | } 52 | } 53 | 54 | /** 55 | * @init 56 | * @param {String} filename 文件名称 57 | * @param {String} fileContent 文件内容 58 | */ 59 | 60 | exports.init = function(filename, fileContent){ 61 | if(typeof(fileContent) == 'undefined'){ 62 | if(f.isDir(filename)){ 63 | var filelist = f.getdirlist(filename, '(css|scss|less)$'); 64 | filelist.forEach(function(item){ 65 | csslintInit(item); 66 | }) 67 | }else if(f.isFile(filename) && ($.is.css(filename) || $.is.less(filename) || $.is.sass(filename) ) ){ 68 | csslintInit(filename); 69 | }else{ 70 | console.log('jdf csslint ' + filename + ' is not exists'); 71 | } 72 | }else{ 73 | csslintInit(filename, fileContent); 74 | } 75 | } -------------------------------------------------------------------------------- /example/2.14jdf/source/lib/vm.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @vm 3 | */ 4 | var path = require('path'); 5 | var fs = require('fs'); 6 | var util = require('util'); 7 | 8 | var $ = require('./base.js'); 9 | var f = require('./file.js'); 10 | var jdf = require("./jdf.js"); 11 | 12 | var Velocity = require('velocityjs'); 13 | 14 | //exports 15 | var vm = module.exports; 16 | 17 | /** 18 | * @velocityjs extend 19 | * @{String} str 数据内容 20 | * @{String} dirname 文件的dirname 21 | */ 22 | vm.parse = function(str, dirname){ 23 | var dirname = typeof dirname == 'undefined' ? '' : dirname; 24 | var arr = str.match(/^(){0}/gmi); 25 | var res = { 26 | vm:[], 27 | tpl:[], 28 | js:[], 29 | css:[] 30 | }; 31 | 32 | if (arr) { 33 | for (var i =0 ; i 32 | /** 33 | 默认内置的webview 34 | */ 35 | @property (nonatomic, strong, readonly) __kindof HPKWebView *defaultWebView; 36 | 37 | /** 38 | 默认内置webview对应的model 39 | */ 40 | @property (nonatomic, strong, readonly) HPKModel *defaultWebViewModel; 41 | 42 | /** 43 | 生成默认的webview,webviewModel以及navigation delegate扩展 44 | 45 | @param detailHandler HPKPageHandler 46 | @param webViewClass webview的class,应该是HPKWebView的子类 47 | @param defaultWebViewIndex webview在container中的index 48 | */ 49 | - (instancetype)initWithDetailHandler:(HPKPageHandler *)detailHandler 50 | defaultWebViewClass:(Class)webViewClass 51 | defaultWebViewIndex:(NSInteger)defaultWebViewIndex; 52 | 53 | /** 54 | 重置defaultWebview,生成新的webview,并清理复用回收池 55 | */ 56 | - (void)resetWebView; 57 | 58 | /** 59 | webView contentSize变化回调 60 | */ 61 | - (void)webviewContentSizeChange:(__kindof HPKWebView *)webView 62 | newSize:(CGSize)newSize 63 | oldSize:(CGSize)oldSize; 64 | 65 | @end 66 | -------------------------------------------------------------------------------- /example/4.iOSWebView/iOSWebView/globalWebViewBase/Source/_HPKUtils.h: -------------------------------------------------------------------------------- 1 | // 2 | // _HPKUtils.h 3 | // 4 | // Copyright (c) 2019 dequanzhu 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | // 24 | 25 | 26 | #ifndef _HPKUtils_h 27 | #define _HPKUtils_h 28 | 29 | #import "HPKPageManager.h" 30 | 31 | #define HPKInfoLog(logformat, ...) \ 32 | [[HPKPageManager sharedInstance] logWithErrorLevel:kHPKLogLevelInfo logFormat:(logformat), ## __VA_ARGS__]; 33 | 34 | #define HPKErrorLog(logformat, ...) \ 35 | [[HPKPageManager sharedInstance] logWithErrorLevel:kHPKLogLevelError logFormat:(logformat), ## __VA_ARGS__]; 36 | 37 | #define HPKFatalLog(logformat, ...) \ 38 | [[HPKPageManager sharedInstance] logWithErrorLevel:kHPKLogLevelFatal logFormat:(logformat), ## __VA_ARGS__]; 39 | 40 | @interface HPKPageManager (_utils) 41 | - (void)logWithErrorLevel:(HPKLogLevel)errorLevel logFormat:(NSString *)logFormat, ... NS_FORMAT_FUNCTION(2, 3); 42 | @end 43 | 44 | typedef void (^HPKKVOCallback)(NSObject *oldValue, NSObject *newValue); 45 | @interface NSObject (HPKKVO) 46 | 47 | - (void)safeAddObserver:(id)observer keyPath:(NSString *)keyPath callback:(HPKKVOCallback)callback; 48 | - (void)safeRemoveObserver:(id)observer keyPath:(NSString *)keyPath; 49 | - (void)safeRemoveAllObserver; 50 | @end 51 | 52 | #pragma mark - 53 | 54 | #define isiOS13Beta1 \ 55 | ([@"13.0" isEqualToString:[[UIDevice currentDevice] systemVersion]]) 56 | 57 | #endif /* _HPKUtils_h */ 58 | -------------------------------------------------------------------------------- /example/3.7bigpipe/index.php: -------------------------------------------------------------------------------- 1 | \n"; 25 | } 26 | 27 | function test_simple_replace($msg){ 28 | global $use_padding; 29 | $padding = ''; 30 | if ($use_padding) { 31 | for ($i = 0; $i < 8192; $i++) { $padding .= ' '; } 32 | } 33 | return "$msg
      \n"; 34 | } 35 | ?> 36 | 37 | 38 | 39 | 40 | 41 | BigPipe example 42 | 43 | 44 | 45 | 46 |

      BigPipe test

      47 | 48 |

      1、增加文本

      49 | 52 | 53 |

      2、延时30s

      54 | use_span = true; 58 | echo $pagelet; 59 | } 60 | $pagelet = new Pagelet("delayed_done", "test_simple_replace", 10, array('Ok 2')); 61 | $pagelet->use_span = true; 62 | echo $pagelet; 63 | ?> 64 | 65 |

      3、增加内联js片断

      66 | add_content('
      -
      '); 69 | $pagelet->add_javascript_code("$('javascript_inline_test').innerHTML = 'Ok 3';"); 70 | echo $pagelet; 71 | ?> 72 | 73 | 74 |

      4、增加js文件和内联js片断

      75 |
      -
      76 | add_javascript('test2.js'); 79 | $pagelet->add_javascript_code("test2('external_js2', 'Ok 4');"); 80 | echo $pagelet; 81 | 82 | $pagelet = new Pagelet('final_ok'); 83 | $pagelet->add_javascript_code("$('header').innerHTML = 'All done';", 12); 84 | echo $pagelet; 85 | 86 | echo "\n"; 87 | BigPipe::render(); 88 | -------------------------------------------------------------------------------- /example/2.14jdf/source/doc/a_tool_lint.md: -------------------------------------------------------------------------------- 1 | # html/js/css文件lint代码质量检查 2 | 3 | ## 使用说明 4 | 5 | * 方法1:在当前目录中,使用 `jdf lint` 或者 `jdf lint ./test` 可直接检查当前目录或者指定目录下的所有文件。 6 | * 方法2:在当前目录中,使用 `jdf lint test.html` 可直接检查指定的文件。 7 | * 方法3:可直接使用 `jdf lint http://www.jd.com` 检查在线页面。 8 | 9 | ## 检查html文件 10 | 11 | `jdf lint` 可以快速检测html文件中代码的书写错误,比如 `test.html` 的内容如下: 12 | 13 |
      14 |
      15 | 16 | 17 | 18 | 运行 `jdf lint test.html` 命令之后,会看到以下提示信息: 19 | 20 | jdf lint: test/test.html 21 | #1 22 | >> line: 9, column: 2 23 | >> msg: the id "box" is already in use 24 | #2 25 | >> line: 10, column: 2 26 | >> msg: the "type" attribute is not double quoted 27 | 28 | 很明显,在此hmtl文件中存在两个问题: 29 | 30 | * 问题1:页面中有两个元素使用了重复的id 31 | * 问题2:`input` 元素的 `type` 属性值没有加双引号 32 | 33 | ## 检查css文件 34 | 35 | `jdf lint` 可以快速检测css的书写错误,比如 `btn.css` 内容如下: 36 | 37 | .btn{ 38 | colo: #fff 39 | border:1px solid red; 40 | } 41 | 42 | 很明显 `.btn` 样式存在两个问题 43 | 44 | * 问题1: `colo` 属性是不存在的,可能应该为 `color` 45 | * 问题2: `colo: #fff` 后和 `border:1px solid red;` 前少了一个分号 `;` 46 | 47 | 此时jdf命令行下会有如下提示,方便查找问题所在 48 | 49 | jdf csslint: There are 2 problems in lib/csslint.css 50 | 51 | #1 warning at line 2, col 2 52 | Unknown property 'colo'. 53 | colo: #fff 54 | 55 | #2 error at line 3, col 8 56 | Expected RBRACE at line 3, col 8. 57 | border:1px solid red; 58 | 59 | 注意:less/scss文件需要编译成css后才能检测,否则提示会不准确。 60 | 61 | ## 检查js文件 62 | 63 | `jdf lint` 可快速检测js代码的书写错误,比如 `test.js` 的内容如下: 64 | 65 | function test() { 66 | var a = 1 67 | } 68 | 69 | 运行 `jdf lint test.js` 命令之后,会看到以下提示信息: 70 | 71 | #1 72 | >> line: 4, column: 12 73 | >> msg: Expected ";" and instead saw "}". 74 | >> at: var a = 1 75 | #2 76 | >> line: 4, column: 7 77 | >> msg: Unused "a". 78 | >> at: var a = 1 79 | 很明显,在此js文件中有两个问题: 80 | 81 | * 问题1:在代码 `var a = 1` 结尾处没有加分号 82 | * 问题2:a变量只是被定义了,却没有被使用 83 | 84 | ## 注意事项 85 | 86 | * 此工具会自动**递归检查**指定目录中所有的html、vm、tpl、css、sass、less、js文件,其它文件会自动忽略。 87 | * 在使用 `jdf lint` 检查在线页面时,url前必须要加上http。 88 | * 默认csslint功能是关闭状态,可以通过config.json的{{build.csslint}}键值设置为true进行开启,这样在 `jdf build` 下会自动检测 89 | 90 | ## 原理浅析 91 | 92 | csslint可用于检查CSS取值和潜在问题,使用了Nicholas大神的npm模块parser-lib作为css解析器,并按照parser-lib给出的API来编写检查规则。 93 | csslint的每一个规则都是通过监听parser-lib给出的事件来进行相应的判断: 94 | 95 | * startrule为规则开始 96 | * property为找到一个属性时的事件 97 | * endrule为一个规则结束 98 | 99 | 一旦规则结束并且没有统计到任何property,则说明规则为空。 100 | -------------------------------------------------------------------------------- /example/2.14jdf/source/doc/core_vm.md: -------------------------------------------------------------------------------- 1 | # vm模板 2 | 3 | ## 设计原则 4 | 让前端来写后端的vm模板,并且前端不需要搭建各种繁杂的后端环境,前后端以 .vm 为沟通桥梁,另外模板的数据源可以在项目开始前前后端约定之后生成JSON文件,从而使两个角色并行开发。 5 | 6 | ## velocity模板引挚 7 | velocity模板语法的javascript实现,Velocity是基于Java的模板引擎,应用广泛。Velocity模板适用于大量模板使用的场景,支持模板嵌套,复杂的逻辑运算,包含基本数据类型、变量赋值和函数等功能。 8 | 9 | ## 目录结构 10 | * html/vm.html 11 | * widget/vm/vm.json 12 | * widget/vm/vm.vm 13 | 14 | ## 引用方法 15 | 16 | {%widget name="vm" data='{"name":"myname"}'%} 17 | 18 | 注意data之间的单双引号,data内容必须为json类型 19 | 20 | ## 数据源分类 21 | * data传参数据源,如 {%widget name="vm" data='{"name":"myname"}' %} 中的{"name":"myname"} 22 | * 数据源文件,如widget/vm/vm.json的内容 23 | * 两者优先级 "data传参数据源" > "数据源文件",即data传参数据源和数据源文件,数据名称相同时,以"data传参数据源"为准 24 | 25 | ## velocity基本语法 26 | 27 | * 1."#"用来标识Velocity的脚本语句,包括#set、#if 、#else、#end、#foreach、#end、#iinclude、#parse、#macro等,如: 28 | 29 | #if($info.images) 30 | 31 | #else 32 | 33 | #end 34 | 35 | * 2."$"用来标识一个变量,如 36 | 37 | $i、$msg.errorNum 38 | 39 | * 3."!"用来强制把不存在的变量显示为空白 40 | 41 | $!msg 42 | 43 | * 4.注释,如: 44 | 45 | ## 这是一行注释,不会输出 46 | 47 | ## velocity语法详解 48 | 49 | 具体更详细的语法可参考[官网] (http://velocity.apache.org/engine/devel/user-guide.html) 50 | 如vm.vm 51 | 52 | 53 | * 1.变量赋值输出 54 | 55 | Welcome $name to Javayou.com! 56 | today is $date. 57 | tdday is $mydae.//未被定义的变量将当成字符串 58 | 59 | * 2.设置变量值,所有变量都以$开头 60 | 61 | #set( $iAmVariable = "good!" ) 62 | Welcome $name to Javayou.com! 63 | today is $date. 64 | $iAmVariable 65 | 66 | * 3.if,else判断 67 | 68 | #set ($admin = "admin") 69 | #set ($user = "user") 70 | #if ($admin == $user) 71 | Welcome admin! 72 | #else 73 | Welcome user! 74 | #end 75 | 76 | * 4.迭代数据List ($velocityCount为列举序号,默认从1开始) 77 | 78 | #foreach( $product in $allProducts ) 79 |
    • $velocityCount $product.title
    • 80 | #end 81 | 82 | * 5.迭代数据get key 83 | 84 | #foreach($key in $myProducts.keySet() ) 85 | $key `s value: $myProducts.get($key) 86 | #end 87 | 88 | * 6.导入其它文件,可输入多个 89 | 90 | #parse("vm_a.vm") 91 | #parse("vm_b.vm") 92 | 93 | * 7.[todo多个文件用逗号隔开] 94 | 95 | * 8.简单遍历多个div 96 | #foreach( $i in [1,2,3,4] ) 97 |
      $i
      98 | #end 99 | 100 | 101 | 102 | ## 数据源举例 103 | 104 | 如vm.json 105 | 106 | { 107 | "name":"vm name", 108 | "allProducts":[ 109 | { 110 | "title": "风", 111 | "from": "中国" 112 | }, 113 | { 114 | "title": "应用", 115 | "from": "河北" 116 | } 117 | ], 118 | "myProducts":{ 119 | "age":9, 120 | "from":"cn" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /example/4.iOSWebView/iOSWebView/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // iOSWebView 4 | // 5 | // Copyright © 2019 putaoshu. Licensed under the MIT license. 6 | // 7 | 8 | #import "AppDelegate.h" 9 | #import "homeViewController.h" 10 | #import "navViewController.h" 11 | 12 | 13 | @interface AppDelegate () 14 | 15 | @end 16 | 17 | @implementation AppDelegate 18 | 19 | 20 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 21 | 22 | self.window = [[UIWindow alloc]initWithFrame:[[UIScreen mainScreen] bounds]]; 23 | self.window.backgroundColor = [UIColor whiteColor]; 24 | homeViewController *vc = [[homeViewController alloc] init]; 25 | 26 | navViewController *nav = [[navViewController alloc] initWithRootViewController:vc]; 27 | 28 | self.window.rootViewController = nav; 29 | [self.window makeKeyAndVisible]; 30 | 31 | 32 | return YES; 33 | } 34 | 35 | 36 | - (void)applicationWillResignActive:(UIApplication *)application { 37 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 38 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 39 | } 40 | 41 | 42 | - (void)applicationDidEnterBackground:(UIApplication *)application { 43 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 44 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 45 | } 46 | 47 | 48 | - (void)applicationWillEnterForeground:(UIApplication *)application { 49 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 50 | } 51 | 52 | 53 | - (void)applicationDidBecomeActive:(UIApplication *)application { 54 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 55 | } 56 | 57 | 58 | - (void)applicationWillTerminate:(UIApplication *)application { 59 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 60 | } 61 | 62 | 63 | @end 64 | -------------------------------------------------------------------------------- /example/4.iOSWebView/iOSWebView/login.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 11 | 12 | 13 | 57 | 58 | 62 | 63 | 64 | 65 |
      66 | 67 | 68 |
      Login Callback
      69 | 70 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /example/2.14jdf/source/doc/core_css.md: -------------------------------------------------------------------------------- 1 | # css组件 2 | 3 | ## 设计原则 4 | 5 | 简单,实用,可复用 6 | 7 | ## css组件 8 | 9 | * 基础库 10 | * reset 11 | * lib 12 | * scss基类 [https://github.com/marvin1023/sassCore/blob/master/core/_css3.scss](https://github.com/marvin1023/sassCore/blob/master/core/_css3.scss) 13 | * transitionPropertyName 14 | * border-radius 15 | * box-shadow 16 | * translate、scale 17 | * animation 18 | * grid 19 | 20 | * 元件/静态组件 21 | 22 | * table 23 | * form 24 | * button 25 | * box 26 | * page 27 | * tips 28 | * dropdown 29 | * tab 30 | * step 31 | * loading 32 | * crumb 33 | 34 | ## css组件编写规范 35 | 36 | * 文件目录,依据原来js组件目录规范,以test组件示例如下 37 | 38 | | | ├── test //test组件 39 | | | | └── 1.0.0 40 | | | | ├── example 组件示例文件夹 41 | | | | | ├──test.html 组件示例 42 | | | | | └──test_other.html 43 | | | | | 44 | | | | ├── i 组件图片文件夹 45 | | | | ├── images 组件素材文件夹 46 | | | | ├── test.md 组件文档 47 | | | | └── test.css 样式文件 48 | 49 | * 命名:以“-”为基准,比如 `.ui-list` 是文本列表 50 | 51 | ## css组件代码示例 52 | 53 | 以ui-list即文本列表来示例 54 | 55 | html 56 | 57 | 63 | 64 | css 65 | 66 | .ui-list{list-style:disc inside;} 67 | 68 | example 69 | 70 | 71 | 72 | 73 | 74 | ui-xxx 75 | 76 | 77 | 78 | 79 | 80 |

      xxx

      81 | 82 | 83 | 84 | 85 | 注意:example中的title是所有example索引菜单上的文字,如果有多个example,使用"_"分开,比如 86 | 87 | ui_list.html 88 | ui_list_ext.html 89 | 90 | ## css组件扩展命名 91 | 以下A和B那一个更好一些? 92 | 93 | A)基于当前样式名扩展 94 | 95 |

      图文列表

      96 |
        97 | 98 |

        图文列表-竖排

        99 |
          100 | 101 |

          图文列表-图片距左

          102 |
            103 | 104 | B)加特有属性样式名,全局统一调用 105 | 106 |

            图文列表

            107 |
              108 |
                109 |
                  110 | 111 | C)用实际业务来定义 112 | 113 |

                  图文列表-竖排

                  114 |
                    115 | 116 |

                    图文列表-图片距左

                    117 |
                      118 | 119 | 最终我们选择C),命名有语义 120 | 121 | -------------------------------------------------------------------------------- /example/3.8node_universal/server.prod.js: -------------------------------------------------------------------------------- 1 | //依赖库 2 | import express from 'express' 3 | import serialize from 'serialize-javascript' 4 | import React from 'react' 5 | 6 | //将React元素渲染为其初始HTML。React将返回一个HTML字符串。可以使用此方法在服务器上生成HTML 7 | import { renderToString } from 'react-dom/server' 8 | 9 | import { Provider } from 'react-redux' 10 | import { createMemoryHistory, match, RouterContext } from 'react-router' 11 | import { syncHistoryWithStore, routerReducer } from 'react-router-redux' 12 | 13 | //引入store和routes 14 | import { configureStore } from './src/store' 15 | import routes from './src/routes' 16 | 17 | const app = express() 18 | app.use('/public', express.static(__dirname + '/public')) 19 | 20 | //拼接页面模板 也可以设置在源码文件中 21 | const HTML = ({ content, store }) => ( 22 | 23 | 24 | 25 | 26 | 27 | 28 |
                      29 | 75 | 76 |
                      77 |
                      78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /example/4.iOSWebView/iOSWebView/globalWebViewBase/Source/HPKScrollProcessor.h: -------------------------------------------------------------------------------- 1 | // 2 | // HPKScrollProcessor.h 3 | // 4 | // Copyright (c) 2019 dequanzhu 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | // 24 | 25 | 26 | #import "HPKPageManager.h" 27 | #import "HPKViewProtocol.h" 28 | #import "HPKModelProtocol.h" 29 | #import "HPKControllerProtocol.h" 30 | 31 | typedef NSObject* (^HPKScrollProcessorDelegateBlock)(HPKModel *model , BOOL isGetViewEvent); 32 | 33 | typedef NS_ENUM (NSInteger, HPKLayoutType) { 34 | kHPKLayoutTypeAutoCalculateFrame, //根据ComponentIndex及相应的protocol自动计算 35 | kHPKLayoutTypeManualCalculateFrame, //根据ComponentModel中的Frame布局 36 | }; 37 | /** 38 | * 底层页components滚动管理 39 | */ 40 | @interface HPKScrollProcessor : NSObject 41 | 42 | #pragma mark - 43 | 44 | - (instancetype)initWithScrollView:(__kindof UIScrollView *)scrollView 45 | layoutType:(HPKLayoutType)layoutType 46 | scrollDelegateBlock:(HPKScrollProcessorDelegateBlock)scrollDelegateBlock; 47 | 48 | #pragma mark - layout 49 | 50 | - (void)relayoutWithComponentFrameChange; 51 | - (void)addComponentModelAndRelayout:(HPKModel *)componentModel; 52 | - (void)removeComponentModelAndRelayout:(HPKModel *)componentModel; 53 | - (void)layoutWithComponentModels:(NSArray *)componentModels; 54 | 55 | #pragma mark - scroll 56 | 57 | - (void)scrollToContentOffset:(CGPoint)toContentOffset animated:(BOOL)animated; 58 | - (void)scrollToComponentView:(HPKView *)componentView atOffset:(CGFloat)offsetY animated:(BOOL)animated; 59 | - (void)scrollToComponentModel:(HPKModel *)componentModel atOffset:(CGFloat)offsetY animated:(BOOL)animated; 60 | 61 | #pragma mark - get View or Model 62 | 63 | - (NSArray *)getAllComponentModels; 64 | - (NSArray *)getVisibleComponentModels; 65 | - (NSArray *)getVisibleComponentViews; 66 | 67 | //get model 68 | - (HPKModel *)getComponentModelByComponentView:(HPKView *)componentView; 69 | - (HPKModel *)getComponentModelByIndex:(NSString *)componentIndex; 70 | 71 | //get view 72 | - (HPKView *)getComponentViewByComponentModel:(HPKModel *)componentModel; 73 | - (HPKView *)getComponentViewByIndex:(NSString *)componentIndex; 74 | 75 | @end 76 | -------------------------------------------------------------------------------- /example/2.14jdf/source/doc/a_tool_csssprite.md: -------------------------------------------------------------------------------- 1 | # csssprite图片合并 2 | 3 | ## 使用说明 4 | ### 默认单位为px 5 | * 非常简单,只需要在css文件中对要合并的图片路径增加?__sprite后缀即可,比如 6 | 7 | .csssprite .abtest_huafei s { 8 | background:url(i/icon_01.png?__sprite) no-repeat; 9 | } 10 | .csssprite .abtest_lvxing s { 11 | background:url(i/icon_03.png?__sprite) no-repeat 6px 0px; 12 | } 13 | .csssprite .abtest_caipiao s { 14 | background:url(i/icon_05.png?__sprite) no-repeat 5px 0px; 15 | } 16 | 17 | * 执行jdf output,后台会进行css sprite编译操作后 18 | 19 | .csssprite .abtest_huafei s { 20 | background:url(i/sprite_csssprite.png?__sprite) no-repeat; 21 | background-position:0 0 22 | } 23 | .csssprite .abtest_lvxing s { 24 | background:url(i/sprite_csssprite.png?__sprite) no-repeat 6px 0; 25 | background-position:6px -39px 26 | } 27 | .csssprite .abtest_caipiao s { 28 | background:url(i/sprite_csssprite.png?__sprite) no-repeat 5px 0; 29 | background-position:5px -78px 30 | } 31 | 32 | * 其中icon_01.png,icon_03.png,icon_05.png小图片被合成为sprite_csssprite.png,其中csssprite为当前css文件的文件名,sprite_为前缀 33 | 34 | ### 当css单位为rem时 35 | * 在background中写上px到rem的转换比例 36 | ```css 37 | html{ 38 | font-size: 20px; 39 | } 40 | .icon1, .icon2{ 41 | width: 1.8rem; 42 | height: 1.8rem; 43 | margin: 10px; 44 | background: url(i/icon7.png?__sprite__rem20) no-repeat; 45 | border: 1px solid black; 46 | } 47 | .icon2{ 48 | background: url(i/icon8.png?__sprite__rem20) no-repeat; 49 | } 50 | ``` 51 | 转换之后: 52 | ```css 53 | html { 54 | font-size: 20px 55 | } 56 | .icon1, .icon2 { 57 | width: 1.8rem; 58 | height: 1.8rem; 59 | margin: 10px; 60 | background: url(http://misc.360buyimg.com/jdf/Test/widget/w2/i/w2.png?__sprite__rem20) no-repeat; 61 | background-position: 0 0; 62 | background-size: 1.8rem 4.6rem; 63 | border: 1px solid #000 64 | } 65 | .icon2 { 66 | background: url(http://misc.360buyimg.com/jdf/Test/widget/w2/i/w2.png?__sprite__rem20) no-repeat; 67 | background-position: 0 -2.3rem; 68 | background-size: 1.8rem 4.6rem 69 | } 70 | ``` 71 | 72 | ## 切图说明 73 | * 把psd中图片所有icon类小图切换,在css中设置好background-position,在相对应图片后面增加?__sprite后缀 74 | 75 | ## 配置说明 76 | * 默认为开启状态,可以通过config.json的{{output.csssprite}}键值设置为false进行关闭 77 | * 图片之间上下间距可以通过config.json的{{output.cssspriteMargin}}键值设置 78 | 79 | ## 特性说明 80 | * 支持的图片格式:png,jpg,png输出png24格式,IE6的png24图片需要单独处理 81 | * 支持no-repeat,background-position可自由设置 82 | * 后续支持repeat-x,repeat-y 83 | 84 | ## 原理解析 85 | * 分析css文件内容,取出带有?__sprite的图片路径,同时对此background的backgroud-repeat、background-position进行记录 86 | * 取出所有图片,依靠backgroud-repeat、background-position进行图片合并,并生成合并的新图片 87 | * 把css文件所有sprite图片路径替换成合并的新图片路径 88 | 89 | ## 解析css 90 | * 利用正则实现一个简单的css语法解析器,可把css内容解析为 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 |
                      属性 说明
                      content 图片内容
                      url 如:i/icon.png 图片url
                      item 如:background: url(i/icon.png?__sprite) no-repeat 图片background
                      repeat null | repeat-x | repeat-y 重复
                      width number 图片的宽度
                      height number 图片的高度
                      101 | 102 | ## 系统支持 103 | win,mac,linux 104 | -------------------------------------------------------------------------------- /example/3.8node_universal/public/style.css: -------------------------------------------------------------------------------- 1 | /*! normalize.css v4.1.1 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block}audio:not([controls]){display:none;height:0}progress{vertical-align:baseline}[hidden],template{display:none}a{background-color:transparent;-webkit-text-decoration-skip:objects}a:active,a:hover{outline-width:0}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:inherit;font-weight:bolder}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}h1,h2,h3,h4,h5,h6{line-height:1.15}mark{background-color:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}svg:not(:root){overflow:hidden}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}figure{margin:1em 40px}hr{box-sizing:content-box;height:0;overflow:visible}button,input,optgroup,select,textarea{font:inherit;margin:0}optgroup{font-weight:700}button,input{overflow:visible}button,select{text-transform:none}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-input-placeholder{color:inherit;opacity:.54}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}html{color:#333;font-family:Helvetica,Arial,sans-serif;background-color:#fff}h1,h2,h3,h4,h5,li,p,span{color:#333;font-weight:400}pre{padding:10px}code,pre{background-color:#fafafa;color:#333}a{font-size:24px}a,a:hover{color:#61dafb;text-decoration:none}main{padding:0 1em}ul{list-style:none}a,li,p{font-size:16px;line-height:1.5;letter-spacing:0}a,h3,li,p{font-weight:400}h3{font-size:24px}h2{font-size:28px}h1,h2{font-weight:400}h1{font-size:32px}@media (min-width:550px){a,li,p{font-size:20px}h3{font-size:28px}h2{font-size:32px}h1{font-size:36px}}@media (min-width:750px){a,li,p{font-size:22px}h3{font-size:30px}h2{font-size:36px}h1{font-size:40px}}@media (min-width:1000px){a,li,p{font-size:26px}h3{font-size:36px}h2{font-size:40px}h1{font-size:44px}}@media (min-width:1200px){a,li,p{font-size:28px}h3{font-size:40px}h2{font-size:44px}h1{font-size:48px}}.Header_header__1qRCL{width:100%;background-color:#f0f8ff;text-align:center;padding:1em 0}.Header_header__1qRCL a{color:#61dafb}.Header_header__1qRCL .Header_todo__2w5Zt{color:#999}.Footer_footer__2dyxG{width:100%;padding:.5em 0;background-color:#eee;text-align:center}.Footer_footer__2dyxG span{color:#000} -------------------------------------------------------------------------------- /example/2.14jdf/source/test/jdf_output.js: -------------------------------------------------------------------------------- 1 | var f = require('../lib/file.js'); 2 | var $ = require('../lib/base.js'); 3 | var child = require("child_process"); 4 | var path = require('path'); 5 | var expect = require('expect.js'); 6 | 7 | describe('##jdf output...', function(){ 8 | this.timeout(10000); 9 | 10 | var css_background_url = f.read('result/css_background_url/css_background_url.css').split('\r\n'); 11 | var css_background_url_build = ''; 12 | 13 | var css_background_sprite_base64 = f.read('result/css_background_sprite_base64/css_background_sprite_base64.css').split('\r\n'); 14 | var css_background_sprite_base64_build = ''; 15 | 16 | var css_hack = f.read('result/css_hack/css_hack.css').split('\r\n'); 17 | var css_hack_build = ''; 18 | 19 | var js_cmd_define = f.read('result/js_cmd_define/js_cmd_define.js'); 20 | var js_cmd_define_build = ''; 21 | 22 | var js_seajs_use = f.read('result/js_seajs_use/js_seajs_use.js'); 23 | var js_seajs_use_build = ''; 24 | 25 | var sass_import_lib = f.read('result/sass_import_lib/sass_import_lib.css'); 26 | var sass_import_lib_build = ''; 27 | 28 | before(function(done){ 29 | child.exec('jdf o', function(error, stdout, stderr){ 30 | if(!error){ 31 | css_background_url_build = f.read('build/jdf-test/widget/css_background_url/css_background_url.css'); 32 | css_background_sprite_base64_build = f.read('build/jdf-test/widget/css_background_sprite_base64/css_background_sprite_base64.css'); 33 | css_hack_build = f.read('build/jdf-test/widget/css_hack/css_hack.css'); 34 | 35 | js_cmd_define_build = f.read('build/jdf-test/widget/js_cmd_define/js_cmd_define.js'); 36 | js_seajs_use_build = f.read('build/jdf-test/widget/js_seajs_use/js_seajs_use.js'); 37 | 38 | sass_import_lib_build = f.read('build/jdf-test/widget/sass_import_lib/sass_import_lib.css'); 39 | 40 | done(); 41 | } 42 | }); 43 | }); 44 | 45 | describe('#css_background_url', function(){ 46 | css_background_url.forEach(function(item, index){ 47 | it('test' + (index + 1) + ' should equal', function(){ 48 | var css_result = css_background_url[index]; 49 | 50 | if(css_result){ 51 | expect(css_background_url_build).to.contain(css_result); 52 | } 53 | }); 54 | }); 55 | }); 56 | 57 | describe('#css_background_sprite_base64', function(){ 58 | css_background_sprite_base64.forEach(function(item, index){ 59 | it('test' + (index + 1) + ' should equal', function(){ 60 | var css_result = css_background_sprite_base64[index]; 61 | 62 | if(css_result){ 63 | setTimeout(function(){ 64 | expect(css_background_sprite_base64_build).to.contain(css_result); 65 | }, 200) 66 | } 67 | }); 68 | }); 69 | }); 70 | 71 | describe('#css_hack', function(){ 72 | css_hack.forEach(function(item, index){ 73 | it('test' + (index + 1) + ' should equal', function(){ 74 | var css_result = css_hack[index]; 75 | 76 | if(css_result){ 77 | expect(css_hack_build).to.contain(css_result); 78 | } 79 | }); 80 | }); 81 | }); 82 | 83 | describe('#js_cmd_define', function(){ 84 | it('add cdn and project path for dependence', function(){ 85 | expect(js_cmd_define_build).to.contain(js_cmd_define); 86 | }) 87 | }); 88 | 89 | describe('#js_seajs_use', function(){ 90 | it('add cdn and project path for seajs use', function(){ 91 | expect(js_seajs_use_build).to.contain(js_seajs_use); 92 | }) 93 | }); 94 | 95 | describe('#sass_import_lib', function(){ 96 | it('import lib in sass file', function(){ 97 | expect(sass_import_lib_build).to.contain(sass_import_lib); 98 | }) 99 | }); 100 | }); 101 | 102 | 103 | 104 | 105 | -------------------------------------------------------------------------------- /example/4.iOSWebView/iOSWebView.xcodeproj/xcshareddata/xcschemes/wkWebView.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /example/4.iOSWebView/iOSWebView/JSSDKIframeViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // JSSDKIframeViewController.m 3 | // iOSWebView 4 | // 5 | // Copyright © 2019 putaoshu. Licensed under the MIT license. 6 | // 7 | 8 | #import "JSSDKIframeViewController.h" 9 | #import "JSSDKViewControllerBase/WebViewJavascriptBridge.h" 10 | 11 | @interface JSSDKIframeViewController () 12 | 13 | @property WebViewJavascriptBridge* bridge; 14 | 15 | @end 16 | 17 | @implementation JSSDKIframeViewController 18 | 19 | - (void)viewDidLoad { 20 | [super viewDidLoad]; 21 | 22 | if (_bridge) { return; } 23 | 24 | WKWebView* webView = [[NSClassFromString(@"WKWebView") alloc] initWithFrame:self.view.bounds]; 25 | //webView.navigationDelegate = self; 26 | [self.view addSubview:webView]; 27 | [WebViewJavascriptBridge enableLogging]; 28 | _bridge = [WebViewJavascriptBridge bridgeForWebView:webView]; 29 | [_bridge setWebViewDelegate:self]; 30 | 31 | [_bridge registerHandler:@"testObjcCallback" handler:^(id data, WVJBResponseCallback responseCallback) { 32 | NSLog(@"testObjcCallback called: %@", data); 33 | responseCallback(@"Response from testObjcCallback"); 34 | }]; 35 | 36 | [_bridge callHandler:@"testJavascriptHandler" data:@{ @"foo":@"before ready" }]; 37 | 38 | [self renderButtons:webView]; 39 | [self loadExamplePage:webView]; 40 | //[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://localhost:3000/JSSDK.html"]]]; 41 | 42 | //self.navigationController.delegate = self; 43 | } 44 | 45 | #pragma mark - 加载状态的回调 46 | // 页面开始加载时调用 47 | - (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation { 48 | NSLog(@"页面开始加载"); 49 | } 50 | // 当内容开始返回时调用 51 | - (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation { 52 | NSLog(@"数据开始返回"); 53 | } 54 | 55 | // 页面加载完成之后调用 56 | - (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation { 57 | NSLog(@"页面已经加载完成"); 58 | } 59 | // 页面加载失败时调用 60 | - (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation { 61 | NSLog(@"页面加载失败"); 62 | } 63 | 64 | - (void)renderButtons:(WKWebView*)webView { 65 | UIFont* font = [UIFont fontWithName:@"HelveticaNeue" size:12.0]; 66 | 67 | UIButton *callbackButton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 68 | [callbackButton setTitle:@"Native Call handler" forState:UIControlStateNormal]; 69 | [callbackButton addTarget:self action:@selector(callHandler:) forControlEvents:UIControlEventTouchUpInside]; 70 | [self.view insertSubview:callbackButton aboveSubview:webView]; 71 | callbackButton.frame = CGRectMake(5, 64, 150, 40); 72 | callbackButton.titleLabel.font = font; 73 | 74 | UIButton* reloadButton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 75 | [reloadButton setTitle:@"Reload webview" forState:UIControlStateNormal]; 76 | [reloadButton addTarget:webView action:@selector(reload) forControlEvents:UIControlEventTouchUpInside]; 77 | [self.view insertSubview:reloadButton aboveSubview:webView]; 78 | reloadButton.frame = CGRectMake(150, 64, 100, 40); 79 | reloadButton.titleLabel.font = font; 80 | } 81 | 82 | - (void)callHandler:(id)sender { 83 | id data = @{ @"greetingFromObjC": @"Hi there, JS!" }; 84 | [_bridge callHandler:@"testJavascriptHandler" data:data responseCallback:^(id response) { 85 | NSLog(@"testJavascriptHandler responded: %@", response); 86 | }]; 87 | } 88 | 89 | - (void)loadExamplePage:(WKWebView*)webView { 90 | NSString* htmlPath = [[NSBundle mainBundle] pathForResource:@"JSSDKIframe" ofType:@"html"]; 91 | NSString* appHtml = [NSString stringWithContentsOfFile:htmlPath encoding:NSUTF8StringEncoding error:nil]; 92 | NSURL *baseURL = [NSURL fileURLWithPath:htmlPath]; 93 | [webView loadHTMLString:appHtml baseURL:baseURL]; 94 | } 95 | @end 96 | 97 | -------------------------------------------------------------------------------- /example/4.iOSWebView/iOSWebView/globalWebViewBase/Source/HPKPageManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // HPKPageManager.m 3 | // 4 | // Copyright (c) 2019 dequanzhu 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | // 24 | 25 | 26 | #import "HPKPageManager.h" 27 | #import "HPKWebViewPool.h" 28 | #import "WKWebView + HPKExtension.h" 29 | 30 | @implementation HPKPageManager 31 | 32 | + (HPKPageManager *)sharedInstance { 33 | static dispatch_once_t once; 34 | static HPKPageManager *singleton; 35 | dispatch_once(&once, 36 | ^{ 37 | singleton = [[HPKPageManager alloc] init]; 38 | }); 39 | return singleton; 40 | } 41 | 42 | - (instancetype)init { 43 | self = [super init]; 44 | if (self) { 45 | self.showWebViewWithAnimation = YES; 46 | self.componentsPrepareWorkRange = [UIScreen mainScreen].bounds.size.height / 2; 47 | self.componentsMaxReuseCount = 10; 48 | self.webViewShowMaxRetryTimes = 50; 49 | self.webViewMaxReuseTimes = NSIntegerMax; 50 | self.webViewReuseLoadUrlStr = @""; 51 | } 52 | return self; 53 | } 54 | 55 | #pragma mark - HPKReusableWebView 56 | 57 | - (__kindof HPKWebView *)dequeueWebViewWithClass:(Class)webViewClass webViewHolder:(NSObject *)webViewHolder { 58 | return [[HPKWebViewPool sharedInstance] dequeueWebViewWithClass:webViewClass webViewHolder:webViewHolder]; 59 | } 60 | 61 | - (void)enqueueWebView:(__kindof HPKWebView *)webView { 62 | [[HPKWebViewPool sharedInstance] enqueueWebView:webView]; 63 | } 64 | 65 | - (void)removeReusableWebView:(__kindof HPKWebView *)webView { 66 | [[HPKWebViewPool sharedInstance] removeReusableWebView:webView]; 67 | } 68 | 69 | - (void)clearAllReusableWebViews { 70 | [[HPKWebViewPool sharedInstance] clearAllReusableWebViews]; 71 | } 72 | 73 | - (void)clearAllReusableWebViewsWithClass:(Class)webViewClass { 74 | [[HPKWebViewPool sharedInstance] clearAllReusableWebViewsWithClass:webViewClass]; 75 | } 76 | 77 | - (void)reloadAllReusableWebViews { 78 | [[HPKWebViewPool sharedInstance] reloadAllReusableWebViews]; 79 | } 80 | 81 | #pragma mark - HPKWebView 82 | 83 | + (void)configCustomUAWithType:(HPKWebViewUAConfigType)type 84 | UAString:(NSString *)customString { 85 | [WKWebView configCustomUAWithType:((type == kHPKWebViewUAConfigTypeReplace) ? kConfigUATypeReplace : kConfigUATypeAppend) 86 | UAString:customString]; 87 | } 88 | 89 | + (void)safeClearAllCacheIncludeiOS8:(BOOL)includeiOS8 { 90 | [WKWebView safeClearAllCacheIncludeiOS8:includeiOS8]; 91 | } 92 | 93 | + (void)fixWKWebViewMenuItems { 94 | [WKWebView fixWKWebViewMenuItems]; 95 | } 96 | 97 | + (void)disableWebViewDoubleClick{ 98 | [WKWebView disableWebViewDoubleClick]; 99 | } 100 | 101 | @end 102 | -------------------------------------------------------------------------------- /example/2.14jdf/source/doc/core_js.md: -------------------------------------------------------------------------------- 1 | # js组件 2 | 3 | ## 组件类型 4 | * ui和unit组件 5 | * widget中js组件 6 | * 非标准化组件 7 | 8 | ## 组件写法 9 | * 源码 10 | 11 | define(function(require, exports, module){ 12 | var a = require('widget/a/a.js'); 13 | var b = require('widget/b/b.js'); 14 | 15 | function init(){ 16 | //todo 17 | } 18 | exports.init = init; 19 | //or return init; 20 | }) 21 | 22 | * 工具编译后 23 | 24 | define(['js/test.js'], ['/widget/a/a.js', 'widget/b/b.js' ], function(require, exports, module){ 25 | require("widget/a/a.js"),require("widget/b/b.js"); 26 | function init(){} 27 | exports.init = init; 28 | }) 29 | 30 | * 其中 'js/test.js' 为当前文件的id, ['widget/a/a.js', 'widget/b/b.js', ] 为当前js依赖的文件数组 31 | 32 | ## 引用方法 33 | 34 | * ui和unit组件引用方法 35 | 36 | seajs.use(['jdf/1.0.0/unit/event/1.0.0/event.js'],function(event){ 37 | //todo 38 | }) 39 | 40 | * 项目内js引用方法 41 | * 源码 42 | 43 | seajs.use(['/js/a.js','/js/b.js'],function(a,b){ 44 | //todo 45 | }) 46 | 47 | * 工具编译后 (projectPaht为项目路径名) 48 | 49 | seajs.use(['projectPaht/js/a.js','projectPaht/js/b.js'],function(a,b){ 50 | //todo 51 | }) 52 | 53 | * 组件内require引用 54 | 55 | define(function(require, exports){ 56 | var login = require('login.js'); 57 | 58 | function init(){ 59 | //todo 60 | } 61 | exports.init = init; 62 | }) 63 | 64 | * 加载器会保证require加载完成后才执行init 65 | 66 | 67 | ## 公共base引用 68 | 69 | 70 | 71 | 72 | 73 | 74 | ## 页面头尾初始化 75 | * 标准头尾 76 | 77 | seajs.use('jdf/1.0.0/unit/globalInit/1.0.0/globalInit',function(globalInit){ 78 | globalInit(); 79 | }); 80 | 81 | * 非标准头尾 82 | 83 | * 需要单独配置 84 | 85 | ## 本地调试 86 | * 在页面后面增加?isdebug那么页面中所有js文件就不会combo合并,即 87 | 88 | http://localhost:3000/html/index.html?isdebug 89 | 90 | * 使用jdf工具,则可以不压缩静态文件直接上传至测试服务器,中间仅增加了路径引用 91 | 92 | jdf upload -debug 93 | 94 | 95 | ## 最佳实践 96 | 项目核心js顶部首先配置alias,如下 97 | 98 | seajs.config({ 99 | alias:{ 100 | 'globalInit':'jdf/1.0.0/unit/globalInit/1.0.0/globalInit', 101 | 'event':'jdf/1.0.0/unit/event/1.0.0/event.js' 102 | } 103 | }) 104 | 105 | 项目页面引用时直接用alias来代替 106 | 107 | seajs.use('jdf/1.0.0/unit/globalInit/1.0.0/globalInit',function(globalInit){ 108 | globalInit(); 109 | }); 110 | seajs.use('event',function(event){}) 111 | 112 | 这样做的目的: 113 | 114 | * 方便对所用到了的组件统一管理 115 | * 后续升级只要修改一处即可 116 | 117 | # js依赖管理方案 118 | 119 | seajs的config中base所有项目统一设置假设为 http://cdn.com/ 120 | 121 | 示例 (假设工程名为jdf_dependent) 122 | 123 | * widget js文件使用require 124 | 125 | 本地 require('/widget/test/test.js') ==> 工具编译后 require('jdf_dependent/widget/test/test.js') 126 | 实现请求url为 http://cdn.com/jdf_dependent/widget/test/test.js 127 | 128 | * widget js文件使用use 129 | 130 | 本地 seajs.use('/widget/test/test.js') ==> 工具编译后 seajs.use('jdf_dependent/widget/test/test.js') 131 | 实现请求url为 http://cdn.com/jdf_dependent/widget/test/test.js 132 | 133 | * widget js中使用ui, unit组件调用方式如下 (注意不要加/, 因为这个是基于base, 所以编译不做处理) 134 | 135 | seajs.use('product/index/js/base/ui/accordion/accordion') ==> 工具编译后 seajs.use('product/index/js/base/ui/accordion/accordion') 136 | require('product/index/js/base/ui/accordion/accordion') ==> 工具编译后 require('product/index/js/base/ui/accordion/accordion') 137 | 实现请求url为 http://cdn.com/product/index/js/base/ui/accordion/accordion.js 138 | 139 | * js中使用调用方式如下 (注意不要加/, 因为这个是基于base) 140 | 141 | seajs.use('/js/test.js') ==> 工具编译后 seajs.use('jdf_dependent/js/test.js') 142 | require('/js/test.js') ==> 工具编译后 require('jdf_dependent/js/test.js') 143 | 实现请求url为 http://cdn.com/jdf_dependent/js/test.js 144 | 145 | -------------------------------------------------------------------------------- /example/2.14jdf/source/lib/buildCss.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @build less/sass to css 3 | * @ctime 2014-3-5 4 | * 5 | * @less 文档 http://lesscss.org/#using-less-configuration syncImport 6 | * @npm https://npmjs.org/package/less 7 | * @Dist folder file size is big ==> https://github.com/less/less.js/issues/1918 8 | * 9 | * @sass 文档 https://www.npmjs.org/package/node-sass 10 | * @github https://github.com/andrew/node-sass 11 | * @npm https://npmjs.org/package/node-sass 12 | * @Compatibility @mixin has "};" ==> https://github.com/andrew/node-sass/issues/254 13 | * 14 | */ 15 | 16 | var path = require('path'); 17 | var fs = require('fs'); 18 | 19 | //lib自身组件 20 | var $ = require('./base.js'); 21 | var f = require('./file.js'); 22 | var jdf = require('./jdf.js'); 23 | var fileLint = require('./fileLint.js'); 24 | 25 | //外部组件 26 | var Sass = require('node-sass'); 27 | var Less = require('less'); 28 | var Colors = require('colors'); 29 | 30 | //exports 31 | var buildCss = module.exports = {}; 32 | 33 | /** 34 | * @init 35 | */ 36 | buildCss.init = function(rSource, target){ 37 | var allTag = true; 38 | var source = f.realpath(rSource); 39 | 40 | if(source){ 41 | if(f.isDir(source)){ 42 | fs.readdirSync(source).forEach(function(name){ 43 | if(name != '.' && name != '..' && !(/.svn/.test(name))){ 44 | allTag = buildCss.init(source + '/' + name, target + '/' + name) && allTag; 45 | } 46 | }); 47 | } else if(f.isFile(source) && ($.is.css(source) || $.is.less(source) || $.is.sass(source) ) ){ 48 | if(jdf.config.build.hasCmdLog) console.log('buildCss---'+rSource); 49 | 50 | var autoprefixerFn = function(file){ 51 | if(jdf.config.build.autoprefixer){ 52 | require('./buildByAutoprefixer.js').init({contents:file.contents, path:file.path }, jdf.config.build.autoprefixerOptions) 53 | }else{ 54 | f.write(file.path, file.contents); 55 | } 56 | } 57 | 58 | target = $.getCssExtname(target); 59 | 60 | if( $.is.less(source) || $.is.sass(source) ) { 61 | var sourceContent = f.read(source); 62 | //为空 "node-sass": "0.9.3" 编译会报错 https://github.com/sass/node-sass/issues/381 63 | if(sourceContent==''){ 64 | return; 65 | } 66 | 67 | if($.is.less(source) && jdf.config.build.less){ 68 | try{ 69 | Less.render(sourceContent, {filename: source, syncImport:true}, function(error, output){ 70 | if(error){ 71 | console.log(error); 72 | }else{ 73 | var targetContent = output.css; 74 | if(jdf.config.build.csslint) fileLint.init(source); 75 | autoprefixerFn({contents:targetContent, path:target }); 76 | //f.write(target, targetContent); 77 | } 78 | }); 79 | }catch(e){ 80 | console.log('jdf error [jdf.buildCss] - less'); 81 | console.log(Colors.red('> '+source)); 82 | console.log(Colors.red('>'), e); 83 | } 84 | } 85 | 86 | if($.is.sass(source) && jdf.config.build.sass){ 87 | try{ 88 | var css = Sass.renderSync({ 89 | data: sourceContent, 90 | includePaths: [path.dirname(source)], 91 | // outputStyle: 'compressed' 92 | outputStyle: 'expanded' 93 | }); 94 | if(jdf.config.build.csslint) fileLint.init(source); 95 | autoprefixerFn({contents:css.css.toString(), path:target }); 96 | // f.write(target, css.css); 97 | }catch(e){ 98 | console.log('jdf error [jdf.buildCss] - sass'); 99 | console.log(Colors.red('> '+source)); 100 | console.log(Colors.red('> line: ' + e.line + ', column: ' + e.column)); 101 | console.log(Colors.red('>'), 'message: ' + e.message); 102 | } 103 | } 104 | } 105 | 106 | if($.is.css(source) && jdf.config.build.autoprefixer){ 107 | var sourceContent = f.read(source); 108 | autoprefixerFn({contents:sourceContent, path:target }) 109 | } 110 | } else { 111 | allTag = false; 112 | } 113 | } else { 114 | //console.log('error'); 115 | } 116 | return allTag; 117 | } -------------------------------------------------------------------------------- /example/4.iOSWebView/iOSWebView/globalWebViewBase/Source/_HPKAspects.h: -------------------------------------------------------------------------------- 1 | // 2 | // Aspects.h 3 | // Aspects - A delightful, simple library for aspect oriented programming. 4 | // 5 | // Copyright (c) 2014 Peter Steinberger. Licensed under the MIT license. 6 | // 7 | 8 | #import 9 | 10 | typedef NS_OPTIONS(NSUInteger, HPK_AspectOptions) { 11 | AspectPositionAfter = 0, /// Called after the original implementation (default) 12 | AspectPositionInstead = 1, /// Will replace the original implementation. 13 | AspectPositionBefore = 2, /// Called before the original implementation. 14 | 15 | AspectOptionAutomaticRemoval = 1 << 3 /// Will remove the hook after the first execution. 16 | }; 17 | 18 | /// Opaque Aspect Token that allows to deregister the hook. 19 | @protocol HPK_AspectToken 20 | 21 | /// Deregisters an aspect. 22 | /// @return YES if deregistration is successful, otherwise NO. 23 | - (BOOL)remove; 24 | 25 | @end 26 | 27 | /// The AspectInfo protocol is the first parameter of our block syntax. 28 | @protocol HPK_AspectInfo 29 | 30 | /// The instance that is currently hooked. 31 | - (id)instance; 32 | 33 | /// The original invocation of the hooked method. 34 | - (NSInvocation *)originalInvocation; 35 | 36 | /// All method arguments, boxed. This is lazily evaluated. 37 | - (NSArray *)arguments; 38 | 39 | @end 40 | 41 | /** 42 | Aspects uses Objective-C message forwarding to hook into messages. This will create some overhead. Don't add aspects to methods that are called a lot. Aspects is meant for view/controller code that is not called a 1000 times per second. 43 | 44 | Adding aspects returns an opaque token which can be used to deregister again. All calls are thread safe. 45 | */ 46 | @interface NSObject (HPK_Aspects) 47 | 48 | /// Adds a block of code before/instead/after the current `selector` for a specific class. 49 | /// 50 | /// @param block Aspects replicates the type signature of the method being hooked. 51 | /// The first parameter will be `id`, followed by all parameters of the method. 52 | /// These parameters are optional and will be filled to match the block signature. 53 | /// You can even use an empty block, or one that simple gets `id`. 54 | /// 55 | /// @note Hooking static methods is not supported. 56 | /// @return A token which allows to later deregister the aspect. 57 | + (id)HPK_aspect_hookSelector:(SEL)selector 58 | withOptions:(HPK_AspectOptions)options 59 | usingBlock:(id)block 60 | error:(NSError **)error; 61 | 62 | /// Adds a block of code before/instead/after the current `selector` for a specific instance. 63 | - (id)HPK_aspect_hookSelector:(SEL)selector 64 | withOptions:(HPK_AspectOptions)options 65 | usingBlock:(id)block 66 | error:(NSError **)error; 67 | 68 | @end 69 | 70 | 71 | typedef NS_ENUM(NSUInteger, HPK_AspectErrorCode) { 72 | AspectErrorSelectorBlacklisted, /// Selectors like release, retain, autorelease are blacklisted. 73 | AspectErrorDoesNotRespondToSelector, /// Selector could not be found. 74 | AspectErrorSelectorDeallocPosition, /// When hooking dealloc, only AspectPositionBefore is allowed. 75 | AspectErrorSelectorAlreadyHookedInClassHierarchy, /// Statically hooking the same method in subclasses is not allowed. 76 | AspectErrorFailedToAllocateClassPair, /// The runtime failed creating a class pair. 77 | AspectErrorMissingBlockSignature, /// The block misses compile time signature info and can't be called. 78 | AspectErrorIncompatibleBlockSignature, /// The block signature does not match the method or is too large. 79 | 80 | AspectErrorRemoveObjectAlreadyDeallocated = 100 /// (for removing) The object hooked is already deallocated. 81 | }; 82 | 83 | extern NSString *const HPK_AspectErrorDomain; 84 | -------------------------------------------------------------------------------- /example/2.14jdf/source/README.md: -------------------------------------------------------------------------------- 1 | # jdf 2 | 3 | [![NPM version](https://badge.fury.io/js/jdf.png)](http://badge.fury.io/js/jdf) [![Build Status](https://api.travis-ci.org/putaoshu/jdf.svg?branch=master)](https://travis-ci.org/putaoshu/jdf) 4 | 5 | [![NPM](https://nodei.co/npm/jdf.png?downloads=true)](https://nodei.co/npm/jdf/) 6 | 7 | ## 关于JDF 8 | 9 | * JDF京东前端开发集成解决方案(Jingdong front-end integrated solution) 10 | * 目的是合理、快速和高效的解决前端开发中的工程和项目问题,主要提供了: 11 | * 前端命令行工具:集调试、构建、布署为一体 12 | * 前端模块:下载、预览、发布 13 | * 前端开发流程:项目构建、编译、输出、联调、上线 14 | * 前端组件:UI组件和业务组件(内网开源) 15 | * 前端文档:编码规范、开发规范、组件和工具文档 16 | * 前端周边扩展:代码文档和示例自动生成工具、代码编辑器插件、可视化工具等 17 | 18 | ## 更新日志 19 | 20 | * [changelog](https://github.com/putaoshu/jdf/blob/master/CHANGELOG.md) 21 | 22 | ## 安装、使用与快速入门 23 | 24 | * jdf依赖nodejs和python 25 | * [nodejs安装](http://nodejs.org/download/) node版本要求v4.2.6及以上和[v6.9.4](https://nodejs.org/dist/v6.9.4/)以下 26 | * [python安装](https://www.python.org/downloads/) python版本无要求 27 | * 安装jdf 28 | * npm install jdf **-g** 29 | * 安装测试 30 | * 执行 jdf -v 如果出现版本号则说明你已安装成功 31 | * 请仔细阅读快速入门文档,就可以开始项目开发了 32 | * [快速入门](https://github.com/putaoshu/jdf/blob/master/doc/a_tool_develop.md) 33 | * 更进一步,请阅读核心文档 34 | * [目录规范](https://github.com/putaoshu/jdf/blob/master/doc/core_dir_standard.md) 35 | * [配置文件文档](https://github.com/putaoshu/jdf/blob/master/doc/a_tool_config.md) 36 | * [命令手册](https://github.com/putaoshu/jdf/blob/master/doc/a_tool_command.md) 37 | 38 | ## 帮助文档 39 | * [widget组件](https://github.com/putaoshu/jdf/blob/master/doc/core_widget.md) 40 | * [js组件](https://github.com/putaoshu/jdf/blob/master/doc/core_js.md) 41 | * [js前端模板](https://github.com/putaoshu/jdf/blob/master/doc/core_tpl.md) 42 | * [css组件](https://github.com/putaoshu/jdf/blob/master/doc/core_css.md) 43 | * [vm模板使用文档](https://github.com/putaoshu/jdf/blob/master/doc/core_vm.md) 44 | * [smarty模版使用文档](https://github.com/putaoshu/jdf/blob/master/doc/core_smarty.md) 45 | * [文件格式化](https://github.com/putaoshu/jdf/blob/master/doc/a_tool_format.md) 46 | * [本地server](https://github.com/putaoshu/jdf/blob/master/doc/a_tool_server.md) 47 | * [文件lint代码质量检查](https://github.com/putaoshu/jdf/blob/master/doc/a_tool_lint.md) 48 | * [liveReload自动刷新浏览器](https://github.com/putaoshu/jdf/blob/master/doc/a_tool_livereload.md) 49 | * [csssprite图片合并](https://github.com/putaoshu/jdf/blob/master/doc/a_tool_csssprite.md) 50 | 51 | ## 核心功能 52 | 53 | #### 跨平台 54 | * 完美支持windows、mac、linux三大系统 55 | 56 | #### 项目构建 57 | * 生成标准化的项目文件夹 58 | * 支持本地,联调,线上三种开发流程 59 | * 每个项目都拥有一个单独的配置文件,按选项统一编译 60 | 61 | #### 模块开发 62 | * 可快速方便的对模块进行创建,引用,预览,安装和发布 63 | * 通过积累,可形成完全符合自己业务的模块云服务 64 | 65 | #### 模块编译 66 | * 支持模块编译,内置模块编译引挚 67 | * 支持将vm和smarty模版编译为html 68 | * 支持将sass和less编译为css 69 | * 支持ES6 70 | 71 | #### 项目优化 72 | * 自动将页面中的js、css引用转换成combo请求格式 73 | * 自动压缩优化js、css、png文件 74 | 75 | #### 项目输出 76 | * 默认给所有静态资源添加CDN域名前缀或后缀戳 77 | * 支持cmd规范,自动提取文件id和dependencies,压缩时保留require关键字 78 | * 支持png图片压缩插件,将png24压缩为png8 79 | * 自动生成css雪碧图,并更新background-position属性值 80 | * 可将小图片一键生成base64编码 81 | * 支持图片生成webp格式,并更新相关css图片链接 82 | * 文件编码统一化,即无论当前文件格式是gbk,gb2312,utf8,utf8-bom,统一输出utf8 83 | 84 | #### 项目联调 85 | * 一键上传文件到测试服务器,方便开发预览 86 | 87 | #### 本地服务 88 | * 支持开启本地服务器,方便调试 89 | * 支持本地静态文件预览,内置本地开发调试服务器,以及当前目录浏览 90 | * 支持实时监听文件,文件被修改时会自动编译成css,并刷新浏览器 91 | * 实时在控制台输出错误信息,方便定位代码错误 92 | 93 | #### 辅助工具 94 | * 支持html/js/css文件格式化 95 | * 支持html/js/css代码压缩 96 | * 支持html/js/css文件lint,代码质量检查 97 | * 支持chrome浏览器的LiveReload插件 98 | 99 | #### 周边扩展 100 | * [JDF demo下载](https://o8tcolhwh.qnssl.com/jdf_demo.tar) 101 | * [JDF windows可视化工具JDF_UI下载](https://o8tcolhwh.qnssl.com/JDF_UI.exe) 102 | * [JDF Sublime Text2 插件安装](https://sublime.wbond.net/packages/Jdf%20-%20Tool) 103 | * [JDF组件构建平台示例](https://o8tcolhwh.qnssl.com/JDF_build_platform.gif) 104 | * [JDD文档快速生成工具](https://github.com/putaoshu/jdd) 105 | 106 | #### QQ群 107 | * JDF官方支持群 305542952 108 | 109 | #### 捐助支持 110 | * [![捐助支持](http://img12.360buyimg.com/uba/jfs/t7039/155/7364878/28421/e34519ee/5971c075N7e8bdbe3.png)](http://img12.360buyimg.com/uba/jfs/t7039/155/7364878/28421/e34519ee/5971c075N7e8bdbe3.png) 111 | 112 | --------------------------------------------------------------------------------