зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1631581 - Part 2: Rename NamedConstructor to LegacyFactoryFunction r=edgar
Differential Revision: https://phabricator.services.mozilla.com/D111210
This commit is contained in:
Родитель
6eb4c94b83
Коммит
76d2e42ae7
|
@ -802,7 +802,7 @@ static bool DefineConstructor(JSContext* cx, JS::Handle<JSObject*> global,
|
|||
static JSObject* CreateInterfaceObject(
|
||||
JSContext* cx, JS::Handle<JSObject*> global,
|
||||
JS::Handle<JSObject*> constructorProto, const JSClass* constructorClass,
|
||||
unsigned ctorNargs, const NamedConstructor* namedConstructors,
|
||||
unsigned ctorNargs, const LegacyFactoryFunction* namedConstructors,
|
||||
JS::Handle<JSObject*> proto, const NativeProperties* properties,
|
||||
const NativeProperties* chromeOnlyProperties, const char* name,
|
||||
bool isChrome, bool defineOnGlobal, const char* const* legacyWindowAliases,
|
||||
|
@ -1020,7 +1020,7 @@ void CreateInterfaceObjects(
|
|||
JS::Handle<JSObject*> protoProto, const JSClass* protoClass,
|
||||
JS::Heap<JSObject*>* protoCache, JS::Handle<JSObject*> constructorProto,
|
||||
const JSClass* constructorClass, unsigned ctorNargs,
|
||||
const NamedConstructor* namedConstructors,
|
||||
const LegacyFactoryFunction* namedConstructors,
|
||||
JS::Heap<JSObject*>* constructorCache, const NativeProperties* properties,
|
||||
const NativeProperties* chromeOnlyProperties, const char* name,
|
||||
bool defineOnGlobal, const char* const* unscopableNames, bool isGlobal,
|
||||
|
|
|
@ -666,7 +666,7 @@ struct JSNativeHolder {
|
|||
const NativePropertyHooks* mPropertyHooks;
|
||||
};
|
||||
|
||||
struct NamedConstructor {
|
||||
struct LegacyFactoryFunction {
|
||||
const char* mName;
|
||||
const JSNativeHolder mHolder;
|
||||
unsigned mNargs;
|
||||
|
@ -731,7 +731,7 @@ void CreateInterfaceObjects(
|
|||
JS::Handle<JSObject*> protoProto, const JSClass* protoClass,
|
||||
JS::Heap<JSObject*>* protoCache, JS::Handle<JSObject*> constructorProto,
|
||||
const JSClass* constructorClass, unsigned ctorNargs,
|
||||
const NamedConstructor* namedConstructors,
|
||||
const LegacyFactoryFunction* namedConstructors,
|
||||
JS::Heap<JSObject*>* constructorCache, const NativeProperties* properties,
|
||||
const NativeProperties* chromeOnlyProperties, const char* name,
|
||||
bool defineOnGlobal, const char* const* unscopableNames, bool isGlobal,
|
||||
|
@ -2336,7 +2336,7 @@ inline bool UseDOMXray(JSObject* obj) {
|
|||
|
||||
inline bool IsDOMConstructor(JSObject* obj) {
|
||||
if (JS_IsNativeFunction(obj, dom::Constructor)) {
|
||||
// NamedConstructor, like Image
|
||||
// LegacyFactoryFunction, like Image
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -952,9 +952,9 @@ class CGInterfaceObjectJSClass(CGThing):
|
|||
|
||||
prototypeID, depth = PrototypeIDAndDepth(self.descriptor)
|
||||
slotCount = "DOM_INTERFACE_SLOTS_BASE"
|
||||
if len(self.descriptor.interface.namedConstructors) > 0:
|
||||
slotCount += " + %i /* slots for the named constructors */" % len(
|
||||
self.descriptor.interface.namedConstructors
|
||||
if len(self.descriptor.interface.legacyFactoryFunctions) > 0:
|
||||
slotCount += " + %i /* slots for the legacy factory functions */" % len(
|
||||
self.descriptor.interface.legacyFactoryFunctions
|
||||
)
|
||||
(protoGetter, _) = InterfaceObjectProtoGetter(self.descriptor, forXrays=True)
|
||||
|
||||
|
@ -2308,11 +2308,11 @@ class CGClassConstructor(CGAbstractStaticMethod):
|
|||
)
|
||||
|
||||
|
||||
def NamedConstructorName(m):
|
||||
def LegacyFactoryFunctionName(m):
|
||||
return "_" + m.identifier.name
|
||||
|
||||
|
||||
class CGNamedConstructors(CGThing):
|
||||
class CGLegacyFactoryFunctions(CGThing):
|
||||
def __init__(self, descriptor):
|
||||
self.descriptor = descriptor
|
||||
CGThing.__init__(self)
|
||||
|
@ -2321,7 +2321,7 @@ class CGNamedConstructors(CGThing):
|
|||
return ""
|
||||
|
||||
def define(self):
|
||||
if len(self.descriptor.interface.namedConstructors) == 0:
|
||||
if len(self.descriptor.interface.legacyFactoryFunctions) == 0:
|
||||
return ""
|
||||
|
||||
constructorID = "constructors::id::"
|
||||
|
@ -2331,15 +2331,15 @@ class CGNamedConstructors(CGThing):
|
|||
constructorID += "_ID_Count"
|
||||
|
||||
namedConstructors = ""
|
||||
for n in self.descriptor.interface.namedConstructors:
|
||||
for n in self.descriptor.interface.legacyFactoryFunctions:
|
||||
namedConstructors += (
|
||||
'{ "%s", { %s, &sNamedConstructorNativePropertyHooks }, %i },\n'
|
||||
% (n.identifier.name, NamedConstructorName(n), methodLength(n))
|
||||
'{ "%s", { %s, &sLegacyFactoryFunctionNativePropertyHooks }, %i },\n'
|
||||
% (n.identifier.name, LegacyFactoryFunctionName(n), methodLength(n))
|
||||
)
|
||||
|
||||
return fill(
|
||||
"""
|
||||
const NativePropertyHooks sNamedConstructorNativePropertyHooks = {
|
||||
const NativePropertyHooks sLegacyFactoryFunctionNativePropertyHooks = {
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
|
@ -2349,7 +2349,7 @@ class CGNamedConstructors(CGThing):
|
|||
nullptr
|
||||
};
|
||||
|
||||
static const NamedConstructor namedConstructors[] = {
|
||||
static const LegacyFactoryFunction namedConstructors[] = {
|
||||
$*{namedConstructors}
|
||||
{ nullptr, { nullptr, nullptr }, 0 }
|
||||
};
|
||||
|
@ -3645,7 +3645,7 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
|
|||
constructArgs = methodLength(self.descriptor.interface.ctor())
|
||||
else:
|
||||
constructArgs = 0
|
||||
if len(self.descriptor.interface.namedConstructors) > 0:
|
||||
if len(self.descriptor.interface.legacyFactoryFunctions) > 0:
|
||||
namedConstructors = "namedConstructors"
|
||||
else:
|
||||
namedConstructors = "nullptr"
|
||||
|
@ -3673,8 +3673,8 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
|
|||
getConstructorProto = CGGeneric(getConstructorProto)
|
||||
constructorProto = "constructorProto"
|
||||
else:
|
||||
# We don't have slots to store the named constructors.
|
||||
assert len(self.descriptor.interface.namedConstructors) == 0
|
||||
# We don't have slots to store the legacy factory functions.
|
||||
assert len(self.descriptor.interface.legacyFactoryFunctions) == 0
|
||||
interfaceClass = "nullptr"
|
||||
interfaceCache = "nullptr"
|
||||
getConstructorProto = None
|
||||
|
@ -10511,7 +10511,7 @@ def GetWebExposedName(idlObject, descriptor):
|
|||
def GetConstructorNameForReporting(descriptor, ctor):
|
||||
# Figure out the name of our constructor for reporting purposes.
|
||||
# For unnamed webidl constructors, identifier.name is "constructor" but
|
||||
# the name JS sees is the interface name; for named constructors
|
||||
# the name JS sees is the interface name; for legacy factory functions
|
||||
# identifier.name is the actual name.
|
||||
ctorName = ctor.identifier.name
|
||||
if ctorName == "constructor":
|
||||
|
@ -16139,8 +16139,10 @@ class CGDescriptor(CGThing):
|
|||
defaultToJSONMethod = None
|
||||
needCrossOriginPropertyArrays = False
|
||||
unscopableNames = list()
|
||||
for n in descriptor.interface.namedConstructors:
|
||||
cgThings.append(CGClassConstructor(descriptor, n, NamedConstructorName(n)))
|
||||
for n in descriptor.interface.legacyFactoryFunctions:
|
||||
cgThings.append(
|
||||
CGClassConstructor(descriptor, n, LegacyFactoryFunctionName(n))
|
||||
)
|
||||
for m in descriptor.interface.members:
|
||||
if m.isMethod() and m.identifier.name == "QueryInterface":
|
||||
continue
|
||||
|
@ -16249,7 +16251,7 @@ class CGDescriptor(CGThing):
|
|||
if descriptor.interface.hasInterfaceObject():
|
||||
cgThings.append(CGClassConstructor(descriptor, descriptor.interface.ctor()))
|
||||
cgThings.append(CGInterfaceObjectJSClass(descriptor, properties))
|
||||
cgThings.append(CGNamedConstructors(descriptor))
|
||||
cgThings.append(CGLegacyFactoryFunctions(descriptor))
|
||||
|
||||
cgThings.append(CGLegacyCallHook(descriptor))
|
||||
if descriptor.interface.getExtendedAttribute("NeedResolve"):
|
||||
|
@ -17651,7 +17653,7 @@ def getGlobalNames(config):
|
|||
for desc in config.getDescriptors(registersGlobalNamesOnWindow=True):
|
||||
names.append((desc.name, desc))
|
||||
names.extend(
|
||||
(n.identifier.name, desc) for n in desc.interface.namedConstructors
|
||||
(n.identifier.name, desc) for n in desc.interface.legacyFactoryFunctions
|
||||
)
|
||||
names.extend((n, desc) for n in desc.interface.legacyWindowAliases)
|
||||
return names
|
||||
|
@ -18053,7 +18055,7 @@ class CGBindingRoot(CGThing):
|
|||
# generates only a few false positives.
|
||||
bindingHeaders["mozilla/ProfilerLabels.h"] = any(
|
||||
# constructor profiler label
|
||||
d.interface.namedConstructors
|
||||
d.interface.legacyFactoryFunctions
|
||||
or (d.interface.hasInterfaceObject() and d.interface.ctor())
|
||||
or any(
|
||||
# getter/setter profiler labels
|
||||
|
@ -19073,7 +19075,7 @@ class CGBindingImplClass(CGClass):
|
|||
|
||||
if iface.ctor():
|
||||
appendMethod(iface.ctor(), isConstructor=True)
|
||||
for n in iface.namedConstructors:
|
||||
for n in iface.legacyFactoryFunctions:
|
||||
appendMethod(n, isConstructor=True)
|
||||
for m in iface.members:
|
||||
if m.isMethod():
|
||||
|
|
|
@ -879,7 +879,7 @@ def getTypesFromDescriptor(descriptor, includeArgs=True, includeReturns=True):
|
|||
members = [m for m in descriptor.interface.members]
|
||||
if descriptor.interface.ctor():
|
||||
members.append(descriptor.interface.ctor())
|
||||
members.extend(descriptor.interface.namedConstructors)
|
||||
members.extend(descriptor.interface.legacyFactoryFunctions)
|
||||
signatures = [s for m in members if m.isMethod() for s in m.signatures()]
|
||||
types = []
|
||||
for s in signatures:
|
||||
|
|
|
@ -315,9 +315,9 @@ class IDLScope(IDLObject):
|
|||
)
|
||||
|
||||
# We do the merging of overloads here as opposed to in IDLInterface
|
||||
# because we need to merge overloads of NamedConstructors and we need to
|
||||
# because we need to merge overloads of LegacyFactoryFunctions and we need to
|
||||
# detect conflicts in those across interfaces. See also the comment in
|
||||
# IDLInterface.addExtendedAttributes for "NamedConstructor".
|
||||
# IDLInterface.addExtendedAttributes for "LegacyFactoryFunction".
|
||||
if isinstance(originalObject, IDLMethod) and isinstance(newObject, IDLMethod):
|
||||
return originalObject.addOverload(newObject)
|
||||
|
||||
|
@ -632,7 +632,7 @@ class IDLPartialInterfaceOrNamespace(IDLObject):
|
|||
for attr in attrs:
|
||||
identifier = attr.identifier()
|
||||
|
||||
if identifier == "NamedConstructor":
|
||||
if identifier == "LegacyFactoryFunction":
|
||||
self.propagatedExtendedAttrs.append(attr)
|
||||
elif identifier == "SecureContext":
|
||||
self._haveSecureContextExtendedAttribute = True
|
||||
|
@ -947,7 +947,7 @@ class IDLInterfaceOrNamespace(IDLInterfaceOrInterfaceMixinOrNamespace):
|
|||
# namedConstructors needs deterministic ordering because bindings code
|
||||
# outputs the constructs in the order that namedConstructors enumerates
|
||||
# them.
|
||||
self.namedConstructors = list()
|
||||
self.legacyFactoryFunctions = list()
|
||||
self.legacyWindowAliases = []
|
||||
self.includedMixins = set()
|
||||
# self.interfacesBasedOnSelf is the set of interfaces that inherit from
|
||||
|
@ -1177,10 +1177,10 @@ class IDLInterfaceOrNamespace(IDLInterfaceOrInterfaceMixinOrNamespace):
|
|||
# it doesn't get in the way later.
|
||||
self.members.remove(ctor)
|
||||
|
||||
for ctor in self.namedConstructors:
|
||||
for ctor in self.legacyFactoryFunctions:
|
||||
if self.globalNames:
|
||||
raise WebIDLError(
|
||||
"Can't have both a named constructor and [Global]",
|
||||
"Can't have both a legacy factory function and [Global]",
|
||||
[self.location, ctor.location],
|
||||
)
|
||||
assert len(ctor._exposureGlobalNames) == 0
|
||||
|
@ -1477,7 +1477,7 @@ class IDLInterfaceOrNamespace(IDLInterfaceOrInterfaceMixinOrNamespace):
|
|||
ctor = self.ctor()
|
||||
if ctor is not None:
|
||||
ctor.validate()
|
||||
for namedCtor in self.namedConstructors:
|
||||
for namedCtor in self.legacyFactoryFunctions:
|
||||
namedCtor.validate()
|
||||
|
||||
indexedGetter = None
|
||||
|
@ -1829,10 +1829,10 @@ class IDLInterface(IDLInterfaceOrNamespace):
|
|||
)
|
||||
|
||||
self._noInterfaceObject = True
|
||||
elif identifier == "NamedConstructor":
|
||||
elif identifier == "LegacyFactoryFunction":
|
||||
if not attr.hasValue():
|
||||
raise WebIDLError(
|
||||
"NamedConstructor must either take an identifier or take a named argument list",
|
||||
"LegacyFactoryFunction must either take an identifier or take a named argument list",
|
||||
[attr.location],
|
||||
)
|
||||
|
||||
|
@ -1849,27 +1849,27 @@ class IDLInterface(IDLInterfaceOrNamespace):
|
|||
[IDLExtendedAttribute(self.location, ("Throws",))]
|
||||
)
|
||||
|
||||
# We need to detect conflicts for NamedConstructors across
|
||||
# We need to detect conflicts for LegacyFactoryFunctions across
|
||||
# interfaces. We first call resolve on the parentScope,
|
||||
# which will merge all NamedConstructors with the same
|
||||
# which will merge all LegacyFactoryFunctions with the same
|
||||
# identifier accross interfaces as overloads.
|
||||
method.resolve(self.parentScope)
|
||||
|
||||
# Then we look up the identifier on the parentScope. If the
|
||||
# result is the same as the method we're adding then it
|
||||
# hasn't been added as an overload and it's the first time
|
||||
# we've encountered a NamedConstructor with that identifier.
|
||||
# we've encountered a LegacyFactoryFunction with that identifier.
|
||||
# If the result is not the same as the method we're adding
|
||||
# then it has been added as an overload and we need to check
|
||||
# whether the result is actually one of our existing
|
||||
# NamedConstructors.
|
||||
# LegacyFactoryFunctions.
|
||||
newMethod = self.parentScope.lookupIdentifier(method.identifier)
|
||||
if newMethod == method:
|
||||
self.namedConstructors.append(method)
|
||||
elif newMethod not in self.namedConstructors:
|
||||
self.legacyFactoryFunctions.append(method)
|
||||
elif newMethod not in self.legacyFactoryFunctions:
|
||||
raise WebIDLError(
|
||||
"NamedConstructor conflicts with a "
|
||||
"NamedConstructor of a different interface",
|
||||
"LegacyFactoryFunction conflicts with a "
|
||||
"LegacyFactoryFunction of a different interface",
|
||||
[method.location, newMethod.location],
|
||||
)
|
||||
elif identifier == "ExceptionClass":
|
||||
|
@ -6479,7 +6479,7 @@ class IDLConstructor(IDLMethod):
|
|||
raise WebIDLError(
|
||||
"[HTMLConstructor] must take no arguments", [attr.location]
|
||||
)
|
||||
# We shouldn't end up here for named constructors.
|
||||
# We shouldn't end up here for legacy factory functions.
|
||||
assert self.identifier.name == "constructor"
|
||||
|
||||
if any(len(sig[1]) != 0 for sig in self.signatures()):
|
||||
|
|
|
@ -24,9 +24,9 @@ def WebIDLTest(parser, harness):
|
|||
try:
|
||||
parser.parse(
|
||||
"""
|
||||
[Global, Exposed=TestNamedConstructorGlobal,
|
||||
NamedConstructor=FooBar]
|
||||
interface TestNamedConstructorGlobal {
|
||||
[Global, Exposed=TestLegacyFactoryFunctionGlobal,
|
||||
LegacyFactoryFunction=FooBar]
|
||||
interface TestLegacyFactoryFunctionGlobal {
|
||||
};
|
||||
"""
|
||||
)
|
||||
|
@ -41,9 +41,9 @@ def WebIDLTest(parser, harness):
|
|||
try:
|
||||
parser.parse(
|
||||
"""
|
||||
[NamedConstructor=FooBar, Global,
|
||||
Exposed=TestNamedConstructorGlobal]
|
||||
interface TestNamedConstructorGlobal {
|
||||
[LegacyFactoryFunction=FooBar, Global,
|
||||
Exposed=TestLegacyFactoryFunctionGlobal]
|
||||
interface TestLegacyFactoryFunctionGlobal {
|
||||
};
|
||||
"""
|
||||
)
|
||||
|
|
|
@ -20,8 +20,8 @@ def WebIDLTest(parser, harness):
|
|||
|
||||
parser.parse(
|
||||
"""
|
||||
[LegacyNoInterfaceObject, NamedConstructor=FooBar]
|
||||
interface TestNamedConstructorLegacyNoInterfaceObject {
|
||||
[LegacyNoInterfaceObject, LegacyFactoryFunction=FooBar]
|
||||
interface TestLegacyFactoryFunctionLegacyNoInterfaceObject {
|
||||
};
|
||||
"""
|
||||
)
|
||||
|
|
|
@ -151,15 +151,15 @@ TestInterface includes InterfaceMixin;
|
|||
interface OnlyForUseInConstructor {
|
||||
};
|
||||
|
||||
[NamedConstructor=Test,
|
||||
NamedConstructor=Test(DOMString str),
|
||||
NamedConstructor=Test2(DictForConstructor dict, any any1, object obj1,
|
||||
[LegacyFactoryFunction=Test,
|
||||
LegacyFactoryFunction=Test(DOMString str),
|
||||
LegacyFactoryFunction=Test2(DictForConstructor dict, any any1, object obj1,
|
||||
object? obj2, sequence<Dict> seq, optional any any2,
|
||||
optional object obj3, optional object? obj4),
|
||||
NamedConstructor=Test3((long or record<DOMString, any>) arg1),
|
||||
NamedConstructor=Test4(record<DOMString, record<DOMString, any>> arg1),
|
||||
NamedConstructor=Test5(record<DOMString, sequence<record<DOMString, record<DOMString, sequence<sequence<any>>>>>> arg1),
|
||||
NamedConstructor=Test6(sequence<record<ByteString, sequence<sequence<record<ByteString, record<USVString, any>>>>>> arg1),
|
||||
LegacyFactoryFunction=Test3((long or record<DOMString, any>) arg1),
|
||||
LegacyFactoryFunction=Test4(record<DOMString, record<DOMString, any>> arg1),
|
||||
LegacyFactoryFunction=Test5(record<DOMString, sequence<record<DOMString, record<DOMString, sequence<sequence<any>>>>>> arg1),
|
||||
LegacyFactoryFunction=Test6(sequence<record<ByteString, sequence<sequence<record<ByteString, record<USVString, any>>>>>> arg1),
|
||||
Exposed=Window]
|
||||
interface TestInterface {
|
||||
constructor();
|
||||
|
|
|
@ -3,12 +3,12 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
[NamedConstructor=Example,
|
||||
NamedConstructor=Example(DOMString str),
|
||||
NamedConstructor=Example2(DictForConstructor dict, any any1, object obj1,
|
||||
[LegacyFactoryFunction=Example,
|
||||
LegacyFactoryFunction=Example(DOMString str),
|
||||
LegacyFactoryFunction=Example2(DictForConstructor dict, any any1, object obj1,
|
||||
object? obj2, sequence<Dict> seq, optional any any2,
|
||||
optional object obj3, optional object? obj4),
|
||||
NamedConstructor=Example2((long or record<DOMString, any>) arg1),
|
||||
LegacyFactoryFunction=Example2((long or record<DOMString, any>) arg1),
|
||||
Exposed=Window]
|
||||
interface TestExampleInterface {
|
||||
constructor();
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
* and create derivative works of this document.
|
||||
*/
|
||||
|
||||
[NamedConstructor=Audio(optional DOMString src),
|
||||
[LegacyFactoryFunction=Audio(optional DOMString src),
|
||||
Exposed=Window]
|
||||
interface HTMLAudioElement : HTMLMediaElement {
|
||||
[HTMLConstructor] constructor();
|
||||
|
|
|
@ -16,7 +16,7 @@ interface imgIRequest;
|
|||
interface URI;
|
||||
interface nsIStreamListener;
|
||||
|
||||
[NamedConstructor=Image(optional unsigned long width, optional unsigned long height),
|
||||
[LegacyFactoryFunction=Image(optional unsigned long width, optional unsigned long height),
|
||||
Exposed=Window]
|
||||
interface HTMLImageElement : HTMLElement {
|
||||
[HTMLConstructor] constructor();
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
* and create derivative works of this document.
|
||||
*/
|
||||
|
||||
[NamedConstructor=Option(optional DOMString text = "", optional DOMString value, optional boolean defaultSelected = false, optional boolean selected = false),
|
||||
[LegacyFactoryFunction=Option(optional DOMString text = "", optional DOMString value, optional boolean defaultSelected = false, optional boolean selected = false),
|
||||
Exposed=Window]
|
||||
interface HTMLOptionElement : HTMLElement {
|
||||
[HTMLConstructor] constructor();
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
*/
|
||||
|
||||
[Pref="media.webspeech.recognition.enable",
|
||||
NamedConstructor=webkitSpeechGrammar,
|
||||
LegacyFactoryFunction=webkitSpeechGrammar,
|
||||
Func="SpeechRecognition::IsAuthorized",
|
||||
Exposed=Window]
|
||||
interface SpeechGrammar {
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
*/
|
||||
|
||||
[Pref="media.webspeech.recognition.enable",
|
||||
NamedConstructor=webkitSpeechGrammarList,
|
||||
LegacyFactoryFunction=webkitSpeechGrammarList,
|
||||
Func="SpeechRecognition::IsAuthorized",
|
||||
Exposed=Window]
|
||||
interface SpeechGrammarList {
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
*/
|
||||
|
||||
[Pref="media.webspeech.recognition.enable",
|
||||
NamedConstructor=webkitSpeechRecognition,
|
||||
LegacyFactoryFunction=webkitSpeechRecognition,
|
||||
Func="SpeechRecognition::IsAuthorized",
|
||||
Exposed=Window]
|
||||
interface SpeechRecognition : EventTarget {
|
||||
|
|
Загрузка…
Ссылка в новой задаче