Giter Club home page Giter Club logo

documentation's Introduction

documentation's People

Contributors

anishkny avatar barake avatar brad avatar calebpaul avatar chinitadelrey avatar clsource avatar cpg avatar darenr avatar elithecho avatar gliechtenstein avatar gtramontina avatar lukeramsden avatar maks avatar moagggi avatar pborreli avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

documentation's Issues

Call JS functions inside web containers from the parent app

This is the opposite of #66

Currently if you want to dynamically update contents inside a web container, you have to re-render the whole view.

But the nice thing about web containers is it's a completely isolated environment from the outside world, so if we can simply send a message to the container it can update on its own without us re-rendering the entire view.

map

Map component leaves a blank field and no map is loaded.

Edit: Didn't set api code, but now i have changed it the frame appears with "google" in the corner but now map is showing.

Support YAML

YAML is a terser format than JSON, and JSON is a subset of YAML; that is, valid JSON is also valid YAML, so there would be no backward compatibility issues.

For example, converting https://imagejason.herokuapp.com yields the document below. Some might find this format preferable.

---
"$jason":
  head:
    title: image sample
    data:
      db:
      - _id: 58a63ebabb7fa20400ab5b9d
        url: https://s3-us-west-2.amazonaws.com/fm.ethan.jason/223FAE7F-6025-470D-8367-7E7EB6434B08.jpeg
        __v: 0
      - _id: 58a408b246c81004001fbc7f
        url: https://s3-us-west-2.amazonaws.com/fm.ethan.jason/3C0FFB05-3B6B-4F46-A084-6CF74C465410.jpeg
        __v: 0
      - _id: 5888b9986029e204008ee021
        url: https://s3-us-west-2.amazonaws.com/fm.ethan.jason/095DFFE3-8BEE-4683-A5EE-6CC607AA094D.jpeg
        __v: 0
      - _id: 588795f6ee17f50400cefd1e
        url: https://s3-us-west-2.amazonaws.com/fm.ethan.jason/1119278C-8C49-45D2-B402-1E8BA9753E2E.jpeg
        __v: 0
      - _id: 587b07c3b58c750400eeb978
        url: https://s3-us-west-2.amazonaws.com/fm.ethan.jason/D7D03190-88F3-429B-9F6D-0E710B87681A.jpeg
        __v: 0
      - _id: 587b0765b58c750400eeb977
        url: https://s3-us-west-2.amazonaws.com/fm.ethan.jason/0C78B00B-7613-4973-8EC9-F5F681B03948.jpeg
        __v: 0
      - _id: 586f1f8f7da7450400c0aaea
        url: https://s3-us-west-2.amazonaws.com/fm.ethan.jason/7DAA7B7F-63FF-40FF-94A3-925FF5909C4C.jpeg
        __v: 0
      - _id: 586dc151424b2a0400c157e5
        url: https://s3-us-west-2.amazonaws.com/fm.ethan.jason/0D674AC2-8EB8-4FF8-9441-F6C3FD796A3D.jpeg
        __v: 0
      - _id: 586dbbf7424b2a0400c157e4
        url: https://s3-us-west-2.amazonaws.com/fm.ethan.jason/06538FBF-8150-491E-AD4D-A3D86008FA5A.jpeg
        __v: 0
      - _id: 586bf598d928ff04009cf0f5
        url: https://s3-us-west-2.amazonaws.com/fm.ethan.jason/FB201FED-ECDF-4E9D-B64F-131A0FF3A956.jpeg
        __v: 0
      - _id: 5867543679eb6b0400a34e1b
        url: https://s3-us-west-2.amazonaws.com/fm.ethan.jason/6EA56BBE-36BB-4583-8EBA-754DFB75820A.jpeg
        __v: 0
      - _id: 58572ebf2915d60400f0e020
        url: https://s3-us-west-2.amazonaws.com/fm.ethan.jason/14C6F89B-D220-4490-8710-F85A9CAA130E.jpeg
        __v: 0
      - _id: 5853855f4c24b70400ac4ac3
        url: https://s3-us-west-2.amazonaws.com/fm.ethan.jason/E043A6EF-2247-4D17-A63A-8625A3DDE623.jpeg
        __v: 0
      - _id: 584dfbe3a38e9304003fe34a
        url: https://s3-us-west-2.amazonaws.com/fm.ethan.jason/6D860BE2-202A-4471-B115-02FDE24DBAE9.jpeg
        __v: 0
      - _id: 583ad05e2ade400400cade37
        url: https://s3-us-west-2.amazonaws.com/fm.ethan.jason/B6332326-9C4B-4878-B908-EE7C74A6BC89.jpeg
        __v: 0
      - _id: 5837bbbc3e351a040000f256
        url: https://s3-us-west-2.amazonaws.com/fm.ethan.jason/353399FF-5658-4C4B-87DE-4E57F77F8E11.jpeg
        __v: 0
      - _id: 5837bb993e351a040000f255
        url: https://s3-us-west-2.amazonaws.com/fm.ethan.jason/291C2C62-6DBC-401D-A04A-F83E81DC5C89.jpeg
        __v: 0
      - _id: 582f74ae7d5cbc0400353651
        url: https://s3-us-west-2.amazonaws.com/fm.ethan.jason/52D80F3E-F155-43F3-A1A9-0EECA5B3E92B.jpeg
        __v: 0
      - _id: 582a7c29943e050400369d78
        url: https://s3-us-west-2.amazonaws.com/fm.ethan.jason/6D38F3DE-15DC-40E8-BFC4-665E567DB650.jpeg
        __v: 0
      - _id: 5828ee24ecbbb90400f719d7
        url: https://s3-us-west-2.amazonaws.com/fm.ethan.jason/EF149342-E05D-4B32-94A6-4EB840527984.jpeg
        __v: 0
      - _id: 582237369eb108040063173d
        url: https://s3-us-west-2.amazonaws.com/fm.ethan.jason/5771CEA9-F1DD-4502-8671-5EEFE85C7504.jpeg
        __v: 0
      - _id: 5821fb7b802f060300c0a337
        url: https://s3-us-west-2.amazonaws.com/fm.ethan.jason/ECEB2B7B-B8F9-404C-BADF-3C9AE59763F8.jpeg
        __v: 0
      - _id: 5821d01848751c03007bda8b
        url: https://s3-us-west-2.amazonaws.com/fm.ethan.jason/BB43115A-C3FA-4CD6-89BD-214ACD5DF8A2.jpeg
        __v: 0
      - _id: 5821cffc48751c03007bda8a
        url: https://s3-us-west-2.amazonaws.com/fm.ethan.jason/FCA699B4-C750-4F1C-B812-5C083E8C78B0.jpeg
        __v: 0
      - _id: 5821a039881ec5030008c3ea
        url: https://s3-us-west-2.amazonaws.com/fm.ethan.jason/CF60C612-66D6-43A2-9D56-6A708BECAFC2.jpeg
        __v: 0
      - _id: 582160f1b364ab0300ffe4e2
        url: https://s3-us-west-2.amazonaws.com/fm.ethan.jason/BD71DDA7-9F3B-4A3C-9DC5-A9D1D2603CFD.jpeg
        __v: 0
      - _id: 5820c2963bc8e703007433a0
        url: https://s3-us-west-2.amazonaws.com/fm.ethan.jason/F04BCB1B-60D8-42EB-835E-3D20B58B9340.jpeg
        __v: 0
      - _id: 581ff3af8d42060300c834dd
        url: https://s3-us-west-2.amazonaws.com/fm.ethan.jason/4766FA79-8908-4561-899B-E0FFE097FC40.jpeg
        __v: 0
      - _id: 581feae8d6e05303005f920b
        url: https://s3-us-west-2.amazonaws.com/fm.ethan.jason/6F30F374-AD8A-46CD-B02E-D88350ED0F5D.jpeg
        __v: 0
      - _id: 581f638494f6b30300a371fe
        url: https://s3-us-west-2.amazonaws.com/fm.ethan.jason/7662CB2F-822D-4EB7-8ECA-13EBE22E07B8.jpeg
        __v: 0
      - _id: 580f0c0f99c71a0300137a40
        url: https://s3-us-west-2.amazonaws.com/fm.ethan.jason/9504C536-7352-4C0D-BDB5-A7564D36F282.jpeg
        __v: 0
      - _id: 5806b9e1c9803f0300800ea4
        url: https://s3-us-west-2.amazonaws.com/fm.ethan.jason/BF2F5DD1-B929-4BBB-893F-6DBF3130C00D.jpeg
        __v: 0
      - _id: 57fef2e8a7d9ac0300a3203e
        url: https://s3-us-west-2.amazonaws.com/fm.ethan.jason/A5BFD3AC-A4D3-4DBC-B4FB-22CBBA7CE500.jpeg
        __v: 0
      - _id: 57f684aa2838180300e2fc35
        url: https://s3-us-west-2.amazonaws.com/fm.ethan.jason/037D6539-CCCA-4F8F-AC47-117796D3C3D6.jpeg
        __v: 0
      - _id: 57ead0601e3bfb03002fea15
        url: https://s3-us-west-2.amazonaws.com/fm.ethan.jason/F4425082-5E76-47E2-B7E7-8EDABB9BD73F.jpeg
        __v: 0
      - _id: 57bf5a85d4ed5103002b712a
        url: https://s3-us-west-2.amazonaws.com/fm.ethan.jason/DEEFCD96-CAF0-4529-A896-CC14BB34E443.jpeg
        __v: 0
      - _id: 57bc81d7d58e2f03005573b8
        url: https://s3-us-west-2.amazonaws.com/fm.ethan.jason/4BBFB817-93F1-474E-A179-B0462BB68016.jpeg
        __v: 0
      - _id: 57bb715ca56d200300df67c9
        url: https://s3-us-west-2.amazonaws.com/fm.ethan.jason/D3BDA263-BAB1-4114-89A5-8CB8B1F76020.jpeg
        __v: 0
      - _id: 57bb70d8a67a2703007b4053
        url: https://s3-us-west-2.amazonaws.com/fm.ethan.jason/4449D16F-D4B6-4868-BD56-8E217AC85756.jpeg
        __v: 0
      - _id: 576f8d1521deda0300f370e5
        url: https://s3-us-west-2.amazonaws.com/fm.ethan.jason/BA46A4BA-C113-430C-BDA3-412AF6398C43.jpeg
        __v: 0
      - _id: 576f8d0121deda0300f370e4
        url: https://s3-us-west-2.amazonaws.com/fm.ethan.jason/EDAF76DF-5428-4E9E-998B-7CF2200D51B8.jpeg
        __v: 0
      - _id: 573696c686be6003009f7621
        url: https://s3-us-west-2.amazonaws.com/fm.ethan.jason/FDE039DA-8178-4EB5-81AC-57651F57D333.jpeg
        __v: 0
      - _id: 573695b586be6003009f7620
        url: https://s3-us-west-2.amazonaws.com/fm.ethan.jason/F907B98F-72D2-4F76-A9D1-4BC849AE95B4.jpeg
        __v: 0
      - _id: 5736918186be6003009f761f
        url: https://s3-us-west-2.amazonaws.com/fm.ethan.jason/C80C0D52-8ABB-4556-AB34-FB16BC2D45B8.jpeg
        __v: 0
      - _id: 573690f686be6003009f761e
        url: https://s3-us-west-2.amazonaws.com/fm.ethan.jason/7C7222B0-2EB4-47B3-A721-1B77C78C6BC8.jpeg
        __v: 0
      - _id: 573690a986be6003009f761d
        url: https://s3-us-west-2.amazonaws.com/fm.ethan.jason/4981B329-62CB-466F-9F1B-569BDE5060E1.jpeg
        __v: 0
      - _id: 571a4ebe44096303002092f4
        url: https://s3-us-west-2.amazonaws.com/fm.ethan.jason/CD8D15B0-978A-4823-A687-F048EA728257.jpeg
        __v: 0
      - _id: 571a4e9144096303002092f3
        url: https://s3-us-west-2.amazonaws.com/fm.ethan.jason/45C8A405-FD8E-4574-B155-3B84BD902B5E.jpeg
        __v: 0
      - _id: 5719a2cd6bb4cc03002f5bbf
        url: https://s3-us-west-2.amazonaws.com/fm.ethan.jason/6693C2F6-8830-41ED-8B7D-49CB22FE1E01.jpeg
        __v: 0
      - _id: 5719907f1aa0f80300c55277
        url: https://s3-us-west-2.amazonaws.com/fm.ethan.jason/5F6CD831-3F6A-4F81-90B1-4BE744EC73EA.jpeg
        __v: 0
      - _id: 571982bd0eb36403003c681f
        url: https://s3-us-west-2.amazonaws.com/fm.ethan.jason/C4B3C0D9-1D7A-4F76-9F13-C4E549A8179E.jpeg
        __v: 0
      - _id: 571978ca414fc203003d8c3b
        url: https://s3-us-west-2.amazonaws.com/fm.ethan.jason/842AC9A6-308C-4777-8014-B1A3DDF0F69F.jpeg
        __v: 0
      - _id: 5719761e414fc203003d8c3a
        url: https://s3-us-west-2.amazonaws.com/fm.ethan.jason/3F1A0FFC-3A9A-4651-84F0-4D0BE0D5CAB7.jpeg
        __v: 0
      - _id: 571975079bb7260300cb1884
        url: https://s3-us-west-2.amazonaws.com/fm.ethan.jason/D2FAE975-2BB6-4077-8762-ECA703902914.jpeg
        __v: 0
      - _id: 571971ae0707630300a0c04b
        url: https://s3-us-west-2.amazonaws.com/fm.ethan.jason/B079FA13-373D-4F00-B948-3DF95457B376.jpeg
        __v: 0
      - _id: 5719514128437b0300833f5e
        url: https://s3-us-west-2.amazonaws.com/fm.ethan.jason/A6FBD9B2-AEDC-49C7-8A35-820A62C6309F.jpeg
        __v: 0
      - _id: 5719512628437b0300833f5d
        url: https://s3-us-west-2.amazonaws.com/fm.ethan.jason/2A5928B5-A1E7-4256-B012-1C871A779842.jpeg
        __v: 0
    actions:
      "$load":
        type: "$set"
        options:
          selected: ''
        success:
          type: "$render"
      "$pull":
        type: "$media.camera"
        options:
          quality: '0.4'
        success:
          type: "$network.upload"
          options:
            type: s3
            bucket: fm.ethan.jason
            data: "{{$jason.data}}"
            content_type: "{{$jason.content_type}}"
            path: ''
            sign_url: https://imagejason.herokuapp.com/sign_url
          success:
            type: "$network.request"
            options:
              url: https://imagejason.herokuapp.com/post
              method: post
              data:
                bucket: fm.ethan.jason
                path: "/"
                filename: "{{$jason.filename}}"
            success:
              type: "$reload"
    templates:
      body:
        style:
          border: none
        header:
          menu:
            text: View Full Source
            href:
              url: https://github.com/Jasonette/s3-upload-example/blob/master/app.js
              view: web
        sections:
        - style:
            spacing: '0'
            padding: '0'
          header:
            type: vertical
            style:
              align: center
              padding: '20'
              z_index: "-1"
            components:
            - type: image
              url: https://d30y9cdsu7xlg0.cloudfront.net/png/126349-200.png
              style:
                z_index: "-1"
                width: '100'
          items:
          - "{{#if db && db.length > 0}}":
              "{{#each db}}":
                type: image
                style:
                  width: 100%
                  padding: '0'
                url: "{{url}}"
          - "{{#else}}": []

