├── tests ├── omil-tests │ ├── t.hbs │ ├── yox.js │ ├── t2.js │ ├── t3.js │ ├── a.js │ ├── t.html │ └── t.js ├── omil-projects │ ├── src │ │ ├── index.css │ │ ├── assets │ │ │ ├── logo.png │ │ │ ├── store.cn.jpg │ │ │ ├── transfer.png │ │ │ ├── omi-snippets.png │ │ │ ├── oHeader.css │ │ │ └── logo.svg │ │ ├── events │ │ │ └── events.js │ │ ├── index.js │ │ ├── components │ │ │ ├── React │ │ │ │ ├── EnoType.tsx │ │ │ │ ├── Eno.eno │ │ │ │ └── Eno.js │ │ │ ├── oHeader.omi │ │ │ ├── oFileTest.omi │ │ │ ├── oGallery.omi │ │ │ ├── oPanel.omi │ │ │ └── oSearch.omi │ │ ├── oApp.omi │ │ └── stores │ │ │ └── stores.js │ ├── dist │ │ ├── 36ebaea2592e751f845f811468cd4c06.png │ │ ├── index.html │ │ └── demo.html │ ├── .babelrc │ └── webpack.config.js ├── omil-components │ ├── Test.eno │ ├── abc.pug │ ├── Test.js │ ├── Abc.eno │ ├── Abc.js │ ├── Login.eno │ ├── Login.js │ └── Register.eno └── omil-babel │ └── index.js ├── docs └── guide │ ├── public │ ├── js │ │ ├── book.js │ │ ├── book-post.js │ │ └── book-sidebar.js │ ├── favicon.ico │ ├── images │ │ ├── transfer.png │ │ └── omi-snippets.png │ ├── css │ │ ├── spectre_custom.css │ │ └── book.css │ ├── menu │ │ └── index.html │ ├── archives │ │ ├── 2019 │ │ │ ├── index.html │ │ │ └── 07 │ │ │ │ └── index.html │ │ └── index.html │ ├── index.html │ ├── home │ │ └── index.html │ ├── install │ │ └── index.html │ └── plugin │ │ └── index.html │ ├── .gitignore │ ├── package.json │ └── _config.yml ├── .npmignore ├── .gitignore ├── libs ├── .DS_Store ├── scripts │ ├── extension │ │ ├── classProperty.js │ │ ├── convert.js │ │ └── transform.js │ ├── modules │ │ ├── render.js │ │ ├── define.js │ │ ├── import.js │ │ └── export.js │ ├── loader │ │ └── transform.js │ ├── index.js │ └── ast │ │ └── index.js ├── utils │ ├── getModules.js │ ├── annotation.js │ └── comments.js ├── styles │ ├── extension │ │ └── index.js │ ├── loader │ │ └── index.js │ └── index.js ├── templates │ ├── styledcomponents │ │ └── index.js │ └── index.js ├── index.js └── loaders │ └── index.js ├── package.json └── README.EN.md /tests/omil-tests/t.hbs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/guide/public/js/book.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/omil-projects/src/index.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/guide/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | dist 2 | tests 3 | docs 4 | node_modules -------------------------------------------------------------------------------- /tests/omil-tests/yox.js: -------------------------------------------------------------------------------- 1 | Yox.filter(element, {}) 2 | this.$attrs -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | yarn-error.log 4 | docs -------------------------------------------------------------------------------- /libs/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wscats/omil/master/libs/.DS_Store -------------------------------------------------------------------------------- /docs/guide/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wscats/omil/master/docs/guide/public/favicon.ico -------------------------------------------------------------------------------- /docs/guide/public/images/transfer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wscats/omil/master/docs/guide/public/images/transfer.png -------------------------------------------------------------------------------- /tests/omil-projects/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wscats/omil/master/tests/omil-projects/src/assets/logo.png -------------------------------------------------------------------------------- /tests/omil-projects/src/events/events.js: -------------------------------------------------------------------------------- 1 | import { 2 | EventEmitter 3 | } from 'events' 4 | export default new EventEmitter() -------------------------------------------------------------------------------- /docs/guide/public/images/omi-snippets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wscats/omil/master/docs/guide/public/images/omi-snippets.png -------------------------------------------------------------------------------- /tests/omil-projects/src/assets/store.cn.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wscats/omil/master/tests/omil-projects/src/assets/store.cn.jpg -------------------------------------------------------------------------------- /tests/omil-projects/src/assets/transfer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wscats/omil/master/tests/omil-projects/src/assets/transfer.png -------------------------------------------------------------------------------- /tests/omil-projects/src/assets/omi-snippets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wscats/omil/master/tests/omil-projects/src/assets/omi-snippets.png -------------------------------------------------------------------------------- /tests/omil-projects/src/assets/oHeader.css: -------------------------------------------------------------------------------- 1 | header { 2 | color: white; 3 | text-align: center; 4 | line-height: 50px; 5 | width: 100%; 6 | } -------------------------------------------------------------------------------- /tests/omil-projects/dist/36ebaea2592e751f845f811468cd4c06.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wscats/omil/master/tests/omil-projects/dist/36ebaea2592e751f845f811468cd4c06.png -------------------------------------------------------------------------------- /tests/omil-components/Test.eno: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /tests/omil-projects/src/index.js: -------------------------------------------------------------------------------- 1 | import { 2 | h, 3 | render, 4 | define, 5 | } from 'omi'; 6 | import oApp from './oApp.omi' 7 | import stores from './stores/stores' 8 | define('o-app', oApp) 9 | render(h('o-app'), 'body', stores) -------------------------------------------------------------------------------- /tests/omil-projects/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "@babel/preset-env", 4 | [ 5 | "@babel/preset-react", 6 | { 7 | "pragma": "h" 8 | } 9 | ] 10 | ] 11 | } -------------------------------------------------------------------------------- /libs/scripts/extension/classProperty.js: -------------------------------------------------------------------------------- 1 | const { 2 | transformSync 3 | } = require("@babel/core"); 4 | module.exports = (code, options) => { 5 | let output = transformSync(code, { 6 | plugins: [ 7 | require("@babel/plugin-proposal-class-properties", { "loose": true }) 8 | ] 9 | }) 10 | return output 11 | } -------------------------------------------------------------------------------- /libs/utils/getModules.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | module.exports = (path) => { 3 | return new Promise((resolve, reject) => { 4 | fs.readFile(path, (err, data) => { 5 | if (err) { 6 | reject() 7 | } else { 8 | resolve(data.toString()) 9 | } 10 | }) 11 | }) 12 | } -------------------------------------------------------------------------------- /docs/guide/public/css/spectre_custom.css: -------------------------------------------------------------------------------- 1 | .container { 2 | height: 100%; } 3 | 4 | .columns { 5 | height: 100%; } 6 | 7 | html, body { 8 | height: 100%; 9 | margin: 0; } 10 | 11 | a { 12 | color: #004ed0; } 13 | 14 | a:hover { 15 | color: #6d6d6d; 16 | text-decoration: none; } 17 | 18 | img { 19 | max-width: 100%; 20 | max-height: 100%; } 21 | -------------------------------------------------------------------------------- /libs/utils/annotation.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | remove(option) { 3 | const { 4 | code, 5 | type 6 | } = option 7 | switch (type) { 8 | case 'html': 9 | return html(code) 10 | } 11 | } 12 | } 13 | 14 | const html = (code) => { 15 | code = code.replace(//g, '') 16 | return code 17 | } -------------------------------------------------------------------------------- /libs/scripts/modules/render.js: -------------------------------------------------------------------------------- 1 | module.exports = (option) => { 2 | let { 3 | templateComponentName, 4 | sourceObj 5 | } = option 6 | 7 | if (templateComponentName&&sourceObj.file==='html') { 8 | // console.log(templateComponentName, sourceObj.file) 9 | return ` 10 | render(html${'`<'}${templateComponentName}${'/>`'}, 'body'); 11 | ` 12 | } else { 13 | return '' 14 | } 15 | } -------------------------------------------------------------------------------- /tests/omil-babel/index.js: -------------------------------------------------------------------------------- 1 | const babel = require("@babel/core"); 2 | const code = babel.transformSync(` 3 | const fn = () => 1; 4 | class A extends B { 5 | name = 1 6 | constructor(props){ 7 | super(props) 8 | this.name = 'eno' 9 | } 10 | } 11 | `, { 12 | presets: [ 13 | require("@babel/preset-env") 14 | ], 15 | plugins: [ 16 | require("@babel/plugin-proposal-class-properties"), 17 | ] 18 | }); 19 | console.log(code); -------------------------------------------------------------------------------- /tests/omil-components/abc.pug: -------------------------------------------------------------------------------- 1 | doctype html 2 | html(lang="en") 3 | head 4 | title= pageTitle 5 | script(type='text/javascript'). 6 | if (foo) bar(1 + 5) 7 | body 8 | h1 Pug - node template engine 9 | #container.col 10 | if youAreUsingPug 11 | p You are amazing 12 | else 13 | p Get on it! 14 | p. 15 | Pug is a terse and simple templating language with a 16 | strong focus on performance and powerful features. -------------------------------------------------------------------------------- /tests/omil-projects/src/components/React/EnoType.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | interface EnoTypeProps { } 3 | interface EnoTypeState { name: string } 4 | export default (Component: React.ComponentType) => { 5 | return class EnoType extends React.Component { 6 | constructor(props: EnoTypeProps) { 7 | super(props) 8 | this.state = { name: 'Eno Yao' } 9 | } 10 | render() { return } 11 | } 12 | } -------------------------------------------------------------------------------- /tests/omil-projects/dist/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /tests/omil-projects/dist/demo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /libs/styles/extension/index.js: -------------------------------------------------------------------------------- 1 | const sass = require('./sass.sync.js') 2 | 3 | const compileSass = (data) => { 4 | return new Promise((resolve, reject) => { 5 | sass.compile(data, { 6 | style: sass.style.compressed, 7 | // style: sass.style.compact, 8 | // style: sass.style.expanded, 9 | // style: sass.style.nested, 10 | }, (result) => { 11 | // console.log(result) 12 | resolve(result) 13 | }); 14 | }) 15 | } 16 | 17 | module.exports = { 18 | compileSass 19 | } -------------------------------------------------------------------------------- /tests/omil-projects/src/components/React/Eno.eno: -------------------------------------------------------------------------------- 1 | 7 | 20 | -------------------------------------------------------------------------------- /tests/omil-components/Test.js: -------------------------------------------------------------------------------- 1 | import { Component as WeElement, createElement as h } from "react"; 2 | 3 | function _defineProperty(obj, key, value) { 4 | if (key in obj) { 5 | Object.defineProperty(obj, key, { 6 | value: value, 7 | enumerable: true, 8 | configurable: true, 9 | writable: true 10 | }); 11 | } else { 12 | obj[key] = value; 13 | } 14 | 15 | return obj; 16 | } 17 | 18 | class Header extends WeElement { 19 | render() { 20 | return h("div", null, this.name); 21 | } 22 | 23 | constructor() { 24 | _defineProperty(this, "name", 1); 25 | } 26 | } 27 | 28 | export default Header; 29 | -------------------------------------------------------------------------------- /tests/omil-tests/t2.js: -------------------------------------------------------------------------------- 1 | var omil = require('../../libs') 2 | omil({ 3 | type: 'extension', 4 | // file: 'html', 5 | options: null, 6 | source: ` 7 | 16 | `, 17 | callback(code) { 18 | console.log(code.allScript) 19 | } 20 | }).compileSass(` 21 | p{ 22 | color:red; 23 | span{ 24 | font-size:14px 25 | } 26 | } 27 | `).then((data) => { 28 | // console.log(data.text) 29 | }); -------------------------------------------------------------------------------- /libs/templates/styledcomponents/index.js: -------------------------------------------------------------------------------- 1 | // const cheerio = require('cheerio'); 2 | module.exports = ({ style, template }) => { 3 | // console.log({ style, template }) 4 | // console.log($('StyledComponents').html()) 5 | if (style) { 6 | return template 7 | } else { 8 | // let $ = cheerio.load(template) 9 | // let html = $('StyledComponents').html() 10 | // console.log(html) 11 | template = template.replace(/\([\n\s\S]*)<\/StyledComponents\>/g, '$1') 12 | // console.log(template) 13 | // return html ? html : template 14 | return template 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /docs/guide/public/js/book-post.js: -------------------------------------------------------------------------------- 1 | // add figcaption under image 2 | document.querySelectorAll('img').forEach(function(img){ 3 | if(img.getAttribute('alt')) { 4 | let parent = img.parentNode; 5 | let figcaption = document.createElement('figcaption'); 6 | figcaption.innerHTML = img.getAttribute('alt'); 7 | parent.appendChild(figcaption); 8 | } 9 | }) 10 | 11 | // add table wrapper 12 | document.querySelectorAll('.book-post > table').forEach(function(table){ 13 | let parent = table.parentNode; 14 | let wrapper = document.createElement('div'); 15 | wrapper.className = 'table-wrapper' 16 | parent.insertBefore(wrapper, table); 17 | wrapper.appendChild(table); 18 | }) -------------------------------------------------------------------------------- /libs/styles/loader/index.js: -------------------------------------------------------------------------------- 1 | const sass = require('node-sass') 2 | const compileSass = (data) => { 3 | return new Promise((resolve, reject) => { 4 | sass.render({ 5 | data, 6 | }, function (err, result) { 7 | if (err) { 8 | reject() 9 | } else { 10 | resolve(result.css.toString()) 11 | } 12 | }); 13 | }) 14 | } 15 | const compileSassSync = (data) => { 16 | return sass.renderSync({ 17 | data, 18 | },{ 19 | outputStyle: 'compressed' 20 | }) 21 | .css 22 | .toString() 23 | } 24 | 25 | module.exports = { 26 | compileSass, 27 | compileSassSync 28 | } -------------------------------------------------------------------------------- /tests/omil-projects/src/components/React/Eno.js: -------------------------------------------------------------------------------- 1 | import { Component as WeElement, createElement as h } from "react"; 2 | import styled from "styled-components"; 3 | import EnoType from "./EnoType.tsx"; 4 | const StyledComponents = styled.div` 5 | p { 6 | color: #58bc58; 7 | } 8 | `; 9 | export default EnoType( 10 | class Eno extends WeElement { 11 | render() { 12 | return h( 13 | StyledComponents, 14 | null, 15 | h("div", null, h("p", null, this.state.name)) 16 | ); 17 | } 18 | 19 | constructor(props) { 20 | super(props); 21 | this.state = { 22 | name: "abc", 23 | age: 18 24 | }; 25 | } 26 | } 27 | ); 28 | -------------------------------------------------------------------------------- /docs/guide/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hexo-site", 3 | "version": "0.0.0", 4 | "private": true, 5 | "hexo": { 6 | "version": "3.9.0" 7 | }, 8 | "scripts": { 9 | "start": "hexo server", 10 | "build": "hexo generate" 11 | }, 12 | "dependencies": { 13 | "hexo": "^3.9.0", 14 | "hexo-deployer-git": "^1.0.0", 15 | "hexo-generator-archive": "^0.1.5", 16 | "hexo-generator-category": "^0.1.3", 17 | "hexo-generator-index": "^0.2.1", 18 | "hexo-generator-tag": "^0.2.0", 19 | "hexo-renderer-ejs": "^0.3.1", 20 | "hexo-renderer-marked": "^1.0.1", 21 | "hexo-renderer-scss": "^1.2.0", 22 | "hexo-renderer-stylus": "^0.3.3", 23 | "hexo-server": "^0.3.3" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /libs/scripts/extension/convert.js: -------------------------------------------------------------------------------- 1 | // enoOmi -> eno-omi 2 | 3 | const convertToCamelCase = (str) => { 4 | let strArr = str.split('-'); 5 | if (strArr[0] === '') { 6 | strArr.shift() 7 | } 8 | for (let i = 1, len = strArr.length; i < len; i++) { 9 | if (strArr[i] !== '') { 10 | strArr[i] = strArr[i][0].toUpperCase() + strArr[i].substring(1) 11 | } 12 | } 13 | return strArr.join('') 14 | } 15 | 16 | const captain = (str) => { 17 | return str.substring(0, 1).toUpperCase() + str.substring(1); 18 | } 19 | 20 | const isCaptain = (str) => { 21 | return /[A-Z]/.test(str.substring(0, 1)) 22 | } 23 | 24 | module.exports = { 25 | convertToCamelCase, 26 | captain, 27 | isCaptain 28 | } -------------------------------------------------------------------------------- /tests/omil-projects/src/components/oHeader.omi: -------------------------------------------------------------------------------- 1 | 7 | 24 | -------------------------------------------------------------------------------- /tests/omil-tests/t3.js: -------------------------------------------------------------------------------- 1 | var omil = require('../../libs') 2 | omil({ 3 | type: 'extension', 4 | // file: 'html', 5 | options: null, 6 | source: ` 7 | 16 | 22 | `, 23 | callback(code) { 24 | console.log(code.allScript) 25 | } 26 | }).compileSass(` 27 | p{ 28 | color:red; 29 | span{ 30 | font-size:14px 31 | } 32 | } 33 | `).then((data) => { 34 | // console.log(data.text) 35 | }); -------------------------------------------------------------------------------- /tests/omil-projects/src/components/oFileTest.omi: -------------------------------------------------------------------------------- 1 | 7 | 24 | -------------------------------------------------------------------------------- /tests/omil-projects/src/oApp.omi: -------------------------------------------------------------------------------- 1 | 10 | 30 | -------------------------------------------------------------------------------- /libs/index.js: -------------------------------------------------------------------------------- 1 | const compileAll = require('./loaders/index') 2 | const path = require('path') 3 | const fs = require('fs') 4 | 5 | module.exports = function (source, map) { 6 | // use in omi-snippets 7 | if (typeof source === 'object') { 8 | const callback = (info, code, map) => { 9 | return code 10 | } 11 | const sourceObj = source 12 | const output = compileAll(sourceObj, source.options, source.callback) 13 | const compileSass = require('./styles/extension/index').compileSass 14 | return { 15 | compileSass, 16 | } 17 | } else { 18 | const callback = this.async() 19 | const sourceObj = { 20 | source 21 | } 22 | // use in webpack loader 23 | const { 24 | getOptions 25 | } = require('loader-utils') 26 | const options = getOptions(this) || {} 27 | const output = compileAll(sourceObj, options, callback) 28 | } 29 | }; -------------------------------------------------------------------------------- /libs/scripts/loader/transform.js: -------------------------------------------------------------------------------- 1 | const { 2 | transform 3 | } = require("@babel/core"); 4 | module.exports = (code, options) => { 5 | return new Promise((resolve, reject) => { 6 | const defaultOption = { 7 | presets: [ 8 | ["@babel/preset-env"], 9 | // [ 10 | // "@babel/preset-react", 11 | // { 12 | // "pragma": "h", 13 | // } 14 | // ] 15 | ], 16 | 17 | } 18 | // comibine option 19 | const finalOptions = Object.assign({}, defaultOption, { 20 | ...options 21 | }); 22 | // console.log(finalOptions) 23 | transform(code, { 24 | ...finalOptions 25 | }, (err, result) => { 26 | if (err) { 27 | reject(err) 28 | } else { 29 | // console.log(result) 30 | resolve(result) 31 | } 32 | }); 33 | }) 34 | } -------------------------------------------------------------------------------- /tests/omil-components/Abc.eno: -------------------------------------------------------------------------------- 1 | 4 | 24 | -------------------------------------------------------------------------------- /libs/scripts/modules/define.js: -------------------------------------------------------------------------------- 1 | const { 2 | convertToCamelCase, 3 | captain, 4 | isCaptain 5 | } = require('../extension/convert') 6 | 7 | module.exports = (option) => { 8 | let { 9 | templateComponentName, 10 | script 11 | } = option 12 | 13 | if (templateComponentName) { 14 | const templateComponentCamelCaseName = captain(convertToCamelCase(templateComponentName)) 15 | const isHoc = script.match(/export\s+default[\n\s\S]+?class[\s\w]*\{|module.exports\s*=[\n\s\S]*?class\s*\{/g) 16 | // hoc 17 | if (isHoc && isHoc[0].replace(/([\s\.\=])/g, "").length > 19) { 18 | return ` 19 | // export default ${templateComponentCamelCaseName} 20 | ` 21 | } else { 22 | switch (isCaptain(templateComponentName)) { 23 | case true: 24 | return ` 25 | export default ${templateComponentCamelCaseName} 26 | ` 27 | default: 28 | 29 | return ` 30 | define('${templateComponentName}', ${templateComponentCamelCaseName}); 31 | ` 32 | } 33 | } 34 | 35 | } else { 36 | return '' 37 | } 38 | } -------------------------------------------------------------------------------- /tests/omil-projects/src/assets/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /libs/scripts/extension/transform.js: -------------------------------------------------------------------------------- 1 | const { 2 | transform, 3 | transformSync 4 | } = require("@babel/core"); 5 | module.exports = (code, options) => { 6 | return new Promise((resolve, reject) => { 7 | // console.log(code,options) 8 | const defaultOption = { 9 | plugins: [ 10 | require("@babel/plugin-proposal-class-properties") 11 | ], 12 | presets: [ 13 | // [require('@babel/plugin-proposal-class-properties')], 14 | // [require("@babel/preset-env")], 15 | [ 16 | require("@babel/preset-react"), 17 | { 18 | "pragma": "h", 19 | } 20 | ] 21 | ], 22 | 23 | } 24 | // comibine option 25 | const finalOptions = Object.assign({}, defaultOption, { 26 | ...options 27 | }); 28 | // console.log(finalOptions) 29 | transform(code, { 30 | ...finalOptions 31 | }, (err, result) => { 32 | if (err) { 33 | reject(err) 34 | } else { 35 | // console.log(result) 36 | resolve(result) 37 | } 38 | }); 39 | }) 40 | 41 | } -------------------------------------------------------------------------------- /tests/omil-tests/a.js: -------------------------------------------------------------------------------- 1 | var omil = require('../../libs') 2 | omil({ 3 | type: 'extension', 4 | // file: 'html', 5 | options: null, 6 | source: ` 7 | 14 | 50 | `, 51 | callback(code) { 52 | console.log(code.allScript) 53 | } 54 | }).compileSass(` 55 | p{ 56 | color:red; 57 | span{ 58 | font-size:14px 59 | } 60 | } 61 | `).then((data) => { 62 | // console.log(data.text) 63 | }); -------------------------------------------------------------------------------- /libs/utils/comments.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | deleteCodeComments(code) { 3 | // console.log(code) 4 | // return code.replace(/"(?:\\"|[^"])*"|'(?:\\'|[^'])*'|\/\*[\S\s]*?\*\/|\/(?:\\\/|[^\/\r\n])+\/(?=[^\/])|\/\/.*|\.\s*require|(?:^|[^$])\brequire\s*\(\s*(["'])(.+?)\1\s*\)/g, '\n') 5 | // return code.replace(/(?:^|\n|\r)\s*\/\*[\s\S]*?\*\/\s*(?:\r|\n|$)/g, '\n').replace(/(?:^|\n|\r)\s*\/\/.*(?:\r|\n|$)/g, '\n') 6 | // return code.replace(/(?:^|\n|\r)\s*\/\*[\s\S]*?\*\/\s*(?:\r|\n|$)/g, '\n').replace(/(|\n|\r)\s*\/\/.*(?:\r|\n|$)/g, '\n') 7 | // let noComment = code.replace(/(?:^|\n|\r)\s*\/\*[\s\S]*?\*\/\s*(?:\r|\n|$)/g, '\n') 8 | // let noComment2 = code.replace(/(?:^|\n|\r)\s*\/\/.*(?:\r|\n|$)/g, '\n'); 9 | // console.log(noComment2) 10 | // return noComment 11 | let reg = /("([^\\\"]*(\\.)?)*")|('([^\\\']*(\\.)?)*')|(\/{2,}.*?(\r|\n))|(\/\*(\n|.)*?\*\/)/g;// 正则表达式 12 | return code.replace(reg, function (word) { // 去除注释后的文本 13 | return /^\/{2,}/.test(word) || /^\/\*/.test(word) ? "" : word; 14 | }); 15 | } 16 | } 17 | // function deleteCodeComments(code) { 18 | // return code.replace(/(?:^|\n|\r)\s*\/\*[\s\S]*?\*\/\s*(?:\r|\n|$)/g, '\n').replace(/(?:^|\n|\r)\s*\/\/.*(?:\r|\n|$)/g, '\n') 19 | // } 20 | // let string = ` 21 | // // abc 22 | // abc 23 | // cba 24 | // /*** 179283719 25 | // 213132*/ 26 | // ` 27 | // let result = deleteCodeComments(string) 28 | // console.log(result) -------------------------------------------------------------------------------- /tests/omil-tests/t.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Document 9 | 10 | 11 | 12 |
13 | 14 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /tests/omil-components/Abc.js: -------------------------------------------------------------------------------- 1 | var _temp; 2 | 3 | import { Component as WeElement, createElement as h } from "react"; 4 | import styled from "styled-components"; 5 | const StyledComponents = styled.div` 6 | .logBox { 7 | background: #fff; 8 | width: 76%; 9 | height: 20rem; 10 | position: absolute; 11 | left: 50%; 12 | top: 50%; 13 | transform: translate(-50%, -50%); 14 | } 15 | .logBox header { 16 | color: #000; 17 | text-align: center; 18 | line-height: 50px; 19 | } 20 | `; 21 | export default withRouter( 22 | Form.create({ 23 | name: "normal_login" 24 | })( 25 | ((_temp = class Abc extends WeElement { 26 | render() { 27 | return h(StyledComponents, null, h("div", null, "hello world")); 28 | } 29 | 30 | constructor(props) { 31 | super(props); 32 | 33 | this.handleSubmit = e => { 34 | e.preventDefault(); 35 | this.props.form.validateFields((err, values) => { 36 | if (!err) { 37 | console.log("Received values of form: ", values); 38 | } 39 | }); 40 | }; 41 | 42 | console.log(props); 43 | const { getFieldDecorator } = this.props.form; 44 | } 45 | }), 46 | _temp) 47 | ) 48 | ); 49 | dateFields((err, values) => { 50 | if (!err) { 51 | console.log("Received values of form: ", values); 52 | } 53 | }); 54 | }); 55 | 56 | console.log(props); 57 | const { getFieldDecorator } = this.props.form; 58 | } 59 | }), 60 | _temp) 61 | ) 62 | ); 63 | -------------------------------------------------------------------------------- /libs/styles/index.js: -------------------------------------------------------------------------------- 1 | const compileStyle = (sourceObj) => { 2 | // console.log(sourceObj) 3 | const omi = sourceObj.source 4 | const type = sourceObj.type 5 | let compileSassSync = null 6 | switch (type) { 7 | // use in omi-snippets 8 | case 'extension': 9 | compileSassSync = (sass) => { 10 | return sass 11 | } 12 | break 13 | // loader branch 14 | default: 15 | compileSassSync = require('./loader').compileSassSync 16 | } 17 | 18 | const styleInTag = (() => { 19 | // match content 20 | let isExistStyle = omi.match(/]*>[\s\S]*?<\/style>/g) 21 | // judge 70 | `, 71 | callback(code) { 72 | console.log(code.allScript) 73 | } 74 | }).compileSass(` 75 | p{ 76 | color:red; 77 | span{ 78 | font-size:14px 79 | } 80 | } 81 | `).then((data) => { 82 | // console.log(data.text) 83 | }); -------------------------------------------------------------------------------- /tests/omil-projects/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | module.exports = { 3 | // devtool: 'source-map', 4 | mode: 'development', 5 | entry: './src/index.js', 6 | output: { 7 | path: path.resolve(__dirname, 'dist'), 8 | filename: 'bundle.test.js' 9 | }, 10 | module: { 11 | rules: [{ 12 | test: /\.omi|eno$/, 13 | exclude: /(node_modules|bower_components)/, 14 | use: [{ 15 | // test 16 | loader: path.resolve(__dirname, '../../', 'libs'), 17 | options: { 18 | sourceMaps: 'both', 19 | plugins: [ 20 | [ 21 | "@babel/plugin-transform-runtime", 22 | { 23 | "absoluteRuntime": false, 24 | "corejs": false, 25 | "helpers": true, 26 | "regenerator": true, 27 | "useESModules": false 28 | } 29 | ], 30 | ["@babel/plugin-proposal-class-properties"] 31 | ] 32 | } 33 | }], 34 | }, { 35 | test: /\.js$/, 36 | exclude: /(node_modules|bower_components)/, 37 | use: { 38 | loader: 'babel-loader', 39 | options: { 40 | presets: ['@babel/preset-env'] 41 | } 42 | } 43 | }, { 44 | test: /\.css$/, 45 | use: ['to-string-loader', 'css-loader'] 46 | }, { 47 | test: /\.(png|jpg|gif)$/i, 48 | use: [{ 49 | loader: 'file-loader', 50 | options: { 51 | limit: 8192 52 | } 53 | }] 54 | }] 55 | } 56 | }; -------------------------------------------------------------------------------- /libs/templates/index.js: -------------------------------------------------------------------------------- 1 | const annotation = require('../utils/annotation') 2 | const { 3 | convertToCamelCase, 4 | captain, 5 | isCaptain 6 | } = require('../scripts/extension/convert') 7 | const cheerio = require('cheerio') 8 | 9 | const findAttr = (templateInTag, attr) => { 10 | let attrKey = templateInTag.match(/]*>/g)[0] 11 | if (attrKey.indexOf(attr) >= 0) { 12 | let $ = cheerio.load(attrKey) 13 | return $('template').attr(attr).replace(/^\s*|\s*$/g, "") || '' 14 | } else { 15 | return '' 16 | } 17 | } 18 | 19 | const compileTemplate = (sourceObj) => { 20 | const omi = sourceObj.source 21 | const templateInTag = ( 22 | omi 23 | .match(/]*>([\s\S]*?)<\/template>/g)[0] 24 | ) 25 | let template = ( 26 | templateInTag 27 | .replace(/]*>|<\/template>/g, '') 28 | ) 29 | 30 | // lang="xxx" 31 | const templateLang = findAttr(templateInTag, 'lang') 32 | 33 | // name="xxx" 34 | const templateComponentName = findAttr(templateInTag, 'name') 35 | 36 | // framework="xxx" 37 | const templateFrameworkName = findAttr(templateInTag, 'framework') 38 | 39 | // xxx 40 | if (isCaptain(templateComponentName)) { 41 | template = `${template}` 42 | } 43 | 44 | // render="xxx" 45 | // const templateWithRender = findAttr(templateInTag, 'render') 46 | 47 | // console.log({ 48 | // templateLang, 49 | // templateComponentName, 50 | // templateFrameworkName 51 | // }) 52 | 53 | // remove annotation 54 | template = annotation.remove({ 55 | code: template, 56 | type: 'html' 57 | }) 58 | return { 59 | template, 60 | templateLang, 61 | templateComponentName, 62 | templateFrameworkName 63 | } 64 | } 65 | 66 | module.exports = compileTemplate -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "omil", 3 | "version": "2.0.7", 4 | "description": "Webpack loader for Omi.js, React.js or Rax.js components", 5 | "main": "libs/index.js", 6 | "scripts": { 7 | "start": "webpack" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/Wscats/omil.git" 12 | }, 13 | "bugs": { 14 | "url": "https://github.com/Wscats/omil/issues" 15 | }, 16 | "homepage": "https://github.com/Wscats/omil", 17 | "author": "Eno Yao ", 18 | "license": "MIT", 19 | "devDependencies": { 20 | "@babel/core": "^7.4.3", 21 | "@babel/generator": "^7.4.0", 22 | "@babel/plugin-transform-runtime": "^7.4.4", 23 | "@babel/preset-env": "^7.4.3", 24 | "@babel/preset-react": "^7.0.0", 25 | "@babel/types": "^7.4.4", 26 | "babel-loader": "^8.0.0-beta.0", 27 | "babel-plugin-transform-class-properties": "^6.24.1", 28 | "css-loader": "^2.1.1", 29 | "file-loader": "^3.0.1", 30 | "loader-utils": "^1.2.3", 31 | "recast": "^0.18.1", 32 | "sass-loader": "^7.1.0", 33 | "style-loader": "^0.23.1", 34 | "to-string-loader": "^1.1.5", 35 | "url-loader": "^1.1.2", 36 | "webpack": "^4.30.0", 37 | "webpack-cli": "^3.3.1" 38 | }, 39 | "keywords": [ 40 | "omi", 41 | "webcomponents", 42 | "jsx", 43 | "proxy", 44 | "preact", 45 | "react", 46 | "rax", 47 | "virtual dom", 48 | "vdom", 49 | "components", 50 | "virtual", 51 | "dom", 52 | "eno", 53 | "yao", 54 | "wscats", 55 | "loader", 56 | "dk" 57 | ], 58 | "peerDependencies": { 59 | "node-sass": "^4.12.0" 60 | }, 61 | "dependencies": { 62 | "@babel/core": "^7.9.6", 63 | "@babel/plugin-proposal-class-properties": "^7.8.3", 64 | "@babel/preset-env": "^7.9.6", 65 | "@babel/preset-react": "^7.9.4", 66 | "babel-plugin-transform-class-properties": "^6.24.1", 67 | "cheerio": "^1.0.0-rc.3", 68 | "node-sass": "^4.14.1", 69 | "omi": "^6.19.3" 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /docs/guide/public/js/book-sidebar.js: -------------------------------------------------------------------------------- 1 | // collapse sidebar 2 | var i = 0; 3 | document.querySelectorAll('.book-sidebar > .sidebar-content > ul > li > ul > li').forEach(function(li){ 4 | var ul = li.querySelector('ul'); 5 | if(ul){ 6 | var accordion = document.createElement('div'); 7 | accordion.setAttribute("class", "accordion"); 8 | 9 | var checkbox = document.createElement('input'); 10 | checkbox.setAttribute("type", "checkbox"); 11 | checkbox.setAttribute("id", "accordion-" + i); 12 | checkbox.setAttribute("hidden", ""); 13 | 14 | var label = document.createElement('label'); 15 | label.setAttribute("class", "accordion-header c-hand"); 16 | label.setAttribute("for", "accordion-" + i); 17 | var icon = document.createElement('i'); 18 | icon.setAttribute("class", "icon icon-caret"); 19 | label.appendChild(icon); 20 | 21 | var acco_body = document.createElement('div'); 22 | acco_body.setAttribute("class", "accordion-body") 23 | acco_body.appendChild(ul); 24 | 25 | accordion.appendChild(checkbox); 26 | accordion.appendChild(acco_body); 27 | li.appendChild(label); 28 | li.appendChild(accordion); 29 | i++; 30 | } 31 | }) 32 | 33 | // highlight current tab 34 | document.querySelectorAll('.sidebar-content a').forEach(function(item){ 35 | if(item.href === window.location.href || item.href === window.location.href.slice(0, -1)) { 36 | item.className = "book-sidebar-current"; 37 | var parent = item.parentNode; 38 | while(parent.className != "sidebar-content") { 39 | if(parent.className == "accordion") { 40 | break; 41 | } 42 | parent = parent.parentNode; 43 | } 44 | if(parent.className == "accordion") { 45 | parent.querySelector('input').setAttribute("checked", ""); 46 | } 47 | } 48 | }) 49 | 50 | document.getElementsByClassName("sidebar-content")[0].style.display = "block"; -------------------------------------------------------------------------------- /docs/guide/_config.yml: -------------------------------------------------------------------------------- 1 | # Hexo Configuration 2 | ## Docs: https://hexo.io/docs/configuration.html 3 | ## Source: https://github.com/hexojs/hexo/ 4 | 5 | # Site 6 | title: Omil 7 | subtitle: 8 | description: 9 | keywords: 10 | author: Eno Yao 11 | language: 12 | timezone: 13 | 14 | # URL 15 | ## If your site is put in a subdirectory, set url as 'http://yoursite.com/child' and root as '/child/' 16 | url: https://wscats.github.io/omi-docs/public/home 17 | root: ../ 18 | permalink: :title/ 19 | permalink_defaults: 20 | 21 | # Directory 22 | source_dir: source 23 | public_dir: public 24 | tag_dir: tags 25 | archive_dir: archives 26 | category_dir: categories 27 | code_dir: downloads/code 28 | i18n_dir: :lang 29 | skip_render: 30 | 31 | # Writing 32 | new_post_name: :title.md # File name of new posts 33 | default_layout: post 34 | titlecase: false # Transform title into titlecase 35 | external_link: true # Open external links in new tab 36 | filename_case: 0 37 | render_drafts: false 38 | post_asset_folder: false 39 | relative_link: false 40 | future: true 41 | highlight: 42 | enable: true 43 | line_number: true 44 | auto_detect: false 45 | tab_replace: 46 | 47 | # Home page setting 48 | 49 | home_page: home.md # filename under /source/_posts/ 50 | menu_page: menu.md # filename under /source/_posts/ 51 | 52 | # path: Root path for your blogs index page. (default = '') 53 | # per_page: Posts displayed per page. (0 = disable pagination) 54 | # order_by: Posts order. (Order by date descending by default) 55 | index_generator: 56 | path: '' 57 | per_page: 10 58 | order_by: -date 59 | 60 | # Category & Tag 61 | default_category: uncategorized 62 | category_map: 63 | tag_map: 64 | 65 | # Date / Time format 66 | ## Hexo uses Moment.js to parse and display date 67 | ## You can customize the date format as defined in 68 | ## http://momentjs.com/docs/#/displaying/format/ 69 | date_format: YYYY-MM-DD 70 | time_format: HH:mm:ss 71 | 72 | # Pagination 73 | ## Set per_page to 0 to disable pagination 74 | per_page: 10 75 | pagination_dir: page 76 | 77 | # Extensions 78 | ## Plugins: https://hexo.io/plugins/ 79 | ## Themes: https://hexo.io/themes/ 80 | theme: book 81 | 82 | # Deployment 83 | ## Docs: https://hexo.io/docs/deployment.html 84 | deploy: 85 | type: git 86 | repository: https://github.com/Wscats/omil 87 | branch: master 88 | 89 | -------------------------------------------------------------------------------- /tests/omil-projects/src/stores/stores.js: -------------------------------------------------------------------------------- 1 | export default { 2 | data: { 3 | isShowGallery: true, 4 | galleryImg: '', 5 | news:[{ 6 | src:'https://camo.githubusercontent.com/5a3ce051411cca4d8abd0e0abff879bb5a871520/68747470733a2f2f74656e63656e742e6769746875622e696f2f6f6d692f6173736574732f6f6d692d6c6f676f323031392e737667', 7 | title: 'omi-docs', 8 | description: 'Omi official documents', 9 | rotate: 0 10 | },{ 11 | src:'https://camo.githubusercontent.com/5a3ce051411cca4d8abd0e0abff879bb5a871520/68747470733a2f2f74656e63656e742e6769746875622e696f2f6f6d692f6173736574732f6f6d692d6c6f676f323031392e737667', 12 | title: 'omio', 13 | description: 'Omi for old browsers with same api(IE8+ and mobile browsers)', 14 | rotate: 45 15 | },{ 16 | src:'https://camo.githubusercontent.com/5a3ce051411cca4d8abd0e0abff879bb5a871520/68747470733a2f2f74656e63656e742e6769746875622e696f2f6f6d692f6173736574732f6f6d692d6c6f676f323031392e737667', 17 | title: 'omis', 18 | description: 'Server-side rendering(support omio only)', 19 | rotate: 90 20 | },{ 21 | src:'https://camo.githubusercontent.com/5a3ce051411cca4d8abd0e0abff879bb5a871520/68747470733a2f2f74656e63656e742e6769746875622e696f2f6f6d692f6173736574732f6f6d692d6c6f676f323031392e737667', 22 | title: 'omi-router', 23 | description: 'Omi official router in 1KB js', 24 | rotate: 135 25 | },{ 26 | src:'https://camo.githubusercontent.com/5a3ce051411cca4d8abd0e0abff879bb5a871520/68747470733a2f2f74656e63656e742e6769746875622e696f2f6f6d692f6173736574732f6f6d692d6c6f676f323031392e737667', 27 | title: 'omi-cli', 28 | description: 'Project scaffolding', 29 | rotate: 180 30 | },{ 31 | src:'https://camo.githubusercontent.com/5a3ce051411cca4d8abd0e0abff879bb5a871520/68747470733a2f2f74656e63656e742e6769746875622e696f2f6f6d692f6173736574732f6f6d692d6c6f676f323031392e737667', 32 | title: 'omi-devtools', 33 | description: 'Browser DevTools extension', 34 | rotate: 225 35 | },{ 36 | src:'https://camo.githubusercontent.com/5a3ce051411cca4d8abd0e0abff879bb5a871520/68747470733a2f2f74656e63656e742e6769746875622e696f2f6f6d692f6173736574732f6f6d692d6c6f676f323031392e737667', 37 | title: 'omiu', 38 | description: 'Omi official UI', 39 | rotate: 270 40 | }], 41 | showNews:[] 42 | } 43 | } -------------------------------------------------------------------------------- /libs/scripts/index.js: -------------------------------------------------------------------------------- 1 | const compileStyle = require('../styles/index') 2 | const { deleteCodeComments } = require('../utils/comments') 3 | const cheerio = require('cheerio') 4 | const { 5 | isCaptain 6 | } = require('./extension/convert') 7 | const compileScript = (sourceObj) => { 8 | const omi = sourceObj.source 9 | const { 10 | style, 11 | isExistStyle, 12 | styleLang, 13 | templateComponentName 14 | } = sourceObj 15 | 16 | const scriptInTag = (() => { 17 | // match some content like 18 | let isExistScript = omi.match(/]*>[\s\S]*?<\/script>/g) 19 | // judge ' 24 | } 25 | })() 26 | let script = ( 27 | // clear tag which is 28 | scriptInTag 29 | .replace(/]*>|<\/script>/g, '') 30 | ) 31 | // console.log(script) 32 | // delete comments 33 | script = deleteCodeComments(script) 34 | // console.log(script) 35 | const styleInScript = (() => { 36 | // if css(){} or css = 'xxx' in script , we should combine style and css functuon 37 | if (isCaptain(templateComponentName)) { 38 | script = script.replace(/static\s*css\s*=([^\)]*)/g, `static css = $1`) 39 | return script 40 | return script 41 | } else { 42 | script = script.replace(/static\s*css\s*=([^\)]*)/g, `static css = ${'`'}${style}${'`'}+$1`) 43 | return script 44 | } 45 | 46 | })() 47 | 48 | const scriptType = (() => { 49 | let type = scriptInTag.match(/]*>/g)[0] 50 | if (type.indexOf('type') >= 0) { 51 | let $ = cheerio.load(type) 52 | // console.log($('template').attr('lang')||'') 53 | // return lang.replace(/]*)["']\s*>/g, '$1') 54 | return $('script').attr('type').replace(/^\s*|\s*$/g, "") || '' 55 | } else { 56 | return '' 57 | } 58 | })() 59 | 60 | 61 | const scriptLang = (() => { 62 | if (scriptInTag) { 63 | return scriptInTag 64 | .match(/]*>/g)[0] 65 | .replace(/]*)["']\s*>/g, '$1') 66 | } 67 | })() 68 | return { 69 | isExistScript: scriptInTag ? true : false, 70 | scriptType, 71 | scriptLang, 72 | script, 73 | style, 74 | isExistStyle, 75 | styleLang 76 | }; 77 | 78 | } 79 | 80 | module.exports = compileScript -------------------------------------------------------------------------------- /tests/omil-projects/src/components/oGallery.omi: -------------------------------------------------------------------------------- 1 | 15 | 25 | 26 | 89 | 90 | -------------------------------------------------------------------------------- /tests/omil-components/Login.eno: -------------------------------------------------------------------------------- 1 | 7 | 8 | 69 | -------------------------------------------------------------------------------- /libs/scripts/modules/import.js: -------------------------------------------------------------------------------- 1 | const { 2 | isCaptain 3 | } = require('../extension/convert') 4 | 5 | module.exports = (option) => { 6 | const { 7 | script, 8 | isExistScript, 9 | scriptLang, 10 | template, 11 | templateLang, 12 | templateComponentName, 13 | templateFrameworkName, 14 | style, 15 | styleLang, 16 | isExistStyle, 17 | sourceObj 18 | } = option 19 | // console.log(style) 20 | const { 21 | file 22 | } = sourceObj 23 | switch (file) { 24 | case 'html': 25 | return ` 26 | const { 27 | ${ 28 | // register component 29 | 'WeElement,' 30 | } 31 | ${ 32 | // when you use component, you should define 33 | templateComponentName ? 'define,' : '' 34 | } 35 | html, 36 | h, 37 | render 38 | } = omi; 39 | ` 40 | break 41 | default: 42 | // console.log(isCaptain(templateComponentName)) 43 | switch (isCaptain(templateComponentName)) { 44 | // A 45 | case true: 46 | return ` 47 | import { 48 | ${ 49 | // register component 50 | 'Component as WeElement,' 51 | } 52 | ${ 53 | // JSX or HTML 54 | // html, 55 | // htm, 56 | templateLang === 'html' || templateLang === 'htm' ? 'html' : 'createElement as h' 57 | } 58 | } from '${ 59 | // react , omi or rax 60 | templateFrameworkName ? templateFrameworkName : 'react' 61 | }'; 62 | ` 63 | // css 64 | + 65 | ` 66 | ${style ? 'import styled from "styled-components"' : ''} 67 | ` 68 | // + ` 69 | // ${style ? 'const StyledComponents = styled.div`' + style + '`' : ''} 70 | // ` 71 | // + 72 | // ` 73 | // import { 74 | // ${ 75 | // // when you use component, you should define 76 | // templateComponentName ? 'render,' : '' 77 | // } 78 | // ${ 79 | // 'findDOMNode' 80 | // } 81 | // } from "react-dom" 82 | // ` 83 | break; 84 | // a 85 | default: 86 | return ` 87 | import { 88 | ${ 89 | // register component 90 | 'WeElement,' 91 | } 92 | ${ 93 | // when you use component, you should define 94 | templateComponentName ? 'define,' : '' 95 | } 96 | ${ 97 | // JSX or HTML 98 | // html, 99 | // htm, 100 | templateLang === 'html' || templateLang === 'htm' ? 'html' : 'h' 101 | } 102 | } from '${ 103 | // react , omi or rax 104 | templateFrameworkName ? templateFrameworkName : 'omi' 105 | }'; 106 | ` 107 | break; 108 | } 109 | } 110 | 111 | } -------------------------------------------------------------------------------- /tests/omil-components/Login.js: -------------------------------------------------------------------------------- 1 | var _temp; 2 | 3 | import { Component as WeElement, createElement as h } from "react"; 4 | import styled from "styled-components"; 5 | import React from "react"; 6 | import { Provider, connect } from "react-redux"; 7 | import { withRouter } from "react-router"; 8 | import store from "../../store/index"; 9 | import { Form, Icon, Input, Button, Checkbox } from "antd"; 10 | const StyledComponents = styled.div` 11 | .logBox { 12 | background: #fff; 13 | width: 76%; 14 | height: 20rem; 15 | position: absolute; 16 | left: 50%; 17 | top: 50%; 18 | transform: translate(-50%, -50%); 19 | } 20 | .logBox header { 21 | color: #000; 22 | text-align: center; 23 | line-height: 50px; 24 | } 25 | `; 26 | export default withRouter( 27 | Form.create({ 28 | name: "normal_login" 29 | })( 30 | ((_temp = class Login extends WeElement { 31 | render() { 32 | return h( 33 | StyledComponents, 34 | null, 35 | h( 36 | "div", 37 | { 38 | className: "logBox" 39 | }, 40 | h("header", null, "\u60A8\u597D\uFF0C\u8BF7\u767B\u9646"), 41 | this.renderWn 42 | ) 43 | ); 44 | } 45 | 46 | constructor(props) { 47 | super(props); 48 | 49 | this.handleSubmit = e => { 50 | e.preventDefault(); 51 | this.props.form.validateFields((err, values) => { 52 | if (!err) { 53 | console.log("Received values of form: ", values); 54 | } 55 | }); 56 | }; 57 | 58 | console.log(props); 59 | const { getFieldDecorator } = this.props.form; 60 | } 61 | 62 | renderWn() { 63 | return h( 64 | Form, 65 | { 66 | onSubmit: this.handleSubmit, 67 | className: "login-form" 68 | }, 69 | h( 70 | Form.Item, 71 | null, 72 | getFieldDecorator("username", { 73 | rules: [ 74 | { 75 | required: true, 76 | message: "Please input your username!" 77 | } 78 | ] 79 | })( 80 | h(Input, { 81 | prefix: h(Icon, { 82 | type: "user", 83 | style: { 84 | color: "rgba(0,0,0,.25)" 85 | } 86 | }), 87 | placeholder: "Username" 88 | }) 89 | ) 90 | ), 91 | h( 92 | Form.Item, 93 | null, 94 | getFieldDecorator("password", { 95 | rules: [ 96 | { 97 | required: true, 98 | message: "Please input your Password!" 99 | } 100 | ] 101 | })( 102 | h(Input, { 103 | prefix: h(Icon, { 104 | type: "lock", 105 | style: { 106 | color: "rgba(0,0,0,.25)" 107 | } 108 | }), 109 | type: "password", 110 | placeholder: "Password" 111 | }) 112 | ) 113 | ), 114 | h( 115 | Form.Item, 116 | null, 117 | getFieldDecorator("remember", { 118 | valuePropName: "checked", 119 | initialValue: true 120 | })(h(Checkbox, null, "Remember me")), 121 | h( 122 | "a", 123 | { 124 | className: "login-form-forgot", 125 | href: "" 126 | }, 127 | "Forgot password" 128 | ), 129 | h( 130 | Button, 131 | { 132 | type: "primary", 133 | htmlType: "submit", 134 | className: "login-form-button" 135 | }, 136 | "Log in" 137 | ), 138 | "Or ", 139 | h( 140 | "a", 141 | { 142 | href: "" 143 | }, 144 | "register now!" 145 | ) 146 | ) 147 | ); 148 | } 149 | }), 150 | _temp) 151 | ) 152 | ); 153 | -------------------------------------------------------------------------------- /tests/omil-projects/src/components/oPanel.omi: -------------------------------------------------------------------------------- 1 | 14 | 58 | -------------------------------------------------------------------------------- /tests/omil-projects/src/components/oSearch.omi: -------------------------------------------------------------------------------- 1 | 19 | 47 | -------------------------------------------------------------------------------- /libs/loaders/index.js: -------------------------------------------------------------------------------- 1 | const compileStyle = require('../styles/index') 2 | const compileTemplate = require('../templates/index') 3 | const compileScript = require('../scripts/index') 4 | 5 | // const getModules = require('../utils/getModules') 6 | const modulesStart = require('../scripts/modules/import') 7 | const modulesEnd = require('../scripts/modules/export') 8 | const defineComponent = require('../scripts/modules/define') 9 | const renderComponent = require('../scripts/modules/render') 10 | 11 | // hander styled components 12 | const handleStyledComponents = require('../templates/styledcomponents') 13 | 14 | // handle ast 15 | const ast = require('../scripts/ast') 16 | 17 | // handle sass 18 | const compileSass = require('../styles/extension/index').compileSass 19 | const path = require('path') 20 | const compileAll = async (sourceObj, options, callback) => { 21 | // html 22 | let { 23 | template, 24 | templateLang, 25 | templateComponentName, 26 | templateFrameworkName 27 | } = html = compileTemplate(sourceObj) 28 | // css 29 | let { 30 | style, 31 | isExistStyle, 32 | styleLang, 33 | } = compileStyle(sourceObj) 34 | 35 | // console.log(style,styleLang) 36 | // sass and jsx 37 | // use in omi-snippets 38 | style = sourceObj.type === 'extension' && styleLang === 'scss' ? ((await compileSass(style)).text || '').replace(/[\r\n]/g, "") : style 39 | // js 40 | let { 41 | script, 42 | isExistScript, 43 | scriptType, 44 | scriptLang, 45 | // variable 46 | // style, 47 | // isExistStyle, 48 | // styleLang 49 | } = js = compileScript({ 50 | ...sourceObj, 51 | style, 52 | styleLang, 53 | isExistStyle, 54 | templateComponentName 55 | }) 56 | // console.log(template) 57 | // console.log(style) 58 | // console.log(script) 59 | // whether exist 60 | template = handleStyledComponents({ style, template }); 61 | 62 | // html -> jsx 63 | try { 64 | if (templateLang !== 'html' && templateLang !== 'htm') { 65 | const transform = require('../scripts/extension/transform') 66 | // handle template 67 | template = (await transform(template, { 68 | // not in strict mode 69 | sourceType: 'script', 70 | })).code 71 | // console.log(template) 72 | } 73 | } catch (e) { 74 | callback({ 75 | status: 'fail', 76 | allScript: '', 77 | e 78 | }) 79 | throw new Error("Babel compile failed, see issues https://github.com/Wscats/eno-loader/issues") 80 | } 81 | 82 | // console.log(template) 83 | try { 84 | let allScript = ( 85 | // import html modules to transform html to jsx 86 | modulesStart({ 87 | script, 88 | isExistScript, 89 | scriptLang, 90 | template, 91 | templateLang, 92 | templateComponentName, 93 | templateFrameworkName, 94 | style, 95 | styleLang, 96 | isExistStyle, 97 | sourceObj 98 | }) + (() => { 99 | // handle static property in class 100 | const classProperty = require('../scripts/extension/classProperty') 101 | let exportReg = 'export\\s+default\\s*\\{|module.exports\\s*=\\s*\\{|export\\s+default\\s*class\\s*\\{|module.exports\\s*=\\s*class\\s*\\{|export\\s+default[\\n\\s\\S]+?class[\\s\\w]*\\{|module.exports\\s*=[\\n\\s\\S]*?class\\s*\\{' 102 | let exportReplaceReg = new RegExp(exportReg, 'g') 103 | let exportCompileReg = new RegExp('((' + exportReg + ')[\\s\\S]+)', 'g') 104 | let exportCode = script.match(exportCompileReg)[0] 105 | // console.log(exportCode) 106 | // console.log(classProperty(exportCode).code) 107 | script = script 108 | // load css and html 109 | // support export default {} and export default class {} 110 | .replace(exportReplaceReg, modulesEnd({ 111 | script, 112 | isExistScript, 113 | scriptLang, 114 | template, 115 | templateLang, 116 | templateComponentName, 117 | style, 118 | styleLang, 119 | isExistStyle, 120 | })) 121 | 122 | return script.replace(exportCompileReg, classProperty(exportCode).code) 123 | })() + 124 | // define('my-eno', myEno) 125 | defineComponent({ 126 | script, 127 | templateComponentName 128 | }) + 129 | // render(html`my-eno`, body) 130 | renderComponent({ 131 | templateComponentName, 132 | sourceObj 133 | }) 134 | ) 135 | // console.log(allScript) 136 | // ast 137 | allScript = (await ast({ 138 | script, 139 | allScript, 140 | isExistScript, 141 | scriptType, 142 | scriptLang, 143 | template, 144 | templateLang, 145 | templateComponentName, 146 | style, 147 | styleLang, 148 | isExistStyle 149 | }, null)).code 150 | // console.log(allScript) 151 | // as async return 152 | if (sourceObj.type === 'extension') { 153 | // callback(allScript) 154 | callback({ 155 | status: 'success', 156 | allScript, 157 | e: null 158 | }) 159 | } else { 160 | // handle template 161 | const transform = require('../scripts/loader/transform') 162 | // es6 -> es5 163 | const result = await transform(allScript, options) 164 | // console.log(result) 165 | callback(null, result.code, result.map) 166 | } 167 | 168 | // callback(null, result.code) 169 | } catch (e) { 170 | callback({ 171 | status: 'fail', 172 | allScript: '', 173 | e 174 | }) 175 | console.log(e) 176 | throw new Error("Babel compile failed, see issues https://github.com/Wscats/eno-loader/issues"); 177 | } 178 | } 179 | 180 | module.exports = compileAll -------------------------------------------------------------------------------- /libs/scripts/modules/export.js: -------------------------------------------------------------------------------- 1 | const { 2 | convertToCamelCase, 3 | captain, 4 | isCaptain 5 | } = require('../extension/convert') 6 | 7 | module.exports = (option) => { 8 | let { 9 | script, 10 | style, 11 | template, 12 | templateLang, 13 | templateComponentName 14 | } = option; 15 | // 1. static css = `xxx` 16 | const styleInScript = (() => { 17 | // style in script 18 | return /static\s*css\s*=([^\)]*)/g.test(script) 19 | })() 20 | // 2. css()=>{return ``} 21 | const styleInScript2 = (() => { 22 | // style in script 23 | return /css\s*\([^\)]*\)\s*\{[\s\S]*return([\s\S]*)/g.test(script) 24 | })() 25 | const css = (() => { 26 | if (styleInScript || style === undefined) { 27 | return '' 28 | } else { 29 | return `static css = (${'`'}${style}${'`'})` 30 | } 31 | })() 32 | 33 | const css2 = (() => { 34 | if (styleInScript2 || style === undefined) { 35 | return '' 36 | } else { 37 | return ` 38 | css() { 39 | return (${'`'}${style}${'`'}) 40 | } 41 | ` 42 | } 43 | })() 44 | const templateComponentCamelCaseName = (() => { 45 | if (templateComponentName) { 46 | return captain(convertToCamelCase(templateComponentName)) 47 | } else { 48 | return '' 49 | } 50 | })() 51 | 52 | const componentName = (() => { 53 | if (templateComponentName) { 54 | const templateComponentCamelCaseName = convertToCamelCase(templateComponentName) 55 | // return `const ${templateComponentCamelCaseName} =` 56 | return `` 57 | } else { 58 | return `export default` 59 | 60 | } 61 | })() 62 | 63 | // 2. render()=>{return ``} 64 | const renderInScript = (() => { 65 | // style in script 66 | return /render\s*\([^\)]*\)\s*\{[\s\S]*return([\s\S]*)/g.test(script) 67 | })() 68 | 69 | // ast(script, null) 70 | // console.log(templateComponentCamelCaseName) 71 | 72 | // 1.module.exports=class{ 19 remove . and = 73 | // 2.export default class { 19 74 | // console.log(script.match(/export\s+default[\n\s\S]+?class[\s\w]*\{|module.exports\s*=[\n\s\S]*?class\s*\{/g)) 75 | const isHoc = script.match(/export\s+default[\n\s\S]+?class[\s\w]*\{|module.exports\s*=[\n\s\S]*?class\s*\{/g) 76 | 77 | // hoc 78 | if (isHoc && isHoc[0].replace(/([\s\.\=])/g, "").length > 19) { 79 | let hocScript; 80 | switch (isCaptain(templateComponentName)) { 81 | // react hoc 82 | case true: 83 | switch (templateLang) { 84 | // html 85 | case 'html': 86 | return ` 87 | ${style ? 'const StyledComponents = styled.div`' + style + '`' : ''} 88 | `+ ` 89 | ${script.match(/export\s+default[\n\s\S]+?class[\s\w]*|module.exports\s*=[\n\s\S]*?class\s*/g)[0]} ${templateComponentCamelCaseName} extends WeElement { 90 | render() { 91 | return (html${'`'}${template}${'`'}) 92 | } 93 | ` 94 | // jsx 95 | default: 96 | return ` 97 | ${style ? 'const StyledComponents = styled.div`' + style + '`' : ''} 98 | `+ ` 99 | ${script.match(/export\s+default[\n\s\S]+?class[\s\w]*|module.exports\s*=[\n\s\S]*?class\s*/g)[0]} ${templateComponentCamelCaseName} extends WeElement { 100 | render() { 101 | return ${template} 102 | } 103 | ` 104 | } 105 | // omi hoc 106 | default: 107 | switch (templateLang) { 108 | // html 109 | case 'html': 110 | hocScript = ` 111 | ${script.match(/export\s+default[\n\s\S]+?class[\s\w]*|module.exports\s*=[\n\s\S]*?class\s*/g)[0]} extends WeElement { 112 | render(props) { 113 | return (html${'`'}${template}${'`'}) 114 | } 115 | `.replace(/export\s+default([\n\s\S]+?class[\s\w]*)|module.exports(\s*=[\n\s\S]*?class\s*)/g, `const ${captain(convertToCamelCase(templateComponentName))} = $1$2`) 116 | // console.log(hocScript) 117 | return hocScript 118 | // jsx 119 | default: 120 | hocScript = ` 121 | ${script.match(/export\s+default[\n\s\S]+?class[\s\w]*|module.exports\s*=[\n\s\S]*?class\s*/g)[0]} extends WeElement { 122 | render(props) { 123 | return ${template} 124 | } 125 | `.replace(/export\s+default([\n\s\S]+?class[\s\w]*)|module.exports(\s*=[\n\s\S]*?class\s*)/g, `const ${captain(convertToCamelCase(templateComponentName))} = $1$2`) 126 | // console.log(hocScript) 127 | return hocScript 128 | } 129 | 130 | } 131 | } 132 | switch (isCaptain(templateComponentName)) { 133 | // react without static css 134 | case true: 135 | switch (templateLang) { 136 | // html 137 | case 'html': 138 | return ` 139 | ${style ? 'const StyledComponents = styled.div`' + style + '`;' : ''}` + 140 | `${componentName} class ${templateComponentCamelCaseName} extends WeElement { 141 | render() { 142 | return (html${'`'}${template}${'`'}) 143 | } 144 | ` 145 | // jsx 146 | default: 147 | return ` 148 | ${style ? 'const StyledComponents = styled.div`' + style + '`;' : ''}` + 149 | `${componentName} class ${templateComponentCamelCaseName} extends WeElement { 150 | render() { 151 | return ${template} 152 | } 153 | ` 154 | } 155 | // omi 156 | default: 157 | switch (templateLang) { 158 | // html 159 | case 'html': 160 | return ` 161 | ${componentName} class ${templateComponentCamelCaseName} extends WeElement { 162 | ${css} 163 | render(props) { 164 | return (html${'`'}${template}${'`'}) 165 | } 166 | ` 167 | // jsx 168 | default: 169 | return ` 170 | ${componentName} class ${templateComponentCamelCaseName} extends WeElement { 171 | ${css} 172 | render(props) { 173 | return ${template} 174 | } 175 | ` 176 | } 177 | } 178 | } -------------------------------------------------------------------------------- /docs/guide/public/menu/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | Omil 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 |
47 |
48 |
49 |
50 |
51 |

52 | Omil 53 |

54 | 89 |
90 | 91 | 92 |
93 | 94 |
95 |
96 |
97 | 110 | 111 |
112 | 113 |
114 | 128 | 129 | 130 | 146 | 147 |
148 |
149 |
150 | 151 |
152 | 166 | 167 | 168 | 184 | 185 |
186 | 187 | 188 |
189 | 190 | 191 | 192 |
193 | 194 | 195 | 196 |
197 |
198 | 199 |
200 |
201 |
202 |
203 |
204 | Expand all 205 | Back to top 206 | Go to bottom 207 |
208 |
209 | 210 | 257 |
258 |
259 |
260 |
261 | 262 | 263 | 264 | -------------------------------------------------------------------------------- /README.EN.md: -------------------------------------------------------------------------------- 1 | English | [简体中文](./README.CN.md) 2 | 3 | # Install 4 | 5 | > Webpack loader for Omi Single-File Components 6 | 7 | You can use [npm](https://www.npmjs.com/package/omil) install or [git](https://github.com/Wscats/omil) clone it. 8 | ```bash 9 | npm install omil --save-dev 10 | # or 11 | npm install eno-loader --save-dev 12 | ``` 13 | Configuration webpack file like this: 14 | ```js 15 | module: { 16 | rules: [{ 17 | test: /\.omi|eno$/, 18 | use: [{ 19 | loader: require.resolve('omil'), 20 | options: { 21 | // Use in development, You should remove in production 22 | sourceMaps: 'both', 23 | // Config babel plugins for async, await and other many features 24 | plugins: [ 25 | [ 26 | "@babel/plugin-transform-runtime", 27 | { 28 | "absoluteRuntime": false, 29 | "corejs": false, 30 | "helpers": true, 31 | "regenerator": true, 32 | "useESModules": false 33 | } 34 | ] 35 | ] 36 | } 37 | }], 38 | // Or you can use eno-loader or omil directly 39 | // use: ['eno-loader'] 40 | // use: ['omil'] 41 | }] 42 | } 43 | ``` 44 | > [Loader Demo](https://wscats.github.io/omil/dist) 45 | 46 | ## Why Omil Or Eno Loader? 47 | 48 | `omil` is a loader for [webpack](https://webpack.js.org/) that allows you to author Omi components in a format called Single-File Components. 49 | 50 | ## Usage In Omi 51 | 52 | A `*.omi` file is a custom file format that uses HTML-like syntax to describe a Omi component. Each `*.omi` file consists of three types of top-level language blocks: `