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 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 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(COCOA)
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 ENABLE(CONTEXT_MENUS)
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    DEPRECATED_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(COCOA)
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
214String contextMenuItemTagNoGuessesFound()
215{
216    return WEB_UI_STRING("No Guesses Found", "No Guesses Found context menu item");
217}
218
219String contextMenuItemTagIgnoreSpelling()
220{
221    return WEB_UI_STRING("Ignore Spelling", "Ignore Spelling context menu item");
222}
223
224String contextMenuItemTagLearnSpelling()
225{
226    return WEB_UI_STRING("Learn Spelling", "Learn Spelling context menu item");
227}
228
229#if PLATFORM(COCOA)
230String contextMenuItemTagSearchInSpotlight()
231{
232    return WEB_UI_STRING("Search in Spotlight", "Search in Spotlight context menu item");
233}
234#endif
235
236String contextMenuItemTagSearchWeb()
237{
238#if PLATFORM(COCOA)
239    RetainPtr<CFStringRef> searchProviderName = adoptCF(wkCopyDefaultSearchProviderDisplayName());
240    return formatLocalizedString(WEB_UI_STRING("Search with %@", "Search with search provider context menu item with provider name inserted"), searchProviderName.get());
241#else
242    return WEB_UI_STRING("Search with Google", "Search with Google context menu item");
243#endif
244}
245
246String contextMenuItemTagLookUpInDictionary(const String& selectedString)
247{
248#if USE(CF)
249    RetainPtr<CFStringRef> selectedCFString = truncatedStringForLookupMenuItem(selectedString).createCFString();
250    return formatLocalizedString(WEB_UI_STRING("Look Up “%@”", "Look Up context menu item with selected word"), selectedCFString.get());
251#else
252    return WEB_UI_STRING("Look Up “<selection>”", "Look Up context menu item with selected word").replace("<selection>", truncatedStringForLookupMenuItem(selectedString));
253#endif
254}
255
256String contextMenuItemTagOpenLink()
257{
258    return WEB_UI_STRING("Open Link", "Open Link context menu item");
259}
260
261String contextMenuItemTagIgnoreGrammar()
262{
263    return WEB_UI_STRING("Ignore Grammar", "Ignore Grammar context menu item");
264}
265
266String contextMenuItemTagSpellingMenu()
267{
268    return WEB_UI_STRING("Spelling and Grammar", "Spelling and Grammar context sub-menu item");
269}
270
271String contextMenuItemTagShowSpellingPanel(bool show)
272{
273    if (show)
274        return WEB_UI_STRING("Show Spelling and Grammar", "menu item title");
275    return WEB_UI_STRING("Hide Spelling and Grammar", "menu item title");
276}
277
278String contextMenuItemTagCheckSpelling()
279{
280    return WEB_UI_STRING("Check Document Now", "Check spelling context menu item");
281}
282
283String contextMenuItemTagCheckSpellingWhileTyping()
284{
285    return WEB_UI_STRING("Check Spelling While Typing", "Check spelling while typing context menu item");
286}
287
288String contextMenuItemTagCheckGrammarWithSpelling()
289{
290    return WEB_UI_STRING("Check Grammar With Spelling", "Check grammar with spelling context menu item");
291}
292
293String contextMenuItemTagFontMenu()
294{
295    return WEB_UI_STRING("Font", "Font context sub-menu item");
296}
297
298#if PLATFORM(COCOA)
299String contextMenuItemTagShowFonts()
300{
301    return WEB_UI_STRING("Show Fonts", "Show fonts context menu item");
302}
303#endif
304
305String contextMenuItemTagBold()
306{
307    return WEB_UI_STRING("Bold", "Bold context menu item");
308}
309
310String contextMenuItemTagItalic()
311{
312    return WEB_UI_STRING("Italic", "Italic context menu item");
313}
314
315String contextMenuItemTagUnderline()
316{
317    return WEB_UI_STRING("Underline", "Underline context menu item");
318}
319
320String contextMenuItemTagOutline()
321{
322    return WEB_UI_STRING("Outline", "Outline context menu item");
323}
324
325#if PLATFORM(COCOA)
326String contextMenuItemTagStyles()
327{
328    return WEB_UI_STRING("Styles...", "Styles context menu item");
329}
330
331String contextMenuItemTagShowColors()
332{
333    return WEB_UI_STRING("Show Colors", "Show colors context menu item");
334}
335
336String contextMenuItemTagSpeechMenu()
337{
338    return WEB_UI_STRING("Speech", "Speech context sub-menu item");
339}
340
341String contextMenuItemTagStartSpeaking()
342{
343    return WEB_UI_STRING("Start Speaking", "Start speaking context menu item");
344}
345
346String contextMenuItemTagStopSpeaking()
347{
348    return WEB_UI_STRING("Stop Speaking", "Stop speaking context menu item");
349}
350#endif
351
352String contextMenuItemTagWritingDirectionMenu()
353{
354    return WEB_UI_STRING("Paragraph Direction", "Paragraph direction context sub-menu item");
355}
356
357String contextMenuItemTagTextDirectionMenu()
358{
359    return WEB_UI_STRING("Selection Direction", "Selection direction context sub-menu item");
360}
361
362String contextMenuItemTagDefaultDirection()
363{
364    return WEB_UI_STRING("Default", "Default writing direction context menu item");
365}
366
367String contextMenuItemTagLeftToRight()
368{
369    return WEB_UI_STRING("Left to Right", "Left to Right context menu item");
370}
371
372String contextMenuItemTagRightToLeft()
373{
374    return WEB_UI_STRING("Right to Left", "Right to Left context menu item");
375}
376
377#if PLATFORM(COCOA)
378
379String contextMenuItemTagCorrectSpellingAutomatically()
380{
381    return WEB_UI_STRING("Correct Spelling Automatically", "Correct Spelling Automatically context menu item");
382}
383
384String contextMenuItemTagSubstitutionsMenu()
385{
386    return WEB_UI_STRING("Substitutions", "Substitutions context sub-menu item");
387}
388
389String contextMenuItemTagShowSubstitutions(bool show)
390{
391    if (show)
392        return WEB_UI_STRING("Show Substitutions", "menu item title");
393    return WEB_UI_STRING("Hide Substitutions", "menu item title");
394}
395
396String contextMenuItemTagSmartCopyPaste()
397{
398    return WEB_UI_STRING("Smart Copy/Paste", "Smart Copy/Paste context menu item");
399}
400
401String contextMenuItemTagSmartQuotes()
402{
403    return WEB_UI_STRING("Smart Quotes", "Smart Quotes context menu item");
404}
405
406String contextMenuItemTagSmartDashes()
407{
408    return WEB_UI_STRING("Smart Dashes", "Smart Dashes context menu item");
409}
410
411String contextMenuItemTagSmartLinks()
412{
413    return WEB_UI_STRING("Smart Links", "Smart Links context menu item");
414}
415
416String contextMenuItemTagTextReplacement()
417{
418    return WEB_UI_STRING("Text Replacement", "Text Replacement context menu item");
419}
420
421String contextMenuItemTagTransformationsMenu()
422{
423    return WEB_UI_STRING("Transformations", "Transformations context sub-menu item");
424}
425
426String contextMenuItemTagMakeUpperCase()
427{
428    return WEB_UI_STRING("Make Upper Case", "Make Upper Case context menu item");
429}
430
431String contextMenuItemTagMakeLowerCase()
432{
433    return WEB_UI_STRING("Make Lower Case", "Make Lower Case context menu item");
434}
435
436String contextMenuItemTagCapitalize()
437{
438    return WEB_UI_STRING("Capitalize", "Capitalize context menu item");
439}
440
441String contextMenuItemTagChangeBack(const String& replacedString)
442{
443    notImplemented();
444    return replacedString;
445}
446
447#endif // PLATFORM(COCOA)
448
449String contextMenuItemTagOpenVideoInNewWindow()
450{
451    return WEB_UI_STRING("Open Video in New Window", "Open Video in New Window context menu item");
452}
453
454String contextMenuItemTagOpenAudioInNewWindow()
455{
456    return WEB_UI_STRING("Open Audio in New Window", "Open Audio in New Window context menu item");
457}
458
459String contextMenuItemTagDownloadVideoToDisk()
460{
461    return WEB_UI_STRING("Download Video", "Download Video To Disk context menu item");
462}
463
464String contextMenuItemTagDownloadAudioToDisk()
465{
466    return WEB_UI_STRING("Download Audio", "Download Audio To Disk context menu item");
467}
468
469String contextMenuItemTagCopyVideoLinkToClipboard()
470{
471    return WEB_UI_STRING("Copy Video Address", "Copy Video Address Location context menu item");
472}
473
474String contextMenuItemTagCopyAudioLinkToClipboard()
475{
476    return WEB_UI_STRING("Copy Audio Address", "Copy Audio Address Location context menu item");
477}
478
479String contextMenuItemTagToggleMediaControls()
480{
481    return WEB_UI_STRING("Controls", "Media Controls context menu item");
482}
483
484String contextMenuItemTagShowMediaControls()
485{
486    return WEB_UI_STRING("Show Controls", "Show Media Controls context menu item");
487}
488
489String contextMenuItemTagHideMediaControls()
490{
491    return WEB_UI_STRING("Hide Controls", "Hide Media Controls context menu item");
492}
493
494String contextMenuItemTagToggleMediaLoop()
495{
496    return WEB_UI_STRING("Loop", "Media Loop context menu item");
497}
498
499String contextMenuItemTagEnterVideoFullscreen()
500{
501    return WEB_UI_STRING("Enter Full Screen", "Video Enter Fullscreen context menu item");
502}
503
504String contextMenuItemTagExitVideoFullscreen()
505{
506    return WEB_UI_STRING("Exit Full Screen", "Video Exit Fullscreen context menu item");
507}
508
509String contextMenuItemTagMediaPlay()
510{
511    return WEB_UI_STRING("Play", "Media Play context menu item");
512}
513
514String contextMenuItemTagMediaPause()
515{
516    return WEB_UI_STRING("Pause", "Media Pause context menu item");
517}
518
519String contextMenuItemTagMediaMute()
520{
521    return WEB_UI_STRING("Mute", "Media Mute context menu item");
522}
523
524String contextMenuItemTagInspectElement()
525{
526    return WEB_UI_STRING("Inspect Element", "Inspect Element context menu item");
527}
528
529#endif // ENABLE(CONTEXT_MENUS)
530
531#if !PLATFORM(IOS)
532String searchMenuNoRecentSearchesText()
533{
534    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");
535}
536
537String searchMenuRecentSearchesText()
538{
539    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");
540}
541
542String searchMenuClearRecentSearchesText()
543{
544    return WEB_UI_STRING("Clear Recent Searches", "menu item in Recent Searches menu that empties menu's contents");
545}
546
547String AXWebAreaText()
548{
549    return WEB_UI_STRING("HTML content", "accessibility role description for web area");
550}
551
552String AXLinkText()
553{
554    return WEB_UI_STRING("link", "accessibility role description for link");
555}
556
557String AXListMarkerText()
558{
559    return WEB_UI_STRING("list marker", "accessibility role description for list marker");
560}
561
562String AXImageMapText()
563{
564    return WEB_UI_STRING("image map", "accessibility role description for image map");
565}
566
567String AXHeadingText()
568{
569    return WEB_UI_STRING("heading", "accessibility role description for headings");
570}
571
572String AXDefinitionText()
573{
574    return WEB_UI_STRING("definition", "role description of ARIA definition role");
575}
576
577String AXDescriptionListText()
578{
579    return WEB_UI_STRING("description list", "accessibility role description of a description list");
580}
581
582String AXDescriptionListTermText()
583{
584    return WEB_UI_STRING("term", "term word of a description list");
585}
586
587String AXDescriptionListDetailText()
588{
589    return WEB_UI_STRING("description", "description detail");
590}
591
592String AXFooterRoleDescriptionText()
593{
594    return WEB_UI_STRING("footer", "accessibility role description for a footer");
595}
596
597String AXFileUploadButtonText()
598{
599    return WEB_UI_STRING("file upload button", "accessibility role description for a file upload button");
600}
601
602String AXSearchFieldCancelButtonText()
603{
604    return WEB_UI_STRING("cancel", "accessibility description for a search field cancel button");
605}
606
607String AXButtonActionVerb()
608{
609    return WEB_UI_STRING("press", "Verb stating the action that will occur when a button is pressed, as used by accessibility");
610}
611
612String AXRadioButtonActionVerb()
613{
614    return WEB_UI_STRING("select", "Verb stating the action that will occur when a radio button is clicked, as used by accessibility");
615}
616
617String AXTextFieldActionVerb()
618{
619    return WEB_UI_STRING("activate", "Verb stating the action that will occur when a text field is selected, as used by accessibility");
620}
621
622String AXCheckedCheckBoxActionVerb()
623{
624    return WEB_UI_STRING("uncheck", "Verb stating the action that will occur when a checked checkbox is clicked, as used by accessibility");
625}
626
627String AXUncheckedCheckBoxActionVerb()
628{
629    return WEB_UI_STRING("check", "Verb stating the action that will occur when an unchecked checkbox is clicked, as used by accessibility");
630}
631
632String AXLinkActionVerb()
633{
634    return WEB_UI_STRING("jump", "Verb stating the action that will occur when a link is clicked, as used by accessibility");
635}
636
637String AXMenuListPopupActionVerb()
638{
639    notImplemented();
640    return "select";
641}
642
643String AXMenuListActionVerb()
644{
645    notImplemented();
646    return "select";
647}
648
649String AXListItemActionVerb()
650{
651    notImplemented();
652    return "select";
653}
654#endif // !PLATFORM(IOS)
655
656#if PLATFORM(COCOA)
657String AXARIAContentGroupText(const String& ariaType)
658{
659    if (ariaType == "ARIAApplicationAlert")
660        return WEB_UI_STRING("alert", "An ARIA accessibility group that acts as an alert.");
661    if (ariaType == "ARIAApplicationAlertDialog")
662        return WEB_UI_STRING("alert dialog", "An ARIA accessibility group that acts as an alert dialog.");
663    if (ariaType == "ARIAApplicationDialog")
664        return WEB_UI_STRING("dialog", "An ARIA accessibility group that acts as an dialog.");
665    if (ariaType == "ARIAApplicationLog")
666        return WEB_UI_STRING("log", "An ARIA accessibility group that acts as a console log.");
667    if (ariaType == "ARIAApplicationMarquee")
668        return WEB_UI_STRING("marquee", "An ARIA accessibility group that acts as a marquee.");
669    if (ariaType == "ARIAApplicationStatus")
670        return WEB_UI_STRING("application status", "An ARIA accessibility group that acts as a status update.");
671    if (ariaType == "ARIAApplicationTimer")
672        return WEB_UI_STRING("timer", "An ARIA accessibility group that acts as an updating timer.");
673    if (ariaType == "ARIADocument")
674        return WEB_UI_STRING("document", "An ARIA accessibility group that acts as a document.");
675    if (ariaType == "ARIADocumentArticle")
676        return WEB_UI_STRING("article", "An ARIA accessibility group that acts as an article.");
677    if (ariaType == "ARIADocumentNote")
678        return WEB_UI_STRING("note", "An ARIA accessibility group that acts as a note in a document.");
679    if (ariaType == "ARIADocumentRegion")
680        return WEB_UI_STRING("region", "An ARIA accessibility group that acts as a distinct region in a document.");
681    if (ariaType == "ARIALandmarkApplication")
682        return WEB_UI_STRING("application", "An ARIA accessibility group that acts as an application.");
683    if (ariaType == "ARIALandmarkBanner")
684        return WEB_UI_STRING("banner", "An ARIA accessibility group that acts as a banner.");
685    if (ariaType == "ARIALandmarkComplementary")
686        return WEB_UI_STRING("complementary", "An ARIA accessibility group that acts as a region of complementary information.");
687    if (ariaType == "ARIALandmarkContentInfo")
688        return WEB_UI_STRING("content information", "An ARIA accessibility group that contains content.");
689    if (ariaType == "ARIALandmarkMain")
690        return WEB_UI_STRING("main", "An ARIA accessibility group that is the main portion of the website.");
691    if (ariaType == "ARIALandmarkNavigation")
692        return WEB_UI_STRING("navigation", "An ARIA accessibility group that contains the main navigation elements of a website.");
693    if (ariaType == "ARIALandmarkSearch")
694        return WEB_UI_STRING("search", "An ARIA accessibility group that contains a search feature of a website.");
695    if (ariaType == "ARIAUserInterfaceTooltip")
696        return WEB_UI_STRING("tooltip", "An ARIA accessibility group that acts as a tooltip.");
697    if (ariaType == "ARIATabPanel")
698        return WEB_UI_STRING("tab panel", "An ARIA accessibility group that contains the content of a tab.");
699    if (ariaType == "ARIADocumentMath")
700        return WEB_UI_STRING("math", "An ARIA accessibility group that contains mathematical symbols.");
701    return String();
702}
703
704String AXHorizontalRuleDescriptionText()
705{
706    return WEB_UI_STRING("separator", "accessibility role description for a horizontal rule [<hr>]");
707}
708
709#endif // PLATFORM(COCOA)
710
711String missingPluginText()
712{
713    return WEB_UI_STRING("Missing Plug-in", "Label text to be used when a plugin is missing");
714}
715
716String crashedPluginText()
717{
718    return WEB_UI_STRING("Plug-in Failure", "Label text to be used if plugin host process has crashed");
719}
720
721String blockedPluginByContentSecurityPolicyText()
722{
723    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");
724}
725
726String insecurePluginVersionText()
727{
728    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");
729}
730
731String multipleFileUploadText(unsigned numberOfFiles)
732{
733    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);
734}
735
736String unknownFileSizeText()
737{
738    return WEB_UI_STRING_KEY("Unknown", "Unknown (filesize)", "Unknown filesize FTP directory listing item");
739}
740
741#if PLATFORM(WIN)
742String uploadFileText()
743{
744    notImplemented();
745    return "upload";
746}
747
748String allFilesText()
749{
750    notImplemented();
751    return "all files";
752}
753#endif
754
755#if PLATFORM(COCOA)
756String builtInPDFPluginName()
757{
758    // Also exposed to DOM.
759    return WEB_UI_STRING("WebKit built-in PDF", "Pseudo plug-in name, visible in the Installed Plug-ins page in Safari.");
760}
761
762String pdfDocumentTypeDescription()
763{
764    // Also exposed to DOM.
765    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.");
766}
767
768String postScriptDocumentTypeDescription()
769{
770    // Also exposed to DOM.
771    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.");
772}
773
774String keygenMenuItem512()
775{
776    return WEB_UI_STRING("512 (Low Grade)", "Menu item title for KEYGEN pop-up menu");
777}
778
779String keygenMenuItem1024()
780{
781    return WEB_UI_STRING("1024 (Medium Grade)", "Menu item title for KEYGEN pop-up menu");
782}
783
784String keygenMenuItem2048()
785{
786    return WEB_UI_STRING("2048 (High Grade)", "Menu item title for KEYGEN pop-up menu");
787}
788
789String keygenKeychainItemName(const String& host)
790{
791    return formatLocalizedString(WEB_UI_STRING("Key from %@", "Name of keychain key generated by the KEYGEN tag"), host.createCFString().get());
792}
793
794#endif
795
796#if PLATFORM(IOS)
797String htmlSelectMultipleItems(size_t count)
798{
799    switch (count) {
800    case 0:
801        return WEB_UI_STRING("0 Items", "Present the element <select multiple> when no <option> items are selected (iOS only)");
802    case 1:
803        return WEB_UI_STRING("1 Item", "Present the element <select multiple> when a single <option> is selected (iOS only)");
804    default:
805        return formatLocalizedString(WEB_UI_STRING("%zu Items", "Present the number of selected <option> items in a <select multiple> element (iOS only)"), count);
806    }
807}
808
809String fileButtonChooseMediaFileLabel()
810{
811    return WEB_UI_STRING("Choose Media (Single)", "Title for file button used in HTML forms for media files");
812}
813
814String fileButtonChooseMultipleMediaFilesLabel()
815{
816    return WEB_UI_STRING("Choose Media (Multiple)", "Title for file button used in HTML5 forms for multiple media files");
817}
818
819String fileButtonNoMediaFileSelectedLabel()
820{
821    return WEB_UI_STRING("no media selected (single)", "Text to display in file button used in HTML forms for media files when no media file is selected");
822}
823
824String fileButtonNoMediaFilesSelectedLabel()
825{
826    return WEB_UI_STRING("no media selected (multiple)", "Text to display in file button used in HTML forms for media files when no media files are selected and the button allows multiple files to be selected");
827}
828#endif
829
830String imageTitle(const String& filename, const IntSize& size)
831{
832#if USE(CF)
833    RetainPtr<CFLocaleRef> locale = adoptCF(CFLocaleCopyCurrent());
834    RetainPtr<CFNumberFormatterRef> formatter = adoptCF(CFNumberFormatterCreate(0, locale.get(), kCFNumberFormatterDecimalStyle));
835
836    int widthInt = size.width();
837    RetainPtr<CFNumberRef> width = adoptCF(CFNumberCreate(0, kCFNumberIntType, &widthInt));
838    RetainPtr<CFStringRef> widthString = adoptCF(CFNumberFormatterCreateStringWithNumber(0, formatter.get(), width.get()));
839
840    int heightInt = size.height();
841    RetainPtr<CFNumberRef> height = adoptCF(CFNumberCreate(0, kCFNumberIntType, &heightInt));
842    RetainPtr<CFStringRef> heightString = adoptCF(CFNumberFormatterCreateStringWithNumber(0, formatter.get(), height.get()));
843
844    return formatLocalizedString(WEB_UI_STRING("%@ %@×%@ pixels", "window title for a standalone image (uses multiplication symbol, not x)"), filename.createCFString().get(), widthString.get(), heightString.get());
845#else
846    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);
847#endif
848}
849
850String mediaElementLoadingStateText()
851{
852    return WEB_UI_STRING("Loading...", "Media controller status message when the media is loading");
853}
854
855String mediaElementLiveBroadcastStateText()
856{
857    return WEB_UI_STRING("Live Broadcast", "Media controller status message when watching a live broadcast");
858}
859
860String localizedMediaControlElementString(const String& name)
861{
862    if (name == "AudioElement")
863        return WEB_UI_STRING("audio playback", "accessibility label for audio element controller");
864    if (name == "VideoElement")
865        return WEB_UI_STRING("video playback", "accessibility label for video element controller");
866    if (name == "MuteButton")
867        return WEB_UI_STRING("mute", "accessibility label for mute button");
868    if (name == "UnMuteButton")
869        return WEB_UI_STRING("unmute", "accessibility label for turn mute off button");
870    if (name == "PlayButton")
871        return WEB_UI_STRING("play", "accessibility label for play button");
872    if (name == "PauseButton")
873        return WEB_UI_STRING("pause", "accessibility label for pause button");
874    if (name == "Slider")
875        return WEB_UI_STRING("movie time", "accessibility label for timeline slider");
876    if (name == "SliderThumb")
877        return WEB_UI_STRING("timeline slider thumb", "accessibility label for timeline thumb");
878    if (name == "RewindButton")
879        return WEB_UI_STRING("back 30 seconds", "accessibility label for seek back 30 seconds button");
880    if (name == "ReturnToRealtimeButton")
881        return WEB_UI_STRING("return to realtime", "accessibility label for return to real time button");
882    if (name == "CurrentTimeDisplay")
883        return WEB_UI_STRING("elapsed time", "accessibility label for elapsed time display");
884    if (name == "TimeRemainingDisplay")
885        return WEB_UI_STRING("remaining time", "accessibility label for time remaining display");
886    if (name == "StatusDisplay")
887        return WEB_UI_STRING("status", "accessibility label for movie status");
888    if (name == "EnterFullscreenButton")
889        return WEB_UI_STRING("enter fullscreen", "accessibility label for enter fullscreen button");
890    if (name == "ExitFullscreenButton")
891        return WEB_UI_STRING("exit fullscreen", "accessibility label for exit fullscreen button");
892    if (name == "SeekForwardButton")
893        return WEB_UI_STRING("fast forward", "accessibility label for fast forward button");
894    if (name == "SeekBackButton")
895        return WEB_UI_STRING("fast reverse", "accessibility label for fast reverse button");
896    if (name == "ShowClosedCaptionsButton")
897        return WEB_UI_STRING("show closed captions", "accessibility label for show closed captions button");
898    if (name == "HideClosedCaptionsButton")
899        return WEB_UI_STRING("hide closed captions", "accessibility label for hide closed captions button");
900
901    // FIXME: the ControlsPanel container should never be visible in the accessibility hierarchy.
902    if (name == "ControlsPanel")
903        return String();
904
905    ASSERT_NOT_REACHED();
906    return String();
907}
908
909String localizedMediaControlElementHelpText(const String& name)
910{
911    if (name == "AudioElement")
912        return WEB_UI_STRING("audio element playback controls and status display", "accessibility help text for audio element controller");
913    if (name == "VideoElement")
914        return WEB_UI_STRING("video element playback controls and status display", "accessibility help text for video element controller");
915    if (name == "MuteButton")
916        return WEB_UI_STRING("mute audio tracks", "accessibility help text for mute button");
917    if (name == "UnMuteButton")
918        return WEB_UI_STRING("unmute audio tracks", "accessibility help text for un mute button");
919    if (name == "PlayButton")
920        return WEB_UI_STRING("begin playback", "accessibility help text for play button");
921    if (name == "PauseButton")
922        return WEB_UI_STRING("pause playback", "accessibility help text for pause button");
923    if (name == "Slider")
924        return WEB_UI_STRING("movie time scrubber", "accessibility help text for timeline slider");
925    if (name == "SliderThumb")
926        return WEB_UI_STRING("movie time scrubber thumb", "accessibility help text for timeline slider thumb");
927    if (name == "RewindButton")
928        return WEB_UI_STRING("seek movie back 30 seconds", "accessibility help text for jump back 30 seconds button");
929    if (name == "ReturnToRealtimeButton")
930        return WEB_UI_STRING("return streaming movie to real time", "accessibility help text for return streaming movie to real time button");
931    if (name == "CurrentTimeDisplay")
932        return WEB_UI_STRING("current movie time in seconds", "accessibility help text for elapsed time display");
933    if (name == "TimeRemainingDisplay")
934        return WEB_UI_STRING("number of seconds of movie remaining", "accessibility help text for remaining time display");
935    if (name == "StatusDisplay")
936        return WEB_UI_STRING("current movie status", "accessibility help text for movie status display");
937    if (name == "SeekBackButton")
938        return WEB_UI_STRING("seek quickly back", "accessibility help text for fast rewind button");
939    if (name == "SeekForwardButton")
940        return WEB_UI_STRING("seek quickly forward", "accessibility help text for fast forward button");
941    if (name == "FullscreenButton")
942        return WEB_UI_STRING("Play movie in fullscreen mode", "accessibility help text for enter fullscreen button");
943    if (name == "ShowClosedCaptionsButton")
944        return WEB_UI_STRING("start displaying closed captions", "accessibility help text for show closed captions button");
945    if (name == "HideClosedCaptionsButton")
946        return WEB_UI_STRING("stop displaying closed captions", "accessibility help text for hide closed captions button");
947
948    // The description of this button is descriptive enough that it doesn't require help text.
949    if (name == "EnterFullscreenButton")
950        return String();
951
952    ASSERT_NOT_REACHED();
953    return String();
954}
955
956String localizedMediaTimeDescription(float time)
957{
958    if (!std::isfinite(time))
959        return WEB_UI_STRING("indefinite time", "accessibility help text for an indefinite media controller time value");
960
961    int seconds = static_cast<int>(fabsf(time));
962    int days = seconds / (60 * 60 * 24);
963    int hours = seconds / (60 * 60);
964    int minutes = (seconds / 60) % 60;
965    seconds %= 60;
966
967    if (days)
968        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);
969    if (hours)
970        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);
971    if (minutes)
972        return formatLocalizedString(WEB_UI_STRING("%1$d minutes %2$d seconds", "accessibility help text for media controller time value >= 60 seconds"), minutes, seconds);
973    return formatLocalizedString(WEB_UI_STRING("%1$d seconds", "accessibility help text for media controller time value < 60 seconds"), seconds);
974}
975
976String validationMessageValueMissingText()
977{
978    return WEB_UI_STRING("value missing", "Validation message for required form control elements that have no value");
979}
980
981String validationMessageValueMissingForCheckboxText()
982{
983    return validationMessageValueMissingText();
984}
985
986String validationMessageValueMissingForFileText()
987{
988    return validationMessageValueMissingText();
989}
990
991String validationMessageValueMissingForMultipleFileText()
992{
993    return validationMessageValueMissingText();
994}
995
996String validationMessageValueMissingForRadioText()
997{
998    return validationMessageValueMissingText();
999}
1000
1001String validationMessageValueMissingForSelectText()
1002{
1003    return validationMessageValueMissingText();
1004}
1005
1006String validationMessageTypeMismatchText()
1007{
1008    return WEB_UI_STRING("type mismatch", "Validation message for input form controls with a value not matching type");
1009}
1010
1011String validationMessageTypeMismatchForEmailText()
1012{
1013    return validationMessageTypeMismatchText();
1014}
1015
1016String validationMessageTypeMismatchForMultipleEmailText()
1017{
1018    return validationMessageTypeMismatchText();
1019}
1020
1021String validationMessageTypeMismatchForURLText()
1022{
1023    return validationMessageTypeMismatchText();
1024}
1025
1026String validationMessagePatternMismatchText()
1027{
1028    return WEB_UI_STRING("pattern mismatch", "Validation message for input form controls requiring a constrained value according to pattern");
1029}
1030
1031String validationMessageTooLongText(int, int)
1032{
1033    return WEB_UI_STRING("too long", "Validation message for form control elements with a value longer than maximum allowed length");
1034}
1035
1036String validationMessageRangeUnderflowText(const String&)
1037{
1038    return WEB_UI_STRING("range underflow", "Validation message for input form controls with value lower than allowed minimum");
1039}
1040
1041String validationMessageRangeOverflowText(const String&)
1042{
1043    return WEB_UI_STRING("range overflow", "Validation message for input form controls with value higher than allowed maximum");
1044}
1045
1046String validationMessageStepMismatchText(const String&, const String&)
1047{
1048    return WEB_UI_STRING("step mismatch", "Validation message for input form controls with value not respecting the step attribute");
1049}
1050
1051String validationMessageBadInputForNumberText()
1052{
1053    notImplemented();
1054    return validationMessageTypeMismatchText();
1055}
1056
1057String clickToExitFullScreenText()
1058{
1059    return WEB_UI_STRING("Click to exit full screen mode", "Message to display in browser window when in webkit full screen mode.");
1060}
1061
1062#if ENABLE(VIDEO_TRACK)
1063String textTrackSubtitlesText()
1064{
1065    return WEB_UI_STRING("Subtitles", "Menu section heading for subtitles");
1066}
1067
1068String textTrackOffMenuItemText()
1069{
1070    return WEB_UI_STRING("Off", "Menu item label for the track that represents disabling closed captions");
1071}
1072
1073String textTrackAutomaticMenuItemText()
1074{
1075    return formatLocalizedString(WEB_UI_STRING("Auto (Recommended)", "Menu item label for automatic track selection behavior"));
1076}
1077
1078String textTrackNoLabelText()
1079{
1080    return WEB_UI_STRING_KEY("Unknown", "Unknown (text track)", "Menu item label for a text track that has no other name");
1081}
1082
1083#if PLATFORM(COCOA) || PLATFORM(WIN)
1084String textTrackCountryAndLanguageMenuItemText(const String& title, const String& country, const String& language)
1085{
1086    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());
1087}
1088
1089String textTrackLanguageMenuItemText(const String& title, const String& language)
1090{
1091    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());
1092}
1093
1094String closedCaptionTrackMenuItemText(const String& title)
1095{
1096    return formatLocalizedString(WEB_UI_STRING("%@ CC", "Text track contains closed captions"), title.createCFString().get());
1097}
1098
1099String sdhTrackMenuItemText(const String& title)
1100{
1101    return formatLocalizedString(WEB_UI_STRING("%@ SDH", "Text track contains subtitles for the deaf and hard of hearing"), title.createCFString().get());
1102}
1103
1104String easyReaderTrackMenuItemText(const String& title)
1105{
1106    return formatLocalizedString(WEB_UI_STRING("%@ Easy Reader", "Text track contains simplified (3rd grade level) subtitles"), title.createCFString().get());
1107}
1108#endif
1109
1110#endif
1111
1112String snapshottedPlugInLabelTitle()
1113{
1114    return WEB_UI_STRING("Snapshotted Plug-In", "Title of the label to show on a snapshotted plug-in");
1115}
1116
1117String snapshottedPlugInLabelSubtitle()
1118{
1119    return WEB_UI_STRING("Click to restart", "Subtitle of the label to show on a snapshotted plug-in");
1120}
1121
1122String useBlockedPlugInContextMenuTitle()
1123{
1124    return formatLocalizedString(WEB_UI_STRING("Show in blocked plug-in", "Title of the context menu item to show when PDFPlugin was used instead of a blocked plugin"));
1125}
1126
1127#if ENABLE(SUBTLE_CRYPTO)
1128String webCryptoMasterKeyKeychainLabel(const String& localizedApplicationName)
1129{
1130    return formatLocalizedString(WEB_UI_STRING("%@ WebCrypto Master Key", "Name of application's single WebCrypto master key in Keychain"), localizedApplicationName.createCFString().get());
1131}
1132
1133String webCryptoMasterKeyKeychainComment()
1134{
1135    return WEB_UI_STRING("Used to encrypt WebCrypto keys in persistent storage, such as IndexedDB", "Description of WebCrypto master keys in Keychain");
1136}
1137#endif
1138
1139} // namespace WebCore
1140