Android: Badge in the header is not showed

I'm trying the following full code on Android 7, using Jason:

{
  "$jason": {
    "head": {
      "title": "Hello world",
      "descriptions": "Badge in the header not working",
      "icon": "https://s3.amazonaws.com/jasonclient/hello.png"
    },
    "body": {
      "header": {
        "title": "This is the title",
        "menu": {
          "text": "Tap",
          "style": {
            "color": "#0000ff",
            "font": "HelveticaNeue-Bold",
            "size": "17"
          },
          "action": {
            "type": "$util.toast",
            "options": {
              "text": "Good job!"
            }
          },
          "badge": {
            "text": "3",
            "style": {
              "background": "#ff0000",
              "color": "#ffffff",
              "top": 10,
              "left": 20
            }
          }
        }
      }
    }
  }
}

I see the header, with the title, and the Tap menu. Even the action is working, but the badge is NOT visible at all. I tried even without/changing top/left attributes

Register a media-type with IANA

Hey everyone,

Here's something I've been willing to bring up but am just taking the time write now…

It is my understanding that Jasonette understands a very specific json format called Jason, correct?

Assuming the above is true, what do you think about registering a media type with IANA? I'll list down some name options that come to mind as examples of what I mean and then I'll expand of the benefits of having a registered media type.

  • application/vnd.jason+json (this would be my preference given the format name is Jason)
  • application/vnd.jasonette+json (kinda weird as jasonette is the name of the "browser", not the format)

