Giter VIP home page Giter VIP logo

app-decorators's People

Contributors

serkansipahi avatar spaceone avatar

Stargazers

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

Watchers

 avatar  avatar

app-decorators's Issues

tree based dependency injection

find ideas:

  • idea for simple inject

js based:

@component({
    name: 'todo-list',
    extends: 'ul',
})
@inject({ 
    WorkflowService,
    UserService
})
class Foo {
    create({ WorkflowService, UserService }){
         this.workflowService = WorkflowService;
         this.userService = UserService;
    }
}

html based:

<com-foo>
   <env-inject export="$" module="jQuery"></env-inject>
   <env-inject export="_" module="underscore"></env-inject>
</com-foo>

allow to set a @component on class with many subclasses

class Foo {
    parentMethodCall(){
    }
    a() { }
    b() { }
}
class Bar extends Foo {
    parentMethodCall(){
        super.parentMethodCall();
    }
    c() { }
    d() { }
}
class Baz extends Bar {
    parentMethodCall(){
        super.parentMethodCall();
    }
    e() { }
    f() { }
}

@component(HTMLFormElement)
class Yellow extends Baz {
    static x() {}
    static y() {}
        parentMethodCall(){
        super.parentMethodCall();
    }
    createdCallback() {
    }
    attachedCallback() {
    }
    attributeChangedCallback(attrName, oldVal, newVal) {
    }
    detachedCallback() {
    }
}

// create domInstance
let yellow = Yellow.instance();

black-hole component

@component({
    extends: 'progress',
})
@view(`
    <div class="progress-wrapper">
        <black-hole category="1"></back-hole>
    </div>
`)
class Progress {

}

let progress = Progress.create();
// or if put put this into dom
<progress is="com-progress"></progress>

will render to

<div class="progress-wrapper">
    <black-hole>
        <progress is="com-progress"></progress>
    </back-hole>
</div>

Lazy Loader/Register Babel-Plugin component suggestion

load.js proposal required for outfile (see below)

let load = async (...args, modules) => {
	let modules = await Promise.all([...args].map(module => System.import(module)));
        Object.assign(modules, _modules);
}

export {
	load,
}

in

@component({
	name: 'com-page',
	extends: 'form',
})
class Pages {
	@action('/', ['startpage']) onStartpageAction({ modules, params }){
		// ..code ...
	}
	@action('/?sidebar={{type}}', ['sidebar']) onSidebarAction({ modules, params }){
		// ..code ...
	}
	@on('click .buy', ['checkout', 'payment']) onBuyAction({ modules, event }){
		// ..code ...
	}
}

out:

import * as _load from './helpers/load'

@component()
class Pages {
	@action('/', ['startpage']) async onStartpageAction({ modules, params }){
		await _load.load(['startpage'], modules);
		// ..code ...
	}
	@action('/?sidebar={{type}}', ['sidebar']) async onSidebarAction({ modules, params }){
		await _load.load(['sidebar'], modules);
		// ..code ...
	}
	@on('click .buy', ['checkout', 'payment']) async onBuyAction({ modules, event }){
		await _load.load(['checkout', 'payment'], modules);
		// ..code ...
	}
}

Info: modules declaration can be used for auto bundling!

Optimizer for Building an Component with there dependency e.g. (view, style, etc)

@component({
    extends: 'img'
})
@view(`
   <div class="foo">{{id}}</div>
   <div class="bar">{{nr}}</div>
`)
@style(´
    .bar {
        background-color: red;
     }
    .foo {
        background-color: blue;
    }
´)
class Baz {

}

should compiled to:

<com-baz>
  <style>
    .bar {
        background-color: red;
     }
    .foo {
        background-color: blue;
    }
  </style>
  <div class="foo"><view-node class="com-baz-id"></view-node></div>
  <div class="bar"><view-node class="com-baz-nr"></view-node></div>
  <script>
        // compiled javascript code from Class Baz
  </script>
  <!-- or -->
  <script async src="file.js"></script>
