git0 0.2.10 → 0.2.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/TypeScript-React-Starter/LICENSE +21 -0
- package/TypeScript-React-Starter/README-CRA.md +1281 -0
- package/TypeScript-React-Starter/README.md +810 -0
- package/TypeScript-React-Starter/package.json +28 -0
- package/TypeScript-React-Starter/public/favicon.ico +0 -0
- package/TypeScript-React-Starter/public/index.html +31 -0
- package/TypeScript-React-Starter/src/App.css +24 -0
- package/TypeScript-React-Starter/src/App.test.tsx +8 -0
- package/TypeScript-React-Starter/src/App.tsx +23 -0
- package/TypeScript-React-Starter/src/actions/index.tsx +24 -0
- package/TypeScript-React-Starter/src/components/Hello.css +13 -0
- package/TypeScript-React-Starter/src/components/Hello.test.tsx +30 -0
- package/TypeScript-React-Starter/src/components/Hello.tsx +35 -0
- package/TypeScript-React-Starter/src/constants/index.tsx +6 -0
- package/TypeScript-React-Starter/src/containers/Hello.tsx +20 -0
- package/TypeScript-React-Starter/src/index.css +5 -0
- package/TypeScript-React-Starter/src/index.tsx +22 -0
- package/TypeScript-React-Starter/src/logo.svg +7 -0
- package/TypeScript-React-Starter/src/reducers/index.tsx +15 -0
- package/TypeScript-React-Starter/src/types/index.tsx +5 -0
- package/TypeScript-React-Starter/tsconfig.json +29 -0
- package/TypeScript-React-Starter/tslint.json +11 -0
- package/TypeScript-React-Starter/yarn.lock +4785 -0
- package/package.json +2 -2
- package/src/github-api.js +1 -0
- package/svelte-nodegui/.all-contributorsrc +60 -0
- package/svelte-nodegui/.vscode/launch.json +29 -0
- package/svelte-nodegui/CHANGELOG.md +153 -0
- package/svelte-nodegui/LICENSE +22 -0
- package/svelte-nodegui/README.md +151 -0
- package/svelte-nodegui/demo/.editorconfig +15 -0
- package/svelte-nodegui/demo/.vscode/extensions.json +3 -0
- package/svelte-nodegui/demo/livereload.js +29 -0
- package/svelte-nodegui/demo/package-lock.json +3514 -0
- package/svelte-nodegui/demo/package.json +35 -0
- package/svelte-nodegui/demo/src/App.svelte +29 -0
- package/svelte-nodegui/demo/src/app.ts +31 -0
- package/svelte-nodegui/demo/tsconfig.json +40 -0
- package/svelte-nodegui/demo/webpack.config.js +110 -0
- package/svelte-nodegui/extras/assets/kitchen.png +0 -0
- package/svelte-nodegui/extras/assets/nodegui.png +0 -0
- package/svelte-nodegui/extras/assets/nodegui_white.png +0 -0
- package/svelte-nodegui/extras/assets/start_icon.png +0 -0
- package/svelte-nodegui/extras/legal/logo/thanks.md +13 -0
- package/svelte-nodegui/extras/legal/yode/LICENSE +21 -0
- package/svelte-nodegui/extras/legal/yoga/LICENSE +0 -0
- package/svelte-nodegui/extras/logo/nodegui-circle.png +0 -0
- package/svelte-nodegui/extras/logo/nodegui.png +0 -0
- package/svelte-nodegui/extras/logo/nodegui.svg +4 -0
- package/svelte-nodegui/nativescript-svelte-todo.gif +0 -0
- package/svelte-nodegui/package-lock.json +1749 -0
- package/svelte-nodegui/package.json +44 -0
- package/svelte-nodegui/repl-workers/bundler/commonjs.js +58 -0
- package/svelte-nodegui/repl-workers/bundler/index.js +353 -0
- package/svelte-nodegui/repl-workers/package-lock.json +484 -0
- package/svelte-nodegui/repl-workers/package.json +21 -0
- package/svelte-nodegui/repl-workers/rollup.config.js +21 -0
- package/svelte-nodegui/rollup.config.js +81 -0
- package/svelte-nodegui/scripts/create-pkg.js +42 -0
- package/svelte-nodegui/src/components/AsComponent.svelte +16 -0
- package/svelte-nodegui/src/components/SlotComponent.svelte +4 -0
- package/svelte-nodegui/src/components/Template.svelte +10 -0
- package/svelte-nodegui/src/components/Template.svelte.d.ts +6 -0
- package/svelte-nodegui/src/components/index.ts +2 -0
- package/svelte-nodegui/src/dom/index.ts +132 -0
- package/svelte-nodegui/src/dom/nativescript-vue-next/LICENCE +21 -0
- package/svelte-nodegui/src/dom/nativescript-vue-next/index.ts +19 -0
- package/svelte-nodegui/src/dom/nativescript-vue-next/runtime/index.ts +21 -0
- package/svelte-nodegui/src/dom/nativescript-vue-next/runtime/nodes.ts +890 -0
- package/svelte-nodegui/src/dom/nativescript-vue-next/runtime/registry.ts +262 -0
- package/svelte-nodegui/src/dom/nativescript-vue-next/runtime/runtimeHelpers.ts +20 -0
- package/svelte-nodegui/src/dom/react-nodegui/LICENSE +21 -0
- package/svelte-nodegui/src/dom/react-nodegui/src/components/AbstractComponents/RNAbstractButton.ts +67 -0
- package/svelte-nodegui/src/dom/react-nodegui/src/components/Action/RNAction.ts +146 -0
- package/svelte-nodegui/src/dom/react-nodegui/src/components/Action/index.ts +37 -0
- package/svelte-nodegui/src/dom/react-nodegui/src/components/AnimatedImage/RNAnimatedImage.ts +76 -0
- package/svelte-nodegui/src/dom/react-nodegui/src/components/AnimatedImage/index.ts +45 -0
- package/svelte-nodegui/src/dom/react-nodegui/src/components/BoxView/RNBoxView.ts +99 -0
- package/svelte-nodegui/src/dom/react-nodegui/src/components/BoxView/index.ts +49 -0
- package/svelte-nodegui/src/dom/react-nodegui/src/components/Button/RNButton.ts +71 -0
- package/svelte-nodegui/src/dom/react-nodegui/src/components/Button/index.ts +49 -0
- package/svelte-nodegui/src/dom/react-nodegui/src/components/CheckBox/RNCheckBox.ts +71 -0
- package/svelte-nodegui/src/dom/react-nodegui/src/components/CheckBox/index.ts +50 -0
- package/svelte-nodegui/src/dom/react-nodegui/src/components/ComboBox/RNComboBox.ts +118 -0
- package/svelte-nodegui/src/dom/react-nodegui/src/components/ComboBox/index.ts +50 -0
- package/svelte-nodegui/src/dom/react-nodegui/src/components/Dial/RNDial.ts +69 -0
- package/svelte-nodegui/src/dom/react-nodegui/src/components/Dial/index.ts +41 -0
- package/svelte-nodegui/src/dom/react-nodegui/src/components/GridView/GridColumn/RNGridColumn.ts +95 -0
- package/svelte-nodegui/src/dom/react-nodegui/src/components/GridView/GridColumn/index.ts +49 -0
- package/svelte-nodegui/src/dom/react-nodegui/src/components/GridView/GridRow/RNGridRow.ts +141 -0
- package/svelte-nodegui/src/dom/react-nodegui/src/components/GridView/GridRow/index.ts +47 -0
- package/svelte-nodegui/src/dom/react-nodegui/src/components/GridView/RNGridView.ts +185 -0
- package/svelte-nodegui/src/dom/react-nodegui/src/components/GridView/index.ts +51 -0
- package/svelte-nodegui/src/dom/react-nodegui/src/components/GridView/utils.ts +59 -0
- package/svelte-nodegui/src/dom/react-nodegui/src/components/Image/RNImage.ts +135 -0
- package/svelte-nodegui/src/dom/react-nodegui/src/components/Image/index.ts +46 -0
- package/svelte-nodegui/src/dom/react-nodegui/src/components/LineEdit/RNLineEdit.ts +82 -0
- package/svelte-nodegui/src/dom/react-nodegui/src/components/LineEdit/index.ts +41 -0
- package/svelte-nodegui/src/dom/react-nodegui/src/components/Menu/RNMenu.ts +49 -0
- package/svelte-nodegui/src/dom/react-nodegui/src/components/Menu/index.ts +44 -0
- package/svelte-nodegui/src/dom/react-nodegui/src/components/MenuBar/RNMenuBar.ts +51 -0
- package/svelte-nodegui/src/dom/react-nodegui/src/components/MenuBar/index.ts +42 -0
- package/svelte-nodegui/src/dom/react-nodegui/src/components/PlainTextEdit/RNPlainTextEdit.ts +82 -0
- package/svelte-nodegui/src/dom/react-nodegui/src/components/PlainTextEdit/index.ts +44 -0
- package/svelte-nodegui/src/dom/react-nodegui/src/components/ProgressBar/RNProgressBar.ts +78 -0
- package/svelte-nodegui/src/dom/react-nodegui/src/components/ProgressBar/index.ts +43 -0
- package/svelte-nodegui/src/dom/react-nodegui/src/components/RadioButton/RNRadioButton.ts +50 -0
- package/svelte-nodegui/src/dom/react-nodegui/src/components/RadioButton/index.ts +43 -0
- package/svelte-nodegui/src/dom/react-nodegui/src/components/ScrollArea/RNScrollArea.ts +51 -0
- package/svelte-nodegui/src/dom/react-nodegui/src/components/ScrollArea/index.ts +44 -0
- package/svelte-nodegui/src/dom/react-nodegui/src/components/Slider/RNSlider.ts +97 -0
- package/svelte-nodegui/src/dom/react-nodegui/src/components/Slider/index.ts +46 -0
- package/svelte-nodegui/src/dom/react-nodegui/src/components/SpinBox/RNSpinBox.ts +88 -0
- package/svelte-nodegui/src/dom/react-nodegui/src/components/SpinBox/index.ts +49 -0
- package/svelte-nodegui/src/dom/react-nodegui/src/components/Svg/RNSvg.ts +67 -0
- package/svelte-nodegui/src/dom/react-nodegui/src/components/Svg/index.ts +43 -0
- package/svelte-nodegui/src/dom/react-nodegui/src/components/SystemTrayIcon/RNSystemTrayIcon.ts +141 -0
- package/svelte-nodegui/src/dom/react-nodegui/src/components/SystemTrayIcon/index.ts +43 -0
- package/svelte-nodegui/src/dom/react-nodegui/src/components/Tab/RNTab.ts +69 -0
- package/svelte-nodegui/src/dom/react-nodegui/src/components/Tab/index.ts +48 -0
- package/svelte-nodegui/src/dom/react-nodegui/src/components/TabItem/RNTabItem.ts +72 -0
- package/svelte-nodegui/src/dom/react-nodegui/src/components/TabItem/index.ts +40 -0
- package/svelte-nodegui/src/dom/react-nodegui/src/components/Text/RNText.ts +65 -0
- package/svelte-nodegui/src/dom/react-nodegui/src/components/Text/index.ts +49 -0
- package/svelte-nodegui/src/dom/react-nodegui/src/components/View/RNView.ts +306 -0
- package/svelte-nodegui/src/dom/react-nodegui/src/components/View/index.ts +44 -0
- package/svelte-nodegui/src/dom/react-nodegui/src/components/Window/RNWindow.ts +66 -0
- package/svelte-nodegui/src/dom/react-nodegui/src/components/Window/index.ts +50 -0
- package/svelte-nodegui/src/dom/react-nodegui/src/components/config.ts +95 -0
- package/svelte-nodegui/src/dom/react-nodegui/src/index.ts +52 -0
- package/svelte-nodegui/src/dom/react-nodegui/src/reconciler/index.ts +226 -0
- package/svelte-nodegui/src/dom/react-nodegui/src/utils/decoupleFromReact.ts +2 -0
- package/svelte-nodegui/src/dom/react-nodegui/src/utils/helpers.ts +14 -0
- package/svelte-nodegui/src/dom/shared/Logger.ts +16 -0
- package/svelte-nodegui/src/dom/shared/index.ts +1 -0
- package/svelte-nodegui/src/dom/svelte/HeadElement.ts +41 -0
- package/svelte-nodegui/src/dom/svelte/RNObject.ts +95 -0
- package/svelte-nodegui/src/dom/svelte/StyleElement.ts +92 -0
- package/svelte-nodegui/src/dom/svelte/SvelteNodeGUIDocument.ts +124 -0
- package/svelte-nodegui/src/dom/svelte/TemplateElement.ts +16 -0
- package/svelte-nodegui/src/dom/svelte-elements.ts +111 -0
- package/svelte-nodegui/src/index.ts +62 -0
- package/svelte-nodegui/src/svelte-nodegui.ts +159 -0
- package/svelte-nodegui/src/transitions/bezier.ts +112 -0
- package/svelte-nodegui/src/transitions/index.ts +227 -0
- package/svelte-nodegui/tsconfig.json +19 -0
- package/svelte-nodegui/website/README.md +33 -0
- package/svelte-nodegui/website/blog/2019-05-30-welcome.md +12 -0
- package/svelte-nodegui/website/docs/api/classes/renderer.md +49 -0
- package/svelte-nodegui/website/docs/api/classes/rnaction.md +608 -0
- package/svelte-nodegui/website/docs/api/classes/rngridcolumn.md +232 -0
- package/svelte-nodegui/website/docs/api/classes/rngridrow.md +247 -0
- package/svelte-nodegui/website/docs/api/classes/rnmenu.md +1337 -0
- package/svelte-nodegui/website/docs/api/classes/rnmenubar.md +1341 -0
- package/svelte-nodegui/website/docs/api/globals.md +832 -0
- package/svelte-nodegui/website/docs/api/index.md +0 -0
- package/svelte-nodegui/website/docs/api/interfaces/_react_proxy_.reactproxycomponent.md +38 -0
- package/svelte-nodegui/website/docs/api/interfaces/abstractbuttonprops.md +306 -0
- package/svelte-nodegui/website/docs/api/interfaces/actionprops.md +115 -0
- package/svelte-nodegui/website/docs/api/interfaces/animatedimageprops.md +297 -0
- package/svelte-nodegui/website/docs/api/interfaces/boxviewprops.md +245 -0
- package/svelte-nodegui/website/docs/api/interfaces/buttonprops.md +313 -0
- package/svelte-nodegui/website/docs/api/interfaces/checkboxprops.md +313 -0
- package/svelte-nodegui/website/docs/api/interfaces/comboboxprops.md +343 -0
- package/svelte-nodegui/website/docs/api/interfaces/datawithoffset.md +32 -0
- package/svelte-nodegui/website/docs/api/interfaces/dialprops.md +259 -0
- package/svelte-nodegui/website/docs/api/interfaces/gridviewprops.md +273 -0
- package/svelte-nodegui/website/docs/api/interfaces/imageprops.md +311 -0
- package/svelte-nodegui/website/docs/api/interfaces/lineeditprops.md +266 -0
- package/svelte-nodegui/website/docs/api/interfaces/menubarprops.md +245 -0
- package/svelte-nodegui/website/docs/api/interfaces/menuprops.md +245 -0
- package/svelte-nodegui/website/docs/api/interfaces/plaintexteditprops.md +259 -0
- package/svelte-nodegui/website/docs/api/interfaces/progressbarprops.md +266 -0
- package/svelte-nodegui/website/docs/api/interfaces/radiobuttonprops.md +282 -0
- package/svelte-nodegui/website/docs/api/interfaces/scrollareaprops.md +245 -0
- package/svelte-nodegui/website/docs/api/interfaces/sliderprops.md +329 -0
- package/svelte-nodegui/website/docs/api/interfaces/spinboxprops.md +273 -0
- package/svelte-nodegui/website/docs/api/interfaces/systemtrayiconprops.md +97 -0
- package/svelte-nodegui/website/docs/api/interfaces/tabitemprops.md +28 -0
- package/svelte-nodegui/website/docs/api/interfaces/tabprops.md +245 -0
- package/svelte-nodegui/website/docs/api/interfaces/textprops.md +277 -0
- package/svelte-nodegui/website/docs/api/interfaces/viewprops.md +261 -0
- package/svelte-nodegui/website/docs/api/interfaces/windowprops.md +245 -0
- package/svelte-nodegui/website/docs/api/modules/_react_proxy_.md +29 -0
- package/svelte-nodegui/website/docs/doc1.md +162 -0
- package/svelte-nodegui/website/docs/guides/custom-nodegui-native-plugin.md +6 -0
- package/svelte-nodegui/website/docs/guides/debugging-in-vscode.md +39 -0
- package/svelte-nodegui/website/docs/guides/debugging.md +59 -0
- package/svelte-nodegui/website/docs/guides/getting-started.md +141 -0
- package/svelte-nodegui/website/docs/guides/handle-events.md +188 -0
- package/svelte-nodegui/website/docs/guides/images.md +62 -0
- package/svelte-nodegui/website/docs/guides/layout.md +281 -0
- package/svelte-nodegui/website/docs/guides/networking.md +31 -0
- package/svelte-nodegui/website/docs/guides/packaging.md +32 -0
- package/svelte-nodegui/website/docs/guides/scroll-view.md +69 -0
- package/svelte-nodegui/website/docs/guides/styling.md +208 -0
- package/svelte-nodegui/website/docs/guides/tutorial.md +82 -0
- package/svelte-nodegui/website/docs/guides/using-native-node-modules.md +55 -0
- package/svelte-nodegui/website/docs/mdx.md +22 -0
- package/svelte-nodegui/website/docs/scripts/fixdocs.js +21 -0
- package/svelte-nodegui/website/docusaurus.config.js +131 -0
- package/svelte-nodegui/website/package.json +33 -0
- package/svelte-nodegui/website/sidebars.js +77 -0
- package/svelte-nodegui/website/src/components/CodeExample.js +42 -0
- package/svelte-nodegui/website/src/components/CreateNativeApps.js +46 -0
- package/svelte-nodegui/website/src/components/Features.js +62 -0
- package/svelte-nodegui/website/src/components/Hero.js +85 -0
- package/svelte-nodegui/website/src/components/SplitView.js +18 -0
- package/svelte-nodegui/website/src/components/Talks.js +68 -0
- package/svelte-nodegui/website/src/components/Try.js +83 -0
- package/svelte-nodegui/website/src/components/common.js +41 -0
- package/svelte-nodegui/website/src/components/styles.css +61 -0
- package/svelte-nodegui/website/src/css/custom.css +34 -0
- package/svelte-nodegui/website/src/pages/index.js +32 -0
- package/svelte-nodegui/website/src/pages/styles.module.css +35 -0
- package/svelte-nodegui/website/static/CNAME +1 -0
- package/svelte-nodegui/website/static/img/box-layout-1.png +0 -0
- package/svelte-nodegui/website/static/img/box-layout-2.png +0 -0
- package/svelte-nodegui/website/static/img/code-sample.png +0 -0
- package/svelte-nodegui/website/static/img/demo.png +0 -0
- package/svelte-nodegui/website/static/img/favicon.ico +0 -0
- package/svelte-nodegui/website/static/img/flex-layout-1.png +0 -0
- package/svelte-nodegui/website/static/img/grid-layout-1.png +0 -0
- package/svelte-nodegui/website/static/img/logo-circle.png +0 -0
- package/svelte-nodegui/website/static/img/logo.png +0 -0
- package/svelte-nodegui/website/static/img/logo.svg +5 -0
- package/svelte-nodegui/website/static/img/logox200.png +0 -0
- package/svelte-nodegui/website/static/img/undraw_building_websites.svg +1 -0
- package/svelte-nodegui/website/static/img/undraw_code_review.svg +1 -0
- package/svelte-nodegui/website/static/img/undraw_docusaurus_mountain.svg +170 -0
- package/svelte-nodegui/website/static/img/undraw_docusaurus_react.svg +169 -0
- package/svelte-nodegui/website/static/img/undraw_docusaurus_tree.svg +1 -0
- package/svelte-nodegui/website/static/img/undraw_react.svg +1 -0
- package/svelte-nodegui/website/static/img/undraw_website_setup.svg +1 -0
- package/svelte-nodegui/website/static/img/undraw_windows.svg +11 -0
- package/svelte-nodegui/website/website/sidebars.js +32 -0
- package/svelte-nodegui/website/yarn.lock +10533 -0
- package/bun.lock +0 -159
- package/docs-config/bun.lock +0 -6139
|
@@ -0,0 +1,890 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getViewClass,
|
|
3
|
+
getViewMeta,
|
|
4
|
+
normalizeElementName,
|
|
5
|
+
NSVViewMeta,
|
|
6
|
+
} from './registry'
|
|
7
|
+
import { ELEMENT_REF } from './runtimeHelpers';
|
|
8
|
+
// import { debug } from '../shared';
|
|
9
|
+
import { Component, NodeObject, NodeWidget, QObjectSignals, QWidgetSignals } from '@nodegui/nodegui'
|
|
10
|
+
import type { RNComponent } from "../../react-nodegui/src/components/config";
|
|
11
|
+
import { warn, error, log } from '../../shared/Logger';
|
|
12
|
+
import { EventWidget } from '@nodegui/nodegui/dist/lib/core/EventWidget';
|
|
13
|
+
import { QVariantType } from '@nodegui/nodegui/dist/lib/QtCore/QVariant';
|
|
14
|
+
import { RNWindow } from '../../react-nodegui/src/components/Window/RNWindow';
|
|
15
|
+
import SvelteNodeGUIDocument from '../../svelte/SvelteNodeGUIDocument';
|
|
16
|
+
// import { default as set } from "set-value";
|
|
17
|
+
|
|
18
|
+
// import unset from 'unset-value'
|
|
19
|
+
|
|
20
|
+
// import {isContentView, isLayout} from "./index";
|
|
21
|
+
|
|
22
|
+
declare var __DEV__: boolean
|
|
23
|
+
declare var __TEST__: boolean
|
|
24
|
+
|
|
25
|
+
export const enum NSVNodeTypes {
|
|
26
|
+
TEXT = 'text',
|
|
27
|
+
ELEMENT = 'element',
|
|
28
|
+
COMMENT = 'comment',
|
|
29
|
+
ROOT = 'root',
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// View Flags indicate the kind of view the element is
|
|
33
|
+
// this avoids extra checks during runtime to determine
|
|
34
|
+
// the method to use for adding/removing child nodes
|
|
35
|
+
//
|
|
36
|
+
export const enum NSVViewFlags {
|
|
37
|
+
NONE = 0,
|
|
38
|
+
SKIP_ADD_TO_DOM = 1 << 0,
|
|
39
|
+
/* NativeScript-specific. TODO: determine NodeGUI-specific ones. */
|
|
40
|
+
// CONTENT_VIEW = 1 << 1,
|
|
41
|
+
// LAYOUT_VIEW = 1 << 2,
|
|
42
|
+
NO_CHILDREN = 1 << 3,
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
type EventListener = (args: unknown) => void;
|
|
46
|
+
|
|
47
|
+
export function componentIsEventWidget<Signals extends {} = {}>(component: Component): component is EventWidget<Signals> {
|
|
48
|
+
if(!component){
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
if(typeof (component as EventWidget<Signals>).addEventListener === "function"){
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function componentIsStyleable<Signals extends QWidgetSignals = QWidgetSignals>(component: Component): component is NodeWidget<Signals> {
|
|
58
|
+
if(!component){
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
if(typeof (component as NodeWidget<Signals>)._rawInlineStyle === "string"){
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export function componentHasPropertyAccessor<Signals extends QObjectSignals = QObjectSignals>(component: Component): component is NodeObject<Signals> {
|
|
68
|
+
if(!component){
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
if(typeof (component as NodeObject<Signals>).property === "function"){
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export function componentSupportsId<Signals extends QWidgetSignals = QWidgetSignals>(component: Component): component is NodeWidget<Signals> {
|
|
78
|
+
if(typeof (component as NodeWidget<Signals>).setObjectName === "function"){
|
|
79
|
+
return true;
|
|
80
|
+
}
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export function* elementIterator(el: NSVNode): Iterable<NSVNode> {
|
|
85
|
+
yield el;
|
|
86
|
+
for (let child of el.childNodes) {
|
|
87
|
+
yield* elementIterator(child)
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export type NativeView<T extends Component = Component> = T & RNComponent;
|
|
92
|
+
|
|
93
|
+
interface IStyleProxy {
|
|
94
|
+
setProperty(propertyName: string, value: string, priority?: string): void;
|
|
95
|
+
removeProperty(property: string): void;
|
|
96
|
+
// animation: string;
|
|
97
|
+
cssText: string;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
let nodeId: number = 0
|
|
101
|
+
|
|
102
|
+
export abstract class NSVNode {
|
|
103
|
+
protected constructor(nodeType: NSVNodeTypes) {
|
|
104
|
+
this.nodeType = nodeType
|
|
105
|
+
this.nodeId = nodeId++
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
nodeRole?: string
|
|
109
|
+
nodeId: number
|
|
110
|
+
nodeType: NSVNodeTypes
|
|
111
|
+
get textContent(): string|null {
|
|
112
|
+
if(this.nodeType === NSVNodeTypes.TEXT){
|
|
113
|
+
return (this as NSVNode as NSVText).data;
|
|
114
|
+
}
|
|
115
|
+
if(this.nodeType === NSVNodeTypes.ELEMENT){
|
|
116
|
+
return this.childNodes.map(childNode => childNode.textContent).join("");
|
|
117
|
+
}
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
set textContent(value: string){
|
|
121
|
+
if(this.nodeType === NSVNodeTypes.TEXT){
|
|
122
|
+
(this as NSVNode as NSVText).data = (value ?? "");
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
if(this.nodeType === NSVNodeTypes.ELEMENT){
|
|
126
|
+
this.childNodes.forEach(c => (this as NSVNode as NSVElement).removeChild(c as NSVNode));
|
|
127
|
+
(this as NSVNode as NSVElement).appendChild(new NSVText(value));
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
parentNode: NSVNode | null = null
|
|
133
|
+
parentElement: NSVElement | null = null
|
|
134
|
+
childNodes: NSVNode[] = []
|
|
135
|
+
|
|
136
|
+
nextSibling: NSVNode | null = null
|
|
137
|
+
previousSibling: NSVNode | null = null
|
|
138
|
+
|
|
139
|
+
get firstChild() {
|
|
140
|
+
return this.childNodes.length ? this.childNodes[0] : null
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
get lastChild() {
|
|
144
|
+
return this.childNodes.length
|
|
145
|
+
? this.childNodes[this.childNodes.length - 1]
|
|
146
|
+
: null
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
appendChild(child: NSVNode): NSVNode {
|
|
150
|
+
if(child === this || ![NSVNodeTypes.ELEMENT, NSVNodeTypes.ROOT].includes(this.nodeType)){
|
|
151
|
+
throw new Error("HierarchyRequestError: The operation would yield an incorrect node tree.");
|
|
152
|
+
}
|
|
153
|
+
if(child instanceof NSVNode === false){
|
|
154
|
+
throw new Error("TypeError: Argument 1 ('child') to Node.appendChild must be an instance of NSVNode");
|
|
155
|
+
}
|
|
156
|
+
if(child.parentNode === this){
|
|
157
|
+
return child;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
child.previousSibling = this.childNodes[this.childNodes.length - 1] ?? null;
|
|
161
|
+
child.nextSibling = null;
|
|
162
|
+
|
|
163
|
+
// If the child is already a child of this, remove it from our childNodes array before adding it to the end.
|
|
164
|
+
if(child.parentNode === this){
|
|
165
|
+
const childIndex = this.childNodes.findIndex(c => c === child);
|
|
166
|
+
if(childIndex === -1){
|
|
167
|
+
throw new Error("NotFoundError: the object can not be found here.");
|
|
168
|
+
}
|
|
169
|
+
this.childNodes.splice(childIndex, 0);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
this.childNodes.push(child);
|
|
173
|
+
child.parentNode = this as NSVNode;
|
|
174
|
+
if(this.nodeType === NSVNodeTypes.ELEMENT){
|
|
175
|
+
child.parentElement = this as NSVNode as NSVElement;
|
|
176
|
+
|
|
177
|
+
if(child.nodeType === NSVNodeTypes.TEXT){
|
|
178
|
+
(this as NSVNode as NSVElement).updateNativeText();
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
return child;
|
|
182
|
+
}
|
|
183
|
+
insertBefore(newNode: NSVNode, referenceNode: NSVNode): NSVNode {
|
|
184
|
+
if(newNode === this || ![NSVNodeTypes.ELEMENT, NSVNodeTypes.ROOT].includes(this.nodeType)){
|
|
185
|
+
throw new Error("HierarchyRequestError: The operation would yield an incorrect node tree.");
|
|
186
|
+
}
|
|
187
|
+
if(newNode instanceof NSVNode === false){
|
|
188
|
+
throw new Error("TypeError: Argument 1 ('newNode') to Node.insertBefore must be an instance of NSVNode");
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// console.log(`[Node.insertBefore] ${newNode}, ${referenceNode}`);
|
|
192
|
+
const referenceIndex = referenceNode == null ?
|
|
193
|
+
-1 :
|
|
194
|
+
this.childNodes.findIndex(node => node === referenceNode);
|
|
195
|
+
if(referenceIndex === -1){
|
|
196
|
+
this.appendChild(newNode);
|
|
197
|
+
} else {
|
|
198
|
+
newNode.previousSibling = this.childNodes[referenceIndex - 1] ?? null;
|
|
199
|
+
newNode.nextSibling = this.childNodes[referenceIndex];
|
|
200
|
+
|
|
201
|
+
// If the child is already a child of this, remove it from our childNodes array before adding it to the end.
|
|
202
|
+
if(newNode.parentNode === this){
|
|
203
|
+
const newNodeIndex = this.childNodes.findIndex(c => c === newNode);
|
|
204
|
+
if(newNodeIndex === -1){
|
|
205
|
+
throw new Error("NotFoundError: the object can not be found here.");
|
|
206
|
+
}
|
|
207
|
+
this.childNodes.splice(newNodeIndex, 0);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
this.childNodes.splice(referenceIndex, 0, newNode);
|
|
211
|
+
newNode.parentNode = this as NSVNode;
|
|
212
|
+
if(this.nodeType === NSVNodeTypes.ELEMENT){
|
|
213
|
+
newNode.parentElement = this as NSVNode as NSVElement;
|
|
214
|
+
|
|
215
|
+
if(newNode.nodeType === NSVNodeTypes.TEXT){
|
|
216
|
+
(this as NSVNode as NSVElement).updateNativeText();
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
return newNode;
|
|
222
|
+
}
|
|
223
|
+
removeChild(child: NSVNode): NSVNode {
|
|
224
|
+
if(child === this){
|
|
225
|
+
throw new Error("HierarchyRequestError: The operation would yield an incorrect node tree.");
|
|
226
|
+
}
|
|
227
|
+
if(child instanceof NSVNode === false){
|
|
228
|
+
throw new Error("TypeError: Argument 1 ('child') to Node.removeChild must be an instance of NSVNode");
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
const childIndex = this.childNodes.findIndex(c => c === child);
|
|
232
|
+
if(childIndex === -1){
|
|
233
|
+
throw new Error("NotFoundError: the object can not be found here.");
|
|
234
|
+
}
|
|
235
|
+
if(childIndex !== -1){
|
|
236
|
+
child.previousSibling = null;
|
|
237
|
+
child.nextSibling = null;
|
|
238
|
+
this.childNodes.splice(childIndex, 1);
|
|
239
|
+
child.parentNode = null;
|
|
240
|
+
if(this.nodeType === NSVNodeTypes.ELEMENT){
|
|
241
|
+
child.parentElement = null;
|
|
242
|
+
|
|
243
|
+
if(child.nodeType === NSVNodeTypes.TEXT){
|
|
244
|
+
(this as NSVNode as NSVElement).updateNativeText();
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
return child;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
export class NSVElement<T extends NativeView = NativeView> extends NSVNode {
|
|
254
|
+
private readonly _tagName: string
|
|
255
|
+
private readonly _nativeView: T;
|
|
256
|
+
private _meta: NSVViewMeta<T> | undefined
|
|
257
|
+
private readonly recycledNewProps: Record<string, any> = {};
|
|
258
|
+
private readonly recycledOldProps: Record<string, any> = {};
|
|
259
|
+
private readonly propsSetter: Record<string, (value: any) => void> = {};
|
|
260
|
+
public ownerDocument: SvelteNodeGUIDocument|null = null;
|
|
261
|
+
|
|
262
|
+
constructor(tagName: string){
|
|
263
|
+
super(NSVNodeTypes.ELEMENT);
|
|
264
|
+
|
|
265
|
+
this._tagName = normalizeElementName(tagName);
|
|
266
|
+
|
|
267
|
+
const viewClass = getViewClass(tagName);
|
|
268
|
+
if(viewClass){
|
|
269
|
+
// this._nativeView = new viewClass();
|
|
270
|
+
this._nativeView = viewClass; // We're now calling new in the resolver itself
|
|
271
|
+
|
|
272
|
+
// console.log(`!! [${tagName}] nativeView was instantiated!`, this._nativeView);
|
|
273
|
+
(this._nativeView as any)[ELEMENT_REF] = this;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
get tagName(): string {
|
|
278
|
+
return this._tagName
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
get nativeView() {
|
|
282
|
+
return this._nativeView
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
private readonly stylesMap = new Map<string, string|number>();
|
|
286
|
+
|
|
287
|
+
get id(): string {
|
|
288
|
+
if(componentSupportsId(this.nativeView)){
|
|
289
|
+
return this.nativeView.objectName();
|
|
290
|
+
} else {
|
|
291
|
+
console.warn(`<${this._tagName}> is a virtual element (i.e. has no corresponding Qt Widget) and so the attribute "id" cannot be accessed.`);
|
|
292
|
+
return "";
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
set id(value: string){
|
|
297
|
+
if(componentSupportsId(this.nativeView)){
|
|
298
|
+
this.nativeView.setObjectName(value);
|
|
299
|
+
} else {
|
|
300
|
+
console.warn(`<${this._tagName}> is a virtual element (i.e. has no corresponding Qt Widget) and so the attribute "id" cannot be set on it.`);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/* istanbul ignore next */
|
|
305
|
+
setStyle(property: string, value: string | number | null, priority: "important"|""): void {
|
|
306
|
+
// console.log(`[NSVElement] this.setStyle("${property}", "${value}")`);
|
|
307
|
+
// log.debug(() => `setStyle ${this} ${property} ${value}`)
|
|
308
|
+
|
|
309
|
+
if(!(value = value.toString().trim()).length){
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
if(!componentIsStyleable(this.nativeView)){
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
const currentValue = this.stylesMap.get(property);
|
|
318
|
+
if(currentValue === value || typeof value === "undefined"){
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
if(value === null){
|
|
323
|
+
this.stylesMap.delete(property);
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
this.stylesMap.set(property, `${value}${priority ? " !important" : ""}`);
|
|
327
|
+
|
|
328
|
+
/* NodeGUI doesn't seem to give property-by-property access into the styles, so for now, we'll just inefficiently rewrite the whole inline style upon any update. */
|
|
329
|
+
let updatedRawInlineStyle: string = "";
|
|
330
|
+
let i = 0;
|
|
331
|
+
for (const [property, value] of this.stylesMap) {
|
|
332
|
+
updatedRawInlineStyle += `${i > 0 ? "\n" : ""}${property}:${value};`;
|
|
333
|
+
i++;
|
|
334
|
+
}
|
|
335
|
+
// console.log(`[NSVElement.setStyle] this.nativeView.setInlineStyle("${updatedRawInlineStyle}");`);
|
|
336
|
+
this.nativeView.setInlineStyle(updatedRawInlineStyle);
|
|
337
|
+
|
|
338
|
+
// const rawInlineStyle: string = this.nativeView._rawInlineStyle;
|
|
339
|
+
// const styleDeclarations: string[] = rawInlineStyle.trim().split(";").map(styleDeclaration => styleDeclaration.trim());
|
|
340
|
+
// const styleMaps: [property: string, value: string][] = styleDeclarations.map((styleDeclaration) => styleDeclaration.split(":", 2) as [string, string]);
|
|
341
|
+
// const stylesMap: Map<string, string> = new Map();
|
|
342
|
+
// styleMaps.forEach(([property, value]) => {
|
|
343
|
+
// stylesMap.set(property, value);
|
|
344
|
+
// });
|
|
345
|
+
// stylesMap.set(property, value);
|
|
346
|
+
// const updatedRawInlineStyle: string = styleMaps.reduce((acc: string, [property, value]) => `${acc}\n${property}:${value};`, "").slice("\n".length);
|
|
347
|
+
// this.nativeView.setInlineStyle(updatedRawInlineStyle);
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
/**
|
|
351
|
+
* Accessed by Svelte's set_style() function.
|
|
352
|
+
* Expected to return an object that provides setters for each style.
|
|
353
|
+
* @example node.style.setProperty(key, value, important ? 'important' : '');
|
|
354
|
+
*/
|
|
355
|
+
public readonly style = {
|
|
356
|
+
setProperty: (propertyName: string, value: string, priority: "important"|"") => {
|
|
357
|
+
// console.log(`[NSVElement] style.setProperty("${propertyName}", "${value}${priority ? " important" : ""}")`);
|
|
358
|
+
this.setStyle(propertyName, value, priority);
|
|
359
|
+
},
|
|
360
|
+
|
|
361
|
+
removeProperty: (propertyName: string) => {
|
|
362
|
+
// console.log(`[NSVElement] style.removeProperty("${propertyName}")`);
|
|
363
|
+
this.setStyle(propertyName, null, "");
|
|
364
|
+
},
|
|
365
|
+
|
|
366
|
+
get animation(): string {
|
|
367
|
+
console.warn(`[NSVElement] Animation support not yet implemented.`);
|
|
368
|
+
// return [...animations.keys()].join(", ")
|
|
369
|
+
return "";
|
|
370
|
+
},
|
|
371
|
+
|
|
372
|
+
set animation(value: string) {
|
|
373
|
+
console.warn(`[NSVElement] Animation support not yet implemented.`);
|
|
374
|
+
// log.debug(() => `setting animation ${value}`)
|
|
375
|
+
// let new_animations = value.trim() == "" ? [] : value.split(',').map(a => a.trim());
|
|
376
|
+
// //add new ones
|
|
377
|
+
// for (let anim of new_animations) {
|
|
378
|
+
// if (!animations.has(anim)) {
|
|
379
|
+
// addAnimation(anim);
|
|
380
|
+
// }
|
|
381
|
+
// }
|
|
382
|
+
// //remove old ones
|
|
383
|
+
// for (let anim of animations.keys()) {
|
|
384
|
+
// if (new_animations.indexOf(anim) < 0) {
|
|
385
|
+
// removeAnimation(anim);
|
|
386
|
+
// }
|
|
387
|
+
// }
|
|
388
|
+
},
|
|
389
|
+
|
|
390
|
+
get cssText(): string {
|
|
391
|
+
console.warn(`[NSVElement.getCssText] (not yet implemented)`);
|
|
392
|
+
return "";
|
|
393
|
+
// log.debug(() => "got css text");
|
|
394
|
+
// return getStyleAttribute();
|
|
395
|
+
},
|
|
396
|
+
|
|
397
|
+
set cssText(value: string) {
|
|
398
|
+
console.warn(`[NSVElement.setCssText] (not yet implemented)`);
|
|
399
|
+
// log.debug(() => "set css text");
|
|
400
|
+
// setStyleAttribute(value);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
updateNativeText(): void {
|
|
405
|
+
if(componentHasPropertyAccessor(this.nativeView)){
|
|
406
|
+
this.nativeView.setProperty("text", this.textContent);
|
|
407
|
+
return;
|
|
408
|
+
}
|
|
409
|
+
error(`updateNativeText() called on element that does not implement it.`, this);
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
get meta(): NSVViewMeta<T> {
|
|
413
|
+
if (this._meta) {
|
|
414
|
+
return this._meta
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
return (this._meta = getViewMeta(this.tagName))
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
/**
|
|
421
|
+
* We keep references to the event listeners so that the Svelte NodeGUI HostConfig can remove any attached event listener if it needs to replace it.
|
|
422
|
+
*/
|
|
423
|
+
private _eventListeners?: Map<string, any>;
|
|
424
|
+
|
|
425
|
+
get eventListeners() {
|
|
426
|
+
if(!this._eventListeners){
|
|
427
|
+
this._eventListeners = new Map();
|
|
428
|
+
}
|
|
429
|
+
return this._eventListeners!;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
addEventListener<Signals extends {}, SignalType extends keyof Signals>(
|
|
433
|
+
event: SignalType,
|
|
434
|
+
handler: Signals[SignalType],
|
|
435
|
+
options: AddEventListenerOptions = {}
|
|
436
|
+
) {
|
|
437
|
+
if(!componentIsEventWidget<Signals>(this.nativeView)){
|
|
438
|
+
return;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
// log(`add event listener ${this} ${event}`);
|
|
442
|
+
|
|
443
|
+
const { capture, once } = options
|
|
444
|
+
if (capture) {
|
|
445
|
+
warn('Bubble propagation is not supported')
|
|
446
|
+
return
|
|
447
|
+
}
|
|
448
|
+
if (once) {
|
|
449
|
+
const oldHandler = handler
|
|
450
|
+
const self = this
|
|
451
|
+
handler = ((...args: any) => {
|
|
452
|
+
const res = (oldHandler as unknown as EventListener).call(null, ...args)
|
|
453
|
+
if (res !== null) {
|
|
454
|
+
self.removeEventListener(event, handler)
|
|
455
|
+
}
|
|
456
|
+
}) as unknown as Signals[SignalType]
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
//svelte compatibility wrapper
|
|
460
|
+
(handler as any).__wrapper = (handler as any).__wrapper || ((args: unknown) => {
|
|
461
|
+
/* I don't see any evidence that Qt events include the event name, so not sure what to do here. */
|
|
462
|
+
(args as any).type = event;
|
|
463
|
+
(handler as unknown as EventListener)(args)
|
|
464
|
+
});
|
|
465
|
+
|
|
466
|
+
this.nativeView.addEventListener<SignalType>(event, handler)
|
|
467
|
+
this.eventListeners.set(event as string, handler);
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
removeEventListener<Signals extends {}, SignalType extends keyof Signals>(event: SignalType, handler?: Signals[SignalType]) {
|
|
471
|
+
if(!componentIsEventWidget<Signals>(this.nativeView)){
|
|
472
|
+
return;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
this.eventListeners.delete(event as string);
|
|
476
|
+
this.nativeView.removeEventListener(event, handler)
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
dispatchEvent(event: string) {
|
|
480
|
+
if (this.nativeView) {
|
|
481
|
+
/**
|
|
482
|
+
* I don't see that NodeGUI has implemented QCoreApplication::sendEvent, so I think we can only no-op here.
|
|
483
|
+
* @see https://doc.qt.io/qt-5/eventsandfilters.html#sending-events
|
|
484
|
+
* @see https://doc.qt.io/qt-5/qcoreapplication.html#sendEvent
|
|
485
|
+
*
|
|
486
|
+
* I don't see any evidence that Qt events include the event name, so not sure whether to pass
|
|
487
|
+
* on an event name (which was for NativeScript purposes anyway) at all here.
|
|
488
|
+
*/
|
|
489
|
+
// this.nativeView.notify({ eventName: event, object: this.nativeView })
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
getAttribute(name: string): unknown {
|
|
494
|
+
if(!this.nativeView){
|
|
495
|
+
return void 0;
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
if(componentHasPropertyAccessor(this.nativeView)){
|
|
499
|
+
/**
|
|
500
|
+
* @see https://doc.qt.io/archives/qt-5.8/qobject.html#property
|
|
501
|
+
*/
|
|
502
|
+
return this.nativeView.property(name);
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
return (this.nativeView as any)[name];
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
private static readonly recycledOldProps: Record<string, any> = Object.freeze({});
|
|
509
|
+
|
|
510
|
+
setAttribute(name: string, value: unknown) {
|
|
511
|
+
/*
|
|
512
|
+
* A note to myself after following this rabbit hole several times before:
|
|
513
|
+
* Users may intuitively try to set the "text" property on an element such as <text>, simply because
|
|
514
|
+
* it's a likely property name to expect, and because it appears to be corroborated by Intellisense,
|
|
515
|
+
* due to our default of typing any unrecognised JSX key as a string value.
|
|
516
|
+
*
|
|
517
|
+
* In fact, RNText doesn't implement a text property in its setProps() method, so it (correctly) no-ops.
|
|
518
|
+
* To set text, we expect users to write it as:
|
|
519
|
+
*
|
|
520
|
+
* <text>hello</text>
|
|
521
|
+
*
|
|
522
|
+
* ... This creates an NSVText node with the text "hello", which Svelte reads using the .data accessor.
|
|
523
|
+
*/
|
|
524
|
+
|
|
525
|
+
["style",
|
|
526
|
+
"styleSheet", // TODO: implement
|
|
527
|
+
"class",
|
|
528
|
+
"className"].forEach(n => {
|
|
529
|
+
if(name.startsWith(n)){
|
|
530
|
+
// console.log(`[NSVElement.setAttribute("${name}", "${value}")]`);
|
|
531
|
+
}
|
|
532
|
+
})
|
|
533
|
+
|
|
534
|
+
if(name === "style"){
|
|
535
|
+
/*
|
|
536
|
+
* e.g. <view style={`align-items: center; justify-content: center; height: 100%;`}>
|
|
537
|
+
* c.f. <view style="align-items: center; justify-content: center; height: 100%;">
|
|
538
|
+
*
|
|
539
|
+
* We have three options here. We can either:
|
|
540
|
+
* 1) Parse the AST and set the styles one-by-one (neat, but inefficient), or;
|
|
541
|
+
* 2) Serialise this.stylesMap and merge it with this incoming value.
|
|
542
|
+
* 3) Clear this.stylesMap and replace _rawInlineStyle with this incoming value.
|
|
543
|
+
*
|
|
544
|
+
* The easiest to do is number 3..!
|
|
545
|
+
*/
|
|
546
|
+
this.stylesMap.clear();
|
|
547
|
+
if(componentIsStyleable(this._nativeView)){
|
|
548
|
+
// console.log(`[NSVElement.setAttribute("${name}", value)] – Setting _rawInlineStyle!`);
|
|
549
|
+
this._nativeView.setInlineStyle(value as string);
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
return;
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
if(name === "stylesheet"){
|
|
556
|
+
console.warn(`[NSVElement.setAttribute("${name}", value)] – TODO: implement stylesheet.`);
|
|
557
|
+
return;
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
if(name === "nodeRole" && typeof value === "string"){
|
|
561
|
+
this.nodeRole = value;
|
|
562
|
+
return;
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
if(name === "id"){
|
|
566
|
+
// console.log(`[NSVElement.setAttribute("${name}", "${value}")]`);
|
|
567
|
+
/**
|
|
568
|
+
* setProps would also do the trick, but we want our wrapping element to set the very
|
|
569
|
+
* same id on itself, too.
|
|
570
|
+
*/
|
|
571
|
+
this.id = value as string;
|
|
572
|
+
return;
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
if(name === "class"){
|
|
576
|
+
// console.log(`[NSVElement.setAttribute("${name}", "${value}")] on <${this.tagName}>`);
|
|
577
|
+
/**
|
|
578
|
+
* The "class" property isn't handled by setProps for some reason.
|
|
579
|
+
* It's probably special-cased by the React Host Config.
|
|
580
|
+
*/
|
|
581
|
+
if(componentHasPropertyAccessor(this.nativeView)){
|
|
582
|
+
/**
|
|
583
|
+
* @see https://doc.qt.io/archives/qt-5.8/qobject.html#property
|
|
584
|
+
*/
|
|
585
|
+
this.nativeView.setProperty(name, value as string);
|
|
586
|
+
return;
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
// /**
|
|
591
|
+
// * The 'ios' and 'android' properties (e.g. on ActionItem)
|
|
592
|
+
// * are readonly, so we need to assign one level lower.
|
|
593
|
+
// */
|
|
594
|
+
// if(name === "ios" && value){
|
|
595
|
+
// Object.keys(value).forEach((key: string) => {
|
|
596
|
+
// set(this.nativeView.ios, key, value);
|
|
597
|
+
// });
|
|
598
|
+
// return;
|
|
599
|
+
// }
|
|
600
|
+
|
|
601
|
+
// if(name === "android" && value){
|
|
602
|
+
// Object.keys(value).forEach((key: string) => {
|
|
603
|
+
// set(this.nativeView.android, key, value);
|
|
604
|
+
// });
|
|
605
|
+
// return;
|
|
606
|
+
// }
|
|
607
|
+
|
|
608
|
+
// set(this.nativeView, name, value)
|
|
609
|
+
|
|
610
|
+
if(!this.nativeView){
|
|
611
|
+
return;
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
/**
|
|
615
|
+
* React NodeGUI's API for setting props expects an object of props.
|
|
616
|
+
* We only set props one-at-a-time, so we'll avoid reallocations by re-using and cleaning up the same static object.
|
|
617
|
+
*/
|
|
618
|
+
this.recycledNewProps[name] = value;
|
|
619
|
+
this.nativeView.setProps(this.recycledNewProps, this.recycledOldProps);
|
|
620
|
+
delete this.recycledNewProps[name];
|
|
621
|
+
/**
|
|
622
|
+
* No way to tell whether a setter existed for the given attribute name, unfortunately.
|
|
623
|
+
* So we can't fall back to this.nativeView.setProperty() (though arguably that would be dangerous anyway).
|
|
624
|
+
*/
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
removeAttribute(name: string) {
|
|
628
|
+
if(name === "nodeRole"){
|
|
629
|
+
this.nodeRole = void 0;
|
|
630
|
+
return;
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
// potential issue: unsetValue is an empty object
|
|
634
|
+
// not all properties/attributes may know/check for this
|
|
635
|
+
// set(this.nativeView, name, unsetValue)
|
|
636
|
+
|
|
637
|
+
// originally we deleted the property, but in case of built-in properties
|
|
638
|
+
// this would break them. For example, deleting the padding property
|
|
639
|
+
// will prevent us from changing the padding once we deleted it
|
|
640
|
+
// that's not the expected behaviour.
|
|
641
|
+
// unset(this.nativeView, name)
|
|
642
|
+
|
|
643
|
+
console.warn(
|
|
644
|
+
`[NSVElement.removeAttribute] React NodeGUI hasn't implemented removeAttribute, so it's unclear how to implement ` +
|
|
645
|
+
`removeAttribute() in Svelte NodeGUI. You may want to try passing null or undefined instead of removing the attribute.`
|
|
646
|
+
);
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
removeChild(child: NSVNode): NSVNode {
|
|
650
|
+
const node = super.removeChild(child);
|
|
651
|
+
|
|
652
|
+
if (this.meta.viewFlags & NSVViewFlags.NO_CHILDREN) {
|
|
653
|
+
// debug('NO_CHILDREN')
|
|
654
|
+
return
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
if (this.meta?.viewFlags & NSVViewFlags.NO_CHILDREN) {
|
|
658
|
+
// debug('NO_CHILDREN')
|
|
659
|
+
return
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
if(child.nodeType === NSVNodeTypes.ELEMENT){
|
|
663
|
+
const childElement = child as NSVElement;
|
|
664
|
+
|
|
665
|
+
if(this.nativeView){
|
|
666
|
+
if(childElement.nativeView){
|
|
667
|
+
// console.log(`Successful native remove: ${this.toString()} X ${childElement.toString()}`);
|
|
668
|
+
this.nativeView.removeChild(childElement.nativeView);
|
|
669
|
+
} else {
|
|
670
|
+
// console.warn(`No native child to remove: ${this.toString()} X ${childElement.toString()}`);
|
|
671
|
+
}
|
|
672
|
+
} else {
|
|
673
|
+
// console.warn(`Skipping native remove: ${this.toString()} X ${childElement.toString()}`);
|
|
674
|
+
// It's probably a virtual element like Head, Style, etc; there is no native view to remove from.
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
return node;
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
appendChild(child: NSVNode): NSVNode {
|
|
682
|
+
const node = super.appendChild(child);
|
|
683
|
+
|
|
684
|
+
if(child.nodeType === NSVNodeTypes.ELEMENT){
|
|
685
|
+
const childElement = child as NSVElement;
|
|
686
|
+
|
|
687
|
+
if(this.meta?.nodeOps?.insert){
|
|
688
|
+
const defer: boolean = this.meta.nodeOps.insert(childElement, this, -1) === "defer";
|
|
689
|
+
if(!defer){
|
|
690
|
+
return node;
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
if(this.nativeView){
|
|
695
|
+
if(childElement.nativeView){
|
|
696
|
+
// console.log(`Successful native append: ${this.toString()} > ${childElement.toString()}`);
|
|
697
|
+
this.nativeView.appendChild(childElement.nativeView);
|
|
698
|
+
} else {
|
|
699
|
+
// console.warn(`No native child to append: ${this.toString()} > ${childElement.toString()}`);
|
|
700
|
+
}
|
|
701
|
+
} else {
|
|
702
|
+
// console.warn(`Skipping native append: ${this.toString()} > ${childElement.toString()}`);
|
|
703
|
+
// It's probably a virtual element like Head, Style, etc; there is no native view to append into.
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
return node;
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
insertBefore(newNode: NSVNode, referenceNode?: NSVNode | null): NSVNode {
|
|
711
|
+
const node = super.insertBefore(newNode, referenceNode);
|
|
712
|
+
|
|
713
|
+
if(newNode.nodeType === NSVNodeTypes.ELEMENT){
|
|
714
|
+
const newElement = newNode as NSVElement;
|
|
715
|
+
|
|
716
|
+
const referenceIndex = referenceNode == null ?
|
|
717
|
+
-1 :
|
|
718
|
+
this.childNodes.findIndex(node => node === referenceNode);
|
|
719
|
+
|
|
720
|
+
if(this.meta?.nodeOps?.insert){
|
|
721
|
+
const defer: boolean = this.meta.nodeOps.insert(newElement, this, referenceIndex) === "defer";
|
|
722
|
+
if(!defer){
|
|
723
|
+
return node;
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
if(this.nativeView){
|
|
728
|
+
if(newElement.nativeView){
|
|
729
|
+
if(referenceNode){
|
|
730
|
+
if((referenceNode as NSVElement).nativeView){
|
|
731
|
+
// console.log(`Successful native insertBefore: > ${newElement.toString()}, ${referenceNode.toString()}`);
|
|
732
|
+
this.nativeView.insertBefore(newElement.nativeView, (referenceNode as NSVElement).nativeView);
|
|
733
|
+
} else {
|
|
734
|
+
// We're at the mercy of the underlying React NodeGUI and NodeGUI implementations.
|
|
735
|
+
|
|
736
|
+
function findClosestNonVirtualPreviousElementSibling(node: NSVNode): NSVElement|null {
|
|
737
|
+
let haul: NSVElement|null = null;
|
|
738
|
+
while(node = node.previousSibling){
|
|
739
|
+
if(node.nodeType === NSVNodeTypes.ELEMENT && (node as NSVElement).nativeView){
|
|
740
|
+
haul = node as NSVElement;
|
|
741
|
+
break;
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
return haul;
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
const closest: NSVElement|null = findClosestNonVirtualPreviousElementSibling(referenceNode);
|
|
749
|
+
if(closest){
|
|
750
|
+
// console.warn(`No native referenceNode to insertBefore (was given ${referenceNode.toString()}), so will try inserting before the closest eligible previousSibling instead: ${this.toString()} > ${newElement.toString()}, ${closest.toString()}`);
|
|
751
|
+
this.nativeView.insertBefore(newElement.nativeView, closest.nativeView);
|
|
752
|
+
} else {
|
|
753
|
+
// console.warn(`No native referenceNode to insertBefore (was given ${referenceNode.toString()}), and no eligible previousSiblings, so will try appendChild instead: ${this.toString()} > ${newElement.toString()}`);
|
|
754
|
+
this.nativeView.appendChild(newElement.nativeView);
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
} else {
|
|
758
|
+
// console.warn(`No referenceNode to insertBefore, so will try appendChild instead: ${this.toString()} > ${newElement.toString()}, ${referenceNode?.toString() ?? "NONE"}`);
|
|
759
|
+
this.nativeView.appendChild(newElement.nativeView);
|
|
760
|
+
}
|
|
761
|
+
} else {
|
|
762
|
+
console.warn(`No native newNode to insertBefore: ${this.toString()} > ${newElement.toString()}, ${referenceNode?.toString() ?? "NONE"}`);
|
|
763
|
+
}
|
|
764
|
+
} else {
|
|
765
|
+
// It's probably a virtual element like Head, Style, etc; there is no native view to insert into.
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
return node;
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
toString(): string {
|
|
773
|
+
if(this.tagName === NSVNodeTypes.TEXT){
|
|
774
|
+
const textContent = this.textContent;
|
|
775
|
+
return `<${this.tagName}(${this.nodeId}) id="${this.id}">${textContent.slice(0, 15)}${textContent.length > 15 ? "..." : ""}</text>`;
|
|
776
|
+
}
|
|
777
|
+
return `<${this.tagName}(${this.nodeId}) id="${this.id}">`;
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
export class NSVComment extends NSVNode {
|
|
782
|
+
constructor(public data: string = "") {
|
|
783
|
+
super(NSVNodeTypes.COMMENT);
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
toString(): string {
|
|
787
|
+
return "NSVComment:" + `"` + this.data + `"`;
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
/**
|
|
792
|
+
* This is a text node. It's a virtual element (is non-visual), and serves only as a data structure.
|
|
793
|
+
* Whenever its data changes, we tell its parentNode to update its "text" property.
|
|
794
|
+
*/
|
|
795
|
+
export class NSVText extends NSVNode {
|
|
796
|
+
private _data: string;
|
|
797
|
+
|
|
798
|
+
constructor(data: string = ""){
|
|
799
|
+
super(NSVNodeTypes.TEXT);
|
|
800
|
+
// console.log(`[NSVText] constructor "${this._text}"`);
|
|
801
|
+
this.data = data;
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
get data(): string | undefined {
|
|
805
|
+
return this._data;
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
set data(t: string | undefined) {
|
|
809
|
+
// console.log(`NSVText text setter was called!`);
|
|
810
|
+
this._data = t;
|
|
811
|
+
// Tell any parent node to update its "text" property because this text node has just updated its contents.
|
|
812
|
+
if(this.parentNode?.nodeType === NSVNodeTypes.ELEMENT){
|
|
813
|
+
(this.parentNode as NSVElement).updateNativeText();
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
|
|
817
|
+
/**
|
|
818
|
+
* The Svelte runtime calls this upon the text node.
|
|
819
|
+
* @see set_data()
|
|
820
|
+
*/
|
|
821
|
+
get wholeText(): string|undefined {
|
|
822
|
+
// console.log(`NSVText get wholeText was called!`);
|
|
823
|
+
let _wholeText = "";
|
|
824
|
+
if(this.previousSibling?.nodeType === NSVNodeTypes.TEXT){
|
|
825
|
+
_wholeText += (this.previousSibling as NSVText).data;
|
|
826
|
+
}
|
|
827
|
+
if(this.nextSibling?.nodeType === NSVNodeTypes.TEXT){
|
|
828
|
+
_wholeText += (this.nextSibling as NSVText).wholeText; // recurses
|
|
829
|
+
} else {
|
|
830
|
+
_wholeText += this.data;
|
|
831
|
+
}
|
|
832
|
+
// console.log(`get wholeText: ${_wholeText}`);
|
|
833
|
+
return _wholeText;
|
|
834
|
+
}
|
|
835
|
+
replaceWholeText(wholeText: string): null | NSVText {
|
|
836
|
+
console.log(`NSVText replaceWholeText was called!`);
|
|
837
|
+
let recipient: NSVText = this;
|
|
838
|
+
if(this.previousSibling?.nodeType === NSVNodeTypes.TEXT){
|
|
839
|
+
recipient = this.previousSibling as NSVText;
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
let nextSibling: NSVNode = recipient;
|
|
843
|
+
while(nextSibling = recipient.nextSibling){
|
|
844
|
+
if(nextSibling.nodeType !== NSVNodeTypes.TEXT){
|
|
845
|
+
break;
|
|
846
|
+
}
|
|
847
|
+
nextSibling.parentNode.removeChild(nextSibling);
|
|
848
|
+
}
|
|
849
|
+
recipient.data = wholeText;
|
|
850
|
+
return wholeText === "" ? null : recipient;
|
|
851
|
+
}
|
|
852
|
+
|
|
853
|
+
toString(): string {
|
|
854
|
+
const textContent = this.textContent;
|
|
855
|
+
return `<#text(${this.nodeId})>${this.data.slice(0, 15)}${this.data.length > 15 ? "..." : ""}</#text>`;
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
export class NSVRoot<T extends NativeView = NativeView> extends NSVNode {
|
|
860
|
+
baseRef?: NSVElement<T>
|
|
861
|
+
|
|
862
|
+
constructor() {
|
|
863
|
+
super(NSVNodeTypes.ROOT)
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
get text(): string | undefined {
|
|
867
|
+
error(`text() getter called on element that does not implement it.`, this);
|
|
868
|
+
return void 0;
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
set text(t: string | undefined) {
|
|
872
|
+
error(`text() setter called on element that does not implement it.`, this);
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
setBaseRef(el: NSVNode|null): void {
|
|
876
|
+
// console.log(`NSVRoot->appendChild(${el.nodeType})`)
|
|
877
|
+
if (el instanceof NSVElement) {
|
|
878
|
+
this.baseRef = el
|
|
879
|
+
}
|
|
880
|
+
// no-op
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
toString(): string {
|
|
884
|
+
if(this.baseRef){
|
|
885
|
+
return "NSVRoot:" + this.baseRef.toString();
|
|
886
|
+
} else {
|
|
887
|
+
return "NSVRoot:" + "null";
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
}
|