There's a concept called content negotiation, where client and server can exchange information using the Accept and Content-Type headers to communicate, respectively, what the client is able to understand (preferred format) and what the server responded with. This way we can have a single entry point into our systems, for example https://example.com, and serve different representations when possible. A normal web browser would hit the above URL with Accept=text/html and we can simply respond with an HTML representation of requested resource. Jasonette would hit it with Accept=application/vnd.jason+json and we can simply respond with a Jason representation of that same resource.

Using application/json on its own does provide any clues about format semantics. A media type, like application/vnd.jason+json tells clients that they can use a JSON parser (+json) to read the contents and, together with vnd.jason, use the dictionary (meaning) defined by the Jason format. Here's a somewhat recent Hacker News thread on the subject regarding a new json-based format someone created (quite lengthy though).

On the client side, for example, Jasonette could implement (handle) different media types besides Jason, just like regular web browsers do when you follow a image/png resource, or even a video/mp4 resource by understanding the Content-Type and running the appropriate parser/renderer.

Hope we can get a conversation started and move this forward!

Component ratio support

There are several places where we can optimize to make Jasonette scroll smoothly.

One of those cases is handling component dimension. To understand why this is so, I need to discuss how this is implemented internally. You can skip this part and jump to the next "proposal" section if you're just curious about the proposed solution.