</com-baz>

refactor on.js on.helper.registerNamespaces

Redruce complexity of data structure

this:

    registerNamespaces: (target) => {

        // define $appDecorators.on namespace
        if(!target.$appDecorators) target.$appDecorators = {};
        if(!target.$appDecorators.on) {
            target.$appDecorators.on = {
                events : { local: {} },
            };
        }

        // define $onCreated.on namespace
        if(!target.$onCreated) target.$onCreated = {};
        if(!target.$onCreated.on) target.$onCreated.on = [];

        // define $onDetached.on callbacks
        if(!target.$onDetached) target.$onDetached = {};
        if(!target.$onDetached.on) target.$onDetached.on = [];

        // define $onAttached.on callbacks
        if(!target.$onAttached) target.$onAttached = {};
        if(!target.$onAttached.on) target.$onAttached.on = [];

        return target;

    }

to

    registerNamespaces: (target) => {

        // define $appDecorators.on namespace
        if(!target.$appDecorators) target.$appDecorators = {};
        if(!target.$appDecorators.on) {
            target.$appDecorators.on = {
                events: { local: {} },
                created: [],
                attached: [],
                detached: [],
            };
        }
        return target;

    }

Using more Promises ( finding ideas )

Ideas

@component()
@view(`
    <div class="foo">
         <com-loader></com-loader>
         <com-foo></com-foo>
    </div>
`)
class Foo {
    // fetch event bubbles over .loader an event with promise as value. 
    // If Promise resolved then onFetch will be called
    @on('fetch com-loader') @then onFetch({ result }) {

    }
    @on('ready com-foo') @then onReady({ result }){

    }
    // eventA, eventB and eventC send an promise through the event.
    // only when the promises (internal promise.all) resolved onAbc will be called
    @subscribe('eventA, eventB, eventC') @then onAbc({ resA, resB, resC }){

    }
}

// or
let component = Comfoo.create();
component.ready.then(() => {
    // awesome code
});

// or for subscriber
pubsub.publish('eventA', new Promise((resolve, reject) => setTimeout(resolve, 5000))); 
pubsub.publish('eventB', new Promise((resolve, reject) => setTimeout(resolve, 2000))); 
pubsub.publish('eventC', new Promise((resolve, reject) => setTimeout(resolve, 3000))); 

Refactor src/libs/customelement.js

Name of Plugin: babel-plugin-app-decorators-component

Example 1 (required)

in:

@component()
class Helloworld {

}

out:

@component()
class Helloworld extend HTMLElement {

}

Example 2 (required)

in:

@component({
   extends: 'img'
})
class Helloworld {

}

out:

@component({
   extends: 'img'
})
class Helloworld extends HTMLImageElement {

}

Example 3 (not required)

in:

class Foo  {}
class Bar extends Foo {}

@component({
   extends: 'form'
})
class Helloworld extends Bar {

}

out:

class Foo extends HTMLFormElement {}
class Bar extends Foo {}

@component({
   extends: 'img'
})
class Helloworld extends Bar {

}

improvement decorator order using

Es sollte egal sein welcher decorator als ersten getagged wurde. Es sollte immer gewährleistet werden das eine Klasse mit seinen Komponenten initialisiert werden kann. Hintergrund: Die decorator lösen sich von innen nach außen auf. Wenn wie im "Beispiel 2 - siehe unten" der äußerste decorator nicht die @ component ist, geht @view verloren weil @ component denk er hätte alles und beginnt mit dem instanziieren.

Beispiel 1:

@component()
@view(`
     <div>Hello world</div>
`)
@style(`
     .bar {
         display: block;
     }
`)
class Foo {

}

Beispiel 2:

@view(`
     <div>Hello world</div>
`)
@component()
@style(`
     .bar {
         display: block;
     }
`)
class Foo {

}

Lösungen/Ideen:

src/apps/router: move popstate listener to src/libs/router.js

do something like this:

