summaryrefslogtreecommitdiff
path: root/content/handlers/javascript/duktape/generics.js
diff options
context:
space:
mode:
Diffstat (limited to 'content/handlers/javascript/duktape/generics.js')
-rw-r--r--content/handlers/javascript/duktape/generics.js129
1 files changed, 129 insertions, 0 deletions
diff --git a/content/handlers/javascript/duktape/generics.js b/content/handlers/javascript/duktape/generics.js
new file mode 100644
index 000000000..e6e952a46
--- /dev/null
+++ b/content/handlers/javascript/duktape/generics.js
@@ -0,0 +1,129 @@
+/*
+ * Generics for Duktape binding in NetSurf
+ *
+ * The result of this *MUST* be setting a NetSurf object only.
+ *
+ * That object will then be absorbed into the global object as a hidden
+ * object which is used by the rest of the bindings.
+ */
+
+var NetSurf = {
+ /* The make-proxy call for list-type objects */
+ makeListProxy: function(inner) {
+ return new Proxy(inner, {
+ has: function(target, key) {
+ if (typeof key == 'number') {
+ return (key >= 0) && (key < target.length);
+ } else {
+ return key in target;
+ }
+ },
+ get: function(target, key) {
+ if (typeof key == 'number') {
+ return target.item(key);
+ } else {
+ return target[key];
+ }
+ },
+ });
+ },
+ /* The make-proxy call for nodemap-type objects */
+ makeNodeMapProxy: function(inner) {
+ return new Proxy(inner, {
+ has: function(target, key) {
+ if (typeof key == 'number') {
+ return (key >= 0) && (key < target.length);
+ } else {
+ return target.getNamedItem(key) || (key in target);
+ }
+ },
+ get: function(target, key) {
+ if (typeof key == 'number') {
+ return target.item(key);
+ } else {
+ var attr = target.getNamedItem(key);
+ if (attr) {
+ return attr;
+ }
+ return target[key];
+ }
+ },
+ });
+ },
+ consoleFormatter: function Formatter() {
+
+ if (arguments.length == 0) {
+ return new Array("");
+ } else if (arguments.length == 1) {
+ return new Array(arguments[0].toString());
+ }
+
+ const target = arguments[0];
+ const current = arguments[1];
+
+ if (typeof target !== "string") {
+ return Array.from(arguments);
+ }
+
+ const offset = target.search("%");
+
+ if (offset == -1 || offset >= (target.length - 1)) {
+ // We've a string, but the % either doesn't exist or is
+ // at the end of it, so give up
+ return Array.from(arguments);
+ }
+
+ const specifier = target[offset + 1];
+
+ var converted = undefined;
+
+ if (specifier === 's') {
+ // Stringification
+ converted = current.toString();
+ } else if (specifier === 'd' || specifier === 'i') {
+ converted = parseInt(current, 10).toString();
+ } else if (specifier === 'f') {
+ converted = parseFloat(current).toString();
+ } else if (specifier === 'o') {
+ // TODO: Objectification?
+ converted = current.toString();
+ } else if (specifier === 'O') {
+ // TODO: JSONification
+ converted = current.toString();
+ }
+
+ var result = new Array();
+
+ if (converted !== undefined) {
+ // We converted it, so we need to absorb the formatted thing
+ // and move on
+ var newtarget = "";
+ if (offset > 0) {
+ newtarget = target.substring(0, offset);
+ }
+ newtarget = newtarget + converted;
+ if (offset < target.length - 2) {
+ newtarget = newtarget + target.substring(offset + 2, target.length);
+ }
+ result.push(newtarget);
+ } else {
+ // Undefined, so we drop this argument and move on
+ result.push(target);
+ }
+
+ var i;
+ for (i = 2; i < arguments.length; i++) {
+ result.push(arguments[i]);
+ }
+
+ if (result[0].search("%") == -1) {
+ return result;
+ }
+
+ if (result.length === 1) {
+ return result;
+ }
+
+ return Formatter.apply(result);
+ }
+};