1. How app layout works

How Jasonette handles layout

All mobile devices implement some sort of "autolayout" features (both iOS and Android). This makes sure components without a dimension attribute will be automatically resized to "just work".

But sometimes the autolayout feature gets confused how exactly to lay them out. This is especially the case when you're loading an image. If you don't set the width and height directly on the image, Jasonette will try to figure it out AFTER the image has loaded by looking at the image file itself.

This normally does a good job but in some cases this resolution is visible and that's what makes it feel "jerky" when scrolling. Currently you can get around this if you use fixed width and height (must set both width and height)

How most native apps handle layout

Also note that this is not a "native vs. non-native" problem. Just take a look at a google search page for https://www.google.com/search?q=ios+scroll+jerky&oq=ios+scroll+&aqs=chrome.0.69i59j69i57j0l4.16386j0j7&sourceid=chrome&ie=UTF-8#q=ios+scroll+stutter This is a very common problem even among native ios developers.

And this is why a lot of apps have uniform components (Instagram used to only allow square images and many apps have fixed media sizes just to not worry about all the complexity that arise by allowing variable component sizes).

And even the apps that do have variable component sizes have to work hard to implement custom optimization logic for their apps. While difficult this is possible if you have a specific business logic because you can build your optimization logic around this assumption.

But the goal of Jasonette is to try to come up with a reusable approach to handling these things, so the optimization needs to be universal and shouldn't depend on a specific business logic.

