📄 webeditorclient.mm
字号:
case EditActionJustify: return UI_STRING_KEY("Justify", "Justify (Undo action name)", "Undo action name"); case EditActionSetWritingDirection: return UI_STRING_KEY("Set Writing Direction", "Set Writing Direction (Undo action name)", "Undo action name"); case EditActionSubscript: return UI_STRING_KEY("Subscript", "Subscript (Undo action name)", "Undo action name"); case EditActionSuperscript: return UI_STRING_KEY("Superscript", "Superscript (Undo action name)", "Undo action name"); case EditActionUnderline: return UI_STRING_KEY("Underline", "Underline (Undo action name)", "Undo action name"); case EditActionOutline: return UI_STRING_KEY("Outline", "Outline (Undo action name)", "Undo action name"); case EditActionUnscript: return UI_STRING_KEY("Unscript", "Unscript (Undo action name)", "Undo action name"); case EditActionDrag: return UI_STRING_KEY("Drag", "Drag (Undo action name)", "Undo action name"); case EditActionCut: return UI_STRING_KEY("Cut", "Cut (Undo action name)", "Undo action name"); case EditActionPaste: return UI_STRING_KEY("Paste", "Paste (Undo action name)", "Undo action name"); case EditActionPasteFont: return UI_STRING_KEY("Paste Font", "Paste Font (Undo action name)", "Undo action name"); case EditActionPasteRuler: return UI_STRING_KEY("Paste Ruler", "Paste Ruler (Undo action name)", "Undo action name"); case EditActionTyping: return UI_STRING_KEY("Typing", "Typing (Undo action name)", "Undo action name"); case EditActionCreateLink: return UI_STRING_KEY("Create Link", "Create Link (Undo action name)", "Undo action name"); case EditActionUnlink: return UI_STRING_KEY("Unlink", "Unlink (Undo action name)", "Undo action name"); case EditActionInsertList: return UI_STRING_KEY("Insert List", "Insert List (Undo action name)", "Undo action name"); case EditActionFormatBlock: return UI_STRING_KEY("Formatting", "Format Block (Undo action name)", "Undo action name"); case EditActionIndent: return UI_STRING_KEY("Indent", "Indent (Undo action name)", "Undo action name"); case EditActionOutdent: return UI_STRING_KEY("Outdent", "Outdent (Undo action name)", "Undo action name"); } return nil;}void WebEditorClient::registerCommandForUndoOrRedo(PassRefPtr<EditCommand> cmd, bool isRedo){ ASSERT(cmd); NSUndoManager *undoManager = [m_webView undoManager]; NSString *actionName = undoNameForEditAction(cmd->editingAction()); WebEditCommand *command = [WebEditCommand commandWithEditCommand:cmd]; [undoManager registerUndoWithTarget:m_undoTarget.get() selector:(isRedo ? @selector(redoEditing:) : @selector(undoEditing:)) object:command]; if (actionName) [undoManager setActionName:actionName]; m_haveUndoRedoOperations = YES;}void WebEditorClient::registerCommandForUndo(PassRefPtr<EditCommand> cmd){ registerCommandForUndoOrRedo(cmd, false);}void WebEditorClient::registerCommandForRedo(PassRefPtr<EditCommand> cmd){ registerCommandForUndoOrRedo(cmd, true);}void WebEditorClient::clearUndoRedoOperations(){ if (m_haveUndoRedoOperations) { // workaround for <rdar://problem/4645507> NSUndoManager dies // with uncaught exception when undo items cleared while // groups are open NSUndoManager *undoManager = [m_webView undoManager]; int groupingLevel = [undoManager groupingLevel]; for (int i = 0; i < groupingLevel; ++i) [undoManager endUndoGrouping]; [undoManager removeAllActionsWithTarget:m_undoTarget.get()]; for (int i = 0; i < groupingLevel; ++i) [undoManager beginUndoGrouping]; m_haveUndoRedoOperations = NO; } }bool WebEditorClient::canUndo() const{ return [[m_webView undoManager] canUndo];}bool WebEditorClient::canRedo() const{ return [[m_webView undoManager] canRedo];}void WebEditorClient::undo(){ if (canUndo()) [[m_webView undoManager] undo];}void WebEditorClient::redo(){ if (canRedo()) [[m_webView undoManager] redo]; }void WebEditorClient::handleKeyboardEvent(KeyboardEvent* event){ Frame* frame = event->target()->toNode()->document()->frame(); WebHTMLView *webHTMLView = [[kit(frame) frameView] documentView]; if ([webHTMLView _interceptEditingKeyEvent:event shouldSaveCommand:NO]) event->setDefaultHandled();}void WebEditorClient::handleInputMethodKeydown(KeyboardEvent* event){ Frame* frame = event->target()->toNode()->document()->frame(); WebHTMLView *webHTMLView = [[kit(frame) frameView] documentView]; if ([webHTMLView _interceptEditingKeyEvent:event shouldSaveCommand:YES]) event->setDefaultHandled();}#define FormDelegateLog(ctrl) LOG(FormDelegate, "control=%@", ctrl)void WebEditorClient::textFieldDidBeginEditing(Element* element){ if (!element->isHTMLElement()) return; DOMHTMLInputElement* inputElement = [DOMHTMLInputElement _wrapHTMLInputElement:(HTMLInputElement*)element]; FormDelegateLog(inputElement); CallFormDelegate(m_webView, @selector(textFieldDidBeginEditing:inFrame:), inputElement, kit(element->document()->frame()));}void WebEditorClient::textFieldDidEndEditing(Element* element){ if (!element->isHTMLElement()) return; DOMHTMLInputElement* inputElement = [DOMHTMLInputElement _wrapHTMLInputElement:(HTMLInputElement*)element]; FormDelegateLog(inputElement); CallFormDelegate(m_webView, @selector(textFieldDidEndEditing:inFrame:), inputElement, kit(element->document()->frame()));} void WebEditorClient::textDidChangeInTextField(Element* element){ if (!element->isHTMLElement()) return; DOMHTMLInputElement* inputElement = [DOMHTMLInputElement _wrapHTMLInputElement:(HTMLInputElement*)element]; FormDelegateLog(inputElement); CallFormDelegate(m_webView, @selector(textDidChangeInTextField:inFrame:), inputElement, kit(element->document()->frame()));}static SEL selectorForKeyEvent(KeyboardEvent* event){ // FIXME: This helper function is for the auto-fill code so we can pass a selector to the form delegate. // Eventually, we should move all of the auto-fill code down to WebKit and remove the need for this function by // not relying on the selector in the new implementation. // The key identifiers are from <http://www.w3.org/TR/DOM-Level-3-Events/keyset.html#KeySet-Set> String key = event->keyIdentifier(); if (key == "Up") return @selector(moveUp:); if (key == "Down") return @selector(moveDown:); if (key == "U+001B") return @selector(cancel:); if (key == "U+0009") { if (event->shiftKey()) return @selector(insertBacktab:); return @selector(insertTab:); } if (key == "Enter") return @selector(insertNewline:); return 0;}bool WebEditorClient::doTextFieldCommandFromEvent(Element* element, KeyboardEvent* event){ if (!element->isHTMLElement()) return NO; DOMHTMLInputElement* inputElement = [DOMHTMLInputElement _wrapHTMLInputElement:(HTMLInputElement*)element]; FormDelegateLog(inputElement); if (SEL commandSelector = selectorForKeyEvent(event)) return CallFormDelegateReturningBoolean(NO, m_webView, @selector(textField:doCommandBySelector:inFrame:), inputElement, commandSelector, kit(element->document()->frame())); return NO;}void WebEditorClient::textWillBeDeletedInTextField(Element* element){ if (!element->isHTMLElement()) return; DOMHTMLInputElement* inputElement = [DOMHTMLInputElement _wrapHTMLInputElement:(HTMLInputElement*)element]; FormDelegateLog(inputElement); // We're using the deleteBackward selector for all deletion operations since the autofill code treats all deletions the same way. CallFormDelegateReturningBoolean(NO, m_webView, @selector(textField:doCommandBySelector:inFrame:), inputElement, @selector(deleteBackward:), kit(element->document()->frame()));}void WebEditorClient::textDidChangeInTextArea(Element* element){ if (!element->isHTMLElement()) return; DOMHTMLTextAreaElement* textAreaElement = [DOMHTMLTextAreaElement _wrapHTMLTextAreaElement:(HTMLTextAreaElement*)element]; FormDelegateLog(textAreaElement); CallFormDelegate(m_webView, @selector(textDidChangeInTextArea:inFrame:), textAreaElement, kit(element->document()->frame()));}void WebEditorClient::ignoreWordInSpellDocument(const String& text){ [[NSSpellChecker sharedSpellChecker] ignoreWord:text inSpellDocumentWithTag:spellCheckerDocumentTag()];}void WebEditorClient::learnWord(const String& text){ [[NSSpellChecker sharedSpellChecker] learnWord:text];}void WebEditorClient::checkSpellingOfString(const UChar* text, int length, int* misspellingLocation, int* misspellingLength){ NSString* textString = [[NSString alloc] initWithCharactersNoCopy:const_cast<UChar*>(text) length:length freeWhenDone:NO]; NSRange range = [[NSSpellChecker sharedSpellChecker] checkSpellingOfString:textString startingAt:0 language:nil wrap:NO inSpellDocumentWithTag:spellCheckerDocumentTag() wordCount:NULL]; [textString release]; if (misspellingLocation) { // WebCore expects -1 to represent "not found" if (range.location == NSNotFound) *misspellingLocation = -1; else *misspellingLocation = range.location; } if (misspellingLength) *misspellingLength = range.length;}void WebEditorClient::checkGrammarOfString(const UChar* text, int length, Vector<GrammarDetail>& details, int* badGrammarLocation, int* badGrammarLength){#ifndef BUILDING_ON_TIGER NSArray *grammarDetails; NSString* textString = [[NSString alloc] initWithCharactersNoCopy:const_cast<UChar*>(text) length:length freeWhenDone:NO]; NSRange range = [[NSSpellChecker sharedSpellChecker] checkGrammarOfString:textString startingAt:0 language:nil wrap:NO inSpellDocumentWithTag:spellCheckerDocumentTag() details:&grammarDetails]; [textString release]; if (badGrammarLocation) // WebCore expects -1 to represent "not found" *badGrammarLocation = (range.location == NSNotFound) ? -1 : range.location; if (badGrammarLength) *badGrammarLength = range.length; for (NSDictionary *detail in grammarDetails) { ASSERT(detail); GrammarDetail grammarDetail; NSValue *detailRangeAsNSValue = [detail objectForKey:NSGrammarRange]; ASSERT(detailRangeAsNSValue); NSRange detailNSRange = [detailRangeAsNSValue rangeValue]; ASSERT(detailNSRange.location != NSNotFound && detailNSRange.length > 0); grammarDetail.location = detailNSRange.location; grammarDetail.length = detailNSRange.length; grammarDetail.userDescription = [detail objectForKey:NSGrammarUserDescription]; NSArray *guesses = [detail objectForKey:NSGrammarCorrections]; for (NSString *guess in guesses) grammarDetail.guesses.append(String(guess)); details.append(grammarDetail); }#endif}void WebEditorClient::checkSpellingAndGrammarOfParagraph(const UChar* text, int length, bool checkGrammar, Vector<TextCheckingResult>& results){#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) NSString *textString = [[NSString alloc] initWithCharactersNoCopy:const_cast<UChar*>(text) length:length freeWhenDone:NO]; NSTextCheckingTypes checkingTypes = checkGrammar ? (NSTextCheckingTypeOrthography | NSTextCheckingTypeSpelling | NSTextCheckingTypeGrammar) : (NSTextCheckingTypeOrthography | NSTextCheckingTypeSpelling); NSArray *incomingResults = [[NSSpellChecker sharedSpellChecker] checkString:textString range:NSMakeRange(0, [textString length]) types:checkingTypes options:nil inSpellDocumentWithTag:spellCheckerDocumentTag() orthography:NULL wordCount:NULL]; [textString release]; for (NSTextCheckingResult *incomingResult in incomingResults) { NSRange resultRange = [incomingResult range]; NSTextCheckingType resultType = [incomingResult resultType]; ASSERT(resultRange.location != NSNotFound && resultRange.length > 0); if (NSTextCheckingTypeSpelling == resultType) { TextCheckingResult result; result.resultType = 1; result.location = resultRange.location; result.length = resultRange.length; results.append(result); } else if (checkGrammar && NSTextCheckingTypeGrammar == resultType) { TextCheckingResult result; NSArray *details = [incomingResult grammarDetails]; result.resultType = 2; result.location = resultRange.location; result.length = resultRange.length; for (NSDictionary *incomingDetail in details) { ASSERT(incomingDetail); GrammarDetail detail; NSValue *detailRangeAsNSValue = [incomingDetail objectForKey:NSGrammarRange]; ASSERT(detailRangeAsNSValue); NSRange detailNSRange = [detailRangeAsNSValue rangeValue]; ASSERT(detailNSRange.location != NSNotFound && detailNSRange.length > 0); detail.location = detailNSRange.location; detail.length = detailNSRange.length; detail.userDescription = [incomingDetail objectForKey:NSGrammarUserDescription]; NSArray *guesses = [incomingDetail objectForKey:NSGrammarCorrections]; for (NSString *guess in guesses) detail.guesses.append(String(guess)); result.details.append(detail); } results.append(result); } }#endif}void WebEditorClient::updateSpellingUIWithGrammarString(const String& badGrammarPhrase, const GrammarDetail& grammarDetail){#ifndef BUILDING_ON_TIGER NSMutableArray* corrections = [NSMutableArray array]; for (unsigned i = 0; i < grammarDetail.guesses.size(); i++) { NSString* guess = grammarDetail.guesses[i]; [corrections addObject:guess]; } NSRange grammarRange = NSMakeRange(grammarDetail.location, grammarDetail.length); NSString* grammarUserDescription = grammarDetail.userDescription; NSMutableDictionary* grammarDetailDict = [NSDictionary dictionaryWithObjectsAndKeys:[NSValue valueWithRange:grammarRange], NSGrammarRange, grammarUserDescription, NSGrammarUserDescription, corrections, NSGrammarCorrections, nil]; [[NSSpellChecker sharedSpellChecker] updateSpellingPanelWithGrammarString:badGrammarPhrase detail:grammarDetailDict];#endif}void WebEditorClient::updateSpellingUIWithMisspelledWord(const String& misspelledWord){ [[NSSpellChecker sharedSpellChecker] updateSpellingPanelWithMisspelledWord:misspelledWord];}void WebEditorClient::showSpellingUI(bool show){ NSPanel *spellingPanel = [[NSSpellChecker sharedSpellChecker] spellingPanel]; if (show) [spellingPanel orderFront:nil]; else [spellingPanel orderOut:nil];}bool WebEditorClient::spellingUIIsShowing(){ return [[[NSSpellChecker sharedSpellChecker] spellingPanel] isVisible];}void WebEditorClient::getGuessesForWord(const String& word, WTF::Vector<String>& guesses){ NSArray* stringsArray = [[NSSpellChecker sharedSpellChecker] guessesForWord:word]; unsigned count = [stringsArray count]; guesses.clear(); if (count > 0) { NSEnumerator* enumerator = [stringsArray objectEnumerator]; NSString* string; while ((string = [enumerator nextObject]) != nil) guesses.append(string); }}void WebEditorClient::setInputMethodState(bool){}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -