зеркало из https://github.com/mozilla/gecko-dev.git
Fix for nsbeta2+ bug 31134 -- paste in edit menu not enabled correctly. Add a new command set for clipboard-related menu items, and fire it on Copy. Also ensure that Undo/Redo commands are updated correctly, and avoid bogus command updating in plain text compose (since that caused JS errors). r=kin,jfrancis.
This commit is contained in:
Родитель
e70cbf16b9
Коммит
bc5e13e277
|
@ -54,8 +54,9 @@
|
|||
<commandset id="globalEditMenuItems"/>
|
||||
<commandset id="selectEditMenuItems"/>
|
||||
<commandset id="undoEditMenuItems"/>
|
||||
<commandset id="clipboardEditMenuItems"/>
|
||||
|
||||
<commandset id="composerMenuItems"/>
|
||||
<commandset id="commonEditorMenuItems"/>
|
||||
<commandset id="composerEditMenuItems"/>
|
||||
<commandset id="composerSaveMenuItems"/>
|
||||
</commands>
|
||||
|
@ -111,7 +112,7 @@
|
|||
<button id="newButton"/>
|
||||
<button id="openButton"/>
|
||||
<button id="saveButton"/>
|
||||
<toolbarseparator/>
|
||||
<spring class="separator_small"/>
|
||||
<button id="printButton"/>
|
||||
<button id="findButton"/>
|
||||
<button id="spellingButton"/>
|
||||
|
|
|
@ -211,17 +211,17 @@ function EditorSharedStartup()
|
|||
// Set platform-specific hints for how to select cells
|
||||
// Mac uses "Cmd", all others use "Ctrl"
|
||||
var tableKey = GetString(gIsMac ? "XulKeyMac" : "TableSelectKey");
|
||||
var DragStr = tableKey+GetString("Drag");
|
||||
var ClickStr = tableKey+GetString("Click");
|
||||
var dragStr = tableKey+GetString("Drag");
|
||||
var clickStr = tableKey+GetString("Click");
|
||||
|
||||
var DelStr = GetString(gIsMac ? "Clear" : "Del");
|
||||
var delStr = GetString(gIsMac ? "Clear" : "Del");
|
||||
|
||||
document.getElementById("menu_SelectCell").setAttribute("acceltext", ClickStr);
|
||||
document.getElementById("menu_SelectRow").setAttribute("acceltext", DragStr);
|
||||
document.getElementById("menu_SelectColumn").setAttribute("acceltext", DragStr);
|
||||
document.getElementById("menu_SelectAllCells").setAttribute("acceltext", DragStr);
|
||||
SafeSetAttribute("menu_SelectCell", "acceltext", clickStr);
|
||||
SafeSetAttribute("menu_SelectRow", "acceltext", dragStr);
|
||||
SafeSetAttribute("menu_SelectColumn", "acceltext", dragStr);
|
||||
SafeSetAttribute("menu_SelectAllCells", "acceltext", dragStr);
|
||||
// And add "Del" or "Clear"
|
||||
document.getElementById("menu_DeleteCellContents").setAttribute("acceltext",DelStr);
|
||||
SafeSetAttribute("menu_DeleteCellContents", "acceltext", delStr);
|
||||
|
||||
// hide UI that we don't have components for
|
||||
RemoveInapplicableUIElements();
|
||||
|
@ -238,6 +238,13 @@ function EditorShutdown()
|
|||
return editorShell.Shutdown();
|
||||
}
|
||||
|
||||
function SafeSetAttribute(nodeID, attributeName, attributeValue)
|
||||
{
|
||||
var theNode = document.getElementById(nodeID);
|
||||
if (theNode)
|
||||
theNode.setAttribute(attributeName, attributeValue);
|
||||
}
|
||||
|
||||
// We use this alot!
|
||||
function GetString(id)
|
||||
{
|
||||
|
|
|
@ -69,7 +69,9 @@
|
|||
<commandset id="globalEditMenuItems"/>
|
||||
<commandset id="selectEditMenuItems"/>
|
||||
<commandset id="undoEditMenuItems"/>
|
||||
<commandset id="clipboardEditMenuItems"/>
|
||||
|
||||
<commandset id="commonEditorMenuItems"/>
|
||||
<commandset id="composerMenuItems"/>
|
||||
<commandset id="composerEditMenuItems"/>
|
||||
<commandset id="composerSaveMenuItems"/>
|
||||
|
|
|
@ -78,12 +78,11 @@
|
|||
</keyset>
|
||||
|
||||
<!-- commands updated when the editor gets created -->
|
||||
<commandset id="composerMenuItems"
|
||||
<commandset id="commonEditorMenuItems"
|
||||
commandupdater="true"
|
||||
events="create"
|
||||
oncommandupdate="goUpdateComposerMenuItems(this)"
|
||||
>
|
||||
|
||||
<command id="cmd_open" oncommand="goDoCommand('cmd_open')"/>
|
||||
<command id="cmd_openRemote" value="&openremoteCmd.label;" oncommand="goDoCommand('cmd_openRemote')"/>
|
||||
<command id="cmd_close" value="&closeCmd.label;" oncommand="goDoCommand('cmd_close')"/>
|
||||
|
@ -94,7 +93,13 @@
|
|||
<command id="cmd_print_button" buttonaction="goDoCommand('cmd_print')"/>
|
||||
|
||||
<command id="cmd_quit" value="&exitCmd.label;" oncommand="goDoCommand('cmd_quit')"/>
|
||||
</commandset>
|
||||
|
||||
<commandset id="composerMenuItems"
|
||||
commandupdater="true"
|
||||
events="create"
|
||||
oncommandupdate="goUpdateComposerMenuItems(this)"
|
||||
>
|
||||
<!-- format menu -->
|
||||
<command id="cmd_listProperties" oncommand="goDoCommand('cmd_listProperties')"/>
|
||||
<command id="cmd_pageProperties" oncommand="goDoCommand('cmd_pageProperties')"/>
|
||||
|
|
|
@ -1570,14 +1570,14 @@ static void CheckForFocus(nsIDocument* aDocument)
|
|||
|
||||
nsCOMPtr<nsIDOMWindow> domWindow = do_QueryInterface(ourWindow);
|
||||
if (domWindow == focusedWindow) {
|
||||
PRBool active;
|
||||
PRBool active;
|
||||
commandDispatcher->GetActive(&active);
|
||||
commandDispatcher->SetFocusedElement(nsnull);
|
||||
if(active) {
|
||||
commandDispatcher->SetFocusedElement(nsnull);
|
||||
if(active) {
|
||||
// We need to restore focus and make sure we null
|
||||
// out the focused element.
|
||||
domWindow->Focus();
|
||||
}
|
||||
}
|
||||
}
|
||||
commandDispatcher->SetSuppressFocus(PR_FALSE);
|
||||
}
|
||||
|
@ -2839,94 +2839,104 @@ PresShell::DoCopy()
|
|||
{
|
||||
nsCOMPtr<nsIDocument> doc;
|
||||
GetDocument(getter_AddRefs(doc));
|
||||
if (doc) {
|
||||
nsString buffer;
|
||||
nsresult rv;
|
||||
if (!doc) return NS_ERROR_FAILURE;
|
||||
|
||||
nsString buffer;
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsIDOMSelection> sel;
|
||||
|
||||
nsCOMPtr<nsIEventStateManager> manager;
|
||||
nsCOMPtr<nsIContent> content;
|
||||
rv = mPresContext->GetEventStateManager(getter_AddRefs(manager));
|
||||
if (NS_FAILED(rv) || !manager)
|
||||
return rv?rv:NS_ERROR_FAILURE;
|
||||
rv = manager->GetFocusedContent(getter_AddRefs(content));
|
||||
if (NS_SUCCEEDED(rv) && content)
|
||||
nsCOMPtr<nsIDOMSelection> sel;
|
||||
|
||||
nsCOMPtr<nsIEventStateManager> manager;
|
||||
nsCOMPtr<nsIContent> content;
|
||||
rv = mPresContext->GetEventStateManager(getter_AddRefs(manager));
|
||||
if (NS_FAILED(rv) || !manager)
|
||||
return rv?rv:NS_ERROR_FAILURE;
|
||||
rv = manager->GetFocusedContent(getter_AddRefs(content));
|
||||
if (NS_SUCCEEDED(rv) && content)
|
||||
{
|
||||
//check to see if we need to get selection from frame
|
||||
//optimization that MAY need to be expanded as more things implement their own "selection"
|
||||
nsCOMPtr<nsIDOMNSHTMLInputElement> htmlInputElement(do_QueryInterface(content));
|
||||
nsCOMPtr<nsIDOMNSHTMLTextAreaElement> htmlTextAreaElement(do_QueryInterface(content));
|
||||
if (htmlInputElement || htmlTextAreaElement)
|
||||
{
|
||||
//check to see if we need to get selection from frame
|
||||
//optimization that MAY need to be expanded as more things implement their own "selection"
|
||||
nsCOMPtr<nsIDOMNSHTMLInputElement> htmlInputElement(do_QueryInterface(content));
|
||||
nsCOMPtr<nsIDOMNSHTMLTextAreaElement> htmlTextAreaElement(do_QueryInterface(content));
|
||||
if (htmlInputElement || htmlTextAreaElement)
|
||||
{
|
||||
nsIFrame *htmlInputFrame;
|
||||
rv = GetPrimaryFrameFor(content, &htmlInputFrame);
|
||||
if (NS_FAILED(rv) || !htmlInputFrame)
|
||||
return rv?rv:NS_ERROR_FAILURE;
|
||||
nsCOMPtr<nsISelectionController> selCon;
|
||||
rv = htmlInputFrame->GetSelectionController(mPresContext,getter_AddRefs(selCon));
|
||||
if (NS_FAILED(rv) || !selCon)
|
||||
return rv?rv:NS_ERROR_FAILURE;
|
||||
rv = selCon->GetSelection(nsISelectionController::SELECTION_NORMAL, getter_AddRefs(sel));
|
||||
}
|
||||
nsIFrame *htmlInputFrame;
|
||||
rv = GetPrimaryFrameFor(content, &htmlInputFrame);
|
||||
if (NS_FAILED(rv) || !htmlInputFrame)
|
||||
return rv?rv:NS_ERROR_FAILURE;
|
||||
nsCOMPtr<nsISelectionController> selCon;
|
||||
rv = htmlInputFrame->GetSelectionController(mPresContext,getter_AddRefs(selCon));
|
||||
if (NS_FAILED(rv) || !selCon)
|
||||
return rv?rv:NS_ERROR_FAILURE;
|
||||
rv = selCon->GetSelection(nsISelectionController::SELECTION_NORMAL, getter_AddRefs(sel));
|
||||
}
|
||||
if (!sel) //get selection from this PresShell
|
||||
rv = GetSelection(nsISelectionController::SELECTION_NORMAL, getter_AddRefs(sel));
|
||||
|
||||
if (NS_FAILED(rv) || !sel)
|
||||
return rv?rv:NS_ERROR_FAILURE;
|
||||
}
|
||||
if (!sel) //get selection from this PresShell
|
||||
rv = GetSelection(nsISelectionController::SELECTION_NORMAL, getter_AddRefs(sel));
|
||||
|
||||
if (NS_FAILED(rv) || !sel)
|
||||
return rv?rv:NS_ERROR_FAILURE;
|
||||
|
||||
doc->CreateXIF(buffer,sel);
|
||||
doc->CreateXIF(buffer,sel);
|
||||
|
||||
// Get the Clipboard
|
||||
NS_WITH_SERVICE(nsIClipboard, clipboard, kCClipboardCID, &rv);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
// Get the Clipboard
|
||||
NS_WITH_SERVICE(nsIClipboard, clipboard, kCClipboardCID, &rv);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
if ( clipboard ) {
|
||||
// Create a transferable for putting data on the Clipboard
|
||||
nsCOMPtr<nsITransferable> trans;
|
||||
rv = nsComponentManager::CreateInstance(kCTransferableCID, nsnull,
|
||||
NS_GET_IID(nsITransferable),
|
||||
getter_AddRefs(trans));
|
||||
if ( trans ) {
|
||||
// The data on the clipboard will be in "XIF" format
|
||||
// so give the clipboard transferable a "XIFConverter" for
|
||||
// converting from XIF to other formats
|
||||
nsCOMPtr<nsIFormatConverter> xifConverter;
|
||||
rv = nsComponentManager::CreateInstance(kCXIFConverterCID, nsnull,
|
||||
NS_GET_IID(nsIFormatConverter),
|
||||
getter_AddRefs(xifConverter));
|
||||
if ( xifConverter ) {
|
||||
// Add the XIF DataFlavor to the transferable
|
||||
// this tells the transferable that it can handle receiving the XIF format
|
||||
trans->AddDataFlavor(kXIFMime);
|
||||
if ( clipboard ) {
|
||||
// Create a transferable for putting data on the Clipboard
|
||||
nsCOMPtr<nsITransferable> trans;
|
||||
rv = nsComponentManager::CreateInstance(kCTransferableCID, nsnull,
|
||||
NS_GET_IID(nsITransferable),
|
||||
getter_AddRefs(trans));
|
||||
if ( trans ) {
|
||||
// The data on the clipboard will be in "XIF" format
|
||||
// so give the clipboard transferable a "XIFConverter" for
|
||||
// converting from XIF to other formats
|
||||
nsCOMPtr<nsIFormatConverter> xifConverter;
|
||||
rv = nsComponentManager::CreateInstance(kCXIFConverterCID, nsnull,
|
||||
NS_GET_IID(nsIFormatConverter),
|
||||
getter_AddRefs(xifConverter));
|
||||
if ( xifConverter ) {
|
||||
// Add the XIF DataFlavor to the transferable
|
||||
// this tells the transferable that it can handle receiving the XIF format
|
||||
trans->AddDataFlavor(kXIFMime);
|
||||
|
||||
// Add the converter for going from XIF to other formats
|
||||
trans->SetConverter(xifConverter);
|
||||
// Add the converter for going from XIF to other formats
|
||||
trans->SetConverter(xifConverter);
|
||||
|
||||
// Now add the XIF data to the transferable, placing it into a nsISupportsWString object.
|
||||
// the transferable wants the number bytes for the data and since it is double byte
|
||||
// we multiply by 2.
|
||||
nsCOMPtr<nsISupportsWString> dataWrapper;
|
||||
rv = nsComponentManager::CreateInstance(NS_SUPPORTS_WSTRING_PROGID,
|
||||
nsnull,
|
||||
NS_GET_IID(nsISupportsWString),
|
||||
getter_AddRefs(dataWrapper));
|
||||
if ( dataWrapper ) {
|
||||
dataWrapper->SetData ( NS_CONST_CAST(PRUnichar*,buffer.GetUnicode()) );
|
||||
// QI the data object an |nsISupports| so that when the transferable holds
|
||||
// onto it, it will addref the correct interface.
|
||||
nsCOMPtr<nsISupports> genericDataObj ( do_QueryInterface(dataWrapper) );
|
||||
trans->SetTransferData(kXIFMime, genericDataObj, buffer.Length()*2);
|
||||
}
|
||||
|
||||
// put the transferable on the clipboard
|
||||
clipboard->SetData(trans, nsnull, nsIClipboard::kGlobalClipboard);
|
||||
// Now add the XIF data to the transferable, placing it into a nsISupportsWString object.
|
||||
// the transferable wants the number bytes for the data and since it is double byte
|
||||
// we multiply by 2.
|
||||
nsCOMPtr<nsISupportsWString> dataWrapper;
|
||||
rv = nsComponentManager::CreateInstance(NS_SUPPORTS_WSTRING_PROGID,
|
||||
nsnull,
|
||||
NS_GET_IID(nsISupportsWString),
|
||||
getter_AddRefs(dataWrapper));
|
||||
if ( dataWrapper ) {
|
||||
dataWrapper->SetData ( NS_CONST_CAST(PRUnichar*,buffer.GetUnicode()) );
|
||||
// QI the data object an |nsISupports| so that when the transferable holds
|
||||
// onto it, it will addref the correct interface.
|
||||
nsCOMPtr<nsISupports> genericDataObj ( do_QueryInterface(dataWrapper) );
|
||||
trans->SetTransferData(kXIFMime, genericDataObj, buffer.Length()*2);
|
||||
}
|
||||
|
||||
// put the transferable on the clipboard
|
||||
clipboard->SetData(trans, nsnull, nsIClipboard::kGlobalClipboard);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now that we have copied, update the Paste menu item
|
||||
nsCOMPtr<nsIScriptGlobalObject> globalObject;
|
||||
doc->GetScriptGlobalObject(getter_AddRefs(globalObject));
|
||||
nsCOMPtr<nsIDOMWindow> domWindow = do_QueryInterface(globalObject);
|
||||
if (domWindow)
|
||||
{
|
||||
domWindow->UpdateCommands(NS_ConvertASCIItoUCS2("clipboard"));
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -1570,14 +1570,14 @@ static void CheckForFocus(nsIDocument* aDocument)
|
|||
|
||||
nsCOMPtr<nsIDOMWindow> domWindow = do_QueryInterface(ourWindow);
|
||||
if (domWindow == focusedWindow) {
|
||||
PRBool active;
|
||||
PRBool active;
|
||||
commandDispatcher->GetActive(&active);
|
||||
commandDispatcher->SetFocusedElement(nsnull);
|
||||
if(active) {
|
||||
commandDispatcher->SetFocusedElement(nsnull);
|
||||
if(active) {
|
||||
// We need to restore focus and make sure we null
|
||||
// out the focused element.
|
||||
domWindow->Focus();
|
||||
}
|
||||
}
|
||||
}
|
||||
commandDispatcher->SetSuppressFocus(PR_FALSE);
|
||||
}
|
||||
|
@ -2839,94 +2839,104 @@ PresShell::DoCopy()
|
|||
{
|
||||
nsCOMPtr<nsIDocument> doc;
|
||||
GetDocument(getter_AddRefs(doc));
|
||||
if (doc) {
|
||||
nsString buffer;
|
||||
nsresult rv;
|
||||
if (!doc) return NS_ERROR_FAILURE;
|
||||
|
||||
nsString buffer;
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsIDOMSelection> sel;
|
||||
|
||||
nsCOMPtr<nsIEventStateManager> manager;
|
||||
nsCOMPtr<nsIContent> content;
|
||||
rv = mPresContext->GetEventStateManager(getter_AddRefs(manager));
|
||||
if (NS_FAILED(rv) || !manager)
|
||||
return rv?rv:NS_ERROR_FAILURE;
|
||||
rv = manager->GetFocusedContent(getter_AddRefs(content));
|
||||
if (NS_SUCCEEDED(rv) && content)
|
||||
nsCOMPtr<nsIDOMSelection> sel;
|
||||
|
||||
nsCOMPtr<nsIEventStateManager> manager;
|
||||
nsCOMPtr<nsIContent> content;
|
||||
rv = mPresContext->GetEventStateManager(getter_AddRefs(manager));
|
||||
if (NS_FAILED(rv) || !manager)
|
||||
return rv?rv:NS_ERROR_FAILURE;
|
||||
rv = manager->GetFocusedContent(getter_AddRefs(content));
|
||||
if (NS_SUCCEEDED(rv) && content)
|
||||
{
|
||||
//check to see if we need to get selection from frame
|
||||
//optimization that MAY need to be expanded as more things implement their own "selection"
|
||||
nsCOMPtr<nsIDOMNSHTMLInputElement> htmlInputElement(do_QueryInterface(content));
|
||||
nsCOMPtr<nsIDOMNSHTMLTextAreaElement> htmlTextAreaElement(do_QueryInterface(content));
|
||||
if (htmlInputElement || htmlTextAreaElement)
|
||||
{
|
||||
//check to see if we need to get selection from frame
|
||||
//optimization that MAY need to be expanded as more things implement their own "selection"
|
||||
nsCOMPtr<nsIDOMNSHTMLInputElement> htmlInputElement(do_QueryInterface(content));
|
||||
nsCOMPtr<nsIDOMNSHTMLTextAreaElement> htmlTextAreaElement(do_QueryInterface(content));
|
||||
if (htmlInputElement || htmlTextAreaElement)
|
||||
{
|
||||
nsIFrame *htmlInputFrame;
|
||||
rv = GetPrimaryFrameFor(content, &htmlInputFrame);
|
||||
if (NS_FAILED(rv) || !htmlInputFrame)
|
||||
return rv?rv:NS_ERROR_FAILURE;
|
||||
nsCOMPtr<nsISelectionController> selCon;
|
||||
rv = htmlInputFrame->GetSelectionController(mPresContext,getter_AddRefs(selCon));
|
||||
if (NS_FAILED(rv) || !selCon)
|
||||
return rv?rv:NS_ERROR_FAILURE;
|
||||
rv = selCon->GetSelection(nsISelectionController::SELECTION_NORMAL, getter_AddRefs(sel));
|
||||
}
|
||||
nsIFrame *htmlInputFrame;
|
||||
rv = GetPrimaryFrameFor(content, &htmlInputFrame);
|
||||
if (NS_FAILED(rv) || !htmlInputFrame)
|
||||
return rv?rv:NS_ERROR_FAILURE;
|
||||
nsCOMPtr<nsISelectionController> selCon;
|
||||
rv = htmlInputFrame->GetSelectionController(mPresContext,getter_AddRefs(selCon));
|
||||
if (NS_FAILED(rv) || !selCon)
|
||||
return rv?rv:NS_ERROR_FAILURE;
|
||||
rv = selCon->GetSelection(nsISelectionController::SELECTION_NORMAL, getter_AddRefs(sel));
|
||||
}
|
||||
if (!sel) //get selection from this PresShell
|
||||
rv = GetSelection(nsISelectionController::SELECTION_NORMAL, getter_AddRefs(sel));
|
||||
|
||||
if (NS_FAILED(rv) || !sel)
|
||||
return rv?rv:NS_ERROR_FAILURE;
|
||||
}
|
||||
if (!sel) //get selection from this PresShell
|
||||
rv = GetSelection(nsISelectionController::SELECTION_NORMAL, getter_AddRefs(sel));
|
||||
|
||||
if (NS_FAILED(rv) || !sel)
|
||||
return rv?rv:NS_ERROR_FAILURE;
|
||||
|
||||
doc->CreateXIF(buffer,sel);
|
||||
doc->CreateXIF(buffer,sel);
|
||||
|
||||
// Get the Clipboard
|
||||
NS_WITH_SERVICE(nsIClipboard, clipboard, kCClipboardCID, &rv);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
// Get the Clipboard
|
||||
NS_WITH_SERVICE(nsIClipboard, clipboard, kCClipboardCID, &rv);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
if ( clipboard ) {
|
||||
// Create a transferable for putting data on the Clipboard
|
||||
nsCOMPtr<nsITransferable> trans;
|
||||
rv = nsComponentManager::CreateInstance(kCTransferableCID, nsnull,
|
||||
NS_GET_IID(nsITransferable),
|
||||
getter_AddRefs(trans));
|
||||
if ( trans ) {
|
||||
// The data on the clipboard will be in "XIF" format
|
||||
// so give the clipboard transferable a "XIFConverter" for
|
||||
// converting from XIF to other formats
|
||||
nsCOMPtr<nsIFormatConverter> xifConverter;
|
||||
rv = nsComponentManager::CreateInstance(kCXIFConverterCID, nsnull,
|
||||
NS_GET_IID(nsIFormatConverter),
|
||||
getter_AddRefs(xifConverter));
|
||||
if ( xifConverter ) {
|
||||
// Add the XIF DataFlavor to the transferable
|
||||
// this tells the transferable that it can handle receiving the XIF format
|
||||
trans->AddDataFlavor(kXIFMime);
|
||||
if ( clipboard ) {
|
||||
// Create a transferable for putting data on the Clipboard
|
||||
nsCOMPtr<nsITransferable> trans;
|
||||
rv = nsComponentManager::CreateInstance(kCTransferableCID, nsnull,
|
||||
NS_GET_IID(nsITransferable),
|
||||
getter_AddRefs(trans));
|
||||
if ( trans ) {
|
||||
// The data on the clipboard will be in "XIF" format
|
||||
// so give the clipboard transferable a "XIFConverter" for
|
||||
// converting from XIF to other formats
|
||||
nsCOMPtr<nsIFormatConverter> xifConverter;
|
||||
rv = nsComponentManager::CreateInstance(kCXIFConverterCID, nsnull,
|
||||
NS_GET_IID(nsIFormatConverter),
|
||||
getter_AddRefs(xifConverter));
|
||||
if ( xifConverter ) {
|
||||
// Add the XIF DataFlavor to the transferable
|
||||
// this tells the transferable that it can handle receiving the XIF format
|
||||
trans->AddDataFlavor(kXIFMime);
|
||||
|
||||
// Add the converter for going from XIF to other formats
|
||||
trans->SetConverter(xifConverter);
|
||||
// Add the converter for going from XIF to other formats
|
||||
trans->SetConverter(xifConverter);
|
||||
|
||||
// Now add the XIF data to the transferable, placing it into a nsISupportsWString object.
|
||||
// the transferable wants the number bytes for the data and since it is double byte
|
||||
// we multiply by 2.
|
||||
nsCOMPtr<nsISupportsWString> dataWrapper;
|
||||
rv = nsComponentManager::CreateInstance(NS_SUPPORTS_WSTRING_PROGID,
|
||||
nsnull,
|
||||
NS_GET_IID(nsISupportsWString),
|
||||
getter_AddRefs(dataWrapper));
|
||||
if ( dataWrapper ) {
|
||||
dataWrapper->SetData ( NS_CONST_CAST(PRUnichar*,buffer.GetUnicode()) );
|
||||
// QI the data object an |nsISupports| so that when the transferable holds
|
||||
// onto it, it will addref the correct interface.
|
||||
nsCOMPtr<nsISupports> genericDataObj ( do_QueryInterface(dataWrapper) );
|
||||
trans->SetTransferData(kXIFMime, genericDataObj, buffer.Length()*2);
|
||||
}
|
||||
|
||||
// put the transferable on the clipboard
|
||||
clipboard->SetData(trans, nsnull, nsIClipboard::kGlobalClipboard);
|
||||
// Now add the XIF data to the transferable, placing it into a nsISupportsWString object.
|
||||
// the transferable wants the number bytes for the data and since it is double byte
|
||||
// we multiply by 2.
|
||||
nsCOMPtr<nsISupportsWString> dataWrapper;
|
||||
rv = nsComponentManager::CreateInstance(NS_SUPPORTS_WSTRING_PROGID,
|
||||
nsnull,
|
||||
NS_GET_IID(nsISupportsWString),
|
||||
getter_AddRefs(dataWrapper));
|
||||
if ( dataWrapper ) {
|
||||
dataWrapper->SetData ( NS_CONST_CAST(PRUnichar*,buffer.GetUnicode()) );
|
||||
// QI the data object an |nsISupports| so that when the transferable holds
|
||||
// onto it, it will addref the correct interface.
|
||||
nsCOMPtr<nsISupports> genericDataObj ( do_QueryInterface(dataWrapper) );
|
||||
trans->SetTransferData(kXIFMime, genericDataObj, buffer.Length()*2);
|
||||
}
|
||||
|
||||
// put the transferable on the clipboard
|
||||
clipboard->SetData(trans, nsnull, nsIClipboard::kGlobalClipboard);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now that we have copied, update the Paste menu item
|
||||
nsCOMPtr<nsIScriptGlobalObject> globalObject;
|
||||
doc->GetScriptGlobalObject(getter_AddRefs(globalObject));
|
||||
nsCOMPtr<nsIDOMWindow> domWindow = do_QueryInterface(globalObject);
|
||||
if (domWindow)
|
||||
{
|
||||
domWindow->UpdateCommands(NS_ConvertASCIItoUCS2("clipboard"));
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -93,6 +93,8 @@
|
|||
#include "nsIDOMWindow.h" //needed for notify selection changed to update the menus ect.
|
||||
#include "nsITextContent.h" //needed to create initial text control content
|
||||
|
||||
#include "nsITransactionManager.h"
|
||||
#include "nsITransactionListener.h"
|
||||
|
||||
#define DEFAULT_COLUMN_WIDTH 20
|
||||
|
||||
|
@ -122,7 +124,12 @@ static nsresult GetElementFactoryService(nsIElementFactory **aFactory)
|
|||
|
||||
//listen for the return key. kinda lame.
|
||||
//listen for onchange notifications
|
||||
class nsTextInputListener : public nsIDOMKeyListener, public nsSupportsWeakReference, public nsIDOMSelectionListener, public nsIDocumentObserver, public nsIDOMFocusListener
|
||||
class nsTextInputListener : public nsIDOMKeyListener,
|
||||
public nsIDOMSelectionListener,
|
||||
public nsIDOMFocusListener,
|
||||
public nsIDocumentObserver,
|
||||
public nsITransactionListener,
|
||||
public nsSupportsWeakReference
|
||||
{
|
||||
public:
|
||||
/** the default constructor
|
||||
|
@ -216,6 +223,30 @@ public:
|
|||
/* END interfaces from nsIDOMFocusListener*/
|
||||
|
||||
|
||||
/** nsITransactionListener interfaces
|
||||
*/
|
||||
|
||||
NS_IMETHOD WillDo(nsITransactionManager *aManager, nsITransaction *aTransaction, PRBool *aInterrupt);
|
||||
NS_IMETHOD DidDo(nsITransactionManager *aManager, nsITransaction *aTransaction, nsresult aDoResult);
|
||||
NS_IMETHOD WillUndo(nsITransactionManager *aManager, nsITransaction *aTransaction, PRBool *aInterrupt);
|
||||
NS_IMETHOD DidUndo(nsITransactionManager *aManager, nsITransaction *aTransaction, nsresult aUndoResult);
|
||||
NS_IMETHOD WillRedo(nsITransactionManager *aManager, nsITransaction *aTransaction, PRBool *aInterrupt);
|
||||
NS_IMETHOD DidRedo(nsITransactionManager *aManager, nsITransaction *aTransaction, nsresult aRedoResult);
|
||||
NS_IMETHOD WillBeginBatch(nsITransactionManager *aManager, PRBool *aInterrupt);
|
||||
NS_IMETHOD DidBeginBatch(nsITransactionManager *aManager, nsresult aResult);
|
||||
NS_IMETHOD WillEndBatch(nsITransactionManager *aManager, PRBool *aInterrupt);
|
||||
NS_IMETHOD DidEndBatch(nsITransactionManager *aManager, nsresult aResult);
|
||||
NS_IMETHOD WillMerge(nsITransactionManager *aManager, nsITransaction *aTopTransaction,
|
||||
nsITransaction *aTransactionToMerge, PRBool *aInterrupt);
|
||||
NS_IMETHOD DidMerge(nsITransactionManager *aManager, nsITransaction *aTopTransaction,
|
||||
nsITransaction *aTransactionToMerge,
|
||||
PRBool aDidMerge, nsresult aMergeResult);
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
nsresult UpdateTextInputCommands(const nsString& commandsToUpdate);
|
||||
|
||||
protected:
|
||||
|
||||
nsGfxTextControlFrame2* mFrame; // weak reference
|
||||
|
@ -223,6 +254,9 @@ protected:
|
|||
|
||||
PRPackedBool mSelectionWasCollapsed;
|
||||
PRPackedBool mKnowSelectionCollapsed;
|
||||
|
||||
PRPackedBool mFirstDoOfFirstUndo;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -250,7 +284,13 @@ nsTextInputListener::~nsTextInputListener()
|
|||
}
|
||||
|
||||
|
||||
NS_IMPL_QUERY_INTERFACE5(nsTextInputListener, nsIDOMKeyListener, nsISupportsWeakReference, nsIDOMSelectionListener, nsIDocumentObserver, nsIDOMFocusListener)
|
||||
NS_IMPL_QUERY_INTERFACE6(nsTextInputListener,
|
||||
nsIDOMKeyListener,
|
||||
nsIDOMSelectionListener,
|
||||
nsIDOMFocusListener,
|
||||
nsIDocumentObserver,
|
||||
nsITransactionListener,
|
||||
nsISupportsWeakReference)
|
||||
|
||||
|
||||
nsresult
|
||||
|
@ -326,28 +366,9 @@ nsTextInputListener::NotifySelectionChanged(nsIDOMDocument* aDoc, nsIDOMSelectio
|
|||
mSelectionWasCollapsed = collapsed;
|
||||
mKnowSelectionCollapsed = PR_TRUE;
|
||||
|
||||
nsCOMPtr<nsIContent> content;
|
||||
nsresult rv = mFrame->GetContent(getter_AddRefs(content));
|
||||
if (NS_FAILED(rv) || !content )
|
||||
return rv?rv:NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIDocument> doc;
|
||||
rv = content->GetDocument(*getter_AddRefs(doc));
|
||||
if (NS_FAILED(rv) || !doc )
|
||||
return rv?rv:NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIScriptGlobalObject> scriptGlobalObject;
|
||||
rv = doc->GetScriptGlobalObject(getter_AddRefs(scriptGlobalObject));
|
||||
if (NS_FAILED(rv) || !scriptGlobalObject )
|
||||
return rv?rv:NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIDOMWindow> domWindow = do_QueryInterface(scriptGlobalObject, &rv);
|
||||
if (NS_FAILED(rv) || !domWindow )
|
||||
return rv?rv:NS_ERROR_FAILURE;
|
||||
|
||||
return domWindow->UpdateCommands(NS_ConvertASCIItoUCS2("select"));
|
||||
|
||||
return UpdateTextInputCommands(NS_ConvertASCIItoUCS2("select"));
|
||||
}
|
||||
|
||||
//DOCUMENT INTERFACE
|
||||
|
||||
NS_IMETHODIMP nsTextInputListener::ContentChanged(nsIDocument *aDocument,
|
||||
|
@ -422,6 +443,7 @@ nsresult
|
|||
nsTextInputListener::Focus(nsIDOMEvent* aEvent)
|
||||
{
|
||||
nsCOMPtr<nsIContent> content;
|
||||
|
||||
if (NS_SUCCEEDED(mFrame->GetContent(getter_AddRefs(content))) && content)
|
||||
{
|
||||
nsCOMPtr<nsIDocument> doc;
|
||||
|
@ -430,7 +452,11 @@ nsTextInputListener::Focus(nsIDOMEvent* aEvent)
|
|||
doc->AddObserver(this);
|
||||
}
|
||||
}
|
||||
return mFrame->GetText(&mFocusedValue, PR_FALSE);
|
||||
|
||||
nsresult rv = mFrame->GetText(&mFocusedValue, PR_FALSE);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -438,12 +464,14 @@ nsTextInputListener::Blur (nsIDOMEvent* aEvent)
|
|||
{
|
||||
if (!mFrame)
|
||||
return NS_OK;
|
||||
|
||||
nsAutoString blurValue;
|
||||
mFrame->GetText(&blurValue,PR_FALSE);
|
||||
if (mFocusedValue.Compare(blurValue))//different fire onchange
|
||||
{
|
||||
return mFrame->CallOnChange();
|
||||
mFrame->CallOnChange();
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIContent> content;
|
||||
if (NS_SUCCEEDED(mFrame->GetContent(getter_AddRefs(content))) && content)
|
||||
{
|
||||
|
@ -460,8 +488,134 @@ nsTextInputListener::Blur (nsIDOMEvent* aEvent)
|
|||
|
||||
//END focuslistener
|
||||
|
||||
NS_IMETHODIMP nsTextInputListener::WillDo(nsITransactionManager *aManager,
|
||||
nsITransaction *aTransaction, PRBool *aInterrupt)
|
||||
{
|
||||
*aInterrupt = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsTextInputListener::DidDo(nsITransactionManager *aManager,
|
||||
nsITransaction *aTransaction, nsresult aDoResult)
|
||||
{
|
||||
// we only need to update if the undo count is now 1
|
||||
PRInt32 undoCount;
|
||||
aManager->GetNumberOfUndoItems(&undoCount);
|
||||
if (undoCount == 1)
|
||||
{
|
||||
if (mFirstDoOfFirstUndo)
|
||||
UpdateTextInputCommands(NS_ConvertASCIItoUCS2("undo"));
|
||||
|
||||
mFirstDoOfFirstUndo = PR_FALSE;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsTextInputListener::WillUndo(nsITransactionManager *aManager,
|
||||
nsITransaction *aTransaction, PRBool *aInterrupt)
|
||||
{
|
||||
*aInterrupt = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsTextInputListener::DidUndo(nsITransactionManager *aManager,
|
||||
nsITransaction *aTransaction, nsresult aUndoResult)
|
||||
{
|
||||
PRInt32 undoCount;
|
||||
aManager->GetNumberOfUndoItems(&undoCount);
|
||||
if (undoCount == 0)
|
||||
mFirstDoOfFirstUndo = PR_TRUE; // reset the state for the next do
|
||||
|
||||
UpdateTextInputCommands(NS_ConvertASCIItoUCS2("undo"));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsTextInputListener::WillRedo(nsITransactionManager *aManager,
|
||||
nsITransaction *aTransaction, PRBool *aInterrupt)
|
||||
{
|
||||
*aInterrupt = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsTextInputListener::DidRedo(nsITransactionManager *aManager,
|
||||
nsITransaction *aTransaction, nsresult aRedoResult)
|
||||
{
|
||||
UpdateTextInputCommands(NS_ConvertASCIItoUCS2("undo"));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsTextInputListener::WillBeginBatch(nsITransactionManager *aManager, PRBool *aInterrupt)
|
||||
{
|
||||
*aInterrupt = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsTextInputListener::DidBeginBatch(nsITransactionManager *aManager, nsresult aResult)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsTextInputListener::WillEndBatch(nsITransactionManager *aManager, PRBool *aInterrupt)
|
||||
{
|
||||
*aInterrupt = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsTextInputListener::DidEndBatch(nsITransactionManager *aManager, nsresult aResult)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsTextInputListener::WillMerge(nsITransactionManager *aManager,
|
||||
nsITransaction *aTopTransaction, nsITransaction *aTransactionToMerge, PRBool *aInterrupt)
|
||||
{
|
||||
*aInterrupt = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsTextInputListener::DidMerge(nsITransactionManager *aManager,
|
||||
nsITransaction *aTopTransaction, nsITransaction *aTransactionToMerge,
|
||||
PRBool aDidMerge, nsresult aMergeResult)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
nsresult nsTextInputListener::UpdateTextInputCommands(const nsString& commandsToUpdate)
|
||||
{
|
||||
if (!mFrame) return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
nsCOMPtr<nsIContent> content;
|
||||
nsresult rv = mFrame->GetContent(getter_AddRefs(content));
|
||||
if (NS_FAILED(rv) || !content )
|
||||
return rv?rv:NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIDocument> doc;
|
||||
rv = content->GetDocument(*getter_AddRefs(doc));
|
||||
if (NS_FAILED(rv) || !doc )
|
||||
return rv?rv:NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIScriptGlobalObject> scriptGlobalObject;
|
||||
rv = doc->GetScriptGlobalObject(getter_AddRefs(scriptGlobalObject));
|
||||
if (NS_FAILED(rv) || !scriptGlobalObject )
|
||||
return rv?rv:NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIDOMWindow> domWindow = do_QueryInterface(scriptGlobalObject, &rv);
|
||||
if (NS_FAILED(rv) || !domWindow )
|
||||
return rv?rv:NS_ERROR_FAILURE;
|
||||
|
||||
return domWindow->UpdateCommands(commandsToUpdate);
|
||||
}
|
||||
|
||||
|
||||
//END NSTEXTINPUTLISTENER
|
||||
|
||||
#ifdef XP_MAC
|
||||
#pragma mark -
|
||||
#endif
|
||||
|
||||
class nsTextInputSelectionImpl : public nsSupportsWeakReference, public nsISelectionController, public nsIFrameSelection
|
||||
{
|
||||
|
@ -1014,7 +1168,7 @@ nsGfxTextControlFrame2::Destroy(nsIPresContext* aPresContext)
|
|||
if (NS_FAILED(rv) || !shell)
|
||||
return rv?rv:NS_ERROR_FAILURE;
|
||||
|
||||
//get the document
|
||||
// get the document
|
||||
nsCOMPtr<nsIDocument> doc;
|
||||
rv = shell->GetDocument(getter_AddRefs(doc));
|
||||
if (NS_FAILED(rv) || !doc)
|
||||
|
@ -1618,11 +1772,22 @@ nsGfxTextControlFrame2::CreateAnonymousContent(nsIPresContext* aPresContext,
|
|||
domSelection->AddSelectionListener(listener);
|
||||
}
|
||||
}
|
||||
listener = do_QueryInterface(NS_REINTERPRET_CAST(nsISupports *,mTextListener));//ambiguous
|
||||
if (listener)
|
||||
domSelection->AddSelectionListener(listener);
|
||||
}
|
||||
|
||||
domSelection->AddSelectionListener(NS_STATIC_CAST(nsIDOMSelectionListener *, mTextListener));
|
||||
}
|
||||
|
||||
// also set up the text listener as a transaction listener on the editor
|
||||
if (mEditor && mTextListener)
|
||||
{
|
||||
nsCOMPtr<nsITransactionManager> txMgr;
|
||||
rv = mEditor->GetTransactionManager(getter_AddRefs(txMgr));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (!txMgr) return NS_ERROR_NULL_POINTER;
|
||||
|
||||
rv = txMgr->AddListener(NS_STATIC_CAST(nsITransactionListener*, mTextListener));
|
||||
if (NS_FAILED(rv)) rv;
|
||||
}
|
||||
|
||||
// Get the default value for the textfield.
|
||||
|
||||
nsAutoString defaultValue;
|
||||
|
@ -1671,7 +1836,6 @@ nsGfxTextControlFrame2::CreateAnonymousContent(nsIPresContext* aPresContext,
|
|||
return rv;
|
||||
}
|
||||
|
||||
|
||||
if (mContent)
|
||||
{
|
||||
rv = mEditor->GetFlags(&editorFlags);
|
||||
|
|
|
@ -72,6 +72,7 @@ Rights Reserved.
|
|||
<commandset id="globalEditMenuItems"/>
|
||||
<commandset id="selectEditMenuItems"/>
|
||||
<commandset id="undoEditMenuItems"/>
|
||||
<commandset id="clipboardEditMenuItems"/>
|
||||
</commands>
|
||||
|
||||
<broadcasterset id="broadcasterset"/>
|
||||
|
|
|
@ -78,6 +78,7 @@ Rights Reserved.
|
|||
<commandset id="globalEditMenuItems"/>
|
||||
<commandset id="selectEditMenuItems"/>
|
||||
<commandset id="undoEditMenuItems"/>
|
||||
<commandset id="clipboardEditMenuItems"/>
|
||||
</commands>
|
||||
|
||||
<broadcasterset id="broadcasterset"/>
|
||||
|
|
|
@ -80,7 +80,9 @@ Rights Reserved.
|
|||
<commandset id="globalEditMenuItems"/>
|
||||
<commandset id="selectEditMenuItems"/>
|
||||
<commandset id="undoEditMenuItems"/>
|
||||
<commandset id="clipboardEditMenuItems"/>
|
||||
|
||||
<commandset id="commonEditorMenuItems"/>
|
||||
<commandset id="composerMenuItems"/>
|
||||
<commandset id="composerEditMenuItems"/>
|
||||
<commandset id="composerSaveMenuItems"/>
|
||||
|
@ -158,6 +160,7 @@ Rights Reserved.
|
|||
<!--- REMOVE KEYSET UNTIL IT WORKS CORRECTLY ON MAC!
|
||||
ACTUALLY, EVERY TIME YOU TYPE ANY OF THE KEY DEFINED HERE AFTER WITHOUT ANY OF THE MODIFIERS PRESSED, THE COMMAND IS EXECUTED.
|
||||
|
||||
These also need to call goDoCommand(), not editor JS functions. - - smfr
|
||||
<keyset id="defaultKeySet">
|
||||
<key id="acmdkey" disabled="false" shift="false" xulkey="true" alt="false" key="a" onkeypress="EditorSelectAll()" />
|
||||
<key id="bcmdkey" disabled="false" shift="false" xulkey="true" alt="false" key="b" onkeypress="EditorApplyStyle('b')"/>
|
||||
|
|
|
@ -75,6 +75,7 @@ Contributor(s): ______________________________________. -->
|
|||
<commandset id="globalEditMenuItems"/>
|
||||
<commandset id="selectEditMenuItems"/>
|
||||
<commandset id="undoEditMenuItems"/>
|
||||
<commandset id="clipboardEditMenuItems"/>
|
||||
</commands>
|
||||
|
||||
<!-- broadcasters are appended from the overlay -->
|
||||
|
|
|
@ -205,7 +205,6 @@ function goUpdateGlobalEditMenuItems()
|
|||
goUpdateCommand('cmd_cut');
|
||||
goUpdateCommand('cmd_copy');
|
||||
goUpdateCommand('cmd_paste');
|
||||
goUpdateCommand('cmd_pasteQuote');
|
||||
goUpdateCommand('cmd_selectAll');
|
||||
goUpdateCommand('cmd_delete');
|
||||
}
|
||||
|
@ -225,10 +224,13 @@ function goUpdateUndoEditMenuItems()
|
|||
//dump("Updating undo/redo menu items\n");
|
||||
goUpdateCommand('cmd_undo');
|
||||
goUpdateCommand('cmd_redo');
|
||||
}
|
||||
|
||||
// we shouldn't really do this here, but we don't get the right notifications now
|
||||
// update menu items that depend on clipboard contents
|
||||
function goUpdatePasteMenuItems()
|
||||
{
|
||||
//dump("Updating clipboard menu items\n");
|
||||
goUpdateCommand('cmd_paste');
|
||||
goUpdateCommand('cmd_pasteQuote');
|
||||
}
|
||||
|
||||
// This used to be BrowserNewEditorWindow in navigator.js
|
||||
|
|
|
@ -72,6 +72,11 @@
|
|||
commandupdater="true"
|
||||
events="undo"
|
||||
oncommandupdate="goUpdateUndoEditMenuItems()"/>
|
||||
|
||||
<commandset id="clipboardEditMenuItems"
|
||||
commandupdater="true"
|
||||
events="clipboard"
|
||||
oncommandupdate="goUpdatePasteMenuItems()"/>
|
||||
|
||||
<broadcaster id="cmd_undo"
|
||||
oncommand="goDoCommand('cmd_undo')"
|
||||
|
|
Загрузка…
Ссылка в новой задаче