2. Proposal

We can get around a lot of layout performance issues by:

  1. having a uniform component size
  2. setting the width and height manually

But in many cases we want to have variable sized components AND make it work. Like I mentioned in the previous section, this is not an easy task and there is no silver bullet approach to solving this in one fell swoop, so I think the best approach is to keep improving the most obvious use cases.

One such case is components where we know:

  1. at least either the width or the height
  2. the ratio of width vs. height

Here are some examples:

An image with width of 30% and height that's twice the size of the width:

{
  "type": "image",
  "url": "http://...",
  "style": {
    "width": "30%",
    "ratio": "2"
  }
}

An image with width of 100 and height that's half the size of the width:

{
  "type": "image",
  "url": "http://...",
  "style": {
    "width": "100",
    "ratio": "0.5"
  }
}

Because of the way components are implemented I think we can apply this not just to images but all components, which would improve the performance for this specific case.

If you have better ideas about the JSON syntax, or any other ideas, feel free to share.

MkDocs automation

This repo uses Mkdocs to generate the end-result on github pages, therefore need to run mkdocs gh-deploy --clean every time a change is made on the master branch.

I didn't look into this but maybe there's a simple way to automate the build process?

Documentation for image type button

Buttons used to be text only, for example:

{
  "type": "button",
  "text": "Press"
}

