Not part of build. Bug 30088 - type ahead find, fixes based on comments from r=Akkana
This commit is contained in:
Родитель
e3791121af
Коммит
20500cd3b7
|
@ -1 +1,2 @@
|
|||
Makefile
|
||||
|
||||
|
|
|
@ -96,3 +96,4 @@ xpi::
|
|||
bin/components/typeaheadfind.xpt \
|
||||
bin/chrome/typeaheadfind.jar \
|
||||
bin/defaults/pref/typeaheadfind.js )
|
||||
|
||||
|
|
|
@ -1,60 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Original Author: Aaron Leventhal (aaronl@netscape.com)
|
||||
* Contributors:
|
||||
*
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the NPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
var gVersion = "0.1";
|
||||
|
||||
var err = initInstall("Type Ahead Find", "typeaheadfind", gVersion);
|
||||
logComment("initInstall: " + err);
|
||||
|
||||
var fProgram = getFolder("Program");
|
||||
logComment("fProgram: " + fProgram);
|
||||
|
||||
err = addDirectory("", gVersion, "bin", fProgram, "", true);
|
||||
logComment("addDirectory: " + err);
|
||||
|
||||
// Register chrome
|
||||
registerChrome(LOCALE | DELAYED_CHROME, getFolder("Chrome","typeaheadfind.jar"), "locale/en-US/typeaheadfind/");
|
||||
|
||||
if (getLastError() == SUCCESS) {
|
||||
err = performInstall();
|
||||
logComment("performInstall: " + err);
|
||||
} else {
|
||||
cancelInstall(err);
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
typeaheadfind.jar:
|
||||
locale/en-US/typeaheadfind/contents.rdf (resources/locale/en-US/contents.rdf)
|
||||
locale/en-US/typeaheadfind/typeaheadfind.properties (resources/locale/en-US/typeaheadfind.properties)
|
|
@ -82,4 +82,3 @@ include <$(DEPTH)\config\rules.mak>
|
|||
|
||||
libs::
|
||||
$(MAKE_INSTALL) resources\content\prefs\typeaheadfind.js $(DIST)\bin\defaults\pref
|
||||
|
||||
|
|
|
@ -148,7 +148,10 @@ nsTypeAheadFind::nsTypeAheadFind():
|
|||
return;
|
||||
|
||||
nsCOMPtr<nsIPref> prefs(do_GetService(NS_PREF_CONTRACTID));
|
||||
if (!prefs)
|
||||
mSearchRange = do_CreateInstance(kRangeCID);
|
||||
mStartPointRange = do_CreateInstance(kRangeCID);
|
||||
mEndPointRange = do_CreateInstance(kRangeCID);
|
||||
if (!prefs || !mSearchRange || !mStartPointRange || !mEndPointRange)
|
||||
return;
|
||||
|
||||
mFind = do_CreateInstance(NS_FIND_CONTRACTID);
|
||||
|
@ -745,14 +748,18 @@ NS_IMETHODIMP nsTypeAheadFind::KeyPress(nsIDOMEvent* aEvent)
|
|||
// If first character is bad, flush it away anyway
|
||||
if (mTypeAheadBuffer.Length == 1)
|
||||
#endif
|
||||
mTypeAheadBuffer = Substring(mTypeAheadBuffer, 0, mTypeAheadBuffer.Length() - 1);
|
||||
mTypeAheadBuffer = Substring(mTypeAheadBuffer, 0,
|
||||
mTypeAheadBuffer.Length() - 1);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
nsresult nsTypeAheadFind::FindItNow(PRBool aIsRepeatingSameChar, PRBool aIsLinksOnly, PRBool aIsFirstVisiblePreferred, PRBool aIsBackspace)
|
||||
nsresult nsTypeAheadFind::FindItNow(PRBool aIsRepeatingSameChar,
|
||||
PRBool aIsLinksOnly,
|
||||
PRBool aIsFirstVisiblePreferred,
|
||||
PRBool aIsBackspace)
|
||||
{
|
||||
nsCOMPtr<nsIPresShell> presShell;
|
||||
nsCOMPtr<nsIPresShell> startingPresShell(do_QueryReferent(mFocusedWeakShell));
|
||||
|
@ -815,20 +822,17 @@ nsresult nsTypeAheadFind::FindItNow(PRBool aIsRepeatingSameChar, PRBool aIsLinks
|
|||
if (NS_FAILED(GetSearchContainers(currentContainer, aIsRepeatingSameChar,
|
||||
aIsFirstVisiblePreferred, PR_TRUE,
|
||||
getter_AddRefs(presShell),
|
||||
getter_AddRefs(presContext),
|
||||
getter_AddRefs(searchRange),
|
||||
getter_AddRefs(startPointRange),
|
||||
getter_AddRefs(endPointRange))))
|
||||
getter_AddRefs(presContext))))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (aIsBackspace && mStartFindRange && startingDocShell == currentDocShell) {
|
||||
// when backspace is pressed, start where first char was found
|
||||
mStartFindRange->CloneRange(getter_AddRefs(startPointRange));
|
||||
mStartFindRange->CloneRange(getter_AddRefs(mStartPointRange));
|
||||
}
|
||||
|
||||
PRInt32 rangeCompareResult = 0;
|
||||
startPointRange->CompareBoundaryPoints(nsIDOMRange::START_TO_START ,
|
||||
searchRange, &rangeCompareResult);
|
||||
mStartPointRange->CompareBoundaryPoints(nsIDOMRange::START_TO_START ,
|
||||
searchRange, &rangeCompareResult);
|
||||
// No need to wrap find in doc if starting at beginning
|
||||
PRBool hasWrapped = (rangeCompareResult <= 0);
|
||||
|
||||
|
@ -839,26 +843,28 @@ nsresult nsTypeAheadFind::FindItNow(PRBool aIsRepeatingSameChar, PRBool aIsLinks
|
|||
findBuffer = PromiseFlatString(mTypeAheadBuffer);
|
||||
|
||||
while (PR_TRUE) { // ----- Outer while loop: go through all docs -----
|
||||
while (PR_TRUE) { // Inner while loop: go through a single document
|
||||
mFind->Find(findBuffer.get(), searchRange,
|
||||
startPointRange, endPointRange, getter_AddRefs(returnRange));
|
||||
while (PR_TRUE) { // === Inner while loop: go through a single doc ===
|
||||
mFind->Find(findBuffer.get(), mSearchRange,
|
||||
mStartPointRange, mEndPointRange, getter_AddRefs(returnRange));
|
||||
if (!returnRange)
|
||||
break;
|
||||
break; // Nothing found in this doc, go to outer loop (try next doc)
|
||||
// ------- Test resulting found range for success conditions ------
|
||||
PRBool isInsideLink, isStartingLink;
|
||||
RangeStartsInsideLink(returnRange, presShell, &isInsideLink,
|
||||
&isStartingLink);
|
||||
PRBool isInsideLink = PR_FALSE, isStartingLink = PR_FALSE;
|
||||
if (aIsLinksOnly) // Don't check if inside link when searching all text
|
||||
RangeStartsInsideLink(returnRange, presShell, &isInsideLink,
|
||||
&isStartingLink);
|
||||
|
||||
if (!IsRangeVisible(presShell, presContext, returnRange,
|
||||
aIsFirstVisiblePreferred, getter_AddRefs(startPointRange)) ||
|
||||
aIsFirstVisiblePreferred,
|
||||
getter_AddRefs(mStartPointRange)) ||
|
||||
(aIsRepeatingSameChar && !isStartingLink) ||
|
||||
(aIsLinksOnly && !isInsideLink) ||
|
||||
(mStartLinksOnlyPref && aIsLinksOnly && !isStartingLink)) {
|
||||
// ------ Failure ------
|
||||
// Start find again from here
|
||||
returnRange->CloneRange(getter_AddRefs(startPointRange));
|
||||
returnRange->CloneRange(getter_AddRefs(mStartPointRange));
|
||||
// Collapse to end
|
||||
startPointRange->Collapse(mRepeatingMode == eRepeatingReverse);
|
||||
mStartPointRange->Collapse(mRepeatingMode == eRepeatingReverse);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -896,21 +902,20 @@ nsresult nsTypeAheadFind::FindItNow(PRBool aIsRepeatingSameChar, PRBool aIsLinks
|
|||
DisplayStatus(PR_TRUE, focusedContent, PR_FALSE);
|
||||
return NS_OK;
|
||||
}
|
||||
// ======= end-inner-while: go through a single document ==========
|
||||
// ======= end-inner-while (go through a single document) ==========
|
||||
|
||||
// ---------- Nothing found yet -------------
|
||||
// ---------- Nothing found yet, try next document -------------
|
||||
do {
|
||||
// ==== Second inner loop - get another while ====
|
||||
if (NS_SUCCEEDED(docShellEnumerator->HasMoreElements(&hasMoreDocShells))
|
||||
&& hasMoreDocShells) {
|
||||
docShellEnumerator->GetNext(getter_AddRefs(currentContainer));
|
||||
NS_ASSERTION(currentContainer, "HasMoreElements lied to us!");
|
||||
if (NS_FAILED(GetSearchContainers(currentContainer,
|
||||
aIsRepeatingSameChar,
|
||||
aIsFirstVisiblePreferred, PR_FALSE,
|
||||
getter_AddRefs(presShell),
|
||||
getter_AddRefs(presContext),
|
||||
getter_AddRefs(searchRange),
|
||||
getter_AddRefs(startPointRange),
|
||||
getter_AddRefs(endPointRange))))
|
||||
getter_AddRefs(presContext))))
|
||||
return NS_ERROR_FAILURE;
|
||||
currentDocShell = do_QueryInterface(currentContainer);
|
||||
if (currentDocShell)
|
||||
|
@ -921,15 +926,15 @@ nsresult nsTypeAheadFind::FindItNow(PRBool aIsRepeatingSameChar, PRBool aIsLinks
|
|||
nsIDocShell::ENUMERATE_FORWARDS,
|
||||
getter_AddRefs(docShellEnumerator));
|
||||
}
|
||||
while (docShellEnumerator);
|
||||
while (docShellEnumerator); // ==== end second inner while ===
|
||||
|
||||
if (currentDocShell != startingDocShell)
|
||||
continue; // Try next document
|
||||
|
||||
// Finished searching through docshells:
|
||||
// If aFirstVisiblePreferred == PR_TRUE, we may
|
||||
// need to go through all docshells twice -
|
||||
// once to look for visible matches, the second time for any match
|
||||
// If aFirstVisiblePreferred == PR_TRUE, we may need to go through all
|
||||
// docshells twice -once to look for visible matches, the second time
|
||||
// for any match
|
||||
if (!hasWrapped || aIsFirstVisiblePreferred) {
|
||||
aIsFirstVisiblePreferred = PR_FALSE;
|
||||
hasWrapped = PR_TRUE;
|
||||
|
@ -960,14 +965,8 @@ nsresult nsTypeAheadFind::GetSearchContainers(nsISupports *aContainer,
|
|||
PRBool aIsFirstVisiblePreferred,
|
||||
PRBool aCanUseDocSelection,
|
||||
nsIPresShell **aPresShell,
|
||||
nsIPresContext **aPresContext,
|
||||
nsIDOMRange **aSearchRange,
|
||||
nsIDOMRange **aStartPointRange,
|
||||
nsIDOMRange **aEndPointRange)
|
||||
nsIPresContext **aPresContext)
|
||||
{
|
||||
*aSearchRange = nsnull;
|
||||
*aStartPointRange = nsnull;
|
||||
*aEndPointRange = nsnull;
|
||||
*aPresShell = nsnull;
|
||||
*aPresContext = nsnull;
|
||||
|
||||
|
@ -993,13 +992,9 @@ nsresult nsTypeAheadFind::GetSearchContainers(nsISupports *aContainer,
|
|||
if (NS_FAILED(rootContent->ChildCount(childCount)))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIDOMRange> searchRange(do_CreateInstance(kRangeCID));
|
||||
nsCOMPtr<nsIDOMRange> startPointRange(do_CreateInstance(kRangeCID));
|
||||
nsCOMPtr<nsIDOMRange> endPointRange(do_CreateInstance(kRangeCID));
|
||||
|
||||
searchRange->SelectNodeContents(rootNode);
|
||||
endPointRange->SetStart(rootNode, childCount);
|
||||
endPointRange->SetEnd(rootNode, childCount);
|
||||
mSearchRange->SelectNodeContents(rootNode);
|
||||
mEndPointRange->SetStart(rootNode, childCount);
|
||||
mEndPointRange->SetEnd(rootNode, childCount);
|
||||
|
||||
// Consider current selection as null if
|
||||
// it's not in the currently focused document
|
||||
|
@ -1010,8 +1005,10 @@ nsresult nsTypeAheadFind::GetSearchContainers(nsISupports *aContainer,
|
|||
|
||||
if (!currentSelectionRange || aIsFirstVisiblePreferred) {
|
||||
// Ensure visible range, move forward if necessary
|
||||
IsRangeVisible(*aPresShell, *aPresContext, searchRange,
|
||||
aIsFirstVisiblePreferred, getter_AddRefs(startPointRange));
|
||||
// This uses ignores the return value, but usese the side effect of
|
||||
// IsRangeVisible. It returns the first visible range after searchRange
|
||||
IsRangeVisible(*aPresShell, *aPresContext, mSearchRange,
|
||||
aIsFirstVisiblePreferred, getter_AddRefs(mStartPointRange));
|
||||
}
|
||||
else {
|
||||
PRInt32 startOffset;
|
||||
|
@ -1026,13 +1023,10 @@ nsresult nsTypeAheadFind::GetSearchContainers(nsISupports *aContainer,
|
|||
}
|
||||
if (!startNode)
|
||||
startNode = rootNode;
|
||||
startPointRange->SetStart(startNode, startOffset);
|
||||
startPointRange->Collapse(PR_TRUE); // collapse to start
|
||||
mStartPointRange->SetStart(startNode, startOffset);
|
||||
mStartPointRange->Collapse(PR_TRUE); // collapse to start
|
||||
}
|
||||
|
||||
NS_ADDREF(*aSearchRange = searchRange);
|
||||
NS_ADDREF(*aStartPointRange = startPointRange);
|
||||
NS_ADDREF(*aEndPointRange = endPointRange);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -1510,7 +1504,7 @@ PRBool nsTypeAheadFind::IsRangeVisible(nsIPresShell *aPresShell,
|
|||
if (containingView) {
|
||||
relFrameRect.x = frameOffset.x;
|
||||
relFrameRect.y = frameOffset.y;
|
||||
viewManager->IsRectVisible(containingView, relFrameRect
|
||||
viewManager->IsRectVisible(containingView, relFrameRect,
|
||||
NS_STATIC_CAST(PRUint16, (kMinPixels * p2t)),
|
||||
&isFirstVisible, &isBelowViewPort);
|
||||
}
|
||||
|
@ -1591,6 +1585,6 @@ void nsTypeAheadFind::DisplayStatus(PRBool aSuccess,
|
|||
}
|
||||
}
|
||||
browserChrome->SetStatus(nsIWebBrowserChrome::STATUS_LINK,
|
||||
PromiseFlatString(statusString).get());
|
||||
PromiseFlatString(statusString).get());
|
||||
}
|
||||
|
||||
|
|
|
@ -152,10 +152,7 @@ protected:
|
|||
PRBool aIsFirstVisiblePreferred,
|
||||
PRBool aCanUseDocSelection,
|
||||
nsIPresShell **aPresShell,
|
||||
nsIPresContext **aPresContext,
|
||||
nsIDOMRange **aSearchRange,
|
||||
nsIDOMRange **aStartRange,
|
||||
nsIDOMRange **aEndRange);
|
||||
nsIPresContext **aPresContext);
|
||||
void DisplayStatus(PRBool aSuccess, nsIContent *aFocusedContent,
|
||||
PRBool aClearStatus);
|
||||
nsresult GetTranslatedString(const nsAString& aKey, nsAString& aStringOut);
|
||||
|
@ -183,6 +180,9 @@ protected:
|
|||
|
||||
// where selection was when user started the find
|
||||
nsCOMPtr<nsIDOMRange> mStartFindRange;
|
||||
nsCOMPtr<nsIDOMRange> mSearchRange;
|
||||
nsCOMPtr<nsIDOMRange> mStartPointRange;
|
||||
nsCOMPtr<nsIDOMRange> mEndPointRange;
|
||||
|
||||
// Cached useful interfaces
|
||||
nsCOMPtr<nsIFind> mFind;
|
||||
|
|
|
@ -1,94 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Original Author: Aaron Leventhal (aaronl@netscape.com)
|
||||
* Contributors:
|
||||
*
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the NPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsIGenericFactory.h"
|
||||
#include "nsTypeAheadFind.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIRegistry.h"
|
||||
#include "prprf.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsICategoryManager.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Define a table of CIDs implemented by this module along with other
|
||||
// information like the function to create an instance, contractid, and
|
||||
// class name.
|
||||
//
|
||||
// The Registration and Unregistration proc are optional in the structure.
|
||||
//
|
||||
|
||||
|
||||
// This function is called at component registration time
|
||||
static NS_METHOD nsTypeAheadFindRegistrationProc(nsIComponentManager *aCompMgr,
|
||||
nsIFile *aPath, const char *registryLocation, const char *componentType,
|
||||
const nsModuleComponentInfo *info)
|
||||
{
|
||||
// This function performs the extra step of installing us as
|
||||
// an application component. This makes sure that we're
|
||||
// initialized on application startup.
|
||||
|
||||
// Register nsTypeAheadFind to be instantiated on startup.
|
||||
// XXX This is needed on linux, but for some reason not needed on win32.
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsICategoryManager> categoryManager(do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv));
|
||||
if (NS_SUCCEEDED(rv))
|
||||
rv = categoryManager->AddCategoryEntry(APPSTARTUP_CATEGORY, "Type Ahead Find",
|
||||
"service," NS_TYPEAHEADFIND_CONTRACTID, PR_TRUE, PR_TRUE, nsnull);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsTypeAheadFind,nsTypeAheadFind::GetInstance);
|
||||
|
||||
static void PR_CALLBACK TypeAheadFindModuleDtor(nsIModule* self)
|
||||
{
|
||||
nsTypeAheadFind::ReleaseInstance();
|
||||
}
|
||||
|
||||
static const nsModuleComponentInfo components[] =
|
||||
{
|
||||
{ "TypeAheadFind Component", NS_TYPEAHEADFIND_CID, NS_TYPEAHEADFIND_CONTRACTID,
|
||||
nsTypeAheadFindConstructor, nsTypeAheadFindRegistrationProc,
|
||||
nsnull // Unregistration proc
|
||||
}
|
||||
};
|
||||
|
||||
NS_IMPL_NSGETMODULE_WITH_DTOR(nsTypeAheadFind, components, TypeAheadFindModuleDtor)
|
||||
|
|
@ -39,4 +39,4 @@
|
|||
pref("accessibility.typeaheadfind", true);
|
||||
pref("accessibility.typeaheadfind.linksonly", true);
|
||||
pref("accessibility.typeaheadfind.startlinksonly", false);
|
||||
pref("accessibility.typeaheadfind.timeout", 2500);
|
||||
pref("accessibility.typeaheadfind.timeout", 5000);
|
||||
|
|
|
@ -18,3 +18,4 @@
|
|||
<RDF:Description about="urn:mozilla:locale:en-US:typeaheadfind"
|
||||
chrome:localeVersion="1.0.0"/>
|
||||
</RDF:RDF>
|
||||
|
||||
|
|
|
@ -6,3 +6,4 @@ linkfound = Link found: "
|
|||
linknotfound = Link not found: "
|
||||
closequote = "
|
||||
stopfind = Type ahead find stopped.
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче