зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1332812. Remove some more unused or nearly-unused nsIDOMElement bits. r=froydnj
This commit is contained in:
Родитель
c22552fc85
Коммит
b249de7c3a
|
@ -601,12 +601,6 @@ Element::ClassList()
|
|||
return slots->mClassList;
|
||||
}
|
||||
|
||||
void
|
||||
Element::GetClassList(nsISupports** aClassList)
|
||||
{
|
||||
NS_ADDREF(*aClassList = ClassList());
|
||||
}
|
||||
|
||||
void
|
||||
Element::GetAttributeNames(nsTArray<nsString>& aResult)
|
||||
{
|
||||
|
@ -623,13 +617,6 @@ Element::GetElementsByTagName(const nsAString& aLocalName)
|
|||
return NS_GetContentList(this, kNameSpaceID_Unknown, aLocalName);
|
||||
}
|
||||
|
||||
void
|
||||
Element::GetElementsByTagName(const nsAString& aLocalName,
|
||||
nsIDOMHTMLCollection** aResult)
|
||||
{
|
||||
*aResult = GetElementsByTagName(aLocalName).take();
|
||||
}
|
||||
|
||||
nsIFrame*
|
||||
Element::GetStyledFrame()
|
||||
{
|
||||
|
@ -1416,21 +1403,6 @@ Element::GetElementsByTagNameNS(const nsAString& aNamespaceURI,
|
|||
return NS_GetContentList(this, nameSpaceId, aLocalName);
|
||||
}
|
||||
|
||||
nsresult
|
||||
Element::GetElementsByTagNameNS(const nsAString& namespaceURI,
|
||||
const nsAString& localName,
|
||||
nsIDOMHTMLCollection** aResult)
|
||||
{
|
||||
mozilla::ErrorResult rv;
|
||||
nsCOMPtr<nsIHTMLCollection> list =
|
||||
GetElementsByTagNameNS(namespaceURI, localName, rv);
|
||||
if (rv.Failed()) {
|
||||
return rv.StealNSResult();
|
||||
}
|
||||
list.forget(aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
Element::HasAttributeNS(const nsAString& aNamespaceURI,
|
||||
const nsAString& aLocalName) const
|
||||
|
@ -1454,15 +1426,6 @@ Element::GetElementsByClassName(const nsAString& aClassNames)
|
|||
return nsContentUtils::GetElementsByClassName(this, aClassNames);
|
||||
}
|
||||
|
||||
nsresult
|
||||
Element::GetElementsByClassName(const nsAString& aClassNames,
|
||||
nsIDOMHTMLCollection** aResult)
|
||||
{
|
||||
*aResult =
|
||||
nsContentUtils::GetElementsByClassName(this, aClassNames).take();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the count of descendants (inclusive of aContent) in
|
||||
* the uncomposed document that are explicitly set as editable.
|
||||
|
|
|
@ -1093,20 +1093,6 @@ public:
|
|||
*/
|
||||
static CORSMode AttrValueToCORSMode(const nsAttrValue* aValue);
|
||||
|
||||
// These are just used to implement nsIDOMElement using
|
||||
// NS_FORWARD_NSIDOMELEMENT_TO_GENERIC and for quickstubs.
|
||||
void
|
||||
GetElementsByTagName(const nsAString& aQualifiedName,
|
||||
nsIDOMHTMLCollection** aResult);
|
||||
nsresult
|
||||
GetElementsByTagNameNS(const nsAString& aNamespaceURI,
|
||||
const nsAString& aLocalName,
|
||||
nsIDOMHTMLCollection** aResult);
|
||||
nsresult
|
||||
GetElementsByClassName(const nsAString& aClassNames,
|
||||
nsIDOMHTMLCollection** aResult);
|
||||
void GetClassList(nsISupports** aClassList);
|
||||
|
||||
virtual JSObject* WrapObject(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) final override;
|
||||
|
||||
nsINode* GetScopeChainParent() const override;
|
||||
|
@ -1655,31 +1641,6 @@ NS_IMETHOD GetTagName(nsAString& aTagName) final override \
|
|||
Element::GetTagName(aTagName); \
|
||||
return NS_OK; \
|
||||
} \
|
||||
NS_IMETHOD GetId(nsAString& aId) final override \
|
||||
{ \
|
||||
Element::GetId(aId); \
|
||||
return NS_OK; \
|
||||
} \
|
||||
NS_IMETHOD SetId(const nsAString& aId) final override \
|
||||
{ \
|
||||
Element::SetId(aId); \
|
||||
return NS_OK; \
|
||||
} \
|
||||
NS_IMETHOD GetClassName(nsAString& aClassName) final override \
|
||||
{ \
|
||||
Element::GetClassName(aClassName); \
|
||||
return NS_OK; \
|
||||
} \
|
||||
NS_IMETHOD SetClassName(const nsAString& aClassName) final override \
|
||||
{ \
|
||||
Element::SetClassName(aClassName); \
|
||||
return NS_OK; \
|
||||
} \
|
||||
NS_IMETHOD GetClassList(nsISupports** aClassList) final override \
|
||||
{ \
|
||||
Element::GetClassList(aClassList); \
|
||||
return NS_OK; \
|
||||
} \
|
||||
NS_IMETHOD GetAttributes(nsIDOMMozNamedAttrMap** aAttributes) final override \
|
||||
{ \
|
||||
NS_ADDREF(*aAttributes = Attributes()); \
|
||||
|
@ -1694,13 +1655,6 @@ NS_IMETHOD GetAttribute(const nsAString& name, nsAString& _retval) final \
|
|||
_retval = attr; \
|
||||
return NS_OK; \
|
||||
} \
|
||||
NS_IMETHOD GetAttributeNS(const nsAString& namespaceURI, \
|
||||
const nsAString& localName, \
|
||||
nsAString& _retval) final override \
|
||||
{ \
|
||||
Element::GetAttributeNS(namespaceURI, localName, _retval); \
|
||||
return NS_OK; \
|
||||
} \
|
||||
NS_IMETHOD SetAttribute(const nsAString& name, \
|
||||
const nsAString& value) override \
|
||||
{ \
|
||||
|
@ -1708,28 +1662,6 @@ NS_IMETHOD SetAttribute(const nsAString& name, \
|
|||
Element::SetAttribute(name, value, rv); \
|
||||
return rv.StealNSResult(); \
|
||||
} \
|
||||
NS_IMETHOD SetAttributeNS(const nsAString& namespaceURI, \
|
||||
const nsAString& qualifiedName, \
|
||||
const nsAString& value) final override \
|
||||
{ \
|
||||
mozilla::ErrorResult rv; \
|
||||
Element::SetAttributeNS(namespaceURI, qualifiedName, value, rv); \
|
||||
return rv.StealNSResult(); \
|
||||
} \
|
||||
using Element::RemoveAttribute; \
|
||||
NS_IMETHOD RemoveAttribute(const nsAString& name) final override \
|
||||
{ \
|
||||
mozilla::ErrorResult rv; \
|
||||
RemoveAttribute(name, rv); \
|
||||
return rv.StealNSResult(); \
|
||||
} \
|
||||
NS_IMETHOD RemoveAttributeNS(const nsAString& namespaceURI, \
|
||||
const nsAString& localName) final override \
|
||||
{ \
|
||||
mozilla::ErrorResult rv; \
|
||||
Element::RemoveAttributeNS(namespaceURI, localName, rv); \
|
||||
return rv.StealNSResult(); \
|
||||
} \
|
||||
using Element::HasAttribute; \
|
||||
NS_IMETHOD HasAttribute(const nsAString& name, \
|
||||
bool* _retval) final override \
|
||||
|
@ -1737,46 +1669,12 @@ NS_IMETHOD HasAttribute(const nsAString& name, \
|
|||
*_retval = HasAttribute(name); \
|
||||
return NS_OK; \
|
||||
} \
|
||||
NS_IMETHOD HasAttributeNS(const nsAString& namespaceURI, \
|
||||
const nsAString& localName, \
|
||||
bool* _retval) final override \
|
||||
{ \
|
||||
*_retval = Element::HasAttributeNS(namespaceURI, localName); \
|
||||
return NS_OK; \
|
||||
} \
|
||||
NS_IMETHOD HasAttributes(bool* _retval) final override \
|
||||
{ \
|
||||
*_retval = Element::HasAttributes(); \
|
||||
return NS_OK; \
|
||||
} \
|
||||
NS_IMETHOD GetAttributeNode(const nsAString& name, \
|
||||
nsIDOMAttr** _retval) final override \
|
||||
{ \
|
||||
NS_IF_ADDREF(*_retval = Element::GetAttributeNode(name)); \
|
||||
return NS_OK; \
|
||||
} \
|
||||
NS_IMETHOD SetAttributeNode(nsIDOMAttr* newAttr, \
|
||||
nsIDOMAttr** _retval) final override \
|
||||
{ \
|
||||
if (!newAttr) { \
|
||||
return NS_ERROR_INVALID_POINTER; \
|
||||
} \
|
||||
mozilla::ErrorResult rv; \
|
||||
mozilla::dom::Attr* attr = static_cast<mozilla::dom::Attr*>(newAttr); \
|
||||
*_retval = Element::SetAttributeNode(*attr, rv).take(); \
|
||||
return rv.StealNSResult(); \
|
||||
} \
|
||||
NS_IMETHOD RemoveAttributeNode(nsIDOMAttr* oldAttr, \
|
||||
nsIDOMAttr** _retval) final override \
|
||||
{ \
|
||||
if (!oldAttr) { \
|
||||
return NS_ERROR_INVALID_POINTER; \
|
||||
} \
|
||||
mozilla::ErrorResult rv; \
|
||||
mozilla::dom::Attr* attr = static_cast<mozilla::dom::Attr*>(oldAttr); \
|
||||
*_retval = Element::RemoveAttributeNode(*attr, rv).take(); \
|
||||
return rv.StealNSResult(); \
|
||||
} \
|
||||
NS_IMETHOD GetAttributeNodeNS(const nsAString& namespaceURI, \
|
||||
const nsAString& localName, \
|
||||
nsIDOMAttr** _retval) final override \
|
||||
|
@ -1784,34 +1682,5 @@ NS_IMETHOD GetAttributeNodeNS(const nsAString& namespaceURI, \
|
|||
NS_IF_ADDREF(*_retval = Element::GetAttributeNodeNS(namespaceURI, \
|
||||
localName)); \
|
||||
return NS_OK; \
|
||||
} \
|
||||
NS_IMETHOD SetAttributeNodeNS(nsIDOMAttr* newAttr, \
|
||||
nsIDOMAttr** _retval) final override \
|
||||
{ \
|
||||
mozilla::ErrorResult rv; \
|
||||
mozilla::dom::Attr* attr = static_cast<mozilla::dom::Attr*>(newAttr); \
|
||||
*_retval = Element::SetAttributeNodeNS(*attr, rv).take(); \
|
||||
return rv.StealNSResult(); \
|
||||
} \
|
||||
NS_IMETHOD GetElementsByTagName(const nsAString& name, \
|
||||
nsIDOMHTMLCollection** _retval) final \
|
||||
override \
|
||||
{ \
|
||||
Element::GetElementsByTagName(name, _retval); \
|
||||
return NS_OK; \
|
||||
} \
|
||||
NS_IMETHOD GetElementsByTagNameNS(const nsAString& namespaceURI, \
|
||||
const nsAString& localName, \
|
||||
nsIDOMHTMLCollection** _retval) final \
|
||||
override \
|
||||
{ \
|
||||
return Element::GetElementsByTagNameNS(namespaceURI, localName, \
|
||||
_retval); \
|
||||
} \
|
||||
NS_IMETHOD GetElementsByClassName(const nsAString& classes, \
|
||||
nsIDOMHTMLCollection** _retval) final \
|
||||
override \
|
||||
{ \
|
||||
return Element::GetElementsByClassName(classes, _retval); \
|
||||
}
|
||||
#endif // mozilla_dom_Element_h__
|
||||
|
|
|
@ -869,26 +869,23 @@ void
|
|||
nsObjectLoadingContent::GetNestedParams(nsTArray<MozPluginParameter>& aParams,
|
||||
bool aIgnoreCodebase)
|
||||
{
|
||||
nsCOMPtr<nsIDOMElement> domElement =
|
||||
nsCOMPtr<Element> ourElement =
|
||||
do_QueryInterface(static_cast<nsIObjectLoadingContent*>(this));
|
||||
|
||||
nsCOMPtr<nsIDOMHTMLCollection> allParams;
|
||||
nsCOMPtr<nsIHTMLCollection> allParams;
|
||||
NS_NAMED_LITERAL_STRING(xhtml_ns, "http://www.w3.org/1999/xhtml");
|
||||
domElement->GetElementsByTagNameNS(xhtml_ns,
|
||||
NS_LITERAL_STRING("param"), getter_AddRefs(allParams));
|
||||
|
||||
if (!allParams)
|
||||
ErrorResult rv;
|
||||
allParams = ourElement->GetElementsByTagNameNS(xhtml_ns,
|
||||
NS_LITERAL_STRING("param"),
|
||||
rv);
|
||||
if (rv.Failed()) {
|
||||
return;
|
||||
}
|
||||
MOZ_ASSERT(allParams);
|
||||
|
||||
uint32_t numAllParams;
|
||||
allParams->GetLength(&numAllParams);
|
||||
uint32_t numAllParams = allParams->Length();
|
||||
for (uint32_t i = 0; i < numAllParams; i++) {
|
||||
nsCOMPtr<nsIDOMNode> pNode;
|
||||
allParams->Item(i, getter_AddRefs(pNode));
|
||||
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(pNode);
|
||||
|
||||
if (!element)
|
||||
continue;
|
||||
RefPtr<Element> element = allParams->Item(i);
|
||||
|
||||
nsAutoString name;
|
||||
element->GetAttribute(NS_LITERAL_STRING("name"), name);
|
||||
|
@ -896,16 +893,13 @@ nsObjectLoadingContent::GetNestedParams(nsTArray<MozPluginParameter>& aParams,
|
|||
if (name.IsEmpty())
|
||||
continue;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> parent;
|
||||
nsCOMPtr<nsIContent> parent = element->GetParent();
|
||||
nsCOMPtr<nsIDOMHTMLObjectElement> domObject;
|
||||
nsCOMPtr<nsIDOMHTMLAppletElement> domApplet;
|
||||
pNode->GetParentNode(getter_AddRefs(parent));
|
||||
while (!(domObject || domApplet) && parent) {
|
||||
domObject = do_QueryInterface(parent);
|
||||
domApplet = do_QueryInterface(parent);
|
||||
nsCOMPtr<nsIDOMNode> temp;
|
||||
parent->GetParentNode(getter_AddRefs(temp));
|
||||
parent = temp;
|
||||
parent = parent->GetParent();
|
||||
}
|
||||
|
||||
if (domApplet) {
|
||||
|
@ -916,8 +910,7 @@ nsObjectLoadingContent::GetNestedParams(nsTArray<MozPluginParameter>& aParams,
|
|||
continue;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMNode> domNode = do_QueryInterface(domElement);
|
||||
if (parent == domNode) {
|
||||
if (parent == ourElement) {
|
||||
MozPluginParameter param;
|
||||
element->GetAttribute(NS_LITERAL_STRING("name"), param.mName);
|
||||
element->GetAttribute(NS_LITERAL_STRING("value"), param.mValue);
|
||||
|
|
|
@ -29,45 +29,14 @@ interface nsIDOMElement : nsIDOMNode
|
|||
{
|
||||
readonly attribute DOMString tagName;
|
||||
|
||||
attribute DOMString id;
|
||||
attribute DOMString className;
|
||||
/**
|
||||
* Returns a DOMTokenList object reflecting the class attribute.
|
||||
*/
|
||||
readonly attribute nsISupports classList;
|
||||
|
||||
readonly attribute nsIDOMMozNamedAttrMap attributes;
|
||||
DOMString getAttribute(in DOMString name);
|
||||
DOMString getAttributeNS(in DOMString namespaceURI,
|
||||
in DOMString localName);
|
||||
void setAttribute(in DOMString name,
|
||||
in DOMString value);
|
||||
void setAttributeNS(in DOMString namespaceURI,
|
||||
in DOMString qualifiedName,
|
||||
in DOMString value);
|
||||
void removeAttribute(in DOMString name);
|
||||
void removeAttributeNS(in DOMString namespaceURI,
|
||||
in DOMString localName);
|
||||
boolean hasAttribute(in DOMString name);
|
||||
boolean hasAttributeNS(in DOMString namespaceURI,
|
||||
in DOMString localName);
|
||||
boolean hasAttributes();
|
||||
|
||||
// Obsolete methods.
|
||||
nsIDOMAttr getAttributeNode(in DOMString name);
|
||||
nsIDOMAttr setAttributeNode(in nsIDOMAttr newAttr);
|
||||
nsIDOMAttr removeAttributeNode(in nsIDOMAttr oldAttr);
|
||||
nsIDOMAttr getAttributeNodeNS(in DOMString namespaceURI,
|
||||
in DOMString localName);
|
||||
nsIDOMAttr setAttributeNodeNS(in nsIDOMAttr newAttr)
|
||||
raises(DOMException);
|
||||
|
||||
nsIDOMHTMLCollection getElementsByTagName(in DOMString name);
|
||||
nsIDOMHTMLCollection getElementsByTagNameNS(in DOMString namespaceURI,
|
||||
in DOMString localName);
|
||||
/**
|
||||
* Retrieve elements matching all classes listed in a
|
||||
* space-separated string.
|
||||
*/
|
||||
nsIDOMHTMLCollection getElementsByClassName(in DOMString classes);
|
||||
};
|
||||
|
|
|
@ -713,19 +713,6 @@ PersistNodeFixup::GetNodeToFixup(nsIDOMNode *aNodeIn, nsIDOMNode **aNodeOut)
|
|||
} else {
|
||||
NS_ADDREF(*aNodeOut = aNodeIn);
|
||||
}
|
||||
nsCOMPtr<nsIDOMHTMLElement> element(do_QueryInterface(*aNodeOut));
|
||||
if (element) {
|
||||
// Make sure this is not XHTML
|
||||
nsAutoString namespaceURI;
|
||||
element->GetNamespaceURI(namespaceURI);
|
||||
if (namespaceURI.IsEmpty()) {
|
||||
// This is a tag-soup node. It may have a _base_href attribute
|
||||
// stuck on it by the parser, but since we're fixing up all URIs
|
||||
// relative to the overall document base that will screw us up.
|
||||
// Just remove the _base_href.
|
||||
element->RemoveAttribute(NS_LITERAL_STRING("_base_href"));
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -1155,8 +1142,9 @@ PersistNodeFixup::FixupNode(nsIDOMNode *aNodeIn,
|
|||
}
|
||||
// Unset the codebase too, since we'll correctly relativize the
|
||||
// code and archive paths.
|
||||
IgnoredErrorResult ignored;
|
||||
static_cast<dom::HTMLSharedObjectElement*>(newApplet.get())->
|
||||
RemoveAttribute(NS_LITERAL_STRING("codebase"));
|
||||
RemoveAttribute(NS_LITERAL_STRING("codebase"), ignored);
|
||||
FixupAttribute(*aNodeOut, "code");
|
||||
FixupAttribute(*aNodeOut, "archive");
|
||||
// restore the base URI we really want to have
|
||||
|
@ -1233,10 +1221,12 @@ PersistNodeFixup::FixupNode(nsIDOMNode *aNodeIn,
|
|||
case NS_FORM_INPUT_COLOR:
|
||||
nodeAsInput->GetValue(valueStr, dom::CallerType::System);
|
||||
// Avoid superfluous value="" serialization
|
||||
if (valueStr.IsEmpty())
|
||||
outElt->RemoveAttribute(valueAttr);
|
||||
else
|
||||
if (valueStr.IsEmpty()) {
|
||||
IgnoredErrorResult ignored;
|
||||
outElt->RemoveAttribute(valueAttr, ignored);
|
||||
} else {
|
||||
outElt->SetAttribute(valueAttr, valueStr);
|
||||
}
|
||||
break;
|
||||
case NS_FORM_INPUT_CHECKBOX:
|
||||
case NS_FORM_INPUT_RADIO:
|
||||
|
|
|
@ -12,9 +12,6 @@ interface MozXULTemplateBuilder;
|
|||
|
||||
[Func="IsChromeOrXBL"]
|
||||
interface XULElement : Element {
|
||||
[SetterThrows]
|
||||
attribute DOMString className;
|
||||
|
||||
// Layout properties
|
||||
[SetterThrows]
|
||||
attribute DOMString align;
|
||||
|
|
|
@ -455,10 +455,6 @@ public:
|
|||
}
|
||||
|
||||
// WebIDL API
|
||||
void SetClassName(const nsAString& aValue, mozilla::ErrorResult& rv)
|
||||
{
|
||||
SetXULAttr(nsGkAtoms::_class, aValue, rv);
|
||||
}
|
||||
void GetAlign(DOMString& aValue) const
|
||||
{
|
||||
GetXULAttr(nsGkAtoms::align, aValue);
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include "nsISupportsBase.h"
|
||||
#include "nsLiteralString.h"
|
||||
#include "nsUnicharUtils.h"
|
||||
#include "nsIHTMLCollection.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
|
@ -1028,32 +1029,25 @@ TextEditRules::DidRedo(Selection* aSelection,
|
|||
}
|
||||
|
||||
NS_ENSURE_STATE(mTextEditor);
|
||||
nsCOMPtr<nsIDOMElement> theRoot = do_QueryInterface(mTextEditor->GetRoot());
|
||||
RefPtr<Element> theRoot = mTextEditor->GetRoot();
|
||||
NS_ENSURE_TRUE(theRoot, NS_ERROR_FAILURE);
|
||||
|
||||
nsCOMPtr<nsIDOMHTMLCollection> nodeList;
|
||||
nsresult rv = theRoot->GetElementsByTagName(NS_LITERAL_STRING("br"),
|
||||
getter_AddRefs(nodeList));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (nodeList) {
|
||||
uint32_t len;
|
||||
nodeList->GetLength(&len);
|
||||
nsCOMPtr<nsIHTMLCollection> nodeList =
|
||||
theRoot->GetElementsByTagName(NS_LITERAL_STRING("br"));
|
||||
MOZ_ASSERT(nodeList);
|
||||
uint32_t len = nodeList->Length();
|
||||
|
||||
if (len != 1) {
|
||||
// only in the case of one br could there be the bogus node
|
||||
mBogusNode = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
if (len != 1) {
|
||||
// only in the case of one br could there be the bogus node
|
||||
mBogusNode = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMNode> node;
|
||||
nodeList->Item(0, getter_AddRefs(node));
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(node);
|
||||
MOZ_ASSERT(content);
|
||||
if (mTextEditor->IsMozEditorBogusNode(content)) {
|
||||
mBogusNode = node;
|
||||
} else {
|
||||
mBogusNode = nullptr;
|
||||
}
|
||||
RefPtr<Element> node = nodeList->Item(0);
|
||||
if (mTextEditor->IsMozEditorBogusNode(node)) {
|
||||
mBogusNode = do_QueryInterface(node);
|
||||
} else {
|
||||
mBogusNode = nullptr;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -522,7 +522,7 @@ nsFormFillController::GetSearchParam(nsAString &aSearchParam)
|
|||
|
||||
mFocusedInput->GetName(aSearchParam);
|
||||
if (aSearchParam.IsEmpty()) {
|
||||
nsCOMPtr<nsIDOMHTMLElement> element = do_QueryInterface(mFocusedInput);
|
||||
nsCOMPtr<Element> element = do_QueryInterface(mFocusedInput);
|
||||
element->GetId(aSearchParam);
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче