~ubuntu-branches/ubuntu/maverick/webkit/maverick

« back to all changes in this revision

Viewing changes to WebCore/platform/ContextMenu.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Mike Hommey
  • Date: 2007-08-19 15:54:12 UTC
  • Revision ID: james.westby@ubuntu.com-20070819155412-uxxg1h9plpghmtbi
Tags: upstream-0~svn25144
ImportĀ upstreamĀ versionĀ 0~svn25144

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
 
3
 *
 
4
 * Redistribution and use in source and binary forms, with or without
 
5
 * modification, are permitted provided that the following conditions
 
6
 * are met:
 
7
 * 1. Redistributions of source code must retain the above copyright
 
8
 *    notice, this list of conditions and the following disclaimer.
 
9
 * 2. Redistributions in binary form must reproduce the above copyright
 
10
 *    notice, this list of conditions and the following disclaimer in the
 
11
 *    documentation and/or other materials provided with the distribution.
 
12
 *
 
13
 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
 
14
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 
15
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 
16
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
 
17
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 
18
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 
19
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 
20
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 
21
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 
22
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 
23
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 
24
 */
 
25
 
 
26
#include "config.h"
 
27
#include "ContextMenu.h"
 
28
 
 
29
#include "CSSComputedStyleDeclaration.h"
 
30
#include "CSSProperty.h"
 
31
#include "CSSPropertyNames.h"
 
32
#include "ContextMenuController.h"
 
33
#include "Document.h"
 
34
#include "Editor.h"
 
35
#include "Frame.h"
 
36
#include "FrameLoader.h"
 
37
#include "KURL.h"
 
38
#include "LocalizedStrings.h"
 
39
#include "Node.h"
 
40
#include "Page.h"
 
41
#include "ResourceRequest.h"
 
42
#include "SelectionController.h"
 
43
#include "TextIterator.h"
 
44
#include <memory>
 
45
 
 
46
using namespace std;
 
47
using namespace WTF;
 
48
using namespace Unicode;
 