As of today, both Android (it was already working this way from the beginning unofficially, just haven't been documented) and iOS (via Jasonette/JASONETTE-iOS#94) support image type buttons. The JSON markup looks like:

{
  "type": "button",
  "url": "https://jasonette.github.io/Jasonpedia/assets/0.png"
}

A test case for image buttons on Jasonpedia: https://github.com/Jasonette/Jasonpedia/blob/gh-pages/view/component/button/3.json

javascript in actions

In line with the "post offline" question, what's the recommended way to write actions involving client-side JS?

Something simple, like "add message to recently posted messages list".

Document $oauth

There's a huge chunk of code at JasonOauthAction.m that's not documented.

It's one of the most powerful features of Jasonette and needs to be documented.

Need to decide on the box-sizing policy

Some of the dimensions are not consistent on iOS and Android.

Basically the same problem as CSS box-sizing property.

For example when you set width: 100%, on Android it actually sets the width to full 100%, which means it will go out of bounds if there's a padding involved, but on iOS the OS makes sure the elements don't go out of bound, so setting width: 100% is almost like saying max-width: 100%.

Currently a way around this problem is to not use width: 100% and rely on autosizing.

But this does need to be addressed and we need to come up with a consistent policy.

Accepting suggestions for the loading indicator attribute name

Here's a pull request by @wajahatch888 waiting to be merged for a loading indicator: Jasonette/JASONETTE-iOS#87

I've tried it and it works awesome. One thing I want to make sure is we name this attribute the best way possible. So far we're calling it loading, which looks like this:

For href

{
  "type": "label",
  "text": "Go",
  "href": {
    "url": "https://....",
    "loading": "true"
  }
}

For $network.request

{
  "type": "$network.request",
  "options": {
    "url": "https://...."
    "loading": "true"
  }
}

The question is: Can we come up with a better naming than loading?

Please feel free to share ideas if anyone has a better name suggestion for this attribute. Thanks!

#each with index

currently #each doesn't support index so if you need to use an index inside the loop you need to do some convoluted Javascript magic. Would be nice if we could do something like:

{
  "{{#each $jason}}": {
    "type": "label",
    "text": "{{$index}}"
  }
}

Or maybe there's a better syntax.

Keyboard type

Just like HTML has multiple input types, support multiple input types for the keyboard when textfield or textarea is focused.

This feature will be triggered by supporting an additional attribute called keyboard (tentative) to textarea and textfield components. Example:

{
  "type": "textfield",
  "name": "phone_num",
  "keyboard": "phone"
}

For starters I think the following will be enough:

  • text (default)
  • number
  • phone
  • email
  • url

But any suggestion is welcome, including the attribute name.

Document where actions can or cannot be attached to respond to touch

Need to add the following to the documentation somewhere :


action can be attached to various UI elements to respond to touch, but not all.

CAN be attached to:

  1. menu - $jason.body.header.menu
  2. tabs - $jason.body.footer.tabs
  3. footer input - $jason.body.footer.input.left and $jason.body.footer.input.right
  4. Top level of a section item - Example: $body.sections[0].items[0]
  5. Layer item - Example - $body.layers[0].items[0]
  6. Button component - Normally you need to attach actions at at the item level as described above. But if you want to attach an action at a component level, you can use "type": "button.

CANNOT be attached to:

CANNOT attach to a label or image component unless it's at item level - For example this doesn't work because the action is not attached to item level, which in this case would be "type": "vertical":

{
  "items": [{
    "type": "vertical",
    "components": [{
      "type": "label",
      "text": "touch me",
      "action": { ... } 
    }]
  }]
}

Exception - You can attach to a label when the label is the top level item

{
  "items": [{
    "type": "label",
    "text": "touch me",
    "action": { ... } 
  }]
}

If you really want to attach an action to a component, use buttons, like this:

{
  "items": [{
    "type": "vertical",
    "components": [{
      "type": "image",
      "url": "https://.....",
      "action": { ... } 
    }]
  }]
}

Feedback needed - New feature for the template engine.

A few days ago I pushed a new feature for the template engine which fixes one of the most annoying problems people have been facing.

Problem

For example here's a problematic situation:

{
  "{{#each $jason.posts}}": {
    "type": "vertical",
    "components": [{
      "type": "label",
      "text": "{{content}}"
    }, {
      "type": "label",
      "text": "{{$jason.username}}"
    }]
  }
}

This looks like it should work but it DOES NOT work.

More specifically, the {{$jason.username}} part doesn't work.

That's because it's inside the context of $jason.posts loop. When you think you're accessing $jason.username, you would be actually accessing $jason.posts[0].$jason.username, $jason.posts[1].$jason.username,etc.

Solution

We cannot use above markup because it's ambiguous what you're trying to do. After all, you may actually have an attribute called $jason under one of the post items, and may indeed be trying to access $jason.posts[0].$jason.username!

To handle this without ambiguity we need a way to access the root scope from inside the loop. And that's what this new feature does--it lets you access the root context using the keyword $root. Here's the updated JSON, which WILL work in the latest develop branch.

{
  "{{#each $jason.posts}}": {
    "type": "vertical",
    "components": [{
      "type": "label",
      "text": "{{content}}"
    }, {
      "type": "label",
      "text": "{{$root.$jason.username}}"
    }]
  }
}

Since $root functions as the gateway to access the root context, this means you can access not just $jason but any other variables like $cache or $get this way. Here's an example:

{
  "{{#each $jason.posts}}": {
    "type": "vertical",
    "components": [{
      "type": "label",
      "text": "{{content}}"
    }, {
      "type": "label",
      "text": "{{$root.$get.some_local_variable}}"
    }]
  }
}

Discussion

I haven't made this official so looking for any suggestions on the naming (Right now it's $root), or if you have a better idea on how to handle this problem, or any feedback, please feel free to share.

p.s.
BTW I do plan on open sourcing this JS in the future as well.

Clarify inline action vs regsitry based trigger gotcha

In most cases, defining actions under $jason.head.actions and calling them via trigger is recommended.

This is because if we ever happen to pass around dynamic arguments, these template expressions may get instantiated on view render and will baked into the view.

For example, in the following case we want to display an alert with the local variable val at the time of user tap.

{
  "type": "label",
  "text": "push",
  "action": {
    "type": "$util.alert",
    "options": {
        "title": "value",
        "description": "{{$get.val}}"
    }
  }
}

However what actually happens is: this will get rendered at load time with the val value at the time of render. Then this action is not dynamic anymore because all its arguments have been instantiated. This is why it's recommended that you put all actions under head.actions so that these don't get instantiated at view render.

But this point can be confusing for people new to the framework.

So this issue is for figuring out how to deal with this problem. Could be through better documentation, could be through some sort of warning messages, something else, or all of the above.

Add connection type to $env

We could detect if it's wifi or 3g or lte, etc. and render completely different versions of an app if we wanted. Just need to add another attribute to $env

Document image type button

People try to attach "action" to images. Perhaps we will support this in the future, but for now only button components can support actions.

However buttons can be a label type or an image type, so you can just use button to display interactive images. This needs to be documented

header option for $network.request action not working

