kbrsh/moon

use moon in browser

sadeghbarati opened this issue · 8 comments

hey @kbrsh I really need help

in a Project, I have to use the moon in browser
but actually I don't have any idea how to use it

there are two formats in moon can use it through the browser

  1. requirements ( moon and moon-browser )
<div id="root"></div>

<script type="text/moon">
  const paragraph = (<p>Hello {{ message }}</p>);
</script>
  1. requirements ( moon-mvl and idk )
<div id="root"></div>

<script type="text/mvl">
  <p>Hello {{ message }}</p>
</script>

I want to use format 2 but

Please explains Two ways
to how to use it in browser

and how to add moon-driver and moon.use to them

kbrsh commented

Format 2 is not supported anymore, and Moon's view language is just an extension of JavaScript instead. You can make a JavaScript file called index.js and link to it using moon-browser, and you will be able to use format 1 as usual.

<div id="root"></div>

<script type="text/moon" src="index.js"></script>

This change was made to better represent views as pure functions. The view language is just another syntax for function calls, and you can make functions that return these views as you described in format 1.

Let me know if I answered your question.

here my index.html file

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    
    <div id="root"></div>

    <script src="js/moon.min.js"></script>
    <script src="js/moon-browser.min.js"></script>

    <script type="text/moon" src="js/index.js"></script>
</body>
</html>

and index.js

const Todos = ({ data }) => (
    <for={todo} of={data.todos} name="ul">
        <li>{todo}</li>
    </for>
);

Moon.use({
    data: Moon.data.driver({
        todo: "",
        todos: [
            "Learn Moon",
            "Take a nap",
            "Go Shopping"
        ]
    }),
    view: Moon.view.driver("#root")
});

Moon.run(({ data }) => ({
    view: (<Todos data={data}/>)
}));

without localhost server i got this error in console

Access to XMLHttpRequest at 'file:///C:/Users/Sadegh/Desktop/moon/js/index.js' from origin 'null' 
has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: 
http, data, chrome, chrome-extension, https.

with localhost server i got this error

Uncaught TypeError: Moon.data.driver is not a function
    at <anonymous>:8:21
    at XMLHttpRequest.i.onload

all codes with moon-browser are compiled except Moon.data.driver

var m0,m1,m2,m3,m4,m5;const Todos = ({ data }) => (
    (function(){if(m3===undefined){m3=[];m4={};}m0=[];m1=function(todo){return Moon.view.m("li",m4,[Moon.view.m("text",{"":todo},m3)]);};for(m2=0;m2<data.todos.length;m2++){m0.push(m1(data.todos[m2],m2));}return Moon.view.m("ul",m4,m0);})()


);

Moon.use({
    data: Moon.data.driver({
        todo: "",
        todos: [
            "Learn Moon",
            "Take a nap",
            "Go Shopping"
        ]
    }),
    view: Moon.view.driver("#root")
});

Moon.run(({ data }) => ({
    view: ((function(){if(m5===undefined){m5=[];}return Todos({"data":data,children:m5});})())
}));

can u Accept PR for Documents you haven't noticed or u add it ?

  1. like u have to run moon-browser with localhost
  2. use new moon instead of mvl
  3. more example of single-file-components(cli template) and moon-browser
  4. update dataset, ariaset, style with events like click or others
const updateDataset = function(event) {
	this.dataset.foo = "baz" ?
        event.target.dataset.foo = "baz" ?
}
  1. if I have multiple pages and each page have special data like index.html, about.html, post.html, contact.html

Do I have to do this?

index.html

<script type="text/moon" src="index.js"></script>

index.js

const Index = ({ data }) => (
    <header>Same Header</header>
    <for={todo} of={data.todos} name="ul">
        <li>{todo}</li>
    </for>
    <footer>Same Footer</footer>
);

Moon.use({
    data: Moon.data.driver({
        todo: "",
        todos: [
            "Learn Moon",
            "Take a nap",
            "Go Shopping"
        ]
    }),
    view: Moon.view.driver("#root")
});

Moon.run(({ data }) => ({
    view: (<Index data={data}/>)
}));

post.html

<script type="text/moon" src="post.js"></script>

post.js

const Post = ({ data }) => (
    <header>Same Header</header>
    <for={post} of={posts} name="ul">
        <if {post.published}>
           <li>{post.title}, {post.content}</li>
        </if>
    </for>
    <footer>Same Footer</footer>
);

Moon.use({
    data: Moon.data.driver({
        post: "",
        posts: [
            {
                "title": "Post1",
                "content": "Content",
                "published": true
            }
        ]
    }),
    view: Moon.view.driver("#root")
});

Moon.run(({ data }) => ({
    view: (<Post data={data}/>)
}));

  1. if I had repetitive components like header and footer i have to include in js files ? can i use it before and after <div id="root"></div> ?

if u clarify documents no more annoying issues open again

kbrsh commented
  1. This is a given because moon-browser, or any script for that matter, cannot access the file system. It's a security risk.
  2. The old way is never mentioned in the documentation, only the new way.
  3. I'll definitely work on more examples once I get some more drivers done.
  4. This can be done by making an HTML attribute like dataset={foo} and then updating foo with the data driver in an @click event.
  5. Yes, you will have to do that. Each page is like a separate app, and if you want one then you'll have to build an SPA with routing.
  6. You can make a separate JS file defining Header and Footer components and use them. Ideally you would use JS modules and Moon CLI, and I'm curious — what is your use case that requires HTML files and Moon Browser? You could use Moon CLI and npm run build to get a completely static bundle.

I'm using VsCode LiveReload Extensions for running moon and moon-browser
but still, have this problem

VM63:8 Uncaught TypeError: Moon.data.driver is not a function
    at <anonymous>:8:18
    at XMLHttpRequest.i.onload (moon-browser.min.js:formatted:561)
(anonymous) @ VM63:8
i.onload @ moon-browser.min.js:formatted:561
load (async)
a @ moon-browser.min.js:formatted:556
(anonymous) @ moon-browser.min.js:formatted:573

NVM

this is deployed project with same code on the document

http://moon-browser.surge.sh/

go and check the console

kbrsh commented

You're not using the latest stable version of Moon — you're using the version from the master branch, which is unstable. If you want stable builds, download them from the releases, NPM, or a CDN.

How should I know that I should not use the new version?
worked with v1.0.0-beta.3

kbrsh commented

It works with beta 4 as well, the problem is that you're not using the latest beta. You're using the build directly from the master branch, which is unstable and undocumented. You'll need to download it directly from the releases, NPM, or a CDN like unpkg.