7ff4fc3467395a36fde4e619db32840003a8ba80
[WebKit-https.git] / Source / WebCore / platform / LocalizedStrings.cpp
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 <wtf/MathExtras.h>
33 #include <wtf/text/TextBreakIterator.h>
34 #include <wtf/unicode/CharacterNames.h>
35
36 #if USE(CF)
37 #include <wtf/RetainPtr.h>
38 #endif
39
40 #if USE(GLIB)
41 #include <wtf/glib/GUniquePtr.h>
42 #endif
43
44 namespace WebCore {
45
46 // We can't use String::deprecatedFormat 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.
51 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     auto 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 #elif USE(GLIB)
69     va_list arguments;
70     va_start(arguments, format);
71     GUniquePtr<gchar> result(g_strdup_vprintf(format.utf8().data(), arguments));
72     va_end(arguments);
73     return String::fromUTF8(result.get());
74 #else
75     notImplemented();
76     return format;
77 #endif
78 }
79
80 #if ENABLE(CONTEXT_MENUS)
81
82 static String truncatedStringForLookupMenuItem(const String& original)
83 {
84     // Truncate the string if it's too long. This number is roughly the same as the one used by AppKit.
85     unsigned maxNumberOfGraphemeClustersInLookupMenuItem = 24;
86
87     String trimmed = original.stripWhiteSpace();
88     unsigned numberOfCharacters = numCodeUnitsInGraphemeClusters(trimmed, maxNumberOfGraphemeClustersInLookupMenuItem);
89     return numberOfCharacters == trimmed.length() ? trimmed : makeString(trimmed.left(numberOfCharacters), horizontalEllipsis);
90 }
91
92 #endif
93
94 String inputElementAltText()
95 {
96     return WEB_UI_STRING_KEY("Submit", "Submit (input element)", "alt text for <input> elements with no alt, title, or value");
97 }
98
99 String resetButtonDefaultLabel()
100 {
101     return WEB_UI_STRING("Reset", "default label for Reset buttons in forms on web pages");
102 }
103
104 String searchableIndexIntroduction()
105 {
106     return WEB_UI_STRING("This is a searchable index. Enter search keywords: ",
107                          "text that appears at the start of nearly-obsolete web pages in the form of a 'searchable index'");
108 }
109
110 String submitButtonDefaultLabel()
111 {
112     return WEB_UI_STRING("Submit", "default label for Submit buttons in forms on web pages");
113 }
114
115 String fileButtonChooseFileLabel()
116 {
117     return WEB_UI_STRING("Choose File", "title for a single file chooser button used in HTML forms");
118 }
119
120 String fileButtonChooseMultipleFilesLabel()
121 {
122     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.");
123 }
124
125 String fileButtonNoFileSelectedLabel()
126 {
127     return WEB_UI_STRING("no file selected", "text to display in file button used in HTML forms when no file is selected");
128 }
129
130 String fileButtonNoFilesSelectedLabel()
131 {
132     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");
133 }
134
135 String defaultDetailsSummaryText()
136 {
137     return WEB_UI_STRING("Details", "text to display in <details> tag when it has no <summary> child");
138 }
139
140 #if ENABLE(CONTEXT_MENUS)
141
142 String contextMenuItemTagOpenLinkInNewWindow()
143 {
144     return WEB_UI_STRING_WITH_MNEMONIC("Open Link in New Window", "Open Link in New _Window", "Open in New Window context menu item");
145 }
146
147 String contextMenuItemTagDownloadLinkToDisk()
148 {
149     return WEB_UI_STRING_WITH_MNEMONIC("Download Linked File", "_Download Linked File", "Download Linked File context menu item");
150 }
151
152 #if !PLATFORM(GTK)
153 String contextMenuItemTagCopyLinkToClipboard()
154 {
155     return WEB_UI_STRING("Copy Link", "Copy Link context menu item");
156 }
157 #endif
158
159 String contextMenuItemTagOpenImageInNewWindow()
160 {
161     return WEB_UI_STRING_WITH_MNEMONIC("Open Image in New Window", "Open _Image in New Window", "Open Image in New Window context menu item");
162 }
163
164 #if !PLATFORM(GTK)
165 String contextMenuItemTagDownloadImageToDisk()
166 {
167     return WEB_UI_STRING("Download Image", "Download Image context menu item");
168 }
169 #endif
170
171 String contextMenuItemTagCopyImageToClipboard()
172 {
173     return WEB_UI_STRING_WITH_MNEMONIC("Copy Image", "Cop_y Image", "Copy Image context menu item");
174 }
175
176 String contextMenuItemTagOpenFrameInNewWindow()
177 {
178     return WEB_UI_STRING_WITH_MNEMONIC("Open Frame in New Window", "Open _Frame in New Window", "Open Frame in New Window context menu item");
179 }
180
181 String contextMenuItemTagCopy()
182 {
183     return WEB_UI_STRING_WITH_MNEMONIC("Copy", "_Copy", "Copy context menu item");
184 }
185
186 String contextMenuItemTagGoBack()
187 {
188     return WEB_UI_STRING_WITH_MNEMONIC("Back", "_Back", "Back context menu item");
189 }
190
191 String contextMenuItemTagGoForward()
192 {
193     return WEB_UI_STRING_WITH_MNEMONIC("Forward", "_Forward", "Forward context menu item");
194 }
195
196 String contextMenuItemTagStop()
197 {
198     return WEB_UI_STRING_WITH_MNEMONIC("Stop", "_Stop", "Stop context menu item");
199 }
200
201 String contextMenuItemTagReload()
202 {
203     return WEB_UI_STRING_WITH_MNEMONIC("Reload", "_Reload", "Reload context menu item");
204 }
205
206 String contextMenuItemTagCut()
207 {
208     return WEB_UI_STRING_WITH_MNEMONIC("Cut", "Cu_t", "Cut context menu item");
209 }
210
211 String contextMenuItemTagPaste()
212 {
213     return WEB_UI_STRING_WITH_MNEMONIC("Paste", "_Paste", "Paste context menu item");
214 }
215
216 String contextMenuItemTagNoGuessesFound()
217 {
218     return WEB_UI_STRING("No Guesses Found", "No Guesses Found context menu item");
219 }
220
221 String contextMenuItemTagIgnoreSpelling()
222 {
223     return WEB_UI_STRING_WITH_MNEMONIC("Ignore Spelling", "_Ignore Spelling", "Ignore Spelling context menu item");
224 }
225
226 String contextMenuItemTagLearnSpelling()
227 {
228     return WEB_UI_STRING_WITH_MNEMONIC("Learn Spelling", "_Learn Spelling", "Learn Spelling context menu item");
229 }
230
231 String contextMenuItemTagLookUpInDictionary(const String& selectedString)
232 {
233 #if USE(CF)
234     auto selectedCFString = truncatedStringForLookupMenuItem(selectedString).createCFString();
235     return formatLocalizedString(WEB_UI_CFSTRING("Look Up “%@”", "Look Up context menu item with selected word"), selectedCFString.get());
236 #elif USE(GLIB)
237     return formatLocalizedString(WEB_UI_STRING("Look Up “%s”", "Look Up context menu item with selected word"), truncatedStringForLookupMenuItem(selectedString).utf8().data());
238 #else
239     return WEB_UI_STRING("Look Up “<selection>”", "Look Up context menu item with selected word").replace("<selection>", truncatedStringForLookupMenuItem(selectedString));
240 #endif
241 }
242
243 String contextMenuItemTagOpenLink()
244 {
245     return WEB_UI_STRING_WITH_MNEMONIC("Open Link", "_Open Link", "Open Link context menu item");
246 }
247
248 String contextMenuItemTagIgnoreGrammar()
249 {
250     return WEB_UI_STRING_WITH_MNEMONIC("Ignore Grammar", "Ignore _Grammar", "Ignore Grammar context menu item");
251 }
252
253 String contextMenuItemTagSpellingMenu()
254 {
255     return WEB_UI_STRING_WITH_MNEMONIC("Spelling and Grammar", "Spelling and _Grammar", "Spelling and Grammar context sub-menu item");
256 }
257
258 String contextMenuItemTagShowSpellingPanel(bool show)
259 {
260     if (show)
261         return WEB_UI_STRING_WITH_MNEMONIC("Show Spelling and Grammar", "_Show Spelling and Grammar", "menu item title");
262     return WEB_UI_STRING_WITH_MNEMONIC("Hide Spelling and Grammar", "_Hide Spelling and Grammar", "menu item title");
263 }
264
265 String contextMenuItemTagCheckSpelling()
266 {
267     return WEB_UI_STRING_WITH_MNEMONIC("Check Document Now", "_Check Document Now", "Check spelling context menu item");
268 }
269
270 String contextMenuItemTagCheckSpellingWhileTyping()
271 {
272     return WEB_UI_STRING_WITH_MNEMONIC("Check Spelling While Typing", "Check Spelling While _Typing", "Check spelling while typing context menu item");
273 }
274
275 String contextMenuItemTagCheckGrammarWithSpelling()
276 {
277     return WEB_UI_STRING_WITH_MNEMONIC("Check Grammar With Spelling", "Check _Grammar With Spelling", "Check grammar with spelling context menu item");
278 }
279
280 String contextMenuItemTagFontMenu()
281 {
282     return WEB_UI_STRING_WITH_MNEMONIC("Font", "_Font", "Font context sub-menu item");
283 }
284
285 String contextMenuItemTagBold()
286 {
287     return WEB_UI_STRING_WITH_MNEMONIC("Bold", "_Bold", "Bold context menu item");
288 }
289
290 String contextMenuItemTagItalic()
291 {
292     return WEB_UI_STRING_WITH_MNEMONIC("Italic", "_Italic", "Italic context menu item");
293 }
294
295 String contextMenuItemTagUnderline()
296 {
297     return WEB_UI_STRING_WITH_MNEMONIC("Underline", "_Underline", "Underline context menu item");
298 }
299
300 String contextMenuItemTagOutline()
301 {
302     return WEB_UI_STRING_WITH_MNEMONIC("Outline", "_Outline", "Outline context menu item");
303 }
304
305 #if !PLATFORM(GTK)
306 String contextMenuItemTagWritingDirectionMenu()
307 {
308     return WEB_UI_STRING("Paragraph Direction", "Paragraph direction context sub-menu item");
309 }
310
311 String contextMenuItemTagTextDirectionMenu()
312 {
313     return WEB_UI_STRING("Selection Direction", "Selection direction context sub-menu item");
314 }
315
316 String contextMenuItemTagDefaultDirection()
317 {
318     return WEB_UI_STRING("Default", "Default writing direction context menu item");
319 }
320
321 String contextMenuItemTagLeftToRight()
322 {
323     return WEB_UI_STRING("Left to Right", "Left to Right context menu item");
324 }
325
326 String contextMenuItemTagRightToLeft()
327 {
328     return WEB_UI_STRING("Right to Left", "Right to Left context menu item");
329 }
330 #endif
331
332 String contextMenuItemTagOpenVideoInNewWindow()
333 {
334     return WEB_UI_STRING_WITH_MNEMONIC("Open Video in New Window", "Open _Video in New Window", "Open Video in New Window context menu item");
335 }
336
337 String contextMenuItemTagOpenAudioInNewWindow()
338 {
339     return WEB_UI_STRING_WITH_MNEMONIC("Open Audio in New Window", "Open _Audio in New Window", "Open Audio in New Window context menu item");
340 }
341
342 String contextMenuItemTagDownloadVideoToDisk()
343 {
344     return WEB_UI_STRING_WITH_MNEMONIC("Download Video", "Download _Video", "Download Video To Disk context menu item");
345 }
346
347 String contextMenuItemTagDownloadAudioToDisk()
348 {
349     return WEB_UI_STRING_WITH_MNEMONIC("Download Audio", "Download _Audio", "Download Audio To Disk context menu item");
350 }
351
352 #if !PLATFORM(GTK)
353 String contextMenuItemTagCopyVideoLinkToClipboard()
354 {
355     return WEB_UI_STRING("Copy Video Address", "Copy Video Address Location context menu item");
356 }
357
358 String contextMenuItemTagCopyAudioLinkToClipboard()
359 {
360     return WEB_UI_STRING("Copy Audio Address", "Copy Audio Address Location context menu item");
361 }
362
363 String contextMenuItemTagToggleMediaControls()
364 {
365     return WEB_UI_STRING("Controls", "Media Controls context menu item");
366 }
367
368 String contextMenuItemTagShowMediaControls()
369 {
370     return WEB_UI_STRING("Show Controls", "Show Media Controls context menu item");
371 }
372
373 String contextMenuItemTagHideMediaControls()
374 {
375     return WEB_UI_STRING("Hide Controls", "Hide Media Controls context menu item");
376 }
377
378 String contextMenuItemTagToggleMediaLoop()
379 {
380     return WEB_UI_STRING("Loop", "Media Loop context menu item");
381 }
382
383 String contextMenuItemTagEnterVideoFullscreen()
384 {
385     return WEB_UI_STRING("Enter Full Screen", "Video Enter Fullscreen context menu item");
386 }
387
388 String contextMenuItemTagExitVideoFullscreen()
389 {
390     return WEB_UI_STRING_KEY("Exit Full Screen", "Exit Full Screen (context menu)", "Video Exit Fullscreen context menu item");
391 }
392 #endif
393
394 String contextMenuItemTagMediaPlay()
395 {
396     return WEB_UI_STRING_WITH_MNEMONIC("Play", "_Play", "Media Play context menu item");
397 }
398
399 String contextMenuItemTagMediaPause()
400 {
401     return WEB_UI_STRING_WITH_MNEMONIC("Pause", "_Pause", "Media Pause context menu item");
402 }
403
404 String contextMenuItemTagMediaMute()
405 {
406     return WEB_UI_STRING_WITH_MNEMONIC("Mute", "_Mute", "Media Mute context menu item");
407 }
408
409 String contextMenuItemTagInspectElement()
410 {
411     return WEB_UI_STRING_WITH_MNEMONIC("Inspect Element", "Inspect _Element", "Inspect Element context menu item");
412 }
413
414 #endif // ENABLE(CONTEXT_MENUS)
415
416 #if !PLATFORM(IOS)
417
418 String searchMenuNoRecentSearchesText()
419 {
420     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");
421 }
422
423 String searchMenuRecentSearchesText()
424 {
425     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");
426 }
427
428 String searchMenuClearRecentSearchesText()
429 {
430     return WEB_UI_STRING("Clear Recent Searches", "menu item in Recent Searches menu that empties menu's contents");
431 }
432
433 #endif // !PLATFORM(IOS)
434
435 String AXWebAreaText()
436 {
437     return WEB_UI_STRING("HTML content", "accessibility role description for web area");
438 }
439
440 String AXLinkText()
441 {
442     return WEB_UI_STRING("link", "accessibility role description for link");
443 }
444
445 String AXListMarkerText()
446 {
447     return WEB_UI_STRING("list marker", "accessibility role description for list marker");
448 }
449
450 String AXImageMapText()
451 {
452     return WEB_UI_STRING("image map", "accessibility role description for image map");
453 }
454
455 String AXHeadingText()
456 {
457     return WEB_UI_STRING("heading", "accessibility role description for headings");
458 }
459
460 String AXDefinitionText()
461 {
462     return WEB_UI_STRING("definition", "role description of ARIA definition role");
463 }
464
465 String AXDescriptionListText()
466 {
467     return WEB_UI_STRING("description list", "accessibility role description of a description list");
468 }
469
470 String AXDescriptionListTermText()
471 {
472     return WEB_UI_STRING("term", "term word of a description list");
473 }
474
475 String AXDescriptionListDetailText()
476 {
477     return WEB_UI_STRING("description", "description detail");
478 }
479
480 String AXDetailsText()
481 {
482     return WEB_UI_STRING("details", "accessibility role description for a details element");
483 }
484
485 String AXSummaryText()
486 {
487     return WEB_UI_STRING("summary", "accessibility role description for a summary element");
488 }
489
490 String AXFooterRoleDescriptionText()
491 {
492     return WEB_UI_STRING("footer", "accessibility role description for a footer");
493 }
494
495 String AXFileUploadButtonText()
496 {
497     return WEB_UI_STRING("file upload button", "accessibility role description for a file upload button");
498 }
499
500 String AXOutputText()
501 {
502     return WEB_UI_STRING("output", "accessibility role description for an output element");
503 }
504
505 String AXAttachmentRoleText()
506 {
507     return WEB_UI_STRING("attachment", "accessibility role description for an attachment element");
508 }
509     
510 String AXSearchFieldCancelButtonText()
511 {
512     return WEB_UI_STRING("cancel", "accessibility description for a search field cancel button");
513 }
514
515 String AXFeedText()
516 {
517     return WEB_UI_STRING("feed", "accessibility role description for a group containing a scrollable list of articles.");
518 }
519
520 String AXFigureText()
521 {
522     return WEB_UI_STRING("figure", "accessibility role description for a figure element.");
523 }
524
525 String AXEmailFieldText()
526 {
527     return WEB_UI_STRING("email field", "accessibility role description for an email field.");
528 }
529
530 String AXTelephoneFieldText()
531 {
532     return WEB_UI_STRING("telephone number field", "accessibility role description for a telephone number field.");
533 }
534
535 String AXURLFieldText()
536 {
537     return WEB_UI_STRING("URL field", "accessibility role description for a URL field.");
538 }
539
540 String AXDateFieldText()
541 {
542     return WEB_UI_STRING("date field", "accessibility role description for a date field.");
543 }
544
545 String AXTimeFieldText()
546 {
547     return WEB_UI_STRING("time field", "accessibility role description for a time field.");
548 }
549
550 String AXDateTimeFieldText()
551 {
552     return WEB_UI_STRING("date and time field", "accessibility role description for a date and time field.");
553 }
554
555 String AXMonthFieldText()
556 {
557     return WEB_UI_STRING("month and year field", "accessibility role description for a month field.");
558 }
559
560 String AXNumberFieldText()
561 {
562     return WEB_UI_STRING("number field", "accessibility role description for a number field.");
563 }
564
565 String AXWeekFieldText()
566 {
567     return WEB_UI_STRING("week and year field", "accessibility role description for a time field.");
568 }
569
570 String AXButtonActionVerb()
571 {
572     return WEB_UI_STRING("press", "Verb stating the action that will occur when a button is pressed, as used by accessibility");
573 }
574
575 String AXRadioButtonActionVerb()
576 {
577     return WEB_UI_STRING("select", "Verb stating the action that will occur when a radio button is clicked, as used by accessibility");
578 }
579
580 String AXTextFieldActionVerb()
581 {
582     return WEB_UI_STRING("activate", "Verb stating the action that will occur when a text field is selected, as used by accessibility");
583 }
584
585 String AXCheckedCheckBoxActionVerb()
586 {
587     return WEB_UI_STRING("uncheck", "Verb stating the action that will occur when a checked checkbox is clicked, as used by accessibility");
588 }
589
590 String AXUncheckedCheckBoxActionVerb()
591 {
592     return WEB_UI_STRING("check", "Verb stating the action that will occur when an unchecked checkbox is clicked, as used by accessibility");
593 }
594
595 String AXLinkActionVerb()
596 {
597     return WEB_UI_STRING("jump", "Verb stating the action that will occur when a link is clicked, as used by accessibility");
598 }
599
600 String AXMenuListPopupActionVerb()
601 {
602     notImplemented();
603     return "select";
604 }
605
606 String AXMenuListActionVerb()
607 {
608     notImplemented();
609     return "select";
610 }
611
612 String AXListItemActionVerb()
613 {
614     notImplemented();
615     return "select";
616 }
617
618 String AXAutoFillCredentialsLabel()
619 {
620     return WEB_UI_STRING("password auto fill", "Label for the auto fill credentials button inside a text field.");
621 }
622
623 String AXAutoFillContactsLabel()
624 {
625     return WEB_UI_STRING("contact info auto fill", "Label for the auto fill contacts button inside a text field.");
626 }
627
628 String AXAutoFillStrongPasswordLabel()
629 {
630     return WEB_UI_STRING("strong password auto fill", "Label for the strong password auto fill button inside a text field.");
631 }
632
633 String autoFillStrongPasswordLabel()
634 {
635     return WEB_UI_STRING("Strong Password", "Label for strong password.");
636 }
637
638 String missingPluginText()
639 {
640     return WEB_UI_STRING("Missing Plug-in", "Label text to be used when a plugin is missing");
641 }
642
643 String crashedPluginText()
644 {
645     return WEB_UI_STRING("Plug-in Failure", "Label text to be used if plugin host process has crashed");
646 }
647
648 String blockedPluginByContentSecurityPolicyText()
649 {
650     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");
651 }
652
653 String insecurePluginVersionText()
654 {
655     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");
656 }
657
658 String unsupportedPluginText()
659 {
660     return WEB_UI_STRING_KEY("Unsupported Plug-in", "Unsupported Plug-In", "Label text to be used when an unsupported plug-in was blocked from loading");
661 }
662
663 String multipleFileUploadText(unsigned numberOfFiles)
664 {
665     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);
666 }
667
668 String unknownFileSizeText()
669 {
670     return WEB_UI_STRING_KEY("Unknown", "Unknown (filesize)", "Unknown filesize FTP directory listing item");
671 }
672
673 String imageTitle(const String& filename, const IntSize& size)
674 {
675 #if USE(CF)
676     auto locale = adoptCF(CFLocaleCopyCurrent());
677     auto formatter = adoptCF(CFNumberFormatterCreate(0, locale.get(), kCFNumberFormatterDecimalStyle));
678
679     int widthInt = size.width();
680     auto width = adoptCF(CFNumberCreate(0, kCFNumberIntType, &widthInt));
681     auto widthString = adoptCF(CFNumberFormatterCreateStringWithNumber(0, formatter.get(), width.get()));
682
683     int heightInt = size.height();
684     auto height = adoptCF(CFNumberCreate(0, kCFNumberIntType, &heightInt));
685     auto heightString = adoptCF(CFNumberFormatterCreateStringWithNumber(0, formatter.get(), height.get()));
686
687     return formatLocalizedString(WEB_UI_CFSTRING("%@ %@×%@ pixels", "window title for a standalone image (uses multiplication symbol, not x)"), filename.createCFString().get(), widthString.get(), heightString.get());
688 #elif USE(GLIB)
689     return formatLocalizedString(WEB_UI_STRING("%s %d×%d pixels", "window title for a standalone image (uses multiplication symbol, not x)"), filename.utf8().data(), size.width(), size.height());
690 #else
691     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);
692 #endif
693 }
694
695 String mediaElementLoadingStateText()
696 {
697     return WEB_UI_STRING("Loading…", "Media controller status message when the media is loading");
698 }
699
700 String mediaElementLiveBroadcastStateText()
701 {
702     return WEB_UI_STRING("Live Broadcast", "Media controller status message when watching a live broadcast");
703 }
704
705 String localizedMediaControlElementString(const String& name)
706 {
707     if (name == "AudioElement")
708         return WEB_UI_STRING("audio playback", "accessibility label for audio element controller");
709     if (name == "VideoElement")
710         return WEB_UI_STRING("video playback", "accessibility label for video element controller");
711     if (name == "MuteButton")
712         return WEB_UI_STRING("mute", "accessibility label for mute button");
713     if (name == "UnMuteButton")
714         return WEB_UI_STRING("unmute", "accessibility label for turn mute off button");
715     if (name == "PlayButton")
716         return WEB_UI_STRING("play", "accessibility label for play button");
717     if (name == "PauseButton")
718         return WEB_UI_STRING("pause", "accessibility label for pause button");
719     if (name == "Slider")
720         return WEB_UI_STRING("movie time", "accessibility label for timeline slider");
721     if (name == "SliderThumb")
722         return WEB_UI_STRING("timeline slider thumb", "accessibility label for timeline thumb");
723     if (name == "RewindButton")
724         return WEB_UI_STRING("back 30 seconds", "accessibility label for seek back 30 seconds button");
725     if (name == "ReturnToRealtimeButton")
726         return WEB_UI_STRING("return to realtime", "accessibility label for return to real time button");
727     if (name == "CurrentTimeDisplay")
728         return WEB_UI_STRING("elapsed time", "accessibility label for elapsed time display");
729     if (name == "TimeRemainingDisplay")
730         return WEB_UI_STRING("remaining time", "accessibility label for time remaining display");
731     if (name == "StatusDisplay")
732         return WEB_UI_STRING("status", "accessibility label for movie status");
733     if (name == "EnterFullscreenButton")
734         return WEB_UI_STRING("enter full screen", "accessibility label for enter full screen button");
735     if (name == "ExitFullscreenButton")
736         return WEB_UI_STRING("exit full screen", "accessibility label for exit full screen button");
737     if (name == "SeekForwardButton")
738         return WEB_UI_STRING("fast forward", "accessibility label for fast forward button");
739     if (name == "SeekBackButton")
740         return WEB_UI_STRING("fast reverse", "accessibility label for fast reverse button");
741     if (name == "ShowClosedCaptionsButton")
742         return WEB_UI_STRING("show closed captions", "accessibility label for show closed captions button");
743     if (name == "HideClosedCaptionsButton")
744         return WEB_UI_STRING("hide closed captions", "accessibility label for hide closed captions button");
745
746     // FIXME: the ControlsPanel container should never be visible in the accessibility hierarchy.
747     if (name == "ControlsPanel")
748         return String();
749
750     ASSERT_NOT_REACHED();
751     return String();
752 }
753
754 String localizedMediaControlElementHelpText(const String& name)
755 {
756     if (name == "AudioElement")
757         return WEB_UI_STRING("audio element playback controls and status display", "accessibility help text for audio element controller");
758     if (name == "VideoElement")
759         return WEB_UI_STRING("video element playback controls and status display", "accessibility help text for video element controller");
760     if (name == "MuteButton")
761         return WEB_UI_STRING("mute audio tracks", "accessibility help text for mute button");
762     if (name == "UnMuteButton")
763         return WEB_UI_STRING("unmute audio tracks", "accessibility help text for un mute button");
764     if (name == "PlayButton")
765         return WEB_UI_STRING("begin playback", "accessibility help text for play button");
766     if (name == "PauseButton")
767         return WEB_UI_STRING("pause playback", "accessibility help text for pause button");
768     if (name == "Slider")
769         return WEB_UI_STRING("movie time scrubber", "accessibility help text for timeline slider");
770     if (name == "SliderThumb")
771         return WEB_UI_STRING("movie time scrubber thumb", "accessibility help text for timeline slider thumb");
772     if (name == "RewindButton")
773         return WEB_UI_STRING("seek movie back 30 seconds", "accessibility help text for jump back 30 seconds button");
774     if (name == "ReturnToRealtimeButton")
775         return WEB_UI_STRING("return streaming movie to real time", "accessibility help text for return streaming movie to real time button");
776     if (name == "CurrentTimeDisplay")
777         return WEB_UI_STRING("current movie time in seconds", "accessibility help text for elapsed time display");
778     if (name == "TimeRemainingDisplay")
779         return WEB_UI_STRING("number of seconds of movie remaining", "accessibility help text for remaining time display");
780     if (name == "StatusDisplay")
781         return WEB_UI_STRING("current movie status", "accessibility help text for movie status display");
782     if (name == "SeekBackButton")
783         return WEB_UI_STRING("seek quickly back", "accessibility help text for fast rewind button");
784     if (name == "SeekForwardButton")
785         return WEB_UI_STRING("seek quickly forward", "accessibility help text for fast forward button");
786     if (name == "FullscreenButton")
787         return WEB_UI_STRING("Play movie in fullscreen mode", "accessibility help text for enter fullscreen button");
788     if (name == "ShowClosedCaptionsButton")
789         return WEB_UI_STRING("start displaying closed captions", "accessibility help text for show closed captions button");
790     if (name == "HideClosedCaptionsButton")
791         return WEB_UI_STRING("stop displaying closed captions", "accessibility help text for hide closed captions button");
792
793     // The description of this button is descriptive enough that it doesn't require help text.
794     if (name == "EnterFullscreenButton")
795         return String();
796     
797     ASSERT_NOT_REACHED();
798     return String();
799 }
800
801 String localizedMediaTimeDescription(float time)
802 {
803     if (!std::isfinite(time))
804         return WEB_UI_STRING("indefinite time", "accessibility help text for an indefinite media controller time value");
805
806     int seconds = static_cast<int>(fabsf(time));
807     int days = seconds / (60 * 60 * 24);
808     int hours = seconds / (60 * 60);
809     int minutes = (seconds / 60) % 60;
810     seconds %= 60;
811
812     if (days)
813         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);
814     if (hours)
815         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);
816     if (minutes)
817         return formatLocalizedString(WEB_UI_STRING("%1$d minutes %2$d seconds", "accessibility help text for media controller time value >= 60 seconds"), minutes, seconds);
818     return formatLocalizedString(WEB_UI_STRING("%1$d seconds", "accessibility help text for media controller time value < 60 seconds"), seconds);
819 }
820
821 String validationMessageValueMissingText()
822 {
823     return WEB_UI_STRING("Fill out this field", "Validation message for required form control elements that have no value");
824 }
825
826 String validationMessageValueMissingForCheckboxText()
827 {
828     return WEB_UI_STRING("Select this checkbox", "Validation message for required checkboxes that have not be selected");
829 }
830
831 String validationMessageValueMissingForFileText()
832 {
833     return WEB_UI_STRING("Select a file", "Validation message for required file inputs that have no value");
834 }
835
836 String validationMessageValueMissingForMultipleFileText()
837 {
838     return validationMessageValueMissingForFileText();
839 }
840
841 String validationMessageValueMissingForRadioText()
842 {
843     return WEB_UI_STRING("Select one of these options", "Validation message for required radio boxes that have no selection");
844 }
845
846 String validationMessageValueMissingForSelectText()
847 {
848     return WEB_UI_STRING("Select an item in the list", "Validation message for required menu list controls that have no selection");
849 }
850
851 String validationMessageTypeMismatchText()
852 {
853     return WEB_UI_STRING("Invalid value", "Validation message for input form controls with a value not matching type");
854 }
855
856 String validationMessageTypeMismatchForEmailText()
857 {
858     return WEB_UI_STRING("Enter an email address", "Validation message for input form controls of type 'email' that have an invalid value");
859 }
860
861 String validationMessageTypeMismatchForMultipleEmailText()
862 {
863     return validationMessageTypeMismatchForEmailText();
864 }
865
866 String validationMessageTypeMismatchForURLText()
867 {
868     return WEB_UI_STRING("Enter a URL", "Validation message for input form controls of type 'url' that have an invalid value");
869 }
870
871 String validationMessagePatternMismatchText()
872 {
873     return WEB_UI_STRING("Match the requested format", "Validation message for input form controls requiring a constrained value according to pattern");
874 }
875
876 #if !PLATFORM(GTK)
877 String validationMessageTooShortText(int, int minLength)
878 {
879     return formatLocalizedString(WEB_UI_STRING("Use at least %d characters", "Validation message for form control elements with a value shorter than minimum allowed length"), minLength);
880 }
881
882 #if !PLATFORM(COCOA)
883 String validationMessageTooLongText(int, int maxLength)
884 {
885     return formatLocalizedString(WEB_UI_STRING("Use no more than %d characters", "Validation message for form control elements with a value shorter than maximum allowed length"), maxLength);
886 }
887 #endif
888 #endif
889
890 String validationMessageRangeUnderflowText(const String& minimum)
891 {
892 #if USE(CF)
893     return formatLocalizedString(WEB_UI_CFSTRING("Value must be greater than or equal to %@", "Validation message for input form controls with value lower than allowed minimum"), minimum.createCFString().get());
894 #elif USE(GLIB)
895     return formatLocalizedString(WEB_UI_STRING("Value must be greater than or equal to %s", "Validation message for input form controls with value lower than allowed minimum"), minimum.utf8().data());
896 #else
897     UNUSED_PARAM(minimum);
898     return WEB_UI_STRING("range underflow", "Validation message for input form controls with value lower than allowed minimum");
899 #endif
900 }
901
902 String validationMessageRangeOverflowText(const String& maximum)
903 {
904 #if USE(CF)
905     return formatLocalizedString(WEB_UI_CFSTRING("Value must be less than or equal to %@", "Validation message for input form controls with value higher than allowed maximum"), maximum.createCFString().get());
906 #elif USE(GLIB)
907     return formatLocalizedString(WEB_UI_STRING("Value must be less than or equal to %s", "Validation message for input form controls with value higher than allowed maximum"), maximum.utf8().data());
908 #else
909     UNUSED_PARAM(maximum);
910     return WEB_UI_STRING("range overflow", "Validation message for input form controls with value higher than allowed maximum");
911 #endif
912 }
913
914 String validationMessageStepMismatchText(const String&, const String&)
915 {
916     return WEB_UI_STRING("Enter a valid value", "Validation message for input form controls with value not respecting the step attribute");
917 }
918
919 String validationMessageBadInputForNumberText()
920 {
921     return WEB_UI_STRING("Enter a number", "Validation message for number fields where the user entered a non-number string");
922 }
923
924 String clickToExitFullScreenText()
925 {
926     return WEB_UI_STRING("Click to Exit Full Screen", "Message to display in browser window when in webkit full screen mode.");
927 }
928
929 #if ENABLE(VIDEO_TRACK)
930
931 String textTrackSubtitlesText()
932 {
933     return WEB_UI_STRING("Subtitles", "Menu section heading for subtitles");
934 }
935
936 String textTrackOffMenuItemText()
937 {
938     return WEB_UI_STRING("Off", "Menu item label for the track that represents disabling closed captions");
939 }
940
941 String textTrackAutomaticMenuItemText()
942 {
943     return formatLocalizedString(WEB_UI_STRING("Auto (Recommended)", "Menu item label for automatic track selection behavior"));
944 }
945
946 String textTrackNoLabelText()
947 {
948     return WEB_UI_STRING_KEY("Unknown", "Unknown (text track)", "Menu item label for a text track that has no other name");
949 }
950
951 String audioTrackNoLabelText()
952 {
953     return WEB_UI_STRING_KEY("Unknown", "Unknown (audio track)", "Menu item label for an audio track that has no other name");
954 }
955
956 #endif
957
958 #if ENABLE(VIDEO_TRACK) && USE(CF)
959
960 String textTrackCountryAndLanguageMenuItemText(const String& title, const String& country, const String& language)
961 {
962     return formatLocalizedString(WEB_UI_CFSTRING("%@ (%@-%@)", "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());
963 }
964
965 String textTrackLanguageMenuItemText(const String& title, const String& language)
966 {
967     return formatLocalizedString(WEB_UI_CFSTRING("%@ (%@)", "Text track display name format that includes the language of the subtitle, in the form of 'Title (Language)'"), title.createCFString().get(), language.createCFString().get());
968 }
969
970 String closedCaptionTrackMenuItemText(const String& title)
971 {
972     return formatLocalizedString(WEB_UI_CFSTRING("%@ CC", "Text track contains closed captions"), title.createCFString().get());
973 }
974
975 String sdhTrackMenuItemText(const String& title)
976 {
977     return formatLocalizedString(WEB_UI_CFSTRING("%@ SDH", "Text track contains subtitles for the deaf and hard of hearing"), title.createCFString().get());
978 }
979
980 String easyReaderTrackMenuItemText(const String& title)
981 {
982     return formatLocalizedString(WEB_UI_CFSTRING("%@ Easy Reader", "Text track contains simplified (3rd grade level) subtitles"), title.createCFString().get());
983 }
984
985 String forcedTrackMenuItemText(const String& title)
986 {
987     return formatLocalizedString(WEB_UI_CFSTRING("%@ Forced", "Text track contains forced subtitles"), title.createCFString().get());
988 }
989
990 String audioDescriptionTrackSuffixText(const String& title)
991 {
992     return formatLocalizedString(WEB_UI_CFSTRING("%@ AD", "Text track contains Audio Descriptions"), title.createCFString().get());
993 }
994
995 #endif
996
997 String snapshottedPlugInLabelTitle()
998 {
999     return WEB_UI_STRING("Snapshotted Plug-In", "Title of the label to show on a snapshotted plug-in");
1000 }
1001
1002 String snapshottedPlugInLabelSubtitle()
1003 {
1004     return WEB_UI_STRING("Click to restart", "Subtitle of the label to show on a snapshotted plug-in");
1005 }
1006
1007 String useBlockedPlugInContextMenuTitle()
1008 {
1009     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"));
1010 }
1011
1012 #if ENABLE(SUBTLE_CRYPTO)
1013
1014 String webCryptoMasterKeyKeychainLabel(const String& localizedApplicationName)
1015 {
1016 #if USE(CF)
1017     return formatLocalizedString(WEB_UI_CFSTRING("%@ WebCrypto Master Key", "Name of application's single WebCrypto master key in Keychain"), localizedApplicationName.createCFString().get());
1018 #elif USE(GLIB)
1019     return formatLocalizedString(WEB_UI_STRING("%s WebCrypto Master Key", "Name of application's single WebCrypto master key in Keychain"), localizedApplicationName.utf8().data());
1020 #else
1021     return String::fromUTF8("<application> WebCrypto Master Key", "Name of application's single WebCrypto master key in Keychain").replace("<application>", localizedApplicationName);
1022 #endif
1023 }
1024
1025 String webCryptoMasterKeyKeychainComment()
1026 {
1027     return WEB_UI_STRING("Used to encrypt WebCrypto keys in persistent storage, such as IndexedDB", "Description of WebCrypto master keys in Keychain");
1028 }
1029
1030 #endif
1031
1032 #if PLATFORM(WATCHOS)
1033
1034 String numberPadOKButtonTitle()
1035 {
1036     return WEB_UI_STRING_KEY("OK", "OK (OK button title in extra zoomed number pad)", "Title of the OK button for the number pad in zoomed form controls.");
1037 }
1038
1039 String formControlDoneButtonTitle()
1040 {
1041     return WEB_UI_STRING("Done", "Title of the Done button for zoomed form controls.");
1042 }
1043
1044 String formControlCancelButtonTitle()
1045 {
1046     return WEB_UI_STRING("Cancel", "Title of the Cancel button for zoomed form controls.");
1047 }
1048
1049 String formControlHideButtonTitle()
1050 {
1051     return WEB_UI_STRING("Hide", "Title of the Hide button for zoomed form controls.");
1052 }
1053
1054 String formControlGoButtonTitle()
1055 {
1056     return WEB_UI_STRING("Go", "Title of the Go button for zoomed form controls.");
1057 }
1058
1059 String formControlSearchButtonTitle()
1060 {
1061     return WEB_UI_STRING("Search", "Title of the Search button for zoomed form controls.");
1062 }
1063
1064 String datePickerSetButtonTitle()
1065 {
1066     return WEB_UI_STRING_KEY("Set", "Set (Button below date picker for extra zoom mode)", "Set button below date picker");
1067 }
1068
1069 String datePickerDayLabelTitle()
1070 {
1071     return WEB_UI_STRING_KEY("DAY", "DAY (Date picker for extra zoom mode)", "Day label in date picker");
1072 }
1073
1074 String datePickerMonthLabelTitle()
1075 {
1076     return WEB_UI_STRING_KEY("MONTH", "MONTH (Date picker for extra zoom mode)", "Month label in date picker");
1077 }
1078
1079 String datePickerYearLabelTitle()
1080 {
1081     return WEB_UI_STRING_KEY("YEAR", "YEAR (Date picker for extra zoom mode)", "Year label in date picker");
1082 }
1083
1084 #endif
1085
1086 } // namespace WebCore