summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Coppeard <jcoppeard@mozilla.com>2020-08-27 09:14:33 +0000
committerMoonchild <moonchild@palemoon.org>2020-08-27 09:14:33 +0000
commit22f300f7c431bbf4de20437d2ebd7bff38284efb (patch)
treeaf0678b528562e6ff4875e41d8bf07deadde44ec
parent8924e4ddd3d0b463ed3694fb788df9928d4e7dd5 (diff)
downloadUXP-22f300f7c431bbf4de20437d2ebd7bff38284efb.tar
UXP-22f300f7c431bbf4de20437d2ebd7bff38284efb.tar.gz
UXP-22f300f7c431bbf4de20437d2ebd7bff38284efb.tar.lz
UXP-22f300f7c431bbf4de20437d2ebd7bff38284efb.tar.xz
UXP-22f300f7c431bbf4de20437d2ebd7bff38284efb.zip
Issue #618 - Add JS API to associate scripts with DOM elements after compilation
Ref BZ 1342416
-rw-r--r--js/src/jsapi.cpp11
-rw-r--r--js/src/jsapi.h9
-rw-r--r--js/src/jsscript.cpp35
-rw-r--r--js/src/jsscript.h2
4 files changed, 45 insertions, 12 deletions
diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp
index 69a3ba2ac..dd1b25486 100644
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -4432,6 +4432,17 @@ JS::CompileFunction(JSContext* cx, AutoObjectVector& envChain,
chars.get(), length, fun);
}
+JS_PUBLIC_API(bool)
+JS::InitScriptSourceElement(JSContext* cx, HandleScript script,
+ HandleObject element, HandleString elementAttrName)
+{
+ MOZ_ASSERT(cx);
+ MOZ_ASSERT(CurrentThreadCanAccessRuntime(cx->runtime()));
+
+ RootedScriptSource sso(cx, &script->sourceObject()->as<ScriptSourceObject>());
+ return ScriptSourceObject::initElementProperties(cx, sso, element, elementAttrName);
+}
+
JS_PUBLIC_API(JSString*)
JS_DecompileScript(JSContext* cx, HandleScript script, const char* name, unsigned indent)
{
diff --git a/js/src/jsapi.h b/js/src/jsapi.h
index 5cdfd958e..476bc03b9 100644
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -4212,6 +4212,15 @@ CompileFunction(JSContext* cx, AutoObjectVector& envChain,
const char* name, unsigned nargs, const char* const* argnames,
const char* bytes, size_t length, JS::MutableHandleFunction fun);
+/*
+ * Associate an element wrapper and attribute name with a previously compiled
+ * script, for debugging purposes. Calling this function is optional, but should
+ * be done before script execution if it is required.
+ */
+extern JS_PUBLIC_API(bool)
+InitScriptSourceElement(JSContext* cx, HandleScript script,
+ HandleObject element, HandleString elementAttrName = nullptr);
+
} /* namespace JS */
extern JS_PUBLIC_API(JSString*)
diff --git a/js/src/jsscript.cpp b/js/src/jsscript.cpp
index bdd411d04..ba2e540e4 100644
--- a/js/src/jsscript.cpp
+++ b/js/src/jsscript.cpp
@@ -1407,19 +1407,10 @@ ScriptSourceObject::initFromOptions(JSContext* cx, HandleScriptSource source,
MOZ_ASSERT(source->getReservedSlot(ELEMENT_PROPERTY_SLOT).isMagic(JS_GENERIC_MAGIC));
MOZ_ASSERT(source->getReservedSlot(INTRODUCTION_SCRIPT_SLOT).isMagic(JS_GENERIC_MAGIC));
- RootedValue element(cx, ObjectOrNullValue(options.element()));
- if (!cx->compartment()->wrap(cx, &element))
+ RootedObject element(cx, options.element());
+ RootedString elementAttributeName(cx, options.elementAttributeName());
+ if (!initElementProperties(cx, source, element, elementAttributeName))
return false;
- source->setReservedSlot(ELEMENT_SLOT, element);
-
- RootedValue elementAttributeName(cx);
- if (options.elementAttributeName())
- elementAttributeName = StringValue(options.elementAttributeName());
- else
- elementAttributeName = UndefinedValue();
- if (!cx->compartment()->wrap(cx, &elementAttributeName))
- return false;
- source->setReservedSlot(ELEMENT_PROPERTY_SLOT, elementAttributeName);
// There is no equivalent of cross-compartment wrappers for scripts. If the
// introduction script and ScriptSourceObject are in different compartments,
@@ -1437,6 +1428,26 @@ ScriptSourceObject::initFromOptions(JSContext* cx, HandleScriptSource source,
return true;
}
+bool
+ScriptSourceObject::initElementProperties(JSContext* cx, HandleScriptSource source,
+ HandleObject element, HandleString elementAttrName)
+{
+ RootedValue elementValue(cx, ObjectOrNullValue(element));
+ if (!cx->compartment()->wrap(cx, &elementValue))
+ return false;
+
+ RootedValue nameValue(cx);
+ if (elementAttrName)
+ nameValue = StringValue(elementAttrName);
+ if (!cx->compartment()->wrap(cx, &nameValue))
+ return false;
+
+ source->setReservedSlot(ELEMENT_SLOT, elementValue);
+ source->setReservedSlot(ELEMENT_PROPERTY_SLOT, nameValue);
+
+ return true;
+}
+
/* static */ bool
JSScript::loadSource(JSContext* cx, ScriptSource* ss, bool* worked)
{
diff --git a/js/src/jsscript.h b/js/src/jsscript.h
index c19fbfc71..74803c0f6 100644
--- a/js/src/jsscript.h
+++ b/js/src/jsscript.h
@@ -620,6 +620,8 @@ class ScriptSourceObject : public NativeObject
// are provided by |options|, re-wrapping as necessary.
static bool initFromOptions(JSContext* cx, HandleScriptSource source,
const ReadOnlyCompileOptions& options);
+ static bool initElementProperties(JSContext* cx, HandleScriptSource source,
+ HandleObject element, HandleString elementAttrName);
ScriptSource* source() const {
return static_cast<ScriptSource*>(getReservedSlot(SOURCE_SLOT).toPrivate());