let routerConfig = {
    event: {
        popstate: 'popstate'
    },
    popstate_scope: Eventhandler.create({
        element: window
    }),
};
// and in src/libs/router.js
_bindInternalCoreEvents(){
    this.popstate_scope.on(this.event.popstate, ::this._onAction);
}
_removeInternalCoreEvents(){
    this.popstate_scope.off(this.event.popstate);
}

this is important because we want to make sure that every event is removed from eventlistener if eventhandler will be destroyed.

src/libs/router.js: allow to pass wildcard-route: "/*" and notFound-route"/notFound"

let router = Router.create({
    scope: document.body,
    routes: [
        // will match all registered routes
        ['all /*', function wildcard() {} ],
        // will match if route not found and if notFound registered
        ['notFound /notFound', function notFound() {} ],
    ],
});

or

let router = Router.create({
    scope: document.body,
});

// will match all registered routes
router.on('all /*', () => {

});

// will match if route not found and if notFound registered
router.on('notFound /notFound', () => {

});

important to-do´s

  • Documentation:
    • remove "extends" from "component" decorator to own decorator (@mixin)
    • I think if we want to playing directly on the native element (e.g. img, form, etc) we should use the "extends" variant but if we want to enrich a element with special markup e.g <google-maps lat="40.731" lng="33.33"></google-maps> we should use it without "extends". <com-image src="image" /> vs <img is="image" />
    • always specify the dependencies e.g. @ on is depend to @CustomElement
  • replace this "target.$onCreated.push" with ""target.$onCreated.on.push(.., or target.$onCreated.view.push"
  • if inner-component or black-hole on render force it can makes problems
  • Offline-App: Service Worker and as fallback AppCache (IOS Safari)
  • Decorators: @comopnent + @view: whenever we render use request-animation frame
  • Implementing a representativ benchmark (performance) test (Ist/soll state)
  • Implementing in compute-intensive areas/places Webworker
  • Using <black-hole /> element if CustomElement has Markup:
    <com-foo> <img class="im-always-here" /> </com-foo>
  • implementing bluebird library (for better exception handling)
  • callback if customElement is ready: element.then(() => {})
  • Tests: @CustomElement -> on detached eventhandler.removeEvents
  • @CustomElement, @ on: onAttached, onDetached no re-render( what actually do, but no tests) and re-add events onAttached
  • removing jspm-karma dependency ! We want to use the native karma behavior! obsolet
  • name of customelement if using @CustomElement --> implemented <--
    • if only "@CustomElement" the name of customelement is depending of class name --> implemented <--
      • e.g. class foo {} = <com-foo></com-foo> --> implemented <--
    • removing com as customelment-name prefixproperty. --> implemented <--
    • if @CustomElement({ name: 'my-element' }) the name of customelement is <my-element></my-element> --> implemented <--
    • if @CustomElement({ name: 'my-element', extends: 'div' }) the name of customelement is <div is="my-element"></div>. --> implemented <--
  • Deprecated/Remove: @CustomElement(HTMLElement) --> passing Element ! --> implemented <--
    • We follow the standard implementation. Write this in Documentation
  • @ model + PouchDB
  • @CustomElement: createClass, createProperties, defineProperties ---> use the methods from core-js
  • routercontroller example/idea:
class checkout {
   // already implemented
   @action('/index') startpage() {
       // do something
   }
   // already implemented
   @action('/index/{{id}}/{{type}}?a=1&b=2#c=3&d=4') details({actions, params, hashes}) {
       // params and hashes are reserved?!?!
    }
    // for next step
   @post @action('error.html') error(){
   }
}

/*
- for e.g. url: /checkout/index/123/descrption
- alias for routename checkout::details, checkout::startpage
- Todo´s for that: need Class Router, and something like a dispatcher
- Useful for Router - HTML5 History-API:
  - for resolving url -> new URL('https://my-domain.com')
  - see for more information black-book
*/ 
// For Safari ( dont forget a generic form for see: "src/datas/elements.js" )
if (typeof HTMLElement !== 'function'){
    var _HTMLElement = function(){};
    _HTMLElement.prototype = HTMLElement.prototype;
    HTMLElement = _HTMLElement;
}

// For IE10
// https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent
(function () {
    function CustomEvent ( event, params ) {
        params = params || { bubbles: false, cancelable: false, detail: undefined };
        var evt = document.createEvent( 'CustomEvent' );
        evt.initCustomEvent( event, params.bubbles, params.cancelable, params.detail );
        return evt;
    }

    CustomEvent.prototype = window.Event.prototype;

    window.CustomEvent = CustomEvent;
})();

@ on in views ( by injection )

// example/idea

@view(`
   <div @on('click')="methodClickFoo()" class="foo">Foo</div>
   <div @on('mousenter')="methodMouseenterFoo()" class="bar">bar</div>
`)

Should be removed (Libs)

Should be removed (Libs)

  • Immutablejs ( 5000 lines)
  • PouchDB ( 13000 lines ) ( new Version is better because is modulized )
  • Bluebird (5500 lines)
  • xregexexp (5000 lines), we should find different solution
  • Webcomponent ( 2000 lines ), load if required

Performance etc, ...

FRONTEND
  - Progressiv Webapps
   -- Blogs
     + https://medium.com/javascript-scene/native-apps-are-doomed-ac397148a2c0
  - Promises ( use it everywhere you can )
  - Web Workers
  - Client Caching
   - - Service Workers
     + cache api
     + fetch() API
     + Push notifications
     + Web App Manifest
     + on revisit the site browser will install the Site as Webapp ( add to Homescreen )
     + fallback for Service-Workers -> application Cache
     + https://github.com/GoogleChrome/samples/tree/gh-pages/service-worker (examples)
     + https://www.udacity.com/course/offline-web-applications--ud899 
     + https://serviceworke.rs/
   - - Application Cache
   - - Cache Storage
  - IndexedDB
  - MOBILE
    + add to homescreen
    + app install banner
    + <meta name="theme-color">
  - CSS
    + SaSS
    + https://css-tricks.com/authoring-critical-fold-css/
    + will-change
       - https://github.com/postcss/postcss-will-change
    + scroll-behavior: smooth
    + https://developers.google.com/web/updates/2016/06/css-containment
       - css-containment
  - CSSOM
     + http://webkrauts.de/artikel/2015/cssom--cascading-style-sheet-object-model
  - Web Animations API
  - Request Animation Frame
  - Benchmark testing / Profiling
  - Blob urls, etc
  - render on viewport
  - https://github.com/webcomponents/shadydom v1
    + http://blog.aurelia.io/2016/05/23/aurelia-shadow-dom-v1-slots-prerelease/
    + https://developers.google.com/web/fundamentals/getting-started/primers/shadowdom
  - https://github.com/webcomponents/shadycss
  - https://github.com/GoogleChrome/samples (a repo containing samples tied to new functionality in each release of Google Chrome)
  - https://developers.google.com/web/fundamentals/
  - https://developers.google.com/web/fundamentals/performance/
  - https://github.com/WICG
  - prefetch ( <link src="foo.html"> )
  - async ( <script src="foo.js" async></scrip> )
  - application-shell ( fast init start )
  - Improving Scroll Performance with Passive Event Listeners
     + https://developers.google.com/web/updates/2016/06/passive-event-listeners 
     + https://www.webreflection.co.uk/blog/2016/04/17/new-dom4-standards
     + https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md
     + https://blog.chromium.org/2016/05/new-apis-to-help-developers-improve.html
  - Reduce the Scope and Complexity of Style Calculations
    + https://github.com/wilsonpage/fastdom
    + https://developers.google.com/web/fundamentals/performance/rendering/avoid-large-complex-layouts-and-layout-thrashing
    + https://developers.google.com/web/fundamentals/performance/rendering/simplify-paint-complexity-and-reduce-paint-areas
  - Javascript-Styleguid
    + https://github.com/airbnb/javascript

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.