{ "type": "$network.request", "options": { "url": "http://www.jasonbase.com/messages.json", "method": "post", "data": { "user_id": "fI9", "message": "Hello there" }, "header": { "auth_token": "fnekfla98dls9sNFK0nf3" } }, "success": { "type": "$render" }, "error": { "type": "$util.alert", "options": { "title": "Error", "description": "Uh oh, something went wrong" } } }

In the previous code, if we pass header with this request, it doesnot add header.
Android File: JasonNetworkAction, header option condition is not handelled.

can i do pull request to patch this issue?

Public component directory

Implement some way to share components with the community (probably as mixins)

Could be built on top of Jasonbase or can be a separate thing.

Discussion - Relative URL support

@brad came up with a great feature that takes care of relative URLs. Here's the PR: Jasonette/JASONETTE-Android#35

The solution basically:

  1. Looks at the url attribute of the strings.xml (The same url used for the root url of the app itself)
  2. Use that as the root url with which all the relative URLs in the app will be resolved.

So for example, if the app's root URL is https://www.jasonbase.com/things/nfk.json, you would be able to specify just the relative path throughout the app like this:

{
  "type": "image",
  "url": "/avatar.png"
}

I like the idea of being able to make the URLs domain independent, which would make the JSON code much more reusable and powerful.

I have a couple of thoughts on this, and also wanted to put this out there for public discussion before we make any decision.

Discussion 1. one root_url per view?

Maybe we can make this more flexible by stating the root url inside the JSON instead of using the hardcoded value from strings.xml? That way instead of having a single global root_url, we can namespace them per view. Also it's 100% powered by the JSON instead of hardcoded values. Here's an example:

{
  "$jason": {
    "head": {
      "root_url": "https://www.jasonbase.com/things",
      "title": "relative path demo",
      ...
    },
    "body": {
      "sections": [{
        "items": [{
          "type": "label",
          "text": "go",
          "href": {
            "url": "/f3h.json"
          }
        }]
      }]
    }
  }
}

Discussion 2. Would this type of approach make the code less readable?

Upon thinking more about this I've come up with some concerns. One of the coolest things about Jasonette is you can basically walk through all the referenced JSON to figure out how the entire app works.

But maybe adding a relative url element puts more burden on people trying to figure out what the JSON does? After all, we're adding one more step for users to think about whenever they come across a url. I'm not suggesting this is a serious problem, but just wanted to bring this to the table and hear what others think.

Discussion 3. Can we use templates to achieve similar effect?

Going back to above example, maybe we can achieve the same effect without introducing new concepts. For example we can $set a local variable called root and use that inside templates. Not exactly as succinct as the original solution suggested by brad but it does make the code more modular and shareable:

