add support GTK server

This commit is contained in:
Namhyeon Go 2020-10-20 17:58:58 +09:00
parent cfed419ab5
commit 38ae99300d
4 changed files with 284 additions and 9 deletions

157
lib/dompath.js Normal file
View File

@ -0,0 +1,157 @@
// https://stackoverflow.com/a/58677712/3702603
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
Elements = {};
Elements.DOMPath = {};
/**
* @param {!Node} node
* @param {boolean=} optimized
* @return {string}
*/
Elements.DOMPath.xPath = function (node, optimized) {
if (node.nodeType === Node.DOCUMENT_NODE) {
return '/';
}
const steps = [];
let contextNode = node;
while (contextNode) {
const step = Elements.DOMPath._xPathValue(contextNode, optimized);
if (!step) {
break;
} // Error - bail out early.
steps.push(step);
if (step.optimized) {
break;
}
contextNode = contextNode.parentNode;
}
steps.reverse();
return (steps.length && steps[0].optimized ? '' : '/') + steps.join('/');
};
/**
* @param {!Node} node
* @param {boolean=} optimized
* @return {?Elements.DOMPath.Step}
*/
Elements.DOMPath._xPathValue = function (node, optimized) {
let ownValue;
const ownIndex = Elements.DOMPath._xPathIndex(node);
if (ownIndex === -1) {
return null;
} // Error.
switch (node.nodeType) {
case Node.ELEMENT_NODE:
if (optimized && node.getAttribute('id')) {
return new Elements.DOMPath.Step('//*[@id="' + node.getAttribute('id') + '"]', true);
}
ownValue = node.localName;
break;
case Node.ATTRIBUTE_NODE:
ownValue = '@' + node.nodeName;
break;
case Node.TEXT_NODE:
case Node.CDATA_SECTION_NODE:
ownValue = 'text()';
break;
case Node.PROCESSING_INSTRUCTION_NODE:
ownValue = 'processing-instruction()';
break;
case Node.COMMENT_NODE:
ownValue = 'comment()';
break;
case Node.DOCUMENT_NODE:
ownValue = '';
break;
default:
ownValue = '';
break;
}
if (ownIndex > 0) {
ownValue += '[' + ownIndex + ']';
}
return new Elements.DOMPath.Step(ownValue, node.nodeType === Node.DOCUMENT_NODE);
};
/**
* @param {!Node} node
* @return {number}
*/
Elements.DOMPath._xPathIndex = function (node) {
// Returns -1 in case of error, 0 if no siblings matching the same expression,
// <XPath index among the same expression-matching sibling nodes> otherwise.
function areNodesSimilar(left, right) {
if (left === right) {
return true;
}
if (left.nodeType === Node.ELEMENT_NODE && right.nodeType === Node.ELEMENT_NODE) {
return left.localName === right.localName;
}
if (left.nodeType === right.nodeType) {
return true;
}
// XPath treats CDATA as text nodes.
const leftType = left.nodeType === Node.CDATA_SECTION_NODE ? Node.TEXT_NODE : left.nodeType;
const rightType = right.nodeType === Node.CDATA_SECTION_NODE ? Node.TEXT_NODE : right.nodeType;
return leftType === rightType;
}
const siblings = node.parentNode ? node.parentNode.children : null;
if (!siblings) {
return 0;
} // Root node - no siblings.
let hasSameNamedElements;
for (let i = 0; i < siblings.length; ++i) {
if (areNodesSimilar(node, siblings[i]) && siblings[i] !== node) {
hasSameNamedElements = true;
break;
}
}
if (!hasSameNamedElements) {
return 0;
}
let ownIndex = 1; // XPath indices start with 1.
for (let i = 0; i < siblings.length; ++i) {
if (areNodesSimilar(node, siblings[i])) {
if (siblings[i] === node) {
return ownIndex;
}
++ownIndex;
}
}
return -1; // An error occurred: |node| not found in parent's children.
};
/**
* @unrestricted
*/
Elements.DOMPath.Step = class {
/**
* @param {string} value
* @param {boolean} optimized
*/
constructor(value, optimized) {
this.value = value;
this.optimized = optimized || false;
}
/**
* @override
* @return {string}
*/
toString() {
return this.value;
}
};

112
lib/gtkserver.js Normal file
View File