49
 
 
50
namespace WebCore {
 
51
 
 
52
ContextMenuController* ContextMenu::controller() const
 
53
{
 
54
    if (Node* node = m_hitTestResult.innerNonSharedNode())
 
55
        if (Frame* frame = node->document()->frame())
 
56
            if (Page* page = frame->page())
 
57
                return page->contextMenuController();
 
58
    return 0;
 
59
}
 
60
 
 
61
static auto_ptr<ContextMenuItem> separatorItem()
 
62
{
 
63
    return auto_ptr<ContextMenuItem>(new ContextMenuItem(SeparatorType, ContextMenuItemTagNoAction, String()));
 
64
}
 
65
 
 
66
static void createAndAppendFontSubMenu(const HitTestResult& result, ContextMenuItem& fontMenuItem)
 
67
{
 
68
    ContextMenu fontMenu(result);
 
69
 
 
70
#if PLATFORM(MAC)
 
71
    ContextMenuItem showFonts(ActionType, ContextMenuItemTagShowFonts, contextMenuItemTagShowFonts());
 
72
#endif
 
73
    ContextMenuItem bold(ActionType, ContextMenuItemTagBold, contextMenuItemTagBold());
 
74
    ContextMenuItem italic(ActionType, ContextMenuItemTagItalic, contextMenuItemTagItalic());
 
75
    ContextMenuItem underline(ActionType, ContextMenuItemTagUnderline, contextMenuItemTagUnderline());
 
76
    ContextMenuItem outline(ActionType, ContextMenuItemTagOutline, contextMenuItemTagOutline());
 
77
#if PLATFORM(MAC)
 
78
    ContextMenuItem styles(ActionType, ContextMenuItemTagStyles, contextMenuItemTagStyles());
 
79
    ContextMenuItem showColors(ActionType, ContextMenuItemTagShowColors, contextMenuItemTagShowColors());
 
80
#endif
 
81
 
 
82
#if PLATFORM(MAC)
 
83
    fontMenu.appendItem(showFonts);
 
84
#endif
 
85
    fontMenu.appendItem(bold);
 
86
    fontMenu.appendItem(italic);
 
87
    fontMenu.appendItem(underline);
 
88
    fontMenu.appendItem(outline);
 
89
#if PLATFORM(MAC)
 
90
    fontMenu.appendItem(styles);
 
91
    fontMenu.appendItem(*separatorItem());
 
92
    fontMenu.appendItem(showColors);
 
93
#endif
 
94
 
 
95
    fontMenuItem.setSubMenu(&fontMenu);
 
96
}
 
97
 
 
98
#ifndef BUILDING_ON_TIGER
 
99
static void createAndAppendSpellingAndGrammarSubMenu(const HitTestResult& result, ContextMenuItem& spellingAndGrammarMenuItem)
 
100
{
 
101
    ContextMenu spellingAndGrammarMenu(result);
 
102
 
 
103
    ContextMenuItem showSpellingPanel(ActionType, ContextMenuItemTagShowSpellingPanel, 
 
104
        contextMenuItemTagShowSpellingPanel(true));
 
105
    ContextMenuItem checkSpelling(ActionType, ContextMenuItemTagCheckSpelling, 
 
106
        contextMenuItemTagCheckSpelling());
 
107
    ContextMenuItem checkAsYouType(ActionType, ContextMenuItemTagCheckSpellingWhileTyping, 
 
108
        contextMenuItemTagCheckSpellingWhileTyping());
 
109
    ContextMenuItem grammarWithSpelling(ActionType, ContextMenuItemTagCheckGrammarWithSpelling, 
 
110
        contextMenuItemTagCheckGrammarWithSpelling());
 
111
 
 
112
    spellingAndGrammarMenu.appendItem(showSpellingPanel);
 
113
    spellingAndGrammarMenu.appendItem(checkSpelling);
 
114
    spellingAndGrammarMenu.appendItem(checkAsYouType);
 
115
    spellingAndGrammarMenu.appendItem(grammarWithSpelling);
 
116
 
 
117
    spellingAndGrammarMenuItem.setSubMenu(&spellingAndGrammarMenu);
 
118
}
 
119
#else
 
120
 
 
121
static void createAndAppendSpellingSubMenu(const HitTestResult& result, ContextMenuItem& spellingMenuItem)
 
122
{
 
123
    ContextMenu spellingMenu(result);
 
124
 
 
125
    ContextMenuItem showSpellingPanel(ActionType, ContextMenuItemTagShowSpellingPanel, 
 
126
        contextMenuItemTagShowSpellingPanel(true));
 
127
    ContextMenuItem checkSpelling(ActionType, ContextMenuItemTagCheckSpelling, 
 
128
        contextMenuItemTagCheckSpelling());
 
129
    ContextMenuItem checkAsYouType(ActionType, ContextMenuItemTagCheckSpellingWhileTyping, 
 
130
        contextMenuItemTagCheckSpellingWhileTyping());
 
131
 
 
132
    spellingMenu.appendItem(showSpellingPanel);
 
133
    spellingMenu.appendItem(checkSpelling);
 
134
    spellingMenu.appendItem(checkAsYouType);
 
135
 
 
136
    spellingMenuItem.setSubMenu(&spellingMenu);
 
137
}
 
138
#endif
 
139
 
 
140
#if PLATFORM(MAC)
 
141
static void createAndAppendSpeechSubMenu(const HitTestResult& result, ContextMenuItem& speechMenuItem)
 
142
{
 
143
    ContextMenu speechMenu(result);
 
144
 
 
145
    ContextMenuItem start(ActionType, ContextMenuItemTagStartSpeaking, contextMenuItemTagStartSpeaking());
 
146
    ContextMenuItem stop(ActionType, ContextMenuItemTagStopSpeaking, contextMenuItemTagStopSpeaking());
 
147
 
 
148
    speechMenu.appendItem(start);
 
149
    speechMenu.appendItem(stop);
 
150
 
 
151
    speechMenuItem.setSubMenu(&speechMenu);
 
152
}
 
153
#endif
 
154
 
 
155
static void createAndAppendWritingDirectionSubMenu(const HitTestResult& result, ContextMenuItem& writingDirectionMenuItem)
 
156
{
 
157
    ContextMenu writingDirectionMenu(result);
 
158
 
 
159
    ContextMenuItem defaultItem(ActionType, ContextMenuItemTagDefaultDirection, 
 
160
        contextMenuItemTagDefaultDirection());
 
161
    ContextMenuItem ltr(ActionType, ContextMenuItemTagLeftToRight, contextMenuItemTagLeftToRight());
 
162
    ContextMenuItem rtl(ActionType, ContextMenuItemTagRightToLeft, contextMenuItemTagRightToLeft());
 
163
 
 
164
    writingDirectionMenu.appendItem(defaultItem);
 
165
    writingDirectionMenu.appendItem(ltr);
 
166
    writingDirectionMenu.appendItem(rtl);
 
167
 
 
168
    writingDirectionMenuItem.setSubMenu(&writingDirectionMenu);
 
169
}
 
170
 
 
171
static bool selectionContainsPossibleWord(Frame* frame)
 
172
{
 
173
    // Current algorithm: look for a character that's not just a separator.
 
174
    for (TextIterator it(frame->selectionController()->toRange().get()); !it.atEnd(); it.advance()) {
 
175
        int length = it.length();
 
176
        const UChar* characters = it.characters();
 
177
        for (int i = 0; i < length; ++i)
 
178
            if (!(category(characters[i]) & (Separator_Space | Separator_Line | Separator_Paragraph)))
 
179
                return true;
 
180
    }
 
181
    return false;
 
182
}
 
183
 
 
184
void ContextMenu::populate()
 
185
{
 
186
    ContextMenuItem OpenLinkItem(ActionType, ContextMenuItemTagOpenLink, contextMenuItemTagOpenLink());
 
187
    ContextMenuItem OpenLinkInNewWindowItem(ActionType, ContextMenuItemTagOpenLinkInNewWindow, 
 
188
        contextMenuItemTagOpenLinkInNewWindow());
 
189
    ContextMenuItem DownloadFileItem(ActionType, ContextMenuItemTagDownloadLinkToDisk, 
 
190
        contextMenuItemTagDownloadLinkToDisk());
 
191
    ContextMenuItem CopyLinkItem(ActionType, ContextMenuItemTagCopyLinkToClipboard, 
 
192
        contextMenuItemTagCopyLinkToClipboard());
 
193
    ContextMenuItem OpenImageInNewWindowItem(ActionType, ContextMenuItemTagOpenImageInNewWindow, 
 
194
        contextMenuItemTagOpenImageInNewWindow());
 
195
    ContextMenuItem DownloadImageItem(ActionType, ContextMenuItemTagDownloadImageToDisk, 
 
196
        contextMenuItemTagDownloadImageToDisk());
 
197
    ContextMenuItem CopyImageItem(ActionType, ContextMenuItemTagCopyImageToClipboard, 
 
198
        contextMenuItemTagCopyImageToClipboard());
 
199
#if PLATFORM(MAC)
 
200
    ContextMenuItem SearchSpotlightItem(ActionType, ContextMenuItemTagSearchInSpotlight, 
 
201
        contextMenuItemTagSearchInSpotlight());
 
202
    ContextMenuItem LookInDictionaryItem(ActionType, ContextMenuItemTagLookUpInDictionary, 
 
203
        contextMenuItemTagLookUpInDictionary());
 
204
#endif
 
205
    ContextMenuItem SearchWebItem(ActionType, ContextMenuItemTagSearchWeb, contextMenuItemTagSearchWeb());
 
206
    ContextMenuItem CopyItem(ActionType, ContextMenuItemTagCopy, contextMenuItemTagCopy());
 
207
    ContextMenuItem BackItem(ActionType, ContextMenuItemTagGoBack, contextMenuItemTagGoBack());
 
208
    ContextMenuItem ForwardItem(ActionType, ContextMenuItemTagGoForward,  contextMenuItemTagGoForward());
 
209
    ContextMenuItem StopItem(ActionType, ContextMenuItemTagStop, contextMenuItemTagStop());
 
210
    ContextMenuItem ReloadItem(ActionType, ContextMenuItemTagReload, contextMenuItemTagReload());
 
211
    ContextMenuItem OpenFrameItem(ActionType, ContextMenuItemTagOpenFrameInNewWindow, 
 
212
        contextMenuItemTagOpenFrameInNewWindow());
 
213
    ContextMenuItem NoGuessesItem(ActionType, ContextMenuItemTagNoGuessesFound, 
 
214
        contextMenuItemTagNoGuessesFound());
 
215
    ContextMenuItem IgnoreSpellingItem(ActionType, ContextMenuItemTagIgnoreSpelling, 
 
216
        contextMenuItemTagIgnoreSpelling());
 
217
    ContextMenuItem LearnSpellingItem(ActionType, ContextMenuItemTagLearnSpelling, 
 
218
        contextMenuItemTagLearnSpelling());
 
219
    ContextMenuItem IgnoreGrammarItem(ActionType, ContextMenuItemTagIgnoreGrammar, 
 
220
        contextMenuItemTagIgnoreGrammar());
 
221
    ContextMenuItem CutItem(ActionType, ContextMenuItemTagCut, contextMenuItemTagCut());
 
222
    ContextMenuItem PasteItem(ActionType, ContextMenuItemTagPaste, contextMenuItemTagPaste());
 
223
    
 
224
    HitTestResult result = hitTestResult();
 
225
    
 
226
    Node* node = m_hitTestResult.innerNonSharedNode();
 
227
    if (!node)
 
228
        return;
 
229
    Frame* frame = node->document()->frame();
 
230
    if (!frame)
 
231
        return;
 
232
 
 
233
    if (!result.isContentEditable()) {
 
234
        FrameLoader* loader = frame->loader();
 
235
        KURL linkURL = result.absoluteLinkURL();
 
236
        if (!linkURL.isEmpty()) {
 
237
            if (loader->canHandleRequest(ResourceRequest(linkURL))) {
 
238
                appendItem(OpenLinkItem);
 
239
                appendItem(OpenLinkInNewWindowItem);
 
240
                appendItem(DownloadFileItem);
 
241
            }
 
242
            appendItem(CopyLinkItem);
 
243
        }
 
244
 
 
245
        KURL imageURL = result.absoluteImageURL();
 
246
        if (!imageURL.isEmpty()) {
 
247
            if (!linkURL.isEmpty())
 
248
                appendItem(*separatorItem());
 
249
 
 
250
            appendItem(OpenImageInNewWindowItem);
 
251
            appendItem(DownloadImageItem);
 
252
            if (imageURL.isLocalFile() || m_hitTestResult.image())
 
253
                appendItem(CopyImageItem);
 
254
        }
 
255
 
 
256
        if (imageURL.isEmpty() && linkURL.isEmpty()) {
 
257
            if (result.isSelected()) {
 
258
                if (selectionContainsPossibleWord(frame)) {
 
259
#if PLATFORM(MAC)
 
260
                    appendItem(SearchSpotlightItem);
 
261
#endif
 
262
                    appendItem(SearchWebItem);
 
263
                    appendItem(*separatorItem());
 
264
#if PLATFORM(MAC)
 
265
                    appendItem(LookInDictionaryItem);
 
266
                    appendItem(*separatorItem());
 
267
#endif
 
268
                }
 
269
                appendItem(CopyItem);
 
270
            } else {
 
271
                if (loader->canGoBackOrForward(-1))
 
272
                    appendItem(BackItem);
 
273
 
 
274
                if (loader->canGoBackOrForward(1))
 
275
                    appendItem(ForwardItem);
 
276
 
 
277
                if (loader->isLoading())
 
278
                    appendItem(StopItem);
 
279
                else
 
280
                    appendItem(ReloadItem);
 
281
 
 
282
                if (frame->page() && frame != frame->page()->mainFrame())
 
283
                    appendItem(OpenFrameItem);
 
284
            }
 
285
        }
 
286
    } else { // Make an editing context menu
 
287
        SelectionController* selectionController = frame->selectionController();
 
288
        bool inPasswordField = selectionController->isInPasswordField();
 
289
        
 
290
        if (!inPasswordField) {
 
291
            // Consider adding spelling-related or grammar-related context menu items (never both, since a single selected range
 
292
            // is never considered a misspelling and bad grammar at the same time)
 
293
            bool misspelling = frame->editor()->isSelectionMisspelled();
 
294
            bool badGrammar = !misspelling && (frame->editor()->isGrammarCheckingEnabled() && frame->editor()->isSelectionUngrammatical());
 
295
            
 
296
            if (misspelling || badGrammar) {
 
297
                Vector<String> guesses = misspelling ? frame->editor()->guessesForMisspelledSelection()
 
298
                    : frame->editor()->guessesForUngrammaticalSelection();
 
299
                size_t size = guesses.size();
 
300
                if (size == 0) {
 
301
                    // If there's bad grammar but no suggestions (e.g., repeated word), just leave off the suggestions
 
302
                    // list and trailing separator rather than adding a "No Guesses Found" item (matches AppKit)
 
303
                    if (misspelling) {
 
304
                        appendItem(NoGuessesItem);
 
305
                        appendItem(*separatorItem());
 
306
                    }
 
307
                } else {
 
308
                    for (unsigned i = 0; i < size; i++) {
 
309
                        const String &guess = guesses[i];
 
310
                        if (!guess.isEmpty()) {
 
311
                            ContextMenuItem item(ActionType, ContextMenuItemTagSpellingGuess, guess);
 
312
                            appendItem(item);
 
313
                        }
 
314
                    }
 
315
                    appendItem(*separatorItem());                    
 
316
                }
 
317
                
 
318
                if (misspelling) {
 
319
                    appendItem(IgnoreSpellingItem);
 
320
                    appendItem(LearnSpellingItem);
 
321
                } else
 
322
                    appendItem(IgnoreGrammarItem);
 
323
                appendItem(*separatorItem());
 
324
            }
 
325
        }
 
326
 
 
327
        FrameLoader* loader = frame->loader();
 
328
        KURL linkURL = result.absoluteLinkURL();
 
329
        if (!linkURL.isEmpty()) {
 
330
            if (loader->canHandleRequest(ResourceRequest(linkURL))) {
 
331
                appendItem(OpenLinkItem);
 
332
                appendItem(OpenLinkInNewWindowItem);
 
333
                appendItem(DownloadFileItem);
 
334
            }
 
335
            appendItem(CopyLinkItem);
 
336
            appendItem(*separatorItem());
 
337
        }
 
338
 
 
339
        if (result.isSelected() && !inPasswordField && selectionContainsPossibleWord(frame)) {
 
340
#if PLATFORM(MAC)
 
341
            appendItem(SearchSpotlightItem);
 
342
#endif
 
343
            appendItem(SearchWebItem);
 
344
            appendItem(*separatorItem());
 
345
     
 
346
#if PLATFORM(MAC)
 
347
            appendItem(LookInDictionaryItem);
 
348
            appendItem(*separatorItem());
 
349
#endif
 
350
        }
 
351
 
 
352
        appendItem(CutItem);
 
353
        appendItem(CopyItem);
 
354
        appendItem(PasteItem);
 
355
 
 
356
        if (!inPasswordField) {
 
357
            appendItem(*separatorItem());
 
358
#ifndef BUILDING_ON_TIGER
 
359
            ContextMenuItem SpellingAndGrammarMenuItem(SubmenuType, ContextMenuItemTagSpellingMenu, 
 
360
                contextMenuItemTagSpellingMenu());
 
361
            createAndAppendSpellingAndGrammarSubMenu(m_hitTestResult, SpellingAndGrammarMenuItem);
 
362
            appendItem(SpellingAndGrammarMenuItem);
 
363
#else
 
364
            ContextMenuItem SpellingMenuItem(SubmenuType, ContextMenuItemTagSpellingMenu, 
 
365
                contextMenuItemTagSpellingMenu());
 
366
            createAndAppendSpellingSubMenu(m_hitTestResult, SpellingMenuItem);
 
367
            appendItem(SpellingMenuItem);
 
368
#endif
 
369
            ContextMenuItem  FontMenuItem(SubmenuType, ContextMenuItemTagFontMenu, 
 
370
                contextMenuItemTagFontMenu());
 
371
            createAndAppendFontSubMenu(m_hitTestResult, FontMenuItem);
 
372
            appendItem(FontMenuItem);
 
373
#if PLATFORM(MAC)
 
374
            ContextMenuItem SpeechMenuItem(SubmenuType, ContextMenuItemTagSpeechMenu, 
 
375
                contextMenuItemTagSpeechMenu());
 
376
            createAndAppendSpeechSubMenu(m_hitTestResult, SpeechMenuItem);
 
377
            appendItem(SpeechMenuItem);
 
378
#endif
 
379
            ContextMenuItem WritingDirectionMenuItem(SubmenuType, ContextMenuItemTagWritingDirectionMenu, 
 
380
                contextMenuItemTagWritingDirectionMenu());
 
381
            createAndAppendWritingDirectionSubMenu(m_hitTestResult, WritingDirectionMenuItem);
 
382
            appendItem(WritingDirectionMenuItem);
 
383
        }
 
384
    }
 
385
}
 
386
 
 
387
void ContextMenu::addInspectElementItem()
 
388
{
 
389
    Node* node = m_hitTestResult.innerNonSharedNode();
 
390
    if (!node)
 
391
        return;
 
392
 
 
393
    Frame* frame = node->document()->frame();
 
394
    if (!frame)
 
395
        return;
 
396
 
 
397
    Page* page = frame->page();
 
398
    if (!page)
 
399
        return;
 
400
 
 
401
    if (!page->inspectorController())
 
402
        return;
 
403
 
 
404
    ContextMenuItem InspectElementItem(ActionType, ContextMenuItemTagInspectElement, contextMenuItemTagInspectElement());
 
405
    appendItem(*separatorItem());
 
406
    appendItem(InspectElementItem);
 
407
}
 
408
 
 
409
static bool triStateToBool(Frame::TriState state)
 
410
{
 
411
    return state == Frame::trueTriState;
 
412
}
 
413
 
 
414
void ContextMenu::checkOrEnableIfNeeded(ContextMenuItem& item) const
 
415
{
 
416
    if (item.type() == SeparatorType)
 
417
        return;
 
418
    
 
419
    Frame* frame = m_hitTestResult.innerNonSharedNode()->document()->frame();
 
420
    if (!frame)
 
421
        return;
 
422
 
 
423
    bool shouldEnable = true;
 
424
    bool shouldCheck = false; 
 
425
 
 
426
    switch (item.action()) {
 
427
        case ContextMenuItemTagCheckSpelling:
 
428
            shouldEnable = frame->editor()->canEdit();
 
429
            break;
 
430
        case ContextMenuItemTagDefaultDirection:
 
431
            shouldCheck = false;
 
432
            shouldEnable = false;
 
433
            break;
 
434
        case ContextMenuItemTagLeftToRight:
 
435
        case ContextMenuItemTagRightToLeft: {
 
436
            ExceptionCode ec = 0;
 
437
            RefPtr<CSSStyleDeclaration> style = frame->document()->createCSSStyleDeclaration();
 
438
            String direction = item.action() == ContextMenuItemTagLeftToRight ? "ltr" : "rtl";
 
439
            style->setProperty(CSS_PROP_DIRECTION, direction, false, ec);
 
440
            shouldCheck = triStateToBool(frame->selectionHasStyle(style.get()));
 
441
            shouldEnable = true;
 
442
            break;
 
443
        }
 
444
        case ContextMenuItemTagCopy:
 
445
            shouldEnable = frame->editor()->canDHTMLCopy() || frame->editor()->canCopy();
 
446
            break;
 
447
        case ContextMenuItemTagCut:
 
448
            shouldEnable = frame->editor()->canDHTMLCut() || frame->editor()->canCut();
 
449
            break;
 
450
        case ContextMenuItemTagIgnoreSpelling:
 
451
        case ContextMenuItemTagLearnSpelling:
 
452
            shouldEnable = frame->selectionController()->isRange();
 
453
            break;
 
454
        case ContextMenuItemTagPaste:
 
455
            shouldEnable = frame->editor()->canDHTMLPaste() || frame->editor()->canPaste();
 
456
            break;
 
457
        case ContextMenuItemTagUnderline: {
 
458
            ExceptionCode ec = 0;
 
459
            RefPtr<CSSStyleDeclaration> style = frame->document()->createCSSStyleDeclaration();
 
460
            style->setProperty(CSS_PROP__WEBKIT_TEXT_DECORATIONS_IN_EFFECT, "underline", false, ec);
 
461
            shouldCheck = triStateToBool(frame->selectionHasStyle(style.get()));
 
462
            shouldEnable = frame->editor()->canEditRichly();
 
463
            break;
 
464
        }
 
465
        case ContextMenuItemTagLookUpInDictionary:
 
466
            shouldEnable = frame->selectionController()->isRange();
 
467
            break;
 
468
        case ContextMenuItemTagCheckGrammarWithSpelling:
 
469
#ifndef BUILDING_ON_TIGER
 
470
            if (frame->editor()->isGrammarCheckingEnabled())
 
471
                shouldCheck = true;
 
472
            shouldEnable = true;
 
473
#endif
 
474
            break;
 
475
        case ContextMenuItemTagItalic: {
 
476
            ExceptionCode ec = 0;
 
477
            RefPtr<CSSStyleDeclaration> style = frame->document()->createCSSStyleDeclaration();
 
478
            style->setProperty(CSS_PROP_FONT_STYLE, "italic", false, ec);
 
479
            shouldCheck = triStateToBool(frame->selectionHasStyle(style.get()));
 
480
            shouldEnable = frame->editor()->canEditRichly();
 
481
            break;
 
482
        }
 
483
        case ContextMenuItemTagBold: {
 
484
            ExceptionCode ec = 0;
 
485
            RefPtr<CSSStyleDeclaration> style = frame->document()->createCSSStyleDeclaration();
 
486
            style->setProperty(CSS_PROP_FONT_WEIGHT, "bold", false, ec);
 
487
            shouldCheck = triStateToBool(frame->selectionHasStyle(style.get()));
 
488
            shouldEnable = frame->editor()->canEditRichly();
 
489
            break;
 
490
        }
 
491
        case ContextMenuItemTagOutline:
 
492
            shouldEnable = false;
 
493
            break;
 
494
        case ContextMenuItemTagShowSpellingPanel:
 
495
#ifndef BUILDING_ON_TIGER
 
496
            if (frame->editor()->spellingPanelIsShowing())
 
497
                item.setTitle(contextMenuItemTagShowSpellingPanel(false));
 
498
            else
 
499
                item.setTitle(contextMenuItemTagShowSpellingPanel(true));
 
500
#endif
 
501
            shouldEnable = frame->editor()->canEdit();
 
502
            break;
 
503
        case ContextMenuItemTagNoGuessesFound:
 
504
            shouldEnable = false;
 
505
            break;
 
506
        case ContextMenuItemTagCheckSpellingWhileTyping:
 
507
            shouldCheck = frame->editor()->isContinuousSpellCheckingEnabled();
 
508
            break;
 
509
        case ContextMenuItemTagNoAction:
 
510
        case ContextMenuItemTagOpenLinkInNewWindow:
 
511
        case ContextMenuItemTagDownloadLinkToDisk:
 
512
        case ContextMenuItemTagCopyLinkToClipboard:
 
513
        case ContextMenuItemTagOpenImageInNewWindow:
 
514
        case ContextMenuItemTagDownloadImageToDisk:
 
515
        case ContextMenuItemTagCopyImageToClipboard:
 
516
        case ContextMenuItemTagOpenFrameInNewWindow:
 
517
        case ContextMenuItemTagGoBack:
 
518
        case ContextMenuItemTagGoForward:
 
519
        case ContextMenuItemTagStop:
 
520
        case ContextMenuItemTagReload:
 
521
        case ContextMenuItemTagSpellingGuess:
 
522
        case ContextMenuItemTagOther:
 
523
        case ContextMenuItemTagSearchInSpotlight:
 
524
        case ContextMenuItemTagSearchWeb:
 
525
        case ContextMenuItemTagOpenWithDefaultApplication:
 
526
        case ContextMenuItemPDFActualSize:
 
527
        case ContextMenuItemPDFZoomIn:
 
528
        case ContextMenuItemPDFZoomOut:
 
529
        case ContextMenuItemPDFAutoSize:
 
530
        case ContextMenuItemPDFSinglePage:
 
531
        case ContextMenuItemPDFFacingPages:
 
532
        case ContextMenuItemPDFContinuous:
 
533
        case ContextMenuItemPDFNextPage:
 
534
        case ContextMenuItemPDFPreviousPage:
 
535
        case ContextMenuItemTagOpenLink:
 
536
        case ContextMenuItemTagIgnoreGrammar:
 
537
        case ContextMenuItemTagSpellingMenu:
 
538
        case ContextMenuItemTagFontMenu:
 
539
        case ContextMenuItemTagShowFonts:
 
540
        case ContextMenuItemTagStyles:
 
541
        case ContextMenuItemTagShowColors:
 
542
        case ContextMenuItemTagSpeechMenu:
 
543
        case ContextMenuItemTagStartSpeaking:
 
544
        case ContextMenuItemTagStopSpeaking:
 
545
        case ContextMenuItemTagWritingDirectionMenu:
 
546
        case ContextMenuItemTagPDFSinglePageScrolling:
 
547
        case ContextMenuItemTagPDFFacingPagesScrolling:
 
548
        case ContextMenuItemTagInspectElement:
 
549
        case ContextMenuItemBaseApplicationTag:
 
550
            break;
 
551
    }
 
552
 
 
553
    item.setChecked(shouldCheck);
 
554
    item.setEnabled(shouldEnable);
 
555
}
 
556
 
 
557
}