{
  "$jason": {
    "head": {
      "root_url": "https://www.jasonbase.com/things",
      "title": "relative path demo",
      "actions": {
        "$load": {
          "type": "$set",
          "options": {
            "root": "https://www.jasonbase.com/things"
          },
          "success": {
            "type": "$render"
          }
      },
      "templates": {
        "body": {
          "sections": [{
            "items": [{
              "type": "label",
              "text": "go",
              "href": {
                "url": "{{$get.root}}/f3h.json"
              }
            }]
          }]
        }
      },
      ...
    }
  }
}

What do you guys think? Any ideas/feedback welcome!

GPS support?

Jasonette is extremely interesting, thank you for the work so far, however I could not find any reference to using the devices' GPS, nor the examples make use of it. If Jasonette can't use GPS, please make it explicit somewhere in the documentation. Geofencing in particular is critical to an application I would like to use Jasonette to build. Thanks.

Giacecco

Spec for the NEW sandboxed Local Storage - Feedback appreciated

One of the most frequently requested features is local key/value storage. This is a sensitive problem since it's directly related to security. Browsers have sandboxing for many good reasons. This is why I've been delaying making a decision on this until I've come up with a couple of ideas.

Now I have, and wanted to share. Note that none of the ideas involve having a single global storage, but involves having a local storage sandbox per each URL and accessing them from one view to another.

Here are the two:

1. Readonly exports

If you are aware of javascript module system you can think of this as a similar method. We would introduce two new actions $state.export and $state.import. Users would need to first visit a URL to "export" all the values it wants to export, and then once that's done, other views can reference the value using $state.import. If you try to $state.import before it's been exported, it will not return the value;

I actually took a shot at a quick prototype over at $state branch The code is commented so it should be self-explanatory how it should work.

  • Pros: it's pretty simple (conceptually as well as implementation-wise) and intuitive. Easy to implement.
  • Cons: the states are "readonly" from other views. You can write to the state of any URL ONLY from itself.

An example code:

Exporting:

    {
        "type": "$state.export",
        "options": {
            "username": "Ethan",
            "email": "[email protected]"
        },
        "success": {
            "type": "$close"
        }
    }

Importing

     {
        "type": "$state.import",
        "options": {
            "db": "https://www.jasonbase.com/things/3nf.json"
        },
        "success": {
            "type": "$set",
            "options": {
                "db": "{{$jason.db}}"
            }
        }
     }

It works pretty similarly to how Javascript module system works. you can export and other modules can import to use them, but they are readonly (the similarity to Javascript module system is another reason why this feels simpler)

But like I said, not being able to write has some drawbacks, which is why I have another idea:

2. Read/Write state variables

Here, you not only can read from another URL's state, but also can write to it. Here the API would consist of: $state.set and $state.get.

Since being able to write to another view's sandbox is a big deal in terms of security, we also need another security measure. In this case we will also need to explicitly state the public state variables so that only those state variables can be set from outside of the view. This may look something like this:

{
  "$jason": {
    "head": {
      "state": ["username", "email"],
      ...
    }
  }
}

Basically we are stating that anyone can set the state variable for this URL but ONLY the "username" and "email" variables.

I've attached below a full example of what it would look like. But before we go on, just a quick explanation on how this works:

  1. abc.json is the master view which transitions to 123.json
  2. User can select an option from 123.json
  3. When the user selects an item, it sets the abc.json's selected state variable via $state.set, and returns via $back action.
  4. When we return to abc.json, the $show event triggers $state.get and renders the view based on the state we've just set.

abc.json

{
  "$jason": {
    "head": {
      "state": ["selected"],
      "actions": {
        "$show": {
          "type": "$state.get",
          "options": {
            "db": "https://www.jasonbase.com/things/abc.json"
          },
          "success": [{
            "{{#if ('db' in $jason) && ('selected' in $jason.db)}}": {
              "type": "$set",
              "options": {
                "selected": "{{$jason.db.selected}}"
              },
              "success": {
                "type": "$render"
              }
            }
          }, {
            "{{#else}}": {
              "type": "$set",
              "options": {
                "selected": "Nothing selected"
              },
              "success": {
                "type": "$render"
              }
            }
          }]
        }
      },
      "templates": {
        "body": {
          "sections": [{
            "header": {
              "type": "label",
              "text": "{{$get.selected}}"
            },
            "items": [{
              "type": "label",
              "text": "Select Items",
              "href": {
                "url": "https://www.jasonbase.com/things/123.json"
              }
            }]
          }]
        }
      }
    }
  }
}

123.json

{
  "$jason": {
    "head": {
      "data": {
        "items": [{
          "text": "Item 1"
        }, {
          "text": "Item 2"
        }, {
          "text": "Item 3"
        }]
      },
      "templates": {
        "body": {
          "sections": [{
            "items": {
              "{{#each items}}": {
                "type": "label",
                "text": "{{text}}",
                "action": {
                  "type": "$state.set",
                  "options": {
                    "selected@https://www.jasonbase.com/things/abc.json": "{{text}}"
                  },
                  "success": {
                    "type": "$back"
                  }
                }
              }
            }
          }]
        }
      }
    }
  }
}
  • pros: more flexible
  • cons:
    1. more complex, which means there can be some unforeseen edge cases.
    2. This one's more important: Because we rely on the "state" declaration on the view in order to determine what state variable is read/writeable, every time we access $state.get, we need to query the the state's owner URL (one network/file request) to check its $jason.head.state attribute to make sure the attribute has been declared accessible. (The first solution I suggested above doesn't have this problem since the variable will simply be empty if it hasn't been already exported)

Feedback appreciated

I wanted to share here because I'm still trying to decide on this since people have been requesting this either directly or indirectly (a lot of the problems people talk about on the forum can be made easier by supporting this, for example almost all bugs/issues related to tab bar or $params will become irrelevant when we support this since we can deprecate $params and just use the $state instead, which is much more robust and flexible).

I would appreciate any kind of feedback on either of the two. Especially if you have a better idea or improvement, or any security holes I missed, please feel free to share.

Thanks!

post offline

Use case: post a message to chat when the user is offline

Intended UX:

  • user posts a message
  • message appears in the view immediately with a "..." or spinner indicator
  • when the server acknowledges the message, the indicator changes to check mark (or simply disappears)
  • server can explicitly reject the request (403 etc) or it might expire after a specified timeout

Implementation options:

  1. "virtual" network.request (backend has to make sure repeated requests are ignored), with return options like "success","failure" (500 etc), "offline" and exponential backoff (so app wont spam the server in case of error); but the problem is that user should also see its message together with server-sent ones (with a spinner indicator or something)
  2. could be currently awkwardly worked around with $global but really there should be some API support.
  3. another option is some kind of an object synchronized with server

I could help with drafting the API for this.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.