@ -0,0 +1,112 @@
////////////////////////////////////////////////////////////////////////
// GTKServer API
////////////////////////////////////////////////////////////////////////
// Common (Elements)
var GTKElements = [];
// Common (Element)
var GTKElement = function(elementType) {
this.Width = 0;
this.Height = 0;
this.setWidth = function(width) {
this.Width = width;
};
this.setHeight = function(height) {
this.Height = height;
};
this,onchange = function() {};
this.onclick = function() {};
this.onmouseover = function() {};
this.onmouseout = function() {};
this.onkeydown = function() {};
this.onload = function() {};
this.addEventListener = function(ev, fn) {
if (typeof(fn) == "function") {
this['on' + ev] = fn;
} else {
throw new TypeError("listener must be a function");
}
};
GTKElements.push(this);
};
// Window
var Window = function() {
GTKElement.apply(this, arguments);
this.Title = "WelsonJS GTK GUI Application";
this.setTitle = function(title) {
this.Title = title;
};
};
Window.prototype = new GTKElement();
Window.prototype.constructor = Window;
// Table
var Table = function() {
GTKElement.apply(this, arguments);
this.attach = function(element, left, right, top, buttom) {
// TODO: Table.Attach()
};
};
Table.prototype = new GTKElement();
Table.prototype.constructor = Table;
// Button
var Button = function() {
GTKElement.apply(this, arguments);
this.Text = "Button";
this.setText = function(text) {
this.Text = text;
};
};
Button.prototype = new GTKElement();
Button.prototype.constructor = Button;
// Label
var Label = function() {
GTKElement.apply(this, arguments);
this.Text = "Label";
this.setText = function(text) {
this.Text = text;
};
};
Label.prototype = new GTKElement();
Label.prototype.constructor = Label;
// RadioBox
var RadioBox = function() {
GTKElement.apply(this, arguments);
this.Text = "RadioBox";
this.setText = function(text) {
this.Text = text;
};
};
RadioBox.prototype = new GTKElement();
RadioBox.prototype.constructor = RadioBox;
// CheckBox
var CheckBox = function() {
GTKElement.apply(this, arguments);
this.Text = "CheckBox";
this.setText = function(text) {
this.Text = text;
};
};
CheckBox.prototype = new GTKElement();
CheckBox.prototype.constructor = CheckBox;
// TextBox
var TextBox = function() {
this.Text = "TextBox";
this.setText = function(text) {
this.Text = text;
};
};
TextBox.prototype = new GTKElement();
TextBox.prototype.constructor = TextBox;

View File

@ -1,7 +1,6 @@
////////////////////////////////////////////////////////////////////////
// HTTPServer API
///////////////////////////////////////////////////////////////////////
var HTTPServer = {
_this: this, // Avoid conflicts between HTTPServer and Winsock variables
@ -24,24 +23,31 @@ var HTTPServer = {
Connections: {},
CreateWinsockObject: function() {
return CreateObject([
"MSWinsock.Winsock.1",
"MSWinsock.Winsock"
], "listener_");
},
Bind: function(port) {
try {
_this.Listener = CreateObject(["MSWinsock.Winsock.1", "MSWinsock.Winsock"], "listener_");
_this.Listener = _this.CreateWinsockObject();
_this.Listener.localPort = port;
_this.Listener.bind();
_this.Listener.listen();
console.info("Listening port: " + port);
} catch(e) {
} catch (e) {
console.error("port " + port " could not bind: " + e.message);
}
},
OnRequest : function(request, response) {
OnRequest: function(request, response) {
console.log("HTTPServer.OnRequest() dose not implemented");
},
CreateServer: function(OnRequest) {
if(typeof OnRequest !== "function") {
if (typeof OnRequest !== "function") {
throw new TypeError("OnRequest() must be a function.");
}
_this.OnRequest = OnRequest;
@ -53,11 +59,11 @@ var HTTPServer = {
console.info("Connection request " + requestID);
_this.Connections[requestID] = {
Listener: CreateObject(["MSWinsock.Winsock.1", "MSWinsock.Winsock"], "listener_");
Listener: _this.CreateWinsockObject()
};
_this.Connections[requestID].Listener.accept(requestID);
},
DataArrival: function(length) {
// TODO: DataArrival
},

View File

@ -10,7 +10,7 @@ exports.require = global.require;
// only less than IE 9
////////////////////////////////////////////////////////////////////////
if (!window.addEventListener) {
Element = function() {};
global.Element = function() {};
(function(WindowPrototype, DocumentPrototype, ElementPrototype, registry) {
if (!DocumentPrototype.head) {
@ -111,7 +111,7 @@ if (!window.addEventListener) {
element[key] = ElementPrototype[key];
return element;
}
})(window, document, Element.prototype, []);
})(window, document, global.Element.prototype, []);
}
////////////////////////////////////////////////////////////////////////