Comparing version 0.0.1 to 0.0.2
@@ -14,3 +14,3 @@ const manila = require('manila/parse'); | ||
return str.replace(/[&<>'"]/g, c => { | ||
return str.replace(/[<>'"]/g, c => { | ||
@@ -17,0 +17,0 @@ return escapeMap[c]; |
166
dist.js
@@ -1,165 +0,1 @@ | ||
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ | ||
'use strict'; | ||
var compile = require('./compile'); | ||
window.manila = window.manila || {}; | ||
window.manila.handlers = {}; | ||
var components = {}, | ||
selection = void 0; | ||
function component(componentName, component) { | ||
var vm = window.manila.data[componentName] || {}, | ||
el = document.querySelector('[data-component="' + componentName + '"]'); | ||
compile('#' + componentName + '-template').then(function (render) { | ||
function resolve(data) { | ||
var index = 0; | ||
window.manila.handlers[componentName] = []; | ||
data.on = function (event, handler) { | ||
for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) { | ||
args[_key - 2] = arguments[_key]; | ||
} | ||
var eventString = void 0; | ||
window.manila.handlers[componentName][index] = function (e) { | ||
e.stopPropagation(); | ||
args.push(e); | ||
handler.apply(data, args); | ||
if (e.target.tagName !== 'INPUT' && e.target.tagName !== 'TEXTAREA') { | ||
resolve(data); | ||
} | ||
}; | ||
eventString = 'on' + event + '=manila.handlers.' + componentName + '[' + index + '](event)'; | ||
index++; | ||
return eventString; | ||
}; | ||
el.innerHTML = render(data); | ||
} | ||
vm.render = function () { | ||
resolve(vm); | ||
}; | ||
var methods = component(vm); | ||
if (methods) { | ||
components[componentName] = {}; | ||
Object.keys(methods).forEach(function (key) { | ||
components[componentName][key] = function () { | ||
for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { | ||
args[_key2] = arguments[_key2]; | ||
} | ||
var result = methods[key].apply(vm, args); | ||
resolve(vm); | ||
return result; | ||
}; | ||
}); | ||
} | ||
resolve(vm); | ||
}); | ||
return window.manila; | ||
} | ||
window.manila.component = component; | ||
window.manila.components = components; | ||
module.exports = { | ||
component: component, | ||
components: components | ||
}; | ||
},{"./compile":2}],2:[function(require,module,exports){ | ||
'use strict'; | ||
var manila = require('manila/parse'); | ||
var cache = {}, | ||
escapeMap = { | ||
'<': '<', | ||
'>': '>', | ||
'"': '"', | ||
'\'': ''' | ||
}; | ||
function htmlEscape(str) { | ||
return str.replace(/[&<>'"]/g, function (c) { | ||
return escapeMap[c]; | ||
}); | ||
} | ||
window.manila = window.manila || {}; | ||
window.manila.e = function (val) { | ||
return typeof val === 'string' ? htmlEscape(val) : val; | ||
}; | ||
module.exports = function compile(selector) { | ||
return new Promise(function (resolve) { | ||
if (!selector) { | ||
resolve(function () {}); | ||
} else { | ||
if (cache[selector]) { | ||
resolve(cache[selector]); | ||
} | ||
cache[selector] = manila(document.querySelector(selector).innerHTML); | ||
resolve(cache[selector]); | ||
} | ||
}); | ||
}; | ||
},{"manila/parse":3}],3:[function(require,module,exports){ | ||
'use strict'; | ||
module.exports = function(template) { | ||
return new Function('context', | ||
"var p=[];with(context){p.push(`" + | ||
template | ||
.replace(/\\/g, "\\\\") | ||
.replace(/`/g, "\\`") | ||
.replace(/<::(?!\s*}.*?::>)(?!.*{\s*::>)(.*?)::>/g, "`);try{p.push($1)}catch(e){}p.push(`") | ||
.replace(/<::?(?!\s*}.*?::?>)(?!.*{\s*::?>)(.*?)::?>/g, "`);try{p.push(manila.e($1))}catch(e){}p.push(`") | ||
.replace(/<::?(.*?)::?>/g, "`);$1\np.push(`") | ||
+ "`);}return p.join('');"); | ||
}; | ||
},{}]},{},[1]); | ||
!function n(r,e,t){function a(i,u){if(!e[i]){if(!r[i]){var c="function"==typeof require&&require;if(!u&&c)return c(i,!0);if(o)return o(i,!0);var p=new Error("Cannot find module '"+i+"'");throw p.code="MODULE_NOT_FOUND",p}var s=e[i]={exports:{}};r[i][0].call(s.exports,function(n){var e=r[i][1][n];return a(e?e:n)},s,s.exports,n,r,e,t)}return e[i].exports}for(var o="function"==typeof require&&require,i=0;i<t.length;i++)a(t[i]);return a}({1:[function(n,r,e){"use strict";function t(n,r){var e=window.manila.data[n]||{},t=document.querySelector('[data-component="'+n+'"]');return a("#"+n+"-template").then(function(a){function i(r){var e=0;window.manila.handlers[n]=[],r.on=function(t,a){for(var o=arguments.length,u=Array(o>2?o-2:0),c=2;o>c;c++)u[c-2]=arguments[c];var p=void 0;return window.manila.handlers[n][e]=function(n){n.stopPropagation(),u.push(n),a.apply(r,u),"INPUT"!==n.target.tagName&&"TEXTAREA"!==n.target.tagName&&i(r)},p="on"+t+"=manila.handlers."+n+"["+e+"](event)",e++,p},t.innerHTML=a(r)}e.render=function(){i(e)};var u=r(e);u&&(o[n]={},Object.keys(u).forEach(function(r){o[n][r]=function(){for(var n=arguments.length,t=Array(n),a=0;n>a;a++)t[a]=arguments[a];var o=u[r].apply(e,t);return i(e),o}})),i(e)}),window.manila}var a=n("./compile");window.manila=window.manila||{},window.manila.handlers={};var o={};window.manila.component=t,window.manila.components=o,r.exports={component:t,components:o}},{"./compile":2}],2:[function(n,r,e){"use strict";function t(n){return n.replace(/[&<>'"]/g,function(n){return i[n]})}var a=n("manila/parse"),o={},i={"<":"<",">":">",'"':""","'":"'"};window.manila=window.manila||{},window.manila.e=function(n){return"string"==typeof n?t(n):n},r.exports=function(n){return new Promise(function(r){n?(o[n]&&r(o[n]),o[n]=a(document.querySelector(n).innerHTML),r(o[n])):r(function(){})})}},{"manila/parse":3}],3:[function(n,r,e){"use strict";r.exports=function(n){return new Function("context","var p=[];with(context){p.push(`"+n.replace(/\\/g,"\\\\").replace(/`/g,"\\`").replace(/<::(?!\s*}.*?::>)(?!.*{\s*::>)(.*?)::>/g,"`);try{p.push($1)}catch(e){}p.push(`").replace(/<::?(?!\s*}.*?::?>)(?!.*{\s*::?>)(.*?)::?>/g,"`);try{p.push(manila.e($1))}catch(e){}p.push(`").replace(/<::?(.*?)::?>/g,"`);$1\np.push(`")+"`);}return p.join('');")}},{}]},{},[1]); |
{ | ||
"name": "mnla", | ||
"version": "0.0.1", | ||
"version": "0.0.2", | ||
"description": "", | ||
@@ -8,2 +8,3 @@ "main": "mnla.js", | ||
"js": "browserify client.js -o dist.js -t [ babelify --presets [ es2015 ] ]", | ||
"build": "browserify client.js -o dist.js -t [ babelify --presets [ es2015 ] ] && uglifyjs dist.js --compress --mangle --screw-ie8 --output dist.js", | ||
"watch": "npm-watch" | ||
@@ -28,4 +29,5 @@ }, | ||
"babelify": "^7.2.0", | ||
"npm-watch": "^0.1.4" | ||
"npm-watch": "^0.1.4", | ||
"uglify-js": "^2.6.2" | ||
} | ||
} |
# MNLA | ||
MNLA is a wrapper for the [Manila](https://github.com/mgrahamjo/manila) template engine. It allows you to bind your server-side Manila templates to client side components, re-rendering the templates when the underlying data model changes. | ||
MNLA is a wrapper for the [Manila](https://github.com/mgrahamjo/manila) template engine that provides universal (isomorphic) rendering and client-side data binding. It adds only 2.5KB of client-side code and 2KB of server-side code on top of the Manila template engine, which is 4KB of server-side code. | ||
@@ -15,2 +15,8 @@ ## Installation | ||
You can demo the Hello World yourself: | ||
``` | ||
git clone https://github.com/mgrahamjo/mnla && cd mnla/hello-world && npm install && node index | ||
``` | ||
### Server side: | ||
@@ -27,17 +33,25 @@ | ||
.use(express.static('assets')) | ||
.use('/assets', express.static('assets')) | ||
// If you aren't using a bundler like Browserify, | ||
// make a static route for the MNLA source code: | ||
.use('/node_modules/mnla', express.static('node_modules/mnla')) | ||
// add a static route for the MNLA source code: | ||
.use(express.static('node_modules/mnla')) | ||
// Tell Express to use the MNLA template engine: | ||
.engine('mnla', mnla) | ||
.set('view engine', 'mnla') | ||
.set('views', './views') | ||
// Set up some routes: | ||
.get('/', require('./controllers/index')) | ||
.get('/message', require('./controllers/message')); // JSON endpoint | ||
.get('/message', require('./controllers/message')) // JSON endpoint | ||
// Start the app | ||
.listen(1337, () => { | ||
console.log('Listening on localhost:1337'); | ||
}); | ||
``` | ||
app.listen(1337, () => { | ||
console.log('Listening on localhost:1337'); | ||
}); | ||
```javascript | ||
// controllers/message.js | ||
// Here is a controller for the json endpoint /message. | ||
module.exports = (req, res) => { | ||
res.json({ | ||
message: "hello, world!" | ||
}); | ||
}; | ||
``` | ||
@@ -47,6 +61,3 @@ | ||
// controllers/index.js | ||
const | ||
manila = require('mnla/server'), | ||
// message is the controller for a JSON endpoint | ||
message = require('./message'); | ||
const manila = require('mnla/server'); | ||
@@ -56,6 +67,13 @@ module.exports = (req, res) => { | ||
// Here we define our component names and underlying data sources: | ||
message: message, | ||
input: message | ||
// You can pass a json endpoint as a data source: | ||
message: require('./message'), | ||
// Or you can pass raw data: | ||
input: { | ||
message: "hello, world!" | ||
}, | ||
// If you wanted to set up a client-side component | ||
// that isn't rendered on the server side, you would pass null | ||
// clientComponent: null | ||
}, | ||
// Don't forget to pass req and res to component controllers: | ||
// Don't forget to pass req and res (the 'message' controller we included expects them) | ||
req, res) | ||
@@ -68,14 +86,5 @@ .then(templateData => { | ||
```javascript | ||
// controllers/message.js | ||
// component controllers | ||
module.exports = (req, res) => { | ||
res.json({ | ||
message: "hello, world!" | ||
}); | ||
}; | ||
``` | ||
```html | ||
<!-- views/message.mnla --> | ||
<!-- This is the template for the message component --> | ||
<h1><:message:></h1> | ||
@@ -86,2 +95,3 @@ ``` | ||
<!-- views/input.mnla --> | ||
<!-- This is the template for the input component --> | ||
<!-- 'on' is a special method that you can use to listen to DOM events. --> | ||
@@ -107,4 +117,4 @@ <!-- 'updateMessage' is a custom handler that we'll define in a client side script. --> | ||
<!-- and don't forget your client side scripts: --> | ||
<script src="/node_modules/mnla/dist.js"></script> | ||
<script src="/assets/js/app.js"></script> | ||
<script src="/dist.js"></script> <!-- this is from the node_modules/mnla folder --> | ||
<script src="/js/app.js"></script> <!-- this is from the assets folder --> | ||
</body> | ||
@@ -120,4 +130,6 @@ </html> | ||
.component('message', vm => { | ||
// Add methods and properties to vm (view model) here. | ||
// Return an object with methods that can be called by other components | ||
// When this runs, vm (view model) is already populated with the properties | ||
// that the 'message' controller set on the server side. | ||
// You can add additional methods and properties to vm here. | ||
// Return an object with methods that can be called by other components. | ||
return { | ||
@@ -130,6 +142,5 @@ update: message => { | ||
.component('input', vm => { | ||
// Here we define the updateMessage method we used in the template. | ||
// Here we define the updateMessage method we used in the template as an event listener. | ||
vm.updateMessage = event => { | ||
// Inform the message component of the new value | ||
// using the 'update' method we created | ||
// Inform the message component of the new value using the 'update' method we created. | ||
manila.components.message.update(event.target.value); | ||
@@ -139,1 +150,3 @@ }; | ||
``` | ||
Now you can run `node index`, and open up http://localhost:1337. The html is populated with the "hello, world!" message even before the client side javascript runs, and it stays up-to-date as you update the input. |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
143
11496
4
130
3