first commit
This commit is contained in:
29
AccountMgr.md
Executable file
29
AccountMgr.md
Executable file
@@ -0,0 +1,29 @@
|
|||||||
|
## Install sshd
|
||||||
|
In order to enable ssh on Ubuntu Linux, we first need to perform an SSH package installation. Open up terminal and enter command:
|
||||||
|
|
||||||
|
$ sudo apt install sshd
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Create a user using command line
|
||||||
|
Let's start by creating a new user. Open up terminal and enter:
|
||||||
|
|
||||||
|
$ sudo adduser --no-create-home username
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Create non-login/system user
|
||||||
|
Let's start by creating a new user. Open up terminal and enter:
|
||||||
|
|
||||||
|
$ sudo useradd -r username
|
||||||
|
|
||||||
|
|
||||||
|
## Change default shell
|
||||||
|
$ grep user /etc/passwd
|
||||||
|
|
||||||
|
$ usermod --shell /bin/bash user
|
||||||
|
|
||||||
|
$ grep user /etc/passwd
|
||||||
|
|
||||||
|
## Adding User to the sudo Group
|
||||||
|
$ usermod -aG sudo username
|
||||||
12
Android.md
Normal file
12
Android.md
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
# Remote debug android phone
|
||||||
|
### Set the target device to listen for a TCP/IP connection on port 5555
|
||||||
|
```
|
||||||
|
$adb -s device_id tcpip 5555
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Connect to the device by its IP address
|
||||||
|
```
|
||||||
|
$adb connect device_ip_address
|
||||||
|
$adb devices
|
||||||
|
```
|
||||||
19
BashScriptFile.md
Executable file
19
BashScriptFile.md
Executable file
@@ -0,0 +1,19 @@
|
|||||||
|
## Basic bash script
|
||||||
|
```
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# declare STRING variable
|
||||||
|
STRING="Hello World"
|
||||||
|
|
||||||
|
#print variable on a screen
|
||||||
|
echo $STRING
|
||||||
|
```
|
||||||
|
|
||||||
|
## Backup bash script
|
||||||
|
|
||||||
|
```
|
||||||
|
#!/bin/bash
|
||||||
|
tar -czf backup.tar.gz /home/app/data
|
||||||
|
```
|
||||||
|
|
||||||
|
[Bash Scripting Tutorial](https://linuxconfig.org/bash-scripting-tutorial)
|
||||||
487
CustomElements.md
Executable file
487
CustomElements.md
Executable file
@@ -0,0 +1,487 @@
|
|||||||
|
# Custom element concepts
|
||||||
|
|
||||||
|
To define a custom element, create a class that extends **PolymerElement** and pass the class to the **customElements.define** method.The custom element's name must start with a lower-case ASCII letter and must contain a dash (-).
|
||||||
|
|
||||||
|
import {PolymerElement} from '@polymer/polymer/polymer-element.js';
|
||||||
|
|
||||||
|
export class MyPolymerElement extends PolymerElement {
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
customElements.define('my-polymer-element', MyPolymerElement);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Polymer element lifecycle
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Reaction Description
|
||||||
|
|
||||||
|
|
||||||
|
constructor -Called when the element is upgraded.The constructor is a logical place to setdefault values,and to manually set up event listeners for the element itself.
|
||||||
|
|
||||||
|
connectedCallback -Called when the element is added to a document.Can be called multiple times during the lifetime of an element.Uses include adding document-level event listeners.
|
||||||
|
|
||||||
|
disconnectedCallback -Called when the element is removed from a document. Can be called multiple times during the lifetime of an element.Uses include removing event listeners added in connectedCallback.
|
||||||
|
|
||||||
|
ready -Called during Polymer-specific element initialization. Called once, the first time the element is attached to the document.
|
||||||
|
|
||||||
|
attributeChangedCallback -Called when any of the element's attributes are changed, appended, removed, or replaced.Use to handle attribute changes that don't correspond to declared properties.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Polymer element initialization
|
||||||
|
|
||||||
|
ready() {
|
||||||
|
super.ready();
|
||||||
|
// do something that requires access to the shadow tree
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
The PolymerElement class initializes your element's template and data system during the **ready** callback, so if you override ready, you must call **super.ready()** before accessing the element's shadow tree.
|
||||||
|
|
||||||
|
|
||||||
|
### Defer non-critical work
|
||||||
|
|
||||||
|
When possible, defer work until after first paint. The render-status module provides an "afterNextRender" utility for this purpose.
|
||||||
|
|
||||||
|
import {PolymerElement} from '@polymer/polymer/polymer-element.js';
|
||||||
|
import {afterNextRender} from '@polymer/polymer/lib/utils/render-status.js';
|
||||||
|
|
||||||
|
class DeferElement extends PolymerElement {
|
||||||
|
...
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
// When possible, use afterNextRender to defer non-critical
|
||||||
|
// work until after first paint.
|
||||||
|
afterNextRender(this, function() {
|
||||||
|
this.addEventListener('click', this._handleClick);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
### Element upgrades
|
||||||
|
|
||||||
|
Adding a definition for an element causes any existing instances of that element to be upgraded to the custom class.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
<my-element></my-element>
|
||||||
|
|
||||||
|
|
||||||
|
### Extending other elements
|
||||||
|
|
||||||
|
In addition to PolymerElement, a custom element can extend another custom element:
|
||||||
|
|
||||||
|
import {MyElment} from './my-element.js';
|
||||||
|
|
||||||
|
export class ExtendedElement extends MyElement {
|
||||||
|
|
||||||
|
static get is() { return 'extended-element'; }
|
||||||
|
|
||||||
|
....
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
customElements.define(ExtendedElement.is, ExtendedElement);
|
||||||
|
|
||||||
|
|
||||||
|
### Sharing code with class expression mixins
|
||||||
|
|
||||||
|
A mixin is simply a function that takes a class and returns a subclass:
|
||||||
|
|
||||||
|
MyMixin = function(superClass) {
|
||||||
|
return class extends superClass {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.addEventListener('keypress', (e) => this._handlePress(e));
|
||||||
|
}
|
||||||
|
....
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Or using an ES6 arrow function:
|
||||||
|
|
||||||
|
MyMixin = (superClass) => class extends superClass {
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Add a mixin to your element like this:
|
||||||
|
|
||||||
|
class MyElement extends MyMixin(PolymerElement) {
|
||||||
|
static get is() { return 'my-element' }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
When creating a mixin that you intend to share with other groups or publish, a couple of additional steps are recommended:
|
||||||
|
|
||||||
|
- Use the dedupingMixin function to produce a mixin that can only be applied once.
|
||||||
|
|
||||||
|
- Define the mixin in an ES module and export it.
|
||||||
|
For Example,
|
||||||
|
|
||||||
|
|
||||||
|
class MyElement extends MixinB(MixinA(Polymer.Element)) { ... }
|
||||||
|
|
||||||
|
|
||||||
|
At this point, your element contains two copies of MixinB in its prototype chain. dedupingMixin takes a mixin function as an argument, and returns a new, deduplicating mixin function:
|
||||||
|
|
||||||
|
mixin-b.js
|
||||||
|
|
||||||
|
|
||||||
|
import {dedupingMixin} from '@polymer/polymer/lib/utils/mixin.js';
|
||||||
|
|
||||||
|
// define the mixin
|
||||||
|
let internalMixinB = (base) =>
|
||||||
|
class extends base {
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
// deduplicate and export it
|
||||||
|
export const MixinB = dedupingMixin(internalMixinB);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Declare Properties
|
||||||
|
|
||||||
|
Declared properties can specify:
|
||||||
|
|
||||||
|
* Property type.Type: constructor
|
||||||
|
* Default value.Type: boolean, number, string or function.
|
||||||
|
* Property change observer. Calls a method whenever the property value changes.Type: string
|
||||||
|
* Read-only status. Prevents accidental changes to the property value.Type: boolean
|
||||||
|
* Two-way data binding support. Fires an event whenever the property value changes.Type: boolean
|
||||||
|
* Computed property. Dynamically calculates a value based on other properties.Type: string
|
||||||
|
* Property reflection to attribute. Updates the corresponding attribute value when the property value changes.Type: boolean
|
||||||
|
|
||||||
|
|
||||||
|
Example
|
||||||
|
|
||||||
|
class XCustom extends PolymerElement {
|
||||||
|
|
||||||
|
static get properties() {
|
||||||
|
return {
|
||||||
|
user: String,
|
||||||
|
isHappy: Boolean,
|
||||||
|
count: {
|
||||||
|
type: Number,
|
||||||
|
readOnly: true,
|
||||||
|
notify: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
customElements.define('x-custom', XCustom);
|
||||||
|
|
||||||
|
|
||||||
|
### Property name to attribute name mapping
|
||||||
|
|
||||||
|
When mapping attribute names to property names:
|
||||||
|
|
||||||
|
-Attribute names are converted to lowercase property names. For example, the attribute "firstName" maps to "firstname".
|
||||||
|
|
||||||
|
- Attribute names with dashes are converted to camelCase property names by capitalizing the character following each dash,then removing the dashes. For example, the attribute "first-name" maps to "firstName".
|
||||||
|
|
||||||
|
|
||||||
|
### Configuring object and array properties
|
||||||
|
|
||||||
|
For object and array properties you can pass an object or array in JSON format:
|
||||||
|
|
||||||
|
<my-element book='{ "title": "Persuasion", "author": "Austen" }'></my-element>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Configuring default property values
|
||||||
|
Default values for properties may be specified in the properties object using the value field, or set imperatively in the element's constructor.
|
||||||
|
|
||||||
|
|
||||||
|
**Default in properties object**
|
||||||
|
|
||||||
|
class XCustom extends PolymerElement {
|
||||||
|
|
||||||
|
static get properties() {
|
||||||
|
return {
|
||||||
|
mode: {
|
||||||
|
type: String,
|
||||||
|
value: 'auto'
|
||||||
|
},
|
||||||
|
|
||||||
|
data: {
|
||||||
|
type: Object,
|
||||||
|
notify: true,
|
||||||
|
value: function() { return {}; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
**Default in constructor**
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.mode = 'auto';
|
||||||
|
this.data = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
static get properties() {
|
||||||
|
return {
|
||||||
|
mode: String,
|
||||||
|
|
||||||
|
data: {
|
||||||
|
type: Object,
|
||||||
|
notify: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
### Property change notification events (notify)
|
||||||
|
|
||||||
|
When a property is set to notify: true, an event is fired whenever the property value changes. The event name is:
|
||||||
|
|
||||||
|
**property-name-changed**
|
||||||
|
|
||||||
|
Where property-name is the dash-case version of the property name. For example, a change to **this.firstName** fires **first-name-changed**.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Read-only properties
|
||||||
|
|
||||||
|
When a property only "produces" data and never consumes data, this can be made explicit to avoid accidental changes from the host by setting the readOnly flag to true in the properties property definition. In order for the element to actually change the value of the property, it must use a private generated setter of the convention **_setProperty(value)** where Property is the property name, with the first character converted to uppercase (if alphabetic). For example, the setter for **oneProperty** is **_setOneProperty**, and the setter for**_privateProperty** is **_set_privateProperty**.
|
||||||
|
|
||||||
|
|
||||||
|
class XCustom extends PolymerElement {
|
||||||
|
|
||||||
|
static get properties() {
|
||||||
|
return {
|
||||||
|
response: {
|
||||||
|
type: Object,
|
||||||
|
readOnly: true,
|
||||||
|
notify: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
responseHandler(response) {
|
||||||
|
// set read-only property
|
||||||
|
this._setResponse(response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
### Reflecting properties to attributes
|
||||||
|
In specific cases, it may be useful to keep an HTML attribute value in sync with a property value. This may be achieved by setting **reflectToAttribute: true **on a property in the properties configuration object. This causes any observable change to the property to trigger an update to the corresponding attribute.Since attributes only take string values, the property value is serialized to a string.For Example,
|
||||||
|
|
||||||
|
class XCustom extends PolymerElement {
|
||||||
|
|
||||||
|
static get properties() {
|
||||||
|
return {
|
||||||
|
loaded: {
|
||||||
|
type: Boolean,
|
||||||
|
reflectToAttribute: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_onLoad() {
|
||||||
|
this.loaded = true;
|
||||||
|
// results in this.setAttribute('loaded', true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Custom deserializers
|
||||||
|
|
||||||
|
The type system includes built-in support for Boolean and Number values, Object and Array values expressed as JSON, or Date objects expressed as any Date-parsable string representation. To support other types, you can override the element's **_deserializeValue** method.
|
||||||
|
|
||||||
|
|
||||||
|
_deserializeValue(value, type) {
|
||||||
|
if (type == MyCustomType) {
|
||||||
|
return stringToMyCustomType(value);
|
||||||
|
} else {
|
||||||
|
return super._deserializeValue(value, type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Attribute serialization
|
||||||
|
|
||||||
|
When reflecting a property to an attribute or binding a property to an attribute, the property value is serialized to the attribute.
|
||||||
|
|
||||||
|
By default, values are serialized according to value's current type, regardless of the property's type value:
|
||||||
|
|
||||||
|
*String. No serialization required.
|
||||||
|
*Date or Number. Serialized using toString.
|
||||||
|
*Boolean. Results in a non-valued attribute to be either set (true) or removed (false).
|
||||||
|
*Array or Object. Serialized using JSON.stringify.
|
||||||
|
|
||||||
|
To add custom serialization for other data types, override your element's **_serializeValue** method.
|
||||||
|
|
||||||
|
_serializeValue(value) {
|
||||||
|
if (value instanceof MyCustomType) {
|
||||||
|
return value.toString();
|
||||||
|
}
|
||||||
|
return super._serializeValue(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Define a legacy element
|
||||||
|
|
||||||
|
Legacy elements can use use the Polymer function to register an element. The function takes as its argument the prototype for the new element. The prototype must have an is property that specifies the HTML tag name for your custom element.For Examples,
|
||||||
|
|
||||||
|
// register an element
|
||||||
|
MyElement = Polymer({
|
||||||
|
|
||||||
|
is: 'my-element',
|
||||||
|
|
||||||
|
// See below for lifecycle callbacks
|
||||||
|
created: function() {
|
||||||
|
this.textContent = 'My element!';
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
// create an instance with createElement:
|
||||||
|
var el1 = document.createElement('my-element');
|
||||||
|
|
||||||
|
// ... or with the constructor:
|
||||||
|
var el2 = new MyElement();
|
||||||
|
|
||||||
|
|
||||||
|
### Legacy lifecycle callbacks
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
legacy callback Description
|
||||||
|
|
||||||
|
|
||||||
|
created -Called when the element has been created, but before property values are set and local DOM is initialized.Use for one-time set-up before property values are set.Equivalent to the native constructor.
|
||||||
|
|
||||||
|
|
||||||
|
ready -Called after property values are set and local DOM is initialized.Use for one-time configuration of your component after its shadow DOM tree is initialized.
|
||||||
|
|
||||||
|
attached -Called after the element is attached to the document.
|
||||||
|
|
||||||
|
detached -Called after the element is detached from the document.
|
||||||
|
|
||||||
|
attributeChanged -Called when one of the element's attributes is changed.
|
||||||
|
|
||||||
|
|
||||||
|
**Using legacy behaviors with class-style elements**
|
||||||
|
|
||||||
|
You can add legacy behaviors to your class-style element using the mixinBehavior function:
|
||||||
|
|
||||||
|
import {PolymerElement} from '@polymer/polymer/lib/legacy/class.js';
|
||||||
|
import {mixinBehaviors} from '@polymer/polymer/polymer-element.js';
|
||||||
|
|
||||||
|
class XClass extends Polymer.mixinBehaviors([MyBehavior, MyBehavior2], PolymerElement) {
|
||||||
|
|
||||||
|
...
|
||||||
|
}
|
||||||
|
customElements.define('x-class', XClass);
|
||||||
|
|
||||||
|
|
||||||
|
# LitElement
|
||||||
|
## A simple base class for creating custom elements rendered with lit-html.
|
||||||
|
|
||||||
|
LitElement uses lit-html to render into the element's Shadow DOM and Polymer's PropertiesMixin
|
||||||
|
to help manage element properties and attributes. LitElement reacts to changes in properties
|
||||||
|
and renders declaratively using `lit-html`.
|
||||||
|
|
||||||
|
* **React to changes:** LitElement reacts to changes in properties and attributes by
|
||||||
|
asynchronously rendering, ensuring changes are batched. This reduces overhead
|
||||||
|
and maintains consistent state.
|
||||||
|
|
||||||
|
* **Declarative rendering** LitElement uses `lit-html` to declaratively describe
|
||||||
|
how an element should render. Then `lit-html` ensures that updates
|
||||||
|
are fast by creating the static DOM once and smartly updating only the parts of
|
||||||
|
the DOM that change. Pass a JavaScript string to the `html` tag function,
|
||||||
|
describing dynamic parts with standard JavaScript template expressions:
|
||||||
|
|
||||||
|
* static elements: ``` html`<div>Hi</div>` ```
|
||||||
|
* expression: ``` html`<div>${disabled ? 'Off' : 'On'}</div>` ```
|
||||||
|
* attribute: ``` html`<div class$="${color} special"></div>` ```
|
||||||
|
* event handler: ``` html`<button on-click="${(e) => this._clickHandler(e)}"></button>` ```
|
||||||
|
|
||||||
|
|
||||||
|
## Getting started
|
||||||
|
|
||||||
|
* The easiest way to try out LitElement is to use one of these online tools:
|
||||||
|
|
||||||
|
* Runs in all supported browsers: StackBlitz, Glitch
|
||||||
|
* Runs in browsers with JavaScript Modules: JSFiddle, JSBin, CodePen.
|
||||||
|
* You can also copy this HTML file into a local file and run it in any browser that supports JavaScript Modules.
|
||||||
|
|
||||||
|
* When you're ready to use LitElement in a project, install it via npm. To run the project in the browser, a module-compatible toolchain is required. We recommend installing the Polymer CLI and using its development server as follows.
|
||||||
|
|
||||||
|
|
||||||
|
1. Add LitElement to your project:
|
||||||
|
|
||||||
|
```npm i @polymer/lit-element```
|
||||||
|
|
||||||
|
2. Create an element by extending LitElement and calling `customElements.define` with your class (see the examples below).
|
||||||
|
|
||||||
|
3. Install the Polymer CLI:
|
||||||
|
|
||||||
|
```npm i -g polymer-cli@next```
|
||||||
|
|
||||||
|
4. Run the development server and open a browser pointing to its URL:
|
||||||
|
|
||||||
|
```polymer serve```
|
||||||
|
|
||||||
|
> LitElement is published on [npm](https://www.npmjs.com/package/@polymer/lit-element) using JavaScript Modules.
|
||||||
|
This means it can take advantage of the standard native JavaScript module loader available in all current major browsers.
|
||||||
|
>
|
||||||
|
> However, since LitElement uses npm convention to reference dependencies by name, a light transform to rewrite specifiers to URLs is required to get it to run in the browser. The polymer-cli's development server `polymer serve` automatically handles this transform.
|
||||||
|
|
||||||
|
Tools like [WebPack](https://webpack.js.org/) and [Rollup](https://rollupjs.org/) can also be used to serve and/or bundle LitElement.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Minimal Example
|
||||||
|
|
||||||
|
1. Create a class that extends `LitElement`.
|
||||||
|
2. Implement a static `properties` getter that returns the element's properties
|
||||||
|
(which automatically become observed attributes).
|
||||||
|
3. Then implement a `_render(props)` method and use the element's
|
||||||
|
current properties (props) to return a `lit-html` template result to render
|
||||||
|
into the element. This is the only method that must be implemented by subclasses.
|
||||||
|
|
||||||
|
```html
|
||||||
|
<script src="node_modules/@webcomponents/webcomponents-bundle.js"></script>
|
||||||
|
<script type="module">
|
||||||
|
import {LitElement, html} from '@polymer/lit-element';
|
||||||
|
|
||||||
|
class MyElement extends LitElement {
|
||||||
|
|
||||||
|
static get properties() { return { mood: String }}
|
||||||
|
|
||||||
|
_render({mood}) {
|
||||||
|
return html`<style> .mood { color: green; } </style>
|
||||||
|
Web Components are <span class="mood">${mood}</span>!`;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
customElements.define('my-element', MyElement);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<my-element mood="happy"></my-element>
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
353
Dart.md
Normal file
353
Dart.md
Normal file
@@ -0,0 +1,353 @@
|
|||||||
|
## Dart
|
||||||
|
- Dart is the language behind flutter
|
||||||
|
- Dart is an object oriented language
|
||||||
|
- can run on Android,ios,desktop and web
|
||||||
|
|
||||||
|
### Variable Delecartion and Initialization
|
||||||
|
- store values and reference them multiple times
|
||||||
|
- Variable name should start with small letter.
|
||||||
|
- Variable name should be declared in camelCase.
|
||||||
|
- Combination of lowercase and uppercase letter, as well as all digits from 0 to 9 and the underscore character like this
|
||||||
|
- first character cannot be a digit
|
||||||
|
|
||||||
|
### String Concatenation and Interpolation
|
||||||
|
To concatenate two string use "+" sign .
|
||||||
|
Can also use "$" sign inside the string.
|
||||||
|
e.g print("My name is $firstName $lastname")
|
||||||
|
|
||||||
|
Interpolation can evaluate an expression inside a string with the ${} syntax.
|
||||||
|
e.g print('Sum is ${num1 + num2})
|
||||||
|
|
||||||
|
### String Escaping
|
||||||
|
Write the backslash before the single quote inside the string.
|
||||||
|
e.g print('Today I\'m feel good')
|
||||||
|
|
||||||
|
Can solve with double quote too.
|
||||||
|
e.g print("Today I'm feel good")
|
||||||
|
|
||||||
|
You can make a "raw" string by prefixing it with r
|
||||||
|
e.g print(r'C:\Window\System 32')
|
||||||
|
|
||||||
|
### Multiline String
|
||||||
|
Use a triple quote (''' or """), with either single quote or double quote at the beginning and at the end.
|
||||||
|
|
||||||
|
e.g print( '''
|
||||||
|
the initial newline is ignored
|
||||||
|
but the last newline is not ignored
|
||||||
|
''');
|
||||||
|
|
||||||
|
### Ternary Operator
|
||||||
|
The conditional operator is considered as short hand for if-else statement. Conditional operator is also called as “Ternary Operator”.
|
||||||
|
|
||||||
|
result = testCondition ? trueValue : falseValue
|
||||||
|
|
||||||
|
### Type inference with "var"
|
||||||
|
We don't need to declare variable type explicitly,can use "var" instead.
|
||||||
|
Can be set more than once.
|
||||||
|
|
||||||
|
### The final keyword
|
||||||
|
The final keyword is used to hardcode the values of the variable and it cannot be altered in future, neither any kind of operations performed on these variables can alter its value (state).
|
||||||
|
-final means read only (can only be set once)
|
||||||
|
-If we try to reassign the same variable then it will display error.
|
||||||
|
|
||||||
|
e.g void main() {
|
||||||
|
final geek1 = "Geeks For Geeks";
|
||||||
|
print(geek1);
|
||||||
|
|
||||||
|
// Can't reassign like this
|
||||||
|
geek1 = "Geeks For Geeks Again!!"; /
|
||||||
|
|
||||||
|
// Assigning value to geek2
|
||||||
|
// variable with datatype
|
||||||
|
final String geek2 = "Geeks For Geeks Again!!";
|
||||||
|
|
||||||
|
// Printing variable geek2
|
||||||
|
print(geek2);
|
||||||
|
}
|
||||||
|
|
||||||
|
### The Const Keyword
|
||||||
|
The const keyword in Dart behaves exactly like the final keyword. The only difference between final and const is that the const makes the variable constant from compile-time only. Using const on an object, makes the object’s entire deep state strictly fixed at compile-time and that the object with this state will be considered frozen and completely immutable.
|
||||||
|
|
||||||
|
### Using var,final,const with lists
|
||||||
|
-You can declare list variables as var,final,const.
|
||||||
|
-Final and Const variables can only be set once.
|
||||||
|
-Final variables can't be re-assigned but you can still modify their contents.
|
||||||
|
-But not with const variable.
|
||||||
|
|
||||||
|
### Sets and List
|
||||||
|
-Sets are collection of unique values using curly brackets.
|
||||||
|
-Lists can contain duplicate values using square brackets.
|
||||||
|
-Sets can use union method, intersection and difference method.
|
||||||
|
|
||||||
|
### Map
|
||||||
|
-Used to store a collection of key value pairs.
|
||||||
|
-When declaring a Map with var/final/const, key and values can have any type we want.
|
||||||
|
-You can add type annotations to lists, sets and maps literals.Type annotations are not required but they help you wirte safer code.
|
||||||
|
e.g Map <String, dynamic> person ={
|
||||||
|
'name' : 'Lilly',
|
||||||
|
'age' : 20,
|
||||||
|
};
|
||||||
|
|
||||||
|
### As Operator
|
||||||
|
If you declare a map with dynamic values and want to assign map values to variables of specific type,you can use the 'as' operator.
|
||||||
|
e.g Map <String, dynamic> person ={
|
||||||
|
'name' : 'Lilly',
|
||||||
|
'age' : 20,
|
||||||
|
};
|
||||||
|
var name = person ['name'] as String;
|
||||||
|
print(name);
|
||||||
|
|
||||||
|
|
||||||
|
### Spreads
|
||||||
|
"..." adds the elements of a list to the enclosing list/collection.
|
||||||
|
e.g final colors =[
|
||||||
|
'green','gret',
|
||||||
|
...['black','cyan'],
|
||||||
|
];
|
||||||
|
|
||||||
|
### The assertion operator(!)
|
||||||
|
-assign nullable value to non-nullable value.
|
||||||
|
-IF we're sure that a nullable variable will always have a non-nullable value,we can use the assertion operator(!).
|
||||||
|
-'!' is also called the bang operator.
|
||||||
|
e.g void main(){
|
||||||
|
int x = 7;
|
||||||
|
|
||||||
|
//To indicate that a variable might have the value null, just add ?
|
||||||
|
int ? maybeValue;
|
||||||
|
|
||||||
|
if (x > 0){
|
||||||
|
maybeValue =x;
|
||||||
|
}
|
||||||
|
// valid, value is non-nullable
|
||||||
|
int value = maybeValue !;
|
||||||
|
print(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
### Functions
|
||||||
|
-encapsulate some code and reuse it multiple times
|
||||||
|
eg:
|
||||||
|
void main(){
|
||||||
|
sayHi();
|
||||||
|
}
|
||||||
|
|
||||||
|
void sayHi(){
|
||||||
|
print('Hi');
|
||||||
|
print('Welcome');
|
||||||
|
}
|
||||||
|
|
||||||
|
### Required and default values
|
||||||
|
1.Without null safety : arguments can be omitted.
|
||||||
|
2.With null safety:
|
||||||
|
-make arguments nullable (e.g {String ? name})
|
||||||
|
-make arguments non-nullable
|
||||||
|
use a default value ( e.g {String name = 'Andera'})
|
||||||
|
mark them as required ( e.g {required String name})
|
||||||
|
3.Null safety gives you compile-time guarantees about what can and cannot be null.
|
||||||
|
|
||||||
|
### Fat arrow notation(=>)
|
||||||
|
Need a function body with only one statement?Use the "=>" notation.
|
||||||
|
|
||||||
|
eg: int sum (int x,int y)=>x + y;
|
||||||
|
|
||||||
|
### The where and firstWhere methods
|
||||||
|
where :filter items inside a collection
|
||||||
|
firstWhere :find an item inside a collection
|
||||||
|
eg:
|
||||||
|
void main(){
|
||||||
|
cost list =[1,2,3,4];
|
||||||
|
final even =list.where((value)=>value % 2 == 0);
|
||||||
|
final value =list.firstWhere((x)=>x == 4,orElse:()=> -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
### The reduce method
|
||||||
|
-Used to combine all items inside a list and produce a single result.
|
||||||
|
eg:
|
||||||
|
void main(){
|
||||||
|
cost list =[1,2,3,4];
|
||||||
|
final sum =list.reduce((previousValue,element)=>previousValue + element);
|
||||||
|
}
|
||||||
|
|
||||||
|
### Const constructors
|
||||||
|
Have a class where all variables are final?User a 'const' constructor.
|
||||||
|
eg:
|
||||||
|
class Complex{
|
||||||
|
const Complex(this.re,this.im);
|
||||||
|
final double re;
|
||||||
|
final double im;
|
||||||
|
}
|
||||||
|
|
||||||
|
### Static methods and variables
|
||||||
|
-The static variables belong to the class instead of a specific instance. A static variable is common to all instances of a class: this means only a single copy of the static variable is shared among all the instances of a class. The memory allocation for static variables happens only once in the class area at the time of class loading.
|
||||||
|
-Use static const to define a global constant that belonds to a class.
|
||||||
|
-Static variables can be declared using the static keyword followed by data type then the variable name
|
||||||
|
e.g static [date_type] [variable_name];
|
||||||
|
|
||||||
|
-The static variable can be accessed directly from the class name itself rather than creating an instance of it.
|
||||||
|
e.g Classname.staticVariable;
|
||||||
|
|
||||||
|
|
||||||
|
### Private variables and methods
|
||||||
|
-Encapsulate things that should not be accessible outside a class.
|
||||||
|
-You cannot directly access a private name from a different library
|
||||||
|
-Private identifier in Dart start with an underscore. ( e.g _balance, _ 123)
|
||||||
|
|
||||||
|
### Abstract classes
|
||||||
|
-connot be instantiated
|
||||||
|
-to define an interface that can be implemented by subclasses
|
||||||
|
-You can always assign an instance of a subclass to a variable of the parent class
|
||||||
|
eg:
|
||||||
|
abstract class Shape{
|
||||||
|
double get area;
|
||||||
|
}
|
||||||
|
|
||||||
|
class Square extends Shape{
|
||||||
|
Square(this.side);
|
||||||
|
final double side;
|
||||||
|
|
||||||
|
@override
|
||||||
|
double get area=>side * side;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main(){
|
||||||
|
// final shape =Shape();
|
||||||
|
final square =Square(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
### Difference between implements and extends
|
||||||
|
keyword type abstract methods concrete method
|
||||||
|
|
||||||
|
-extends single must override can override
|
||||||
|
|
||||||
|
-implements multiple must override must override
|
||||||
|
|
||||||
|
### Copying objects with copyWith
|
||||||
|
If yout need copy-behaviour in your immutable classes,create a 'copyWith' method.
|
||||||
|
eg:
|
||||||
|
class Credentials {
|
||||||
|
final String email;
|
||||||
|
final String password;
|
||||||
|
|
||||||
|
const Credentials({this.email = '', this.password = ''});
|
||||||
|
|
||||||
|
Credentials copyWith({
|
||||||
|
String? email,
|
||||||
|
String? password,
|
||||||
|
}) {
|
||||||
|
return Credentials(
|
||||||
|
email: email ?? this.email,
|
||||||
|
password: password ?? this.password,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => 'Credentials($email,$password)';
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
const credentials = Credentials();
|
||||||
|
final update = credentials.copyWith(email: "example@gamil.com");
|
||||||
|
print(update);
|
||||||
|
}
|
||||||
|
|
||||||
|
### Mixins
|
||||||
|
-to share functionality in multiple classes without code duplication
|
||||||
|
-Mixins can't be instantiated
|
||||||
|
eg:
|
||||||
|
|
||||||
|
mixin Swimming {
|
||||||
|
void swim() => print('swimming');
|
||||||
|
}
|
||||||
|
|
||||||
|
class Animal {
|
||||||
|
void breathe() => print('breathing');
|
||||||
|
}
|
||||||
|
|
||||||
|
class Fish extends Animal with Swimming {}
|
||||||
|
|
||||||
|
class Human extends Animal with Swimming {}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
final fish = Fish();
|
||||||
|
fish.swim();
|
||||||
|
final human = Human();
|
||||||
|
human.swim();
|
||||||
|
}
|
||||||
|
|
||||||
|
### Extensions
|
||||||
|
-add functionality to existing classes,without modifying them.
|
||||||
|
-only named extensions can be imported
|
||||||
|
eg:
|
||||||
|
extensins.dart
|
||||||
|
import number_parsing.dart;
|
||||||
|
void main(){
|
||||||
|
int.tryParse('123');
|
||||||
|
'123'.toIntOrNull();
|
||||||
|
'456'.toIntOrNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
number_parsing.dart
|
||||||
|
extension numberParsing on String{
|
||||||
|
int? toIntOrNull()=>int.tryParse(this);
|
||||||
|
}
|
||||||
|
### Asynchronous
|
||||||
|
Asynchronous operation let your program complete work while waiting for another operation to finish.
|
||||||
|
-Fetching data from network
|
||||||
|
-Writing to a database
|
||||||
|
-Reading data from file
|
||||||
|
|
||||||
|
### Future
|
||||||
|
- A future represents the result of an asynchronous operation, and can have two states: uncompleted or completed.
|
||||||
|
-A future can't listen to a variable change.
|
||||||
|
-It's a one-time response.
|
||||||
|
|
||||||
|
### Async and await
|
||||||
|
Async
|
||||||
|
- You can use the async keyword before a function’s body to mark it as asynchronous.
|
||||||
|
|
||||||
|
Await
|
||||||
|
-You can use the await keyword to get the completed result of an asynchronous expression. The await keyword only works within an async function.
|
||||||
|
-Await is only allowed inside async functions
|
||||||
|
-To wait until a future completes
|
||||||
|
|
||||||
|
Future<String> createOrderMessage() async {
|
||||||
|
var order = await fetchUserOrder();
|
||||||
|
return 'Your order is: $order';
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<String> fetchUserOrder() =>
|
||||||
|
// Imagine that this function is
|
||||||
|
// more complex and slow.
|
||||||
|
Future.delayed(
|
||||||
|
Duration(seconds: 2),
|
||||||
|
() => 'Large Latte',
|
||||||
|
);
|
||||||
|
|
||||||
|
Future<void> main() async {
|
||||||
|
print('Fetching user order...');
|
||||||
|
print(await createOrderMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
### Stream
|
||||||
|
-Streams provide an asynchronous sequence of data.
|
||||||
|
-There are two kinds of streams: single subscription or broadcast.
|
||||||
|
|
||||||
|
Future<int> sumStream(Stream<int> stream) async {
|
||||||
|
var sum = 0;
|
||||||
|
await for (var value in stream) {
|
||||||
|
sum += value;
|
||||||
|
}
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
Stream<int> countStream(int to) async* {
|
||||||
|
for (int i = 1; i <= to; i++) {
|
||||||
|
yield i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> main() async {
|
||||||
|
var stream = countStream(10);
|
||||||
|
var sum = await sumStream(stream);
|
||||||
|
print(sum); // 55
|
||||||
|
}
|
||||||
|
|
||||||
873
DataSystem.md
Executable file
873
DataSystem.md
Executable file
@@ -0,0 +1,873 @@
|
|||||||
|
# Data system concepts
|
||||||
|
|
||||||
|
1. Observers- Callbacks invoked when data changes.
|
||||||
|
|
||||||
|
2. Computed properties- Virtual properties computed based on other properties, and recomputed when the input data changes.
|
||||||
|
|
||||||
|
3. Data bindings- Annotations that update the properties, attributes, or text content of a DOM node when data changes.
|
||||||
|
|
||||||
|
Simple element:
|
||||||
|
|
||||||
|
class NameCard extends PolymerElement {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.name = {first: 'Kai', last: 'Li'};
|
||||||
|
}
|
||||||
|
static get template() {
|
||||||
|
return html `
|
||||||
|
<div>[[name.first]] [[name.last]]</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
customElements.define('name-card', NameCard);
|
||||||
|
|
||||||
|
|
||||||
|
1. The `<name-card>` element has a name property that refers to a JavaScript object.
|
||||||
|
|
||||||
|
|
||||||
|
2. The `<name-card>` element hosts a local DOM tree, that contains a single <div> element.
|
||||||
|
|
||||||
|
|
||||||
|
3. Data bindings in the template link the JavaScript object to the <div> element.
|
||||||
|
|
||||||
|
|
||||||
|
For example,
|
||||||
|
|
||||||
|
the `<name-card>` element has data bindings for the paths "name.first" and "name.last"
|
||||||
|
|
||||||
|
|
||||||
|
## Observable changes
|
||||||
|
-Setting a direct property of the element.
|
||||||
|
|
||||||
|
this.owner = 'Jane';
|
||||||
|
|
||||||
|
-Setting a subproperty of the element using a two way data binding.
|
||||||
|
|
||||||
|
<local-dom-child name="{{hostProperty.subProperty}}"></local-dom-child>
|
||||||
|
|
||||||
|
## Unobservable changes
|
||||||
|
|
||||||
|
-Setting a subproperty of an object.
|
||||||
|
|
||||||
|
// unobservable subproperty change
|
||||||
|
this.address.street = 'Elm Street';
|
||||||
|
|
||||||
|
-Mutating an array:
|
||||||
|
|
||||||
|
// unobservable change using native Array.push
|
||||||
|
this.users.push({ name: 'Maturin'});
|
||||||
|
|
||||||
|
## Mutating objects and arrays observably
|
||||||
|
Polymer provides methods for making observable changes to subproperties and arrays:
|
||||||
|
|
||||||
|
// mutate an object observably
|
||||||
|
this.set('address.street', 'Half Moon Street');
|
||||||
|
|
||||||
|
// mutate an array observably
|
||||||
|
this.push('users', { name: 'Maturin'});
|
||||||
|
|
||||||
|
#### Batched property changes
|
||||||
|
|
||||||
|
You can atomically set multiple properties using the setProperties method.
|
||||||
|
|
||||||
|
this.setProperties({item: 'Orange', count: 12 });
|
||||||
|
|
||||||
|
For example,
|
||||||
|
|
||||||
|
// observer fires twice
|
||||||
|
this.a = 10;
|
||||||
|
this.b = 20;
|
||||||
|
|
||||||
|
// observer fires once
|
||||||
|
this.setProperties({a: 10, b: 20});
|
||||||
|
The two types of data binding annotations are:
|
||||||
|
|
||||||
|
|
||||||
|
### 1 - Automatic,
|
||||||
|
which allows upward (target to host) and downwards (host to target) data flow. Automatic bindings use double curly brackets ({{ }}):
|
||||||
|
|
||||||
|
<my-input value="{{name}}"></my-input>
|
||||||
|
### 2 - One-way,
|
||||||
|
which only allows downwards data flow. Upward data flow is disabled. One-way bindings use double square brackets ([[ ]]).
|
||||||
|
|
||||||
|
<name-tag name="[[name]]"></name-tag>
|
||||||
|
|
||||||
|
#### Example of one-way binding (downward)
|
||||||
|
|
||||||
|
class XHost extends PolymerElement {
|
||||||
|
static get template() {
|
||||||
|
return html`
|
||||||
|
<x-target some-prop="[[value]]"></x-target>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
....................
|
||||||
|
|
||||||
|
...
|
||||||
|
class XTarget extends PolymerElement {
|
||||||
|
static get properties() {
|
||||||
|
return {
|
||||||
|
someProp: {
|
||||||
|
type: String //no notify: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
...
|
||||||
|
|
||||||
|
...
|
||||||
|
class XHost extends PolymerElement {
|
||||||
|
static get template() {
|
||||||
|
return html`
|
||||||
|
<!-- changes to "value" propagate downward to "someProp" on target -->
|
||||||
|
<!-- changes to "someProp" are not notified to host due to notify:falsey -->
|
||||||
|
<x-target some-prop="{{value}}"></x-target>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
...
|
||||||
|
|
||||||
|
#### Example of one-way binding (upward, child-to-host)
|
||||||
|
|
||||||
|
|
||||||
|
...
|
||||||
|
class XTarget extends PolymerElement {
|
||||||
|
static get properties() {
|
||||||
|
return {
|
||||||
|
someProp: {
|
||||||
|
type: String,
|
||||||
|
notify: true,
|
||||||
|
readOnly: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
...
|
||||||
|
customElements.define('x-target', XTarget);
|
||||||
|
...
|
||||||
|
|
||||||
|
class XHost extends PolymerElement {
|
||||||
|
static get template() {
|
||||||
|
return html`
|
||||||
|
<!-- changes to "value" are ignored by child because "someProp" is read-only -->
|
||||||
|
<!-- changes to "someProp" propagate upward to "value" on host -->
|
||||||
|
<x-target some-prop="{{value}}"></x-target>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
...
|
||||||
|
customElements.define('x-host', XHost);
|
||||||
|
|
||||||
|
#### Example of no data flow / nonsensical state
|
||||||
|
|
||||||
|
...
|
||||||
|
class XTarget extends PolymerElement {
|
||||||
|
static get properties() {
|
||||||
|
return {
|
||||||
|
someProp: {
|
||||||
|
type: String,
|
||||||
|
notify: true,
|
||||||
|
readOnly: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
...
|
||||||
|
customElements.define('x-target', XTarget);
|
||||||
|
...
|
||||||
|
|
||||||
|
class XHost extends PolymerElement {
|
||||||
|
static get template() {
|
||||||
|
return html`
|
||||||
|
<!-- changes to "value" are ignored by child because "someProp" is read-only -->
|
||||||
|
<!-- changes to "someProp" don't propagate upward because of the one-way binding -->
|
||||||
|
<x-target some-prop="[[value]]"></x-target>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
...
|
||||||
|
customElements.define('x-host', XHost);
|
||||||
|
|
||||||
|
|
||||||
|
## Property effects
|
||||||
|
|
||||||
|
1. Computed properties.
|
||||||
|
2. Data bindings.
|
||||||
|
3. Reflected values.
|
||||||
|
4. Observers.
|
||||||
|
5. Change notification events.
|
||||||
|
|
||||||
|
|
||||||
|
#### Data bindings
|
||||||
|
|
||||||
|
Two-way property binding:
|
||||||
|
|
||||||
|
target-property="{{hostProperty}}"
|
||||||
|
|
||||||
|
One-way property binding:
|
||||||
|
|
||||||
|
target-property="[[hostProperty]]"
|
||||||
|
|
||||||
|
Attribute binding:
|
||||||
|
|
||||||
|
target-attribute$="[[hostProperty]]"
|
||||||
|
|
||||||
|
# Work with object and array data
|
||||||
|
|
||||||
|
Get a value by path
|
||||||
|
Use the get method to retrieve a value based on its path.
|
||||||
|
|
||||||
|
// retrieve a subproperty by path
|
||||||
|
|
||||||
|
var value = this.get('myProp.subProp');
|
||||||
|
// Retrieve the 11th item in myArray
|
||||||
|
|
||||||
|
var item = this.get(['myArray', 11])
|
||||||
|
|
||||||
|
### Set a property or subproperty by path
|
||||||
|
Use the set method to make an observable change to a subproperty.
|
||||||
|
|
||||||
|
// clear an array
|
||||||
|
this.set('group.members', []);
|
||||||
|
|
||||||
|
// set a subproperty
|
||||||
|
this.set('profile.name', 'Alex');
|
||||||
|
|
||||||
|
### Working with arrays
|
||||||
|
Example
|
||||||
|
|
||||||
|
import { PolymerElement, html } from '@polymer/polymer/polymer-element.js';
|
||||||
|
import '@polymer/polymer/lib/elements/dom-repeat.js';
|
||||||
|
|
||||||
|
class XCustom extends PolymerElement {
|
||||||
|
static get template() {
|
||||||
|
return html`
|
||||||
|
<template is="dom-repeat" items="[[users]]"><p>{{item}}</p></template>
|
||||||
|
<p><button on-click="addUser">add</button><button on-click="removeUser">remove</button><button on-click="_reset">reset</button></p>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this._reset();
|
||||||
|
}
|
||||||
|
addUser() {
|
||||||
|
var user = "wing sang";
|
||||||
|
this.push('users', user);
|
||||||
|
}
|
||||||
|
removeUser() {
|
||||||
|
var user = "wing sang";
|
||||||
|
var index = this.users.indexOf(user);
|
||||||
|
this.splice('users', index, 1);
|
||||||
|
}
|
||||||
|
_reset() {
|
||||||
|
this.users=["wing sang", "deshaun", "kelley"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
customElements.define('x-custom', XCustom);
|
||||||
|
|
||||||
|
### Batch multiple property changes
|
||||||
|
|
||||||
|
Use **setProperties** method to make a batch change to a set of properties. This ensures the property changes run as a coherent set.
|
||||||
|
|
||||||
|
this.setProperties({
|
||||||
|
date: 'Jan 17, 2017',
|
||||||
|
verified: true
|
||||||
|
});
|
||||||
|
|
||||||
|
**setProperties** supports an optional **setReadOnly** flag as the second parameter. If you need to set read-only properties as part of a batch change, pass true for the second parameter:
|
||||||
|
|
||||||
|
this.setProperties({
|
||||||
|
date: 'Jan 17, 2017',
|
||||||
|
verified: true
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
#### Link two paths to the same object
|
||||||
|
|
||||||
|
linkPaths('selectedUser', 'users.1');
|
||||||
|
|
||||||
|
|
||||||
|
To remove a path linkage, call **unlinkPaths**, passing in the first path you passed to linkPaths:
|
||||||
|
|
||||||
|
unlinkPaths('selectedUser');
|
||||||
|
|
||||||
|
|
||||||
|
# Observers and computed properties
|
||||||
|
- Simple observers observe a single property.
|
||||||
|
- Complex observers can observe one or more properties or paths.
|
||||||
|
|
||||||
|
## Simple observers
|
||||||
|
Simple observers are declared in the properties object, and always observe a single property.
|
||||||
|
Simple observers only fire when the property itself changes. They don't fire on subproperty changes, or array mutation. If you need these changes, use a complex observer with a wildcard path
|
||||||
|
|
||||||
|
### Observe a property
|
||||||
|
Define a simple observer by adding an observer key to the property's declaration, identifying the observer method by name.
|
||||||
|
|
||||||
|
Example
|
||||||
|
|
||||||
|
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||||
|
|
||||||
|
class XCustom extends PolymerElement {
|
||||||
|
static get properties() {
|
||||||
|
return {
|
||||||
|
active: {
|
||||||
|
type: Boolean,
|
||||||
|
// Observer method identified by name
|
||||||
|
observer: '_activeChanged'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Observer method defined as a class method
|
||||||
|
_activeChanged(newValue, oldValue) {
|
||||||
|
this.toggleClass('highlight', newValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
customElements.define('x-custom', XCustom);
|
||||||
|
|
||||||
|
|
||||||
|
The observer method is usually defined on the class itself, although an observer method can also be defined by a superclass, subclass, or a class mixin, as long as the named method exists on the element.
|
||||||
|
|
||||||
|
## Complex observers
|
||||||
|
Complex observers are declared in the observers array. Complex observers can monitor one or more paths. These paths are called the observer's dependencies.
|
||||||
|
|
||||||
|
static get observers() {
|
||||||
|
return [
|
||||||
|
// Observer method name, followed by a list of dependencies, in parenthesis
|
||||||
|
'userListChanged(users.*, filter)'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
Each dependency represents:
|
||||||
|
|
||||||
|
- A specific property (for example, firstName).
|
||||||
|
|
||||||
|
- A specific subproperty (for example, address.street).
|
||||||
|
|
||||||
|
- Mutations on a specific array (for example, users.splices).
|
||||||
|
|
||||||
|
- All subproperty changes and array mutations below a given path (for example, users.*).
|
||||||
|
|
||||||
|
### Observe changes to multiple properties
|
||||||
|
|
||||||
|
To observe changes to a set of properties, use the observers array.
|
||||||
|
|
||||||
|
Observers do not receive old values as arguments, only new values. Only single-property observers defined in the properties object receive both old and new values.
|
||||||
|
|
||||||
|
|
||||||
|
Example
|
||||||
|
|
||||||
|
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||||
|
|
||||||
|
class XCustom extends PolymerElement {
|
||||||
|
|
||||||
|
static get properties() {
|
||||||
|
return {
|
||||||
|
preload: Boolean,
|
||||||
|
src: String,
|
||||||
|
size: String
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Each item of observers array is a method name followed by
|
||||||
|
// a comma-separated list of one or more dependencies.
|
||||||
|
static get observers() {
|
||||||
|
return [
|
||||||
|
'updateImage(preload, src, size)'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Each method referenced in observers must be defined in
|
||||||
|
// element prototype. The arguments to the method are new value
|
||||||
|
// of each dependency, and may be undefined.
|
||||||
|
updateImage(preload, src, size) {
|
||||||
|
// ... do work using dependent values
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
customElements.define('x-custom', XCustom);
|
||||||
|
|
||||||
|
|
||||||
|
## Observe sub-property changes
|
||||||
|
|
||||||
|
- Define an observers array.
|
||||||
|
- Add an item to the observers array. The item must be a method name followed by a comma-separated list of one or more paths. For example, **onNameChange(dog.name) for one path, or onNameChange(dog.name, cat.name) for multiple paths**. **Each path is a sub-property** that you want to observe.
|
||||||
|
- Define the method in your element prototype. When the method is called, the argument to the method is the new value of the sub-property.
|
||||||
|
|
||||||
|
|
||||||
|
Example
|
||||||
|
|
||||||
|
import { PolymerElement, html } from '@polymer/polymer/polymer-element.js';
|
||||||
|
|
||||||
|
class XCustom extends PolymerElement {
|
||||||
|
static get template () {
|
||||||
|
return html`
|
||||||
|
<!-- Sub-property is updated via property binding. -->
|
||||||
|
<input value="{{user.name::input}}">
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
static get properties() {
|
||||||
|
return {
|
||||||
|
user: {
|
||||||
|
type: Object,
|
||||||
|
value: function() {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Observe the name sub-property on the user object
|
||||||
|
static get observers() {
|
||||||
|
return [
|
||||||
|
'userNameChanged(user.name)'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
// For a property or sub-property dependency, the corresponding
|
||||||
|
// argument is the new value of the property or sub-property
|
||||||
|
userNameChanged: function(name) {
|
||||||
|
if (name) {
|
||||||
|
console.log('new name: ' + name);
|
||||||
|
} else {
|
||||||
|
console.log('user name is undefined');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
customElements.define('x-custom', XCustom);
|
||||||
|
|
||||||
|
## Observe array mutations
|
||||||
|
|
||||||
|
static get observers() {
|
||||||
|
return [
|
||||||
|
'usersAddedOrRemoved(users.splices)'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
- indexSplices. The set of changes that occurred to the array, in terms of array indexes. Each indexSplices record contains the following properties:
|
||||||
|
- index. Position where the splice started.
|
||||||
|
- removed. Array of removed items.
|
||||||
|
- addedCount. Number of new items inserted at index.
|
||||||
|
- object: A reference to the array in question.
|
||||||
|
- type: The string literal 'splice'.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Example
|
||||||
|
|
||||||
|
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||||
|
|
||||||
|
class XCustom extends PolymerElement {
|
||||||
|
static get properties() {
|
||||||
|
return {
|
||||||
|
users: {
|
||||||
|
type: Array,
|
||||||
|
value: function() {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Observe changes to the users array
|
||||||
|
static get observers() {
|
||||||
|
return [
|
||||||
|
'usersAddedOrRemoved(users.splices)'
|
||||||
|
];
|
||||||
|
}
|
||||||
|
// For an array mutation dependency, the corresponding argument is a change record
|
||||||
|
usersAddedOrRemoved(changeRecord) {
|
||||||
|
if (changeRecord) {
|
||||||
|
changeRecord.indexSplices.forEach(function(s) {
|
||||||
|
s.removed.forEach(function(user) {
|
||||||
|
console.log(user.name + ' was removed');
|
||||||
|
});
|
||||||
|
for (var i=0; i<s.addedCount; i++) {
|
||||||
|
var index = s.index + i;
|
||||||
|
var newUser = s.object[index];
|
||||||
|
console.log('User ' + newUser.name + ' added at index ' + index);
|
||||||
|
}
|
||||||
|
}, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ready() {
|
||||||
|
super.ready();
|
||||||
|
this.push('users', {name: "Jack Aubrey"});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
customElements.define('x-custom', XCustom);
|
||||||
|
|
||||||
|
|
||||||
|
### Observe all changes related to a path
|
||||||
|
|
||||||
|
To call an observer when any (deep) sub-property of an object or array changes, specify a path with a wildcard (*).
|
||||||
|
|
||||||
|
When you specify a path with a wildcard, the argument passed to your observer is a change record object with the following properties:
|
||||||
|
|
||||||
|
- path. Path to the property that changed. Use this to determine whether a property changed, a sub-property changed, or an array was mutated.
|
||||||
|
- value. New value of the path that changed.
|
||||||
|
- base. The object matching the non-wildcard portion of the path.
|
||||||
|
|
||||||
|
Example
|
||||||
|
|
||||||
|
import { PolymerElement, html } from '@polymer/polymer/polymer-element.js';
|
||||||
|
|
||||||
|
class XCustom extends PolymerElement {
|
||||||
|
static get template() {
|
||||||
|
return html`
|
||||||
|
<input value="{{user.name.first::input}}" placeholder="First Name">
|
||||||
|
<input value="{{user.name.last::input}}" placeholder="Last Name">
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
static get properties() {
|
||||||
|
return {
|
||||||
|
user: {
|
||||||
|
type: Object,
|
||||||
|
value: function() {
|
||||||
|
return {'name':{}};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static get observers() {
|
||||||
|
return [
|
||||||
|
'userNameChanged(user.name.*)'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
userNameChanged(changeRecord) {
|
||||||
|
console.log('path: ' + changeRecord.path);
|
||||||
|
console.log('value: ' + changeRecord.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
customElements.define('x-custom', XCustom);
|
||||||
|
|
||||||
|
static get properties() {
|
||||||
|
return {
|
||||||
|
firstName: {
|
||||||
|
type: String
|
||||||
|
},
|
||||||
|
lastName: {
|
||||||
|
type: String
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static get observers() {
|
||||||
|
return [
|
||||||
|
'nameChanged(firstName, lastName)'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
nameChanged: function(firstName, lastName) {
|
||||||
|
console.log('new name:', firstName, lastName);
|
||||||
|
}
|
||||||
|
|
||||||
|
## Computed properties
|
||||||
|
|
||||||
|
Note: The definition of a computing function looks like **the definition of a multi-property observer**, and the two act almost identically. The only difference is that the computed property function returns a value that's exposed as a virtual property.
|
||||||
|
|
||||||
|
import { PolymerElement, html } from '@polymer/polymer/polymer-element.js';
|
||||||
|
|
||||||
|
class XCustom extends PolymerElement {
|
||||||
|
static get template() {
|
||||||
|
return html`
|
||||||
|
<p>My name is <span>{{fullName}}</span></p>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
static get properties() {
|
||||||
|
return {
|
||||||
|
first: String,
|
||||||
|
last: String,
|
||||||
|
fullName: {
|
||||||
|
type: String,
|
||||||
|
// when `first` or `last` changes `computeFullName` is called once
|
||||||
|
// and the value it returns is stored as `fullName`
|
||||||
|
computed: 'computeFullName(first, last)'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
computeFullName(first, last) {
|
||||||
|
return first + ' ' + last;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
customElements.define('x-custom', XCustom);
|
||||||
|
|
||||||
|
## Dynamic observer methods
|
||||||
|
For example,
|
||||||
|
|
||||||
|
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||||
|
|
||||||
|
class NameCard extends PolymerElement {
|
||||||
|
static get properties() {
|
||||||
|
return {
|
||||||
|
// Override default format by assigning a new formatter
|
||||||
|
// function
|
||||||
|
formatter: {
|
||||||
|
type: Function
|
||||||
|
},
|
||||||
|
formattedName: {
|
||||||
|
computed: 'formatter(name.title, name.first, name.last)'
|
||||||
|
},
|
||||||
|
name: {
|
||||||
|
type: Object,
|
||||||
|
value() {
|
||||||
|
return { title: "", first: "", last: "" };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.formatter = this.defaultFormatter;
|
||||||
|
}
|
||||||
|
defaultFormatter(title, first, last) {
|
||||||
|
return `${title} ${first} ${last}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
customElements.define('name-card', NameCard);
|
||||||
|
|
||||||
|
Setting a new value for formatter causes the formattedName property to update, even if the name property doesn't change:
|
||||||
|
|
||||||
|
nameCard.name = { title: 'Admiral', first: 'Grace', last: 'Hopper'}
|
||||||
|
console.log(nameCard.formattedName); // Admiral Grace Hopper
|
||||||
|
nameCard.formatter = function(title, first, last) {
|
||||||
|
return `${last}, ${first}`
|
||||||
|
}
|
||||||
|
console.log(nameCard.formattedName); // Hopper, Grace
|
||||||
|
|
||||||
|
|
||||||
|
### Add a simple observer dynamically
|
||||||
|
You can create a simple observer dynamically using the _createPropertyObserver instance method. For example:
|
||||||
|
|
||||||
|
this._observedPropertyChanged = (newVal) => { console.log('observedProperty changed to ' + newVal); };
|
||||||
|
this._createPropertyObserver('observedProperty', '_observedPropertyChanged', true);
|
||||||
|
|
||||||
|
### Add a complex observer dynamically
|
||||||
|
You can create a computed property dynamically using the _createMethodObserver instance method. For example:
|
||||||
|
|
||||||
|
this._createMethodObserver('_observeSeveralProperties(prop1,prop2,prop3)', true);
|
||||||
|
|
||||||
|
### Add a computed property dynamically
|
||||||
|
You can create a computed property dynamically using the _createComputedProperty instance method. For example:
|
||||||
|
|
||||||
|
this._createComputedProperty('newProperty', '_computeNewProperty(prop1,prop2)', true);
|
||||||
|
|
||||||
|
|
||||||
|
# Data Bindings
|
||||||
|
|
||||||
|
A data binding connects data from a custom element (the host element) to a property or attribute of an element in its local DOM (the child or target element).
|
||||||
|
|
||||||
|
static get template() {
|
||||||
|
return html`
|
||||||
|
<target-element target-property="{{hostProperty}}"></target-element>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
### Bind to a target property
|
||||||
|
|
||||||
|
<target-element name="{{myName}}"></target-element>
|
||||||
|
|
||||||
|
This example binds the target element's name property to the host element's myName property.
|
||||||
|
|
||||||
|
|
||||||
|
### Bind to text content
|
||||||
|
To bind to a target element's textContent, you can simply include the annotation or compound binding inside the target element.
|
||||||
|
|
||||||
|
import { PolymerElement, html } from '@polymer/polymer/polymer-element.js';
|
||||||
|
|
||||||
|
class UserView extends PolymerElement {
|
||||||
|
static get properties() {
|
||||||
|
return {
|
||||||
|
name: String
|
||||||
|
};
|
||||||
|
}
|
||||||
|
static get template() {
|
||||||
|
return html`
|
||||||
|
<div>[[name]]</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
customElements.define('user-view', UserView);
|
||||||
|
<!-- usage -->
|
||||||
|
<user-view name="Samuel"></user-view>
|
||||||
|
|
||||||
|
### Bind to a target attribute
|
||||||
|
|
||||||
|
To bind to an attribute, add a dollar sign ($) after the attribute name:
|
||||||
|
|
||||||
|
<div style$="color: {{myColor}};">
|
||||||
|
|
||||||
|
Attribute binding results in a call to:
|
||||||
|
|
||||||
|
element.setAttribute(attr,value);
|
||||||
|
|
||||||
|
As opposed to:
|
||||||
|
|
||||||
|
element.property = value;
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
static get template() {
|
||||||
|
return html`
|
||||||
|
<!-- Attribute binding -->
|
||||||
|
<my-element selected$="[[value]]"></my-element>
|
||||||
|
<!-- results in <my-element>.setAttribute('selected', this.value); -->
|
||||||
|
|
||||||
|
<!-- Property binding -->
|
||||||
|
<my-element selected="{{value}}"></my-element>
|
||||||
|
<!-- results in <my-element>.selected = this.value; -->
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
### Bind to a host sub-property
|
||||||
|
|
||||||
|
main-view.js
|
||||||
|
|
||||||
|
import { PolymerElement, html } from '@polymer/polymer/polymer-element.js';
|
||||||
|
import './user-view.js';
|
||||||
|
|
||||||
|
class MainView extends PolymerElement {
|
||||||
|
static get properties() {
|
||||||
|
return {
|
||||||
|
user: {
|
||||||
|
type: Object,
|
||||||
|
value: function () { return { given: "San", family: "Zhang" }; }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
static get template() {
|
||||||
|
return html`
|
||||||
|
<user-view given="{{user.given}}" family="{{user.family}}"></user-view>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
customElements.define('main-view', MainView);
|
||||||
|
|
||||||
|
user-view.js
|
||||||
|
|
||||||
|
import { PolymerElement, html } from '@polymer/polymer/polymer-element.js';
|
||||||
|
|
||||||
|
class UserView extends PolymerElement {
|
||||||
|
static get properties() {
|
||||||
|
return {
|
||||||
|
given: String,
|
||||||
|
family: String
|
||||||
|
};
|
||||||
|
}
|
||||||
|
static get template() {
|
||||||
|
return html`
|
||||||
|
<div>[[given]] [[family]]</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
customElements.define('user-view', UserView);
|
||||||
|
|
||||||
|
index.html
|
||||||
|
|
||||||
|
<main-view></main-view>
|
||||||
|
|
||||||
|
## Logical not operator
|
||||||
|
|
||||||
|
static get template() {
|
||||||
|
return html`
|
||||||
|
<my-page show-login="[[!isLoggedIn]]"></my-page>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
### Computed bindings
|
||||||
|
|
||||||
|
<div>[[_formatName(first, last, title)]]</div>
|
||||||
|
|
||||||
|
A computed binding is useful if you don't need to expose a computed property as part of the element's API, or use it elsewhere in the element. Computed bindings are also useful for filtering or transforming values for display.
|
||||||
|
|
||||||
|
Example
|
||||||
|
|
||||||
|
class XCustom extends PolymerElement {
|
||||||
|
static get properties() {
|
||||||
|
return {
|
||||||
|
given: String,
|
||||||
|
family: String
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
_formatName(given, family) {
|
||||||
|
return `${family}, ${given}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
static get template() {
|
||||||
|
return html`
|
||||||
|
My name is <span>[[_formatName(given, family)]]</span>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
customElements.define('x-custom', XCustom);
|
||||||
|
|
||||||
|
### Literal arguments to computed bindings
|
||||||
|
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
static get template() {
|
||||||
|
return html`
|
||||||
|
<span>{{translate('Hello\!\, nice to meet you', given, family)}}</span>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
### Compound bindings
|
||||||
|
You can combine string literals and bindings in a single property binding or text content binding. For example:
|
||||||
|
|
||||||
|
<img src$="https://www.example.com/profiles/[[userId]].jpg">
|
||||||
|
|
||||||
|
<span>Name: [[lastname]], [[firstname]]</span>
|
||||||
|
|
||||||
|
|
||||||
|
## Binding to arrays and array items
|
||||||
|
|
||||||
|
<!-- Don't do this! This format doesn't work -->
|
||||||
|
<span>{{array[0]}}</span>
|
||||||
|
<!-- Don't do this! Data may display, but won't be updated correctly -->
|
||||||
|
<span>{{array.0}}</span>
|
||||||
|
|
||||||
|
### Bind to an array item
|
||||||
|
You can use a computed binding to bind to a specific array item, or to a subproperty of an array item, like array[index].name.
|
||||||
|
|
||||||
|
|
||||||
|
class XCustom extends PolymerElement {
|
||||||
|
static get properties() {
|
||||||
|
return {
|
||||||
|
myArray: {
|
||||||
|
type: Array,
|
||||||
|
value: [{ name: 'Bob' }, { name: 'Wing Sang' }]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
// first argument is the change record for the array change,
|
||||||
|
// change.base is the array specified in the binding
|
||||||
|
arrayItem(change, index, path) {
|
||||||
|
// this.get(path, root) returns a value for a path
|
||||||
|
// relative to a root object.
|
||||||
|
return this.get(path, change.base[index]);
|
||||||
|
}
|
||||||
|
ready() {
|
||||||
|
super.ready();
|
||||||
|
// mutate the array
|
||||||
|
this.unshift('myArray', { name: 'Fatma' });
|
||||||
|
// change a subproperty
|
||||||
|
this.set('myArray.1.name', 'Rupert');
|
||||||
|
}
|
||||||
|
static get template() {
|
||||||
|
return html`
|
||||||
|
<div>[[arrayItem(myArray.*, 0, 'name')]]</div>
|
||||||
|
<div>[[arrayItem(myArray.*, 1, 'name')]]</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
## Two-way binding to a non-Polymer element
|
||||||
|
|
||||||
|
Example
|
||||||
|
|
||||||
|
<!-- Listens for `input` event and sets hostValue to <input>.value -->
|
||||||
|
<input value="{{hostValue::input}}">
|
||||||
|
|
||||||
|
<!-- Listens for `change` event and sets hostChecked to <input>.checked -->
|
||||||
|
<input type="checkbox" checked="{{hostChecked::change}}">
|
||||||
|
|
||||||
|
<!-- Listens for `timeupdate ` event and sets hostTime to <video>.currentTime -->
|
||||||
|
<video url="..." current-time="{{hostTime::timeupdate}}">
|
||||||
198
EventsOfPolymer.md
Executable file
198
EventsOfPolymer.md
Executable file
@@ -0,0 +1,198 @@
|
|||||||
|
# Add and Remove Listeners
|
||||||
|
|
||||||
|
ready() {
|
||||||
|
super.ready();
|
||||||
|
this.addEventListener('click', e => this._myClickListener(e));
|
||||||
|
}
|
||||||
|
The previous example uses an arrow function to ensure the listener is called with the element as the this value. You can also use bind to create a bound instance of the listener function. This can be useful if you need to remove the listener.
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this._boundListener = this._myLocationListener.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
connectedCallback() {
|
||||||
|
super.connectedCallback();
|
||||||
|
window.addEventListener('hashchange', this._boundListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
disconnectedCallback() {
|
||||||
|
super.disconnectedCallback();
|
||||||
|
window.removeEventListener('hashchange', this._boundListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
# Fire custom events
|
||||||
|
|
||||||
|
To fire a custom event from the host element use the standard CustomEvent constructor and the dispatchEvent method.
|
||||||
|
|
||||||
|
x-custom.js
|
||||||
|
|
||||||
|
class XCustom extends PolymerElement {
|
||||||
|
static get template(){
|
||||||
|
return html`
|
||||||
|
<button on-click="handleClick">Kick Me</button>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
handleClick(e) {
|
||||||
|
this.dispatchEvent(new CustomEvent('kick', {detail: {kicked: true}}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
customElements.define('x-custom', XCustom);
|
||||||
|
|
||||||
|
index.html
|
||||||
|
|
||||||
|
<x-custom></x-custom>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
document.querySelector('x-custom').addEventListener('kick', function (e) {
|
||||||
|
console.log(e.detail.kicked); // true
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
To make a custom event pass through shadow DOM boundaries, set the composed flag to true when you create the event:
|
||||||
|
|
||||||
|
|
||||||
|
var event = new CustomEvent('my-event', {bubbles: true, composed: true});
|
||||||
|
|
||||||
|
# Handle Retargeted events
|
||||||
|
The event's composedPath() method returns an array of nodes through which the event will pass. So event.composedPath()[0] represents the original target for the event (unless that target is hidden in a closed shadow root).
|
||||||
|
|
||||||
|
event-retargeting.js
|
||||||
|
|
||||||
|
class EventRetargeting extends PolymerElement {
|
||||||
|
static get template(){
|
||||||
|
return html`
|
||||||
|
<button id="myButton">Click Me</button>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
ready() {
|
||||||
|
super.ready();
|
||||||
|
this.$.myButton.addEventListener('click', e => {this._handleClick(e)});
|
||||||
|
}
|
||||||
|
|
||||||
|
_handleClick(e) {
|
||||||
|
console.info(e.target.id + ' was clicked.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
customElements.define('event-retargeting', EventRetargeting);
|
||||||
|
|
||||||
|
index.html
|
||||||
|
|
||||||
|
<event-retargeting></event-retargeting>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
var el = document.querySelector('event-retargeting');
|
||||||
|
el.addEventListener('click', function(e){
|
||||||
|
// logs the instance of event-targeting that hosts #myButton
|
||||||
|
console.info('target is:', e.target);
|
||||||
|
// logs [#myButton, ShadowRoot, event-retargeting,
|
||||||
|
// body, html, document, Window]
|
||||||
|
console.info('composedPath is:', e.composedPath());
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
# Using gesture event
|
||||||
|
|
||||||
|
Gesture events require some extra setup, so you can't simply add a listener using the generic addEventListener method. To listen for a gesture event:
|
||||||
|
Use an annotated event listener for one of the gesture events.
|
||||||
|
|
||||||
|
<div on-tap="tapHandler">Tap here!</div>
|
||||||
|
|
||||||
|
## Gesture event types
|
||||||
|
|
||||||
|
The following are the gesture event types supported, with a short description and list of detail properties available on event.detail for each type:
|
||||||
|
|
||||||
|
1 . down—finger/button went down
|
||||||
|
x—clientX coordinate for event
|
||||||
|
y—clientY coordinate for event
|
||||||
|
sourceEvent—the original DOM event that caused the down action
|
||||||
|
2 . up—finger/button went up
|
||||||
|
x—clientX coordinate for event
|
||||||
|
y—clientY coordinate for event
|
||||||
|
sourceEvent—the original DOM event that caused the up action
|
||||||
|
3 . tap—down & up occurred
|
||||||
|
x—clientX coordinate for event
|
||||||
|
y—clientY coordinate for event
|
||||||
|
sourceEvent—the original DOM event that caused the tap action
|
||||||
|
4 . track—moving while finger/button is down
|
||||||
|
1. state—a string indicating the tracking state:
|
||||||
|
2. start—fired when tracking is first detected (finger/button down and moved past a pre-set distance threshold)
|
||||||
|
track—fired while tracking
|
||||||
|
3. end—fired when tracking ends
|
||||||
|
x—clientX coordinate for event
|
||||||
|
y—clientY coordinate for event
|
||||||
|
dx—change in pixels horizontally since the first track event
|
||||||
|
dy—change in pixels vertically since the first track event
|
||||||
|
ddx—change in pixels horizontally since last track event
|
||||||
|
ddy—change in pixels vertically since last track event
|
||||||
|
hover()—a function that may be called to determine the element currently being hovered
|
||||||
|
|
||||||
|
Example,
|
||||||
|
|
||||||
|
class DragMe extends GestureEventListeners(PolymerElement){
|
||||||
|
static get template(){
|
||||||
|
return html`
|
||||||
|
<style>
|
||||||
|
#dragme {
|
||||||
|
width: 500px;
|
||||||
|
height: 500px;
|
||||||
|
background: lightgray;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div id="dragme" on-track="handleTrack">[[message]]</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
handleTrack(e) {
|
||||||
|
switch(e.detail.state) {
|
||||||
|
case 'start':
|
||||||
|
this.message = 'Tracking started!';
|
||||||
|
break;
|
||||||
|
case 'track':
|
||||||
|
this.message = 'Tracking in progress... ' +
|
||||||
|
e.detail.x + ', ' + e.detail.y;
|
||||||
|
break;
|
||||||
|
case 'end':
|
||||||
|
this.message = 'Tracking ended!';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#### Example imperative event listener
|
||||||
|
|
||||||
|
import {PolymerElement, html} from '@polymer/polymer/polymer-element.js';
|
||||||
|
import {GestureEventListeners} from '@polymer/polymer/lib/mixins/gesture-event-listeners.js';
|
||||||
|
import * as Gestures from '@polymer/polymer/lib/utils/gestures.js';
|
||||||
|
|
||||||
|
class TapMe extends GestureEventListeners(PolymerElement){
|
||||||
|
static get template(){
|
||||||
|
return html`
|
||||||
|
<style>
|
||||||
|
:host {
|
||||||
|
display: block;
|
||||||
|
width: 200px;
|
||||||
|
height: 200px;
|
||||||
|
border: 1px solid blue;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div>Tap me!</div>
|
||||||
|
<div>I've been tapped [[count]] times.</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.count = 0;
|
||||||
|
Gestures.addListener(this, 'tap', this.handleTap.bind(this));
|
||||||
|
}
|
||||||
|
handleTap(e) {
|
||||||
|
this.count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
customElements.define('tap-me', TapMe);
|
||||||
|
|
||||||
|
## Gestures and scroll direction
|
||||||
|
|
||||||
|
Listening for certain gestures controls the scrolling direction for touch input. For example, nodes with a listener for the track event will prevent scrolling by default. Elements can override scroll direction with this.setScrollDirection(direction, node), where direction is one of 'x', 'y', 'none', or 'all', and node defaults to this.
|
||||||
164
GitCMD.md
Executable file
164
GitCMD.md
Executable file
@@ -0,0 +1,164 @@
|
|||||||
|
# Git Basics
|
||||||
|
### Create a new repository
|
||||||
|
|
||||||
|
$ touch README.md
|
||||||
|
$ git init
|
||||||
|
$ git add README.md
|
||||||
|
$ git commit -m "first commit"
|
||||||
|
$ git remote add origin https://github.com/example/rhymes.git
|
||||||
|
$ git push -u origin master
|
||||||
|
|
||||||
|
### Getting project from a repository
|
||||||
|
|
||||||
|
$ git clone https://github.com/example/rhymes.git
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Tracking New Files
|
||||||
|
Add file contents to the index.
|
||||||
|
|
||||||
|
$ git add README.md
|
||||||
|
|
||||||
|
Show the working tree status.
|
||||||
|
|
||||||
|
$ git status
|
||||||
|
Record changes to the repository.
|
||||||
|
|
||||||
|
$ git commit -m "first commit"
|
||||||
|
|
||||||
|
Push an existing repository and Update remote refs along with associated objects
|
||||||
|
$ git push -u origin master
|
||||||
|
|
||||||
|
### Remove files from the working tree and from the index
|
||||||
|
|
||||||
|
$ git rm file_name
|
||||||
|
|
||||||
|
### Fetch from and integrate with another repository or a local branch
|
||||||
|
$ git pull
|
||||||
|
$ git pull origin master
|
||||||
|
|
||||||
|
|
||||||
|
### Managing branches
|
||||||
|
To create a new branch
|
||||||
|
|
||||||
|
$ git branch branch_name
|
||||||
|
|
||||||
|
If you know branch lists, you run
|
||||||
|
|
||||||
|
$ git branch
|
||||||
|
$ git branch -a
|
||||||
|
|
||||||
|
If you are currently on your branch
|
||||||
|
|
||||||
|
$ git checkout you_branch_name
|
||||||
|
|
||||||
|
Deleting branch
|
||||||
|
|
||||||
|
$ git branch -d branch_name
|
||||||
|
|
||||||
|
### Merging branches
|
||||||
|
Before using "git merge", make sure the correct local branch is checked out.
|
||||||
|
|
||||||
|
$ git checkout master
|
||||||
|
$ git merge remote_branch
|
||||||
|
|
||||||
|
|
||||||
|
### View current remotes
|
||||||
|
|
||||||
|
$ git remote -v
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
origin https://github.com/OWNER/REPOSITORY.git (fetch)
|
||||||
|
|
||||||
|
origin https://github.com/OWNER/REPOSITORY.git (push)
|
||||||
|
|
||||||
|
### Adding Remote Repositories
|
||||||
|
$ git remote add other_user_name https://github.com/example/rhymes.git
|
||||||
|
Example:
|
||||||
|
|
||||||
|
$ git remote add pb https://github.com/paulboone/ticgit
|
||||||
|
|
||||||
|
origin https://github.com/OWNER/REPOSITORY.git (fetch)
|
||||||
|
|
||||||
|
origin https://github.com/OWNER/REPOSITORY.git (push)
|
||||||
|
|
||||||
|
pb https://github.com/paulboone/ticgit (fetch)
|
||||||
|
|
||||||
|
pb https://github.com/paulboone/ticgit (push)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Fetch a copy of other user's work.
|
||||||
|
|
||||||
|
$ git fetch user_name
|
||||||
|
|
||||||
|
|
||||||
|
### Removing a remote
|
||||||
|
|
||||||
|
If you want to know other user's works,
|
||||||
|
|
||||||
|
$ git remote add other_user_name https://github.com/example/rhymes.git
|
||||||
|
|
||||||
|
and then you can see works
|
||||||
|
|
||||||
|
# Merge
|
||||||
|
## Review all the branches (both local and remote).
|
||||||
|
$ git branch -a
|
||||||
|
## Check out a local copy of other_user work and review it.
|
||||||
|
$ git remote add name http://branch/name.git
|
||||||
|
$ git fetch name
|
||||||
|
$ git checkout -b remote_branch name/remote_branch
|
||||||
|
$ git diff master remote_branch
|
||||||
|
$ git log -1 -p
|
||||||
|
## Checkout master and merge Bobs changes in.
|
||||||
|
$ git checkout master
|
||||||
|
$ git merge remote_branch
|
||||||
|
|
||||||
|
example,
|
||||||
|
|
||||||
|
From https://git.com/Alice/rhymes
|
||||||
|
de64fd9..95029d3 master -> John/master
|
||||||
|
* [new branch] test -> John/test
|
||||||
|
* [new branch] test_change -> John/phyo_change
|
||||||
|
|
||||||
|
|
||||||
|
### Rebase forked repository Or update forked repository
|
||||||
|
|
||||||
|
* Add the remote of original repository, example call it "upstream":
|
||||||
|
> $git remote add upstream https://git.autoleum.com/Sai/fserver-fe
|
||||||
|
|
||||||
|
* Fetch all the branches of that remote into remote-tracking branches,such as upstream/master:
|
||||||
|
> $git fetch upstream
|
||||||
|
|
||||||
|
* checkout master branch
|
||||||
|
> $git checkout master
|
||||||
|
|
||||||
|
* merge branches
|
||||||
|
>$ git merge upstream/master
|
||||||
|
|
||||||
|
* Rewrite your master branch so that any commits of yours that aren't already in upstream/master are replayed on top of that other branch
|
||||||
|
> $git rebase upstream/master
|
||||||
|
|
||||||
|
* Push your forked master, need to use '-f' for first time push
|
||||||
|
> $git push -f origin master
|
||||||
|
|
||||||
|
## Create Patch From Diff
|
||||||
|
> $git diff > mypatch.patch
|
||||||
|
> $git apply mypatch.patch
|
||||||
|
|
||||||
|
|
||||||
|
## Store Git Credential
|
||||||
|
>$ git config credential.helper store<br/>
|
||||||
|
>$ git push http://example.com/repo.git<br/>
|
||||||
|
Username: [type your username]<br/>
|
||||||
|
Password: [type your password]
|
||||||
|
|
||||||
|
|
||||||
|
[several days later]
|
||||||
|
>$ git push http://example.com/repo.git<br/>
|
||||||
|
[your credentials are used automatically]
|
||||||
|
|
||||||
|
|
||||||
|
## Install GOGS repo From npm
|
||||||
|
> $npm install --save git+https://git.mokkon.com/sainw/mokkon-reactjs.git#v1.1.0
|
||||||
22
GoLanguage.md
Executable file
22
GoLanguage.md
Executable file
@@ -0,0 +1,22 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var a [2]string
|
||||||
|
a[0] = "Hello"
|
||||||
|
a[1] = "World"
|
||||||
|
fmt.Println(a[0], a[1])
|
||||||
|
fmt.Println(a)
|
||||||
|
|
||||||
|
primes := [6]int{2, 3, 5, 7, 11, 13}
|
||||||
|
fmt.Println(primes)
|
||||||
|
fmt.Println(split(30))
|
||||||
|
}
|
||||||
|
|
||||||
|
func split(sum int)(x,y int){
|
||||||
|
x=sum/9
|
||||||
|
y=sum-x
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
34
Installation.md
Executable file
34
Installation.md
Executable file
@@ -0,0 +1,34 @@
|
|||||||
|
# Installation
|
||||||
|
|
||||||
|
## Chrome
|
||||||
|
$ sudo apt-get install libxss1 libappindicator1 libindicator7
|
||||||
|
|
||||||
|
$ wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
|
||||||
|
|
||||||
|
$ sudo dpkg -i google-chrome*.deb
|
||||||
|
|
||||||
|
$ sudo apt-get install -f
|
||||||
|
|
||||||
|
## Atom
|
||||||
|
Install form terminal
|
||||||
|
|
||||||
|
$ sudo add-apt-repository ppa:webupd8team/atom
|
||||||
|
|
||||||
|
$ sudo apt update
|
||||||
|
|
||||||
|
$ sudo apt install atom
|
||||||
|
|
||||||
|
## Team Viewer
|
||||||
|
Download the TeamViewer DEB package from https://www.teamviewer.com/download/linux/?_ga=2.117699849.1611532503.1532929360-1758681613.1532929360
|
||||||
|
|
||||||
|
$ wget link..
|
||||||
|
|
||||||
|
## Visual Studio Code
|
||||||
|
|
||||||
|
$ wget https://az764295.vo.msecnd.net/stable/1dfc5e557209371715f655691b1235b6b26a06be/code_1.25.1-1531323788_amd64.deb
|
||||||
|
|
||||||
|
## Git
|
||||||
|
|
||||||
|
$ sudo apt-get install git
|
||||||
|
|
||||||
|
$ git --version
|
||||||
114
Linux-Commands.md
Executable file
114
Linux-Commands.md
Executable file
@@ -0,0 +1,114 @@
|
|||||||
|
### 1. pwd command
|
||||||
|
To find out the path of the current working directory (folder).
|
||||||
|
|
||||||
|
### 2. ls command
|
||||||
|
To know what files are in the directory you are in.
|
||||||
|
|
||||||
|
### 3. cd command
|
||||||
|
To navigate through the Linux files and directories.
|
||||||
|
|
||||||
|
### 4. mkdir command
|
||||||
|
To create a folder or a directory.
|
||||||
|
|
||||||
|
$ mkdri folderName
|
||||||
|
|
||||||
|
### 5. rmdir command
|
||||||
|
If you need to delete a directory, use the rmdir command. However, rmdir only allows you to delete empty directories.
|
||||||
|
|
||||||
|
$ rmdir folderName
|
||||||
|
|
||||||
|
### 6. rm command
|
||||||
|
To delete files and directories within them. Use "rm -r" to delete just the directory.
|
||||||
|
|
||||||
|
$ rm fileName
|
||||||
|
|
||||||
|
### 7. touch command
|
||||||
|
The touch command is used to create a file. It can be anything, from an empty txt file to an empty zip file.
|
||||||
|
|
||||||
|
$ touch new.txt
|
||||||
|
|
||||||
|
### 8. cp command
|
||||||
|
To copy files from the current directory to a different directory. It takes two arguments: The first is the location of the file to be copied, the second is where to copy.
|
||||||
|
|
||||||
|
$ cp scenery.jpg /hochmod commandme/username/Pictures
|
||||||
|
|
||||||
|
### 9. mv command
|
||||||
|
To move files through the command line.We can also use the mv command to rename a file.We can also use the mv command to rename a file. For example, if we want to rename the file “text” to “new”, we can use “mv text new”. It takes the two arguments, just like the cp command.
|
||||||
|
|
||||||
|
$ mv new.txt text.txt
|
||||||
|
|
||||||
|
### 10. locate command
|
||||||
|
You can use this command to locate a file, just like the search command in Windows.
|
||||||
|
|
||||||
|
$ locate text.txt
|
||||||
|
|
||||||
|
### 11. echo command
|
||||||
|
To move some data into a file.
|
||||||
|
|
||||||
|
$ echo hello, my name is alok >> text.txt
|
||||||
|
|
||||||
|
### 12. cat command
|
||||||
|
To display the contents of a file. It is usually used to easily view programs.
|
||||||
|
|
||||||
|
$ cat text.txt
|
||||||
|
|
||||||
|
### 13. df command
|
||||||
|
The df command shows the size, used space, and available space on the mounted filesystems of your computer.
|
||||||
|
|
||||||
|
### 14. du command
|
||||||
|
Use du to know the disk usage of a file in your system.
|
||||||
|
|
||||||
|
### 15. diff command
|
||||||
|
The diff command compares two text files and shows the differences between them. There are many options to tailor the display to your requirements.
|
||||||
|
|
||||||
|
$ diff file1.ext file2.ext
|
||||||
|
|
||||||
|
|
||||||
|
### 16. tar command
|
||||||
|
The tar command is the most used command to archive multiple files into a tarball — a common Linux file format that is similar to zip format, with compression being optional.
|
||||||
|
|
||||||
|
```
|
||||||
|
## Untar files in Current Directory ##
|
||||||
|
|
||||||
|
tar -xvf file.tar
|
||||||
|
```
|
||||||
|
|
||||||
|
some examples of tar commands
|
||||||
|
https://www.tecmint.com/18-tar-command-examples-in-linux/
|
||||||
|
|
||||||
|
### 17. zip, unzip command
|
||||||
|
Use zip to compress files into a zip archive, and unzip to extract files from a zip archive.
|
||||||
|
|
||||||
|
### 18. uname command
|
||||||
|
The uname command, short for Unix Name, will print detailed information about your Linux system like the machine name, operating system, kernel, and so on.
|
||||||
|
|
||||||
|
### 19.chmod command
|
||||||
|
To make a file executable and to change the permissions granted to it in Linux.
|
||||||
|
|
||||||
|
$ chmod +x numbers.py
|
||||||
|
|
||||||
|
### 20. hostname command
|
||||||
|
To know your name in your host or network. Adding a -i to the end will display the IP address of your network.
|
||||||
|
|
||||||
|
### 21. ping command
|
||||||
|
To check your connectivity status to a server. For example, by simply entering ping google.com, the command will check whether you’re able to connect to Google and also measure the response time.
|
||||||
|
|
||||||
|
### 22. history command
|
||||||
|
The history command lists the commands you have previously issued on the command line. You can repeat any of the commands from your history by typing an exclamation point ! and the number of the command from the history list.
|
||||||
|
|
||||||
|
### 23. exit command
|
||||||
|
The exit command will close a terminal window, end the execution of a shell script, or log you out of an SSH remote access session.
|
||||||
|
|
||||||
|
### 24. shutdown command
|
||||||
|
The shutdown command lets you shut down or reboot your Linux system.
|
||||||
|
|
||||||
|
### 25. To update System
|
||||||
|
|
||||||
|
$ sudo apt update
|
||||||
|
$ sudo apt upgrade
|
||||||
|
|
||||||
|
### 26. Find text in files
|
||||||
|
Find "Spreadsheets" text in files with extension '.go'
|
||||||
|
```
|
||||||
|
$find . -type f -name "*.go" -exec grep -lr "Spreadsheets" {} \;
|
||||||
|
```
|
||||||
31
Network.md
Executable file
31
Network.md
Executable file
@@ -0,0 +1,31 @@
|
|||||||
|
# Ubuntu 18.04 - realtek wired network "DISABLED"
|
||||||
|
https://askubuntu.com/questions/906636/ethernet-adapter-was-disable-on-ubuntu-17-04
|
||||||
|
|
||||||
|
# Install TL-WN8200ND Driver
|
||||||
|
* cd ~
|
||||||
|
* sudo apt-get install git linux-headers-generic build-essential dkms
|
||||||
|
* git clone https://github.com/agtbaskara/rtl8192eu-linux-driver.git
|
||||||
|
* cd rtl8192eu-linux-driver
|
||||||
|
* sudo dkms add .
|
||||||
|
* sudo dkms install rtl8192eu/1.0
|
||||||
|
* cd /usr/src/rtl8192eu-1.0/
|
||||||
|
* sudo make clean
|
||||||
|
* sudo make
|
||||||
|
* sudo make install
|
||||||
|
* sudo modprobe -a 8192eu
|
||||||
|
|
||||||
|
reference link => https://askubuntu.com/questions/1003112/unable-to-install-driver-wn8200nd-v2-rtl8192eu
|
||||||
|
|
||||||
|
# Install TL-WN8200ND Driver in 20.04
|
||||||
|
* sudo apt -y install linux-headers-generic build-essential dkms git
|
||||||
|
* git clone https://github.com/clnhub/rtl8192eu-linux
|
||||||
|
* cd rtl8192eu-linux
|
||||||
|
* ./install_wifi.sh
|
||||||
|
|
||||||
|
reference link => https://askubuntu.com/questions/1212932/install-usb-wireless-adapter-tp-link-tl-wn8200nd-in-ubuntu
|
||||||
|
|
||||||
|
# Install TL-WN823N Driver in 22.04
|
||||||
|
* sudo apt -y install linux-headers-generic build-essential dkms git
|
||||||
|
* git clone https://github.com/clnhub/rtl8192eu-linux
|
||||||
|
* cd rtl8192eu-linux
|
||||||
|
* ./install_wifi.sh
|
||||||
77
PcConfig.md
Executable file
77
PcConfig.md
Executable file
@@ -0,0 +1,77 @@
|
|||||||
|
## System Update
|
||||||
|
We can use this cmd in terminal to make system update
|
||||||
|
|
||||||
|
$sudo apt-get update
|
||||||
|
|
||||||
|
## Change Date & Time
|
||||||
|
|
||||||
|
0
|
||||||
|
The command date
|
||||||
|
|
||||||
|
|
||||||
|
$ date
|
||||||
|
Tue Jun 9 18:04:30 EEST 2015
|
||||||
|
|
||||||
|
The command zdump used to echo the time in a specified time zone.
|
||||||
|
|
||||||
|
$ zdump EEST
|
||||||
|
EEST Tue Jun 9 15:05:17 2015 EEST
|
||||||
|
|
||||||
|
hwclock
|
||||||
|
|
||||||
|
$ sudo hwclock
|
||||||
|
Tue 09 Jun 2015 06:05:55 PM EEST -0.656710 seconds
|
||||||
|
|
||||||
|
clock but needs to install xview-clients
|
||||||
|
|
||||||
|
sudo apt-get install xview-clients
|
||||||
|
|
||||||
|
using ntpdate command. ntpdate is used to set system time but using without sudo will just print the time and date.
|
||||||
|
|
||||||
|
$ ntpdate
|
||||||
|
|
||||||
|
30 July 7:
|
||||||
|
0
|
||||||
|
|
||||||
|
#Date and change using terminal
|
||||||
|
|
||||||
|
$timedatectl
|
||||||
|
$sudo timedatectl set-timezone Asia/Yangon
|
||||||
|
|
||||||
|
## Change Launguage
|
||||||
|
|
||||||
|
Edit two files:
|
||||||
|
|
||||||
|
sudoedit /etc/default/locale:
|
||||||
|
|
||||||
|
LANG="en_US"
|
||||||
|
LANGUAGE="en_US:en"
|
||||||
|
|
||||||
|
sudoedit ~/.pam_environment:
|
||||||
|
|
||||||
|
LANG=en_US
|
||||||
|
LANGUAGE=en_US
|
||||||
|
|
||||||
|
## Add custom to Dock
|
||||||
|
- add custom program to favourite of ubuntu Dock
|
||||||
|
- first create [.desktop] under directory [sudo nano /usr/share/applications/yourapp.desktop]
|
||||||
|
|
||||||
|
```
|
||||||
|
#!/usr/bin/env xdg-open
|
||||||
|
[Desktop Entry]
|
||||||
|
Version=1.0
|
||||||
|
Type=Application
|
||||||
|
Terminal=false
|
||||||
|
Exec=/path/to/yourapp
|
||||||
|
Name=YourApp
|
||||||
|
Comment=Description of YourApp
|
||||||
|
Icon=/path/to/yourapp.png
|
||||||
|
```
|
||||||
|
|
||||||
|
- Make this file executable
|
||||||
|
```sudo chmod +x /usr/share/applications/yourapp.desktop```
|
||||||
|
|
||||||
|
- Log out and log in
|
||||||
|
|
||||||
|
link>>https://averagelinuxuser.com/ubuntu_custom_launcher_dock/
|
||||||
|
|
||||||
9
README.md
Executable file
9
README.md
Executable file
@@ -0,0 +1,9 @@
|
|||||||
|
# [Installation](https://git.mokkon.com/sainw/reference/src/master/Installation.md)
|
||||||
|
# [Account Management] (https://git.mokkon.com/sainw/reference/src/master/AccountMgr.md)
|
||||||
|
|
||||||
|
# [PC Configuration] (https://git.mokkon.com/sainw/reference/src/master/PcConfig.md)
|
||||||
|
|
||||||
|
# [Git Commands] (https://git.mokkon.com/sainw/reference/src/master/GitCMD.md)
|
||||||
|
|
||||||
|
# [Vi Commands] (https://git.mokkon.com/sainw/reference/src/master/ViEditor.md)
|
||||||
|
|
||||||
46
SBC.md
Executable file
46
SBC.md
Executable file
@@ -0,0 +1,46 @@
|
|||||||
|
# Setup Single Board Computer (SBC)
|
||||||
|
1. [ Update BIOS Setting](#update-bios-setting)
|
||||||
|
2. [ Install Network Manager Tool](#install-network-manager-tool)
|
||||||
|
3. [Set Static IP Address](#set-static-ip-address)
|
||||||
|
4. [Restart Network Manager](#restart-network-manager)
|
||||||
|
|
||||||
|
## Update BIOS Setting
|
||||||
|
Menu: Advanced -> Miscellaneous Configuration -> OS Selection
|
||||||
|
|
||||||
|
Change OS type to "Win 8.x"
|
||||||
|
|
||||||
|
## Install Network Manager Tool
|
||||||
|
> sudo apt install network-manager
|
||||||
|
|
||||||
|
### Enable Wifi
|
||||||
|
> nmcli r wifi on
|
||||||
|
|
||||||
|
### List Wifi
|
||||||
|
> nmcli d wifi list
|
||||||
|
|
||||||
|
### Connect to Wifi
|
||||||
|
> nmcli d wifi connect ssid_name password "password"
|
||||||
|
|
||||||
|
### View Devices
|
||||||
|
> nmcli dev status
|
||||||
|
|
||||||
|
|
||||||
|
### Show Connection
|
||||||
|
> nmcli con show
|
||||||
|
|
||||||
|
|
||||||
|
## Set Static IP Address
|
||||||
|
> nmcli con edit ssid_name
|
||||||
|
>
|
||||||
|
> nmcli> set ipv4.addresses 192.168.1.111/24
|
||||||
|
>
|
||||||
|
> nmcli> save
|
||||||
|
>
|
||||||
|
> nmcli> quit
|
||||||
|
|
||||||
|
|
||||||
|
## Restart Network Manager
|
||||||
|
> sudo systemctl status NetworkManager.service
|
||||||
|
>
|
||||||
|
> sudo systemctl restart NetworkManager.service
|
||||||
|
|
||||||
896
ShadowDOMAndStyling.md
Executable file
896
ShadowDOMAndStyling.md
Executable file
@@ -0,0 +1,896 @@
|
|||||||
|
# Shadow DOM concepts
|
||||||
|
|
||||||
|
You can add a shadow tree to an element imperatively by calling attachShadow:
|
||||||
|
|
||||||
|
var div = document.createElement('div');
|
||||||
|
var shadowRoot = div.attachShadow({mode: 'open'});
|
||||||
|
shadowRoot.innerHTML ='<h1>Hello Shadow DOM</h1>';
|
||||||
|
|
||||||
|
## Shadow DOM and composition
|
||||||
|
|
||||||
|
By default, if an element has shadow DOM, the shadow tree is rendered instead of the element's children. To allow children to render, you can add a **slot** element to your shadow tree.
|
||||||
|
Consider the following shadow tree for my-header:
|
||||||
|
|
||||||
|
<header>
|
||||||
|
<h1><slot></slot></h1>
|
||||||
|
<button>Menu</button>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
The user can add children like this:
|
||||||
|
|
||||||
|
<my-header>Shadow DOM</my-header>
|
||||||
|
|
||||||
|
The header renders as if the <slot> element was replaced by the children:
|
||||||
|
|
||||||
|
<my-header>
|
||||||
|
<header>
|
||||||
|
<h1>Shadow DOM</h1>
|
||||||
|
<button>Menu</button>
|
||||||
|
</header>
|
||||||
|
</my-header>
|
||||||
|
|
||||||
|
While the <slot> elements don't render, they are included in the flattened tree, so they can take part in event bubbling, for example.
|
||||||
|
|
||||||
|
You can control where a child should be distributed into the flattened tree using named slots.
|
||||||
|
|
||||||
|
<h2><slot name="title"></slot></h2>
|
||||||
|
<div><slot></slot></div>
|
||||||
|
A named slot only accepts top-level children that have a matching slot attribute:
|
||||||
|
|
||||||
|
<span slot="title">A heading</span>
|
||||||
|
|
||||||
|
## Fallback content
|
||||||
|
|
||||||
|
A slot can contain fallback content that's displayed when no nodes are assigned to the slot. For example:
|
||||||
|
|
||||||
|
<!-- shows note with warning icon -->
|
||||||
|
<fancy-note>
|
||||||
|
<img slot="icon" src="warning.png">
|
||||||
|
Do not operate heavy equipment while coding.
|
||||||
|
</fancy-note>
|
||||||
|
|
||||||
|
If the user omits the icon, the fallback content supplies a default icon:
|
||||||
|
|
||||||
|
<!-- shows note with default icon -->
|
||||||
|
<fancy-note>
|
||||||
|
Please code responsibly.
|
||||||
|
</fancy-note>
|
||||||
|
|
||||||
|
## Slot APIs
|
||||||
|
Shadow DOM provides a few new APIs for checking distribution:
|
||||||
|
|
||||||
|
-**HTMLElement.assignedSlot** property gives the assigned slot for an element, or null if the element isn't assigned to a slot.
|
||||||
|
|
||||||
|
-**HTMLSlotElement.assignedNodes** method returns the list of nodes associated with a given slot. When called with the {flatten: true} option, returns the distributed nodes for a slot.
|
||||||
|
|
||||||
|
-**HTMLSlotElement.slotchange** event is fired when a slot's distributed nodes change.
|
||||||
|
|
||||||
|
## Observe added and removed children
|
||||||
|
|
||||||
|
Use the FlattenedNodesObserver class to track when the flattened node list changes.
|
||||||
|
|
||||||
|
import { FlattenedNodesObserver } from '@polymer/polymer/lib/utils/flattened-nodes-observer.js';
|
||||||
|
...
|
||||||
|
this._observer = new FlattenedNodesObserver(this.$.slot, (info) => {
|
||||||
|
this._processNewNodes(info.addedNodes);
|
||||||
|
this._processRemovedNodes(info.removedNodes);
|
||||||
|
});
|
||||||
|
|
||||||
|
## Event retargeting
|
||||||
|
|
||||||
|
Retargeting adjusts the event's target so that it represents an element in the same scope as the listening element.
|
||||||
|
|
||||||
|
For example, given a tree like this:
|
||||||
|
|
||||||
|
<example-card>
|
||||||
|
#shadow-root
|
||||||
|
<div>
|
||||||
|
<fancy-button>
|
||||||
|
#shadow-root
|
||||||
|
<img>
|
||||||
|
|
||||||
|
If the user clicks on the image element the click event bubbles up the tree:
|
||||||
|
|
||||||
|
* A listener on the image element itself receives the **img** as the target.
|
||||||
|
* A listener on the **fancy-button** receives the **fancy-button** as the target, because the original target is inside its shadow root.
|
||||||
|
|
||||||
|
* A listener on the **div** in **example-card**'s shadow DOM also receives **fancy-button** as the target, since they are in the same shadow DOM tree.
|
||||||
|
* A listener on the **example-card** receives the **example-card** itself as the target.
|
||||||
|
|
||||||
|
|
||||||
|
The event provides a **composedPath** method that returns an array of nodes that the event will pass through.
|
||||||
|
|
||||||
|
To allow a custom event to travel through a shadow DOM boundary and be retargeted, you need to create it with the **composed** flag set to **true**:
|
||||||
|
|
||||||
|
var event = new CustomEvent('my-event', {bubbles: true, composed: true});
|
||||||
|
|
||||||
|
## Shadow DOM styling
|
||||||
|
Styles inside a shadow tree are scoped to the shadow tree, and don't affect elements outside the shadow tree. Styles outside the shadow tree also don't match selectors inside the shadow tree.
|
||||||
|
|
||||||
|
There is one case where a style rule inside a shadow tree matches an element outside the shadow tree. You can define styles for the host element, using the **:host** pseudoclass or the **:host()** functional pseudoclass.
|
||||||
|
|
||||||
|
#shadow-root
|
||||||
|
<style>
|
||||||
|
/* custom elements default to display: inline */
|
||||||
|
:host {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
/* set a special background when the host element
|
||||||
|
has the .warning class */
|
||||||
|
:host(.warning) {
|
||||||
|
background-color: red;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
You can also style light DOM children that are assigned to slots using the **::slotted()** pseudoelement. For example,
|
||||||
|
|
||||||
|
#shadow-root
|
||||||
|
<style>
|
||||||
|
::slotted(img) {
|
||||||
|
border-radius: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
## Theming and custom properties
|
||||||
|
|
||||||
|
html {
|
||||||
|
--my-theme-color: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
The substitution can include default values to use if no property is set:
|
||||||
|
|
||||||
|
:host {
|
||||||
|
background-color: var(--my-theme-color, blue);
|
||||||
|
}
|
||||||
|
The default can even be another var() function:
|
||||||
|
|
||||||
|
background-color: var(--my-theme-color, var(--another-theme-color, blue));
|
||||||
|
|
||||||
|
|
||||||
|
#### Custom property mixins
|
||||||
|
|
||||||
|
Custom property mixins are a feature built on top of the custom property specification.
|
||||||
|
|
||||||
|
html {
|
||||||
|
--my-custom-mixin: {
|
||||||
|
color: white;
|
||||||
|
background-color: blue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
A component can import or mix in the entire set of rules using the @apply rule:
|
||||||
|
|
||||||
|
:host {
|
||||||
|
@apply --my-custom-mixin;
|
||||||
|
}
|
||||||
|
|
||||||
|
## Shadow DOM polyfills
|
||||||
|
|
||||||
|
|
||||||
|
The polyfills use a combination of techniques to emulate shadow DOM:
|
||||||
|
|
||||||
|
* Shady DOM. Maintains the logical divisions of shadow tree and descendant tree internally, so children added to the light DOM or shadow DOM render correctly. Patches DOM APIs on affected elements in order to emulate the native shadow DOM APIs.
|
||||||
|
* Shady CSS. Provides style encapsulation by adding classes to shadow DOM children and rewriting style rules so that they apply to the correct scope.
|
||||||
|
|
||||||
|
# Specify a DOM template
|
||||||
|
1.Define a template property on the constructor
|
||||||
|
|
||||||
|
import {PolymerElement, html} from '@polymer/polymer/polymer-element.js';
|
||||||
|
class MyElement extends PolymerElement {
|
||||||
|
static get template() {
|
||||||
|
return html`<style>:host { color: blue; }</style>
|
||||||
|
<h2>String template</h2>
|
||||||
|
<div>This is my template!</div>`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
customElements.define('my-element', MyElement);
|
||||||
|
2.Inherit a template from another Polymer element
|
||||||
|
|
||||||
|
#### Inherit a base class template without modifying it
|
||||||
|
Base class definition:
|
||||||
|
|
||||||
|
import {PolymerElement, html} from '@polymer/polymer/polymer-element.js';
|
||||||
|
export class BaseClass extends PolymerElement {
|
||||||
|
static get template() {
|
||||||
|
return html`This content has been inherited from BaseClass.`; }
|
||||||
|
}
|
||||||
|
customElements.define('base-class', BaseClass);
|
||||||
|
Child class definition:
|
||||||
|
|
||||||
|
import {PolymerElement, html} from '@polymer/polymer/polymer-element.js';
|
||||||
|
import {BaseClass} from './base-class.js'
|
||||||
|
export class ChildClass extends BaseClass {
|
||||||
|
// ... no template defined, child inherits
|
||||||
|
// parent's template
|
||||||
|
}
|
||||||
|
customElements.define('child-class', ChildClass);
|
||||||
|
|
||||||
|
#### Override a base class template in a child class
|
||||||
|
Base class definition:
|
||||||
|
|
||||||
|
import {PolymerElement, html} from '@polymer/polymer/polymer-element.js';
|
||||||
|
export class BaseClass extends PolymerElement {
|
||||||
|
static get template() {
|
||||||
|
return html`This content has been inherited from BaseClass.`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
customElements.define('base-class', BaseClass);
|
||||||
|
Child class definition:
|
||||||
|
|
||||||
|
import {PolymerElement, html} from '@polymer/polymer/polymer-element.js';
|
||||||
|
import {BaseClass} from './base-class.js'
|
||||||
|
export class ChildClass extends BaseClass {
|
||||||
|
static get template() {
|
||||||
|
return html`Base class template has been overridden. Hello from ChildClass!`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
customElements.define('child-class', ChildClass);
|
||||||
|
|
||||||
|
#### Extend a base class template in a child class
|
||||||
|
To extend a base class template, include the base class template in your child class template literal with the expression **${super.template}**. You will also need to tag the template literal with the html function:
|
||||||
|
|
||||||
|
Base class definition:
|
||||||
|
|
||||||
|
class BaseClass extends PolymerElement {
|
||||||
|
static get template() {
|
||||||
|
return html`
|
||||||
|
<p>This content has been inherited from BaseClass.</p>`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
customElements.define('base-class', BaseClass);
|
||||||
|
Child class definition:
|
||||||
|
|
||||||
|
class ChildClass extends BaseClass {
|
||||||
|
static get template() {
|
||||||
|
return html`
|
||||||
|
<p>This content is from ChildClass.</p>
|
||||||
|
<p>${super.template}</p>
|
||||||
|
<p>Hello again from ChildClass.</p>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
customElements.define('child-class', ChildClass);
|
||||||
|
#### Provide template extension points
|
||||||
|
You can provide template extension points by composing your base class template literal using expressions, like **${this.partialTemplate}**.
|
||||||
|
|
||||||
|
Base class definition:
|
||||||
|
|
||||||
|
export class BaseClass extends PolymerElement {
|
||||||
|
static get template() {
|
||||||
|
return html`
|
||||||
|
<div>${this.headerTemplate}</div>
|
||||||
|
<p>Hello this is some content</p>
|
||||||
|
<div>${this.footerTemplate}</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
static get headerTemplate() { return html`<h1>BaseClass: Header</h1>` }
|
||||||
|
static get footerTemplate() { return html`<h1>BaseClass: Footer</h1>` }
|
||||||
|
}
|
||||||
|
|
||||||
|
Child class definition:
|
||||||
|
|
||||||
|
export class ChildClass extends BaseClass {
|
||||||
|
// template definition inherited from BaseClass
|
||||||
|
|
||||||
|
// partial templates overridden by ChildClass
|
||||||
|
static get headerTemplate() { return html`<h2>ChildClass: Header</h2>` }
|
||||||
|
static get footerTemplate() { return html`<h2>ChildClass: Footer</h2>` }
|
||||||
|
}
|
||||||
|
|
||||||
|
## URLs in templates
|
||||||
|
To ensure URLs resolve properly, Polymer provides two properties that can be used in data bindings:
|
||||||
|
|
||||||
|
**importPath** -A static getter on the element class. To set URLs relative to the import, you must override the **importPath** getter.
|
||||||
|
|
||||||
|
For Example,
|
||||||
|
|
||||||
|
// This getter must be defined for your element if you want to use importPath
|
||||||
|
static get importPath() {
|
||||||
|
// return the base URL for this import
|
||||||
|
return import.meta.url;
|
||||||
|
}
|
||||||
|
|
||||||
|
static get template() {
|
||||||
|
return html`
|
||||||
|
<img src$="[[importPath]]checked.jpg">
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
|
**rootPath** -An instance property set to the value of **Polymer.rootPath** which is globally settable and defaults to the main document URL. It may be useful to set **Polymer.rootPath** to provide a stable application mount path when using client side routing.
|
||||||
|
|
||||||
|
<a href$="[[rootPath]]users/profile">View profile</a>
|
||||||
|
## Static node map
|
||||||
|
|
||||||
|
Any node specified in the element's template with an **id** is stored on the **this.$** hash by **id**.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
class MyElement extends PolymerElement {
|
||||||
|
static get template() {
|
||||||
|
return html`Hello World from <span id="name"></span>!`;
|
||||||
|
}
|
||||||
|
ready() {
|
||||||
|
super.ready();
|
||||||
|
this.$.name.textContent = this.tagName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
## Remove empty text nodes
|
||||||
|
Add the **strip-whitespace** boolean attribute to a template to remove any empty text nodes from the template's contents.
|
||||||
|
|
||||||
|
<dom-module id="no-whitespace">
|
||||||
|
<template strip-whitespace>
|
||||||
|
<div>Some Text</div>
|
||||||
|
<div>More Text</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
class NoWhitespace extends PolymerElement {
|
||||||
|
static get is() { return 'no-whitespace' }
|
||||||
|
ready() {
|
||||||
|
super.ready();
|
||||||
|
console.log(this.shadowRoot.childNodes.length); // 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
customElements.define(NoWhitespace.is, NoWhitespace);
|
||||||
|
</script>
|
||||||
|
</dom-module>
|
||||||
|
|
||||||
|
## Preserve template contents
|
||||||
|
If you want to access the contents of a nested template, you can add the **preserve-content** attribute to the template.
|
||||||
|
|
||||||
|
class CustomTemplate extends PolymerElement {
|
||||||
|
static get tempate() { return html`
|
||||||
|
<template id="special-template" preserve-content>
|
||||||
|
<div>I am very special.</div>
|
||||||
|
</template>`
|
||||||
|
}
|
||||||
|
ready() {
|
||||||
|
super.ready();
|
||||||
|
// retrieve the nested template
|
||||||
|
let template = this.shadowRoot.querySelector('#special-template');
|
||||||
|
|
||||||
|
//
|
||||||
|
for (let i=0; i<10; i++) {
|
||||||
|
this.shadowRoot.appendChild(document.importNode(template.content, true));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
customElements.define(CustomTemplate.is, CustomTemplate);
|
||||||
|
|
||||||
|
## Create your own shadow root
|
||||||
|
You may want to create your own shadow root. You can do this by creating a shadow root before calling **super.ready()**—or before the **ready** callback.
|
||||||
|
|
||||||
|
You can also override the _attachDom method:
|
||||||
|
|
||||||
|
_attachDom(dom) {
|
||||||
|
this.attachShadow({mode: 'open', delegatesFocus: true});
|
||||||
|
super._attachDom(dom);
|
||||||
|
}
|
||||||
|
|
||||||
|
# Style an element's shadow DOM
|
||||||
|
## Style your elements
|
||||||
|
|
||||||
|
Shadow DOM permits encapsulation of styling rules for custom elements. You can freely define styling information for your elements, such as fonts, text colors, and classes, without fear of the styles applying outside the scope of your element.
|
||||||
|
|
||||||
|
|
||||||
|
custom-element.js
|
||||||
|
|
||||||
|
...
|
||||||
|
static get template() {
|
||||||
|
return html`
|
||||||
|
<!-- Encapsulated, element-level stylesheet -->
|
||||||
|
<style>
|
||||||
|
p {
|
||||||
|
color: green;
|
||||||
|
}
|
||||||
|
.myclass {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<p>I'm a shadow DOM child element of <code>custom-element</code>.</p>
|
||||||
|
<p class="myclass">So am I.</p>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
index.html
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<script type="module" src="custom-element.js"></script>
|
||||||
|
<!-- Document-level stylesheet -->
|
||||||
|
<style>
|
||||||
|
.myclass {
|
||||||
|
color: blue;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<custom-element></custom-element>
|
||||||
|
<p class="myclass">I am outside of <code>custom-element</code>. Because of encapsulation, <code>custom-element</code>'s styles won't leak to me.</p>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
## Use inheritance from document-level styles
|
||||||
|
When used in an HTML document, your element will still inherit any styling information that applies to its parent element:
|
||||||
|
|
||||||
|
custom-element.js
|
||||||
|
|
||||||
|
...
|
||||||
|
static get template() {
|
||||||
|
return html`
|
||||||
|
<div>
|
||||||
|
I inherit styles from <code>custom-element</code>'s parent in the light DOM.
|
||||||
|
I'm also sans-serif and blue.
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
...
|
||||||
|
|
||||||
|
index.html
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<script type="module" src="custom-element.js"></script>
|
||||||
|
<!-- Document-level stylesheet -->
|
||||||
|
<style>
|
||||||
|
p {
|
||||||
|
font-family: sans-serif;
|
||||||
|
color:blue;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<!-- This paragraph uses document-level styles: -->
|
||||||
|
<p>I'm sans-serif and blue.</p>
|
||||||
|
|
||||||
|
<!-- And the text within custom-element inherits style from the paragraph element: -->
|
||||||
|
<p><custom-element></custom-element></p>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
Styles declared inside shadow DOM will override styles declared outside of it:
|
||||||
|
|
||||||
|
custom-element.js
|
||||||
|
|
||||||
|
...
|
||||||
|
static get template() {
|
||||||
|
return html`
|
||||||
|
<!-- Encapsulated, element-level stylesheet
|
||||||
|
overrides document-level stylesheet -->
|
||||||
|
<style>
|
||||||
|
p {
|
||||||
|
font-family: sans-serif;
|
||||||
|
color: green;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<p>I'm green.</p>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
...
|
||||||
|
|
||||||
|
index.html
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<script type="module" src="custom-element.js"></script>
|
||||||
|
<!-- Document-level stylesheet -->
|
||||||
|
<style>
|
||||||
|
p {
|
||||||
|
font-family: sans-serif;
|
||||||
|
color:blue;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<p>I'm blue.</p>
|
||||||
|
<p><custom-element></custom-element></p>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
## Style the host element
|
||||||
|
The element to which shadow DOM is attached is known as the host. To style the host, use the :host selector.
|
||||||
|
|
||||||
|
You can use CSS selectors to determine when and how to style the host. In this code sample:
|
||||||
|
|
||||||
|
* The selector :host matches any <custom-element> element
|
||||||
|
* The selector :host(.blue) matches <custom-element> elements of class blue
|
||||||
|
* The selector :host(.red) matches <custom-element> elements of class red
|
||||||
|
* The selector :host(:hover) matches <custom-element> elements when they are hovered over
|
||||||
|
|
||||||
|
custom-element.js
|
||||||
|
|
||||||
|
...
|
||||||
|
static get template() {
|
||||||
|
return html`
|
||||||
|
<style>
|
||||||
|
:host { font-family: sans-serif; }
|
||||||
|
:host(.blue) {color: blue;}
|
||||||
|
:host(.red) {color: red;}
|
||||||
|
:host(:hover) {color: green;}
|
||||||
|
</style>
|
||||||
|
<p>Hi, from custom-element!</p>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
...
|
||||||
|
|
||||||
|
index.html
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<script type="module" src="custom-element.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<custom-element class="blue"></custom-element>
|
||||||
|
<custom-element class="red"></custom-element>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
## Style slotted content (distributed children)
|
||||||
|
To style slotted content, use the ::slotted() syntax.
|
||||||
|
|
||||||
|
You can select by element type:
|
||||||
|
|
||||||
|
custom-element.js
|
||||||
|
|
||||||
|
...
|
||||||
|
static get template() {
|
||||||
|
return html`
|
||||||
|
<style>
|
||||||
|
h1 ::slotted(h1) {
|
||||||
|
font-family: sans-serif;
|
||||||
|
color: green;
|
||||||
|
}
|
||||||
|
p ::slotted(p) {
|
||||||
|
font-family: sans-serif;
|
||||||
|
color: blue;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<h1><slot name='heading1'></slot></h1>
|
||||||
|
<p><slot name='para'></slot></p>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
...
|
||||||
|
|
||||||
|
index.html
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<script type="module" src="custom-element.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<custom-element>
|
||||||
|
<h1 slot="heading1">Heading 1. I'm green.</h1>
|
||||||
|
<p slot="para">Paragraph text. I'm blue.</p>
|
||||||
|
</custom-element>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
You can select by class:
|
||||||
|
|
||||||
|
custom-element.js
|
||||||
|
|
||||||
|
...
|
||||||
|
static get template() {
|
||||||
|
return html`
|
||||||
|
<style>
|
||||||
|
p ::slotted(.green) {
|
||||||
|
color:green;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<p>
|
||||||
|
<slot name='para1'></slot>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<slot name='para2'></slot>
|
||||||
|
</p>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
...
|
||||||
|
index.html
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<script type="module" src="custom-element.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<custom-element>
|
||||||
|
<div slot="para1" class="green">I'm green!</div>
|
||||||
|
<div slot="para1">I'm not green.</div>
|
||||||
|
<div slot="para2" class="green">I'm green too.</div>
|
||||||
|
<div slot="para2">I'm not green.</div>
|
||||||
|
</custom-element>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
|
||||||
|
And you can select by slot name:
|
||||||
|
|
||||||
|
custom-element.js
|
||||||
|
|
||||||
|
...
|
||||||
|
static get template() {
|
||||||
|
return html`
|
||||||
|
<style>
|
||||||
|
p ::slotted([slot=para1]) {
|
||||||
|
color:green;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<p>
|
||||||
|
<slot name='para1'></slot>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<slot name='para2'></slot>
|
||||||
|
</p>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
...
|
||||||
|
index.html
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<script type="module" src="custom-element.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<custom-element>
|
||||||
|
<div slot="para1">I'm green.</div>
|
||||||
|
<div slot="para2">I'm not green.</div>
|
||||||
|
</custom-element>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
## Style directional text with the :dir() selector
|
||||||
|
The :dir() CSS selector allows for styling text specific to its orientation (right-to-left or left-to-right).
|
||||||
|
|
||||||
|
The **DirMixin** provides limited support for the **:dir()** selector. Use of **dir()** requires the application to set the **dir** attribute on <html>. All elements will use the same direction.
|
||||||
|
|
||||||
|
For elements that extend **PolymerElement**, add **DirMixin** to use **:dir()** styling.For Example,
|
||||||
|
|
||||||
|
using-dir-selector.js
|
||||||
|
|
||||||
|
import { PolymerElement, html } from '@polymer/polymer/polymer-element.js';
|
||||||
|
import DirMixin from '@polymer/polymer/lib/mixins/dir-mixin.js';
|
||||||
|
class UsingDirSelector extends DirMixin(PolymerElement) {
|
||||||
|
static get template() {
|
||||||
|
return html`
|
||||||
|
<style>
|
||||||
|
:host {
|
||||||
|
display: block;
|
||||||
|
color: blue;
|
||||||
|
}
|
||||||
|
:host(:dir(rtl)) {
|
||||||
|
color: green;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
...
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
customElements.define('using-dir-selector', UsingDirSelector);
|
||||||
|
|
||||||
|
index.html
|
||||||
|
|
||||||
|
<html lang="en" dir="rtl">
|
||||||
|
<head>
|
||||||
|
<script type="module" src="./using-dir-selector.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<using-dir-selector></using-dir-selector>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
|
## Use style modules
|
||||||
|
|
||||||
|
To create a style module:
|
||||||
|
|
||||||
|
1.Use JavaScript to create a <dom-module> element:
|
||||||
|
|
||||||
|
const styleElement = document.createElement('dom-module');
|
||||||
|
2.Set the <dom-module> element's innerHTML property to contain a **template** element that wraps a **style** block:
|
||||||
|
|
||||||
|
styleElement.innerHTML =
|
||||||
|
`<template>
|
||||||
|
<style>
|
||||||
|
/* Your shared styles go here */
|
||||||
|
</style>
|
||||||
|
</template>`;
|
||||||
|
|
||||||
|
3.Register your style module as an element:
|
||||||
|
|
||||||
|
styleElement.register('style-element');
|
||||||
|
|
||||||
|
You'll most likely want to package the style module in its own JavaScript file. The element that uses the styles will need to import that file. For example:
|
||||||
|
|
||||||
|
import './style-element.js';
|
||||||
|
|
||||||
|
When you create the element that will use the styles, include the style module in the opening tag of the style block:
|
||||||
|
|
||||||
|
static get template() {
|
||||||
|
return html`
|
||||||
|
<style include="style-element">
|
||||||
|
<!-- Any additional styles go here -->
|
||||||
|
</style>
|
||||||
|
<!-- The rest of your element template goes here -->
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
## Use custom-style in document-level styles
|
||||||
|
To ensure that your styles behave according to the Shadow DOM v1 specifications in all browsers, use custom-style when you define document-level styles
|
||||||
|
|
||||||
|
Import **custom-style** from **@polymer/polymer/lib/elements/custom-style.js**:
|
||||||
|
|
||||||
|
index.html
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<script src="./custom-element.js" type="module">
|
||||||
|
<script src="../@polymer/polymer/lib/elements/custom-style.js" type="module">
|
||||||
|
<custom-style>
|
||||||
|
<style>
|
||||||
|
/* Document-level styles go here */
|
||||||
|
</style>
|
||||||
|
</custom-style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<custom-element></custom-element>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
# Use custom properties
|
||||||
|
|
||||||
|
## Use the custom CSS properties provided by a Polymer element
|
||||||
|
The author of a Polymer element can provide custom CSS properties that you can use to style the appearance of the element in your application.
|
||||||
|
For Example,
|
||||||
|
|
||||||
|
index.html
|
||||||
|
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<script type="module" src="./flex-container.js">
|
||||||
|
<script type="module" src="./flex-item.js">
|
||||||
|
<!-- custom-style element invokes the custom properties polyfill -->
|
||||||
|
<script type="module" src="./node_modules/@polymer/polymer/lib/elements/custom-style.js"></script>
|
||||||
|
|
||||||
|
<!-- ensure that custom props are polyfilled on browsers that don't support them -->
|
||||||
|
<custom-style>
|
||||||
|
<style>
|
||||||
|
html {
|
||||||
|
/* Set a value for the custom CSS property --flex-direction */
|
||||||
|
--flex-direction: column
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</custom-style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<flex-container>
|
||||||
|
<flex-item>flex item 1</flex-item>
|
||||||
|
<!-- ... -->
|
||||||
|
<flex-item>flex item n</flex-item>
|
||||||
|
</flex-container>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
|
## Provide custom CSS properties to users of your elements
|
||||||
|
For example,
|
||||||
|
|
||||||
|
flex-container.js (your code)
|
||||||
|
|
||||||
|
/* ... */
|
||||||
|
class FlexContainer extends PolymerElement {
|
||||||
|
static get template () {
|
||||||
|
return html`
|
||||||
|
<style>
|
||||||
|
:host {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: var(--flex-direction);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<!-- ... -->
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* ... */
|
||||||
|
|
||||||
|
|
||||||
|
Users can then assign their own value to --flex-direction like so:
|
||||||
|
|
||||||
|
index.html (user's code)
|
||||||
|
|
||||||
|
|
||||||
|
...
|
||||||
|
<style>
|
||||||
|
html {
|
||||||
|
--flex-direction: column
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
...
|
||||||
|
|
||||||
|
## Create default values for your CSS properties
|
||||||
|
To set a default value for a CSS property, use the following syntax:
|
||||||
|
|
||||||
|
div {
|
||||||
|
background-color: var(--theme-background, #e3f2fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
## Inheritance and global styles
|
||||||
|
Custom CSS properties inherit down the DOM hierarchy. In the code sample below, <custom-element> will inherit the custom properties defined for div, but not the custom properties defined for span.
|
||||||
|
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<!-- custom-style element invokes the custom properties polyfill -->
|
||||||
|
<script type="module" src="node_modules/@polymer/polymer/lib/elements/custom-style.js"></script>
|
||||||
|
|
||||||
|
<!-- ensure that custom props are polyfilled on browsers that don't support them -->
|
||||||
|
<custom-style>
|
||||||
|
<style>
|
||||||
|
div {
|
||||||
|
/* flex-container is a child of div and will inherit these */
|
||||||
|
--theme-dark-blue: #0d47a1;
|
||||||
|
--theme-light-blue: #e3f2fd;
|
||||||
|
color: var(--theme-dark-blue);
|
||||||
|
background-color: var(--theme-light-blue);
|
||||||
|
}
|
||||||
|
span {
|
||||||
|
/* flex-container is not a child of span and will not inherit these */
|
||||||
|
--theme-wide-padding: 24px;
|
||||||
|
--theme-font-family: Roboto, Noto, sans-serif;
|
||||||
|
padding: var(--theme-wide-padding);
|
||||||
|
font-family: var(--theme-font-family);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</custom-style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div>
|
||||||
|
<flex-container>
|
||||||
|
<flex-item>flex item 1</flex-item>
|
||||||
|
<flex-item>flex item 2</flex-item>
|
||||||
|
<flex-item>flex item 3</flex-item>
|
||||||
|
</flex-container>
|
||||||
|
</div>
|
||||||
|
<span>
|
||||||
|
<p>hello i am in a span</p>
|
||||||
|
</span>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
|
## Use custom CSS mixins
|
||||||
|
Using CSS mixins, you can define a set of CSS properties as a single custom property.
|
||||||
|
|
||||||
|
selector {
|
||||||
|
--mixin-name: {
|
||||||
|
/* rules */
|
||||||
|
};
|
||||||
|
}
|
||||||
|
Use @apply to apply a mixin:
|
||||||
|
|
||||||
|
selector {
|
||||||
|
@apply --mixin-name;
|
||||||
|
}
|
||||||
|
Note that any element using the @apply syntax must import the **@apply** polyfill:
|
||||||
|
|
||||||
|
// import CSS mixins polyfill
|
||||||
|
import '@webcomponents/shadycss/entrypoints/apply-shim.js';
|
||||||
|
|
||||||
|
## Custom property API for Polymer elements
|
||||||
|
To update all elements on the page, you can also call Polymer.updateStyles.
|
||||||
|
|
||||||
|
**UpdateStyles** can take a object with property/value pairs to update the current values of custom properties.
|
||||||
|
|
||||||
|
Example
|
||||||
|
|
||||||
|
class XCustom extends PolymerElement {
|
||||||
|
static get changeTheme() {
|
||||||
|
return function() {
|
||||||
|
this.updateStyles({
|
||||||
|
'--my-toolbar-color': 'blue',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static template get (){
|
||||||
|
return html`
|
||||||
|
<style>
|
||||||
|
:host {
|
||||||
|
--my-toolbar-color: red;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<my-toolbar>My awesome app</my-toolbar>
|
||||||
|
<button on-tap="changeTheme">Change theme</button>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
customElements.define('x-custom', XCustom);
|
||||||
|
|
||||||
|
Occasionally an element needs to get the value of a custom property at runtime. This is handled slightly differently depending on whether the shady CSS polyfill is loaded:
|
||||||
|
|
||||||
|
if (ShadyCSS) {
|
||||||
|
style = ShadyCSS.getComputedStyleValue(this, '--something');
|
||||||
|
} else {
|
||||||
|
style = getComputedStyle(this).getPropertyValue('--something');
|
||||||
|
}
|
||||||
|
Elements using the legacy API can use the **getComputedStyleValue** instance method instead of testing for ShadyCSS.
|
||||||
31
Sqlite.md
Executable file
31
Sqlite.md
Executable file
@@ -0,0 +1,31 @@
|
|||||||
|
## Build Sqlite for FTS5 Support
|
||||||
|
##
|
||||||
|
> wget "https://www.sqlite.org/src/tarball/sqlite.tar.gz?r=release" -O sqlite.tar.gz
|
||||||
|
|
||||||
|
> tar -xzvf sqlite.tar.gz
|
||||||
|
|
||||||
|
> cd sqlite
|
||||||
|
|
||||||
|
> ./configure --enable-fts5
|
||||||
|
|
||||||
|
> make
|
||||||
|
|
||||||
|
> sudo make install
|
||||||
|
|
||||||
|
## Sqlite in Android emulator
|
||||||
|
```
|
||||||
|
// list connected devices
|
||||||
|
adb devices
|
||||||
|
|
||||||
|
// connect to the device
|
||||||
|
adb -s device_id shell
|
||||||
|
|
||||||
|
// switch to root
|
||||||
|
su
|
||||||
|
|
||||||
|
// change to database directory
|
||||||
|
cd /data/data/package_name/databases
|
||||||
|
|
||||||
|
// open databae file with sqlite3
|
||||||
|
sqlite3 database_file
|
||||||
|
```
|
||||||
52
SystemdService.md
Executable file
52
SystemdService.md
Executable file
@@ -0,0 +1,52 @@
|
|||||||
|
# systemd service file
|
||||||
|
> `application.service`
|
||||||
|
> ```
|
||||||
|
[Unit]
|
||||||
|
Description=Gogs (Go Git Service)
|
||||||
|
After=syslog.target
|
||||||
|
After=network.target
|
||||||
|
#After=postgresql.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
# Modify these two values and uncomment them if you have
|
||||||
|
# repos with lots of files and get an HTTP error 500 because
|
||||||
|
# of that
|
||||||
|
###
|
||||||
|
#LimitMEMLOCK=infinity
|
||||||
|
#LimitNOFILE=65535
|
||||||
|
Type=simple
|
||||||
|
User=git
|
||||||
|
Group=git
|
||||||
|
|
||||||
|
WorkingDirectory=/apps/gogs
|
||||||
|
ExecStart=/apps/gogs/gogs web
|
||||||
|
Restart=always
|
||||||
|
Environment=USER=git HOME=/home/git
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Copy config to systemd
|
||||||
|
> sudo cp ./gogs.service /etc/systemd/system
|
||||||
|
>
|
||||||
|
> sudo systemctl daemon-reload
|
||||||
|
|
||||||
|
## Start a service
|
||||||
|
> sudo systemctl start application.service
|
||||||
|
|
||||||
|
## Stop a service
|
||||||
|
> sudo systemctl stop application.service
|
||||||
|
|
||||||
|
## Restart a service
|
||||||
|
> sudo systemctl restart application.service
|
||||||
|
|
||||||
|
## To start a service at boot
|
||||||
|
> sudo systemctl enable application.service
|
||||||
|
|
||||||
|
## Disable a service starting at boot
|
||||||
|
> sudo systemctl disable application.service
|
||||||
|
|
||||||
|
## Check Status of a service
|
||||||
|
> systemctl status application.service
|
||||||
56
VPN.md
Executable file
56
VPN.md
Executable file
@@ -0,0 +1,56 @@
|
|||||||
|
|
||||||
|
## Renew Server Key
|
||||||
|
In CA Server
|
||||||
|
```
|
||||||
|
cd ~/EasyRSA-3.0.4/
|
||||||
|
sudo ./easyrsa gen-crl
|
||||||
|
sudo cp /home/causr/EasyRSA-3.0.4/pki/crl.pem /etc/openvpn/crl.pem
|
||||||
|
```
|
||||||
|
Restart vpnserver
|
||||||
|
```
|
||||||
|
sudo systemctl restart openvpn.service
|
||||||
|
sudo systemctl status openvpn.service
|
||||||
|
|
||||||
|
```
|
||||||
|
## Generate client key
|
||||||
|
|
||||||
|
In VPN Server
|
||||||
|
```
|
||||||
|
cd ~/EasyRSA-3.0.4/
|
||||||
|
./easyrsa gen-req client1 nopass
|
||||||
|
cp pki/private/client1.key ~/client-configs/keys/
|
||||||
|
scp pki/reqs/client1.req causr@ca_ip:/tmp
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
In CA Server
|
||||||
|
```
|
||||||
|
cd ~/EasyRSA-3.0.4/
|
||||||
|
./easyrsa import-req /tmp/client1.req client1
|
||||||
|
./easyrsa sign-req client client1
|
||||||
|
scp pki/issued/client1.crt sammy@your_server_ip:/tmp
|
||||||
|
```
|
||||||
|
|
||||||
|
In VPN Server
|
||||||
|
```
|
||||||
|
cp /tmp/client1.crt ~/client-configs/keys/
|
||||||
|
cd ~/client-configs
|
||||||
|
sudo ./make_config.sh client1
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Revoking Client Certificates
|
||||||
|
In CA Server
|
||||||
|
```
|
||||||
|
cd ~/EasyRSA-3.0.4/
|
||||||
|
./easyrsa revoke client2
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Install VPN manager in client for Ubuntu 18
|
||||||
|
```
|
||||||
|
sudo apt install network-manager-openvpn-gnome
|
||||||
|
```
|
||||||
|
|
||||||
|
https://www.digitalocean.com/community/tutorials/how-to-set-up-an-openvpn-server-on-ubuntu-18-04
|
||||||
80
ViEditor.md
Executable file
80
ViEditor.md
Executable file
@@ -0,0 +1,80 @@
|
|||||||
|
# How to Use the vi Editor
|
||||||
|
## Starting vi
|
||||||
|
|
||||||
|
vi filename -edit a file named "filename"
|
||||||
|
|
||||||
|
vi newfile -create a new file named "newfile"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## ENTERING TEXT
|
||||||
|
|
||||||
|
i -insert text left of cursor
|
||||||
|
|
||||||
|
a -append text right of cursorf cursor
|
||||||
|
|
||||||
|
|
||||||
|
## Moving the Cursor
|
||||||
|
To move the cursor to another position, you must be in command mode.
|
||||||
|
|
||||||
|
|
||||||
|
Key Cursor Movement
|
||||||
|
--- ---------------
|
||||||
|
h left one space
|
||||||
|
j down one line
|
||||||
|
k up one line
|
||||||
|
l right one space
|
||||||
|
w forward word by word
|
||||||
|
b backward word by word
|
||||||
|
$ to end of line
|
||||||
|
0 (zero) to beginning of line
|
||||||
|
H to top line of screen
|
||||||
|
M to middle line of screen
|
||||||
|
L to last line of screen
|
||||||
|
G to last line of file
|
||||||
|
1G to first line of file
|
||||||
|
<Control>f scroll forward one screen
|
||||||
|
<Control>b scroll backward one screen
|
||||||
|
<Control>d scroll down one-half screen
|
||||||
|
<Control>u scroll up one-half screen
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## BASIC EDITING
|
||||||
|
x delete character
|
||||||
|
nx delete n characters
|
||||||
|
X delete character before cursor
|
||||||
|
dw delete word
|
||||||
|
ndw delete n words
|
||||||
|
dd delete line
|
||||||
|
ndd delete n lines
|
||||||
|
D delete characters from cursor to end of line
|
||||||
|
r replace character under cursor
|
||||||
|
cw replace a word
|
||||||
|
ncw replace n words
|
||||||
|
C change text from cursor to end of line
|
||||||
|
o insert blank line below cursor
|
||||||
|
(ready for insertion)
|
||||||
|
O insert blank line above cursor
|
||||||
|
(ready for insertion)
|
||||||
|
J join succeeding line to current cursor line
|
||||||
|
nJ join n succeeding lines to current cursor line
|
||||||
|
u undo last change
|
||||||
|
U restore current line
|
||||||
|
|
||||||
|
|
||||||
|
## Moving by Searching
|
||||||
|
* Type / (slash).
|
||||||
|
* Enter the text to search for.
|
||||||
|
|
||||||
|
|
||||||
|
n -repeat last search in same direction
|
||||||
|
|
||||||
|
N -repeat last search in opposite direction
|
||||||
|
|
||||||
|
|
||||||
|
## Closing and Saving a File
|
||||||
|
|
||||||
|
ZZ -save file and then quit
|
||||||
|
:w -save file
|
||||||
|
:q! -discard changes and quit file
|
||||||
11
WirelessOnMacbookAir.md
Normal file
11
WirelessOnMacbookAir.md
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
1. Purge the broken driver
|
||||||
|
$sudo apt purge bcmwl-kernel-source broadcom-sta-dkms
|
||||||
|
|
||||||
|
2. Install the necessary Linux headers
|
||||||
|
$sudo apt update
|
||||||
|
$sudo apt install linux-headers-$(uname -r)
|
||||||
|
|
||||||
|
3. Install the correct firmware and package
|
||||||
|
$sudo apt install firmware-b43-installer broadcom-sta-dkms
|
||||||
|
|
||||||
|
4. Reboot
|
||||||
0
bash/.keep
Executable file
0
bash/.keep
Executable file
5
figma.md
Normal file
5
figma.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
|
||||||
|
### Figma Agnet for Linux
|
||||||
|
In Linux to use local fonts in Figma web broswer, **Figma agnet for linux** must be installed.
|
||||||
|
|
||||||
|
https://github.com/neetly/figma-agent-linux
|
||||||
61
flutter.md
Executable file
61
flutter.md
Executable file
@@ -0,0 +1,61 @@
|
|||||||
|
## App Store Screenshots Creators
|
||||||
|
https://www.appstorescreenshot.com/preview
|
||||||
|
|
||||||
|
## flutter commands
|
||||||
|
Create flutter project
|
||||||
|
|
||||||
|
`flutter create -i objc -a java --org com.mokkon.fcs_dev`
|
||||||
|
|
||||||
|
Build bundle
|
||||||
|
|
||||||
|
`flutter build appbundle -t lib/main-prod.dart --flavor prod`
|
||||||
|
|
||||||
|
Clean flutter build
|
||||||
|
|
||||||
|
`flutter clean`
|
||||||
|
|
||||||
|
List devices
|
||||||
|
|
||||||
|
`flutter devices`
|
||||||
|
|
||||||
|
Run current flutter project
|
||||||
|
|
||||||
|
`flutter run -d #device_id`
|
||||||
|
|
||||||
|
Get packages
|
||||||
|
|
||||||
|
`flutter pub get`
|
||||||
|
|
||||||
|
Upgrade flutter
|
||||||
|
|
||||||
|
`flutter upgrade`
|
||||||
|
|
||||||
|
Flutter doctor
|
||||||
|
|
||||||
|
`flutter doctor`
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
Layouts
|
||||||
|
https://medium.com/flutter-community/breaking-layouts-in-rows-and-columns-in-flutter-8ea1ce4c1316
|
||||||
|
|
||||||
|
Scroll
|
||||||
|
https://medium.com/@diegoveloper/flutter-lets-know-the-scrollcontroller-and-scrollnotification-652b2685a4ac
|
||||||
|
|
||||||
|
All widgets
|
||||||
|
https://itsallwidgets.com/
|
||||||
|
|
||||||
|
Widget Catalog
|
||||||
|
https://flutter.dev/docs/development/ui/widgets
|
||||||
|
|
||||||
|
Key Value Store
|
||||||
|
https://github.com/hivedb/hive
|
||||||
|
|
||||||
|
Complex UI
|
||||||
|
https://www.youtube.com/watch?v=FCyoHclCqc8
|
||||||
|
|
||||||
|
Animated Login
|
||||||
|
https://www.youtube.com/watch?v=NHAIiAmxTAU
|
||||||
|
|
||||||
|
Flutter Widget with RenderObject
|
||||||
|
https://nicksnettravels.builttoroam.com/create-a-flutter-widget/
|
||||||
9
react.md
Executable file
9
react.md
Executable file
@@ -0,0 +1,9 @@
|
|||||||
|
React library https://reactjs.org/
|
||||||
|
|
||||||
|
React Material UI https://material-ui.com/
|
||||||
|
|
||||||
|
Material UI templates https://material-ui.com/getting-started/templates/
|
||||||
|
|
||||||
|
Redux https://redux.js.org/
|
||||||
|
|
||||||
|
React Redux https://react-redux.js.org/
|
||||||
0
resource/README.md
Executable file
0
resource/README.md
Executable file
Reference in New Issue
Block a user