mirror of
https://github.com/gnh1201/welsonjs.git
synced 2025-05-15 22:21:04 +00:00
add support GTK server
This commit is contained in:
parent
cfed419ab5
commit
38ae99300d
157
lib/dompath.js
Normal file
157
lib/dompath.js
Normal 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
112
lib/gtkserver.js
Normal 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;
|
|
@ -1,7 +1,6 @@
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
// HTTPServer API
|
// HTTPServer API
|
||||||
///////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
var HTTPServer = {
|
var HTTPServer = {
|
||||||
_this: this, // Avoid conflicts between HTTPServer and Winsock variables
|
_this: this, // Avoid conflicts between HTTPServer and Winsock variables
|
||||||
|
|
||||||
|
@ -24,24 +23,31 @@ var HTTPServer = {
|
||||||
|
|
||||||
Connections: {},
|
Connections: {},
|
||||||
|
|
||||||
|
CreateWinsockObject: function() {
|
||||||
|
return CreateObject([
|
||||||
|
"MSWinsock.Winsock.1",
|
||||||
|
"MSWinsock.Winsock"
|
||||||
|
], "listener_");
|
||||||
|
},
|
||||||
|
|
||||||
Bind: function(port) {
|
Bind: function(port) {
|
||||||
try {
|
try {
|
||||||
_this.Listener = CreateObject(["MSWinsock.Winsock.1", "MSWinsock.Winsock"], "listener_");
|
_this.Listener = _this.CreateWinsockObject();
|
||||||
_this.Listener.localPort = port;
|
_this.Listener.localPort = port;
|
||||||
_this.Listener.bind();
|
_this.Listener.bind();
|
||||||
_this.Listener.listen();
|
_this.Listener.listen();
|
||||||
console.info("Listening port: " + port);
|
console.info("Listening port: " + port);
|
||||||
} catch(e) {
|
} catch (e) {
|
||||||
console.error("port " + port " could not bind: " + e.message);
|
console.error("port " + port " could not bind: " + e.message);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
OnRequest : function(request, response) {
|
OnRequest: function(request, response) {
|
||||||
console.log("HTTPServer.OnRequest() dose not implemented");
|
console.log("HTTPServer.OnRequest() dose not implemented");
|
||||||
},
|
},
|
||||||
|
|
||||||
CreateServer: function(OnRequest) {
|
CreateServer: function(OnRequest) {
|
||||||
if(typeof OnRequest !== "function") {
|
if (typeof OnRequest !== "function") {
|
||||||
throw new TypeError("OnRequest() must be a function.");
|
throw new TypeError("OnRequest() must be a function.");
|
||||||
}
|
}
|
||||||
_this.OnRequest = OnRequest;
|
_this.OnRequest = OnRequest;
|
||||||
|
@ -53,7 +59,7 @@ var HTTPServer = {
|
||||||
console.info("Connection request " + requestID);
|
console.info("Connection request " + requestID);
|
||||||
|
|
||||||
_this.Connections[requestID] = {
|
_this.Connections[requestID] = {
|
||||||
Listener: CreateObject(["MSWinsock.Winsock.1", "MSWinsock.Winsock"], "listener_");
|
Listener: _this.CreateWinsockObject()
|
||||||
};
|
};
|
||||||
_this.Connections[requestID].Listener.accept(requestID);
|
_this.Connections[requestID].Listener.accept(requestID);
|
||||||
},
|
},
|
||||||
|
|
|
@ -10,7 +10,7 @@ exports.require = global.require;
|
||||||
// only less than IE 9
|
// only less than IE 9
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
if (!window.addEventListener) {
|
if (!window.addEventListener) {
|
||||||
Element = function() {};
|
global.Element = function() {};
|
||||||
|
|
||||||
(function(WindowPrototype, DocumentPrototype, ElementPrototype, registry) {
|
(function(WindowPrototype, DocumentPrototype, ElementPrototype, registry) {
|
||||||
if (!DocumentPrototype.head) {
|
if (!DocumentPrototype.head) {
|
||||||
|
@ -111,7 +111,7 @@ if (!window.addEventListener) {
|
||||||
element[key] = ElementPrototype[key];
|
element[key] = ElementPrototype[key];
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
})(window, document, Element.prototype, []);
|
})(window, document, global.Element.prototype, []);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
Loading…
Reference in New Issue
Block a user