diff --git a/apps/demo-angular/package.json b/apps/demo-angular/package.json
index 79fa198..931a8e2 100644
--- a/apps/demo-angular/package.json
+++ b/apps/demo-angular/package.json
@@ -9,18 +9,19 @@
"@angular/platform-browser": "file:../../node_modules/@angular/platform-browser",
"@angular/platform-browser-dynamic": "file:../../node_modules/@angular/platform-browser-dynamic",
"@angular/router": "file:../../node_modules/@angular/router",
+ "@finalsite/rich-text-editor": "file:../../dist/packages/rich-text-editor",
"@nativescript/angular": "file:../../node_modules/@nativescript/angular",
"@nativescript/core": "file:../../node_modules/@nativescript/core",
+ "@nota/nativescript-webview-ext": "^8.0.2",
"nativescript-theme-core": "file:../../node_modules/nativescript-theme-core",
"reflect-metadata": "file:../../node_modules/reflect-metadata",
"rxjs": "file:../../node_modules/rxjs",
- "zone.js": "file:../../node_modules/zone.js",
- "@finalsite/rich-text-editor": "file:../../dist/packages/rich-text-editor"
+ "zone.js": "file:../../node_modules/zone.js"
},
"devDependencies": {
"@angular/compiler-cli": "file:../../node_modules/@angular/compiler-cli",
"@nativescript/android": "7.0.1",
- "@nativescript/ios": "7.2.0",
+ "@nativescript/ios": "^8.3.3",
"@nativescript/webpack": "~4.1.0",
"@ngtools/webpack": "file:../../node_modules/@ngtools/webpack",
"typescript": "~4.0.0"
diff --git a/apps/demo-angular/src/app.module.ts b/apps/demo-angular/src/app.module.ts
index c869e4d..743f564 100644
--- a/apps/demo-angular/src/app.module.ts
+++ b/apps/demo-angular/src/app.module.ts
@@ -1,6 +1,8 @@
import { NgModule, NO_ERRORS_SCHEMA } from '@angular/core';
import { NativeScriptModule } from '@nativescript/angular';
+import {WebViewExtModule} from "@nota/nativescript-webview-ext/angular"
+
import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module';
import { HomeComponent } from './home.component';
@@ -9,6 +11,6 @@ import { HomeComponent } from './home.component';
schemas: [NO_ERRORS_SCHEMA],
declarations: [AppComponent, HomeComponent],
bootstrap: [AppComponent],
- imports: [NativeScriptModule, AppRoutingModule],
+ imports: [NativeScriptModule, AppRoutingModule, WebViewExtModule],
})
export class AppModule {}
diff --git a/apps/demo-angular/src/assets/html/default.html b/apps/demo-angular/src/assets/html/default.html
new file mode 100644
index 0000000..45cf1a2
--- /dev/null
+++ b/apps/demo-angular/src/assets/html/default.html
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+ CKEditor
+
+
+
+
+
+
+
diff --git a/apps/demo-angular/src/assets/js/ckeditor4.js b/apps/demo-angular/src/assets/js/ckeditor4.js
new file mode 100644
index 0000000..b850c4d
--- /dev/null
+++ b/apps/demo-angular/src/assets/js/ckeditor4.js
@@ -0,0 +1,165 @@
+// bridge interface for a regular content editable div
+let nsWebViewBridge;
+const waitCKEDITOR = setInterval(function () {
+ if (!window.CKEDITOR) return;
+ clearInterval(waitCKEDITOR);
+
+ nsWebViewBridge = window.nsWebViewBridge;
+ if (nsWebViewBridge) {
+ initBridge();
+ } else {
+ window.addEventListener('ns-bridge-ready', function (e) {
+ nsWebViewBridge = e.detail;
+ initBridge();
+ });
+ }
+}, 10);
+
+const insertHeadScript = function (src) {
+ var externalScript = document.createElement('script');
+ externalScript.setAttribute('src', src);
+ document.head.appendChild(externalScript);
+};
+
+const insertHeadCSS = function (src) {
+ var externalCSS = document.createElement('link');
+ externalCSS.setAttribute('rel', 'stylesheet');
+ externalCSS.setAttribute('type', 'text/css');
+ externalCSS.setAttribute('href', src);
+ document.head.appendChild(externalCSS);
+};
+
+let currentSavedSelection;
+const saveSelectionPromise = function () {
+ currentSavedSelection = CKEDITOR.instances.editor.getSelection().createBookmarks();
+ return Promise.resolve();
+};
+
+const restoreSelectionPromise = function () {
+ CKEDITOR.instances.editor.getSelection().selectBookmarks(currentSavedSelection);
+ return Promise.resolve();
+};
+
+const getHtmlPromise = function () {
+ return Promise.resolve(CKEDITOR.instances.editor.getData());
+};
+
+function initBridge() {
+ // android can end up reloading the html a lot and end up in a weird state somehow :/
+ if (CKEDITOR.instances.editor) CKEDITOR.instances.editor.destroy();
+
+ const editorDiv = document.getElementById('editor');
+
+ // disable UI things that we're replacing with native buttons
+ const editorInstance = CKEDITOR.inline('editor', {
+ extraPlugins: 'justify,indentblock,indentlist',
+ removePlugins: 'liststyle,tableselection,tabletools,tableresize,contextmenu,toolbar',
+ allowedContent: true,
+ toolbar: [],
+ });
+
+ nsWebViewBridge.on('sourceChanged', function (data) {
+ editorInstance.setData(data);
+ });
+
+ nsWebViewBridge.on('done', function (data) {
+ editorInstance.focusManager.blur(true);
+ editorInstance.getSelection().removeAllRanges();
+ editorDiv.blur();
+ });
+
+ /*
+ * handle regular commands that dont take arguments
+ */
+ const CKE_COMMAND_MAP = {
+ insertorderedlist: 'numberedlist',
+ insertunorderedlist: 'bulletedlist',
+ };
+ const commonListeners = ['undo', 'redo', 'removeFormat', 'bold', 'underline', 'italic', 'justifyleft', 'justifycenter', 'justifyright', 'insertorderedlist', 'insertunorderedlist', 'outdent', 'indent'];
+ commonListeners.forEach((event) => {
+ nsWebViewBridge.on(event, (value) => {
+ value = value || null;
+ event = CKE_COMMAND_MAP[event] || event;
+ editorInstance.execCommand(event, false, value);
+ });
+ });
+
+ /*
+ * Commands that take an argument are usually just CKEDITOR styles applied to selected text
+ */
+ const CKE_COMMAND_STYLE_MAP = {
+ formatblock: (value) => new CKEDITOR.style({ element: value }),
+ createLink: (value) => new CKEDITOR.style({ element: 'a', attributes: { href: value }, type: CKEDITOR.STYLE_INLINE }),
+ backcolor: (value) => new CKEDITOR.style({ element: 'span', styles: { 'background-color': value } }),
+ fontname: (value) => {
+ return new CKEDITOR.style({
+ element: 'span',
+ styles: { 'font-family': value },
+ overrides: [
+ {
+ element: 'font',
+ attributes: { face: null },
+ },
+ ],
+ });
+ },
+ fontsize: (value) => {
+ return new CKEDITOR.style({
+ element: 'span',
+ styles: { 'font-size': value },
+ overrides: [
+ {
+ element: 'font',
+ attributes: { size: null },
+ },
+ ],
+ });
+ },
+ forecolor: (value) => {
+ return new CKEDITOR.style({
+ element: 'span',
+ styles: { color: value },
+ overrides: [
+ {
+ element: 'font',
+ attributes: { color: null },
+ },
+ ],
+ });
+ },
+ };
+
+ Object.keys(CKE_COMMAND_STYLE_MAP).forEach((event) => {
+ nsWebViewBridge.on(event, (value) => {
+ if (!value) return;
+ editorInstance.applyStyle(CKE_COMMAND_STYLE_MAP[event](value));
+ });
+ });
+
+ editorInstance.on('instanceReady', () => {
+ editorInstance.on(
+ 'doubleclick',
+ function (evt) {
+ // TODO: emit this to the native side maybe?
+ return false;
+ },
+ null,
+ null,
+ 1
+ ); // last param gives this priority
+
+ editorInstance.on('focus', function (event) {
+ nsWebViewBridge.emit('focus');
+ });
+
+ editorInstance.on('blur', function (event) {
+ nsWebViewBridge.emit('blur');
+ });
+
+ editorInstance.on('change', function (event) {
+ nsWebViewBridge.emit('input', editorInstance.getData());
+ });
+
+ nsWebViewBridge.emit('ready');
+ });
+}
diff --git a/apps/demo-angular/src/assets/js/contenteditable.js b/apps/demo-angular/src/assets/js/contenteditable.js
new file mode 100644
index 0000000..1228f98
--- /dev/null
+++ b/apps/demo-angular/src/assets/js/contenteditable.js
@@ -0,0 +1,158 @@
+// bridge interface for a regular content editable div
+
+const nsWebViewBridge = window.nsWebViewBridge;
+
+if (nsWebViewBridge) {
+ initBridge();
+} else {
+ window.addEventListener('ns-bridge-ready', function (e) {
+ const nsWebViewBridge = e.detail;
+ initBridge();
+ });
+}
+
+const insertHeadScript = function (src) {
+ var externalScript = document.createElement('script');
+ externalScript.setAttribute('src', src);
+ document.head.appendChild(externalScript);
+};
+
+const insertHeadCSS = function (src) {
+ var externalCSS = document.createElement('link');
+ externalCSS.setAttribute('rel', 'stylesheet');
+ externalCSS.setAttribute('type', 'text/css');
+ externalCSS.setAttribute('href', src);
+ document.head.appendChild(externalCSS);
+};
+
+let currentSavedSelection;
+const saveSelectionPromise = function () {
+ const editorInstance = document.getElementById('editor');
+ const range = window.getSelection().getRangeAt(0);
+ const preSelectionRange = range.cloneRange();
+ preSelectionRange.selectNodeContents(editorInstance);
+ preSelectionRange.setEnd(range.startContainer, range.startOffset);
+ const start = preSelectionRange.toString().length;
+
+ currentSavedSelection = {
+ start: start,
+ end: start + range.toString().length,
+ };
+ return Promise.resolve();
+};
+
+const restoreSelectionPromise = function () {
+ const editorInstance = document.getElementById('editor');
+ let charIndex = 0,
+ range = document.createRange();
+ range.setStart(editorInstance, 0);
+ range.collapse(true);
+ let nodeStack = [editorInstance],
+ node,
+ foundStart = false,
+ stop = false;
+
+ while (!stop && (node = nodeStack.pop())) {
+ if (node.nodeType == 3) {
+ const nextCharIndex = charIndex + node.length;
+ if (!foundStart && currentSavedSelection.start >= charIndex && currentSavedSelection.start <= nextCharIndex) {
+ range.setStart(node, currentSavedSelection.start - charIndex);
+ foundStart = true;
+ }
+ if (foundStart && currentSavedSelection.end >= charIndex && currentSavedSelection.end <= nextCharIndex) {
+ range.setEnd(node, currentSavedSelection.end - charIndex);
+ stop = true;
+ }
+ charIndex = nextCharIndex;
+ } else {
+ let i = node.childNodes.length;
+ while (i--) {
+ nodeStack.push(node.childNodes[i]);
+ }
+ }
+ }
+
+ const sel = window.getSelection();
+ sel.removeAllRanges();
+ sel.addRange(range);
+
+ return Promise.resolve();
+};
+
+const getHtmlPromise = function () {
+ const editorInstance = document.getElementById('editor');
+ return Promise.resolve(editorInstance.innerHTML);
+};
+
+function initBridge() {
+ const editorInstance = document.getElementById('editor');
+
+ editorInstance.addEventListener(
+ 'blur',
+ () => {
+ nsWebViewBridge.emit('blur');
+ },
+ false
+ );
+ editorInstance.addEventListener(
+ 'focus',
+ () => {
+ nsWebViewBridge.emit('focus');
+ },
+ false
+ );
+ editorInstance.addEventListener(
+ 'input',
+ () => {
+ nsWebViewBridge.emit('input', editorInstance.innerHTML);
+ },
+ false
+ );
+
+ nsWebViewBridge.on('sourceChanged', function (data) {
+ editorInstance.innerHTML = data;
+ });
+
+ nsWebViewBridge.on('focus', function () {
+ editorInstance.focus();
+ });
+
+ nsWebViewBridge.on('done', function () {
+ window.getSelection().removeAllRanges();
+ editorInstance.blur();
+ });
+
+ nsWebViewBridge.on('fontsize', (value) => {
+ document.execCommand('fontsize', false, '7');
+ const fontElements = document.getElementsByTagName('font');
+ for (let i = 0, len = fontElements.length; i < len; ++i) {
+ if (fontElements[i].size == '7') {
+ fontElements[i].removeAttribute('size');
+ fontElements[i].style.fontSize = value;
+ }
+ }
+ editorInstance.dispatchEvent(new Event('input'));
+ });
+
+ nsWebViewBridge.on('fontname', (value) => {
+ document.execCommand('fontsize', false, '7');
+ const fontElements = document.getElementsByTagName('font');
+ for (let i = 0, len = fontElements.length; i < len; ++i) {
+ if (fontElements[i].size == '7') {
+ fontElements[i].removeAttribute('size');
+ fontElements[i].style.fontFamily = value;
+ }
+ }
+ editorInstance.dispatchEvent(new Event('input'));
+ });
+
+ const commonListeners = ['undo', 'redo', 'removeFormat', 'bold', 'underline', 'italic', 'justifyleft', 'justifycenter', 'justifyright', 'insertorderedlist', 'insertunorderedlist', 'outdent', 'indent', 'createLink', 'formatblock', 'forecolor', 'backcolor'];
+ commonListeners.forEach((event) => {
+ nsWebViewBridge.on(event, (value) => {
+ value = value || null;
+ document.execCommand(event, false, value);
+ });
+ });
+
+ nsWebViewBridge.emit('ready');
+}
diff --git a/apps/demo-angular/src/plugin-demos/rich-text-editor.component.html b/apps/demo-angular/src/plugin-demos/rich-text-editor.component.html
index dff21c8..117ec47 100644
--- a/apps/demo-angular/src/plugin-demos/rich-text-editor.component.html
+++ b/apps/demo-angular/src/plugin-demos/rich-text-editor.component.html
@@ -1,8 +1,7 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
diff --git a/apps/demo-angular/src/plugin-demos/rich-text-editor.component.ts b/apps/demo-angular/src/plugin-demos/rich-text-editor.component.ts
index c9debbc..aaa5536 100644
--- a/apps/demo-angular/src/plugin-demos/rich-text-editor.component.ts
+++ b/apps/demo-angular/src/plugin-demos/rich-text-editor.component.ts
@@ -8,10 +8,24 @@ import {} from '@finalsite/rich-text-editor';
})
export class RichTextEditorComponent {
demoShared: DemoSharedRichTextEditor;
+ _editorContent: string =
+ '
Leonardo Nicknamed Leo , is a fictional superhero and one of the four main characters in the Teenage Mutant Ninja Turtles comics and related media.
He is often depicted wearing a blue bandanna. His signature weapons are two Ninjatos , commonly confused as Katanas . Leonardo is the eldest brother and the leader of the group. He is the most skilled, the most serious, the most spiritual, the most mature, the most disciplined and the most in-line with Splinter's teachings and thoughts. Like all of the brothers, he is named after an Italian Renaissance artist, in this case Leonardo da Vinci . Leonardo da Vinci is widely considered the most diversely skilled individual of the Renaissance period, and as such Leonardo is also considered the most diversely skilled ninja turtle. In the Mirage comics, all four of the Turtles wear red masks, but for the creators to tell them apart, he was written and redrawn to have an ocean-blue mask.
Raphael Nicknamed Raph , is a fictional superhero and one of the four main characters of the Teenage Mutant Ninja Turtles comics and all related media. He is generally depicted as the second oldest/mid-middle-child of the turtle brothers, but has once been portrayed as the eldest.
He is usually depicted wearing a red eye mask; in this regard he is the only turtle to retain the color in all media, whereas the others each received a different color. Raphael wields twin sai , the points of which are usually sharpened, as his primary weapon. Raphael is most famous for his temperamental and cynical personality, being short-tempered, aggressive, sullen, maddened, sarcastic, and rebellious. He is portrayed in most interaction as speaking with a Brooklyn accent . It may be a coincidence, but the fact that he has a bad and fiery attitude and temper and the fact that his mask is still red may be linked, since the color red is typically associated with anger.
The origin of Raphael's anger is not always fully explored, but in some incarnations appears to stem partly from the realization that they are the only creatures of their kind and ultimately alone. He also has a somewhat rival relationship with his only older brother Leonardo because he is seen as the group's leader. Raphael also gives his younger and youngest brother Michelangelo a hard time because of Michelangelo’s fiery optimism. He is the second eldest of the turtles, and second-in-command . Like all of the brothers, he is named after a Renaissance artist; in this case, he is named after the 16th-century Italian painter Raphael . In 2011, Raphael placed 23rd on IGN 's Top 100 Comic Book Heroes, a list that did not feature any of his brothers. He is the only Teenage Turtle brother whose name does not end in the letter "O".
[https://en.wikipedia.org/wiki/Teenage_Mutant_Ninja_Turtles ]
';
constructor(private _ngZone: NgZone) {}
ngOnInit() {
this.demoShared = new DemoSharedRichTextEditor();
}
+
+ onViewSource() {
+ alert(this._editorContent)
+ }
+
+ get editorContent() {
+ return this._editorContent;
+ }
+
+ set editorContent(content) {
+ this._editorContent = content
+ }
}
diff --git a/apps/demo-angular/src/plugin-demos/rich-text-editor.module.ts b/apps/demo-angular/src/plugin-demos/rich-text-editor.module.ts
index e03b975..f28d503 100644
--- a/apps/demo-angular/src/plugin-demos/rich-text-editor.module.ts
+++ b/apps/demo-angular/src/plugin-demos/rich-text-editor.module.ts
@@ -1,9 +1,10 @@
import { NgModule, NO_ERRORS_SCHEMA } from '@angular/core';
import { NativeScriptCommonModule, NativeScriptRouterModule } from '@nativescript/angular';
import { RichTextEditorComponent } from './rich-text-editor.component';
+import { NativeScriptRichTextEditorModule } from '@finalsite/rich-text-editor/angular'
@NgModule({
- imports: [NativeScriptCommonModule, NativeScriptRouterModule.forChild([{ path: '', component: RichTextEditorComponent }])],
+ imports: [NativeScriptCommonModule, NativeScriptRichTextEditorModule, NativeScriptRouterModule.forChild([{ path: '', component: RichTextEditorComponent }])],
declarations: [RichTextEditorComponent],
schemas: [NO_ERRORS_SCHEMA],
})
diff --git a/apps/demo-angular/webpack.config.js b/apps/demo-angular/webpack.config.js
index 77e424b..283e687 100644
--- a/apps/demo-angular/webpack.config.js
+++ b/apps/demo-angular/webpack.config.js
@@ -329,7 +329,7 @@ module.exports = (env) => {
verbose: !!verbose,
}),
// Copy assets
- new CopyWebpackPlugin([...copyTargets, { from: { glob: '**/*.jpg', dot: false } }, { from: { glob: '**/*.png', dot: false } }], copyIgnore),
+ new CopyWebpackPlugin([...copyTargets, { from: { glob: 'assets/**', dot: false } }, { from: { glob: 'fonts/**', dot: false } }, { from: { glob: '**/*.jpg', dot: false } }, { from: { glob: '**/*.png', dot: false } }], copyIgnore),
new nsWebpack.GenerateNativeScriptEntryPointsPlugin('bundle'),
// For instructions on how to set up workers with webpack
// check out https://github.com/nativescript/worker-loader
diff --git a/apps/demo-vue/.editorconfig b/apps/demo-vue/.editorconfig
new file mode 100644
index 0000000..84ba4fa
--- /dev/null
+++ b/apps/demo-vue/.editorconfig
@@ -0,0 +1,19 @@
+root = true
+
+[*]
+end_of_line = lf
+insert_final_newline = true
+trim_trailing_whitespace = true
+charset = utf-8
+
+[*.json]
+indent_style = space
+indent_size = 2
+
+[*.js]
+indent_style = space
+indent_size = 2
+
+[*.ts]
+indent_style = space
+indent_size = 2
\ No newline at end of file
diff --git a/apps/demo-vue/.gitignore b/apps/demo-vue/.gitignore
new file mode 100644
index 0000000..1cb1231
--- /dev/null
+++ b/apps/demo-vue/.gitignore
@@ -0,0 +1,28 @@
+# NativeScript
+hooks/
+node_modules/
+platforms/
+
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+
+# General
+.DS_Store
+.AppleDouble
+.LSOverride
+.idea
+.cloud
+.project
+tmp/
+typings/
+
+# Visual Studio Code
+.vscode/*
+!.vscode/settings.json
+!.vscode/tasks.json
+!.vscode/launch.json
+!.vscode/extensions.json
diff --git a/apps/demo-vue/.vscode/extensions.json b/apps/demo-vue/.vscode/extensions.json
new file mode 100644
index 0000000..2a163b8
--- /dev/null
+++ b/apps/demo-vue/.vscode/extensions.json
@@ -0,0 +1,3 @@
+{
+ "recommendations": ["nativescript.nativescript"]
+}
diff --git a/apps/demo-vue/App_Resources/Android/app.gradle b/apps/demo-vue/App_Resources/Android/app.gradle
new file mode 100644
index 0000000..5b26299
--- /dev/null
+++ b/apps/demo-vue/App_Resources/Android/app.gradle
@@ -0,0 +1,25 @@
+// You can add your native dependencies here
+dependencies {
+// implementation 'androidx.multidex:multidex:2.0.1'
+}
+
+android {
+ // compileSdkVersion 32
+ // buildToolsVersion "32.0.0"
+ // ndkVersion ""
+
+ defaultConfig {
+ minSdkVersion 17
+ // targetSdkVersion 32
+
+ // Version Information
+ versionCode 1
+ versionName "1.0.0"
+
+ generatedDensities = []
+ }
+
+ aaptOptions {
+ additionalParameters "--no-version-vectors"
+ }
+}
diff --git a/apps/demo-vue/App_Resources/Android/before-plugins.gradle b/apps/demo-vue/App_Resources/Android/before-plugins.gradle
new file mode 100644
index 0000000..9faffb8
--- /dev/null
+++ b/apps/demo-vue/App_Resources/Android/before-plugins.gradle
@@ -0,0 +1,15 @@
+// this configurations is loaded before building plugins, as well as before building
+// the app - this is where you can apply global settings and overrides
+
+project.ext {
+ // androidXAppCompat = "1.4.1"
+ // androidXExifInterface = "1.3.3"
+ // androidXFragment = "1.4.1"
+ // androidXMaterial = "1.5.0"
+ // androidXMultidex = "2.0.1"
+ // androidXTransition = "1.4.1"
+ // androidXViewPager = "1.0.0"
+
+ // useKotlin = true
+ // kotlinVersion = "1.6.0"
+}
diff --git a/apps/demo-vue/App_Resources/Android/src/main/AndroidManifest.xml b/apps/demo-vue/App_Resources/Android/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..6601773
--- /dev/null
+++ b/apps/demo-vue/App_Resources/Android/src/main/AndroidManifest.xml
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/demo-vue/App_Resources/Android/src/main/res/drawable-hdpi/background.png b/apps/demo-vue/App_Resources/Android/src/main/res/drawable-hdpi/background.png
new file mode 100644
index 0000000..bbefbf4
Binary files /dev/null and b/apps/demo-vue/App_Resources/Android/src/main/res/drawable-hdpi/background.png differ
diff --git a/apps/demo-vue/App_Resources/Android/src/main/res/drawable-hdpi/logo.png b/apps/demo-vue/App_Resources/Android/src/main/res/drawable-hdpi/logo.png
new file mode 100644
index 0000000..e788deb
Binary files /dev/null and b/apps/demo-vue/App_Resources/Android/src/main/res/drawable-hdpi/logo.png differ
diff --git a/apps/demo-vue/App_Resources/Android/src/main/res/drawable-ldpi/background.png b/apps/demo-vue/App_Resources/Android/src/main/res/drawable-ldpi/background.png
new file mode 100644
index 0000000..f6a08ee
Binary files /dev/null and b/apps/demo-vue/App_Resources/Android/src/main/res/drawable-ldpi/background.png differ
diff --git a/apps/demo-vue/App_Resources/Android/src/main/res/drawable-ldpi/logo.png b/apps/demo-vue/App_Resources/Android/src/main/res/drawable-ldpi/logo.png
new file mode 100644
index 0000000..e4cac1a
Binary files /dev/null and b/apps/demo-vue/App_Resources/Android/src/main/res/drawable-ldpi/logo.png differ
diff --git a/apps/demo-vue/App_Resources/Android/src/main/res/drawable-mdpi/background.png b/apps/demo-vue/App_Resources/Android/src/main/res/drawable-mdpi/background.png
new file mode 100644
index 0000000..0c90f0f
Binary files /dev/null and b/apps/demo-vue/App_Resources/Android/src/main/res/drawable-mdpi/background.png differ
diff --git a/apps/demo-vue/App_Resources/Android/src/main/res/drawable-mdpi/logo.png b/apps/demo-vue/App_Resources/Android/src/main/res/drawable-mdpi/logo.png
new file mode 100644
index 0000000..ce3c3a4
Binary files /dev/null and b/apps/demo-vue/App_Resources/Android/src/main/res/drawable-mdpi/logo.png differ
diff --git a/apps/demo-vue/App_Resources/Android/src/main/res/drawable-nodpi/splash_screen.xml b/apps/demo-vue/App_Resources/Android/src/main/res/drawable-nodpi/splash_screen.xml
new file mode 100644
index 0000000..ada77f9
--- /dev/null
+++ b/apps/demo-vue/App_Resources/Android/src/main/res/drawable-nodpi/splash_screen.xml
@@ -0,0 +1,8 @@
+
+ -
+
+
+ -
+
+
+
\ No newline at end of file
diff --git a/apps/demo-vue/App_Resources/Android/src/main/res/drawable-xhdpi/background.png b/apps/demo-vue/App_Resources/Android/src/main/res/drawable-xhdpi/background.png
new file mode 100644
index 0000000..3541570
Binary files /dev/null and b/apps/demo-vue/App_Resources/Android/src/main/res/drawable-xhdpi/background.png differ
diff --git a/apps/demo-vue/App_Resources/Android/src/main/res/drawable-xhdpi/logo.png b/apps/demo-vue/App_Resources/Android/src/main/res/drawable-xhdpi/logo.png
new file mode 100644
index 0000000..88267df
Binary files /dev/null and b/apps/demo-vue/App_Resources/Android/src/main/res/drawable-xhdpi/logo.png differ
diff --git a/apps/demo-vue/App_Resources/Android/src/main/res/drawable-xxhdpi/background.png b/apps/demo-vue/App_Resources/Android/src/main/res/drawable-xxhdpi/background.png
new file mode 100644
index 0000000..abb0fc7
Binary files /dev/null and b/apps/demo-vue/App_Resources/Android/src/main/res/drawable-xxhdpi/background.png differ
diff --git a/apps/demo-vue/App_Resources/Android/src/main/res/drawable-xxhdpi/logo.png b/apps/demo-vue/App_Resources/Android/src/main/res/drawable-xxhdpi/logo.png
new file mode 100644
index 0000000..55800c9
Binary files /dev/null and b/apps/demo-vue/App_Resources/Android/src/main/res/drawable-xxhdpi/logo.png differ
diff --git a/apps/demo-vue/App_Resources/Android/src/main/res/drawable-xxxhdpi/background.png b/apps/demo-vue/App_Resources/Android/src/main/res/drawable-xxxhdpi/background.png
new file mode 100644
index 0000000..1089775
Binary files /dev/null and b/apps/demo-vue/App_Resources/Android/src/main/res/drawable-xxxhdpi/background.png differ
diff --git a/apps/demo-vue/App_Resources/Android/src/main/res/drawable-xxxhdpi/logo.png b/apps/demo-vue/App_Resources/Android/src/main/res/drawable-xxxhdpi/logo.png
new file mode 100644
index 0000000..0703f90
Binary files /dev/null and b/apps/demo-vue/App_Resources/Android/src/main/res/drawable-xxxhdpi/logo.png differ
diff --git a/apps/demo-vue/App_Resources/Android/src/main/res/drawable/ic_launcher_foreground.xml b/apps/demo-vue/App_Resources/Android/src/main/res/drawable/ic_launcher_foreground.xml
new file mode 100644
index 0000000..fd826a3
--- /dev/null
+++ b/apps/demo-vue/App_Resources/Android/src/main/res/drawable/ic_launcher_foreground.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
diff --git a/apps/demo-vue/App_Resources/Android/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/apps/demo-vue/App_Resources/Android/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 0000000..7353dbd
--- /dev/null
+++ b/apps/demo-vue/App_Resources/Android/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/apps/demo-vue/App_Resources/Android/src/main/res/mipmap-hdpi/ic_launcher.png b/apps/demo-vue/App_Resources/Android/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..69948d2
Binary files /dev/null and b/apps/demo-vue/App_Resources/Android/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/apps/demo-vue/App_Resources/Android/src/main/res/mipmap-mdpi/ic_launcher.png b/apps/demo-vue/App_Resources/Android/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..90a58cd
Binary files /dev/null and b/apps/demo-vue/App_Resources/Android/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/apps/demo-vue/App_Resources/Android/src/main/res/mipmap-xhdpi/ic_launcher.png b/apps/demo-vue/App_Resources/Android/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..70a2a0d
Binary files /dev/null and b/apps/demo-vue/App_Resources/Android/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/apps/demo-vue/App_Resources/Android/src/main/res/mipmap-xxhdpi/ic_launcher.png b/apps/demo-vue/App_Resources/Android/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..1ee5a94
Binary files /dev/null and b/apps/demo-vue/App_Resources/Android/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/apps/demo-vue/App_Resources/Android/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/apps/demo-vue/App_Resources/Android/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000..66e9d4b
Binary files /dev/null and b/apps/demo-vue/App_Resources/Android/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/apps/demo-vue/App_Resources/Android/src/main/res/values-v21/colors.xml b/apps/demo-vue/App_Resources/Android/src/main/res/values-v21/colors.xml
new file mode 100644
index 0000000..da5ca2f
--- /dev/null
+++ b/apps/demo-vue/App_Resources/Android/src/main/res/values-v21/colors.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/apps/demo-vue/App_Resources/Android/src/main/res/values-v21/styles.xml b/apps/demo-vue/App_Resources/Android/src/main/res/values-v21/styles.xml
new file mode 100644
index 0000000..04d8a06
--- /dev/null
+++ b/apps/demo-vue/App_Resources/Android/src/main/res/values-v21/styles.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/demo-vue/App_Resources/Android/src/main/res/values-v29/styles.xml b/apps/demo-vue/App_Resources/Android/src/main/res/values-v29/styles.xml
new file mode 100644
index 0000000..9a2a79d
--- /dev/null
+++ b/apps/demo-vue/App_Resources/Android/src/main/res/values-v29/styles.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/apps/demo-vue/App_Resources/Android/src/main/res/values/colors.xml b/apps/demo-vue/App_Resources/Android/src/main/res/values/colors.xml
new file mode 100644
index 0000000..78c4a51
--- /dev/null
+++ b/apps/demo-vue/App_Resources/Android/src/main/res/values/colors.xml
@@ -0,0 +1,14 @@
+
+
+
+ #F5F5F5
+
+
+ #757575
+
+
+ #65ADF1
+
+
+
+
diff --git a/apps/demo-vue/App_Resources/Android/src/main/res/values/ic_launcher_background.xml b/apps/demo-vue/App_Resources/Android/src/main/res/values/ic_launcher_background.xml
new file mode 100644
index 0000000..c5d5899
--- /dev/null
+++ b/apps/demo-vue/App_Resources/Android/src/main/res/values/ic_launcher_background.xml
@@ -0,0 +1,4 @@
+
+
+ #FFFFFF
+
\ No newline at end of file
diff --git a/apps/demo-vue/App_Resources/Android/src/main/res/values/styles.xml b/apps/demo-vue/App_Resources/Android/src/main/res/values/styles.xml
new file mode 100644
index 0000000..4f91b61
--- /dev/null
+++ b/apps/demo-vue/App_Resources/Android/src/main/res/values/styles.xml
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/demo-vue/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/Contents.json b/apps/demo-vue/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000..1a8b0e6
--- /dev/null
+++ b/apps/demo-vue/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,122 @@
+{
+ "images" : [
+ {
+ "size" : "20x20",
+ "idiom" : "iphone",
+ "filename" : "icon-20@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "20x20",
+ "idiom" : "iphone",
+ "filename" : "icon-20@3x.png",
+ "scale" : "3x"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "iphone",
+ "filename" : "icon-29.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "iphone",
+ "filename" : "icon-29@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "iphone",
+ "filename" : "icon-29@3x.png",
+ "scale" : "3x"
+ },
+ {
+ "size" : "40x40",
+ "idiom" : "iphone",
+ "filename" : "icon-40@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "40x40",
+ "idiom" : "iphone",
+ "filename" : "icon-40@3x.png",
+ "scale" : "3x"
+ },
+ {
+ "size" : "60x60",
+ "idiom" : "iphone",
+ "filename" : "icon-60@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "60x60",
+ "idiom" : "iphone",
+ "filename" : "icon-60@3x.png",
+ "scale" : "3x"
+ },
+ {
+ "size" : "20x20",
+ "idiom" : "ipad",
+ "filename" : "icon-20.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "20x20",
+ "idiom" : "ipad",
+ "filename" : "icon-20@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "ipad",
+ "filename" : "icon-29.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "ipad",
+ "filename" : "icon-29@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "40x40",
+ "idiom" : "ipad",
+ "filename" : "icon-40.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "40x40",
+ "idiom" : "ipad",
+ "filename" : "icon-40@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "icon-76.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "icon-76@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "83.5x83.5",
+ "idiom" : "ipad",
+ "filename" : "icon-83.5@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "1024x1024",
+ "idiom" : "ios-marketing",
+ "filename" : "icon-1024.png",
+ "scale" : "1x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/apps/demo-vue/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-1024.png b/apps/demo-vue/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-1024.png
new file mode 100644
index 0000000..b46c8bb
Binary files /dev/null and b/apps/demo-vue/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-1024.png differ
diff --git a/apps/demo-vue/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-20.png b/apps/demo-vue/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-20.png
new file mode 100644
index 0000000..d73288a
Binary files /dev/null and b/apps/demo-vue/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-20.png differ
diff --git a/apps/demo-vue/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-20@2x.png b/apps/demo-vue/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-20@2x.png
new file mode 100644
index 0000000..c8d24cd
Binary files /dev/null and b/apps/demo-vue/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-20@2x.png differ
diff --git a/apps/demo-vue/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-20@3x.png b/apps/demo-vue/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-20@3x.png
new file mode 100644
index 0000000..1b00c84
Binary files /dev/null and b/apps/demo-vue/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-20@3x.png differ
diff --git a/apps/demo-vue/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-29.png b/apps/demo-vue/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-29.png
new file mode 100644
index 0000000..72a1641
Binary files /dev/null and b/apps/demo-vue/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-29.png differ
diff --git a/apps/demo-vue/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-29@2x.png b/apps/demo-vue/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-29@2x.png
new file mode 100644
index 0000000..05ab752
Binary files /dev/null and b/apps/demo-vue/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-29@2x.png differ
diff --git a/apps/demo-vue/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-29@3x.png b/apps/demo-vue/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-29@3x.png
new file mode 100644
index 0000000..ee72082
Binary files /dev/null and b/apps/demo-vue/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-29@3x.png differ
diff --git a/apps/demo-vue/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-40.png b/apps/demo-vue/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-40.png
new file mode 100644
index 0000000..2859288
Binary files /dev/null and b/apps/demo-vue/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-40.png differ
diff --git a/apps/demo-vue/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-40@2x.png b/apps/demo-vue/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-40@2x.png
new file mode 100644
index 0000000..88824fa
Binary files /dev/null and b/apps/demo-vue/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-40@2x.png differ
diff --git a/apps/demo-vue/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-40@3x.png b/apps/demo-vue/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-40@3x.png
new file mode 100644
index 0000000..02a930c
Binary files /dev/null and b/apps/demo-vue/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-40@3x.png differ
diff --git a/apps/demo-vue/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-60@2x.png b/apps/demo-vue/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-60@2x.png
new file mode 100644
index 0000000..d7b077f
Binary files /dev/null and b/apps/demo-vue/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-60@2x.png differ
diff --git a/apps/demo-vue/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-60@3x.png b/apps/demo-vue/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-60@3x.png
new file mode 100644
index 0000000..2f872dd
Binary files /dev/null and b/apps/demo-vue/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-60@3x.png differ
diff --git a/apps/demo-vue/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-76.png b/apps/demo-vue/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-76.png
new file mode 100644
index 0000000..7fb23a7
Binary files /dev/null and b/apps/demo-vue/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-76.png differ
diff --git a/apps/demo-vue/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-76@2x.png b/apps/demo-vue/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-76@2x.png
new file mode 100644
index 0000000..cb04c36
Binary files /dev/null and b/apps/demo-vue/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-76@2x.png differ
diff --git a/apps/demo-vue/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-83.5@2x.png b/apps/demo-vue/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-83.5@2x.png
new file mode 100644
index 0000000..e882226
Binary files /dev/null and b/apps/demo-vue/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-83.5@2x.png differ
diff --git a/apps/demo-vue/App_Resources/iOS/Assets.xcassets/Contents.json b/apps/demo-vue/App_Resources/iOS/Assets.xcassets/Contents.json
new file mode 100644
index 0000000..da4a164
--- /dev/null
+++ b/apps/demo-vue/App_Resources/iOS/Assets.xcassets/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/apps/demo-vue/App_Resources/iOS/Assets.xcassets/LaunchScreen.AspectFill.imageset/Contents.json b/apps/demo-vue/App_Resources/iOS/Assets.xcassets/LaunchScreen.AspectFill.imageset/Contents.json
new file mode 100644
index 0000000..ab5edd0
--- /dev/null
+++ b/apps/demo-vue/App_Resources/iOS/Assets.xcassets/LaunchScreen.AspectFill.imageset/Contents.json
@@ -0,0 +1,23 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "LaunchScreen-AspectFill.png",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "LaunchScreen-AspectFill@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "LaunchScreen-AspectFill@3x.png",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/apps/demo-vue/App_Resources/iOS/Assets.xcassets/LaunchScreen.AspectFill.imageset/LaunchScreen-AspectFill.png b/apps/demo-vue/App_Resources/iOS/Assets.xcassets/LaunchScreen.AspectFill.imageset/LaunchScreen-AspectFill.png
new file mode 100644
index 0000000..cb35cfa
Binary files /dev/null and b/apps/demo-vue/App_Resources/iOS/Assets.xcassets/LaunchScreen.AspectFill.imageset/LaunchScreen-AspectFill.png differ
diff --git a/apps/demo-vue/App_Resources/iOS/Assets.xcassets/LaunchScreen.AspectFill.imageset/LaunchScreen-AspectFill@2x.png b/apps/demo-vue/App_Resources/iOS/Assets.xcassets/LaunchScreen.AspectFill.imageset/LaunchScreen-AspectFill@2x.png
new file mode 100644
index 0000000..6eefb9a
Binary files /dev/null and b/apps/demo-vue/App_Resources/iOS/Assets.xcassets/LaunchScreen.AspectFill.imageset/LaunchScreen-AspectFill@2x.png differ
diff --git a/apps/demo-vue/App_Resources/iOS/Assets.xcassets/LaunchScreen.AspectFill.imageset/LaunchScreen-AspectFill@3x.png b/apps/demo-vue/App_Resources/iOS/Assets.xcassets/LaunchScreen.AspectFill.imageset/LaunchScreen-AspectFill@3x.png
new file mode 100644
index 0000000..0ef5102
Binary files /dev/null and b/apps/demo-vue/App_Resources/iOS/Assets.xcassets/LaunchScreen.AspectFill.imageset/LaunchScreen-AspectFill@3x.png differ
diff --git a/apps/demo-vue/App_Resources/iOS/Assets.xcassets/LaunchScreen.Center.imageset/Contents.json b/apps/demo-vue/App_Resources/iOS/Assets.xcassets/LaunchScreen.Center.imageset/Contents.json
new file mode 100644
index 0000000..444d715
--- /dev/null
+++ b/apps/demo-vue/App_Resources/iOS/Assets.xcassets/LaunchScreen.Center.imageset/Contents.json
@@ -0,0 +1,23 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "LaunchScreen-Center.png",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "LaunchScreen-Center@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "LaunchScreen-Center@3x.png",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/apps/demo-vue/App_Resources/iOS/Assets.xcassets/LaunchScreen.Center.imageset/LaunchScreen-Center.png b/apps/demo-vue/App_Resources/iOS/Assets.xcassets/LaunchScreen.Center.imageset/LaunchScreen-Center.png
new file mode 100644
index 0000000..280c30e
Binary files /dev/null and b/apps/demo-vue/App_Resources/iOS/Assets.xcassets/LaunchScreen.Center.imageset/LaunchScreen-Center.png differ
diff --git a/apps/demo-vue/App_Resources/iOS/Assets.xcassets/LaunchScreen.Center.imageset/LaunchScreen-Center@2x.png b/apps/demo-vue/App_Resources/iOS/Assets.xcassets/LaunchScreen.Center.imageset/LaunchScreen-Center@2x.png
new file mode 100644
index 0000000..f984b9e
Binary files /dev/null and b/apps/demo-vue/App_Resources/iOS/Assets.xcassets/LaunchScreen.Center.imageset/LaunchScreen-Center@2x.png differ
diff --git a/apps/demo-vue/App_Resources/iOS/Assets.xcassets/LaunchScreen.Center.imageset/LaunchScreen-Center@3x.png b/apps/demo-vue/App_Resources/iOS/Assets.xcassets/LaunchScreen.Center.imageset/LaunchScreen-Center@3x.png
new file mode 100644
index 0000000..95d86f3
Binary files /dev/null and b/apps/demo-vue/App_Resources/iOS/Assets.xcassets/LaunchScreen.Center.imageset/LaunchScreen-Center@3x.png differ
diff --git a/apps/demo-vue/App_Resources/iOS/Info.plist b/apps/demo-vue/App_Resources/iOS/Info.plist
new file mode 100644
index 0000000..ea3e3ea
--- /dev/null
+++ b/apps/demo-vue/App_Resources/iOS/Info.plist
@@ -0,0 +1,47 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ en
+ CFBundleDisplayName
+ ${PRODUCT_NAME}
+ CFBundleExecutable
+ ${EXECUTABLE_NAME}
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ ${PRODUCT_NAME}
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ 1.0
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ 1.0
+ LSRequiresIPhoneOS
+
+ UILaunchStoryboardName
+ LaunchScreen
+ UIRequiresFullScreen
+
+ UIRequiredDeviceCapabilities
+
+ armv7
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+
+
diff --git a/apps/demo-vue/App_Resources/iOS/LaunchScreen.storyboard b/apps/demo-vue/App_Resources/iOS/LaunchScreen.storyboard
new file mode 100644
index 0000000..c4e5a3f
--- /dev/null
+++ b/apps/demo-vue/App_Resources/iOS/LaunchScreen.storyboard
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/demo-vue/App_Resources/iOS/build.xcconfig b/apps/demo-vue/App_Resources/iOS/build.xcconfig
new file mode 100644
index 0000000..0d38fe0
--- /dev/null
+++ b/apps/demo-vue/App_Resources/iOS/build.xcconfig
@@ -0,0 +1,6 @@
+// You can add custom settings here
+// for example you can uncomment the following line to force distribution code signing
+// CODE_SIGN_IDENTITY = iPhone Distribution
+// To build for device with XCode you need to specify your development team.
+// DEVELOPMENT_TEAM = YOUR_TEAM_ID;
+ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
diff --git a/apps/demo-vue/app/app.js b/apps/demo-vue/app/app.js
new file mode 100644
index 0000000..f37ae73
--- /dev/null
+++ b/apps/demo-vue/app/app.js
@@ -0,0 +1,10 @@
+import Vue from 'nativescript-vue'
+
+import Home from './components/Home'
+
+import RichTextEditor from "@finalsite/rich-text-editor/vue"
+RichTextEditor.install(Vue)
+
+new Vue({
+ render: (h) => h('frame', [h(Home)]),
+}).$start()
diff --git a/apps/demo-vue/app/app.scss b/apps/demo-vue/app/app.scss
new file mode 100644
index 0000000..9c3948e
--- /dev/null
+++ b/apps/demo-vue/app/app.scss
@@ -0,0 +1,21 @@
+@import '@nativescript/theme/core';
+@import '@nativescript/theme/default';
+
+// Place any CSS rules you want to apply on both iOS and Android here.
+// This is where the vast majority of your CSS code goes.
+
+// Font icon class
+.fab {
+ font-family: 'Font Awesome 5 Brands', 'fa-brands-400';
+ font-weight: 400;
+}
+
+.fas {
+ font-family: 'Font Awesome 5 Free', 'fa-solid-900';
+ font-weight: 900;
+}
+
+.far {
+ font-family: 'Font Awesome 5 Free', 'fa-regular-400';
+ font-weight: 400;
+}
diff --git a/apps/demo-vue/app/assets/html/default.html b/apps/demo-vue/app/assets/html/default.html
new file mode 100644
index 0000000..45cf1a2
--- /dev/null
+++ b/apps/demo-vue/app/assets/html/default.html
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+ CKEditor
+
+
+
+
+
+
+
diff --git a/apps/demo-vue/app/assets/js/ckeditor4.js b/apps/demo-vue/app/assets/js/ckeditor4.js
new file mode 100644
index 0000000..b850c4d
--- /dev/null
+++ b/apps/demo-vue/app/assets/js/ckeditor4.js
@@ -0,0 +1,165 @@
+// bridge interface for a regular content editable div
+let nsWebViewBridge;
+const waitCKEDITOR = setInterval(function () {
+ if (!window.CKEDITOR) return;
+ clearInterval(waitCKEDITOR);
+
+ nsWebViewBridge = window.nsWebViewBridge;
+ if (nsWebViewBridge) {
+ initBridge();
+ } else {
+ window.addEventListener('ns-bridge-ready', function (e) {
+ nsWebViewBridge = e.detail;
+ initBridge();
+ });
+ }
+}, 10);
+
+const insertHeadScript = function (src) {
+ var externalScript = document.createElement('script');
+ externalScript.setAttribute('src', src);
+ document.head.appendChild(externalScript);
+};
+
+const insertHeadCSS = function (src) {
+ var externalCSS = document.createElement('link');
+ externalCSS.setAttribute('rel', 'stylesheet');
+ externalCSS.setAttribute('type', 'text/css');
+ externalCSS.setAttribute('href', src);
+ document.head.appendChild(externalCSS);
+};
+
+let currentSavedSelection;
+const saveSelectionPromise = function () {
+ currentSavedSelection = CKEDITOR.instances.editor.getSelection().createBookmarks();
+ return Promise.resolve();
+};
+
+const restoreSelectionPromise = function () {
+ CKEDITOR.instances.editor.getSelection().selectBookmarks(currentSavedSelection);
+ return Promise.resolve();
+};
+
+const getHtmlPromise = function () {
+ return Promise.resolve(CKEDITOR.instances.editor.getData());
+};
+
+function initBridge() {
+ // android can end up reloading the html a lot and end up in a weird state somehow :/
+ if (CKEDITOR.instances.editor) CKEDITOR.instances.editor.destroy();
+
+ const editorDiv = document.getElementById('editor');
+
+ // disable UI things that we're replacing with native buttons
+ const editorInstance = CKEDITOR.inline('editor', {
+ extraPlugins: 'justify,indentblock,indentlist',
+ removePlugins: 'liststyle,tableselection,tabletools,tableresize,contextmenu,toolbar',
+ allowedContent: true,
+ toolbar: [],
+ });
+
+ nsWebViewBridge.on('sourceChanged', function (data) {
+ editorInstance.setData(data);
+ });
+
+ nsWebViewBridge.on('done', function (data) {
+ editorInstance.focusManager.blur(true);
+ editorInstance.getSelection().removeAllRanges();
+ editorDiv.blur();
+ });
+
+ /*
+ * handle regular commands that dont take arguments
+ */
+ const CKE_COMMAND_MAP = {
+ insertorderedlist: 'numberedlist',
+ insertunorderedlist: 'bulletedlist',
+ };
+ const commonListeners = ['undo', 'redo', 'removeFormat', 'bold', 'underline', 'italic', 'justifyleft', 'justifycenter', 'justifyright', 'insertorderedlist', 'insertunorderedlist', 'outdent', 'indent'];
+ commonListeners.forEach((event) => {
+ nsWebViewBridge.on(event, (value) => {
+ value = value || null;
+ event = CKE_COMMAND_MAP[event] || event;
+ editorInstance.execCommand(event, false, value);
+ });
+ });
+
+ /*
+ * Commands that take an argument are usually just CKEDITOR styles applied to selected text
+ */
+ const CKE_COMMAND_STYLE_MAP = {
+ formatblock: (value) => new CKEDITOR.style({ element: value }),
+ createLink: (value) => new CKEDITOR.style({ element: 'a', attributes: { href: value }, type: CKEDITOR.STYLE_INLINE }),
+ backcolor: (value) => new CKEDITOR.style({ element: 'span', styles: { 'background-color': value } }),
+ fontname: (value) => {
+ return new CKEDITOR.style({
+ element: 'span',
+ styles: { 'font-family': value },
+ overrides: [
+ {
+ element: 'font',
+ attributes: { face: null },
+ },
+ ],
+ });
+ },
+ fontsize: (value) => {
+ return new CKEDITOR.style({
+ element: 'span',
+ styles: { 'font-size': value },
+ overrides: [
+ {
+ element: 'font',
+ attributes: { size: null },
+ },
+ ],
+ });
+ },
+ forecolor: (value) => {
+ return new CKEDITOR.style({
+ element: 'span',
+ styles: { color: value },
+ overrides: [
+ {
+ element: 'font',
+ attributes: { color: null },
+ },
+ ],
+ });
+ },
+ };
+
+ Object.keys(CKE_COMMAND_STYLE_MAP).forEach((event) => {
+ nsWebViewBridge.on(event, (value) => {
+ if (!value) return;
+ editorInstance.applyStyle(CKE_COMMAND_STYLE_MAP[event](value));
+ });
+ });
+
+ editorInstance.on('instanceReady', () => {
+ editorInstance.on(
+ 'doubleclick',
+ function (evt) {
+ // TODO: emit this to the native side maybe?
+ return false;
+ },
+ null,
+ null,
+ 1
+ ); // last param gives this priority
+
+ editorInstance.on('focus', function (event) {
+ nsWebViewBridge.emit('focus');
+ });
+
+ editorInstance.on('blur', function (event) {
+ nsWebViewBridge.emit('blur');
+ });
+
+ editorInstance.on('change', function (event) {
+ nsWebViewBridge.emit('input', editorInstance.getData());
+ });
+
+ nsWebViewBridge.emit('ready');
+ });
+}
diff --git a/apps/demo-vue/app/assets/js/contenteditable.js b/apps/demo-vue/app/assets/js/contenteditable.js
new file mode 100644
index 0000000..1228f98
--- /dev/null
+++ b/apps/demo-vue/app/assets/js/contenteditable.js
@@ -0,0 +1,158 @@
+// bridge interface for a regular content editable div
+
+const nsWebViewBridge = window.nsWebViewBridge;
+
+if (nsWebViewBridge) {
+ initBridge();
+} else {
+ window.addEventListener('ns-bridge-ready', function (e) {
+ const nsWebViewBridge = e.detail;
+ initBridge();
+ });
+}
+
+const insertHeadScript = function (src) {
+ var externalScript = document.createElement('script');
+ externalScript.setAttribute('src', src);
+ document.head.appendChild(externalScript);
+};
+
+const insertHeadCSS = function (src) {
+ var externalCSS = document.createElement('link');
+ externalCSS.setAttribute('rel', 'stylesheet');
+ externalCSS.setAttribute('type', 'text/css');
+ externalCSS.setAttribute('href', src);
+ document.head.appendChild(externalCSS);
+};
+
+let currentSavedSelection;
+const saveSelectionPromise = function () {
+ const editorInstance = document.getElementById('editor');
+ const range = window.getSelection().getRangeAt(0);
+ const preSelectionRange = range.cloneRange();
+ preSelectionRange.selectNodeContents(editorInstance);
+ preSelectionRange.setEnd(range.startContainer, range.startOffset);
+ const start = preSelectionRange.toString().length;
+
+ currentSavedSelection = {
+ start: start,
+ end: start + range.toString().length,
+ };
+ return Promise.resolve();
+};
+
+const restoreSelectionPromise = function () {
+ const editorInstance = document.getElementById('editor');
+ let charIndex = 0,
+ range = document.createRange();
+ range.setStart(editorInstance, 0);
+ range.collapse(true);
+ let nodeStack = [editorInstance],
+ node,
+ foundStart = false,
+ stop = false;
+
+ while (!stop && (node = nodeStack.pop())) {
+ if (node.nodeType == 3) {
+ const nextCharIndex = charIndex + node.length;
+ if (!foundStart && currentSavedSelection.start >= charIndex && currentSavedSelection.start <= nextCharIndex) {
+ range.setStart(node, currentSavedSelection.start - charIndex);
+ foundStart = true;
+ }
+ if (foundStart && currentSavedSelection.end >= charIndex && currentSavedSelection.end <= nextCharIndex) {
+ range.setEnd(node, currentSavedSelection.end - charIndex);
+ stop = true;
+ }
+ charIndex = nextCharIndex;
+ } else {
+ let i = node.childNodes.length;
+ while (i--) {
+ nodeStack.push(node.childNodes[i]);
+ }
+ }
+ }
+
+ const sel = window.getSelection();
+ sel.removeAllRanges();
+ sel.addRange(range);
+
+ return Promise.resolve();
+};
+
+const getHtmlPromise = function () {
+ const editorInstance = document.getElementById('editor');
+ return Promise.resolve(editorInstance.innerHTML);
+};
+
+function initBridge() {
+ const editorInstance = document.getElementById('editor');
+
+ editorInstance.addEventListener(
+ 'blur',
+ () => {
+ nsWebViewBridge.emit('blur');
+ },
+ false
+ );
+ editorInstance.addEventListener(
+ 'focus',
+ () => {
+ nsWebViewBridge.emit('focus');
+ },
+ false
+ );
+ editorInstance.addEventListener(
+ 'input',
+ () => {
+ nsWebViewBridge.emit('input', editorInstance.innerHTML);
+ },
+ false
+ );
+
+ nsWebViewBridge.on('sourceChanged', function (data) {
+ editorInstance.innerHTML = data;
+ });
+
+ nsWebViewBridge.on('focus', function () {
+ editorInstance.focus();
+ });
+
+ nsWebViewBridge.on('done', function () {
+ window.getSelection().removeAllRanges();
+ editorInstance.blur();
+ });
+
+ nsWebViewBridge.on('fontsize', (value) => {
+ document.execCommand('fontsize', false, '7');
+ const fontElements = document.getElementsByTagName('font');
+ for (let i = 0, len = fontElements.length; i < len; ++i) {
+ if (fontElements[i].size == '7') {
+ fontElements[i].removeAttribute('size');
+ fontElements[i].style.fontSize = value;
+ }
+ }
+ editorInstance.dispatchEvent(new Event('input'));
+ });
+
+ nsWebViewBridge.on('fontname', (value) => {
+ document.execCommand('fontsize', false, '7');
+ const fontElements = document.getElementsByTagName('font');
+ for (let i = 0, len = fontElements.length; i < len; ++i) {
+ if (fontElements[i].size == '7') {
+ fontElements[i].removeAttribute('size');
+ fontElements[i].style.fontFamily = value;
+ }
+ }
+ editorInstance.dispatchEvent(new Event('input'));
+ });
+
+ const commonListeners = ['undo', 'redo', 'removeFormat', 'bold', 'underline', 'italic', 'justifyleft', 'justifycenter', 'justifyright', 'insertorderedlist', 'insertunorderedlist', 'outdent', 'indent', 'createLink', 'formatblock', 'forecolor', 'backcolor'];
+ commonListeners.forEach((event) => {
+ nsWebViewBridge.on(event, (value) => {
+ value = value || null;
+ document.execCommand(event, false, value);
+ });
+ });
+
+ nsWebViewBridge.emit('ready');
+}
diff --git a/apps/demo-vue/app/components/Home.vue b/apps/demo-vue/app/components/Home.vue
new file mode 100644
index 0000000..957300f
--- /dev/null
+++ b/apps/demo-vue/app/components/Home.vue
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/demo-vue/app/fonts/fa-brands-400.ttf b/apps/demo-vue/app/fonts/fa-brands-400.ttf
new file mode 100644
index 0000000..0a30775
Binary files /dev/null and b/apps/demo-vue/app/fonts/fa-brands-400.ttf differ
diff --git a/apps/demo-vue/app/fonts/fa-regular-400.ttf b/apps/demo-vue/app/fonts/fa-regular-400.ttf
new file mode 100644
index 0000000..b5414de
Binary files /dev/null and b/apps/demo-vue/app/fonts/fa-regular-400.ttf differ
diff --git a/apps/demo-vue/app/fonts/fa-solid-900.ttf b/apps/demo-vue/app/fonts/fa-solid-900.ttf
new file mode 100644
index 0000000..53c8f36
Binary files /dev/null and b/apps/demo-vue/app/fonts/fa-solid-900.ttf differ
diff --git a/apps/demo-vue/jsconfig.json b/apps/demo-vue/jsconfig.json
new file mode 100644
index 0000000..c904a96
--- /dev/null
+++ b/apps/demo-vue/jsconfig.json
@@ -0,0 +1,10 @@
+{
+ "compilerOptions": {
+ "baseUrl": "./",
+ "paths": {
+ "~/*": ["app/*"],
+ "@/*": ["app/*"]
+ }
+ },
+ "include": ["app/**/*"]
+}
diff --git a/apps/demo-vue/nativescript.config.ts b/apps/demo-vue/nativescript.config.ts
new file mode 100644
index 0000000..8964bec
--- /dev/null
+++ b/apps/demo-vue/nativescript.config.ts
@@ -0,0 +1,11 @@
+import { NativeScriptConfig } from '@nativescript/core';
+
+export default {
+ id: 'org.nativescript.demovue',
+ appPath: 'app',
+ appResourcesPath: 'App_Resources',
+ android: {
+ v8Flags: '--expose_gc',
+ markingMode: 'none'
+ }
+} as NativeScriptConfig;
\ No newline at end of file
diff --git a/apps/demo-vue/package.json b/apps/demo-vue/package.json
new file mode 100644
index 0000000..502b266
--- /dev/null
+++ b/apps/demo-vue/package.json
@@ -0,0 +1,18 @@
+{
+ "name": "demo-vue",
+ "main": "app/app.js",
+ "version": "1.0.0",
+ "private": true,
+ "dependencies": {
+ "@finalsite/rich-text-editor": "file:../../dist/packages/rich-text-editor",
+ "@nativescript/core": "~8.3.0",
+ "@nativescript/theme": "~3.0.2",
+ "@nota/nativescript-webview-ext": "^8.0.2",
+ "nativescript-vue": "~2.9.0"
+ },
+ "devDependencies": {
+ "@nativescript/ios": "8.3.3",
+ "@nativescript/webpack": "~5.0.6",
+ "nativescript-vue-template-compiler": "~2.9.0"
+ }
+}
diff --git a/apps/demo-vue/webpack.config.js b/apps/demo-vue/webpack.config.js
new file mode 100644
index 0000000..a561e0e
--- /dev/null
+++ b/apps/demo-vue/webpack.config.js
@@ -0,0 +1,12 @@
+const webpack = require("@nativescript/webpack");
+
+module.exports = (env) => {
+ webpack.init(env);
+
+ // Learn how to customize:
+ // https://docs.nativescript.org/webpack
+
+ return webpack.resolveConfig();
+};
+
+
diff --git a/apps/demo/package.json b/apps/demo/package.json
index 5b02c8d..4f5aa59 100644
--- a/apps/demo/package.json
+++ b/apps/demo/package.json
@@ -10,7 +10,7 @@
},
"devDependencies": {
"@nativescript/android": "7.0.1",
- "@nativescript/ios": "7.2.0",
+ "@nativescript/ios": "^8.3.3",
"@nativescript/webpack": "~4.1.0",
"typescript": "~4.0.0"
}
diff --git a/packages/rich-text-editor/README.md b/packages/rich-text-editor/README.md
index c889253..1377bc6 100644
--- a/packages/rich-text-editor/README.md
+++ b/packages/rich-text-editor/README.md
@@ -59,11 +59,88 @@ And include the css file
_Important_ In order for the toolbar to display correctly you must use a GridLayout or RootLayout as your root layout
+In your component's component file, initialize your editor's html:
+
+```
+editorContent: string = '
Leonardo ;
+```
+
+_Ensure that there your app is wrapped in a GridLayout. See demo for an example_
+Include the xmlns:
+
+```
+xmlns:RIE="@finalsite/rich-text-editor"
+```
+
+Then, include the text editor & editor's html in your component's html file:
+
+```
+
+```
+
+#### Add Custom Toolbar Buttons
+
+```
+
+
+
+
+```
+
+#### Use a custom editor
+
+```
+
+```
+
See demo for usage
## Usage (Angular)
-// TODO
+### Setup
+
+Run `npm install @nota/nativescript-webview-ext@8.0.2`.
+
+In your component's `app.module.ts`, import & setup `@nota/nativescript-webview-ext/angular`
+
+```
+import { NgModule, NO_ERRORS_SCHEMA } from '@angular/core';
+import { NativeScriptModule } from '@nativescript/angular';
+
+import {WebViewExtModule} from "@nota/nativescript-webview-ext/angular" <-- Add here
+...
+
+@NgModule({
+ imports: [...YourImports, WebViewExtModule] <-- Add here
+})
+export class AppModule {}
+```
+
+In your component's module file, import and include the NativeScriptRichTextEditorModule:
+
+```
+import { NativeScriptRichTextEditorModule } from '@finalsite/rich-text-editor/angular'
+
+...
+
+@NgModule({
+ imports: [NativeScriptRichTextEditorModule, ...otherModules],
+ declarations: [YourComponents],
+ schemas: [YourSchemas],
+})
+```
+
+_View the demo-angular folder to see an angular demo_
+
+## Usage (Vue)
+
+In your apps `app.js` (entry file), include the following two lines:
+
+ import RichTextEditor from "@finalsite/rich-text-editor/vue";
+ RichTextEditor.install(Vue);
+
+_View the demo-vue folder to see a vue demo_
+_To run it, `cd apps/demo-vue && ns run ios`_
## Dependencies/Credit
diff --git a/packages/rich-text-editor/angular/index.ts b/packages/rich-text-editor/angular/index.ts
new file mode 100644
index 0000000..5a6ad34
--- /dev/null
+++ b/packages/rich-text-editor/angular/index.ts
@@ -0,0 +1,9 @@
+import { NgModule } from '@angular/core';
+import { registerElement } from '@nativescript/angular';
+import { RichTextEditor } from '@finalsite/rich-text-editor';
+
+
+@NgModule()
+export class NativeScriptRichTextEditorModule {}
+
+registerElement('RichTextEditor', () => RichTextEditor);
diff --git a/packages/rich-text-editor/angular/package.json b/packages/rich-text-editor/angular/package.json
new file mode 100644
index 0000000..293e1ba
--- /dev/null
+++ b/packages/rich-text-editor/angular/package.json
@@ -0,0 +1,18 @@
+{
+ "name": "@finalsite/rich-text-editor/angular",
+ "ngPackage": {
+ "lib": {
+ "entryFile": "index.ts",
+ "umdModuleIds": {
+ "@nativescript/core": "ns-core",
+ "@nativescript/angular": "ns-angular",
+ "@finalsite/rich-text-editor": "ns-rich-text-editor",
+ "@nota/nativescript-webview-ext": "ns-nota-webview-ext"
+ }
+ },
+ "whitelistedNonPeerDependencies": [
+ "@nota/nativescript-webview-ext",
+ "@nota/nativescript-webview-ext/angular"
+ ]
+ }
+}
diff --git a/packages/rich-text-editor/angular/tsconfig.angular.json b/packages/rich-text-editor/angular/tsconfig.angular.json
new file mode 100644
index 0000000..f863ac9
--- /dev/null
+++ b/packages/rich-text-editor/angular/tsconfig.angular.json
@@ -0,0 +1,10 @@
+{
+ "extends": "../../../node_modules/ng-packagr/lib/ts/conf/tsconfig.ngc.json",
+ "compilerOptions": {
+ "types": ["node"],
+ "baseUrl": ".",
+ "paths": {
+ "@finalsite/rich-text-editor": ["../../../dist/packages/rich-text-editor"]
+ }
+ }
+}
diff --git a/packages/rich-text-editor/common.ts b/packages/rich-text-editor/common.ts
index 6058640..ae78c26 100644
--- a/packages/rich-text-editor/common.ts
+++ b/packages/rich-text-editor/common.ts
@@ -1,4 +1,4 @@
-import { knownFolders, Enums, Property, GridLayout, AddChildFromBuilder, StackLayout, Button, PercentLength, ScrollView, Page, GridUnitType, ItemSpec, action, prompt, inputType, LayoutBase, Screen, ContentView, Label, CSSType, path, ViewBase } from '@nativescript/core';
+import { knownFolders, Enums, Property, GridLayout, AddChildFromBuilder, StackLayout, Button, PercentLength, ScrollView, Page, GridUnitType, ItemSpec, action, prompt, inputType, LayoutBase, Screen, ContentView, Label, CSSType, path, ViewBase, ProxyViewContainer } from '@nativescript/core';
import { PromptResult } from '@nativescript/core/ui/dialogs/dialogs-common';
import { LoadFinishedEventData, ShouldOverrideUrlLoadEventData, WebViewEventData, WebViewExt } from '@nota/nativescript-webview-ext';
@@ -245,16 +245,28 @@ export abstract class RichTextEditorCommon extends WebViewExt implements AddChil
this._originalParent = this.parent as LayoutBase;
let finder: ViewBase = this.parent;
+
while (finder && !(finder instanceof Page)) {
finder = finder.parent;
}
let pg: Page = finder as Page;
- if (!(pg.content instanceof GridLayout)) {
+
+ if (pg.content instanceof ProxyViewContainer) {
+ const proxyContent: ProxyViewContainer = pg.content as ProxyViewContainer;
+ proxyContent.eachLayoutChild((childLayout) => {
+ if (childLayout instanceof GridLayout) {
+ this._rootLayout = childLayout as GridLayout;
+ }
+ });
+ } else {
+ this._rootLayout = pg.content as GridLayout;
+ }
+
+ if (!(this._rootLayout instanceof GridLayout)) {
console.log(`\n********Warning**********\n A root GridLayout is required in order for the RichTextEditor to work correctly\n\n`);
}
this._currentPage = pg;
- this._rootLayout = pg.content as GridLayout;
this._rootLayout.addChild(this._toolbar);
this._webViewSrc = encodeURI(`${knownFolders.currentApp().path}/assets/html/default.html`);
diff --git a/packages/rich-text-editor/package.json b/packages/rich-text-editor/package.json
index 4b10a82..58df259 100644
--- a/packages/rich-text-editor/package.json
+++ b/packages/rich-text-editor/package.json
@@ -15,7 +15,7 @@
"url": "https://github.com/NativeScript/plugins.git"
},
"dependencies": {
- "@nota/nativescript-webview-ext": "8.0.2"
+ "@nota/nativescript-webview-ext": "^8.0.2"
},
"keywords": [
"NativeScript",
diff --git a/packages/rich-text-editor/vue/index.ts b/packages/rich-text-editor/vue/index.ts
new file mode 100644
index 0000000..e9f32f5
--- /dev/null
+++ b/packages/rich-text-editor/vue/index.ts
@@ -0,0 +1,12 @@
+import { RichTextEditor as Editor } from "..";
+import "@nota/nativescript-webview-ext/vue"
+
+const RichTextEditor = {
+ install(Vue) {
+ Vue.registerElement(
+ 'RichTextEditor',
+ () => Editor,
+ );
+ }
+};
+export default RichTextEditor;
\ No newline at end of file