diff --git a/.eslintrc.js b/.eslintrc.js index 92c3edf944..0a82ead2e1 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -34,6 +34,7 @@ module.exports = { "react/jsx-curly-spacing": [2, "never"], "react/jsx-equals-spacing": [2, "never"], "react/jsx-key": 2, + "react/jsx-no-bind": 2, "react/jsx-no-comment-textnodes": 2, "react/jsx-no-duplicate-props": 2, "react/jsx-no-target-blank": 2, diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a939f4790..8783307ade 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,15 +1,23 @@ - -## 1.12.1 (2017-06-05) + +## 1.14.2 (2017-07-19) -* 1.12.0 changelog ([97aaf71](https://github.com/mozilla/activity-stream/commit/97aaf71)) -* 1.12.1 ([32c6caf](https://github.com/mozilla/activity-stream/commit/32c6caf)) -* Enable travisci for 1.12.1 ([0126ba0](https://github.com/mozilla/activity-stream/commit/0126ba0)) -* fix (addon): #2670 fix LinkChecker to match m-c ([83a2fa0](https://github.com/mozilla/activity-stream/commit/83a2fa0)), closes [#2670](https://github.com/mozilla/activity-stream/issues/2670) +* 1.14.1 changelog ([642b84b](https://github.com/mozilla/activity-stream/commit/642b84b)) +* 1.14.2 ([a4df548](https://github.com/mozilla/activity-stream/commit/a4df548)) +* Query experiment definitions from experimenter fixes #2100 ([9fe0978](https://github.com/mozilla/activity-stream/commit/9fe0978)), closes [#2100](https://github.com/mozilla/activity-stream/issues/2100) - -# 1.12.0 (2017-05-30) + +## 1.14.1 (2017-07-04) + +* 1.14.0 changelog ([466fba6](https://github.com/mozilla/activity-stream/commit/466fba6)) +* 1.14.1 ([b212502](https://github.com/mozilla/activity-stream/commit/b212502)) +* fix(db): 2817 - Add shutdown blocker for metadata store ([78d6ddf](https://github.com/mozilla/activity-stream/commit/78d6ddf)) + + + + +# 1.14.0 (2017-06-28) * import(mc): Import style nits from patch landed in mc ([5bcae82](https://github.com/mozilla/activity-stream/commit/5bcae82)) * Add hasHighResIcon to link object fixes #2392 ([c82fbab](https://github.com/mozilla/activity-stream/commit/c82fbab)), closes [#2392](https://github.com/mozilla/activity-stream/issues/2392) @@ -33,7 +41,13 @@ * 1.10.1 ([bc3d00e](https://github.com/mozilla/activity-stream/commit/bc3d00e)) * 1.11.0 ([cdab802](https://github.com/mozilla/activity-stream/commit/cdab802)) * 1.11.0 changelog ([f5e53aa](https://github.com/mozilla/activity-stream/commit/f5e53aa)) -* 1.12.0 ([756b10c](https://github.com/mozilla/activity-stream/commit/756b10c)) +* 1.12.0 ([25e9719](https://github.com/mozilla/activity-stream/commit/25e9719)) +* 1.12.0 changelog ([943f19e](https://github.com/mozilla/activity-stream/commit/943f19e)) +* 1.12.1 ([b6ca7c5](https://github.com/mozilla/activity-stream/commit/b6ca7c5)) +* 1.12.1 changelog ([be56c40](https://github.com/mozilla/activity-stream/commit/be56c40)) +* 1.13.0 ([5994a45](https://github.com/mozilla/activity-stream/commit/5994a45)) +* 1.13.0 changelog ([7b5d59e](https://github.com/mozilla/activity-stream/commit/7b5d59e)) +* 1.14.0 ([779f3f3](https://github.com/mozilla/activity-stream/commit/779f3f3)) * 1.2.0 ([31471c9](https://github.com/mozilla/activity-stream/commit/31471c9)) * 1.2.0 changelog ([08afc9e](https://github.com/mozilla/activity-stream/commit/08afc9e)) * 1.3.0 ([fc89c69](https://github.com/mozilla/activity-stream/commit/fc89c69)) @@ -54,6 +68,7 @@ * Add commit hash to the addon version for dev/pre-release channels ([b736cfc](https://github.com/mozilla/activity-stream/commit/b736cfc)) * Add new pocket hot fix experiment fixes #2534 ([1cc6a9d](https://github.com/mozilla/activity-stream/commit/1cc6a9d)), closes [#2534](https://github.com/mozilla/activity-stream/issues/2534) * Add PureRenderMixin for stateless components ([33d7881](https://github.com/mozilla/activity-stream/commit/33d7881)) +* Add recent bookmarks section. Closes #2621 ([82f707c](https://github.com/mozilla/activity-stream/commit/82f707c)), closes [#2621](https://github.com/mozilla/activity-stream/issues/2621) * Add users/bots to .mention-bot blacklist ([24b489c](https://github.com/mozilla/activity-stream/commit/24b489c)) * Address review comments ([5819e9e](https://github.com/mozilla/activity-stream/commit/5819e9e)) * catch errors in pageWorker.destroy ([65dd332](https://github.com/mozilla/activity-stream/commit/65dd332)) @@ -79,17 +94,23 @@ * Dedupe weighted highlights results ([740db7a](https://github.com/mozilla/activity-stream/commit/740db7a)) * Deprecate simple-storage fixes #2179 ([829c709](https://github.com/mozilla/activity-stream/commit/829c709)), closes [#2179](https://github.com/mozilla/activity-stream/issues/2179) * enable screenshots experiment for 20% ([9b86740](https://github.com/mozilla/activity-stream/commit/9b86740)) +* enable TravisCI for 1.14.0 ([ae10ad1](https://github.com/mozilla/activity-stream/commit/ae10ad1)) +* feat (addon): #2666 graduate metadataNoService experiment ([0bbb243](https://github.com/mozilla/activity-stream/commit/0bbb243)) * feat (content): #1988 new style for top sites (behind screenshots experiment) ([3e22f74](https://github.com/mozilla/activity-stream/commit/3e22f74)) * feat (content): #2227 add "Show two rows" checkbox to prefs sidebar ([db9dd3f](https://github.com/mozilla/activity-stream/commit/db9dd3f)) * feat (content): #2385 collapse highlights on section title click ([5c5536e](https://github.com/mozilla/activity-stream/commit/5c5536e)) * feat (content): #2410 "graduate" preferences sidebar ([5b275b1](https://github.com/mozilla/activity-stream/commit/5b275b1)) * feat (content): #2421 pinned site updates ([e493b40](https://github.com/mozilla/activity-stream/commit/e493b40)) +* feat (content): #2617 collapsible sections ([0671d80](https://github.com/mozilla/activity-stream/commit/0671d80)) * feat (customization): #2273 implement dismiss UI in Edit Top Sites ([0ead72f](https://github.com/mozilla/activity-stream/commit/0ead72f)) +* feat (customization): #2275 top sites drag and drop ([785068d](https://github.com/mozilla/activity-stream/commit/785068d)) * feat (experiment): #2065 screenshots in highlights experiment ([695a462](https://github.com/mozilla/activity-stream/commit/695a462)) * feat (experiment): #2300 add experiment for two rows of top sites by default ([dfe9139](https://github.com/mozilla/activity-stream/commit/dfe9139)) +* feat (experiment): #2647 graduate pocket experiment ([f93599a](https://github.com/mozilla/activity-stream/commit/f93599a)) * feat (metrics): #1595 implement undesired event pings for loader and missing image ([8f97a5f](https://github.com/mozilla/activity-stream/commit/8f97a5f)) * feat (metrics): #1782 ping event when slow addon detected ([2988d54](https://github.com/mozilla/activity-stream/commit/2988d54)) * feat (metrics): #2063 Track `screenshot` image type in event telemetry ([c1e2265](https://github.com/mozilla/activity-stream/commit/c1e2265)) +* feat (metrics): add telemetry for drag and drop ([14fef9c](https://github.com/mozilla/activity-stream/commit/14fef9c)) * feat (metrics): add user events for Add/Edit top site features ([c0136e9](https://github.com/mozilla/activity-stream/commit/c0136e9)) * feat (styles): add animation for sidebar and change button to X while open ([4d40954](https://github.com/mozilla/activity-stream/commit/4d40954)) * feat (top sites): #2218 implement pref to show more/less top sites ([b3c5dc3](https://github.com/mozilla/activity-stream/commit/b3c5dc3)) @@ -106,6 +127,7 @@ * feat(mc) #2518 Add PlacesFeed with observers ([6db968b](https://github.com/mozilla/activity-stream/commit/6db968b)) * feat(metadata) Closes #1410 Create a metadata parser ([121aa50](https://github.com/mozilla/activity-stream/commit/121aa50)), closes [#1410](https://github.com/mozilla/activity-stream/issues/1410) * feature (addon): #414 context menu share ([e85463c](https://github.com/mozilla/activity-stream/commit/e85463c)) +* Filter out bookmark labels, reverts the changes from #2687 ([4e8ffa7](https://github.com/mozilla/activity-stream/commit/4e8ffa7)) * fix (addon): #1228 simplify url hiding ([d6c0aed](https://github.com/mozilla/activity-stream/commit/d6c0aed)), closes [#1228](https://github.com/mozilla/activity-stream/issues/1228) * fix (addon): #1314 remove ShareProvider race condition workaround ([b4db98e](https://github.com/mozilla/activity-stream/commit/b4db98e)), closes [#1314](https://github.com/mozilla/activity-stream/issues/1314) * fix (addon): #1373 fix sharing from new private windows ([8d20a1d](https://github.com/mozilla/activity-stream/commit/8d20a1d)), closes [#1373](https://github.com/mozilla/activity-stream/issues/1373) @@ -118,6 +140,7 @@ * fix (addon): #2102 handle exceptions/rejects from _computeImageSize() ([25cc080](https://github.com/mozilla/activity-stream/commit/25cc080)), closes [#2102](https://github.com/mozilla/activity-stream/issues/2102) * fix (addon): #2461 fix typo in _handleExperimentChange ([ba15733](https://github.com/mozilla/activity-stream/commit/ba15733)), closes [#2461](https://github.com/mozilla/activity-stream/issues/2461) * fix (addon): #2522 fix dead object exception related to pinning ([e3b508f](https://github.com/mozilla/activity-stream/commit/e3b508f)), closes [#2522](https://github.com/mozilla/activity-stream/issues/2522) +* fix (addon): #2670 fix LinkChecker to match m-c ([7f3a8f3](https://github.com/mozilla/activity-stream/commit/7f3a8f3)), closes [#2670](https://github.com/mozilla/activity-stream/issues/2670) * fix (addon): fixes for getScreenshots ([af69251](https://github.com/mozilla/activity-stream/commit/af69251)) * fix (addon): Remove timline paths from app urls ([a5f9a80](https://github.com/mozilla/activity-stream/commit/a5f9a80)) * fix (content): #1298 stop propagation on "Share" click event ([8cad296](https://github.com/mozilla/activity-stream/commit/8cad296)), closes [#1298](https://github.com/mozilla/activity-stream/issues/1298) @@ -133,13 +156,19 @@ * fix (content): #2227 convert prefs modal to a sidebar ([09995fe](https://github.com/mozilla/activity-stream/commit/09995fe)), closes [#2227](https://github.com/mozilla/activity-stream/issues/2227) * fix (content): #2415 unpin site when dismissing (if pinned) ([28d5eee](https://github.com/mozilla/activity-stream/commit/28d5eee)), closes [#2415](https://github.com/mozilla/activity-stream/issues/2415) * fix (content): add system fonts for Windows and Ubuntu ([5322bd2](https://github.com/mozilla/activity-stream/commit/5322bd2)) +* fix (content): create dedicated "drop zone" div ([1fad5f0](https://github.com/mozilla/activity-stream/commit/1fad5f0)) * fix (content): fix user event dispatching in TopSites ([290edf7](https://github.com/mozilla/activity-stream/commit/290edf7)) * fix (content): Implement new gutter size ([d0cfe7c](https://github.com/mozilla/activity-stream/commit/d0cfe7c)) * fix (debug): #1875 Fix debug page ([1f616c5](https://github.com/mozilla/activity-stream/commit/1f616c5)), closes [#1875](https://github.com/mozilla/activity-stream/issues/1875) +* fix (drag n drop): #2633 close context menu on drag start ([7bf38da](https://github.com/mozilla/activity-stream/commit/7bf38da)), closes [#2633](https://github.com/mozilla/activity-stream/issues/2633) +* fix (drag n drop): #2634 only allow dropping of other topsites (for now) ([fc64d54](https://github.com/mozilla/activity-stream/commit/fc64d54)), closes [#2634](https://github.com/mozilla/activity-stream/issues/2634) +* fix (drag n drop): make drop zone a link to topsite url ([378f849](https://github.com/mozilla/activity-stream/commit/378f849)) +* fix (drag n drop): prevent click when dropping topsite onto itself ([8be5b97](https://github.com/mozilla/activity-stream/commit/8be5b97)) * fix (experiment): #2164 retire originalNewTabSites experiment ([37881de](https://github.com/mozilla/activity-stream/commit/37881de)), closes [#2164](https://github.com/mozilla/activity-stream/issues/2164) * fix (experiment): #2165 use default top sites feed for screenshots experiment ([53cd78f](https://github.com/mozilla/activity-stream/commit/53cd78f)), closes [#2165](https://github.com/mozilla/activity-stream/issues/2165) * fix (experiments) #2282 hide Edit Top Sites behind newTabPrefs experiment ([2d8bc9f](https://github.com/mozilla/activity-stream/commit/2d8bc9f)), closes [#2282](https://github.com/mozilla/activity-stream/issues/2282) * fix (experiments): #2246 hide New Tab Prefs behind an experiment ([2bcf635](https://github.com/mozilla/activity-stream/commit/2bcf635)), closes [#2246](https://github.com/mozilla/activity-stream/issues/2246) +* fix (experiments): #2667 remove/disable metadataLocalRefresh experiment ([1d4ddd0](https://github.com/mozilla/activity-stream/commit/1d4ddd0)), closes [#2667](https://github.com/mozilla/activity-stream/issues/2667) * fix (experiments): boolify editTopSites experiment value ([b5f6e3e](https://github.com/mozilla/activity-stream/commit/b5f6e3e)) * fix (feeds): #2469 ignore actions before APP_INIT in Highlights Feed ([a495ca1](https://github.com/mozilla/activity-stream/commit/a495ca1)), closes [#2469](https://github.com/mozilla/activity-stream/issues/2469) * fix (feeds): skip empty slots in MetadataFeed ([46106ce](https://github.com/mozilla/activity-stream/commit/46106ce)) @@ -149,10 +178,13 @@ * fix (metrics) #1268 Switch timing uses of Date.now to absPerf.now ([5f8f1e7](https://github.com/mozilla/activity-stream/commit/5f8f1e7)), closes [#1268](https://github.com/mozilla/activity-stream/issues/1268) * fix (pinning): do not pass empty slots to getCachedMetadata ([3d5ab47](https://github.com/mozilla/activity-stream/commit/3d5ab47)) * fix (screenshots): s/screenshots/screenshotsAsync/ miss ([40ba21e](https://github.com/mozilla/activity-stream/commit/40ba21e)) +* fix (sidebar): #2618 fix Done button on bottom and make contents scrollable ([615cb28](https://github.com/mozilla/activity-stream/commit/615cb28)), closes [#2618](https://github.com/mozilla/activity-stream/issues/2618) * fix (style) #2168 leave border on when icon is above screenshot ([94ed478](https://github.com/mozilla/activity-stream/commit/94ed478)), closes [#2168](https://github.com/mozilla/activity-stream/issues/2168) * fix (style): #2095 css fixes for narrow windows ([effba6e](https://github.com/mozilla/activity-stream/commit/effba6e)), closes [#2095](https://github.com/mozilla/activity-stream/issues/2095) * fix (style): #2168 no icon borders for screenshots experiment ([10c7130](https://github.com/mozilla/activity-stream/commit/10c7130)), closes [#2168](https://github.com/mozilla/activity-stream/issues/2168) * fix (style): #2217 round corners for full size icons ([45d5d55](https://github.com/mozilla/activity-stream/commit/45d5d55)), closes [#2217](https://github.com/mozilla/activity-stream/issues/2217) +* fix (style): #2690 only show sidebar scrollbar when needed ([41f5d69](https://github.com/mozilla/activity-stream/commit/41f5d69)), closes [#2690](https://github.com/mozilla/activity-stream/issues/2690) +* fix (style): #2708 fix top site icon truncation during collapse animation ([e7fe4c4](https://github.com/mozilla/activity-stream/commit/e7fe4c4)), closes [#2708](https://github.com/mozilla/activity-stream/issues/2708) * fix (style): tweak for top sites hover state ([4b32fce](https://github.com/mozilla/activity-stream/commit/4b32fce)) * fix (styles): #2091 fix placeholder CSS when screenshot experiment enabled ([3873792](https://github.com/mozilla/activity-stream/commit/3873792)), closes [#2091](https://github.com/mozilla/activity-stream/issues/2091) * fix (styles): #2125 fix site icon fallback style in screenshots experiment ([c2f7a76](https://github.com/mozilla/activity-stream/commit/c2f7a76)), closes [#2125](https://github.com/mozilla/activity-stream/issues/2125) @@ -161,10 +193,14 @@ * fix (styles): #2443 fix z-index of top sites edit menu ([9197012](https://github.com/mozilla/activity-stream/commit/9197012)), closes [#2443](https://github.com/mozilla/activity-stream/issues/2443) * fix (styles): #2444 fix z-index of pref sidebar ([ec214fb](https://github.com/mozilla/activity-stream/commit/ec214fb)), closes [#2444](https://github.com/mozilla/activity-stream/issues/2444) * fix (styles): #2497 remove box-shadow transitions in search box ([0eaae45](https://github.com/mozilla/activity-stream/commit/0eaae45)), closes [#2497](https://github.com/mozilla/activity-stream/issues/2497) +* fix (styles): better cursor styles for d-n-d in edit mode ([16ad9f9](https://github.com/mozilla/activity-stream/commit/16ad9f9)) * fix (styles): change background color to a light gray ([85b6887](https://github.com/mozilla/activity-stream/commit/85b6887)) * fix (styles): change sidebar and gear icon to fixed position ([ec9b891](https://github.com/mozilla/activity-stream/commit/ec9b891)) * fix (styles): fix settings button z-index ([5bb4a3b](https://github.com/mozilla/activity-stream/commit/5bb4a3b)) * fix (styles): style updates from @bryanbell ([5b37be0](https://github.com/mozilla/activity-stream/commit/5b37be0)) +* fix (tests): mock out pocket fetch functions ([f93faf9](https://github.com/mozilla/activity-stream/commit/f93faf9)) +* fix (travis): comment out failing test ([4652e63](https://github.com/mozilla/activity-stream/commit/4652e63)) +* fix (travis): fix tests. return promise from mock asyncFetchLinks() ([84fbf74](https://github.com/mozilla/activity-stream/commit/84fbf74)) * fix top site query so bookmark info works in context menu ([4dd3652](https://github.com/mozilla/activity-stream/commit/4dd3652)) * Fix travisci.yaml ([a747abc](https://github.com/mozilla/activity-stream/commit/a747abc)) * fix(content) #1816 Use label instead of provider_name for spotlight ([c751114](https://github.com/mozilla/activity-stream/commit/c751114)) @@ -180,6 +216,7 @@ * Graduate DedupedCombinedFrency experiment #2160 ([ace5e8e](https://github.com/mozilla/activity-stream/commit/ace5e8e)) * Graduate metadata long cache fixes #2352 ([c0cf817](https://github.com/mozilla/activity-stream/commit/c0cf817)), closes [#2352](https://github.com/mozilla/activity-stream/issues/2352) * Grammar fix in comment ([514b6f4](https://github.com/mozilla/activity-stream/commit/514b6f4)) +* Group duplicate recent bookmarks as 1 item. Fixes #2686. ([52f1e8f](https://github.com/mozilla/activity-stream/commit/52f1e8f)), closes [#2686](https://github.com/mozilla/activity-stream/issues/2686) * Improve localization comments in strings.properties ([5f38724](https://github.com/mozilla/activity-stream/commit/5f38724)) * Increase cohort size for screenshot experiment ([5e668b6](https://github.com/mozilla/activity-stream/commit/5e668b6)) * Increase localFetch experiment population to 20% fixes #2144 ([f0cbf7b](https://github.com/mozilla/activity-stream/commit/f0cbf7b)), closes [#2144](https://github.com/mozilla/activity-stream/issues/2144) @@ -194,7 +231,7 @@ * remove (content): remove Header component ([8ca0007](https://github.com/mozilla/activity-stream/commit/8ca0007)) * remove no longer used recommended logic ([ee8feaf](https://github.com/mozilla/activity-stream/commit/ee8feaf)) * remove(content+addon): Remove RequestRecentLinks/RequestTopFrecent action and handling (#1585) ([8adedd1](https://github.com/mozilla/activity-stream/commit/8adedd1)) -* Replace performance ping values with a valid 32 bit integer fixes #2601 ([eedc908](https://github.com/mozilla/activity-stream/commit/eedc908)), closes [#2601](https://github.com/mozilla/activity-stream/issues/2601) +* Replace performance ping values with a valid 32 bit integer fixes #2601 ([1214714](https://github.com/mozilla/activity-stream/commit/1214714)), closes [#2601](https://github.com/mozilla/activity-stream/issues/2601) * Revert "chore(package): update various dependencies to latest version" (#1696) ([a62da54](https://github.com/mozilla/activity-stream/commit/a62da54)) * Revert "chore(package): update various dependencies to latest version" (#1698) ([c697893](https://github.com/mozilla/activity-stream/commit/c697893)) * Revert "feat(highlights) - New design for bottom highlights", r=@sarracini ([2cb7942](https://github.com/mozilla/activity-stream/commit/2cb7942)) @@ -202,6 +239,7 @@ * review feedback tweaks ([341f2c4](https://github.com/mozilla/activity-stream/commit/341f2c4)) * Review feedback tweaks v2 ([170b2a7](https://github.com/mozilla/activity-stream/commit/170b2a7)) * Review fixup ([404611e](https://github.com/mozilla/activity-stream/commit/404611e)) +* Should show pointer cursor while hover to the search button, fix #2614 ([a7b4927](https://github.com/mozilla/activity-stream/commit/a7b4927)), closes [#2614](https://github.com/mozilla/activity-stream/issues/2614) * String change to be consistent with desktop ([c5d5d49](https://github.com/mozilla/activity-stream/commit/c5d5d49)) * Update feeds on metadata change fixes #1969 ([7c93ca3](https://github.com/mozilla/activity-stream/commit/7c93ca3)), closes [#1969](https://github.com/mozilla/activity-stream/issues/1969) * Update to Metadata Parser 0.6.0 fixes #2082 ([f4eba25](https://github.com/mozilla/activity-stream/commit/f4eba25)), closes [#2082](https://github.com/mozilla/activity-stream/issues/2082) @@ -209,109 +247,7 @@ * v1.1.4 changelog ([0a91220](https://github.com/mozilla/activity-stream/commit/0a91220)) * v1.10.0 changelog ([533da28](https://github.com/mozilla/activity-stream/commit/533da28)) * v1.10.1 changelog ([571c80e](https://github.com/mozilla/activity-stream/commit/571c80e)) -* feat(a11y): Closes #1993 Bring '...' button to foreground ([473ead6](https://github.com/mozilla/activity-stream/commit/473ead6)), closes [#1993](https://github.com/mozilla/activity-stream/issues/1993) -* feat(addon): #1452 Add 'Feeds' to allow for custom update cycles ([94d350b](https://github.com/mozilla/activity-stream/commit/94d350b)) -* feat(addon): #1512 Add lodash.debounce and timers to vendor-src ([2d747e7](https://github.com/mozilla/activity-stream/commit/2d747e7)) -* feat(addon): #2045 Add support for screenshots ([385da1a](https://github.com/mozilla/activity-stream/commit/385da1a)) -* feat(addon): #2045 Add UI to support screenshots ([4ce4982](https://github.com/mozilla/activity-stream/commit/4ce4982)) -* feat(addon): add benchmarking support ([e0573d8](https://github.com/mozilla/activity-stream/commit/e0573d8)) -* feat(benchmark): #1236 add baseline benchmarks ([4981e9b](https://github.com/mozilla/activity-stream/commit/4981e9b)) -* feat(content): #1537 Onboarding tooltip for top sites/highlights ([ad665a9](https://github.com/mozilla/activity-stream/commit/ad665a9)) -* feat(content): #1906 Add Snippet component ([494777d](https://github.com/mozilla/activity-stream/commit/494777d)) -* feat(content): #2466 Enable pocket pref for all users ([378b9ab](https://github.com/mozilla/activity-stream/commit/378b9ab)) -* feat(content): #2486 Track impressions for Pocket ([7f06e15](https://github.com/mozilla/activity-stream/commit/7f06e15)) -* feat(content): #2496 UX improvements for Pocket ([19fa70d](https://github.com/mozilla/activity-stream/commit/19fa70d)) -* feat(content): #2536 Logo should link to Pocket, +Feedback form ([0b97cb6](https://github.com/mozilla/activity-stream/commit/0b97cb6)) -* feat(content): #2600 Add telemetry on the 'Read More' links for Pocket ([2a8eec6](https://github.com/mozilla/activity-stream/commit/2a8eec6)) -* feat(content): Add "Save to Pocket" functionality to Spotlight/LinkMenu ([5364ad7](https://github.com/mozilla/activity-stream/commit/5364ad7)) -* feat(content): Add 2x logo for Pocket (#2494) ([4f7bfb0](https://github.com/mozilla/activity-stream/commit/4f7bfb0)) -* feat(content): Add basic token matching for Timeline all/bookmark views with search in header. ([e9eaa2b](https://github.com/mozilla/activity-stream/commit/e9eaa2b)) -* feat(content): Add dismiss button for timeline filtering ([f8bda05](https://github.com/mozilla/activity-stream/commit/f8bda05)) -* feat(content): Add pocket trending stories for test-pilot add-on ([2c7aff0](https://github.com/mozilla/activity-stream/commit/2c7aff0)) -* feat(content): Configure pocket experiment threshold ([4e8c7a3](https://github.com/mozilla/activity-stream/commit/4e8c7a3)) -* feat(content): Implement new tab preferences pane (#2196) ([833ef2b](https://github.com/mozilla/activity-stream/commit/833ef2b)) -* feat(content): Refresh pocket feed on pref change ([48de7ee](https://github.com/mozilla/activity-stream/commit/48de7ee)) -* feat(experiments): #964 Add experiment overriding via prefs ([da1fddf](https://github.com/mozilla/activity-stream/commit/da1fddf)) -* feat(experiments): Add display for experiments to debug (#1728) ([a4fb50a](https://github.com/mozilla/activity-stream/commit/a4fb50a)) -* feat(experiments): Closes #1084 Run MetadataService vs Embedly ([d6cb5fe](https://github.com/mozilla/activity-stream/commit/d6cb5fe)), closes [#1084](https://github.com/mozilla/activity-stream/issues/1084) -* feat(experiments): Closes #1431 Set up local metadata parser as experiment ([bc368b3](https://github.com/mozilla/activity-stream/commit/bc368b3)), closes [#1431](https://github.com/mozilla/activity-stream/issues/1431) -* feat(experiments): Closes #1952 Use orig tiles algorithm for top sites ([798b517](https://github.com/mozilla/activity-stream/commit/798b517)), closes [#1952](https://github.com/mozilla/activity-stream/issues/1952) -* feat(feeds): #1452 Remove History, Old Highlights Feeds ([50c058d](https://github.com/mozilla/activity-stream/commit/50c058d)) -* feat(feeds): #1681 Add PlacesStatsFeed for history, bookmarks size ([a78c055](https://github.com/mozilla/activity-stream/commit/a78c055)) -* feat(feeds): #1750 PageModProvider, add broadcasting/send to feeds ([7575cd7](https://github.com/mozilla/activity-stream/commit/7575cd7)) -* feat(feeds): #1775 Add Search feed ([cb4cf14](https://github.com/mozilla/activity-stream/commit/cb4cf14)) -* feat(highlights): Always show recent bookmarks even without images (#1844) ([b0d232f](https://github.com/mozilla/activity-stream/commit/b0d232f)) -* feat(Highlights): Closes #1767; show highlights after welcome popup w/o reload ([df7f9f6](https://github.com/mozilla/activity-stream/commit/df7f9f6)), closes [#1767](https://github.com/mozilla/activity-stream/issues/1767) -* feat(highlights): Closes #2377 Remove favicon for highlights ([db353a9](https://github.com/mozilla/activity-stream/commit/db353a9)), closes [#2377](https://github.com/mozilla/activity-stream/issues/2377) -* feat(highlights): Fetch a minimum number of results if not enough recent links (#1474) ([da37c98](https://github.com/mozilla/activity-stream/commit/da37c98)) -* feat(highlights): Implement new grid highlights, remove old spotlight feed, r=@sarracini ([5567ab8](https://github.com/mozilla/activity-stream/commit/5567ab8)) -* feat(highlights): Implement new query and adjust weights ([b838901](https://github.com/mozilla/activity-stream/commit/b838901)) -* feat(intl): #2031 Add locale to state adnd Intl reducer ([950f737](https://github.com/mozilla/activity-stream/commit/950f737)) -* feat(intl): #2031 add locales build step to bundle ([4ee1918](https://github.com/mozilla/activity-stream/commit/4ee1918)) -* feat(intl): #2031 Load correct localization and strings ([a368e12](https://github.com/mozilla/activity-stream/commit/a368e12)) -* feat(intl): #2117 convert strings to .properties and add pontoon-to-json ([2e76bc7](https://github.com/mozilla/activity-stream/commit/2e76bc7)) -* feat(l10n): #2009 Add build script to export and commit strings to strings repository templates ([1618432](https://github.com/mozilla/activity-stream/commit/1618432)) -* feat(l10n): #2012 Add import build script that updates strings repository and replaces strings local ([41ebfab](https://github.com/mozilla/activity-stream/commit/41ebfab)) -* feat(l10n): Closes #2016 Create strings file and implement i18n in React ([6a96b82](https://github.com/mozilla/activity-stream/commit/6a96b82)), closes [#2016](https://github.com/mozilla/activity-stream/issues/2016) -* feat(l10n): Closes #2019 Localize number display ([14a7244](https://github.com/mozilla/activity-stream/commit/14a7244)), closes [#2019](https://github.com/mozilla/activity-stream/issues/2019) -* feat(l10n): Closes #2122 Add comments to strings.properties ([f1e82ec](https://github.com/mozilla/activity-stream/commit/f1e82ec)), closes [#2122](https://github.com/mozilla/activity-stream/issues/2122) -* feat(l10n): Closes #2136 Determine dir of html ([e90f0d1](https://github.com/mozilla/activity-stream/commit/e90f0d1)), closes [#2136](https://github.com/mozilla/activity-stream/issues/2136) -* feat(l10n): Fixes #2128 Add support files for locales ([48f534f](https://github.com/mozilla/activity-stream/commit/48f534f)), closes [#2128](https://github.com/mozilla/activity-stream/issues/2128) -* feat(mc): #2249 Add Store, Actions, Reducers, and Redux ([faec714](https://github.com/mozilla/activity-stream/commit/faec714)) -* feat(mc): #2269 Add handling for NEW_TAB_LOAD ([d17628a](https://github.com/mozilla/activity-stream/commit/d17628a)) -* feat(mc): #2269 Add MessageManager ([4260eb3](https://github.com/mozilla/activity-stream/commit/4260eb3)) -* feat(mc): #2386 Add react-redux to content and Top Sites shell ([681c497](https://github.com/mozilla/activity-stream/commit/681c497)) -* feat(mc): #2400 Add new actions for top sites ([e95b759](https://github.com/mozilla/activity-stream/commit/e95b759)) -* feat(mc): #2400 Add TopSites/Screenshots reducer to system-addon ([2c13073](https://github.com/mozilla/activity-stream/commit/2c13073)) -* feat(mc): #2405 Port base of Top Sites UI ([5e05dbb](https://github.com/mozilla/activity-stream/commit/5e05dbb)) -* feat(mc): #2472 Integrate default top sites ([b6f58a5](https://github.com/mozilla/activity-stream/commit/b6f58a5)) -* feat(mc): #2518 Add bookmarking, deleting, blocking apis ([7addd99](https://github.com/mozilla/activity-stream/commit/7addd99)) -* feat(mc): Add bootstrap.js and other files for mc version of add-on ([f788e6f](https://github.com/mozilla/activity-stream/commit/f788e6f)) -* feat(mc): Additionally localize LinkMenu (#2564) ([bbabcbb](https://github.com/mozilla/activity-stream/commit/bbabcbb)) -* feat(mc): Closes #2292 Add base content code ([1389736](https://github.com/mozilla/activity-stream/commit/1389736)), closes [#2292](https://github.com/mozilla/activity-stream/issues/2292) -* feat(mc): Closes #2292 Add vendor for react and react-dom ([54b3a45](https://github.com/mozilla/activity-stream/commit/54b3a45)), closes [#2292](https://github.com/mozilla/activity-stream/issues/2292) -* feat(mc): Closes #2328 Add base css and build task ([ec0d3b3](https://github.com/mozilla/activity-stream/commit/ec0d3b3)), closes [#2328](https://github.com/mozilla/activity-stream/issues/2328) -* feat(mc): Closes #2401 Port top sites feed to system addon ([0baaa5d](https://github.com/mozilla/activity-stream/commit/0baaa5d)), closes [#2401](https://github.com/mozilla/activity-stream/issues/2401) -* feat(mc): Implement TelemetryFeed.jsm to replace tab tracker ([d661e2d](https://github.com/mozilla/activity-stream/commit/d661e2d)) -* feat(mc): Port localization code using react-intl and reusing strings (#2555) ([864d49c](https://github.com/mozilla/activity-stream/commit/864d49c)) -* feat(metadata): Closes #1409 Create a page scraper ([1fcfd1c](https://github.com/mozilla/activity-stream/commit/1fcfd1c)), closes [#1409](https://github.com/mozilla/activity-stream/issues/1409) -* feat(metadata): Closes #1417 Add a framescript for local metadata parsing ([c1f1c5c](https://github.com/mozilla/activity-stream/commit/c1f1c5c)), closes [#1417](https://github.com/mozilla/activity-stream/issues/1417) -* feat(metadata): Closes #1430 Init PageScraper and pref it off ([1ac6370](https://github.com/mozilla/activity-stream/commit/1ac6370)), closes [#1430](https://github.com/mozilla/activity-stream/issues/1430) -* feat(metadata): Closes #1588 add provider_name to metadata ([c9f498b](https://github.com/mozilla/activity-stream/commit/c9f498b)), closes [#1588](https://github.com/mozilla/activity-stream/issues/1588) -* feat(metadata): Closes #1685 Fetch page content locally ([fc4e40f](https://github.com/mozilla/activity-stream/commit/fc4e40f)), closes [#1685](https://github.com/mozilla/activity-stream/issues/1685) -* feat(metadata): Closes #1940 Deprecate Embedly ([fa5e99a](https://github.com/mozilla/activity-stream/commit/fa5e99a)), closes [#1940](https://github.com/mozilla/activity-stream/issues/1940) -* feat(metadata): Closes #2044 compute and store favicon sizes ([9eddc0b](https://github.com/mozilla/activity-stream/commit/9eddc0b)), closes [#2044](https://github.com/mozilla/activity-stream/issues/2044) -* feat(metadata): Compute image size locally (#1644) ([51264fa](https://github.com/mozilla/activity-stream/commit/51264fa)) -* feat(metrics): #2486 - Add impression-stats ping ([10528f4](https://github.com/mozilla/activity-stream/commit/10528f4)) -* feat(metrics): Closes #1175 Add metadata_source to pings ([08dcefd](https://github.com/mozilla/activity-stream/commit/08dcefd)), closes [#1175](https://github.com/mozilla/activity-stream/issues/1175) -* feat(metrics): Closes #1961 Capture telemetry for clearing history ([c33773a](https://github.com/mozilla/activity-stream/commit/c33773a)), closes [#1961](https://github.com/mozilla/activity-stream/issues/1961) -* feat(mozilla-central): #2038 Add a moz.build for copying over to mozilla-central ([8b3298f](https://github.com/mozilla/activity-stream/commit/8b3298f)) -* feat(mozilla-central): #2039 Update the package script to generate a mozilla-central version of the ([7b8a056](https://github.com/mozilla/activity-stream/commit/7b8a056)) -* feat(mozilla-central): #2040 Update README documentation on how to export the add-on to mozilla-cent ([af6a73e](https://github.com/mozilla/activity-stream/commit/af6a73e)) -* feat(mozilla-central): #2041 Add an export script that copies over and patches mozilla-central to bu ([af4b257](https://github.com/mozilla/activity-stream/commit/af4b257)) -* feat(NewTab): (closes #1675) show placeholder content when "waiting" dialog up ([ccb4a48](https://github.com/mozilla/activity-stream/commit/ccb4a48)), closes [#1675](https://github.com/mozilla/activity-stream/issues/1675) -* feat(page-worker): #1090 Added page worker ([e3d45bd](https://github.com/mozilla/activity-stream/commit/e3d45bd)) -* feat(page-worker): #1090 change NEWTAB_RENDER event ([a1fbc72](https://github.com/mozilla/activity-stream/commit/a1fbc72)) -* feat(page-worker): #1090 Remove old messages, rehydrate store ([8608a52](https://github.com/mozilla/activity-stream/commit/8608a52)) -* feat(page-worker): #1090 Set TabTracker id in onOpen ([5b972f0](https://github.com/mozilla/activity-stream/commit/5b972f0)) -* feat(page-worker): #1090 ShareProvider.providers race condition fix ([a4cfc48](https://github.com/mozilla/activity-stream/commit/a4cfc48)) -* feat(places): Ditch the left join on moz_favicons (#2380) ([6a302ff](https://github.com/mozilla/activity-stream/commit/6a302ff)) -* feat(places): Fixes #1901 Refresh after clearing history ([9cd3279](https://github.com/mozilla/activity-stream/commit/9cd3279)), closes [#1901](https://github.com/mozilla/activity-stream/issues/1901) -* feat(prefs): Closes #2170 Global pref to turn experiments off ([190b75c](https://github.com/mozilla/activity-stream/commit/190b75c)), closes [#2170](https://github.com/mozilla/activity-stream/issues/2170) -* feat(redux): #1090 move store to common ([9bec520](https://github.com/mozilla/activity-stream/commit/9bec520)) -* feat(rtl): Closes #2023 Make Activity Stream RTL ([c1cb03a](https://github.com/mozilla/activity-stream/commit/c1cb03a)), closes [#2023](https://github.com/mozilla/activity-stream/issues/2023) -* feat(share): #2174 Remove ShareProvider and tests ([dbb8c05](https://github.com/mozilla/activity-stream/commit/dbb8c05)) -* feat(share): #2174 Remove ShareProviders reducer and actions ([555ef3f](https://github.com/mozilla/activity-stream/commit/555ef3f)) -* feat(share): #2174 Remove sharing from LinkMenu ([21992f6](https://github.com/mozilla/activity-stream/commit/21992f6)) -* feat(system-addon): Closes #2437 Send entire message to parent ([1b98739](https://github.com/mozilla/activity-stream/commit/1b98739)), closes [#2437](https://github.com/mozilla/activity-stream/issues/2437) -* feat(system-addon): Closes #2455 start AS on browser-ui-startup-complete ([211412f](https://github.com/mozilla/activity-stream/commit/211412f)), closes [#2455](https://github.com/mozilla/activity-stream/issues/2455) -* feat(system-addon): Create search feed + base search UI (#2427) ([7b21593](https://github.com/mozilla/activity-stream/commit/7b21593)) -* feat(system-addon): Hook in events from places with context menu (#2575) ([ea64b5e](https://github.com/mozilla/activity-stream/commit/ea64b5e)) -* feat(testing): Include original git commit message in hg test-merges version (#2338) ([1f399b7](https://github.com/mozilla/activity-stream/commit/1f399b7)) -* feat(tests): Closes #2145 Migrate private browsing test to mochitest ([550b824](https://github.com/mozilla/activity-stream/commit/550b824)), closes [#2145](https://github.com/mozilla/activity-stream/issues/2145) -* feat(tests): Migrate about:home test to mochitest (#2192) ([4e6916a](https://github.com/mozilla/activity-stream/commit/4e6916a)) -* feat(timeline): Improve filtering with word boundary and smart-case-sensitive matches (#1350) ([22806ca](https://github.com/mozilla/activity-stream/commit/22806ca)) -* feat(topsites): Show shorter top sites label without top level domain ([66576d7](https://github.com/mozilla/activity-stream/commit/66576d7)) +* chore: Cleanup ESLint global definitions - remove unnecessary ones now eslint-plugin-mozilla is used ([5cde685](https://github.com/mozilla/activity-stream/commit/5cde685)) * chore(actions): Remove unused experiment actions ([7198a54](https://github.com/mozilla/activity-stream/commit/7198a54)) * chore(addon): #1509 - Host the add-on release channel via Test Pilot ([454f581](https://github.com/mozilla/activity-stream/commit/454f581)) * chore(addon): #1583 - Remove the recommendation module ([cb0dce5](https://github.com/mozilla/activity-stream/commit/cb0dce5)) @@ -325,7 +261,6 @@ * chore(addon): Closes #1245 Remove unused 'previewsOnly' flag ([73e7577](https://github.com/mozilla/activity-stream/commit/73e7577)), closes [#1245](https://github.com/mozilla/activity-stream/issues/1245) * chore(addon): Convert metadata server URI to prod stack (#1205) ([cf70903](https://github.com/mozilla/activity-stream/commit/cf70903)) * chore(addon): Disable ExperimentProvider for SHIELD study users. (#1602) ([668ade9](https://github.com/mozilla/activity-stream/commit/668ade9)) -* chore(addon): Enable travis for 1.12.0 ([2594a17](https://github.com/mozilla/activity-stream/commit/2594a17)) * chore(addon): Fix invalid template strings in addon/MetadataStore.js ([d559e61](https://github.com/mozilla/activity-stream/commit/d559e61)) * chore(addon): Fix the version format ([795a46f](https://github.com/mozilla/activity-stream/commit/795a46f)) * chore(addon): Fix TravisCI build script ([5644944](https://github.com/mozilla/activity-stream/commit/5644944)) @@ -365,8 +300,11 @@ * chore(files): Sort constants.js alphabetically ([3d8a401](https://github.com/mozilla/activity-stream/commit/3d8a401)) * chore(gitignore): Ignore .update.rdf ([2b63494](https://github.com/mozilla/activity-stream/commit/2b63494)) * chore(l10n): Update L10n from changeset 13c44b6cc47ad03d47e5abaff92417681b010463 ([9e9c5ff](https://github.com/mozilla/activity-stream/commit/9e9c5ff)) +* chore(l10n): Update L10n from changeset 261f22ead1750df829ad286e40b5e23eb883bc31 ([036e6e6](https://github.com/mozilla/activity-stream/commit/036e6e6)) * chore(l10n): Update L10n from changeset 2f14751736f6cf3fc071590b4f57b6e5260e35ad ([610729c](https://github.com/mozilla/activity-stream/commit/610729c)) * chore(l10n): Update L10n from changeset 47736a48a2ecf13cf718abe550616a6b293936ef ([13fd993](https://github.com/mozilla/activity-stream/commit/13fd993)) +* chore(l10n): Update L10n from changeset 5761e22f1c47db5e47157bba1ed9d0cf7227a920 ([2db079d](https://github.com/mozilla/activity-stream/commit/2db079d)) +* chore(l10n): Update L10n from changeset 5d1af13de50940e10186f8ec239ce55f7a18c1ca ([f76583e](https://github.com/mozilla/activity-stream/commit/f76583e)) * chore(l10n): Update L10n from changeset 7812f9d6f1e619635ed9e625a27a27cc8bc07679 ([c77516c](https://github.com/mozilla/activity-stream/commit/c77516c)) * chore(l10n): Update L10n from changeset adea115fd8f92f6b6421492f3ea4b106b6fe4554 ([44e39c5](https://github.com/mozilla/activity-stream/commit/44e39c5)) * chore(l10n): Update L10n from changeset aeb6efa419adfadf3dcc9d8882dc29be1218e9ca ([cc373b9](https://github.com/mozilla/activity-stream/commit/cc373b9)) @@ -389,11 +327,13 @@ * chore(mc): #2287 Add coverage reporting ([fd1b606](https://github.com/mozilla/activity-stream/commit/fd1b606)) * chore(mc): #2330 Import changes from review of Bug 1349288 ([5944c5f](https://github.com/mozilla/activity-stream/commit/5944c5f)) * chore(mc): #2572 Add Telemetry for search, Top Sites clicks ([d217f90](https://github.com/mozilla/activity-stream/commit/d217f90)) +* chore(mc): #2651 Remove unused file ([da3bc1a](https://github.com/mozilla/activity-stream/commit/da3bc1a)) * chore(mc): A few accessibility-related fixes ([d0c58fc](https://github.com/mozilla/activity-stream/commit/d0c58fc)) * chore(mc): Backport changes from Bug 1350411 ([9ea3181](https://github.com/mozilla/activity-stream/commit/9ea3181)) * chore(mc): Backport class definition from Bug 1350411 (#2501) ([14c3693](https://github.com/mozilla/activity-stream/commit/14c3693)) * chore(mc): Clean up moz.build and scripts to export without tests enabled (#2493) ([b4c46b6](https://github.com/mozilla/activity-stream/commit/b4c46b6)) * chore(mc): Closes #2308 Backport changes from Bug 1345122 ([4c4b4eb](https://github.com/mozilla/activity-stream/commit/4c4b4eb)), closes [#2308](https://github.com/mozilla/activity-stream/issues/2308) +* chore(mc): Fix buildmc:copy task for startmc (#2612) ([a9ca91b](https://github.com/mozilla/activity-stream/commit/a9ca91b)), closes [#2612](https://github.com/mozilla/activity-stream/issues/2612) * chore(mc): Remove patch for moz.build (#2251) ([21f5976](https://github.com/mozilla/activity-stream/commit/21f5976)) * chore(mc): Remove unneeded eslint patch that has landed (#2490) ([1496119](https://github.com/mozilla/activity-stream/commit/1496119)) * chore(mc): Rename sass partials to start with _ (#2597) ([c1964d1](https://github.com/mozilla/activity-stream/commit/c1964d1)) @@ -511,17 +451,132 @@ * tests(mc): #2451 Move test setup to beforeEach instead of before ([5e82d9d](https://github.com/mozilla/activity-stream/commit/5e82d9d)) * tests(mc): Add test coverage for Search, Topsites components ([78b611b](https://github.com/mozilla/activity-stream/commit/78b611b)) * tests(mc): Exclude content-src src and test from buildmc ([ee6696a](https://github.com/mozilla/activity-stream/commit/ee6696a)) +* tests(mc): Reenable tiles tests (#2695) ([20796f5](https://github.com/mozilla/activity-stream/commit/20796f5)) * tests(mc): Rename tests with jsx to .jsx (#2586) ([1b6f68f](https://github.com/mozilla/activity-stream/commit/1b6f68f)) * tests(metadata): Closes #1467 Integration test for framescript ([ffb0a3f](https://github.com/mozilla/activity-stream/commit/ffb0a3f)), closes [#1467](https://github.com/mozilla/activity-stream/issues/1467) * tests(mocha): #1255 Add shim for Services ([ba3425b](https://github.com/mozilla/activity-stream/commit/ba3425b)) * tests(shims): #1375 General override globals ([ae7c779](https://github.com/mozilla/activity-stream/commit/ae7c779)) * tests(shims): #1375 Task global for test shims ([903b18f](https://github.com/mozilla/activity-stream/commit/903b18f)) * tests(topsites): Add action tests for TOP_SITES click ([0b8e11c](https://github.com/mozilla/activity-stream/commit/0b8e11c)) +* feat(a11y): Closes #1993 Bring '...' button to foreground ([473ead6](https://github.com/mozilla/activity-stream/commit/473ead6)), closes [#1993](https://github.com/mozilla/activity-stream/issues/1993) +* feat(addon): #1452 Add 'Feeds' to allow for custom update cycles ([94d350b](https://github.com/mozilla/activity-stream/commit/94d350b)) +* feat(addon): #1512 Add lodash.debounce and timers to vendor-src ([2d747e7](https://github.com/mozilla/activity-stream/commit/2d747e7)) +* feat(addon): #2045 Add support for screenshots ([385da1a](https://github.com/mozilla/activity-stream/commit/385da1a)) +* feat(addon): #2045 Add UI to support screenshots ([4ce4982](https://github.com/mozilla/activity-stream/commit/4ce4982)) +* feat(addon): add benchmarking support ([e0573d8](https://github.com/mozilla/activity-stream/commit/e0573d8)) +* feat(benchmark): #1236 add baseline benchmarks ([4981e9b](https://github.com/mozilla/activity-stream/commit/4981e9b)) +* feat(content): #1537 Onboarding tooltip for top sites/highlights ([ad665a9](https://github.com/mozilla/activity-stream/commit/ad665a9)) +* feat(content): #1906 Add Snippet component ([494777d](https://github.com/mozilla/activity-stream/commit/494777d)) +* feat(content): #2466 Enable pocket pref for all users ([378b9ab](https://github.com/mozilla/activity-stream/commit/378b9ab)) +* feat(content): #2486 Track impressions for Pocket ([7f06e15](https://github.com/mozilla/activity-stream/commit/7f06e15)) +* feat(content): #2496 UX improvements for Pocket ([19fa70d](https://github.com/mozilla/activity-stream/commit/19fa70d)) +* feat(content): #2536 Logo should link to Pocket, +Feedback form ([0b97cb6](https://github.com/mozilla/activity-stream/commit/0b97cb6)) +* feat(content): #2600 Add telemetry on the 'Read More' links for Pocket ([6f8f52c](https://github.com/mozilla/activity-stream/commit/6f8f52c)) +* feat(content): Add "Save to Pocket" functionality to Spotlight/LinkMenu ([5364ad7](https://github.com/mozilla/activity-stream/commit/5364ad7)) +* feat(content): Add 2x logo for Pocket (#2494) ([4f7bfb0](https://github.com/mozilla/activity-stream/commit/4f7bfb0)) +* feat(content): Add basic token matching for Timeline all/bookmark views with search in header. ([e9eaa2b](https://github.com/mozilla/activity-stream/commit/e9eaa2b)) +* feat(content): Add dismiss button for timeline filtering ([f8bda05](https://github.com/mozilla/activity-stream/commit/f8bda05)) +* feat(content): Add pocket trending stories for test-pilot add-on ([2c7aff0](https://github.com/mozilla/activity-stream/commit/2c7aff0)) +* feat(content): Configure pocket experiment threshold ([4e8c7a3](https://github.com/mozilla/activity-stream/commit/4e8c7a3)) +* feat(content): Implement new tab preferences pane (#2196) ([833ef2b](https://github.com/mozilla/activity-stream/commit/833ef2b)) +* feat(content): Refresh pocket feed on pref change ([48de7ee](https://github.com/mozilla/activity-stream/commit/48de7ee)) +* feat(experiments): #964 Add experiment overriding via prefs ([da1fddf](https://github.com/mozilla/activity-stream/commit/da1fddf)) +* feat(experiments): Add display for experiments to debug (#1728) ([a4fb50a](https://github.com/mozilla/activity-stream/commit/a4fb50a)) +* feat(experiments): Closes #1084 Run MetadataService vs Embedly ([d6cb5fe](https://github.com/mozilla/activity-stream/commit/d6cb5fe)), closes [#1084](https://github.com/mozilla/activity-stream/issues/1084) +* feat(experiments): Closes #1431 Set up local metadata parser as experiment ([bc368b3](https://github.com/mozilla/activity-stream/commit/bc368b3)), closes [#1431](https://github.com/mozilla/activity-stream/issues/1431) +* feat(experiments): Closes #1952 Use orig tiles algorithm for top sites ([798b517](https://github.com/mozilla/activity-stream/commit/798b517)), closes [#1952](https://github.com/mozilla/activity-stream/issues/1952) +* feat(feeds): #1452 Remove History, Old Highlights Feeds ([50c058d](https://github.com/mozilla/activity-stream/commit/50c058d)) +* feat(feeds): #1681 Add PlacesStatsFeed for history, bookmarks size ([a78c055](https://github.com/mozilla/activity-stream/commit/a78c055)) +* feat(feeds): #1750 PageModProvider, add broadcasting/send to feeds ([7575cd7](https://github.com/mozilla/activity-stream/commit/7575cd7)) +* feat(feeds): #1775 Add Search feed ([cb4cf14](https://github.com/mozilla/activity-stream/commit/cb4cf14)) +* feat(highlights): Always show recent bookmarks even without images (#1844) ([b0d232f](https://github.com/mozilla/activity-stream/commit/b0d232f)) +* feat(Highlights): Closes #1767; show highlights after welcome popup w/o reload ([df7f9f6](https://github.com/mozilla/activity-stream/commit/df7f9f6)), closes [#1767](https://github.com/mozilla/activity-stream/issues/1767) +* feat(highlights): Closes #2377 Remove favicon for highlights ([db353a9](https://github.com/mozilla/activity-stream/commit/db353a9)), closes [#2377](https://github.com/mozilla/activity-stream/issues/2377) +* feat(highlights): Fetch a minimum number of results if not enough recent links (#1474) ([da37c98](https://github.com/mozilla/activity-stream/commit/da37c98)) +* feat(highlights): Implement new grid highlights, remove old spotlight feed, r=@sarracini ([5567ab8](https://github.com/mozilla/activity-stream/commit/5567ab8)) +* feat(highlights): Implement new query and adjust weights ([b838901](https://github.com/mozilla/activity-stream/commit/b838901)) +* feat(intl): #2031 Add locale to state adnd Intl reducer ([950f737](https://github.com/mozilla/activity-stream/commit/950f737)) +* feat(intl): #2031 add locales build step to bundle ([4ee1918](https://github.com/mozilla/activity-stream/commit/4ee1918)) +* feat(intl): #2031 Load correct localization and strings ([a368e12](https://github.com/mozilla/activity-stream/commit/a368e12)) +* feat(intl): #2117 convert strings to .properties and add pontoon-to-json ([2e76bc7](https://github.com/mozilla/activity-stream/commit/2e76bc7)) +* feat(l10n): #2009 Add build script to export and commit strings to strings repository templates ([1618432](https://github.com/mozilla/activity-stream/commit/1618432)) +* feat(l10n): #2012 Add import build script that updates strings repository and replaces strings local ([41ebfab](https://github.com/mozilla/activity-stream/commit/41ebfab)) +* feat(l10n): Closes #2016 Create strings file and implement i18n in React ([6a96b82](https://github.com/mozilla/activity-stream/commit/6a96b82)), closes [#2016](https://github.com/mozilla/activity-stream/issues/2016) +* feat(l10n): Closes #2019 Localize number display ([14a7244](https://github.com/mozilla/activity-stream/commit/14a7244)), closes [#2019](https://github.com/mozilla/activity-stream/issues/2019) +* feat(l10n): Closes #2122 Add comments to strings.properties ([f1e82ec](https://github.com/mozilla/activity-stream/commit/f1e82ec)), closes [#2122](https://github.com/mozilla/activity-stream/issues/2122) +* feat(l10n): Closes #2136 Determine dir of html ([e90f0d1](https://github.com/mozilla/activity-stream/commit/e90f0d1)), closes [#2136](https://github.com/mozilla/activity-stream/issues/2136) +* feat(l10n): Fixes #2128 Add support files for locales ([48f534f](https://github.com/mozilla/activity-stream/commit/48f534f)), closes [#2128](https://github.com/mozilla/activity-stream/issues/2128) +* feat(mc): #2249 Add Store, Actions, Reducers, and Redux ([faec714](https://github.com/mozilla/activity-stream/commit/faec714)) +* feat(mc): #2269 Add handling for NEW_TAB_LOAD ([d17628a](https://github.com/mozilla/activity-stream/commit/d17628a)) +* feat(mc): #2269 Add MessageManager ([4260eb3](https://github.com/mozilla/activity-stream/commit/4260eb3)) +* feat(mc): #2386 Add react-redux to content and Top Sites shell ([681c497](https://github.com/mozilla/activity-stream/commit/681c497)) +* feat(mc): #2400 Add new actions for top sites ([e95b759](https://github.com/mozilla/activity-stream/commit/e95b759)) +* feat(mc): #2400 Add TopSites/Screenshots reducer to system-addon ([2c13073](https://github.com/mozilla/activity-stream/commit/2c13073)) +* feat(mc): #2405 Port base of Top Sites UI ([5e05dbb](https://github.com/mozilla/activity-stream/commit/5e05dbb)) +* feat(mc): #2472 Integrate default top sites ([b6f58a5](https://github.com/mozilla/activity-stream/commit/b6f58a5)) +* feat(mc): #2507 Add ActivityStreamPrefs.jsm to manage default prefs ([3fc09c0](https://github.com/mozilla/activity-stream/commit/3fc09c0)) +* feat(mc): #2518 Add bookmarking, deleting, blocking apis ([7addd99](https://github.com/mozilla/activity-stream/commit/7addd99)) +* feat(mc): #2684 Add Prefs feed, panel UI, and reducer ([c96f365](https://github.com/mozilla/activity-stream/commit/c96f365)) +* feat(mc): Add bootstrap.js and other files for mc version of add-on ([f788e6f](https://github.com/mozilla/activity-stream/commit/f788e6f)) +* feat(mc): Additionally localize LinkMenu (#2564) ([bbabcbb](https://github.com/mozilla/activity-stream/commit/bbabcbb)) +* feat(mc): Allow packaging of the system add-on .xpi for stand-alone installation (#2607) ([72f12c6](https://github.com/mozilla/activity-stream/commit/72f12c6)) +* feat(mc): Closes #2292 Add base content code ([1389736](https://github.com/mozilla/activity-stream/commit/1389736)), closes [#2292](https://github.com/mozilla/activity-stream/issues/2292) +* feat(mc): Closes #2292 Add vendor for react and react-dom ([54b3a45](https://github.com/mozilla/activity-stream/commit/54b3a45)), closes [#2292](https://github.com/mozilla/activity-stream/issues/2292) +* feat(mc): Closes #2328 Add base css and build task ([ec0d3b3](https://github.com/mozilla/activity-stream/commit/ec0d3b3)), closes [#2328](https://github.com/mozilla/activity-stream/issues/2328) +* feat(mc): Closes #2401 Port top sites feed to system addon ([0baaa5d](https://github.com/mozilla/activity-stream/commit/0baaa5d)), closes [#2401](https://github.com/mozilla/activity-stream/issues/2401) +* feat(mc): Implement search suggestions by reusing contentSearchUI (#2611) ([8ab1982](https://github.com/mozilla/activity-stream/commit/8ab1982)) +* feat(mc): Implement TelemetryFeed.jsm to replace tab tracker ([d661e2d](https://github.com/mozilla/activity-stream/commit/d661e2d)) +* feat(mc): Port localization code using react-intl and reusing strings (#2555) ([864d49c](https://github.com/mozilla/activity-stream/commit/864d49c)) +* feat(metadata): Closes #1409 Create a page scraper ([1fcfd1c](https://github.com/mozilla/activity-stream/commit/1fcfd1c)), closes [#1409](https://github.com/mozilla/activity-stream/issues/1409) +* feat(metadata): Closes #1417 Add a framescript for local metadata parsing ([c1f1c5c](https://github.com/mozilla/activity-stream/commit/c1f1c5c)), closes [#1417](https://github.com/mozilla/activity-stream/issues/1417) +* feat(metadata): Closes #1430 Init PageScraper and pref it off ([1ac6370](https://github.com/mozilla/activity-stream/commit/1ac6370)), closes [#1430](https://github.com/mozilla/activity-stream/issues/1430) +* feat(metadata): Closes #1588 add provider_name to metadata ([c9f498b](https://github.com/mozilla/activity-stream/commit/c9f498b)), closes [#1588](https://github.com/mozilla/activity-stream/issues/1588) +* feat(metadata): Closes #1685 Fetch page content locally ([fc4e40f](https://github.com/mozilla/activity-stream/commit/fc4e40f)), closes [#1685](https://github.com/mozilla/activity-stream/issues/1685) +* feat(metadata): Closes #1940 Deprecate Embedly ([fa5e99a](https://github.com/mozilla/activity-stream/commit/fa5e99a)), closes [#1940](https://github.com/mozilla/activity-stream/issues/1940) +* feat(metadata): Closes #2044 compute and store favicon sizes ([9eddc0b](https://github.com/mozilla/activity-stream/commit/9eddc0b)), closes [#2044](https://github.com/mozilla/activity-stream/issues/2044) +* feat(metadata): Compute image size locally (#1644) ([51264fa](https://github.com/mozilla/activity-stream/commit/51264fa)) +* feat(metrics): #2486 - Add impression-stats ping ([10528f4](https://github.com/mozilla/activity-stream/commit/10528f4)) +* feat(metrics): Closes #1175 Add metadata_source to pings ([08dcefd](https://github.com/mozilla/activity-stream/commit/08dcefd)), closes [#1175](https://github.com/mozilla/activity-stream/issues/1175) +* feat(metrics): Closes #1961 Capture telemetry for clearing history ([c33773a](https://github.com/mozilla/activity-stream/commit/c33773a)), closes [#1961](https://github.com/mozilla/activity-stream/issues/1961) +* feat(mozilla-central): #2038 Add a moz.build for copying over to mozilla-central ([8b3298f](https://github.com/mozilla/activity-stream/commit/8b3298f)) +* feat(mozilla-central): #2039 Update the package script to generate a mozilla-central version of the ([7b8a056](https://github.com/mozilla/activity-stream/commit/7b8a056)) +* feat(mozilla-central): #2040 Update README documentation on how to export the add-on to mozilla-cent ([af6a73e](https://github.com/mozilla/activity-stream/commit/af6a73e)) +* feat(mozilla-central): #2041 Add an export script that copies over and patches mozilla-central to bu ([af4b257](https://github.com/mozilla/activity-stream/commit/af4b257)) +* feat(NewTab): (closes #1675) show placeholder content when "waiting" dialog up ([ccb4a48](https://github.com/mozilla/activity-stream/commit/ccb4a48)), closes [#1675](https://github.com/mozilla/activity-stream/issues/1675) +* feat(page-worker): #1090 Added page worker ([e3d45bd](https://github.com/mozilla/activity-stream/commit/e3d45bd)) +* feat(page-worker): #1090 change NEWTAB_RENDER event ([a1fbc72](https://github.com/mozilla/activity-stream/commit/a1fbc72)) +* feat(page-worker): #1090 Remove old messages, rehydrate store ([8608a52](https://github.com/mozilla/activity-stream/commit/8608a52)) +* feat(page-worker): #1090 Set TabTracker id in onOpen ([5b972f0](https://github.com/mozilla/activity-stream/commit/5b972f0)) +* feat(page-worker): #1090 ShareProvider.providers race condition fix ([a4cfc48](https://github.com/mozilla/activity-stream/commit/a4cfc48)) +* feat(places): Ditch the left join on moz_favicons (#2380) ([6a302ff](https://github.com/mozilla/activity-stream/commit/6a302ff)) +* feat(places): Fixes #1901 Refresh after clearing history ([9cd3279](https://github.com/mozilla/activity-stream/commit/9cd3279)), closes [#1901](https://github.com/mozilla/activity-stream/issues/1901) +* feat(prefs): Closes #2170 Global pref to turn experiments off ([190b75c](https://github.com/mozilla/activity-stream/commit/190b75c)), closes [#2170](https://github.com/mozilla/activity-stream/issues/2170) +* feat(redux): #1090 move store to common ([9bec520](https://github.com/mozilla/activity-stream/commit/9bec520)) +* feat(rtl): Closes #2023 Make Activity Stream RTL ([c1cb03a](https://github.com/mozilla/activity-stream/commit/c1cb03a)), closes [#2023](https://github.com/mozilla/activity-stream/issues/2023) +* feat(share): #2174 Remove ShareProvider and tests ([dbb8c05](https://github.com/mozilla/activity-stream/commit/dbb8c05)) +* feat(share): #2174 Remove ShareProviders reducer and actions ([555ef3f](https://github.com/mozilla/activity-stream/commit/555ef3f)) +* feat(share): #2174 Remove sharing from LinkMenu ([21992f6](https://github.com/mozilla/activity-stream/commit/21992f6)) +* feat(system-addon): Closes #2437 Send entire message to parent ([1b98739](https://github.com/mozilla/activity-stream/commit/1b98739)), closes [#2437](https://github.com/mozilla/activity-stream/issues/2437) +* feat(system-addon): Closes #2455 start AS on browser-ui-startup-complete ([211412f](https://github.com/mozilla/activity-stream/commit/211412f)), closes [#2455](https://github.com/mozilla/activity-stream/issues/2455) +* feat(system-addon): Create search feed + base search UI (#2427) ([7b21593](https://github.com/mozilla/activity-stream/commit/7b21593)) +* feat(system-addon): Hook in events from places with context menu (#2575) ([ea64b5e](https://github.com/mozilla/activity-stream/commit/ea64b5e)) +* feat(testing): Include original git commit message in hg test-merges version (#2338) ([1f399b7](https://github.com/mozilla/activity-stream/commit/1f399b7)) +* feat(tests): Closes #2145 Migrate private browsing test to mochitest ([550b824](https://github.com/mozilla/activity-stream/commit/550b824)), closes [#2145](https://github.com/mozilla/activity-stream/issues/2145) +* feat(tests): Migrate about:home test to mochitest (#2192) ([4e6916a](https://github.com/mozilla/activity-stream/commit/4e6916a)) +* feat(timeline): Improve filtering with word boundary and smart-case-sensitive matches (#1350) ([22806ca](https://github.com/mozilla/activity-stream/commit/22806ca)) +* feat(topsites): Show shorter top sites label without top level domain ([66576d7](https://github.com/mozilla/activity-stream/commit/66576d7)) +* Fix(addon): #1620 - Update experimentId for TabTracker upon changes ([445f46c](https://github.com/mozilla/activity-stream/commit/445f46c)) +* Fix(content): #2463 Add localization note to header_stories ([2386eb5](https://github.com/mozilla/activity-stream/commit/2386eb5)) +* Fix(content): #2467 Dismissing a Pocket story doesn't add a new one ([d830277](https://github.com/mozilla/activity-stream/commit/d830277)) +* Fix(reducers): Fix mutation of .prefs in Prefs reducer (nobug) ([70a68c4](https://github.com/mozilla/activity-stream/commit/70a68c4)) +* Fix(test): fix the test failure in metadata store ([e99119f](https://github.com/mozilla/activity-stream/commit/e99119f)) +* Fix(tests): fixes #2394 to make test-merges send mail on errors (#2395) ([1b85dc5](https://github.com/mozilla/activity-stream/commit/1b85dc5)), closes [#2394](https://github.com/mozilla/activity-stream/issues/2394) [#2395](https://github.com/mozilla/activity-stream/issues/2395) * docs(activity-stream): add contributing.md (#1357) ([270b509](https://github.com/mozilla/activity-stream/commit/270b509)) * docs(deploy): Minor documentation typos (#2347) ([98c65f0](https://github.com/mozilla/activity-stream/commit/98c65f0)) * docs(l10n): #2123 Add docs for localization ([8fde9e0](https://github.com/mozilla/activity-stream/commit/8fde9e0)) * docs(l10n): Add tips for RTL-ing CSS (#2142) ([d5c4857](https://github.com/mozilla/activity-stream/commit/d5c4857)) * docs(mc): #2333 Amend data dictionary to reflect new pings ([18885ad](https://github.com/mozilla/activity-stream/commit/18885ad)) +* docs(mc): #2507 Add docs for preferences in the system add-on ([3e53edb](https://github.com/mozilla/activity-stream/commit/3e53edb)) * docs(mc): Add getting started documentation ([0ed0f01](https://github.com/mozilla/activity-stream/commit/0ed0f01)) * docs(mc): Add testing documentation ([6d500ad](https://github.com/mozilla/activity-stream/commit/6d500ad)) * docs(mc): Fix typo (#2571) ([f2e0743](https://github.com/mozilla/activity-stream/commit/f2e0743)), closes [#2571](https://github.com/mozilla/activity-stream/issues/2571) @@ -529,11 +584,6 @@ * vendor(mc): Add vendor/Redux.jsm ([f192a5a](https://github.com/mozilla/activity-stream/commit/f192a5a)) * vendor(mc): Use minified vendor react-intl@2.2.3 for system-addon (#2574) ([323a7e4](https://github.com/mozilla/activity-stream/commit/323a7e4)) * contextmenu(system-addon): Closes #2544 Port context menu UI ([d52b242](https://github.com/mozilla/activity-stream/commit/d52b242)), closes [#2544](https://github.com/mozilla/activity-stream/issues/2544) -* Fix(addon): #1620 - Update experimentId for TabTracker upon changes ([445f46c](https://github.com/mozilla/activity-stream/commit/445f46c)) -* Fix(content): #2463 Add localization note to header_stories ([2386eb5](https://github.com/mozilla/activity-stream/commit/2386eb5)) -* Fix(content): #2467 Dismissing a Pocket story doesn't add a new one ([d830277](https://github.com/mozilla/activity-stream/commit/d830277)) -* Fix(test): fix the test failure in metadata store ([e99119f](https://github.com/mozilla/activity-stream/commit/e99119f)) -* Fix(tests): fixes #2394 to make test-merges send mail on errors (#2395) ([1b85dc5](https://github.com/mozilla/activity-stream/commit/1b85dc5)), closes [#2394](https://github.com/mozilla/activity-stream/issues/2394) [#2395](https://github.com/mozilla/activity-stream/issues/2395) * style(mc): Remove 100% height on base ([4935085](https://github.com/mozilla/activity-stream/commit/4935085)) * style(mc): Style touch-ups from bbell ([8efea2f](https://github.com/mozilla/activity-stream/commit/8efea2f)) * feature(addon): #1511 persist active experiments in prefs. ([1940dea](https://github.com/mozilla/activity-stream/commit/1940dea)) @@ -570,11 +620,13 @@ * fix(coloranalyzer): Fixes #1920 Resolve on null color for ColorAnalyzer ([18c2f98](https://github.com/mozilla/activity-stream/commit/18c2f98)), closes [#1920](https://github.com/mozilla/activity-stream/issues/1920) * fix(content): #2079 Remove vertical padding on search input ([6ca5218](https://github.com/mozilla/activity-stream/commit/6ca5218)) * fix(content): #2561 Persist Pocket dismissals ([d9e76df](https://github.com/mozilla/activity-stream/commit/d9e76df)) -* fix(content): #2637 Pocket info modal needs a faster fade-in-out ([d1d182b](https://github.com/mozilla/activity-stream/commit/d1d182b)) +* fix(content): #2637 Pocket info modal needs a faster fade-in-out ([6ef1b3c](https://github.com/mozilla/activity-stream/commit/6ef1b3c)) +* fix(content): #2677 Pocket card overlaps with history card ([1488e8c](https://github.com/mozilla/activity-stream/commit/1488e8c)) * fix(content): Bumped tippy-top-sites for better icons ([2bfe0e8](https://github.com/mozilla/activity-stream/commit/2bfe0e8)) * fix(content): Closes #1149 Remove best image logic ([ed2b7cf](https://github.com/mozilla/activity-stream/commit/ed2b7cf)), closes [#1149](https://github.com/mozilla/activity-stream/issues/1149) * fix(content): Detect stabilization of state to reload from "Hang on tight" (#1636) ([70432bb](https://github.com/mozilla/activity-stream/commit/70432bb)) * fix(content): Disable search for current release ([f63d315](https://github.com/mozilla/activity-stream/commit/f63d315)) +* fix(content): Enhance #2708 fix to avoid line wrapping of Highlights ([fd96cca](https://github.com/mozilla/activity-stream/commit/fd96cca)) * fix(content): Improve localization values and notes for Pocket (read more) (#2495) ([2c372f0](https://github.com/mozilla/activity-stream/commit/2c372f0)) * fix(content): Remove 'Delete from History' from Pocket context menu (#2570) ([ffe9abc](https://github.com/mozilla/activity-stream/commit/ffe9abc)) * fix(content): Remove comment for unused arg in selectAndDedupe ([7dae034](https://github.com/mozilla/activity-stream/commit/7dae034)) @@ -618,6 +670,7 @@ * fix(mc): closes #2519, fix err message/suggest workaround for test-merges ([94b25b4](https://github.com/mozilla/activity-stream/commit/94b25b4)), closes [#2519](https://github.com/mozilla/activity-stream/issues/2519) * fix(mc): Fix typo in PlacesFeed and test (#2559) ([8c87be9](https://github.com/mozilla/activity-stream/commit/8c87be9)), closes [#2559](https://github.com/mozilla/activity-stream/issues/2559) * fix(mc): Fix unused files error for jar.mn (#2391) ([5e1fe44](https://github.com/mozilla/activity-stream/commit/5e1fe44)), closes [#2391](https://github.com/mozilla/activity-stream/issues/2391) +* fix(mc): Re-enable tightly-coupled search tests and correctly use newtab as the searchPurpose (#2689 ([5215925](https://github.com/mozilla/activity-stream/commit/5215925)) * fix(mc): Selectively not copy content-src (jsx, scss) and webpack config from system-addon to mozill ([934887d](https://github.com/mozilla/activity-stream/commit/934887d)) * fix(mc): Send a dummy content message to trigger ContentSearch initialization (#2558) ([dc23841](https://github.com/mozilla/activity-stream/commit/dc23841)) * fix(mc): Switch Task/yield usage to async/await ([5cb5271](https://github.com/mozilla/activity-stream/commit/5cb5271)) @@ -659,6 +712,7 @@ * fix(test): #1407 - Fix a race condition in places caching unit test ([509f8e7](https://github.com/mozilla/activity-stream/commit/509f8e7)) * fix(test): #1442 - fix a test failure in MetadataStore.js ([b39ef74](https://github.com/mozilla/activity-stream/commit/b39ef74)) * fix(test): fix a test failure in test-PlacesProvider.js ([00e6b37](https://github.com/mozilla/activity-stream/commit/00e6b37)) +* fix(test): Fix shell quoting issue in test-merges (#2638) ([920ed7d](https://github.com/mozilla/activity-stream/commit/920ed7d)), closes [#2638](https://github.com/mozilla/activity-stream/issues/2638) * fix(test): Potentially fix intermittent weightedHighlights test failure ([b70a35b](https://github.com/mozilla/activity-stream/commit/b70a35b)) * fix(tests): #1823 Only run tests after before in content-test/index.js ([a053f82](https://github.com/mozilla/activity-stream/commit/a053f82)) * fix(tests): #2362 disable m-c undo notification tests (#2364) ([e868917](https://github.com/mozilla/activity-stream/commit/e868917)) diff --git a/addon/ActivityStreams.js b/addon/ActivityStreams.js index 87bb13bc42..848ef7d344 100644 --- a/addon/ActivityStreams.js +++ b/addon/ActivityStreams.js @@ -107,7 +107,7 @@ ActivityStreams.prototype = { if (!this.options.shield_variant) { this._experimentProvider.init(); } - this._tabTracker.init(this.appURLs, this._experimentProvider.experimentId, this._store); + this._tabTracker.init(this.appURLs, this._experimentProvider, this._store); this._searchProvider.init(); this._initializePreviewProvider(this._metadataStore, this._tabTracker, this._store); this._initializePageScraper(this._previewProvider, this._tabTracker); @@ -225,7 +225,12 @@ ActivityStreams.prototype = { _respondToPlacesRequests({msg, worker}) { switch (msg.type) { case am.type("NOTIFY_BOOKMARK_ADD"): - PlacesProvider.links.asyncAddBookmark(msg.data); + PlacesProvider.links.asyncAddBookmark(msg.data.url); + + // Request metadata for the new bookmark if it has been added from PocketStories. + if (msg.data.source === "RECOMMENDED") { + this._pageScraper.asyncFetchLinks([{url: msg.data.url}], msg.type, true); + } break; case am.type("NOTIFY_BOOKMARK_DELETE"): PlacesProvider.links.asyncDeleteBookmark(msg.data); @@ -307,11 +312,6 @@ ActivityStreams.prototype = { this._tabTracker.handleImpressionStats(msg.data); }, - _handleExperimentChange(prefName) { - this._tabTracker.experimentId = this._experimentProvider.experimentID; - this.broadcast(am.actions.Response("EXPERIMENTS_RESPONSE", this._experimentProvider.data)); - }, - _respondToUIChanges(args) { const {msg} = args; switch (msg.type) { @@ -341,9 +341,6 @@ ActivityStreams.prototype = { this._handleCurrentEngineChanges = this._handleCurrentEngineChanges.bind(this); this._searchProvider.on("browser-search-engine-modified", this._handleCurrentEngineChanges); - this._handleExperimentChange = this._handleExperimentChange.bind(this); - this._experimentProvider.on("change", this._handleExperimentChange); - // This is a collection of handlers that receive messages from content this._contentToAddonHandlers = (msgName, args) => { // Log requests first so that the requests are logged before responses @@ -370,7 +367,6 @@ ActivityStreams.prototype = { _removeListeners() { PLACES_CHANGES_EVENTS.forEach(event => PlacesProvider.links.off(event, this._handlePlacesChanges)); this._searchProvider.off("browser-search-engine-modified", this._handleCurrentEngineChanges); - this._experimentProvider.off("change", this._handleExperimentChange); this.off(CONTENT_TO_ADDON, this._contentToAddonHandlers); }, diff --git a/addon/ExperimentProvider.js b/addon/ExperimentProvider.js index 82391661de..d89e9eac01 100644 --- a/addon/ExperimentProvider.js +++ b/addon/ExperimentProvider.js @@ -1,10 +1,13 @@ const {Cu} = require("chrome"); const prefService = require("sdk/preferences/service"); const simplePrefs = require("sdk/simple-prefs"); -const {PrefsTarget} = require("sdk/preferences/event-target"); +const {setTimeout} = require("sdk/timers"); const {preferencesBranch} = require("sdk/self"); const PREF_PREFIX = `extensions.${preferencesBranch}.experiments.`; +const EXPERIMENTS_ENDPOINT = "experiments.endpoint"; +const EXPERIMENTS_REFRESH_TIMEOUT = 60 * 60 * 1000; // Refresh once per hour +Cu.importGlobalProperties(["fetch"]); Cu.import("resource://gre/modules/XPCOMUtils.jsm"); XPCOMUtils.defineLazyGetter(this, "EventEmitter", () => { @@ -13,76 +16,85 @@ XPCOMUtils.defineLazyGetter(this, "EventEmitter", () => { }); exports.ExperimentProvider = class ExperimentProvider { - constructor(experiments = require("../experiments.json"), rng) { - this._experiments = experiments; + constructor(experiments = null, rng) { + this._testMode = false; + this._experiments = {}; this._rng = rng || Math.random; this._data = {}; this._experimentId = null; - this._target = PrefsTarget(); - EventEmitter.decorate(this); - this._onPrefChange = this._onPrefChange.bind(this); + if (experiments) { + this._testMode = true; + this._experiments = experiments; + } + EventEmitter.decorate(this); } init() { + if (this._testMode) { + this.setupExperiments(); + } else { + const experimentsEndpoint = simplePrefs.prefs[EXPERIMENTS_ENDPOINT]; + if (experimentsEndpoint) { + fetch(simplePrefs.prefs[EXPERIMENTS_ENDPOINT]) + .then(response => response.json()) + .then(experiments => { + this._experiments = {}; + this._data = {}; + experiments.forEach(experiment => { + this._experiments[experiment.slug] = experiment; + }); + this.setupExperiments(); + setTimeout(this.init.bind(this), EXPERIMENTS_REFRESH_TIMEOUT); + }) + .catch(e => { + Cu.reportError(e); + }); + } + } + } + + setupExperiments() { this.setValues(); - Object.keys(this._experiments).forEach(experimentName => { - this._target.on(PREF_PREFIX + experimentName, this._onPrefChange); - Object.defineProperty(this._data, experimentName, { + Object.keys(this._experiments).forEach(experimentId => { + Object.defineProperty(this._data, experimentId, { get() { - return prefService.get(PREF_PREFIX + experimentName); + return prefService.get(PREF_PREFIX + experimentId); }, enumerable: true }); }); } - _onPrefChange(prefName) { - this.overrideExperimentPrefs(prefName); - this.emit("change", prefName); - } - - /** - * This is called when experiment prefs are changed so - * that users are pulled out of all experiment reporting. - */ - overrideExperimentPrefs(prefName) { - simplePrefs.prefs.experimentsOverridden = true; - this._experimentId = null; - } - /** * This is used to disable all experiments, i.e set all their * values to their original control value. */ disableAllExperiments() { - Object.keys(this._experiments).forEach(key => { - const experiment = this._experiments[key]; + Object.keys(this._experiments).forEach(experimentId => { + const experiment = this._experiments[experimentId]; const {active, control} = experiment; if (active) { - prefService.set(PREF_PREFIX + key, control.value); + prefService.set(PREF_PREFIX + experimentId, control.value); } }); } enroll(experimentId, variant) { - this._experimentId = variant.id; + this._experimentId = experimentId; prefService.set(PREF_PREFIX + experimentId, variant.value); - if (experimentId === "topSitesTwoRowsDefault") { - simplePrefs.prefs.showMoreTopSites = true; - } this.emit("experimentEnrolled", {id: experimentId, variant}); } setValues() { if (simplePrefs.prefs.experimentsOverridden) { console.log(`The following experiments were turned on via overrides:\n`); // eslint-disable-line no-console - Object.keys(this._experiments).forEach(experimentName => { - const {variant, control} = this._experiments[experimentName]; - if (prefService.get(PREF_PREFIX + experimentName) === variant.value) { - console.log(`- ${experimentName} - \n`); // eslint-disable-line no-console + Object.keys(this._experiments).forEach(experimentId => { + const {variant, control} = this._experiments[experimentId]; + if (prefService.get(PREF_PREFIX + experimentId) === variant.value) { + console.log(`- ${experimentId} - \n`); // eslint-disable-line no-console } else { - prefService.set(PREF_PREFIX + experimentName, control.value); + prefService.set(PREF_PREFIX + experimentId, control.value); } }); return; @@ -98,36 +110,36 @@ exports.ExperimentProvider = class ExperimentProvider { let floor = 0; let inExperiment; - Object.keys(this._experiments).forEach(key => { - const experiment = this._experiments[key]; + Object.keys(this._experiments).forEach(experimentId => { + const experiment = this._experiments[experimentId]; const {variant, control} = experiment; - if (prefService.get(PREF_PREFIX + key) === variant.value) { + if (prefService.get(PREF_PREFIX + experimentId) === variant.value) { if (experiment.active) { // If the user is already part of an active experiment, set the experiment id. - this._experimentId = variant.id; + this._experimentId = experimentId; } else { // If the user is part of an inactive experiment, // reset that experiment's pref. - prefService.set(PREF_PREFIX + key, control.value); + prefService.set(PREF_PREFIX + experimentId, control.value); this._experimentId = null; } } }); - Object.keys(this._experiments).forEach(key => { - const experiment = this._experiments[key]; + Object.keys(this._experiments).forEach(experimentId => { + const experiment = this._experiments[experimentId]; const {variant, control} = experiment; const ceiling = variant.threshold + floor; // If the experiment is not new or not active you will not be assigned to it. - if (prefService.has(PREF_PREFIX + key) || !experiment.active) { + if (prefService.has(PREF_PREFIX + experimentId) || !experiment.active) { return; } // If the experiment pref is undefined, it's a new experiment. Start // by assuming the user will not be in it. - prefService.set(PREF_PREFIX + key, control.value); + prefService.set(PREF_PREFIX + experimentId, control.value); if (ceiling > 1) { throw new Error("Your variant cohort sizes should add up to less than 1."); @@ -142,7 +154,7 @@ exports.ExperimentProvider = class ExperimentProvider { // randomly assign them to a variant (or control) inExperiment = randomNumber >= floor && randomNumber < ceiling; if (inExperiment) { - this.enroll(key, variant); + this.enroll(experimentId, variant); } floor = ceiling; }); @@ -161,14 +173,11 @@ exports.ExperimentProvider = class ExperimentProvider { destroy() { this._experimentId = null; - Object.keys(this._experiments).forEach(experimentName => { - this._target.removeListener(PREF_PREFIX + experimentName, this._onPrefChange); - }); } clearPrefs() { - Object.keys(this._experiments).forEach(experimentName => { - prefService.reset(PREF_PREFIX + experimentName); + Object.keys(this._experiments).forEach(experimentId => { + prefService.reset(PREF_PREFIX + experimentId); }); simplePrefs.prefs.experimentsOverridden = false; } diff --git a/addon/Feeds/BookmarksFeed.js b/addon/Feeds/BookmarksFeed.js index 2eba12f4bf..4276651e7d 100644 --- a/addon/Feeds/BookmarksFeed.js +++ b/addon/Feeds/BookmarksFeed.js @@ -1,9 +1,10 @@ const {Cu} = require("chrome"); const {PlacesProvider} = require("addon/PlacesProvider"); const Feed = require("addon/lib/Feed"); -const {BOOKMARKS_LENGTH} = require("common/constants"); +const {BOOKMARKS_LENGTH, BOOKMARKS_THRESHOLD} = require("common/constants"); const am = require("common/action-manager"); const getScreenshot = require("addon/lib/getScreenshot"); +const simplePrefs = require("sdk/simple-prefs"); Cu.import("resource://gre/modules/Task.jsm"); @@ -16,18 +17,36 @@ module.exports = class BookmarksFeed extends Feed { this.missingData = false; } + /** + * Get the timestamp of the oldest bookmark. Used to filter out default bookmarks. + * Tries to fetch from prefs first otherwise goes out and does a query in PlacesProvider for it. + * + * @returns Integer Timestamp with dateAdded of oldest bookmark. + * @private + */ + _getDefaultBookmarksAge() { + return Task.spawn(function*() { + const prefValue = parseInt(simplePrefs.prefs.defaultBookmarksAge, 10); + + if (prefValue && prefValue !== 0) { + return prefValue; + } + + const result = yield PlacesProvider.links.getDefaultBookmarksAge(); + simplePrefs.prefs.defaultBookmarksAge = result.toString(); + return result; + }); + } + /** * shouldGetScreenshot - Returns true if the link/site provided meets the following: * - is a bookmark - * - has metadata * - doesn't have any images * * @return bool */ shouldGetScreenshot(link) { - return link.bookmarkGuid && - link.hasMetadata && - (!link.images || link.images.length === 0); + return link.bookmarkGuid && (!link.images || link.images.length === 0); } /** @@ -38,8 +57,13 @@ module.exports = class BookmarksFeed extends Feed { getData() { return Task.spawn(function*() { let links; + const defaultBookmarksAge = yield this._getDefaultBookmarksAge(); + // Get links from places - links = yield PlacesProvider.links.getBookmarks({limit: BOOKMARKS_LENGTH}); + links = yield PlacesProvider.links.getBookmarks({ + limit: BOOKMARKS_LENGTH, + ageMin: defaultBookmarksAge + BOOKMARKS_THRESHOLD + }); // Get metadata from PreviewProvider links = yield this.options.getCachedMetadata(links, "BOOKMARKS_RESPONSE"); @@ -62,6 +86,9 @@ module.exports = class BookmarksFeed extends Feed { } } + // Filter out bookmarks that don't have title. + links = links.filter(l => l.title); + return am.actions.Response("BOOKMARKS_RESPONSE", links); }.bind(this)); } diff --git a/addon/Feeds/HighlightsFeed.js b/addon/Feeds/HighlightsFeed.js deleted file mode 100644 index 75e9c3a079..0000000000 --- a/addon/Feeds/HighlightsFeed.js +++ /dev/null @@ -1,166 +0,0 @@ -const simplePrefs = require("sdk/simple-prefs"); -const {Cu} = require("chrome"); -const {PlacesProvider} = require("addon/PlacesProvider"); -const {Recommender} = require("common/recommender/Recommender"); -const Feed = require("addon/lib/Feed"); -const {TOP_SITES_DEFAULT_LENGTH, HIGHLIGHTS_LENGTH} = require("common/constants"); -const am = require("common/action-manager"); -const getScreenshot = require("addon/lib/getScreenshot"); - -Cu.import("resource://gre/modules/Task.jsm"); - -const UPDATE_TIME = 15 * 60 * 1000; // 15 minutes - -module.exports = class HighlightsFeed extends Feed { - constructor(options) { - super(options); - this.baselineRecommender = null; // Added in initializeRecommender - this.getScreenshot = getScreenshot; - this.missingData = false; - } - - /** - * getCoefficientsFromPrefs - Try to get the coefficients for the recommender from prefs. - * They should be an array of numbers - * - * @return {array/null} If we could parse them, we return the array. - * If we couldn't parse them, we return null. - */ - getCoefficientsFromPrefs() { - try { - let value = JSON.parse(simplePrefs.prefs.weightedHighlightsCoefficients); - if (Array.isArray(value)) { - return value; - } - Cu.reportError("Coefficients values must be a valid array"); - } catch (e) { - Cu.reportError(e); - } - return null; - } - - /** - * initializeRecommender - This creates a recommender and assigns it to .baselineRecommender - * To do this, it calls the .getAllHistoryItems query on places provider. - * It will then refresh the app - * - * @return {Promise} Returns the promise created by .getAllHistoryItems - */ - initializeRecommender(reason) { - return PlacesProvider.links.getAllHistoryItems().then(links => { - let highlightsCoefficients = this.getCoefficientsFromPrefs(); - this.baselineRecommender = new Recommender(links, { - experiments: this.store.getState().Experiments.values, - highlightsCoefficients - }); - }).then(() => this.refresh(reason)); - } - - /** - * shouldGetScreenshot - Returns true if the link/site provided meets the following: - * - is a bookmark - * - has metadata - * - doesn't have any images - * - * @return bool - */ - shouldGetScreenshot(link) { - return link.bookmarkGuid && - link.hasMetadata && - (!link.images || link.images.length === 0); - } - - /** - * getData - * - * @return Promise A promise that resolves with the "HIGHLIGHTS_RESPONSE" action - */ - getData() { - return Task.spawn(function*() { - if (!this.baselineRecommender) { - return Promise.reject(new Error("Tried to get weighted highlights but there was no baselineRecommender")); - } - - let links; - // Get links from places - links = yield PlacesProvider.links.getRecentlyVisited(); - - // Get metadata from PreviewProvider - links = yield this.options.getCachedMetadata(links, "HIGHLIGHTS_RESPONSE"); - - // Score the links - links = yield this.baselineRecommender.scoreEntries(links); - - this.missingData = false; - - // Get screenshots if we are missing images - links = links.slice(0, 18); - for (let link of links) { - if (this.shouldGetScreenshot(link)) { - const screenshot = this.getScreenshot(link.url, this.store); - if (screenshot) { - link.screenshot = screenshot; - link.metadata_source = `${link.metadata_source}+Screenshot`; - } else { - this.missingData = true; - } - } - if (!link.hasMetadata) { - this.missingData = true; - } - } - - return am.actions.Response("HIGHLIGHTS_RESPONSE", links); - }.bind(this)); - } - onAction(state, action) { - // Ignore any actions that come in before APP_INIT. We aren't ready. - if (!this.baselineRecommender && action.type !== am.type("APP_INIT")) { - return; - } - - switch (action.type) { - case am.type("APP_INIT"): - // When the app inititalizes, create a recommender, and then refresh the data. - this.initializeRecommender("app was initializing"); - break; - case am.type("RECEIVE_BOOKMARK_ADDED"): - // We always want new bookmarks - this.refresh("a bookmark was added"); - break; - case am.type("SCREENSHOT_UPDATED"): - if (this.missingData) { - this.refresh("new screenshot is available and we're missing data"); - } - break; - case am.type("METADATA_UPDATED"): - if (this.missingData) { - this.refresh("new metadata is available and we're missing data"); - } else if (state.Highlights.rows.length < (HIGHLIGHTS_LENGTH + TOP_SITES_DEFAULT_LENGTH)) { - // If the user visits a site and we don't have enough weighted highlights yet, refresh the data. - this.refresh("new metadata is available and there were not enough sites"); - } else if (Date.now() - this.state.lastUpdated >= UPDATE_TIME) { - // If the user visits a site & the last time we refreshed the data was older than 15 minutes, refresh the data. - this.refresh("new metadata is available and the sites were too old"); - } - break; - case am.type("PREF_CHANGED_RESPONSE"): - // If the weightedHighlightsCoefficients pref was changed and we have a recommender, we reinitialize it. - if (action.data.name === "weightedHighlightsCoefficients" && this.baselineRecommender) { - this.initializeRecommender("coefficients were changed"); - } - break; - case am.type("SYNC_COMPLETE"): - // We always want new synced tabs. - this.refresh("new tabs synced"); - break; - case am.type("MANY_LINKS_CHANGED"): - // manyLinksChanged is an event fired by Places when all history is cleared, - // or when frecency of links change due to something like a sync - this.refresh("frecency of many links changed"); - break; - } - } -}; - -module.exports.UPDATE_TIME = UPDATE_TIME; diff --git a/addon/Feeds/MetadataFeed.js b/addon/Feeds/MetadataFeed.js index c0ed76c099..4c559e2809 100644 --- a/addon/Feeds/MetadataFeed.js +++ b/addon/Feeds/MetadataFeed.js @@ -3,6 +3,7 @@ const {Cu} = require("chrome"); const {PlacesProvider} = require("addon/PlacesProvider"); const Feed = require("addon/lib/Feed"); const am = require("common/action-manager"); +const {VISITAGAIN_LENGTH} = require("common/constants"); const MAX_NUM_LINKS = 5; const UPDATE_TIME = 24 * 60 * 60 * 1000; // Update once per day @@ -44,13 +45,10 @@ module.exports = class MetadataFeed extends Feed { links.forEach(link => this.urlsToFetch.push(link.url)); this.refresh(reason); }) - // Finally, get initial highlights metadata. This should be done last because - // it takes the longest, processing 100+ urls. - .then(() => PlacesProvider.links.getRecentlyVisited()) + // Finally, get initial visit again metadata. + .then(() => PlacesProvider.links.getRecentlyVisited({limit: VISITAGAIN_LENGTH})) .then(links => { - // We need to cap this otherwise on some average profile we'll attempt to - // fetch hundreds of links and hog the mainthread for a long time - links.slice(0, 50).forEach(link => this.urlsToFetch.push(link.url)); + links.forEach(link => this.urlsToFetch.push(link.url)); this.refresh(reason); }); } diff --git a/addon/Feeds/VisitAgainFeed.js b/addon/Feeds/VisitAgainFeed.js new file mode 100644 index 0000000000..47bcdcd255 --- /dev/null +++ b/addon/Feeds/VisitAgainFeed.js @@ -0,0 +1,101 @@ +const {Cu} = require("chrome"); +const {PlacesProvider} = require("addon/PlacesProvider"); +const Feed = require("addon/lib/Feed"); +const am = require("common/action-manager"); +const getScreenshot = require("addon/lib/getScreenshot"); +const {dedupeOne} = require("common/selectors/selectAndDedupe"); +const {VISITAGAIN_LENGTH} = require("common/constants"); + +Cu.import("resource://gre/modules/Task.jsm"); + +const UPDATE_TIME = 15 * 60 * 1000; // 15 minutes + +module.exports = class VisitAgainFeed extends Feed { + constructor(options) { + super(options); + this.getScreenshot = getScreenshot; + this.missingData = false; + } + + /** + * shouldGetScreenshot - Returns true if the link/site provided meets the following: + * - has metadata + * - doesn't have any images + * + * @return bool + */ + shouldGetScreenshot(link) { + return link.hasMetadata && (!link.images || link.images.length === 0); + } + + /** + * getData + * + * @return Promise A promise that resolves with the "VISITAGAIN_RESPONSE" action + */ + getData() { + return Task.spawn(function*() { + let links; + // Get links from places + links = yield PlacesProvider.links.getRecentlyVisited({limit: VISITAGAIN_LENGTH}); + + // Get metadata from PreviewProvider + links = yield this.options.getCachedMetadata(links, "VISITAGAIN_RESPONSE"); + + this.missingData = false; + + // Get screenshots if we are missing images + for (let link of links) { + if (this.shouldGetScreenshot(link)) { + const screenshot = this.getScreenshot(link.url, this.store); + if (screenshot) { + link.screenshot = screenshot; + link.metadata_source = `${link.metadata_source}+Screenshot`; + } else { + this.missingData = true; + } + } + if (!link.hasMetadata) { + this.missingData = true; + } + } + + links = dedupeOne(links.filter(s => s.hasMetadata && s.images && s.images.length)); + + return am.actions.Response("VISITAGAIN_RESPONSE", links); + }.bind(this)); + } + + onAction(state, action) { + switch (action.type) { + case am.type("APP_INIT"): + // When the app inititalizes refresh the data. TODO + this.refresh("app was initializing"); + break; + case am.type("SCREENSHOT_UPDATED"): + if (this.missingData) { + this.refresh("new screenshot is available and we're missing data"); + } + break; + case am.type("RECEIVE_PLACES_CHANGES"): + this.refresh("always need the newest sites"); + break; + case am.type("METADATA_UPDATED"): + if (this.missingData) { + this.refresh("new metadata is available and we're missing data"); + } + break; + case am.type("SYNC_COMPLETE"): + // We always want new synced tabs. + this.refresh("new tabs synced"); + break; + case am.type("MANY_LINKS_CHANGED"): + // manyLinksChanged is an event fired by Places when all history is cleared, + // or when frecency of links change due to something like a sync + this.refresh("frecency of many links changed"); + break; + } + } +}; + +module.exports.UPDATE_TIME = UPDATE_TIME; diff --git a/addon/Feeds/feeds.js b/addon/Feeds/feeds.js index f96b875919..7b63a67aaf 100644 --- a/addon/Feeds/feeds.js +++ b/addon/Feeds/feeds.js @@ -1,17 +1,16 @@ const TopSitesFeed = require("./TopSitesFeed"); const PocketStoriesFeed = require("./PocketStoriesFeed"); const PocketTopicsFeed = require("./PocketTopicsFeed"); -const HighlightsFeed = require("./HighlightsFeed"); const PlacesStatsFeed = require("./PlacesStatsFeed"); const SearchFeed = require("./SearchFeed"); const MetadataFeed = require("./MetadataFeed"); const LocalizationFeed = require("./LocalizationFeed"); const SystemTickFeed = require("./SystemTickFeed"); const BookmarksFeed = require("./BookmarksFeed"); +const VisitAgainFeed = require("./VisitAgainFeed"); module.exports = [ TopSitesFeed, - HighlightsFeed, SearchFeed, PocketStoriesFeed, PocketTopicsFeed, @@ -19,5 +18,6 @@ module.exports = [ MetadataFeed, LocalizationFeed, SystemTickFeed, - BookmarksFeed + BookmarksFeed, + VisitAgainFeed ]; diff --git a/addon/MetadataStore.js b/addon/MetadataStore.js index 148b8a0e3f..f2ab2e2890 100644 --- a/addon/MetadataStore.js +++ b/addon/MetadataStore.js @@ -164,7 +164,19 @@ MetadataStore.prototype = { } try { - this._conn = yield Sqlite.openConnection({path: this._path}); + let conn = yield Sqlite.openConnection({path: this._path}); + // Set up shutdown blocker for sqlite.jsm to ensure this connection gets closed properly + try { + Sqlite.shutdown.addBlocker("Activity Stream metadata store connection is closing", + Task.async(function*() { + yield conn.close(); + })); + } catch (ex) { + // It's too late to block shutdown, just close the connection. + yield conn.close(); + throw ex; + } + this._conn = conn; yield this._conn.execute("PRAGMA journal_mode = WAL;"); yield this._conn.execute("PRAGMA foreign_keys = ON;"); yield this._asyncCreateTableSchema(); diff --git a/addon/PageScraper.js b/addon/PageScraper.js index e6eae02342..577fc63cff 100644 --- a/addon/PageScraper.js +++ b/addon/PageScraper.js @@ -90,18 +90,27 @@ PageScraper.prototype = { /** * Make a network request for links that the MetadataFeed has requested metadata for. * Attempt to parse the html from that page and insert into the DB + * + * @param {Array} links Links that need metadata. + * {String} eventType Source event of request. + * {Bool} forceFetch Flag to avoid checking if metadata exists. Used for unvisited bookmarks. */ - asyncFetchLinks: Task.async(function*(links, eventType) { + asyncFetchLinks: Task.async(function*(links, eventType, forceFetch = false) { let savedUrlsCount = 0; for (let link of links) { const linkEvent = this._tabTracker.generateEvent({source: eventType}); this._tabTracker.handlePerformanceEvent(linkEvent, PERFORMANCE_EVENT_NAMES.local_fetch_event, 1); - let linkExists = yield this._previewProvider.asyncLinkExist(link.url); - if (linkExists) { - this._tabTracker.handlePerformanceEvent(linkEvent, PERFORMANCE_EVENT_NAMES.metadata_exists, 1); - continue; + + // When we are not certain if metadata exists. + if (!forceFetch) { + let linkExists = yield this._previewProvider.asyncLinkExist(link.url); + if (linkExists) { + this._tabTracker.handlePerformanceEvent(linkEvent, PERFORMANCE_EVENT_NAMES.metadata_exists, 1); + continue; + } } + let rawHTML; try { rawHTML = yield this._fetchContent(link.url); diff --git a/addon/PlacesProvider.js b/addon/PlacesProvider.js index bb377cc32d..036538f4e2 100644 --- a/addon/PlacesProvider.js +++ b/addon/PlacesProvider.js @@ -749,8 +749,8 @@ Links.prototype = { * * @returns {Promise} Returns a promise with the most recent bookmarks. */ - getBookmarks: Task.async(function*(options = {limit: 3}) { - let {limit} = options; + getBookmarks: Task.async(function*(options = {limit: 3, ageMin: 0}) { + let {limit, ageMin} = options; const columns = [ "bookmarkDateCreated", @@ -781,8 +781,10 @@ Links.prototype = { b.dateAdded / 1000 as bookmarkDateCreated FROM moz_bookmarks b, moz_places p WHERE type = :type + AND b.lastModified > ${ageMin} AND b.fk = p.id - AND p.last_visit_date IS NOT NULL + AND (SELECT guid FROM moz_bookmarks WHERE id = (SELECT parent FROM moz_bookmarks WHERE id = b.parent)) != "tags________" + AND url_hash NOT BETWEEN hash("place", "prefix_lo") AND hash("place", "prefix_hi") ORDER BY b.lastModified DESC LIMIT ${limit}`; @@ -791,6 +793,20 @@ Links.prototype = { return this._processLinks(links); }), + /** + * Get the timestamp/dateAdded of the oldest bookmark. + */ + getDefaultBookmarksAge: Task.async(function*() { + const columns = ["defaultBookmarksAge"]; + let sqlQuery = `SELECT dateAdded AS defaultBookmarksAge + FROM moz_bookmarks + ORDER BY dateAdded ASC + LIMIT 1`; + + const result = yield this.executePlacesQuery(sqlQuery, {columns}); + return result[0].defaultBookmarksAge; + }), + /** * Get all history items from the past 90 days. * Used to determine frequency of domain visits. diff --git a/addon/PreviewProvider.js b/addon/PreviewProvider.js index 95ef417212..e795637645 100644 --- a/addon/PreviewProvider.js +++ b/addon/PreviewProvider.js @@ -202,6 +202,7 @@ PreviewProvider.prototype = { cache_key: link.cache_key, lastVisitDate: link.lastVisitDate, bookmarkDateCreated: link.bookmarkDateCreated, + bookmarkLastModified: link.lastModified, bookmarkGuid: link.bookmarkGuid, hasMetadata: false }; @@ -349,7 +350,9 @@ PreviewProvider.prototype = { * Check if a single link exists in the metadata DB */ asyncLinkExist: Task.async(function*(url) { - let key = createCacheKey(url); + const sanitizedURLObject = this._sanitizeURL(url); + const sanitizedURL = sanitizedURLObject ? sanitizedURLObject.toString() : ""; + const key = createCacheKey(sanitizedURL); if (!key) { return false; } diff --git a/addon/TabTracker.js b/addon/TabTracker.js index d98b7957da..d460b4851c 100644 --- a/addon/TabTracker.js +++ b/addon/TabTracker.js @@ -20,7 +20,10 @@ const PERFORMANCE_NOTIF = "performance-event"; const PERF_LOG_COMPLETE_NOTIF = "performance-log-complete"; const UNDESIRED_NOTIF = "undesired-event"; const IMPRESSION_NOTIF = "impression-stats"; -const USER_PREFS = ["showSearch", "showTopSites", "showPocket", "showHighlights", "showBookmarks", "showMoreTopSites", "collapseHighlights", "collapseBookmarks"]; +const USER_PREFS = [ + "showSearch", "showTopSites", "showPocket", "showHighlights", "showBookmarks", "showMoreTopSites", + "collapseHighlights", "collapseBookmarks", "collapseVisitAgain", "showVisitAgain" +]; function TabTracker(options) { this._tabData = {}; @@ -36,9 +39,9 @@ TabTracker.prototype = { return this._tabData; }, - init(trackableURLs, experimentId, store) { + init(trackableURLs, experimentProvider, store) { + this._experimentProvider = experimentProvider; this._trackableURLs = trackableURLs; - this._experimentID = experimentId; this._store = store; this.enabled = simplePrefs.prefs[TELEMETRY_PREF]; @@ -98,8 +101,8 @@ TabTracker.prototype = { this._tabData.session_id = this._tabData.session_id || String(uuid()); payload.session_id = this._tabData.session_id; payload.user_prefs = this._getUserPreferences(); - if (this._experimentID) { - payload.experiment_id = this._experimentID; + if (this._experimentProvider.experimentId) { + payload.experiment_id = this._experimentProvider.experimentId; } }, @@ -111,15 +114,11 @@ TabTracker.prototype = { } }, - set experimentId(experimentId) { - this._experimentID = experimentId || null; - }, - isActivityStreamsURL(URL) { return this._trackableURLs.indexOf(URL) !== -1; }, - handleUserEvent(payload, experimentId) { + handleUserEvent(payload) { payload.action = "activity_stream_event"; payload.tab_id = tabs.activeTab.id; this._setCommonProperties(payload, tabs.activeTab.url); @@ -129,7 +128,7 @@ TabTracker.prototype = { } }, - handleUndesiredEvent(payload, experimentId) { + handleUndesiredEvent(payload) { payload.action = "activity_stream_masga_event"; payload.tab_id = tabs.activeTab.id; this._setCommonProperties(payload, tabs.activeTab.url); @@ -139,7 +138,7 @@ TabTracker.prototype = { Services.obs.notifyObservers(null, UNDESIRED_NOTIF, JSON.stringify(payload)); }, - handleImpressionStats(payload, experimentId) { + handleImpressionStats(payload) { payload.action = "activity_stream_impression"; this._setCommonProperties(payload, tabs.activeTab.url); Services.obs.notifyObservers(null, IMPRESSION_NOTIF, JSON.stringify(payload)); diff --git a/common/action-manager.js b/common/action-manager.js index b1d7bc5499..7b6811cf14 100644 --- a/common/action-manager.js +++ b/common/action-manager.js @@ -7,6 +7,8 @@ const am = new ActionManager([ "APP_UNLOAD", "BOOKMARKS_REQUEST", "BOOKMARKS_RESPONSE", + "VISITAGAIN_REQUEST", + "VISITAGAIN_RESPONSE", "EXPERIMENTS_RESPONSE", "HIGHLIGHTS_AWAITING_METADATA", "HIGHLIGHTS_LINKS_REQUEST", @@ -147,8 +149,8 @@ function NotifyUpdateSearchString(searchString) { return Notify("NOTIFY_UPDATE_SEARCH_STRING", {searchString}, {skipMasterStore: true}); } -function NotifyBookmarkAdd(url) { - return Notify("NOTIFY_BOOKMARK_ADD", url); +function NotifyBookmarkAdd(data) { + return Notify("NOTIFY_BOOKMARK_ADD", data); } function NotifyBookmarkDelete(bookmarkGuid) { diff --git a/common/constants.js b/common/constants.js index 96bbd1459b..5e856d2b72 100644 --- a/common/constants.js +++ b/common/constants.js @@ -18,14 +18,17 @@ module.exports = { // Number of "Read More" topics to display at the bottom of Pocket recommendations POCKET_TOPICS_LENGTH: 5, - // Number of large Highlight tiles in the new Highlights world, including - // all rows. - HIGHLIGHTS_LENGTH: 9, - // Number of items in the Bookmarks section. Request more than actually being displayed // in case the user will remove some of them we still have 3 items to display. - BOOKMARKS_LENGTH: 6, + BOOKMARKS_LENGTH: 12, BOOKMARKS_DISPLAYED_LENGTH: 3, + // Delay amount added to oldest bookmarkAdded timestamp, used to filter out default browser bookmarks. + BOOKMARKS_THRESHOLD: 3 * 1e6, // 3 seconds to microseconds. + + // Number of links requested from placesProvider. + VISITAGAIN_LENGTH: 24, + // Number of links actually displayed. + VISITAGAIN_DISPLAYED_LENGTH: 6, // How many items per query? LINKS_QUERY_LIMIT: 500, @@ -46,12 +49,12 @@ module.exports = { NEWTAB_PREFS_ENCODING: { "showSearch": 1 << 0, "showTopSites": 1 << 1, - "showHighlights": 1 << 2, "showMoreTopSites": 1 << 3, "showPocket": 1 << 4, - "collapseHighlights": 1 << 5, "collapseBookmarks": 1 << 6, - "showBookmarks": 1 << 7 + "showBookmarks": 1 << 7, + "showVisitAgain": 1 << 8, + "collapseVisitAgain": 1 << 9 }, // The minimum size to consider an icon high res diff --git a/common/event-constants.js b/common/event-constants.js index 5520005e93..c6316d1c2a 100644 --- a/common/event-constants.js +++ b/common/event-constants.js @@ -41,7 +41,8 @@ const constants = { "RECOMMENDED", "ACTIVITY_FEED", "NEW_TAB", - "BOOKMARKS" + "BOOKMARKS", + "VISITAGAIN" ]) }; diff --git a/common/recommender/Baseline.js b/common/recommender/Baseline.js deleted file mode 100644 index 6d166f5478..0000000000 --- a/common/recommender/Baseline.js +++ /dev/null @@ -1,330 +0,0 @@ -"use strict"; - -const {BOOKMARK_AGE_DIVIDEND} = require("common/constants"); -const getBestImage = require("../getBestImage"); - -const {Cu} = require("chrome"); -Cu.importGlobalProperties(["URL"]); - -/** - * Score function for URLs. - * See tests and `scoreEntry` comments for more insight into how the score is computed. - * - * @param {Array.} history - User history used to assign higher score to popular domains. - * @param {Object} options - settings for the scoring function. - */ -class Baseline { - constructor(history, options = {}) { - this.domainCounts = history.reduce(this.countDomainOccurrences, new Map()); - this.options = options; - // Features that are extracted from URLs and need normalization. - // Key 0 holds the min, key 1 holds max, using arrays for brevity. - this.normalizeFeatures = { - description: {min: 1, max: 0}, - pathLength: {min: 1, max: 0}, - image: {min: 1, max: 0} - }; - - // These are features used for adjusting the final score. - // Used by decay function to filter out features. - this.adjustmentFeatures = ["bookmarkAge", "imageCount", "age", "idf"]; - - if (!this.options.highlightsCoefficients) { - throw new Error("Coefficients not specified"); - } - } - - extractFeatures(entry) { - const urlObj = new URL(entry.url); - const host = urlObj.host; - // For empty profiles. - const occurrences = this.domainCounts.get(host) || 1; - const domainCountsSize = this.domainCounts.size || 1; - const tf = entry.visitCount || 1; - const idf = Math.log(1 + domainCountsSize / occurrences); - - const age = this.normalizeTimestamp(entry.lastVisitDate); - const imageCount = entry.images ? entry.images.length : 0; - const description = this.extractDescriptionLength(entry); - const pathLength = urlObj.pathname.split("/").filter(e => e.length).length; - const image = this.extractImage(entry.images); - const queryLength = urlObj.search.length; - - // For bookmarks, compute a positive age in milliseconds; otherwise default 0 - const bookmarkAge = entry.bookmarkDateCreated ? Math.max(1, Date.now() - entry.bookmarkDateCreated) : 0; - - const features = {age, tf, idf, imageCount, bookmarkAge, description, pathLength, queryLength, image}; - this.updateFeatureMinMax(features); - - return Object.assign({}, entry, {features, host}); - } - - // Adjust all values in the range [0, 1]. - normalize(features) { - return Object.keys(this.normalizeFeatures).reduce((acc, key) => { - const {min, max} = this.normalizeFeatures[key]; - if (max > min) { // No division by 0. - let delta = max - min; - acc[key] = (features[key] - min) / delta; - } - - return acc; - }, Object.assign({}, features)); - } - - scoreEntry(entry) { - entry.features = this.normalize(entry.features); - - // Initial score based on visits and number of occurrences of the domain. - const {tf, idf} = entry.features; - let score = this.decay(tf * idf, // Score - // Features: Age in hours, number of visits to url, how often you go to the domain, number of images, - // length of path, length of description, size of biggest image. - entry.features, - // Features weights: Positive values decrease the score proportional to a factor of feature * weight. - // Negative values increase score proportional to a factor of feature * weight. - this.options.highlightsCoefficients); - - score = this.adjustScore(score, entry.features); - - return Object.assign({}, entry, {score}); - } - - /** - * Extra penalty/reward we want to adjust the score by. - * - * @param {Number} score - initial value. - * @param {Object} features - associated features and their values. - */ - adjustScore(score, features) { - let newScore = score; - - newScore /= Math.pow(1 + features.age, 2); - - if (!features.imageCount || !features.image) { - newScore = 0; - } - - if (!features.description || !features.pathLength) { - newScore *= 0.2; - } - - // Boost boomarks even if they have low score or no images giving a - // just-bookmarked page a near-infinite boost - if (features.bookmarkAge) { - newScore += BOOKMARK_AGE_DIVIDEND / features.bookmarkAge; - } - - return newScore; - } - - extractDescriptionLength(entry) { - if (!entry.description || - entry.title === entry.description || - entry.url === entry.description) { - return 0; - } - - return entry.description.length; - } - - /** - * Update min and max values of the features that require normalization. - * - * @param {Object} newFeatures - features and associated values. - */ - updateFeatureMinMax(newFeatures) { - Object.keys(this.normalizeFeatures).forEach(key => { - this.normalizeFeatures[key].min = this.selectMinValue(this.normalizeFeatures[key].min, newFeatures[key]); - this.normalizeFeatures[key].max = this.selectMaxValue(this.normalizeFeatures[key].max, newFeatures[key]); - }); - } - - /** - * Guard against undefined values that cause Math.{min, max} to return NaN. - */ - selectMaxValue(oldv, newv) { - const value = Math.max(oldv, newv); - if (Number.isNaN(value)) { - return oldv; - } - - return value; - } - - selectMinValue(oldv, newv) { - const value = Math.min(oldv, newv); - if (Number.isNaN(value)) { - return oldv; - } - - return value; - } - - updateOptions(options) { - this.options = options; - } - - /** - * Scoring function for an array of URLs. - * - * @param {Array.} entries - * @returns {Array.} sorted and with the associated score value. - */ - score(entries) { - let results = entries.map(entry => this.extractFeatures(entry)) - .map(entry => this.scoreEntry(entry)) - .sort(this.sortDescByScore) - .filter(entry => entry.score > 0); - - // Decreases score for similar consecutive items and remove duplicates - results = this._adjustConsecutiveEntries(results); - let dedupedEntries = this._dedupeSites(results); - - // Sort again after adjusting score. - return dedupedEntries.sort(this.sortDescByScore); - } - - /** - * Reduce user history to a map of hosts and number of visits - * - * @param {Map.} result - Accumulator - * @param {Object} entry - * @returns {Map.} - */ - countDomainOccurrences(result, entry) { - let host = entry.reversedHost - .split("") - .reverse() - .join("") - .slice(1); // moc.buhtig. => github.com - result.set(host, entry.visitCount); - - return result; - } - - /** - * Return the size of the image. - * Assumes `getBestImage` returns the best image it has. - * @param {Array} images - * @returns {Number} - */ - extractImage(images) { - const image = getBestImage(images); - - // Sanity check: validate that an image exists and we have dimensions before trying to compute size. - if (!image || !image.width || !image.height) { - return 0; - } - - return Math.min(image.width * image.height, 1e5); - } - - /** - * @param {Number} value - * @returns {Number} - */ - normalizeTimestamp(value) { - if (!value) { - return 0; - } - - let r = (Date.now() - value) / (1e3 * 3600 * 24); - return parseFloat(r.toFixed(4)); - } - - /** - * @param {Number} value - initial score based on frequency. - * @param {Object} features - object of features and associated values for a URL. - * @param {Array.} coef - weights - * @returns {Number} - */ - decay(value, features, coef) { - // Get all available features, filter out the ones we don't use in - // computing initial score. - const featNames = Object.keys(features) - .filter(f => this.adjustmentFeatures.indexOf(f) === -1) - .sort(); - - if (featNames.length !== coef.length) { - throw new Error("Different number of features and weights"); - } - - // Multiply feature value by weight and sum up all results. - let exp = featNames.reduce((acc, name, i) => acc + features[name] * coef[i], 0); - - // Throw error instead of trying to fallback because results will be wrong. - if (Number.isNaN(exp)) { - throw new Error("Could not compute feature score"); - } - - return value * Math.pow(Math.E, -exp); - } - - sortDescByScore(a, b) { - return b.score - a.score; - } - - /** - * Determine if two entries are similar. Used to lower the score for similar consecutive items. - * - * @param {Object} prev - * @param {Object} curr - * @returns {boolean} - * @private - */ - _similarItems(prev, curr) { - const imgPrev = getBestImage(prev.images); - const imgCurr = getBestImage(curr.images); - const hasImage = imgPrev && imgCurr; - return prev.host === curr.host || (hasImage && imgPrev.url === imgCurr.url); - } - - /** - * Decrease the score for consecutive items which are similar (see `_similarItems`). - * Combined with sorting by score the result is we don't see similar consecutive - * items. - * - * @param {Array} entries - scored and sorted highlight items. - */ - _adjustConsecutiveEntries(entries) { - let penalty = 0.8; - - if (entries.length < 2) { - return entries; - } - - entries.reduce((prev, curr) => { - if (this._similarItems(prev, curr)) { - curr.score *= penalty; - penalty -= 0.2; - } else { - penalty = 0.8; - } - - return curr; - }); - - return entries; - } - - _dedupeSites(entries) { - let dedupedEntries = new Map(); - entries.forEach(item => { - let key = this._createDedupeKey(item); - if (!dedupedEntries.get(key)) { - dedupedEntries.set(key, [item]); - } - }); - - let results = []; - dedupedEntries.forEach(item => results.push(item[0])); - return results; - } - - _createDedupeKey(entry) { - return entry.host; - } -} - -exports.Baseline = Baseline; diff --git a/common/recommender/Recommender.js b/common/recommender/Recommender.js deleted file mode 100644 index 490d9bee68..0000000000 --- a/common/recommender/Recommender.js +++ /dev/null @@ -1,21 +0,0 @@ -"use strict"; - -const {Baseline} = require("./Baseline"); - -class Recommender { - constructor(history, options = {}) { - // XXX Based on currently running experiments this could include - // a mechanism of choosing different recommendation systems. - this.recommender = new Baseline(history, options); - } - - scoreEntries(entries) { - return this.recommender.score(entries); - } - - updateOptions(options) { - this.recommender.updateOptions(options); - } -} - -exports.Recommender = Recommender; diff --git a/common/reducers/reducers.js b/common/reducers/reducers.js index f174db1ab8..03de2671ca 100644 --- a/common/reducers/reducers.js +++ b/common/reducers/reducers.js @@ -11,6 +11,7 @@ module.exports = { TopSites: setRowsOrError("TOP_FRECENT_SITES_REQUEST", "TOP_FRECENT_SITES_RESPONSE"), Highlights: setRowsOrError("HIGHLIGHTS_REQUEST", "HIGHLIGHTS_RESPONSE"), Bookmarks: setRowsOrError("BOOKMARKS_REQUEST", "BOOKMARKS_RESPONSE"), + VisitAgain: setRowsOrError("VISITAGAIN_REQUEST", "VISITAGAIN_RESPONSE"), PocketStories: setRowsOrError("POCKET_STORIES_REQUEST", "POCKET_STORIES_RESPONSE"), PocketTopics: setRowsOrError("POCKET_TOPICS_REQUEST", "POCKET_TOPICS_RESPONSE"), Search: setSearchContent("SEARCH_STATE_UPDATED", "SEARCH_SUGGESTIONS_RESPONSE", "SEARCH_CYCLE_CURRENT_ENGINE_RESPONSE"), diff --git a/common/selectors/getHighlightContextFromSite.js b/common/selectors/getHighlightContextFromSite.js index 61b7f6a07c..263c31de5e 100644 --- a/common/selectors/getHighlightContextFromSite.js +++ b/common/selectors/getHighlightContextFromSite.js @@ -14,10 +14,9 @@ module.exports = function getHighlightContextFromSite(site) { if (site.context_message) { result.label = site.context_message; } - - if (site.bookmarkDateCreated) { + if (site.bookmarkLastModified || site.bookmarkDateCreated) { result.type = "bookmark"; - result.date = site.bookmarkDateCreated; + result.date = site.bookmarkLastModified || site.bookmarkDateCreated; // syncedFrom and isOpen are not currently implemented, but they // will be added in the future } else if (site.syncedFrom) { diff --git a/common/selectors/selectAndDedupe.js b/common/selectors/selectAndDedupe.js index e7f1fd0507..3736a8cd58 100644 --- a/common/selectors/selectAndDedupe.js +++ b/common/selectors/selectAndDedupe.js @@ -1,8 +1,5 @@ -const dedupe = require("fancy-dedupe"); - -// NOTE: The Math.random() fallback is because there can be empty slots thanks to pinning -// with a limited history. -dedupe.defaults.createKey = site => (site ? site.cache_key || site.hostname || site.url : Math.random()); +const vendor = require("common/vendor"); +const dedupe = vendor("fancy-dedupe"); /** * Dedupe items and appends defaults if result length is smaller than required. @@ -13,11 +10,15 @@ dedupe.defaults.createKey = site => (site ? site.cache_key || site.hostname || s * @param {Array} group.defaults - default values to use. * @returns {Array} */ -module.exports = function selectAndDedupe(group) { +module.exports.selectAndDedupe = function selectAndDedupe(group) { return group.reduce((result, options, index, arr) => { let current; let sites = options.sites; + // NOTE: The Math.random() fallback is because there can be empty slots thanks to pinning + // with a limited history. + dedupe.defaults.createKey = site => (site ? site.cache_key || site.hostname || site.url : Math.random()); + if (options.defaults) { // Dedupe the defaults first. let defaults = dedupe.group([sites, options.defaults])[1]; @@ -44,3 +45,15 @@ module.exports = function selectAndDedupe(group) { return result; }, []); }; + +/** + * Dedupe websites based on hostname. + * + * @param {Array} list + * @returns {Array} + */ +module.exports.dedupeOne = list => { + dedupe.defaults.createKey = site => (site ? site.hostname : Math.random()); + + return dedupe.one(list); +}; diff --git a/common/selectors/selectorUtils.js b/common/selectors/selectorUtils.js index b92d4ff2c0..d0185be6de 100644 --- a/common/selectors/selectorUtils.js +++ b/common/selectors/selectorUtils.js @@ -5,6 +5,6 @@ * @return {Boolean} */ function areSelectorsReady(state) { - return state.TopSites.init && state.Highlights.init && state.Experiments.init; + return state.TopSites.init && state.Experiments.init; } module.exports = {areSelectorsReady}; diff --git a/common/selectors/selectors.js b/common/selectors/selectors.js index 0daef6632b..6b3a04f140 100644 --- a/common/selectors/selectors.js +++ b/common/selectors/selectors.js @@ -1,8 +1,7 @@ const {createSelector} = require("common/vendor")("reselect"); const firstRunData = require("lib/first-run-data"); -const selectAndDedupe = require("./selectAndDedupe"); -const {assignImageAndBackgroundColor} = require("./colorSelectors"); -const {TOP_SITES_DEFAULT_LENGTH, TOP_SITES_SHOWMORE_LENGTH, HIGHLIGHTS_LENGTH} = require("common/constants"); +const {selectAndDedupe} = require("./selectAndDedupe"); +const {TOP_SITES_DEFAULT_LENGTH, TOP_SITES_SHOWMORE_LENGTH} = require("common/constants"); const {areSelectorsReady} = require("./selectorUtils"); /** @@ -20,36 +19,32 @@ module.exports.justDispatch = (() => ({})); */ module.exports.selectNewTabSites = createSelector( [ - state => state.Highlights, state => state.PocketStories, state => state.PocketTopics, state => state.TopSites, state => state.Experiments, state => state.Prefs, state => state.Bookmarks, + state => state.VisitAgain, state => state ], - (Highlights, PocketStories, PocketTopics, TopSites, Experiments, Prefs, Bookmarks, state) => { // eslint-disable-line max-params - const [topSitesRows, highlightsRows] = selectAndDedupe([ + (PocketStories, PocketTopics, TopSites, Experiments, Prefs, Bookmarks, VisitAgain, state) => { // eslint-disable-line max-params + const [topSitesRows] = selectAndDedupe([ { sites: TopSites.rows, max: Prefs.prefs.showMoreTopSites ? TOP_SITES_SHOWMORE_LENGTH : TOP_SITES_DEFAULT_LENGTH, defaults: firstRunData.TopSites - }, - { - sites: assignImageAndBackgroundColor(Highlights.rows), - max: HIGHLIGHTS_LENGTH } ]); return { TopSites: Object.assign({}, TopSites, {rows: topSitesRows}), PocketStories: Object.assign({}, PocketStories), PocketTopics: Object.assign({}, PocketTopics), - Highlights: Object.assign({}, Highlights, {rows: highlightsRows}), Experiments, Prefs, Bookmarks: Object.assign({}, Bookmarks, {rows: Bookmarks.rows}), + VisitAgain, isReady: areSelectorsReady(state) }; } diff --git a/common/vendor-src.js b/common/vendor-src.js index e82caf5247..b3a575adb8 100644 --- a/common/vendor-src.js +++ b/common/vendor-src.js @@ -15,7 +15,8 @@ if (typeof platform_require !== "undefined") { const vendorModules = { "redux": require("redux"), "redux-thunk": require("redux-thunk"), - "reselect": require("reselect") + "reselect": require("reselect"), + "fancy-dedupe": require("fancy-dedupe") }; // Addon-only modules. Also needed for tests diff --git a/content-src/.eslintrc.js b/content-src/.eslintrc.js new file mode 100644 index 0000000000..5c85ef7feb --- /dev/null +++ b/content-src/.eslintrc.js @@ -0,0 +1,5 @@ +module.exports = { + "rules": { + "react/jsx-no-bind": 0 + } +}; diff --git a/content-src/components/Bookmarks/Bookmarks.js b/content-src/components/Bookmarks/Bookmarks.js index 268ad419ea..0c0ac6ce1d 100644 --- a/content-src/components/Bookmarks/Bookmarks.js +++ b/content-src/components/Bookmarks/Bookmarks.js @@ -45,7 +45,7 @@ const Bookmarks = React.createClass({ return sites.map((site, i) => -

- {this.renderIcon()} - +

+ + {this.renderIcon()} + +

{this.props.children} diff --git a/content-src/components/CollapsibleSection/CollapsibleSection.scss b/content-src/components/CollapsibleSection/CollapsibleSection.scss index e3c2bcb43a..8f9a221bf8 100644 --- a/content-src/components/CollapsibleSection/CollapsibleSection.scss +++ b/content-src/components/CollapsibleSection/CollapsibleSection.scss @@ -1,12 +1,19 @@ .collapsible-section { .section-title { - cursor: pointer; + + .click-target { + cursor: pointer; + } .icon { - margin: -5px 0 0 8px; + margin: -5px 0 0; + + &.icon-arrowhead-down { + margin-left: 8px; + } &.icon-arrowhead-forward { - margin-top: -4px; + margin: -4px 0 0 8px; } } } @@ -17,6 +24,10 @@ max-height: 500px; transition: max-height 0.5s cubic-bezier(0.07, 0.95, 0, 1); + // This is so the top sites favicon doesn't get clipped during animation: + margin-inline-start: -7px; + padding: 0 7px; + &.animating { overflow: hidden; } diff --git a/content-src/components/LinkMenu/LinkMenu.js b/content-src/components/LinkMenu/LinkMenu.js index 46a9a966d1..5149e69870 100644 --- a/content-src/components/LinkMenu/LinkMenu.js +++ b/content-src/components/LinkMenu/LinkMenu.js @@ -96,7 +96,7 @@ const LinkMenu = React.createClass({ label: this.props.intl.formatMessage({id: "menu_action_bookmark"}), icon: "bookmark", userEvent: "BOOKMARK_ADD", - onClick: () => dispatch(actions.NotifyBookmarkAdd(site.url)) + onClick: () => dispatch(actions.NotifyBookmarkAdd({url: site.url, source: this.props.source})) }), {type: "separator"}, { diff --git a/content-src/components/NewTabPage/NewTabPage.js b/content-src/components/NewTabPage/NewTabPage.js index 426db67fbd..bbd7afbb6e 100644 --- a/content-src/components/NewTabPage/NewTabPage.js +++ b/content-src/components/NewTabPage/NewTabPage.js @@ -3,7 +3,7 @@ const {connect} = require("react-redux"); const {selectNewTabSites} = require("common/selectors/selectors"); const TopSites = require("components/TopSites/TopSites"); const Bookmarks = require("components/Bookmarks/Bookmarks"); -const Spotlight = require("components/Spotlight/Spotlight"); +const VisitAgain = require("components/VisitAgain/VisitAgain"); const PocketStories = require("components/PocketStories/PocketStories"); const Search = require("components/Search/Search"); const Loader = require("components/Loader/Loader"); @@ -12,12 +12,11 @@ const {actions} = require("common/action-manager"); const setFavicon = require("lib/set-favicon"); const PAGE_NAME = "NEW_TAB"; const { - HIGHLIGHTS_LENGTH, TOP_SITES_DEFAULT_LENGTH, + TOP_SITES_DEFAULT_LENGTH, TOP_SITES_SHOWMORE_LENGTH, POCKET_STORIES_LENGTH, - BOOKMARKS_DISPLAYED_LENGTH + BOOKMARKS_DISPLAYED_LENGTH, VISITAGAIN_DISPLAYED_LENGTH } = require("common/constants"); const {injectIntl} = require("react-intl"); -const classNames = require("classnames"); const NewTabPage = React.createClass({ getInitialState() { @@ -25,17 +24,13 @@ const NewTabPage = React.createClass({ }, _getNewTabStats() { let stats = { - highlightsSize: 0, topsitesSize: 0, topsitesTippytop: 0, topsitesScreenshot: 0, topsitesLowResIcon: 0 }; if (this.props.isReady) { - const {showTopSites, showHighlights} = this.props.Prefs.prefs; - if (showHighlights) { - stats.highlightsSize = this.props.Highlights.rows.length; - } + const {showTopSites} = this.props.Prefs.prefs; if (showTopSites) { const topSites = this.props.TopSites.rows; stats.topsitesSize = topSites.length; @@ -86,10 +81,10 @@ const NewTabPage = React.createClass({ }, render() { const props = this.props; - const {showSearch, showTopSites, showPocket, showHighlights, showBookmarks, showMoreTopSites} = props.Prefs.prefs; + const {showSearch, showTopSites, showPocket, showBookmarks, showVisitAgain, showMoreTopSites} = props.Prefs.prefs; return (
-
+
{showSearch &&
@@ -114,16 +109,16 @@ const NewTabPage = React.createClass({ length={POCKET_STORIES_LENGTH} stories={props.PocketStories.rows} topics={props.PocketTopics.rows} prefs={props.Prefs.prefs} /> } - {showHighlights && - - } {showBookmarks && } + {showVisitAgain && + + }
@@ -134,7 +129,6 @@ const NewTabPage = React.createClass({ NewTabPage.propTypes = { TopSites: React.PropTypes.object.isRequired, PocketStories: React.PropTypes.object.isRequired, - Highlights: React.PropTypes.object.isRequired, Bookmarks: React.PropTypes.object.isRequired, Experiments: React.PropTypes.object.isRequired, Prefs: React.PropTypes.object.isRequired, diff --git a/content-src/components/NewTabPage/NewTabPage.scss b/content-src/components/NewTabPage/NewTabPage.scss index 76263decb1..ae80f9fff3 100644 --- a/content-src/components/NewTabPage/NewTabPage.scss +++ b/content-src/components/NewTabPage/NewTabPage.scss @@ -3,12 +3,6 @@ max-width: $wrapper-max-width; margin: auto; padding: $wrapper-vertical-padding 0; - - &.show-highlights { - // if we are showing highlights, we want to stay top aligned to avoid everything - // jumping up and down when changing between collapsed/uncollapsed - margin-top: 0; - } } @keyframes fadeIn { diff --git a/content-src/components/PocketStories/PocketStories.js b/content-src/components/PocketStories/PocketStories.js index 72228c2e7f..daf7648f3e 100644 --- a/content-src/components/PocketStories/PocketStories.js +++ b/content-src/components/PocketStories/PocketStories.js @@ -53,7 +53,7 @@ const PocketStories = React.createClass({ return stories.map((story, i) => @@ -48,56 +48,58 @@ const PreferencesPane = React.createClass({
-
-

-

-
- - -

-
-
- - -

-
- -
-
- - -

-
-
- - -

-
-
- - -

+

+
+
+ + +

+
+ + +
+
+
+ + +

+
+
+ + +

+
+
+ + +

+
+
+
+
-
- -
); diff --git a/content-src/components/PreferencesPane/PreferencesPane.scss b/content-src/components/PreferencesPane/PreferencesPane.scss index 86ee871a6e..0874f38e3f 100644 --- a/content-src/components/PreferencesPane/PreferencesPane.scss +++ b/content-src/components/PreferencesPane/PreferencesPane.scss @@ -5,9 +5,10 @@ background: $white; border-left: solid 1px $faintest-black; box-shadow: $sidebar-shadow; - min-height: 100%; + height: 100%; offset-inline-end: 0; - padding: 40px; + overflow: hidden; + padding: 40px 40px 70px; position: fixed; top: 0; transition: 0.1s cubic-bezier(0, 0, 0, 1); @@ -28,6 +29,9 @@ } .prefs-modal-inner-wrapper { + height: 100%; + overflow-y: auto; + section { margin: 20px 0; @@ -82,8 +86,19 @@ } } + .sidebar-inner-wrapper { + height: 100%; + position: relative; + width: 100%; + } + .actions { + background: $white; + bottom: -70px; padding: 15px 0; + position: absolute; + right: 0; + width: 100%; } // CSS styled checkbox diff --git a/content-src/components/Spotlight/Spotlight.js b/content-src/components/Spotlight/Spotlight.js index 8c0ec2f1bc..ea1713b2f1 100644 --- a/content-src/components/Spotlight/Spotlight.js +++ b/content-src/components/Spotlight/Spotlight.js @@ -1,10 +1,7 @@ const React = require("react"); -const {connect} = require("react-redux"); -const {justDispatch} = require("common/selectors/selectors"); const getHighlightContextFromSite = require("common/selectors/getHighlightContextFromSite"); const {prettyUrl} = require("lib/utils"); const {actions} = require("common/action-manager"); -const CollapsibleSection = require("components/CollapsibleSection/CollapsibleSection"); const LinkMenu = require("components/LinkMenu/LinkMenu"); const LinkMenuButton = require("components/LinkMenuButton/LinkMenuButton"); const {HighlightContext, PlaceholderHighlightContext} = require("components/HighlightContext/HighlightContext"); @@ -117,64 +114,6 @@ function renderPlaceholderList() { return placeholders; } -const Spotlight = React.createClass({ - getDefaultProps() { - return { - length: 3, - page: "NEW_TAB", - placeholder: false, - prefs: {} - }; - }, - onClickFactory(index, site) { - return () => { - let payload = { - event: "CLICK", - page: this.props.page, - source: "FEATURED", - action_position: index, - highlight_type: site.type, - metadata_source: site.metadata_source - }; - this.props.dispatch(actions.NotifyEvent(payload)); - }; - }, - // XXX factor out into a stateless component - renderSiteList() { - const sites = this.props.sites.slice(0, this.props.length); - - return sites.map((site, i) => - - ); - }, - render() { - return ( - -
    - {this.props.placeholder ? renderPlaceholderList() : this.renderSiteList()} -
-
- ); - } -}); - -Spotlight.propTypes = { - page: React.PropTypes.string.isRequired, - sites: React.PropTypes.array.isRequired, - length: React.PropTypes.number, - prefs: React.PropTypes.object -}; - -module.exports = connect(justDispatch)(Spotlight); -module.exports.Spotlight = Spotlight; module.exports.SpotlightItem = SpotlightItem; module.exports.PlaceholderSpotlightItem = PlaceholderSpotlightItem; module.exports.renderPlaceholderList = renderPlaceholderList; diff --git a/content-src/components/Spotlight/Spotlight.scss b/content-src/components/Spotlight/Spotlight.scss index 1e95a9d56c..94e99a3c59 100644 --- a/content-src/components/Spotlight/Spotlight.scss +++ b/content-src/components/Spotlight/Spotlight.scss @@ -23,6 +23,8 @@ &.collapsible-section { .section-body { max-height: 975px; + margin-inline-start: 0; + padding: 0; } } } diff --git a/content-src/components/TopSites/TopSites.js b/content-src/components/TopSites/TopSites.js index c2d6567102..52ce466c1d 100644 --- a/content-src/components/TopSites/TopSites.js +++ b/content-src/components/TopSites/TopSites.js @@ -614,7 +614,7 @@ const TopSiteForm = React.createClass({ "((\\d{1,3}\\.){3}\\d{1,3}))" + // OR ip (v4) address "(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*" + // port and path "(\\?[;&a-z\\d%_.~+=-]*)?" + // query string - "(\\#[-a-z\\d_]*)?$", "i"); // fragment locater + "(\\#[\\/-a-z\\d_]*)?$", "i"); // fragment locater return pattern.test(this.state.url); }, validateForm() { diff --git a/content-src/components/VisitAgain/VisitAgain.js b/content-src/components/VisitAgain/VisitAgain.js new file mode 100644 index 0000000000..da7dbad335 --- /dev/null +++ b/content-src/components/VisitAgain/VisitAgain.js @@ -0,0 +1,71 @@ +const React = require("react"); +const {connect} = require("react-redux"); +const {justDispatch} = require("common/selectors/selectors"); +const {actions} = require("common/action-manager"); +const {SpotlightItem} = require("components/Spotlight/Spotlight"); +const CollapsibleSection = require("components/CollapsibleSection/CollapsibleSection"); +const getBestImage = require("common/getBestImage"); +const {VISITAGAIN_DISPLAYED_LENGTH} = require("common/constants"); + +const VisitAgain = React.createClass({ + getDefaultProps() { + return { + length: VISITAGAIN_DISPLAYED_LENGTH, + page: "NEW_TAB", + placeholder: false + }; + }, + onClickFactory(index, site) { + return () => { + let payload = { + event: "CLICK", + page: this.props.page, + source: "VISITAGAIN", + action_position: index, + highlight_type: site.type, + metadata_source: site.metadata_source + }; + this.props.dispatch(actions.NotifyEvent(payload)); + }; + }, + renderSiteList() { + const sites = this.props.sites.slice(0, this.props.length); + + return sites.map((site, i) => + + ); + }, + render() { + const shouldRender = !this.props.placeholder && (this.props.sites.length !== 0); + + if (!shouldRender) { + return null; + } + + return ( +
    + {this.renderSiteList()} +
+
); + } +}); + +VisitAgain.propTypes = { + page: React.PropTypes.string.isRequired, + sites: React.PropTypes.array.isRequired, + length: React.PropTypes.number, + prefs: React.PropTypes.object +}; + +module.exports = connect(justDispatch)(VisitAgain); +module.exports.VisitAgain = VisitAgain; diff --git a/content-src/lib/fake-data.js b/content-src/lib/fake-data.js index 0cf41c1703..8ab05f7842 100644 --- a/content-src/lib/fake-data.js +++ b/content-src/lib/fake-data.js @@ -1,14 +1,17 @@ -const {HIGHLIGHTS_LENGTH, POCKET_STORIES_LENGTH, POCKET_TOPICS_LENGTH, DEFAULT_LOCALE} = require("common/constants"); +const { + BOOKMARKS_LENGTH, POCKET_STORIES_LENGTH, + POCKET_TOPICS_LENGTH, DEFAULT_LOCALE, VISITAGAIN_LENGTH +} = require("common/constants"); const faker = require("test/faker"); const STRINGS = require("../../data/locales/locales.json")[DEFAULT_LOCALE]; module.exports = { - "Highlights": { - "rows": faker.createRows({images: HIGHLIGHTS_LENGTH}), + "VisitAgain": { + "rows": faker.createRows({images: VISITAGAIN_LENGTH}), "error": false }, "Bookmarks": { - "rows": faker.createRows({images: HIGHLIGHTS_LENGTH, type: "bookmark"}), + "rows": faker.createRows({images: BOOKMARKS_LENGTH, type: "bookmark"}), "error": false }, "PocketStories": { @@ -47,8 +50,8 @@ module.exports = { "prefs": { "showSearch": true, "showTopSites": true, - "showHighlights": true, "showBookmarks": true, + "showVisitAgain": true, "showPocket": true }, "error": false diff --git a/content-src/static/img/glyph-history-16.svg b/content-src/static/img/glyph-history-16.svg new file mode 100644 index 0000000000..302021eeaf --- /dev/null +++ b/content-src/static/img/glyph-history-16.svg @@ -0,0 +1,6 @@ + + + + diff --git a/content-src/styles/icons.scss b/content-src/styles/icons.scss index 8f0f71e2ea..97529432da 100644 --- a/content-src/styles/icons.scss +++ b/content-src/styles/icons.scss @@ -63,6 +63,10 @@ background-image: url('#{$image-path}list-icon.svg'); } + &.icon-history { + background-image: url('#{$image-path}glyph-history-16.svg'); + } + &.icon-historyItem { background-image: url('#{$image-path}glyph-historyItem-16.svg'); } diff --git a/content-test/.eslintrc.js b/content-test/.eslintrc.js new file mode 100644 index 0000000000..5c85ef7feb --- /dev/null +++ b/content-test/.eslintrc.js @@ -0,0 +1,5 @@ +module.exports = { + "rules": { + "react/jsx-no-bind": 0 + } +}; diff --git a/content-test/addon/ExperimentProvider.test.js b/content-test/addon/ExperimentProvider.test.js index a039eb8cfd..7e18eabc7e 100644 --- a/content-test/addon/ExperimentProvider.test.js +++ b/content-test/addon/ExperimentProvider.test.js @@ -1,14 +1,13 @@ -const simplePrefs = require("sdk/simple-prefs"); const createExperimentProvider = require("inject!addon/ExperimentProvider"); const {PrefService} = require("shims/sdk/preferences/service"); const PrefsTarget = require("shims/sdk/preferences/event-target"); const {preferencesBranch} = require("sdk/self"); -const PREF_PREFIX = `extensions.${preferencesBranch}.experiments.`; const DEFAULT_OPTIONS = { clientID: "foo", experiments: { foo: { + slug: "foo", name: "Foo Test", active: true, description: "A test about foo", @@ -17,7 +16,7 @@ const DEFAULT_OPTIONS = { description: "Foo is 42 by default" }, variant: { - id: "foo_01", + id: "foo", value: true, threshold: 0.5, description: "Twice the foo" @@ -68,7 +67,7 @@ describe("ExperimentProvider", () => { }); it("should set .experimentId", () => { setup({n: 0.1}); - assert.equal(experimentProvider.experimentId, "foo_01", "should be foo_01 if in experiment"); + assert.equal(experimentProvider.experimentId, "foo", "should be foo if in experiment"); }); it("should set .data ", () => { setup({clientID: "baz", n: 0.6}); @@ -88,14 +87,14 @@ describe("ExperimentProvider", () => { active: true, description: "foo", control: {value: false, description: "foo"}, - variant: {id: "foo_01", value: true, threshold: 0.5, description: "foo"} + variant: {value: true, threshold: 0.5, description: "foo"} }, - bar: { + bar_01: { name: "bar", active: true, description: "bar", control: {value: false, description: "bar"}, - variant: {id: "bar_01", value: true, threshold: 0.6, description: "bar"} + variant: {value: true, threshold: 0.6, description: "bar"} } } }); @@ -110,31 +109,30 @@ describe("ExperimentProvider", () => { name: "kitty", active: true, control: {value: false}, - variant: {id: "kitty_01", threshold: 0.2, value: true} + variant: {threshold: 0.2, value: true} }, dachshund: { name: "dachshund", active: true, control: {value: false}, - variant: {id: "dachshund_01", threshold: 0.2, value: true} + variant: {threshold: 0.2, value: true} } }, n: randomNumber }); assert.isTrue(experimentProvider.data.dachshund, "dachshund should be selected"); assert.isFalse(experimentProvider.data.kitty, "kitty should not be selected"); - assert.equal(experimentProvider.experimentId, "dachshund_01", "the experimentId should be dachshund_01"); + assert.equal(experimentProvider.experimentId, "dachshund", "the experimentId should be dachshund"); }); it("should skip experiments with active:false", () => { setup({ clientID: "foo", experiments: { - foo: { + asdasd: { active: false, name: "foo", control: {value: "bloo"}, variant: { - id: "asdasd", threshold: 0.3, value: "blah" } @@ -149,277 +147,13 @@ describe("ExperimentProvider", () => { assert.equal(JSON.stringify(experimentProvider.data), JSON.stringify({foo: true})); }); - describe("overrides", () => { - it("should create new prefs for new experiments after override", () => { - let data = { - clientID: "foo", - experiments: { - kitty: { - name: "kitty", - active: true, - control: {value: false}, - variant: {id: "kitty_01", threshold: 0.2, value: true} - } - }, - n: 0.8 - }; - setup(data); - - prefService.set(`${PREF_PREFIX}foo`, true); - experimentProvider._onPrefChange(); - - experimentProvider.destroy(); - data.experiments.dachshund = { - name: "dachshund", - active: true, - control: {value: false}, - variant: {id: "dachshund_01", threshold: 0.2, value: true} - }; - data.n = 0.1; - - setup(data); - - assert.isFalse(experimentProvider.data.dachshund); - }); - it("should override experiments and not set an experimentId", () => { - setup({n: 0.2}); - assert.isTrue(experimentProvider.data.foo); - assert.equal(experimentProvider.experimentId, "foo_01"); - - prefService.set(`${PREF_PREFIX}foo`, false); - experimentProvider._onPrefChange(); - - assert.equal(experimentProvider.data.foo, DEFAULT_OPTIONS.experiments.foo.control.value); - assert.isNull(experimentProvider.experimentId); - }); - it("should turn on an experiment even if it is active: false", () => { - setup({n: 0.8}); - assert.isFalse(experimentProvider.data.foo); - assert.isNull(experimentProvider.experimentId); - - prefService.set(`${PREF_PREFIX}foo`, true); - experimentProvider._onPrefChange(); - - assert.equal(experimentProvider.data.foo, DEFAULT_OPTIONS.experiments.foo.variant.value); - assert.isNull(experimentProvider.experimentId); - }); - it["should enable a disabled experiment"] = assert => { - let data = { - clientID: "foo", - experiments: { - kitty: { - name: "kitty", - active: false, - control: {value: false}, - variant: {id: "kitty_01", threshold: 0.2, value: true} - } - }, - n: 0.1 - }; - setup(data); - assert.equal(experimentProvider.data.kitty, undefined); - assert.isNull(experimentProvider.experimentId); - - experimentProvider.destroy(); - data.experiments.kitty.active = true; - - setup(data); - - assert.isTrue(experimentProvider.data.kitty); - assert.equal(experimentProvider.experimentId, "kitty_01"); - }; - it("should override multiple experiments", () => { - setup({ - experiments: { - foo: { - name: "foo", - active: true, - description: "foo", - control: {value: false, description: "foo"}, - variant: {id: "foo_01", value: true, threshold: 0.2, description: "foo"} - }, - bar: { - name: "bar", - active: true, - description: "bar", - control: {value: false, description: "bar"}, - variant: {id: "bar_01", value: true, threshold: 0.2, description: "bar"} - } - }, - n: 0.4 - }); - assert.isFalse(experimentProvider.data.foo); - assert.isFalse(experimentProvider.data.bar); - - prefService.set(`${PREF_PREFIX}foo`, true); - prefService.set(`${PREF_PREFIX}bar`, true); - experimentProvider._onPrefChange(); - - assert.isTrue(experimentProvider.data.foo); - assert.isTrue(experimentProvider.data.bar); - assert.isNull(experimentProvider.experimentId); - }); - it("should add a pref listener on new, active experiments", () => { - setup({n: 0.3}); - assert.calledWith(experimentProvider._target.on, `${PREF_PREFIX}foo`); - }); - it("should remove the pref listener on experiment prefs and reset experimentId", () => { - setup({n: 0.1}); - experimentProvider.destroy(); - assert.calledWith(experimentProvider._target.off, `${PREF_PREFIX}foo`); - assert.isNull(experimentProvider.experimentId); - }); - it("should reset experiments on a pref change", () => { - setup({ - experiments: { - foo: { - name: "foo", - active: true, - description: "foo", - control: {value: false, description: "foo"}, - variant: {id: "foo_01", value: true, threshold: 0.2, description: "foo"} - } - }, - n: 0.3 - }); - assert.isFalse(experimentProvider.data.foo); - prefService.set(`${PREF_PREFIX}foo`, true); - experimentProvider._onPrefChange(); - assert.isTrue(experimentProvider.data.foo); - }); - it("should disable experiment with participating user", () => { - let data = { - clientID: "foo", - experiments: { - kitty: { - name: "kitty", - active: true, - control: {value: false}, - variant: {id: "kitty_01", threshold: 0.2, value: true} - } - }, - n: 0.1 - }; - setup(data); - assert.isTrue(experimentProvider.data.kitty); - assert.equal(experimentProvider.experimentId, "kitty_01"); - - experimentProvider.destroy(); - - assert.isTrue(experimentProvider.data.kitty); - assert.isNull(experimentProvider.experimentId); - - data.experiments.kitty.active = false; - setup(data); - - assert.isFalse(experimentProvider.data.kitty); - assert.isNull(experimentProvider.experimentId); - - // Reactivating an experiment that a user was in that became - // inactive should not re-consider that user. - data.experiments.kitty.active = true; - experimentProvider.destroy(); - setup(data); - - assert.isFalse(experimentProvider.data.kitty); - assert.isNull(experimentProvider.experimentId); - }); - it("should make new experiment available", () => { - let data = { - clientID: "foo", - experiments: { - kitty: { - name: "kitty", - active: true, - control: {value: false}, - variant: {id: "kitty_01", threshold: 0.2, value: true} - } - }, - n: 0.3 - }; - setup(data); - assert.isFalse(experimentProvider.data.kitty); - assert.isNull(experimentProvider.experimentId); - - experimentProvider.destroy(); - data.experiments.dachshund = { - name: "dachshund", - active: true, - control: {value: false}, - variant: {id: "dachshund_01", threshold: 0.2, value: true} - }; - data.n = 0.1; - - setup(data); - - // We weren't in the kitty experiment initally, so we will stay - // out of it even though our new random number would normally choose kitty. - assert.isFalse(experimentProvider.data.kitty); - assert.isTrue(experimentProvider.data.dachshund); - assert.equal(experimentProvider.experimentId, "dachshund_01"); - }); - it("should remain in override state after restart", () => { - setup({n: 0.8}); - assert.isFalse(experimentProvider.data.foo); - assert.isFalse(simplePrefs.prefs.experimentsOverridden); - - prefService.set(`${PREF_PREFIX}foo`, true); - experimentProvider._onPrefChange(); - - assert.isTrue(experimentProvider.data.foo); - assert.isTrue(simplePrefs.prefs.experimentsOverridden); - - experimentProvider.destroy(); - setup({n: 0.8}); - - assert.isTrue(experimentProvider.data.foo); - assert.isTrue(simplePrefs.prefs.experimentsOverridden); - }); - it("should disable all active experiments if pref says so", () => { - const data = { - clientID: "foo", - experiments: { - activeFoo: { - name: "Active Foo Test", - active: true, - control: {value: "control_val"}, - variant: {id: "foo_01", value: "variant_val", threshold: 0.5} - }, - notActiveFoo: { - name: "Not Active Foo Test", - active: false, - control: {value: false}, - variant: {id: "foo_02", value: true, threshold: 0.5} - } - } - }; - prefService.set(`extensions.${preferencesBranch}.activateExperiments`, false); - setup(data); - assert.equal(prefService.get(`${PREF_PREFIX}activeFoo`), data.experiments.activeFoo.control.value); - assert.equal(prefService.get(`${PREF_PREFIX}notActiveFoo`, undefined)); - }); - }); - describe("listeners", () => { - it("should emit a change event on a pref change", () => { - setup(); - experimentProvider._onPrefChange("foo"); - assert.calledWith(experimentProvider.emit, "change", "foo"); - }); it("should emit an event on experiment enrollment", () => { setup(); const experimentId = "foo"; - const variant = {description: "Twice the foo", id: "foo_01", threshold: 0.5, value: true}; + const variant = {description: "Twice the foo", id: "foo", threshold: 0.5, value: true}; experimentProvider.enroll(experimentId, variant); assert.calledWith(experimentProvider.emit, "experimentEnrolled", {id: experimentId, variant}); }); - it("should set showMoreTopSites pref on topSitesTwoRowsDefault experiment enrollment", () => { - setup(); - simplePrefs.prefs.showMoreTopSites = false; - const experimentId = "topSitesTwoRowsDefault"; - const variant = {description: "Show two rows of Top Sites by default", id: "exp-20-topsites-tworows", threshold: 0.2, value: true}; - experimentProvider.enroll(experimentId, variant); - assert.isTrue(simplePrefs.prefs.showMoreTopSites); - }); }); }); diff --git a/content-test/addon/Feeds/BookmarksFeed.test.js b/content-test/addon/Feeds/BookmarksFeed.test.js new file mode 100644 index 0000000000..b79be02078 --- /dev/null +++ b/content-test/addon/Feeds/BookmarksFeed.test.js @@ -0,0 +1,197 @@ +const {BOOKMARKS_LENGTH, BOOKMARKS_THRESHOLD} = require("common/constants"); +const moment = require("moment"); +const testLinks = [{url: "foo.com", hostname: "foo.com"}, + {url: "bar.com", hostname: "bar.com"}]; +const getCachedMetadata = links => links.map( + link => { + link.title = link.url; + return link; + } +); +const PlacesProvider = { + links: { + getBookmarks: sinon.spy(() => Promise.resolve(testLinks)), + getDefaultBookmarksAge: sinon.spy(() => Promise.resolve(50)) + } +}; +const testScreenshot = "screenshot.jpg"; + +const createStoreWithState = state => ({ + state, + getState() { + return this.state; + } +}); + +describe("BookmarksFeed", () => { + let BookmarksFeed; + let instance; + let reduxState; + let fakeSimplePrefs; + beforeEach(() => { + fakeSimplePrefs = {prefs: {defaultBookmarksAge: "0"}}; + BookmarksFeed = require("inject!addon/Feeds/BookmarksFeed")({ + "addon/PlacesProvider": {PlacesProvider}, + "addon/lib/getScreenshot": sinon.spy(() => testScreenshot), + "sdk/simple-prefs": fakeSimplePrefs + }); + Object.keys(PlacesProvider.links).forEach(k => PlacesProvider.links[k].reset()); + instance = new BookmarksFeed({getCachedMetadata}); + instance.refresh = sinon.spy(); + reduxState = {Experiments: {values: {}}}; + instance.store = {getState() { return reduxState; }}; + sinon.spy(instance.options, "getCachedMetadata"); + }); + it("should create a BookmarksFeed", () => { + assert.instanceOf(instance, BookmarksFeed); + }); + it("should have an UPDATE_TIME of 15 minutes", () => { + const time = moment.duration(BookmarksFeed.UPDATE_TIME); + assert.equal(time.minutes(), 15); + }); + describe("#getData", () => { + it("should resolve with a BOOKMARKS_RESPONSE action", () => + instance.getData() + .then(action => { + assert.isObject(action); + assert.equal(action.type, "BOOKMARKS_RESPONSE"); + assert.lengthOf(action.data, 2); + }) + ); + it("should call getBookmarks with a limit of BOOKMARKS_LENGTH and defaultBookmarkAge", () => + instance.getData() + .then(() => { + assert.calledWithExactly(PlacesProvider.links.getBookmarks, { + limit: BOOKMARKS_LENGTH, + ageMin: 50 + BOOKMARKS_THRESHOLD + }); + }) + ); + it("should run sites through getCachedMetadata", () => + instance.getData() + .then(action => { + assert.calledOnce(instance.options.getCachedMetadata); + assert.deepEqual(action.data, getCachedMetadata(testLinks)); + }) + ); + it("should set missingData to true if a link is missing a required screenshot", () => { + instance.shouldGetScreenshot = () => true; + instance.getScreenshot = sinon.spy(site => null); + return instance.getData().then(() => { + assert.equal(instance.missingData, true); + }); + }); + it("should set hasMetadata to false if a link is missing screenshot", () => { + instance.options.getCachedMetadata = links => links.map( + link => { link.hasMetadata = false; return link; } + ); + return instance.getData().then(() => { + assert.equal(instance.missingData, true); + }); + }); + describe("test feed correctly filters links", () => { + let store; + beforeEach(() => { + store = createStoreWithState({}); + instance.connectStore(store); + }); + it("should filter links with no title", () => { + instance.options.getCachedMetadata = links => links.map( + link => { link.title = null; return link; } + ); + return instance.getData().then(result => { + assert.equal(result.data.length, 0); + }); + }); + it("should get some links from PlacesProvider", () => + PlacesProvider.links.getBookmarks().then(links => assert.notEqual(links, 0)) + ); + it("should allow links with with metadata", () => + instance.getData().then(result => assert.equal(result.data.length, testLinks.length)) + ); + }); + describe("fetching bookmark timestamp", () => { + it("should call getDefaultBookmarksAge when the defaultBookmarksAge is not set (is 0)", () => + instance.getData().then(() => { + assert.calledOnce(PlacesProvider.links.getDefaultBookmarksAge); + } + )); + it("should set defaultBookmarksAge to '50' (the string)", () => + instance.getData().then(() => { + assert.equal(fakeSimplePrefs.prefs.defaultBookmarksAge, "50"); + } + )); + it("should use the defaultBookmarksAge pref value instead of placesProvider query", () => { + fakeSimplePrefs = {prefs: {defaultBookmarksAge: "99"}}; + BookmarksFeed = require("inject!addon/Feeds/BookmarksFeed")({ + "addon/PlacesProvider": {PlacesProvider}, + "addon/lib/getScreenshot": sinon.spy(() => testScreenshot), + "sdk/simple-prefs": fakeSimplePrefs + }); + instance = new BookmarksFeed({getCachedMetadata}); + + return instance.getData().then(result => { + assert.calledWithExactly(PlacesProvider.links.getBookmarks, { + limit: BOOKMARKS_LENGTH, + ageMin: 99 + BOOKMARKS_THRESHOLD + }); + }); + }); + }); + }); + describe("#onAction", () => { + let store; + beforeEach(() => { + instance.refresh = sinon.spy(); + store = createStoreWithState({}); + instance.connectStore(store); + }); + it("should call refresh on APP_INIT", () => { + instance.onAction(store.getState(), {type: "APP_INIT"}); + assert.calledOnce(instance.refresh); + assert.calledWith(instance.refresh, "app was initializing"); + }); + it("should call refresh on RECEIVE_BOOKMARK_ADDED", () => { + instance.onAction(store.getState(), {type: "RECEIVE_BOOKMARK_ADDED"}); + assert.calledOnce(instance.refresh); + assert.calledWith(instance.refresh, "a bookmark was added"); + }); + it("should call refresh on RECEIVE_BOOKMARK_REMOVED", () => { + instance.onAction(store.getState(), {type: "RECEIVE_BOOKMARK_REMOVED"}); + assert.calledOnce(instance.refresh); + assert.calledWith(instance.refresh, "a bookmark was removed"); + }); + it("should call refresh on SCREENSHOT_UPDATED if missing data is true", () => { + instance.missingData = true; + instance.onAction(store.getState(), {type: "SCREENSHOT_UPDATED"}); + assert.calledOnce(instance.refresh); + assert.calledWith(instance.refresh, "new screenshot is available and we're missing data"); + }); + it("should not call refresh on SCREENSHOT_UPDATED if missing data is false", () => { + instance.missingData = false; + instance.onAction(store.getState(), {type: "SCREENSHOT_UPDATED"}); + assert.notCalled(instance.refresh); + }); + it("should call refresh on METADATA_UPDATED if missing data is true", () => { + instance.missingData = true; + instance.onAction(store.getState(), {type: "METADATA_UPDATED"}); + assert.calledOnce(instance.refresh); + assert.calledWith(instance.refresh, "new metadata is available and we're missing data"); + }); + it("should not call refresh on METADATA_UPDATED if missing data is false", () => { + instance.missingData = false; + instance.onAction(store.getState(), {type: "METADATA_UPDATED"}); + assert.notCalled(instance.refresh); + }); + it("should call refresh on SYNC_COMPLETE", () => { + instance.onAction(store.getState(), {type: "SYNC_COMPLETE"}); + assert.calledOnce(instance.refresh); + assert.calledWith(instance.refresh, "new tabs synced"); + }); + it("should not call refresh on MANY_LINKS_CHANGED", () => { + instance.onAction(store.getState(), {type: "MANY_LINKS_CHANGED"}); + assert.calledOnce(instance.refresh); + assert.calledWith(instance.refresh, "frecency of many links changed"); + }); + }); +}); diff --git a/content-test/addon/Feeds/HighlightsFeed.test.js b/content-test/addon/Feeds/HighlightsFeed.test.js deleted file mode 100644 index 03eac8b575..0000000000 --- a/content-test/addon/Feeds/HighlightsFeed.test.js +++ /dev/null @@ -1,232 +0,0 @@ -const {TOP_SITES_DEFAULT_LENGTH, HIGHLIGHTS_LENGTH} = require("common/constants"); -const moment = require("moment"); -const {SimplePrefs} = require("sdk/simple-prefs"); - -const simplePrefs = new SimplePrefs(); -const testLinks = [{url: "foo.com"}, {url: "bar.com"}]; -const oldTestLinks = [{url: "boo.com"}, {url: "far.com"}]; -const getCachedMetadata = links => links.map( - link => { link.hasMetadata = true; return link; } -); -const PlacesProvider = { - links: { - getAllHistoryItems: sinon.spy(() => Promise.resolve(testLinks)), - getRecentlyVisited: sinon.spy(() => Promise.resolve(testLinks)), - getHighlightsLinks: sinon.spy(() => Promise.resolve(oldTestLinks)) - } -}; -const testScreenshot = "screenshot.jpg"; - -class Recommender { - constructor(...args) { - this.args = args; - } -} -const createStoreWithState = state => ({ - state, - getState() { - return this.state; - } -}); - -describe("HighlightsFeed", () => { - let HighlightsFeed; - let instance; - let reduxState; - beforeEach(() => { - HighlightsFeed = require("inject!addon/Feeds/HighlightsFeed")({ - "addon/PlacesProvider": {PlacesProvider}, - "sdk/simple-prefs": simplePrefs, - "common/recommender/Recommender": {Recommender}, - "addon/lib/getScreenshot": sinon.spy(() => testScreenshot) - }); - Object.keys(PlacesProvider.links).forEach(k => PlacesProvider.links[k].reset()); - instance = new HighlightsFeed({getCachedMetadata}); - instance.refresh = sinon.spy(); - reduxState = {Experiments: {values: {}}}; - instance.store = {getState() { return reduxState; }}; - sinon.spy(instance.options, "getCachedMetadata"); - }); - it("should create a HighlightsFeed", () => { - assert.instanceOf(instance, HighlightsFeed); - }); - it("should have an UPDATE_TIME of 15 minutes", () => { - const time = moment.duration(HighlightsFeed.UPDATE_TIME); - assert.equal(time.minutes(), 15); - }); - describe("#getCoefficientsFromPrefs", () => { - it("should return coefficients from prefs", () => { - simplePrefs.prefs.weightedHighlightsCoefficients = "[0, 1, 2]"; - assert.deepEqual(instance.getCoefficientsFromPrefs(), [0, 1, 2]); - }); - it("should return null if there were parsing errors", () => { - simplePrefs.prefs.weightedHighlightsCoefficients = "not valid"; - assert.isNull(instance.getCoefficientsFromPrefs()); - }); - it("should return null if the pref does not return an array", () => { - simplePrefs.prefs.weightedHighlightsCoefficients = "{}"; - assert.isNull(instance.getCoefficientsFromPrefs()); - }); - }); - describe("#initializeRecommender", () => { - it("should return a promise", () => { - assert.instanceOf(instance.initializeRecommender(), Promise); - }); - it("should set .baselineRecommender", () => - instance.initializeRecommender().then(() => - assert.instanceOf(instance.baselineRecommender, Recommender) - ) - ); - it("should pass the right args", () => { - simplePrefs.prefs.weightedHighlightsCoefficients = "[0, 1, 2]"; - return instance.initializeRecommender().then(() => { - assert.equal(instance.baselineRecommender.args[0], testLinks); - assert.deepEqual(instance.baselineRecommender.args[1], { - experiments: reduxState.Experiments.values, - highlightsCoefficients: [0, 1, 2] - }); - }); - }); - it("should call refresh with the reason", () => { - instance.refresh = sinon.spy(); - return instance.initializeRecommender("foo").then(() => { - assert.calledWith(instance.refresh, "foo"); - }); - }); - }); - describe("#getData", () => { - it("should reject if baselineRecommender is undefined", () => instance.getData() - .catch(e => { - assert.instanceOf(e, Error); - assert.equal(e.message, "Tried to get weighted highlights but there was no baselineRecommender"); - }) - ); - it("should resolve with a HIGHLIGHTS_RESPONSE action if there are weighted highlights", () => { - instance.baselineRecommender = {scoreEntries: links => links}; - return instance.getData() - .then(action => { - assert.isObject(action); - assert.equal(action.type, "HIGHLIGHTS_RESPONSE"); - assert.lengthOf(action.data, 2); - }); - }); - it("should run sites through getCachedMetadata", () => { - instance.baselineRecommender = {scoreEntries: links => links}; - return instance.getData() - .then(action => { - assert.calledOnce(instance.options.getCachedMetadata); - assert.deepEqual(action.data, getCachedMetadata(testLinks)); - }); - }); - it("should run sites through scoreEntries AFTER getCachedMetadata", () => { - instance.baselineRecommender = {scoreEntries: sinon.spy(links => links)}; - return instance.getData() - .then(action => ( - assert.calledWithExactly(instance.baselineRecommender.scoreEntries, getCachedMetadata(testLinks)) - )); - }); - it("should not add screenshots to sites that don't qualify for a screenshot", () => { - instance.baselineRecommender = {scoreEntries: sinon.spy(links => links)}; - instance.shouldGetScreenshot = () => false; - return instance.getData().then(result => { - assert.notCalled(instance.getScreenshot); - for (let link of result.data) { - assert.equal(link.screenshot, undefined); - } - }); - }); - it("should add screenshots to sites that qualify for a screenshot", () => { - instance.baselineRecommender = {scoreEntries: sinon.spy(links => links)}; - instance.shouldGetScreenshot = () => true; - return instance.getData().then(result => { - assert.calledTwice(instance.getScreenshot); - for (let link of result.data) { - assert.equal(link.screenshot, testScreenshot); - assert.notEqual(link.metadata_source.indexOf("+Screenshot"), -1); - } - }); - }); - it("should set missingData to true if a topsite is missing a required screenshot", () => { - instance.baselineRecommender = {scoreEntries: sinon.spy(links => links)}; - instance.shouldGetScreenshot = () => true; - instance.getScreenshot = sinon.spy(site => null); - return instance.getData().then(result => { - assert.equal(instance.missingData, true); - }); - }); - it("should set missingData to true if a highlight is missing metadata", () => { - instance.baselineRecommender = {scoreEntries: sinon.spy(links => links)}; - instance.options.getCachedMetadata = links => links.map( - link => { link.hasMetadata = false; return link; } - ); - return instance.getData().then(result => { - assert.equal(instance.missingData, true); - }); - }); - }); - describe("#onAction", () => { - let clock; - let store; - beforeEach(() => { - instance.refresh = sinon.spy(); - instance.baselineRecommender = {scoreEntries: sinon.spy(links => links)}; - clock = sinon.useFakeTimers(); - store = createStoreWithState({}); - instance.connectStore(store); - }); - afterEach(() => { - clock.restore(); - }); - it("should call refresh on APP_INIT", () => { - instance.initializeRecommender = sinon.spy(); - instance.onAction(store.getState(), {type: "APP_INIT"}); - assert.calledWith(instance.initializeRecommender, "app was initializing"); - }); - it("should call refresh on RECEIVE_BOOKMARK_ADDED", () => { - instance.onAction({}, {type: "RECEIVE_BOOKMARK_ADDED"}); - assert.calledOnce(instance.refresh); - assert.calledWith(instance.refresh, "a bookmark was added"); - }); - it("should call refresh on METADATA_UPDATED if there are not enough sites", () => { - store.state.Highlights = {rows: Array(HIGHLIGHTS_LENGTH + TOP_SITES_DEFAULT_LENGTH - 1).fill("site")}; - instance.onAction(store.getState(), {type: "METADATA_UPDATED"}); - assert.calledOnce(instance.refresh); - assert.calledWith(instance.refresh, "new metadata is available and there were not enough sites"); - }); - it("should not call refresh on METADATA_UPDATED if there are enough sites", () => { - store.state.Highlights = {rows: Array(HIGHLIGHTS_LENGTH + TOP_SITES_DEFAULT_LENGTH).fill("site")}; - instance.onAction(store.getState(), {type: "METADATA_UPDATED"}); - assert.notCalled(instance.refresh); - }); - it("should call refresh on METADATA_UPDATED if .lastUpdated is too old", () => { - store.state.Highlights = {rows: Array(HIGHLIGHTS_LENGTH + TOP_SITES_DEFAULT_LENGTH).fill("site")}; - instance.lastUpdated = 0; - clock.tick(HighlightsFeed.UPDATE_TIME); - instance.onAction(store.getState(), {type: "METADATA_UPDATED"}); - assert.calledOnce(instance.refresh); - assert.calledWith(instance.refresh, "new metadata is available and the sites were too old"); - }); - it("should not call refresh on METADATA_UPDATED if .lastUpdated is less than update time", () => { - store.state.Highlights = {rows: Array(HIGHLIGHTS_LENGTH + TOP_SITES_DEFAULT_LENGTH).fill("site")}; - instance.lastUpdated = 0; - clock.tick(HighlightsFeed.UPDATE_TIME - 1); - instance.onAction(store.getState(), {type: "METADATA_UPDATED"}); - assert.notCalled(instance.refresh); - }); - it("should update the coefficients if the weightedHighlightsCoefficients pref is changed", () => { - instance.initializeRecommender = sinon.spy(); - instance.onAction(store.getState(), {type: "PREF_CHANGED_RESPONSE", data: {name: "weightedHighlightsCoefficients"}}); - assert.calledWith(instance.initializeRecommender, "coefficients were changed"); - }); - it("should call refresh on SYNC_COMPLETE", () => { - instance.onAction({}, {type: "SYNC_COMPLETE"}); - assert.calledOnce(instance.refresh); - assert.calledWith(instance.refresh, "new tabs synced"); - }); - it("should call refresh on MANY_LINKS_CHANGED", () => { - instance.onAction({}, {type: "MANY_LINKS_CHANGED"}); - assert.calledOnce(instance.refresh); - assert.calledWith(instance.refresh, "frecency of many links changed"); - }); - }); -}); diff --git a/content-test/addon/Feeds/VisitAgainFeed.test.js b/content-test/addon/Feeds/VisitAgainFeed.test.js new file mode 100644 index 0000000000..cec7b077d1 --- /dev/null +++ b/content-test/addon/Feeds/VisitAgainFeed.test.js @@ -0,0 +1,149 @@ +const {VISITAGAIN_LENGTH} = require("common/constants"); +const moment = require("moment"); +const testLinks = [{url: "foo.com", hostname: "foo.com"}, + {url: "bar.com", hostname: "bar.com"}]; +const getCachedMetadata = links => links.map( + link => { + link.hasMetadata = true; + link.images = [1, 2, 3]; + return link; + } +); +const PlacesProvider = {links: {getRecentlyVisited: sinon.spy(() => Promise.resolve(testLinks))}}; +const testScreenshot = "screenshot.jpg"; + +const createStoreWithState = state => ({ + state, + getState() { + return this.state; + } +}); + +describe("VisitAgainFeed", () => { + let VisitAgainFeed; + let instance; + let reduxState; + beforeEach(() => { + VisitAgainFeed = require("inject!addon/Feeds/VisitAgainFeed")({ + "addon/PlacesProvider": {PlacesProvider}, + "addon/lib/getScreenshot": sinon.spy(() => testScreenshot) + }); + Object.keys(PlacesProvider.links).forEach(k => PlacesProvider.links[k].reset()); + instance = new VisitAgainFeed({getCachedMetadata}); + instance.refresh = sinon.spy(); + reduxState = {Experiments: {values: {}}}; + instance.store = {getState() { return reduxState; }}; + sinon.spy(instance.options, "getCachedMetadata"); + }); + it("should create a VisitAgainFeed", () => { + assert.instanceOf(instance, VisitAgainFeed); + }); + it("should have an UPDATE_TIME of 15 minutes", () => { + const time = moment.duration(VisitAgainFeed.UPDATE_TIME); + assert.equal(time.minutes(), 15); + }); + describe("#getData", () => { + it("should resolve with a VISITAGAIN_RESPONSE action", () => + instance.getData() + .then(action => { + assert.isObject(action); + assert.equal(action.type, "VISITAGAIN_RESPONSE"); + assert.lengthOf(action.data, 2); + }) + ); + it("should call getRecentlyVisited with a limit of VISITAGAIN_LENGTH", () => + instance.getData() + .then(() => { + assert.calledWithExactly(PlacesProvider.links.getRecentlyVisited, {limit: VISITAGAIN_LENGTH}); + }) + ); + it("should run sites through getCachedMetadata", () => + instance.getData() + .then(action => { + assert.calledOnce(instance.options.getCachedMetadata); + assert.deepEqual(action.data, getCachedMetadata(testLinks)); + }) + ); + it("should set missingData to true if a topsite is missing a required screenshot", () => { + instance.shouldGetScreenshot = () => true; + instance.getScreenshot = sinon.spy(site => null); + return instance.getData().then(() => { + assert.equal(instance.missingData, true); + }); + }); + it("should set hasMetadata to false if a link is missing screenshot", () => { + instance.options.getCachedMetadata = links => links.map( + link => { link.hasMetadata = false; return link; } + ); + return instance.getData().then(() => { + assert.equal(instance.missingData, true); + }); + }); + describe("test feed correctly filters links", () => { + let store; + beforeEach(() => { + store = createStoreWithState({}); + instance.connectStore(store); + }); + it("should filter links with hasMetadata set to false", () => { + instance.options.getCachedMetadata = links => links.map( + link => { link.hasMetadata = false; return link; } + ); + return instance.getData().then(result => { + assert.equal(result.data.length, 0); + }); + }); + it("should filter links with no images", () => { + instance.options.getCachedMetadata = links => links.map( + link => { + link.hasMetadata = true; + link.images = []; + return link; + } + ); + return instance.getData().then(result => { + assert.equal(result.data.length, 0); + }); + }); + }); + }); + describe("#onAction", () => { + let store; + beforeEach(() => { + instance.refresh = sinon.spy(); + store = createStoreWithState({}); + instance.connectStore(store); + }); + it("should call refresh on APP_INIT", () => { + instance.onAction(store.getState(), {type: "APP_INIT"}); + assert.calledOnce(instance.refresh); + assert.calledWith(instance.refresh, "app was initializing"); + }); + it("should call refresh on METADATA_UPDATED missingData is true", () => { + instance.missingData = true; + instance.onAction(store.getState(), {type: "METADATA_UPDATED"}); + assert.calledOnce(instance.refresh); + assert.calledWith(instance.refresh, "new metadata is available and we're missing data"); + }); + it("should not call refresh on METADATA_UPDATED if missingData is false", () => { + instance.missingData = false; + instance.onAction(store.getState(), {type: "METADATA_UPDATED"}); + assert.notCalled(instance.refresh); + }); + it("should call refresh on SYNC_COMPLETE", () => { + instance.onAction({}, {type: "SYNC_COMPLETE"}); + assert.calledOnce(instance.refresh); + assert.calledWith(instance.refresh, "new tabs synced"); + }); + it("should call refresh on MANY_LINKS_CHANGED", () => { + instance.onAction({}, {type: "MANY_LINKS_CHANGED"}); + assert.calledOnce(instance.refresh); + assert.calledWith(instance.refresh, "frecency of many links changed"); + }); + it("should call refresh on RECEIVE_PLACES_CHANGES", () => { + instance.onAction({}, {type: "RECEIVE_PLACES_CHANGES"}); + assert.calledOnce(instance.refresh); + assert.calledWith(instance.refresh, "always need the newest sites"); + }); + }); +}); diff --git a/content-test/addon/PreviewProvider.test.js b/content-test/addon/PreviewProvider.test.js index daa09d101c..6b11d15e54 100644 --- a/content-test/addon/PreviewProvider.test.js +++ b/content-test/addon/PreviewProvider.test.js @@ -5,10 +5,16 @@ const BACKGROUND_COLOR = [255, 255, 255]; const getColor = function() { return Promise.resolve(BACKGROUND_COLOR); }; + +let fakeSite = {"url": "https://getMyFaviconColor.com", "favicon": "favicon.ico"}; +const {PreviewProvider} = createPreviewProvider({"addon/ColorAnalyzerProvider": {getColor}}); + describe("PreviewProvider", () => { - const {PreviewProvider} = createPreviewProvider({"addon/ColorAnalyzerProvider": {getColor}}); - const previewProvider = new PreviewProvider({}, {}); - let fakeSite = {"url": "https://getMyFaviconColor.com", "favicon": "favicon.ico"}; + let previewProvider; + + beforeEach(() => { + previewProvider = new PreviewProvider({}, {}); + }); it("should be an get the correct color and set the background fade", () => { const expectedColor = [...BACKGROUND_COLOR, BACKGROUND_FADE]; @@ -19,4 +25,18 @@ describe("PreviewProvider", () => { fakeSite.favicon = null; return previewProvider._getFaviconColors(fakeSite).then(color => assert.equal(color, null)); }); + + describe("asyncLinkExists", () => { + it("should sanitize the url before calling createCacheKey", () => { + const fakeMetadataStore = {asyncCacheKeyExists: url => Promise.resolve(url)}; + previewProvider = new PreviewProvider({}, fakeMetadataStore); + + const url1 = previewProvider.asyncLinkExist("https://developer.mozilla.org/search?bar=foo"); + const url2 = previewProvider.asyncLinkExist("https://developer.mozilla.org/search"); + + return Promise.all([url1, url2]).then(([v1, v2]) => { + assert.equal(v1, v2); + }); + }); + }); }); diff --git a/content-test/common/Baseline.test.js b/content-test/common/Baseline.test.js deleted file mode 100644 index 8101cef6d5..0000000000 --- a/content-test/common/Baseline.test.js +++ /dev/null @@ -1,579 +0,0 @@ -const {Baseline} = require("common/recommender/Baseline"); -const {createSite} = require("test/faker"); - -const fakeHistory = [ - { - reversedHost: "moc.elgoog.", - visitCount: 1 - }, - { - reversedHost: "moc.buhtig.", - visitCount: 1 - }, - { - reversedHost: "moc.oof.", - visitCount: 2 - }, - { - reversedHost: "moc.rab.", - visitCount: 2 - }, - { - reversedHost: "moc.1rab.", - visitCount: 2 - }, - { - reversedHost: "moc.2rab.", - visitCount: 2 - } -]; - -const fakeUrls = [ - { - url: "http://google.com/calendar", - host: "google.com", - visitCount: 2, - title: "Activity Stream", - description: "", - images: [{"url": "google.com", "width": 100, "height": 100}], - imageCount: 1, - lastVisitDate: Date.now() - 1e2 - }, - { - url: "http://github.com/mozilla/activity-stream", - host: "github.com", - visitCount: 1, - title: "Activity Stream", - description: "", - images: [{"url": "github.com", "width": 100, "height": 100}], - imageCount: 1, - lastVisitDate: Date.now() - 1e2 - }, - { - url: "http://github.com/mozilla/activity-stream", - host: "github.com", - visitCount: 1, - title: "Activity Stream", - description: "", - images: [{"url": "github.com", "width": 100, "height": 100}], - imageCount: 1, - lastVisitDate: Date.now() - 1e2 - }, - { - url: "http://foo.com/test", - host: "foo.com", - visitCount: 1, - title: "Activity Stream", - description: "", - images: [{"url": "foo.com", "width": 100, "height": 100}], - imageCount: 1, - lastVisitDate: Date.now() - 1e2 - }, - { - url: "http://bar.com/test", - host: "bar.com", - visitCount: 1, - title: "Activity Stream", - bookmarkDateCreated: 1, - description: "", - images: [{"url": "bar.com", "width": 100, "height": 100}], - imageCount: 1, - lastVisitDate: Date.now() - 1e2 - }, - { - url: "http://bar1.com/test", - host: "bar1.com", - visitCount: 1, - title: "Old link", - description: "", - images: [{"url": "bar1.com", "width": 100, "height": 100}], - imageCount: 1, - lastVisitDate: Date.now() - 1e6 - }, - { - url: "http://bar2.com/test", - host: "bar2.com", - visitCount: 30, - title: "Very visited", - description: "", - images: [{"url": "bar2.com", "width": 100, "height": 100}], - imageCount: 1, - lastVisitDate: Date.now() - 1e2 - } -]; - -describe("Baseline", () => { - let baseline; - let sandbox; - - beforeEach(() => { - sandbox = sinon.sandbox.create(); - baseline = new Baseline( - fakeHistory, - {highlightsCoefficients: [-0.1, -0.1, -0.1, 0.4, 0.2]} - ); - }); - - afterEach(() => { - sandbox.restore(); - }); - - it("should return a score for the urls", () => { - let items = baseline.score(fakeUrls); - assert.isNumber(items[0].score); - }); - - it("should return 0 for when no images are present", () => { - assert.equal(baseline.extractImage({}), 0); - }); - - it("should return 0 when image array is empty", () => { - assert.equal(baseline.extractImage({images: []}), 0); - }); - - it("should return 0 for when images don't have size", () => { - assert.equal(baseline.extractImage({images: [{}]}), 0); - }); - - it("should return 0 for when images don't have width or height", () => { - assert.equal(baseline.extractImage({images: [{url: "foo"}]}), 0); - }); - - it("should extract image size", () => { - const images = [{width: 300, height: 300, url: "bar"}]; - assert.equal(baseline.extractImage(images), 300 * 300); - }); - - it("should remove duplicate domains", () => { - let items = baseline.score(fakeUrls); - assert.equal(items.length, fakeUrls.length - 1); - }); - - it("should keep the highest scored duplicate domain", () => { - // we are under the assumption that the sites are pre-sorted by score - // before entering the dedupe function - const fakethings = [ - {host: "google.com", score: 10}, - {host: "github.com", score: 20}, - {host: "github.com", score: 5}, - {host: "github.com", score: 3}]; - let items = baseline._dedupeSites(fakethings); - assert.equal(items.length, 2); - assert.equal(items[1].score, 20); - }); - - it("should sort items", () => { - let items = baseline.score(fakeUrls); - let descending = true; - - for (let i = 1; i < items.length; i++) { - descending &= items[i - 1].score > items[i].score; - } - - assert.isOk(descending); - }); - - it("should remove items with no images except bookmarks", () => { - let fakeUrlsWithNoImages = fakeUrls.map(item => Object.assign({}, item, {images: []})); - let items = baseline.score(fakeUrlsWithNoImages); - assert.equal(items.length, 1); - }); - - it("should decrease score for consecutive items from the same domain", () => { - let fakeUrlsWithScore = fakeUrls.map(url => Object.assign({}, url, {score: 1})); - let items = baseline._adjustConsecutiveEntries(fakeUrlsWithScore); - assert.ok(items[1].score > items[2].score); - }); - - it("should decrease score for consecutive items with same image", () => { - let fakeUrlsWithScore = [ - {host: "foo.com", images: [{size: 1000, width: 300, height: 300, url: "http://www.sameimage.jpg"}], score: 1}, - {host: "bar.com", images: [{size: 1000, width: 300, height: 300, url: "http://www.sameimage.jpg"}], score: 1}, - {host: "bar.com", images: [{size: 1000, width: 300, height: 300, url: "http://www.sameimage.jpg"}], score: 1}, - {host: "diff.com", images: [{size: 1000, width: 300, height: 300, url: "http://www.diffimage.jpg"}], score: 1} - ]; - let items = baseline._adjustConsecutiveEntries(fakeUrlsWithScore); - assert.ok(items[0].score > items[1].score); - assert.ok(items[1].score > items[2].score); - assert.equal(items[1].score, 0.8); - assert.equal(items[3].score, 1); - }); - - it("should decrease score for consecutive items with same image (1 entry)", () => { - let fakeUrlsWithScore = [ - {host: "foo.com", images: [{size: 1000, width: 300, height: 300, url: "http://www.sameimage.jpg"}], score: 1} - ]; - let items = baseline._adjustConsecutiveEntries(fakeUrlsWithScore); - assert.equal(items[0].score, 1); - }); - - it("should decrease score for consecutive items with same image (no entries)", () => { - let items = baseline._adjustConsecutiveEntries([]); - assert.equal(items.length, 0); - }); - - it("should reset penalty coefficient after 2 consecutive & different items in the list", () => { - let fakeUrlsWithScore = [ - {host: "foo.com", images: [{size: 1000, width: 300, height: 300, url: "http://www.sameimage.jpg"}], score: 1}, - {host: "bar.com", images: [{size: 1000, width: 300, height: 300, url: "http://www.sameimage.jpg"}], score: 1}, - {host: "diff.com", images: [{size: 1000, width: 300, height: 300, url: "http://www.diffimage.jpg"}], score: 1}, - {host: "diff.com", images: [{size: 1000, width: 300, height: 300, url: "http://www.diffimage.jpg"}], score: 1} - ]; - let items = baseline._adjustConsecutiveEntries(fakeUrlsWithScore); - assert.equal(items[3].score, 0.8); - }); - - it("should decrease by the right amount", () => { - let fakeUrlsWithScore = fakeUrls.map(url => Object.assign({}, url, {score: 1})); - let items = baseline._adjustConsecutiveEntries(fakeUrlsWithScore); - // Items 1 and 2 are both github links so second one gets a lower score. - assert.equal(items[1].score, 1); - assert.equal(items[2].score, 0.8); - assert.equal(items[3].score, 1); - }); - - it("should rank websites visited a long time ago lower", () => { - let items = baseline.score(fakeUrls); - assert.equal(items[items.length - 2].title, "Old link"); - }); - - it("should rank websites with a lot of visits lower", () => { - let items = baseline.score(fakeUrls); - assert.equal(items[items.length - 1].title, "Very visited"); - }); - - describe("feature extraction", () => { - let entry; - beforeEach(() => { - entry = createSite({images: 2}); - }); - describe("assert correct calls", () => { - let updateFeatureStub; - beforeEach(() => { - updateFeatureStub = sandbox.stub(baseline, "updateFeatureMinMax"); - }); - - it("should update min max values", () => { - baseline.extractFeatures(entry); - - sinon.assert.calledOnce(updateFeatureStub); - }); - }); - it("should extract the correct path length", () => { - entry.url = "https://www.mozilla.org/projects/firefox/51.0a1/whatsnew/?oldversion=50.0a2"; - const result = baseline.extractFeatures(entry); - - assert.equal(result.features.pathLength, 4); - }); - it("should extract the correct number of images", () => { - const result = baseline.extractFeatures(entry); - - assert.isNumber(result.features.imageCount); - assert.equal(result.features.imageCount, entry.images.length); - }); - it("should extract the description", () => { - const result = baseline.extractFeatures(entry); - - assert.equal(result.features.description, entry.description.length); - }); - - it("should call `normalizeTimestamp`", () => { - const stub = sandbox.stub(baseline, "normalizeTimestamp"); - baseline.extractFeatures(entry); - - sinon.assert.calledOnce(stub); - }); - - it("should call `extractDescriptionLength`", () => { - const stub = sandbox.stub(baseline, "extractDescriptionLength"); - baseline.extractFeatures(entry); - - sinon.assert.calledOnce(stub); - }); - - it("should call `extractImage`", () => { - const stub = sandbox.stub(baseline, "extractImage"); - baseline.extractFeatures(entry); - - sinon.assert.calledOnce(stub); - }); - - it("should select min", () => { - assert.equal(baseline.selectMinValue(2, 1), 1); - }); - - it("should select max", () => { - assert.equal(baseline.selectMaxValue(2, 1), 2); - }); - - it("should not fail if argument is undefined or NaN", () => { - assert.equal(baseline.selectMaxValue(2, undefined), 2); - assert.equal(baseline.selectMaxValue(2, NaN), 2); - }); - - it("should not fail if argument is undefined or NaN", () => { - assert.equal(baseline.selectMinValue(2, undefined), 2); - assert.equal(baseline.selectMinValue(2, NaN), 2); - }); - - it("should return 0 if no description", () => { - const result = baseline.extractDescriptionLength({title: "http://www.firefox.com"}); - - assert.equal(result, 0); - }); - - it("should return 0 if description === url", () => { - const result = baseline.extractDescriptionLength({ - description: "http://www.firefox.com", - title: "http://www.firefox.com" - }); - - assert.equal(result, 0); - }); - - it("should return 0 if description === title", () => { - const result = baseline.extractDescriptionLength({ - title: "foo", - description: "foo" - }); - - assert.equal(result, 0); - }); - - it("should return correct length for valid description", () => { - const result = baseline.extractDescriptionLength({ - title: "foo", - description: "bar" - }); - - assert.equal(result, 3); - }); - - it("should not extract 0 occurrences", () => { - const result = baseline.extractFeatures({url: "http://www.neverbeforevisited.com"}); - - // If the URL was visited for the first time this session then - // occurrences in history is 0. Division by zero would result in Infinity. - // This is a sanity check. - assert.ok(result.features.idf < 10 && result.features.idf > 0); - }); - - it("should not extract 0 visits", () => { - const result = baseline.extractFeatures({ - url: "http://www.neverbeforevisited.com", - visitCount: 0 // Should never happen. - }); - - assert.equal(result.features.tf, 1); - }); - it("should not fail with feature value Infinity (on new profiles) for new websites", () => { - const result = baseline.extractFeatures({url: "http://www.neverbeforevisited.com"}); - - assert.isNumber(result.features.idf); - assert.isTrue(Number.isFinite(result.features.idf)); - }); - it("should not fail with feature value Infinity (on new profiles) for no history", () => { - baseline = new Baseline([], {highlightsCoefficients: [-0.1, -0.1, -0.1, 0.4, 0.2]}); - const result = baseline.extractFeatures({url: "http://www.neverbeforevisited.com"}); - - assert.isNumber(result.features.idf); - assert.isTrue(Number.isFinite(result.features.idf)); - }); - it("should call `extractDescriptionLength`", () => { - const stub = sandbox.stub(baseline, "extractDescriptionLength"); - baseline.extractFeatures(entry); - - sinon.assert.calledWithExactly(stub, entry); - }); - }); - - describe("decay", () => { - it("should throw an error for undefined values", () => { - assert.throws(() => baseline.decay(10, {foo: 1, bar: undefined}, [2, 3])); - }); - it("should call filter on the features", () => { - const result = baseline.decay(10, {foo: 1, bookmarkAge: 2}, [1]); - - assert.isNumber(result); - }); - it("should throw when different number of features and weights", () => { - assert.throws(() => baseline.decay(10, {foo: 1}, [1, 2])); - }); - }); - - describe("scoring", () => { - let entry; - beforeEach(() => { - entry = { - features: { - age: 1, - tf: 10, - idf: 10, - queryLength: 0, - imageCount: 1, - pathLength: 1, - bookmarkAge: 0, - description: 10, - image: 1 - } - }; - }); - - describe("normalizeTimestamp", () => { - it("should return a number if entry has undefined timestamp", () => { - const result = baseline.normalizeTimestamp(); - - assert.isNumber(result); - }); - it("should return a number if entry has timestamp", () => { - const result = baseline.normalizeTimestamp(Date.now() - 1e2); - - assert.isNumber(result); - }); - }); - - describe("scoreEntry", () => { - let normalizeStub; - let decayStub; - let adjustScoreStub; - beforeEach(() => { - normalizeStub = sandbox.stub(baseline, "normalize").returns(entry.features); - decayStub = sandbox.stub(baseline, "decay").returns(42); - adjustScoreStub = sandbox.stub(baseline, "adjustScore").returns(42); - }); - it("should call normalize", () => { - baseline.scoreEntry(entry); - - sinon.assert.calledOnce(normalizeStub); - sinon.assert.calledWith(normalizeStub, entry.features); - }); - it("should call decay", () => { - baseline.scoreEntry(entry); - const score = entry.features.tf * entry.features.idf; - - sinon.assert.calledOnce(decayStub); - sinon.assert.calledWith(decayStub, score, entry.features, baseline.options.highlightsCoefficients); - }); - it("should call adjust", () => { - baseline.scoreEntry(entry); - - sinon.assert.calledOnce(adjustScoreStub); - sinon.assert.calledWith(adjustScoreStub, 42, entry.features); - }); - it("should return a score", () => { - const result = baseline.scoreEntry(entry); - - assert.ok(result.score); - assert.isNumber(result.score); - }); - }); - - it("should rank bookmarks higher", () => { - const features = Object.assign({}, entry.features, {bookmarkAge: 1}); - const bookmarkScore = baseline.adjustScore(10, features); - const regularScore = baseline.adjustScore(10, entry.features); - - assert.isNumber(bookmarkScore); - assert.isNumber(regularScore); - assert.ok(bookmarkScore > regularScore); - }); - - it("should rank newer bookmarks higher", () => { - const oldFeatures = Object.assign({}, entry.features, {bookmarkAge: 100}); - const oldScore = baseline.adjustScore(10, oldFeatures); - const newFeatures = Object.assign({}, entry.features, {bookmarkAge: 1}); - const newScore = baseline.adjustScore(10, newFeatures); - - assert.ok(newScore > oldScore); - }); - }); - - describe("updateFeatureMinMax", () => { - let features; - beforeEach(() => { - baseline = new Baseline(fakeHistory, {highlightsCoefficients: [-0.1, -0.1, -0.1, 0.4, 0.2]}); - const entry = createSite({images: 2}); - features = baseline.extractFeatures(entry); - }); - it("should call `selectMinValue`", () => { - const stub = sandbox.stub(baseline, "selectMinValue"); - const callCount = Object.keys(baseline.normalizeFeatures).length; - baseline.updateFeatureMinMax(features); - - sinon.assert.callCount(stub, callCount); - }); - it("should store min value of features that need normalization", () => { - features.pathLength = 0; - baseline.updateFeatureMinMax(features); - - assert.equal(baseline.normalizeFeatures.pathLength.min, features.pathLength); - }); - - it("should store max value of features that need normalization", () => { - assert.equal(baseline.normalizeFeatures.description.max, features.description.length); - }); - - it("should keep old value if an entry is undefined by accident", () => { - const noImageFeatures = Object.assign({}, features, {image: undefined}); - baseline = new Baseline(fakeHistory, {highlightsCoefficients: [-0.1, -0.1, -0.1, 0.4, 0.2]}); - const {min, max} = baseline.normalizeFeatures.image; - - baseline.updateFeatureMinMax(noImageFeatures); - - assert.equal(baseline.normalizeFeatures.image.min, min); - assert.equal(baseline.normalizeFeatures.image.max, max); - }); - }); - - describe("normalize", () => { - let features; - beforeEach(() => { - baseline = new Baseline(fakeHistory, {highlightsCoefficients: [-0.1, -0.1, -0.1, 0.4, 0.2]}); - const entry = createSite({images: 2}); - features = baseline.extractFeatures(entry).features; - }); - it("should not normalize if min > max", () => { - baseline.normalizeFeatures.tf = {min: 10, max: 1}; - features.tf = 5; - const result = baseline.normalize(features); - - assert.isNumber(result.tf); - assert.equal(result.tf, features.tf); - }); - it("should not divide by 0", () => { - baseline.normalizeFeatures.description = {min: 0, max: 0}; - const result = baseline.normalize(features); - - assert.equal(result.description, features.description); - }); - it("should normalize features", () => { - baseline.normalizeFeatures.idf = {min: 1, max: 11}; - features.idf = 5; - const result = baseline.normalize(features); - - assert.isNumber(result.idf); - assert.ok(result.idf < 1 && result.idf > 0); - }); - it("should simply return features that shouldn't be normalized", () => { - const result = baseline.normalize(features); - - assert.isNumber(result.imageCount); - assert.equal(result.imageCount, features.imageCount); - }); - }); - - describe("options", () => { - const options = {highlightsCoefficients: [1, 2, 3]}; - it("should throw an error if highlightsCoefficients not provided", () => { - assert.throws(() => new Baseline(fakeHistory)); - }); - it("should instantiate the recommender with the correct settings", () => { - baseline = new Baseline(fakeHistory, options); - assert.deepEqual(baseline.options, options); - }); - it("should update the correct settings", () => { - baseline.updateOptions(options); - assert.deepEqual(baseline.options, options); - }); - }); -}); diff --git a/content-test/common/Recommender.test.js b/content-test/common/Recommender.test.js deleted file mode 100644 index be59bd5181..0000000000 --- a/content-test/common/Recommender.test.js +++ /dev/null @@ -1,22 +0,0 @@ -const {Recommender} = require("common/recommender/Recommender"); -const {Baseline} = require("common/recommender/Baseline"); -const {assert} = require("chai"); - -describe("recommender", () => { - let recommender; - beforeEach(() => { - recommender = new Recommender([], {highlightsCoefficients: [0.1, -0.2, -0.2, -0.1, -0.8, -0.2, 0.1, 0.2]}); - }); - it("should instantiate the recommender with the baseline weight function", () => { - assert.property(recommender, "recommender"); - }); - it("should instantiate with an instance of Baseline", () => { - assert.ok(recommender.recommender instanceof Baseline); - }); - it("should forward the options to the Baseline weight function", () => { - const options = {highlightsCoefficients: [1, 2, 3]}; - recommender.updateOptions(options); - - assert.deepEqual(recommender.recommender.options, options); - }); -}); diff --git a/content-test/common/reducers/Experiments.test.js b/content-test/common/reducers/Experiments.test.js index 9a264375d6..792b98f778 100644 --- a/content-test/common/reducers/Experiments.test.js +++ b/content-test/common/reducers/Experiments.test.js @@ -25,7 +25,7 @@ describe("Experiments reducer", () => { it("should ignore events other than EXPERIMENTS_RESPONSE", () => { const prevState = {error: false, data: {}}; const state = Experiments(prevState, { - type: "SPOTLIGHT_RESPONSE", + type: "BOOKMARKS_RESPONSE", error: true, data: new Error("Whatever") }); diff --git a/content-test/common/selectors/selectAndDedupe.test.js b/content-test/common/selectors/selectAndDedupe.test.js index dcbfae44d5..56e6a4a17b 100644 --- a/content-test/common/selectors/selectAndDedupe.test.js +++ b/content-test/common/selectors/selectAndDedupe.test.js @@ -1,8 +1,23 @@ -const selectAndDedupe = require("common/selectors/selectAndDedupe"); +const {selectAndDedupe, dedupeOne} = require("common/selectors/selectAndDedupe"); -const urlToSite = url => ({url}); +describe("dedupeOne", () => { + const urlToSite = url => ({url, hostname: url}); + + it("should dedupe items by hostname", () => { + const result = dedupeOne([ + "http://www.mozilla.org", + "http://www.firefox.org", + "http://www.mozilla.org" + ].map(urlToSite)); + assert.lengthOf(result, 2); + assert.deepEqual(result[0].url, "http://www.mozilla.org"); + assert.deepEqual(result[1].url, "http://www.firefox.org"); + }); +}); describe("selectAndDedupe", () => { + const urlToSite = url => ({url}); + it("should dedupe items", () => { const result = selectAndDedupe([ {sites: [{url: "http://www.mozilla.org"}]}, diff --git a/content-test/common/selectors/selectorUtils.test.js b/content-test/common/selectors/selectorUtils.test.js index f9bd991b4f..20aad33bd5 100644 --- a/content-test/common/selectors/selectorUtils.test.js +++ b/content-test/common/selectors/selectorUtils.test.js @@ -2,10 +2,9 @@ const {areSelectorsReady} = require("common/selectors/selectorUtils.js"); describe("selectorUtils", () => { describe("areSelectorsReady", () => { - it("should return true if state.{TopSites,Highlights,Experiments}.init are all true", () => { + it("should return true if state.{TopSites,Experiments}.init are all true", () => { const fakeStoreState = { TopSites: {init: true}, - Highlights: {init: true}, Experiments: {init: true} }; @@ -14,7 +13,6 @@ describe("selectorUtils", () => { it("should return true if state.TopSites.init is false", () => { const fakeStoreState = { TopSites: {init: false}, - Highlights: {init: true}, Experiments: {init: true} }; @@ -23,19 +21,9 @@ describe("selectorUtils", () => { it("should return true if state.Experiments.init is false", () => { const fakeStoreState = { TopSites: {init: true}, - Highlights: {init: true}, Experiments: {init: false} }; - assert.isFalse(areSelectorsReady(fakeStoreState)); - }); - it("should return true if state.Highlights.init is false", () => { - const fakeStoreState = { - TopSites: {init: true}, - Highlights: {init: false}, - Experiments: {init: true} - }; - assert.isFalse(areSelectorsReady(fakeStoreState)); }); }); diff --git a/content-test/common/selectors/selectors.test.js b/content-test/common/selectors/selectors.test.js index 09257dce5e..49d74ee88f 100644 --- a/content-test/common/selectors/selectors.test.js +++ b/content-test/common/selectors/selectors.test.js @@ -3,7 +3,7 @@ const React = require("react"); const TestUtils = require("react-addons-test-utils"); const firstRunData = require("lib/first-run-data"); const {justDispatch, selectNewTabSites} = require("common/selectors/selectors"); -const {TOP_SITES_DEFAULT_LENGTH, HIGHLIGHTS_LENGTH} = require("common/constants.js"); +const {TOP_SITES_DEFAULT_LENGTH} = require("common/constants.js"); const {rawMockData, createMockProvider} = require("test/test-utils"); const fakeState = rawMockData; @@ -41,7 +41,7 @@ describe("selectors", () => { beforeEach(() => setup()); it("should return the right properties", () => { - ["Highlights", "TopSites"].forEach(prop => assert.property(state, prop)); + ["TopSites"].forEach(prop => assert.property(state, prop)); }); describe("TopSites", () => { @@ -63,42 +63,5 @@ describe("selectors", () => { assert.deepEqual(state.TopSites.rows, rows.concat(firstRunData.TopSites).slice(0, TOP_SITES_DEFAULT_LENGTH)); }); }); - - // Note that this is for Weighted Highlights turned ON (see setup function) - describe("Highlights", () => { - it("should have a length of HIGHLIGHTS_LENGTH", () => { - assert.lengthOf(state.Highlights.rows, HIGHLIGHTS_LENGTH); - }); - it("should render the right sites in the right order", () => { - const highlights = [{url: "http://foo1.com"}, {url: "http://www.foo2.com"}, {url: "http://www.foo3.com"}, - {url: "http://foo4.com"}, {url: "http://www.foo5.com"}, {url: "http://www.foo6.com"}]; - setup({Highlights: highlights}); - assert.lengthOf(state.Highlights.rows, highlights.length); - highlights.forEach((item, i) => { - assert.equal(state.Highlights.rows[i].url, item.url); - }); - }); - it("should show available data if fewer than MIN_HIGHLIGHTS_LENGTH", () => { - setup({Highlights: [{url: "http://foo.com"}, {url: "http://www.bar.com"}]}); - assert.lengthOf(state.Highlights.rows, 2); - }); - it("should internally dedupe", () => { - setup({Highlights: [{url: "https://foo.com", cache_key: "foo.com/"}, {url: "http://www.foo.com", cache_key: "foo.com/"}]}); - assert.lengthOf(state.Highlights.rows, 1); - assert.equal(state.Highlights.rows[0].url, "https://foo.com"); - }); - it("should dedupe against TopSites", () => { - setup({ - TopSites: [{url: "https://foo.com"}], - Highlights: [{url: "https://foo.com"}, {url: "https://bar.com"}] - }); - assert.lengthOf(state.Highlights.rows, 1); - assert.equal(state.Highlights.rows[0].url, "https://bar.com"); - }); - it("should be processed by assignImageAndBackgroundColor", () => { - setup({Highlights: [{url: "http://asdad23asd.com", background_color: [0, 0, 0]}]}); - assert.equal(state.Highlights.rows[0].backgroundColor, "rgb(0, 0, 0)"); - }); - }); }); }); diff --git a/content-test/components/Bookmarks.story.js b/content-test/components/Bookmarks.story.js index 34539bfa5b..6fc61ec816 100644 --- a/content-test/components/Bookmarks.story.js +++ b/content-test/components/Bookmarks.story.js @@ -3,7 +3,7 @@ const {Bookmarks} = require("components/Bookmarks/Bookmarks"); const {storiesOf, action} = require("@kadira/storybook"); const {selectNewTabSites} = require("common/selectors/selectors"); const {createMockProvider, rawMockData, faker} = require("test/test-utils"); -const {HIGHLIGHTS_LENGTH} = require("common/constants"); +const {BOOKMARKS_LENGTH} = require("common/constants"); const Provider = createMockProvider({dispatch: action("dispatched a redux action")}); // We have to set up both faker slightly differently if we're building @@ -44,21 +44,21 @@ let fakeBookmarksItems = mockData.Bookmarks.rows; storiesOf("Highlight List", module) .add("All valid properties", () => - + ) .add("Missing a row (eg because user has insufficient history)", () => - + ) .add("Missing an item (eg because user has insufficient history)", () => - + ) .add("Placeholder view (data still loading)", () => - + ); diff --git a/content-test/components/Bookmarks.test.js b/content-test/components/Bookmarks.test.js index 471df4aa91..4adeb12be0 100644 --- a/content-test/components/Bookmarks.test.js +++ b/content-test/components/Bookmarks.test.js @@ -7,7 +7,7 @@ const ReactDOM = require("react-dom"); const TestUtils = require("react-addons-test-utils"); const {mockData, faker, renderWithProvider} = require("test/test-utils"); const fakeBookmarkItems = mockData.Bookmarks.rows; -const fakeNonBookmarkItems = mockData.Highlights.rows; +const fakeNonBookmarkItems = mockData.VisitAgain.rows; const fakeSiteWithImage = faker.createSite(); const getBestImage = require("common/getBestImage"); const {BOOKMARKS_DISPLAYED_LENGTH} = require("common/constants"); diff --git a/content-test/components/EditTopSites.test.js b/content-test/components/EditTopSites.test.js index a7a827df6d..d54db6e769 100644 --- a/content-test/components/EditTopSites.test.js +++ b/content-test/components/EditTopSites.test.js @@ -185,5 +185,7 @@ describe("TopSiteForm", () => { assert.ok(wrapper.instance().validateUrl()); wrapper.setState({"url": "mozillaorg"}); assert.isFalse(wrapper.instance().validateUrl()); + wrapper.setState({"url": "https://mozilla.invisionapp.com/d/main/#/projects/prototypes"}); + assert.ok(wrapper.instance().validateUrl()); }); }); diff --git a/content-test/components/LinkMenu.test.js b/content-test/components/LinkMenu.test.js index e66efd07f4..898e28ceca 100644 --- a/content-test/components/LinkMenu.test.js +++ b/content-test/components/LinkMenu.test.js @@ -130,7 +130,8 @@ describe("LinkMenu", () => { checkOption({ ref: "addBookmark", event: "NOTIFY_BOOKMARK_ADD", - eventData: DEFAULT_PROPS.site.url, + // Event source defined by DEFAULT_PROPS. + eventData: {url: DEFAULT_PROPS.site.url, source: "ACTIVITY_FEED"}, userEvent: "BOOKMARK_ADD" }); checkOption({ diff --git a/content-test/components/NewTabPage.test.js b/content-test/components/NewTabPage.test.js index 77c6f6bbaa..7effdb5f49 100644 --- a/content-test/components/NewTabPage.test.js +++ b/content-test/components/NewTabPage.test.js @@ -3,14 +3,14 @@ const TestUtils = require("react-addons-test-utils"); const ConnectedNewTabPage = require("components/NewTabPage/NewTabPage"); const {NewTabPage} = ConnectedNewTabPage; const TopSites = require("components/TopSites/TopSites"); -const Spotlight = require("components/Spotlight/Spotlight"); const Bookmarks = require("components/Bookmarks/Bookmarks"); +const VisitAgain = require("components/VisitAgain/VisitAgain"); const PocketStories = require("components/PocketStories/PocketStories"); const {mockData, renderWithProvider} = require("test/test-utils"); const {selectNewTabSites} = require("common/selectors/selectors"); const {connect} = require("react-redux"); const {injectIntl} = require("react-intl"); -const {BOOKMARKS_DISPLAYED_LENGTH} = require("common/constants"); +const {BOOKMARKS_DISPLAYED_LENGTH, VISITAGAIN_DISPLAYED_LENGTH} = require("common/constants"); const fakeProps = Object.assign({}, {intl: {formatMessage: () => {}}}, mockData); @@ -65,29 +65,26 @@ describe("NewTabPage", () => { assert.equal(topSites.props.sites, fakeProps.TopSites.rows); }); - it("should render Spotlight components with correct data", () => { - const spotlightSites = TestUtils.findRenderedComponentWithType(instance, Spotlight); - assert.equal(spotlightSites.props.sites, fakeProps.Highlights.rows); - }); - it("should render Stories components with correct data", () => { const storiesComponent = TestUtils.findRenderedComponentWithType(instance, PocketStories); assert.equal(storiesComponent.props.stories, fakeProps.PocketStories.rows); }); + it("should render VisitAgain component with correct data", () => { + const comp = TestUtils.findRenderedComponentWithType(instance, VisitAgain); + assert.equal(comp.props.sites, fakeProps.VisitAgain.rows); + }); + it("should render connected component with correct props", () => { const container = renderWithProvider(); const inner = TestUtils.findRenderedComponentWithType(container, NewTabPage); Object.keys(NewTabPage.propTypes).forEach(key => assert.property(inner.props, key)); }); - it("should pass placeholder=true to Spotlight, Stories, TopSites and Bookmarks when isReady is false", () => { + it("should pass placeholder=true to Stories, TopSites and Bookmarks when isReady is false", () => { instance = renderWithProvider( {}} />); - let spotlight = TestUtils.findRenderedComponentWithType(instance, Spotlight); - assert.equal(spotlight.props.placeholder, true); - let stories = TestUtils.findRenderedComponentWithType(instance, PocketStories); assert.equal(stories.props.placeholder, true); @@ -96,16 +93,16 @@ describe("NewTabPage", () => { let bookmarks = TestUtils.findRenderedComponentWithType(instance, Bookmarks); assert.equal(bookmarks.props.placeholder, true); + + let visitAgain = TestUtils.findRenderedComponentWithType(instance, VisitAgain); + assert.equal(visitAgain.props.placeholder, true); }); - it("should pass placeholder=false to Spotlight, Stories, TopSites and Bookmarks when isReady is true", () => { + it("should pass placeholder=false to Stories, TopSites and Bookmarks when isReady is true", () => { let propsWithIsReadyTrue = Object.assign({}, fakeProps, {isReady: true}); instance = renderWithProvider( {}} />); - let spotLight = TestUtils.findRenderedComponentWithType(instance, Spotlight); - assert.equal(spotLight.props.placeholder, false); - let stories = TestUtils.findRenderedComponentWithType(instance, PocketStories); assert.equal(stories.props.placeholder, false); @@ -114,6 +111,9 @@ describe("NewTabPage", () => { let bookmarks = TestUtils.findRenderedComponentWithType(instance, Bookmarks); assert.equal(bookmarks.props.placeholder, false); + + let visitAgain = TestUtils.findRenderedComponentWithType(instance, VisitAgain); + assert.equal(visitAgain.props.placeholder, false); }); it("should show the Bookmarks section when showBookmarks is true", () => { @@ -140,6 +140,30 @@ describe("NewTabPage", () => { assert.equal(comp.props.length, BOOKMARKS_DISPLAYED_LENGTH); }); + it("should show the VisitAgain section when showVisitAgain is true", () => { + let props = Object.assign({}, fakeProps, {isReady: true, Prefs: {prefs: {showVisitAgain: true}}}); + instance = renderWithProvider( {}} />); + + const children = TestUtils.scryRenderedComponentsWithType(instance, VisitAgain); + assert.equal(children.length, 1); + }); + + it("should hide the VisitAgain section when showVisitAgain is false", () => { + let props = Object.assign({}, fakeProps, {isReady: true, Prefs: {prefs: {showVisitAgain: false}}}); + instance = renderWithProvider( {}} />); + + const children = TestUtils.scryRenderedComponentsWithType(instance, VisitAgain); + assert.equal(children.length, 0); + }); + + it("should pass correct length prop to VisitAgain component", () => { + let propsWithIsReadyTrue = Object.assign({}, fakeProps, {isReady: true}); + instance = renderWithProvider( {}} />); + + const comp = TestUtils.findRenderedComponentWithType(instance, VisitAgain); + assert.equal(comp.props.length, VISITAGAIN_DISPLAYED_LENGTH); + }); + describe("delete events", () => { it("should have the correct page, source, index for top site delete menu", done => { setupConnected(a => { @@ -155,20 +179,6 @@ describe("NewTabPage", () => { const deleteLink = TestUtils.scryRenderedDOMComponentsWithClass(item, "context-menu-link")[0]; TestUtils.Simulate.click(deleteLink); }); - it("should have the correct page, source, index for spotlight delete menu", done => { - setupConnected(a => { - if (a.type === "NOTIFY_USER_EVENT") { - assert.equal(a.data.page, "NEW_TAB"); - assert.equal(a.data.source, "FEATURED"); - assert.equal(a.data.action_position, 0); - assert.equal(a.data.metadata_source, "EmbedlyTest"); - done(); - } - }); - const item = TestUtils.findRenderedComponentWithType(instance, Spotlight); - const deleteLink = TestUtils.scryRenderedDOMComponentsWithClass(item, "context-menu-link")[0]; - TestUtils.Simulate.click(deleteLink); - }); }); describe("loader events", () => { @@ -187,7 +197,6 @@ describe("NewTabPage", () => { it("should fire an event if data is ready", done => { renderWithProvider( { if (a.type === "NOTIFY_NEWTAB_STATS") { - assert.equal(a.data.highlightsSize, mockData.Highlights.rows.length); assert.equal(a.data.topsitesSize, mockData.TopSites.rows.length); assert.equal(a.data.topsitesTippytop, 0); assert.equal(a.data.topsitesScreenshot, 0); diff --git a/content-test/components/PocketStories.test.js b/content-test/components/PocketStories.test.js index f090471003..1f760c5ec3 100644 --- a/content-test/components/PocketStories.test.js +++ b/content-test/components/PocketStories.test.js @@ -54,6 +54,11 @@ describe("PocketStories", () => { el = ReactDOM.findDOMNode(emptyInstance); assert.notOk(el); }); + it("should pass correct source value to SpotlightItems", () => { + const children = TestUtils.scryRenderedComponentsWithType(instance, SpotlightItem); + + assert.equal(children[0].props.source, "RECOMMENDED"); + }); }); describe("actions", () => { diff --git a/content-test/components/PreferencesPane.test.js b/content-test/components/PreferencesPane.test.js index d840860ce8..4b4adce96c 100644 --- a/content-test/components/PreferencesPane.test.js +++ b/content-test/components/PreferencesPane.test.js @@ -5,7 +5,6 @@ const DEFAULT_PREFS = { "showSearch": true, "showTopSites": true, "showMoreTopSites": false, - "showHighlights": true, "showPocket": false }; @@ -47,11 +46,6 @@ describe("PreferencesPane", () => { assert.isFalse(wrapper.ref("showMoreTopSites").prop("checked")); }); - it("the highlights checkbox should be checked by default", () => { - wrapper.ref("prefs-button").simulate("click"); - assert.isTrue(wrapper.ref("showHighlightsCheckbox").prop("checked")); - }); - it("the search checkbox should be unchecked if pref is off", () => { setup({showSearch: false}); wrapper.ref("prefs-button").simulate("click"); @@ -70,12 +64,6 @@ describe("PreferencesPane", () => { assert.isTrue(wrapper.ref("showMoreTopSites").prop("checked")); }); - it("the highlights checkbox should be unchecked if pref is off", () => { - setup({showHighlights: false}); - wrapper.ref("prefs-button").simulate("click"); - assert.isFalse(wrapper.ref("showHighlightsCheckbox").prop("checked")); - }); - it("the sidebar should be closed when done button is clicked", () => { wrapper.ref("prefs-button").simulate("click"); assert.isFalse(wrapper.ref("sidebar").hasClass("hidden")); diff --git a/content-test/components/Spotlight-unweighted.story.js b/content-test/components/Spotlight-unweighted.story.js deleted file mode 100644 index 0f59b8e737..0000000000 --- a/content-test/components/Spotlight-unweighted.story.js +++ /dev/null @@ -1,49 +0,0 @@ -const React = require("react"); -const {Spotlight} = require("components/Spotlight/Spotlight"); -const {storiesOf, action} = require("@kadira/storybook"); -const {createMockProvider} = require("../test-utils"); -const {mockData, faker} = require("test/test-utils"); -const Provider = createMockProvider({dispatch: action("dispatched a redux action")}); - -// We have to set up both faker slightly differently if we're building -// statically (eg for storybooks.io). In theory, we should need to run -// the faker thing from any story file that uses faker, but for whatever -// reason, that doesn't seem to actually be true. I'd guess that webpack -// somehow optimizes things so that there's only a single copy of faker -// in memory at once. Interestingly, putting this code in config.js doesn't -// work at all. - -// Note that process.env.STORYBOOK_* variables are injected by storybook -// via webpack. -if (process.env.STORYBOOK_STATIC) { - faker.base_tip_top_favicon_prefix = "content/"; -} - -// 698px = $wrapper-max-width + 2 (presumably for the border) -const style = {width: "698px"}; - -// XXX should get rid of container here. See comment in ContextMenu.story -// for details. -const Container = props => ( - -
- {props.children} -
-
-); - -// Note that if a site image is not in the cache, it can take a while -// (eg 10 seconds) to load, because the image load starts very late, for -// unclear reasons. Presumably something to do with faker, tippy-top-sites, -// lorempixel (used by faker for the images), or Spotlight (aka Highlight) -// itself. - -// the normal, unweighted data -const fakeSpotlightItems = mockData.Highlights.rows; - -storiesOf("Highlight List (unweighted)", module) - .add("All valid properties", () => - - - - ); diff --git a/content-test/components/Spotlight.story.js b/content-test/components/Spotlight.story.js deleted file mode 100644 index 26c07c8da5..0000000000 --- a/content-test/components/Spotlight.story.js +++ /dev/null @@ -1,108 +0,0 @@ -const React = require("react"); -const {Spotlight, SpotlightItem} = require("components/Spotlight/Spotlight"); -const {storiesOf, action} = require("@kadira/storybook"); -const {selectNewTabSites} = require("common/selectors/selectors"); -const {createMockProvider, rawMockData, faker} = require("test/test-utils"); -const {HIGHLIGHTS_LENGTH} = require("common/constants"); -const createSite = faker.createSite; -const Provider = createMockProvider({dispatch: action("dispatched a redux action")}); - -// We have to set up both faker slightly differently if we're building -// statically (eg for storybooks.io). In theory, we should need to run -// the faker thing from any story file that uses faker, but for whatever -// reason, that doesn't seem to actually be true. I'd guess that webpack -// somehow optimizes things so that there's only a single copy of faker -// in memory at once. Interestingly, putting this code in config.js doesn't -// work at all. - -// Note that process.env.STORYBOOK_* variables are injected by storybook -// via webpack. -if (process.env.STORYBOOK_STATIC) { - faker.base_tip_top_favicon_prefix = "content/"; -} - -// XXX should get rid of container here. See comment in ContextMenu.story -// for details. - -// 698px = $wrapper-max-width + 2 (presumably for the border) -const style = {width: "698px"}; -const Container = props => ( - -
- {props.children} -
-
-); - -// Note that if a site image is not in the cache, it can take a while -// (eg 10 seconds) to load, because the image load starts very late, for -// unclear reasons. Presumably something to do with faker, tippy-top-sites, -// lorempixel (used by faker for the images), or Spotlight (aka Highlight) -// itself. -let mockData = Object.assign({}, rawMockData, selectNewTabSites(rawMockData)); -let fakeSpotlightItems = mockData.Highlights.rows; - -storiesOf("Highlight List", module) - .add("All valid properties", () => - - - - ) - .add("Missing a row (eg because user has insufficient history)", () => - - - - ) - .add("Missing an item (eg because user has insufficient history)", () => - - - - ) - .add("Placeholder view (data still loading)", () => - - - - ); - -storiesOf("Highlight Item", module) - .add("All valid properties", () => { - const site = createSite({images: 1}); - site.bestImage = site.images[0]; - return (); - }) - .add("Title overflows text area", () => { - const site = createSite({images: 1}); - site.bestImage = site.images[0]; - site.title = "The Most Awesome Aggregator Site You're Ever Going To See On The Entire English-Speaking Part World Wide Web"; - return (); - }) - .add("Title + desc overflows text area", () => { - const site = createSite({images: 1}); - site.bestImage = site.images[0]; - site.title = "The Most Awesome Aggregator Site You're Ever Going To See"; - site.description = "The quick brown fox jumps over the laziest dog"; - return (); - }) - .add("Missing provider_name metadata", () => { - const site = createSite({images: 1}); - site.bestImage = site.images[0]; - delete site.provider_name; - return (); - }) - .add("Missing an image", () => { - const site = createSite({images: 0}); - return (); - }) - .add("Missing a favicon_url", () => { - const site = createSite({images: 1}); - site.bestImage = site.images[0]; - site.favicon_url = null; - site.background_color = null; - return (); - }) - .add("Missing a description", () => { - const site = createSite({images: 1}); - site.bestImage = site.images[0]; - site.description = null; - return (); - }); diff --git a/content-test/components/Spotlight.test.js b/content-test/components/Spotlight.test.js index a9407872bd..da6fe6c36c 100644 --- a/content-test/components/Spotlight.test.js +++ b/content-test/components/Spotlight.test.js @@ -1,5 +1,5 @@ const ConnectedSpotlight = require("components/Spotlight/Spotlight"); -const {PlaceholderSpotlightItem, Spotlight, SpotlightItem} = ConnectedSpotlight; +const {PlaceholderSpotlightItem, SpotlightItem} = ConnectedSpotlight; const getHighlightContextFromSite = require("common/selectors/getHighlightContextFromSite"); const LinkMenu = require("components/LinkMenu/LinkMenu"); const LinkMenuButton = require("components/LinkMenuButton/LinkMenuButton"); @@ -8,51 +8,12 @@ const React = require("react"); const ReactDOM = require("react-dom"); const TestUtils = require("react-addons-test-utils"); const {shallow} = require("enzyme"); -const {mockData, mountWithProvider, faker, renderWithProvider} = require("test/test-utils"); -const fakeSpotlightItems = mockData.Highlights.rows; +const {mountWithProvider, faker, renderWithProvider} = require("test/test-utils"); const fakeSiteWithImage = faker.createSite(); const {prettyUrl} = require("lib/utils"); fakeSiteWithImage.bestImage = fakeSiteWithImage.images[0]; -describe("Spotlight", () => { - let instance; - let el; - - describe("valid sites", () => { - beforeEach(() => { - instance = renderWithProvider(); - el = ReactDOM.findDOMNode(instance); - }); - - it("should create the element", () => { - assert.ok(el); - }); - it("should render a SpotlightItem for each item", () => { - const children = TestUtils.scryRenderedComponentsWithType(instance, SpotlightItem); - assert.equal(children.length, 3); - }); - }); - - describe("actions", () => { - it("should fire a click event when an item is clicked", done => { - function dispatch(a) { - if (a.type === "NOTIFY_USER_EVENT") { - assert.equal(a.data.event, "CLICK"); - assert.equal(a.data.page, "NEW_TAB"); - assert.equal(a.data.source, "FEATURED"); - assert.equal(a.data.action_position, 0); - assert.equal(a.data.metadata_source, "EmbedlyTest"); - assert.equal(a.data.highlight_type, fakeSpotlightItems[0].type); - done(); - } - } - instance = renderWithProvider(); - TestUtils.Simulate.click(TestUtils.scryRenderedComponentsWithType(instance, SpotlightItem)[0].refs.link); - }); - }); -}); - describe("SpotlightItem", () => { const fakeSite = fakeSiteWithImage; let instance; diff --git a/content-test/components/VisitAgain.test.js b/content-test/components/VisitAgain.test.js new file mode 100644 index 0000000000..a8767d5468 --- /dev/null +++ b/content-test/components/VisitAgain.test.js @@ -0,0 +1,112 @@ +const ConnectedSpotlight = require("components/Spotlight/Spotlight"); +const ConnectedVisitAgain = require("components/VisitAgain/VisitAgain"); +const {SpotlightItem} = ConnectedSpotlight; +const {VisitAgain} = ConnectedVisitAgain; +const React = require("react"); +const ReactDOM = require("react-dom"); +const TestUtils = require("react-addons-test-utils"); +const {mockData, renderWithProvider} = require("test/test-utils"); +const fakeVisitAgainItems = mockData.VisitAgain.rows; +const {VISITAGAIN_DISPLAYED_LENGTH} = require("common/constants"); +const getBestImage = require("common/getBestImage"); +const CollapsibleSection = require("components/CollapsibleSection/CollapsibleSection"); + +describe("Bookmarks", () => { + let instance; + let el; + let stubDispatcher; + + describe("valid sites", () => { + beforeEach(() => { + stubDispatcher = sinon.stub(); + instance = renderWithProvider(); + el = ReactDOM.findDOMNode(instance); + }); + + it("should create the element", () => { + assert.ok(el); + }); + it("should not render if placeholder prop is true", () => { + instance = renderWithProvider(); + el = ReactDOM.findDOMNode(instance); + assert.equal(el, null); + }); + it("should not render if there are no items to display", () => { + instance = renderWithProvider(); + el = ReactDOM.findDOMNode(instance); + assert.equal(el, null); + }); + it("should render correct number of SpotlightItems", () => { + const children = TestUtils.scryRenderedComponentsWithType(instance, SpotlightItem); + + // Make sure more than VISITAGAIN_DISPLAY_LENGTH sites are provided and + // component actually slices down to the correct number. + assert.isTrue(instance.props.sites.length > VISITAGAIN_DISPLAYED_LENGTH); + assert.equal(children.length, VISITAGAIN_DISPLAYED_LENGTH); + }); + it("should provide `VISITAGAIN` source prop to SpotlightItems", () => { + let i; + instance = renderWithProvider(); + + const children = TestUtils.scryRenderedComponentsWithType(instance, SpotlightItem); + + for (i = 0; i < children.length; i++) { + assert.equal(children[i].props.source, "VISITAGAIN"); + } + }); + it("should provide bestImage prop to SpotlightItems", () => { + let i; + instance = renderWithProvider(); + const children = TestUtils.scryRenderedComponentsWithType(instance, SpotlightItem); + for (i = 0; i < children.length; i++) { + assert.equal(children[i].props.bestImage, getBestImage(fakeVisitAgainItems[i].images)); + } + }); + it("should pass props.prefs to CollapsibleSection component", () => { + instance = renderWithProvider(); + + const comp = TestUtils.findRenderedComponentWithType(instance, CollapsibleSection); + + assert.deepEqual(comp.props.prefs, instance.props.prefs); + }); + it("should pass `collapseVisitAgain` to CollapsibleSection component", () => { + instance = renderWithProvider(); + + const comp = TestUtils.findRenderedComponentWithType(instance, CollapsibleSection); + + assert.equal(comp.props.prefName, "collapseVisitAgain"); + }); + }); + + describe("actions", () => { + it("should fire a click event when an item is clicked", done => { + function dispatch(a) { + if (a.type === "NOTIFY_USER_EVENT") { + assert.equal(a.data.event, "CLICK"); + assert.equal(a.data.page, "NEW_TAB"); + assert.equal(a.data.source, "VISITAGAIN"); + assert.equal(a.data.action_position, 0); + assert.equal(a.data.metadata_source, "EmbedlyTest"); + assert.equal(a.data.highlight_type, fakeVisitAgainItems[0].type); + done(); + } + } + instance = renderWithProvider(); + TestUtils.Simulate.click(TestUtils.scryRenderedComponentsWithType(instance, SpotlightItem)[0].refs.link); + }); + }); +}); diff --git a/docs/v1-test-pilot/data_dictionary.md b/docs/v1-test-pilot/data_dictionary.md index 55352d0094..6b2df59970 100644 --- a/docs/v1-test-pilot/data_dictionary.md +++ b/docs/v1-test-pilot/data_dictionary.md @@ -27,7 +27,6 @@ The Activity Stream addon sends various types of pings to the backend (HTTPS POS "total_history_size": 9, "ua": "python-requests/2.9.1", "unload_reason": "close", - "highlights_size": 20, "topsites_size": 6, "topsites_screenshot": 1, "topsites_tippytop": 3, @@ -115,7 +114,7 @@ The Activity Stream addon sends various types of pings to the backend (HTTPS POS | `client_id` | [Required] An identifier for this client. | :one: | `date` | [Auto populated by Onyx] The date in YYYY-MM-DD format. | :three: | `experiment_id` | [Optional] The unique identifier for a specific experiment. | :one: -| `event_id` | [Required] An identifier shared by multiple performance pings that describe ane entire request flow. | :one: +| `event_id` | [Required] An identifier shared by multiple performance pings that describe an entire request flow. | :one: | `event` | [Required] The type of event. Any user defined string ("click", "share", "delete", "more_items") | :one: | `highlight_type` | [Optional] Either ["bookmarks", "recommendation", "history"]. | :one: | `ip` | [Auto populated by Onyx] The IP address of the client. | :two: @@ -138,7 +137,6 @@ The Activity Stream addon sends various types of pings to the backend (HTTPS POS | `url` | [Optional] The URL of the recommendation shown in one of the highlights spots, if any. | :one: | `value` | [Required] An integer that represents the measured performance value. Can store counts, times in milliseconds, and should always be a positive integer.| :one: | `ver` | [Auto populated by Onyx] The version of the Onyx API the ping was sent to. | :one: -| `highlights_size` | [Optional] The size of the Highlights set. | :one: | `topsites_size` | [Optional] The size of the Topsites set. | :one: | `topsites_screenshot` | [Optional] The size of the Topsites set with screenshot metadata. | :one: | `topsites_tippytop` | [Optional] The size of the Topsites set with TippyTop metadata. | :one: @@ -157,7 +155,6 @@ The Activity Stream addon sends various types of pings to the backend (HTTPS POS | --- | --- | | `showSearch` | 1 | | `showTopSites` | 2 | -| `showHighlights` | 4 | | `showMoreTopSites` | 8 | | `showPocket` | 16 | diff --git a/docs/v1-test-pilot/data_events.md b/docs/v1-test-pilot/data_events.md index 661392a2ab..5d8c5c0bce 100644 --- a/docs/v1-test-pilot/data_events.md +++ b/docs/v1-test-pilot/data_events.md @@ -33,6 +33,7 @@ A user event ping includes some basic metadata (tab id, addon version, etc.) as // Basic metadata   "tab_id": "-5-2",   "client_id": "26288a14-5cc4-d14f-ae0a-bb01ef45be9c", + "session_id": "005deed0-e3e4-4c02-a041-17405fd703f6",   "addon_version": "1.0.12",   "locale": "en-US", "action": "activity_stream_event", @@ -53,6 +54,7 @@ A user event ping includes some basic metadata (tab id, addon version, etc.) as   "action": "activity_stream_event",   "tab_id": "-5-2",   "client_id": "26288a14-5cc4-d14f-ae0a-bb01ef45be9c", + "session_id": "005deed0-e3e4-4c02-a041-17405fd703f6",   "addon_version": "1.0.12",   "locale": "en-US" } @@ -69,6 +71,7 @@ A user event ping includes some basic metadata (tab id, addon version, etc.) as   "action": "activity_stream_event",   "tab_id": "-5-3",   "client_id": "26288a14-5cc4-d14f-ae0a-bb01ef45be9c", + "session_id": "005deed0-e3e4-4c02-a041-17405fd703f6",   "addon_version": "1.0.12",   "locale": "en-US", "metadata_source": ["MetadataService" | "Local" | "TippyTopProvider"], @@ -91,6 +94,7 @@ A user event ping includes some basic metadata (tab id, addon version, etc.) as   "action": "activity_stream_event",   "tab_id": "-3-13",   "client_id": "83982d21-4f49-eb44-a3ed-8e9ac6f87b05", + "session_id": "005deed0-e3e4-4c02-a041-17405fd703f6",   "addon_version": "1.0.12",   "locale": "en-US", "metadata_source": ["MetadataService" | "Local" | "TippyTopProvider"] @@ -107,6 +111,7 @@ A user event ping includes some basic metadata (tab id, addon version, etc.) as   "action": "activity_stream_event",   "tab_id": "-5-3",   "client_id": "26288a14-5cc4-d14f-ae0a-bb01ef45be9c", + "session_id": "005deed0-e3e4-4c02-a041-17405fd703f6",   "addon_version": "1.0.12",   "locale": "en-US", } @@ -123,6 +128,7 @@ A user event ping includes some basic metadata (tab id, addon version, etc.) as   "action": "activity_stream_event",   "tab_id": "-5-4",   "client_id": "26288a14-5cc4-d14f-ae0a-bb01ef45be9c", + "session_id": "005deed0-e3e4-4c02-a041-17405fd703f6",   "addon_version": "1.0.12",   "locale": "en-US", "metadata_source": ["MetadataService" | "Local" | "TippyTopProvider"], @@ -145,6 +151,7 @@ A user event ping includes some basic metadata (tab id, addon version, etc.) as   "action": "activity_stream_event",   "tab_id": "-3-16",   "client_id": "83982d21-4f49-eb44-a3ed-8e9ac6f87b05", + "session_id": "005deed0-e3e4-4c02-a041-17405fd703f6",   "addon_version": "1.0.12",   "locale": "en-US" } @@ -163,6 +170,7 @@ It doesn't capture success or failure to share after.   "action": "activity_stream_event",   "tab_id": "-3-16",   "client_id": "83982d21-4f49-eb44-a3ed-8e9ac6f87b05", + "session_id": "005deed0-e3e4-4c02-a041-17405fd703f6",   "addon_version": "1.0.12",   "locale": "en-US" } @@ -178,6 +186,7 @@ It doesn't capture success or failure to share after.   "action": "activity_stream_event",   "tab_id": "-5-3",   "client_id": "26288a14-5cc4-d14f-ae0a-bb01ef45be9c", + "session_id": "005deed0-e3e4-4c02-a041-17405fd703f6",   "addon_version": "1.0.12",   "locale": "en-US", } @@ -193,6 +202,7 @@ It doesn't capture success or failure to share after.   "action": "activity_stream_event",   "tab_id": "-5-3",   "client_id": "26288a14-5cc4-d14f-ae0a-bb01ef45be9c", + "session_id": "005deed0-e3e4-4c02-a041-17405fd703f6",   "addon_version": "1.0.12",   "locale": "en-US", } @@ -208,6 +218,7 @@ It doesn't capture success or failure to share after.   "action": "activity_stream_event",   "tab_id": "-5-3",   "client_id": "26288a14-5cc4-d14f-ae0a-bb01ef45be9c", + "session_id": "005deed0-e3e4-4c02-a041-17405fd703f6",   "addon_version": "1.0.12",   "locale": "en-US", } @@ -223,6 +234,7 @@ It doesn't capture success or failure to share after.   "action": "activity_stream_event",   "tab_id": "-5-3",   "client_id": "26288a14-5cc4-d14f-ae0a-bb01ef45be9c", + "session_id": "005deed0-e3e4-4c02-a041-17405fd703f6",   "addon_version": "1.0.12",   "locale": "en-US", } @@ -239,6 +251,7 @@ It doesn't capture success or failure to share after.   "action": "activity_stream_event",   "tab_id": "-5-4",   "client_id": "26288a14-5cc4-d14f-ae0a-bb01ef45be9c", + "session_id": "005deed0-e3e4-4c02-a041-17405fd703f6",   "addon_version": "1.0.12",   "locale": "en-US", "metadata_source": ["MetadataService" | "Local" | "TippyTopProvider"], @@ -256,6 +269,7 @@ It doesn't capture success or failure to share after.   "action": "activity_stream_event",   "tab_id": "-5-4",   "client_id": "26288a14-5cc4-d14f-ae0a-bb01ef45be9c", + "session_id": "005deed0-e3e4-4c02-a041-17405fd703f6",   "addon_version": "1.0.12",   "locale": "en-US", "metadata_source": ["MetadataService" | "Local" | "TippyTopProvider"], @@ -272,6 +286,7 @@ It doesn't capture success or failure to share after.   "action": "activity_stream_event",   "tab_id": "-5-3",   "client_id": "26288a14-5cc4-d14f-ae0a-bb01ef45be9c", + "session_id": "005deed0-e3e4-4c02-a041-17405fd703f6",   "addon_version": "1.0.12",   "locale": "en-US", } @@ -287,6 +302,7 @@ It doesn't capture success or failure to share after.   "action": "activity_stream_event",   "tab_id": "-5-3",   "client_id": "26288a14-5cc4-d14f-ae0a-bb01ef45be9c", + "session_id": "005deed0-e3e4-4c02-a041-17405fd703f6",   "addon_version": "1.0.12",   "locale": "en-US", } @@ -302,6 +318,7 @@ It doesn't capture success or failure to share after.   "action": "activity_stream_event",   "tab_id": "-5-3",   "client_id": "26288a14-5cc4-d14f-ae0a-bb01ef45be9c", + "session_id": "005deed0-e3e4-4c02-a041-17405fd703f6",   "addon_version": "1.0.12",   "locale": "en-US", } @@ -318,6 +335,7 @@ It doesn't capture success or failure to share after.   "action": "activity_stream_event",   "tab_id": "-5-3",   "client_id": "26288a14-5cc4-d14f-ae0a-bb01ef45be9c", + "session_id": "005deed0-e3e4-4c02-a041-17405fd703f6",   "addon_version": "1.0.12",   "locale": "en-US", } @@ -334,6 +352,7 @@ It doesn't capture success or failure to share after.   "action": "activity_stream_event",   "tab_id": "-5-3",   "client_id": "26288a14-5cc4-d14f-ae0a-bb01ef45be9c", + "session_id": "005deed0-e3e4-4c02-a041-17405fd703f6",   "addon_version": "1.0.12",   "locale": "en-US", } @@ -350,6 +369,7 @@ It doesn't capture success or failure to share after.   "action": "activity_stream_event",   "tab_id": "-5-3",   "client_id": "26288a14-5cc4-d14f-ae0a-bb01ef45be9c", + "session_id": "005deed0-e3e4-4c02-a041-17405fd703f6",   "addon_version": "1.0.12",   "locale": "en-US", } @@ -375,12 +395,12 @@ All `"activity_stream_session"` pings have the following basic shape. Some field "tab_id": "-5-2", "load_latency": 774, "client_id": "26288a14-5cc4-d14f-ae0a-bb01ef45be9c", + "session_id": "005deed0-e3e4-4c02-a041-17405fd703f6", "addon_version": "1.0.12", "locale": "en-US", "page": ["NEW_TAB" | "HOME"], "action": "activity_stream_session", "session_duration": 4199, - "highlights_size": 20, "topsites_size": 6, "topsites_screenshot": 1, "topsites_tippytop": 3, @@ -405,21 +425,6 @@ In some undesired app states, the app will send a ping about it to our metrics s ### Types of bad states -#### Highlight without an image - -```js -{ - "event": "MISSING_IMAGE", - "source": "HIGHLIGHTS", - "page": "NEW_TAB", - "action": "activity_stream_masga_event", - "tab_id": "-5-2", - "client_id": "26288a14-5cc4-d14f-ae0a-bb01ef45be9c", - "addon_version": "1.0.12", - "locale": "en-US" -} -``` - #### Show loader ```js @@ -430,6 +435,7 @@ In some undesired app states, the app will send a ping about it to our metrics s "action": "activity_stream_masga_event", "tab_id": "-5-2", "client_id": "26288a14-5cc4-d14f-ae0a-bb01ef45be9c", + "session_id": "005deed0-e3e4-4c02-a041-17405fd703f6", "addon_version": "1.0.12", "locale": "en-US" } @@ -446,6 +452,7 @@ In some undesired app states, the app will send a ping about it to our metrics s "action": "activity_stream_masga_event", "tab_id": "-5-2", "client_id": "26288a14-5cc4-d14f-ae0a-bb01ef45be9c", + "session_id": "005deed0-e3e4-4c02-a041-17405fd703f6", "addon_version": "1.0.12", "locale": "en-US" } @@ -462,6 +469,7 @@ Note that it re-uses the same payload [schema](https://github.com/mozilla/infern "source": "pocket", "action": "activity_stream_impression", "client_id": "26288a14-5cc4-d14f-ae0a-bb01ef45be9c", + "session_id": "005deed0-e3e4-4c02-a041-17405fd703f6", "addon_version": "1.0.12", "locale": "en-US", // `id` is the GUID of the recommended item @@ -476,6 +484,7 @@ Note that it re-uses the same payload [schema](https://github.com/mozilla/infern "source": "pocket", "action": "activity_stream_impression", "client_id": "26288a14-5cc4-d14f-ae0a-bb01ef45be9c", + "session_id": "005deed0-e3e4-4c02-a041-17405fd703f6", "addon_version": "1.0.12", "locale": "en-US", // `user_action`: `[click|pocket|block]`, the value is the 0-based index of the `tiles` array diff --git a/docs/v2-system-addon/1.GETTING_STARTED.md b/docs/v2-system-addon/1.GETTING_STARTED.md index f1f29ce323..52d12cfb50 100644 --- a/docs/v2-system-addon/1.GETTING_STARTED.md +++ b/docs/v2-system-addon/1.GETTING_STARTED.md @@ -1,34 +1,60 @@ # Activity Stream (System add-on) +## Contents of this guide + +- Installation, set-up, and other basics (this page) +- [Writing unit tests](./unit_testing_guide.md) +- [Adding new Telemetry (user and performance metrics)](./telemetry.md) +- [Reading/changing Firefox prefs](./preferences.md) +- [Adding new sections](./sections.md) + ## Where to ask questions - Most of the core dev team can be found on the `#activity-stream` mozilla irc channel. - You can also direct message the core team (`dmose`, `emtwo`, `jkerim`, `k88hudson`, `Mardak`, `nanj`, `r1cky`, `ursula`) + You can also direct message the core team (`dmose`, `emtwo`, `jkerim`, `k88hudson`, `Mardak`, `nanj`, `r1cky`, `ursula`, `andreio`) or our manager (`tspurway`) - Our Mozilla slack channel is #activitystream - File issues/questions on Github: https://github.com/mozilla/activity-stream/issues. We typically triage new issues every Monday. -## Testing in Firefox Nightly +## How to try Activity Stream -If you just want to see the current version of Activity Stream in Firefox, you can +If you just want to try out the current version of Activity Stream in Firefox, you can install [Firefox Nightly](https://www.mozilla.org/en-US/firefox/channel/desktop/#nightly) go to `about:config`, and set the `browser.newtabpage.activity-stream.enabled` pref to `true`. +## Source code and submitting pull requests + +Inside this repository, there are two versions of Activity Stream; the **test pilot version** (v1) +and the **system add-on version** (v2). + +These docs refer to the **system add-on version**, which is the production version +of Activity Stream that is included with Firefox. The latest copy of the source code +for this version can be found in the [system-addon/](../../system-addon/) subdirectory. +You can ignore the other directories/files in the repository. + +A copy of this code is exported to Mozilla central on a regular basis, which can +be found at [browser/extensions/activity-stream](https://searchfox.org/mozilla-central/source/browser/extensions/activity-stream). +Keep in mind that some of these files are generated, so if you intend on editing any files, you should +do so in the Github version. + +Pull requests should be sent against the master branch of https://github.com/mozilla/activity-stream, +NOT against Mozilla central. + ## Prerequisites for development -### Operating system +### Operating system and software The Activity Stream development environment is designed to work on Mac and Linux. If you need to develop on Windows, you might want to reach out on IRC (#activity-stream) if you run into any problems. -### Software +You will also need to install: -- Node.js 6.9.1+ (On Mac, the best way to install Node.js is to use the [install link on the Node.js homepage](https://nodejs.org/en/)) +- Node.js 7+ (On Mac, the best way to install Node.js is to use the [install link on the Node.js homepage](https://nodejs.org/en/)) - npm (packaged with Node.js) -### activity-stream +### Activity Stream Github repository You will need to to clone Activity Stream to a local directory from the `master` branch of our Github repository: https://github.com/mozilla/activity-stream @@ -51,18 +77,17 @@ Check out [these docs on artifact builds](https://developer.mozilla.org/en-US/do for instructions about how to download and configure Mozilla Central if you have never done so before. -## Source code and PRs +**To build Firefox way faster**, you should definitely enable Artifact builds. +To do that, create a `.mozconfig` (or `mozconfig`) file in the root of your +mozilla-central directory and add the following to it: -The latest copy of the source code for Activity Stream can be found in the `system-addon/` -subdirectory of `activity-stream`. +```bash +# Automatically download and use compiled C++ components: +ac_add_options --enable-artifact-builds -The current version of Activity Stream that is shipped with Firefox nightly can -be found in `mozilla-central/browser/extensions/activity-stream`. Keep in mind that -some of these files are generated, so if you intend on editing any files, you should -do so in the Github version. - -PRs should be sent against the master branch of https://github.com/mozilla/activity-stream, -NOT against mozilla central. +# Write build artifacts to: +mk_add_options MOZ_OBJDIR=./objdir-frontend +``` ## Building diff --git a/docs/v2-system-addon/data_dictionary.md b/docs/v2-system-addon/data_dictionary.md index 58c9d6106c..bd4379fde5 100644 --- a/docs/v2-system-addon/data_dictionary.md +++ b/docs/v2-system-addon/data_dictionary.md @@ -1,7 +1,7 @@ # Activity Stream Pings The Activity Stream system add-on sends various types of pings to the backend (HTTPS POST) [Onyx server](https://github.com/mozilla/onyx) : -- a `session` ping that describes the ending of an Activity Stream session (lose focus event on Activity Stream), and +- a `session` ping that describes the ending of an Activity Stream session (a new tab is closed or refreshed), and - an `event` ping that records specific data about individual user interactions while interacting with Activity Stream - a `performance` ping that records specific performance related events - an `undesired` ping that records data about bad app states and missing data @@ -109,10 +109,13 @@ Schema definitions/validations that can be used for tests can be found in `syste | `highlight_type` | [Optional] Either ["bookmarks", "recommendation", "history"]. | :one: | `ip` | [Auto populated by Onyx] The IP address of the client. | :two: | `locale` | [Auto populated by Onyx] The browser chrome's language (eg. en-US). | :two: +| `load_trigger_ts` | [Optional][Server Counter][Server Alert for too many omissions] DOMHighResTimeStamp of the action perceived by the user to trigger the load of this page. | :one: +| `load_trigger_type` | [Server Counter][Server Alert for too many omissions] Either ["menu_plus_or_keyboard", "unexpected"]. | :one: | `metadata_source` | [Optional] The source of which we computed metadata. Either (`MetadataService` or `Local` or `TippyTopProvider`). | :one: | `page` | [Required] Either ["NEW_TAB", "HOME"]. | :one: | `recommender_type` | [Optional] The type of recommendation that is being shown, if any. | :one: -| `session_duration` | [Required] Defined to be the time in milliseconds between the newtab gaining and losing focus. | :one: +| `session_duration` | [Optional][Server Counter][Server Alert for too many omissions] Time in (integer) milliseconds of the difference between the new tab becoming visible +and losing focus. | :one: | `session_id` | [Optional] The unique identifier for a specific session. | :one: | `source` | [Required] Either ("recent_links", "recent_bookmarks", "frecent_links", "top_sites", "spotlight", "sidebar") and indicates what `action`. | :two: | `received_at` | [Auto populated by Onyx] The time in ms since epoch. | :three: @@ -124,11 +127,12 @@ Schema definitions/validations that can be used for tests can be found in `syste | `value` | [Required] An integer that represents the measured performance value. Can store counts, times in milliseconds, and should always be a positive integer.| :one: | `ver` | [Auto populated by Onyx] The version of the Onyx API the ping was sent to. | :one: | `highlights_size` | [Optional] The size of the Highlights set. | :one: +| `topsites_first_painted_ts` | [Optional][Service Counter][Server Alert for too many omissions] Timestamp of when the Top Sites element finished painting (possibly with only placeholder screenshots) | :one: | `topsites_size` | [Optional] The size of the Topsites set. | :one: | `topsites_screenshot` | [Optional] The size of the Topsites set with screenshot metadata. | :one: | `topsites_tippytop` | [Optional] The size of the Topsites set with TippyTop metadata. | :one: | `user_prefs` | [optional] The encoded integer of user's preferences. | :one: & :four: - +| `visibility_event_rcvd_ts` | [Optional][Server Counter][Server Alert for too many omissions] DOMHighResTimeStamp of when the page itself receives an event that document.visibilityState == visible. | :one: **Where:** diff --git a/docs/v2-system-addon/data_events.md b/docs/v2-system-addon/data_events.md index 76d51c4103..21357f5f46 100644 --- a/docs/v2-system-addon/data_events.md +++ b/docs/v2-system-addon/data_events.md @@ -21,7 +21,7 @@ A user event ping includes some basic metadata (tab id, addon version, etc.) as ```js { // This indicates the type of interaction -  "event": ["CLICK", "SEARCH", "BLOCK", "DELETE", "OPEN_NEW_WINDOW", "OPEN_PRIVATE_WINDOW", "BOOKMARK_DELETE", "BOOKMARK_ADD"], +  "event": ["CLICK", "SEARCH", "BLOCK", "DELETE", "OPEN_NEW_WINDOW", "OPEN_PRIVATE_WINDOW", "BOOKMARK_DELETE", "BOOKMARK_ADD", "OPEN_NEWTAB_PREFS", "CLOSE_NEWTAB_PREFS"], // Optional field indicating the UI component type "source": "TOP_SITES", @@ -34,6 +34,7 @@ A user event ping includes some basic metadata (tab id, addon version, etc.) as // Basic metadata "page": ["about:newtab" | "about:home"],   "client_id": "26288a14-5cc4-d14f-ae0a-bb01ef45be9c", + "session_id": "005deed0-e3e4-4c02-a041-17405fd703f6",   "addon_version": "1.0.12",   "locale": "en-US", "action": "activity_stream_event" @@ -52,6 +53,7 @@ A user event ping includes some basic metadata (tab id, addon version, etc.) as "action": "activity_stream_event", "page": ["about:newtab" | "about:home"],   "client_id": "26288a14-5cc4-d14f-ae0a-bb01ef45be9c", + "session_id": "005deed0-e3e4-4c02-a041-17405fd703f6",   "addon_version": "1.0.12",   "locale": "en-US" } @@ -69,6 +71,7 @@ A user event ping includes some basic metadata (tab id, addon version, etc.) as "action": "activity_stream_event", "page": ["about:newtab" | "about:home"], "client_id": "26288a14-5cc4-d14f-ae0a-bb01ef45be9c", + "session_id": "005deed0-e3e4-4c02-a041-17405fd703f6",   "addon_version": "1.0.12",   "locale": "en-US" } @@ -86,6 +89,7 @@ A user event ping includes some basic metadata (tab id, addon version, etc.) as "action": "activity_stream_event", "page": ["about:newtab" | "about:home"], "client_id": "26288a14-5cc4-d14f-ae0a-bb01ef45be9c", + "session_id": "005deed0-e3e4-4c02-a041-17405fd703f6",   "addon_version": "1.0.12",   "locale": "en-US" } @@ -103,6 +107,7 @@ A user event ping includes some basic metadata (tab id, addon version, etc.) as "action": "activity_stream_event", "page": ["about:newtab" | "about:home"], "client_id": "26288a14-5cc4-d14f-ae0a-bb01ef45be9c", + "session_id": "005deed0-e3e4-4c02-a041-17405fd703f6",   "addon_version": "1.0.12",   "locale": "en-US" } @@ -120,6 +125,7 @@ A user event ping includes some basic metadata (tab id, addon version, etc.) as "action": "activity_stream_event", "page": ["about:newtab" | "about:home"], "client_id": "26288a14-5cc4-d14f-ae0a-bb01ef45be9c", + "session_id": "005deed0-e3e4-4c02-a041-17405fd703f6",   "addon_version": "1.0.12",   "locale": "en-US" } @@ -137,6 +143,7 @@ A user event ping includes some basic metadata (tab id, addon version, etc.) as "action": "activity_stream_event", "page": ["about:newtab" | "about:home"], "client_id": "26288a14-5cc4-d14f-ae0a-bb01ef45be9c", + "session_id": "005deed0-e3e4-4c02-a041-17405fd703f6",   "addon_version": "1.0.12",   "locale": "en-US" } @@ -154,6 +161,7 @@ A user event ping includes some basic metadata (tab id, addon version, etc.) as "action": "activity_stream_event", "page": ["about:newtab" | "about:home"], "client_id": "26288a14-5cc4-d14f-ae0a-bb01ef45be9c", + "session_id": "005deed0-e3e4-4c02-a041-17405fd703f6",   "addon_version": "1.0.12",   "locale": "en-US" } @@ -171,6 +179,39 @@ A user event ping includes some basic metadata (tab id, addon version, etc.) as "action": "activity_stream_event", "page": ["about:newtab" | "about:home"], "client_id": "26288a14-5cc4-d14f-ae0a-bb01ef45be9c", + "session_id": "005deed0-e3e4-4c02-a041-17405fd703f6", +  "addon_version": "1.0.12", +  "locale": "en-US" +} +``` + +#### Opening the new tab preferences pane + +```js +{ +  "event": "OPEN_NEWTAB_PREFS", +   + // Basic metadata + "action": "activity_stream_event", + "page": ["about:newtab" | "about:home"], + "client_id": "26288a14-5cc4-d14f-ae0a-bb01ef45be9c", + "session_id": "005deed0-e3e4-4c02-a041-17405fd703f6", +  "addon_version": "1.0.12", +  "locale": "en-US" +} +``` + +#### Closing the new tab preferences pane + +```js +{ +  "event": "CLOSE_NEWTAB_PREFS", +   + // Basic metadata + "action": "activity_stream_event", + "page": ["about:newtab" | "about:home"], + "client_id": "26288a14-5cc4-d14f-ae0a-bb01ef45be9c", + "session_id": "005deed0-e3e4-4c02-a041-17405fd703f6",   "addon_version": "1.0.12",   "locale": "en-US" } @@ -188,6 +229,7 @@ All `"activity_stream_session"` pings have the following basic shape. Some field { "action": "activity_stream_session", "client_id": "26288a14-5cc4-d14f-ae0a-bb01ef45be9c", + "session_id": "005deed0-e3e4-4c02-a041-17405fd703f6", "addon_version": "1.0.12", "locale": "en-US", "page": ["about:newtab" | "about:home"], @@ -204,3 +246,36 @@ Here are different scenarios that cause a session end event to be sent: 3. Closing the browser 5. Refreshing 6. Navigating to a new URL via the url bar or file menu + + +### Session performance data + +This data is held in a child object of the `activity_stream_session` event called `perf`. All fields suffixed by `_ts` are type `DOMHighResTimeStamp` (aka a double of milliseconds, with a 5 microsecond precision) with 0 being the [timeOrigin](https://developer.mozilla.org/en-US/docs/Web/API/DOMHighResTimeStamp#The_time_origin) of the browser's hidden chrome window. + +An example might look like this: + +```javascript +perf: { + // Timestamp of the action perceived by the user to trigger the load + // of this page. + // + // Not required at least for error cases where the + // observer event doesn't fire + "load_trigger_ts": 1, + + // What was the perceived trigger of the load action: + "load_trigger_type": [ + "menu_plus_or_keyboard" | // newtab only + "unexpected" // sessions lacking actual start times + ], + + // when the page itself receives an event that document.visibilityStat=visible + "visibility_event_rcvd_ts": 2, + + // When did the topsites element finish painting? Note that, at least for + // the first tab to be loaded, and maybe some others, this will be before + // topsites has yet to receive screenshots updates from the add-on code, + // and is therefore just showing placeholder screenshots. + "topsites_first_painted_ts": 5, +} +``` diff --git a/docs/v2-system-addon/sections.md b/docs/v2-system-addon/sections.md new file mode 100644 index 0000000000..35e5007d50 --- /dev/null +++ b/docs/v2-system-addon/sections.md @@ -0,0 +1,76 @@ +# Sections in Activity Stream + +Each section in Activity Stream displays data from a corresponding section feed +in a standardised `Section` UI component. Section feeds are responsible for +registering/deregistering their UI component and supplying rows data (the sites +for the section to display). + +Activity Stream loads sections from the `SECTIONS` map in `ActivityStream.jsm`. +Configuration objects must be keyed by a unique section id and have the +properties `{feed, showByDefault}`, where `feed` is the section feed class. + +The `Section` UI component displays the rows provided by the section feed. If no +rows are available it displays an empty state consisting of an icon and a +message. Optionally, the section may have a info option menu that is displayed +when users hover over the info icon. + +## Section feeds + +Each section feed is given the pref +`{Activity Stream pref branch}.feeds.section.{section_id}`. This pref turns the +section feed on and off. + +### Registering the section + +The section feed must listen for the events `INIT` (dispatched +when Activity Stream is initialised) and `FEED_INIT` (dispatched when a feed is +re-enabled having been turned off, with the feed id as the `data`) and respond +by dispatching a `SECTION_REGISTER` action to enable the section's UI component. +The action's `data` object should have the following properties: + +```js +{ + id, // Unique section id + icon, // Section icon id - new icons should be added to icons.scss + title: {id, values}, // Title localisation id and placeholder values + maxCards, // Max number of site cards to dispay + contextMenuOptions, // Default context-menu options for cards + infoOption: { // Info option dialog + header: {id, values}, // Header localisation id and values + body: {id, values}, // Body localisation id and values + link: {href, id, values}, // Link href, localisation id and values + }, + emptyState: { // State if no cards are visible + message: {id, values}, // Message localisation id and values + icon // Icon id - new icons should be added to icons.scss + } +} +``` + +### Deregistering the section + +The section feed must have an `uninit` method. This is called when the section +feed is disabled by turning the section's pref off. + +In `uninit` the feed must broadcast a `SECTION_DEREGISTER` action with the +section id as the data. This will remove the section's UI component from every +existing Activity Stream page. + +### Updating the section rows + +The section feed can dispatch a `SECTION_ROWS_UPDATE` action to update its rows. +The action's data object must be passed the section's `id` and an array `rows` +of sites to display. Each site object must have the following properties: + +```js +{ + type, // One of the types in Card/types.js, e.g. "Trending" + title, // Title string + description, // Description string + image, // Image url + url // Site url +} +``` + +Optionally, rows can also be passed with the `SECTION_REGISTER` action if the +feed already has rows to display. diff --git a/docs/v2-system-addon/snippets.md b/docs/v2-system-addon/snippets.md new file mode 100644 index 0000000000..57e9fb200b --- /dev/null +++ b/docs/v2-system-addon/snippets.md @@ -0,0 +1,53 @@ +# Snippets in ActivityStream + +## `gSnippetsMap` + +`gSnippetsMap` is available to all snippet templates and has methods that a +regular `Map` has: `set`, `get`, `delete`, `clear`, etc. + +If you don't care about the completion of the transaction, you may simply use these +methods synchronously: + +```js +function setFoo() { + gSnippetsMap.set("foo", 123); + return gSnippetsMap.get("foo"); // returns 123 +} +``` + +However, unlike the previous version of snippets, `set`, `delete`, and `clear` +all return a `Promise` that will resolve or reject when the `indexedDB` transaction +is complete. For example: + +```js +async function setFoo() { + await gSnippetsMap.set("foo", 123); + return gSnippetsMap.get("foo"); +} +``` + +### Expected values in gSnippetsMap + +Note that names and functionality of values in v4 snippets have been preserved +where possible. + +`snippets-cached-version`: The version number of the snippets cached in `snippets`. + +`snippets-last-update`: The last time snippets were updated. + +`snippets`: The cached payload of the response from the snippets server. + +`blockList`: An array of snippet IDs that have been blocked by the users, or an empty array if none have been blocked. + +`blockSnippetById(id)`: A function that adds an id to a blockList and returns +a Promise that resolves when the blockList has been written to indexedDB. + +`appData.snippetsURL`: The URL at from which snippets are fetched + +`appData.version`: The current version of snippets + +`appData.profileCreatedWeeksAgo`: The date the user's profile was created + +`appData.profileResetWeeksAgo`: The date the user's profile was reset. `null` if the profile hasn't been reset. + +`appData.telemetryEnabled`: Is telemetry enabled for the user? diff --git a/docs/v2-system-addon/telemetry.md b/docs/v2-system-addon/telemetry.md new file mode 100644 index 0000000000..79cfdc4140 --- /dev/null +++ b/docs/v2-system-addon/telemetry.md @@ -0,0 +1,17 @@ +# Adding/Changing Telemetry Checklist + +Adding telemetry generally involves a few steps: + +1. - [ ] File a "user story issue" about who wants what question answered. This will be used to track server-side data handling implementation (ETL, dashboard implementation...). + + > As an engineer, I see the distribution of times between triggering a new tab load by tab menu entry, plus button or keyboard shortcut and when the visibility event is fired on that page, so that I can understand how long it takes before the page becomes visible and how close to instantaneous that feels. + +1. - [ ] File or update your existing client-side implementation bug so that it points to the "user story issue". +1. - [ ] Talk to Marina (@emtwo) about the dashboard you're hoping to see from the data you're adding, and work with her to create a data model (or request her review on it after the fact). +1. - [ ] Update `system-addon/test/schemas/pings.js` with a commented JOI schema of your changes, and add tests to system-addon/test/unit/TelemetryFeed.test.js to exercise the ping creation. +1. - [ ] Update [data_events.md](data_events.md) with an example of the data in question +1. - [ ] Update any fields that you've added, deleted, or changed in [data_dictionary.md](data_dictionary.md) +1. - [ ] Get review from Nan (@ncloudioj) and/or Marina (@emtwo) on the data schema and the documentation changes. +1. - [ ] Request `data-review` of your documentation changes from a [data steward](https://wiki.mozilla.org/Firefox/Data_Collection) to ensure suitability for collection controlled by the opt-out `datareporting.healthreport.uploadEnabled` pref. We've been working with François Marier (@fmarier), so he's a good candidate as he's likely to have the most context. +1. - [ ] Implement as usual... +1. - [ ] After landing the implementation, check with Nan (@ncloudioj) to make sure the pings are making it to the database diff --git a/karma.mc.config.js b/karma.mc.config.js index c7d16c88a6..8396eaaebc 100644 --- a/karma.mc.config.js +++ b/karma.mc.config.js @@ -82,6 +82,19 @@ module.exports = function(config) { } }] }, + { + test: /\.js$/, + exclude: [/node_modules/, /test/], + use: [{ + loader: "babel-loader", + options: { + plugins: [ + ["transform-async-to-module-method", {module: "co-task", method: "async"}], + "transform-es2015-modules-commonjs" + ] + } + }] + }, { test: /\.jsx$/, exclude: /node_modules/, diff --git a/locales/ach/strings.properties b/locales/ach/strings.properties index d1f015cce4..b1ecac57cd 100644 --- a/locales/ach/strings.properties +++ b/locales/ach/strings.properties @@ -2,7 +2,12 @@ newtab_page_title=Dirica matidi manyen default_label_loading=Tye ka cano… header_top_sites=Kakube maloyo -header_highlights=Wiye madito +# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is +# meant to inform that section contains no information because +# the user hasn't added any bookmarks. +header_bookmarks_placeholder=Pud i pee ki alamabuk. +# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the +# corresponding content (stories) provider # LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give # context on how the element is related to the user, e.g. type indicates that @@ -26,6 +31,11 @@ menu_action_open_new_window=Yab i dirica manyen menu_action_open_private_window=Yab i dirica manyen me mung menu_action_dismiss=Kwer menu_action_delete=Kwany ki ii gin mukato +menu_action_pin=Mwon +# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in +# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a +# page from history. +menu_action_save_to_pocket=Gwoki i jaba # LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder # for what the user has typed in the search input field, e.g. 'Search for ' + @@ -69,8 +79,8 @@ settings_pane_search_body=Yeny Kakube ki i dirica ni matidi manyen. settings_pane_topsites_header=Kakube ma gi loyo settings_pane_topsites_body=Nong kakube ma ilimo loyo. settings_pane_topsites_options_showmore=Nyut rek ariyo -settings_pane_highlights_header=Wiye madito -settings_pane_highlights_body=Nen angec i yeny mamegi mukato ki alamabukke ni ma i cweyo manyen. +settings_pane_bookmarks_header=Alamabuk ma cocoki +settings_pane_visit_again_header=Lim Kidoco settings_pane_done_button=Otum # LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal @@ -83,3 +93,19 @@ edit_topsites_done_button=Otum edit_topsites_pin_button=Mwon kakube man edit_topsites_edit_button=Yub kakube man edit_topsites_dismiss_button=Kwer kakube man +edit_topsites_add_button=Medi + +# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal. +topsites_form_edit_header=Yub Kakube maloyo +topsites_form_add_button=Medi +topsites_form_save_button=Gwoki +topsites_form_cancel_button=Kwer + +# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the +# trending stories section and precedes a list of links to popular topics. +# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the +# end of the list of popular topic links. +# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction +# to Pocket as part of the feedback form. +# LOCALIZATION NOTE (pocket_feedback_body): This is shown below +# (pocket_feedback_header) to provide more information about Pocket. diff --git a/locales/ar/strings.properties b/locales/ar/strings.properties index 65f4af51a4..c621df05e8 100644 --- a/locales/ar/strings.properties +++ b/locales/ar/strings.properties @@ -2,7 +2,16 @@ newtab_page_title=لسان جديد default_label_loading=يُحمّل… header_top_sites=المواقع الأكثر زيارة -header_highlights=أهم الأحداث +header_stories=أهم الأخبار +header_visit_again=زرها مجددا +header_bookmarks=أحدث العلامات +# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is +# meant to inform that section contains no information because +# the user hasn't added any bookmarks. +header_bookmarks_placeholder=لا علامات لديك بعد. +# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the +# corresponding content (stories) provider +header_stories_from=من # LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give # context on how the element is related to the user, e.g. type indicates that @@ -10,6 +19,7 @@ header_highlights=أهم الأحداث type_label_visited=مُزارة type_label_bookmarked=معلّمة type_label_synced=مُزامنة من جهاز آخر +type_label_recommended=مُتداول # LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open" type_label_open=مفتوحة type_label_topic=الموضوع @@ -26,6 +36,14 @@ menu_action_open_new_window=افتح في نافذة جديدة menu_action_open_private_window=افتح في نافذة خاصة جديدة menu_action_dismiss=ألغِ menu_action_delete=احذف من التأريخ +menu_action_pin=ثبّت +menu_action_unpin=أزل +confirm_history_delete_p1=هل أنت متأكد أنك تريد حذف كل وجود لهذه الصفحة من تأريخك؟ +# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in +# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a +# page from history. +confirm_history_delete_notice_p2=لا يمكن التراجع عن هذا الإجراء. +menu_action_save_to_pocket=احفظ في Pocket # LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder # for what the user has typed in the search input field, e.g. 'Search for ' + @@ -69,8 +87,12 @@ settings_pane_search_body=ابحث في الوِب من اللسان الجدي settings_pane_topsites_header=المواقع الأكثر زيارة settings_pane_topsites_body=وصول للمواقع التي تزورها أكثر. settings_pane_topsites_options_showmore=اعرض صفّين -settings_pane_highlights_header=أهم الأحداث -settings_pane_highlights_body=اطّلع على تأريخ التصفح الأحدث، و العلامات المنشأة حديثًا. +settings_pane_bookmarks_header=أحدث العلامات +settings_pane_bookmarks_body=علاماتك المعلّمة حديثًا في مكان واحد. +settings_pane_visit_again_header=زرها مجددا +settings_pane_visit_again_body=سيعرض لك فَيَرفُكس بعضًا من تأريخ تصفحك الذي قد تود تذكّره لاحقًا. +settings_pane_pocketstories_header=أهم المواضيع +settings_pane_pocketstories_body=يساعدك Pocket –عضو في أسرة موزيلا– على الوصول إلى محتوى عالِ الجودة ربما لم يُكن ليتاح لك بدونه. settings_pane_done_button=تمّ # LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal @@ -81,5 +103,31 @@ edit_topsites_showmore_button=اعرض المزيد edit_topsites_showless_button=اعرض أقل edit_topsites_done_button=تمّ edit_topsites_pin_button=ثبّت هذا الموقع +edit_topsites_unpin_button=افصل هذا الموقع edit_topsites_edit_button=حرّر هذا الموقع edit_topsites_dismiss_button=احذف هذا الموقع +edit_topsites_add_button=أضِفْ + +# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal. +topsites_form_add_header=موقع شائع جديد +topsites_form_edit_header=حرّر الموقع الشائع +topsites_form_title_placeholder=أدخل عنوانًا +topsites_form_url_placeholder=اكتب أو ألصق مسارًا +topsites_form_add_button=أضِفْ +topsites_form_save_button=احفظ +topsites_form_cancel_button=ألغِ +topsites_form_url_validation=مطلوب مسار صالح + +# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the +# trending stories section and precedes a list of links to popular topics. +pocket_read_more=المواضيع الشائعة: +# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the +# end of the list of popular topic links. +pocket_read_even_more=اعرض المزيد من الأخبار +# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction +# to Pocket as part of the feedback form. +pocket_feedback_header=أفضل ما في الوِب، انتقاها أكثر من ٢٥ مليون شخص. +# LOCALIZATION NOTE (pocket_feedback_body): This is shown below +# (pocket_feedback_header) to provide more information about Pocket. +pocket_feedback_body=يساعدك Pocket –عضو في أسرة موزيلا– على الوصول إلى محتوى عالِ الجودة ربما لم يُكن ليتاح لك بدونه. +pocket_send_feedback=أرسل انطباعك diff --git a/locales/az/strings.properties b/locales/az/strings.properties index 71d87bfa46..1006abfa98 100644 --- a/locales/az/strings.properties +++ b/locales/az/strings.properties @@ -2,7 +2,19 @@ newtab_page_title=Yeni Vərəq default_label_loading=Yüklənir… header_top_sites=Qabaqcıl Saytlar -header_highlights=Seçilmişlər +header_stories=Qabaqcıl Hekayələr +header_visit_again=Təkrar ziyarət et +header_bookmarks=Son Əlfəcinlər +# LOCALIZATION NOTE(header_recommended_by): This is followed by the name +# of the corresponding content provider. +header_recommended_by={provider} məsləhət görür +# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is +# meant to inform that section contains no information because +# the user hasn't added any bookmarks. +header_bookmarks_placeholder=Hələlik heç əlfəcininiz yoxdur. +# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the +# corresponding content (stories) provider +header_stories_from=qaynaq: # LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give # context on how the element is related to the user, e.g. type indicates that @@ -10,9 +22,11 @@ header_highlights=Seçilmişlər type_label_visited=Ziyarət edilib type_label_bookmarked=Əlfəcinlənib type_label_synced=Digər cihazdan sync edilib +type_label_recommended=Populyar # LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open" type_label_open=Açıq type_label_topic=Mövzu +type_label_now=İndi # LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context # menu and are meant as a call to action for a given page. @@ -26,6 +40,14 @@ menu_action_open_new_window=Yeni Pəncərədə Aç menu_action_open_private_window=Yeni Məxfi Pəncərədə Aç menu_action_dismiss=Rədd et menu_action_delete=Tarixçədən Sil +menu_action_pin=Bərkid +menu_action_unpin=Çıxart +confirm_history_delete_p1=Bu səhifənin bütün parçalarını tarixçənizdən silmək istədiyinizə əminsiniz? +# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in +# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a +# page from history. +confirm_history_delete_notice_p2=Bu əməliyyat geri alına bilməz. +menu_action_save_to_pocket=Pocket-ə Saxla # LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder # for what the user has typed in the search input field, e.g. 'Search for ' + @@ -47,6 +69,10 @@ search_header={search_engine_name} Axtarış search_web_placeholder=İnternetdə Axtar search_settings=Axtarış Tənzimləmələrini Dəyiş +# LOCALIZATION NOTE (section_info_option): This is the screenreader text for the +# (?) icon that would show a section's description with optional feedback link. +section_info_option=Məlumat + # LOCALIZATION NOTE (welcome_*): This is shown as a modal dialog, typically on a # first-run experience when there's no data to display yet welcome_title=Yeni vərəqə xoş gəldiniz @@ -69,8 +95,12 @@ settings_pane_search_body=Yeni vərəqinizdən Web-də axtarış edin. settings_pane_topsites_header=Qabaqcıl Saytlar settings_pane_topsites_body=Ən çox ziyarət etdiyiniz saytları görün. settings_pane_topsites_options_showmore=İki sətir göstər -settings_pane_highlights_header=Seçilmişlər -settings_pane_highlights_body=Son gəzmə tarixçəniz və yeni yaradılar əlfəcinlərinizə göz gəzdirin. +settings_pane_bookmarks_header=Son Əlfəcinlər +settings_pane_bookmarks_body=Yeni yaradılan əlfəcinlər tək bir əlverişli yerdə. +settings_pane_visit_again_header=Təkrar ziyarət et +settings_pane_visit_again_body=Firefox tarixçənizdən yadda saxlamaq və ya geri qayıtmaq istəyə biləcəyiniz hissələri göstərəcək. +settings_pane_pocketstories_header=Qabaqcıl Hekayələr +settings_pane_pocketstories_body=Pocket, Mozilla ailəsinin üzvü, yüksək keyfiyyətli məzmunları kəşf etməyinizə kömək edəcək. settings_pane_done_button=Oldu # LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal @@ -81,5 +111,42 @@ edit_topsites_showmore_button=Daha çox göstər edit_topsites_showless_button=Daha az göstər edit_topsites_done_button=Oldu edit_topsites_pin_button=Bu saytı sabitlə +edit_topsites_unpin_button=Bu saytı çıxart edit_topsites_edit_button=Bu saytı düzəlt edit_topsites_dismiss_button=Bu saytı çıxart +edit_topsites_add_button=Əlavə et + +# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal. +topsites_form_add_header=Yeni Qabaqcıl Saytlar +topsites_form_edit_header=Qabaqcıl Saytları Dəyişdir +topsites_form_title_placeholder=Başlıq daxil et +topsites_form_url_placeholder=Ünvanı yazın və ya yapışdırın +topsites_form_add_button=Əlavə et +topsites_form_save_button=Saxla +topsites_form_cancel_button=Ləğv et +topsites_form_url_validation=Doğru ünvan tələb olunur + +# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the +# trending stories section and precedes a list of links to popular topics. +pocket_read_more=Məşhur Mövzular: +# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the +# end of the list of popular topic links. +pocket_read_even_more=Daha çox hekayə gör +# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction +# to Pocket as part of the feedback form. +pocket_feedback_header=25 milyon nəfərin dəstəyi ilə internetin ən yaxşıları. +# LOCALIZATION NOTE (pocket_feedback_body): This is shown below +# (pocket_feedback_header) to provide more information about Pocket. +pocket_feedback_body=Pocket, Mozilla ailəsinin üzvü, yüksək keyfiyyətli məzmunları kəşf etməyinizə kömək edəcək. +pocket_send_feedback=Əks-əlaqə göndər + +# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations, +# in the space that would have shown a few stories, this is shown instead. +# {provider} is replaced by the name of the content provider for this section. + +# LOCALIZATION NOTE (manual_migration_explanation): This message is shown to encourage users to +# import their browser profile from another browser they might be using. +# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the +# process of importing another browser’s profile into Firefox. +# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process +# of importing another browser’s profile profile into Firefox. diff --git a/locales/be/strings.properties b/locales/be/strings.properties index 52a0c259d9..9a4d073d79 100644 --- a/locales/be/strings.properties +++ b/locales/be/strings.properties @@ -2,7 +2,16 @@ newtab_page_title=Новая картка default_label_loading=Загрузка… header_top_sites=Папулярныя сайты -header_highlights=Выбранае +header_stories=Галоўныя навіны +header_visit_again=Наведаць зноў +header_bookmarks=Нядаўнія закладкі +# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is +# meant to inform that section contains no information because +# the user hasn't added any bookmarks. +header_bookmarks_placeholder=У вас яшчэ няма закладак. +# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the +# corresponding content (stories) provider +header_stories_from=ад # LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give # context on how the element is related to the user, e.g. type indicates that @@ -10,6 +19,7 @@ header_highlights=Выбранае type_label_visited=Наведанае type_label_bookmarked=У закладках type_label_synced=Сінхранізаванае з іншай прылады +type_label_recommended=Тэндэнцыі # LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open" type_label_open=Адкрыта type_label_topic=Тэма @@ -26,6 +36,14 @@ menu_action_open_new_window=Адкрыць у новым акне menu_action_open_private_window=Адкрыць у новым прыватным акне menu_action_dismiss=Адхіліць menu_action_delete=Выдаліць з гісторыі +menu_action_pin=Замацаваць +menu_action_unpin=Адмацаваць +confirm_history_delete_p1=Вы сапраўды жадаеце выдаліць усе запісы аб гэтай старонцы з гісторыі? +# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in +# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a +# page from history. +confirm_history_delete_notice_p2=Гэта дзеянне немагчыма адмяніць. +menu_action_save_to_pocket=Захаваць у Pocket # LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder # for what the user has typed in the search input field, e.g. 'Search for ' + @@ -69,8 +87,12 @@ settings_pane_search_body=Пошук у Сеціве з вашай новай к settings_pane_topsites_header=Папулярныя сайты settings_pane_topsites_body=Доступ да сайтаў, якія вы часцей наведваеце. settings_pane_topsites_options_showmore=Паказваць два шэрагі -settings_pane_highlights_header=Выбранае -settings_pane_highlights_body=Агляд нядаўняй гісторыі прагляду і новых картак. +settings_pane_bookmarks_header=Нядаўнія закладкі +settings_pane_bookmarks_body=Вашы новыя закладкі ў адным зручным месцы. +settings_pane_visit_again_header=Наведаць зноў +settings_pane_visit_again_body=Firefox пакажа вам элементы гісторыі прагляду, якія вы, магчыма, захочаце запомніць або наведаць зноў. +settings_pane_pocketstories_header=Галоўныя навіны +settings_pane_pocketstories_body=Pocket, частка сям'і Mozilla, дапаможа падключыць вас да якаснага зместу, які вы можаце не знайсці іншым чынам. settings_pane_done_button=Гатова # LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal @@ -81,5 +103,31 @@ edit_topsites_showmore_button=Паказаць больш edit_topsites_showless_button=Паказаць менш edit_topsites_done_button=Гатова edit_topsites_pin_button=Замацаваць гэты сайт +edit_topsites_unpin_button=Адшпіліць гэты сайт edit_topsites_edit_button=Рэдагаваць гэты сайт edit_topsites_dismiss_button=Адхіліць гэты сайт +edit_topsites_add_button=Дадаць + +# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal. +topsites_form_add_header=Новы папулярны сайт +topsites_form_edit_header=Рэдагаваць папулярны сайт +topsites_form_title_placeholder=Увядзіце назву +topsites_form_url_placeholder=Увядзіце або ўстаўце URL +topsites_form_add_button=Дадаць +topsites_form_save_button=Захаваць +topsites_form_cancel_button=Скасаваць +topsites_form_url_validation=Патрабуецца сапраўдны URL + +# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the +# trending stories section and precedes a list of links to popular topics. +pocket_read_more=Папулярныя тэмы: +# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the +# end of the list of popular topic links. +pocket_read_even_more=Іншыя навіны +# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction +# to Pocket as part of the feedback form. +pocket_feedback_header=Лепшае з Сеціва, што адабралі больш за 25 мільёнаў чалавек. +# LOCALIZATION NOTE (pocket_feedback_body): This is shown below +# (pocket_feedback_header) to provide more information about Pocket. +pocket_feedback_body=Pocket, частка сям'і Mozilla, дапаможа падключыць вас да якаснага зместу, які вы можаце не знайсці іншым чынам. +pocket_send_feedback=Даслаць водгук diff --git a/locales/bg/strings.properties b/locales/bg/strings.properties index e682baa48e..ab65d5d264 100644 --- a/locales/bg/strings.properties +++ b/locales/bg/strings.properties @@ -2,7 +2,16 @@ newtab_page_title=Нов раздел default_label_loading=Зареждане… header_top_sites=Най-посещавани -header_highlights=Акценти +header_stories=Популярни +header_visit_again=Посещаване +header_bookmarks=Последни отметки +# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is +# meant to inform that section contains no information because +# the user hasn't added any bookmarks. +header_bookmarks_placeholder=Все още нямате отметки. +# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the +# corresponding content (stories) provider +header_stories_from=от # LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give # context on how the element is related to the user, e.g. type indicates that @@ -10,6 +19,7 @@ header_highlights=Акценти type_label_visited=Посетена type_label_bookmarked=Отметната type_label_synced=Синхронизирана от друго устройство +type_label_recommended=Тенденции # LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open" type_label_open=Отваряне type_label_topic=Тема @@ -24,8 +34,16 @@ menu_action_copy_address=Копиране на адрес menu_action_email_link=Препратка по ел. поща… menu_action_open_new_window=Отваряне в раздел menu_action_open_private_window=Отваряне в поверителен прозорец -menu_action_dismiss=Прекратяване +menu_action_dismiss=Отхвърляне menu_action_delete=Премахване от историята +menu_action_pin=Закачане +menu_action_unpin=Откачане +confirm_history_delete_p1=Сигурни ли сте, че желаете да премахнете страницата навсякъде от историята? +# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in +# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a +# page from history. +confirm_history_delete_notice_p2=Действието е необратимо. +menu_action_save_to_pocket=Запазване в Pocket # LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder # for what the user has typed in the search input field, e.g. 'Search for ' + @@ -69,8 +87,12 @@ settings_pane_search_body=Търсете в мрежата от нов разд settings_pane_topsites_header=Най-посещавани settings_pane_topsites_body=Достъп до сайтовете, които посещавате най-често. settings_pane_topsites_options_showmore=Показване на два реда -settings_pane_highlights_header=Акценти -settings_pane_highlights_body=Върнете се назад в скорошната историята на сърфиране и последно направените отметки. +settings_pane_bookmarks_header=Последни отметки +settings_pane_bookmarks_body=Всички нови отметки на едно място. +settings_pane_visit_again_header=Посещаване +settings_pane_visit_again_body=Firefox ще ви показва части от вашата история на разглеждане, към която бихте желали да се върнете или запомните. +settings_pane_pocketstories_header=Популярни +settings_pane_pocketstories_body=Pocket, част от семейството на Mozilla, ще ви помогне да намерите висококачествено съдържанието, което може да не сте открили до сега. settings_pane_done_button=Готово # LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal @@ -81,5 +103,31 @@ edit_topsites_showmore_button=Повече edit_topsites_showless_button=По-малко edit_topsites_done_button=Готово edit_topsites_pin_button=Закачане +edit_topsites_unpin_button=Премахване от закачените edit_topsites_edit_button=Редактиране edit_topsites_dismiss_button=Изтриване +edit_topsites_add_button=Добавяне + +# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal. +topsites_form_add_header=Нов най-посещаван сайт +topsites_form_edit_header=Редактиране на най-посещаван сайт +topsites_form_title_placeholder=Заглавие +topsites_form_url_placeholder=Адрес +topsites_form_add_button=Добавяне +topsites_form_save_button=Запазване +topsites_form_cancel_button=Отказ +topsites_form_url_validation=Необходим е валиден URL + +# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the +# trending stories section and precedes a list of links to popular topics. +pocket_read_more=Популярни теми: +# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the +# end of the list of popular topic links. +pocket_read_even_more=Повече статии +# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction +# to Pocket as part of the feedback form. +pocket_feedback_header=Най-доброто от интернет, подбрано от над 25 милиона души. +# LOCALIZATION NOTE (pocket_feedback_body): This is shown below +# (pocket_feedback_header) to provide more information about Pocket. +pocket_feedback_body=Pocket, част от семейството на Mozilla, ще ви помогне да намерите висококачествено съдържанието, което може да не сте открили до сега. +pocket_send_feedback=Обратна връзка diff --git a/locales/bn-BD/strings.properties b/locales/bn-BD/strings.properties index 12f8974afb..5ce393502d 100644 --- a/locales/bn-BD/strings.properties +++ b/locales/bn-BD/strings.properties @@ -2,7 +2,16 @@ newtab_page_title=নতুন ট্যাব default_label_loading=লোড হচ্ছে… header_top_sites=শীর্ঘ সাইট -header_highlights=হাইলাইট +header_stories=শীর্ষ গল্প +header_visit_again=পুনরায় ভিজিট করুন +header_bookmarks=সাম্প্রতিক বুকমার্ক +# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is +# meant to inform that section contains no information because +# the user hasn't added any bookmarks. +header_bookmarks_placeholder=এখনও কোন বুকমার্ক নেই। +# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the +# corresponding content (stories) provider +header_stories_from=থেকে # LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give # context on how the element is related to the user, e.g. type indicates that @@ -10,6 +19,7 @@ header_highlights=হাইলাইট type_label_visited=পরিদর্শিত type_label_bookmarked=বুকমার্ক করা হয়েছে type_label_synced=অন্য ডিভাইস থেকে সিঙ্ক করা হয়েছে +type_label_recommended=ঝোঁক # LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open" type_label_open=খোলা type_label_topic=টপিক @@ -26,6 +36,14 @@ menu_action_open_new_window=নতুন উইন্ডোতে খুলু menu_action_open_private_window=নতুন ব্যক্তিগত উইন্ডোতে খুলুন menu_action_dismiss=বাতিল menu_action_delete=ইতিহাস থেকে মুছে ফেলুন +menu_action_pin=পিন +menu_action_unpin=আনপিন +confirm_history_delete_p1=আপনি কি নিশ্চিতভাবে আপনার ইতিহাস থেকে এই পাতার সকল কিছু মুছে ফেলতে চান? +# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in +# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a +# page from history. +confirm_history_delete_notice_p2=এই পরিবর্তনটি অপরিবর্তনীয়। +menu_action_save_to_pocket=Pocket এ সংরক্ষণ করুন # LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder # for what the user has typed in the search input field, e.g. 'Search for ' + @@ -69,8 +87,10 @@ settings_pane_search_body=আপনার নতুন ট্যাব থেক settings_pane_topsites_header=শীর্ষ সাইট settings_pane_topsites_body=আপনি যেসব সাইটে বেশি যান সেসব সাইটে প্রবেশ করুন। settings_pane_topsites_options_showmore=দুটি সারি দেখান -settings_pane_highlights_header=গুরুত্বপূর্ণ -settings_pane_highlights_body=আপনার বিগত ব্রাউজিং ইতিহাস এবং নতুনভাবে তৈরি করা বুর্কমার্কগুলো দেখুন। +settings_pane_bookmarks_header=সাম্প্রতিক বুকমার্ক +settings_pane_bookmarks_body=আপনার নতুন করা বুকমার্ক সহজ অবস্থানে রাখা হয়েছে। +settings_pane_visit_again_header=পুনরায় ভিজিট করুন +settings_pane_pocketstories_header=শীর্ষ গল্প settings_pane_done_button=হয়েছে # LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal @@ -81,5 +101,28 @@ edit_topsites_showmore_button=আরও দেখান edit_topsites_showless_button=কম দেখান edit_topsites_done_button=হয়েছে edit_topsites_pin_button=সাইটটি পিন করুন +edit_topsites_unpin_button=এই সাইট আনপিন করুন edit_topsites_edit_button=সাইটটি সম্পাদনা করুন edit_topsites_dismiss_button=সাইটটি মুছে দিন +edit_topsites_add_button=যোগ + +# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal. +topsites_form_add_header=নতুন শীর্ষ সাইট +topsites_form_edit_header=শীর্ষ সাইট সম্পাদনা করুন +topsites_form_title_placeholder=নাম দিন +topsites_form_add_button=যোগ +topsites_form_save_button=সংরক্ষণ +topsites_form_cancel_button=বাতিল +topsites_form_url_validation=কার্যকর URL প্রয়োজন + +# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the +# trending stories section and precedes a list of links to popular topics. +pocket_read_more=জনপ্রিয় বিষয়: +# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the +# end of the list of popular topic links. +pocket_read_even_more=আরও গল্প দেখুন +# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction +# to Pocket as part of the feedback form. +# LOCALIZATION NOTE (pocket_feedback_body): This is shown below +# (pocket_feedback_header) to provide more information about Pocket. +pocket_send_feedback=প্রতিক্রিয়া জানান diff --git a/locales/ca/strings.properties b/locales/ca/strings.properties index d46d152851..f208321c44 100644 --- a/locales/ca/strings.properties +++ b/locales/ca/strings.properties @@ -2,7 +2,16 @@ newtab_page_title=Pestanya nova default_label_loading=S'està carregant… header_top_sites=Llocs principals -header_highlights=Destacats +header_stories=Articles populars +header_visit_again=Torneu a visitar +header_bookmarks=Adreces d'interès recents +# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is +# meant to inform that section contains no information because +# the user hasn't added any bookmarks. +header_bookmarks_placeholder=Encara no teniu cap adreça d'interès. +# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the +# corresponding content (stories) provider +header_stories_from=de # LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give # context on how the element is related to the user, e.g. type indicates that @@ -10,6 +19,7 @@ header_highlights=Destacats type_label_visited=Visitats type_label_bookmarked=A les adreces d'interès type_label_synced=Sincronitzat des d'un altre dispositiu +type_label_recommended=Tendència # LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open" type_label_open=Obert type_label_topic=Tema @@ -26,6 +36,14 @@ menu_action_open_new_window=Obre en una finestra nova menu_action_open_private_window=Obre en una finestra privada nova menu_action_dismiss=Descarta menu_action_delete=Elimina de l'historial +menu_action_pin=Fixa +menu_action_unpin=No fixis +confirm_history_delete_p1=Segur que voleu suprimir de l'historial totes les instàncies d'aquesta pàgina? +# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in +# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a +# page from history. +confirm_history_delete_notice_p2=Aquesta acció no es pot desfer. +menu_action_save_to_pocket=Desa al Pocket # LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder # for what the user has typed in the search input field, e.g. 'Search for ' + @@ -69,8 +87,12 @@ settings_pane_search_body=Cerca al web des de la pestanya nova. settings_pane_topsites_header=Llocs principals settings_pane_topsites_body=Accediu als llocs web que visiteu més sovint. settings_pane_topsites_options_showmore=Mostra dues files -settings_pane_highlights_header=Destacats -settings_pane_highlights_body=Vegeu el vostre historial de navegació i les adreces d'interès més recents. +settings_pane_bookmarks_header=Adreces d'interès recents +settings_pane_bookmarks_body=Les adreces d'interès que aneu creant, en un lloc còmode. +settings_pane_visit_again_header=Torneu a visitar +settings_pane_visit_again_body=El Firefox us mostrarà parts del vostre historial de navegació que potser us agradaria recordar o tornar a visitar. +settings_pane_pocketstories_header=Articles populars +settings_pane_pocketstories_body=El Pocket, membre de la família Mozilla, us permet accedir a contingut d'alta qualitat que d'altra manera potser no trobaríeu. settings_pane_done_button=Fet # LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal @@ -81,5 +103,31 @@ edit_topsites_showmore_button=Mostra'n més edit_topsites_showless_button=Mostra'n menys edit_topsites_done_button=Fet edit_topsites_pin_button=Fixa aquest lloc +edit_topsites_unpin_button=No fixis aquest lloc edit_topsites_edit_button=Edita aquest lloc edit_topsites_dismiss_button=Elimina aquest lloc +edit_topsites_add_button=Afegeix + +# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal. +topsites_form_add_header=Lloc principal nou +topsites_form_edit_header=Edita el lloc principal +topsites_form_title_placeholder=Escriviu el títol +topsites_form_url_placeholder=Escriviu o enganxeu un URL +topsites_form_add_button=Afegeix +topsites_form_save_button=Desa +topsites_form_cancel_button=Cancel·la +topsites_form_url_validation=Es necessita un URL vàlid + +# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the +# trending stories section and precedes a list of links to popular topics. +pocket_read_more=Temes populars: +# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the +# end of the list of popular topic links. +pocket_read_even_more=Mostra més articles +# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction +# to Pocket as part of the feedback form. +pocket_feedback_header=El millor del web, seleccionat per més de 25 milions de persones. +# LOCALIZATION NOTE (pocket_feedback_body): This is shown below +# (pocket_feedback_header) to provide more information about Pocket. +pocket_feedback_body=El Pocket, membre de la família Mozilla, us permet accedir a contingut d'alta qualitat que d'altra manera potser no trobaríeu. +pocket_send_feedback=Doneu la vostra opinió diff --git a/locales/cs/strings.properties b/locales/cs/strings.properties index 2da6d8d894..4c0c789821 100644 --- a/locales/cs/strings.properties +++ b/locales/cs/strings.properties @@ -2,7 +2,19 @@ newtab_page_title=Nový panel default_label_loading=Načítání… header_top_sites=Top stránky -header_highlights=Vybrané +header_stories=Nejlepší příběhy +header_visit_again=Znovu navštívit +header_bookmarks=Nedávno přidané záložky +# LOCALIZATION NOTE(header_recommended_by): This is followed by the name +# of the corresponding content provider. +header_recommended_by=Doporučení ze služby {provider} +# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is +# meant to inform that section contains no information because +# the user hasn't added any bookmarks. +header_bookmarks_placeholder=Zatím nemáte uložené žádné záložky. +# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the +# corresponding content (stories) provider +header_stories_from=ze šlužby # LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give # context on how the element is related to the user, e.g. type indicates that @@ -10,9 +22,11 @@ header_highlights=Vybrané type_label_visited=Navštívené type_label_bookmarked=V záložkách type_label_synced=Synchronizované z jiného zařízení +type_label_recommended=Populární # LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open" type_label_open=Otevřené type_label_topic=Téma +type_label_now=Teď # LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context # menu and are meant as a call to action for a given page. @@ -26,6 +40,14 @@ menu_action_open_new_window=Otevřít v novém okně menu_action_open_private_window=Otevřít v novém anonymním okně menu_action_dismiss=Skrýt menu_action_delete=Smazat z historie +menu_action_pin=Připnout +menu_action_unpin=Odepnout +confirm_history_delete_p1=Opravdu chcete smazat všechny výskyty této stránky z vaší historie? +# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in +# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a +# page from history. +confirm_history_delete_notice_p2=Tuto akci nelze vzít zpět. +menu_action_save_to_pocket=Uložit do služby Pocket # LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder # for what the user has typed in the search input field, e.g. 'Search for ' + @@ -47,6 +69,10 @@ search_header=Vyhledat pomocí {search_engine_name} search_web_placeholder=Hledat na webu search_settings=Změnit nastavení vyhledávání +# LOCALIZATION NOTE (section_info_option): This is the screenreader text for the +# (?) icon that would show a section's description with optional feedback link. +section_info_option=Informace + # LOCALIZATION NOTE (welcome_*): This is shown as a modal dialog, typically on a # first-run experience when there's no data to display yet welcome_title=Vítejte na stránce nového panelu @@ -69,8 +95,12 @@ settings_pane_search_body=Vyhledávání na webu rovnou ze stránky nového pane settings_pane_topsites_header=Top stránky settings_pane_topsites_body=Přístup ke stránkám, které nejčastěji navštěvujete. settings_pane_topsites_options_showmore=Zobrazit dva řádky -settings_pane_highlights_header=Vybrané -settings_pane_highlights_body=Pohled zpět na vaši nedávnou historii a nově vytvořené záložky. +settings_pane_bookmarks_header=Nedávno přidané záložky +settings_pane_bookmarks_body=Vaše nově přidané záložky na místě hned po ruce. +settings_pane_visit_again_header=Znovu navštívit +settings_pane_visit_again_body=Firefox vám ukáže některé položky z vaší historie prohlížení, které byste si mohli chtít připomenout nebo se k nim vrátit. +settings_pane_pocketstories_header=Nejlepší příběhy +settings_pane_pocketstories_body=Pocket, služba od Mozilly, vám pomůže najít vysoce kvalitní obsah, který byste jinak neobjevili. settings_pane_done_button=Hotovo # LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal @@ -81,5 +111,46 @@ edit_topsites_showmore_button=Zobrazit více edit_topsites_showless_button=Zobrazit méně edit_topsites_done_button=Hotovo edit_topsites_pin_button=Připnout tuto stránku +edit_topsites_unpin_button=Odepnout tuto stránku edit_topsites_edit_button=Upravit tuto stránku edit_topsites_dismiss_button=Skrýt tuto stránku +edit_topsites_add_button=Přidat + +# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal. +topsites_form_add_header=Nová top stránka +topsites_form_edit_header=Upravit top stránku +topsites_form_title_placeholder=Zadejte název +topsites_form_url_placeholder=Zadejte nebo vložte URL adresu +topsites_form_add_button=Přidat +topsites_form_save_button=Uložit +topsites_form_cancel_button=Zrušit +topsites_form_url_validation=Je vyžadována platná URL + +# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the +# trending stories section and precedes a list of links to popular topics. +pocket_read_more=Populární témata: +# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the +# end of the list of popular topic links. +pocket_read_even_more=Zobrazit více příběhů +# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction +# to Pocket as part of the feedback form. +pocket_feedback_header=To nejlepší na webu podle hodnocení více než 25 milionů lidí. +# LOCALIZATION NOTE (pocket_feedback_body): This is shown below +# (pocket_feedback_header) to provide more information about Pocket. +pocket_feedback_body=Pocket, služba od Mozilly, vám pomůže najít vysoce kvalitní obsah, který byste jinak neobjevili. +pocket_send_feedback=Odeslat zpětnou vazbu + +# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations, +# in the space that would have shown a few stories, this is shown instead. +# {provider} is replaced by the name of the content provider for this section. +topstories_empty_state=Už jste všechno přečetli. Další příběhy ze služby {provider} tu najdete zase později. Ale pokud se nemůžete dočkat, vyberte své oblíbené téma a podívejte se na další velké příběhy z celého webu. + +# LOCALIZATION NOTE (manual_migration_explanation): This message is shown to encourage users to +# import their browser profile from another browser they might be using. +manual_migration_explanation=Vyzkoušejte Firefox se svými oblíbenými stránkami a záložkami z jiného prohlížeče. +# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the +# process of importing another browser’s profile into Firefox. +manual_migration_cancel_button=Ne, děkuji +# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process +# of importing another browser’s profile profile into Firefox. +manual_migration_import_button=Importovat nyní diff --git a/locales/cy/strings.properties b/locales/cy/strings.properties index 0fbfb91d55..8dab02c764 100644 --- a/locales/cy/strings.properties +++ b/locales/cy/strings.properties @@ -2,7 +2,19 @@ newtab_page_title=Tab Newydd default_label_loading=Llwytho… header_top_sites=Hoff Wefannau -header_highlights=Goreuon +header_stories=Hoff Straeon +header_visit_again=Ymweld Eto +header_bookmarks=Nodau Tudalen Diweddar +# LOCALIZATION NOTE(header_recommended_by): This is followed by the name +# of the corresponding content provider. +header_recommended_by=Argymhellwyd gan {provider} +# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is +# meant to inform that section contains no information because +# the user hasn't added any bookmarks. +header_bookmarks_placeholder=Nid oes gennych unrhyw nodau tudalen eto. +# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the +# corresponding content (stories) provider +header_stories_from=oddi wrth # LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give # context on how the element is related to the user, e.g. type indicates that @@ -10,9 +22,11 @@ header_highlights=Goreuon type_label_visited=Ymwelwyd type_label_bookmarked=Nod Tudalen type_label_synced=Cydweddwyd o ddyfais arall +type_label_recommended=Trendio # LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open" type_label_open=Ar Agor type_label_topic=Pwnc +type_label_now=Nawr # LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context # menu and are meant as a call to action for a given page. @@ -26,6 +40,14 @@ menu_action_open_new_window=Agor Ffenestr Newydd menu_action_open_private_window=Agor mewn Ffenestr Preifat Newydd menu_action_dismiss=Cau menu_action_delete=Dileu o'r Hanes +menu_action_pin=Pinio +menu_action_unpin=Dad-binio +confirm_history_delete_p1=Ydych chi'n siŵr eich bod chi am ddileu pob enghraifft o'r dudalen hon o'ch hanes? +# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in +# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a +# page from history. +confirm_history_delete_notice_p2=Nid oes modd dadwneud hyn. +menu_action_save_to_pocket=Cadw i Pocket # LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder # for what the user has typed in the search input field, e.g. 'Search for ' + @@ -47,6 +69,10 @@ search_header={search_engine_name} Chwilio search_web_placeholder=Chwilio'r We search_settings=Newid y Gosodiadau Chwilio +# LOCALIZATION NOTE (section_info_option): This is the screenreader text for the +# (?) icon that would show a section's description with optional feedback link. +section_info_option=Gwybodaeth + # LOCALIZATION NOTE (welcome_*): This is shown as a modal dialog, typically on a # first-run experience when there's no data to display yet welcome_title=Croeso i dab newydd @@ -69,8 +95,12 @@ settings_pane_search_body=Chwilio'r We o'ch tab newydd. settings_pane_topsites_header=Hoff Wefannau settings_pane_topsites_body=Cael mynediad at y gwefannau rydych yn ymweld â nhw amlaf. settings_pane_topsites_options_showmore=Dangos dwy res -settings_pane_highlights_header=Goreuon -settings_pane_highlights_body=Edrych nôl ar eich hanes pori a nodau tudalen diweddar. +settings_pane_bookmarks_header=Nodau Tudalen Diweddar +settings_pane_bookmarks_body=Eich nodau tudalen diweddaraf mewn un lleoliad hwylus. +settings_pane_visit_again_header=Ymweld Eto +settings_pane_visit_again_body=Gall Firefox ddangos i chi rannau o'ch hanes pori yr hoffech eu cofio neu fynd nôl atyn nhw. +settings_pane_pocketstories_header=Hoff Straeon +settings_pane_pocketstories_body=Gall Pocket, sy'n rhan o deulu Mozilla, eich helpu i ganfod cynnwys o ansawdd uchel na fyddech wedi eu canfod fel arall. settings_pane_done_button=Gorffen # LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal @@ -81,5 +111,46 @@ edit_topsites_showmore_button=Dangos rhagor edit_topsites_showless_button=Dangos llai edit_topsites_done_button=Gorffen edit_topsites_pin_button=Pinio'r wefan +edit_topsites_unpin_button=Dad-binio'r wefan edit_topsites_edit_button=Golygu'r wefan edit_topsites_dismiss_button=Dileu'r wefan +edit_topsites_add_button=Ychwanegu + +# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal. +topsites_form_add_header=Hoff Wefan Newydd +topsites_form_edit_header=Golygu'r Hoff Wefan +topsites_form_title_placeholder=Rhoi teitl +topsites_form_url_placeholder=Teipio neu ludo URL +topsites_form_add_button=Ychwanegu +topsites_form_save_button=Cadw +topsites_form_cancel_button=Diddymu +topsites_form_url_validation=Mae angen URL Ddilys + +# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the +# trending stories section and precedes a list of links to popular topics. +pocket_read_more=Pynciau Poblogaidd: +# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the +# end of the list of popular topic links. +pocket_read_even_more=Gweld Rhagor o Straeon +# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction +# to Pocket as part of the feedback form. +pocket_feedback_header=Y gorau o'r we, wedi ei gasglu gan dros 25 miliwn o bobl. +# LOCALIZATION NOTE (pocket_feedback_body): This is shown below +# (pocket_feedback_header) to provide more information about Pocket. +pocket_feedback_body=Gall Pocket, sy'n rhan o deulu Mozilla, eich helpu i ganfod cynnwys o ansawdd uchel na fyddech wedi eu canfod fel arall. +pocket_send_feedback=Anfon Adborth + +# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations, +# in the space that would have shown a few stories, this is shown instead. +# {provider} is replaced by the name of the content provider for this section. +topstories_empty_state=Rydych wedi dal i fynDewch nôl rhywbryd eto am fwy o'r straeon pwysicaf gan {provider}. Methu aros? Dewiswch bwnc poblogaidd i ganfod straeon da o ar draws y we. + +# LOCALIZATION NOTE (manual_migration_explanation): This message is shown to encourage users to +# import their browser profile from another browser they might be using. +manual_migration_explanation=Profwch Firefox gyda'ch hoff wefannau a nodau tudalen o borwr arall. +# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the +# process of importing another browser’s profile into Firefox. +manual_migration_cancel_button=Dim Diolch +# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process +# of importing another browser’s profile profile into Firefox. +manual_migration_import_button=Mewnforio Nawr diff --git a/locales/da/strings.properties b/locales/da/strings.properties index f5afa465cd..99d0309c9c 100644 --- a/locales/da/strings.properties +++ b/locales/da/strings.properties @@ -2,7 +2,19 @@ newtab_page_title=Nyt faneblad default_label_loading=Indlæser… header_top_sites=Mest besøgte websider -header_highlights=Højdepunkter +header_stories=Tophistorier +header_visit_again=Besøg igen +header_bookmarks=Seneste bogmærker +# LOCALIZATION NOTE(header_recommended_by): This is followed by the name +# of the corresponding content provider. +header_recommended_by=Anbefalet af {provider} +# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is +# meant to inform that section contains no information because +# the user hasn't added any bookmarks. +header_bookmarks_placeholder=Du har ingen bogmærker endnu. +# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the +# corresponding content (stories) provider +header_stories_from=fra # LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give # context on how the element is related to the user, e.g. type indicates that @@ -10,9 +22,11 @@ header_highlights=Højdepunkter type_label_visited=Besøgt type_label_bookmarked=Bogmærket type_label_synced=Synkroniseret fra en anden enhed +type_label_recommended=Populært # LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open" type_label_open=Åben type_label_topic=Emne +type_label_now=Nu # LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context # menu and are meant as a call to action for a given page. @@ -26,6 +40,14 @@ menu_action_open_new_window=Åbn i et nyt vindue menu_action_open_private_window=Åbn i et nyt privat vindue menu_action_dismiss=Afvis menu_action_delete=Slet fra historik +menu_action_pin=Fastgør +menu_action_unpin=Frigør +confirm_history_delete_p1=Er du sikker på, at du vil slette alle forekomster af denne side fra din historik? +# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in +# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a +# page from history. +confirm_history_delete_notice_p2=Denne handling kan ikke fortrydes. +menu_action_save_to_pocket=Gem til Pocket # LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder # for what the user has typed in the search input field, e.g. 'Search for ' + @@ -47,6 +69,10 @@ search_header={search_engine_name}-søgning search_web_placeholder=Søg på internettet search_settings=Skift søgeindstillinger +# LOCALIZATION NOTE (section_info_option): This is the screenreader text for the +# (?) icon that would show a section's description with optional feedback link. +section_info_option=Info + # LOCALIZATION NOTE (welcome_*): This is shown as a modal dialog, typically on a # first-run experience when there's no data to display yet welcome_title=Velkommen til nyt faneblad @@ -69,8 +95,12 @@ settings_pane_search_body=Søg på nettet fra Nyt faneblad. settings_pane_topsites_header=Mest besøgte websider settings_pane_topsites_body=Adgang til de websider, du besøger oftest. settings_pane_topsites_options_showmore=Vis to rækker -settings_pane_highlights_header=Højdepunkter -settings_pane_highlights_body=Se tilbage på din seneste browserhistorik og nyligt oprettede bogmærker. +settings_pane_bookmarks_header=Seneste bogmærker +settings_pane_bookmarks_body=Dine seneste bogmærker samlet ét sted. +settings_pane_visit_again_header=Besøg igen +settings_pane_visit_again_body=Firefox viser dig dele af din browserhistorik, som du måske vil huske på eller vende tilbage til. +settings_pane_pocketstories_header=Tophistorier +settings_pane_pocketstories_body=Pocket, en del af Mozilla-familien, hjælper dig med at opdage indhold af høj kvalitet, som du måske ellers ikke ville have fundet. settings_pane_done_button=Færdig # LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal @@ -81,5 +111,46 @@ edit_topsites_showmore_button=Vis flere edit_topsites_showless_button=Vis færre edit_topsites_done_button=Færdig edit_topsites_pin_button=Fastgør denne webside +edit_topsites_unpin_button=Frigør denne webside edit_topsites_edit_button=Rediger denne webside edit_topsites_dismiss_button=Afvis denne webside +edit_topsites_add_button=Tilføj + +# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal. +topsites_form_add_header=Ny webside +topsites_form_edit_header=Rediger mest besøgte webside +topsites_form_title_placeholder=Indtast en titel +topsites_form_url_placeholder=Indtast eller indsæt en URL +topsites_form_add_button=Tilføj +topsites_form_save_button=Gem +topsites_form_cancel_button=Annuller +topsites_form_url_validation=Gyldig URL påkrævet + +# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the +# trending stories section and precedes a list of links to popular topics. +pocket_read_more=Populære emner: +# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the +# end of the list of popular topic links. +pocket_read_even_more=Se flere historier +# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction +# to Pocket as part of the feedback form. +pocket_feedback_header=Det bedste fra nettet, udvalgt af mere end 25 millioner mennesker. +# LOCALIZATION NOTE (pocket_feedback_body): This is shown below +# (pocket_feedback_header) to provide more information about Pocket. +pocket_feedback_body=Pocket, en del af Mozilla-familien, hjælper dig med at opdage indhold af høj kvalitet, som du måske ellers ikke ville have fundet. +pocket_send_feedback=Send feedback + +# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations, +# in the space that would have shown a few stories, this is shown instead. +# {provider} is replaced by the name of the content provider for this section. +topstories_empty_state=Der er ikke flere nye historier. Kom tilbage senere for at se flere tophistorier fra {provider}. Kan du ikke vente? Vælg et populært emne og find flere spændende historier fra hele verden. + +# LOCALIZATION NOTE (manual_migration_explanation): This message is shown to encourage users to +# import their browser profile from another browser they might be using. +manual_migration_explanation=Prøv Firefox med dine favorit-websteder og bogmærker fra en anden browser. +# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the +# process of importing another browser’s profile into Firefox. +manual_migration_cancel_button=Nej tak +# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process +# of importing another browser’s profile profile into Firefox. +manual_migration_import_button=Importer nu diff --git a/locales/de/strings.properties b/locales/de/strings.properties index 075478040a..29e6a9bb5c 100644 --- a/locales/de/strings.properties +++ b/locales/de/strings.properties @@ -2,7 +2,19 @@ newtab_page_title=Neuer Tab default_label_loading=Wird geladen… header_top_sites=Meistbesuchte Seiten -header_highlights=Wichtige Seiten +header_stories=Meistgelesene Meldungen +header_visit_again=Erneut besuchen +header_bookmarks=Neue Lesezeichen +# LOCALIZATION NOTE(header_recommended_by): This is followed by the name +# of the corresponding content provider. +header_recommended_by=Empfohlen von {provider} +# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is +# meant to inform that section contains no information because +# the user hasn't added any bookmarks. +header_bookmarks_placeholder=Sie haben noch keine Lesezeichen. +# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the +# corresponding content (stories) provider +header_stories_from=von # LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give # context on how the element is related to the user, e.g. type indicates that @@ -10,9 +22,11 @@ header_highlights=Wichtige Seiten type_label_visited=Besucht type_label_bookmarked=Lesezeichen type_label_synced=Von anderem Gerät synchronisiert +type_label_recommended=Populär # LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open" type_label_open=Geöffnet type_label_topic=Thema +type_label_now=Jetzt # LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context # menu and are meant as a call to action for a given page. @@ -26,6 +40,14 @@ menu_action_open_new_window=In neuem Fenster öffnen menu_action_open_private_window=In neuem privaten Fenster öffnen menu_action_dismiss=Schließen menu_action_delete=Aus Chronik löschen +menu_action_pin=Anheften +menu_action_unpin=Lösen +confirm_history_delete_p1=Soll wirklich jede Instanz dieser Seite aus Ihrer Chronik gelöscht werden? +# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in +# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a +# page from history. +confirm_history_delete_notice_p2=Diese Aktion kann nicht rückgängig gemacht werden. +menu_action_save_to_pocket=Bei Pocket speichern # LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder # for what the user has typed in the search input field, e.g. 'Search for ' + @@ -47,6 +69,10 @@ search_header={search_engine_name}-Suche search_web_placeholder=Das Web durchsuchen search_settings=Sucheinstellungen ändern +# LOCALIZATION NOTE (section_info_option): This is the screenreader text for the +# (?) icon that would show a section's description with optional feedback link. +section_info_option=Info + # LOCALIZATION NOTE (welcome_*): This is shown as a modal dialog, typically on a # first-run experience when there's no data to display yet welcome_title=Willkommen im neuen Tab @@ -68,9 +94,13 @@ settings_pane_search_header=Suche settings_pane_search_body=Suchen Sie aus einem neuen Tab im Internet. settings_pane_topsites_header=Meistbesuchte Seiten settings_pane_topsites_body=Schneller Zugriff auf Ihre meistbesuchten Websites. -settings_pane_topsites_options_showmore=Zwei Spalten anzeigen -settings_pane_highlights_header=Meistbesuchte Seiten -settings_pane_highlights_body=Übersicht über Ihre zuletzt besuchten Seiten und neuen Lesezeichen. +settings_pane_topsites_options_showmore=Zwei Reihen anzeigen +settings_pane_bookmarks_header=Neue Lesezeichen +settings_pane_bookmarks_body=Ihre neu erstellten Lesezeichen praktisch an einem Ort. +settings_pane_visit_again_header=Erneut besuchen +settings_pane_visit_again_body=Firefox zeigt Ihnen Teile Ihrer Surf-Chronik, die Sie sich vielleicht merken oder erneut besuchen möchten. +settings_pane_pocketstories_header=Meistgelesene Meldungen +settings_pane_pocketstories_body=Pocket, ein Teil der Mozilla-Familie, hilft Ihnen beim Finden von qualitativ hochwertigen Inhalten, die Sie ansonsten vielleicht nicht gefunden hätten. settings_pane_done_button=Fertig # LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal @@ -81,5 +111,46 @@ edit_topsites_showmore_button=Mehr anzeigen edit_topsites_showless_button=Weniger anzeigen edit_topsites_done_button=Fertig edit_topsites_pin_button=Website immer in aktueller Position anzeigen +edit_topsites_unpin_button=Diese Website lösen edit_topsites_edit_button=Diese Website bearbeiten edit_topsites_dismiss_button=Website entfernen +edit_topsites_add_button=Hinzufügen + +# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal. +topsites_form_add_header=Neue meistbesuchte Seite +topsites_form_edit_header=Meistbesuchte Seite bearbeiten +topsites_form_title_placeholder=Titel eingeben +topsites_form_url_placeholder=Eine URL eingeben oder einfügen +topsites_form_add_button=Hinzufügen +topsites_form_save_button=Speichern +topsites_form_cancel_button=Abbrechen +topsites_form_url_validation=Gültige URL erforderlich + +# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the +# trending stories section and precedes a list of links to popular topics. +pocket_read_more=Beliebte Themen: +# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the +# end of the list of popular topic links. +pocket_read_even_more=Weitere Nachrichten ansehen +# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction +# to Pocket as part of the feedback form. +pocket_feedback_header=Das Beste aus dem Web, zusammengetragen von 25 Millionen Menschen. +# LOCALIZATION NOTE (pocket_feedback_body): This is shown below +# (pocket_feedback_header) to provide more information about Pocket. +pocket_feedback_body=Pocket, ein Teil der Mozilla-Familie, hilft Ihnen beim Finden von qualitativ hochwertigen Inhalten, die Sie ansonsten vielleicht nicht gefunden hätten. +pocket_send_feedback=Feedback senden + +# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations, +# in the space that would have shown a few stories, this is shown instead. +# {provider} is replaced by the name of the content provider for this section. +topstories_empty_state=Jetzt kennen Sie die Neuigkeiten. Schauen Sie später wieder vorbei, um neue Informationen von {provider} zu erhalten. Können sie nicht warten? Wählen Sie ein beliebtes Thema und lesen Sie weitere interessante Geschichten aus dem Internet. + +# LOCALIZATION NOTE (manual_migration_explanation): This message is shown to encourage users to +# import their browser profile from another browser they might be using. +manual_migration_explanation=Nutzen Sie Firefox mit Ihren Lieblings-Websites und Lesezeichen aus einem anderen Browser. +# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the +# process of importing another browser’s profile into Firefox. +manual_migration_cancel_button=Nein, danke +# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process +# of importing another browser’s profile profile into Firefox. +manual_migration_import_button=Jetzt importieren diff --git a/locales/dsb/strings.properties b/locales/dsb/strings.properties index 4c0f1a7b87..1fd457d934 100644 --- a/locales/dsb/strings.properties +++ b/locales/dsb/strings.properties @@ -2,7 +2,19 @@ newtab_page_title=Nowy rejtark default_label_loading=Zacytujo se… header_top_sites=Nejcesćej woglědane sedła -header_highlights=Wjerški +header_stories=Nejcesćej pśecytane powěźenki +header_visit_again=Hyšći raz se woglědaś +header_bookmarks=Nejnowše cytańske znamjenja +# LOCALIZATION NOTE(header_recommended_by): This is followed by the name +# of the corresponding content provider. +header_recommended_by=Wót {provider} dopórucony +# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is +# meant to inform that section contains no information because +# the user hasn't added any bookmarks. +header_bookmarks_placeholder=Hyšći cytańske znamjenja njamaśo. +# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the +# corresponding content (stories) provider +header_stories_from=wót # LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give # context on how the element is related to the user, e.g. type indicates that @@ -10,9 +22,11 @@ header_highlights=Wjerški type_label_visited=Woglědany type_label_bookmarked=Ako cytańske znamje skłaźony type_label_synced=Z drugego rěda synchronizěrowany +type_label_recommended=Popularny # LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open" type_label_open=Wócynjony type_label_topic=Tema +type_label_now=Něnto # LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context # menu and are meant as a call to action for a given page. @@ -26,6 +40,14 @@ menu_action_open_new_window=W nowem woknje wócyniś menu_action_open_private_window=W nowem priwatnem woknje wócyniś menu_action_dismiss=Zachyśiś menu_action_delete=Z historije lašowaś +menu_action_pin=Pśipěś +menu_action_unpin=Wótpěś +confirm_history_delete_p1=Cośo napšawdu kuždu instancu toś togo boka ze swójeje historije lašowaś? +# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in +# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a +# page from history. +confirm_history_delete_notice_p2=Toś ta akcija njedajo se anulěrowaś. +menu_action_save_to_pocket=Pla Pocket składowaś # LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder # for what the user has typed in the search input field, e.g. 'Search for ' + @@ -47,6 +69,10 @@ search_header=Z {search_engine_name} pytaś search_web_placeholder=Web pśepytaś search_settings=Pytańske nastajenja změniś +# LOCALIZATION NOTE (section_info_option): This is the screenreader text for the +# (?) icon that would show a section's description with optional feedback link. +section_info_option=Info + # LOCALIZATION NOTE (welcome_*): This is shown as a modal dialog, typically on a # first-run experience when there's no data to display yet welcome_title=Witajśo k nowemu rejtarkoju @@ -69,8 +95,12 @@ settings_pane_search_body=Pśepytajśo web ze swójogo nowego rejtarka. settings_pane_topsites_header=Nejcesćej woglědane sedła settings_pane_topsites_body=Wócyńśo websedła, kótarež sćo se nejcesćej woglědał. settings_pane_topsites_options_showmore=Dwě smužki pokazaś -settings_pane_highlights_header=Wjerški -settings_pane_highlights_body=Woglědajśo se nejnowšu pśeglědowańsku historiju a nowo napórane cytańske znamjenja. +settings_pane_bookmarks_header=Nejnowše cytańske znamjenja +settings_pane_bookmarks_body=Waše nowo załožone cytańske znamjenja ned k ruce. +settings_pane_visit_again_header=Hyšći raz se woglědaś +settings_pane_visit_again_body=Firefox wam źěle wašeje pśeglědowańskeje historije pokazaś, kótarež cośo se snaź spomnjeś abo na kótarež cośo slědk pśiś. +settings_pane_pocketstories_header=Nejcesćej pśecytane powěźenki +settings_pane_pocketstories_body=Pocket, źěl familije Mozilla, buźo pomagaś, was z wopśimjeśim wusokeje kwality zwězowaś, kótaryž njeby wy snaź howac namakał. settings_pane_done_button=Gótowo # LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal @@ -81,5 +111,46 @@ edit_topsites_showmore_button=Wěcej pokazaś edit_topsites_showless_button=Mjenjej pokazaś edit_topsites_done_button=Gótowo edit_topsites_pin_button=Sedło pśipěś +edit_topsites_unpin_button=Toś to sedło wótpěś edit_topsites_edit_button=Toś to sedło wobźěłaś edit_topsites_dismiss_button=Sedło zachyśiś +edit_topsites_add_button=Pśidaś + +# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal. +topsites_form_add_header=Nowe nejcesćej woglědane sedło +topsites_form_edit_header=Nejcesćej woglědane sedło wobźěłaś +topsites_form_title_placeholder=Titel zapódaś +topsites_form_url_placeholder=URL zapódaś abo zasajźiś +topsites_form_add_button=Pśidaś +topsites_form_save_button=Składowaś +topsites_form_cancel_button=Pśetergnuś +topsites_form_url_validation=Płaśiwy URL trěbny + +# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the +# trending stories section and precedes a list of links to popular topics. +pocket_read_more=Woblubowane temy: +# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the +# end of the list of popular topic links. +pocket_read_even_more=Dalšne powěźeńki se woglědaś +# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction +# to Pocket as part of the feedback form. +pocket_feedback_header=Nejlěpše z weba, zezběrane wót wěcej ako 25 milionow luźi. +# LOCALIZATION NOTE (pocket_feedback_body): This is shown below +# (pocket_feedback_header) to provide more information about Pocket. +pocket_feedback_body=Pocket, źěl familije Mozilla, buźo pomagaś, was z wopśimjeśim wusokeje kwality zwězowaś, kótaryž njeby wy snaź howac namakał. +pocket_send_feedback=Komentar pósłaś + +# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations, +# in the space that would have shown a few stories, this is shown instead. +# {provider} is replaced by the name of the content provider for this section. +topstories_empty_state=To jo nachylu wšykno. Wrośćo se pózdźej wjelicnych tšojeńkow dla wót {provider}. Njamóžośo cakaś? Wubjeŕśo woblubowanu temu, aby dalšne wjelicne tšojeńka we webje namakał. + +# LOCALIZATION NOTE (manual_migration_explanation): This message is shown to encourage users to +# import their browser profile from another browser they might be using. +manual_migration_explanation=Wopytajśo Firefox ze swójimi nejlubšymi websedłami a cytańskimi znamjenjami z drugego wobglědowaka. +# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the +# process of importing another browser’s profile into Firefox. +manual_migration_cancel_button=Ně, źěkujom se +# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process +# of importing another browser’s profile profile into Firefox. +manual_migration_import_button=Něnto importěrowaś diff --git a/locales/el/strings.properties b/locales/el/strings.properties index b65d1272c0..e272d1f8b0 100644 --- a/locales/el/strings.properties +++ b/locales/el/strings.properties @@ -2,7 +2,19 @@ newtab_page_title=Νέα καρτέλα default_label_loading=Φόρτωση… header_top_sites=Κορυφαίες ιστοσελίδες -header_highlights=Κορυφαίες στιγμές +header_stories=Κορυφαίες ιστορίες +header_visit_again=Επίσκεψη ξανά +header_bookmarks=Πρόσφατοι σελιδοδείκτες +# LOCALIZATION NOTE(header_recommended_by): This is followed by the name +# of the corresponding content provider. +header_recommended_by=Προτεινόμενο από τον πάροχο {provider} +# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is +# meant to inform that section contains no information because +# the user hasn't added any bookmarks. +header_bookmarks_placeholder=Δεν έχετε κανένα σελιδοδείκτη ακόμα. +# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the +# corresponding content (stories) provider +header_stories_from=από # LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give # context on how the element is related to the user, e.g. type indicates that @@ -10,9 +22,11 @@ header_highlights=Κορυφαίες στιγμές type_label_visited=Από ιστορικό type_label_bookmarked=Από σελιδοδείκτες type_label_synced=Συγχρονισμένα από άλλη συσκευή +type_label_recommended=Τάσεις # LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open" type_label_open=Ανοικτό type_label_topic=Θέμα +type_label_now=Τώρα # LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context # menu and are meant as a call to action for a given page. @@ -26,6 +40,14 @@ menu_action_open_new_window=Άνοιγμα σε νέο παράθυρο menu_action_open_private_window=Άνοιγμα σε νέο ιδιωτικό παράθυρο menu_action_dismiss=Απόρριψη menu_action_delete=Διαγραφή από ιστορικό +menu_action_pin=Καρφίτσωμα +menu_action_unpin=Ξεκαρφίτσωμα +confirm_history_delete_p1=Θέλετε σίγουρα να διαγράψετε κάθε παρουσία της σελίδας αυτής από το ιστορικό σας; +# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in +# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a +# page from history. +confirm_history_delete_notice_p2=Αυτή η ενέργεια δεν μπορεί να αναιρεθεί. +menu_action_save_to_pocket=Αποθήκευση στο Pocket # LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder # for what the user has typed in the search input field, e.g. 'Search for ' + @@ -47,6 +69,10 @@ search_header=Αναζήτηση {search_engine_name} search_web_placeholder=Αναζήτηση στον ιστό search_settings=Αλλαγή ρυθμίσεων αναζήτησης +# LOCALIZATION NOTE (section_info_option): This is the screenreader text for the +# (?) icon that would show a section's description with optional feedback link. +section_info_option=Πληροφορίες + # LOCALIZATION NOTE (welcome_*): This is shown as a modal dialog, typically on a # first-run experience when there's no data to display yet welcome_title=Καλώς ορίσατε στη νέα καρτέλα @@ -69,8 +95,12 @@ settings_pane_search_body=Αναζήτηση στο διαδίκτυο από τ settings_pane_topsites_header=Κορυφαίες ιστοσελίδες settings_pane_topsites_body=Πρόσβαση στις ιστοσελίδες που επισκέπτεστε περισσότερο. settings_pane_topsites_options_showmore=Εμφάνιση δύο σειρών -settings_pane_highlights_header=Κορυφαίες στιγμές -settings_pane_highlights_body=Επιστρέψτε στο πρόσφατο ιστορικό περιήγησης και τους νέους σας σελιδοδείκτες. +settings_pane_bookmarks_header=Πρόσφατοι σελιδοδείκτες +settings_pane_bookmarks_body=Οι νέοι σας σελιδοδείκτες σε μια βολική τοποθεσία. +settings_pane_visit_again_header=Επίσκεψη ξανά +settings_pane_visit_again_body=Το Firefox θα σάς δείξει μέρη του ιστορικού περιήγησής σας που ίσως θέλετε να θυμηθείτε ή να επισκεφθείτε ξανά. +settings_pane_pocketstories_header=Κορυφαίες ιστορίες +settings_pane_pocketstories_body=Το Pocket, ένα μέλος της οικογένειας Mozilla, θα σάς βοηθήσει να ανακαλύψετε περιεχόμενο υψηλής ποιότητας που ίσως να μην βρίσκατε διαφορετικά. settings_pane_done_button=Τέλος # LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal @@ -81,5 +111,46 @@ edit_topsites_showmore_button=Εμφάνιση περισσότερων edit_topsites_showless_button=Εμφάνιση λιγότερων edit_topsites_done_button=Τέλος edit_topsites_pin_button=Καρφίτσωμα ιστοσελίδας +edit_topsites_unpin_button=Ξεκαρφίτσωμα ιστοσελίδας edit_topsites_edit_button=Επεξεργασία ιστοσελίδας edit_topsites_dismiss_button=Απόρριψη ιστοσελίδας +edit_topsites_add_button=Προσθήκη + +# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal. +topsites_form_add_header=Νέα κορυφαία ιστοσελίδα +topsites_form_edit_header=Επεξεργασία κορυφαίας ιστοσελίδας +topsites_form_title_placeholder=Εισάγετε έναν τίτλο +topsites_form_url_placeholder=Πληκτρολόγηση ή επικόλληση ενός URL +topsites_form_add_button=Προσθήκη +topsites_form_save_button=Αποθήκευση +topsites_form_cancel_button=Ακύρωση +topsites_form_url_validation=Απαιτείται έγκυρο URL + +# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the +# trending stories section and precedes a list of links to popular topics. +pocket_read_more=Δημοφιλή θέματα: +# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the +# end of the list of popular topic links. +pocket_read_even_more=Προβολή περισσότερων ιστοριών +# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction +# to Pocket as part of the feedback form. +pocket_feedback_header=Τα καλύτερα του διαδικτύου, παρέχονται από πάνω από 25 εκατομμύρια άτομα. +# LOCALIZATION NOTE (pocket_feedback_body): This is shown below +# (pocket_feedback_header) to provide more information about Pocket. +pocket_feedback_body=Το Pocket, ένα μέλος της οικογένειας Mozilla, θα σάς βοηθήσει να ανακαλύψετε περιεχόμενο υψηλής ποιότητας που ίσως να μην βρίσκατε διαφορετικά. +pocket_send_feedback=Αποστολή σχολίων + +# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations, +# in the space that would have shown a few stories, this is shown instead. +# {provider} is replaced by the name of the content provider for this section. +topstories_empty_state=Δεν υπάρχει κάτι νεότερο. Ελέγξτε αργότερα για περισσότερες ιστορίες από τον πάροχο {provider}. Δεν μπορείτε να περιμένετε; Διαλέξτε κάποιο από τα δημοφιλή θέματα και ανακαλύψτε ενδιαφέρουσες ιστορίες από όλο τον Ιστό. + +# LOCALIZATION NOTE (manual_migration_explanation): This message is shown to encourage users to +# import their browser profile from another browser they might be using. +manual_migration_explanation=Δοκιμάστε τον Firefox για τις αγαπημένες σας σελίδες και σελιδοδείκτες από άλλους περιηγητές. +# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the +# process of importing another browser’s profile into Firefox. +manual_migration_cancel_button=Όχι ευχαριστώ +# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process +# of importing another browser’s profile profile into Firefox. +manual_migration_import_button=Εισαγωγή τώρα diff --git a/locales/en-GB/strings.properties b/locales/en-GB/strings.properties index 69ac045e0d..b0d348cc91 100644 --- a/locales/en-GB/strings.properties +++ b/locales/en-GB/strings.properties @@ -2,7 +2,16 @@ newtab_page_title=New Tab default_label_loading=Loading… header_top_sites=Top Sites -header_highlights=Highlights +header_stories=Top Stories +header_visit_again=Visit Again +header_bookmarks=Recent Bookmarks +# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is +# meant to inform that section contains no information because +# the user hasn't added any bookmarks. +header_bookmarks_placeholder=You don’t have any bookmarks yet. +# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the +# corresponding content (stories) provider +header_stories_from=from # LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give # context on how the element is related to the user, e.g. type indicates that @@ -10,6 +19,7 @@ header_highlights=Highlights type_label_visited=Visited type_label_bookmarked=Bookmarked type_label_synced=Synchronised from another device +type_label_recommended=Trending # LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open" type_label_open=Open type_label_topic=Topic @@ -26,6 +36,14 @@ menu_action_open_new_window=Open in a New Window menu_action_open_private_window=Open in a New Private Window menu_action_dismiss=Dismiss menu_action_delete=Delete from History +menu_action_pin=Pin +menu_action_unpin=Unpin +confirm_history_delete_p1=Are you sure you want to delete every instance of this page from your history? +# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in +# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a +# page from history. +confirm_history_delete_notice_p2=This action cannot be undone. +menu_action_save_to_pocket=Save to Pocket # LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder # for what the user has typed in the search input field, e.g. 'Search for ' + @@ -69,8 +87,12 @@ settings_pane_search_body=Search the Web from your new tab. settings_pane_topsites_header=Top Sites settings_pane_topsites_body=Access the web sites you visit most. settings_pane_topsites_options_showmore=Show two rows -settings_pane_highlights_header=Highlights -settings_pane_highlights_body=Look back at your recent browsing history and newly created bookmarks. +settings_pane_bookmarks_header=Recent Bookmarks +settings_pane_bookmarks_body=Your newly created bookmarks in one handy location. +settings_pane_visit_again_header=Visit Again +settings_pane_visit_again_body=Firefox will show you parts of your browsing history that you might want to remember or get back to. +settings_pane_pocketstories_header=Top Stories +settings_pane_pocketstories_body=Pocket, a part of the Mozilla family, will help connect you to high-quality content that you may not have found otherwise. settings_pane_done_button=Done # LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal @@ -81,5 +103,31 @@ edit_topsites_showmore_button=Show more edit_topsites_showless_button=Show less edit_topsites_done_button=Done edit_topsites_pin_button=Pin this site +edit_topsites_unpin_button=Unpin this site edit_topsites_edit_button=Edit this site edit_topsites_dismiss_button=Dismiss this site +edit_topsites_add_button=Add + +# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal. +topsites_form_add_header=Top Sites +topsites_form_edit_header=Edit Top Site +topsites_form_title_placeholder=Enter a title +topsites_form_url_placeholder=Type or paste a URL +topsites_form_add_button=Add +topsites_form_save_button=Save +topsites_form_cancel_button=Cancel +topsites_form_url_validation=Valid URL required + +# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the +# trending stories section and precedes a list of links to popular topics. +pocket_read_more=Popular Topics: +# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the +# end of the list of popular topic links. +pocket_read_even_more=View More Stories +# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction +# to Pocket as part of the feedback form. +pocket_feedback_header=The best of the web, curated by over 25 million people. +# LOCALIZATION NOTE (pocket_feedback_body): This is shown below +# (pocket_feedback_header) to provide more information about Pocket. +pocket_feedback_body=Pocket, a part of the Mozilla family, will help connect you to high-quality content that you may not have found otherwise. +pocket_send_feedback=Send Feedback diff --git a/locales/en-US/strings.properties b/locales/en-US/strings.properties index afe5a9d320..a8fc1c5208 100644 --- a/locales/en-US/strings.properties +++ b/locales/en-US/strings.properties @@ -2,13 +2,16 @@ newtab_page_title=New Tab default_label_loading=Loading… header_top_sites=Top Sites -header_highlights=Highlights header_stories=Top Stories +header_visit_again=Visit Again header_bookmarks=Recent Bookmarks +# LOCALIZATION NOTE(header_recommended_by): This is followed by the name +# of the corresponding content provider. +header_recommended_by=Recommended by {provider} # LOCALIZATION NOTE(header_bookmarks_placeholder): This message is # meant to inform that section contains no information because # the user hasn't added any bookmarks. -header_bookmarks_placeholder=You don't have any bookmarks yet. +header_bookmarks_placeholder=You don’t have any bookmarks yet. # LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the # corresponding content (stories) provider header_stories_from=from @@ -23,6 +26,7 @@ type_label_recommended=Trending # LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open" type_label_open=Open type_label_topic=Topic +type_label_now=Now # LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context # menu and are meant as a call to action for a given page. @@ -36,6 +40,13 @@ menu_action_open_new_window=Open in a New Window menu_action_open_private_window=Open in a New Private Window menu_action_dismiss=Dismiss menu_action_delete=Delete from History +menu_action_pin=Pin +menu_action_unpin=Unpin +confirm_history_delete_p1=Are you sure you want to delete every instance of this page from your history? +# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in +# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a +# page from history. +confirm_history_delete_notice_p2=This action cannot be undone. menu_action_save_to_pocket=Save to Pocket # LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder @@ -58,6 +69,10 @@ search_header={search_engine_name} Search search_web_placeholder=Search the Web search_settings=Change Search Settings +# LOCALIZATION NOTE (section_info_option): This is the screenreader text for the +# (?) icon that would show a section's description with optional feedback link. +section_info_option=Info + # LOCALIZATION NOTE (welcome_*): This is shown as a modal dialog, typically on a # first-run experience when there's no data to display yet welcome_title=Welcome to new tab @@ -80,10 +95,10 @@ settings_pane_search_body=Search the Web from your new tab. settings_pane_topsites_header=Top Sites settings_pane_topsites_body=Access the websites you visit most. settings_pane_topsites_options_showmore=Show two rows -settings_pane_highlights_header=Highlights -settings_pane_highlights_body=Look back at your recent browsing history and newly created bookmarks. settings_pane_bookmarks_header=Recent Bookmarks settings_pane_bookmarks_body=Your newly created bookmarks in one handy location. +settings_pane_visit_again_header=Visit Again +settings_pane_visit_again_body=Firefox will show you parts of your browsing history that you might want to remember or get back to. settings_pane_pocketstories_header=Top Stories settings_pane_pocketstories_body=Pocket, a part of the Mozilla family, will help connect you to high-quality content that you may not have found otherwise. settings_pane_done_button=Done @@ -92,8 +107,8 @@ settings_pane_done_button=Done # dialog. edit_topsites_button_text=Edit edit_topsites_button_label=Customize your Top Sites section -edit_topsites_showmore_button=Show more -edit_topsites_showless_button=Show less +edit_topsites_showmore_button=Show More +edit_topsites_showless_button=Show Fewer edit_topsites_done_button=Done edit_topsites_pin_button=Pin this site edit_topsites_unpin_button=Unpin this site @@ -124,3 +139,18 @@ pocket_feedback_header=The best of the web, curated by over 25 million people. # (pocket_feedback_header) to provide more information about Pocket. pocket_feedback_body=Pocket, a part of the Mozilla family, will help connect you to high-quality content that you may not have found otherwise. pocket_send_feedback=Send Feedback + +# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations, +# in the space that would have shown a few stories, this is shown instead. +# {provider} is replaced by the name of the content provider for this section. +topstories_empty_state=You’ve caught up. Check back later for more top stories from {provider}. Can’t wait? Select a popular topic to find more great stories from around the web. + +# LOCALIZATION NOTE (manual_migration_explanation): This message is shown to encourage users to +# import their browser profile from another browser they might be using. +manual_migration_explanation=Try Firefox with your favorite sites and bookmarks from another browser. +# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the +# process of importing another browser’s profile into Firefox. +manual_migration_cancel_button=No Thanks +# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process +# of importing another browser’s profile profile into Firefox. +manual_migration_import_button=Import Now diff --git a/locales/eo/strings.properties b/locales/eo/strings.properties index c2838d21f9..50ae6140d5 100644 --- a/locales/eo/strings.properties +++ b/locales/eo/strings.properties @@ -2,7 +2,16 @@ newtab_page_title=Nova legosigno default_label_loading=Ŝargado… header_top_sites=Plej vizititaj -header_highlights=Elstaraĵoj +header_stories=Ĉefaj artikoloj +header_visit_again=Viziti denove +header_bookmarks=Ĵusaj legosignoj +# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is +# meant to inform that section contains no information because +# the user hasn't added any bookmarks. +header_bookmarks_placeholder=Vi ankoraŭ ne havas legosignojn. +# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the +# corresponding content (stories) provider +header_stories_from=el # LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give # context on how the element is related to the user, e.g. type indicates that @@ -10,6 +19,7 @@ header_highlights=Elstaraĵoj type_label_visited=Vizititaj type_label_bookmarked=Kun legosigno type_label_synced=Spegulitaj el alia aparato +type_label_recommended=Tendencoj # LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open" type_label_open=Malfermita type_label_topic=Temo @@ -26,6 +36,14 @@ menu_action_open_new_window=Malfermi en nova fenestro menu_action_open_private_window=Malfermi en nova privata fenestro menu_action_dismiss=Ignori menu_action_delete=Forigi el historio +menu_action_pin=Alpingli +menu_action_unpin=Depingli +confirm_history_delete_p1=Ĉu vi certe volas forigi ĉiun aperon de tiu ĉi paĝo el via historio? +# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in +# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a +# page from history. +confirm_history_delete_notice_p2=Tiu ĉi ago ne estas malfarebla. +menu_action_save_to_pocket=Konservi en Pocket # LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder # for what the user has typed in the search input field, e.g. 'Search for ' + @@ -62,6 +80,54 @@ time_label_day={number}t # LOCALIZATION NOTE (settings_pane_*): This is shown in the Settings Pane sidebar. settings_pane_button_label=Personecigi la paĝon por novaj langetoj +settings_pane_header=Preferoj pri nova langeto +settings_pane_body=Elekti tion, kio estos videbla je malfermo de nova langeto. +settings_pane_search_header=Serĉi +settings_pane_search_body=Serĉi la Teksaĵon el via nova langeto. +settings_pane_topsites_header=Plej vizitaj +settings_pane_topsites_body=Aliri la plej ofte vizitajn retejojn. +settings_pane_topsites_options_showmore=Montri en du vicoj +settings_pane_bookmarks_header=Ĵusaj legosignoj +settings_pane_bookmarks_body=Viaj ĵus kreitaj legosignoj, ĉemane. +settings_pane_visit_again_header=Viziti denove +settings_pane_visit_again_body=Firefoĉ montros al vi partojn de via retuma historio, kiujn vi eble volas memori aŭ viziti denove. +settings_pane_pocketstories_header=Ĉefaj artikoloj +settings_pane_pocketstories_body=Pocket, parto de la familio de Mozilla, helpos vin trovi altkvalitan enhavon, kiun vi eble ne trovos aliloke. +settings_pane_done_button=Farita # LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal # dialog. +edit_topsites_button_text=Redakti +edit_topsites_button_label=Personecigi la sekcion 'plej vizititaj' +edit_topsites_showmore_button=Montri pli +edit_topsites_showless_button=Montri malpli +edit_topsites_done_button=Farita +edit_topsites_pin_button=Alpingli ĉi tiun retejon +edit_topsites_unpin_button=Depingli tiun ĉi retejon +edit_topsites_edit_button=Redakti ĉi tiun retejon +edit_topsites_dismiss_button=Ignori ĉi tiun retejon +edit_topsites_add_button=Aldoni + +# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal. +topsites_form_add_header=Nova ofta retejo +topsites_form_edit_header=Redakti ofta retejo +topsites_form_title_placeholder=Tajpu titolon +topsites_form_url_placeholder=Tajpu aŭ alguu retadreson +topsites_form_add_button=Aldoni +topsites_form_save_button=Konservi +topsites_form_cancel_button=Nuligi +topsites_form_url_validation=Valida retadreso estas postulata + +# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the +# trending stories section and precedes a list of links to popular topics. +pocket_read_more=Ĉefaj temoj: +# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the +# end of the list of popular topic links. +pocket_read_even_more=Montri pli da artikoloj +# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction +# to Pocket as part of the feedback form. +pocket_feedback_header=La plejbono el la Teksaĵo, reviziita de pli ol 25 milionoj da personoj. +# LOCALIZATION NOTE (pocket_feedback_body): This is shown below +# (pocket_feedback_header) to provide more information about Pocket. +pocket_feedback_body=Pocket, parto de la familio de Mozilla, helpos vin trovi altkvalitan enhavon, kiun vi eble ne trovos aliloke. +pocket_send_feedback=Sendi komentojn diff --git a/locales/es-AR/strings.properties b/locales/es-AR/strings.properties index eed2409bd2..fc33f7416d 100644 --- a/locales/es-AR/strings.properties +++ b/locales/es-AR/strings.properties @@ -2,7 +2,19 @@ newtab_page_title=Nueva pestaña default_label_loading=Cargando… header_top_sites=Más visitados -header_highlights=Destacados +header_stories=Historias principales +header_visit_again=Visitar de nuevo +header_bookmarks=Marcadores recientes +# LOCALIZATION NOTE(header_recommended_by): This is followed by the name +# of the corresponding content provider. +header_recommended_by=Recomendado por {provider} +# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is +# meant to inform that section contains no information because +# the user hasn't added any bookmarks. +header_bookmarks_placeholder=Todavía no hay ningún marcador. +# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the +# corresponding content (stories) provider +header_stories_from=de # LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give # context on how the element is related to the user, e.g. type indicates that @@ -10,9 +22,11 @@ header_highlights=Destacados type_label_visited=Visitados type_label_bookmarked=Marcados type_label_synced=Sincronizados de otro dispositivo +type_label_recommended=Tendencias # LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open" type_label_open=Abrir type_label_topic=Tópico +type_label_now=Ahora # LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context # menu and are meant as a call to action for a given page. @@ -26,6 +40,14 @@ menu_action_open_new_window=Abrir en nueva ventana menu_action_open_private_window=Abrir en nueva ventana privada menu_action_dismiss=Descartar menu_action_delete=Borrar del historial +menu_action_pin=Pegar +menu_action_unpin=Despegar +confirm_history_delete_p1=¿Está seguro de querer borrar cualquier instancia de esta página del historial? +# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in +# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a +# page from history. +confirm_history_delete_notice_p2=Esta acción no puede deshacerse. +menu_action_save_to_pocket=Guardar en Pocket # LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder # for what the user has typed in the search input field, e.g. 'Search for ' + @@ -47,6 +69,10 @@ search_header=Buscar con {search_engine_name} search_web_placeholder=Buscar en la web search_settings=Cambiar opciones de búsqueda +# LOCALIZATION NOTE (section_info_option): This is the screenreader text for the +# (?) icon that would show a section's description with optional feedback link. +section_info_option=Información + # LOCALIZATION NOTE (welcome_*): This is shown as a modal dialog, typically on a # first-run experience when there's no data to display yet welcome_title=Bienvenido a una nueva pestaña @@ -69,8 +95,12 @@ settings_pane_search_body=Buscar en la Web desde nueva pestaña. settings_pane_topsites_header=Más visitados settings_pane_topsites_body=Acceder a los sitios web más visitados. settings_pane_topsites_options_showmore=Mostrar dos filas -settings_pane_highlights_header=Destacados -settings_pane_highlights_body=Mirar hacia atrás el historial de navegación reciente y los marcadores recién creados. +settings_pane_bookmarks_header=Marcadores recientes +settings_pane_bookmarks_body=Los marcadores recién creados en una ubicación cómoda. +settings_pane_visit_again_header=Visitar de nuevo +settings_pane_visit_again_body=Firefox mostrará partes del historial de navegación que podría querer recordar o volver a visitar. +settings_pane_pocketstories_header=Historias principales +settings_pane_pocketstories_body=Pocket, parte de la familia Mozilla, ayudará a conectarte con contenido de alta calidad que no podrías haber encontrado de otra forma. settings_pane_done_button=Listo # LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal @@ -81,5 +111,45 @@ edit_topsites_showmore_button=Mostrar más edit_topsites_showless_button=Mostrar menos edit_topsites_done_button=Listo edit_topsites_pin_button=Pegar este sitio +edit_topsites_unpin_button=Despegar este sitio edit_topsites_edit_button=Editar este sitio edit_topsites_dismiss_button=Descartar este sitio +edit_topsites_add_button=Agregar + +# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal. +topsites_form_add_header=Nuevo sitio más visitado +topsites_form_edit_header=Editar sitio más visitado +topsites_form_title_placeholder=Ingresar un título +topsites_form_url_placeholder=Escribir o pegar URL +topsites_form_add_button=Agregar +topsites_form_save_button=Guardar +topsites_form_cancel_button=Cancelar +topsites_form_url_validation=Se requiere URL válida + +# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the +# trending stories section and precedes a list of links to popular topics. +pocket_read_more=Tópicos populares: +# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the +# end of the list of popular topic links. +pocket_read_even_more=Ver más historias +# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction +# to Pocket as part of the feedback form. +pocket_feedback_header=Lo mejor de la web, seleccionado por más de 25 millones de personas. +# LOCALIZATION NOTE (pocket_feedback_body): This is shown below +# (pocket_feedback_header) to provide more information about Pocket. +pocket_feedback_body=Pocket, parte de la familia Mozilla, ayudará a conectarte con contenido de alta calidad que no podrías haber encontrado de otra forma. +pocket_send_feedback=Enviar opinión + +# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations, +# in the space that would have shown a few stories, this is shown instead. +# {provider} is replaced by the name of the content provider for this section. + +# LOCALIZATION NOTE (manual_migration_explanation): This message is shown to encourage users to +# import their browser profile from another browser they might be using. +manual_migration_explanation=Probá Firefox con tus sitios favoritos y marcadores de otro navegador. +# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the +# process of importing another browser’s profile into Firefox. +manual_migration_cancel_button=No gracias +# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process +# of importing another browser’s profile profile into Firefox. +manual_migration_import_button=Importar ahora diff --git a/locales/es-CL/strings.properties b/locales/es-CL/strings.properties index a1e64c3045..151b44d40c 100644 --- a/locales/es-CL/strings.properties +++ b/locales/es-CL/strings.properties @@ -2,7 +2,16 @@ newtab_page_title=Nueva pestaña default_label_loading=Cargando… header_top_sites=Sitios frecuentes -header_highlights=Destacados +header_stories=Historias populares +header_visit_again=Volver a visitar +header_bookmarks=Marcadores recientes +# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is +# meant to inform that section contains no information because +# the user hasn't added any bookmarks. +header_bookmarks_placeholder=Todavía no tienes marcadores. +# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the +# corresponding content (stories) provider +header_stories_from=de # LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give # context on how the element is related to the user, e.g. type indicates that @@ -10,6 +19,7 @@ header_highlights=Destacados type_label_visited=Visitado type_label_bookmarked=Marcado type_label_synced=Sacado de otro dispositivo +type_label_recommended=Popular # LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open" type_label_open=Abrir type_label_topic=Tema @@ -26,6 +36,14 @@ menu_action_open_new_window=Abrir en una nueva ventana menu_action_open_private_window=Abrir en una nueva ventana privada menu_action_dismiss=Descartar menu_action_delete=Eliminar del historial +menu_action_pin=Fijar +menu_action_unpin=Soltar +confirm_history_delete_p1=¿Estás seguro de que quieres eliminar cada instancia de esta página de tu historial? +# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in +# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a +# page from history. +confirm_history_delete_notice_p2=Esta acción no puede ser deshecha. +menu_action_save_to_pocket=Guardar en Pocket # LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder # for what the user has typed in the search input field, e.g. 'Search for ' + @@ -69,8 +87,12 @@ settings_pane_search_body=Busca en la Web desde tu nueva pestaña. settings_pane_topsites_header=Sitios frecuentes settings_pane_topsites_body=Accede a los sitios que más visitas. settings_pane_topsites_options_showmore=Mostrar dos filas -settings_pane_highlights_header=Destacados -settings_pane_highlights_body=Dale un vistazo a tu historial de navegación y marcadores recientes. +settings_pane_bookmarks_header=Marcadores recientes +settings_pane_bookmarks_body=Tus marcadores recién creados en un lugar accesible. +settings_pane_visit_again_header=Volver a visitar +settings_pane_visit_again_body=Firefox te mostrará partes de tu historial de navegación que podrías querer recordar o volver a visitar. +settings_pane_pocketstories_header=Historias populares +settings_pane_pocketstories_body=Pocket, una parte de la familia de Mozilla, te ayudará a conectarte con contenido de alta calidad que de otra forma no hubieras encontrado. settings_pane_done_button=Hecho # LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal @@ -81,5 +103,31 @@ edit_topsites_showmore_button=Mostrar más edit_topsites_showless_button=Mostrar menos edit_topsites_done_button=Hecho edit_topsites_pin_button=Fijar este sitio +edit_topsites_unpin_button=Soltar este sitio edit_topsites_edit_button=Editar este sitio edit_topsites_dismiss_button=Sacar este sitio +edit_topsites_add_button=Añadir + +# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal. +topsites_form_add_header=Nuevo sitio frecuente +topsites_form_edit_header=Editar sitio frecuente +topsites_form_title_placeholder=Ingresar un título +topsites_form_url_placeholder=Escribe o pega una URL +topsites_form_add_button=Añadir +topsites_form_save_button=Guardar +topsites_form_cancel_button=Cancelar +topsites_form_url_validation=URL válida requerida + +# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the +# trending stories section and precedes a list of links to popular topics. +pocket_read_more=Temas populares: +# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the +# end of the list of popular topic links. +pocket_read_even_more=Ver más historias +# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction +# to Pocket as part of the feedback form. +pocket_feedback_header=Lo mejor de la web, revisado por más de 25 millones de personas. +# LOCALIZATION NOTE (pocket_feedback_body): This is shown below +# (pocket_feedback_header) to provide more information about Pocket. +pocket_feedback_body=Pocket, una parte de la familia de Mozilla, te ayudará a conectarte con contenido de alta calidad que de otra forma no hubieras encontrado. +pocket_send_feedback=Enviar comentario diff --git a/locales/es-ES/strings.properties b/locales/es-ES/strings.properties index 1ba76307cc..06a2613635 100644 --- a/locales/es-ES/strings.properties +++ b/locales/es-ES/strings.properties @@ -2,7 +2,19 @@ newtab_page_title=Nueva pestaña default_label_loading=Cargando… header_top_sites=Sitios favoritos -header_highlights=Destacados +header_stories=Historias populares +header_visit_again=Visitar de nuevo +header_bookmarks=Marcadores recientes +# LOCALIZATION NOTE(header_recommended_by): This is followed by the name +# of the corresponding content provider. +header_recommended_by=Recomendado por {provider} +# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is +# meant to inform that section contains no information because +# the user hasn't added any bookmarks. +header_bookmarks_placeholder=Todavía no tienes ningún marcador. +# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the +# corresponding content (stories) provider +header_stories_from=desde # LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give # context on how the element is related to the user, e.g. type indicates that @@ -10,9 +22,11 @@ header_highlights=Destacados type_label_visited=Visitados type_label_bookmarked=En marcadores type_label_synced=Sincronizado desde otro dispositivo +type_label_recommended=Tendencias # LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open" type_label_open=Abrir type_label_topic=Tema +type_label_now=Ahora # LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context # menu and are meant as a call to action for a given page. @@ -26,6 +40,14 @@ menu_action_open_new_window=Abrir en una nueva ventana menu_action_open_private_window=Abrir en una nueva ventana privada menu_action_dismiss=Ignorar menu_action_delete=Eliminar del historial +menu_action_pin=Fijar +menu_action_unpin=Soltar +confirm_history_delete_p1=¿Estás seguro de que quieres eliminar de tu historial todas las instancias de esta página? +# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in +# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a +# page from history. +confirm_history_delete_notice_p2=Esta acción no se puede deshacer. +menu_action_save_to_pocket=Guardar en Pocket # LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder # for what the user has typed in the search input field, e.g. 'Search for ' + @@ -47,6 +69,10 @@ search_header=Búsqueda de {search_engine_name} search_web_placeholder=Buscar en la Web search_settings=Cambiar ajustes de búsqueda +# LOCALIZATION NOTE (section_info_option): This is the screenreader text for the +# (?) icon that would show a section's description with optional feedback link. +section_info_option=Info + # LOCALIZATION NOTE (welcome_*): This is shown as a modal dialog, typically on a # first-run experience when there's no data to display yet welcome_title=Bienvenido a la nueva pestaña @@ -69,8 +95,12 @@ settings_pane_search_body=Busca en la Web desde tu nueva pestaña. settings_pane_topsites_header=Sitios populares settings_pane_topsites_body=Accede a las páginas que más visitas. settings_pane_topsites_options_showmore=Mostrar dos líneas -settings_pane_highlights_header=Resaltados -settings_pane_highlights_body=Échale un vistazo al historial de navegación y marcadores más recientes. +settings_pane_bookmarks_header=Marcadores recientes +settings_pane_bookmarks_body=Tus marcadores recién creados, fácilmente accesibles. +settings_pane_visit_again_header=Visitar de nuevo +settings_pane_visit_again_body=Firefox te mostrará partes de tu historial de navegación que te gustaría recordar o volver a visitar. +settings_pane_pocketstories_header=Historias populares +settings_pane_pocketstories_body=Pocket, que forma parte de la familia de Mozilla, te ayudará a encontrar contenido de alta calidad que puede que no encuentres de otra forma. settings_pane_done_button=Hecho # LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal @@ -81,5 +111,46 @@ edit_topsites_showmore_button=Mostrar más edit_topsites_showless_button=Mostrar menos edit_topsites_done_button=Hecho edit_topsites_pin_button=Fijar este sitio +edit_topsites_unpin_button=Eliminar este sitio fijo edit_topsites_edit_button=Editar este sitio edit_topsites_dismiss_button=Olvidar este sitio +edit_topsites_add_button=Agregar + +# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal. +topsites_form_add_header=Nuevo sitio popular +topsites_form_edit_header=Editar sitio popular +topsites_form_title_placeholder=Introducir título +topsites_form_url_placeholder=Escribir o pegar una URL +topsites_form_add_button=Agregar +topsites_form_save_button=Guardar +topsites_form_cancel_button=Cancelar +topsites_form_url_validation=Se requiere una URL válida + +# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the +# trending stories section and precedes a list of links to popular topics. +pocket_read_more=Temas populares: +# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the +# end of the list of popular topic links. +pocket_read_even_more=Ver más historias +# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction +# to Pocket as part of the feedback form. +pocket_feedback_header=Lo mejor de la web, confirmado por más de 25 millones de personas. +# LOCALIZATION NOTE (pocket_feedback_body): This is shown below +# (pocket_feedback_header) to provide more information about Pocket. +pocket_feedback_body=Pocket, que forma parte de la familia de Mozilla, te ayudará a encontrar contenido de alta calidad que puede que no encuentres de otra forma. +pocket_send_feedback=Enviar comentario + +# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations, +# in the space that would have shown a few stories, this is shown instead. +# {provider} is replaced by the name of the content provider for this section. +topstories_empty_state=Ya estás al día. Vuelve luego y busca más historias de {provider}. ¿No puedes esperar? Selecciona un tema popular y encontrás más historias alucinantes por toda la web. + +# LOCALIZATION NOTE (manual_migration_explanation): This message is shown to encourage users to +# import their browser profile from another browser they might be using. +manual_migration_explanation=Prueba Firefox con tusmarcadores y sitios favoritos importados desde otro navegador. +# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the +# process of importing another browser’s profile into Firefox. +manual_migration_cancel_button=No, gracias +# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process +# of importing another browser’s profile profile into Firefox. +manual_migration_import_button=Importar ahora diff --git a/locales/es-MX/strings.properties b/locales/es-MX/strings.properties index 2cdea700d1..72a162ca8c 100644 --- a/locales/es-MX/strings.properties +++ b/locales/es-MX/strings.properties @@ -2,7 +2,16 @@ newtab_page_title=Nueva pestaña default_label_loading=Cargando… header_top_sites=Sitios favoritos -header_highlights=Destacados +header_stories=Historias populares +header_visit_again=Visitar de nuevo +header_bookmarks=Marcadores recientes +# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is +# meant to inform that section contains no information because +# the user hasn't added any bookmarks. +header_bookmarks_placeholder=Aún no tienes ningún marcador. +# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the +# corresponding content (stories) provider +header_stories_from=de # LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give # context on how the element is related to the user, e.g. type indicates that @@ -10,6 +19,7 @@ header_highlights=Destacados type_label_visited=Visitados type_label_bookmarked=Marcados type_label_synced=Sincronizado desde otro dispositivo +type_label_recommended=Tendencias # LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open" type_label_open=Abrir type_label_topic=Tema @@ -26,6 +36,14 @@ menu_action_open_new_window=Abrir en una Nueva Ventana menu_action_open_private_window=Abrir en una Nueva Ventana Privada menu_action_dismiss=Descartar menu_action_delete=Eliminar del historial +menu_action_pin=Anclar +menu_action_unpin=Desanclar +confirm_history_delete_p1=¿Estás seguro de que quieres eliminar de tu historial todas las instancias de esta página? +# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in +# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a +# page from history. +confirm_history_delete_notice_p2=Esta acción no se puede deshacer. +menu_action_save_to_pocket=Guardar en Pocket # LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder # for what the user has typed in the search input field, e.g. 'Search for ' + @@ -69,8 +87,12 @@ settings_pane_search_body=Busca en la web de tu nueva pestaña. settings_pane_topsites_header=Sitios populares settings_pane_topsites_body=Accede a los sitios web que más visitas. settings_pane_topsites_options_showmore=Mostrar dos filas -settings_pane_highlights_header=Destacados -settings_pane_highlights_body=Ve tu historial de navegación reciente y tus marcadores recién creados. +settings_pane_bookmarks_header=Marcadores recientes +settings_pane_bookmarks_body=Tus marcadores recién creados en un solo lugar. +settings_pane_visit_again_header=Visitar de nuevo +settings_pane_visit_again_body=Firefox te mostrará partes de tu historial de navegación que a lo mejor te gustaría recordar o volver a visitar. +settings_pane_pocketstories_header=Historias populares +settings_pane_pocketstories_body=Pocket, miembro de la familia Mozilla, te ayuda a conectarte con contenido de alta calidad que tal vez no hubieras encontrado de otra forma. settings_pane_done_button=Listo # LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal @@ -81,5 +103,31 @@ edit_topsites_showmore_button=Mostrar más edit_topsites_showless_button=Mostrar menos edit_topsites_done_button=Listo edit_topsites_pin_button=Fijar este sitio +edit_topsites_unpin_button=Despegar este sitio edit_topsites_edit_button=Editar este sitio edit_topsites_dismiss_button=Descartar este sitio +edit_topsites_add_button=Agregar + +# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal. +topsites_form_add_header=Nuevo sitio popular +topsites_form_edit_header=Editar sitio popular +topsites_form_title_placeholder=Introducir un título +topsites_form_url_placeholder=Escribir o pegar una URL +topsites_form_add_button=Agregar +topsites_form_save_button=Guardar +topsites_form_cancel_button=Cancelar +topsites_form_url_validation=Se requiere una URL válida + +# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the +# trending stories section and precedes a list of links to popular topics. +pocket_read_more=Temas populares: +# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the +# end of the list of popular topic links. +pocket_read_even_more=Ver más historias +# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction +# to Pocket as part of the feedback form. +pocket_feedback_header=Lo mejor de la web, seleccionado por más 25 millones de personas. +# LOCALIZATION NOTE (pocket_feedback_body): This is shown below +# (pocket_feedback_header) to provide more information about Pocket. +pocket_feedback_body=Pocket, miembro de la familia Mozilla, te ayuda a conectarte con contenido de alta calidad que tal vez no hubieras encontrado de otra forma. +pocket_send_feedback=Enviar opinión diff --git a/locales/et/strings.properties b/locales/et/strings.properties index c5e89c6316..fe4c7240e1 100644 --- a/locales/et/strings.properties +++ b/locales/et/strings.properties @@ -3,6 +3,10 @@ default_label_loading=Laadimine… header_top_sites=Top saidid header_highlights=Esiletõstetud +header_stories=Top lood +# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the +# corresponding content (stories) provider +header_stories_from=allikast # LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give # context on how the element is related to the user, e.g. type indicates that @@ -10,6 +14,7 @@ header_highlights=Esiletõstetud type_label_visited=Külastatud type_label_bookmarked=Järjehoidjatest type_label_synced=Sünkroniseeritud teisest seadmest +type_label_recommended=Menukad # LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open" type_label_open=Avatud type_label_topic=Teema @@ -26,6 +31,7 @@ menu_action_open_new_window=Ava uues aknas menu_action_open_private_window=Ava uues privaatses aknas menu_action_dismiss=Peida menu_action_delete=Kustuta ajaloost +menu_action_save_to_pocket=Salvesta Pocketisse # LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder # for what the user has typed in the search input field, e.g. 'Search for ' + @@ -71,6 +77,8 @@ settings_pane_topsites_body=Ligipääs enim külastatud veebilehtedele. settings_pane_topsites_options_showmore=Kuvatakse kahel real settings_pane_highlights_header=Esiletõstetud settings_pane_highlights_body=Tagasivaade hiljutisele lehitsemisajaloole ning lisatud järjehoidjatele. +settings_pane_pocketstories_header=Top lood +settings_pane_pocketstories_body=Pocket, osana Mozilla perekonnast, aitab sul leida kvaliteetset sisu, mida sa muidu poleks ehk leidnud. settings_pane_done_button=Valmis # LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal @@ -81,5 +89,31 @@ edit_topsites_showmore_button=Kuva rohkem edit_topsites_showless_button=Näita vähem edit_topsites_done_button=Valmis edit_topsites_pin_button=Kinnita see sait +edit_topsites_unpin_button=Eemalda see sait edit_topsites_edit_button=Muuda seda saiti edit_topsites_dismiss_button=Peida see sait +edit_topsites_add_button=Lisa + +# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal. +topsites_form_add_header=Uue top saidi lisamine +topsites_form_edit_header=Top saidi muutmine +topsites_form_title_placeholder=Sisesta pealkiri +topsites_form_url_placeholder=Sisesta või aseta URL +topsites_form_add_button=Lisa +topsites_form_save_button=Salvesta +topsites_form_cancel_button=Tühista +topsites_form_url_validation=URL peab olema korrektne + +# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the +# trending stories section and precedes a list of links to popular topics. +pocket_read_more=Populaarsed teemad: +# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the +# end of the list of popular topic links. +pocket_read_even_more=Rohkem lugusid +# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction +# to Pocket as part of the feedback form. +pocket_feedback_header=Parim osa veebist, mille on kokku pannud rohkem kui 25 miljonit inimest. +# LOCALIZATION NOTE (pocket_feedback_body): This is shown below +# (pocket_feedback_header) to provide more information about Pocket. +pocket_feedback_body=Pocket, osana Mozilla perekonnast, aitab sul leida kvaliteetset sisu, mida sa muidu poleks ehk leidnud. +pocket_send_feedback=Saada tagasisidet diff --git a/locales/fa/strings.properties b/locales/fa/strings.properties index 9d39b3e435..15202895b2 100644 --- a/locales/fa/strings.properties +++ b/locales/fa/strings.properties @@ -2,7 +2,16 @@ newtab_page_title=زبانه جدید default_label_loading=در حال بارگیری… header_top_sites=سایت‌های برتر -header_highlights=برجسته‌ها +header_stories=برترین داستان‌ها +header_visit_again=مشاهده دوباره +header_bookmarks=نشانک‌های اخیر +# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is +# meant to inform that section contains no information because +# the user hasn't added any bookmarks. +header_bookmarks_placeholder=هنوز هیچ نشانکی ندارید. +# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the +# corresponding content (stories) provider +header_stories_from=از # LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give # context on how the element is related to the user, e.g. type indicates that @@ -10,6 +19,7 @@ header_highlights=برجسته‌ها type_label_visited=مشاهده شده type_label_bookmarked=نشانک شده type_label_synced=هم‌گام شده از دستگاهی دیگر +type_label_recommended=موضوعات داغ # LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open" type_label_open=باز کردن type_label_topic=موضوع @@ -26,6 +36,14 @@ menu_action_open_new_window=باز کردن در یک پنجره جدید menu_action_open_private_window=بار کردن در یک پنجره ناشناس جدید menu_action_dismiss=رد کردن menu_action_delete=حذف از تاریخچه +menu_action_pin=سنجاق کردن +menu_action_unpin=جدا کردن +confirm_history_delete_p1=آیا از پاک کردن همه نمونه‌های این صفحه از تاریخ‌چه خود اطمینان دارید؟ +# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in +# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a +# page from history. +confirm_history_delete_notice_p2=این عمل قابل برگشت نیست. +menu_action_save_to_pocket=ذخیره‌سازی در Pocket # LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder # for what the user has typed in the search input field, e.g. 'Search for ' + @@ -69,8 +87,12 @@ settings_pane_search_body=وب را از زبانه جدید خود جست‌و settings_pane_topsites_header=سایت‌های برتر settings_pane_topsites_body=به وب‌سایت‌هایی که بیشترین بازدید از آنها را داشتید دسترسی داشته باشید. settings_pane_topsites_options_showmore=نمایش دو ردیفی -settings_pane_highlights_header=برجسته‌ها -settings_pane_highlights_body=نگاهی دوباره به سابقه مرور اخیرتان و نشانک‌های تازه ایجاد شده. +settings_pane_bookmarks_header=نشانک‌های اخیر +settings_pane_bookmarks_body=به‌تازگی شما نشانک‌هایی را در یک محل مناسب ساخته‌اید. +settings_pane_visit_again_header=مشاهده دوباره +settings_pane_visit_again_body=فایرفاکس بخش‌هایی از تاریخ‌چه مرورتان را که ممکن است بخواهید به یاد داشته باشید یا به آن‌ها بازگردید به شما نشان خواهد داد. +settings_pane_pocketstories_header=برترین داستان‌ها +settings_pane_pocketstories_body=Pocket، بخشی از خانواده موزیلا، کمک خواهد کرد تا به محتوایی با کیفیت بالا مرتبط شوید که در غیر این صورت ممکن بود پیدا نکنید. settings_pane_done_button=انجام شد # LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal @@ -81,5 +103,31 @@ edit_topsites_showmore_button=نمایش بیشتر edit_topsites_showless_button=نمایش کمتر edit_topsites_done_button=انجام شد edit_topsites_pin_button=چسباندن این سایت +edit_topsites_unpin_button=لغو سنجاق کردن این پایگاه اینترنتی edit_topsites_edit_button=ویرایش این سایت edit_topsites_dismiss_button=نادیده گرفتن این سایت +edit_topsites_add_button=افزودن + +# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal. +topsites_form_add_header=سایت برتر جدید +topsites_form_edit_header=ویرایش سایت برتر +topsites_form_title_placeholder=عنوان را وارد کنید +topsites_form_url_placeholder=یک URL تایپ کنید یا بچسبانید +topsites_form_add_button=افزودن +topsites_form_save_button=ذخیره +topsites_form_cancel_button=انصراف +topsites_form_url_validation=URL معتبر الزامی است + +# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the +# trending stories section and precedes a list of links to popular topics. +pocket_read_more=موضوع‌های محبوب: +# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the +# end of the list of popular topic links. +pocket_read_even_more=مشاهده داستان‌های بیشتر +# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction +# to Pocket as part of the feedback form. +pocket_feedback_header=بهترین‌های وب، گزینش شده توسط بیش از ۲۵ میلیون نفر. +# LOCALIZATION NOTE (pocket_feedback_body): This is shown below +# (pocket_feedback_header) to provide more information about Pocket. +pocket_feedback_body=Pocket، بخشی از خانواده موزیلا، کمک خواهد کرد تا به محتوایی با کیفیت بالا مرتبط شوید که در غیر این صورت ممکن بود پیدا نکنید. +pocket_send_feedback=ارسال بازخورد diff --git a/locales/fi/strings.properties b/locales/fi/strings.properties index 92ce23769a..a8a21e4c18 100644 --- a/locales/fi/strings.properties +++ b/locales/fi/strings.properties @@ -2,7 +2,15 @@ newtab_page_title=Uusi välilehti default_label_loading=Ladataan… header_top_sites=Ykkössivustot -header_highlights=Nostot +header_stories=Ykkösjutut +header_visit_again=Käy toistekin +header_bookmarks=Uusimmat kirjanmerkit +# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is +# meant to inform that section contains no information because +# the user hasn't added any bookmarks. +header_bookmarks_placeholder=Sinulla ei ole vielä kirjanmerkkejä. +# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the +# corresponding content (stories) provider # LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give # context on how the element is related to the user, e.g. type indicates that @@ -10,6 +18,7 @@ header_highlights=Nostot type_label_visited=Vierailtu type_label_bookmarked=Kirjanmerkki type_label_synced=Synkronoitu toiselta laitteelta +type_label_recommended=Pinnalla # LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open" type_label_open=Avoin type_label_topic=Aihe @@ -26,6 +35,14 @@ menu_action_open_new_window=Avaa uuteen ikkunaan menu_action_open_private_window=Avaa uuteen yksityiseen ikkunaan menu_action_dismiss=Hylkää menu_action_delete=Poista historiasta +menu_action_pin=Kiinnitä +menu_action_unpin=Poista kiinnitys +confirm_history_delete_p1=Haluatko varmasti poistaa tämän sivun kaikkialta historiastasi? +# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in +# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a +# page from history. +confirm_history_delete_notice_p2=Tämä toiminto on peruuttamaton. +menu_action_save_to_pocket=Tallenna Pocket-palveluun # LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder # for what the user has typed in the search input field, e.g. 'Search for ' + @@ -35,6 +52,7 @@ search_for_something_with=Hae {search_term} palvelusta: # LOCALIZATION NOTE (search_button): This is screenreader only text for the # search button. +search_button=Haku # LOCALIZATION NOTE (search_header): Displayed at the top of the panel # showing search suggestions. {search_engine_name} is replaced with the name of @@ -60,17 +78,51 @@ time_label_hour={number} h time_label_day={number} pv # LOCALIZATION NOTE (settings_pane_*): This is shown in the Settings Pane sidebar. +settings_pane_button_label=Muokkaa Uusi välilehti -sivua settings_pane_header=Uuden välilehden asetukset +settings_pane_body=Valitse mitä näet, kun avaat uuden välilehden. +settings_pane_search_header=Haku +settings_pane_search_body=Tee verkkohakuja uudesta välilehdestä. settings_pane_topsites_header=Ykkössivustot -settings_pane_highlights_header=Nostot +settings_pane_topsites_options_showmore=Näytä kaksi riviä +settings_pane_bookmarks_header=Uusimmat kirjanmerkit +settings_pane_bookmarks_body=Uusimmat kirjanmerkkisi, yhdessä kätevässä paikassa. +settings_pane_visit_again_header=Käy toistekin +settings_pane_pocketstories_header=Ykkösjutut settings_pane_done_button=Valmis # LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal # dialog. edit_topsites_button_text=Muokkaa +edit_topsites_button_label=Muokkaa Ykkössivustot-osiota edit_topsites_showmore_button=Näytä enemmän edit_topsites_showless_button=Näytä vähemmän edit_topsites_done_button=Valmis edit_topsites_pin_button=Kiinnitä tämä sivusto +edit_topsites_unpin_button=Poista tämän sivuston kiinnitys edit_topsites_edit_button=Muokkaa tätä sivustoa edit_topsites_dismiss_button=Hylkää tämä sivusto +edit_topsites_add_button=Lisää + +# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal. +topsites_form_add_header=Uusi ykkössivusto +topsites_form_edit_header=Muokkaa ykkössivustoa +topsites_form_title_placeholder=Kirjoita otsikko +topsites_form_url_placeholder=Kirjoita tai liitä osoite +topsites_form_add_button=Lisää +topsites_form_save_button=Tallenna +topsites_form_cancel_button=Peruuta +topsites_form_url_validation=Kelvollinen osoite vaaditaan + +# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the +# trending stories section and precedes a list of links to popular topics. +pocket_read_more=Suositut aiheet: +# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the +# end of the list of popular topic links. +pocket_read_even_more=Katso lisää juttuja +# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction +# to Pocket as part of the feedback form. +pocket_feedback_header=Netin parhaat palat, valikoitu yli 25 miljoonan ihmisen voimin. +# LOCALIZATION NOTE (pocket_feedback_body): This is shown below +# (pocket_feedback_header) to provide more information about Pocket. +pocket_send_feedback=Lähetä palautetta diff --git a/locales/fr/strings.properties b/locales/fr/strings.properties index ae033239d0..13fd8d1279 100644 --- a/locales/fr/strings.properties +++ b/locales/fr/strings.properties @@ -2,7 +2,19 @@ newtab_page_title=Nouvel onglet default_label_loading=Chargement… header_top_sites=Sites les plus visités -header_highlights=Éléments-clés +header_stories=Articles populaires +header_visit_again=Visiter à nouveau +header_bookmarks=Marque-pages récents +# LOCALIZATION NOTE(header_recommended_by): This is followed by the name +# of the corresponding content provider. +header_recommended_by=Recommandé par {provider} +# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is +# meant to inform that section contains no information because +# the user hasn't added any bookmarks. +header_bookmarks_placeholder=Vous ne possédez aucun marque-page pour l’instant. +# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the +# corresponding content (stories) provider +header_stories_from=par # LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give # context on how the element is related to the user, e.g. type indicates that @@ -10,9 +22,11 @@ header_highlights=Éléments-clés type_label_visited=Visité type_label_bookmarked=Ajouté aux marque-pages type_label_synced=Synchronisé depuis un autre appareil +type_label_recommended=Tendance # LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open" type_label_open=Ouvert type_label_topic=Thème +type_label_now=Maintenant # LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context # menu and are meant as a call to action for a given page. @@ -26,6 +40,14 @@ menu_action_open_new_window=Ouvrir dans une nouvelle fenêtre menu_action_open_private_window=Ouvrir dans une nouvelle fenêtre privée menu_action_dismiss=Retirer menu_action_delete=Supprimer de l’historique +menu_action_pin=Épingler +menu_action_unpin=Détacher +confirm_history_delete_p1=Voulez-vous vraiment supprimer de l’historique toutes les occurrences de cette page ? +# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in +# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a +# page from history. +confirm_history_delete_notice_p2=Cette action est irréversible. +menu_action_save_to_pocket=Enregistrer dans Pocket # LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder # for what the user has typed in the search input field, e.g. 'Search for ' + @@ -47,6 +69,10 @@ search_header=Recherche {search_engine_name} search_web_placeholder=Rechercher sur le Web search_settings=Paramètres de recherche +# LOCALIZATION NOTE (section_info_option): This is the screenreader text for the +# (?) icon that would show a section's description with optional feedback link. +section_info_option=Informations + # LOCALIZATION NOTE (welcome_*): This is shown as a modal dialog, typically on a # first-run experience when there's no data to display yet welcome_title=Bienvenue sur la page Nouvel onglet @@ -65,12 +91,16 @@ settings_pane_button_label=Personnaliser la page Nouvel onglet settings_pane_header=Préférences Nouvel onglet settings_pane_body=Choisissez ce qui s’affiche à l’ouverture d’un nouvel onglet. settings_pane_search_header=Recherche -settings_pane_search_body=Effectuez une recherche sur le Web à partir du nouvel onglet. +settings_pane_search_body=Effectuez une recherche sur le Web depuis le nouvel onglet. settings_pane_topsites_header=Sites les plus visités settings_pane_topsites_body=Accédez aux sites que vous consultez le plus. settings_pane_topsites_options_showmore=Afficher deux lignes -settings_pane_highlights_header=Éléments-clés -settings_pane_highlights_body=Revenir sur votre historique de navigation récent et sur vos marque-pages nouvellement créés. +settings_pane_bookmarks_header=Marque-pages récents +settings_pane_bookmarks_body=Vos nouveaux marque-pages, facilement accessibles. +settings_pane_visit_again_header=Visiter à nouveau +settings_pane_visit_again_body=Firefox affichera des extraits de votre historique de navigation dont vous pourriez vouloir vous souvenir ou que vous pourriez vouloir revisiter. +settings_pane_pocketstories_header=Articles populaires +settings_pane_pocketstories_body=Pocket, un membre de la famille Mozilla, vous aide à découvrir du contenu de grande qualité que vous auriez pu manquer dans le cas contraire. settings_pane_done_button=Terminé # LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal @@ -81,5 +111,46 @@ edit_topsites_showmore_button=Afficher plus edit_topsites_showless_button=Afficher moins edit_topsites_done_button=Terminé edit_topsites_pin_button=Épingler ce site +edit_topsites_unpin_button=Relâcher ce site edit_topsites_edit_button=Modifier ce site edit_topsites_dismiss_button=Retirer ce site +edit_topsites_add_button=Ajouter + +# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal. +topsites_form_add_header=Nouveau site populaire +topsites_form_edit_header=Modifier le site populaire +topsites_form_title_placeholder=Saisir un titre +topsites_form_url_placeholder=Saisir ou coller une adresse web +topsites_form_add_button=Ajouter +topsites_form_save_button=Enregistrer +topsites_form_cancel_button=Annuler +topsites_form_url_validation=Adresse web valide requise + +# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the +# trending stories section and precedes a list of links to popular topics. +pocket_read_more=Sujets populaires : +# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the +# end of the list of popular topic links. +pocket_read_even_more=Afficher plus d’articles +# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction +# to Pocket as part of the feedback form. +pocket_feedback_header=Le meilleur du Web, sélectionné par plus de 25 millions de personnes. +# LOCALIZATION NOTE (pocket_feedback_body): This is shown below +# (pocket_feedback_header) to provide more information about Pocket. +pocket_feedback_body=Pocket, un membre de la famille Mozilla, vous aide à découvrir du contenu de grande qualité que vous auriez pu manquer dans le cas contraire. +pocket_send_feedback=Donner mon avis + +# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations, +# in the space that would have shown a few stories, this is shown instead. +# {provider} is replaced by the name of the content provider for this section. +topstories_empty_state=Il n’y en a pas d’autres. Revenez plus tard pour plus d’articles de {provider}. Vous ne voulez pas attendre ? Choisissez un sujet parmi les plus populaires pour découvrir d’autres articles intéressants sur le Web. + +# LOCALIZATION NOTE (manual_migration_explanation): This message is shown to encourage users to +# import their browser profile from another browser they might be using. +manual_migration_explanation=Essayez Firefox avec vos sites et marque-pages préférés, importés depuis un autre navigateur. +# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the +# process of importing another browser’s profile into Firefox. +manual_migration_cancel_button=Non merci +# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process +# of importing another browser’s profile profile into Firefox. +manual_migration_import_button=Importer maintenant diff --git a/locales/fy-NL/strings.properties b/locales/fy-NL/strings.properties index 34f0c7a849..004f6b8e15 100644 --- a/locales/fy-NL/strings.properties +++ b/locales/fy-NL/strings.properties @@ -2,7 +2,19 @@ newtab_page_title=Nij ljepblêd default_label_loading=Lade… header_top_sites=Topwebsites -header_highlights=Hichtepunten +header_stories=Topferhalen +header_visit_again=Nochris besykje +header_bookmarks=Resinte blêdwizers +# LOCALIZATION NOTE(header_recommended_by): This is followed by the name +# of the corresponding content provider. +header_recommended_by=Oanrekommandearre troch {provider} +# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is +# meant to inform that section contains no information because +# the user hasn't added any bookmarks. +header_bookmarks_placeholder=Jo hawwe noch gjin inkelde blêdwizer. +# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the +# corresponding content (stories) provider +header_stories_from=fan # LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give # context on how the element is related to the user, e.g. type indicates that @@ -10,9 +22,11 @@ header_highlights=Hichtepunten type_label_visited=Besocht type_label_bookmarked=Blêdwizer makke type_label_synced=Syngronisearre fan oar apparaat ôf +type_label_recommended=Trending # LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open" type_label_open=Iepene type_label_topic=Underwerp +type_label_now=No # LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context # menu and are meant as a call to action for a given page. @@ -26,6 +40,14 @@ menu_action_open_new_window=Iepenje yn in nij finster menu_action_open_private_window=Iepenje yn in nij priveefinster menu_action_dismiss=Fuortsmite menu_action_delete=Fuortsmite út skiednis +menu_action_pin=Fêstsette +menu_action_unpin=Losmeitsje +confirm_history_delete_p1=Binne jo wis dat jo elke ferwizing fan dizze side út jo skiednis fuortsmite wolle? +# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in +# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a +# page from history. +confirm_history_delete_notice_p2=Dizze aksje kin net ûngedien makke wurde. +menu_action_save_to_pocket=Bewarje nei Pocket # LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder # for what the user has typed in the search input field, e.g. 'Search for ' + @@ -47,6 +69,10 @@ search_header={search_engine_name} trochsykje search_web_placeholder=Sykje op it web search_settings=Sykynstellingen wizigje +# LOCALIZATION NOTE (section_info_option): This is the screenreader text for the +# (?) icon that would show a section's description with optional feedback link. +section_info_option=Ynfo + # LOCALIZATION NOTE (welcome_*): This is shown as a modal dialog, typically on a # first-run experience when there's no data to display yet welcome_title=Wolkom by it nije ljepblêd @@ -69,8 +95,12 @@ settings_pane_search_body=Sykje op it web fan jo nije ljepblêd út. settings_pane_topsites_header=Topwebsites settings_pane_topsites_body=Benaderje de websites dy't jo it meast besykje. settings_pane_topsites_options_showmore=Twa rigen toane -settings_pane_highlights_header=Hichtepunten -settings_pane_highlights_body=Sjoch werom nei jo resinte sneupskiednis en nij makke blêdwizers. +settings_pane_bookmarks_header=Resinte blêdwizers +settings_pane_bookmarks_body=Jo koartlyn oanmakke blêdwizers op ien handich plak. +settings_pane_visit_again_header=Nochris besykje +settings_pane_visit_again_body=Firefox sil jo ûnderdielen fan jo sneupskiednis toane dy't jo miskien ûnthâlde of nei werom gean wolle. +settings_pane_pocketstories_header=Topferhalen +settings_pane_pocketstories_body=Pocket, part fan de Mozilla-famylje, sil jo helpe te ferbinen mei hege kwaliteit ynhâld dy't jo oars miskien net fûn hienen. settings_pane_done_button=Dien # LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal @@ -81,5 +111,46 @@ edit_topsites_showmore_button=Mear toane edit_topsites_showless_button=Minder toane edit_topsites_done_button=Dien edit_topsites_pin_button=Dizze side fêstsette +edit_topsites_unpin_button=Dizze webstee loskeppelje edit_topsites_edit_button=Dizze side bewurkje edit_topsites_dismiss_button=Dizze side fuortsmite +edit_topsites_add_button=Tafoegje + +# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal. +topsites_form_add_header=Nije topwebsite +topsites_form_edit_header=Topwebsite tafoegje +topsites_form_title_placeholder=Titel ynfiere +topsites_form_url_placeholder=Typ of plak in URL +topsites_form_add_button=Tafoegje +topsites_form_save_button=Bewarje +topsites_form_cancel_button=Annulearje +topsites_form_url_validation=Jildige URL fereaske + +# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the +# trending stories section and precedes a list of links to popular topics. +pocket_read_more=Populêre ûnderwerpen: +# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the +# end of the list of popular topic links. +pocket_read_even_more=Mear ferhalen besjen +# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction +# to Pocket as part of the feedback form. +pocket_feedback_header=It bêste fan it web, sammele troch mear as 25 miljoen minsken. +# LOCALIZATION NOTE (pocket_feedback_body): This is shown below +# (pocket_feedback_header) to provide more information about Pocket. +pocket_feedback_body=Pocket, part fan de Mozilla-famylje, sil jo helpe te ferbinen mei hege kwaliteit ynhâld dy't jo oars miskien net fûn hienen. +pocket_send_feedback=Kommentaar ferstjoere + +# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations, +# in the space that would have shown a few stories, this is shown instead. +# {provider} is replaced by the name of the content provider for this section. +topstories_empty_state=Jo binne by. Kom letter werom foar mear ferhalen fan {provider}. Kin jo net wachtsje? Selektearje in populêr ûnderwerp om mear ferhalen fan it ynternet te finen. + +# LOCALIZATION NOTE (manual_migration_explanation): This message is shown to encourage users to +# import their browser profile from another browser they might be using. +manual_migration_explanation=Probearje Firefox mei jo favorite websites en blêdwizers fan in oare browser. +# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the +# process of importing another browser’s profile into Firefox. +manual_migration_cancel_button=Nee tankewol +# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process +# of importing another browser’s profile profile into Firefox. +manual_migration_import_button=No ymportearje diff --git a/locales/ga-IE/strings.properties b/locales/ga-IE/strings.properties index 7c2fa111a6..7437c6c368 100644 --- a/locales/ga-IE/strings.properties +++ b/locales/ga-IE/strings.properties @@ -1,8 +1,17 @@ newtab_page_title=Cluaisín Nua -default_label_loading=Á Luchtú… +default_label_loading=Á Lódáil… header_top_sites=Barrshuímh -header_highlights=Buaicphointí +header_stories=Barrscéalta +header_visit_again=Cuairt Arís +header_bookmarks=Leabharmharcanna Le Déanaí +# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is +# meant to inform that section contains no information because +# the user hasn't added any bookmarks. +header_bookmarks_placeholder=Níl aon leabharmharcanna agat. +# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the +# corresponding content (stories) provider +header_stories_from=ó # LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give # context on how the element is related to the user, e.g. type indicates that @@ -10,6 +19,7 @@ header_highlights=Buaicphointí type_label_visited=Feicthe type_label_bookmarked=Leabharmharcáilte type_label_synced=Sioncronaithe ó ghléas eile +type_label_recommended=Treochtáil # LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open" type_label_open=Oscailte type_label_topic=Ábhar @@ -19,13 +29,21 @@ type_label_topic=Ábhar # LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to # bookmarks" menu_action_bookmark=Cruthaigh leabharmharc -menu_action_remove_bookmark=Scrios Leabharmharc +menu_action_remove_bookmark=Scrios an Leabharmharc menu_action_copy_address=Cóipeáil an Seoladh menu_action_email_link=Seol an Nasc trí Ríomhphost… menu_action_open_new_window=Oscail i bhFuinneog Nua menu_action_open_private_window=Oscail i bhFuinneog Nua Phríobháideach menu_action_dismiss=Ruaig menu_action_delete=Scrios ón Stair +menu_action_pin=Pionnáil +menu_action_unpin=Díphionnáil +confirm_history_delete_p1=An bhfuil tú cinnte gur mhaith leat an leathanach seo a scriosadh go hiomlán ó do stair? +# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in +# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a +# page from history. +confirm_history_delete_notice_p2=Ní féidir an gníomh seo a chur ar ceal. +menu_action_save_to_pocket=Sábháil in Pocket # LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder # for what the user has typed in the search input field, e.g. 'Search for ' + @@ -35,6 +53,7 @@ search_for_something_with=Déan cuardach ar {search_term} le: # LOCALIZATION NOTE (search_button): This is screenreader only text for the # search button. +search_button=Cuardach # LOCALIZATION NOTE (search_header): Displayed at the top of the panel # showing search suggestions. {search_engine_name} is replaced with the name of @@ -60,6 +79,55 @@ time_label_hour={number}u time_label_day={number}l # LOCALIZATION NOTE (settings_pane_*): This is shown in the Settings Pane sidebar. +settings_pane_button_label=Saincheap an Leathanach do Chluaisín Nua +settings_pane_header=Sainroghanna do Chluaisín Nua +settings_pane_body=Roghnaigh na rudaí a fheicfidh tú nuair a osclóidh tú cluaisín nua. +settings_pane_search_header=Cuardach +settings_pane_search_body=Cuardaigh an Gréasán go díreach ón gcluaisín nua. +settings_pane_topsites_header=Barrshuímh +settings_pane_topsites_body=Na suímh Ghréasáin a dtugann tú cuairt orthu is minice. +settings_pane_topsites_options_showmore=Taispeáin dhá shraith +settings_pane_bookmarks_header=Leabharmharcanna Le Déanaí +settings_pane_bookmarks_body=Do chuid leabharmharcanna nua in áit amháin. +settings_pane_visit_again_header=Cuairt Arís +settings_pane_visit_again_body=Taispeánann Firefox nascanna ó do stair bhrabhsála a mbeadh suim agat filleadh orthu amach anseo. +settings_pane_pocketstories_header=Barrscéalta +settings_pane_pocketstories_body=Le Pocket, ball de theaghlach Mozilla, beidh tú ábalta teacht ar ábhar den chéad scoth go héasca. +settings_pane_done_button=Déanta # LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal # dialog. +edit_topsites_button_text=Eagar +edit_topsites_button_label=Saincheap na Barrshuímh +edit_topsites_showmore_button=Taispeáin níos mó +edit_topsites_showless_button=Taispeáin níos lú +edit_topsites_done_button=Déanta +edit_topsites_pin_button=Greamaigh an suíomh seo +edit_topsites_unpin_button=Díghreamaigh an suíomh seo +edit_topsites_edit_button=Cuir an suíomh seo in eagar +edit_topsites_dismiss_button=Ruaig an suíomh seo +edit_topsites_add_button=Cuir leis + +# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal. +topsites_form_add_header=Barrshuíomh Nua +topsites_form_edit_header=Cuir an Barrshuíomh in Eagar +topsites_form_title_placeholder=Cuir teideal isteach +topsites_form_url_placeholder=Clóscríobh nó greamaigh URL +topsites_form_add_button=Cuir leis +topsites_form_save_button=Sábháil +topsites_form_cancel_button=Cealaigh +topsites_form_url_validation=URL neamhbhailí + +# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the +# trending stories section and precedes a list of links to popular topics. +pocket_read_more=Topaicí i mbéal an phobail: +# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the +# end of the list of popular topic links. +pocket_read_even_more=Tuilleadh Scéalta +# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction +# to Pocket as part of the feedback form. +pocket_feedback_header=Ábhar den chéad scoth ón Ghréasán, le níos mó ná 25 milliún duine i mbun coimeádaíochta. +# LOCALIZATION NOTE (pocket_feedback_body): This is shown below +# (pocket_feedback_header) to provide more information about Pocket. +pocket_feedback_body=Le Pocket, ball de theaghlach Mozilla, beidh tú ábalta teacht ar ábhar den chéad scoth go héasca. +pocket_send_feedback=Tabhair Aiseolas Dúinn diff --git a/locales/gd/strings.properties b/locales/gd/strings.properties index d4feb94c2d..0463ad167f 100644 --- a/locales/gd/strings.properties +++ b/locales/gd/strings.properties @@ -2,7 +2,16 @@ newtab_page_title=Taba ùr default_label_loading=’Ga luchdadh… header_top_sites=Brod nan làrach -header_highlights=Highlights +header_stories=Brod nan sgeul +header_visit_again=Tadhail a-rithist +header_bookmarks=Comharran-lìn o chionn goirid +# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is +# meant to inform that section contains no information because +# the user hasn't added any bookmarks. +header_bookmarks_placeholder=Chan eil comharra-lìn sam bith agad fhathast. +# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the +# corresponding content (stories) provider +header_stories_from=o # LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give # context on how the element is related to the user, e.g. type indicates that @@ -10,6 +19,7 @@ header_highlights=Highlights type_label_visited=Na thadhail thu air type_label_bookmarked=’Nan comharran-lìn type_label_synced=Sioncronaichte o uidheam eile +type_label_recommended=A’ treandadh # LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open" type_label_open=Fosgailte type_label_topic=Cuspair @@ -26,6 +36,14 @@ menu_action_open_new_window=Fosgail ann an uinneag ùr menu_action_open_private_window=Fosgail ann an uinneag phrìobhaideach ùr menu_action_dismiss=Leig seachad menu_action_delete=Sguab às an eachdraidh +menu_action_pin=Prìnich +menu_action_unpin=Dì-phrìnich +confirm_history_delete_p1=A bheil thu cinnteach gu bheil thu airson gach ionstans na duilleige seo a sguabadh às an eachdraidh agad? +# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in +# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a +# page from history. +confirm_history_delete_notice_p2=Cha ghabh seo a neo-dhèanamh. +menu_action_save_to_pocket=Sàbhail sa phòcaid # LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder # for what the user has typed in the search input field, e.g. 'Search for ' + @@ -35,6 +53,7 @@ search_for_something_with=Lorg {search_term} le: # LOCALIZATION NOTE (search_button): This is screenreader only text for the # search button. +search_button=Lorg # LOCALIZATION NOTE (search_header): Displayed at the top of the panel # showing search suggestions. {search_engine_name} is replaced with the name of @@ -60,6 +79,55 @@ time_label_hour={number}u time_label_day={number}l # LOCALIZATION NOTE (settings_pane_*): This is shown in the Settings Pane sidebar. +settings_pane_button_label=Gnàthaich duilleag nan tabaichean ùra agad +settings_pane_header=Roghainnean nan tabaichean ùra +settings_pane_body=Tagh na chì thu nuair a dh’fhosglas tu taba ùr. +settings_pane_search_header=Lorg +settings_pane_search_body=Lorg air an lìon on taba ùr agad. +settings_pane_topsites_header=Brod nan làrach +settings_pane_topsites_body=Faigh cothrom air na làraichean air an tadhail thu gu tric. +settings_pane_topsites_options_showmore=Seall dà ràgh +settings_pane_bookmarks_header=Comharran-lìn o chionn goirid +settings_pane_bookmarks_body=Na comharran-lìn ùra agad san aon àite ghoireasach. +settings_pane_visit_again_header=Tadhail a-rithist +settings_pane_visit_again_body=Seallaidh Firefox cuid dhen eachdraidh bhrabhsaidh agad dhut a bu toil leat cuimhneachadh no tadhal air a-rithist ma dh’fhaoidte. +settings_pane_pocketstories_header=Brod nan sgeul +settings_pane_pocketstories_body=Pocket, ball de theaghlach Mozilla, a cheanglas tu ri susbaint fhìor-mhath nach biodh tu air fhaicinn air dòigh eile. +settings_pane_done_button=Deiseil # LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal # dialog. +edit_topsites_button_text=Deasaich +edit_topsites_button_label=Gnàthaich earrann brod nan làrach agad +edit_topsites_showmore_button=Seall barrachd +edit_topsites_showless_button=Seall nas lugha +edit_topsites_done_button=Deiseil +edit_topsites_pin_button=Prìnich an làrach seo +edit_topsites_unpin_button=Dì-phrìnich an làrach seo +edit_topsites_edit_button=Deasaich an làrach seo +edit_topsites_dismiss_button=Leig seachad an làrach seo +edit_topsites_add_button=Cuir ris + +# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal. +topsites_form_add_header=Brod làraich ùr +topsites_form_edit_header=Deasaich am brod làraich +topsites_form_title_placeholder=Cuir ainm a-steach +topsites_form_url_placeholder=Sgrìobh URL no cuir fear ann +topsites_form_add_button=Cuir ris +topsites_form_save_button=Sàbhail +topsites_form_cancel_button=Sguir dheth +topsites_form_url_validation=Tha feum air URL dligheach + +# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the +# trending stories section and precedes a list of links to popular topics. +pocket_read_more=Cuspairean fèillmhor: +# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the +# end of the list of popular topic links. +pocket_read_even_more=Seall barrachd sgeul +# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction +# to Pocket as part of the feedback form. +pocket_feedback_header=Brod an eadar-lìn, air a dheasachadh le barrachd air 25 millean duine. +# LOCALIZATION NOTE (pocket_feedback_body): This is shown below +# (pocket_feedback_header) to provide more information about Pocket. +pocket_feedback_body=Pocket, ball de theaghlach Mozilla, a cheanglas tu ri susbaint fhìor-mhath nach biodh tu air fhaicinn air dòigh eile. +pocket_send_feedback=Dè do bheachd air? diff --git a/locales/he/strings.properties b/locales/he/strings.properties index a059e6148d..8b0620bd25 100644 --- a/locales/he/strings.properties +++ b/locales/he/strings.properties @@ -2,7 +2,16 @@ newtab_page_title=לשונית חדשה default_label_loading=בטעינה… header_top_sites=אתרים מובילים -header_highlights=המלצות +header_stories=סיפורים מובילים +header_visit_again=ביקור חוזר +header_bookmarks=סימניות אחרונות +# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is +# meant to inform that section contains no information because +# the user hasn't added any bookmarks. +header_bookmarks_placeholder=אין לך סימניות עדיין. +# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the +# corresponding content (stories) provider +header_stories_from=מאת # LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give # context on how the element is related to the user, e.g. type indicates that @@ -10,6 +19,7 @@ header_highlights=המלצות type_label_visited=ביקורים קודמים type_label_bookmarked=נוצרה סימניה type_label_synced=סונכרן מהתקן אחר +type_label_recommended=פופולרי # LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open" type_label_open=פתיחה type_label_topic=נושא @@ -24,8 +34,16 @@ menu_action_copy_address=העתקת כתובת menu_action_email_link=שליחת קישור בדוא״ל… menu_action_open_new_window=פתיחה בחלון חדש menu_action_open_private_window=פתיחה בלשונית פרטית חדשה -menu_action_dismiss=ביטול +menu_action_dismiss=הסרה menu_action_delete=מחיקה מההיסטוריה +menu_action_pin=הצמדה +menu_action_unpin=ביטול הצמדה +confirm_history_delete_p1=למחוק כל עותק של העמוד הזה מההיסטוריה שלך? +# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in +# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a +# page from history. +confirm_history_delete_notice_p2=לא ניתן לבטל פעולה זו. +menu_action_save_to_pocket=שמירה ל־Pocket # LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder # for what the user has typed in the search input field, e.g. 'Search for ' + @@ -69,8 +87,12 @@ settings_pane_search_body=חיפוש באינטרנט ישירות מהלשונ settings_pane_topsites_header=אתרים מובילים settings_pane_topsites_body=גישה לאתרים בהם ביקרת הכי הרבה. settings_pane_topsites_options_showmore=הצגת שתי שורות -settings_pane_highlights_header=המלצות -settings_pane_highlights_body=ניתן להסתכל על היסטוריית הגלישה העדכנית שלך ועל הסימניות האחרונות שנוצרו. +settings_pane_bookmarks_header=סימניות אחרונות +settings_pane_bookmarks_body=הסימניות החדשות שיצרת במיקום נוח ואחיד. +settings_pane_visit_again_header=ביקור חוזר +settings_pane_visit_again_body=Firefox תציג לך חלקים מהיסטוריית הגלישה שלך שאולי יעניין אותך להיזכר בהם או לחזור אליהם. +settings_pane_pocketstories_header=סיפורים מובילים +settings_pane_pocketstories_body=Pocket, חלק ממשפחת Mozilla, יסייע לך להתחבר לתוכן באיכות גבוהה שיתכן שלא היה מגיע אליך בדרך אחרת. settings_pane_done_button=סיום # LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal @@ -81,5 +103,31 @@ edit_topsites_showmore_button=להציג יותר edit_topsites_showless_button=להציג פחות edit_topsites_done_button=בוצע edit_topsites_pin_button=נעיצת אתר זה +edit_topsites_unpin_button=ביטול הצמדת אתר זה edit_topsites_edit_button=עריכת אתר זה edit_topsites_dismiss_button=התעלמות מאתר זה +edit_topsites_add_button=הוספה + +# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal. +topsites_form_add_header=אתר מוביל חדש +topsites_form_edit_header=עריכת אתר מוביל +topsites_form_title_placeholder=נא להזין כותרת +topsites_form_url_placeholder=נא להקליד או להזין כתובת +topsites_form_add_button=הוספה +topsites_form_save_button=שמירה +topsites_form_cancel_button=ביטול +topsites_form_url_validation=נדרשת כתובת תקינה + +# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the +# trending stories section and precedes a list of links to popular topics. +pocket_read_more=נושאים פופולריים: +# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the +# end of the list of popular topic links. +pocket_read_even_more=צפייה בחדשות נוספות +# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction +# to Pocket as part of the feedback form. +pocket_feedback_header=המיטב מרחבי האינטרנט, נאסף על ידי 25 מיליון אנשים. +# LOCALIZATION NOTE (pocket_feedback_body): This is shown below +# (pocket_feedback_header) to provide more information about Pocket. +pocket_feedback_body=Pocket, חלק ממשפחת Mozilla, יסייע לך להתחבר לתוכן באיכות גבוהה שיתכן שלא היה מגיע אליך בדרך אחרת. +pocket_send_feedback=שליחת משוב diff --git a/locales/hi-IN/strings.properties b/locales/hi-IN/strings.properties index 531e6df638..2f2c700793 100644 --- a/locales/hi-IN/strings.properties +++ b/locales/hi-IN/strings.properties @@ -2,7 +2,14 @@ newtab_page_title=नया टैब default_label_loading=लोड हो रहा है… header_top_sites=सर्वोच्च साइटें -header_highlights=प्रमुखताएँ +header_visit_again=पुनः पधारें +header_bookmarks=हाल के पुस्तचिह्न +# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is +# meant to inform that section contains no information because +# the user hasn't added any bookmarks. +# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the +# corresponding content (stories) provider +header_stories_from=के द्वारा # LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give # context on how the element is related to the user, e.g. type indicates that @@ -10,6 +17,7 @@ header_highlights=प्रमुखताएँ type_label_visited=देखी गई type_label_bookmarked=पुस्तचिह्न लगाया हुआ type_label_synced=किसी अन्य उपकरण से समकालीन किया गया +type_label_recommended=लोकप्रिय # LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open" type_label_open=खोलें type_label_topic=विषय @@ -26,6 +34,9 @@ menu_action_open_new_window=एक नई विंडो में खोले menu_action_open_private_window=एक नई निजी विंडो में खोलें menu_action_dismiss=निरस्त करें menu_action_delete=इतिहास से मिटाएँ +# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in +# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a +# page from history. # LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder # for what the user has typed in the search input field, e.g. 'Search for ' + @@ -69,8 +80,6 @@ settings_pane_search_body=अपने नए टैब से वेब पर settings_pane_topsites_header=सर्वोच्च साइटें settings_pane_topsites_body=आपके द्वारा सबसे ज्यादा खोजी जाने वाली वेबसाइट्स देखें. settings_pane_topsites_options_showmore=दो पंक्तियाँ दिखाएँ -settings_pane_highlights_header=प्रमुखताएँ -settings_pane_highlights_body=अपने हाल के ब्राउज़िंग इतिहास और नए बनाए गए पुस्तचिन्हों को वापस देखें. settings_pane_done_button=संपन्न # LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal @@ -83,3 +92,16 @@ edit_topsites_done_button=पूर्ण edit_topsites_pin_button=इस साइट को पिन करें edit_topsites_edit_button=इस साइट को संपादित करें edit_topsites_dismiss_button=इस साइट को ख़ारिज करें + +# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal. + +# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the +# trending stories section and precedes a list of links to popular topics. +# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the +# end of the list of popular topic links. +pocket_read_even_more=और कहानियाँ देखें +# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction +# to Pocket as part of the feedback form. +# LOCALIZATION NOTE (pocket_feedback_body): This is shown below +# (pocket_feedback_header) to provide more information about Pocket. +pocket_send_feedback=प्रतिक्रिया भेजें diff --git a/locales/hsb/strings.properties b/locales/hsb/strings.properties index aa0ce3f0d2..23498775d7 100644 --- a/locales/hsb/strings.properties +++ b/locales/hsb/strings.properties @@ -2,7 +2,19 @@ newtab_page_title=Nowy rajtark default_label_loading=Začituje so… header_top_sites=Najhusćišo wopytane sydła -header_highlights=Wjerški +header_stories=Najhusćišo přečitane zdźělenki +header_visit_again=Hišće raz wopytać +header_bookmarks=Najnowše zapołožki +# LOCALIZATION NOTE(header_recommended_by): This is followed by the name +# of the corresponding content provider. +header_recommended_by=Wot {provider} doporučeny +# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is +# meant to inform that section contains no information because +# the user hasn't added any bookmarks. +header_bookmarks_placeholder=Hišće zapołožki nimaće. +# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the +# corresponding content (stories) provider +header_stories_from=wot # LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give # context on how the element is related to the user, e.g. type indicates that @@ -10,9 +22,11 @@ header_highlights=Wjerški type_label_visited=Wopytany type_label_bookmarked=Jako zapołožka składowany type_label_synced=Z druheho grata synchronizowany +type_label_recommended=Popularny # LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open" type_label_open=Wočinjeny type_label_topic=Tema +type_label_now=Nětko # LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context # menu and are meant as a call to action for a given page. @@ -26,6 +40,14 @@ menu_action_open_new_window=W nowym woknje wočinić menu_action_open_private_window=W nowym priwatnym woknje wočinić menu_action_dismiss=Zaćisnyć menu_action_delete=Z historije zhašeć +menu_action_pin=Připjeć +menu_action_unpin=Wotpjeć +confirm_history_delete_p1=Chceće woprawdźe kóždu instancu tuteje strony ze swojeje historije zhašeć? +# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in +# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a +# page from history. +confirm_history_delete_notice_p2=Tuta akcija njeda so cofnyć. +menu_action_save_to_pocket=Pola Pocket składować # LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder # for what the user has typed in the search input field, e.g. 'Search for ' + @@ -47,6 +69,10 @@ search_header=Z {search_engine_name} pytać search_web_placeholder=Web přepytać search_settings=Pytanske nastajenja změnić +# LOCALIZATION NOTE (section_info_option): This is the screenreader text for the +# (?) icon that would show a section's description with optional feedback link. +section_info_option=Info + # LOCALIZATION NOTE (welcome_*): This is shown as a modal dialog, typically on a # first-run experience when there's no data to display yet welcome_title=Witajće k nowemu rajtarkej @@ -68,9 +94,13 @@ settings_pane_search_header=Pytać settings_pane_search_body=Přepytajće web ze swojeho noweho rajtarka. settings_pane_topsites_header=Najhusćišo wopytane sydła settings_pane_topsites_body=Wočińće websydła, kotrež sće najhusćišo wopytał. -settings_pane_topsites_options_showmore=Dwě lince pokazać -settings_pane_highlights_header=Wjerški -settings_pane_highlights_body=Wobhladajće sej najnowšu přehladowansku historiju a nowo wutworjene zapołožki. +settings_pane_topsites_options_showmore=Dwaj rjadaj pokazać +settings_pane_bookmarks_header=Najnowše zapołožki +settings_pane_bookmarks_body=Waše nowo załožene zapołožki hnydom k ruce. +settings_pane_visit_again_header=Hišće raz wopytać +settings_pane_visit_again_body=Firefox wam dźěle wašeje přehladowanskeje historije pokazać, kotrež chceće sej snano spomjatkować abo na kotrež chceće wróćo přińć. +settings_pane_pocketstories_header=Najhusćišo přečitane zdźělenki +settings_pane_pocketstories_body=Pocket, dźěl swójby Mozilla, budźe pomhać, was z wobsahom wysokeje kwality zwjazować, kotryž njebyšće snano hewak namakał. settings_pane_done_button=Hotowo # LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal @@ -81,5 +111,46 @@ edit_topsites_showmore_button=Wjace pokazać edit_topsites_showless_button=Mjenje pokazać edit_topsites_done_button=Hotowo edit_topsites_pin_button=Tute sydło připjeć +edit_topsites_unpin_button=Tute sydło wotpinyć edit_topsites_edit_button=Tute sydło wobdźěłać edit_topsites_dismiss_button=Sydło zaćisnyć +edit_topsites_add_button=Přidać + +# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal. +topsites_form_add_header=Nowe najhusćišo wopytane sydło +topsites_form_edit_header=Najhusćišo wopytane sydło wobdźěłać +topsites_form_title_placeholder=Titul zapodać +topsites_form_url_placeholder=URL zapodać abo zasadźić +topsites_form_add_button=Přidać +topsites_form_save_button=Składować +topsites_form_cancel_button=Přetorhnyć +topsites_form_url_validation=Płaćiwy URL trěbny + +# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the +# trending stories section and precedes a list of links to popular topics. +pocket_read_more=Woblubowane temy: +# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the +# end of the list of popular topic links. +pocket_read_even_more=Dalše zdźělenki sej wobhladać +# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction +# to Pocket as part of the feedback form. +pocket_feedback_header=Najlěpše z weba, zhromadźene wot wjace hač 25 milionow ludźi. +# LOCALIZATION NOTE (pocket_feedback_body): This is shown below +# (pocket_feedback_header) to provide more information about Pocket. +pocket_feedback_body=Pocket, dźěl swójby Mozilla, budźe pomhać, was z wobsahom wysokeje kwality zwjazować, kotryž njebyšće snano hewak namakał. +pocket_send_feedback=Komentar pósłać + +# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations, +# in the space that would have shown a few stories, this is shown instead. +# {provider} is replaced by the name of the content provider for this section. +topstories_empty_state=To je nachwilu wšitko. Wróćće so pozdźišo dalšich wulkotnych stawiznow dla wot {provider}. Njemóžeće čakać? Wubjerće woblubowanu temu, zo byšće dalše wulkotne stawizny z weba namakał. + +# LOCALIZATION NOTE (manual_migration_explanation): This message is shown to encourage users to +# import their browser profile from another browser they might be using. +manual_migration_explanation=Wupruwujće Firefox ze swojimi najlubšimi websydłami a zapołožkami z druheho wobhladowaka. +# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the +# process of importing another browser’s profile into Firefox. +manual_migration_cancel_button=Ně, dźakuju so +# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process +# of importing another browser’s profile profile into Firefox. +manual_migration_import_button=Nětko importować diff --git a/locales/hu/strings.properties b/locales/hu/strings.properties index 86250474d0..df606f7224 100644 --- a/locales/hu/strings.properties +++ b/locales/hu/strings.properties @@ -2,7 +2,19 @@ newtab_page_title=Új lap default_label_loading=Betöltés… header_top_sites=Népszerű oldalak -header_highlights=Kiemelések +header_stories=Népszerű történetek +header_visit_again=Látogasson el ismét +header_bookmarks=Friss könyvjelzők +# LOCALIZATION NOTE(header_recommended_by): This is followed by the name +# of the corresponding content provider. +header_recommended_by=A(z) {provider} ajánlásával +# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is +# meant to inform that section contains no information because +# the user hasn't added any bookmarks. +header_bookmarks_placeholder=Még nincs könyvjelzője. +# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the +# corresponding content (stories) provider +header_stories_from=innen: # LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give # context on how the element is related to the user, e.g. type indicates that @@ -10,9 +22,11 @@ header_highlights=Kiemelések type_label_visited=Látogatott type_label_bookmarked=Könyvjelzőzött type_label_synced=Másik eszközről szinkronizálva +type_label_recommended=Népszerű # LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open" type_label_open=Megnyitás type_label_topic=Téma +type_label_now=Most # LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context # menu and are meant as a call to action for a given page. @@ -26,6 +40,14 @@ menu_action_open_new_window=Megnyitás új ablakban menu_action_open_private_window=Megnyitás új privát ablakban menu_action_dismiss=Elutasítás menu_action_delete=Törlés az előzményekből +menu_action_pin=Rögzítés +menu_action_unpin=Rögzítés feloldása +confirm_history_delete_p1=Biztosan törli ezen oldal minden példányát az előzményekből? +# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in +# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a +# page from history. +confirm_history_delete_notice_p2=Ez a művelet nem vonható vissza. +menu_action_save_to_pocket=Mentés a Pocketbe # LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder # for what the user has typed in the search input field, e.g. 'Search for ' + @@ -47,6 +69,10 @@ search_header={search_engine_name} keresés search_web_placeholder=Keresés a weben search_settings=Keresési beállítások módosítása +# LOCALIZATION NOTE (section_info_option): This is the screenreader text for the +# (?) icon that would show a section's description with optional feedback link. +section_info_option=Információ + # LOCALIZATION NOTE (welcome_*): This is shown as a modal dialog, typically on a # first-run experience when there's no data to display yet welcome_title=Üdvözöljük az új lapon @@ -69,8 +95,12 @@ settings_pane_search_body=Keresés a weben az új lapon. settings_pane_topsites_header=Népszerű oldalak settings_pane_topsites_body=A leggyakrabban látogatott webhelyek elérése. settings_pane_topsites_options_showmore=Két sor megjelenítése -settings_pane_highlights_header=Kiemelések -settings_pane_highlights_body=A böngészési előzmények, és az újonnan létrehozott könyvjelzők visszanézése. +settings_pane_bookmarks_header=Friss könyvjelzők +settings_pane_bookmarks_body=A frissen létrehozott könyvjelzői egy praktikus helyen. +settings_pane_visit_again_header=Látogasson el ismét +settings_pane_visit_again_body=A Firefox megjeleníti a böngészési előzményeinek azt a részét, amelyet lehet hogy meg szeretne jegyezni, vagy ahová vissza akar térni. +settings_pane_pocketstories_header=Népszerű történetek +settings_pane_pocketstories_body=A Pocket a Mozilla család tagja, segít az olyan jó minőségű tartalmak fellelésében, melyekkel egyébként nem is találkozott volna. settings_pane_done_button=Kész # LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal @@ -81,5 +111,46 @@ edit_topsites_showmore_button=Több megjelenítése edit_topsites_showless_button=Kevesebb megjelenítése edit_topsites_done_button=Kész edit_topsites_pin_button=Webhely rögzítése +edit_topsites_unpin_button=Rögzítés feloldása edit_topsites_edit_button=Webhely szerkesztése edit_topsites_dismiss_button=Webhely eltávolítása +edit_topsites_add_button=Hozzáadás + +# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal. +topsites_form_add_header=Új népszerű oldal +topsites_form_edit_header=Népszerű oldal szerkesztése +topsites_form_title_placeholder=Cím megadása +topsites_form_url_placeholder=Írjon vagy illesszen be egy URL-t +topsites_form_add_button=Hozzáadás +topsites_form_save_button=Mentés +topsites_form_cancel_button=Mégse +topsites_form_url_validation=Érvényes URL szükséges + +# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the +# trending stories section and precedes a list of links to popular topics. +pocket_read_more=Népszerű témák: +# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the +# end of the list of popular topic links. +pocket_read_even_more=További történetek +# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction +# to Pocket as part of the feedback form. +pocket_feedback_header=A web legjava, több mint 25 millió ember válogatásában. +# LOCALIZATION NOTE (pocket_feedback_body): This is shown below +# (pocket_feedback_header) to provide more information about Pocket. +pocket_feedback_body=A Pocket a Mozilla család tagja, segít az olyan jó minőségű tartalmak fellelésében, melyekkel egyébként nem is találkozott volna. +pocket_send_feedback=Visszajelzés küldése + +# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations, +# in the space that would have shown a few stories, this is shown instead. +# {provider} is replaced by the name of the content provider for this section. +topstories_empty_state=Már felzárkózott. Nézzen vissza később a legújabb {provider} hírekért. Nem tud várni? Válasszon egy népszerű témát, hogy még több sztorit találjon a weben. + +# LOCALIZATION NOTE (manual_migration_explanation): This message is shown to encourage users to +# import their browser profile from another browser they might be using. +manual_migration_explanation=Próbálja ki a Firefoxot egy másik böngészőben lévő kedvenc oldalaival és könyvjelzőivel. +# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the +# process of importing another browser’s profile into Firefox. +manual_migration_cancel_button=Köszönöm, nem +# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process +# of importing another browser’s profile profile into Firefox. +manual_migration_import_button=Importálás most diff --git a/locales/id/strings.properties b/locales/id/strings.properties index 46f5dc41f0..3328ab8c4d 100644 --- a/locales/id/strings.properties +++ b/locales/id/strings.properties @@ -3,6 +3,10 @@ default_label_loading=Memuat… header_top_sites=Situs Teratas header_highlights=Sorotan +header_stories=Cerita Utama +# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the +# corresponding content (stories) provider +header_stories_from=dari # LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give # context on how the element is related to the user, e.g. type indicates that @@ -10,6 +14,7 @@ header_highlights=Sorotan type_label_visited=Dikunjungi type_label_bookmarked=Dimarkahi type_label_synced=Disinkronkan dari perangkat lain +type_label_recommended=Trending # LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open" type_label_open=Buka type_label_topic=Topik @@ -26,6 +31,7 @@ menu_action_open_new_window=Buka di Jendela Baru menu_action_open_private_window=Buka di Jendela Penjelajahan Pribadi Baru menu_action_dismiss=Tutup menu_action_delete=Hapus dari Riwayat +menu_action_save_to_pocket=Simpan ke Pocket # LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder # for what the user has typed in the search input field, e.g. 'Search for ' + @@ -71,6 +77,8 @@ settings_pane_topsites_body=Mengakses situs web yang paling sering Anda kunjungi settings_pane_topsites_options_showmore=Tampilkan dua baris settings_pane_highlights_header=Sorotan settings_pane_highlights_body=Melihat kembali pada riwayat peramban terbaru dan markah yang baru dibuat. +settings_pane_pocketstories_header=Cerita Utama +settings_pane_pocketstories_body=Pocket, bagian dari keluarga Mozilla, akan membantu hubungkan Anda dengan konten berkualitas tinggi yang tak dapat Anda temukan di tempat lain. settings_pane_done_button=Selesai # LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal @@ -81,5 +89,31 @@ edit_topsites_showmore_button=Tampilkan lainnya edit_topsites_showless_button=Tampilkan lebih sedikit edit_topsites_done_button=Selesai edit_topsites_pin_button=Sematkan situs ini +edit_topsites_unpin_button=Lepaskan situs ini edit_topsites_edit_button=Sunting situs ini edit_topsites_dismiss_button=Abaikan situs ini +edit_topsites_add_button=Tambah + +# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal. +topsites_form_add_header=Situs Pilihan Baru +topsites_form_edit_header=Ubah Situs Pilihan +topsites_form_title_placeholder=Masukkan judul +topsites_form_url_placeholder=Ketik atau tempel URL +topsites_form_add_button=Tambah +topsites_form_save_button=Simpan +topsites_form_cancel_button=Batalkan +topsites_form_url_validation=URL valid diperlukan + +# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the +# trending stories section and precedes a list of links to popular topics. +pocket_read_more=Topik Populer: +# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the +# end of the list of popular topic links. +pocket_read_even_more=Lihat Cerita Lainnya +# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction +# to Pocket as part of the feedback form. +pocket_feedback_header=Yang terbaik dari Web, dikurasi lebih dari 25 juta orang. +# LOCALIZATION NOTE (pocket_feedback_body): This is shown below +# (pocket_feedback_header) to provide more information about Pocket. +pocket_feedback_body=Pocket, bagian dari keluarga Mozilla, akan membantu hubungkan Anda dengan konten berkualitas tinggi yang tak dapat Anda temukan di tempat lain. +pocket_send_feedback=Kirim Umpanbalik diff --git a/locales/it/strings.properties b/locales/it/strings.properties index 7ab02fb6de..40e3e683c4 100644 --- a/locales/it/strings.properties +++ b/locales/it/strings.properties @@ -2,7 +2,19 @@ newtab_page_title=Nuova scheda default_label_loading=Caricamento… header_top_sites=Siti principali -header_highlights=In evidenza +header_stories=Storie principali +header_visit_again=Visita di nuovo +header_bookmarks=Segnalibri recenti +# LOCALIZATION NOTE(header_recommended_by): This is followed by the name +# of the corresponding content provider. +header_recommended_by=Consigliato da {provider} +# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is +# meant to inform that section contains no information because +# the user hasn't added any bookmarks. +header_bookmarks_placeholder=Non è ancora disponibile alcun segnalibro. +# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the +# corresponding content (stories) provider +header_stories_from=da # LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give # context on how the element is related to the user, e.g. type indicates that @@ -10,9 +22,11 @@ header_highlights=In evidenza type_label_visited=Visitato type_label_bookmarked=Nei segnalibri type_label_synced=Sincronizzato da un altro dispositivo +type_label_recommended=Di tendenza # LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open" type_label_open=Apri type_label_topic=Argomento +type_label_now=Adesso # LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context # menu and are meant as a call to action for a given page. @@ -26,6 +40,14 @@ menu_action_open_new_window=Apri in una nuova finestra menu_action_open_private_window=Apri in una nuova finestra anonima menu_action_dismiss=Rimuovi menu_action_delete=Elimina dalla cronologia +menu_action_pin=Aggiungi alla bacheca +menu_action_unpin=Rimuovi dalla bacheca +confirm_history_delete_p1=Eliminare tutte le occorrenze di questa pagina dalla cronologia? +# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in +# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a +# page from history. +confirm_history_delete_notice_p2=Questa operazione non può essere annullata. +menu_action_save_to_pocket=Salva in Pocket # LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder # for what the user has typed in the search input field, e.g. 'Search for ' + @@ -47,6 +69,10 @@ search_header=Ricerca {search_engine_name} search_web_placeholder=Cerca sul Web search_settings=Cambia impostazioni di ricerca +# LOCALIZATION NOTE (section_info_option): This is the screenreader text for the +# (?) icon that would show a section's description with optional feedback link. +section_info_option=Info + # LOCALIZATION NOTE (welcome_*): This is shown as a modal dialog, typically on a # first-run experience when there's no data to display yet welcome_title=Benvenuto nella nuova scheda @@ -69,8 +95,12 @@ settings_pane_search_body=Avvia ricerche in una nuova scheda. settings_pane_topsites_header=Siti principali settings_pane_topsites_body=Accedi ai siti che visiti più spesso. settings_pane_topsites_options_showmore=Visualizza due righe -settings_pane_highlights_header=In evidenza -settings_pane_highlights_body=Visualizza gli elementi più recenti nella cronologia e gli ultimi segnalibri memorizzati. +settings_pane_bookmarks_header=Segnalibri recenti +settings_pane_bookmarks_body=Tutti i segnalibri appena creati, facilmente accessibili. +settings_pane_visit_again_header=Visita di nuovo +settings_pane_visit_again_body=Firefox mostrerà alcuni elementi, estratti dalla cronologia di navigazione, che potresti voler visitare di nuovo. +settings_pane_pocketstories_header=Storie principali +settings_pane_pocketstories_body=Grazie a Pocket, un componente della famiglia Mozilla, puoi raggiungere contenuti di alta qualità che altrimenti potrebbero sfuggirti. settings_pane_done_button=Fatto # LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal @@ -81,5 +111,46 @@ edit_topsites_showmore_button=Visualizza altri edit_topsites_showless_button=Nascondi altri edit_topsites_done_button=Fatto edit_topsites_pin_button=Aggiungi sito alla bacheca +edit_topsites_unpin_button=Rimuovi sito dalla bacheca edit_topsites_edit_button=Modifica questo sito edit_topsites_dismiss_button=Ignora questo sito +edit_topsites_add_button=Aggiungi + +# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal. +topsites_form_add_header=Nuovi sito principale +topsites_form_edit_header=Modifica sito principale +topsites_form_title_placeholder=Inserire un titolo +topsites_form_url_placeholder=Digitare o incollare un URL +topsites_form_add_button=Aggiungi +topsites_form_save_button=Salva +topsites_form_cancel_button=Annulla +topsites_form_url_validation=È necessario fornire un URL valido + +# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the +# trending stories section and precedes a list of links to popular topics. +pocket_read_more=Argomenti popolari: +# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the +# end of the list of popular topic links. +pocket_read_even_more=Visualizza altre storie +# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction +# to Pocket as part of the feedback form. +pocket_feedback_header=Il meglio del web, selezionato da 25 milioni di persone. +# LOCALIZATION NOTE (pocket_feedback_body): This is shown below +# (pocket_feedback_header) to provide more information about Pocket. +pocket_feedback_body=Grazie a Pocket, un componente della famiglia Mozilla, puoi raggiungere contenuti di alta qualità che altrimenti potrebbero sfuggirti. +pocket_send_feedback=Invia feedback + +# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations, +# in the space that would have shown a few stories, this is shown instead. +# {provider} is replaced by the name of the content provider for this section. +topstories_empty_state=Non c'è altro. Controlla più tardi per altre storie da {provider}. Non vuoi aspettare? Seleziona un argomento tra quelli più popolari per scoprire altre notizie interessanti dal Web. + +# LOCALIZATION NOTE (manual_migration_explanation): This message is shown to encourage users to +# import their browser profile from another browser they might be using. +manual_migration_explanation=Prova Firefox con i siti preferiti e i segnalibri importati da un altro browser. +# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the +# process of importing another browser’s profile into Firefox. +manual_migration_cancel_button=No grazie +# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process +# of importing another browser’s profile profile into Firefox. +manual_migration_import_button=Importa adesso diff --git a/locales/ja/strings.properties b/locales/ja/strings.properties index ccca25cbbb..7e1efc6de3 100644 --- a/locales/ja/strings.properties +++ b/locales/ja/strings.properties @@ -2,17 +2,31 @@ newtab_page_title=新しいタブ default_label_loading=読み込み中... header_top_sites=トップサイト -header_highlights=ハイライト +header_stories=トップ記事 +header_visit_again=再度訪れる +header_bookmarks=最近のブックマーク +# LOCALIZATION NOTE(header_recommended_by): This is followed by the name +# of the corresponding content provider. +header_recommended_by={provider} のおすすめ +# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is +# meant to inform that section contains no information because +# the user hasn't added any bookmarks. +header_bookmarks_placeholder=まだブックマークがありません。 +# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the +# corresponding content (stories) provider +header_stories_from=配信元 # LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give # context on how the element is related to the user, e.g. type indicates that # the page is bookmarked, or is currently open on another device type_label_visited=訪問済み -type_label_bookmarked=ブックマーク +type_label_bookmarked=ブックマーク済み type_label_synced=他の端末から同期 +type_label_recommended=話題の記事 # LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open" type_label_open=開く type_label_topic=トピック +type_label_now=今 # LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context # menu and are meant as a call to action for a given page. @@ -26,6 +40,14 @@ menu_action_open_new_window=新しいウィンドウで開く menu_action_open_private_window=新しいプライベートウィンドウで開く menu_action_dismiss=閉じる menu_action_delete=履歴から削除 +menu_action_pin=ピン留め +menu_action_unpin=ピン留めを外す +confirm_history_delete_p1=本当にこのページに関して保存されているあらゆる情報を履歴から削除しますか? +# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in +# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a +# page from history. +confirm_history_delete_notice_p2=この操作は取り消せません。 +menu_action_save_to_pocket=Pocket へ保存 # LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder # for what the user has typed in the search input field, e.g. 'Search for ' + @@ -47,6 +69,10 @@ search_header={search_engine_name} 検索 search_web_placeholder=ウェブを検索 search_settings=検索設定を変更 +# LOCALIZATION NOTE (section_info_option): This is the screenreader text for the +# (?) icon that would show a section's description with optional feedback link. +section_info_option=情報 + # LOCALIZATION NOTE (welcome_*): This is shown as a modal dialog, typically on a # first-run experience when there's no data to display yet welcome_title=新しいタブへようこそ @@ -69,8 +95,12 @@ settings_pane_search_body=新しいタブからウェブを検索します。 settings_pane_topsites_header=トップサイト settings_pane_topsites_body=よく訪れるサイトへアクセス。 settings_pane_topsites_options_showmore=2 行で表示 -settings_pane_highlights_header=ハイライト -settings_pane_highlights_body=最近の閲覧履歴と新たに作成されたブックマークを振り返りましょう。 +settings_pane_bookmarks_header=最近のブックマーク +settings_pane_bookmarks_body=新たに作成されたブックマークをひとつの場所にまとめて使いやすく。 +settings_pane_visit_again_header=再度訪れる +settings_pane_visit_again_body=Firefox は、ブラウジング履歴の中から、あなたが覚えておきたい、あるいは後で戻りたいと思われるページの一覧を表示します。 +settings_pane_pocketstories_header=トップ記事 +settings_pane_pocketstories_body=Mozilla ファミリーの一員となった Pocket は、他では見つからなかったかもしれない高品質なコンテンツとあなたを結び付ける手助けをします。 settings_pane_done_button=完了 # LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal @@ -81,5 +111,46 @@ edit_topsites_showmore_button=もっと見る edit_topsites_showless_button=折りたたむ edit_topsites_done_button=完了 edit_topsites_pin_button=このサイトをピン留め +edit_topsites_unpin_button=このサイトのピン留めを外す edit_topsites_edit_button=このサイトを編集 edit_topsites_dismiss_button=このサイトを削除 +edit_topsites_add_button=追加 + +# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal. +topsites_form_add_header=新着トップサイト +topsites_form_edit_header=トップサイトを編集 +topsites_form_title_placeholder=タイトルを入力 +topsites_form_url_placeholder=URL を入力するか貼り付け +topsites_form_add_button=追加 +topsites_form_save_button=保存 +topsites_form_cancel_button=キャンセル +topsites_form_url_validation=正しい URL を入力してください + +# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the +# trending stories section and precedes a list of links to popular topics. +pocket_read_more=人気のトピック: +# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the +# end of the list of popular topic links. +pocket_read_even_more=他の記事を見る +# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction +# to Pocket as part of the feedback form. +pocket_feedback_header=2,500 万人以上の人々によって収集されている、ウェブ上で最も優れたコンテンツ。 +# LOCALIZATION NOTE (pocket_feedback_body): This is shown below +# (pocket_feedback_header) to provide more information about Pocket. +pocket_feedback_body=Mozilla ファミリーの一員となった Pocket は、他では見つからなかったかもしれない高品質なコンテンツとあなたを結び付ける手助けをします。 +pocket_send_feedback=フィードバックを送る + +# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations, +# in the space that would have shown a few stories, this is shown instead. +# {provider} is replaced by the name of the content provider for this section. +topstories_empty_state=すべて既読です。また後で戻って {provider} からのおすすめ記事をチェックしてください。もし待ちきれないなら、人気のトピックを選択すれば、他にもウェブ上の優れた記事を見つけられます。 + +# LOCALIZATION NOTE (manual_migration_explanation): This message is shown to encourage users to +# import their browser profile from another browser they might be using. +manual_migration_explanation=他のブラウザーから Firefox へあなたのお気に入りのサイトやブックマークを取り込んでみましょう。 +# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the +# process of importing another browser’s profile into Firefox. +manual_migration_cancel_button=今はしない +# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process +# of importing another browser’s profile profile into Firefox. +manual_migration_import_button=今すぐインポート diff --git a/locales/ka/strings.properties b/locales/ka/strings.properties index 036ca74052..cc0acb76e6 100644 --- a/locales/ka/strings.properties +++ b/locales/ka/strings.properties @@ -1,37 +1,156 @@ +newtab_page_title=ახალი ჩანართი +default_label_loading=იტვირთება… +header_top_sites=მთავარი საიტები +header_stories=მთავარი სიახლეები +header_visit_again=ხელახლა ნახვა +header_bookmarks=ბოლოს ჩანიშნულები +# LOCALIZATION NOTE(header_recommended_by): This is followed by the name +# of the corresponding content provider. +header_recommended_by=რეკომენდებულია {provider}-ის მიერ +# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is +# meant to inform that section contains no information because +# the user hasn't added any bookmarks. +header_bookmarks_placeholder=სანიშნეები ჯერ არაა დამატებული. +# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the +# corresponding content (stories) provider +header_stories_from=-იდან # LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give # context on how the element is related to the user, e.g. type indicates that # the page is bookmarked, or is currently open on another device +type_label_visited=მონახულებული +type_label_bookmarked=ჩანიშნული +type_label_synced=სხვა მოწყობილობიდან დასინქრონებული +type_label_recommended=პოპულარული # LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open" +type_label_open=გახსნა +type_label_topic=თემა +type_label_now=ახლა # LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context # menu and are meant as a call to action for a given page. # LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to # bookmarks" +menu_action_bookmark=ჩანიშვნა +menu_action_remove_bookmark=სანიშნეებიდან ამოღება +menu_action_copy_address=მისამართის დაკოპირება +menu_action_email_link=ბმულის გაგზავნა… +menu_action_open_new_window=ახალ ფანჯარაში გახსნა +menu_action_open_private_window=ახალ პირად ფანჯარაში გახსნა +menu_action_dismiss=დახურვა +menu_action_delete=ისტორიიდან ამოშლა +menu_action_pin=მიმაგრება +menu_action_unpin=მოხსნა +confirm_history_delete_p1=ნამდვილად გსურთ, ამ გვერდის ყველა ჩანაწერის ისტორიიდან ამოშლა? +# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in +# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a +# page from history. +confirm_history_delete_notice_p2=ეს ქმედება შეუქცევადია. +menu_action_save_to_pocket=Pocket-ში შენახვა # LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder # for what the user has typed in the search input field, e.g. 'Search for ' + # search_term + 'with:' becomes 'Search for abc with:' # The search engine name is displayed as an icon and does not need a translation +search_for_something_with={search_term} -ის ძიება: # LOCALIZATION NOTE (search_button): This is screenreader only text for the # search button. +search_button=ძიება # LOCALIZATION NOTE (search_header): Displayed at the top of the panel # showing search suggestions. {search_engine_name} is replaced with the name of # the current default search engine. e.g. 'Google Search' +search_header={search_engine_name} -ში ძიება # LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when # the user hasn't typed anything yet. +search_web_placeholder=ინტერნეტში ძიება +search_settings=ძიების პარამეტრების შეცვლა + +# LOCALIZATION NOTE (section_info_option): This is the screenreader text for the +# (?) icon that would show a section's description with optional feedback link. +section_info_option=ინფორმაცია # LOCALIZATION NOTE (welcome_*): This is shown as a modal dialog, typically on a # first-run experience when there's no data to display yet +welcome_title=მოგესალმებით ახალ ჩანართზე +welcome_body=Firefox ამ სივრცეს გამოიყენებს თქვენთვის ყველაზე საჭირო სანიშნეების, სტატიების, ვიდეოებისა და ბოლოს მონახულებული გვერდებისთვის, რომ ადვილად შეძლოთ მათზე დაბრუნება. +welcome_label=რჩეული ვებ-გვერდების დადგენა # LOCALIZATION NOTE (time_label_*): {number} is a placeholder for a number which # represents a shortened timestamp format, e.g. '10m' means '10 minutes ago'. +time_label_less_than_minute=<1წთ +time_label_minute={number}წთ +time_label_hour={number}სთ +time_label_day={number}დღე # LOCALIZATION NOTE (settings_pane_*): This is shown in the Settings Pane sidebar. +settings_pane_button_label=მოირგეთ ახალი ჩანართის გვერდი +settings_pane_header=ახალი ჩანართის პარამეტრები +settings_pane_body=აირჩიეთ რისი ხილვა გსურთ ახალი ჩანართის გახსნისას. +settings_pane_search_header=ძიება +settings_pane_search_body=ძიება ინტერნეტში ახალი ჩანართიდან. +settings_pane_topsites_header=საუკეთესო საიტები +settings_pane_topsites_body=წვდომა ხშირად მონახულებულ საიტებთან. +settings_pane_topsites_options_showmore=ორ რიგად ჩვენება +settings_pane_bookmarks_header=ბოლოს ჩანიშნულები +settings_pane_bookmarks_body=ახლად შექმნილი სანიშნეები, ერთი ხელის გაწვდენაზე. +settings_pane_visit_again_header=ხელახლა ნახვა +settings_pane_visit_again_body=Firefox გაჩვენებთ მონახულებული გვერდების ისტორიიდან იმას, რისი გახსენებაც ან რაზე დაბრუნებაც გენდომებათ. +settings_pane_pocketstories_header=მთავარი სიახლეები +settings_pane_pocketstories_body=Pocket არის Mozilla-ს ოჯახის ნაწილი, რომელიც დაგეხმარებათ ისეთი მაღალი ხარისხის კონტენტის მოძიებაში, რომელიც სხვა გზებით, შეიძლება ვერ მოგენახათ. +settings_pane_done_button=მზადაა # LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal # dialog. +edit_topsites_button_text=ჩასწორება +edit_topsites_button_label=მოირგეთ რჩეული საიტების განყოფილება +edit_topsites_showmore_button=მეტის ჩვენება +edit_topsites_showless_button=ნაკლების ჩვენება +edit_topsites_done_button=მზადაა +edit_topsites_pin_button=საიტის მიმაგრება +edit_topsites_unpin_button=მიმაგრების მოხსნა +edit_topsites_edit_button=საიტის ჩასწორება +edit_topsites_dismiss_button=საიტის დამალვა +edit_topsites_add_button=დამატება + +# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal. +topsites_form_add_header=ახალი საიტი რჩეულებში +topsites_form_edit_header=რჩეული საიტების ჩასწორება +topsites_form_title_placeholder=სათაურის შეყვანა +topsites_form_url_placeholder=აკრიფეთ ან ჩასვით URL +topsites_form_add_button=დამატება +topsites_form_save_button=შენახვა +topsites_form_cancel_button=გაუქმება +topsites_form_url_validation=საჭიროა მართებული URL + +# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the +# trending stories section and precedes a list of links to popular topics. +pocket_read_more=პოპულარული თემები: +# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the +# end of the list of popular topic links. +pocket_read_even_more=მეტი სიახლის ნახვა +# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction +# to Pocket as part of the feedback form. +pocket_feedback_header=საუკეთესოები ინტერნეტიდან, 25 მილიონზე მეტი ადამიანის მიერ არჩეული. +# LOCALIZATION NOTE (pocket_feedback_body): This is shown below +# (pocket_feedback_header) to provide more information about Pocket. +pocket_feedback_body=Pocket არის Mozilla-ს ოჯახის ნაწილი, რომელიც დაგეხმარებათ ისეთი მაღალი ხარისხის კონტენტის მოძიებაში, რომელიც სხვა გზებით, შეიძლება ვერ მოგენახათ. +pocket_send_feedback=უკუკავშირი + +# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations, +# in the space that would have shown a few stories, this is shown instead. +# {provider} is replaced by the name of the content provider for this section. +topstories_empty_state=უკვე ყველაფერი წაკითხული გაქვთ. {provider}-იდან ახალი რჩეული სტატიების მისაღებად, მოგვიანებით შემოიარეთ. თუ ვერ ითმენთ, აირჩიეთ რომელიმე მოთხოვნადი თემა, ახალი საინტერესო სტატიების მოსაძიებლად. + +# LOCALIZATION NOTE (manual_migration_explanation): This message is shown to encourage users to +# import their browser profile from another browser they might be using. +manual_migration_explanation=სცადეთ Firefox, გადმოიტანეთ თქვენი რჩეული საიტები და სანიშნეები სხვა ბრაუზერიდან. +# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the +# process of importing another browser’s profile into Firefox. +manual_migration_cancel_button=არა, გმადლობთ +# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process +# of importing another browser’s profile profile into Firefox. +manual_migration_import_button=ახლავე გადმოტანა diff --git a/locales/kab/strings.properties b/locales/kab/strings.properties index e4936f4150..7748ddcf0c 100644 --- a/locales/kab/strings.properties +++ b/locales/kab/strings.properties @@ -2,7 +2,19 @@ newtab_page_title=Iccer amaynut default_label_loading=Asali… header_top_sites=Ismal ifazen -header_highlights=Iferdisen tisura +header_stories=Tiqsiɣin ifazen +header_visit_again=Rzu tikelt-nniḍen +header_bookmarks=Ticraḍ n melmi kan +# LOCALIZATION NOTE(header_recommended_by): This is followed by the name +# of the corresponding content provider. +header_recommended_by=Iwelleh-it-id {provider} +# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is +# meant to inform that section contains no information because +# the user hasn't added any bookmarks. +header_bookmarks_placeholder=Ur ɣur-k ara ticraḍ yakan. +# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the +# corresponding content (stories) provider +header_stories_from=seg # LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give # context on how the element is related to the user, e.g. type indicates that @@ -10,9 +22,11 @@ header_highlights=Iferdisen tisura type_label_visited=Yettwarza type_label_bookmarked=Yettwacreḍ type_label_synced=Yemtawi seg ibenk-nniḍen +type_label_recommended=Tiddin # LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open" type_label_open=Yeldi type_label_topic=Asentel +type_label_now=Tura # LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context # menu and are meant as a call to action for a given page. @@ -26,6 +40,14 @@ menu_action_open_new_window=Ldei deg usfaylu amaynut menu_action_open_private_window=Ldi deg usfaylu uslig amaynut menu_action_dismiss=Kkes menu_action_delete=Kkes seg umazray +menu_action_pin=Senteḍ +menu_action_unpin=Serreḥ +confirm_history_delete_p1=Tebɣiḍ ad tekksed yal tummant n usebter-agi seg umazray-ik? +# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in +# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a +# page from history. +confirm_history_delete_notice_p2=Tigawt-agi ur tettuɣal ara ar deffir. +menu_action_save_to_pocket=Sekles ɣer Pocket # LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder # for what the user has typed in the search input field, e.g. 'Search for ' + @@ -47,6 +69,10 @@ search_header=Anadi {search_engine_name} search_web_placeholder=Nadi di Web search_settings=Snifel iγewwaṛen n unadi +# LOCALIZATION NOTE (section_info_option): This is the screenreader text for the +# (?) icon that would show a section's description with optional feedback link. +section_info_option=Talɣut + # LOCALIZATION NOTE (welcome_*): This is shown as a modal dialog, typically on a # first-run experience when there's no data to display yet welcome_title=Ansuf ar yiccer amaynut @@ -69,8 +95,12 @@ settings_pane_search_body=Nadi di Web seg iccer-ik amaynut. settings_pane_topsites_header=Ismal ifazen settings_pane_topsites_body=Kcem ar yesmal web i trezzuḍ s waṭas. settings_pane_topsites_options_showmore=Sken sin izirigen -settings_pane_highlights_header=Asebrureq -settings_pane_highlights_body=Wali ar deffir ar umazray n tunigin yezrin akked tecraḍ i terniḍ melmi kan. +settings_pane_bookmarks_header=Ticraḍ n melmi kan +settings_pane_bookmarks_body=Ticraḍ yettwarnan melmi kan deg iwen n umdiq ɣef afus. +settings_pane_visit_again_header=Rzu tikelt-nniḍen +settings_pane_visit_again_body=Firefox ad d-yesken tukkist n umazray-ik n tunigin i tzemreḍ ad twalid tikelt-nniḍen. +settings_pane_pocketstories_header=Tiqsiɣin ifazen +settings_pane_pocketstories_body=Pocket, aɛeggal n twaxult n Mozilla, ak-d-yefk afus ad twaliḍ agbur n tɣara meqqren i tzemred ad tzegleḍ. settings_pane_done_button=Immed # LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal @@ -81,5 +111,46 @@ edit_topsites_showmore_button=Sken ugar edit_topsites_showless_button=Sken qel edit_topsites_done_button=Immed edit_topsites_pin_button=Ṭṭef asmel-agi +edit_topsites_unpin_button=Serreḥ asmel-agi edit_topsites_edit_button=Ẓreg asmel-agi edit_topsites_dismiss_button=Anef i usmel-agi +edit_topsites_add_button=Rnu + +# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal. +topsites_form_add_header=Asmel ifazen amaynut +topsites_form_edit_header=Ẓreg asmel ifazen +topsites_form_title_placeholder=Sekcem azwel +topsites_form_url_placeholder=Aru neɣ sekcem tansa URL +topsites_form_add_button=Rnu +topsites_form_save_button=Sekles +topsites_form_cancel_button=Sefsex +topsites_form_url_validation=Tansa URL tameɣtut tettwasra + +# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the +# trending stories section and precedes a list of links to popular topics. +pocket_read_more=Isental ittwasnen aṭas: +# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the +# end of the list of popular topic links. +pocket_read_even_more=Wali ugar n teqsiḍin +# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction +# to Pocket as part of the feedback form. +pocket_feedback_header=D amezwaru n Web, ittwafren sγur ugar 25 imelyan n imdanen. +# LOCALIZATION NOTE (pocket_feedback_body): This is shown below +# (pocket_feedback_header) to provide more information about Pocket. +pocket_feedback_body=Pocket, aɛeggal n twaxult n Mozilla, ak-d-yefk afus ad twaliḍ agbur n tɣara meqqren i tzemred ad tzegleḍ. +pocket_send_feedback=Azen tikti + +# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations, +# in the space that would have shown a few stories, this is shown instead. +# {provider} is replaced by the name of the content provider for this section. +topstories_empty_state=Ulac wiyaḍ. Uɣal-d ticki s wugar n imagraden seg {provider}. Ur tebɣiḍ ara ad terǧuḍ? Fren asentel seg wid yettwasnen akken ad twaliḍ imagraden yelhan di Web. + +# LOCALIZATION NOTE (manual_migration_explanation): This message is shown to encourage users to +# import their browser profile from another browser they might be using. +manual_migration_explanation=Ɛreḍ Firefox s ismal-ik inurifen akked ticraḍ seg iminig-nniḍen. +# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the +# process of importing another browser’s profile into Firefox. +manual_migration_cancel_button=Ala, tanemmirt +# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process +# of importing another browser’s profile profile into Firefox. +manual_migration_import_button=Kter tura diff --git a/locales/kk/strings.properties b/locales/kk/strings.properties index e9a4b395d4..dd746d38d3 100644 --- a/locales/kk/strings.properties +++ b/locales/kk/strings.properties @@ -2,7 +2,16 @@ newtab_page_title=Жаңа бет default_label_loading=Жүктелуде… header_top_sites=Топ сайттар -header_highlights=Бастысы +header_stories=Топ хикаялар +header_visit_again=Қайтадан шолу +header_bookmarks=Соңғы бетбелгілер +# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is +# meant to inform that section contains no information because +# the user hasn't added any bookmarks. +header_bookmarks_placeholder=Сізде әлі бетбелгілер жоқ. +# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the +# corresponding content (stories) provider +header_stories_from=ұсынған # LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give # context on how the element is related to the user, e.g. type indicates that @@ -10,6 +19,7 @@ header_highlights=Бастысы type_label_visited=Қаралған type_label_bookmarked=Бетбелгілерде type_label_synced=Басқа құрылғыдан синхрондалған +type_label_recommended=Әйгілі # LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open" type_label_open=Ашу type_label_topic=Тақырып @@ -26,6 +36,14 @@ menu_action_open_new_window=Жаңа терезеде ашу menu_action_open_private_window=Жаңа жекелік терезесінде ашу menu_action_dismiss=Тайдыру menu_action_delete=Тарихтан өшіру +menu_action_pin=Бекіту +menu_action_unpin=Бекітуді алып тастау +confirm_history_delete_p1=Бұл парақтың барлық кездесулерін шолу тарихыңыздан өшіруді қалайсыз ба? +# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in +# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a +# page from history. +confirm_history_delete_notice_p2=Бұл әрекетті болдырмау мүмкін болмайды. +menu_action_save_to_pocket=Pocket-ке сақтау # LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder # for what the user has typed in the search input field, e.g. 'Search for ' + @@ -69,8 +87,12 @@ settings_pane_search_body=Жаңа беттен интернеттен ізде settings_pane_topsites_header=Топ сайттар settings_pane_topsites_body=Көбірек қаралатын сайттарға қатынау. settings_pane_topsites_options_showmore=Екі жолды көрсету -settings_pane_highlights_header=Бастысы -settings_pane_highlights_body=Жуырдағы шолу тарихы мен жаңа жасалған бетбелгілерге қарау. +settings_pane_bookmarks_header=Соңғы бетбелгілер +settings_pane_bookmarks_body=Сіздің жаңадан жасалған бетбелгілер бір ыңғайлы жерде. +settings_pane_visit_again_header=Қайтадан шолу +settings_pane_visit_again_body=Firefox сізге есте сақтауды немесе қайта шолуды қалауыңыз мүмкін тарихыңыздың бөліктерін көрсетеді. +settings_pane_pocketstories_header=Топ хикаялар +settings_pane_pocketstories_body=Pocket, Mozilla құрамындағы өнім, сізге әдетте табылмауы мүмкін құрамаға байланысуға көмектеседі. settings_pane_done_button=Дайын # LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal @@ -81,5 +103,31 @@ edit_topsites_showmore_button=Көбірек көрсету edit_topsites_showless_button=Азырақ көрсету edit_topsites_done_button=Дайын edit_topsites_pin_button=Бұл сайтты жапсыру +edit_topsites_unpin_button=Бұл сайтты бекітуден алып тастау edit_topsites_edit_button=Бұл сайтты түзету edit_topsites_dismiss_button=Бұл сайтты тайдыру +edit_topsites_add_button=Қосу + +# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal. +topsites_form_add_header=Жаңа топ сайты +topsites_form_edit_header=Топ сайтын түзету +topsites_form_title_placeholder=Атауын енгізіңіз +topsites_form_url_placeholder=Сілтемені теріңіз немесе кірістіріңіз +topsites_form_add_button=Қосу +topsites_form_save_button=Сақтау +topsites_form_cancel_button=Бас тарту +topsites_form_url_validation=Жарамды сілтеме керек + +# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the +# trending stories section and precedes a list of links to popular topics. +pocket_read_more=Әйгілі тақырыптар: +# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the +# end of the list of popular topic links. +pocket_read_even_more=Көбірек хикаяларды қарау +# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction +# to Pocket as part of the feedback form. +pocket_feedback_header=Интернеттің ең жақсысы, 25 миллион адаммен танылған. +# LOCALIZATION NOTE (pocket_feedback_body): This is shown below +# (pocket_feedback_header) to provide more information about Pocket. +pocket_feedback_body=Pocket, Mozilla құрамындағы өнім, сізге әдетте табылмауы мүмкін құрамаға байланысуға көмектеседі. +pocket_send_feedback=Кері байланыс хабарламасын жіберу diff --git a/locales/ko/strings.properties b/locales/ko/strings.properties index 2a889f2b2c..1765f60c8d 100644 --- a/locales/ko/strings.properties +++ b/locales/ko/strings.properties @@ -3,6 +3,10 @@ default_label_loading=읽는 중… header_top_sites=상위 사이트 header_highlights=하이라이트 +header_stories=상위 이야기 +# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the +# corresponding content (stories) provider +header_stories_from=출처 # LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give # context on how the element is related to the user, e.g. type indicates that @@ -10,6 +14,7 @@ header_highlights=하이라이트 type_label_visited=방문한 사이트 type_label_bookmarked=즐겨찾기 type_label_synced=다른 기기에서 동기화 +type_label_recommended=트랜드 # LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open" type_label_open=열기 type_label_topic=주제 @@ -26,6 +31,7 @@ menu_action_open_new_window=새 창에서 열기 menu_action_open_private_window=새 사생활 보호 창에서 열기 menu_action_dismiss=닫기 menu_action_delete=방문 기록에서 삭제 +menu_action_save_to_pocket=Pocket에 저장 # LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder # for what the user has typed in the search input field, e.g. 'Search for ' + @@ -71,6 +77,8 @@ settings_pane_topsites_body=가장 많이 방문한 웹 사이트에 접근하 settings_pane_topsites_options_showmore=두 줄로 보기 settings_pane_highlights_header=하이라이트 settings_pane_highlights_body=최근 방문 기록과 북마크를 살펴보세요. +settings_pane_pocketstories_header=상위 이야기 +settings_pane_pocketstories_body=Mozilla 가족의 일원인 Pocket으로 다른 곳에서는 찾아보기 힘든 고 품질의 콘텐츠를 연결할 수 있습니다. settings_pane_done_button=완료 # LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal @@ -81,5 +89,31 @@ edit_topsites_showmore_button=더보기 edit_topsites_showless_button=줄이기 edit_topsites_done_button=완료 edit_topsites_pin_button=이 사이트 고정 +edit_topsites_unpin_button=이 사이트 고정 취소 edit_topsites_edit_button=이 사이트 수정 edit_topsites_dismiss_button=이 사이트 제거 +edit_topsites_add_button=추가 + +# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal. +topsites_form_add_header=새로운 인기 사이트 +topsites_form_edit_header=인기 사이트 편집 +topsites_form_title_placeholder=제목 입력 +topsites_form_url_placeholder=URL 입력 또는 붙여 넣기 +topsites_form_add_button=추가 +topsites_form_save_button=저장 +topsites_form_cancel_button=취소 +topsites_form_url_validation=유효한 URL이 필요합니다 + +# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the +# trending stories section and precedes a list of links to popular topics. +pocket_read_more=인기 주제: +# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the +# end of the list of popular topic links. +pocket_read_even_more=더 많은 이야기 보기 +# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction +# to Pocket as part of the feedback form. +pocket_feedback_header=2천 5백만 명에 의해 추천되는 최고의 웹입니다. +# LOCALIZATION NOTE (pocket_feedback_body): This is shown below +# (pocket_feedback_header) to provide more information about Pocket. +pocket_feedback_body=Mozilla 가족의 일원인 Pocket으로 다른 곳에서는 찾아보기 힘든 고 품질의 콘텐츠를 연결할 수 있습니다. +pocket_send_feedback=의견 보내기 diff --git a/locales/lt/strings.properties b/locales/lt/strings.properties index b5a5a1b2bd..47f7ad71a4 100644 --- a/locales/lt/strings.properties +++ b/locales/lt/strings.properties @@ -2,7 +2,16 @@ newtab_page_title=Nauja kortelė default_label_loading=Įkeliama… header_top_sites=Lankomiausios svetainės -header_highlights=Akcentai +header_stories=Populiariausi straipsniai +header_visit_again=Aplankykite vėl +header_bookmarks=Paskiausi adresyno įrašai +# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is +# meant to inform that section contains no information because +# the user hasn't added any bookmarks. +header_bookmarks_placeholder=Jūs dar neturite adresyno įrašų. +# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the +# corresponding content (stories) provider +header_stories_from=iš # LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give # context on how the element is related to the user, e.g. type indicates that @@ -10,6 +19,7 @@ header_highlights=Akcentai type_label_visited=Aplankyti type_label_bookmarked=Adresyne type_label_synced=Sinchronizuoti iš kito įrenginio +type_label_recommended=Populiaru # LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open" type_label_open=Atviri type_label_topic=Tema @@ -26,6 +36,14 @@ menu_action_open_new_window=Atverti naujame lange menu_action_open_private_window=Atverti naujame privačiajame lange menu_action_dismiss=Paslėpti menu_action_delete=Pašalinti iš istorijos +menu_action_pin=Įsegti +menu_action_unpin=Išsegti +confirm_history_delete_p1=Ar tikrai norite pašalinti visus šio tinklalapio įrašus iš savo naršymo žurnalo? +# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in +# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a +# page from history. +confirm_history_delete_notice_p2=Atlikus šį veiksmą, jo atšaukti neįmanoma. +menu_action_save_to_pocket=Įrašyti į „Pocket“ # LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder # for what the user has typed in the search input field, e.g. 'Search for ' + @@ -69,8 +87,12 @@ settings_pane_search_body=Ieškokite saityne tiesiai iš naujos kortelės. settings_pane_topsites_header=Lankomiausios svetainės settings_pane_topsites_body=Pasiekite jūsų dažniausiai lankomas svetaines. settings_pane_topsites_options_showmore=Rodyti dvi eilutes -settings_pane_highlights_header=Akcentai -settings_pane_highlights_body=Pažvelkite į savo naujausią naršymo istoriją bei paskiausiai pridėtus adresyno įrašus. +settings_pane_bookmarks_header=Paskiausi adresyno įrašai +settings_pane_bookmarks_body=Jūsų naujai sukurti adresyno įrašai vienoje vietoje. +settings_pane_visit_again_header=Aplankykite vėl +settings_pane_visit_again_body=„Firefox“ pateiks ištraukas iš jūsų naršymo žurnalo, kurias galbūt norėtumėte prisiminti. +settings_pane_pocketstories_header=Populiariausi straipsniai +settings_pane_pocketstories_body=„Pocket“, „Mozillos“ šeimos dalis, padės jums atrasti kokybišką turinį, kurio kitaip gal nebūtumėte radę. settings_pane_done_button=Atlikta # LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal @@ -81,5 +103,31 @@ edit_topsites_showmore_button=Rodyti daugiau edit_topsites_showless_button=Rodyti mažiau edit_topsites_done_button=Atlikta edit_topsites_pin_button=Įsegti šią svetainę +edit_topsites_unpin_button=Išsegti šią svetainę edit_topsites_edit_button=Redaguoti šią svetainę edit_topsites_dismiss_button=Paslėpti šią svetainę +edit_topsites_add_button=Pridėti + +# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal. +topsites_form_add_header=Nauja mėgstama svetainė +topsites_form_edit_header=Redaguoti mėgstamą svetainę +topsites_form_title_placeholder=Įveskite pavadinimą +topsites_form_url_placeholder=Įveskite arba įklijuokite URL +topsites_form_add_button=Pridėti +topsites_form_save_button=Įrašyti +topsites_form_cancel_button=Atsisakyti +topsites_form_url_validation=Reikalingas tinkamas URL + +# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the +# trending stories section and precedes a list of links to popular topics. +pocket_read_more=Populiarios temos: +# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the +# end of the list of popular topic links. +pocket_read_even_more=Rodyti daugiau straipsnių +# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction +# to Pocket as part of the feedback form. +pocket_feedback_header=Geriausi dalykai internete, kuruojami daugiau nei 25 milijonų žmonių. +# LOCALIZATION NOTE (pocket_feedback_body): This is shown below +# (pocket_feedback_header) to provide more information about Pocket. +pocket_feedback_body=„Pocket“, „Mozillos“ šeimos dalis, padės jums atrasti kokybišką turinį, kurio kitaip gal nebūtumėte radę. +pocket_send_feedback=Siųsti atsiliepimą diff --git a/locales/ml/strings.properties b/locales/ml/strings.properties index 036ca74052..e55a2fb59c 100644 --- a/locales/ml/strings.properties +++ b/locales/ml/strings.properties @@ -1,37 +1,119 @@ +newtab_page_title=പുതിയ ടാബ് +default_label_loading=ലോഡ്ചെയ്യുന്നു… +header_top_sites=മികച്ച സൈറ്റുകൾ +header_highlights=ഹൈലൈറ്റുകൾ +header_stories=മികച്ച ലേഖനങ്ങൾ +# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the +# corresponding content (stories) provider +header_stories_from=എവിടെ നിന്നും # LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give # context on how the element is related to the user, e.g. type indicates that # the page is bookmarked, or is currently open on another device +type_label_visited=സന്ദർശിച്ചത്‌ +type_label_bookmarked=അടയാളപ്പെടുത്തിയത് +type_label_synced=മറ്റു ഉപകരണങ്ങളുമായി സാമ്യപ്പെടുക +type_label_recommended=ട്രെൻഡിംഗ് # LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open" +type_label_open=തുറക്കുക +type_label_topic=വിഷയം # LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context # menu and are meant as a call to action for a given page. # LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to # bookmarks" +menu_action_bookmark=അടയാളം +menu_action_remove_bookmark=അടയാളം മാറ്റുക +menu_action_copy_address=വിലാസം പകർത്തുക +menu_action_email_link=ഇമെയിൽ വിലാസം… +menu_action_open_new_window=പുതിയ ജാലകത്തിൽ തുറക്കുക +menu_action_open_private_window=പുതിയ രസഹ്യജാലകത്തിൽ തുറക്കുക +menu_action_dismiss=പുറത്താക്കുക +menu_action_delete=ചരിത്രത്തിൽ നിന്ന് ഒഴിവാക്കുക +menu_action_save_to_pocket=പോക്കറ്റിലേയ്ക്ക് സംരക്ഷിയ്ക്കുക # LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder # for what the user has typed in the search input field, e.g. 'Search for ' + # search_term + 'with:' becomes 'Search for abc with:' # The search engine name is displayed as an icon and does not need a translation +search_for_something_with=തിരയാൻ {search_term} : എന്നത് ഉപയോഗിയ്ക്കുക # LOCALIZATION NOTE (search_button): This is screenreader only text for the # search button. +search_button=തിരയുക # LOCALIZATION NOTE (search_header): Displayed at the top of the panel # showing search suggestions. {search_engine_name} is replaced with the name of # the current default search engine. e.g. 'Google Search' +search_header={search_engine_name} തിരയുക # LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when # the user hasn't typed anything yet. +search_web_placeholder=ഇൻറർനെറ്റിൽ തിരയുക +search_settings=തിരയാനുള്ള രീതികൾ മാറ്റുക # LOCALIZATION NOTE (welcome_*): This is shown as a modal dialog, typically on a # first-run experience when there's no data to display yet +welcome_title=പുതിയ ജാലകത്തിലേക്കു സ്വാഗതം +welcome_body=നിങ്ങളുടെ ഏറ്റവും ശ്രദ്ധേയമായ അടയാളങ്ങൾ, ലേഖനങ്ങൾ, വീഡിയോകൾ, കൂടാതെ നിങ്ങൾ സമീപകാലത്ത് സന്ദർശിച്ച താളുകൾ എന്നിവ കാണിക്കുന്നതിനായി ഫയർഫോക്സ് ഈ ഇടം ഉപയോഗിക്കും, അതിനാൽ നിങ്ങൾക്ക് എളുപ്പത്തിൽ അവയിലേക്ക് തിരിച്ചു പോകാം. +welcome_label=താങ്കളുടെ ഹൈലൈറ്റ്സ് തിരിച്ചറിയുന്നു # LOCALIZATION NOTE (time_label_*): {number} is a placeholder for a number which # represents a shortened timestamp format, e.g. '10m' means '10 minutes ago'. +time_label_less_than_minute=<1 മിനിറ്റ് +time_label_minute={number} മിനിറ്റ് +time_label_hour={number} മിനിറ്റ് +time_label_day={number} മിനിറ്റ് # LOCALIZATION NOTE (settings_pane_*): This is shown in the Settings Pane sidebar. +settings_pane_button_label=നിങ്ങളുടെ പുതിയ ടാബ് താള് ഇഷ്ടാനുസൃതമാക്കുക +settings_pane_header=പുതിയ ടാബിന്റെ മുൻഗണനകൾ +settings_pane_body=പുതിയ ടാബ് തുറക്കുമ്പോൾ എന്ത് കാണണമെന്ന് തീരുമാനിക്കുക. +settings_pane_search_header=തിരയുക +settings_pane_search_body=പുതിയ ടാബിൽ നിന്ന് ഇന്റർനെറ്റിൽ തിരയുക. +settings_pane_topsites_header=മുന്നേറിയ സൈറ്റുകൾ +settings_pane_topsites_body=നിങ്ങൾ കൂടുതൽ സന്ദർശിക്കുന്ന വെബ്‌സൈറ്റുകളിൽ പ്രവേശിക്കുക. +settings_pane_topsites_options_showmore=രണ്ടു വരികൾ കാണിയ്ക്കുക +settings_pane_highlights_header=ഹൈലൈറ്റുകൾ +settings_pane_highlights_body=നിങ്ങളുടെ സമീപകാല ബ്രൗസിംഗ് ചരിത്രവും പുതുതായി സൃഷ്ടിച്ച അടയാളങ്ങളും കാണുക. +settings_pane_pocketstories_header=മികച്ച ലേഖനങ്ങൾ +settings_pane_pocketstories_body=മോസില്ല‌ കുടുംബാംഗമായ പോക്കറ്റ്, വിട്ടുപോയേയ്ക്കാവുന്ന മികച്ച ലേഖനങ്ങൾ നിങ്ങളുടെ ശ്രദ്ധയിൽ എത്തിയ്ക്കുന്നു. +settings_pane_done_button=തീർന്നു # LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal # dialog. +edit_topsites_button_text=തിരുത്തുക +edit_topsites_button_label=നിങ്ങളുടെ മുന്നേറിയ സൈറ്റുകളുടെ വിഭാഗം ഇഷ്ടാനുസൃതമാക്കുക +edit_topsites_showmore_button=കൂടുതൽ കാണിക്കുക +edit_topsites_showless_button=കുറച്ച് കാണിക്കുക +edit_topsites_done_button=തീർന്നു +edit_topsites_pin_button=ഈ സൈറ്റ് പിൻ ചെയ്യുക +edit_topsites_unpin_button=ഈ സൈറ്റ് അണ്‍പിന്‍ ചെയ്യുക +edit_topsites_edit_button=ഈ സൈറ്റ് തിരുത്തുക +edit_topsites_dismiss_button=ഈ സൈറ്റ് പുറത്താക്കുക +edit_topsites_add_button=ചേര്‍ക്കുക + +# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal. +topsites_form_add_header=പുതിയ മികച്ച സൈറ്റുകൾ +topsites_form_edit_header=മികച്ച സൈറ്റ് ലിസ്റ്റ് തിരുത്തൂ +topsites_form_title_placeholder=തലക്കെട്ട് നൽകൂ +topsites_form_url_placeholder=വെബ്URLനൽകൂ +topsites_form_add_button=ചേർക്കൂ +topsites_form_save_button=സംരക്ഷിയ്ക്കൂ +topsites_form_cancel_button=ഒഴിവാക്കൂ +topsites_form_url_validation=പ്രവർത്തിയ്ക്കുന്ന URL ആവശ്യമാണ് + +# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the +# trending stories section and precedes a list of links to popular topics. +pocket_read_more=ജനപ്രിയ വിഷയങ്ങൾ: +# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the +# end of the list of popular topic links. +pocket_read_even_more=കൂടുതൽ ലേഖനങ്ങൾ കാണുക +# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction +# to Pocket as part of the feedback form. +pocket_feedback_header=250 ലക്ഷം പേരാൽ തെരഞ്ഞെടുക്കപ്പെട്ട വെബിലെ ഏറ്റവും മികച്ചവയാണിവ. +# LOCALIZATION NOTE (pocket_feedback_body): This is shown below +# (pocket_feedback_header) to provide more information about Pocket. +pocket_feedback_body=മോസില്ല‌ കുടുംബാംഗമായ പോക്കറ്റ്, വിട്ടുപോയേയ്ക്കാവുന്ന മികച്ച ലേഖനങ്ങൾ നിങ്ങളുടെ ശ്രദ്ധയിൽ എത്തിയ്ക്കുന്നു. +pocket_send_feedback=പ്രതികരണം അയയ്ക്കുക diff --git a/locales/mr/strings.properties b/locales/mr/strings.properties index 036ca74052..b3fb7edd4e 100644 --- a/locales/mr/strings.properties +++ b/locales/mr/strings.properties @@ -1,37 +1,85 @@ +newtab_page_title=नवीन टॅब +default_label_loading=दाखल करीत आहे… +header_top_sites=खास साईट्स +header_highlights=ठळक +header_stories=महत्वाच्या गोष्टी +# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the +# corresponding content (stories) provider +header_stories_from=कडून # LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give # context on how the element is related to the user, e.g. type indicates that # the page is bookmarked, or is currently open on another device +type_label_visited=भेट दिलेले +type_label_bookmarked=वाचनखुण लावले +type_label_synced=इतर साधनावरुन ताळमेळ केले # LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open" +type_label_open=उघडा +type_label_topic=विषय # LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context # menu and are meant as a call to action for a given page. # LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to # bookmarks" +menu_action_bookmark=वाचनखुण +menu_action_remove_bookmark=वाचनखुण काढा +menu_action_copy_address=पत्त्याची प्रत बनवा +menu_action_email_link=दुवा इमेल करा… +menu_action_open_new_window=नवीन पटलात उघडा +menu_action_open_private_window=नवीन खाजगी पटलात उघडा +menu_action_dismiss=रद्द करा +menu_action_delete=इतिहासातून नष्ट करा +menu_action_save_to_pocket=Pocket मध्ये जतन करा # LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder # for what the user has typed in the search input field, e.g. 'Search for ' + # search_term + 'with:' becomes 'Search for abc with:' # The search engine name is displayed as an icon and does not need a translation +search_for_something_with=शोधा {search_term} सोबत: # LOCALIZATION NOTE (search_button): This is screenreader only text for the # search button. +search_button=शोधा # LOCALIZATION NOTE (search_header): Displayed at the top of the panel # showing search suggestions. {search_engine_name} is replaced with the name of # the current default search engine. e.g. 'Google Search' +search_header={search_engine_name} शोध # LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when # the user hasn't typed anything yet. +search_web_placeholder=वेबवर शोधा +search_settings=शोध सेटिंग बदला # LOCALIZATION NOTE (welcome_*): This is shown as a modal dialog, typically on a # first-run experience when there's no data to display yet +welcome_title=नवीन टॅबवर स्वागत आहे # LOCALIZATION NOTE (time_label_*): {number} is a placeholder for a number which # represents a shortened timestamp format, e.g. '10m' means '10 minutes ago'. +time_label_less_than_minute=<1मि +time_label_minute={number}मि +time_label_hour={number}ता +time_label_day={number}दि # LOCALIZATION NOTE (settings_pane_*): This is shown in the Settings Pane sidebar. +settings_pane_button_label=आपले नवीन टॅब पृष्ठ सानुकूलित करा +settings_pane_header=नवीन टॅब प्राधान्ये +settings_pane_body=नवीन टॅब उघडल्यानंतर काय दिसायला हवे ते निवडा. +settings_pane_search_header=शोध +settings_pane_search_body=आपल्या नवीन टॅब वरून वेबवर शोधा. # LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal # dialog. + +# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal. + +# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the +# trending stories section and precedes a list of links to popular topics. +# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the +# end of the list of popular topic links. +# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction +# to Pocket as part of the feedback form. +# LOCALIZATION NOTE (pocket_feedback_body): This is shown below +# (pocket_feedback_header) to provide more information about Pocket. diff --git a/locales/ms/strings.properties b/locales/ms/strings.properties index cea168ac26..ef9dd75225 100644 --- a/locales/ms/strings.properties +++ b/locales/ms/strings.properties @@ -2,7 +2,19 @@ newtab_page_title=Tab Baru default_label_loading=Memuatkan… header_top_sites=Laman Teratas -header_highlights=Serlahan +header_stories=Berita Hangat +header_visit_again=Lawat Semula +header_bookmarks=Tandabuku Terkini +# LOCALIZATION NOTE(header_recommended_by): This is followed by the name +# of the corresponding content provider. +header_recommended_by=Disyorkan oleh {provider} +# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is +# meant to inform that section contains no information because +# the user hasn't added any bookmarks. +header_bookmarks_placeholder=Anda masih belum ada tandabuku lagi. +# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the +# corresponding content (stories) provider +header_stories_from=dari # LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give # context on how the element is related to the user, e.g. type indicates that @@ -10,9 +22,11 @@ header_highlights=Serlahan type_label_visited=Dilawati type_label_bookmarked=Ditandabuku type_label_synced=Sync dari peranti lain +type_label_recommended=Trending # LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open" type_label_open=Buka type_label_topic=Topik +type_label_now=Sekarang # LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context # menu and are meant as a call to action for a given page. @@ -26,6 +40,14 @@ menu_action_open_new_window=Buka dalam Tetingkap Baru menu_action_open_private_window=Buka dalam Tetingkap Peribadi Baru menu_action_dismiss=Abai menu_action_delete=Hapuskan sejarah +menu_action_pin=Pin +menu_action_unpin=Nyahpin +confirm_history_delete_p1=Anda pasti mahu menghapuskan setiap contoh halaman ini daripada sejarah anda? +# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in +# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a +# page from history. +confirm_history_delete_notice_p2=Tindakan ini tidak boleh dibatalkan. +menu_action_save_to_pocket=Simpan ke Pocket # LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder # for what the user has typed in the search input field, e.g. 'Search for ' + @@ -47,6 +69,10 @@ search_header={search_engine_name} Cari search_web_placeholder=Cari dalam Web search_settings=Ubah Tetapan Carian +# LOCALIZATION NOTE (section_info_option): This is the screenreader text for the +# (?) icon that would show a section's description with optional feedback link. +section_info_option=Info + # LOCALIZATION NOTE (welcome_*): This is shown as a modal dialog, typically on a # first-run experience when there's no data to display yet welcome_title=Selamat Datang ke tab baru @@ -69,8 +95,12 @@ settings_pane_search_body=Carian Web dari tab baru anda. settings_pane_topsites_header=Laman Teratas settings_pane_topsites_body=Akses laman web yang paling banyak dilawati. settings_pane_topsites_options_showmore=Papar dua baris -settings_pane_highlights_header=Serlahan -settings_pane_highlights_body=Papar semula sejarah pelayaran terkini dan tandabuku yang baru diwujudkan. +settings_pane_bookmarks_header=Tandabuku Terkini +settings_pane_bookmarks_body=Tandabuku baru yang anda cipta terletak di lokasi yang mudah dicapai. +settings_pane_visit_again_header=Lawat Semula +settings_pane_visit_again_body=Firefox akan mempamerkan kepada anda sebahagian sejarah pelayaran anda yang mungkin anda mahu mengingatinya atau kembali semula. +settings_pane_pocketstories_header=Berita Hangat +settings_pane_pocketstories_body=Pocket, sebahagian daripada ciri-ciri Mozilla, akan membantu anda sentiasa berhubung dengan kandungan berkualiti tinggi yang mungkin tidak akan anda jumpa sebaliknya. settings_pane_done_button=Siap # LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal @@ -81,5 +111,46 @@ edit_topsites_showmore_button=Papar selanjutnya edit_topsites_showless_button=Papar minima edit_topsites_done_button=Siap edit_topsites_pin_button=Pin laman ini +edit_topsites_unpin_button=Nyahpin laman ini edit_topsites_edit_button=Edit laman ini edit_topsites_dismiss_button=Buang laman ini +edit_topsites_add_button=Tambah + +# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal. +topsites_form_add_header=Laman Teratas Baru +topsites_form_edit_header=Edit Laman Teratas +topsites_form_title_placeholder=Masukkan tajuk +topsites_form_url_placeholder=Taip atau tampal URL +topsites_form_add_button=Tambah +topsites_form_save_button=Simpan +topsites_form_cancel_button=Batal +topsites_form_url_validation=Perlukan URL yang sah + +# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the +# trending stories section and precedes a list of links to popular topics. +pocket_read_more=Topik Popular: +# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the +# end of the list of popular topic links. +pocket_read_even_more=Papar Kisah Selanjutnya +# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction +# to Pocket as part of the feedback form. +pocket_feedback_header=Terbaik daripada web, disokong oleh lebih 25 juta pengguna. +# LOCALIZATION NOTE (pocket_feedback_body): This is shown below +# (pocket_feedback_header) to provide more information about Pocket. +pocket_feedback_body=Pocket, sebahagian daripada ciri Mozilla, akan membantu anda sentiasa berhubung dengan kandungan berkualiti tinggi yang mungkin tidak akan anda jumpa tanpanya. +pocket_send_feedback=Hantar Maklum balas + +# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations, +# in the space that would have shown a few stories, this is shown instead. +# {provider} is replaced by the name of the content provider for this section. +topstories_empty_state=Anda sudah di sini. Tapi sila datang lagi untuk mendapatkan lebih banyak berita hangat daripada {provider}. Tidak boleh tunggu? Pilih topik untuk mendapatkannya dari serata dunia. + +# LOCALIZATION NOTE (manual_migration_explanation): This message is shown to encourage users to +# import their browser profile from another browser they might be using. +manual_migration_explanation=Cuba Firefox dengan laman kegemaran dan tandabuku anda daripada pelayar lain. +# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the +# process of importing another browser’s profile into Firefox. +manual_migration_cancel_button=Tidak, Terima kasih +# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process +# of importing another browser’s profile profile into Firefox. +manual_migration_import_button=Import Sekarang diff --git a/locales/nb-NO/strings.properties b/locales/nb-NO/strings.properties index c1a921283e..a3f645f6fb 100644 --- a/locales/nb-NO/strings.properties +++ b/locales/nb-NO/strings.properties @@ -2,7 +2,19 @@ newtab_page_title=Ny fane default_label_loading=Laster … header_top_sites=Mest besøkte nettsider -header_highlights=Høydepunkter +header_stories=Hovedsakene +header_visit_again=Besøk igjen +header_bookmarks=Nylige bokmerker +# LOCALIZATION NOTE(header_recommended_by): This is followed by the name +# of the corresponding content provider. +header_recommended_by=Anbefalt av {provider} +# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is +# meant to inform that section contains no information because +# the user hasn't added any bookmarks. +header_bookmarks_placeholder=Du har ingen bokmerker enda. +# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the +# corresponding content (stories) provider +header_stories_from=fra # LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give # context on how the element is related to the user, e.g. type indicates that @@ -10,9 +22,11 @@ header_highlights=Høydepunkter type_label_visited=Besøkt type_label_bookmarked=Bokmerket type_label_synced=Synkronisert fra annen enhet +type_label_recommended=Trender # LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open" type_label_open=Åpne type_label_topic=Emne +type_label_now=Nå # LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context # menu and are meant as a call to action for a given page. @@ -26,6 +40,14 @@ menu_action_open_new_window=Åpne i nytt vindu menu_action_open_private_window=Åpne i nytt privat vindu menu_action_dismiss=Avslå menu_action_delete=Slett fra historikk +menu_action_pin=Fest +menu_action_unpin=Løsne +confirm_history_delete_p1=Er du sikker på at du vil slette alle forekomster av denne siden fra historikken? +# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in +# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a +# page from history. +confirm_history_delete_notice_p2=Denne handlingen kan ikke angres. +menu_action_save_to_pocket=Lagre til Pocket # LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder # for what the user has typed in the search input field, e.g. 'Search for ' + @@ -47,6 +69,10 @@ search_header={search_engine_name}-søk search_web_placeholder=Søk på nettet search_settings=Endre søkeinnstillinger +# LOCALIZATION NOTE (section_info_option): This is the screenreader text for the +# (?) icon that would show a section's description with optional feedback link. +section_info_option=Informasjon + # LOCALIZATION NOTE (welcome_*): This is shown as a modal dialog, typically on a # first-run experience when there's no data to display yet welcome_title=Velkommen til ny fane @@ -69,8 +95,12 @@ settings_pane_search_body=Søk på nettet fra din nye fane. settings_pane_topsites_header=Mest besøkte settings_pane_topsites_body=Tilgang til nettsidene du besøker mest. settings_pane_topsites_options_showmore=Vis to rader -settings_pane_highlights_header=Høydepunkter -settings_pane_highlights_body=Se tilbake på din siste nettleserhistorikk og nyopprettede bokmerker. +settings_pane_bookmarks_header=Nylige bokmerker +settings_pane_bookmarks_body=De nyeste bokmerkene dine på en plass. +settings_pane_visit_again_header=Besøk igjen +settings_pane_visit_again_body=Firefox viser deg deler av din surfehistorikk som du kanskje ønsker å huske eller komme tilbake til. +settings_pane_pocketstories_header=Hovedsakene +settings_pane_pocketstories_body=Pocket, en del av Mozilla-familien, vil hjelpe deg med å finne innhold av høy kvalitet, som du kanskje ikke ville ha funnet ellers. settings_pane_done_button=Ferdig # LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal @@ -81,5 +111,46 @@ edit_topsites_showmore_button=Vis mer edit_topsites_showless_button=Vis mindre edit_topsites_done_button=Ferdig edit_topsites_pin_button=Fest nettsiden +edit_topsites_unpin_button=Frigjør denne nettsiden edit_topsites_edit_button=Rediger denne nettsiden edit_topsites_dismiss_button=Avvis denne nettsiden +edit_topsites_add_button=Legg til + +# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal. +topsites_form_add_header=Nytt toppsted +topsites_form_edit_header=Rediger toppsted +topsites_form_title_placeholder=Oppgi en tittel +topsites_form_url_placeholder=Skriv eller lim inn en URL +topsites_form_add_button=Legg til +topsites_form_save_button=Lagre +topsites_form_cancel_button=Avbryt +topsites_form_url_validation=Gyldig URL er nødvendig + +# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the +# trending stories section and precedes a list of links to popular topics. +pocket_read_more=Populære emner: +# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the +# end of the list of popular topic links. +pocket_read_even_more=Vis flere saker +# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction +# to Pocket as part of the feedback form. +pocket_feedback_header=Det beste av nettet, kurert av over 25 millioner mennesker. +# LOCALIZATION NOTE (pocket_feedback_body): This is shown below +# (pocket_feedback_header) to provide more information about Pocket. +pocket_feedback_body=Pocket, en del av Mozilla-familien, vil hjelpe deg med å finne innhold av høy kvalitet, som du kanskje ikke ville ha funnet ellers. +pocket_send_feedback=Send tilbakemelding + +# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations, +# in the space that would have shown a few stories, this is shown instead. +# {provider} is replaced by the name of the content provider for this section. +topstories_empty_state=Du har tatt igjen. Kom tilbake senere for flere topphistorier fra {provider}. Kan du ikke vente? Velg et populært emne for å finne flere gode artikler fra hele Internett. + +# LOCALIZATION NOTE (manual_migration_explanation): This message is shown to encourage users to +# import their browser profile from another browser they might be using. +manual_migration_explanation=Prøv Firefox med dine favorittnettsteder og bokmerker fra en annen nettleser. +# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the +# process of importing another browser’s profile into Firefox. +manual_migration_cancel_button=Nei takk +# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process +# of importing another browser’s profile profile into Firefox. +manual_migration_import_button=Importer nå diff --git a/locales/nl/strings.properties b/locales/nl/strings.properties index 9d1599e199..f621d30b30 100644 --- a/locales/nl/strings.properties +++ b/locales/nl/strings.properties @@ -2,7 +2,19 @@ newtab_page_title=Nieuw tabblad default_label_loading=Laden… header_top_sites=Topwebsites -header_highlights=Highlights +header_stories=Topverhalen +header_visit_again=Nogmaals bezoeken +header_bookmarks=Recente bladwijzers +# LOCALIZATION NOTE(header_recommended_by): This is followed by the name +# of the corresponding content provider. +header_recommended_by=Aanbevolen door {provider} +# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is +# meant to inform that section contains no information because +# the user hasn't added any bookmarks. +header_bookmarks_placeholder=U hebt nog geen bladwijzers. +# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the +# corresponding content (stories) provider +header_stories_from=van # LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give # context on how the element is related to the user, e.g. type indicates that @@ -10,9 +22,11 @@ header_highlights=Highlights type_label_visited=Bezocht type_label_bookmarked=Bladwijzer gemaakt type_label_synced=Gesynchroniseerd vanaf ander apparaat +type_label_recommended=Trending # LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open" type_label_open=Open type_label_topic=Onderwerp +type_label_now=Nu # LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context # menu and are meant as a call to action for a given page. @@ -26,6 +40,14 @@ menu_action_open_new_window=Openen in een nieuw venster menu_action_open_private_window=Openen in een nieuw privévenster menu_action_dismiss=Verwijderen menu_action_delete=Verwijderen uit geschiedenis +menu_action_pin=Vastmaken +menu_action_unpin=Losmaken +confirm_history_delete_p1=Weet u zeker dat u alle exemplaren van deze pagina uit uw geschiedenis wilt verwijderen? +# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in +# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a +# page from history. +confirm_history_delete_notice_p2=Deze actie kan niet ongedaan worden gemaakt. +menu_action_save_to_pocket=Opslaan naar Pocket # LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder # for what the user has typed in the search input field, e.g. 'Search for ' + @@ -47,6 +69,10 @@ search_header={search_engine_name} doorzoeken search_web_placeholder=Zoeken op het web search_settings=Zoekinstellingen wijzigen +# LOCALIZATION NOTE (section_info_option): This is the screenreader text for the +# (?) icon that would show a section's description with optional feedback link. +section_info_option=Info + # LOCALIZATION NOTE (welcome_*): This is shown as a modal dialog, typically on a # first-run experience when there's no data to display yet welcome_title=Welkom bij het nieuwe tabblad @@ -63,14 +89,18 @@ time_label_day={number} d # LOCALIZATION NOTE (settings_pane_*): This is shown in the Settings Pane sidebar. settings_pane_button_label=Uw Nieuw-tabbladpagina aanpassen settings_pane_header=Nieuw-tabbladvoorkeuren -settings_pane_body=Kiezen wat u ziet bij het openen van een nieuw tabblad. +settings_pane_body=Kies wat u ziet bij het openen van een nieuw tabblad. settings_pane_search_header=Zoeken settings_pane_search_body=Het web doorzoeken vanaf uw nieuwe tabblad. settings_pane_topsites_header=Topwebsites settings_pane_topsites_body=De websites benaderen die u het vaakst bezoekt. settings_pane_topsites_options_showmore=Twee rijen tonen -settings_pane_highlights_header=Highlights -settings_pane_highlights_body=Terugkijken naar uw recente navigatiegeschiedenis en nieuw aangemaakte bladwijzers. +settings_pane_bookmarks_header=Recente bladwijzers +settings_pane_bookmarks_body=Uw nieuw aangemaakte bladwijzers op één handige plek. +settings_pane_visit_again_header=Nogmaals bezoeken +settings_pane_visit_again_body=Firefox toont delen van uw navigatiegeschiedenis die u wellicht wilt onthouden of opnieuw wilt bezoeken. +settings_pane_pocketstories_header=Topverhalen +settings_pane_pocketstories_body=Pocket, een onderdeel van de Mozilla-familie, helpt u bij het vinden van inhoud met hoge kwaliteit die u anders misschien niet had kunnen vinden. settings_pane_done_button=Gereed # LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal @@ -81,5 +111,46 @@ edit_topsites_showmore_button=Meer tonen edit_topsites_showless_button=Minder tonen edit_topsites_done_button=Gereed edit_topsites_pin_button=Deze website vastmaken +edit_topsites_unpin_button=Deze website losmaken edit_topsites_edit_button=Deze website bewerken edit_topsites_dismiss_button=Deze website verwijderen +edit_topsites_add_button=Toevoegen + +# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal. +topsites_form_add_header=Nieuwe topwebsite +topsites_form_edit_header=Topwebsite bewerken +topsites_form_title_placeholder=Voer een titel in +topsites_form_url_placeholder=Typ of plak een URL +topsites_form_add_button=Toevoegen +topsites_form_save_button=Opslaan +topsites_form_cancel_button=Annuleren +topsites_form_url_validation=Geldige URL vereist + +# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the +# trending stories section and precedes a list of links to popular topics. +pocket_read_more=Populaire onderwerpen: +# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the +# end of the list of popular topic links. +pocket_read_even_more=Meer verhalen bekijken +# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction +# to Pocket as part of the feedback form. +pocket_feedback_header=Het beste van het web, geselecteerd door meer dan 25 miljoen mensen. +# LOCALIZATION NOTE (pocket_feedback_body): This is shown below +# (pocket_feedback_header) to provide more information about Pocket. +pocket_feedback_body=Pocket, een onderdeel van de Mozilla-familie, helpt u bij het vinden van inhoud met hoge kwaliteit die u anders misschien niet had kunnen vinden. +pocket_send_feedback=Feedback verzenden + +# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations, +# in the space that would have shown a few stories, this is shown instead. +# {provider} is replaced by the name of the content provider for this section. +topstories_empty_state=U bent weer bij. Kijk later nog eens voor meer topverhalen van {provider}. Kunt u niet wachten? Selecteer een populair onderwerp voor meer geweldige verhalen van het hele web. + +# LOCALIZATION NOTE (manual_migration_explanation): This message is shown to encourage users to +# import their browser profile from another browser they might be using. +manual_migration_explanation=Probeer Firefox met uw favoriete websites en bladwijzers uit een andere browser. +# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the +# process of importing another browser’s profile into Firefox. +manual_migration_cancel_button=Nee bedankt +# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process +# of importing another browser’s profile profile into Firefox. +manual_migration_import_button=Nu importeren diff --git a/locales/nn-NO/strings.properties b/locales/nn-NO/strings.properties index 90975f3008..d9510146d1 100644 --- a/locales/nn-NO/strings.properties +++ b/locales/nn-NO/strings.properties @@ -2,7 +2,16 @@ newtab_page_title=Ny flik default_label_loading=Lastar… header_top_sites=Mest vitja -header_highlights=Høgdepunkt +header_stories=Hovudsakene +header_visit_again=Bes;kigjen +header_bookmarks=Nylege bokmerke +# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is +# meant to inform that section contains no information because +# the user hasn't added any bookmarks. +header_bookmarks_placeholder=Du har ingen bokmerke enno. +# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the +# corresponding content (stories) provider +header_stories_from=frå # LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give # context on how the element is related to the user, e.g. type indicates that @@ -10,6 +19,7 @@ header_highlights=Høgdepunkt type_label_visited=Vitja type_label_bookmarked=Bokmerkte type_label_synced=Synkronisert frå ei anna eining +type_label_recommended=Trendar # LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open" type_label_open=Opna type_label_topic=Emne @@ -26,6 +36,14 @@ menu_action_open_new_window=Opna i nytt vindauge menu_action_open_private_window=Opna i eit nytt privat vindauge menu_action_dismiss=Avslå menu_action_delete=Slett frå historikk +menu_action_pin=Fest +menu_action_unpin=L:ys +confirm_history_delete_p1=Er du sikker på at du vil slette alle førekomstar av denne sida frå historikken din? +# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in +# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a +# page from history. +confirm_history_delete_notice_p2=Denne handlinga kan ikkje angrast. +menu_action_save_to_pocket=Lagre til Pocket # LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder # for what the user has typed in the search input field, e.g. 'Search for ' + @@ -69,8 +87,12 @@ settings_pane_search_body=Søk på nettet frå den nye fana di. settings_pane_topsites_header=Mest besøkte settings_pane_topsites_body=Tilgang til nettsidene du besøker mest. settings_pane_topsites_options_showmore=Vis to rader -settings_pane_highlights_header=Høgdepunkt -settings_pane_highlights_body=Sjå tilbake på nyleg nettlesarhistorikk og nyleg oppretta bokmerke. +settings_pane_bookmarks_header=Nylege bokmerke +settings_pane_bookmarks_body=Dei nyaste bokmerka dine på ein plass. +settings_pane_visit_again_header=Besøk igjen +settings_pane_visit_again_body=Firefox viser deg delar av surfehistorikken din som du kanskje ønskjer å hugse eller kome tilbake til. +settings_pane_pocketstories_header=Hovudsakene +settings_pane_pocketstories_body=Pocket, ein del av Mozilla-familien, vil hjelpe deg med å finne innhald av høg kvalitet, som du kanskje ikkje ville ha funne elles. settings_pane_done_button=Ferdig # LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal @@ -81,5 +103,31 @@ edit_topsites_showmore_button=Vis meir edit_topsites_showless_button=Vis mindre edit_topsites_done_button=Ferdig edit_topsites_pin_button=Fest sida +edit_topsites_unpin_button=Løys frå denne nettsida edit_topsites_edit_button=Rediger denne nettsida edit_topsites_dismiss_button=Avvis denne nettsida +edit_topsites_add_button=Legg til + +# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal. +topsites_form_add_header=Ny mest vitja +topsites_form_edit_header=Rediger mest vitja +topsites_form_title_placeholder=Skriv inn ein tittel +topsites_form_url_placeholder=Skriv eller lim inn ein URL +topsites_form_add_button=Legg til +topsites_form_save_button=Lagre +topsites_form_cancel_button=Avbryt +topsites_form_url_validation=Gyldig URL er påkravd + +# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the +# trending stories section and precedes a list of links to popular topics. +pocket_read_more=Populære emne: +# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the +# end of the list of popular topic links. +pocket_read_even_more=Vis fleire saker +# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction +# to Pocket as part of the feedback form. +pocket_feedback_header=Det beste av nettet, sett saman av over 25 millioner menneske. +# LOCALIZATION NOTE (pocket_feedback_body): This is shown below +# (pocket_feedback_header) to provide more information about Pocket. +pocket_feedback_body=Pocket, ein del av Mozilla-familien, vil hjelpe deg med å finne innhald av høg kvalitet, som du kanskje ikkje ville ha funne elles. +pocket_send_feedback=Send tilbakemelding diff --git a/locales/pl/strings.properties b/locales/pl/strings.properties index f346058507..62be33e654 100644 --- a/locales/pl/strings.properties +++ b/locales/pl/strings.properties @@ -2,7 +2,19 @@ newtab_page_title=Nowa karta default_label_loading=Wczytywanie… header_top_sites=Popularne -header_highlights=Wyróżnione +header_stories=Popularne artykuły +header_visit_again=Odwiedź ponownie +header_bookmarks=Najnowsze zakładki +# LOCALIZATION NOTE(header_recommended_by): This is followed by the name +# of the corresponding content provider. +header_recommended_by=Poleca: {provider} +# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is +# meant to inform that section contains no information because +# the user hasn't added any bookmarks. +header_bookmarks_placeholder=Nie ma jeszcze żadnych zakładek. +# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the +# corresponding content (stories) provider +header_stories_from=od: # LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give # context on how the element is related to the user, e.g. type indicates that @@ -10,9 +22,11 @@ header_highlights=Wyróżnione type_label_visited=Odwiedzone type_label_bookmarked=Zakładka type_label_synced=Z innego urządzenia +type_label_recommended=Polecane # LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open" type_label_open=Otwarte type_label_topic=Temat +type_label_now=Teraz # LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context # menu and are meant as a call to action for a given page. @@ -26,6 +40,14 @@ menu_action_open_new_window=Otwórz w nowym oknie menu_action_open_private_window=Otwórz w nowym oknie prywatnym menu_action_dismiss=Odrzuć menu_action_delete=Usuń z historii +menu_action_pin=Przypnij +menu_action_unpin=Odepnij +confirm_history_delete_p1=Czy na pewno usunąć każde wystąpienie tej strony z historii? +# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in +# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a +# page from history. +confirm_history_delete_notice_p2=Nie można tego cofnąć. +menu_action_save_to_pocket=Zapisz w Pocket # LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder # for what the user has typed in the search input field, e.g. 'Search for ' + @@ -47,6 +69,10 @@ search_header=Wyszukiwanie w {search_engine_name} search_web_placeholder=Szukaj search_settings=Zmień ustawienia wyszukiwania +# LOCALIZATION NOTE (section_info_option): This is the screenreader text for the +# (?) icon that would show a section's description with optional feedback link. +section_info_option=Informacja + # LOCALIZATION NOTE (welcome_*): This is shown as a modal dialog, typically on a # first-run experience when there's no data to display yet welcome_title=Witamy w nowej karcie @@ -69,8 +95,12 @@ settings_pane_search_body=Szukaj w Internecie na nowej karcie. settings_pane_topsites_header=Popularne settings_pane_topsites_body=Otwieraj najczęściej odwiedzane strony. settings_pane_topsites_options_showmore=Dwa rzędy -settings_pane_highlights_header=Wyróżnione -settings_pane_highlights_body=Przeglądaj historię i nowo dodane zakładki. +settings_pane_bookmarks_header=Najnowsze zakładki +settings_pane_bookmarks_body=Nowo utworzone zakładki w jednym miejscu. +settings_pane_visit_again_header=Odwiedź ponownie +settings_pane_visit_again_body=Firefox pokaże strony z historii, do których warto wrócić. +settings_pane_pocketstories_header=Popularne artykuły +settings_pane_pocketstories_body=Pocket, będący częścią Mozilli, pomoże w szukaniu artykułów wysokiej jakości, aby nic Cię nie ominęło. settings_pane_done_button=Gotowe # LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal @@ -81,5 +111,46 @@ edit_topsites_showmore_button=Więcej edit_topsites_showless_button=Mniej edit_topsites_done_button=Gotowe edit_topsites_pin_button=Przypnij tę stronę +edit_topsites_unpin_button=Odepnij tę stronę edit_topsites_edit_button=Edytuj tę stronę edit_topsites_dismiss_button=Odrzuć tę stronę +edit_topsites_add_button=Dodaj + +# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal. +topsites_form_add_header=Nowa popularna strona +topsites_form_edit_header=Edytuj popularną stronę +topsites_form_title_placeholder=Wpisz tytuł +topsites_form_url_placeholder=Wpisz lub wklej adres +topsites_form_add_button=Dodaj +topsites_form_save_button=Zapisz +topsites_form_cancel_button=Anuluj +topsites_form_url_validation=Wymagany jest prawidłowy adres + +# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the +# trending stories section and precedes a list of links to popular topics. +pocket_read_more=Popularne tematy: +# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the +# end of the list of popular topic links. +pocket_read_even_more=Więcej artykułów +# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction +# to Pocket as part of the feedback form. +pocket_feedback_header=Najlepsze, co oferuje Internet, wybrane przez ponad 25 milionów osób. +# LOCALIZATION NOTE (pocket_feedback_body): This is shown below +# (pocket_feedback_header) to provide more information about Pocket. +pocket_feedback_body=Pocket, będący częścią Mozilli, pomoże w szukaniu artykułów wysokiej jakości, aby nic Cię nie ominęło. +pocket_send_feedback=Wyślij opinię + +# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations, +# in the space that would have shown a few stories, this is shown instead. +# {provider} is replaced by the name of the content provider for this section. +topstories_empty_state=To na razie wszystko. {provider} później będzie mieć więcej popularnych artykułów. Nie możesz się doczekać? Wybierz popularny temat, aby znaleźć więcej artykułów z całego Internetu. + +# LOCALIZATION NOTE (manual_migration_explanation): This message is shown to encourage users to +# import their browser profile from another browser they might be using. +manual_migration_explanation=Wypróbuj Firefoksa ze swoimi ulubionymi stronami i zakładkami z innej przeglądarki. +# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the +# process of importing another browser’s profile into Firefox. +manual_migration_cancel_button=Nie, dziękuję +# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process +# of importing another browser’s profile profile into Firefox. +manual_migration_import_button=Importuj teraz diff --git a/locales/pt-BR/strings.properties b/locales/pt-BR/strings.properties index 5cc568aab1..a263c6ae9e 100644 --- a/locales/pt-BR/strings.properties +++ b/locales/pt-BR/strings.properties @@ -2,7 +2,19 @@ newtab_page_title=Nova aba default_label_loading=Carregando… header_top_sites=Sites preferidos -header_highlights=Destaques +header_stories=Histórias populares +header_visit_again=Visitar novamente +header_bookmarks=Favoritos recentes +# LOCALIZATION NOTE(header_recommended_by): This is followed by the name +# of the corresponding content provider. +header_recommended_by=Recomendado por {provider} +# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is +# meant to inform that section contains no information because +# the user hasn't added any bookmarks. +header_bookmarks_placeholder=Você ainda não tem nenhum favorito. +# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the +# corresponding content (stories) provider +header_stories_from=de # LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give # context on how the element is related to the user, e.g. type indicates that @@ -10,9 +22,11 @@ header_highlights=Destaques type_label_visited=Visitado type_label_bookmarked=Adicionado aos favoritos type_label_synced=Sincronizado a partir de outro dispositivo +type_label_recommended=Tendência # LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open" -type_label_open=Abrir +type_label_open=Abertas type_label_topic=Tópico +type_label_now=Agora # LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context # menu and are meant as a call to action for a given page. @@ -26,6 +40,14 @@ menu_action_open_new_window=Abrir em uma nova janela menu_action_open_private_window=Abrir em uma nova janela privativa menu_action_dismiss=Dispensar menu_action_delete=Excluir do histórico +menu_action_pin=Fixar +menu_action_unpin=Desafixar +confirm_history_delete_p1=Você tem certeza que deseja deletar todas as ocorrências dessa página do seu histórico? +# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in +# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a +# page from history. +confirm_history_delete_notice_p2=Essa ação não pode ser desfeita. +menu_action_save_to_pocket=Salvar no Pocket # LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder # for what the user has typed in the search input field, e.g. 'Search for ' + @@ -47,6 +69,10 @@ search_header=Pesquisa {search_engine_name} search_web_placeholder=Pesquisar na Web search_settings=Alterar configurações de pesquisa +# LOCALIZATION NOTE (section_info_option): This is the screenreader text for the +# (?) icon that would show a section's description with optional feedback link. +section_info_option=Info + # LOCALIZATION NOTE (welcome_*): This is shown as a modal dialog, typically on a # first-run experience when there's no data to display yet welcome_title=Bem-vindo a nova aba @@ -69,9 +95,13 @@ settings_pane_search_body=Pesquise na Web a partir da sua nova aba. settings_pane_topsites_header=Sites preferidos settings_pane_topsites_body=Acesse os sites que você mais visita. settings_pane_topsites_options_showmore=Mostrar duas linhas -settings_pane_highlights_header=Destaques -settings_pane_highlights_body=Veja o seu histórico de navegação recente e favoritos recentemente criados. -settings_pane_done_button=Concluir +settings_pane_bookmarks_header=Favoritos recentes +settings_pane_bookmarks_body=Seus favoritos recém criados em uma posição acessível. +settings_pane_visit_again_header=Visite novamente +settings_pane_visit_again_body=Firefox irá exibir a você partes do seu histórico de navegação que você pode querer relembrar ou acessar novamente. +settings_pane_pocketstories_header=Histórias populares +settings_pane_pocketstories_body=O Pocket, parte da família Mozilla, irá ajudar a conecta-se a conteúdo de alta qualidade que talvez não tenha encontrado de outra forma. +settings_pane_done_button=Concluído # LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal # dialog. @@ -79,7 +109,48 @@ edit_topsites_button_text=Editar edit_topsites_button_label=Personalizar a sua seção de sites preferidos edit_topsites_showmore_button=Mostrar mais edit_topsites_showless_button=Mostrar menos -edit_topsites_done_button=Concluir +edit_topsites_done_button=Concluído edit_topsites_pin_button=Fixar este site +edit_topsites_unpin_button=Desafixar este site edit_topsites_edit_button=Editar este site edit_topsites_dismiss_button=Descartar este site +edit_topsites_add_button=Adicionar + +# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal. +topsites_form_add_header=Novo site popular +topsites_form_edit_header=Editar site popular +topsites_form_title_placeholder=Digite um título +topsites_form_url_placeholder=Digite ou cole um URL +topsites_form_add_button=Adicionar +topsites_form_save_button=Salvar +topsites_form_cancel_button=Cancelar +topsites_form_url_validation=É necessário uma URL válida + +# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the +# trending stories section and precedes a list of links to popular topics. +pocket_read_more=Tópicos populares: +# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the +# end of the list of popular topic links. +pocket_read_even_more=Ver mais histórias +# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction +# to Pocket as part of the feedback form. +pocket_feedback_header=O melhor da web, com curadoria de mais de 25 milhões de pessoas. +# LOCALIZATION NOTE (pocket_feedback_body): This is shown below +# (pocket_feedback_header) to provide more information about Pocket. +pocket_feedback_body=O Pocket, parte da família Mozilla, irá ajudar a conecta-se a conteúdo de alta qualidade que talvez não tenha encontrado de outra forma. +pocket_send_feedback=Enviar feedback + +# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations, +# in the space that would have shown a few stories, this is shown instead. +# {provider} is replaced by the name of the content provider for this section. +topstories_empty_state=Você já viu tudo. Volte mais tarde para mais histórias do {provider}. Não consegue esperar? Escolha um assunto popular para encontrar mais grandes histórias através da web. + +# LOCALIZATION NOTE (manual_migration_explanation): This message is shown to encourage users to +# import their browser profile from another browser they might be using. +manual_migration_explanation=Use o Firefox com seus sites favoritos de outro navegador. +# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the +# process of importing another browser’s profile into Firefox. +manual_migration_cancel_button=Não, obrigado +# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process +# of importing another browser’s profile profile into Firefox. +manual_migration_import_button=Importar agora diff --git a/locales/pt-PT/strings.properties b/locales/pt-PT/strings.properties index b694e91b9e..547d3096e7 100644 --- a/locales/pt-PT/strings.properties +++ b/locales/pt-PT/strings.properties @@ -2,7 +2,19 @@ newtab_page_title=Novo separador default_label_loading=A carregar… header_top_sites=Sites mais visitados -header_highlights=Destaques +header_stories=Histórias principais +header_visit_again=Visitar novamente +header_bookmarks=Marcadores recentes +# LOCALIZATION NOTE(header_recommended_by): This is followed by the name +# of the corresponding content provider. +header_recommended_by=Recomendado por {provider} +# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is +# meant to inform that section contains no information because +# the user hasn't added any bookmarks. +header_bookmarks_placeholder=Ainda não tem quaisquer marcadores. +# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the +# corresponding content (stories) provider +header_stories_from=de # LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give # context on how the element is related to the user, e.g. type indicates that @@ -10,9 +22,11 @@ header_highlights=Destaques type_label_visited=Visitados type_label_bookmarked=Guardados nos marcadores type_label_synced=Sincronizado a partir de outro dispositivo +type_label_recommended=Tendência # LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open" type_label_open=Abertos type_label_topic=Tópico +type_label_now=Agora # LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context # menu and are meant as a call to action for a given page. @@ -25,7 +39,15 @@ menu_action_email_link=Enviar ligação por email… menu_action_open_new_window=Abrir em nova janela menu_action_open_private_window=Abrir em nova janela privada menu_action_dismiss=Dispensar -menu_action_delete=Eliminar do histórico +menu_action_delete=Apagar do histórico +menu_action_pin=Afixar +menu_action_unpin=Desafixar +confirm_history_delete_p1=Tem a certeza de que deseja apagar todas as instâncias desta página do seu histórico? +# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in +# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a +# page from history. +confirm_history_delete_notice_p2=Esta ação não pode ser desfeita. +menu_action_save_to_pocket=Guardar no Pocket # LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder # for what the user has typed in the search input field, e.g. 'Search for ' + @@ -47,6 +69,10 @@ search_header=Pesquisa {search_engine_name} search_web_placeholder=Pesquisar na Web search_settings=Alterar definições de pesquisa +# LOCALIZATION NOTE (section_info_option): This is the screenreader text for the +# (?) icon that would show a section's description with optional feedback link. +section_info_option=Informação + # LOCALIZATION NOTE (welcome_*): This is shown as a modal dialog, typically on a # first-run experience when there's no data to display yet welcome_title=Bem-vindo ao novo separador @@ -62,15 +88,19 @@ time_label_day={number}d # LOCALIZATION NOTE (settings_pane_*): This is shown in the Settings Pane sidebar. settings_pane_button_label=Personalizar a sua página de novo separador -settings_pane_header=Novas preferências de separador -settings_pane_body=Escolha o que ver quando abre um novo separador. -settings_pane_search_header=Pesquisar +settings_pane_header=Preferências de novo separador +settings_pane_body=Escolha o que vê quando abre um novo separador. +settings_pane_search_header=Pesquisa settings_pane_search_body=Pesquise na Web a partir do seu novo separador. settings_pane_topsites_header=Sites mais visitados settings_pane_topsites_body=Aceda aos websites que mais visita. settings_pane_topsites_options_showmore=Mostrar duas linhas -settings_pane_highlights_header=Destaques -settings_pane_highlights_body=Veja o seu histórico de navegação recente e marcadores recentemente criados. +settings_pane_bookmarks_header=Marcadores recentes +settings_pane_bookmarks_body=Os seus marcadores recém-criados num único local acessível. +settings_pane_visit_again_header=Visitar novamente +settings_pane_visit_again_body=O Firefox irá mostrar-lhe partes do seu histórico de navegação que pode querer relembrar ou voltar a aceder. +settings_pane_pocketstories_header=Histórias principais +settings_pane_pocketstories_body=O Pocket, parte da família Mozilla, irá ajudar a ligar-se a conteúdo de alta qualidade que você poderia não ter encontrado de outra forma. settings_pane_done_button=Feito # LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal @@ -81,5 +111,46 @@ edit_topsites_showmore_button=Mostrar mais edit_topsites_showless_button=Mostrar menos edit_topsites_done_button=Feito edit_topsites_pin_button=Afixar este site +edit_topsites_unpin_button=Desafixar este site edit_topsites_edit_button=Editar este site edit_topsites_dismiss_button=Descartar este site +edit_topsites_add_button=Adicionar + +# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal. +topsites_form_add_header=Novo site mais visitado +topsites_form_edit_header=Editar site mais visitado +topsites_form_title_placeholder=Digite um título +topsites_form_url_placeholder=Digite ou cole um URL +topsites_form_add_button=Adicionar +topsites_form_save_button=Guardar +topsites_form_cancel_button=Cancelar +topsites_form_url_validation=URL válido requerido + +# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the +# trending stories section and precedes a list of links to popular topics. +pocket_read_more=Tópicos populares: +# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the +# end of the list of popular topic links. +pocket_read_even_more=Ver mais histórias +# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction +# to Pocket as part of the feedback form. +pocket_feedback_header=O melhor da web, com curadoria de mais de 25 milhões de pessoas. +# LOCALIZATION NOTE (pocket_feedback_body): This is shown below +# (pocket_feedback_header) to provide more information about Pocket. +pocket_feedback_body=O Pocket, parte da família Mozilla, irá ajudar a ligar-se a conteúdo de alta qualidade que você poderia não ter encontrado de outra forma. +pocket_send_feedback=Enviar feedback + +# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations, +# in the space that would have shown a few stories, this is shown instead. +# {provider} is replaced by the name of the content provider for this section. +topstories_empty_state=Já apanhou tudo. Verifique mais tarde para mais histórias principais de {provider}. Não pode esperar? Selecione um tópico popular para encontrar mais boas histórias de toda a web. + +# LOCALIZATION NOTE (manual_migration_explanation): This message is shown to encourage users to +# import their browser profile from another browser they might be using. +manual_migration_explanation=Experimente o Firefox com os seus sites favoritos e marcadores de outro navegador. +# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the +# process of importing another browser’s profile into Firefox. +manual_migration_cancel_button=Não obrigado +# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process +# of importing another browser’s profile profile into Firefox. +manual_migration_import_button=Importar agora diff --git a/locales/rm/strings.properties b/locales/rm/strings.properties index eaacf3b33b..19b911f32f 100644 --- a/locales/rm/strings.properties +++ b/locales/rm/strings.properties @@ -3,6 +3,10 @@ default_label_loading=Chargiar… header_top_sites=Paginas preferidas header_highlights=Accents +header_stories=Artitgels populars +# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the +# corresponding content (stories) provider +header_stories_from=da # LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give # context on how the element is related to the user, e.g. type indicates that @@ -10,6 +14,7 @@ header_highlights=Accents type_label_visited=Visità type_label_bookmarked=Cun segnapagina type_label_synced=Sincronisà dad auters apparats +type_label_recommended=Popular # LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open" type_label_open=Avert type_label_topic=Tema @@ -26,6 +31,7 @@ menu_action_open_new_window=Avrir en ina nova fanestra menu_action_open_private_window=Avrir en ina nova fanestra privata menu_action_dismiss=Serrar menu_action_delete=Stizzar da la cronologia +menu_action_save_to_pocket=Memorisar en Pocket # LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder # for what the user has typed in the search input field, e.g. 'Search for ' + @@ -71,6 +77,8 @@ settings_pane_topsites_body=Acceder las websites che ti visitas il pli savens. settings_pane_topsites_options_showmore=Mussar duas colonnas settings_pane_highlights_header=Accents settings_pane_highlights_body=Dar in sguard enavos sin websites visitadas dacurt e sin segnapaginas creads dacurt. +settings_pane_pocketstories_header=Artitgels populars +settings_pane_pocketstories_body=Pocket che fa part da Mozilla ta gida da scuvrir cuntegn dad auta qualitad che ti avessas uschiglio forsa manchentà. settings_pane_done_button=Finì # LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal @@ -81,5 +89,31 @@ edit_topsites_showmore_button=Mussar dapli edit_topsites_showless_button=Mussar pli pauc edit_topsites_done_button=Finì edit_topsites_pin_button=Fixar questa pagina +edit_topsites_unpin_button=Betg pli fixar questa pagina edit_topsites_edit_button=Modifitgar questa pagina edit_topsites_dismiss_button=Allontanar questa pagina +edit_topsites_add_button=Agiuntar + +# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal. +topsites_form_add_header=Nova pagina populara +topsites_form_edit_header=Modifitgar la pagina populara +topsites_form_title_placeholder=Endatar in titel +topsites_form_url_placeholder=Tippar u encollar in URL +topsites_form_add_button=Agiuntar +topsites_form_save_button=Memorisar +topsites_form_cancel_button=Interrumper +topsites_form_url_validation=In URL valid è necessari + +# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the +# trending stories section and precedes a list of links to popular topics. +pocket_read_more=Temas populars: +# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the +# end of the list of popular topic links. +pocket_read_even_more=Mussar dapli artitgels +# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction +# to Pocket as part of the feedback form. +pocket_feedback_header=Il meglier ord il web, selecziunà da dapli che 25 milliuns umans. +# LOCALIZATION NOTE (pocket_feedback_body): This is shown below +# (pocket_feedback_header) to provide more information about Pocket. +pocket_feedback_body=Pocket che fa part da Mozilla ta gida da scuvrir cuntegn dad auta qualitad che ti avessas uschiglio forsa manchentà. +pocket_send_feedback=Trametter in resun diff --git a/locales/ro/strings.properties b/locales/ro/strings.properties index fa42857446..89804716a9 100644 --- a/locales/ro/strings.properties +++ b/locales/ro/strings.properties @@ -3,6 +3,9 @@ default_label_loading=Se încarcă… header_top_sites=Site-uri de top header_highlights=Evidențieri +# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the +# corresponding content (stories) provider +header_stories_from=de la # LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give # context on how the element is related to the user, e.g. type indicates that @@ -62,7 +65,7 @@ time_label_day={number}d # LOCALIZATION NOTE (settings_pane_*): This is shown in the Settings Pane sidebar. settings_pane_button_label=Particularizează pagina de filă nouă -settings_pane_header=Preferințe filă nouă +settings_pane_header=Preferințe pentru filă nouă settings_pane_body=Alege ce să vezi la deschiderea unei noi file. settings_pane_search_header=Caută settings_pane_search_body=Caută pe web din noua filă. @@ -83,3 +86,25 @@ edit_topsites_done_button=Gata edit_topsites_pin_button=Fixează acest site edit_topsites_edit_button=Editează acest site edit_topsites_dismiss_button=Înlătură acest site +edit_topsites_add_button=Adaugă + +# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal. +topsites_form_add_header=Site de top nou +topsites_form_edit_header=Editează site-ul de top +topsites_form_title_placeholder=Introdu un titlu +topsites_form_url_placeholder=Tastează sau lipește un URL +topsites_form_add_button=Adaugă +topsites_form_save_button=Salvează +topsites_form_cancel_button=Renunță +topsites_form_url_validation=URL valid necesar + +# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the +# trending stories section and precedes a list of links to popular topics. +pocket_read_more=Subiecte populare: +# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the +# end of the list of popular topic links. +# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction +# to Pocket as part of the feedback form. +# LOCALIZATION NOTE (pocket_feedback_body): This is shown below +# (pocket_feedback_header) to provide more information about Pocket. +pocket_send_feedback=Trimite feedback diff --git a/locales/ru/strings.properties b/locales/ru/strings.properties index 31e026f616..fcdfa558c9 100644 --- a/locales/ru/strings.properties +++ b/locales/ru/strings.properties @@ -2,7 +2,16 @@ newtab_page_title=Новая вкладка default_label_loading=Загрузка… header_top_sites=Топ сайтов -header_highlights=Избранные +header_stories=Топ статей +header_visit_again=Посетить снова +header_bookmarks=Недавние закладки +# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is +# meant to inform that section contains no information because +# the user hasn't added any bookmarks. +header_bookmarks_placeholder=У вас ещё нет каких-либо закладок. +# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the +# corresponding content (stories) provider +header_stories_from=от # LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give # context on how the element is related to the user, e.g. type indicates that @@ -10,6 +19,7 @@ header_highlights=Избранные type_label_visited=Посещено type_label_bookmarked=В закладках type_label_synced=Синхронизировано с другого устройства +type_label_recommended=Популярные # LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open" type_label_open=Открыта type_label_topic=Тема @@ -26,6 +36,14 @@ menu_action_open_new_window=Открыть в новом окне menu_action_open_private_window=Открыть в новом приватном окне menu_action_dismiss=Скрыть menu_action_delete=Удалить из истории +menu_action_pin=Прикрепить +menu_action_unpin=Открепить +confirm_history_delete_p1=Вы действительно хотите удалить все записи об этой странице из вашей истории? +# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in +# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a +# page from history. +confirm_history_delete_notice_p2=Это действие не может быть отменено. +menu_action_save_to_pocket=Сохранить в Pocket # LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder # for what the user has typed in the search input field, e.g. 'Search for ' + @@ -69,8 +87,12 @@ settings_pane_search_body=Поиск в Интернете с вашей нов settings_pane_topsites_header=Топ сайтов settings_pane_topsites_body=Получите доступ к сайтам, которые вы посещаете чаще всего. settings_pane_topsites_options_showmore=Показать в два ряда -settings_pane_highlights_header=Избранные -settings_pane_highlights_body=Посмотрите на вашу недавнюю историю веб-сёрфинга и недавно сделанные закладки. +settings_pane_bookmarks_header=Недавние закладки +settings_pane_bookmarks_body=Ваши новые закладки в одном удобном расположении. +settings_pane_visit_again_header=Посетить снова +settings_pane_visit_again_body=Firefox покажет вам элементы вашей истории просмотра, которые вы, возможно, захотите вспомнить или посетить снова. +settings_pane_pocketstories_header=Топ статей +settings_pane_pocketstories_body=Pocket, часть семьи Mozilla, поможет подключить вас к высококачественному контенту, который вы бы иначе не нашли. settings_pane_done_button=Готово # LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal @@ -81,5 +103,31 @@ edit_topsites_showmore_button=Показать больше edit_topsites_showless_button=Показать меньше edit_topsites_done_button=Готово edit_topsites_pin_button=Закрепить этот сайт +edit_topsites_unpin_button=Открепить этот сайт edit_topsites_edit_button=Изменить этот сайт edit_topsites_dismiss_button=Скрыть этот сайт +edit_topsites_add_button=Добавить + +# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal. +topsites_form_add_header=Новый сайт в топе +topsites_form_edit_header=Изменить сайт из топа +topsites_form_title_placeholder=Введите название +topsites_form_url_placeholder=Введите или вставьте URL +topsites_form_add_button=Добавить +topsites_form_save_button=Сохранить +topsites_form_cancel_button=Отмена +topsites_form_url_validation=Введите корректный URL + +# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the +# trending stories section and precedes a list of links to popular topics. +pocket_read_more=Популярные темы: +# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the +# end of the list of popular topic links. +pocket_read_even_more=Больше статей +# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction +# to Pocket as part of the feedback form. +pocket_feedback_header=Лучшее из Интернета, отобранное более чем 25 миллионами людей. +# LOCALIZATION NOTE (pocket_feedback_body): This is shown below +# (pocket_feedback_header) to provide more information about Pocket. +pocket_feedback_body=Pocket, часть семьи Mozilla, поможет подключить вас к высококачественному контенту, который вы можете иначе и не найти. +pocket_send_feedback=Отправить отзыв diff --git a/locales/sk/strings.properties b/locales/sk/strings.properties index d29094f83e..a66d2970ea 100644 --- a/locales/sk/strings.properties +++ b/locales/sk/strings.properties @@ -2,7 +2,19 @@ newtab_page_title=Nová karta default_label_loading=Načítava sa… header_top_sites=Top stránky -header_highlights=Vybrané stránky +header_stories=Top príbehy +header_visit_again=Navštívte znova +header_bookmarks=Nedávno pridané záložky +# LOCALIZATION NOTE(header_recommended_by): This is followed by the name +# of the corresponding content provider. +header_recommended_by=Odporúča {provider} +# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is +# meant to inform that section contains no information because +# the user hasn't added any bookmarks. +header_bookmarks_placeholder=Zatiaľ nemáte žiadne záložky. +# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the +# corresponding content (stories) provider +header_stories_from=zo služby # LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give # context on how the element is related to the user, e.g. type indicates that @@ -10,9 +22,11 @@ header_highlights=Vybrané stránky type_label_visited=Navštívené type_label_bookmarked=V záložkách type_label_synced=Synchronizované z ďalšieho zariadenia +type_label_recommended=Trendy # LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open" type_label_open=Otvorené type_label_topic=Téma +type_label_now=Teraz # LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context # menu and are meant as a call to action for a given page. @@ -26,6 +40,14 @@ menu_action_open_new_window=Otvoriť v novom okne menu_action_open_private_window=Otvoriť v novom okne režimu Súkromné prehliadanie menu_action_dismiss=Skryť menu_action_delete=Odstrániť z histórie +menu_action_pin=Pripnúť +menu_action_unpin=Odopnúť +confirm_history_delete_p1=Ste si istí, že chcete odstrániť všetky výskyty tejto stránky zo svojej histórie prehliadania? +# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in +# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a +# page from history. +confirm_history_delete_notice_p2=Túto akciu nie je možné vrátiť späť. +menu_action_save_to_pocket=Uložiť do služby Pocket # LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder # for what the user has typed in the search input field, e.g. 'Search for ' + @@ -47,6 +69,10 @@ search_header=Vyhľadávanie pomocou {search_engine_name} search_web_placeholder=Vyhľadávanie na webe search_settings=Zmeniť nastavenia vyhľadávania +# LOCALIZATION NOTE (section_info_option): This is the screenreader text for the +# (?) icon that would show a section's description with optional feedback link. +section_info_option=Informácie + # LOCALIZATION NOTE (welcome_*): This is shown as a modal dialog, typically on a # first-run experience when there's no data to display yet welcome_title=Vitajte na stránke novej karty @@ -69,8 +95,12 @@ settings_pane_search_body=Vyhľadávanie zo stránky novej karty. settings_pane_topsites_header=Top stránky settings_pane_topsites_body=Prístup k webovým stránkam, ktoré navštevujete najčastejšie. settings_pane_topsites_options_showmore=Zobraziť dva riadky -settings_pane_highlights_header=Vybrané stránky -settings_pane_highlights_body=Pozrite sa na vašu nedávnu históriu prehliadania a na novovytvorené záložky. +settings_pane_bookmarks_header=Nedávno pridané záložky +settings_pane_bookmarks_body=Vaše nedávno pridané záložky na jednom mieste. +settings_pane_visit_again_header=Navštívte znova +settings_pane_visit_again_body=Firefox vám ukáže niektoré časti vašej histórie prehliadania, ktoré by ste si mohli chcieť pripomenúť alebo sa k nim vrátiť. +settings_pane_pocketstories_header=Top príbehy +settings_pane_pocketstories_body=Pocket, súčasť Mozilla rodiny, vám pomôže nájsť vysokokvalitný obsah, ktorý by ste inde zrejme nenašli. settings_pane_done_button=Hotovo # LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal @@ -81,5 +111,46 @@ edit_topsites_showmore_button=Zobraziť viac edit_topsites_showless_button=Zobraziť menej edit_topsites_done_button=Hotovo edit_topsites_pin_button=Pripnúť túto stránku +edit_topsites_unpin_button=Zrušiť pripnutie tejto stránky edit_topsites_edit_button=Upraviť túto stránku edit_topsites_dismiss_button=Odstrániť túto stránku +edit_topsites_add_button=Pridať + +# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal. +topsites_form_add_header=Nová top stránka +topsites_form_edit_header=Upraviť top stránku +topsites_form_title_placeholder=Zadajte názov +topsites_form_url_placeholder=Zadajte alebo prilepte URL +topsites_form_add_button=Pridať +topsites_form_save_button=Uložiť +topsites_form_cancel_button=Zrušiť +topsites_form_url_validation=Vyžaduje sa platná URL + +# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the +# trending stories section and precedes a list of links to popular topics. +pocket_read_more=Populárne témy: +# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the +# end of the list of popular topic links. +pocket_read_even_more=Zobraziť ďalšie príbehy +# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction +# to Pocket as part of the feedback form. +pocket_feedback_header=To najlepšie z webu - podľa názoru 25 miliónov ľudí. +# LOCALIZATION NOTE (pocket_feedback_body): This is shown below +# (pocket_feedback_header) to provide more information about Pocket. +pocket_feedback_body=Pocket, súčasť Mozilla rodiny, vám pomôže nájsť vysokokvalitný obsah, ktorý by ste inde zrejme nenašli. +pocket_send_feedback=Odoslať spätnú väzbu + +# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations, +# in the space that would have shown a few stories, this is shown instead. +# {provider} is replaced by the name of the content provider for this section. +topstories_empty_state=Už ste prečítali všetko. Ďalšie príbehy zo služby {provider} tu nájdete opäť neskôr. Nemôžete sa dočkať? Vyberte si populárnu tému a pozrite sa na ďalšie skvelé príbehy z celého webu. + +# LOCALIZATION NOTE (manual_migration_explanation): This message is shown to encourage users to +# import their browser profile from another browser they might be using. +manual_migration_explanation=Vyskúšajte Firefox so svojimi obľúbenými stránkami a záložkami z iného prehliadača. +# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the +# process of importing another browser’s profile into Firefox. +manual_migration_cancel_button=Nie, ďakujem +# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process +# of importing another browser’s profile profile into Firefox. +manual_migration_import_button=Importovať teraz diff --git a/locales/sl/strings.properties b/locales/sl/strings.properties index fcb3ec8fa4..fe732627a2 100644 --- a/locales/sl/strings.properties +++ b/locales/sl/strings.properties @@ -2,7 +2,18 @@ newtab_page_title=Nov zavihek default_label_loading=Nalaganje … header_top_sites=Glavne strani -header_highlights=Poudarki +header_stories=Glavne vesti +header_visit_again=Obiščite znova +header_bookmarks=Nedavni zaznamki +# LOCALIZATION NOTE(header_recommended_by): This is followed by the name +# of the corresponding content provider. +# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is +# meant to inform that section contains no information because +# the user hasn't added any bookmarks. +header_bookmarks_placeholder=Nimate še nobenih zaznamkov. +# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the +# corresponding content (stories) provider +header_stories_from=od # LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give # context on how the element is related to the user, e.g. type indicates that @@ -10,9 +21,11 @@ header_highlights=Poudarki type_label_visited=Obiskano type_label_bookmarked=Med zaznamki type_label_synced=Sinhronizirano z druge naprave +type_label_recommended=Najbolj priljubljeno # LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open" type_label_open=Odpri type_label_topic=Tema +type_label_now=Zdaj # LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context # menu and are meant as a call to action for a given page. @@ -26,6 +39,14 @@ menu_action_open_new_window=Odpri v novem oknu menu_action_open_private_window=Odpri v novem zasebnem oknu menu_action_dismiss=Opusti menu_action_delete=Izbriši iz zgodovine +menu_action_pin=Pripni +menu_action_unpin=Odpni +confirm_history_delete_p1=Ali ste prepričani, da želite izbrisati vse primerke te strani iz zgodovine? +# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in +# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a +# page from history. +confirm_history_delete_notice_p2=Tega dejanja ni mogoče razveljaviti. +menu_action_save_to_pocket=Shrani v Pocket # LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder # for what the user has typed in the search input field, e.g. 'Search for ' + @@ -47,6 +68,9 @@ search_header=Iskanje {search_engine_name} search_web_placeholder=Iskanje po spletu search_settings=Spremeni nastavitve iskanja +# LOCALIZATION NOTE (section_info_option): This is the screenreader text for the +# (?) icon that would show a section's description with optional feedback link. + # LOCALIZATION NOTE (welcome_*): This is shown as a modal dialog, typically on a # first-run experience when there's no data to display yet welcome_title=Dobrodošli v novem zavihku @@ -69,8 +93,12 @@ settings_pane_search_body=Iščite po spletu s strani novega zavihka. settings_pane_topsites_header=Glavne strani settings_pane_topsites_body=Priročen dostop do najbolj obiskanih strani. settings_pane_topsites_options_showmore=Prikaži dve vrsti -settings_pane_highlights_header=Poudarki -settings_pane_highlights_body=Pogled nazaj na nedavno zgodovino brskanja in novo ustvarjene zaznamke. +settings_pane_bookmarks_header=Nedavni zaznamki +settings_pane_bookmarks_body=Vaši novo ustvarjeni zaznamki na enem mestu. +settings_pane_visit_again_header=Obiščite znova +settings_pane_visit_again_body=Firefox vam bo prikazoval dele zgodovine brskanja, ki bi se jih morda želeli spomniti ali se nanje vrniti. +settings_pane_pocketstories_header=Glavne vesti +settings_pane_pocketstories_body=Pocket, del Mozilline družine, vam bo pomagal pridobiti visokokakovostne vsebine, ki jih sicer ne bi našli. settings_pane_done_button=Končano # LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal @@ -81,5 +109,45 @@ edit_topsites_showmore_button=Prikaži več edit_topsites_showless_button=Prikaži manj edit_topsites_done_button=Končano edit_topsites_pin_button=Pripni to stran +edit_topsites_unpin_button=Odpni to stran edit_topsites_edit_button=Uredi to stran edit_topsites_dismiss_button=Odstrani to stran +edit_topsites_add_button=Dodaj + +# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal. +topsites_form_add_header=Nova glavna stran +topsites_form_edit_header=Uredi glavno stran +topsites_form_title_placeholder=Vnesite naslov +topsites_form_url_placeholder=Vnesite ali prilepite URL +topsites_form_add_button=Dodaj +topsites_form_save_button=Shrani +topsites_form_cancel_button=Prekliči +topsites_form_url_validation=Vnesite veljaven URL + +# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the +# trending stories section and precedes a list of links to popular topics. +pocket_read_more=Priljubljene teme: +# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the +# end of the list of popular topic links. +pocket_read_even_more=Prikaži več vesti +# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction +# to Pocket as part of the feedback form. +pocket_feedback_header=Najboljše s spleta, kar je izbralo več kot 25 milijonov ljudi. +# LOCALIZATION NOTE (pocket_feedback_body): This is shown below +# (pocket_feedback_header) to provide more information about Pocket. +pocket_feedback_body=Pocket, del Mozilline družine, vam bo pomagal pridobiti visokokakovostne vsebine, ki jih sicer ne bi našli. +pocket_send_feedback=Pošlji povratne informacije + +# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations, +# in the space that would have shown a few stories, this is shown instead. +# {provider} is replaced by the name of the content provider for this section. + +# LOCALIZATION NOTE (manual_migration_explanation): This message is shown to encourage users to +# import their browser profile from another browser they might be using. +manual_migration_explanation=Preskusite Firefox s svojimi priljubljenimi stranmi in zaznamki iz drugih brskalnikov. +# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the +# process of importing another browser’s profile into Firefox. +manual_migration_cancel_button=Ne, hvala +# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process +# of importing another browser’s profile profile into Firefox. +manual_migration_import_button=Uvozi zdaj diff --git a/locales/sr/strings.properties b/locales/sr/strings.properties index e0f1b52bca..9acbc15fc2 100644 --- a/locales/sr/strings.properties +++ b/locales/sr/strings.properties @@ -2,7 +2,16 @@ newtab_page_title=Нови језичак default_label_loading=Учитавање… header_top_sites=Популарни сајтови -header_highlights=Истакнути +header_stories=Популарне приче +header_visit_again=Посетите поново +header_bookmarks=Недавне забелешке +# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is +# meant to inform that section contains no information because +# the user hasn't added any bookmarks. +header_bookmarks_placeholder=Још увек немате забелешке. +# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the +# corresponding content (stories) provider +header_stories_from=од # LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give # context on how the element is related to the user, e.g. type indicates that @@ -10,6 +19,7 @@ header_highlights=Истакнути type_label_visited=Посећене type_label_bookmarked=Забележено type_label_synced=Синхронизовано са другог уређаја +type_label_recommended=У тренду # LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open" type_label_open=Отвори type_label_topic=Тема @@ -26,6 +36,14 @@ menu_action_open_new_window=Отвори у новом прозору menu_action_open_private_window=Отвори у новом приватном прозору menu_action_dismiss=Занемари menu_action_delete=Уклони из историјата +menu_action_pin=Закачи +menu_action_unpin=Откачи +confirm_history_delete_p1=Да ли сте сигурни да желите да обришете све посете ове странице из ваше историје? +# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in +# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a +# page from history. +confirm_history_delete_notice_p2=Ова радња се не може опозвати. +menu_action_save_to_pocket=Сачувај на Pocket # LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder # for what the user has typed in the search input field, e.g. 'Search for ' + @@ -68,9 +86,13 @@ settings_pane_search_header=Претрага settings_pane_search_body=Претражујте веб из вашег новог језичка. settings_pane_topsites_header=Популарни сајтови settings_pane_topsites_body=Приступите најпосећенијим веб сајтовима. -settings_pane_topsites_options_showmore=Прикажи два реда -settings_pane_highlights_header=Истакнути -settings_pane_highlights_body=Прегледајте ваш скорашњи историјат и нове забелешке. +settings_pane_topsites_options_showmore=Прикажи у два реда +settings_pane_bookmarks_header=Недавне забелешке +settings_pane_bookmarks_body=Ваша нова забелешка на јединственом месту. +settings_pane_visit_again_header=Посетите поново +settings_pane_visit_again_body=Firefox ће вам приказивати делове ваше историје прегледања коју можда желите да запамтите или да им се вратите. +settings_pane_pocketstories_header=Популарне приче +settings_pane_pocketstories_body=Pocket, део Mozilla-ине породице, ће вам помоћи да повежете ваш квалитетан садржај који можда не би пронашли другачије. settings_pane_done_button=Готово # LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal @@ -81,5 +103,31 @@ edit_topsites_showmore_button=Прикажи више edit_topsites_showless_button=Прикажи мање edit_topsites_done_button=Готово edit_topsites_pin_button=Закачи овај сајт +edit_topsites_unpin_button=Откачи овај сајт edit_topsites_edit_button=Уреди овај сајт edit_topsites_dismiss_button=Одбаци овај сајт +edit_topsites_add_button=Додај + +# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal. +topsites_form_add_header=Нови популарни сајтови +topsites_form_edit_header=Уреди популарне сајтове +topsites_form_title_placeholder=Унесите наслов +topsites_form_url_placeholder=Унесите или налепите URL +topsites_form_add_button=Додај +topsites_form_save_button=Сачувај +topsites_form_cancel_button=Откажи +topsites_form_url_validation=Исправан URL се захтева + +# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the +# trending stories section and precedes a list of links to popular topics. +pocket_read_more=Популарне теме: +# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the +# end of the list of popular topic links. +pocket_read_even_more=Погледајте још прича +# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction +# to Pocket as part of the feedback form. +pocket_feedback_header=Најбоље од веба од преко 25 милиона кустоса. +# LOCALIZATION NOTE (pocket_feedback_body): This is shown below +# (pocket_feedback_header) to provide more information about Pocket. +pocket_feedback_body=Pocket, део Mozilla-ине породице, ће вам помоћи да повежете ваш квалитетан садржај који можда не би пронашли другачије. +pocket_send_feedback=Пошаљи повратну информацију diff --git a/locales/sv-SE/strings.properties b/locales/sv-SE/strings.properties index 3e7776f6ec..73a4dc6d3a 100644 --- a/locales/sv-SE/strings.properties +++ b/locales/sv-SE/strings.properties @@ -2,7 +2,19 @@ newtab_page_title=Ny flik default_label_loading=Laddar… header_top_sites=Mest besökta -header_highlights=Höjdpunkter +header_stories=Huvudnyheter +header_visit_again=Besökt igen +header_bookmarks=Senaste bokmärken +# LOCALIZATION NOTE(header_recommended_by): This is followed by the name +# of the corresponding content provider. +header_recommended_by=Rekommenderas av {provider} +# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is +# meant to inform that section contains no information because +# the user hasn't added any bookmarks. +header_bookmarks_placeholder=Du har inga bokmärken ännu. +# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the +# corresponding content (stories) provider +header_stories_from=från # LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give # context on how the element is related to the user, e.g. type indicates that @@ -10,9 +22,11 @@ header_highlights=Höjdpunkter type_label_visited=Besökta type_label_bookmarked=Bokmärkta type_label_synced=Synkroniserade från en annan enhet +type_label_recommended=Trend # LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open" type_label_open=Öppna type_label_topic=Ämne +type_label_now=Nu # LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context # menu and are meant as a call to action for a given page. @@ -26,6 +40,14 @@ menu_action_open_new_window=Öppna i nytt fönster menu_action_open_private_window=Öppna i nytt privat fönster menu_action_dismiss=Avfärda menu_action_delete=Ta bort från historik +menu_action_pin=Fäst +menu_action_unpin=Lösgör +confirm_history_delete_p1=Är du säker på att du vill radera varje förekomst av den här sidan från din historik? +# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in +# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a +# page from history. +confirm_history_delete_notice_p2=Den här åtgärden kan inte ångras. +menu_action_save_to_pocket=Spara till Pocket # LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder # for what the user has typed in the search input field, e.g. 'Search for ' + @@ -47,6 +69,10 @@ search_header={search_engine_name} search_web_placeholder=Sök på webben search_settings=Ändra sökinställningar +# LOCALIZATION NOTE (section_info_option): This is the screenreader text for the +# (?) icon that would show a section's description with optional feedback link. +section_info_option=Info + # LOCALIZATION NOTE (welcome_*): This is shown as a modal dialog, typically on a # first-run experience when there's no data to display yet welcome_title=Välkommen till ny flik @@ -69,8 +95,12 @@ settings_pane_search_body=Sök på webben från din nya flik. settings_pane_topsites_header=Mest besökta settings_pane_topsites_body=Åtkomst till de webbplatser du besökt mest. settings_pane_topsites_options_showmore=Visa två rader -settings_pane_highlights_header=Höjdpunkter -settings_pane_highlights_body=Titta tillbaka på din senaste webbhistorik och nyskapade bokmärken. +settings_pane_bookmarks_header=Senaste bokmärken +settings_pane_bookmarks_body=Dina nyskapade bokmärken på ett bra ställe. +settings_pane_visit_again_header=Besökt igen +settings_pane_visit_again_body=Firefox visar dig delar av din surfhistorik som du kanske vill komma ihåg eller återkomma till. +settings_pane_pocketstories_header=Huvudnyheter +settings_pane_pocketstories_body=Pocket, en del av Mozilla-familjen, hjälper dig att hitta högkvalitativt innehåll som du kanske annars inte hade hittat. settings_pane_done_button=Klar # LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal @@ -81,5 +111,46 @@ edit_topsites_showmore_button=Visa mer edit_topsites_showless_button=Visa mindre edit_topsites_done_button=Klar edit_topsites_pin_button=Fäst denna webbplats +edit_topsites_unpin_button=Lösgör webbplatsen edit_topsites_edit_button=Redigera denna webbplats edit_topsites_dismiss_button=Avfärda denna webbplats +edit_topsites_add_button=Lägg till + +# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal. +topsites_form_add_header=Ny mest besökt +topsites_form_edit_header=Redigera mest besökta +topsites_form_title_placeholder=Ange en titel +topsites_form_url_placeholder=Skriv eller klistra in en URL +topsites_form_add_button=Lägg till +topsites_form_save_button=Spara +topsites_form_cancel_button=Avbryt +topsites_form_url_validation=Giltig URL krävs + +# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the +# trending stories section and precedes a list of links to popular topics. +pocket_read_more=Populära ämnen: +# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the +# end of the list of popular topic links. +pocket_read_even_more=Visa fler nyheter +# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction +# to Pocket as part of the feedback form. +pocket_feedback_header=Det bästa av webben, sammanställt av över 25 miljoner människor. +# LOCALIZATION NOTE (pocket_feedback_body): This is shown below +# (pocket_feedback_header) to provide more information about Pocket. +pocket_feedback_body=Pocket, en del av Mozilla-familjen, hjälper dig att hitta högkvalitativt innehåll som du kanske annars inte hade hittat. +pocket_send_feedback=Skicka återkoppling + +# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations, +# in the space that would have shown a few stories, this is shown instead. +# {provider} is replaced by the name of the content provider for this section. +topstories_empty_state=Det finns inte fler. Kom tillbaka senare för fler huvudnyheter från {provider}. Kan du inte vänta? Välj ett populärt ämne för att hitta fler bra nyheter från hela världen. + +# LOCALIZATION NOTE (manual_migration_explanation): This message is shown to encourage users to +# import their browser profile from another browser they might be using. +manual_migration_explanation=Prova Firefox med dina favoritwebbplatser och bokmärken från en annan webbläsare. +# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the +# process of importing another browser’s profile into Firefox. +manual_migration_cancel_button=Nej tack +# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process +# of importing another browser’s profile profile into Firefox. +manual_migration_import_button=Importera nu diff --git a/locales/ta/strings.properties b/locales/ta/strings.properties index 3e511579a8..e689d1dbd4 100644 --- a/locales/ta/strings.properties +++ b/locales/ta/strings.properties @@ -2,7 +2,16 @@ newtab_page_title=புதிய கீற்று default_label_loading=ஏற்றுகிறது… header_top_sites=சிறந்த தளங்கள் -header_highlights=சிறப்பம்சங்கள் +header_stories=முக்கிய கதைகள் +header_visit_again=மீண்டும் வருக +header_bookmarks=சமீபத்திய புத்தகக்குறிகள் +# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is +# meant to inform that section contains no information because +# the user hasn't added any bookmarks. +header_bookmarks_placeholder=நீங்கள் புத்தகக்குறிகளைக் கொண்டிருக்கவில்லை . +# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the +# corresponding content (stories) provider +header_stories_from=அனுப்பியவர் # LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give # context on how the element is related to the user, e.g. type indicates that @@ -10,6 +19,7 @@ header_highlights=சிறப்பம்சங்கள் type_label_visited=பார்த்தவை type_label_bookmarked=புத்தகக்குறியிடப்பட்டது type_label_synced=இன்னொரு சாதனத்திலிருந்து ஒத்திசைக்கப்பட்டது +type_label_recommended=பிரபலமான # LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open" type_label_open=திற type_label_topic=தலைப்பு @@ -26,12 +36,20 @@ menu_action_open_new_window=ஒரு புதிய சாளரத்தி menu_action_open_private_window=ஒரு புதிய அந்தரங்க சாளரத்தில் திற menu_action_dismiss=வெளியேற்று menu_action_delete=வரலாற்றிலருந்து அழி +menu_action_pin=பொருத்து +menu_action_unpin=விடுவி +confirm_history_delete_p1=இப்பக்கத்தை உங்களின் வரலாற்றிலிருந்து முழுமையாக நீக்க விரும்புகிறீர்களா? +# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in +# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a +# page from history. +confirm_history_delete_notice_p2=இச்செயலை மீட்க முடியாது. +menu_action_save_to_pocket=பாக்கட்டில் சேமி # LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder # for what the user has typed in the search input field, e.g. 'Search for ' + # search_term + 'with:' becomes 'Search for abc with:' # The search engine name is displayed as an icon and does not need a translation -search_for_something_with={search_term} என்பதற்காகத் தேடு: +search_for_something_with={search_term} சொல்லிற்காகத் தேடு: # LOCALIZATION NOTE (search_button): This is screenreader only text for the # search button. @@ -69,8 +87,12 @@ settings_pane_search_body=புதிய கீற்றிலீருந் settings_pane_topsites_header=சிறந்த தளங்கள் settings_pane_topsites_body=நீங்கள் அடிக்கடி பார்க்கும் தளங்களை அணுகவும். settings_pane_topsites_options_showmore=இரு வரிசைகளைக் காண்பி -settings_pane_highlights_header=முக்கியம்சங்கள் -settings_pane_highlights_body=உங்கள் சமீபத்திய உலாவல் வரலாற்றையும் புதிதாகச் சேர்த்த புக்மார்க்குகளையும் திரும்பப் பார்க்கவும். +settings_pane_bookmarks_header=சமீபத்திய புத்தகக்குறிகள் +settings_pane_bookmarks_body=ஒரு வசதியான இடத்தில் உங்கள் புதிதாக உருவாக்கப்பட்ட புத்தகக்குறிகள். +settings_pane_visit_again_header=மீண்டும் வருக +settings_pane_visit_again_body=பயர்பாக்ஸ் நீங்கள் நினைவுப்படுத்த (அ) திரும்பப் பெற விரும்பும் உங்கள் உலாவல் வரலாற்றின் சில பகுதிகளைக் காட்டும். +settings_pane_pocketstories_header=முக்கிய கதைகள் +settings_pane_pocketstories_body=Pocket, ஒரு மொசில்லா குடும்ப உறுப்பினராக, உயர்தர உள்ளடக்கங்களுடன் இணைய உதவுகிறது, இது இல்லையேல் அது சாத்தியமாகது. settings_pane_done_button=முடிந்தது # LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal @@ -81,5 +103,31 @@ edit_topsites_showmore_button=கூடுதலாகக் காட்டு edit_topsites_showless_button=குறைவாகக் காண்பி edit_topsites_done_button=முடிந்தது edit_topsites_pin_button=இத்தளத்தை இடமுனையில் வை +edit_topsites_unpin_button=முனையிலிருந்து நீக்கு edit_topsites_edit_button=இத்தளத்தை தொகு edit_topsites_dismiss_button=இந்த தளத்தை வெளியேற்று +edit_topsites_add_button=சேர் + +# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal. +topsites_form_add_header=புதிய முக்கிய தளம் +topsites_form_edit_header=முக்கிய தளத்தை தொகு +topsites_form_title_placeholder=தலைப்பை இடு +topsites_form_url_placeholder=உள்ளிடு (அ) ஒரு URL ஒட்டு +topsites_form_add_button=சேர் +topsites_form_save_button=சேமி +topsites_form_cancel_button=தவிர் +topsites_form_url_validation=சரியான URL தேவை + +# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the +# trending stories section and precedes a list of links to popular topics. +pocket_read_more=பிரபலமான தலைப்புகள்: +# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the +# end of the list of popular topic links. +pocket_read_even_more=இன்னும் கதைகளைப் பார்க்கவும் +# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction +# to Pocket as part of the feedback form. +pocket_feedback_header=இணையத்தின் சிறந்த செயலி, 250 இலட்ச மக்களால் தேர்ந்தெடுக்கப்பட்டது. +# LOCALIZATION NOTE (pocket_feedback_body): This is shown below +# (pocket_feedback_header) to provide more information about Pocket. +pocket_feedback_body=Pocket, ஒரு மொசில்லா குடும்ப உறுப்பினராக, உயர்தர உள்ளடக்கங்களுடன் இணைய உதவுகிறது, இது இல்லையேல் அது சாத்தியமாகது. +pocket_send_feedback=கருத்துகளைத் தெறிவிக்கவும் diff --git a/locales/te/strings.properties b/locales/te/strings.properties index 3b5e59f7cd..500144105c 100644 --- a/locales/te/strings.properties +++ b/locales/te/strings.properties @@ -2,7 +2,16 @@ newtab_page_title=కొత్త ట్యాబు default_label_loading=వస్తోంది… header_top_sites=మేటి సైట్లు -header_highlights=ముఖ్యాంశాలు +header_stories=ముఖ్య కథనాలు +header_visit_again=మళ్లీ సందర్శించండి +header_bookmarks=ఇటీవలి ఇష్టాంశములు +# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is +# meant to inform that section contains no information because +# the user hasn't added any bookmarks. +header_bookmarks_placeholder=మీకు ఇంకా బుక్మార్క్లు లేవు. +# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the +# corresponding content (stories) provider +header_stories_from=నుండి # LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give # context on how the element is related to the user, e.g. type indicates that @@ -10,6 +19,7 @@ header_highlights=ముఖ్యాంశాలు type_label_visited=సందర్శించినవి type_label_bookmarked=ఇష్టాంశము చేయబడినది type_label_synced=మరో పరికరం నుంచి సమకాలీకరించి తెచ్చుకున్నవి +type_label_recommended=ట్రెండింగ్ # LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open" type_label_open=తెరువు type_label_topic=విషయం @@ -26,6 +36,14 @@ menu_action_open_new_window=కొత్త విండోలో తెరు menu_action_open_private_window=కొత్త వ్యక్తిగత విండోలో తెరువు menu_action_dismiss=విస్మరించు menu_action_delete=చరిత్ర నుంచి తీసివేయి +menu_action_pin=పిన్ +menu_action_unpin=పిన్ తీసివేయి +confirm_history_delete_p1=మీరు మీ చరిత్ర నుండి ఈ పేజీ యొక్క ప్రతి ఉదాహరణకు తొలగించాలనుకుంటున్నారా? +# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in +# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a +# page from history. +confirm_history_delete_notice_p2=ఈ చర్యను రద్దు చేయలేము. +menu_action_save_to_pocket=Pocket కి సేవ్ చేయండి # LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder # for what the user has typed in the search input field, e.g. 'Search for ' + @@ -69,8 +87,12 @@ settings_pane_search_body=కొత్త ట్యాబు నుండే జ settings_pane_topsites_header=మేటి సైట్లు settings_pane_topsites_body=మీరు ఎక్కువగా చూసే వెబ్‌సైట్లను చూడండి. settings_pane_topsites_options_showmore=రెండు వరుసలు చూపించు -settings_pane_highlights_header=విశేషాలు -settings_pane_highlights_body=మీ ఇటీవలి విహరణ చరిత్రనూ కొత్త ఇష్టాంశాలను చూడండి. +settings_pane_bookmarks_header=ఇటీవలి బుక్మార్క్లు +settings_pane_bookmarks_body=ఒక సులభ స్థానంలో మీ క్రొత్తగా సృష్టించిన బుక్మార్క్లు. +settings_pane_visit_again_header=మళ్లీ సందర్శించండి +settings_pane_visit_again_body=మీరు బ్రౌజింగ్ చరిత్రలో గుర్తుంచుకోవాల్సిన లేదా తిరిగి పొందవలసిన భాగాలను చూపిస్తుంది. +settings_pane_pocketstories_header=ముఖ్య కథనాలు +settings_pane_pocketstories_body=Mozilla కుటుంబం యొక్క Pocket, మీరు కనుగొనలేకపోయే అధిక-నాణ్యత విషయముకి మిమ్మల్ని అనుసంధానించడానికి సహాయపడుతుంది. settings_pane_done_button=పూర్తయింది # LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal @@ -81,5 +103,31 @@ edit_topsites_showmore_button=ఇంకా చూపించు edit_topsites_showless_button=కొన్నే చూపించు edit_topsites_done_button=పూర్తయింది edit_topsites_pin_button=ఈ సైటును ఇక్కడ గుచ్చు +edit_topsites_unpin_button=ఈ సైట్ను అన్పిన్ చేయండి edit_topsites_edit_button=ఈ సైటును మార్చు edit_topsites_dismiss_button=ఈ సైటుని తీసివేయి +edit_topsites_add_button=జోడించు + +# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal. +topsites_form_add_header=కొత్త టాప్ సైట్ +topsites_form_edit_header=టాప్ సైట్ను సవరించండి +topsites_form_title_placeholder=శీర్షికను నమోదు చేయండి +topsites_form_url_placeholder=URL ను టైప్ చేయండి లేదా అతికించండి +topsites_form_add_button=చేర్చు +topsites_form_save_button=భద్రపరచు +topsites_form_cancel_button=రద్దుచేయి +topsites_form_url_validation=చెల్లుబాటు అయ్యే URL అవసరం + +# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the +# trending stories section and precedes a list of links to popular topics. +pocket_read_more=ప్రముఖ అంశాలు: +# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the +# end of the list of popular topic links. +pocket_read_even_more=మరిన్ని కథలను వీక్షించండి +# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction +# to Pocket as part of the feedback form. +pocket_feedback_header=వెబ్లో అత్యుత్తమమైనది, 25 మిలియన్లకు పైగా ప్రజలు పర్యవేక్షించినవి. +# LOCALIZATION NOTE (pocket_feedback_body): This is shown below +# (pocket_feedback_header) to provide more information about Pocket. +pocket_feedback_body=Mozilla కుటుంబం యొక్క Pocket, మీరు కనుగొనలేకపోయే అధిక-నాణ్యత విషయముకి మిమ్మల్ని అనుసంధానించడానికి సహాయపడుతుంది. +pocket_send_feedback=అభిప్రాయాన్ని పంపండి diff --git a/locales/th/strings.properties b/locales/th/strings.properties index f6f6fd649a..9a87768c7f 100644 --- a/locales/th/strings.properties +++ b/locales/th/strings.properties @@ -2,7 +2,19 @@ newtab_page_title=แท็บใหม่ default_label_loading=กำลังโหลด… header_top_sites=ไซต์เด่น -header_highlights=รายการเด่น +header_stories=เรื่องราวเด่น +header_visit_again=เยี่ยมชมอีกครั้ง +header_bookmarks=ที่คั่นหน้าเมื่อเร็ว ๆ นี้ +# LOCALIZATION NOTE(header_recommended_by): This is followed by the name +# of the corresponding content provider. +header_recommended_by=แนะนำโดย {provider} +# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is +# meant to inform that section contains no information because +# the user hasn't added any bookmarks. +header_bookmarks_placeholder=คุณยังไม่มีที่คั่นหน้าใด ๆ +# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the +# corresponding content (stories) provider +header_stories_from=จาก # LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give # context on how the element is related to the user, e.g. type indicates that @@ -10,9 +22,11 @@ header_highlights=รายการเด่น type_label_visited=เยี่ยมชมแล้ว type_label_bookmarked=มีที่คั่นหน้าแล้ว type_label_synced=ซิงค์จากอุปกรณ์อื่น +type_label_recommended=กำลังนิยม # LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open" type_label_open=เปิด type_label_topic=หัวข้อ +type_label_now=ตอนนี้ # LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context # menu and are meant as a call to action for a given page. @@ -26,6 +40,13 @@ menu_action_open_new_window=เปิดในหน้าต่างใหม menu_action_open_private_window=เปิดในหน้าต่างส่วนตัวใหม่ menu_action_dismiss=ยกเลิก menu_action_delete=ลบออกจากประวัติ +menu_action_pin=ปักหมุด +menu_action_unpin=ถอดหมุด +# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in +# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a +# page from history. +confirm_history_delete_notice_p2=การกระทำนี้ไม่สามารถเลิกทำได้ +menu_action_save_to_pocket=บันทึกไปยัง Pocket # LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder # for what the user has typed in the search input field, e.g. 'Search for ' + @@ -47,6 +68,10 @@ search_header=ค้นหา {search_engine_name} search_web_placeholder=ค้นหาเว็บ search_settings=เปลี่ยนการตั้งค่าการค้นหา +# LOCALIZATION NOTE (section_info_option): This is the screenreader text for the +# (?) icon that would show a section's description with optional feedback link. +section_info_option=ข้อมูล + # LOCALIZATION NOTE (welcome_*): This is shown as a modal dialog, typically on a # first-run experience when there's no data to display yet welcome_title=ยินดีต้อนรับสู่แท็บใหม่ @@ -69,8 +94,10 @@ settings_pane_search_body=ค้นหาเว็บจากแท็บให settings_pane_topsites_header=ไซต์เด่น settings_pane_topsites_body=เข้าถึงเว็บไซต์ที่คุณเยี่ยมชมมากที่สุด settings_pane_topsites_options_showmore=แสดงสองแถว -settings_pane_highlights_header=รายการเด่น -settings_pane_highlights_body=มองย้อนกลับมาดูประวัติการท่องเว็บเมื่อเร็ว ๆ นี้และที่คั่นหน้าที่สร้างใหม่ของคุณ +settings_pane_bookmarks_header=ที่คั่นหน้าเมื่อเร็ว ๆ นี้ +settings_pane_visit_again_header=เยี่ยมชมอีกครั้ง +settings_pane_pocketstories_header=เรื่องราวเด่น +settings_pane_pocketstories_body=Pocket ส่วนหนึ่งของครอบครัว Mozilla จะช่วยเชื่อมต่อคุณกับเนื้อหาคุณภาพสูงที่คุณอาจไม่พบที่อื่น settings_pane_done_button=เสร็จสิ้น # LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal @@ -81,5 +108,45 @@ edit_topsites_showmore_button=แสดงเพิ่มเติม edit_topsites_showless_button=แสดงน้อยลง edit_topsites_done_button=เสร็จสิ้น edit_topsites_pin_button=ปักหมุดไซต์นี้ +edit_topsites_unpin_button=ถอดหมุดไซต์นี้ edit_topsites_edit_button=แก้ไขไซต์นี้ edit_topsites_dismiss_button=ไม่สนใจไซต์นี้ +edit_topsites_add_button=เพิ่ม + +# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal. +topsites_form_add_header=ไซต์เด่นใหม่ +topsites_form_edit_header=แก้ไขไซต์เด่น +topsites_form_title_placeholder=ป้อนชื่อเรื่อง +topsites_form_url_placeholder=พิมพ์หรือวาง URL +topsites_form_add_button=เพิ่ม +topsites_form_save_button=บันทึก +topsites_form_cancel_button=ยกเลิก +topsites_form_url_validation=ต้องการ URL ที่ถูกต้อง + +# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the +# trending stories section and precedes a list of links to popular topics. +pocket_read_more=หัวข้อยอดนิยม: +# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the +# end of the list of popular topic links. +pocket_read_even_more=ดูเรื่องราวเพิ่มเติม +# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction +# to Pocket as part of the feedback form. +pocket_feedback_header=ที่สุดของเว็บ จัดรายการโดยผู้คนกว่า 25 ล้านคน +# LOCALIZATION NOTE (pocket_feedback_body): This is shown below +# (pocket_feedback_header) to provide more information about Pocket. +pocket_feedback_body=Pocket ส่วนหนึ่งของครอบครัว Mozilla จะช่วยเชื่อมต่อคุณกับเนื้อหาคุณภาพสูงที่คุณอาจไม่พบที่อื่น +pocket_send_feedback=ส่งข้อคิดเห็น + +# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations, +# in the space that would have shown a few stories, this is shown instead. +# {provider} is replaced by the name of the content provider for this section. + +# LOCALIZATION NOTE (manual_migration_explanation): This message is shown to encourage users to +# import their browser profile from another browser they might be using. +manual_migration_explanation=ลอง Firefox ด้วยไซต์โปรดและที่คั่นหน้าของคุณจากเบราว์เซอร์อื่น +# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the +# process of importing another browser’s profile into Firefox. +manual_migration_cancel_button=ไม่ ขอบคุณ +# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process +# of importing another browser’s profile profile into Firefox. +manual_migration_import_button=นำเข้าตอนนี้ diff --git a/locales/tr/strings.properties b/locales/tr/strings.properties index 3496cd373f..e078af9528 100644 --- a/locales/tr/strings.properties +++ b/locales/tr/strings.properties @@ -2,7 +2,19 @@ newtab_page_title=Yeni Sekme default_label_loading=Yükleniyor… header_top_sites=En Sık Kullanılan Siteler -header_highlights=Öne Çıkanlar +header_stories=İlginç Yazılar +header_visit_again=Yeniden Ziyaret Edin +header_bookmarks=Son Yer imleri +# LOCALIZATION NOTE(header_recommended_by): This is followed by the name +# of the corresponding content provider. +header_recommended_by={provider} öneriyor +# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is +# meant to inform that section contains no information because +# the user hasn't added any bookmarks. +header_bookmarks_placeholder=Henüz hiç yer iminiz yok. +# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the +# corresponding content (stories) provider +header_stories_from=kaynak: # LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give # context on how the element is related to the user, e.g. type indicates that @@ -10,9 +22,11 @@ header_highlights=Öne Çıkanlar type_label_visited=Ziyaret edildi type_label_bookmarked=Yer imlerine eklendi type_label_synced=Başka bir cihazdan eşitlendi +type_label_recommended=Popüler # LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open" type_label_open=Açık type_label_topic=Konu +type_label_now=Şimdi # LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context # menu and are meant as a call to action for a given page. @@ -26,6 +40,14 @@ menu_action_open_new_window=Yeni pencerede aç menu_action_open_private_window=Yeni gizli pencerede aç menu_action_dismiss=Kapat menu_action_delete=Geçmişten sil +menu_action_pin=Sabitle +menu_action_unpin=Sabitleneni kaldır +confirm_history_delete_p1=Bu sayfanın tüm kayıtlarını geçmişinizden silmek istediğinizden emin misiniz? +# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in +# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a +# page from history. +confirm_history_delete_notice_p2=Bu işlem geri alınamaz. +menu_action_save_to_pocket=Pocket’a kaydet # LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder # for what the user has typed in the search input field, e.g. 'Search for ' + @@ -47,6 +69,10 @@ search_header={search_engine_name} Araması search_web_placeholder=Web'de ara search_settings=Arama ayarlarını değiştir +# LOCALIZATION NOTE (section_info_option): This is the screenreader text for the +# (?) icon that would show a section's description with optional feedback link. +section_info_option=Bilgi + # LOCALIZATION NOTE (welcome_*): This is shown as a modal dialog, typically on a # first-run experience when there's no data to display yet welcome_title=Yeni sekmeye hoş geldiniz @@ -69,8 +95,12 @@ settings_pane_search_body=Yeni sekme üzerinden web'de arama yapın. settings_pane_topsites_header=Sık Kullandıklarınız settings_pane_topsites_body=En sık ziyaret ettiğiniz web sitelerine erişin. settings_pane_topsites_options_showmore=İki satır göster -settings_pane_highlights_header=Öne Çıkanlar -settings_pane_highlights_body=Yakın zamandaki gezinti geçmişinize ve yeni eklediğiniz yer imlerine göz atın. +settings_pane_bookmarks_header=Son Yer İmleri +settings_pane_bookmarks_body=Yeni eklediğiniz yer imlerini bir araya topladık. +settings_pane_visit_again_header=Yeniden Ziyaret Edin +settings_pane_visit_again_body=Firefox, gezinti geçmişinizden hatırlamak veya yeniden ziyaret etmek isteyebileceğiniz sayfaları burada gösterecek. +settings_pane_pocketstories_header=İlginç Yazılar +settings_pane_pocketstories_body=Mozilla ailesinin yeni üyesi Pocket, kolayca bulamayacağınız, kaliteli içerikleri karşınıza getiriyor. settings_pane_done_button=Tamam # LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal @@ -81,5 +111,46 @@ edit_topsites_showmore_button=Daha fazla göster edit_topsites_showless_button=Daha az göster edit_topsites_done_button=Tamam edit_topsites_pin_button=Bu siteyi sabitle +edit_topsites_unpin_button=Siteyi sabitlikten çıkar edit_topsites_edit_button=Bu siteyi düzenle edit_topsites_dismiss_button=Bu siteyi görmezden gel +edit_topsites_add_button=Ekle + +# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal. +topsites_form_add_header=Yeni sık kullanılan site +topsites_form_edit_header=Sık kullanılan siteyi düzenle +topsites_form_title_placeholder=Başlık yazın +topsites_form_url_placeholder=Adres yazın ve yapıştırın +topsites_form_add_button=Ekle +topsites_form_save_button=Kaydet +topsites_form_cancel_button=İptal +topsites_form_url_validation=Geçerli bir adres gerekli + +# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the +# trending stories section and precedes a list of links to popular topics. +pocket_read_more=Popüler konular: +# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the +# end of the list of popular topic links. +pocket_read_even_more=Daha fazla yazı göster +# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction +# to Pocket as part of the feedback form. +pocket_feedback_header=25 milyon kişinin katkılarıyla, web’in en iyileri. +# LOCALIZATION NOTE (pocket_feedback_body): This is shown below +# (pocket_feedback_header) to provide more information about Pocket. +pocket_feedback_body=Mozilla ailesinin yeni üyesi Pocket, kolayca bulamayacağınız, kaliteli içerikleri karşınıza getiriyor. +pocket_send_feedback=Görüş gönder + +# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations, +# in the space that would have shown a few stories, this is shown instead. +# {provider} is replaced by the name of the content provider for this section. +topstories_empty_state=Hepsini bitirdiniz. Yeni {provider} haberleri için daha fazla yine gelin. Beklemek istemiyor musunuz? İlginç yazılara ulaşmak için popüler konulardan birini seçebilirsiniz. + +# LOCALIZATION NOTE (manual_migration_explanation): This message is shown to encourage users to +# import their browser profile from another browser they might be using. +manual_migration_explanation=Başka tarayıcılardaki sevdiğiniz siteleri ve yer imlerinizi Firefox’a aktarabilirsiniz. +# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the +# process of importing another browser’s profile into Firefox. +manual_migration_cancel_button=Gerek yok +# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process +# of importing another browser’s profile profile into Firefox. +manual_migration_import_button=Olur, aktaralım diff --git a/locales/uk/strings.properties b/locales/uk/strings.properties index 80d491379d..e1542fae3a 100644 --- a/locales/uk/strings.properties +++ b/locales/uk/strings.properties @@ -2,7 +2,16 @@ newtab_page_title=Нова вкладка default_label_loading=Завантаження… header_top_sites=Популярні сайти -header_highlights=Обране +header_stories=Головні новини +header_visit_again=Відвідати знову +header_bookmarks=Недавно закладені +# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is +# meant to inform that section contains no information because +# the user hasn't added any bookmarks. +header_bookmarks_placeholder=У вас ще немає закладок. +# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the +# corresponding content (stories) provider +header_stories_from=від # LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give # context on how the element is related to the user, e.g. type indicates that @@ -10,6 +19,7 @@ header_highlights=Обране type_label_visited=Відвідано type_label_bookmarked=Закладено type_label_synced=Синхронізовано з іншого пристрою +type_label_recommended=Популярне # LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open" type_label_open=Відкрито type_label_topic=Тема @@ -26,6 +36,14 @@ menu_action_open_new_window=Відкрити в новому вікні menu_action_open_private_window=Відкрити в приватному вікні menu_action_dismiss=Сховати menu_action_delete=Видалити з історії +menu_action_pin=Прикріпити +menu_action_unpin=Відкріпити +confirm_history_delete_p1=Ви справді хочете видалити всі записи про цю сторінку з історії? +# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in +# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a +# page from history. +confirm_history_delete_notice_p2=Цю дію неможливо відмінити. +menu_action_save_to_pocket=Зберегти в Pocket # LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder # for what the user has typed in the search input field, e.g. 'Search for ' + @@ -69,8 +87,12 @@ settings_pane_search_body=Пошук в Інтернеті з нової вкл settings_pane_topsites_header=Популярні сайти settings_pane_topsites_body=Доступ до найчастіше відвідуваних веб-сайтів. settings_pane_topsites_options_showmore=Показувати два рядки -settings_pane_highlights_header=Обране -settings_pane_highlights_body=Огляд нещодавньої історії перегляду та нових закладок. +settings_pane_bookmarks_header=Недавно закладені +settings_pane_bookmarks_body=Ваші нові закладки в одному зручному розташуванні. +settings_pane_visit_again_header=Відвідати знову +settings_pane_visit_again_body=Firefox покаже вам елементи історії перегляду, які ви, можливо, захочете запам'ятати чи відвідати знову. +settings_pane_pocketstories_header=Головні новини +settings_pane_pocketstories_body=Pocket, частина сім'ї Mozilla, допоможе підключити вас до якісного вмісту, що ви можете інакше й не знайти. settings_pane_done_button=Готово # LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal @@ -81,5 +103,31 @@ edit_topsites_showmore_button=Показати більше edit_topsites_showless_button=Показати менше edit_topsites_done_button=Готово edit_topsites_pin_button=Закріпити цей сайт +edit_topsites_unpin_button=Відкріпити цей сайт edit_topsites_edit_button=Змінити цей сайт -edit_topsites_dismiss_button=Відхилити цей сайт +edit_topsites_dismiss_button=Сховати цей сайт +edit_topsites_add_button=Додати + +# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal. +topsites_form_add_header=Новий популярний сайт +topsites_form_edit_header=Редагувати популярний сайт +topsites_form_title_placeholder=Введіть назву +topsites_form_url_placeholder=Введіть або вставте URL-адресу +topsites_form_add_button=Додати +topsites_form_save_button=Зберегти +topsites_form_cancel_button=Скасувати +topsites_form_url_validation=Необхідна дійсна адреса URL + +# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the +# trending stories section and precedes a list of links to popular topics. +pocket_read_more=Популярні теми: +# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the +# end of the list of popular topic links. +pocket_read_even_more=Переглянути більше історій +# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction +# to Pocket as part of the feedback form. +pocket_feedback_header=Найкраще з Інтернету, відібрано понад 25 мільйонами людей. +# LOCALIZATION NOTE (pocket_feedback_body): This is shown below +# (pocket_feedback_header) to provide more information about Pocket. +pocket_feedback_body=Pocket, частина сім'ї Mozilla, допоможе підключити вас до якісного вмісту, що ви можете інакше й не знайти. +pocket_send_feedback=Надіслати відгук diff --git a/locales/ur/strings.properties b/locales/ur/strings.properties index abe742f943..c07f1dcc28 100644 --- a/locales/ur/strings.properties +++ b/locales/ur/strings.properties @@ -2,7 +2,15 @@ newtab_page_title=نیا ٹیب default_label_loading=لوڈ کر رہا ہے… header_top_sites=بہترین سائٹیں -header_highlights=شہ سرخياں +header_stories=بہترین کہانیاں +header_visit_again=دوبارہ دورہ کریں +header_bookmarks=حالیہ نشانیاں +# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is +# meant to inform that section contains no information because +# the user hasn't added any bookmarks. +# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the +# corresponding content (stories) provider +header_stories_from=من جانب # LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give # context on how the element is related to the user, e.g. type indicates that @@ -10,6 +18,7 @@ header_highlights=شہ سرخياں type_label_visited=دورہ شدہ type_label_bookmarked=نشان شدہ type_label_synced=کسی دوسرے آلے سے ہمہ وقت ساز کیا گیا ہے +type_label_recommended=رجحان سازی # LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open" type_label_open=کھولیں type_label_topic=عنوان @@ -26,6 +35,13 @@ menu_action_open_new_window=نئے دریچے میں کھولیں menu_action_open_private_window=نئی نجی دریچے میں کھولیں menu_action_dismiss=برخاست کریں menu_action_delete=تاریخ سے حذف کریں +menu_action_pin=پن +confirm_history_delete_p1=کیا آپ کو یقین ہے کہ آپ اس صفحہ کا ہر نمونہ اپنے سابقات سے حذف کرنا چاہتے ہیں؟ +# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in +# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a +# page from history. +confirm_history_delete_notice_p2=یہ عمل کلعدم نہیں ہو سکتا۔ +menu_action_save_to_pocket=Pocket میں محفوظ کریں # LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder # for what the user has typed in the search input field, e.g. 'Search for ' + @@ -63,16 +79,48 @@ time_label_day={number}d # LOCALIZATION NOTE (settings_pane_*): This is shown in the Settings Pane sidebar. settings_pane_button_label=اپنے نئے ٹیب کہ صفحہ کی تخصیص کریں settings_pane_header=نئے َٹیب کی ترجیحات +settings_pane_body=انتخاب کریں آپ کیا دیکھنا چاہتےہیں جب آپ نیا ٹیب کھولیں گے۔ settings_pane_search_header=تلاش settings_pane_search_body=اپنے نئے ٹیب سے وہب پر تلاش کریں۔ settings_pane_topsites_header=بہترین سائٹیں +settings_pane_topsites_body=اپنی سب سے زیادہ دورہ کردہ ویب سائٹ تک رسائی حاصل کریں۔ settings_pane_topsites_options_showmore=دو قطاریں دکھائیں -settings_pane_highlights_header=شہ سرخياں +settings_pane_bookmarks_header=حالیہ نشانیاں +settings_pane_visit_again_header=دوبارہ دورہ کریں +settings_pane_pocketstories_header=بہترین کہانیاں settings_pane_done_button=ہوگیا # LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal # dialog. edit_topsites_button_text=تدوین +edit_topsites_button_label=اپنی بہترین سائٹس والے حصے کی تخصیص کریں +edit_topsites_showmore_button=مزید دکھائیں edit_topsites_done_button=ہوگیا +edit_topsites_pin_button=اس سائَٹ کو پن کریں +edit_topsites_unpin_button=اس سائٹ کو انپن کریں edit_topsites_edit_button=اس سائٹ کی تدوین کریں edit_topsites_dismiss_button=اس سائٹ کو برخاست کریں +edit_topsites_add_button=آظافہ کریں + +# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal. +topsites_form_add_header=نئی بہترین سائٹ +topsites_form_edit_header=بہترین سائٹٹ کیی تدوین کریں +topsites_form_title_placeholder=ایک عنوان داخل کریں +topsites_form_url_placeholder=ٹائپ کریں یا ایک URL چسباں کریں +topsites_form_add_button=اظافہ کریں +topsites_form_save_button=محفوظ کریں +topsites_form_cancel_button=منسوخ کریں +topsites_form_url_validation=جائز URL درکار ہے + +# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the +# trending stories section and precedes a list of links to popular topics. +pocket_read_more=مشہور مضامین: +# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the +# end of the list of popular topic links. +pocket_read_even_more=مزید کہانیاں دیکھیں +# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction +# to Pocket as part of the feedback form. +# LOCALIZATION NOTE (pocket_feedback_body): This is shown below +# (pocket_feedback_header) to provide more information about Pocket. +pocket_feedback_body=Pocket ایک جصہ ہے Mozilla کے خاندان کا،آپ کو اعلی میعار کے مواد سے جڑنے میں مدد دے گا جو شاید آپ بصورت دیگر نہ ڈھونڈ سکتے۔ +pocket_send_feedback=جواب الجواب ارسال کریں diff --git a/locales/vi/strings.properties b/locales/vi/strings.properties index 036ca74052..017ed337bd 100644 --- a/locales/vi/strings.properties +++ b/locales/vi/strings.properties @@ -1,26 +1,63 @@ +newtab_page_title=Tab mới +default_label_loading=Đang tải… +header_top_sites=Trang web hàng đầu +header_stories=Câu chuyện hàng đầu +header_visit_again=Truy cập lại +header_bookmarks=Các bookmark gần đây +# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is +# meant to inform that section contains no information because +# the user hasn't added any bookmarks. +header_bookmarks_placeholder=Bạn chưa có bookmark nào. +# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the +# corresponding content (stories) provider +header_stories_from=từ # LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give # context on how the element is related to the user, e.g. type indicates that # the page is bookmarked, or is currently open on another device +type_label_visited=Đã truy cập +type_label_bookmarked=Đã được đánh dấu +type_label_synced=Đồng bộ từ thiết bị khác +type_label_recommended=Xu hướng # LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open" +type_label_open=Mở +type_label_topic=Chủ đề # LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context # menu and are meant as a call to action for a given page. # LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to # bookmarks" +menu_action_bookmark=Đánh dấu +menu_action_remove_bookmark=Xóa đánh dấu +menu_action_copy_address=Chép địa chỉ +menu_action_email_link=Liên kết Email... +menu_action_open_new_window=Mở trong Cửa Sổ Mới +menu_action_open_private_window=Mở trong cửa sổ riêng tư mới +menu_action_dismiss=Bỏ qua +menu_action_delete=Xóa từ lịch xử +menu_action_pin=Ghim +menu_action_unpin=Bỏ ghim +# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in +# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a +# page from history. +confirm_history_delete_notice_p2=Hành động này không thể hoàn tác. +menu_action_save_to_pocket=Lưu vào Pocket # LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder # for what the user has typed in the search input field, e.g. 'Search for ' + # search_term + 'with:' becomes 'Search for abc with:' # The search engine name is displayed as an icon and does not need a translation +search_for_something_with=Tìm {search_term} với: # LOCALIZATION NOTE (search_button): This is screenreader only text for the # search button. +search_button=Tìm kiếm # LOCALIZATION NOTE (search_header): Displayed at the top of the panel # showing search suggestions. {search_engine_name} is replaced with the name of # the current default search engine. e.g. 'Google Search' +search_header=Công cụ tìm kiếm {search_engine_name} # LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when # the user hasn't typed anything yet. @@ -30,8 +67,23 @@ # LOCALIZATION NOTE (time_label_*): {number} is a placeholder for a number which # represents a shortened timestamp format, e.g. '10m' means '10 minutes ago'. +time_label_less_than_minute=<1phút +time_label_minute={number}phút +time_label_hour={number}giờ # LOCALIZATION NOTE (settings_pane_*): This is shown in the Settings Pane sidebar. +settings_pane_search_header=Tìm kiếm # LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal # dialog. + +# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal. + +# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the +# trending stories section and precedes a list of links to popular topics. +# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the +# end of the list of popular topic links. +# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction +# to Pocket as part of the feedback form. +# LOCALIZATION NOTE (pocket_feedback_body): This is shown below +# (pocket_feedback_header) to provide more information about Pocket. diff --git a/locales/zh-CN/strings.properties b/locales/zh-CN/strings.properties index 8ca3be4d16..f1ce733c66 100644 --- a/locales/zh-CN/strings.properties +++ b/locales/zh-CN/strings.properties @@ -1,18 +1,32 @@ newtab_page_title=新标签页 -default_label_loading=载入中… +default_label_loading=正在载入… header_top_sites=常用网站 -header_highlights=集锦 +header_stories=热门报道 +header_visit_again=再次造访 +header_bookmarks=最近的书签 +# LOCALIZATION NOTE(header_recommended_by): This is followed by the name +# of the corresponding content provider. +header_recommended_by={provider} 推荐 +# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is +# meant to inform that section contains no information because +# the user hasn't added any bookmarks. +header_bookmarks_placeholder=您还没有最近的书签。 +# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the +# corresponding content (stories) provider +header_stories_from=出自 # LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give # context on how the element is related to the user, e.g. type indicates that # the page is bookmarked, or is currently open on another device -type_label_visited=访问过 -type_label_bookmarked=加了书签 -type_label_synced=从其他设备同步过来的 +type_label_visited=曾经访问 +type_label_bookmarked=已加书签 +type_label_synced=从其他设备同步而来 +type_label_recommended=趋势 # LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open" type_label_open=打开 type_label_topic=主题 +type_label_now=现在 # LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context # menu and are meant as a call to action for a given page. @@ -24,8 +38,16 @@ menu_action_copy_address=复制地址 menu_action_email_link=用邮件发送链接… menu_action_open_new_window=在新窗口中打开 menu_action_open_private_window=在新的隐私浏览窗口中打开 -menu_action_dismiss=隐藏 +menu_action_dismiss=消除 menu_action_delete=从历史记录中删除 +menu_action_pin=固定 +menu_action_unpin=取消固定 +confirm_history_delete_p1=确定删除此页面在您的历史记录中的所有记录? +# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in +# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a +# page from history. +confirm_history_delete_notice_p2=此操作不能撤销。 +menu_action_save_to_pocket=保存到 Pocket # LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder # for what the user has typed in the search input field, e.g. 'Search for ' + @@ -47,6 +69,10 @@ search_header={search_engine_name} 搜索 search_web_placeholder=在网络上搜索 search_settings=更改搜索设置 +# LOCALIZATION NOTE (section_info_option): This is the screenreader text for the +# (?) icon that would show a section's description with optional feedback link. +section_info_option=信息 + # LOCALIZATION NOTE (welcome_*): This is shown as a modal dialog, typically on a # first-run experience when there's no data to display yet welcome_title=欢迎使用新标签页 @@ -63,14 +89,18 @@ time_label_day={number} 天前 # LOCALIZATION NOTE (settings_pane_*): This is shown in the Settings Pane sidebar. settings_pane_button_label=定制您的新标签页 settings_pane_header=新标签页选项 -settings_pane_body=选择您在打开新标签页时看到什么。 +settings_pane_body=选择您在新标签页上看到哪些组件。 settings_pane_search_header=搜索 -settings_pane_search_body=从您的新标签页在网络上搜索。 +settings_pane_search_body=从您的新标签页搜索网络。 settings_pane_topsites_header=常用网站 settings_pane_topsites_body=访问您经常造访的网站。 settings_pane_topsites_options_showmore=双行显示 -settings_pane_highlights_header=集锦 -settings_pane_highlights_body=回顾您的最近浏览和新增书签。 +settings_pane_bookmarks_header=最近的书签 +settings_pane_bookmarks_body=您最近创建的书签将在此显示。 +settings_pane_visit_again_header=再次造访 +settings_pane_visit_again_body=Firefox 在此显示您可能想记住或再次访问的浏览记录。 +settings_pane_pocketstories_header=热门报道 +settings_pane_pocketstories_body=Pocket,Mozilla 家族的一员,它可以帮助您找到更多不易发现的高品质内容。 settings_pane_done_button=完成 # LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal @@ -81,5 +111,46 @@ edit_topsites_showmore_button=显示更多 edit_topsites_showless_button=显示更少 edit_topsites_done_button=完成 edit_topsites_pin_button=固定此网站 +edit_topsites_unpin_button=取消固定此网站 edit_topsites_edit_button=编辑此网站 edit_topsites_dismiss_button=隐藏此网站 +edit_topsites_add_button=添加 + +# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal. +topsites_form_add_header=新建常用网站 +topsites_form_edit_header=编辑常用网站 +topsites_form_title_placeholder=输入标题 +topsites_form_url_placeholder=输入或粘贴一个网址 +topsites_form_add_button=添加 +topsites_form_save_button=保存 +topsites_form_cancel_button=取消 +topsites_form_url_validation=需要有效的网址 + +# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the +# trending stories section and precedes a list of links to popular topics. +pocket_read_more=热门主题: +# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the +# end of the list of popular topic links. +pocket_read_even_more=查看更多报道 +# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction +# to Pocket as part of the feedback form. +pocket_feedback_header=超过2500万人构成的互联网。 +# LOCALIZATION NOTE (pocket_feedback_body): This is shown below +# (pocket_feedback_header) to provide more information about Pocket. +pocket_feedback_body=Pocket,Mozilla 家族的一员,它可以帮助您找到更多不易发现的高品质内容。 +pocket_send_feedback=发送反馈 + +# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations, +# in the space that would have shown a few stories, this is shown instead. +# {provider} is replaced by the name of the content provider for this section. +topstories_empty_state=已经都看过了。请过会再来查看 {provider} 提供的热门故事。不想等待?选择一个热门话题,找到网络上的更多好故事。 + +# LOCALIZATION NOTE (manual_migration_explanation): This message is shown to encourage users to +# import their browser profile from another browser they might be using. +manual_migration_explanation=将您在其他浏览器中常用的网站和书签导入 Firefox,体验别具一格的浏览器。 +# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the +# process of importing another browser’s profile into Firefox. +manual_migration_cancel_button=不用了 +# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process +# of importing another browser’s profile profile into Firefox. +manual_migration_import_button=立即导入 diff --git a/locales/zh-TW/strings.properties b/locales/zh-TW/strings.properties index ab1b2bf638..4d30e2d77e 100644 --- a/locales/zh-TW/strings.properties +++ b/locales/zh-TW/strings.properties @@ -2,7 +2,19 @@ newtab_page_title=新分頁 default_label_loading=載入中… header_top_sites=熱門網站 -header_highlights=精選網站 +header_stories=熱門文章 +header_visit_again=再次造訪 +header_bookmarks=近期新增的書籤 +# LOCALIZATION NOTE(header_recommended_by): This is followed by the name +# of the corresponding content provider. +header_recommended_by={provider} 推薦 +# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is +# meant to inform that section contains no information because +# the user hasn't added any bookmarks. +header_bookmarks_placeholder=您還沒有任何書籤。 +# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the +# corresponding content (stories) provider +header_stories_from=來自 # LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give # context on how the element is related to the user, e.g. type indicates that @@ -10,9 +22,11 @@ header_highlights=精選網站 type_label_visited=造訪過的網站 type_label_bookmarked=已加入書籤 type_label_synced=從其他裝置同步過來 +type_label_recommended=熱門 # LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open" type_label_open=開啟 type_label_topic=主題 +type_label_now=現在 # LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context # menu and are meant as a call to action for a given page. @@ -26,6 +40,14 @@ menu_action_open_new_window=用新視窗開啟 menu_action_open_private_window=用新隱私視窗開啟 menu_action_dismiss=隱藏 menu_action_delete=從瀏覽紀錄刪除 +menu_action_pin=釘選 +menu_action_unpin=取消釘選 +confirm_history_delete_p1=您確定要刪除此頁面的所有瀏覽紀錄? +# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in +# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a +# page from history. +confirm_history_delete_notice_p2=無法還原此操作。 +menu_action_save_to_pocket=儲存至 Pocket # LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder # for what the user has typed in the search input field, e.g. 'Search for ' + @@ -47,6 +69,10 @@ search_header={search_engine_name} 搜尋 search_web_placeholder=搜尋 Web search_settings=變更搜尋選項 +# LOCALIZATION NOTE (section_info_option): This is the screenreader text for the +# (?) icon that would show a section's description with optional feedback link. +section_info_option=更多資訊 + # LOCALIZATION NOTE (welcome_*): This is shown as a modal dialog, typically on a # first-run experience when there's no data to display yet welcome_title=歡迎來到新分頁 @@ -69,8 +95,12 @@ settings_pane_search_body=直接在新分頁頁面搜尋網頁。 settings_pane_topsites_header=熱門網站 settings_pane_topsites_body=前往您最常造訪的網站。 settings_pane_topsites_options_showmore=顯示兩行 -settings_pane_highlights_header=精選網站 -settings_pane_highlights_body=看看您最近的瀏覽紀錄,以及新建立的書籤項目。 +settings_pane_bookmarks_header=近期新增的書籤 +settings_pane_bookmarks_body=將您新建立的書籤,放在隨手可得的地方。 +settings_pane_visit_again_header=再次造訪 +settings_pane_visit_again_body=Firefox 將顯示您一部份可能想要再次開啟的瀏覽紀錄。 +settings_pane_pocketstories_header=熱門文章 +settings_pane_pocketstories_body=Pocket 是 Mozilla 家族的一份子,將您可能沒發現的高品質內容帶到眼前。 settings_pane_done_button=完成 # LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal @@ -81,5 +111,46 @@ edit_topsites_showmore_button=顯示更多 edit_topsites_showless_button=顯示更少 edit_topsites_done_button=完成 edit_topsites_pin_button=釘選此網站 +edit_topsites_unpin_button=取消釘選此網站 edit_topsites_edit_button=編輯此網站 edit_topsites_dismiss_button=忽略此網站 +edit_topsites_add_button=新增 + +# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal. +topsites_form_add_header=新增熱門網站 +topsites_form_edit_header=編輯熱門網站 +topsites_form_title_placeholder=輸入標題 +topsites_form_url_placeholder=輸入或貼上網址 +topsites_form_add_button=新增 +topsites_form_save_button=儲存 +topsites_form_cancel_button=取消 +topsites_form_url_validation=請輸入有效的網址 + +# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the +# trending stories section and precedes a list of links to popular topics. +pocket_read_more=熱門主題: +# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the +# end of the list of popular topic links. +pocket_read_even_more=檢視更多文章 +# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction +# to Pocket as part of the feedback form. +pocket_feedback_header=由超過兩千五百萬人找出來的 Web 最佳內容。 +# LOCALIZATION NOTE (pocket_feedback_body): This is shown below +# (pocket_feedback_header) to provide more information about Pocket. +pocket_feedback_body=Pocket 是 Mozilla 家族的一份子,將您可能沒發現的高品質內容帶到眼前。 +pocket_send_feedback=傳送意見回饋 + +# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations, +# in the space that would have shown a few stories, this is shown instead. +# {provider} is replaced by the name of the content provider for this section. +topstories_empty_state=所有文章都讀完啦!晚點再來,{provider} 將提供更多推薦故事。等不及了?選擇熱門主題,看看 Web 上各式精采資訊。 + +# LOCALIZATION NOTE (manual_migration_explanation): This message is shown to encourage users to +# import their browser profile from another browser they might be using. +manual_migration_explanation=匯入其他瀏覽器裡的書籤和網站,體驗 Firefox 的方便之處。 +# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the +# process of importing another browser’s profile into Firefox. +manual_migration_cancel_button=不必了 +# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process +# of importing another browser’s profile profile into Firefox. +manual_migration_import_button=立即匯入 diff --git a/mozilla-central-patches/disable-as-top-sites-feed-tests.diff b/mozilla-central-patches/disable-as-top-sites-feed-tests.diff deleted file mode 100644 index 776a8c79d1..0000000000 --- a/mozilla-central-patches/disable-as-top-sites-feed-tests.diff +++ /dev/null @@ -1,12 +0,0 @@ -diff --git a/testing/profiles/prefs_general.js b/testing/profiles/prefs_general.js ---- a/testing/profiles/prefs_general.js -+++ b/testing/profiles/prefs_general.js -@@ -220,6 +220,9 @@ user_pref("browser.download.panel.shown" - // which test runs first and happens to open about:newtab - user_pref("browser.newtabpage.introShown", true); - -+// Turn off Top Sites queries in activity-stream -+user_pref("browser.newtabpage.activity-stream.feeds.topsites", false); -+ - // Enable webapps testing mode, which bypasses native installation. - user_pref("browser.webapps.testing", true); diff --git a/mozilla-central-patches/disable-search-tests.diff b/mozilla-central-patches/disable-search-tests.diff index fa18f42925..693c58afde 100644 --- a/mozilla-central-patches/disable-search-tests.diff +++ b/mozilla-central-patches/disable-search-tests.diff @@ -1,28 +1,8 @@ diff --git a/browser/components/search/test/browser.ini b/browser/components/search/test/browser.ini --- a/browser/components/search/test/browser.ini +++ b/browser/components/search/test/browser.ini -@@ -21,4 +21,6 @@ support-files = - [browser_amazon_behavior.js] -+skip-if = true # mozilla/activity-stream#2339 - [browser_bing.js] - [browser_bing_behavior.js] -+skip-if = true # mozilla/activity-stream#2339 - [browser_contextmenu.js] -@@ -28,2 +30,3 @@ skip-if = os == "mac" # bug 967013 - [browser_ddg_behavior.js] -+skip-if = true # mozilla/activity-stream#2339 - [browser_google.js] @@ -31,3 +34,3 @@ skip-if = artifact # bug 1315953 [browser_google_codes.js] -skip-if = artifact # bug 1315953 +skip-if = true # bug 1315953 / mozilla/activity-stream#2366 [browser_google_nocodes.js] -@@ -35,3 +38,3 @@ skip-if = artifact # bug 1315953 - [browser_google_behavior.js] --skip-if = artifact # bug 1315953 -+skip-if = true # mozilla/activity-stream#2339 - [browser_healthreport.js] -@@ -45,2 +48,3 @@ skip-if = artifact # bug 1315953 - [browser_yahoo_behavior.js] -+skip-if = true # mozilla/activity-stream#2339 - [browser_abouthome_behavior.js] diff --git a/mozilla-central-patches/disable-tiles-tests.diff b/mozilla-central-patches/disable-tiles-tests.diff deleted file mode 100644 index 87ea451ee3..0000000000 --- a/mozilla-central-patches/disable-tiles-tests.diff +++ /dev/null @@ -1,7 +0,0 @@ -diff --git a/browser/base/moz.build b/browser/base/moz.build ---- a/browser/base/moz.build -+++ b/browser/base/moz.build -@@ -21,3 +21,2 @@ BROWSER_CHROME_MANIFESTS += [ - 'content/test/general/browser.ini', -- 'content/test/newtab/browser.ini', - 'content/test/pageinfo/browser.ini', diff --git a/mozilla-central-patches/disable-undo-notification-tests.diff b/mozilla-central-patches/disable-undo-notification-tests.diff deleted file mode 100644 index bcacc52699..0000000000 --- a/mozilla-central-patches/disable-undo-notification-tests.diff +++ /dev/null @@ -1,9 +0,0 @@ -diff --git a/browser/components/migration/tests/browser/browser.ini b/browser/components/migration/tests/browser/browser.ini ---- a/browser/components/migration/tests/browser/browser.ini -+++ b/browser/components/migration/tests/browser/browser.ini -@@ -1,3 +1,5 @@ - [browser_undo_notification.js] -+skip-if = true # disable until activity-stream handles the appropriate messages - [browser_undo_notification_wording.js] -+skip-if = true # disable until activity-stream handles the appropriate messages - [browser_undo_notification_multiple_dismissal.js] diff --git a/mozilla-central-patches/disable-usage-telemetry-tests.diff b/mozilla-central-patches/disable-usage-telemetry-tests.diff deleted file mode 100644 index 17d6e761fd..0000000000 --- a/mozilla-central-patches/disable-usage-telemetry-tests.diff +++ /dev/null @@ -1,7 +0,0 @@ -diff --git a/browser/modules/test/browser/browser.ini b/browser/modules/test/browser/browser.ini ---- a/browser/modules/test/browser/browser.ini -+++ b/browser/modules/test/browser/browser.ini -@@ -44,2 +44,3 @@ support-files = - [browser_UsageTelemetry_content.js] -+skip-if = true # disabled on pine until we have newtab search implemented - [browser_UsageTelemetry_content_aboutHome.js] diff --git a/mozilla-central-patches/enable-mc-as.diff b/mozilla-central-patches/enable-mc-as.diff deleted file mode 100644 index 99d3cb90e4..0000000000 --- a/mozilla-central-patches/enable-mc-as.diff +++ /dev/null @@ -1,28 +0,0 @@ -diff --git a/browser/app/profile/firefox.js b/browser/app/profile/firefox.js ---- a/browser/app/profile/firefox.js -+++ b/browser/app/profile/firefox.js -@@ -1227,5 +1227,5 @@ pref("browser.newtabpage.directory.ping", "https://tiles.services.mozilla.com/v3 - - // activates Activity Stream --pref("browser.newtabpage.activity-stream.enabled", false); -+pref("browser.newtabpage.activity-stream.enabled", true); - - // Enable the DOM fullscreen API. -diff --git a/browser/extensions/activity-stream/moz.build b/browser/extensions/activity-stream/moz.build ---- a/browser/extensions/activity-stream/moz.build -+++ b/browser/extensions/activity-stream/moz.build -@@ -17,2 +17,4 @@ FINAL_TARGET_PP_FILES.features['activity-stream@mozilla.org'] += [ - - JAR_MANIFESTS += ['jar.mn'] -+ -+BROWSER_CHROME_MANIFESTS += ['test/functional/mochitest/browser.ini'] -diff --git a/browser/extensions/activity-stream/test/functional/mochitest/browser.ini b/browser/extensions/activity-stream/test/functional/mochitest/browser.ini ---- a/browser/extensions/activity-stream/test/functional/mochitest/browser.ini -+++ b/browser/extensions/activity-stream/test/functional/mochitest/browser.ini -@@ -4,5 +4,5 @@ - # The tests can be run locally using 'npm run mochitest' which does various - # overrides. --skip-if=!activity_stream -+#skip-if=!activity_stream - - [browser_dummy_test.js] diff --git a/package.json b/package.json index 39ce85af7e..8730dbdae7 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "activity-streams", "description": "A rich visual history feed and a reimagined home page make it easier than ever to find exactly what you're looking for in Firefox.\n\nLearn more about this Test Pilot experiment at https://testpilot.firefox.com/.", - "version": "1.12.1", + "version": "1.14.2", "author": "Mozilla (https://mozilla.org/)", "bugs": { "url": "https://github.com/mozilla/activity-stream/issues" @@ -73,6 +73,7 @@ "minimist": "1.2.0", "mkdirp": "0.5.1", "mocha": "3.1.2", + "mock-raf": "1.0.0", "node-sass": "3.11.2", "npm-run-all": "3.1.1", "pontoon-to-json": "2.0.0", @@ -84,7 +85,7 @@ "sass-lint": "1.10.1", "shelljs": "0.7.6", "simple-git": "1.65.0", - "sinon": "2.1.0", + "sinon": "2.3.4", "style-loader": "0.13.1", "svgo": "0.7.1", "webpack": "2.2.1", @@ -151,6 +152,13 @@ "value": "https://tiles.services.mozilla.com/v3/links/activity-stream", "hidden": true }, + { + "name": "experiments.endpoint", + "title": "Experiments Definitions Endpoint", + "type": "string", + "value": "https://experimenter-cdn.services.mozilla.com/api/v1/activity-stream/experiments.json", + "hidden": true + }, { "name": "weightedHighlightsCoefficients", "title": "recommender weights", @@ -184,12 +192,6 @@ "type": "bool", "value": true }, - { - "name": "showHighlights", - "title": "Show the Highlights section on the New Tab page", - "type": "bool", - "value": true - }, { "name": "showBookmarks", "title": "Show the Bookmarks section on the New Tab page", @@ -203,10 +205,10 @@ "value": false }, { - "name": "collapseHighlights", - "title": "Collapse the Highlights on the New Tab page leaving only section title visible", + "name": "showVisitAgain", + "title": "Show the Visit Again section on the New Tab page", "type": "bool", - "value": false + "value": true }, { "name": "collapseTopSites", @@ -225,6 +227,18 @@ "title": "Collapse the Bookmarks section on the New Tab page leaving only section title visible", "type": "bool", "value": false + }, + { + "name": "collapseVisitAgain", + "title": "Collapse the Visit Again section on the New Tab page leaving only section title visible", + "type": "bool", + "value": false + }, + { + "name": "defaultBookmarksAge", + "title": "Timestamp of oldest bookmark used to filter out default bookmarks. String type used in order to support large timestamp value.", + "type": "string", + "value": "0" } ], "repository": "mozilla/activity-stream", @@ -245,8 +259,8 @@ "bundle:html": "node ./bin/generate-html.js > data/content/activity-streams.html", "postbundle": "du -hs ./data/content/*", "bundlestats": "NODE_ENV=production webpack --json | webpack-bundle-size-analyzer", - "mochitest": "(cd ../mozilla-central && ./mach mochitest --setpref browser.newtabpage.activity-stream.enabled=true --extra-mozinfo-json=$PWD/browser/extensions/activity-stream/test/mozinfo.json browser/extensions/activity-stream/test/functional/mochitest )", - "mochitest-debug": "(cd ../mozilla-central && ./mach mochitest --jsdebugger --setpref browser.newtabpage.activity-stream.enabled=true --extra-mozinfo-json=$PWD/browser/extensions/activity-stream/test/mozinfo.json browser/extensions/activity-stream/test/functional/mochitest )", + "mochitest": "(cd ../mozilla-central && ./mach mochitest browser/extensions/activity-stream/test/functional/mochitest )", + "mochitest-debug": "(cd ../mozilla-central && ./mach mochitest --jsdebugger browser/extensions/activity-stream/test/functional/mochitest )", "buildmc": "npm-run-all buildmc:*", "prebuildmc": "rimraf ../mozilla-central/browser/extensions/activity-stream", "buildmc:webpack": "webpack --config webpack.system-addon.config.js", diff --git a/system-addon/README.md b/system-addon/README.md index 7d2ee1d3ec..f114571ef9 100644 --- a/system-addon/README.md +++ b/system-addon/README.md @@ -7,4 +7,4 @@ via the browser.newtabpage.activity-stream.enabled pref. The files in this directory, including vendor dependencies, are imported from the system-addon directory in https://github.com/mozilla/activity-stream. -Read [docs/v2-system-addon](https://github.com/mozilla/activity-stream/tree/master/docs/v2-system-addon) for more detail. +Read [docs/v2-system-addon](https://github.com/mozilla/activity-stream/tree/master/docs/v2-system-addon/1.GETTING_STARTED.md) for more detail. diff --git a/system-addon/bootstrap.js b/system-addon/bootstrap.js index 7fda49675e..7ea0423634 100644 --- a/system-addon/bootstrap.js +++ b/system-addon/bootstrap.js @@ -4,17 +4,16 @@ "use strict"; const {classes: Cc, interfaces: Ci, utils: Cu} = Components; -Cu.importGlobalProperties(["fetch"]); Cu.import("resource://gre/modules/XPCOMUtils.jsm"); +Cu.importGlobalProperties(["fetch"]); XPCOMUtils.defineLazyModuleGetter(this, "Preferences", "resource://gre/modules/Preferences.jsm"); - XPCOMUtils.defineLazyModuleGetter(this, "Services", "resource://gre/modules/Services.jsm"); const ACTIVITY_STREAM_ENABLED_PREF = "browser.newtabpage.activity-stream.enabled"; -const BROWSER_READY_NOTIFICATION = "browser-ui-startup-complete"; +const BROWSER_READY_NOTIFICATION = "sessionstore-windows-restored"; const REASON_SHUTDOWN_ON_PREF_CHANGE = "PREF_OFF"; const REASON_STARTUP_ON_PREF_CHANGE = "PREF_ON"; const RESOURCE_BASE = "resource://activity-stream"; @@ -62,7 +61,11 @@ function init(reason) { } const options = Object.assign({}, startupData || {}, ACTIVITY_STREAM_OPTIONS); activityStream = new ActivityStream(options); - activityStream.init(reason); + try { + activityStream.init(reason); + } catch (e) { + Cu.reportError(e); + } } /** @@ -113,7 +116,8 @@ function observe(subject, topic, data) { switch (topic) { case BROWSER_READY_NOTIFICATION: Services.obs.removeObserver(observe, BROWSER_READY_NOTIFICATION); - onBrowserReady(); + // Avoid running synchronously during this event that's used for timing + Services.tm.dispatchToMainThread(() => onBrowserReady()); break; } } diff --git a/system-addon/common/Actions.jsm b/system-addon/common/Actions.jsm index f4c5952947..a0bb9702e8 100644 --- a/system-addon/common/Actions.jsm +++ b/system-addon/common/Actions.jsm @@ -17,38 +17,61 @@ const globalImportContext = typeof Window === "undefined" ? BACKGROUND_PROCESS : // Export for tests this.globalImportContext = globalImportContext; -const actionTypes = [ +// Create an object that avoids accidental differing key/value pairs: +// { +// INIT: "INIT", +// UNINIT: "UNINIT" +// } +const actionTypes = {}; +for (const type of [ "BLOCK_URL", "BOOKMARK_URL", "DELETE_BOOKMARK_BY_ID", "DELETE_HISTORY_URL", + "DELETE_HISTORY_URL_CONFIRM", + "DIALOG_CANCEL", + "DIALOG_OPEN", + "FEED_INIT", "INIT", "LOCALE_UPDATED", + "MIGRATION_CANCEL", + "MIGRATION_START", + "NEW_TAB_INIT", "NEW_TAB_INITIAL_STATE", "NEW_TAB_LOAD", "NEW_TAB_UNLOAD", - "NEW_TAB_VISIBLE", + "OPEN_LINK", "OPEN_NEW_WINDOW", "OPEN_PRIVATE_WINDOW", + "PINNED_SITES_UPDATED", "PLACES_BOOKMARK_ADDED", "PLACES_BOOKMARK_CHANGED", "PLACES_BOOKMARK_REMOVED", "PLACES_HISTORY_CLEARED", "PLACES_LINK_BLOCKED", "PLACES_LINK_DELETED", + "PREFS_INITIAL_VALUES", + "PREF_CHANGED", + "SAVE_SESSION_PERF_DATA", + "SAVE_TO_POCKET", "SCREENSHOT_UPDATED", + "SECTION_DEREGISTER", + "SECTION_REGISTER", + "SECTION_ROWS_UPDATE", + "SET_PREF", + "SNIPPETS_DATA", + "SNIPPETS_RESET", + "SYSTEM_TICK", "TELEMETRY_PERFORMANCE_EVENT", "TELEMETRY_UNDESIRED_EVENT", "TELEMETRY_USER_EVENT", + "TOP_SITES_PIN", + "TOP_SITES_UNPIN", "TOP_SITES_UPDATED", "UNINIT" -// The line below creates an object like this: -// { -// INIT: "INIT", -// UNINIT: "UNINIT" -// } -// It prevents accidentally adding a different key/value name. -].reduce((obj, type) => { obj[type] = type; return obj; }, {}); +]) { + actionTypes[type] = type; +} // Helper function for creating routed actions between content and main // Not intended to be used by consumers @@ -160,6 +183,11 @@ function PerfEvent(data, importContext = globalImportContext) { return importContext === UI_CODE ? SendToMain(action) : action; } +function SetPref(name, value, importContext = globalImportContext) { + const action = {type: actionTypes.SET_PREF, data: {name, value}}; + return importContext === UI_CODE ? SendToMain(action) : action; +} + this.actionTypes = actionTypes; this.actionCreators = { @@ -168,7 +196,8 @@ this.actionCreators = { UndesiredEvent, PerfEvent, SendToContent, - SendToMain + SendToMain, + SetPref }; // These are helpers to test for certain kinds of actions diff --git a/system-addon/common/PerfService.jsm b/system-addon/common/PerfService.jsm new file mode 100644 index 0000000000..a340fd6b57 --- /dev/null +++ b/system-addon/common/PerfService.jsm @@ -0,0 +1,113 @@ +/* globals Services */ +"use strict"; + +let usablePerfObj; + +let Cu; +const isRunningInChrome = typeof Window === "undefined"; + +/* istanbul ignore if */ +if (isRunningInChrome) { + Cu = Components.utils; +} else { + Cu = {import() {}}; +} + +Cu.import("resource://gre/modules/Services.jsm"); + +/* istanbul ignore if */ +if (isRunningInChrome) { + // Borrow the high-resolution timer from the hidden window.... + usablePerfObj = Services.appShell.hiddenDOMWindow.performance; +} else { // we must be running in content space + usablePerfObj = performance; +} + +this._PerfService = function _PerfService(options) { + // For testing, so that we can use a fake Window.performance object with + // known state. + if (options && options.performanceObj) { + this._perf = options.performanceObj; + } else { + this._perf = usablePerfObj; + } +}; + +_PerfService.prototype = { + /** + * Calls the underlying mark() method on the appropriate Window.performance + * object to add a mark with the given name to the appropriate performance + * timeline. + * + * @param {String} name the name to give the current mark + * @return {void} + */ + mark: function mark(str) { + this._perf.mark(str); + }, + + /** + * Calls the underlying getEntriesByName on the appropriate Window.performance + * object. + * + * @param {String} name + * @param {String} type eg "mark" + * @return {Array} Performance* objects + */ + getEntriesByName: function getEntriesByName(name, type) { + return this._perf.getEntriesByName(name, type); + }, + + /** + * The timeOrigin property from the appropriate performance object. + * Used to ensure that timestamps from the add-on code and the content code + * are comparable. + * + * @return {Number} A double of milliseconds with a precision of 0.5us. + */ + get timeOrigin() { + return this._perf.timeOrigin; + }, + + /** + * Returns the "absolute" version of performance.now(), i.e. one that + * based on the timeOrigin of the XUL hiddenwindow. + * + * @return {Number} + */ + absNow: function absNow() { + return this.timeOrigin + this._perf.now(); + }, + + /** + * This returns the absolute startTime from the most recent performance.mark() + * with the given name. + * + * @param {String} name the name to lookup the start time for + * + * @return {Number} the returned start time, as a DOMHighResTimeStamp + * + * @throws {Error} "No Marks with the name ..." if none are available + * + * @note Always surround calls to this by try/catch. Otherwise your code + * may fail when the `privacy.resistFingerprinting` pref is true. When + * this pref is set, all attempts to get marks will likely fail, which will + * cause this method to throw. + * + * See [bug 1369303](https://bugzilla.mozilla.org/show_bug.cgi?id=1369303) + * for more info. + */ + getMostRecentAbsMarkStartByName(name) { + let entries = this.getEntriesByName(name, "mark"); + + if (!entries.length) { + throw new Error(`No marks with the name ${name}`); + } + + let mostRecentEntry = entries[entries.length - 1]; + return this._perf.timeOrigin + mostRecentEntry.startTime; + } +}; + +this.perfService = new _PerfService(); +this.EXPORTED_SYMBOLS = ["_PerfService", "perfService"]; diff --git a/system-addon/common/Reducers.jsm b/system-addon/common/Reducers.jsm index 16ae5c3bb0..8aaf6eb0e8 100644 --- a/system-addon/common/Reducers.jsm +++ b/system-addon/common/Reducers.jsm @@ -16,12 +16,22 @@ const INITIAL_STATE = { // The version of the system-addon version: null }, + Snippets: {initialized: false}, TopSites: { // Have we received real data from history yet? initialized: false, // The history (and possibly default) links rows: [] - } + }, + Prefs: { + initialized: false, + values: {} + }, + Dialog: { + visible: false, + data: {} + }, + Sections: [] }; function App(prevState = INITIAL_STATE.App, action) { @@ -43,9 +53,44 @@ function App(prevState = INITIAL_STATE.App, action) { } } +/** + * insertPinned - Inserts pinned links in their specified slots + * + * @param {array} a list of links + * @param {array} a list of pinned links + * @return {array} resulting list of links with pinned links inserted + */ +function insertPinned(links, pinned) { + // Remove any pinned links + const pinnedUrls = pinned.map(link => link && link.url); + let newLinks = links.filter(link => (link ? !pinnedUrls.includes(link.url) : false)); + newLinks = newLinks.map(link => { + if (link && link.isPinned) { + delete link.isPinned; + delete link.pinTitle; + delete link.pinIndex; + } + return link; + }); + + // Then insert them in their specified location + pinned.forEach((val, index) => { + if (!val) { return; } + let link = Object.assign({}, val, {isPinned: true, pinIndex: index, pinTitle: val.title}); + if (index > newLinks.length) { + newLinks[index] = link; + } else { + newLinks.splice(index, 0, link); + } + }); + + return newLinks; +} + function TopSites(prevState = INITIAL_STATE.TopSites, action) { let hasMatch; let newRows; + let pinned; switch (action.type) { case at.TOP_SITES_UPDATED: if (!action.data) { @@ -54,7 +99,7 @@ function TopSites(prevState = INITIAL_STATE.TopSites, action) { return Object.assign({}, prevState, {initialized: true, rows: action.data}); case at.SCREENSHOT_UPDATED: newRows = prevState.rows.map(row => { - if (row.url === action.data.url) { + if (row && row.url === action.data.url) { hasMatch = true; return Object.assign({}, row, {screenshot: action.data.screenshot}); } @@ -62,8 +107,11 @@ function TopSites(prevState = INITIAL_STATE.TopSites, action) { }); return hasMatch ? Object.assign({}, prevState, {rows: newRows}) : prevState; case at.PLACES_BOOKMARK_ADDED: + if (!action.data) { + return prevState; + } newRows = prevState.rows.map(site => { - if (site.url === action.data.url) { + if (site && site.url === action.data.url) { const {bookmarkGuid, bookmarkTitle, lastModified} = action.data; return Object.assign({}, site, {bookmarkGuid, bookmarkTitle, bookmarkDateCreated: lastModified}); } @@ -71,8 +119,11 @@ function TopSites(prevState = INITIAL_STATE.TopSites, action) { }); return Object.assign({}, prevState, {rows: newRows}); case at.PLACES_BOOKMARK_REMOVED: + if (!action.data) { + return prevState; + } newRows = prevState.rows.map(site => { - if (site.url === action.data.url) { + if (site && site.url === action.data.url) { const newSite = Object.assign({}, site); delete newSite.bookmarkGuid; delete newSite.bookmarkTitle; @@ -84,14 +135,127 @@ function TopSites(prevState = INITIAL_STATE.TopSites, action) { return Object.assign({}, prevState, {rows: newRows}); case at.PLACES_LINK_DELETED: case at.PLACES_LINK_BLOCKED: - newRows = prevState.rows.filter(val => val.url !== action.data.url); + newRows = prevState.rows.filter(val => val && val.url !== action.data.url); return Object.assign({}, prevState, {rows: newRows}); + case at.PINNED_SITES_UPDATED: + pinned = action.data; + newRows = insertPinned(prevState.rows, pinned); + return Object.assign({}, prevState, {rows: newRows}); + default: + return prevState; + } +} + +function Dialog(prevState = INITIAL_STATE.Dialog, action) { + switch (action.type) { + case at.DIALOG_OPEN: + return Object.assign({}, prevState, {visible: true, data: action.data}); + case at.DIALOG_CANCEL: + return Object.assign({}, prevState, {visible: false}); + case at.DELETE_HISTORY_URL: + return Object.assign({}, INITIAL_STATE.Dialog); + default: + return prevState; + } +} + +function Prefs(prevState = INITIAL_STATE.Prefs, action) { + let newValues; + switch (action.type) { + case at.PREFS_INITIAL_VALUES: + return Object.assign({}, prevState, {initialized: true, values: action.data}); + case at.PREF_CHANGED: + newValues = Object.assign({}, prevState.values); + newValues[action.data.name] = action.data.value; + return Object.assign({}, prevState, {values: newValues}); + default: + return prevState; + } +} + +function Sections(prevState = INITIAL_STATE.Sections, action) { + let hasMatch; + let newState; + switch (action.type) { + case at.SECTION_DEREGISTER: + return prevState.filter(section => section.id !== action.data); + case at.SECTION_REGISTER: + // If section exists in prevState, update it + newState = prevState.map(section => { + if (section && section.id === action.data.id) { + hasMatch = true; + return Object.assign({}, section, action.data); + } + return section; + }); + // If section doesn't exist in prevState, create a new section object and + // append it to the sections state + if (!hasMatch) { + const initialized = action.data.rows && action.data.rows.length > 0; + newState.push(Object.assign({title: "", initialized, rows: []}, action.data)); + } + return newState; + case at.SECTION_ROWS_UPDATE: + return prevState.map(section => { + if (section && section.id === action.data.id) { + return Object.assign({}, section, action.data); + } + return section; + }); + case at.PLACES_BOOKMARK_ADDED: + if (!action.data) { + return prevState; + } + return prevState.map(section => Object.assign({}, section, { + rows: section.rows.map(item => { + // find the item within the rows that is attempted to be bookmarked + if (item.url === action.data.url) { + const {bookmarkGuid, bookmarkTitle, lastModified} = action.data; + Object.assign(item, {bookmarkGuid, bookmarkTitle, bookmarkDateCreated: lastModified}); + } + return item; + }) + })); + case at.PLACES_BOOKMARK_REMOVED: + if (!action.data) { + return prevState; + } + return prevState.map(section => Object.assign({}, section, { + rows: section.rows.map(item => { + // find the bookmark within the rows that is attempted to be removed + if (item.url === action.data.url) { + const newSite = Object.assign({}, item); + delete newSite.bookmarkGuid; + delete newSite.bookmarkTitle; + delete newSite.bookmarkDateCreated; + return newSite; + } + return item; + }) + })); + case at.PLACES_LINK_DELETED: + case at.PLACES_LINK_BLOCKED: + return prevState.map(section => + Object.assign({}, section, {rows: section.rows.filter(site => site.url !== action.data.url)})); + default: + return prevState; + } +} + +function Snippets(prevState = INITIAL_STATE.Snippets, action) { + switch (action.type) { + case at.SNIPPETS_DATA: + return Object.assign({}, prevState, {initialized: true}, action.data); + case at.SNIPPETS_RESET: + return INITIAL_STATE.Snippets; default: return prevState; } } this.INITIAL_STATE = INITIAL_STATE; -this.reducers = {TopSites, App}; -this.EXPORTED_SYMBOLS = ["reducers", "INITIAL_STATE"]; +this.reducers = {TopSites, App, Snippets, Prefs, Dialog, Sections}; +this.insertPinned = insertPinned; + +this.EXPORTED_SYMBOLS = ["reducers", "INITIAL_STATE", "insertPinned"]; diff --git a/system-addon/content-src/activity-stream.jsx b/system-addon/content-src/activity-stream.jsx index 7f1a1733e0..d831d35204 100644 --- a/system-addon/content-src/activity-stream.jsx +++ b/system-addon/content-src/activity-stream.jsx @@ -5,9 +5,20 @@ const {Provider} = require("react-redux"); const initStore = require("content-src/lib/init-store"); const {reducers} = require("common/Reducers.jsm"); const DetectUserSessionStart = require("content-src/lib/detect-user-session-start"); +const {SnippetsProvider} = require("content-src/lib/snippets"); new DetectUserSessionStart().sendEventOrAddListener(); const store = initStore(reducers); ReactDOM.render(, document.getElementById("root")); + +// Trigger snippets when snippets data has been received. +const snippets = new SnippetsProvider(); +const unsubscribe = store.subscribe(() => { + const state = store.getState(); + if (state.Snippets.initialized) { + snippets.init({appData: state.Snippets}); + unsubscribe(); + } +}); diff --git a/system-addon/content-src/activity-stream.scss b/system-addon/content-src/activity-stream.scss index c063d9fb3a..305d550704 100644 --- a/system-addon/content-src/activity-stream.scss +++ b/system-addon/content-src/activity-stream.scss @@ -10,7 +10,7 @@ body, body { background: $bg-color; - color: $dark-grey; + color: $grey-90; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Ubuntu', 'Helvetica Neue', sans-serif; font-size: 16px; } @@ -85,7 +85,7 @@ a { background: $default-button-bg; border: solid 1px $default-button-border; border-radius: 5px; - color: $mid-light-grey; + color: $grey-90; cursor: pointer; padding: 10px 30px; @@ -106,5 +106,11 @@ a { // Components @import './components/Base/Base'; @import './components/TopSites/TopSites'; +@import './components/Sections/Sections'; +@import './components/Topics/Topics'; @import './components/Search/Search'; @import './components/ContextMenu/ContextMenu'; +@import './components/PreferencesPane/PreferencesPane'; +@import './components/ConfirmDialog/ConfirmDialog'; +@import './components/Card/Card'; +@import './components/ManualMigration/ManualMigration'; diff --git a/system-addon/content-src/components/Base/Base.jsx b/system-addon/content-src/components/Base/Base.jsx index 2c34cf1aa3..c0a5e0cce7 100644 --- a/system-addon/content-src/components/Base/Base.jsx +++ b/system-addon/content-src/components/Base/Base.jsx @@ -3,6 +3,10 @@ const {connect} = require("react-redux"); const {addLocaleData, IntlProvider} = require("react-intl"); const TopSites = require("content-src/components/TopSites/TopSites"); const Search = require("content-src/components/Search/Search"); +const ConfirmDialog = require("content-src/components/ConfirmDialog/ConfirmDialog"); +const ManualMigration = require("content-src/components/ManualMigration/ManualMigration"); +const PreferencesPane = require("content-src/components/PreferencesPane/PreferencesPane"); +const Sections = require("content-src/components/Sections/Sections"); // Locales that should be displayed RTL const RTL_LIST = ["ar", "he", "fa", "ur"]; @@ -34,7 +38,9 @@ class Base extends React.Component { } render() { - let {locale, strings, initialized} = this.props.App; + const props = this.props; + const {locale, strings, initialized} = props.App; + const prefs = props.Prefs.values; if (!initialized) { return null; } @@ -42,12 +48,16 @@ class Base extends React.Component { return (
- - + {prefs.showSearch && } + {!prefs.migrationExpired && } + {prefs.showTopSites && } + +
+
); } } -module.exports = connect(state => ({App: state.App}))(Base); +module.exports = connect(state => ({App: state.App, Prefs: state.Prefs}))(Base); diff --git a/system-addon/content-src/components/Base/_Base.scss b/system-addon/content-src/components/Base/_Base.scss index 46bae71457..4c076550cb 100644 --- a/system-addon/content-src/components/Base/_Base.scss +++ b/system-addon/content-src/components/Base/_Base.scss @@ -27,4 +27,8 @@ main { font-weight: bold; text-transform: uppercase; margin: 0 0 $section-title-bottom-margin; + + span { + vertical-align: middle; + } } diff --git a/system-addon/content-src/components/Card/Card.jsx b/system-addon/content-src/components/Card/Card.jsx new file mode 100644 index 0000000000..d7f98a54fa --- /dev/null +++ b/system-addon/content-src/components/Card/Card.jsx @@ -0,0 +1,81 @@ +const React = require("react"); +const LinkMenu = require("content-src/components/LinkMenu/LinkMenu"); +const shortURL = require("content-src/lib/short-url"); +const {FormattedMessage} = require("react-intl"); +const cardContextTypes = require("./types"); +const {actionCreators: ac, actionTypes: at} = require("common/Actions.jsm"); + +/** + * Card component. + * Cards are found within a Section component and contain information about a link such + * as preview image, page title, page description, and some context about if the page + * was visited, bookmarked, trending etc... + * Each Section can make an unordered list of Cards which will create one instane of + * this class. Each card will then get a context menu which reflects the actions that + * can be done on this Card. + */ +class Card extends React.Component { + constructor(props) { + super(props); + this.state = {showContextMenu: false, activeCard: null}; + this.onMenuButtonClick = this.onMenuButtonClick.bind(this); + this.onMenuUpdate = this.onMenuUpdate.bind(this); + this.onLinkClick = this.onLinkClick.bind(this); + } + onMenuButtonClick(event) { + event.preventDefault(); + this.setState({ + activeCard: this.props.index, + showContextMenu: true + }); + } + onLinkClick(event) { + event.preventDefault(); + this.props.dispatch(ac.SendToMain({type: at.OPEN_LINK, data: this.props.link})); + this.props.dispatch(ac.UserEvent({ + event: "CLICK", + source: this.props.eventSource, + action_position: this.props.index + })); + } + onMenuUpdate(showContextMenu) { + this.setState({showContextMenu}); + } + render() { + const {index, link, dispatch, contextMenuOptions} = this.props; + const isContextMenuOpen = this.state.showContextMenu && this.state.activeCard === index; + const hostname = shortURL(link); + const {icon, intlID} = cardContextTypes[link.type]; + + return (
  • + +
  • ); + } +} +module.exports = Card; diff --git a/system-addon/content-src/components/Card/_Card.scss b/system-addon/content-src/components/Card/_Card.scss new file mode 100644 index 0000000000..6859cf5ccd --- /dev/null +++ b/system-addon/content-src/components/Card/_Card.scss @@ -0,0 +1,110 @@ +.card-outer { + background: $white; + display: inline-block; + margin-inline-end: $base-gutter; + margin-bottom: $card-margin-bottom; + width: $card-width; + border-radius: $border-radius; + border-color: $faintest-black; + height: $card-height; + position: relative; + @include context-menu-button; + + .card { + height: 100%; + border-radius: $border-radius; + } + + > a { + display: block; + color: inherit; + height: 100%; + outline: none; + position: absolute; + + &.active, &:focus { + .card { + @include fade-in; + } + } + } + + &:hover, &:focus, &.active { + outline: none; + @include fade-in; + @include context-menu-button-hover; + } + + .card-preview-image { + position: relative; + background-size: cover; + background-position: center; + background-repeat: no-repeat; + height: $card-preview-image-height; + border-bottom-color: $faintest-black; + border-bottom-style: solid; + border-bottom-width: 1px; + border-radius: $border-radius $border-radius 0 0; + } + + .card-details { + padding: 10px 16px 12px; + } + + .card-text { + overflow: hidden; + max-height: $card-text-height; + + &.full-height { + max-height: $card-description-height-max; + } + } + + .card-host-name { + color: $mid-light-grey; + font-size: 10px; + padding-bottom: 4px; + text-transform: uppercase; + } + + .card-title { + margin: 0 0 2px; + font-size: inherit; + word-wrap: break-word; + line-height: 19px; + } + + .card-description { + font-size: 12px; + margin: 0; + word-wrap: break-word; + overflow: hidden; + line-height: 19px; + } + + .card-context { + padding: 16px 16px 14px 14px; + position: absolute; + bottom: 0; + left: 0; + right: 0; + color: $light-grey; + font-size: 11px; + display: flex; + align-items: center; + } + + .card-context-icon { + opacity: 0.5; + font-size: 13px; + margin-inline-end: 6px; + display: block; + } + + .card-context-label { + flex-grow: 1; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } +} diff --git a/system-addon/content-src/components/Card/types.js b/system-addon/content-src/components/Card/types.js new file mode 100644 index 0000000000..546f538005 --- /dev/null +++ b/system-addon/content-src/components/Card/types.js @@ -0,0 +1,18 @@ +module.exports = { + history: { + intlID: "type_label_visited", + icon: "historyItem" + }, + bookmark: { + intlID: "type_label_bookmarked", + icon: "bookmark" + }, + trending: { + intlID: "type_label_recommended", + icon: "trending" + }, + now: { + intlID: "type_label_now", + icon: "now" + } +}; diff --git a/system-addon/content-src/components/ConfirmDialog/ConfirmDialog.jsx b/system-addon/content-src/components/ConfirmDialog/ConfirmDialog.jsx new file mode 100644 index 0000000000..533be912e2 --- /dev/null +++ b/system-addon/content-src/components/ConfirmDialog/ConfirmDialog.jsx @@ -0,0 +1,80 @@ +const React = require("react"); +const {connect} = require("react-redux"); +const {FormattedMessage} = require("react-intl"); +const {actionTypes, actionCreators: ac} = require("common/Actions.jsm"); + +/** + * ConfirmDialog component. + * One primary action button, one cancel button. + * + * Content displayed is controlled by `data` prop the component receives. + * Example: + * data: { + * // Any sort of data needed to be passed around by actions. + * payload: site.url, + * // Primary button SendToMain action. + * action: "DELETE_HISTORY_URL", + * // Primary button USerEvent action. + * userEvent: "DELETE", + * // Array of locale ids to display. + * message_body: ["confirm_history_delete_p1", "confirm_history_delete_notice_p2"], + * // Text for primary button. + * confirm_button_string_id: "menu_action_delete" + * }, + */ +const ConfirmDialog = React.createClass({ + getDefaultProps() { + return { + visible: false, + data: {} + }; + }, + + _handleCancelBtn() { + this.props.dispatch({type: actionTypes.DIALOG_CANCEL}); + this.props.dispatch(ac.UserEvent({event: actionTypes.DIALOG_CANCEL})); + }, + + _handleConfirmBtn() { + this.props.data.onConfirm.forEach(this.props.dispatch); + }, + + _renderModalMessage() { + const message_body = this.props.data.body_string_id; + + if (!message_body) { + return null; + } + + return ( + {message_body.map(msg =>

    )} +
    ); + }, + + render() { + if (!this.props.visible) { + return null; + } + + return (
    +
    +
    +
    + {this._renderModalMessage()} +
    +
    + + +
    +
    +
    ); + } +}); + +module.exports = connect(state => state.Dialog)(ConfirmDialog); +module.exports._unconnected = ConfirmDialog; +module.exports.Dialog = ConfirmDialog; diff --git a/system-addon/content-src/components/ConfirmDialog/ConfirmDialog.scss b/system-addon/content-src/components/ConfirmDialog/ConfirmDialog.scss new file mode 100644 index 0000000000..01ef2387ed --- /dev/null +++ b/system-addon/content-src/components/ConfirmDialog/ConfirmDialog.scss @@ -0,0 +1,50 @@ +.confirmation-dialog { + .modal { + position: fixed; + width: 400px; + top: 20%; + left: 50%; + margin-left: -200px; + box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.08); + } + + section { + margin: 0; + } + + .modal-message { + padding: 24px; + } + + .actions { + justify-content: flex-end; + + button { + margin-inline-end: 16px; + + &.done { + margin-inline-start: 0; + margin-inline-end: 0; + } + } + } +} + +.modal-overlay { + background: $bg-grey; + height: 100%; + left: 0; + opacity: 0.8; + position: fixed; + top: 0; + width: 100%; + z-index: 11001; +} + +.modal { + background: $white; + border: solid 1px $faintest-black; + border-radius: $border-radius; + font-size: 14px; + z-index: 11002; +} \ No newline at end of file diff --git a/system-addon/content-src/components/ContextMenu/ContextMenu.jsx b/system-addon/content-src/components/ContextMenu/ContextMenu.jsx index 680a2a6f25..2b8422e254 100644 --- a/system-addon/content-src/components/ContextMenu/ContextMenu.jsx +++ b/system-addon/content-src/components/ContextMenu/ContextMenu.jsx @@ -21,46 +21,60 @@ class ContextMenu extends React.Component { window.removeEventListener("click", this.hideContext); } } - componentDidUnmount() { + componentWillUnmount() { window.removeEventListener("click", this.hideContext); } - onKeyDown(event, option) { + render() { + return (); + } +} + +class ContextMenuItem extends React.Component { + constructor(props) { + super(props); + this.onClick = this.onClick.bind(this); + this.onKeyDown = this.onKeyDown.bind(this); + } + onClick() { + this.props.hideContext(); + this.props.option.onClick(); + } + onKeyDown(event) { + const {option} = this.props; switch (event.key) { case "Tab": // tab goes down in context menu, shift + tab goes up in context menu // if we're on the last item, one more tab will close the context menu // similarly, if we're on the first item, one more shift + tab will close it if ((event.shiftKey && option.first) || (!event.shiftKey && option.last)) { - this.hideContext(); + this.props.hideContext(); } break; case "Enter": - this.hideContext(); + this.props.hideContext(); option.onClick(); break; } } render() { - return (); + + ); } } module.exports = ContextMenu; +module.exports.ContextMenu = ContextMenu; +module.exports.ContextMenuItem = ContextMenuItem; diff --git a/system-addon/content-src/components/ContextMenu/_ContextMenu.scss b/system-addon/content-src/components/ContextMenu/_ContextMenu.scss index 9f4d39ecc8..08704a283a 100644 --- a/system-addon/content-src/components/ContextMenu/_ContextMenu.scss +++ b/system-addon/content-src/components/ContextMenu/_ContextMenu.scss @@ -38,7 +38,7 @@ color: $white; a { - color: $dark-grey; + color: $grey-90; } &:hover, &:focus { diff --git a/system-addon/content-src/components/LinkMenu/LinkMenu.jsx b/system-addon/content-src/components/LinkMenu/LinkMenu.jsx index 2931969ddf..b179716579 100644 --- a/system-addon/content-src/components/LinkMenu/LinkMenu.jsx +++ b/system-addon/content-src/components/LinkMenu/LinkMenu.jsx @@ -1,86 +1,39 @@ const React = require("react"); const {injectIntl} = require("react-intl"); const ContextMenu = require("content-src/components/ContextMenu/ContextMenu"); -const {actionTypes, actionCreators: ac} = require("common/Actions.jsm"); +const {actionCreators: ac} = require("common/Actions.jsm"); +const linkMenuOptions = require("content-src/lib/link-menu-options"); +const DEFAULT_SITE_MENU_OPTIONS = ["CheckPinTopSite", "Separator", "OpenInNewWindow", "OpenInPrivateWindow"]; class LinkMenu extends React.Component { - getBookmarkStatus(site) { - return (site.bookmarkGuid ? { - id: "menu_action_remove_bookmark", - icon: "bookmark-remove", - action: "DELETE_BOOKMARK_BY_ID", - data: site.bookmarkGuid, - userEvent: "BOOKMARK_DELETE" - } : { - id: "menu_action_bookmark", - icon: "bookmark", - action: "BOOKMARK_URL", - data: site.url, - userEvent: "BOOKMARK_ADD" - }); - } - getDefaultContextMenu(site) { - return [{ - id: "menu_action_open_new_window", - icon: "new-window", - action: "OPEN_NEW_WINDOW", - data: {url: site.url}, - userEvent: "OPEN_NEW_WINDOW" - }, - { - id: "menu_action_open_private_window", - icon: "new-window-private", - action: "OPEN_PRIVATE_WINDOW", - data: {url: site.url}, - userEvent: "OPEN_PRIVATE_WINDOW" - }]; - } getOptions() { - const {dispatch, site, index, source} = this.props; + const props = this.props; + const {site, index, source} = props; - // default top sites have a limited set of context menu options - let options = this.getDefaultContextMenu(site); + // Handle special case of default site + const propOptions = !site.isDefault ? props.options : DEFAULT_SITE_MENU_OPTIONS; - // all other top sites have all the following context menu options - if (!site.isDefault) { - options = [ - this.getBookmarkStatus(site), - {type: "separator"}, - ...options, - {type: "separator"}, - { - id: "menu_action_dismiss", - icon: "dismiss", - action: "BLOCK_URL", - data: site.url, - userEvent: "BLOCK" - }, - { - id: "menu_action_delete", - icon: "delete", - action: "DELETE_HISTORY_URL", - data: site.url, - userEvent: "DELETE" - }]; - } - options.forEach(option => { - const {action, data, id, type, userEvent} = option; - // Convert message ids to localized labels and add onClick function + const options = propOptions.map(o => linkMenuOptions[o](site, index)).map(option => { + const {action, id, type, userEvent} = option; if (!type && id) { - option.label = this.props.intl.formatMessage(option); + option.label = props.intl.formatMessage(option); option.onClick = () => { - dispatch(ac.SendToMain({type: actionTypes[action], data})); - dispatch(ac.UserEvent({ - event: userEvent, - source, - action_position: index - })); + props.dispatch(action); + if (userEvent) { + props.dispatch(ac.UserEvent({ + event: userEvent, + source, + action_position: index + })); + } }; } + return option; }); - // this is for a11y - we want to know which item is the first and which item - // is the last, so we can close the context menu accordingly + // This is for accessibility to support making each item tabbable. + // We want to know which item is the first and which item + // is the last, so we can close the context menu accordingly. options[0].first = true; options[options.length - 1].last = true; return options; diff --git a/system-addon/content-src/components/ManualMigration/ManualMigration.jsx b/system-addon/content-src/components/ManualMigration/ManualMigration.jsx new file mode 100644 index 0000000000..d4e8f4c746 --- /dev/null +++ b/system-addon/content-src/components/ManualMigration/ManualMigration.jsx @@ -0,0 +1,49 @@ +const React = require("react"); +const {connect} = require("react-redux"); +const {FormattedMessage} = require("react-intl"); +const {actionTypes: at, actionCreators: ac} = require("common/Actions.jsm"); + +/** + * Manual migration component used to start the profile import wizard. + * Message is presented temporarily and will go away if: + * 1. User clicks "No Thanks" + * 2. User completed the data import + * 3. After 3 active days + * 4. User clicks "Cancel" on the import wizard (currently not implemented). + */ +class ManualMigration extends React.Component { + constructor(props) { + super(props); + this.onLaunchTour = this.onLaunchTour.bind(this); + this.onCancelTour = this.onCancelTour.bind(this); + } + onLaunchTour() { + this.props.dispatch(ac.SendToMain({type: at.MIGRATION_START})); + this.props.dispatch(ac.UserEvent({event: at.MIGRATION_START})); + } + + onCancelTour() { + this.props.dispatch(ac.SendToMain({type: at.MIGRATION_CANCEL})); + this.props.dispatch(ac.UserEvent({event: at.MIGRATION_CANCEL})); + } + + render() { + return (
    +

    + + +

    +
    + + +
    +
    ); + } +} + +module.exports = connect()(ManualMigration); +module.exports._unconnected = ManualMigration; diff --git a/system-addon/content-src/components/ManualMigration/ManualMigration.scss b/system-addon/content-src/components/ManualMigration/ManualMigration.scss new file mode 100644 index 0000000000..b67b94f881 --- /dev/null +++ b/system-addon/content-src/components/ManualMigration/ManualMigration.scss @@ -0,0 +1,42 @@ +.manual-migration-container { + background: rgba(215, 215, 219, .5); + font-size: 13px; + height: 50px; + border-radius: 2px; + margin-bottom: $search-margin-bottom; + + display: flex; + justify-content: space-between; + + p { + margin: 0; + margin-inline-end: 4px; + margin-inline-start: 12px; + align-self: center; + display: flex; + justify-content: space-between; + } + + .icon { + margin: 0; + margin-inline-end: 12px; + align-self: center; + } +} + +.manual-migration-actions { + display: flex; + justify-content: space-between; + border: none; + padding: 0; + + button { + align-self: center; + padding: 0 12px; + height: 24px; + margin-inline-end: 12px; + font-size: 13px; + min-width: 100px; + white-space: nowrap; + } +} diff --git a/system-addon/content-src/components/PreferencesPane/PreferencesPane.jsx b/system-addon/content-src/components/PreferencesPane/PreferencesPane.jsx new file mode 100644 index 0000000000..f2094e1d2d --- /dev/null +++ b/system-addon/content-src/components/PreferencesPane/PreferencesPane.jsx @@ -0,0 +1,95 @@ +const React = require("react"); +const {connect} = require("react-redux"); +const {injectIntl, FormattedMessage} = require("react-intl"); +const {actionCreators: ac} = require("common/Actions.jsm"); + +const PreferencesInput = props => ( +
    + + + {props.descStringId &&

    } +
    +); + +class PreferencesPane extends React.Component { + constructor(props) { + super(props); + this.state = {visible: false}; + this.handleClickOutside = this.handleClickOutside.bind(this); + this.handleChange = this.handleChange.bind(this); + this.togglePane = this.togglePane.bind(this); + + // TODO This is temporary until sections register their PreferenceInput component automatically + try { + this.topStoriesOptions = JSON.parse(props.Prefs.values["feeds.section.topstories.options"]); + } catch (e) { + console.error("Problem parsing feeds.section.topstories.options", e); // eslint-disable-line no-console + } + } + componentDidMount() { + document.addEventListener("click", this.handleClickOutside); + } + componentWillUnmount() { + document.removeEventListener("click", this.handleClickOutside); + } + handleClickOutside(event) { + // if we are showing the sidebar and there is a click outside, close it. + if (this.state.visible && !this.refs.wrapper.contains(event.target)) { + this.togglePane(); + } + } + handleChange(event) { + const target = event.target; + this.props.dispatch(ac.SetPref(target.name, target.checked)); + } + togglePane() { + this.setState({visible: !this.state.visible}); + const event = this.state.visible ? "CLOSE_NEWTAB_PREFS" : "OPEN_NEWTAB_PREFS"; + this.props.dispatch(ac.UserEvent({event})); + } + render() { + const props = this.props; + const prefs = props.Prefs.values; + const isVisible = this.state.visible; + return ( +
    +
    +
    +
    +
    +
    +

    +

    + + + + + + {this.topStoriesOptions && !this.topStoriesOptions.hidden && + } +
    +
    + +
    +
    +
    +
    ); + } +} + +module.exports = connect(state => ({Prefs: state.Prefs}))(injectIntl(PreferencesPane)); +module.exports.PreferencesPane = PreferencesPane; +module.exports.PreferencesInput = PreferencesInput; diff --git a/system-addon/content-src/components/PreferencesPane/_PreferencesPane.scss b/system-addon/content-src/components/PreferencesPane/_PreferencesPane.scss new file mode 100644 index 0000000000..1d579e6414 --- /dev/null +++ b/system-addon/content-src/components/PreferencesPane/_PreferencesPane.scss @@ -0,0 +1,173 @@ +.prefs-pane { + font-size: 13px; + + .sidebar { + background: $white; + border-left: solid 1px $faintest-black; + box-shadow: $sidebar-shadow; + min-height: 100%; + offset-inline-end: 0; + padding: 40px; + position: fixed; + top: 0; + transition: 0.1s cubic-bezier(0, 0, 0, 1); + transition-property: left, right; + width: 400px; + z-index: 12000; + + &.hidden { + offset-inline-end: -400px; + } + + h1 { + border-bottom: solid 1px $faintest-black; + font-size: 24px; + margin: 0; + padding: 20px 0; + } + } + + .prefs-modal-inner-wrapper { + section { + margin: 20px 0; + + p { + margin: 5px 0 5px 30px; + } + + label { + position: relative; + + input { + offset-inline-start: -30px; + position: absolute; + top: 0; + } + } + + > label { + font-size: 16px; + font-weight: bold; + } + + .options { + background: $bg-grey; + border: solid 1px $faintest-black; + border-radius: $border-radius; + margin: 15px 0; + margin-inline-start: 30px; + padding: 10px; + + label { + background-position: 35px center; + background-repeat: no-repeat; + display: inline-block; + font-weight: normal; + height: 21px; + line-height: 21px; + padding-inline-start: 63px; + width: 100%; + + &:dir(rtl) { + background-position: 217px center; + } + } + } + + &.disabled { + .options { + opacity: 0.5; + } + } + } + } + + .actions { + padding: 15px 0; + } + + // CSS styled checkbox + [type='checkbox']:not(:checked), + [type='checkbox']:checked { + offset-inline-start: -9999px; + position: absolute; + } + + [type='checkbox']:not(:checked) + label, + [type='checkbox']:checked + label { + cursor: pointer; + padding: 0 30px; + position: relative; + } + + [type='checkbox']:not(:checked) + label::before, + [type='checkbox']:checked + label::before { + background: $white; + border: 1px solid $checkbox-border; + border-radius: $border-radius; + content: ''; + height: 21px; + offset-inline-start: 0; + position: absolute; + top: 0; + width: 21px; + } + + // checkmark + [type='checkbox']:not(:checked) + label::after, + [type='checkbox']:checked + label::after { + background: url('chrome://global/skin/in-content/check.svg') no-repeat center center; // sass-lint:disable-line no-url-domains + content: ''; + height: 21px; + offset-inline-start: 0; + position: absolute; + top: 0; + width: 21px; + -moz-context-properties: fill, stroke; + fill: $checkbox-blue; + stroke: none; + } + + // checkmark changes + [type='checkbox']:not(:checked) + label::after { + opacity: 0; + } + + [type='checkbox']:checked + label::after { + opacity: 1; + } + + // hover + [type='checkbox'] + label:hover::before { + border: 1px solid $checkbox-blue; + } + + // accessibility + [type='checkbox']:checked:focus + label::before, + [type='checkbox']:not(:checked):focus + label::before { + border: 1px dotted $checkbox-blue; + } +} + +.prefs-pane-button { + button { + background-color: transparent; + border: 0; + cursor: pointer; + opacity: 0.7; + padding: 15px; + position: fixed; + right: 15px; + top: 15px; + z-index: 12001; + + &:hover { + background-color: $very-light-grey; + } + + &:dir(rtl) { + left: 5px; + right: auto; + } + } +} diff --git a/system-addon/content-src/components/Search/Search.jsx b/system-addon/content-src/components/Search/Search.jsx index a4f4a29216..a6f8a5857e 100644 --- a/system-addon/content-src/components/Search/Search.jsx +++ b/system-addon/content-src/components/Search/Search.jsx @@ -23,8 +23,13 @@ class Search extends React.Component { } onInputMount(input) { if (input) { + // The first "newtab" parameter here is called the "healthReportKey" and needs + // to be "newtab" so that BrowserUsageTelemetry.jsm knows to handle events with + // this name, and can add the appropriate telemetry probes for search. Without the + // correct name, certain tests like browser_UsageTelemetry_content.js will fail (See + // github ticket #2348 for more details) this.controller = new ContentSearchUIController(input, input.parentNode, - "newtab", "activity"); + "newtab", "newtab"); addEventListener("ContentSearchClient", this); } else { this.controller = null; @@ -32,13 +37,18 @@ class Search extends React.Component { } } + /* + * Do not change the ID on the input field, as legacy newtab code + * specifically looks for the id 'newtab-search-text' on input fields + * in order to execute searches in various tests + */ render() { return (
    -