runs in ios

This commit is contained in:
hariroshan 2023-01-06 19:21:13 +05:30
parent 12850e2add
commit 28f82ad2a8
29 changed files with 1218 additions and 690 deletions

View File

@ -1,17 +1,18 @@
{
"type": "application",
"source-directories": [
"src"
"src",
"nativescript-bind-elm/src"
],
"elm-version": "0.19.1",
"dependencies": {
"direct": {
"elm/browser": "1.0.2",
"elm/core": "1.0.5",
"elm/html": "1.0.0"
"elm/html": "1.0.0",
"elm/json": "1.1.3"
},
"indirect": {
"elm/json": "1.1.3",
"elm/time": "1.0.0",
"elm/url": "1.0.0",
"elm/virtual-dom": "1.0.3"

View File

@ -1,13 +1,22 @@
{
"type": "package",
"name": "hariroshan/elm-native",
"summary": "Nativescript bindings to build mobile apps using elm",
"license": "BSD-3-Clause",
"version": "0.1.0",
"exposed-modules": [],
"elm-version": "0.19.0 <= v < 2.0.0",
"dependencies": {
"elm/core": "1.0.0 <= v < 2.0.0"
},
"test-dependencies": {}
"type": "package",
"name": "hariroshan/elm-native",
"summary": "Nativescript bindings to build mobile apps using elm",
"license": "BSD-3-Clause",
"version": "0.1.0",
"exposed-modules": [
"Native",
"Native.Attributes",
"Native.Frame",
"Native.Page",
"Native.Layout",
"Native.Event"
],
"elm-version": "0.19.0 <= v < 2.0.0",
"dependencies": {
"elm/core": "1.0.0 <= v < 2.0.0",
"elm/html": "1.0.0 <= v < 2.0.0",
"elm/json": "1.1.3 <= v < 2.0.0"
},
"test-dependencies": {}
}

View File

@ -1,5 +1,12 @@
module Native exposing (Native)
module Native exposing (label)
import Html exposing (Attribute, Html)
type Native
= Native
label : List (Attribute msg) -> List (Html msg) -> Html msg
label attrs children =
Html.node "ns-label" attrs children

View File

@ -0,0 +1,9 @@
module Native.Attributes exposing (text)
import Html exposing (Attribute)
import Html.Attributes exposing (attribute)
text : String -> Attribute msg
text =
attribute "text"

View File

@ -0,0 +1,10 @@
module Native.Event exposing (on)
import Html exposing (Attribute)
import Html.Events as Event
import Json.Decode as D
on : String -> D.Decoder msg -> Attribute msg
on eventName =
Event.on eventName

View File

@ -0,0 +1,74 @@
module Native.Frame exposing (Frame, asElement, frame, root)
import Html exposing (Attribute, Html)
import Native.Page as Page exposing (Page)
type Frame msg
= Frame (Html msg)
frame : { a | next : Maybe page, history : List page } -> List ( page, { a | next : Maybe page, history : List page } -> Page msg ) -> List (Attribute msg) -> Frame msg
frame model pages attrs =
Frame
(Html.node "ns-frame"
attrs
(model.history
|> List.foldl
(\next acc ->
pages
|> getPage next model
|> Maybe.map (\x -> x :: acc)
|> Maybe.withDefault acc
)
[]
)
-- ([ pages
-- |> getPage model.current model
-- , model.next
-- |> Maybe.map
-- (\next ->
-- pages
-- |> getPage next model
-- )
-- |> Maybe.withDefault []
-- ]
-- |> List.concat
-- )
)
getPage : a -> b -> List ( a, b -> Page msg ) -> Maybe (Html msg)
getPage target model pages =
pages
|> findInList target Tuple.first Nothing
|> Maybe.map
(\( _, fx ) ->
model
|> fx
|> Page.unwrap
)
findInList : b -> (a -> b) -> Maybe a -> List a -> Maybe a
findInList target toItem acc ls =
case ls of
[] ->
acc
h :: r ->
if target == toItem h then
Just h
else
findInList target toItem acc r
root : Frame msg -> Html msg
root (Frame e) =
e
asElement : Frame msg -> Html msg
asElement =
root

View File

@ -0,0 +1,17 @@
module Native.Layout exposing (Layout, asElement, rootLayout)
import Html exposing (Attribute, Html)
type Layout msg
= Layout (Html msg)
rootLayout : List (Attribute msg) -> List (Html msg) -> Layout msg
rootLayout attrs children =
Layout (Html.node "ns-root-layout" attrs children)
asElement : Layout msg -> Html msg
asElement (Layout e) =
e

View File

@ -0,0 +1,22 @@
module Native.Page exposing (Page, page, unwrap)
import Html exposing (Attribute, Html)
import Native.Layout as Layout exposing (Layout)
type Page msg
= Page (Html msg)
page : List (Attribute msg) -> Layout msg -> Page msg
page attrs layout =
Page
(Html.node "ns-page"
attrs
[ Layout.asElement layout ]
)
unwrap : Page msg -> Html msg
unwrap (Page e) =
e

View File

@ -9,7 +9,7 @@ type rec context = {
elm: unit => elmModule,
flags: Js.Nullable.t<Obj.t>,
initPorts: Js.Nullable.t<Obj.t => unit>,
createFunctions: Obj.t => Obj.t,
withCustomElements: (. Obj.t, Types.handler) => Obj.t,
elements: array<Types.customElement>,
}
@ -20,16 +20,15 @@ type rec context = {
external setGlobalDocument: (global, Dom.document) => unit = "document"
let getRootLayout: unit => NativescriptCore.rootLayout = _ =>
%raw(`document.body.children[0].object`)
%raw(`document.body.children[0].data`)
let initElements = (params: context) => {
let htmlElement = params.window->Mock.hTMLElement
let customElements = params.window->Mock.customElements
htmlElement->params.createFunctions->ignore
params.elements->Belt.Array.forEach(element => {
element.tagName->customElements.define(htmlElement->element.make)
let newClass = params.withCustomElements(. htmlElement, element.handler)
customElements.define(. element.tagName, newClass)
})
NativescriptCore.Application.run({
@ -60,10 +59,10 @@ let start: config => unit = config => {
initPorts: config.initPorts,
elm: config.elmModule,
elements: Native.allElements,
createFunctions: CustomElement.createFunctions,
withCustomElements: CustomElement.withCustomElements,
}
let defineCustomElements = `initElements({window, createFunctions, elements})`
let defineCustomElements = `initElements({window, withCustomElements, elements})`
let elmRoot = "elm-root"
let elmInitScript = `

View File

@ -1,163 +1,2 @@
type constructor = {
observedAttributes: array<string>,
name: string,
}
type event
type nativeObject = {
on: (event, event => unit) => unit,
off: (event, event => unit) => unit,
}
type super = {
addEventListener: (event, event => unit) => unit,
removeEventListener: (event, event => unit) => unit,
}
type extendedThis = {
getAttributes: unit => Js.Dict.t<string>,
getProps: unit => Js.Dict.t<string>,
init: unit => unit,
update: (string, string) => unit,
dispose: unit => unit,
isConnected: bool,
render: Js.Nullable.t<unit => unit>,
object: nativeObject,
}
type this = {
getAttribute: string => Js.Nullable.t<string>,
style: string,
super: super,
constructor: constructor,
}
%%private(
@scope("prototype") @set
external assignGetPropsInProto: (Obj.t, unit => Js.Dict.t<string>) => unit = "getProps"
@scope("prototype") @set
external assignGetAttributes: (Obj.t, unit => Js.Dict.t<string>) => unit = "getAttributes"
@scope("prototype") @set
external assignConstructor: (Obj.t, unit => unit) => unit = "constructor"
@scope("prototype") @set
external assignAttributeChangedCallback: (Obj.t, (string, unit, string) => unit) => unit =
"attributeChangedCallback"
@scope("prototype") @set
external assignConnectedCallback: (Obj.t, unit => unit) => unit = "connectedCallback"
@scope("prototype") @set
external assignDisconnectedCallback: (Obj.t, unit => unit) => unit = "disconnectedCallback"
@scope("prototype") @set
external assignAddEventListener: (Obj.t, (event, event => unit) => unit) => unit =
"addEventListener"
@scope("prototype") @set
external assignRemoveEventListener: (Obj.t, (event, event => unit) => unit) => unit =
"removeEventListener"
@set
external assignObservedAttributes: (Obj.t, unit => array<string>) => unit = "observedAttributes"
@val external this: this = "this"
external toExtendedThis: this => extendedThis = "%identity"
@val external thisSuper: unit => unit = "this.super"
@set
external setThisProps: (this, Js.Dict.t<string>) => unit = "props"
let withAttrs = class => {
class->assignObservedAttributes(_ => [])
class->assignGetAttributes(_ => {
this.constructor.observedAttributes->Belt.Array.reduce(Js.Dict.empty(), (acc, attrName) => {
let attrValue = switch this.getAttribute(attrName)->Js.Nullable.toOption {
| Some(a) => Some(a)
| None => attrName == "style" ? Some(this.style) : None
}
let attrNameMap = attrName == "class" ? "className" : attrName
attrValue
->Belt.Option.map(
value => {
acc->Js.Dict.set(attrNameMap, value)
acc
},
)
->Belt.Option.getWithDefault(acc)
})
})
}
let withProps = class => {
class->assignGetPropsInProto(() => {
(this->toExtendedThis).getAttributes()
})
}
let withCreate = class => {
class->assignConstructor(() => {
thisSuper()
Js.log(this.constructor.name ++ " created")
(this->toExtendedThis).init()
})
}
let withInitAndUpdate = class => {
class->assignAttributeChangedCallback((name, _, value) => {
let extendedThis = this->toExtendedThis
this->setThisProps(extendedThis.getProps())
extendedThis.update(name, value)
Js.log(this.constructor.name ++ " update")
})
}
let withMountAndRender = class => {
class->assignConnectedCallback(_ => {
let extendedThis = this->toExtendedThis
if extendedThis.isConnected {
extendedThis.render->Js.Nullable.toOption->Belt.Option.forEach(fx => fx())
}
Js.log(this.constructor.name ++ " connected")
})
}
let withUnmount = class => {
class->assignDisconnectedCallback(_ => {
(this->toExtendedThis).dispose()
Js.log(this.constructor.name ++ " disconnected")
})
}
let withEventListener = class => {
class->assignAddEventListener((event, callback) => {
this.super.addEventListener(event, callback)
(this->toExtendedThis).object.on(event, callback)
})
class->assignRemoveEventListener((event, callback) => {
this.super.removeEventListener(event, callback)
(this->toExtendedThis).object.off(event, callback)
})
}
)
let createFunctions = class =>
[
withAttrs,
withProps,
withCreate,
withInitAndUpdate,
withMountAndRender,
withUnmount,
withEventListener,
]->Belt.Array.reduce(class, (acc, cur) => {
cur(acc)
acc
})
@module("./custom")
external withCustomElements: (. Obj.t, Types.handler) => Obj.t = "withCustomElements"

View File

@ -1,11 +1,30 @@
module TextView = {
let tagName = "ns-text-view"
let make = class => class
module Label = {
%%private(
@module("@nativescript/core") @new
external new: unit => Types.nativeObject = "Label"
let label = new()
let attributes = Helper.getPropsForObject(Obj.magic(label))
label.destroyNode(.)
)
let tagName = "ns-label"
let handler: Types.handler = {
init: (. ()) => new(),
observedAttributes: attributes,
render: Js.Nullable.return((. current: Types.this, _) =>
Helper.addView(. current.parentElement, current)
),
pageAdded: Js.Nullable.null,
update: NativescriptCore.update,
dispose: NativescriptCore.dispose,
addEventListener: NativescriptCore.addEventListener,
removeEventListener: NativescriptCore.removeEventListener,
}
}
let all: array<Types.customElement> = [
{
tagName: TextView.tagName,
make: TextView.make,
tagName: Label.tagName,
handler: Label.handler,
},
]

View File

@ -0,0 +1 @@
let all: array<Types.customElement>

View File

@ -0,0 +1,73 @@
let always = (x, _) => x
let rec assignDeep: (Obj.t, array<string>, int, 'a) => unit = (object, keys, i, value) => {
let optionKey = keys->Belt.Array.get(i)
optionKey
->Belt.Option.flatMap(key => Js.Dict.get(Obj.magic(object), key)->Belt.Option.map(x => (key, x)))
->Belt.Option.forEach(((key, v)) => {
if keys->Array.length - 1 == i {
Js.Dict.set(Obj.magic(object), key, value)
} else {
assignDeep(v, keys, i + 1, value)
}
})
}
let setAttribute: (Obj.t, string, 'a) => unit = (object, key, value) => {
if !(key->Js.String2.includes(".")) {
Js.Dict.set(Obj.magic(object), key, value)
} else {
let keys = key->Js.String2.split(".")
assignDeep(Obj.magic(object), keys, 0, value)
}
}
let init = (object, props) => {
Js.Dict.keys(Obj.magic(props))->Belt.Array.forEach(key =>
setAttribute(object, key, Js.Dict.unsafeGet(props, key))
)
}
let update = setAttribute
external typeOf: 'a => string = "typeof"
let getPropsForObject: Obj.t => array<string> = %raw(`
function(object){
let arr = []
for (var prop in object) {
if (prop.startsWith("_")) continue
if (typeof object[prop] === "function") continue
arr.push(prop)
}
return arr
}
`)
let addView: (. 'a, 'b) => unit = %raw(`
function(parentElement, thisElement) {
requestAnimationFrame(() => {
const children = Array.from(parentElement.children)
const hasActionBar = children.some(x =>
x.tagName.toLowerCase() === "ns-action-bar"
)
const index = (Array.from(parentElement.children).indexOf(thisElement))
parentElement.data.insertChild(thisElement.data, hasActionBar ? index - 1 : index);
})
}
`)
let dbg = x => {
Js.log(x)
x
}
let dbg2 = (x, lbl) => {
Js.log2(lbl, x)
x
}
let flip: (('a, 'b) => 'c, 'b, 'a) => 'c = (fx, x, y) => fx(y, x)
/*
*/

View File

@ -1,10 +1,31 @@
module RootLayout = {
%%private(
@module("@nativescript/core") @new
external new: unit => Types.nativeObject = "RootLayout"
let layout = new()
let attributes = Helper.getPropsForObject(Obj.magic(layout))
layout.destroyNode(.)
)
let tagName = "ns-root-layout"
let make = class => class
let handler: Types.handler = {
init: (. ()) => new(),
observedAttributes: attributes,
render: Js.Nullable.return((. current: Types.this, _) =>
if !Js.Nullable.isNullable(current.parentElement.data.insertChild) {
Types.requestAnimationFrame(._ => Helper.addView(. current.parentElement, current))
}
),
pageAdded: Js.Nullable.null,
update: NativescriptCore.update,
dispose: NativescriptCore.dispose,
addEventListener: NativescriptCore.addEventListener,
removeEventListener: NativescriptCore.removeEventListener,
}
}
let all: array<Types.customElement> = [
{
tagName: RootLayout.tagName,
make: RootLayout.make,
handler: RootLayout.handler,
},
]

View File

@ -0,0 +1 @@
let all: array<Types.customElement>

View File

@ -1,2 +1,66 @@
module Frame = {
%%private(
@module("@nativescript/core") @new
external new: unit => Types.nativeObject = "Frame"
let frame = new()
let attributes = Helper.getPropsForObject(Obj.magic(frame))
frame.destroyNode(.)
)
let tagName = "ns-frame"
let allElements: array<Types.customElement> = Belt.Array.concatMany([Elements.all, Layouts.all])
let handler: Types.handler = {
init: (. ()) => new(),
observedAttributes: attributes,
update: NativescriptCore.update,
render: Js.Nullable.null,
pageAdded: Js.Nullable.return((. current: Types.this) => {
current.data->Types.navigate({
create: _ =>
(current.children->Array.unsafe_get(current.children->Array.length - 1)).data,
})
}),
dispose: NativescriptCore.dispose,
addEventListener: NativescriptCore.addEventListener,
removeEventListener: NativescriptCore.removeEventListener,
}
}
module Page = {
%%private(
@module("@nativescript/core") @new
external new: unit => Types.nativeObject = "Page"
let page = new()
let attributes = Helper.getPropsForObject(Obj.magic(page))
page.destroyNode(.)
)
let tagName = "ns-page"
let handler: Types.handler = {
init: (. ()) => new(),
observedAttributes: attributes,
update: NativescriptCore.update,
render: Js.Nullable.return((. current: Types.this, nativeObject) => {
// page should have one child which is a layout
nativeObject->Types.setContent((current.children->Array.unsafe_get(0)).data)
Types.requestAnimationFrame(._ => {
current.parentElement.handler.pageAdded
->Js.Nullable.toOption
->Belt.Option.forEach(fx => fx(. current.parentElement))
})
}),
pageAdded: Js.Nullable.null,
dispose: NativescriptCore.dispose,
addEventListener: NativescriptCore.addEventListener,
removeEventListener: NativescriptCore.removeEventListener,
}
}
let allElements: array<Types.customElement> = Belt.Array.concatMany([
Elements.all,
Layouts.all,
[
{tagName: Page.tagName, handler: Page.handler},
{tagName: Frame.tagName, handler: Frame.handler},
],
])

View File

@ -0,0 +1 @@
let allElements: array<Types.customElement>

View File

@ -6,3 +6,15 @@ module Application = {
@module("@nativescript/core") @scope("Application")
external run: config => unit = "run"
}
let update = (. nativeObject, attr, newValue) =>
nativeObject->Obj.magic->Helper.update(attr, newValue)
let dispose = (. nativeObject: Types.nativeObject) => nativeObject.destroyNode(.)
let addEventListener = (. nativeObject: Types.nativeObject, event, callback) => {
nativeObject.on(. event, callback)
}
let removeEventListener = (. nativeObject: Types.nativeObject, event, callback) => {
nativeObject.off(. event, callback)
}

View File

@ -1,4 +1,50 @@
type event
type rec nativeObject = {
on: (. event, event => unit) => unit,
off: (. event, event => unit) => unit,
destroyNode: (. unit) => unit,
insertChild: Js.Nullable.t<(. nativeObject, int) => unit>,
}
type constructor = {
observedAttributes: array<string>,
name: string,
}
@val external requestAnimationFrame: (. unit => unit) => unit = "requestAnimationFrame"
@set
external setContent: (nativeObject, 'a) => unit = "content"
type navigationConfig = {create: unit => nativeObject}
@send
external navigate: (nativeObject, navigationConfig) => unit = "navigate"
type rec handler = {
init: (. unit) => nativeObject,
observedAttributes: array<string>,
update: (. nativeObject, string, string) => unit,
render: Js.Nullable.t<(. this, nativeObject) => unit>,
pageAdded: Js.Nullable.t<(. this) => unit>,
dispose: (. nativeObject) => unit,
addEventListener: (. nativeObject, event, event => unit) => unit,
removeEventListener: (. nativeObject, event, event => unit) => unit,
}
and this = {
getAttribute: string => Js.Nullable.t<string>,
style: string,
constructor: constructor,
parentElement: this,
handler: handler,
data: nativeObject,
children: array<this>,
navigate: this => unit,
}
@val external this: this = "this"
type customElement = {
tagName: string,
make: Obj.t => Obj.t,
handler: handler,
}

View File

@ -0,0 +1,37 @@
export const withCustomElements = (UIElement, handler) =>
class extends UIElement {
constructor() {
super()
this.handler = handler
this.data = this.handler.init()
console.log(`${this.tagName} created`)
}
static get observedAttributes() {
return handler.observedAttributes
}
attributeChangedCallback(name, old, newValue) {
this.handler.update(this.data, name, newValue)
console.log(`${this.tagName} update`)
}
connectedCallback() {
if (this.isConnected && this.handler.render) {
this.handler.render(this, this.data)
}
console.log(`${this.tagName} connected`)
}
disconnectedCallback() {
this.handler.dispose(this.data)
console.log(`${this.tagName} disconnected`)
}
addEventListener(event, callback) {
super.addEventListener(event, callback);
this.handler.addEventListener(this.data, event, callback)
}
removeEventListener(event, callback) {
super.removeEventListener(event, callback);
this.handler.removeEventListener(this.data, event, callback);
}
}

View File

@ -1,4 +1,4 @@
declare module "App.bs" {
declare module "App.bs.js" {
type port = any
type config = {
elmModule: () => any,

View File

@ -10,7 +10,7 @@ external document: Dom.window => Dom.document = "document"
@get
external hTMLElement: Dom.window => Obj.t = "HTMLElement"
type customElement = {define: (string, Obj.t) => unit}
type customElement = {define: (. string, Obj.t) => unit}
@get
external customElements: Dom.window => customElement = "customElements"

View File

@ -1,24 +1,27 @@
"use strict";
const Element_1 = (require("happy-dom/lib/nodes/element/Element"));
const HTMLUnknownElement_1 = (require("happy-dom/lib/nodes/html-unknown-element/HTMLUnknownElement"));
const Text_1 = (require("happy-dom/lib/nodes/text/Text"));
const Comment_1 = (require("happy-dom/lib/nodes/comment/Comment"));
const Node_1 = (require("happy-dom/lib/nodes/node/Node"));
const TreeWalker_1 = (require("happy-dom/lib/tree-walker/TreeWalker"));
const DocumentFragment_1 = (require("happy-dom/lib/nodes/document-fragment/DocumentFragment"));
const XMLParser_1 = (require("happy-dom/lib/xml-parser/XMLParser"));
const Event_1 = (require("happy-dom/lib/event/Event"));
const DOMImplementation_1 = (require("happy-dom/lib/dom-implementation/DOMImplementation"));
const Attr_1 = (require("happy-dom/lib/attribute/Attr"));
const NamespaceURI_1 = (require("happy-dom/lib/config/NamespaceURI"));
const DocumentType_1 = (require("happy-dom/lib/nodes/document-type/DocumentType"));
const ParentNodeUtility_1 = (require("happy-dom/lib/nodes/parent-node/ParentNodeUtility"));
const QuerySelector_1 = (require("happy-dom/lib/query-selector/QuerySelector"));
const DOMException_1 = (require("happy-dom/lib/exception/DOMException"));
const HTMLCollectionFactory_1 = (require("happy-dom/lib/nodes/element/HTMLCollectionFactory"));
const DocumentReadyStateEnum_1 = (require("happy-dom/lib/nodes/document/DocumentReadyStateEnum"));
const DocumentReadyStateManager_1 = (require("happy-dom/lib/nodes/document/DocumentReadyStateManager"));
const Selection_1 = (require("happy-dom/lib/selection/Selection"));
const Element_1 = (require("../../node_modules/happy-dom/lib/nodes/element/Element"));
const HTMLUnknownElement_1 = (require("../../node_modules/happy-dom/lib/nodes/html-unknown-element/HTMLUnknownElement"));
const Text_1 = (require("../../node_modules/happy-dom/lib/nodes/text/Text"));
const Comment_1 = (require("../../node_modules/happy-dom/lib/nodes/comment/Comment"));
const Node_1 = (require("../../node_modules/happy-dom/lib/nodes/node/Node"));
const TreeWalker_1 = (require("../../node_modules/happy-dom/lib/tree-walker/TreeWalker"));
const DocumentFragment_1 = (require("../../node_modules/happy-dom/lib/nodes/document-fragment/DocumentFragment"));
const XMLParser_1 = (require("../../node_modules/happy-dom/lib/xml-parser/XMLParser"));
const Event_1 = (require("../../node_modules/happy-dom/lib/event/Event"));
const DOMImplementation_1 = (require("../../node_modules/happy-dom/lib/dom-implementation/DOMImplementation"));
// const ElementTag_1 = (require("../../node_modules/happy-dom/lib/config/ElementTag"));
const Attr_1 = (require("../../node_modules/happy-dom/lib/attribute/Attr"));
const NamespaceURI_1 = (require("../../node_modules/happy-dom/lib/config/NamespaceURI"));
const DocumentType_1 = (require("../../node_modules/happy-dom/lib/nodes/document-type/DocumentType"));
const ParentNodeUtility_1 = (require("../../node_modules/happy-dom/lib/nodes/parent-node/ParentNodeUtility"));
const QuerySelector_1 = (require("../../node_modules/happy-dom/lib/query-selector/QuerySelector"));
const DOMException_1 = (require("../../node_modules/happy-dom/lib/exception/DOMException"));
const HTMLCollectionFactory_1 = (require("../../node_modules/happy-dom/lib/nodes/element/HTMLCollectionFactory"));
const DocumentReadyStateEnum_1 = (require("../../node_modules/happy-dom/lib/nodes/document/DocumentReadyStateEnum"));
const DocumentReadyStateManager_1 = (require("../../node_modules/happy-dom/lib/nodes/document/DocumentReadyStateManager"));
const Selection_1 = (require("../../node_modules/happy-dom/lib/selection/Selection"));
/**
* Document.
*/

View File

@ -1,18 +1,18 @@
import Document from "./document";
import Node_1 from "happy-dom/lib/nodes/node/Node";
import CustomEvent_1 from "happy-dom/lib/event/events/CustomEvent";
import HTMLElement_1 from "happy-dom/lib/nodes/html-element/HTMLElement";
import CustomElementRegistry_1 from "happy-dom/lib/custom-element/CustomElementRegistry";
import EventTarget_1 from "happy-dom/lib/event/EventTarget";
const Node_1 = require("../../node_modules/happy-dom/lib/nodes/node/Node");
const CustomEvent_1 = require("../../node_modules/happy-dom/lib/event/events/CustomEvent");
const HTMLElement_1 = require("../../node_modules/happy-dom/lib/nodes/html-element/HTMLElement");
const CustomElementRegistry_1 = require("../../node_modules/happy-dom/lib/custom-element/CustomElementRegistry");
const EventTarget_1 = require("../../node_modules/happy-dom/lib/event/EventTarget");
export class Window extends EventTarget_1 {
export class Window extends EventTarget_1.default {
constructor() {
super();
this.Node = Node_1;
this.CustomEvent = CustomEvent_1;
this.HTMLElement = HTMLElement_1;
this.customElements = new CustomElementRegistry_1();
const document = new Document(this)
this.Node = Node_1.default;
this.CustomEvent = CustomEvent_1.default;
this.HTMLElement = HTMLElement_1.default;
this.customElements = new CustomElementRegistry_1.default();
const document = new Document(this)
this.document = document;
}
}

View File

@ -1,6 +1,6 @@
{
"name": "elm-native",
"main": "src/index.ts",
"main": "src/index.js",
"version": "0.1.0",
"private": true,
"scripts": {
@ -14,10 +14,11 @@
"@nativescript/core": "~8.4.0",
"@nativescript/theme": "~3.0.2",
"elm": "^0.19.1-5",
"happy-dom": "^8.1.2",
"happy-dom": "^6.0.4",
"vm-shim": "^0.0.6"
},
"devDependencies": {
"@nativescript/ios": "8.3.3",
"@nativescript/types": "~8.4.0",
"@nativescript/webpack": "~5.0.12",
"elm-webpack-loader": "^8.0.0",

View File

@ -1,46 +1,93 @@
module Main exposing (main)
import Browser
import Html exposing (Html, text)
import Html exposing (Html)
import Json.Decode as D
import Native
import Native.Attributes
import Native.Event as Event
import Native.Frame as Frame
import Native.Layout exposing (rootLayout)
import Native.Page as Page
main : Program () Model Msg
main =
Browser.sandbox
{ init = init
, view = view
, update = update
}
type NavPage
= Details
type alias Model =
{ count : Int }
{ count : Int
, next : Maybe NavPage
, history : List NavPage
}
initialModel : Model
initialModel =
{ count = 0 }
init : Model
init =
let
_ =
Debug.log "HEllo from ELM" "World"
in
{ count = 0, history = [ Details ], next = Nothing }
type Msg
= Increment
| Decrement
= Inc
| Dec
| GoToDetails
| Destory
update : Msg -> Model -> Model
update msg model =
case msg of
Increment ->
Dec ->
{ model | count = model.count - 1 }
Inc ->
{ model | count = model.count + 1 }
Decrement ->
{ model | count = model.count - 1 }
GoToDetails ->
{ model | history = Details :: model.history, next = Just Details }
Destory ->
{ model
| next = Nothing
, history =
case model.next of
Nothing ->
model.history |> List.drop 1
Just _ ->
model.history
}
detailsPage : Model -> Page.Page Msg
detailsPage _ =
Page.page [
-- Event.on "navigatedTo" (D.succeed Destory)
]
(rootLayout []
[ Native.label [ Native.Attributes.text "Hello from elm" ] []
]
)
view : Model -> Html Msg
view model =
text "Hello"
main : Program () Model Msg
main =
let
_ =
Debug.log "INIT" "ELM"
in
Browser.sandbox
{ init = initialModel
, view = view
, update = update
}
Frame.frame
model
[ ( Details, detailsPage )
]
[]
|> Frame.root

View File

@ -1,4 +1,5 @@
const webpack = require("@nativescript/webpack");
const path = require('path');
module.exports = (env) => {
webpack.init(env);

1088
yarn.lock

File diff suppressed because it is too large Load Diff