@makano/rew 1.2.2 → 1.2.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,18 +0,0 @@
1
- <!doctype html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8" />
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
- <title>$OPTIONS(title)</title>
7
-
8
- <style>
9
- /* $OPTIONS(style) */
10
- </style>
11
-
12
- <script>
13
- window.onerror = () => alert('ERror');
14
- </script>
15
- </head>
16
-
17
- <body></body>
18
- </html>
@@ -1,245 +0,0 @@
1
- try {
2
- window.execContext = $OPTIONS(json.execContext);
3
- } catch (e) {
4
- window.execContext = {};
5
- }
6
-
7
- try {
8
- window.exec = $OPTIONS(exec);
9
- } catch (e) {
10
- window.exec = function () {};
11
- }
12
-
13
- const DOM = [];
14
-
15
- const findInDom = (id) => DOM.find((el) => el.widgetOptions.uuid == id) || DOM.find((el) => el.id == id);
16
-
17
- const parseStyleValue = (val) => val;
18
-
19
- const addTo = (el, parent) => {
20
- if (parent == 'null') {
21
- document.body.appendChild(el);
22
- } else {
23
- findInDom(parent).appendChild(el);
24
- }
25
- };
26
-
27
- const initElement = (el, options, update = false) => {
28
- if (el.widgetOptions) {
29
- if (el.widgetOptions.style) {
30
- for (let i in options.style) {
31
- el.style.removeProperty(i, el.widgetOptions.style[i]);
32
- }
33
- }
34
- if (el.widgetOptions.attr) {
35
- for (let i in el.widgetOptions.attr) {
36
- el.removeAttribute(i);
37
- }
38
- }
39
- }
40
-
41
- el.widgetOptions = options;
42
- el.id = options.id;
43
- el.textContent = options.data.text;
44
-
45
- if (options.style) {
46
- for (let i in options.style) {
47
- el.style.setProperty(i, options.style[i]);
48
- }
49
- }
50
-
51
- if (options.attr) {
52
- for (let i in options.attr) {
53
- el.setAttribute(i, options.attr[i]);
54
- }
55
- }
56
-
57
- if (options.children.length) {
58
- options.children.forEach((option) => {
59
- option.parent = options.uuid;
60
- if (update) updateElement(findInDom(option.uuid), option);
61
- else createElement(option);
62
- });
63
- }
64
-
65
- if (options.parent) {
66
- addTo(el, options.parent);
67
- }
68
- };
69
-
70
- const updateElement = (el, options) => {
71
- if (!el) return;
72
- initElement(el, options, true);
73
- return el;
74
- };
75
-
76
- const events = [
77
- 'click',
78
- 'dblclick',
79
- 'mousedown',
80
- 'mouseup',
81
- 'mouseover',
82
- 'mouseout',
83
- 'mousemove',
84
- 'mouseenter',
85
- 'mouseleave',
86
- 'keydown',
87
- 'keypress',
88
- 'keyup',
89
- 'change',
90
- 'input',
91
- 'submit',
92
- 'focus',
93
- 'blur',
94
- 'copy',
95
- 'cut',
96
- 'paste',
97
- 'scroll',
98
- 'wheel',
99
- 'resize',
100
- 'contextmenu',
101
- 'drag',
102
- 'dragstart',
103
- 'dragend',
104
- 'dragenter',
105
- 'dragleave',
106
- 'dragover',
107
- 'drop',
108
- 'error',
109
- 'load',
110
- 'abort',
111
- ];
112
- const handleListeners = (el) => {
113
- events.forEach((event) => {
114
- el.addEventListener(event, (e) => {
115
- sendData({
116
- action: 'hook:eventTrigger',
117
- data: {
118
- rid: 'event_trigger',
119
- object: {
120
- uuid: el.widgetOptions.uuid,
121
- event,
122
- data: {
123
- mouse: { x: e.clientX, y: e.clientY },
124
- key: { code: e.keyCode, key: e.key },
125
- },
126
- },
127
- },
128
- });
129
- });
130
- });
131
- };
132
-
133
- function eventHandlerFunction({ uuid, hookID, event }) {
134
- return function (e) {
135
- sendData({
136
- action: 'hook:event_' + event,
137
- data: {
138
- rid: hookID,
139
- object: {
140
- uuid,
141
- event,
142
- data: {
143
- mouse: { x: e.clientX, y: e.clientY },
144
- key: { code: e.keyCode, key: e.key },
145
- },
146
- },
147
- },
148
- });
149
- };
150
- }
151
-
152
- const createElement = (options) => {
153
- const el = document.createElement(options.element);
154
- DOM.push(el);
155
- initElement(el, options);
156
- return el;
157
- };
158
-
159
- const stringifyJSON = (json) => {
160
- try {
161
- return JSON.stringify(json, null, 4);
162
- } catch (e) {
163
- return json.toString();
164
- }
165
- };
166
-
167
- const log = (...strings) => {
168
- window.webkit.messageHandlers.external.postMessage(
169
- JSON.stringify(
170
- {
171
- action: 'log',
172
- data: strings
173
- .map((r) => (typeof r == 'object' ? stringifyJSON(r) : `${r.toString()}`))
174
- // .map((i) => i.replace(/\"/g, '\\\\"').replace(/\n/g, "\\\\n"))
175
- .join('\n'),
176
- },
177
- null,
178
- 4,
179
- ),
180
- );
181
- };
182
-
183
- const sendData = (data) => {
184
- log('RESPONSE::' + stringifyJSON(data));
185
- };
186
-
187
- function process_data(data) {
188
- return JSON.parse(data);
189
- }
190
-
191
- window.recieveMessage = (data) => {
192
- const edata = data;
193
- if (edata.action == 'eventListen') {
194
- const el = findInDom(edata.data.uuid);
195
- if (el) {
196
- el.addEventListener(edata.data.event, eventHandlerFunction(edata.data));
197
- }
198
- } else if (edata.action == 'createElement') {
199
- const options = edata.data;
200
- try {
201
- createElement(options);
202
- } catch (e) {
203
- log(e.toString());
204
- }
205
- } else if (edata.action == 'addStyleSheet') {
206
- const style = document.createElement('style');
207
- style.textContent = edata.data;
208
- document.head.appendChild(style);
209
- } else if (edata.action == 'updateElement') {
210
- const options = edata.data;
211
- try {
212
- updateElement(findInDom(options.uuid), options);
213
- } catch (e) {
214
- log(e.toString());
215
- }
216
- } else if (edata.action == 'findElement') {
217
- const id = edata.data.id;
218
- const rid = edata.data.rid;
219
- try {
220
- sendData({
221
- action: 'hook:findElement',
222
- data: { rid, object: findInDom(id)?.widgetOptions },
223
- });
224
- } catch (e) {
225
- log(e.toString());
226
- }
227
- } else if (edata.action == 'message') {
228
- window.dispatchEvent(
229
- new CustomEvent('message', {
230
- detail: edata.data,
231
- }),
232
- );
233
- }
234
- };
235
-
236
- window.addEventListener('load', () => {
237
- window.exec({
238
- ...window.execContext,
239
- window,
240
- log,
241
- send: (data) => sendData({ action: 'message', data }),
242
- onRecieve: (cb) => window.addEventListener('message', (e) => cb(e.detail || {})),
243
- });
244
- log('SETUP::READY');
245
- });
@@ -1,184 +0,0 @@
1
- const emitter = require('../../../functions/emitter');
2
- const { struct } = require('../../../models/struct');
3
- const { generateRandomID } = require('../../../functions/id');
4
-
5
- module.exports.uiClasses = (context, options, send, recieve, hook, rmHook) => {
6
- const _sanitizeOptions = (options) => {
7
- return {
8
- ...options,
9
- children: options.children.map((i) => i.options),
10
- };
11
- };
12
- const RemWidgetOptions = struct({
13
- element: 'div',
14
- class: '',
15
- attr: {},
16
- id: '',
17
- data: {
18
- text: '',
19
- },
20
- children: [],
21
- uuid: '',
22
- parent: '!any',
23
- style: {},
24
- });
25
-
26
- const CreatedElements = [];
27
-
28
- class RewWidget {
29
- _emitter = emitter();
30
- on(event, callback) {
31
- const hookID = this.uuid + '_' + generateRandomID(4);
32
- this._emitter.on(event, callback, { hookID });
33
- hook(
34
- hookID,
35
- 'event_' + event,
36
- (data) => {
37
- this.emit(event, data);
38
- },
39
- false,
40
- );
41
- send({ action: 'eventListen', data: { uuid: this.uuid, event, hookID } });
42
- return this;
43
- }
44
- off(event, callback) {
45
- this._emitter.off(event, callback, (e) => rmHook(e.hookID));
46
- return this;
47
- }
48
- emit(event, callback) {
49
- this._emitter.emit(event, callback);
50
- return this;
51
- }
52
-
53
- options = RemWidgetOptions();
54
- constructor(options = RemWidgetOptions()) {
55
- const config = RemWidgetOptions(options);
56
- config.uuid = generateRandomID();
57
- this.options = config;
58
- this.options.children.forEach((child) => (child.parent = this));
59
- this.init();
60
- CreatedElements.push(this);
61
- }
62
-
63
- init() {
64
- send({ action: 'createElement', data: _sanitizeOptions(this.options) });
65
- }
66
-
67
- parent = null;
68
-
69
- get uuid() {
70
- return this.options.uuid;
71
- }
72
-
73
- get id() {
74
- return this.options.id;
75
- }
76
-
77
- get children() {
78
- return this.options.children;
79
- }
80
-
81
- find(id, recursive = true) {
82
- let childFound = this.children.find((e) => e.id == id) || this.children.find((e) => e.uuid == id);
83
- if (childFound) return childFound;
84
- else if (!recursive) return null;
85
- for (let child of this.children) {
86
- let subchild = child.find(id);
87
- if (subchild) {
88
- return subchild;
89
- }
90
- }
91
- }
92
-
93
- update() {
94
- send({ action: 'updateElement', data: _sanitizeOptions(this.options) });
95
- return this;
96
- }
97
-
98
- text(text) {
99
- this.options.data.text = text;
100
- return this.update();
101
- }
102
-
103
- data(key, value) {
104
- if (!value) return this.options.data[key];
105
- this.options.data[key] = value;
106
- return this.update();
107
- }
108
-
109
- attr(attr, reset = false) {
110
- if (reset) this.options.attr = attr;
111
- else this.options.attr = { ...this.options.attr, ...attr };
112
- return this.update();
113
- }
114
-
115
- style(style, reset = false) {
116
- if (reset) this.options.style = style;
117
- else this.options.style = { ...this.options.style, ...style };
118
- return this.update();
119
- }
120
-
121
- add(child) {
122
- this.options.children.push(child);
123
- return this.update();
124
- }
125
-
126
- remove(childId, recursive = true) {
127
- const child = typeof childId == 'string' ? this.find(childId, recursive) : childId;
128
- if (!child) return this;
129
- if (recursive && child.parent !== this) {
130
- child.parent.remove(child);
131
- } else {
132
- this.options.children.splice(this.options.children.indexOf(child), 1);
133
- this.update();
134
- }
135
- return this;
136
- }
137
- }
138
-
139
- class RewTextWidget extends RewWidget {
140
- constructor(text = '', options = RemWidgetOptions({})) {
141
- super({
142
- ...options,
143
- data: { ...options.data, text },
144
- });
145
- }
146
- }
147
-
148
- class StyleSheet {
149
- constructor(css = '') {
150
- send({ action: 'addStyleSheet', data: css });
151
- }
152
- }
153
-
154
- function findElement(id) {
155
- return new Promise((r) => {
156
- const rid = generateRandomID();
157
- hook(rid, 'findElement', (data) => {
158
- r(CreatedElements.find((e) => e.uuid == data.uuid) || data);
159
- });
160
- send({ action: 'findElement', data: { id, rid } });
161
- });
162
- }
163
-
164
- // hook('event_trigger', 'eventTrigger', (data) => {
165
- // const el = CreatedElements.find(e => e.uuid = data.uuid);
166
- // if(el){
167
- // el.emit(data.event, data.data);
168
- // }
169
- // }, false);
170
-
171
- const Transmitter = {
172
- send: (data) => send({ action: 'message', data }),
173
- recieve: (cb) => recieve((data) => cb(data.data)),
174
- };
175
-
176
- return {
177
- Widget: RewWidget,
178
- Text: RewTextWidget,
179
- WidgetOptions: RemWidgetOptions,
180
- findElement,
181
- StyleSheet: StyleSheet,
182
- Transmitter,
183
- };
184
- };
@@ -1,157 +0,0 @@
1
- const path = require('path');
2
- const { spawn, exec } = require('child_process');
3
- const fs = require('fs');
4
- const { uiClasses } = require('./modules/ui/classes');
5
- const { generateRandomID } = require('../functions/id');
6
- const { THEME_PATH } = require('../const/files');
7
- const readline = require('readline');
8
- const emitter = require('../functions/emitter');
9
-
10
- const BIN_PATH = path.resolve(__dirname, '../../../bin/ui');
11
- const HTML_STRING = fs.readFileSync(path.resolve(__dirname, '../html/ui.html'), { encoding: 'utf-8' });
12
- const JS_STRING = fs.readFileSync(path.resolve(__dirname, '../html/ui.js'), {
13
- encoding: 'utf-8',
14
- });
15
-
16
- const replaceString = (string, options) =>
17
- string.replace(/\$OPTIONS\(([^)]+)\)/g, (_, n) =>
18
- n.startsWith('json.') ? JSON.stringify(options[n.split('json.')[1]] || '{}') : options[n] || _,
19
- );
20
-
21
- const defaultOptions = {
22
- title: 'Title',
23
- onExit: () => process.exit(),
24
- style: '',
25
- stylePath: THEME_PATH,
26
- exec: () => {},
27
- execContext: {},
28
- };
29
-
30
- module.exports = (context) => ({
31
- start: (o = {}) => {
32
- const options = {
33
- ...defaultOptions,
34
- ...o,
35
- };
36
-
37
- const hookedSocketListeners = {};
38
-
39
- const runId = generateRandomID();
40
- const tmpFile = '/tmp/' + runId + '.ruw.ui.socket';
41
-
42
- options.runId = runId;
43
-
44
- if (fs.existsSync(options.stylePath)) options.style = fs.readFileSync(options.stylePath, { encoding: 'utf-8' }) + '\n' + options.style;
45
-
46
- options.style = ' */\n' + options.style + '\n/* ';
47
-
48
- const HTML = replaceString(HTML_STRING, options);
49
- const JS = replaceString(JS_STRING, options);
50
-
51
- /**
52
- * Queue for future writes
53
- * @type {string[]}
54
- * */
55
- const queue = [];
56
-
57
- const send = (data) => {
58
- const content = fs.readFileSync(tmpFile, { encoding: 'utf-8' });
59
- if (content) {
60
- queue.push(data);
61
- } else {
62
- fs.writeFileSync(tmpFile, typeof data !== 'string' ? JSON.stringify(data) : data);
63
- }
64
- };
65
-
66
- const sendEvent = (data) => {
67
- send({
68
- action: 'JS',
69
- data: `window.recieveMessage(${JSON.stringify(data)})`,
70
- });
71
- };
72
-
73
- const g_emitter = emitter();
74
-
75
- const recieve = (data) => {
76
- g_emitter.emit('recieve', data);
77
- };
78
-
79
- const rl = readline.createInterface({
80
- input: process.stdin,
81
- output: process.stdout,
82
- });
83
-
84
- rl.question('', () => {});
85
-
86
- fs.writeFileSync(tmpFile, '');
87
-
88
- fs.watch(tmpFile, { encoding: 'utf-8' }).on('change', () => {
89
- if (queue.length) {
90
- send(queue.pop());
91
- }
92
- });
93
-
94
- const p = spawn(options.bin || BIN_PATH, [runId]);
95
-
96
- p.on('close', (code) => {
97
- rl.close();
98
- options.onExit(code);
99
- });
100
-
101
- process.on('beforeExit', () => {
102
- p.kill();
103
- fs.unlinkSync(tmpFile);
104
- });
105
-
106
- g_emitter.on('recieve', (edata) => {
107
- if (edata.action.startsWith('hook:')) {
108
- const hook = hookedSocketListeners[edata.data.rid];
109
- const type = edata.action.split('hook:')[1];
110
- if (hook && hook.type == type) {
111
- hookedSocketListeners[edata.data.rid].cb(edata.data.object);
112
- if (hook.once) delete hookedSocketListeners[edata.data.rid];
113
- }
114
- }
115
- });
116
-
117
- return new Promise((r) => {
118
- p.stdout.on('data', (data) => {
119
- if (data.toString().startsWith('RESPONSE::')) {
120
- const d = data.toString().split('RESPONSE::')[1];
121
- const jd = JSON.parse(d);
122
- recieve(jd);
123
- } else if (data.toString().trim().endsWith('SETUP::READY')) {
124
- console.log('READY');
125
- r(
126
- uiClasses(
127
- context,
128
- options,
129
- sendEvent,
130
- (cb) => {
131
- g_emitter.on('recieve', cb);
132
- },
133
- (rid, type, cb, once = true) => {
134
- // Add hook
135
- hookedSocketListeners[rid] = { type, cb, once };
136
- },
137
- (rid) => {
138
- // Remove hook
139
- delete hookedSocketListeners[rid];
140
- },
141
- ),
142
- );
143
- } else if (data.toString().endsWith('SETUP::HTML')) {
144
- send({ action: 'JS2', data: JS, isSetup: true });
145
- } else if (data.toString() == 'INIT::READY') {
146
- send({ action: 'HTML', data: HTML });
147
- } else {
148
- console.log(data.toString());
149
- }
150
- });
151
-
152
- p.stderr.on('data', (data) => {
153
- console.error(data.toString());
154
- });
155
- });
156
- },
157
- });
package/meson.build DELETED
@@ -1,13 +0,0 @@
1
- project('rew', 'cpp',
2
- version : '0.1',
3
- default_options : ['warning_level=3', 'cpp_std=c++14'])
4
-
5
- gtk3 = dependency('gtk+-3.0', method : 'pkg-config')
6
- webkit2gtk = dependency('webkit2gtk-4.0', method : 'pkg-config')
7
- libwebsockets = dependency('libwebsockets', method : 'pkg-config')
8
- jsoncpp = dependency('jsoncpp', method : 'pkg-config')
9
-
10
- executable('ui',
11
- 'cpp/ui.cpp',
12
- install : true,
13
- dependencies : [gtk3, webkit2gtk, libwebsockets, jsoncpp])