diff --git a/docs/API-Reference.md b/docs/API-Reference.md index be7625a0f..fcf5c8c58 100644 --- a/docs/API-Reference.md +++ b/docs/API-Reference.md @@ -745,14 +745,13 @@ scload() will return the result of the last statement evaluated in the file. ### scsave() function -The scsave() function saves an in-memory javascript object to a -specified file. Under the hood, scsave() uses JSON (specifically -json2.js) to save the object. There will usually be no need to call -this function directly - If you want to have a javascript object -automatically loaded at startup and saved on shutdown then use the -`persist()` module. The `persist()` module uses scsave and scload -under the hood. Any in-memory object saved using the `scsave()` -function can later be restored using the `scload()` function. +The scsave() function saves an in-memory javascript object to a specified file. +Under the hood, scsave() uses JSON to save the object. There will usually be no +need to call this function directly - If you want to have a javascript object +automatically loaded at startup and saved on shutdown then use the `persist()` +module. The `persist()` module uses scsave and scload under the hood. Any +in-memory object saved using the `scsave()` function can later be restored +using the `scload()` function. #### Parameters @@ -985,8 +984,8 @@ others. ### Important Although ScriptCraft now supports Node.js style modules, it does not -support node modules. Node.js and Rhino are two very different -Javascript environments. ScriptCraft uses Rhino Javascript, not +support node modules. Node.js and Nashorn are two very different +Javascript environments. ScriptCraft uses Nashorn Javascript, not Node.js. Standard Node.js modules such as `'fs'` are not available in ScriptCraft. Modules can be loaded using relative or absolute paths. Per the CommonJS diff --git a/src/main/java/bukkit/org/scriptcraftjs/bukkit/ScriptCraftPlugin.java b/src/main/java/bukkit/org/scriptcraftjs/bukkit/ScriptCraftPlugin.java index 510e7b622..c9c5fa4f1 100644 --- a/src/main/java/bukkit/org/scriptcraftjs/bukkit/ScriptCraftPlugin.java +++ b/src/main/java/bukkit/org/scriptcraftjs/bukkit/ScriptCraftPlugin.java @@ -2,7 +2,6 @@ import org.bukkit.command.Command; import org.bukkit.command.CommandSender; -import org.bukkit.event.Listener; import org.bukkit.plugin.java.JavaPlugin; import javax.script.Invocable; @@ -12,7 +11,7 @@ import java.util.ArrayList; import java.util.List; -public class ScriptCraftPlugin extends JavaPlugin implements Listener +public class ScriptCraftPlugin extends JavaPlugin { public boolean canary = false; public boolean bukkit = true; diff --git a/src/main/js/lib/events-bukkit.js b/src/main/js/lib/events-bukkit.js index 398392415..c85af9c6c 100644 --- a/src/main/js/lib/events-bukkit.js +++ b/src/main/js/lib/events-bukkit.js @@ -1,25 +1,13 @@ /*global Java, exports, org, __plugin */ var bkEventPriority = org.bukkit.event.EventPriority, - bkEventExecutor = org.bukkit.plugin.EventExecutor, - bkRegisteredListener = org.bukkit.plugin.RegisteredListener; + bkHandlerList = org.bukkit.event.HandlerList, + bkPluginManager = org.bukkit.Bukkit.pluginManager; -var nashorn = typeof Java != 'undefined'; +// Ask Nashorn to generate a class implementing the Listener +// interface, so that we may instantiate it to tag our event +// handlers. +var ScriptCraftListener = Java.extend(org.bukkit.event.Listener, {}); -function getHandlerListForEventType(eventType) { - var result = null; - var clazz = null; - if (nashorn) { - //Nashorn doesn't like when getHandlerList is in a superclass of your event - //so to avoid this problem, call getHandlerList using java.lang.reflect - //methods - clazz = eventType['class']; - result = clazz.getMethod('getHandlerList').invoke(null); - } else { - result = eventType.getHandlerList(); - } - - return result; -} exports.on = function( /* Java Class */ eventType, @@ -29,53 +17,45 @@ exports.on = function( /* (optional) String (HIGH, HIGHEST, LOW, LOWEST, NORMAL, MONITOR), */ priority ) { - var handlerList, regd, eventExecutor; - if (typeof priority == 'undefined') { priority = bkEventPriority.HIGHEST; } else { priority = bkEventPriority[priority.toUpperCase().trim()]; } - handlerList = getHandlerListForEventType(eventType); var result = {}; - eventExecutor = new bkEventExecutor({ - execute: function(l, evt) { - function cancel() { - if (evt instanceof org.bukkit.event.Cancellable) { - evt.setCancelled(true); - } - } - /* - let handlers use this.cancel() to cancel the current event - or this.unregister() to unregister from future events. - */ - var bound = {}; - for (var i in result) { - bound[i] = result[i]; + var eventExecutor = function(l, evt) { + function cancel() { + if (evt instanceof org.bukkit.event.Cancellable) { + evt.setCancelled(true); } - bound.cancel = cancel; - handler.call(bound, evt, cancel); } - }); - /* - wph 20130222 issue #64 bad interaction with Essentials plugin - if another plugin tries to unregister a Listener (not a Plugin or a RegisteredListener) - then BOOM! the other plugin will throw an error because Rhino can't coerce an - equals() method from an Interface. - The workaround is to make the ScriptCraftPlugin java class a Listener. - Should only unregister() registered plugins in ScriptCraft js code. - */ - regd = new bkRegisteredListener( - __plugin, - eventExecutor, + /* + let handlers use this.cancel() to cancel the current event + or this.unregister() to unregister from future events. + */ + var bound = {}; + for (var i in result) { + bound[i] = result[i]; + } + bound.cancel = cancel; + handler.call(bound, evt, cancel); + }; + + // Create an instance of our empty Listener implementation to track the handler + var listener = new ScriptCraftListener(); + + bkPluginManager.registerEvent( + eventType.class, + listener, priority, - __plugin, - false + eventExecutor, + __plugin ); - handlerList.register(regd); + result.unregister = function() { - handlerList.unregister(regd); + bkHandlerList.unregisterAll(listener); }; + return result; }; diff --git a/src/main/js/lib/events-canary.js b/src/main/js/lib/events-canary.js index b2341bd47..723844ec5 100644 --- a/src/main/js/lib/events-canary.js +++ b/src/main/js/lib/events-canary.js @@ -1,4 +1,4 @@ -/*global nashorn, exports, require, Packages, __plugin*/ +/*global exports, require, Packages, __plugin*/ var cmPriority = Packages.net.canarymod.plugin.Priority, cmCanary = Packages.net.canarymod.Canary, cmPluginListener = Packages.net.canarymod.plugin.PluginListener; @@ -58,10 +58,7 @@ exports.on = function( The workaround is to make the ScriptCraftPlugin java class a Listener. Should only unregister() registered plugins in ScriptCraft js code. */ - if (nashorn) { - // nashorn - eventType = require('nashorn-type')(eventType); - } + eventType = eventType.class; regd = new cmPluginListener({}); cmHookExecutor.registerHook( regd, diff --git a/src/main/js/lib/json2.js b/src/main/js/lib/json2.js deleted file mode 100644 index c8d7073e3..000000000 --- a/src/main/js/lib/json2.js +++ /dev/null @@ -1,489 +0,0 @@ -/* - json2.js - 2013-05-26 - - Public Domain. - - NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. - - See http://www.JSON.org/js.html - - - This code should be minified before deployment. - See http://javascript.crockford.com/jsmin.html - - USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO - NOT CONTROL. - - - This file creates a global JSON object containing two methods: stringify - and parse. - - JSON.stringify(value, replacer, space) - value any JavaScript value, usually an object or array. - - replacer an optional parameter that determines how object - values are stringified for objects. It can be a - function or an array of strings. - - space an optional parameter that specifies the indentation - of nested structures. If it is omitted, the text will - be packed without extra whitespace. If it is a number, - it will specify the number of spaces to indent at each - level. If it is a string (such as '\t' or ' '), - it contains the characters used to indent at each level. - - This method produces a JSON text from a JavaScript value. - - When an object value is found, if the object contains a toJSON - method, its toJSON method will be called and the result will be - stringified. A toJSON method does not serialize: it returns the - value represented by the name/value pair that should be serialized, - or undefined if nothing should be serialized. The toJSON method - will be passed the key associated with the value, and this will be - bound to the value - - For example, this would serialize Dates as ISO strings. - - Date.prototype.toJSON = function (key) { - function f(n) { - // Format integers to have at least two digits. - return n < 10 ? '0' + n : n; - } - - return this.getUTCFullYear() + '-' + - f(this.getUTCMonth() + 1) + '-' + - f(this.getUTCDate()) + 'T' + - f(this.getUTCHours()) + ':' + - f(this.getUTCMinutes()) + ':' + - f(this.getUTCSeconds()) + 'Z'; - }; - - You can provide an optional replacer method. It will be passed the - key and value of each member, with this bound to the containing - object. The value that is returned from your method will be - serialized. If your method returns undefined, then the member will - be excluded from the serialization. - - If the replacer parameter is an array of strings, then it will be - used to select the members to be serialized. It filters the results - such that only members with keys listed in the replacer array are - stringified. - - Values that do not have JSON representations, such as undefined or - functions, will not be serialized. Such values in objects will be - dropped; in arrays they will be replaced with null. You can use - a replacer function to replace those with JSON values. - JSON.stringify(undefined) returns undefined. - - The optional space parameter produces a stringification of the - value that is filled with line breaks and indentation to make it - easier to read. - - If the space parameter is a non-empty string, then that string will - be used for indentation. If the space parameter is a number, then - the indentation will be that many spaces. - - Example: - - text = JSON.stringify(['e', {pluribus: 'unum'}]); - // text is '["e",{"pluribus":"unum"}]' - - - text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t'); - // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]' - - text = JSON.stringify([new Date()], function (key, value) { - return this[key] instanceof Date ? - 'Date(' + this[key] + ')' : value; - }); - // text is '["Date(---current time---)"]' - - - JSON.parse(text, reviver) - This method parses a JSON text to produce an object or array. - It can throw a SyntaxError exception. - - The optional reviver parameter is a function that can filter and - transform the results. It receives each of the keys and values, - and its return value is used instead of the original value. - If it returns what it received, then the structure is not modified. - If it returns undefined then the member is deleted. - - Example: - - // Parse the text. Values that look like ISO date strings will - // be converted to Date objects. - - myData = JSON.parse(text, function (key, value) { - var a; - if (typeof value === 'string') { - a = -/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value); - if (a) { - return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], - +a[5], +a[6])); - } - } - return value; - }); - - myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) { - var d; - if (typeof value === 'string' && - value.slice(0, 5) === 'Date(' && - value.slice(-1) === ')') { - d = new Date(value.slice(5, -1)); - if (d) { - return d; - } - } - return value; - }); - - - This is a reference implementation. You are free to copy, modify, or - redistribute. -*/ - -/*jslint evil: true, regexp: true */ - -/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply, - call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours, - getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join, - lastIndex, length, parse, prototype, push, replace, slice, stringify, - test, toJSON, toString, valueOf -*/ - -// Create a JSON object only if one does not already exist. We create the -// methods in a closure to avoid creating global variables. - -if (typeof JSON !== 'object') { - JSON = {}; -} - -(function() { - 'use strict'; - - function f(n) { - // Format integers to have at least two digits. - return n < 10 ? '0' + n : n; - } - - if (typeof Date.prototype.toJSON !== 'function') { - Date.prototype.toJSON = function() { - return isFinite(this.valueOf()) - ? this.getUTCFullYear() + - '-' + - f(this.getUTCMonth() + 1) + - '-' + - f(this.getUTCDate()) + - 'T' + - f(this.getUTCHours()) + - ':' + - f(this.getUTCMinutes()) + - ':' + - f(this.getUTCSeconds()) + - 'Z' - : null; - }; - - String.prototype.toJSON = Number.prototype.toJSON = Boolean.prototype.toJSON = function() { - return this.valueOf(); - }; - } - - var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, - escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, - gap, - indent, - meta = { - // table of character substitutions - '\b': '\\b', - '\t': '\\t', - '\n': '\\n', - '\f': '\\f', - '\r': '\\r', - '"': '\\"', - '\\': '\\\\' - }, - rep; - - function quote(string) { - // If the string contains no control characters, no quote characters, and no - // backslash characters, then we can safely slap some quotes around it. - // Otherwise we must also replace the offending characters with safe escape - // sequences. - - escapable.lastIndex = 0; - return escapable.test(string) - ? '"' + - string.replace(escapable, function(a) { - var c = meta[a]; - return typeof c === 'string' - ? c - : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); - }) + - '"' - : '"' + string + '"'; - } - - function str(key, holder) { - // Produce a string from holder[key]. - - var i, // The loop counter. - k, // The member key. - v, // The member value. - length, - mind = gap, - partial, - value = holder[key]; - - // If the value has a toJSON method, call it to obtain a replacement value. - - if ( - value && - typeof value === 'object' && - typeof value.toJSON === 'function' - ) { - value = value.toJSON(key); - } - - // If we were called with a replacer function, then call the replacer to - // obtain a replacement value. - - if (typeof rep === 'function') { - value = rep.call(holder, key, value); - } - - // What happens next depends on the value's type. - - switch (typeof value) { - case 'string': - return quote(value); - - case 'number': - // JSON numbers must be finite. Encode non-finite numbers as null. - - return isFinite(value) ? String(value) : 'null'; - - case 'boolean': - case 'null': - // If the value is a boolean or null, convert it to a string. Note: - // typeof null does not produce 'null'. The case is included here in - // the remote chance that this gets fixed someday. - - return String(value); - - // If the type is 'object', we might be dealing with an object or an array or - // null. - - case 'object': - // Due to a specification blunder in ECMAScript, typeof null is 'object', - // so watch out for that case. - - if (!value) { - return 'null'; - } - - // Make an array to hold the partial results of stringifying this object value. - - gap += indent; - partial = []; - - // Is the value an array? - - if (Object.prototype.toString.apply(value) === '[object Array]') { - // The value is an array. Stringify every element. Use null as a placeholder - // for non-JSON values. - - length = value.length; - for (i = 0; i < length; i += 1) { - partial[i] = str(i, value) || 'null'; - } - - // Join all of the elements together, separated with commas, and wrap them in - // brackets. - - v = - partial.length === 0 - ? '[]' - : gap - ? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' - : '[' + partial.join(',') + ']'; - gap = mind; - return v; - } - - // If the replacer is an array, use it to select the members to be stringified. - - if (rep && typeof rep === 'object') { - length = rep.length; - for (i = 0; i < length; i += 1) { - if (typeof rep[i] === 'string') { - k = rep[i]; - v = str(k, value); - if (v) { - partial.push(quote(k) + (gap ? ': ' : ':') + v); - } - } - } - } else { - // Otherwise, iterate through all of the keys in the object. - - for (k in value) { - if (Object.prototype.hasOwnProperty.call(value, k)) { - v = str(k, value); - if (v) { - partial.push(quote(k) + (gap ? ': ' : ':') + v); - } - } - } - } - - // Join all of the member texts together, separated with commas, - // and wrap them in braces. - - v = - partial.length === 0 - ? '{}' - : gap - ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' - : '{' + partial.join(',') + '}'; - gap = mind; - return v; - } - } - - // If the JSON object does not yet have a stringify method, give it one. - - if (typeof JSON.stringify !== 'function') { - JSON.stringify = function(value, replacer, space) { - // The stringify method takes a value and an optional replacer, and an optional - // space parameter, and returns a JSON text. The replacer can be a function - // that can replace values, or an array of strings that will select the keys. - // A default replacer method can be provided. Use of the space parameter can - // produce text that is more easily readable. - - var i; - gap = ''; - indent = ''; - - // If the space parameter is a number, make an indent string containing that - // many spaces. - - if (typeof space === 'number') { - for (i = 0; i < space; i += 1) { - indent += ' '; - } - - // If the space parameter is a string, it will be used as the indent string. - } else if (typeof space === 'string') { - indent = space; - } - - // If there is a replacer, it must be a function or an array. - // Otherwise, throw an error. - - rep = replacer; - if ( - replacer && - typeof replacer !== 'function' && - (typeof replacer !== 'object' || typeof replacer.length !== 'number') - ) { - throw new Error('JSON.stringify'); - } - - // Make a fake root object containing our value under the key of ''. - // Return the result of stringifying the value. - - return str('', { '': value }); - }; - } - - // If the JSON object does not yet have a parse method, give it one. - - if (typeof JSON.parse !== 'function') { - JSON.parse = function(text, reviver) { - // The parse method takes a text and an optional reviver function, and returns - // a JavaScript value if the text is a valid JSON text. - - var j; - - function walk(holder, key) { - // The walk method is used to recursively walk the resulting structure so - // that modifications can be made. - - var k, - v, - value = holder[key]; - if (value && typeof value === 'object') { - for (k in value) { - if (Object.prototype.hasOwnProperty.call(value, k)) { - v = walk(value, k); - if (v !== undefined) { - value[k] = v; - } else { - delete value[k]; - } - } - } - } - return reviver.call(holder, key, value); - } - - // Parsing happens in four stages. In the first stage, we replace certain - // Unicode characters with escape sequences. JavaScript handles many characters - // incorrectly, either silently deleting them, or treating them as line endings. - - text = String(text); - cx.lastIndex = 0; - if (cx.test(text)) { - text = text.replace(cx, function(a) { - return '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); - }); - } - - // In the second stage, we run the text against regular expressions that look - // for non-JSON patterns. We are especially concerned with '()' and 'new' - // because they can cause invocation, and '=' because it can cause mutation. - // But just to be safe, we want to reject all unexpected forms. - - // We split the second stage into 4 regexp operations in order to work around - // crippling inefficiencies in IE's and Safari's regexp engines. First we - // replace the JSON backslash pairs with '@' (a non-JSON character). Second, we - // replace all simple value tokens with ']' characters. Third, we delete all - // open brackets that follow a colon or comma or that begin the text. Finally, - // we look to see that the remaining characters are only whitespace or ']' or - // ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval. - - if ( - /^[\],:{}\s]*$/.test( - text - .replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@') - .replace( - /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, - ']' - ) - .replace(/(?:^|:|,)(?:\s*\[)+/g, '') - ) - ) { - // In the third stage we use the eval function to compile the text into a - // JavaScript structure. The '{' operator is subject to a syntactic ambiguity - // in JavaScript: it can begin a block or an object literal. We wrap the text - // in parens to eliminate the ambiguity. - - j = eval('(' + text + ')'); - - // In the optional fourth stage, we recursively walk the new structure, passing - // each name/value pair to a reviver function for possible transformation. - - return typeof reviver === 'function' ? walk({ '': j }, '') : j; - } - - // If the text is not JSON parseable, then a SyntaxError is thrown. - - throw new SyntaxError('JSON.parse'); - }; - } -})(); diff --git a/src/main/js/lib/nashorn-type.js b/src/main/js/lib/nashorn-type.js deleted file mode 100644 index 78a7087a1..000000000 --- a/src/main/js/lib/nashorn-type.js +++ /dev/null @@ -1,8 +0,0 @@ -/* - The .class operator causes problems for non-nashorn Java on Mac OS X and some other - environments. So need to have it in a separate module which should only be loaded in - nashorn environment. -*/ -module.exports = function(t) { - return t.class; -}; diff --git a/src/main/js/lib/require.js b/src/main/js/lib/require.js index 4e301deb0..3ed6a02f7 100644 --- a/src/main/js/lib/require.js +++ b/src/main/js/lib/require.js @@ -50,8 +50,8 @@ others. ### Important Although ScriptCraft now supports Node.js style modules, it does not -support node modules. Node.js and Rhino are two very different -Javascript environments. ScriptCraft uses Rhino Javascript, not +support node modules. Node.js and Nashorn are two very different +Javascript environments. ScriptCraft uses Nashorn Javascript, not Node.js. Standard Node.js modules such as `'fs'` are not available in ScriptCraft. Modules can be loaded using relative or absolute paths. Per the CommonJS diff --git a/src/main/js/lib/scriptcraft.js b/src/main/js/lib/scriptcraft.js index 139818036..4e34a1d9a 100644 --- a/src/main/js/lib/scriptcraft.js +++ b/src/main/js/lib/scriptcraft.js @@ -234,14 +234,13 @@ scload() will return the result of the last statement evaluated in the file. ### scsave() function -The scsave() function saves an in-memory javascript object to a -specified file. Under the hood, scsave() uses JSON (specifically -json2.js) to save the object. There will usually be no need to call -this function directly - If you want to have a javascript object -automatically loaded at startup and saved on shutdown then use the -`persist()` module. The `persist()` module uses scsave and scload -under the hood. Any in-memory object saved using the `scsave()` -function can later be restored using the `scload()` function. +The scsave() function saves an in-memory javascript object to a specified file. +Under the hood, scsave() uses JSON to save the object. There will usually be no +need to call this function directly - If you want to have a javascript object +automatically loaded at startup and saved on shutdown then use the `persist()` +module. The `persist()` module uses scsave and scload under the hood. Any +in-memory object saved using the `scsave()` function can later be restored +using the `scload()` function. #### Parameters @@ -539,7 +538,6 @@ function __onEnable(__engine, __plugin, __script) { } wrappedCode = '(' + code + ')'; result = __engine.eval(wrappedCode); - // issue #103 avoid side-effects of || operator on Mac Rhino } catch (e) { logError('Error evaluating ' + canonizedFilename + ', ' + e); } finally { @@ -577,9 +575,7 @@ function __onEnable(__engine, __plugin, __script) { Canary.manager().enablePlugin(pluginName); } else { __plugin.pluginLoader.disablePlugin(__plugin); - org.bukkit.event.HandlerList['unregisterAll(org.bukkit.plugin.Plugin)']( - __plugin - ); + org.bukkit.event.HandlerList.unregisterAll(__plugin); server.scheduler.cancelTasks(__plugin); __plugin.pluginLoader.enablePlugin(__plugin); } @@ -698,13 +694,8 @@ function __onEnable(__engine, __plugin, __script) { ); throw e; } finally { - /* - wph 20140312 don't delete self on nashorn until https://bugs.openjdk.java.net/browse/JDK-8034055 is fixed - */ - if (!nashorn) { - delete global.self; - delete global.__engine; - } + delete global.self; + delete global.__engine; } } if (cmdName == 'jsp') { @@ -764,15 +755,6 @@ function __onEnable(__engine, __plugin, __script) { } global.config = config; global.__plugin = __plugin; - /* - wph 20131229 Issue #103 JSON is not bundled with javax.scripting / Rhino on Mac. - */ - (function() { - var jsonFileReader = new FileReader( - new File(jsPluginsRootDirName + '/lib/json2.js') - ); - __engine['eval(java.io.Reader)'](jsonFileReader); - })(); global.addUnloadHandler = _addUnloadHandler; global.refresh = _refresh; diff --git a/src/main/js/lib/tabcomplete.js b/src/main/js/lib/tabcomplete.js index 66442ed08..3c653be1a 100644 --- a/src/main/js/lib/tabcomplete.js +++ b/src/main/js/lib/tabcomplete.js @@ -183,11 +183,7 @@ var onTabCompleteJS = function() { symbol = null; break; } - if (typeof symbol == 'undefined') { - break; - } - // nashorn - object[missingProperty] returns null not undefined - if (symbol == null) { + if (typeof symbol == 'undefined' || symbol === null) { break; } lastGoodSymbol = symbol; diff --git a/src/main/js/modules/canary/items.js b/src/main/js/modules/canary/items.js index 8eaa67935..5a9345fd4 100644 --- a/src/main/js/modules/canary/items.js +++ b/src/main/js/modules/canary/items.js @@ -1,4 +1,4 @@ -/*global nashorn, require, Packages, module*/ +/*global require, Packages, module*/ var ItemType = Packages.net.canarymod.api.inventory.ItemType; var Canary = Packages.net.canarymod.Canary; var itemFactory = Canary.factory().itemFactory; @@ -34,39 +34,21 @@ function getMaterialHandler(material) { } }; } -if (nashorn) { - /* - nashorn - */ - var itemTypeClass = require('nashorn-type')(ItemType); - var materials = itemTypeClass.getDeclaredFields(); - var name; - for (var i = 0; i < materials.length; i++) { - if (materials[i].type != itemTypeClass) { - continue; - } - var materialField = materials[i]; - name = '' + materialField.name; - name = name.replace(/^(.)/, function(a) { - return a.toLowerCase(); - }); - items[name] = getMaterialHandler(materialField.get(ItemType)); - } -} else { - // non-nashorn - for (var field in ItemType) { - if (ItemType[field] === undefined) { - continue; - } - if (!(ItemType[field] instanceof ItemType)) { - continue; - } - name = ('' + field).replace(/^(.)/, function(a) { - return a.toLowerCase(); - }); - items[name] = getMaterialHandler(ItemType[field]); +var itemTypeClass = ItemType.class; +var materials = itemTypeClass.getDeclaredFields(); +var name; +for (var i = 0; i < materials.length; i++) { + if (materials[i].type != itemTypeClass) { + continue; } + var materialField = materials[i]; + name = '' + materialField.name; + name = name.replace(/^(.)/, function(a) { + return a.toLowerCase(); + }); + + items[name] = getMaterialHandler(materialField.get(ItemType)); } module.exports = items; diff --git a/src/main/js/plugins/alias/alias.js b/src/main/js/plugins/alias/alias.js index e59c0b1ae..753edd2cc 100644 --- a/src/main/js/plugins/alias/alias.js +++ b/src/main/js/plugins/alias/alias.js @@ -172,19 +172,12 @@ command('alias', function(params, invoker) { echo(invoker, 'Usage:\n' + _usage); return; } - /* - wph 20140122 this is kind of dumb but Nashorn has some serious problems - accessing object properties by array index notation - in JRE8 alias[operation] returns null - definitely a bug in Nashorn. - */ - for (var key in alias) { - if (key == operation) { - fn = alias[key]; - fn(params.slice(1), invoker); - return; - } + + if (alias[operation]) { + alias[operation](params.slice(1), invoker); + } else { + echo(invoker, 'Usage:\n' + _usage); } - echo(invoker, 'Usage:\n' + _usage); }); var _intercept = function(msg, invoker, exec) {