1/*
2 * Copyright (C) 2003, 2006, 2009, 2010, 2012, 2013 Apple Inc. All rights reserved.
3 * Copyright (C) 2010 Igalia S.L
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#include "config.h"
28#include "LocalizedStrings.h"
29
30#include "IntSize.h"
31#include "NotImplemented.h"
32#include "TextBreakIterator.h"
33#include <wtf/MathExtras.h>
34#include <wtf/unicode/CharacterNames.h>
35
36#if USE(CF)
37#include <wtf/RetainPtr.h>
38#endif
39
40#if PLATFORM(MAC)
41#include "WebCoreSystemInterface.h"
42#endif
43
44namespace WebCore {
45
46// We can't use String::format for two reasons:
47//  1) It doesn't handle non-ASCII characters in the format string.
48//  2) It doesn't handle the %2$d syntax.
49// Note that because |format| is used as the second parameter to va_start, it cannot be a reference
50// type according to section 18.7/3 of the C++ N1905 standard.
51static String formatLocalizedString(String format, ...)
52{
53#if USE(CF)
54    va_list arguments;
55    va_start(arguments, format);
56
57#if COMPILER(CLANG)
58#pragma clang diagnostic push
59#pragma clang diagnostic ignored "-Wformat-nonliteral"
60#endif
61    RetainPtr<CFStringRef> result = adoptCF(CFStringCreateWithFormatAndArguments(0, 0, format.createCFString().get(), arguments));
62#if COMPILER(CLANG)
63#pragma clang diagnostic pop
64#endif
65
66    va_end(arguments);
67    return result.get();
68#else
69    notImplemented();
70    return format;
71#endif
72}
73
74#if !PLATFORM(MAC) || PLATFORM(IOS) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
75static String truncatedStringForLookupMenuItem(const String& original)
76{
77    if (original.isEmpty())
78        return original;
79
80    // Truncate the string if it's too long. This is in consistency with AppKit.
81    unsigned maxNumberOfGraphemeClustersInLookupMenuItem = 24;
82    DEFINE_STATIC_LOCAL(String, ellipsis, (&horizontalEllipsis, 1));
83
84    String trimmed = original.stripWhiteSpace();
85    unsigned numberOfCharacters = numCharactersInGraphemeClusters(trimmed, maxNumberOfGraphemeClustersInLookupMenuItem);
86    return numberOfCharacters == trimmed.length() ? trimmed : trimmed.left(numberOfCharacters) + ellipsis;
87}
88#endif
89
90String inputElementAltText()
91{
92    return WEB_UI_STRING_KEY("Submit", "Submit (input element)", "alt text for <input> elements with no alt, title, or value");
93}
94
95String resetButtonDefaultLabel()
96{
97    return WEB_UI_STRING("Reset", "default label for Reset buttons in forms on web pages");
98}
99
100String searchableIndexIntroduction()
101{
102    return WEB_UI_STRING("This is a searchable index. Enter search keywords: ",
103                         "text that appears at the start of nearly-obsolete web pages in the form of a 'searchable index'");
104}
105
106String submitButtonDefaultLabel()
107{
108    return WEB_UI_STRING("Submit", "default label for Submit buttons in forms on web pages");
109}
110
111String fileButtonChooseFileLabel()
112{
113    return WEB_UI_STRING("Choose File", "title for a single file chooser button used in HTML forms");
114}
115
116String fileButtonChooseMultipleFilesLabel()
117{
118    return WEB_UI_STRING("Choose Files", "title for a multiple file chooser button used in HTML forms. This title should be as short as possible.");
119}
120
121String fileButtonNoFileSelectedLabel()
122{
123    return WEB_UI_STRING("no file selected", "text to display in file button used in HTML forms when no file is selected");
124}
125
126String fileButtonNoFilesSelectedLabel()
127{
128    return WEB_UI_STRING("no files selected", "text to display in file button used in HTML forms when no files are selected and the button allows multiple files to be selected");
129}
130
131String defaultDetailsSummaryText()
132{
133    return WEB_UI_STRING("Details", "text to display in <details> tag when it has no <summary> child");
134}
135
136#if PLATFORM(MAC)
137String copyImageUnknownFileLabel()
138{
139    return WEB_UI_STRING("unknown", "Unknown filename");
140}
141#endif
142
143#if ENABLE(CONTEXT_MENUS)
144String contextMenuItemTagOpenLinkInNewWindow()
145{
146    return WEB_UI_STRING("Open Link in New Window", "Open in New Window context menu item");
147}
148
149String contextMenuItemTagDownloadLinkToDisk()
150{
151    return WEB_UI_STRING("Download Linked File", "Download Linked File context menu item");
152}
153
154String contextMenuItemTagCopyLinkToClipboard()
155{
156    return WEB_UI_STRING("Copy Link", "Copy Link context menu item");
157}
158
159String contextMenuItemTagOpenImageInNewWindow()
160{
161    return WEB_UI_STRING("Open Image in New Window", "Open Image in New Window context menu item");
162}
163
164String contextMenuItemTagDownloadImageToDisk()
165{
166    return WEB_UI_STRING("Download Image", "Download Image context menu item");
167}
168
169String contextMenuItemTagCopyImageToClipboard()
170{
171    return WEB_UI_STRING("Copy Image", "Copy Image context menu item");
172}
173
174String contextMenuItemTagOpenFrameInNewWindow()
175{
176    return WEB_UI_STRING("Open Frame in New Window", "Open Frame in New Window context menu item");
177}
178
179String contextMenuItemTagCopy()
180{
181    return WEB_UI_STRING("Copy", "Copy context menu item");
182}
183
184String contextMenuItemTagGoBack()
185{
186    return WEB_UI_STRING("Back", "Back context menu item");
187}
188
189String contextMenuItemTagGoForward()
190{
191    return WEB_UI_STRING("Forward", "Forward context menu item");
192}
193
194String contextMenuItemTagStop()
195{
196    return WEB_UI_STRING("Stop", "Stop context menu item");
197}
198
199String contextMenuItemTagReload()
200{
201    return WEB_UI_STRING("Reload", "Reload context menu item");
202}
203
204String contextMenuItemTagCut()
205{
206    return WEB_UI_STRING("Cut", "Cut context menu item");
207}
208
209String contextMenuItemTagPaste()
210{
211    return WEB_UI_STRING("Paste", "Paste context menu item");
212}
213
214#if PLATFORM(QT)
215String contextMenuItemTagSelectAll()
216{
217    notImplemented();
218    return "Select All";
219}
220#endif
221
222String contextMenuItemTagNoGuessesFound()
223{
224    return WEB_UI_STRING("No Guesses Found", "No Guesses Found context menu item");
225}
226
227String contextMenuItemTagIgnoreSpelling()
228{
229    return WEB_UI_STRING("Ignore Spelling", "Ignore Spelling context menu item");
230}
231
232String contextMenuItemTagLearnSpelling()
233{
234    return WEB_UI_STRING("Learn Spelling", "Learn Spelling context menu item");
235}
236
237#if PLATFORM(MAC)
238String contextMenuItemTagSearchInSpotlight()
239{
240    return WEB_UI_STRING("Search in Spotlight", "Search in Spotlight context menu item");
241}
242#endif
243
244String contextMenuItemTagSearchWeb()
245{
246#if PLATFORM(MAC) && (PLATFORM(IOS) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070)
247    RetainPtr<CFStringRef> searchProviderName = adoptCF(wkCopyDefaultSearchProviderDisplayName());
248    return formatLocalizedString(WEB_UI_STRING("Search with %@", "Search with search provider context menu item with provider name inserted"), searchProviderName.get());
249#else
250    return WEB_UI_STRING("Search with Google", "Search with Google context menu item");
251#endif
252}
253
254String contextMenuItemTagLookUpInDictionary(const String& selectedString)
255{
256#if PLATFORM(MAC) && !PLATFORM(IOS) && __MAC_OS_X_VERSION_MIN_REQUIRED == 1060
257    UNUSED_PARAM(selectedString);
258    return WEB_UI_STRING("Look Up in Dictionary", "Look Up in Dictionary context menu item");
259#else
260#if USE(CF)
261    RetainPtr<CFStringRef> selectedCFString = truncatedStringForLookupMenuItem(selectedString).createCFString();
262    return formatLocalizedString(WEB_UI_STRING("Look Up “%@”", "Look Up context menu item with selected word"), selectedCFString.get());
263#else
264    return WEB_UI_STRING("Look Up “<selection>”", "Look Up context menu item with selected word").replace("<selection>", truncatedStringForLookupMenuItem(selectedString));
265#endif
266#endif
267}
268
269String contextMenuItemTagOpenLink()
270{
271    return WEB_UI_STRING("Open Link", "Open Link context menu item");
272}
273
274String contextMenuItemTagIgnoreGrammar()
275{
276    return WEB_UI_STRING("Ignore Grammar", "Ignore Grammar context menu item");
277}
278
279String contextMenuItemTagSpellingMenu()
280{
281    return WEB_UI_STRING("Spelling and Grammar", "Spelling and Grammar context sub-menu item");
282}
283
284String contextMenuItemTagShowSpellingPanel(bool show)
285{
286    if (show)
287        return WEB_UI_STRING("Show Spelling and Grammar", "menu item title");
288    return WEB_UI_STRING("Hide Spelling and Grammar", "menu item title");
289}
290
291String contextMenuItemTagCheckSpelling()
292{
293    return WEB_UI_STRING("Check Document Now", "Check spelling context menu item");
294}
295
296String contextMenuItemTagCheckSpellingWhileTyping()
297{
298    return WEB_UI_STRING("Check Spelling While Typing", "Check spelling while typing context menu item");
299}
300
301String contextMenuItemTagCheckGrammarWithSpelling()
302{
303    return WEB_UI_STRING("Check Grammar With Spelling", "Check grammar with spelling context menu item");
304}
305
306String contextMenuItemTagFontMenu()
307{
308    return WEB_UI_STRING("Font", "Font context sub-menu item");
309}
310
311#if PLATFORM(MAC)
312String contextMenuItemTagShowFonts()
313{
314    return WEB_UI_STRING("Show Fonts", "Show fonts context menu item");
315}
316#endif
317
318String contextMenuItemTagBold()
319{
320    return WEB_UI_STRING("Bold", "Bold context menu item");
321}
322
323String contextMenuItemTagItalic()
324{
325    return WEB_UI_STRING("Italic", "Italic context menu item");
326}
327
328String contextMenuItemTagUnderline()
329{
330    return WEB_UI_STRING("Underline", "Underline context menu item");
331}
332
333String contextMenuItemTagOutline()
334{
335    return WEB_UI_STRING("Outline", "Outline context menu item");
336}
337
338#if PLATFORM(MAC)
339String contextMenuItemTagStyles()
340{
341    return WEB_UI_STRING("Styles...", "Styles context menu item");
342}
343
344String contextMenuItemTagShowColors()
345{
346    return WEB_UI_STRING("Show Colors", "Show colors context menu item");
347}
348
349String contextMenuItemTagSpeechMenu()
350{
351    return WEB_UI_STRING("Speech", "Speech context sub-menu item");
352}
353
354String contextMenuItemTagStartSpeaking()
355{
356    return WEB_UI_STRING("Start Speaking", "Start speaking context menu item");
357}
358
359String contextMenuItemTagStopSpeaking()
360{
361    return WEB_UI_STRING("Stop Speaking", "Stop speaking context menu item");
362}
363#endif
364
365String contextMenuItemTagWritingDirectionMenu()
366{
367    return WEB_UI_STRING("Paragraph Direction", "Paragraph direction context sub-menu item");
368}
369
370String contextMenuItemTagTextDirectionMenu()
371{
372    return WEB_UI_STRING("Selection Direction", "Selection direction context sub-menu item");
373}
374
375String contextMenuItemTagDefaultDirection()
376{
377    return WEB_UI_STRING("Default", "Default writing direction context menu item");
378}
379
380String contextMenuItemTagLeftToRight()
381{
382    return WEB_UI_STRING("Left to Right", "Left to Right context menu item");
383}
384
385String contextMenuItemTagRightToLeft()
386{
387    return WEB_UI_STRING("Right to Left", "Right to Left context menu item");
388}
389
390#if PLATFORM(MAC)
391
392String contextMenuItemTagCorrectSpellingAutomatically()
393{
394    return WEB_UI_STRING("Correct Spelling Automatically", "Correct Spelling Automatically context menu item");
395}
396
397String contextMenuItemTagSubstitutionsMenu()
398{
399    return WEB_UI_STRING("Substitutions", "Substitutions context sub-menu item");
400}
401
402String contextMenuItemTagShowSubstitutions(bool show)
403{
404    if (show)
405        return WEB_UI_STRING("Show Substitutions", "menu item title");
406    return WEB_UI_STRING("Hide Substitutions", "menu item title");
407}
408
409String contextMenuItemTagSmartCopyPaste()
410{
411    return WEB_UI_STRING("Smart Copy/Paste", "Smart Copy/Paste context menu item");
412}
413
414String contextMenuItemTagSmartQuotes()
415{
416    return WEB_UI_STRING("Smart Quotes", "Smart Quotes context menu item");
417}
418
419String contextMenuItemTagSmartDashes()
420{
421    return WEB_UI_STRING("Smart Dashes", "Smart Dashes context menu item");
422}
423
424String contextMenuItemTagSmartLinks()
425{
426    return WEB_UI_STRING("Smart Links", "Smart Links context menu item");
427}
428
429String contextMenuItemTagTextReplacement()
430{
431    return WEB_UI_STRING("Text Replacement", "Text Replacement context menu item");
432}
433
434String contextMenuItemTagTransformationsMenu()
435{
436    return WEB_UI_STRING("Transformations", "Transformations context sub-menu item");
437}
438
439String contextMenuItemTagMakeUpperCase()
440{
441    return WEB_UI_STRING("Make Upper Case", "Make Upper Case context menu item");
442}
443
444String contextMenuItemTagMakeLowerCase()
445{
446    return WEB_UI_STRING("Make Lower Case", "Make Lower Case context menu item");
447}
448
449String contextMenuItemTagCapitalize()
450{
451    return WEB_UI_STRING("Capitalize", "Capitalize context menu item");
452}
453
454String contextMenuItemTagChangeBack(const String& replacedString)
455{
456    notImplemented();
457    return replacedString;
458}
459
460#endif // PLATFORM(MAC)
461
462String contextMenuItemTagOpenVideoInNewWindow()
463{
464    return WEB_UI_STRING("Open Video in New Window", "Open Video in New Window context menu item");
465}
466
467String contextMenuItemTagOpenAudioInNewWindow()
468{
469    return WEB_UI_STRING("Open Audio in New Window", "Open Audio in New Window context menu item");
470}
471
472String contextMenuItemTagDownloadVideoToDisk()
473{
474    return WEB_UI_STRING("Download Video", "Download Video To Disk context menu item");
475}
476
477String contextMenuItemTagDownloadAudioToDisk()
478{
479    return WEB_UI_STRING("Download Audio", "Download Audio To Disk context menu item");
480}
481
482String contextMenuItemTagCopyVideoLinkToClipboard()
483{
484    return WEB_UI_STRING("Copy Video Address", "Copy Video Address Location context menu item");
485}
486
487String contextMenuItemTagCopyAudioLinkToClipboard()
488{
489    return WEB_UI_STRING("Copy Audio Address", "Copy Audio Address Location context menu item");
490}
491
492String contextMenuItemTagToggleMediaControls()
493{
494    return WEB_UI_STRING("Controls", "Media Controls context menu item");
495}
496
497String contextMenuItemTagShowMediaControls()
498{
499    return WEB_UI_STRING("Show Controls", "Show Media Controls context menu item");
500}
501
502String contextMenuItemTagHideMediaControls()
503{
504    return WEB_UI_STRING("Hide Controls", "Hide Media Controls context menu item");
505}
506
507String contextMenuItemTagToggleMediaLoop()
508{
509    return WEB_UI_STRING("Loop", "Media Loop context menu item");
510}
511
512String contextMenuItemTagEnterVideoFullscreen()
513{
514    return WEB_UI_STRING("Enter Full Screen", "Video Enter Fullscreen context menu item");
515}
516
517String contextMenuItemTagExitVideoFullscreen()
518{
519    return WEB_UI_STRING("Exit Full Screen", "Video Exit Fullscreen context menu item");
520}
521
522String contextMenuItemTagMediaPlay()
523{
524    return WEB_UI_STRING("Play", "Media Play context menu item");
525}
526
527String contextMenuItemTagMediaPause()
528{
529    return WEB_UI_STRING("Pause", "Media Pause context menu item");
530}
531
532String contextMenuItemTagMediaMute()
533{
534    return WEB_UI_STRING("Mute", "Media Mute context menu item");
535}
536
537String contextMenuItemTagInspectElement()
538{
539    return WEB_UI_STRING("Inspect Element", "Inspect Element context menu item");
540}
541
542#endif // ENABLE(CONTEXT_MENUS)
543
544#if !PLATFORM(IOS)
545String searchMenuNoRecentSearchesText()
546{
547    return WEB_UI_STRING("No recent searches", "Label for only item in menu that appears when clicking on the search field image, when no searches have been performed");
548}
549
550String searchMenuRecentSearchesText()
551{
552    return WEB_UI_STRING("Recent Searches", "label for first item in the menu that appears when clicking on the search field image, used as embedded menu title");
553}
554
555String searchMenuClearRecentSearchesText()
556{
557    return WEB_UI_STRING("Clear Recent Searches", "menu item in Recent Searches menu that empties menu's contents");
558}
559
560String AXWebAreaText()
561{
562    return WEB_UI_STRING("HTML content", "accessibility role description for web area");
563}
564
565String AXLinkText()
566{
567    return WEB_UI_STRING("link", "accessibility role description for link");
568}
569
570String AXListMarkerText()
571{
572    return WEB_UI_STRING("list marker", "accessibility role description for list marker");
573}
574
575String AXImageMapText()
576{
577    return WEB_UI_STRING("image map", "accessibility role description for image map");
578}
579
580String AXHeadingText()
581{
582    return WEB_UI_STRING("heading", "accessibility role description for headings");
583}
584
585String AXDefinitionText()
586{
587    return WEB_UI_STRING("definition", "role description of ARIA definition role");
588}
589
590String AXDescriptionListText()
591{
592    return WEB_UI_STRING("description list", "accessibility role description of a description list");
593}
594
595String AXDescriptionListTermText()
596{
597    return WEB_UI_STRING("term", "term word of a description list");
598}
599
600String AXDescriptionListDetailText()
601{
602    return WEB_UI_STRING("description", "description detail");
603}
604
605String AXFooterRoleDescriptionText()
606{
607    return WEB_UI_STRING("footer", "accessibility role description for a footer");
608}
609
610String AXFileUploadButtonText()
611{
612    return WEB_UI_STRING("file upload button", "accessibility role description for a file upload button");
613}
614
615String AXButtonActionVerb()
616{
617    return WEB_UI_STRING("press", "Verb stating the action that will occur when a button is pressed, as used by accessibility");
618}
619
620String AXRadioButtonActionVerb()
621{
622    return WEB_UI_STRING("select", "Verb stating the action that will occur when a radio button is clicked, as used by accessibility");
623}
624
625String AXTextFieldActionVerb()
626{
627    return WEB_UI_STRING("activate", "Verb stating the action that will occur when a text field is selected, as used by accessibility");
628}
629
630String AXCheckedCheckBoxActionVerb()
631{
632    return WEB_UI_STRING("uncheck", "Verb stating the action that will occur when a checked checkbox is clicked, as used by accessibility");
633}
634
635String AXUncheckedCheckBoxActionVerb()
636{
637    return WEB_UI_STRING("check", "Verb stating the action that will occur when an unchecked checkbox is clicked, as used by accessibility");
638}
639
640String AXLinkActionVerb()
641{
642    return WEB_UI_STRING("jump", "Verb stating the action that will occur when a link is clicked, as used by accessibility");
643}
644
645String AXMenuListPopupActionVerb()
646{
647    notImplemented();
648    return "select";
649}
650
651String AXMenuListActionVerb()
652{
653    notImplemented();
654    return "select";
655}
656
657String AXListItemActionVerb()
658{
659    notImplemented();
660    return "select";
661}
662#endif // !PLATFORM(IOS)
663
664#if PLATFORM(MAC) || PLATFORM(IOS)
665String AXARIAContentGroupText(const String& ariaType)
666{
667    if (ariaType == "ARIAApplicationAlert")
668        return WEB_UI_STRING("alert", "An ARIA accessibility group that acts as an alert.");
669    if (ariaType == "ARIAApplicationAlertDialog")
670        return WEB_UI_STRING("alert dialog", "An ARIA accessibility group that acts as an alert dialog.");
671    if (ariaType == "ARIAApplicationDialog")
672        return WEB_UI_STRING("dialog", "An ARIA accessibility group that acts as an dialog.");
673    if (ariaType == "ARIAApplicationLog")
674        return WEB_UI_STRING("log", "An ARIA accessibility group that acts as a console log.");
675    if (ariaType == "ARIAApplicationMarquee")
676        return WEB_UI_STRING("marquee", "An ARIA accessibility group that acts as a marquee.");
677    if (ariaType == "ARIAApplicationStatus")
678        return WEB_UI_STRING("application status", "An ARIA accessibility group that acts as a status update.");
679    if (ariaType == "ARIAApplicationTimer")
680        return WEB_UI_STRING("timer", "An ARIA accessibility group that acts as an updating timer.");
681    if (ariaType == "ARIADocument")
682        return WEB_UI_STRING("document", "An ARIA accessibility group that acts as a document.");
683    if (ariaType == "ARIADocumentArticle")
684        return WEB_UI_STRING("article", "An ARIA accessibility group that acts as an article.");
685    if (ariaType == "ARIADocumentNote")
686        return WEB_UI_STRING("note", "An ARIA accessibility group that acts as a note in a document.");
687    if (ariaType == "ARIADocumentRegion")
688        return WEB_UI_STRING("region", "An ARIA accessibility group that acts as a distinct region in a document.");
689    if (ariaType == "ARIALandmarkApplication")
690        return WEB_UI_STRING("application", "An ARIA accessibility group that acts as an application.");
691    if (ariaType == "ARIALandmarkBanner")
692        return WEB_UI_STRING("banner", "An ARIA accessibility group that acts as a banner.");
693    if (ariaType == "ARIALandmarkComplementary")
694        return WEB_UI_STRING("complementary", "An ARIA accessibility group that acts as a region of complementary information.");
695    if (ariaType == "ARIALandmarkContentInfo")
696        return WEB_UI_STRING("content information", "An ARIA accessibility group that contains content.");
697    if (ariaType == "ARIALandmarkMain")
698        return WEB_UI_STRING("main", "An ARIA accessibility group that is the main portion of the website.");
699    if (ariaType == "ARIALandmarkNavigation")
700        return WEB_UI_STRING("navigation", "An ARIA accessibility group that contains the main navigation elements of a website.");
701    if (ariaType == "ARIALandmarkSearch")
702        return WEB_UI_STRING("search", "An ARIA accessibility group that contains a search feature of a website.");
703    if (ariaType == "ARIAUserInterfaceTooltip")
704        return WEB_UI_STRING("tooltip", "An ARIA accessibility group that acts as a tooltip.");
705    if (ariaType == "ARIATabPanel")
706        return WEB_UI_STRING("tab panel", "An ARIA accessibility group that contains the content of a tab.");
707    if (ariaType == "ARIADocumentMath")
708        return WEB_UI_STRING("math", "An ARIA accessibility group that contains mathematical symbols.");
709    return String();
710}
711#endif // PLATFORM(MAC) || PLATFORM(IOS)
712
713String missingPluginText()
714{
715    return WEB_UI_STRING("Missing Plug-in", "Label text to be used when a plugin is missing");
716}
717
718String crashedPluginText()
719{
720    return WEB_UI_STRING("Plug-in Failure", "Label text to be used if plugin host process has crashed");
721}
722
723String blockedPluginByContentSecurityPolicyText()
724{
725    return WEB_UI_STRING_KEY("Blocked Plug-in", "Blocked Plug-In (Blocked by page's Content Security Policy)", "Label text to be used if plugin is blocked by a page's Content Security Policy");
726}
727
728String insecurePluginVersionText()
729{
730    return WEB_UI_STRING_KEY("Blocked Plug-in", "Blocked Plug-In (Insecure plug-in)", "Label text to be used when an insecure plug-in version was blocked from loading");
731}
732
733String multipleFileUploadText(unsigned numberOfFiles)
734{
735    return formatLocalizedString(WEB_UI_STRING("%d files", "Label to describe the number of files selected in a file upload control that allows multiple files"), numberOfFiles);
736}
737
738String unknownFileSizeText()
739{
740    return WEB_UI_STRING_KEY("Unknown", "Unknown (filesize)", "Unknown filesize FTP directory listing item");
741}
742
743#if PLATFORM(WIN)
744String uploadFileText()
745{
746    notImplemented();
747    return "upload";
748}
749
750String allFilesText()
751{
752    notImplemented();
753    return "all files";
754}
755#endif
756
757#if PLATFORM(MAC)
758String builtInPDFPluginName()
759{
760    // Also exposed to DOM.
761    return WEB_UI_STRING("WebKit built-in PDF", "Pseudo plug-in name, visible in the Installed Plug-ins page in Safari.");
762}
763
764String pdfDocumentTypeDescription()
765{
766    // Also exposed to DOM.
767    return WEB_UI_STRING("Portable Document Format", "Description of the primary type supported by the PDF pseudo plug-in. Visible in the Installed Plug-ins page in Safari.");
768}
769
770String postScriptDocumentTypeDescription()
771{
772    // Also exposed to DOM.
773    return WEB_UI_STRING("PostScript", "Description of the PostScript type supported by the PDF pseudo plug-in. Visible in the Installed Plug-ins page in Safari.");
774}
775
776String keygenMenuItem512()
777{
778    return WEB_UI_STRING("512 (Low Grade)", "Menu item title for KEYGEN pop-up menu");
779}
780
781String keygenMenuItem1024()
782{
783    return WEB_UI_STRING("1024 (Medium Grade)", "Menu item title for KEYGEN pop-up menu");
784}
785
786String keygenMenuItem2048()
787{
788    return WEB_UI_STRING("2048 (High Grade)", "Menu item title for KEYGEN pop-up menu");
789}
790
791String keygenKeychainItemName(const String& host)
792{
793    return formatLocalizedString(WEB_UI_STRING("Key from %@", "Name of keychain key generated by the KEYGEN tag"), host.createCFString().get());
794}
795
796#endif
797
798#if PLATFORM(IOS)
799String htmlSelectMultipleItems(size_t count)
800{
801    switch (count) {
802    case 0:
803        return WEB_UI_STRING("0 Items", "Present the element <select multiple> when no <option> items are selected (iOS only)");
804    case 1:
805        return WEB_UI_STRING("1 Item", "Present the element <select multiple> when a single <option> is selected (iOS only)");
806    default:
807        return formatLocalizedString(WEB_UI_STRING("%zu Items", "Present the number of selected <option> items in a <select multiple> element (iOS only)"), count);
808    }
809}
810#endif
811
812String imageTitle(const String& filename, const IntSize& size)
813{
814#if USE(CF)
815    RetainPtr<CFLocaleRef> locale = adoptCF(CFLocaleCopyCurrent());
816    RetainPtr<CFNumberFormatterRef> formatter = adoptCF(CFNumberFormatterCreate(0, locale.get(), kCFNumberFormatterDecimalStyle));
817
818    int widthInt = size.width();
819    RetainPtr<CFNumberRef> width = adoptCF(CFNumberCreate(0, kCFNumberIntType, &widthInt));
820    RetainPtr<CFStringRef> widthString = adoptCF(CFNumberFormatterCreateStringWithNumber(0, formatter.get(), width.get()));
821
822    int heightInt = size.height();
823    RetainPtr<CFNumberRef> height = adoptCF(CFNumberCreate(0, kCFNumberIntType, &heightInt));
824    RetainPtr<CFStringRef> heightString = adoptCF(CFNumberFormatterCreateStringWithNumber(0, formatter.get(), height.get()));
825
826    return formatLocalizedString(WEB_UI_STRING("%@ %@×%@ pixels", "window title for a standalone image (uses multiplication symbol, not x)"), filename.createCFString().get(), widthString.get(), heightString.get());
827#else
828    return formatLocalizedString(WEB_UI_STRING("<filename> %d×%d pixels", "window title for a standalone image (uses multiplication symbol, not x)"), size.width(), size.height()).replace("<filename>", filename);
829#endif
830}
831
832String mediaElementLoadingStateText()
833{
834    return WEB_UI_STRING("Loading...", "Media controller status message when the media is loading");
835}
836
837String mediaElementLiveBroadcastStateText()
838{
839    return WEB_UI_STRING("Live Broadcast", "Media controller status message when watching a live broadcast");
840}
841
842String localizedMediaControlElementString(const String& name)
843{
844    if (name == "AudioElement")
845        return WEB_UI_STRING("audio playback", "accessibility label for audio element controller");
846    if (name == "VideoElement")
847        return WEB_UI_STRING("video playback", "accessibility label for video element controller");
848    if (name == "MuteButton")
849        return WEB_UI_STRING("mute", "accessibility label for mute button");
850    if (name == "UnMuteButton")
851        return WEB_UI_STRING("unmute", "accessibility label for turn mute off button");
852    if (name == "PlayButton")
853        return WEB_UI_STRING("play", "accessibility label for play button");
854    if (name == "PauseButton")
855        return WEB_UI_STRING("pause", "accessibility label for pause button");
856    if (name == "Slider")
857        return WEB_UI_STRING("movie time", "accessibility label for timeline slider");
858    if (name == "SliderThumb")
859        return WEB_UI_STRING("timeline slider thumb", "accessibility label for timeline thumb");
860    if (name == "RewindButton")
861        return WEB_UI_STRING("back 30 seconds", "accessibility label for seek back 30 seconds button");
862    if (name == "ReturnToRealtimeButton")
863        return WEB_UI_STRING("return to realtime", "accessibility label for return to real time button");
864    if (name == "CurrentTimeDisplay")
865        return WEB_UI_STRING("elapsed time", "accessibility label for elapsed time display");
866    if (name == "TimeRemainingDisplay")
867        return WEB_UI_STRING("remaining time", "accessibility label for time remaining display");
868    if (name == "StatusDisplay")
869        return WEB_UI_STRING("status", "accessibility label for movie status");
870    if (name == "EnterFullscreenButton")
871        return WEB_UI_STRING("enter fullscreen", "accessibility label for enter fullscreen button");
872    if (name == "ExitFullscreenButton")
873        return WEB_UI_STRING("exit fullscreen", "accessibility label for exit fullscreen button");
874    if (name == "SeekForwardButton")
875        return WEB_UI_STRING("fast forward", "accessibility label for fast forward button");
876    if (name == "SeekBackButton")
877        return WEB_UI_STRING("fast reverse", "accessibility label for fast reverse button");
878    if (name == "ShowClosedCaptionsButton")
879        return WEB_UI_STRING("show closed captions", "accessibility label for show closed captions button");
880    if (name == "HideClosedCaptionsButton")
881        return WEB_UI_STRING("hide closed captions", "accessibility label for hide closed captions button");
882
883    // FIXME: the ControlsPanel container should never be visible in the accessibility hierarchy.
884    if (name == "ControlsPanel")
885        return String();
886
887    ASSERT_NOT_REACHED();
888    return String();
889}
890
891String localizedMediaControlElementHelpText(const String& name)
892{
893    if (name == "AudioElement")
894        return WEB_UI_STRING("audio element playback controls and status display", "accessibility help text for audio element controller");
895    if (name == "VideoElement")
896        return WEB_UI_STRING("video element playback controls and status display", "accessibility help text for video element controller");
897    if (name == "MuteButton")
898        return WEB_UI_STRING("mute audio tracks", "accessibility help text for mute button");
899    if (name == "UnMuteButton")
900        return WEB_UI_STRING("unmute audio tracks", "accessibility help text for un mute button");
901    if (name == "PlayButton")
902        return WEB_UI_STRING("begin playback", "accessibility help text for play button");
903    if (name == "PauseButton")
904        return WEB_UI_STRING("pause playback", "accessibility help text for pause button");
905    if (name == "Slider")
906        return WEB_UI_STRING("movie time scrubber", "accessibility help text for timeline slider");
907    if (name == "SliderThumb")
908        return WEB_UI_STRING("movie time scrubber thumb", "accessibility help text for timeline slider thumb");
909    if (name == "RewindButton")
910        return WEB_UI_STRING("seek movie back 30 seconds", "accessibility help text for jump back 30 seconds button");
911    if (name == "ReturnToRealtimeButton")
912        return WEB_UI_STRING("return streaming movie to real time", "accessibility help text for return streaming movie to real time button");
913    if (name == "CurrentTimeDisplay")
914        return WEB_UI_STRING("current movie time in seconds", "accessibility help text for elapsed time display");
915    if (name == "TimeRemainingDisplay")
916        return WEB_UI_STRING("number of seconds of movie remaining", "accessibility help text for remaining time display");
917    if (name == "StatusDisplay")
918        return WEB_UI_STRING("current movie status", "accessibility help text for movie status display");
919    if (name == "SeekBackButton")
920        return WEB_UI_STRING("seek quickly back", "accessibility help text for fast rewind button");
921    if (name == "SeekForwardButton")
922        return WEB_UI_STRING("seek quickly forward", "accessibility help text for fast forward button");
923    if (name == "FullscreenButton")
924        return WEB_UI_STRING("Play movie in fullscreen mode", "accessibility help text for enter fullscreen button");
925    if (name == "ShowClosedCaptionsButton")
926        return WEB_UI_STRING("start displaying closed captions", "accessibility help text for show closed captions button");
927    if (name == "HideClosedCaptionsButton")
928        return WEB_UI_STRING("stop displaying closed captions", "accessibility help text for hide closed captions button");
929
930    // The description of this button is descriptive enough that it doesn't require help text.
931    if (name == "EnterFullscreenButton")
932        return String();
933
934    ASSERT_NOT_REACHED();
935    return String();
936}
937
938String localizedMediaTimeDescription(float time)
939{
940    if (!std::isfinite(time))
941        return WEB_UI_STRING("indefinite time", "accessibility help text for an indefinite media controller time value");
942
943    int seconds = static_cast<int>(fabsf(time));
944    int days = seconds / (60 * 60 * 24);
945    int hours = seconds / (60 * 60);
946    int minutes = (seconds / 60) % 60;
947    seconds %= 60;
948
949    if (days)
950        return formatLocalizedString(WEB_UI_STRING("%1$d days %2$d hours %3$d minutes %4$d seconds", "accessibility help text for media controller time value >= 1 day"), days, hours, minutes, seconds);
951    if (hours)
952        return formatLocalizedString(WEB_UI_STRING("%1$d hours %2$d minutes %3$d seconds", "accessibility help text for media controller time value >= 60 minutes"), hours, minutes, seconds);
953    if (minutes)
954        return formatLocalizedString(WEB_UI_STRING("%1$d minutes %2$d seconds", "accessibility help text for media controller time value >= 60 seconds"), minutes, seconds);
955    return formatLocalizedString(WEB_UI_STRING("%1$d seconds", "accessibility help text for media controller time value < 60 seconds"), seconds);
956}
957
958String validationMessageValueMissingText()
959{
960    return WEB_UI_STRING("value missing", "Validation message for required form control elements that have no value");
961}
962
963String validationMessageValueMissingForCheckboxText()
964{
965    return validationMessageValueMissingText();
966}
967
968String validationMessageValueMissingForFileText()
969{
970    return validationMessageValueMissingText();
971}
972
973String validationMessageValueMissingForMultipleFileText()
974{
975    return validationMessageValueMissingText();
976}
977
978String validationMessageValueMissingForRadioText()
979{
980    return validationMessageValueMissingText();
981}
982
983String validationMessageValueMissingForSelectText()
984{
985    return validationMessageValueMissingText();
986}
987
988String validationMessageTypeMismatchText()
989{
990    return WEB_UI_STRING("type mismatch", "Validation message for input form controls with a value not matching type");
991}
992
993String validationMessageTypeMismatchForEmailText()
994{
995    return validationMessageTypeMismatchText();
996}
997
998String validationMessageTypeMismatchForMultipleEmailText()
999{
1000    return validationMessageTypeMismatchText();
1001}
1002
1003String validationMessageTypeMismatchForURLText()
1004{
1005    return validationMessageTypeMismatchText();
1006}
1007
1008String validationMessagePatternMismatchText()
1009{
1010    return WEB_UI_STRING("pattern mismatch", "Validation message for input form controls requiring a constrained value according to pattern");
1011}
1012
1013String validationMessageTooLongText(int, int)
1014{
1015    return WEB_UI_STRING("too long", "Validation message for form control elements with a value longer than maximum allowed length");
1016}
1017
1018String validationMessageRangeUnderflowText(const String&)
1019{
1020    return WEB_UI_STRING("range underflow", "Validation message for input form controls with value lower than allowed minimum");
1021}
1022
1023String validationMessageRangeOverflowText(const String&)
1024{
1025    return WEB_UI_STRING("range overflow", "Validation message for input form controls with value higher than allowed maximum");
1026}
1027
1028String validationMessageStepMismatchText(const String&, const String&)
1029{
1030    return WEB_UI_STRING("step mismatch", "Validation message for input form controls with value not respecting the step attribute");
1031}
1032
1033String validationMessageBadInputForNumberText()
1034{
1035    notImplemented();
1036    return validationMessageTypeMismatchText();
1037}
1038
1039String clickToExitFullScreenText()
1040{
1041    return WEB_UI_STRING("Click to exit full screen mode", "Message to display in browser window when in webkit full screen mode.");
1042}
1043
1044#if ENABLE(VIDEO_TRACK)
1045String textTrackSubtitlesText()
1046{
1047    return WEB_UI_STRING("Subtitles", "Menu section heading for subtitles");
1048}
1049
1050String textTrackOffMenuItemText()
1051{
1052    return WEB_UI_STRING("Off", "Menu item label for the track that represents disabling closed captions");
1053}
1054
1055String textTrackAutomaticMenuItemText()
1056{
1057    return formatLocalizedString(WEB_UI_STRING("Auto (Recommended)", "Menu item label for automatic track selection behavior"));
1058}
1059
1060String textTrackNoLabelText()
1061{
1062    return WEB_UI_STRING_KEY("Unknown", "Unknown (text track)", "Menu item label for a text track that has no other name");
1063}
1064
1065#if PLATFORM(MAC) || PLATFORM(WIN)
1066String textTrackCountryAndLanguageMenuItemText(const String& title, const String& country, const String& language)
1067{
1068    return formatLocalizedString(WEB_UI_STRING("%@ (%@-%@)", "Text track display name format that includes the country and language of the subtitle, in the form of 'Title (Language-Country)'"), title.createCFString().get(), language.createCFString().get(), country.createCFString().get());
1069}
1070
1071String textTrackLanguageMenuItemText(const String& title, const String& language)
1072{
1073    return formatLocalizedString(WEB_UI_STRING("%@ (%@)", "Text track display name format that includes the language of the subtitle, in the form of 'Title (Language)'"), title.createCFString().get(), language.createCFString().get());
1074}
1075
1076String closedCaptionTrackMenuItemText(const String& title)
1077{
1078    return formatLocalizedString(WEB_UI_STRING("%@ CC", "Text track contains closed captions"), title.createCFString().get());
1079}
1080
1081String sdhTrackMenuItemText(const String& title)
1082{
1083    return formatLocalizedString(WEB_UI_STRING("%@ SDH", "Text track contains subtitles for the deaf and hard of hearing"), title.createCFString().get());
1084}
1085
1086String easyReaderTrackMenuItemText(const String& title)
1087{
1088    return formatLocalizedString(WEB_UI_STRING("%@ Easy Reader", "Text track contains simplified (3rd grade level) subtitles"), title.createCFString().get());
1089}
1090#endif
1091
1092#endif
1093
1094String snapshottedPlugInLabelTitle()
1095{
1096    return WEB_UI_STRING("Snapshotted Plug-In", "Title of the label to show on a snapshotted plug-in");
1097}
1098
1099String snapshottedPlugInLabelSubtitle()
1100{
1101    return WEB_UI_STRING("Click to restart", "Subtitle of the label to show on a snapshotted plug-in");
1102}
1103
1104} // namespace WebCore
1105